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 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.
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.
28 * 07 17 2012 yuche.tsai
30 * Let netdev bring up.
32 * 07 17 2012 yuche.tsai
34 * Compile no error before trial run.
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
42 * Sync CFG80211 modification from branch 2,2.
45 * [WCXRP00001169] [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration with corresponding network configuration
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.
53 * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path
54 * add CONNECT_BY_BSSID policy
57 * [WCXRP00001123] [MT6620 Wi-Fi][Driver] Add option to disable beacon content change detection
58 * add compile option to disable beacon content change detection.
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
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
69 * [WCXRP00001021] [MT5931][Driver] Correct scan result generation for conversion between BSS type and operation mode
70 * correct type casting issue.
72 * 08 23 2011 yuche.tsai
74 * Fix multicast address list issue.
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
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.
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
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
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
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.
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.
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
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
114 * 2. replace only BSS-DESC which doesn't have a valid SSID.
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.
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
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
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
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.
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
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.
146 * 04 14 2011 cm.chang
147 * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
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
156 * 03 25 2011 yuche.tsai
158 * Always update Bss Type, for Bss Type for P2P Network is changing every time.
160 * 03 23 2011 yuche.tsai
162 * Fix concurrent issue when AIS scan result would overwrite p2p scan result.
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
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.
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
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.
180 * 02 22 2011 yuche.tsai
181 * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue
182 * Fix WSC big endian issue.
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.
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.
192 * 01 26 2011 cm.chang
193 * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
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
200 * 01 14 2011 yuche.tsai
201 * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
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.
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.
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
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
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
226 * [WCXRP00000280] [MT6620 Wi-Fi][Driver] Enable BSS selection with best RCPI policy in SCN module
227 * SCN: enable BEST RSSI selection policy support
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
236 * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group
237 * Refine the HT rate disallow TKIP pairwise cipher .
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
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
248 * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine
249 * update the frog's new p2p state machine.
251 * 10 01 2010 yuche.tsai
253 * [MT6620 P2P] Fix Big Endian Issue when parse P2P device name TLV.
256 * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
257 * eliminate unused variables which lead gcc to argue
261 * use static memory pool for storing IEs of scanning result.
263 * 09 07 2010 yuche.tsai
265 * When indicate scan result, append IE buffer information in the scan result.
267 * 09 03 2010 yuche.tsai
269 * 1. Update Beacon RX count when running SLT.
270 * 2. Ignore Beacon when running SLT, would not update information from Beacon.
272 * 09 03 2010 kevin.huang
274 * Refine #include sequence and solve recursive/nested #include issue
276 * 08 31 2010 kevin.huang
278 * Use LINK LIST operation to process SCAN result
280 * 08 29 2010 yuche.tsai
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.
285 * 08 23 2010 yuche.tsai
287 * Add P2P Device Found Indication to supplicant
291 * reset BSS_DESC_T variables before parsing IE due to peer might have been reconfigured.
293 * 08 20 2010 yuche.tsai
295 * Workaround for P2P Descriptor Infinite loop issue.
299 * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI.
300 * There is no CFG_SUPPORT_BOW in driver domain source.
302 * 08 16 2010 yuche.tsai
304 * Modify code of processing Probe Resonse frame for P2P.
306 * 08 12 2010 yuche.tsai
308 * Add function to get P2P descriptor of BSS descriptor directly.
310 * 08 11 2010 yuche.tsai
312 * Modify Scan result processing for P2P module.
314 * 08 05 2010 yuche.tsai
316 * Update P2P Device Discovery result add function.
320 * surpress compilation warning.
322 * 07 26 2010 yuche.tsai
324 * Add support for Probe Request & Response parsing.
328 * 1) change BG_SCAN to ONLINE_SCAN for consistent term
329 * 2) only clear scanning result when scan is permitted to do
331 * 07 21 2010 yuche.tsai
333 * Fix compile error for SCAN module while disabling P2P feature.
335 * 07 21 2010 yuche.tsai
337 * Add P2P Scan & Scan Result Parsing & Saving.
341 * update for security supporting.
345 * [WPD00003833] [MT6620 and MT5931] Driver migration.
346 * Add Ad-Hoc support to AIS-FSM
350 * [WPD00003833] [MT6620 and MT5931] Driver migration.
351 * SCN module is now able to handle multiple concurrent scanning requests
355 * [WPD00003833] [MT6620 and MT5931] Driver migration.
356 * driver no longer generates probe request frames
360 * [WPD00003833] [MT6620 and MT5931] Driver migration.
361 * remove timer in DRV-SCN.
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
371 * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
374 * [WPD00003833][MT6620 and MT5931] Driver migration
375 * take use of RLM module for parsing/generating HT IEs for 11n capability
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
384 * [WPD00003833][MT6620 and MT5931] Driver migration
385 * correct BSS_DESC_T initialization after allocated.
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
394 * [WPD00003833][MT6620 and MT5931] Driver migration
395 * add scan uninitialization procedure
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
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
412 * [WPD00003833][MT6620 and MT5931] Driver migration
413 * send MMPDU in basic rate.
416 * [WPD00003833][MT6620 and MT5931] Driver migration
417 * modify Beacon/ProbeResp to complete parsing,
418 * because host software has looser memory usage restriction
421 * [WPD00003833][MT6620 and MT5931] Driver migration
425 * [WPD00003833][MT6620 and MT5931] Driver migration
426 * comment out RLM APIs by CFG_RLM_MIGRATION.
428 * 06 21 2010 yuche.tsai
429 * [WPD00003839][MT6620 5931][P2P] Feature migration
430 * Update P2P Function call.
433 * [WPD00003833][MT6620 and MT5931] Driver migration
434 * RSN/PRIVACY compilation flag awareness correction
437 * [WPD00003833][MT6620 and MT5931] Driver migration
438 * specify correct value for management frames.
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
445 * [WPD00003840][MT6620 5931] Security migration
446 * migration from MT6620 firmware.
448 * 06 17 2010 yuche.tsai
449 * [WPD00003839][MT6620 5931][P2P] Feature migration
450 * Fix compile error when enable P2P function.
453 * [WPD00003833][MT6620 and MT5931] Driver migration
454 * correct when ADHOC support is turned on.
457 * [WPD00003833][MT6620 and MT5931] Driver migration
460 * 06 04 2010 george.huang
461 * [BORA00000678][MT6620]WiFi LP integration
462 * [PM] Support U-APSD for STA mode
465 * [BORA00000680][MT6620] Support the statistic for Microsoft os query
466 * adding the TKIP disallow join a HT AP code.
468 * 05 14 2010 kevin.huang
469 * [BORA00000794][WIFISYS][New Feature]Power Management Support
470 * Add more chance of JOIN retry for BG_SCAN
472 * 05 12 2010 kevin.huang
473 * [BORA00000794][WIFISYS][New Feature]Power Management Support
474 * Add Power Management - Legacy PS-POLL support.
477 * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
478 * adjsut the pre-authentication code.
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
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
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
492 * 04 13 2010 kevin.huang
493 * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
494 * Add new HW CH macro support
497 * [BORA00000680][MT6620] Support the statistic for Microsoft os query
498 * fixed the firmware return the broadcast frame at wrong tc.
501 * [BORA00000605][WIFISYS] Phase3 Integration
502 * let the rsn wapi IE always parsing.
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
508 * 03 18 2010 kevin.huang
509 * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
510 * Solve the compile warning for 'return non-void' function
512 * 03 16 2010 kevin.huang
513 * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
516 * 03 10 2010 kevin.huang
517 * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support
519 * * * * * * * * * * * * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req
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.
526 * [BORA00000605][WIFISYS] Phase3 Integration
527 * Refine the variable and parameter for security.
529 * 02 26 2010 kevin.huang
530 * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
531 * Fix No PKT_INFO_T issue
533 * 02 26 2010 kevin.huang
534 * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
535 * Update outgoing ProbeRequest Frame's TX data rate
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.
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
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
550 * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
551 * add and fixed some security function.
553 * 01 22 2010 cm.chang
554 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
555 * Support protection and bandwidth switch
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
561 * 01 11 2010 kevin.huang
562 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
563 * Add Deauth and Disassoc Handler
565 * 01 08 2010 kevin.huang
566 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
568 * Refine Beacon processing, add read RF channel from RX Status
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
574 * 12 18 2009 cm.chang
575 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
578 * Dec 12 2009 mtk01104
579 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
580 * Modify u2EstimatedExtraIELen for probe request
582 * Dec 9 2009 mtk01104
583 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
584 * Add HT cap IE to probe request
586 * Dec 7 2009 mtk01461
587 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
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
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
599 * Nov 30 2009 mtk01461
600 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
601 * Rename u4RSSI to i4RSSI
603 * Nov 30 2009 mtk01461
604 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
605 * Report event of scan result to host
607 * Nov 26 2009 mtk01461
608 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
609 * Fix SCAN Record update
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
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
619 * Nov 20 2009 mtk02468
620 * [BORA00000337] To check in codes for FPGA emulation
621 * Removed the use of SW_RFB->u2FrameLength
623 * Nov 20 2009 mtk01461
624 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
625 * Fix uninitial aucMacAddress[] for ProbeReq
627 * Nov 16 2009 mtk01461
628 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
629 * Add scanSearchBssDescByPolicy()
631 * Nov 5 2009 mtk01461
632 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
633 * Add Send Probe Request Frame
635 * Oct 30 2009 mtk01461
636 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
640 /*******************************************************************************
641 * C O M P I L E R F L A G S
642 ********************************************************************************
645 /*******************************************************************************
646 * E X T E R N A L R E F E R E N C E S
647 ********************************************************************************
651 /*******************************************************************************
653 ********************************************************************************
655 #define REPLICATED_BEACON_TIME_THRESHOLD (3000)
656 #define REPLICATED_BEACON_FRESH_PERIOD (10000)
657 #define REPLICATED_BEACON_STRENGTH_THRESHOLD (32)
659 #define ROAMING_NO_SWING_RCPI_STEP (10)
661 /*******************************************************************************
663 ********************************************************************************
666 /*******************************************************************************
667 * P U B L I C D A T A
668 ********************************************************************************
671 /*******************************************************************************
672 * P R I V A T E D A T A
673 ********************************************************************************
676 /*******************************************************************************
678 ********************************************************************************
681 /*******************************************************************************
682 * F U N C T I O N D E C L A R A T I O N S
683 ********************************************************************************
686 /*******************************************************************************
688 ********************************************************************************
690 /*----------------------------------------------------------------------------*/
692 * @brief This function is used by SCN to initialize its variables
698 /*----------------------------------------------------------------------------*/
701 IN P_ADAPTER_T prAdapter
704 P_SCAN_INFO_T prScanInfo;
705 P_BSS_DESC_T prBSSDesc;
712 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
713 pucBSSBuff = &prScanInfo->aucScanBuffer[0];
716 DBGLOG(SCN, INFO, ("->scnInit()\n"));
718 //4 <1> Reset STATE and Message List
719 prScanInfo->eCurrentState = SCAN_STATE_IDLE;
721 prScanInfo->rLastScanCompletedTime = (OS_SYSTIME)0;
723 LINK_INITIALIZE(&prScanInfo->rPendingMsgList);
726 //4 <2> Reset link list of BSS_DESC_T
727 kalMemZero((PVOID) pucBSSBuff, SCN_MAX_BUFFER_SIZE);
729 LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList);
730 LINK_INITIALIZE(&prScanInfo->rBSSDescList);
732 for (i = 0; i < CFG_MAX_NUM_BSS_LIST; i++) {
734 prBSSDesc = (P_BSS_DESC_T)pucBSSBuff;
736 LINK_INSERT_TAIL(&prScanInfo->rFreeBSSDescList, &prBSSDesc->rLinkEntry);
738 pucBSSBuff += ALIGN_4(sizeof(BSS_DESC_T));
740 /* Check if the memory allocation consist with this initialization function */
741 ASSERT(((UINT_32)pucBSSBuff - (UINT_32)&prScanInfo->aucScanBuffer[0]) == SCN_MAX_BUFFER_SIZE);
743 /* reset freest channel information */
744 prScanInfo->fgIsSparseChannelValid = FALSE;
747 } /* end of scnInit() */
750 /*----------------------------------------------------------------------------*/
752 * @brief This function is used by SCN to uninitialize its variables
758 /*----------------------------------------------------------------------------*/
761 IN P_ADAPTER_T prAdapter
764 P_SCAN_INFO_T prScanInfo;
768 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
770 DBGLOG(SCN, INFO, ("->scnUninit()\n"));
772 //4 <1> Reset STATE and Message List
773 prScanInfo->eCurrentState = SCAN_STATE_IDLE;
775 prScanInfo->rLastScanCompletedTime = (OS_SYSTIME)0;
777 /* NOTE(Kevin): Check rPendingMsgList ? */
779 //4 <2> Reset link list of BSS_DESC_T
780 LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList);
781 LINK_INITIALIZE(&prScanInfo->rBSSDescList);
784 } /* end of scnUninit() */
788 /*----------------------------------------------------------------------------*/
790 * @brief Find the corresponding BSS Descriptor according to given BSSID
792 * @param[in] prAdapter Pointer to the Adapter structure.
793 * @param[in] aucBSSID Given BSSID.
795 * @return Pointer to BSS Descriptor, if found. NULL, if not found
797 /*----------------------------------------------------------------------------*/
799 scanSearchBssDescByBssid (
800 IN P_ADAPTER_T prAdapter,
804 return scanSearchBssDescByBssidAndSsid(prAdapter,
811 /*----------------------------------------------------------------------------*/
813 * @brief Find the corresponding BSS Descriptor according to given BSSID
815 * @param[in] prAdapter Pointer to the Adapter structure.
816 * @param[in] aucBSSID Given BSSID.
817 * @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases)
818 * @param[in] prSsid Specified SSID
820 * @return Pointer to BSS Descriptor, if found. NULL, if not found
822 /*----------------------------------------------------------------------------*/
824 scanSearchBssDescByBssidAndSsid (
825 IN P_ADAPTER_T prAdapter,
826 IN UINT_8 aucBSSID[],
827 IN BOOLEAN fgCheckSsid,
828 IN P_PARAM_SSID_T prSsid
831 P_SCAN_INFO_T prScanInfo;
832 P_LINK_T prBSSDescList;
833 P_BSS_DESC_T prBssDesc;
834 P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T)NULL;
840 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
842 prBSSDescList = &prScanInfo->rBSSDescList;
844 /* Search BSS Desc from current SCAN result list. */
845 LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
847 if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) {
848 if(fgCheckSsid == FALSE || prSsid == NULL) {
852 if(EQUAL_SSID(prBssDesc->aucSSID,
853 prBssDesc->ucSSIDLen,
855 prSsid->u4SsidLen)) {
858 else if(prDstBssDesc == NULL && prBssDesc->fgIsHiddenSSID == TRUE) {
859 prDstBssDesc = prBssDesc;
862 /* 20120206 frog: Equal BSSID but not SSID, SSID not hidden, SSID must be updated. */
863 COPY_SSID(prBssDesc->aucSSID,
864 prBssDesc->ucSSIDLen,
875 } /* end of scanSearchBssDescByBssid() */
878 /*----------------------------------------------------------------------------*/
880 * @brief Find the corresponding BSS Descriptor according to given Transmitter Address.
882 * @param[in] prAdapter Pointer to the Adapter structure.
883 * @param[in] aucSrcAddr Given Source Address(TA).
885 * @return Pointer to BSS Descriptor, if found. NULL, if not found
887 /*----------------------------------------------------------------------------*/
889 scanSearchBssDescByTA (
890 IN P_ADAPTER_T prAdapter,
891 IN UINT_8 aucSrcAddr[]
894 return scanSearchBssDescByTAAndSsid(prAdapter,
900 /*----------------------------------------------------------------------------*/
902 * @brief Find the corresponding BSS Descriptor according to given Transmitter Address.
904 * @param[in] prAdapter Pointer to the Adapter structure.
905 * @param[in] aucSrcAddr Given Source Address(TA).
906 * @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases)
907 * @param[in] prSsid Specified SSID
909 * @return Pointer to BSS Descriptor, if found. NULL, if not found
911 /*----------------------------------------------------------------------------*/
913 scanSearchBssDescByTAAndSsid (
914 IN P_ADAPTER_T prAdapter,
915 IN UINT_8 aucSrcAddr[],
916 IN BOOLEAN fgCheckSsid,
917 IN P_PARAM_SSID_T prSsid
920 P_SCAN_INFO_T prScanInfo;
921 P_LINK_T prBSSDescList;
922 P_BSS_DESC_T prBssDesc;
923 P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T)NULL;
929 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
931 prBSSDescList = &prScanInfo->rBSSDescList;
933 /* Search BSS Desc from current SCAN result list. */
934 LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
936 if (EQUAL_MAC_ADDR(prBssDesc->aucSrcAddr, aucSrcAddr)) {
937 if(fgCheckSsid == FALSE || prSsid == NULL) {
941 if(EQUAL_SSID(prBssDesc->aucSSID,
942 prBssDesc->ucSSIDLen,
944 prSsid->u4SsidLen)) {
947 else if(prDstBssDesc == NULL && prBssDesc->fgIsHiddenSSID == TRUE) {
948 prDstBssDesc = prBssDesc;
956 } /* end of scanSearchBssDescByTA() */
959 /*----------------------------------------------------------------------------*/
961 * @brief Find the corresponding BSS Descriptor according to
962 * given eBSSType, BSSID and Transmitter Address
964 * @param[in] prAdapter Pointer to the Adapter structure.
965 * @param[in] eBSSType BSS Type of incoming Beacon/ProbeResp frame.
966 * @param[in] aucBSSID Given BSSID of Beacon/ProbeResp frame.
967 * @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame.
969 * @return Pointer to BSS Descriptor, if found. NULL, if not found
971 /*----------------------------------------------------------------------------*/
973 scanSearchExistingBssDesc (
974 IN P_ADAPTER_T prAdapter,
975 IN ENUM_BSS_TYPE_T eBSSType,
976 IN UINT_8 aucBSSID[],
977 IN UINT_8 aucSrcAddr[]
980 return scanSearchExistingBssDescWithSsid(prAdapter,
989 /*----------------------------------------------------------------------------*/
991 * @brief Find the corresponding BSS Descriptor according to
992 * given eBSSType, BSSID and Transmitter Address
994 * @param[in] prAdapter Pointer to the Adapter structure.
995 * @param[in] eBSSType BSS Type of incoming Beacon/ProbeResp frame.
996 * @param[in] aucBSSID Given BSSID of Beacon/ProbeResp frame.
997 * @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame.
998 * @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases)
999 * @param[in] prSsid Specified SSID
1001 * @return Pointer to BSS Descriptor, if found. NULL, if not found
1003 /*----------------------------------------------------------------------------*/
1005 scanSearchExistingBssDescWithSsid (
1006 IN P_ADAPTER_T prAdapter,
1007 IN ENUM_BSS_TYPE_T eBSSType,
1008 IN UINT_8 aucBSSID[],
1009 IN UINT_8 aucSrcAddr[],
1010 IN BOOLEAN fgCheckSsid,
1011 IN P_PARAM_SSID_T prSsid
1014 P_SCAN_INFO_T prScanInfo;
1015 P_BSS_DESC_T prBssDesc, prIBSSBssDesc;
1020 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1024 case BSS_TYPE_P2P_DEVICE:
1025 fgCheckSsid = FALSE;
1026 case BSS_TYPE_INFRASTRUCTURE:
1027 case BSS_TYPE_BOW_DEVICE:
1029 prBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, fgCheckSsid, prSsid);
1031 /* if (eBSSType == prBssDesc->eBSSType) */
1038 prIBSSBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, fgCheckSsid, prSsid);
1039 prBssDesc = scanSearchBssDescByTAAndSsid(prAdapter, aucSrcAddr, fgCheckSsid, prSsid);
1042 * Rules to maintain the SCAN Result:
1044 * CASE I We have TA1(BSSID1), but it change its BSSID to BSSID2
1045 * -> Update TA1 entry's BSSID.
1046 * CASE II We have TA1(BSSID1), and get TA1(BSSID1) again
1047 * -> Update TA1 entry's contain.
1048 * CASE III We have a SCAN result TA1(BSSID1), and TA2(BSSID2). Sooner or
1049 * later, TA2 merge into TA1, we get TA2(BSSID1)
1050 * -> Remove TA2 first and then replace TA1 entry's TA with TA2, Still have only one entry of BSSID.
1051 * CASE IV We have a SCAN result TA1(BSSID1), and another TA2 also merge into BSSID1.
1052 * -> Replace TA1 entry's TA with TA2, Still have only one entry.
1054 * -> Add this one to SCAN result.
1057 if ((!prIBSSBssDesc) || // CASE I
1058 (prBssDesc == prIBSSBssDesc)) { // CASE II
1063 P_LINK_T prBSSDescList;
1064 P_LINK_T prFreeBSSDescList;
1067 prBSSDescList = &prScanInfo->rBSSDescList;
1068 prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1070 /* Remove this BSS Desc from the BSS Desc list */
1071 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1073 /* Return this BSS Desc to the free BSS Desc list. */
1074 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1076 return prIBSSBssDesc;
1080 if (prIBSSBssDesc) { // CASE IV
1082 return prIBSSBssDesc;
1086 break; // Return NULL;
1094 return (P_BSS_DESC_T)NULL;
1096 } /* end of scanSearchExistingBssDesc() */
1099 /*----------------------------------------------------------------------------*/
1101 * @brief Delete BSS Descriptors from current list according to given Remove Policy.
1103 * @param[in] u4RemovePolicy Remove Policy.
1107 /*----------------------------------------------------------------------------*/
1109 scanRemoveBssDescsByPolicy (
1110 IN P_ADAPTER_T prAdapter,
1111 IN UINT_32 u4RemovePolicy
1114 P_CONNECTION_SETTINGS_T prConnSettings;
1115 P_SCAN_INFO_T prScanInfo;
1116 P_LINK_T prBSSDescList;
1117 P_LINK_T prFreeBSSDescList;
1118 P_BSS_DESC_T prBssDesc;
1123 prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
1124 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1125 prBSSDescList = &prScanInfo->rBSSDescList;
1126 prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1128 //DBGLOG(SCN, TRACE, ("Before Remove - Number Of SCAN Result = %ld\n",
1129 //prBSSDescList->u4NumElem));
1131 if (u4RemovePolicy & SCN_RM_POLICY_TIMEOUT) {
1132 P_BSS_DESC_T prBSSDescNext;
1133 OS_SYSTIME rCurrentTime;
1136 GET_CURRENT_SYSTIME(&rCurrentTime);
1138 /* Search BSS Desc from current SCAN result list. */
1139 LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1141 if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
1142 (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
1143 /* Don't remove the one currently we are connected. */
1147 if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
1148 SEC_TO_SYSTIME(SCN_BSS_DESC_REMOVE_TIMEOUT_SEC)) ) {
1150 //DBGLOG(SCN, TRACE, ("Remove TIMEOUT BSS DESC(%#x): MAC: "MACSTR", Current Time = %08lx, Update Time = %08lx\n",
1151 //prBssDesc, MAC2STR(prBssDesc->aucBSSID), rCurrentTime, prBssDesc->rUpdateTime));
1153 /* Remove this BSS Desc from the BSS Desc list */
1154 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1156 /* Return this BSS Desc to the free BSS Desc list. */
1157 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1161 else if (u4RemovePolicy & SCN_RM_POLICY_OLDEST_HIDDEN) {
1162 P_BSS_DESC_T prBssDescOldest = (P_BSS_DESC_T)NULL;
1165 /* Search BSS Desc from current SCAN result list. */
1166 LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1168 if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
1169 (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
1170 /* Don't remove the one currently we are connected. */
1174 if (!prBssDesc->fgIsHiddenSSID) {
1178 if (!prBssDescOldest) { /* 1st element */
1179 prBssDescOldest = prBssDesc;
1183 if (TIME_BEFORE(prBssDesc->rUpdateTime, prBssDescOldest->rUpdateTime)) {
1184 prBssDescOldest = prBssDesc;
1188 if (prBssDescOldest) {
1190 //DBGLOG(SCN, TRACE, ("Remove OLDEST HIDDEN BSS DESC(%#x): MAC: "MACSTR", Update Time = %08lx\n",
1191 //prBssDescOldest, MAC2STR(prBssDescOldest->aucBSSID), prBssDescOldest->rUpdateTime));
1193 /* Remove this BSS Desc from the BSS Desc list */
1194 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescOldest);
1196 /* Return this BSS Desc to the free BSS Desc list. */
1197 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDescOldest->rLinkEntry);
1200 else if (u4RemovePolicy & SCN_RM_POLICY_SMART_WEAKEST) {
1201 P_BSS_DESC_T prBssDescWeakest = (P_BSS_DESC_T)NULL;
1202 P_BSS_DESC_T prBssDescWeakestSameSSID = (P_BSS_DESC_T)NULL;
1203 UINT_32 u4SameSSIDCount = 0;
1206 /* Search BSS Desc from current SCAN result list. */
1207 LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1209 if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
1210 (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
1211 /* Don't remove the one currently we are connected. */
1215 if ((!prBssDesc->fgIsHiddenSSID) &&
1216 (EQUAL_SSID(prBssDesc->aucSSID,
1217 prBssDesc->ucSSIDLen,
1218 prConnSettings->aucSSID,
1219 prConnSettings->ucSSIDLen))) {
1223 if (!prBssDescWeakestSameSSID) {
1224 prBssDescWeakestSameSSID = prBssDesc;
1226 else if (prBssDesc->ucRCPI < prBssDescWeakestSameSSID->ucRCPI) {
1227 prBssDescWeakestSameSSID = prBssDesc;
1231 if (!prBssDescWeakest) { /* 1st element */
1232 prBssDescWeakest = prBssDesc;
1236 if (prBssDesc->ucRCPI < prBssDescWeakest->ucRCPI) {
1237 prBssDescWeakest = prBssDesc;
1242 if ((u4SameSSIDCount >= SCN_BSS_DESC_SAME_SSID_THRESHOLD) &&
1243 (prBssDescWeakestSameSSID)) {
1244 prBssDescWeakest = prBssDescWeakestSameSSID;
1247 if (prBssDescWeakest) {
1249 //DBGLOG(SCN, TRACE, ("Remove WEAKEST BSS DESC(%#x): MAC: "MACSTR", Update Time = %08lx\n",
1250 //prBssDescOldest, MAC2STR(prBssDescOldest->aucBSSID), prBssDescOldest->rUpdateTime));
1252 /* Remove this BSS Desc from the BSS Desc list */
1253 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescWeakest);
1255 /* Return this BSS Desc to the free BSS Desc list. */
1256 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDescWeakest->rLinkEntry);
1259 else if (u4RemovePolicy & SCN_RM_POLICY_ENTIRE) {
1260 P_BSS_DESC_T prBSSDescNext;
1262 LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1264 if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
1265 (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
1266 /* Don't remove the one currently we are connected. */
1270 /* Remove this BSS Desc from the BSS Desc list */
1271 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1273 /* Return this BSS Desc to the free BSS Desc list. */
1274 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1281 } /* end of scanRemoveBssDescsByPolicy() */
1284 /*----------------------------------------------------------------------------*/
1286 * @brief Delete BSS Descriptors from current list according to given BSSID.
1288 * @param[in] prAdapter Pointer to the Adapter structure.
1289 * @param[in] aucBSSID Given BSSID.
1293 /*----------------------------------------------------------------------------*/
1295 scanRemoveBssDescByBssid (
1296 IN P_ADAPTER_T prAdapter,
1297 IN UINT_8 aucBSSID[]
1300 P_SCAN_INFO_T prScanInfo;
1301 P_LINK_T prBSSDescList;
1302 P_LINK_T prFreeBSSDescList;
1303 P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T)NULL;
1304 P_BSS_DESC_T prBSSDescNext;
1310 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1311 prBSSDescList = &prScanInfo->rBSSDescList;
1312 prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1314 /* Check if such BSS Descriptor exists in a valid list */
1315 LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1317 if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) {
1319 /* Remove this BSS Desc from the BSS Desc list */
1320 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1322 /* Return this BSS Desc to the free BSS Desc list. */
1323 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1325 /* BSSID is not unique, so need to traverse whols link-list */
1330 } /* end of scanRemoveBssDescByBssid() */
1333 /*----------------------------------------------------------------------------*/
1335 * @brief Delete BSS Descriptors from current list according to given band configuration
1337 * @param[in] prAdapter Pointer to the Adapter structure.
1338 * @param[in] eBand Given band
1339 * @param[in] eNetTypeIndex AIS - Remove IBSS/Infrastructure BSS
1340 * BOW - Remove BOW BSS
1341 * P2P - Remove P2P BSS
1345 /*----------------------------------------------------------------------------*/
1347 scanRemoveBssDescByBandAndNetwork (
1348 IN P_ADAPTER_T prAdapter,
1349 IN ENUM_BAND_T eBand,
1350 IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex
1353 P_SCAN_INFO_T prScanInfo;
1354 P_LINK_T prBSSDescList;
1355 P_LINK_T prFreeBSSDescList;
1356 P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T)NULL;
1357 P_BSS_DESC_T prBSSDescNext;
1361 ASSERT(eBand <= BAND_NUM);
1362 ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM);
1364 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1365 prBSSDescList = &prScanInfo->rBSSDescList;
1366 prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1369 if(eBand == BAND_NULL) {
1370 return; /* no need to do anything, keep all scan result */
1373 /* Check if such BSS Descriptor exists in a valid list */
1374 LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1377 if(prBssDesc->eBand == eBand) {
1378 switch (eNetTypeIndex) {
1379 case NETWORK_TYPE_AIS_INDEX:
1380 if((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE)
1381 || (prBssDesc->eBSSType == BSS_TYPE_IBSS)) {
1386 case NETWORK_TYPE_P2P_INDEX:
1387 if(prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) {
1392 case NETWORK_TYPE_BOW_INDEX:
1393 if(prBssDesc->eBSSType == BSS_TYPE_BOW_DEVICE) {
1404 if(fgToRemove == TRUE) {
1405 /* Remove this BSS Desc from the BSS Desc list */
1406 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1408 /* Return this BSS Desc to the free BSS Desc list. */
1409 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1414 } /* end of scanRemoveBssDescByBand() */
1417 /*----------------------------------------------------------------------------*/
1419 * @brief Clear the CONNECTION FLAG of a specified BSS Descriptor.
1421 * @param[in] aucBSSID Given BSSID.
1425 /*----------------------------------------------------------------------------*/
1427 scanRemoveConnFlagOfBssDescByBssid (
1428 IN P_ADAPTER_T prAdapter,
1429 IN UINT_8 aucBSSID[]
1432 P_SCAN_INFO_T prScanInfo;
1433 P_LINK_T prBSSDescList;
1434 P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T)NULL;
1440 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1441 prBSSDescList = &prScanInfo->rBSSDescList;
1443 /* Search BSS Desc from current SCAN result list. */
1444 LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1446 if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) {
1447 prBssDesc->fgIsConnected = FALSE;
1448 prBssDesc->fgIsConnecting = FALSE;
1450 /* BSSID is not unique, so need to traverse whols link-list */
1456 } /* end of scanRemoveConnectionFlagOfBssDescByBssid() */
1459 /*----------------------------------------------------------------------------*/
1461 * @brief Allocate new BSS_DESC_T
1463 * @param[in] prAdapter Pointer to the Adapter structure.
1465 * @return Pointer to BSS Descriptor, if has free space. NULL, if has no space.
1467 /*----------------------------------------------------------------------------*/
1469 scanAllocateBssDesc (
1470 IN P_ADAPTER_T prAdapter
1473 P_SCAN_INFO_T prScanInfo;
1474 P_LINK_T prFreeBSSDescList;
1475 P_BSS_DESC_T prBssDesc;
1479 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1481 prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1483 LINK_REMOVE_HEAD(prFreeBSSDescList, prBssDesc, P_BSS_DESC_T);
1486 P_LINK_T prBSSDescList;
1488 kalMemZero(prBssDesc, sizeof(BSS_DESC_T));
1490 #if CFG_ENABLE_WIFI_DIRECT
1491 LINK_INITIALIZE(&(prBssDesc->rP2pDeviceList));
1492 prBssDesc->fgIsP2PPresent = FALSE;
1493 #endif /* CFG_ENABLE_WIFI_DIRECT */
1495 prBSSDescList = &prScanInfo->rBSSDescList;
1497 /* NOTE(Kevin): In current design, this new empty BSS_DESC_T will be
1498 * inserted to BSSDescList immediately.
1500 LINK_INSERT_TAIL(prBSSDescList, &prBssDesc->rLinkEntry);
1505 } /* end of scanAllocateBssDesc() */
1508 /*----------------------------------------------------------------------------*/
1510 * @brief This API parses Beacon/ProbeResp frame and insert extracted BSS_DESC_T
1511 * with IEs into prAdapter->rWifiVar.rScanInfo.aucScanBuffer
1513 * @param[in] prAdapter Pointer to the Adapter structure.
1514 * @param[in] prSwRfb Pointer to the receiving frame buffer.
1516 * @return Pointer to BSS Descriptor
1517 * NULL if the Beacon/ProbeResp frame is invalid
1519 /*----------------------------------------------------------------------------*/
1522 IN P_ADAPTER_T prAdapter,
1523 IN P_SW_RFB_T prSwRfb
1526 P_BSS_DESC_T prBssDesc = NULL;
1528 ENUM_BSS_TYPE_T eBSSType = BSS_TYPE_INFRASTRUCTURE;
1532 UINT_16 u2Offset = 0;
1534 P_WLAN_BEACON_FRAME_T prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T)NULL;
1535 P_IE_SSID_T prIeSsid = (P_IE_SSID_T)NULL;
1536 P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T)NULL;
1537 P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T)NULL;
1538 P_HIF_RX_HEADER_T prHifRxHdr;
1539 UINT_8 ucHwChannelNum = 0;
1540 UINT_8 ucIeDsChannelNum = 0;
1541 UINT_8 ucIeHtChannelNum = 0;
1542 BOOLEAN fgIsValidSsid = FALSE, fgEscape = FALSE;
1544 UINT_64 u8Timestamp;
1545 BOOLEAN fgIsNewBssDesc = FALSE;
1553 prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T)prSwRfb->pvHeader;
1555 WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2CapInfo, &u2CapInfo);
1556 WLAN_GET_FIELD_64(&prWlanBeaconFrame->au4Timestamp[0], &u8Timestamp);
1559 switch (u2CapInfo & CAP_INFO_BSS_TYPE) {
1561 /* It can also be Group Owner of P2P Group. */
1562 eBSSType = BSS_TYPE_INFRASTRUCTURE;
1566 eBSSType = BSS_TYPE_IBSS;
1569 /* The P2P Device shall set the ESS bit of the Capabilities field in the Probe Response fame to 0 and IBSS bit to 0. (3.1.2.1.1) */
1570 eBSSType = BSS_TYPE_P2P_DEVICE;
1573 #if CFG_ENABLE_BT_OVER_WIFI
1574 // @TODO: add rule to identify BOW beacons
1581 //4 <1.1> Pre-parse SSID IE
1582 pucIE = prWlanBeaconFrame->aucInfoElem;
1583 u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
1584 (UINT_16)OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]);
1586 if (u2IELength > CFG_IE_BUFFER_SIZE) {
1587 u2IELength = CFG_IE_BUFFER_SIZE;
1590 IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
1591 switch (IE_ID(pucIE)) {
1593 if (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID) {
1596 /* D-Link DWL-900AP+ */
1597 if (IE_LEN(pucIE) == 0) {
1598 fgIsValidSsid = FALSE;
1600 /* Cisco AP1230A - (IE_LEN(pucIE) == 1) && (SSID_IE(pucIE)->aucSSID[0] == '\0') */
1601 /* Linksys WRK54G/ASUS WL520g - (IE_LEN(pucIE) == n) && (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') */
1603 for (i = 0; i < IE_LEN(pucIE); i++) {
1604 ucSSIDChar |= SSID_IE(pucIE)->aucSSID[i];
1608 fgIsValidSsid = TRUE;
1612 /* Update SSID to BSS Descriptor only if SSID is not hidden. */
1613 if (fgIsValidSsid == TRUE) {
1614 COPY_SSID(rSsid.aucSsid,
1616 SSID_IE(pucIE)->aucSSID,
1617 SSID_IE(pucIE)->ucLength);
1626 if(fgEscape == TRUE) {
1632 //4 <1.2> Replace existing BSS_DESC_T or allocate a new one
1633 prBssDesc = scanSearchExistingBssDescWithSsid(prAdapter,
1635 (PUINT_8)prWlanBeaconFrame->aucBSSID,
1636 (PUINT_8)prWlanBeaconFrame->aucSrcAddr,
1638 fgIsValidSsid == TRUE ? &rSsid : NULL);
1640 if (prBssDesc == (P_BSS_DESC_T)NULL) {
1641 fgIsNewBssDesc = TRUE;
1644 //4 <1.2.1> First trial of allocation
1645 prBssDesc = scanAllocateBssDesc(prAdapter);
1650 //4 <1.2.2> Hidden is useless, remove the oldest hidden ssid. (for passive scan)
1651 scanRemoveBssDescsByPolicy(prAdapter,
1652 (SCN_RM_POLICY_EXCLUDE_CONNECTED | SCN_RM_POLICY_OLDEST_HIDDEN));
1654 //4 <1.2.3> Second tail of allocation
1655 prBssDesc = scanAllocateBssDesc(prAdapter);
1660 //4 <1.2.4> Remove the weakest one
1661 /* If there are more than half of BSS which has the same ssid as connection
1662 * setting, remove the weakest one from them.
1663 * Else remove the weakest one.
1665 scanRemoveBssDescsByPolicy(prAdapter,
1666 (SCN_RM_POLICY_EXCLUDE_CONNECTED | SCN_RM_POLICY_SMART_WEAKEST));
1668 //4 <1.2.5> reallocation
1669 prBssDesc = scanAllocateBssDesc(prAdapter);
1674 //4 <1.2.6> no space, should not happen
1675 //ASSERT(0); // still no space available ?
1683 OS_SYSTIME rCurrentTime;
1686 // if the received strength is much weaker than the original one,
1687 // ignore it due to it might be received on the folding frequency
1689 GET_CURRENT_SYSTIME(&rCurrentTime);
1691 if (prBssDesc->eBSSType != eBSSType) {
1692 prBssDesc->eBSSType = eBSSType;
1694 else if(HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr) != prBssDesc->ucChannelNum &&
1695 prBssDesc->ucRCPI > prSwRfb->prHifRxHdr->ucRcpi) {
1697 // for signal strength is too much weaker and previous beacon is not stale
1698 if((prBssDesc->ucRCPI - prSwRfb->prHifRxHdr->ucRcpi) >= REPLICATED_BEACON_STRENGTH_THRESHOLD &&
1699 rCurrentTime - prBssDesc->rUpdateTime <= REPLICATED_BEACON_FRESH_PERIOD) {
1702 // for received beacons too close in time domain
1703 else if(rCurrentTime - prBssDesc->rUpdateTime <= REPLICATED_BEACON_TIME_THRESHOLD) {
1708 /* if Timestamp has been reset, re-generate BSS DESC 'cause AP should have reset itself */
1709 if(prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && u8Timestamp < prBssDesc->u8TimeStamp.QuadPart) {
1710 BOOLEAN fgIsConnected, fgIsConnecting;
1712 /* set flag for indicating this is a new BSS-DESC */
1713 fgIsNewBssDesc = TRUE;
1715 /* backup 2 flags for APs which reset timestamp unexpectedly */
1716 fgIsConnected = prBssDesc->fgIsConnected;
1717 fgIsConnecting = prBssDesc->fgIsConnecting;
1718 scanRemoveBssDescByBssid(prAdapter, prBssDesc->aucBSSID);
1720 prBssDesc = scanAllocateBssDesc(prAdapter);
1726 prBssDesc->fgIsConnected = fgIsConnected;
1727 prBssDesc->fgIsConnecting = fgIsConnecting;
1731 /* NOTE: Keep consistency of Scan Record during JOIN process */
1732 if ((fgIsNewBssDesc == FALSE) && prBssDesc->fgIsConnecting) {
1736 //4 <2> Get information from Fixed Fields
1737 prBssDesc->eBSSType = eBSSType; /* Update the latest BSS type information. */
1739 COPY_MAC_ADDR(prBssDesc->aucSrcAddr, prWlanBeaconFrame->aucSrcAddr);
1741 COPY_MAC_ADDR(prBssDesc->aucBSSID, prWlanBeaconFrame->aucBSSID);
1743 prBssDesc->u8TimeStamp.QuadPart = u8Timestamp;
1745 WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2BeaconInterval, &prBssDesc->u2BeaconInterval);
1747 prBssDesc->u2CapInfo = u2CapInfo;
1750 //4 <2.1> Retrieve IEs for later parsing
1751 u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
1752 (UINT_16)OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]);
1754 if (u2IELength > CFG_IE_BUFFER_SIZE) {
1755 u2IELength = CFG_IE_BUFFER_SIZE;
1756 prBssDesc->fgIsIEOverflow = TRUE;
1759 prBssDesc->fgIsIEOverflow = FALSE;
1761 prBssDesc->u2IELength = u2IELength;
1763 kalMemCopy(prBssDesc->aucIEBuf, prWlanBeaconFrame->aucInfoElem, u2IELength);
1765 //4 <2.2> reset prBssDesc variables in case that AP has been reconfigured
1766 prBssDesc->fgIsERPPresent = FALSE;
1767 prBssDesc->fgIsHTPresent = FALSE;
1768 prBssDesc->eSco = CHNL_EXT_SCN;
1769 prBssDesc->fgIEWAPI = FALSE;
1770 #if CFG_RSN_MIGRATION
1771 prBssDesc->fgIERSN = FALSE;
1773 #if CFG_PRIVACY_MIGRATION
1774 prBssDesc->fgIEWPA = FALSE;
1778 //4 <3.1> Full IE parsing on SW_RFB_T
1779 pucIE = prWlanBeaconFrame->aucInfoElem;
1782 IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
1784 switch (IE_ID(pucIE)) {
1786 if ((!prIeSsid) && /* NOTE(Kevin): for Atheros IOT #1 */
1787 (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) {
1788 BOOLEAN fgIsHiddenSSID = FALSE;
1792 prIeSsid = (P_IE_SSID_T)pucIE;
1794 /* D-Link DWL-900AP+ */
1795 if (IE_LEN(pucIE) == 0) {
1796 fgIsHiddenSSID = TRUE;
1798 /* Cisco AP1230A - (IE_LEN(pucIE) == 1) && (SSID_IE(pucIE)->aucSSID[0] == '\0') */
1799 /* Linksys WRK54G/ASUS WL520g - (IE_LEN(pucIE) == n) && (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') */
1801 for (i = 0; i < IE_LEN(pucIE); i++) {
1802 ucSSIDChar |= SSID_IE(pucIE)->aucSSID[i];
1806 fgIsHiddenSSID = TRUE;
1810 /* Update SSID to BSS Descriptor only if SSID is not hidden. */
1811 if (!fgIsHiddenSSID) {
1812 COPY_SSID(prBssDesc->aucSSID,
1813 prBssDesc->ucSSIDLen,
1814 SSID_IE(pucIE)->aucSSID,
1815 SSID_IE(pucIE)->ucLength);
1821 case ELEM_ID_SUP_RATES:
1822 /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8.
1823 * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B),
1824 * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)"
1826 /* TP-LINK will set extra and incorrect ie with ELEM_ID_SUP_RATES */
1827 if ((!prIeSupportedRate) && (IE_LEN(pucIE) <= RATE_NUM)) {
1828 prIeSupportedRate = SUP_RATES_IE(pucIE);
1832 case ELEM_ID_DS_PARAM_SET:
1833 if (IE_LEN(pucIE) == ELEM_MAX_LEN_DS_PARAMETER_SET) {
1834 ucIeDsChannelNum = DS_PARAM_IE(pucIE)->ucCurrChnl;
1839 if (IE_LEN(pucIE) <= ELEM_MAX_LEN_TIM) {
1840 prBssDesc->ucDTIMPeriod = TIM_IE(pucIE)->ucDTIMPeriod;
1844 case ELEM_ID_IBSS_PARAM_SET:
1845 if (IE_LEN(pucIE) == ELEM_MAX_LEN_IBSS_PARAMETER_SET){
1846 prBssDesc->u2ATIMWindow = IBSS_PARAM_IE(pucIE)->u2ATIMWindow;
1850 #if 0 //CFG_SUPPORT_802_11D
1851 case ELEM_ID_COUNTRY_INFO:
1852 prBssDesc->prIECountry = (P_IE_COUNTRY_T)pucIE;
1856 case ELEM_ID_ERP_INFO:
1857 if (IE_LEN(pucIE) == ELEM_MAX_LEN_ERP) {
1858 prBssDesc->fgIsERPPresent = TRUE;
1862 case ELEM_ID_EXTENDED_SUP_RATES:
1863 if (!prIeExtSupportedRate) {
1864 prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE);
1868 #if CFG_RSN_MIGRATION
1870 if (rsnParseRsnIE(prAdapter, RSN_IE(pucIE), &prBssDesc->rRSNInfo)) {
1871 prBssDesc->fgIERSN = TRUE;
1872 prBssDesc->u2RsnCap = prBssDesc->rRSNInfo.u2RsnCap;
1873 if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) {
1874 rsnCheckPmkidCache(prAdapter, prBssDesc);
1880 case ELEM_ID_HT_CAP:
1881 prBssDesc->fgIsHTPresent = TRUE;
1885 if (IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) {
1889 if ((((P_IE_HT_OP_T) pucIE)->ucInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) {
1890 prBssDesc->eSco = (ENUM_CHNL_EXT_T)
1891 (((P_IE_HT_OP_T) pucIE)->ucInfo1 & HT_OP_INFO1_SCO);
1893 ucIeHtChannelNum = ((P_IE_HT_OP_T) pucIE)->ucPrimaryChannel;
1897 #if CFG_SUPPORT_WAPI
1899 if (wapiParseWapiIE(WAPI_IE(pucIE), &prBssDesc->rIEWAPI)) {
1900 prBssDesc->fgIEWAPI = TRUE;
1905 case ELEM_ID_VENDOR: // ELEM_ID_P2P, ELEM_ID_WMM
1908 UINT_16 u2SubTypeVersion;
1909 #if CFG_PRIVACY_MIGRATION
1910 if (rsnParseCheckForWFAInfoElem(prAdapter, pucIE, &ucOuiType, &u2SubTypeVersion)) {
1911 if ((ucOuiType == VENDOR_OUI_TYPE_WPA) &&
1912 (u2SubTypeVersion == VERSION_WPA)) {
1914 if (rsnParseWpaIE(prAdapter, WPA_IE(pucIE), &prBssDesc->rWPAInfo)) {
1915 prBssDesc->fgIEWPA = TRUE;
1921 #if CFG_ENABLE_WIFI_DIRECT
1922 if(prAdapter->fgIsP2PRegistered) {
1923 if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType)) {
1924 if (ucOuiType == VENDOR_OUI_TYPE_P2P) {
1925 prBssDesc->fgIsP2PPresent = TRUE;
1929 #endif /* CFG_ENABLE_WIFI_DIRECT */
1938 //4 <3.2> Save information from IEs - SSID
1939 /* Update Flag of Hidden SSID for used in SEARCH STATE. */
1941 /* NOTE(Kevin): in current driver, the ucSSIDLen == 0 represent
1942 * all cases of hidden SSID.
1943 * If the fgIsHiddenSSID == TRUE, it means we didn't get the ProbeResp with
1946 if (prBssDesc->ucSSIDLen == 0) {
1947 prBssDesc->fgIsHiddenSSID = TRUE;
1950 prBssDesc->fgIsHiddenSSID = FALSE;
1954 //4 <3.3> Check rate information in related IEs.
1955 if (prIeSupportedRate || prIeExtSupportedRate) {
1956 rateGetRateSetFromIEs(prIeSupportedRate,
1957 prIeExtSupportedRate,
1958 &prBssDesc->u2OperationalRateSet,
1959 &prBssDesc->u2BSSBasicRateSet,
1960 &prBssDesc->fgIsUnknownBssBasicRate);
1964 //4 <4> Update information from HIF RX Header
1966 prHifRxHdr = prSwRfb->prHifRxHdr;
1970 //4 <4.1> Get TSF comparison result
1971 prBssDesc->fgIsLargerTSF = HIF_RX_HDR_GET_TCL_FLAG(prHifRxHdr);
1973 //4 <4.2> Get Band information
1974 prBssDesc->eBand = HIF_RX_HDR_GET_RF_BAND(prHifRxHdr);
1976 //4 <4.2> Get channel and RCPI information
1977 ucHwChannelNum = HIF_RX_HDR_GET_CHNL_NUM(prHifRxHdr);
1979 if (BAND_2G4 == prBssDesc->eBand) {
1981 /* Update RCPI if in right channel */
1982 if (ucIeDsChannelNum >= 1 && ucIeDsChannelNum <= 14) {
1984 // Receive Beacon/ProbeResp frame from adjacent channel.
1985 if ((ucIeDsChannelNum == ucHwChannelNum) ||
1986 (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) {
1987 prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
1990 // trust channel information brought by IE
1991 prBssDesc->ucChannelNum = ucIeDsChannelNum;
1993 else if(ucIeHtChannelNum >= 1 && ucIeHtChannelNum <= 14) {
1994 // Receive Beacon/ProbeResp frame from adjacent channel.
1995 if ((ucIeHtChannelNum == ucHwChannelNum) ||
1996 (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) {
1997 prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
2000 // trust channel information brought by IE
2001 prBssDesc->ucChannelNum = ucIeHtChannelNum;
2004 prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
2006 prBssDesc->ucChannelNum = ucHwChannelNum;
2011 if(ucIeHtChannelNum >= 1 && ucIeHtChannelNum < 200) {
2012 // Receive Beacon/ProbeResp frame from adjacent channel.
2013 if ((ucIeHtChannelNum == ucHwChannelNum) ||
2014 (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) {
2015 prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
2018 // trust channel information brought by IE
2019 prBssDesc->ucChannelNum = ucIeHtChannelNum;
2022 /* Always update RCPI */
2023 prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
2025 prBssDesc->ucChannelNum = ucHwChannelNum;
2031 //4 <5> PHY type setting
2032 prBssDesc->ucPhyTypeSet = 0;
2034 if (BAND_2G4 == prBssDesc->eBand) {
2035 /* check if support 11n */
2036 if (prBssDesc->fgIsHTPresent) {
2037 prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT;
2040 /* if not 11n only */
2041 if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) {
2042 /* check if support 11g */
2043 if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM) ||
2044 prBssDesc->fgIsERPPresent) {
2045 prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_ERP;
2048 /* if not 11g only */
2049 if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_OFDM)) {
2050 /* check if support 11b */
2051 if ((prBssDesc->u2OperationalRateSet & RATE_SET_HR_DSSS)) {
2052 prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS;
2057 else { /* (BAND_5G == prBssDesc->eBande) */
2058 /* check if support 11n */
2059 if (prBssDesc->fgIsHTPresent) {
2060 prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT;
2063 /* if not 11n only */
2064 if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) {
2065 /* Support 11a definitely */
2066 prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM;
2068 ASSERT(!(prBssDesc->u2OperationalRateSet & RATE_SET_HR_DSSS));
2073 //4 <6> Update BSS_DESC_T's Last Update TimeStamp.
2074 GET_CURRENT_SYSTIME(&prBssDesc->rUpdateTime);
2080 /*----------------------------------------------------------------------------*/
2082 * @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to scan result for query
2084 * @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure.
2086 * @retval WLAN_STATUS_SUCCESS It is a valid Scan Result and been sent to the host.
2087 * @retval WLAN_STATUS_FAILURE It is not a valid Scan Result.
2089 /*----------------------------------------------------------------------------*/
2092 IN P_ADAPTER_T prAdapter,
2093 IN P_BSS_DESC_T prBssDesc,
2094 IN P_SW_RFB_T prSwRfb
2097 P_SCAN_INFO_T prScanInfo;
2098 UINT_8 aucRatesEx[PARAM_MAX_LEN_RATES_EX];
2099 P_WLAN_BEACON_FRAME_T prWlanBeaconFrame;
2100 PARAM_MAC_ADDRESS rMacAddr;
2102 ENUM_PARAM_NETWORK_TYPE_T eNetworkType;
2103 PARAM_802_11_CONFIG_T rConfiguration;
2104 ENUM_PARAM_OP_MODE_T eOpMode;
2105 UINT_8 ucRateLen = 0;
2111 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
2113 if (prBssDesc->eBand == BAND_2G4) {
2114 if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM)
2115 || prBssDesc->fgIsERPPresent) {
2116 eNetworkType = PARAM_NETWORK_TYPE_OFDM24;
2119 eNetworkType = PARAM_NETWORK_TYPE_DS;
2123 ASSERT(prBssDesc->eBand == BAND_5G);
2124 eNetworkType = PARAM_NETWORK_TYPE_OFDM5;
2127 if(prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) {
2128 /* NOTE(Kevin): Not supported by WZC(TBD) */
2129 return WLAN_STATUS_FAILURE;
2132 prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T)prSwRfb->pvHeader;
2133 COPY_MAC_ADDR(rMacAddr, prWlanBeaconFrame->aucBSSID);
2134 COPY_SSID(rSsid.aucSsid,
2137 prBssDesc->ucSSIDLen);
2139 rConfiguration.u4Length = sizeof(PARAM_802_11_CONFIG_T);
2140 rConfiguration.u4BeaconPeriod = (UINT_32) prWlanBeaconFrame->u2BeaconInterval;
2141 rConfiguration.u4ATIMWindow = prBssDesc->u2ATIMWindow;
2142 rConfiguration.u4DSConfig = nicChannelNum2Freq(prBssDesc->ucChannelNum);
2143 rConfiguration.rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T);
2145 rateGetDataRatesFromRateSet(prBssDesc->u2OperationalRateSet,
2150 /* NOTE(Kevin): Set unused entries, if any, at the end of the array to 0.
2151 * from OID_802_11_BSSID_LIST
2153 for (i = ucRateLen; i < sizeof(aucRatesEx) / sizeof(aucRatesEx[0]) ; i++) {
2157 switch(prBssDesc->eBSSType) {
2159 eOpMode = NET_TYPE_IBSS;
2162 case BSS_TYPE_INFRASTRUCTURE:
2163 case BSS_TYPE_P2P_DEVICE:
2164 case BSS_TYPE_BOW_DEVICE:
2166 eOpMode = NET_TYPE_INFRA;
2170 kalIndicateBssInfo(prAdapter->prGlueInfo,
2171 (PUINT_8)prSwRfb->pvHeader,
2172 prSwRfb->u2PacketLen,
2173 prBssDesc->ucChannelNum,
2174 RCPI_TO_dBm(prBssDesc->ucRCPI));
2176 nicAddScanResult(prAdapter,
2179 prWlanBeaconFrame->u2CapInfo & CAP_INFO_PRIVACY ? 1 : 0,
2180 RCPI_TO_dBm(prBssDesc->ucRCPI),
2185 prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen,
2186 (PUINT_8)((UINT_32)(prSwRfb->pvHeader) + WLAN_MAC_MGMT_HEADER_LEN));
2188 return WLAN_STATUS_SUCCESS;
2190 } /* end of scanAddScanResult() */
2193 /*----------------------------------------------------------------------------*/
2195 * @brief Parse the content of given Beacon or ProbeResp Frame.
2197 * @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure.
2199 * @retval WLAN_STATUS_SUCCESS if not report this SW_RFB_T to host
2200 * @retval WLAN_STATUS_PENDING if report this SW_RFB_T to host as scan result
2202 /*----------------------------------------------------------------------------*/
2204 scanProcessBeaconAndProbeResp (
2205 IN P_ADAPTER_T prAdapter,
2206 IN P_SW_RFB_T prSwRfb
2209 P_CONNECTION_SETTINGS_T prConnSettings;
2210 P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T)NULL;
2211 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2212 P_BSS_INFO_T prAisBssInfo;
2213 P_WLAN_BEACON_FRAME_T prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T)NULL;
2215 P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T)NULL;
2221 //4 <0> Ignore invalid Beacon Frame
2222 if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) <
2223 (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN)) {
2231 prSltInfo = &prAdapter->rWifiVar.rSltInfo;
2233 if (prSltInfo->fgIsDUT) {
2234 DBGLOG(P2P, INFO, ("\n\rBCN: RX\n"));
2235 prSltInfo->u4BeaconReceiveCnt++;
2236 return WLAN_STATUS_SUCCESS;
2239 return WLAN_STATUS_SUCCESS;
2244 prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
2245 prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
2246 prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T)prSwRfb->pvHeader;
2248 //4 <1> Parse and add into BSS_DESC_T
2249 prBssDesc = scanAddToBssDesc(prAdapter, prSwRfb);
2253 //4 <1.1> Beacon Change Detection for Connected BSS
2254 if(prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED &&
2255 ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && prConnSettings->eOPMode != NET_TYPE_IBSS)
2256 || (prBssDesc->eBSSType == BSS_TYPE_IBSS && prConnSettings->eOPMode != NET_TYPE_INFRA)) &&
2257 EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID) &&
2258 EQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen)) {
2259 BOOLEAN fgNeedDisconnect = FALSE;
2261 #if CFG_SUPPORT_BEACON_CHANGE_DETECTION
2262 // <1.1.2> check if supported rate differs
2263 if(prAisBssInfo->u2OperationalRateSet != prBssDesc->u2OperationalRateSet) {
2264 fgNeedDisconnect = TRUE;
2268 // <1.1.3> beacon content change detected, disconnect immediately
2269 if(fgNeedDisconnect == TRUE) {
2270 aisBssBeaconTimeout(prAdapter);
2274 //4 <1.1> Update AIS_BSS_INFO
2275 if(((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && prConnSettings->eOPMode != NET_TYPE_IBSS)
2276 || (prBssDesc->eBSSType == BSS_TYPE_IBSS && prConnSettings->eOPMode != NET_TYPE_INFRA))) {
2277 if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
2279 /* *not* checking prBssDesc->fgIsConnected anymore,
2280 * due to Linksys AP uses " " as hidden SSID, and would have different BSS descriptor */
2281 if ((!prAisBssInfo->ucDTIMPeriod) &&
2282 EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID) &&
2283 (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) &&
2284 ((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_BEACON)) {
2286 prAisBssInfo->ucDTIMPeriod = prBssDesc->ucDTIMPeriod;
2288 /* sync with firmware for beacon information */
2289 nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_AIS_INDEX);
2293 #if CFG_SUPPORT_ADHOC
2294 if (EQUAL_SSID(prBssDesc->aucSSID,
2295 prBssDesc->ucSSIDLen,
2296 prConnSettings->aucSSID,
2297 prConnSettings->ucSSIDLen) &&
2298 (prBssDesc->eBSSType == BSS_TYPE_IBSS) &&
2299 (prAisBssInfo->eCurrentOPMode == OP_MODE_IBSS)) {
2301 ibssProcessMatchedBeacon(prAdapter, prAisBssInfo, prBssDesc, prSwRfb->prHifRxHdr->ucRcpi);
2303 #endif /* CFG_SUPPORT_ADHOC */
2306 rlmProcessBcn(prAdapter,
2308 ((P_WLAN_BEACON_FRAME_T)(prSwRfb->pvHeader))->aucInfoElem,
2309 (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
2310 (UINT_16)(OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0])));
2312 //4 <3> Send SW_RFB_T to HIF when we perform SCAN for HOST
2313 if(prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE
2314 || prBssDesc->eBSSType == BSS_TYPE_IBSS) {
2315 /* for AIS, send to host */
2316 if (prConnSettings->fgIsScanReqIssued &&
2317 rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum) == TRUE) {
2320 BOOLEAN fgAddToScanResult;
2322 /* check ucChannelNum/eBand for adjacement channel filtering */
2323 if(cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel) == TRUE &&
2324 (eBand != prBssDesc->eBand || ucChannel != prBssDesc->ucChannelNum)) {
2325 fgAddToScanResult = FALSE;
2328 fgAddToScanResult = TRUE;
2331 if(fgAddToScanResult == TRUE) {
2332 rStatus = scanAddScanResult(prAdapter, prBssDesc, prSwRfb);
2337 #if CFG_ENABLE_WIFI_DIRECT
2338 if(prAdapter->fgIsP2PRegistered) {
2339 scanP2pProcessBeaconAndProbeResp(
2351 } /* end of scanProcessBeaconAndProbeResp() */
2354 /*----------------------------------------------------------------------------*/
2356 * \brief Search the Candidate of BSS Descriptor for JOIN(Infrastructure) or
2357 * MERGE(AdHoc) according to current Connection Policy.
2359 * \return Pointer to BSS Descriptor, if found. NULL, if not found
2361 /*----------------------------------------------------------------------------*/
2363 scanSearchBssDescByPolicy (
2364 IN P_ADAPTER_T prAdapter,
2365 IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex
2368 P_CONNECTION_SETTINGS_T prConnSettings;
2369 P_BSS_INFO_T prBssInfo;
2370 P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
2371 P_SCAN_INFO_T prScanInfo;
2373 P_LINK_T prBSSDescList;
2375 P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T)NULL;
2376 P_BSS_DESC_T prPrimaryBssDesc = (P_BSS_DESC_T)NULL;
2377 P_BSS_DESC_T prCandidateBssDesc = (P_BSS_DESC_T)NULL;
2379 P_STA_RECORD_T prStaRec = (P_STA_RECORD_T)NULL;
2380 P_STA_RECORD_T prPrimaryStaRec;
2381 P_STA_RECORD_T prCandidateStaRec = (P_STA_RECORD_T)NULL;
2383 OS_SYSTIME rCurrentTime;
2385 /* The first one reach the check point will be our candidate */
2386 BOOLEAN fgIsFindFirst = (BOOLEAN)FALSE;
2388 BOOLEAN fgIsFindBestRSSI = (BOOLEAN)FALSE;
2389 BOOLEAN fgIsFindBestEncryptionLevel = (BOOLEAN)FALSE;
2390 //BOOLEAN fgIsFindMinChannelLoad = (BOOLEAN)FALSE;
2392 /* TODO(Kevin): Support Min Channel Load */
2393 //UINT_8 aucChannelLoad[CHANNEL_NUM] = {0};
2395 BOOLEAN fgIsFixedChannel;
2401 prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
2402 prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]);
2404 prAisSpecBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo);
2406 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
2407 prBSSDescList = &prScanInfo->rBSSDescList;
2409 GET_CURRENT_SYSTIME(&rCurrentTime);
2411 /* check for fixed channel operation */
2412 if(eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) {
2413 fgIsFixedChannel = cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel);
2416 fgIsFixedChannel = FALSE;
2420 if (prConnSettings->ucSSIDLen < ELEM_MAX_LEN_SSID) {
2421 prConnSettings->aucSSID[prConnSettings->ucSSIDLen] = '\0';
2425 DBGLOG(SCN, INFO, ("SEARCH: Num Of BSS_DESC_T = %d, Look for SSID: %s\n",
2426 prBSSDescList->u4NumElem, prConnSettings->aucSSID));
2429 //4 <1> The outer loop to search for a candidate.
2430 LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
2432 /* TODO(Kevin): Update Minimum Channel Load Information here */
2434 DBGLOG(SCN, INFO, ("SEARCH: ["MACSTR"], SSID:%s\n",
2435 MAC2STR(prBssDesc->aucBSSID), prBssDesc->aucSSID));
2438 //4 <2> Check PHY Type and attributes
2439 //4 <2.1> Check Unsupported BSS PHY Type
2440 if (!(prBssDesc->ucPhyTypeSet & (prAdapter->rWifiVar.ucAvailablePhyTypeSet))) {
2442 DBGLOG(SCN, INFO, ("SEARCH: Ignore unsupported ucPhyTypeSet = %x\n",
2443 prBssDesc->ucPhyTypeSet));
2447 //4 <2.2> Check if has unknown NonHT BSS Basic Rate Set.
2448 if (prBssDesc->fgIsUnknownBssBasicRate) {
2453 //4 <2.3> Check if fixed operation cases should be aware
2454 if (fgIsFixedChannel == TRUE &&
2455 (prBssDesc->eBand != eBand || prBssDesc->ucChannelNum != ucChannel)) {
2459 //4 <2.4> Check if the channel is legal under regulatory domain
2460 if(rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum) == FALSE) {
2464 //4 <2.5> Check if this BSS_DESC_T is stale
2465 if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
2466 SEC_TO_SYSTIME(SCN_BSS_DESC_REMOVE_TIMEOUT_SEC)) ) {
2471 //4 <3> Check if reach the excessive join retry limit
2472 /* NOTE(Kevin): STA_RECORD_T is recorded by TA. */
2473 prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) eNetTypeIndex,
2474 prBssDesc->aucSrcAddr);
2478 * The Status Code is the result of a Previous Connection Request, we use this as SCORE for choosing a proper
2479 * candidate (Also used for compare see <6>)
2480 * The Reason Code is an indication of the reason why AP reject us, we use this Code for "Reject"
2481 * a SCAN result to become our candidate(Like a blacklist).
2483 #if 0 /* TODO(Kevin): */
2484 if (prStaRec->u2ReasonCode != REASON_CODE_RESERVED) {
2485 DBGLOG(SCN, INFO, ("SEARCH: Ignore BSS with previous Reason Code = %d\n",
2486 prStaRec->u2ReasonCode));
2491 if (prStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL) {
2492 /* NOTE(Kevin): greedy association - after timeout, we'll still
2493 * try to associate to the AP whose STATUS of conection attempt
2495 * We may also use (ucJoinFailureCount x JOIN_RETRY_INTERVAL_SEC) for
2498 if ((prStaRec->ucJoinFailureCount < JOIN_MAX_RETRY_FAILURE_COUNT) ||
2499 (CHECK_FOR_TIMEOUT(rCurrentTime,
2500 prStaRec->rLastJoinTime,
2501 SEC_TO_SYSTIME(JOIN_RETRY_INTERVAL_SEC)))) {
2503 /* NOTE(Kevin): Every JOIN_RETRY_INTERVAL_SEC interval, we can retry
2504 * JOIN_MAX_RETRY_FAILURE_COUNT times.
2506 if (prStaRec->ucJoinFailureCount >= JOIN_MAX_RETRY_FAILURE_COUNT) {
2507 prStaRec->ucJoinFailureCount = 0;
2509 DBGLOG(SCN, INFO, ("SEARCH: Try to join BSS again which has Status Code = %d (Curr = %ld/Last Join = %ld)\n",
2510 prStaRec->u2StatusCode, rCurrentTime, prStaRec->rLastJoinTime));
2513 DBGLOG(SCN, INFO, ("SEARCH: Ignore BSS which reach maximum Join Retry Count = %d \n",
2514 JOIN_MAX_RETRY_FAILURE_COUNT));
2522 //4 <4> Check for various NETWORK conditions
2523 if (eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) {
2525 //4 <4.1> Check BSS Type for the corresponding Operation Mode in Connection Setting
2526 /* NOTE(Kevin): For NET_TYPE_AUTO_SWITCH, we will always pass following check. */
2527 if (((prConnSettings->eOPMode == NET_TYPE_INFRA) &&
2528 (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE)) ||
2529 ((prConnSettings->eOPMode == NET_TYPE_IBSS || prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS) &&
2530 (prBssDesc->eBSSType != BSS_TYPE_IBSS))) {
2532 DBGLOG(SCN, INFO, ("SEARCH: Ignore eBSSType = %s\n",
2533 ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) ?
2534 "INFRASTRUCTURE" : "IBSS")));
2538 //4 <4.2> Check AP's BSSID if OID_802_11_BSSID has been set.
2539 if ((prConnSettings->fgIsConnByBssidIssued) &&
2540 (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE)) {
2542 if (UNEQUAL_MAC_ADDR(prConnSettings->aucBSSID, prBssDesc->aucBSSID)) {
2544 DBGLOG(SCN, INFO, ("SEARCH: Ignore due to BSSID was not matched!\n"));
2549 #if CFG_SUPPORT_ADHOC
2550 //4 <4.3> Check for AdHoc Mode
2551 if (prBssDesc->eBSSType == BSS_TYPE_IBSS) {
2552 OS_SYSTIME rCurrentTime;
2554 //4 <4.3.1> Check if this SCAN record has been updated recently for IBSS.
2555 /* NOTE(Kevin): Because some STA may change its BSSID frequently after it
2556 * create the IBSS - e.g. IPN2220, so we need to make sure we get the new one.
2557 * For BSS, if the old record was matched, however it won't be able to pass
2558 * the Join Process later.
2560 GET_CURRENT_SYSTIME(&rCurrentTime);
2561 if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
2562 SEC_TO_SYSTIME(SCN_ADHOC_BSS_DESC_TIMEOUT_SEC))) {
2563 DBGLOG(SCN, LOUD, ("SEARCH: Skip old record of BSS Descriptor - BSSID:["MACSTR"]\n\n",
2564 MAC2STR(prBssDesc->aucBSSID)));
2568 //4 <4.3.2> Check Peer's capability
2569 if (ibssCheckCapabilityForAdHocMode(prAdapter, prBssDesc) == WLAN_STATUS_FAILURE) {
2572 ("SEARCH: Ignore BSS DESC MAC: "MACSTR", Capability is not supported for current AdHoc Mode.\n",
2573 MAC2STR(prPrimaryBssDesc->aucBSSID)));
2579 //4 <4.3.3> Compare TSF
2580 if (prBssInfo->fgIsBeaconActivated &&
2581 UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID)) {
2584 ("SEARCH: prBssDesc->fgIsLargerTSF = %d\n",
2585 prBssDesc->fgIsLargerTSF));
2587 if (!prBssDesc->fgIsLargerTSF) {
2589 ("SEARCH: Ignore BSS DESC MAC: ["MACSTR"], Smaller TSF\n", MAC2STR(prBssDesc->aucBSSID)));
2594 #endif /* CFG_SUPPORT_ADHOC */
2601 #if 0 /* TODO(Kevin): For IBSS */
2602 //4 <2.c> Check if this SCAN record has been updated recently for IBSS.
2603 /* NOTE(Kevin): Because some STA may change its BSSID frequently after it
2604 * create the IBSS, so we need to make sure we get the new one.
2605 * For BSS, if the old record was matched, however it won't be able to pass
2606 * the Join Process later.
2608 if (prBssDesc->eBSSType == BSS_TYPE_IBSS) {
2609 OS_SYSTIME rCurrentTime;
2611 GET_CURRENT_SYSTIME(&rCurrentTime);
2612 if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
2613 SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) {
2614 DBGLOG(SCAN, TRACE, ("Skip old record of BSS Descriptor - BSSID:["MACSTR"]\n\n",
2615 MAC2STR(prBssDesc->aucBSSID)));
2620 if ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) &&
2621 (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED)) {
2622 OS_SYSTIME rCurrentTime;
2624 GET_CURRENT_SYSTIME(&rCurrentTime);
2625 if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
2626 SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) {
2627 DBGLOG(SCAN, TRACE, ("Skip old record of BSS Descriptor - BSSID:["MACSTR"]\n\n",
2628 MAC2STR(prBssDesc->aucBSSID)));
2634 //4 <4B> Check for IBSS AdHoc Mode.
2635 /* Skip if one or more BSS Basic Rate are not supported by current AdHocMode */
2636 if (prPrimaryBssDesc->eBSSType == BSS_TYPE_IBSS) {
2637 //4 <4B.1> Check if match the Capability of current IBSS AdHoc Mode.
2638 if (ibssCheckCapabilityForAdHocMode(prAdapter, prPrimaryBssDesc) == WLAN_STATUS_FAILURE) {
2641 ("Ignore BSS DESC MAC: "MACSTR", Capability is not supported for current AdHoc Mode.\n",
2642 MAC2STR(prPrimaryBssDesc->aucBSSID)));
2648 //4 <4B.2> IBSS Merge Decision Flow for SEARCH STATE.
2649 if (prAdapter->fgIsIBSSActive &&
2650 UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prPrimaryBssDesc->aucBSSID)) {
2652 if (!fgIsLocalTSFRead) {
2653 NIC_GET_CURRENT_TSF(prAdapter, &rCurrentTsf);
2656 ("\n\nCurrent TSF : %08lx-%08lx\n\n",
2657 rCurrentTsf.u.HighPart, rCurrentTsf.u.LowPart));
2660 if (rCurrentTsf.QuadPart > prPrimaryBssDesc->u8TimeStamp.QuadPart) {
2662 ("Ignore BSS DESC MAC: ["MACSTR"], Current BSSID: ["MACSTR"].\n",
2663 MAC2STR(prPrimaryBssDesc->aucBSSID), MAC2STR(prBssInfo->aucBSSID)));
2666 ("\n\nBSS's TSF : %08lx-%08lx\n\n",
2667 prPrimaryBssDesc->u8TimeStamp.u.HighPart, prPrimaryBssDesc->u8TimeStamp.u.LowPart));
2669 prPrimaryBssDesc->fgIsLargerTSF = FALSE;
2673 prPrimaryBssDesc->fgIsLargerTSF = TRUE;
2679 //4 <5> Check the Encryption Status.
2680 if (rsnPerformPolicySelection(prPrimaryBssDesc)) {
2682 if (prPrimaryBssDesc->ucEncLevel > 0) {
2683 fgIsFindBestEncryptionLevel = TRUE;
2685 fgIsFindFirst = FALSE;
2689 /* Can't pass the Encryption Status Check, get next one */
2693 /* For RSN Pre-authentication, update the PMKID canidate list for
2694 same SSID and encrypt status */
2695 /* Update PMKID candicate list. */
2696 if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) {
2697 rsnUpdatePmkidCandidateList(prPrimaryBssDesc);
2698 if (prAdapter->rWifiVar.rAisBssInfo.u4PmkidCandicateCount) {
2699 prAdapter->rWifiVar.rAisBssInfo.fgIndicatePMKID = rsnCheckPmkidCandicate();
2706 prPrimaryBssDesc = (P_BSS_DESC_T)NULL;
2708 //4 <6> Check current Connection Policy.
2709 switch (prConnSettings->eConnectionPolicy) {
2710 case CONNECT_BY_SSID_BEST_RSSI:
2711 /* Choose Hidden SSID to join only if the `fgIsEnableJoin...` is TRUE */
2712 if (prAdapter->rWifiVar.fgEnableJoinToHiddenSSID && prBssDesc->fgIsHiddenSSID) {
2713 /* NOTE(Kevin): following if () statement means that
2714 * If Target is hidden, then we won't connect when user specify SSID_ANY policy.
2716 if (prConnSettings->ucSSIDLen) {
2717 prPrimaryBssDesc = prBssDesc;
2719 fgIsFindBestRSSI = TRUE;
2723 else if (EQUAL_SSID(prBssDesc->aucSSID,
2724 prBssDesc->ucSSIDLen,
2725 prConnSettings->aucSSID,
2726 prConnSettings->ucSSIDLen)) {
2727 prPrimaryBssDesc = prBssDesc;
2729 fgIsFindBestRSSI = TRUE;
2733 case CONNECT_BY_SSID_ANY:
2734 /* NOTE(Kevin): In this policy, we don't know the desired
2735 * SSID from user, so we should exclude the Hidden SSID from scan list.
2736 * And because we refuse to connect to Hidden SSID node at the beginning, so
2737 * when the JOIN Module deal with a BSS_DESC_T which has fgIsHiddenSSID == TRUE,
2738 * then the Connection Settings must be valid without doubt.
2740 if (!prBssDesc->fgIsHiddenSSID) {
2741 prPrimaryBssDesc = prBssDesc;
2743 fgIsFindFirst = TRUE;
2747 case CONNECT_BY_BSSID:
2748 if(EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prConnSettings->aucBSSID)) {
2749 prPrimaryBssDesc = prBssDesc;
2758 /* Primary Candidate was not found */
2759 if (prPrimaryBssDesc == NULL) {
2763 //4 <7> Check the Encryption Status.
2764 if (prPrimaryBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) {
2765 #if CFG_SUPPORT_WAPI
2766 if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) {
2767 if (wapiPerformPolicySelection(prAdapter, prPrimaryBssDesc)) {
2768 fgIsFindFirst = TRUE;
2771 /* Can't pass the Encryption Status Check, get next one */
2777 #if CFG_RSN_MIGRATION
2778 if (rsnPerformPolicySelection(prAdapter, prPrimaryBssDesc)) {
2779 if (prAisSpecBssInfo->fgCounterMeasure) {
2780 DBGLOG(RSN, INFO, ("Skip while at counter measure period!!!\n"));
2784 if (prPrimaryBssDesc->ucEncLevel > 0) {
2785 fgIsFindBestEncryptionLevel = TRUE;
2787 fgIsFindFirst = FALSE;
2791 /* Update PMKID candicate list. */
2792 if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) {
2793 rsnUpdatePmkidCandidateList(prPrimaryBssDesc);
2794 if (prAisSpecBssInfo->u4PmkidCandicateCount) {
2795 if (rsnCheckPmkidCandicate()) {
2796 DBGLOG(RSN, WARN, ("Prepare a timer to indicate candidate "MACSTR"\n",
2797 MAC2STR(prAisSpecBssInfo->arPmkidCache[prAisSpecBssInfo->u4PmkidCacheCount].rBssidInfo.aucBssid)));
2798 cnmTimerStopTimer(&prAisSpecBssInfo->rPreauthenticationTimer);
2799 cnmTimerStartTimer(&prAisSpecBssInfo->rPreauthenticationTimer,
2800 SEC_TO_MSEC(WAIT_TIME_IND_PMKID_CANDICATE_SEC));
2807 /* Can't pass the Encryption Status Check, get next one */
2813 /* Todo:: P2P and BOW Policy Selection */
2816 prPrimaryStaRec = prStaRec;
2818 //4 <8> Compare the Candidate and the Primary Scan Record.
2819 if (!prCandidateBssDesc) {
2820 prCandidateBssDesc = prPrimaryBssDesc;
2821 prCandidateStaRec = prPrimaryStaRec;
2823 //4 <8.1> Condition - Get the first matched one.
2824 if (fgIsFindFirst) {
2829 #if 0 /* TODO(Kevin): For security(TBD) */
2830 //4 <6B> Condition - Choose the one with best Encryption Score.
2831 if (fgIsFindBestEncryptionLevel) {
2832 if (prCandidateBssDesc->ucEncLevel <
2833 prPrimaryBssDesc->ucEncLevel) {
2835 prCandidateBssDesc = prPrimaryBssDesc;
2836 prCandidateStaRec = prPrimaryStaRec;
2841 /* If reach here, that means they have the same Encryption Score.
2844 //4 <6C> Condition - Give opportunity to the one we didn't connect before.
2845 // For roaming, only compare the candidates other than current associated BSSID.
2846 if (!prCandidateBssDesc->fgIsConnected && !prPrimaryBssDesc->fgIsConnected) {
2847 if ((prCandidateStaRec != (P_STA_RECORD_T)NULL) &&
2848 (prCandidateStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL)) {
2850 DBGLOG(SCAN, TRACE, ("So far -BSS DESC MAC: "MACSTR" has nonzero Status Code = %d\n",
2851 MAC2STR(prCandidateBssDesc->aucBSSID), prCandidateStaRec->u2StatusCode));
2853 if (prPrimaryStaRec != (P_STA_RECORD_T)NULL) {
2854 if (prPrimaryStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL) {
2856 /* Give opportunity to the one with smaller rLastJoinTime */
2857 if (TIME_BEFORE(prCandidateStaRec->rLastJoinTime,
2858 prPrimaryStaRec->rLastJoinTime)) {
2861 /* We've connect to CANDIDATE recently, let us try PRIMARY now */
2863 prCandidateBssDesc = prPrimaryBssDesc;
2864 prCandidateStaRec = prPrimaryStaRec;
2868 /* PRIMARY's u2StatusCode = 0 */
2870 prCandidateBssDesc = prPrimaryBssDesc;
2871 prCandidateStaRec = prPrimaryStaRec;
2875 /* PRIMARY has no StaRec - We didn't connet to PRIMARY before */
2877 prCandidateBssDesc = prPrimaryBssDesc;
2878 prCandidateStaRec = prPrimaryStaRec;
2883 if ((prPrimaryStaRec != (P_STA_RECORD_T)NULL) &&
2884 (prPrimaryStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL)) {
2892 //4 <6D> Condition - Visible SSID win Hidden SSID.
2893 if (prCandidateBssDesc->fgIsHiddenSSID) {
2894 if (!prPrimaryBssDesc->fgIsHiddenSSID) {
2895 prCandidateBssDesc = prPrimaryBssDesc; /* The non Hidden SSID win. */
2896 prCandidateStaRec = prPrimaryStaRec;
2901 if (prPrimaryBssDesc->fgIsHiddenSSID) {
2907 //4 <6E> Condition - Choose the one with better RCPI(RSSI).
2908 if (fgIsFindBestRSSI) {
2909 /* TODO(Kevin): We shouldn't compare the actual value, we should
2910 * allow some acceptable tolerance of some RSSI percentage here.
2912 DBGLOG(SCN, TRACE, ("Candidate ["MACSTR"]: RCPI = %d, Primary ["MACSTR"]: RCPI = %d\n",
2913 MAC2STR(prCandidateBssDesc->aucBSSID), prCandidateBssDesc->ucRCPI,
2914 MAC2STR(prPrimaryBssDesc->aucBSSID), prPrimaryBssDesc->ucRCPI));
2916 ASSERT(!(prCandidateBssDesc->fgIsConnected &&
2917 prPrimaryBssDesc->fgIsConnected));
2919 /* NOTE: To prevent SWING, we do roaming only if target AP has at least 5dBm larger than us. */
2920 if (prCandidateBssDesc->fgIsConnected) {
2921 if (prCandidateBssDesc->ucRCPI + ROAMING_NO_SWING_RCPI_STEP <= prPrimaryBssDesc->ucRCPI) {
2923 prCandidateBssDesc = prPrimaryBssDesc;
2924 prCandidateStaRec = prPrimaryStaRec;
2928 else if (prPrimaryBssDesc->fgIsConnected) {
2929 if (prCandidateBssDesc->ucRCPI < prPrimaryBssDesc->ucRCPI + ROAMING_NO_SWING_RCPI_STEP) {
2931 prCandidateBssDesc = prPrimaryBssDesc;
2932 prCandidateStaRec = prPrimaryStaRec;
2936 else if (prCandidateBssDesc->ucRCPI < prPrimaryBssDesc->ucRCPI) {
2937 prCandidateBssDesc = prPrimaryBssDesc;
2938 prCandidateStaRec = prPrimaryStaRec;
2944 /* If reach here, that means they have the same Encryption Score, and
2945 * both RSSI value are close too.
2947 //4 <6F> Seek the minimum Channel Load for less interference.
2948 if (fgIsFindMinChannelLoad) {
2950 /* TODO(Kevin): Check which one has minimum channel load in its channel */
2956 return prCandidateBssDesc;
2958 } /* end of scanSearchBssDescByPolicy() */