rtw_mlme.c 157 KB

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