2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/scan.c#3 $
6 \brief This file defines the scan profile and the processing function of
7 scan result for SCAN Module.
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.
20 ** 01 16 2013 yuche.tsai
21 ** [ALPS00431980] [WFD]Aupus one ?play game 10 minitues?wfd connection automaticlly disconnect
22 ** Fix possible FW assert issue.
24 * 07 17 2012 yuche.tsai
26 * Let netdev bring up.
28 * 07 17 2012 yuche.tsai
30 * Compile no error before trial run.
33 * [WCXRP00001258] [MT6620][MT5931][MT6628][Driver] Do not use stale scan result for deciding connection target
34 * drop off scan result which is older than 5 seconds when choosing which BSS to join
38 * Sync CFG80211 modification from branch 2,2.
41 * [WCXRP00001169] [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration with corresponding network configuration
45 * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration with corresponding network configuration
46 * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting preferred band configuration corresponding to network type.
49 * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path
50 * add CONNECT_BY_BSSID policy
53 * [WCXRP00001123] [MT6620 Wi-Fi][Driver] Add option to disable beacon content change detection
54 * add compile option to disable beacon content change detection.
57 * [WCXRP00001085] [MT6628 Wi-Fi][Driver] deprecate old BSS-DESC if timestamp is reset with received beacon/probe response frames
58 * deprecate old BSS-DESC when timestamp in received beacon/probe response frames showed a smaller value than before
61 * [WCXRP00001031] [All Wi-Fi][Driver] Check HT IE length to avoid wrong SCO parameter
62 * Ignore HT OP IE if its length field is not valid
65 * [WCXRP00001021] [MT5931][Driver] Correct scan result generation for conversion between BSS type and operation mode
66 * correct type casting issue.
68 * 08 23 2011 yuche.tsai
70 * Fix multicast address list issue.
73 * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time
74 * sparse channel detection:
75 * driver: collect sparse channel information with scan-done event
78 * [WCXRP00000922] [MT6620 Wi-Fi][Driver] traverse whole BSS-DESC list for removing
79 * traverse whole BSS-DESC list because BSSID is not unique anymore.
82 * [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
83 * for multiple BSS descriptior detecting issue:
84 * 1) check BSSID for infrastructure network
85 * 2) check SSID for AdHoc network
88 * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings to work around some tricky AP which use space character as hidden SSID
89 * check for BSSID for beacons used to update DTIM
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 * do not check BSS descriptor for connected flag due to linksys's hidden SSID will use another BSS descriptor and never connected
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 * just pass beacons with the same BSSID.
100 * [WCXRP00000849] [MT6620 Wi-Fi][Driver] Remove some of the WAPI define for make sure the value is initialize, for customer not enable WAPI
101 * For make sure wapi initial value is set.
104 * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings to work around some tricky AP which use space character as hidden SSID
105 * Do not check for SSID as beacon content change due to the existence of single BSSID with multiple SSID AP configuration
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
110 * 2. replace only BSS-DESC which doesn't have a valid SSID.
113 * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings to work around some tricky AP which use space character as hidden SSID
114 * remove unused temporal variable reference.
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 * allow to have a single BSSID with multiple SSID to be presented in scanning result
121 * [WCXRP00000757] [MT6620 Wi-Fi][Driver][SCN] take use of RLM API to filter out BSS in disallowed channels
122 * filter out BSS in disallowed channel by
123 * 1. do not add to scan result array if BSS is at disallowed channel
124 * 2. do not allow to search for BSS-DESC in disallowed channels
126 * 05 02 2011 cm.chang
127 * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number
128 * Refine range of valid channel number
131 * [MT6620 Wi-Fi][Driver] Take parsed result for channel information instead of hardware channel number passed from firmware domain
132 * take parsed result for generating scanning result with channel information.
134 * 05 02 2011 cm.chang
135 * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number
136 * Check if channel is valided before record ing BSS channel
138 * 04 18 2011 terry.wu
139 * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
140 * Remove flag CFG_WIFI_DIRECT_MOVED.
142 * 04 14 2011 cm.chang
143 * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
146 * 04 12 2011 eddie.chen
147 * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
148 * Fix the sta index in processing security frame
149 * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4
152 * 03 25 2011 yuche.tsai
154 * Always update Bss Type, for Bss Type for P2P Network is changing every time.
156 * 03 23 2011 yuche.tsai
158 * Fix concurrent issue when AIS scan result would overwrite p2p scan result.
161 * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently
162 * filtering out other BSS coming from adjacent channels
164 * 03 11 2011 chinglan.wang
165 * [WCXRP00000537] [MT6620 Wi-Fi][Driver] Can not connect to 802.11b/g/n mixed AP with WEP security.
169 * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently
170 * When fixed channel operation is necessary, AIS-FSM would scan and only connect for BSS on the specific channel
173 * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation because NdisMSleep() won't sleep long enough for specified interval such as 500ms
174 * implement beacon change detection by checking SSID and supported rate.
176 * 02 22 2011 yuche.tsai
177 * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue
178 * Fix WSC big endian issue.
180 * 02 21 2011 terry.wu
181 * [WCXRP00000476] [MT6620 Wi-Fi][Driver] Clean P2P scan list while removing P2P
182 * Clean P2P scan list while removing P2P.
184 * 01 27 2011 yuche.tsai
185 * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate.
186 * Fix scan channel extension issue when p2p module is not registered.
188 * 01 26 2011 cm.chang
189 * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
193 * [WCXRP00000380] [MT6620 Wi-Fi][Driver] SSID information should come from buffered BSS_DESC_T rather than using beacon-carried information
194 * SSID should come from buffered prBssDesc rather than beacon-carried information
196 * 01 14 2011 yuche.tsai
197 * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
200 * 01 14 2011 yuche.tsai
201 * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
202 * Memfree for P2P Descriptor & P2P Descriptor List.
204 * 01 14 2011 yuche.tsai
205 * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
206 * Free P2P Descriptor List & Descriptor under BSS Descriptor.
209 * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease physically continous memory demands
210 * 1) correct typo in scan.c
211 * 2) TX descriptors, RX descriptos and management buffer should use virtually continous buffer instead of physically contineous one
214 * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease physically continous memory demands
215 * separate kalMemAlloc() into virtually-continous and physically-continous type to ease slab system pressure
218 * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side
219 * while being unloaded, clear all pending interrupt then set LP-own to firmware
222 * [WCXRP00000280] [MT6620 Wi-Fi][Driver] Enable BSS selection with best RCPI policy in SCN module
223 * SCN: enable BEST RSSI selection policy support
226 * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for initial TX rate selection of auto-rate algorithm
227 * update ucRcpi of STA_RECORD_T for AIS when
228 * 1) Beacons for IBSS merge is received
229 * 2) Associate Response for a connecting peer is received
232 * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group
233 * Refine the HT rate disallow TKIP pairwise cipher .
236 * [WCXRP00000091] [MT6620 Wi-Fi][Driver] Add scanning logic to filter out beacons which is received on the folding frequency
237 * trust HT IE if available for 5GHz band
240 * [WCXRP00000091] [MT6620 Wi-Fi][Driver] Add scanning logic to filter out beacons which is received on the folding frequency
241 * add timing and strenght constraint for filtering out beacons with same SSID/TA but received on different channels
244 * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine
245 * update the frog's new p2p state machine.
247 * 10 01 2010 yuche.tsai
249 * [MT6620 P2P] Fix Big Endian Issue when parse P2P device name TLV.
252 * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
253 * eliminate unused variables which lead gcc to argue
257 * use static memory pool for storing IEs of scanning result.
259 * 09 07 2010 yuche.tsai
261 * When indicate scan result, append IE buffer information in the scan result.
263 * 09 03 2010 yuche.tsai
265 * 1. Update Beacon RX count when running SLT.
266 * 2. Ignore Beacon when running SLT, would not update information from Beacon.
268 * 09 03 2010 kevin.huang
270 * Refine #include sequence and solve recursive/nested #include issue
272 * 08 31 2010 kevin.huang
274 * Use LINK LIST operation to process SCAN result
276 * 08 29 2010 yuche.tsai
278 * 1. Fix P2P Descriptor List to be a link list, to avoid link corrupt after Bss Descriptor Free.
279 * 2.. Fix P2P Device Name Length BE issue.
281 * 08 23 2010 yuche.tsai
283 * Add P2P Device Found Indication to supplicant
287 * reset BSS_DESC_T variables before parsing IE due to peer might have been reconfigured.
289 * 08 20 2010 yuche.tsai
291 * Workaround for P2P Descriptor Infinite loop issue.
295 * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI.
296 * There is no CFG_SUPPORT_BOW in driver domain source.
298 * 08 16 2010 yuche.tsai
300 * Modify code of processing Probe Resonse frame for P2P.
302 * 08 12 2010 yuche.tsai
304 * Add function to get P2P descriptor of BSS descriptor directly.
306 * 08 11 2010 yuche.tsai
308 * Modify Scan result processing for P2P module.
310 * 08 05 2010 yuche.tsai
312 * Update P2P Device Discovery result add function.
316 * surpress compilation warning.
318 * 07 26 2010 yuche.tsai
320 * Add support for Probe Request & Response parsing.
324 * 1) change BG_SCAN to ONLINE_SCAN for consistent term
325 * 2) only clear scanning result when scan is permitted to do
327 * 07 21 2010 yuche.tsai
329 * Fix compile error for SCAN module while disabling P2P feature.
331 * 07 21 2010 yuche.tsai
333 * Add P2P Scan & Scan Result Parsing & Saving.
337 * update for security supporting.
341 * [WPD00003833] [MT6620 and MT5931] Driver migration.
342 * Add Ad-Hoc support to AIS-FSM
346 * [WPD00003833] [MT6620 and MT5931] Driver migration.
347 * SCN module is now able to handle multiple concurrent scanning requests
351 * [WPD00003833] [MT6620 and MT5931] Driver migration.
352 * driver no longer generates probe request frames
356 * [WPD00003833] [MT6620 and MT5931] Driver migration.
357 * remove timer in DRV-SCN.
361 * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection)
362 * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass
363 * 3) implment DRV-SCN module, currently only accepts single scan request, other request will be directly dropped by returning BUSY
367 * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
370 * [WPD00003833][MT6620 and MT5931] Driver migration
371 * take use of RLM module for parsing/generating HT IEs for 11n capability
374 * [WPD00003833][MT6620 and MT5931] Driver migration
375 * 1) ignore RSN checking when RSN is not turned on.
376 * 2) set STA-REC deactivation callback as NULL
377 * 3) add variable initialization API based on PHY configuration
380 * [WPD00003833][MT6620 and MT5931] Driver migration
381 * correct BSS_DESC_T initialization after allocated.
384 * [WPD00003833][MT6620 and MT5931] Driver migration
385 * 1) for event packet, no need to fill RFB.
386 * 2) when wlanAdapterStart() failed, no need to initialize state machines
387 * 3) after Beacon/ProbeResp parsing, corresponding BSS_DESC_T should be marked as IE-parsed
390 * [WPD00003833][MT6620 and MT5931] Driver migration
391 * add scan uninitialization procedure
394 * [WPD00003833][MT6620 and MT5931] Driver migration
395 * if beacon/probe-resp is received in 2.4GHz bands and there is ELEM_ID_DS_PARAM_SET IE available,
396 * trust IE instead of RMAC information
399 * [WPD00003833][MT6620 and MT5931] Driver migration
400 * 1) sync to. CMD/EVENT document v0.03
401 * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again.
402 * 3) send command packet to indicate FW-PM after
403 * a) 1st beacon is received after AIS has connected to an AP
404 * b) IBSS-ALONE has been created
405 * c) IBSS-MERGE has occured
408 * [WPD00003833][MT6620 and MT5931] Driver migration
409 * send MMPDU in basic rate.
412 * [WPD00003833][MT6620 and MT5931] Driver migration
413 * modify Beacon/ProbeResp to complete parsing,
414 * because host software has looser memory usage restriction
417 * [WPD00003833][MT6620 and MT5931] Driver migration
421 * [WPD00003833][MT6620 and MT5931] Driver migration
422 * comment out RLM APIs by CFG_RLM_MIGRATION.
424 * 06 21 2010 yuche.tsai
425 * [WPD00003839][MT6620 5931][P2P] Feature migration
426 * Update P2P Function call.
429 * [WPD00003833][MT6620 and MT5931] Driver migration
430 * RSN/PRIVACY compilation flag awareness correction
433 * [WPD00003833][MT6620 and MT5931] Driver migration
434 * specify correct value for management frames.
436 * 06 18 2010 cm.chang
437 * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
438 * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
441 * [WPD00003840][MT6620 5931] Security migration
442 * migration from MT6620 firmware.
444 * 06 17 2010 yuche.tsai
445 * [WPD00003839][MT6620 5931][P2P] Feature migration
446 * Fix compile error when enable P2P function.
449 * [WPD00003833][MT6620 and MT5931] Driver migration
450 * correct when ADHOC support is turned on.
453 * [WPD00003833][MT6620 and MT5931] Driver migration
456 * 06 04 2010 george.huang
457 * [BORA00000678][MT6620]WiFi LP integration
458 * [PM] Support U-APSD for STA mode
461 * [BORA00000680][MT6620] Support the statistic for Microsoft os query
462 * adding the TKIP disallow join a HT AP code.
464 * 05 14 2010 kevin.huang
465 * [BORA00000794][WIFISYS][New Feature]Power Management Support
466 * Add more chance of JOIN retry for BG_SCAN
468 * 05 12 2010 kevin.huang
469 * [BORA00000794][WIFISYS][New Feature]Power Management Support
470 * Add Power Management - Legacy PS-POLL support.
473 * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
474 * adjsut the pre-authentication code.
476 * 04 27 2010 kevin.huang
477 * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
478 * Add Set Slot Time and Beacon Timeout Support for AdHoc Mode
480 * 04 24 2010 cm.chang
481 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
482 * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
484 * 04 19 2010 kevin.huang
485 * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
486 * Add Beacon Timeout Support and will send Null frame to diagnose connection
488 * 04 13 2010 kevin.huang
489 * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
490 * Add new HW CH macro support
493 * [BORA00000680][MT6620] Support the statistic for Microsoft os query
494 * fixed the firmware return the broadcast frame at wrong tc.
497 * [BORA00000605][WIFISYS] Phase3 Integration
498 * let the rsn wapi IE always parsing.
500 * 03 24 2010 cm.chang
501 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
502 * Not carry HT cap when being associated with b/g only AP
504 * 03 18 2010 kevin.huang
505 * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
506 * Solve the compile warning for 'return non-void' function
508 * 03 16 2010 kevin.huang
509 * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
512 * 03 10 2010 kevin.huang
513 * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support
515 * * * * * * * * * * * * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req
518 * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
519 * move the AIS specific variable for security to AIS specific structure.
522 * [BORA00000605][WIFISYS] Phase3 Integration
523 * Refine the variable and parameter for security.
525 * 02 26 2010 kevin.huang
526 * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
527 * Fix No PKT_INFO_T issue
529 * 02 26 2010 kevin.huang
530 * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
531 * Update outgoing ProbeRequest Frame's TX data rate
534 * [BORA00000592][MT6620 Wi-Fi] Adding the security related code for driver
535 * refine the scan procedure, reduce the WPA and WAPI IE parsing, and move the parsing to the time for join.
537 * 02 23 2010 kevin.huang
538 * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
539 * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb
541 * 02 04 2010 kevin.huang
542 * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
543 * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
546 * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
547 * add and fixed some security function.
549 * 01 22 2010 cm.chang
550 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
551 * Support protection and bandwidth switch
553 * 01 20 2010 kevin.huang
554 * [BORA00000569][WIFISYS] Phase 2 Integration Test
555 * Add PHASE_2_INTEGRATION_WORK_AROUND and CFG_SUPPORT_BCM flags
557 * 01 11 2010 kevin.huang
558 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
559 * Add Deauth and Disassoc Handler
561 * 01 08 2010 kevin.huang
562 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
564 * Refine Beacon processing, add read RF channel from RX Status
566 * 01 04 2010 tehuang.liu
567 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
568 * For working out the first connection Chariot-verified version
570 * 12 18 2009 cm.chang
571 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
574 * Dec 12 2009 mtk01104
575 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
576 * Modify u2EstimatedExtraIELen for probe request
578 * Dec 9 2009 mtk01104
579 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
580 * Add HT cap IE to probe request
582 * Dec 7 2009 mtk01461
583 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
587 * Dec 3 2009 mtk01461
588 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
589 * Update the process of SCAN Result by adding more Phy Attributes
591 * Dec 1 2009 mtk01088
592 * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
593 * adjust the function and code for meet the new define
595 * Nov 30 2009 mtk01461
596 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
597 * Rename u4RSSI to i4RSSI
599 * Nov 30 2009 mtk01461
600 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
601 * Report event of scan result to host
603 * Nov 26 2009 mtk01461
604 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
605 * Fix SCAN Record update
607 * Nov 24 2009 mtk01461
608 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
609 * Revise MGMT Handler with Retain Status and Integrate with TXM
611 * Nov 23 2009 mtk01461
612 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
613 * Add (Ext)Support Rate Set IE to ProbeReq
615 * Nov 20 2009 mtk02468
616 * [BORA00000337] To check in codes for FPGA emulation
617 * Removed the use of SW_RFB->u2FrameLength
619 * Nov 20 2009 mtk01461
620 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
621 * Fix uninitial aucMacAddress[] for ProbeReq
623 * Nov 16 2009 mtk01461
624 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
625 * Add scanSearchBssDescByPolicy()
627 * Nov 5 2009 mtk01461
628 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
629 * Add Send Probe Request Frame
631 * Oct 30 2009 mtk01461
632 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
636 /*******************************************************************************
637 * C O M P I L E R F L A G S
638 ********************************************************************************
641 /*******************************************************************************
642 * E X T E R N A L R E F E R E N C E S
643 ********************************************************************************
647 /*******************************************************************************
649 ********************************************************************************
651 #define REPLICATED_BEACON_TIME_THRESHOLD (3000)
652 #define REPLICATED_BEACON_FRESH_PERIOD (10000)
653 #define REPLICATED_BEACON_STRENGTH_THRESHOLD (32)
655 #define ROAMING_NO_SWING_RCPI_STEP (10)
657 /*******************************************************************************
659 ********************************************************************************
662 /*******************************************************************************
663 * P U B L I C D A T A
664 ********************************************************************************
667 /*******************************************************************************
668 * P R I V A T E D A T A
669 ********************************************************************************
672 /*******************************************************************************
674 ********************************************************************************
677 /*******************************************************************************
678 * F U N C T I O N D E C L A R A T I O N S
679 ********************************************************************************
682 /*******************************************************************************
684 ********************************************************************************
686 /*----------------------------------------------------------------------------*/
688 * @brief This function is used by SCN to initialize its variables
694 /*----------------------------------------------------------------------------*/
697 IN P_ADAPTER_T prAdapter
700 P_SCAN_INFO_T prScanInfo;
701 P_BSS_DESC_T prBSSDesc;
708 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
709 pucBSSBuff = &prScanInfo->aucScanBuffer[0];
712 DBGLOG(SCN, INFO, ("->scnInit()\n"));
714 //4 <1> Reset STATE and Message List
715 prScanInfo->eCurrentState = SCAN_STATE_IDLE;
717 prScanInfo->rLastScanCompletedTime = (OS_SYSTIME)0;
719 LINK_INITIALIZE(&prScanInfo->rPendingMsgList);
722 //4 <2> Reset link list of BSS_DESC_T
723 kalMemZero((PVOID) pucBSSBuff, SCN_MAX_BUFFER_SIZE);
725 LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList);
726 LINK_INITIALIZE(&prScanInfo->rBSSDescList);
728 for (i = 0; i < CFG_MAX_NUM_BSS_LIST; i++) {
730 prBSSDesc = (P_BSS_DESC_T)pucBSSBuff;
732 LINK_INSERT_TAIL(&prScanInfo->rFreeBSSDescList, &prBSSDesc->rLinkEntry);
734 pucBSSBuff += ALIGN_4(sizeof(BSS_DESC_T));
736 /* Check if the memory allocation consist with this initialization function */
737 ASSERT(((UINT_32)pucBSSBuff - (UINT_32)&prScanInfo->aucScanBuffer[0]) == SCN_MAX_BUFFER_SIZE);
739 /* reset freest channel information */
740 prScanInfo->fgIsSparseChannelValid = FALSE;
743 } /* end of scnInit() */
746 /*----------------------------------------------------------------------------*/
748 * @brief This function is used by SCN to uninitialize its variables
754 /*----------------------------------------------------------------------------*/
757 IN P_ADAPTER_T prAdapter
760 P_SCAN_INFO_T prScanInfo;
764 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
766 DBGLOG(SCN, INFO, ("->scnUninit()\n"));
768 //4 <1> Reset STATE and Message List
769 prScanInfo->eCurrentState = SCAN_STATE_IDLE;
771 prScanInfo->rLastScanCompletedTime = (OS_SYSTIME)0;
773 /* NOTE(Kevin): Check rPendingMsgList ? */
775 //4 <2> Reset link list of BSS_DESC_T
776 LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList);
777 LINK_INITIALIZE(&prScanInfo->rBSSDescList);
780 } /* end of scnUninit() */
784 /*----------------------------------------------------------------------------*/
786 * @brief Find the corresponding BSS Descriptor according to given BSSID
788 * @param[in] prAdapter Pointer to the Adapter structure.
789 * @param[in] aucBSSID Given BSSID.
791 * @return Pointer to BSS Descriptor, if found. NULL, if not found
793 /*----------------------------------------------------------------------------*/
795 scanSearchBssDescByBssid (
796 IN P_ADAPTER_T prAdapter,
800 return scanSearchBssDescByBssidAndSsid(prAdapter,
807 /*----------------------------------------------------------------------------*/
809 * @brief Find the corresponding BSS Descriptor according to given BSSID
811 * @param[in] prAdapter Pointer to the Adapter structure.
812 * @param[in] aucBSSID Given BSSID.
813 * @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases)
814 * @param[in] prSsid Specified SSID
816 * @return Pointer to BSS Descriptor, if found. NULL, if not found
818 /*----------------------------------------------------------------------------*/
820 scanSearchBssDescByBssidAndSsid (
821 IN P_ADAPTER_T prAdapter,
822 IN UINT_8 aucBSSID[],
823 IN BOOLEAN fgCheckSsid,
824 IN P_PARAM_SSID_T prSsid
827 P_SCAN_INFO_T prScanInfo;
828 P_LINK_T prBSSDescList;
829 P_BSS_DESC_T prBssDesc;
830 P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T)NULL;
836 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
838 prBSSDescList = &prScanInfo->rBSSDescList;
840 /* Search BSS Desc from current SCAN result list. */
841 LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
843 if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) {
844 if(fgCheckSsid == FALSE || prSsid == NULL) {
848 if(EQUAL_SSID(prBssDesc->aucSSID,
849 prBssDesc->ucSSIDLen,
851 prSsid->u4SsidLen)) {
854 else if(prDstBssDesc == NULL && prBssDesc->fgIsHiddenSSID == TRUE) {
855 prDstBssDesc = prBssDesc;
858 /* 20120206 frog: Equal BSSID but not SSID, SSID not hidden, SSID must be updated. */
859 COPY_SSID(prBssDesc->aucSSID,
860 prBssDesc->ucSSIDLen,
871 } /* end of scanSearchBssDescByBssid() */
874 /*----------------------------------------------------------------------------*/
876 * @brief Find the corresponding BSS Descriptor according to given Transmitter Address.
878 * @param[in] prAdapter Pointer to the Adapter structure.
879 * @param[in] aucSrcAddr Given Source Address(TA).
881 * @return Pointer to BSS Descriptor, if found. NULL, if not found
883 /*----------------------------------------------------------------------------*/
885 scanSearchBssDescByTA (
886 IN P_ADAPTER_T prAdapter,
887 IN UINT_8 aucSrcAddr[]
890 return scanSearchBssDescByTAAndSsid(prAdapter,
896 /*----------------------------------------------------------------------------*/
898 * @brief Find the corresponding BSS Descriptor according to given Transmitter Address.
900 * @param[in] prAdapter Pointer to the Adapter structure.
901 * @param[in] aucSrcAddr Given Source Address(TA).
902 * @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases)
903 * @param[in] prSsid Specified SSID
905 * @return Pointer to BSS Descriptor, if found. NULL, if not found
907 /*----------------------------------------------------------------------------*/
909 scanSearchBssDescByTAAndSsid (
910 IN P_ADAPTER_T prAdapter,
911 IN UINT_8 aucSrcAddr[],
912 IN BOOLEAN fgCheckSsid,
913 IN P_PARAM_SSID_T prSsid
916 P_SCAN_INFO_T prScanInfo;
917 P_LINK_T prBSSDescList;
918 P_BSS_DESC_T prBssDesc;
919 P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T)NULL;
925 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
927 prBSSDescList = &prScanInfo->rBSSDescList;
929 /* Search BSS Desc from current SCAN result list. */
930 LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
932 if (EQUAL_MAC_ADDR(prBssDesc->aucSrcAddr, aucSrcAddr)) {
933 if(fgCheckSsid == FALSE || prSsid == NULL) {
937 if(EQUAL_SSID(prBssDesc->aucSSID,
938 prBssDesc->ucSSIDLen,
940 prSsid->u4SsidLen)) {
943 else if(prDstBssDesc == NULL && prBssDesc->fgIsHiddenSSID == TRUE) {
944 prDstBssDesc = prBssDesc;
952 } /* end of scanSearchBssDescByTA() */
955 /*----------------------------------------------------------------------------*/
957 * @brief Find the corresponding BSS Descriptor according to
958 * given eBSSType, BSSID and Transmitter Address
960 * @param[in] prAdapter Pointer to the Adapter structure.
961 * @param[in] eBSSType BSS Type of incoming Beacon/ProbeResp frame.
962 * @param[in] aucBSSID Given BSSID of Beacon/ProbeResp frame.
963 * @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame.
965 * @return Pointer to BSS Descriptor, if found. NULL, if not found
967 /*----------------------------------------------------------------------------*/
969 scanSearchExistingBssDesc (
970 IN P_ADAPTER_T prAdapter,
971 IN ENUM_BSS_TYPE_T eBSSType,
972 IN UINT_8 aucBSSID[],
973 IN UINT_8 aucSrcAddr[]
976 return scanSearchExistingBssDescWithSsid(prAdapter,
985 /*----------------------------------------------------------------------------*/
987 * @brief Find the corresponding BSS Descriptor according to
988 * given eBSSType, BSSID and Transmitter Address
990 * @param[in] prAdapter Pointer to the Adapter structure.
991 * @param[in] eBSSType BSS Type of incoming Beacon/ProbeResp frame.
992 * @param[in] aucBSSID Given BSSID of Beacon/ProbeResp frame.
993 * @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame.
994 * @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases)
995 * @param[in] prSsid Specified SSID
997 * @return Pointer to BSS Descriptor, if found. NULL, if not found
999 /*----------------------------------------------------------------------------*/
1001 scanSearchExistingBssDescWithSsid (
1002 IN P_ADAPTER_T prAdapter,
1003 IN ENUM_BSS_TYPE_T eBSSType,
1004 IN UINT_8 aucBSSID[],
1005 IN UINT_8 aucSrcAddr[],
1006 IN BOOLEAN fgCheckSsid,
1007 IN P_PARAM_SSID_T prSsid
1010 P_SCAN_INFO_T prScanInfo;
1011 P_BSS_DESC_T prBssDesc, prIBSSBssDesc;
1016 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1020 case BSS_TYPE_P2P_DEVICE:
1021 fgCheckSsid = FALSE;
1022 case BSS_TYPE_INFRASTRUCTURE:
1023 case BSS_TYPE_BOW_DEVICE:
1025 prBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, fgCheckSsid, prSsid);
1027 /* if (eBSSType == prBssDesc->eBSSType) */
1034 prIBSSBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, fgCheckSsid, prSsid);
1035 prBssDesc = scanSearchBssDescByTAAndSsid(prAdapter, aucSrcAddr, fgCheckSsid, prSsid);
1038 * Rules to maintain the SCAN Result:
1040 * CASE I We have TA1(BSSID1), but it change its BSSID to BSSID2
1041 * -> Update TA1 entry's BSSID.
1042 * CASE II We have TA1(BSSID1), and get TA1(BSSID1) again
1043 * -> Update TA1 entry's contain.
1044 * CASE III We have a SCAN result TA1(BSSID1), and TA2(BSSID2). Sooner or
1045 * later, TA2 merge into TA1, we get TA2(BSSID1)
1046 * -> Remove TA2 first and then replace TA1 entry's TA with TA2, Still have only one entry of BSSID.
1047 * CASE IV We have a SCAN result TA1(BSSID1), and another TA2 also merge into BSSID1.
1048 * -> Replace TA1 entry's TA with TA2, Still have only one entry.
1050 * -> Add this one to SCAN result.
1053 if ((!prIBSSBssDesc) || // CASE I
1054 (prBssDesc == prIBSSBssDesc)) { // CASE II
1059 P_LINK_T prBSSDescList;
1060 P_LINK_T prFreeBSSDescList;
1063 prBSSDescList = &prScanInfo->rBSSDescList;
1064 prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1066 /* Remove this BSS Desc from the BSS Desc list */
1067 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1069 /* Return this BSS Desc to the free BSS Desc list. */
1070 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1072 return prIBSSBssDesc;
1076 if (prIBSSBssDesc) { // CASE IV
1078 return prIBSSBssDesc;
1082 break; // Return NULL;
1090 return (P_BSS_DESC_T)NULL;
1092 } /* end of scanSearchExistingBssDesc() */
1095 /*----------------------------------------------------------------------------*/
1097 * @brief Delete BSS Descriptors from current list according to given Remove Policy.
1099 * @param[in] u4RemovePolicy Remove Policy.
1103 /*----------------------------------------------------------------------------*/
1105 scanRemoveBssDescsByPolicy (
1106 IN P_ADAPTER_T prAdapter,
1107 IN UINT_32 u4RemovePolicy
1110 P_CONNECTION_SETTINGS_T prConnSettings;
1111 P_SCAN_INFO_T prScanInfo;
1112 P_LINK_T prBSSDescList;
1113 P_LINK_T prFreeBSSDescList;
1114 P_BSS_DESC_T prBssDesc;
1119 prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
1120 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1121 prBSSDescList = &prScanInfo->rBSSDescList;
1122 prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1124 //DBGLOG(SCN, TRACE, ("Before Remove - Number Of SCAN Result = %ld\n",
1125 //prBSSDescList->u4NumElem));
1127 if (u4RemovePolicy & SCN_RM_POLICY_TIMEOUT) {
1128 P_BSS_DESC_T prBSSDescNext;
1129 OS_SYSTIME rCurrentTime;
1132 GET_CURRENT_SYSTIME(&rCurrentTime);
1134 /* Search BSS Desc from current SCAN result list. */
1135 LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1137 if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
1138 (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
1139 /* Don't remove the one currently we are connected. */
1143 if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
1144 SEC_TO_SYSTIME(SCN_BSS_DESC_REMOVE_TIMEOUT_SEC)) ) {
1146 //DBGLOG(SCN, TRACE, ("Remove TIMEOUT BSS DESC(%#x): MAC: "MACSTR", Current Time = %08lx, Update Time = %08lx\n",
1147 //prBssDesc, MAC2STR(prBssDesc->aucBSSID), rCurrentTime, prBssDesc->rUpdateTime));
1149 /* Remove this BSS Desc from the BSS Desc list */
1150 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1152 /* Return this BSS Desc to the free BSS Desc list. */
1153 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1157 else if (u4RemovePolicy & SCN_RM_POLICY_OLDEST_HIDDEN) {
1158 P_BSS_DESC_T prBssDescOldest = (P_BSS_DESC_T)NULL;
1161 /* Search BSS Desc from current SCAN result list. */
1162 LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1164 if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
1165 (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
1166 /* Don't remove the one currently we are connected. */
1170 if (!prBssDesc->fgIsHiddenSSID) {
1174 if (!prBssDescOldest) { /* 1st element */
1175 prBssDescOldest = prBssDesc;
1179 if (TIME_BEFORE(prBssDesc->rUpdateTime, prBssDescOldest->rUpdateTime)) {
1180 prBssDescOldest = prBssDesc;
1184 if (prBssDescOldest) {
1186 //DBGLOG(SCN, TRACE, ("Remove OLDEST HIDDEN BSS DESC(%#x): MAC: "MACSTR", Update Time = %08lx\n",
1187 //prBssDescOldest, MAC2STR(prBssDescOldest->aucBSSID), prBssDescOldest->rUpdateTime));
1189 /* Remove this BSS Desc from the BSS Desc list */
1190 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescOldest);
1192 /* Return this BSS Desc to the free BSS Desc list. */
1193 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDescOldest->rLinkEntry);
1196 else if (u4RemovePolicy & SCN_RM_POLICY_SMART_WEAKEST) {
1197 P_BSS_DESC_T prBssDescWeakest = (P_BSS_DESC_T)NULL;
1198 P_BSS_DESC_T prBssDescWeakestSameSSID = (P_BSS_DESC_T)NULL;
1199 UINT_32 u4SameSSIDCount = 0;
1202 /* Search BSS Desc from current SCAN result list. */
1203 LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1205 if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
1206 (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
1207 /* Don't remove the one currently we are connected. */
1211 if ((!prBssDesc->fgIsHiddenSSID) &&
1212 (EQUAL_SSID(prBssDesc->aucSSID,
1213 prBssDesc->ucSSIDLen,
1214 prConnSettings->aucSSID,
1215 prConnSettings->ucSSIDLen))) {
1219 if (!prBssDescWeakestSameSSID) {
1220 prBssDescWeakestSameSSID = prBssDesc;
1222 else if (prBssDesc->ucRCPI < prBssDescWeakestSameSSID->ucRCPI) {
1223 prBssDescWeakestSameSSID = prBssDesc;
1227 if (!prBssDescWeakest) { /* 1st element */
1228 prBssDescWeakest = prBssDesc;
1232 if (prBssDesc->ucRCPI < prBssDescWeakest->ucRCPI) {
1233 prBssDescWeakest = prBssDesc;
1238 if ((u4SameSSIDCount >= SCN_BSS_DESC_SAME_SSID_THRESHOLD) &&
1239 (prBssDescWeakestSameSSID)) {
1240 prBssDescWeakest = prBssDescWeakestSameSSID;
1243 if (prBssDescWeakest) {
1245 //DBGLOG(SCN, TRACE, ("Remove WEAKEST BSS DESC(%#x): MAC: "MACSTR", Update Time = %08lx\n",
1246 //prBssDescOldest, MAC2STR(prBssDescOldest->aucBSSID), prBssDescOldest->rUpdateTime));
1248 /* Remove this BSS Desc from the BSS Desc list */
1249 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescWeakest);
1251 /* Return this BSS Desc to the free BSS Desc list. */
1252 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDescWeakest->rLinkEntry);
1255 else if (u4RemovePolicy & SCN_RM_POLICY_ENTIRE) {
1256 P_BSS_DESC_T prBSSDescNext;
1258 LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1260 if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
1261 (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
1262 /* Don't remove the one currently we are connected. */
1266 /* Remove this BSS Desc from the BSS Desc list */
1267 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1269 /* Return this BSS Desc to the free BSS Desc list. */
1270 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1277 } /* end of scanRemoveBssDescsByPolicy() */
1280 /*----------------------------------------------------------------------------*/
1282 * @brief Delete BSS Descriptors from current list according to given BSSID.
1284 * @param[in] prAdapter Pointer to the Adapter structure.
1285 * @param[in] aucBSSID Given BSSID.
1289 /*----------------------------------------------------------------------------*/
1291 scanRemoveBssDescByBssid (
1292 IN P_ADAPTER_T prAdapter,
1293 IN UINT_8 aucBSSID[]
1296 P_SCAN_INFO_T prScanInfo;
1297 P_LINK_T prBSSDescList;
1298 P_LINK_T prFreeBSSDescList;
1299 P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T)NULL;
1300 P_BSS_DESC_T prBSSDescNext;
1306 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1307 prBSSDescList = &prScanInfo->rBSSDescList;
1308 prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1310 /* Check if such BSS Descriptor exists in a valid list */
1311 LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1313 if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) {
1315 /* Remove this BSS Desc from the BSS Desc list */
1316 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1318 /* Return this BSS Desc to the free BSS Desc list. */
1319 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1321 /* BSSID is not unique, so need to traverse whols link-list */
1326 } /* end of scanRemoveBssDescByBssid() */
1329 /*----------------------------------------------------------------------------*/
1331 * @brief Delete BSS Descriptors from current list according to given band configuration
1333 * @param[in] prAdapter Pointer to the Adapter structure.
1334 * @param[in] eBand Given band
1335 * @param[in] eNetTypeIndex AIS - Remove IBSS/Infrastructure BSS
1336 * BOW - Remove BOW BSS
1337 * P2P - Remove P2P BSS
1341 /*----------------------------------------------------------------------------*/
1343 scanRemoveBssDescByBandAndNetwork (
1344 IN P_ADAPTER_T prAdapter,
1345 IN ENUM_BAND_T eBand,
1346 IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex
1349 P_SCAN_INFO_T prScanInfo;
1350 P_LINK_T prBSSDescList;
1351 P_LINK_T prFreeBSSDescList;
1352 P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T)NULL;
1353 P_BSS_DESC_T prBSSDescNext;
1357 ASSERT(eBand <= BAND_NUM);
1358 ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM);
1360 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1361 prBSSDescList = &prScanInfo->rBSSDescList;
1362 prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1365 if(eBand == BAND_NULL) {
1366 return; /* no need to do anything, keep all scan result */
1369 /* Check if such BSS Descriptor exists in a valid list */
1370 LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1373 if(prBssDesc->eBand == eBand) {
1374 switch (eNetTypeIndex) {
1375 case NETWORK_TYPE_AIS_INDEX:
1376 if((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE)
1377 || (prBssDesc->eBSSType == BSS_TYPE_IBSS)) {
1382 case NETWORK_TYPE_P2P_INDEX:
1383 if(prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) {
1388 case NETWORK_TYPE_BOW_INDEX:
1389 if(prBssDesc->eBSSType == BSS_TYPE_BOW_DEVICE) {
1400 if(fgToRemove == TRUE) {
1401 /* Remove this BSS Desc from the BSS Desc list */
1402 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1404 /* Return this BSS Desc to the free BSS Desc list. */
1405 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1410 } /* end of scanRemoveBssDescByBand() */
1413 /*----------------------------------------------------------------------------*/
1415 * @brief Clear the CONNECTION FLAG of a specified BSS Descriptor.
1417 * @param[in] aucBSSID Given BSSID.
1421 /*----------------------------------------------------------------------------*/
1423 scanRemoveConnFlagOfBssDescByBssid (
1424 IN P_ADAPTER_T prAdapter,
1425 IN UINT_8 aucBSSID[]
1428 P_SCAN_INFO_T prScanInfo;
1429 P_LINK_T prBSSDescList;
1430 P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T)NULL;
1436 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1437 prBSSDescList = &prScanInfo->rBSSDescList;
1439 /* Search BSS Desc from current SCAN result list. */
1440 LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1442 if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) {
1443 prBssDesc->fgIsConnected = FALSE;
1444 prBssDesc->fgIsConnecting = FALSE;
1446 /* BSSID is not unique, so need to traverse whols link-list */
1452 } /* end of scanRemoveConnectionFlagOfBssDescByBssid() */
1455 /*----------------------------------------------------------------------------*/
1457 * @brief Allocate new BSS_DESC_T
1459 * @param[in] prAdapter Pointer to the Adapter structure.
1461 * @return Pointer to BSS Descriptor, if has free space. NULL, if has no space.
1463 /*----------------------------------------------------------------------------*/
1465 scanAllocateBssDesc (
1466 IN P_ADAPTER_T prAdapter
1469 P_SCAN_INFO_T prScanInfo;
1470 P_LINK_T prFreeBSSDescList;
1471 P_BSS_DESC_T prBssDesc;
1475 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1477 prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1479 LINK_REMOVE_HEAD(prFreeBSSDescList, prBssDesc, P_BSS_DESC_T);
1482 P_LINK_T prBSSDescList;
1484 kalMemZero(prBssDesc, sizeof(BSS_DESC_T));
1486 #if CFG_ENABLE_WIFI_DIRECT
1487 LINK_INITIALIZE(&(prBssDesc->rP2pDeviceList));
1488 prBssDesc->fgIsP2PPresent = FALSE;
1489 #endif /* CFG_ENABLE_WIFI_DIRECT */
1491 prBSSDescList = &prScanInfo->rBSSDescList;
1493 /* NOTE(Kevin): In current design, this new empty BSS_DESC_T will be
1494 * inserted to BSSDescList immediately.
1496 LINK_INSERT_TAIL(prBSSDescList, &prBssDesc->rLinkEntry);
1501 } /* end of scanAllocateBssDesc() */
1504 /*----------------------------------------------------------------------------*/
1506 * @brief This API parses Beacon/ProbeResp frame and insert extracted BSS_DESC_T
1507 * with IEs into prAdapter->rWifiVar.rScanInfo.aucScanBuffer
1509 * @param[in] prAdapter Pointer to the Adapter structure.
1510 * @param[in] prSwRfb Pointer to the receiving frame buffer.
1512 * @return Pointer to BSS Descriptor
1513 * NULL if the Beacon/ProbeResp frame is invalid
1515 /*----------------------------------------------------------------------------*/
1518 IN P_ADAPTER_T prAdapter,
1519 IN P_SW_RFB_T prSwRfb
1522 P_BSS_DESC_T prBssDesc = NULL;
1524 ENUM_BSS_TYPE_T eBSSType = BSS_TYPE_INFRASTRUCTURE;
1528 UINT_16 u2Offset = 0;
1530 P_WLAN_BEACON_FRAME_T prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T)NULL;
1531 P_IE_SSID_T prIeSsid = (P_IE_SSID_T)NULL;
1532 P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T)NULL;
1533 P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T)NULL;
1534 P_HIF_RX_HEADER_T prHifRxHdr;
1535 UINT_8 ucHwChannelNum = 0;
1536 UINT_8 ucIeDsChannelNum = 0;
1537 UINT_8 ucIeHtChannelNum = 0;
1538 BOOLEAN fgIsValidSsid = FALSE, fgEscape = FALSE;
1540 UINT_64 u8Timestamp;
1541 BOOLEAN fgIsNewBssDesc = FALSE;
1549 prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T)prSwRfb->pvHeader;
1551 WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2CapInfo, &u2CapInfo);
1552 WLAN_GET_FIELD_64(&prWlanBeaconFrame->au4Timestamp[0], &u8Timestamp);
1555 switch (u2CapInfo & CAP_INFO_BSS_TYPE) {
1557 /* It can also be Group Owner of P2P Group. */
1558 eBSSType = BSS_TYPE_INFRASTRUCTURE;
1562 eBSSType = BSS_TYPE_IBSS;
1565 /* 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) */
1566 eBSSType = BSS_TYPE_P2P_DEVICE;
1569 #if CFG_ENABLE_BT_OVER_WIFI
1570 // @TODO: add rule to identify BOW beacons
1577 //4 <1.1> Pre-parse SSID IE
1578 pucIE = prWlanBeaconFrame->aucInfoElem;
1579 u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
1580 (UINT_16)OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]);
1582 if (u2IELength > CFG_IE_BUFFER_SIZE) {
1583 u2IELength = CFG_IE_BUFFER_SIZE;
1586 IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
1587 switch (IE_ID(pucIE)) {
1589 if (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID) {
1592 /* D-Link DWL-900AP+ */
1593 if (IE_LEN(pucIE) == 0) {
1594 fgIsValidSsid = FALSE;
1596 /* Cisco AP1230A - (IE_LEN(pucIE) == 1) && (SSID_IE(pucIE)->aucSSID[0] == '\0') */
1597 /* Linksys WRK54G/ASUS WL520g - (IE_LEN(pucIE) == n) && (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') */
1599 for (i = 0; i < IE_LEN(pucIE); i++) {
1600 ucSSIDChar |= SSID_IE(pucIE)->aucSSID[i];
1604 fgIsValidSsid = TRUE;
1608 /* Update SSID to BSS Descriptor only if SSID is not hidden. */
1609 if (fgIsValidSsid == TRUE) {
1610 COPY_SSID(rSsid.aucSsid,
1612 SSID_IE(pucIE)->aucSSID,
1613 SSID_IE(pucIE)->ucLength);
1622 if(fgEscape == TRUE) {
1628 //4 <1.2> Replace existing BSS_DESC_T or allocate a new one
1629 prBssDesc = scanSearchExistingBssDescWithSsid(prAdapter,
1631 (PUINT_8)prWlanBeaconFrame->aucBSSID,
1632 (PUINT_8)prWlanBeaconFrame->aucSrcAddr,
1634 fgIsValidSsid == TRUE ? &rSsid : NULL);
1636 if (prBssDesc == (P_BSS_DESC_T)NULL) {
1637 fgIsNewBssDesc = TRUE;
1640 //4 <1.2.1> First trial of allocation
1641 prBssDesc = scanAllocateBssDesc(prAdapter);
1646 //4 <1.2.2> Hidden is useless, remove the oldest hidden ssid. (for passive scan)
1647 scanRemoveBssDescsByPolicy(prAdapter,
1648 (SCN_RM_POLICY_EXCLUDE_CONNECTED | SCN_RM_POLICY_OLDEST_HIDDEN));
1650 //4 <1.2.3> Second tail of allocation
1651 prBssDesc = scanAllocateBssDesc(prAdapter);
1656 //4 <1.2.4> Remove the weakest one
1657 /* If there are more than half of BSS which has the same ssid as connection
1658 * setting, remove the weakest one from them.
1659 * Else remove the weakest one.
1661 scanRemoveBssDescsByPolicy(prAdapter,
1662 (SCN_RM_POLICY_EXCLUDE_CONNECTED | SCN_RM_POLICY_SMART_WEAKEST));
1664 //4 <1.2.5> reallocation
1665 prBssDesc = scanAllocateBssDesc(prAdapter);
1670 //4 <1.2.6> no space, should not happen
1671 //ASSERT(0); // still no space available ?
1679 OS_SYSTIME rCurrentTime;
1682 // if the received strength is much weaker than the original one,
1683 // ignore it due to it might be received on the folding frequency
1685 GET_CURRENT_SYSTIME(&rCurrentTime);
1687 prBssDesc->eBSSType = eBSSType;
1689 if(HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr) != prBssDesc->ucChannelNum &&
1690 prBssDesc->ucRCPI > prSwRfb->prHifRxHdr->ucRcpi) {
1692 // for signal strength is too much weaker and previous beacon is not stale
1693 if((prBssDesc->ucRCPI - prSwRfb->prHifRxHdr->ucRcpi) >= REPLICATED_BEACON_STRENGTH_THRESHOLD &&
1694 rCurrentTime - prBssDesc->rUpdateTime <= REPLICATED_BEACON_FRESH_PERIOD) {
1697 // for received beacons too close in time domain
1698 else if(rCurrentTime - prBssDesc->rUpdateTime <= REPLICATED_BEACON_TIME_THRESHOLD) {
1703 /* if Timestamp has been reset, re-generate BSS DESC 'cause AP should have reset itself */
1704 if(prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && u8Timestamp < prBssDesc->u8TimeStamp.QuadPart) {
1705 BOOLEAN fgIsConnected, fgIsConnecting;
1707 /* set flag for indicating this is a new BSS-DESC */
1708 fgIsNewBssDesc = TRUE;
1710 /* backup 2 flags for APs which reset timestamp unexpectedly */
1711 fgIsConnected = prBssDesc->fgIsConnected;
1712 fgIsConnecting = prBssDesc->fgIsConnecting;
1713 scanRemoveBssDescByBssid(prAdapter, prBssDesc->aucBSSID);
1715 prBssDesc = scanAllocateBssDesc(prAdapter);
1721 prBssDesc->fgIsConnected = fgIsConnected;
1722 prBssDesc->fgIsConnecting = fgIsConnecting;
1726 /* NOTE: Keep consistency of Scan Record during JOIN process */
1727 if ((fgIsNewBssDesc == FALSE) && prBssDesc->fgIsConnecting) {
1731 //4 <2> Get information from Fixed Fields
1732 prBssDesc->eBSSType = eBSSType; /* Update the latest BSS type information. */
1734 COPY_MAC_ADDR(prBssDesc->aucSrcAddr, prWlanBeaconFrame->aucSrcAddr);
1736 COPY_MAC_ADDR(prBssDesc->aucBSSID, prWlanBeaconFrame->aucBSSID);
1738 prBssDesc->u8TimeStamp.QuadPart = u8Timestamp;
1740 WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2BeaconInterval, &prBssDesc->u2BeaconInterval);
1742 prBssDesc->u2CapInfo = u2CapInfo;
1745 //4 <2.1> Retrieve IEs for later parsing
1746 u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
1747 (UINT_16)OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]);
1749 if (u2IELength > CFG_IE_BUFFER_SIZE) {
1750 u2IELength = CFG_IE_BUFFER_SIZE;
1751 prBssDesc->fgIsIEOverflow = TRUE;
1754 prBssDesc->fgIsIEOverflow = FALSE;
1756 prBssDesc->u2IELength = u2IELength;
1758 kalMemCopy(prBssDesc->aucIEBuf, prWlanBeaconFrame->aucInfoElem, u2IELength);
1760 //4 <2.2> reset prBssDesc variables in case that AP has been reconfigured
1761 prBssDesc->fgIsERPPresent = FALSE;
1762 prBssDesc->fgIsHTPresent = FALSE;
1763 prBssDesc->eSco = CHNL_EXT_SCN;
1764 prBssDesc->fgIEWAPI = FALSE;
1765 #if CFG_RSN_MIGRATION
1766 prBssDesc->fgIERSN = FALSE;
1768 #if CFG_PRIVACY_MIGRATION
1769 prBssDesc->fgIEWPA = FALSE;
1773 //4 <3.1> Full IE parsing on SW_RFB_T
1774 pucIE = prWlanBeaconFrame->aucInfoElem;
1777 IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
1779 switch (IE_ID(pucIE)) {
1781 if ((!prIeSsid) && /* NOTE(Kevin): for Atheros IOT #1 */
1782 (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) {
1783 BOOLEAN fgIsHiddenSSID = FALSE;
1787 prIeSsid = (P_IE_SSID_T)pucIE;
1789 /* D-Link DWL-900AP+ */
1790 if (IE_LEN(pucIE) == 0) {
1791 fgIsHiddenSSID = TRUE;
1793 /* Cisco AP1230A - (IE_LEN(pucIE) == 1) && (SSID_IE(pucIE)->aucSSID[0] == '\0') */
1794 /* Linksys WRK54G/ASUS WL520g - (IE_LEN(pucIE) == n) && (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') */
1796 for (i = 0; i < IE_LEN(pucIE); i++) {
1797 ucSSIDChar |= SSID_IE(pucIE)->aucSSID[i];
1801 fgIsHiddenSSID = TRUE;
1805 /* Update SSID to BSS Descriptor only if SSID is not hidden. */
1806 if (!fgIsHiddenSSID) {
1807 COPY_SSID(prBssDesc->aucSSID,
1808 prBssDesc->ucSSIDLen,
1809 SSID_IE(pucIE)->aucSSID,
1810 SSID_IE(pucIE)->ucLength);
1816 case ELEM_ID_SUP_RATES:
1817 /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8.
1818 * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B),
1819 * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)"
1821 /* TP-LINK will set extra and incorrect ie with ELEM_ID_SUP_RATES */
1822 if ((!prIeSupportedRate) && (IE_LEN(pucIE) <= RATE_NUM)) {
1823 prIeSupportedRate = SUP_RATES_IE(pucIE);
1827 case ELEM_ID_DS_PARAM_SET:
1828 if (IE_LEN(pucIE) == ELEM_MAX_LEN_DS_PARAMETER_SET) {
1829 ucIeDsChannelNum = DS_PARAM_IE(pucIE)->ucCurrChnl;
1834 if (IE_LEN(pucIE) <= ELEM_MAX_LEN_TIM) {
1835 prBssDesc->ucDTIMPeriod = TIM_IE(pucIE)->ucDTIMPeriod;
1839 case ELEM_ID_IBSS_PARAM_SET:
1840 if (IE_LEN(pucIE) == ELEM_MAX_LEN_IBSS_PARAMETER_SET){
1841 prBssDesc->u2ATIMWindow = IBSS_PARAM_IE(pucIE)->u2ATIMWindow;
1845 #if 0 //CFG_SUPPORT_802_11D
1846 case ELEM_ID_COUNTRY_INFO:
1847 prBssDesc->prIECountry = (P_IE_COUNTRY_T)pucIE;
1851 case ELEM_ID_ERP_INFO:
1852 if (IE_LEN(pucIE) == ELEM_MAX_LEN_ERP) {
1853 prBssDesc->fgIsERPPresent = TRUE;
1857 case ELEM_ID_EXTENDED_SUP_RATES:
1858 if (!prIeExtSupportedRate) {
1859 prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE);
1863 #if CFG_RSN_MIGRATION
1865 if (rsnParseRsnIE(prAdapter, RSN_IE(pucIE), &prBssDesc->rRSNInfo)) {
1866 prBssDesc->fgIERSN = TRUE;
1867 prBssDesc->u2RsnCap = prBssDesc->rRSNInfo.u2RsnCap;
1868 if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) {
1869 rsnCheckPmkidCache(prAdapter, prBssDesc);
1875 case ELEM_ID_HT_CAP:
1876 prBssDesc->fgIsHTPresent = TRUE;
1880 if (IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) {
1884 if ((((P_IE_HT_OP_T) pucIE)->ucInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) {
1885 prBssDesc->eSco = (ENUM_CHNL_EXT_T)
1886 (((P_IE_HT_OP_T) pucIE)->ucInfo1 & HT_OP_INFO1_SCO);
1888 ucIeHtChannelNum = ((P_IE_HT_OP_T) pucIE)->ucPrimaryChannel;
1892 #if CFG_SUPPORT_WAPI
1894 if (wapiParseWapiIE(WAPI_IE(pucIE), &prBssDesc->rIEWAPI)) {
1895 prBssDesc->fgIEWAPI = TRUE;
1900 case ELEM_ID_VENDOR: // ELEM_ID_P2P, ELEM_ID_WMM
1903 UINT_16 u2SubTypeVersion;
1904 #if CFG_PRIVACY_MIGRATION
1905 if (rsnParseCheckForWFAInfoElem(prAdapter, pucIE, &ucOuiType, &u2SubTypeVersion)) {
1906 if ((ucOuiType == VENDOR_OUI_TYPE_WPA) &&
1907 (u2SubTypeVersion == VERSION_WPA)) {
1909 if (rsnParseWpaIE(prAdapter, WPA_IE(pucIE), &prBssDesc->rWPAInfo)) {
1910 prBssDesc->fgIEWPA = TRUE;
1916 #if CFG_ENABLE_WIFI_DIRECT
1917 if(prAdapter->fgIsP2PRegistered) {
1918 if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType)) {
1919 if (ucOuiType == VENDOR_OUI_TYPE_P2P) {
1920 prBssDesc->fgIsP2PPresent = TRUE;
1924 #endif /* CFG_ENABLE_WIFI_DIRECT */
1933 //4 <3.2> Save information from IEs - SSID
1934 /* Update Flag of Hidden SSID for used in SEARCH STATE. */
1936 /* NOTE(Kevin): in current driver, the ucSSIDLen == 0 represent
1937 * all cases of hidden SSID.
1938 * If the fgIsHiddenSSID == TRUE, it means we didn't get the ProbeResp with
1941 if (prBssDesc->ucSSIDLen == 0) {
1942 prBssDesc->fgIsHiddenSSID = TRUE;
1945 prBssDesc->fgIsHiddenSSID = FALSE;
1949 //4 <3.3> Check rate information in related IEs.
1950 if (prIeSupportedRate || prIeExtSupportedRate) {
1951 rateGetRateSetFromIEs(prIeSupportedRate,
1952 prIeExtSupportedRate,
1953 &prBssDesc->u2OperationalRateSet,
1954 &prBssDesc->u2BSSBasicRateSet,
1955 &prBssDesc->fgIsUnknownBssBasicRate);
1959 //4 <4> Update information from HIF RX Header
1961 prHifRxHdr = prSwRfb->prHifRxHdr;
1965 //4 <4.1> Get TSF comparison result
1966 prBssDesc->fgIsLargerTSF = HIF_RX_HDR_GET_TCL_FLAG(prHifRxHdr);
1968 //4 <4.2> Get Band information
1969 prBssDesc->eBand = HIF_RX_HDR_GET_RF_BAND(prHifRxHdr);
1971 //4 <4.2> Get channel and RCPI information
1972 ucHwChannelNum = HIF_RX_HDR_GET_CHNL_NUM(prHifRxHdr);
1974 if (BAND_2G4 == prBssDesc->eBand) {
1976 /* Update RCPI if in right channel */
1977 if (ucIeDsChannelNum >= 1 && ucIeDsChannelNum <= 14) {
1979 // Receive Beacon/ProbeResp frame from adjacent channel.
1980 if ((ucIeDsChannelNum == ucHwChannelNum) ||
1981 (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) {
1982 prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
1985 // trust channel information brought by IE
1986 prBssDesc->ucChannelNum = ucIeDsChannelNum;
1988 else if(ucIeHtChannelNum >= 1 && ucIeHtChannelNum <= 14) {
1989 // Receive Beacon/ProbeResp frame from adjacent channel.
1990 if ((ucIeHtChannelNum == ucHwChannelNum) ||
1991 (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) {
1992 prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
1995 // trust channel information brought by IE
1996 prBssDesc->ucChannelNum = ucIeHtChannelNum;
1999 prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
2001 prBssDesc->ucChannelNum = ucHwChannelNum;
2006 if(ucIeHtChannelNum >= 1 && ucIeHtChannelNum < 200) {
2007 // Receive Beacon/ProbeResp frame from adjacent channel.
2008 if ((ucIeHtChannelNum == ucHwChannelNum) ||
2009 (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) {
2010 prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
2013 // trust channel information brought by IE
2014 prBssDesc->ucChannelNum = ucIeHtChannelNum;
2017 /* Always update RCPI */
2018 prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
2020 prBssDesc->ucChannelNum = ucHwChannelNum;
2026 //4 <5> PHY type setting
2027 prBssDesc->ucPhyTypeSet = 0;
2029 if (BAND_2G4 == prBssDesc->eBand) {
2030 /* check if support 11n */
2031 if (prBssDesc->fgIsHTPresent) {
2032 prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT;
2035 /* if not 11n only */
2036 if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) {
2037 /* check if support 11g */
2038 if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM) ||
2039 prBssDesc->fgIsERPPresent) {
2040 prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_ERP;
2043 /* if not 11g only */
2044 if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_OFDM)) {
2045 /* check if support 11b */
2046 if ((prBssDesc->u2OperationalRateSet & RATE_SET_HR_DSSS)) {
2047 prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS;
2052 else { /* (BAND_5G == prBssDesc->eBande) */
2053 /* check if support 11n */
2054 if (prBssDesc->fgIsHTPresent) {
2055 prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT;
2058 /* if not 11n only */
2059 if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) {
2060 /* Support 11a definitely */
2061 prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM;
2063 ASSERT(!(prBssDesc->u2OperationalRateSet & RATE_SET_HR_DSSS));
2068 //4 <6> Update BSS_DESC_T's Last Update TimeStamp.
2069 GET_CURRENT_SYSTIME(&prBssDesc->rUpdateTime);
2075 /*----------------------------------------------------------------------------*/
2077 * @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to scan result for query
2079 * @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure.
2081 * @retval WLAN_STATUS_SUCCESS It is a valid Scan Result and been sent to the host.
2082 * @retval WLAN_STATUS_FAILURE It is not a valid Scan Result.
2084 /*----------------------------------------------------------------------------*/
2087 IN P_ADAPTER_T prAdapter,
2088 IN P_BSS_DESC_T prBssDesc,
2089 IN P_SW_RFB_T prSwRfb
2092 P_SCAN_INFO_T prScanInfo;
2093 UINT_8 aucRatesEx[PARAM_MAX_LEN_RATES_EX];
2094 P_WLAN_BEACON_FRAME_T prWlanBeaconFrame;
2095 PARAM_MAC_ADDRESS rMacAddr;
2097 ENUM_PARAM_NETWORK_TYPE_T eNetworkType;
2098 PARAM_802_11_CONFIG_T rConfiguration;
2099 ENUM_PARAM_OP_MODE_T eOpMode;
2100 UINT_8 ucRateLen = 0;
2106 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
2108 if (prBssDesc->eBand == BAND_2G4) {
2109 if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM)
2110 || prBssDesc->fgIsERPPresent) {
2111 eNetworkType = PARAM_NETWORK_TYPE_OFDM24;
2114 eNetworkType = PARAM_NETWORK_TYPE_DS;
2118 ASSERT(prBssDesc->eBand == BAND_5G);
2119 eNetworkType = PARAM_NETWORK_TYPE_OFDM5;
2122 if(prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) {
2123 /* NOTE(Kevin): Not supported by WZC(TBD) */
2124 return WLAN_STATUS_FAILURE;
2127 prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T)prSwRfb->pvHeader;
2128 COPY_MAC_ADDR(rMacAddr, prWlanBeaconFrame->aucBSSID);
2129 COPY_SSID(rSsid.aucSsid,
2132 prBssDesc->ucSSIDLen);
2134 rConfiguration.u4Length = sizeof(PARAM_802_11_CONFIG_T);
2135 rConfiguration.u4BeaconPeriod = (UINT_32) prWlanBeaconFrame->u2BeaconInterval;
2136 rConfiguration.u4ATIMWindow = prBssDesc->u2ATIMWindow;
2137 rConfiguration.u4DSConfig = nicChannelNum2Freq(prBssDesc->ucChannelNum);
2138 rConfiguration.rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T);
2140 rateGetDataRatesFromRateSet(prBssDesc->u2OperationalRateSet,
2145 /* NOTE(Kevin): Set unused entries, if any, at the end of the array to 0.
2146 * from OID_802_11_BSSID_LIST
2148 for (i = ucRateLen; i < sizeof(aucRatesEx) / sizeof(aucRatesEx[0]) ; i++) {
2152 switch(prBssDesc->eBSSType) {
2154 eOpMode = NET_TYPE_IBSS;
2157 case BSS_TYPE_INFRASTRUCTURE:
2158 case BSS_TYPE_P2P_DEVICE:
2159 case BSS_TYPE_BOW_DEVICE:
2161 eOpMode = NET_TYPE_INFRA;
2165 kalIndicateBssInfo(prAdapter->prGlueInfo,
2166 (PUINT_8)prSwRfb->pvHeader,
2167 prSwRfb->u2PacketLen,
2168 prBssDesc->ucChannelNum,
2169 RCPI_TO_dBm(prBssDesc->ucRCPI));
2171 nicAddScanResult(prAdapter,
2174 prWlanBeaconFrame->u2CapInfo & CAP_INFO_PRIVACY ? 1 : 0,
2175 RCPI_TO_dBm(prBssDesc->ucRCPI),
2180 prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen,
2181 (PUINT_8)((UINT_32)(prSwRfb->pvHeader) + WLAN_MAC_MGMT_HEADER_LEN));
2183 return WLAN_STATUS_SUCCESS;
2185 } /* end of scanAddScanResult() */
2188 /*----------------------------------------------------------------------------*/
2190 * @brief Parse the content of given Beacon or ProbeResp Frame.
2192 * @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure.
2194 * @retval WLAN_STATUS_SUCCESS if not report this SW_RFB_T to host
2195 * @retval WLAN_STATUS_PENDING if report this SW_RFB_T to host as scan result
2197 /*----------------------------------------------------------------------------*/
2199 scanProcessBeaconAndProbeResp (
2200 IN P_ADAPTER_T prAdapter,
2201 IN P_SW_RFB_T prSwRfb
2204 P_CONNECTION_SETTINGS_T prConnSettings;
2205 P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T)NULL;
2206 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2207 P_BSS_INFO_T prAisBssInfo;
2208 P_WLAN_BEACON_FRAME_T prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T)NULL;
2210 P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T)NULL;
2216 //4 <0> Ignore invalid Beacon Frame
2217 if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) <
2218 (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN)) {
2226 prSltInfo = &prAdapter->rWifiVar.rSltInfo;
2228 if (prSltInfo->fgIsDUT) {
2229 DBGLOG(P2P, INFO, ("\n\rBCN: RX\n"));
2230 prSltInfo->u4BeaconReceiveCnt++;
2231 return WLAN_STATUS_SUCCESS;
2234 return WLAN_STATUS_SUCCESS;
2239 prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
2240 prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
2241 prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T)prSwRfb->pvHeader;
2243 //4 <1> Parse and add into BSS_DESC_T
2244 prBssDesc = scanAddToBssDesc(prAdapter, prSwRfb);
2248 //4 <1.1> Beacon Change Detection for Connected BSS
2249 if(prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED &&
2250 ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && prConnSettings->eOPMode != NET_TYPE_IBSS)
2251 || (prBssDesc->eBSSType == BSS_TYPE_IBSS && prConnSettings->eOPMode != NET_TYPE_INFRA)) &&
2252 EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID) &&
2253 EQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen)) {
2254 BOOLEAN fgNeedDisconnect = FALSE;
2256 #if CFG_SUPPORT_BEACON_CHANGE_DETECTION
2257 // <1.1.2> check if supported rate differs
2258 if(prAisBssInfo->u2OperationalRateSet != prBssDesc->u2OperationalRateSet) {
2259 fgNeedDisconnect = TRUE;
2263 // <1.1.3> beacon content change detected, disconnect immediately
2264 if(fgNeedDisconnect == TRUE) {
2265 aisBssBeaconTimeout(prAdapter);
2269 //4 <1.1> Update AIS_BSS_INFO
2270 if(((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && prConnSettings->eOPMode != NET_TYPE_IBSS)
2271 || (prBssDesc->eBSSType == BSS_TYPE_IBSS && prConnSettings->eOPMode != NET_TYPE_INFRA))) {
2272 if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
2274 /* *not* checking prBssDesc->fgIsConnected anymore,
2275 * due to Linksys AP uses " " as hidden SSID, and would have different BSS descriptor */
2276 if ((!prAisBssInfo->ucDTIMPeriod) &&
2277 EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID) &&
2278 (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) &&
2279 ((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_BEACON)) {
2281 prAisBssInfo->ucDTIMPeriod = prBssDesc->ucDTIMPeriod;
2283 /* sync with firmware for beacon information */
2284 nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_AIS_INDEX);
2288 #if CFG_SUPPORT_ADHOC
2289 if (EQUAL_SSID(prBssDesc->aucSSID,
2290 prBssDesc->ucSSIDLen,
2291 prConnSettings->aucSSID,
2292 prConnSettings->ucSSIDLen) &&
2293 (prBssDesc->eBSSType == BSS_TYPE_IBSS) &&
2294 (prAisBssInfo->eCurrentOPMode == OP_MODE_IBSS)) {
2296 ibssProcessMatchedBeacon(prAdapter, prAisBssInfo, prBssDesc, prSwRfb->prHifRxHdr->ucRcpi);
2298 #endif /* CFG_SUPPORT_ADHOC */
2301 rlmProcessBcn(prAdapter,
2303 ((P_WLAN_BEACON_FRAME_T)(prSwRfb->pvHeader))->aucInfoElem,
2304 (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
2305 (UINT_16)(OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0])));
2307 //4 <3> Send SW_RFB_T to HIF when we perform SCAN for HOST
2308 if(prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE
2309 || prBssDesc->eBSSType == BSS_TYPE_IBSS) {
2310 /* for AIS, send to host */
2311 if (prConnSettings->fgIsScanReqIssued &&
2312 rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum) == TRUE) {
2315 BOOLEAN fgAddToScanResult;
2317 /* check ucChannelNum/eBand for adjacement channel filtering */
2318 if(cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel) == TRUE &&
2319 (eBand != prBssDesc->eBand || ucChannel != prBssDesc->ucChannelNum)) {
2320 fgAddToScanResult = FALSE;
2323 fgAddToScanResult = TRUE;
2326 if(fgAddToScanResult == TRUE) {
2327 rStatus = scanAddScanResult(prAdapter, prBssDesc, prSwRfb);
2332 #if CFG_ENABLE_WIFI_DIRECT
2333 if(prAdapter->fgIsP2PRegistered) {
2334 scanP2pProcessBeaconAndProbeResp(
2346 } /* end of scanProcessBeaconAndProbeResp() */
2349 /*----------------------------------------------------------------------------*/
2351 * \brief Search the Candidate of BSS Descriptor for JOIN(Infrastructure) or
2352 * MERGE(AdHoc) according to current Connection Policy.
2354 * \return Pointer to BSS Descriptor, if found. NULL, if not found
2356 /*----------------------------------------------------------------------------*/
2358 scanSearchBssDescByPolicy (
2359 IN P_ADAPTER_T prAdapter,
2360 IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex
2363 P_CONNECTION_SETTINGS_T prConnSettings;
2364 P_BSS_INFO_T prBssInfo;
2365 P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
2366 P_SCAN_INFO_T prScanInfo;
2368 P_LINK_T prBSSDescList;
2370 P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T)NULL;
2371 P_BSS_DESC_T prPrimaryBssDesc = (P_BSS_DESC_T)NULL;
2372 P_BSS_DESC_T prCandidateBssDesc = (P_BSS_DESC_T)NULL;
2374 P_STA_RECORD_T prStaRec = (P_STA_RECORD_T)NULL;
2375 P_STA_RECORD_T prPrimaryStaRec;
2376 P_STA_RECORD_T prCandidateStaRec = (P_STA_RECORD_T)NULL;
2378 OS_SYSTIME rCurrentTime;
2380 /* The first one reach the check point will be our candidate */
2381 BOOLEAN fgIsFindFirst = (BOOLEAN)FALSE;
2383 BOOLEAN fgIsFindBestRSSI = (BOOLEAN)FALSE;
2384 BOOLEAN fgIsFindBestEncryptionLevel = (BOOLEAN)FALSE;
2385 //BOOLEAN fgIsFindMinChannelLoad = (BOOLEAN)FALSE;
2387 /* TODO(Kevin): Support Min Channel Load */
2388 //UINT_8 aucChannelLoad[CHANNEL_NUM] = {0};
2390 BOOLEAN fgIsFixedChannel;
2396 prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
2397 prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]);
2399 prAisSpecBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo);
2401 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
2402 prBSSDescList = &prScanInfo->rBSSDescList;
2404 GET_CURRENT_SYSTIME(&rCurrentTime);
2406 /* check for fixed channel operation */
2407 if(eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) {
2408 fgIsFixedChannel = cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel);
2411 fgIsFixedChannel = FALSE;
2415 if (prConnSettings->ucSSIDLen < ELEM_MAX_LEN_SSID) {
2416 prConnSettings->aucSSID[prConnSettings->ucSSIDLen] = '\0';
2420 DBGLOG(SCN, INFO, ("SEARCH: Num Of BSS_DESC_T = %d, Look for SSID: %s\n",
2421 prBSSDescList->u4NumElem, prConnSettings->aucSSID));
2424 //4 <1> The outer loop to search for a candidate.
2425 LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
2427 /* TODO(Kevin): Update Minimum Channel Load Information here */
2429 DBGLOG(SCN, INFO, ("SEARCH: ["MACSTR"], SSID:%s\n",
2430 MAC2STR(prBssDesc->aucBSSID), prBssDesc->aucSSID));
2433 //4 <2> Check PHY Type and attributes
2434 //4 <2.1> Check Unsupported BSS PHY Type
2435 if (!(prBssDesc->ucPhyTypeSet & (prAdapter->rWifiVar.ucAvailablePhyTypeSet))) {
2437 DBGLOG(SCN, INFO, ("SEARCH: Ignore unsupported ucPhyTypeSet = %x\n",
2438 prBssDesc->ucPhyTypeSet));
2442 //4 <2.2> Check if has unknown NonHT BSS Basic Rate Set.
2443 if (prBssDesc->fgIsUnknownBssBasicRate) {
2448 //4 <2.3> Check if fixed operation cases should be aware
2449 if (fgIsFixedChannel == TRUE &&
2450 (prBssDesc->eBand != eBand || prBssDesc->ucChannelNum != ucChannel)) {
2454 //4 <2.4> Check if the channel is legal under regulatory domain
2455 if(rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum) == FALSE) {
2459 //4 <2.5> Check if this BSS_DESC_T is stale
2460 if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
2461 SEC_TO_SYSTIME(SCN_BSS_DESC_REMOVE_TIMEOUT_SEC)) ) {
2466 //4 <3> Check if reach the excessive join retry limit
2467 /* NOTE(Kevin): STA_RECORD_T is recorded by TA. */
2468 prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) eNetTypeIndex,
2469 prBssDesc->aucSrcAddr);
2473 * The Status Code is the result of a Previous Connection Request, we use this as SCORE for choosing a proper
2474 * candidate (Also used for compare see <6>)
2475 * The Reason Code is an indication of the reason why AP reject us, we use this Code for "Reject"
2476 * a SCAN result to become our candidate(Like a blacklist).
2478 #if 0 /* TODO(Kevin): */
2479 if (prStaRec->u2ReasonCode != REASON_CODE_RESERVED) {
2480 DBGLOG(SCN, INFO, ("SEARCH: Ignore BSS with previous Reason Code = %d\n",
2481 prStaRec->u2ReasonCode));
2486 if (prStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL) {
2487 /* NOTE(Kevin): greedy association - after timeout, we'll still
2488 * try to associate to the AP whose STATUS of conection attempt
2490 * We may also use (ucJoinFailureCount x JOIN_RETRY_INTERVAL_SEC) for
2493 if ((prStaRec->ucJoinFailureCount < JOIN_MAX_RETRY_FAILURE_COUNT) ||
2494 (CHECK_FOR_TIMEOUT(rCurrentTime,
2495 prStaRec->rLastJoinTime,
2496 SEC_TO_SYSTIME(JOIN_RETRY_INTERVAL_SEC)))) {
2498 /* NOTE(Kevin): Every JOIN_RETRY_INTERVAL_SEC interval, we can retry
2499 * JOIN_MAX_RETRY_FAILURE_COUNT times.
2501 if (prStaRec->ucJoinFailureCount >= JOIN_MAX_RETRY_FAILURE_COUNT) {
2502 prStaRec->ucJoinFailureCount = 0;
2504 DBGLOG(SCN, INFO, ("SEARCH: Try to join BSS again which has Status Code = %d (Curr = %ld/Last Join = %ld)\n",
2505 prStaRec->u2StatusCode, rCurrentTime, prStaRec->rLastJoinTime));
2508 DBGLOG(SCN, INFO, ("SEARCH: Ignore BSS which reach maximum Join Retry Count = %d \n",
2509 JOIN_MAX_RETRY_FAILURE_COUNT));
2517 //4 <4> Check for various NETWORK conditions
2518 if (eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) {
2520 //4 <4.1> Check BSS Type for the corresponding Operation Mode in Connection Setting
2521 /* NOTE(Kevin): For NET_TYPE_AUTO_SWITCH, we will always pass following check. */
2522 if (((prConnSettings->eOPMode == NET_TYPE_INFRA) &&
2523 (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE)) ||
2524 ((prConnSettings->eOPMode == NET_TYPE_IBSS || prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS) &&
2525 (prBssDesc->eBSSType != BSS_TYPE_IBSS))) {
2527 DBGLOG(SCN, INFO, ("SEARCH: Ignore eBSSType = %s\n",
2528 ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) ?
2529 "INFRASTRUCTURE" : "IBSS")));
2533 //4 <4.2> Check AP's BSSID if OID_802_11_BSSID has been set.
2534 if ((prConnSettings->fgIsConnByBssidIssued) &&
2535 (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE)) {
2537 if (UNEQUAL_MAC_ADDR(prConnSettings->aucBSSID, prBssDesc->aucBSSID)) {
2539 DBGLOG(SCN, INFO, ("SEARCH: Ignore due to BSSID was not matched!\n"));
2544 #if CFG_SUPPORT_ADHOC
2545 //4 <4.3> Check for AdHoc Mode
2546 if (prBssDesc->eBSSType == BSS_TYPE_IBSS) {
2547 OS_SYSTIME rCurrentTime;
2549 //4 <4.3.1> Check if this SCAN record has been updated recently for IBSS.
2550 /* NOTE(Kevin): Because some STA may change its BSSID frequently after it
2551 * create the IBSS - e.g. IPN2220, so we need to make sure we get the new one.
2552 * For BSS, if the old record was matched, however it won't be able to pass
2553 * the Join Process later.
2555 GET_CURRENT_SYSTIME(&rCurrentTime);
2556 if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
2557 SEC_TO_SYSTIME(SCN_ADHOC_BSS_DESC_TIMEOUT_SEC))) {
2558 DBGLOG(SCN, LOUD, ("SEARCH: Skip old record of BSS Descriptor - BSSID:["MACSTR"]\n\n",
2559 MAC2STR(prBssDesc->aucBSSID)));
2563 //4 <4.3.2> Check Peer's capability
2564 if (ibssCheckCapabilityForAdHocMode(prAdapter, prBssDesc) == WLAN_STATUS_FAILURE) {
2567 ("SEARCH: Ignore BSS DESC MAC: "MACSTR", Capability is not supported for current AdHoc Mode.\n",
2568 MAC2STR(prPrimaryBssDesc->aucBSSID)));
2574 //4 <4.3.3> Compare TSF
2575 if (prBssInfo->fgIsBeaconActivated &&
2576 UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID)) {
2579 ("SEARCH: prBssDesc->fgIsLargerTSF = %d\n",
2580 prBssDesc->fgIsLargerTSF));
2582 if (!prBssDesc->fgIsLargerTSF) {
2584 ("SEARCH: Ignore BSS DESC MAC: ["MACSTR"], Smaller TSF\n", MAC2STR(prBssDesc->aucBSSID)));
2589 #endif /* CFG_SUPPORT_ADHOC */
2596 #if 0 /* TODO(Kevin): For IBSS */
2597 //4 <2.c> Check if this SCAN record has been updated recently for IBSS.
2598 /* NOTE(Kevin): Because some STA may change its BSSID frequently after it
2599 * create the IBSS, so we need to make sure we get the new one.
2600 * For BSS, if the old record was matched, however it won't be able to pass
2601 * the Join Process later.
2603 if (prBssDesc->eBSSType == BSS_TYPE_IBSS) {
2604 OS_SYSTIME rCurrentTime;
2606 GET_CURRENT_SYSTIME(&rCurrentTime);
2607 if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
2608 SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) {
2609 DBGLOG(SCAN, TRACE, ("Skip old record of BSS Descriptor - BSSID:["MACSTR"]\n\n",
2610 MAC2STR(prBssDesc->aucBSSID)));
2615 if ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) &&
2616 (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED)) {
2617 OS_SYSTIME rCurrentTime;
2619 GET_CURRENT_SYSTIME(&rCurrentTime);
2620 if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
2621 SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) {
2622 DBGLOG(SCAN, TRACE, ("Skip old record of BSS Descriptor - BSSID:["MACSTR"]\n\n",
2623 MAC2STR(prBssDesc->aucBSSID)));
2629 //4 <4B> Check for IBSS AdHoc Mode.
2630 /* Skip if one or more BSS Basic Rate are not supported by current AdHocMode */
2631 if (prPrimaryBssDesc->eBSSType == BSS_TYPE_IBSS) {
2632 //4 <4B.1> Check if match the Capability of current IBSS AdHoc Mode.
2633 if (ibssCheckCapabilityForAdHocMode(prAdapter, prPrimaryBssDesc) == WLAN_STATUS_FAILURE) {
2636 ("Ignore BSS DESC MAC: "MACSTR", Capability is not supported for current AdHoc Mode.\n",
2637 MAC2STR(prPrimaryBssDesc->aucBSSID)));
2643 //4 <4B.2> IBSS Merge Decision Flow for SEARCH STATE.
2644 if (prAdapter->fgIsIBSSActive &&
2645 UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prPrimaryBssDesc->aucBSSID)) {
2647 if (!fgIsLocalTSFRead) {
2648 NIC_GET_CURRENT_TSF(prAdapter, &rCurrentTsf);
2651 ("\n\nCurrent TSF : %08lx-%08lx\n\n",
2652 rCurrentTsf.u.HighPart, rCurrentTsf.u.LowPart));
2655 if (rCurrentTsf.QuadPart > prPrimaryBssDesc->u8TimeStamp.QuadPart) {
2657 ("Ignore BSS DESC MAC: ["MACSTR"], Current BSSID: ["MACSTR"].\n",
2658 MAC2STR(prPrimaryBssDesc->aucBSSID), MAC2STR(prBssInfo->aucBSSID)));
2661 ("\n\nBSS's TSF : %08lx-%08lx\n\n",
2662 prPrimaryBssDesc->u8TimeStamp.u.HighPart, prPrimaryBssDesc->u8TimeStamp.u.LowPart));
2664 prPrimaryBssDesc->fgIsLargerTSF = FALSE;
2668 prPrimaryBssDesc->fgIsLargerTSF = TRUE;
2674 //4 <5> Check the Encryption Status.
2675 if (rsnPerformPolicySelection(prPrimaryBssDesc)) {
2677 if (prPrimaryBssDesc->ucEncLevel > 0) {
2678 fgIsFindBestEncryptionLevel = TRUE;
2680 fgIsFindFirst = FALSE;
2684 /* Can't pass the Encryption Status Check, get next one */
2688 /* For RSN Pre-authentication, update the PMKID canidate list for
2689 same SSID and encrypt status */
2690 /* Update PMKID candicate list. */
2691 if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) {
2692 rsnUpdatePmkidCandidateList(prPrimaryBssDesc);
2693 if (prAdapter->rWifiVar.rAisBssInfo.u4PmkidCandicateCount) {
2694 prAdapter->rWifiVar.rAisBssInfo.fgIndicatePMKID = rsnCheckPmkidCandicate();
2701 prPrimaryBssDesc = (P_BSS_DESC_T)NULL;
2703 //4 <6> Check current Connection Policy.
2704 switch (prConnSettings->eConnectionPolicy) {
2705 case CONNECT_BY_SSID_BEST_RSSI:
2706 /* Choose Hidden SSID to join only if the `fgIsEnableJoin...` is TRUE */
2707 if (prAdapter->rWifiVar.fgEnableJoinToHiddenSSID && prBssDesc->fgIsHiddenSSID) {
2708 /* NOTE(Kevin): following if () statement means that
2709 * If Target is hidden, then we won't connect when user specify SSID_ANY policy.
2711 if (prConnSettings->ucSSIDLen) {
2712 prPrimaryBssDesc = prBssDesc;
2714 fgIsFindBestRSSI = TRUE;
2718 else if (EQUAL_SSID(prBssDesc->aucSSID,
2719 prBssDesc->ucSSIDLen,
2720 prConnSettings->aucSSID,
2721 prConnSettings->ucSSIDLen)) {
2722 prPrimaryBssDesc = prBssDesc;
2724 fgIsFindBestRSSI = TRUE;
2728 case CONNECT_BY_SSID_ANY:
2729 /* NOTE(Kevin): In this policy, we don't know the desired
2730 * SSID from user, so we should exclude the Hidden SSID from scan list.
2731 * And because we refuse to connect to Hidden SSID node at the beginning, so
2732 * when the JOIN Module deal with a BSS_DESC_T which has fgIsHiddenSSID == TRUE,
2733 * then the Connection Settings must be valid without doubt.
2735 if (!prBssDesc->fgIsHiddenSSID) {
2736 prPrimaryBssDesc = prBssDesc;
2738 fgIsFindFirst = TRUE;
2742 case CONNECT_BY_BSSID:
2743 if(EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prConnSettings->aucBSSID)) {
2744 prPrimaryBssDesc = prBssDesc;
2753 /* Primary Candidate was not found */
2754 if (prPrimaryBssDesc == NULL) {
2758 //4 <7> Check the Encryption Status.
2759 if (prPrimaryBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) {
2760 #if CFG_SUPPORT_WAPI
2761 if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) {
2762 if (wapiPerformPolicySelection(prAdapter, prPrimaryBssDesc)) {
2763 fgIsFindFirst = TRUE;
2766 /* Can't pass the Encryption Status Check, get next one */
2772 #if CFG_RSN_MIGRATION
2773 if (rsnPerformPolicySelection(prAdapter, prPrimaryBssDesc)) {
2774 if (prAisSpecBssInfo->fgCounterMeasure) {
2775 DBGLOG(RSN, INFO, ("Skip while at counter measure period!!!\n"));
2779 if (prPrimaryBssDesc->ucEncLevel > 0) {
2780 fgIsFindBestEncryptionLevel = TRUE;
2782 fgIsFindFirst = FALSE;
2786 /* Update PMKID candicate list. */
2787 if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) {
2788 rsnUpdatePmkidCandidateList(prPrimaryBssDesc);
2789 if (prAisSpecBssInfo->u4PmkidCandicateCount) {
2790 if (rsnCheckPmkidCandicate()) {
2791 DBGLOG(RSN, WARN, ("Prepare a timer to indicate candidate "MACSTR"\n",
2792 MAC2STR(prAisSpecBssInfo->arPmkidCache[prAisSpecBssInfo->u4PmkidCacheCount].rBssidInfo.aucBssid)));
2793 cnmTimerStopTimer(&prAisSpecBssInfo->rPreauthenticationTimer);
2794 cnmTimerStartTimer(&prAisSpecBssInfo->rPreauthenticationTimer,
2795 SEC_TO_MSEC(WAIT_TIME_IND_PMKID_CANDICATE_SEC));
2802 /* Can't pass the Encryption Status Check, get next one */
2808 /* Todo:: P2P and BOW Policy Selection */
2811 prPrimaryStaRec = prStaRec;
2813 //4 <8> Compare the Candidate and the Primary Scan Record.
2814 if (!prCandidateBssDesc) {
2815 prCandidateBssDesc = prPrimaryBssDesc;
2816 prCandidateStaRec = prPrimaryStaRec;
2818 //4 <8.1> Condition - Get the first matched one.
2819 if (fgIsFindFirst) {
2824 #if 0 /* TODO(Kevin): For security(TBD) */
2825 //4 <6B> Condition - Choose the one with best Encryption Score.
2826 if (fgIsFindBestEncryptionLevel) {
2827 if (prCandidateBssDesc->ucEncLevel <
2828 prPrimaryBssDesc->ucEncLevel) {
2830 prCandidateBssDesc = prPrimaryBssDesc;
2831 prCandidateStaRec = prPrimaryStaRec;
2836 /* If reach here, that means they have the same Encryption Score.
2839 //4 <6C> Condition - Give opportunity to the one we didn't connect before.
2840 // For roaming, only compare the candidates other than current associated BSSID.
2841 if (!prCandidateBssDesc->fgIsConnected && !prPrimaryBssDesc->fgIsConnected) {
2842 if ((prCandidateStaRec != (P_STA_RECORD_T)NULL) &&
2843 (prCandidateStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL)) {
2845 DBGLOG(SCAN, TRACE, ("So far -BSS DESC MAC: "MACSTR" has nonzero Status Code = %d\n",
2846 MAC2STR(prCandidateBssDesc->aucBSSID), prCandidateStaRec->u2StatusCode));
2848 if (prPrimaryStaRec != (P_STA_RECORD_T)NULL) {
2849 if (prPrimaryStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL) {
2851 /* Give opportunity to the one with smaller rLastJoinTime */
2852 if (TIME_BEFORE(prCandidateStaRec->rLastJoinTime,
2853 prPrimaryStaRec->rLastJoinTime)) {
2856 /* We've connect to CANDIDATE recently, let us try PRIMARY now */
2858 prCandidateBssDesc = prPrimaryBssDesc;
2859 prCandidateStaRec = prPrimaryStaRec;
2863 /* PRIMARY's u2StatusCode = 0 */
2865 prCandidateBssDesc = prPrimaryBssDesc;
2866 prCandidateStaRec = prPrimaryStaRec;
2870 /* PRIMARY has no StaRec - We didn't connet to PRIMARY before */
2872 prCandidateBssDesc = prPrimaryBssDesc;
2873 prCandidateStaRec = prPrimaryStaRec;
2878 if ((prPrimaryStaRec != (P_STA_RECORD_T)NULL) &&
2879 (prPrimaryStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL)) {
2887 //4 <6D> Condition - Visible SSID win Hidden SSID.
2888 if (prCandidateBssDesc->fgIsHiddenSSID) {
2889 if (!prPrimaryBssDesc->fgIsHiddenSSID) {
2890 prCandidateBssDesc = prPrimaryBssDesc; /* The non Hidden SSID win. */
2891 prCandidateStaRec = prPrimaryStaRec;
2896 if (prPrimaryBssDesc->fgIsHiddenSSID) {
2902 //4 <6E> Condition - Choose the one with better RCPI(RSSI).
2903 if (fgIsFindBestRSSI) {
2904 /* TODO(Kevin): We shouldn't compare the actual value, we should
2905 * allow some acceptable tolerance of some RSSI percentage here.
2907 DBGLOG(SCN, TRACE, ("Candidate ["MACSTR"]: RCPI = %d, Primary ["MACSTR"]: RCPI = %d\n",
2908 MAC2STR(prCandidateBssDesc->aucBSSID), prCandidateBssDesc->ucRCPI,
2909 MAC2STR(prPrimaryBssDesc->aucBSSID), prPrimaryBssDesc->ucRCPI));
2911 ASSERT(!(prCandidateBssDesc->fgIsConnected &&
2912 prPrimaryBssDesc->fgIsConnected));
2914 /* NOTE: To prevent SWING, we do roaming only if target AP has at least 5dBm larger than us. */
2915 if (prCandidateBssDesc->fgIsConnected) {
2916 if (prCandidateBssDesc->ucRCPI + ROAMING_NO_SWING_RCPI_STEP <= prPrimaryBssDesc->ucRCPI) {
2918 prCandidateBssDesc = prPrimaryBssDesc;
2919 prCandidateStaRec = prPrimaryStaRec;
2923 else if (prPrimaryBssDesc->fgIsConnected) {
2924 if (prCandidateBssDesc->ucRCPI < prPrimaryBssDesc->ucRCPI + ROAMING_NO_SWING_RCPI_STEP) {
2926 prCandidateBssDesc = prPrimaryBssDesc;
2927 prCandidateStaRec = prPrimaryStaRec;
2931 else if (prCandidateBssDesc->ucRCPI < prPrimaryBssDesc->ucRCPI) {
2932 prCandidateBssDesc = prPrimaryBssDesc;
2933 prCandidateStaRec = prPrimaryStaRec;
2939 /* If reach here, that means they have the same Encryption Score, and
2940 * both RSSI value are close too.
2942 //4 <6F> Seek the minimum Channel Load for less interference.
2943 if (fgIsFindMinChannelLoad) {
2945 /* TODO(Kevin): Check which one has minimum channel load in its channel */
2951 return prCandidateBssDesc;
2953 } /* end of scanSearchBssDescByPolicy() */