scan.c 103 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107
  1. /*
  2. ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/scan.c#3
  3. */
  4. /*! \file "scan.c"
  5. \brief This file defines the scan profile and the processing function of
  6. scan result for SCAN Module.
  7. The SCAN Profile selection is part of SCAN MODULE and responsible for defining
  8. SCAN Parameters - e.g. MIN_CHANNEL_TIME, number of scan channels.
  9. In this file we also define the process of SCAN Result including adding, searching
  10. and removing SCAN record from the list.
  11. */
  12. /*
  13. ** Log: scan.c
  14. **
  15. ** 01 30 2013 yuche.tsai
  16. ** [ALPS00451578] [JB2][WFD][Case Fail][JE][MR1]?????????[Java (JE),660,-1361051648,99,
  17. ** /data/core/,0,system_server_crash,system_server]JE happens when try to connect WFD.(4/5)
  18. ** Fix possible old scan result indicate to supplicant after formation.
  19. **
  20. ** 01 16 2013 yuche.tsai
  21. ** [ALPS00431980] [WFD]Aupus one ?play game 10 minitues?wfd connection automaticlly disconnect
  22. ** Fix possible FW assert issue.
  23. *
  24. * 07 17 2012 yuche.tsai
  25. * NULL
  26. * Let netdev bring up.
  27. *
  28. * 07 17 2012 yuche.tsai
  29. * NULL
  30. * Compile no error before trial run.
  31. *
  32. * 06 25 2012 cp.wu
  33. * [WCXRP00001258] [MT6620][MT5931][MT6628][Driver] Do not use stale scan result for deciding connection target
  34. * drop off scan result which is older than 5 seconds when choosing which BSS to join
  35. *
  36. * 03 02 2012 terry.wu
  37. * NULL
  38. * Sync CFG80211 modification from branch 2,2.
  39. *
  40. * 01 16 2012 cp.wu
  41. * [WCXRP00001169] [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band
  42. * configuration with corresponding network configuration
  43. * correct typo.
  44. *
  45. * 01 16 2012 cp.wu
  46. * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration
  47. * with corresponding network configuration
  48. * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting preferred
  49. * band configuration corresponding to network type.
  50. *
  51. * 12 05 2011 cp.wu
  52. * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path
  53. * add CONNECT_BY_BSSID policy
  54. *
  55. * 11 23 2011 cp.wu
  56. * [WCXRP00001123] [MT6620 Wi-Fi][Driver] Add option to disable beacon content change detection
  57. * add compile option to disable beacon content change detection.
  58. *
  59. * 11 04 2011 cp.wu
  60. * [WCXRP00001085] [MT6628 Wi-Fi][Driver] deprecate old BSS-DESC if timestamp
  61. * is reset with received beacon/probe response frames
  62. * deprecate old BSS-DESC when timestamp in received beacon/probe response frames showed a smaller value than before
  63. *
  64. * 10 11 2011 cm.chang
  65. * [WCXRP00001031] [All Wi-Fi][Driver] Check HT IE length to avoid wrong SCO parameter
  66. * Ignore HT OP IE if its length field is not valid
  67. *
  68. * 09 30 2011 cp.wu
  69. * [WCXRP00001021] [MT5931][Driver] Correct scan result generation for conversion between BSS type and operation mode
  70. * correct type casting issue.
  71. *
  72. * 08 23 2011 yuche.tsai
  73. * NULL
  74. * Fix multicast address list issue.
  75. *
  76. * 08 11 2011 cp.wu
  77. * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time
  78. * sparse channel detection:
  79. * driver: collect sparse channel information with scan-done event
  80. *
  81. * 08 10 2011 cp.wu
  82. * [WCXRP00000922] [MT6620 Wi-Fi][Driver] traverse whole BSS-DESC list for removing
  83. * traverse whole BSS-DESC list because BSSID is not unique anymore.
  84. *
  85. * 07 12 2011 cp.wu
  86. * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple
  87. * SSID settings to work around some tricky AP which use space character as hidden SSID
  88. * for multiple BSS descriptior detecting issue:
  89. * 1) check BSSID for infrastructure network
  90. * 2) check SSID for AdHoc network
  91. *
  92. * 07 12 2011 cp.wu
  93. * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple
  94. * SSID settings to work around some tricky AP which use space character as hidden SSID
  95. * check for BSSID for beacons used to update DTIM
  96. *
  97. * 07 12 2011 cp.wu
  98. * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple
  99. * SSID settings to work around some tricky AP which use space character as hidden SSID
  100. * do not check BSS descriptor for connected flag due to linksys's hidden
  101. * SSID will use another BSS descriptor and never connected
  102. *
  103. * 07 11 2011 cp.wu
  104. * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple
  105. * SSID settings to work around some tricky AP which use space character as hidden SSID
  106. * just pass beacons with the same BSSID.
  107. *
  108. * 07 11 2011 wh.su
  109. * [WCXRP00000849] [MT6620 Wi-Fi][Driver] Remove some of the WAPI define
  110. * for make sure the value is initialize, for customer not enable WAPI
  111. * For make sure wapi initial value is set.
  112. *
  113. * 06 28 2011 cp.wu
  114. * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple
  115. * SSID settings to work around some tricky AP which use space character as hidden SSID
  116. * Do not check for SSID as beacon content change due to the existence of
  117. * single BSSID with multiple SSID AP configuration
  118. *
  119. * 06 27 2011 cp.wu
  120. * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple
  121. * SSID settings to work around some tricky AP which use space character as hidden SSID
  122. * 1. correct logic
  123. * 2. replace only BSS-DESC which doesn't have a valid SSID.
  124. *
  125. * 06 27 2011 cp.wu
  126. * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID
  127. * settings to work around some tricky AP which use space character as hidden SSID
  128. * remove unused temporal variable reference.
  129. *
  130. * 06 27 2011 cp.wu
  131. * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID
  132. * settings to work around some tricky AP which use space character as hidden SSID
  133. * allow to have a single BSSID with multiple SSID to be presented in scanning result
  134. *
  135. * 06 02 2011 cp.wu
  136. * [WCXRP00000757] [MT6620 Wi-Fi][Driver][SCN] take use of RLM API to filter out BSS in disallowed channels
  137. * filter out BSS in disallowed channel by
  138. * 1. do not add to scan result array if BSS is at disallowed channel
  139. * 2. do not allow to search for BSS-DESC in disallowed channels
  140. *
  141. * 05 02 2011 cm.chang
  142. * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number
  143. * Refine range of valid channel number
  144. *
  145. * 05 02 2011 cp.wu
  146. * [MT6620 Wi-Fi][Driver] Take parsed result for channel information instead of
  147. * hardware channel number passed from firmware domain
  148. * take parsed result for generating scanning result with channel information.
  149. *
  150. * 05 02 2011 cm.chang
  151. * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number
  152. * Check if channel is valided before record ing BSS channel
  153. *
  154. * 04 18 2011 terry.wu
  155. * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
  156. * Remove flag CFG_WIFI_DIRECT_MOVED.
  157. *
  158. * 04 14 2011 cm.chang
  159. * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
  160. * .
  161. *
  162. * 04 12 2011 eddie.chen
  163. * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
  164. * Fix the sta index in processing security frame
  165. * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4
  166. * Add debug message.
  167. *
  168. * 03 25 2011 yuche.tsai
  169. * NULL
  170. * Always update Bss Type, for Bss Type for P2P Network is changing every time.
  171. *
  172. * 03 23 2011 yuche.tsai
  173. * NULL
  174. * Fix concurrent issue when AIS scan result would overwrite p2p scan result.
  175. *
  176. * 03 14 2011 cp.wu
  177. * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently
  178. * filtering out other BSS coming from adjacent channels
  179. *
  180. * 03 11 2011 chinglan.wang
  181. * [WCXRP00000537] [MT6620 Wi-Fi][Driver] Can not connect to 802.11b/g/n mixed AP with WEP security.
  182. * .
  183. *
  184. * 03 11 2011 cp.wu
  185. * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently
  186. * When fixed channel operation is necessary, AIS-FSM would scan and only connect for BSS on the specific channel
  187. *
  188. * 02 24 2011 cp.wu
  189. * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation because NdisMSleep()
  190. * won't sleep long enough for specified interval such as 500ms
  191. * implement beacon change detection by checking SSID and supported rate.
  192. *
  193. * 02 22 2011 yuche.tsai
  194. * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue
  195. * Fix WSC big endian issue.
  196. *
  197. * 02 21 2011 terry.wu
  198. * [WCXRP00000476] [MT6620 Wi-Fi][Driver] Clean P2P scan list while removing P2P
  199. * Clean P2P scan list while removing P2P.
  200. *
  201. * 01 27 2011 yuche.tsai
  202. * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate.
  203. * Fix scan channel extension issue when p2p module is not registered.
  204. *
  205. * 01 26 2011 cm.chang
  206. * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
  207. * .
  208. *
  209. * 01 21 2011 cp.wu
  210. * [WCXRP00000380] [MT6620 Wi-Fi][Driver] SSID information should come from buffered
  211. * BSS_DESC_T rather than using beacon-carried information
  212. * SSID should come from buffered prBssDesc rather than beacon-carried information
  213. *
  214. * 01 14 2011 yuche.tsai
  215. * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
  216. * Fix compile error.
  217. *
  218. * 01 14 2011 yuche.tsai
  219. * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
  220. * Memfree for P2P Descriptor & P2P Descriptor List.
  221. *
  222. * 01 14 2011 yuche.tsai
  223. * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
  224. * Free P2P Descriptor List & Descriptor under BSS Descriptor.
  225. *
  226. * 01 04 2011 cp.wu
  227. * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc
  228. * and vmalloc implementations to ease physically continuous memory demands
  229. * 1) correct typo in scan.c
  230. * 2) TX descriptors, RX descriptos and management buffer should use virtually
  231. * continuous buffer instead of physically continuous one
  232. *
  233. * 01 04 2011 cp.wu
  234. * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc
  235. * and vmalloc implementations to ease physically continuous memory demands
  236. * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure
  237. *
  238. * 12 31 2010 cp.wu
  239. * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side
  240. * while being unloaded, clear all pending interrupt then set LP-own to firmware
  241. *
  242. * 12 21 2010 cp.wu
  243. * [WCXRP00000280] [MT6620 Wi-Fi][Driver] Enable BSS selection with best RCPI policy in SCN module
  244. * SCN: enable BEST RSSI selection policy support
  245. *
  246. * 11 29 2010 cp.wu
  247. * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC
  248. * for initial TX rate selection of auto-rate algorithm
  249. * update ucRcpi of STA_RECORD_T for AIS when
  250. * 1) Beacons for IBSS merge is received
  251. * 2) Associate Response for a connecting peer is received
  252. *
  253. * 11 03 2010 wh.su
  254. * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group
  255. * Refine the HT rate disallow TKIP pairwise cipher .
  256. *
  257. * 10 12 2010 cp.wu
  258. * [WCXRP00000091] [MT6620 Wi-Fi][Driver] Add scanning logic to filter out
  259. * beacons which is received on the folding frequency
  260. * trust HT IE if available for 5GHz band
  261. *
  262. * 10 11 2010 cp.wu
  263. * [WCXRP00000091] [MT6620 Wi-Fi][Driver] Add scanning logic to filter out
  264. * beacons which is received on the folding frequency
  265. * add timing and strenght constraint for filtering out beacons with same SSID/TA but received on different channels
  266. *
  267. * 10 08 2010 wh.su
  268. * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine
  269. * update the frog's new p2p state machine.
  270. *
  271. * 10 01 2010 yuche.tsai
  272. * NULL
  273. * [MT6620 P2P] Fix Big Endian Issue when parse P2P device name TLV.
  274. *
  275. * 09 24 2010 cp.wu
  276. * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
  277. * eliminate unused variables which lead gcc to argue
  278. *
  279. * 09 08 2010 cp.wu
  280. * NULL
  281. * use static memory pool for storing IEs of scanning result.
  282. *
  283. * 09 07 2010 yuche.tsai
  284. * NULL
  285. * When indicate scan result, append IE buffer information in the scan result.
  286. *
  287. * 09 03 2010 yuche.tsai
  288. * NULL
  289. * 1. Update Beacon RX count when running SLT.
  290. * 2. Ignore Beacon when running SLT, would not update information from Beacon.
  291. *
  292. * 09 03 2010 kevin.huang
  293. * NULL
  294. * Refine #include sequence and solve recursive/nested #include issue
  295. *
  296. * 08 31 2010 kevin.huang
  297. * NULL
  298. * Use LINK LIST operation to process SCAN result
  299. *
  300. * 08 29 2010 yuche.tsai
  301. * NULL
  302. * 1. Fix P2P Descriptor List to be a link list, to avoid link corrupt after Bss Descriptor Free.
  303. * 2.. Fix P2P Device Name Length BE issue.
  304. *
  305. * 08 23 2010 yuche.tsai
  306. * NULL
  307. * Add P2P Device Found Indication to supplicant
  308. *
  309. * 08 20 2010 cp.wu
  310. * NULL
  311. * reset BSS_DESC_T variables before parsing IE due to peer might have been reconfigured.
  312. *
  313. * 08 20 2010 yuche.tsai
  314. * NULL
  315. * Workaround for P2P Descriptor Infinite loop issue.
  316. *
  317. * 08 16 2010 cp.wu
  318. * NULL
  319. * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI.
  320. * There is no CFG_SUPPORT_BOW in driver domain source.
  321. *
  322. * 08 16 2010 yuche.tsai
  323. * NULL
  324. * Modify code of processing Probe Resonse frame for P2P.
  325. *
  326. * 08 12 2010 yuche.tsai
  327. * NULL
  328. * Add function to get P2P descriptor of BSS descriptor directly.
  329. *
  330. * 08 11 2010 yuche.tsai
  331. * NULL
  332. * Modify Scan result processing for P2P module.
  333. *
  334. * 08 05 2010 yuche.tsai
  335. * NULL
  336. * Update P2P Device Discovery result add function.
  337. *
  338. * 08 03 2010 cp.wu
  339. * NULL
  340. * surpress compilation warning.
  341. *
  342. * 07 26 2010 yuche.tsai
  343. *
  344. * Add support for Probe Request & Response parsing.
  345. *
  346. * 07 21 2010 cp.wu
  347. *
  348. * 1) change BG_SCAN to ONLINE_SCAN for consistent term
  349. * 2) only clear scanning result when scan is permitted to do
  350. *
  351. * 07 21 2010 yuche.tsai
  352. *
  353. * Fix compile error for SCAN module while disabling P2P feature.
  354. *
  355. * 07 21 2010 yuche.tsai
  356. *
  357. * Add P2P Scan & Scan Result Parsing & Saving.
  358. *
  359. * 07 19 2010 wh.su
  360. *
  361. * update for security supporting.
  362. *
  363. * 07 19 2010 cp.wu
  364. *
  365. * [WPD00003833] [MT6620 and MT5931] Driver migration.
  366. * Add Ad-Hoc support to AIS-FSM
  367. *
  368. * 07 19 2010 cp.wu
  369. *
  370. * [WPD00003833] [MT6620 and MT5931] Driver migration.
  371. * SCN module is now able to handle multiple concurrent scanning requests
  372. *
  373. * 07 15 2010 cp.wu
  374. *
  375. * [WPD00003833] [MT6620 and MT5931] Driver migration.
  376. * driver no longer generates probe request frames
  377. *
  378. * 07 14 2010 cp.wu
  379. *
  380. * [WPD00003833] [MT6620 and MT5931] Driver migration.
  381. * remove timer in DRV-SCN.
  382. *
  383. * 07 09 2010 cp.wu
  384. *
  385. * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection)
  386. * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass
  387. * 3) implment DRV-SCN module, currently only accepts single scan request,
  388. * other request will be directly dropped by returning BUSY
  389. *
  390. * 07 08 2010 cp.wu
  391. *
  392. * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
  393. *
  394. * 07 08 2010 cp.wu
  395. * [WPD00003833][MT6620 and MT5931] Driver migration
  396. * take use of RLM module for parsing/generating HT IEs for 11n capability
  397. *
  398. * 07 05 2010 cp.wu
  399. * [WPD00003833][MT6620 and MT5931] Driver migration
  400. * 1) ignore RSN checking when RSN is not turned on.
  401. * 2) set STA-REC deactivation callback as NULL
  402. * 3) add variable initialization API based on PHY configuration
  403. *
  404. * 07 05 2010 cp.wu
  405. * [WPD00003833][MT6620 and MT5931] Driver migration
  406. * correct BSS_DESC_T initialization after allocated.
  407. *
  408. * 07 02 2010 cp.wu
  409. * [WPD00003833][MT6620 and MT5931] Driver migration
  410. * 1) for event packet, no need to fill RFB.
  411. * 2) when wlanAdapterStart() failed, no need to initialize state machines
  412. * 3) after Beacon/ProbeResp parsing, corresponding BSS_DESC_T should be marked as IE-parsed
  413. *
  414. * 07 01 2010 cp.wu
  415. * [WPD00003833][MT6620 and MT5931] Driver migration
  416. * add scan uninitialization procedure
  417. *
  418. * 06 30 2010 cp.wu
  419. * [WPD00003833][MT6620 and MT5931] Driver migration
  420. * if beacon/probe-resp is received in 2.4GHz bands and there is ELEM_ID_DS_PARAM_SET IE available,
  421. * trust IE instead of RMAC information
  422. *
  423. * 06 29 2010 cp.wu
  424. * [WPD00003833][MT6620 and MT5931] Driver migration
  425. * 1) sync to. CMD/EVENT document v0.03
  426. * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again.
  427. * 3) send command packet to indicate FW-PM after
  428. * a) 1st beacon is received after AIS has connected to an AP
  429. * b) IBSS-ALONE has been created
  430. * c) IBSS-MERGE has occurred
  431. *
  432. * 06 28 2010 cp.wu
  433. * [WPD00003833][MT6620 and MT5931] Driver migration
  434. * send MMPDU in basic rate.
  435. *
  436. * 06 25 2010 cp.wu
  437. * [WPD00003833][MT6620 and MT5931] Driver migration
  438. * modify Beacon/ProbeResp to complete parsing,
  439. * because host software has looser memory usage restriction
  440. *
  441. * 06 23 2010 cp.wu
  442. * [WPD00003833][MT6620 and MT5931] Driver migration
  443. * integrate .
  444. *
  445. * 06 22 2010 cp.wu
  446. * [WPD00003833][MT6620 and MT5931] Driver migration
  447. * comment out RLM APIs by CFG_RLM_MIGRATION.
  448. *
  449. * 06 21 2010 yuche.tsai
  450. * [WPD00003839][MT6620 5931][P2P] Feature migration
  451. * Update P2P Function call.
  452. *
  453. * 06 21 2010 cp.wu
  454. * [WPD00003833][MT6620 and MT5931] Driver migration
  455. * RSN/PRIVACY compilation flag awareness correction
  456. *
  457. * 06 21 2010 cp.wu
  458. * [WPD00003833][MT6620 and MT5931] Driver migration
  459. * specify correct value for management frames.
  460. *
  461. * 06 18 2010 cm.chang
  462. * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
  463. * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
  464. *
  465. * 06 18 2010 wh.su
  466. * [WPD00003840][MT6620 5931] Security migration
  467. * migration from MT6620 firmware.
  468. *
  469. * 06 17 2010 yuche.tsai
  470. * [WPD00003839][MT6620 5931][P2P] Feature migration
  471. * Fix compile error when enable P2P function.
  472. *
  473. * 06 15 2010 cp.wu
  474. * [WPD00003833][MT6620 and MT5931] Driver migration
  475. * correct when ADHOC support is turned on.
  476. *
  477. * 06 15 2010 cp.wu
  478. * [WPD00003833][MT6620 and MT5931] Driver migration
  479. * add scan.c.
  480. *
  481. * 06 04 2010 george.huang
  482. * [BORA00000678][MT6620]WiFi LP integration
  483. * [PM] Support U-APSD for STA mode
  484. *
  485. * 05 28 2010 wh.su
  486. * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query
  487. * adding the TKIP disallow join a HT AP code.
  488. *
  489. * 05 14 2010 kevin.huang
  490. * [BORA00000794][WIFISYS][New Feature]Power Management Support
  491. * Add more chance of JOIN retry for BG_SCAN
  492. *
  493. * 05 12 2010 kevin.huang
  494. * [BORA00000794][WIFISYS][New Feature]Power Management Support
  495. * Add Power Management - Legacy PS-POLL support.
  496. *
  497. * 04 29 2010 wh.su
  498. * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
  499. * adjsut the pre-authentication code.
  500. *
  501. * 04 27 2010 kevin.huang
  502. * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
  503. * Add Set Slot Time and Beacon Timeout Support for AdHoc Mode
  504. *
  505. * 04 24 2010 cm.chang
  506. * [BORA00000018]Integrate WIFI part into BORA for the 1st time
  507. * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
  508. *
  509. * 04 19 2010 kevin.huang
  510. * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
  511. * Add Beacon Timeout Support and will send Null frame to diagnose connection
  512. *
  513. * 04 13 2010 kevin.huang
  514. * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
  515. * Add new HW CH macro support
  516. *
  517. * 04 06 2010 wh.su
  518. * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query
  519. * fixed the firmware return the broadcast frame at wrong tc.
  520. *
  521. * 03 29 2010 wh.su
  522. * [BORA00000605][WIFISYS] Phase3 Integration
  523. * let the rsn wapi IE always parsing.
  524. *
  525. * 03 24 2010 cm.chang
  526. * [BORA00000018]Integrate WIFI part into BORA for the 1st time
  527. * Not carry HT cap when being associated with b/g only AP
  528. *
  529. * 03 18 2010 kevin.huang
  530. * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
  531. * Solve the compile warning for 'return non-void' function
  532. *
  533. * 03 16 2010 kevin.huang
  534. * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
  535. * Add AdHoc Mode
  536. *
  537. * 03 10 2010 kevin.huang
  538. * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support
  539. *
  540. * * * * * * * * * * * * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req
  541. *
  542. * 03 03 2010 wh.su
  543. * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
  544. * move the AIS specific variable for security to AIS specific structure.
  545. *
  546. * 03 01 2010 wh.su
  547. * [BORA00000605][WIFISYS] Phase3 Integration
  548. * Refine the variable and parameter for security.
  549. *
  550. * 02 26 2010 kevin.huang
  551. * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
  552. * Fix No PKT_INFO_T issue
  553. *
  554. * 02 26 2010 kevin.huang
  555. * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
  556. * Update outgoing ProbeRequest Frame's TX data rate
  557. *
  558. * 02 23 2010 wh.su
  559. * [BORA00000592][MT6620 Wi-Fi] Adding the security related code for driver
  560. * refine the scan procedure, reduce the WPA and WAPI IE parsing, and move the parsing to the time for join.
  561. *
  562. * 02 23 2010 kevin.huang
  563. * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
  564. * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb
  565. *
  566. * 02 04 2010 kevin.huang
  567. * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
  568. * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
  569. *
  570. * 01 27 2010 wh.su
  571. * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
  572. * add and fixed some security function.
  573. *
  574. * 01 22 2010 cm.chang
  575. * [BORA00000018]Integrate WIFI part into BORA for the 1st time
  576. * Support protection and bandwidth switch
  577. *
  578. * 01 20 2010 kevin.huang
  579. * [BORA00000569][WIFISYS] Phase 2 Integration Test
  580. * Add PHASE_2_INTEGRATION_WORK_AROUND and CFG_SUPPORT_BCM flags
  581. *
  582. * 01 11 2010 kevin.huang
  583. * [BORA00000018]Integrate WIFI part into BORA for the 1st time
  584. * Add Deauth and Disassoc Handler
  585. *
  586. * 01 08 2010 kevin.huang
  587. * [BORA00000018]Integrate WIFI part into BORA for the 1st time
  588. *
  589. * Refine Beacon processing, add read RF channel from RX Status
  590. *
  591. * 01 04 2010 tehuang.liu
  592. * [BORA00000018]Integrate WIFI part into BORA for the 1st time
  593. * For working out the first connection Chariot-verified version
  594. *
  595. * 12 18 2009 cm.chang
  596. * [BORA00000018]Integrate WIFI part into BORA for the 1st time
  597. * .
  598. *
  599. * Dec 12 2009 mtk01104
  600. * [BORA00000018] Integrate WIFI part into BORA for the 1st time
  601. * Modify u2EstimatedExtraIELen for probe request
  602. *
  603. * Dec 9 2009 mtk01104
  604. * [BORA00000018] Integrate WIFI part into BORA for the 1st time
  605. * Add HT cap IE to probe request
  606. *
  607. * Dec 7 2009 mtk01461
  608. * [BORA00000018] Integrate WIFI part into BORA for the 1st time
  609. * Fix lint warning
  610. *
  611. *
  612. * Dec 3 2009 mtk01461
  613. * [BORA00000018] Integrate WIFI part into BORA for the 1st time
  614. * Update the process of SCAN Result by adding more Phy Attributes
  615. *
  616. * Dec 1 2009 mtk01088
  617. * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
  618. * adjust the function and code for meet the new define
  619. *
  620. * Nov 30 2009 mtk01461
  621. * [BORA00000018] Integrate WIFI part into BORA for the 1st time
  622. * Rename u4RSSI to i4RSSI
  623. *
  624. * Nov 30 2009 mtk01461
  625. * [BORA00000018] Integrate WIFI part into BORA for the 1st time
  626. * Report event of scan result to host
  627. *
  628. * Nov 26 2009 mtk01461
  629. * [BORA00000018] Integrate WIFI part into BORA for the 1st time
  630. * Fix SCAN Record update
  631. *
  632. * Nov 24 2009 mtk01461
  633. * [BORA00000018] Integrate WIFI part into BORA for the 1st time
  634. * Revise MGMT Handler with Retain Status and Integrate with TXM
  635. *
  636. * Nov 23 2009 mtk01461
  637. * [BORA00000018] Integrate WIFI part into BORA for the 1st time
  638. * Add (Ext)Support Rate Set IE to ProbeReq
  639. *
  640. * Nov 20 2009 mtk02468
  641. * [BORA00000337] To check in codes for FPGA emulation
  642. * Removed the use of SW_RFB->u2FrameLength
  643. *
  644. * Nov 20 2009 mtk01461
  645. * [BORA00000018] Integrate WIFI part into BORA for the 1st time
  646. * Fix uninitial aucMacAddress[] for ProbeReq
  647. *
  648. * Nov 16 2009 mtk01461
  649. * [BORA00000018] Integrate WIFI part into BORA for the 1st time
  650. * Add scanSearchBssDescByPolicy()
  651. *
  652. * Nov 5 2009 mtk01461
  653. * [BORA00000018] Integrate WIFI part into BORA for the 1st time
  654. * Add Send Probe Request Frame
  655. *
  656. * Oct 30 2009 mtk01461
  657. * [BORA00000018] Integrate WIFI part into BORA for the 1st time
  658. *
  659. */
  660. /*******************************************************************************
  661. * C O M P I L E R F L A G S
  662. ********************************************************************************
  663. */
  664. /*******************************************************************************
  665. * E X T E R N A L R E F E R E N C E S
  666. ********************************************************************************
  667. */
  668. #include "precomp.h"
  669. /*******************************************************************************
  670. * C O N S T A N T S
  671. ********************************************************************************
  672. */
  673. #define REPLICATED_BEACON_TIME_THRESHOLD (3000)
  674. #define REPLICATED_BEACON_FRESH_PERIOD (10000)
  675. #define REPLICATED_BEACON_STRENGTH_THRESHOLD (32)
  676. #define ROAMING_NO_SWING_RCPI_STEP (10)
  677. /*******************************************************************************
  678. * D A T A T Y P E S
  679. ********************************************************************************
  680. */
  681. /*******************************************************************************
  682. * P U B L I C D A T A
  683. ********************************************************************************
  684. */
  685. /*******************************************************************************
  686. * P R I V A T E D A T A
  687. ********************************************************************************
  688. */
  689. /*******************************************************************************
  690. * M A C R O S
  691. ********************************************************************************
  692. */
  693. /*******************************************************************************
  694. * F U N C T I O N D E C L A R A T I O N S
  695. ********************************************************************************
  696. */
  697. /*******************************************************************************
  698. * F U N C T I O N S
  699. ********************************************************************************
  700. */
  701. /*----------------------------------------------------------------------------*/
  702. /*!
  703. * @brief This function is used by SCN to initialize its variables
  704. *
  705. * @param (none)
  706. *
  707. * @return (none)
  708. */
  709. /*----------------------------------------------------------------------------*/
  710. VOID scnInit(IN P_ADAPTER_T prAdapter)
  711. {
  712. P_SCAN_INFO_T prScanInfo;
  713. P_BSS_DESC_T prBSSDesc;
  714. PUINT_8 pucBSSBuff;
  715. UINT_32 i;
  716. ASSERT(prAdapter);
  717. prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
  718. pucBSSBuff = &prScanInfo->aucScanBuffer[0];
  719. DBGLOG(SCN, INFO, "->scnInit()\n");
  720. /* 4 <1> Reset STATE and Message List */
  721. prScanInfo->eCurrentState = SCAN_STATE_IDLE;
  722. prScanInfo->rLastScanCompletedTime = (OS_SYSTIME) 0;
  723. LINK_INITIALIZE(&prScanInfo->rPendingMsgList);
  724. /* 4 <2> Reset link list of BSS_DESC_T */
  725. kalMemZero((PVOID) pucBSSBuff, SCN_MAX_BUFFER_SIZE);
  726. LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList);
  727. LINK_INITIALIZE(&prScanInfo->rBSSDescList);
  728. for (i = 0; i < CFG_MAX_NUM_BSS_LIST; i++) {
  729. prBSSDesc = (P_BSS_DESC_T) pucBSSBuff;
  730. LINK_INSERT_TAIL(&prScanInfo->rFreeBSSDescList, &prBSSDesc->rLinkEntry);
  731. pucBSSBuff += ALIGN_4(sizeof(BSS_DESC_T));
  732. }
  733. /* Check if the memory allocation consist with this initialization function */
  734. ASSERT(((ULONG) pucBSSBuff - (ULONG)&prScanInfo->aucScanBuffer[0]) == SCN_MAX_BUFFER_SIZE);
  735. /* reset freest channel information */
  736. prScanInfo->fgIsSparseChannelValid = FALSE;
  737. /* reset NLO state */
  738. prScanInfo->fgNloScanning = FALSE;
  739. prScanInfo->fgPscnOnnning = FALSE;
  740. prScanInfo->prPscnParam = kalMemAlloc(sizeof(PSCN_PARAM_T), VIR_MEM_TYPE);
  741. if (prScanInfo->prPscnParam)
  742. kalMemZero(prScanInfo->prPscnParam, sizeof(PSCN_PARAM_T));
  743. prScanInfo->eCurrentPSCNState = PSCN_IDLE;
  744. } /* end of scnInit() */
  745. /*----------------------------------------------------------------------------*/
  746. /*!
  747. * @brief This function is used by SCN to uninitialize its variables
  748. *
  749. * @param (none)
  750. *
  751. * @return (none)
  752. */
  753. /*----------------------------------------------------------------------------*/
  754. VOID scnUninit(IN P_ADAPTER_T prAdapter)
  755. {
  756. P_SCAN_INFO_T prScanInfo;
  757. ASSERT(prAdapter);
  758. prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
  759. DBGLOG(SCN, INFO, "->scnUninit()\n");
  760. /* 4 <1> Reset STATE and Message List */
  761. prScanInfo->eCurrentState = SCAN_STATE_IDLE;
  762. prScanInfo->rLastScanCompletedTime = (OS_SYSTIME) 0;
  763. /* NOTE(Kevin): Check rPendingMsgList ? */
  764. /* 4 <2> Reset link list of BSS_DESC_T */
  765. LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList);
  766. LINK_INITIALIZE(&prScanInfo->rBSSDescList);
  767. kalMemFree(prScanInfo->prPscnParam, VIR_MEM_TYPE, sizeof(PSCN_PARAM_T));
  768. prScanInfo->eCurrentPSCNState = PSCN_IDLE;
  769. } /* end of scnUninit() */
  770. /*----------------------------------------------------------------------------*/
  771. /*!
  772. * @brief Find the corresponding BSS Descriptor according to given BSSID
  773. *
  774. * @param[in] prAdapter Pointer to the Adapter structure.
  775. * @param[in] aucBSSID Given BSSID.
  776. *
  777. * @return Pointer to BSS Descriptor, if found. NULL, if not found
  778. */
  779. /*----------------------------------------------------------------------------*/
  780. P_BSS_DESC_T scanSearchBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[])
  781. {
  782. return scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, FALSE, NULL);
  783. }
  784. /*----------------------------------------------------------------------------*/
  785. /*!
  786. * @brief Find the corresponding BSS Descriptor according to given BSSID
  787. *
  788. * @param[in] prAdapter Pointer to the Adapter structure.
  789. * @param[in] aucBSSID Given BSSID.
  790. * @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases)
  791. * @param[in] prSsid Specified SSID
  792. *
  793. * @return Pointer to BSS Descriptor, if found. NULL, if not found
  794. */
  795. /*----------------------------------------------------------------------------*/
  796. P_BSS_DESC_T
  797. scanSearchBssDescByBssidAndSsid(IN P_ADAPTER_T prAdapter,
  798. IN UINT_8 aucBSSID[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid)
  799. {
  800. P_SCAN_INFO_T prScanInfo;
  801. P_LINK_T prBSSDescList;
  802. P_BSS_DESC_T prBssDesc;
  803. P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T) NULL;
  804. ASSERT(prAdapter);
  805. ASSERT(aucBSSID);
  806. prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
  807. prBSSDescList = &prScanInfo->rBSSDescList;
  808. /* Search BSS Desc from current SCAN result list. */
  809. LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
  810. if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) {
  811. if (fgCheckSsid == FALSE || prSsid == NULL)
  812. return prBssDesc;
  813. if (EQUAL_SSID(prBssDesc->aucSSID,
  814. prBssDesc->ucSSIDLen, prSsid->aucSsid, prSsid->u4SsidLen)) {
  815. return prBssDesc;
  816. } else if (prDstBssDesc == NULL && prBssDesc->fgIsHiddenSSID == TRUE) {
  817. prDstBssDesc = prBssDesc;
  818. } else {
  819. /* 20120206 frog: Equal BSSID but not SSID, SSID not hidden,
  820. * SSID must be updated. */
  821. COPY_SSID(prBssDesc->aucSSID,
  822. prBssDesc->ucSSIDLen, prSsid->aucSsid, prSsid->u4SsidLen);
  823. return prBssDesc;
  824. }
  825. }
  826. }
  827. return prDstBssDesc;
  828. } /* end of scanSearchBssDescByBssid() */
  829. /*----------------------------------------------------------------------------*/
  830. /*!
  831. * @brief Find the corresponding BSS Descriptor according to given Transmitter Address.
  832. *
  833. * @param[in] prAdapter Pointer to the Adapter structure.
  834. * @param[in] aucSrcAddr Given Source Address(TA).
  835. *
  836. * @return Pointer to BSS Descriptor, if found. NULL, if not found
  837. */
  838. /*----------------------------------------------------------------------------*/
  839. P_BSS_DESC_T scanSearchBssDescByTA(IN P_ADAPTER_T prAdapter, IN UINT_8 aucSrcAddr[])
  840. {
  841. return scanSearchBssDescByTAAndSsid(prAdapter, aucSrcAddr, FALSE, NULL);
  842. }
  843. /*----------------------------------------------------------------------------*/
  844. /*!
  845. * @brief Find the corresponding BSS Descriptor according to given Transmitter Address.
  846. *
  847. * @param[in] prAdapter Pointer to the Adapter structure.
  848. * @param[in] aucSrcAddr Given Source Address(TA).
  849. * @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases)
  850. * @param[in] prSsid Specified SSID
  851. *
  852. * @return Pointer to BSS Descriptor, if found. NULL, if not found
  853. */
  854. /*----------------------------------------------------------------------------*/
  855. P_BSS_DESC_T
  856. scanSearchBssDescByTAAndSsid(IN P_ADAPTER_T prAdapter,
  857. IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid)
  858. {
  859. P_SCAN_INFO_T prScanInfo;
  860. P_LINK_T prBSSDescList;
  861. P_BSS_DESC_T prBssDesc;
  862. P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T) NULL;
  863. ASSERT(prAdapter);
  864. ASSERT(aucSrcAddr);
  865. prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
  866. prBSSDescList = &prScanInfo->rBSSDescList;
  867. /* Search BSS Desc from current SCAN result list. */
  868. LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
  869. if (EQUAL_MAC_ADDR(prBssDesc->aucSrcAddr, aucSrcAddr)) {
  870. if (fgCheckSsid == FALSE || prSsid == NULL)
  871. return prBssDesc;
  872. if (EQUAL_SSID(prBssDesc->aucSSID,
  873. prBssDesc->ucSSIDLen, prSsid->aucSsid, prSsid->u4SsidLen)) {
  874. return prBssDesc;
  875. } else if (prDstBssDesc == NULL && prBssDesc->fgIsHiddenSSID == TRUE) {
  876. prDstBssDesc = prBssDesc;
  877. }
  878. }
  879. }
  880. return prDstBssDesc;
  881. } /* end of scanSearchBssDescByTA() */
  882. #if CFG_SUPPORT_HOTSPOT_2_0
  883. /*----------------------------------------------------------------------------*/
  884. /*!
  885. * @brief Find the corresponding BSS Descriptor according to given BSSID
  886. *
  887. * @param[in] prAdapter Pointer to the Adapter structure.
  888. * @param[in] aucBSSID Given BSSID.
  889. * @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases)
  890. * @param[in] prSsid Specified SSID
  891. *
  892. * @return Pointer to BSS Descriptor, if found. NULL, if not found
  893. */
  894. /*----------------------------------------------------------------------------*/
  895. P_BSS_DESC_T scanSearchBssDescByBssidAndLatestUpdateTime(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[])
  896. {
  897. P_SCAN_INFO_T prScanInfo;
  898. P_LINK_T prBSSDescList;
  899. P_BSS_DESC_T prBssDesc;
  900. P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T) NULL;
  901. OS_SYSTIME rLatestUpdateTime = 0;
  902. ASSERT(prAdapter);
  903. ASSERT(aucBSSID);
  904. prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
  905. prBSSDescList = &prScanInfo->rBSSDescList;
  906. /* Search BSS Desc from current SCAN result list. */
  907. LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
  908. if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) {
  909. if (!rLatestUpdateTime || CHECK_FOR_EXPIRATION(prBssDesc->rUpdateTime, rLatestUpdateTime)) {
  910. prDstBssDesc = prBssDesc;
  911. COPY_SYSTIME(rLatestUpdateTime, prBssDesc->rUpdateTime);
  912. }
  913. }
  914. }
  915. return prDstBssDesc;
  916. } /* end of scanSearchBssDescByBssid() */
  917. #endif
  918. /*----------------------------------------------------------------------------*/
  919. /*!
  920. * @brief Find the corresponding BSS Descriptor according to
  921. * given eBSSType, BSSID and Transmitter Address
  922. *
  923. * @param[in] prAdapter Pointer to the Adapter structure.
  924. * @param[in] eBSSType BSS Type of incoming Beacon/ProbeResp frame.
  925. * @param[in] aucBSSID Given BSSID of Beacon/ProbeResp frame.
  926. * @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame.
  927. *
  928. * @return Pointer to BSS Descriptor, if found. NULL, if not found
  929. */
  930. /*----------------------------------------------------------------------------*/
  931. P_BSS_DESC_T
  932. scanSearchExistingBssDesc(IN P_ADAPTER_T prAdapter,
  933. IN ENUM_BSS_TYPE_T eBSSType, IN UINT_8 aucBSSID[], IN UINT_8 aucSrcAddr[])
  934. {
  935. return scanSearchExistingBssDescWithSsid(prAdapter, eBSSType, aucBSSID, aucSrcAddr, FALSE, NULL);
  936. }
  937. /*----------------------------------------------------------------------------*/
  938. /*!
  939. * @brief Find the corresponding BSS Descriptor according to
  940. * given eBSSType, BSSID and Transmitter Address
  941. *
  942. * @param[in] prAdapter Pointer to the Adapter structure.
  943. * @param[in] eBSSType BSS Type of incoming Beacon/ProbeResp frame.
  944. * @param[in] aucBSSID Given BSSID of Beacon/ProbeResp frame.
  945. * @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame.
  946. * @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases)
  947. * @param[in] prSsid Specified SSID
  948. *
  949. * @return Pointer to BSS Descriptor, if found. NULL, if not found
  950. */
  951. /*----------------------------------------------------------------------------*/
  952. P_BSS_DESC_T
  953. scanSearchExistingBssDescWithSsid(IN P_ADAPTER_T prAdapter,
  954. IN ENUM_BSS_TYPE_T eBSSType,
  955. IN UINT_8 aucBSSID[],
  956. IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid)
  957. {
  958. P_SCAN_INFO_T prScanInfo;
  959. P_BSS_DESC_T prBssDesc, prIBSSBssDesc;
  960. P_LINK_T prBSSDescList;
  961. P_LINK_T prFreeBSSDescList;
  962. ASSERT(prAdapter);
  963. ASSERT(aucSrcAddr);
  964. prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
  965. switch (eBSSType) {
  966. case BSS_TYPE_P2P_DEVICE:
  967. fgCheckSsid = FALSE;
  968. case BSS_TYPE_INFRASTRUCTURE:
  969. case BSS_TYPE_BOW_DEVICE:
  970. {
  971. prBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, fgCheckSsid, prSsid);
  972. /* if (eBSSType == prBssDesc->eBSSType) */
  973. return prBssDesc;
  974. }
  975. case BSS_TYPE_IBSS:
  976. {
  977. prIBSSBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, fgCheckSsid, prSsid);
  978. prBssDesc = scanSearchBssDescByTAAndSsid(prAdapter, aucSrcAddr, fgCheckSsid, prSsid);
  979. /* NOTE(Kevin):
  980. * Rules to maintain the SCAN Result:
  981. * For AdHoc -
  982. * CASE I We have TA1(BSSID1), but it change its BSSID to BSSID2
  983. * -> Update TA1 entry's BSSID.
  984. * CASE II We have TA1(BSSID1), and get TA1(BSSID1) again
  985. * -> Update TA1 entry's contain.
  986. * CASE III We have a SCAN result TA1(BSSID1), and TA2(BSSID2). Sooner or
  987. * later, TA2 merge into TA1, we get TA2(BSSID1)
  988. * -> Remove TA2 first and then replace TA1 entry's TA with TA2,
  989. * Still have only one entry of BSSID.
  990. * CASE IV We have a SCAN result TA1(BSSID1), and another TA2 also merge into BSSID1.
  991. * -> Replace TA1 entry's TA with TA2, Still have only one entry.
  992. * CASE V New IBSS
  993. * -> Add this one to SCAN result.
  994. */
  995. if (prBssDesc) {
  996. if ((!prIBSSBssDesc) || /* CASE I */
  997. (prBssDesc == prIBSSBssDesc)) { /* CASE II */
  998. return prBssDesc;
  999. } /* CASE III */
  1000. prBSSDescList = &prScanInfo->rBSSDescList;
  1001. prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
  1002. /* Remove this BSS Desc from the BSS Desc list */
  1003. LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
  1004. /* Return this BSS Desc to the free BSS Desc list. */
  1005. LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
  1006. return prIBSSBssDesc;
  1007. }
  1008. if (prIBSSBssDesc) { /* CASE IV */
  1009. return prIBSSBssDesc;
  1010. }
  1011. /* CASE V */
  1012. break; /* Return NULL; */
  1013. }
  1014. default:
  1015. break;
  1016. }
  1017. return (P_BSS_DESC_T) NULL;
  1018. } /* end of scanSearchExistingBssDesc() */
  1019. /*----------------------------------------------------------------------------*/
  1020. /*!
  1021. * @brief Delete BSS Descriptors from current list according to given Remove Policy.
  1022. *
  1023. * @param[in] u4RemovePolicy Remove Policy.
  1024. *
  1025. * @return (none)
  1026. */
  1027. /*----------------------------------------------------------------------------*/
  1028. VOID scanRemoveBssDescsByPolicy(IN P_ADAPTER_T prAdapter, IN UINT_32 u4RemovePolicy)
  1029. {
  1030. P_CONNECTION_SETTINGS_T prConnSettings;
  1031. P_SCAN_INFO_T prScanInfo;
  1032. P_LINK_T prBSSDescList;
  1033. P_LINK_T prFreeBSSDescList;
  1034. P_BSS_DESC_T prBssDesc;
  1035. ASSERT(prAdapter);
  1036. prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
  1037. prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
  1038. prBSSDescList = &prScanInfo->rBSSDescList;
  1039. prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
  1040. /* DBGLOG(SCN, TRACE, ("Before Remove - Number Of SCAN Result = %ld\n", */
  1041. /* prBSSDescList->u4NumElem)); */
  1042. if (u4RemovePolicy & SCN_RM_POLICY_TIMEOUT) {
  1043. P_BSS_DESC_T prBSSDescNext;
  1044. OS_SYSTIME rCurrentTime;
  1045. GET_CURRENT_SYSTIME(&rCurrentTime);
  1046. /* Search BSS Desc from current SCAN result list. */
  1047. LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
  1048. if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
  1049. (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
  1050. /* Don't remove the one currently we are connected. */
  1051. continue;
  1052. }
  1053. if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
  1054. SEC_TO_SYSTIME(SCN_BSS_DESC_REMOVE_TIMEOUT_SEC))) {
  1055. /* DBGLOG(SCN, TRACE, ("Remove TIMEOUT BSS DESC(%#x):
  1056. * MAC: %pM, Current Time = %08lx, Update Time = %08lx\n", */
  1057. /* prBssDesc, prBssDesc->aucBSSID, rCurrentTime, prBssDesc->rUpdateTime)); */
  1058. /* Remove this BSS Desc from the BSS Desc list */
  1059. LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
  1060. /* Return this BSS Desc to the free BSS Desc list. */
  1061. LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
  1062. }
  1063. }
  1064. } else if (u4RemovePolicy & SCN_RM_POLICY_OLDEST_HIDDEN) {
  1065. P_BSS_DESC_T prBssDescOldest = (P_BSS_DESC_T) NULL;
  1066. /* Search BSS Desc from current SCAN result list. */
  1067. LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
  1068. if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
  1069. (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
  1070. /* Don't remove the one currently we are connected. */
  1071. continue;
  1072. }
  1073. if (!prBssDesc->fgIsHiddenSSID)
  1074. continue;
  1075. if (!prBssDescOldest) { /* 1st element */
  1076. prBssDescOldest = prBssDesc;
  1077. continue;
  1078. }
  1079. if (TIME_BEFORE(prBssDesc->rUpdateTime, prBssDescOldest->rUpdateTime))
  1080. prBssDescOldest = prBssDesc;
  1081. }
  1082. if (prBssDescOldest) {
  1083. /* DBGLOG(SCN, TRACE, ("Remove OLDEST HIDDEN BSS DESC(%#x):
  1084. * MAC: %pM, Update Time = %08lx\n", */
  1085. /* prBssDescOldest, prBssDescOldest->aucBSSID, prBssDescOldest->rUpdateTime)); */
  1086. /* Remove this BSS Desc from the BSS Desc list */
  1087. LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescOldest);
  1088. /* Return this BSS Desc to the free BSS Desc list. */
  1089. LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDescOldest->rLinkEntry);
  1090. }
  1091. } else if (u4RemovePolicy & SCN_RM_POLICY_SMART_WEAKEST) {
  1092. P_BSS_DESC_T prBssDescWeakest = (P_BSS_DESC_T) NULL;
  1093. P_BSS_DESC_T prBssDescWeakestSameSSID = (P_BSS_DESC_T) NULL;
  1094. UINT_32 u4SameSSIDCount = 0;
  1095. /* Search BSS Desc from current SCAN result list. */
  1096. LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
  1097. if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
  1098. (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
  1099. /* Don't remove the one currently we are connected. */
  1100. continue;
  1101. }
  1102. if ((!prBssDesc->fgIsHiddenSSID) &&
  1103. (EQUAL_SSID(prBssDesc->aucSSID,
  1104. prBssDesc->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen))) {
  1105. u4SameSSIDCount++;
  1106. if (!prBssDescWeakestSameSSID)
  1107. prBssDescWeakestSameSSID = prBssDesc;
  1108. else if (prBssDesc->ucRCPI < prBssDescWeakestSameSSID->ucRCPI)
  1109. prBssDescWeakestSameSSID = prBssDesc;
  1110. }
  1111. if (!prBssDescWeakest) { /* 1st element */
  1112. prBssDescWeakest = prBssDesc;
  1113. continue;
  1114. }
  1115. if (prBssDesc->ucRCPI < prBssDescWeakest->ucRCPI)
  1116. prBssDescWeakest = prBssDesc;
  1117. }
  1118. if ((u4SameSSIDCount >= SCN_BSS_DESC_SAME_SSID_THRESHOLD) && (prBssDescWeakestSameSSID))
  1119. prBssDescWeakest = prBssDescWeakestSameSSID;
  1120. if (prBssDescWeakest) {
  1121. /* DBGLOG(SCN, TRACE, ("Remove WEAKEST BSS DESC(%#x): MAC: %pM, Update Time = %08lx\n", */
  1122. /* prBssDescOldest, prBssDescOldest->aucBSSID, prBssDescOldest->rUpdateTime)); */
  1123. /* Remove this BSS Desc from the BSS Desc list */
  1124. LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescWeakest);
  1125. /* Return this BSS Desc to the free BSS Desc list. */
  1126. LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDescWeakest->rLinkEntry);
  1127. }
  1128. } else if (u4RemovePolicy & SCN_RM_POLICY_ENTIRE) {
  1129. P_BSS_DESC_T prBSSDescNext;
  1130. LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
  1131. if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
  1132. (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
  1133. /* Don't remove the one currently we are connected. */
  1134. continue;
  1135. }
  1136. /* Remove this BSS Desc from the BSS Desc list */
  1137. LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
  1138. /* Return this BSS Desc to the free BSS Desc list. */
  1139. LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
  1140. }
  1141. }
  1142. return;
  1143. } /* end of scanRemoveBssDescsByPolicy() */
  1144. /*----------------------------------------------------------------------------*/
  1145. /*!
  1146. * @brief Delete BSS Descriptors from current list according to given BSSID.
  1147. *
  1148. * @param[in] prAdapter Pointer to the Adapter structure.
  1149. * @param[in] aucBSSID Given BSSID.
  1150. *
  1151. * @return (none)
  1152. */
  1153. /*----------------------------------------------------------------------------*/
  1154. VOID scanRemoveBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[])
  1155. {
  1156. P_SCAN_INFO_T prScanInfo;
  1157. P_LINK_T prBSSDescList;
  1158. P_LINK_T prFreeBSSDescList;
  1159. P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL;
  1160. P_BSS_DESC_T prBSSDescNext;
  1161. ASSERT(prAdapter);
  1162. ASSERT(aucBSSID);
  1163. prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
  1164. prBSSDescList = &prScanInfo->rBSSDescList;
  1165. prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
  1166. /* Check if such BSS Descriptor exists in a valid list */
  1167. LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
  1168. if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) {
  1169. /* Remove this BSS Desc from the BSS Desc list */
  1170. LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
  1171. /* Return this BSS Desc to the free BSS Desc list. */
  1172. LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
  1173. /* BSSID is not unique, so need to traverse whols link-list */
  1174. }
  1175. }
  1176. } /* end of scanRemoveBssDescByBssid() */
  1177. /*----------------------------------------------------------------------------*/
  1178. /*!
  1179. * @brief Delete BSS Descriptors from current list according to given band configuration
  1180. *
  1181. * @param[in] prAdapter Pointer to the Adapter structure.
  1182. * @param[in] eBand Given band
  1183. * @param[in] eNetTypeIndex AIS - Remove IBSS/Infrastructure BSS
  1184. * BOW - Remove BOW BSS
  1185. * P2P - Remove P2P BSS
  1186. *
  1187. * @return (none)
  1188. */
  1189. /*----------------------------------------------------------------------------*/
  1190. VOID
  1191. scanRemoveBssDescByBandAndNetwork(IN P_ADAPTER_T prAdapter,
  1192. IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex)
  1193. {
  1194. P_SCAN_INFO_T prScanInfo;
  1195. P_LINK_T prBSSDescList;
  1196. P_LINK_T prFreeBSSDescList;
  1197. P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL;
  1198. P_BSS_DESC_T prBSSDescNext;
  1199. BOOLEAN fgToRemove;
  1200. ASSERT(prAdapter);
  1201. ASSERT(eBand <= BAND_NUM);
  1202. ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM);
  1203. prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
  1204. prBSSDescList = &prScanInfo->rBSSDescList;
  1205. prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
  1206. if (eBand == BAND_NULL)
  1207. return; /* no need to do anything, keep all scan result */
  1208. /* Check if such BSS Descriptor exists in a valid list */
  1209. LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
  1210. fgToRemove = FALSE;
  1211. if (prBssDesc->eBand == eBand) {
  1212. switch (eNetTypeIndex) {
  1213. case NETWORK_TYPE_AIS_INDEX:
  1214. if ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE)
  1215. || (prBssDesc->eBSSType == BSS_TYPE_IBSS)) {
  1216. fgToRemove = TRUE;
  1217. }
  1218. break;
  1219. case NETWORK_TYPE_P2P_INDEX:
  1220. if (prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE)
  1221. fgToRemove = TRUE;
  1222. break;
  1223. case NETWORK_TYPE_BOW_INDEX:
  1224. if (prBssDesc->eBSSType == BSS_TYPE_BOW_DEVICE)
  1225. fgToRemove = TRUE;
  1226. break;
  1227. default:
  1228. ASSERT(0);
  1229. break;
  1230. }
  1231. }
  1232. if (fgToRemove == TRUE) {
  1233. /* Remove this BSS Desc from the BSS Desc list */
  1234. LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
  1235. /* Return this BSS Desc to the free BSS Desc list. */
  1236. LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
  1237. }
  1238. }
  1239. } /* end of scanRemoveBssDescByBand() */
  1240. /*----------------------------------------------------------------------------*/
  1241. /*!
  1242. * @brief Clear the CONNECTION FLAG of a specified BSS Descriptor.
  1243. *
  1244. * @param[in] aucBSSID Given BSSID.
  1245. *
  1246. * @return (none)
  1247. */
  1248. /*----------------------------------------------------------------------------*/
  1249. VOID scanRemoveConnFlagOfBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[])
  1250. {
  1251. P_SCAN_INFO_T prScanInfo;
  1252. P_LINK_T prBSSDescList;
  1253. P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL;
  1254. ASSERT(prAdapter);
  1255. ASSERT(aucBSSID);
  1256. prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
  1257. prBSSDescList = &prScanInfo->rBSSDescList;
  1258. /* Search BSS Desc from current SCAN result list. */
  1259. LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
  1260. if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) {
  1261. prBssDesc->fgIsConnected = FALSE;
  1262. prBssDesc->fgIsConnecting = FALSE;
  1263. /* BSSID is not unique, so need to traverse whols link-list */
  1264. }
  1265. }
  1266. return;
  1267. } /* end of scanRemoveConnectionFlagOfBssDescByBssid() */
  1268. /*----------------------------------------------------------------------------*/
  1269. /*!
  1270. * @brief Allocate new BSS_DESC_T
  1271. *
  1272. * @param[in] prAdapter Pointer to the Adapter structure.
  1273. *
  1274. * @return Pointer to BSS Descriptor, if has free space. NULL, if has no space.
  1275. */
  1276. /*----------------------------------------------------------------------------*/
  1277. P_BSS_DESC_T scanAllocateBssDesc(IN P_ADAPTER_T prAdapter)
  1278. {
  1279. P_SCAN_INFO_T prScanInfo;
  1280. P_LINK_T prFreeBSSDescList;
  1281. P_BSS_DESC_T prBssDesc;
  1282. ASSERT(prAdapter);
  1283. prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
  1284. prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
  1285. LINK_REMOVE_HEAD(prFreeBSSDescList, prBssDesc, P_BSS_DESC_T);
  1286. if (prBssDesc) {
  1287. P_LINK_T prBSSDescList;
  1288. kalMemZero(prBssDesc, sizeof(BSS_DESC_T));
  1289. #if CFG_ENABLE_WIFI_DIRECT
  1290. LINK_INITIALIZE(&(prBssDesc->rP2pDeviceList));
  1291. prBssDesc->fgIsP2PPresent = FALSE;
  1292. #endif /* CFG_ENABLE_WIFI_DIRECT */
  1293. prBSSDescList = &prScanInfo->rBSSDescList;
  1294. /* NOTE(Kevin): In current design, this new empty BSS_DESC_T will be
  1295. * inserted to BSSDescList immediately.
  1296. */
  1297. LINK_INSERT_TAIL(prBSSDescList, &prBssDesc->rLinkEntry);
  1298. }
  1299. return prBssDesc;
  1300. } /* end of scanAllocateBssDesc() */
  1301. /*----------------------------------------------------------------------------*/
  1302. /*!
  1303. * @brief This API parses Beacon/ProbeResp frame and insert extracted BSS_DESC_T
  1304. * with IEs into prAdapter->rWifiVar.rScanInfo.aucScanBuffer
  1305. *
  1306. * @param[in] prAdapter Pointer to the Adapter structure.
  1307. * @param[in] prSwRfb Pointer to the receiving frame buffer.
  1308. *
  1309. * @return Pointer to BSS Descriptor
  1310. * NULL if the Beacon/ProbeResp frame is invalid
  1311. */
  1312. /*----------------------------------------------------------------------------*/
  1313. P_BSS_DESC_T scanAddToBssDesc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
  1314. {
  1315. P_BSS_DESC_T prBssDesc = NULL;
  1316. UINT_16 u2CapInfo;
  1317. ENUM_BSS_TYPE_T eBSSType = BSS_TYPE_INFRASTRUCTURE;
  1318. PUINT_8 pucIE;
  1319. UINT_16 u2IELength;
  1320. UINT_16 u2Offset = 0;
  1321. P_WLAN_BEACON_FRAME_T prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) NULL;
  1322. P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL;
  1323. P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T) NULL;
  1324. P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T) NULL;
  1325. P_HIF_RX_HEADER_T prHifRxHdr;
  1326. UINT_8 ucHwChannelNum = 0;
  1327. UINT_8 ucIeDsChannelNum = 0;
  1328. UINT_8 ucIeHtChannelNum = 0;
  1329. BOOLEAN fgIsValidSsid = FALSE, fgEscape = FALSE;
  1330. PARAM_SSID_T rSsid;
  1331. UINT_64 u8Timestamp;
  1332. BOOLEAN fgIsNewBssDesc = FALSE;
  1333. UINT_32 i;
  1334. UINT_8 ucSSIDChar;
  1335. UINT_8 ucOuiType;
  1336. UINT_16 u2SubTypeVersion;
  1337. ASSERT(prAdapter);
  1338. ASSERT(prSwRfb);
  1339. prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) prSwRfb->pvHeader;
  1340. WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2CapInfo, &u2CapInfo);
  1341. WLAN_GET_FIELD_64(&prWlanBeaconFrame->au4Timestamp[0], &u8Timestamp);
  1342. /* decide BSS type */
  1343. switch (u2CapInfo & CAP_INFO_BSS_TYPE) {
  1344. case CAP_INFO_ESS:
  1345. /* It can also be Group Owner of P2P Group. */
  1346. eBSSType = BSS_TYPE_INFRASTRUCTURE;
  1347. break;
  1348. case CAP_INFO_IBSS:
  1349. eBSSType = BSS_TYPE_IBSS;
  1350. break;
  1351. case 0:
  1352. /* The P2P Device shall set the ESS bit of the Capabilities field
  1353. * in the Probe Response fame to 0 and IBSS bit to 0. (3.1.2.1.1) */
  1354. eBSSType = BSS_TYPE_P2P_DEVICE;
  1355. break;
  1356. #if CFG_ENABLE_BT_OVER_WIFI
  1357. /* @TODO: add rule to identify BOW beacons */
  1358. #endif
  1359. default:
  1360. DBGLOG(SCN, ERROR, "wrong bss type %d\n", (INT_32)(u2CapInfo & CAP_INFO_BSS_TYPE));
  1361. return NULL;
  1362. }
  1363. /* 4 <1.1> Pre-parse SSID IE */
  1364. pucIE = prWlanBeaconFrame->aucInfoElem;
  1365. u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
  1366. (UINT_16) OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]);
  1367. if (u2IELength > CFG_IE_BUFFER_SIZE)
  1368. u2IELength = CFG_IE_BUFFER_SIZE;
  1369. kalMemZero(&rSsid, sizeof(rSsid));
  1370. IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
  1371. switch (IE_ID(pucIE)) {
  1372. case ELEM_ID_SSID:
  1373. if (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID) {
  1374. ucSSIDChar = '\0';
  1375. /* D-Link DWL-900AP+ */
  1376. if (IE_LEN(pucIE) == 0)
  1377. fgIsValidSsid = FALSE;
  1378. /* Cisco AP1230A - (IE_LEN(pucIE) == 1) && (SSID_IE(pucIE)->aucSSID[0] == '\0') */
  1379. /* Linksys WRK54G/WL520g - (IE_LEN(pucIE) == n) &&
  1380. * (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') */
  1381. else {
  1382. for (i = 0; i < IE_LEN(pucIE); i++)
  1383. ucSSIDChar |= SSID_IE(pucIE)->aucSSID[i];
  1384. if (ucSSIDChar)
  1385. fgIsValidSsid = TRUE;
  1386. }
  1387. /* Update SSID to BSS Descriptor only if SSID is not hidden. */
  1388. if (fgIsValidSsid == TRUE) {
  1389. COPY_SSID(rSsid.aucSsid,
  1390. rSsid.u4SsidLen, SSID_IE(pucIE)->aucSSID, SSID_IE(pucIE)->ucLength);
  1391. }
  1392. }
  1393. fgEscape = TRUE;
  1394. break;
  1395. default:
  1396. break;
  1397. }
  1398. if (fgEscape == TRUE)
  1399. break;
  1400. }
  1401. if (fgIsValidSsid)
  1402. DBGLOG(SCN, EVENT, "%s %pM channel %d\n", rSsid.aucSsid, prWlanBeaconFrame->aucBSSID,
  1403. HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr));
  1404. else
  1405. DBGLOG(SCN, EVENT, "hidden ssid, %pM channel %d\n", prWlanBeaconFrame->aucBSSID,
  1406. HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr));
  1407. /* 4 <1.2> Replace existing BSS_DESC_T or allocate a new one */
  1408. prBssDesc = scanSearchExistingBssDescWithSsid(prAdapter,
  1409. eBSSType,
  1410. (PUINT_8) prWlanBeaconFrame->aucBSSID,
  1411. (PUINT_8) prWlanBeaconFrame->aucSrcAddr,
  1412. fgIsValidSsid, fgIsValidSsid == TRUE ? &rSsid : NULL);
  1413. if (prBssDesc == (P_BSS_DESC_T) NULL) {
  1414. fgIsNewBssDesc = TRUE;
  1415. do {
  1416. /* 4 <1.2.1> First trial of allocation */
  1417. prBssDesc = scanAllocateBssDesc(prAdapter);
  1418. if (prBssDesc)
  1419. break;
  1420. /* 4 <1.2.2> Hidden is useless, remove the oldest hidden ssid. (for passive scan) */
  1421. scanRemoveBssDescsByPolicy(prAdapter,
  1422. (SCN_RM_POLICY_EXCLUDE_CONNECTED |
  1423. SCN_RM_POLICY_OLDEST_HIDDEN |
  1424. SCN_RM_POLICY_TIMEOUT));
  1425. /* 4 <1.2.3> Second tail of allocation */
  1426. prBssDesc = scanAllocateBssDesc(prAdapter);
  1427. if (prBssDesc)
  1428. break;
  1429. /* 4 <1.2.4> Remove the weakest one */
  1430. /* If there are more than half of BSS which has the same ssid as connection
  1431. * setting, remove the weakest one from them.
  1432. * Else remove the weakest one.
  1433. */
  1434. scanRemoveBssDescsByPolicy(prAdapter,
  1435. (SCN_RM_POLICY_EXCLUDE_CONNECTED | SCN_RM_POLICY_SMART_WEAKEST));
  1436. /* 4 <1.2.5> reallocation */
  1437. prBssDesc = scanAllocateBssDesc(prAdapter);
  1438. if (prBssDesc)
  1439. break;
  1440. /* 4 <1.2.6> no space, should not happen */
  1441. DBGLOG(SCN, ERROR, "no bss desc available after remove policy\n");
  1442. return NULL;
  1443. } while (FALSE);
  1444. } else {
  1445. OS_SYSTIME rCurrentTime;
  1446. /* WCXRP00000091 */
  1447. /* if the received strength is much weaker than the original one, */
  1448. /* ignore it due to it might be received on the folding frequency */
  1449. GET_CURRENT_SYSTIME(&rCurrentTime);
  1450. if (prBssDesc->eBSSType != eBSSType) {
  1451. prBssDesc->eBSSType = eBSSType;
  1452. } else if (HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr) != prBssDesc->ucChannelNum &&
  1453. prBssDesc->ucRCPI > prSwRfb->prHifRxHdr->ucRcpi) {
  1454. /* for signal strength is too much weaker and previous beacon is not stale */
  1455. if ((prBssDesc->ucRCPI - prSwRfb->prHifRxHdr->ucRcpi) >= REPLICATED_BEACON_STRENGTH_THRESHOLD &&
  1456. (rCurrentTime - prBssDesc->rUpdateTime) <= REPLICATED_BEACON_FRESH_PERIOD) {
  1457. DBGLOG(SCN, EVENT, "rssi is too much weaker and previous one is fresh\n");
  1458. return prBssDesc;
  1459. }
  1460. /* for received beacons too close in time domain */
  1461. else if (rCurrentTime - prBssDesc->rUpdateTime <= REPLICATED_BEACON_TIME_THRESHOLD) {
  1462. DBGLOG(SCN, EVENT, "receive beacon/probe reponses too close\n");
  1463. return prBssDesc;
  1464. }
  1465. }
  1466. /* if Timestamp has been reset, re-generate BSS DESC 'cause AP should have reset itself */
  1467. if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && u8Timestamp < prBssDesc->u8TimeStamp.QuadPart) {
  1468. BOOLEAN fgIsConnected, fgIsConnecting;
  1469. /* set flag for indicating this is a new BSS-DESC */
  1470. fgIsNewBssDesc = TRUE;
  1471. /* backup 2 flags for APs which reset timestamp unexpectedly */
  1472. fgIsConnected = prBssDesc->fgIsConnected;
  1473. fgIsConnecting = prBssDesc->fgIsConnecting;
  1474. scanRemoveBssDescByBssid(prAdapter, prBssDesc->aucBSSID);
  1475. prBssDesc = scanAllocateBssDesc(prAdapter);
  1476. if (!prBssDesc)
  1477. return NULL;
  1478. /* restore */
  1479. prBssDesc->fgIsConnected = fgIsConnected;
  1480. prBssDesc->fgIsConnecting = fgIsConnecting;
  1481. }
  1482. }
  1483. #if 1
  1484. prBssDesc->u2RawLength = prSwRfb->u2PacketLen;
  1485. if (prBssDesc->u2RawLength > CFG_RAW_BUFFER_SIZE)
  1486. prBssDesc->u2RawLength = CFG_RAW_BUFFER_SIZE;
  1487. kalMemCopy(prBssDesc->aucRawBuf, prWlanBeaconFrame, prBssDesc->u2RawLength);
  1488. #endif
  1489. /* NOTE: Keep consistency of Scan Record during JOIN process */
  1490. if ((fgIsNewBssDesc == FALSE) && prBssDesc->fgIsConnecting) {
  1491. DBGLOG(SCN, INFO, "we're connecting this BSS(%pM) now, don't update it\n",
  1492. prBssDesc->aucBSSID);
  1493. return prBssDesc;
  1494. }
  1495. /* 4 <2> Get information from Fixed Fields */
  1496. prBssDesc->eBSSType = eBSSType; /* Update the latest BSS type information. */
  1497. COPY_MAC_ADDR(prBssDesc->aucSrcAddr, prWlanBeaconFrame->aucSrcAddr);
  1498. COPY_MAC_ADDR(prBssDesc->aucBSSID, prWlanBeaconFrame->aucBSSID);
  1499. prBssDesc->u8TimeStamp.QuadPart = u8Timestamp;
  1500. WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2BeaconInterval, &prBssDesc->u2BeaconInterval);
  1501. prBssDesc->u2CapInfo = u2CapInfo;
  1502. /* 4 <2.1> Retrieve IEs for later parsing */
  1503. u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
  1504. (UINT_16) OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]);
  1505. if (u2IELength > CFG_IE_BUFFER_SIZE) {
  1506. u2IELength = CFG_IE_BUFFER_SIZE;
  1507. prBssDesc->fgIsIEOverflow = TRUE;
  1508. } else {
  1509. prBssDesc->fgIsIEOverflow = FALSE;
  1510. }
  1511. prBssDesc->u2IELength = u2IELength;
  1512. kalMemCopy(prBssDesc->aucIEBuf, prWlanBeaconFrame->aucInfoElem, u2IELength);
  1513. /* 4 <2.2> reset prBssDesc variables in case that AP has been reconfigured */
  1514. prBssDesc->fgIsERPPresent = FALSE;
  1515. prBssDesc->fgIsHTPresent = FALSE;
  1516. prBssDesc->eSco = CHNL_EXT_SCN;
  1517. prBssDesc->fgIEWAPI = FALSE;
  1518. #if CFG_RSN_MIGRATION
  1519. prBssDesc->fgIERSN = FALSE;
  1520. #endif
  1521. #if CFG_PRIVACY_MIGRATION
  1522. prBssDesc->fgIEWPA = FALSE;
  1523. #endif
  1524. /* 4 <3.1> Full IE parsing on SW_RFB_T */
  1525. pucIE = prWlanBeaconFrame->aucInfoElem;
  1526. IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
  1527. switch (IE_ID(pucIE)) {
  1528. case ELEM_ID_SSID:
  1529. if ((!prIeSsid) && /* NOTE(Kevin): for Atheros IOT #1 */
  1530. (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) {
  1531. BOOLEAN fgIsHiddenSSID = FALSE;
  1532. ucSSIDChar = '\0';
  1533. prIeSsid = (P_IE_SSID_T) pucIE;
  1534. /* D-Link DWL-900AP+ */
  1535. if (IE_LEN(pucIE) == 0)
  1536. fgIsHiddenSSID = TRUE;
  1537. /* Cisco AP1230A - (IE_LEN(pucIE) == 1) && (SSID_IE(pucIE)->aucSSID[0] == '\0') */
  1538. /* Linksys WRK54G/WL520g - (IE_LEN(pucIE) == n) &&
  1539. * (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') */
  1540. else {
  1541. for (i = 0; i < IE_LEN(pucIE); i++)
  1542. ucSSIDChar |= SSID_IE(pucIE)->aucSSID[i];
  1543. if (!ucSSIDChar)
  1544. fgIsHiddenSSID = TRUE;
  1545. }
  1546. /* Update SSID to BSS Descriptor only if SSID is not hidden. */
  1547. if (!fgIsHiddenSSID) {
  1548. COPY_SSID(prBssDesc->aucSSID,
  1549. prBssDesc->ucSSIDLen,
  1550. SSID_IE(pucIE)->aucSSID, SSID_IE(pucIE)->ucLength);
  1551. }
  1552. #if 0
  1553. /*
  1554. After we connect to a hidden SSID, prBssDesc->aucSSID[] will
  1555. not be empty and prBssDesc->ucSSIDLen will not be 0,
  1556. so maybe we need to empty prBssDesc->aucSSID[] and set
  1557. prBssDesc->ucSSIDLen to 0 in prBssDesc to avoid that
  1558. UI still displays hidden SSID AP in scan list after
  1559. we disconnect the hidden SSID AP.
  1560. */
  1561. else {
  1562. prBssDesc->aucSSID[0] = '\0';
  1563. prBssDesc->ucSSIDLen = 0;
  1564. }
  1565. #endif
  1566. }
  1567. break;
  1568. case ELEM_ID_SUP_RATES:
  1569. /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8.
  1570. * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B),
  1571. * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)"
  1572. */
  1573. /* TP-LINK will set extra and incorrect ie with ELEM_ID_SUP_RATES */
  1574. if ((!prIeSupportedRate) && (IE_LEN(pucIE) <= RATE_NUM))
  1575. prIeSupportedRate = SUP_RATES_IE(pucIE);
  1576. break;
  1577. case ELEM_ID_DS_PARAM_SET:
  1578. if (IE_LEN(pucIE) == ELEM_MAX_LEN_DS_PARAMETER_SET)
  1579. ucIeDsChannelNum = DS_PARAM_IE(pucIE)->ucCurrChnl;
  1580. break;
  1581. case ELEM_ID_TIM:
  1582. if (IE_LEN(pucIE) <= ELEM_MAX_LEN_TIM)
  1583. prBssDesc->ucDTIMPeriod = TIM_IE(pucIE)->ucDTIMPeriod;
  1584. break;
  1585. case ELEM_ID_IBSS_PARAM_SET:
  1586. if (IE_LEN(pucIE) == ELEM_MAX_LEN_IBSS_PARAMETER_SET)
  1587. prBssDesc->u2ATIMWindow = IBSS_PARAM_IE(pucIE)->u2ATIMWindow;
  1588. break;
  1589. #if 0 /* CFG_SUPPORT_802_11D */
  1590. case ELEM_ID_COUNTRY_INFO:
  1591. prBssDesc->prIECountry = (P_IE_COUNTRY_T) pucIE;
  1592. break;
  1593. #endif
  1594. case ELEM_ID_ERP_INFO:
  1595. if (IE_LEN(pucIE) == ELEM_MAX_LEN_ERP)
  1596. prBssDesc->fgIsERPPresent = TRUE;
  1597. break;
  1598. case ELEM_ID_EXTENDED_SUP_RATES:
  1599. if (!prIeExtSupportedRate)
  1600. prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE);
  1601. break;
  1602. #if CFG_RSN_MIGRATION
  1603. case ELEM_ID_RSN:
  1604. if (rsnParseRsnIE(prAdapter, RSN_IE(pucIE), &prBssDesc->rRSNInfo)) {
  1605. prBssDesc->fgIERSN = TRUE;
  1606. prBssDesc->u2RsnCap = prBssDesc->rRSNInfo.u2RsnCap;
  1607. if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2)
  1608. rsnCheckPmkidCache(prAdapter, prBssDesc);
  1609. }
  1610. break;
  1611. #endif
  1612. case ELEM_ID_HT_CAP:
  1613. prBssDesc->fgIsHTPresent = TRUE;
  1614. break;
  1615. case ELEM_ID_HT_OP:
  1616. if (IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2))
  1617. break;
  1618. if ((((P_IE_HT_OP_T) pucIE)->ucInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) {
  1619. prBssDesc->eSco = (ENUM_CHNL_EXT_T)
  1620. (((P_IE_HT_OP_T) pucIE)->ucInfo1 & HT_OP_INFO1_SCO);
  1621. }
  1622. ucIeHtChannelNum = ((P_IE_HT_OP_T) pucIE)->ucPrimaryChannel;
  1623. break;
  1624. #if CFG_SUPPORT_WAPI
  1625. case ELEM_ID_WAPI:
  1626. if (wapiParseWapiIE(WAPI_IE(pucIE), &prBssDesc->rIEWAPI))
  1627. prBssDesc->fgIEWAPI = TRUE;
  1628. break;
  1629. #endif
  1630. case ELEM_ID_VENDOR: /* ELEM_ID_P2P, ELEM_ID_WMM */
  1631. #if CFG_PRIVACY_MIGRATION
  1632. if (rsnParseCheckForWFAInfoElem(prAdapter, pucIE, &ucOuiType, &u2SubTypeVersion)) {
  1633. if ((ucOuiType == VENDOR_OUI_TYPE_WPA) && (u2SubTypeVersion == VERSION_WPA)) {
  1634. if (rsnParseWpaIE(prAdapter, WPA_IE(pucIE), &prBssDesc->rWPAInfo))
  1635. prBssDesc->fgIEWPA = TRUE;
  1636. }
  1637. }
  1638. #endif
  1639. #if CFG_ENABLE_WIFI_DIRECT
  1640. if (prAdapter->fgIsP2PRegistered) {
  1641. if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType)) {
  1642. if (ucOuiType == VENDOR_OUI_TYPE_P2P)
  1643. prBssDesc->fgIsP2PPresent = TRUE;
  1644. }
  1645. }
  1646. #endif /* CFG_ENABLE_WIFI_DIRECT */
  1647. break;
  1648. /* no default */
  1649. }
  1650. }
  1651. /* 4 <3.2> Save information from IEs - SSID */
  1652. /* Update Flag of Hidden SSID for used in SEARCH STATE. */
  1653. /* NOTE(Kevin): in current driver, the ucSSIDLen == 0 represent
  1654. * all cases of hidden SSID.
  1655. * If the fgIsHiddenSSID == TRUE, it means we didn't get the ProbeResp with
  1656. * valid SSID.
  1657. */
  1658. if (prBssDesc->ucSSIDLen == 0)
  1659. prBssDesc->fgIsHiddenSSID = TRUE;
  1660. else
  1661. prBssDesc->fgIsHiddenSSID = FALSE;
  1662. /* 4 <3.3> Check rate information in related IEs. */
  1663. if (prIeSupportedRate || prIeExtSupportedRate) {
  1664. rateGetRateSetFromIEs(prIeSupportedRate,
  1665. prIeExtSupportedRate,
  1666. &prBssDesc->u2OperationalRateSet,
  1667. &prBssDesc->u2BSSBasicRateSet, &prBssDesc->fgIsUnknownBssBasicRate);
  1668. }
  1669. /* 4 <4> Update information from HIF RX Header */
  1670. {
  1671. prHifRxHdr = prSwRfb->prHifRxHdr;
  1672. ASSERT(prHifRxHdr);
  1673. /* 4 <4.1> Get TSF comparison result */
  1674. prBssDesc->fgIsLargerTSF = HIF_RX_HDR_GET_TCL_FLAG(prHifRxHdr);
  1675. /* 4 <4.2> Get Band information */
  1676. prBssDesc->eBand = HIF_RX_HDR_GET_RF_BAND(prHifRxHdr);
  1677. /* 4 <4.2> Get channel and RCPI information */
  1678. ucHwChannelNum = HIF_RX_HDR_GET_CHNL_NUM(prHifRxHdr);
  1679. if (BAND_2G4 == prBssDesc->eBand) {
  1680. /* Update RCPI if in right channel */
  1681. if (ucIeDsChannelNum >= 1 && ucIeDsChannelNum <= 14) {
  1682. /* Receive Beacon/ProbeResp frame from adjacent channel. */
  1683. if ((ucIeDsChannelNum == ucHwChannelNum) || (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI))
  1684. prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
  1685. /* trust channel information brought by IE */
  1686. prBssDesc->ucChannelNum = ucIeDsChannelNum;
  1687. } else if (ucIeHtChannelNum >= 1 && ucIeHtChannelNum <= 14) {
  1688. /* Receive Beacon/ProbeResp frame from adjacent channel. */
  1689. if ((ucIeHtChannelNum == ucHwChannelNum) || (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI))
  1690. prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
  1691. /* trust channel information brought by IE */
  1692. prBssDesc->ucChannelNum = ucIeHtChannelNum;
  1693. } else {
  1694. prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
  1695. prBssDesc->ucChannelNum = ucHwChannelNum;
  1696. }
  1697. }
  1698. /* 5G Band */
  1699. else {
  1700. if (ucIeHtChannelNum >= 1 && ucIeHtChannelNum < 200) {
  1701. /* Receive Beacon/ProbeResp frame from adjacent channel. */
  1702. if ((ucIeHtChannelNum == ucHwChannelNum) || (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI))
  1703. prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
  1704. /* trust channel information brought by IE */
  1705. prBssDesc->ucChannelNum = ucIeHtChannelNum;
  1706. } else {
  1707. /* Always update RCPI */
  1708. prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
  1709. prBssDesc->ucChannelNum = ucHwChannelNum;
  1710. }
  1711. }
  1712. }
  1713. /* 4 <5> PHY type setting */
  1714. prBssDesc->ucPhyTypeSet = 0;
  1715. if (BAND_2G4 == prBssDesc->eBand) {
  1716. /* check if support 11n */
  1717. if (prBssDesc->fgIsHTPresent)
  1718. prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT;
  1719. /* if not 11n only */
  1720. if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) {
  1721. /* check if support 11g */
  1722. if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM) || prBssDesc->fgIsERPPresent)
  1723. prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_ERP;
  1724. /* if not 11g only */
  1725. if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_OFDM)) {
  1726. /* check if support 11b */
  1727. if ((prBssDesc->u2OperationalRateSet & RATE_SET_HR_DSSS))
  1728. prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS;
  1729. }
  1730. }
  1731. } else { /* (BAND_5G == prBssDesc->eBande) */
  1732. /* check if support 11n */
  1733. if (prBssDesc->fgIsHTPresent)
  1734. prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT;
  1735. /* if not 11n only */
  1736. if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) {
  1737. /* Support 11a definitely */
  1738. prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM;
  1739. ASSERT(!(prBssDesc->u2OperationalRateSet & RATE_SET_HR_DSSS));
  1740. }
  1741. }
  1742. /* 4 <6> Update BSS_DESC_T's Last Update TimeStamp. */
  1743. GET_CURRENT_SYSTIME(&prBssDesc->rUpdateTime);
  1744. return prBssDesc;
  1745. }
  1746. /*----------------------------------------------------------------------------*/
  1747. /*!
  1748. * @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to scan result for query
  1749. *
  1750. * @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure.
  1751. *
  1752. * @retval WLAN_STATUS_SUCCESS It is a valid Scan Result and been sent to the host.
  1753. * @retval WLAN_STATUS_FAILURE It is not a valid Scan Result.
  1754. */
  1755. /*----------------------------------------------------------------------------*/
  1756. WLAN_STATUS scanAddScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb)
  1757. {
  1758. P_SCAN_INFO_T prScanInfo;
  1759. UINT_8 aucRatesEx[PARAM_MAX_LEN_RATES_EX];
  1760. P_WLAN_BEACON_FRAME_T prWlanBeaconFrame;
  1761. PARAM_MAC_ADDRESS rMacAddr;
  1762. PARAM_SSID_T rSsid;
  1763. ENUM_PARAM_NETWORK_TYPE_T eNetworkType;
  1764. PARAM_802_11_CONFIG_T rConfiguration;
  1765. ENUM_PARAM_OP_MODE_T eOpMode;
  1766. UINT_8 ucRateLen = 0;
  1767. UINT_32 i;
  1768. ASSERT(prAdapter);
  1769. ASSERT(prSwRfb);
  1770. prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
  1771. if (prBssDesc->eBand == BAND_2G4) {
  1772. if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM)
  1773. || prBssDesc->fgIsERPPresent) {
  1774. eNetworkType = PARAM_NETWORK_TYPE_OFDM24;
  1775. } else {
  1776. eNetworkType = PARAM_NETWORK_TYPE_DS;
  1777. }
  1778. } else {
  1779. ASSERT(prBssDesc->eBand == BAND_5G);
  1780. eNetworkType = PARAM_NETWORK_TYPE_OFDM5;
  1781. }
  1782. if (prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) {
  1783. /* NOTE(Kevin): Not supported by WZC(TBD) */
  1784. return WLAN_STATUS_FAILURE;
  1785. }
  1786. prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) prSwRfb->pvHeader;
  1787. COPY_MAC_ADDR(rMacAddr, prWlanBeaconFrame->aucBSSID);
  1788. COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen);
  1789. rConfiguration.u4Length = sizeof(PARAM_802_11_CONFIG_T);
  1790. rConfiguration.u4BeaconPeriod = (UINT_32) prWlanBeaconFrame->u2BeaconInterval;
  1791. rConfiguration.u4ATIMWindow = prBssDesc->u2ATIMWindow;
  1792. rConfiguration.u4DSConfig = nicChannelNum2Freq(prBssDesc->ucChannelNum);
  1793. rConfiguration.rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T);
  1794. rateGetDataRatesFromRateSet(prBssDesc->u2OperationalRateSet, 0, aucRatesEx, &ucRateLen);
  1795. /* NOTE(Kevin): Set unused entries, if any, at the end of the array to 0.
  1796. * from OID_802_11_BSSID_LIST
  1797. */
  1798. for (i = ucRateLen; i < sizeof(aucRatesEx) / sizeof(aucRatesEx[0]); i++)
  1799. aucRatesEx[i] = 0;
  1800. switch (prBssDesc->eBSSType) {
  1801. case BSS_TYPE_IBSS:
  1802. eOpMode = NET_TYPE_IBSS;
  1803. break;
  1804. case BSS_TYPE_INFRASTRUCTURE:
  1805. case BSS_TYPE_P2P_DEVICE:
  1806. case BSS_TYPE_BOW_DEVICE:
  1807. default:
  1808. eOpMode = NET_TYPE_INFRA;
  1809. break;
  1810. }
  1811. DBGLOG(SCN, TRACE, "ind %s %d\n", prBssDesc->aucSSID, prBssDesc->ucChannelNum);
  1812. #if (CFG_SUPPORT_TDLS == 1)
  1813. {
  1814. if (flgTdlsTestExtCapElm == TRUE) {
  1815. /* only for RALINK AP */
  1816. UINT8 *pucElm = (UINT8 *) (prSwRfb->pvHeader + prSwRfb->u2PacketLen);
  1817. kalMemCopy(pucElm - 9, aucTdlsTestExtCapElm, 7);
  1818. prSwRfb->u2PacketLen -= 2;
  1819. /* prSwRfb->u2PacketLen += 7; */
  1820. DBGLOG(TDLS, INFO,
  1821. "<tdls> %s: append ext cap element to %pM\n",
  1822. __func__, prBssDesc->aucBSSID);
  1823. }
  1824. }
  1825. #endif /* CFG_SUPPORT_TDLS */
  1826. if (prAdapter->rWifiVar.rScanInfo.fgNloScanning &&
  1827. test_bit(SUSPEND_FLAG_CLEAR_WHEN_RESUME, &prAdapter->ulSuspendFlag)) {
  1828. UINT_8 i = 0;
  1829. P_BSS_DESC_T *pprPendBssDesc = &prScanInfo->rNloParam.aprPendingBssDescToInd[0];
  1830. for (; i < SCN_SSID_MATCH_MAX_NUM; i++) {
  1831. if (pprPendBssDesc[i])
  1832. continue;
  1833. DBGLOG(SCN, INFO,
  1834. "indicate bss[%pM] before wiphy resume, need to indicate again after wiphy resume\n",
  1835. prBssDesc->aucBSSID);
  1836. pprPendBssDesc[i] = prBssDesc;
  1837. break;
  1838. }
  1839. }
  1840. kalIndicateBssInfo(prAdapter->prGlueInfo,
  1841. (PUINT_8) prSwRfb->pvHeader,
  1842. prSwRfb->u2PacketLen, prBssDesc->ucChannelNum, RCPI_TO_dBm(prBssDesc->ucRCPI));
  1843. nicAddScanResult(prAdapter,
  1844. rMacAddr,
  1845. &rSsid,
  1846. prWlanBeaconFrame->u2CapInfo & CAP_INFO_PRIVACY ? 1 : 0,
  1847. RCPI_TO_dBm(prBssDesc->ucRCPI),
  1848. eNetworkType,
  1849. &rConfiguration,
  1850. eOpMode,
  1851. aucRatesEx,
  1852. prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen,
  1853. (PUINT_8) ((ULONG) (prSwRfb->pvHeader) + WLAN_MAC_MGMT_HEADER_LEN));
  1854. return WLAN_STATUS_SUCCESS;
  1855. } /* end of scanAddScanResult() */
  1856. #if 1
  1857. BOOLEAN scanCheckBssIsLegal(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc)
  1858. {
  1859. BOOLEAN fgAddToScanResult = FALSE;
  1860. ENUM_BAND_T eBand = 0;
  1861. UINT_8 ucChannel = 0;
  1862. ASSERT(prAdapter);
  1863. /* check the channel is in the legal doamin */
  1864. if (rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum) == TRUE) {
  1865. /* check ucChannelNum/eBand for adjacement channel filtering */
  1866. if (cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel) == TRUE &&
  1867. (eBand != prBssDesc->eBand || ucChannel != prBssDesc->ucChannelNum)) {
  1868. fgAddToScanResult = FALSE;
  1869. } else {
  1870. fgAddToScanResult = TRUE;
  1871. }
  1872. }
  1873. return fgAddToScanResult;
  1874. }
  1875. VOID scanReportBss2Cfg80211(IN P_ADAPTER_T prAdapter, IN ENUM_BSS_TYPE_T eBSSType, IN P_BSS_DESC_T SpecificprBssDesc)
  1876. {
  1877. P_SCAN_INFO_T prScanInfo = (P_SCAN_INFO_T) NULL;
  1878. P_LINK_T prBSSDescList = (P_LINK_T) NULL;
  1879. P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL;
  1880. RF_CHANNEL_INFO_T rChannelInfo;
  1881. ASSERT(prAdapter);
  1882. prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
  1883. prBSSDescList = &prScanInfo->rBSSDescList;
  1884. DBGLOG(SCN, TRACE, "scanReportBss2Cfg80211\n");
  1885. if (SpecificprBssDesc) {
  1886. {
  1887. /* check BSSID is legal channel */
  1888. if (!scanCheckBssIsLegal(prAdapter, SpecificprBssDesc)) {
  1889. DBGLOG(SCN, TRACE, "Remove specific SSID[%s %d]\n",
  1890. SpecificprBssDesc->aucSSID, SpecificprBssDesc->ucChannelNum);
  1891. return;
  1892. }
  1893. DBGLOG(SCN, TRACE, "Report Specific SSID[%s]\n", SpecificprBssDesc->aucSSID);
  1894. if (eBSSType == BSS_TYPE_INFRASTRUCTURE) {
  1895. kalIndicateBssInfo(prAdapter->prGlueInfo,
  1896. (PUINT_8) SpecificprBssDesc->aucRawBuf,
  1897. SpecificprBssDesc->u2RawLength,
  1898. SpecificprBssDesc->ucChannelNum,
  1899. RCPI_TO_dBm(SpecificprBssDesc->ucRCPI));
  1900. } else {
  1901. rChannelInfo.ucChannelNum = SpecificprBssDesc->ucChannelNum;
  1902. rChannelInfo.eBand = SpecificprBssDesc->eBand;
  1903. kalP2PIndicateBssInfo(prAdapter->prGlueInfo,
  1904. (PUINT_8) SpecificprBssDesc->aucRawBuf,
  1905. SpecificprBssDesc->u2RawLength,
  1906. &rChannelInfo, RCPI_TO_dBm(SpecificprBssDesc->ucRCPI));
  1907. }
  1908. #if CFG_ENABLE_WIFI_DIRECT
  1909. SpecificprBssDesc->fgIsP2PReport = FALSE;
  1910. #endif
  1911. }
  1912. } else {
  1913. /* Search BSS Desc from current SCAN result list. */
  1914. LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
  1915. #if CFG_AUTO_CHANNEL_SEL_SUPPORT
  1916. /* 4 Auto Channel Selection:Record the AP Number */
  1917. P_PARAM_CHN_LOAD_INFO prChnLoad;
  1918. UINT_8 ucIdx = 0;
  1919. if (((prBssDesc->ucChannelNum > 0) && (prBssDesc->ucChannelNum <= 48))
  1920. || (prBssDesc->ucChannelNum >= 147) /*non-DFS Channel */) {
  1921. if (prBssDesc->ucChannelNum <= HW_CHNL_NUM_MAX_2G4) {
  1922. ucIdx = prBssDesc->ucChannelNum - 1;
  1923. } else if (prBssDesc->ucChannelNum <= 48) {
  1924. ucIdx = (UINT_8) (HW_CHNL_NUM_MAX_2G4 + (prBssDesc->ucChannelNum - 34) / 4);
  1925. } else {
  1926. ucIdx =
  1927. (UINT_8) (HW_CHNL_NUM_MAX_2G4 + 4 + (prBssDesc->ucChannelNum - 149) / 4);
  1928. }
  1929. if (ucIdx < MAX_AUTO_CHAL_NUM) {
  1930. prChnLoad = (P_PARAM_CHN_LOAD_INFO) &
  1931. (prAdapter->rWifiVar.rChnLoadInfo.rEachChnLoad[ucIdx]);
  1932. prChnLoad->ucChannel = prBssDesc->ucChannelNum;
  1933. prChnLoad->u2APNum++;
  1934. } else {
  1935. DBGLOG(SCN, WARN, "ACS: ChIdx > MAX_AUTO_CHAL_NUM\n");
  1936. }
  1937. }
  1938. #endif
  1939. /* check BSSID is legal channel */
  1940. if (!scanCheckBssIsLegal(prAdapter, prBssDesc)) {
  1941. DBGLOG(SCN, TRACE, "Remove SSID[%s %d]\n",
  1942. prBssDesc->aucSSID, prBssDesc->ucChannelNum);
  1943. continue;
  1944. }
  1945. if ((prBssDesc->eBSSType == eBSSType)
  1946. #if CFG_ENABLE_WIFI_DIRECT
  1947. || ((eBSSType == BSS_TYPE_P2P_DEVICE) && (prBssDesc->fgIsP2PReport == TRUE))
  1948. #endif
  1949. ) {
  1950. DBGLOG(SCN, TRACE, "Report ALL SSID[%s %d]\n",
  1951. prBssDesc->aucSSID, prBssDesc->ucChannelNum);
  1952. if (eBSSType == BSS_TYPE_INFRASTRUCTURE) {
  1953. if (prBssDesc->u2RawLength != 0) {
  1954. kalIndicateBssInfo(prAdapter->prGlueInfo,
  1955. (PUINT_8) prBssDesc->aucRawBuf,
  1956. prBssDesc->u2RawLength,
  1957. prBssDesc->ucChannelNum,
  1958. RCPI_TO_dBm(prBssDesc->ucRCPI));
  1959. kalMemZero(prBssDesc->aucRawBuf, CFG_RAW_BUFFER_SIZE);
  1960. prBssDesc->u2RawLength = 0;
  1961. #if CFG_ENABLE_WIFI_DIRECT
  1962. prBssDesc->fgIsP2PReport = FALSE;
  1963. #endif
  1964. }
  1965. } else {
  1966. #if CFG_ENABLE_WIFI_DIRECT
  1967. if (prBssDesc->fgIsP2PReport == TRUE) {
  1968. #endif
  1969. rChannelInfo.ucChannelNum = prBssDesc->ucChannelNum;
  1970. rChannelInfo.eBand = prBssDesc->eBand;
  1971. kalP2PIndicateBssInfo(prAdapter->prGlueInfo,
  1972. (PUINT_8) prBssDesc->aucRawBuf,
  1973. prBssDesc->u2RawLength,
  1974. &rChannelInfo, RCPI_TO_dBm(prBssDesc->ucRCPI));
  1975. /* do not clear it then we can pass the bss in Specific report */
  1976. /* kalMemZero(prBssDesc->aucRawBuf,CFG_RAW_BUFFER_SIZE); */
  1977. /*
  1978. the BSS entry will not be cleared after scan done.
  1979. So if we dont receive the BSS in next scan, we cannot
  1980. pass it. We use u2RawLength for the purpose.
  1981. */
  1982. /* prBssDesc->u2RawLength=0; */
  1983. #if CFG_ENABLE_WIFI_DIRECT
  1984. prBssDesc->fgIsP2PReport = FALSE;
  1985. }
  1986. #endif
  1987. }
  1988. }
  1989. }
  1990. #if CFG_AUTO_CHANNEL_SEL_SUPPORT
  1991. prAdapter->rWifiVar.rChnLoadInfo.fgDataReadyBit = TRUE;
  1992. #endif
  1993. }
  1994. }
  1995. #endif
  1996. /*----------------------------------------------------------------------------*/
  1997. /*!
  1998. * @brief Parse the content of given Beacon or ProbeResp Frame.
  1999. *
  2000. * @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure.
  2001. *
  2002. * @retval WLAN_STATUS_SUCCESS if not report this SW_RFB_T to host
  2003. * @retval WLAN_STATUS_PENDING if report this SW_RFB_T to host as scan result
  2004. */
  2005. /*----------------------------------------------------------------------------*/
  2006. WLAN_STATUS scanProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
  2007. {
  2008. P_CONNECTION_SETTINGS_T prConnSettings;
  2009. P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL;
  2010. WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
  2011. P_BSS_INFO_T prAisBssInfo;
  2012. P_WLAN_BEACON_FRAME_T prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) NULL;
  2013. #if CFG_SLT_SUPPORT
  2014. P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T) NULL;
  2015. #endif
  2016. ASSERT(prAdapter);
  2017. ASSERT(prSwRfb);
  2018. /* 4 <0> Ignore invalid Beacon Frame */
  2019. if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) <
  2020. (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN)) {
  2021. /* to debug beacon length too small issue */
  2022. UINT_32 u4MailBox0;
  2023. nicGetMailbox(prAdapter, 0, &u4MailBox0);
  2024. DBGLOG(SCN, WARN, "if conn sys also get less length (0x5a means yes) %x\n", (UINT_32) u4MailBox0);
  2025. DBGLOG(SCN, WARN, "u2PacketLen %d, u2HeaderLen %d, payloadLen %d\n",
  2026. prSwRfb->u2PacketLen, prSwRfb->u2HeaderLen,
  2027. prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen);
  2028. /* dumpMemory8(prSwRfb->pvHeader, prSwRfb->u2PacketLen); */
  2029. #ifndef _lint
  2030. ASSERT(0);
  2031. #endif /* _lint */
  2032. return rStatus;
  2033. }
  2034. #if CFG_SLT_SUPPORT
  2035. prSltInfo = &prAdapter->rWifiVar.rSltInfo;
  2036. if (prSltInfo->fgIsDUT) {
  2037. DBGLOG(SCN, INFO, "\n\rBCN: RX\n");
  2038. prSltInfo->u4BeaconReceiveCnt++;
  2039. return WLAN_STATUS_SUCCESS;
  2040. } else {
  2041. return WLAN_STATUS_SUCCESS;
  2042. }
  2043. #endif
  2044. prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
  2045. prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
  2046. prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) prSwRfb->pvHeader;
  2047. /*ALPS01475157: don't show SSID on scan list for multicast MAC AP */
  2048. if (IS_BMCAST_MAC_ADDR(prWlanBeaconFrame->aucSrcAddr)) {
  2049. DBGLOG(SCN, WARN, "received beacon/probe response from multicast AP\n");
  2050. return rStatus;
  2051. }
  2052. /* 4 <1> Parse and add into BSS_DESC_T */
  2053. prBssDesc = scanAddToBssDesc(prAdapter, prSwRfb);
  2054. if (prBssDesc) {
  2055. /* 4 <1.1> Beacon Change Detection for Connected BSS */
  2056. if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED &&
  2057. ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && prConnSettings->eOPMode != NET_TYPE_IBSS)
  2058. || (prBssDesc->eBSSType == BSS_TYPE_IBSS && prConnSettings->eOPMode != NET_TYPE_INFRA)) &&
  2059. EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID) &&
  2060. EQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, prAisBssInfo->aucSSID,
  2061. prAisBssInfo->ucSSIDLen)) {
  2062. BOOLEAN fgNeedDisconnect = FALSE;
  2063. #if CFG_SUPPORT_BEACON_CHANGE_DETECTION
  2064. /* <1.1.2> check if supported rate differs */
  2065. if (prAisBssInfo->u2OperationalRateSet != prBssDesc->u2OperationalRateSet)
  2066. fgNeedDisconnect = TRUE;
  2067. #endif
  2068. #if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE
  2069. if (
  2070. #if CFG_SUPPORT_WAPI
  2071. (prAdapter->rWifiVar.rConnSettings.fgWapiMode == TRUE &&
  2072. !wapiPerformPolicySelection(prAdapter, prBssDesc)) ||
  2073. #endif
  2074. rsnCheckSecurityModeChanged(prAdapter, prAisBssInfo, prBssDesc)) {
  2075. DBGLOG(SCN, INFO, "Beacon security mode change detected\n");
  2076. fgNeedDisconnect = FALSE;
  2077. aisBssSecurityChanged(prAdapter);
  2078. }
  2079. #endif
  2080. /* <1.1.3> beacon content change detected, disconnect immediately */
  2081. if (fgNeedDisconnect == TRUE)
  2082. aisBssBeaconTimeout(prAdapter);
  2083. }
  2084. /* 4 <1.1> Update AIS_BSS_INFO */
  2085. if (((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && prConnSettings->eOPMode != NET_TYPE_IBSS)
  2086. || (prBssDesc->eBSSType == BSS_TYPE_IBSS && prConnSettings->eOPMode != NET_TYPE_INFRA))) {
  2087. if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
  2088. /* *not* checking prBssDesc->fgIsConnected anymore,
  2089. * due to Linksys AP uses " " as hidden SSID, and would have different BSS descriptor */
  2090. if ((!prAisBssInfo->ucDTIMPeriod) &&
  2091. EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID) &&
  2092. (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) &&
  2093. ((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_BEACON)) {
  2094. prAisBssInfo->ucDTIMPeriod = prBssDesc->ucDTIMPeriod;
  2095. /* sync with firmware for beacon information */
  2096. nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_AIS_INDEX);
  2097. }
  2098. }
  2099. #if CFG_SUPPORT_ADHOC
  2100. if (EQUAL_SSID(prBssDesc->aucSSID,
  2101. prBssDesc->ucSSIDLen,
  2102. prConnSettings->aucSSID,
  2103. prConnSettings->ucSSIDLen) &&
  2104. (prBssDesc->eBSSType == BSS_TYPE_IBSS) && (prAisBssInfo->eCurrentOPMode == OP_MODE_IBSS)) {
  2105. ibssProcessMatchedBeacon(prAdapter, prAisBssInfo, prBssDesc,
  2106. prSwRfb->prHifRxHdr->ucRcpi);
  2107. }
  2108. #endif /* CFG_SUPPORT_ADHOC */
  2109. }
  2110. rlmProcessBcn(prAdapter,
  2111. prSwRfb,
  2112. ((P_WLAN_BEACON_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem,
  2113. (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
  2114. (UINT_16) (OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0])));
  2115. /* 4 <3> Send SW_RFB_T to HIF when we perform SCAN for HOST */
  2116. if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE || prBssDesc->eBSSType == BSS_TYPE_IBSS) {
  2117. /* for AIS, send to host */
  2118. if (prConnSettings->fgIsScanReqIssued || prAdapter->rWifiVar.rScanInfo.fgNloScanning) {
  2119. BOOLEAN fgAddToScanResult;
  2120. fgAddToScanResult = scanCheckBssIsLegal(prAdapter, prBssDesc);
  2121. if (fgAddToScanResult == TRUE)
  2122. rStatus = scanAddScanResult(prAdapter, prBssDesc, prSwRfb);
  2123. }
  2124. }
  2125. #if CFG_ENABLE_WIFI_DIRECT
  2126. if (prAdapter->fgIsP2PRegistered)
  2127. scanP2pProcessBeaconAndProbeResp(prAdapter, prSwRfb, &rStatus, prBssDesc, prWlanBeaconFrame);
  2128. #endif
  2129. }
  2130. return rStatus;
  2131. } /* end of scanProcessBeaconAndProbeResp() */
  2132. /*----------------------------------------------------------------------------*/
  2133. /*!
  2134. * \brief Search the Candidate of BSS Descriptor for JOIN(Infrastructure) or
  2135. * MERGE(AdHoc) according to current Connection Policy.
  2136. *
  2137. * \return Pointer to BSS Descriptor, if found. NULL, if not found
  2138. */
  2139. /*----------------------------------------------------------------------------*/
  2140. P_BSS_DESC_T scanSearchBssDescByPolicy(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex)
  2141. {
  2142. P_CONNECTION_SETTINGS_T prConnSettings;
  2143. P_BSS_INFO_T prBssInfo;
  2144. P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
  2145. P_SCAN_INFO_T prScanInfo;
  2146. P_LINK_T prBSSDescList;
  2147. P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL;
  2148. P_BSS_DESC_T prPrimaryBssDesc = (P_BSS_DESC_T) NULL;
  2149. P_BSS_DESC_T prCandidateBssDesc = (P_BSS_DESC_T) NULL;
  2150. P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL;
  2151. P_STA_RECORD_T prPrimaryStaRec;
  2152. P_STA_RECORD_T prCandidateStaRec = (P_STA_RECORD_T) NULL;
  2153. OS_SYSTIME rCurrentTime;
  2154. /* The first one reach the check point will be our candidate */
  2155. BOOLEAN fgIsFindFirst = (BOOLEAN) FALSE;
  2156. BOOLEAN fgIsFindBestRSSI = (BOOLEAN) FALSE;
  2157. BOOLEAN fgIsFindBestEncryptionLevel = (BOOLEAN) FALSE;
  2158. /* BOOLEAN fgIsFindMinChannelLoad = (BOOLEAN)FALSE; */
  2159. /* TODO(Kevin): Support Min Channel Load */
  2160. /* UINT_8 aucChannelLoad[CHANNEL_NUM] = {0}; */
  2161. BOOLEAN fgIsFixedChannel;
  2162. ENUM_BAND_T eBand = 0;
  2163. UINT_8 ucChannel = 0;
  2164. ASSERT(prAdapter);
  2165. prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
  2166. prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]);
  2167. prAisSpecBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo);
  2168. prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
  2169. prBSSDescList = &prScanInfo->rBSSDescList;
  2170. GET_CURRENT_SYSTIME(&rCurrentTime);
  2171. /* check for fixed channel operation */
  2172. if (eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) {
  2173. #if CFG_P2P_LEGACY_COEX_REVISE
  2174. fgIsFixedChannel = cnmAisDetectP2PChannel(prAdapter, &eBand, &ucChannel);
  2175. #else
  2176. fgIsFixedChannel = cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel);
  2177. #endif
  2178. } else {
  2179. fgIsFixedChannel = FALSE;
  2180. }
  2181. #if DBG
  2182. if (prConnSettings->ucSSIDLen < ELEM_MAX_LEN_SSID)
  2183. prConnSettings->aucSSID[prConnSettings->ucSSIDLen] = '\0';
  2184. #endif
  2185. DBGLOG(SCN, INFO, "SEARCH: Bss Num: %d, Look for SSID: %s, %pM Band=%d, channel=%d\n",
  2186. (UINT_32) prBSSDescList->u4NumElem, prConnSettings->aucSSID,
  2187. (prConnSettings->aucBSSID), eBand, ucChannel);
  2188. /* 4 <1> The outer loop to search for a candidate. */
  2189. LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
  2190. /* TODO(Kevin): Update Minimum Channel Load Information here */
  2191. DBGLOG(SCN, TRACE, "SEARCH: [ %pM ], SSID:%s\n",
  2192. prBssDesc->aucBSSID, prBssDesc->aucSSID);
  2193. /* 4 <2> Check PHY Type and attributes */
  2194. /* 4 <2.1> Check Unsupported BSS PHY Type */
  2195. if (!(prBssDesc->ucPhyTypeSet & (prAdapter->rWifiVar.ucAvailablePhyTypeSet))) {
  2196. DBGLOG(SCN, TRACE, "SEARCH: Ignore unsupported ucPhyTypeSet = %x\n", prBssDesc->ucPhyTypeSet);
  2197. continue;
  2198. }
  2199. /* 4 <2.2> Check if has unknown NonHT BSS Basic Rate Set. */
  2200. if (prBssDesc->fgIsUnknownBssBasicRate)
  2201. continue;
  2202. /* 4 <2.3> Check if fixed operation cases should be aware */
  2203. if (fgIsFixedChannel == TRUE && (prBssDesc->eBand != eBand || prBssDesc->ucChannelNum != ucChannel))
  2204. continue;
  2205. /* 4 <2.4> Check if the channel is legal under regulatory domain */
  2206. if (rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum) == FALSE)
  2207. continue;
  2208. /* 4 <2.5> Check if this BSS_DESC_T is stale */
  2209. if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
  2210. SEC_TO_SYSTIME(SCN_BSS_DESC_REMOVE_TIMEOUT_SEC))) {
  2211. BOOLEAN fgIsNeedToCheckTimeout = TRUE;
  2212. #if CFG_SUPPORT_ROAMING
  2213. P_ROAMING_INFO_T prRoamingFsmInfo;
  2214. prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo);
  2215. if ((prRoamingFsmInfo->eCurrentState == ROAMING_STATE_DISCOVERY) ||
  2216. (prRoamingFsmInfo->eCurrentState == ROAMING_STATE_ROAM)) {
  2217. if (++prRoamingFsmInfo->RoamingEntryTimeoutSkipCount <
  2218. ROAMING_ENTRY_TIMEOUT_SKIP_COUNT_MAX) {
  2219. fgIsNeedToCheckTimeout = FALSE;
  2220. DBGLOG(SCN, INFO, "SEARCH: Romaing skip SCN_BSS_DESC_REMOVE_TIMEOUT_SEC\n");
  2221. }
  2222. }
  2223. #endif
  2224. if (fgIsNeedToCheckTimeout == TRUE) {
  2225. DBGLOG(SCN, TRACE, "Ignore stale bss %pM\n", prBssDesc->aucBSSID);
  2226. continue;
  2227. }
  2228. }
  2229. /* 4 <3> Check if reach the excessive join retry limit */
  2230. /* NOTE(Kevin): STA_RECORD_T is recorded by TA. */
  2231. prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) eNetTypeIndex, prBssDesc->aucSrcAddr);
  2232. if (prStaRec) {
  2233. /* NOTE(Kevin):
  2234. * The Status Code is the result of a Previous Connection Request,
  2235. * we use this as SCORE for choosing a proper
  2236. * candidate (Also used for compare see <6>)
  2237. * The Reason Code is an indication of the reason why AP reject us,
  2238. * we use this Code for "Reject"
  2239. * a SCAN result to become our candidate(Like a blacklist).
  2240. */
  2241. #if 0 /* TODO(Kevin): */
  2242. if (prStaRec->u2ReasonCode != REASON_CODE_RESERVED) {
  2243. DBGLOG(SCN, INFO, "SEARCH: Ignore BSS with previous Reason Code = %d\n",
  2244. prStaRec->u2ReasonCode);
  2245. continue;
  2246. } else
  2247. #endif
  2248. if (prStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL) {
  2249. /* NOTE(Kevin): greedy association - after timeout, we'll still
  2250. * try to associate to the AP whose STATUS of conection attempt
  2251. * was not success.
  2252. * We may also use (ucJoinFailureCount x JOIN_RETRY_INTERVAL_SEC) for
  2253. * time bound.
  2254. */
  2255. if ((prStaRec->ucJoinFailureCount < JOIN_MAX_RETRY_FAILURE_COUNT) ||
  2256. (CHECK_FOR_TIMEOUT(rCurrentTime,
  2257. prStaRec->rLastJoinTime,
  2258. SEC_TO_SYSTIME(JOIN_RETRY_INTERVAL_SEC)))) {
  2259. /* NOTE(Kevin): Every JOIN_RETRY_INTERVAL_SEC interval, we can retry
  2260. * JOIN_MAX_RETRY_FAILURE_COUNT times.
  2261. */
  2262. if (prStaRec->ucJoinFailureCount >= JOIN_MAX_RETRY_FAILURE_COUNT)
  2263. prStaRec->ucJoinFailureCount = 0;
  2264. DBGLOG(SCN, INFO,
  2265. "SEARCH: Try to join BSS again,Status Code=%d (Curr=%u/Last Join=%u)\n",
  2266. prStaRec->u2StatusCode, rCurrentTime, prStaRec->rLastJoinTime);
  2267. } else {
  2268. DBGLOG(SCN, INFO,
  2269. "SEARCH: Ignore BSS which reach maximum Join Retry Count = %d\n",
  2270. JOIN_MAX_RETRY_FAILURE_COUNT);
  2271. continue;
  2272. }
  2273. }
  2274. }
  2275. /* 4 <4> Check for various NETWORK conditions */
  2276. if (eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) {
  2277. /* 4 <4.1> Check BSS Type for the corresponding Operation Mode in Connection Setting */
  2278. /* NOTE(Kevin): For NET_TYPE_AUTO_SWITCH, we will always pass following check. */
  2279. if (((prConnSettings->eOPMode == NET_TYPE_INFRA) &&
  2280. (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE))
  2281. #if CFG_SUPPORT_ADHOC
  2282. || ((prConnSettings->eOPMode == NET_TYPE_IBSS
  2283. || prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS)
  2284. && (prBssDesc->eBSSType != BSS_TYPE_IBSS))
  2285. #endif
  2286. ) {
  2287. DBGLOG(SCN, TRACE, "Cur OPMode %d, Ignore eBSSType = %d\n",
  2288. prConnSettings->eOPMode, prBssDesc->eBSSType);
  2289. continue;
  2290. }
  2291. /* 4 <4.2> Check AP's BSSID if OID_802_11_BSSID has been set. */
  2292. if ((prConnSettings->fgIsConnByBssidIssued) &&
  2293. (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE)) {
  2294. if (UNEQUAL_MAC_ADDR(prConnSettings->aucBSSID, prBssDesc->aucBSSID)) {
  2295. DBGLOG(SCN, TRACE, "SEARCH: Ignore due to BSSID was not matched!\n");
  2296. continue;
  2297. }
  2298. }
  2299. #if CFG_SUPPORT_ADHOC
  2300. /* 4 <4.3> Check for AdHoc Mode */
  2301. if (prBssDesc->eBSSType == BSS_TYPE_IBSS) {
  2302. OS_SYSTIME rCurrentTime;
  2303. /* 4 <4.3.1> Check if this SCAN record has been updated recently for IBSS. */
  2304. /* NOTE(Kevin): Because some STA may change its BSSID frequently after it
  2305. * create the IBSS - e.g. IPN2220, so we need to make sure we get the new one.
  2306. * For BSS, if the old record was matched, however it won't be able to pass
  2307. * the Join Process later.
  2308. */
  2309. GET_CURRENT_SYSTIME(&rCurrentTime);
  2310. if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
  2311. SEC_TO_SYSTIME(SCN_ADHOC_BSS_DESC_TIMEOUT_SEC))) {
  2312. DBGLOG(SCN, LOUD,
  2313. "SEARCH: Skip old record of BSS Descriptor - BSSID:[%pM]\n\n",
  2314. prBssDesc->aucBSSID);
  2315. continue;
  2316. }
  2317. /* 4 <4.3.2> Check Peer's capability */
  2318. if (ibssCheckCapabilityForAdHocMode(prAdapter, prBssDesc) == WLAN_STATUS_FAILURE) {
  2319. if (prPrimaryBssDesc)
  2320. DBGLOG(SCN, INFO,
  2321. "SEARCH: BSS DESC MAC: %pM, not supported AdHoc Mode.\n",
  2322. prPrimaryBssDesc->aucBSSID);
  2323. continue;
  2324. }
  2325. /* 4 <4.3.3> Compare TSF */
  2326. if (prBssInfo->fgIsBeaconActivated &&
  2327. UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID)) {
  2328. DBGLOG(SCN, LOUD,
  2329. "SEARCH: prBssDesc->fgIsLargerTSF = %d\n", prBssDesc->fgIsLargerTSF);
  2330. if (!prBssDesc->fgIsLargerTSF) {
  2331. DBGLOG(SCN, INFO,
  2332. "SEARCH: Ignore BSS DESC MAC: [ %pM ], Smaller TSF\n",
  2333. prBssDesc->aucBSSID);
  2334. continue;
  2335. }
  2336. }
  2337. }
  2338. #endif /* CFG_SUPPORT_ADHOC */
  2339. }
  2340. #if 0 /* TODO(Kevin): For IBSS */
  2341. /* 4 <2.c> Check if this SCAN record has been updated recently for IBSS. */
  2342. /* NOTE(Kevin): Because some STA may change its BSSID frequently after it
  2343. * create the IBSS, so we need to make sure we get the new one.
  2344. * For BSS, if the old record was matched, however it won't be able to pass
  2345. * the Join Process later.
  2346. */
  2347. if (prBssDesc->eBSSType == BSS_TYPE_IBSS) {
  2348. OS_SYSTIME rCurrentTime;
  2349. GET_CURRENT_SYSTIME(&rCurrentTime);
  2350. if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
  2351. SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) {
  2352. DBGLOG(SCAN, TRACE, "Skip old record of BSS Descriptor - BSSID:[%pM]\n\n",
  2353. prBssDesc->aucBSSID);
  2354. continue;
  2355. }
  2356. }
  2357. if ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) &&
  2358. (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED)) {
  2359. OS_SYSTIME rCurrentTime;
  2360. GET_CURRENT_SYSTIME(&rCurrentTime);
  2361. if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
  2362. SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) {
  2363. DBGLOG(SCAN, TRACE, "Skip old record of BSS Descriptor - BSSID:[%pM]\n\n",
  2364. (prBssDesc->aucBSSID));
  2365. continue;
  2366. }
  2367. }
  2368. /* 4 <4B> Check for IBSS AdHoc Mode. */
  2369. /* Skip if one or more BSS Basic Rate are not supported by current AdHocMode */
  2370. if (prPrimaryBssDesc->eBSSType == BSS_TYPE_IBSS) {
  2371. /* 4 <4B.1> Check if match the Capability of current IBSS AdHoc Mode. */
  2372. if (ibssCheckCapabilityForAdHocMode(prAdapter, prPrimaryBssDesc) == WLAN_STATUS_FAILURE) {
  2373. DBGLOG(SCAN, TRACE,
  2374. "Ignore BSS DESC MAC: %pM, Capability not supported for AdHoc Mode.\n",
  2375. prPrimaryBssDesc->aucBSSID);
  2376. continue;
  2377. }
  2378. /* 4 <4B.2> IBSS Merge Decision Flow for SEARCH STATE. */
  2379. if (prAdapter->fgIsIBSSActive &&
  2380. UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prPrimaryBssDesc->aucBSSID)) {
  2381. if (!fgIsLocalTSFRead) {
  2382. NIC_GET_CURRENT_TSF(prAdapter, &rCurrentTsf);
  2383. DBGLOG(SCAN, TRACE,
  2384. "\n\nCurrent TSF : %08lx-%08lx\n\n",
  2385. rCurrentTsf.u.HighPart, rCurrentTsf.u.LowPart);
  2386. }
  2387. if (rCurrentTsf.QuadPart > prPrimaryBssDesc->u8TimeStamp.QuadPart) {
  2388. DBGLOG(SCAN, TRACE,
  2389. "Ignore BSS DESC MAC: [%pM], Current BSSID: [%pM].\n",
  2390. prPrimaryBssDesc->aucBSSID, prBssInfo->aucBSSID);
  2391. DBGLOG(SCAN, TRACE,
  2392. "\n\nBSS's TSF : %08lx-%08lx\n\n",
  2393. prPrimaryBssDesc->u8TimeStamp.u.HighPart,
  2394. prPrimaryBssDesc->u8TimeStamp.u.LowPart);
  2395. prPrimaryBssDesc->fgIsLargerTSF = FALSE;
  2396. continue;
  2397. } else {
  2398. prPrimaryBssDesc->fgIsLargerTSF = TRUE;
  2399. }
  2400. }
  2401. }
  2402. /* 4 <5> Check the Encryption Status. */
  2403. if (rsnPerformPolicySelection(prPrimaryBssDesc)) {
  2404. if (prPrimaryBssDesc->ucEncLevel > 0) {
  2405. fgIsFindBestEncryptionLevel = TRUE;
  2406. fgIsFindFirst = FALSE;
  2407. }
  2408. } else {
  2409. /* Can't pass the Encryption Status Check, get next one */
  2410. continue;
  2411. }
  2412. /* For RSN Pre-authentication, update the PMKID canidate list for
  2413. same SSID and encrypt status */
  2414. /* Update PMKID candicate list. */
  2415. if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) {
  2416. rsnUpdatePmkidCandidateList(prPrimaryBssDesc);
  2417. if (prAdapter->rWifiVar.rAisBssInfo.u4PmkidCandicateCount)
  2418. prAdapter->rWifiVar.rAisBssInfo.fgIndicatePMKID = rsnCheckPmkidCandicate();
  2419. }
  2420. #endif
  2421. prPrimaryBssDesc = (P_BSS_DESC_T) NULL;
  2422. /* 4 <6> Check current Connection Policy. */
  2423. switch (prConnSettings->eConnectionPolicy) {
  2424. case CONNECT_BY_SSID_BEST_RSSI:
  2425. /* Choose Hidden SSID to join only if the `fgIsEnableJoin...` is TRUE */
  2426. if (prAdapter->rWifiVar.fgEnableJoinToHiddenSSID && prBssDesc->fgIsHiddenSSID) {
  2427. /* NOTE(Kevin): following if () statement means that
  2428. * If Target is hidden, then we won't connect when user specify SSID_ANY policy.
  2429. */
  2430. if (prConnSettings->ucSSIDLen) {
  2431. prPrimaryBssDesc = prBssDesc;
  2432. fgIsFindBestRSSI = TRUE;
  2433. }
  2434. } else if (EQUAL_SSID(prBssDesc->aucSSID,
  2435. prBssDesc->ucSSIDLen,
  2436. prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) {
  2437. prPrimaryBssDesc = prBssDesc;
  2438. fgIsFindBestRSSI = TRUE;
  2439. DBGLOG(SCN, TRACE, "SEARCH: fgIsFindBestRSSI=TRUE, %d, prPrimaryBssDesc=[ %pM ]\n",
  2440. prBssDesc->ucRCPI, prPrimaryBssDesc->aucBSSID);
  2441. }
  2442. break;
  2443. case CONNECT_BY_SSID_ANY:
  2444. /* NOTE(Kevin): In this policy, we don't know the desired
  2445. * SSID from user, so we should exclude the Hidden SSID from scan list.
  2446. * And because we refuse to connect to Hidden SSID node at the beginning, so
  2447. * when the JOIN Module deal with a BSS_DESC_T which has fgIsHiddenSSID == TRUE,
  2448. * then the Connection Settings must be valid without doubt.
  2449. */
  2450. if (!prBssDesc->fgIsHiddenSSID) {
  2451. prPrimaryBssDesc = prBssDesc;
  2452. fgIsFindFirst = TRUE;
  2453. }
  2454. break;
  2455. case CONNECT_BY_BSSID:
  2456. if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prConnSettings->aucBSSID))
  2457. prPrimaryBssDesc = prBssDesc;
  2458. break;
  2459. default:
  2460. break;
  2461. }
  2462. /* Primary Candidate was not found */
  2463. if (prPrimaryBssDesc == NULL)
  2464. continue;
  2465. /* 4 <7> Check the Encryption Status. */
  2466. if (prPrimaryBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) {
  2467. #if CFG_SUPPORT_WAPI
  2468. if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) {
  2469. DBGLOG(SCN, TRACE, "SEARCH: fgWapiMode == 1\n");
  2470. if (wapiPerformPolicySelection(prAdapter, prPrimaryBssDesc)) {
  2471. fgIsFindFirst = TRUE;
  2472. } else {
  2473. /* Can't pass the Encryption Status Check, get next one */
  2474. DBGLOG(SCN, TRACE, "SEARCH: WAPI cannot pass the Encryption Status Check!\n");
  2475. continue;
  2476. }
  2477. } else
  2478. #endif
  2479. #if CFG_RSN_MIGRATION
  2480. if (rsnPerformPolicySelection(prAdapter, prPrimaryBssDesc)) {
  2481. if (prAisSpecBssInfo->fgCounterMeasure) {
  2482. DBGLOG(RSN, INFO, "Skip while at counter measure period!!!\n");
  2483. continue;
  2484. }
  2485. if (prPrimaryBssDesc->ucEncLevel > 0) {
  2486. fgIsFindBestEncryptionLevel = TRUE;
  2487. fgIsFindFirst = FALSE;
  2488. }
  2489. #if 0
  2490. /* Update PMKID candicate list. */
  2491. if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) {
  2492. rsnUpdatePmkidCandidateList(prPrimaryBssDesc);
  2493. if (prAisSpecBssInfo->u4PmkidCandicateCount) {
  2494. if (rsnCheckPmkidCandicate()) {
  2495. DBGLOG(RSN, WARN,
  2496. "Prepare a timer to indicate candidate %pM\n",
  2497. (prAisSpecBssInfo->arPmkidCache
  2498. [prAisSpecBssInfo->u4PmkidCacheCount].
  2499. rBssidInfo.aucBssid)));
  2500. cnmTimerStopTimer(&prAisSpecBssInfo->rPreauthenticationTimer);
  2501. cnmTimerStartTimer(&prAisSpecBssInfo->rPreauthenticationTimer,
  2502. SEC_TO_MSEC
  2503. (WAIT_TIME_IND_PMKID_CANDICATE_SEC));
  2504. }
  2505. }
  2506. }
  2507. #endif
  2508. } else {
  2509. /* Can't pass the Encryption Status Check, get next one */
  2510. continue;
  2511. }
  2512. #endif
  2513. } else {
  2514. /* Todo:: P2P and BOW Policy Selection */
  2515. }
  2516. prPrimaryStaRec = prStaRec;
  2517. /* 4 <8> Compare the Candidate and the Primary Scan Record. */
  2518. if (!prCandidateBssDesc) {
  2519. prCandidateBssDesc = prPrimaryBssDesc;
  2520. prCandidateStaRec = prPrimaryStaRec;
  2521. /* 4 <8.1> Condition - Get the first matched one. */
  2522. if (fgIsFindFirst)
  2523. break;
  2524. } else {
  2525. #if 0 /* TODO(Kevin): For security(TBD) */
  2526. /* 4 <6B> Condition - Choose the one with best Encryption Score. */
  2527. if (fgIsFindBestEncryptionLevel) {
  2528. if (prCandidateBssDesc->ucEncLevel < prPrimaryBssDesc->ucEncLevel) {
  2529. prCandidateBssDesc = prPrimaryBssDesc;
  2530. prCandidateStaRec = prPrimaryStaRec;
  2531. continue;
  2532. }
  2533. }
  2534. /* If reach here, that means they have the same Encryption Score.
  2535. */
  2536. /* 4 <6C> Condition - Give opportunity to the one we didn't connect before. */
  2537. /* For roaming, only compare the candidates other than current associated BSSID. */
  2538. if (!prCandidateBssDesc->fgIsConnected && !prPrimaryBssDesc->fgIsConnected) {
  2539. if ((prCandidateStaRec != (P_STA_RECORD_T) NULL) &&
  2540. (prCandidateStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL)) {
  2541. DBGLOG(SCAN, TRACE,
  2542. "So far -BSS DESC MAC: %pM has nonzero Status Code = %d\n",
  2543. prCandidateBssDesc->aucBSSID,
  2544. prCandidateStaRec->u2StatusCode);
  2545. if (prPrimaryStaRec != (P_STA_RECORD_T) NULL) {
  2546. if (prPrimaryStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL) {
  2547. /* Give opportunity to the one with smaller rLastJoinTime */
  2548. if (TIME_BEFORE(prCandidateStaRec->rLastJoinTime,
  2549. prPrimaryStaRec->rLastJoinTime)) {
  2550. continue;
  2551. }
  2552. /* We've connect to CANDIDATE recently,
  2553. * let us try PRIMARY now */
  2554. else {
  2555. prCandidateBssDesc = prPrimaryBssDesc;
  2556. prCandidateStaRec = prPrimaryStaRec;
  2557. continue;
  2558. }
  2559. }
  2560. /* PRIMARY's u2StatusCode = 0 */
  2561. else {
  2562. prCandidateBssDesc = prPrimaryBssDesc;
  2563. prCandidateStaRec = prPrimaryStaRec;
  2564. continue;
  2565. }
  2566. }
  2567. /* PRIMARY has no StaRec - We didn't connet to PRIMARY before */
  2568. else {
  2569. prCandidateBssDesc = prPrimaryBssDesc;
  2570. prCandidateStaRec = prPrimaryStaRec;
  2571. continue;
  2572. }
  2573. } else {
  2574. if ((prPrimaryStaRec != (P_STA_RECORD_T) NULL) &&
  2575. (prPrimaryStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL)) {
  2576. continue;
  2577. }
  2578. }
  2579. }
  2580. #endif
  2581. /* 4 <6D> Condition - Visible SSID win Hidden SSID. */
  2582. if (prCandidateBssDesc->fgIsHiddenSSID) {
  2583. if (!prPrimaryBssDesc->fgIsHiddenSSID) {
  2584. prCandidateBssDesc = prPrimaryBssDesc; /* The non Hidden SSID win. */
  2585. prCandidateStaRec = prPrimaryStaRec;
  2586. continue;
  2587. }
  2588. } else {
  2589. if (prPrimaryBssDesc->fgIsHiddenSSID)
  2590. continue;
  2591. }
  2592. /* 4 <6E> Condition - Choose the one with better RCPI(RSSI). */
  2593. if (fgIsFindBestRSSI) {
  2594. /* TODO(Kevin): We shouldn't compare the actual value, we should
  2595. * allow some acceptable tolerance of some RSSI percentage here.
  2596. */
  2597. DBGLOG(SCN, TRACE,
  2598. "Candidate [%pM]: RCPI = %d, joinFailCnt=%d, Primary [%pM]: RCPI = %d, joinFailCnt=%d\n",
  2599. prCandidateBssDesc->aucBSSID,
  2600. prCandidateBssDesc->ucRCPI, prCandidateBssDesc->ucJoinFailureCount,
  2601. prPrimaryBssDesc->aucBSSID,
  2602. prPrimaryBssDesc->ucRCPI, prPrimaryBssDesc->ucJoinFailureCount);
  2603. ASSERT(!(prCandidateBssDesc->fgIsConnected && prPrimaryBssDesc->fgIsConnected));
  2604. if (prPrimaryBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD) {
  2605. /* give a chance to do join if join fail before
  2606. * SCN_BSS_DECRASE_JOIN_FAIL_CNT_SEC seconds
  2607. */
  2608. if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rJoinFailTime,
  2609. SEC_TO_SYSTIME(SCN_BSS_JOIN_FAIL_CNT_RESET_SEC))) {
  2610. prBssDesc->ucJoinFailureCount = SCN_BSS_JOIN_FAIL_THRESOLD -
  2611. SCN_BSS_JOIN_FAIL_RESET_STEP;
  2612. DBGLOG(SCN, INFO,
  2613. "decrease join fail count for Bss %pM to %u, timeout second %d\n",
  2614. prBssDesc->aucBSSID, prBssDesc->ucJoinFailureCount,
  2615. SCN_BSS_JOIN_FAIL_CNT_RESET_SEC);
  2616. }
  2617. }
  2618. /* NOTE: To prevent SWING,
  2619. * we do roaming only if target AP has at least 5dBm larger than us. */
  2620. if (prCandidateBssDesc->fgIsConnected) {
  2621. if (prCandidateBssDesc->ucRCPI + ROAMING_NO_SWING_RCPI_STEP <=
  2622. prPrimaryBssDesc->ucRCPI &&
  2623. prPrimaryBssDesc->ucJoinFailureCount < SCN_BSS_JOIN_FAIL_THRESOLD) {
  2624. prCandidateBssDesc = prPrimaryBssDesc;
  2625. prCandidateStaRec = prPrimaryStaRec;
  2626. continue;
  2627. }
  2628. } else if (prPrimaryBssDesc->fgIsConnected) {
  2629. if (prCandidateBssDesc->ucRCPI <
  2630. (prPrimaryBssDesc->ucRCPI + ROAMING_NO_SWING_RCPI_STEP) ||
  2631. (prCandidateBssDesc->ucJoinFailureCount >=
  2632. SCN_BSS_JOIN_FAIL_THRESOLD)) {
  2633. prCandidateBssDesc = prPrimaryBssDesc;
  2634. prCandidateStaRec = prPrimaryStaRec;
  2635. continue;
  2636. }
  2637. } else if (prPrimaryBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD)
  2638. continue;
  2639. else if (prCandidateBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD ||
  2640. prCandidateBssDesc->ucRCPI < prPrimaryBssDesc->ucRCPI) {
  2641. prCandidateBssDesc = prPrimaryBssDesc;
  2642. prCandidateStaRec = prPrimaryStaRec;
  2643. continue;
  2644. }
  2645. }
  2646. #if 0
  2647. /* If reach here, that means they have the same Encryption Score, and
  2648. * both RSSI value are close too.
  2649. */
  2650. /* 4 <6F> Seek the minimum Channel Load for less interference. */
  2651. if (fgIsFindMinChannelLoad) {
  2652. /* Do nothing */
  2653. /* TODO(Kevin): Check which one has minimum channel load in its channel */
  2654. }
  2655. #endif
  2656. }
  2657. }
  2658. if (prCandidateBssDesc != NULL) {
  2659. DBGLOG(SCN, INFO,
  2660. "SEARCH: Candidate BSS: %pM\n", prCandidateBssDesc->aucBSSID);
  2661. }
  2662. return prCandidateBssDesc;
  2663. } /* end of scanSearchBssDescByPolicy() */
  2664. #if CFG_SUPPORT_AGPS_ASSIST
  2665. VOID scanReportScanResultToAgps(P_ADAPTER_T prAdapter)
  2666. {
  2667. P_LINK_T prBSSDescList = &prAdapter->rWifiVar.rScanInfo.rBSSDescList;
  2668. P_BSS_DESC_T prBssDesc = NULL;
  2669. P_AGPS_AP_LIST_T prAgpsApList;
  2670. P_AGPS_AP_INFO_T prAgpsInfo;
  2671. P_SCAN_INFO_T prScanInfo = &prAdapter->rWifiVar.rScanInfo;
  2672. UINT_8 ucIndex = 0;
  2673. prAgpsApList = kalMemAlloc(sizeof(AGPS_AP_LIST_T), VIR_MEM_TYPE);
  2674. if (!prAgpsApList)
  2675. return;
  2676. prAgpsInfo = &prAgpsApList->arApInfo[0];
  2677. LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
  2678. if (prBssDesc->rUpdateTime < prScanInfo->rLastScanCompletedTime)
  2679. continue;
  2680. COPY_MAC_ADDR(prAgpsInfo->aucBSSID, prBssDesc->aucBSSID);
  2681. prAgpsInfo->ePhyType = AGPS_PHY_G;
  2682. prAgpsInfo->u2Channel = prBssDesc->ucChannelNum;
  2683. prAgpsInfo->i2ApRssi = RCPI_TO_dBm(prBssDesc->ucRCPI);
  2684. prAgpsInfo++;
  2685. ucIndex++;
  2686. if (ucIndex == 32)
  2687. break;
  2688. }
  2689. prAgpsApList->ucNum = ucIndex;
  2690. GET_CURRENT_SYSTIME(&prScanInfo->rLastScanCompletedTime);
  2691. /* DBGLOG(SCN, INFO, ("num of scan list:%d\n", ucIndex)); */
  2692. kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_AP_LIST, (PUINT_8) prAgpsApList, sizeof(AGPS_AP_LIST_T));
  2693. kalMemFree(prAgpsApList, VIR_MEM_TYPE, sizeof(AGPS_AP_LIST_T));
  2694. }
  2695. #endif