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 * 07 17 2012 yuche.tsai
22 * Let netdev bring up.
24 * 07 17 2012 yuche.tsai
26 * Compile no error before trial run.
29 * [WCXRP00001258] [MT6620][MT5931][MT6628][Driver] Do not use stale scan result for deciding connection target
30 * drop off scan result which is older than 5 seconds when choosing which BSS to join
34 * Sync CFG80211 modification from branch 2,2.
37 * [WCXRP00001169] [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration with corresponding network configuration
41 * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration with corresponding network configuration
42 * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting preferred band configuration corresponding to network type.
45 * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path
46 * add CONNECT_BY_BSSID policy
49 * [WCXRP00001123] [MT6620 Wi-Fi][Driver] Add option to disable beacon content change detection
50 * add compile option to disable beacon content change detection.
53 * [WCXRP00001085] [MT6628 Wi-Fi][Driver] deprecate old BSS-DESC if timestamp is reset with received beacon/probe response frames
54 * deprecate old BSS-DESC when timestamp in received beacon/probe response frames showed a smaller value than before
57 * [WCXRP00001031] [All Wi-Fi][Driver] Check HT IE length to avoid wrong SCO parameter
58 * Ignore HT OP IE if its length field is not valid
61 * [WCXRP00001021] [MT5931][Driver] Correct scan result generation for conversion between BSS type and operation mode
62 * correct type casting issue.
64 * 08 23 2011 yuche.tsai
66 * Fix multicast address list issue.
69 * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time
70 * sparse channel detection:
71 * driver: collect sparse channel information with scan-done event
74 * [WCXRP00000922] [MT6620 Wi-Fi][Driver] traverse whole BSS-DESC list for removing
75 * traverse whole BSS-DESC list because BSSID is not unique anymore.
78 * [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
79 * for multiple BSS descriptior detecting issue:
80 * 1) check BSSID for infrastructure network
81 * 2) check SSID for AdHoc network
84 * [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
85 * check for BSSID for beacons used to update DTIM
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 * do not check BSS descriptor for connected flag due to linksys's hidden SSID will use another BSS descriptor and never connected
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 * just pass beacons with the same BSSID.
96 * [WCXRP00000849] [MT6620 Wi-Fi][Driver] Remove some of the WAPI define for make sure the value is initialize, for customer not enable WAPI
97 * For make sure wapi initial value is set.
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 * Do not check for SSID as beacon content change due to the existence of single BSSID with multiple SSID AP configuration
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
106 * 2. replace only BSS-DESC which doesn't have a valid SSID.
109 * [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 * remove unused temporal variable reference.
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 * allow to have a single BSSID with multiple SSID to be presented in scanning result
117 * [WCXRP00000757] [MT6620 Wi-Fi][Driver][SCN] take use of RLM API to filter out BSS in disallowed channels
118 * filter out BSS in disallowed channel by
119 * 1. do not add to scan result array if BSS is at disallowed channel
120 * 2. do not allow to search for BSS-DESC in disallowed channels
122 * 05 02 2011 cm.chang
123 * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number
124 * Refine range of valid channel number
127 * [MT6620 Wi-Fi][Driver] Take parsed result for channel information instead of hardware channel number passed from firmware domain
128 * take parsed result for generating scanning result with channel information.
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 * Check if channel is valided before record ing BSS channel
134 * 04 18 2011 terry.wu
135 * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
136 * Remove flag CFG_WIFI_DIRECT_MOVED.
138 * 04 14 2011 cm.chang
139 * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
142 * 04 12 2011 eddie.chen
143 * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
144 * Fix the sta index in processing security frame
145 * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4
148 * 03 25 2011 yuche.tsai
150 * Always update Bss Type, for Bss Type for P2P Network is changing every time.
152 * 03 23 2011 yuche.tsai
154 * Fix concurrent issue when AIS scan result would overwrite p2p scan result.
157 * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently
158 * filtering out other BSS coming from adjacent channels
160 * 03 11 2011 chinglan.wang
161 * [WCXRP00000537] [MT6620 Wi-Fi][Driver] Can not connect to 802.11b/g/n mixed AP with WEP security.
165 * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently
166 * When fixed channel operation is necessary, AIS-FSM would scan and only connect for BSS on the specific channel
169 * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation because NdisMSleep() won't sleep long enough for specified interval such as 500ms
170 * implement beacon change detection by checking SSID and supported rate.
172 * 02 22 2011 yuche.tsai
173 * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue
174 * Fix WSC big endian issue.
176 * 02 21 2011 terry.wu
177 * [WCXRP00000476] [MT6620 Wi-Fi][Driver] Clean P2P scan list while removing P2P
178 * Clean P2P scan list while removing P2P.
180 * 01 27 2011 yuche.tsai
181 * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate.
182 * Fix scan channel extension issue when p2p module is not registered.
184 * 01 26 2011 cm.chang
185 * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
189 * [WCXRP00000380] [MT6620 Wi-Fi][Driver] SSID information should come from buffered BSS_DESC_T rather than using beacon-carried information
190 * SSID should come from buffered prBssDesc rather than beacon-carried information
192 * 01 14 2011 yuche.tsai
193 * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
196 * 01 14 2011 yuche.tsai
197 * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
198 * Memfree for P2P Descriptor & P2P Descriptor List.
200 * 01 14 2011 yuche.tsai
201 * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
202 * Free P2P Descriptor List & Descriptor under BSS Descriptor.
205 * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease physically continous memory demands
206 * 1) correct typo in scan.c
207 * 2) TX descriptors, RX descriptos and management buffer should use virtually continous buffer instead of physically contineous one
210 * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease physically continous memory demands
211 * separate kalMemAlloc() into virtually-continous and physically-continous type to ease slab system pressure
214 * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side
215 * while being unloaded, clear all pending interrupt then set LP-own to firmware
218 * [WCXRP00000280] [MT6620 Wi-Fi][Driver] Enable BSS selection with best RCPI policy in SCN module
219 * SCN: enable BEST RSSI selection policy support
222 * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for initial TX rate selection of auto-rate algorithm
223 * update ucRcpi of STA_RECORD_T for AIS when
224 * 1) Beacons for IBSS merge is received
225 * 2) Associate Response for a connecting peer is received
228 * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group
229 * Refine the HT rate disallow TKIP pairwise cipher .
232 * [WCXRP00000091] [MT6620 Wi-Fi][Driver] Add scanning logic to filter out beacons which is received on the folding frequency
233 * trust HT IE if available for 5GHz band
236 * [WCXRP00000091] [MT6620 Wi-Fi][Driver] Add scanning logic to filter out beacons which is received on the folding frequency
237 * add timing and strenght constraint for filtering out beacons with same SSID/TA but received on different channels
240 * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine
241 * update the frog's new p2p state machine.
243 * 10 01 2010 yuche.tsai
245 * [MT6620 P2P] Fix Big Endian Issue when parse P2P device name TLV.
248 * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
249 * eliminate unused variables which lead gcc to argue
253 * use static memory pool for storing IEs of scanning result.
255 * 09 07 2010 yuche.tsai
257 * When indicate scan result, append IE buffer information in the scan result.
259 * 09 03 2010 yuche.tsai
261 * 1. Update Beacon RX count when running SLT.
262 * 2. Ignore Beacon when running SLT, would not update information from Beacon.
264 * 09 03 2010 kevin.huang
266 * Refine #include sequence and solve recursive/nested #include issue
268 * 08 31 2010 kevin.huang
270 * Use LINK LIST operation to process SCAN result
272 * 08 29 2010 yuche.tsai
274 * 1. Fix P2P Descriptor List to be a link list, to avoid link corrupt after Bss Descriptor Free.
275 * 2.. Fix P2P Device Name Length BE issue.
277 * 08 23 2010 yuche.tsai
279 * Add P2P Device Found Indication to supplicant
283 * reset BSS_DESC_T variables before parsing IE due to peer might have been reconfigured.
285 * 08 20 2010 yuche.tsai
287 * Workaround for P2P Descriptor Infinite loop issue.
291 * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI.
292 * There is no CFG_SUPPORT_BOW in driver domain source.
294 * 08 16 2010 yuche.tsai
296 * Modify code of processing Probe Resonse frame for P2P.
298 * 08 12 2010 yuche.tsai
300 * Add function to get P2P descriptor of BSS descriptor directly.
302 * 08 11 2010 yuche.tsai
304 * Modify Scan result processing for P2P module.
306 * 08 05 2010 yuche.tsai
308 * Update P2P Device Discovery result add function.
312 * surpress compilation warning.
314 * 07 26 2010 yuche.tsai
316 * Add support for Probe Request & Response parsing.
320 * 1) change BG_SCAN to ONLINE_SCAN for consistent term
321 * 2) only clear scanning result when scan is permitted to do
323 * 07 21 2010 yuche.tsai
325 * Fix compile error for SCAN module while disabling P2P feature.
327 * 07 21 2010 yuche.tsai
329 * Add P2P Scan & Scan Result Parsing & Saving.
333 * update for security supporting.
337 * [WPD00003833] [MT6620 and MT5931] Driver migration.
338 * Add Ad-Hoc support to AIS-FSM
342 * [WPD00003833] [MT6620 and MT5931] Driver migration.
343 * SCN module is now able to handle multiple concurrent scanning requests
347 * [WPD00003833] [MT6620 and MT5931] Driver migration.
348 * driver no longer generates probe request frames
352 * [WPD00003833] [MT6620 and MT5931] Driver migration.
353 * remove timer in DRV-SCN.
357 * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection)
358 * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass
359 * 3) implment DRV-SCN module, currently only accepts single scan request, other request will be directly dropped by returning BUSY
363 * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
366 * [WPD00003833][MT6620 and MT5931] Driver migration
367 * take use of RLM module for parsing/generating HT IEs for 11n capability
370 * [WPD00003833][MT6620 and MT5931] Driver migration
371 * 1) ignore RSN checking when RSN is not turned on.
372 * 2) set STA-REC deactivation callback as NULL
373 * 3) add variable initialization API based on PHY configuration
376 * [WPD00003833][MT6620 and MT5931] Driver migration
377 * correct BSS_DESC_T initialization after allocated.
380 * [WPD00003833][MT6620 and MT5931] Driver migration
381 * 1) for event packet, no need to fill RFB.
382 * 2) when wlanAdapterStart() failed, no need to initialize state machines
383 * 3) after Beacon/ProbeResp parsing, corresponding BSS_DESC_T should be marked as IE-parsed
386 * [WPD00003833][MT6620 and MT5931] Driver migration
387 * add scan uninitialization procedure
390 * [WPD00003833][MT6620 and MT5931] Driver migration
391 * if beacon/probe-resp is received in 2.4GHz bands and there is ELEM_ID_DS_PARAM_SET IE available,
392 * trust IE instead of RMAC information
395 * [WPD00003833][MT6620 and MT5931] Driver migration
396 * 1) sync to. CMD/EVENT document v0.03
397 * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again.
398 * 3) send command packet to indicate FW-PM after
399 * a) 1st beacon is received after AIS has connected to an AP
400 * b) IBSS-ALONE has been created
401 * c) IBSS-MERGE has occured
404 * [WPD00003833][MT6620 and MT5931] Driver migration
405 * send MMPDU in basic rate.
408 * [WPD00003833][MT6620 and MT5931] Driver migration
409 * modify Beacon/ProbeResp to complete parsing,
410 * because host software has looser memory usage restriction
413 * [WPD00003833][MT6620 and MT5931] Driver migration
417 * [WPD00003833][MT6620 and MT5931] Driver migration
418 * comment out RLM APIs by CFG_RLM_MIGRATION.
420 * 06 21 2010 yuche.tsai
421 * [WPD00003839][MT6620 5931][P2P] Feature migration
422 * Update P2P Function call.
425 * [WPD00003833][MT6620 and MT5931] Driver migration
426 * RSN/PRIVACY compilation flag awareness correction
429 * [WPD00003833][MT6620 and MT5931] Driver migration
430 * specify correct value for management frames.
432 * 06 18 2010 cm.chang
433 * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
434 * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
437 * [WPD00003840][MT6620 5931] Security migration
438 * migration from MT6620 firmware.
440 * 06 17 2010 yuche.tsai
441 * [WPD00003839][MT6620 5931][P2P] Feature migration
442 * Fix compile error when enable P2P function.
445 * [WPD00003833][MT6620 and MT5931] Driver migration
446 * correct when ADHOC support is turned on.
449 * [WPD00003833][MT6620 and MT5931] Driver migration
452 * 06 04 2010 george.huang
453 * [BORA00000678][MT6620]WiFi LP integration
454 * [PM] Support U-APSD for STA mode
457 * [BORA00000680][MT6620] Support the statistic for Microsoft os query
458 * adding the TKIP disallow join a HT AP code.
460 * 05 14 2010 kevin.huang
461 * [BORA00000794][WIFISYS][New Feature]Power Management Support
462 * Add more chance of JOIN retry for BG_SCAN
464 * 05 12 2010 kevin.huang
465 * [BORA00000794][WIFISYS][New Feature]Power Management Support
466 * Add Power Management - Legacy PS-POLL support.
469 * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
470 * adjsut the pre-authentication code.
472 * 04 27 2010 kevin.huang
473 * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
474 * Add Set Slot Time and Beacon Timeout Support for AdHoc Mode
476 * 04 24 2010 cm.chang
477 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
478 * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
480 * 04 19 2010 kevin.huang
481 * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
482 * Add Beacon Timeout Support and will send Null frame to diagnose connection
484 * 04 13 2010 kevin.huang
485 * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
486 * Add new HW CH macro support
489 * [BORA00000680][MT6620] Support the statistic for Microsoft os query
490 * fixed the firmware return the broadcast frame at wrong tc.
493 * [BORA00000605][WIFISYS] Phase3 Integration
494 * let the rsn wapi IE always parsing.
496 * 03 24 2010 cm.chang
497 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
498 * Not carry HT cap when being associated with b/g only AP
500 * 03 18 2010 kevin.huang
501 * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
502 * Solve the compile warning for 'return non-void' function
504 * 03 16 2010 kevin.huang
505 * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
508 * 03 10 2010 kevin.huang
509 * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support
511 * * * * * * * * * * * * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req
514 * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
515 * move the AIS specific variable for security to AIS specific structure.
518 * [BORA00000605][WIFISYS] Phase3 Integration
519 * Refine the variable and parameter for security.
521 * 02 26 2010 kevin.huang
522 * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
523 * Fix No PKT_INFO_T issue
525 * 02 26 2010 kevin.huang
526 * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
527 * Update outgoing ProbeRequest Frame's TX data rate
530 * [BORA00000592][MT6620 Wi-Fi] Adding the security related code for driver
531 * refine the scan procedure, reduce the WPA and WAPI IE parsing, and move the parsing to the time for join.
533 * 02 23 2010 kevin.huang
534 * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
535 * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb
537 * 02 04 2010 kevin.huang
538 * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
539 * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
542 * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
543 * add and fixed some security function.
545 * 01 22 2010 cm.chang
546 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
547 * Support protection and bandwidth switch
549 * 01 20 2010 kevin.huang
550 * [BORA00000569][WIFISYS] Phase 2 Integration Test
551 * Add PHASE_2_INTEGRATION_WORK_AROUND and CFG_SUPPORT_BCM flags
553 * 01 11 2010 kevin.huang
554 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
555 * Add Deauth and Disassoc Handler
557 * 01 08 2010 kevin.huang
558 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
560 * Refine Beacon processing, add read RF channel from RX Status
562 * 01 04 2010 tehuang.liu
563 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
564 * For working out the first connection Chariot-verified version
566 * 12 18 2009 cm.chang
567 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
570 * Dec 12 2009 mtk01104
571 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
572 * Modify u2EstimatedExtraIELen for probe request
574 * Dec 9 2009 mtk01104
575 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
576 * Add HT cap IE to probe request
578 * Dec 7 2009 mtk01461
579 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
583 * Dec 3 2009 mtk01461
584 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
585 * Update the process of SCAN Result by adding more Phy Attributes
587 * Dec 1 2009 mtk01088
588 * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
589 * adjust the function and code for meet the new define
591 * Nov 30 2009 mtk01461
592 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
593 * Rename u4RSSI to i4RSSI
595 * Nov 30 2009 mtk01461
596 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
597 * Report event of scan result to host
599 * Nov 26 2009 mtk01461
600 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
601 * Fix SCAN Record update
603 * Nov 24 2009 mtk01461
604 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
605 * Revise MGMT Handler with Retain Status and Integrate with TXM
607 * Nov 23 2009 mtk01461
608 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
609 * Add (Ext)Support Rate Set IE to ProbeReq
611 * Nov 20 2009 mtk02468
612 * [BORA00000337] To check in codes for FPGA emulation
613 * Removed the use of SW_RFB->u2FrameLength
615 * Nov 20 2009 mtk01461
616 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
617 * Fix uninitial aucMacAddress[] for ProbeReq
619 * Nov 16 2009 mtk01461
620 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
621 * Add scanSearchBssDescByPolicy()
623 * Nov 5 2009 mtk01461
624 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
625 * Add Send Probe Request Frame
627 * Oct 30 2009 mtk01461
628 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
632 /*******************************************************************************
633 * C O M P I L E R F L A G S
634 ********************************************************************************
637 /*******************************************************************************
638 * E X T E R N A L R E F E R E N C E S
639 ********************************************************************************
643 /*******************************************************************************
645 ********************************************************************************
647 #define REPLICATED_BEACON_TIME_THRESHOLD (3000)
648 #define REPLICATED_BEACON_FRESH_PERIOD (10000)
649 #define REPLICATED_BEACON_STRENGTH_THRESHOLD (32)
651 #define ROAMING_NO_SWING_RCPI_STEP (10)
653 /*******************************************************************************
655 ********************************************************************************
658 /*******************************************************************************
659 * P U B L I C D A T A
660 ********************************************************************************
663 /*******************************************************************************
664 * P R I V A T E D A T A
665 ********************************************************************************
668 /*******************************************************************************
670 ********************************************************************************
673 /*******************************************************************************
674 * F U N C T I O N D E C L A R A T I O N S
675 ********************************************************************************
678 /*******************************************************************************
680 ********************************************************************************
682 /*----------------------------------------------------------------------------*/
684 * @brief This function is used by SCN to initialize its variables
690 /*----------------------------------------------------------------------------*/
693 IN P_ADAPTER_T prAdapter
696 P_SCAN_INFO_T prScanInfo;
697 P_BSS_DESC_T prBSSDesc;
704 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
705 pucBSSBuff = &prScanInfo->aucScanBuffer[0];
708 DBGLOG(SCN, INFO, ("->scnInit()\n"));
710 //4 <1> Reset STATE and Message List
711 prScanInfo->eCurrentState = SCAN_STATE_IDLE;
713 prScanInfo->rLastScanCompletedTime = (OS_SYSTIME)0;
715 LINK_INITIALIZE(&prScanInfo->rPendingMsgList);
718 //4 <2> Reset link list of BSS_DESC_T
719 kalMemZero((PVOID) pucBSSBuff, SCN_MAX_BUFFER_SIZE);
721 LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList);
722 LINK_INITIALIZE(&prScanInfo->rBSSDescList);
724 for (i = 0; i < CFG_MAX_NUM_BSS_LIST; i++) {
726 prBSSDesc = (P_BSS_DESC_T)pucBSSBuff;
728 LINK_INSERT_TAIL(&prScanInfo->rFreeBSSDescList, &prBSSDesc->rLinkEntry);
730 pucBSSBuff += ALIGN_4(sizeof(BSS_DESC_T));
732 /* Check if the memory allocation consist with this initialization function */
733 ASSERT(((UINT_32)pucBSSBuff - (UINT_32)&prScanInfo->aucScanBuffer[0]) == SCN_MAX_BUFFER_SIZE);
735 /* reset freest channel information */
736 prScanInfo->fgIsSparseChannelValid = FALSE;
739 } /* end of scnInit() */
742 /*----------------------------------------------------------------------------*/
744 * @brief This function is used by SCN to uninitialize its variables
750 /*----------------------------------------------------------------------------*/
753 IN P_ADAPTER_T prAdapter
756 P_SCAN_INFO_T prScanInfo;
760 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
762 DBGLOG(SCN, INFO, ("->scnUninit()\n"));
764 //4 <1> Reset STATE and Message List
765 prScanInfo->eCurrentState = SCAN_STATE_IDLE;
767 prScanInfo->rLastScanCompletedTime = (OS_SYSTIME)0;
769 /* NOTE(Kevin): Check rPendingMsgList ? */
771 //4 <2> Reset link list of BSS_DESC_T
772 LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList);
773 LINK_INITIALIZE(&prScanInfo->rBSSDescList);
776 } /* end of scnUninit() */
780 /*----------------------------------------------------------------------------*/
782 * @brief Find the corresponding BSS Descriptor according to given BSSID
784 * @param[in] prAdapter Pointer to the Adapter structure.
785 * @param[in] aucBSSID Given BSSID.
787 * @return Pointer to BSS Descriptor, if found. NULL, if not found
789 /*----------------------------------------------------------------------------*/
791 scanSearchBssDescByBssid (
792 IN P_ADAPTER_T prAdapter,
796 return scanSearchBssDescByBssidAndSsid(prAdapter,
803 /*----------------------------------------------------------------------------*/
805 * @brief Find the corresponding BSS Descriptor according to given BSSID
807 * @param[in] prAdapter Pointer to the Adapter structure.
808 * @param[in] aucBSSID Given BSSID.
809 * @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases)
810 * @param[in] prSsid Specified SSID
812 * @return Pointer to BSS Descriptor, if found. NULL, if not found
814 /*----------------------------------------------------------------------------*/
816 scanSearchBssDescByBssidAndSsid (
817 IN P_ADAPTER_T prAdapter,
818 IN UINT_8 aucBSSID[],
819 IN BOOLEAN fgCheckSsid,
820 IN P_PARAM_SSID_T prSsid
823 P_SCAN_INFO_T prScanInfo;
824 P_LINK_T prBSSDescList;
825 P_BSS_DESC_T prBssDesc;
826 P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T)NULL;
832 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
834 prBSSDescList = &prScanInfo->rBSSDescList;
836 /* Search BSS Desc from current SCAN result list. */
837 LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
839 if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) {
840 if(fgCheckSsid == FALSE || prSsid == NULL) {
844 if(EQUAL_SSID(prBssDesc->aucSSID,
845 prBssDesc->ucSSIDLen,
847 prSsid->u4SsidLen)) {
850 else if(prDstBssDesc == NULL && prBssDesc->fgIsHiddenSSID == TRUE) {
851 prDstBssDesc = prBssDesc;
854 /* 20120206 frog: Equal BSSID but not SSID, SSID not hidden, SSID must be updated. */
855 COPY_SSID(prBssDesc->aucSSID,
856 prBssDesc->ucSSIDLen,
867 } /* end of scanSearchBssDescByBssid() */
870 /*----------------------------------------------------------------------------*/
872 * @brief Find the corresponding BSS Descriptor according to given Transmitter Address.
874 * @param[in] prAdapter Pointer to the Adapter structure.
875 * @param[in] aucSrcAddr Given Source Address(TA).
877 * @return Pointer to BSS Descriptor, if found. NULL, if not found
879 /*----------------------------------------------------------------------------*/
881 scanSearchBssDescByTA (
882 IN P_ADAPTER_T prAdapter,
883 IN UINT_8 aucSrcAddr[]
886 return scanSearchBssDescByTAAndSsid(prAdapter,
892 /*----------------------------------------------------------------------------*/
894 * @brief Find the corresponding BSS Descriptor according to given Transmitter Address.
896 * @param[in] prAdapter Pointer to the Adapter structure.
897 * @param[in] aucSrcAddr Given Source Address(TA).
898 * @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases)
899 * @param[in] prSsid Specified SSID
901 * @return Pointer to BSS Descriptor, if found. NULL, if not found
903 /*----------------------------------------------------------------------------*/
905 scanSearchBssDescByTAAndSsid (
906 IN P_ADAPTER_T prAdapter,
907 IN UINT_8 aucSrcAddr[],
908 IN BOOLEAN fgCheckSsid,
909 IN P_PARAM_SSID_T prSsid
912 P_SCAN_INFO_T prScanInfo;
913 P_LINK_T prBSSDescList;
914 P_BSS_DESC_T prBssDesc;
915 P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T)NULL;
921 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
923 prBSSDescList = &prScanInfo->rBSSDescList;
925 /* Search BSS Desc from current SCAN result list. */
926 LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
928 if (EQUAL_MAC_ADDR(prBssDesc->aucSrcAddr, aucSrcAddr)) {
929 if(fgCheckSsid == FALSE || prSsid == NULL) {
933 if(EQUAL_SSID(prBssDesc->aucSSID,
934 prBssDesc->ucSSIDLen,
936 prSsid->u4SsidLen)) {
939 else if(prDstBssDesc == NULL && prBssDesc->fgIsHiddenSSID == TRUE) {
940 prDstBssDesc = prBssDesc;
948 } /* end of scanSearchBssDescByTA() */
951 /*----------------------------------------------------------------------------*/
953 * @brief Find the corresponding BSS Descriptor according to
954 * given eBSSType, BSSID and Transmitter Address
956 * @param[in] prAdapter Pointer to the Adapter structure.
957 * @param[in] eBSSType BSS Type of incoming Beacon/ProbeResp frame.
958 * @param[in] aucBSSID Given BSSID of Beacon/ProbeResp frame.
959 * @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame.
961 * @return Pointer to BSS Descriptor, if found. NULL, if not found
963 /*----------------------------------------------------------------------------*/
965 scanSearchExistingBssDesc (
966 IN P_ADAPTER_T prAdapter,
967 IN ENUM_BSS_TYPE_T eBSSType,
968 IN UINT_8 aucBSSID[],
969 IN UINT_8 aucSrcAddr[]
972 return scanSearchExistingBssDescWithSsid(prAdapter,
981 /*----------------------------------------------------------------------------*/
983 * @brief Find the corresponding BSS Descriptor according to
984 * given eBSSType, BSSID and Transmitter Address
986 * @param[in] prAdapter Pointer to the Adapter structure.
987 * @param[in] eBSSType BSS Type of incoming Beacon/ProbeResp frame.
988 * @param[in] aucBSSID Given BSSID of Beacon/ProbeResp frame.
989 * @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame.
990 * @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases)
991 * @param[in] prSsid Specified SSID
993 * @return Pointer to BSS Descriptor, if found. NULL, if not found
995 /*----------------------------------------------------------------------------*/
997 scanSearchExistingBssDescWithSsid (
998 IN P_ADAPTER_T prAdapter,
999 IN ENUM_BSS_TYPE_T eBSSType,
1000 IN UINT_8 aucBSSID[],
1001 IN UINT_8 aucSrcAddr[],
1002 IN BOOLEAN fgCheckSsid,
1003 IN P_PARAM_SSID_T prSsid
1006 P_SCAN_INFO_T prScanInfo;
1007 P_BSS_DESC_T prBssDesc, prIBSSBssDesc;
1012 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1016 case BSS_TYPE_P2P_DEVICE:
1017 fgCheckSsid = FALSE;
1018 case BSS_TYPE_INFRASTRUCTURE:
1019 case BSS_TYPE_BOW_DEVICE:
1021 prBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, fgCheckSsid, prSsid);
1023 /* if (eBSSType == prBssDesc->eBSSType) */
1030 prIBSSBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, fgCheckSsid, prSsid);
1031 prBssDesc = scanSearchBssDescByTAAndSsid(prAdapter, aucSrcAddr, fgCheckSsid, prSsid);
1034 * Rules to maintain the SCAN Result:
1036 * CASE I We have TA1(BSSID1), but it change its BSSID to BSSID2
1037 * -> Update TA1 entry's BSSID.
1038 * CASE II We have TA1(BSSID1), and get TA1(BSSID1) again
1039 * -> Update TA1 entry's contain.
1040 * CASE III We have a SCAN result TA1(BSSID1), and TA2(BSSID2). Sooner or
1041 * later, TA2 merge into TA1, we get TA2(BSSID1)
1042 * -> Remove TA2 first and then replace TA1 entry's TA with TA2, Still have only one entry of BSSID.
1043 * CASE IV We have a SCAN result TA1(BSSID1), and another TA2 also merge into BSSID1.
1044 * -> Replace TA1 entry's TA with TA2, Still have only one entry.
1046 * -> Add this one to SCAN result.
1049 if ((!prIBSSBssDesc) || // CASE I
1050 (prBssDesc == prIBSSBssDesc)) { // CASE II
1055 P_LINK_T prBSSDescList;
1056 P_LINK_T prFreeBSSDescList;
1059 prBSSDescList = &prScanInfo->rBSSDescList;
1060 prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1062 /* Remove this BSS Desc from the BSS Desc list */
1063 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1065 /* Return this BSS Desc to the free BSS Desc list. */
1066 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1068 return prIBSSBssDesc;
1072 if (prIBSSBssDesc) { // CASE IV
1074 return prIBSSBssDesc;
1078 break; // Return NULL;
1086 return (P_BSS_DESC_T)NULL;
1088 } /* end of scanSearchExistingBssDesc() */
1091 /*----------------------------------------------------------------------------*/
1093 * @brief Delete BSS Descriptors from current list according to given Remove Policy.
1095 * @param[in] u4RemovePolicy Remove Policy.
1099 /*----------------------------------------------------------------------------*/
1101 scanRemoveBssDescsByPolicy (
1102 IN P_ADAPTER_T prAdapter,
1103 IN UINT_32 u4RemovePolicy
1106 P_CONNECTION_SETTINGS_T prConnSettings;
1107 P_SCAN_INFO_T prScanInfo;
1108 P_LINK_T prBSSDescList;
1109 P_LINK_T prFreeBSSDescList;
1110 P_BSS_DESC_T prBssDesc;
1115 prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
1116 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1117 prBSSDescList = &prScanInfo->rBSSDescList;
1118 prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1120 //DBGLOG(SCN, TRACE, ("Before Remove - Number Of SCAN Result = %ld\n",
1121 //prBSSDescList->u4NumElem));
1123 if (u4RemovePolicy & SCN_RM_POLICY_TIMEOUT) {
1124 P_BSS_DESC_T prBSSDescNext;
1125 OS_SYSTIME rCurrentTime;
1128 GET_CURRENT_SYSTIME(&rCurrentTime);
1130 /* Search BSS Desc from current SCAN result list. */
1131 LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1133 if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
1134 (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
1135 /* Don't remove the one currently we are connected. */
1139 if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
1140 SEC_TO_SYSTIME(SCN_BSS_DESC_REMOVE_TIMEOUT_SEC)) ) {
1142 //DBGLOG(SCN, TRACE, ("Remove TIMEOUT BSS DESC(%#x): MAC: "MACSTR", Current Time = %08lx, Update Time = %08lx\n",
1143 //prBssDesc, MAC2STR(prBssDesc->aucBSSID), rCurrentTime, prBssDesc->rUpdateTime));
1145 /* Remove this BSS Desc from the BSS Desc list */
1146 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1148 /* Return this BSS Desc to the free BSS Desc list. */
1149 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1153 else if (u4RemovePolicy & SCN_RM_POLICY_OLDEST_HIDDEN) {
1154 P_BSS_DESC_T prBssDescOldest = (P_BSS_DESC_T)NULL;
1157 /* Search BSS Desc from current SCAN result list. */
1158 LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1160 if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
1161 (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
1162 /* Don't remove the one currently we are connected. */
1166 if (!prBssDesc->fgIsHiddenSSID) {
1170 if (!prBssDescOldest) { /* 1st element */
1171 prBssDescOldest = prBssDesc;
1175 if (TIME_BEFORE(prBssDesc->rUpdateTime, prBssDescOldest->rUpdateTime)) {
1176 prBssDescOldest = prBssDesc;
1180 if (prBssDescOldest) {
1182 //DBGLOG(SCN, TRACE, ("Remove OLDEST HIDDEN BSS DESC(%#x): MAC: "MACSTR", Update Time = %08lx\n",
1183 //prBssDescOldest, MAC2STR(prBssDescOldest->aucBSSID), prBssDescOldest->rUpdateTime));
1185 /* Remove this BSS Desc from the BSS Desc list */
1186 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescOldest);
1188 /* Return this BSS Desc to the free BSS Desc list. */
1189 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDescOldest->rLinkEntry);
1192 else if (u4RemovePolicy & SCN_RM_POLICY_SMART_WEAKEST) {
1193 P_BSS_DESC_T prBssDescWeakest = (P_BSS_DESC_T)NULL;
1194 P_BSS_DESC_T prBssDescWeakestSameSSID = (P_BSS_DESC_T)NULL;
1195 UINT_32 u4SameSSIDCount = 0;
1198 /* Search BSS Desc from current SCAN result list. */
1199 LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1201 if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
1202 (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
1203 /* Don't remove the one currently we are connected. */
1207 if ((!prBssDesc->fgIsHiddenSSID) &&
1208 (EQUAL_SSID(prBssDesc->aucSSID,
1209 prBssDesc->ucSSIDLen,
1210 prConnSettings->aucSSID,
1211 prConnSettings->ucSSIDLen))) {
1215 if (!prBssDescWeakestSameSSID) {
1216 prBssDescWeakestSameSSID = prBssDesc;
1218 else if (prBssDesc->ucRCPI < prBssDescWeakestSameSSID->ucRCPI) {
1219 prBssDescWeakestSameSSID = prBssDesc;
1223 if (!prBssDescWeakest) { /* 1st element */
1224 prBssDescWeakest = prBssDesc;
1228 if (prBssDesc->ucRCPI < prBssDescWeakest->ucRCPI) {
1229 prBssDescWeakest = prBssDesc;
1234 if ((u4SameSSIDCount >= SCN_BSS_DESC_SAME_SSID_THRESHOLD) &&
1235 (prBssDescWeakestSameSSID)) {
1236 prBssDescWeakest = prBssDescWeakestSameSSID;
1239 if (prBssDescWeakest) {
1241 //DBGLOG(SCN, TRACE, ("Remove WEAKEST BSS DESC(%#x): MAC: "MACSTR", Update Time = %08lx\n",
1242 //prBssDescOldest, MAC2STR(prBssDescOldest->aucBSSID), prBssDescOldest->rUpdateTime));
1244 /* Remove this BSS Desc from the BSS Desc list */
1245 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescWeakest);
1247 /* Return this BSS Desc to the free BSS Desc list. */
1248 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDescWeakest->rLinkEntry);
1251 else if (u4RemovePolicy & SCN_RM_POLICY_ENTIRE) {
1252 P_BSS_DESC_T prBSSDescNext;
1254 LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1256 if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
1257 (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
1258 /* Don't remove the one currently we are connected. */
1262 /* Remove this BSS Desc from the BSS Desc list */
1263 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1265 /* Return this BSS Desc to the free BSS Desc list. */
1266 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1273 } /* end of scanRemoveBssDescsByPolicy() */
1276 /*----------------------------------------------------------------------------*/
1278 * @brief Delete BSS Descriptors from current list according to given BSSID.
1280 * @param[in] prAdapter Pointer to the Adapter structure.
1281 * @param[in] aucBSSID Given BSSID.
1285 /*----------------------------------------------------------------------------*/
1287 scanRemoveBssDescByBssid (
1288 IN P_ADAPTER_T prAdapter,
1289 IN UINT_8 aucBSSID[]
1292 P_SCAN_INFO_T prScanInfo;
1293 P_LINK_T prBSSDescList;
1294 P_LINK_T prFreeBSSDescList;
1295 P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T)NULL;
1296 P_BSS_DESC_T prBSSDescNext;
1302 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1303 prBSSDescList = &prScanInfo->rBSSDescList;
1304 prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1306 /* Check if such BSS Descriptor exists in a valid list */
1307 LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1309 if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) {
1311 /* Remove this BSS Desc from the BSS Desc list */
1312 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1314 /* Return this BSS Desc to the free BSS Desc list. */
1315 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1317 /* BSSID is not unique, so need to traverse whols link-list */
1322 } /* end of scanRemoveBssDescByBssid() */
1325 /*----------------------------------------------------------------------------*/
1327 * @brief Delete BSS Descriptors from current list according to given band configuration
1329 * @param[in] prAdapter Pointer to the Adapter structure.
1330 * @param[in] eBand Given band
1331 * @param[in] eNetTypeIndex AIS - Remove IBSS/Infrastructure BSS
1332 * BOW - Remove BOW BSS
1333 * P2P - Remove P2P BSS
1337 /*----------------------------------------------------------------------------*/
1339 scanRemoveBssDescByBandAndNetwork (
1340 IN P_ADAPTER_T prAdapter,
1341 IN ENUM_BAND_T eBand,
1342 IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex
1345 P_SCAN_INFO_T prScanInfo;
1346 P_LINK_T prBSSDescList;
1347 P_LINK_T prFreeBSSDescList;
1348 P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T)NULL;
1349 P_BSS_DESC_T prBSSDescNext;
1353 ASSERT(eBand <= BAND_NUM);
1354 ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM);
1356 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1357 prBSSDescList = &prScanInfo->rBSSDescList;
1358 prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1361 if(eBand == BAND_NULL) {
1362 return; /* no need to do anything, keep all scan result */
1365 /* Check if such BSS Descriptor exists in a valid list */
1366 LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1369 if(prBssDesc->eBand == eBand) {
1370 switch (eNetTypeIndex) {
1371 case NETWORK_TYPE_AIS_INDEX:
1372 if((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE)
1373 || (prBssDesc->eBSSType == BSS_TYPE_IBSS)) {
1378 case NETWORK_TYPE_P2P_INDEX:
1379 if(prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) {
1384 case NETWORK_TYPE_BOW_INDEX:
1385 if(prBssDesc->eBSSType == BSS_TYPE_BOW_DEVICE) {
1396 if(fgToRemove == TRUE) {
1397 /* Remove this BSS Desc from the BSS Desc list */
1398 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1400 /* Return this BSS Desc to the free BSS Desc list. */
1401 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1406 } /* end of scanRemoveBssDescByBand() */
1409 /*----------------------------------------------------------------------------*/
1411 * @brief Clear the CONNECTION FLAG of a specified BSS Descriptor.
1413 * @param[in] aucBSSID Given BSSID.
1417 /*----------------------------------------------------------------------------*/
1419 scanRemoveConnFlagOfBssDescByBssid (
1420 IN P_ADAPTER_T prAdapter,
1421 IN UINT_8 aucBSSID[]
1424 P_SCAN_INFO_T prScanInfo;
1425 P_LINK_T prBSSDescList;
1426 P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T)NULL;
1432 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1433 prBSSDescList = &prScanInfo->rBSSDescList;
1435 /* Search BSS Desc from current SCAN result list. */
1436 LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1438 if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) {
1439 prBssDesc->fgIsConnected = FALSE;
1440 prBssDesc->fgIsConnecting = FALSE;
1442 /* BSSID is not unique, so need to traverse whols link-list */
1448 } /* end of scanRemoveConnectionFlagOfBssDescByBssid() */
1451 /*----------------------------------------------------------------------------*/
1453 * @brief Allocate new BSS_DESC_T
1455 * @param[in] prAdapter Pointer to the Adapter structure.
1457 * @return Pointer to BSS Descriptor, if has free space. NULL, if has no space.
1459 /*----------------------------------------------------------------------------*/
1461 scanAllocateBssDesc (
1462 IN P_ADAPTER_T prAdapter
1465 P_SCAN_INFO_T prScanInfo;
1466 P_LINK_T prFreeBSSDescList;
1467 P_BSS_DESC_T prBssDesc;
1471 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1473 prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1475 LINK_REMOVE_HEAD(prFreeBSSDescList, prBssDesc, P_BSS_DESC_T);
1478 P_LINK_T prBSSDescList;
1480 kalMemZero(prBssDesc, sizeof(BSS_DESC_T));
1482 #if CFG_ENABLE_WIFI_DIRECT
1483 LINK_INITIALIZE(&(prBssDesc->rP2pDeviceList));
1484 prBssDesc->fgIsP2PPresent = FALSE;
1485 #endif /* CFG_ENABLE_WIFI_DIRECT */
1487 prBSSDescList = &prScanInfo->rBSSDescList;
1489 /* NOTE(Kevin): In current design, this new empty BSS_DESC_T will be
1490 * inserted to BSSDescList immediately.
1492 LINK_INSERT_TAIL(prBSSDescList, &prBssDesc->rLinkEntry);
1497 } /* end of scanAllocateBssDesc() */
1500 /*----------------------------------------------------------------------------*/
1502 * @brief This API parses Beacon/ProbeResp frame and insert extracted BSS_DESC_T
1503 * with IEs into prAdapter->rWifiVar.rScanInfo.aucScanBuffer
1505 * @param[in] prAdapter Pointer to the Adapter structure.
1506 * @param[in] prSwRfb Pointer to the receiving frame buffer.
1508 * @return Pointer to BSS Descriptor
1509 * NULL if the Beacon/ProbeResp frame is invalid
1511 /*----------------------------------------------------------------------------*/
1514 IN P_ADAPTER_T prAdapter,
1515 IN P_SW_RFB_T prSwRfb
1518 P_BSS_DESC_T prBssDesc = NULL;
1520 ENUM_BSS_TYPE_T eBSSType = BSS_TYPE_INFRASTRUCTURE;
1524 UINT_16 u2Offset = 0;
1526 P_WLAN_BEACON_FRAME_T prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T)NULL;
1527 P_IE_SSID_T prIeSsid = (P_IE_SSID_T)NULL;
1528 P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T)NULL;
1529 P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T)NULL;
1530 P_HIF_RX_HEADER_T prHifRxHdr;
1531 UINT_8 ucHwChannelNum = 0;
1532 UINT_8 ucIeDsChannelNum = 0;
1533 UINT_8 ucIeHtChannelNum = 0;
1534 BOOLEAN fgIsValidSsid = FALSE, fgEscape = FALSE;
1536 UINT_64 u8Timestamp;
1544 prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T)prSwRfb->pvHeader;
1546 WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2CapInfo, &u2CapInfo);
1547 WLAN_GET_FIELD_64(&prWlanBeaconFrame->au4Timestamp[0], &u8Timestamp);
1550 switch (u2CapInfo & CAP_INFO_BSS_TYPE) {
1552 /* It can also be Group Owner of P2P Group. */
1553 eBSSType = BSS_TYPE_INFRASTRUCTURE;
1557 eBSSType = BSS_TYPE_IBSS;
1560 /* 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) */
1561 eBSSType = BSS_TYPE_P2P_DEVICE;
1564 #if CFG_ENABLE_BT_OVER_WIFI
1565 // @TODO: add rule to identify BOW beacons
1572 //4 <1.1> Pre-parse SSID IE
1573 pucIE = prWlanBeaconFrame->aucInfoElem;
1574 u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
1575 (UINT_16)OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]);
1577 if (u2IELength > CFG_IE_BUFFER_SIZE) {
1578 u2IELength = CFG_IE_BUFFER_SIZE;
1581 IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
1582 switch (IE_ID(pucIE)) {
1584 if (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID) {
1587 /* D-Link DWL-900AP+ */
1588 if (IE_LEN(pucIE) == 0) {
1589 fgIsValidSsid = FALSE;
1591 /* Cisco AP1230A - (IE_LEN(pucIE) == 1) && (SSID_IE(pucIE)->aucSSID[0] == '\0') */
1592 /* Linksys WRK54G/ASUS WL520g - (IE_LEN(pucIE) == n) && (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') */
1594 for (i = 0; i < IE_LEN(pucIE); i++) {
1595 ucSSIDChar |= SSID_IE(pucIE)->aucSSID[i];
1599 fgIsValidSsid = TRUE;
1603 /* Update SSID to BSS Descriptor only if SSID is not hidden. */
1604 if (fgIsValidSsid == TRUE) {
1605 COPY_SSID(rSsid.aucSsid,
1607 SSID_IE(pucIE)->aucSSID,
1608 SSID_IE(pucIE)->ucLength);
1617 if(fgEscape == TRUE) {
1623 //4 <1.2> Replace existing BSS_DESC_T or allocate a new one
1624 prBssDesc = scanSearchExistingBssDescWithSsid(prAdapter,
1626 (PUINT_8)prWlanBeaconFrame->aucBSSID,
1627 (PUINT_8)prWlanBeaconFrame->aucSrcAddr,
1629 fgIsValidSsid == TRUE ? &rSsid : NULL);
1631 if (prBssDesc == (P_BSS_DESC_T)NULL) {
1633 //4 <1.2.1> First trial of allocation
1634 prBssDesc = scanAllocateBssDesc(prAdapter);
1639 //4 <1.2.2> Hidden is useless, remove the oldest hidden ssid. (for passive scan)
1640 scanRemoveBssDescsByPolicy(prAdapter,
1641 (SCN_RM_POLICY_EXCLUDE_CONNECTED | SCN_RM_POLICY_OLDEST_HIDDEN));
1643 //4 <1.2.3> Second tail of allocation
1644 prBssDesc = scanAllocateBssDesc(prAdapter);
1649 //4 <1.2.4> Remove the weakest one
1650 /* If there are more than half of BSS which has the same ssid as connection
1651 * setting, remove the weakest one from them.
1652 * Else remove the weakest one.
1654 scanRemoveBssDescsByPolicy(prAdapter,
1655 (SCN_RM_POLICY_EXCLUDE_CONNECTED | SCN_RM_POLICY_SMART_WEAKEST));
1657 //4 <1.2.5> reallocation
1658 prBssDesc = scanAllocateBssDesc(prAdapter);
1663 //4 <1.2.6> no space, should not happen
1664 //ASSERT(0); // still no space available ?
1672 OS_SYSTIME rCurrentTime;
1675 // if the received strength is much weaker than the original one,
1676 // ignore it due to it might be received on the folding frequency
1678 GET_CURRENT_SYSTIME(&rCurrentTime);
1680 prBssDesc->eBSSType = eBSSType;
1682 if(HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr) != prBssDesc->ucChannelNum &&
1683 prBssDesc->ucRCPI > prSwRfb->prHifRxHdr->ucRcpi) {
1685 // for signal strength is too much weaker and previous beacon is not stale
1686 if((prBssDesc->ucRCPI - prSwRfb->prHifRxHdr->ucRcpi) >= REPLICATED_BEACON_STRENGTH_THRESHOLD &&
1687 rCurrentTime - prBssDesc->rUpdateTime <= REPLICATED_BEACON_FRESH_PERIOD) {
1690 // for received beacons too close in time domain
1691 else if(rCurrentTime - prBssDesc->rUpdateTime <= REPLICATED_BEACON_TIME_THRESHOLD) {
1696 /* if Timestamp has been reset, re-generate BSS DESC 'cause AP should have reset itself */
1697 if(prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && u8Timestamp < prBssDesc->u8TimeStamp.QuadPart) {
1698 scanRemoveBssDescByBssid(prAdapter, prBssDesc->aucBSSID);
1700 prBssDesc = scanAllocateBssDesc(prAdapter);
1707 /* NOTE: Keep consistency of Scan Record during JOIN process */
1708 if (prBssDesc->fgIsConnecting) {
1712 //4 <2> Get information from Fixed Fields
1713 prBssDesc->eBSSType = eBSSType; /* Update the latest BSS type information. */
1715 COPY_MAC_ADDR(prBssDesc->aucSrcAddr, prWlanBeaconFrame->aucSrcAddr);
1717 COPY_MAC_ADDR(prBssDesc->aucBSSID, prWlanBeaconFrame->aucBSSID);
1719 prBssDesc->u8TimeStamp.QuadPart = u8Timestamp;
1721 WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2BeaconInterval, &prBssDesc->u2BeaconInterval);
1723 prBssDesc->u2CapInfo = u2CapInfo;
1726 //4 <2.1> Retrieve IEs for later parsing
1727 u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
1728 (UINT_16)OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]);
1730 if (u2IELength > CFG_IE_BUFFER_SIZE) {
1731 u2IELength = CFG_IE_BUFFER_SIZE;
1732 prBssDesc->fgIsIEOverflow = TRUE;
1735 prBssDesc->fgIsIEOverflow = FALSE;
1737 prBssDesc->u2IELength = u2IELength;
1739 kalMemCopy(prBssDesc->aucIEBuf, prWlanBeaconFrame->aucInfoElem, u2IELength);
1741 //4 <2.2> reset prBssDesc variables in case that AP has been reconfigured
1742 prBssDesc->fgIsERPPresent = FALSE;
1743 prBssDesc->fgIsHTPresent = FALSE;
1744 prBssDesc->eSco = CHNL_EXT_SCN;
1745 prBssDesc->fgIEWAPI = FALSE;
1746 #if CFG_RSN_MIGRATION
1747 prBssDesc->fgIERSN = FALSE;
1749 #if CFG_PRIVACY_MIGRATION
1750 prBssDesc->fgIEWPA = FALSE;
1754 //4 <3.1> Full IE parsing on SW_RFB_T
1755 pucIE = prWlanBeaconFrame->aucInfoElem;
1758 IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
1760 switch (IE_ID(pucIE)) {
1762 if ((!prIeSsid) && /* NOTE(Kevin): for Atheros IOT #1 */
1763 (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) {
1764 BOOLEAN fgIsHiddenSSID = FALSE;
1768 prIeSsid = (P_IE_SSID_T)pucIE;
1770 /* D-Link DWL-900AP+ */
1771 if (IE_LEN(pucIE) == 0) {
1772 fgIsHiddenSSID = TRUE;
1774 /* Cisco AP1230A - (IE_LEN(pucIE) == 1) && (SSID_IE(pucIE)->aucSSID[0] == '\0') */
1775 /* Linksys WRK54G/ASUS WL520g - (IE_LEN(pucIE) == n) && (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') */
1777 for (i = 0; i < IE_LEN(pucIE); i++) {
1778 ucSSIDChar |= SSID_IE(pucIE)->aucSSID[i];
1782 fgIsHiddenSSID = TRUE;
1786 /* Update SSID to BSS Descriptor only if SSID is not hidden. */
1787 if (!fgIsHiddenSSID) {
1788 COPY_SSID(prBssDesc->aucSSID,
1789 prBssDesc->ucSSIDLen,
1790 SSID_IE(pucIE)->aucSSID,
1791 SSID_IE(pucIE)->ucLength);
1797 case ELEM_ID_SUP_RATES:
1798 /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8.
1799 * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B),
1800 * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)"
1802 /* TP-LINK will set extra and incorrect ie with ELEM_ID_SUP_RATES */
1803 if ((!prIeSupportedRate) && (IE_LEN(pucIE) <= RATE_NUM)) {
1804 prIeSupportedRate = SUP_RATES_IE(pucIE);
1808 case ELEM_ID_DS_PARAM_SET:
1809 if (IE_LEN(pucIE) == ELEM_MAX_LEN_DS_PARAMETER_SET) {
1810 ucIeDsChannelNum = DS_PARAM_IE(pucIE)->ucCurrChnl;
1815 if (IE_LEN(pucIE) <= ELEM_MAX_LEN_TIM) {
1816 prBssDesc->ucDTIMPeriod = TIM_IE(pucIE)->ucDTIMPeriod;
1820 case ELEM_ID_IBSS_PARAM_SET:
1821 if (IE_LEN(pucIE) == ELEM_MAX_LEN_IBSS_PARAMETER_SET){
1822 prBssDesc->u2ATIMWindow = IBSS_PARAM_IE(pucIE)->u2ATIMWindow;
1826 #if 0 //CFG_SUPPORT_802_11D
1827 case ELEM_ID_COUNTRY_INFO:
1828 prBssDesc->prIECountry = (P_IE_COUNTRY_T)pucIE;
1832 case ELEM_ID_ERP_INFO:
1833 if (IE_LEN(pucIE) == ELEM_MAX_LEN_ERP) {
1834 prBssDesc->fgIsERPPresent = TRUE;
1838 case ELEM_ID_EXTENDED_SUP_RATES:
1839 if (!prIeExtSupportedRate) {
1840 prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE);
1844 #if CFG_RSN_MIGRATION
1846 if (rsnParseRsnIE(prAdapter, RSN_IE(pucIE), &prBssDesc->rRSNInfo)) {
1847 prBssDesc->fgIERSN = TRUE;
1848 prBssDesc->u2RsnCap = prBssDesc->rRSNInfo.u2RsnCap;
1849 if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) {
1850 rsnCheckPmkidCache(prAdapter, prBssDesc);
1856 case ELEM_ID_HT_CAP:
1857 prBssDesc->fgIsHTPresent = TRUE;
1861 if (IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) {
1865 if ((((P_IE_HT_OP_T) pucIE)->ucInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) {
1866 prBssDesc->eSco = (ENUM_CHNL_EXT_T)
1867 (((P_IE_HT_OP_T) pucIE)->ucInfo1 & HT_OP_INFO1_SCO);
1869 ucIeHtChannelNum = ((P_IE_HT_OP_T) pucIE)->ucPrimaryChannel;
1873 #if CFG_SUPPORT_WAPI
1875 if (wapiParseWapiIE(WAPI_IE(pucIE), &prBssDesc->rIEWAPI)) {
1876 prBssDesc->fgIEWAPI = TRUE;
1881 case ELEM_ID_VENDOR: // ELEM_ID_P2P, ELEM_ID_WMM
1884 UINT_16 u2SubTypeVersion;
1885 #if CFG_PRIVACY_MIGRATION
1886 if (rsnParseCheckForWFAInfoElem(prAdapter, pucIE, &ucOuiType, &u2SubTypeVersion)) {
1887 if ((ucOuiType == VENDOR_OUI_TYPE_WPA) &&
1888 (u2SubTypeVersion == VERSION_WPA)) {
1890 if (rsnParseWpaIE(prAdapter, WPA_IE(pucIE), &prBssDesc->rWPAInfo)) {
1891 prBssDesc->fgIEWPA = TRUE;
1897 #if CFG_ENABLE_WIFI_DIRECT
1898 if(prAdapter->fgIsP2PRegistered) {
1899 if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType)) {
1900 if (ucOuiType == VENDOR_OUI_TYPE_P2P) {
1901 prBssDesc->fgIsP2PPresent = TRUE;
1905 #endif /* CFG_ENABLE_WIFI_DIRECT */
1914 //4 <3.2> Save information from IEs - SSID
1915 /* Update Flag of Hidden SSID for used in SEARCH STATE. */
1917 /* NOTE(Kevin): in current driver, the ucSSIDLen == 0 represent
1918 * all cases of hidden SSID.
1919 * If the fgIsHiddenSSID == TRUE, it means we didn't get the ProbeResp with
1922 if (prBssDesc->ucSSIDLen == 0) {
1923 prBssDesc->fgIsHiddenSSID = TRUE;
1926 prBssDesc->fgIsHiddenSSID = FALSE;
1930 //4 <3.3> Check rate information in related IEs.
1931 if (prIeSupportedRate || prIeExtSupportedRate) {
1932 rateGetRateSetFromIEs(prIeSupportedRate,
1933 prIeExtSupportedRate,
1934 &prBssDesc->u2OperationalRateSet,
1935 &prBssDesc->u2BSSBasicRateSet,
1936 &prBssDesc->fgIsUnknownBssBasicRate);
1940 //4 <4> Update information from HIF RX Header
1942 prHifRxHdr = prSwRfb->prHifRxHdr;
1946 //4 <4.1> Get TSF comparison result
1947 prBssDesc->fgIsLargerTSF = HIF_RX_HDR_GET_TCL_FLAG(prHifRxHdr);
1949 //4 <4.2> Get Band information
1950 prBssDesc->eBand = HIF_RX_HDR_GET_RF_BAND(prHifRxHdr);
1952 //4 <4.2> Get channel and RCPI information
1953 ucHwChannelNum = HIF_RX_HDR_GET_CHNL_NUM(prHifRxHdr);
1955 if (BAND_2G4 == prBssDesc->eBand) {
1957 /* Update RCPI if in right channel */
1958 if (ucIeDsChannelNum >= 1 && ucIeDsChannelNum <= 14) {
1960 // Receive Beacon/ProbeResp frame from adjacent channel.
1961 if ((ucIeDsChannelNum == ucHwChannelNum) ||
1962 (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) {
1963 prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
1966 // trust channel information brought by IE
1967 prBssDesc->ucChannelNum = ucIeDsChannelNum;
1969 else if(ucIeHtChannelNum >= 1 && ucIeHtChannelNum <= 14) {
1970 // Receive Beacon/ProbeResp frame from adjacent channel.
1971 if ((ucIeHtChannelNum == ucHwChannelNum) ||
1972 (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) {
1973 prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
1976 // trust channel information brought by IE
1977 prBssDesc->ucChannelNum = ucIeHtChannelNum;
1980 prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
1982 prBssDesc->ucChannelNum = ucHwChannelNum;
1987 if(ucIeHtChannelNum >= 1 && ucIeHtChannelNum < 200) {
1988 // Receive Beacon/ProbeResp frame from adjacent channel.
1989 if ((ucIeHtChannelNum == ucHwChannelNum) ||
1990 (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) {
1991 prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
1994 // trust channel information brought by IE
1995 prBssDesc->ucChannelNum = ucIeHtChannelNum;
1998 /* Always update RCPI */
1999 prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
2001 prBssDesc->ucChannelNum = ucHwChannelNum;
2007 //4 <5> PHY type setting
2008 prBssDesc->ucPhyTypeSet = 0;
2010 if (BAND_2G4 == prBssDesc->eBand) {
2011 /* check if support 11n */
2012 if (prBssDesc->fgIsHTPresent) {
2013 prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT;
2016 /* if not 11n only */
2017 if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) {
2018 /* check if support 11g */
2019 if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM) ||
2020 prBssDesc->fgIsERPPresent) {
2021 prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_ERP;
2024 /* if not 11g only */
2025 if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_OFDM)) {
2026 /* check if support 11b */
2027 if ((prBssDesc->u2OperationalRateSet & RATE_SET_HR_DSSS)) {
2028 prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS;
2033 else { /* (BAND_5G == prBssDesc->eBande) */
2034 /* check if support 11n */
2035 if (prBssDesc->fgIsHTPresent) {
2036 prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT;
2039 /* if not 11n only */
2040 if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) {
2041 /* Support 11a definitely */
2042 prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM;
2044 ASSERT(!(prBssDesc->u2OperationalRateSet & RATE_SET_HR_DSSS));
2049 //4 <6> Update BSS_DESC_T's Last Update TimeStamp.
2050 GET_CURRENT_SYSTIME(&prBssDesc->rUpdateTime);
2057 extern int numOfTblRssi;
2058 extern TABLE_RSSI mTABLE_RSSI[MAX_SCAN_RSSI_NUM];
2059 extern int mTblRssiStatus[MAX_SCAN_RSSI_NUM];
2061 #define RSSI_DEG(x...) //printk(x)
2063 PARAM_RSSI processAvgRssi(UINT_8 ucRCPI, PARAM_MAC_ADDRESS rMacAddr)
2066 PARAM_RSSI rRssi = RCPI_TO_dBm(ucRCPI);
2067 PARAM_RSSI rRssi2 = rRssi;
2068 PARAM_RSSI AvgRssiX8, AvgRssi;
2073 RSSI_DEG("---- processAvgRssi ---- \n");
2076 for(i = 0; i < numOfTblRssi; i++) {
2077 RSSI_DEG("-%02x:%02x:%02x:%02x:%02x:%02x\n",
2078 mTABLE_RSSI[i].arMacAddress[0], mTABLE_RSSI[i].arMacAddress[1], mTABLE_RSSI[i].arMacAddress[2], mTABLE_RSSI[i].arMacAddress[3], mTABLE_RSSI[i].arMacAddress[4], mTABLE_RSSI[i].arMacAddress[5]);
2079 if(EQUAL_MAC_ADDR(rMacAddr, mTABLE_RSSI[i].arMacAddress)) {
2081 AvgRssiX8 = mTABLE_RSSI[i].AvgRssiX8;
2082 AvgRssi = mTABLE_RSSI[i].AvgRssi;
2083 mTblRssiStatus[i] = 1;
2089 AvgRssiX8 = rRssi << 3;
2092 AvgRssiX8 = (AvgRssiX8 - AvgRssi) + rRssi;
2095 AvgRssi = AvgRssiX8 >> 3;
2098 COPY_MAC_ADDR(mTABLE_RSSI[numOfTblRssi].arMacAddress, rMacAddr);
2099 mTABLE_RSSI[numOfTblRssi].AvgRssi = AvgRssi;
2100 mTABLE_RSSI[numOfTblRssi].AvgRssiX8 = AvgRssiX8;
2102 mTblRssiStatus[i] = 1;
2104 mTABLE_RSSI[i].AvgRssi = AvgRssi;
2105 mTABLE_RSSI[i].AvgRssiX8 = AvgRssiX8;
2108 RSSI_DEG("results : %02x:%02x:%02x:%02x:%02x:%02x %d -> %d\n",
2109 rMacAddr[0], rMacAddr[1], rMacAddr[2], rMacAddr[3], rMacAddr[4], rMacAddr[5], rRssi2, AvgRssi);
2114 void sortAvgRssi(void)
2118 RSSI_DEG("---- sortAvgRssi numOfTblRssi = %d ---- \n", numOfTblRssi);
2120 for(i = 0; i < numOfTblRssi; i++) {
2121 if(mTblRssiStatus[i] == 1) {
2122 memmove(&mTABLE_RSSI[index++], &mTABLE_RSSI[i], sizeof(TABLE_RSSI));
2125 numOfTblRssi = index;
2127 RSSI_DEG("--numOfTblRssi = %d.\n", numOfTblRssi);
2129 for(i = 0; i < numOfTblRssi; i++) {
2130 mTblRssiStatus[i] = 0;
2136 /*----------------------------------------------------------------------------*/
2138 * @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to scan result for query
2140 * @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure.
2142 * @retval WLAN_STATUS_SUCCESS It is a valid Scan Result and been sent to the host.
2143 * @retval WLAN_STATUS_FAILURE It is not a valid Scan Result.
2145 /*----------------------------------------------------------------------------*/
2148 IN P_ADAPTER_T prAdapter,
2149 IN P_BSS_DESC_T prBssDesc,
2150 IN P_SW_RFB_T prSwRfb
2153 P_SCAN_INFO_T prScanInfo;
2154 UINT_8 aucRatesEx[PARAM_MAX_LEN_RATES_EX];
2155 P_WLAN_BEACON_FRAME_T prWlanBeaconFrame;
2156 PARAM_MAC_ADDRESS rMacAddr;
2158 ENUM_PARAM_NETWORK_TYPE_T eNetworkType;
2159 PARAM_802_11_CONFIG_T rConfiguration;
2160 ENUM_PARAM_OP_MODE_T eOpMode;
2161 UINT_8 ucRateLen = 0;
2168 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
2170 if (prBssDesc->eBand == BAND_2G4) {
2171 if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM)
2172 || prBssDesc->fgIsERPPresent) {
2173 eNetworkType = PARAM_NETWORK_TYPE_OFDM24;
2176 eNetworkType = PARAM_NETWORK_TYPE_DS;
2180 ASSERT(prBssDesc->eBand == BAND_5G);
2181 eNetworkType = PARAM_NETWORK_TYPE_OFDM5;
2184 if(prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) {
2185 /* NOTE(Kevin): Not supported by WZC(TBD) */
2186 return WLAN_STATUS_FAILURE;
2189 prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T)prSwRfb->pvHeader;
2190 COPY_MAC_ADDR(rMacAddr, prWlanBeaconFrame->aucBSSID);
2191 COPY_SSID(rSsid.aucSsid,
2194 prBssDesc->ucSSIDLen);
2196 rConfiguration.u4Length = sizeof(PARAM_802_11_CONFIG_T);
2197 rConfiguration.u4BeaconPeriod = (UINT_32) prWlanBeaconFrame->u2BeaconInterval;
2198 rConfiguration.u4ATIMWindow = prBssDesc->u2ATIMWindow;
2199 rConfiguration.u4DSConfig = nicChannelNum2Freq(prBssDesc->ucChannelNum);
2200 rConfiguration.rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T);
2202 rateGetDataRatesFromRateSet(prBssDesc->u2OperationalRateSet,
2207 /* NOTE(Kevin): Set unused entries, if any, at the end of the array to 0.
2208 * from OID_802_11_BSSID_LIST
2210 for (i = ucRateLen; i < sizeof(aucRatesEx) / sizeof(aucRatesEx[0]) ; i++) {
2214 switch(prBssDesc->eBSSType) {
2216 eOpMode = NET_TYPE_IBSS;
2219 case BSS_TYPE_INFRASTRUCTURE:
2220 case BSS_TYPE_P2P_DEVICE:
2221 case BSS_TYPE_BOW_DEVICE:
2223 eOpMode = NET_TYPE_INFRA;
2228 AvgRssi = processAvgRssi(prBssDesc->ucRCPI, rMacAddr);
2231 kalIndicateBssInfo(prAdapter->prGlueInfo,
2232 (PUINT_8)prSwRfb->pvHeader,
2233 prSwRfb->u2PacketLen,
2234 prBssDesc->ucChannelNum,
2238 RCPI_TO_dBm(prBssDesc->ucRCPI));
2241 nicAddScanResult(prAdapter,
2244 prWlanBeaconFrame->u2CapInfo & CAP_INFO_PRIVACY ? 1 : 0,
2245 RCPI_TO_dBm(prBssDesc->ucRCPI),
2250 prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen,
2251 (PUINT_8)((UINT_32)(prSwRfb->pvHeader) + WLAN_MAC_MGMT_HEADER_LEN));
2253 return WLAN_STATUS_SUCCESS;
2255 } /* end of scanAddScanResult() */
2258 /*----------------------------------------------------------------------------*/
2260 * @brief Parse the content of given Beacon or ProbeResp Frame.
2262 * @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure.
2264 * @retval WLAN_STATUS_SUCCESS if not report this SW_RFB_T to host
2265 * @retval WLAN_STATUS_PENDING if report this SW_RFB_T to host as scan result
2267 /*----------------------------------------------------------------------------*/
2269 scanProcessBeaconAndProbeResp (
2270 IN P_ADAPTER_T prAdapter,
2271 IN P_SW_RFB_T prSwRfb
2274 P_CONNECTION_SETTINGS_T prConnSettings;
2275 P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T)NULL;
2276 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2277 P_BSS_INFO_T prAisBssInfo;
2278 P_WLAN_BEACON_FRAME_T prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T)NULL;
2280 P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T)NULL;
2286 //4 <0> Ignore invalid Beacon Frame
2287 if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) <
2288 (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN)) {
2296 prSltInfo = &prAdapter->rWifiVar.rSltInfo;
2298 if (prSltInfo->fgIsDUT) {
2299 DBGLOG(P2P, INFO, ("\n\rBCN: RX\n"));
2300 prSltInfo->u4BeaconReceiveCnt++;
2301 return WLAN_STATUS_SUCCESS;
2304 return WLAN_STATUS_SUCCESS;
2309 prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
2310 prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
2311 prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T)prSwRfb->pvHeader;
2313 //4 <1> Parse and add into BSS_DESC_T
2314 prBssDesc = scanAddToBssDesc(prAdapter, prSwRfb);
2318 //4 <1.1> Beacon Change Detection for Connected BSS
2319 if(prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED &&
2320 ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && prConnSettings->eOPMode != NET_TYPE_IBSS)
2321 || (prBssDesc->eBSSType == BSS_TYPE_IBSS && prConnSettings->eOPMode != NET_TYPE_INFRA)) &&
2322 EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID) &&
2323 EQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen)) {
2324 BOOLEAN fgNeedDisconnect = FALSE;
2326 #if CFG_SUPPORT_BEACON_CHANGE_DETECTION
2327 // <1.1.2> check if supported rate differs
2328 if(prAisBssInfo->u2OperationalRateSet != prBssDesc->u2OperationalRateSet) {
2329 fgNeedDisconnect = TRUE;
2333 // <1.1.3> beacon content change detected, disconnect immediately
2334 if(fgNeedDisconnect == TRUE) {
2335 aisBssBeaconTimeout(prAdapter);
2339 //4 <1.1> Update AIS_BSS_INFO
2340 if(((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && prConnSettings->eOPMode != NET_TYPE_IBSS)
2341 || (prBssDesc->eBSSType == BSS_TYPE_IBSS && prConnSettings->eOPMode != NET_TYPE_INFRA))) {
2342 if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
2344 /* *not* checking prBssDesc->fgIsConnected anymore,
2345 * due to Linksys AP uses " " as hidden SSID, and would have different BSS descriptor */
2346 if ((!prAisBssInfo->ucDTIMPeriod) &&
2347 EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID) &&
2348 (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) &&
2349 ((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_BEACON)) {
2351 prAisBssInfo->ucDTIMPeriod = prBssDesc->ucDTIMPeriod;
2353 /* sync with firmware for beacon information */
2354 nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_AIS_INDEX);
2358 #if CFG_SUPPORT_ADHOC
2359 if (EQUAL_SSID(prBssDesc->aucSSID,
2360 prBssDesc->ucSSIDLen,
2361 prConnSettings->aucSSID,
2362 prConnSettings->ucSSIDLen) &&
2363 (prBssDesc->eBSSType == BSS_TYPE_IBSS) &&
2364 (prAisBssInfo->eCurrentOPMode == OP_MODE_IBSS)) {
2366 ibssProcessMatchedBeacon(prAdapter, prAisBssInfo, prBssDesc, prSwRfb->prHifRxHdr->ucRcpi);
2368 #endif /* CFG_SUPPORT_ADHOC */
2371 rlmProcessBcn(prAdapter,
2373 ((P_WLAN_BEACON_FRAME_T)(prSwRfb->pvHeader))->aucInfoElem,
2374 (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
2375 (UINT_16)(OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0])));
2377 //4 <3> Send SW_RFB_T to HIF when we perform SCAN for HOST
2378 if(prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE
2379 || prBssDesc->eBSSType == BSS_TYPE_IBSS) {
2380 /* for AIS, send to host */
2381 if (prConnSettings->fgIsScanReqIssued &&
2382 rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum) == TRUE) {
2385 BOOLEAN fgAddToScanResult;
2387 /* check ucChannelNum/eBand for adjacement channel filtering */
2388 if(cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel) == TRUE &&
2389 (eBand != prBssDesc->eBand || ucChannel != prBssDesc->ucChannelNum)) {
2390 fgAddToScanResult = FALSE;
2393 fgAddToScanResult = TRUE;
2396 if(fgAddToScanResult == TRUE) {
2397 rStatus = scanAddScanResult(prAdapter, prBssDesc, prSwRfb);
2402 #if CFG_ENABLE_WIFI_DIRECT
2403 if(prAdapter->fgIsP2PRegistered) {
2404 scanP2pProcessBeaconAndProbeResp(
2416 } /* end of scanProcessBeaconAndProbeResp() */
2419 /*----------------------------------------------------------------------------*/
2421 * \brief Search the Candidate of BSS Descriptor for JOIN(Infrastructure) or
2422 * MERGE(AdHoc) according to current Connection Policy.
2424 * \return Pointer to BSS Descriptor, if found. NULL, if not found
2426 /*----------------------------------------------------------------------------*/
2428 scanSearchBssDescByPolicy (
2429 IN P_ADAPTER_T prAdapter,
2430 IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex
2433 P_CONNECTION_SETTINGS_T prConnSettings;
2434 P_BSS_INFO_T prBssInfo;
2435 P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
2436 P_SCAN_INFO_T prScanInfo;
2438 P_LINK_T prBSSDescList;
2440 P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T)NULL;
2441 P_BSS_DESC_T prPrimaryBssDesc = (P_BSS_DESC_T)NULL;
2442 P_BSS_DESC_T prCandidateBssDesc = (P_BSS_DESC_T)NULL;
2444 P_STA_RECORD_T prStaRec = (P_STA_RECORD_T)NULL;
2445 P_STA_RECORD_T prPrimaryStaRec;
2446 P_STA_RECORD_T prCandidateStaRec = (P_STA_RECORD_T)NULL;
2448 OS_SYSTIME rCurrentTime;
2450 /* The first one reach the check point will be our candidate */
2451 BOOLEAN fgIsFindFirst = (BOOLEAN)FALSE;
2453 BOOLEAN fgIsFindBestRSSI = (BOOLEAN)FALSE;
2454 BOOLEAN fgIsFindBestEncryptionLevel = (BOOLEAN)FALSE;
2455 //BOOLEAN fgIsFindMinChannelLoad = (BOOLEAN)FALSE;
2457 /* TODO(Kevin): Support Min Channel Load */
2458 //UINT_8 aucChannelLoad[CHANNEL_NUM] = {0};
2460 BOOLEAN fgIsFixedChannel;
2466 prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
2467 prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]);
2469 prAisSpecBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo);
2471 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
2472 prBSSDescList = &prScanInfo->rBSSDescList;
2474 GET_CURRENT_SYSTIME(&rCurrentTime);
2476 /* check for fixed channel operation */
2477 if(eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) {
2478 fgIsFixedChannel = cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel);
2481 fgIsFixedChannel = FALSE;
2485 if (prConnSettings->ucSSIDLen < ELEM_MAX_LEN_SSID) {
2486 prConnSettings->aucSSID[prConnSettings->ucSSIDLen] = '\0';
2490 DBGLOG(SCN, INFO, ("SEARCH: Num Of BSS_DESC_T = %d, Look for SSID: %s\n",
2491 prBSSDescList->u4NumElem, prConnSettings->aucSSID));
2494 //4 <1> The outer loop to search for a candidate.
2495 LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
2497 /* TODO(Kevin): Update Minimum Channel Load Information here */
2499 DBGLOG(SCN, INFO, ("SEARCH: ["MACSTR"], SSID:%s\n",
2500 MAC2STR(prBssDesc->aucBSSID), prBssDesc->aucSSID));
2503 //4 <2> Check PHY Type and attributes
2504 //4 <2.1> Check Unsupported BSS PHY Type
2505 if (!(prBssDesc->ucPhyTypeSet & (prAdapter->rWifiVar.ucAvailablePhyTypeSet))) {
2507 DBGLOG(SCN, INFO, ("SEARCH: Ignore unsupported ucPhyTypeSet = %x\n",
2508 prBssDesc->ucPhyTypeSet));
2512 //4 <2.2> Check if has unknown NonHT BSS Basic Rate Set.
2513 if (prBssDesc->fgIsUnknownBssBasicRate) {
2518 //4 <2.3> Check if fixed operation cases should be aware
2519 if (fgIsFixedChannel == TRUE &&
2520 (prBssDesc->eBand != eBand || prBssDesc->ucChannelNum != ucChannel)) {
2524 //4 <2.4> Check if the channel is legal under regulatory domain
2525 if(rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum) == FALSE) {
2529 //4 <2.5> Check if this BSS_DESC_T is stale
2530 if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
2531 SEC_TO_SYSTIME(SCN_BSS_DESC_REMOVE_TIMEOUT_SEC)) ) {
2536 //4 <3> Check if reach the excessive join retry limit
2537 /* NOTE(Kevin): STA_RECORD_T is recorded by TA. */
2538 prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) eNetTypeIndex,
2539 prBssDesc->aucSrcAddr);
2543 * The Status Code is the result of a Previous Connection Request, we use this as SCORE for choosing a proper
2544 * candidate (Also used for compare see <6>)
2545 * The Reason Code is an indication of the reason why AP reject us, we use this Code for "Reject"
2546 * a SCAN result to become our candidate(Like a blacklist).
2548 #if 0 /* TODO(Kevin): */
2549 if (prStaRec->u2ReasonCode != REASON_CODE_RESERVED) {
2550 DBGLOG(SCN, INFO, ("SEARCH: Ignore BSS with previous Reason Code = %d\n",
2551 prStaRec->u2ReasonCode));
2556 if (prStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL) {
2557 /* NOTE(Kevin): greedy association - after timeout, we'll still
2558 * try to associate to the AP whose STATUS of conection attempt
2560 * We may also use (ucJoinFailureCount x JOIN_RETRY_INTERVAL_SEC) for
2563 if ((prStaRec->ucJoinFailureCount < JOIN_MAX_RETRY_FAILURE_COUNT) ||
2564 (CHECK_FOR_TIMEOUT(rCurrentTime,
2565 prStaRec->rLastJoinTime,
2566 SEC_TO_SYSTIME(JOIN_RETRY_INTERVAL_SEC)))) {
2568 /* NOTE(Kevin): Every JOIN_RETRY_INTERVAL_SEC interval, we can retry
2569 * JOIN_MAX_RETRY_FAILURE_COUNT times.
2571 if (prStaRec->ucJoinFailureCount >= JOIN_MAX_RETRY_FAILURE_COUNT) {
2572 prStaRec->ucJoinFailureCount = 0;
2574 DBGLOG(SCN, INFO, ("SEARCH: Try to join BSS again which has Status Code = %d (Curr = %ld/Last Join = %ld)\n",
2575 prStaRec->u2StatusCode, rCurrentTime, prStaRec->rLastJoinTime));
2578 DBGLOG(SCN, INFO, ("SEARCH: Ignore BSS which reach maximum Join Retry Count = %d \n",
2579 JOIN_MAX_RETRY_FAILURE_COUNT));
2587 //4 <4> Check for various NETWORK conditions
2588 if (eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) {
2590 //4 <4.1> Check BSS Type for the corresponding Operation Mode in Connection Setting
2591 /* NOTE(Kevin): For NET_TYPE_AUTO_SWITCH, we will always pass following check. */
2592 if (((prConnSettings->eOPMode == NET_TYPE_INFRA) &&
2593 (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE)) ||
2594 ((prConnSettings->eOPMode == NET_TYPE_IBSS || prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS) &&
2595 (prBssDesc->eBSSType != BSS_TYPE_IBSS))) {
2597 DBGLOG(SCN, INFO, ("SEARCH: Ignore eBSSType = %s\n",
2598 ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) ?
2599 "INFRASTRUCTURE" : "IBSS")));
2603 //4 <4.2> Check AP's BSSID if OID_802_11_BSSID has been set.
2604 if ((prConnSettings->fgIsConnByBssidIssued) &&
2605 (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE)) {
2607 if (UNEQUAL_MAC_ADDR(prConnSettings->aucBSSID, prBssDesc->aucBSSID)) {
2609 DBGLOG(SCN, INFO, ("SEARCH: Ignore due to BSSID was not matched!\n"));
2614 #if CFG_SUPPORT_ADHOC
2615 //4 <4.3> Check for AdHoc Mode
2616 if (prBssDesc->eBSSType == BSS_TYPE_IBSS) {
2617 OS_SYSTIME rCurrentTime;
2619 //4 <4.3.1> Check if this SCAN record has been updated recently for IBSS.
2620 /* NOTE(Kevin): Because some STA may change its BSSID frequently after it
2621 * create the IBSS - e.g. IPN2220, so we need to make sure we get the new one.
2622 * For BSS, if the old record was matched, however it won't be able to pass
2623 * the Join Process later.
2625 GET_CURRENT_SYSTIME(&rCurrentTime);
2626 if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
2627 SEC_TO_SYSTIME(SCN_ADHOC_BSS_DESC_TIMEOUT_SEC))) {
2628 DBGLOG(SCN, LOUD, ("SEARCH: Skip old record of BSS Descriptor - BSSID:["MACSTR"]\n\n",
2629 MAC2STR(prBssDesc->aucBSSID)));
2633 //4 <4.3.2> Check Peer's capability
2634 if (ibssCheckCapabilityForAdHocMode(prAdapter, prBssDesc) == WLAN_STATUS_FAILURE) {
2637 ("SEARCH: Ignore BSS DESC MAC: "MACSTR", Capability is not supported for current AdHoc Mode.\n",
2638 MAC2STR(prPrimaryBssDesc->aucBSSID)));
2644 //4 <4.3.3> Compare TSF
2645 if (prBssInfo->fgIsBeaconActivated &&
2646 UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID)) {
2649 ("SEARCH: prBssDesc->fgIsLargerTSF = %d\n",
2650 prBssDesc->fgIsLargerTSF));
2652 if (!prBssDesc->fgIsLargerTSF) {
2654 ("SEARCH: Ignore BSS DESC MAC: ["MACSTR"], Smaller TSF\n", MAC2STR(prBssDesc->aucBSSID)));
2659 #endif /* CFG_SUPPORT_ADHOC */
2666 #if 0 /* TODO(Kevin): For IBSS */
2667 //4 <2.c> Check if this SCAN record has been updated recently for IBSS.
2668 /* NOTE(Kevin): Because some STA may change its BSSID frequently after it
2669 * create the IBSS, so we need to make sure we get the new one.
2670 * For BSS, if the old record was matched, however it won't be able to pass
2671 * the Join Process later.
2673 if (prBssDesc->eBSSType == BSS_TYPE_IBSS) {
2674 OS_SYSTIME rCurrentTime;
2676 GET_CURRENT_SYSTIME(&rCurrentTime);
2677 if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
2678 SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) {
2679 DBGLOG(SCAN, TRACE, ("Skip old record of BSS Descriptor - BSSID:["MACSTR"]\n\n",
2680 MAC2STR(prBssDesc->aucBSSID)));
2685 if ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) &&
2686 (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED)) {
2687 OS_SYSTIME rCurrentTime;
2689 GET_CURRENT_SYSTIME(&rCurrentTime);
2690 if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
2691 SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) {
2692 DBGLOG(SCAN, TRACE, ("Skip old record of BSS Descriptor - BSSID:["MACSTR"]\n\n",
2693 MAC2STR(prBssDesc->aucBSSID)));
2699 //4 <4B> Check for IBSS AdHoc Mode.
2700 /* Skip if one or more BSS Basic Rate are not supported by current AdHocMode */
2701 if (prPrimaryBssDesc->eBSSType == BSS_TYPE_IBSS) {
2702 //4 <4B.1> Check if match the Capability of current IBSS AdHoc Mode.
2703 if (ibssCheckCapabilityForAdHocMode(prAdapter, prPrimaryBssDesc) == WLAN_STATUS_FAILURE) {
2706 ("Ignore BSS DESC MAC: "MACSTR", Capability is not supported for current AdHoc Mode.\n",
2707 MAC2STR(prPrimaryBssDesc->aucBSSID)));
2713 //4 <4B.2> IBSS Merge Decision Flow for SEARCH STATE.
2714 if (prAdapter->fgIsIBSSActive &&
2715 UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prPrimaryBssDesc->aucBSSID)) {
2717 if (!fgIsLocalTSFRead) {
2718 NIC_GET_CURRENT_TSF(prAdapter, &rCurrentTsf);
2721 ("\n\nCurrent TSF : %08lx-%08lx\n\n",
2722 rCurrentTsf.u.HighPart, rCurrentTsf.u.LowPart));
2725 if (rCurrentTsf.QuadPart > prPrimaryBssDesc->u8TimeStamp.QuadPart) {
2727 ("Ignore BSS DESC MAC: ["MACSTR"], Current BSSID: ["MACSTR"].\n",
2728 MAC2STR(prPrimaryBssDesc->aucBSSID), MAC2STR(prBssInfo->aucBSSID)));
2731 ("\n\nBSS's TSF : %08lx-%08lx\n\n",
2732 prPrimaryBssDesc->u8TimeStamp.u.HighPart, prPrimaryBssDesc->u8TimeStamp.u.LowPart));
2734 prPrimaryBssDesc->fgIsLargerTSF = FALSE;
2738 prPrimaryBssDesc->fgIsLargerTSF = TRUE;
2744 //4 <5> Check the Encryption Status.
2745 if (rsnPerformPolicySelection(prPrimaryBssDesc)) {
2747 if (prPrimaryBssDesc->ucEncLevel > 0) {
2748 fgIsFindBestEncryptionLevel = TRUE;
2750 fgIsFindFirst = FALSE;
2754 /* Can't pass the Encryption Status Check, get next one */
2758 /* For RSN Pre-authentication, update the PMKID canidate list for
2759 same SSID and encrypt status */
2760 /* Update PMKID candicate list. */
2761 if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) {
2762 rsnUpdatePmkidCandidateList(prPrimaryBssDesc);
2763 if (prAdapter->rWifiVar.rAisBssInfo.u4PmkidCandicateCount) {
2764 prAdapter->rWifiVar.rAisBssInfo.fgIndicatePMKID = rsnCheckPmkidCandicate();
2771 prPrimaryBssDesc = (P_BSS_DESC_T)NULL;
2773 //4 <6> Check current Connection Policy.
2774 switch (prConnSettings->eConnectionPolicy) {
2775 case CONNECT_BY_SSID_BEST_RSSI:
2776 /* Choose Hidden SSID to join only if the `fgIsEnableJoin...` is TRUE */
2777 if (prAdapter->rWifiVar.fgEnableJoinToHiddenSSID && prBssDesc->fgIsHiddenSSID) {
2778 /* NOTE(Kevin): following if () statement means that
2779 * If Target is hidden, then we won't connect when user specify SSID_ANY policy.
2781 if (prConnSettings->ucSSIDLen) {
2782 prPrimaryBssDesc = prBssDesc;
2784 fgIsFindBestRSSI = TRUE;
2788 else if (EQUAL_SSID(prBssDesc->aucSSID,
2789 prBssDesc->ucSSIDLen,
2790 prConnSettings->aucSSID,
2791 prConnSettings->ucSSIDLen)) {
2792 prPrimaryBssDesc = prBssDesc;
2794 fgIsFindBestRSSI = TRUE;
2798 case CONNECT_BY_SSID_ANY:
2799 /* NOTE(Kevin): In this policy, we don't know the desired
2800 * SSID from user, so we should exclude the Hidden SSID from scan list.
2801 * And because we refuse to connect to Hidden SSID node at the beginning, so
2802 * when the JOIN Module deal with a BSS_DESC_T which has fgIsHiddenSSID == TRUE,
2803 * then the Connection Settings must be valid without doubt.
2805 if (!prBssDesc->fgIsHiddenSSID) {
2806 prPrimaryBssDesc = prBssDesc;
2808 fgIsFindFirst = TRUE;
2812 case CONNECT_BY_BSSID:
2813 if(EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prConnSettings->aucBSSID)) {
2814 prPrimaryBssDesc = prBssDesc;
2823 /* Primary Candidate was not found */
2824 if (prPrimaryBssDesc == NULL) {
2828 //4 <7> Check the Encryption Status.
2829 if (prPrimaryBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) {
2830 #if CFG_SUPPORT_WAPI
2831 if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) {
2832 if (wapiPerformPolicySelection(prAdapter, prPrimaryBssDesc)) {
2833 fgIsFindFirst = TRUE;
2836 /* Can't pass the Encryption Status Check, get next one */
2842 #if CFG_RSN_MIGRATION
2843 if (rsnPerformPolicySelection(prAdapter, prPrimaryBssDesc)) {
2844 if (prAisSpecBssInfo->fgCounterMeasure) {
2845 DBGLOG(RSN, INFO, ("Skip while at counter measure period!!!\n"));
2849 if (prPrimaryBssDesc->ucEncLevel > 0) {
2850 fgIsFindBestEncryptionLevel = TRUE;
2852 fgIsFindFirst = FALSE;
2856 /* Update PMKID candicate list. */
2857 if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) {
2858 rsnUpdatePmkidCandidateList(prPrimaryBssDesc);
2859 if (prAisSpecBssInfo->u4PmkidCandicateCount) {
2860 if (rsnCheckPmkidCandicate()) {
2861 DBGLOG(RSN, WARN, ("Prepare a timer to indicate candidate "MACSTR"\n",
2862 MAC2STR(prAisSpecBssInfo->arPmkidCache[prAisSpecBssInfo->u4PmkidCacheCount].rBssidInfo.aucBssid)));
2863 cnmTimerStopTimer(&prAisSpecBssInfo->rPreauthenticationTimer);
2864 cnmTimerStartTimer(&prAisSpecBssInfo->rPreauthenticationTimer,
2865 SEC_TO_MSEC(WAIT_TIME_IND_PMKID_CANDICATE_SEC));
2872 /* Can't pass the Encryption Status Check, get next one */
2878 /* Todo:: P2P and BOW Policy Selection */
2881 prPrimaryStaRec = prStaRec;
2883 //4 <8> Compare the Candidate and the Primary Scan Record.
2884 if (!prCandidateBssDesc) {
2885 prCandidateBssDesc = prPrimaryBssDesc;
2886 prCandidateStaRec = prPrimaryStaRec;
2888 //4 <8.1> Condition - Get the first matched one.
2889 if (fgIsFindFirst) {
2894 #if 0 /* TODO(Kevin): For security(TBD) */
2895 //4 <6B> Condition - Choose the one with best Encryption Score.
2896 if (fgIsFindBestEncryptionLevel) {
2897 if (prCandidateBssDesc->ucEncLevel <
2898 prPrimaryBssDesc->ucEncLevel) {
2900 prCandidateBssDesc = prPrimaryBssDesc;
2901 prCandidateStaRec = prPrimaryStaRec;
2906 /* If reach here, that means they have the same Encryption Score.
2909 //4 <6C> Condition - Give opportunity to the one we didn't connect before.
2910 // For roaming, only compare the candidates other than current associated BSSID.
2911 if (!prCandidateBssDesc->fgIsConnected && !prPrimaryBssDesc->fgIsConnected) {
2912 if ((prCandidateStaRec != (P_STA_RECORD_T)NULL) &&
2913 (prCandidateStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL)) {
2915 DBGLOG(SCAN, TRACE, ("So far -BSS DESC MAC: "MACSTR" has nonzero Status Code = %d\n",
2916 MAC2STR(prCandidateBssDesc->aucBSSID), prCandidateStaRec->u2StatusCode));
2918 if (prPrimaryStaRec != (P_STA_RECORD_T)NULL) {
2919 if (prPrimaryStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL) {
2921 /* Give opportunity to the one with smaller rLastJoinTime */
2922 if (TIME_BEFORE(prCandidateStaRec->rLastJoinTime,
2923 prPrimaryStaRec->rLastJoinTime)) {
2926 /* We've connect to CANDIDATE recently, let us try PRIMARY now */
2928 prCandidateBssDesc = prPrimaryBssDesc;
2929 prCandidateStaRec = prPrimaryStaRec;
2933 /* PRIMARY's u2StatusCode = 0 */
2935 prCandidateBssDesc = prPrimaryBssDesc;
2936 prCandidateStaRec = prPrimaryStaRec;
2940 /* PRIMARY has no StaRec - We didn't connet to PRIMARY before */
2942 prCandidateBssDesc = prPrimaryBssDesc;
2943 prCandidateStaRec = prPrimaryStaRec;
2948 if ((prPrimaryStaRec != (P_STA_RECORD_T)NULL) &&
2949 (prPrimaryStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL)) {
2957 //4 <6D> Condition - Visible SSID win Hidden SSID.
2958 if (prCandidateBssDesc->fgIsHiddenSSID) {
2959 if (!prPrimaryBssDesc->fgIsHiddenSSID) {
2960 prCandidateBssDesc = prPrimaryBssDesc; /* The non Hidden SSID win. */
2961 prCandidateStaRec = prPrimaryStaRec;
2966 if (prPrimaryBssDesc->fgIsHiddenSSID) {
2972 //4 <6E> Condition - Choose the one with better RCPI(RSSI).
2973 if (fgIsFindBestRSSI) {
2974 /* TODO(Kevin): We shouldn't compare the actual value, we should
2975 * allow some acceptable tolerance of some RSSI percentage here.
2977 DBGLOG(SCN, TRACE, ("Candidate ["MACSTR"]: RCPI = %d, Primary ["MACSTR"]: RCPI = %d\n",
2978 MAC2STR(prCandidateBssDesc->aucBSSID), prCandidateBssDesc->ucRCPI,
2979 MAC2STR(prPrimaryBssDesc->aucBSSID), prPrimaryBssDesc->ucRCPI));
2981 ASSERT(!(prCandidateBssDesc->fgIsConnected &&
2982 prPrimaryBssDesc->fgIsConnected));
2984 /* NOTE: To prevent SWING, we do roaming only if target AP has at least 5dBm larger than us. */
2985 if (prCandidateBssDesc->fgIsConnected) {
2986 if (prCandidateBssDesc->ucRCPI + ROAMING_NO_SWING_RCPI_STEP <= prPrimaryBssDesc->ucRCPI) {
2988 prCandidateBssDesc = prPrimaryBssDesc;
2989 prCandidateStaRec = prPrimaryStaRec;
2993 else if (prPrimaryBssDesc->fgIsConnected) {
2994 if (prCandidateBssDesc->ucRCPI < prPrimaryBssDesc->ucRCPI + ROAMING_NO_SWING_RCPI_STEP) {
2996 prCandidateBssDesc = prPrimaryBssDesc;
2997 prCandidateStaRec = prPrimaryStaRec;
3001 else if (prCandidateBssDesc->ucRCPI < prPrimaryBssDesc->ucRCPI) {
3002 prCandidateBssDesc = prPrimaryBssDesc;
3003 prCandidateStaRec = prPrimaryStaRec;
3009 /* If reach here, that means they have the same Encryption Score, and
3010 * both RSSI value are close too.
3012 //4 <6F> Seek the minimum Channel Load for less interference.
3013 if (fgIsFindMinChannelLoad) {
3015 /* TODO(Kevin): Check which one has minimum channel load in its channel */
3021 return prCandidateBssDesc;
3023 } /* end of scanSearchBssDescByPolicy() */