rtw_mlme.c 137 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of version 2 of the GNU General Public License as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along with
  15. * this program; if not, write to the Free Software Foundation, Inc.,
  16. * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  17. *
  18. *
  19. ******************************************************************************/
  20. #define _RTW_MLME_C_
  21. #include <hal_data.h>
  22. extern void indicate_wx_scan_complete_event(_adapter *padapter);
  23. extern u8 rtw_do_join(_adapter *padapter);
  24. void rtw_init_mlme_timer(_adapter *padapter)
  25. {
  26. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  27. rtw_init_timer(&(pmlmepriv->assoc_timer), padapter, rtw_join_timeout_handler);
  28. rtw_init_timer(&(pmlmepriv->scan_to_timer), padapter, rtw_scan_timeout_handler);
  29. #ifdef CONFIG_DFS_MASTER
  30. rtw_init_timer(&(pmlmepriv->dfs_master_timer), padapter, rtw_dfs_master_timer_hdl, padapter);
  31. #endif
  32. #ifdef CONFIG_SET_SCAN_DENY_TIMER
  33. rtw_init_timer(&(pmlmepriv->set_scan_deny_timer), padapter, rtw_set_scan_deny_timer_hdl);
  34. #endif
  35. #ifdef RTK_DMP_PLATFORM
  36. _init_workitem(&(pmlmepriv->Linkup_workitem), Linkup_workitem_callback, padapter);
  37. _init_workitem(&(pmlmepriv->Linkdown_workitem), Linkdown_workitem_callback, padapter);
  38. #endif
  39. }
  40. sint _rtw_init_mlme_priv(_adapter *padapter)
  41. {
  42. sint i;
  43. u8 *pbuf;
  44. struct wlan_network *pnetwork;
  45. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  46. sint res = _SUCCESS;
  47. /* We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). */
  48. /* _rtw_memset((u8 *)pmlmepriv, 0, sizeof(struct mlme_priv)); */
  49. /*qos_priv*/
  50. /*pmlmepriv->qospriv.qos_option = pregistrypriv->wmm_enable;*/
  51. /*ht_priv*/
  52. #ifdef CONFIG_80211N_HT
  53. pmlmepriv->htpriv.ampdu_enable = _FALSE;/*set to disabled*/
  54. #endif
  55. pmlmepriv->nic_hdl = (u8 *)padapter;
  56. pmlmepriv->pscanned = NULL;
  57. /*pmlmepriv->fw_state = WIFI_STATION_STATE; */ /*Must sync with rtw_wdev_alloc()*/
  58. /*init_fwstate(pmlmepriv, WIFI_STATION_STATE);*/
  59. init_fwstate(pmlmepriv, WIFI_NULL_STATE);/*assigned interface role(STA/AP) must after execute set_opmode*/
  60. /* wdev->iftype = NL80211_IFTYPE_STATION*/
  61. pmlmepriv->cur_network.network.InfrastructureMode = Ndis802_11AutoUnknown;
  62. pmlmepriv->scan_mode = SCAN_ACTIVE; /* 1: active, 0: pasive. Maybe someday we should rename this varable to "active_mode" (Jeff) */
  63. _rtw_spinlock_init(&(pmlmepriv->lock));
  64. _rtw_init_queue(&(pmlmepriv->free_bss_pool));
  65. _rtw_init_queue(&(pmlmepriv->scanned_queue));
  66. set_scanned_network_val(pmlmepriv, 0);
  67. _rtw_memset(&pmlmepriv->assoc_ssid, 0, sizeof(NDIS_802_11_SSID));
  68. pbuf = rtw_zvmalloc(MAX_BSS_CNT * (sizeof(struct wlan_network)));
  69. if (pbuf == NULL) {
  70. res = _FAIL;
  71. goto exit;
  72. }
  73. pmlmepriv->free_bss_buf = pbuf;
  74. pnetwork = (struct wlan_network *)pbuf;
  75. for (i = 0; i < MAX_BSS_CNT; i++) {
  76. _rtw_init_listhead(&(pnetwork->list));
  77. rtw_list_insert_tail(&(pnetwork->list), &(pmlmepriv->free_bss_pool.queue));
  78. pnetwork++;
  79. }
  80. /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
  81. rtw_clear_scan_deny(padapter);
  82. #ifdef CONFIG_ARP_KEEP_ALIVE
  83. pmlmepriv->bGetGateway = 0;
  84. pmlmepriv->GetGatewayTryCnt = 0;
  85. #endif
  86. #ifdef CONFIG_LAYER2_ROAMING
  87. #define RTW_ROAM_SCAN_RESULT_EXP_MS (5*1000)
  88. #define RTW_ROAM_RSSI_DIFF_TH 10
  89. #define RTW_ROAM_SCAN_INTERVAL_MS (10*1000)
  90. #define RTW_ROAM_RSSI_THRESHOLD 70
  91. pmlmepriv->roam_flags = 0
  92. | RTW_ROAM_ON_EXPIRED
  93. #ifdef CONFIG_LAYER2_ROAMING_RESUME
  94. | RTW_ROAM_ON_RESUME
  95. #endif
  96. #ifdef CONFIG_LAYER2_ROAMING_ACTIVE
  97. | RTW_ROAM_ACTIVE
  98. #endif
  99. ;
  100. pmlmepriv->roam_scanr_exp_ms = RTW_ROAM_SCAN_RESULT_EXP_MS;
  101. pmlmepriv->roam_rssi_diff_th = RTW_ROAM_RSSI_DIFF_TH;
  102. pmlmepriv->roam_scan_int_ms = RTW_ROAM_SCAN_INTERVAL_MS;
  103. pmlmepriv->roam_rssi_threshold = RTW_ROAM_RSSI_THRESHOLD;
  104. #endif /* CONFIG_LAYER2_ROAMING */
  105. #ifdef CONFIG_RTW_80211R
  106. memset(&pmlmepriv->ftpriv, 0, sizeof(ft_priv));
  107. pmlmepriv->ftpriv.ft_flags = 0
  108. | RTW_FT_STA_SUPPORTED
  109. | RTW_FT_STA_OVER_DS_SUPPORTED
  110. ;
  111. #endif
  112. rtw_init_mlme_timer(padapter);
  113. exit:
  114. return res;
  115. }
  116. void rtw_mfree_mlme_priv_lock(struct mlme_priv *pmlmepriv);
  117. void rtw_mfree_mlme_priv_lock(struct mlme_priv *pmlmepriv)
  118. {
  119. _rtw_spinlock_free(&pmlmepriv->lock);
  120. _rtw_spinlock_free(&(pmlmepriv->free_bss_pool.lock));
  121. _rtw_spinlock_free(&(pmlmepriv->scanned_queue.lock));
  122. }
  123. static void rtw_free_mlme_ie_data(u8 **ppie, u32 *plen)
  124. {
  125. if (*ppie) {
  126. rtw_mfree(*ppie, *plen);
  127. *plen = 0;
  128. *ppie = NULL;
  129. }
  130. }
  131. void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv)
  132. {
  133. #if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
  134. rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
  135. rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
  136. rtw_free_mlme_ie_data(&pmlmepriv->wps_beacon_ie, &pmlmepriv->wps_beacon_ie_len);
  137. rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_req_ie, &pmlmepriv->wps_probe_req_ie_len);
  138. rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_resp_ie, &pmlmepriv->wps_probe_resp_ie_len);
  139. rtw_free_mlme_ie_data(&pmlmepriv->wps_assoc_resp_ie, &pmlmepriv->wps_assoc_resp_ie_len);
  140. rtw_free_mlme_ie_data(&pmlmepriv->p2p_beacon_ie, &pmlmepriv->p2p_beacon_ie_len);
  141. rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_req_ie, &pmlmepriv->p2p_probe_req_ie_len);
  142. rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_resp_ie, &pmlmepriv->p2p_probe_resp_ie_len);
  143. rtw_free_mlme_ie_data(&pmlmepriv->p2p_go_probe_resp_ie, &pmlmepriv->p2p_go_probe_resp_ie_len);
  144. rtw_free_mlme_ie_data(&pmlmepriv->p2p_assoc_req_ie, &pmlmepriv->p2p_assoc_req_ie_len);
  145. rtw_free_mlme_ie_data(&pmlmepriv->p2p_assoc_resp_ie, &pmlmepriv->p2p_assoc_resp_ie_len);
  146. #endif
  147. #if defined(CONFIG_WFD) && defined(CONFIG_IOCTL_CFG80211)
  148. rtw_free_mlme_ie_data(&pmlmepriv->wfd_beacon_ie, &pmlmepriv->wfd_beacon_ie_len);
  149. rtw_free_mlme_ie_data(&pmlmepriv->wfd_probe_req_ie, &pmlmepriv->wfd_probe_req_ie_len);
  150. rtw_free_mlme_ie_data(&pmlmepriv->wfd_probe_resp_ie, &pmlmepriv->wfd_probe_resp_ie_len);
  151. rtw_free_mlme_ie_data(&pmlmepriv->wfd_go_probe_resp_ie, &pmlmepriv->wfd_go_probe_resp_ie_len);
  152. rtw_free_mlme_ie_data(&pmlmepriv->wfd_assoc_req_ie, &pmlmepriv->wfd_assoc_req_ie_len);
  153. rtw_free_mlme_ie_data(&pmlmepriv->wfd_assoc_resp_ie, &pmlmepriv->wfd_assoc_resp_ie_len);
  154. #endif
  155. #ifdef CONFIG_RTW_80211R
  156. rtw_free_mlme_ie_data(&pmlmepriv->auth_rsp, &pmlmepriv->auth_rsp_len);
  157. #endif
  158. }
  159. #if defined(CONFIG_WFD) && defined(CONFIG_IOCTL_CFG80211)
  160. int rtw_mlme_update_wfd_ie_data(struct mlme_priv *mlme, u8 type, u8 *ie, u32 ie_len)
  161. {
  162. _adapter *adapter = mlme_to_adapter(mlme);
  163. struct wifi_display_info *wfd_info = &adapter->wfd_info;
  164. u8 clear = 0;
  165. u8 **t_ie = NULL;
  166. u32 *t_ie_len = NULL;
  167. int ret = _FAIL;
  168. if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST))
  169. goto success;
  170. if (wfd_info->wfd_enable == _TRUE)
  171. goto success; /* WFD IE is build by self */
  172. if (!ie && !ie_len)
  173. clear = 1;
  174. else if (!ie || !ie_len) {
  175. RTW_PRINT(FUNC_ADPT_FMT" type:%u, ie:%p, ie_len:%u"
  176. , FUNC_ADPT_ARG(adapter), type, ie, ie_len);
  177. rtw_warn_on(1);
  178. goto exit;
  179. }
  180. switch (type) {
  181. case MLME_BEACON_IE:
  182. t_ie = &mlme->wfd_beacon_ie;
  183. t_ie_len = &mlme->wfd_beacon_ie_len;
  184. break;
  185. case MLME_PROBE_REQ_IE:
  186. t_ie = &mlme->wfd_probe_req_ie;
  187. t_ie_len = &mlme->wfd_probe_req_ie_len;
  188. break;
  189. case MLME_PROBE_RESP_IE:
  190. t_ie = &mlme->wfd_probe_resp_ie;
  191. t_ie_len = &mlme->wfd_probe_resp_ie_len;
  192. break;
  193. case MLME_GO_PROBE_RESP_IE:
  194. t_ie = &mlme->wfd_go_probe_resp_ie;
  195. t_ie_len = &mlme->wfd_go_probe_resp_ie_len;
  196. break;
  197. case MLME_ASSOC_REQ_IE:
  198. t_ie = &mlme->wfd_assoc_req_ie;
  199. t_ie_len = &mlme->wfd_assoc_req_ie_len;
  200. break;
  201. case MLME_ASSOC_RESP_IE:
  202. t_ie = &mlme->wfd_assoc_resp_ie;
  203. t_ie_len = &mlme->wfd_assoc_resp_ie_len;
  204. break;
  205. default:
  206. RTW_PRINT(FUNC_ADPT_FMT" unsupported type:%u"
  207. , FUNC_ADPT_ARG(adapter), type);
  208. rtw_warn_on(1);
  209. goto exit;
  210. }
  211. if (*t_ie) {
  212. u32 free_len = *t_ie_len;
  213. *t_ie_len = 0;
  214. rtw_mfree(*t_ie, free_len);
  215. *t_ie = NULL;
  216. }
  217. if (!clear) {
  218. *t_ie = rtw_malloc(ie_len);
  219. if (*t_ie == NULL) {
  220. RTW_ERR(FUNC_ADPT_FMT" type:%u, rtw_malloc() fail\n"
  221. , FUNC_ADPT_ARG(adapter), type);
  222. goto exit;
  223. }
  224. _rtw_memcpy(*t_ie, ie, ie_len);
  225. *t_ie_len = ie_len;
  226. }
  227. if (*t_ie && *t_ie_len) {
  228. u8 *attr_content;
  229. u32 attr_contentlen = 0;
  230. attr_content = rtw_get_wfd_attr_content(*t_ie, *t_ie_len, WFD_ATTR_DEVICE_INFO, NULL, &attr_contentlen);
  231. if (attr_content && attr_contentlen) {
  232. if (RTW_GET_BE16(attr_content + 2) != wfd_info->rtsp_ctrlport) {
  233. wfd_info->rtsp_ctrlport = RTW_GET_BE16(attr_content + 2);
  234. RTW_INFO(FUNC_ADPT_FMT" type:%u, RTSP CTRL port = %u\n"
  235. , FUNC_ADPT_ARG(adapter), type, wfd_info->rtsp_ctrlport);
  236. }
  237. }
  238. }
  239. success:
  240. ret = _SUCCESS;
  241. exit:
  242. return ret;
  243. }
  244. #endif /* defined(CONFIG_WFD) && defined(CONFIG_IOCTL_CFG80211) */
  245. void _rtw_free_mlme_priv(struct mlme_priv *pmlmepriv)
  246. {
  247. if (NULL == pmlmepriv) {
  248. rtw_warn_on(1);
  249. goto exit;
  250. }
  251. rtw_free_mlme_priv_ie_data(pmlmepriv);
  252. if (pmlmepriv) {
  253. rtw_mfree_mlme_priv_lock(pmlmepriv);
  254. if (pmlmepriv->free_bss_buf)
  255. rtw_vmfree(pmlmepriv->free_bss_buf, MAX_BSS_CNT * sizeof(struct wlan_network));
  256. }
  257. exit:
  258. return;
  259. }
  260. sint _rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork)
  261. {
  262. _irqL irqL;
  263. if (pnetwork == NULL)
  264. goto exit;
  265. _enter_critical_bh(&queue->lock, &irqL);
  266. rtw_list_insert_tail(&pnetwork->list, &queue->queue);
  267. _exit_critical_bh(&queue->lock, &irqL);
  268. exit:
  269. return _SUCCESS;
  270. }
  271. /*
  272. struct wlan_network *_rtw_dequeue_network(_queue *queue)
  273. {
  274. _irqL irqL;
  275. struct wlan_network *pnetwork;
  276. _enter_critical_bh(&queue->lock, &irqL);
  277. if (_rtw_queue_empty(queue) == _TRUE)
  278. pnetwork = NULL;
  279. else
  280. {
  281. pnetwork = LIST_CONTAINOR(get_next(&queue->queue), struct wlan_network, list);
  282. rtw_list_delete(&(pnetwork->list));
  283. }
  284. _exit_critical_bh(&queue->lock, &irqL);
  285. return pnetwork;
  286. }
  287. */
  288. struct wlan_network *_rtw_alloc_network(struct mlme_priv *pmlmepriv) /* (_queue *free_queue) */
  289. {
  290. _irqL irqL;
  291. struct wlan_network *pnetwork;
  292. _queue *free_queue = &pmlmepriv->free_bss_pool;
  293. _list *plist = NULL;
  294. _enter_critical_bh(&free_queue->lock, &irqL);
  295. if (_rtw_queue_empty(free_queue) == _TRUE) {
  296. pnetwork = NULL;
  297. goto exit;
  298. }
  299. plist = get_next(&(free_queue->queue));
  300. pnetwork = LIST_CONTAINOR(plist , struct wlan_network, list);
  301. rtw_list_delete(&pnetwork->list);
  302. pnetwork->network_type = 0;
  303. pnetwork->fixed = _FALSE;
  304. pnetwork->last_scanned = rtw_get_current_time();
  305. pnetwork->aid = 0;
  306. pnetwork->join_res = 0;
  307. pmlmepriv->num_of_scanned++;
  308. exit:
  309. _exit_critical_bh(&free_queue->lock, &irqL);
  310. return pnetwork;
  311. }
  312. void _rtw_free_network(struct mlme_priv *pmlmepriv , struct wlan_network *pnetwork, u8 isfreeall)
  313. {
  314. u32 delta_time;
  315. u32 lifetime = SCANQUEUE_LIFETIME;
  316. _irqL irqL;
  317. _queue *free_queue = &(pmlmepriv->free_bss_pool);
  318. if (pnetwork == NULL)
  319. goto exit;
  320. if (pnetwork->fixed == _TRUE)
  321. goto exit;
  322. if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) ||
  323. (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE))
  324. lifetime = 1;
  325. if (!isfreeall) {
  326. delta_time = (u32) rtw_get_passing_time_ms(pnetwork->last_scanned);
  327. if (delta_time < lifetime) /* unit:msec */
  328. goto exit;
  329. }
  330. _enter_critical_bh(&free_queue->lock, &irqL);
  331. rtw_list_delete(&(pnetwork->list));
  332. rtw_list_insert_tail(&(pnetwork->list), &(free_queue->queue));
  333. pmlmepriv->num_of_scanned--;
  334. /* RTW_INFO("_rtw_free_network:SSID=%s\n", pnetwork->network.Ssid.Ssid); */
  335. _exit_critical_bh(&free_queue->lock, &irqL);
  336. exit:
  337. return;
  338. }
  339. void _rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork)
  340. {
  341. _queue *free_queue = &(pmlmepriv->free_bss_pool);
  342. if (pnetwork == NULL)
  343. goto exit;
  344. if (pnetwork->fixed == _TRUE)
  345. goto exit;
  346. /* _enter_critical(&free_queue->lock, &irqL); */
  347. rtw_list_delete(&(pnetwork->list));
  348. rtw_list_insert_tail(&(pnetwork->list), get_list_head(free_queue));
  349. pmlmepriv->num_of_scanned--;
  350. /* _exit_critical(&free_queue->lock, &irqL); */
  351. exit:
  352. return;
  353. }
  354. /*
  355. return the wlan_network with the matching addr
  356. Shall be calle under atomic context... to avoid possible racing condition...
  357. */
  358. struct wlan_network *_rtw_find_network(_queue *scanned_queue, u8 *addr)
  359. {
  360. /* _irqL irqL; */
  361. _list *phead, *plist;
  362. struct wlan_network *pnetwork = NULL;
  363. u8 zero_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
  364. if (_rtw_memcmp(zero_addr, addr, ETH_ALEN)) {
  365. pnetwork = NULL;
  366. goto exit;
  367. }
  368. /* _enter_critical_bh(&scanned_queue->lock, &irqL); */
  369. phead = get_list_head(scanned_queue);
  370. plist = get_next(phead);
  371. while (plist != phead) {
  372. pnetwork = LIST_CONTAINOR(plist, struct wlan_network , list);
  373. if (_rtw_memcmp(addr, pnetwork->network.MacAddress, ETH_ALEN) == _TRUE)
  374. break;
  375. plist = get_next(plist);
  376. }
  377. if (plist == phead)
  378. pnetwork = NULL;
  379. /* _exit_critical_bh(&scanned_queue->lock, &irqL); */
  380. exit:
  381. return pnetwork;
  382. }
  383. void _rtw_free_network_queue(_adapter *padapter, u8 isfreeall)
  384. {
  385. _irqL irqL;
  386. _list *phead, *plist;
  387. struct wlan_network *pnetwork;
  388. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  389. _queue *scanned_queue = &pmlmepriv->scanned_queue;
  390. _enter_critical_bh(&scanned_queue->lock, &irqL);
  391. phead = get_list_head(scanned_queue);
  392. plist = get_next(phead);
  393. while (rtw_end_of_queue_search(phead, plist) == _FALSE) {
  394. pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
  395. plist = get_next(plist);
  396. _rtw_free_network(pmlmepriv, pnetwork, isfreeall);
  397. }
  398. _exit_critical_bh(&scanned_queue->lock, &irqL);
  399. }
  400. sint rtw_if_up(_adapter *padapter)
  401. {
  402. sint res;
  403. if (RTW_CANNOT_RUN(padapter) ||
  404. (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == _FALSE)) {
  405. res = _FALSE;
  406. } else
  407. res = _TRUE;
  408. return res;
  409. }
  410. void rtw_generate_random_ibss(u8 *pibss)
  411. {
  412. *((u32 *)(&pibss[2])) = rtw_random32();
  413. pibss[0] = 0x02; /* in ad-hoc mode local bit must set to 1 */
  414. pibss[1] = 0x11;
  415. pibss[2] = 0x87;
  416. }
  417. u8 *rtw_get_capability_from_ie(u8 *ie)
  418. {
  419. return ie + 8 + 2;
  420. }
  421. u16 rtw_get_capability(WLAN_BSSID_EX *bss)
  422. {
  423. u16 val;
  424. _rtw_memcpy((u8 *)&val, rtw_get_capability_from_ie(bss->IEs), 2);
  425. return le16_to_cpu(val);
  426. }
  427. u8 *rtw_get_timestampe_from_ie(u8 *ie)
  428. {
  429. return ie + 0;
  430. }
  431. u8 *rtw_get_beacon_interval_from_ie(u8 *ie)
  432. {
  433. return ie + 8;
  434. }
  435. int rtw_init_mlme_priv(_adapter *padapter) /* (struct mlme_priv *pmlmepriv) */
  436. {
  437. int res;
  438. res = _rtw_init_mlme_priv(padapter);/* (pmlmepriv); */
  439. return res;
  440. }
  441. void rtw_free_mlme_priv(struct mlme_priv *pmlmepriv)
  442. {
  443. _rtw_free_mlme_priv(pmlmepriv);
  444. }
  445. int rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork);
  446. int rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork)
  447. {
  448. int res;
  449. res = _rtw_enqueue_network(queue, pnetwork);
  450. return res;
  451. }
  452. /*
  453. static struct wlan_network *rtw_dequeue_network(_queue *queue)
  454. {
  455. struct wlan_network *pnetwork;
  456. pnetwork = _rtw_dequeue_network(queue);
  457. return pnetwork;
  458. }
  459. */
  460. struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv);
  461. struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv) /* (_queue *free_queue) */
  462. {
  463. struct wlan_network *pnetwork;
  464. pnetwork = _rtw_alloc_network(pmlmepriv);
  465. return pnetwork;
  466. }
  467. void rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork, u8 is_freeall);
  468. void rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork, u8 is_freeall)/* (struct wlan_network *pnetwork, _queue *free_queue) */
  469. {
  470. _rtw_free_network(pmlmepriv, pnetwork, is_freeall);
  471. }
  472. void rtw_free_network_nolock(_adapter *padapter, struct wlan_network *pnetwork);
  473. void rtw_free_network_nolock(_adapter *padapter, struct wlan_network *pnetwork)
  474. {
  475. _rtw_free_network_nolock(&(padapter->mlmepriv), pnetwork);
  476. #ifdef CONFIG_IOCTL_CFG80211
  477. rtw_cfg80211_unlink_bss(padapter, pnetwork);
  478. #endif /* CONFIG_IOCTL_CFG80211 */
  479. }
  480. void rtw_free_network_queue(_adapter *dev, u8 isfreeall)
  481. {
  482. _rtw_free_network_queue(dev, isfreeall);
  483. }
  484. /*
  485. return the wlan_network with the matching addr
  486. Shall be calle under atomic context... to avoid possible racing condition...
  487. */
  488. struct wlan_network *rtw_find_network(_queue *scanned_queue, u8 *addr)
  489. {
  490. struct wlan_network *pnetwork = _rtw_find_network(scanned_queue, addr);
  491. return pnetwork;
  492. }
  493. int rtw_is_same_ibss(_adapter *adapter, struct wlan_network *pnetwork)
  494. {
  495. int ret = _TRUE;
  496. struct security_priv *psecuritypriv = &adapter->securitypriv;
  497. if ((psecuritypriv->dot11PrivacyAlgrthm != _NO_PRIVACY_) &&
  498. (pnetwork->network.Privacy == 0))
  499. ret = _FALSE;
  500. else if ((psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_) &&
  501. (pnetwork->network.Privacy == 1))
  502. ret = _FALSE;
  503. else
  504. ret = _TRUE;
  505. return ret;
  506. }
  507. inline int is_same_ess(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b)
  508. {
  509. return (a->Ssid.SsidLength == b->Ssid.SsidLength)
  510. && _rtw_memcmp(a->Ssid.Ssid, b->Ssid.Ssid, a->Ssid.SsidLength) == _TRUE;
  511. }
  512. int is_same_network(WLAN_BSSID_EX *src, WLAN_BSSID_EX *dst, u8 feature)
  513. {
  514. u16 s_cap, d_cap;
  515. if (rtw_bug_check(dst, src, &s_cap, &d_cap) == _FALSE)
  516. return _FALSE;
  517. _rtw_memcpy((u8 *)&s_cap, rtw_get_capability_from_ie(src->IEs), 2);
  518. _rtw_memcpy((u8 *)&d_cap, rtw_get_capability_from_ie(dst->IEs), 2);
  519. s_cap = le16_to_cpu(s_cap);
  520. d_cap = le16_to_cpu(d_cap);
  521. #ifdef CONFIG_P2P
  522. if ((feature == 1) && /* 1: P2P supported */
  523. (_rtw_memcmp(src->MacAddress, dst->MacAddress, ETH_ALEN) == _TRUE)
  524. )
  525. return _TRUE;
  526. #endif
  527. return ((src->Ssid.SsidLength == dst->Ssid.SsidLength) &&
  528. /* (src->Configuration.DSConfig == dst->Configuration.DSConfig) && */
  529. ((_rtw_memcmp(src->MacAddress, dst->MacAddress, ETH_ALEN)) == _TRUE) &&
  530. ((_rtw_memcmp(src->Ssid.Ssid, dst->Ssid.Ssid, src->Ssid.SsidLength)) == _TRUE) &&
  531. ((s_cap & WLAN_CAPABILITY_IBSS) ==
  532. (d_cap & WLAN_CAPABILITY_IBSS)) &&
  533. ((s_cap & WLAN_CAPABILITY_BSS) ==
  534. (d_cap & WLAN_CAPABILITY_BSS)));
  535. }
  536. struct wlan_network *_rtw_find_same_network(_queue *scanned_queue, struct wlan_network *network)
  537. {
  538. _list *phead, *plist;
  539. struct wlan_network *found = NULL;
  540. phead = get_list_head(scanned_queue);
  541. plist = get_next(phead);
  542. while (plist != phead) {
  543. found = LIST_CONTAINOR(plist, struct wlan_network , list);
  544. if (is_same_network(&network->network, &found->network, 0))
  545. break;
  546. plist = get_next(plist);
  547. }
  548. if (plist == phead)
  549. found = NULL;
  550. exit:
  551. return found;
  552. }
  553. struct wlan_network *rtw_find_same_network(_queue *scanned_queue, struct wlan_network *network)
  554. {
  555. _irqL irqL;
  556. struct wlan_network *found = NULL;
  557. if (scanned_queue == NULL || network == NULL)
  558. goto exit;
  559. _enter_critical_bh(&scanned_queue->lock, &irqL);
  560. found = _rtw_find_same_network(scanned_queue, network);
  561. _exit_critical_bh(&scanned_queue->lock, &irqL);
  562. exit:
  563. return found;
  564. }
  565. struct wlan_network *rtw_get_oldest_wlan_network(_queue *scanned_queue)
  566. {
  567. _list *plist, *phead;
  568. struct wlan_network *pwlan = NULL;
  569. struct wlan_network *oldest = NULL;
  570. phead = get_list_head(scanned_queue);
  571. plist = get_next(phead);
  572. while (1) {
  573. if (rtw_end_of_queue_search(phead, plist) == _TRUE)
  574. break;
  575. pwlan = LIST_CONTAINOR(plist, struct wlan_network, list);
  576. if (pwlan->fixed != _TRUE) {
  577. if (oldest == NULL || time_after(oldest->last_scanned, pwlan->last_scanned))
  578. oldest = pwlan;
  579. }
  580. plist = get_next(plist);
  581. }
  582. return oldest;
  583. }
  584. void update_network(WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src,
  585. _adapter *padapter, bool update_ie)
  586. {
  587. u8 ss_ori = dst->PhyInfo.SignalStrength;
  588. u8 sq_ori = dst->PhyInfo.SignalQuality;
  589. long rssi_ori = dst->Rssi;
  590. u8 ss_smp = src->PhyInfo.SignalStrength;
  591. u8 sq_smp = src->PhyInfo.SignalQuality;
  592. long rssi_smp = src->Rssi;
  593. u8 ss_final;
  594. u8 sq_final;
  595. long rssi_final;
  596. #ifdef CONFIG_ANTENNA_DIVERSITY
  597. rtw_hal_antdiv_rssi_compared(padapter, dst, src); /* this will update src.Rssi, need consider again */
  598. #endif
  599. #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) && 1
  600. if (strcmp(dst->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
  601. RTW_INFO(FUNC_ADPT_FMT" %s("MAC_FMT", ch%u) ss_ori:%3u, sq_ori:%3u, rssi_ori:%3ld, ss_smp:%3u, sq_smp:%3u, rssi_smp:%3ld\n"
  602. , FUNC_ADPT_ARG(padapter)
  603. , src->Ssid.Ssid, MAC_ARG(src->MacAddress), src->Configuration.DSConfig
  604. , ss_ori, sq_ori, rssi_ori
  605. , ss_smp, sq_smp, rssi_smp
  606. );
  607. }
  608. #endif
  609. /* The rule below is 1/5 for sample value, 4/5 for history value */
  610. if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&(padapter->mlmepriv.cur_network.network), src, 0)) {
  611. /* Take the recvpriv's value for the connected AP*/
  612. ss_final = padapter->recvpriv.signal_strength;
  613. sq_final = padapter->recvpriv.signal_qual;
  614. /* the rssi value here is undecorated, and will be used for antenna diversity */
  615. if (sq_smp != 101) /* from the right channel */
  616. rssi_final = (src->Rssi + dst->Rssi * 4) / 5;
  617. else
  618. rssi_final = rssi_ori;
  619. } else {
  620. if (sq_smp != 101) { /* from the right channel */
  621. ss_final = ((u32)(src->PhyInfo.SignalStrength) + (u32)(dst->PhyInfo.SignalStrength) * 4) / 5;
  622. sq_final = ((u32)(src->PhyInfo.SignalQuality) + (u32)(dst->PhyInfo.SignalQuality) * 4) / 5;
  623. rssi_final = (src->Rssi + dst->Rssi * 4) / 5;
  624. } else {
  625. /* bss info not receving from the right channel, use the original RX signal infos */
  626. ss_final = dst->PhyInfo.SignalStrength;
  627. sq_final = dst->PhyInfo.SignalQuality;
  628. rssi_final = dst->Rssi;
  629. }
  630. }
  631. if (update_ie) {
  632. dst->Reserved[0] = src->Reserved[0];
  633. dst->Reserved[1] = src->Reserved[1];
  634. _rtw_memcpy((u8 *)dst, (u8 *)src, get_WLAN_BSSID_EX_sz(src));
  635. }
  636. dst->PhyInfo.SignalStrength = ss_final;
  637. dst->PhyInfo.SignalQuality = sq_final;
  638. dst->Rssi = rssi_final;
  639. #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) && 1
  640. if (strcmp(dst->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
  641. RTW_INFO(FUNC_ADPT_FMT" %s("MAC_FMT"), SignalStrength:%u, SignalQuality:%u, RawRSSI:%ld\n"
  642. , FUNC_ADPT_ARG(padapter)
  643. , dst->Ssid.Ssid, MAC_ARG(dst->MacAddress), dst->PhyInfo.SignalStrength, dst->PhyInfo.SignalQuality, dst->Rssi);
  644. }
  645. #endif
  646. #if 0 /* old codes, may be useful one day...
  647. * RTW_INFO("update_network: rssi=0x%lx dst->Rssi=%d ,dst->Rssi=0x%lx , src->Rssi=0x%lx",(dst->Rssi+src->Rssi)/2,dst->Rssi,dst->Rssi,src->Rssi); */
  648. if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&(padapter->mlmepriv.cur_network.network), src)) {
  649. /* RTW_INFO("b:ssid=%s update_network: src->rssi=0x%d padapter->recvpriv.ui_rssi=%d\n",src->Ssid.Ssid,src->Rssi,padapter->recvpriv.signal); */
  650. if (padapter->recvpriv.signal_qual_data.total_num++ >= PHY_LINKQUALITY_SLID_WIN_MAX) {
  651. padapter->recvpriv.signal_qual_data.total_num = PHY_LINKQUALITY_SLID_WIN_MAX;
  652. last_evm = padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index];
  653. padapter->recvpriv.signal_qual_data.total_val -= last_evm;
  654. }
  655. padapter->recvpriv.signal_qual_data.total_val += query_rx_pwr_percentage(src->Rssi);
  656. padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index++] = query_rx_pwr_percentage(src->Rssi);
  657. if (padapter->recvpriv.signal_qual_data.index >= PHY_LINKQUALITY_SLID_WIN_MAX)
  658. padapter->recvpriv.signal_qual_data.index = 0;
  659. /* RTW_INFO("Total SQ=%d pattrib->signal_qual= %d\n", padapter->recvpriv.signal_qual_data.total_val, src->Rssi); */
  660. /* <1> Showed on UI for user,in percentage. */
  661. tmpVal = padapter->recvpriv.signal_qual_data.total_val / padapter->recvpriv.signal_qual_data.total_num;
  662. padapter->recvpriv.signal = (u8)tmpVal; /* Link quality */
  663. src->Rssi = translate_percentage_to_dbm(padapter->recvpriv.signal) ;
  664. } else {
  665. /* RTW_INFO("ELSE:ssid=%s update_network: src->rssi=0x%d dst->rssi=%d\n",src->Ssid.Ssid,src->Rssi,dst->Rssi); */
  666. src->Rssi = (src->Rssi + dst->Rssi) / 2; /* dBM */
  667. }
  668. /* RTW_INFO("a:update_network: src->rssi=0x%d padapter->recvpriv.ui_rssi=%d\n",src->Rssi,padapter->recvpriv.signal); */
  669. #endif
  670. }
  671. static void update_current_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork)
  672. {
  673. struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
  674. rtw_bug_check(&(pmlmepriv->cur_network.network),
  675. &(pmlmepriv->cur_network.network),
  676. &(pmlmepriv->cur_network.network),
  677. &(pmlmepriv->cur_network.network));
  678. if ((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) && (is_same_network(&(pmlmepriv->cur_network.network), pnetwork, 0))) {
  679. /* if(pmlmepriv->cur_network.network.IELength<= pnetwork->IELength) */
  680. {
  681. update_network(&(pmlmepriv->cur_network.network), pnetwork, adapter, _TRUE);
  682. rtw_update_protection(adapter, (pmlmepriv->cur_network.network.IEs) + sizeof(NDIS_802_11_FIXED_IEs),
  683. pmlmepriv->cur_network.network.IELength);
  684. }
  685. }
  686. }
  687. /*
  688. Caller must hold pmlmepriv->lock first.
  689. */
  690. void rtw_update_scanned_network(_adapter *adapter, WLAN_BSSID_EX *target)
  691. {
  692. _irqL irqL;
  693. _list *plist, *phead;
  694. ULONG bssid_ex_sz;
  695. struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
  696. struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
  697. #ifdef CONFIG_P2P
  698. struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
  699. #endif /* CONFIG_P2P */
  700. _queue *queue = &(pmlmepriv->scanned_queue);
  701. struct wlan_network *pnetwork = NULL;
  702. struct wlan_network *oldest = NULL;
  703. int target_find = 0;
  704. u8 feature = 0;
  705. _enter_critical_bh(&queue->lock, &irqL);
  706. phead = get_list_head(queue);
  707. plist = get_next(phead);
  708. #if 0
  709. RTW_INFO("%s => ssid:%s , rssi:%ld , ss:%d\n",
  710. __func__, target->Ssid.Ssid, target->Rssi, target->PhyInfo.SignalStrength);
  711. #endif
  712. #ifdef CONFIG_P2P
  713. if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
  714. feature = 1; /* p2p enable */
  715. #endif
  716. while (1) {
  717. if (rtw_end_of_queue_search(phead, plist) == _TRUE)
  718. break;
  719. pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
  720. rtw_bug_check(pnetwork, pnetwork, pnetwork, pnetwork);
  721. #ifdef CONFIG_P2P
  722. if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
  723. (_rtw_memcmp(pnetwork->network.MacAddress, target->MacAddress, ETH_ALEN) == _TRUE)) {
  724. target_find = 1;
  725. break;
  726. }
  727. #endif
  728. if (is_same_network(&(pnetwork->network), target, feature)) {
  729. target_find = 1;
  730. break;
  731. }
  732. if (rtw_roam_flags(adapter)) {
  733. /* TODO: don't select netowrk in the same ess as oldest if it's new enough*/
  734. }
  735. #ifdef CONFIG_RSSI_PRIORITY
  736. if ((oldest == NULL) || (pnetwork->network.PhyInfo.SignalStrength < oldest->network.PhyInfo.SignalStrength))
  737. oldest = pnetwork;
  738. #else
  739. if (oldest == NULL || time_after(oldest->last_scanned, pnetwork->last_scanned))
  740. oldest = pnetwork;
  741. #endif
  742. plist = get_next(plist);
  743. }
  744. /* If we didn't find a match, then get a new network slot to initialize
  745. * with this beacon's information */
  746. /* if (rtw_end_of_queue_search(phead,plist)== _TRUE) { */
  747. if (!target_find) {
  748. if (_rtw_queue_empty(&(pmlmepriv->free_bss_pool)) == _TRUE) {
  749. /* If there are no more slots, expire the oldest */
  750. /* list_del_init(&oldest->list); */
  751. pnetwork = oldest;
  752. if (pnetwork == NULL) {
  753. goto exit;
  754. }
  755. #ifdef CONFIG_RSSI_PRIORITY
  756. RTW_DBG("%s => ssid:%s ,bssid:"MAC_FMT" will be deleted from scanned_queue (rssi:%ld , ss:%d)\n",
  757. __func__, pnetwork->network.Ssid.Ssid, MAC_ARG(pnetwork->network.MacAddress), pnetwork->network.Rssi, pnetwork->network.PhyInfo.SignalStrength);
  758. #else
  759. RTW_DBG("%s => ssid:%s ,bssid:"MAC_FMT" will be deleted from scanned_queue\n",
  760. __func__, pnetwork->network.Ssid.Ssid, MAC_ARG(pnetwork->network.MacAddress));
  761. #endif
  762. #ifdef CONFIG_ANTENNA_DIVERSITY
  763. rtw_hal_get_odm_var(adapter, HAL_ODM_ANTDIV_SELECT, &(target->PhyInfo.Optimum_antenna), NULL);
  764. #endif
  765. _rtw_memcpy(&(pnetwork->network), target, get_WLAN_BSSID_EX_sz(target));
  766. /* pnetwork->last_scanned = rtw_get_current_time(); */
  767. /* variable initialize */
  768. pnetwork->fixed = _FALSE;
  769. pnetwork->last_scanned = rtw_get_current_time();
  770. pnetwork->network_type = 0;
  771. pnetwork->aid = 0;
  772. pnetwork->join_res = 0;
  773. /* bss info not receving from the right channel */
  774. if (pnetwork->network.PhyInfo.SignalQuality == 101)
  775. pnetwork->network.PhyInfo.SignalQuality = 0;
  776. } else {
  777. /* Otherwise just pull from the free list */
  778. pnetwork = rtw_alloc_network(pmlmepriv); /* will update scan_time */
  779. if (pnetwork == NULL) {
  780. goto exit;
  781. }
  782. bssid_ex_sz = get_WLAN_BSSID_EX_sz(target);
  783. target->Length = bssid_ex_sz;
  784. #ifdef CONFIG_ANTENNA_DIVERSITY
  785. rtw_hal_get_odm_var(adapter, HAL_ODM_ANTDIV_SELECT, &(target->PhyInfo.Optimum_antenna), NULL);
  786. #endif
  787. _rtw_memcpy(&(pnetwork->network), target, bssid_ex_sz);
  788. pnetwork->last_scanned = rtw_get_current_time();
  789. /* bss info not receving from the right channel */
  790. if (pnetwork->network.PhyInfo.SignalQuality == 101)
  791. pnetwork->network.PhyInfo.SignalQuality = 0;
  792. rtw_list_insert_tail(&(pnetwork->list), &(queue->queue));
  793. }
  794. } else {
  795. /* we have an entry and we are going to update it. But this entry may
  796. * be already expired. In this case we do the same as we found a new
  797. * net and call the new_net handler
  798. */
  799. bool update_ie = _TRUE;
  800. pnetwork->last_scanned = rtw_get_current_time();
  801. /* target.Reserved[0]==1, means that scaned network is a bcn frame. */
  802. if ((pnetwork->network.IELength > target->IELength) && (target->Reserved[0] == 1))
  803. update_ie = _FALSE;
  804. /* probe resp(3) > beacon(1) > probe req(2) */
  805. if ((target->Reserved[0] != 2) &&
  806. (target->Reserved[0] >= pnetwork->network.Reserved[0])
  807. )
  808. update_ie = _TRUE;
  809. else
  810. update_ie = _FALSE;
  811. update_network(&(pnetwork->network), target, adapter, update_ie);
  812. }
  813. exit:
  814. _exit_critical_bh(&queue->lock, &irqL);
  815. }
  816. void rtw_add_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork);
  817. void rtw_add_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork)
  818. {
  819. _irqL irqL;
  820. struct mlme_priv *pmlmepriv = &(((_adapter *)adapter)->mlmepriv);
  821. /* _queue *queue = &(pmlmepriv->scanned_queue); */
  822. /* _enter_critical_bh(&queue->lock, &irqL); */
  823. #if defined(CONFIG_P2P) && defined(CONFIG_P2P_REMOVE_GROUP_INFO)
  824. if (adapter->registrypriv.wifi_spec == 0)
  825. rtw_bss_ex_del_p2p_attr(pnetwork, P2P_ATTR_GROUP_INFO);
  826. #endif
  827. if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST))
  828. rtw_bss_ex_del_wfd_ie(pnetwork);
  829. update_current_network(adapter, pnetwork);
  830. rtw_update_scanned_network(adapter, pnetwork);
  831. /* _exit_critical_bh(&queue->lock, &irqL); */
  832. }
  833. /* select the desired network based on the capability of the (i)bss.
  834. * check items: (1) security
  835. * (2) network_type
  836. * (3) WMM
  837. * (4) HT
  838. * (5) others */
  839. int rtw_is_desired_network(_adapter *adapter, struct wlan_network *pnetwork);
  840. int rtw_is_desired_network(_adapter *adapter, struct wlan_network *pnetwork)
  841. {
  842. struct security_priv *psecuritypriv = &adapter->securitypriv;
  843. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  844. u32 desired_encmode;
  845. u32 privacy;
  846. /* u8 wps_ie[512]; */
  847. uint wps_ielen;
  848. int bselected = _TRUE;
  849. desired_encmode = psecuritypriv->ndisencryptstatus;
  850. privacy = pnetwork->network.Privacy;
  851. if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
  852. if (rtw_get_wps_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_, pnetwork->network.IELength - _FIXED_IE_LENGTH_, NULL, &wps_ielen) != NULL)
  853. return _TRUE;
  854. else
  855. return _FALSE;
  856. }
  857. if (adapter->registrypriv.wifi_spec == 1) { /* for correct flow of 8021X to do.... */
  858. u8 *p = NULL;
  859. uint ie_len = 0;
  860. if ((desired_encmode == Ndis802_11EncryptionDisabled) && (privacy != 0))
  861. bselected = _FALSE;
  862. if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
  863. p = rtw_get_ie(pnetwork->network.IEs + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pnetwork->network.IELength - _BEACON_IE_OFFSET_));
  864. if (p && ie_len > 0)
  865. bselected = _TRUE;
  866. else
  867. bselected = _FALSE;
  868. }
  869. }
  870. if ((desired_encmode != Ndis802_11EncryptionDisabled) && (privacy == 0)) {
  871. RTW_INFO("desired_encmode: %d, privacy: %d\n", desired_encmode, privacy);
  872. bselected = _FALSE;
  873. }
  874. if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) {
  875. if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
  876. bselected = _FALSE;
  877. }
  878. return bselected;
  879. }
  880. /* TODO: Perry : For Power Management */
  881. void rtw_atimdone_event_callback(_adapter *adapter , u8 *pbuf)
  882. {
  883. return;
  884. }
  885. void rtw_survey_event_callback(_adapter *adapter, u8 *pbuf)
  886. {
  887. _irqL irqL;
  888. u32 len;
  889. WLAN_BSSID_EX *pnetwork;
  890. struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
  891. pnetwork = (WLAN_BSSID_EX *)pbuf;
  892. #ifdef CONFIG_RTL8712
  893. /* endian_convert */
  894. pnetwork->Length = le32_to_cpu(pnetwork->Length);
  895. pnetwork->Ssid.SsidLength = le32_to_cpu(pnetwork->Ssid.SsidLength);
  896. pnetwork->Privacy = le32_to_cpu(pnetwork->Privacy);
  897. pnetwork->Rssi = le32_to_cpu(pnetwork->Rssi);
  898. pnetwork->NetworkTypeInUse = le32_to_cpu(pnetwork->NetworkTypeInUse);
  899. pnetwork->Configuration.ATIMWindow = le32_to_cpu(pnetwork->Configuration.ATIMWindow);
  900. pnetwork->Configuration.BeaconPeriod = le32_to_cpu(pnetwork->Configuration.BeaconPeriod);
  901. pnetwork->Configuration.DSConfig = le32_to_cpu(pnetwork->Configuration.DSConfig);
  902. pnetwork->Configuration.FHConfig.DwellTime = le32_to_cpu(pnetwork->Configuration.FHConfig.DwellTime);
  903. pnetwork->Configuration.FHConfig.HopPattern = le32_to_cpu(pnetwork->Configuration.FHConfig.HopPattern);
  904. pnetwork->Configuration.FHConfig.HopSet = le32_to_cpu(pnetwork->Configuration.FHConfig.HopSet);
  905. pnetwork->Configuration.FHConfig.Length = le32_to_cpu(pnetwork->Configuration.FHConfig.Length);
  906. pnetwork->Configuration.Length = le32_to_cpu(pnetwork->Configuration.Length);
  907. pnetwork->InfrastructureMode = le32_to_cpu(pnetwork->InfrastructureMode);
  908. pnetwork->IELength = le32_to_cpu(pnetwork->IELength);
  909. #endif
  910. len = get_WLAN_BSSID_EX_sz(pnetwork);
  911. if (len > (sizeof(WLAN_BSSID_EX))) {
  912. return;
  913. }
  914. _enter_critical_bh(&pmlmepriv->lock, &irqL);
  915. /* update IBSS_network 's timestamp */
  916. if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == _TRUE) {
  917. if (_rtw_memcmp(&(pmlmepriv->cur_network.network.MacAddress), pnetwork->MacAddress, ETH_ALEN)) {
  918. struct wlan_network *ibss_wlan = NULL;
  919. _irqL irqL;
  920. _rtw_memcpy(pmlmepriv->cur_network.network.IEs, pnetwork->IEs, 8);
  921. _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  922. ibss_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->MacAddress);
  923. if (ibss_wlan) {
  924. _rtw_memcpy(ibss_wlan->network.IEs , pnetwork->IEs, 8);
  925. _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  926. goto exit;
  927. }
  928. _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  929. }
  930. }
  931. /* lock pmlmepriv->lock when you accessing network_q */
  932. if ((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == _FALSE) {
  933. if (pnetwork->Ssid.Ssid[0] == 0)
  934. pnetwork->Ssid.SsidLength = 0;
  935. rtw_add_network(adapter, pnetwork);
  936. }
  937. exit:
  938. _exit_critical_bh(&pmlmepriv->lock, &irqL);
  939. return;
  940. }
  941. void rtw_surveydone_event_callback(_adapter *adapter, u8 *pbuf)
  942. {
  943. _irqL irqL;
  944. struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
  945. #ifdef CONFIG_RTW_80211R
  946. struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
  947. #endif
  948. #ifdef CONFIG_MLME_EXT
  949. mlmeext_surveydone_event_callback(adapter);
  950. #endif
  951. _enter_critical_bh(&pmlmepriv->lock, &irqL);
  952. if (pmlmepriv->wps_probe_req_ie) {
  953. u32 free_len = pmlmepriv->wps_probe_req_ie_len;
  954. pmlmepriv->wps_probe_req_ie_len = 0;
  955. rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
  956. pmlmepriv->wps_probe_req_ie = NULL;
  957. }
  958. if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _FALSE) {
  959. RTW_INFO(FUNC_ADPT_FMT" fw_state:0x%x\n", FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv));
  960. /* rtw_warn_on(1); */
  961. }
  962. _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
  963. _exit_critical_bh(&pmlmepriv->lock, &irqL);
  964. _cancel_timer_ex(&pmlmepriv->scan_to_timer);
  965. _enter_critical_bh(&pmlmepriv->lock, &irqL);
  966. #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
  967. rtw_set_signal_stat_timer(&adapter->recvpriv);
  968. #endif
  969. if (pmlmepriv->to_join == _TRUE) {
  970. if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)) {
  971. if (check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE) {
  972. set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
  973. if (rtw_select_and_join_from_scanned_queue(pmlmepriv) == _SUCCESS)
  974. _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
  975. else {
  976. WLAN_BSSID_EX *pdev_network = &(adapter->registrypriv.dev_network);
  977. u8 *pibss = adapter->registrypriv.dev_network.MacAddress;
  978. /* pmlmepriv->fw_state ^= _FW_UNDER_SURVEY; */ /* because don't set assoc_timer */
  979. _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
  980. _rtw_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID));
  981. _rtw_memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
  982. rtw_update_registrypriv_dev_network(adapter);
  983. rtw_generate_random_ibss(pibss);
  984. /*pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;*/
  985. init_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
  986. if (rtw_create_ibss_cmd(adapter, 0) != _SUCCESS)
  987. RTW_ERR("rtw_create_ibss_cmd FAIL\n");
  988. pmlmepriv->to_join = _FALSE;
  989. }
  990. }
  991. } else {
  992. int s_ret;
  993. set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
  994. pmlmepriv->to_join = _FALSE;
  995. s_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
  996. if (_SUCCESS == s_ret)
  997. _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
  998. else if (s_ret == 2) { /* there is no need to wait for join */
  999. _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
  1000. rtw_indicate_connect(adapter);
  1001. } else {
  1002. RTW_INFO("try_to_join, but select scanning queue fail, to_roam:%d\n", rtw_to_roam(adapter));
  1003. if (rtw_to_roam(adapter) != 0) {
  1004. if (rtw_dec_to_roam(adapter) == 0
  1005. || _SUCCESS != rtw_sitesurvey_cmd(adapter, &pmlmepriv->assoc_ssid, 1, NULL, 0)
  1006. ) {
  1007. rtw_set_to_roam(adapter, 0);
  1008. #ifdef CONFIG_INTEL_WIDI
  1009. if (adapter->mlmepriv.widi_state == INTEL_WIDI_STATE_ROAMING) {
  1010. _rtw_memset(pmlmepriv->sa_ext, 0x00, L2SDTA_SERVICE_VE_LEN);
  1011. intel_widi_wk_cmd(adapter, INTEL_WIDI_LISTEN_WK, NULL, 0);
  1012. RTW_INFO("change to widi listen\n");
  1013. }
  1014. #endif /* CONFIG_INTEL_WIDI */
  1015. rtw_free_assoc_resources(adapter, 1);
  1016. rtw_indicate_disconnect(adapter, 0, _FALSE);
  1017. } else
  1018. pmlmepriv->to_join = _TRUE;
  1019. } else
  1020. rtw_indicate_disconnect(adapter, 0, _FALSE);
  1021. _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
  1022. }
  1023. }
  1024. } else {
  1025. if (rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)) {
  1026. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)
  1027. && check_fwstate(pmlmepriv, _FW_LINKED)) {
  1028. if (rtw_select_roaming_candidate(pmlmepriv) == _SUCCESS) {
  1029. #ifdef CONFIG_RTW_80211R
  1030. if (rtw_chk_ft_flags(adapter, RTW_FT_OVER_DS_SUPPORTED)) {
  1031. start_clnt_ft_action(adapter, (u8 *)pmlmepriv->roam_network->network.MacAddress);
  1032. } else {
  1033. /*wait a little time to retrieve packets buffered in the current ap while scan*/
  1034. _set_timer(&pmlmeext->ft_roam_timer, 30);
  1035. }
  1036. #else
  1037. receive_disconnect(adapter, pmlmepriv->cur_network.network.MacAddress
  1038. , WLAN_REASON_ACTIVE_ROAM, _FALSE);
  1039. #endif
  1040. }
  1041. }
  1042. }
  1043. }
  1044. /* RTW_INFO("scan complete in %dms\n",rtw_get_passing_time_ms(pmlmepriv->scan_start_time)); */
  1045. _exit_critical_bh(&pmlmepriv->lock, &irqL);
  1046. #ifdef CONFIG_P2P_PS
  1047. if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
  1048. p2p_ps_wk_cmd(adapter, P2P_PS_SCAN_DONE, 0);
  1049. #endif /* CONFIG_P2P_PS */
  1050. rtw_mi_os_xmit_schedule(adapter);
  1051. #ifdef CONFIG_DRVEXT_MODULE_WSC
  1052. drvext_surveydone_callback(&adapter->drvextpriv);
  1053. #endif
  1054. #ifdef DBG_CONFIG_ERROR_DETECT
  1055. {
  1056. struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
  1057. if (pmlmeext->sitesurvey_res.bss_cnt == 0) {
  1058. /* rtw_hal_sreset_reset(adapter); */
  1059. }
  1060. }
  1061. #endif
  1062. #ifdef CONFIG_IOCTL_CFG80211
  1063. rtw_cfg80211_surveydone_event_callback(adapter);
  1064. #endif /* CONFIG_IOCTL_CFG80211 */
  1065. rtw_indicate_scan_done(adapter, _FALSE);
  1066. #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_IOCTL_CFG80211)
  1067. rtw_cfg80211_indicate_scan_done_for_buddy(adapter, _FALSE);
  1068. #endif
  1069. }
  1070. void rtw_dummy_event_callback(_adapter *adapter , u8 *pbuf)
  1071. {
  1072. }
  1073. void rtw_fwdbg_event_callback(_adapter *adapter , u8 *pbuf)
  1074. {
  1075. }
  1076. static void free_scanqueue(struct mlme_priv *pmlmepriv)
  1077. {
  1078. _irqL irqL, irqL0;
  1079. _queue *free_queue = &pmlmepriv->free_bss_pool;
  1080. _queue *scan_queue = &pmlmepriv->scanned_queue;
  1081. _list *plist, *phead, *ptemp;
  1082. _enter_critical_bh(&scan_queue->lock, &irqL0);
  1083. _enter_critical_bh(&free_queue->lock, &irqL);
  1084. phead = get_list_head(scan_queue);
  1085. plist = get_next(phead);
  1086. while (plist != phead) {
  1087. ptemp = get_next(plist);
  1088. rtw_list_delete(plist);
  1089. rtw_list_insert_tail(plist, &free_queue->queue);
  1090. plist = ptemp;
  1091. pmlmepriv->num_of_scanned--;
  1092. }
  1093. _exit_critical_bh(&free_queue->lock, &irqL);
  1094. _exit_critical_bh(&scan_queue->lock, &irqL0);
  1095. }
  1096. void rtw_reset_rx_info(struct debug_priv *pdbgpriv)
  1097. {
  1098. pdbgpriv->dbg_rx_ampdu_drop_count = 0;
  1099. pdbgpriv->dbg_rx_ampdu_forced_indicate_count = 0;
  1100. pdbgpriv->dbg_rx_ampdu_loss_count = 0;
  1101. pdbgpriv->dbg_rx_dup_mgt_frame_drop_count = 0;
  1102. pdbgpriv->dbg_rx_ampdu_window_shift_cnt = 0;
  1103. }
  1104. /*
  1105. *rtw_free_assoc_resources: the caller has to lock pmlmepriv->lock
  1106. */
  1107. void rtw_free_assoc_resources(_adapter *adapter, int lock_scanned_queue)
  1108. {
  1109. _irqL irqL;
  1110. struct wlan_network *pwlan = NULL;
  1111. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  1112. struct sta_priv *pstapriv = &adapter->stapriv;
  1113. struct wlan_network *tgt_network = &pmlmepriv->cur_network;
  1114. struct dvobj_priv *psdpriv = adapter->dvobj;
  1115. struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
  1116. #ifdef CONFIG_TDLS
  1117. struct tdls_info *ptdlsinfo = &adapter->tdlsinfo;
  1118. #endif /* CONFIG_TDLS */
  1119. RTW_INFO("%s-"ADPT_FMT" tgt_network MacAddress=" MAC_FMT"ssid=%s\n",
  1120. __func__, ADPT_ARG(adapter), MAC_ARG(tgt_network->network.MacAddress), tgt_network->network.Ssid.Ssid);
  1121. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
  1122. struct sta_info *psta;
  1123. psta = rtw_get_stainfo(&adapter->stapriv, tgt_network->network.MacAddress);
  1124. #ifdef CONFIG_TDLS
  1125. if (ptdlsinfo->link_established == _TRUE) {
  1126. rtw_tdls_cmd(adapter, NULL, TDLS_RS_RCR);
  1127. rtw_reset_tdls_info(adapter);
  1128. rtw_free_all_stainfo(adapter);
  1129. /* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
  1130. } else
  1131. #endif /* CONFIG_TDLS */
  1132. {
  1133. /* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
  1134. rtw_free_stainfo(adapter, psta);
  1135. }
  1136. /* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
  1137. }
  1138. if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
  1139. struct sta_info *psta;
  1140. rtw_free_all_stainfo(adapter);
  1141. psta = rtw_get_bcmc_stainfo(adapter);
  1142. /* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
  1143. rtw_free_stainfo(adapter, psta);
  1144. /* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
  1145. rtw_init_bcmc_stainfo(adapter);
  1146. }
  1147. if (lock_scanned_queue)
  1148. _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  1149. pwlan = _rtw_find_same_network(&pmlmepriv->scanned_queue, tgt_network);
  1150. if ((pwlan) && (!check_fwstate(pmlmepriv, WIFI_UNDER_WPS))) {
  1151. pwlan->fixed = _FALSE;
  1152. RTW_INFO("free disconnecting network of scanned_queue\n");
  1153. rtw_free_network_nolock(adapter, pwlan);
  1154. #ifdef CONFIG_P2P
  1155. if (!rtw_p2p_chk_state(&adapter->wdinfo, P2P_STATE_NONE)) {
  1156. rtw_mi_set_scan_deny(adapter, 2000);
  1157. /* rtw_clear_scan_deny(adapter); */
  1158. }
  1159. #endif /* CONFIG_P2P */
  1160. } else {
  1161. if (pwlan == NULL)
  1162. RTW_INFO("free disconnecting network of scanned_queue failed due to pwlan== NULL\n\n");
  1163. if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
  1164. RTW_INFO("donot free disconnecting network of scanned_queue when WIFI_UNDER_WPS\n\n");
  1165. }
  1166. if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) && (adapter->stapriv.asoc_sta_count == 1))
  1167. /*||check_fwstate(pmlmepriv, WIFI_STATION_STATE)*/) {
  1168. if (pwlan)
  1169. rtw_free_network_nolock(adapter, pwlan);
  1170. }
  1171. if (lock_scanned_queue)
  1172. _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  1173. adapter->securitypriv.key_mask = 0;
  1174. rtw_reset_rx_info(pdbgpriv);
  1175. }
  1176. /*
  1177. *rtw_indicate_connect: the caller has to lock pmlmepriv->lock
  1178. */
  1179. void rtw_indicate_connect(_adapter *padapter)
  1180. {
  1181. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  1182. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  1183. pmlmepriv->to_join = _FALSE;
  1184. if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
  1185. set_fwstate(pmlmepriv, _FW_LINKED);
  1186. rtw_led_control(padapter, LED_CTL_LINK);
  1187. #ifdef CONFIG_DRVEXT_MODULE
  1188. if (padapter->drvextpriv.enable_wpa)
  1189. indicate_l2_connect(padapter);
  1190. else
  1191. #endif
  1192. {
  1193. rtw_os_indicate_connect(padapter);
  1194. }
  1195. }
  1196. rtw_set_to_roam(padapter, 0);
  1197. #ifdef CONFIG_INTEL_WIDI
  1198. if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_ROAMING) {
  1199. _rtw_memset(pmlmepriv->sa_ext, 0x00, L2SDTA_SERVICE_VE_LEN);
  1200. intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_WK, NULL, 0);
  1201. RTW_INFO("change to widi listen\n");
  1202. }
  1203. #endif /* CONFIG_INTEL_WIDI */
  1204. if (!check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE))
  1205. rtw_mi_set_scan_deny(padapter, 3000);
  1206. }
  1207. /*
  1208. *rtw_indicate_disconnect: the caller has to lock pmlmepriv->lock
  1209. */
  1210. void rtw_indicate_disconnect(_adapter *padapter, u16 reason, u8 locally_generated)
  1211. {
  1212. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  1213. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  1214. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  1215. WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
  1216. struct sta_info *psta;
  1217. struct sta_priv *pstapriv = &padapter->stapriv;
  1218. u8 *wps_ie = NULL;
  1219. uint wpsie_len = 0;
  1220. _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING | WIFI_UNDER_WPS);
  1221. /* force to clear cur_network_scanned's SELECTED REGISTRAR */
  1222. if (pmlmepriv->cur_network_scanned) {
  1223. WLAN_BSSID_EX *current_joined_bss = &(pmlmepriv->cur_network_scanned->network);
  1224. if (current_joined_bss) {
  1225. wps_ie = rtw_get_wps_ie(current_joined_bss->IEs + _FIXED_IE_LENGTH_,
  1226. current_joined_bss->IELength - _FIXED_IE_LENGTH_, NULL, &wpsie_len);
  1227. if (wps_ie && wpsie_len > 0) {
  1228. u8 *attr = NULL;
  1229. u32 attr_len;
  1230. attr = rtw_get_wps_attr(wps_ie, wpsie_len, WPS_ATTR_SELECTED_REGISTRAR,
  1231. NULL, &attr_len);
  1232. if (attr)
  1233. *(attr + 4) = 0;
  1234. }
  1235. }
  1236. }
  1237. /* RTW_INFO("clear wps when %s\n", __func__); */
  1238. if (rtw_to_roam(padapter) > 0)
  1239. _clr_fwstate_(pmlmepriv, _FW_LINKED);
  1240. #ifdef CONFIG_WAPI_SUPPORT
  1241. psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
  1242. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
  1243. rtw_wapi_return_one_sta_info(padapter, psta->hwaddr);
  1244. else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
  1245. check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))
  1246. rtw_wapi_return_all_sta_info(padapter);
  1247. #endif
  1248. if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)
  1249. || (rtw_to_roam(padapter) <= 0)
  1250. ) {
  1251. rtw_os_indicate_disconnect(padapter, reason, locally_generated);
  1252. /* set ips_deny_time to avoid enter IPS before LPS leave */
  1253. rtw_set_ips_deny(padapter, 3000);
  1254. _clr_fwstate_(pmlmepriv, _FW_LINKED);
  1255. rtw_led_control(padapter, LED_CTL_NO_LINK);
  1256. rtw_clear_scan_deny(padapter);
  1257. }
  1258. #ifdef CONFIG_P2P_PS
  1259. p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1);
  1260. #endif /* CONFIG_P2P_PS */
  1261. #ifdef CONFIG_LPS
  1262. rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 1);
  1263. #endif
  1264. #ifdef CONFIG_BEAMFORMING
  1265. beamforming_wk_cmd(padapter, BEAMFORMING_CTRL_LEAVE, cur_network->MacAddress, ETH_ALEN, 1);
  1266. #endif /*CONFIG_BEAMFORMING*/
  1267. }
  1268. inline void rtw_indicate_scan_done(_adapter *padapter, bool aborted)
  1269. {
  1270. RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
  1271. rtw_os_indicate_scan_done(padapter, aborted);
  1272. #ifdef CONFIG_IPS
  1273. if (is_primary_adapter(padapter)
  1274. && (_FALSE == adapter_to_pwrctl(padapter)->bInSuspend)
  1275. && (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE | WIFI_UNDER_LINKING) == _FALSE)) {
  1276. struct pwrctrl_priv *pwrpriv;
  1277. pwrpriv = adapter_to_pwrctl(padapter);
  1278. rtw_set_ips_deny(padapter, 0);
  1279. #ifdef CONFIG_IPS_CHECK_IN_WD
  1280. _set_timer(&adapter_to_dvobj(padapter)->dynamic_chk_timer, 1);
  1281. #else /* !CONFIG_IPS_CHECK_IN_WD */
  1282. _rtw_set_pwr_state_check_timer(pwrpriv, 1);
  1283. #endif /* !CONFIG_IPS_CHECK_IN_WD */
  1284. }
  1285. #endif /* CONFIG_IPS */
  1286. }
  1287. static u32 _rtw_wait_scan_done(_adapter *adapter, u8 abort, u32 timeout_ms)
  1288. {
  1289. u32 start;
  1290. u32 pass_ms;
  1291. struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
  1292. struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
  1293. start = rtw_get_current_time();
  1294. pmlmeext->scan_abort = abort;
  1295. while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)
  1296. && rtw_get_passing_time_ms(start) <= timeout_ms) {
  1297. if (RTW_CANNOT_RUN(adapter))
  1298. break;
  1299. RTW_INFO(FUNC_NDEV_FMT"fw_state=_FW_UNDER_SURVEY!\n", FUNC_NDEV_ARG(adapter->pnetdev));
  1300. rtw_msleep_os(20);
  1301. }
  1302. if (_TRUE == abort) {
  1303. if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
  1304. if (!RTW_CANNOT_RUN(adapter))
  1305. RTW_INFO(FUNC_NDEV_FMT"waiting for scan_abort time out!\n", FUNC_NDEV_ARG(adapter->pnetdev));
  1306. #ifdef CONFIG_PLATFORM_MSTAR
  1307. /*_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);*/
  1308. set_survey_timer(pmlmeext, 0);
  1309. mlme_set_scan_to_timer(pmlmepriv, 50);
  1310. #endif
  1311. rtw_indicate_scan_done(adapter, _TRUE);
  1312. }
  1313. }
  1314. pmlmeext->scan_abort = _FALSE;
  1315. pass_ms = rtw_get_passing_time_ms(start);
  1316. return pass_ms;
  1317. }
  1318. void rtw_scan_wait_completed(_adapter *adapter)
  1319. {
  1320. u32 scan_to = SCANNING_TIMEOUT;
  1321. #ifdef CONFIG_SCAN_BACKOP
  1322. if (is_supported_5g(adapter->registrypriv.wireless_mode)
  1323. && IsSupported24G(adapter->registrypriv.wireless_mode)) /*dual band*/
  1324. scan_to = CONC_SCANNING_TIMEOUT_DUAL_BAND;
  1325. else /*single band*/
  1326. scan_to = CONC_SCANNING_TIMEOUT_SINGLE_BAND;
  1327. #endif /* CONFIG_SCAN_BACKOP */
  1328. _rtw_wait_scan_done(adapter, _FALSE, scan_to);
  1329. }
  1330. u32 rtw_scan_abort_timeout(_adapter *adapter, u32 timeout_ms)
  1331. {
  1332. return _rtw_wait_scan_done(adapter, _TRUE, timeout_ms);
  1333. }
  1334. void rtw_scan_abort_no_wait(_adapter *adapter)
  1335. {
  1336. struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
  1337. struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
  1338. if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
  1339. pmlmeext->scan_abort = _TRUE;
  1340. }
  1341. void rtw_scan_abort(_adapter *adapter)
  1342. {
  1343. rtw_scan_abort_timeout(adapter, 200);
  1344. }
  1345. static struct sta_info *rtw_joinbss_update_stainfo(_adapter *padapter, struct wlan_network *pnetwork)
  1346. {
  1347. int i;
  1348. struct sta_info *bmc_sta, *psta = NULL;
  1349. struct recv_reorder_ctrl *preorder_ctrl;
  1350. struct sta_priv *pstapriv = &padapter->stapriv;
  1351. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  1352. psta = rtw_get_stainfo(pstapriv, pnetwork->network.MacAddress);
  1353. if (psta == NULL)
  1354. psta = rtw_alloc_stainfo(pstapriv, pnetwork->network.MacAddress);
  1355. if (psta) { /* update ptarget_sta */
  1356. RTW_INFO("%s\n", __FUNCTION__);
  1357. psta->aid = pnetwork->join_res;
  1358. #if 0 /* alloc macid when call rtw_alloc_stainfo(), and release macid when call rtw_free_stainfo() */
  1359. #ifdef CONFIG_CONCURRENT_MODE
  1360. if (PRIMARY_ADAPTER == padapter->adapter_type)
  1361. psta->mac_id = 0;
  1362. else
  1363. psta->mac_id = 2;
  1364. #else
  1365. psta->mac_id = 0;
  1366. #endif
  1367. #endif /* removed */
  1368. update_sta_info(padapter, psta);
  1369. /* update station supportRate */
  1370. psta->bssratelen = rtw_get_rateset_len(pnetwork->network.SupportedRates);
  1371. _rtw_memcpy(psta->bssrateset, pnetwork->network.SupportedRates, psta->bssratelen);
  1372. rtw_hal_update_sta_rate_mask(padapter, psta);
  1373. psta->wireless_mode = pmlmeext->cur_wireless_mode;
  1374. psta->raid = rtw_hal_networktype_to_raid(padapter, psta);
  1375. /* sta mode */
  1376. rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);
  1377. /* security related */
  1378. #ifdef CONFIG_RTW_80211R
  1379. if ((padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) && (psta->ft_pairwise_key_installed == _FALSE)) {
  1380. #else
  1381. if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
  1382. #endif
  1383. padapter->securitypriv.binstallGrpkey = _FALSE;
  1384. padapter->securitypriv.busetkipkey = _FALSE;
  1385. padapter->securitypriv.bgrpkey_handshake = _FALSE;
  1386. psta->ieee8021x_blocked = _TRUE;
  1387. psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
  1388. _rtw_memset((u8 *)&psta->dot118021x_UncstKey, 0, sizeof(union Keytype));
  1389. _rtw_memset((u8 *)&psta->dot11tkiprxmickey, 0, sizeof(union Keytype));
  1390. _rtw_memset((u8 *)&psta->dot11tkiptxmickey, 0, sizeof(union Keytype));
  1391. _rtw_memset((u8 *)&psta->dot11txpn, 0, sizeof(union pn48));
  1392. psta->dot11txpn.val = psta->dot11txpn.val + 1;
  1393. #ifdef CONFIG_IEEE80211W
  1394. _rtw_memset((u8 *)&psta->dot11wtxpn, 0, sizeof(union pn48));
  1395. #endif /* CONFIG_IEEE80211W */
  1396. _rtw_memset((u8 *)&psta->dot11rxpn, 0, sizeof(union pn48));
  1397. }
  1398. /* Commented by Albert 2012/07/21 */
  1399. /* When doing the WPS, the wps_ie_len won't equal to 0 */
  1400. /* And the Wi-Fi driver shouldn't allow the data packet to be tramsmitted. */
  1401. if (padapter->securitypriv.wps_ie_len != 0) {
  1402. psta->ieee8021x_blocked = _TRUE;
  1403. padapter->securitypriv.wps_ie_len = 0;
  1404. }
  1405. /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info */
  1406. /* if A-MPDU Rx is enabled, reseting rx_ordering_ctrl wstart_b(indicate_seq) to default value=0xffff */
  1407. /* todo: check if AP can send A-MPDU packets */
  1408. for (i = 0; i < 16 ; i++) {
  1409. /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
  1410. preorder_ctrl = &psta->recvreorder_ctrl[i];
  1411. preorder_ctrl->enable = _FALSE;
  1412. preorder_ctrl->indicate_seq = 0xffff;
  1413. #ifdef DBG_RX_SEQ
  1414. RTW_INFO("DBG_RX_SEQ %s:%d indicate_seq:%u\n", __FUNCTION__, __LINE__,
  1415. preorder_ctrl->indicate_seq);
  1416. #endif
  1417. preorder_ctrl->wend_b = 0xffff;
  1418. preorder_ctrl->wsize_b = 64;/* max_ampdu_sz; */ /* ex. 32(kbytes) -> wsize_b=32 */
  1419. preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID;
  1420. }
  1421. bmc_sta = rtw_get_bcmc_stainfo(padapter);
  1422. if (bmc_sta) {
  1423. for (i = 0; i < 16 ; i++) {
  1424. /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
  1425. preorder_ctrl = &bmc_sta->recvreorder_ctrl[i];
  1426. preorder_ctrl->enable = _FALSE;
  1427. preorder_ctrl->indicate_seq = 0xffff;
  1428. #ifdef DBG_RX_SEQ
  1429. RTW_INFO("DBG_RX_SEQ %s:%d indicate_seq:%u\n", __FUNCTION__, __LINE__,
  1430. preorder_ctrl->indicate_seq);
  1431. #endif
  1432. preorder_ctrl->wend_b = 0xffff;
  1433. preorder_ctrl->wsize_b = 64;/* max_ampdu_sz; */ /* ex. 32(kbytes) -> wsize_b=32 */
  1434. preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID;
  1435. }
  1436. }
  1437. }
  1438. return psta;
  1439. }
  1440. /* pnetwork : returns from rtw_joinbss_event_callback
  1441. * ptarget_wlan: found from scanned_queue */
  1442. static void rtw_joinbss_update_network(_adapter *padapter, struct wlan_network *ptarget_wlan, struct wlan_network *pnetwork)
  1443. {
  1444. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  1445. struct wlan_network *cur_network = &(pmlmepriv->cur_network);
  1446. RTW_INFO("%s\n", __FUNCTION__);
  1447. /* why not use ptarget_wlan?? */
  1448. _rtw_memcpy(&cur_network->network, &pnetwork->network, pnetwork->network.Length);
  1449. /* some IEs in pnetwork is wrong, so we should use ptarget_wlan IEs */
  1450. cur_network->network.IELength = ptarget_wlan->network.IELength;
  1451. _rtw_memcpy(&cur_network->network.IEs[0], &ptarget_wlan->network.IEs[0], MAX_IE_SZ);
  1452. cur_network->aid = pnetwork->join_res;
  1453. #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
  1454. rtw_set_signal_stat_timer(&padapter->recvpriv);
  1455. #endif
  1456. padapter->recvpriv.signal_strength = ptarget_wlan->network.PhyInfo.SignalStrength;
  1457. padapter->recvpriv.signal_qual = ptarget_wlan->network.PhyInfo.SignalQuality;
  1458. /* the ptarget_wlan->network.Rssi is raw data, we use ptarget_wlan->network.PhyInfo.SignalStrength instead (has scaled) */
  1459. padapter->recvpriv.rssi = translate_percentage_to_dbm(ptarget_wlan->network.PhyInfo.SignalStrength);
  1460. #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1
  1461. RTW_INFO(FUNC_ADPT_FMT" signal_strength:%3u, rssi:%3d, signal_qual:%3u"
  1462. "\n"
  1463. , FUNC_ADPT_ARG(padapter)
  1464. , padapter->recvpriv.signal_strength
  1465. , padapter->recvpriv.rssi
  1466. , padapter->recvpriv.signal_qual
  1467. );
  1468. #endif
  1469. #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
  1470. rtw_set_signal_stat_timer(&padapter->recvpriv);
  1471. #endif
  1472. /* update fw_state */ /* will clr _FW_UNDER_LINKING here indirectly */
  1473. switch (pnetwork->network.InfrastructureMode) {
  1474. case Ndis802_11Infrastructure:
  1475. if (pmlmepriv->fw_state & WIFI_UNDER_WPS)
  1476. /*pmlmepriv->fw_state = WIFI_STATION_STATE|WIFI_UNDER_WPS;*/
  1477. init_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_UNDER_WPS);
  1478. else
  1479. /*pmlmepriv->fw_state = WIFI_STATION_STATE;*/
  1480. init_fwstate(pmlmepriv, WIFI_STATION_STATE);
  1481. break;
  1482. case Ndis802_11IBSS:
  1483. /*pmlmepriv->fw_state = WIFI_ADHOC_STATE;*/
  1484. init_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
  1485. break;
  1486. default:
  1487. /*pmlmepriv->fw_state = WIFI_NULL_STATE;*/
  1488. init_fwstate(pmlmepriv, WIFI_NULL_STATE);
  1489. break;
  1490. }
  1491. rtw_update_protection(padapter, (cur_network->network.IEs) + sizeof(NDIS_802_11_FIXED_IEs),
  1492. (cur_network->network.IELength));
  1493. #ifdef CONFIG_80211N_HT
  1494. rtw_update_ht_cap(padapter, cur_network->network.IEs, cur_network->network.IELength, (u8) cur_network->network.Configuration.DSConfig);
  1495. #endif
  1496. }
  1497. /* Notes: the fucntion could be > passive_level (the same context as Rx tasklet)
  1498. * pnetwork : returns from rtw_joinbss_event_callback
  1499. * ptarget_wlan: found from scanned_queue
  1500. * if join_res > 0, for (fw_state==WIFI_STATION_STATE), we check if "ptarget_sta" & "ptarget_wlan" exist.
  1501. * if join_res > 0, for (fw_state==WIFI_ADHOC_STATE), we only check if "ptarget_wlan" exist.
  1502. * if join_res > 0, update "cur_network->network" from "pnetwork->network" if (ptarget_wlan !=NULL).
  1503. */
  1504. /* #define REJOIN */
  1505. void rtw_joinbss_event_prehandle(_adapter *adapter, u8 *pbuf)
  1506. {
  1507. _irqL irqL, irqL2;
  1508. static u8 retry = 0;
  1509. struct sta_info *ptarget_sta = NULL, *pcur_sta = NULL;
  1510. struct sta_priv *pstapriv = &adapter->stapriv;
  1511. struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
  1512. struct wlan_network *pnetwork = (struct wlan_network *)pbuf;
  1513. struct wlan_network *cur_network = &(pmlmepriv->cur_network);
  1514. struct wlan_network *pcur_wlan = NULL, *ptarget_wlan = NULL;
  1515. unsigned int the_same_macaddr = _FALSE;
  1516. #ifdef CONFIG_RTL8712
  1517. /* endian_convert */
  1518. pnetwork->join_res = le32_to_cpu(pnetwork->join_res);
  1519. pnetwork->network_type = le32_to_cpu(pnetwork->network_type);
  1520. pnetwork->network.Length = le32_to_cpu(pnetwork->network.Length);
  1521. pnetwork->network.Ssid.SsidLength = le32_to_cpu(pnetwork->network.Ssid.SsidLength);
  1522. pnetwork->network.Privacy = le32_to_cpu(pnetwork->network.Privacy);
  1523. pnetwork->network.Rssi = le32_to_cpu(pnetwork->network.Rssi);
  1524. pnetwork->network.NetworkTypeInUse = le32_to_cpu(pnetwork->network.NetworkTypeInUse) ;
  1525. pnetwork->network.Configuration.ATIMWindow = le32_to_cpu(pnetwork->network.Configuration.ATIMWindow);
  1526. pnetwork->network.Configuration.BeaconPeriod = le32_to_cpu(pnetwork->network.Configuration.BeaconPeriod);
  1527. pnetwork->network.Configuration.DSConfig = le32_to_cpu(pnetwork->network.Configuration.DSConfig);
  1528. pnetwork->network.Configuration.FHConfig.DwellTime = le32_to_cpu(pnetwork->network.Configuration.FHConfig.DwellTime);
  1529. pnetwork->network.Configuration.FHConfig.HopPattern = le32_to_cpu(pnetwork->network.Configuration.FHConfig.HopPattern);
  1530. pnetwork->network.Configuration.FHConfig.HopSet = le32_to_cpu(pnetwork->network.Configuration.FHConfig.HopSet);
  1531. pnetwork->network.Configuration.FHConfig.Length = le32_to_cpu(pnetwork->network.Configuration.FHConfig.Length);
  1532. pnetwork->network.Configuration.Length = le32_to_cpu(pnetwork->network.Configuration.Length);
  1533. pnetwork->network.InfrastructureMode = le32_to_cpu(pnetwork->network.InfrastructureMode);
  1534. pnetwork->network.IELength = le32_to_cpu(pnetwork->network.IELength);
  1535. #endif
  1536. rtw_get_encrypt_decrypt_from_registrypriv(adapter);
  1537. the_same_macaddr = _rtw_memcmp(pnetwork->network.MacAddress, cur_network->network.MacAddress, ETH_ALEN);
  1538. pnetwork->network.Length = get_WLAN_BSSID_EX_sz(&pnetwork->network);
  1539. if (pnetwork->network.Length > sizeof(WLAN_BSSID_EX)) {
  1540. goto ignore_joinbss_callback;
  1541. }
  1542. _enter_critical_bh(&pmlmepriv->lock, &irqL);
  1543. pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0;
  1544. pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0;
  1545. if (pnetwork->join_res > 0) {
  1546. _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  1547. retry = 0;
  1548. if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
  1549. /* s1. find ptarget_wlan */
  1550. if (check_fwstate(pmlmepriv, _FW_LINKED)) {
  1551. if (the_same_macaddr == _TRUE)
  1552. ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
  1553. else {
  1554. pcur_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
  1555. if (pcur_wlan)
  1556. pcur_wlan->fixed = _FALSE;
  1557. pcur_sta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
  1558. if (pcur_sta) {
  1559. /* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); */
  1560. rtw_free_stainfo(adapter, pcur_sta);
  1561. /* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); */
  1562. }
  1563. ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress);
  1564. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) {
  1565. if (ptarget_wlan)
  1566. ptarget_wlan->fixed = _TRUE;
  1567. }
  1568. }
  1569. } else {
  1570. ptarget_wlan = _rtw_find_same_network(&pmlmepriv->scanned_queue, pnetwork);
  1571. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) {
  1572. if (ptarget_wlan)
  1573. ptarget_wlan->fixed = _TRUE;
  1574. }
  1575. }
  1576. /* s2. update cur_network */
  1577. if (ptarget_wlan)
  1578. rtw_joinbss_update_network(adapter, ptarget_wlan, pnetwork);
  1579. else {
  1580. RTW_PRINT("Can't find ptarget_wlan when joinbss_event callback\n");
  1581. _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  1582. goto ignore_joinbss_callback;
  1583. }
  1584. /* s3. find ptarget_sta & update ptarget_sta after update cur_network only for station mode */
  1585. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) {
  1586. ptarget_sta = rtw_joinbss_update_stainfo(adapter, pnetwork);
  1587. if (ptarget_sta == NULL) {
  1588. RTW_ERR("Can't update stainfo when joinbss_event callback\n");
  1589. _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  1590. goto ignore_joinbss_callback;
  1591. }
  1592. }
  1593. /* s4. indicate connect */
  1594. if (MLME_IS_STA(adapter) || MLME_IS_ADHOC(adapter)) {
  1595. pmlmepriv->cur_network_scanned = ptarget_wlan;
  1596. rtw_indicate_connect(adapter);
  1597. }
  1598. /* s5. Cancle assoc_timer */
  1599. _cancel_timer_ex(&pmlmepriv->assoc_timer);
  1600. } else {
  1601. _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  1602. goto ignore_joinbss_callback;
  1603. }
  1604. _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  1605. } else if (pnetwork->join_res == -4) {
  1606. rtw_reset_securitypriv(adapter);
  1607. _set_timer(&pmlmepriv->assoc_timer, 1);
  1608. /* rtw_free_assoc_resources(adapter, 1); */
  1609. if ((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == _TRUE) {
  1610. _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
  1611. }
  1612. } else { /* if join_res < 0 (join fails), then try again */
  1613. #ifdef REJOIN
  1614. res = _FAIL;
  1615. if (retry < 2) {
  1616. res = rtw_select_and_join_from_scanned_queue(pmlmepriv);
  1617. }
  1618. if (res == _SUCCESS) {
  1619. /* extend time of assoc_timer */
  1620. _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
  1621. retry++;
  1622. } else if (res == 2) { /* there is no need to wait for join */
  1623. _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
  1624. rtw_indicate_connect(adapter);
  1625. } else {
  1626. #endif
  1627. _set_timer(&pmlmepriv->assoc_timer, 1);
  1628. /* rtw_free_assoc_resources(adapter, 1); */
  1629. _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
  1630. #ifdef REJOIN
  1631. retry = 0;
  1632. }
  1633. #endif
  1634. }
  1635. ignore_joinbss_callback:
  1636. _exit_critical_bh(&pmlmepriv->lock, &irqL);
  1637. }
  1638. void rtw_joinbss_event_callback(_adapter *adapter, u8 *pbuf)
  1639. {
  1640. struct wlan_network *pnetwork = (struct wlan_network *)pbuf;
  1641. mlmeext_joinbss_event_callback(adapter, pnetwork->join_res);
  1642. rtw_mi_os_xmit_schedule(adapter);
  1643. }
  1644. void rtw_sta_media_status_rpt(_adapter *adapter, struct sta_info *sta, bool connected)
  1645. {
  1646. struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
  1647. bool miracast_enabled = 0;
  1648. bool miracast_sink = 0;
  1649. u8 role = H2C_MSR_ROLE_RSVD;
  1650. if (sta == NULL) {
  1651. RTW_PRINT(FUNC_ADPT_FMT" sta is NULL\n"
  1652. , FUNC_ADPT_ARG(adapter));
  1653. rtw_warn_on(1);
  1654. return;
  1655. }
  1656. if (sta->mac_id >= macid_ctl->num) {
  1657. RTW_PRINT(FUNC_ADPT_FMT" invalid macid:%u\n"
  1658. , FUNC_ADPT_ARG(adapter), sta->mac_id);
  1659. rtw_warn_on(1);
  1660. return;
  1661. }
  1662. if (!rtw_macid_is_used(macid_ctl, sta->mac_id)) {
  1663. RTW_PRINT(FUNC_ADPT_FMT" macid:%u not is used, set connected to 0\n"
  1664. , FUNC_ADPT_ARG(adapter), sta->mac_id);
  1665. connected = 0;
  1666. rtw_warn_on(1);
  1667. }
  1668. if (connected && !rtw_macid_is_bmc(macid_ctl, sta->mac_id)) {
  1669. miracast_enabled = STA_OP_WFD_MODE(sta) != 0 && is_miracast_enabled(adapter);
  1670. miracast_sink = miracast_enabled && (STA_OP_WFD_MODE(sta) & MIRACAST_SINK);
  1671. #ifdef CONFIG_TDLS
  1672. if (sta->tdls_sta_state & TDLS_LINKED_STATE)
  1673. role = H2C_MSR_ROLE_TDLS;
  1674. else
  1675. #endif
  1676. if (MLME_IS_STA(adapter)) {
  1677. if (MLME_IS_GC(adapter))
  1678. role = H2C_MSR_ROLE_GO;
  1679. else
  1680. role = H2C_MSR_ROLE_AP;
  1681. } else if (MLME_IS_AP(adapter)) {
  1682. if (MLME_IS_GO(adapter))
  1683. role = H2C_MSR_ROLE_GC;
  1684. else
  1685. role = H2C_MSR_ROLE_STA;
  1686. } else if (MLME_IS_ADHOC(adapter) || MLME_IS_ADHOC_MASTER(adapter))
  1687. role = H2C_MSR_ROLE_ADHOC;
  1688. #ifdef CONFIG_WFD
  1689. if (role == H2C_MSR_ROLE_GC
  1690. || role == H2C_MSR_ROLE_GO
  1691. || role == H2C_MSR_ROLE_TDLS
  1692. ) {
  1693. if (adapter->wfd_info.rtsp_ctrlport
  1694. || adapter->wfd_info.tdls_rtsp_ctrlport
  1695. || adapter->wfd_info.peer_rtsp_ctrlport)
  1696. rtw_wfd_st_switch(sta, 1);
  1697. }
  1698. #endif
  1699. }
  1700. rtw_hal_set_FwMediaStatusRpt_single_cmd(adapter
  1701. , connected
  1702. , miracast_enabled
  1703. , miracast_sink
  1704. , role
  1705. , sta->mac_id
  1706. );
  1707. }
  1708. u8 rtw_sta_media_status_rpt_cmd(_adapter *adapter, struct sta_info *sta, bool connected)
  1709. {
  1710. struct cmd_priv *cmdpriv = &adapter->cmdpriv;
  1711. struct cmd_obj *cmdobj;
  1712. struct drvextra_cmd_parm *cmd_parm;
  1713. struct sta_media_status_rpt_cmd_parm *rpt_parm;
  1714. u8 res = _SUCCESS;
  1715. cmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
  1716. if (cmdobj == NULL) {
  1717. res = _FAIL;
  1718. goto exit;
  1719. }
  1720. cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
  1721. if (cmd_parm == NULL) {
  1722. rtw_mfree((u8 *)cmdobj, sizeof(struct cmd_obj));
  1723. res = _FAIL;
  1724. goto exit;
  1725. }
  1726. rpt_parm = (struct sta_media_status_rpt_cmd_parm *)rtw_zmalloc(sizeof(struct sta_media_status_rpt_cmd_parm));
  1727. if (rpt_parm == NULL) {
  1728. rtw_mfree((u8 *)cmdobj, sizeof(struct cmd_obj));
  1729. rtw_mfree((u8 *)cmd_parm, sizeof(struct drvextra_cmd_parm));
  1730. res = _FAIL;
  1731. goto exit;
  1732. }
  1733. rpt_parm->sta = sta;
  1734. rpt_parm->connected = connected;
  1735. cmd_parm->ec_id = STA_MSTATUS_RPT_WK_CID;
  1736. cmd_parm->type = 0;
  1737. cmd_parm->size = sizeof(struct sta_media_status_rpt_cmd_parm);
  1738. cmd_parm->pbuf = (u8 *)rpt_parm;
  1739. init_h2fwcmd_w_parm_no_rsp(cmdobj, cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
  1740. res = rtw_enqueue_cmd(cmdpriv, cmdobj);
  1741. exit:
  1742. return res;
  1743. }
  1744. inline void rtw_sta_media_status_rpt_cmd_hdl(_adapter *adapter, struct sta_media_status_rpt_cmd_parm *parm)
  1745. {
  1746. rtw_sta_media_status_rpt(adapter, parm->sta, parm->connected);
  1747. }
  1748. void rtw_stassoc_event_callback(_adapter *adapter, u8 *pbuf)
  1749. {
  1750. _irqL irqL;
  1751. struct sta_info *psta;
  1752. struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
  1753. struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf;
  1754. struct wlan_network *cur_network = &(pmlmepriv->cur_network);
  1755. struct wlan_network *ptarget_wlan = NULL;
  1756. #if CONFIG_RTW_MACADDR_ACL
  1757. if (rtw_access_ctrl(adapter, pstassoc->macaddr) == _FALSE)
  1758. return;
  1759. #endif
  1760. #if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
  1761. if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
  1762. psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
  1763. if (psta) {
  1764. u8 *passoc_req = NULL;
  1765. u32 assoc_req_len = 0;
  1766. rtw_sta_media_status_rpt(adapter, psta, 1);
  1767. #ifndef CONFIG_AUTO_AP_MODE
  1768. ap_sta_info_defer_update(adapter, psta);
  1769. /* report to upper layer */
  1770. RTW_INFO("indicate_sta_assoc_event to upper layer - hostapd\n");
  1771. #ifdef CONFIG_IOCTL_CFG80211
  1772. _enter_critical_bh(&psta->lock, &irqL);
  1773. if (psta->passoc_req && psta->assoc_req_len > 0) {
  1774. passoc_req = rtw_zmalloc(psta->assoc_req_len);
  1775. if (passoc_req) {
  1776. assoc_req_len = psta->assoc_req_len;
  1777. _rtw_memcpy(passoc_req, psta->passoc_req, assoc_req_len);
  1778. rtw_mfree(psta->passoc_req , psta->assoc_req_len);
  1779. psta->passoc_req = NULL;
  1780. psta->assoc_req_len = 0;
  1781. }
  1782. }
  1783. _exit_critical_bh(&psta->lock, &irqL);
  1784. if (passoc_req && assoc_req_len > 0) {
  1785. rtw_cfg80211_indicate_sta_assoc(adapter, passoc_req, assoc_req_len);
  1786. rtw_mfree(passoc_req, assoc_req_len);
  1787. }
  1788. #else /* !CONFIG_IOCTL_CFG80211 */
  1789. rtw_indicate_sta_assoc_event(adapter, psta);
  1790. #endif /* !CONFIG_IOCTL_CFG80211 */
  1791. #endif /* !CONFIG_AUTO_AP_MODE */
  1792. #ifdef CONFIG_BEAMFORMING
  1793. beamforming_wk_cmd(adapter, BEAMFORMING_CTRL_ENTER, (u8 *)psta, sizeof(struct sta_info), 0);
  1794. #endif/*CONFIG_BEAMFORMING*/
  1795. if (is_wep_enc(adapter->securitypriv.dot11PrivacyAlgrthm))
  1796. rtw_ap_wep_pk_setting(adapter, psta);
  1797. }
  1798. goto exit;
  1799. }
  1800. #endif /* defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
  1801. /* for AD-HOC mode */
  1802. psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
  1803. if (psta == NULL) {
  1804. RTW_ERR(FUNC_ADPT_FMT" get no sta_info with "MAC_FMT"\n"
  1805. , FUNC_ADPT_ARG(adapter), MAC_ARG(pstassoc->macaddr));
  1806. rtw_warn_on(1);
  1807. goto exit;
  1808. }
  1809. rtw_hal_set_odm_var(adapter, HAL_ODM_STA_INFO, psta, _TRUE);
  1810. rtw_sta_media_status_rpt(adapter, psta, 1);
  1811. if (adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
  1812. psta->dot118021XPrivacy = adapter->securitypriv.dot11PrivacyAlgrthm;
  1813. psta->ieee8021x_blocked = _FALSE;
  1814. _enter_critical_bh(&pmlmepriv->lock, &irqL);
  1815. if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) ||
  1816. (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)) {
  1817. if (adapter->stapriv.asoc_sta_count == 2) {
  1818. _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  1819. ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
  1820. pmlmepriv->cur_network_scanned = ptarget_wlan;
  1821. if (ptarget_wlan)
  1822. ptarget_wlan->fixed = _TRUE;
  1823. _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  1824. /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
  1825. rtw_indicate_connect(adapter);
  1826. }
  1827. }
  1828. _exit_critical_bh(&pmlmepriv->lock, &irqL);
  1829. mlmeext_sta_add_event_callback(adapter, psta);
  1830. #ifdef CONFIG_RTL8711
  1831. /* submit SetStaKey_cmd to tell fw, fw will allocate an CAM entry for this sta */
  1832. rtw_setstakey_cmd(adapter, psta, GROUP_KEY, _TRUE);
  1833. #endif
  1834. exit:
  1835. return;
  1836. }
  1837. #ifdef CONFIG_IEEE80211W
  1838. void rtw_sta_timeout_event_callback(_adapter *adapter, u8 *pbuf)
  1839. {
  1840. _irqL irqL;
  1841. struct sta_info *psta;
  1842. struct stadel_event *pstadel = (struct stadel_event *)pbuf;
  1843. struct sta_priv *pstapriv = &adapter->stapriv;
  1844. psta = rtw_get_stainfo(&adapter->stapriv, pstadel->macaddr);
  1845. if (psta) {
  1846. u8 updated = _FALSE;
  1847. _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  1848. if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) {
  1849. rtw_list_delete(&psta->asoc_list);
  1850. pstapriv->asoc_list_cnt--;
  1851. updated = ap_free_sta(adapter, psta, _TRUE, WLAN_REASON_PREV_AUTH_NOT_VALID, _TRUE);
  1852. }
  1853. _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  1854. associated_clients_update(adapter, updated, STA_INFO_UPDATE_ALL);
  1855. }
  1856. }
  1857. #endif /* CONFIG_IEEE80211W */
  1858. #ifdef CONFIG_RTW_80211R
  1859. void rtw_update_ft_stainfo(_adapter *padapter, WLAN_BSSID_EX *pnetwork)
  1860. {
  1861. struct sta_priv *pstapriv = &padapter->stapriv;
  1862. struct sta_info *psta = NULL;
  1863. psta = rtw_get_stainfo(pstapriv, pnetwork->MacAddress);
  1864. if (psta == NULL)
  1865. psta = rtw_alloc_stainfo(pstapriv, pnetwork->MacAddress);
  1866. if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
  1867. padapter->securitypriv.binstallGrpkey = _FALSE;
  1868. padapter->securitypriv.busetkipkey = _FALSE;
  1869. padapter->securitypriv.bgrpkey_handshake = _FALSE;
  1870. psta->ieee8021x_blocked = _TRUE;
  1871. psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
  1872. psta->dot11txpn.val = psta->dot11txpn.val + 1;
  1873. _rtw_memset((u8 *)&psta->dot118021x_UncstKey, 0, sizeof(union Keytype));
  1874. _rtw_memset((u8 *)&psta->dot11tkiprxmickey, 0, sizeof(union Keytype));
  1875. _rtw_memset((u8 *)&psta->dot11tkiptxmickey, 0, sizeof(union Keytype));
  1876. _rtw_memset((u8 *)&psta->dot11txpn, 0, sizeof(union pn48));
  1877. #ifdef CONFIG_IEEE80211W
  1878. _rtw_memset((u8 *)&psta->dot11wtxpn, 0, sizeof(union pn48));
  1879. #endif
  1880. _rtw_memset((u8 *)&psta->dot11rxpn, 0, sizeof(union pn48));
  1881. }
  1882. }
  1883. void rtw_ft_reassoc_event_callback(_adapter *padapter, u8 *pbuf)
  1884. {
  1885. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  1886. struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf;
  1887. ft_priv *pftpriv = &pmlmepriv->ftpriv;
  1888. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  1889. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  1890. WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
  1891. struct cfg80211_ft_event_params ft_evt_parms;
  1892. _irqL irqL;
  1893. _rtw_memset(&ft_evt_parms, 0, sizeof(ft_evt_parms));
  1894. rtw_update_ft_stainfo(padapter, pnetwork);
  1895. ft_evt_parms.ies_len = pftpriv->ft_event.ies_len;
  1896. ft_evt_parms.ies = rtw_zmalloc(ft_evt_parms.ies_len);
  1897. if (ft_evt_parms.ies)
  1898. _rtw_memcpy((void *)ft_evt_parms.ies, pftpriv->ft_event.ies, ft_evt_parms.ies_len);
  1899. else
  1900. goto err_2;
  1901. ft_evt_parms.target_ap = rtw_zmalloc(ETH_ALEN);
  1902. if (ft_evt_parms.target_ap)
  1903. _rtw_memcpy((void *)ft_evt_parms.target_ap, pstassoc->macaddr, ETH_ALEN);
  1904. else
  1905. goto err_1;
  1906. ft_evt_parms.ric_ies = pftpriv->ft_event.ric_ies;
  1907. ft_evt_parms.ric_ies_len = pftpriv->ft_event.ric_ies_len;
  1908. _enter_critical_bh(&pmlmepriv->lock, &irqL);
  1909. rtw_set_ft_status(padapter, RTW_FT_AUTHENTICATED_STA);
  1910. _exit_critical_bh(&pmlmepriv->lock, &irqL);
  1911. rtw_cfg80211_ft_event(padapter, &ft_evt_parms);
  1912. RTW_INFO("%s: to "MAC_FMT"\n", __func__, MAC_ARG(ft_evt_parms.target_ap));
  1913. rtw_mfree((u8 *)pftpriv->ft_event.target_ap, ETH_ALEN);
  1914. err_1:
  1915. rtw_mfree((u8 *)ft_evt_parms.ies, ft_evt_parms.ies_len);
  1916. err_2:
  1917. return;
  1918. }
  1919. #endif
  1920. void rtw_sta_mstatus_disc_rpt(_adapter *adapter, u8 mac_id)
  1921. {
  1922. struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
  1923. RTW_INFO("%s "ADPT_FMT" - mac_id=%d\n", __func__, ADPT_ARG(adapter), mac_id);
  1924. if (mac_id >= 0 && mac_id < macid_ctl->num) {
  1925. rtw_hal_set_FwMediaStatusRpt_single_cmd(adapter, 0, 0, 0, 0, mac_id);
  1926. /*
  1927. * For safety, prevent from keeping macid sleep.
  1928. * If we can sure all power mode enter/leave are paired,
  1929. * this check can be removed.
  1930. * Lucas@20131113
  1931. */
  1932. /* wakeup macid after disconnect. */
  1933. /*if (MLME_IS_STA(adapter))*/
  1934. rtw_hal_macid_wakeup(adapter, mac_id);
  1935. } else {
  1936. RTW_PRINT(FUNC_ADPT_FMT" invalid macid:%u\n"
  1937. , FUNC_ADPT_ARG(adapter), mac_id);
  1938. rtw_warn_on(1);
  1939. }
  1940. }
  1941. void rtw_sta_mstatus_report(_adapter *adapter)
  1942. {
  1943. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  1944. struct wlan_network *tgt_network = &pmlmepriv->cur_network;
  1945. struct sta_info *psta = NULL;
  1946. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
  1947. psta = rtw_get_stainfo(&adapter->stapriv, tgt_network->network.MacAddress);
  1948. if (psta)
  1949. rtw_sta_mstatus_disc_rpt(adapter, psta->mac_id);
  1950. else {
  1951. RTW_INFO("%s "ADPT_FMT" - mac_addr: "MAC_FMT" psta == NULL\n", __func__, ADPT_ARG(adapter), MAC_ARG(tgt_network->network.MacAddress));
  1952. rtw_warn_on(1);
  1953. }
  1954. }
  1955. }
  1956. void rtw_stadel_event_callback(_adapter *adapter, u8 *pbuf)
  1957. {
  1958. _irqL irqL, irqL2;
  1959. struct sta_info *psta;
  1960. struct wlan_network *pwlan = NULL;
  1961. WLAN_BSSID_EX *pdev_network = NULL;
  1962. u8 *pibss = NULL;
  1963. struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
  1964. struct stadel_event *pstadel = (struct stadel_event *)pbuf;
  1965. struct sta_priv *pstapriv = &adapter->stapriv;
  1966. struct wlan_network *tgt_network = &(pmlmepriv->cur_network);
  1967. struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
  1968. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  1969. RTW_INFO("%s(mac_id=%d)=" MAC_FMT "\n", __func__, pstadel->mac_id, MAC_ARG(pstadel->macaddr));
  1970. rtw_sta_mstatus_disc_rpt(adapter, pstadel->mac_id);
  1971. psta = rtw_get_stainfo(&adapter->stapriv, pstadel->macaddr);
  1972. if (psta == NULL) {
  1973. RTW_INFO("%s(mac_id=%d)=" MAC_FMT " psta == NULL\n", __func__, pstadel->mac_id, MAC_ARG(pstadel->macaddr));
  1974. /*rtw_warn_on(1);*/
  1975. }
  1976. if (psta)
  1977. rtw_wfd_st_switch(psta, 0);
  1978. /* if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) */
  1979. if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
  1980. #ifdef CONFIG_IOCTL_CFG80211
  1981. #ifdef COMPAT_KERNEL_RELEASE
  1982. #elif (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)) || defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
  1983. rtw_cfg80211_indicate_sta_disassoc(adapter, pstadel->macaddr, *(u16 *)pstadel->rsvd);
  1984. #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)) || defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) */
  1985. #endif /* CONFIG_IOCTL_CFG80211 */
  1986. return;
  1987. }
  1988. mlmeext_sta_del_event_callback(adapter);
  1989. _enter_critical_bh(&pmlmepriv->lock, &irqL2);
  1990. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
  1991. u16 reason = *((unsigned short *)(pstadel->rsvd));
  1992. bool roam = _FALSE;
  1993. struct wlan_network *roam_target = NULL;
  1994. #ifdef CONFIG_LAYER2_ROAMING
  1995. #ifdef CONFIG_RTW_80211R
  1996. if (reason == WLAN_REASON_EXPIRATION_CHK && rtw_chk_roam_flags(adapter, RTW_ROAM_ON_EXPIRED))
  1997. pmlmepriv->ftpriv.ft_roam_on_expired = _TRUE;
  1998. else
  1999. pmlmepriv->ftpriv.ft_roam_on_expired = _FALSE;
  2000. #endif
  2001. if (adapter->registrypriv.wifi_spec == 1)
  2002. roam = _FALSE;
  2003. else if (reason == WLAN_REASON_EXPIRATION_CHK && rtw_chk_roam_flags(adapter, RTW_ROAM_ON_EXPIRED))
  2004. roam = _TRUE;
  2005. else if (reason == WLAN_REASON_ACTIVE_ROAM && rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)) {
  2006. roam = _TRUE;
  2007. roam_target = pmlmepriv->roam_network;
  2008. }
  2009. #ifdef CONFIG_INTEL_WIDI
  2010. else if (adapter->mlmepriv.widi_state == INTEL_WIDI_STATE_CONNECTED)
  2011. roam = _TRUE;
  2012. #endif /* CONFIG_INTEL_WIDI */
  2013. if (roam == _TRUE) {
  2014. if (rtw_to_roam(adapter) > 0)
  2015. rtw_dec_to_roam(adapter); /* this stadel_event is caused by roaming, decrease to_roam */
  2016. else if (rtw_to_roam(adapter) == 0)
  2017. rtw_set_to_roam(adapter, adapter->registrypriv.max_roaming_times);
  2018. } else
  2019. rtw_set_to_roam(adapter, 0);
  2020. #endif /* CONFIG_LAYER2_ROAMING */
  2021. rtw_free_uc_swdec_pending_queue(adapter);
  2022. rtw_free_assoc_resources(adapter, 1);
  2023. rtw_free_mlme_priv_ie_data(pmlmepriv);
  2024. _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  2025. /* remove the network entry in scanned_queue */
  2026. pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress);
  2027. if ((pwlan) && (!check_fwstate(pmlmepriv, WIFI_UNDER_WPS))) {
  2028. pwlan->fixed = _FALSE;
  2029. rtw_free_network_nolock(adapter, pwlan);
  2030. }
  2031. _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  2032. rtw_indicate_disconnect(adapter, *(u16 *)pstadel->rsvd, pstadel->locally_generated);
  2033. #ifdef CONFIG_INTEL_WIDI
  2034. if (!rtw_to_roam(adapter))
  2035. process_intel_widi_disconnect(adapter, 1);
  2036. #endif /* CONFIG_INTEL_WIDI */
  2037. _rtw_roaming(adapter, roam_target);
  2038. }
  2039. if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
  2040. check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
  2041. /* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
  2042. rtw_free_stainfo(adapter, psta);
  2043. /* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
  2044. if (adapter->stapriv.asoc_sta_count == 1) { /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
  2045. /* rtw_indicate_disconnect(adapter); */ /* removed@20091105 */
  2046. _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  2047. /* free old ibss network */
  2048. /* pwlan = rtw_find_network(&pmlmepriv->scanned_queue, pstadel->macaddr); */
  2049. pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress);
  2050. if (pwlan) {
  2051. pwlan->fixed = _FALSE;
  2052. rtw_free_network_nolock(adapter, pwlan);
  2053. }
  2054. _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  2055. /* re-create ibss */
  2056. pdev_network = &(adapter->registrypriv.dev_network);
  2057. pibss = adapter->registrypriv.dev_network.MacAddress;
  2058. _rtw_memcpy(pdev_network, &tgt_network->network, get_WLAN_BSSID_EX_sz(&tgt_network->network));
  2059. _rtw_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID));
  2060. _rtw_memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
  2061. rtw_update_registrypriv_dev_network(adapter);
  2062. rtw_generate_random_ibss(pibss);
  2063. if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
  2064. set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
  2065. _clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE);
  2066. }
  2067. if (rtw_create_ibss_cmd(adapter, 0) != _SUCCESS)
  2068. RTW_ERR("rtw_create_ibss_cmd FAIL\n");
  2069. }
  2070. }
  2071. _exit_critical_bh(&pmlmepriv->lock, &irqL2);
  2072. }
  2073. void rtw_cpwm_event_callback(PADAPTER padapter, u8 *pbuf)
  2074. {
  2075. #ifdef CONFIG_LPS_LCLK
  2076. struct reportpwrstate_parm *preportpwrstate;
  2077. #endif
  2078. #ifdef CONFIG_LPS_LCLK
  2079. preportpwrstate = (struct reportpwrstate_parm *)pbuf;
  2080. preportpwrstate->state |= (u8)(adapter_to_pwrctl(padapter)->cpwm_tog + 0x80);
  2081. cpwm_int_hdl(padapter, preportpwrstate);
  2082. #endif
  2083. }
  2084. void rtw_wmm_event_callback(PADAPTER padapter, u8 *pbuf)
  2085. {
  2086. WMMOnAssocRsp(padapter);
  2087. }
  2088. /*
  2089. * rtw_join_timeout_handler - Timeout/failure handler for CMD JoinBss
  2090. */
  2091. void rtw_join_timeout(struct mlme_priv *pmlmepriv)
  2092. {
  2093. _adapter *adapter = container_of(pmlmepriv, _adapter, mlmepriv);
  2094. _irqL irqL;
  2095. #if 0
  2096. if (rtw_is_drv_stopped(adapter)) {
  2097. _rtw_up_sema(&pmlmepriv->assoc_terminate);
  2098. return;
  2099. }
  2100. #endif
  2101. RTW_INFO("%s, fw_state=%x\n", __FUNCTION__, get_fwstate(pmlmepriv));
  2102. if (RTW_CANNOT_RUN(adapter))
  2103. return;
  2104. _enter_critical_bh(&pmlmepriv->lock, &irqL);
  2105. #ifdef CONFIG_LAYER2_ROAMING
  2106. if (rtw_to_roam(adapter) > 0) { /* join timeout caused by roaming */
  2107. while (1) {
  2108. rtw_dec_to_roam(adapter);
  2109. if (rtw_to_roam(adapter) != 0) { /* try another */
  2110. int do_join_r;
  2111. RTW_INFO("%s try another roaming\n", __FUNCTION__);
  2112. do_join_r = rtw_do_join(adapter);
  2113. if (_SUCCESS != do_join_r) {
  2114. RTW_INFO("%s roaming do_join return %d\n", __FUNCTION__ , do_join_r);
  2115. continue;
  2116. }
  2117. break;
  2118. } else {
  2119. #ifdef CONFIG_INTEL_WIDI
  2120. if (adapter->mlmepriv.widi_state == INTEL_WIDI_STATE_ROAMING) {
  2121. _rtw_memset(pmlmepriv->sa_ext, 0x00, L2SDTA_SERVICE_VE_LEN);
  2122. intel_widi_wk_cmd(adapter, INTEL_WIDI_LISTEN_WK, NULL, 0);
  2123. RTW_INFO("change to widi listen\n");
  2124. }
  2125. #endif /* CONFIG_INTEL_WIDI */
  2126. RTW_INFO("%s We've try roaming but fail\n", __FUNCTION__);
  2127. #ifdef CONFIG_RTW_80211R
  2128. rtw_clr_ft_flags(adapter, RTW_FT_SUPPORTED|RTW_FT_OVER_DS_SUPPORTED);
  2129. rtw_reset_ft_status(adapter);
  2130. #endif
  2131. rtw_indicate_disconnect(adapter, 0, _FALSE);
  2132. break;
  2133. }
  2134. }
  2135. } else
  2136. #endif
  2137. {
  2138. rtw_indicate_disconnect(adapter, 0, _FALSE);
  2139. free_scanqueue(pmlmepriv);/* ??? */
  2140. #ifdef CONFIG_IOCTL_CFG80211
  2141. /* indicate disconnect for the case that join_timeout and check_fwstate != FW_LINKED */
  2142. rtw_cfg80211_indicate_disconnect(adapter, 0, _FALSE);
  2143. #endif /* CONFIG_IOCTL_CFG80211 */
  2144. }
  2145. _exit_critical_bh(&pmlmepriv->lock, &irqL);
  2146. #ifdef CONFIG_DRVEXT_MODULE_WSC
  2147. drvext_assoc_fail_indicate(&adapter->drvextpriv);
  2148. #endif
  2149. }
  2150. void rtw_join_timeout_handler(struct timer_list *t) {
  2151. struct mlme_priv *pmlmepriv = from_timer(pmlmepriv, t, assoc_timer);
  2152. rtw_join_timeout(pmlmepriv);
  2153. }
  2154. /*
  2155. * rtw_scan_timeout_handler - Timeout/Faliure handler for CMD SiteSurvey
  2156. * @adapter: pointer to _adapter structure
  2157. */
  2158. void rtw_scan_timeout_handler(struct timer_list *t)
  2159. {
  2160. struct mlme_priv *pmlmepriv = from_timer(pmlmepriv, t, scan_to_timer);
  2161. _adapter *adapter = container_of(pmlmepriv, _adapter, mlmepriv);
  2162. _irqL irqL;
  2163. RTW_INFO(FUNC_ADPT_FMT" fw_state=%x\n", FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv));
  2164. _enter_critical_bh(&pmlmepriv->lock, &irqL);
  2165. _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
  2166. _exit_critical_bh(&pmlmepriv->lock, &irqL);
  2167. #ifdef CONFIG_IOCTL_CFG80211
  2168. rtw_cfg80211_surveydone_event_callback(adapter);
  2169. #endif /* CONFIG_IOCTL_CFG80211 */
  2170. rtw_indicate_scan_done(adapter, _TRUE);
  2171. #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_IOCTL_CFG80211)
  2172. rtw_cfg80211_indicate_scan_done_for_buddy(adapter, _TRUE);
  2173. #endif
  2174. }
  2175. void rtw_mlme_reset_auto_scan_int(_adapter *adapter, u8 *reason)
  2176. {
  2177. struct mlme_priv *mlme = &adapter->mlmepriv;
  2178. struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
  2179. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  2180. u8 u_ch;
  2181. u32 interval_ms = 0xffffffff; /* 0xffffffff: special value to make min() works well, also means no auto scan */
  2182. *reason = RTW_AUTO_SCAN_REASON_UNSPECIFIED;
  2183. rtw_mi_get_ch_setting_union(adapter, &u_ch, NULL, NULL);
  2184. if (hal_chk_bw_cap(adapter, BW_CAP_40M)
  2185. && is_client_associated_to_ap(adapter) == _TRUE
  2186. && u_ch >= 1 && u_ch <= 14
  2187. && adapter->registrypriv.wifi_spec
  2188. /* TODO: AP Connected is 40MHz capability? */
  2189. ) {
  2190. interval_ms = rtw_min(interval_ms, 60 * 1000);
  2191. *reason |= RTW_AUTO_SCAN_REASON_2040_BSS;
  2192. }
  2193. exit:
  2194. if (interval_ms == 0xffffffff)
  2195. interval_ms = 0;
  2196. rtw_mlme_set_auto_scan_int(adapter, interval_ms);
  2197. return;
  2198. }
  2199. void rtw_drv_scan_by_self(_adapter *padapter, u8 reason)
  2200. {
  2201. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  2202. struct rtw_ieee80211_channel ch_for_2040_bss[14] = {
  2203. {1, RTW_IEEE80211_CHAN_PASSIVE_SCAN},
  2204. {2, RTW_IEEE80211_CHAN_PASSIVE_SCAN},
  2205. {3, RTW_IEEE80211_CHAN_PASSIVE_SCAN},
  2206. {4, RTW_IEEE80211_CHAN_PASSIVE_SCAN},
  2207. {5, RTW_IEEE80211_CHAN_PASSIVE_SCAN},
  2208. {6, RTW_IEEE80211_CHAN_PASSIVE_SCAN},
  2209. {7, RTW_IEEE80211_CHAN_PASSIVE_SCAN},
  2210. {8, RTW_IEEE80211_CHAN_PASSIVE_SCAN},
  2211. {9, RTW_IEEE80211_CHAN_PASSIVE_SCAN},
  2212. {10, RTW_IEEE80211_CHAN_PASSIVE_SCAN},
  2213. {11, RTW_IEEE80211_CHAN_PASSIVE_SCAN},
  2214. {12, RTW_IEEE80211_CHAN_PASSIVE_SCAN},
  2215. {13, RTW_IEEE80211_CHAN_PASSIVE_SCAN},
  2216. {14, RTW_IEEE80211_CHAN_PASSIVE_SCAN},
  2217. };
  2218. struct rtw_ieee80211_channel *ch_sel = NULL;
  2219. int ch_num = 0;
  2220. if (rtw_is_scan_deny(padapter))
  2221. goto exit;
  2222. if (!rtw_is_adapter_up(padapter))
  2223. goto exit;
  2224. if (rtw_mi_busy_traffic_check(padapter, _FALSE)) {
  2225. #ifdef CONFIG_LAYER2_ROAMING
  2226. if (rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE) && pmlmepriv->need_to_roam == _TRUE) {
  2227. RTW_INFO("need to roam, don't care BusyTraffic\n");
  2228. } else
  2229. #endif
  2230. {
  2231. RTW_INFO(FUNC_ADPT_FMT" exit BusyTraffic\n", FUNC_ADPT_ARG(padapter));
  2232. goto exit;
  2233. }
  2234. }
  2235. if (check_fwstate(pmlmepriv, WIFI_AP_STATE) && check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
  2236. RTW_INFO(FUNC_ADPT_FMT" WIFI_AP_STATE && WIFI_UNDER_WPS\n", FUNC_ADPT_ARG(padapter));
  2237. goto exit;
  2238. }
  2239. if (check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY | _FW_UNDER_LINKING)) == _TRUE) {
  2240. RTW_INFO(FUNC_ADPT_FMT" _FW_UNDER_SURVEY|_FW_UNDER_LINKING\n", FUNC_ADPT_ARG(padapter));
  2241. goto exit;
  2242. }
  2243. #ifdef CONFIG_CONCURRENT_MODE
  2244. if (rtw_mi_buddy_check_fwstate(padapter, (_FW_UNDER_SURVEY | _FW_UNDER_LINKING | WIFI_UNDER_WPS))) {
  2245. RTW_INFO(FUNC_ADPT_FMT", but buddy_intf is under scanning or linking or wps_phase\n", FUNC_ADPT_ARG(padapter));
  2246. goto exit;
  2247. }
  2248. #endif
  2249. RTW_INFO(FUNC_ADPT_FMT" reason:0x%02x\n", FUNC_ADPT_ARG(padapter), reason);
  2250. /* only for 20/40 BSS */
  2251. if (reason == RTW_AUTO_SCAN_REASON_2040_BSS) {
  2252. ch_sel = ch_for_2040_bss;
  2253. ch_num = 14;
  2254. }
  2255. rtw_set_802_11_bssid_list_scan(padapter, NULL, 0, ch_sel, ch_num);
  2256. exit:
  2257. return;
  2258. }
  2259. static void rtw_auto_scan_handler(_adapter *padapter)
  2260. {
  2261. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  2262. u8 reason = RTW_AUTO_SCAN_REASON_UNSPECIFIED;
  2263. rtw_mlme_reset_auto_scan_int(padapter, &reason);
  2264. #ifdef CONFIG_P2P
  2265. if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
  2266. goto exit;
  2267. #endif
  2268. #ifdef CONFIG_TDLS
  2269. if (padapter->tdlsinfo.link_established == _TRUE)
  2270. goto exit;
  2271. #endif
  2272. if (pmlmepriv->auto_scan_int_ms == 0
  2273. || rtw_get_passing_time_ms(pmlmepriv->scan_start_time) < pmlmepriv->auto_scan_int_ms)
  2274. goto exit;
  2275. rtw_drv_scan_by_self(padapter, reason);
  2276. exit:
  2277. return;
  2278. }
  2279. static u8 is_drv_in_lps(_adapter *adapter)
  2280. {
  2281. u8 is_in_lps = _FALSE;
  2282. #ifdef CONFIG_LPS_LCLK_WD_TIMER /* to avoid leaving lps 32k frequently*/
  2283. if ((adapter_to_pwrctl(adapter)->bFwCurrentInPSMode == _TRUE)
  2284. #ifdef CONFIG_BT_COEXIST
  2285. && (rtw_btcoex_IsBtControlLps(adapter) == _FALSE)
  2286. #endif
  2287. )
  2288. is_in_lps = _TRUE;
  2289. #endif /* CONFIG_LPS_LCLK_WD_TIMER*/
  2290. return is_in_lps;
  2291. }
  2292. void rtw_iface_dynamic_check_timer_handlder(_adapter *adapter)
  2293. {
  2294. #ifdef CONFIG_AP_MODE
  2295. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  2296. #endif /* CONFIG_AP_MODE */
  2297. if (adapter->net_closed == _TRUE)
  2298. return;
  2299. #ifdef CONFIG_LPS_LCLK_WD_TIMER /* to avoid leaving lps 32k frequently*/
  2300. if (is_drv_in_lps(adapter)) {
  2301. u8 bEnterPS;
  2302. linked_status_chk(adapter, 1);
  2303. bEnterPS = traffic_status_watchdog(adapter, 1);
  2304. if (bEnterPS) {
  2305. /* rtw_lps_ctrl_wk_cmd(adapter, LPS_CTRL_ENTER, 1); */
  2306. rtw_hal_dm_watchdog_in_lps(adapter);
  2307. } else {
  2308. /* call rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 1) in traffic_status_watchdog() */
  2309. }
  2310. }
  2311. #endif /* CONFIG_LPS_LCLK_WD_TIMER */
  2312. /* auto site survey */
  2313. rtw_auto_scan_handler(adapter);
  2314. #ifndef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
  2315. #ifdef CONFIG_AP_MODE
  2316. if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
  2317. expire_timeout_chk(adapter);
  2318. #endif
  2319. #endif /* !CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
  2320. #ifdef CONFIG_BR_EXT
  2321. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
  2322. rcu_read_lock();
  2323. #endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) */
  2324. #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
  2325. if (adapter->pnetdev->br_port
  2326. #else /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
  2327. if (rcu_dereference(adapter->pnetdev->rx_handler_data)
  2328. #endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
  2329. && (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE)) {
  2330. /* expire NAT2.5 entry */
  2331. void nat25_db_expire(_adapter *priv);
  2332. nat25_db_expire(adapter);
  2333. if (adapter->pppoe_connection_in_progress > 0)
  2334. adapter->pppoe_connection_in_progress--;
  2335. /* due to rtw_dynamic_check_timer_handlder() is called every 2 seconds */
  2336. if (adapter->pppoe_connection_in_progress > 0)
  2337. adapter->pppoe_connection_in_progress--;
  2338. }
  2339. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
  2340. rcu_read_unlock();
  2341. #endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) */
  2342. #endif /* CONFIG_BR_EXT */
  2343. }
  2344. /*#define DBG_TRAFFIC_STATISTIC*/
  2345. static void collect_traffic_statistics(_adapter *padapter)
  2346. {
  2347. struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
  2348. /*_rtw_memset(&pdvobjpriv->traffic_stat, 0, sizeof(struct rtw_traffic_statistics));*/
  2349. /* Tx bytes reset*/
  2350. pdvobjpriv->traffic_stat.tx_bytes = 0;
  2351. pdvobjpriv->traffic_stat.tx_pkts = 0;
  2352. pdvobjpriv->traffic_stat.tx_drop = 0;
  2353. /* Rx bytes reset*/
  2354. pdvobjpriv->traffic_stat.rx_bytes = 0;
  2355. pdvobjpriv->traffic_stat.rx_pkts = 0;
  2356. pdvobjpriv->traffic_stat.rx_drop = 0;
  2357. rtw_mi_traffic_statistics(padapter);
  2358. /* Calculate throughput in last interval */
  2359. pdvobjpriv->traffic_stat.cur_tx_bytes = pdvobjpriv->traffic_stat.tx_bytes - pdvobjpriv->traffic_stat.last_tx_bytes;
  2360. pdvobjpriv->traffic_stat.cur_rx_bytes = pdvobjpriv->traffic_stat.rx_bytes - pdvobjpriv->traffic_stat.last_rx_bytes;
  2361. pdvobjpriv->traffic_stat.last_tx_bytes = pdvobjpriv->traffic_stat.tx_bytes;
  2362. pdvobjpriv->traffic_stat.last_rx_bytes = pdvobjpriv->traffic_stat.rx_bytes;
  2363. pdvobjpriv->traffic_stat.cur_tx_tp = (u32)(pdvobjpriv->traffic_stat.cur_tx_bytes * 8 / 2 / 1024 / 1024);
  2364. pdvobjpriv->traffic_stat.cur_rx_tp = (u32)(pdvobjpriv->traffic_stat.cur_rx_bytes * 8 / 2 / 1024 / 1024);
  2365. #ifdef DBG_TRAFFIC_STATISTIC
  2366. RTW_INFO("\n========================\n");
  2367. RTW_INFO("cur_tx_bytes:%lld\n", pdvobjpriv->traffic_stat.cur_tx_bytes);
  2368. RTW_INFO("cur_rx_bytes:%lld\n", pdvobjpriv->traffic_stat.cur_rx_bytes);
  2369. RTW_INFO("last_tx_bytes:%lld\n", pdvobjpriv->traffic_stat.last_tx_bytes);
  2370. RTW_INFO("last_rx_bytes:%lld\n", pdvobjpriv->traffic_stat.last_rx_bytes);
  2371. RTW_INFO("cur_tx_tp:%d\n", pdvobjpriv->traffic_stat.cur_tx_tp);
  2372. RTW_INFO("cur_rx_tp:%d\n", pdvobjpriv->traffic_stat.cur_rx_tp);
  2373. #endif
  2374. }
  2375. void rtw_dynamic_check_timer_handlder(struct timer_list *t)
  2376. {
  2377. struct dvobj_priv *pdvobj = from_timer(pdvobj, t, dynamic_chk_timer);
  2378. _adapter *adapter = dvobj_get_primary_adapter(pdvobj);
  2379. #if (MP_DRIVER == 1)
  2380. if (adapter->registrypriv.mp_mode == 1 && adapter->mppriv.mp_dm == 0) { /* for MP ODM dynamic Tx power tracking */
  2381. /* RTW_INFO("%s mp_dm =0 return\n", __func__); */
  2382. goto exit;
  2383. }
  2384. #endif
  2385. if (!adapter)
  2386. goto exit;
  2387. if (!rtw_is_hw_init_completed(adapter))
  2388. goto exit;
  2389. if (RTW_CANNOT_RUN(adapter))
  2390. goto exit;
  2391. collect_traffic_statistics(adapter);
  2392. rtw_mi_dynamic_check_timer_handlder(adapter);
  2393. if (!is_drv_in_lps(adapter))
  2394. rtw_dynamic_chk_wk_cmd(adapter);
  2395. exit:
  2396. _set_timer(&pdvobj->dynamic_chk_timer, 2000);
  2397. }
  2398. #ifdef CONFIG_SET_SCAN_DENY_TIMER
  2399. inline bool rtw_is_scan_deny(_adapter *adapter)
  2400. {
  2401. struct mlme_priv *mlmepriv = &adapter->mlmepriv;
  2402. return (ATOMIC_READ(&mlmepriv->set_scan_deny) != 0) ? _TRUE : _FALSE;
  2403. }
  2404. inline void rtw_clear_scan_deny(_adapter *adapter)
  2405. {
  2406. struct mlme_priv *mlmepriv = &adapter->mlmepriv;
  2407. ATOMIC_SET(&mlmepriv->set_scan_deny, 0);
  2408. if (0)
  2409. RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
  2410. }
  2411. void rtw_set_scan_deny_timer_hdl(struct timer_list *t)
  2412. {
  2413. struct mlme_priv *pmlmepriv = from_timer(pmlmepriv, t, set_scan_deny_timer);
  2414. _adapter *adapter = container_of(pmlmepriv, _adapter, mlmepriv);
  2415. rtw_clear_scan_deny(adapter);
  2416. }
  2417. void rtw_set_scan_deny(_adapter *adapter, u32 ms)
  2418. {
  2419. struct mlme_priv *mlmepriv = &adapter->mlmepriv;
  2420. if (0)
  2421. RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
  2422. ATOMIC_SET(&mlmepriv->set_scan_deny, 1);
  2423. _set_timer(&mlmepriv->set_scan_deny_timer, ms);
  2424. }
  2425. #endif
  2426. #ifdef CONFIG_LAYER2_ROAMING
  2427. /*
  2428. * Select a new roaming candidate from the original @param candidate and @param competitor
  2429. * @return _TRUE: candidate is updated
  2430. * @return _FALSE: candidate is not updated
  2431. */
  2432. static int rtw_check_roaming_candidate(struct mlme_priv *mlme
  2433. , struct wlan_network **candidate, struct wlan_network *competitor)
  2434. {
  2435. int updated = _FALSE;
  2436. _adapter *adapter = container_of(mlme, _adapter, mlmepriv);
  2437. #ifdef CONFIG_RTW_80211R
  2438. ft_priv *pftpriv = &mlme->ftpriv;
  2439. u32 mdie_len = 0;
  2440. u8 *ptmp = NULL;
  2441. #endif
  2442. if (is_same_ess(&competitor->network, &mlme->cur_network.network) == _FALSE)
  2443. goto exit;
  2444. if (rtw_is_desired_network(adapter, competitor) == _FALSE)
  2445. goto exit;
  2446. #ifdef CONFIG_LAYER2_ROAMING
  2447. if (mlme->need_to_roam == _FALSE)
  2448. goto exit;
  2449. #endif
  2450. #ifdef CONFIG_RTW_80211R
  2451. if (rtw_chk_ft_flags(adapter, RTW_FT_SUPPORTED)) {
  2452. ptmp = rtw_get_ie(&competitor->network.IEs[12], _MDIE_, &mdie_len, competitor->network.IELength-12);
  2453. if (ptmp) {
  2454. if (!_rtw_memcmp(&pftpriv->mdid, ptmp+2, 2))
  2455. goto exit;
  2456. /*The candidate don't support over-the-DS*/
  2457. if (rtw_chk_ft_flags(adapter, RTW_FT_STA_OVER_DS_SUPPORTED)) {
  2458. if ((rtw_chk_ft_flags(adapter, RTW_FT_OVER_DS_SUPPORTED) && !(*(ptmp+4) & 0x01)) ||
  2459. (!rtw_chk_ft_flags(adapter, RTW_FT_OVER_DS_SUPPORTED) && (*(ptmp+4) & 0x01))) {
  2460. RTW_INFO("FT: ignore the candidate(" MAC_FMT ") for over-the-DS\n", MAC_ARG(competitor->network.MacAddress));
  2461. rtw_clr_ft_flags(adapter, RTW_FT_OVER_DS_SUPPORTED);
  2462. goto exit;
  2463. }
  2464. }
  2465. } else
  2466. goto exit;
  2467. }
  2468. #endif
  2469. RTW_INFO("roam candidate:%s %s("MAC_FMT", ch%3u) rssi:%d, age:%5d\n",
  2470. (competitor == mlme->cur_network_scanned) ? "*" : " " ,
  2471. competitor->network.Ssid.Ssid,
  2472. MAC_ARG(competitor->network.MacAddress),
  2473. competitor->network.Configuration.DSConfig,
  2474. (int)competitor->network.Rssi,
  2475. rtw_get_passing_time_ms(competitor->last_scanned)
  2476. );
  2477. /* got specific addr to roam */
  2478. if (!is_zero_mac_addr(mlme->roam_tgt_addr)) {
  2479. if (_rtw_memcmp(mlme->roam_tgt_addr, competitor->network.MacAddress, ETH_ALEN) == _TRUE)
  2480. goto update;
  2481. else
  2482. goto exit;
  2483. }
  2484. #if 1
  2485. if (rtw_get_passing_time_ms((u32)competitor->last_scanned) >= mlme->roam_scanr_exp_ms)
  2486. goto exit;
  2487. if (competitor->network.Rssi - mlme->cur_network_scanned->network.Rssi < mlme->roam_rssi_diff_th)
  2488. goto exit;
  2489. if (*candidate != NULL && (*candidate)->network.Rssi >= competitor->network.Rssi)
  2490. goto exit;
  2491. #else
  2492. goto exit;
  2493. #endif
  2494. update:
  2495. *candidate = competitor;
  2496. updated = _TRUE;
  2497. exit:
  2498. return updated;
  2499. }
  2500. int rtw_select_roaming_candidate(struct mlme_priv *mlme)
  2501. {
  2502. _irqL irqL;
  2503. int ret = _FAIL;
  2504. _list *phead;
  2505. _adapter *adapter;
  2506. _queue *queue = &(mlme->scanned_queue);
  2507. struct wlan_network *pnetwork = NULL;
  2508. struct wlan_network *candidate = NULL;
  2509. u8 bSupportAntDiv = _FALSE;
  2510. if (mlme->cur_network_scanned == NULL) {
  2511. rtw_warn_on(1);
  2512. goto exit;
  2513. }
  2514. _enter_critical_bh(&(mlme->scanned_queue.lock), &irqL);
  2515. phead = get_list_head(queue);
  2516. adapter = (_adapter *)mlme->nic_hdl;
  2517. mlme->pscanned = get_next(phead);
  2518. while (!rtw_end_of_queue_search(phead, mlme->pscanned)) {
  2519. pnetwork = LIST_CONTAINOR(mlme->pscanned, struct wlan_network, list);
  2520. if (pnetwork == NULL) {
  2521. ret = _FAIL;
  2522. goto exit;
  2523. }
  2524. mlme->pscanned = get_next(mlme->pscanned);
  2525. if (0)
  2526. RTW_INFO("%s("MAC_FMT", ch%u) rssi:%d\n"
  2527. , pnetwork->network.Ssid.Ssid
  2528. , MAC_ARG(pnetwork->network.MacAddress)
  2529. , pnetwork->network.Configuration.DSConfig
  2530. , (int)pnetwork->network.Rssi);
  2531. rtw_check_roaming_candidate(mlme, &candidate, pnetwork);
  2532. }
  2533. if (candidate == NULL) {
  2534. RTW_INFO("%s: return _FAIL(candidate == NULL)\n", __FUNCTION__);
  2535. ret = _FAIL;
  2536. goto exit;
  2537. } else {
  2538. RTW_INFO("%s: candidate: %s("MAC_FMT", ch:%u)\n", __FUNCTION__,
  2539. candidate->network.Ssid.Ssid, MAC_ARG(candidate->network.MacAddress),
  2540. candidate->network.Configuration.DSConfig);
  2541. mlme->roam_network = candidate;
  2542. if (_rtw_memcmp(candidate->network.MacAddress, mlme->roam_tgt_addr, ETH_ALEN) == _TRUE)
  2543. _rtw_memset(mlme->roam_tgt_addr, 0, ETH_ALEN);
  2544. }
  2545. ret = _SUCCESS;
  2546. exit:
  2547. _exit_critical_bh(&(mlme->scanned_queue.lock), &irqL);
  2548. return ret;
  2549. }
  2550. #endif /* CONFIG_LAYER2_ROAMING */
  2551. /*
  2552. * Select a new join candidate from the original @param candidate and @param competitor
  2553. * @return _TRUE: candidate is updated
  2554. * @return _FALSE: candidate is not updated
  2555. */
  2556. static int rtw_check_join_candidate(struct mlme_priv *mlme
  2557. , struct wlan_network **candidate, struct wlan_network *competitor)
  2558. {
  2559. int updated = _FALSE;
  2560. _adapter *adapter = container_of(mlme, _adapter, mlmepriv);
  2561. /* check bssid, if needed */
  2562. if (mlme->assoc_by_bssid == _TRUE) {
  2563. if (_rtw_memcmp(competitor->network.MacAddress, mlme->assoc_bssid, ETH_ALEN) == _FALSE)
  2564. goto exit;
  2565. }
  2566. /* check ssid, if needed */
  2567. if (mlme->assoc_ssid.Ssid[0] && mlme->assoc_ssid.SsidLength) {
  2568. if (competitor->network.Ssid.SsidLength != mlme->assoc_ssid.SsidLength
  2569. || _rtw_memcmp(competitor->network.Ssid.Ssid, mlme->assoc_ssid.Ssid, mlme->assoc_ssid.SsidLength) == _FALSE
  2570. )
  2571. goto exit;
  2572. }
  2573. if (rtw_is_desired_network(adapter, competitor) == _FALSE)
  2574. goto exit;
  2575. #ifdef CONFIG_LAYER2_ROAMING
  2576. if (rtw_to_roam(adapter) > 0) {
  2577. if (rtw_get_passing_time_ms((u32)competitor->last_scanned) >= mlme->roam_scanr_exp_ms
  2578. || is_same_ess(&competitor->network, &mlme->cur_network.network) == _FALSE
  2579. )
  2580. goto exit;
  2581. }
  2582. #endif
  2583. if (*candidate == NULL || (*candidate)->network.Rssi < competitor->network.Rssi) {
  2584. *candidate = competitor;
  2585. updated = _TRUE;
  2586. }
  2587. if (updated) {
  2588. RTW_INFO("[by_bssid:%u][assoc_ssid:%s][to_roam:%u] "
  2589. "new candidate: %s("MAC_FMT", ch%u) rssi:%d\n",
  2590. mlme->assoc_by_bssid,
  2591. mlme->assoc_ssid.Ssid,
  2592. rtw_to_roam(adapter),
  2593. (*candidate)->network.Ssid.Ssid,
  2594. MAC_ARG((*candidate)->network.MacAddress),
  2595. (*candidate)->network.Configuration.DSConfig,
  2596. (int)(*candidate)->network.Rssi
  2597. );
  2598. }
  2599. exit:
  2600. return updated;
  2601. }
  2602. /*
  2603. Calling context:
  2604. The caller of the sub-routine will be in critical section...
  2605. The caller must hold the following spinlock
  2606. pmlmepriv->lock
  2607. */
  2608. int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv)
  2609. {
  2610. _irqL irqL;
  2611. int ret;
  2612. _list *phead;
  2613. _adapter *adapter;
  2614. _queue *queue = &(pmlmepriv->scanned_queue);
  2615. struct wlan_network *pnetwork = NULL;
  2616. struct wlan_network *candidate = NULL;
  2617. u8 bSupportAntDiv = _FALSE;
  2618. adapter = (_adapter *)pmlmepriv->nic_hdl;
  2619. _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  2620. #ifdef CONFIG_LAYER2_ROAMING
  2621. if (pmlmepriv->roam_network) {
  2622. candidate = pmlmepriv->roam_network;
  2623. pmlmepriv->roam_network = NULL;
  2624. goto candidate_exist;
  2625. }
  2626. #endif
  2627. phead = get_list_head(queue);
  2628. pmlmepriv->pscanned = get_next(phead);
  2629. while (!rtw_end_of_queue_search(phead, pmlmepriv->pscanned)) {
  2630. pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
  2631. if (pnetwork == NULL) {
  2632. ret = _FAIL;
  2633. goto exit;
  2634. }
  2635. pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
  2636. if (0)
  2637. RTW_INFO("%s("MAC_FMT", ch%u) rssi:%d\n"
  2638. , pnetwork->network.Ssid.Ssid
  2639. , MAC_ARG(pnetwork->network.MacAddress)
  2640. , pnetwork->network.Configuration.DSConfig
  2641. , (int)pnetwork->network.Rssi);
  2642. rtw_check_join_candidate(pmlmepriv, &candidate, pnetwork);
  2643. }
  2644. if (candidate == NULL) {
  2645. RTW_INFO("%s: return _FAIL(candidate == NULL)\n", __FUNCTION__);
  2646. #ifdef CONFIG_WOWLAN
  2647. _clr_fwstate_(pmlmepriv, _FW_LINKED | _FW_UNDER_LINKING);
  2648. #endif
  2649. ret = _FAIL;
  2650. goto exit;
  2651. } else {
  2652. RTW_INFO("%s: candidate: %s("MAC_FMT", ch:%u)\n", __FUNCTION__,
  2653. candidate->network.Ssid.Ssid, MAC_ARG(candidate->network.MacAddress),
  2654. candidate->network.Configuration.DSConfig);
  2655. goto candidate_exist;
  2656. }
  2657. candidate_exist:
  2658. /* check for situation of _FW_LINKED */
  2659. if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
  2660. RTW_INFO("%s: _FW_LINKED while ask_for_joinbss!!!\n", __FUNCTION__);
  2661. #if 0 /* for WPA/WPA2 authentication, wpa_supplicant will expect authentication from AP, it is needed to reconnect AP... */
  2662. if (is_same_network(&pmlmepriv->cur_network.network, &candidate->network)) {
  2663. RTW_INFO("%s: _FW_LINKED and is same network, it needn't join again\n", __FUNCTION__);
  2664. rtw_indicate_connect(adapter);/* rtw_indicate_connect again */
  2665. ret = 2;
  2666. goto exit;
  2667. } else
  2668. #endif
  2669. {
  2670. rtw_disassoc_cmd(adapter, 0, 0);
  2671. rtw_indicate_disconnect(adapter, 0, _FALSE);
  2672. rtw_free_assoc_resources(adapter, 0);
  2673. }
  2674. }
  2675. #ifdef CONFIG_ANTENNA_DIVERSITY
  2676. rtw_hal_get_def_var(adapter, HAL_DEF_IS_SUPPORT_ANT_DIV, &(bSupportAntDiv));
  2677. if (_TRUE == bSupportAntDiv) {
  2678. u8 CurrentAntenna;
  2679. rtw_hal_get_odm_var(adapter, HAL_ODM_ANTDIV_SELECT, &(CurrentAntenna), NULL);
  2680. RTW_INFO("#### Opt_Ant_(%s) , cur_Ant(%s)\n",
  2681. (MAIN_ANT == candidate->network.PhyInfo.Optimum_antenna) ? "MAIN_ANT" : "AUX_ANT",
  2682. (MAIN_ANT == CurrentAntenna) ? "MAIN_ANT" : "AUX_ANT"
  2683. );
  2684. }
  2685. #endif
  2686. set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
  2687. ret = rtw_joinbss_cmd(adapter, candidate);
  2688. exit:
  2689. _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  2690. return ret;
  2691. }
  2692. sint rtw_set_auth(_adapter *adapter, struct security_priv *psecuritypriv)
  2693. {
  2694. struct cmd_obj *pcmd;
  2695. struct setauth_parm *psetauthparm;
  2696. struct cmd_priv *pcmdpriv = &(adapter->cmdpriv);
  2697. sint res = _SUCCESS;
  2698. pcmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
  2699. if (pcmd == NULL) {
  2700. res = _FAIL; /* try again */
  2701. goto exit;
  2702. }
  2703. psetauthparm = (struct setauth_parm *)rtw_zmalloc(sizeof(struct setauth_parm));
  2704. if (psetauthparm == NULL) {
  2705. rtw_mfree((unsigned char *)pcmd, sizeof(struct cmd_obj));
  2706. res = _FAIL;
  2707. goto exit;
  2708. }
  2709. _rtw_memset(psetauthparm, 0, sizeof(struct setauth_parm));
  2710. psetauthparm->mode = (unsigned char)psecuritypriv->dot11AuthAlgrthm;
  2711. pcmd->cmdcode = _SetAuth_CMD_;
  2712. pcmd->parmbuf = (unsigned char *)psetauthparm;
  2713. pcmd->cmdsz = (sizeof(struct setauth_parm));
  2714. pcmd->rsp = NULL;
  2715. pcmd->rspsz = 0;
  2716. _rtw_init_listhead(&pcmd->list);
  2717. res = rtw_enqueue_cmd(pcmdpriv, pcmd);
  2718. exit:
  2719. return res;
  2720. }
  2721. sint rtw_set_key(_adapter *adapter, struct security_priv *psecuritypriv, sint keyid, u8 set_tx, bool enqueue)
  2722. {
  2723. u8 keylen;
  2724. struct cmd_obj *pcmd;
  2725. struct setkey_parm *psetkeyparm;
  2726. struct cmd_priv *pcmdpriv = &(adapter->cmdpriv);
  2727. struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
  2728. sint res = _SUCCESS;
  2729. psetkeyparm = (struct setkey_parm *)rtw_zmalloc(sizeof(struct setkey_parm));
  2730. if (psetkeyparm == NULL) {
  2731. res = _FAIL;
  2732. goto exit;
  2733. }
  2734. _rtw_memset(psetkeyparm, 0, sizeof(struct setkey_parm));
  2735. if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
  2736. psetkeyparm->algorithm = (unsigned char)psecuritypriv->dot118021XGrpPrivacy;
  2737. } else {
  2738. psetkeyparm->algorithm = (u8)psecuritypriv->dot11PrivacyAlgrthm;
  2739. }
  2740. psetkeyparm->keyid = (u8)keyid;/* 0~3 */
  2741. psetkeyparm->set_tx = set_tx;
  2742. if (is_wep_enc(psetkeyparm->algorithm))
  2743. adapter->securitypriv.key_mask |= BIT(psetkeyparm->keyid);
  2744. RTW_INFO("==> rtw_set_key algorithm(%x),keyid(%x),key_mask(%x)\n", psetkeyparm->algorithm, psetkeyparm->keyid, adapter->securitypriv.key_mask);
  2745. switch (psetkeyparm->algorithm) {
  2746. case _WEP40_:
  2747. keylen = 5;
  2748. _rtw_memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen);
  2749. break;
  2750. case _WEP104_:
  2751. keylen = 13;
  2752. _rtw_memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen);
  2753. break;
  2754. case _TKIP_:
  2755. keylen = 16;
  2756. _rtw_memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
  2757. psetkeyparm->grpkey = 1;
  2758. break;
  2759. case _AES_:
  2760. keylen = 16;
  2761. _rtw_memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
  2762. psetkeyparm->grpkey = 1;
  2763. break;
  2764. default:
  2765. res = _FAIL;
  2766. rtw_mfree((unsigned char *)psetkeyparm, sizeof(struct setkey_parm));
  2767. goto exit;
  2768. }
  2769. if (enqueue) {
  2770. pcmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
  2771. if (pcmd == NULL) {
  2772. rtw_mfree((unsigned char *)psetkeyparm, sizeof(struct setkey_parm));
  2773. res = _FAIL; /* try again */
  2774. goto exit;
  2775. }
  2776. pcmd->cmdcode = _SetKey_CMD_;
  2777. pcmd->parmbuf = (u8 *)psetkeyparm;
  2778. pcmd->cmdsz = (sizeof(struct setkey_parm));
  2779. pcmd->rsp = NULL;
  2780. pcmd->rspsz = 0;
  2781. _rtw_init_listhead(&pcmd->list);
  2782. /* _rtw_init_sema(&(pcmd->cmd_sem), 0); */
  2783. res = rtw_enqueue_cmd(pcmdpriv, pcmd);
  2784. } else {
  2785. setkey_hdl(adapter, (u8 *)psetkeyparm);
  2786. rtw_mfree((u8 *) psetkeyparm, sizeof(struct setkey_parm));
  2787. }
  2788. exit:
  2789. return res;
  2790. }
  2791. /* adjust IEs for rtw_joinbss_cmd in WMM */
  2792. int rtw_restruct_wmm_ie(_adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len, uint initial_out_len)
  2793. {
  2794. unsigned int ielength = 0;
  2795. unsigned int i, j;
  2796. i = 12; /* after the fixed IE */
  2797. while (i < in_len) {
  2798. ielength = initial_out_len;
  2799. if (in_ie[i] == 0xDD && in_ie[i + 2] == 0x00 && in_ie[i + 3] == 0x50 && in_ie[i + 4] == 0xF2 && in_ie[i + 5] == 0x02 && i + 5 < in_len) { /* WMM element ID and OUI */
  2800. /* Append WMM IE to the last index of out_ie */
  2801. #if 0
  2802. for (j = i; j < i + (in_ie[i + 1] + 2); j++) {
  2803. out_ie[ielength] = in_ie[j];
  2804. ielength++;
  2805. }
  2806. out_ie[initial_out_len + 8] = 0x00; /* force the QoS Info Field to be zero */
  2807. #endif
  2808. for (j = i; j < i + 9; j++) {
  2809. out_ie[ielength] = in_ie[j];
  2810. ielength++;
  2811. }
  2812. out_ie[initial_out_len + 1] = 0x07;
  2813. out_ie[initial_out_len + 6] = 0x00;
  2814. out_ie[initial_out_len + 8] = 0x00;
  2815. break;
  2816. }
  2817. i += (in_ie[i + 1] + 2); /* to the next IE element */
  2818. }
  2819. return ielength;
  2820. }
  2821. /*
  2822. * Ported from 8185: IsInPreAuthKeyList(). (Renamed from SecIsInPreAuthKeyList(), 2006-10-13.)
  2823. * Added by Annie, 2006-05-07.
  2824. *
  2825. * Search by BSSID,
  2826. * Return Value:
  2827. * -1 :if there is no pre-auth key in the table
  2828. * >=0 :if there is pre-auth key, and return the entry id
  2829. *
  2830. * */
  2831. static int SecIsInPMKIDList(_adapter *Adapter, u8 *bssid)
  2832. {
  2833. struct security_priv *psecuritypriv = &Adapter->securitypriv;
  2834. int i = 0;
  2835. do {
  2836. if ((psecuritypriv->PMKIDList[i].bUsed) &&
  2837. (_rtw_memcmp(psecuritypriv->PMKIDList[i].Bssid, bssid, ETH_ALEN) == _TRUE))
  2838. break;
  2839. else {
  2840. i++;
  2841. /* continue; */
  2842. }
  2843. } while (i < NUM_PMKID_CACHE);
  2844. if (i == NUM_PMKID_CACHE) {
  2845. i = -1;/* Could not find. */
  2846. } else {
  2847. /* There is one Pre-Authentication Key for the specific BSSID. */
  2848. }
  2849. return i;
  2850. }
  2851. /*
  2852. * Check the RSN IE length
  2853. * If the RSN IE length <= 20, the RSN IE didn't include the PMKID information
  2854. * 0-11th element in the array are the fixed IE
  2855. * 12th element in the array is the IE
  2856. * 13th element in the array is the IE length
  2857. * */
  2858. static int rtw_append_pmkid(_adapter *adapter, int iEntry, u8 *ie, uint ie_len)
  2859. {
  2860. struct security_priv *sec = &adapter->securitypriv;
  2861. if (ie[13] > 20) {
  2862. int i;
  2863. u16 pmkid_cnt = RTW_GET_LE16(ie + 14 + 20);
  2864. if (pmkid_cnt == 1 && _rtw_memcmp(ie + 14 + 20 + 2, &sec->PMKIDList[iEntry].PMKID, 16)) {
  2865. RTW_INFO(FUNC_ADPT_FMT" has carried the same PMKID:"KEY_FMT"\n"
  2866. , FUNC_ADPT_ARG(adapter), KEY_ARG(&sec->PMKIDList[iEntry].PMKID));
  2867. goto exit;
  2868. }
  2869. RTW_INFO(FUNC_ADPT_FMT" remove original PMKID, count:%u\n"
  2870. , FUNC_ADPT_ARG(adapter), pmkid_cnt);
  2871. for (i = 0; i < pmkid_cnt; i++)
  2872. RTW_INFO(" "KEY_FMT"\n", KEY_ARG(ie + 14 + 20 + 2 + i * 16));
  2873. ie_len -= 2 + pmkid_cnt * 16;
  2874. ie[13] = 20;
  2875. }
  2876. if (ie[13] <= 20) {
  2877. /* The RSN IE didn't include the PMK ID, append the PMK information */
  2878. RTW_INFO(FUNC_ADPT_FMT" append PMKID:"KEY_FMT"\n"
  2879. , FUNC_ADPT_ARG(adapter), KEY_ARG(&sec->PMKIDList[iEntry].PMKID));
  2880. RTW_PUT_LE16(&ie[ie_len], 1);
  2881. ie_len += 2;
  2882. _rtw_memcpy(&ie[ie_len], &sec->PMKIDList[iEntry].PMKID, 16);
  2883. ie_len += 16;
  2884. ie[13] += 18;/* PMKID length = 2+16 */
  2885. }
  2886. exit:
  2887. return ie_len;
  2888. }
  2889. static int rtw_remove_pmkid(_adapter *adapter, u8 *ie, uint ie_len)
  2890. {
  2891. struct security_priv *sec = &adapter->securitypriv;
  2892. int i;
  2893. u16 pmkid_cnt = RTW_GET_LE16(ie + 14 + 20);
  2894. if (ie[13] <= 20)
  2895. goto exit;
  2896. RTW_INFO(FUNC_ADPT_FMT" remove original PMKID, count:%u\n"
  2897. , FUNC_ADPT_ARG(adapter), pmkid_cnt);
  2898. for (i = 0; i < pmkid_cnt; i++)
  2899. RTW_INFO(" "KEY_FMT"\n", KEY_ARG(ie + 14 + 20 + 2 + i * 16));
  2900. ie_len -= 2 + pmkid_cnt * 16;
  2901. ie[13] = 20;
  2902. exit:
  2903. return ie_len;
  2904. }
  2905. sint rtw_restruct_sec_ie(_adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len)
  2906. {
  2907. u8 authmode = 0x0, securitytype, match;
  2908. u8 sec_ie[255], uncst_oui[4], bkup_ie[255];
  2909. u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01};
  2910. uint ielength, cnt, remove_cnt;
  2911. int iEntry;
  2912. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  2913. struct security_priv *psecuritypriv = &adapter->securitypriv;
  2914. uint ndisauthmode = psecuritypriv->ndisauthtype;
  2915. uint ndissecuritytype = psecuritypriv->ndisencryptstatus;
  2916. /* copy fixed ie only */
  2917. _rtw_memcpy(out_ie, in_ie, 12);
  2918. ielength = 12;
  2919. if ((ndisauthmode == Ndis802_11AuthModeWPA) || (ndisauthmode == Ndis802_11AuthModeWPAPSK))
  2920. authmode = _WPA_IE_ID_;
  2921. if ((ndisauthmode == Ndis802_11AuthModeWPA2) || (ndisauthmode == Ndis802_11AuthModeWPA2PSK))
  2922. authmode = _WPA2_IE_ID_;
  2923. if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
  2924. _rtw_memcpy(out_ie + ielength, psecuritypriv->wps_ie, psecuritypriv->wps_ie_len);
  2925. ielength += psecuritypriv->wps_ie_len;
  2926. } else if ((authmode == _WPA_IE_ID_) || (authmode == _WPA2_IE_ID_)) {
  2927. /* copy RSN or SSN */
  2928. _rtw_memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0], psecuritypriv->supplicant_ie[1] + 2);
  2929. /* debug for CONFIG_IEEE80211W
  2930. {
  2931. int jj;
  2932. printk("supplicant_ie_length=%d &&&&&&&&&&&&&&&&&&&\n", psecuritypriv->supplicant_ie[1]+2);
  2933. for(jj=0; jj < psecuritypriv->supplicant_ie[1]+2; jj++)
  2934. printk(" %02x ", psecuritypriv->supplicant_ie[jj]);
  2935. printk("\n");
  2936. }*/
  2937. ielength += psecuritypriv->supplicant_ie[1] + 2;
  2938. rtw_report_sec_ie(adapter, authmode, psecuritypriv->supplicant_ie);
  2939. #ifdef CONFIG_DRVEXT_MODULE
  2940. drvext_report_sec_ie(&adapter->drvextpriv, authmode, sec_ie);
  2941. #endif
  2942. }
  2943. iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid);
  2944. if (iEntry < 0) {
  2945. if (authmode == _WPA2_IE_ID_)
  2946. ielength = rtw_remove_pmkid(adapter, out_ie, ielength);
  2947. } else {
  2948. if (authmode == _WPA2_IE_ID_)
  2949. ielength = rtw_append_pmkid(adapter, iEntry, out_ie, ielength);
  2950. }
  2951. return ielength;
  2952. }
  2953. void rtw_init_registrypriv_dev_network(_adapter *adapter)
  2954. {
  2955. struct registry_priv *pregistrypriv = &adapter->registrypriv;
  2956. WLAN_BSSID_EX *pdev_network = &pregistrypriv->dev_network;
  2957. u8 *myhwaddr = adapter_mac_addr(adapter);
  2958. _rtw_memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN);
  2959. _rtw_memcpy(&pdev_network->Ssid, &pregistrypriv->ssid, sizeof(NDIS_802_11_SSID));
  2960. pdev_network->Configuration.Length = sizeof(NDIS_802_11_CONFIGURATION);
  2961. pdev_network->Configuration.BeaconPeriod = 100;
  2962. pdev_network->Configuration.FHConfig.Length = 0;
  2963. pdev_network->Configuration.FHConfig.HopPattern = 0;
  2964. pdev_network->Configuration.FHConfig.HopSet = 0;
  2965. pdev_network->Configuration.FHConfig.DwellTime = 0;
  2966. }
  2967. void rtw_update_registrypriv_dev_network(_adapter *adapter)
  2968. {
  2969. int sz = 0;
  2970. struct registry_priv *pregistrypriv = &adapter->registrypriv;
  2971. WLAN_BSSID_EX *pdev_network = &pregistrypriv->dev_network;
  2972. struct security_priv *psecuritypriv = &adapter->securitypriv;
  2973. struct wlan_network *cur_network = &adapter->mlmepriv.cur_network;
  2974. /* struct xmit_priv *pxmitpriv = &adapter->xmitpriv; */
  2975. struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
  2976. #if 0
  2977. pxmitpriv->vcs_setting = pregistrypriv->vrtl_carrier_sense;
  2978. pxmitpriv->vcs = pregistrypriv->vcs_type;
  2979. pxmitpriv->vcs_type = pregistrypriv->vcs_type;
  2980. /* pxmitpriv->rts_thresh = pregistrypriv->rts_thresh; */
  2981. pxmitpriv->frag_len = pregistrypriv->frag_thresh;
  2982. adapter->qospriv.qos_option = pregistrypriv->wmm_enable;
  2983. #endif
  2984. pdev_network->Privacy = (psecuritypriv->dot11PrivacyAlgrthm > 0 ? 1 : 0) ; /* adhoc no 802.1x */
  2985. pdev_network->Rssi = 0;
  2986. switch (pregistrypriv->wireless_mode) {
  2987. case WIRELESS_11B:
  2988. pdev_network->NetworkTypeInUse = (Ndis802_11DS);
  2989. break;
  2990. case WIRELESS_11G:
  2991. case WIRELESS_11BG:
  2992. case WIRELESS_11_24N:
  2993. case WIRELESS_11G_24N:
  2994. case WIRELESS_11BG_24N:
  2995. pdev_network->NetworkTypeInUse = (Ndis802_11OFDM24);
  2996. break;
  2997. case WIRELESS_11A:
  2998. case WIRELESS_11A_5N:
  2999. pdev_network->NetworkTypeInUse = (Ndis802_11OFDM5);
  3000. break;
  3001. case WIRELESS_11ABGN:
  3002. if (pregistrypriv->channel > 14)
  3003. pdev_network->NetworkTypeInUse = (Ndis802_11OFDM5);
  3004. else
  3005. pdev_network->NetworkTypeInUse = (Ndis802_11OFDM24);
  3006. break;
  3007. default:
  3008. /* TODO */
  3009. break;
  3010. }
  3011. pdev_network->Configuration.DSConfig = (pregistrypriv->channel);
  3012. if (cur_network->network.InfrastructureMode == Ndis802_11IBSS) {
  3013. pdev_network->Configuration.ATIMWindow = (0);
  3014. if (pmlmeext->cur_channel != 0)
  3015. pdev_network->Configuration.DSConfig = pmlmeext->cur_channel;
  3016. else
  3017. pdev_network->Configuration.DSConfig = 1;
  3018. }
  3019. pdev_network->InfrastructureMode = (cur_network->network.InfrastructureMode);
  3020. /* 1. Supported rates */
  3021. /* 2. IE */
  3022. /* rtw_set_supported_rate(pdev_network->SupportedRates, pregistrypriv->wireless_mode) ; */ /* will be called in rtw_generate_ie */
  3023. sz = rtw_generate_ie(pregistrypriv);
  3024. pdev_network->IELength = sz;
  3025. pdev_network->Length = get_WLAN_BSSID_EX_sz((WLAN_BSSID_EX *)pdev_network);
  3026. /* notes: translate IELength & Length after assign the Length to cmdsz in createbss_cmd(); */
  3027. /* pdev_network->IELength = cpu_to_le32(sz); */
  3028. }
  3029. void rtw_get_encrypt_decrypt_from_registrypriv(_adapter *adapter)
  3030. {
  3031. }
  3032. /* the fucntion is at passive_level */
  3033. void rtw_joinbss_reset(_adapter *padapter)
  3034. {
  3035. u8 threshold;
  3036. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  3037. /* todo: if you want to do something io/reg/hw setting before join_bss, please add code here */
  3038. #ifdef CONFIG_80211N_HT
  3039. struct ht_priv *phtpriv = &pmlmepriv->htpriv;
  3040. pmlmepriv->num_FortyMHzIntolerant = 0;
  3041. pmlmepriv->num_sta_no_ht = 0;
  3042. phtpriv->ampdu_enable = _FALSE;/* reset to disabled */
  3043. #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI)
  3044. /* TH=1 => means that invalidate usb rx aggregation */
  3045. /* TH=0 => means that validate usb rx aggregation, use init value. */
  3046. if (phtpriv->ht_option) {
  3047. if (padapter->registrypriv.wifi_spec == 1)
  3048. threshold = 1;
  3049. else
  3050. threshold = 0;
  3051. rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
  3052. } else {
  3053. threshold = 1;
  3054. rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
  3055. }
  3056. #endif/* #if defined( CONFIG_USB_HCI) || defined (CONFIG_SDIO_HCI) */
  3057. #endif/* #ifdef CONFIG_80211N_HT */
  3058. }
  3059. #ifdef CONFIG_80211N_HT
  3060. void rtw_ht_use_default_setting(_adapter *padapter)
  3061. {
  3062. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  3063. struct ht_priv *phtpriv = &pmlmepriv->htpriv;
  3064. struct registry_priv *pregistrypriv = &padapter->registrypriv;
  3065. BOOLEAN bHwLDPCSupport = _FALSE, bHwSTBCSupport = _FALSE;
  3066. #ifdef CONFIG_BEAMFORMING
  3067. BOOLEAN bHwSupportBeamformer = _FALSE, bHwSupportBeamformee = _FALSE;
  3068. #endif /* CONFIG_BEAMFORMING */
  3069. if (pregistrypriv->wifi_spec)
  3070. phtpriv->bss_coexist = 1;
  3071. else
  3072. phtpriv->bss_coexist = 0;
  3073. phtpriv->sgi_40m = TEST_FLAG(pregistrypriv->short_gi, BIT1) ? _TRUE : _FALSE;
  3074. phtpriv->sgi_20m = TEST_FLAG(pregistrypriv->short_gi, BIT0) ? _TRUE : _FALSE;
  3075. /* LDPC support */
  3076. rtw_hal_get_def_var(padapter, HAL_DEF_RX_LDPC, (u8 *)&bHwLDPCSupport);
  3077. CLEAR_FLAGS(phtpriv->ldpc_cap);
  3078. if (bHwLDPCSupport) {
  3079. if (TEST_FLAG(pregistrypriv->ldpc_cap, BIT4))
  3080. SET_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_RX);
  3081. }
  3082. rtw_hal_get_def_var(padapter, HAL_DEF_TX_LDPC, (u8 *)&bHwLDPCSupport);
  3083. if (bHwLDPCSupport) {
  3084. if (TEST_FLAG(pregistrypriv->ldpc_cap, BIT5))
  3085. SET_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_TX);
  3086. }
  3087. if (phtpriv->ldpc_cap)
  3088. RTW_INFO("[HT] HAL Support LDPC = 0x%02X\n", phtpriv->ldpc_cap);
  3089. /* STBC */
  3090. rtw_hal_get_def_var(padapter, HAL_DEF_TX_STBC, (u8 *)&bHwSTBCSupport);
  3091. CLEAR_FLAGS(phtpriv->stbc_cap);
  3092. if (bHwSTBCSupport) {
  3093. if (TEST_FLAG(pregistrypriv->stbc_cap, BIT5))
  3094. SET_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX);
  3095. }
  3096. rtw_hal_get_def_var(padapter, HAL_DEF_RX_STBC, (u8 *)&bHwSTBCSupport);
  3097. if (bHwSTBCSupport) {
  3098. if (TEST_FLAG(pregistrypriv->stbc_cap, BIT4))
  3099. SET_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_RX);
  3100. }
  3101. if (phtpriv->stbc_cap)
  3102. RTW_INFO("[HT] HAL Support STBC = 0x%02X\n", phtpriv->stbc_cap);
  3103. /* Beamforming setting */
  3104. CLEAR_FLAGS(phtpriv->beamform_cap);
  3105. #ifdef CONFIG_BEAMFORMING
  3106. rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&bHwSupportBeamformer);
  3107. rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&bHwSupportBeamformee);
  3108. if (TEST_FLAG(pregistrypriv->beamform_cap, BIT4) && bHwSupportBeamformer) {
  3109. SET_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE);
  3110. RTW_INFO("[HT] HAL Support Beamformer\n");
  3111. }
  3112. if (TEST_FLAG(pregistrypriv->beamform_cap, BIT5) && bHwSupportBeamformee) {
  3113. SET_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE);
  3114. RTW_INFO("[HT] HAL Support Beamformee\n");
  3115. }
  3116. #endif /* CONFIG_BEAMFORMING */
  3117. }
  3118. void rtw_build_wmm_ie_ht(_adapter *padapter, u8 *out_ie, uint *pout_len)
  3119. {
  3120. unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
  3121. int out_len;
  3122. u8 *pframe;
  3123. if (padapter->mlmepriv.qospriv.qos_option == 0) {
  3124. out_len = *pout_len;
  3125. pframe = rtw_set_ie(out_ie + out_len, _VENDOR_SPECIFIC_IE_,
  3126. _WMM_IE_Length_, WMM_IE, pout_len);
  3127. padapter->mlmepriv.qospriv.qos_option = 1;
  3128. }
  3129. }
  3130. /* the fucntion is >= passive_level */
  3131. unsigned int rtw_restructure_ht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len, u8 channel)
  3132. {
  3133. u32 ielen, out_len;
  3134. u32 rx_packet_offset, max_recvbuf_sz;
  3135. HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor;
  3136. HT_CAP_AMPDU_DENSITY best_ampdu_density;
  3137. unsigned char *p, *pframe;
  3138. struct rtw_ieee80211_ht_cap ht_capie;
  3139. u8 cbw40_enable = 0, rf_type = 0, operation_bw = 0, rf_num = 0, rx_stbc_nss = 0, rx_nss = 0;
  3140. struct registry_priv *pregistrypriv = &padapter->registrypriv;
  3141. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  3142. struct ht_priv *phtpriv = &pmlmepriv->htpriv;
  3143. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  3144. struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
  3145. phtpriv->ht_option = _FALSE;
  3146. out_len = *pout_len;
  3147. _rtw_memset(&ht_capie, 0, sizeof(struct rtw_ieee80211_ht_cap));
  3148. ht_capie.cap_info = IEEE80211_HT_CAP_DSSSCCK40;
  3149. if (phtpriv->sgi_20m)
  3150. ht_capie.cap_info |= IEEE80211_HT_CAP_SGI_20;
  3151. /* Get HT BW */
  3152. if (in_ie == NULL) {
  3153. /* TDLS: TODO 20/40 issue */
  3154. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
  3155. operation_bw = padapter->mlmeextpriv.cur_bwmode;
  3156. if (operation_bw > CHANNEL_WIDTH_40)
  3157. operation_bw = CHANNEL_WIDTH_40;
  3158. } else
  3159. /* TDLS: TODO 40? */
  3160. operation_bw = CHANNEL_WIDTH_40;
  3161. } else {
  3162. p = rtw_get_ie(in_ie, _HT_ADD_INFO_IE_, &ielen, in_len);
  3163. if (p && (ielen == sizeof(struct ieee80211_ht_addt_info))) {
  3164. struct HT_info_element *pht_info = (struct HT_info_element *)(p + 2);
  3165. if (pht_info->infos[0] & BIT(2)) {
  3166. switch (pht_info->infos[0] & 0x3) {
  3167. case 1:
  3168. case 3:
  3169. operation_bw = CHANNEL_WIDTH_40;
  3170. break;
  3171. default:
  3172. operation_bw = CHANNEL_WIDTH_20;
  3173. break;
  3174. }
  3175. } else
  3176. operation_bw = CHANNEL_WIDTH_20;
  3177. }
  3178. }
  3179. /* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
  3180. if (hal_chk_bw_cap(padapter, BW_CAP_40M)) {
  3181. if (channel > 14) {
  3182. if (REGSTY_IS_BW_5G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40))
  3183. cbw40_enable = 1;
  3184. } else {
  3185. if (REGSTY_IS_BW_2G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40))
  3186. cbw40_enable = 1;
  3187. }
  3188. }
  3189. if ((cbw40_enable == 1) && (operation_bw == CHANNEL_WIDTH_40)) {
  3190. ht_capie.cap_info |= IEEE80211_HT_CAP_SUP_WIDTH;
  3191. if (phtpriv->sgi_40m)
  3192. ht_capie.cap_info |= IEEE80211_HT_CAP_SGI_40;
  3193. }
  3194. /* todo: disable SM power save mode */
  3195. ht_capie.cap_info |= IEEE80211_HT_CAP_SM_PS;
  3196. /* RX LDPC */
  3197. if (TEST_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_RX)) {
  3198. ht_capie.cap_info |= IEEE80211_HT_CAP_LDPC_CODING;
  3199. RTW_INFO("[HT] Declare supporting RX LDPC\n");
  3200. }
  3201. /* TX STBC */
  3202. if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX)) {
  3203. ht_capie.cap_info |= IEEE80211_HT_CAP_TX_STBC;
  3204. RTW_INFO("[HT] Declare supporting TX STBC\n");
  3205. }
  3206. /* RX STBC */
  3207. if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_RX)) {
  3208. if ((pregistrypriv->rx_stbc == 0x3) || /* enable for 2.4/5 GHz */
  3209. ((channel <= 14) && (pregistrypriv->rx_stbc == 0x1)) || /* enable for 2.4GHz */
  3210. ((channel > 14) && (pregistrypriv->rx_stbc == 0x2)) || /* enable for 5GHz */
  3211. (pregistrypriv->wifi_spec == 1)) {
  3212. /* HAL_DEF_RX_STBC means STBC RX spatial stream, todo: VHT 4 streams */
  3213. rtw_hal_get_def_var(padapter, HAL_DEF_RX_STBC, (u8 *)(&rx_stbc_nss));
  3214. SET_HT_CAP_ELE_RX_STBC(&ht_capie, rx_stbc_nss);
  3215. RTW_INFO("[HT] Declare supporting RX STBC = %d\n", rx_stbc_nss);
  3216. }
  3217. }
  3218. /* fill default supported_mcs_set */
  3219. _rtw_memcpy(ht_capie.supp_mcs_set, pmlmeext->default_supported_mcs_set, 16);
  3220. /* update default supported_mcs_set */
  3221. rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
  3222. rx_nss = rtw_min(rf_type_to_rf_rx_cnt(rf_type), hal_spec->rx_nss_num);
  3223. switch (rx_nss) {
  3224. case 1:
  3225. set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_1R);
  3226. break;
  3227. case 2:
  3228. #ifdef CONFIG_DISABLE_MCS13TO15
  3229. if (((cbw40_enable == 1) && (operation_bw == CHANNEL_WIDTH_40)) && (pregistrypriv->wifi_spec != 1))
  3230. set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_2R_13TO15_OFF);
  3231. else
  3232. #endif
  3233. set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_2R);
  3234. break;
  3235. case 3:
  3236. set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_3R);
  3237. break;
  3238. case 4:
  3239. set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_4R);
  3240. break;
  3241. default:
  3242. RTW_WARN("rf_type:%d or rx_nss:%u is not expected\n", rf_type, hal_spec->rx_nss_num);
  3243. }
  3244. {
  3245. rtw_hal_get_def_var(padapter, HAL_DEF_RX_PACKET_OFFSET, &rx_packet_offset);
  3246. rtw_hal_get_def_var(padapter, HAL_DEF_MAX_RECVBUF_SZ, &max_recvbuf_sz);
  3247. if (max_recvbuf_sz - rx_packet_offset >= (8191 - 256)) {
  3248. RTW_INFO("%s IEEE80211_HT_CAP_MAX_AMSDU is set\n", __FUNCTION__);
  3249. ht_capie.cap_info = ht_capie.cap_info | IEEE80211_HT_CAP_MAX_AMSDU;
  3250. }
  3251. }
  3252. /*
  3253. AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
  3254. AMPDU_para [4:2]:Min MPDU Start Spacing
  3255. */
  3256. /*
  3257. #if defined(CONFIG_RTL8188E) && defined(CONFIG_SDIO_HCI)
  3258. ht_capie.ampdu_params_info = 2;
  3259. #else
  3260. ht_capie.ampdu_params_info = (IEEE80211_HT_CAP_AMPDU_FACTOR&0x03);
  3261. #endif
  3262. */
  3263. if (padapter->driver_rx_ampdu_factor != 0xFF)
  3264. max_rx_ampdu_factor = (HT_CAP_AMPDU_FACTOR)padapter->driver_rx_ampdu_factor;
  3265. else
  3266. rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
  3267. /* rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor); */
  3268. ht_capie.ampdu_params_info = (max_rx_ampdu_factor & 0x03);
  3269. if (padapter->driver_rx_ampdu_spacing != 0xFF)
  3270. ht_capie.ampdu_params_info |= ((padapter->driver_rx_ampdu_spacing & 0x07) << 2);
  3271. else {
  3272. if (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_) {
  3273. /*
  3274. * Todo : Each chip must to ask DD , this chip best ampdu_density setting
  3275. * By yiwei.sun
  3276. */
  3277. rtw_hal_get_def_var(padapter, HW_VAR_BEST_AMPDU_DENSITY, &best_ampdu_density);
  3278. ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY & (best_ampdu_density << 2));
  3279. } else
  3280. ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY & 0x00);
  3281. }
  3282. #ifdef CONFIG_BEAMFORMING
  3283. ht_capie.tx_BF_cap_info = 0;
  3284. /* HT Beamformer*/
  3285. if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE)) {
  3286. /* Transmit NDP Capable */
  3287. SET_HT_CAP_TXBF_TRANSMIT_NDP_CAP(&ht_capie, 1);
  3288. /* Explicit Compressed Steering Capable */
  3289. SET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(&ht_capie, 1);
  3290. /* Compressed Steering Number Antennas */
  3291. SET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(&ht_capie, 1);
  3292. rtw_hal_get_def_var(padapter, HAL_DEF_BEAMFORMER_CAP, (u8 *)&rf_num);
  3293. SET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS(&ht_capie, rf_num);
  3294. }
  3295. /* HT Beamformee */
  3296. if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE)) {
  3297. /* Receive NDP Capable */
  3298. SET_HT_CAP_TXBF_RECEIVE_NDP_CAP(&ht_capie, 1);
  3299. /* Explicit Compressed Beamforming Feedback Capable */
  3300. SET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(&ht_capie, 2);
  3301. rtw_hal_get_def_var(padapter, HAL_DEF_BEAMFORMEE_CAP, (u8 *)&rf_num);
  3302. SET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(&ht_capie, rf_num);
  3303. }
  3304. #endif/*CONFIG_BEAMFORMING*/
  3305. pframe = rtw_set_ie(out_ie + out_len, _HT_CAPABILITY_IE_,
  3306. sizeof(struct rtw_ieee80211_ht_cap), (unsigned char *)&ht_capie, pout_len);
  3307. phtpriv->ht_option = _TRUE;
  3308. if (in_ie != NULL) {
  3309. p = rtw_get_ie(in_ie, _HT_ADD_INFO_IE_, &ielen, in_len);
  3310. if (p && (ielen == sizeof(struct ieee80211_ht_addt_info))) {
  3311. out_len = *pout_len;
  3312. pframe = rtw_set_ie(out_ie + out_len, _HT_ADD_INFO_IE_, ielen, p + 2 , pout_len);
  3313. }
  3314. }
  3315. return phtpriv->ht_option;
  3316. }
  3317. /* the fucntion is > passive_level (in critical_section) */
  3318. void rtw_update_ht_cap(_adapter *padapter, u8 *pie, uint ie_len, u8 channel)
  3319. {
  3320. u8 *p, max_ampdu_sz;
  3321. int len;
  3322. /* struct sta_info *bmc_sta, *psta; */
  3323. struct rtw_ieee80211_ht_cap *pht_capie;
  3324. struct ieee80211_ht_addt_info *pht_addtinfo;
  3325. /* struct recv_reorder_ctrl *preorder_ctrl; */
  3326. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  3327. struct ht_priv *phtpriv = &pmlmepriv->htpriv;
  3328. /* struct recv_priv *precvpriv = &padapter->recvpriv; */
  3329. struct registry_priv *pregistrypriv = &padapter->registrypriv;
  3330. /* struct wlan_network *pcur_network = &(pmlmepriv->cur_network);; */
  3331. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  3332. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  3333. u8 cbw40_enable = 0;
  3334. if (!phtpriv->ht_option)
  3335. return;
  3336. if ((!pmlmeinfo->HT_info_enable) || (!pmlmeinfo->HT_caps_enable))
  3337. return;
  3338. RTW_INFO("+rtw_update_ht_cap()\n");
  3339. /* maybe needs check if ap supports rx ampdu. */
  3340. if ((phtpriv->ampdu_enable == _FALSE) && (pregistrypriv->ampdu_enable == 1)) {
  3341. if (pregistrypriv->wifi_spec == 1) {
  3342. /* remove this part because testbed AP should disable RX AMPDU */
  3343. /* phtpriv->ampdu_enable = _FALSE; */
  3344. phtpriv->ampdu_enable = _TRUE;
  3345. } else
  3346. phtpriv->ampdu_enable = _TRUE;
  3347. }
  3348. /* check Max Rx A-MPDU Size */
  3349. len = 0;
  3350. p = rtw_get_ie(pie + sizeof(NDIS_802_11_FIXED_IEs), _HT_CAPABILITY_IE_, &len, ie_len - sizeof(NDIS_802_11_FIXED_IEs));
  3351. if (p && len > 0) {
  3352. pht_capie = (struct rtw_ieee80211_ht_cap *)(p + 2);
  3353. max_ampdu_sz = (pht_capie->ampdu_params_info & IEEE80211_HT_CAP_AMPDU_FACTOR);
  3354. max_ampdu_sz = 1 << (max_ampdu_sz + 3); /* max_ampdu_sz (kbytes); */
  3355. /* RTW_INFO("rtw_update_ht_cap(): max_ampdu_sz=%d\n", max_ampdu_sz); */
  3356. phtpriv->rx_ampdu_maxlen = max_ampdu_sz;
  3357. }
  3358. len = 0;
  3359. p = rtw_get_ie(pie + sizeof(NDIS_802_11_FIXED_IEs), _HT_ADD_INFO_IE_, &len, ie_len - sizeof(NDIS_802_11_FIXED_IEs));
  3360. if (p && len > 0) {
  3361. pht_addtinfo = (struct ieee80211_ht_addt_info *)(p + 2);
  3362. /* todo: */
  3363. }
  3364. if (hal_chk_bw_cap(padapter, BW_CAP_40M)) {
  3365. if (channel > 14) {
  3366. if (REGSTY_IS_BW_5G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40))
  3367. cbw40_enable = 1;
  3368. } else {
  3369. if (REGSTY_IS_BW_2G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40))
  3370. cbw40_enable = 1;
  3371. }
  3372. }
  3373. /* update cur_bwmode & cur_ch_offset */
  3374. if ((cbw40_enable) &&
  3375. (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & BIT(1)) &&
  3376. (pmlmeinfo->HT_info.infos[0] & BIT(2))) {
  3377. struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
  3378. int i;
  3379. u8 rf_type = RF_1T1R;
  3380. u8 tx_nss = 0;
  3381. rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
  3382. tx_nss = rtw_min(rf_type_to_rf_tx_cnt(rf_type), hal_spec->tx_nss_num);
  3383. /* update the MCS set */
  3384. for (i = 0; i < 16; i++)
  3385. pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= pmlmeext->default_supported_mcs_set[i];
  3386. /* update the MCS rates */
  3387. switch (tx_nss) {
  3388. case 1:
  3389. set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_1R);
  3390. break;
  3391. case 2:
  3392. #ifdef CONFIG_DISABLE_MCS13TO15
  3393. if (pmlmeext->cur_bwmode == CHANNEL_WIDTH_40 && pregistrypriv->wifi_spec != 1)
  3394. set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R_13TO15_OFF);
  3395. else
  3396. #endif
  3397. set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R);
  3398. break;
  3399. case 3:
  3400. set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_3R);
  3401. break;
  3402. case 4:
  3403. set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_4R);
  3404. break;
  3405. default:
  3406. RTW_WARN("rf_type:%d or tx_nss_num:%u is not expected\n", rf_type, hal_spec->tx_nss_num);
  3407. }
  3408. /* switch to the 40M Hz mode accoring to the AP */
  3409. /* pmlmeext->cur_bwmode = CHANNEL_WIDTH_40; */
  3410. switch ((pmlmeinfo->HT_info.infos[0] & 0x3)) {
  3411. case EXTCHNL_OFFSET_UPPER:
  3412. pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
  3413. break;
  3414. case EXTCHNL_OFFSET_LOWER:
  3415. pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
  3416. break;
  3417. default:
  3418. pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  3419. break;
  3420. }
  3421. }
  3422. /* */
  3423. /* Config SM Power Save setting */
  3424. /* */
  3425. pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2;
  3426. if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC) {
  3427. #if 0
  3428. u8 i;
  3429. /* update the MCS rates */
  3430. for (i = 0; i < 16; i++)
  3431. pmlmeinfo->HT_caps.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
  3432. #endif
  3433. RTW_INFO("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __FUNCTION__);
  3434. }
  3435. /* */
  3436. /* Config current HT Protection mode. */
  3437. /* */
  3438. pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3;
  3439. #if 0 /* move to rtw_update_sta_info_client() */
  3440. /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info */
  3441. /* if A-MPDU Rx is enabled, reseting rx_ordering_ctrl wstart_b(indicate_seq) to default value=0xffff */
  3442. /* todo: check if AP can send A-MPDU packets */
  3443. bmc_sta = rtw_get_bcmc_stainfo(padapter);
  3444. if (bmc_sta) {
  3445. for (i = 0; i < 16 ; i++) {
  3446. /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
  3447. preorder_ctrl = &bmc_sta->recvreorder_ctrl[i];
  3448. preorder_ctrl->enable = _FALSE;
  3449. preorder_ctrl->indicate_seq = 0xffff;
  3450. #ifdef DBG_RX_SEQ
  3451. RTW_INFO("DBG_RX_SEQ %s:%d indicate_seq:%u\n", __FUNCTION__, __LINE__,
  3452. preorder_ctrl->indicate_seq);
  3453. #endif
  3454. preorder_ctrl->wend_b = 0xffff;
  3455. preorder_ctrl->wsize_b = 64;/* max_ampdu_sz; */ /* ex. 32(kbytes) -> wsize_b=32 */
  3456. }
  3457. }
  3458. psta = rtw_get_stainfo(&padapter->stapriv, pcur_network->network.MacAddress);
  3459. if (psta) {
  3460. for (i = 0; i < 16 ; i++) {
  3461. /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
  3462. preorder_ctrl = &psta->recvreorder_ctrl[i];
  3463. preorder_ctrl->enable = _FALSE;
  3464. preorder_ctrl->indicate_seq = 0xffff;
  3465. #ifdef DBG_RX_SEQ
  3466. RTW_INFO("DBG_RX_SEQ %s:%d indicate_seq:%u\n", __FUNCTION__, __LINE__,
  3467. preorder_ctrl->indicate_seq);
  3468. #endif
  3469. preorder_ctrl->wend_b = 0xffff;
  3470. preorder_ctrl->wsize_b = 64;/* max_ampdu_sz; */ /* ex. 32(kbytes) -> wsize_b=32 */
  3471. }
  3472. }
  3473. #endif
  3474. }
  3475. #ifdef CONFIG_TDLS
  3476. void rtw_issue_addbareq_cmd_tdls(_adapter *padapter, struct xmit_frame *pxmitframe)
  3477. {
  3478. struct pkt_attrib *pattrib = &pxmitframe->attrib;
  3479. struct sta_info *ptdls_sta = NULL;
  3480. u8 issued;
  3481. int priority;
  3482. struct ht_priv *phtpriv;
  3483. priority = pattrib->priority;
  3484. if (pattrib->direct_link == _TRUE) {
  3485. ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->dst);
  3486. if ((ptdls_sta != NULL) && (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE)) {
  3487. phtpriv = &ptdls_sta->htpriv;
  3488. if ((phtpriv->ht_option == _TRUE) && (phtpriv->ampdu_enable == _TRUE)) {
  3489. issued = (phtpriv->agg_enable_bitmap >> priority) & 0x1;
  3490. issued |= (phtpriv->candidate_tid_bitmap >> priority) & 0x1;
  3491. if (0 == issued) {
  3492. RTW_INFO("[%s], p=%d\n", __FUNCTION__, priority);
  3493. ptdls_sta->htpriv.candidate_tid_bitmap |= BIT((u8)priority);
  3494. rtw_addbareq_cmd(padapter, (u8)priority, pattrib->dst);
  3495. }
  3496. }
  3497. }
  3498. }
  3499. }
  3500. #endif /* CONFIG_TDLS */
  3501. void rtw_issue_addbareq_cmd(_adapter *padapter, struct xmit_frame *pxmitframe)
  3502. {
  3503. u8 issued;
  3504. int priority;
  3505. struct sta_info *psta = NULL;
  3506. struct ht_priv *phtpriv;
  3507. struct pkt_attrib *pattrib = &pxmitframe->attrib;
  3508. s32 bmcst = IS_MCAST(pattrib->ra);
  3509. /* if(bmcst || (padapter->mlmepriv.LinkDetectInfo.bTxBusyTraffic == _FALSE)) */
  3510. if (bmcst || (padapter->mlmepriv.LinkDetectInfo.NumTxOkInPeriod < 100))
  3511. return;
  3512. priority = pattrib->priority;
  3513. #ifdef CONFIG_TDLS
  3514. rtw_issue_addbareq_cmd_tdls(padapter, pxmitframe);
  3515. #endif /* CONFIG_TDLS */
  3516. psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
  3517. if (pattrib->psta != psta) {
  3518. RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta);
  3519. return;
  3520. }
  3521. if (psta == NULL) {
  3522. RTW_INFO("%s, psta==NUL\n", __func__);
  3523. return;
  3524. }
  3525. if (!(psta->state & _FW_LINKED)) {
  3526. RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
  3527. return;
  3528. }
  3529. phtpriv = &psta->htpriv;
  3530. if ((phtpriv->ht_option == _TRUE) && (phtpriv->ampdu_enable == _TRUE)) {
  3531. issued = (phtpriv->agg_enable_bitmap >> priority) & 0x1;
  3532. issued |= (phtpriv->candidate_tid_bitmap >> priority) & 0x1;
  3533. if (0 == issued) {
  3534. RTW_INFO("rtw_issue_addbareq_cmd, p=%d\n", priority);
  3535. psta->htpriv.candidate_tid_bitmap |= BIT((u8)priority);
  3536. rtw_addbareq_cmd(padapter, (u8) priority, pattrib->ra);
  3537. }
  3538. }
  3539. }
  3540. void rtw_append_exented_cap(_adapter *padapter, u8 *out_ie, uint *pout_len)
  3541. {
  3542. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  3543. struct ht_priv *phtpriv = &pmlmepriv->htpriv;
  3544. #ifdef CONFIG_80211AC_VHT
  3545. struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
  3546. #endif /* CONFIG_80211AC_VHT */
  3547. u8 cap_content[8] = { 0 };
  3548. u8 *pframe;
  3549. u8 null_content[8] = {0};
  3550. if (phtpriv->bss_coexist)
  3551. SET_EXT_CAPABILITY_ELE_BSS_COEXIST(cap_content, 1);
  3552. #ifdef CONFIG_80211AC_VHT
  3553. if (pvhtpriv->vht_option)
  3554. SET_EXT_CAPABILITY_ELE_OP_MODE_NOTIF(cap_content, 1);
  3555. #endif /* CONFIG_80211AC_VHT */
  3556. /*
  3557. From 802.11 specification,if a STA does not support any of capabilities defined
  3558. in the Extended Capabilities element, then the STA is not required to
  3559. transmit the Extended Capabilities element.
  3560. */
  3561. if (_FALSE == _rtw_memcmp(cap_content, null_content, 8))
  3562. pframe = rtw_set_ie(out_ie + *pout_len, EID_EXTCapability, 8, cap_content , pout_len);
  3563. }
  3564. #endif
  3565. #ifdef CONFIG_LAYER2_ROAMING
  3566. inline void rtw_set_to_roam(_adapter *adapter, u8 to_roam)
  3567. {
  3568. if (to_roam == 0)
  3569. adapter->mlmepriv.to_join = _FALSE;
  3570. adapter->mlmepriv.to_roam = to_roam;
  3571. }
  3572. inline u8 rtw_dec_to_roam(_adapter *adapter)
  3573. {
  3574. adapter->mlmepriv.to_roam--;
  3575. return adapter->mlmepriv.to_roam;
  3576. }
  3577. inline u8 rtw_to_roam(_adapter *adapter)
  3578. {
  3579. return adapter->mlmepriv.to_roam;
  3580. }
  3581. void rtw_roaming(_adapter *padapter, struct wlan_network *tgt_network)
  3582. {
  3583. _irqL irqL;
  3584. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  3585. _enter_critical_bh(&pmlmepriv->lock, &irqL);
  3586. _rtw_roaming(padapter, tgt_network);
  3587. _exit_critical_bh(&pmlmepriv->lock, &irqL);
  3588. }
  3589. void _rtw_roaming(_adapter *padapter, struct wlan_network *tgt_network)
  3590. {
  3591. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  3592. struct wlan_network *cur_network = &pmlmepriv->cur_network;
  3593. int do_join_r;
  3594. if (0 < rtw_to_roam(padapter)) {
  3595. RTW_INFO("roaming from %s("MAC_FMT"), length:%d\n",
  3596. cur_network->network.Ssid.Ssid, MAC_ARG(cur_network->network.MacAddress),
  3597. cur_network->network.Ssid.SsidLength);
  3598. _rtw_memcpy(&pmlmepriv->assoc_ssid, &cur_network->network.Ssid, sizeof(NDIS_802_11_SSID));
  3599. pmlmepriv->assoc_by_bssid = _FALSE;
  3600. #ifdef CONFIG_WAPI_SUPPORT
  3601. rtw_wapi_return_all_sta_info(padapter);
  3602. #endif
  3603. while (1) {
  3604. do_join_r = rtw_do_join(padapter);
  3605. if (_SUCCESS == do_join_r)
  3606. break;
  3607. else {
  3608. RTW_INFO("roaming do_join return %d\n", do_join_r);
  3609. rtw_dec_to_roam(padapter);
  3610. if (rtw_to_roam(padapter) > 0)
  3611. continue;
  3612. else {
  3613. RTW_INFO("%s(%d) -to roaming fail, indicate_disconnect\n", __FUNCTION__, __LINE__);
  3614. #ifdef CONFIG_RTW_80211R
  3615. rtw_clr_ft_flags(padapter, RTW_FT_SUPPORTED|RTW_FT_OVER_DS_SUPPORTED);
  3616. rtw_reset_ft_status(padapter);
  3617. #endif
  3618. rtw_indicate_disconnect(padapter, 0, _FALSE);
  3619. break;
  3620. }
  3621. }
  3622. }
  3623. }
  3624. }
  3625. #endif /* CONFIG_LAYER2_ROAMING */
  3626. bool rtw_adjust_chbw(_adapter *adapter, u8 req_ch, u8 *req_bw, u8 *req_offset)
  3627. {
  3628. struct registry_priv *regsty = adapter_to_regsty(adapter);
  3629. u8 allowed_bw;
  3630. if (req_ch <= 14)
  3631. allowed_bw = REGSTY_BW_2G(regsty);
  3632. else
  3633. allowed_bw = REGSTY_BW_5G(regsty);
  3634. allowed_bw = hal_largest_bw(adapter, allowed_bw);
  3635. if (allowed_bw == CHANNEL_WIDTH_80 && *req_bw > CHANNEL_WIDTH_80)
  3636. *req_bw = CHANNEL_WIDTH_80;
  3637. else if (allowed_bw == CHANNEL_WIDTH_40 && *req_bw > CHANNEL_WIDTH_40)
  3638. *req_bw = CHANNEL_WIDTH_40;
  3639. else if (allowed_bw == CHANNEL_WIDTH_20 && *req_bw > CHANNEL_WIDTH_20) {
  3640. *req_bw = CHANNEL_WIDTH_20;
  3641. *req_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  3642. } else
  3643. return _FALSE;
  3644. return _TRUE;
  3645. }
  3646. sint rtw_linked_check(_adapter *padapter)
  3647. {
  3648. if ((check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) ||
  3649. (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
  3650. if (padapter->stapriv.asoc_sta_count > 2)
  3651. return _TRUE;
  3652. } else {
  3653. /* Station mode */
  3654. if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == _TRUE)
  3655. return _TRUE;
  3656. }
  3657. return _FALSE;
  3658. }
  3659. u8 rtw_is_adapter_up(_adapter *padapter)
  3660. {
  3661. if (padapter == NULL)
  3662. return _FALSE;
  3663. if (RTW_CANNOT_RUN(padapter)) {
  3664. RTW_INFO(FUNC_ADPT_FMT "-(bSurpriseRemoved == _TRUE) || ( bDriverStopped == _TRUE)\n", FUNC_ADPT_ARG(padapter));
  3665. return _FALSE;
  3666. }
  3667. if (!rtw_is_hw_init_completed(padapter)) {
  3668. /*RTW_INFO(FUNC_ADPT_FMT "-(hw_init_completed == _FALSE)\n", FUNC_ADPT_ARG(padapter));*/
  3669. return _FALSE;
  3670. }
  3671. if (padapter->bup == _FALSE) {
  3672. /*RTW_INFO(FUNC_ADPT_FMT "-(bup == _FALSE)\n", FUNC_ADPT_ARG(padapter));*/
  3673. return _FALSE;
  3674. }
  3675. return _TRUE;
  3676. }
  3677. bool is_miracast_enabled(_adapter *adapter)
  3678. {
  3679. bool enabled = 0;
  3680. #ifdef CONFIG_WFD
  3681. struct wifi_display_info *wfdinfo = &adapter->wfd_info;
  3682. enabled = (wfdinfo->stack_wfd_mode & (MIRACAST_SOURCE | MIRACAST_SINK))
  3683. || (wfdinfo->op_wfd_mode & (MIRACAST_SOURCE | MIRACAST_SINK));
  3684. #endif
  3685. return enabled;
  3686. }
  3687. bool rtw_chk_miracast_mode(_adapter *adapter, u8 mode)
  3688. {
  3689. bool ret = 0;
  3690. #ifdef CONFIG_WFD
  3691. struct wifi_display_info *wfdinfo = &adapter->wfd_info;
  3692. ret = (wfdinfo->stack_wfd_mode & mode) || (wfdinfo->op_wfd_mode & mode);
  3693. #endif
  3694. return ret;
  3695. }
  3696. const char *get_miracast_mode_str(int mode)
  3697. {
  3698. if (mode == MIRACAST_SOURCE)
  3699. return "SOURCE";
  3700. else if (mode == MIRACAST_SINK)
  3701. return "SINK";
  3702. else if (mode == (MIRACAST_SOURCE | MIRACAST_SINK))
  3703. return "SOURCE&SINK";
  3704. else if (mode == MIRACAST_DISABLED)
  3705. return "DISABLED";
  3706. else
  3707. return "INVALID";
  3708. }
  3709. #ifdef CONFIG_WFD
  3710. static bool wfd_st_match_rule(_adapter *adapter, u8 *local_naddr, u8 *local_port, u8 *remote_naddr, u8 *remote_port)
  3711. {
  3712. struct wifi_display_info *wfdinfo = &adapter->wfd_info;
  3713. if (ntohs(*((u16 *)local_port)) == wfdinfo->rtsp_ctrlport
  3714. || ntohs(*((u16 *)local_port)) == wfdinfo->tdls_rtsp_ctrlport
  3715. || ntohs(*((u16 *)remote_port)) == wfdinfo->peer_rtsp_ctrlport)
  3716. return _TRUE;
  3717. return _FALSE;
  3718. }
  3719. static struct st_register wfd_st_reg = {
  3720. .s_proto = 0x06,
  3721. .rule = wfd_st_match_rule,
  3722. };
  3723. #endif /* CONFIG_WFD */
  3724. inline void rtw_wfd_st_switch(struct sta_info *sta, bool on)
  3725. {
  3726. #ifdef CONFIG_WFD
  3727. if (on)
  3728. rtw_st_ctl_register(&sta->st_ctl, SESSION_TRACKER_REG_ID_WFD, &wfd_st_reg);
  3729. else
  3730. rtw_st_ctl_unregister(&sta->st_ctl, SESSION_TRACKER_REG_ID_WFD);
  3731. #endif
  3732. }