hal_com.c 405 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430
  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 _HAL_COM_C_
  16. #include <drv_types.h>
  17. #include "hal_com_h2c.h"
  18. #include "hal_data.h"
  19. #ifdef RTW_HALMAC
  20. #include "../../hal/hal_halmac.h"
  21. #endif
  22. void rtw_dump_fw_info(void *sel, _adapter *adapter)
  23. {
  24. HAL_DATA_TYPE *hal_data = NULL;
  25. if (!adapter)
  26. return;
  27. hal_data = GET_HAL_DATA(adapter);
  28. if (hal_data->bFWReady)
  29. RTW_PRINT_SEL(sel, "FW VER -%d.%d\n", hal_data->firmware_version, hal_data->firmware_sub_version);
  30. else
  31. RTW_PRINT_SEL(sel, "FW not ready\n");
  32. }
  33. /* #define CONFIG_GTK_OL_DBG */
  34. /*#define DBG_SEC_CAM_MOVE*/
  35. #ifdef DBG_SEC_CAM_MOVE
  36. void rtw_hal_move_sta_gk_to_dk(_adapter *adapter)
  37. {
  38. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  39. int cam_id, index = 0;
  40. u8 *addr = NULL;
  41. if (!MLME_IS_STA(adapter))
  42. return;
  43. addr = get_bssid(pmlmepriv);
  44. if (addr == NULL) {
  45. RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
  46. return;
  47. }
  48. rtw_clean_dk_section(adapter);
  49. do {
  50. cam_id = rtw_camid_search(adapter, addr, index, 1);
  51. if (cam_id == -1)
  52. RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
  53. else
  54. rtw_sec_cam_swap(adapter, cam_id, index);
  55. index++;
  56. } while (index < 4);
  57. }
  58. void rtw_hal_read_sta_dk_key(_adapter *adapter, u8 key_id)
  59. {
  60. struct security_priv *psecuritypriv = &adapter->securitypriv;
  61. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  62. struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
  63. _irqL irqL;
  64. u8 get_key[16];
  65. _rtw_memset(get_key, 0, sizeof(get_key));
  66. if (key_id > 4) {
  67. RTW_INFO("%s [ERROR] gtk_keyindex:%d invalid\n", __func__, key_id);
  68. rtw_warn_on(1);
  69. return;
  70. }
  71. rtw_sec_read_cam_ent(adapter, key_id, NULL, NULL, get_key);
  72. /*update key into related sw variable*/
  73. _enter_critical_bh(&cam_ctl->lock, &irqL);
  74. if (_rtw_camid_is_gk(adapter, key_id)) {
  75. RTW_INFO("[HW KEY] -Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(get_key));
  76. RTW_INFO("[cam_cache KEY] - Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(&dvobj->cam_cache[key_id].key));
  77. }
  78. _exit_critical_bh(&cam_ctl->lock, &irqL);
  79. }
  80. #endif
  81. #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
  82. char rtw_phy_para_file_path[PATH_LENGTH_MAX];
  83. #endif
  84. void dump_chip_info(HAL_VERSION ChipVersion)
  85. {
  86. int cnt = 0;
  87. u8 buf[128] = {0};
  88. if (IS_8188E(ChipVersion))
  89. cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188E_");
  90. else if (IS_8188F(ChipVersion))
  91. cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188F_");
  92. else if (IS_8188GTV(ChipVersion))
  93. cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188GTV_");
  94. else if (IS_8812_SERIES(ChipVersion))
  95. cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8812_");
  96. else if (IS_8192E(ChipVersion))
  97. cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192E_");
  98. else if (IS_8821_SERIES(ChipVersion))
  99. cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821_");
  100. else if (IS_8723B_SERIES(ChipVersion))
  101. cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723B_");
  102. else if (IS_8703B_SERIES(ChipVersion))
  103. cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8703B_");
  104. else if (IS_8723D_SERIES(ChipVersion))
  105. cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723D_");
  106. else if (IS_8814A_SERIES(ChipVersion))
  107. cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8814A_");
  108. else if (IS_8822B_SERIES(ChipVersion))
  109. cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822B_");
  110. else if (IS_8821C_SERIES(ChipVersion))
  111. cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821C_");
  112. else if (IS_8710B_SERIES(ChipVersion))
  113. cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8710B_");
  114. else if (IS_8192F_SERIES(ChipVersion))
  115. cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192F_");
  116. else
  117. cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_UNKNOWN_");
  118. cnt += sprintf((buf + cnt), "%s_", IS_NORMAL_CHIP(ChipVersion) ? "Normal_Chip" : "Test_Chip");
  119. if (IS_CHIP_VENDOR_TSMC(ChipVersion))
  120. cnt += sprintf((buf + cnt), "%s_", "TSMC");
  121. else if (IS_CHIP_VENDOR_UMC(ChipVersion))
  122. cnt += sprintf((buf + cnt), "%s_", "UMC");
  123. else if (IS_CHIP_VENDOR_SMIC(ChipVersion))
  124. cnt += sprintf((buf + cnt), "%s_", "SMIC");
  125. if (IS_A_CUT(ChipVersion))
  126. cnt += sprintf((buf + cnt), "A_CUT_");
  127. else if (IS_B_CUT(ChipVersion))
  128. cnt += sprintf((buf + cnt), "B_CUT_");
  129. else if (IS_C_CUT(ChipVersion))
  130. cnt += sprintf((buf + cnt), "C_CUT_");
  131. else if (IS_D_CUT(ChipVersion))
  132. cnt += sprintf((buf + cnt), "D_CUT_");
  133. else if (IS_E_CUT(ChipVersion))
  134. cnt += sprintf((buf + cnt), "E_CUT_");
  135. else if (IS_F_CUT(ChipVersion))
  136. cnt += sprintf((buf + cnt), "F_CUT_");
  137. else if (IS_I_CUT(ChipVersion))
  138. cnt += sprintf((buf + cnt), "I_CUT_");
  139. else if (IS_J_CUT(ChipVersion))
  140. cnt += sprintf((buf + cnt), "J_CUT_");
  141. else if (IS_K_CUT(ChipVersion))
  142. cnt += sprintf((buf + cnt), "K_CUT_");
  143. else
  144. cnt += sprintf((buf + cnt), "UNKNOWN_CUT(%d)_", ChipVersion.CUTVersion);
  145. if (IS_1T1R(ChipVersion))
  146. cnt += sprintf((buf + cnt), "1T1R_");
  147. else if (IS_1T2R(ChipVersion))
  148. cnt += sprintf((buf + cnt), "1T2R_");
  149. else if (IS_2T2R(ChipVersion))
  150. cnt += sprintf((buf + cnt), "2T2R_");
  151. else if (IS_3T3R(ChipVersion))
  152. cnt += sprintf((buf + cnt), "3T3R_");
  153. else if (IS_3T4R(ChipVersion))
  154. cnt += sprintf((buf + cnt), "3T4R_");
  155. else if (IS_4T4R(ChipVersion))
  156. cnt += sprintf((buf + cnt), "4T4R_");
  157. else
  158. cnt += sprintf((buf + cnt), "UNKNOWN_RFTYPE(%d)_", ChipVersion.RFType);
  159. cnt += sprintf((buf + cnt), "RomVer(%d)\n", ChipVersion.ROMVer);
  160. RTW_INFO("%s", buf);
  161. }
  162. u8 rtw_hal_get_port(_adapter *adapter)
  163. {
  164. u8 hw_port = get_hw_port(adapter);
  165. #ifdef CONFIG_CLIENT_PORT_CFG
  166. u8 clt_port = get_clt_port(adapter);
  167. if (clt_port)
  168. hw_port = clt_port;
  169. #ifdef DBG_HW_PORT
  170. if (MLME_IS_STA(adapter) && (adapter->client_id != MAX_CLIENT_PORT_NUM)) {
  171. if(hw_port == CLT_PORT_INVALID) {
  172. RTW_ERR(ADPT_FMT" @@@@@ Client port == 0 @@@@@\n", ADPT_ARG(adapter));
  173. rtw_warn_on(1);
  174. }
  175. }
  176. else if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
  177. if (hw_port != HW_PORT0) {
  178. RTW_ERR(ADPT_FMT" @@@@@ AP / MESH port != 0 @@@@@\n", ADPT_ARG(adapter));
  179. rtw_warn_on(1);
  180. }
  181. }
  182. if (0)
  183. RTW_INFO(ADPT_FMT" - HP:%d,CP:%d\n", ADPT_ARG(adapter), get_hw_port(adapter), get_clt_port(adapter));
  184. #endif /*DBG_HW_PORT*/
  185. #endif/*CONFIG_CLIENT_PORT_CFG*/
  186. return hw_port;
  187. }
  188. void rtw_hal_config_rftype(PADAPTER padapter)
  189. {
  190. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
  191. if (IS_1T1R(pHalData->version_id)) {
  192. pHalData->rf_type = RF_1T1R;
  193. pHalData->NumTotalRFPath = 1;
  194. } else if (IS_2T2R(pHalData->version_id)) {
  195. pHalData->rf_type = RF_2T2R;
  196. pHalData->NumTotalRFPath = 2;
  197. } else if (IS_1T2R(pHalData->version_id)) {
  198. pHalData->rf_type = RF_1T2R;
  199. pHalData->NumTotalRFPath = 2;
  200. } else if (IS_3T3R(pHalData->version_id)) {
  201. pHalData->rf_type = RF_3T3R;
  202. pHalData->NumTotalRFPath = 3;
  203. } else if (IS_4T4R(pHalData->version_id)) {
  204. pHalData->rf_type = RF_4T4R;
  205. pHalData->NumTotalRFPath = 4;
  206. } else {
  207. pHalData->rf_type = RF_1T1R;
  208. pHalData->NumTotalRFPath = 1;
  209. }
  210. RTW_INFO("%s RF_Type is %d TotalTxPath is %d\n", __FUNCTION__, pHalData->rf_type, pHalData->NumTotalRFPath);
  211. }
  212. #define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80
  213. /*
  214. * Description:
  215. * Use hardware(efuse), driver parameter(registry) and default channel plan
  216. * to decide which one should be used.
  217. *
  218. * Parameters:
  219. * padapter pointer of adapter
  220. * hw_alpha2 country code from HW (efuse/eeprom/mapfile)
  221. * hw_chplan channel plan from HW (efuse/eeprom/mapfile)
  222. * BIT[7] software configure mode; 0:Enable, 1:disable
  223. * BIT[6:0] Channel Plan
  224. * sw_alpha2 country code from HW (registry/module param)
  225. * sw_chplan channel plan from SW (registry/module param)
  226. * def_chplan channel plan used when HW/SW both invalid
  227. * AutoLoadFail efuse autoload fail or not
  228. *
  229. */
  230. void hal_com_config_channel_plan(
  231. IN PADAPTER padapter,
  232. IN char *hw_alpha2,
  233. IN u8 hw_chplan,
  234. IN char *sw_alpha2,
  235. IN u8 sw_chplan,
  236. IN u8 def_chplan,
  237. IN BOOLEAN AutoLoadFail
  238. )
  239. {
  240. struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
  241. PHAL_DATA_TYPE pHalData;
  242. u8 force_hw_chplan = _FALSE;
  243. int chplan = -1;
  244. const struct country_chplan *country_ent = NULL, *ent;
  245. pHalData = GET_HAL_DATA(padapter);
  246. /* treat 0xFF as invalid value, bypass hw_chplan & force_hw_chplan parsing */
  247. if (hw_chplan == 0xFF)
  248. goto chk_hw_country_code;
  249. if (AutoLoadFail == _TRUE)
  250. goto chk_sw_config;
  251. #ifndef CONFIG_FORCE_SW_CHANNEL_PLAN
  252. if (hw_chplan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
  253. force_hw_chplan = _TRUE;
  254. #endif
  255. hw_chplan &= (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
  256. chk_hw_country_code:
  257. if (hw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(hw_alpha2)) {
  258. ent = rtw_get_chplan_from_country(hw_alpha2);
  259. if (ent) {
  260. /* get chplan from hw country code, by pass hw chplan setting */
  261. country_ent = ent;
  262. chplan = ent->chplan;
  263. goto chk_sw_config;
  264. } else
  265. RTW_PRINT("%s unsupported hw_alpha2:\"%c%c\"\n", __func__, hw_alpha2[0], hw_alpha2[1]);
  266. }
  267. if (rtw_is_channel_plan_valid(hw_chplan))
  268. chplan = hw_chplan;
  269. else if (force_hw_chplan == _TRUE) {
  270. RTW_PRINT("%s unsupported hw_chplan:0x%02X\n", __func__, hw_chplan);
  271. /* hw infomaton invalid, refer to sw information */
  272. force_hw_chplan = _FALSE;
  273. }
  274. chk_sw_config:
  275. if (force_hw_chplan == _TRUE)
  276. goto done;
  277. if (sw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(sw_alpha2)) {
  278. ent = rtw_get_chplan_from_country(sw_alpha2);
  279. if (ent) {
  280. /* get chplan from sw country code, by pass sw chplan setting */
  281. country_ent = ent;
  282. chplan = ent->chplan;
  283. goto done;
  284. } else
  285. RTW_PRINT("%s unsupported sw_alpha2:\"%c%c\"\n", __func__, sw_alpha2[0], sw_alpha2[1]);
  286. }
  287. if (rtw_is_channel_plan_valid(sw_chplan)) {
  288. /* cancel hw_alpha2 because chplan is specified by sw_chplan*/
  289. country_ent = NULL;
  290. chplan = sw_chplan;
  291. } else if (sw_chplan != RTW_CHPLAN_UNSPECIFIED)
  292. RTW_PRINT("%s unsupported sw_chplan:0x%02X\n", __func__, sw_chplan);
  293. done:
  294. if (chplan == -1) {
  295. RTW_PRINT("%s use def_chplan:0x%02X\n", __func__, def_chplan);
  296. chplan = def_chplan;
  297. } else if (country_ent) {
  298. RTW_PRINT("%s country code:\"%c%c\" with chplan:0x%02X\n", __func__
  299. , country_ent->alpha2[0], country_ent->alpha2[1], country_ent->chplan);
  300. } else
  301. RTW_PRINT("%s chplan:0x%02X\n", __func__, chplan);
  302. rfctl->country_ent = country_ent;
  303. rfctl->ChannelPlan = chplan;
  304. pHalData->bDisableSWChannelPlan = force_hw_chplan;
  305. }
  306. BOOLEAN
  307. HAL_IsLegalChannel(
  308. IN PADAPTER Adapter,
  309. IN u32 Channel
  310. )
  311. {
  312. BOOLEAN bLegalChannel = _TRUE;
  313. if (Channel > 14) {
  314. if (is_supported_5g(Adapter->registrypriv.wireless_mode) == _FALSE) {
  315. bLegalChannel = _FALSE;
  316. RTW_INFO("Channel > 14 but wireless_mode do not support 5G\n");
  317. }
  318. } else if ((Channel <= 14) && (Channel >= 1)) {
  319. if (IsSupported24G(Adapter->registrypriv.wireless_mode) == _FALSE) {
  320. bLegalChannel = _FALSE;
  321. RTW_INFO("(Channel <= 14) && (Channel >=1) but wireless_mode do not support 2.4G\n");
  322. }
  323. } else {
  324. bLegalChannel = _FALSE;
  325. RTW_INFO("Channel is Invalid !!!\n");
  326. }
  327. return bLegalChannel;
  328. }
  329. u8 MRateToHwRate(u8 rate)
  330. {
  331. u8 ret = DESC_RATE1M;
  332. switch (rate) {
  333. case MGN_1M:
  334. ret = DESC_RATE1M;
  335. break;
  336. case MGN_2M:
  337. ret = DESC_RATE2M;
  338. break;
  339. case MGN_5_5M:
  340. ret = DESC_RATE5_5M;
  341. break;
  342. case MGN_11M:
  343. ret = DESC_RATE11M;
  344. break;
  345. case MGN_6M:
  346. ret = DESC_RATE6M;
  347. break;
  348. case MGN_9M:
  349. ret = DESC_RATE9M;
  350. break;
  351. case MGN_12M:
  352. ret = DESC_RATE12M;
  353. break;
  354. case MGN_18M:
  355. ret = DESC_RATE18M;
  356. break;
  357. case MGN_24M:
  358. ret = DESC_RATE24M;
  359. break;
  360. case MGN_36M:
  361. ret = DESC_RATE36M;
  362. break;
  363. case MGN_48M:
  364. ret = DESC_RATE48M;
  365. break;
  366. case MGN_54M:
  367. ret = DESC_RATE54M;
  368. break;
  369. case MGN_MCS0:
  370. ret = DESC_RATEMCS0;
  371. break;
  372. case MGN_MCS1:
  373. ret = DESC_RATEMCS1;
  374. break;
  375. case MGN_MCS2:
  376. ret = DESC_RATEMCS2;
  377. break;
  378. case MGN_MCS3:
  379. ret = DESC_RATEMCS3;
  380. break;
  381. case MGN_MCS4:
  382. ret = DESC_RATEMCS4;
  383. break;
  384. case MGN_MCS5:
  385. ret = DESC_RATEMCS5;
  386. break;
  387. case MGN_MCS6:
  388. ret = DESC_RATEMCS6;
  389. break;
  390. case MGN_MCS7:
  391. ret = DESC_RATEMCS7;
  392. break;
  393. case MGN_MCS8:
  394. ret = DESC_RATEMCS8;
  395. break;
  396. case MGN_MCS9:
  397. ret = DESC_RATEMCS9;
  398. break;
  399. case MGN_MCS10:
  400. ret = DESC_RATEMCS10;
  401. break;
  402. case MGN_MCS11:
  403. ret = DESC_RATEMCS11;
  404. break;
  405. case MGN_MCS12:
  406. ret = DESC_RATEMCS12;
  407. break;
  408. case MGN_MCS13:
  409. ret = DESC_RATEMCS13;
  410. break;
  411. case MGN_MCS14:
  412. ret = DESC_RATEMCS14;
  413. break;
  414. case MGN_MCS15:
  415. ret = DESC_RATEMCS15;
  416. break;
  417. case MGN_MCS16:
  418. ret = DESC_RATEMCS16;
  419. break;
  420. case MGN_MCS17:
  421. ret = DESC_RATEMCS17;
  422. break;
  423. case MGN_MCS18:
  424. ret = DESC_RATEMCS18;
  425. break;
  426. case MGN_MCS19:
  427. ret = DESC_RATEMCS19;
  428. break;
  429. case MGN_MCS20:
  430. ret = DESC_RATEMCS20;
  431. break;
  432. case MGN_MCS21:
  433. ret = DESC_RATEMCS21;
  434. break;
  435. case MGN_MCS22:
  436. ret = DESC_RATEMCS22;
  437. break;
  438. case MGN_MCS23:
  439. ret = DESC_RATEMCS23;
  440. break;
  441. case MGN_MCS24:
  442. ret = DESC_RATEMCS24;
  443. break;
  444. case MGN_MCS25:
  445. ret = DESC_RATEMCS25;
  446. break;
  447. case MGN_MCS26:
  448. ret = DESC_RATEMCS26;
  449. break;
  450. case MGN_MCS27:
  451. ret = DESC_RATEMCS27;
  452. break;
  453. case MGN_MCS28:
  454. ret = DESC_RATEMCS28;
  455. break;
  456. case MGN_MCS29:
  457. ret = DESC_RATEMCS29;
  458. break;
  459. case MGN_MCS30:
  460. ret = DESC_RATEMCS30;
  461. break;
  462. case MGN_MCS31:
  463. ret = DESC_RATEMCS31;
  464. break;
  465. case MGN_VHT1SS_MCS0:
  466. ret = DESC_RATEVHTSS1MCS0;
  467. break;
  468. case MGN_VHT1SS_MCS1:
  469. ret = DESC_RATEVHTSS1MCS1;
  470. break;
  471. case MGN_VHT1SS_MCS2:
  472. ret = DESC_RATEVHTSS1MCS2;
  473. break;
  474. case MGN_VHT1SS_MCS3:
  475. ret = DESC_RATEVHTSS1MCS3;
  476. break;
  477. case MGN_VHT1SS_MCS4:
  478. ret = DESC_RATEVHTSS1MCS4;
  479. break;
  480. case MGN_VHT1SS_MCS5:
  481. ret = DESC_RATEVHTSS1MCS5;
  482. break;
  483. case MGN_VHT1SS_MCS6:
  484. ret = DESC_RATEVHTSS1MCS6;
  485. break;
  486. case MGN_VHT1SS_MCS7:
  487. ret = DESC_RATEVHTSS1MCS7;
  488. break;
  489. case MGN_VHT1SS_MCS8:
  490. ret = DESC_RATEVHTSS1MCS8;
  491. break;
  492. case MGN_VHT1SS_MCS9:
  493. ret = DESC_RATEVHTSS1MCS9;
  494. break;
  495. case MGN_VHT2SS_MCS0:
  496. ret = DESC_RATEVHTSS2MCS0;
  497. break;
  498. case MGN_VHT2SS_MCS1:
  499. ret = DESC_RATEVHTSS2MCS1;
  500. break;
  501. case MGN_VHT2SS_MCS2:
  502. ret = DESC_RATEVHTSS2MCS2;
  503. break;
  504. case MGN_VHT2SS_MCS3:
  505. ret = DESC_RATEVHTSS2MCS3;
  506. break;
  507. case MGN_VHT2SS_MCS4:
  508. ret = DESC_RATEVHTSS2MCS4;
  509. break;
  510. case MGN_VHT2SS_MCS5:
  511. ret = DESC_RATEVHTSS2MCS5;
  512. break;
  513. case MGN_VHT2SS_MCS6:
  514. ret = DESC_RATEVHTSS2MCS6;
  515. break;
  516. case MGN_VHT2SS_MCS7:
  517. ret = DESC_RATEVHTSS2MCS7;
  518. break;
  519. case MGN_VHT2SS_MCS8:
  520. ret = DESC_RATEVHTSS2MCS8;
  521. break;
  522. case MGN_VHT2SS_MCS9:
  523. ret = DESC_RATEVHTSS2MCS9;
  524. break;
  525. case MGN_VHT3SS_MCS0:
  526. ret = DESC_RATEVHTSS3MCS0;
  527. break;
  528. case MGN_VHT3SS_MCS1:
  529. ret = DESC_RATEVHTSS3MCS1;
  530. break;
  531. case MGN_VHT3SS_MCS2:
  532. ret = DESC_RATEVHTSS3MCS2;
  533. break;
  534. case MGN_VHT3SS_MCS3:
  535. ret = DESC_RATEVHTSS3MCS3;
  536. break;
  537. case MGN_VHT3SS_MCS4:
  538. ret = DESC_RATEVHTSS3MCS4;
  539. break;
  540. case MGN_VHT3SS_MCS5:
  541. ret = DESC_RATEVHTSS3MCS5;
  542. break;
  543. case MGN_VHT3SS_MCS6:
  544. ret = DESC_RATEVHTSS3MCS6;
  545. break;
  546. case MGN_VHT3SS_MCS7:
  547. ret = DESC_RATEVHTSS3MCS7;
  548. break;
  549. case MGN_VHT3SS_MCS8:
  550. ret = DESC_RATEVHTSS3MCS8;
  551. break;
  552. case MGN_VHT3SS_MCS9:
  553. ret = DESC_RATEVHTSS3MCS9;
  554. break;
  555. case MGN_VHT4SS_MCS0:
  556. ret = DESC_RATEVHTSS4MCS0;
  557. break;
  558. case MGN_VHT4SS_MCS1:
  559. ret = DESC_RATEVHTSS4MCS1;
  560. break;
  561. case MGN_VHT4SS_MCS2:
  562. ret = DESC_RATEVHTSS4MCS2;
  563. break;
  564. case MGN_VHT4SS_MCS3:
  565. ret = DESC_RATEVHTSS4MCS3;
  566. break;
  567. case MGN_VHT4SS_MCS4:
  568. ret = DESC_RATEVHTSS4MCS4;
  569. break;
  570. case MGN_VHT4SS_MCS5:
  571. ret = DESC_RATEVHTSS4MCS5;
  572. break;
  573. case MGN_VHT4SS_MCS6:
  574. ret = DESC_RATEVHTSS4MCS6;
  575. break;
  576. case MGN_VHT4SS_MCS7:
  577. ret = DESC_RATEVHTSS4MCS7;
  578. break;
  579. case MGN_VHT4SS_MCS8:
  580. ret = DESC_RATEVHTSS4MCS8;
  581. break;
  582. case MGN_VHT4SS_MCS9:
  583. ret = DESC_RATEVHTSS4MCS9;
  584. break;
  585. default:
  586. break;
  587. }
  588. return ret;
  589. }
  590. u8 hw_rate_to_m_rate(u8 rate)
  591. {
  592. u8 ret_rate = MGN_1M;
  593. switch (rate) {
  594. case DESC_RATE1M:
  595. ret_rate = MGN_1M;
  596. break;
  597. case DESC_RATE2M:
  598. ret_rate = MGN_2M;
  599. break;
  600. case DESC_RATE5_5M:
  601. ret_rate = MGN_5_5M;
  602. break;
  603. case DESC_RATE11M:
  604. ret_rate = MGN_11M;
  605. break;
  606. case DESC_RATE6M:
  607. ret_rate = MGN_6M;
  608. break;
  609. case DESC_RATE9M:
  610. ret_rate = MGN_9M;
  611. break;
  612. case DESC_RATE12M:
  613. ret_rate = MGN_12M;
  614. break;
  615. case DESC_RATE18M:
  616. ret_rate = MGN_18M;
  617. break;
  618. case DESC_RATE24M:
  619. ret_rate = MGN_24M;
  620. break;
  621. case DESC_RATE36M:
  622. ret_rate = MGN_36M;
  623. break;
  624. case DESC_RATE48M:
  625. ret_rate = MGN_48M;
  626. break;
  627. case DESC_RATE54M:
  628. ret_rate = MGN_54M;
  629. break;
  630. case DESC_RATEMCS0:
  631. ret_rate = MGN_MCS0;
  632. break;
  633. case DESC_RATEMCS1:
  634. ret_rate = MGN_MCS1;
  635. break;
  636. case DESC_RATEMCS2:
  637. ret_rate = MGN_MCS2;
  638. break;
  639. case DESC_RATEMCS3:
  640. ret_rate = MGN_MCS3;
  641. break;
  642. case DESC_RATEMCS4:
  643. ret_rate = MGN_MCS4;
  644. break;
  645. case DESC_RATEMCS5:
  646. ret_rate = MGN_MCS5;
  647. break;
  648. case DESC_RATEMCS6:
  649. ret_rate = MGN_MCS6;
  650. break;
  651. case DESC_RATEMCS7:
  652. ret_rate = MGN_MCS7;
  653. break;
  654. case DESC_RATEMCS8:
  655. ret_rate = MGN_MCS8;
  656. break;
  657. case DESC_RATEMCS9:
  658. ret_rate = MGN_MCS9;
  659. break;
  660. case DESC_RATEMCS10:
  661. ret_rate = MGN_MCS10;
  662. break;
  663. case DESC_RATEMCS11:
  664. ret_rate = MGN_MCS11;
  665. break;
  666. case DESC_RATEMCS12:
  667. ret_rate = MGN_MCS12;
  668. break;
  669. case DESC_RATEMCS13:
  670. ret_rate = MGN_MCS13;
  671. break;
  672. case DESC_RATEMCS14:
  673. ret_rate = MGN_MCS14;
  674. break;
  675. case DESC_RATEMCS15:
  676. ret_rate = MGN_MCS15;
  677. break;
  678. case DESC_RATEMCS16:
  679. ret_rate = MGN_MCS16;
  680. break;
  681. case DESC_RATEMCS17:
  682. ret_rate = MGN_MCS17;
  683. break;
  684. case DESC_RATEMCS18:
  685. ret_rate = MGN_MCS18;
  686. break;
  687. case DESC_RATEMCS19:
  688. ret_rate = MGN_MCS19;
  689. break;
  690. case DESC_RATEMCS20:
  691. ret_rate = MGN_MCS20;
  692. break;
  693. case DESC_RATEMCS21:
  694. ret_rate = MGN_MCS21;
  695. break;
  696. case DESC_RATEMCS22:
  697. ret_rate = MGN_MCS22;
  698. break;
  699. case DESC_RATEMCS23:
  700. ret_rate = MGN_MCS23;
  701. break;
  702. case DESC_RATEMCS24:
  703. ret_rate = MGN_MCS24;
  704. break;
  705. case DESC_RATEMCS25:
  706. ret_rate = MGN_MCS25;
  707. break;
  708. case DESC_RATEMCS26:
  709. ret_rate = MGN_MCS26;
  710. break;
  711. case DESC_RATEMCS27:
  712. ret_rate = MGN_MCS27;
  713. break;
  714. case DESC_RATEMCS28:
  715. ret_rate = MGN_MCS28;
  716. break;
  717. case DESC_RATEMCS29:
  718. ret_rate = MGN_MCS29;
  719. break;
  720. case DESC_RATEMCS30:
  721. ret_rate = MGN_MCS30;
  722. break;
  723. case DESC_RATEMCS31:
  724. ret_rate = MGN_MCS31;
  725. break;
  726. case DESC_RATEVHTSS1MCS0:
  727. ret_rate = MGN_VHT1SS_MCS0;
  728. break;
  729. case DESC_RATEVHTSS1MCS1:
  730. ret_rate = MGN_VHT1SS_MCS1;
  731. break;
  732. case DESC_RATEVHTSS1MCS2:
  733. ret_rate = MGN_VHT1SS_MCS2;
  734. break;
  735. case DESC_RATEVHTSS1MCS3:
  736. ret_rate = MGN_VHT1SS_MCS3;
  737. break;
  738. case DESC_RATEVHTSS1MCS4:
  739. ret_rate = MGN_VHT1SS_MCS4;
  740. break;
  741. case DESC_RATEVHTSS1MCS5:
  742. ret_rate = MGN_VHT1SS_MCS5;
  743. break;
  744. case DESC_RATEVHTSS1MCS6:
  745. ret_rate = MGN_VHT1SS_MCS6;
  746. break;
  747. case DESC_RATEVHTSS1MCS7:
  748. ret_rate = MGN_VHT1SS_MCS7;
  749. break;
  750. case DESC_RATEVHTSS1MCS8:
  751. ret_rate = MGN_VHT1SS_MCS8;
  752. break;
  753. case DESC_RATEVHTSS1MCS9:
  754. ret_rate = MGN_VHT1SS_MCS9;
  755. break;
  756. case DESC_RATEVHTSS2MCS0:
  757. ret_rate = MGN_VHT2SS_MCS0;
  758. break;
  759. case DESC_RATEVHTSS2MCS1:
  760. ret_rate = MGN_VHT2SS_MCS1;
  761. break;
  762. case DESC_RATEVHTSS2MCS2:
  763. ret_rate = MGN_VHT2SS_MCS2;
  764. break;
  765. case DESC_RATEVHTSS2MCS3:
  766. ret_rate = MGN_VHT2SS_MCS3;
  767. break;
  768. case DESC_RATEVHTSS2MCS4:
  769. ret_rate = MGN_VHT2SS_MCS4;
  770. break;
  771. case DESC_RATEVHTSS2MCS5:
  772. ret_rate = MGN_VHT2SS_MCS5;
  773. break;
  774. case DESC_RATEVHTSS2MCS6:
  775. ret_rate = MGN_VHT2SS_MCS6;
  776. break;
  777. case DESC_RATEVHTSS2MCS7:
  778. ret_rate = MGN_VHT2SS_MCS7;
  779. break;
  780. case DESC_RATEVHTSS2MCS8:
  781. ret_rate = MGN_VHT2SS_MCS8;
  782. break;
  783. case DESC_RATEVHTSS2MCS9:
  784. ret_rate = MGN_VHT2SS_MCS9;
  785. break;
  786. case DESC_RATEVHTSS3MCS0:
  787. ret_rate = MGN_VHT3SS_MCS0;
  788. break;
  789. case DESC_RATEVHTSS3MCS1:
  790. ret_rate = MGN_VHT3SS_MCS1;
  791. break;
  792. case DESC_RATEVHTSS3MCS2:
  793. ret_rate = MGN_VHT3SS_MCS2;
  794. break;
  795. case DESC_RATEVHTSS3MCS3:
  796. ret_rate = MGN_VHT3SS_MCS3;
  797. break;
  798. case DESC_RATEVHTSS3MCS4:
  799. ret_rate = MGN_VHT3SS_MCS4;
  800. break;
  801. case DESC_RATEVHTSS3MCS5:
  802. ret_rate = MGN_VHT3SS_MCS5;
  803. break;
  804. case DESC_RATEVHTSS3MCS6:
  805. ret_rate = MGN_VHT3SS_MCS6;
  806. break;
  807. case DESC_RATEVHTSS3MCS7:
  808. ret_rate = MGN_VHT3SS_MCS7;
  809. break;
  810. case DESC_RATEVHTSS3MCS8:
  811. ret_rate = MGN_VHT3SS_MCS8;
  812. break;
  813. case DESC_RATEVHTSS3MCS9:
  814. ret_rate = MGN_VHT3SS_MCS9;
  815. break;
  816. case DESC_RATEVHTSS4MCS0:
  817. ret_rate = MGN_VHT4SS_MCS0;
  818. break;
  819. case DESC_RATEVHTSS4MCS1:
  820. ret_rate = MGN_VHT4SS_MCS1;
  821. break;
  822. case DESC_RATEVHTSS4MCS2:
  823. ret_rate = MGN_VHT4SS_MCS2;
  824. break;
  825. case DESC_RATEVHTSS4MCS3:
  826. ret_rate = MGN_VHT4SS_MCS3;
  827. break;
  828. case DESC_RATEVHTSS4MCS4:
  829. ret_rate = MGN_VHT4SS_MCS4;
  830. break;
  831. case DESC_RATEVHTSS4MCS5:
  832. ret_rate = MGN_VHT4SS_MCS5;
  833. break;
  834. case DESC_RATEVHTSS4MCS6:
  835. ret_rate = MGN_VHT4SS_MCS6;
  836. break;
  837. case DESC_RATEVHTSS4MCS7:
  838. ret_rate = MGN_VHT4SS_MCS7;
  839. break;
  840. case DESC_RATEVHTSS4MCS8:
  841. ret_rate = MGN_VHT4SS_MCS8;
  842. break;
  843. case DESC_RATEVHTSS4MCS9:
  844. ret_rate = MGN_VHT4SS_MCS9;
  845. break;
  846. default:
  847. RTW_INFO("hw_rate_to_m_rate(): Non supported Rate [%x]!!!\n", rate);
  848. break;
  849. }
  850. return ret_rate;
  851. }
  852. void HalSetBrateCfg(
  853. IN PADAPTER Adapter,
  854. IN u8 *mBratesOS,
  855. OUT u16 *pBrateCfg)
  856. {
  857. u8 i, is_brate, brate;
  858. for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
  859. is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
  860. brate = mBratesOS[i] & 0x7f;
  861. if (is_brate) {
  862. switch (brate) {
  863. case IEEE80211_CCK_RATE_1MB:
  864. *pBrateCfg |= RATE_1M;
  865. break;
  866. case IEEE80211_CCK_RATE_2MB:
  867. *pBrateCfg |= RATE_2M;
  868. break;
  869. case IEEE80211_CCK_RATE_5MB:
  870. *pBrateCfg |= RATE_5_5M;
  871. break;
  872. case IEEE80211_CCK_RATE_11MB:
  873. *pBrateCfg |= RATE_11M;
  874. break;
  875. case IEEE80211_OFDM_RATE_6MB:
  876. *pBrateCfg |= RATE_6M;
  877. break;
  878. case IEEE80211_OFDM_RATE_9MB:
  879. *pBrateCfg |= RATE_9M;
  880. break;
  881. case IEEE80211_OFDM_RATE_12MB:
  882. *pBrateCfg |= RATE_12M;
  883. break;
  884. case IEEE80211_OFDM_RATE_18MB:
  885. *pBrateCfg |= RATE_18M;
  886. break;
  887. case IEEE80211_OFDM_RATE_24MB:
  888. *pBrateCfg |= RATE_24M;
  889. break;
  890. case IEEE80211_OFDM_RATE_36MB:
  891. *pBrateCfg |= RATE_36M;
  892. break;
  893. case IEEE80211_OFDM_RATE_48MB:
  894. *pBrateCfg |= RATE_48M;
  895. break;
  896. case IEEE80211_OFDM_RATE_54MB:
  897. *pBrateCfg |= RATE_54M;
  898. break;
  899. }
  900. }
  901. }
  902. }
  903. static VOID
  904. _OneOutPipeMapping(
  905. IN PADAPTER pAdapter
  906. )
  907. {
  908. struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
  909. pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
  910. pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
  911. pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */
  912. pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
  913. pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
  914. pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
  915. pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
  916. pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
  917. }
  918. static VOID
  919. _TwoOutPipeMapping(
  920. IN PADAPTER pAdapter,
  921. IN BOOLEAN bWIFICfg
  922. )
  923. {
  924. struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
  925. if (bWIFICfg) { /* WMM */
  926. /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
  927. /* { 0, 1, 0, 1, 0, 0, 0, 0, 0 }; */
  928. /* 0:ep_0 num, 1:ep_1 num */
  929. pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */
  930. pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
  931. pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
  932. pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
  933. pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
  934. pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
  935. pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
  936. pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
  937. } else { /* typical setting */
  938. /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
  939. /* { 1, 1, 0, 0, 0, 0, 0, 0, 0 }; */
  940. /* 0:ep_0 num, 1:ep_1 num */
  941. pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
  942. pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
  943. pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
  944. pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
  945. pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
  946. pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
  947. pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
  948. pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
  949. }
  950. }
  951. static VOID _ThreeOutPipeMapping(
  952. IN PADAPTER pAdapter,
  953. IN BOOLEAN bWIFICfg
  954. )
  955. {
  956. struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
  957. if (bWIFICfg) { /* for WMM */
  958. /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
  959. /* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
  960. /* 0:H, 1:N, 2:L */
  961. pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
  962. pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
  963. pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
  964. pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
  965. pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
  966. pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
  967. pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
  968. pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
  969. } else { /* typical setting */
  970. /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
  971. /* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
  972. /* 0:H, 1:N, 2:L */
  973. pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
  974. pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
  975. pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
  976. pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
  977. pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
  978. pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
  979. pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
  980. pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
  981. }
  982. }
  983. static VOID _FourOutPipeMapping(
  984. IN PADAPTER pAdapter,
  985. IN BOOLEAN bWIFICfg
  986. )
  987. {
  988. struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
  989. if (bWIFICfg) { /* for WMM */
  990. /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
  991. /* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
  992. /* 0:H, 1:N, 2:L ,3:E */
  993. pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
  994. pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
  995. pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
  996. pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
  997. pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
  998. pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
  999. pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
  1000. pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
  1001. } else { /* typical setting */
  1002. /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
  1003. /* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
  1004. /* 0:H, 1:N, 2:L */
  1005. pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
  1006. pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
  1007. pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
  1008. pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
  1009. pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
  1010. pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
  1011. pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
  1012. pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
  1013. }
  1014. }
  1015. BOOLEAN
  1016. Hal_MappingOutPipe(
  1017. IN PADAPTER pAdapter,
  1018. IN u8 NumOutPipe
  1019. )
  1020. {
  1021. struct registry_priv *pregistrypriv = &pAdapter->registrypriv;
  1022. BOOLEAN bWIFICfg = (pregistrypriv->wifi_spec) ? _TRUE : _FALSE;
  1023. BOOLEAN result = _TRUE;
  1024. switch (NumOutPipe) {
  1025. case 2:
  1026. _TwoOutPipeMapping(pAdapter, bWIFICfg);
  1027. break;
  1028. case 3:
  1029. case 4:
  1030. case 5:
  1031. case 6:
  1032. _ThreeOutPipeMapping(pAdapter, bWIFICfg);
  1033. break;
  1034. case 1:
  1035. _OneOutPipeMapping(pAdapter);
  1036. break;
  1037. default:
  1038. result = _FALSE;
  1039. break;
  1040. }
  1041. return result;
  1042. }
  1043. void rtw_hal_reqtxrpt(_adapter *padapter, u8 macid)
  1044. {
  1045. if (padapter->hal_func.reqtxrpt)
  1046. padapter->hal_func.reqtxrpt(padapter, macid);
  1047. }
  1048. void rtw_hal_dump_macaddr(void *sel, _adapter *adapter)
  1049. {
  1050. int i;
  1051. _adapter *iface;
  1052. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  1053. u8 mac_addr[ETH_ALEN];
  1054. #ifdef CONFIG_MI_WITH_MBSSID_CAM
  1055. rtw_mbid_cam_dump(sel, __func__, adapter);
  1056. #else
  1057. for (i = 0; i < dvobj->iface_nums; i++) {
  1058. iface = dvobj->padapters[i];
  1059. if (iface) {
  1060. rtw_hal_get_hwreg(iface, HW_VAR_MAC_ADDR, mac_addr);
  1061. RTW_PRINT_SEL(sel, ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n",
  1062. ADPT_ARG(iface), iface->hw_port, MAC_ARG(mac_addr));
  1063. }
  1064. }
  1065. #endif
  1066. }
  1067. #ifdef RTW_HALMAC
  1068. void rtw_hal_hw_port_enable(_adapter *adapter)
  1069. {
  1070. #if 1
  1071. u8 port_enable = _TRUE;
  1072. rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
  1073. #else
  1074. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  1075. struct rtw_halmac_bcn_ctrl bcn_ctrl;
  1076. _rtw_memset(&bcn_ctrl, 0, sizeof(struct rtw_halmac_bcn_ctrl));
  1077. bcn_ctrl.enable_bcn = 1;
  1078. bcn_ctrl.rx_bssid_fit = 1;
  1079. bcn_ctrl.rxbcn_rpt = 1;
  1080. /*rtw_halmac_get_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,
  1081. struct rtw_halmac_bcn_ctrl *bcn_ctrl)*/
  1082. if (rtw_halmac_set_bcn_ctrl(dvobj, get_hw_port(adapter), &bcn_ctrl) == -1) {
  1083. RTW_ERR(ADPT_FMT" - hw port(%d) enable fail!!\n", ADPT_ARG(adapter), get_hw_port(adapter));
  1084. rtw_warn_on(1);
  1085. }
  1086. #endif
  1087. }
  1088. void rtw_hal_hw_port_disable(_adapter *adapter)
  1089. {
  1090. u8 port_enable = _FALSE;
  1091. rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
  1092. }
  1093. void rtw_restore_hw_port_cfg(_adapter *adapter)
  1094. {
  1095. #ifdef CONFIG_MI_WITH_MBSSID_CAM
  1096. #else
  1097. int i;
  1098. _adapter *iface;
  1099. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  1100. for (i = 0; i < dvobj->iface_nums; i++) {
  1101. iface = dvobj->padapters[i];
  1102. if (iface)
  1103. rtw_hal_hw_port_enable(iface);
  1104. }
  1105. #endif
  1106. }
  1107. #endif
  1108. void rtw_mi_set_mac_addr(_adapter *adapter)
  1109. {
  1110. #ifdef CONFIG_MI_WITH_MBSSID_CAM
  1111. rtw_mi_set_mbid_cam(adapter);
  1112. #else
  1113. int i;
  1114. _adapter *iface;
  1115. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  1116. for (i = 0; i < dvobj->iface_nums; i++) {
  1117. iface = dvobj->padapters[i];
  1118. if (iface)
  1119. rtw_hal_set_hwreg(iface, HW_VAR_MAC_ADDR, adapter_mac_addr(iface));
  1120. }
  1121. #endif
  1122. if (1)
  1123. rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter);
  1124. }
  1125. void rtw_init_hal_com_default_value(PADAPTER Adapter)
  1126. {
  1127. PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
  1128. struct registry_priv *regsty = adapter_to_regsty(Adapter);
  1129. pHalData->AntDetection = 1;
  1130. pHalData->antenna_test = _FALSE;
  1131. pHalData->RegIQKFWOffload = regsty->iqk_fw_offload;
  1132. pHalData->ch_switch_offload = regsty->ch_switch_offload;
  1133. #ifdef RTW_REDUCE_SCAN_SWITCH_CH_TIME
  1134. if (pHalData->ch_switch_offload == 0)
  1135. pHalData->ch_switch_offload = 1;
  1136. #endif
  1137. }
  1138. #ifdef CONFIG_FW_C2H_REG
  1139. void c2h_evt_clear(_adapter *adapter)
  1140. {
  1141. rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
  1142. }
  1143. s32 c2h_evt_read_88xx(_adapter *adapter, u8 *buf)
  1144. {
  1145. s32 ret = _FAIL;
  1146. int i;
  1147. u8 trigger;
  1148. if (buf == NULL)
  1149. goto exit;
  1150. trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
  1151. if (trigger == C2H_EVT_HOST_CLOSE) {
  1152. goto exit; /* Not ready */
  1153. } else if (trigger != C2H_EVT_FW_CLOSE) {
  1154. goto clear_evt; /* Not a valid value */
  1155. }
  1156. _rtw_memset(buf, 0, C2H_REG_LEN);
  1157. /* Read ID, LEN, SEQ */
  1158. SET_C2H_ID_88XX(buf, rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL));
  1159. SET_C2H_SEQ_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX));
  1160. SET_C2H_PLEN_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX));
  1161. if (0) {
  1162. RTW_INFO("%s id=0x%02x, seq=%u, plen=%u, trigger=0x%02x\n", __func__
  1163. , C2H_ID_88XX(buf), C2H_SEQ_88XX(buf), C2H_PLEN_88XX(buf), trigger);
  1164. }
  1165. /* Read the content */
  1166. for (i = 0; i < C2H_PLEN_88XX(buf); i++)
  1167. *(C2H_PAYLOAD_88XX(buf) + i) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
  1168. RTW_DBG_DUMP("payload: ", C2H_PAYLOAD_88XX(buf), C2H_PLEN_88XX(buf));
  1169. ret = _SUCCESS;
  1170. clear_evt:
  1171. /*
  1172. * Clear event to notify FW we have read the command.
  1173. * If this field isn't clear, the FW won't update the next command message.
  1174. */
  1175. c2h_evt_clear(adapter);
  1176. exit:
  1177. return ret;
  1178. }
  1179. #endif /* CONFIG_FW_C2H_REG */
  1180. #ifdef CONFIG_FW_C2H_PKT
  1181. #ifndef DBG_C2H_PKT_PRE_HDL
  1182. #define DBG_C2H_PKT_PRE_HDL 0
  1183. #endif
  1184. #ifndef DBG_C2H_PKT_HDL
  1185. #define DBG_C2H_PKT_HDL 0
  1186. #endif
  1187. void rtw_hal_c2h_pkt_pre_hdl(_adapter *adapter, u8 *buf, u16 len)
  1188. {
  1189. #ifdef RTW_HALMAC
  1190. /* TODO: extract hal_mac IC's code here*/
  1191. #else
  1192. u8 parse_fail = 0;
  1193. u8 hdl_here = 0;
  1194. s32 ret = _FAIL;
  1195. u8 id, seq, plen;
  1196. u8 *payload;
  1197. if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
  1198. parse_fail = 1;
  1199. goto exit;
  1200. }
  1201. hdl_here = rtw_hal_c2h_id_handle_directly(adapter, id, seq, plen, payload) == _TRUE ? 1 : 0;
  1202. if (hdl_here)
  1203. ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
  1204. else
  1205. ret = rtw_c2h_packet_wk_cmd(adapter, buf, len);
  1206. exit:
  1207. if (parse_fail)
  1208. RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
  1209. else if (ret != _SUCCESS || DBG_C2H_PKT_PRE_HDL > 0) {
  1210. RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
  1211. , hdl_here ? "handle" : "enqueue"
  1212. , ret == _SUCCESS ? "ok" : "fail"
  1213. );
  1214. if (DBG_C2H_PKT_PRE_HDL >= 2)
  1215. RTW_PRINT_DUMP("dump: ", buf, len);
  1216. }
  1217. #endif
  1218. }
  1219. void rtw_hal_c2h_pkt_hdl(_adapter *adapter, u8 *buf, u16 len)
  1220. {
  1221. #ifdef RTW_HALMAC
  1222. adapter->hal_func.hal_mac_c2h_handler(adapter, buf, len);
  1223. #else
  1224. u8 parse_fail = 0;
  1225. u8 bypass = 0;
  1226. s32 ret = _FAIL;
  1227. u8 id, seq, plen;
  1228. u8 *payload;
  1229. if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
  1230. parse_fail = 1;
  1231. goto exit;
  1232. }
  1233. #ifdef CONFIG_WOWLAN
  1234. if (adapter_to_pwrctl(adapter)->wowlan_mode == _TRUE) {
  1235. bypass = 1;
  1236. ret = _SUCCESS;
  1237. goto exit;
  1238. }
  1239. #endif
  1240. ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
  1241. exit:
  1242. if (parse_fail)
  1243. RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
  1244. else if (ret != _SUCCESS || bypass || DBG_C2H_PKT_HDL > 0) {
  1245. RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
  1246. , !bypass ? "handle" : "bypass"
  1247. , ret == _SUCCESS ? "ok" : "fail"
  1248. );
  1249. if (DBG_C2H_PKT_HDL >= 2)
  1250. RTW_PRINT_DUMP("dump: ", buf, len);
  1251. }
  1252. #endif
  1253. }
  1254. #endif /* CONFIG_FW_C2H_PKT */
  1255. void c2h_iqk_offload(_adapter *adapter, u8 *data, u8 len)
  1256. {
  1257. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
  1258. struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
  1259. RTW_INFO("IQK offload finish in %dms\n", rtw_get_passing_time_ms(iqk_sctx->submit_time));
  1260. if (0)
  1261. RTW_INFO_DUMP("C2H_IQK_FINISH: ", data, len);
  1262. rtw_sctx_done(&iqk_sctx);
  1263. }
  1264. int c2h_iqk_offload_wait(_adapter *adapter, u32 timeout_ms)
  1265. {
  1266. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
  1267. struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
  1268. iqk_sctx->submit_time = rtw_get_current_time();
  1269. iqk_sctx->timeout_ms = timeout_ms;
  1270. iqk_sctx->status = RTW_SCTX_SUBMITTED;
  1271. return rtw_sctx_wait(iqk_sctx, __func__);
  1272. }
  1273. #define GET_C2H_MAC_HIDDEN_RPT_UUID_X(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 8)
  1274. #define GET_C2H_MAC_HIDDEN_RPT_UUID_Y(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
  1275. #define GET_C2H_MAC_HIDDEN_RPT_UUID_Z(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 5)
  1276. #define GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 2, 5, 11)
  1277. #define GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 4)
  1278. #define GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 4, 3)
  1279. #define GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 7, 1)
  1280. #define GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 4)
  1281. #define GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 4, 4)
  1282. #define GET_C2H_MAC_HIDDEN_RPT_BW(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 3)
  1283. #define GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 5, 3)
  1284. #define GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 2, 2)
  1285. #define GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 6, 2)
  1286. #ifndef DBG_C2H_MAC_HIDDEN_RPT_HANDLE
  1287. #define DBG_C2H_MAC_HIDDEN_RPT_HANDLE 0
  1288. #endif
  1289. #ifdef CONFIG_RTW_MAC_HIDDEN_RPT
  1290. int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
  1291. {
  1292. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
  1293. struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
  1294. int ret = _FAIL;
  1295. u32 uuid;
  1296. u8 uuid_x;
  1297. u8 uuid_y;
  1298. u8 uuid_z;
  1299. u16 uuid_crc;
  1300. u8 hci_type;
  1301. u8 package_type;
  1302. u8 tr_switch;
  1303. u8 wl_func;
  1304. u8 hw_stype;
  1305. u8 bw;
  1306. u8 ant_num;
  1307. u8 protocol;
  1308. u8 nic;
  1309. int i;
  1310. if (len < MAC_HIDDEN_RPT_LEN) {
  1311. RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_LEN);
  1312. goto exit;
  1313. }
  1314. uuid_x = GET_C2H_MAC_HIDDEN_RPT_UUID_X(data);
  1315. uuid_y = GET_C2H_MAC_HIDDEN_RPT_UUID_Y(data);
  1316. uuid_z = GET_C2H_MAC_HIDDEN_RPT_UUID_Z(data);
  1317. uuid_crc = GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(data);
  1318. hci_type = GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(data);
  1319. package_type = GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(data);
  1320. tr_switch = GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(data);
  1321. wl_func = GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(data);
  1322. hw_stype = GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(data);
  1323. bw = GET_C2H_MAC_HIDDEN_RPT_BW(data);
  1324. ant_num = GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(data);
  1325. protocol = GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(data);
  1326. nic = GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(data);
  1327. if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
  1328. for (i = 0; i < len; i++)
  1329. RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
  1330. RTW_PRINT("uuid x:0x%02x y:0x%02x z:0x%x crc:0x%x\n", uuid_x, uuid_y, uuid_z, uuid_crc);
  1331. RTW_PRINT("hci_type:0x%x\n", hci_type);
  1332. RTW_PRINT("package_type:0x%x\n", package_type);
  1333. RTW_PRINT("tr_switch:0x%x\n", tr_switch);
  1334. RTW_PRINT("wl_func:0x%x\n", wl_func);
  1335. RTW_PRINT("hw_stype:0x%x\n", hw_stype);
  1336. RTW_PRINT("bw:0x%x\n", bw);
  1337. RTW_PRINT("ant_num:0x%x\n", ant_num);
  1338. RTW_PRINT("protocol:0x%x\n", protocol);
  1339. RTW_PRINT("nic:0x%x\n", nic);
  1340. }
  1341. /*
  1342. * NOTICE:
  1343. * for now, the following is common info/format
  1344. * if there is any hal difference need to export
  1345. * some IC dependent code will need to be implement
  1346. */
  1347. hal_data->PackageType = package_type;
  1348. hal_spec->wl_func &= mac_hidden_wl_func_to_hal_wl_func(wl_func);
  1349. hal_spec->bw_cap &= mac_hidden_max_bw_to_hal_bw_cap(bw);
  1350. hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, ant_num);
  1351. hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, ant_num);
  1352. hal_spec->proto_cap &= mac_hidden_proto_to_hal_proto_cap(protocol);
  1353. hal_spec->hci_type = hci_type;
  1354. /* TODO: tr_switch */
  1355. ret = _SUCCESS;
  1356. exit:
  1357. return ret;
  1358. }
  1359. int c2h_mac_hidden_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
  1360. {
  1361. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
  1362. struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
  1363. int ret = _FAIL;
  1364. int i;
  1365. if (len < MAC_HIDDEN_RPT_2_LEN) {
  1366. RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_2_LEN);
  1367. goto exit;
  1368. }
  1369. if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
  1370. for (i = 0; i < len; i++)
  1371. RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
  1372. }
  1373. #if defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV)
  1374. if (IS_8188F(hal_data->version_id) || IS_8188GTV(hal_data->version_id)) {
  1375. #define GET_C2H_MAC_HIDDEN_RPT_IRV(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 4)
  1376. u8 irv = GET_C2H_MAC_HIDDEN_RPT_IRV(data);
  1377. if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
  1378. RTW_PRINT("irv:0x%x\n", irv);
  1379. if(irv != 0xf)
  1380. hal_data->version_id.CUTVersion = irv;
  1381. }
  1382. #endif
  1383. ret = _SUCCESS;
  1384. exit:
  1385. return ret;
  1386. }
  1387. int hal_read_mac_hidden_rpt(_adapter *adapter)
  1388. {
  1389. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
  1390. int ret = _FAIL;
  1391. int ret_fwdl;
  1392. u8 mac_hidden_rpt[MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN] = {0};
  1393. systime start = rtw_get_current_time();
  1394. u32 cnt = 0;
  1395. u32 timeout_ms = 800;
  1396. u32 min_cnt = 10;
  1397. u8 id = C2H_DEFEATURE_RSVD;
  1398. int i;
  1399. #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
  1400. u8 hci_type = rtw_get_intf_type(adapter);
  1401. if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
  1402. && !rtw_is_hw_init_completed(adapter))
  1403. rtw_hal_power_on(adapter);
  1404. #endif
  1405. /* inform FW mac hidden rpt from reg is needed */
  1406. rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DEFEATURE_RSVD);
  1407. /* download FW */
  1408. pHalData->not_xmitframe_fw_dl = 1;
  1409. ret_fwdl = rtw_hal_fw_dl(adapter, _FALSE);
  1410. pHalData->not_xmitframe_fw_dl = 0;
  1411. if (ret_fwdl != _SUCCESS)
  1412. goto mac_hidden_rpt_hdl;
  1413. /* polling for data ready */
  1414. start = rtw_get_current_time();
  1415. do {
  1416. cnt++;
  1417. id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
  1418. if (id == C2H_MAC_HIDDEN_RPT || RTW_CANNOT_IO(adapter))
  1419. break;
  1420. rtw_msleep_os(10);
  1421. } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
  1422. if (id == C2H_MAC_HIDDEN_RPT) {
  1423. /* read data */
  1424. for (i = 0; i < MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN; i++)
  1425. mac_hidden_rpt[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
  1426. }
  1427. /* inform FW mac hidden rpt has read */
  1428. rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DBG);
  1429. mac_hidden_rpt_hdl:
  1430. c2h_mac_hidden_rpt_hdl(adapter, mac_hidden_rpt, MAC_HIDDEN_RPT_LEN);
  1431. c2h_mac_hidden_rpt_2_hdl(adapter, mac_hidden_rpt + MAC_HIDDEN_RPT_LEN, MAC_HIDDEN_RPT_2_LEN);
  1432. if (ret_fwdl == _SUCCESS && id == C2H_MAC_HIDDEN_RPT)
  1433. ret = _SUCCESS;
  1434. exit:
  1435. #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
  1436. if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
  1437. && !rtw_is_hw_init_completed(adapter))
  1438. rtw_hal_power_off(adapter);
  1439. #endif
  1440. RTW_INFO("%s %s! (%u, %dms), fwdl:%d, id:0x%02x\n", __func__
  1441. , (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), ret_fwdl, id);
  1442. return ret;
  1443. }
  1444. #endif /* CONFIG_RTW_MAC_HIDDEN_RPT */
  1445. int c2h_defeature_dbg_hdl(_adapter *adapter, u8 *data, u8 len)
  1446. {
  1447. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
  1448. struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
  1449. int ret = _FAIL;
  1450. int i;
  1451. if (len < DEFEATURE_DBG_LEN) {
  1452. RTW_WARN("%s len(%u) < %d\n", __func__, len, DEFEATURE_DBG_LEN);
  1453. goto exit;
  1454. }
  1455. for (i = 0; i < len; i++)
  1456. RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
  1457. ret = _SUCCESS;
  1458. exit:
  1459. return ret;
  1460. }
  1461. #ifndef DBG_CUSTOMER_STR_RPT_HANDLE
  1462. #define DBG_CUSTOMER_STR_RPT_HANDLE 0
  1463. #endif
  1464. #ifdef CONFIG_RTW_CUSTOMER_STR
  1465. s32 rtw_hal_h2c_customer_str_req(_adapter *adapter)
  1466. {
  1467. u8 h2c_data[H2C_CUSTOMER_STR_REQ_LEN] = {0};
  1468. SET_H2CCMD_CUSTOMER_STR_REQ_EN(h2c_data, 1);
  1469. return rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_REQ, H2C_CUSTOMER_STR_REQ_LEN, h2c_data);
  1470. }
  1471. #define C2H_CUSTOMER_STR_RPT_BYTE0(_data) ((u8 *)(_data))
  1472. #define C2H_CUSTOMER_STR_RPT_2_BYTE8(_data) ((u8 *)(_data))
  1473. int c2h_customer_str_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
  1474. {
  1475. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  1476. int ret = _FAIL;
  1477. int i;
  1478. if (len < CUSTOMER_STR_RPT_LEN) {
  1479. RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_LEN);
  1480. goto exit;
  1481. }
  1482. if (DBG_CUSTOMER_STR_RPT_HANDLE)
  1483. RTW_PRINT_DUMP("customer_str_rpt: ", data, CUSTOMER_STR_RPT_LEN);
  1484. _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
  1485. if (dvobj->customer_str_sctx != NULL) {
  1486. if (dvobj->customer_str_sctx->status != RTW_SCTX_SUBMITTED)
  1487. RTW_WARN("%s invalid sctx.status:%d\n", __func__, dvobj->customer_str_sctx->status);
  1488. _rtw_memcpy(dvobj->customer_str, C2H_CUSTOMER_STR_RPT_BYTE0(data), CUSTOMER_STR_RPT_LEN);
  1489. dvobj->customer_str_sctx->status = RTX_SCTX_CSTR_WAIT_RPT2;
  1490. } else
  1491. RTW_WARN("%s sctx not set\n", __func__);
  1492. _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
  1493. ret = _SUCCESS;
  1494. exit:
  1495. return ret;
  1496. }
  1497. int c2h_customer_str_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
  1498. {
  1499. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  1500. int ret = _FAIL;
  1501. int i;
  1502. if (len < CUSTOMER_STR_RPT_2_LEN) {
  1503. RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_2_LEN);
  1504. goto exit;
  1505. }
  1506. if (DBG_CUSTOMER_STR_RPT_HANDLE)
  1507. RTW_PRINT_DUMP("customer_str_rpt_2: ", data, CUSTOMER_STR_RPT_2_LEN);
  1508. _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
  1509. if (dvobj->customer_str_sctx != NULL) {
  1510. if (dvobj->customer_str_sctx->status != RTX_SCTX_CSTR_WAIT_RPT2)
  1511. RTW_WARN("%s rpt not ready\n", __func__);
  1512. _rtw_memcpy(dvobj->customer_str + CUSTOMER_STR_RPT_LEN, C2H_CUSTOMER_STR_RPT_2_BYTE8(data), CUSTOMER_STR_RPT_2_LEN);
  1513. rtw_sctx_done(&dvobj->customer_str_sctx);
  1514. } else
  1515. RTW_WARN("%s sctx not set\n", __func__);
  1516. _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
  1517. ret = _SUCCESS;
  1518. exit:
  1519. return ret;
  1520. }
  1521. /* read customer str */
  1522. s32 rtw_hal_customer_str_read(_adapter *adapter, u8 *cs)
  1523. {
  1524. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  1525. struct submit_ctx sctx;
  1526. s32 ret = _SUCCESS;
  1527. _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
  1528. if (dvobj->customer_str_sctx != NULL)
  1529. ret = _FAIL;
  1530. else {
  1531. rtw_sctx_init(&sctx, 2 * 1000);
  1532. dvobj->customer_str_sctx = &sctx;
  1533. }
  1534. _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
  1535. if (ret == _FAIL) {
  1536. RTW_WARN("%s another handle ongoing\n", __func__);
  1537. goto exit;
  1538. }
  1539. ret = rtw_customer_str_req_cmd(adapter);
  1540. if (ret != _SUCCESS) {
  1541. RTW_WARN("%s read cmd fail\n", __func__);
  1542. _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
  1543. dvobj->customer_str_sctx = NULL;
  1544. _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
  1545. goto exit;
  1546. }
  1547. /* wait till rpt done or timeout */
  1548. rtw_sctx_wait(&sctx, __func__);
  1549. _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
  1550. dvobj->customer_str_sctx = NULL;
  1551. if (sctx.status == RTW_SCTX_DONE_SUCCESS)
  1552. _rtw_memcpy(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
  1553. else
  1554. ret = _FAIL;
  1555. _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
  1556. exit:
  1557. return ret;
  1558. }
  1559. s32 rtw_hal_h2c_customer_str_write(_adapter *adapter, const u8 *cs)
  1560. {
  1561. u8 h2c_data_w1[H2C_CUSTOMER_STR_W1_LEN] = {0};
  1562. u8 h2c_data_w2[H2C_CUSTOMER_STR_W2_LEN] = {0};
  1563. u8 h2c_data_w3[H2C_CUSTOMER_STR_W3_LEN] = {0};
  1564. s32 ret;
  1565. SET_H2CCMD_CUSTOMER_STR_W1_EN(h2c_data_w1, 1);
  1566. _rtw_memcpy(H2CCMD_CUSTOMER_STR_W1_BYTE0(h2c_data_w1), cs, 6);
  1567. SET_H2CCMD_CUSTOMER_STR_W2_EN(h2c_data_w2, 1);
  1568. _rtw_memcpy(H2CCMD_CUSTOMER_STR_W2_BYTE6(h2c_data_w2), cs + 6, 6);
  1569. SET_H2CCMD_CUSTOMER_STR_W3_EN(h2c_data_w3, 1);
  1570. _rtw_memcpy(H2CCMD_CUSTOMER_STR_W3_BYTE12(h2c_data_w3), cs + 6 + 6, 4);
  1571. ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W1, H2C_CUSTOMER_STR_W1_LEN, h2c_data_w1);
  1572. if (ret != _SUCCESS) {
  1573. RTW_WARN("%s w1 fail\n", __func__);
  1574. goto exit;
  1575. }
  1576. ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W2, H2C_CUSTOMER_STR_W2_LEN, h2c_data_w2);
  1577. if (ret != _SUCCESS) {
  1578. RTW_WARN("%s w2 fail\n", __func__);
  1579. goto exit;
  1580. }
  1581. ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W3, H2C_CUSTOMER_STR_W3_LEN, h2c_data_w3);
  1582. if (ret != _SUCCESS) {
  1583. RTW_WARN("%s w3 fail\n", __func__);
  1584. goto exit;
  1585. }
  1586. exit:
  1587. return ret;
  1588. }
  1589. /* write customer str and check if value reported is the same as requested */
  1590. s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs)
  1591. {
  1592. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  1593. struct submit_ctx sctx;
  1594. s32 ret = _SUCCESS;
  1595. _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
  1596. if (dvobj->customer_str_sctx != NULL)
  1597. ret = _FAIL;
  1598. else {
  1599. rtw_sctx_init(&sctx, 2 * 1000);
  1600. dvobj->customer_str_sctx = &sctx;
  1601. }
  1602. _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
  1603. if (ret == _FAIL) {
  1604. RTW_WARN("%s another handle ongoing\n", __func__);
  1605. goto exit;
  1606. }
  1607. ret = rtw_customer_str_write_cmd(adapter, cs);
  1608. if (ret != _SUCCESS) {
  1609. RTW_WARN("%s write cmd fail\n", __func__);
  1610. _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
  1611. dvobj->customer_str_sctx = NULL;
  1612. _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
  1613. goto exit;
  1614. }
  1615. ret = rtw_customer_str_req_cmd(adapter);
  1616. if (ret != _SUCCESS) {
  1617. RTW_WARN("%s read cmd fail\n", __func__);
  1618. _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
  1619. dvobj->customer_str_sctx = NULL;
  1620. _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
  1621. goto exit;
  1622. }
  1623. /* wait till rpt done or timeout */
  1624. rtw_sctx_wait(&sctx, __func__);
  1625. _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
  1626. dvobj->customer_str_sctx = NULL;
  1627. if (sctx.status == RTW_SCTX_DONE_SUCCESS) {
  1628. if (_rtw_memcmp(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN) != _TRUE) {
  1629. RTW_WARN("%s read back check fail\n", __func__);
  1630. RTW_INFO_DUMP("write req: ", cs, RTW_CUSTOMER_STR_LEN);
  1631. RTW_INFO_DUMP("read back: ", dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
  1632. ret = _FAIL;
  1633. }
  1634. } else
  1635. ret = _FAIL;
  1636. _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
  1637. exit:
  1638. return ret;
  1639. }
  1640. #endif /* CONFIG_RTW_CUSTOMER_STR */
  1641. #ifdef RTW_PER_CMD_SUPPORT_FW
  1642. #define H2C_REQ_PER_RPT_LEN 5
  1643. #define SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 4, __Value)
  1644. #define SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 4, __Value)
  1645. #define SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(__pH2CCmd, __Value) SET_BITS_TO_LE_4BYTE(__pH2CCmd + 1, 0, 32, __Value)
  1646. u8 rtw_hal_set_req_per_rpt_cmd(_adapter *adapter, u8 group_macid,
  1647. u8 rpt_type, u32 macid_bitmap)
  1648. {
  1649. u8 ret = _FAIL;
  1650. u8 cmd_buf[H2C_REQ_PER_RPT_LEN] = {0};
  1651. SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(cmd_buf, group_macid);
  1652. SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(cmd_buf, rpt_type);
  1653. SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(cmd_buf, macid_bitmap);
  1654. ret = rtw_hal_fill_h2c_cmd(adapter,
  1655. H2C_REQ_PER_RPT,
  1656. H2C_REQ_PER_RPT_LEN,
  1657. cmd_buf);
  1658. return ret;
  1659. }
  1660. #define GET_C2H_PER_RATE_RPT_TYPE0_MACID0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
  1661. #define GET_C2H_PER_RATE_RPT_TYPE0_PER0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
  1662. #define GET_C2H_PER_RATE_RPT_TYPE0_RATE0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)
  1663. #define GET_C2H_PER_RATE_RPT_TYPE0_BW0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)
  1664. #define GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 4, 0, 16)
  1665. #define GET_C2H_PER_RATE_RPT_TYPE0_MACID1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)
  1666. #define GET_C2H_PER_RATE_RPT_TYPE0_PER1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 8)
  1667. #define GET_C2H_PER_RATE_RPT_TYPE0_RATE1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)
  1668. #define GET_C2H_PER_RATE_RPT_TYPE0_BW1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 2)
  1669. #define GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 10, 0, 16)
  1670. #define GET_C2H_PER_RATE_RPT_TYPE1_MACID0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
  1671. #define GET_C2H_PER_RATE_RPT_TYPE1_PER0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
  1672. #define GET_C2H_PER_RATE_RPT_TYPE1_RATE0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)
  1673. #define GET_C2H_PER_RATE_RPT_TYPE1_BW0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)
  1674. #define GET_C2H_PER_RATE_RPT_TYPE1_MACID1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 8)
  1675. #define GET_C2H_PER_RATE_RPT_TYPE1_PER1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 8)
  1676. #define GET_C2H_PER_RATE_RPT_TYPE1_RATE1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)
  1677. #define GET_C2H_PER_RATE_RPT_TYPE1_BW1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 2)
  1678. #define GET_C2H_PER_RATE_RPT_TYPE1_MACID2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)
  1679. #define GET_C2H_PER_RATE_RPT_TYPE1_PER2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 8)
  1680. #define GET_C2H_PER_RATE_RPT_TYPE1_RATE2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 10, 0, 8)
  1681. #define GET_C2H_PER_RATE_RPT_TYPE1_BW2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 11, 0, 2)
  1682. static void per_rate_rpt_update(_adapter *adapter, u8 mac_id,
  1683. u8 per, u8 rate,
  1684. u8 bw, u8 total_pkt)
  1685. {
  1686. #ifdef CONFIG_RTW_MESH
  1687. rtw_ieee80211s_update_metric(adapter, mac_id,
  1688. per, rate,
  1689. bw, total_pkt);
  1690. #endif
  1691. }
  1692. int c2h_per_rate_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
  1693. {
  1694. /* Now only consider type0, since it covers all params in type1
  1695. * type0: mac_id, per, rate, bw, total_pkt
  1696. * type1: mac_id, per, rate, bw
  1697. */
  1698. u8 mac_id[2] = {0}, per[2] = {0}, rate[2] = {0}, bw[2] = {0};
  1699. u16 total_pkt[2] = {0};
  1700. int ret = _FAIL, i, macid_cnt = 0;
  1701. /* type0:
  1702. * 1 macid includes 6 bytes info + 1 byte 0xff
  1703. * 2 macid includes 2*6 bytes info
  1704. */
  1705. if (!(len == 7 || len == 12)) {
  1706. RTW_WARN("%s len(%u) != 7 or 12\n", __FUNCTION__, len);
  1707. goto exit;
  1708. }
  1709. macid_cnt++;
  1710. mac_id[0] = GET_C2H_PER_RATE_RPT_TYPE0_MACID0(data);
  1711. per[0] = GET_C2H_PER_RATE_RPT_TYPE0_PER0(data);
  1712. rate[0] = GET_C2H_PER_RATE_RPT_TYPE0_RATE0(data);
  1713. bw[0] = GET_C2H_PER_RATE_RPT_TYPE0_BW0(data);
  1714. total_pkt[0] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(data);
  1715. mac_id[1] = GET_C2H_PER_RATE_RPT_TYPE0_MACID1(data);
  1716. /* 0xff means no report anymore */
  1717. if (mac_id[1] == 0xff)
  1718. goto update_per;
  1719. if (len != 12) {
  1720. RTW_WARN("%s incorrect format\n", __FUNCTION__);
  1721. goto exit;
  1722. }
  1723. macid_cnt++;
  1724. per[1] = GET_C2H_PER_RATE_RPT_TYPE0_PER1(data);
  1725. rate[1] = GET_C2H_PER_RATE_RPT_TYPE0_RATE1(data);
  1726. bw[1] = GET_C2H_PER_RATE_RPT_TYPE0_BW1(data);
  1727. total_pkt[1] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(data);
  1728. update_per:
  1729. for (i = 0; i < macid_cnt; i++) {
  1730. RTW_DBG("[%s] type0 rpt[%d]: macid = %u, per = %u, "
  1731. "rate = %u, bw = %u, total_pkt = %u\n",
  1732. __FUNCTION__, i, mac_id[i], per[i],
  1733. rate[i], bw[i], total_pkt[i]);
  1734. per_rate_rpt_update(adapter, mac_id[i],
  1735. per[i], rate[i],
  1736. bw[i], total_pkt[i]);
  1737. }
  1738. ret = _SUCCESS;
  1739. exit:
  1740. return ret;
  1741. }
  1742. #endif /* RTW_PER_CMD_SUPPORT_FW */
  1743. void rtw_hal_update_sta_wset(_adapter *adapter, struct sta_info *psta)
  1744. {
  1745. u8 w_set = 0;
  1746. if (psta->wireless_mode & WIRELESS_11B)
  1747. w_set |= WIRELESS_CCK;
  1748. if ((psta->wireless_mode & WIRELESS_11G) || (psta->wireless_mode & WIRELESS_11A))
  1749. w_set |= WIRELESS_OFDM;
  1750. if (psta->wireless_mode & WIRELESS_11_24N)
  1751. w_set |= WIRELESS_HT;
  1752. if ((psta->wireless_mode & WIRELESS_11AC) || (psta->wireless_mode & WIRELESS_11_5N))
  1753. w_set |= WIRELESS_VHT;
  1754. psta->cmn.support_wireless_set = w_set;
  1755. }
  1756. void rtw_hal_update_sta_mimo_type(_adapter *adapter, struct sta_info *psta)
  1757. {
  1758. s8 tx_nss, rx_nss;
  1759. tx_nss = rtw_get_sta_tx_nss(adapter, psta);
  1760. rx_nss = rtw_get_sta_rx_nss(adapter, psta);
  1761. if ((tx_nss == 1) && (rx_nss == 1))
  1762. psta->cmn.mimo_type = RF_1T1R;
  1763. else if ((tx_nss == 1) && (rx_nss == 2))
  1764. psta->cmn.mimo_type = RF_1T2R;
  1765. else if ((tx_nss == 2) && (rx_nss == 2))
  1766. psta->cmn.mimo_type = RF_2T2R;
  1767. else if ((tx_nss == 2) && (rx_nss == 3))
  1768. psta->cmn.mimo_type = RF_2T3R;
  1769. else if ((tx_nss == 2) && (rx_nss == 4))
  1770. psta->cmn.mimo_type = RF_2T4R;
  1771. else if ((tx_nss == 3) && (rx_nss == 3))
  1772. psta->cmn.mimo_type = RF_3T3R;
  1773. else if ((tx_nss == 3) && (rx_nss == 4))
  1774. psta->cmn.mimo_type = RF_3T4R;
  1775. else if ((tx_nss == 4) && (rx_nss == 4))
  1776. psta->cmn.mimo_type = RF_4T4R;
  1777. else
  1778. rtw_warn_on(1);
  1779. RTW_INFO("STA - MAC_ID:%d, Tx - %d SS, Rx - %d SS\n",
  1780. psta->cmn.mac_id, tx_nss, rx_nss);
  1781. }
  1782. void rtw_hal_update_sta_smps_cap(_adapter *adapter, struct sta_info *psta)
  1783. {
  1784. /*Spatial Multiplexing Power Save*/
  1785. #if 0
  1786. if (check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
  1787. #ifdef CONFIG_80211N_HT
  1788. if (psta->htpriv.ht_option) {
  1789. if (psta->htpriv.smps_cap == 0)
  1790. psta->cmn.sm_ps = SM_PS_STATIC;
  1791. else if (psta->htpriv.smps_cap == 1)
  1792. psta->cmn.sm_ps = SM_PS_DYNAMIC;
  1793. else
  1794. psta->cmn.sm_ps = SM_PS_DISABLE;
  1795. }
  1796. #endif /* CONFIG_80211N_HT */
  1797. } else
  1798. #endif
  1799. psta->cmn.sm_ps = SM_PS_DISABLE;
  1800. RTW_INFO("STA - MAC_ID:%d, SM_PS %d\n",
  1801. psta->cmn.mac_id, psta->cmn.sm_ps);
  1802. }
  1803. u8 rtw_get_mgntframe_raid(_adapter *adapter, unsigned char network_type)
  1804. {
  1805. u8 raid;
  1806. if (IS_NEW_GENERATION_IC(adapter)) {
  1807. raid = (network_type & WIRELESS_11B) ? RATEID_IDX_B
  1808. : RATEID_IDX_G;
  1809. } else {
  1810. raid = (network_type & WIRELESS_11B) ? RATR_INX_WIRELESS_B
  1811. : RATR_INX_WIRELESS_G;
  1812. }
  1813. return raid;
  1814. }
  1815. void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta)
  1816. {
  1817. struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
  1818. u8 i, rf_type, tx_nss;
  1819. u64 tx_ra_bitmap = 0, tmp64=0;
  1820. if (psta == NULL)
  1821. return;
  1822. /* b/g mode ra_bitmap */
  1823. for (i = 0; i < sizeof(psta->bssrateset); i++) {
  1824. if (psta->bssrateset[i])
  1825. tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);
  1826. }
  1827. #ifdef CONFIG_80211N_HT
  1828. if (padapter->registrypriv.ht_enable && is_supported_ht(padapter->registrypriv.wireless_mode)) {
  1829. rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
  1830. tx_nss = rtw_min(rf_type_to_rf_tx_cnt(rf_type), hal_spec->tx_nss_num);
  1831. #ifdef CONFIG_80211AC_VHT
  1832. if (psta->vhtpriv.vht_option) {
  1833. /* AC mode ra_bitmap */
  1834. tx_ra_bitmap |= (rtw_vht_mcs_map_to_bitmap(psta->vhtpriv.vht_mcs_map, tx_nss) << 12);
  1835. } else
  1836. #endif /* CONFIG_80211AC_VHT */
  1837. if (psta->htpriv.ht_option) {
  1838. /* n mode ra_bitmap */
  1839. /* Handling SMPS mode for AP MODE only*/
  1840. if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
  1841. /*0:static SMPS, 1:dynamic SMPS, 3:SMPS disabled, 2:reserved*/
  1842. if (psta->htpriv.smps_cap == 0 || psta->htpriv.smps_cap == 1) {
  1843. /*operate with only one active receive chain // 11n-MCS rate <= MSC7*/
  1844. tx_nss = rtw_min(tx_nss, 1);
  1845. }
  1846. }
  1847. tmp64 = rtw_ht_mcs_set_to_bitmap(psta->htpriv.ht_cap.supp_mcs_set, tx_nss);
  1848. tx_ra_bitmap |= (tmp64 << 12);
  1849. }
  1850. }
  1851. #endif /* CONFIG_80211N_HT */
  1852. psta->cmn.ra_info.ramask = tx_ra_bitmap;
  1853. psta->init_rate = get_highest_rate_idx(tx_ra_bitmap) & 0x3f;
  1854. }
  1855. void rtw_hal_update_sta_ra_info(PADAPTER padapter, struct sta_info *psta)
  1856. {
  1857. rtw_hal_update_sta_mimo_type(padapter, psta);
  1858. rtw_hal_update_sta_smps_cap(padapter, psta);
  1859. rtw_hal_update_sta_rate_mask(padapter, psta);
  1860. }
  1861. static u32 hw_bcn_ctrl_addr(_adapter *adapter, u8 hw_port)
  1862. {
  1863. struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
  1864. if (hw_port >= hal_spec->port_num) {
  1865. RTW_ERR(FUNC_ADPT_FMT" HW Port(%d) invalid\n", FUNC_ADPT_ARG(adapter), hw_port);
  1866. rtw_warn_on(1);
  1867. return 0;
  1868. }
  1869. switch (hw_port) {
  1870. case HW_PORT0:
  1871. return REG_BCN_CTRL;
  1872. case HW_PORT1:
  1873. return REG_BCN_CTRL_1;
  1874. }
  1875. return 0;
  1876. }
  1877. static void rtw_hal_get_msr(_adapter *adapter, u8 *net_type)
  1878. {
  1879. #ifdef RTW_HALMAC
  1880. rtw_halmac_get_network_type(adapter_to_dvobj(adapter),
  1881. adapter->hw_port, net_type);
  1882. #else /* !RTW_HALMAC */
  1883. switch (adapter->hw_port) {
  1884. case HW_PORT0:
  1885. /*REG_CR - BIT[17:16]-Network Type for port 1*/
  1886. *net_type = rtw_read8(adapter, MSR) & 0x03;
  1887. break;
  1888. case HW_PORT1:
  1889. /*REG_CR - BIT[19:18]-Network Type for port 1*/
  1890. *net_type = (rtw_read8(adapter, MSR) & 0x0C) >> 2;
  1891. break;
  1892. #if defined(CONFIG_RTL8814A)
  1893. case HW_PORT2:
  1894. /*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
  1895. *net_type = rtw_read8(adapter, MSR1) & 0x03;
  1896. break;
  1897. case HW_PORT3:
  1898. /*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
  1899. *net_type = (rtw_read8(adapter, MSR1) & 0x0C) >> 2;
  1900. break;
  1901. case HW_PORT4:
  1902. /*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
  1903. *net_type = (rtw_read8(adapter, MSR1) & 0x30) >> 4;
  1904. break;
  1905. #endif /*#if defined(CONFIG_RTL8814A)*/
  1906. default:
  1907. RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
  1908. ADPT_ARG(adapter), adapter->hw_port);
  1909. rtw_warn_on(1);
  1910. break;
  1911. }
  1912. #endif /* !RTW_HALMAC */
  1913. }
  1914. #if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM) /*For 2 hw ports - 88E/92E/8812/8821/8723B*/
  1915. static u8 rtw_hal_net_type_decision(_adapter *adapter, u8 net_type)
  1916. {
  1917. if ((adapter->hw_port == HW_PORT0) && (rtw_get_mbid_cam_entry_num(adapter))) {
  1918. if (net_type != _HW_STATE_NOLINK_)
  1919. return _HW_STATE_AP_;
  1920. }
  1921. return net_type;
  1922. }
  1923. #endif
  1924. static void rtw_hal_set_msr(_adapter *adapter, u8 net_type)
  1925. {
  1926. #ifdef RTW_HALMAC
  1927. #if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
  1928. net_type = rtw_hal_net_type_decision(adapter, net_type);
  1929. #endif
  1930. rtw_halmac_set_network_type(adapter_to_dvobj(adapter),
  1931. adapter->hw_port, net_type);
  1932. #else /* !RTW_HALMAC */
  1933. u8 val8 = 0;
  1934. switch (adapter->hw_port) {
  1935. case HW_PORT0:
  1936. #if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
  1937. net_type = rtw_hal_net_type_decision(adapter, net_type);
  1938. #endif
  1939. /*REG_CR - BIT[17:16]-Network Type for port 0*/
  1940. val8 = rtw_read8(adapter, MSR) & 0x0C;
  1941. val8 |= net_type;
  1942. rtw_write8(adapter, MSR, val8);
  1943. break;
  1944. case HW_PORT1:
  1945. /*REG_CR - BIT[19:18]-Network Type for port 1*/
  1946. val8 = rtw_read8(adapter, MSR) & 0x03;
  1947. val8 |= net_type << 2;
  1948. rtw_write8(adapter, MSR, val8);
  1949. break;
  1950. #if defined(CONFIG_RTL8814A)
  1951. case HW_PORT2:
  1952. /*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
  1953. val8 = rtw_read8(adapter, MSR1) & 0xFC;
  1954. val8 |= net_type;
  1955. rtw_write8(adapter, MSR1, val8);
  1956. break;
  1957. case HW_PORT3:
  1958. /*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
  1959. val8 = rtw_read8(adapter, MSR1) & 0xF3;
  1960. val8 |= net_type << 2;
  1961. rtw_write8(adapter, MSR1, val8);
  1962. break;
  1963. case HW_PORT4:
  1964. /*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
  1965. val8 = rtw_read8(adapter, MSR1) & 0xCF;
  1966. val8 |= net_type << 4;
  1967. rtw_write8(adapter, MSR1, val8);
  1968. break;
  1969. #endif /* CONFIG_RTL8814A */
  1970. default:
  1971. RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
  1972. ADPT_ARG(adapter), adapter->hw_port);
  1973. rtw_warn_on(1);
  1974. break;
  1975. }
  1976. #endif /* !RTW_HALMAC */
  1977. }
  1978. #ifndef SEC_CAM_ACCESS_TIMEOUT_MS
  1979. #define SEC_CAM_ACCESS_TIMEOUT_MS 200
  1980. #endif
  1981. #ifndef DBG_SEC_CAM_ACCESS
  1982. #define DBG_SEC_CAM_ACCESS 0
  1983. #endif
  1984. u32 rtw_sec_read_cam(_adapter *adapter, u8 addr)
  1985. {
  1986. _mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
  1987. u32 rdata;
  1988. u32 cnt = 0;
  1989. systime start = 0, end = 0;
  1990. u8 timeout = 0;
  1991. u8 sr = 0;
  1992. _enter_critical_mutex(mutex, NULL);
  1993. rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | addr);
  1994. start = rtw_get_current_time();
  1995. while (1) {
  1996. if (rtw_is_surprise_removed(adapter)) {
  1997. sr = 1;
  1998. break;
  1999. }
  2000. cnt++;
  2001. if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
  2002. break;
  2003. if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
  2004. timeout = 1;
  2005. break;
  2006. }
  2007. }
  2008. end = rtw_get_current_time();
  2009. rdata = rtw_read32(adapter, REG_CAMREAD);
  2010. _exit_critical_mutex(mutex, NULL);
  2011. if (DBG_SEC_CAM_ACCESS || timeout) {
  2012. RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, rdata:0x%08x, to:%u, polling:%u, %d ms\n"
  2013. , FUNC_ADPT_ARG(adapter), addr, rdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
  2014. }
  2015. return rdata;
  2016. }
  2017. void rtw_sec_write_cam(_adapter *adapter, u8 addr, u32 wdata)
  2018. {
  2019. _mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
  2020. u32 cnt = 0;
  2021. systime start = 0, end = 0;
  2022. u8 timeout = 0;
  2023. u8 sr = 0;
  2024. _enter_critical_mutex(mutex, NULL);
  2025. rtw_write32(adapter, REG_CAMWRITE, wdata);
  2026. rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | CAM_WRITE | addr);
  2027. start = rtw_get_current_time();
  2028. while (1) {
  2029. if (rtw_is_surprise_removed(adapter)) {
  2030. sr = 1;
  2031. break;
  2032. }
  2033. cnt++;
  2034. if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
  2035. break;
  2036. if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
  2037. timeout = 1;
  2038. break;
  2039. }
  2040. }
  2041. end = rtw_get_current_time();
  2042. _exit_critical_mutex(mutex, NULL);
  2043. if (DBG_SEC_CAM_ACCESS || timeout) {
  2044. RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
  2045. , FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
  2046. }
  2047. }
  2048. void rtw_sec_read_cam_ent(_adapter *adapter, u8 id, u8 *ctrl, u8 *mac, u8 *key)
  2049. {
  2050. unsigned int val, addr;
  2051. u8 i;
  2052. u32 rdata;
  2053. u8 begin = 0;
  2054. u8 end = 5; /* TODO: consider other key length accordingly */
  2055. if (!ctrl && !mac && !key) {
  2056. rtw_warn_on(1);
  2057. goto exit;
  2058. }
  2059. /* TODO: check id range */
  2060. if (!ctrl && !mac)
  2061. begin = 2; /* read from key */
  2062. if (!key && !mac)
  2063. end = 0; /* read to ctrl */
  2064. else if (!key)
  2065. end = 2; /* read to mac */
  2066. for (i = begin; i <= end; i++) {
  2067. rdata = rtw_sec_read_cam(adapter, (id << 3) | i);
  2068. switch (i) {
  2069. case 0:
  2070. if (ctrl)
  2071. _rtw_memcpy(ctrl, (u8 *)(&rdata), 2);
  2072. if (mac)
  2073. _rtw_memcpy(mac, ((u8 *)(&rdata)) + 2, 2);
  2074. break;
  2075. case 1:
  2076. if (mac)
  2077. _rtw_memcpy(mac + 2, (u8 *)(&rdata), 4);
  2078. break;
  2079. default:
  2080. if (key)
  2081. _rtw_memcpy(key + (i - 2) * 4, (u8 *)(&rdata), 4);
  2082. break;
  2083. }
  2084. }
  2085. exit:
  2086. return;
  2087. }
  2088. void rtw_sec_write_cam_ent(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
  2089. {
  2090. unsigned int i;
  2091. int j;
  2092. u8 addr, addr1 = 0;
  2093. u32 wdata, wdata1 = 0;
  2094. /* TODO: consider other key length accordingly */
  2095. #if 0
  2096. switch ((ctrl & 0x1c) >> 2) {
  2097. case _WEP40_:
  2098. case _TKIP_:
  2099. case _AES_:
  2100. case _WEP104_:
  2101. }
  2102. #else
  2103. j = 7;
  2104. #endif
  2105. for (; j >= 0; j--) {
  2106. switch (j) {
  2107. case 0:
  2108. wdata = (ctrl | (mac[0] << 16) | (mac[1] << 24));
  2109. break;
  2110. case 1:
  2111. wdata = (mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24));
  2112. break;
  2113. case 6:
  2114. case 7:
  2115. wdata = 0;
  2116. break;
  2117. default:
  2118. i = (j - 2) << 2;
  2119. wdata = (key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24));
  2120. break;
  2121. }
  2122. addr = (id << 3) + j;
  2123. #if defined(CONFIG_RTL8192F)
  2124. if(j == 1) {
  2125. wdata1 = wdata;
  2126. addr1 = addr;
  2127. continue;
  2128. }
  2129. #endif
  2130. rtw_sec_write_cam(adapter, addr, wdata);
  2131. }
  2132. #if defined(CONFIG_RTL8192F)
  2133. rtw_sec_write_cam(adapter, addr1, wdata1);
  2134. #endif
  2135. }
  2136. void rtw_sec_clr_cam_ent(_adapter *adapter, u8 id)
  2137. {
  2138. u8 addr;
  2139. addr = (id << 3);
  2140. rtw_sec_write_cam(adapter, addr, 0);
  2141. }
  2142. bool rtw_sec_read_cam_is_gk(_adapter *adapter, u8 id)
  2143. {
  2144. bool res;
  2145. u16 ctrl;
  2146. rtw_sec_read_cam_ent(adapter, id, (u8 *)&ctrl, NULL, NULL);
  2147. res = (ctrl & BIT6) ? _TRUE : _FALSE;
  2148. return res;
  2149. }
  2150. #ifdef CONFIG_MBSSID_CAM
  2151. void rtw_mbid_cam_init(struct dvobj_priv *dvobj)
  2152. {
  2153. struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
  2154. _rtw_spinlock_init(&mbid_cam_ctl->lock);
  2155. mbid_cam_ctl->bitmap = 0;
  2156. ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
  2157. _rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
  2158. }
  2159. void rtw_mbid_cam_deinit(struct dvobj_priv *dvobj)
  2160. {
  2161. struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
  2162. _rtw_spinlock_free(&mbid_cam_ctl->lock);
  2163. }
  2164. void rtw_mbid_cam_reset(_adapter *adapter)
  2165. {
  2166. _irqL irqL;
  2167. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  2168. struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
  2169. _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
  2170. mbid_cam_ctl->bitmap = 0;
  2171. _rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
  2172. _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
  2173. ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
  2174. }
  2175. static u8 _rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
  2176. {
  2177. u8 i;
  2178. u8 cam_id = INVALID_CAM_ID;
  2179. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  2180. for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
  2181. if (mac_addr && _rtw_memcmp(dvobj->mbid_cam_cache[i].mac_addr, mac_addr, ETH_ALEN) == _TRUE) {
  2182. cam_id = i;
  2183. break;
  2184. }
  2185. }
  2186. RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
  2187. return cam_id;
  2188. }
  2189. u8 rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
  2190. {
  2191. _irqL irqL;
  2192. u8 cam_id = INVALID_CAM_ID;
  2193. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  2194. struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
  2195. _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
  2196. cam_id = _rtw_mbid_cam_search_by_macaddr(adapter, mac_addr);
  2197. _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
  2198. return cam_id;
  2199. }
  2200. static u8 _rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
  2201. {
  2202. u8 i;
  2203. u8 cam_id = INVALID_CAM_ID;
  2204. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  2205. for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
  2206. if (iface_id == dvobj->mbid_cam_cache[i].iface_id) {
  2207. cam_id = i;
  2208. break;
  2209. }
  2210. }
  2211. if (cam_id != INVALID_CAM_ID)
  2212. RTW_INFO("%s iface_id:%d mac:"MAC_FMT" - cam_id:%d\n",
  2213. __func__, iface_id, MAC_ARG(dvobj->mbid_cam_cache[cam_id].mac_addr), cam_id);
  2214. return cam_id;
  2215. }
  2216. u8 rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
  2217. {
  2218. _irqL irqL;
  2219. u8 cam_id = INVALID_CAM_ID;
  2220. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  2221. struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
  2222. _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
  2223. cam_id = _rtw_mbid_cam_search_by_ifaceid(adapter, iface_id);
  2224. _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
  2225. return cam_id;
  2226. }
  2227. u8 rtw_get_max_mbid_cam_id(_adapter *adapter)
  2228. {
  2229. _irqL irqL;
  2230. s8 i;
  2231. u8 cam_id = INVALID_CAM_ID;
  2232. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  2233. struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
  2234. _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
  2235. for (i = (TOTAL_MBID_CAM_NUM - 1); i >= 0; i--) {
  2236. if (mbid_cam_ctl->bitmap & BIT(i)) {
  2237. cam_id = i;
  2238. break;
  2239. }
  2240. }
  2241. _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
  2242. /*RTW_INFO("%s max cam_id:%d\n", __func__, cam_id);*/
  2243. return cam_id;
  2244. }
  2245. inline u8 rtw_get_mbid_cam_entry_num(_adapter *adapter)
  2246. {
  2247. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  2248. struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
  2249. return ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
  2250. }
  2251. static inline void mbid_cam_cache_init(_adapter *adapter, struct mbid_cam_cache *pmbid_cam, u8 *mac_addr)
  2252. {
  2253. if (adapter && pmbid_cam && mac_addr) {
  2254. _rtw_memcpy(pmbid_cam->mac_addr, mac_addr, ETH_ALEN);
  2255. pmbid_cam->iface_id = adapter->iface_id;
  2256. }
  2257. }
  2258. static inline void mbid_cam_cache_clr(struct mbid_cam_cache *pmbid_cam)
  2259. {
  2260. if (pmbid_cam) {
  2261. _rtw_memset(pmbid_cam->mac_addr, 0, ETH_ALEN);
  2262. pmbid_cam->iface_id = CONFIG_IFACE_NUMBER;
  2263. }
  2264. }
  2265. u8 rtw_mbid_camid_alloc(_adapter *adapter, u8 *mac_addr)
  2266. {
  2267. _irqL irqL;
  2268. u8 cam_id = INVALID_CAM_ID, i;
  2269. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  2270. struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
  2271. u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
  2272. if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
  2273. goto exit;
  2274. if (entry_num >= TOTAL_MBID_CAM_NUM) {
  2275. RTW_INFO(FUNC_ADPT_FMT" failed !! MBSSID number :%d over TOTAL_CAM_ENTRY(8)\n", FUNC_ADPT_ARG(adapter), entry_num);
  2276. rtw_warn_on(1);
  2277. }
  2278. _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
  2279. for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
  2280. if (!(mbid_cam_ctl->bitmap & BIT(i))) {
  2281. mbid_cam_ctl->bitmap |= BIT(i);
  2282. cam_id = i;
  2283. break;
  2284. }
  2285. }
  2286. if ((cam_id != INVALID_CAM_ID) && (mac_addr))
  2287. mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[cam_id], mac_addr);
  2288. _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
  2289. if (cam_id != INVALID_CAM_ID) {
  2290. ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
  2291. RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
  2292. #ifdef DBG_MBID_CAM_DUMP
  2293. rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
  2294. #endif
  2295. } else
  2296. RTW_INFO("%s [WARN] "MAC_FMT" - invalid cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
  2297. exit:
  2298. return cam_id;
  2299. }
  2300. u8 rtw_mbid_cam_info_change(_adapter *adapter, u8 *mac_addr)
  2301. {
  2302. _irqL irqL;
  2303. u8 entry_id = INVALID_CAM_ID;
  2304. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  2305. struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
  2306. _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
  2307. entry_id = _rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
  2308. if (entry_id != INVALID_CAM_ID)
  2309. mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[entry_id], mac_addr);
  2310. _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
  2311. return entry_id;
  2312. }
  2313. u8 rtw_mbid_cam_assign(_adapter *adapter, u8 *mac_addr, u8 camid)
  2314. {
  2315. _irqL irqL;
  2316. u8 ret = _FALSE;
  2317. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  2318. struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
  2319. if ((camid >= TOTAL_MBID_CAM_NUM) || (camid == INVALID_CAM_ID)) {
  2320. RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), camid);
  2321. rtw_warn_on(1);
  2322. }
  2323. if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
  2324. goto exit;
  2325. _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
  2326. if (!(mbid_cam_ctl->bitmap & BIT(camid))) {
  2327. if (mac_addr) {
  2328. mbid_cam_ctl->bitmap |= BIT(camid);
  2329. mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[camid], mac_addr);
  2330. ret = _TRUE;
  2331. }
  2332. }
  2333. _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
  2334. if (ret == _TRUE) {
  2335. ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
  2336. RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), camid);
  2337. #ifdef DBG_MBID_CAM_DUMP
  2338. rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
  2339. #endif
  2340. } else
  2341. RTW_INFO("%s [WARN] mac:"MAC_FMT" - cam_id:%d assigned failed\n", __func__, MAC_ARG(mac_addr), camid);
  2342. exit:
  2343. return ret;
  2344. }
  2345. void rtw_mbid_camid_clean(_adapter *adapter, u8 mbss_canid)
  2346. {
  2347. _irqL irqL;
  2348. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  2349. struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
  2350. if ((mbss_canid >= TOTAL_MBID_CAM_NUM) || (mbss_canid == INVALID_CAM_ID)) {
  2351. RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), mbss_canid);
  2352. rtw_warn_on(1);
  2353. }
  2354. _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
  2355. mbid_cam_cache_clr(&dvobj->mbid_cam_cache[mbss_canid]);
  2356. mbid_cam_ctl->bitmap &= (~BIT(mbss_canid));
  2357. _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
  2358. ATOMIC_DEC(&mbid_cam_ctl->mbid_entry_num);
  2359. RTW_INFO("%s - cam_id:%d\n", __func__, mbss_canid);
  2360. }
  2361. int rtw_mbid_cam_cache_dump(void *sel, const char *fun_name, _adapter *adapter)
  2362. {
  2363. _irqL irqL;
  2364. u8 i;
  2365. _adapter *iface;
  2366. u8 iface_id;
  2367. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  2368. struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
  2369. u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
  2370. u8 max_cam_id = rtw_get_max_mbid_cam_id(adapter);
  2371. RTW_PRINT_SEL(sel, "== MBSSID CAM DUMP (%s)==\n", fun_name);
  2372. _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
  2373. RTW_PRINT_SEL(sel, "Entry numbers:%d, max_camid:%d, bitmap:0x%08x\n", entry_num, max_cam_id, mbid_cam_ctl->bitmap);
  2374. for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
  2375. RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
  2376. if (mbid_cam_ctl->bitmap & BIT(i)) {
  2377. iface_id = dvobj->mbid_cam_cache[i].iface_id;
  2378. _RTW_PRINT_SEL(sel, "IF_ID:%d\t", iface_id);
  2379. _RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\t", MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
  2380. iface = dvobj->padapters[iface_id];
  2381. if (iface) {
  2382. if (MLME_IS_STA(iface))
  2383. _RTW_PRINT_SEL(sel, "ROLE:%s\n", "STA");
  2384. else if (MLME_IS_AP(iface))
  2385. _RTW_PRINT_SEL(sel, "ROLE:%s\n", "AP");
  2386. else if (MLME_IS_MESH(iface))
  2387. _RTW_PRINT_SEL(sel, "ROLE:%s\n", "MESH");
  2388. else
  2389. _RTW_PRINT_SEL(sel, "ROLE:%s\n", "NONE");
  2390. }
  2391. } else
  2392. _RTW_PRINT_SEL(sel, "N/A\n");
  2393. }
  2394. _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
  2395. return 0;
  2396. }
  2397. static void read_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
  2398. {
  2399. u8 poll = 1;
  2400. u8 cam_ready = _FALSE;
  2401. u32 cam_data1 = 0;
  2402. u16 cam_data2 = 0;
  2403. if (RTW_CANNOT_RUN(padapter))
  2404. return;
  2405. rtw_write32(padapter, REG_MBIDCAMCFG_2, BIT_MBIDCAM_POLL | ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT));
  2406. do {
  2407. if (0 == (rtw_read32(padapter, REG_MBIDCAMCFG_2) & BIT_MBIDCAM_POLL)) {
  2408. cam_ready = _TRUE;
  2409. break;
  2410. }
  2411. poll++;
  2412. } while ((poll % 10) != 0 && !RTW_CANNOT_RUN(padapter));
  2413. if (cam_ready) {
  2414. cam_data1 = rtw_read32(padapter, REG_MBIDCAMCFG_1);
  2415. mac[0] = cam_data1 & 0xFF;
  2416. mac[1] = (cam_data1 >> 8) & 0xFF;
  2417. mac[2] = (cam_data1 >> 16) & 0xFF;
  2418. mac[3] = (cam_data1 >> 24) & 0xFF;
  2419. cam_data2 = rtw_read16(padapter, REG_MBIDCAMCFG_2);
  2420. mac[4] = cam_data2 & 0xFF;
  2421. mac[5] = (cam_data2 >> 8) & 0xFF;
  2422. }
  2423. }
  2424. int rtw_mbid_cam_dump(void *sel, const char *fun_name, _adapter *adapter)
  2425. {
  2426. /*_irqL irqL;*/
  2427. u8 i;
  2428. u8 mac_addr[ETH_ALEN];
  2429. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  2430. struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
  2431. RTW_PRINT_SEL(sel, "\n== MBSSID HW-CAM DUMP (%s)==\n", fun_name);
  2432. /*_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
  2433. for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
  2434. RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
  2435. _rtw_memset(mac_addr, 0, ETH_ALEN);
  2436. read_mbssid_cam(adapter, i, mac_addr);
  2437. _RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\n", MAC_ARG(mac_addr));
  2438. }
  2439. /*_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
  2440. return 0;
  2441. }
  2442. static void write_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
  2443. {
  2444. u32 cam_val[2] = {0};
  2445. cam_val[0] = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0];
  2446. cam_val[1] = ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT) | (mac[5] << 8) | mac[4];
  2447. rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_WRITE, (u8 *)cam_val);
  2448. }
  2449. static void clear_mbssid_cam(_adapter *padapter, u8 cam_addr)
  2450. {
  2451. rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_CLEAR, &cam_addr);
  2452. }
  2453. void rtw_ap_set_mbid_num(_adapter *adapter, u8 ap_num)
  2454. {
  2455. rtw_write8(adapter, REG_MBID_NUM,
  2456. ((rtw_read8(adapter, REG_MBID_NUM) & 0xF8) | ((ap_num -1) & 0x07)));
  2457. }
  2458. void rtw_mbid_cam_enable(_adapter *adapter)
  2459. {
  2460. /*enable MBSSID*/
  2461. rtw_hal_rcr_add(adapter, RCR_ENMBID);
  2462. }
  2463. void rtw_mi_set_mbid_cam(_adapter *adapter)
  2464. {
  2465. u8 i;
  2466. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  2467. struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
  2468. #ifdef DBG_MBID_CAM_DUMP
  2469. rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
  2470. #endif
  2471. for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
  2472. if (mbid_cam_ctl->bitmap & BIT(i)) {
  2473. write_mbssid_cam(adapter, i, dvobj->mbid_cam_cache[i].mac_addr);
  2474. RTW_INFO("%s - cam_id:%d => mac:"MAC_FMT"\n", __func__, i, MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
  2475. }
  2476. }
  2477. rtw_mbid_cam_enable(adapter);
  2478. }
  2479. #endif /*CONFIG_MBSSID_CAM*/
  2480. #ifdef CONFIG_FW_HANDLE_TXBCN
  2481. #define H2C_BCN_OFFLOAD_LEN 1
  2482. #define SET_H2CCMD_BCN_OFFLOAD_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value)
  2483. #define SET_H2CCMD_BCN_ROOT_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value)
  2484. #define SET_H2CCMD_BCN_VAP1_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value)
  2485. #define SET_H2CCMD_BCN_VAP2_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value)
  2486. #define SET_H2CCMD_BCN_VAP3_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 1, __Value)
  2487. #define SET_H2CCMD_BCN_VAP4_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 5, 1, __Value)
  2488. void rtw_hal_set_fw_ap_bcn_offload_cmd(_adapter *adapter, bool fw_bcn_en, u8 tbtt_rpt_map)
  2489. {
  2490. u8 fw_bcn_offload[1] = {0};
  2491. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  2492. if (fw_bcn_en)
  2493. SET_H2CCMD_BCN_OFFLOAD_EN(fw_bcn_offload, 1);
  2494. if (tbtt_rpt_map & BIT(0))
  2495. SET_H2CCMD_BCN_ROOT_TBTT_RPT(fw_bcn_offload, 1);
  2496. if (tbtt_rpt_map & BIT(1))
  2497. SET_H2CCMD_BCN_VAP1_TBTT_RPT(fw_bcn_offload, 1);
  2498. if (tbtt_rpt_map & BIT(2))
  2499. SET_H2CCMD_BCN_VAP2_TBTT_RPT(fw_bcn_offload, 1);
  2500. if (tbtt_rpt_map & BIT(3))
  2501. SET_H2CCMD_BCN_VAP3_TBTT_RPT(fw_bcn_offload, 1);
  2502. dvobj->vap_tbtt_rpt_map = tbtt_rpt_map;
  2503. dvobj->fw_bcn_offload = fw_bcn_en;
  2504. RTW_INFO("[FW BCN] Offload : %s\n", (dvobj->fw_bcn_offload) ? "EN" : "DIS");
  2505. RTW_INFO("[FW BCN] TBTT RPT map : 0x%02x\n", dvobj->vap_tbtt_rpt_map);
  2506. rtw_hal_fill_h2c_cmd(adapter, H2C_FW_BCN_OFFLOAD,
  2507. H2C_BCN_OFFLOAD_LEN, fw_bcn_offload);
  2508. }
  2509. void rtw_hal_set_bcn_rsvdpage_loc_cmd(_adapter *adapter)
  2510. {
  2511. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  2512. u8 ret, vap_id;
  2513. u32 page_size = 0;
  2514. u8 bcn_rsvdpage[H2C_BCN_RSVDPAGE_LEN] = {0};
  2515. rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
  2516. #if 1
  2517. for (vap_id = 0; vap_id < CONFIG_LIMITED_AP_NUM; vap_id++) {
  2518. if (dvobj->vap_map & BIT(vap_id))
  2519. bcn_rsvdpage[vap_id] = vap_id * (MAX_BEACON_LEN / page_size);
  2520. }
  2521. #else
  2522. #define SET_H2CCMD_BCN_RSVDPAGE_LOC_ROOT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value)
  2523. #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 8, __Value)
  2524. #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 8, __Value)
  2525. #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP3(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 8, __Value)
  2526. #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP4(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 8, __Value)
  2527. if (dvobj->vap_map & BIT(0))
  2528. SET_H2CCMD_BCN_RSVDPAGE_LOC_ROOT(bcn_rsvdpage, 0);
  2529. if (dvobj->vap_map & BIT(1))
  2530. SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP1(bcn_rsvdpage,
  2531. 1 * (MAX_BEACON_LEN / page_size));
  2532. if (dvobj->vap_map & BIT(2))
  2533. SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP2(bcn_rsvdpage,
  2534. 2 * (MAX_BEACON_LEN / page_size));
  2535. if (dvobj->vap_map & BIT(3))
  2536. SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP3(bcn_rsvdpage,
  2537. 3 * (MAX_BEACON_LEN / page_size));
  2538. if (dvobj->vap_map & BIT(4))
  2539. SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP4(bcn_rsvdpage,
  2540. 4 * (MAX_BEACON_LEN / page_size));
  2541. #endif
  2542. if (1) {
  2543. RTW_INFO("[BCN_LOC] vap_map : 0x%02x\n", dvobj->vap_map);
  2544. RTW_INFO("[BCN_LOC] page_size :%d, @bcn_page_num :%d\n"
  2545. , page_size, (MAX_BEACON_LEN / page_size));
  2546. RTW_INFO("[BCN_LOC] root ap : 0x%02x\n", *bcn_rsvdpage);
  2547. RTW_INFO("[BCN_LOC] vap_1 : 0x%02x\n", *(bcn_rsvdpage + 1));
  2548. RTW_INFO("[BCN_LOC] vap_2 : 0x%02x\n", *(bcn_rsvdpage + 2));
  2549. RTW_INFO("[BCN_LOC] vap_3 : 0x%02x\n", *(bcn_rsvdpage + 3));
  2550. RTW_INFO("[BCN_LOC] vap_4 : 0x%02x\n", *(bcn_rsvdpage + 4));
  2551. }
  2552. ret = rtw_hal_fill_h2c_cmd(adapter, H2C_BCN_RSVDPAGE,
  2553. H2C_BCN_RSVDPAGE_LEN, bcn_rsvdpage);
  2554. }
  2555. void rtw_ap_multi_bcn_cfg(_adapter *adapter)
  2556. {
  2557. u8 dft_bcn_space = DEFAULT_BCN_INTERVAL;
  2558. u8 sub_bcn_space = (DEFAULT_BCN_INTERVAL / CONFIG_LIMITED_AP_NUM);
  2559. /*enable to rx data frame*/
  2560. rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
  2561. /*Disable Port0's beacon function*/
  2562. rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
  2563. /*Reset Port0's TSF*/
  2564. rtw_write8(adapter, REG_DUAL_TSF_RST, BIT_TSFTR_RST);
  2565. rtw_ap_set_mbid_num(adapter, CONFIG_LIMITED_AP_NUM);
  2566. /*BCN space & BCN sub-space 0x554[15:0] = 0x64,0x5BC[23:16] = 0x21*/
  2567. rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), HW_PORT0, dft_bcn_space);
  2568. rtw_write8(adapter, REG_MBSSID_BCN_SPACE3 + 2, sub_bcn_space);
  2569. #if 0 /*setting in hw_var_set_opmode_mbid - ResumeTxBeacon*/
  2570. /*BCN hold time 0x540[19:8] = 0x80*/
  2571. rtw_write8(adapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
  2572. rtw_write8(adapter, REG_TBTT_PROHIBIT + 2,
  2573. (rtw_read8(adapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
  2574. #endif
  2575. /*ATIM window -0x55A = 0x32, reg 0x570 = 0x32, reg 0x5A0 = 0x32 */
  2576. rtw_write8(adapter, REG_ATIMWND, 0x32);
  2577. rtw_write8(adapter, REG_ATIMWND1_V1, 0x32);
  2578. rtw_write8(adapter, REG_ATIMWND2, 0x32);
  2579. rtw_write8(adapter, REG_ATIMWND3, 0x32);
  2580. /*
  2581. rtw_write8(adapter, REG_ATIMWND4, 0x32);
  2582. rtw_write8(adapter, REG_ATIMWND5, 0x32);
  2583. rtw_write8(adapter, REG_ATIMWND6, 0x32);
  2584. rtw_write8(adapter, REG_ATIMWND7, 0x32);*/
  2585. /*no limit setting - 0x5A7 = 0xFF - Packet in Hi Queue Tx immediately*/
  2586. rtw_write8(adapter, REG_HIQ_NO_LMT_EN, 0xFF);
  2587. /*Mask all beacon*/
  2588. rtw_write8(adapter, REG_MBSSID_CTRL, 0);
  2589. /*BCN invalid bit setting 0x454[6] = 1*/
  2590. /*rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);*/
  2591. /*Enable Port0's beacon function*/
  2592. rtw_write8(adapter, REG_BCN_CTRL,
  2593. rtw_read8(adapter, REG_BCN_CTRL) | BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT | BIT_EN_BCN_FUNCTION);
  2594. /* Enable HW seq for BCN
  2595. * 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT */
  2596. #ifdef CONFIG_RTL8822B
  2597. if (IS_HARDWARE_TYPE_8822B(adapter))
  2598. rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);
  2599. #endif
  2600. }
  2601. static void _rtw_mbid_bcn_cfg(_adapter *adapter, bool mbcnq_en, u8 mbcnq_id)
  2602. {
  2603. if (mbcnq_id >= CONFIG_LIMITED_AP_NUM) {
  2604. RTW_ERR(FUNC_ADPT_FMT"- mbid bcnq_id(%d) invalid\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
  2605. rtw_warn_on(1);
  2606. }
  2607. if (mbcnq_en) {
  2608. rtw_write8(adapter, REG_MBSSID_CTRL,
  2609. rtw_read8(adapter, REG_MBSSID_CTRL) | BIT(mbcnq_id));
  2610. RTW_INFO(FUNC_ADPT_FMT"- mbid bcnq_id(%d) enabled\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
  2611. } else {
  2612. rtw_write8(adapter, REG_MBSSID_CTRL,
  2613. rtw_read8(adapter, REG_MBSSID_CTRL) & (~BIT(mbcnq_id)));
  2614. RTW_INFO(FUNC_ADPT_FMT"- mbid bcnq_id(%d) disabled\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
  2615. }
  2616. }
  2617. /*#define CONFIG_FW_TBTT_RPT*/
  2618. void rtw_ap_mbid_bcn_en(_adapter *adapter, u8 ap_id)
  2619. {
  2620. RTW_INFO(FUNC_ADPT_FMT"- ap_id(%d)\n", FUNC_ADPT_ARG(adapter), ap_id);
  2621. #ifdef CONFIG_FW_TBTT_RPT
  2622. if (rtw_ap_get_nums(adapter) >= 1) {
  2623. u8 tbtt_rpt_map = adapter_to_dvobj(adapter)->vap_tbtt_rpt_map;
  2624. rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE,
  2625. tbtt_rpt_map | BIT(ap_id));/*H2C-0xBA*/
  2626. }
  2627. #else
  2628. if (rtw_ap_get_nums(adapter) == 1)
  2629. rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE, 0);/*H2C-0xBA*/
  2630. #endif
  2631. rtw_hal_set_bcn_rsvdpage_loc_cmd(adapter);/*H2C-0x09*/
  2632. _rtw_mbid_bcn_cfg(adapter, _TRUE, ap_id);
  2633. }
  2634. void rtw_ap_mbid_bcn_dis(_adapter *adapter, u8 ap_id)
  2635. {
  2636. RTW_INFO(FUNC_ADPT_FMT"- ap_id(%d)\n", FUNC_ADPT_ARG(adapter), ap_id);
  2637. _rtw_mbid_bcn_cfg(adapter, _FALSE, ap_id);
  2638. if (rtw_ap_get_nums(adapter) == 0)
  2639. rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _FALSE, 0);
  2640. #ifdef CONFIG_FW_TBTT_RPT
  2641. else if (rtw_ap_get_nums(adapter) >= 1) {
  2642. u8 tbtt_rpt_map = adapter_to_dvobj(adapter)->vap_tbtt_rpt_map;
  2643. rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE,
  2644. tbtt_rpt_map & ~BIT(ap_id));/*H2C-0xBA*/
  2645. }
  2646. #endif
  2647. }
  2648. #endif
  2649. #ifdef CONFIG_SWTIMER_BASED_TXBCN
  2650. void rtw_ap_multi_bcn_cfg(_adapter *adapter)
  2651. {
  2652. #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
  2653. rtw_write8(adapter, REG_BCN_CTRL, DIS_TSF_UDT);
  2654. #else
  2655. rtw_write8(adapter, REG_BCN_CTRL, DIS_TSF_UDT | DIS_BCNQ_SUB);
  2656. #endif
  2657. /*enable to rx data frame*/
  2658. rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
  2659. /*Beacon Control related register for first time*/
  2660. rtw_write8(adapter, REG_BCNDMATIM, 0x02); /* 2ms */
  2661. /*rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF);*/
  2662. rtw_write8(adapter, REG_ATIMWND, 0x0c); /* 12ms */
  2663. #ifndef CONFIG_HW_P0_TSF_SYNC
  2664. rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
  2665. #endif
  2666. /*reset TSF*/
  2667. rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
  2668. /*enable BCN0 Function for if1*/
  2669. /*don't enable update TSF0 for if1 (due to TSF update when beacon,probe rsp are received)*/
  2670. #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
  2671. rtw_write8(adapter, REG_BCN_CTRL, BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT |BIT_EN_BCN_FUNCTION);
  2672. #else
  2673. rtw_write8(adapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
  2674. #endif
  2675. #ifdef CONFIG_BCN_XMIT_PROTECT
  2676. rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);
  2677. #endif
  2678. if (IS_HARDWARE_TYPE_8821(adapter) || IS_HARDWARE_TYPE_8192E(adapter))/* select BCN on port 0 for DualBeacon*/
  2679. rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) & (~BIT_BCN_PORT_SEL));
  2680. /* Enable HW seq for BCN
  2681. * 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT */
  2682. #ifdef CONFIG_RTL8822B
  2683. if (IS_HARDWARE_TYPE_8822B(adapter))
  2684. rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);
  2685. #endif
  2686. }
  2687. #endif
  2688. #ifdef CONFIG_MI_WITH_MBSSID_CAM
  2689. void rtw_hal_set_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
  2690. {
  2691. #if 0 /*TODO - modify for more flexible*/
  2692. u8 idx = 0;
  2693. if ((check_fwstate(&adapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) &&
  2694. (DEV_STA_NUM(adapter_to_dvobj(adapter)) == 1)) {
  2695. for (idx = 0; idx < 6; idx++)
  2696. rtw_write8(GET_PRIMARY_ADAPTER(adapter), (REG_MACID + idx), val[idx]);
  2697. } else {
  2698. /*MBID entry_id = 0~7 ,0 for root AP, 1~7 for VAP*/
  2699. u8 entry_id;
  2700. if ((check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) &&
  2701. (DEV_AP_NUM(adapter_to_dvobj(adapter)) == 1)) {
  2702. entry_id = 0;
  2703. if (rtw_mbid_cam_assign(adapter, val, entry_id)) {
  2704. RTW_INFO(FUNC_ADPT_FMT" Root AP assigned success\n", FUNC_ADPT_ARG(adapter));
  2705. write_mbssid_cam(adapter, entry_id, val);
  2706. }
  2707. } else {
  2708. entry_id = rtw_mbid_camid_alloc(adapter, val);
  2709. if (entry_id != INVALID_CAM_ID)
  2710. write_mbssid_cam(adapter, entry_id, val);
  2711. }
  2712. }
  2713. #else
  2714. {
  2715. /*
  2716. MBID entry_id = 0~7 ,for IFACE_ID0 ~ IFACE_IDx
  2717. */
  2718. u8 entry_id = rtw_mbid_camid_alloc(adapter, mac_addr);
  2719. if (entry_id != INVALID_CAM_ID) {
  2720. write_mbssid_cam(adapter, entry_id, mac_addr);
  2721. RTW_INFO("%s "ADPT_FMT"- mbid(%d) mac_addr ="MAC_FMT"\n", __func__,
  2722. ADPT_ARG(adapter), entry_id, MAC_ARG(mac_addr));
  2723. }
  2724. }
  2725. #endif
  2726. }
  2727. void rtw_hal_change_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
  2728. {
  2729. u8 idx = 0;
  2730. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  2731. u8 entry_id;
  2732. if (!mac_addr) {
  2733. rtw_warn_on(1);
  2734. return;
  2735. }
  2736. entry_id = rtw_mbid_cam_info_change(adapter, mac_addr);
  2737. if (entry_id != INVALID_CAM_ID)
  2738. write_mbssid_cam(adapter, entry_id, mac_addr);
  2739. }
  2740. #ifdef CONFIG_SWTIMER_BASED_TXBCN
  2741. u16 rtw_hal_bcn_interval_adjust(_adapter *adapter, u16 bcn_interval)
  2742. {
  2743. if (adapter_to_dvobj(adapter)->inter_bcn_space != bcn_interval)
  2744. return adapter_to_dvobj(adapter)->inter_bcn_space;
  2745. else
  2746. return bcn_interval;
  2747. }
  2748. #endif/*CONFIG_SWTIMER_BASED_TXBCN*/
  2749. #endif/*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
  2750. static void rtw_hal_set_macaddr_port(_adapter *adapter, u8 *val)
  2751. {
  2752. u8 idx = 0;
  2753. u32 reg_macid = 0;
  2754. enum _hw_port hwport;
  2755. if (val == NULL)
  2756. return;
  2757. hwport = get_hw_port(adapter);
  2758. RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,
  2759. ADPT_ARG(adapter), hwport, MAC_ARG(val));
  2760. #ifdef RTW_HALMAC
  2761. rtw_halmac_set_mac_address(adapter_to_dvobj(adapter), hwport, val);
  2762. #else /* !RTW_HALMAC */
  2763. switch (hwport) {
  2764. case HW_PORT0:
  2765. default:
  2766. reg_macid = REG_MACID;
  2767. break;
  2768. case HW_PORT1:
  2769. reg_macid = REG_MACID1;
  2770. break;
  2771. #if defined(CONFIG_RTL8814A)
  2772. case HW_PORT2:
  2773. reg_macid = REG_MACID2;
  2774. break;
  2775. case HW_PORT3:
  2776. reg_macid = REG_MACID3;
  2777. break;
  2778. case HW_PORT4:
  2779. reg_macid = REG_MACID4;
  2780. break;
  2781. #endif/*defined(CONFIG_RTL8814A)*/
  2782. }
  2783. for (idx = 0; idx < ETH_ALEN; idx++)
  2784. rtw_write8(GET_PRIMARY_ADAPTER(adapter), (reg_macid + idx), val[idx]);
  2785. #endif /* !RTW_HALMAC */
  2786. }
  2787. static void rtw_hal_get_macaddr_port(_adapter *adapter, u8 *mac_addr)
  2788. {
  2789. u8 idx = 0;
  2790. u32 reg_macid = 0;
  2791. if (mac_addr == NULL)
  2792. return;
  2793. _rtw_memset(mac_addr, 0, ETH_ALEN);
  2794. #ifdef RTW_HALMAC
  2795. rtw_halmac_get_mac_address(adapter_to_dvobj(adapter), adapter->hw_port, mac_addr);
  2796. #else /* !RTW_HALMAC */
  2797. switch (adapter->hw_port) {
  2798. case HW_PORT0:
  2799. default:
  2800. reg_macid = REG_MACID;
  2801. break;
  2802. case HW_PORT1:
  2803. reg_macid = REG_MACID1;
  2804. break;
  2805. #if defined(CONFIG_RTL8814A)
  2806. case HW_PORT2:
  2807. reg_macid = REG_MACID2;
  2808. break;
  2809. case HW_PORT3:
  2810. reg_macid = REG_MACID3;
  2811. break;
  2812. case HW_PORT4:
  2813. reg_macid = REG_MACID4;
  2814. break;
  2815. #endif /*defined(CONFIG_RTL8814A)*/
  2816. }
  2817. for (idx = 0; idx < ETH_ALEN; idx++)
  2818. mac_addr[idx] = rtw_read8(GET_PRIMARY_ADAPTER(adapter), (reg_macid + idx));
  2819. #endif /* !RTW_HALMAC */
  2820. RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,
  2821. ADPT_ARG(adapter), adapter->hw_port, MAC_ARG(mac_addr));
  2822. }
  2823. static void rtw_hal_set_bssid(_adapter *adapter, u8 *val)
  2824. {
  2825. u8 hw_port = rtw_hal_get_port(adapter);
  2826. #ifdef RTW_HALMAC
  2827. rtw_halmac_set_bssid(adapter_to_dvobj(adapter), hw_port, val);
  2828. #else /* !RTW_HALMAC */
  2829. u8 idx = 0;
  2830. u32 reg_bssid = 0;
  2831. switch (hw_port) {
  2832. case HW_PORT0:
  2833. default:
  2834. reg_bssid = REG_BSSID;
  2835. break;
  2836. case HW_PORT1:
  2837. reg_bssid = REG_BSSID1;
  2838. break;
  2839. #if defined(CONFIG_RTL8814A)
  2840. case HW_PORT2:
  2841. reg_bssid = REG_BSSID2;
  2842. break;
  2843. case HW_PORT3:
  2844. reg_bssid = REG_BSSID3;
  2845. break;
  2846. case HW_PORT4:
  2847. reg_bssid = REG_BSSID4;
  2848. break;
  2849. #endif/*defined(CONFIG_RTL8814A)*/
  2850. }
  2851. for (idx = 0 ; idx < ETH_ALEN; idx++)
  2852. rtw_write8(adapter, (reg_bssid + idx), val[idx]);
  2853. #endif /* !RTW_HALMAC */
  2854. RTW_INFO("%s "ADPT_FMT"- hw port -%d BSSID: "MAC_FMT"\n",
  2855. __func__, ADPT_ARG(adapter), hw_port, MAC_ARG(val));
  2856. }
  2857. static void rtw_hal_set_tsf_update(_adapter *adapter, u8 en)
  2858. {
  2859. u32 addr = 0;
  2860. u8 val8;
  2861. rtw_hal_get_hwreg(adapter, HW_VAR_BCN_CTRL_ADDR, (u8 *)&addr);
  2862. if (addr) {
  2863. val8 = rtw_read8(adapter, addr);
  2864. if (en && (val8 & DIS_TSF_UDT)) {
  2865. rtw_write8(adapter, addr, val8 & ~DIS_TSF_UDT);
  2866. #ifdef DBG_TSF_UPDATE
  2867. RTW_INFO("port%u("ADPT_FMT") enable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
  2868. #endif
  2869. }
  2870. if (!en && !(val8 & DIS_TSF_UDT)) {
  2871. rtw_write8(adapter, addr, val8 | DIS_TSF_UDT);
  2872. #ifdef DBG_TSF_UPDATE
  2873. RTW_INFO("port%u("ADPT_FMT") disable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
  2874. #endif
  2875. }
  2876. } else {
  2877. RTW_WARN("unknown port%d("ADPT_FMT") %s TSF update\n"
  2878. , adapter->hw_port, ADPT_ARG(adapter), en ? "enable" : "disable");
  2879. rtw_warn_on(1);
  2880. }
  2881. }
  2882. static void rtw_hal_set_hw_update_tsf(PADAPTER padapter)
  2883. {
  2884. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  2885. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  2886. #if defined(CONFIG_RTL8822B) || defined(CONFIG_MI_WITH_MBSSID_CAM)
  2887. RTW_INFO("[Warn] %s "ADPT_FMT" enter func\n", __func__, ADPT_ARG(padapter));
  2888. rtw_warn_on(1);
  2889. return;
  2890. #endif
  2891. if (!pmlmeext->en_hw_update_tsf)
  2892. return;
  2893. /* check RCR */
  2894. if (!rtw_hal_rcr_check(padapter, RCR_CBSSID_BCN))
  2895. return;
  2896. if (pmlmeext->tsf_update_required) {
  2897. pmlmeext->tsf_update_pause_stime = 0;
  2898. rtw_hal_set_tsf_update(padapter, 1);
  2899. }
  2900. pmlmeext->en_hw_update_tsf = 0;
  2901. }
  2902. void rtw_iface_enable_tsf_update(_adapter *adapter)
  2903. {
  2904. adapter->mlmeextpriv.tsf_update_pause_stime = 0;
  2905. adapter->mlmeextpriv.tsf_update_required = 1;
  2906. #ifdef CONFIG_MI_WITH_MBSSID_CAM
  2907. #else
  2908. rtw_hal_set_tsf_update(adapter, 1);
  2909. #endif
  2910. }
  2911. void rtw_iface_disable_tsf_update(_adapter *adapter)
  2912. {
  2913. adapter->mlmeextpriv.tsf_update_required = 0;
  2914. adapter->mlmeextpriv.tsf_update_pause_stime = 0;
  2915. adapter->mlmeextpriv.en_hw_update_tsf = 0;
  2916. #ifdef CONFIG_MI_WITH_MBSSID_CAM
  2917. #else
  2918. rtw_hal_set_tsf_update(adapter, 0);
  2919. #endif
  2920. }
  2921. static void rtw_hal_tsf_update_pause(_adapter *adapter)
  2922. {
  2923. #ifdef CONFIG_MI_WITH_MBSSID_CAM
  2924. #else
  2925. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  2926. _adapter *iface;
  2927. int i;
  2928. u8 val8;
  2929. for (i = 0; i < dvobj->iface_nums; i++) {
  2930. iface = dvobj->padapters[i];
  2931. if (!iface)
  2932. continue;
  2933. rtw_hal_set_tsf_update(iface, 0);
  2934. if (iface->mlmeextpriv.tsf_update_required) {
  2935. iface->mlmeextpriv.tsf_update_pause_stime = rtw_get_current_time();
  2936. if (!iface->mlmeextpriv.tsf_update_pause_stime)
  2937. iface->mlmeextpriv.tsf_update_pause_stime++;
  2938. }
  2939. iface->mlmeextpriv.en_hw_update_tsf = 0;
  2940. }
  2941. #endif
  2942. }
  2943. static void rtw_hal_tsf_update_restore(_adapter *adapter)
  2944. {
  2945. #ifdef CONFIG_MI_WITH_MBSSID_CAM
  2946. #else
  2947. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  2948. _adapter *iface;
  2949. int i;
  2950. for (i = 0; i < dvobj->iface_nums; i++) {
  2951. iface = dvobj->padapters[i];
  2952. if (!iface)
  2953. continue;
  2954. if (iface->mlmeextpriv.tsf_update_required) {
  2955. /* enable HW TSF update when recive beacon*/
  2956. iface->mlmeextpriv.en_hw_update_tsf = 1;
  2957. #ifdef DBG_TSF_UPDATE
  2958. RTW_INFO("port%d("ADPT_FMT") enabling TSF update...\n"
  2959. , iface->hw_port, ADPT_ARG(iface));
  2960. #endif
  2961. }
  2962. }
  2963. #endif
  2964. }
  2965. void rtw_hal_periodic_tsf_update_chk(_adapter *adapter)
  2966. {
  2967. #ifdef CONFIG_MI_WITH_MBSSID_CAM
  2968. #else
  2969. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  2970. _adapter *iface;
  2971. struct mlme_ext_priv *mlmeext;
  2972. int i;
  2973. u32 restore_ms = 0;
  2974. if (dvobj->periodic_tsf_update_etime) {
  2975. if (rtw_time_after(rtw_get_current_time(), dvobj->periodic_tsf_update_etime)) {
  2976. /* end for restore status */
  2977. dvobj->periodic_tsf_update_etime = 0;
  2978. rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
  2979. }
  2980. return;
  2981. }
  2982. if (dvobj->rf_ctl.offch_state != OFFCHS_NONE)
  2983. return;
  2984. /*
  2985. * all required ifaces can switch to restore status together
  2986. * loop all pause iface to get largest restore time required
  2987. */
  2988. for (i = 0; i < dvobj->iface_nums; i++) {
  2989. iface = dvobj->padapters[i];
  2990. if (!iface)
  2991. continue;
  2992. mlmeext = &iface->mlmeextpriv;
  2993. if (mlmeext->tsf_update_required
  2994. && mlmeext->tsf_update_pause_stime
  2995. && rtw_get_passing_time_ms(mlmeext->tsf_update_pause_stime)
  2996. > mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_pause_factor
  2997. ) {
  2998. if (restore_ms < mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor)
  2999. restore_ms = mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor;
  3000. }
  3001. }
  3002. if (!restore_ms)
  3003. return;
  3004. dvobj->periodic_tsf_update_etime = rtw_get_current_time() + rtw_ms_to_systime(restore_ms);
  3005. if (!dvobj->periodic_tsf_update_etime)
  3006. dvobj->periodic_tsf_update_etime++;
  3007. rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
  3008. /* set timer to end restore status */
  3009. _set_timer(&dvobj->periodic_tsf_update_end_timer, restore_ms);
  3010. #endif
  3011. }
  3012. void rtw_hal_periodic_tsf_update_end_timer_hdl(void *ctx)
  3013. {
  3014. struct dvobj_priv *dvobj = (struct dvobj_priv *)ctx;
  3015. if (dev_is_surprise_removed(dvobj) || dev_is_drv_stopped(dvobj))
  3016. return;
  3017. rtw_periodic_tsf_update_end_cmd(dvobj_get_primary_adapter(dvobj));
  3018. }
  3019. static inline u8 hw_var_rcr_config(_adapter *adapter, u32 rcr)
  3020. {
  3021. int err;
  3022. err = rtw_write32(adapter, REG_RCR, rcr);
  3023. if (err == _SUCCESS)
  3024. GET_HAL_DATA(adapter)->ReceiveConfig = rcr;
  3025. return err;
  3026. }
  3027. static inline u8 hw_var_rcr_get(_adapter *adapter, u32 *rcr)
  3028. {
  3029. u32 v32;
  3030. v32 = rtw_read32(adapter, REG_RCR);
  3031. if (rcr)
  3032. *rcr = v32;
  3033. GET_HAL_DATA(adapter)->ReceiveConfig = v32;
  3034. return _SUCCESS;
  3035. }
  3036. /* only check SW RCR variable */
  3037. inline u8 rtw_hal_rcr_check(_adapter *adapter, u32 check_bit)
  3038. {
  3039. PHAL_DATA_TYPE hal;
  3040. u32 rcr;
  3041. hal = GET_HAL_DATA(adapter);
  3042. rcr = hal->ReceiveConfig;
  3043. if ((rcr & check_bit) == check_bit)
  3044. return 1;
  3045. return 0;
  3046. }
  3047. inline u8 rtw_hal_rcr_add(_adapter *adapter, u32 add)
  3048. {
  3049. PHAL_DATA_TYPE hal;
  3050. u32 rcr;
  3051. u8 ret = _SUCCESS;
  3052. hal = GET_HAL_DATA(adapter);
  3053. rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
  3054. rcr |= add;
  3055. if (rcr != hal->ReceiveConfig)
  3056. ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
  3057. return ret;
  3058. }
  3059. inline u8 rtw_hal_rcr_clear(_adapter *adapter, u32 clear)
  3060. {
  3061. PHAL_DATA_TYPE hal;
  3062. u32 rcr;
  3063. u8 ret = _SUCCESS;
  3064. hal = GET_HAL_DATA(adapter);
  3065. rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
  3066. rcr &= ~clear;
  3067. if (rcr != hal->ReceiveConfig)
  3068. ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
  3069. return ret;
  3070. }
  3071. void rtw_hal_rcr_set_chk_bssid(_adapter *adapter, u8 self_action)
  3072. {
  3073. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
  3074. struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
  3075. u32 rcr, rcr_new;
  3076. struct mi_state mstate, mstate_s;
  3077. rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
  3078. rcr_new = rcr;
  3079. #if defined(CONFIG_MI_WITH_MBSSID_CAM) && !defined(CONFIG_CLIENT_PORT_CFG)
  3080. rcr_new &= ~(RCR_CBSSID_BCN | RCR_CBSSID_DATA);
  3081. #else
  3082. rtw_mi_status_no_self(adapter, &mstate);
  3083. rtw_mi_status_no_others(adapter, &mstate_s);
  3084. /* only adjust parameters interested */
  3085. switch (self_action) {
  3086. case MLME_SCAN_ENTER:
  3087. mstate_s.scan_num = 1;
  3088. mstate_s.scan_enter_num = 1;
  3089. break;
  3090. case MLME_SCAN_DONE:
  3091. mstate_s.scan_enter_num = 0;
  3092. break;
  3093. case MLME_STA_CONNECTING:
  3094. mstate_s.lg_sta_num = 1;
  3095. mstate_s.ld_sta_num = 0;
  3096. break;
  3097. case MLME_STA_CONNECTED:
  3098. mstate_s.lg_sta_num = 0;
  3099. mstate_s.ld_sta_num = 1;
  3100. break;
  3101. case MLME_STA_DISCONNECTED:
  3102. mstate_s.lg_sta_num = 0;
  3103. mstate_s.ld_sta_num = 0;
  3104. break;
  3105. #ifdef CONFIG_TDLS
  3106. case MLME_TDLS_LINKED:
  3107. mstate_s.ld_tdls_num = 1;
  3108. break;
  3109. case MLME_TDLS_NOLINK:
  3110. mstate_s.ld_tdls_num = 0;
  3111. break;
  3112. #endif
  3113. #ifdef CONFIG_AP_MODE
  3114. case MLME_AP_STARTED:
  3115. mstate_s.ap_num = 1;
  3116. break;
  3117. case MLME_AP_STOPPED:
  3118. mstate_s.ap_num = 0;
  3119. mstate_s.ld_ap_num = 0;
  3120. break;
  3121. #endif
  3122. #ifdef CONFIG_RTW_MESH
  3123. case MLME_MESH_STARTED:
  3124. mstate_s.mesh_num = 1;
  3125. break;
  3126. case MLME_MESH_STOPPED:
  3127. mstate_s.mesh_num = 0;
  3128. mstate_s.ld_mesh_num = 0;
  3129. break;
  3130. #endif
  3131. case MLME_ACTION_NONE:
  3132. case MLME_ADHOC_STARTED:
  3133. /* caller without effect of decision */
  3134. break;
  3135. default:
  3136. rtw_warn_on(1);
  3137. };
  3138. rtw_mi_status_merge(&mstate, &mstate_s);
  3139. if (MSTATE_AP_NUM(&mstate) || MSTATE_MESH_NUM(&mstate) || MSTATE_TDLS_LD_NUM(&mstate)
  3140. #ifdef CONFIG_FIND_BEST_CHANNEL
  3141. || MSTATE_SCAN_ENTER_NUM(&mstate)
  3142. #endif
  3143. || hal_data->in_cta_test
  3144. )
  3145. rcr_new &= ~RCR_CBSSID_DATA;
  3146. else
  3147. rcr_new |= RCR_CBSSID_DATA;
  3148. if (MSTATE_SCAN_ENTER_NUM(&mstate) || hal_data->in_cta_test)
  3149. rcr_new &= ~RCR_CBSSID_BCN;
  3150. else if (MSTATE_STA_LG_NUM(&mstate)
  3151. || adapter_to_dvobj(adapter)->periodic_tsf_update_etime
  3152. )
  3153. rcr_new |= RCR_CBSSID_BCN;
  3154. else if ((MSTATE_AP_NUM(&mstate) && adapter->registrypriv.wifi_spec) /* for 11n Logo 4.2.31/4.2.32 */
  3155. || MSTATE_MESH_NUM(&mstate)
  3156. )
  3157. rcr_new &= ~RCR_CBSSID_BCN;
  3158. else
  3159. rcr_new |= RCR_CBSSID_BCN;
  3160. #ifdef CONFIG_CLIENT_PORT_CFG
  3161. if (get_clt_num(adapter) > MAX_CLIENT_PORT_NUM)
  3162. rcr_new &= ~RCR_CBSSID_BCN;
  3163. #endif
  3164. #endif /* CONFIG_MI_WITH_MBSSID_CAM */
  3165. if (rcr == rcr_new)
  3166. return;
  3167. if (!hal_spec->rx_tsf_filter
  3168. && (rcr & RCR_CBSSID_BCN) && !(rcr_new & RCR_CBSSID_BCN))
  3169. rtw_hal_tsf_update_pause(adapter);
  3170. rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr_new);
  3171. if (!hal_spec->rx_tsf_filter
  3172. && !(rcr & RCR_CBSSID_BCN) && (rcr_new & RCR_CBSSID_BCN)
  3173. && self_action != MLME_STA_CONNECTING)
  3174. rtw_hal_tsf_update_restore(adapter);
  3175. }
  3176. static void hw_var_set_rcr_am(_adapter *adapter, u8 enable)
  3177. {
  3178. u32 rcr = RCR_AM;
  3179. if (enable)
  3180. rtw_hal_rcr_add(adapter, rcr);
  3181. else
  3182. rtw_hal_rcr_clear(adapter, rcr);
  3183. }
  3184. static void hw_var_set_bcn_interval(_adapter *adapter, u16 interval)
  3185. {
  3186. #ifdef CONFIG_SWTIMER_BASED_TXBCN
  3187. interval = rtw_hal_bcn_interval_adjust(adapter, interval);
  3188. #endif
  3189. #ifdef RTW_HALMAC
  3190. rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), adapter->hw_port, interval);
  3191. #else
  3192. rtw_write16(adapter, REG_MBSSID_BCN_SPACE, interval);
  3193. #endif
  3194. #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
  3195. {
  3196. struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
  3197. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  3198. if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
  3199. RTW_INFO("%s==> bcn_interval:%d, eraly_int:%d\n", __func__, interval, interval >> 1);
  3200. rtw_write8(adapter, REG_DRVERLYINT, interval >> 1);
  3201. }
  3202. }
  3203. #endif
  3204. }
  3205. void hw_var_port_switch(_adapter *adapter)
  3206. {
  3207. #ifdef CONFIG_CONCURRENT_MODE
  3208. #ifdef CONFIG_RUNTIME_PORT_SWITCH
  3209. /*
  3210. 0x102: MSR
  3211. 0x550: REG_BCN_CTRL
  3212. 0x551: REG_BCN_CTRL_1
  3213. 0x55A: REG_ATIMWND
  3214. 0x560: REG_TSFTR
  3215. 0x568: REG_TSFTR1
  3216. 0x570: REG_ATIMWND_1
  3217. 0x610: REG_MACID
  3218. 0x618: REG_BSSID
  3219. 0x700: REG_MACID1
  3220. 0x708: REG_BSSID1
  3221. */
  3222. int i;
  3223. u8 msr;
  3224. u8 bcn_ctrl;
  3225. u8 bcn_ctrl_1;
  3226. u8 atimwnd[2];
  3227. u8 atimwnd_1[2];
  3228. u8 tsftr[8];
  3229. u8 tsftr_1[8];
  3230. u8 macid[6];
  3231. u8 bssid[6];
  3232. u8 macid_1[6];
  3233. u8 bssid_1[6];
  3234. #if defined(CONFIG_RTL8192F)
  3235. u16 wlan_act_mask_ctrl = 0;
  3236. u16 en_port_mask = EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION;
  3237. #endif
  3238. u8 hw_port;
  3239. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  3240. _adapter *iface = NULL;
  3241. msr = rtw_read8(adapter, MSR);
  3242. bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
  3243. bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
  3244. #if defined(CONFIG_RTL8192F)
  3245. wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
  3246. #endif
  3247. for (i = 0; i < 2; i++)
  3248. atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
  3249. for (i = 0; i < 2; i++)
  3250. atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
  3251. for (i = 0; i < 8; i++)
  3252. tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
  3253. for (i = 0; i < 8; i++)
  3254. tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
  3255. for (i = 0; i < 6; i++)
  3256. macid[i] = rtw_read8(adapter, REG_MACID + i);
  3257. for (i = 0; i < 6; i++)
  3258. bssid[i] = rtw_read8(adapter, REG_BSSID + i);
  3259. for (i = 0; i < 6; i++)
  3260. macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
  3261. for (i = 0; i < 6; i++)
  3262. bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
  3263. #ifdef DBG_RUNTIME_PORT_SWITCH
  3264. RTW_INFO(FUNC_ADPT_FMT" before switch\n"
  3265. "msr:0x%02x\n"
  3266. "bcn_ctrl:0x%02x\n"
  3267. "bcn_ctrl_1:0x%02x\n"
  3268. #if defined(CONFIG_RTL8192F)
  3269. "wlan_act_mask_ctrl:0x%02x\n"
  3270. #endif
  3271. "atimwnd:0x%04x\n"
  3272. "atimwnd_1:0x%04x\n"
  3273. "tsftr:%llu\n"
  3274. "tsftr1:%llu\n"
  3275. "macid:"MAC_FMT"\n"
  3276. "bssid:"MAC_FMT"\n"
  3277. "macid_1:"MAC_FMT"\n"
  3278. "bssid_1:"MAC_FMT"\n"
  3279. , FUNC_ADPT_ARG(adapter)
  3280. , msr
  3281. , bcn_ctrl
  3282. , bcn_ctrl_1
  3283. #if defined(CONFIG_RTL8192F)
  3284. , wlan_act_mask_ctrl
  3285. #endif
  3286. , *((u16 *)atimwnd)
  3287. , *((u16 *)atimwnd_1)
  3288. , *((u64 *)tsftr)
  3289. , *((u64 *)tsftr_1)
  3290. , MAC_ARG(macid)
  3291. , MAC_ARG(bssid)
  3292. , MAC_ARG(macid_1)
  3293. , MAC_ARG(bssid_1)
  3294. );
  3295. #endif /* DBG_RUNTIME_PORT_SWITCH */
  3296. /* disable bcn function, disable update TSF */
  3297. rtw_write8(adapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
  3298. rtw_write8(adapter, REG_BCN_CTRL_1, (bcn_ctrl_1 & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
  3299. #if defined(CONFIG_RTL8192F)
  3300. rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl & ~en_port_mask);
  3301. #endif
  3302. /* switch msr */
  3303. msr = (msr & 0xf0) | ((msr & 0x03) << 2) | ((msr & 0x0c) >> 2);
  3304. rtw_write8(adapter, MSR, msr);
  3305. /* write port0 */
  3306. rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1 & ~EN_BCN_FUNCTION);
  3307. for (i = 0; i < 2; i++)
  3308. rtw_write8(adapter, REG_ATIMWND + i, atimwnd_1[i]);
  3309. for (i = 0; i < 8; i++)
  3310. rtw_write8(adapter, REG_TSFTR + i, tsftr_1[i]);
  3311. for (i = 0; i < 6; i++)
  3312. rtw_write8(adapter, REG_MACID + i, macid_1[i]);
  3313. for (i = 0; i < 6; i++)
  3314. rtw_write8(adapter, REG_BSSID + i, bssid_1[i]);
  3315. /* write port1 */
  3316. rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl & ~EN_BCN_FUNCTION);
  3317. for (i = 0; i < 2; i++)
  3318. rtw_write8(adapter, REG_ATIMWND_1 + i, atimwnd[i]);
  3319. for (i = 0; i < 8; i++)
  3320. rtw_write8(adapter, REG_TSFTR1 + i, tsftr[i]);
  3321. for (i = 0; i < 6; i++)
  3322. rtw_write8(adapter, REG_MACID1 + i, macid[i]);
  3323. for (i = 0; i < 6; i++)
  3324. rtw_write8(adapter, REG_BSSID1 + i, bssid[i]);
  3325. /* write bcn ctl */
  3326. #ifdef CONFIG_BT_COEXIST
  3327. /* always enable port0 beacon function for PSTDMA */
  3328. if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter)
  3329. || IS_HARDWARE_TYPE_8723D(adapter))
  3330. bcn_ctrl_1 |= EN_BCN_FUNCTION;
  3331. /* always disable port1 beacon function for PSTDMA */
  3332. if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter))
  3333. bcn_ctrl &= ~EN_BCN_FUNCTION;
  3334. #endif
  3335. rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1);
  3336. rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl);
  3337. #if defined(CONFIG_RTL8192F)
  3338. /* if the setting of port0 and port1 are the same, it does not need to switch port setting*/
  3339. if(((wlan_act_mask_ctrl & en_port_mask) != 0) && ((wlan_act_mask_ctrl & en_port_mask)
  3340. != (EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION)))
  3341. wlan_act_mask_ctrl ^= en_port_mask;
  3342. rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl);
  3343. #endif
  3344. if (adapter->iface_id == IFACE_ID0)
  3345. iface = dvobj->padapters[IFACE_ID1];
  3346. else if (adapter->iface_id == IFACE_ID1)
  3347. iface = dvobj->padapters[IFACE_ID0];
  3348. if (adapter->hw_port == HW_PORT0) {
  3349. adapter->hw_port = HW_PORT1;
  3350. iface->hw_port = HW_PORT0;
  3351. RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
  3352. ADPT_ARG(iface), ADPT_ARG(adapter));
  3353. } else {
  3354. adapter->hw_port = HW_PORT0;
  3355. iface->hw_port = HW_PORT1;
  3356. RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
  3357. ADPT_ARG(adapter), ADPT_ARG(iface));
  3358. }
  3359. #ifdef DBG_RUNTIME_PORT_SWITCH
  3360. msr = rtw_read8(adapter, MSR);
  3361. bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
  3362. bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
  3363. #if defined(CONFIG_RTL8192F)
  3364. wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
  3365. #endif
  3366. for (i = 0; i < 2; i++)
  3367. atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
  3368. for (i = 0; i < 2; i++)
  3369. atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
  3370. for (i = 0; i < 8; i++)
  3371. tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
  3372. for (i = 0; i < 8; i++)
  3373. tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
  3374. for (i = 0; i < 6; i++)
  3375. macid[i] = rtw_read8(adapter, REG_MACID + i);
  3376. for (i = 0; i < 6; i++)
  3377. bssid[i] = rtw_read8(adapter, REG_BSSID + i);
  3378. for (i = 0; i < 6; i++)
  3379. macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
  3380. for (i = 0; i < 6; i++)
  3381. bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
  3382. RTW_INFO(FUNC_ADPT_FMT" after switch\n"
  3383. "msr:0x%02x\n"
  3384. "bcn_ctrl:0x%02x\n"
  3385. "bcn_ctrl_1:0x%02x\n"
  3386. #if defined(CONFIG_RTL8192F)
  3387. "wlan_act_mask_ctrl:0x%02x\n"
  3388. #endif
  3389. "atimwnd:%u\n"
  3390. "atimwnd_1:%u\n"
  3391. "tsftr:%llu\n"
  3392. "tsftr1:%llu\n"
  3393. "macid:"MAC_FMT"\n"
  3394. "bssid:"MAC_FMT"\n"
  3395. "macid_1:"MAC_FMT"\n"
  3396. "bssid_1:"MAC_FMT"\n"
  3397. , FUNC_ADPT_ARG(adapter)
  3398. , msr
  3399. , bcn_ctrl
  3400. , bcn_ctrl_1
  3401. #if defined(CONFIG_RTL8192F)
  3402. , wlan_act_mask_ctrl
  3403. #endif
  3404. , *((u16 *)atimwnd)
  3405. , *((u16 *)atimwnd_1)
  3406. , *((u64 *)tsftr)
  3407. , *((u64 *)tsftr_1)
  3408. , MAC_ARG(macid)
  3409. , MAC_ARG(bssid)
  3410. , MAC_ARG(macid_1)
  3411. , MAC_ARG(bssid_1)
  3412. );
  3413. #endif /* DBG_RUNTIME_PORT_SWITCH */
  3414. #endif /* CONFIG_RUNTIME_PORT_SWITCH */
  3415. #endif /* CONFIG_CONCURRENT_MODE */
  3416. }
  3417. const char *const _h2c_msr_role_str[] = {
  3418. "RSVD",
  3419. "STA",
  3420. "AP",
  3421. "GC",
  3422. "GO",
  3423. "TDLS",
  3424. "ADHOC",
  3425. "MESH",
  3426. "INVALID",
  3427. };
  3428. #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
  3429. s32 rtw_hal_set_default_port_id_cmd(_adapter *adapter, u8 mac_id)
  3430. {
  3431. s32 ret = _SUCCESS;
  3432. u8 parm[H2C_DEFAULT_PORT_ID_LEN] = {0};
  3433. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  3434. u8 port_id = rtw_hal_get_port(adapter);
  3435. if ((dvobj->dft.port_id == port_id) && (dvobj->dft.mac_id == mac_id))
  3436. return ret;
  3437. SET_H2CCMD_DFTPID_PORT_ID(parm, port_id);
  3438. SET_H2CCMD_DFTPID_MAC_ID(parm, mac_id);
  3439. RTW_DBG_DUMP("DFT port id parm:", parm, H2C_DEFAULT_PORT_ID_LEN);
  3440. RTW_INFO("%s ("ADPT_FMT") port_id :%d, mad_id:%d\n",
  3441. __func__, ADPT_ARG(adapter), port_id, mac_id);
  3442. ret = rtw_hal_fill_h2c_cmd(adapter, H2C_DEFAULT_PORT_ID, H2C_DEFAULT_PORT_ID_LEN, parm);
  3443. dvobj->dft.port_id = port_id;
  3444. dvobj->dft.mac_id = mac_id;
  3445. return ret;
  3446. }
  3447. s32 rtw_set_default_port_id(_adapter *adapter)
  3448. {
  3449. s32 ret = _SUCCESS;
  3450. struct sta_info *psta;
  3451. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  3452. if (is_client_associated_to_ap(adapter)) {
  3453. psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
  3454. if (psta)
  3455. ret = rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
  3456. } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
  3457. } else {
  3458. }
  3459. return ret;
  3460. }
  3461. s32 rtw_set_ps_rsvd_page(_adapter *adapter)
  3462. {
  3463. s32 ret = _SUCCESS;
  3464. u16 media_status_rpt = RT_MEDIA_CONNECT;
  3465. struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
  3466. if (adapter->iface_id == pwrctl->fw_psmode_iface_id)
  3467. return ret;
  3468. rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
  3469. (u8 *)&media_status_rpt);
  3470. return ret;
  3471. }
  3472. #if 0
  3473. _adapter * _rtw_search_dp_iface(_adapter *adapter)
  3474. {
  3475. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  3476. _adapter *iface;
  3477. _adapter *target_iface = NULL;
  3478. int i;
  3479. u8 sta_num = 0, tdls_num = 0, ap_num = 0, mesh_num = 0, adhoc_num = 0;
  3480. u8 p2p_go_num = 0, p2p_gc_num = 0;
  3481. _adapter *sta_ifs[8];
  3482. _adapter *ap_ifs[8];
  3483. _adapter *mesh_ifs[8];
  3484. _adapter *gc_ifs[8];
  3485. _adapter *go_ifs[8];
  3486. for (i = 0; i < dvobj->iface_nums; i++) {
  3487. iface = dvobj->padapters[i];
  3488. if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
  3489. if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE) {
  3490. sta_ifs[sta_num++] = iface;
  3491. #ifdef CONFIG_TDLS
  3492. if (iface->tdlsinfo.link_established == _TRUE)
  3493. tdls_num++;
  3494. #endif
  3495. #ifdef CONFIG_P2P
  3496. if (MLME_IS_GC(iface))
  3497. gc_ifs[p2p_gc_num++] = iface;
  3498. #endif
  3499. }
  3500. #ifdef CONFIG_AP_MODE
  3501. } else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
  3502. if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE) {
  3503. ap_ifs[ap_num++] = iface;
  3504. #ifdef CONFIG_P2P
  3505. if (MLME_IS_GO(iface))
  3506. go_ifs[p2p_go_num++] = iface;
  3507. #endif
  3508. }
  3509. #endif
  3510. } else if (check_fwstate(&iface->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE
  3511. && check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE
  3512. ) {
  3513. adhoc_num++;
  3514. #ifdef CONFIG_RTW_MESH
  3515. } else if (check_fwstate(&iface->mlmepriv, WIFI_MESH_STATE) == _TRUE
  3516. && check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE
  3517. ) {
  3518. mesh_ifs[mesh_num++] = iface;
  3519. #endif
  3520. }
  3521. }
  3522. if (p2p_gc_num) {
  3523. target_iface = gc_ifs[0];
  3524. }
  3525. else if (sta_num) {
  3526. if(sta_num == 1) {
  3527. target_iface = sta_ifs[0];
  3528. } else if (sta_num >= 2) {
  3529. /*TODO get target_iface by timestamp*/
  3530. target_iface = sta_ifs[0];
  3531. }
  3532. } else if (ap_num) {
  3533. target_iface = ap_ifs[0];
  3534. }
  3535. RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", sta_num);
  3536. RTW_INFO("[IFS_ASSOC_STATUS] - TDLS :%d", tdls_num);
  3537. RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", ap_num);
  3538. RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", mesh_num);
  3539. RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", adhoc_num);
  3540. RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", p2p_gc_num);
  3541. RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", p2p_go_num);
  3542. if (target_iface)
  3543. RTW_INFO("%s => target_iface ("ADPT_FMT")\n",
  3544. __func__, ADPT_ARG(target_iface));
  3545. else
  3546. RTW_INFO("%s => target_iface NULL\n", __func__);
  3547. return target_iface;
  3548. }
  3549. void rtw_search_default_port(_adapter *adapter)
  3550. {
  3551. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  3552. _adapter *adp_iface = NULL;
  3553. #ifdef CONFIG_WOWLAN
  3554. struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
  3555. if (pwrpriv->wowlan_mode == _TRUE) {
  3556. adp_iface = adapter;
  3557. goto exit;
  3558. }
  3559. #endif
  3560. adp_iface = _rtw_search_dp_iface(adapter);
  3561. exit :
  3562. if ((adp_iface != NULL) && (MLME_IS_STA(adp_iface)))
  3563. rtw_set_default_port_id(adp_iface);
  3564. else
  3565. rtw_hal_set_default_port_id_cmd(adapter, 0);
  3566. if (1) {
  3567. _adapter *tmp_adp;
  3568. tmp_adp = (adp_iface) ? adp_iface : adapter;
  3569. RTW_INFO("%s ("ADPT_FMT")=> hw_port :%d, default_port(%d)\n",
  3570. __func__, ADPT_ARG(adapter), get_hw_port(tmp_adp), get_dft_portid(tmp_adp));
  3571. }
  3572. }
  3573. #endif
  3574. #endif /*CONFIG_FW_MULTI_PORT_SUPPORT*/
  3575. #ifdef CONFIG_P2P_PS
  3576. #ifdef RTW_HALMAC
  3577. void rtw_set_p2p_ps_offload_cmd(_adapter *adapter, u8 p2p_ps_state)
  3578. {
  3579. PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
  3580. struct wifidirect_info *pwdinfo = &adapter->wdinfo;
  3581. struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
  3582. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  3583. WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
  3584. struct sta_priv *pstapriv = &adapter->stapriv;
  3585. struct sta_info *psta;
  3586. HAL_P2P_PS_PARA p2p_ps_para;
  3587. int status = -1;
  3588. u8 i;
  3589. u8 hw_port = rtw_hal_get_port(adapter);
  3590. _rtw_memset(&p2p_ps_para, 0, sizeof(HAL_P2P_PS_PARA));
  3591. _rtw_memcpy((&p2p_ps_para) , &hal->p2p_ps_offload , sizeof(hal->p2p_ps_offload));
  3592. (&p2p_ps_para)->p2p_port_id = hw_port;
  3593. (&p2p_ps_para)->p2p_group = 0;
  3594. psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
  3595. if (psta) {
  3596. (&p2p_ps_para)->p2p_macid = psta->cmn.mac_id;
  3597. } else {
  3598. if (p2p_ps_state != P2P_PS_DISABLE) {
  3599. RTW_ERR("%s , psta was NULL\n", __func__);
  3600. return;
  3601. }
  3602. }
  3603. switch (p2p_ps_state) {
  3604. case P2P_PS_DISABLE:
  3605. RTW_INFO("P2P_PS_DISABLE\n");
  3606. _rtw_memset(&p2p_ps_para , 0, sizeof(HAL_P2P_PS_PARA));
  3607. break;
  3608. case P2P_PS_ENABLE:
  3609. RTW_INFO("P2P_PS_ENABLE\n");
  3610. /* update CTWindow value. */
  3611. if (pwdinfo->ctwindow > 0) {
  3612. (&p2p_ps_para)->ctwindow_en = 1;
  3613. (&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
  3614. /*RTW_INFO("%s , ctwindow_length = %d\n" , __func__ , (&p2p_ps_para)->ctwindow_length);*/
  3615. }
  3616. if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) {
  3617. (&p2p_ps_para)->offload_en = 1;
  3618. if (pwdinfo->role == P2P_ROLE_GO) {
  3619. (&p2p_ps_para)->role = 1;
  3620. (&p2p_ps_para)->all_sta_sleep = 0;
  3621. } else
  3622. (&p2p_ps_para)->role = 0;
  3623. (&p2p_ps_para)->discovery = 0;
  3624. }
  3625. /* hw only support 2 set of NoA */
  3626. for (i = 0; i < pwdinfo->noa_num; i++) {
  3627. /* To control the register setting for which NOA */
  3628. (&p2p_ps_para)->noa_sel = i;
  3629. (&p2p_ps_para)->noa_en = 1;
  3630. /* config P2P NoA Descriptor Register */
  3631. /* config NOA duration */
  3632. (&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[i];
  3633. /* config NOA interval */
  3634. (&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[i];
  3635. /* config NOA start time */
  3636. (&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[i];
  3637. /* config NOA count */
  3638. (&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[i];
  3639. /*RTW_INFO("%s , noa_duration_para = %d , noa_interval_para = %d , noa_start_time_para = %d , noa_count_para = %d\n" , __func__ ,
  3640. (&p2p_ps_para)->noa_duration_para , (&p2p_ps_para)->noa_interval_para ,
  3641. (&p2p_ps_para)->noa_start_time_para , (&p2p_ps_para)->noa_count_para);*/
  3642. status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
  3643. if (status == -1)
  3644. RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
  3645. }
  3646. break;
  3647. case P2P_PS_SCAN:
  3648. /*This feature FW not ready 20161116 YiWei*/
  3649. return;
  3650. RTW_INFO("P2P_PS_SCAN\n");
  3651. (&p2p_ps_para)->discovery = 1;
  3652. /*
  3653. (&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
  3654. (&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
  3655. (&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
  3656. (&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
  3657. (&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
  3658. */
  3659. break;
  3660. case P2P_PS_SCAN_DONE:
  3661. /*This feature FW not ready 20161116 YiWei*/
  3662. return;
  3663. RTW_INFO("P2P_PS_SCAN_DONE\n");
  3664. (&p2p_ps_para)->discovery = 0;
  3665. /*
  3666. pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
  3667. (&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
  3668. (&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
  3669. (&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
  3670. (&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
  3671. (&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
  3672. */
  3673. break;
  3674. default:
  3675. break;
  3676. }
  3677. if (p2p_ps_state != P2P_PS_ENABLE || (&p2p_ps_para)->noa_en == 0) {
  3678. status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
  3679. if (status == -1)
  3680. RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
  3681. }
  3682. _rtw_memcpy(&hal->p2p_ps_offload , (&p2p_ps_para) , sizeof(hal->p2p_ps_offload));
  3683. }
  3684. #endif /* RTW_HALMAC */
  3685. #endif /* CONFIG_P2P */
  3686. /*
  3687. * rtw_hal_set_FwMediaStatusRpt_cmd -
  3688. *
  3689. * @adapter:
  3690. * @opmode: 0:disconnect, 1:connect
  3691. * @miracast: 0:it's not in miracast scenario. 1:it's in miracast scenario
  3692. * @miracast_sink: 0:source. 1:sink
  3693. * @role: The role of this macid. 0:rsvd. 1:STA. 2:AP. 3:GC. 4:GO. 5:TDLS
  3694. * @macid:
  3695. * @macid_ind: 0:update Media Status to macid. 1:update Media Status from macid to macid_end
  3696. * @macid_end:
  3697. */
  3698. s32 rtw_hal_set_FwMediaStatusRpt_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, bool macid_ind, u8 macid_end)
  3699. {
  3700. struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
  3701. u8 parm[H2C_MEDIA_STATUS_RPT_LEN] = {0};
  3702. int i;
  3703. s32 ret;
  3704. #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
  3705. u8 hw_port = rtw_hal_get_port(adapter);
  3706. #endif
  3707. SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, opmode);
  3708. SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, macid_ind);
  3709. SET_H2CCMD_MSRRPT_PARM_MIRACAST(parm, miracast);
  3710. SET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(parm, miracast_sink);
  3711. SET_H2CCMD_MSRRPT_PARM_ROLE(parm, role);
  3712. SET_H2CCMD_MSRRPT_PARM_MACID(parm, macid);
  3713. SET_H2CCMD_MSRRPT_PARM_MACID_END(parm, macid_end);
  3714. #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
  3715. SET_H2CCMD_MSRRPT_PARM_PORT_NUM(parm, hw_port);
  3716. #endif
  3717. RTW_DBG_DUMP("MediaStatusRpt parm:", parm, H2C_MEDIA_STATUS_RPT_LEN);
  3718. ret = rtw_hal_fill_h2c_cmd(adapter, H2C_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, parm);
  3719. if (ret != _SUCCESS)
  3720. goto exit;
  3721. #if defined(CONFIG_RTL8188E)
  3722. if (rtw_get_chip_type(adapter) == RTL8188E) {
  3723. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
  3724. /* 8188E FW doesn't set macid no link, driver does it by self */
  3725. if (opmode)
  3726. rtw_hal_set_hwreg(adapter, HW_VAR_MACID_LINK, &macid);
  3727. else
  3728. rtw_hal_set_hwreg(adapter, HW_VAR_MACID_NOLINK, &macid);
  3729. /* for 8188E RA */
  3730. #if (RATE_ADAPTIVE_SUPPORT == 1)
  3731. if (hal_data->fw_ractrl == _FALSE) {
  3732. u8 max_macid;
  3733. max_macid = rtw_search_max_mac_id(adapter);
  3734. rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, &max_macid);
  3735. }
  3736. #endif
  3737. }
  3738. #endif
  3739. #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
  3740. /* TODO: this should move to IOT issue area */
  3741. if (rtw_get_chip_type(adapter) == RTL8812
  3742. || rtw_get_chip_type(adapter) == RTL8821
  3743. ) {
  3744. if (MLME_IS_STA(adapter))
  3745. Hal_PatchwithJaguar_8812(adapter, opmode);
  3746. }
  3747. #endif
  3748. SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
  3749. if (macid_ind == 0)
  3750. macid_end = macid;
  3751. for (i = macid; macid <= macid_end; macid++) {
  3752. rtw_macid_ctl_set_h2c_msr(macid_ctl, macid, parm[0]);
  3753. if (!opmode) {
  3754. rtw_macid_ctl_set_bw(macid_ctl, macid, CHANNEL_WIDTH_20);
  3755. rtw_macid_ctl_set_vht_en(macid_ctl, macid, 0);
  3756. rtw_macid_ctl_set_rate_bmp0(macid_ctl, macid, 0);
  3757. rtw_macid_ctl_set_rate_bmp1(macid_ctl, macid, 0);
  3758. }
  3759. }
  3760. if (!opmode)
  3761. rtw_update_tx_rate_bmp(adapter_to_dvobj(adapter));
  3762. exit:
  3763. return ret;
  3764. }
  3765. inline s32 rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid)
  3766. {
  3767. return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 0, 0);
  3768. }
  3769. inline s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, u8 macid_end)
  3770. {
  3771. return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 1, macid_end);
  3772. }
  3773. void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
  3774. {
  3775. struct hal_ops *pHalFunc = &padapter->hal_func;
  3776. u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0};
  3777. u8 ret = 0;
  3778. RTW_INFO("RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",
  3779. rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
  3780. rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
  3781. rsvdpageloc->LocBTQosNull);
  3782. SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
  3783. SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
  3784. SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
  3785. SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
  3786. SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
  3787. ret = rtw_hal_fill_h2c_cmd(padapter,
  3788. H2C_RSVD_PAGE,
  3789. H2C_RSVDPAGE_LOC_LEN,
  3790. u1H2CRsvdPageParm);
  3791. }
  3792. #ifdef CONFIG_GPIO_WAKEUP
  3793. void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable)
  3794. {
  3795. PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
  3796. if (IS_8723D_SERIES(pHalData->version_id) || IS_8822B_SERIES(pHalData->version_id) || IS_8821C_SERIES(pHalData->version_id))
  3797. rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
  3798. /*
  3799. * Switch GPIO_13, GPIO_14 to wlan control, or pull GPIO_13,14 MUST fail.
  3800. * It happended at 8723B/8192E/8821A. New IC will check multi function GPIO,
  3801. * and implement HAL function.
  3802. * TODO: GPIO_8 multi function?
  3803. */
  3804. if ((index == 13 || index == 14)
  3805. #if defined(CONFIG_RTL8821A) && defined(CONFIG_SDIO_HCI)
  3806. /* 8821A's LED2 circuit(used by HW_LED strategy) needs enable WL GPIO control of GPIO[14:13], can't disable */
  3807. && (!IS_HW_LED_STRATEGY(rtw_led_get_strategy(padapter)) || enable)
  3808. #endif
  3809. )
  3810. rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
  3811. }
  3812. void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval)
  3813. {
  3814. if (index <= 7) {
  3815. /* config GPIO mode */
  3816. rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
  3817. rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
  3818. /* config GPIO Sel */
  3819. /* 0: input */
  3820. /* 1: output */
  3821. rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
  3822. rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) | BIT(index));
  3823. /* set output value */
  3824. if (outputval) {
  3825. rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
  3826. rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) | BIT(index));
  3827. } else {
  3828. rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
  3829. rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(index));
  3830. }
  3831. } else if (index <= 15) {
  3832. /* 88C Series: */
  3833. /* index: 11~8 transform to 3~0 */
  3834. /* 8723 Series: */
  3835. /* index: 12~8 transform to 4~0 */
  3836. index -= 8;
  3837. /* config GPIO mode */
  3838. rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
  3839. rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
  3840. /* config GPIO Sel */
  3841. /* 0: input */
  3842. /* 1: output */
  3843. rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
  3844. rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) | BIT(index));
  3845. /* set output value */
  3846. if (outputval) {
  3847. rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
  3848. rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) | BIT(index));
  3849. } else {
  3850. rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
  3851. rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) & ~BIT(index));
  3852. }
  3853. } else {
  3854. RTW_INFO("%s: invalid GPIO%d=%d\n",
  3855. __FUNCTION__, index, outputval);
  3856. }
  3857. }
  3858. void rtw_hal_set_input_gpio(_adapter *padapter, u8 index)
  3859. {
  3860. if (index <= 7) {
  3861. /* config GPIO mode */
  3862. rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
  3863. rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
  3864. /* config GPIO Sel */
  3865. /* 0: input */
  3866. /* 1: output */
  3867. rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
  3868. rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) & ~BIT(index));
  3869. } else if (index <= 15) {
  3870. /* 88C Series: */
  3871. /* index: 11~8 transform to 3~0 */
  3872. /* 8723 Series: */
  3873. /* index: 12~8 transform to 4~0 */
  3874. index -= 8;
  3875. /* config GPIO mode */
  3876. rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
  3877. rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
  3878. /* config GPIO Sel */
  3879. /* 0: input */
  3880. /* 1: output */
  3881. rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
  3882. rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) & ~BIT(index));
  3883. } else
  3884. RTW_INFO("%s: invalid GPIO%d\n", __func__, index);
  3885. }
  3886. #endif
  3887. void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
  3888. {
  3889. struct hal_ops *pHalFunc = &padapter->hal_func;
  3890. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
  3891. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  3892. u8 res = 0, count = 0, ret = 0;
  3893. #ifdef CONFIG_WOWLAN
  3894. u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
  3895. RTW_INFO("%s: RWC: %d ArpRsp: %d NbrAdv: %d LocNDPInfo: %d\n",
  3896. __func__, rsvdpageloc->LocRemoteCtrlInfo,
  3897. rsvdpageloc->LocArpRsp, rsvdpageloc->LocNbrAdv,
  3898. rsvdpageloc->LocNDPInfo);
  3899. RTW_INFO("%s:GtkRsp: %d GtkInfo: %d ProbeReq: %d NetworkList: %d\n",
  3900. __func__, rsvdpageloc->LocGTKRsp, rsvdpageloc->LocGTKInfo,
  3901. rsvdpageloc->LocProbeReq, rsvdpageloc->LocNetList);
  3902. if (check_fwstate(pmlmepriv, _FW_LINKED)) {
  3903. SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
  3904. SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
  3905. SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm,
  3906. rsvdpageloc->LocNbrAdv);
  3907. SET_H2CCMD_AOAC_RSVDPAGE_LOC_NDP_INFO(u1H2CAoacRsvdPageParm,
  3908. rsvdpageloc->LocNDPInfo);
  3909. #ifdef CONFIG_GTK_OL
  3910. SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
  3911. SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
  3912. SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
  3913. #endif /* CONFIG_GTK_OL */
  3914. ret = rtw_hal_fill_h2c_cmd(padapter,
  3915. H2C_AOAC_RSVD_PAGE,
  3916. H2C_AOAC_RSVDPAGE_LOC_LEN,
  3917. u1H2CAoacRsvdPageParm);
  3918. RTW_INFO("AOAC Report=%d\n", rsvdpageloc->LocAOACReport);
  3919. _rtw_memset(&u1H2CAoacRsvdPageParm, 0, sizeof(u1H2CAoacRsvdPageParm));
  3920. SET_H2CCMD_AOAC_RSVDPAGE_LOC_AOAC_REPORT(u1H2CAoacRsvdPageParm,
  3921. rsvdpageloc->LocAOACReport);
  3922. ret = rtw_hal_fill_h2c_cmd(padapter,
  3923. H2C_AOAC_RSVDPAGE3,
  3924. H2C_AOAC_RSVDPAGE_LOC_LEN,
  3925. u1H2CAoacRsvdPageParm);
  3926. pwrpriv->wowlan_aoac_rpt_loc = rsvdpageloc->LocAOACReport;
  3927. }
  3928. #ifdef CONFIG_PNO_SUPPORT
  3929. else {
  3930. if (!pwrpriv->wowlan_in_resume) {
  3931. RTW_INFO("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
  3932. _rtw_memset(&u1H2CAoacRsvdPageParm, 0,
  3933. sizeof(u1H2CAoacRsvdPageParm));
  3934. SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm,
  3935. rsvdpageloc->LocPNOInfo);
  3936. ret = rtw_hal_fill_h2c_cmd(padapter,
  3937. H2C_AOAC_RSVDPAGE3,
  3938. H2C_AOAC_RSVDPAGE_LOC_LEN,
  3939. u1H2CAoacRsvdPageParm);
  3940. }
  3941. }
  3942. #endif /* CONFIG_PNO_SUPPORT */
  3943. #endif /* CONFIG_WOWLAN */
  3944. }
  3945. #ifdef DBG_FW_DEBUG_MSG_PKT
  3946. void rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
  3947. {
  3948. struct hal_ops *pHalFunc = &padapter->hal_func;
  3949. u8 u1H2C_fw_dbg_msg_pkt_parm[H2C_FW_DBG_MSG_PKT_LEN] = {0};
  3950. u8 ret = 0;
  3951. RTW_INFO("RsvdPageLoc: loc_fw_dbg_msg_pkt =%d\n", rsvdpageloc->loc_fw_dbg_msg_pkt);
  3952. SET_H2CCMD_FW_DBG_MSG_PKT_EN(u1H2C_fw_dbg_msg_pkt_parm, 1);
  3953. SET_H2CCMD_RSVDPAGE_LOC_FW_DBG_MSG_PKT(u1H2C_fw_dbg_msg_pkt_parm, rsvdpageloc->loc_fw_dbg_msg_pkt);
  3954. ret = rtw_hal_fill_h2c_cmd(padapter,
  3955. H2C_FW_DBG_MSG_PKT,
  3956. H2C_FW_DBG_MSG_PKT_LEN,
  3957. u1H2C_fw_dbg_msg_pkt_parm);
  3958. }
  3959. #endif /*DBG_FW_DEBUG_MSG_PKT*/
  3960. /*#define DBG_GET_RSVD_PAGE*/
  3961. int rtw_hal_get_rsvd_page(_adapter *adapter, u32 page_offset,
  3962. u32 page_num, u8 *buffer, u32 buffer_size)
  3963. {
  3964. u32 addr = 0, size = 0, count = 0;
  3965. u32 page_size = 0, data_low = 0, data_high = 0;
  3966. u16 txbndy = 0, offset = 0;
  3967. u8 i = 0;
  3968. bool rst = _FALSE;
  3969. #ifdef DBG_LA_MODE
  3970. struct registry_priv *registry_par = &adapter->registrypriv;
  3971. if(registry_par->la_mode_en == 1) {
  3972. RTW_INFO("%s LA debug mode can't dump rsvd pg \n", __func__);
  3973. return rst;
  3974. }
  3975. #endif
  3976. rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
  3977. addr = page_offset * page_size;
  3978. size = page_num * page_size;
  3979. if (buffer_size < size) {
  3980. RTW_ERR("%s buffer_size(%d) < get page total size(%d)\n",
  3981. __func__, buffer_size, size);
  3982. return rst;
  3983. }
  3984. #ifdef RTW_HALMAC
  3985. if (rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), 2, addr, size, buffer) < 0)
  3986. rst = _FALSE;
  3987. else
  3988. rst = _TRUE;
  3989. #else
  3990. txbndy = rtw_read8(adapter, REG_TDECTRL + 1);
  3991. offset = (txbndy + page_offset) * page_size / 8;
  3992. count = (buffer_size / 8) + 1;
  3993. rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x69);
  3994. for (i = 0 ; i < count ; i++) {
  3995. rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, offset + i);
  3996. data_low = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
  3997. data_high = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
  3998. _rtw_memcpy(buffer + (i * 8),
  3999. &data_low, sizeof(data_low));
  4000. _rtw_memcpy(buffer + ((i * 8) + 4),
  4001. &data_high, sizeof(data_high));
  4002. }
  4003. rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x0);
  4004. rst = _TRUE;
  4005. #endif /*RTW_HALMAC*/
  4006. #ifdef DBG_GET_RSVD_PAGE
  4007. RTW_INFO("%s [page_offset:%d , page_num:%d][start_addr:0x%04x , size:%d]\n",
  4008. __func__, page_offset, page_num, addr, size);
  4009. RTW_INFO_DUMP("\n", buffer, size);
  4010. RTW_INFO(" ==================================================\n");
  4011. #endif
  4012. return rst;
  4013. }
  4014. void rtw_dump_rsvd_page(void *sel, _adapter *adapter, u8 page_offset, u8 page_num)
  4015. {
  4016. u32 page_size = 0;
  4017. u8 *buffer = NULL;
  4018. u32 buf_size = 0;
  4019. if (page_num == 0)
  4020. return;
  4021. RTW_PRINT_SEL(sel, "======= RSVD PAGE DUMP =======\n");
  4022. RTW_PRINT_SEL(sel, "page_offset:%d, page_num:%d\n", page_offset, page_num);
  4023. rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
  4024. if (page_size) {
  4025. buf_size = page_size * page_num;
  4026. buffer = rtw_zvmalloc(buf_size);
  4027. if (buffer) {
  4028. rtw_hal_get_rsvd_page(adapter, page_offset, page_num, buffer, buf_size);
  4029. RTW_DUMP_SEL(sel, buffer, buf_size);
  4030. rtw_vmfree(buffer, buf_size);
  4031. } else
  4032. RTW_PRINT_SEL(sel, "ERROR - rsvd_buf mem allocate failed\n");
  4033. } else
  4034. RTW_PRINT_SEL(sel, "ERROR - Tx page size is zero ??\n");
  4035. RTW_PRINT_SEL(sel, "==========================\n");
  4036. }
  4037. #ifdef CONFIG_SUPPORT_FIFO_DUMP
  4038. void rtw_dump_fifo(void *sel, _adapter *adapter, u8 fifo_sel, u32 fifo_addr, u32 fifo_size)
  4039. {
  4040. u8 *buffer = NULL;
  4041. u32 buff_size = 0;
  4042. static const char * const fifo_sel_str[] = {
  4043. "TX", "RX", "RSVD_PAGE", "REPORT", "LLT", "RXBUF_FW"
  4044. };
  4045. if (fifo_sel > 5) {
  4046. RTW_ERR("fifo_sel:%d invalid\n", fifo_sel);
  4047. return;
  4048. }
  4049. RTW_PRINT_SEL(sel, "========= FIFO DUMP =========\n");
  4050. RTW_PRINT_SEL(sel, "%s FIFO DUMP [start_addr:0x%04x , size:%d]\n", fifo_sel_str[fifo_sel], fifo_addr, fifo_size);
  4051. if (fifo_size) {
  4052. buff_size = RND4(fifo_size);
  4053. buffer = rtw_zvmalloc(buff_size);
  4054. if (buffer == NULL)
  4055. buff_size = 0;
  4056. }
  4057. rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), fifo_sel, fifo_addr, buff_size, buffer);
  4058. if (buffer) {
  4059. RTW_DUMP_SEL(sel, buffer, fifo_size);
  4060. rtw_vmfree(buffer, buff_size);
  4061. }
  4062. RTW_PRINT_SEL(sel, "==========================\n");
  4063. }
  4064. #endif
  4065. #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
  4066. static void rtw_hal_force_enable_rxdma(_adapter *adapter)
  4067. {
  4068. RTW_INFO("%s: Set 0x690=0x00\n", __func__);
  4069. rtw_write8(adapter, REG_WOW_CTRL,
  4070. (rtw_read8(adapter, REG_WOW_CTRL) & 0xf0));
  4071. RTW_PRINT("%s: Release RXDMA\n", __func__);
  4072. rtw_write32(adapter, REG_RXPKT_NUM,
  4073. (rtw_read32(adapter, REG_RXPKT_NUM) & (~RW_RELEASE_EN)));
  4074. }
  4075. #if defined(CONFIG_RTL8188E)
  4076. static void rtw_hal_disable_tx_report(_adapter *adapter)
  4077. {
  4078. rtw_write8(adapter, REG_TX_RPT_CTRL,
  4079. ((rtw_read8(adapter, REG_TX_RPT_CTRL) & ~BIT(1))) & ~BIT(5));
  4080. RTW_INFO("disable TXRPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
  4081. }
  4082. static void rtw_hal_enable_tx_report(_adapter *adapter)
  4083. {
  4084. rtw_write8(adapter, REG_TX_RPT_CTRL,
  4085. ((rtw_read8(adapter, REG_TX_RPT_CTRL) | BIT(1))) | BIT(5));
  4086. RTW_INFO("enable TX_RPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
  4087. }
  4088. #endif
  4089. static void rtw_hal_release_rx_dma(_adapter *adapter)
  4090. {
  4091. u32 val32 = 0;
  4092. val32 = rtw_read32(adapter, REG_RXPKT_NUM);
  4093. rtw_write32(adapter, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
  4094. RTW_INFO("%s, [0x%04x]: 0x%08x\n",
  4095. __func__, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
  4096. }
  4097. static u8 rtw_hal_pause_rx_dma(_adapter *adapter)
  4098. {
  4099. PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
  4100. u8 ret = 0;
  4101. s8 trycnt = 100;
  4102. u32 tmp = 0;
  4103. int res = 0;
  4104. /* RX DMA stop */
  4105. RTW_PRINT("Pause DMA\n");
  4106. rtw_write32(adapter, REG_RXPKT_NUM,
  4107. (rtw_read32(adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
  4108. do {
  4109. if ((rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE)) {
  4110. #ifdef CONFIG_USB_HCI
  4111. /* stop interface before leave */
  4112. if (_TRUE == hal->usb_intf_start) {
  4113. rtw_intf_stop(adapter);
  4114. RTW_ENABLE_FUNC(adapter, DF_RX_BIT);
  4115. RTW_ENABLE_FUNC(adapter, DF_TX_BIT);
  4116. }
  4117. #endif /* CONFIG_USB_HCI */
  4118. RTW_PRINT("RX_DMA_IDLE is true\n");
  4119. ret = _SUCCESS;
  4120. break;
  4121. }
  4122. #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
  4123. else {
  4124. res = RecvOnePkt(adapter);
  4125. RTW_PRINT("RecvOnePkt Result: %d\n", res);
  4126. }
  4127. #endif /* CONFIG_SDIO_HCI || CONFIG_GSPI_HCI */
  4128. #ifdef CONFIG_USB_HCI
  4129. else {
  4130. /* to avoid interface start repeatedly */
  4131. if (_FALSE == hal->usb_intf_start)
  4132. rtw_intf_start(adapter);
  4133. }
  4134. #endif /* CONFIG_USB_HCI */
  4135. } while (trycnt--);
  4136. if (trycnt < 0) {
  4137. tmp = rtw_read16(adapter, REG_RXPKT_NUM + 2);
  4138. RTW_PRINT("Stop RX DMA failed......\n");
  4139. RTW_PRINT("%s, RXPKT_NUM: 0x%02x\n",
  4140. __func__, ((tmp & 0xFF00) >> 8));
  4141. if (tmp & BIT(3))
  4142. RTW_PRINT("%s, RX DMA has req\n",
  4143. __func__);
  4144. else
  4145. RTW_PRINT("%s, RX DMA no req\n",
  4146. __func__);
  4147. ret = _FAIL;
  4148. }
  4149. return ret;
  4150. }
  4151. #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
  4152. #ifndef RTW_HALMAC
  4153. static u8 rtw_hal_enable_cpwm2(_adapter *adapter)
  4154. {
  4155. u8 ret = 0;
  4156. int res = 0;
  4157. u32 tmp = 0;
  4158. #ifdef CONFIG_GPIO_WAKEUP
  4159. return _SUCCESS;
  4160. #else
  4161. RTW_PRINT("%s\n", __func__);
  4162. res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
  4163. if (!res)
  4164. RTW_INFO("read SDIO_REG_HIMR: 0x%08x\n", tmp);
  4165. else
  4166. RTW_INFO("sdio_local_read fail\n");
  4167. tmp = SDIO_HIMR_CPWM2_MSK;
  4168. res = sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
  4169. if (!res) {
  4170. res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
  4171. RTW_INFO("read again SDIO_REG_HIMR: 0x%08x\n", tmp);
  4172. ret = _SUCCESS;
  4173. } else {
  4174. RTW_INFO("sdio_local_write fail\n");
  4175. ret = _FAIL;
  4176. }
  4177. return ret;
  4178. #endif /* CONFIG_CPIO_WAKEUP */
  4179. }
  4180. #endif
  4181. #endif /* CONFIG_SDIO_HCI, CONFIG_GSPI_HCI */
  4182. #endif /* CONFIG_WOWLAN || CONFIG_AP_WOWLAN */
  4183. #ifdef CONFIG_WOWLAN
  4184. /*
  4185. * rtw_hal_check_wow_ctrl
  4186. * chk_type: _TRUE means to check enable, if 0x690 & bit1 (for 8051), WOW enable successful.
  4187. * If 0x1C7 == 0 (for 3081), WOW enable successful.
  4188. * _FALSE means to check disable, if 0x690 & bit1 (for 8051), WOW disable fail.
  4189. * If 0x120 & bit16 || 0x284 & bit18 (for 3081), WOW disable fail.
  4190. */
  4191. static u8 rtw_hal_check_wow_ctrl(_adapter *adapter, u8 chk_type)
  4192. {
  4193. u32 fe1_imr = 0xFF, rxpkt_num = 0xFF;
  4194. u8 mstatus = 0;
  4195. u8 reason = 0xFF;
  4196. u8 trycnt = 25;
  4197. u8 res = _FALSE;
  4198. if (IS_HARDWARE_TYPE_JAGUAR2(adapter)) {
  4199. if (chk_type) {
  4200. reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
  4201. RTW_INFO("%s reason:0x%02x\n", __func__, reason);
  4202. while (reason && trycnt > 1) {
  4203. reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
  4204. RTW_PRINT("Loop index: %d :0x%02x\n",
  4205. trycnt, reason);
  4206. trycnt--;
  4207. rtw_msleep_os(20);
  4208. }
  4209. if (!reason)
  4210. res = _TRUE;
  4211. else
  4212. res = _FALSE;
  4213. } else {
  4214. /* Wait FW to cleare 0x120 bit16, 0x284 bit18 to 0 */
  4215. fe1_imr = rtw_read32(adapter, REG_FE1IMR); /* RxDone IMR for 3081 */
  4216. rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM); /* Release RXDMA */
  4217. RTW_PRINT("%s REG_FE1IMR (reg120): 0x%x, REG_RXPKT_NUM(reg284): 0x%x\n", __func__, fe1_imr, rxpkt_num);
  4218. while (((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN)) && trycnt > 1) {
  4219. rtw_msleep_os(20);
  4220. fe1_imr = rtw_read32(adapter, REG_FE1IMR);
  4221. rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM);
  4222. RTW_PRINT("Loop index: %d :0x%x, 0x%x\n",
  4223. trycnt, fe1_imr, rxpkt_num);
  4224. trycnt--;
  4225. }
  4226. if ((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN))
  4227. res = _FALSE;
  4228. else
  4229. res = _TRUE;
  4230. }
  4231. } else {
  4232. mstatus = rtw_read8(adapter, REG_WOW_CTRL);
  4233. RTW_INFO("%s mstatus:0x%02x\n", __func__, mstatus);
  4234. if (chk_type) {
  4235. while (!(mstatus & BIT1) && trycnt > 1) {
  4236. mstatus = rtw_read8(adapter, REG_WOW_CTRL);
  4237. RTW_PRINT("Loop index: %d :0x%02x\n",
  4238. trycnt, mstatus);
  4239. trycnt--;
  4240. rtw_msleep_os(20);
  4241. }
  4242. if (mstatus & BIT1)
  4243. res = _TRUE;
  4244. else
  4245. res = _FALSE;
  4246. } else {
  4247. while (mstatus & BIT1 && trycnt > 1) {
  4248. mstatus = rtw_read8(adapter, REG_WOW_CTRL);
  4249. RTW_PRINT("Loop index: %d :0x%02x\n",
  4250. trycnt, mstatus);
  4251. trycnt--;
  4252. rtw_msleep_os(20);
  4253. }
  4254. if (mstatus & BIT1)
  4255. res = _FALSE;
  4256. else
  4257. res = _TRUE;
  4258. }
  4259. }
  4260. RTW_PRINT("%s check_type: %d res: %d trycnt: %d\n",
  4261. __func__, chk_type, res, (25 - trycnt));
  4262. return res;
  4263. }
  4264. #ifdef CONFIG_PNO_SUPPORT
  4265. static u8 rtw_hal_check_pno_enabled(_adapter *adapter)
  4266. {
  4267. struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
  4268. u8 res = 0, count = 0;
  4269. u8 ret = _FALSE;
  4270. if (ppwrpriv->wowlan_pno_enable && ppwrpriv->wowlan_in_resume == _FALSE) {
  4271. res = rtw_read8(adapter, REG_PNO_STATUS);
  4272. while (!(res & BIT(7)) && count < 25) {
  4273. RTW_INFO("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n",
  4274. count, res);
  4275. res = rtw_read8(adapter, REG_PNO_STATUS);
  4276. count++;
  4277. rtw_msleep_os(2);
  4278. }
  4279. if (res & BIT(7))
  4280. ret = _TRUE;
  4281. else
  4282. ret = _FALSE;
  4283. RTW_INFO("cmd: 0x81 REG_PNO_STATUS: ret(%d)\n", ret);
  4284. }
  4285. return ret;
  4286. }
  4287. #endif
  4288. static void rtw_hal_backup_rate(_adapter *adapter)
  4289. {
  4290. RTW_INFO("%s\n", __func__);
  4291. /* backup data rate to register 0x8b for wowlan FW */
  4292. rtw_write8(adapter, 0x8d, 1);
  4293. rtw_write8(adapter, 0x8c, 0);
  4294. rtw_write8(adapter, 0x8f, 0x40);
  4295. rtw_write8(adapter, 0x8b, rtw_read8(adapter, 0x2f0));
  4296. }
  4297. #ifdef CONFIG_GTK_OL
  4298. static void rtw_hal_fw_sync_cam_id(_adapter *adapter)
  4299. {
  4300. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  4301. int cam_id, index = 0;
  4302. u8 *addr = NULL;
  4303. if (!MLME_IS_STA(adapter))
  4304. return;
  4305. addr = get_bssid(pmlmepriv);
  4306. if (addr == NULL) {
  4307. RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
  4308. return;
  4309. }
  4310. rtw_clean_dk_section(adapter);
  4311. do {
  4312. cam_id = rtw_camid_search(adapter, addr, index, 1);
  4313. if (cam_id == -1)
  4314. RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
  4315. else
  4316. rtw_sec_cam_swap(adapter, cam_id, index);
  4317. index++;
  4318. } while (index < 4);
  4319. rtw_write8(adapter, REG_SECCFG, 0xcc);
  4320. }
  4321. static void rtw_hal_update_gtk_offload_info(_adapter *adapter)
  4322. {
  4323. struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
  4324. struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
  4325. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  4326. struct security_priv *psecuritypriv = &adapter->securitypriv;
  4327. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  4328. struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
  4329. _irqL irqL;
  4330. u8 get_key[16];
  4331. u8 gtk_id = 0, offset = 0, i = 0, sz = 0, aoac_rpt_ver = 0, has_rekey = _FALSE;
  4332. u64 replay_count = 0, tmp_iv_hdr = 0, pkt_pn = 0;
  4333. if (!MLME_IS_STA(adapter))
  4334. return;
  4335. _rtw_memset(get_key, 0, sizeof(get_key));
  4336. _rtw_memcpy(&replay_count,
  4337. paoac_rpt->replay_counter_eapol_key, 8);
  4338. /*read gtk key index*/
  4339. gtk_id = paoac_rpt->key_index;
  4340. aoac_rpt_ver = paoac_rpt->version_info;
  4341. if (aoac_rpt_ver == 0) {
  4342. /* initial verison */
  4343. if (gtk_id == 5)
  4344. has_rekey = _FALSE;
  4345. else
  4346. has_rekey = _TRUE;
  4347. } else if (aoac_rpt_ver >= 1) {
  4348. /* Add krack patch */
  4349. if (gtk_id == 5)
  4350. RTW_WARN("%s FW check iv fail\n", __func__);
  4351. if (aoac_rpt_ver == 1)
  4352. RTW_WARN("%s aoac report version should be update to v2\n", __func__);
  4353. /* Fix key id mismatch */
  4354. if (aoac_rpt_ver == 2)
  4355. has_rekey = paoac_rpt->rekey_ok == 1 ? _TRUE : _FALSE;
  4356. }
  4357. if (has_rekey == _FALSE) {
  4358. RTW_INFO("%s no rekey event happened.\n", __func__);
  4359. } else if (has_rekey == _TRUE) {
  4360. RTW_INFO("%s update security key.\n", __func__);
  4361. /*read key from sec-cam,for DK ,keyindex is equal to cam-id*/
  4362. rtw_sec_read_cam_ent(adapter, gtk_id,
  4363. NULL, NULL, get_key);
  4364. rtw_clean_hw_dk_cam(adapter);
  4365. if (_rtw_camid_is_gk(adapter, gtk_id)) {
  4366. _enter_critical_bh(&cam_ctl->lock, &irqL);
  4367. _rtw_memcpy(&dvobj->cam_cache[gtk_id].key,
  4368. get_key, 16);
  4369. _exit_critical_bh(&cam_ctl->lock, &irqL);
  4370. } else {
  4371. struct setkey_parm parm_gtk;
  4372. parm_gtk.algorithm = paoac_rpt->security_type;
  4373. parm_gtk.keyid = gtk_id;
  4374. _rtw_memcpy(parm_gtk.key, get_key, 16);
  4375. setkey_hdl(adapter, (u8 *)&parm_gtk);
  4376. }
  4377. /*update key into related sw variable and sec-cam cache*/
  4378. psecuritypriv->dot118021XGrpKeyid = gtk_id;
  4379. _rtw_memcpy(&psecuritypriv->dot118021XGrpKey[gtk_id],
  4380. get_key, 16);
  4381. /* update SW TKIP TX/RX MIC value */
  4382. if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
  4383. offset = RTW_KEK_LEN + RTW_TKIP_MIC_LEN;
  4384. _rtw_memcpy(
  4385. &psecuritypriv->dot118021XGrptxmickey[gtk_id],
  4386. &(paoac_rpt->group_key[offset]),
  4387. RTW_TKIP_MIC_LEN);
  4388. offset = RTW_KEK_LEN;
  4389. _rtw_memcpy(
  4390. &psecuritypriv->dot118021XGrprxmickey[gtk_id],
  4391. &(paoac_rpt->group_key[offset]),
  4392. RTW_TKIP_MIC_LEN);
  4393. }
  4394. RTW_PRINT("GTK (%d) "KEY_FMT"\n", gtk_id,
  4395. KEY_ARG(psecuritypriv->dot118021XGrpKey[gtk_id].skey));
  4396. }
  4397. /* Update broadcast RX IV */
  4398. if (psecuritypriv->dot118021XGrpPrivacy == _AES_) {
  4399. sz = sizeof(psecuritypriv->iv_seq[0]);
  4400. for (i = 0 ; i < 4 ; i++) {
  4401. _rtw_memcpy(&tmp_iv_hdr, paoac_rpt->rxgtk_iv[i], sz);
  4402. tmp_iv_hdr = le64_to_cpu(tmp_iv_hdr);
  4403. pkt_pn = CCMPH_2_PN(tmp_iv_hdr);
  4404. _rtw_memcpy(psecuritypriv->iv_seq[i], &pkt_pn, sz);
  4405. }
  4406. }
  4407. rtw_clean_dk_section(adapter);
  4408. rtw_write8(adapter, REG_SECCFG, 0x0c);
  4409. #ifdef CONFIG_GTK_OL_DBG
  4410. /* if (gtk_keyindex != 5) */
  4411. dump_sec_cam(RTW_DBGDUMP, adapter);
  4412. dump_sec_cam_cache(RTW_DBGDUMP, adapter);
  4413. #endif
  4414. }
  4415. #endif /*CONFIG_GTK_OL*/
  4416. static void rtw_dump_aoac_rpt(_adapter *adapter)
  4417. {
  4418. struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
  4419. struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
  4420. int i = 0;
  4421. RTW_INFO_DUMP("[AOAC-RPT] IV -", paoac_rpt->iv, 8);
  4422. RTW_INFO_DUMP("[AOAC-RPT] Replay counter of EAPOL key - ",
  4423. paoac_rpt->replay_counter_eapol_key, 8);
  4424. RTW_INFO_DUMP("[AOAC-RPT] Group key - ", paoac_rpt->group_key, 32);
  4425. RTW_INFO("[AOAC-RPT] Key Index - %d\n", paoac_rpt->key_index);
  4426. RTW_INFO("[AOAC-RPT] Security Type - %d\n", paoac_rpt->security_type);
  4427. RTW_INFO("[AOAC-RPT] wow_pattern_idx - %d\n",
  4428. paoac_rpt->wow_pattern_idx);
  4429. RTW_INFO("[AOAC-RPT] version_info - %d\n", paoac_rpt->version_info);
  4430. RTW_INFO("[AOAC-RPT] rekey_ok - %d\n", paoac_rpt->rekey_ok);
  4431. RTW_INFO_DUMP("[AOAC-RPT] RX PTK IV-", paoac_rpt->rxptk_iv, 8);
  4432. RTW_INFO_DUMP("[AOAC-RPT] RX GTK[0] IV-", paoac_rpt->rxgtk_iv[0], 8);
  4433. RTW_INFO_DUMP("[AOAC-RPT] RX GTK[1] IV-", paoac_rpt->rxgtk_iv[1], 8);
  4434. RTW_INFO_DUMP("[AOAC-RPT] RX GTK[2] IV-", paoac_rpt->rxgtk_iv[2], 8);
  4435. RTW_INFO_DUMP("[AOAC-RPT] RX GTK[3] IV-", paoac_rpt->rxgtk_iv[3], 8);
  4436. }
  4437. static void rtw_hal_get_aoac_rpt(_adapter *adapter)
  4438. {
  4439. struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
  4440. struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
  4441. u32 page_offset = 0, page_number = 0;
  4442. u32 page_size = 0, buf_size = 0;
  4443. u8 *buffer = NULL;
  4444. u8 i = 0, tmp = 0;
  4445. int ret = -1;
  4446. /* read aoac report from rsvd page */
  4447. page_offset = pwrctl->wowlan_aoac_rpt_loc;
  4448. page_number = 1;
  4449. rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
  4450. buf_size = page_size * page_number;
  4451. buffer = rtw_zvmalloc(buf_size);
  4452. if (buffer == NULL) {
  4453. RTW_ERR("%s buffer allocate failed size(%d)\n",
  4454. __func__, buf_size);
  4455. return;
  4456. }
  4457. RTW_INFO("Get AOAC Report from rsvd page_offset:%d\n", page_offset);
  4458. ret = rtw_hal_get_rsvd_page(adapter, page_offset,
  4459. page_number, buffer, buf_size);
  4460. if (ret == _FALSE) {
  4461. RTW_ERR("%s get aoac report failed\n", __func__);
  4462. rtw_warn_on(1);
  4463. goto _exit;
  4464. }
  4465. _rtw_memset(paoac_rpt, 0, sizeof(struct aoac_report));
  4466. _rtw_memcpy(paoac_rpt, buffer, sizeof(struct aoac_report));
  4467. for (i = 0 ; i < 4 ; i++) {
  4468. tmp = paoac_rpt->replay_counter_eapol_key[i];
  4469. paoac_rpt->replay_counter_eapol_key[i] =
  4470. paoac_rpt->replay_counter_eapol_key[7 - i];
  4471. paoac_rpt->replay_counter_eapol_key[7 - i] = tmp;
  4472. }
  4473. rtw_dump_aoac_rpt(adapter);
  4474. _exit:
  4475. if (buffer)
  4476. rtw_vmfree(buffer, buf_size);
  4477. }
  4478. static void rtw_hal_update_tx_iv(_adapter *adapter)
  4479. {
  4480. struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
  4481. struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
  4482. struct sta_info *psta;
  4483. struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
  4484. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  4485. struct security_priv *psecpriv = &adapter->securitypriv;
  4486. u16 val16 = 0;
  4487. u32 val32 = 0;
  4488. u64 txiv = 0;
  4489. u8 *pval = NULL;
  4490. psta = rtw_get_stainfo(&adapter->stapriv,
  4491. get_my_bssid(&pmlmeinfo->network));
  4492. /* Update TX iv data. */
  4493. pval = (u8 *)&paoac_rpt->iv;
  4494. if (psecpriv->dot11PrivacyAlgrthm == _TKIP_) {
  4495. val16 = ((u16)(paoac_rpt->iv[2]) << 0) +
  4496. ((u16)(paoac_rpt->iv[0]) << 8);
  4497. val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
  4498. ((u32)(paoac_rpt->iv[5]) << 8) +
  4499. ((u32)(paoac_rpt->iv[6]) << 16) +
  4500. ((u32)(paoac_rpt->iv[7]) << 24);
  4501. } else if (psecpriv->dot11PrivacyAlgrthm == _AES_) {
  4502. val16 = ((u16)(paoac_rpt->iv[0]) << 0) +
  4503. ((u16)(paoac_rpt->iv[1]) << 8);
  4504. val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
  4505. ((u32)(paoac_rpt->iv[5]) << 8) +
  4506. ((u32)(paoac_rpt->iv[6]) << 16) +
  4507. ((u32)(paoac_rpt->iv[7]) << 24);
  4508. }
  4509. if (psta) {
  4510. txiv = val16 + ((u64)val32 << 16);
  4511. if (txiv != 0)
  4512. psta->dot11txpn.val = txiv;
  4513. }
  4514. }
  4515. static void rtw_hal_update_sw_security_info(_adapter *adapter)
  4516. {
  4517. struct security_priv *psecpriv = &adapter->securitypriv;
  4518. u8 sz = sizeof (psecpriv->iv_seq);
  4519. rtw_hal_update_tx_iv(adapter);
  4520. #ifdef CONFIG_GTK_OL
  4521. if (psecpriv->binstallKCK_KEK == _TRUE &&
  4522. psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK)
  4523. rtw_hal_update_gtk_offload_info(adapter);
  4524. #else
  4525. _rtw_memset(psecpriv->iv_seq, 0, sz);
  4526. #endif
  4527. }
  4528. static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type)
  4529. {
  4530. struct hal_ops *pHalFunc = &adapter->hal_func;
  4531. u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN] = {0};
  4532. u8 adopt = 1, check_period = 5;
  4533. u8 ret = _FAIL;
  4534. u8 hw_port = rtw_hal_get_port(adapter);
  4535. SET_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, enable);
  4536. SET_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);
  4537. SET_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);
  4538. SET_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);
  4539. #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
  4540. SET_H2CCMD_KEEPALIVE_PARM_PORT_NUM(u1H2CKeepAliveParm, hw_port);
  4541. RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
  4542. #else
  4543. RTW_INFO("%s(): enable = %d\n", __func__, enable);
  4544. #endif
  4545. ret = rtw_hal_fill_h2c_cmd(adapter,
  4546. H2C_KEEP_ALIVE,
  4547. H2C_KEEP_ALIVE_CTRL_LEN,
  4548. u1H2CKeepAliveParm);
  4549. return ret;
  4550. }
  4551. static u8 rtw_hal_set_disconnect_decision_cmd(_adapter *adapter, u8 enable)
  4552. {
  4553. struct hal_ops *pHalFunc = &adapter->hal_func;
  4554. u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN] = {0};
  4555. u8 adopt = 1, check_period = 30, trypkt_num = 5;
  4556. u8 ret = _FAIL;
  4557. u8 hw_port = rtw_hal_get_port(adapter);
  4558. SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable);
  4559. SET_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);
  4560. SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);
  4561. SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);
  4562. #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
  4563. SET_H2CCMD_DISCONDECISION_PORT_NUM(u1H2CDisconDecisionParm, hw_port);
  4564. RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
  4565. #else
  4566. RTW_INFO("%s(): enable = %d\n", __func__, enable);
  4567. #endif
  4568. ret = rtw_hal_fill_h2c_cmd(adapter,
  4569. H2C_DISCON_DECISION,
  4570. H2C_DISCON_DECISION_LEN,
  4571. u1H2CDisconDecisionParm);
  4572. return ret;
  4573. }
  4574. static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_unit)
  4575. {
  4576. struct registry_priv *registry_par = &adapter->registrypriv;
  4577. struct security_priv *psecpriv = &adapter->securitypriv;
  4578. struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
  4579. struct hal_ops *pHalFunc = &adapter->hal_func;
  4580. u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN] = {0};
  4581. u8 discont_wake = 0, gpionum = 0, gpio_dur = 0;
  4582. u8 hw_unicast = 0, gpio_pulse_cnt = 0, gpio_pulse_en = 0;
  4583. u8 sdio_wakeup_enable = 1;
  4584. u8 gpio_high_active = 0;
  4585. u8 magic_pkt = 0;
  4586. u8 gpio_unit = 0; /*0: 64ns, 1: 8ms*/
  4587. u8 ret = _FAIL;
  4588. #ifdef CONFIG_DIS_UPHY
  4589. u8 dis_uphy = 0, dis_uphy_unit = 0, dis_uphy_time = 0;
  4590. #endif /* CONFIG_DIS_UPHY */
  4591. #ifdef CONFIG_GPIO_WAKEUP
  4592. gpio_high_active = ppwrpriv->is_high_active;
  4593. gpionum = WAKEUP_GPIO_IDX;
  4594. sdio_wakeup_enable = 0;
  4595. #endif /* CONFIG_GPIO_WAKEUP */
  4596. if (!ppwrpriv->wowlan_pno_enable &&
  4597. registry_par->wakeup_event & BIT(0))
  4598. magic_pkt = enable;
  4599. if ((registry_par->wakeup_event & BIT(1)) &&
  4600. (psecpriv->dot11PrivacyAlgrthm == _WEP40_ ||
  4601. psecpriv->dot11PrivacyAlgrthm == _WEP104_))
  4602. hw_unicast = 1;
  4603. if (registry_par->wakeup_event & BIT(2))
  4604. discont_wake = enable;
  4605. RTW_INFO("%s(): enable=%d change_unit=%d\n", __func__,
  4606. enable, change_unit);
  4607. /* time = (gpio_dur/2) * gpio_unit, default:256 ms */
  4608. if (enable && change_unit) {
  4609. gpio_dur = 0x40;
  4610. gpio_unit = 1;
  4611. gpio_pulse_en = 1;
  4612. }
  4613. #ifdef CONFIG_PLATFORM_ARM_RK3188
  4614. if (enable) {
  4615. gpio_pulse_en = 1;
  4616. gpio_pulse_cnt = 0x04;
  4617. }
  4618. #endif
  4619. SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable);
  4620. SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, enable);
  4621. SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);
  4622. SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);
  4623. SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);
  4624. SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);
  4625. #ifdef CONFIG_GTK_OL
  4626. if (psecpriv->binstallKCK_KEK == _TRUE &&
  4627. psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK)
  4628. SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 0);
  4629. else
  4630. SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 1);
  4631. #else
  4632. SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, enable);
  4633. #endif
  4634. SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake);
  4635. SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);
  4636. SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);
  4637. SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur);
  4638. SET_H2CCMD_WOWLAN_CHANGE_UNIT(u1H2CWoWlanCtrlParm, gpio_unit);
  4639. SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, gpio_pulse_en);
  4640. SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt);
  4641. #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
  4642. if (enable)
  4643. SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
  4644. #endif
  4645. #ifdef CONFIG_DIS_UPHY
  4646. if (enable) {
  4647. dis_uphy = 1;
  4648. /* time unit: 0 -> ms, 1 -> 256 ms*/
  4649. dis_uphy_unit = 1;
  4650. dis_uphy_time = 0x4;
  4651. }
  4652. SET_H2CCMD_WOWLAN_DISABLE_UPHY(u1H2CWoWlanCtrlParm, dis_uphy);
  4653. SET_H2CCMD_WOWLAN_UNIT_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_unit);
  4654. SET_H2CCMD_WOWLAN_TIME_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_time);
  4655. if (ppwrpriv->hst2dev_high_active == 1)
  4656. SET_H2CCMD_WOWLAN_RISE_HST2DEV(u1H2CWoWlanCtrlParm, 1);
  4657. #ifdef CONFIG_RTW_ONE_PIN_GPIO
  4658. SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
  4659. SET_H2CCMD_WOWLAN_DEV2HST_EN(u1H2CWoWlanCtrlParm, 1);
  4660. SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 0);
  4661. #else
  4662. SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 1);
  4663. #endif /* CONFIG_RTW_ONE_PIN_GPIO */
  4664. #endif /* CONFIG_DIS_UPHY */
  4665. ret = rtw_hal_fill_h2c_cmd(adapter,
  4666. H2C_WOWLAN,
  4667. H2C_WOWLAN_LEN,
  4668. u1H2CWoWlanCtrlParm);
  4669. return ret;
  4670. }
  4671. static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable)
  4672. {
  4673. struct hal_ops *pHalFunc = &adapter->hal_func;
  4674. struct security_priv *psecuritypriv = &(adapter->securitypriv);
  4675. struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
  4676. struct registry_priv *pregistrypriv = &adapter->registrypriv;
  4677. u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN] = {0};
  4678. u8 ret = _FAIL, count = 0;
  4679. RTW_INFO("%s(): enable=%d\n", __func__, enable);
  4680. if (!ppwrpriv->wowlan_pno_enable) {
  4681. SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
  4682. u1H2CRemoteWakeCtrlParm, enable);
  4683. SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
  4684. u1H2CRemoteWakeCtrlParm, 1);
  4685. #ifdef CONFIG_GTK_OL
  4686. if (psecuritypriv->binstallKCK_KEK == _TRUE &&
  4687. psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
  4688. SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
  4689. u1H2CRemoteWakeCtrlParm, 1);
  4690. } else {
  4691. RTW_INFO("no kck kek\n");
  4692. SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
  4693. u1H2CRemoteWakeCtrlParm, 0);
  4694. }
  4695. #endif /* CONFIG_GTK_OL */
  4696. #ifdef CONFIG_IPV6
  4697. if (ppwrpriv->wowlan_ns_offload_en == _TRUE) {
  4698. RTW_INFO("enable NS offload\n");
  4699. SET_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(
  4700. u1H2CRemoteWakeCtrlParm, enable);
  4701. }
  4702. /*
  4703. * filter NetBios name service pkt to avoid being waked-up
  4704. * by this kind of unicast pkt this exceptional modification
  4705. * is used for match competitor's behavior
  4706. */
  4707. SET_H2CCMD_REMOTE_WAKE_CTRL_NBNS_FILTER_EN(
  4708. u1H2CRemoteWakeCtrlParm, enable);
  4709. #endif /*CONFIG_IPV6*/
  4710. #ifdef CONFIG_RTL8192F
  4711. if (IS_HARDWARE_TYPE_8192F(adapter)){
  4712. SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(
  4713. u1H2CRemoteWakeCtrlParm, enable);
  4714. }
  4715. #endif /* CONFIG_RTL8192F */
  4716. if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) ||
  4717. (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) ||
  4718. (psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) {
  4719. SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
  4720. u1H2CRemoteWakeCtrlParm, 0);
  4721. } else {
  4722. SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
  4723. u1H2CRemoteWakeCtrlParm, 1);
  4724. }
  4725. if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_ &&
  4726. psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
  4727. SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
  4728. u1H2CRemoteWakeCtrlParm, enable);
  4729. if (IS_HARDWARE_TYPE_8188E(adapter) ||
  4730. IS_HARDWARE_TYPE_8812(adapter)) {
  4731. SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
  4732. u1H2CRemoteWakeCtrlParm, 0);
  4733. SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
  4734. u1H2CRemoteWakeCtrlParm, 1);
  4735. }
  4736. }
  4737. SET_H2CCMD_REMOTE_WAKE_CTRL_FW_PARSING_UNTIL_WAKEUP(
  4738. u1H2CRemoteWakeCtrlParm, 1);
  4739. }
  4740. #ifdef CONFIG_PNO_SUPPORT
  4741. else {
  4742. SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
  4743. u1H2CRemoteWakeCtrlParm, enable);
  4744. SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(
  4745. u1H2CRemoteWakeCtrlParm, enable);
  4746. }
  4747. #endif
  4748. #ifdef CONFIG_P2P_WOWLAN
  4749. if (_TRUE == ppwrpriv->wowlan_p2p_mode) {
  4750. RTW_INFO("P2P OFFLOAD ENABLE\n");
  4751. SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 1);
  4752. } else {
  4753. RTW_INFO("P2P OFFLOAD DISABLE\n");
  4754. SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 0);
  4755. }
  4756. #endif /* CONFIG_P2P_WOWLAN */
  4757. ret = rtw_hal_fill_h2c_cmd(adapter,
  4758. H2C_REMOTE_WAKE_CTRL,
  4759. H2C_REMOTE_WAKE_CTRL_LEN,
  4760. u1H2CRemoteWakeCtrlParm);
  4761. return ret;
  4762. }
  4763. static u8 rtw_hal_set_global_info_cmd(_adapter *adapter, u8 group_alg, u8 pairwise_alg)
  4764. {
  4765. struct hal_ops *pHalFunc = &adapter->hal_func;
  4766. u8 ret = _FAIL;
  4767. u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN] = {0};
  4768. RTW_INFO("%s(): group_alg=%d pairwise_alg=%d\n",
  4769. __func__, group_alg, pairwise_alg);
  4770. SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm,
  4771. pairwise_alg);
  4772. SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm,
  4773. group_alg);
  4774. ret = rtw_hal_fill_h2c_cmd(adapter,
  4775. H2C_AOAC_GLOBAL_INFO,
  4776. H2C_AOAC_GLOBAL_INFO_LEN,
  4777. u1H2CAOACGlobalInfoParm);
  4778. return ret;
  4779. }
  4780. #ifdef CONFIG_PNO_SUPPORT
  4781. static u8 rtw_hal_set_scan_offload_info_cmd(_adapter *adapter,
  4782. PRSVDPAGE_LOC rsvdpageloc, u8 enable)
  4783. {
  4784. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
  4785. struct hal_ops *pHalFunc = &adapter->hal_func;
  4786. u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN] = {0};
  4787. u8 res = 0, count = 0, ret = _FAIL;
  4788. RTW_INFO("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",
  4789. __func__, rsvdpageloc->LocProbePacket,
  4790. rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);
  4791. SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);
  4792. SET_H2CCMD_AOAC_NLO_IPS_EN(u1H2CScanOffloadInfoParm, enable);
  4793. SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm,
  4794. rsvdpageloc->LocScanInfo);
  4795. SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm,
  4796. rsvdpageloc->LocProbePacket);
  4797. /*
  4798. SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm,
  4799. rsvdpageloc->LocSSIDInfo);
  4800. */
  4801. ret = rtw_hal_fill_h2c_cmd(adapter,
  4802. H2C_D0_SCAN_OFFLOAD_INFO,
  4803. H2C_SCAN_OFFLOAD_CTRL_LEN,
  4804. u1H2CScanOffloadInfoParm);
  4805. return ret;
  4806. }
  4807. #endif /* CONFIG_PNO_SUPPORT */
  4808. void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable)
  4809. {
  4810. struct security_priv *psecpriv = &padapter->securitypriv;
  4811. struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
  4812. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  4813. struct registry_priv *pregistry = &padapter->registrypriv;
  4814. struct sta_info *psta = NULL;
  4815. u16 media_status_rpt;
  4816. u8 pkt_type = 0;
  4817. u8 ret = _SUCCESS;
  4818. RTW_PRINT("+%s()+: enable=%d\n", __func__, enable);
  4819. rtw_hal_set_wowlan_ctrl_cmd(padapter, enable, _FALSE);
  4820. if (enable) {
  4821. rtw_hal_set_global_info_cmd(padapter,
  4822. psecpriv->dot118021XGrpPrivacy,
  4823. psecpriv->dot11PrivacyAlgrthm);
  4824. if (!(ppwrpriv->wowlan_pno_enable)) {
  4825. if (pregistry->wakeup_event & BIT(2))
  4826. rtw_hal_set_disconnect_decision_cmd(padapter,
  4827. enable);
  4828. #ifdef CONFIG_ARP_KEEP_ALIVE
  4829. if ((psecpriv->dot11PrivacyAlgrthm == _WEP40_) ||
  4830. (psecpriv->dot11PrivacyAlgrthm == _WEP104_))
  4831. pkt_type = 0;
  4832. else
  4833. pkt_type = 1;
  4834. #else
  4835. pkt_type = 0;
  4836. #endif /* CONFIG_ARP_KEEP_ALIVE */
  4837. rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type);
  4838. }
  4839. rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
  4840. #ifdef CONFIG_PNO_SUPPORT
  4841. rtw_hal_check_pno_enabled(padapter);
  4842. #endif /* CONFIG_PNO_SUPPORT */
  4843. } else {
  4844. #if 0
  4845. {
  4846. u32 PageSize = 0;
  4847. rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
  4848. dump_TX_FIFO(padapter, 4, PageSize);
  4849. }
  4850. #endif
  4851. rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
  4852. }
  4853. RTW_PRINT("-%s()-\n", __func__);
  4854. }
  4855. #endif /* CONFIG_WOWLAN */
  4856. #ifdef CONFIG_AP_WOWLAN
  4857. static u8 rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter *adapter, u8 enable)
  4858. {
  4859. struct security_priv *psecpriv = &adapter->securitypriv;
  4860. struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
  4861. struct hal_ops *pHalFunc = &adapter->hal_func;
  4862. u8 u1H2CAPWoWlanCtrlParm[H2C_AP_WOW_GPIO_CTRL_LEN] = {0};
  4863. u8 gpionum = 0, gpio_dur = 0;
  4864. u8 gpio_pulse = enable;
  4865. u8 sdio_wakeup_enable = 1;
  4866. u8 gpio_high_active = 0;
  4867. u8 ret = _FAIL;
  4868. #ifdef CONFIG_GPIO_WAKEUP
  4869. gpio_high_active = ppwrpriv->is_high_active;
  4870. gpionum = WAKEUP_GPIO_IDX;
  4871. sdio_wakeup_enable = 0;
  4872. #endif /*CONFIG_GPIO_WAKEUP*/
  4873. RTW_INFO("%s(): enable=%d\n", __func__, enable);
  4874. SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm,
  4875. gpionum);
  4876. SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm,
  4877. gpio_pulse);
  4878. SET_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm,
  4879. gpio_high_active);
  4880. SET_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm,
  4881. enable);
  4882. SET_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm,
  4883. gpio_dur);
  4884. ret = rtw_hal_fill_h2c_cmd(adapter,
  4885. H2C_AP_WOW_GPIO_CTRL,
  4886. H2C_AP_WOW_GPIO_CTRL_LEN,
  4887. u1H2CAPWoWlanCtrlParm);
  4888. return ret;
  4889. }
  4890. static u8 rtw_hal_set_ap_offload_ctrl_cmd(_adapter *adapter, u8 enable)
  4891. {
  4892. struct hal_ops *pHalFunc = &adapter->hal_func;
  4893. u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN] = {0};
  4894. u8 ret = _FAIL;
  4895. RTW_INFO("%s(): bFuncEn=%d\n", __func__, enable);
  4896. SET_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, enable);
  4897. ret = rtw_hal_fill_h2c_cmd(adapter,
  4898. H2C_AP_OFFLOAD,
  4899. H2C_AP_OFFLOAD_LEN,
  4900. u1H2CAPOffloadCtrlParm);
  4901. return ret;
  4902. }
  4903. static u8 rtw_hal_set_ap_ps_cmd(_adapter *adapter, u8 enable)
  4904. {
  4905. struct hal_ops *pHalFunc = &adapter->hal_func;
  4906. u8 ap_ps_parm[H2C_AP_PS_LEN] = {0};
  4907. u8 ret = _FAIL;
  4908. RTW_INFO("%s(): enable=%d\n" , __func__ , enable);
  4909. SET_H2CCMD_AP_WOW_PS_EN(ap_ps_parm, enable);
  4910. #ifndef CONFIG_USB_HCI
  4911. SET_H2CCMD_AP_WOW_PS_32K_EN(ap_ps_parm, enable);
  4912. #endif /*CONFIG_USB_HCI*/
  4913. SET_H2CCMD_AP_WOW_PS_RF(ap_ps_parm, enable);
  4914. if (enable)
  4915. SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x32);
  4916. else
  4917. SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x0);
  4918. ret = rtw_hal_fill_h2c_cmd(adapter, H2C_SAP_PS_,
  4919. H2C_AP_PS_LEN, ap_ps_parm);
  4920. return ret;
  4921. }
  4922. static void rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,
  4923. PRSVDPAGE_LOC rsvdpageloc)
  4924. {
  4925. struct hal_ops *pHalFunc = &padapter->hal_func;
  4926. u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
  4927. u8 ret = _FAIL, header = 0;
  4928. if (pHalFunc->fill_h2c_cmd == NULL) {
  4929. RTW_INFO("%s: Please hook fill_h2c_cmd first!\n", __func__);
  4930. return;
  4931. }
  4932. header = rtw_read8(padapter, REG_BCNQ_BDNY);
  4933. RTW_INFO("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,
  4934. rsvdpageloc->LocApOffloadBCN,
  4935. rsvdpageloc->LocProbeRsp,
  4936. header);
  4937. SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,
  4938. rsvdpageloc->LocApOffloadBCN + header);
  4939. ret = rtw_hal_fill_h2c_cmd(padapter, H2C_BCN_RSVDPAGE,
  4940. H2C_BCN_RSVDPAGE_LEN, rsvdparm);
  4941. if (ret == _FAIL)
  4942. RTW_INFO("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__);
  4943. rtw_msleep_os(10);
  4944. _rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));
  4945. SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm,
  4946. rsvdpageloc->LocProbeRsp + header);
  4947. ret = rtw_hal_fill_h2c_cmd(padapter, H2C_PROBERSP_RSVDPAGE,
  4948. H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);
  4949. if (ret == _FAIL)
  4950. RTW_INFO("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__);
  4951. rtw_msleep_os(10);
  4952. }
  4953. static void rtw_hal_set_fw_ap_wow_related_cmd(_adapter *padapter, u8 enable)
  4954. {
  4955. rtw_hal_set_ap_offload_ctrl_cmd(padapter, enable);
  4956. rtw_hal_set_ap_wowlan_ctrl_cmd(padapter, enable);
  4957. rtw_hal_set_ap_ps_cmd(padapter, enable);
  4958. }
  4959. static void rtw_hal_ap_wow_enable(_adapter *padapter)
  4960. {
  4961. struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
  4962. struct security_priv *psecuritypriv = &padapter->securitypriv;
  4963. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  4964. struct hal_ops *pHalFunc = &padapter->hal_func;
  4965. struct sta_info *psta = NULL;
  4966. PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
  4967. #ifdef DBG_CHECK_FW_PS_STATE
  4968. struct dvobj_priv *psdpriv = padapter->dvobj;
  4969. struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
  4970. #endif /*DBG_CHECK_FW_PS_STATE*/
  4971. int res;
  4972. u16 media_status_rpt;
  4973. RTW_INFO("%s, WOWLAN_AP_ENABLE\n", __func__);
  4974. #ifdef DBG_CHECK_FW_PS_STATE
  4975. if (rtw_fw_ps_state(padapter) == _FAIL) {
  4976. pdbgpriv->dbg_enwow_dload_fw_fail_cnt++;
  4977. RTW_PRINT("wowlan enable no leave 32k\n");
  4978. }
  4979. #endif /*DBG_CHECK_FW_PS_STATE*/
  4980. /* 1. Download WOWLAN FW*/
  4981. rtw_hal_fw_dl(padapter, _TRUE);
  4982. media_status_rpt = RT_MEDIA_CONNECT;
  4983. rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
  4984. (u8 *)&media_status_rpt);
  4985. issue_beacon(padapter, 0);
  4986. rtw_msleep_os(2);
  4987. #if defined(CONFIG_RTL8188E)
  4988. if (IS_HARDWARE_TYPE_8188E(padapter))
  4989. rtw_hal_disable_tx_report(padapter);
  4990. #endif
  4991. /* RX DMA stop */
  4992. res = rtw_hal_pause_rx_dma(padapter);
  4993. if (res == _FAIL)
  4994. RTW_PRINT("[WARNING] pause RX DMA fail\n");
  4995. #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
  4996. /* Enable CPWM2 only. */
  4997. res = rtw_hal_enable_cpwm2(padapter);
  4998. if (res == _FAIL)
  4999. RTW_PRINT("[WARNING] enable cpwm2 fail\n");
  5000. #endif
  5001. #ifdef CONFIG_GPIO_WAKEUP
  5002. rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _TRUE);
  5003. #endif
  5004. /* 5. Set Enable WOWLAN H2C command. */
  5005. RTW_PRINT("Set Enable AP WOWLan cmd\n");
  5006. rtw_hal_set_fw_ap_wow_related_cmd(padapter, 1);
  5007. rtw_write8(padapter, REG_MCUTST_WOWLAN, 0);
  5008. #ifdef CONFIG_USB_HCI
  5009. rtw_mi_intf_stop(padapter);
  5010. #endif
  5011. #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
  5012. /* Invoid SE0 reset signal during suspending*/
  5013. rtw_write8(padapter, REG_RSV_CTRL, 0x20);
  5014. if (IS_8188F(pHalData->version_id) == FALSE
  5015. && IS_8188GTV(pHalData->version_id) == FALSE)
  5016. rtw_write8(padapter, REG_RSV_CTRL, 0x60);
  5017. #endif
  5018. }
  5019. static void rtw_hal_ap_wow_disable(_adapter *padapter)
  5020. {
  5021. struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
  5022. struct hal_ops *pHalFunc = &padapter->hal_func;
  5023. #ifdef DBG_CHECK_FW_PS_STATE
  5024. struct dvobj_priv *psdpriv = padapter->dvobj;
  5025. struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
  5026. #endif /*DBG_CHECK_FW_PS_STATE*/
  5027. u16 media_status_rpt;
  5028. u8 val8;
  5029. RTW_INFO("%s, WOWLAN_AP_DISABLE\n", __func__);
  5030. /* 1. Read wakeup reason*/
  5031. pwrctl->wowlan_wake_reason = rtw_read8(padapter, REG_MCUTST_WOWLAN);
  5032. RTW_PRINT("wakeup_reason: 0x%02x\n",
  5033. pwrctl->wowlan_wake_reason);
  5034. rtw_hal_set_fw_ap_wow_related_cmd(padapter, 0);
  5035. rtw_msleep_os(2);
  5036. #ifdef DBG_CHECK_FW_PS_STATE
  5037. if (rtw_fw_ps_state(padapter) == _FAIL) {
  5038. pdbgpriv->dbg_diswow_dload_fw_fail_cnt++;
  5039. RTW_PRINT("wowlan enable no leave 32k\n");
  5040. }
  5041. #endif /*DBG_CHECK_FW_PS_STATE*/
  5042. #if defined(CONFIG_RTL8188E)
  5043. if (IS_HARDWARE_TYPE_8188E(padapter))
  5044. rtw_hal_enable_tx_report(padapter);
  5045. #endif
  5046. rtw_hal_force_enable_rxdma(padapter);
  5047. rtw_hal_fw_dl(padapter, _FALSE);
  5048. #ifdef CONFIG_GPIO_WAKEUP
  5049. #ifdef CONFIG_RTW_ONE_PIN_GPIO
  5050. rtw_hal_set_input_gpio(padapter, WAKEUP_GPIO_IDX);
  5051. #else
  5052. #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
  5053. if (pwrctl->is_high_active == 0)
  5054. rtw_hal_set_input_gpio(padapter, WAKEUP_GPIO_IDX);
  5055. else
  5056. rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, 0);
  5057. #else
  5058. val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
  5059. RTW_PRINT("Set Wake GPIO to default(%d).\n", val8);
  5060. rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, val8);
  5061. rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _FALSE);
  5062. #endif/*CONFIG_WAKEUP_GPIO_INPUT_MODE*/
  5063. #endif /* CONFIG_RTW_ONE_PIN_GPIO */
  5064. #endif
  5065. media_status_rpt = RT_MEDIA_CONNECT;
  5066. rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
  5067. (u8 *)&media_status_rpt);
  5068. issue_beacon(padapter, 0);
  5069. }
  5070. #endif /*CONFIG_AP_WOWLAN*/
  5071. #ifdef CONFIG_P2P_WOWLAN
  5072. static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
  5073. {
  5074. u8 *ssid_ie;
  5075. sint ssid_len_ori;
  5076. int len_diff = 0;
  5077. ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
  5078. /* RTW_INFO("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
  5079. if (ssid_ie && ssid_len_ori > 0) {
  5080. switch (hidden_ssid_mode) {
  5081. case 1: {
  5082. u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
  5083. u32 remain_len = 0;
  5084. remain_len = ies_len - (next_ie - ies);
  5085. ssid_ie[1] = 0;
  5086. _rtw_memcpy(ssid_ie + 2, next_ie, remain_len);
  5087. len_diff -= ssid_len_ori;
  5088. break;
  5089. }
  5090. case 2:
  5091. _rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
  5092. break;
  5093. default:
  5094. break;
  5095. }
  5096. }
  5097. return len_diff;
  5098. }
  5099. static void rtw_hal_construct_P2PBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
  5100. {
  5101. /* struct xmit_frame *pmgntframe; */
  5102. /* struct pkt_attrib *pattrib; */
  5103. /* unsigned char *pframe; */
  5104. struct rtw_ieee80211_hdr *pwlanhdr;
  5105. unsigned short *fctrl;
  5106. unsigned int rate_len;
  5107. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  5108. u32 pktlen;
  5109. /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
  5110. /* _irqL irqL;
  5111. * struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  5112. * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
  5113. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  5114. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  5115. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  5116. WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
  5117. u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  5118. #ifdef CONFIG_P2P
  5119. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  5120. #endif /* CONFIG_P2P */
  5121. /* for debug */
  5122. u8 *dbgbuf = pframe;
  5123. u8 dbgbufLen = 0, index = 0;
  5124. RTW_INFO("%s\n", __FUNCTION__);
  5125. /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
  5126. /* _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
  5127. * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
  5128. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  5129. fctrl = &(pwlanhdr->frame_ctl);
  5130. *(fctrl) = 0;
  5131. _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
  5132. _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
  5133. _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
  5134. SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
  5135. /* pmlmeext->mgnt_seq++; */
  5136. set_frame_sub_type(pframe, WIFI_BEACON);
  5137. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  5138. pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  5139. if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
  5140. /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
  5141. #ifdef CONFIG_P2P
  5142. /* for P2P : Primary Device Type & Device Name */
  5143. u32 wpsielen = 0, insert_len = 0;
  5144. u8 *wpsie = NULL;
  5145. wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
  5146. if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
  5147. uint wps_offset, remainder_ielen;
  5148. u8 *premainder_ie, *pframe_wscie;
  5149. wps_offset = (uint)(wpsie - cur_network->IEs);
  5150. premainder_ie = wpsie + wpsielen;
  5151. remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
  5152. #ifdef CONFIG_IOCTL_CFG80211
  5153. if (pwdinfo->driver_interface == DRIVER_CFG80211) {
  5154. if (pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len > 0) {
  5155. _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
  5156. pframe += wps_offset;
  5157. pktlen += wps_offset;
  5158. _rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
  5159. pframe += pmlmepriv->wps_beacon_ie_len;
  5160. pktlen += pmlmepriv->wps_beacon_ie_len;
  5161. /* copy remainder_ie to pframe */
  5162. _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
  5163. pframe += remainder_ielen;
  5164. pktlen += remainder_ielen;
  5165. } else {
  5166. _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
  5167. pframe += cur_network->IELength;
  5168. pktlen += cur_network->IELength;
  5169. }
  5170. } else
  5171. #endif /* CONFIG_IOCTL_CFG80211 */
  5172. {
  5173. pframe_wscie = pframe + wps_offset;
  5174. _rtw_memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
  5175. pframe += (wps_offset + wpsielen);
  5176. pktlen += (wps_offset + wpsielen);
  5177. /* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
  5178. /* Primary Device Type */
  5179. /* Type: */
  5180. *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
  5181. insert_len += 2;
  5182. /* Length: */
  5183. *(u16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
  5184. insert_len += 2;
  5185. /* Value: */
  5186. /* Category ID */
  5187. *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
  5188. insert_len += 2;
  5189. /* OUI */
  5190. *(u32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
  5191. insert_len += 4;
  5192. /* Sub Category ID */
  5193. *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
  5194. insert_len += 2;
  5195. /* Device Name */
  5196. /* Type: */
  5197. *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
  5198. insert_len += 2;
  5199. /* Length: */
  5200. *(u16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
  5201. insert_len += 2;
  5202. /* Value: */
  5203. _rtw_memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
  5204. insert_len += pwdinfo->device_name_len;
  5205. /* update wsc ie length */
  5206. *(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
  5207. /* pframe move to end */
  5208. pframe += insert_len;
  5209. pktlen += insert_len;
  5210. /* copy remainder_ie to pframe */
  5211. _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
  5212. pframe += remainder_ielen;
  5213. pktlen += remainder_ielen;
  5214. }
  5215. } else
  5216. #endif /* CONFIG_P2P */
  5217. {
  5218. int len_diff;
  5219. _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
  5220. len_diff = update_hidden_ssid(
  5221. pframe + _BEACON_IE_OFFSET_
  5222. , cur_network->IELength - _BEACON_IE_OFFSET_
  5223. , pmlmeinfo->hidden_ssid_mode
  5224. );
  5225. pframe += (cur_network->IELength + len_diff);
  5226. pktlen += (cur_network->IELength + len_diff);
  5227. }
  5228. #if 0
  5229. {
  5230. u8 *wps_ie;
  5231. uint wps_ielen;
  5232. u8 sr = 0;
  5233. wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
  5234. pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
  5235. if (wps_ie && wps_ielen > 0)
  5236. rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
  5237. if (sr != 0)
  5238. set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
  5239. else
  5240. _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
  5241. }
  5242. #endif
  5243. #ifdef CONFIG_P2P
  5244. if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
  5245. u32 len;
  5246. #ifdef CONFIG_IOCTL_CFG80211
  5247. if (pwdinfo->driver_interface == DRIVER_CFG80211) {
  5248. len = pmlmepriv->p2p_beacon_ie_len;
  5249. if (pmlmepriv->p2p_beacon_ie && len > 0)
  5250. _rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
  5251. } else
  5252. #endif /* CONFIG_IOCTL_CFG80211 */
  5253. {
  5254. len = build_beacon_p2p_ie(pwdinfo, pframe);
  5255. }
  5256. pframe += len;
  5257. pktlen += len;
  5258. #ifdef CONFIG_WFD
  5259. len = rtw_append_beacon_wfd_ie(padapter, pframe);
  5260. pframe += len;
  5261. pktlen += len;
  5262. #endif
  5263. }
  5264. #endif /* CONFIG_P2P */
  5265. goto _issue_bcn;
  5266. }
  5267. /* below for ad-hoc mode */
  5268. /* timestamp will be inserted by hardware */
  5269. pframe += 8;
  5270. pktlen += 8;
  5271. /* beacon interval: 2 bytes */
  5272. _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
  5273. pframe += 2;
  5274. pktlen += 2;
  5275. /* capability info: 2 bytes */
  5276. _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
  5277. pframe += 2;
  5278. pktlen += 2;
  5279. /* SSID */
  5280. pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
  5281. /* supported rates... */
  5282. rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
  5283. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
  5284. /* DS parameter set */
  5285. pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
  5286. /* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
  5287. {
  5288. u8 erpinfo = 0;
  5289. u32 ATIMWindow;
  5290. /* IBSS Parameter Set... */
  5291. /* ATIMWindow = cur->Configuration.ATIMWindow; */
  5292. ATIMWindow = 0;
  5293. pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
  5294. /* ERP IE */
  5295. pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pktlen);
  5296. }
  5297. /* EXTERNDED SUPPORTED RATE */
  5298. if (rate_len > 8)
  5299. pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
  5300. /* todo:HT for adhoc */
  5301. _issue_bcn:
  5302. /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
  5303. /* pmlmepriv->update_bcn = _FALSE;
  5304. *
  5305. * _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
  5306. * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
  5307. *pLength = pktlen;
  5308. #if 0
  5309. /* printf dbg msg */
  5310. dbgbufLen = pktlen;
  5311. RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P BEACON\n");
  5312. for (index = 0; index < dbgbufLen; index++)
  5313. printk("%x ", *(dbgbuf + index));
  5314. printk("\n");
  5315. RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P BEACON\n");
  5316. #endif
  5317. }
  5318. static void rtw_hal_construct_P2PProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
  5319. {
  5320. /* struct xmit_frame *pmgntframe; */
  5321. /* struct pkt_attrib *pattrib; */
  5322. /* unsigned char *pframe; */
  5323. struct rtw_ieee80211_hdr *pwlanhdr;
  5324. unsigned short *fctrl;
  5325. unsigned char *mac;
  5326. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  5327. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  5328. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  5329. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  5330. /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
  5331. u16 beacon_interval = 100;
  5332. u16 capInfo = 0;
  5333. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  5334. u8 wpsie[255] = { 0x00 };
  5335. u32 wpsielen = 0, p2pielen = 0;
  5336. u32 pktlen;
  5337. #ifdef CONFIG_WFD
  5338. u32 wfdielen = 0;
  5339. #endif
  5340. #ifdef CONFIG_INTEL_WIDI
  5341. u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
  5342. #endif /* CONFIG_INTEL_WIDI */
  5343. /* for debug */
  5344. u8 *dbgbuf = pframe;
  5345. u8 dbgbufLen = 0, index = 0;
  5346. RTW_INFO("%s\n", __FUNCTION__);
  5347. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  5348. mac = adapter_mac_addr(padapter);
  5349. fctrl = &(pwlanhdr->frame_ctl);
  5350. *(fctrl) = 0;
  5351. /* DA filled by FW */
  5352. _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
  5353. _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
  5354. /* Use the device address for BSSID field. */
  5355. _rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
  5356. SetSeqNum(pwlanhdr, 0);
  5357. set_frame_sub_type(fctrl, WIFI_PROBERSP);
  5358. pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  5359. pframe += pktlen;
  5360. /* timestamp will be inserted by hardware */
  5361. pframe += 8;
  5362. pktlen += 8;
  5363. /* beacon interval: 2 bytes */
  5364. _rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
  5365. pframe += 2;
  5366. pktlen += 2;
  5367. /* capability info: 2 bytes */
  5368. /* ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
  5369. capInfo |= cap_ShortPremble;
  5370. capInfo |= cap_ShortSlot;
  5371. _rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
  5372. pframe += 2;
  5373. pktlen += 2;
  5374. /* SSID */
  5375. pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pktlen);
  5376. /* supported rates... */
  5377. /* Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
  5378. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pktlen);
  5379. /* DS parameter set */
  5380. pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pktlen);
  5381. #ifdef CONFIG_IOCTL_CFG80211
  5382. if (pwdinfo->driver_interface == DRIVER_CFG80211) {
  5383. if (pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL) {
  5384. /* WPS IE */
  5385. _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
  5386. pktlen += pmlmepriv->wps_probe_resp_ie_len;
  5387. pframe += pmlmepriv->wps_probe_resp_ie_len;
  5388. /* P2P IE */
  5389. _rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
  5390. pktlen += pmlmepriv->p2p_probe_resp_ie_len;
  5391. pframe += pmlmepriv->p2p_probe_resp_ie_len;
  5392. }
  5393. } else
  5394. #endif /* CONFIG_IOCTL_CFG80211 */
  5395. {
  5396. /* Todo: WPS IE */
  5397. /* Noted by Albert 20100907 */
  5398. /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
  5399. wpsielen = 0;
  5400. /* WPS OUI */
  5401. *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
  5402. wpsielen += 4;
  5403. /* WPS version */
  5404. /* Type: */
  5405. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
  5406. wpsielen += 2;
  5407. /* Length: */
  5408. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
  5409. wpsielen += 2;
  5410. /* Value: */
  5411. wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
  5412. #ifdef CONFIG_INTEL_WIDI
  5413. /* Commented by Kurt */
  5414. /* Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext. */
  5415. if (_rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE
  5416. || pmlmepriv->num_p2p_sdt != 0) {
  5417. /* Sec dev type */
  5418. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SEC_DEV_TYPE_LIST);
  5419. wpsielen += 2;
  5420. /* Length: */
  5421. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
  5422. wpsielen += 2;
  5423. /* Value: */
  5424. /* Category ID */
  5425. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_DISPLAYS);
  5426. wpsielen += 2;
  5427. /* OUI */
  5428. *(u32 *)(wpsie + wpsielen) = cpu_to_be32(INTEL_DEV_TYPE_OUI);
  5429. wpsielen += 4;
  5430. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_WIDI_CONSUMER_SINK);
  5431. wpsielen += 2;
  5432. if (_rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE) {
  5433. /* Vendor Extension */
  5434. _rtw_memcpy(wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN);
  5435. wpsielen += L2SDTA_SERVICE_VE_LEN;
  5436. }
  5437. }
  5438. #endif /* CONFIG_INTEL_WIDI */
  5439. /* WiFi Simple Config State */
  5440. /* Type: */
  5441. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
  5442. wpsielen += 2;
  5443. /* Length: */
  5444. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
  5445. wpsielen += 2;
  5446. /* Value: */
  5447. wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; /* Not Configured. */
  5448. /* Response Type */
  5449. /* Type: */
  5450. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
  5451. wpsielen += 2;
  5452. /* Length: */
  5453. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
  5454. wpsielen += 2;
  5455. /* Value: */
  5456. wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
  5457. /* UUID-E */
  5458. /* Type: */
  5459. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
  5460. wpsielen += 2;
  5461. /* Length: */
  5462. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
  5463. wpsielen += 2;
  5464. /* Value: */
  5465. if (pwdinfo->external_uuid == 0) {
  5466. _rtw_memset(wpsie + wpsielen, 0x0, 16);
  5467. _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
  5468. } else
  5469. _rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
  5470. wpsielen += 0x10;
  5471. /* Manufacturer */
  5472. /* Type: */
  5473. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
  5474. wpsielen += 2;
  5475. /* Length: */
  5476. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
  5477. wpsielen += 2;
  5478. /* Value: */
  5479. _rtw_memcpy(wpsie + wpsielen, "Realtek", 7);
  5480. wpsielen += 7;
  5481. /* Model Name */
  5482. /* Type: */
  5483. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
  5484. wpsielen += 2;
  5485. /* Length: */
  5486. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
  5487. wpsielen += 2;
  5488. /* Value: */
  5489. _rtw_memcpy(wpsie + wpsielen, "8192CU", 6);
  5490. wpsielen += 6;
  5491. /* Model Number */
  5492. /* Type: */
  5493. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
  5494. wpsielen += 2;
  5495. /* Length: */
  5496. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
  5497. wpsielen += 2;
  5498. /* Value: */
  5499. wpsie[wpsielen++] = 0x31; /* character 1 */
  5500. /* Serial Number */
  5501. /* Type: */
  5502. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
  5503. wpsielen += 2;
  5504. /* Length: */
  5505. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
  5506. wpsielen += 2;
  5507. /* Value: */
  5508. _rtw_memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);
  5509. wpsielen += ETH_ALEN;
  5510. /* Primary Device Type */
  5511. /* Type: */
  5512. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
  5513. wpsielen += 2;
  5514. /* Length: */
  5515. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
  5516. wpsielen += 2;
  5517. /* Value: */
  5518. /* Category ID */
  5519. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
  5520. wpsielen += 2;
  5521. /* OUI */
  5522. *(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
  5523. wpsielen += 4;
  5524. /* Sub Category ID */
  5525. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
  5526. wpsielen += 2;
  5527. /* Device Name */
  5528. /* Type: */
  5529. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
  5530. wpsielen += 2;
  5531. /* Length: */
  5532. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
  5533. wpsielen += 2;
  5534. /* Value: */
  5535. _rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
  5536. wpsielen += pwdinfo->device_name_len;
  5537. /* Config Method */
  5538. /* Type: */
  5539. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
  5540. wpsielen += 2;
  5541. /* Length: */
  5542. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
  5543. wpsielen += 2;
  5544. /* Value: */
  5545. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
  5546. wpsielen += 2;
  5547. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
  5548. p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
  5549. pframe += p2pielen;
  5550. pktlen += p2pielen;
  5551. }
  5552. #ifdef CONFIG_WFD
  5553. wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
  5554. pframe += wfdielen;
  5555. pktlen += wfdielen;
  5556. #endif
  5557. *pLength = pktlen;
  5558. #if 0
  5559. /* printf dbg msg */
  5560. dbgbufLen = pktlen;
  5561. RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
  5562. for (index = 0; index < dbgbufLen; index++)
  5563. printk("%x ", *(dbgbuf + index));
  5564. printk("\n");
  5565. RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
  5566. #endif
  5567. }
  5568. static void rtw_hal_construct_P2PNegoRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
  5569. {
  5570. struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
  5571. unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
  5572. u8 action = P2P_PUB_ACTION_ACTION;
  5573. u32 p2poui = cpu_to_be32(P2POUI);
  5574. u8 oui_subtype = P2P_GO_NEGO_RESP;
  5575. u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
  5576. u8 p2pielen = 0, i;
  5577. uint wpsielen = 0;
  5578. u16 wps_devicepassword_id = 0x0000;
  5579. uint wps_devicepassword_id_len = 0;
  5580. u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
  5581. u16 len_channellist_attr = 0;
  5582. u32 pktlen;
  5583. u8 dialogToken = 0;
  5584. /* struct xmit_frame *pmgntframe; */
  5585. /* struct pkt_attrib *pattrib; */
  5586. /* unsigned char *pframe; */
  5587. struct rtw_ieee80211_hdr *pwlanhdr;
  5588. unsigned short *fctrl;
  5589. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  5590. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  5591. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  5592. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  5593. /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
  5594. #ifdef CONFIG_WFD
  5595. u32 wfdielen = 0;
  5596. #endif
  5597. /* for debug */
  5598. u8 *dbgbuf = pframe;
  5599. u8 dbgbufLen = 0, index = 0;
  5600. RTW_INFO("%s\n", __FUNCTION__);
  5601. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  5602. fctrl = &(pwlanhdr->frame_ctl);
  5603. *(fctrl) = 0;
  5604. /* RA, filled by FW */
  5605. _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
  5606. _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
  5607. _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
  5608. SetSeqNum(pwlanhdr, 0);
  5609. set_frame_sub_type(pframe, WIFI_ACTION);
  5610. pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  5611. pframe += pktlen;
  5612. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
  5613. pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
  5614. pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
  5615. pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
  5616. /* dialog token, filled by FW */
  5617. pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
  5618. _rtw_memset(wpsie, 0x00, 255);
  5619. wpsielen = 0;
  5620. /* WPS Section */
  5621. wpsielen = 0;
  5622. /* WPS OUI */
  5623. *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
  5624. wpsielen += 4;
  5625. /* WPS version */
  5626. /* Type: */
  5627. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
  5628. wpsielen += 2;
  5629. /* Length: */
  5630. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
  5631. wpsielen += 2;
  5632. /* Value: */
  5633. wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
  5634. /* Device Password ID */
  5635. /* Type: */
  5636. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
  5637. wpsielen += 2;
  5638. /* Length: */
  5639. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
  5640. wpsielen += 2;
  5641. /* Value: */
  5642. if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
  5643. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
  5644. else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
  5645. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
  5646. else
  5647. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
  5648. wpsielen += 2;
  5649. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
  5650. /* P2P IE Section. */
  5651. /* P2P OUI */
  5652. p2pielen = 0;
  5653. p2pie[p2pielen++] = 0x50;
  5654. p2pie[p2pielen++] = 0x6F;
  5655. p2pie[p2pielen++] = 0x9A;
  5656. p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
  5657. /* Commented by Albert 20100908 */
  5658. /* According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
  5659. /* 1. Status */
  5660. /* 2. P2P Capability */
  5661. /* 3. Group Owner Intent */
  5662. /* 4. Configuration Timeout */
  5663. /* 5. Operating Channel */
  5664. /* 6. Intended P2P Interface Address */
  5665. /* 7. Channel List */
  5666. /* 8. Device Info */
  5667. /* 9. Group ID ( Only GO ) */
  5668. /* ToDo: */
  5669. /* P2P Status */
  5670. /* Type: */
  5671. p2pie[p2pielen++] = P2P_ATTR_STATUS;
  5672. /* Length: */
  5673. *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
  5674. p2pielen += 2;
  5675. /* Value, filled by FW */
  5676. p2pie[p2pielen++] = 1;
  5677. /* P2P Capability */
  5678. /* Type: */
  5679. p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
  5680. /* Length: */
  5681. *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
  5682. p2pielen += 2;
  5683. /* Value: */
  5684. /* Device Capability Bitmap, 1 byte */
  5685. if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
  5686. /* Commented by Albert 2011/03/08 */
  5687. /* According to the P2P specification */
  5688. /* if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
  5689. p2pie[p2pielen++] = 0;
  5690. } else {
  5691. /* Be group owner or meet the error case */
  5692. p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
  5693. }
  5694. /* Group Capability Bitmap, 1 byte */
  5695. if (pwdinfo->persistent_supported)
  5696. p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
  5697. else
  5698. p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
  5699. /* Group Owner Intent */
  5700. /* Type: */
  5701. p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
  5702. /* Length: */
  5703. *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
  5704. p2pielen += 2;
  5705. /* Value: */
  5706. if (pwdinfo->peer_intent & 0x01) {
  5707. /* Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
  5708. p2pie[p2pielen++] = (pwdinfo->intent << 1);
  5709. } else {
  5710. /* Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
  5711. p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
  5712. }
  5713. /* Configuration Timeout */
  5714. /* Type: */
  5715. p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
  5716. /* Length: */
  5717. *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
  5718. p2pielen += 2;
  5719. /* Value: */
  5720. p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
  5721. p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
  5722. /* Operating Channel */
  5723. /* Type: */
  5724. p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
  5725. /* Length: */
  5726. *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
  5727. p2pielen += 2;
  5728. /* Value: */
  5729. /* Country String */
  5730. p2pie[p2pielen++] = 'X';
  5731. p2pie[p2pielen++] = 'X';
  5732. /* The third byte should be set to 0x04. */
  5733. /* Described in the "Operating Channel Attribute" section. */
  5734. p2pie[p2pielen++] = 0x04;
  5735. /* Operating Class */
  5736. if (pwdinfo->operating_channel <= 14) {
  5737. /* Operating Class */
  5738. p2pie[p2pielen++] = 0x51;
  5739. } else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
  5740. /* Operating Class */
  5741. p2pie[p2pielen++] = 0x73;
  5742. } else {
  5743. /* Operating Class */
  5744. p2pie[p2pielen++] = 0x7c;
  5745. }
  5746. /* Channel Number */
  5747. p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
  5748. /* Intended P2P Interface Address */
  5749. /* Type: */
  5750. p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
  5751. /* Length: */
  5752. *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
  5753. p2pielen += 2;
  5754. /* Value: */
  5755. _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
  5756. p2pielen += ETH_ALEN;
  5757. /* Channel List */
  5758. /* Type: */
  5759. p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
  5760. /* Country String(3) */
  5761. /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
  5762. /* + number of channels in all classes */
  5763. len_channellist_attr = 3
  5764. + (1 + 1) * (u16)ch_list->reg_classes
  5765. + get_reg_classes_full_count(ch_list);
  5766. #ifdef CONFIG_CONCURRENT_MODE
  5767. if (rtw_mi_buddy_check_fwstate(padapter, _FW_LINKED))
  5768. *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
  5769. else
  5770. *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
  5771. #else
  5772. *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
  5773. #endif
  5774. p2pielen += 2;
  5775. /* Value: */
  5776. /* Country String */
  5777. p2pie[p2pielen++] = 'X';
  5778. p2pie[p2pielen++] = 'X';
  5779. /* The third byte should be set to 0x04. */
  5780. /* Described in the "Operating Channel Attribute" section. */
  5781. p2pie[p2pielen++] = 0x04;
  5782. /* Channel Entry List */
  5783. #ifdef CONFIG_CONCURRENT_MODE
  5784. if (rtw_mi_check_status(padapter, MI_LINKED)) {
  5785. u8 union_ch = rtw_mi_get_union_chan(padapter);
  5786. /* Operating Class */
  5787. if (union_ch > 14) {
  5788. if (union_ch >= 149)
  5789. p2pie[p2pielen++] = 0x7c;
  5790. else
  5791. p2pie[p2pielen++] = 0x73;
  5792. } else
  5793. p2pie[p2pielen++] = 0x51;
  5794. /* Number of Channels */
  5795. /* Just support 1 channel and this channel is AP's channel */
  5796. p2pie[p2pielen++] = 1;
  5797. /* Channel List */
  5798. p2pie[p2pielen++] = union_ch;
  5799. } else
  5800. #endif /* CONFIG_CONCURRENT_MODE */
  5801. {
  5802. int i, j;
  5803. for (j = 0; j < ch_list->reg_classes; j++) {
  5804. /* Operating Class */
  5805. p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
  5806. /* Number of Channels */
  5807. p2pie[p2pielen++] = ch_list->reg_class[j].channels;
  5808. /* Channel List */
  5809. for (i = 0; i < ch_list->reg_class[j].channels; i++)
  5810. p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
  5811. }
  5812. }
  5813. /* Device Info */
  5814. /* Type: */
  5815. p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
  5816. /* Length: */
  5817. /* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
  5818. /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
  5819. *(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
  5820. p2pielen += 2;
  5821. /* Value: */
  5822. /* P2P Device Address */
  5823. _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
  5824. p2pielen += ETH_ALEN;
  5825. /* Config Method */
  5826. /* This field should be big endian. Noted by P2P specification. */
  5827. *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
  5828. p2pielen += 2;
  5829. /* Primary Device Type */
  5830. /* Category ID */
  5831. *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
  5832. p2pielen += 2;
  5833. /* OUI */
  5834. *(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
  5835. p2pielen += 4;
  5836. /* Sub Category ID */
  5837. *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
  5838. p2pielen += 2;
  5839. /* Number of Secondary Device Types */
  5840. p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
  5841. /* Device Name */
  5842. /* Type: */
  5843. *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
  5844. p2pielen += 2;
  5845. /* Length: */
  5846. *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
  5847. p2pielen += 2;
  5848. /* Value: */
  5849. _rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
  5850. p2pielen += pwdinfo->device_name_len;
  5851. if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
  5852. /* Group ID Attribute */
  5853. /* Type: */
  5854. p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
  5855. /* Length: */
  5856. *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
  5857. p2pielen += 2;
  5858. /* Value: */
  5859. /* p2P Device Address */
  5860. _rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
  5861. p2pielen += ETH_ALEN;
  5862. /* SSID */
  5863. _rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
  5864. p2pielen += pwdinfo->nego_ssidlen;
  5865. }
  5866. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
  5867. #ifdef CONFIG_WFD
  5868. wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
  5869. pframe += wfdielen;
  5870. pktlen += wfdielen;
  5871. #endif
  5872. *pLength = pktlen;
  5873. #if 0
  5874. /* printf dbg msg */
  5875. dbgbufLen = pktlen;
  5876. RTW_INFO("======> DBG MSG FOR CONSTRAUCT Nego Rsp\n");
  5877. for (index = 0; index < dbgbufLen; index++)
  5878. printk("%x ", *(dbgbuf + index));
  5879. printk("\n");
  5880. RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Nego Rsp\n");
  5881. #endif
  5882. }
  5883. static void rtw_hal_construct_P2PInviteRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
  5884. {
  5885. unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
  5886. u8 action = P2P_PUB_ACTION_ACTION;
  5887. u32 p2poui = cpu_to_be32(P2POUI);
  5888. u8 oui_subtype = P2P_INVIT_RESP;
  5889. u8 p2pie[255] = { 0x00 };
  5890. u8 p2pielen = 0, i;
  5891. u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
  5892. u16 len_channellist_attr = 0;
  5893. u32 pktlen;
  5894. u8 dialogToken = 0;
  5895. #ifdef CONFIG_WFD
  5896. u32 wfdielen = 0;
  5897. #endif
  5898. /* struct xmit_frame *pmgntframe; */
  5899. /* struct pkt_attrib *pattrib; */
  5900. /* unsigned char *pframe; */
  5901. struct rtw_ieee80211_hdr *pwlanhdr;
  5902. unsigned short *fctrl;
  5903. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  5904. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  5905. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  5906. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  5907. /* for debug */
  5908. u8 *dbgbuf = pframe;
  5909. u8 dbgbufLen = 0, index = 0;
  5910. RTW_INFO("%s\n", __FUNCTION__);
  5911. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  5912. fctrl = &(pwlanhdr->frame_ctl);
  5913. *(fctrl) = 0;
  5914. /* RA fill by FW */
  5915. _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
  5916. _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
  5917. /* BSSID fill by FW */
  5918. _rtw_memset(pwlanhdr->addr3, 0, ETH_ALEN);
  5919. SetSeqNum(pwlanhdr, 0);
  5920. set_frame_sub_type(pframe, WIFI_ACTION);
  5921. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  5922. pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  5923. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
  5924. pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
  5925. pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
  5926. pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
  5927. /* dialog token, filled by FW */
  5928. pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
  5929. /* P2P IE Section. */
  5930. /* P2P OUI */
  5931. p2pielen = 0;
  5932. p2pie[p2pielen++] = 0x50;
  5933. p2pie[p2pielen++] = 0x6F;
  5934. p2pie[p2pielen++] = 0x9A;
  5935. p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
  5936. /* Commented by Albert 20101005 */
  5937. /* According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
  5938. /* 1. Status */
  5939. /* 2. Configuration Timeout */
  5940. /* 3. Operating Channel ( Only GO ) */
  5941. /* 4. P2P Group BSSID ( Only GO ) */
  5942. /* 5. Channel List */
  5943. /* P2P Status */
  5944. /* Type: */
  5945. p2pie[p2pielen++] = P2P_ATTR_STATUS;
  5946. /* Length: */
  5947. *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
  5948. p2pielen += 2;
  5949. /* Value: filled by FW, defult value is FAIL INFO UNAVAILABLE */
  5950. p2pie[p2pielen++] = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
  5951. /* Configuration Timeout */
  5952. /* Type: */
  5953. p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
  5954. /* Length: */
  5955. *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
  5956. p2pielen += 2;
  5957. /* Value: */
  5958. p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
  5959. p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
  5960. /* due to defult value is FAIL INFO UNAVAILABLE, so the following IE is not needed */
  5961. #if 0
  5962. if (status_code == P2P_STATUS_SUCCESS) {
  5963. struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
  5964. if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
  5965. /* The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
  5966. /* In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
  5967. /* First one is operating channel attribute. */
  5968. /* Second one is P2P Group BSSID attribute. */
  5969. /* Operating Channel */
  5970. /* Type: */
  5971. p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
  5972. /* Length: */
  5973. *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
  5974. p2pielen += 2;
  5975. /* Value: */
  5976. /* Country String */
  5977. p2pie[p2pielen++] = 'X';
  5978. p2pie[p2pielen++] = 'X';
  5979. /* The third byte should be set to 0x04. */
  5980. /* Described in the "Operating Channel Attribute" section. */
  5981. p2pie[p2pielen++] = 0x04;
  5982. /* Operating Class */
  5983. p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
  5984. /* Channel Number */
  5985. p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
  5986. /* P2P Group BSSID */
  5987. /* Type: */
  5988. p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
  5989. /* Length: */
  5990. *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
  5991. p2pielen += 2;
  5992. /* Value: */
  5993. /* P2P Device Address for GO */
  5994. _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
  5995. p2pielen += ETH_ALEN;
  5996. }
  5997. /* Channel List */
  5998. /* Type: */
  5999. p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
  6000. /* Length: */
  6001. /* Country String(3) */
  6002. /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
  6003. /* + number of channels in all classes */
  6004. len_channellist_attr = 3
  6005. + (1 + 1) * (u16)ch_list->reg_classes
  6006. + get_reg_classes_full_count(ch_list);
  6007. #ifdef CONFIG_CONCURRENT_MODE
  6008. if (rtw_mi_check_status(padapter, MI_LINKED))
  6009. *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
  6010. else
  6011. *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
  6012. #else
  6013. *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
  6014. #endif
  6015. p2pielen += 2;
  6016. /* Value: */
  6017. /* Country String */
  6018. p2pie[p2pielen++] = 'X';
  6019. p2pie[p2pielen++] = 'X';
  6020. /* The third byte should be set to 0x04. */
  6021. /* Described in the "Operating Channel Attribute" section. */
  6022. p2pie[p2pielen++] = 0x04;
  6023. /* Channel Entry List */
  6024. #ifdef CONFIG_CONCURRENT_MODE
  6025. if (rtw_mi_check_status(padapter, MI_LINKED)) {
  6026. u8 union_ch = rtw_mi_get_union_chan(padapter);
  6027. /* Operating Class */
  6028. if (union_ch > 14) {
  6029. if (union_ch >= 149)
  6030. p2pie[p2pielen++] = 0x7c;
  6031. else
  6032. p2pie[p2pielen++] = 0x73;
  6033. } else
  6034. p2pie[p2pielen++] = 0x51;
  6035. /* Number of Channels */
  6036. /* Just support 1 channel and this channel is AP's channel */
  6037. p2pie[p2pielen++] = 1;
  6038. /* Channel List */
  6039. p2pie[p2pielen++] = union_ch;
  6040. } else
  6041. #endif /* CONFIG_CONCURRENT_MODE */
  6042. {
  6043. int i, j;
  6044. for (j = 0; j < ch_list->reg_classes; j++) {
  6045. /* Operating Class */
  6046. p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
  6047. /* Number of Channels */
  6048. p2pie[p2pielen++] = ch_list->reg_class[j].channels;
  6049. /* Channel List */
  6050. for (i = 0; i < ch_list->reg_class[j].channels; i++)
  6051. p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
  6052. }
  6053. }
  6054. }
  6055. #endif
  6056. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
  6057. #ifdef CONFIG_WFD
  6058. wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
  6059. pframe += wfdielen;
  6060. pktlen += wfdielen;
  6061. #endif
  6062. *pLength = pktlen;
  6063. #if 0
  6064. /* printf dbg msg */
  6065. dbgbufLen = pktlen;
  6066. RTW_INFO("======> DBG MSG FOR CONSTRAUCT Invite Rsp\n");
  6067. for (index = 0; index < dbgbufLen; index++)
  6068. printk("%x ", *(dbgbuf + index));
  6069. printk("\n");
  6070. RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Invite Rsp\n");
  6071. #endif
  6072. }
  6073. static void rtw_hal_construct_P2PProvisionDisRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
  6074. {
  6075. unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
  6076. u8 action = P2P_PUB_ACTION_ACTION;
  6077. u8 dialogToken = 0;
  6078. u32 p2poui = cpu_to_be32(P2POUI);
  6079. u8 oui_subtype = P2P_PROVISION_DISC_RESP;
  6080. u8 wpsie[100] = { 0x00 };
  6081. u8 wpsielen = 0;
  6082. u32 pktlen;
  6083. #ifdef CONFIG_WFD
  6084. u32 wfdielen = 0;
  6085. #endif
  6086. /* struct xmit_frame *pmgntframe; */
  6087. /* struct pkt_attrib *pattrib; */
  6088. /* unsigned char *pframe; */
  6089. struct rtw_ieee80211_hdr *pwlanhdr;
  6090. unsigned short *fctrl;
  6091. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  6092. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6093. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6094. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  6095. /* for debug */
  6096. u8 *dbgbuf = pframe;
  6097. u8 dbgbufLen = 0, index = 0;
  6098. RTW_INFO("%s\n", __FUNCTION__);
  6099. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  6100. fctrl = &(pwlanhdr->frame_ctl);
  6101. *(fctrl) = 0;
  6102. /* RA filled by FW */
  6103. _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
  6104. _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
  6105. _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
  6106. SetSeqNum(pwlanhdr, 0);
  6107. set_frame_sub_type(pframe, WIFI_ACTION);
  6108. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  6109. pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  6110. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
  6111. pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
  6112. pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
  6113. pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
  6114. /* dialog token, filled by FW */
  6115. pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
  6116. wpsielen = 0;
  6117. /* WPS OUI */
  6118. /* *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI ); */
  6119. RTW_PUT_BE32(wpsie, WPSOUI);
  6120. wpsielen += 4;
  6121. #if 0
  6122. /* WPS version */
  6123. /* Type: */
  6124. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
  6125. wpsielen += 2;
  6126. /* Length: */
  6127. *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
  6128. wpsielen += 2;
  6129. /* Value: */
  6130. wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
  6131. #endif
  6132. /* Config Method */
  6133. /* Type: */
  6134. /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD ); */
  6135. RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
  6136. wpsielen += 2;
  6137. /* Length: */
  6138. /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 ); */
  6139. RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
  6140. wpsielen += 2;
  6141. /* Value: filled by FW, default value is PBC */
  6142. /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method ); */
  6143. RTW_PUT_BE16(wpsie + wpsielen, WPS_CM_PUSH_BUTTON);
  6144. wpsielen += 2;
  6145. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
  6146. #ifdef CONFIG_WFD
  6147. wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);
  6148. pframe += wfdielen;
  6149. pktlen += wfdielen;
  6150. #endif
  6151. *pLength = pktlen;
  6152. /* printf dbg msg */
  6153. #if 0
  6154. dbgbufLen = pktlen;
  6155. RTW_INFO("======> DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
  6156. for (index = 0; index < dbgbufLen; index++)
  6157. printk("%x ", *(dbgbuf + index));
  6158. printk("\n");
  6159. RTW_INFO("<====== DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
  6160. #endif
  6161. }
  6162. u8 rtw_hal_set_FwP2PRsvdPage_cmd(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
  6163. {
  6164. u8 u1H2CP2PRsvdPageParm[H2C_P2PRSVDPAGE_LOC_LEN] = {0};
  6165. struct hal_ops *pHalFunc = &adapter->hal_func;
  6166. u8 ret = _FAIL;
  6167. RTW_INFO("P2PRsvdPageLoc: P2PBeacon=%d P2PProbeRsp=%d NegoRsp=%d InviteRsp=%d PDRsp=%d\n",
  6168. rsvdpageloc->LocP2PBeacon, rsvdpageloc->LocP2PProbeRsp,
  6169. rsvdpageloc->LocNegoRsp, rsvdpageloc->LocInviteRsp,
  6170. rsvdpageloc->LocPDRsp);
  6171. SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(u1H2CP2PRsvdPageParm, rsvdpageloc->LocProbeRsp);
  6172. SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocPsPoll);
  6173. SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocNullData);
  6174. SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocQosNull);
  6175. SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocBTQosNull);
  6176. /* FillH2CCmd8723B(padapter, H2C_8723B_P2P_OFFLOAD_RSVD_PAGE, H2C_P2PRSVDPAGE_LOC_LEN, u1H2CP2PRsvdPageParm); */
  6177. ret = rtw_hal_fill_h2c_cmd(adapter,
  6178. H2C_P2P_OFFLOAD_RSVD_PAGE,
  6179. H2C_P2PRSVDPAGE_LOC_LEN,
  6180. u1H2CP2PRsvdPageParm);
  6181. return ret;
  6182. }
  6183. u8 rtw_hal_set_p2p_wowlan_offload_cmd(_adapter *adapter)
  6184. {
  6185. u8 offload_cmd[H2C_P2P_OFFLOAD_LEN] = {0};
  6186. struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
  6187. struct P2P_WoWlan_Offload_t *p2p_wowlan_offload = (struct P2P_WoWlan_Offload_t *)offload_cmd;
  6188. struct hal_ops *pHalFunc = &adapter->hal_func;
  6189. u8 ret = _FAIL;
  6190. _rtw_memset(p2p_wowlan_offload, 0 , sizeof(struct P2P_WoWlan_Offload_t));
  6191. RTW_INFO("%s\n", __func__);
  6192. switch (pwdinfo->role) {
  6193. case P2P_ROLE_DEVICE:
  6194. RTW_INFO("P2P_ROLE_DEVICE\n");
  6195. p2p_wowlan_offload->role = 0;
  6196. break;
  6197. case P2P_ROLE_CLIENT:
  6198. RTW_INFO("P2P_ROLE_CLIENT\n");
  6199. p2p_wowlan_offload->role = 1;
  6200. break;
  6201. case P2P_ROLE_GO:
  6202. RTW_INFO("P2P_ROLE_GO\n");
  6203. p2p_wowlan_offload->role = 2;
  6204. break;
  6205. default:
  6206. RTW_INFO("P2P_ROLE_DISABLE\n");
  6207. break;
  6208. }
  6209. p2p_wowlan_offload->Wps_Config[0] = pwdinfo->supported_wps_cm >> 8;
  6210. p2p_wowlan_offload->Wps_Config[1] = pwdinfo->supported_wps_cm;
  6211. offload_cmd = (u8 *)p2p_wowlan_offload;
  6212. RTW_INFO("p2p_wowlan_offload: %x:%x:%x\n", offload_cmd[0], offload_cmd[1], offload_cmd[2]);
  6213. ret = rtw_hal_fill_h2c_cmd(adapter,
  6214. H2C_P2P_OFFLOAD,
  6215. H2C_P2P_OFFLOAD_LEN,
  6216. offload_cmd);
  6217. return ret;
  6218. /* FillH2CCmd8723B(adapter, H2C_8723B_P2P_OFFLOAD, sizeof(struct P2P_WoWlan_Offload_t), (u8 *)p2p_wowlan_offload); */
  6219. }
  6220. #endif /* CONFIG_P2P_WOWLAN */
  6221. void rtw_hal_construct_beacon(_adapter *padapter,
  6222. u8 *pframe, u32 *pLength)
  6223. {
  6224. struct rtw_ieee80211_hdr *pwlanhdr;
  6225. u16 *fctrl;
  6226. u32 rate_len, pktlen;
  6227. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6228. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6229. WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
  6230. u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  6231. /* RTW_INFO("%s\n", __FUNCTION__); */
  6232. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  6233. fctrl = &(pwlanhdr->frame_ctl);
  6234. *(fctrl) = 0;
  6235. _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
  6236. _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
  6237. _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
  6238. SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
  6239. /* pmlmeext->mgnt_seq++; */
  6240. set_frame_sub_type(pframe, WIFI_BEACON);
  6241. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  6242. pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  6243. /* timestamp will be inserted by hardware */
  6244. pframe += 8;
  6245. pktlen += 8;
  6246. /* beacon interval: 2 bytes */
  6247. _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
  6248. pframe += 2;
  6249. pktlen += 2;
  6250. #if 0
  6251. /* capability info: 2 bytes */
  6252. _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
  6253. pframe += 2;
  6254. pktlen += 2;
  6255. if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
  6256. /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
  6257. pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
  6258. _rtw_memcpy(pframe, cur_network->IEs + sizeof(NDIS_802_11_FIXED_IEs), pktlen);
  6259. goto _ConstructBeacon;
  6260. }
  6261. /* below for ad-hoc mode */
  6262. /* SSID */
  6263. pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
  6264. /* supported rates... */
  6265. rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
  6266. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
  6267. /* DS parameter set */
  6268. pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
  6269. if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
  6270. u32 ATIMWindow;
  6271. /* IBSS Parameter Set... */
  6272. /* ATIMWindow = cur->Configuration.ATIMWindow; */
  6273. ATIMWindow = 0;
  6274. pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
  6275. }
  6276. /* todo: ERP IE */
  6277. /* EXTERNDED SUPPORTED RATE */
  6278. if (rate_len > 8)
  6279. pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
  6280. /* todo:HT for adhoc */
  6281. #endif
  6282. _ConstructBeacon:
  6283. if ((pktlen + TXDESC_SIZE) > MAX_BEACON_LEN) {
  6284. RTW_ERR("beacon frame too large ,len(%d,%d)\n",
  6285. (pktlen + TXDESC_SIZE), MAX_BEACON_LEN);
  6286. rtw_warn_on(1);
  6287. return;
  6288. }
  6289. *pLength = pktlen;
  6290. /* RTW_INFO("%s bcn_sz=%d\n", __FUNCTION__, pktlen); */
  6291. }
  6292. static void rtw_hal_construct_PSPoll(_adapter *padapter,
  6293. u8 *pframe, u32 *pLength)
  6294. {
  6295. struct rtw_ieee80211_hdr *pwlanhdr;
  6296. u16 *fctrl;
  6297. u32 pktlen;
  6298. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6299. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6300. /* RTW_INFO("%s\n", __FUNCTION__); */
  6301. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  6302. /* Frame control. */
  6303. fctrl = &(pwlanhdr->frame_ctl);
  6304. *(fctrl) = 0;
  6305. SetPwrMgt(fctrl);
  6306. set_frame_sub_type(pframe, WIFI_PSPOLL);
  6307. /* AID. */
  6308. set_duration(pframe, (pmlmeinfo->aid | 0xc000));
  6309. /* BSSID. */
  6310. _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6311. /* TA. */
  6312. _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
  6313. *pLength = 16;
  6314. }
  6315. #ifdef DBG_FW_DEBUG_MSG_PKT
  6316. void rtw_hal_construct_fw_dbg_msg_pkt(
  6317. PADAPTER padapter,
  6318. u8 *pframe,
  6319. u32 *plength)
  6320. {
  6321. struct rtw_ieee80211_hdr *pwlanhdr;
  6322. u16 *fctrl;
  6323. u32 pktlen;
  6324. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  6325. struct wlan_network *cur_network = &pmlmepriv->cur_network;
  6326. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6327. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6328. u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  6329. /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
  6330. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  6331. fctrl = &pwlanhdr->frame_ctl;
  6332. *(fctrl) = 0;
  6333. _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
  6334. _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
  6335. _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6336. SetSeqNum(pwlanhdr, 0);
  6337. set_frame_sub_type(pframe, WIFI_DATA);
  6338. pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  6339. *plength = pktlen;
  6340. }
  6341. #endif /*DBG_FW_DEBUG_MSG_PKT*/
  6342. void rtw_hal_construct_NullFunctionData(
  6343. PADAPTER padapter,
  6344. u8 *pframe,
  6345. u32 *pLength,
  6346. u8 bQoS,
  6347. u8 AC,
  6348. u8 bEosp,
  6349. u8 bForcePowerSave)
  6350. {
  6351. struct rtw_ieee80211_hdr *pwlanhdr;
  6352. u16 *fctrl;
  6353. u32 pktlen;
  6354. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  6355. struct wlan_network *cur_network = &pmlmepriv->cur_network;
  6356. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6357. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6358. u8 *sta_addr = NULL;
  6359. u8 bssid[ETH_ALEN] = {0};
  6360. /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
  6361. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  6362. fctrl = &pwlanhdr->frame_ctl;
  6363. *(fctrl) = 0;
  6364. if (bForcePowerSave)
  6365. SetPwrMgt(fctrl);
  6366. sta_addr = get_my_bssid(&pmlmeinfo->network);
  6367. if (NULL == sta_addr) {
  6368. _rtw_memcpy(bssid, adapter_mac_addr(padapter), ETH_ALEN);
  6369. sta_addr = bssid;
  6370. }
  6371. switch (cur_network->network.InfrastructureMode) {
  6372. case Ndis802_11Infrastructure:
  6373. SetToDs(fctrl);
  6374. _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6375. _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
  6376. _rtw_memcpy(pwlanhdr->addr3, sta_addr, ETH_ALEN);
  6377. break;
  6378. case Ndis802_11APMode:
  6379. SetFrDs(fctrl);
  6380. _rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
  6381. _rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6382. _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
  6383. break;
  6384. case Ndis802_11IBSS:
  6385. default:
  6386. _rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
  6387. _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
  6388. _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6389. break;
  6390. }
  6391. SetSeqNum(pwlanhdr, 0);
  6392. set_duration(pwlanhdr, 0);
  6393. if (bQoS == _TRUE) {
  6394. struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
  6395. set_frame_sub_type(pframe, WIFI_QOS_DATA_NULL);
  6396. pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos *)pframe;
  6397. SetPriority(&pwlanqoshdr->qc, AC);
  6398. SetEOSP(&pwlanqoshdr->qc, bEosp);
  6399. pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
  6400. } else {
  6401. set_frame_sub_type(pframe, WIFI_DATA_NULL);
  6402. pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  6403. }
  6404. *pLength = pktlen;
  6405. }
  6406. void rtw_hal_construct_ProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength,
  6407. BOOLEAN bHideSSID)
  6408. {
  6409. struct rtw_ieee80211_hdr *pwlanhdr;
  6410. u16 *fctrl;
  6411. u8 *mac, *bssid, *sta_addr;
  6412. u32 pktlen;
  6413. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6414. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6415. WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
  6416. /*RTW_INFO("%s\n", __FUNCTION__);*/
  6417. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  6418. mac = adapter_mac_addr(padapter);
  6419. bssid = cur_network->MacAddress;
  6420. sta_addr = get_my_bssid(&pmlmeinfo->network);
  6421. fctrl = &(pwlanhdr->frame_ctl);
  6422. *(fctrl) = 0;
  6423. _rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
  6424. _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
  6425. _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
  6426. SetSeqNum(pwlanhdr, 0);
  6427. set_frame_sub_type(fctrl, WIFI_PROBERSP);
  6428. pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  6429. pframe += pktlen;
  6430. if (cur_network->IELength > MAX_IE_SZ)
  6431. return;
  6432. _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
  6433. pframe += cur_network->IELength;
  6434. pktlen += cur_network->IELength;
  6435. *pLength = pktlen;
  6436. }
  6437. #ifdef CONFIG_WOWLAN
  6438. static void rtw_hal_append_tkip_mic(PADAPTER padapter,
  6439. u8 *pframe, u32 offset)
  6440. {
  6441. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6442. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6443. struct rtw_ieee80211_hdr *pwlanhdr;
  6444. struct mic_data micdata;
  6445. struct sta_info *psta = NULL;
  6446. int res = 0;
  6447. u8 *payload = (u8 *)(pframe + offset);
  6448. u8 mic[8];
  6449. u8 priority[4] = {0x0};
  6450. u8 null_key[16] = {0x0};
  6451. RTW_INFO("%s(): Add MIC, offset: %d\n", __func__, offset);
  6452. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  6453. psta = rtw_get_stainfo(&padapter->stapriv,
  6454. get_my_bssid(&(pmlmeinfo->network)));
  6455. if (psta != NULL) {
  6456. res = _rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],
  6457. null_key, 16);
  6458. if (res == _TRUE)
  6459. RTW_INFO("%s(): STA dot11tkiptxmickey==0\n", __func__);
  6460. rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]);
  6461. }
  6462. rtw_secmicappend(&micdata, pwlanhdr->addr3, 6); /* DA */
  6463. rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); /* SA */
  6464. priority[0] = 0;
  6465. rtw_secmicappend(&micdata, &priority[0], 4);
  6466. rtw_secmicappend(&micdata, payload, 36); /* payload length = 8 + 28 */
  6467. rtw_secgetmic(&micdata, &(mic[0]));
  6468. payload += 36;
  6469. _rtw_memcpy(payload, &(mic[0]), 8);
  6470. }
  6471. /*
  6472. * Description:
  6473. * Construct the ARP response packet to support ARP offload.
  6474. * */
  6475. static void rtw_hal_construct_ARPRsp(
  6476. PADAPTER padapter,
  6477. u8 *pframe,
  6478. u32 *pLength,
  6479. u8 *pIPAddress
  6480. )
  6481. {
  6482. struct rtw_ieee80211_hdr *pwlanhdr;
  6483. u16 *fctrl;
  6484. u32 pktlen;
  6485. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  6486. struct wlan_network *cur_network = &pmlmepriv->cur_network;
  6487. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6488. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6489. struct security_priv *psecuritypriv = &padapter->securitypriv;
  6490. static u8 ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};
  6491. u8 *pARPRspPkt = pframe;
  6492. /* for TKIP Cal MIC */
  6493. u8 *payload = pframe;
  6494. u8 EncryptionHeadOverhead = 0, arp_offset = 0;
  6495. /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
  6496. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  6497. fctrl = &pwlanhdr->frame_ctl;
  6498. *(fctrl) = 0;
  6499. /* ------------------------------------------------------------------------- */
  6500. /* MAC Header. */
  6501. /* ------------------------------------------------------------------------- */
  6502. SetFrameType(fctrl, WIFI_DATA);
  6503. /* set_frame_sub_type(fctrl, 0); */
  6504. SetToDs(fctrl);
  6505. _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6506. _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
  6507. _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6508. SetSeqNum(pwlanhdr, 0);
  6509. set_duration(pwlanhdr, 0);
  6510. /* SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0); */
  6511. /* SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data); */
  6512. /* SET_80211_HDR_TO_DS(pARPRspPkt, 1); */
  6513. /* SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid); */
  6514. /* SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress); */
  6515. /* SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid); */
  6516. /* SET_80211_HDR_DURATION(pARPRspPkt, 0); */
  6517. /* SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0); */
  6518. #ifdef CONFIG_WAPI_SUPPORT
  6519. *pLength = sMacHdrLng;
  6520. #else
  6521. *pLength = 24;
  6522. #endif
  6523. switch (psecuritypriv->dot11PrivacyAlgrthm) {
  6524. case _WEP40_:
  6525. case _WEP104_:
  6526. EncryptionHeadOverhead = 4;
  6527. break;
  6528. case _TKIP_:
  6529. EncryptionHeadOverhead = 8;
  6530. break;
  6531. case _AES_:
  6532. EncryptionHeadOverhead = 8;
  6533. break;
  6534. #ifdef CONFIG_WAPI_SUPPORT
  6535. case _SMS4_:
  6536. EncryptionHeadOverhead = 18;
  6537. break;
  6538. #endif
  6539. default:
  6540. EncryptionHeadOverhead = 0;
  6541. }
  6542. if (EncryptionHeadOverhead > 0) {
  6543. _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
  6544. *pLength += EncryptionHeadOverhead;
  6545. /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
  6546. SetPrivacy(fctrl);
  6547. }
  6548. /* ------------------------------------------------------------------------- */
  6549. /* Frame Body. */
  6550. /* ------------------------------------------------------------------------- */
  6551. arp_offset = *pLength;
  6552. pARPRspPkt = (u8 *)(pframe + arp_offset);
  6553. payload = pARPRspPkt; /* Get Payload pointer */
  6554. /* LLC header */
  6555. _rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);
  6556. *pLength += 8;
  6557. /* ARP element */
  6558. pARPRspPkt += 8;
  6559. SET_ARP_HTYPE(pARPRspPkt, 1);
  6560. SET_ARP_PTYPE(pARPRspPkt, ETH_P_IP); /* IP protocol */
  6561. SET_ARP_HLEN(pARPRspPkt, ETH_ALEN);
  6562. SET_ARP_PLEN(pARPRspPkt, RTW_IP_ADDR_LEN);
  6563. SET_ARP_OPER(pARPRspPkt, 2); /* ARP response */
  6564. SET_ARP_SENDER_MAC_ADDR(pARPRspPkt, adapter_mac_addr(padapter));
  6565. SET_ARP_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
  6566. #ifdef CONFIG_ARP_KEEP_ALIVE
  6567. if (!is_zero_mac_addr(pmlmepriv->gw_mac_addr)) {
  6568. SET_ARP_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
  6569. SET_ARP_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
  6570. } else
  6571. #endif
  6572. {
  6573. SET_ARP_TARGET_MAC_ADDR(pARPRspPkt,
  6574. get_my_bssid(&(pmlmeinfo->network)));
  6575. SET_ARP_TARGET_IP_ADDR(pARPRspPkt,
  6576. pIPAddress);
  6577. RTW_INFO("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__,
  6578. MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
  6579. RTW_INFO("%s Target IP Addr" IP_FMT "\n", __FUNCTION__,
  6580. IP_ARG(pIPAddress));
  6581. }
  6582. *pLength += 28;
  6583. if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
  6584. if (IS_HARDWARE_TYPE_8188E(padapter) ||
  6585. IS_HARDWARE_TYPE_8812(padapter)) {
  6586. rtw_hal_append_tkip_mic(padapter, pframe, arp_offset);
  6587. }
  6588. *pLength += 8;
  6589. }
  6590. }
  6591. #ifdef CONFIG_IPV6
  6592. /*
  6593. * Description: Neighbor Discovery Offload.
  6594. */
  6595. static void rtw_hal_construct_na_message(_adapter *padapter,
  6596. u8 *pframe, u32 *pLength)
  6597. {
  6598. struct rtw_ieee80211_hdr *pwlanhdr = NULL;
  6599. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  6600. struct wlan_network *cur_network = &pmlmepriv->cur_network;
  6601. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  6602. struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
  6603. struct security_priv *psecuritypriv = &padapter->securitypriv;
  6604. u32 pktlen = 0;
  6605. u16 *fctrl = NULL;
  6606. u8 ns_hdr[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD};
  6607. u8 ipv6_info[4] = {0x60, 0x00, 0x00, 0x00};
  6608. u8 ipv6_contx[4] = {0x00, 0x20, 0x3a, 0xff};
  6609. u8 icmpv6_hdr[8] = {0x88, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00};
  6610. u8 val8 = 0;
  6611. u8 *p_na_msg = pframe;
  6612. /* for TKIP Cal MIC */
  6613. u8 *payload = pframe;
  6614. u8 EncryptionHeadOverhead = 0, na_msg_offset = 0;
  6615. /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
  6616. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  6617. fctrl = &pwlanhdr->frame_ctl;
  6618. *(fctrl) = 0;
  6619. /* ------------------------------------------------------------------------- */
  6620. /* MAC Header. */
  6621. /* ------------------------------------------------------------------------- */
  6622. SetFrameType(fctrl, WIFI_DATA);
  6623. SetToDs(fctrl);
  6624. _rtw_memcpy(pwlanhdr->addr1,
  6625. get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6626. _rtw_memcpy(pwlanhdr->addr2,
  6627. adapter_mac_addr(padapter), ETH_ALEN);
  6628. _rtw_memcpy(pwlanhdr->addr3,
  6629. get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6630. SetSeqNum(pwlanhdr, 0);
  6631. set_duration(pwlanhdr, 0);
  6632. #ifdef CONFIG_WAPI_SUPPORT
  6633. *pLength = sMacHdrLng;
  6634. #else
  6635. *pLength = 24;
  6636. #endif
  6637. switch (psecuritypriv->dot11PrivacyAlgrthm) {
  6638. case _WEP40_:
  6639. case _WEP104_:
  6640. EncryptionHeadOverhead = 4;
  6641. break;
  6642. case _TKIP_:
  6643. EncryptionHeadOverhead = 8;
  6644. break;
  6645. case _AES_:
  6646. EncryptionHeadOverhead = 8;
  6647. break;
  6648. #ifdef CONFIG_WAPI_SUPPORT
  6649. case _SMS4_:
  6650. EncryptionHeadOverhead = 18;
  6651. break;
  6652. #endif
  6653. default:
  6654. EncryptionHeadOverhead = 0;
  6655. }
  6656. if (EncryptionHeadOverhead > 0) {
  6657. _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
  6658. *pLength += EncryptionHeadOverhead;
  6659. /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
  6660. SetPrivacy(fctrl);
  6661. }
  6662. /* ------------------------------------------------------------------------- */
  6663. /* Frame Body. */
  6664. /* ------------------------------------------------------------------------- */
  6665. na_msg_offset = *pLength;
  6666. p_na_msg = (u8 *)(pframe + na_msg_offset);
  6667. payload = p_na_msg; /* Get Payload pointer */
  6668. /* LLC header */
  6669. val8 = sizeof(ns_hdr);
  6670. _rtw_memcpy(p_na_msg, ns_hdr, val8);
  6671. *pLength += val8;
  6672. p_na_msg += val8;
  6673. /* IPv6 Header */
  6674. /* 1 . Information (4 bytes): 0x60 0x00 0x00 0x00 */
  6675. val8 = sizeof(ipv6_info);
  6676. _rtw_memcpy(p_na_msg, ipv6_info, val8);
  6677. *pLength += val8;
  6678. p_na_msg += val8;
  6679. /* 2 . playload : 0x00 0x20 , NextProt : 0x3a (ICMPv6) HopLim : 0xff */
  6680. val8 = sizeof(ipv6_contx);
  6681. _rtw_memcpy(p_na_msg, ipv6_contx, val8);
  6682. *pLength += val8;
  6683. p_na_msg += val8;
  6684. /* 3 . SA : 16 bytes , DA : 16 bytes ( Fw will filled ) */
  6685. _rtw_memset(&(p_na_msg[*pLength]), 0, 32);
  6686. *pLength += 32;
  6687. p_na_msg += 32;
  6688. /* ICMPv6 */
  6689. /* 1. Type : 0x88 (NA)
  6690. * 2. Code : 0x00
  6691. * 3. ChechSum : 0x00 0x00 (RSvd)
  6692. * 4. NAFlag: 0x60 0x00 0x00 0x00 ( Solicited , Override)
  6693. */
  6694. val8 = sizeof(icmpv6_hdr);
  6695. _rtw_memcpy(p_na_msg, icmpv6_hdr, val8);
  6696. *pLength += val8;
  6697. p_na_msg += val8;
  6698. /* TA: 16 bytes*/
  6699. _rtw_memset(&(p_na_msg[*pLength]), 0, 16);
  6700. *pLength += 16;
  6701. p_na_msg += 16;
  6702. /* ICMPv6 Target Link Layer Address */
  6703. p_na_msg[0] = 0x02; /* type */
  6704. p_na_msg[1] = 0x01; /* len 1 unit of 8 octes */
  6705. *pLength += 2;
  6706. p_na_msg += 2;
  6707. _rtw_memset(&(p_na_msg[*pLength]), 0, 6);
  6708. *pLength += 6;
  6709. p_na_msg += 6;
  6710. if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
  6711. if (IS_HARDWARE_TYPE_8188E(padapter) ||
  6712. IS_HARDWARE_TYPE_8812(padapter)) {
  6713. rtw_hal_append_tkip_mic(padapter, pframe,
  6714. na_msg_offset);
  6715. }
  6716. *pLength += 8;
  6717. }
  6718. }
  6719. /*
  6720. * Description: Neighbor Discovery Protocol Information.
  6721. */
  6722. static void rtw_hal_construct_ndp_info(_adapter *padapter,
  6723. u8 *pframe, u32 *pLength)
  6724. {
  6725. struct mlme_ext_priv *pmlmeext = NULL;
  6726. struct mlme_ext_info *pmlmeinfo = NULL;
  6727. struct rtw_ndp_info ndp_info;
  6728. u8 *pndp_info = pframe;
  6729. u8 len = sizeof(struct rtw_ndp_info);
  6730. RTW_INFO("%s: len: %d\n", __func__, len);
  6731. pmlmeext = &padapter->mlmeextpriv;
  6732. pmlmeinfo = &pmlmeext->mlmext_info;
  6733. _rtw_memset(pframe, 0, len);
  6734. _rtw_memset(&ndp_info, 0, len);
  6735. ndp_info.enable = 1;
  6736. ndp_info.check_remote_ip = 0;
  6737. ndp_info.num_of_target_ip = 1;
  6738. _rtw_memcpy(&ndp_info.target_link_addr, adapter_mac_addr(padapter),
  6739. ETH_ALEN);
  6740. _rtw_memcpy(&ndp_info.target_ipv6_addr, pmlmeinfo->ip6_addr,
  6741. RTW_IPv6_ADDR_LEN);
  6742. _rtw_memcpy(pndp_info, &ndp_info, len);
  6743. }
  6744. #endif /* CONFIG_IPV6 */
  6745. #ifdef CONFIG_PNO_SUPPORT
  6746. static void rtw_hal_construct_ProbeReq(_adapter *padapter, u8 *pframe,
  6747. u32 *pLength, pno_ssid_t *ssid)
  6748. {
  6749. struct rtw_ieee80211_hdr *pwlanhdr;
  6750. u16 *fctrl;
  6751. u32 pktlen;
  6752. unsigned char *mac;
  6753. unsigned char bssrate[NumRates];
  6754. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  6755. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  6756. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6757. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6758. int bssrate_len = 0;
  6759. u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  6760. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  6761. mac = adapter_mac_addr(padapter);
  6762. fctrl = &(pwlanhdr->frame_ctl);
  6763. *(fctrl) = 0;
  6764. _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
  6765. _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
  6766. _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
  6767. SetSeqNum(pwlanhdr, 0);
  6768. set_frame_sub_type(pframe, WIFI_PROBEREQ);
  6769. pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  6770. pframe += pktlen;
  6771. if (ssid == NULL)
  6772. pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);
  6773. else {
  6774. /* RTW_INFO("%s len:%d\n", ssid->SSID, ssid->SSID_len); */
  6775. pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen);
  6776. }
  6777. get_rate_set(padapter, bssrate, &bssrate_len);
  6778. if (bssrate_len > 8) {
  6779. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);
  6780. pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);
  6781. } else
  6782. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);
  6783. *pLength = pktlen;
  6784. }
  6785. static void rtw_hal_construct_PNO_info(_adapter *padapter,
  6786. u8 *pframe, u32 *pLength)
  6787. {
  6788. struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
  6789. int i;
  6790. u8 *pPnoInfoPkt = pframe;
  6791. pPnoInfoPkt = (u8 *)(pframe + *pLength);
  6792. _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1);
  6793. pPnoInfoPkt += 1;
  6794. _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1);
  6795. pPnoInfoPkt += 3;
  6796. _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1);
  6797. pPnoInfoPkt += 4;
  6798. _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);
  6799. pPnoInfoPkt += 4;
  6800. _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);
  6801. pPnoInfoPkt += 4;
  6802. _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length, MAX_PNO_LIST_COUNT);
  6803. pPnoInfoPkt += MAX_PNO_LIST_COUNT;
  6804. _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info, MAX_PNO_LIST_COUNT);
  6805. pPnoInfoPkt += MAX_PNO_LIST_COUNT;
  6806. _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info, MAX_PNO_LIST_COUNT);
  6807. pPnoInfoPkt += MAX_PNO_LIST_COUNT;
  6808. _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req, MAX_HIDDEN_AP);
  6809. pPnoInfoPkt += MAX_HIDDEN_AP;
  6810. /*
  6811. SSID is located at 128th Byte in NLO info Page
  6812. */
  6813. *pLength += 128;
  6814. pPnoInfoPkt = pframe + 128;
  6815. for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
  6816. _rtw_memcpy(pPnoInfoPkt, &pwrctl->pno_ssid_list->node[i].SSID,
  6817. pwrctl->pnlo_info->ssid_length[i]);
  6818. *pLength += WLAN_SSID_MAXLEN;
  6819. pPnoInfoPkt += WLAN_SSID_MAXLEN;
  6820. }
  6821. }
  6822. static void rtw_hal_construct_ssid_list(_adapter *padapter,
  6823. u8 *pframe, u32 *pLength)
  6824. {
  6825. struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
  6826. u8 *pSSIDListPkt = pframe;
  6827. int i;
  6828. pSSIDListPkt = (u8 *)(pframe + *pLength);
  6829. for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
  6830. _rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,
  6831. pwrctl->pnlo_info->ssid_length[i]);
  6832. *pLength += WLAN_SSID_MAXLEN;
  6833. pSSIDListPkt += WLAN_SSID_MAXLEN;
  6834. }
  6835. }
  6836. static void rtw_hal_construct_scan_info(_adapter *padapter,
  6837. u8 *pframe, u32 *pLength)
  6838. {
  6839. struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
  6840. u8 *pScanInfoPkt = pframe;
  6841. int i;
  6842. pScanInfoPkt = (u8 *)(pframe + *pLength);
  6843. _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);
  6844. *pLength += 1;
  6845. pScanInfoPkt += 1;
  6846. _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);
  6847. *pLength += 1;
  6848. pScanInfoPkt += 1;
  6849. _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);
  6850. *pLength += 1;
  6851. pScanInfoPkt += 1;
  6852. _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);
  6853. *pLength += 1;
  6854. pScanInfoPkt += 1;
  6855. _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);
  6856. *pLength += 1;
  6857. pScanInfoPkt += 1;
  6858. _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);
  6859. *pLength += 1;
  6860. pScanInfoPkt += 1;
  6861. _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);
  6862. *pLength += 1;
  6863. pScanInfoPkt += 1;
  6864. _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);
  6865. *pLength += 1;
  6866. pScanInfoPkt += 1;
  6867. _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);
  6868. *pLength += 8;
  6869. pScanInfoPkt += 8;
  6870. for (i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {
  6871. _rtw_memcpy(pScanInfoPkt,
  6872. &pwrctl->pscan_info->ssid_channel_info[i], 4);
  6873. *pLength += 4;
  6874. pScanInfoPkt += 4;
  6875. }
  6876. }
  6877. #endif /* CONFIG_PNO_SUPPORT */
  6878. #ifdef CONFIG_GTK_OL
  6879. static void rtw_hal_construct_GTKRsp(
  6880. PADAPTER padapter,
  6881. u8 *pframe,
  6882. u32 *pLength
  6883. )
  6884. {
  6885. struct rtw_ieee80211_hdr *pwlanhdr;
  6886. u16 *fctrl;
  6887. u32 pktlen;
  6888. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  6889. struct wlan_network *cur_network = &pmlmepriv->cur_network;
  6890. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6891. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6892. struct security_priv *psecuritypriv = &padapter->securitypriv;
  6893. static u8 LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};
  6894. static u8 GTKbody_a[11] = {0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};
  6895. u8 *pGTKRspPkt = pframe;
  6896. u8 EncryptionHeadOverhead = 0;
  6897. /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
  6898. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  6899. fctrl = &pwlanhdr->frame_ctl;
  6900. *(fctrl) = 0;
  6901. /* ------------------------------------------------------------------------- */
  6902. /* MAC Header. */
  6903. /* ------------------------------------------------------------------------- */
  6904. SetFrameType(fctrl, WIFI_DATA);
  6905. /* set_frame_sub_type(fctrl, 0); */
  6906. SetToDs(fctrl);
  6907. _rtw_memcpy(pwlanhdr->addr1,
  6908. get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6909. _rtw_memcpy(pwlanhdr->addr2,
  6910. adapter_mac_addr(padapter), ETH_ALEN);
  6911. _rtw_memcpy(pwlanhdr->addr3,
  6912. get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6913. SetSeqNum(pwlanhdr, 0);
  6914. set_duration(pwlanhdr, 0);
  6915. #ifdef CONFIG_WAPI_SUPPORT
  6916. *pLength = sMacHdrLng;
  6917. #else
  6918. *pLength = 24;
  6919. #endif /* CONFIG_WAPI_SUPPORT */
  6920. /* ------------------------------------------------------------------------- */
  6921. /* Security Header: leave space for it if necessary. */
  6922. /* ------------------------------------------------------------------------- */
  6923. switch (psecuritypriv->dot11PrivacyAlgrthm) {
  6924. case _WEP40_:
  6925. case _WEP104_:
  6926. EncryptionHeadOverhead = 4;
  6927. break;
  6928. case _TKIP_:
  6929. EncryptionHeadOverhead = 8;
  6930. break;
  6931. case _AES_:
  6932. EncryptionHeadOverhead = 8;
  6933. break;
  6934. #ifdef CONFIG_WAPI_SUPPORT
  6935. case _SMS4_:
  6936. EncryptionHeadOverhead = 18;
  6937. break;
  6938. #endif /* CONFIG_WAPI_SUPPORT */
  6939. default:
  6940. EncryptionHeadOverhead = 0;
  6941. }
  6942. if (EncryptionHeadOverhead > 0) {
  6943. _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
  6944. *pLength += EncryptionHeadOverhead;
  6945. /* SET_80211_HDR_WEP(pGTKRspPkt, 1); */ /* Suggested by CCW. */
  6946. /* GTK's privacy bit is done by FW */
  6947. /* SetPrivacy(fctrl); */
  6948. }
  6949. /* ------------------------------------------------------------------------- */
  6950. /* Frame Body. */
  6951. /* ------------------------------------------------------------------------- */
  6952. pGTKRspPkt = (u8 *)(pframe + *pLength);
  6953. /* LLC header */
  6954. _rtw_memcpy(pGTKRspPkt, LLCHeader, 8);
  6955. *pLength += 8;
  6956. /* GTK element */
  6957. pGTKRspPkt += 8;
  6958. /* GTK frame body after LLC, part 1 */
  6959. /* TKIP key_length = 32, AES key_length = 16 */
  6960. if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
  6961. GTKbody_a[8] = 0x20;
  6962. /* GTK frame body after LLC, part 1 */
  6963. _rtw_memcpy(pGTKRspPkt, GTKbody_a, 11);
  6964. *pLength += 11;
  6965. pGTKRspPkt += 11;
  6966. /* GTK frame body after LLC, part 2 */
  6967. _rtw_memset(&(pframe[*pLength]), 0, 88);
  6968. *pLength += 88;
  6969. pGTKRspPkt += 88;
  6970. if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
  6971. *pLength += 8;
  6972. }
  6973. #endif /* CONFIG_GTK_OL */
  6974. #define PN_2_CCMPH(ch,key_id) ((ch) & 0x000000000000ffff) \
  6975. | (((ch) & 0x0000ffffffff0000) << 16) \
  6976. | (((key_id) << 30)) \
  6977. | BIT(29)
  6978. static void rtw_hal_construct_remote_control_info(_adapter *adapter,
  6979. u8 *pframe, u32 *pLength)
  6980. {
  6981. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  6982. struct sta_priv *pstapriv = &adapter->stapriv;
  6983. struct security_priv *psecuritypriv = &adapter->securitypriv;
  6984. struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
  6985. struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
  6986. struct sta_info *psta;
  6987. struct stainfo_rxcache *prxcache;
  6988. u8 cur_dot11rxiv[8], id = 0, tid_id = 0, i = 0;
  6989. size_t sz = 0, total = 0;
  6990. u64 ccmp_hdr = 0, tmp_key = 0;
  6991. psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
  6992. if (psta == NULL) {
  6993. rtw_warn_on(1);
  6994. return;
  6995. }
  6996. prxcache = &psta->sta_recvpriv.rxcache;
  6997. sz = sizeof(cur_dot11rxiv);
  6998. /* 3 SEC IV * 1 page */
  6999. rtw_get_sec_iv(adapter, cur_dot11rxiv,
  7000. get_my_bssid(&pmlmeinfo->network));
  7001. _rtw_memcpy(pframe, cur_dot11rxiv, sz);
  7002. *pLength += sz;
  7003. pframe += sz;
  7004. _rtw_memset(&cur_dot11rxiv, 0, sz);
  7005. if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
  7006. id = psecuritypriv->dot118021XGrpKeyid;
  7007. tid_id = prxcache->last_tid;
  7008. REMOTE_INFO_CTRL_SET_VALD_EN(cur_dot11rxiv, 0xdd);
  7009. REMOTE_INFO_CTRL_SET_PTK_EN(cur_dot11rxiv, 1);
  7010. REMOTE_INFO_CTRL_SET_GTK_EN(cur_dot11rxiv, 1);
  7011. REMOTE_INFO_CTRL_SET_GTK_IDX(cur_dot11rxiv, id);
  7012. _rtw_memcpy(pframe, cur_dot11rxiv, sz);
  7013. *pLength += sz;
  7014. pframe += sz;
  7015. _rtw_memcpy(pframe, prxcache->iv[tid_id], sz);
  7016. *pLength += sz;
  7017. pframe += sz;
  7018. total = sizeof(psecuritypriv->iv_seq);
  7019. total /= sizeof(psecuritypriv->iv_seq[0]);
  7020. for (i = 0 ; i < total ; i ++) {
  7021. ccmp_hdr =
  7022. le64_to_cpu(*(u64*)psecuritypriv->iv_seq[i]);
  7023. _rtw_memset(&cur_dot11rxiv, 0, sz);
  7024. if (ccmp_hdr != 0) {
  7025. tmp_key = i;
  7026. ccmp_hdr = PN_2_CCMPH(ccmp_hdr, tmp_key);
  7027. *(u64*)cur_dot11rxiv = cpu_to_le64(ccmp_hdr);
  7028. _rtw_memcpy(pframe, cur_dot11rxiv, sz);
  7029. }
  7030. *pLength += sz;
  7031. pframe += sz;
  7032. }
  7033. }
  7034. }
  7035. /*#define DBG_RSVD_PAGE_CFG*/
  7036. #ifdef DBG_RSVD_PAGE_CFG
  7037. #define RSVD_PAGE_CFG(ops, v1, v2, v3) \
  7038. RTW_INFO("=== [RSVD][%s]-NeedPage:%d, TotalPageNum:%d TotalPacketLen:%d ===\n", \
  7039. ops, v1, v2, v3)
  7040. #endif
  7041. void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
  7042. u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
  7043. RSVDPAGE_LOC *rsvd_page_loc)
  7044. {
  7045. struct security_priv *psecuritypriv = &adapter->securitypriv;
  7046. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  7047. struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
  7048. struct mlme_ext_priv *pmlmeext;
  7049. struct mlme_ext_info *pmlmeinfo;
  7050. u32 ARPLength = 0, GTKLength = 0, PNOLength = 0, ScanInfoLength = 0;
  7051. u32 SSIDLegnth = 0, ProbeReqLength = 0, ns_len = 0, rc_len = 0;
  7052. u8 CurtPktPageNum = 0;
  7053. #ifdef CONFIG_GTK_OL
  7054. struct sta_priv *pstapriv = &adapter->stapriv;
  7055. struct sta_info *psta;
  7056. struct security_priv *psecpriv = &adapter->securitypriv;
  7057. u8 kek[RTW_KEK_LEN];
  7058. u8 kck[RTW_KCK_LEN];
  7059. #endif /* CONFIG_GTK_OL */
  7060. #ifdef CONFIG_PNO_SUPPORT
  7061. int pno_index;
  7062. u8 ssid_num;
  7063. #endif /* CONFIG_PNO_SUPPORT */
  7064. pmlmeext = &adapter->mlmeextpriv;
  7065. pmlmeinfo = &pmlmeext->mlmext_info;
  7066. if (pwrctl->wowlan_pno_enable == _FALSE) {
  7067. /* ARP RSP * 1 page */
  7068. rsvd_page_loc->LocArpRsp = *page_num;
  7069. RTW_INFO("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp);
  7070. rtw_hal_construct_ARPRsp(adapter, &pframe[index],
  7071. &ARPLength, pmlmeinfo->ip_addr);
  7072. rtw_hal_fill_fake_txdesc(adapter,
  7073. &pframe[index - tx_desc],
  7074. ARPLength, _FALSE, _FALSE, _TRUE);
  7075. CurtPktPageNum = (u8)PageNum(tx_desc + ARPLength, page_size);
  7076. *page_num += CurtPktPageNum;
  7077. index += (CurtPktPageNum * page_size);
  7078. #ifdef DBG_RSVD_PAGE_CFG
  7079. RSVD_PAGE_CFG("WOW-ARPRsp", CurtPktPageNum, *page_num, 0);
  7080. #endif
  7081. #ifdef CONFIG_IPV6
  7082. /* 2 NS offload and NDP Info*/
  7083. if (pwrctl->wowlan_ns_offload_en == _TRUE) {
  7084. rsvd_page_loc->LocNbrAdv = *page_num;
  7085. RTW_INFO("LocNbrAdv: %d\n", rsvd_page_loc->LocNbrAdv);
  7086. rtw_hal_construct_na_message(adapter,
  7087. &pframe[index], &ns_len);
  7088. rtw_hal_fill_fake_txdesc(adapter,
  7089. &pframe[index - tx_desc],
  7090. ns_len, _FALSE,
  7091. _FALSE, _TRUE);
  7092. CurtPktPageNum = (u8)PageNum(tx_desc + ns_len,
  7093. page_size);
  7094. *page_num += CurtPktPageNum;
  7095. index += (CurtPktPageNum * page_size);
  7096. #ifdef DBG_RSVD_PAGE_CFG
  7097. RSVD_PAGE_CFG("WOW-NbrAdv", CurtPktPageNum, *page_num, 0);
  7098. #endif
  7099. rsvd_page_loc->LocNDPInfo = *page_num;
  7100. RTW_INFO("LocNDPInfo: %d\n",
  7101. rsvd_page_loc->LocNDPInfo);
  7102. rtw_hal_construct_ndp_info(adapter,
  7103. &pframe[index - tx_desc],
  7104. &ns_len);
  7105. CurtPktPageNum =
  7106. (u8)PageNum(tx_desc + ns_len, page_size);
  7107. *page_num += CurtPktPageNum;
  7108. index += (CurtPktPageNum * page_size);
  7109. #ifdef DBG_RSVD_PAGE_CFG
  7110. RSVD_PAGE_CFG("WOW-NDPInfo", CurtPktPageNum, *page_num, 0);
  7111. #endif
  7112. }
  7113. #endif /*CONFIG_IPV6*/
  7114. /* 3 Remote Control Info. * 1 page */
  7115. rsvd_page_loc->LocRemoteCtrlInfo = *page_num;
  7116. RTW_INFO("LocRemoteCtrlInfo: %d\n", rsvd_page_loc->LocRemoteCtrlInfo);
  7117. rtw_hal_construct_remote_control_info(adapter,
  7118. &pframe[index - tx_desc],
  7119. &rc_len);
  7120. CurtPktPageNum = (u8)PageNum(rc_len, page_size);
  7121. *page_num += CurtPktPageNum;
  7122. *total_pkt_len = index + rc_len;
  7123. #ifdef DBG_RSVD_PAGE_CFG
  7124. RSVD_PAGE_CFG("WOW-RCI", CurtPktPageNum, *page_num, *total_pkt_len);
  7125. #endif
  7126. #ifdef CONFIG_GTK_OL
  7127. index += (CurtPktPageNum * page_size);
  7128. /* if the ap staion info. exists, get the kek, kck from staion info. */
  7129. psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
  7130. if (psta == NULL) {
  7131. _rtw_memset(kek, 0, RTW_KEK_LEN);
  7132. _rtw_memset(kck, 0, RTW_KCK_LEN);
  7133. RTW_INFO("%s, KEK, KCK download rsvd page all zero\n",
  7134. __func__);
  7135. } else {
  7136. _rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);
  7137. _rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);
  7138. }
  7139. /* 3 KEK, KCK */
  7140. rsvd_page_loc->LocGTKInfo = *page_num;
  7141. RTW_INFO("LocGTKInfo: %d\n", rsvd_page_loc->LocGTKInfo);
  7142. if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)) {
  7143. struct security_priv *psecpriv = NULL;
  7144. psecpriv = &adapter->securitypriv;
  7145. _rtw_memcpy(pframe + index - tx_desc,
  7146. &psecpriv->dot11PrivacyAlgrthm, 1);
  7147. _rtw_memcpy(pframe + index - tx_desc + 1,
  7148. &psecpriv->dot118021XGrpPrivacy, 1);
  7149. _rtw_memcpy(pframe + index - tx_desc + 2,
  7150. kck, RTW_KCK_LEN);
  7151. _rtw_memcpy(pframe + index - tx_desc + 2 + RTW_KCK_LEN,
  7152. kek, RTW_KEK_LEN);
  7153. CurtPktPageNum = (u8)PageNum(tx_desc + 2 + RTW_KCK_LEN + RTW_KEK_LEN, page_size);
  7154. } else {
  7155. _rtw_memcpy(pframe + index - tx_desc, kck, RTW_KCK_LEN);
  7156. _rtw_memcpy(pframe + index - tx_desc + RTW_KCK_LEN,
  7157. kek, RTW_KEK_LEN);
  7158. GTKLength = tx_desc + RTW_KCK_LEN + RTW_KEK_LEN;
  7159. if (psta != NULL &&
  7160. psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
  7161. _rtw_memcpy(pframe + index - tx_desc + 56,
  7162. &psta->dot11tkiptxmickey, RTW_TKIP_MIC_LEN);
  7163. GTKLength += RTW_TKIP_MIC_LEN;
  7164. }
  7165. CurtPktPageNum = (u8)PageNum(GTKLength, page_size);
  7166. }
  7167. #if 0
  7168. {
  7169. int i;
  7170. printk("\ntoFW KCK: ");
  7171. for (i = 0; i < 16; i++)
  7172. printk(" %02x ", kck[i]);
  7173. printk("\ntoFW KEK: ");
  7174. for (i = 0; i < 16; i++)
  7175. printk(" %02x ", kek[i]);
  7176. printk("\n");
  7177. }
  7178. RTW_INFO("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n",
  7179. __FUNCTION__, &pframe[index - tx_desc],
  7180. (tx_desc + RTW_KCK_LEN + RTW_KEK_LEN));
  7181. #endif
  7182. *page_num += CurtPktPageNum;
  7183. index += (CurtPktPageNum * page_size);
  7184. #ifdef DBG_RSVD_PAGE_CFG
  7185. RSVD_PAGE_CFG("WOW-GTKInfo", CurtPktPageNum, *page_num, 0);
  7186. #endif
  7187. /* 3 GTK Response */
  7188. rsvd_page_loc->LocGTKRsp = *page_num;
  7189. RTW_INFO("LocGTKRsp: %d\n", rsvd_page_loc->LocGTKRsp);
  7190. rtw_hal_construct_GTKRsp(adapter, &pframe[index], &GTKLength);
  7191. rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
  7192. GTKLength, _FALSE, _FALSE, _TRUE);
  7193. #if 0
  7194. {
  7195. int gj;
  7196. printk("123GTK pkt=>\n");
  7197. for (gj = 0; gj < GTKLength + tx_desc; gj++) {
  7198. printk(" %02x ", pframe[index - tx_desc + gj]);
  7199. if ((gj + 1) % 16 == 0)
  7200. printk("\n");
  7201. }
  7202. printk(" <=end\n");
  7203. }
  7204. RTW_INFO("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n",
  7205. __FUNCTION__, &pframe[index - tx_desc],
  7206. (tx_desc + GTKLength));
  7207. #endif
  7208. CurtPktPageNum = (u8)PageNum(tx_desc + GTKLength, page_size);
  7209. *page_num += CurtPktPageNum;
  7210. index += (CurtPktPageNum * page_size);
  7211. #ifdef DBG_RSVD_PAGE_CFG
  7212. RSVD_PAGE_CFG("WOW-GTKRsp", CurtPktPageNum, *page_num, 0);
  7213. #endif
  7214. /* below page is empty for GTK extension memory */
  7215. /* 3(11) GTK EXT MEM */
  7216. rsvd_page_loc->LocGTKEXTMEM = *page_num;
  7217. RTW_INFO("LocGTKEXTMEM: %d\n", rsvd_page_loc->LocGTKEXTMEM);
  7218. CurtPktPageNum = 2;
  7219. if (page_size >= 256)
  7220. CurtPktPageNum = 1;
  7221. *page_num += CurtPktPageNum;
  7222. /* extension memory for FW */
  7223. *total_pkt_len = index + (page_size * CurtPktPageNum);
  7224. #ifdef DBG_RSVD_PAGE_CFG
  7225. RSVD_PAGE_CFG("WOW-GTKEXTMEM", CurtPktPageNum, *page_num, *total_pkt_len);
  7226. #endif
  7227. #endif /* CONFIG_GTK_OL */
  7228. index += (CurtPktPageNum * page_size);
  7229. /*Reserve 1 page for AOAC report*/
  7230. rsvd_page_loc->LocAOACReport = *page_num;
  7231. RTW_INFO("LocAOACReport: %d\n", rsvd_page_loc->LocAOACReport);
  7232. *page_num += 1;
  7233. *total_pkt_len = index + (page_size * 1);
  7234. #ifdef DBG_RSVD_PAGE_CFG
  7235. RSVD_PAGE_CFG("WOW-AOAC", 1, *page_num, *total_pkt_len);
  7236. #endif
  7237. } else {
  7238. #ifdef CONFIG_PNO_SUPPORT
  7239. if (pwrctl->wowlan_in_resume == _FALSE &&
  7240. pwrctl->pno_inited == _TRUE) {
  7241. /* Broadcast Probe Request */
  7242. rsvd_page_loc->LocProbePacket = *page_num;
  7243. RTW_INFO("loc_probe_req: %d\n",
  7244. rsvd_page_loc->LocProbePacket);
  7245. rtw_hal_construct_ProbeReq(
  7246. adapter,
  7247. &pframe[index],
  7248. &ProbeReqLength,
  7249. NULL);
  7250. rtw_hal_fill_fake_txdesc(adapter,
  7251. &pframe[index - tx_desc],
  7252. ProbeReqLength, _FALSE, _FALSE, _FALSE);
  7253. CurtPktPageNum =
  7254. (u8)PageNum(tx_desc + ProbeReqLength, page_size);
  7255. *page_num += CurtPktPageNum;
  7256. index += (CurtPktPageNum * page_size);
  7257. #ifdef DBG_RSVD_PAGE_CFG
  7258. RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
  7259. #endif
  7260. /* Hidden SSID Probe Request */
  7261. ssid_num = pwrctl->pnlo_info->hidden_ssid_num;
  7262. for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) {
  7263. pwrctl->pnlo_info->loc_probe_req[pno_index] =
  7264. *page_num;
  7265. rtw_hal_construct_ProbeReq(
  7266. adapter,
  7267. &pframe[index],
  7268. &ProbeReqLength,
  7269. &pwrctl->pno_ssid_list->node[pno_index]);
  7270. rtw_hal_fill_fake_txdesc(adapter,
  7271. &pframe[index - tx_desc],
  7272. ProbeReqLength, _FALSE, _FALSE, _FALSE);
  7273. CurtPktPageNum =
  7274. (u8)PageNum(tx_desc + ProbeReqLength, page_size);
  7275. *page_num += CurtPktPageNum;
  7276. index += (CurtPktPageNum * page_size);
  7277. #ifdef DBG_RSVD_PAGE_CFG
  7278. RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
  7279. #endif
  7280. }
  7281. /* PNO INFO Page */
  7282. rsvd_page_loc->LocPNOInfo = *page_num;
  7283. RTW_INFO("LocPNOInfo: %d\n", rsvd_page_loc->LocPNOInfo);
  7284. rtw_hal_construct_PNO_info(adapter,
  7285. &pframe[index - tx_desc],
  7286. &PNOLength);
  7287. CurtPktPageNum = (u8)PageNum(PNOLength, page_size);
  7288. *page_num += CurtPktPageNum;
  7289. index += (CurtPktPageNum * page_size);
  7290. #ifdef DBG_RSVD_PAGE_CFG
  7291. RSVD_PAGE_CFG("WOW-PNOInfo", CurtPktPageNum, *page_num, 0);
  7292. #endif
  7293. /* Scan Info Page */
  7294. rsvd_page_loc->LocScanInfo = *page_num;
  7295. RTW_INFO("LocScanInfo: %d\n", rsvd_page_loc->LocScanInfo);
  7296. rtw_hal_construct_scan_info(adapter,
  7297. &pframe[index - tx_desc],
  7298. &ScanInfoLength);
  7299. CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size);
  7300. *page_num += CurtPktPageNum;
  7301. *total_pkt_len = index + ScanInfoLength;
  7302. index += (CurtPktPageNum * page_size);
  7303. #ifdef DBG_RSVD_PAGE_CFG
  7304. RSVD_PAGE_CFG("WOW-ScanInfo", CurtPktPageNum, *page_num, *total_pkt_len);
  7305. #endif
  7306. }
  7307. #endif /* CONFIG_PNO_SUPPORT */
  7308. }
  7309. }
  7310. static void rtw_hal_gate_bb(_adapter *adapter, bool stop)
  7311. {
  7312. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
  7313. u8 i = 0, val8 = 0, empty = _FAIL;
  7314. u16 val16 = 0;
  7315. if (stop) {
  7316. /* checking TX queue status */
  7317. for (i = 0 ; i < 5 ; i++) {
  7318. rtw_hal_get_hwreg(adapter, HW_VAR_CHK_MGQ_CPU_EMPTY, &empty);
  7319. if (empty) {
  7320. break;
  7321. } else {
  7322. RTW_WARN("%s: MGQ_CPU is busy(%d)!\n",
  7323. __func__, i);
  7324. rtw_mdelay_os(10);
  7325. }
  7326. }
  7327. if (val8 == 5)
  7328. RTW_ERR("%s: Polling MGQ_CPU empty fail!\n", __func__);
  7329. /* Pause TX*/
  7330. pwrpriv->wowlan_txpause_status = rtw_read8(adapter, REG_TXPAUSE);
  7331. rtw_write8(adapter, REG_TXPAUSE, 0xff);
  7332. val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
  7333. val8 &= ~BIT(0);
  7334. rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
  7335. RTW_INFO("%s: BB gated: 0x%02x, store TXPAUSE: %02x\n",
  7336. __func__,
  7337. rtw_read8(adapter, REG_SYS_FUNC_EN),
  7338. pwrpriv->wowlan_txpause_status);
  7339. } else {
  7340. val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
  7341. val8 |= BIT(0);
  7342. rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
  7343. RTW_INFO("%s: BB release: 0x%02x, recover TXPAUSE:%02x\n",
  7344. __func__, rtw_read8(adapter, REG_SYS_FUNC_EN),
  7345. pwrpriv->wowlan_txpause_status);
  7346. /* release TX*/
  7347. rtw_write8(adapter, REG_TXPAUSE, pwrpriv->wowlan_txpause_status);
  7348. }
  7349. }
  7350. static void rtw_hal_reset_mac_rx(_adapter *adapter)
  7351. {
  7352. u8 val8 = 0;
  7353. /* Set REG_CR bit1, bit3, bit7 to 0*/
  7354. val8 = rtw_read8(adapter, REG_CR);
  7355. val8 &= 0x75;
  7356. rtw_write8(adapter, REG_CR, val8);
  7357. val8 = rtw_read8(adapter, REG_CR);
  7358. /* Set REG_CR bit1, bit3, bit7 to 1*/
  7359. val8 |= 0x8a;
  7360. rtw_write8(adapter, REG_CR, val8);
  7361. RTW_INFO("0x%04x: %02x\n", REG_CR, rtw_read8(adapter, REG_CR));
  7362. }
  7363. static u8 rtw_hal_wow_pattern_generate(_adapter *adapter, u8 idx, struct rtl_wow_pattern *pwow_pattern)
  7364. {
  7365. struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
  7366. u8 *pattern;
  7367. u8 len = 0;
  7368. u8 *mask;
  7369. u8 mask_hw[MAX_WKFM_SIZE] = {0};
  7370. u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
  7371. u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  7372. u8 multicast_addr1[2] = {0x33, 0x33};
  7373. u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
  7374. u8 mask_len = 0;
  7375. u8 mac_addr[ETH_ALEN] = {0};
  7376. u16 count = 0;
  7377. int i, j;
  7378. if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
  7379. RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
  7380. __func__, MAX_WKFM_CAM_NUM);
  7381. return _FAIL;
  7382. }
  7383. pattern = pwrctl->patterns[idx].content;
  7384. len = pwrctl->patterns[idx].len;
  7385. mask = pwrctl->patterns[idx].mask;
  7386. _rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
  7387. _rtw_memset(pwow_pattern, 0, sizeof(struct rtl_wow_pattern));
  7388. mask_len = DIV_ROUND_UP(len, 8);
  7389. /* 1. setup A1 table */
  7390. if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
  7391. pwow_pattern->type = PATTERN_BROADCAST;
  7392. else if (memcmp(pattern, multicast_addr1, 2) == 0)
  7393. pwow_pattern->type = PATTERN_MULTICAST;
  7394. else if (memcmp(pattern, multicast_addr2, 3) == 0)
  7395. pwow_pattern->type = PATTERN_MULTICAST;
  7396. else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
  7397. pwow_pattern->type = PATTERN_UNICAST;
  7398. else
  7399. pwow_pattern->type = PATTERN_INVALID;
  7400. /* translate mask from os to mask for hw */
  7401. /******************************************************************************
  7402. * pattern from OS uses 'ethenet frame', like this:
  7403. | 6 | 6 | 2 | 20 | Variable | 4 |
  7404. |--------+--------+------+-----------+------------+-----|
  7405. | 802.3 Mac Header | IP Header | TCP Packet | FCS |
  7406. | DA | SA | Type |
  7407. * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
  7408. | 24 or 30 | 6 | 2 | 20 | Variable | 4 |
  7409. |-------------------+--------+------+-----------+------------+-----|
  7410. | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
  7411. | Others | Tpye |
  7412. * Therefore, we need translate mask_from_OS to mask_to_hw.
  7413. * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
  7414. * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
  7415. * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
  7416. ******************************************************************************/
  7417. /* Shift 6 bits */
  7418. for (i = 0; i < mask_len - 1; i++) {
  7419. mask_hw[i] = mask[i] >> 6;
  7420. mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
  7421. }
  7422. mask_hw[i] = (mask[i] >> 6) & 0x3F;
  7423. /* Set bit 0-5 to zero */
  7424. mask_hw[0] &= 0xC0;
  7425. for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
  7426. pwow_pattern->mask[i] = mask_hw[i * 4];
  7427. pwow_pattern->mask[i] |= (mask_hw[i * 4 + 1] << 8);
  7428. pwow_pattern->mask[i] |= (mask_hw[i * 4 + 2] << 16);
  7429. pwow_pattern->mask[i] |= (mask_hw[i * 4 + 3] << 24);
  7430. }
  7431. /* To get the wake up pattern from the mask.
  7432. * We do not count first 12 bits which means
  7433. * DA[6] and SA[6] in the pattern to match HW design. */
  7434. count = 0;
  7435. for (i = 12; i < len; i++) {
  7436. if ((mask[i / 8] >> (i % 8)) & 0x01) {
  7437. content[count] = pattern[i];
  7438. count++;
  7439. }
  7440. }
  7441. pwow_pattern->crc = rtw_calc_crc(content, count);
  7442. if (pwow_pattern->crc != 0) {
  7443. if (pwow_pattern->type == PATTERN_INVALID)
  7444. pwow_pattern->type = PATTERN_VALID;
  7445. }
  7446. return _SUCCESS;
  7447. }
  7448. #ifndef CONFIG_WOW_PATTERN_HW_CAM
  7449. static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode)
  7450. {
  7451. u8 val8 = 0;
  7452. u16 rxff_bndy = 0;
  7453. u32 rx_dma_buff_sz = 0;
  7454. val8 = rtw_read8(adapter, REG_FIFOPAGE + 3);
  7455. if (val8 != 0)
  7456. RTW_INFO("%s:[%04x]some PKTs in TXPKTBUF\n",
  7457. __func__, (REG_FIFOPAGE + 3));
  7458. rtw_hal_reset_mac_rx(adapter);
  7459. if (wow_mode) {
  7460. rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
  7461. (u8 *)&rx_dma_buff_sz);
  7462. rxff_bndy = rx_dma_buff_sz - 1;
  7463. rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
  7464. RTW_INFO("%s: wow mode, 0x%04x: 0x%04x\n", __func__,
  7465. REG_TRXFF_BNDY + 2,
  7466. rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
  7467. } else {
  7468. rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ,
  7469. (u8 *)&rx_dma_buff_sz);
  7470. rxff_bndy = rx_dma_buff_sz - 1;
  7471. rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
  7472. RTW_INFO("%s: normal mode, 0x%04x: 0x%04x\n", __func__,
  7473. REG_TRXFF_BNDY + 2,
  7474. rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
  7475. }
  7476. }
  7477. bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
  7478. {
  7479. u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
  7480. u16 offset, rx_buf_ptr = 0;
  7481. u16 cam_start_offset = 0;
  7482. u16 ctrl_l = 0, ctrl_h = 0;
  7483. u8 count = 0, tmp = 0;
  7484. int i = 0;
  7485. bool res = _TRUE;
  7486. if (idx > MAX_WKFM_CAM_NUM) {
  7487. RTW_INFO("[Error]: %s, pattern index is out of range\n",
  7488. __func__);
  7489. return _FALSE;
  7490. }
  7491. rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
  7492. (u8 *)&rx_dma_buff_sz);
  7493. if (rx_dma_buff_sz == 0) {
  7494. RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
  7495. return _FALSE;
  7496. }
  7497. rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
  7498. if (page_sz == 0) {
  7499. RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
  7500. return _FALSE;
  7501. }
  7502. offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
  7503. cam_start_offset = offset * page_sz;
  7504. ctrl_l = 0x0;
  7505. ctrl_h = 0x0;
  7506. /* Enable RX packet buffer access */
  7507. rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
  7508. /* Read the WKFM CAM */
  7509. for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
  7510. /*
  7511. * Set Rx packet buffer offset.
  7512. * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
  7513. * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
  7514. * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
  7515. * * Index: The index of the wake up frame mask
  7516. * * WKFMCAM_SIZE: the total size of one WKFM CAM
  7517. * * per entry offset of a WKFM CAM: Addr i * 4 bytes
  7518. */
  7519. rx_buf_ptr =
  7520. (cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
  7521. rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
  7522. rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
  7523. data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
  7524. data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
  7525. RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
  7526. count = 0;
  7527. do {
  7528. tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
  7529. rtw_udelay_os(2);
  7530. count++;
  7531. } while (!tmp && count < 100);
  7532. if (count >= 100) {
  7533. RTW_INFO("%s count:%d\n", __func__, count);
  7534. res = _FALSE;
  7535. }
  7536. }
  7537. /* Disable RX packet buffer access */
  7538. rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
  7539. DISABLE_TRXPKT_BUF_ACCESS);
  7540. return res;
  7541. }
  7542. bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
  7543. struct rtl_wow_pattern *context)
  7544. {
  7545. u32 data = 0, rx_dma_buff_sz = 0, page_sz = 0;
  7546. u16 offset, rx_buf_ptr = 0;
  7547. u16 cam_start_offset = 0;
  7548. u16 ctrl_l = 0, ctrl_h = 0;
  7549. u8 count = 0, tmp = 0;
  7550. int res = 0, i = 0;
  7551. if (idx > MAX_WKFM_CAM_NUM) {
  7552. RTW_INFO("[Error]: %s, pattern index is out of range\n",
  7553. __func__);
  7554. return _FALSE;
  7555. }
  7556. rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
  7557. (u8 *)&rx_dma_buff_sz);
  7558. if (rx_dma_buff_sz == 0) {
  7559. RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
  7560. return _FALSE;
  7561. }
  7562. rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
  7563. if (page_sz == 0) {
  7564. RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
  7565. return _FALSE;
  7566. }
  7567. offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
  7568. cam_start_offset = offset * page_sz;
  7569. if (IS_HARDWARE_TYPE_8188E(adapter)) {
  7570. ctrl_l = 0x0001;
  7571. ctrl_h = 0x0001;
  7572. } else {
  7573. ctrl_l = 0x0f01;
  7574. ctrl_h = 0xf001;
  7575. }
  7576. /* Enable RX packet buffer access */
  7577. rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
  7578. /* Write the WKFM CAM */
  7579. for (i = 0; i < WKFMCAM_ADDR_NUM; i++) {
  7580. /*
  7581. * Set Rx packet buffer offset.
  7582. * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
  7583. * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
  7584. * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
  7585. * * Index: The index of the wake up frame mask
  7586. * * WKFMCAM_SIZE: the total size of one WKFM CAM
  7587. * * per entry offset of a WKFM CAM: Addr i * 4 bytes
  7588. */
  7589. rx_buf_ptr =
  7590. (cam_start_offset + idx * WKFMCAM_SIZE + i * 4) >> 3;
  7591. rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
  7592. if (i == 0) {
  7593. if (context->type == PATTERN_VALID)
  7594. data = BIT(31);
  7595. else if (context->type == PATTERN_BROADCAST)
  7596. data = BIT(31) | BIT(26);
  7597. else if (context->type == PATTERN_MULTICAST)
  7598. data = BIT(31) | BIT(25);
  7599. else if (context->type == PATTERN_UNICAST)
  7600. data = BIT(31) | BIT(24);
  7601. if (context->crc != 0)
  7602. data |= context->crc;
  7603. rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
  7604. rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
  7605. } else if (i == 1) {
  7606. data = 0;
  7607. rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
  7608. rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
  7609. } else if (i == 2 || i == 4) {
  7610. data = context->mask[i - 2];
  7611. rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
  7612. /* write to RX packet buffer*/
  7613. rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
  7614. } else if (i == 3 || i == 5) {
  7615. data = context->mask[i - 2];
  7616. rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
  7617. /* write to RX packet buffer*/
  7618. rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
  7619. }
  7620. count = 0;
  7621. do {
  7622. tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
  7623. rtw_udelay_os(2);
  7624. count++;
  7625. } while (tmp && count < 100);
  7626. if (count >= 100)
  7627. res = _FALSE;
  7628. else
  7629. res = _TRUE;
  7630. }
  7631. /* Disable RX packet buffer access */
  7632. rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
  7633. DISABLE_TRXPKT_BUF_ACCESS);
  7634. return res;
  7635. }
  7636. void rtw_clean_pattern(_adapter *adapter)
  7637. {
  7638. struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
  7639. struct rtl_wow_pattern zero_pattern;
  7640. int i = 0;
  7641. _rtw_memset(&zero_pattern, 0, sizeof(struct rtl_wow_pattern));
  7642. zero_pattern.type = PATTERN_INVALID;
  7643. for (i = 0; i < MAX_WKFM_CAM_NUM; i++)
  7644. rtw_write_to_frame_mask(adapter, i, &zero_pattern);
  7645. rtw_write8(adapter, REG_WKFMCAM_NUM, 0);
  7646. }
  7647. static int rtw_hal_set_pattern(_adapter *adapter, u8 *pattern,
  7648. u8 len, u8 *mask, u8 idx)
  7649. {
  7650. struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
  7651. struct mlme_ext_priv *pmlmeext = NULL;
  7652. struct mlme_ext_info *pmlmeinfo = NULL;
  7653. struct rtl_wow_pattern wow_pattern;
  7654. u8 mask_hw[MAX_WKFM_SIZE] = {0};
  7655. u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
  7656. u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  7657. u8 multicast_addr1[2] = {0x33, 0x33};
  7658. u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
  7659. u8 res = _FALSE, index = 0, mask_len = 0;
  7660. u8 mac_addr[ETH_ALEN] = {0};
  7661. u16 count = 0;
  7662. int i, j;
  7663. if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
  7664. RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
  7665. __func__, MAX_WKFM_CAM_NUM);
  7666. return _FALSE;
  7667. }
  7668. pmlmeext = &adapter->mlmeextpriv;
  7669. pmlmeinfo = &pmlmeext->mlmext_info;
  7670. _rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
  7671. _rtw_memset(&wow_pattern, 0, sizeof(struct rtl_wow_pattern));
  7672. mask_len = DIV_ROUND_UP(len, 8);
  7673. /* 1. setup A1 table */
  7674. if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
  7675. wow_pattern.type = PATTERN_BROADCAST;
  7676. else if (memcmp(pattern, multicast_addr1, 2) == 0)
  7677. wow_pattern.type = PATTERN_MULTICAST;
  7678. else if (memcmp(pattern, multicast_addr2, 3) == 0)
  7679. wow_pattern.type = PATTERN_MULTICAST;
  7680. else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
  7681. wow_pattern.type = PATTERN_UNICAST;
  7682. else
  7683. wow_pattern.type = PATTERN_INVALID;
  7684. /* translate mask from os to mask for hw */
  7685. /******************************************************************************
  7686. * pattern from OS uses 'ethenet frame', like this:
  7687. | 6 | 6 | 2 | 20 | Variable | 4 |
  7688. |--------+--------+------+-----------+------------+-----|
  7689. | 802.3 Mac Header | IP Header | TCP Packet | FCS |
  7690. | DA | SA | Type |
  7691. * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
  7692. | 24 or 30 | 6 | 2 | 20 | Variable | 4 |
  7693. |-------------------+--------+------+-----------+------------+-----|
  7694. | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
  7695. | Others | Tpye |
  7696. * Therefore, we need translate mask_from_OS to mask_to_hw.
  7697. * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
  7698. * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
  7699. * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
  7700. ******************************************************************************/
  7701. /* Shift 6 bits */
  7702. for (i = 0; i < mask_len - 1; i++) {
  7703. mask_hw[i] = mask[i] >> 6;
  7704. mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
  7705. }
  7706. mask_hw[i] = (mask[i] >> 6) & 0x3F;
  7707. /* Set bit 0-5 to zero */
  7708. mask_hw[0] &= 0xC0;
  7709. for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
  7710. wow_pattern.mask[i] = mask_hw[i * 4];
  7711. wow_pattern.mask[i] |= (mask_hw[i * 4 + 1] << 8);
  7712. wow_pattern.mask[i] |= (mask_hw[i * 4 + 2] << 16);
  7713. wow_pattern.mask[i] |= (mask_hw[i * 4 + 3] << 24);
  7714. }
  7715. /* To get the wake up pattern from the mask.
  7716. * We do not count first 12 bits which means
  7717. * DA[6] and SA[6] in the pattern to match HW design. */
  7718. count = 0;
  7719. for (i = 12; i < len; i++) {
  7720. if ((mask[i / 8] >> (i % 8)) & 0x01) {
  7721. content[count] = pattern[i];
  7722. count++;
  7723. }
  7724. }
  7725. wow_pattern.crc = rtw_calc_crc(content, count);
  7726. if (wow_pattern.crc != 0) {
  7727. if (wow_pattern.type == PATTERN_INVALID)
  7728. wow_pattern.type = PATTERN_VALID;
  7729. }
  7730. index = idx;
  7731. if (!pwrctl->bInSuspend)
  7732. index += 2;
  7733. /* write pattern */
  7734. res = rtw_write_to_frame_mask(adapter, index, &wow_pattern);
  7735. if (res == _FALSE)
  7736. RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n",
  7737. __func__, idx);
  7738. return res;
  7739. }
  7740. void rtw_fill_pattern(_adapter *adapter)
  7741. {
  7742. int i = 0, total = 0, index;
  7743. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
  7744. struct rtl_wow_pattern wow_pattern;
  7745. total = pwrpriv->wowlan_pattern_idx;
  7746. if (total > MAX_WKFM_CAM_NUM)
  7747. total = MAX_WKFM_CAM_NUM;
  7748. for (i = 0 ; i < total ; i++) {
  7749. if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
  7750. index = i;
  7751. if (!pwrpriv->bInSuspend)
  7752. index += 2;
  7753. if (rtw_write_to_frame_mask(adapter, index, &wow_pattern) == _FALSE)
  7754. RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i);
  7755. }
  7756. }
  7757. rtw_write8(adapter, REG_WKFMCAM_NUM, total);
  7758. }
  7759. #else /*CONFIG_WOW_PATTERN_HW_CAM*/
  7760. #define WOW_CAM_ACCESS_TIMEOUT_MS 200
  7761. #define WOW_VALID_BIT BIT31
  7762. #define WOW_BC_BIT BIT26
  7763. #define WOW_MC_BIT BIT25
  7764. #define WOW_UC_BIT BIT24
  7765. static u32 _rtw_wow_pattern_read_cam(_adapter *adapter, u8 addr)
  7766. {
  7767. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
  7768. _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
  7769. u32 rdata = 0;
  7770. u32 cnt = 0;
  7771. systime start = 0;
  7772. u8 timeout = 0;
  7773. u8 rst = _FALSE;
  7774. _enter_critical_mutex(mutex, NULL);
  7775. rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_ADDR_V2(addr));
  7776. start = rtw_get_current_time();
  7777. while (1) {
  7778. if (rtw_is_surprise_removed(adapter))
  7779. break;
  7780. cnt++;
  7781. if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
  7782. rst = _SUCCESS;
  7783. break;
  7784. }
  7785. if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
  7786. timeout = 1;
  7787. break;
  7788. }
  7789. }
  7790. rdata = rtw_read32(adapter, REG_WKFMCAM_RWD);
  7791. _exit_critical_mutex(mutex, NULL);
  7792. /*RTW_INFO("%s ==> addr:0x%02x , rdata:0x%08x\n", __func__, addr, rdata);*/
  7793. if (timeout)
  7794. RTW_ERR(FUNC_ADPT_FMT" failed due to polling timeout\n", FUNC_ADPT_ARG(adapter));
  7795. return rdata;
  7796. }
  7797. void rtw_wow_pattern_read_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context)
  7798. {
  7799. int i;
  7800. u32 rdata;
  7801. _rtw_memset(context, 0, sizeof(struct rtl_wow_pattern));
  7802. for (i = 4; i >= 0; i--) {
  7803. rdata = _rtw_wow_pattern_read_cam(adapter, (id << 3) | i);
  7804. switch (i) {
  7805. case 4:
  7806. if (rdata & WOW_BC_BIT)
  7807. context->type = PATTERN_BROADCAST;
  7808. else if (rdata & WOW_MC_BIT)
  7809. context->type = PATTERN_MULTICAST;
  7810. else if (rdata & WOW_UC_BIT)
  7811. context->type = PATTERN_UNICAST;
  7812. else
  7813. context->type = PATTERN_INVALID;
  7814. context->crc = rdata & 0xFFFF;
  7815. break;
  7816. default:
  7817. _rtw_memcpy(&context->mask[i], (u8 *)(&rdata), 4);
  7818. break;
  7819. }
  7820. }
  7821. }
  7822. static void _rtw_wow_pattern_write_cam(_adapter *adapter, u8 addr, u32 wdata)
  7823. {
  7824. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
  7825. _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
  7826. u32 cnt = 0;
  7827. systime start = 0, end = 0;
  7828. u8 timeout = 0;
  7829. /*RTW_INFO("%s ==> addr:0x%02x , wdata:0x%08x\n", __func__, addr, wdata);*/
  7830. _enter_critical_mutex(mutex, NULL);
  7831. rtw_write32(adapter, REG_WKFMCAM_RWD, wdata);
  7832. rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_WE | BIT_WKFCAM_ADDR_V2(addr));
  7833. start = rtw_get_current_time();
  7834. while (1) {
  7835. if (rtw_is_surprise_removed(adapter))
  7836. break;
  7837. cnt++;
  7838. if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1))
  7839. break;
  7840. if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
  7841. timeout = 1;
  7842. break;
  7843. }
  7844. }
  7845. end = rtw_get_current_time();
  7846. _exit_critical_mutex(mutex, NULL);
  7847. if (timeout) {
  7848. RTW_ERR(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
  7849. , FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
  7850. }
  7851. }
  7852. void rtw_wow_pattern_write_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context)
  7853. {
  7854. int j;
  7855. u8 addr;
  7856. u32 wdata = 0;
  7857. for (j = 4; j >= 0; j--) {
  7858. switch (j) {
  7859. case 4:
  7860. wdata = context->crc;
  7861. if (PATTERN_BROADCAST == context->type)
  7862. wdata |= WOW_BC_BIT;
  7863. if (PATTERN_MULTICAST == context->type)
  7864. wdata |= WOW_MC_BIT;
  7865. if (PATTERN_UNICAST == context->type)
  7866. wdata |= WOW_UC_BIT;
  7867. if (PATTERN_INVALID != context->type)
  7868. wdata |= WOW_VALID_BIT;
  7869. break;
  7870. default:
  7871. wdata = context->mask[j];
  7872. break;
  7873. }
  7874. addr = (id << 3) + j;
  7875. _rtw_wow_pattern_write_cam(adapter, addr, wdata);
  7876. }
  7877. }
  7878. static u8 _rtw_wow_pattern_clean_cam(_adapter *adapter)
  7879. {
  7880. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
  7881. _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
  7882. u32 cnt = 0;
  7883. systime start = 0;
  7884. u8 timeout = 0;
  7885. u8 rst = _FAIL;
  7886. _enter_critical_mutex(mutex, NULL);
  7887. rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_CLR_V1);
  7888. start = rtw_get_current_time();
  7889. while (1) {
  7890. if (rtw_is_surprise_removed(adapter))
  7891. break;
  7892. cnt++;
  7893. if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
  7894. rst = _SUCCESS;
  7895. break;
  7896. }
  7897. if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
  7898. timeout = 1;
  7899. break;
  7900. }
  7901. }
  7902. _exit_critical_mutex(mutex, NULL);
  7903. if (timeout)
  7904. RTW_ERR(FUNC_ADPT_FMT" falied ,polling timeout\n", FUNC_ADPT_ARG(adapter));
  7905. return rst;
  7906. }
  7907. void rtw_clean_pattern(_adapter *adapter)
  7908. {
  7909. if (_FAIL == _rtw_wow_pattern_clean_cam(adapter))
  7910. RTW_ERR("rtw_clean_pattern failed\n");
  7911. }
  7912. void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx)
  7913. {
  7914. int j;
  7915. RTW_PRINT_SEL(sel, "=======WOW CAM-ID[%d]=======\n", idx);
  7916. RTW_PRINT_SEL(sel, "[WOW CAM] type:%d\n", pwow_pattern->type);
  7917. RTW_PRINT_SEL(sel, "[WOW CAM] crc:0x%04x\n", pwow_pattern->crc);
  7918. for (j = 0; j < 4; j++)
  7919. RTW_PRINT_SEL(sel, "[WOW CAM] Mask:0x%08x\n", pwow_pattern->mask[j]);
  7920. }
  7921. void rtw_fill_pattern(_adapter *adapter)
  7922. {
  7923. int i = 0, total = 0;
  7924. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
  7925. struct rtl_wow_pattern wow_pattern;
  7926. total = pwrpriv->wowlan_pattern_idx;
  7927. if (total > MAX_WKFM_CAM_NUM)
  7928. total = MAX_WKFM_CAM_NUM;
  7929. for (i = 0 ; i < total ; i++) {
  7930. if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
  7931. rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
  7932. rtw_wow_pattern_write_cam_ent(adapter, i, &wow_pattern);
  7933. }
  7934. }
  7935. }
  7936. #endif
  7937. void rtw_wow_pattern_cam_dump(_adapter *adapter)
  7938. {
  7939. #ifndef CONFIG_WOW_PATTERN_HW_CAM
  7940. int i;
  7941. for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
  7942. RTW_INFO("=======[%d]=======\n", i);
  7943. rtw_read_from_frame_mask(adapter, i);
  7944. }
  7945. #else
  7946. struct rtl_wow_pattern context;
  7947. int i;
  7948. for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
  7949. rtw_wow_pattern_read_cam_ent(adapter, i, &context);
  7950. rtw_dump_wow_pattern(RTW_DBGDUMP, &context, i);
  7951. }
  7952. #endif
  7953. }
  7954. static void rtw_hal_dl_pattern(_adapter *adapter, u8 mode)
  7955. {
  7956. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
  7957. switch (mode) {
  7958. case 0:
  7959. rtw_clean_pattern(adapter);
  7960. RTW_INFO("%s: total patterns: %d\n", __func__, pwrpriv->wowlan_pattern_idx);
  7961. break;
  7962. case 1:
  7963. rtw_set_default_pattern(adapter);
  7964. rtw_fill_pattern(adapter);
  7965. RTW_INFO("%s: pattern total: %d downloaded\n", __func__, pwrpriv->wowlan_pattern_idx);
  7966. break;
  7967. case 2:
  7968. rtw_clean_pattern(adapter);
  7969. rtw_wow_pattern_sw_reset(adapter);
  7970. RTW_INFO("%s: clean patterns\n", __func__);
  7971. break;
  7972. default:
  7973. RTW_INFO("%s: unknown mode\n", __func__);
  7974. break;
  7975. }
  7976. }
  7977. static void rtw_hal_wow_enable(_adapter *adapter)
  7978. {
  7979. struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
  7980. struct security_priv *psecuritypriv = &adapter->securitypriv;
  7981. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  7982. struct hal_ops *pHalFunc = &adapter->hal_func;
  7983. struct sta_info *psta = NULL;
  7984. PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);
  7985. int res;
  7986. u16 media_status_rpt;
  7987. RTW_PRINT(FUNC_ADPT_FMT " WOWLAN_ENABLE\n", FUNC_ADPT_ARG(adapter));
  7988. rtw_hal_gate_bb(adapter, _TRUE);
  7989. #ifdef CONFIG_GTK_OL
  7990. if (psecuritypriv->binstallKCK_KEK == _TRUE)
  7991. rtw_hal_fw_sync_cam_id(adapter);
  7992. #endif
  7993. if (IS_HARDWARE_TYPE_8723B(adapter))
  7994. rtw_hal_backup_rate(adapter);
  7995. rtw_hal_fw_dl(adapter, _TRUE);
  7996. media_status_rpt = RT_MEDIA_CONNECT;
  7997. rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
  7998. (u8 *)&media_status_rpt);
  7999. /* RX DMA stop */
  8000. #if defined(CONFIG_RTL8188E)
  8001. if (IS_HARDWARE_TYPE_8188E(adapter))
  8002. rtw_hal_disable_tx_report(adapter);
  8003. #endif
  8004. res = rtw_hal_pause_rx_dma(adapter);
  8005. if (res == _FAIL)
  8006. RTW_PRINT("[WARNING] pause RX DMA fail\n");
  8007. #ifndef CONFIG_WOW_PATTERN_HW_CAM
  8008. /* Reconfig RX_FF Boundary */
  8009. rtw_hal_set_wow_rxff_boundary(adapter, _TRUE);
  8010. #endif
  8011. /* redownload wow pattern */
  8012. rtw_hal_dl_pattern(adapter, 1);
  8013. if (!pwrctl->wowlan_pno_enable) {
  8014. psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
  8015. if (psta != NULL) {
  8016. #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
  8017. adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
  8018. adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
  8019. rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
  8020. #endif
  8021. rtw_sta_media_status_rpt(adapter, psta, 1);
  8022. }
  8023. }
  8024. #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
  8025. /* Enable CPWM2 only. */
  8026. res = rtw_hal_enable_cpwm2(adapter);
  8027. if (res == _FAIL)
  8028. RTW_PRINT("[WARNING] enable cpwm2 fail\n");
  8029. #endif
  8030. #ifdef CONFIG_GPIO_WAKEUP
  8031. rtw_hal_switch_gpio_wl_ctrl(adapter, WAKEUP_GPIO_IDX, _TRUE);
  8032. #endif
  8033. /* Set WOWLAN H2C command. */
  8034. RTW_PRINT("Set WOWLan cmd\n");
  8035. rtw_hal_set_fw_wow_related_cmd(adapter, 1);
  8036. res = rtw_hal_check_wow_ctrl(adapter, _TRUE);
  8037. if (res == _FALSE)
  8038. RTW_INFO("[Error]%s: set wowlan CMD fail!!\n", __func__);
  8039. pwrctl->wowlan_wake_reason =
  8040. rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
  8041. RTW_PRINT("wowlan_wake_reason: 0x%02x\n",
  8042. pwrctl->wowlan_wake_reason);
  8043. #ifdef CONFIG_GTK_OL_DBG
  8044. dump_sec_cam(RTW_DBGDUMP, adapter);
  8045. dump_sec_cam_cache(RTW_DBGDUMP, adapter);
  8046. #endif
  8047. #ifdef CONFIG_USB_HCI
  8048. /* free adapter's resource */
  8049. rtw_mi_intf_stop(adapter);
  8050. #endif
  8051. #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
  8052. /* Invoid SE0 reset signal during suspending*/
  8053. rtw_write8(adapter, REG_RSV_CTRL, 0x20);
  8054. if (IS_8188F(pHalData->version_id) == FALSE
  8055. && IS_8188GTV(pHalData->version_id) == FALSE)
  8056. rtw_write8(adapter, REG_RSV_CTRL, 0x60);
  8057. #endif
  8058. rtw_hal_gate_bb(adapter, _FALSE);
  8059. }
  8060. #define DBG_WAKEUP_REASON
  8061. #ifdef DBG_WAKEUP_REASON
  8062. void _dbg_wake_up_reason_string(_adapter *adapter, const char *srt_res)
  8063. {
  8064. RTW_INFO(ADPT_FMT "- wake up reason - %s\n", ADPT_ARG(adapter), srt_res);
  8065. }
  8066. void _dbg_rtw_wake_up_reason(_adapter *adapter, u8 reason)
  8067. {
  8068. if (RX_PAIRWISEKEY == reason)
  8069. _dbg_wake_up_reason_string(adapter, "Rx pairwise key");
  8070. else if (RX_GTK == reason)
  8071. _dbg_wake_up_reason_string(adapter, "Rx GTK");
  8072. else if (RX_FOURWAY_HANDSHAKE == reason)
  8073. _dbg_wake_up_reason_string(adapter, "Rx four way handshake");
  8074. else if (RX_DISASSOC == reason)
  8075. _dbg_wake_up_reason_string(adapter, "Rx disassoc");
  8076. else if (RX_DEAUTH == reason)
  8077. _dbg_wake_up_reason_string(adapter, "Rx deauth");
  8078. else if (RX_ARP_REQUEST == reason)
  8079. _dbg_wake_up_reason_string(adapter, "Rx ARP request");
  8080. else if (FW_DECISION_DISCONNECT == reason)
  8081. _dbg_wake_up_reason_string(adapter, "FW detect disconnect");
  8082. else if (RX_MAGIC_PKT == reason)
  8083. _dbg_wake_up_reason_string(adapter, "Rx magic packet");
  8084. else if (RX_UNICAST_PKT == reason)
  8085. _dbg_wake_up_reason_string(adapter, "Rx unicast packet");
  8086. else if (RX_PATTERN_PKT == reason)
  8087. _dbg_wake_up_reason_string(adapter, "Rx pattern packet");
  8088. else if (RTD3_SSID_MATCH == reason)
  8089. _dbg_wake_up_reason_string(adapter, "RTD3 SSID match");
  8090. else if (RX_REALWOW_V2_WAKEUP_PKT == reason)
  8091. _dbg_wake_up_reason_string(adapter, "Rx real WOW V2 wakeup packet");
  8092. else if (RX_REALWOW_V2_ACK_LOST == reason)
  8093. _dbg_wake_up_reason_string(adapter, "Rx real WOW V2 ack lost");
  8094. else if (ENABLE_FAIL_DMA_IDLE == reason)
  8095. _dbg_wake_up_reason_string(adapter, "enable fail DMA idle");
  8096. else if (ENABLE_FAIL_DMA_PAUSE == reason)
  8097. _dbg_wake_up_reason_string(adapter, "enable fail DMA pause");
  8098. else if (AP_OFFLOAD_WAKEUP == reason)
  8099. _dbg_wake_up_reason_string(adapter, "AP offload wakeup");
  8100. else if (CLK_32K_UNLOCK == reason)
  8101. _dbg_wake_up_reason_string(adapter, "clk 32k unlock");
  8102. else if (RTIME_FAIL_DMA_IDLE == reason)
  8103. _dbg_wake_up_reason_string(adapter, "RTIME fail DMA idle");
  8104. else if (CLK_32K_LOCK == reason)
  8105. _dbg_wake_up_reason_string(adapter, "clk 32k lock");
  8106. else
  8107. _dbg_wake_up_reason_string(adapter, "unknown reasoen");
  8108. }
  8109. #endif
  8110. static void rtw_hal_wow_disable(_adapter *adapter)
  8111. {
  8112. struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
  8113. struct security_priv *psecuritypriv = &adapter->securitypriv;
  8114. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  8115. struct hal_ops *pHalFunc = &adapter->hal_func;
  8116. struct sta_info *psta = NULL;
  8117. int res;
  8118. u16 media_status_rpt;
  8119. u8 val8;
  8120. RTW_PRINT("%s, WOWLAN_DISABLE\n", __func__);
  8121. if (!pwrctl->wowlan_pno_enable) {
  8122. psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
  8123. if (psta != NULL)
  8124. rtw_sta_media_status_rpt(adapter, psta, 0);
  8125. else
  8126. RTW_INFO("%s: psta is null\n", __func__);
  8127. }
  8128. if (0) {
  8129. RTW_INFO("0x630:0x%02x\n", rtw_read8(adapter, 0x630));
  8130. RTW_INFO("0x631:0x%02x\n", rtw_read8(adapter, 0x631));
  8131. RTW_INFO("0x634:0x%02x\n", rtw_read8(adapter, 0x634));
  8132. RTW_INFO("0x1c7:0x%02x\n", rtw_read8(adapter, 0x1c7));
  8133. }
  8134. pwrctl->wowlan_wake_reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
  8135. RTW_PRINT("wakeup_reason: 0x%02x\n",
  8136. pwrctl->wowlan_wake_reason);
  8137. #ifdef DBG_WAKEUP_REASON
  8138. _dbg_rtw_wake_up_reason(adapter, pwrctl->wowlan_wake_reason);
  8139. #endif
  8140. rtw_hal_set_fw_wow_related_cmd(adapter, 0);
  8141. res = rtw_hal_check_wow_ctrl(adapter, _FALSE);
  8142. if (res == _FALSE) {
  8143. RTW_INFO("[Error]%s: disable WOW cmd fail\n!!", __func__);
  8144. rtw_hal_force_enable_rxdma(adapter);
  8145. }
  8146. rtw_hal_gate_bb(adapter, _TRUE);
  8147. res = rtw_hal_pause_rx_dma(adapter);
  8148. if (res == _FAIL)
  8149. RTW_PRINT("[WARNING] pause RX DMA fail\n");
  8150. /* clean HW pattern match */
  8151. rtw_hal_dl_pattern(adapter, 0);
  8152. #ifndef CONFIG_WOW_PATTERN_HW_CAM
  8153. /* config RXFF boundary to original */
  8154. rtw_hal_set_wow_rxff_boundary(adapter, _FALSE);
  8155. #endif
  8156. rtw_hal_release_rx_dma(adapter);
  8157. #if defined(CONFIG_RTL8188E)
  8158. if (IS_HARDWARE_TYPE_8188E(adapter))
  8159. rtw_hal_enable_tx_report(adapter);
  8160. #endif
  8161. if ((pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
  8162. (pwrctl->wowlan_wake_reason != RX_DEAUTH) &&
  8163. (pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT)) {
  8164. rtw_hal_get_aoac_rpt(adapter);
  8165. rtw_hal_update_sw_security_info(adapter);
  8166. }
  8167. rtw_hal_fw_dl(adapter, _FALSE);
  8168. #ifdef CONFIG_GPIO_WAKEUP
  8169. #ifdef CONFIG_RTW_ONE_PIN_GPIO
  8170. rtw_hal_set_input_gpio(adapter, WAKEUP_GPIO_IDX);
  8171. #else
  8172. #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
  8173. if (pwrctl->is_high_active == 0)
  8174. rtw_hal_set_input_gpio(adapter, WAKEUP_GPIO_IDX);
  8175. else
  8176. rtw_hal_set_output_gpio(adapter, WAKEUP_GPIO_IDX, 0);
  8177. #else
  8178. val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
  8179. RTW_PRINT("Set Wake GPIO to default(%d).\n", val8);
  8180. rtw_hal_set_output_gpio(adapter, WAKEUP_GPIO_IDX, val8);
  8181. rtw_hal_switch_gpio_wl_ctrl(adapter, WAKEUP_GPIO_IDX, _FALSE);
  8182. #endif
  8183. #endif /* CONFIG_RTW_ONE_PIN_GPIO */
  8184. #endif
  8185. if ((pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT) &&
  8186. (pwrctl->wowlan_wake_reason != RX_PAIRWISEKEY) &&
  8187. (pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
  8188. (pwrctl->wowlan_wake_reason != RX_DEAUTH)) {
  8189. media_status_rpt = RT_MEDIA_CONNECT;
  8190. rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
  8191. (u8 *)&media_status_rpt);
  8192. if (psta != NULL) {
  8193. #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
  8194. adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
  8195. adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
  8196. rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
  8197. #endif
  8198. rtw_sta_media_status_rpt(adapter, psta, 1);
  8199. }
  8200. }
  8201. rtw_hal_gate_bb(adapter, _FALSE);
  8202. }
  8203. #endif /*CONFIG_WOWLAN*/
  8204. #ifdef CONFIG_P2P_WOWLAN
  8205. void rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
  8206. u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
  8207. RSVDPAGE_LOC *rsvd_page_loc)
  8208. {
  8209. u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0;
  8210. u32 P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0;
  8211. u8 CurtPktPageNum = 0;
  8212. /* P2P Beacon */
  8213. rsvd_page_loc->LocP2PBeacon = *page_num;
  8214. rtw_hal_construct_P2PBeacon(adapter, &pframe[index], &P2PBCNLength);
  8215. rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
  8216. P2PBCNLength, _FALSE, _FALSE, _FALSE);
  8217. #if 0
  8218. RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",
  8219. __FUNCTION__, &pframe[index - tx_desc], (P2PBCNLength + tx_desc));
  8220. #endif
  8221. CurtPktPageNum = (u8)PageNum(tx_desc + P2PBCNLength, page_size);
  8222. *page_num += CurtPktPageNum;
  8223. index += (CurtPktPageNum * page_size);
  8224. #ifdef DBG_RSVD_PAGE_CFG
  8225. RSVD_PAGE_CFG("WOW-P2P-Beacon", CurtPktPageNum, *page_num, 0);
  8226. #endif
  8227. /* P2P Probe rsp */
  8228. rsvd_page_loc->LocP2PProbeRsp = *page_num;
  8229. rtw_hal_construct_P2PProbeRsp(adapter, &pframe[index],
  8230. &P2PProbeRspLength);
  8231. rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
  8232. P2PProbeRspLength, _FALSE, _FALSE, _FALSE);
  8233. /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n", */
  8234. /* __FUNCTION__, &pframe[index-tx_desc], (P2PProbeRspLength+tx_desc)); */
  8235. CurtPktPageNum = (u8)PageNum(tx_desc + P2PProbeRspLength, page_size);
  8236. *page_num += CurtPktPageNum;
  8237. index += (CurtPktPageNum * page_size);
  8238. #ifdef DBG_RSVD_PAGE_CFG
  8239. RSVD_PAGE_CFG("WOW-P2P-ProbeRsp", CurtPktPageNum, *page_num, 0);
  8240. #endif
  8241. /* P2P nego rsp */
  8242. rsvd_page_loc->LocNegoRsp = *page_num;
  8243. rtw_hal_construct_P2PNegoRsp(adapter, &pframe[index],
  8244. &P2PNegoRspLength);
  8245. rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
  8246. P2PNegoRspLength, _FALSE, _FALSE, _FALSE);
  8247. /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
  8248. /* __FUNCTION__, &pframe[index-tx_desc], (NegoRspLength+tx_desc)); */
  8249. CurtPktPageNum = (u8)PageNum(tx_desc + P2PNegoRspLength, page_size);
  8250. *page_num += CurtPktPageNum;
  8251. index += (CurtPktPageNum * page_size);
  8252. #ifdef DBG_RSVD_PAGE_CFG
  8253. RSVD_PAGE_CFG("WOW-P2P-NegoRsp", CurtPktPageNum, *page_num, 0);
  8254. #endif
  8255. /* P2P invite rsp */
  8256. rsvd_page_loc->LocInviteRsp = *page_num;
  8257. rtw_hal_construct_P2PInviteRsp(adapter, &pframe[index],
  8258. &P2PInviteRspLength);
  8259. rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
  8260. P2PInviteRspLength, _FALSE, _FALSE, _FALSE);
  8261. /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
  8262. /* __FUNCTION__, &pframe[index-tx_desc], (InviteRspLength+tx_desc)); */
  8263. CurtPktPageNum = (u8)PageNum(tx_desc + P2PInviteRspLength, page_size);
  8264. *page_num += CurtPktPageNum;
  8265. index += (CurtPktPageNum * page_size);
  8266. #ifdef DBG_RSVD_PAGE_CFG
  8267. RSVD_PAGE_CFG("WOW-P2P-InviteRsp", CurtPktPageNum, *page_num, 0);
  8268. #endif
  8269. /* P2P provision discovery rsp */
  8270. rsvd_page_loc->LocPDRsp = *page_num;
  8271. rtw_hal_construct_P2PProvisionDisRsp(adapter,
  8272. &pframe[index], &P2PPDRspLength);
  8273. rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
  8274. P2PPDRspLength, _FALSE, _FALSE, _FALSE);
  8275. /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
  8276. /* __FUNCTION__, &pframe[index-tx_desc], (PDRspLength+tx_desc)); */
  8277. CurtPktPageNum = (u8)PageNum(tx_desc + P2PPDRspLength, page_size);
  8278. *page_num += CurtPktPageNum;
  8279. *total_pkt_len = index + P2PPDRspLength;
  8280. #ifdef DBG_RSVD_PAGE_CFG
  8281. RSVD_PAGE_CFG("WOW-P2P-PDR", CurtPktPageNum, *page_num, *total_pkt_len);
  8282. #endif
  8283. index += (CurtPktPageNum * page_size);
  8284. }
  8285. #endif /* CONFIG_P2P_WOWLAN */
  8286. #ifdef CONFIG_LPS_PG
  8287. #include "hal_halmac.h"
  8288. #define DBG_LPSPG_SEC_DUMP
  8289. #define LPS_PG_INFO_RSVD_LEN 16
  8290. #define LPS_PG_INFO_RSVD_PAGE_NUM 1
  8291. #define DBG_LPSPG_INFO_DUMP
  8292. static void rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter)
  8293. {
  8294. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
  8295. struct sta_info *psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(&adapter->mlmepriv));
  8296. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  8297. PHAL_DATA_TYPE phal_data = GET_HAL_DATA(adapter);
  8298. u8 lps_pg_info[LPS_PG_INFO_RSVD_LEN] = {0};
  8299. #ifdef CONFIG_MBSSID_CAM
  8300. u8 cam_id = INVALID_CAM_ID;
  8301. #endif
  8302. u8 *psec_cam_id = lps_pg_info + 8;
  8303. u8 sec_cam_num = 0;
  8304. u8 drv_rsvdpage_num = 0;
  8305. if (!psta) {
  8306. RTW_ERR("%s [ERROR] sta is NULL\n", __func__);
  8307. rtw_warn_on(1);
  8308. return;
  8309. }
  8310. /*Byte 0 - used macid*/
  8311. LPSPG_RSVD_PAGE_SET_MACID(lps_pg_info, psta->cmn.mac_id);
  8312. RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->cmn.mac_id);
  8313. #ifdef CONFIG_MBSSID_CAM
  8314. /*Byte 1 - used BSSID CAM entry*/
  8315. cam_id = rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
  8316. if (cam_id != INVALID_CAM_ID)
  8317. LPSPG_RSVD_PAGE_SET_MBSSCAMID(lps_pg_info, cam_id);
  8318. RTW_INFO("[LPSPG-INFO] mbss_cam_id:%d\n", cam_id);
  8319. #endif
  8320. #ifdef CONFIG_WOWLAN /*&& pattern match cam used*/
  8321. /*Btye 2 - Max used Pattern Match CAM entry*/
  8322. if (pwrpriv->wowlan_mode == _TRUE &&
  8323. check_fwstate(&adapter->mlmepriv, _FW_LINKED) == _TRUE) {
  8324. LPSPG_RSVD_PAGE_SET_PMC_NUM(lps_pg_info, pwrpriv->wowlan_pattern_idx);
  8325. RTW_INFO("[LPSPG-INFO] Max Pattern Match CAM entry :%d\n", pwrpriv->wowlan_pattern_idx);
  8326. }
  8327. #endif
  8328. #ifdef CONFIG_BEAMFORMING /*&& MU BF*/
  8329. /*Btye 3 - Max MU rate table Group ID*/
  8330. LPSPG_RSVD_PAGE_SET_MU_RAID_GID(lps_pg_info, 0);
  8331. RTW_INFO("[LPSPG-INFO] Max MU rate table Group ID :%d\n", 0);
  8332. #endif
  8333. /*Btye 8 ~15 - used Security CAM entry */
  8334. sec_cam_num = rtw_get_sec_camid(adapter, 8, psec_cam_id);
  8335. /*Btye 4 - used Security CAM entry number*/
  8336. if (sec_cam_num < 8)
  8337. LPSPG_RSVD_PAGE_SET_SEC_CAM_NUM(lps_pg_info, sec_cam_num);
  8338. RTW_INFO("[LPSPG-INFO] Security CAM entry number :%d\n", sec_cam_num);
  8339. /*Btye 5 - Txbuf used page number for fw offload*/
  8340. if (pwrpriv->wowlan_mode == _TRUE || pwrpriv->wowlan_ap_mode == _TRUE)
  8341. drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
  8342. else
  8343. drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
  8344. LPSPG_RSVD_PAGE_SET_DRV_RSVDPAGE_NUM(lps_pg_info, drv_rsvdpage_num);
  8345. RTW_INFO("[LPSPG-INFO] DRV's rsvd page numbers :%d\n", drv_rsvdpage_num);
  8346. #ifdef DBG_LPSPG_SEC_DUMP
  8347. {
  8348. int i;
  8349. for (i = 0; i < sec_cam_num; i++)
  8350. RTW_INFO("%d = sec_cam_id:%d\n", i, psec_cam_id[i]);
  8351. }
  8352. #endif
  8353. #ifdef DBG_LPSPG_INFO_DUMP
  8354. RTW_INFO("==== DBG_LPSPG_INFO_RSVD_PAGE_DUMP====\n");
  8355. RTW_INFO(" %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
  8356. *(lps_pg_info), *(lps_pg_info + 1), *(lps_pg_info + 2), *(lps_pg_info + 3),
  8357. *(lps_pg_info + 4), *(lps_pg_info + 5), *(lps_pg_info + 6), *(lps_pg_info + 7));
  8358. RTW_INFO(" %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
  8359. *(lps_pg_info + 8), *(lps_pg_info + 9), *(lps_pg_info + 10), *(lps_pg_info + 11),
  8360. *(lps_pg_info + 12), *(lps_pg_info + 13), *(lps_pg_info + 14), *(lps_pg_info + 15));
  8361. RTW_INFO("==== DBG_LPSPG_INFO_RSVD_PAGE_DUMP====\n");
  8362. #endif
  8363. rtw_halmac_download_rsvd_page(dvobj, pwrpriv->lpspg_rsvd_page_locate, lps_pg_info, LPS_PG_INFO_RSVD_LEN);
  8364. #ifdef DBG_LPSPG_INFO_DUMP
  8365. RTW_INFO("Get LPS-PG INFO from rsvd page_offset:%d\n", pwrpriv->lpspg_rsvd_page_locate);
  8366. rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, pwrpriv->lpspg_rsvd_page_locate, 1);
  8367. #endif
  8368. }
  8369. static u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter)
  8370. {
  8371. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
  8372. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  8373. u8 lpspg_info[H2C_LPS_PG_INFO_LEN] = {0};
  8374. u8 ret = _FAIL;
  8375. RTW_INFO("%s: loc_lpspg_info:%d\n", __func__, pwrpriv->lpspg_rsvd_page_locate);
  8376. if (_NO_PRIVACY_ != adapter->securitypriv.dot11PrivacyAlgrthm)
  8377. SET_H2CCMD_LPSPG_SEC_CAM_EN(lpspg_info, 1); /*SecurityCAM_En*/
  8378. #ifdef CONFIG_MBSSID_CAM
  8379. SET_H2CCMD_LPSPG_MBID_CAM_EN(lpspg_info, 1); /*BSSIDCAM_En*/
  8380. #endif
  8381. #if defined(CONFIG_WOWLAN) && defined(CONFIG_WOW_PATTERN_HW_CAM)
  8382. if (pwrpriv->wowlan_mode == _TRUE &&
  8383. check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
  8384. SET_H2CCMD_LPSPG_PMC_CAM_EN(lpspg_info, 1); /*PatternMatchCAM_En*/
  8385. }
  8386. #endif
  8387. #ifdef CONFIG_MACID_SEARCH
  8388. SET_H2CCMD_LPSPG_MACID_SEARCH_EN(lpspg_info, 1); /*MACIDSearch_En*/
  8389. #endif
  8390. #ifdef CONFIG_TX_SC
  8391. SET_H2CCMD_LPSPG_TXSC_EN(lpspg_info, 1); /*TXSC_En*/
  8392. #endif
  8393. #ifdef CONFIG_BEAMFORMING /*&& MU BF*/
  8394. SET_H2CCMD_LPSPG_MU_RATE_TB_EN(lpspg_info, 1); /*MURateTable_En*/
  8395. #endif
  8396. SET_H2CCMD_LPSPG_LOC(lpspg_info, pwrpriv->lpspg_rsvd_page_locate);
  8397. #ifdef DBG_LPSPG_INFO_DUMP
  8398. RTW_INFO("==== DBG_LPSPG_INFO_CMD_DUMP====\n");
  8399. RTW_INFO(" H2C_CMD: 0x%02x, H2C_LEN: %d\n", H2C_LPS_PG_INFO, H2C_LPS_PG_INFO_LEN);
  8400. RTW_INFO(" %02X:%02X\n", *(lpspg_info), *(lpspg_info + 1));
  8401. RTW_INFO("==== DBG_LPSPG_INFO_CMD_DUMP====\n");
  8402. #endif
  8403. ret = rtw_hal_fill_h2c_cmd(adapter,
  8404. H2C_LPS_PG_INFO,
  8405. H2C_LPS_PG_INFO_LEN,
  8406. lpspg_info);
  8407. return ret;
  8408. }
  8409. u8 rtw_hal_set_lps_pg_info(_adapter *adapter)
  8410. {
  8411. u8 ret = _FAIL;
  8412. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
  8413. if (pwrpriv->lpspg_rsvd_page_locate == 0) {
  8414. RTW_ERR("%s [ERROR] lpspg_rsvd_page_locate = 0\n", __func__);
  8415. rtw_warn_on(1);
  8416. return ret;
  8417. }
  8418. rtw_hal_set_lps_pg_info_rsvd_page(adapter);
  8419. ret = rtw_hal_set_lps_pg_info_cmd(adapter);
  8420. if (_SUCCESS == ret)
  8421. pwrpriv->blpspg_info_up = _FALSE;
  8422. return ret;
  8423. }
  8424. void rtw_hal_lps_pg_rssi_lv_decide(_adapter *adapter, struct sta_info *sta)
  8425. {
  8426. #if 0
  8427. if (sta->cmn.ra_info.rssi_level >= 4)
  8428. sta->lps_pg_rssi_lv = 3; /*RSSI High - 1SS_VHT_MCS7*/
  8429. else if (sta->cmn.ra_info.rssi_level >= 2)
  8430. sta->lps_pg_rssi_lv = 2; /*RSSI Middle - 1SS_VHT_MCS3*/
  8431. else
  8432. sta->lps_pg_rssi_lv = 1; /*RSSI Lower - Lowest_rate*/
  8433. #else
  8434. sta->lps_pg_rssi_lv = 0;
  8435. #endif
  8436. RTW_INFO("%s mac-id:%d, rssi:%d, rssi_level:%d, lps_pg_rssi_lv:%d\n",
  8437. __func__, sta->cmn.mac_id, sta->cmn.rssi_stat.rssi, sta->cmn.ra_info.rssi_level, sta->lps_pg_rssi_lv);
  8438. }
  8439. void rtw_hal_lps_pg_handler(_adapter *adapter, enum lps_pg_hdl_id hdl_id)
  8440. {
  8441. struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
  8442. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  8443. struct sta_priv *pstapriv = &adapter->stapriv;
  8444. struct sta_info *sta;
  8445. sta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
  8446. switch (hdl_id) {
  8447. case LPS_PG_INFO_CFG:
  8448. rtw_hal_set_lps_pg_info(adapter);
  8449. break;
  8450. case LPS_PG_REDLEMEM:
  8451. {
  8452. /*set xmit_block*/
  8453. rtw_set_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
  8454. if (_FAIL == rtw_hal_fw_mem_dl(adapter, FW_EMEM))
  8455. rtw_warn_on(1);
  8456. /*clearn xmit_block*/
  8457. rtw_clr_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
  8458. }
  8459. break;
  8460. case LPS_PG_PHYDM_DIS:/*Disable RA and PT by H2C*/
  8461. if (sta)
  8462. rtw_phydm_lps_pg_hdl(adapter, sta, _TRUE);
  8463. break;
  8464. case LPS_PG_PHYDM_EN:/*Enable RA and PT by H2C*/
  8465. {
  8466. if (sta) {
  8467. rtw_hal_lps_pg_rssi_lv_decide(adapter, sta);
  8468. rtw_phydm_lps_pg_hdl(adapter, sta, _FALSE);
  8469. sta->lps_pg_rssi_lv = 0;
  8470. }
  8471. }
  8472. break;
  8473. default:
  8474. break;
  8475. }
  8476. }
  8477. #endif /*CONFIG_LPS_PG*/
  8478. static u8 _rtw_mi_assoc_if_num(_adapter *adapter)
  8479. {
  8480. u8 mi_iface_num = 0;
  8481. if (0) {
  8482. RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", DEV_STA_LD_NUM(adapter_to_dvobj(adapter)));
  8483. RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", DEV_AP_NUM(adapter_to_dvobj(adapter)));
  8484. RTW_INFO("[IFS_ASSOC_STATUS] - AP starting :%d", DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
  8485. RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", DEV_MESH_NUM(adapter_to_dvobj(adapter)));
  8486. RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", DEV_ADHOC_NUM(adapter_to_dvobj(adapter)));
  8487. /*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", DEV_P2P_GC_NUM(adapter_to_dvobj(adapter)));*/
  8488. /*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", DEV_P2P_GO_NUM(adapter_to_dvobj(adapter)));*/
  8489. }
  8490. mi_iface_num = (DEV_STA_LD_NUM(adapter_to_dvobj(adapter)) +
  8491. DEV_AP_NUM(adapter_to_dvobj(adapter)) +
  8492. DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
  8493. return mi_iface_num;
  8494. }
  8495. static _adapter *_rtw_search_sta_iface(_adapter *adapter)
  8496. {
  8497. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  8498. _adapter *iface = NULL;
  8499. _adapter *sta_iface = NULL;
  8500. int i;
  8501. for (i = 0; i < dvobj->iface_nums; i++) {
  8502. iface = dvobj->padapters[i];
  8503. if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
  8504. if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE) {
  8505. sta_iface = iface;
  8506. break;
  8507. }
  8508. }
  8509. }
  8510. return sta_iface;
  8511. }
  8512. #ifdef CONFIG_AP_MODE
  8513. static _adapter *_rtw_search_ap_iface(_adapter *adapter)
  8514. {
  8515. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  8516. _adapter *iface = NULL;
  8517. _adapter *ap_iface = NULL;
  8518. int i;
  8519. for (i = 0; i < dvobj->iface_nums; i++) {
  8520. iface = dvobj->padapters[i];
  8521. if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
  8522. ap_iface = iface;
  8523. break;
  8524. }
  8525. }
  8526. return ap_iface;
  8527. }
  8528. #endif
  8529. /*
  8530. * Description: Fill the reserved packets that FW will use to RSVD page.
  8531. * Now we just send 4 types packet to rsvd page.
  8532. * (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
  8533. * Input:
  8534. * finished - FALSE:At the first time we will send all the packets as a large packet to Hw,
  8535. * so we need to set the packet length to total lengh.
  8536. * TRUE: At the second time, we should send the first packet (default:beacon)
  8537. * to Hw again and set the lengh in descriptor to the real beacon lengh.
  8538. * page_num - The amount of reserved page which driver need.
  8539. * If this is not NULL, this function doesn't real download reserved
  8540. * page, but just count the number of reserved page.
  8541. *
  8542. * 2009.10.15 by tynli.
  8543. * 2017.06.20 modified by Lucas.
  8544. *
  8545. * Page Size = 128: 8188e, 8723a/b, 8192c/d,
  8546. * Page Size = 256: 8192e, 8821a
  8547. * Page Size = 512: 8812a
  8548. */
  8549. /*#define DBG_DUMP_SET_RSVD_PAGE*/
  8550. static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page_num)
  8551. {
  8552. PHAL_DATA_TYPE pHalData;
  8553. struct xmit_frame *pcmdframe = NULL;
  8554. struct pkt_attrib *pattrib;
  8555. struct xmit_priv *pxmitpriv;
  8556. struct pwrctrl_priv *pwrctl;
  8557. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  8558. struct hal_ops *pHalFunc = &adapter->hal_func;
  8559. u32 BeaconLength = 0, ProbeRspLength = 0, PSPollLength = 0;
  8560. u32 NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;
  8561. u32 ProbeReqLength = 0, NullFunctionDataLength = 0;
  8562. u8 TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
  8563. u8 TotalPageNum = 0 , CurtPktPageNum = 0 , RsvdPageNum = 0;
  8564. u8 *ReservedPagePacket;
  8565. u16 BufIndex = 0;
  8566. u32 TotalPacketLen = 0, MaxRsvdPageBufSize = 0, PageSize = 0;
  8567. RSVDPAGE_LOC RsvdPageLoc;
  8568. #ifdef DBG_FW_DEBUG_MSG_PKT
  8569. u32 fw_dbg_msg_pkt_len = 0;
  8570. #endif /*DBG_FW_DEBUG_MSG_PKT*/
  8571. #ifdef DBG_CONFIG_ERROR_DETECT
  8572. struct sreset_priv *psrtpriv;
  8573. #endif /* DBG_CONFIG_ERROR_DETECT */
  8574. #ifdef CONFIG_MCC_MODE
  8575. u8 dl_mcc_page = _FAIL;
  8576. #endif /* CONFIG_MCC_MODE */
  8577. u8 nr_assoc_if;
  8578. _adapter *sta_iface = NULL;
  8579. _adapter *ap_iface = NULL;
  8580. bool is_wow_mode = _FALSE;
  8581. pHalData = GET_HAL_DATA(adapter);
  8582. #ifdef DBG_CONFIG_ERROR_DETECT
  8583. psrtpriv = &pHalData->srestpriv;
  8584. #endif
  8585. pxmitpriv = &adapter->xmitpriv;
  8586. pwrctl = adapter_to_pwrctl(adapter);
  8587. rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
  8588. if (PageSize == 0) {
  8589. RTW_ERR("[Error]: %s, PageSize is zero!!\n", __func__);
  8590. return;
  8591. }
  8592. nr_assoc_if = _rtw_mi_assoc_if_num(adapter);
  8593. if ((pwrctl->wowlan_mode == _TRUE && pwrctl->wowlan_in_resume == _FALSE) ||
  8594. pwrctl->wowlan_ap_mode == _TRUE ||
  8595. pwrctl->wowlan_p2p_mode == _TRUE)
  8596. is_wow_mode = _TRUE;
  8597. /*page_num for init time to get rsvd page number*/
  8598. /* Prepare ReservedPagePacket */
  8599. if (page_num) {
  8600. ReservedPagePacket = rtw_zmalloc(MAX_CMDBUF_SZ);
  8601. if (!ReservedPagePacket) {
  8602. RTW_WARN("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
  8603. *page_num = 0xFF;
  8604. return;
  8605. }
  8606. RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm ==>\n",
  8607. FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
  8608. } else {
  8609. if (is_wow_mode)
  8610. RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
  8611. else
  8612. RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
  8613. RTW_INFO(FUNC_ADPT_FMT" PageSize: %d, [ %s ]-RsvdPageNUm: %d\n",
  8614. FUNC_ADPT_ARG(adapter), PageSize, (is_wow_mode) ? "WOW" : "NOR", RsvdPageNum);
  8615. MaxRsvdPageBufSize = RsvdPageNum * PageSize;
  8616. if (MaxRsvdPageBufSize > MAX_CMDBUF_SZ) {
  8617. RTW_ERR("%s MaxRsvdPageBufSize(%d) is larger than MAX_CMDBUF_SZ(%d)",
  8618. __func__, MaxRsvdPageBufSize, MAX_CMDBUF_SZ);
  8619. rtw_warn_on(1);
  8620. return;
  8621. }
  8622. pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
  8623. if (pcmdframe == NULL) {
  8624. RTW_ERR("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
  8625. return;
  8626. }
  8627. ReservedPagePacket = pcmdframe->buf_addr;
  8628. }
  8629. _rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
  8630. BufIndex = TxDescOffset;
  8631. /*======== beacon content =======*/
  8632. rtw_hal_construct_beacon(adapter,
  8633. &ReservedPagePacket[BufIndex], &BeaconLength);
  8634. /*
  8635. * When we count the first page size, we need to reserve description size for the RSVD
  8636. * packet, it will be filled in front of the packet in TXPKTBUF.
  8637. */
  8638. BeaconLength = MAX_BEACON_LEN - TxDescLen;
  8639. CurtPktPageNum = (u8)PageNum((TxDescLen + BeaconLength), PageSize);
  8640. #ifdef CONFIG_FW_HANDLE_TXBCN
  8641. CurtPktPageNum = CurtPktPageNum * CONFIG_LIMITED_AP_NUM;
  8642. #endif
  8643. TotalPageNum += CurtPktPageNum;
  8644. BufIndex += (CurtPktPageNum * PageSize);
  8645. #ifdef DBG_RSVD_PAGE_CFG
  8646. RSVD_PAGE_CFG("Beacon", CurtPktPageNum, TotalPageNum, TotalPacketLen);
  8647. #endif
  8648. /*======== probe response content ========*/
  8649. if (pwrctl->wowlan_ap_mode == _TRUE) {/*WOW mode*/
  8650. #ifdef CONFIG_CONCURRENT_MODE
  8651. if (nr_assoc_if >= 2)
  8652. RTW_ERR("Not support > 2 net-interface in WOW\n");
  8653. #endif
  8654. /* (4) probe response*/
  8655. RsvdPageLoc.LocProbeRsp = TotalPageNum;
  8656. rtw_hal_construct_ProbeRsp(
  8657. adapter, &ReservedPagePacket[BufIndex],
  8658. &ProbeRspLength,
  8659. _FALSE);
  8660. rtw_hal_fill_fake_txdesc(adapter,
  8661. &ReservedPagePacket[BufIndex - TxDescLen],
  8662. ProbeRspLength, _FALSE, _FALSE, _FALSE);
  8663. CurtPktPageNum = (u8)PageNum(TxDescLen + ProbeRspLength, PageSize);
  8664. TotalPageNum += CurtPktPageNum;
  8665. TotalPacketLen = BufIndex + ProbeRspLength;
  8666. BufIndex += (CurtPktPageNum * PageSize);
  8667. #ifdef DBG_RSVD_PAGE_CFG
  8668. RSVD_PAGE_CFG("ProbeRsp", CurtPktPageNum, TotalPageNum, TotalPacketLen);
  8669. #endif
  8670. goto download_page;
  8671. }
  8672. /*======== ps-poll content * 1 page ========*/
  8673. sta_iface = adapter;
  8674. #ifdef CONFIG_CONCURRENT_MODE
  8675. if (!MLME_IS_STA(sta_iface) && DEV_STA_LD_NUM(adapter_to_dvobj(sta_iface))) {
  8676. sta_iface = _rtw_search_sta_iface(adapter);
  8677. RTW_INFO("get ("ADPT_FMT") to create PS-Poll/Null/QosNull\n", ADPT_ARG(sta_iface));
  8678. }
  8679. #endif
  8680. if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
  8681. RsvdPageLoc.LocPsPoll = TotalPageNum;
  8682. RTW_INFO("LocPsPoll: %d\n", RsvdPageLoc.LocPsPoll);
  8683. rtw_hal_construct_PSPoll(sta_iface,
  8684. &ReservedPagePacket[BufIndex], &PSPollLength);
  8685. rtw_hal_fill_fake_txdesc(sta_iface,
  8686. &ReservedPagePacket[BufIndex - TxDescLen],
  8687. PSPollLength, _TRUE, _FALSE, _FALSE);
  8688. CurtPktPageNum = (u8)PageNum((TxDescLen + PSPollLength), PageSize);
  8689. TotalPageNum += CurtPktPageNum;
  8690. BufIndex += (CurtPktPageNum * PageSize);
  8691. #ifdef DBG_RSVD_PAGE_CFG
  8692. RSVD_PAGE_CFG("PSPoll", CurtPktPageNum, TotalPageNum, TotalPacketLen);
  8693. #endif
  8694. }
  8695. #ifdef CONFIG_MCC_MODE
  8696. /*======== MCC * n page ======== */
  8697. if (MCC_EN(adapter)) {/*Normal mode*/
  8698. dl_mcc_page = rtw_hal_dl_mcc_fw_rsvd_page(adapter, ReservedPagePacket,
  8699. &BufIndex, TxDescLen, PageSize, &TotalPageNum, &RsvdPageLoc, page_num);
  8700. } else {
  8701. dl_mcc_page = _FAIL;
  8702. }
  8703. if (dl_mcc_page == _FAIL)
  8704. #endif /* CONFIG_MCC_MODE */
  8705. { /*======== null data * 1 page ======== */
  8706. if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
  8707. RsvdPageLoc.LocNullData = TotalPageNum;
  8708. RTW_INFO("LocNullData: %d\n", RsvdPageLoc.LocNullData);
  8709. rtw_hal_construct_NullFunctionData(
  8710. sta_iface,
  8711. &ReservedPagePacket[BufIndex],
  8712. &NullDataLength,
  8713. _FALSE, 0, 0, _FALSE);
  8714. rtw_hal_fill_fake_txdesc(sta_iface,
  8715. &ReservedPagePacket[BufIndex - TxDescLen],
  8716. NullDataLength, _FALSE, _FALSE, _FALSE);
  8717. CurtPktPageNum = (u8)PageNum(TxDescLen + NullDataLength, PageSize);
  8718. TotalPageNum += CurtPktPageNum;
  8719. BufIndex += (CurtPktPageNum * PageSize);
  8720. #ifdef DBG_RSVD_PAGE_CFG
  8721. RSVD_PAGE_CFG("NullData", CurtPktPageNum, TotalPageNum, TotalPacketLen);
  8722. #endif
  8723. }
  8724. }
  8725. /*======== Qos null data * 1 page ======== */
  8726. if (pwrctl->wowlan_mode == _FALSE ||
  8727. pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
  8728. if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
  8729. RsvdPageLoc.LocQosNull = TotalPageNum;
  8730. RTW_INFO("LocQosNull: %d\n", RsvdPageLoc.LocQosNull);
  8731. rtw_hal_construct_NullFunctionData(sta_iface,
  8732. &ReservedPagePacket[BufIndex],
  8733. &QosNullLength,
  8734. _TRUE, 0, 0, _FALSE);
  8735. rtw_hal_fill_fake_txdesc(sta_iface,
  8736. &ReservedPagePacket[BufIndex - TxDescLen],
  8737. QosNullLength, _FALSE, _FALSE, _FALSE);
  8738. CurtPktPageNum = (u8)PageNum(TxDescLen + QosNullLength,
  8739. PageSize);
  8740. TotalPageNum += CurtPktPageNum;
  8741. BufIndex += (CurtPktPageNum * PageSize);
  8742. #ifdef DBG_RSVD_PAGE_CFG
  8743. RSVD_PAGE_CFG("QosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
  8744. #endif
  8745. }
  8746. }
  8747. #ifdef CONFIG_BT_COEXIST
  8748. /*======== BT Qos null data * 1 page ======== */
  8749. if (pwrctl->wowlan_mode == _FALSE ||
  8750. pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
  8751. ap_iface = adapter;
  8752. #ifdef CONFIG_CONCURRENT_MODE
  8753. if (!MLME_IS_AP(ap_iface) && DEV_AP_NUM(adapter_to_dvobj(ap_iface))) { /*DEV_AP_STARTING_NUM*/
  8754. ap_iface = _rtw_search_ap_iface(adapter);
  8755. RTW_INFO("get ("ADPT_FMT") to create BTQoSNull\n", ADPT_ARG(ap_iface));
  8756. }
  8757. #endif
  8758. if (MLME_IS_AP(ap_iface) || (nr_assoc_if == 0)) {
  8759. RsvdPageLoc.LocBTQosNull = TotalPageNum;
  8760. RTW_INFO("LocBTQosNull: %d\n", RsvdPageLoc.LocBTQosNull);
  8761. rtw_hal_construct_NullFunctionData(ap_iface,
  8762. &ReservedPagePacket[BufIndex],
  8763. &BTQosNullLength,
  8764. _TRUE, 0, 0, _FALSE);
  8765. rtw_hal_fill_fake_txdesc(ap_iface,
  8766. &ReservedPagePacket[BufIndex - TxDescLen],
  8767. BTQosNullLength, _FALSE, _TRUE, _FALSE);
  8768. CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength,
  8769. PageSize);
  8770. TotalPageNum += CurtPktPageNum;
  8771. BufIndex += (CurtPktPageNum * PageSize);
  8772. #ifdef DBG_RSVD_PAGE_CFG
  8773. RSVD_PAGE_CFG("BTQosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
  8774. #endif
  8775. }
  8776. }
  8777. #endif /* CONFIG_BT_COEXIT */
  8778. TotalPacketLen = BufIndex;
  8779. #ifdef DBG_FW_DEBUG_MSG_PKT
  8780. /*======== FW DEBUG MSG * n page ======== */
  8781. RsvdPageLoc.loc_fw_dbg_msg_pkt = TotalPageNum;
  8782. RTW_INFO("loc_fw_dbg_msg_pkt: %d\n", RsvdPageLoc.loc_fw_dbg_msg_pkt);
  8783. rtw_hal_construct_fw_dbg_msg_pkt(
  8784. adapter,
  8785. &ReservedPagePacket[BufIndex],
  8786. &fw_dbg_msg_pkt_len);
  8787. rtw_hal_fill_fake_txdesc(adapter,
  8788. &ReservedPagePacket[BufIndex - TxDescLen],
  8789. fw_dbg_msg_pkt_len, _FALSE, _FALSE, _FALSE);
  8790. CurtPktPageNum = (u8)PageNum(TxDescLen + fw_dbg_msg_pkt_len, PageSize);
  8791. TotalPageNum += CurtPktPageNum;
  8792. TotalPacketLen = BufIndex + fw_dbg_msg_pkt_len;
  8793. BufIndex += (CurtPktPageNum * PageSize);
  8794. #endif /*DBG_FW_DEBUG_MSG_PKT*/
  8795. #ifdef CONFIG_WOWLAN
  8796. /*======== WOW * n page ======== */
  8797. if (pwrctl->wowlan_mode == _TRUE &&
  8798. pwrctl->wowlan_in_resume == _FALSE) {/*WOW mode*/
  8799. rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket,
  8800. BufIndex, TxDescLen, PageSize,
  8801. &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
  8802. }
  8803. #endif /* CONFIG_WOWLAN */
  8804. #ifdef CONFIG_P2P_WOWLAN
  8805. /*======== P2P WOW * n page ======== */
  8806. if (_TRUE == pwrctl->wowlan_p2p_mode) {/*WOW mode*/
  8807. rtw_hal_set_p2p_wow_fw_rsvd_page(adapter, ReservedPagePacket,
  8808. BufIndex, TxDescLen, PageSize,
  8809. &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
  8810. }
  8811. #endif /* CONFIG_P2P_WOWLAN */
  8812. #ifdef CONFIG_LPS_PG
  8813. /*======== LPS PG * 1 page ======== */
  8814. /* must reserved last 1 x page for LPS PG Info*/
  8815. pwrctl->lpspg_rsvd_page_locate = TotalPageNum;
  8816. pwrctl->blpspg_info_up = _TRUE;
  8817. if (page_num)
  8818. TotalPageNum += LPS_PG_INFO_RSVD_PAGE_NUM;
  8819. #ifdef DBG_RSVD_PAGE_CFG
  8820. RSVD_PAGE_CFG("LPS_PG", LPS_PG_INFO_RSVD_PAGE_NUM,
  8821. (page_num) ? TotalPageNum : (TotalPageNum + LPS_PG_INFO_RSVD_PAGE_NUM),
  8822. TotalPacketLen);
  8823. #endif
  8824. #endif
  8825. /*Note: BufIndex already add a TxDescOffset offset in first Beacon page
  8826. * The "TotalPacketLen" is calculate by BufIndex.
  8827. * We need to decrease TxDescOffset before doing length check. by yiwei
  8828. */
  8829. TotalPacketLen = TotalPacketLen - TxDescOffset;
  8830. download_page:
  8831. if (page_num) {
  8832. *page_num = TotalPageNum;
  8833. rtw_mfree(ReservedPagePacket, MAX_CMDBUF_SZ);
  8834. ReservedPagePacket = NULL;
  8835. RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm <==\n",
  8836. FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
  8837. return;
  8838. }
  8839. /* RTW_INFO("%s BufIndex(%d), TxDescLen(%d), PageSize(%d)\n",__func__, BufIndex, TxDescLen, PageSize);*/
  8840. RTW_INFO("%s PageNum(%d), pktlen(%d)\n",
  8841. __func__, TotalPageNum, TotalPacketLen);
  8842. #ifdef CONFIG_LPS_PG
  8843. if ((TotalPageNum + LPS_PG_INFO_RSVD_PAGE_NUM) > RsvdPageNum) {
  8844. pwrctl->lpspg_rsvd_page_locate = 0;
  8845. pwrctl->blpspg_info_up = _FALSE;
  8846. RTW_ERR("%s [LPS_PG] rsvd page %d is not enough! need %d pages\n",
  8847. __func__, RsvdPageNum, (TotalPageNum + LPS_PG_INFO_RSVD_PAGE_NUM));
  8848. rtw_warn_on(1);
  8849. }
  8850. #endif
  8851. if (TotalPacketLen > MaxRsvdPageBufSize) {
  8852. RTW_ERR("%s : rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
  8853. __FUNCTION__, TotalPacketLen, MaxRsvdPageBufSize);
  8854. rtw_warn_on(1);
  8855. goto error;
  8856. } else {
  8857. /* update attribute */
  8858. pattrib = &pcmdframe->attrib;
  8859. update_mgntframe_attrib(adapter, pattrib);
  8860. pattrib->qsel = QSLT_BEACON;
  8861. pattrib->pktlen = TotalPacketLen;
  8862. pattrib->last_txcmdsz = TotalPacketLen;
  8863. #ifdef CONFIG_PCI_HCI
  8864. dump_mgntframe(adapter, pcmdframe);
  8865. #else
  8866. dump_mgntframe_and_wait(adapter, pcmdframe, 100);
  8867. #endif
  8868. }
  8869. RTW_INFO("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n",
  8870. __func__, TotalPacketLen, TotalPageNum);
  8871. #ifdef DBG_DUMP_SET_RSVD_PAGE
  8872. RTW_INFO(" ==================================================\n");
  8873. RTW_INFO_DUMP("\n", ReservedPagePacket, TotalPacketLen);
  8874. RTW_INFO(" ==================================================\n");
  8875. #endif
  8876. if (check_fwstate(pmlmepriv, _FW_LINKED)
  8877. || MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)){
  8878. rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc);
  8879. #ifdef DBG_FW_DEBUG_MSG_PKT
  8880. rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(adapter, &RsvdPageLoc);
  8881. #endif /*DBG_FW_DEBUG_MSG_PKT*/
  8882. #ifdef CONFIG_WOWLAN
  8883. if (pwrctl->wowlan_mode == _TRUE &&
  8884. pwrctl->wowlan_in_resume == _FALSE)
  8885. rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
  8886. #endif /* CONFIG_WOWLAN */
  8887. #ifdef CONFIG_AP_WOWLAN
  8888. if (pwrctl->wowlan_ap_mode == _TRUE)
  8889. rtw_hal_set_ap_rsvdpage_loc_cmd(adapter, &RsvdPageLoc);
  8890. #endif /* CONFIG_AP_WOWLAN */
  8891. } else if (pwrctl->wowlan_pno_enable) {
  8892. #ifdef CONFIG_PNO_SUPPORT
  8893. rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
  8894. if (pwrctl->wowlan_in_resume)
  8895. rtw_hal_set_scan_offload_info_cmd(adapter,
  8896. &RsvdPageLoc, 0);
  8897. else
  8898. rtw_hal_set_scan_offload_info_cmd(adapter,
  8899. &RsvdPageLoc, 1);
  8900. #endif /* CONFIG_PNO_SUPPORT */
  8901. }
  8902. #ifdef CONFIG_P2P_WOWLAN
  8903. if (_TRUE == pwrctl->wowlan_p2p_mode)
  8904. rtw_hal_set_FwP2PRsvdPage_cmd(adapter, &RsvdPageLoc);
  8905. #endif /* CONFIG_P2P_WOWLAN */
  8906. return;
  8907. error:
  8908. rtw_free_xmitframe(pxmitpriv, pcmdframe);
  8909. }
  8910. void rtw_hal_set_fw_rsvd_page(struct _ADAPTER *adapter, bool finished)
  8911. {
  8912. if (finished)
  8913. rtw_mi_tx_beacon_hdl(adapter);
  8914. else
  8915. _rtw_hal_set_fw_rsvd_page(adapter, finished, NULL);
  8916. }
  8917. /**
  8918. * rtw_hal_get_rsvd_page_num() - Get needed reserved page number
  8919. * @adapter: struct _ADAPTER*
  8920. *
  8921. * Caculate needed reserved page number.
  8922. * In different state would get different number, for example normal mode and
  8923. * WOW mode would need different reserved page size.
  8924. *
  8925. * Return the number of reserved page which driver need.
  8926. */
  8927. u8 rtw_hal_get_rsvd_page_num(struct _ADAPTER *adapter)
  8928. {
  8929. u8 num = 0;
  8930. _rtw_hal_set_fw_rsvd_page(adapter, _FALSE, &num);
  8931. return num;
  8932. }
  8933. static void hw_var_set_bcn_func(_adapter *adapter, u8 enable)
  8934. {
  8935. u32 bcn_ctrl_reg;
  8936. #ifdef CONFIG_CONCURRENT_MODE
  8937. if (adapter->hw_port == HW_PORT1)
  8938. bcn_ctrl_reg = REG_BCN_CTRL_1;
  8939. else
  8940. #endif
  8941. bcn_ctrl_reg = REG_BCN_CTRL;
  8942. if (enable)
  8943. rtw_write8(adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
  8944. else {
  8945. u8 val8;
  8946. val8 = rtw_read8(adapter, bcn_ctrl_reg);
  8947. val8 &= ~(EN_BCN_FUNCTION | EN_TXBCN_RPT);
  8948. #ifdef CONFIG_BT_COEXIST
  8949. if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1) {
  8950. /* Always enable port0 beacon function for PSTDMA */
  8951. if (REG_BCN_CTRL == bcn_ctrl_reg)
  8952. val8 |= EN_BCN_FUNCTION;
  8953. }
  8954. #endif
  8955. rtw_write8(adapter, bcn_ctrl_reg, val8);
  8956. }
  8957. #ifdef CONFIG_RTL8192F
  8958. if (IS_HARDWARE_TYPE_8192F(adapter)) {
  8959. u16 val16, val16_ori;
  8960. val16_ori = val16 = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
  8961. #ifdef CONFIG_CONCURRENT_MODE
  8962. if (adapter->hw_port == HW_PORT1) {
  8963. if (enable)
  8964. val16 |= EN_PORT_1_FUNCTION;
  8965. else
  8966. val16 &= ~EN_PORT_1_FUNCTION;
  8967. } else
  8968. #endif
  8969. {
  8970. if (enable)
  8971. val16 |= EN_PORT_0_FUNCTION;
  8972. else
  8973. val16 &= ~EN_PORT_0_FUNCTION;
  8974. #ifdef CONFIG_BT_COEXIST
  8975. if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1)
  8976. val16 |= EN_PORT_0_FUNCTION;
  8977. #endif
  8978. }
  8979. if (val16 != val16_ori)
  8980. rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, val16);
  8981. }
  8982. #endif
  8983. }
  8984. static void hw_var_set_mlme_disconnect(_adapter *adapter)
  8985. {
  8986. u8 val8;
  8987. /* reject all data frames */
  8988. #ifdef CONFIG_CONCURRENT_MODE
  8989. if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
  8990. #endif
  8991. rtw_write16(adapter, REG_RXFLTMAP2, 0x0000);
  8992. #ifdef CONFIG_CONCURRENT_MODE
  8993. if (adapter->hw_port == HW_PORT1) {
  8994. /* reset TSF1 */
  8995. rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1));
  8996. /* disable update TSF1 */
  8997. rtw_iface_disable_tsf_update(adapter);
  8998. if (!IS_HARDWARE_TYPE_8723D(adapter)
  8999. && !IS_HARDWARE_TYPE_8192F(adapter)
  9000. && !IS_HARDWARE_TYPE_8710B(adapter)
  9001. ) {
  9002. /* disable Port1's beacon function */
  9003. val8 = rtw_read8(adapter, REG_BCN_CTRL_1);
  9004. val8 &= ~EN_BCN_FUNCTION;
  9005. rtw_write8(adapter, REG_BCN_CTRL_1, val8);
  9006. }
  9007. } else
  9008. #endif
  9009. {
  9010. /* reset TSF */
  9011. rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
  9012. /* disable update TSF */
  9013. rtw_iface_disable_tsf_update(adapter);
  9014. }
  9015. }
  9016. static void hw_var_set_mlme_sitesurvey(_adapter *adapter, u8 enable)
  9017. {
  9018. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  9019. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
  9020. u16 value_rxfltmap2;
  9021. int i;
  9022. _adapter *iface;
  9023. #ifdef DBG_IFACE_STATUS
  9024. DBG_IFACE_STATUS_DUMP(adapter);
  9025. #endif
  9026. #ifdef CONFIG_FIND_BEST_CHANNEL
  9027. /* Receive all data frames */
  9028. value_rxfltmap2 = 0xFFFF;
  9029. #else
  9030. /* not to receive data frame */
  9031. value_rxfltmap2 = 0;
  9032. #endif
  9033. if (enable) { /* under sitesurvey */
  9034. /*
  9035. * 1. configure REG_RXFLTMAP2
  9036. * 2. disable TSF update & buddy TSF update to avoid updating wrong TSF due to clear RCR_CBSSID_BCN
  9037. * 3. config RCR to receive different BSSID BCN or probe rsp
  9038. */
  9039. rtw_write16(adapter, REG_RXFLTMAP2, value_rxfltmap2);
  9040. rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_ENTER);
  9041. /* Save orignal RRSR setting. needed? */
  9042. hal_data->RegRRSR = rtw_read16(adapter, REG_RRSR);
  9043. #if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
  9044. if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
  9045. /* set 718[1:0]=2'b00 to avoid BF scan hang */
  9046. hal_data->backup_snd_ptcl_ctrl = rtw_read8(adapter, REG_SND_PTCL_CTRL_8812A);
  9047. rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, (hal_data->backup_snd_ptcl_ctrl & 0xfc));
  9048. }
  9049. #endif
  9050. if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
  9051. StopTxBeacon(adapter);
  9052. } else { /* sitesurvey done */
  9053. /*
  9054. * 1. enable rx data frame
  9055. * 2. config RCR not to receive different BSSID BCN or probe rsp
  9056. * 3. doesn't enable TSF update & buddy TSF right now to avoid HW conflict
  9057. * so, we enable TSF update when rx first BCN after sitesurvey done
  9058. */
  9059. if (rtw_mi_check_fwstate(adapter, _FW_LINKED | WIFI_AP_STATE | WIFI_MESH_STATE)) {
  9060. /* enable to rx data frame */
  9061. rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
  9062. }
  9063. rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_DONE);
  9064. /* Restore orignal RRSR setting. needed? */
  9065. rtw_write16(adapter, REG_RRSR, hal_data->RegRRSR);
  9066. #if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
  9067. if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
  9068. /* Restore orignal 0x718 setting*/
  9069. rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, hal_data->backup_snd_ptcl_ctrl);
  9070. }
  9071. #endif
  9072. if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
  9073. ResumeTxBeacon(adapter);
  9074. rtw_mi_tx_beacon_hdl(adapter);
  9075. }
  9076. }
  9077. }
  9078. static void hw_var_set_mlme_join(_adapter *adapter, u8 type)
  9079. {
  9080. u8 val8;
  9081. u16 val16;
  9082. u32 val32;
  9083. u8 RetryLimit = RL_VAL_STA;
  9084. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
  9085. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  9086. #ifdef CONFIG_CONCURRENT_MODE
  9087. if (type == 0) {
  9088. /* prepare to join */
  9089. if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
  9090. StopTxBeacon(adapter);
  9091. /* enable to rx data frame.Accept all data frame */
  9092. rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
  9093. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
  9094. RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
  9095. else /* Ad-hoc Mode */
  9096. RetryLimit = RL_VAL_AP;
  9097. rtw_iface_enable_tsf_update(adapter);
  9098. } else if (type == 1) {
  9099. /* joinbss_event call back when join res < 0 */
  9100. if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
  9101. rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
  9102. rtw_iface_disable_tsf_update(adapter);
  9103. if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
  9104. ResumeTxBeacon(adapter);
  9105. /* reset TSF 1/2 after ResumeTxBeacon */
  9106. rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
  9107. }
  9108. } else if (type == 2) {
  9109. /* sta add event call back */
  9110. if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
  9111. /* fixed beacon issue for 8191su........... */
  9112. rtw_write8(adapter, 0x542 , 0x02);
  9113. RetryLimit = RL_VAL_AP;
  9114. }
  9115. if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
  9116. ResumeTxBeacon(adapter);
  9117. /* reset TSF 1/2 after ResumeTxBeacon */
  9118. rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
  9119. }
  9120. }
  9121. val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
  9122. rtw_write16(adapter, REG_RETRY_LIMIT, val16);
  9123. #else /* !CONFIG_CONCURRENT_MODE */
  9124. if (type == 0) { /* prepare to join */
  9125. /* enable to rx data frame.Accept all data frame */
  9126. rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
  9127. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
  9128. RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
  9129. else /* Ad-hoc Mode */
  9130. RetryLimit = RL_VAL_AP;
  9131. rtw_iface_enable_tsf_update(adapter);
  9132. } else if (type == 1) { /* joinbss_event call back when join res < 0 */
  9133. rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
  9134. rtw_iface_disable_tsf_update(adapter);
  9135. } else if (type == 2) { /* sta add event call back */
  9136. if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
  9137. RetryLimit = RL_VAL_AP;
  9138. }
  9139. val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
  9140. rtw_write16(adapter, REG_RETRY_LIMIT, val16);
  9141. #endif /* !CONFIG_CONCURRENT_MODE */
  9142. }
  9143. #ifdef CONFIG_TSF_RESET_OFFLOAD
  9144. static int rtw_hal_h2c_reset_tsf(_adapter *adapter, u8 reset_port)
  9145. {
  9146. u8 buf[2];
  9147. int ret;
  9148. if (reset_port == HW_PORT0) {
  9149. buf[0] = 0x1;
  9150. buf[1] = 0;
  9151. } else {
  9152. buf[0] = 0x0;
  9153. buf[1] = 0x1;
  9154. }
  9155. ret = rtw_hal_fill_h2c_cmd(adapter, H2C_RESET_TSF, 2, buf);
  9156. return ret;
  9157. }
  9158. int rtw_hal_reset_tsf(_adapter *adapter, u8 reset_port)
  9159. {
  9160. u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
  9161. u32 reg_reset_tsf_cnt = (reset_port == HW_PORT0) ?
  9162. REG_FW_RESET_TSF_CNT_0 : REG_FW_RESET_TSF_CNT_1;
  9163. int ret;
  9164. /* site survey will cause reset tsf fail */
  9165. rtw_mi_buddy_scan_abort(adapter, _FALSE);
  9166. reset_cnt_after = reset_cnt_before = rtw_read8(adapter, reg_reset_tsf_cnt);
  9167. ret = rtw_hal_h2c_reset_tsf(adapter, reset_port);
  9168. if (ret != _SUCCESS)
  9169. return ret;
  9170. while ((reset_cnt_after == reset_cnt_before) && (loop_cnt < 10)) {
  9171. rtw_msleep_os(100);
  9172. loop_cnt++;
  9173. reset_cnt_after = rtw_read8(adapter, reg_reset_tsf_cnt);
  9174. }
  9175. return (loop_cnt >= 10) ? _FAIL : _SUCCESS;
  9176. }
  9177. #endif /* CONFIG_TSF_RESET_OFFLOAD */
  9178. #ifdef CONFIG_HW_P0_TSF_SYNC
  9179. #ifdef CONFIG_CONCURRENT_MODE
  9180. static void hw_port0_tsf_sync_sel(_adapter *adapter, u8 benable, u8 hw_port, u16 tr_offset)
  9181. {
  9182. u8 val8;
  9183. u8 client_id = 0;
  9184. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  9185. #ifdef CONFIG_MCC_MODE
  9186. if (MCC_EN(adapter) && (rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC))) {
  9187. RTW_INFO("[MCC] do not set HW TSF sync\n");
  9188. return;
  9189. }
  9190. #endif
  9191. /* check if port0 is already synced */
  9192. if (benable && dvobj->p0_tsf.sync_port != MAX_HW_PORT && dvobj->p0_tsf.sync_port == hw_port) {
  9193. RTW_WARN(FUNC_ADPT_FMT ": port0 already enable TSF sync(%d)\n",
  9194. FUNC_ADPT_ARG(adapter), dvobj->p0_tsf.sync_port);
  9195. return;
  9196. }
  9197. /* check if port0 already disable sync */
  9198. if (!benable && dvobj->p0_tsf.sync_port == MAX_HW_PORT) {
  9199. RTW_WARN(FUNC_ADPT_FMT ": port0 already disable TSF sync\n", FUNC_ADPT_ARG(adapter));
  9200. return;
  9201. }
  9202. /* check if port0 sync to port0 */
  9203. if (benable && hw_port == HW_PORT0) {
  9204. RTW_ERR(FUNC_ADPT_FMT ": hw_port is port0 under enable\n", FUNC_ADPT_ARG(adapter));
  9205. rtw_warn_on(1);
  9206. return;
  9207. }
  9208. /*0x5B4 [6:4] :SYNC_CLI_SEL - The selector for the CLINT port of sync tsft source for port 0*/
  9209. /* Bit[5:4] : 0 for clint0, 1 for clint1, 2 for clint2, 3 for clint3.
  9210. Bit6 : 1= enable sync to port 0. 0=disable sync to port 0.*/
  9211. val8 = rtw_read8(adapter, REG_TIMER0_SRC_SEL);
  9212. if (benable) {
  9213. /*Disable Port0's beacon function*/
  9214. rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
  9215. /*Reg 0x518[15:0]: TSFTR_SYN_OFFSET*/
  9216. if (tr_offset)
  9217. rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, tr_offset);
  9218. /*reg 0x577[6]=1*/ /*auto sync by tbtt*/
  9219. rtw_write8(adapter, REG_MISC_CTRL, rtw_read8(adapter, REG_MISC_CTRL) | BIT_AUTO_SYNC_BY_TBTT);
  9220. if (HW_PORT1 == hw_port)
  9221. client_id = 0;
  9222. else if (HW_PORT2 == hw_port)
  9223. client_id = 1;
  9224. else if (HW_PORT3 == hw_port)
  9225. client_id = 2;
  9226. else if (HW_PORT4 == hw_port)
  9227. client_id = 3;
  9228. val8 &= 0x8F;
  9229. val8 |= (BIT(6) | (client_id << 4));
  9230. dvobj->p0_tsf.sync_port = hw_port;
  9231. dvobj->p0_tsf.offset = tr_offset;
  9232. rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
  9233. /*Enable Port0's beacon function*/
  9234. rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) | BIT_EN_BCN_FUNCTION);
  9235. RTW_INFO("%s Port_%d TSF sync to P0, timer offset :%d\n", __func__, hw_port, tr_offset);
  9236. } else {
  9237. val8 &= ~BIT(6);
  9238. dvobj->p0_tsf.sync_port = MAX_HW_PORT;
  9239. dvobj->p0_tsf.offset = 0;
  9240. rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
  9241. RTW_INFO("%s P0 TSF sync disable\n", __func__);
  9242. }
  9243. }
  9244. static _adapter * _search_ld_sta(_adapter *adapter, u8 include_self)
  9245. {
  9246. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  9247. u8 i;
  9248. _adapter *iface = NULL;
  9249. if (rtw_mi_get_assoced_sta_num(adapter) == 0) {
  9250. RTW_ERR("STA_LD_NUM == 0\n");
  9251. rtw_warn_on(1);
  9252. }
  9253. for (i = 0; i < dvobj->iface_nums; i++) {
  9254. iface = dvobj->padapters[i];
  9255. if (!iface)
  9256. continue;
  9257. if (include_self == _FALSE && adapter == iface)
  9258. continue;
  9259. if (is_client_associated_to_ap(iface))
  9260. break;
  9261. }
  9262. if (iface)
  9263. RTW_INFO("search STA iface -"ADPT_FMT"\n", ADPT_ARG(iface));
  9264. return iface;
  9265. }
  9266. #endif /*CONFIG_CONCURRENT_MODE*/
  9267. /*Correct port0's TSF*/
  9268. /*#define DBG_P0_TSF_SYNC*/
  9269. void hw_var_set_correct_tsf(PADAPTER adapter, u8 mlme_state)
  9270. {
  9271. #ifdef CONFIG_CONCURRENT_MODE
  9272. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  9273. u8 p0_tsfsync = _FALSE;
  9274. struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
  9275. struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
  9276. _adapter *sta_if = NULL;
  9277. u8 hw_port;
  9278. RTW_INFO(FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(adapter));
  9279. #ifdef DBG_P0_TSF_SYNC
  9280. RTW_INFO("[TSF_SYNC] AP_NUM = %d\n", rtw_mi_get_ap_num(adapter));
  9281. RTW_INFO("[TSF_SYNC] MESH_NUM = %d\n", rtw_mi_get_mesh_num(adapter));
  9282. RTW_INFO("[TSF_SYNC] LD_STA_NUM = %d\n", rtw_mi_get_assoced_sta_num(adapter));
  9283. if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
  9284. RTW_INFO("[TSF_SYNC] org p0 sync port = N/A\n");
  9285. else
  9286. RTW_INFO("[TSF_SYNC] org p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
  9287. RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
  9288. #endif
  9289. switch (mlme_state) {
  9290. case MLME_STA_CONNECTED :
  9291. {
  9292. hw_port = rtw_hal_get_port(adapter);
  9293. if (!MLME_IS_STA(adapter)) {
  9294. RTW_ERR("STA CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
  9295. rtw_warn_on(1);
  9296. }
  9297. if ((dvobj->p0_tsf.sync_port != MAX_HW_PORT) && (hw_port == HW_PORT0)) {
  9298. RTW_ERR(ADPT_FMT" is STA with P0 connected => DIS P0_TSF_SYNC\n", ADPT_ARG(adapter));
  9299. rtw_warn_on(1);
  9300. hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
  9301. }
  9302. if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
  9303. (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))) {
  9304. hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
  9305. #ifdef DBG_P0_TSF_SYNC
  9306. RTW_INFO("[TSF_SYNC] STA_LINKED => EN P0_TSF_SYNC\n");
  9307. #endif
  9308. }
  9309. }
  9310. break;
  9311. case MLME_STA_DISCONNECTED :
  9312. {
  9313. hw_port = rtw_hal_get_port(adapter);
  9314. if (!MLME_IS_STA(adapter)) {
  9315. RTW_ERR("STA DIS_CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
  9316. rtw_warn_on(1);
  9317. }
  9318. if (dvobj->p0_tsf.sync_port == hw_port) {
  9319. if (rtw_mi_get_assoced_sta_num(adapter) >= 2) {
  9320. /* search next appropriate sta*/
  9321. sta_if = _search_ld_sta(adapter, _FALSE);
  9322. if (sta_if) {
  9323. hw_port = rtw_hal_get_port(sta_if);
  9324. hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
  9325. #ifdef DBG_P0_TSF_SYNC
  9326. RTW_INFO("[TSF_SYNC] STA_DIS_CON => CHANGE P0_TSF_SYNC\n");
  9327. #endif
  9328. }
  9329. } else if (rtw_mi_get_assoced_sta_num(adapter) == 1) {
  9330. hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
  9331. #ifdef DBG_P0_TSF_SYNC
  9332. RTW_INFO("[TSF_SYNC] STA_DIS_CON => DIS P0_TSF_SYNC\n");
  9333. #endif
  9334. }
  9335. }
  9336. }
  9337. break;
  9338. case MLME_AP_STARTED :
  9339. case MLME_MESH_STARTED :
  9340. {
  9341. if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
  9342. RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
  9343. rtw_warn_on(1);
  9344. }
  9345. if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
  9346. rtw_mi_get_assoced_sta_num(adapter)) {
  9347. /* get port of sta */
  9348. sta_if = _search_ld_sta(adapter, _FALSE);
  9349. if (sta_if) {
  9350. hw_port = rtw_hal_get_port(sta_if);
  9351. hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
  9352. #ifdef DBG_P0_TSF_SYNC
  9353. RTW_INFO("[TSF_SYNC] AP_START => EN P0_TSF_SYNC\n");
  9354. #endif
  9355. }
  9356. }
  9357. }
  9358. break;
  9359. case MLME_AP_STOPPED :
  9360. case MLME_MESH_STOPPED :
  9361. {
  9362. if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
  9363. RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
  9364. rtw_warn_on(1);
  9365. }
  9366. /*stop ap mode*/
  9367. if ((rtw_mi_get_ap_num(adapter) + rtw_mi_get_mesh_num(adapter) == 1) &&
  9368. (dvobj->p0_tsf.sync_port != MAX_HW_PORT)) {
  9369. hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
  9370. #ifdef DBG_P0_TSF_SYNC
  9371. RTW_INFO("[TSF_SYNC] AP_STOP => DIS P0_TSF_SYNC\n");
  9372. #endif
  9373. }
  9374. }
  9375. break;
  9376. default :
  9377. RTW_ERR(FUNC_ADPT_FMT" unknow state(0x%02x)\n", FUNC_ADPT_ARG(adapter), mlme_state);
  9378. break;
  9379. }
  9380. /*#ifdef DBG_P0_TSF_SYNC*/
  9381. #if 1
  9382. if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
  9383. RTW_INFO("[TSF_SYNC] p0 sync port = N/A\n");
  9384. else
  9385. RTW_INFO("[TSF_SYNC] p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
  9386. RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
  9387. #endif
  9388. #endif /*CONFIG_CONCURRENT_MODE*/
  9389. }
  9390. #else
  9391. static void rtw_hal_correct_tsf(_adapter *padapter, u8 hw_port, u64 tsf)
  9392. {
  9393. if (hw_port == HW_PORT0) {
  9394. /*disable related TSF function*/
  9395. rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~EN_BCN_FUNCTION));
  9396. #if defined(CONFIG_RTL8192F)
  9397. rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
  9398. REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_0_FUNCTION);
  9399. #endif
  9400. rtw_write32(padapter, REG_TSFTR, tsf);
  9401. rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32);
  9402. /*enable related TSF function*/
  9403. rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | EN_BCN_FUNCTION);
  9404. #if defined(CONFIG_RTL8192F)
  9405. rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
  9406. REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
  9407. #endif
  9408. } else if (hw_port == HW_PORT1) {
  9409. /*disable related TSF function*/
  9410. rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~EN_BCN_FUNCTION));
  9411. #if defined(CONFIG_RTL8192F)
  9412. rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
  9413. REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_1_FUNCTION);
  9414. #endif
  9415. rtw_write32(padapter, REG_TSFTR1, tsf);
  9416. rtw_write32(padapter, REG_TSFTR1 + 4, tsf >> 32);
  9417. /*enable related TSF function*/
  9418. rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) | EN_BCN_FUNCTION);
  9419. #if defined(CONFIG_RTL8192F)
  9420. rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
  9421. REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_1_FUNCTION);
  9422. #endif
  9423. } else
  9424. RTW_INFO("%s-[WARN] "ADPT_FMT" invalid hw_port:%d\n", __func__, ADPT_ARG(padapter), hw_port);
  9425. }
  9426. static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
  9427. {
  9428. #ifdef CONFIG_MI_WITH_MBSSID_CAM
  9429. /*do nothing*/
  9430. #else
  9431. u64 tsf;
  9432. struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
  9433. struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
  9434. tsf = mlmeext->TSFValue - rtw_modular64(mlmeext->TSFValue, (mlmeinfo->bcn_interval * 1024)) - 1024; /*us*/
  9435. if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
  9436. || (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
  9437. StopTxBeacon(adapter);
  9438. rtw_hal_correct_tsf(adapter, adapter->hw_port, tsf);
  9439. #ifdef CONFIG_CONCURRENT_MODE
  9440. /* Update buddy port's TSF if it is SoftAP/Mesh for beacon TX issue! */
  9441. if ((mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE
  9442. && (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
  9443. ) {
  9444. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  9445. int i;
  9446. _adapter *iface;
  9447. for (i = 0; i < dvobj->iface_nums; i++) {
  9448. iface = dvobj->padapters[i];
  9449. if (!iface)
  9450. continue;
  9451. if (iface == adapter)
  9452. continue;
  9453. if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
  9454. && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
  9455. ) {
  9456. rtw_hal_correct_tsf(iface, iface->hw_port, tsf);
  9457. #ifdef CONFIG_TSF_RESET_OFFLOAD
  9458. if (rtw_hal_reset_tsf(iface, iface->hw_port) == _FAIL)
  9459. RTW_INFO("%s-[ERROR] "ADPT_FMT" Reset port%d TSF fail\n"
  9460. , __func__, ADPT_ARG(iface), iface->hw_port);
  9461. #endif /* CONFIG_TSF_RESET_OFFLOAD*/
  9462. }
  9463. }
  9464. }
  9465. #endif /* CONFIG_CONCURRENT_MODE */
  9466. if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
  9467. || (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
  9468. ResumeTxBeacon(adapter);
  9469. #endif /*CONFIG_MI_WITH_MBSSID_CAM*/
  9470. }
  9471. #endif
  9472. u64 rtw_hal_get_tsftr_by_port(_adapter *adapter, u8 port)
  9473. {
  9474. struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
  9475. u64 tsftr = 0;
  9476. if (port >= hal_spec->port_num) {
  9477. RTW_ERR("%s invalid port(%d) \n", __func__, port);
  9478. goto exit;
  9479. }
  9480. switch (rtw_get_chip_type(adapter)) {
  9481. #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C)
  9482. case RTL8814A:
  9483. case RTL8822B:
  9484. case RTL8821C:
  9485. {
  9486. u8 val8;
  9487. /* 0x554[30:28] - BIT_BCN_TIMER_SEL_FWRD */
  9488. val8 = rtw_read8(adapter, REG_MBSSID_BCN_SPACE + 3);
  9489. val8 &= 0x8F;
  9490. val8 |= port << 4;
  9491. rtw_write8(adapter, REG_MBSSID_BCN_SPACE + 3, val8);
  9492. tsftr = rtw_read32(adapter, REG_TSFTR + 4);
  9493. tsftr = tsftr << 32;
  9494. tsftr |= rtw_read32(adapter, REG_TSFTR);
  9495. break;
  9496. }
  9497. #endif
  9498. #if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV) \
  9499. || defined(CONFIG_RTL8192E) || defined(CONFIG_RTL8192F) \
  9500. || defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) \
  9501. || defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) \
  9502. || defined(CONFIG_RTL8710B)
  9503. case RTL8188E:
  9504. case RTL8188F:
  9505. case RTL8188GTV:
  9506. case RTL8192E:
  9507. case RTL8192F:
  9508. case RTL8723B:
  9509. case RTL8703B:
  9510. case RTL8723D:
  9511. case RTL8812:
  9512. case RTL8821:
  9513. case RTL8710B:
  9514. {
  9515. u32 addr;
  9516. if (port == HW_PORT0)
  9517. addr = REG_TSFTR;
  9518. else if (port == HW_PORT1)
  9519. addr = REG_TSFTR1;
  9520. else {
  9521. RTW_ERR("%s unknown port(%d) \n", __func__, port);
  9522. goto exit;
  9523. }
  9524. tsftr = rtw_read32(adapter, addr + 4);
  9525. tsftr = tsftr << 32;
  9526. tsftr |= rtw_read32(adapter, addr);
  9527. break;
  9528. }
  9529. #endif
  9530. default:
  9531. RTW_ERR("%s unknow chip type\n", __func__);
  9532. }
  9533. exit:
  9534. return tsftr;
  9535. }
  9536. #ifdef CONFIG_TDLS
  9537. #ifdef CONFIG_TDLS_CH_SW
  9538. s32 rtw_hal_ch_sw_oper_offload(_adapter *padapter, u8 channel, u8 channel_offset, u16 bwmode)
  9539. {
  9540. PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
  9541. u8 ch_sw_h2c_buf[4] = {0x00, 0x00, 0x00, 0x00};
  9542. SET_H2CCMD_CH_SW_OPER_OFFLOAD_CH_NUM(ch_sw_h2c_buf, channel);
  9543. SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_MODE(ch_sw_h2c_buf, bwmode);
  9544. switch (bwmode) {
  9545. case CHANNEL_WIDTH_40:
  9546. SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_40M_SC(ch_sw_h2c_buf, channel_offset);
  9547. break;
  9548. case CHANNEL_WIDTH_80:
  9549. SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_80M_SC(ch_sw_h2c_buf, channel_offset);
  9550. break;
  9551. case CHANNEL_WIDTH_20:
  9552. default:
  9553. break;
  9554. }
  9555. SET_H2CCMD_CH_SW_OPER_OFFLOAD_RFE_TYPE(ch_sw_h2c_buf, pHalData->rfe_type);
  9556. return rtw_hal_fill_h2c_cmd(padapter, H2C_CHNL_SWITCH_OPER_OFFLOAD, sizeof(ch_sw_h2c_buf), ch_sw_h2c_buf);
  9557. }
  9558. #endif
  9559. #endif
  9560. #ifdef CONFIG_WMMPS_STA
  9561. void rtw_hal_update_uapsd_tid(_adapter *adapter)
  9562. {
  9563. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  9564. struct qos_priv *pqospriv = &pmlmepriv->qospriv;
  9565. /* write complement of pqospriv->uapsd_tid to mac register 0x693 because
  9566. it's designed for "0" represents "enable" and "1" represents "disable" */
  9567. rtw_write8(adapter, REG_WMMPS_UAPSD_TID, (u8)(~pqospriv->uapsd_tid));
  9568. }
  9569. #endif /* CONFIG_WMMPS_STA */
  9570. #if defined(CONFIG_BT_COEXIST) && defined(CONFIG_FW_MULTI_PORT_SUPPORT)
  9571. /* For multi-port support, driver needs to inform the port ID to FW for btc operations */
  9572. s32 rtw_hal_set_wifi_btc_port_id_cmd(_adapter *adapter)
  9573. {
  9574. u8 h2c_buf[H2C_BTC_WL_PORT_ID_LEN] = {0};
  9575. u8 hw_port = rtw_hal_get_port(adapter);
  9576. SET_H2CCMD_BTC_WL_PORT_ID(h2c_buf, hw_port);
  9577. RTW_INFO("%s ("ADPT_FMT") - hw_port :%d\n", __func__, ADPT_ARG(adapter), hw_port);
  9578. return rtw_hal_fill_h2c_cmd(adapter, H2C_BTC_WL_PORT_ID, H2C_BTC_WL_PORT_ID_LEN, h2c_buf);
  9579. }
  9580. #endif
  9581. #define LPS_ACTIVE_TIMEOUT 10 /*number of times*/
  9582. void rtw_lps_state_chk(_adapter *adapter, u8 ps_mode)
  9583. {
  9584. if (ps_mode == PS_MODE_ACTIVE) {
  9585. u8 ps_ready = _FALSE;
  9586. s8 leave_wait_count = LPS_ACTIVE_TIMEOUT;
  9587. do {
  9588. if ((rtw_read8(adapter, REG_TCR) & BIT_PWRBIT_OW_EN) == 0) {
  9589. ps_ready = _TRUE;
  9590. break;
  9591. }
  9592. rtw_msleep_os(1);
  9593. } while (leave_wait_count--);
  9594. if (ps_ready == _FALSE) {
  9595. RTW_ERR(FUNC_ADPT_FMT" PS_MODE_ACTIVE check failed\n", FUNC_ADPT_ARG(adapter));
  9596. rtw_warn_on(1);
  9597. }
  9598. }
  9599. }
  9600. u8 SetHwReg(_adapter *adapter, u8 variable, u8 *val)
  9601. {
  9602. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
  9603. u8 ret = _SUCCESS;
  9604. switch (variable) {
  9605. case HW_VAR_MEDIA_STATUS: {
  9606. u8 net_type = *((u8 *)val);
  9607. rtw_hal_set_msr(adapter, net_type);
  9608. }
  9609. break;
  9610. case HW_VAR_DO_IQK:
  9611. if (*val)
  9612. hal_data->bNeedIQK = _TRUE;
  9613. else
  9614. hal_data->bNeedIQK = _FALSE;
  9615. break;
  9616. case HW_VAR_MAC_ADDR:
  9617. #ifdef CONFIG_MI_WITH_MBSSID_CAM
  9618. rtw_hal_set_macaddr_mbid(adapter, val);
  9619. #else
  9620. rtw_hal_set_macaddr_port(adapter, val);
  9621. #endif
  9622. break;
  9623. case HW_VAR_BSSID:
  9624. rtw_hal_set_bssid(adapter, val);
  9625. break;
  9626. case HW_VAR_RCR:
  9627. ret = hw_var_rcr_config(adapter, *((u32 *)val));
  9628. break;
  9629. case HW_VAR_ON_RCR_AM:
  9630. hw_var_set_rcr_am(adapter, 1);
  9631. break;
  9632. case HW_VAR_OFF_RCR_AM:
  9633. hw_var_set_rcr_am(adapter, 0);
  9634. break;
  9635. case HW_VAR_BEACON_INTERVAL:
  9636. hw_var_set_bcn_interval(adapter, *(u16 *)val);
  9637. break;
  9638. #ifdef CONFIG_MBSSID_CAM
  9639. case HW_VAR_MBSSID_CAM_WRITE: {
  9640. u32 cmd = 0;
  9641. u32 *cam_val = (u32 *)val;
  9642. rtw_write32(adapter, REG_MBIDCAMCFG_1, cam_val[0]);
  9643. cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | BIT_MBIDCAM_VALID | cam_val[1];
  9644. rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
  9645. }
  9646. break;
  9647. case HW_VAR_MBSSID_CAM_CLEAR: {
  9648. u32 cmd;
  9649. u8 entry_id = *(u8 *)val;
  9650. rtw_write32(adapter, REG_MBIDCAMCFG_1, 0);
  9651. cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | ((entry_id & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT);
  9652. rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
  9653. }
  9654. break;
  9655. case HW_VAR_RCR_MBSSID_EN:
  9656. if (*((u8 *)val))
  9657. rtw_hal_rcr_add(adapter, RCR_ENMBID);
  9658. else
  9659. rtw_hal_rcr_clear(adapter, RCR_ENMBID);
  9660. break;
  9661. #endif
  9662. case HW_VAR_PORT_SWITCH:
  9663. hw_var_port_switch(adapter);
  9664. break;
  9665. case HW_VAR_INIT_RTS_RATE: {
  9666. u16 brate_cfg = *((u16 *)val);
  9667. u8 rate_index = 0;
  9668. HAL_VERSION *hal_ver = &hal_data->version_id;
  9669. if (IS_8188E(*hal_ver)) {
  9670. while (brate_cfg > 0x1) {
  9671. brate_cfg = (brate_cfg >> 1);
  9672. rate_index++;
  9673. }
  9674. rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index);
  9675. } else
  9676. rtw_warn_on(1);
  9677. }
  9678. break;
  9679. case HW_VAR_SEC_CFG: {
  9680. u16 reg_scr_ori;
  9681. u16 reg_scr;
  9682. reg_scr = reg_scr_ori = rtw_read16(adapter, REG_SECCFG);
  9683. reg_scr |= (SCR_CHK_KEYID | SCR_RxDecEnable | SCR_TxEncEnable);
  9684. if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC))
  9685. reg_scr |= SCR_CHK_BMC;
  9686. if (_rtw_camctl_chk_flags(adapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
  9687. reg_scr |= SCR_NoSKMC;
  9688. if (reg_scr != reg_scr_ori)
  9689. rtw_write16(adapter, REG_SECCFG, reg_scr);
  9690. }
  9691. break;
  9692. case HW_VAR_SEC_DK_CFG: {
  9693. struct security_priv *sec = &adapter->securitypriv;
  9694. u8 reg_scr = rtw_read8(adapter, REG_SECCFG);
  9695. if (val) { /* Enable default key related setting */
  9696. reg_scr |= SCR_TXBCUSEDK;
  9697. if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
  9698. reg_scr |= (SCR_RxUseDK | SCR_TxUseDK);
  9699. } else /* Disable default key related setting */
  9700. reg_scr &= ~(SCR_RXBCUSEDK | SCR_TXBCUSEDK | SCR_RxUseDK | SCR_TxUseDK);
  9701. rtw_write8(adapter, REG_SECCFG, reg_scr);
  9702. }
  9703. break;
  9704. case HW_VAR_ASIX_IOT:
  9705. /* enable ASIX IOT function */
  9706. if (*((u8 *)val) == _TRUE) {
  9707. /* 0xa2e[0]=0 (disable rake receiver) */
  9708. rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
  9709. rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) & ~(BIT0));
  9710. /* 0xa1c=0xa0 (reset channel estimation if signal quality is bad) */
  9711. rtw_write8(adapter, rCCK0_DSPParameter2, 0xa0);
  9712. } else {
  9713. /* restore reg:0xa2e, reg:0xa1c */
  9714. rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
  9715. rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) | (BIT0));
  9716. rtw_write8(adapter, rCCK0_DSPParameter2, 0x00);
  9717. }
  9718. break;
  9719. #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
  9720. case HW_VAR_WOWLAN: {
  9721. struct wowlan_ioctl_param *poidparam;
  9722. poidparam = (struct wowlan_ioctl_param *)val;
  9723. switch (poidparam->subcode) {
  9724. #ifdef CONFIG_WOWLAN
  9725. case WOWLAN_PATTERN_CLEAN:
  9726. rtw_hal_dl_pattern(adapter, 2);
  9727. break;
  9728. case WOWLAN_ENABLE:
  9729. rtw_hal_wow_enable(adapter);
  9730. break;
  9731. case WOWLAN_DISABLE:
  9732. rtw_hal_wow_disable(adapter);
  9733. break;
  9734. #endif /*CONFIG_WOWLAN*/
  9735. #ifdef CONFIG_AP_WOWLAN
  9736. case WOWLAN_AP_ENABLE:
  9737. rtw_hal_ap_wow_enable(adapter);
  9738. break;
  9739. case WOWLAN_AP_DISABLE:
  9740. rtw_hal_ap_wow_disable(adapter);
  9741. break;
  9742. #endif /*CONFIG_AP_WOWLAN*/
  9743. default:
  9744. break;
  9745. }
  9746. }
  9747. break;
  9748. #endif /*defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)*/
  9749. case HW_VAR_BCN_FUNC:
  9750. hw_var_set_bcn_func(adapter, *val);
  9751. break;
  9752. case HW_VAR_MLME_DISCONNECT:
  9753. hw_var_set_mlme_disconnect(adapter);
  9754. break;
  9755. case HW_VAR_MLME_SITESURVEY:
  9756. hw_var_set_mlme_sitesurvey(adapter, *val);
  9757. #ifdef CONFIG_BT_COEXIST
  9758. if (hal_data->EEPROMBluetoothCoexist == 1)
  9759. rtw_btcoex_ScanNotify(adapter, *val ? _TRUE : _FALSE);
  9760. #endif
  9761. break;
  9762. case HW_VAR_MLME_JOIN:
  9763. hw_var_set_mlme_join(adapter, *val);
  9764. #ifdef CONFIG_BT_COEXIST
  9765. if (hal_data->EEPROMBluetoothCoexist == 1) {
  9766. switch (*val) {
  9767. case 0:
  9768. /* Notify coex. mechanism before join */
  9769. rtw_btcoex_ConnectNotify(adapter, _TRUE);
  9770. break;
  9771. case 1:
  9772. case 2:
  9773. /* Notify coex. mechanism after join, whether successful or failed */
  9774. rtw_btcoex_ConnectNotify(adapter, _FALSE);
  9775. break;
  9776. }
  9777. }
  9778. #endif /* CONFIG_BT_COEXIST */
  9779. break;
  9780. case HW_VAR_EN_HW_UPDATE_TSF:
  9781. rtw_hal_set_hw_update_tsf(adapter);
  9782. break;
  9783. case HW_VAR_CORRECT_TSF:
  9784. hw_var_set_correct_tsf(adapter, *val);
  9785. break;
  9786. #if defined(CONFIG_HW_P0_TSF_SYNC) && defined(CONFIG_CONCURRENT_MODE)
  9787. case HW_VAR_TSF_AUTO_SYNC:
  9788. if (*val == _TRUE)
  9789. hw_port0_tsf_sync_sel(adapter, _TRUE, adapter->hw_port, 50);
  9790. else
  9791. hw_port0_tsf_sync_sel(adapter, _FALSE, adapter->hw_port, 50);
  9792. break;
  9793. #endif
  9794. case HW_VAR_APFM_ON_MAC:
  9795. hal_data->bMacPwrCtrlOn = *val;
  9796. RTW_INFO("%s: bMacPwrCtrlOn=%d\n", __func__, hal_data->bMacPwrCtrlOn);
  9797. break;
  9798. #ifdef CONFIG_WMMPS_STA
  9799. case HW_VAR_UAPSD_TID:
  9800. rtw_hal_update_uapsd_tid(adapter);
  9801. break;
  9802. #endif /* CONFIG_WMMPS_STA */
  9803. #ifdef CONFIG_LPS_PG
  9804. case HW_VAR_LPS_PG_HANDLE:
  9805. rtw_hal_lps_pg_handler(adapter, *val);
  9806. break;
  9807. #endif
  9808. #ifdef CONFIG_LPS_LCLK_WD_TIMER
  9809. case HW_VAR_DM_IN_LPS_LCLK:
  9810. rtw_phydm_wd_lps_lclk_hdl(adapter);
  9811. break;
  9812. #endif
  9813. case HW_VAR_ENABLE_RX_BAR:
  9814. if (*val == _TRUE) {
  9815. /* enable RX BAR */
  9816. u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
  9817. val16 |= BIT(8);
  9818. rtw_write16(adapter, REG_RXFLTMAP1, val16);
  9819. } else {
  9820. /* disable RX BAR */
  9821. u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
  9822. val16 &= (~BIT(8));
  9823. rtw_write16(adapter, REG_RXFLTMAP1, val16);
  9824. }
  9825. RTW_INFO("[HW_VAR_ENABLE_RX_BAR] 0x%02X=0x%02X\n",
  9826. REG_RXFLTMAP1, rtw_read16(adapter, REG_RXFLTMAP1));
  9827. break;
  9828. case HW_VAR_HCI_SUS_STATE:
  9829. hal_data->hci_sus_state = *(u8 *)val;
  9830. RTW_INFO("%s: hci_sus_state=%u\n", __func__, hal_data->hci_sus_state);
  9831. break;
  9832. #if defined(CONFIG_AP_MODE) && defined(CONFIG_FW_HANDLE_TXBCN) && defined(CONFIG_SUPPORT_MULTI_BCN)
  9833. case HW_VAR_BCN_HEAD_SEL:
  9834. {
  9835. u8 vap_id = *(u8 *)val;
  9836. if ((vap_id >= CONFIG_LIMITED_AP_NUM) && (vap_id != 0xFF)) {
  9837. RTW_ERR(ADPT_FMT " vap_id(%d:%d) is invalid\n", ADPT_ARG(adapter),vap_id, adapter->vap_id);
  9838. rtw_warn_on(1);
  9839. }
  9840. if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
  9841. u16 drv_pg_bndy = 0, bcn_addr = 0;
  9842. u32 page_size = 0;
  9843. /*rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_BOUNDARY, &drv_pg_bndy);*/
  9844. rtw_halmac_get_rsvd_drv_pg_bndy(adapter_to_dvobj(adapter), &drv_pg_bndy);
  9845. rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
  9846. if (vap_id != 0xFF)
  9847. bcn_addr = drv_pg_bndy + (vap_id * (MAX_BEACON_LEN / page_size));
  9848. else
  9849. bcn_addr = drv_pg_bndy;
  9850. RTW_INFO(ADPT_FMT" vap_id(%d) change BCN HEAD to 0x%04x\n",
  9851. ADPT_ARG(adapter), vap_id, bcn_addr);
  9852. rtw_write16(adapter, REG_FIFOPAGE_CTRL_2,
  9853. (bcn_addr & BIT_MASK_BCN_HEAD_1_V1) | BIT_BCN_VALID_V1);
  9854. }
  9855. }
  9856. break;
  9857. #endif
  9858. case HW_VAR_LPS_STATE_CHK :
  9859. rtw_lps_state_chk(adapter, *(u8 *)val);
  9860. break;
  9861. default:
  9862. if (0)
  9863. RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
  9864. FUNC_ADPT_ARG(adapter), variable);
  9865. ret = _FAIL;
  9866. break;
  9867. }
  9868. return ret;
  9869. }
  9870. void GetHwReg(_adapter *adapter, u8 variable, u8 *val)
  9871. {
  9872. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
  9873. u64 val64;
  9874. switch (variable) {
  9875. case HW_VAR_MAC_ADDR:
  9876. rtw_hal_get_macaddr_port(adapter, val);
  9877. break;
  9878. case HW_VAR_BASIC_RATE:
  9879. *((u16 *)val) = hal_data->BasicRateSet;
  9880. break;
  9881. case HW_VAR_RF_TYPE:
  9882. *((u8 *)val) = hal_data->rf_type;
  9883. break;
  9884. case HW_VAR_MEDIA_STATUS:
  9885. rtw_hal_get_msr(adapter, val);
  9886. break;
  9887. case HW_VAR_DO_IQK:
  9888. *val = hal_data->bNeedIQK;
  9889. break;
  9890. case HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO:
  9891. if (hal_is_band_support(adapter, BAND_ON_5G))
  9892. *val = _TRUE;
  9893. else
  9894. *val = _FALSE;
  9895. break;
  9896. case HW_VAR_APFM_ON_MAC:
  9897. *val = hal_data->bMacPwrCtrlOn;
  9898. break;
  9899. case HW_VAR_RCR:
  9900. hw_var_rcr_get(adapter, (u32 *)val);
  9901. break;
  9902. case HW_VAR_FWLPS_RF_ON:
  9903. /* When we halt NIC, we should check if FW LPS is leave. */
  9904. if (rtw_is_surprise_removed(adapter)
  9905. || (adapter_to_pwrctl(adapter)->rf_pwrstate == rf_off)
  9906. ) {
  9907. /*
  9908. * If it is in HW/SW Radio OFF or IPS state,
  9909. * we do not check Fw LPS Leave,
  9910. * because Fw is unload.
  9911. */
  9912. *val = _TRUE;
  9913. } else {
  9914. u32 rcr = 0;
  9915. rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
  9916. if (rcr & (RCR_UC_MD_EN | RCR_BC_MD_EN | RCR_TIM_PARSER_EN))
  9917. *val = _FALSE;
  9918. else
  9919. *val = _TRUE;
  9920. }
  9921. break;
  9922. case HW_VAR_HCI_SUS_STATE:
  9923. *((u8 *)val) = hal_data->hci_sus_state;
  9924. break;
  9925. case HW_VAR_BCN_CTRL_ADDR:
  9926. *((u32 *)val) = hw_bcn_ctrl_addr(adapter, adapter->hw_port);
  9927. break;
  9928. default:
  9929. if (0)
  9930. RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
  9931. FUNC_ADPT_ARG(adapter), variable);
  9932. break;
  9933. }
  9934. }
  9935. static u32 _get_page_size(struct _ADAPTER *a)
  9936. {
  9937. #ifdef RTW_HALMAC
  9938. struct dvobj_priv *d;
  9939. u32 size = 0;
  9940. int err = 0;
  9941. d = adapter_to_dvobj(a);
  9942. err = rtw_halmac_get_page_size(d, &size);
  9943. if (!err)
  9944. return size;
  9945. RTW_WARN(FUNC_ADPT_FMT ": Fail to get Page size!!(err=%d)\n",
  9946. FUNC_ADPT_ARG(a), err);
  9947. #endif /* RTW_HALMAC */
  9948. return PAGE_SIZE_128;
  9949. }
  9950. u8
  9951. SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
  9952. {
  9953. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
  9954. u8 bResult = _SUCCESS;
  9955. switch (variable) {
  9956. case HAL_DEF_DBG_DUMP_RXPKT:
  9957. hal_data->bDumpRxPkt = *((u8 *)value);
  9958. break;
  9959. case HAL_DEF_DBG_DUMP_TXPKT:
  9960. hal_data->bDumpTxPkt = *((u8 *)value);
  9961. break;
  9962. case HAL_DEF_ANT_DETECT:
  9963. hal_data->AntDetection = *((u8 *)value);
  9964. break;
  9965. default:
  9966. RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
  9967. bResult = _FAIL;
  9968. break;
  9969. }
  9970. return bResult;
  9971. }
  9972. #ifdef CONFIG_BEAMFORMING
  9973. u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter)
  9974. {
  9975. struct registry_priv *pregistrypriv = &adapter->registrypriv;
  9976. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
  9977. if ((pregistrypriv->beamformer_rf_num) && (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter) || IS_HARDWARE_TYPE_8822BU(adapter) || IS_HARDWARE_TYPE_8821C(adapter)))
  9978. return pregistrypriv->beamformer_rf_num;
  9979. else if (IS_HARDWARE_TYPE_8814AE(adapter)
  9980. #if 0
  9981. #if defined(CONFIG_USB_HCI)
  9982. || (IS_HARDWARE_TYPE_8814AU(adapter) && (pUsbModeMech->CurUsbMode == 2 || pUsbModeMech->HubUsbMode == 2)) /* for USB3.0 */
  9983. #endif
  9984. #endif
  9985. ) {
  9986. /*BF cap provided by Yu Chen, Sean, 2015, 01 */
  9987. if (hal_data->rf_type == RF_3T3R)
  9988. return 2;
  9989. else if (hal_data->rf_type == RF_4T4R)
  9990. return 3;
  9991. else
  9992. return 1;
  9993. } else
  9994. return 1;
  9995. }
  9996. u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter)
  9997. {
  9998. struct registry_priv *pregistrypriv = &adapter->registrypriv;
  9999. struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
  10000. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  10001. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
  10002. if ((pregistrypriv->beamformee_rf_num) && (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter) || IS_HARDWARE_TYPE_8822BU(adapter) || IS_HARDWARE_TYPE_8821C(adapter)))
  10003. return pregistrypriv->beamformee_rf_num;
  10004. else if (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter)) {
  10005. if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM)
  10006. return 2;
  10007. else
  10008. return 2;/*TODO: May be 3 in the future, by ChenYu. */
  10009. } else
  10010. return 1;
  10011. }
  10012. #ifdef RTW_BEAMFORMING_VERSION_2
  10013. void rtw_hal_beamforming_config_csirate(PADAPTER adapter)
  10014. {
  10015. struct dm_struct *p_dm_odm;
  10016. struct beamforming_info *bf_info;
  10017. u8 fix_rate_enable = 0;
  10018. u8 new_csi_rate_idx;
  10019. /* Acting as BFee */
  10020. if (IS_BEAMFORMEE(adapter)) {
  10021. #if 0
  10022. /* Do not enable now because it will affect MU performance and CTS/BA rate. 2016.07.19. by tynli. [PCIE-1660] */
  10023. if (IS_HARDWARE_TYPE_8821C(Adapter))
  10024. FixRateEnable = 1; /* Support after 8821C */
  10025. #endif
  10026. p_dm_odm = adapter_to_phydm(adapter);
  10027. bf_info = GET_BEAMFORM_INFO(adapter);
  10028. rtw_halmac_bf_cfg_csi_rate(adapter_to_dvobj(adapter),
  10029. p_dm_odm->rssi_min,
  10030. bf_info->cur_csi_rpt_rate,
  10031. fix_rate_enable, &new_csi_rate_idx);
  10032. if (new_csi_rate_idx != bf_info->cur_csi_rpt_rate)
  10033. bf_info->cur_csi_rpt_rate = new_csi_rate_idx;
  10034. }
  10035. }
  10036. #endif
  10037. #endif
  10038. u8
  10039. GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
  10040. {
  10041. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
  10042. u8 bResult = _SUCCESS;
  10043. switch (variable) {
  10044. case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: {
  10045. struct mlme_priv *pmlmepriv;
  10046. struct sta_priv *pstapriv;
  10047. struct sta_info *psta;
  10048. pmlmepriv = &adapter->mlmepriv;
  10049. pstapriv = &adapter->stapriv;
  10050. psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
  10051. if (psta)
  10052. *((int *)value) = psta->cmn.rssi_stat.rssi;
  10053. }
  10054. break;
  10055. case HAL_DEF_DBG_DUMP_RXPKT:
  10056. *((u8 *)value) = hal_data->bDumpRxPkt;
  10057. break;
  10058. case HAL_DEF_DBG_DUMP_TXPKT:
  10059. *((u8 *)value) = hal_data->bDumpTxPkt;
  10060. break;
  10061. case HAL_DEF_ANT_DETECT:
  10062. *((u8 *)value) = hal_data->AntDetection;
  10063. break;
  10064. case HAL_DEF_TX_PAGE_SIZE:
  10065. *((u32 *)value) = _get_page_size(adapter);
  10066. break;
  10067. case HAL_DEF_EXPLICIT_BEAMFORMER:
  10068. case HAL_DEF_EXPLICIT_BEAMFORMEE:
  10069. case HAL_DEF_VHT_MU_BEAMFORMER:
  10070. case HAL_DEF_VHT_MU_BEAMFORMEE:
  10071. *(u8 *)value = _FALSE;
  10072. break;
  10073. #ifdef CONFIG_BEAMFORMING
  10074. case HAL_DEF_BEAMFORMER_CAP:
  10075. *(u8 *)value = rtw_hal_query_txbfer_rf_num(adapter);
  10076. break;
  10077. case HAL_DEF_BEAMFORMEE_CAP:
  10078. *(u8 *)value = rtw_hal_query_txbfee_rf_num(adapter);
  10079. break;
  10080. #endif
  10081. default:
  10082. RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
  10083. bResult = _FAIL;
  10084. break;
  10085. }
  10086. return bResult;
  10087. }
  10088. BOOLEAN
  10089. eqNByte(
  10090. u8 *str1,
  10091. u8 *str2,
  10092. u32 num
  10093. )
  10094. {
  10095. if (num == 0)
  10096. return _FALSE;
  10097. while (num > 0) {
  10098. num--;
  10099. if (str1[num] != str2[num])
  10100. return _FALSE;
  10101. }
  10102. return _TRUE;
  10103. }
  10104. /*
  10105. * Description:
  10106. * Translate a character to hex digit.
  10107. * */
  10108. u32
  10109. MapCharToHexDigit(
  10110. IN char chTmp
  10111. )
  10112. {
  10113. if (chTmp >= '0' && chTmp <= '9')
  10114. return chTmp - '0';
  10115. else if (chTmp >= 'a' && chTmp <= 'f')
  10116. return 10 + (chTmp - 'a');
  10117. else if (chTmp >= 'A' && chTmp <= 'F')
  10118. return 10 + (chTmp - 'A');
  10119. else
  10120. return 0;
  10121. }
  10122. /*
  10123. * Description:
  10124. * Parse hex number from the string pucStr.
  10125. * */
  10126. BOOLEAN
  10127. GetHexValueFromString(
  10128. IN char *szStr,
  10129. IN OUT u32 *pu4bVal,
  10130. IN OUT u32 *pu4bMove
  10131. )
  10132. {
  10133. char *szScan = szStr;
  10134. /* Check input parameter. */
  10135. if (szStr == NULL || pu4bVal == NULL || pu4bMove == NULL) {
  10136. RTW_INFO("GetHexValueFromString(): Invalid inpur argumetns! szStr: %p, pu4bVal: %p, pu4bMove: %p\n", szStr, pu4bVal, pu4bMove);
  10137. return _FALSE;
  10138. }
  10139. /* Initialize output. */
  10140. *pu4bMove = 0;
  10141. *pu4bVal = 0;
  10142. /* Skip leading space. */
  10143. while (*szScan != '\0' &&
  10144. (*szScan == ' ' || *szScan == '\t')) {
  10145. szScan++;
  10146. (*pu4bMove)++;
  10147. }
  10148. /* Skip leading '0x' or '0X'. */
  10149. if (*szScan == '0' && (*(szScan + 1) == 'x' || *(szScan + 1) == 'X')) {
  10150. szScan += 2;
  10151. (*pu4bMove) += 2;
  10152. }
  10153. /* Check if szScan is now pointer to a character for hex digit, */
  10154. /* if not, it means this is not a valid hex number. */
  10155. if (!IsHexDigit(*szScan))
  10156. return _FALSE;
  10157. /* Parse each digit. */
  10158. do {
  10159. (*pu4bVal) <<= 4;
  10160. *pu4bVal += MapCharToHexDigit(*szScan);
  10161. szScan++;
  10162. (*pu4bMove)++;
  10163. } while (IsHexDigit(*szScan));
  10164. return _TRUE;
  10165. }
  10166. BOOLEAN
  10167. GetFractionValueFromString(
  10168. IN char *szStr,
  10169. IN OUT u8 *pInteger,
  10170. IN OUT u8 *pFraction,
  10171. IN OUT u32 *pu4bMove
  10172. )
  10173. {
  10174. char *szScan = szStr;
  10175. /* Initialize output. */
  10176. *pu4bMove = 0;
  10177. *pInteger = 0;
  10178. *pFraction = 0;
  10179. /* Skip leading space. */
  10180. while (*szScan != '\0' && (*szScan == ' ' || *szScan == '\t')) {
  10181. ++szScan;
  10182. ++(*pu4bMove);
  10183. }
  10184. if (*szScan < '0' || *szScan > '9')
  10185. return _FALSE;
  10186. /* Parse each digit. */
  10187. do {
  10188. (*pInteger) *= 10;
  10189. *pInteger += (*szScan - '0');
  10190. ++szScan;
  10191. ++(*pu4bMove);
  10192. if (*szScan == '.') {
  10193. ++szScan;
  10194. ++(*pu4bMove);
  10195. if (*szScan < '0' || *szScan > '9')
  10196. return _FALSE;
  10197. *pFraction += (*szScan - '0') * 10;
  10198. ++szScan;
  10199. ++(*pu4bMove);
  10200. if (*szScan >= '0' && *szScan <= '9') {
  10201. *pFraction += *szScan - '0';
  10202. ++szScan;
  10203. ++(*pu4bMove);
  10204. }
  10205. return _TRUE;
  10206. }
  10207. } while (*szScan >= '0' && *szScan <= '9');
  10208. return _TRUE;
  10209. }
  10210. /*
  10211. * Description:
  10212. * Return TRUE if szStr is comment out with leading " */ /* ".
  10213. * */
  10214. BOOLEAN
  10215. IsCommentString(
  10216. IN char *szStr
  10217. )
  10218. {
  10219. if (*szStr == '/' && *(szStr + 1) == '/')
  10220. return _TRUE;
  10221. else
  10222. return _FALSE;
  10223. }
  10224. BOOLEAN
  10225. GetU1ByteIntegerFromStringInDecimal(
  10226. IN char *Str,
  10227. IN OUT u8 *pInt
  10228. )
  10229. {
  10230. u16 i = 0;
  10231. *pInt = 0;
  10232. while (Str[i] != '\0') {
  10233. if (Str[i] >= '0' && Str[i] <= '9') {
  10234. *pInt *= 10;
  10235. *pInt += (Str[i] - '0');
  10236. } else
  10237. return _FALSE;
  10238. ++i;
  10239. }
  10240. return _TRUE;
  10241. }
  10242. /* <20121004, Kordan> For example,
  10243. * ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from a string "Hello [Kordan]".
  10244. * If RightQualifier does not exist, it will hang on in the while loop */
  10245. BOOLEAN
  10246. ParseQualifiedString(
  10247. IN char *In,
  10248. IN OUT u32 *Start,
  10249. OUT char *Out,
  10250. IN char LeftQualifier,
  10251. IN char RightQualifier
  10252. )
  10253. {
  10254. u32 i = 0, j = 0;
  10255. char c = In[(*Start)++];
  10256. if (c != LeftQualifier)
  10257. return _FALSE;
  10258. i = (*Start);
  10259. c = In[(*Start)++];
  10260. while (c != RightQualifier && c != '\0')
  10261. c = In[(*Start)++];
  10262. if (c == '\0')
  10263. return _FALSE;
  10264. j = (*Start) - 2;
  10265. strncpy((char *)Out, (const char *)(In + i), j - i + 1);
  10266. return _TRUE;
  10267. }
  10268. BOOLEAN
  10269. isAllSpaceOrTab(
  10270. u8 *data,
  10271. u8 size
  10272. )
  10273. {
  10274. u8 cnt = 0, NumOfSpaceAndTab = 0;
  10275. while (size > cnt) {
  10276. if (data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0')
  10277. ++NumOfSpaceAndTab;
  10278. ++cnt;
  10279. }
  10280. return size == NumOfSpaceAndTab;
  10281. }
  10282. void rtw_hal_check_rxfifo_full(_adapter *adapter)
  10283. {
  10284. struct dvobj_priv *psdpriv = adapter->dvobj;
  10285. struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
  10286. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
  10287. struct registry_priv *regsty = &adapter->registrypriv;
  10288. int save_cnt = _FALSE;
  10289. if (regsty->check_hw_status == 1) {
  10290. /* switch counter to RX fifo */
  10291. if (IS_8188E(pHalData->version_id) ||
  10292. IS_8188F(pHalData->version_id) ||
  10293. IS_8188GTV(pHalData->version_id) ||
  10294. IS_8812_SERIES(pHalData->version_id) ||
  10295. IS_8821_SERIES(pHalData->version_id) ||
  10296. IS_8723B_SERIES(pHalData->version_id) ||
  10297. IS_8192E(pHalData->version_id) ||
  10298. IS_8703B_SERIES(pHalData->version_id) ||
  10299. IS_8723D_SERIES(pHalData->version_id) ||
  10300. IS_8192F_SERIES(pHalData->version_id)) {
  10301. rtw_write8(adapter, REG_RXERR_RPT + 3, rtw_read8(adapter, REG_RXERR_RPT + 3) | 0xa0);
  10302. save_cnt = _TRUE;
  10303. } else {
  10304. /* todo: other chips */
  10305. }
  10306. if (save_cnt) {
  10307. pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
  10308. pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
  10309. pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow - pdbgpriv->dbg_rx_fifo_last_overflow;
  10310. } else {
  10311. /* special value to indicate no implementation */
  10312. pdbgpriv->dbg_rx_fifo_last_overflow = 1;
  10313. pdbgpriv->dbg_rx_fifo_curr_overflow = 1;
  10314. pdbgpriv->dbg_rx_fifo_diff_overflow = 1;
  10315. }
  10316. }
  10317. }
  10318. void linked_info_dump(_adapter *padapter, u8 benable)
  10319. {
  10320. struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
  10321. if (padapter->bLinkInfoDump == benable)
  10322. return;
  10323. RTW_INFO("%s %s\n", __FUNCTION__, (benable) ? "enable" : "disable");
  10324. if (benable) {
  10325. #ifdef CONFIG_LPS
  10326. pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;/* keep org value */
  10327. rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
  10328. #endif
  10329. #ifdef CONFIG_IPS
  10330. pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;/* keep org value */
  10331. rtw_pm_set_ips(padapter, IPS_NONE);
  10332. #endif
  10333. } else {
  10334. #ifdef CONFIG_IPS
  10335. rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);
  10336. #endif /* CONFIG_IPS */
  10337. #ifdef CONFIG_LPS
  10338. rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt);
  10339. #endif /* CONFIG_LPS */
  10340. }
  10341. padapter->bLinkInfoDump = benable ;
  10342. }
  10343. #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
  10344. void rtw_get_raw_rssi_info(void *sel, _adapter *padapter)
  10345. {
  10346. u8 isCCKrate, rf_path;
  10347. PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
  10348. struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
  10349. RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n",
  10350. HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
  10351. isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
  10352. if (isCCKrate)
  10353. psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
  10354. for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
  10355. RTW_PRINT_SEL(sel, "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)\n"
  10356. , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
  10357. if (!isCCKrate) {
  10358. RTW_PRINT_SEL(sel, "\trx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",
  10359. psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
  10360. }
  10361. }
  10362. }
  10363. void rtw_dump_raw_rssi_info(_adapter *padapter, void *sel)
  10364. {
  10365. u8 isCCKrate, rf_path;
  10366. PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
  10367. struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
  10368. _RTW_PRINT_SEL(sel, "============ RAW Rx Info dump ===================\n");
  10369. _RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n", HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
  10370. isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
  10371. if (isCCKrate)
  10372. psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
  10373. for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
  10374. _RTW_PRINT_SEL(sel , "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)"
  10375. , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
  10376. if (!isCCKrate)
  10377. _RTW_PRINT_SEL(sel , ",rx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n", psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
  10378. else
  10379. _RTW_PRINT_SEL(sel , "\n");
  10380. }
  10381. }
  10382. #endif
  10383. #ifdef DBG_RX_DFRAME_RAW_DATA
  10384. void rtw_dump_rx_dframe_info(_adapter *padapter, void *sel)
  10385. {
  10386. #define DBG_RX_DFRAME_RAW_DATA_UC 0
  10387. #define DBG_RX_DFRAME_RAW_DATA_BMC 1
  10388. #define DBG_RX_DFRAME_RAW_DATA_TYPES 2
  10389. _irqL irqL;
  10390. u8 isCCKrate, rf_path;
  10391. struct recv_priv *precvpriv = &(padapter->recvpriv);
  10392. PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
  10393. struct sta_priv *pstapriv = &padapter->stapriv;
  10394. struct sta_info *psta;
  10395. struct sta_recv_dframe_info *psta_dframe_info;
  10396. int i, j;
  10397. _list *plist, *phead;
  10398. u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  10399. u8 null_addr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  10400. if (precvpriv->store_law_data_flag) {
  10401. _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
  10402. for (i = 0; i < NUM_STA; i++) {
  10403. phead = &(pstapriv->sta_hash[i]);
  10404. plist = get_next(phead);
  10405. while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
  10406. psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
  10407. plist = get_next(plist);
  10408. if (psta) {
  10409. if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE)
  10410. && (_rtw_memcmp(psta->cmn.mac_addr, null_addr, ETH_ALEN) != _TRUE)
  10411. && (_rtw_memcmp(psta->cmn.mac_addr, adapter_mac_addr(padapter), ETH_ALEN) != _TRUE)) {
  10412. RTW_PRINT_SEL(sel, "==============================\n");
  10413. RTW_PRINT_SEL(sel, "macaddr =" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));
  10414. for (j = 0; j < DBG_RX_DFRAME_RAW_DATA_TYPES; j++) {
  10415. if (j == DBG_RX_DFRAME_RAW_DATA_UC) {
  10416. psta_dframe_info = &psta->sta_dframe_info;
  10417. RTW_PRINT_SEL(sel, "\n");
  10418. RTW_PRINT_SEL(sel, "Unicast:\n");
  10419. } else if (j == DBG_RX_DFRAME_RAW_DATA_BMC) {
  10420. psta_dframe_info = &psta->sta_dframe_info_bmc;
  10421. RTW_PRINT_SEL(sel, "\n");
  10422. RTW_PRINT_SEL(sel, "Broadcast/Multicast:\n");
  10423. }
  10424. isCCKrate = (psta_dframe_info->sta_data_rate <= DESC_RATE11M) ? TRUE : FALSE;
  10425. RTW_PRINT_SEL(sel, "BW=%s, sgi =%d\n", ch_width_str(psta_dframe_info->sta_bw_mode), psta_dframe_info->sta_sgi);
  10426. RTW_PRINT_SEL(sel, "Rx_Data_Rate = %s\n", HDATA_RATE(psta_dframe_info->sta_data_rate));
  10427. for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
  10428. if (!isCCKrate) {
  10429. RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)", rf_path, psta_dframe_info->sta_RxPwr[rf_path]);
  10430. _RTW_PRINT_SEL(sel , ",rx_ofdm_snr:%d(dB)\n", psta_dframe_info->sta_ofdm_snr[rf_path]);
  10431. } else
  10432. RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)\n", rf_path, (psta_dframe_info->sta_mimo_signal_strength[rf_path]) - 100);
  10433. }
  10434. }
  10435. }
  10436. }
  10437. }
  10438. }
  10439. _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
  10440. }
  10441. }
  10442. #endif
  10443. void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe)
  10444. {
  10445. u8 isCCKrate, rf_path , dframe_type;
  10446. u8 *ptr;
  10447. u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  10448. #ifdef DBG_RX_DFRAME_RAW_DATA
  10449. struct sta_recv_dframe_info *psta_dframe_info;
  10450. #endif
  10451. struct recv_priv *precvpriv = &(padapter->recvpriv);
  10452. PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
  10453. struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
  10454. struct sta_info *psta = prframe->u.hdr.psta;
  10455. struct phydm_phyinfo_struct *p_phy_info = &pattrib->phy_info;
  10456. struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
  10457. psample_pkt_rssi->data_rate = pattrib->data_rate;
  10458. ptr = prframe->u.hdr.rx_data;
  10459. dframe_type = GetFrameType(ptr);
  10460. /*RTW_INFO("=>%s\n", __FUNCTION__);*/
  10461. if (precvpriv->store_law_data_flag) {
  10462. isCCKrate = (pattrib->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
  10463. psample_pkt_rssi->pwdball = p_phy_info->rx_pwdb_all;
  10464. psample_pkt_rssi->pwr_all = p_phy_info->recv_signal_power;
  10465. for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
  10466. psample_pkt_rssi->mimo_signal_strength[rf_path] = p_phy_info->rx_mimo_signal_strength[rf_path];
  10467. psample_pkt_rssi->mimo_signal_quality[rf_path] = p_phy_info->rx_mimo_signal_quality[rf_path];
  10468. if (!isCCKrate) {
  10469. psample_pkt_rssi->ofdm_pwr[rf_path] = p_phy_info->rx_pwr[rf_path];
  10470. psample_pkt_rssi->ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
  10471. }
  10472. }
  10473. #ifdef DBG_RX_DFRAME_RAW_DATA
  10474. if ((dframe_type == WIFI_DATA_TYPE) || (dframe_type == WIFI_QOS_DATA_TYPE) || (padapter->registrypriv.mp_mode == 1)) {
  10475. /*RTW_INFO("=>%s WIFI_DATA_TYPE or WIFI_QOS_DATA_TYPE\n", __FUNCTION__);*/
  10476. if (psta) {
  10477. if (IS_MCAST(get_ra(get_recvframe_data(prframe))))
  10478. psta_dframe_info = &psta->sta_dframe_info_bmc;
  10479. else
  10480. psta_dframe_info = &psta->sta_dframe_info;
  10481. /*RTW_INFO("=>%s psta->cmn.mac_addr="MAC_FMT" !\n",
  10482. __FUNCTION__, MAC_ARG(psta->cmn.mac_addr));*/
  10483. if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) || (padapter->registrypriv.mp_mode == 1)) {
  10484. psta_dframe_info->sta_data_rate = pattrib->data_rate;
  10485. psta_dframe_info->sta_sgi = pattrib->sgi;
  10486. psta_dframe_info->sta_bw_mode = pattrib->bw;
  10487. for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
  10488. psta_dframe_info->sta_mimo_signal_strength[rf_path] = (p_phy_info->rx_mimo_signal_strength[rf_path]);/*Percentage to dbm*/
  10489. if (!isCCKrate) {
  10490. psta_dframe_info->sta_ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
  10491. psta_dframe_info->sta_RxPwr[rf_path] = p_phy_info->rx_pwr[rf_path];
  10492. }
  10493. }
  10494. }
  10495. }
  10496. }
  10497. #endif
  10498. }
  10499. }
  10500. int hal_efuse_macaddr_offset(_adapter *adapter)
  10501. {
  10502. u8 interface_type = 0;
  10503. int addr_offset = -1;
  10504. interface_type = rtw_get_intf_type(adapter);
  10505. switch (rtw_get_chip_type(adapter)) {
  10506. #ifdef CONFIG_RTL8723B
  10507. case RTL8723B:
  10508. if (interface_type == RTW_USB)
  10509. addr_offset = EEPROM_MAC_ADDR_8723BU;
  10510. else if (interface_type == RTW_SDIO)
  10511. addr_offset = EEPROM_MAC_ADDR_8723BS;
  10512. else if (interface_type == RTW_PCIE)
  10513. addr_offset = EEPROM_MAC_ADDR_8723BE;
  10514. break;
  10515. #endif
  10516. #ifdef CONFIG_RTL8703B
  10517. case RTL8703B:
  10518. if (interface_type == RTW_USB)
  10519. addr_offset = EEPROM_MAC_ADDR_8703BU;
  10520. else if (interface_type == RTW_SDIO)
  10521. addr_offset = EEPROM_MAC_ADDR_8703BS;
  10522. break;
  10523. #endif
  10524. #ifdef CONFIG_RTL8723D
  10525. case RTL8723D:
  10526. if (interface_type == RTW_USB)
  10527. addr_offset = EEPROM_MAC_ADDR_8723DU;
  10528. else if (interface_type == RTW_SDIO)
  10529. addr_offset = EEPROM_MAC_ADDR_8723DS;
  10530. else if (interface_type == RTW_PCIE)
  10531. addr_offset = EEPROM_MAC_ADDR_8723DE;
  10532. break;
  10533. #endif
  10534. #ifdef CONFIG_RTL8188E
  10535. case RTL8188E:
  10536. if (interface_type == RTW_USB)
  10537. addr_offset = EEPROM_MAC_ADDR_88EU;
  10538. else if (interface_type == RTW_SDIO)
  10539. addr_offset = EEPROM_MAC_ADDR_88ES;
  10540. else if (interface_type == RTW_PCIE)
  10541. addr_offset = EEPROM_MAC_ADDR_88EE;
  10542. break;
  10543. #endif
  10544. #ifdef CONFIG_RTL8188F
  10545. case RTL8188F:
  10546. if (interface_type == RTW_USB)
  10547. addr_offset = EEPROM_MAC_ADDR_8188FU;
  10548. else if (interface_type == RTW_SDIO)
  10549. addr_offset = EEPROM_MAC_ADDR_8188FS;
  10550. break;
  10551. #endif
  10552. #ifdef CONFIG_RTL8188GTV
  10553. case RTL8188GTV:
  10554. if (interface_type == RTW_USB)
  10555. addr_offset = EEPROM_MAC_ADDR_8188GTVU;
  10556. else if (interface_type == RTW_SDIO)
  10557. addr_offset = EEPROM_MAC_ADDR_8188GTVS;
  10558. break;
  10559. #endif
  10560. #ifdef CONFIG_RTL8812A
  10561. case RTL8812:
  10562. if (interface_type == RTW_USB)
  10563. addr_offset = EEPROM_MAC_ADDR_8812AU;
  10564. else if (interface_type == RTW_PCIE)
  10565. addr_offset = EEPROM_MAC_ADDR_8812AE;
  10566. break;
  10567. #endif
  10568. #ifdef CONFIG_RTL8821A
  10569. case RTL8821:
  10570. if (interface_type == RTW_USB)
  10571. addr_offset = EEPROM_MAC_ADDR_8821AU;
  10572. else if (interface_type == RTW_SDIO)
  10573. addr_offset = EEPROM_MAC_ADDR_8821AS;
  10574. else if (interface_type == RTW_PCIE)
  10575. addr_offset = EEPROM_MAC_ADDR_8821AE;
  10576. break;
  10577. #endif
  10578. #ifdef CONFIG_RTL8192E
  10579. case RTL8192E:
  10580. if (interface_type == RTW_USB)
  10581. addr_offset = EEPROM_MAC_ADDR_8192EU;
  10582. else if (interface_type == RTW_SDIO)
  10583. addr_offset = EEPROM_MAC_ADDR_8192ES;
  10584. else if (interface_type == RTW_PCIE)
  10585. addr_offset = EEPROM_MAC_ADDR_8192EE;
  10586. break;
  10587. #endif
  10588. #ifdef CONFIG_RTL8814A
  10589. case RTL8814A:
  10590. if (interface_type == RTW_USB)
  10591. addr_offset = EEPROM_MAC_ADDR_8814AU;
  10592. else if (interface_type == RTW_PCIE)
  10593. addr_offset = EEPROM_MAC_ADDR_8814AE;
  10594. break;
  10595. #endif
  10596. #ifdef CONFIG_RTL8822B
  10597. case RTL8822B:
  10598. if (interface_type == RTW_USB)
  10599. addr_offset = EEPROM_MAC_ADDR_8822BU;
  10600. else if (interface_type == RTW_SDIO)
  10601. addr_offset = EEPROM_MAC_ADDR_8822BS;
  10602. else if (interface_type == RTW_PCIE)
  10603. addr_offset = EEPROM_MAC_ADDR_8822BE;
  10604. break;
  10605. #endif /* CONFIG_RTL8822B */
  10606. #ifdef CONFIG_RTL8821C
  10607. case RTL8821C:
  10608. if (interface_type == RTW_USB)
  10609. addr_offset = EEPROM_MAC_ADDR_8821CU;
  10610. else if (interface_type == RTW_SDIO)
  10611. addr_offset = EEPROM_MAC_ADDR_8821CS;
  10612. else if (interface_type == RTW_PCIE)
  10613. addr_offset = EEPROM_MAC_ADDR_8821CE;
  10614. break;
  10615. #endif /* CONFIG_RTL8821C */
  10616. #ifdef CONFIG_RTL8710B
  10617. case RTL8710B:
  10618. if (interface_type == RTW_USB)
  10619. addr_offset = EEPROM_MAC_ADDR_8710B;
  10620. break;
  10621. #endif
  10622. #ifdef CONFIG_RTL8192F
  10623. case RTL8192F:
  10624. if (interface_type == RTW_USB)
  10625. addr_offset = EEPROM_MAC_ADDR_8192FU;
  10626. else if (interface_type == RTW_SDIO)
  10627. addr_offset = EEPROM_MAC_ADDR_8192FS;
  10628. else if (interface_type == RTW_PCIE)
  10629. addr_offset = EEPROM_MAC_ADDR_8192FE;
  10630. break;
  10631. #endif /* CONFIG_RTL8192F */
  10632. }
  10633. if (addr_offset == -1) {
  10634. RTW_ERR("%s: unknown combination - chip_type:%u, interface:%u\n"
  10635. , __func__, rtw_get_chip_type(adapter), rtw_get_intf_type(adapter));
  10636. }
  10637. return addr_offset;
  10638. }
  10639. int Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8 *mac_addr)
  10640. {
  10641. int ret = _FAIL;
  10642. int addr_offset;
  10643. addr_offset = hal_efuse_macaddr_offset(padapter);
  10644. if (addr_offset == -1)
  10645. goto exit;
  10646. ret = rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr);
  10647. exit:
  10648. return ret;
  10649. }
  10650. void rtw_dump_cur_efuse(PADAPTER padapter)
  10651. {
  10652. int i =0;
  10653. int mapsize =0;
  10654. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
  10655. EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapsize, _FALSE);
  10656. if (mapsize <= 0 || mapsize > EEPROM_MAX_SIZE) {
  10657. RTW_ERR("wrong map size %d\n", mapsize);
  10658. return;
  10659. }
  10660. #ifdef CONFIG_RTW_DEBUG
  10661. if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
  10662. RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "EFUSE FILE", hal_data->efuse_eeprom_data, mapsize);
  10663. else
  10664. RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "HW EFUSE", hal_data->efuse_eeprom_data, mapsize);
  10665. #endif
  10666. }
  10667. #ifdef CONFIG_EFUSE_CONFIG_FILE
  10668. u32 Hal_readPGDataFromConfigFile(PADAPTER padapter)
  10669. {
  10670. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
  10671. u32 ret = _FALSE;
  10672. u32 maplen = 0;
  10673. EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&maplen, _FALSE);
  10674. if (maplen < 256 || maplen > EEPROM_MAX_SIZE) {
  10675. RTW_ERR("eFuse length error :%d\n", maplen);
  10676. return _FALSE;
  10677. }
  10678. ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data, maplen);
  10679. hal_data->efuse_file_status = ((ret == _FAIL) ? EFUSE_FILE_FAILED : EFUSE_FILE_LOADED);
  10680. if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
  10681. rtw_dump_cur_efuse(padapter);
  10682. return ret;
  10683. }
  10684. u32 Hal_ReadMACAddrFromFile(PADAPTER padapter, u8 *mac_addr)
  10685. {
  10686. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
  10687. u32 ret = _FAIL;
  10688. if (rtw_read_macaddr_from_file(WIFIMAC_PATH, mac_addr) == _SUCCESS
  10689. && rtw_check_invalid_mac_address(mac_addr, _TRUE) == _FALSE
  10690. ) {
  10691. hal_data->macaddr_file_status = MACADDR_FILE_LOADED;
  10692. ret = _SUCCESS;
  10693. } else
  10694. hal_data->macaddr_file_status = MACADDR_FILE_FAILED;
  10695. return ret;
  10696. }
  10697. #endif /* CONFIG_EFUSE_CONFIG_FILE */
  10698. int hal_config_macaddr(_adapter *adapter, bool autoload_fail)
  10699. {
  10700. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
  10701. u8 addr[ETH_ALEN];
  10702. int addr_offset = hal_efuse_macaddr_offset(adapter);
  10703. u8 *hw_addr = NULL;
  10704. int ret = _SUCCESS;
  10705. #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
  10706. u8 ft_mac_addr[ETH_ALEN] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff}; /* FT USB2 for 8822B */
  10707. #endif
  10708. if (autoload_fail)
  10709. goto bypass_hw_pg;
  10710. if (addr_offset != -1)
  10711. hw_addr = &hal_data->efuse_eeprom_data[addr_offset];
  10712. #ifdef CONFIG_EFUSE_CONFIG_FILE
  10713. /* if the hw_addr is written by efuse file, set to NULL */
  10714. if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
  10715. hw_addr = NULL;
  10716. #endif
  10717. if (!hw_addr) {
  10718. /* try getting hw pg data */
  10719. if (Hal_GetPhyEfuseMACAddr(adapter, addr) == _SUCCESS)
  10720. hw_addr = addr;
  10721. }
  10722. #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
  10723. if (_rtw_memcmp(hw_addr, ft_mac_addr, ETH_ALEN))
  10724. hw_addr[0] = 0xff;
  10725. #endif
  10726. /* check hw pg data */
  10727. if (hw_addr && rtw_check_invalid_mac_address(hw_addr, _TRUE) == _FALSE) {
  10728. _rtw_memcpy(hal_data->EEPROMMACAddr, hw_addr, ETH_ALEN);
  10729. goto exit;
  10730. }
  10731. bypass_hw_pg:
  10732. #ifdef CONFIG_EFUSE_CONFIG_FILE
  10733. /* check wifi mac file */
  10734. if (Hal_ReadMACAddrFromFile(adapter, addr) == _SUCCESS) {
  10735. _rtw_memcpy(hal_data->EEPROMMACAddr, addr, ETH_ALEN);
  10736. goto exit;
  10737. }
  10738. #endif
  10739. _rtw_memset(hal_data->EEPROMMACAddr, 0, ETH_ALEN);
  10740. ret = _FAIL;
  10741. exit:
  10742. return ret;
  10743. }
  10744. #ifdef CONFIG_RF_POWER_TRIM
  10745. u32 Array_kfreemap[] = {
  10746. 0x08, 0xe,
  10747. 0x06, 0xc,
  10748. 0x04, 0xa,
  10749. 0x02, 0x8,
  10750. 0x00, 0x6,
  10751. 0x03, 0x4,
  10752. 0x05, 0x2,
  10753. 0x07, 0x0,
  10754. 0x09, 0x0,
  10755. 0x0c, 0x0,
  10756. };
  10757. void rtw_bb_rf_gain_offset(_adapter *padapter)
  10758. {
  10759. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
  10760. struct registry_priv *registry_par = &padapter->registrypriv;
  10761. struct kfree_data_t *kfree_data = &pHalData->kfree_data;
  10762. u8 value = pHalData->EEPROMRFGainOffset;
  10763. u8 tmp = 0x3e;
  10764. u32 res, i = 0;
  10765. u4Byte ArrayLen = sizeof(Array_kfreemap) / sizeof(u32);
  10766. pu4Byte Array = Array_kfreemap;
  10767. u4Byte v1 = 0, v2 = 0, GainValue = 0, target = 0;
  10768. if (registry_par->RegPwrTrimEnable == 2) {
  10769. RTW_INFO("Registry kfree default force disable.\n");
  10770. return;
  10771. }
  10772. #if defined(CONFIG_RTL8723B)
  10773. if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
  10774. RTW_INFO("Offset RF Gain.\n");
  10775. RTW_INFO("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x\n", pHalData->EEPROMRFGainVal);
  10776. if (pHalData->EEPROMRFGainVal != 0xff) {
  10777. if (pHalData->ant_path == RF_PATH_A)
  10778. GainValue = (pHalData->EEPROMRFGainVal & 0x0f);
  10779. else
  10780. GainValue = (pHalData->EEPROMRFGainVal & 0xf0) >> 4;
  10781. RTW_INFO("Ant PATH_%d GainValue Offset = 0x%x\n", (pHalData->ant_path == RF_PATH_A) ? (RF_PATH_A) : (RF_PATH_B), GainValue);
  10782. for (i = 0; i < ArrayLen; i += 2) {
  10783. /* RTW_INFO("ArrayLen in =%d ,Array 1 =0x%x ,Array2 =0x%x\n",i,Array[i],Array[i]+1); */
  10784. v1 = Array[i];
  10785. v2 = Array[i + 1];
  10786. if (v1 == GainValue) {
  10787. RTW_INFO("Offset RF Gain. got v1 =0x%x ,v2 =0x%x\n", v1, v2);
  10788. target = v2;
  10789. break;
  10790. }
  10791. }
  10792. RTW_INFO("pHalData->EEPROMRFGainVal=0x%x ,Gain offset Target Value=0x%x\n", pHalData->EEPROMRFGainVal, target);
  10793. res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
  10794. RTW_INFO("Offset RF Gain. before reg 0x7f=0x%08x\n", res);
  10795. phy_set_rf_reg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18 | BIT17 | BIT16 | BIT15, target);
  10796. res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
  10797. RTW_INFO("Offset RF Gain. After reg 0x7f=0x%08x\n", res);
  10798. } else
  10799. RTW_INFO("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x != 0xff, didn't run Kfree\n", pHalData->EEPROMRFGainVal);
  10800. } else
  10801. RTW_INFO("Using the default RF gain.\n");
  10802. #elif defined(CONFIG_RTL8188E)
  10803. if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
  10804. RTW_INFO("8188ES Offset RF Gain.\n");
  10805. RTW_INFO("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n",
  10806. pHalData->EEPROMRFGainVal);
  10807. if (pHalData->EEPROMRFGainVal != 0xff) {
  10808. res = rtw_hal_read_rfreg(padapter, RF_PATH_A,
  10809. REG_RF_BB_GAIN_OFFSET, 0xffffffff);
  10810. RTW_INFO("Offset RF Gain. reg 0x55=0x%x\n", res);
  10811. res &= 0xfff87fff;
  10812. res |= (pHalData->EEPROMRFGainVal & 0x0f) << 15;
  10813. RTW_INFO("Offset RF Gain. res=0x%x\n", res);
  10814. rtw_hal_write_rfreg(padapter, RF_PATH_A,
  10815. REG_RF_BB_GAIN_OFFSET,
  10816. RF_GAIN_OFFSET_MASK, res);
  10817. } else {
  10818. RTW_INFO("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n",
  10819. pHalData->EEPROMRFGainVal);
  10820. }
  10821. } else
  10822. RTW_INFO("Using the default RF gain.\n");
  10823. #else
  10824. /* TODO: call this when channel switch */
  10825. if (kfree_data->flag & KFREE_FLAG_ON)
  10826. rtw_rf_apply_tx_gain_offset(padapter, 6); /* input ch6 to select BB_GAIN_2G */
  10827. #endif
  10828. }
  10829. #endif /*CONFIG_RF_POWER_TRIM */
  10830. bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data)
  10831. {
  10832. #ifdef CONFIG_RF_POWER_TRIM
  10833. int i, j;
  10834. for (i = 0; i < BB_GAIN_NUM; i++)
  10835. for (j = 0; j < RF_PATH_MAX; j++)
  10836. if (data->bb_gain[i][j] != 0)
  10837. return 0;
  10838. #endif
  10839. return 1;
  10840. }
  10841. #ifdef CONFIG_USB_RX_AGGREGATION
  10842. void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode)
  10843. {
  10844. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
  10845. if (cur_wireless_mode < WIRELESS_11_24N
  10846. && cur_wireless_mode > 0) { /* ABG mode */
  10847. #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
  10848. u32 remainder = 0;
  10849. u8 quotient = 0;
  10850. remainder = MAX_RECVBUF_SZ % (4 * 1024);
  10851. quotient = (u8)(MAX_RECVBUF_SZ >> 12);
  10852. if (quotient > 5) {
  10853. pHalData->rxagg_usb_size = 0x6;
  10854. pHalData->rxagg_usb_timeout = 0x10;
  10855. } else {
  10856. if (remainder >= 2048) {
  10857. pHalData->rxagg_usb_size = quotient;
  10858. pHalData->rxagg_usb_timeout = 0x10;
  10859. } else {
  10860. pHalData->rxagg_usb_size = (quotient - 1);
  10861. pHalData->rxagg_usb_timeout = 0x10;
  10862. }
  10863. }
  10864. #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
  10865. if (0x6 != pHalData->rxagg_usb_size || 0x10 != pHalData->rxagg_usb_timeout) {
  10866. pHalData->rxagg_usb_size = 0x6;
  10867. pHalData->rxagg_usb_timeout = 0x10;
  10868. rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
  10869. pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
  10870. }
  10871. #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
  10872. } else if (cur_wireless_mode >= WIRELESS_11_24N
  10873. && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
  10874. #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
  10875. u32 remainder = 0;
  10876. u8 quotient = 0;
  10877. remainder = MAX_RECVBUF_SZ % (4 * 1024);
  10878. quotient = (u8)(MAX_RECVBUF_SZ >> 12);
  10879. if (quotient > 5) {
  10880. pHalData->rxagg_usb_size = 0x5;
  10881. pHalData->rxagg_usb_timeout = 0x20;
  10882. } else {
  10883. if (remainder >= 2048) {
  10884. pHalData->rxagg_usb_size = quotient;
  10885. pHalData->rxagg_usb_timeout = 0x10;
  10886. } else {
  10887. pHalData->rxagg_usb_size = (quotient - 1);
  10888. pHalData->rxagg_usb_timeout = 0x10;
  10889. }
  10890. }
  10891. #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
  10892. if ((0x5 != pHalData->rxagg_usb_size) || (0x20 != pHalData->rxagg_usb_timeout)) {
  10893. pHalData->rxagg_usb_size = 0x5;
  10894. pHalData->rxagg_usb_timeout = 0x20;
  10895. rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
  10896. pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
  10897. }
  10898. #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
  10899. } else {
  10900. /* RTW_INFO("%s: Unknow wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
  10901. }
  10902. }
  10903. void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, u8 UsbDmaSize, u8 Legacy_UsbDmaSize)
  10904. {
  10905. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
  10906. if (cur_wireless_mode < WIRELESS_11_24N
  10907. && cur_wireless_mode > 0) { /* ABG mode */
  10908. if (Legacy_UsbDmaSize != pHalData->rxagg_usb_size
  10909. || 0x10 != pHalData->rxagg_usb_timeout) {
  10910. pHalData->rxagg_usb_size = Legacy_UsbDmaSize;
  10911. pHalData->rxagg_usb_timeout = 0x10;
  10912. rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
  10913. pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
  10914. }
  10915. } else if (cur_wireless_mode >= WIRELESS_11_24N
  10916. && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
  10917. if (UsbDmaSize != pHalData->rxagg_usb_size
  10918. || 0x20 != pHalData->rxagg_usb_timeout) {
  10919. pHalData->rxagg_usb_size = UsbDmaSize;
  10920. pHalData->rxagg_usb_timeout = 0x20;
  10921. rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
  10922. pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
  10923. }
  10924. } else {
  10925. /* RTW_INFO("%s: Unknown wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
  10926. }
  10927. }
  10928. void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode)
  10929. {
  10930. #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
  10931. rtw_set_usb_agg_by_mode_customer(padapter, cur_wireless_mode, 0x3, 0x3);
  10932. return;
  10933. #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
  10934. rtw_set_usb_agg_by_mode_normal(padapter, cur_wireless_mode);
  10935. }
  10936. #endif /* CONFIG_USB_RX_AGGREGATION */
  10937. /* To avoid RX affect TX throughput */
  10938. void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer)
  10939. {
  10940. struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
  10941. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  10942. struct registry_priv *registry_par = &padapter->registrypriv;
  10943. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
  10944. u8 cur_wireless_mode = WIRELESS_INVALID;
  10945. #ifdef CONFIG_USB_RX_AGGREGATION
  10946. if (!registry_par->dynamic_agg_enable)
  10947. return;
  10948. #ifdef RTW_HALMAC
  10949. if (IS_HARDWARE_TYPE_8822BU(padapter) || IS_HARDWARE_TYPE_8821CU(padapter))
  10950. rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, NULL);
  10951. #else /* !RTW_HALMAC */
  10952. if (IS_HARDWARE_TYPE_8821U(padapter)) { /* || IS_HARDWARE_TYPE_8192EU(padapter)) */
  10953. /* This AGG_PH_TH only for UsbRxAggMode == USB_RX_AGG_USB */
  10954. if ((pHalData->rxagg_mode == RX_AGG_USB) && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) {
  10955. if (pdvobjpriv->traffic_stat.cur_tx_tp > 2 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
  10956. rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1010);
  10957. else if (pdvobjpriv->traffic_stat.last_tx_bytes > 220000 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
  10958. rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1006);
  10959. else
  10960. rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, 0x2005); /* dmc agg th 20K */
  10961. /* RTW_INFO("TX_TP=%u, RX_TP=%u\n", pdvobjpriv->traffic_stat.cur_tx_tp, pdvobjpriv->traffic_stat.cur_rx_tp); */
  10962. }
  10963. } else if (IS_HARDWARE_TYPE_8812(padapter)) {
  10964. #ifdef CONFIG_CONCURRENT_MODE
  10965. u8 i;
  10966. _adapter *iface;
  10967. u8 bassocaed = _FALSE;
  10968. struct mlme_ext_priv *mlmeext;
  10969. for (i = 0; i < pdvobjpriv->iface_nums; i++) {
  10970. iface = pdvobjpriv->padapters[i];
  10971. mlmeext = &iface->mlmeextpriv;
  10972. if (rtw_linked_check(iface) == _TRUE) {
  10973. if (mlmeext->cur_wireless_mode >= cur_wireless_mode)
  10974. cur_wireless_mode = mlmeext->cur_wireless_mode;
  10975. bassocaed = _TRUE;
  10976. }
  10977. }
  10978. if (bassocaed)
  10979. #endif
  10980. rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
  10981. #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
  10982. } else {
  10983. rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
  10984. #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
  10985. }
  10986. #endif /* RTW_HALMAC */
  10987. #endif /* CONFIG_USB_RX_AGGREGATION */
  10988. }
  10989. /* bus-agg check for SoftAP mode */
  10990. inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qsel)
  10991. {
  10992. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  10993. u8 chk_rst = _SUCCESS;
  10994. if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter))
  10995. return chk_rst;
  10996. /* if((pre_qsel == 0xFF)||(next_qsel== 0xFF)) */
  10997. /* return chk_rst; */
  10998. if (((pre_qsel == QSLT_HIGH) || ((next_qsel == QSLT_HIGH)))
  10999. && (pre_qsel != next_qsel)) {
  11000. /* RTW_INFO("### bus-agg break cause of qsel misatch, pre_qsel=0x%02x,next_qsel=0x%02x ###\n", */
  11001. /* pre_qsel,next_qsel); */
  11002. chk_rst = _FAIL;
  11003. }
  11004. return chk_rst;
  11005. }
  11006. /*
  11007. * Description:
  11008. * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload
  11009. * contant.
  11010. *
  11011. * Input:
  11012. * adapter: adapter pointer.
  11013. * page_num: The max. page number that user want to dump.
  11014. * page_size: page size of each page. eg. 128 bytes, 256 bytes, 512byte.
  11015. */
  11016. void dump_TX_FIFO(_adapter *padapter, u8 page_num, u16 page_size)
  11017. {
  11018. int i;
  11019. u8 val = 0;
  11020. u8 base = 0;
  11021. u32 addr = 0;
  11022. u32 count = (page_size / 8);
  11023. if (page_num <= 0) {
  11024. RTW_INFO("!!%s: incorrect input page_num paramter!\n", __func__);
  11025. return;
  11026. }
  11027. if (page_size < 128 || page_size > 512) {
  11028. RTW_INFO("!!%s: incorrect input page_size paramter!\n", __func__);
  11029. return;
  11030. }
  11031. RTW_INFO("+%s+\n", __func__);
  11032. val = rtw_read8(padapter, 0x106);
  11033. rtw_write8(padapter, 0x106, 0x69);
  11034. RTW_INFO("0x106: 0x%02x\n", val);
  11035. base = rtw_read8(padapter, 0x209);
  11036. RTW_INFO("0x209: 0x%02x\n", base);
  11037. addr = ((base)*page_size) / 8;
  11038. for (i = 0 ; i < page_num * count ; i += 2) {
  11039. rtw_write32(padapter, 0x140, addr + i);
  11040. printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
  11041. rtw_write32(padapter, 0x140, addr + i + 1);
  11042. printk(" %08x %08x\n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
  11043. }
  11044. }
  11045. #ifdef CONFIG_GPIO_API
  11046. u8 rtw_hal_get_gpio(_adapter *adapter, u8 gpio_num)
  11047. {
  11048. u8 value = 0;
  11049. u8 direction = 0;
  11050. u32 gpio_pin_input_val = REG_GPIO_PIN_CTRL;
  11051. u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
  11052. u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
  11053. u8 gpio_num_to_set = gpio_num;
  11054. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
  11055. if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
  11056. return value;
  11057. rtw_ps_deny(adapter, PS_DENY_IOCTL);
  11058. RTW_INFO("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate);
  11059. LeaveAllPowerSaveModeDirect(adapter);
  11060. if (gpio_num > 7) {
  11061. gpio_pin_input_val = REG_GPIO_PIN_CTRL_2;
  11062. gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
  11063. gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
  11064. gpio_num_to_set = gpio_num - 8;
  11065. }
  11066. /* Read GPIO Direction */
  11067. direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
  11068. /* According the direction to read register value */
  11069. if (direction)
  11070. value = (rtw_read8(adapter, gpio_pin_output_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
  11071. else
  11072. value = (rtw_read8(adapter, gpio_pin_input_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
  11073. rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
  11074. RTW_INFO("%s direction=%d value=%d\n", __FUNCTION__, direction, value);
  11075. return value;
  11076. }
  11077. int rtw_hal_set_gpio_output_value(_adapter *adapter, u8 gpio_num, bool isHigh)
  11078. {
  11079. u8 direction = 0;
  11080. u8 res = -1;
  11081. u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
  11082. u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
  11083. u8 gpio_num_to_set = gpio_num;
  11084. if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
  11085. return -1;
  11086. rtw_ps_deny(adapter, PS_DENY_IOCTL);
  11087. LeaveAllPowerSaveModeDirect(adapter);
  11088. if (gpio_num > 7) {
  11089. gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
  11090. gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
  11091. gpio_num_to_set = gpio_num - 8;
  11092. }
  11093. /* Read GPIO direction */
  11094. direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
  11095. /* If GPIO is output direction, setting value. */
  11096. if (direction) {
  11097. if (isHigh)
  11098. rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) | BIT(gpio_num_to_set));
  11099. else
  11100. rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) & ~BIT(gpio_num_to_set));
  11101. RTW_INFO("%s Set gpio %x[%d]=%d\n", __FUNCTION__, REG_GPIO_PIN_CTRL + 1, gpio_num, isHigh);
  11102. res = 0;
  11103. } else {
  11104. RTW_INFO("%s The gpio is input,not be set!\n", __FUNCTION__);
  11105. res = -1;
  11106. }
  11107. rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
  11108. return res;
  11109. }
  11110. int rtw_hal_config_gpio(_adapter *adapter, u8 gpio_num, bool isOutput)
  11111. {
  11112. u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
  11113. u8 gpio_num_to_set = gpio_num;
  11114. if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
  11115. return -1;
  11116. RTW_INFO("%s gpio_num =%d direction=%d\n", __FUNCTION__, gpio_num, isOutput);
  11117. rtw_ps_deny(adapter, PS_DENY_IOCTL);
  11118. LeaveAllPowerSaveModeDirect(adapter);
  11119. rtw_hal_gpio_multi_func_reset(adapter, gpio_num);
  11120. if (gpio_num > 7) {
  11121. gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
  11122. gpio_num_to_set = gpio_num - 8;
  11123. }
  11124. if (isOutput)
  11125. rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));
  11126. else
  11127. rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));
  11128. rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
  11129. return 0;
  11130. }
  11131. int rtw_hal_register_gpio_interrupt(_adapter *adapter, int gpio_num, void(*callback)(u8 level))
  11132. {
  11133. u8 value;
  11134. u8 direction;
  11135. PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
  11136. if (IS_HARDWARE_TYPE_8188E(adapter)) {
  11137. if (gpio_num > 7 || gpio_num < 4) {
  11138. RTW_PRINT("%s The gpio number does not included 4~7.\n", __FUNCTION__);
  11139. return -1;
  11140. }
  11141. }
  11142. rtw_ps_deny(adapter, PS_DENY_IOCTL);
  11143. LeaveAllPowerSaveModeDirect(adapter);
  11144. /* Read GPIO direction */
  11145. direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
  11146. if (direction) {
  11147. RTW_PRINT("%s Can't register output gpio as interrupt.\n", __FUNCTION__);
  11148. return -1;
  11149. }
  11150. /* Config GPIO Mode */
  11151. rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) | BIT(gpio_num));
  11152. /* Register GPIO interrupt handler*/
  11153. adapter->gpiointpriv.callback[gpio_num] = callback;
  11154. /* Set GPIO interrupt mode, 0:positive edge, 1:negative edge */
  11155. value = rtw_read8(adapter, REG_GPIO_PIN_CTRL) & BIT(gpio_num);
  11156. adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_HSIMR + 2) ^ value;
  11157. rtw_write8(adapter, REG_GPIO_INTM, adapter->gpiointpriv.interrupt_mode);
  11158. /* Enable GPIO interrupt */
  11159. adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) | BIT(gpio_num);
  11160. rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
  11161. rtw_hal_update_hisr_hsisr_ind(adapter, 1);
  11162. rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
  11163. return 0;
  11164. }
  11165. int rtw_hal_disable_gpio_interrupt(_adapter *adapter, int gpio_num)
  11166. {
  11167. u8 value;
  11168. u8 direction;
  11169. PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
  11170. if (IS_HARDWARE_TYPE_8188E(adapter)) {
  11171. if (gpio_num > 7 || gpio_num < 4) {
  11172. RTW_INFO("%s The gpio number does not included 4~7.\n", __FUNCTION__);
  11173. return -1;
  11174. }
  11175. }
  11176. rtw_ps_deny(adapter, PS_DENY_IOCTL);
  11177. LeaveAllPowerSaveModeDirect(adapter);
  11178. /* Config GPIO Mode */
  11179. rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(gpio_num));
  11180. /* Unregister GPIO interrupt handler*/
  11181. adapter->gpiointpriv.callback[gpio_num] = NULL;
  11182. /* Reset GPIO interrupt mode, 0:positive edge, 1:negative edge */
  11183. adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_GPIO_INTM) & ~BIT(gpio_num);
  11184. rtw_write8(adapter, REG_GPIO_INTM, 0x00);
  11185. /* Disable GPIO interrupt */
  11186. adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) & ~BIT(gpio_num);
  11187. rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
  11188. if (!adapter->gpiointpriv.interrupt_enable_mask)
  11189. rtw_hal_update_hisr_hsisr_ind(adapter, 0);
  11190. rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
  11191. return 0;
  11192. }
  11193. #endif
  11194. s8 rtw_hal_ch_sw_iqk_info_search(_adapter *padapter, u8 central_chnl, u8 bw_mode)
  11195. {
  11196. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
  11197. u8 i;
  11198. for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
  11199. if ((pHalData->iqk_reg_backup[i].central_chnl != 0)) {
  11200. if ((pHalData->iqk_reg_backup[i].central_chnl == central_chnl)
  11201. && (pHalData->iqk_reg_backup[i].bw_mode == bw_mode))
  11202. return i;
  11203. }
  11204. }
  11205. return -1;
  11206. }
  11207. void rtw_hal_ch_sw_iqk_info_backup(_adapter *padapter)
  11208. {
  11209. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
  11210. s8 res;
  11211. u8 i;
  11212. /* If it's an existed record, overwrite it */
  11213. res = rtw_hal_ch_sw_iqk_info_search(padapter, pHalData->current_channel, pHalData->current_channel_bw);
  11214. if ((res >= 0) && (res < MAX_IQK_INFO_BACKUP_CHNL_NUM)) {
  11215. rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[res]));
  11216. return;
  11217. }
  11218. /* Search for the empty record to use */
  11219. for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
  11220. if (pHalData->iqk_reg_backup[i].central_chnl == 0) {
  11221. rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[i]));
  11222. return;
  11223. }
  11224. }
  11225. /* Else, overwrite the oldest record */
  11226. for (i = 1; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++)
  11227. _rtw_memcpy(&(pHalData->iqk_reg_backup[i - 1]), &(pHalData->iqk_reg_backup[i]), sizeof(struct hal_iqk_reg_backup));
  11228. rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[MAX_IQK_INFO_BACKUP_CHNL_NUM - 1]));
  11229. }
  11230. void rtw_hal_ch_sw_iqk_info_restore(_adapter *padapter, u8 ch_sw_use_case)
  11231. {
  11232. rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_RESTORE, &ch_sw_use_case);
  11233. }
  11234. void rtw_dump_mac_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
  11235. {
  11236. u32 mac_cck_ok = 0, mac_ofdm_ok = 0, mac_ht_ok = 0, mac_vht_ok = 0;
  11237. u32 mac_cck_err = 0, mac_ofdm_err = 0, mac_ht_err = 0, mac_vht_err = 0;
  11238. u32 mac_cck_fa = 0, mac_ofdm_fa = 0, mac_ht_fa = 0;
  11239. u32 DropPacket = 0;
  11240. if (!rx_counter) {
  11241. rtw_warn_on(1);
  11242. return;
  11243. }
  11244. if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter))
  11245. phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
  11246. phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x3);
  11247. mac_cck_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
  11248. phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
  11249. mac_ofdm_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
  11250. phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x6);
  11251. mac_ht_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
  11252. mac_vht_ok = 0;
  11253. if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
  11254. phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
  11255. phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
  11256. mac_vht_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
  11257. phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
  11258. }
  11259. phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x4);
  11260. mac_cck_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
  11261. phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
  11262. mac_ofdm_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
  11263. phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x7);
  11264. mac_ht_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
  11265. mac_vht_err = 0;
  11266. if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
  11267. phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
  11268. phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
  11269. mac_vht_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
  11270. phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
  11271. }
  11272. phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x5);
  11273. mac_cck_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
  11274. phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x2);
  11275. mac_ofdm_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
  11276. phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x9);
  11277. mac_ht_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
  11278. /* Mac_DropPacket */
  11279. rtw_write32(padapter, REG_RXERR_RPT, (rtw_read32(padapter, REG_RXERR_RPT) & 0x0FFFFFFF) | Mac_DropPacket);
  11280. DropPacket = rtw_read32(padapter, REG_RXERR_RPT) & 0x0000FFFF;
  11281. rx_counter->rx_pkt_ok = mac_cck_ok + mac_ofdm_ok + mac_ht_ok + mac_vht_ok;
  11282. rx_counter->rx_pkt_crc_error = mac_cck_err + mac_ofdm_err + mac_ht_err + mac_vht_err;
  11283. rx_counter->rx_cck_fa = mac_cck_fa;
  11284. rx_counter->rx_ofdm_fa = mac_ofdm_fa;
  11285. rx_counter->rx_ht_fa = mac_ht_fa;
  11286. rx_counter->rx_pkt_drop = DropPacket;
  11287. }
  11288. void rtw_reset_mac_rx_counters(_adapter *padapter)
  11289. {
  11290. /* If no packet rx, MaxRx clock be gating ,BIT_DISGCLK bit19 set 1 for fix*/
  11291. if (IS_HARDWARE_TYPE_8703B(padapter) ||
  11292. IS_HARDWARE_TYPE_8723D(padapter) ||
  11293. IS_HARDWARE_TYPE_8188F(padapter) ||
  11294. IS_HARDWARE_TYPE_8188GTV(padapter) ||
  11295. IS_HARDWARE_TYPE_8192F(padapter))
  11296. phy_set_mac_reg(padapter, REG_RCR, BIT19, 0x1);
  11297. /* reset mac counter */
  11298. phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x1);
  11299. phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x0);
  11300. }
  11301. void rtw_dump_phy_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
  11302. {
  11303. u32 cckok = 0, cckcrc = 0, ofdmok = 0, ofdmcrc = 0, htok = 0, htcrc = 0, OFDM_FA = 0, CCK_FA = 0, vht_ok = 0, vht_err = 0;
  11304. if (!rx_counter) {
  11305. rtw_warn_on(1);
  11306. return;
  11307. }
  11308. if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
  11309. cckok = phy_query_bb_reg(padapter, 0xF04, 0x3FFF); /* [13:0] */
  11310. ofdmok = phy_query_bb_reg(padapter, 0xF14, 0x3FFF); /* [13:0] */
  11311. htok = phy_query_bb_reg(padapter, 0xF10, 0x3FFF); /* [13:0] */
  11312. vht_ok = phy_query_bb_reg(padapter, 0xF0C, 0x3FFF); /* [13:0] */
  11313. cckcrc = phy_query_bb_reg(padapter, 0xF04, 0x3FFF0000); /* [29:16] */
  11314. ofdmcrc = phy_query_bb_reg(padapter, 0xF14, 0x3FFF0000); /* [29:16] */
  11315. htcrc = phy_query_bb_reg(padapter, 0xF10, 0x3FFF0000); /* [29:16] */
  11316. vht_err = phy_query_bb_reg(padapter, 0xF0C, 0x3FFF0000); /* [29:16] */
  11317. CCK_FA = phy_query_bb_reg(padapter, 0xA5C, bMaskLWord);
  11318. OFDM_FA = phy_query_bb_reg(padapter, 0xF48, bMaskLWord);
  11319. } else {
  11320. cckok = phy_query_bb_reg(padapter, 0xF88, bMaskDWord);
  11321. ofdmok = phy_query_bb_reg(padapter, 0xF94, bMaskLWord);
  11322. htok = phy_query_bb_reg(padapter, 0xF90, bMaskLWord);
  11323. vht_ok = 0;
  11324. cckcrc = phy_query_bb_reg(padapter, 0xF84, bMaskDWord);
  11325. ofdmcrc = phy_query_bb_reg(padapter, 0xF94, bMaskHWord);
  11326. htcrc = phy_query_bb_reg(padapter, 0xF90, bMaskHWord);
  11327. vht_err = 0;
  11328. OFDM_FA = phy_query_bb_reg(padapter, 0xCF0, bMaskLWord) + phy_query_bb_reg(padapter, 0xCF2, bMaskLWord) +
  11329. phy_query_bb_reg(padapter, 0xDA2, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA4, bMaskLWord) +
  11330. phy_query_bb_reg(padapter, 0xDA6, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA8, bMaskLWord);
  11331. CCK_FA = (rtw_read8(padapter, 0xA5B) << 8) | (rtw_read8(padapter, 0xA5C));
  11332. }
  11333. rx_counter->rx_pkt_ok = cckok + ofdmok + htok + vht_ok;
  11334. rx_counter->rx_pkt_crc_error = cckcrc + ofdmcrc + htcrc + vht_err;
  11335. rx_counter->rx_ofdm_fa = OFDM_FA;
  11336. rx_counter->rx_cck_fa = CCK_FA;
  11337. }
  11338. void rtw_reset_phy_trx_ok_counters(_adapter *padapter)
  11339. {
  11340. if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
  11341. phy_set_bb_reg(padapter, 0xB58, BIT0, 0x1);
  11342. phy_set_bb_reg(padapter, 0xB58, BIT0, 0x0);
  11343. }
  11344. }
  11345. void rtw_reset_phy_rx_counters(_adapter *padapter)
  11346. {
  11347. /* reset phy counter */
  11348. if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
  11349. rtw_reset_phy_trx_ok_counters(padapter);
  11350. phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x1);/* reset OFDA FA counter */
  11351. phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x0);
  11352. phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */
  11353. phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
  11354. } else {
  11355. phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
  11356. rtw_msleep_os(10);
  11357. phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
  11358. phy_set_bb_reg(padapter, 0xD00, BIT27, 0x1);/* reset OFDA FA counter */
  11359. phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x1);/* reset OFDA FA counter */
  11360. phy_set_bb_reg(padapter, 0xD00, BIT27, 0x0);
  11361. phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x0);
  11362. phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */
  11363. phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
  11364. }
  11365. }
  11366. #ifdef DBG_RX_COUNTER_DUMP
  11367. void rtw_dump_drv_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
  11368. {
  11369. struct recv_priv *precvpriv = &padapter->recvpriv;
  11370. if (!rx_counter) {
  11371. rtw_warn_on(1);
  11372. return;
  11373. }
  11374. rx_counter->rx_pkt_ok = padapter->drv_rx_cnt_ok;
  11375. rx_counter->rx_pkt_crc_error = padapter->drv_rx_cnt_crcerror;
  11376. rx_counter->rx_pkt_drop = precvpriv->rx_drop - padapter->drv_rx_cnt_drop;
  11377. }
  11378. void rtw_reset_drv_rx_counters(_adapter *padapter)
  11379. {
  11380. struct recv_priv *precvpriv = &padapter->recvpriv;
  11381. padapter->drv_rx_cnt_ok = 0;
  11382. padapter->drv_rx_cnt_crcerror = 0;
  11383. padapter->drv_rx_cnt_drop = precvpriv->rx_drop;
  11384. }
  11385. void rtw_dump_phy_rxcnts_preprocess(_adapter *padapter, u8 rx_cnt_mode)
  11386. {
  11387. u8 initialgain;
  11388. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
  11389. if ((!(padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER)) && (rx_cnt_mode & DUMP_PHY_RX_COUNTER)) {
  11390. rtw_hal_get_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, NULL);
  11391. RTW_INFO("%s CurIGValue:0x%02x\n", __FUNCTION__, initialgain);
  11392. rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
  11393. /*disable dynamic functions, such as high power, DIG*/
  11394. rtw_phydm_ability_backup(padapter);
  11395. rtw_phydm_func_clr(padapter, (ODM_BB_DIG | ODM_BB_FA_CNT));
  11396. } else if ((padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) && (!(rx_cnt_mode & DUMP_PHY_RX_COUNTER))) {
  11397. /* turn on phy-dynamic functions */
  11398. rtw_phydm_ability_restore(padapter);
  11399. initialgain = 0xff; /* restore RX GAIN */
  11400. rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
  11401. }
  11402. }
  11403. void rtw_dump_rx_counters(_adapter *padapter)
  11404. {
  11405. struct dbg_rx_counter rx_counter;
  11406. if (padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER) {
  11407. _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
  11408. rtw_dump_drv_rx_counters(padapter, &rx_counter);
  11409. RTW_INFO("Drv Received packet OK:%d CRC error:%d Drop Packets: %d\n",
  11410. rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_pkt_drop);
  11411. rtw_reset_drv_rx_counters(padapter);
  11412. }
  11413. if (padapter->dump_rx_cnt_mode & DUMP_MAC_RX_COUNTER) {
  11414. _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
  11415. rtw_dump_mac_rx_counters(padapter, &rx_counter);
  11416. RTW_INFO("Mac Received packet OK:%d CRC error:%d FA Counter: %d Drop Packets: %d\n",
  11417. rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
  11418. rx_counter.rx_cck_fa + rx_counter.rx_ofdm_fa + rx_counter.rx_ht_fa,
  11419. rx_counter.rx_pkt_drop);
  11420. rtw_reset_mac_rx_counters(padapter);
  11421. }
  11422. if (padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) {
  11423. _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
  11424. rtw_dump_phy_rx_counters(padapter, &rx_counter);
  11425. /* RTW_INFO("%s: OFDM_FA =%d\n", __FUNCTION__, rx_counter.rx_ofdm_fa); */
  11426. /* RTW_INFO("%s: CCK_FA =%d\n", __FUNCTION__, rx_counter.rx_cck_fa); */
  11427. RTW_INFO("Phy Received packet OK:%d CRC error:%d FA Counter: %d\n", rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
  11428. rx_counter.rx_ofdm_fa + rx_counter.rx_cck_fa);
  11429. rtw_reset_phy_rx_counters(padapter);
  11430. }
  11431. }
  11432. #endif
  11433. u8 rtw_get_current_tx_sgi(_adapter *padapter, struct sta_info *psta)
  11434. {
  11435. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
  11436. u8 curr_tx_sgi = 0;
  11437. struct ra_sta_info *ra_info;
  11438. if (!psta)
  11439. return curr_tx_sgi;
  11440. if (padapter->fix_rate == 0xff) {
  11441. #if defined(CONFIG_RTL8188E)
  11442. #if (RATE_ADAPTIVE_SUPPORT == 1)
  11443. curr_tx_sgi = hal_data->odmpriv.ra_info[psta->cmn.mac_id].rate_sgi;
  11444. #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
  11445. #else
  11446. ra_info = &psta->cmn.ra_info;
  11447. curr_tx_sgi = ((ra_info->curr_tx_rate) & 0x80) >> 7;
  11448. #endif
  11449. } else {
  11450. curr_tx_sgi = ((padapter->fix_rate) & 0x80) >> 7;
  11451. }
  11452. return curr_tx_sgi;
  11453. }
  11454. u8 rtw_get_current_tx_rate(_adapter *padapter, struct sta_info *psta)
  11455. {
  11456. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
  11457. u8 rate_id = 0;
  11458. struct ra_sta_info *ra_info;
  11459. if (!psta)
  11460. return rate_id;
  11461. if (padapter->fix_rate == 0xff) {
  11462. #if defined(CONFIG_RTL8188E)
  11463. #if (RATE_ADAPTIVE_SUPPORT == 1)
  11464. rate_id = hal_data->odmpriv.ra_info[psta->cmn.mac_id].decision_rate;
  11465. #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
  11466. #else
  11467. ra_info = &psta->cmn.ra_info;
  11468. rate_id = ra_info->curr_tx_rate & 0x7f;
  11469. #endif
  11470. } else {
  11471. rate_id = padapter->fix_rate & 0x7f;
  11472. }
  11473. return rate_id;
  11474. }
  11475. void update_IOT_info(_adapter *padapter)
  11476. {
  11477. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  11478. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  11479. switch (pmlmeinfo->assoc_AP_vendor) {
  11480. case HT_IOT_PEER_MARVELL:
  11481. pmlmeinfo->turboMode_cts2self = 1;
  11482. pmlmeinfo->turboMode_rtsen = 0;
  11483. break;
  11484. case HT_IOT_PEER_RALINK:
  11485. pmlmeinfo->turboMode_cts2self = 0;
  11486. pmlmeinfo->turboMode_rtsen = 1;
  11487. break;
  11488. case HT_IOT_PEER_REALTEK:
  11489. /* rtw_write16(padapter, 0x4cc, 0xffff); */
  11490. /* rtw_write16(padapter, 0x546, 0x01c0); */
  11491. break;
  11492. default:
  11493. pmlmeinfo->turboMode_cts2self = 0;
  11494. pmlmeinfo->turboMode_rtsen = 1;
  11495. break;
  11496. }
  11497. }
  11498. /* TODO: merge with phydm, see odm_SetCrystalCap() */
  11499. void hal_set_crystal_cap(_adapter *adapter, u8 crystal_cap)
  11500. {
  11501. crystal_cap = crystal_cap & 0x3F;
  11502. switch (rtw_get_chip_type(adapter)) {
  11503. #if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV)
  11504. case RTL8188E:
  11505. case RTL8188F:
  11506. case RTL8188GTV:
  11507. /* write 0x24[16:11] = 0x24[22:17] = CrystalCap */
  11508. phy_set_bb_reg(adapter, REG_AFE_XTAL_CTRL, 0x007FF800, (crystal_cap | (crystal_cap << 6)));
  11509. break;
  11510. #endif
  11511. #if defined(CONFIG_RTL8812A)
  11512. case RTL8812:
  11513. /* write 0x2C[30:25] = 0x2C[24:19] = CrystalCap */
  11514. phy_set_bb_reg(adapter, REG_MAC_PHY_CTRL, 0x7FF80000, (crystal_cap | (crystal_cap << 6)));
  11515. break;
  11516. #endif
  11517. #if defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || \
  11518. defined(CONFIG_RTL8723D) || defined(CONFIG_RTL8821A) || \
  11519. defined(CONFIG_RTL8192E)
  11520. case RTL8723B:
  11521. case RTL8703B:
  11522. case RTL8723D:
  11523. case RTL8821:
  11524. case RTL8192E:
  11525. /* write 0x2C[23:18] = 0x2C[17:12] = CrystalCap */
  11526. phy_set_bb_reg(adapter, REG_MAC_PHY_CTRL, 0x00FFF000, (crystal_cap | (crystal_cap << 6)));
  11527. break;
  11528. #endif
  11529. #if defined(CONFIG_RTL8814A)
  11530. case RTL8814A:
  11531. /* write 0x2C[26:21] = 0x2C[20:15] = CrystalCap*/
  11532. phy_set_bb_reg(adapter, REG_MAC_PHY_CTRL, 0x07FF8000, (crystal_cap | (crystal_cap << 6)));
  11533. break;
  11534. #endif
  11535. #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8192F)
  11536. case RTL8822B:
  11537. case RTL8821C:
  11538. case RTL8192F:
  11539. /* write 0x28[6:1] = 0x24[30:25] = CrystalCap */
  11540. crystal_cap = crystal_cap & 0x3F;
  11541. phy_set_bb_reg(adapter, REG_AFE_XTAL_CTRL, 0x7E000000, crystal_cap);
  11542. phy_set_bb_reg(adapter, REG_AFE_PLL_CTRL, 0x7E, crystal_cap);
  11543. break;
  11544. #endif
  11545. #if defined(CONFIG_RTL8710B)
  11546. case RTL8710B:
  11547. /*Change by ylb 20160728, Becase 0x2C[23:12] is removed to syson 0x60[29:18] */
  11548. /* 0x2C[23:18] = 0x2C[29:24] = CrystalCap //Xo:[29:24], Xi:[23:18]*/
  11549. crystal_cap = crystal_cap & 0x3F;
  11550. hal_set_syson_reg(adapter, REG_SYS_XTAL_CTRL0, 0x3FFC0000, (crystal_cap | (crystal_cap << 6)));
  11551. break;
  11552. #endif
  11553. default:
  11554. rtw_warn_on(1);
  11555. }
  11556. }
  11557. int hal_spec_init(_adapter *adapter)
  11558. {
  11559. u8 interface_type = 0;
  11560. int ret = _SUCCESS;
  11561. interface_type = rtw_get_intf_type(adapter);
  11562. switch (rtw_get_chip_type(adapter)) {
  11563. #ifdef CONFIG_RTL8723B
  11564. case RTL8723B:
  11565. init_hal_spec_8723b(adapter);
  11566. break;
  11567. #endif
  11568. #ifdef CONFIG_RTL8703B
  11569. case RTL8703B:
  11570. init_hal_spec_8703b(adapter);
  11571. break;
  11572. #endif
  11573. #ifdef CONFIG_RTL8723D
  11574. case RTL8723D:
  11575. init_hal_spec_8723d(adapter);
  11576. break;
  11577. #endif
  11578. #ifdef CONFIG_RTL8188E
  11579. case RTL8188E:
  11580. init_hal_spec_8188e(adapter);
  11581. break;
  11582. #endif
  11583. #ifdef CONFIG_RTL8188F
  11584. case RTL8188F:
  11585. init_hal_spec_8188f(adapter);
  11586. break;
  11587. #endif
  11588. #ifdef CONFIG_RTL8188GTV
  11589. case RTL8188GTV:
  11590. init_hal_spec_8188gtv(adapter);
  11591. break;
  11592. #endif
  11593. #ifdef CONFIG_RTL8812A
  11594. case RTL8812:
  11595. init_hal_spec_8812a(adapter);
  11596. break;
  11597. #endif
  11598. #ifdef CONFIG_RTL8821A
  11599. case RTL8821:
  11600. init_hal_spec_8821a(adapter);
  11601. break;
  11602. #endif
  11603. #ifdef CONFIG_RTL8192E
  11604. case RTL8192E:
  11605. init_hal_spec_8192e(adapter);
  11606. break;
  11607. #endif
  11608. #ifdef CONFIG_RTL8814A
  11609. case RTL8814A:
  11610. init_hal_spec_8814a(adapter);
  11611. break;
  11612. #endif
  11613. #ifdef CONFIG_RTL8822B
  11614. case RTL8822B:
  11615. rtl8822b_init_hal_spec(adapter);
  11616. break;
  11617. #endif
  11618. #ifdef CONFIG_RTL8821C
  11619. case RTL8821C:
  11620. init_hal_spec_rtl8821c(adapter);
  11621. break;
  11622. #endif
  11623. #ifdef CONFIG_RTL8710B
  11624. case RTL8710B:
  11625. init_hal_spec_8710b(adapter);
  11626. break;
  11627. #endif
  11628. #ifdef CONFIG_RTL8192F
  11629. case RTL8192F:
  11630. init_hal_spec_8192f(adapter);
  11631. break;
  11632. #endif
  11633. default:
  11634. RTW_ERR("%s: unknown chip_type:%u\n"
  11635. , __func__, rtw_get_chip_type(adapter));
  11636. ret = _FAIL;
  11637. break;
  11638. }
  11639. return ret;
  11640. }
  11641. static const char *const _band_cap_str[] = {
  11642. /* BIT0 */"2G",
  11643. /* BIT1 */"5G",
  11644. };
  11645. static const char *const _bw_cap_str[] = {
  11646. /* BIT0 */"5M",
  11647. /* BIT1 */"10M",
  11648. /* BIT2 */"20M",
  11649. /* BIT3 */"40M",
  11650. /* BIT4 */"80M",
  11651. /* BIT5 */"160M",
  11652. /* BIT6 */"80_80M",
  11653. };
  11654. static const char *const _proto_cap_str[] = {
  11655. /* BIT0 */"b",
  11656. /* BIT1 */"g",
  11657. /* BIT2 */"n",
  11658. /* BIT3 */"ac",
  11659. };
  11660. static const char *const _wl_func_str[] = {
  11661. /* BIT0 */"P2P",
  11662. /* BIT1 */"MIRACAST",
  11663. /* BIT2 */"TDLS",
  11664. /* BIT3 */"FTM",
  11665. };
  11666. void dump_hal_spec(void *sel, _adapter *adapter)
  11667. {
  11668. struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
  11669. int i;
  11670. RTW_PRINT_SEL(sel, "macid_num:%u\n", hal_spec->macid_num);
  11671. RTW_PRINT_SEL(sel, "sec_cap:0x%02x\n", hal_spec->sec_cap);
  11672. RTW_PRINT_SEL(sel, "sec_cam_ent_num:%u\n", hal_spec->sec_cam_ent_num);
  11673. RTW_PRINT_SEL(sel, "rfpath_num_2g:%u\n", hal_spec->rfpath_num_2g);
  11674. RTW_PRINT_SEL(sel, "rfpath_num_5g:%u\n", hal_spec->rfpath_num_5g);
  11675. RTW_PRINT_SEL(sel, "txgi_max:%u\n", hal_spec->txgi_max);
  11676. RTW_PRINT_SEL(sel, "txgi_pdbm:%u\n", hal_spec->txgi_pdbm);
  11677. RTW_PRINT_SEL(sel, "max_tx_cnt:%u\n", hal_spec->max_tx_cnt);
  11678. RTW_PRINT_SEL(sel, "tx_nss_num:%u\n", hal_spec->tx_nss_num);
  11679. RTW_PRINT_SEL(sel, "rx_nss_num:%u\n", hal_spec->rx_nss_num);
  11680. RTW_PRINT_SEL(sel, "band_cap:");
  11681. for (i = 0; i < BAND_CAP_BIT_NUM; i++) {
  11682. if (((hal_spec->band_cap) >> i) & BIT0 && _band_cap_str[i])
  11683. _RTW_PRINT_SEL(sel, "%s ", _band_cap_str[i]);
  11684. }
  11685. _RTW_PRINT_SEL(sel, "\n");
  11686. RTW_PRINT_SEL(sel, "bw_cap:");
  11687. for (i = 0; i < BW_CAP_BIT_NUM; i++) {
  11688. if (((hal_spec->bw_cap) >> i) & BIT0 && _bw_cap_str[i])
  11689. _RTW_PRINT_SEL(sel, "%s ", _bw_cap_str[i]);
  11690. }
  11691. _RTW_PRINT_SEL(sel, "\n");
  11692. RTW_PRINT_SEL(sel, "proto_cap:");
  11693. for (i = 0; i < PROTO_CAP_BIT_NUM; i++) {
  11694. if (((hal_spec->proto_cap) >> i) & BIT0 && _proto_cap_str[i])
  11695. _RTW_PRINT_SEL(sel, "%s ", _proto_cap_str[i]);
  11696. }
  11697. _RTW_PRINT_SEL(sel, "\n");
  11698. RTW_PRINT_SEL(sel, "wl_func:");
  11699. for (i = 0; i < WL_FUNC_BIT_NUM; i++) {
  11700. if (((hal_spec->wl_func) >> i) & BIT0 && _wl_func_str[i])
  11701. _RTW_PRINT_SEL(sel, "%s ", _wl_func_str[i]);
  11702. }
  11703. _RTW_PRINT_SEL(sel, "\n");
  11704. RTW_PRINT_SEL(sel, "rx_tsf_filter:%u\n", hal_spec->rx_tsf_filter);
  11705. RTW_PRINT_SEL(sel, "pg_txpwr_saddr:0x%X\n", hal_spec->pg_txpwr_saddr);
  11706. RTW_PRINT_SEL(sel, "pg_txgi_diff_factor:%u\n", hal_spec->pg_txgi_diff_factor);
  11707. }
  11708. inline bool hal_chk_band_cap(_adapter *adapter, u8 cap)
  11709. {
  11710. return GET_HAL_SPEC(adapter)->band_cap & cap;
  11711. }
  11712. inline bool hal_chk_bw_cap(_adapter *adapter, u8 cap)
  11713. {
  11714. return GET_HAL_SPEC(adapter)->bw_cap & cap;
  11715. }
  11716. inline bool hal_chk_proto_cap(_adapter *adapter, u8 cap)
  11717. {
  11718. return GET_HAL_SPEC(adapter)->proto_cap & cap;
  11719. }
  11720. inline bool hal_chk_wl_func(_adapter *adapter, u8 func)
  11721. {
  11722. return GET_HAL_SPEC(adapter)->wl_func & func;
  11723. }
  11724. inline bool hal_is_band_support(_adapter *adapter, u8 band)
  11725. {
  11726. return GET_HAL_SPEC(adapter)->band_cap & band_to_band_cap(band);
  11727. }
  11728. inline bool hal_is_bw_support(_adapter *adapter, u8 bw)
  11729. {
  11730. return GET_HAL_SPEC(adapter)->bw_cap & ch_width_to_bw_cap(bw);
  11731. }
  11732. inline bool hal_is_wireless_mode_support(_adapter *adapter, u8 mode)
  11733. {
  11734. u8 proto_cap = GET_HAL_SPEC(adapter)->proto_cap;
  11735. if (mode == WIRELESS_11B)
  11736. if ((proto_cap & PROTO_CAP_11B) && hal_chk_band_cap(adapter, BAND_CAP_2G))
  11737. return 1;
  11738. if (mode == WIRELESS_11G)
  11739. if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_2G))
  11740. return 1;
  11741. if (mode == WIRELESS_11A)
  11742. if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_5G))
  11743. return 1;
  11744. if (mode == WIRELESS_11_24N)
  11745. if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_2G))
  11746. return 1;
  11747. if (mode == WIRELESS_11_5N)
  11748. if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_5G))
  11749. return 1;
  11750. if (mode == WIRELESS_11AC)
  11751. if ((proto_cap & PROTO_CAP_11AC) && hal_chk_band_cap(adapter, BAND_CAP_5G))
  11752. return 1;
  11753. return 0;
  11754. }
  11755. /*
  11756. * hal_largest_bw - starting from in_bw, get largest bw supported by HAL
  11757. * @adapter:
  11758. * @in_bw: starting bw, value of enum channel_width
  11759. *
  11760. * Returns: value of enum channel_width
  11761. */
  11762. u8 hal_largest_bw(_adapter *adapter, u8 in_bw)
  11763. {
  11764. for (; in_bw > CHANNEL_WIDTH_20; in_bw--) {
  11765. if (hal_is_bw_support(adapter, in_bw))
  11766. break;
  11767. }
  11768. if (!hal_is_bw_support(adapter, in_bw))
  11769. rtw_warn_on(1);
  11770. return in_bw;
  11771. }
  11772. void ResumeTxBeacon(_adapter *padapter)
  11773. {
  11774. rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
  11775. rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) | BIT(6));
  11776. #ifdef RTW_HALMAC
  11777. /* Add this for driver using HALMAC because driver doesn't have setup time init by self */
  11778. /* TBTT setup time */
  11779. rtw_write8(padapter, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME);
  11780. #endif
  11781. /* TBTT hold time: 0x540[19:8] */
  11782. rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
  11783. rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
  11784. (rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
  11785. }
  11786. void StopTxBeacon(_adapter *padapter)
  11787. {
  11788. rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
  11789. rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) & (~BIT6));
  11790. /* TBTT hold time: 0x540[19:8] */
  11791. rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF);
  11792. rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
  11793. (rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8));
  11794. }
  11795. #ifdef CONFIG_MI_WITH_MBSSID_CAM /*HW port0 - MBSS*/
  11796. #ifdef CONFIG_CLIENT_PORT_CFG
  11797. const u8 _clt_port_id[MAX_CLIENT_PORT_NUM] = {
  11798. CLT_PORT0,
  11799. CLT_PORT1,
  11800. CLT_PORT2,
  11801. CLT_PORT3
  11802. };
  11803. void rtw_clt_port_init(struct clt_port_t *cltp)
  11804. {
  11805. cltp->bmp = 0;
  11806. cltp->num = 0;
  11807. _rtw_spinlock_init(&cltp->lock);
  11808. }
  11809. void rtw_clt_port_deinit(struct clt_port_t *cltp)
  11810. {
  11811. _rtw_spinlock_free(&cltp->lock);
  11812. }
  11813. static void _hw_client_port_alloc(_adapter *adapter)
  11814. {
  11815. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  11816. struct clt_port_t *cltp = &dvobj->clt_port;
  11817. _irqL irql;
  11818. int i;
  11819. #if 0
  11820. if (cltp->num > MAX_CLIENT_PORT_NUM) {
  11821. RTW_ERR(ADPT_FMT" cann't alloc client (%d)\n", ADPT_ARG(adapter), cltp->num);
  11822. rtw_warn_on(1);
  11823. return;
  11824. }
  11825. #endif
  11826. if (adapter->client_id != MAX_CLIENT_PORT_NUM) {
  11827. RTW_INFO(ADPT_FMT" client_id %d has allocated port:%d\n",
  11828. ADPT_ARG(adapter), adapter->client_id, adapter->client_port);
  11829. return;
  11830. }
  11831. _enter_critical_bh(&cltp->lock, &irql);
  11832. for (i = 0; i < MAX_CLIENT_PORT_NUM; i++) {
  11833. if (!(cltp->bmp & BIT(i)))
  11834. break;
  11835. }
  11836. if (i < MAX_CLIENT_PORT_NUM) {
  11837. adapter->client_id = i;
  11838. cltp->bmp |= BIT(i);
  11839. adapter->client_port = _clt_port_id[i];
  11840. }
  11841. cltp->num++;
  11842. _exit_critical_bh(&cltp->lock, &irql);
  11843. RTW_INFO("%s("ADPT_FMT")id:%d, port:%d clt_num:%d\n",
  11844. __func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
  11845. }
  11846. static void _hw_client_port_free(_adapter *adapter)
  11847. {
  11848. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  11849. struct clt_port_t *cltp = &dvobj->clt_port;
  11850. _irqL irql;
  11851. #if 0
  11852. if (adapter->client_id >= MAX_CLIENT_PORT_NUM) {
  11853. RTW_ERR(ADPT_FMT" client_id %d is invalid\n", ADPT_ARG(adapter), adapter->client_id);
  11854. /*rtw_warn_on(1);*/
  11855. }
  11856. #endif
  11857. RTW_INFO("%s ("ADPT_FMT") id:%d, port:%d clt_num:%d\n",
  11858. __func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
  11859. _enter_critical_bh(&cltp->lock, &irql);
  11860. if (adapter->client_id != MAX_CLIENT_PORT_NUM) {
  11861. cltp->bmp &= ~ BIT(adapter->client_id);
  11862. adapter->client_id = MAX_CLIENT_PORT_NUM;
  11863. adapter->client_port = CLT_PORT_INVALID;
  11864. }
  11865. cltp->num--;
  11866. if (cltp->num < 0)
  11867. cltp->num = 0;
  11868. _exit_critical_bh(&cltp->lock, &irql);
  11869. }
  11870. void rtw_hw_client_port_allocate(_adapter *adapter)
  11871. {
  11872. struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
  11873. if (hal_spec->port_num != 5)
  11874. return;
  11875. _hw_client_port_alloc(adapter);
  11876. }
  11877. void rtw_hw_client_port_release(_adapter *adapter)
  11878. {
  11879. struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
  11880. if (hal_spec->port_num != 5)
  11881. return;
  11882. _hw_client_port_free(adapter);
  11883. }
  11884. #endif /*CONFIG_CLIENT_PORT_CFG*/
  11885. void hw_var_set_opmode_mbid(_adapter *Adapter, u8 mode)
  11886. {
  11887. RTW_INFO("%s()-"ADPT_FMT" mode = %d\n", __func__, ADPT_ARG(Adapter), mode);
  11888. rtw_hal_rcr_set_chk_bssid(Adapter, MLME_ACTION_NONE);
  11889. /* set net_type */
  11890. Set_MSR(Adapter, mode);
  11891. if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
  11892. if (!rtw_mi_get_ap_num(Adapter) && !rtw_mi_get_mesh_num(Adapter))
  11893. StopTxBeacon(Adapter);
  11894. } else if (mode == _HW_STATE_ADHOC_)
  11895. ResumeTxBeacon(Adapter);
  11896. else if (mode == _HW_STATE_AP_)
  11897. /* enable rx ps-poll */
  11898. rtw_write16(Adapter, REG_RXFLTMAP1, rtw_read16(Adapter, REG_RXFLTMAP1) | BIT_CTRLFLT10EN);
  11899. /* enable rx data frame */
  11900. rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
  11901. #ifdef CONFIG_CLIENT_PORT_CFG
  11902. if (mode == _HW_STATE_STATION_)
  11903. rtw_hw_client_port_allocate(Adapter);
  11904. else
  11905. rtw_hw_client_port_release(Adapter);
  11906. #endif
  11907. #if defined(CONFIG_RTL8192F)
  11908. rtw_write16(Adapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(Adapter,
  11909. REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
  11910. #endif
  11911. }
  11912. #endif
  11913. #ifdef CONFIG_ANTENNA_DIVERSITY
  11914. u8 rtw_hal_antdiv_before_linked(_adapter *padapter)
  11915. {
  11916. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
  11917. u8 cur_ant, change_ant;
  11918. if (!pHalData->AntDivCfg)
  11919. return _FALSE;
  11920. if (pHalData->sw_antdiv_bl_state == 0) {
  11921. pHalData->sw_antdiv_bl_state = 1;
  11922. rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &cur_ant, NULL);
  11923. change_ant = (cur_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
  11924. return rtw_antenna_select_cmd(padapter, change_ant, _FALSE);
  11925. }
  11926. pHalData->sw_antdiv_bl_state = 0;
  11927. return _FALSE;
  11928. }
  11929. void rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src)
  11930. {
  11931. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
  11932. if (pHalData->AntDivCfg) {
  11933. /*RTW_INFO("update_network=> org-RSSI(%d), new-RSSI(%d)\n", dst->Rssi, src->Rssi);*/
  11934. /*select optimum_antenna for before linked =>For antenna diversity*/
  11935. if (dst->Rssi >= src->Rssi) {/*keep org parameter*/
  11936. src->Rssi = dst->Rssi;
  11937. src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;
  11938. }
  11939. }
  11940. }
  11941. #endif
  11942. #ifdef CONFIG_PHY_CAPABILITY_QUERY
  11943. void rtw_dump_phy_cap_by_phydmapi(void *sel, _adapter *adapter)
  11944. {
  11945. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
  11946. struct phy_spec_t *phy_spec = &pHalData->phy_spec;
  11947. RTW_PRINT_SEL(sel, "[PHY SPEC] TRx Capability : 0x%08x\n", phy_spec->trx_cap);
  11948. RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Stream Num Index : %d\n", (phy_spec->trx_cap >> 24) & 0xFF); /*Tx Stream Num Index [31:24]*/
  11949. RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Stream Num Index : %d\n", (phy_spec->trx_cap >> 16) & 0xFF); /*Rx Stream Num Index [23:16]*/
  11950. RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Path Num Index : %d\n", (phy_spec->trx_cap >> 8) & 0xFF);/*Tx Path Num Index [15:8]*/
  11951. RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Path Num Index : %d\n\n", (phy_spec->trx_cap & 0xFF));/*Rx Path Num Index [7:0]*/
  11952. RTW_PRINT_SEL(sel, "[PHY SPEC] STBC Capability : 0x%08x\n", phy_spec->stbc_cap);
  11953. RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Tx : %s\n", ((phy_spec->stbc_cap >> 24) & 0xFF) ? "Supported" : "N/A"); /*VHT STBC Tx [31:24]*/
  11954. /*VHT STBC Rx [23:16]
  11955. 0 = not support
  11956. 1 = support for 1 spatial stream
  11957. 2 = support for 1 or 2 spatial streams
  11958. 3 = support for 1 or 2 or 3 spatial streams
  11959. 4 = support for 1 or 2 or 3 or 4 spatial streams*/
  11960. RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Rx :%d\n", ((phy_spec->stbc_cap >> 16) & 0xFF));
  11961. RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Tx : %s\n", ((phy_spec->stbc_cap >> 8) & 0xFF) ? "Supported" : "N/A"); /*HT STBC Tx [15:8]*/
  11962. /*HT STBC Rx [7:0]
  11963. 0 = not support
  11964. 1 = support for 1 spatial stream
  11965. 2 = support for 1 or 2 spatial streams
  11966. 3 = support for 1 or 2 or 3 spatial streams*/
  11967. RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Rx : %d\n\n", (phy_spec->stbc_cap & 0xFF));
  11968. RTW_PRINT_SEL(sel, "[PHY SPEC] LDPC Capability : 0x%08x\n", phy_spec->ldpc_cap);
  11969. RTW_PRINT_SEL(sel, "[PHY SPEC] VHT LDPC Tx : %s\n", ((phy_spec->ldpc_cap >> 24) & 0xFF) ? "Supported" : "N/A"); /*VHT LDPC Tx [31:24]*/
  11970. RTW_PRINT_SEL(sel, "[PHY SPEC] VHT LDPC Rx : %s\n", ((phy_spec->ldpc_cap >> 16) & 0xFF) ? "Supported" : "N/A"); /*VHT LDPC Rx [23:16]*/
  11971. RTW_PRINT_SEL(sel, "[PHY SPEC] HT LDPC Tx : %s\n", ((phy_spec->ldpc_cap >> 8) & 0xFF) ? "Supported" : "N/A"); /*HT LDPC Tx [15:8]*/
  11972. RTW_PRINT_SEL(sel, "[PHY SPEC] HT LDPC Rx : %s\n\n", (phy_spec->ldpc_cap & 0xFF) ? "Supported" : "N/A"); /*HT LDPC Rx [7:0]*/
  11973. #ifdef CONFIG_BEAMFORMING
  11974. RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF Capability : 0x%08x\n", phy_spec->txbf_cap);
  11975. RTW_PRINT_SEL(sel, "[PHY SPEC] VHT MU Bfer : %s\n", ((phy_spec->txbf_cap >> 28) & 0xF) ? "Supported" : "N/A"); /*VHT MU Bfer [31:28]*/
  11976. RTW_PRINT_SEL(sel, "[PHY SPEC] VHT MU Bfee : %s\n", ((phy_spec->txbf_cap >> 24) & 0xF) ? "Supported" : "N/A"); /*VHT MU Bfee [27:24]*/
  11977. RTW_PRINT_SEL(sel, "[PHY SPEC] VHT SU Bfer : %s\n", ((phy_spec->txbf_cap >> 20) & 0xF) ? "Supported" : "N/A"); /*VHT SU Bfer [23:20]*/
  11978. RTW_PRINT_SEL(sel, "[PHY SPEC] VHT SU Bfee : %s\n", ((phy_spec->txbf_cap >> 16) & 0xF) ? "Supported" : "N/A"); /*VHT SU Bfee [19:16]*/
  11979. RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfer : %s\n", ((phy_spec->txbf_cap >> 4) & 0xF) ? "Supported" : "N/A"); /*HT Bfer [7:4]*/
  11980. RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfee : %s\n\n", (phy_spec->txbf_cap & 0xF) ? "Supported" : "N/A"); /*HT Bfee [3:0]*/
  11981. RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF parameter : 0x%08x\n", phy_spec->txbf_param);
  11982. RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Sounding Dim : %d\n", (phy_spec->txbf_param >> 24) & 0xFF); /*VHT Sounding Dim [31:24]*/
  11983. RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Steering Ant : %d\n", (phy_spec->txbf_param >> 16) & 0xFF); /*VHT Steering Ant [23:16]*/
  11984. RTW_PRINT_SEL(sel, "[PHY SPEC] HT Sounding Dim : %d\n", (phy_spec->txbf_param >> 8) & 0xFF); /*HT Sounding Dim [15:8]*/
  11985. RTW_PRINT_SEL(sel, "[PHY SPEC] HT Steering Ant : %d\n", phy_spec->txbf_param & 0xFF); /*HT Steering Ant [7:0]*/
  11986. #endif
  11987. }
  11988. #else
  11989. void rtw_dump_phy_cap_by_hal(void *sel, _adapter *adapter)
  11990. {
  11991. u8 phy_cap = _FALSE;
  11992. /* STBC */
  11993. rtw_hal_get_def_var(adapter, HAL_DEF_TX_STBC, (u8 *)&phy_cap);
  11994. RTW_PRINT_SEL(sel, "[HAL] STBC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
  11995. phy_cap = _FALSE;
  11996. rtw_hal_get_def_var(adapter, HAL_DEF_RX_STBC, (u8 *)&phy_cap);
  11997. RTW_PRINT_SEL(sel, "[HAL] STBC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
  11998. /* LDPC support */
  11999. phy_cap = _FALSE;
  12000. rtw_hal_get_def_var(adapter, HAL_DEF_TX_LDPC, (u8 *)&phy_cap);
  12001. RTW_PRINT_SEL(sel, "[HAL] LDPC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
  12002. phy_cap = _FALSE;
  12003. rtw_hal_get_def_var(adapter, HAL_DEF_RX_LDPC, (u8 *)&phy_cap);
  12004. RTW_PRINT_SEL(sel, "[HAL] LDPC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
  12005. #ifdef CONFIG_BEAMFORMING
  12006. phy_cap = _FALSE;
  12007. rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&phy_cap);
  12008. RTW_PRINT_SEL(sel, "[HAL] Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
  12009. phy_cap = _FALSE;
  12010. rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&phy_cap);
  12011. RTW_PRINT_SEL(sel, "[HAL] Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
  12012. phy_cap = _FALSE;
  12013. rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMER, &phy_cap);
  12014. RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
  12015. phy_cap = _FALSE;
  12016. rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMEE, &phy_cap);
  12017. RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
  12018. #endif
  12019. }
  12020. #endif
  12021. void rtw_dump_phy_cap(void *sel, _adapter *adapter)
  12022. {
  12023. RTW_PRINT_SEL(sel, "\n ======== PHY Capability ========\n");
  12024. #ifdef CONFIG_PHY_CAPABILITY_QUERY
  12025. rtw_dump_phy_cap_by_phydmapi(sel, adapter);
  12026. #else
  12027. rtw_dump_phy_cap_by_hal(sel, adapter);
  12028. #endif
  12029. }
  12030. inline s16 translate_dbm_to_percentage(s16 signal)
  12031. {
  12032. if ((signal <= -100) || (signal >= 20))
  12033. return 0;
  12034. else if (signal >= 0)
  12035. return 100;
  12036. else
  12037. return 100 + signal;
  12038. }
  12039. #ifdef CONFIG_SWTIMER_BASED_TXBCN
  12040. #ifdef CONFIG_BCN_RECOVERY
  12041. #define REG_CPU_MGQ_INFO 0x041C
  12042. #define BIT_BCN_POLL BIT(28)
  12043. u8 rtw_ap_bcn_recovery(_adapter *padapter)
  12044. {
  12045. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
  12046. if (hal_data->issue_bcn_fail >= 2) {
  12047. RTW_ERR("%s ISSUE BCN Fail\n", __func__);
  12048. rtw_write8(padapter, REG_CPU_MGQ_INFO + 3, 0x10);
  12049. hal_data->issue_bcn_fail = 0;
  12050. }
  12051. return _SUCCESS;
  12052. }
  12053. #endif /*CONFIG_BCN_RECOVERY*/
  12054. #ifdef CONFIG_BCN_XMIT_PROTECT
  12055. u8 rtw_ap_bcn_queue_empty_check(_adapter *padapter, u32 txbcn_timer_ms)
  12056. {
  12057. u32 start_time = rtw_get_current_time();
  12058. u8 bcn_queue_empty = _FALSE;
  12059. do {
  12060. if (rtw_read16(padapter, REG_TXPKT_EMPTY) & BIT(11)) {
  12061. bcn_queue_empty = _TRUE;
  12062. break;
  12063. }
  12064. } while (rtw_get_passing_time_ms(start_time) <= (txbcn_timer_ms + 10));
  12065. if (bcn_queue_empty == _FALSE)
  12066. RTW_ERR("%s BCN queue not empty\n", __func__);
  12067. return bcn_queue_empty;
  12068. }
  12069. #endif /*CONFIG_BCN_XMIT_PROTECT*/
  12070. #endif /*CONFIG_SWTIMER_BASED_TXBCN*/
  12071. static void _rf_type_to_ant_path(enum rf_type rf, enum bb_path *tx,
  12072. enum bb_path *rx)
  12073. {
  12074. if (tx) {
  12075. switch (rf) {
  12076. case RF_1T1R:
  12077. case RF_1T2R:
  12078. *tx = BB_PATH_A;
  12079. break;
  12080. case RF_2T2R:
  12081. case RF_2T3R:
  12082. case RF_2T4R:
  12083. *tx = BB_PATH_AB;
  12084. break;
  12085. case RF_3T3R:
  12086. case RF_3T4R:
  12087. *tx = BB_PATH_ABC;
  12088. break;
  12089. case RF_4T4R:
  12090. default:
  12091. *tx = BB_PATH_ABCD;
  12092. break;
  12093. }
  12094. }
  12095. if (rx) {
  12096. switch (rf) {
  12097. case RF_1T1R:
  12098. *rx = BB_PATH_A;
  12099. break;
  12100. case RF_1T2R:
  12101. case RF_2T2R:
  12102. *rx = BB_PATH_AB;
  12103. break;
  12104. case RF_2T3R:
  12105. case RF_3T3R:
  12106. *rx = BB_PATH_ABC;
  12107. break;
  12108. case RF_2T4R:
  12109. case RF_3T4R:
  12110. case RF_4T4R:
  12111. default:
  12112. *rx = BB_PATH_ABCD;
  12113. break;
  12114. }
  12115. }
  12116. }
  12117. /**
  12118. * rtw_hal_get_rf_path() - Get RF path related information
  12119. * @d: struct dvobj_priv*
  12120. * @type: RF type, nTnR
  12121. * @tx: Tx path
  12122. * @rx: Rx path
  12123. *
  12124. * Get RF type, TX path and RX path information.
  12125. */
  12126. void rtw_hal_get_rf_path(struct dvobj_priv *d, enum rf_type *type,
  12127. enum bb_path *tx, enum bb_path *rx)
  12128. {
  12129. struct _ADAPTER *a;
  12130. u8 val8 = RF_1T1R;
  12131. enum rf_type rf;
  12132. a = dvobj_get_primary_adapter(d);
  12133. rtw_hal_get_hwreg(a, HW_VAR_RF_TYPE, &val8);
  12134. rf = (enum rf_type)val8;
  12135. if (type)
  12136. *type = rf;
  12137. if (tx || rx)
  12138. _rf_type_to_ant_path(rf, tx, rx);
  12139. }
  12140. #ifdef RTW_CHANNEL_SWITCH_OFFLOAD
  12141. void rtw_hal_switch_chnl_and_set_bw_offload(_adapter *adapter, u8 central_ch, u8 pri_ch_idx, u8 bw)
  12142. {
  12143. u8 h2c[H2C_SINGLE_CHANNELSWITCH_V2_LEN] = {0};
  12144. PHAL_DATA_TYPE hal;
  12145. struct submit_ctx *chsw_sctx;
  12146. hal = GET_HAL_DATA(adapter);
  12147. chsw_sctx = &hal->chsw_sctx;
  12148. SET_H2CCMD_SINGLE_CH_SWITCH_V2_CENTRAL_CH_NUM(h2c, central_ch);
  12149. SET_H2CCMD_SINGLE_CH_SWITCH_V2_PRIMARY_CH_IDX(h2c, pri_ch_idx);
  12150. SET_H2CCMD_SINGLE_CH_SWITCH_V2_BW(h2c, bw);
  12151. rtw_sctx_init(chsw_sctx, 10);
  12152. rtw_hal_fill_h2c_cmd(adapter, H2C_SINGLE_CHANNELSWITCH_V2, H2C_SINGLE_CHANNELSWITCH_V2_LEN, h2c);
  12153. rtw_sctx_wait(chsw_sctx, __func__);
  12154. }
  12155. #endif /* RTW_CHANNEL_SWITCH_OFFLOAD */