coex.c 244 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466
  1. // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
  2. /* Copyright(c) 2019-2020 Realtek Corporation
  3. */
  4. #include "coex.h"
  5. #include "debug.h"
  6. #include "fw.h"
  7. #include "mac.h"
  8. #include "ps.h"
  9. #include "reg.h"
  10. #define RTW89_COEX_VERSION 0x07000113
  11. #define FCXDEF_STEP 50 /* MUST <= FCXMAX_STEP and match with wl fw*/
  12. enum btc_fbtc_tdma_template {
  13. CXTD_OFF = 0x0,
  14. CXTD_OFF_B2,
  15. CXTD_OFF_EXT,
  16. CXTD_FIX,
  17. CXTD_PFIX,
  18. CXTD_AUTO,
  19. CXTD_PAUTO,
  20. CXTD_AUTO2,
  21. CXTD_PAUTO2,
  22. CXTD_MAX,
  23. };
  24. enum btc_fbtc_tdma_type {
  25. CXTDMA_OFF = 0x0,
  26. CXTDMA_FIX = 0x1,
  27. CXTDMA_AUTO = 0x2,
  28. CXTDMA_AUTO2 = 0x3,
  29. CXTDMA_MAX
  30. };
  31. enum btc_fbtc_tdma_rx_flow_ctrl {
  32. CXFLC_OFF = 0x0,
  33. CXFLC_NULLP = 0x1,
  34. CXFLC_QOSNULL = 0x2,
  35. CXFLC_CTS = 0x3,
  36. CXFLC_MAX
  37. };
  38. enum btc_fbtc_tdma_wlan_tx_pause {
  39. CXTPS_OFF = 0x0, /* no wl tx pause*/
  40. CXTPS_ON = 0x1,
  41. CXTPS_MAX
  42. };
  43. enum btc_mlme_state {
  44. MLME_NO_LINK,
  45. MLME_LINKING,
  46. MLME_LINKED,
  47. };
  48. #define FCXONESLOT_VER 1
  49. struct btc_fbtc_1slot {
  50. u8 fver;
  51. u8 sid; /* slot id */
  52. struct rtw89_btc_fbtc_slot slot;
  53. } __packed;
  54. static const struct rtw89_btc_fbtc_tdma t_def[] = {
  55. [CXTD_OFF] = { CXTDMA_OFF, CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0},
  56. [CXTD_OFF_B2] = { CXTDMA_OFF, CXFLC_OFF, CXTPS_OFF, 0, 0, 1, 0, 0},
  57. [CXTD_OFF_EXT] = { CXTDMA_OFF, CXFLC_OFF, CXTPS_OFF, 0, 0, 2, 0, 0},
  58. [CXTD_FIX] = { CXTDMA_FIX, CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0},
  59. [CXTD_PFIX] = { CXTDMA_FIX, CXFLC_NULLP, CXTPS_ON, 0, 5, 0, 0, 0},
  60. [CXTD_AUTO] = { CXTDMA_AUTO, CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0},
  61. [CXTD_PAUTO] = { CXTDMA_AUTO, CXFLC_NULLP, CXTPS_ON, 0, 5, 0, 0, 0},
  62. [CXTD_AUTO2] = {CXTDMA_AUTO2, CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0},
  63. [CXTD_PAUTO2] = {CXTDMA_AUTO2, CXFLC_NULLP, CXTPS_ON, 0, 5, 0, 0, 0}
  64. };
  65. #define __DEF_FBTC_SLOT(__dur, __cxtbl, __cxtype) \
  66. { .dur = cpu_to_le16(__dur), .cxtbl = cpu_to_le32(__cxtbl), \
  67. .cxtype = cpu_to_le16(__cxtype),}
  68. static const struct rtw89_btc_fbtc_slot s_def[] = {
  69. [CXST_OFF] = __DEF_FBTC_SLOT(100, 0x55555555, SLOT_MIX),
  70. [CXST_B2W] = __DEF_FBTC_SLOT(5, 0xea5a5a5a, SLOT_ISO),
  71. [CXST_W1] = __DEF_FBTC_SLOT(70, 0xea5a5a5a, SLOT_ISO),
  72. [CXST_W2] = __DEF_FBTC_SLOT(15, 0xea5a5a5a, SLOT_ISO),
  73. [CXST_W2B] = __DEF_FBTC_SLOT(15, 0xea5a5a5a, SLOT_ISO),
  74. [CXST_B1] = __DEF_FBTC_SLOT(250, 0xe5555555, SLOT_MIX),
  75. [CXST_B2] = __DEF_FBTC_SLOT(7, 0xea5a5a5a, SLOT_MIX),
  76. [CXST_B3] = __DEF_FBTC_SLOT(5, 0xe5555555, SLOT_MIX),
  77. [CXST_B4] = __DEF_FBTC_SLOT(50, 0xe5555555, SLOT_MIX),
  78. [CXST_LK] = __DEF_FBTC_SLOT(20, 0xea5a5a5a, SLOT_ISO),
  79. [CXST_BLK] = __DEF_FBTC_SLOT(500, 0x55555555, SLOT_MIX),
  80. [CXST_E2G] = __DEF_FBTC_SLOT(0, 0xea5a5a5a, SLOT_MIX),
  81. [CXST_E5G] = __DEF_FBTC_SLOT(0, 0xffffffff, SLOT_ISO),
  82. [CXST_EBT] = __DEF_FBTC_SLOT(0, 0xe5555555, SLOT_MIX),
  83. [CXST_ENULL] = __DEF_FBTC_SLOT(0, 0xaaaaaaaa, SLOT_ISO),
  84. [CXST_WLK] = __DEF_FBTC_SLOT(250, 0xea5a5a5a, SLOT_MIX),
  85. [CXST_W1FDD] = __DEF_FBTC_SLOT(50, 0xffffffff, SLOT_ISO),
  86. [CXST_B1FDD] = __DEF_FBTC_SLOT(50, 0xffffdfff, SLOT_ISO),
  87. };
  88. static const u32 cxtbl[] = {
  89. 0xffffffff, /* 0 */
  90. 0xaaaaaaaa, /* 1 */
  91. 0xe5555555, /* 2 */
  92. 0xee555555, /* 3 */
  93. 0xd5555555, /* 4 */
  94. 0x5a5a5a5a, /* 5 */
  95. 0xfa5a5a5a, /* 6 */
  96. 0xda5a5a5a, /* 7 */
  97. 0xea5a5a5a, /* 8 */
  98. 0x6a5a5aaa, /* 9 */
  99. 0x6a5a6a5a, /* 10 */
  100. 0x6a5a6aaa, /* 11 */
  101. 0x6afa5afa, /* 12 */
  102. 0xaaaa5aaa, /* 13 */
  103. 0xaaffffaa, /* 14 */
  104. 0xaa5555aa, /* 15 */
  105. 0xfafafafa, /* 16 */
  106. 0xffffddff, /* 17 */
  107. 0xdaffdaff, /* 18 */
  108. 0xfafadafa, /* 19 */
  109. 0xea6a6a6a, /* 20 */
  110. 0xea55556a, /* 21 */
  111. 0xaafafafa, /* 22 */
  112. 0xfafaaafa, /* 23 */
  113. 0xfafffaff /* 24 */
  114. };
  115. static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
  116. /* firmware version must be in decreasing order for each chip */
  117. {RTL8851B, RTW89_FW_VER_CODE(0, 29, 29, 0),
  118. .fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5,
  119. .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 2, .fcxgpiodbg = 1,
  120. .fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1,
  121. .fwlrole = 1, .frptmap = 3, .fcxctrl = 1,
  122. .info_buf = 1800, .max_role_num = 6,
  123. },
  124. {RTL8852C, RTW89_FW_VER_CODE(0, 27, 57, 0),
  125. .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
  126. .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
  127. .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1,
  128. .fwlrole = 1, .frptmap = 3, .fcxctrl = 1,
  129. .info_buf = 1280, .max_role_num = 5,
  130. },
  131. {RTL8852C, RTW89_FW_VER_CODE(0, 27, 42, 0),
  132. .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
  133. .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
  134. .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1,
  135. .fwlrole = 1, .frptmap = 2, .fcxctrl = 1,
  136. .info_buf = 1280, .max_role_num = 5,
  137. },
  138. {RTL8852C, RTW89_FW_VER_CODE(0, 27, 0, 0),
  139. .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
  140. .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
  141. .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1,
  142. .fwlrole = 1, .frptmap = 2, .fcxctrl = 1,
  143. .info_buf = 1280, .max_role_num = 5,
  144. },
  145. {RTL8852B, RTW89_FW_VER_CODE(0, 29, 29, 0),
  146. .fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5,
  147. .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 2, .fcxgpiodbg = 1,
  148. .fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1,
  149. .fwlrole = 1, .frptmap = 3, .fcxctrl = 1,
  150. .info_buf = 1800, .max_role_num = 6,
  151. },
  152. {RTL8852B, RTW89_FW_VER_CODE(0, 29, 14, 0),
  153. .fcxbtcrpt = 5, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 4,
  154. .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
  155. .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1,
  156. .fwlrole = 1, .frptmap = 3, .fcxctrl = 1,
  157. .info_buf = 1800, .max_role_num = 6,
  158. },
  159. {RTL8852B, RTW89_FW_VER_CODE(0, 27, 0, 0),
  160. .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
  161. .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
  162. .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1,
  163. .fwlrole = 1, .frptmap = 1, .fcxctrl = 1,
  164. .info_buf = 1280, .max_role_num = 5,
  165. },
  166. {RTL8852A, RTW89_FW_VER_CODE(0, 13, 37, 0),
  167. .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
  168. .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
  169. .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1,
  170. .fwlrole = 1, .frptmap = 3, .fcxctrl = 1,
  171. .info_buf = 1280, .max_role_num = 5,
  172. },
  173. {RTL8852A, RTW89_FW_VER_CODE(0, 13, 0, 0),
  174. .fcxbtcrpt = 1, .fcxtdma = 1, .fcxslots = 1, .fcxcysta = 2,
  175. .fcxstep = 2, .fcxnullsta = 1, .fcxmreg = 1, .fcxgpiodbg = 1,
  176. .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1,
  177. .fwlrole = 0, .frptmap = 0, .fcxctrl = 0,
  178. .info_buf = 1024, .max_role_num = 5,
  179. },
  180. /* keep it to be the last as default entry */
  181. {0, RTW89_FW_VER_CODE(0, 0, 0, 0),
  182. .fcxbtcrpt = 1, .fcxtdma = 1, .fcxslots = 1, .fcxcysta = 2,
  183. .fcxstep = 2, .fcxnullsta = 1, .fcxmreg = 1, .fcxgpiodbg = 1,
  184. .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1,
  185. .fwlrole = 0, .frptmap = 0, .fcxctrl = 0,
  186. .info_buf = 1024, .max_role_num = 5,
  187. },
  188. };
  189. #define RTW89_DEFAULT_BTC_VER_IDX (ARRAY_SIZE(rtw89_btc_ver_defs) - 1)
  190. struct rtw89_btc_btf_tlv {
  191. u8 type;
  192. u8 len;
  193. u8 val[];
  194. } __packed;
  195. enum btc_btf_set_report_en {
  196. RPT_EN_TDMA,
  197. RPT_EN_CYCLE,
  198. RPT_EN_MREG,
  199. RPT_EN_BT_VER_INFO,
  200. RPT_EN_BT_SCAN_INFO,
  201. RPT_EN_BT_DEVICE_INFO,
  202. RPT_EN_BT_AFH_MAP,
  203. RPT_EN_BT_AFH_MAP_LE,
  204. RPT_EN_FW_STEP_INFO,
  205. RPT_EN_TEST,
  206. RPT_EN_WL_ALL,
  207. RPT_EN_BT_ALL,
  208. RPT_EN_ALL,
  209. RPT_EN_MONITER,
  210. };
  211. #define BTF_SET_REPORT_VER 1
  212. struct rtw89_btc_btf_set_report {
  213. u8 fver;
  214. __le32 enable;
  215. __le32 para;
  216. } __packed;
  217. #define BTF_SET_SLOT_TABLE_VER 1
  218. struct rtw89_btc_btf_set_slot_table {
  219. u8 fver;
  220. u8 tbl_num;
  221. u8 buf[];
  222. } __packed;
  223. struct rtw89_btc_btf_set_mon_reg {
  224. u8 fver;
  225. u8 reg_num;
  226. u8 buf[];
  227. } __packed;
  228. enum btc_btf_set_cx_policy {
  229. CXPOLICY_TDMA = 0x0,
  230. CXPOLICY_SLOT = 0x1,
  231. CXPOLICY_TYPE = 0x2,
  232. CXPOLICY_MAX,
  233. };
  234. enum btc_b2w_scoreboard {
  235. BTC_BSCB_ACT = BIT(0),
  236. BTC_BSCB_ON = BIT(1),
  237. BTC_BSCB_WHQL = BIT(2),
  238. BTC_BSCB_BT_S1 = BIT(3),
  239. BTC_BSCB_A2DP_ACT = BIT(4),
  240. BTC_BSCB_RFK_RUN = BIT(5),
  241. BTC_BSCB_RFK_REQ = BIT(6),
  242. BTC_BSCB_LPS = BIT(7),
  243. BTC_BSCB_WLRFK = BIT(11),
  244. BTC_BSCB_BT_HILNA = BIT(13),
  245. BTC_BSCB_BT_CONNECT = BIT(16),
  246. BTC_BSCB_PATCH_CODE = BIT(30),
  247. BTC_BSCB_ALL = GENMASK(30, 0),
  248. };
  249. enum btc_phymap {
  250. BTC_PHY_0 = BIT(0),
  251. BTC_PHY_1 = BIT(1),
  252. BTC_PHY_ALL = BIT(0) | BIT(1),
  253. };
  254. enum btc_cx_state_map {
  255. BTC_WIDLE = 0,
  256. BTC_WBUSY_BNOSCAN,
  257. BTC_WBUSY_BSCAN,
  258. BTC_WSCAN_BNOSCAN,
  259. BTC_WSCAN_BSCAN,
  260. BTC_WLINKING
  261. };
  262. enum btc_ant_phase {
  263. BTC_ANT_WPOWERON = 0,
  264. BTC_ANT_WINIT,
  265. BTC_ANT_WONLY,
  266. BTC_ANT_WOFF,
  267. BTC_ANT_W2G,
  268. BTC_ANT_W5G,
  269. BTC_ANT_W25G,
  270. BTC_ANT_FREERUN,
  271. BTC_ANT_WRFK,
  272. BTC_ANT_BRFK,
  273. BTC_ANT_MAX
  274. };
  275. enum btc_plt {
  276. BTC_PLT_NONE = 0,
  277. BTC_PLT_LTE_RX = BIT(0),
  278. BTC_PLT_GNT_BT_TX = BIT(1),
  279. BTC_PLT_GNT_BT_RX = BIT(2),
  280. BTC_PLT_GNT_WL = BIT(3),
  281. BTC_PLT_BT = BIT(1) | BIT(2),
  282. BTC_PLT_ALL = 0xf
  283. };
  284. enum btc_cx_poicy_main_type {
  285. BTC_CXP_OFF = 0,
  286. BTC_CXP_OFFB,
  287. BTC_CXP_OFFE,
  288. BTC_CXP_FIX,
  289. BTC_CXP_PFIX,
  290. BTC_CXP_AUTO,
  291. BTC_CXP_PAUTO,
  292. BTC_CXP_AUTO2,
  293. BTC_CXP_PAUTO2,
  294. BTC_CXP_MANUAL,
  295. BTC_CXP_USERDEF0,
  296. BTC_CXP_MAIN_MAX
  297. };
  298. enum btc_cx_poicy_type {
  299. /* TDMA off + pri: BT > WL */
  300. BTC_CXP_OFF_BT = (BTC_CXP_OFF << 8) | 0,
  301. /* TDMA off + pri: WL > BT */
  302. BTC_CXP_OFF_WL = (BTC_CXP_OFF << 8) | 1,
  303. /* TDMA off + pri: BT = WL */
  304. BTC_CXP_OFF_EQ0 = (BTC_CXP_OFF << 8) | 2,
  305. /* TDMA off + pri: BT = WL > BT_Lo */
  306. BTC_CXP_OFF_EQ1 = (BTC_CXP_OFF << 8) | 3,
  307. /* TDMA off + pri: WL = BT, BT_Rx > WL_Lo_Tx */
  308. BTC_CXP_OFF_EQ2 = (BTC_CXP_OFF << 8) | 4,
  309. /* TDMA off + pri: WL_Rx = BT, BT_HI > WL_Tx > BT_Lo */
  310. BTC_CXP_OFF_EQ3 = (BTC_CXP_OFF << 8) | 5,
  311. /* TDMA off + pri: BT_Hi > WL > BT_Lo */
  312. BTC_CXP_OFF_BWB0 = (BTC_CXP_OFF << 8) | 6,
  313. /* TDMA off + pri: WL_Hi-Tx > BT_Hi_Rx, BT_Hi > WL > BT_Lo */
  314. BTC_CXP_OFF_BWB1 = (BTC_CXP_OFF << 8) | 7,
  315. /* TDMA off + pri: WL_Hi-Tx > BT, BT_Hi > other-WL > BT_Lo */
  316. BTC_CXP_OFF_BWB2 = (BTC_CXP_OFF << 8) | 8,
  317. /* TDMA off + pri: WL_Hi-Tx = BT */
  318. BTC_CXP_OFF_BWB3 = (BTC_CXP_OFF << 8) | 9,
  319. /* TDMA off+Bcn-Protect + pri: WL_Hi-Tx > BT_Hi_Rx, BT_Hi > WL > BT_Lo*/
  320. BTC_CXP_OFFB_BWB0 = (BTC_CXP_OFFB << 8) | 0,
  321. /* TDMA off + Ext-Ctrl + pri: default */
  322. BTC_CXP_OFFE_DEF = (BTC_CXP_OFFE << 8) | 0,
  323. /* TDMA off + Ext-Ctrl + pri: E2G-slot block all BT */
  324. BTC_CXP_OFFE_DEF2 = (BTC_CXP_OFFE << 8) | 1,
  325. /* TDMA off + Ext-Ctrl + pri: default */
  326. BTC_CXP_OFFE_2GBWISOB = (BTC_CXP_OFFE << 8) | 2,
  327. /* TDMA off + Ext-Ctrl + pri: E2G-slot block all BT */
  328. BTC_CXP_OFFE_2GISOB = (BTC_CXP_OFFE << 8) | 3,
  329. /* TDMA off + Ext-Ctrl + pri: E2G-slot WL > BT */
  330. BTC_CXP_OFFE_2GBWMIXB = (BTC_CXP_OFFE << 8) | 4,
  331. /* TDMA off + Ext-Ctrl + pri: E2G/EBT-slot WL > BT */
  332. BTC_CXP_OFFE_WL = (BTC_CXP_OFFE << 8) | 5,
  333. /* TDMA off + Ext-Ctrl + pri: default */
  334. BTC_CXP_OFFE_2GBWMIXB2 = (BTC_CXP_OFFE << 8) | 6,
  335. /* TDMA Fix slot-0: W1:B1 = 30:30 */
  336. BTC_CXP_FIX_TD3030 = (BTC_CXP_FIX << 8) | 0,
  337. /* TDMA Fix slot-1: W1:B1 = 50:50 */
  338. BTC_CXP_FIX_TD5050 = (BTC_CXP_FIX << 8) | 1,
  339. /* TDMA Fix slot-2: W1:B1 = 20:30 */
  340. BTC_CXP_FIX_TD2030 = (BTC_CXP_FIX << 8) | 2,
  341. /* TDMA Fix slot-3: W1:B1 = 40:10 */
  342. BTC_CXP_FIX_TD4010 = (BTC_CXP_FIX << 8) | 3,
  343. /* TDMA Fix slot-4: W1:B1 = 70:10 */
  344. BTC_CXP_FIX_TD7010 = (BTC_CXP_FIX << 8) | 4,
  345. /* TDMA Fix slot-5: W1:B1 = 20:60 */
  346. BTC_CXP_FIX_TD2060 = (BTC_CXP_FIX << 8) | 5,
  347. /* TDMA Fix slot-6: W1:B1 = 30:60 */
  348. BTC_CXP_FIX_TD3060 = (BTC_CXP_FIX << 8) | 6,
  349. /* TDMA Fix slot-7: W1:B1 = 20:80 */
  350. BTC_CXP_FIX_TD2080 = (BTC_CXP_FIX << 8) | 7,
  351. /* TDMA Fix slot-8: W1:B1 = user-define */
  352. BTC_CXP_FIX_TDW1B1 = (BTC_CXP_FIX << 8) | 8,
  353. /* TDMA Fix slot-9: W1:B1 = 40:20 */
  354. BTC_CXP_FIX_TD4020 = (BTC_CXP_FIX << 8) | 9,
  355. /* TDMA Fix slot-9: W1:B1 = 40:10 */
  356. BTC_CXP_FIX_TD4010ISO = (BTC_CXP_FIX << 8) | 10,
  357. /* PS-TDMA Fix slot-0: W1:B1 = 30:30 */
  358. BTC_CXP_PFIX_TD3030 = (BTC_CXP_PFIX << 8) | 0,
  359. /* PS-TDMA Fix slot-1: W1:B1 = 50:50 */
  360. BTC_CXP_PFIX_TD5050 = (BTC_CXP_PFIX << 8) | 1,
  361. /* PS-TDMA Fix slot-2: W1:B1 = 20:30 */
  362. BTC_CXP_PFIX_TD2030 = (BTC_CXP_PFIX << 8) | 2,
  363. /* PS-TDMA Fix slot-3: W1:B1 = 20:60 */
  364. BTC_CXP_PFIX_TD2060 = (BTC_CXP_PFIX << 8) | 3,
  365. /* PS-TDMA Fix slot-4: W1:B1 = 30:70 */
  366. BTC_CXP_PFIX_TD3070 = (BTC_CXP_PFIX << 8) | 4,
  367. /* PS-TDMA Fix slot-5: W1:B1 = 20:80 */
  368. BTC_CXP_PFIX_TD2080 = (BTC_CXP_PFIX << 8) | 5,
  369. /* PS-TDMA Fix slot-6: W1:B1 = user-define */
  370. BTC_CXP_PFIX_TDW1B1 = (BTC_CXP_PFIX << 8) | 6,
  371. /* TDMA Auto slot-0: W1:B1 = 50:200 */
  372. BTC_CXP_AUTO_TD50B1 = (BTC_CXP_AUTO << 8) | 0,
  373. /* TDMA Auto slot-1: W1:B1 = 60:200 */
  374. BTC_CXP_AUTO_TD60B1 = (BTC_CXP_AUTO << 8) | 1,
  375. /* TDMA Auto slot-2: W1:B1 = 20:200 */
  376. BTC_CXP_AUTO_TD20B1 = (BTC_CXP_AUTO << 8) | 2,
  377. /* TDMA Auto slot-3: W1:B1 = user-define */
  378. BTC_CXP_AUTO_TDW1B1 = (BTC_CXP_AUTO << 8) | 3,
  379. /* PS-TDMA Auto slot-0: W1:B1 = 50:200 */
  380. BTC_CXP_PAUTO_TD50B1 = (BTC_CXP_PAUTO << 8) | 0,
  381. /* PS-TDMA Auto slot-1: W1:B1 = 60:200 */
  382. BTC_CXP_PAUTO_TD60B1 = (BTC_CXP_PAUTO << 8) | 1,
  383. /* PS-TDMA Auto slot-2: W1:B1 = 20:200 */
  384. BTC_CXP_PAUTO_TD20B1 = (BTC_CXP_PAUTO << 8) | 2,
  385. /* PS-TDMA Auto slot-3: W1:B1 = user-define */
  386. BTC_CXP_PAUTO_TDW1B1 = (BTC_CXP_PAUTO << 8) | 3,
  387. /* TDMA Auto slot2-0: W1:B4 = 30:50 */
  388. BTC_CXP_AUTO2_TD3050 = (BTC_CXP_AUTO2 << 8) | 0,
  389. /* TDMA Auto slot2-1: W1:B4 = 30:70 */
  390. BTC_CXP_AUTO2_TD3070 = (BTC_CXP_AUTO2 << 8) | 1,
  391. /* TDMA Auto slot2-2: W1:B4 = 50:50 */
  392. BTC_CXP_AUTO2_TD5050 = (BTC_CXP_AUTO2 << 8) | 2,
  393. /* TDMA Auto slot2-3: W1:B4 = 60:60 */
  394. BTC_CXP_AUTO2_TD6060 = (BTC_CXP_AUTO2 << 8) | 3,
  395. /* TDMA Auto slot2-4: W1:B4 = 20:80 */
  396. BTC_CXP_AUTO2_TD2080 = (BTC_CXP_AUTO2 << 8) | 4,
  397. /* TDMA Auto slot2-5: W1:B4 = user-define */
  398. BTC_CXP_AUTO2_TDW1B4 = (BTC_CXP_AUTO2 << 8) | 5,
  399. /* PS-TDMA Auto slot2-0: W1:B4 = 30:50 */
  400. BTC_CXP_PAUTO2_TD3050 = (BTC_CXP_PAUTO2 << 8) | 0,
  401. /* PS-TDMA Auto slot2-1: W1:B4 = 30:70 */
  402. BTC_CXP_PAUTO2_TD3070 = (BTC_CXP_PAUTO2 << 8) | 1,
  403. /* PS-TDMA Auto slot2-2: W1:B4 = 50:50 */
  404. BTC_CXP_PAUTO2_TD5050 = (BTC_CXP_PAUTO2 << 8) | 2,
  405. /* PS-TDMA Auto slot2-3: W1:B4 = 60:60 */
  406. BTC_CXP_PAUTO2_TD6060 = (BTC_CXP_PAUTO2 << 8) | 3,
  407. /* PS-TDMA Auto slot2-4: W1:B4 = 20:80 */
  408. BTC_CXP_PAUTO2_TD2080 = (BTC_CXP_PAUTO2 << 8) | 4,
  409. /* PS-TDMA Auto slot2-5: W1:B4 = user-define */
  410. BTC_CXP_PAUTO2_TDW1B4 = (BTC_CXP_PAUTO2 << 8) | 5,
  411. BTC_CXP_MAX = 0xffff
  412. };
  413. enum btc_wl_rfk_result {
  414. BTC_WRFK_REJECT = 0,
  415. BTC_WRFK_ALLOW = 1,
  416. };
  417. enum btc_coex_info_map_en {
  418. BTC_COEX_INFO_CX = BIT(0),
  419. BTC_COEX_INFO_WL = BIT(1),
  420. BTC_COEX_INFO_BT = BIT(2),
  421. BTC_COEX_INFO_DM = BIT(3),
  422. BTC_COEX_INFO_MREG = BIT(4),
  423. BTC_COEX_INFO_SUMMARY = BIT(5),
  424. BTC_COEX_INFO_ALL = GENMASK(7, 0),
  425. };
  426. #define BTC_CXP_MASK GENMASK(15, 8)
  427. enum btc_w2b_scoreboard {
  428. BTC_WSCB_ACTIVE = BIT(0),
  429. BTC_WSCB_ON = BIT(1),
  430. BTC_WSCB_SCAN = BIT(2),
  431. BTC_WSCB_UNDERTEST = BIT(3),
  432. BTC_WSCB_RXGAIN = BIT(4),
  433. BTC_WSCB_WLBUSY = BIT(7),
  434. BTC_WSCB_EXTFEM = BIT(8),
  435. BTC_WSCB_TDMA = BIT(9),
  436. BTC_WSCB_FIX2M = BIT(10),
  437. BTC_WSCB_WLRFK = BIT(11),
  438. BTC_WSCB_RXSCAN_PRI = BIT(12),
  439. BTC_WSCB_BT_HILNA = BIT(13),
  440. BTC_WSCB_BTLOG = BIT(14),
  441. BTC_WSCB_ALL = GENMASK(23, 0),
  442. };
  443. enum btc_wl_link_mode {
  444. BTC_WLINK_NOLINK = 0x0,
  445. BTC_WLINK_2G_STA,
  446. BTC_WLINK_2G_AP,
  447. BTC_WLINK_2G_GO,
  448. BTC_WLINK_2G_GC,
  449. BTC_WLINK_2G_SCC,
  450. BTC_WLINK_2G_MCC,
  451. BTC_WLINK_25G_MCC,
  452. BTC_WLINK_25G_DBCC,
  453. BTC_WLINK_5G,
  454. BTC_WLINK_2G_NAN,
  455. BTC_WLINK_OTHER,
  456. BTC_WLINK_MAX
  457. };
  458. enum btc_wl_mrole_type {
  459. BTC_WLMROLE_NONE = 0x0,
  460. BTC_WLMROLE_STA_GC,
  461. BTC_WLMROLE_STA_GC_NOA,
  462. BTC_WLMROLE_STA_GO,
  463. BTC_WLMROLE_STA_GO_NOA,
  464. BTC_WLMROLE_STA_STA,
  465. BTC_WLMROLE_MAX
  466. };
  467. enum btc_bt_hid_type {
  468. BTC_HID_218 = BIT(0),
  469. BTC_HID_418 = BIT(1),
  470. BTC_HID_BLE = BIT(2),
  471. BTC_HID_RCU = BIT(3),
  472. BTC_HID_RCU_VOICE = BIT(4),
  473. BTC_HID_OTHER_LEGACY = BIT(5)
  474. };
  475. enum btc_reset_module {
  476. BTC_RESET_CX = BIT(0),
  477. BTC_RESET_DM = BIT(1),
  478. BTC_RESET_CTRL = BIT(2),
  479. BTC_RESET_CXDM = BIT(0) | BIT(1),
  480. BTC_RESET_BTINFO = BIT(3),
  481. BTC_RESET_MDINFO = BIT(4),
  482. BTC_RESET_ALL = GENMASK(7, 0),
  483. };
  484. enum btc_gnt_state {
  485. BTC_GNT_HW = 0,
  486. BTC_GNT_SW_LO,
  487. BTC_GNT_SW_HI,
  488. BTC_GNT_MAX
  489. };
  490. enum btc_ctr_path {
  491. BTC_CTRL_BY_BT = 0,
  492. BTC_CTRL_BY_WL
  493. };
  494. enum btc_wl_max_tx_time {
  495. BTC_MAX_TX_TIME_L1 = 500,
  496. BTC_MAX_TX_TIME_L2 = 1000,
  497. BTC_MAX_TX_TIME_L3 = 2000,
  498. BTC_MAX_TX_TIME_DEF = 5280
  499. };
  500. enum btc_wl_max_tx_retry {
  501. BTC_MAX_TX_RETRY_L1 = 7,
  502. BTC_MAX_TX_RETRY_L2 = 15,
  503. BTC_MAX_TX_RETRY_DEF = 31,
  504. };
  505. enum btc_reason_and_action {
  506. BTC_RSN_NONE,
  507. BTC_RSN_NTFY_INIT,
  508. BTC_RSN_NTFY_SWBAND,
  509. BTC_RSN_NTFY_WL_STA,
  510. BTC_RSN_NTFY_RADIO_STATE,
  511. BTC_RSN_UPDATE_BT_SCBD,
  512. BTC_RSN_NTFY_WL_RFK,
  513. BTC_RSN_UPDATE_BT_INFO,
  514. BTC_RSN_NTFY_SCAN_START,
  515. BTC_RSN_NTFY_SCAN_FINISH,
  516. BTC_RSN_NTFY_SPECIFIC_PACKET,
  517. BTC_RSN_NTFY_POWEROFF,
  518. BTC_RSN_NTFY_ROLE_INFO,
  519. BTC_RSN_CMD_SET_COEX,
  520. BTC_RSN_ACT1_WORK,
  521. BTC_RSN_BT_DEVINFO_WORK,
  522. BTC_RSN_RFK_CHK_WORK,
  523. BTC_RSN_NUM,
  524. BTC_ACT_NONE = 100,
  525. BTC_ACT_WL_ONLY,
  526. BTC_ACT_WL_5G,
  527. BTC_ACT_WL_OTHER,
  528. BTC_ACT_WL_IDLE,
  529. BTC_ACT_WL_NC,
  530. BTC_ACT_WL_RFK,
  531. BTC_ACT_WL_INIT,
  532. BTC_ACT_WL_OFF,
  533. BTC_ACT_FREERUN,
  534. BTC_ACT_BT_WHQL,
  535. BTC_ACT_BT_RFK,
  536. BTC_ACT_BT_OFF,
  537. BTC_ACT_BT_IDLE,
  538. BTC_ACT_BT_HFP,
  539. BTC_ACT_BT_HID,
  540. BTC_ACT_BT_A2DP,
  541. BTC_ACT_BT_A2DPSINK,
  542. BTC_ACT_BT_PAN,
  543. BTC_ACT_BT_A2DP_HID,
  544. BTC_ACT_BT_A2DP_PAN,
  545. BTC_ACT_BT_PAN_HID,
  546. BTC_ACT_BT_A2DP_PAN_HID,
  547. BTC_ACT_WL_25G_MCC,
  548. BTC_ACT_WL_2G_MCC,
  549. BTC_ACT_WL_2G_SCC,
  550. BTC_ACT_WL_2G_AP,
  551. BTC_ACT_WL_2G_GO,
  552. BTC_ACT_WL_2G_GC,
  553. BTC_ACT_WL_2G_NAN,
  554. BTC_ACT_LAST,
  555. BTC_ACT_NUM = BTC_ACT_LAST - BTC_ACT_NONE,
  556. BTC_ACT_EXT_BIT = BIT(14),
  557. BTC_POLICY_EXT_BIT = BIT(15),
  558. };
  559. #define BTC_FREERUN_ANTISO_MIN 30
  560. #define BTC_TDMA_BTHID_MAX 2
  561. #define BTC_BLINK_NOCONNECT 0
  562. #define BTC_B1_MAX 250 /* unit ms */
  563. static void _run_coex(struct rtw89_dev *rtwdev,
  564. enum btc_reason_and_action reason);
  565. static void _write_scbd(struct rtw89_dev *rtwdev, u32 val, bool state);
  566. static void _update_bt_scbd(struct rtw89_dev *rtwdev, bool only_update);
  567. static void _send_fw_cmd(struct rtw89_dev *rtwdev, u8 h2c_class, u8 h2c_func,
  568. void *param, u16 len)
  569. {
  570. struct rtw89_btc *btc = &rtwdev->btc;
  571. struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
  572. struct rtw89_btc_cx *cx = &btc->cx;
  573. struct rtw89_btc_wl_info *wl = &cx->wl;
  574. int ret;
  575. if (!wl->status.map.init_ok) {
  576. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  577. "[BTC], %s(): return by btc not init!!\n", __func__);
  578. pfwinfo->cnt_h2c_fail++;
  579. return;
  580. } else if ((wl->status.map.rf_off_pre == BTC_LPS_RF_OFF &&
  581. wl->status.map.rf_off == BTC_LPS_RF_OFF) ||
  582. (wl->status.map.lps_pre == BTC_LPS_RF_OFF &&
  583. wl->status.map.lps == BTC_LPS_RF_OFF)) {
  584. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  585. "[BTC], %s(): return by wl off!!\n", __func__);
  586. pfwinfo->cnt_h2c_fail++;
  587. return;
  588. }
  589. pfwinfo->cnt_h2c++;
  590. ret = rtw89_fw_h2c_raw_with_hdr(rtwdev, h2c_class, h2c_func, param, len,
  591. false, true);
  592. if (ret != 0)
  593. pfwinfo->cnt_h2c_fail++;
  594. }
  595. static void _reset_btc_var(struct rtw89_dev *rtwdev, u8 type)
  596. {
  597. struct rtw89_btc *btc = &rtwdev->btc;
  598. struct rtw89_btc_cx *cx = &btc->cx;
  599. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  600. struct rtw89_btc_bt_info *bt = &btc->cx.bt;
  601. struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info;
  602. struct rtw89_btc_wl_link_info *wl_linfo = wl->link_info;
  603. u8 i;
  604. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s\n", __func__);
  605. if (type & BTC_RESET_CX)
  606. memset(cx, 0, sizeof(*cx));
  607. else if (type & BTC_RESET_BTINFO) /* only for BT enable */
  608. memset(bt, 0, sizeof(*bt));
  609. if (type & BTC_RESET_CTRL) {
  610. memset(&btc->ctrl, 0, sizeof(btc->ctrl));
  611. btc->ctrl.trace_step = FCXDEF_STEP;
  612. }
  613. /* Init Coex variables that are not zero */
  614. if (type & BTC_RESET_DM) {
  615. memset(&btc->dm, 0, sizeof(btc->dm));
  616. memset(bt_linfo->rssi_state, 0, sizeof(bt_linfo->rssi_state));
  617. for (i = 0; i < RTW89_PORT_NUM; i++)
  618. memset(wl_linfo[i].rssi_state, 0,
  619. sizeof(wl_linfo[i].rssi_state));
  620. /* set the slot_now table to original */
  621. btc->dm.tdma_now = t_def[CXTD_OFF];
  622. btc->dm.tdma = t_def[CXTD_OFF];
  623. memcpy(&btc->dm.slot_now, s_def, sizeof(btc->dm.slot_now));
  624. memcpy(&btc->dm.slot, s_def, sizeof(btc->dm.slot));
  625. btc->policy_len = 0;
  626. btc->bt_req_len = 0;
  627. btc->dm.coex_info_map = BTC_COEX_INFO_ALL;
  628. btc->dm.wl_tx_limit.tx_time = BTC_MAX_TX_TIME_DEF;
  629. btc->dm.wl_tx_limit.tx_retry = BTC_MAX_TX_RETRY_DEF;
  630. }
  631. if (type & BTC_RESET_MDINFO)
  632. memset(&btc->mdinfo, 0, sizeof(btc->mdinfo));
  633. }
  634. #define BTC_RPT_HDR_SIZE 3
  635. #define BTC_CHK_WLSLOT_DRIFT_MAX 15
  636. #define BTC_CHK_BTSLOT_DRIFT_MAX 15
  637. #define BTC_CHK_HANG_MAX 3
  638. static void _chk_btc_err(struct rtw89_dev *rtwdev, u8 type, u32 cnt)
  639. {
  640. struct rtw89_btc *btc = &rtwdev->btc;
  641. struct rtw89_btc_cx *cx = &btc->cx;
  642. struct rtw89_btc_dm *dm = &btc->dm;
  643. struct rtw89_btc_bt_info *bt = &cx->bt;
  644. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  645. "[BTC], %s(): type:%d cnt:%d\n",
  646. __func__, type, cnt);
  647. switch (type) {
  648. case BTC_DCNT_RPT_HANG:
  649. if (dm->cnt_dm[BTC_DCNT_RPT] == cnt && btc->fwinfo.rpt_en_map)
  650. dm->cnt_dm[BTC_DCNT_RPT_HANG]++;
  651. else
  652. dm->cnt_dm[BTC_DCNT_RPT_HANG] = 0;
  653. if (dm->cnt_dm[BTC_DCNT_RPT_HANG] >= BTC_CHK_HANG_MAX)
  654. dm->error.map.wl_fw_hang = true;
  655. else
  656. dm->error.map.wl_fw_hang = false;
  657. dm->cnt_dm[BTC_DCNT_RPT] = cnt;
  658. break;
  659. case BTC_DCNT_CYCLE_HANG:
  660. if (dm->cnt_dm[BTC_DCNT_CYCLE] == cnt &&
  661. (dm->tdma_now.type != CXTDMA_OFF ||
  662. dm->tdma_now.ext_ctrl == CXECTL_EXT))
  663. dm->cnt_dm[BTC_DCNT_CYCLE_HANG]++;
  664. else
  665. dm->cnt_dm[BTC_DCNT_CYCLE_HANG] = 0;
  666. if (dm->cnt_dm[BTC_DCNT_CYCLE_HANG] >= BTC_CHK_HANG_MAX)
  667. dm->error.map.cycle_hang = true;
  668. else
  669. dm->error.map.cycle_hang = false;
  670. dm->cnt_dm[BTC_DCNT_CYCLE] = cnt;
  671. break;
  672. case BTC_DCNT_W1_HANG:
  673. if (dm->cnt_dm[BTC_DCNT_W1] == cnt &&
  674. dm->tdma_now.type != CXTDMA_OFF)
  675. dm->cnt_dm[BTC_DCNT_W1_HANG]++;
  676. else
  677. dm->cnt_dm[BTC_DCNT_W1_HANG] = 0;
  678. if (dm->cnt_dm[BTC_DCNT_W1_HANG] >= BTC_CHK_HANG_MAX)
  679. dm->error.map.w1_hang = true;
  680. else
  681. dm->error.map.w1_hang = false;
  682. dm->cnt_dm[BTC_DCNT_W1] = cnt;
  683. break;
  684. case BTC_DCNT_B1_HANG:
  685. if (dm->cnt_dm[BTC_DCNT_B1] == cnt &&
  686. dm->tdma_now.type != CXTDMA_OFF)
  687. dm->cnt_dm[BTC_DCNT_B1_HANG]++;
  688. else
  689. dm->cnt_dm[BTC_DCNT_B1_HANG] = 0;
  690. if (dm->cnt_dm[BTC_DCNT_B1_HANG] >= BTC_CHK_HANG_MAX)
  691. dm->error.map.b1_hang = true;
  692. else
  693. dm->error.map.b1_hang = false;
  694. dm->cnt_dm[BTC_DCNT_B1] = cnt;
  695. break;
  696. case BTC_DCNT_E2G_HANG:
  697. if (dm->cnt_dm[BTC_DCNT_E2G] == cnt &&
  698. dm->tdma_now.ext_ctrl == CXECTL_EXT)
  699. dm->cnt_dm[BTC_DCNT_E2G_HANG]++;
  700. else
  701. dm->cnt_dm[BTC_DCNT_E2G_HANG] = 0;
  702. if (dm->cnt_dm[BTC_DCNT_E2G_HANG] >= BTC_CHK_HANG_MAX)
  703. dm->error.map.wl_e2g_hang = true;
  704. else
  705. dm->error.map.wl_e2g_hang = false;
  706. dm->cnt_dm[BTC_DCNT_E2G] = cnt;
  707. break;
  708. case BTC_DCNT_TDMA_NONSYNC:
  709. if (cnt != 0) /* if tdma not sync between drv/fw */
  710. dm->cnt_dm[BTC_DCNT_TDMA_NONSYNC]++;
  711. else
  712. dm->cnt_dm[BTC_DCNT_TDMA_NONSYNC] = 0;
  713. if (dm->cnt_dm[BTC_DCNT_TDMA_NONSYNC] >= BTC_CHK_HANG_MAX)
  714. dm->error.map.tdma_no_sync = true;
  715. else
  716. dm->error.map.tdma_no_sync = false;
  717. break;
  718. case BTC_DCNT_SLOT_NONSYNC:
  719. if (cnt != 0) /* if slot not sync between drv/fw */
  720. dm->cnt_dm[BTC_DCNT_SLOT_NONSYNC]++;
  721. else
  722. dm->cnt_dm[BTC_DCNT_SLOT_NONSYNC] = 0;
  723. if (dm->cnt_dm[BTC_DCNT_SLOT_NONSYNC] >= BTC_CHK_HANG_MAX)
  724. dm->error.map.slot_no_sync = true;
  725. else
  726. dm->error.map.slot_no_sync = false;
  727. break;
  728. case BTC_DCNT_BTCNT_HANG:
  729. cnt = cx->cnt_bt[BTC_BCNT_HIPRI_RX] +
  730. cx->cnt_bt[BTC_BCNT_HIPRI_TX] +
  731. cx->cnt_bt[BTC_BCNT_LOPRI_RX] +
  732. cx->cnt_bt[BTC_BCNT_LOPRI_TX];
  733. if (cnt == 0)
  734. dm->cnt_dm[BTC_DCNT_BTCNT_HANG]++;
  735. else
  736. dm->cnt_dm[BTC_DCNT_BTCNT_HANG] = 0;
  737. if ((dm->cnt_dm[BTC_DCNT_BTCNT_HANG] >= BTC_CHK_HANG_MAX &&
  738. bt->enable.now) || (!dm->cnt_dm[BTC_DCNT_BTCNT_HANG] &&
  739. !bt->enable.now))
  740. _update_bt_scbd(rtwdev, false);
  741. break;
  742. case BTC_DCNT_WL_SLOT_DRIFT:
  743. if (cnt >= BTC_CHK_WLSLOT_DRIFT_MAX)
  744. dm->cnt_dm[BTC_DCNT_WL_SLOT_DRIFT]++;
  745. else
  746. dm->cnt_dm[BTC_DCNT_WL_SLOT_DRIFT] = 0;
  747. if (dm->cnt_dm[BTC_DCNT_WL_SLOT_DRIFT] >= BTC_CHK_HANG_MAX)
  748. dm->error.map.wl_slot_drift = true;
  749. else
  750. dm->error.map.wl_slot_drift = false;
  751. break;
  752. case BTC_DCNT_BT_SLOT_DRIFT:
  753. if (cnt >= BTC_CHK_BTSLOT_DRIFT_MAX)
  754. dm->cnt_dm[BTC_DCNT_BT_SLOT_DRIFT]++;
  755. else
  756. dm->cnt_dm[BTC_DCNT_BT_SLOT_DRIFT] = 0;
  757. if (dm->cnt_dm[BTC_DCNT_BT_SLOT_DRIFT] >= BTC_CHK_HANG_MAX)
  758. dm->error.map.bt_slot_drift = true;
  759. else
  760. dm->error.map.bt_slot_drift = false;
  761. break;
  762. }
  763. }
  764. static void _update_bt_report(struct rtw89_dev *rtwdev, u8 rpt_type, u8 *pfinfo)
  765. {
  766. struct rtw89_btc *btc = &rtwdev->btc;
  767. const struct rtw89_btc_ver *ver = btc->ver;
  768. struct rtw89_btc_bt_info *bt = &btc->cx.bt;
  769. struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info;
  770. struct rtw89_btc_bt_a2dp_desc *a2dp = &bt_linfo->a2dp_desc;
  771. struct rtw89_btc_fbtc_btver *pver = NULL;
  772. struct rtw89_btc_fbtc_btscan_v1 *pscan_v1;
  773. struct rtw89_btc_fbtc_btscan_v2 *pscan_v2;
  774. struct rtw89_btc_fbtc_btafh *pafh_v1 = NULL;
  775. struct rtw89_btc_fbtc_btafh_v2 *pafh_v2 = NULL;
  776. struct rtw89_btc_fbtc_btdevinfo *pdev = NULL;
  777. bool scan_update = true;
  778. int i;
  779. pver = (struct rtw89_btc_fbtc_btver *)pfinfo;
  780. pdev = (struct rtw89_btc_fbtc_btdevinfo *)pfinfo;
  781. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  782. "[BTC], %s(): rpt_type:%d\n",
  783. __func__, rpt_type);
  784. switch (rpt_type) {
  785. case BTC_RPT_TYPE_BT_VER:
  786. bt->ver_info.fw = le32_to_cpu(pver->fw_ver);
  787. bt->ver_info.fw_coex = le32_get_bits(pver->coex_ver, GENMASK(7, 0));
  788. bt->feature = le32_to_cpu(pver->feature);
  789. break;
  790. case BTC_RPT_TYPE_BT_SCAN:
  791. if (ver->fcxbtscan == 1) {
  792. pscan_v1 = (struct rtw89_btc_fbtc_btscan_v1 *)pfinfo;
  793. for (i = 0; i < BTC_SCAN_MAX1; i++) {
  794. bt->scan_info_v1[i] = pscan_v1->scan[i];
  795. if (bt->scan_info_v1[i].win == 0 &&
  796. bt->scan_info_v1[i].intvl == 0)
  797. scan_update = false;
  798. }
  799. } else if (ver->fcxbtscan == 2) {
  800. pscan_v2 = (struct rtw89_btc_fbtc_btscan_v2 *)pfinfo;
  801. for (i = 0; i < CXSCAN_MAX; i++) {
  802. bt->scan_info_v2[i] = pscan_v2->para[i];
  803. if ((pscan_v2->type & BIT(i)) &&
  804. pscan_v2->para[i].win == 0 &&
  805. pscan_v2->para[i].intvl == 0)
  806. scan_update = false;
  807. }
  808. }
  809. if (scan_update)
  810. bt->scan_info_update = 1;
  811. break;
  812. case BTC_RPT_TYPE_BT_AFH:
  813. if (ver->fcxbtafh == 2) {
  814. pafh_v2 = (struct rtw89_btc_fbtc_btafh_v2 *)pfinfo;
  815. if (pafh_v2->map_type & RPT_BT_AFH_SEQ_LEGACY) {
  816. memcpy(&bt_linfo->afh_map[0], pafh_v2->afh_l, 4);
  817. memcpy(&bt_linfo->afh_map[4], pafh_v2->afh_m, 4);
  818. memcpy(&bt_linfo->afh_map[8], pafh_v2->afh_h, 2);
  819. }
  820. if (pafh_v2->map_type & RPT_BT_AFH_SEQ_LE) {
  821. memcpy(&bt_linfo->afh_map_le[0], pafh_v2->afh_le_a, 4);
  822. memcpy(&bt_linfo->afh_map_le[4], pafh_v2->afh_le_b, 1);
  823. }
  824. } else if (ver->fcxbtafh == 1) {
  825. pafh_v1 = (struct rtw89_btc_fbtc_btafh *)pfinfo;
  826. memcpy(&bt_linfo->afh_map[0], pafh_v1->afh_l, 4);
  827. memcpy(&bt_linfo->afh_map[4], pafh_v1->afh_m, 4);
  828. memcpy(&bt_linfo->afh_map[8], pafh_v1->afh_h, 2);
  829. }
  830. break;
  831. case BTC_RPT_TYPE_BT_DEVICE:
  832. a2dp->device_name = le32_to_cpu(pdev->dev_name);
  833. a2dp->vendor_id = le16_to_cpu(pdev->vendor_id);
  834. a2dp->flush_time = le32_to_cpu(pdev->flush_time);
  835. break;
  836. default:
  837. break;
  838. }
  839. }
  840. #define BTC_LEAK_AP_TH 10
  841. #define BTC_CYSTA_CHK_PERIOD 100
  842. struct rtw89_btc_prpt {
  843. u8 type;
  844. __le16 len;
  845. u8 content[];
  846. } __packed;
  847. static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
  848. struct rtw89_btc_btf_fwinfo *pfwinfo,
  849. u8 *prptbuf, u32 index)
  850. {
  851. struct rtw89_btc *btc = &rtwdev->btc;
  852. const struct rtw89_btc_ver *ver = btc->ver;
  853. struct rtw89_btc_dm *dm = &btc->dm;
  854. struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
  855. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  856. struct rtw89_btc_bt_info *bt = &btc->cx.bt;
  857. union rtw89_btc_fbtc_rpt_ctrl_ver_info *prpt = NULL;
  858. union rtw89_btc_fbtc_cysta_info *pcysta = NULL;
  859. struct rtw89_btc_prpt *btc_prpt = NULL;
  860. void *rpt_content = NULL, *pfinfo = NULL;
  861. u8 rpt_type = 0;
  862. u16 wl_slot_set = 0, wl_slot_real = 0;
  863. u32 trace_step = btc->ctrl.trace_step, rpt_len = 0, diff_t = 0;
  864. u32 cnt_leak_slot, bt_slot_real, bt_slot_set, cnt_rx_imr;
  865. u8 i;
  866. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  867. "[BTC], %s(): index:%d\n",
  868. __func__, index);
  869. if (!prptbuf) {
  870. pfwinfo->err[BTFRE_INVALID_INPUT]++;
  871. return 0;
  872. }
  873. btc_prpt = (struct rtw89_btc_prpt *)&prptbuf[index];
  874. rpt_type = btc_prpt->type;
  875. rpt_len = le16_to_cpu(btc_prpt->len);
  876. rpt_content = btc_prpt->content;
  877. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  878. "[BTC], %s(): rpt_type:%d\n",
  879. __func__, rpt_type);
  880. switch (rpt_type) {
  881. case BTC_RPT_TYPE_CTRL:
  882. pcinfo = &pfwinfo->rpt_ctrl.cinfo;
  883. prpt = &pfwinfo->rpt_ctrl.finfo;
  884. if (ver->fcxbtcrpt == 1) {
  885. pfinfo = &pfwinfo->rpt_ctrl.finfo.v1;
  886. pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v1);
  887. } else if (ver->fcxbtcrpt == 4) {
  888. pfinfo = &pfwinfo->rpt_ctrl.finfo.v4;
  889. pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v4);
  890. } else if (ver->fcxbtcrpt == 5) {
  891. pfinfo = &pfwinfo->rpt_ctrl.finfo.v5;
  892. pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v5);
  893. } else if (ver->fcxbtcrpt == 105) {
  894. pfinfo = &pfwinfo->rpt_ctrl.finfo.v105;
  895. pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v105);
  896. pcinfo->req_fver = 5;
  897. break;
  898. } else {
  899. goto err;
  900. }
  901. pcinfo->req_fver = ver->fcxbtcrpt;
  902. break;
  903. case BTC_RPT_TYPE_TDMA:
  904. pcinfo = &pfwinfo->rpt_fbtc_tdma.cinfo;
  905. if (ver->fcxtdma == 1) {
  906. pfinfo = &pfwinfo->rpt_fbtc_tdma.finfo.v1;
  907. pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo.v1);
  908. } else if (ver->fcxtdma == 3) {
  909. pfinfo = &pfwinfo->rpt_fbtc_tdma.finfo.v3;
  910. pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo.v3);
  911. } else {
  912. goto err;
  913. }
  914. pcinfo->req_fver = ver->fcxtdma;
  915. break;
  916. case BTC_RPT_TYPE_SLOT:
  917. pcinfo = &pfwinfo->rpt_fbtc_slots.cinfo;
  918. pfinfo = &pfwinfo->rpt_fbtc_slots.finfo;
  919. pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_slots.finfo);
  920. pcinfo->req_fver = ver->fcxslots;
  921. break;
  922. case BTC_RPT_TYPE_CYSTA:
  923. pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo;
  924. pcysta = &pfwinfo->rpt_fbtc_cysta.finfo;
  925. if (ver->fcxcysta == 2) {
  926. pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v2;
  927. pcysta->v2 = pfwinfo->rpt_fbtc_cysta.finfo.v2;
  928. pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v2);
  929. } else if (ver->fcxcysta == 3) {
  930. pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v3;
  931. pcysta->v3 = pfwinfo->rpt_fbtc_cysta.finfo.v3;
  932. pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v3);
  933. } else if (ver->fcxcysta == 4) {
  934. pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v4;
  935. pcysta->v4 = pfwinfo->rpt_fbtc_cysta.finfo.v4;
  936. pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v4);
  937. } else if (ver->fcxcysta == 5) {
  938. pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v5;
  939. pcysta->v5 = pfwinfo->rpt_fbtc_cysta.finfo.v5;
  940. pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v5);
  941. } else {
  942. goto err;
  943. }
  944. pcinfo->req_fver = ver->fcxcysta;
  945. break;
  946. case BTC_RPT_TYPE_STEP:
  947. pcinfo = &pfwinfo->rpt_fbtc_step.cinfo;
  948. if (ver->fcxstep == 2) {
  949. pfinfo = &pfwinfo->rpt_fbtc_step.finfo.v2;
  950. pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_step.finfo.v2.step[0]) *
  951. trace_step +
  952. offsetof(struct rtw89_btc_fbtc_steps_v2, step);
  953. } else if (ver->fcxstep == 3) {
  954. pfinfo = &pfwinfo->rpt_fbtc_step.finfo.v3;
  955. pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_step.finfo.v3.step[0]) *
  956. trace_step +
  957. offsetof(struct rtw89_btc_fbtc_steps_v3, step);
  958. } else {
  959. goto err;
  960. }
  961. pcinfo->req_fver = ver->fcxstep;
  962. break;
  963. case BTC_RPT_TYPE_NULLSTA:
  964. pcinfo = &pfwinfo->rpt_fbtc_nullsta.cinfo;
  965. if (ver->fcxnullsta == 1) {
  966. pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo.v1;
  967. pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo.v1);
  968. } else if (ver->fcxnullsta == 2) {
  969. pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo.v2;
  970. pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo.v2);
  971. } else {
  972. goto err;
  973. }
  974. pcinfo->req_fver = ver->fcxnullsta;
  975. break;
  976. case BTC_RPT_TYPE_MREG:
  977. pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo;
  978. if (ver->fcxmreg == 1) {
  979. pfinfo = &pfwinfo->rpt_fbtc_mregval.finfo.v1;
  980. pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_mregval.finfo.v1);
  981. } else if (ver->fcxmreg == 2) {
  982. pfinfo = &pfwinfo->rpt_fbtc_mregval.finfo.v2;
  983. pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_mregval.finfo.v2);
  984. } else {
  985. goto err;
  986. }
  987. pcinfo->req_fver = ver->fcxmreg;
  988. break;
  989. case BTC_RPT_TYPE_GPIO_DBG:
  990. pcinfo = &pfwinfo->rpt_fbtc_gpio_dbg.cinfo;
  991. pfinfo = &pfwinfo->rpt_fbtc_gpio_dbg.finfo;
  992. pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_gpio_dbg.finfo);
  993. pcinfo->req_fver = ver->fcxgpiodbg;
  994. break;
  995. case BTC_RPT_TYPE_BT_VER:
  996. pcinfo = &pfwinfo->rpt_fbtc_btver.cinfo;
  997. pfinfo = &pfwinfo->rpt_fbtc_btver.finfo;
  998. pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btver.finfo);
  999. pcinfo->req_fver = ver->fcxbtver;
  1000. break;
  1001. case BTC_RPT_TYPE_BT_SCAN:
  1002. pcinfo = &pfwinfo->rpt_fbtc_btscan.cinfo;
  1003. if (ver->fcxbtscan == 1) {
  1004. pfinfo = &pfwinfo->rpt_fbtc_btscan.finfo.v1;
  1005. pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btscan.finfo.v1);
  1006. } else if (ver->fcxbtscan == 2) {
  1007. pfinfo = &pfwinfo->rpt_fbtc_btscan.finfo.v2;
  1008. pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btscan.finfo.v2);
  1009. }
  1010. pcinfo->req_fver = ver->fcxbtscan;
  1011. break;
  1012. case BTC_RPT_TYPE_BT_AFH:
  1013. pcinfo = &pfwinfo->rpt_fbtc_btafh.cinfo;
  1014. if (ver->fcxbtafh == 1) {
  1015. pfinfo = &pfwinfo->rpt_fbtc_btafh.finfo.v1;
  1016. pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo.v1);
  1017. } else if (ver->fcxbtafh == 2) {
  1018. pfinfo = &pfwinfo->rpt_fbtc_btafh.finfo.v2;
  1019. pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo.v2);
  1020. } else {
  1021. goto err;
  1022. }
  1023. pcinfo->req_fver = ver->fcxbtafh;
  1024. break;
  1025. case BTC_RPT_TYPE_BT_DEVICE:
  1026. pcinfo = &pfwinfo->rpt_fbtc_btdev.cinfo;
  1027. pfinfo = &pfwinfo->rpt_fbtc_btdev.finfo;
  1028. pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btdev.finfo);
  1029. pcinfo->req_fver = ver->fcxbtdevinfo;
  1030. break;
  1031. default:
  1032. pfwinfo->err[BTFRE_UNDEF_TYPE]++;
  1033. return 0;
  1034. }
  1035. pcinfo->rx_len = rpt_len;
  1036. pcinfo->rx_cnt++;
  1037. if (rpt_len != pcinfo->req_len) {
  1038. if (rpt_type < BTC_RPT_TYPE_MAX)
  1039. pfwinfo->len_mismch |= (0x1 << rpt_type);
  1040. else
  1041. pfwinfo->len_mismch |= BIT(31);
  1042. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  1043. "[BTC], %s(): %d rpt_len:%d!=req_len:%d\n",
  1044. __func__, rpt_type, rpt_len, pcinfo->req_len);
  1045. pcinfo->valid = 0;
  1046. return 0;
  1047. } else if (!pfinfo || !rpt_content || !pcinfo->req_len) {
  1048. pfwinfo->err[BTFRE_EXCEPTION]++;
  1049. pcinfo->valid = 0;
  1050. return 0;
  1051. }
  1052. memcpy(pfinfo, rpt_content, pcinfo->req_len);
  1053. pcinfo->valid = 1;
  1054. switch (rpt_type) {
  1055. case BTC_RPT_TYPE_CTRL:
  1056. if (ver->fcxbtcrpt == 1) {
  1057. prpt->v1 = pfwinfo->rpt_ctrl.finfo.v1;
  1058. btc->fwinfo.rpt_en_map = prpt->v1.rpt_enable;
  1059. wl->ver_info.fw_coex = prpt->v1.wl_fw_coex_ver;
  1060. wl->ver_info.fw = prpt->v1.wl_fw_ver;
  1061. dm->wl_fw_cx_offload = !!prpt->v1.wl_fw_cx_offload;
  1062. _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG,
  1063. pfwinfo->event[BTF_EVNT_RPT]);
  1064. /* To avoid I/O if WL LPS or power-off */
  1065. if (wl->status.map.lps != BTC_LPS_RF_OFF &&
  1066. !wl->status.map.rf_off) {
  1067. rtwdev->chip->ops->btc_update_bt_cnt(rtwdev);
  1068. _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0);
  1069. btc->cx.cnt_bt[BTC_BCNT_POLUT] =
  1070. rtw89_mac_get_plt_cnt(rtwdev,
  1071. RTW89_MAC_0);
  1072. }
  1073. } else if (ver->fcxbtcrpt == 4) {
  1074. prpt->v4 = pfwinfo->rpt_ctrl.finfo.v4;
  1075. btc->fwinfo.rpt_en_map = le32_to_cpu(prpt->v4.rpt_info.en);
  1076. wl->ver_info.fw_coex = le32_to_cpu(prpt->v4.wl_fw_info.cx_ver);
  1077. wl->ver_info.fw = le32_to_cpu(prpt->v4.wl_fw_info.fw_ver);
  1078. dm->wl_fw_cx_offload = !!le32_to_cpu(prpt->v4.wl_fw_info.cx_offload);
  1079. for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++)
  1080. memcpy(&dm->gnt.band[i], &prpt->v4.gnt_val[i],
  1081. sizeof(dm->gnt.band[i]));
  1082. btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] =
  1083. le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_HI_TX]);
  1084. btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] =
  1085. le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_HI_RX]);
  1086. btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] =
  1087. le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_LO_TX]);
  1088. btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] =
  1089. le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_LO_RX]);
  1090. btc->cx.cnt_bt[BTC_BCNT_POLUT] =
  1091. le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_POLLUTED]);
  1092. _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0);
  1093. _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG,
  1094. pfwinfo->event[BTF_EVNT_RPT]);
  1095. if (le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_RFK_TIMEOUT]) > 0)
  1096. bt->rfk_info.map.timeout = 1;
  1097. else
  1098. bt->rfk_info.map.timeout = 0;
  1099. dm->error.map.bt_rfk_timeout = bt->rfk_info.map.timeout;
  1100. } else if (ver->fcxbtcrpt == 5) {
  1101. prpt->v5 = pfwinfo->rpt_ctrl.finfo.v5;
  1102. pfwinfo->rpt_en_map = le32_to_cpu(prpt->v5.rpt_info.en);
  1103. wl->ver_info.fw_coex = le32_to_cpu(prpt->v5.rpt_info.cx_ver);
  1104. wl->ver_info.fw = le32_to_cpu(prpt->v5.rpt_info.fw_ver);
  1105. dm->wl_fw_cx_offload = 0;
  1106. for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++)
  1107. memcpy(&dm->gnt.band[i], &prpt->v5.gnt_val[i][0],
  1108. sizeof(dm->gnt.band[i]));
  1109. btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] =
  1110. le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_HI_TX]);
  1111. btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] =
  1112. le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_HI_RX]);
  1113. btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] =
  1114. le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_LO_TX]);
  1115. btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] =
  1116. le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_LO_RX]);
  1117. btc->cx.cnt_bt[BTC_BCNT_POLUT] =
  1118. le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_POLLUTED]);
  1119. _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0);
  1120. _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG,
  1121. pfwinfo->event[BTF_EVNT_RPT]);
  1122. dm->error.map.bt_rfk_timeout = bt->rfk_info.map.timeout;
  1123. } else if (ver->fcxbtcrpt == 105) {
  1124. prpt->v105 = pfwinfo->rpt_ctrl.finfo.v105;
  1125. pfwinfo->rpt_en_map = le32_to_cpu(prpt->v105.rpt_info.en);
  1126. wl->ver_info.fw_coex = le32_to_cpu(prpt->v105.rpt_info.cx_ver);
  1127. wl->ver_info.fw = le32_to_cpu(prpt->v105.rpt_info.fw_ver);
  1128. dm->wl_fw_cx_offload = 0;
  1129. for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++)
  1130. memcpy(&dm->gnt.band[i], &prpt->v105.gnt_val[i][0],
  1131. sizeof(dm->gnt.band[i]));
  1132. btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] =
  1133. le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_HI_TX_V105]);
  1134. btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] =
  1135. le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_HI_RX_V105]);
  1136. btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] =
  1137. le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_LO_TX_V105]);
  1138. btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] =
  1139. le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_LO_RX_V105]);
  1140. btc->cx.cnt_bt[BTC_BCNT_POLUT] =
  1141. le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_POLLUTED_V105]);
  1142. _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0);
  1143. _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG,
  1144. pfwinfo->event[BTF_EVNT_RPT]);
  1145. dm->error.map.bt_rfk_timeout = bt->rfk_info.map.timeout;
  1146. } else {
  1147. goto err;
  1148. }
  1149. break;
  1150. case BTC_RPT_TYPE_TDMA:
  1151. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  1152. "[BTC], %s(): check %d %zu\n", __func__,
  1153. BTC_DCNT_TDMA_NONSYNC,
  1154. sizeof(dm->tdma_now));
  1155. if (ver->fcxtdma == 1)
  1156. _chk_btc_err(rtwdev, BTC_DCNT_TDMA_NONSYNC,
  1157. memcmp(&dm->tdma_now,
  1158. &pfwinfo->rpt_fbtc_tdma.finfo.v1,
  1159. sizeof(dm->tdma_now)));
  1160. else if (ver->fcxtdma == 3)
  1161. _chk_btc_err(rtwdev, BTC_DCNT_TDMA_NONSYNC,
  1162. memcmp(&dm->tdma_now,
  1163. &pfwinfo->rpt_fbtc_tdma.finfo.v3.tdma,
  1164. sizeof(dm->tdma_now)));
  1165. else
  1166. goto err;
  1167. break;
  1168. case BTC_RPT_TYPE_SLOT:
  1169. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  1170. "[BTC], %s(): check %d %zu\n",
  1171. __func__, BTC_DCNT_SLOT_NONSYNC,
  1172. sizeof(dm->slot_now));
  1173. _chk_btc_err(rtwdev, BTC_DCNT_SLOT_NONSYNC,
  1174. memcmp(dm->slot_now,
  1175. pfwinfo->rpt_fbtc_slots.finfo.slot,
  1176. sizeof(dm->slot_now)));
  1177. break;
  1178. case BTC_RPT_TYPE_CYSTA:
  1179. if (ver->fcxcysta == 2) {
  1180. if (le16_to_cpu(pcysta->v2.cycles) < BTC_CYSTA_CHK_PERIOD)
  1181. break;
  1182. /* Check Leak-AP */
  1183. if (le32_to_cpu(pcysta->v2.slot_cnt[CXST_LK]) != 0 &&
  1184. le32_to_cpu(pcysta->v2.leakrx_cnt) != 0 && dm->tdma_now.rxflctrl) {
  1185. if (le32_to_cpu(pcysta->v2.slot_cnt[CXST_LK]) <
  1186. BTC_LEAK_AP_TH * le32_to_cpu(pcysta->v2.leakrx_cnt))
  1187. dm->leak_ap = 1;
  1188. }
  1189. /* Check diff time between WL slot and W1/E2G slot */
  1190. if (dm->tdma_now.type == CXTDMA_OFF &&
  1191. dm->tdma_now.ext_ctrl == CXECTL_EXT)
  1192. wl_slot_set = le16_to_cpu(dm->slot_now[CXST_E2G].dur);
  1193. else
  1194. wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur);
  1195. if (le16_to_cpu(pcysta->v2.tavg_cycle[CXT_WL]) > wl_slot_set) {
  1196. diff_t = le16_to_cpu(pcysta->v2.tavg_cycle[CXT_WL]) - wl_slot_set;
  1197. _chk_btc_err(rtwdev,
  1198. BTC_DCNT_WL_SLOT_DRIFT, diff_t);
  1199. }
  1200. _chk_btc_err(rtwdev, BTC_DCNT_W1_HANG,
  1201. le32_to_cpu(pcysta->v2.slot_cnt[CXST_W1]));
  1202. _chk_btc_err(rtwdev, BTC_DCNT_W1_HANG,
  1203. le32_to_cpu(pcysta->v2.slot_cnt[CXST_B1]));
  1204. _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_HANG,
  1205. le16_to_cpu(pcysta->v2.cycles));
  1206. } else if (ver->fcxcysta == 3) {
  1207. if (le16_to_cpu(pcysta->v3.cycles) < BTC_CYSTA_CHK_PERIOD)
  1208. break;
  1209. cnt_leak_slot = le32_to_cpu(pcysta->v3.slot_cnt[CXST_LK]);
  1210. cnt_rx_imr = le32_to_cpu(pcysta->v3.leak_slot.cnt_rximr);
  1211. /* Check Leak-AP */
  1212. if (cnt_leak_slot != 0 && cnt_rx_imr != 0 &&
  1213. dm->tdma_now.rxflctrl) {
  1214. if (cnt_leak_slot < BTC_LEAK_AP_TH * cnt_rx_imr)
  1215. dm->leak_ap = 1;
  1216. }
  1217. /* Check diff time between real WL slot and W1 slot */
  1218. if (dm->tdma_now.type == CXTDMA_OFF) {
  1219. wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur);
  1220. wl_slot_real = le16_to_cpu(pcysta->v3.cycle_time.tavg[CXT_WL]);
  1221. if (wl_slot_real > wl_slot_set) {
  1222. diff_t = wl_slot_real - wl_slot_set;
  1223. _chk_btc_err(rtwdev, BTC_DCNT_WL_SLOT_DRIFT, diff_t);
  1224. }
  1225. }
  1226. /* Check diff time between real BT slot and EBT/E5G slot */
  1227. if (dm->tdma_now.type == CXTDMA_OFF &&
  1228. dm->tdma_now.ext_ctrl == CXECTL_EXT &&
  1229. btc->bt_req_len != 0) {
  1230. bt_slot_real = le16_to_cpu(pcysta->v3.cycle_time.tavg[CXT_BT]);
  1231. if (btc->bt_req_len > bt_slot_real) {
  1232. diff_t = btc->bt_req_len - bt_slot_real;
  1233. _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, diff_t);
  1234. }
  1235. }
  1236. _chk_btc_err(rtwdev, BTC_DCNT_W1_HANG,
  1237. le32_to_cpu(pcysta->v3.slot_cnt[CXST_W1]));
  1238. _chk_btc_err(rtwdev, BTC_DCNT_B1_HANG,
  1239. le32_to_cpu(pcysta->v3.slot_cnt[CXST_B1]));
  1240. _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_HANG,
  1241. le16_to_cpu(pcysta->v3.cycles));
  1242. } else if (ver->fcxcysta == 4) {
  1243. if (le16_to_cpu(pcysta->v4.cycles) < BTC_CYSTA_CHK_PERIOD)
  1244. break;
  1245. cnt_leak_slot = le16_to_cpu(pcysta->v4.slot_cnt[CXST_LK]);
  1246. cnt_rx_imr = le32_to_cpu(pcysta->v4.leak_slot.cnt_rximr);
  1247. /* Check Leak-AP */
  1248. if (cnt_leak_slot != 0 && cnt_rx_imr != 0 &&
  1249. dm->tdma_now.rxflctrl) {
  1250. if (cnt_leak_slot < BTC_LEAK_AP_TH * cnt_rx_imr)
  1251. dm->leak_ap = 1;
  1252. }
  1253. /* Check diff time between real WL slot and W1 slot */
  1254. if (dm->tdma_now.type == CXTDMA_OFF) {
  1255. wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur);
  1256. wl_slot_real = le16_to_cpu(pcysta->v4.cycle_time.tavg[CXT_WL]);
  1257. if (wl_slot_real > wl_slot_set) {
  1258. diff_t = wl_slot_real - wl_slot_set;
  1259. _chk_btc_err(rtwdev, BTC_DCNT_WL_SLOT_DRIFT, diff_t);
  1260. }
  1261. }
  1262. /* Check diff time between real BT slot and EBT/E5G slot */
  1263. if (dm->tdma_now.type == CXTDMA_OFF &&
  1264. dm->tdma_now.ext_ctrl == CXECTL_EXT &&
  1265. btc->bt_req_len != 0) {
  1266. bt_slot_real = le16_to_cpu(pcysta->v4.cycle_time.tavg[CXT_BT]);
  1267. if (btc->bt_req_len > bt_slot_real) {
  1268. diff_t = btc->bt_req_len - bt_slot_real;
  1269. _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, diff_t);
  1270. }
  1271. }
  1272. _chk_btc_err(rtwdev, BTC_DCNT_W1_HANG,
  1273. le16_to_cpu(pcysta->v4.slot_cnt[CXST_W1]));
  1274. _chk_btc_err(rtwdev, BTC_DCNT_B1_HANG,
  1275. le16_to_cpu(pcysta->v4.slot_cnt[CXST_B1]));
  1276. _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_HANG,
  1277. le16_to_cpu(pcysta->v4.cycles));
  1278. } else if (ver->fcxcysta == 5) {
  1279. if (dm->fddt_train == BTC_FDDT_ENABLE)
  1280. break;
  1281. cnt_leak_slot = le16_to_cpu(pcysta->v5.slot_cnt[CXST_LK]);
  1282. cnt_rx_imr = le32_to_cpu(pcysta->v5.leak_slot.cnt_rximr);
  1283. /* Check Leak-AP */
  1284. if (cnt_leak_slot != 0 && cnt_rx_imr != 0 &&
  1285. dm->tdma_now.rxflctrl) {
  1286. if (le16_to_cpu(pcysta->v5.cycles) >= BTC_CYSTA_CHK_PERIOD &&
  1287. cnt_leak_slot < BTC_LEAK_AP_TH * cnt_rx_imr)
  1288. dm->leak_ap = 1;
  1289. }
  1290. /* Check diff time between real WL slot and W1 slot */
  1291. if (dm->tdma_now.type == CXTDMA_OFF) {
  1292. wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur);
  1293. wl_slot_real = le16_to_cpu(pcysta->v5.cycle_time.tavg[CXT_WL]);
  1294. if (wl_slot_real > wl_slot_set)
  1295. diff_t = wl_slot_real - wl_slot_set;
  1296. else
  1297. diff_t = wl_slot_set - wl_slot_real;
  1298. }
  1299. _chk_btc_err(rtwdev, BTC_DCNT_WL_SLOT_DRIFT, diff_t);
  1300. /* Check diff time between real BT slot and EBT/E5G slot */
  1301. bt_slot_set = btc->bt_req_len;
  1302. bt_slot_real = le16_to_cpu(pcysta->v5.cycle_time.tavg[CXT_BT]);
  1303. diff_t = 0;
  1304. if (dm->tdma_now.type == CXTDMA_OFF &&
  1305. dm->tdma_now.ext_ctrl == CXECTL_EXT &&
  1306. bt_slot_set != 0) {
  1307. if (bt_slot_set > bt_slot_real)
  1308. diff_t = bt_slot_set - bt_slot_real;
  1309. else
  1310. diff_t = bt_slot_real - bt_slot_set;
  1311. }
  1312. _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, diff_t);
  1313. _chk_btc_err(rtwdev, BTC_DCNT_E2G_HANG,
  1314. le16_to_cpu(pcysta->v5.slot_cnt[CXST_E2G]));
  1315. _chk_btc_err(rtwdev, BTC_DCNT_W1_HANG,
  1316. le16_to_cpu(pcysta->v5.slot_cnt[CXST_W1]));
  1317. _chk_btc_err(rtwdev, BTC_DCNT_B1_HANG,
  1318. le16_to_cpu(pcysta->v5.slot_cnt[CXST_B1]));
  1319. _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_HANG,
  1320. le16_to_cpu(pcysta->v5.cycles));
  1321. } else {
  1322. goto err;
  1323. }
  1324. break;
  1325. case BTC_RPT_TYPE_BT_VER:
  1326. case BTC_RPT_TYPE_BT_SCAN:
  1327. case BTC_RPT_TYPE_BT_AFH:
  1328. case BTC_RPT_TYPE_BT_DEVICE:
  1329. _update_bt_report(rtwdev, rpt_type, pfinfo);
  1330. break;
  1331. }
  1332. return (rpt_len + BTC_RPT_HDR_SIZE);
  1333. err:
  1334. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  1335. "[BTC], %s(): Undefined version for type=%d\n", __func__, rpt_type);
  1336. return 0;
  1337. }
  1338. static void _parse_btc_report(struct rtw89_dev *rtwdev,
  1339. struct rtw89_btc_btf_fwinfo *pfwinfo,
  1340. u8 *pbuf, u32 buf_len)
  1341. {
  1342. const struct rtw89_btc_ver *ver = rtwdev->btc.ver;
  1343. struct rtw89_btc_prpt *btc_prpt = NULL;
  1344. u32 index = 0, rpt_len = 0;
  1345. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  1346. "[BTC], %s(): buf_len:%d\n",
  1347. __func__, buf_len);
  1348. while (pbuf) {
  1349. btc_prpt = (struct rtw89_btc_prpt *)&pbuf[index];
  1350. if (index + 2 >= ver->info_buf)
  1351. break;
  1352. /* At least 3 bytes: type(1) & len(2) */
  1353. rpt_len = le16_to_cpu(btc_prpt->len);
  1354. if ((index + rpt_len + BTC_RPT_HDR_SIZE) > buf_len)
  1355. break;
  1356. rpt_len = _chk_btc_report(rtwdev, pfwinfo, pbuf, index);
  1357. if (!rpt_len)
  1358. break;
  1359. index += rpt_len;
  1360. }
  1361. }
  1362. #define BTC_TLV_HDR_LEN 2
  1363. static void _append_tdma(struct rtw89_dev *rtwdev)
  1364. {
  1365. struct rtw89_btc *btc = &rtwdev->btc;
  1366. const struct rtw89_btc_ver *ver = btc->ver;
  1367. struct rtw89_btc_dm *dm = &btc->dm;
  1368. struct rtw89_btc_btf_tlv *tlv;
  1369. struct rtw89_btc_fbtc_tdma *v;
  1370. struct rtw89_btc_fbtc_tdma_v3 *v3;
  1371. u16 len = btc->policy_len;
  1372. if (!btc->update_policy_force &&
  1373. !memcmp(&dm->tdma, &dm->tdma_now, sizeof(dm->tdma))) {
  1374. rtw89_debug(rtwdev,
  1375. RTW89_DBG_BTC, "[BTC], %s(): tdma no change!\n",
  1376. __func__);
  1377. return;
  1378. }
  1379. tlv = (struct rtw89_btc_btf_tlv *)&btc->policy[len];
  1380. tlv->type = CXPOLICY_TDMA;
  1381. if (ver->fcxtdma == 1) {
  1382. v = (struct rtw89_btc_fbtc_tdma *)&tlv->val[0];
  1383. tlv->len = sizeof(*v);
  1384. memcpy(v, &dm->tdma, sizeof(*v));
  1385. btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v);
  1386. } else {
  1387. tlv->len = sizeof(*v3);
  1388. v3 = (struct rtw89_btc_fbtc_tdma_v3 *)&tlv->val[0];
  1389. v3->fver = ver->fcxtdma;
  1390. memcpy(&v3->tdma, &dm->tdma, sizeof(v3->tdma));
  1391. btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v3);
  1392. }
  1393. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  1394. "[BTC], %s(): type:%d, rxflctrl=%d, txpause=%d, wtgle_n=%d, leak_n=%d, ext_ctrl=%d\n",
  1395. __func__, dm->tdma.type, dm->tdma.rxflctrl,
  1396. dm->tdma.txpause, dm->tdma.wtgle_n, dm->tdma.leak_n,
  1397. dm->tdma.ext_ctrl);
  1398. }
  1399. static void _append_slot(struct rtw89_dev *rtwdev)
  1400. {
  1401. struct rtw89_btc *btc = &rtwdev->btc;
  1402. struct rtw89_btc_dm *dm = &btc->dm;
  1403. struct rtw89_btc_btf_tlv *tlv = NULL;
  1404. struct btc_fbtc_1slot *v = NULL;
  1405. u16 len = 0;
  1406. u8 i, cnt = 0;
  1407. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  1408. "[BTC], %s(): A:btc->policy_len = %d\n",
  1409. __func__, btc->policy_len);
  1410. for (i = 0; i < CXST_MAX; i++) {
  1411. if (!btc->update_policy_force &&
  1412. !memcmp(&dm->slot[i], &dm->slot_now[i],
  1413. sizeof(dm->slot[i])))
  1414. continue;
  1415. len = btc->policy_len;
  1416. tlv = (struct rtw89_btc_btf_tlv *)&btc->policy[len];
  1417. v = (struct btc_fbtc_1slot *)&tlv->val[0];
  1418. tlv->type = CXPOLICY_SLOT;
  1419. tlv->len = sizeof(*v);
  1420. v->fver = FCXONESLOT_VER;
  1421. v->sid = i;
  1422. v->slot = dm->slot[i];
  1423. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  1424. "[BTC], %s(): slot-%d: dur=%d, table=0x%08x, type=%d\n",
  1425. __func__, i, dm->slot[i].dur, dm->slot[i].cxtbl,
  1426. dm->slot[i].cxtype);
  1427. cnt++;
  1428. btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v);
  1429. }
  1430. if (cnt > 0)
  1431. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  1432. "[BTC], %s(): slot update (cnt=%d)!!\n",
  1433. __func__, cnt);
  1434. }
  1435. static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map)
  1436. {
  1437. struct rtw89_btc *btc = &rtwdev->btc;
  1438. const struct rtw89_btc_ver *ver = btc->ver;
  1439. u32 bit_map = 0;
  1440. switch (rpt_map) {
  1441. case RPT_EN_TDMA:
  1442. bit_map = BIT(0);
  1443. break;
  1444. case RPT_EN_CYCLE:
  1445. bit_map = BIT(1);
  1446. break;
  1447. case RPT_EN_MREG:
  1448. bit_map = BIT(2);
  1449. break;
  1450. case RPT_EN_BT_VER_INFO:
  1451. bit_map = BIT(3);
  1452. break;
  1453. case RPT_EN_BT_SCAN_INFO:
  1454. bit_map = BIT(4);
  1455. break;
  1456. case RPT_EN_BT_DEVICE_INFO:
  1457. switch (ver->frptmap) {
  1458. case 0:
  1459. case 1:
  1460. case 2:
  1461. bit_map = BIT(6);
  1462. break;
  1463. case 3:
  1464. bit_map = BIT(5);
  1465. break;
  1466. default:
  1467. break;
  1468. }
  1469. break;
  1470. case RPT_EN_BT_AFH_MAP:
  1471. switch (ver->frptmap) {
  1472. case 0:
  1473. case 1:
  1474. case 2:
  1475. bit_map = BIT(5);
  1476. break;
  1477. case 3:
  1478. bit_map = BIT(6);
  1479. break;
  1480. default:
  1481. break;
  1482. }
  1483. break;
  1484. case RPT_EN_BT_AFH_MAP_LE:
  1485. switch (ver->frptmap) {
  1486. case 2:
  1487. bit_map = BIT(8);
  1488. break;
  1489. case 3:
  1490. bit_map = BIT(7);
  1491. break;
  1492. default:
  1493. break;
  1494. }
  1495. break;
  1496. case RPT_EN_FW_STEP_INFO:
  1497. switch (ver->frptmap) {
  1498. case 1:
  1499. case 2:
  1500. bit_map = BIT(7);
  1501. break;
  1502. case 3:
  1503. bit_map = BIT(8);
  1504. break;
  1505. default:
  1506. break;
  1507. }
  1508. break;
  1509. case RPT_EN_TEST:
  1510. bit_map = BIT(31);
  1511. break;
  1512. case RPT_EN_WL_ALL:
  1513. switch (ver->frptmap) {
  1514. case 0:
  1515. case 1:
  1516. case 2:
  1517. bit_map = GENMASK(2, 0);
  1518. break;
  1519. case 3:
  1520. bit_map = GENMASK(2, 0) | BIT(8);
  1521. break;
  1522. default:
  1523. break;
  1524. }
  1525. break;
  1526. case RPT_EN_BT_ALL:
  1527. switch (ver->frptmap) {
  1528. case 0:
  1529. case 1:
  1530. bit_map = GENMASK(6, 3);
  1531. break;
  1532. case 2:
  1533. bit_map = GENMASK(6, 3) | BIT(8);
  1534. break;
  1535. case 3:
  1536. bit_map = GENMASK(7, 3);
  1537. break;
  1538. default:
  1539. break;
  1540. }
  1541. break;
  1542. case RPT_EN_ALL:
  1543. switch (ver->frptmap) {
  1544. case 0:
  1545. bit_map = GENMASK(6, 0);
  1546. break;
  1547. case 1:
  1548. bit_map = GENMASK(7, 0);
  1549. break;
  1550. case 2:
  1551. case 3:
  1552. bit_map = GENMASK(8, 0);
  1553. break;
  1554. default:
  1555. break;
  1556. }
  1557. break;
  1558. case RPT_EN_MONITER:
  1559. switch (ver->frptmap) {
  1560. case 0:
  1561. case 1:
  1562. bit_map = GENMASK(6, 2);
  1563. break;
  1564. case 2:
  1565. bit_map = GENMASK(6, 2) | BIT(8);
  1566. break;
  1567. case 3:
  1568. bit_map = GENMASK(8, 2);
  1569. break;
  1570. default:
  1571. break;
  1572. }
  1573. break;
  1574. }
  1575. return bit_map;
  1576. }
  1577. static void rtw89_btc_fw_en_rpt(struct rtw89_dev *rtwdev,
  1578. u32 rpt_map, bool rpt_state)
  1579. {
  1580. struct rtw89_btc *btc = &rtwdev->btc;
  1581. struct rtw89_btc_wl_smap *wl_smap = &btc->cx.wl.status.map;
  1582. struct rtw89_btc_btf_fwinfo *fwinfo = &btc->fwinfo;
  1583. struct rtw89_btc_btf_set_report r = {0};
  1584. u32 val, bit_map;
  1585. if ((wl_smap->rf_off || wl_smap->lps != BTC_LPS_OFF) && rpt_state != 0)
  1586. return;
  1587. bit_map = rtw89_btc_fw_rpt_ver(rtwdev, rpt_map);
  1588. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  1589. "[BTC], %s(): rpt_map=%x, rpt_state=%x\n",
  1590. __func__, rpt_map, rpt_state);
  1591. if (rpt_state)
  1592. val = fwinfo->rpt_en_map | bit_map;
  1593. else
  1594. val = fwinfo->rpt_en_map & ~bit_map;
  1595. if (val == fwinfo->rpt_en_map)
  1596. return;
  1597. fwinfo->rpt_en_map = val;
  1598. r.fver = BTF_SET_REPORT_VER;
  1599. r.enable = cpu_to_le32(val);
  1600. r.para = cpu_to_le32(rpt_state);
  1601. _send_fw_cmd(rtwdev, BTFC_SET, SET_REPORT_EN, &r, sizeof(r));
  1602. }
  1603. static void rtw89_btc_fw_set_slots(struct rtw89_dev *rtwdev, u8 num,
  1604. struct rtw89_btc_fbtc_slot *s)
  1605. {
  1606. struct rtw89_btc_btf_set_slot_table *tbl = NULL;
  1607. u8 *ptr = NULL;
  1608. u16 n = 0;
  1609. n = sizeof(*s) * num + sizeof(*tbl);
  1610. tbl = kmalloc(n, GFP_KERNEL);
  1611. if (!tbl)
  1612. return;
  1613. tbl->fver = BTF_SET_SLOT_TABLE_VER;
  1614. tbl->tbl_num = num;
  1615. ptr = &tbl->buf[0];
  1616. memcpy(ptr, s, num * sizeof(*s));
  1617. _send_fw_cmd(rtwdev, BTFC_SET, SET_SLOT_TABLE, tbl, n);
  1618. kfree(tbl);
  1619. }
  1620. static void btc_fw_set_monreg(struct rtw89_dev *rtwdev)
  1621. {
  1622. const struct rtw89_chip_info *chip = rtwdev->chip;
  1623. const struct rtw89_btc_ver *ver = rtwdev->btc.ver;
  1624. struct rtw89_btc_btf_set_mon_reg *monreg = NULL;
  1625. u8 n, *ptr = NULL, ulen, cxmreg_max;
  1626. u16 sz = 0;
  1627. n = chip->mon_reg_num;
  1628. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  1629. "[BTC], %s(): mon_reg_num=%d\n", __func__, n);
  1630. if (ver->fcxmreg == 1)
  1631. cxmreg_max = CXMREG_MAX;
  1632. else if (ver->fcxmreg == 2)
  1633. cxmreg_max = CXMREG_MAX_V2;
  1634. else
  1635. return;
  1636. if (n > cxmreg_max) {
  1637. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  1638. "[BTC], %s(): mon reg count %d > %d\n",
  1639. __func__, n, cxmreg_max);
  1640. return;
  1641. }
  1642. ulen = sizeof(struct rtw89_btc_fbtc_mreg);
  1643. sz = (ulen * n) + sizeof(*monreg);
  1644. monreg = kmalloc(sz, GFP_KERNEL);
  1645. if (!monreg)
  1646. return;
  1647. monreg->fver = ver->fcxmreg;
  1648. monreg->reg_num = n;
  1649. ptr = &monreg->buf[0];
  1650. memcpy(ptr, chip->mon_reg, n * ulen);
  1651. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  1652. "[BTC], %s(): sz=%d ulen=%d n=%d\n",
  1653. __func__, sz, ulen, n);
  1654. _send_fw_cmd(rtwdev, BTFC_SET, SET_MREG_TABLE, (u8 *)monreg, sz);
  1655. kfree(monreg);
  1656. rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_MREG, 1);
  1657. }
  1658. static void _update_dm_step(struct rtw89_dev *rtwdev,
  1659. enum btc_reason_and_action reason_or_action)
  1660. {
  1661. struct rtw89_btc *btc = &rtwdev->btc;
  1662. struct rtw89_btc_dm *dm = &btc->dm;
  1663. /* use ring-structure to store dm step */
  1664. dm->dm_step.step[dm->dm_step.step_pos] = reason_or_action;
  1665. dm->dm_step.step_pos++;
  1666. if (dm->dm_step.step_pos >= ARRAY_SIZE(dm->dm_step.step)) {
  1667. dm->dm_step.step_pos = 0;
  1668. dm->dm_step.step_ov = true;
  1669. }
  1670. }
  1671. static void _fw_set_policy(struct rtw89_dev *rtwdev, u16 policy_type,
  1672. enum btc_reason_and_action action)
  1673. {
  1674. struct rtw89_btc *btc = &rtwdev->btc;
  1675. struct rtw89_btc_dm *dm = &btc->dm;
  1676. dm->run_action = action;
  1677. _update_dm_step(rtwdev, action | BTC_ACT_EXT_BIT);
  1678. _update_dm_step(rtwdev, policy_type | BTC_POLICY_EXT_BIT);
  1679. btc->policy_len = 0;
  1680. btc->policy_type = policy_type;
  1681. _append_tdma(rtwdev);
  1682. _append_slot(rtwdev);
  1683. if (btc->policy_len == 0 || btc->policy_len > RTW89_BTC_POLICY_MAXLEN)
  1684. return;
  1685. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  1686. "[BTC], %s(): action = %d -> policy type/len: 0x%04x/%d\n",
  1687. __func__, action, policy_type, btc->policy_len);
  1688. if (dm->tdma.rxflctrl == CXFLC_NULLP ||
  1689. dm->tdma.rxflctrl == CXFLC_QOSNULL)
  1690. btc->lps = 1;
  1691. else
  1692. btc->lps = 0;
  1693. if (btc->lps == 1)
  1694. rtw89_set_coex_ctrl_lps(rtwdev, btc->lps);
  1695. _send_fw_cmd(rtwdev, BTFC_SET, SET_CX_POLICY,
  1696. btc->policy, btc->policy_len);
  1697. memcpy(&dm->tdma_now, &dm->tdma, sizeof(dm->tdma_now));
  1698. memcpy(&dm->slot_now, &dm->slot, sizeof(dm->slot_now));
  1699. if (btc->update_policy_force)
  1700. btc->update_policy_force = false;
  1701. if (btc->lps == 0)
  1702. rtw89_set_coex_ctrl_lps(rtwdev, btc->lps);
  1703. }
  1704. static void _fw_set_drv_info(struct rtw89_dev *rtwdev, u8 type)
  1705. {
  1706. struct rtw89_btc *btc = &rtwdev->btc;
  1707. const struct rtw89_btc_ver *ver = btc->ver;
  1708. struct rtw89_btc_dm *dm = &btc->dm;
  1709. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  1710. struct rtw89_btc_rf_trx_para rf_para = dm->rf_trx_para;
  1711. switch (type) {
  1712. case CXDRVINFO_INIT:
  1713. rtw89_fw_h2c_cxdrv_init(rtwdev);
  1714. break;
  1715. case CXDRVINFO_ROLE:
  1716. if (ver->fwlrole == 0)
  1717. rtw89_fw_h2c_cxdrv_role(rtwdev);
  1718. else if (ver->fwlrole == 1)
  1719. rtw89_fw_h2c_cxdrv_role_v1(rtwdev);
  1720. else if (ver->fwlrole == 2)
  1721. rtw89_fw_h2c_cxdrv_role_v2(rtwdev);
  1722. break;
  1723. case CXDRVINFO_CTRL:
  1724. rtw89_fw_h2c_cxdrv_ctrl(rtwdev);
  1725. break;
  1726. case CXDRVINFO_TRX:
  1727. dm->trx_info.tx_power = u32_get_bits(rf_para.wl_tx_power,
  1728. RTW89_BTC_WL_DEF_TX_PWR);
  1729. dm->trx_info.rx_gain = u32_get_bits(rf_para.wl_rx_gain,
  1730. RTW89_BTC_WL_DEF_TX_PWR);
  1731. dm->trx_info.bt_tx_power = u32_get_bits(rf_para.bt_tx_power,
  1732. RTW89_BTC_WL_DEF_TX_PWR);
  1733. dm->trx_info.bt_rx_gain = u32_get_bits(rf_para.bt_rx_gain,
  1734. RTW89_BTC_WL_DEF_TX_PWR);
  1735. dm->trx_info.cn = wl->cn_report;
  1736. dm->trx_info.nhm = wl->nhm.pwr;
  1737. rtw89_fw_h2c_cxdrv_trx(rtwdev);
  1738. break;
  1739. case CXDRVINFO_RFK:
  1740. rtw89_fw_h2c_cxdrv_rfk(rtwdev);
  1741. break;
  1742. default:
  1743. break;
  1744. }
  1745. }
  1746. static
  1747. void btc_fw_event(struct rtw89_dev *rtwdev, u8 evt_id, void *data, u32 len)
  1748. {
  1749. struct rtw89_btc *btc = &rtwdev->btc;
  1750. struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
  1751. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  1752. "[BTC], %s(): evt_id:%d len:%d\n",
  1753. __func__, evt_id, len);
  1754. if (!len || !data)
  1755. return;
  1756. switch (evt_id) {
  1757. case BTF_EVNT_RPT:
  1758. _parse_btc_report(rtwdev, pfwinfo, data, len);
  1759. break;
  1760. default:
  1761. break;
  1762. }
  1763. }
  1764. static void _set_gnt(struct rtw89_dev *rtwdev, u8 phy_map, u8 wl_state, u8 bt_state)
  1765. {
  1766. struct rtw89_btc *btc = &rtwdev->btc;
  1767. struct rtw89_btc_dm *dm = &btc->dm;
  1768. struct rtw89_mac_ax_gnt *g = dm->gnt.band;
  1769. u8 i;
  1770. if (phy_map > BTC_PHY_ALL)
  1771. return;
  1772. for (i = 0; i < RTW89_PHY_MAX; i++) {
  1773. if (!(phy_map & BIT(i)))
  1774. continue;
  1775. switch (wl_state) {
  1776. case BTC_GNT_HW:
  1777. g[i].gnt_wl_sw_en = 0;
  1778. g[i].gnt_wl = 0;
  1779. break;
  1780. case BTC_GNT_SW_LO:
  1781. g[i].gnt_wl_sw_en = 1;
  1782. g[i].gnt_wl = 0;
  1783. break;
  1784. case BTC_GNT_SW_HI:
  1785. g[i].gnt_wl_sw_en = 1;
  1786. g[i].gnt_wl = 1;
  1787. break;
  1788. }
  1789. switch (bt_state) {
  1790. case BTC_GNT_HW:
  1791. g[i].gnt_bt_sw_en = 0;
  1792. g[i].gnt_bt = 0;
  1793. break;
  1794. case BTC_GNT_SW_LO:
  1795. g[i].gnt_bt_sw_en = 1;
  1796. g[i].gnt_bt = 0;
  1797. break;
  1798. case BTC_GNT_SW_HI:
  1799. g[i].gnt_bt_sw_en = 1;
  1800. g[i].gnt_bt = 1;
  1801. break;
  1802. }
  1803. }
  1804. rtw89_chip_mac_cfg_gnt(rtwdev, &dm->gnt);
  1805. }
  1806. #define BTC_TDMA_WLROLE_MAX 2
  1807. static void _set_bt_ignore_wlan_act(struct rtw89_dev *rtwdev, u8 enable)
  1808. {
  1809. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  1810. "[BTC], %s(): set bt %s wlan_act\n", __func__,
  1811. enable ? "ignore" : "do not ignore");
  1812. _send_fw_cmd(rtwdev, BTFC_SET, SET_BT_IGNORE_WLAN_ACT, &enable, 1);
  1813. }
  1814. #define WL_TX_POWER_NO_BTC_CTRL GENMASK(31, 0)
  1815. #define WL_TX_POWER_ALL_TIME GENMASK(15, 0)
  1816. #define WL_TX_POWER_WITH_BT GENMASK(31, 16)
  1817. #define WL_TX_POWER_INT_PART GENMASK(8, 2)
  1818. #define WL_TX_POWER_FRA_PART GENMASK(1, 0)
  1819. #define B_BTC_WL_TX_POWER_SIGN BIT(7)
  1820. #define B_TSSI_WL_TX_POWER_SIGN BIT(8)
  1821. static void _set_wl_tx_power(struct rtw89_dev *rtwdev, u32 level)
  1822. {
  1823. const struct rtw89_chip_info *chip = rtwdev->chip;
  1824. struct rtw89_btc *btc = &rtwdev->btc;
  1825. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  1826. u32 pwr_val;
  1827. if (wl->rf_para.tx_pwr_freerun == level)
  1828. return;
  1829. wl->rf_para.tx_pwr_freerun = level;
  1830. btc->dm.rf_trx_para.wl_tx_power = level;
  1831. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  1832. "[BTC], %s(): level = %d\n",
  1833. __func__, level);
  1834. if (level == RTW89_BTC_WL_DEF_TX_PWR) {
  1835. pwr_val = WL_TX_POWER_NO_BTC_CTRL;
  1836. } else { /* only apply "force tx power" */
  1837. pwr_val = FIELD_PREP(WL_TX_POWER_INT_PART, level);
  1838. if (pwr_val > RTW89_BTC_WL_DEF_TX_PWR)
  1839. pwr_val = RTW89_BTC_WL_DEF_TX_PWR;
  1840. if (level & B_BTC_WL_TX_POWER_SIGN)
  1841. pwr_val |= B_TSSI_WL_TX_POWER_SIGN;
  1842. pwr_val |= WL_TX_POWER_WITH_BT;
  1843. }
  1844. chip->ops->btc_set_wl_txpwr_ctrl(rtwdev, pwr_val);
  1845. }
  1846. static void _set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level)
  1847. {
  1848. const struct rtw89_chip_info *chip = rtwdev->chip;
  1849. struct rtw89_btc *btc = &rtwdev->btc;
  1850. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  1851. if (wl->rf_para.rx_gain_freerun == level)
  1852. return;
  1853. wl->rf_para.rx_gain_freerun = level;
  1854. btc->dm.rf_trx_para.wl_rx_gain = level;
  1855. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  1856. "[BTC], %s(): level = %d\n",
  1857. __func__, level);
  1858. chip->ops->btc_set_wl_rx_gain(rtwdev, level);
  1859. }
  1860. static void _set_bt_tx_power(struct rtw89_dev *rtwdev, u8 level)
  1861. {
  1862. struct rtw89_btc *btc = &rtwdev->btc;
  1863. struct rtw89_btc_bt_info *bt = &btc->cx.bt;
  1864. u8 buf;
  1865. if (bt->rf_para.tx_pwr_freerun == level)
  1866. return;
  1867. bt->rf_para.tx_pwr_freerun = level;
  1868. btc->dm.rf_trx_para.bt_tx_power = level;
  1869. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  1870. "[BTC], %s(): level = %d\n",
  1871. __func__, level);
  1872. buf = (s8)(-level);
  1873. _send_fw_cmd(rtwdev, BTFC_SET, SET_BT_TX_PWR, &buf, 1);
  1874. }
  1875. #define BTC_BT_RX_NORMAL_LVL 7
  1876. static void _set_bt_rx_gain(struct rtw89_dev *rtwdev, u8 level)
  1877. {
  1878. struct rtw89_btc *btc = &rtwdev->btc;
  1879. struct rtw89_btc_bt_info *bt = &btc->cx.bt;
  1880. if (bt->rf_para.rx_gain_freerun == level ||
  1881. level > BTC_BT_RX_NORMAL_LVL)
  1882. return;
  1883. bt->rf_para.rx_gain_freerun = level;
  1884. btc->dm.rf_trx_para.bt_rx_gain = level;
  1885. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  1886. "[BTC], %s(): level = %d\n",
  1887. __func__, level);
  1888. if (level == BTC_BT_RX_NORMAL_LVL)
  1889. _write_scbd(rtwdev, BTC_WSCB_RXGAIN, false);
  1890. else
  1891. _write_scbd(rtwdev, BTC_WSCB_RXGAIN, true);
  1892. _send_fw_cmd(rtwdev, BTFC_SET, SET_BT_LNA_CONSTRAIN, &level, 1);
  1893. }
  1894. static void _set_rf_trx_para(struct rtw89_dev *rtwdev)
  1895. {
  1896. const struct rtw89_chip_info *chip = rtwdev->chip;
  1897. struct rtw89_btc *btc = &rtwdev->btc;
  1898. struct rtw89_btc_dm *dm = &btc->dm;
  1899. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  1900. struct rtw89_btc_bt_info *bt = &btc->cx.bt;
  1901. struct rtw89_btc_bt_link_info *b = &bt->link_info;
  1902. struct rtw89_btc_rf_trx_para para;
  1903. u32 wl_stb_chg = 0;
  1904. u8 level_id = 0;
  1905. if (!dm->freerun) {
  1906. /* fix LNA2 = level-5 for BT ACI issue at BTG */
  1907. if ((btc->dm.wl_btg_rx && b->profile_cnt.now != 0) ||
  1908. dm->bt_only == 1)
  1909. dm->trx_para_level = 1;
  1910. else
  1911. dm->trx_para_level = 0;
  1912. }
  1913. level_id = (u8)dm->trx_para_level;
  1914. if (level_id >= chip->rf_para_dlink_num ||
  1915. level_id >= chip->rf_para_ulink_num) {
  1916. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  1917. "[BTC], %s(): invalid level_id: %d\n",
  1918. __func__, level_id);
  1919. return;
  1920. }
  1921. if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL))
  1922. para = chip->rf_para_ulink[level_id];
  1923. else
  1924. para = chip->rf_para_dlink[level_id];
  1925. if (para.wl_tx_power != RTW89_BTC_WL_DEF_TX_PWR)
  1926. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  1927. "[BTC], %s(): wl_tx_power=%d\n",
  1928. __func__, para.wl_tx_power);
  1929. _set_wl_tx_power(rtwdev, para.wl_tx_power);
  1930. _set_wl_rx_gain(rtwdev, para.wl_rx_gain);
  1931. _set_bt_tx_power(rtwdev, para.bt_tx_power);
  1932. _set_bt_rx_gain(rtwdev, para.bt_rx_gain);
  1933. if (bt->enable.now == 0 || wl->status.map.rf_off == 1 ||
  1934. wl->status.map.lps == BTC_LPS_RF_OFF)
  1935. wl_stb_chg = 0;
  1936. else
  1937. wl_stb_chg = 1;
  1938. if (wl_stb_chg != dm->wl_stb_chg) {
  1939. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  1940. "[BTC], %s(): wl_stb_chg=%d\n",
  1941. __func__, wl_stb_chg);
  1942. dm->wl_stb_chg = wl_stb_chg;
  1943. chip->ops->btc_wl_s1_standby(rtwdev, dm->wl_stb_chg);
  1944. }
  1945. }
  1946. static void _update_btc_state_map(struct rtw89_dev *rtwdev)
  1947. {
  1948. struct rtw89_btc *btc = &rtwdev->btc;
  1949. struct rtw89_btc_cx *cx = &btc->cx;
  1950. struct rtw89_btc_wl_info *wl = &cx->wl;
  1951. struct rtw89_btc_bt_info *bt = &cx->bt;
  1952. struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info;
  1953. if (wl->status.map.connecting || wl->status.map._4way ||
  1954. wl->status.map.roaming) {
  1955. cx->state_map = BTC_WLINKING;
  1956. } else if (wl->status.map.scan) { /* wl scan */
  1957. if (bt_linfo->status.map.inq_pag)
  1958. cx->state_map = BTC_WSCAN_BSCAN;
  1959. else
  1960. cx->state_map = BTC_WSCAN_BNOSCAN;
  1961. } else if (wl->status.map.busy) { /* only busy */
  1962. if (bt_linfo->status.map.inq_pag)
  1963. cx->state_map = BTC_WBUSY_BSCAN;
  1964. else
  1965. cx->state_map = BTC_WBUSY_BNOSCAN;
  1966. } else { /* wl idle */
  1967. cx->state_map = BTC_WIDLE;
  1968. }
  1969. }
  1970. static void _set_bt_afh_info(struct rtw89_dev *rtwdev)
  1971. {
  1972. const struct rtw89_chip_info *chip = rtwdev->chip;
  1973. struct rtw89_btc *btc = &rtwdev->btc;
  1974. const struct rtw89_btc_ver *ver = btc->ver;
  1975. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  1976. struct rtw89_btc_bt_info *bt = &btc->cx.bt;
  1977. struct rtw89_btc_bt_link_info *b = &bt->link_info;
  1978. struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
  1979. struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1;
  1980. struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2;
  1981. struct rtw89_btc_wl_active_role *r;
  1982. struct rtw89_btc_wl_active_role_v1 *r1;
  1983. struct rtw89_btc_wl_active_role_v2 *r2;
  1984. u8 en = 0, i, ch = 0, bw = 0;
  1985. u8 mode, connect_cnt;
  1986. if (btc->ctrl.manual || wl->status.map.scan)
  1987. return;
  1988. if (ver->fwlrole == 0) {
  1989. mode = wl_rinfo->link_mode;
  1990. connect_cnt = wl_rinfo->connect_cnt;
  1991. } else if (ver->fwlrole == 1) {
  1992. mode = wl_rinfo_v1->link_mode;
  1993. connect_cnt = wl_rinfo_v1->connect_cnt;
  1994. } else if (ver->fwlrole == 2) {
  1995. mode = wl_rinfo_v2->link_mode;
  1996. connect_cnt = wl_rinfo_v2->connect_cnt;
  1997. } else {
  1998. return;
  1999. }
  2000. if (wl->status.map.rf_off || bt->whql_test ||
  2001. mode == BTC_WLINK_NOLINK || mode == BTC_WLINK_5G ||
  2002. connect_cnt > BTC_TDMA_WLROLE_MAX) {
  2003. en = false;
  2004. } else if (mode == BTC_WLINK_2G_MCC || mode == BTC_WLINK_2G_SCC) {
  2005. en = true;
  2006. /* get p2p channel */
  2007. for (i = 0; i < RTW89_PORT_NUM; i++) {
  2008. r = &wl_rinfo->active_role[i];
  2009. r1 = &wl_rinfo_v1->active_role_v1[i];
  2010. r2 = &wl_rinfo_v2->active_role_v2[i];
  2011. if (ver->fwlrole == 0 &&
  2012. (r->role == RTW89_WIFI_ROLE_P2P_GO ||
  2013. r->role == RTW89_WIFI_ROLE_P2P_CLIENT)) {
  2014. ch = r->ch;
  2015. bw = r->bw;
  2016. break;
  2017. } else if (ver->fwlrole == 1 &&
  2018. (r1->role == RTW89_WIFI_ROLE_P2P_GO ||
  2019. r1->role == RTW89_WIFI_ROLE_P2P_CLIENT)) {
  2020. ch = r1->ch;
  2021. bw = r1->bw;
  2022. break;
  2023. } else if (ver->fwlrole == 2 &&
  2024. (r2->role == RTW89_WIFI_ROLE_P2P_GO ||
  2025. r2->role == RTW89_WIFI_ROLE_P2P_CLIENT)) {
  2026. ch = r2->ch;
  2027. bw = r2->bw;
  2028. break;
  2029. }
  2030. }
  2031. } else {
  2032. en = true;
  2033. /* get 2g channel */
  2034. for (i = 0; i < RTW89_PORT_NUM; i++) {
  2035. r = &wl_rinfo->active_role[i];
  2036. r1 = &wl_rinfo_v1->active_role_v1[i];
  2037. r2 = &wl_rinfo_v2->active_role_v2[i];
  2038. if (ver->fwlrole == 0 &&
  2039. r->connected && r->band == RTW89_BAND_2G) {
  2040. ch = r->ch;
  2041. bw = r->bw;
  2042. break;
  2043. } else if (ver->fwlrole == 1 &&
  2044. r1->connected && r1->band == RTW89_BAND_2G) {
  2045. ch = r1->ch;
  2046. bw = r1->bw;
  2047. break;
  2048. } else if (ver->fwlrole == 2 &&
  2049. r2->connected && r2->band == RTW89_BAND_2G) {
  2050. ch = r2->ch;
  2051. bw = r2->bw;
  2052. break;
  2053. }
  2054. }
  2055. }
  2056. switch (bw) {
  2057. case RTW89_CHANNEL_WIDTH_20:
  2058. bw = 20 + chip->afh_guard_ch * 2;
  2059. break;
  2060. case RTW89_CHANNEL_WIDTH_40:
  2061. bw = 40 + chip->afh_guard_ch * 2;
  2062. break;
  2063. case RTW89_CHANNEL_WIDTH_5:
  2064. bw = 5 + chip->afh_guard_ch * 2;
  2065. break;
  2066. case RTW89_CHANNEL_WIDTH_10:
  2067. bw = 10 + chip->afh_guard_ch * 2;
  2068. break;
  2069. default:
  2070. bw = 0;
  2071. en = false; /* turn off AFH info if BW > 40 */
  2072. break;
  2073. }
  2074. if (wl->afh_info.en == en &&
  2075. wl->afh_info.ch == ch &&
  2076. wl->afh_info.bw == bw &&
  2077. b->profile_cnt.last == b->profile_cnt.now) {
  2078. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  2079. "[BTC], %s(): return because no change!\n",
  2080. __func__);
  2081. return;
  2082. }
  2083. wl->afh_info.en = en;
  2084. wl->afh_info.ch = ch;
  2085. wl->afh_info.bw = bw;
  2086. _send_fw_cmd(rtwdev, BTFC_SET, SET_BT_WL_CH_INFO, &wl->afh_info, 3);
  2087. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  2088. "[BTC], %s(): en=%d, ch=%d, bw=%d\n",
  2089. __func__, en, ch, bw);
  2090. btc->cx.cnt_wl[BTC_WCNT_CH_UPDATE]++;
  2091. }
  2092. static bool _check_freerun(struct rtw89_dev *rtwdev)
  2093. {
  2094. struct rtw89_btc *btc = &rtwdev->btc;
  2095. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  2096. struct rtw89_btc_bt_info *bt = &btc->cx.bt;
  2097. struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
  2098. struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1;
  2099. struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info;
  2100. struct rtw89_btc_bt_hid_desc *hid = &bt_linfo->hid_desc;
  2101. if (btc->mdinfo.ant.type == BTC_ANT_SHARED) {
  2102. btc->dm.trx_para_level = 0;
  2103. return false;
  2104. }
  2105. /* The below is dedicated antenna case */
  2106. if (wl_rinfo->connect_cnt > BTC_TDMA_WLROLE_MAX ||
  2107. wl_rinfo_v1->connect_cnt > BTC_TDMA_WLROLE_MAX) {
  2108. btc->dm.trx_para_level = 5;
  2109. return true;
  2110. }
  2111. if (bt_linfo->profile_cnt.now == 0) {
  2112. btc->dm.trx_para_level = 5;
  2113. return true;
  2114. }
  2115. if (hid->pair_cnt > BTC_TDMA_BTHID_MAX) {
  2116. btc->dm.trx_para_level = 5;
  2117. return true;
  2118. }
  2119. /* TODO get isolation by BT psd */
  2120. if (btc->mdinfo.ant.isolation >= BTC_FREERUN_ANTISO_MIN) {
  2121. btc->dm.trx_para_level = 5;
  2122. return true;
  2123. }
  2124. if (!wl->status.map.busy) {/* wl idle -> freerun */
  2125. btc->dm.trx_para_level = 5;
  2126. return true;
  2127. } else if (wl->rssi_level > 1) {/* WL rssi < 50% (-60dBm) */
  2128. btc->dm.trx_para_level = 0;
  2129. return false;
  2130. } else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) {
  2131. if (wl->rssi_level == 0 && bt_linfo->rssi > 31) {
  2132. btc->dm.trx_para_level = 6;
  2133. return true;
  2134. } else if (wl->rssi_level == 1 && bt_linfo->rssi > 36) {
  2135. btc->dm.trx_para_level = 7;
  2136. return true;
  2137. }
  2138. btc->dm.trx_para_level = 0;
  2139. return false;
  2140. } else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_DL)) {
  2141. if (bt_linfo->rssi > 28) {
  2142. btc->dm.trx_para_level = 6;
  2143. return true;
  2144. }
  2145. }
  2146. btc->dm.trx_para_level = 0;
  2147. return false;
  2148. }
  2149. #define _tdma_set_flctrl(btc, flc) ({(btc)->dm.tdma.rxflctrl = flc; })
  2150. #define _tdma_set_flctrl_role(btc, role) ({(btc)->dm.tdma.rxflctrl_role = role; })
  2151. #define _tdma_set_tog(btc, wtg) ({(btc)->dm.tdma.wtgle_n = wtg; })
  2152. #define _tdma_set_lek(btc, lek) ({(btc)->dm.tdma.leak_n = lek; })
  2153. #define _slot_set(btc, sid, dura, tbl, type) \
  2154. do { \
  2155. typeof(sid) _sid = (sid); \
  2156. typeof(btc) _btc = (btc); \
  2157. _btc->dm.slot[_sid].dur = cpu_to_le16(dura);\
  2158. _btc->dm.slot[_sid].cxtbl = cpu_to_le32(tbl); \
  2159. _btc->dm.slot[_sid].cxtype = cpu_to_le16(type); \
  2160. } while (0)
  2161. #define _slot_set_dur(btc, sid, dura) (btc)->dm.slot[sid].dur = cpu_to_le16(dura)
  2162. #define _slot_set_tbl(btc, sid, tbl) (btc)->dm.slot[sid].cxtbl = cpu_to_le32(tbl)
  2163. #define _slot_set_type(btc, sid, type) (btc)->dm.slot[sid].cxtype = cpu_to_le16(type)
  2164. struct btc_btinfo_lb2 {
  2165. u8 connect: 1;
  2166. u8 sco_busy: 1;
  2167. u8 inq_pag: 1;
  2168. u8 acl_busy: 1;
  2169. u8 hfp: 1;
  2170. u8 hid: 1;
  2171. u8 a2dp: 1;
  2172. u8 pan: 1;
  2173. };
  2174. struct btc_btinfo_lb3 {
  2175. u8 retry: 4;
  2176. u8 cqddr: 1;
  2177. u8 inq: 1;
  2178. u8 mesh_busy: 1;
  2179. u8 pag: 1;
  2180. };
  2181. struct btc_btinfo_hb0 {
  2182. s8 rssi;
  2183. };
  2184. struct btc_btinfo_hb1 {
  2185. u8 ble_connect: 1;
  2186. u8 reinit: 1;
  2187. u8 relink: 1;
  2188. u8 igno_wl: 1;
  2189. u8 voice: 1;
  2190. u8 ble_scan: 1;
  2191. u8 role_sw: 1;
  2192. u8 multi_link: 1;
  2193. };
  2194. struct btc_btinfo_hb2 {
  2195. u8 pan_active: 1;
  2196. u8 afh_update: 1;
  2197. u8 a2dp_active: 1;
  2198. u8 slave: 1;
  2199. u8 hid_slot: 2;
  2200. u8 hid_cnt: 2;
  2201. };
  2202. struct btc_btinfo_hb3 {
  2203. u8 a2dp_bitpool: 6;
  2204. u8 tx_3m: 1;
  2205. u8 a2dp_sink: 1;
  2206. };
  2207. union btc_btinfo {
  2208. u8 val;
  2209. struct btc_btinfo_lb2 lb2;
  2210. struct btc_btinfo_lb3 lb3;
  2211. struct btc_btinfo_hb0 hb0;
  2212. struct btc_btinfo_hb1 hb1;
  2213. struct btc_btinfo_hb2 hb2;
  2214. struct btc_btinfo_hb3 hb3;
  2215. };
  2216. static void _set_policy(struct rtw89_dev *rtwdev, u16 policy_type,
  2217. enum btc_reason_and_action action)
  2218. {
  2219. const struct rtw89_chip_info *chip = rtwdev->chip;
  2220. chip->ops->btc_set_policy(rtwdev, policy_type);
  2221. _fw_set_policy(rtwdev, policy_type, action);
  2222. }
  2223. #define BTC_B1_MAX 250 /* unit ms */
  2224. void rtw89_btc_set_policy(struct rtw89_dev *rtwdev, u16 policy_type)
  2225. {
  2226. struct rtw89_btc *btc = &rtwdev->btc;
  2227. struct rtw89_btc_dm *dm = &btc->dm;
  2228. struct rtw89_btc_fbtc_tdma *t = &dm->tdma;
  2229. struct rtw89_btc_fbtc_slot *s = dm->slot;
  2230. u8 type;
  2231. u32 tbl_w1, tbl_b1, tbl_b4;
  2232. if (btc->mdinfo.ant.type == BTC_ANT_SHARED) {
  2233. if (btc->cx.wl.status.map._4way)
  2234. tbl_w1 = cxtbl[1];
  2235. else
  2236. tbl_w1 = cxtbl[8];
  2237. tbl_b1 = cxtbl[3];
  2238. tbl_b4 = cxtbl[3];
  2239. } else {
  2240. tbl_w1 = cxtbl[16];
  2241. tbl_b1 = cxtbl[17];
  2242. tbl_b4 = cxtbl[17];
  2243. }
  2244. type = (u8)((policy_type & BTC_CXP_MASK) >> 8);
  2245. btc->bt_req_en = false;
  2246. switch (type) {
  2247. case BTC_CXP_USERDEF0:
  2248. *t = t_def[CXTD_OFF];
  2249. s[CXST_OFF] = s_def[CXST_OFF];
  2250. _slot_set_tbl(btc, CXST_OFF, cxtbl[2]);
  2251. btc->update_policy_force = true;
  2252. break;
  2253. case BTC_CXP_OFF: /* TDMA off */
  2254. _write_scbd(rtwdev, BTC_WSCB_TDMA, false);
  2255. *t = t_def[CXTD_OFF];
  2256. s[CXST_OFF] = s_def[CXST_OFF];
  2257. switch (policy_type) {
  2258. case BTC_CXP_OFF_BT:
  2259. _slot_set_tbl(btc, CXST_OFF, cxtbl[2]);
  2260. break;
  2261. case BTC_CXP_OFF_WL:
  2262. _slot_set_tbl(btc, CXST_OFF, cxtbl[1]);
  2263. break;
  2264. case BTC_CXP_OFF_EQ0:
  2265. _slot_set_tbl(btc, CXST_OFF, cxtbl[0]);
  2266. break;
  2267. case BTC_CXP_OFF_EQ1:
  2268. _slot_set_tbl(btc, CXST_OFF, cxtbl[16]);
  2269. break;
  2270. case BTC_CXP_OFF_EQ2:
  2271. _slot_set_tbl(btc, CXST_OFF, cxtbl[17]);
  2272. break;
  2273. case BTC_CXP_OFF_EQ3:
  2274. _slot_set_tbl(btc, CXST_OFF, cxtbl[18]);
  2275. break;
  2276. case BTC_CXP_OFF_BWB0:
  2277. _slot_set_tbl(btc, CXST_OFF, cxtbl[5]);
  2278. break;
  2279. case BTC_CXP_OFF_BWB1:
  2280. _slot_set_tbl(btc, CXST_OFF, cxtbl[8]);
  2281. break;
  2282. case BTC_CXP_OFF_BWB3:
  2283. _slot_set_tbl(btc, CXST_OFF, cxtbl[6]);
  2284. break;
  2285. }
  2286. break;
  2287. case BTC_CXP_OFFB: /* TDMA off + beacon protect */
  2288. _write_scbd(rtwdev, BTC_WSCB_TDMA, false);
  2289. *t = t_def[CXTD_OFF_B2];
  2290. s[CXST_OFF] = s_def[CXST_OFF];
  2291. switch (policy_type) {
  2292. case BTC_CXP_OFFB_BWB0:
  2293. _slot_set_tbl(btc, CXST_OFF, cxtbl[8]);
  2294. break;
  2295. }
  2296. break;
  2297. case BTC_CXP_OFFE: /* TDMA off + beacon protect + Ext_control */
  2298. btc->bt_req_en = true;
  2299. _write_scbd(rtwdev, BTC_WSCB_TDMA, true);
  2300. *t = t_def[CXTD_OFF_EXT];
  2301. switch (policy_type) {
  2302. case BTC_CXP_OFFE_DEF:
  2303. s[CXST_E2G] = s_def[CXST_E2G];
  2304. s[CXST_E5G] = s_def[CXST_E5G];
  2305. s[CXST_EBT] = s_def[CXST_EBT];
  2306. s[CXST_ENULL] = s_def[CXST_ENULL];
  2307. break;
  2308. case BTC_CXP_OFFE_DEF2:
  2309. _slot_set(btc, CXST_E2G, 20, cxtbl[1], SLOT_ISO);
  2310. s[CXST_E5G] = s_def[CXST_E5G];
  2311. s[CXST_EBT] = s_def[CXST_EBT];
  2312. s[CXST_ENULL] = s_def[CXST_ENULL];
  2313. break;
  2314. }
  2315. break;
  2316. case BTC_CXP_FIX: /* TDMA Fix-Slot */
  2317. _write_scbd(rtwdev, BTC_WSCB_TDMA, true);
  2318. *t = t_def[CXTD_FIX];
  2319. switch (policy_type) {
  2320. case BTC_CXP_FIX_TD3030:
  2321. _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO);
  2322. _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX);
  2323. break;
  2324. case BTC_CXP_FIX_TD5050:
  2325. _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO);
  2326. _slot_set(btc, CXST_B1, 50, tbl_b1, SLOT_MIX);
  2327. break;
  2328. case BTC_CXP_FIX_TD2030:
  2329. _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO);
  2330. _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX);
  2331. break;
  2332. case BTC_CXP_FIX_TD4010:
  2333. _slot_set(btc, CXST_W1, 40, tbl_w1, SLOT_ISO);
  2334. _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX);
  2335. break;
  2336. case BTC_CXP_FIX_TD4020:
  2337. _slot_set(btc, CXST_W1, 40, cxtbl[1], SLOT_MIX);
  2338. _slot_set(btc, CXST_B1, 20, tbl_b1, SLOT_MIX);
  2339. break;
  2340. case BTC_CXP_FIX_TD7010:
  2341. _slot_set(btc, CXST_W1, 70, tbl_w1, SLOT_ISO);
  2342. _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX);
  2343. break;
  2344. case BTC_CXP_FIX_TD2060:
  2345. _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO);
  2346. _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX);
  2347. break;
  2348. case BTC_CXP_FIX_TD3060:
  2349. _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO);
  2350. _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX);
  2351. break;
  2352. case BTC_CXP_FIX_TD2080:
  2353. _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO);
  2354. _slot_set(btc, CXST_B1, 80, tbl_b1, SLOT_MIX);
  2355. break;
  2356. case BTC_CXP_FIX_TDW1B1: /* W1:B1 = user-define */
  2357. _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1],
  2358. tbl_w1, SLOT_ISO);
  2359. _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1],
  2360. tbl_b1, SLOT_MIX);
  2361. break;
  2362. }
  2363. break;
  2364. case BTC_CXP_PFIX: /* PS-TDMA Fix-Slot */
  2365. _write_scbd(rtwdev, BTC_WSCB_TDMA, true);
  2366. *t = t_def[CXTD_PFIX];
  2367. if (btc->cx.wl.role_info.role_map.role.ap)
  2368. _tdma_set_flctrl(btc, CXFLC_QOSNULL);
  2369. switch (policy_type) {
  2370. case BTC_CXP_PFIX_TD3030:
  2371. _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO);
  2372. _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX);
  2373. break;
  2374. case BTC_CXP_PFIX_TD5050:
  2375. _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO);
  2376. _slot_set(btc, CXST_B1, 50, tbl_b1, SLOT_MIX);
  2377. break;
  2378. case BTC_CXP_PFIX_TD2030:
  2379. _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO);
  2380. _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX);
  2381. break;
  2382. case BTC_CXP_PFIX_TD2060:
  2383. _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO);
  2384. _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX);
  2385. break;
  2386. case BTC_CXP_PFIX_TD3070:
  2387. _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO);
  2388. _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX);
  2389. break;
  2390. case BTC_CXP_PFIX_TD2080:
  2391. _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO);
  2392. _slot_set(btc, CXST_B1, 80, tbl_b1, SLOT_MIX);
  2393. break;
  2394. }
  2395. break;
  2396. case BTC_CXP_AUTO: /* TDMA Auto-Slot */
  2397. _write_scbd(rtwdev, BTC_WSCB_TDMA, true);
  2398. *t = t_def[CXTD_AUTO];
  2399. switch (policy_type) {
  2400. case BTC_CXP_AUTO_TD50B1:
  2401. _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO);
  2402. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2403. break;
  2404. case BTC_CXP_AUTO_TD60B1:
  2405. _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO);
  2406. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2407. break;
  2408. case BTC_CXP_AUTO_TD20B1:
  2409. _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO);
  2410. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2411. break;
  2412. case BTC_CXP_AUTO_TDW1B1: /* W1:B1 = user-define */
  2413. _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1],
  2414. tbl_w1, SLOT_ISO);
  2415. _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1],
  2416. tbl_b1, SLOT_MIX);
  2417. break;
  2418. }
  2419. break;
  2420. case BTC_CXP_PAUTO: /* PS-TDMA Auto-Slot */
  2421. _write_scbd(rtwdev, BTC_WSCB_TDMA, true);
  2422. *t = t_def[CXTD_PAUTO];
  2423. switch (policy_type) {
  2424. case BTC_CXP_PAUTO_TD50B1:
  2425. _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO);
  2426. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2427. break;
  2428. case BTC_CXP_PAUTO_TD60B1:
  2429. _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO);
  2430. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2431. break;
  2432. case BTC_CXP_PAUTO_TD20B1:
  2433. _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO);
  2434. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2435. break;
  2436. case BTC_CXP_PAUTO_TDW1B1:
  2437. _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1],
  2438. tbl_w1, SLOT_ISO);
  2439. _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1],
  2440. tbl_b1, SLOT_MIX);
  2441. break;
  2442. }
  2443. break;
  2444. case BTC_CXP_AUTO2: /* TDMA Auto-Slot2 */
  2445. _write_scbd(rtwdev, BTC_WSCB_TDMA, true);
  2446. *t = t_def[CXTD_AUTO2];
  2447. switch (policy_type) {
  2448. case BTC_CXP_AUTO2_TD3050:
  2449. _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO);
  2450. _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX);
  2451. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2452. break;
  2453. case BTC_CXP_AUTO2_TD3070:
  2454. _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO);
  2455. _slot_set(btc, CXST_B4, 70, tbl_b4, SLOT_MIX);
  2456. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2457. break;
  2458. case BTC_CXP_AUTO2_TD5050:
  2459. _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO);
  2460. _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX);
  2461. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2462. break;
  2463. case BTC_CXP_AUTO2_TD6060:
  2464. _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO);
  2465. _slot_set(btc, CXST_B4, 60, tbl_b4, SLOT_MIX);
  2466. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2467. break;
  2468. case BTC_CXP_AUTO2_TD2080:
  2469. _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO);
  2470. _slot_set(btc, CXST_B4, 80, tbl_b4, SLOT_MIX);
  2471. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2472. break;
  2473. case BTC_CXP_AUTO2_TDW1B4: /* W1:B1 = user-define */
  2474. _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1],
  2475. tbl_w1, SLOT_ISO);
  2476. _slot_set(btc, CXST_B4, dm->slot_dur[CXST_B4],
  2477. tbl_b4, SLOT_MIX);
  2478. break;
  2479. }
  2480. break;
  2481. case BTC_CXP_PAUTO2: /* PS-TDMA Auto-Slot2 */
  2482. _write_scbd(rtwdev, BTC_WSCB_TDMA, true);
  2483. *t = t_def[CXTD_PAUTO2];
  2484. switch (policy_type) {
  2485. case BTC_CXP_PAUTO2_TD3050:
  2486. _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO);
  2487. _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX);
  2488. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2489. break;
  2490. case BTC_CXP_PAUTO2_TD3070:
  2491. _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO);
  2492. _slot_set(btc, CXST_B4, 70, tbl_b4, SLOT_MIX);
  2493. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2494. break;
  2495. case BTC_CXP_PAUTO2_TD5050:
  2496. _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO);
  2497. _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX);
  2498. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2499. break;
  2500. case BTC_CXP_PAUTO2_TD6060:
  2501. _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO);
  2502. _slot_set(btc, CXST_B4, 60, tbl_b4, SLOT_MIX);
  2503. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2504. break;
  2505. case BTC_CXP_PAUTO2_TD2080:
  2506. _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO);
  2507. _slot_set(btc, CXST_B4, 80, tbl_b4, SLOT_MIX);
  2508. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2509. break;
  2510. case BTC_CXP_PAUTO2_TDW1B4: /* W1:B1 = user-define */
  2511. _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1],
  2512. tbl_w1, SLOT_ISO);
  2513. _slot_set(btc, CXST_B4, dm->slot_dur[CXST_B4],
  2514. tbl_b4, SLOT_MIX);
  2515. break;
  2516. }
  2517. break;
  2518. }
  2519. }
  2520. EXPORT_SYMBOL(rtw89_btc_set_policy);
  2521. void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
  2522. {
  2523. struct rtw89_btc *btc = &rtwdev->btc;
  2524. struct rtw89_btc_dm *dm = &btc->dm;
  2525. struct rtw89_btc_fbtc_tdma *t = &dm->tdma;
  2526. struct rtw89_btc_fbtc_slot *s = dm->slot;
  2527. struct rtw89_btc_wl_role_info_v1 *wl_rinfo = &btc->cx.wl.role_info_v1;
  2528. struct rtw89_btc_bt_hid_desc *hid = &btc->cx.bt.link_info.hid_desc;
  2529. struct rtw89_btc_bt_hfp_desc *hfp = &btc->cx.bt.link_info.hfp_desc;
  2530. u8 type, null_role;
  2531. u32 tbl_w1, tbl_b1, tbl_b4;
  2532. type = FIELD_GET(BTC_CXP_MASK, policy_type);
  2533. if (btc->mdinfo.ant.type == BTC_ANT_SHARED) {
  2534. if (btc->cx.wl.status.map._4way)
  2535. tbl_w1 = cxtbl[1];
  2536. else if (hid->exist && hid->type == BTC_HID_218)
  2537. tbl_w1 = cxtbl[7]; /* Ack/BA no break bt Hi-Pri-rx */
  2538. else
  2539. tbl_w1 = cxtbl[8];
  2540. if (dm->leak_ap &&
  2541. (type == BTC_CXP_PFIX || type == BTC_CXP_PAUTO2)) {
  2542. tbl_b1 = cxtbl[3];
  2543. tbl_b4 = cxtbl[3];
  2544. } else if (hid->exist && hid->type == BTC_HID_218) {
  2545. tbl_b1 = cxtbl[4]; /* Ack/BA no break bt Hi-Pri-rx */
  2546. tbl_b4 = cxtbl[4];
  2547. } else {
  2548. tbl_b1 = cxtbl[2];
  2549. tbl_b4 = cxtbl[2];
  2550. }
  2551. } else {
  2552. tbl_w1 = cxtbl[16];
  2553. tbl_b1 = cxtbl[17];
  2554. tbl_b4 = cxtbl[17];
  2555. }
  2556. btc->bt_req_en = false;
  2557. switch (type) {
  2558. case BTC_CXP_USERDEF0:
  2559. btc->update_policy_force = true;
  2560. *t = t_def[CXTD_OFF];
  2561. s[CXST_OFF] = s_def[CXST_OFF];
  2562. _slot_set_tbl(btc, CXST_OFF, cxtbl[2]);
  2563. break;
  2564. case BTC_CXP_OFF: /* TDMA off */
  2565. _write_scbd(rtwdev, BTC_WSCB_TDMA, false);
  2566. *t = t_def[CXTD_OFF];
  2567. s[CXST_OFF] = s_def[CXST_OFF];
  2568. switch (policy_type) {
  2569. case BTC_CXP_OFF_BT:
  2570. _slot_set_tbl(btc, CXST_OFF, cxtbl[2]);
  2571. break;
  2572. case BTC_CXP_OFF_WL:
  2573. _slot_set_tbl(btc, CXST_OFF, cxtbl[1]);
  2574. break;
  2575. case BTC_CXP_OFF_EQ0:
  2576. _slot_set_tbl(btc, CXST_OFF, cxtbl[0]);
  2577. _slot_set_type(btc, CXST_OFF, SLOT_ISO);
  2578. break;
  2579. case BTC_CXP_OFF_EQ1:
  2580. _slot_set_tbl(btc, CXST_OFF, cxtbl[16]);
  2581. break;
  2582. case BTC_CXP_OFF_EQ2:
  2583. _slot_set_tbl(btc, CXST_OFF, cxtbl[0]);
  2584. break;
  2585. case BTC_CXP_OFF_EQ3:
  2586. _slot_set_tbl(btc, CXST_OFF, cxtbl[24]);
  2587. break;
  2588. case BTC_CXP_OFF_BWB0:
  2589. _slot_set_tbl(btc, CXST_OFF, cxtbl[5]);
  2590. break;
  2591. case BTC_CXP_OFF_BWB1:
  2592. _slot_set_tbl(btc, CXST_OFF, cxtbl[8]);
  2593. break;
  2594. case BTC_CXP_OFF_BWB2:
  2595. _slot_set_tbl(btc, CXST_OFF, cxtbl[7]);
  2596. break;
  2597. case BTC_CXP_OFF_BWB3:
  2598. _slot_set_tbl(btc, CXST_OFF, cxtbl[6]);
  2599. break;
  2600. default:
  2601. break;
  2602. }
  2603. break;
  2604. case BTC_CXP_OFFB: /* TDMA off + beacon protect */
  2605. _write_scbd(rtwdev, BTC_WSCB_TDMA, false);
  2606. *t = t_def[CXTD_OFF_B2];
  2607. s[CXST_OFF] = s_def[CXST_OFF];
  2608. switch (policy_type) {
  2609. case BTC_CXP_OFFB_BWB0:
  2610. _slot_set_tbl(btc, CXST_OFF, cxtbl[8]);
  2611. break;
  2612. default:
  2613. break;
  2614. }
  2615. break;
  2616. case BTC_CXP_OFFE: /* TDMA off + beacon protect + Ext_control */
  2617. btc->bt_req_en = true;
  2618. _write_scbd(rtwdev, BTC_WSCB_TDMA, true);
  2619. *t = t_def[CXTD_OFF_EXT];
  2620. /* To avoid wl-s0 tx break by hid/hfp tx */
  2621. if (hid->exist || hfp->exist)
  2622. tbl_w1 = cxtbl[16];
  2623. switch (policy_type) {
  2624. case BTC_CXP_OFFE_DEF:
  2625. s[CXST_E2G] = s_def[CXST_E2G];
  2626. s[CXST_E5G] = s_def[CXST_E5G];
  2627. s[CXST_EBT] = s_def[CXST_EBT];
  2628. s[CXST_ENULL] = s_def[CXST_ENULL];
  2629. break;
  2630. case BTC_CXP_OFFE_DEF2:
  2631. _slot_set(btc, CXST_E2G, 20, cxtbl[1], SLOT_ISO);
  2632. s[CXST_E5G] = s_def[CXST_E5G];
  2633. s[CXST_EBT] = s_def[CXST_EBT];
  2634. s[CXST_ENULL] = s_def[CXST_ENULL];
  2635. break;
  2636. default:
  2637. break;
  2638. }
  2639. s[CXST_OFF] = s_def[CXST_OFF];
  2640. break;
  2641. case BTC_CXP_FIX: /* TDMA Fix-Slot */
  2642. _write_scbd(rtwdev, BTC_WSCB_TDMA, true);
  2643. *t = t_def[CXTD_FIX];
  2644. switch (policy_type) {
  2645. case BTC_CXP_FIX_TD3030:
  2646. _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO);
  2647. _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX);
  2648. break;
  2649. case BTC_CXP_FIX_TD5050:
  2650. _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO);
  2651. _slot_set(btc, CXST_B1, 50, tbl_b1, SLOT_MIX);
  2652. break;
  2653. case BTC_CXP_FIX_TD2030:
  2654. _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO);
  2655. _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX);
  2656. break;
  2657. case BTC_CXP_FIX_TD4010:
  2658. _slot_set(btc, CXST_W1, 40, tbl_w1, SLOT_ISO);
  2659. _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX);
  2660. break;
  2661. case BTC_CXP_FIX_TD4010ISO:
  2662. _slot_set(btc, CXST_W1, 40, cxtbl[1], SLOT_ISO);
  2663. _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX);
  2664. break;
  2665. case BTC_CXP_FIX_TD4020:
  2666. _slot_set(btc, CXST_W1, 40, cxtbl[1], SLOT_MIX);
  2667. _slot_set(btc, CXST_B1, 20, tbl_b1, SLOT_MIX);
  2668. break;
  2669. case BTC_CXP_FIX_TD7010:
  2670. _slot_set(btc, CXST_W1, 70, tbl_w1, SLOT_ISO);
  2671. _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX);
  2672. break;
  2673. case BTC_CXP_FIX_TD2060:
  2674. _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO);
  2675. _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX);
  2676. break;
  2677. case BTC_CXP_FIX_TD3060:
  2678. _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO);
  2679. _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX);
  2680. break;
  2681. case BTC_CXP_FIX_TD2080:
  2682. _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO);
  2683. _slot_set(btc, CXST_B1, 80, tbl_b1, SLOT_MIX);
  2684. break;
  2685. case BTC_CXP_FIX_TDW1B1: /* W1:B1 = user-define */
  2686. _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1],
  2687. tbl_w1, SLOT_ISO);
  2688. _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1],
  2689. tbl_b1, SLOT_MIX);
  2690. break;
  2691. default:
  2692. break;
  2693. }
  2694. break;
  2695. case BTC_CXP_PFIX: /* PS-TDMA Fix-Slot */
  2696. _write_scbd(rtwdev, BTC_WSCB_TDMA, true);
  2697. *t = t_def[CXTD_PFIX];
  2698. switch (policy_type) {
  2699. case BTC_CXP_PFIX_TD3030:
  2700. _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO);
  2701. _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX);
  2702. break;
  2703. case BTC_CXP_PFIX_TD5050:
  2704. _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO);
  2705. _slot_set(btc, CXST_B1, 50, tbl_b1, SLOT_MIX);
  2706. break;
  2707. case BTC_CXP_PFIX_TD2030:
  2708. _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO);
  2709. _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX);
  2710. break;
  2711. case BTC_CXP_PFIX_TD2060:
  2712. _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO);
  2713. _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX);
  2714. break;
  2715. case BTC_CXP_PFIX_TD3070:
  2716. _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO);
  2717. _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX);
  2718. break;
  2719. case BTC_CXP_PFIX_TD2080:
  2720. _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO);
  2721. _slot_set(btc, CXST_B1, 80, tbl_b1, SLOT_MIX);
  2722. break;
  2723. case BTC_CXP_PFIX_TDW1B1: /* W1:B1 = user-define */
  2724. _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1],
  2725. tbl_w1, SLOT_ISO);
  2726. _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1],
  2727. tbl_b1, SLOT_MIX);
  2728. break;
  2729. default:
  2730. break;
  2731. }
  2732. break;
  2733. case BTC_CXP_AUTO: /* TDMA Auto-Slot */
  2734. _write_scbd(rtwdev, BTC_WSCB_TDMA, true);
  2735. *t = t_def[CXTD_AUTO];
  2736. switch (policy_type) {
  2737. case BTC_CXP_AUTO_TD50B1:
  2738. _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO);
  2739. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2740. break;
  2741. case BTC_CXP_AUTO_TD60B1:
  2742. _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO);
  2743. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2744. break;
  2745. case BTC_CXP_AUTO_TD20B1:
  2746. _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO);
  2747. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2748. break;
  2749. case BTC_CXP_AUTO_TDW1B1: /* W1:B1 = user-define */
  2750. _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1],
  2751. tbl_w1, SLOT_ISO);
  2752. _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1],
  2753. tbl_b1, SLOT_MIX);
  2754. break;
  2755. default:
  2756. break;
  2757. }
  2758. break;
  2759. case BTC_CXP_PAUTO: /* PS-TDMA Auto-Slot */
  2760. _write_scbd(rtwdev, BTC_WSCB_TDMA, true);
  2761. *t = t_def[CXTD_PAUTO];
  2762. switch (policy_type) {
  2763. case BTC_CXP_PAUTO_TD50B1:
  2764. _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO);
  2765. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2766. break;
  2767. case BTC_CXP_PAUTO_TD60B1:
  2768. _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO);
  2769. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2770. break;
  2771. case BTC_CXP_PAUTO_TD20B1:
  2772. _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO);
  2773. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2774. break;
  2775. case BTC_CXP_PAUTO_TDW1B1:
  2776. _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1],
  2777. tbl_w1, SLOT_ISO);
  2778. _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1],
  2779. tbl_b1, SLOT_MIX);
  2780. break;
  2781. default:
  2782. break;
  2783. }
  2784. break;
  2785. case BTC_CXP_AUTO2: /* TDMA Auto-Slot2 */
  2786. _write_scbd(rtwdev, BTC_WSCB_TDMA, true);
  2787. *t = t_def[CXTD_AUTO2];
  2788. switch (policy_type) {
  2789. case BTC_CXP_AUTO2_TD3050:
  2790. _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO);
  2791. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2792. _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX);
  2793. break;
  2794. case BTC_CXP_AUTO2_TD3070:
  2795. _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO);
  2796. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2797. _slot_set(btc, CXST_B4, 70, tbl_b4, SLOT_MIX);
  2798. break;
  2799. case BTC_CXP_AUTO2_TD5050:
  2800. _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO);
  2801. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2802. _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX);
  2803. break;
  2804. case BTC_CXP_AUTO2_TD6060:
  2805. _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO);
  2806. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2807. _slot_set(btc, CXST_B4, 60, tbl_b4, SLOT_MIX);
  2808. break;
  2809. case BTC_CXP_AUTO2_TD2080:
  2810. _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO);
  2811. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2812. _slot_set(btc, CXST_B4, 80, tbl_b4, SLOT_MIX);
  2813. break;
  2814. case BTC_CXP_AUTO2_TDW1B4: /* W1:B1 = user-define */
  2815. _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1],
  2816. tbl_w1, SLOT_ISO);
  2817. _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1],
  2818. tbl_b1, SLOT_MIX);
  2819. _slot_set(btc, CXST_B4, dm->slot_dur[CXST_B4],
  2820. tbl_b4, SLOT_MIX);
  2821. break;
  2822. default:
  2823. break;
  2824. }
  2825. break;
  2826. case BTC_CXP_PAUTO2: /* PS-TDMA Auto-Slot2 */
  2827. _write_scbd(rtwdev, BTC_WSCB_TDMA, true);
  2828. *t = t_def[CXTD_PAUTO2];
  2829. switch (policy_type) {
  2830. case BTC_CXP_PAUTO2_TD3050:
  2831. _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO);
  2832. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2833. _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX);
  2834. break;
  2835. case BTC_CXP_PAUTO2_TD3070:
  2836. _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO);
  2837. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2838. _slot_set(btc, CXST_B4, 70, tbl_b4, SLOT_MIX);
  2839. break;
  2840. case BTC_CXP_PAUTO2_TD5050:
  2841. _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO);
  2842. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2843. _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX);
  2844. break;
  2845. case BTC_CXP_PAUTO2_TD6060:
  2846. _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO);
  2847. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2848. _slot_set(btc, CXST_B4, 60, tbl_b4, SLOT_MIX);
  2849. break;
  2850. case BTC_CXP_PAUTO2_TD2080:
  2851. _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO);
  2852. _slot_set(btc, CXST_B1, BTC_B1_MAX, tbl_b1, SLOT_MIX);
  2853. _slot_set(btc, CXST_B4, 80, tbl_b4, SLOT_MIX);
  2854. break;
  2855. case BTC_CXP_PAUTO2_TDW1B4: /* W1:B1 = user-define */
  2856. _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1],
  2857. tbl_w1, SLOT_ISO);
  2858. _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1],
  2859. tbl_b1, SLOT_MIX);
  2860. _slot_set(btc, CXST_B4, dm->slot_dur[CXST_B4],
  2861. tbl_b4, SLOT_MIX);
  2862. break;
  2863. default:
  2864. break;
  2865. }
  2866. break;
  2867. }
  2868. if (wl_rinfo->link_mode == BTC_WLINK_2G_SCC && dm->tdma.rxflctrl) {
  2869. null_role = FIELD_PREP(0x0f, dm->wl_scc.null_role1) |
  2870. FIELD_PREP(0xf0, dm->wl_scc.null_role2);
  2871. _tdma_set_flctrl_role(btc, null_role);
  2872. }
  2873. /* enter leak_slot after each null-1 */
  2874. if (dm->leak_ap && dm->tdma.leak_n > 1)
  2875. _tdma_set_lek(btc, 1);
  2876. if (dm->tdma_instant_excute) {
  2877. btc->dm.tdma.option_ctrl |= BIT(0);
  2878. btc->update_policy_force = true;
  2879. }
  2880. }
  2881. EXPORT_SYMBOL(rtw89_btc_set_policy_v1);
  2882. static void _set_bt_plut(struct rtw89_dev *rtwdev, u8 phy_map,
  2883. u8 tx_val, u8 rx_val)
  2884. {
  2885. struct rtw89_mac_ax_plt plt;
  2886. plt.band = RTW89_MAC_0;
  2887. plt.tx = tx_val;
  2888. plt.rx = rx_val;
  2889. if (phy_map & BTC_PHY_0)
  2890. rtw89_mac_cfg_plt(rtwdev, &plt);
  2891. if (!rtwdev->dbcc_en)
  2892. return;
  2893. plt.band = RTW89_MAC_1;
  2894. if (phy_map & BTC_PHY_1)
  2895. rtw89_mac_cfg_plt(rtwdev, &plt);
  2896. }
  2897. static void _set_ant(struct rtw89_dev *rtwdev, bool force_exec,
  2898. u8 phy_map, u8 type)
  2899. {
  2900. struct rtw89_btc *btc = &rtwdev->btc;
  2901. struct rtw89_btc_dm *dm = &btc->dm;
  2902. struct rtw89_btc_cx *cx = &btc->cx;
  2903. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  2904. struct rtw89_btc_bt_info *bt = &cx->bt;
  2905. struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
  2906. u8 gnt_wl_ctrl, gnt_bt_ctrl, plt_ctrl, i, b2g = 0;
  2907. u32 ant_path_type;
  2908. ant_path_type = ((phy_map << 8) + type);
  2909. if (btc->dm.run_reason == BTC_RSN_NTFY_POWEROFF ||
  2910. btc->dm.run_reason == BTC_RSN_NTFY_RADIO_STATE ||
  2911. btc->dm.run_reason == BTC_RSN_CMD_SET_COEX)
  2912. force_exec = FC_EXEC;
  2913. if (!force_exec && ant_path_type == dm->set_ant_path) {
  2914. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  2915. "[BTC], %s(): return by no change!!\n",
  2916. __func__);
  2917. return;
  2918. } else if (bt->rfk_info.map.run) {
  2919. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  2920. "[BTC], %s(): return by bt rfk!!\n", __func__);
  2921. return;
  2922. } else if (btc->dm.run_reason != BTC_RSN_NTFY_WL_RFK &&
  2923. wl->rfk_info.state != BTC_WRFK_STOP) {
  2924. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  2925. "[BTC], %s(): return by wl rfk!!\n", __func__);
  2926. return;
  2927. }
  2928. dm->set_ant_path = ant_path_type;
  2929. rtw89_debug(rtwdev,
  2930. RTW89_DBG_BTC,
  2931. "[BTC], %s(): path=0x%x, set_type=0x%x\n",
  2932. __func__, phy_map, dm->set_ant_path & 0xff);
  2933. switch (type) {
  2934. case BTC_ANT_WPOWERON:
  2935. rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_BT);
  2936. break;
  2937. case BTC_ANT_WINIT:
  2938. if (bt->enable.now)
  2939. _set_gnt(rtwdev, phy_map, BTC_GNT_SW_LO, BTC_GNT_SW_HI);
  2940. else
  2941. _set_gnt(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO);
  2942. rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL);
  2943. _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_BT, BTC_PLT_BT);
  2944. break;
  2945. case BTC_ANT_WONLY:
  2946. _set_gnt(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO);
  2947. rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL);
  2948. _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_NONE, BTC_PLT_NONE);
  2949. break;
  2950. case BTC_ANT_WOFF:
  2951. rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_BT);
  2952. _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_NONE, BTC_PLT_NONE);
  2953. break;
  2954. case BTC_ANT_W2G:
  2955. rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL);
  2956. if (rtwdev->dbcc_en) {
  2957. for (i = 0; i < RTW89_PHY_MAX; i++) {
  2958. b2g = (wl_dinfo->real_band[i] == RTW89_BAND_2G);
  2959. gnt_wl_ctrl = b2g ? BTC_GNT_HW : BTC_GNT_SW_HI;
  2960. gnt_bt_ctrl = b2g ? BTC_GNT_HW : BTC_GNT_SW_HI;
  2961. /* BT should control by GNT_BT if WL_2G at S0 */
  2962. if (i == 1 &&
  2963. wl_dinfo->real_band[0] == RTW89_BAND_2G &&
  2964. wl_dinfo->real_band[1] == RTW89_BAND_5G)
  2965. gnt_bt_ctrl = BTC_GNT_HW;
  2966. _set_gnt(rtwdev, BIT(i), gnt_wl_ctrl, gnt_bt_ctrl);
  2967. plt_ctrl = b2g ? BTC_PLT_BT : BTC_PLT_NONE;
  2968. _set_bt_plut(rtwdev, BIT(i),
  2969. plt_ctrl, plt_ctrl);
  2970. }
  2971. } else {
  2972. _set_gnt(rtwdev, phy_map, BTC_GNT_HW, BTC_GNT_HW);
  2973. _set_bt_plut(rtwdev, BTC_PHY_ALL,
  2974. BTC_PLT_BT, BTC_PLT_BT);
  2975. }
  2976. break;
  2977. case BTC_ANT_W5G:
  2978. rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL);
  2979. _set_gnt(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_HW);
  2980. _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_NONE, BTC_PLT_NONE);
  2981. break;
  2982. case BTC_ANT_W25G:
  2983. rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL);
  2984. _set_gnt(rtwdev, phy_map, BTC_GNT_HW, BTC_GNT_HW);
  2985. _set_bt_plut(rtwdev, BTC_PHY_ALL,
  2986. BTC_PLT_GNT_WL, BTC_PLT_GNT_WL);
  2987. break;
  2988. case BTC_ANT_FREERUN:
  2989. rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL);
  2990. _set_gnt(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_HI);
  2991. _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_NONE, BTC_PLT_NONE);
  2992. break;
  2993. case BTC_ANT_WRFK:
  2994. rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL);
  2995. _set_gnt(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO);
  2996. _set_bt_plut(rtwdev, phy_map, BTC_PLT_NONE, BTC_PLT_NONE);
  2997. break;
  2998. case BTC_ANT_BRFK:
  2999. rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_BT);
  3000. _set_gnt(rtwdev, phy_map, BTC_GNT_SW_LO, BTC_GNT_SW_HI);
  3001. _set_bt_plut(rtwdev, phy_map, BTC_PLT_NONE, BTC_PLT_NONE);
  3002. break;
  3003. default:
  3004. break;
  3005. }
  3006. }
  3007. static void _action_wl_only(struct rtw89_dev *rtwdev)
  3008. {
  3009. _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WONLY);
  3010. _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_WL_ONLY);
  3011. }
  3012. static void _action_wl_init(struct rtw89_dev *rtwdev)
  3013. {
  3014. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__);
  3015. _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WINIT);
  3016. _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_WL_INIT);
  3017. }
  3018. static void _action_wl_off(struct rtw89_dev *rtwdev)
  3019. {
  3020. struct rtw89_btc *btc = &rtwdev->btc;
  3021. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  3022. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__);
  3023. if (wl->status.map.rf_off || btc->dm.bt_only)
  3024. _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_WOFF);
  3025. _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_WL_OFF);
  3026. }
  3027. static void _action_freerun(struct rtw89_dev *rtwdev)
  3028. {
  3029. struct rtw89_btc *btc = &rtwdev->btc;
  3030. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__);
  3031. _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_FREERUN);
  3032. _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_FREERUN);
  3033. btc->dm.freerun = true;
  3034. }
  3035. static void _action_bt_whql(struct rtw89_dev *rtwdev)
  3036. {
  3037. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__);
  3038. _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
  3039. _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_BT_WHQL);
  3040. }
  3041. static void _action_bt_off(struct rtw89_dev *rtwdev)
  3042. {
  3043. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__);
  3044. _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WONLY);
  3045. _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_BT_OFF);
  3046. }
  3047. static void _action_bt_idle(struct rtw89_dev *rtwdev)
  3048. {
  3049. struct rtw89_btc *btc = &rtwdev->btc;
  3050. struct rtw89_btc_bt_link_info *b = &btc->cx.bt.link_info;
  3051. _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
  3052. if (btc->mdinfo.ant.type == BTC_ANT_SHARED) { /* shared-antenna */
  3053. switch (btc->cx.state_map) {
  3054. case BTC_WBUSY_BNOSCAN: /*wl-busy + bt idle*/
  3055. if (b->profile_cnt.now > 0)
  3056. _set_policy(rtwdev, BTC_CXP_FIX_TD4010,
  3057. BTC_ACT_BT_IDLE);
  3058. else
  3059. _set_policy(rtwdev, BTC_CXP_FIX_TD4020,
  3060. BTC_ACT_BT_IDLE);
  3061. break;
  3062. case BTC_WBUSY_BSCAN: /*wl-busy + bt-inq */
  3063. _set_policy(rtwdev, BTC_CXP_PFIX_TD5050,
  3064. BTC_ACT_BT_IDLE);
  3065. break;
  3066. case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-idle */
  3067. if (b->profile_cnt.now > 0)
  3068. _set_policy(rtwdev, BTC_CXP_FIX_TD4010,
  3069. BTC_ACT_BT_IDLE);
  3070. else
  3071. _set_policy(rtwdev, BTC_CXP_FIX_TD4020,
  3072. BTC_ACT_BT_IDLE);
  3073. break;
  3074. case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq */
  3075. _set_policy(rtwdev, BTC_CXP_FIX_TD5050,
  3076. BTC_ACT_BT_IDLE);
  3077. break;
  3078. case BTC_WLINKING: /* wl-connecting + bt-inq or bt-idle */
  3079. _set_policy(rtwdev, BTC_CXP_FIX_TD7010,
  3080. BTC_ACT_BT_IDLE);
  3081. break;
  3082. case BTC_WIDLE: /* wl-idle + bt-idle */
  3083. _set_policy(rtwdev, BTC_CXP_OFF_BWB1, BTC_ACT_BT_IDLE);
  3084. break;
  3085. }
  3086. } else { /* dedicated-antenna */
  3087. _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_BT_IDLE);
  3088. }
  3089. }
  3090. static void _action_bt_hfp(struct rtw89_dev *rtwdev)
  3091. {
  3092. struct rtw89_btc *btc = &rtwdev->btc;
  3093. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  3094. _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
  3095. if (btc->mdinfo.ant.type == BTC_ANT_SHARED) {
  3096. if (btc->cx.wl.status.map._4way) {
  3097. _set_policy(rtwdev, BTC_CXP_OFF_WL, BTC_ACT_BT_HFP);
  3098. } else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) {
  3099. btc->cx.bt.scan_rx_low_pri = true;
  3100. _set_policy(rtwdev, BTC_CXP_OFF_BWB2, BTC_ACT_BT_HFP);
  3101. } else {
  3102. _set_policy(rtwdev, BTC_CXP_OFF_BWB1, BTC_ACT_BT_HFP);
  3103. }
  3104. } else {
  3105. _set_policy(rtwdev, BTC_CXP_OFF_EQ2, BTC_ACT_BT_HFP);
  3106. }
  3107. }
  3108. static void _action_bt_hid(struct rtw89_dev *rtwdev)
  3109. {
  3110. const struct rtw89_chip_info *chip = rtwdev->chip;
  3111. struct rtw89_btc *btc = &rtwdev->btc;
  3112. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  3113. struct rtw89_btc_bt_info *bt = &btc->cx.bt;
  3114. struct rtw89_btc_bt_hid_desc *hid = &bt->link_info.hid_desc;
  3115. u16 policy_type = BTC_CXP_OFF_BT;
  3116. _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
  3117. if (btc->mdinfo.ant.type == BTC_ANT_SHARED) { /* shared-antenna */
  3118. if (wl->status.map._4way) {
  3119. policy_type = BTC_CXP_OFF_WL;
  3120. } else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) {
  3121. btc->cx.bt.scan_rx_low_pri = true;
  3122. if (hid->type & BTC_HID_BLE)
  3123. policy_type = BTC_CXP_OFF_BWB0;
  3124. else
  3125. policy_type = BTC_CXP_OFF_BWB2;
  3126. } else if (hid->type == BTC_HID_218) {
  3127. bt->scan_rx_low_pri = true;
  3128. policy_type = BTC_CXP_OFF_BWB2;
  3129. } else if (chip->para_ver == 0x1) {
  3130. policy_type = BTC_CXP_OFF_BWB3;
  3131. } else {
  3132. policy_type = BTC_CXP_OFF_BWB1;
  3133. }
  3134. } else { /* dedicated-antenna */
  3135. policy_type = BTC_CXP_OFF_EQ3;
  3136. }
  3137. _set_policy(rtwdev, policy_type, BTC_ACT_BT_HID);
  3138. }
  3139. static void _action_bt_a2dp(struct rtw89_dev *rtwdev)
  3140. {
  3141. struct rtw89_btc *btc = &rtwdev->btc;
  3142. struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info;
  3143. struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc;
  3144. struct rtw89_btc_dm *dm = &btc->dm;
  3145. _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
  3146. switch (btc->cx.state_map) {
  3147. case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2DP */
  3148. if (a2dp.vendor_id == 0x4c || dm->leak_ap) {
  3149. dm->slot_dur[CXST_W1] = 40;
  3150. dm->slot_dur[CXST_B1] = 200;
  3151. _set_policy(rtwdev,
  3152. BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP);
  3153. } else {
  3154. _set_policy(rtwdev,
  3155. BTC_CXP_PAUTO_TD50B1, BTC_ACT_BT_A2DP);
  3156. }
  3157. break;
  3158. case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP */
  3159. _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3050, BTC_ACT_BT_A2DP);
  3160. break;
  3161. case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-A2DP */
  3162. _set_policy(rtwdev, BTC_CXP_AUTO2_TD3050, BTC_ACT_BT_A2DP);
  3163. break;
  3164. case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2DP */
  3165. case BTC_WLINKING: /* wl-connecting + bt-A2DP */
  3166. if (a2dp.vendor_id == 0x4c || dm->leak_ap) {
  3167. dm->slot_dur[CXST_W1] = 40;
  3168. dm->slot_dur[CXST_B1] = 200;
  3169. _set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1,
  3170. BTC_ACT_BT_A2DP);
  3171. } else {
  3172. _set_policy(rtwdev, BTC_CXP_AUTO_TD50B1,
  3173. BTC_ACT_BT_A2DP);
  3174. }
  3175. break;
  3176. case BTC_WIDLE: /* wl-idle + bt-A2DP */
  3177. _set_policy(rtwdev, BTC_CXP_AUTO_TD20B1, BTC_ACT_BT_A2DP);
  3178. break;
  3179. }
  3180. }
  3181. static void _action_bt_a2dpsink(struct rtw89_dev *rtwdev)
  3182. {
  3183. struct rtw89_btc *btc = &rtwdev->btc;
  3184. _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
  3185. switch (btc->cx.state_map) {
  3186. case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2dp_Sink */
  3187. _set_policy(rtwdev, BTC_CXP_PFIX_TD2030, BTC_ACT_BT_A2DPSINK);
  3188. break;
  3189. case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2dp_Sink */
  3190. _set_policy(rtwdev, BTC_CXP_PFIX_TD2060, BTC_ACT_BT_A2DPSINK);
  3191. break;
  3192. case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2dp_Sink */
  3193. _set_policy(rtwdev, BTC_CXP_FIX_TD2030, BTC_ACT_BT_A2DPSINK);
  3194. break;
  3195. case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-A2dp_Sink */
  3196. _set_policy(rtwdev, BTC_CXP_FIX_TD2060, BTC_ACT_BT_A2DPSINK);
  3197. break;
  3198. case BTC_WLINKING: /* wl-connecting + bt-A2dp_Sink */
  3199. _set_policy(rtwdev, BTC_CXP_FIX_TD3030, BTC_ACT_BT_A2DPSINK);
  3200. break;
  3201. case BTC_WIDLE: /* wl-idle + bt-A2dp_Sink */
  3202. _set_policy(rtwdev, BTC_CXP_FIX_TD2080, BTC_ACT_BT_A2DPSINK);
  3203. break;
  3204. }
  3205. }
  3206. static void _action_bt_pan(struct rtw89_dev *rtwdev)
  3207. {
  3208. struct rtw89_btc *btc = &rtwdev->btc;
  3209. _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
  3210. switch (btc->cx.state_map) {
  3211. case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-PAN */
  3212. _set_policy(rtwdev, BTC_CXP_PFIX_TD5050, BTC_ACT_BT_PAN);
  3213. break;
  3214. case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-PAN */
  3215. _set_policy(rtwdev, BTC_CXP_PFIX_TD3070, BTC_ACT_BT_PAN);
  3216. break;
  3217. case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-PAN */
  3218. _set_policy(rtwdev, BTC_CXP_FIX_TD3030, BTC_ACT_BT_PAN);
  3219. break;
  3220. case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-PAN */
  3221. _set_policy(rtwdev, BTC_CXP_FIX_TD3060, BTC_ACT_BT_PAN);
  3222. break;
  3223. case BTC_WLINKING: /* wl-connecting + bt-PAN */
  3224. _set_policy(rtwdev, BTC_CXP_FIX_TD4020, BTC_ACT_BT_PAN);
  3225. break;
  3226. case BTC_WIDLE: /* wl-idle + bt-pan */
  3227. _set_policy(rtwdev, BTC_CXP_PFIX_TD2080, BTC_ACT_BT_PAN);
  3228. break;
  3229. }
  3230. }
  3231. static void _action_bt_a2dp_hid(struct rtw89_dev *rtwdev)
  3232. {
  3233. struct rtw89_btc *btc = &rtwdev->btc;
  3234. struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info;
  3235. struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc;
  3236. struct rtw89_btc_dm *dm = &btc->dm;
  3237. _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
  3238. switch (btc->cx.state_map) {
  3239. case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2DP+HID */
  3240. case BTC_WIDLE: /* wl-idle + bt-A2DP */
  3241. if (a2dp.vendor_id == 0x4c || dm->leak_ap) {
  3242. dm->slot_dur[CXST_W1] = 40;
  3243. dm->slot_dur[CXST_B1] = 200;
  3244. _set_policy(rtwdev,
  3245. BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP_HID);
  3246. } else {
  3247. _set_policy(rtwdev,
  3248. BTC_CXP_PAUTO_TD50B1, BTC_ACT_BT_A2DP_HID);
  3249. }
  3250. break;
  3251. case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP+HID */
  3252. _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3050, BTC_ACT_BT_A2DP_HID);
  3253. break;
  3254. case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-A2DP+HID */
  3255. _set_policy(rtwdev, BTC_CXP_AUTO2_TD3050, BTC_ACT_BT_A2DP_HID);
  3256. break;
  3257. case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2DP+HID */
  3258. case BTC_WLINKING: /* wl-connecting + bt-A2DP+HID */
  3259. if (a2dp.vendor_id == 0x4c || dm->leak_ap) {
  3260. dm->slot_dur[CXST_W1] = 40;
  3261. dm->slot_dur[CXST_B1] = 200;
  3262. _set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1,
  3263. BTC_ACT_BT_A2DP_HID);
  3264. } else {
  3265. _set_policy(rtwdev, BTC_CXP_AUTO_TD50B1,
  3266. BTC_ACT_BT_A2DP_HID);
  3267. }
  3268. break;
  3269. }
  3270. }
  3271. static void _action_bt_a2dp_pan(struct rtw89_dev *rtwdev)
  3272. {
  3273. struct rtw89_btc *btc = &rtwdev->btc;
  3274. _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
  3275. switch (btc->cx.state_map) {
  3276. case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2DP+PAN */
  3277. _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3070, BTC_ACT_BT_A2DP_PAN);
  3278. break;
  3279. case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP+PAN */
  3280. _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3070, BTC_ACT_BT_A2DP_PAN);
  3281. break;
  3282. case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2DP+PAN */
  3283. _set_policy(rtwdev, BTC_CXP_AUTO2_TD5050, BTC_ACT_BT_A2DP_PAN);
  3284. break;
  3285. case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-A2DP+PAN */
  3286. _set_policy(rtwdev, BTC_CXP_AUTO2_TD3070, BTC_ACT_BT_A2DP_PAN);
  3287. break;
  3288. case BTC_WLINKING: /* wl-connecting + bt-A2DP+PAN */
  3289. _set_policy(rtwdev, BTC_CXP_AUTO2_TD3050, BTC_ACT_BT_A2DP_PAN);
  3290. break;
  3291. case BTC_WIDLE: /* wl-idle + bt-A2DP+PAN */
  3292. _set_policy(rtwdev, BTC_CXP_PAUTO2_TD2080, BTC_ACT_BT_A2DP_PAN);
  3293. break;
  3294. }
  3295. }
  3296. static void _action_bt_pan_hid(struct rtw89_dev *rtwdev)
  3297. {
  3298. struct rtw89_btc *btc = &rtwdev->btc;
  3299. _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
  3300. switch (btc->cx.state_map) {
  3301. case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-PAN+HID */
  3302. _set_policy(rtwdev, BTC_CXP_PFIX_TD3030, BTC_ACT_BT_PAN_HID);
  3303. break;
  3304. case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-PAN+HID */
  3305. _set_policy(rtwdev, BTC_CXP_PFIX_TD3070, BTC_ACT_BT_PAN_HID);
  3306. break;
  3307. case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-PAN+HID */
  3308. _set_policy(rtwdev, BTC_CXP_FIX_TD3030, BTC_ACT_BT_PAN_HID);
  3309. break;
  3310. case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-PAN+HID */
  3311. _set_policy(rtwdev, BTC_CXP_FIX_TD3060, BTC_ACT_BT_PAN_HID);
  3312. break;
  3313. case BTC_WLINKING: /* wl-connecting + bt-PAN+HID */
  3314. _set_policy(rtwdev, BTC_CXP_FIX_TD4010, BTC_ACT_BT_PAN_HID);
  3315. break;
  3316. case BTC_WIDLE: /* wl-idle + bt-PAN+HID */
  3317. _set_policy(rtwdev, BTC_CXP_PFIX_TD2080, BTC_ACT_BT_PAN_HID);
  3318. break;
  3319. }
  3320. }
  3321. static void _action_bt_a2dp_pan_hid(struct rtw89_dev *rtwdev)
  3322. {
  3323. struct rtw89_btc *btc = &rtwdev->btc;
  3324. _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
  3325. switch (btc->cx.state_map) {
  3326. case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2DP+PAN+HID */
  3327. _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3070,
  3328. BTC_ACT_BT_A2DP_PAN_HID);
  3329. break;
  3330. case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP+PAN+HID */
  3331. _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3070,
  3332. BTC_ACT_BT_A2DP_PAN_HID);
  3333. break;
  3334. case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-A2DP+PAN+HID */
  3335. _set_policy(rtwdev, BTC_CXP_AUTO2_TD3070,
  3336. BTC_ACT_BT_A2DP_PAN_HID);
  3337. break;
  3338. case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2DP+PAN+HID */
  3339. case BTC_WLINKING: /* wl-connecting + bt-A2DP+PAN+HID */
  3340. _set_policy(rtwdev, BTC_CXP_AUTO2_TD3050,
  3341. BTC_ACT_BT_A2DP_PAN_HID);
  3342. break;
  3343. case BTC_WIDLE: /* wl-idle + bt-A2DP+PAN+HID */
  3344. _set_policy(rtwdev, BTC_CXP_PAUTO2_TD2080,
  3345. BTC_ACT_BT_A2DP_PAN_HID);
  3346. break;
  3347. }
  3348. }
  3349. static void _action_wl_5g(struct rtw89_dev *rtwdev)
  3350. {
  3351. _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W5G);
  3352. _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_5G);
  3353. }
  3354. static void _action_wl_other(struct rtw89_dev *rtwdev)
  3355. {
  3356. struct rtw89_btc *btc = &rtwdev->btc;
  3357. _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
  3358. if (btc->mdinfo.ant.type == BTC_ANT_SHARED)
  3359. _set_policy(rtwdev, BTC_CXP_OFFB_BWB0, BTC_ACT_WL_OTHER);
  3360. else
  3361. _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_OTHER);
  3362. }
  3363. static void _action_wl_nc(struct rtw89_dev *rtwdev)
  3364. {
  3365. _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
  3366. _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_WL_NC);
  3367. }
  3368. static void _action_wl_rfk(struct rtw89_dev *rtwdev)
  3369. {
  3370. struct rtw89_btc *btc = &rtwdev->btc;
  3371. struct rtw89_btc_wl_rfk_info rfk = btc->cx.wl.rfk_info;
  3372. if (rfk.state != BTC_WRFK_START)
  3373. return;
  3374. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): band = %d\n",
  3375. __func__, rfk.band);
  3376. _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WRFK);
  3377. _set_policy(rtwdev, BTC_CXP_OFF_WL, BTC_ACT_WL_RFK);
  3378. }
  3379. static void _set_btg_ctrl(struct rtw89_dev *rtwdev)
  3380. {
  3381. struct rtw89_btc *btc = &rtwdev->btc;
  3382. const struct rtw89_btc_ver *ver = btc->ver;
  3383. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  3384. struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
  3385. struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1;
  3386. struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2;
  3387. struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
  3388. bool is_btg;
  3389. u8 mode;
  3390. if (btc->ctrl.manual)
  3391. return;
  3392. if (ver->fwlrole == 0)
  3393. mode = wl_rinfo->link_mode;
  3394. else if (ver->fwlrole == 1)
  3395. mode = wl_rinfo_v1->link_mode;
  3396. else if (ver->fwlrole == 2)
  3397. mode = wl_rinfo_v2->link_mode;
  3398. else
  3399. return;
  3400. /* notify halbb ignore GNT_BT or not for WL BB Rx-AGC control */
  3401. if (mode == BTC_WLINK_5G) /* always 0 if 5G */
  3402. is_btg = false;
  3403. else if (mode == BTC_WLINK_25G_DBCC &&
  3404. wl_dinfo->real_band[RTW89_PHY_1] != RTW89_BAND_2G)
  3405. is_btg = false;
  3406. else
  3407. is_btg = true;
  3408. if (btc->dm.run_reason != BTC_RSN_NTFY_INIT &&
  3409. is_btg == btc->dm.wl_btg_rx)
  3410. return;
  3411. btc->dm.wl_btg_rx = is_btg;
  3412. if (mode == BTC_WLINK_25G_MCC)
  3413. return;
  3414. rtw89_ctrl_btg(rtwdev, is_btg);
  3415. }
  3416. struct rtw89_txtime_data {
  3417. struct rtw89_dev *rtwdev;
  3418. int type;
  3419. u32 tx_time;
  3420. u8 tx_retry;
  3421. u16 enable;
  3422. bool reenable;
  3423. };
  3424. static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta)
  3425. {
  3426. struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
  3427. struct rtw89_txtime_data *iter_data =
  3428. (struct rtw89_txtime_data *)data;
  3429. struct rtw89_dev *rtwdev = iter_data->rtwdev;
  3430. struct rtw89_vif *rtwvif = rtwsta->rtwvif;
  3431. struct rtw89_btc *btc = &rtwdev->btc;
  3432. struct rtw89_btc_cx *cx = &btc->cx;
  3433. struct rtw89_btc_wl_info *wl = &cx->wl;
  3434. struct rtw89_btc_wl_link_info *plink = NULL;
  3435. u8 port = rtwvif->port;
  3436. u32 tx_time = iter_data->tx_time;
  3437. u8 tx_retry = iter_data->tx_retry;
  3438. u16 enable = iter_data->enable;
  3439. bool reenable = iter_data->reenable;
  3440. plink = &wl->link_info[port];
  3441. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  3442. "[BTC], %s(): port = %d\n", __func__, port);
  3443. if (!plink->connected) {
  3444. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  3445. "[BTC], %s(): connected = %d\n",
  3446. __func__, plink->connected);
  3447. return;
  3448. }
  3449. /* backup the original tx time before tx-limit on */
  3450. if (reenable) {
  3451. rtw89_mac_get_tx_time(rtwdev, rtwsta, &plink->tx_time);
  3452. rtw89_mac_get_tx_retry_limit(rtwdev, rtwsta, &plink->tx_retry);
  3453. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  3454. "[BTC], %s(): reenable, tx_time=%d tx_retry= %d\n",
  3455. __func__, plink->tx_time, plink->tx_retry);
  3456. }
  3457. /* restore the original tx time if no tx-limit */
  3458. if (!enable) {
  3459. rtw89_mac_set_tx_time(rtwdev, rtwsta, true, plink->tx_time);
  3460. rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta, true,
  3461. plink->tx_retry);
  3462. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  3463. "[BTC], %s(): restore, tx_time=%d tx_retry= %d\n",
  3464. __func__, plink->tx_time, plink->tx_retry);
  3465. } else {
  3466. rtw89_mac_set_tx_time(rtwdev, rtwsta, false, tx_time);
  3467. rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta, false, tx_retry);
  3468. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  3469. "[BTC], %s(): set, tx_time=%d tx_retry= %d\n",
  3470. __func__, tx_time, tx_retry);
  3471. }
  3472. }
  3473. static void _set_wl_tx_limit(struct rtw89_dev *rtwdev)
  3474. {
  3475. struct rtw89_btc *btc = &rtwdev->btc;
  3476. const struct rtw89_btc_ver *ver = btc->ver;
  3477. struct rtw89_btc_cx *cx = &btc->cx;
  3478. struct rtw89_btc_dm *dm = &btc->dm;
  3479. struct rtw89_btc_wl_info *wl = &cx->wl;
  3480. struct rtw89_btc_bt_info *bt = &cx->bt;
  3481. struct rtw89_btc_bt_link_info *b = &bt->link_info;
  3482. struct rtw89_btc_bt_hfp_desc *hfp = &b->hfp_desc;
  3483. struct rtw89_btc_bt_hid_desc *hid = &b->hid_desc;
  3484. struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
  3485. struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1;
  3486. struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2;
  3487. struct rtw89_txtime_data data = {.rtwdev = rtwdev};
  3488. u8 mode;
  3489. u8 tx_retry;
  3490. u32 tx_time;
  3491. u16 enable;
  3492. bool reenable = false;
  3493. if (btc->ctrl.manual)
  3494. return;
  3495. if (ver->fwlrole == 0)
  3496. mode = wl_rinfo->link_mode;
  3497. else if (ver->fwlrole == 1)
  3498. mode = wl_rinfo_v1->link_mode;
  3499. else if (ver->fwlrole == 2)
  3500. mode = wl_rinfo_v2->link_mode;
  3501. else
  3502. return;
  3503. if (btc->dm.freerun || btc->ctrl.igno_bt || b->profile_cnt.now == 0 ||
  3504. mode == BTC_WLINK_5G || mode == BTC_WLINK_NOLINK) {
  3505. enable = 0;
  3506. tx_time = BTC_MAX_TX_TIME_DEF;
  3507. tx_retry = BTC_MAX_TX_RETRY_DEF;
  3508. } else if ((hfp->exist && hid->exist) || hid->pair_cnt > 1) {
  3509. enable = 1;
  3510. tx_time = BTC_MAX_TX_TIME_L2;
  3511. tx_retry = BTC_MAX_TX_RETRY_L1;
  3512. } else if (hfp->exist || hid->exist) {
  3513. enable = 1;
  3514. tx_time = BTC_MAX_TX_TIME_L3;
  3515. tx_retry = BTC_MAX_TX_RETRY_L1;
  3516. } else {
  3517. enable = 0;
  3518. tx_time = BTC_MAX_TX_TIME_DEF;
  3519. tx_retry = BTC_MAX_TX_RETRY_DEF;
  3520. }
  3521. if (dm->wl_tx_limit.enable == enable &&
  3522. dm->wl_tx_limit.tx_time == tx_time &&
  3523. dm->wl_tx_limit.tx_retry == tx_retry)
  3524. return;
  3525. if (!dm->wl_tx_limit.enable && enable)
  3526. reenable = true;
  3527. dm->wl_tx_limit.enable = enable;
  3528. dm->wl_tx_limit.tx_time = tx_time;
  3529. dm->wl_tx_limit.tx_retry = tx_retry;
  3530. data.enable = enable;
  3531. data.tx_time = tx_time;
  3532. data.tx_retry = tx_retry;
  3533. data.reenable = reenable;
  3534. ieee80211_iterate_stations_atomic(rtwdev->hw,
  3535. rtw89_tx_time_iter,
  3536. &data);
  3537. }
  3538. static void _set_bt_rx_agc(struct rtw89_dev *rtwdev)
  3539. {
  3540. struct rtw89_btc *btc = &rtwdev->btc;
  3541. const struct rtw89_btc_ver *ver = btc->ver;
  3542. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  3543. struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
  3544. struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1;
  3545. struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2;
  3546. struct rtw89_btc_bt_info *bt = &btc->cx.bt;
  3547. bool bt_hi_lna_rx = false;
  3548. u8 mode;
  3549. if (ver->fwlrole == 0)
  3550. mode = wl_rinfo->link_mode;
  3551. else if (ver->fwlrole == 1)
  3552. mode = wl_rinfo_v1->link_mode;
  3553. else if (ver->fwlrole == 2)
  3554. mode = wl_rinfo_v2->link_mode;
  3555. else
  3556. return;
  3557. if (mode != BTC_WLINK_NOLINK && btc->dm.wl_btg_rx)
  3558. bt_hi_lna_rx = true;
  3559. if (bt_hi_lna_rx == bt->hi_lna_rx)
  3560. return;
  3561. _write_scbd(rtwdev, BTC_WSCB_BT_HILNA, bt_hi_lna_rx);
  3562. }
  3563. static void _set_bt_rx_scan_pri(struct rtw89_dev *rtwdev)
  3564. {
  3565. struct rtw89_btc *btc = &rtwdev->btc;
  3566. struct rtw89_btc_bt_info *bt = &btc->cx.bt;
  3567. _write_scbd(rtwdev, BTC_WSCB_RXSCAN_PRI, (bool)(!!bt->scan_rx_low_pri));
  3568. }
  3569. /* TODO add these functions */
  3570. static void _action_common(struct rtw89_dev *rtwdev)
  3571. {
  3572. struct rtw89_btc *btc = &rtwdev->btc;
  3573. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  3574. _set_btg_ctrl(rtwdev);
  3575. _set_wl_tx_limit(rtwdev);
  3576. _set_bt_afh_info(rtwdev);
  3577. _set_bt_rx_agc(rtwdev);
  3578. _set_rf_trx_para(rtwdev);
  3579. _set_bt_rx_scan_pri(rtwdev);
  3580. if (wl->scbd_change) {
  3581. rtw89_mac_cfg_sb(rtwdev, wl->scbd);
  3582. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], write scbd: 0x%08x\n",
  3583. wl->scbd);
  3584. wl->scbd_change = false;
  3585. btc->cx.cnt_wl[BTC_WCNT_SCBDUPDATE]++;
  3586. }
  3587. btc->dm.tdma_instant_excute = 0;
  3588. }
  3589. static void _action_by_bt(struct rtw89_dev *rtwdev)
  3590. {
  3591. struct rtw89_btc *btc = &rtwdev->btc;
  3592. struct rtw89_btc_bt_info *bt = &btc->cx.bt;
  3593. struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info;
  3594. struct rtw89_btc_bt_hid_desc hid = bt_linfo->hid_desc;
  3595. struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc;
  3596. struct rtw89_btc_bt_pan_desc pan = bt_linfo->pan_desc;
  3597. u8 profile_map = 0;
  3598. if (bt_linfo->hfp_desc.exist)
  3599. profile_map |= BTC_BT_HFP;
  3600. if (bt_linfo->hid_desc.exist)
  3601. profile_map |= BTC_BT_HID;
  3602. if (bt_linfo->a2dp_desc.exist)
  3603. profile_map |= BTC_BT_A2DP;
  3604. if (bt_linfo->pan_desc.exist)
  3605. profile_map |= BTC_BT_PAN;
  3606. switch (profile_map) {
  3607. case BTC_BT_NOPROFILE:
  3608. if (_check_freerun(rtwdev))
  3609. _action_freerun(rtwdev);
  3610. else if (pan.active)
  3611. _action_bt_pan(rtwdev);
  3612. else
  3613. _action_bt_idle(rtwdev);
  3614. break;
  3615. case BTC_BT_HFP:
  3616. if (_check_freerun(rtwdev))
  3617. _action_freerun(rtwdev);
  3618. else
  3619. _action_bt_hfp(rtwdev);
  3620. break;
  3621. case BTC_BT_HFP | BTC_BT_HID:
  3622. case BTC_BT_HID:
  3623. if (_check_freerun(rtwdev))
  3624. _action_freerun(rtwdev);
  3625. else
  3626. _action_bt_hid(rtwdev);
  3627. break;
  3628. case BTC_BT_A2DP:
  3629. if (_check_freerun(rtwdev))
  3630. _action_freerun(rtwdev);
  3631. else if (a2dp.sink)
  3632. _action_bt_a2dpsink(rtwdev);
  3633. else if (bt_linfo->multi_link.now && !hid.pair_cnt)
  3634. _action_bt_a2dp_pan(rtwdev);
  3635. else
  3636. _action_bt_a2dp(rtwdev);
  3637. break;
  3638. case BTC_BT_PAN:
  3639. _action_bt_pan(rtwdev);
  3640. break;
  3641. case BTC_BT_A2DP | BTC_BT_HFP:
  3642. case BTC_BT_A2DP | BTC_BT_HID:
  3643. case BTC_BT_A2DP | BTC_BT_HFP | BTC_BT_HID:
  3644. if (_check_freerun(rtwdev))
  3645. _action_freerun(rtwdev);
  3646. else
  3647. _action_bt_a2dp_hid(rtwdev);
  3648. break;
  3649. case BTC_BT_A2DP | BTC_BT_PAN:
  3650. _action_bt_a2dp_pan(rtwdev);
  3651. break;
  3652. case BTC_BT_PAN | BTC_BT_HFP:
  3653. case BTC_BT_PAN | BTC_BT_HID:
  3654. case BTC_BT_PAN | BTC_BT_HFP | BTC_BT_HID:
  3655. _action_bt_pan_hid(rtwdev);
  3656. break;
  3657. case BTC_BT_A2DP | BTC_BT_PAN | BTC_BT_HID:
  3658. case BTC_BT_A2DP | BTC_BT_PAN | BTC_BT_HFP:
  3659. default:
  3660. _action_bt_a2dp_pan_hid(rtwdev);
  3661. break;
  3662. }
  3663. }
  3664. static void _action_wl_2g_sta(struct rtw89_dev *rtwdev)
  3665. {
  3666. _action_by_bt(rtwdev);
  3667. }
  3668. static void _action_wl_scan(struct rtw89_dev *rtwdev)
  3669. {
  3670. struct rtw89_btc *btc = &rtwdev->btc;
  3671. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  3672. struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
  3673. if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) {
  3674. _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W25G);
  3675. if (btc->mdinfo.ant.type == BTC_ANT_SHARED)
  3676. _set_policy(rtwdev, BTC_CXP_OFFE_DEF,
  3677. BTC_RSN_NTFY_SCAN_START);
  3678. else
  3679. _set_policy(rtwdev, BTC_CXP_OFF_EQ0,
  3680. BTC_RSN_NTFY_SCAN_START);
  3681. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], Scan offload!\n");
  3682. } else if (rtwdev->dbcc_en) {
  3683. if (wl_dinfo->real_band[RTW89_PHY_0] != RTW89_BAND_2G &&
  3684. wl_dinfo->real_band[RTW89_PHY_1] != RTW89_BAND_2G)
  3685. _action_wl_5g(rtwdev);
  3686. else
  3687. _action_by_bt(rtwdev);
  3688. } else {
  3689. if (wl->scan_info.band[RTW89_PHY_0] != RTW89_BAND_2G)
  3690. _action_wl_5g(rtwdev);
  3691. else
  3692. _action_by_bt(rtwdev);
  3693. }
  3694. }
  3695. static void _action_wl_25g_mcc(struct rtw89_dev *rtwdev)
  3696. {
  3697. struct rtw89_btc *btc = &rtwdev->btc;
  3698. _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W25G);
  3699. if (btc->mdinfo.ant.type == BTC_ANT_SHARED) {
  3700. if (btc->cx.bt.link_info.profile_cnt.now == 0)
  3701. _set_policy(rtwdev, BTC_CXP_OFFE_DEF2,
  3702. BTC_ACT_WL_25G_MCC);
  3703. else
  3704. _set_policy(rtwdev, BTC_CXP_OFFE_DEF,
  3705. BTC_ACT_WL_25G_MCC);
  3706. } else { /* dedicated-antenna */
  3707. _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_25G_MCC);
  3708. }
  3709. }
  3710. static void _action_wl_2g_mcc(struct rtw89_dev *rtwdev)
  3711. { struct rtw89_btc *btc = &rtwdev->btc;
  3712. _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
  3713. if (btc->mdinfo.ant.type == BTC_ANT_SHARED) { /* shared-antenna */
  3714. if (btc->cx.bt.link_info.profile_cnt.now == 0)
  3715. _set_policy(rtwdev, BTC_CXP_OFFE_DEF2,
  3716. BTC_ACT_WL_2G_MCC);
  3717. else
  3718. _set_policy(rtwdev, BTC_CXP_OFFE_DEF,
  3719. BTC_ACT_WL_2G_MCC);
  3720. } else { /* dedicated-antenna */
  3721. _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_2G_MCC);
  3722. }
  3723. }
  3724. static void _action_wl_2g_scc(struct rtw89_dev *rtwdev)
  3725. {
  3726. struct rtw89_btc *btc = &rtwdev->btc;
  3727. _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
  3728. if (btc->mdinfo.ant.type == BTC_ANT_SHARED) { /* shared-antenna */
  3729. if (btc->cx.bt.link_info.profile_cnt.now == 0)
  3730. _set_policy(rtwdev,
  3731. BTC_CXP_OFFE_DEF2, BTC_ACT_WL_2G_SCC);
  3732. else
  3733. _set_policy(rtwdev,
  3734. BTC_CXP_OFFE_DEF, BTC_ACT_WL_2G_SCC);
  3735. } else { /* dedicated-antenna */
  3736. _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_2G_SCC);
  3737. }
  3738. }
  3739. static void _action_wl_2g_scc_v1(struct rtw89_dev *rtwdev)
  3740. {
  3741. struct rtw89_btc *btc = &rtwdev->btc;
  3742. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  3743. struct rtw89_btc_bt_info *bt = &btc->cx.bt;
  3744. struct rtw89_btc_dm *dm = &btc->dm;
  3745. struct rtw89_btc_wl_role_info_v1 *wl_rinfo = &wl->role_info_v1;
  3746. u16 policy_type = BTC_CXP_OFF_BT;
  3747. u32 dur;
  3748. if (btc->mdinfo.ant.type == BTC_ANT_DEDICATED) {
  3749. policy_type = BTC_CXP_OFF_EQ0;
  3750. } else {
  3751. /* shared-antenna */
  3752. switch (wl_rinfo->mrole_type) {
  3753. case BTC_WLMROLE_STA_GC:
  3754. dm->wl_scc.null_role1 = RTW89_WIFI_ROLE_STATION;
  3755. dm->wl_scc.null_role2 = RTW89_WIFI_ROLE_P2P_CLIENT;
  3756. dm->wl_scc.ebt_null = 0; /* no ext-slot-control */
  3757. _action_by_bt(rtwdev);
  3758. return;
  3759. case BTC_WLMROLE_STA_STA:
  3760. dm->wl_scc.null_role1 = RTW89_WIFI_ROLE_STATION;
  3761. dm->wl_scc.null_role2 = RTW89_WIFI_ROLE_STATION;
  3762. dm->wl_scc.ebt_null = 0; /* no ext-slot-control */
  3763. _action_by_bt(rtwdev);
  3764. return;
  3765. case BTC_WLMROLE_STA_GC_NOA:
  3766. case BTC_WLMROLE_STA_GO:
  3767. case BTC_WLMROLE_STA_GO_NOA:
  3768. dm->wl_scc.null_role1 = RTW89_WIFI_ROLE_STATION;
  3769. dm->wl_scc.null_role2 = RTW89_WIFI_ROLE_NONE;
  3770. dur = wl_rinfo->mrole_noa_duration;
  3771. if (wl->status.map._4way) {
  3772. dm->wl_scc.ebt_null = 0;
  3773. policy_type = BTC_CXP_OFFE_WL;
  3774. } else if (bt->link_info.status.map.connect == 0) {
  3775. dm->wl_scc.ebt_null = 0;
  3776. policy_type = BTC_CXP_OFFE_2GISOB;
  3777. } else if (bt->link_info.a2dp_desc.exist &&
  3778. dur < btc->bt_req_len) {
  3779. dm->wl_scc.ebt_null = 1; /* tx null at EBT */
  3780. policy_type = BTC_CXP_OFFE_2GBWMIXB2;
  3781. } else if (bt->link_info.a2dp_desc.exist ||
  3782. bt->link_info.pan_desc.exist) {
  3783. dm->wl_scc.ebt_null = 1; /* tx null at EBT */
  3784. policy_type = BTC_CXP_OFFE_2GBWISOB;
  3785. } else {
  3786. dm->wl_scc.ebt_null = 0;
  3787. policy_type = BTC_CXP_OFFE_2GBWISOB;
  3788. }
  3789. break;
  3790. default:
  3791. break;
  3792. }
  3793. }
  3794. _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
  3795. _set_policy(rtwdev, policy_type, BTC_ACT_WL_2G_SCC);
  3796. }
  3797. static void _action_wl_2g_scc_v2(struct rtw89_dev *rtwdev)
  3798. {
  3799. struct rtw89_btc *btc = &rtwdev->btc;
  3800. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  3801. struct rtw89_btc_bt_info *bt = &btc->cx.bt;
  3802. struct rtw89_btc_dm *dm = &btc->dm;
  3803. struct rtw89_btc_wl_role_info_v2 *wl_rinfo = &wl->role_info_v2;
  3804. u16 policy_type = BTC_CXP_OFF_BT;
  3805. u32 dur;
  3806. if (btc->mdinfo.ant.type == BTC_ANT_DEDICATED) {
  3807. policy_type = BTC_CXP_OFF_EQ0;
  3808. } else {
  3809. /* shared-antenna */
  3810. switch (wl_rinfo->mrole_type) {
  3811. case BTC_WLMROLE_STA_GC:
  3812. dm->wl_scc.null_role1 = RTW89_WIFI_ROLE_STATION;
  3813. dm->wl_scc.null_role2 = RTW89_WIFI_ROLE_P2P_CLIENT;
  3814. dm->wl_scc.ebt_null = 0; /* no ext-slot-control */
  3815. _action_by_bt(rtwdev);
  3816. return;
  3817. case BTC_WLMROLE_STA_STA:
  3818. dm->wl_scc.null_role1 = RTW89_WIFI_ROLE_STATION;
  3819. dm->wl_scc.null_role2 = RTW89_WIFI_ROLE_STATION;
  3820. dm->wl_scc.ebt_null = 0; /* no ext-slot-control */
  3821. _action_by_bt(rtwdev);
  3822. return;
  3823. case BTC_WLMROLE_STA_GC_NOA:
  3824. case BTC_WLMROLE_STA_GO:
  3825. case BTC_WLMROLE_STA_GO_NOA:
  3826. dm->wl_scc.null_role1 = RTW89_WIFI_ROLE_STATION;
  3827. dm->wl_scc.null_role2 = RTW89_WIFI_ROLE_NONE;
  3828. dur = wl_rinfo->mrole_noa_duration;
  3829. if (wl->status.map._4way) {
  3830. dm->wl_scc.ebt_null = 0;
  3831. policy_type = BTC_CXP_OFFE_WL;
  3832. } else if (bt->link_info.status.map.connect == 0) {
  3833. dm->wl_scc.ebt_null = 0;
  3834. policy_type = BTC_CXP_OFFE_2GISOB;
  3835. } else if (bt->link_info.a2dp_desc.exist &&
  3836. dur < btc->bt_req_len) {
  3837. dm->wl_scc.ebt_null = 1; /* tx null at EBT */
  3838. policy_type = BTC_CXP_OFFE_2GBWMIXB2;
  3839. } else if (bt->link_info.a2dp_desc.exist ||
  3840. bt->link_info.pan_desc.exist) {
  3841. dm->wl_scc.ebt_null = 1; /* tx null at EBT */
  3842. policy_type = BTC_CXP_OFFE_2GBWISOB;
  3843. } else {
  3844. dm->wl_scc.ebt_null = 0;
  3845. policy_type = BTC_CXP_OFFE_2GBWISOB;
  3846. }
  3847. break;
  3848. default:
  3849. break;
  3850. }
  3851. }
  3852. _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
  3853. _set_policy(rtwdev, policy_type, BTC_ACT_WL_2G_SCC);
  3854. }
  3855. static void _action_wl_2g_ap(struct rtw89_dev *rtwdev)
  3856. {
  3857. struct rtw89_btc *btc = &rtwdev->btc;
  3858. _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
  3859. if (btc->mdinfo.ant.type == BTC_ANT_SHARED) {
  3860. if (btc->cx.bt.link_info.profile_cnt.now == 0)
  3861. _set_policy(rtwdev, BTC_CXP_OFFE_DEF2,
  3862. BTC_ACT_WL_2G_AP);
  3863. else
  3864. _set_policy(rtwdev, BTC_CXP_OFFE_DEF, BTC_ACT_WL_2G_AP);
  3865. } else {/* dedicated-antenna */
  3866. _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_2G_AP);
  3867. }
  3868. }
  3869. static void _action_wl_2g_go(struct rtw89_dev *rtwdev)
  3870. {
  3871. struct rtw89_btc *btc = &rtwdev->btc;
  3872. _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
  3873. if (btc->mdinfo.ant.type == BTC_ANT_SHARED) { /* shared-antenna */
  3874. if (btc->cx.bt.link_info.profile_cnt.now == 0)
  3875. _set_policy(rtwdev,
  3876. BTC_CXP_OFFE_DEF2, BTC_ACT_WL_2G_GO);
  3877. else
  3878. _set_policy(rtwdev,
  3879. BTC_CXP_OFFE_DEF, BTC_ACT_WL_2G_GO);
  3880. } else { /* dedicated-antenna */
  3881. _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_2G_GO);
  3882. }
  3883. }
  3884. static void _action_wl_2g_gc(struct rtw89_dev *rtwdev)
  3885. {
  3886. struct rtw89_btc *btc = &rtwdev->btc;
  3887. _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
  3888. if (btc->mdinfo.ant.type == BTC_ANT_SHARED) { /* shared-antenna */
  3889. _action_by_bt(rtwdev);
  3890. } else {/* dedicated-antenna */
  3891. _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_2G_GC);
  3892. }
  3893. }
  3894. static void _action_wl_2g_nan(struct rtw89_dev *rtwdev)
  3895. {
  3896. struct rtw89_btc *btc = &rtwdev->btc;
  3897. _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
  3898. if (btc->mdinfo.ant.type == BTC_ANT_SHARED) { /* shared-antenna */
  3899. if (btc->cx.bt.link_info.profile_cnt.now == 0)
  3900. _set_policy(rtwdev,
  3901. BTC_CXP_OFFE_DEF2, BTC_ACT_WL_2G_NAN);
  3902. else
  3903. _set_policy(rtwdev,
  3904. BTC_CXP_OFFE_DEF, BTC_ACT_WL_2G_NAN);
  3905. } else { /* dedicated-antenna */
  3906. _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_2G_NAN);
  3907. }
  3908. }
  3909. static u32 _read_scbd(struct rtw89_dev *rtwdev)
  3910. {
  3911. const struct rtw89_chip_info *chip = rtwdev->chip;
  3912. struct rtw89_btc *btc = &rtwdev->btc;
  3913. u32 scbd_val = 0;
  3914. if (!chip->scbd)
  3915. return 0;
  3916. scbd_val = rtw89_mac_get_sb(rtwdev);
  3917. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], read scbd: 0x%08x\n",
  3918. scbd_val);
  3919. btc->cx.cnt_bt[BTC_BCNT_SCBDREAD]++;
  3920. return scbd_val;
  3921. }
  3922. static void _write_scbd(struct rtw89_dev *rtwdev, u32 val, bool state)
  3923. {
  3924. const struct rtw89_chip_info *chip = rtwdev->chip;
  3925. struct rtw89_btc *btc = &rtwdev->btc;
  3926. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  3927. u32 scbd_val = 0;
  3928. u8 force_exec = false;
  3929. if (!chip->scbd)
  3930. return;
  3931. scbd_val = state ? wl->scbd | val : wl->scbd & ~val;
  3932. if (val & BTC_WSCB_ACTIVE || val & BTC_WSCB_ON)
  3933. force_exec = true;
  3934. if (scbd_val != wl->scbd || force_exec) {
  3935. wl->scbd = scbd_val;
  3936. wl->scbd_change = true;
  3937. }
  3938. }
  3939. static u8
  3940. _update_rssi_state(struct rtw89_dev *rtwdev, u8 pre_state, u8 rssi, u8 thresh)
  3941. {
  3942. const struct rtw89_chip_info *chip = rtwdev->chip;
  3943. u8 next_state, tol = chip->rssi_tol;
  3944. if (pre_state == BTC_RSSI_ST_LOW ||
  3945. pre_state == BTC_RSSI_ST_STAY_LOW) {
  3946. if (rssi >= (thresh + tol))
  3947. next_state = BTC_RSSI_ST_HIGH;
  3948. else
  3949. next_state = BTC_RSSI_ST_STAY_LOW;
  3950. } else {
  3951. if (rssi < thresh)
  3952. next_state = BTC_RSSI_ST_LOW;
  3953. else
  3954. next_state = BTC_RSSI_ST_STAY_HIGH;
  3955. }
  3956. return next_state;
  3957. }
  3958. static
  3959. void _update_dbcc_band(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
  3960. {
  3961. struct rtw89_btc *btc = &rtwdev->btc;
  3962. btc->cx.wl.dbcc_info.real_band[phy_idx] =
  3963. btc->cx.wl.scan_info.phy_map & BIT(phy_idx) ?
  3964. btc->cx.wl.dbcc_info.scan_band[phy_idx] :
  3965. btc->cx.wl.dbcc_info.op_band[phy_idx];
  3966. }
  3967. static void _update_wl_info(struct rtw89_dev *rtwdev)
  3968. {
  3969. struct rtw89_btc *btc = &rtwdev->btc;
  3970. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  3971. struct rtw89_btc_wl_link_info *wl_linfo = wl->link_info;
  3972. struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
  3973. struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
  3974. u8 i, cnt_connect = 0, cnt_connecting = 0, cnt_active = 0;
  3975. u8 cnt_2g = 0, cnt_5g = 0, phy;
  3976. u32 wl_2g_ch[2] = {0}, wl_5g_ch[2] = {0};
  3977. bool b2g = false, b5g = false, client_joined = false;
  3978. memset(wl_rinfo, 0, sizeof(*wl_rinfo));
  3979. for (i = 0; i < RTW89_PORT_NUM; i++) {
  3980. /* check if role active? */
  3981. if (!wl_linfo[i].active)
  3982. continue;
  3983. cnt_active++;
  3984. wl_rinfo->active_role[cnt_active - 1].role = wl_linfo[i].role;
  3985. wl_rinfo->active_role[cnt_active - 1].pid = wl_linfo[i].pid;
  3986. wl_rinfo->active_role[cnt_active - 1].phy = wl_linfo[i].phy;
  3987. wl_rinfo->active_role[cnt_active - 1].band = wl_linfo[i].band;
  3988. wl_rinfo->active_role[cnt_active - 1].noa = (u8)wl_linfo[i].noa;
  3989. wl_rinfo->active_role[cnt_active - 1].connected = 0;
  3990. wl->port_id[wl_linfo[i].role] = wl_linfo[i].pid;
  3991. phy = wl_linfo[i].phy;
  3992. /* check dbcc role */
  3993. if (rtwdev->dbcc_en && phy < RTW89_PHY_MAX) {
  3994. wl_dinfo->role[phy] = wl_linfo[i].role;
  3995. wl_dinfo->op_band[phy] = wl_linfo[i].band;
  3996. _update_dbcc_band(rtwdev, phy);
  3997. _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC);
  3998. }
  3999. if (wl_linfo[i].connected == MLME_NO_LINK) {
  4000. continue;
  4001. } else if (wl_linfo[i].connected == MLME_LINKING) {
  4002. cnt_connecting++;
  4003. } else {
  4004. cnt_connect++;
  4005. if ((wl_linfo[i].role == RTW89_WIFI_ROLE_P2P_GO ||
  4006. wl_linfo[i].role == RTW89_WIFI_ROLE_AP) &&
  4007. wl_linfo[i].client_cnt > 1)
  4008. client_joined = true;
  4009. }
  4010. wl_rinfo->role_map.val |= BIT(wl_linfo[i].role);
  4011. wl_rinfo->active_role[cnt_active - 1].ch = wl_linfo[i].ch;
  4012. wl_rinfo->active_role[cnt_active - 1].bw = wl_linfo[i].bw;
  4013. wl_rinfo->active_role[cnt_active - 1].connected = 1;
  4014. /* only care 2 roles + BT coex */
  4015. if (wl_linfo[i].band != RTW89_BAND_2G) {
  4016. if (cnt_5g <= ARRAY_SIZE(wl_5g_ch) - 1)
  4017. wl_5g_ch[cnt_5g] = wl_linfo[i].ch;
  4018. cnt_5g++;
  4019. b5g = true;
  4020. } else {
  4021. if (cnt_2g <= ARRAY_SIZE(wl_2g_ch) - 1)
  4022. wl_2g_ch[cnt_2g] = wl_linfo[i].ch;
  4023. cnt_2g++;
  4024. b2g = true;
  4025. }
  4026. }
  4027. wl_rinfo->connect_cnt = cnt_connect;
  4028. /* Be careful to change the following sequence!! */
  4029. if (cnt_connect == 0) {
  4030. wl_rinfo->link_mode = BTC_WLINK_NOLINK;
  4031. wl_rinfo->role_map.role.none = 1;
  4032. } else if (!b2g && b5g) {
  4033. wl_rinfo->link_mode = BTC_WLINK_5G;
  4034. } else if (wl_rinfo->role_map.role.nan) {
  4035. wl_rinfo->link_mode = BTC_WLINK_2G_NAN;
  4036. } else if (cnt_connect > BTC_TDMA_WLROLE_MAX) {
  4037. wl_rinfo->link_mode = BTC_WLINK_OTHER;
  4038. } else if (b2g && b5g && cnt_connect == 2) {
  4039. if (rtwdev->dbcc_en) {
  4040. switch (wl_dinfo->role[RTW89_PHY_0]) {
  4041. case RTW89_WIFI_ROLE_STATION:
  4042. wl_rinfo->link_mode = BTC_WLINK_2G_STA;
  4043. break;
  4044. case RTW89_WIFI_ROLE_P2P_GO:
  4045. wl_rinfo->link_mode = BTC_WLINK_2G_GO;
  4046. break;
  4047. case RTW89_WIFI_ROLE_P2P_CLIENT:
  4048. wl_rinfo->link_mode = BTC_WLINK_2G_GC;
  4049. break;
  4050. case RTW89_WIFI_ROLE_AP:
  4051. wl_rinfo->link_mode = BTC_WLINK_2G_AP;
  4052. break;
  4053. default:
  4054. wl_rinfo->link_mode = BTC_WLINK_OTHER;
  4055. break;
  4056. }
  4057. } else {
  4058. wl_rinfo->link_mode = BTC_WLINK_25G_MCC;
  4059. }
  4060. } else if (!b5g && cnt_connect == 2) {
  4061. if (wl_rinfo->role_map.role.station &&
  4062. (wl_rinfo->role_map.role.p2p_go ||
  4063. wl_rinfo->role_map.role.p2p_gc ||
  4064. wl_rinfo->role_map.role.ap)) {
  4065. if (wl_2g_ch[0] == wl_2g_ch[1])
  4066. wl_rinfo->link_mode = BTC_WLINK_2G_SCC;
  4067. else
  4068. wl_rinfo->link_mode = BTC_WLINK_2G_MCC;
  4069. } else {
  4070. wl_rinfo->link_mode = BTC_WLINK_2G_MCC;
  4071. }
  4072. } else if (!b5g && cnt_connect == 1) {
  4073. if (wl_rinfo->role_map.role.station)
  4074. wl_rinfo->link_mode = BTC_WLINK_2G_STA;
  4075. else if (wl_rinfo->role_map.role.ap)
  4076. wl_rinfo->link_mode = BTC_WLINK_2G_AP;
  4077. else if (wl_rinfo->role_map.role.p2p_go)
  4078. wl_rinfo->link_mode = BTC_WLINK_2G_GO;
  4079. else if (wl_rinfo->role_map.role.p2p_gc)
  4080. wl_rinfo->link_mode = BTC_WLINK_2G_GC;
  4081. else
  4082. wl_rinfo->link_mode = BTC_WLINK_OTHER;
  4083. }
  4084. /* if no client_joined, don't care P2P-GO/AP role */
  4085. if (wl_rinfo->role_map.role.p2p_go || wl_rinfo->role_map.role.ap) {
  4086. if (!client_joined) {
  4087. if (wl_rinfo->link_mode == BTC_WLINK_2G_SCC ||
  4088. wl_rinfo->link_mode == BTC_WLINK_2G_MCC) {
  4089. wl_rinfo->link_mode = BTC_WLINK_2G_STA;
  4090. wl_rinfo->connect_cnt = 1;
  4091. } else if (wl_rinfo->link_mode == BTC_WLINK_2G_GO ||
  4092. wl_rinfo->link_mode == BTC_WLINK_2G_AP) {
  4093. wl_rinfo->link_mode = BTC_WLINK_NOLINK;
  4094. wl_rinfo->connect_cnt = 0;
  4095. }
  4096. }
  4097. }
  4098. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  4099. "[BTC], cnt_connect = %d, connecting = %d, link_mode = %d\n",
  4100. cnt_connect, cnt_connecting, wl_rinfo->link_mode);
  4101. _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE);
  4102. }
  4103. static void _update_wl_info_v1(struct rtw89_dev *rtwdev)
  4104. {
  4105. struct rtw89_btc *btc = &rtwdev->btc;
  4106. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  4107. struct rtw89_btc_wl_link_info *wl_linfo = wl->link_info;
  4108. struct rtw89_btc_wl_role_info_v1 *wl_rinfo = &wl->role_info_v1;
  4109. struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
  4110. u8 cnt_connect = 0, cnt_connecting = 0, cnt_active = 0;
  4111. u8 cnt_2g = 0, cnt_5g = 0, phy;
  4112. u32 wl_2g_ch[2] = {}, wl_5g_ch[2] = {};
  4113. bool b2g = false, b5g = false, client_joined = false;
  4114. u8 i;
  4115. memset(wl_rinfo, 0, sizeof(*wl_rinfo));
  4116. for (i = 0; i < RTW89_PORT_NUM; i++) {
  4117. if (!wl_linfo[i].active)
  4118. continue;
  4119. cnt_active++;
  4120. wl_rinfo->active_role_v1[cnt_active - 1].role = wl_linfo[i].role;
  4121. wl_rinfo->active_role_v1[cnt_active - 1].pid = wl_linfo[i].pid;
  4122. wl_rinfo->active_role_v1[cnt_active - 1].phy = wl_linfo[i].phy;
  4123. wl_rinfo->active_role_v1[cnt_active - 1].band = wl_linfo[i].band;
  4124. wl_rinfo->active_role_v1[cnt_active - 1].noa = (u8)wl_linfo[i].noa;
  4125. wl_rinfo->active_role_v1[cnt_active - 1].connected = 0;
  4126. wl->port_id[wl_linfo[i].role] = wl_linfo[i].pid;
  4127. phy = wl_linfo[i].phy;
  4128. if (rtwdev->dbcc_en && phy < RTW89_PHY_MAX) {
  4129. wl_dinfo->role[phy] = wl_linfo[i].role;
  4130. wl_dinfo->op_band[phy] = wl_linfo[i].band;
  4131. _update_dbcc_band(rtwdev, phy);
  4132. _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC);
  4133. }
  4134. if (wl_linfo[i].connected == MLME_NO_LINK) {
  4135. continue;
  4136. } else if (wl_linfo[i].connected == MLME_LINKING) {
  4137. cnt_connecting++;
  4138. } else {
  4139. cnt_connect++;
  4140. if ((wl_linfo[i].role == RTW89_WIFI_ROLE_P2P_GO ||
  4141. wl_linfo[i].role == RTW89_WIFI_ROLE_AP) &&
  4142. wl_linfo[i].client_cnt > 1)
  4143. client_joined = true;
  4144. }
  4145. wl_rinfo->role_map.val |= BIT(wl_linfo[i].role);
  4146. wl_rinfo->active_role_v1[cnt_active - 1].ch = wl_linfo[i].ch;
  4147. wl_rinfo->active_role_v1[cnt_active - 1].bw = wl_linfo[i].bw;
  4148. wl_rinfo->active_role_v1[cnt_active - 1].connected = 1;
  4149. /* only care 2 roles + BT coex */
  4150. if (wl_linfo[i].band != RTW89_BAND_2G) {
  4151. if (cnt_5g <= ARRAY_SIZE(wl_5g_ch) - 1)
  4152. wl_5g_ch[cnt_5g] = wl_linfo[i].ch;
  4153. cnt_5g++;
  4154. b5g = true;
  4155. } else {
  4156. if (cnt_2g <= ARRAY_SIZE(wl_2g_ch) - 1)
  4157. wl_2g_ch[cnt_2g] = wl_linfo[i].ch;
  4158. cnt_2g++;
  4159. b2g = true;
  4160. }
  4161. }
  4162. wl_rinfo->connect_cnt = cnt_connect;
  4163. /* Be careful to change the following sequence!! */
  4164. if (cnt_connect == 0) {
  4165. wl_rinfo->link_mode = BTC_WLINK_NOLINK;
  4166. wl_rinfo->role_map.role.none = 1;
  4167. } else if (!b2g && b5g) {
  4168. wl_rinfo->link_mode = BTC_WLINK_5G;
  4169. } else if (wl_rinfo->role_map.role.nan) {
  4170. wl_rinfo->link_mode = BTC_WLINK_2G_NAN;
  4171. } else if (cnt_connect > BTC_TDMA_WLROLE_MAX) {
  4172. wl_rinfo->link_mode = BTC_WLINK_OTHER;
  4173. } else if (b2g && b5g && cnt_connect == 2) {
  4174. if (rtwdev->dbcc_en) {
  4175. switch (wl_dinfo->role[RTW89_PHY_0]) {
  4176. case RTW89_WIFI_ROLE_STATION:
  4177. wl_rinfo->link_mode = BTC_WLINK_2G_STA;
  4178. break;
  4179. case RTW89_WIFI_ROLE_P2P_GO:
  4180. wl_rinfo->link_mode = BTC_WLINK_2G_GO;
  4181. break;
  4182. case RTW89_WIFI_ROLE_P2P_CLIENT:
  4183. wl_rinfo->link_mode = BTC_WLINK_2G_GC;
  4184. break;
  4185. case RTW89_WIFI_ROLE_AP:
  4186. wl_rinfo->link_mode = BTC_WLINK_2G_AP;
  4187. break;
  4188. default:
  4189. wl_rinfo->link_mode = BTC_WLINK_OTHER;
  4190. break;
  4191. }
  4192. } else {
  4193. wl_rinfo->link_mode = BTC_WLINK_25G_MCC;
  4194. }
  4195. } else if (!b5g && cnt_connect == 2) {
  4196. if (wl_rinfo->role_map.role.station &&
  4197. (wl_rinfo->role_map.role.p2p_go ||
  4198. wl_rinfo->role_map.role.p2p_gc ||
  4199. wl_rinfo->role_map.role.ap)) {
  4200. if (wl_2g_ch[0] == wl_2g_ch[1])
  4201. wl_rinfo->link_mode = BTC_WLINK_2G_SCC;
  4202. else
  4203. wl_rinfo->link_mode = BTC_WLINK_2G_MCC;
  4204. } else {
  4205. wl_rinfo->link_mode = BTC_WLINK_2G_MCC;
  4206. }
  4207. } else if (!b5g && cnt_connect == 1) {
  4208. if (wl_rinfo->role_map.role.station)
  4209. wl_rinfo->link_mode = BTC_WLINK_2G_STA;
  4210. else if (wl_rinfo->role_map.role.ap)
  4211. wl_rinfo->link_mode = BTC_WLINK_2G_AP;
  4212. else if (wl_rinfo->role_map.role.p2p_go)
  4213. wl_rinfo->link_mode = BTC_WLINK_2G_GO;
  4214. else if (wl_rinfo->role_map.role.p2p_gc)
  4215. wl_rinfo->link_mode = BTC_WLINK_2G_GC;
  4216. else
  4217. wl_rinfo->link_mode = BTC_WLINK_OTHER;
  4218. }
  4219. /* if no client_joined, don't care P2P-GO/AP role */
  4220. if (wl_rinfo->role_map.role.p2p_go || wl_rinfo->role_map.role.ap) {
  4221. if (!client_joined) {
  4222. if (wl_rinfo->link_mode == BTC_WLINK_2G_SCC ||
  4223. wl_rinfo->link_mode == BTC_WLINK_2G_MCC) {
  4224. wl_rinfo->link_mode = BTC_WLINK_2G_STA;
  4225. wl_rinfo->connect_cnt = 1;
  4226. } else if (wl_rinfo->link_mode == BTC_WLINK_2G_GO ||
  4227. wl_rinfo->link_mode == BTC_WLINK_2G_AP) {
  4228. wl_rinfo->link_mode = BTC_WLINK_NOLINK;
  4229. wl_rinfo->connect_cnt = 0;
  4230. }
  4231. }
  4232. }
  4233. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  4234. "[BTC], cnt_connect = %d, connecting = %d, link_mode = %d\n",
  4235. cnt_connect, cnt_connecting, wl_rinfo->link_mode);
  4236. _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE);
  4237. }
  4238. static void _update_wl_info_v2(struct rtw89_dev *rtwdev)
  4239. {
  4240. struct rtw89_btc *btc = &rtwdev->btc;
  4241. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  4242. struct rtw89_btc_wl_link_info *wl_linfo = wl->link_info;
  4243. struct rtw89_btc_wl_role_info_v2 *wl_rinfo = &wl->role_info_v2;
  4244. struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
  4245. u8 cnt_connect = 0, cnt_connecting = 0, cnt_active = 0;
  4246. u8 cnt_2g = 0, cnt_5g = 0, phy;
  4247. u32 wl_2g_ch[2] = {}, wl_5g_ch[2] = {};
  4248. bool b2g = false, b5g = false, client_joined = false;
  4249. u8 i;
  4250. memset(wl_rinfo, 0, sizeof(*wl_rinfo));
  4251. for (i = 0; i < RTW89_PORT_NUM; i++) {
  4252. if (!wl_linfo[i].active)
  4253. continue;
  4254. cnt_active++;
  4255. wl_rinfo->active_role_v2[cnt_active - 1].role = wl_linfo[i].role;
  4256. wl_rinfo->active_role_v2[cnt_active - 1].pid = wl_linfo[i].pid;
  4257. wl_rinfo->active_role_v2[cnt_active - 1].phy = wl_linfo[i].phy;
  4258. wl_rinfo->active_role_v2[cnt_active - 1].band = wl_linfo[i].band;
  4259. wl_rinfo->active_role_v2[cnt_active - 1].noa = (u8)wl_linfo[i].noa;
  4260. wl_rinfo->active_role_v2[cnt_active - 1].connected = 0;
  4261. wl->port_id[wl_linfo[i].role] = wl_linfo[i].pid;
  4262. phy = wl_linfo[i].phy;
  4263. if (rtwdev->dbcc_en && phy < RTW89_PHY_MAX) {
  4264. wl_dinfo->role[phy] = wl_linfo[i].role;
  4265. wl_dinfo->op_band[phy] = wl_linfo[i].band;
  4266. _update_dbcc_band(rtwdev, phy);
  4267. _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC);
  4268. }
  4269. if (wl_linfo[i].connected == MLME_NO_LINK) {
  4270. continue;
  4271. } else if (wl_linfo[i].connected == MLME_LINKING) {
  4272. cnt_connecting++;
  4273. } else {
  4274. cnt_connect++;
  4275. if ((wl_linfo[i].role == RTW89_WIFI_ROLE_P2P_GO ||
  4276. wl_linfo[i].role == RTW89_WIFI_ROLE_AP) &&
  4277. wl_linfo[i].client_cnt > 1)
  4278. client_joined = true;
  4279. }
  4280. wl_rinfo->role_map.val |= BIT(wl_linfo[i].role);
  4281. wl_rinfo->active_role_v2[cnt_active - 1].ch = wl_linfo[i].ch;
  4282. wl_rinfo->active_role_v2[cnt_active - 1].bw = wl_linfo[i].bw;
  4283. wl_rinfo->active_role_v2[cnt_active - 1].connected = 1;
  4284. /* only care 2 roles + BT coex */
  4285. if (wl_linfo[i].band != RTW89_BAND_2G) {
  4286. if (cnt_5g <= ARRAY_SIZE(wl_5g_ch) - 1)
  4287. wl_5g_ch[cnt_5g] = wl_linfo[i].ch;
  4288. cnt_5g++;
  4289. b5g = true;
  4290. } else {
  4291. if (cnt_2g <= ARRAY_SIZE(wl_2g_ch) - 1)
  4292. wl_2g_ch[cnt_2g] = wl_linfo[i].ch;
  4293. cnt_2g++;
  4294. b2g = true;
  4295. }
  4296. }
  4297. wl_rinfo->connect_cnt = cnt_connect;
  4298. /* Be careful to change the following sequence!! */
  4299. if (cnt_connect == 0) {
  4300. wl_rinfo->link_mode = BTC_WLINK_NOLINK;
  4301. wl_rinfo->role_map.role.none = 1;
  4302. } else if (!b2g && b5g) {
  4303. wl_rinfo->link_mode = BTC_WLINK_5G;
  4304. } else if (wl_rinfo->role_map.role.nan) {
  4305. wl_rinfo->link_mode = BTC_WLINK_2G_NAN;
  4306. } else if (cnt_connect > BTC_TDMA_WLROLE_MAX) {
  4307. wl_rinfo->link_mode = BTC_WLINK_OTHER;
  4308. } else if (b2g && b5g && cnt_connect == 2) {
  4309. if (rtwdev->dbcc_en) {
  4310. switch (wl_dinfo->role[RTW89_PHY_0]) {
  4311. case RTW89_WIFI_ROLE_STATION:
  4312. wl_rinfo->link_mode = BTC_WLINK_2G_STA;
  4313. break;
  4314. case RTW89_WIFI_ROLE_P2P_GO:
  4315. wl_rinfo->link_mode = BTC_WLINK_2G_GO;
  4316. break;
  4317. case RTW89_WIFI_ROLE_P2P_CLIENT:
  4318. wl_rinfo->link_mode = BTC_WLINK_2G_GC;
  4319. break;
  4320. case RTW89_WIFI_ROLE_AP:
  4321. wl_rinfo->link_mode = BTC_WLINK_2G_AP;
  4322. break;
  4323. default:
  4324. wl_rinfo->link_mode = BTC_WLINK_OTHER;
  4325. break;
  4326. }
  4327. } else {
  4328. wl_rinfo->link_mode = BTC_WLINK_25G_MCC;
  4329. }
  4330. } else if (!b5g && cnt_connect == 2) {
  4331. if (wl_rinfo->role_map.role.station &&
  4332. (wl_rinfo->role_map.role.p2p_go ||
  4333. wl_rinfo->role_map.role.p2p_gc ||
  4334. wl_rinfo->role_map.role.ap)) {
  4335. if (wl_2g_ch[0] == wl_2g_ch[1])
  4336. wl_rinfo->link_mode = BTC_WLINK_2G_SCC;
  4337. else
  4338. wl_rinfo->link_mode = BTC_WLINK_2G_MCC;
  4339. } else {
  4340. wl_rinfo->link_mode = BTC_WLINK_2G_MCC;
  4341. }
  4342. } else if (!b5g && cnt_connect == 1) {
  4343. if (wl_rinfo->role_map.role.station)
  4344. wl_rinfo->link_mode = BTC_WLINK_2G_STA;
  4345. else if (wl_rinfo->role_map.role.ap)
  4346. wl_rinfo->link_mode = BTC_WLINK_2G_AP;
  4347. else if (wl_rinfo->role_map.role.p2p_go)
  4348. wl_rinfo->link_mode = BTC_WLINK_2G_GO;
  4349. else if (wl_rinfo->role_map.role.p2p_gc)
  4350. wl_rinfo->link_mode = BTC_WLINK_2G_GC;
  4351. else
  4352. wl_rinfo->link_mode = BTC_WLINK_OTHER;
  4353. }
  4354. /* if no client_joined, don't care P2P-GO/AP role */
  4355. if (wl_rinfo->role_map.role.p2p_go || wl_rinfo->role_map.role.ap) {
  4356. if (!client_joined) {
  4357. if (wl_rinfo->link_mode == BTC_WLINK_2G_SCC ||
  4358. wl_rinfo->link_mode == BTC_WLINK_2G_MCC) {
  4359. wl_rinfo->link_mode = BTC_WLINK_2G_STA;
  4360. wl_rinfo->connect_cnt = 1;
  4361. } else if (wl_rinfo->link_mode == BTC_WLINK_2G_GO ||
  4362. wl_rinfo->link_mode == BTC_WLINK_2G_AP) {
  4363. wl_rinfo->link_mode = BTC_WLINK_NOLINK;
  4364. wl_rinfo->connect_cnt = 0;
  4365. }
  4366. }
  4367. }
  4368. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  4369. "[BTC], cnt_connect = %d, connecting = %d, link_mode = %d\n",
  4370. cnt_connect, cnt_connecting, wl_rinfo->link_mode);
  4371. _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE);
  4372. }
  4373. #define BTC_CHK_HANG_MAX 3
  4374. #define BTC_SCB_INV_VALUE GENMASK(31, 0)
  4375. void rtw89_coex_act1_work(struct work_struct *work)
  4376. {
  4377. struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
  4378. coex_act1_work.work);
  4379. struct rtw89_btc *btc = &rtwdev->btc;
  4380. struct rtw89_btc_dm *dm = &rtwdev->btc.dm;
  4381. struct rtw89_btc_cx *cx = &btc->cx;
  4382. struct rtw89_btc_wl_info *wl = &cx->wl;
  4383. mutex_lock(&rtwdev->mutex);
  4384. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): enter\n", __func__);
  4385. dm->cnt_notify[BTC_NCNT_TIMER]++;
  4386. if (wl->status.map._4way)
  4387. wl->status.map._4way = false;
  4388. if (wl->status.map.connecting)
  4389. wl->status.map.connecting = false;
  4390. _run_coex(rtwdev, BTC_RSN_ACT1_WORK);
  4391. mutex_unlock(&rtwdev->mutex);
  4392. }
  4393. void rtw89_coex_bt_devinfo_work(struct work_struct *work)
  4394. {
  4395. struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
  4396. coex_bt_devinfo_work.work);
  4397. struct rtw89_btc *btc = &rtwdev->btc;
  4398. struct rtw89_btc_dm *dm = &rtwdev->btc.dm;
  4399. struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc;
  4400. mutex_lock(&rtwdev->mutex);
  4401. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): enter\n", __func__);
  4402. dm->cnt_notify[BTC_NCNT_TIMER]++;
  4403. a2dp->play_latency = 0;
  4404. _run_coex(rtwdev, BTC_RSN_BT_DEVINFO_WORK);
  4405. mutex_unlock(&rtwdev->mutex);
  4406. }
  4407. void rtw89_coex_rfk_chk_work(struct work_struct *work)
  4408. {
  4409. struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
  4410. coex_rfk_chk_work.work);
  4411. struct rtw89_btc *btc = &rtwdev->btc;
  4412. struct rtw89_btc_dm *dm = &rtwdev->btc.dm;
  4413. struct rtw89_btc_cx *cx = &btc->cx;
  4414. struct rtw89_btc_wl_info *wl = &cx->wl;
  4415. mutex_lock(&rtwdev->mutex);
  4416. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): enter\n", __func__);
  4417. dm->cnt_notify[BTC_NCNT_TIMER]++;
  4418. if (wl->rfk_info.state != BTC_WRFK_STOP) {
  4419. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  4420. "[BTC], %s(): RFK timeout\n", __func__);
  4421. cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]++;
  4422. dm->error.map.wl_rfk_timeout = true;
  4423. wl->rfk_info.state = BTC_WRFK_STOP;
  4424. _write_scbd(rtwdev, BTC_WSCB_WLRFK, false);
  4425. _run_coex(rtwdev, BTC_RSN_RFK_CHK_WORK);
  4426. }
  4427. mutex_unlock(&rtwdev->mutex);
  4428. }
  4429. static void _update_bt_scbd(struct rtw89_dev *rtwdev, bool only_update)
  4430. {
  4431. const struct rtw89_chip_info *chip = rtwdev->chip;
  4432. struct rtw89_btc *btc = &rtwdev->btc;
  4433. struct rtw89_btc_cx *cx = &btc->cx;
  4434. struct rtw89_btc_bt_info *bt = &btc->cx.bt;
  4435. u32 val;
  4436. bool status_change = false;
  4437. if (!chip->scbd)
  4438. return;
  4439. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s\n", __func__);
  4440. val = _read_scbd(rtwdev);
  4441. if (val == BTC_SCB_INV_VALUE) {
  4442. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  4443. "[BTC], %s(): return by invalid scbd value\n",
  4444. __func__);
  4445. return;
  4446. }
  4447. if (!(val & BTC_BSCB_ON) ||
  4448. btc->dm.cnt_dm[BTC_DCNT_BTCNT_HANG] >= BTC_CHK_HANG_MAX)
  4449. bt->enable.now = 0;
  4450. else
  4451. bt->enable.now = 1;
  4452. if (bt->enable.now != bt->enable.last)
  4453. status_change = true;
  4454. /* reset bt info if bt re-enable */
  4455. if (bt->enable.now && !bt->enable.last) {
  4456. _reset_btc_var(rtwdev, BTC_RESET_BTINFO);
  4457. cx->cnt_bt[BTC_BCNT_REENABLE]++;
  4458. bt->enable.now = 1;
  4459. }
  4460. bt->enable.last = bt->enable.now;
  4461. bt->scbd = val;
  4462. bt->mbx_avl = !!(val & BTC_BSCB_ACT);
  4463. if (bt->whql_test != !!(val & BTC_BSCB_WHQL))
  4464. status_change = true;
  4465. bt->whql_test = !!(val & BTC_BSCB_WHQL);
  4466. bt->btg_type = val & BTC_BSCB_BT_S1 ? BTC_BT_BTG : BTC_BT_ALONE;
  4467. bt->link_info.a2dp_desc.exist = !!(val & BTC_BSCB_A2DP_ACT);
  4468. /* if rfk run 1->0 */
  4469. if (bt->rfk_info.map.run && !(val & BTC_BSCB_RFK_RUN))
  4470. status_change = true;
  4471. bt->rfk_info.map.run = !!(val & BTC_BSCB_RFK_RUN);
  4472. bt->rfk_info.map.req = !!(val & BTC_BSCB_RFK_REQ);
  4473. bt->hi_lna_rx = !!(val & BTC_BSCB_BT_HILNA);
  4474. bt->link_info.status.map.connect = !!(val & BTC_BSCB_BT_CONNECT);
  4475. bt->run_patch_code = !!(val & BTC_BSCB_PATCH_CODE);
  4476. if (!only_update && status_change)
  4477. _run_coex(rtwdev, BTC_RSN_UPDATE_BT_SCBD);
  4478. }
  4479. static bool _chk_wl_rfk_request(struct rtw89_dev *rtwdev)
  4480. {
  4481. struct rtw89_btc *btc = &rtwdev->btc;
  4482. struct rtw89_btc_cx *cx = &btc->cx;
  4483. struct rtw89_btc_bt_info *bt = &cx->bt;
  4484. _update_bt_scbd(rtwdev, true);
  4485. cx->cnt_wl[BTC_WCNT_RFK_REQ]++;
  4486. if ((bt->rfk_info.map.run || bt->rfk_info.map.req) &&
  4487. !bt->rfk_info.map.timeout) {
  4488. cx->cnt_wl[BTC_WCNT_RFK_REJECT]++;
  4489. } else {
  4490. cx->cnt_wl[BTC_WCNT_RFK_GO]++;
  4491. return true;
  4492. }
  4493. return false;
  4494. }
  4495. static
  4496. void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
  4497. {
  4498. struct rtw89_btc *btc = &rtwdev->btc;
  4499. const struct rtw89_btc_ver *ver = btc->ver;
  4500. struct rtw89_btc_dm *dm = &rtwdev->btc.dm;
  4501. struct rtw89_btc_cx *cx = &btc->cx;
  4502. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  4503. struct rtw89_btc_bt_info *bt = &btc->cx.bt;
  4504. struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
  4505. struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1;
  4506. struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2;
  4507. u8 mode;
  4508. lockdep_assert_held(&rtwdev->mutex);
  4509. dm->run_reason = reason;
  4510. _update_dm_step(rtwdev, reason);
  4511. _update_btc_state_map(rtwdev);
  4512. if (ver->fwlrole == 0)
  4513. mode = wl_rinfo->link_mode;
  4514. else if (ver->fwlrole == 1)
  4515. mode = wl_rinfo_v1->link_mode;
  4516. else if (ver->fwlrole == 2)
  4517. mode = wl_rinfo_v2->link_mode;
  4518. else
  4519. return;
  4520. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): reason=%d, mode=%d\n",
  4521. __func__, reason, mode);
  4522. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): wl_only=%d, bt_only=%d\n",
  4523. __func__, dm->wl_only, dm->bt_only);
  4524. /* Be careful to change the following function sequence!! */
  4525. if (btc->ctrl.manual) {
  4526. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  4527. "[BTC], %s(): return for Manual CTRL!!\n",
  4528. __func__);
  4529. return;
  4530. }
  4531. if (btc->ctrl.igno_bt &&
  4532. (reason == BTC_RSN_UPDATE_BT_INFO ||
  4533. reason == BTC_RSN_UPDATE_BT_SCBD)) {
  4534. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  4535. "[BTC], %s(): return for Stop Coex DM!!\n",
  4536. __func__);
  4537. return;
  4538. }
  4539. if (!wl->status.map.init_ok) {
  4540. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  4541. "[BTC], %s(): return for WL init fail!!\n",
  4542. __func__);
  4543. return;
  4544. }
  4545. if (wl->status.map.rf_off_pre == wl->status.map.rf_off &&
  4546. wl->status.map.lps_pre == wl->status.map.lps &&
  4547. (reason == BTC_RSN_NTFY_POWEROFF ||
  4548. reason == BTC_RSN_NTFY_RADIO_STATE)) {
  4549. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  4550. "[BTC], %s(): return for WL rf off state no change!!\n",
  4551. __func__);
  4552. return;
  4553. }
  4554. dm->cnt_dm[BTC_DCNT_RUN]++;
  4555. dm->fddt_train = BTC_FDDT_DISABLE;
  4556. if (btc->ctrl.always_freerun) {
  4557. _action_freerun(rtwdev);
  4558. btc->ctrl.igno_bt = true;
  4559. goto exit;
  4560. }
  4561. if (dm->wl_only) {
  4562. _action_wl_only(rtwdev);
  4563. btc->ctrl.igno_bt = true;
  4564. goto exit;
  4565. }
  4566. if (wl->status.map.rf_off || wl->status.map.lps || dm->bt_only) {
  4567. _action_wl_off(rtwdev);
  4568. btc->ctrl.igno_bt = true;
  4569. goto exit;
  4570. }
  4571. btc->ctrl.igno_bt = false;
  4572. dm->freerun = false;
  4573. bt->scan_rx_low_pri = false;
  4574. if (reason == BTC_RSN_NTFY_INIT) {
  4575. _action_wl_init(rtwdev);
  4576. goto exit;
  4577. }
  4578. if (!cx->bt.enable.now && !cx->other.type) {
  4579. _action_bt_off(rtwdev);
  4580. goto exit;
  4581. }
  4582. if (cx->bt.whql_test) {
  4583. _action_bt_whql(rtwdev);
  4584. goto exit;
  4585. }
  4586. if (wl->rfk_info.state != BTC_WRFK_STOP) {
  4587. _action_wl_rfk(rtwdev);
  4588. goto exit;
  4589. }
  4590. if (cx->state_map == BTC_WLINKING) {
  4591. if (mode == BTC_WLINK_NOLINK || mode == BTC_WLINK_2G_STA ||
  4592. mode == BTC_WLINK_5G) {
  4593. _action_wl_scan(rtwdev);
  4594. goto exit;
  4595. }
  4596. }
  4597. if (wl->status.map.scan) {
  4598. _action_wl_scan(rtwdev);
  4599. goto exit;
  4600. }
  4601. switch (mode) {
  4602. case BTC_WLINK_NOLINK:
  4603. _action_wl_nc(rtwdev);
  4604. break;
  4605. case BTC_WLINK_2G_STA:
  4606. if (wl->status.map.traffic_dir & BIT(RTW89_TFC_DL))
  4607. bt->scan_rx_low_pri = true;
  4608. _action_wl_2g_sta(rtwdev);
  4609. break;
  4610. case BTC_WLINK_2G_AP:
  4611. bt->scan_rx_low_pri = true;
  4612. _action_wl_2g_ap(rtwdev);
  4613. break;
  4614. case BTC_WLINK_2G_GO:
  4615. bt->scan_rx_low_pri = true;
  4616. _action_wl_2g_go(rtwdev);
  4617. break;
  4618. case BTC_WLINK_2G_GC:
  4619. bt->scan_rx_low_pri = true;
  4620. _action_wl_2g_gc(rtwdev);
  4621. break;
  4622. case BTC_WLINK_2G_SCC:
  4623. bt->scan_rx_low_pri = true;
  4624. if (ver->fwlrole == 0)
  4625. _action_wl_2g_scc(rtwdev);
  4626. else if (ver->fwlrole == 1)
  4627. _action_wl_2g_scc_v1(rtwdev);
  4628. else if (ver->fwlrole == 2)
  4629. _action_wl_2g_scc_v2(rtwdev);
  4630. break;
  4631. case BTC_WLINK_2G_MCC:
  4632. bt->scan_rx_low_pri = true;
  4633. _action_wl_2g_mcc(rtwdev);
  4634. break;
  4635. case BTC_WLINK_25G_MCC:
  4636. bt->scan_rx_low_pri = true;
  4637. _action_wl_25g_mcc(rtwdev);
  4638. break;
  4639. case BTC_WLINK_5G:
  4640. _action_wl_5g(rtwdev);
  4641. break;
  4642. case BTC_WLINK_2G_NAN:
  4643. _action_wl_2g_nan(rtwdev);
  4644. break;
  4645. default:
  4646. _action_wl_other(rtwdev);
  4647. break;
  4648. }
  4649. exit:
  4650. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): exit\n", __func__);
  4651. _action_common(rtwdev);
  4652. }
  4653. void rtw89_btc_ntfy_poweron(struct rtw89_dev *rtwdev)
  4654. {
  4655. struct rtw89_btc *btc = &rtwdev->btc;
  4656. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__);
  4657. btc->dm.cnt_notify[BTC_NCNT_POWER_ON]++;
  4658. }
  4659. void rtw89_btc_ntfy_poweroff(struct rtw89_dev *rtwdev)
  4660. {
  4661. struct rtw89_btc *btc = &rtwdev->btc;
  4662. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  4663. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__);
  4664. btc->dm.cnt_notify[BTC_NCNT_POWER_OFF]++;
  4665. btc->cx.wl.status.map.rf_off = 1;
  4666. btc->cx.wl.status.map.busy = 0;
  4667. wl->status.map.lps = BTC_LPS_OFF;
  4668. _write_scbd(rtwdev, BTC_WSCB_ALL, false);
  4669. _run_coex(rtwdev, BTC_RSN_NTFY_POWEROFF);
  4670. rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_ALL, 0);
  4671. btc->cx.wl.status.map.rf_off_pre = btc->cx.wl.status.map.rf_off;
  4672. }
  4673. static void _set_init_info(struct rtw89_dev *rtwdev)
  4674. {
  4675. const struct rtw89_chip_info *chip = rtwdev->chip;
  4676. struct rtw89_btc *btc = &rtwdev->btc;
  4677. struct rtw89_btc_dm *dm = &btc->dm;
  4678. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  4679. dm->init_info.wl_only = (u8)dm->wl_only;
  4680. dm->init_info.bt_only = (u8)dm->bt_only;
  4681. dm->init_info.wl_init_ok = (u8)wl->status.map.init_ok;
  4682. dm->init_info.dbcc_en = rtwdev->dbcc_en;
  4683. dm->init_info.cx_other = btc->cx.other.type;
  4684. dm->init_info.wl_guard_ch = chip->afh_guard_ch;
  4685. dm->init_info.module = btc->mdinfo;
  4686. }
  4687. void rtw89_btc_ntfy_init(struct rtw89_dev *rtwdev, u8 mode)
  4688. {
  4689. struct rtw89_btc *btc = &rtwdev->btc;
  4690. struct rtw89_btc_dm *dm = &rtwdev->btc.dm;
  4691. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  4692. const struct rtw89_chip_info *chip = rtwdev->chip;
  4693. _reset_btc_var(rtwdev, BTC_RESET_ALL);
  4694. btc->dm.run_reason = BTC_RSN_NONE;
  4695. btc->dm.run_action = BTC_ACT_NONE;
  4696. btc->ctrl.igno_bt = true;
  4697. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  4698. "[BTC], %s(): mode=%d\n", __func__, mode);
  4699. dm->cnt_notify[BTC_NCNT_INIT_COEX]++;
  4700. dm->wl_only = mode == BTC_MODE_WL ? 1 : 0;
  4701. dm->bt_only = mode == BTC_MODE_BT ? 1 : 0;
  4702. wl->status.map.rf_off = mode == BTC_MODE_WLOFF ? 1 : 0;
  4703. chip->ops->btc_set_rfe(rtwdev);
  4704. chip->ops->btc_init_cfg(rtwdev);
  4705. if (!wl->status.map.init_ok) {
  4706. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  4707. "[BTC], %s(): return for WL init fail!!\n",
  4708. __func__);
  4709. dm->error.map.init = true;
  4710. return;
  4711. }
  4712. _write_scbd(rtwdev,
  4713. BTC_WSCB_ACTIVE | BTC_WSCB_ON | BTC_WSCB_BTLOG, true);
  4714. _update_bt_scbd(rtwdev, true);
  4715. if (rtw89_mac_get_ctrl_path(rtwdev)) {
  4716. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  4717. "[BTC], %s(): PTA owner warning!!\n",
  4718. __func__);
  4719. dm->error.map.pta_owner = true;
  4720. }
  4721. _set_init_info(rtwdev);
  4722. _set_wl_tx_power(rtwdev, RTW89_BTC_WL_DEF_TX_PWR);
  4723. rtw89_btc_fw_set_slots(rtwdev, CXST_MAX, dm->slot);
  4724. btc_fw_set_monreg(rtwdev);
  4725. _fw_set_drv_info(rtwdev, CXDRVINFO_INIT);
  4726. _fw_set_drv_info(rtwdev, CXDRVINFO_CTRL);
  4727. _run_coex(rtwdev, BTC_RSN_NTFY_INIT);
  4728. }
  4729. void rtw89_btc_ntfy_scan_start(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band)
  4730. {
  4731. struct rtw89_btc *btc = &rtwdev->btc;
  4732. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  4733. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  4734. "[BTC], %s(): phy_idx=%d, band=%d\n",
  4735. __func__, phy_idx, band);
  4736. btc->dm.cnt_notify[BTC_NCNT_SCAN_START]++;
  4737. wl->status.map.scan = true;
  4738. wl->scan_info.band[phy_idx] = band;
  4739. wl->scan_info.phy_map |= BIT(phy_idx);
  4740. _fw_set_drv_info(rtwdev, CXDRVINFO_SCAN);
  4741. if (rtwdev->dbcc_en) {
  4742. wl->dbcc_info.scan_band[phy_idx] = band;
  4743. _update_dbcc_band(rtwdev, phy_idx);
  4744. _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC);
  4745. }
  4746. _run_coex(rtwdev, BTC_RSN_NTFY_SCAN_START);
  4747. }
  4748. void rtw89_btc_ntfy_scan_finish(struct rtw89_dev *rtwdev, u8 phy_idx)
  4749. {
  4750. struct rtw89_btc *btc = &rtwdev->btc;
  4751. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  4752. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  4753. "[BTC], %s(): phy_idx=%d\n", __func__, phy_idx);
  4754. btc->dm.cnt_notify[BTC_NCNT_SCAN_FINISH]++;
  4755. wl->status.map.scan = false;
  4756. wl->scan_info.phy_map &= ~BIT(phy_idx);
  4757. _fw_set_drv_info(rtwdev, CXDRVINFO_SCAN);
  4758. if (rtwdev->dbcc_en) {
  4759. _update_dbcc_band(rtwdev, phy_idx);
  4760. _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC);
  4761. }
  4762. _run_coex(rtwdev, BTC_RSN_NTFY_SCAN_FINISH);
  4763. }
  4764. void rtw89_btc_ntfy_switch_band(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band)
  4765. {
  4766. struct rtw89_btc *btc = &rtwdev->btc;
  4767. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  4768. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  4769. "[BTC], %s(): phy_idx=%d, band=%d\n",
  4770. __func__, phy_idx, band);
  4771. btc->dm.cnt_notify[BTC_NCNT_SWITCH_BAND]++;
  4772. wl->scan_info.band[phy_idx] = band;
  4773. wl->scan_info.phy_map |= BIT(phy_idx);
  4774. _fw_set_drv_info(rtwdev, CXDRVINFO_SCAN);
  4775. if (rtwdev->dbcc_en) {
  4776. wl->dbcc_info.scan_band[phy_idx] = band;
  4777. _update_dbcc_band(rtwdev, phy_idx);
  4778. _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC);
  4779. }
  4780. _run_coex(rtwdev, BTC_RSN_NTFY_SWBAND);
  4781. }
  4782. void rtw89_btc_ntfy_specific_packet(struct rtw89_dev *rtwdev,
  4783. enum btc_pkt_type pkt_type)
  4784. {
  4785. struct rtw89_btc *btc = &rtwdev->btc;
  4786. struct rtw89_btc_cx *cx = &btc->cx;
  4787. struct rtw89_btc_wl_info *wl = &cx->wl;
  4788. struct rtw89_btc_bt_link_info *b = &cx->bt.link_info;
  4789. struct rtw89_btc_bt_hfp_desc *hfp = &b->hfp_desc;
  4790. struct rtw89_btc_bt_hid_desc *hid = &b->hid_desc;
  4791. u32 cnt;
  4792. u32 delay = RTW89_COEX_ACT1_WORK_PERIOD;
  4793. bool delay_work = false;
  4794. switch (pkt_type) {
  4795. case PACKET_DHCP:
  4796. cnt = ++cx->cnt_wl[BTC_WCNT_DHCP];
  4797. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  4798. "[BTC], %s(): DHCP cnt=%d\n", __func__, cnt);
  4799. wl->status.map.connecting = true;
  4800. delay_work = true;
  4801. break;
  4802. case PACKET_EAPOL:
  4803. cnt = ++cx->cnt_wl[BTC_WCNT_EAPOL];
  4804. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  4805. "[BTC], %s(): EAPOL cnt=%d\n", __func__, cnt);
  4806. wl->status.map._4way = true;
  4807. delay_work = true;
  4808. if (hfp->exist || hid->exist)
  4809. delay /= 2;
  4810. break;
  4811. case PACKET_EAPOL_END:
  4812. cnt = ++cx->cnt_wl[BTC_WCNT_EAPOL];
  4813. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  4814. "[BTC], %s(): EAPOL_End cnt=%d\n",
  4815. __func__, cnt);
  4816. wl->status.map._4way = false;
  4817. cancel_delayed_work(&rtwdev->coex_act1_work);
  4818. break;
  4819. case PACKET_ARP:
  4820. cnt = ++cx->cnt_wl[BTC_WCNT_ARP];
  4821. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  4822. "[BTC], %s(): ARP cnt=%d\n", __func__, cnt);
  4823. return;
  4824. case PACKET_ICMP:
  4825. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  4826. "[BTC], %s(): ICMP pkt\n", __func__);
  4827. return;
  4828. default:
  4829. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  4830. "[BTC], %s(): unknown packet type %d\n",
  4831. __func__, pkt_type);
  4832. return;
  4833. }
  4834. if (delay_work) {
  4835. cancel_delayed_work(&rtwdev->coex_act1_work);
  4836. ieee80211_queue_delayed_work(rtwdev->hw,
  4837. &rtwdev->coex_act1_work, delay);
  4838. }
  4839. btc->dm.cnt_notify[BTC_NCNT_SPECIAL_PACKET]++;
  4840. _run_coex(rtwdev, BTC_RSN_NTFY_SPECIFIC_PACKET);
  4841. }
  4842. void rtw89_btc_ntfy_eapol_packet_work(struct work_struct *work)
  4843. {
  4844. struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
  4845. btc.eapol_notify_work);
  4846. mutex_lock(&rtwdev->mutex);
  4847. rtw89_leave_ps_mode(rtwdev);
  4848. rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_EAPOL);
  4849. mutex_unlock(&rtwdev->mutex);
  4850. }
  4851. void rtw89_btc_ntfy_arp_packet_work(struct work_struct *work)
  4852. {
  4853. struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
  4854. btc.arp_notify_work);
  4855. mutex_lock(&rtwdev->mutex);
  4856. rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_ARP);
  4857. mutex_unlock(&rtwdev->mutex);
  4858. }
  4859. void rtw89_btc_ntfy_dhcp_packet_work(struct work_struct *work)
  4860. {
  4861. struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
  4862. btc.dhcp_notify_work);
  4863. mutex_lock(&rtwdev->mutex);
  4864. rtw89_leave_ps_mode(rtwdev);
  4865. rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_DHCP);
  4866. mutex_unlock(&rtwdev->mutex);
  4867. }
  4868. void rtw89_btc_ntfy_icmp_packet_work(struct work_struct *work)
  4869. {
  4870. struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
  4871. btc.icmp_notify_work);
  4872. mutex_lock(&rtwdev->mutex);
  4873. rtw89_leave_ps_mode(rtwdev);
  4874. rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_ICMP);
  4875. mutex_unlock(&rtwdev->mutex);
  4876. }
  4877. #define BT_PROFILE_PROTOCOL_MASK GENMASK(7, 4)
  4878. static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
  4879. {
  4880. const struct rtw89_chip_info *chip = rtwdev->chip;
  4881. struct rtw89_btc *btc = &rtwdev->btc;
  4882. struct rtw89_btc_cx *cx = &btc->cx;
  4883. struct rtw89_btc_bt_info *bt = &cx->bt;
  4884. struct rtw89_btc_bt_link_info *b = &bt->link_info;
  4885. struct rtw89_btc_bt_hfp_desc *hfp = &b->hfp_desc;
  4886. struct rtw89_btc_bt_hid_desc *hid = &b->hid_desc;
  4887. struct rtw89_btc_bt_a2dp_desc *a2dp = &b->a2dp_desc;
  4888. struct rtw89_btc_bt_pan_desc *pan = &b->pan_desc;
  4889. union btc_btinfo btinfo;
  4890. if (buf[BTC_BTINFO_L1] != 6)
  4891. return;
  4892. if (!memcmp(bt->raw_info, buf, BTC_BTINFO_MAX)) {
  4893. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  4894. "[BTC], %s(): return by bt-info duplicate!!\n",
  4895. __func__);
  4896. cx->cnt_bt[BTC_BCNT_INFOSAME]++;
  4897. return;
  4898. }
  4899. memcpy(bt->raw_info, buf, BTC_BTINFO_MAX);
  4900. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  4901. "[BTC], %s(): bt_info[2]=0x%02x\n",
  4902. __func__, bt->raw_info[2]);
  4903. /* reset to mo-connect before update */
  4904. b->status.val = BTC_BLINK_NOCONNECT;
  4905. b->profile_cnt.last = b->profile_cnt.now;
  4906. b->relink.last = b->relink.now;
  4907. a2dp->exist_last = a2dp->exist;
  4908. b->multi_link.last = b->multi_link.now;
  4909. bt->inq_pag.last = bt->inq_pag.now;
  4910. b->profile_cnt.now = 0;
  4911. hid->type = 0;
  4912. /* parse raw info low-Byte2 */
  4913. btinfo.val = bt->raw_info[BTC_BTINFO_L2];
  4914. b->status.map.connect = btinfo.lb2.connect;
  4915. b->status.map.sco_busy = btinfo.lb2.sco_busy;
  4916. b->status.map.acl_busy = btinfo.lb2.acl_busy;
  4917. b->status.map.inq_pag = btinfo.lb2.inq_pag;
  4918. bt->inq_pag.now = btinfo.lb2.inq_pag;
  4919. cx->cnt_bt[BTC_BCNT_INQPAG] += !!(bt->inq_pag.now && !bt->inq_pag.last);
  4920. hfp->exist = btinfo.lb2.hfp;
  4921. b->profile_cnt.now += (u8)hfp->exist;
  4922. hid->exist = btinfo.lb2.hid;
  4923. b->profile_cnt.now += (u8)hid->exist;
  4924. a2dp->exist = btinfo.lb2.a2dp;
  4925. b->profile_cnt.now += (u8)a2dp->exist;
  4926. pan->active = btinfo.lb2.pan;
  4927. btc->dm.trx_info.bt_profile = u32_get_bits(btinfo.val, BT_PROFILE_PROTOCOL_MASK);
  4928. /* parse raw info low-Byte3 */
  4929. btinfo.val = bt->raw_info[BTC_BTINFO_L3];
  4930. if (btinfo.lb3.retry != 0)
  4931. cx->cnt_bt[BTC_BCNT_RETRY]++;
  4932. b->cqddr = btinfo.lb3.cqddr;
  4933. cx->cnt_bt[BTC_BCNT_INQ] += !!(btinfo.lb3.inq && !bt->inq);
  4934. bt->inq = btinfo.lb3.inq;
  4935. cx->cnt_bt[BTC_BCNT_PAGE] += !!(btinfo.lb3.pag && !bt->pag);
  4936. bt->pag = btinfo.lb3.pag;
  4937. b->status.map.mesh_busy = btinfo.lb3.mesh_busy;
  4938. /* parse raw info high-Byte0 */
  4939. btinfo.val = bt->raw_info[BTC_BTINFO_H0];
  4940. /* raw val is dBm unit, translate from -100~ 0dBm to 0~100%*/
  4941. b->rssi = chip->ops->btc_get_bt_rssi(rtwdev, btinfo.hb0.rssi);
  4942. btc->dm.trx_info.bt_rssi = b->rssi;
  4943. /* parse raw info high-Byte1 */
  4944. btinfo.val = bt->raw_info[BTC_BTINFO_H1];
  4945. b->status.map.ble_connect = btinfo.hb1.ble_connect;
  4946. if (btinfo.hb1.ble_connect)
  4947. hid->type |= (hid->exist ? BTC_HID_BLE : BTC_HID_RCU);
  4948. cx->cnt_bt[BTC_BCNT_REINIT] += !!(btinfo.hb1.reinit && !bt->reinit);
  4949. bt->reinit = btinfo.hb1.reinit;
  4950. cx->cnt_bt[BTC_BCNT_RELINK] += !!(btinfo.hb1.relink && !b->relink.now);
  4951. b->relink.now = btinfo.hb1.relink;
  4952. cx->cnt_bt[BTC_BCNT_IGNOWL] += !!(btinfo.hb1.igno_wl && !bt->igno_wl);
  4953. bt->igno_wl = btinfo.hb1.igno_wl;
  4954. if (bt->igno_wl && !cx->wl.status.map.rf_off)
  4955. _set_bt_ignore_wlan_act(rtwdev, false);
  4956. hid->type |= (btinfo.hb1.voice ? BTC_HID_RCU_VOICE : 0);
  4957. bt->ble_scan_en = btinfo.hb1.ble_scan;
  4958. cx->cnt_bt[BTC_BCNT_ROLESW] += !!(btinfo.hb1.role_sw && !b->role_sw);
  4959. b->role_sw = btinfo.hb1.role_sw;
  4960. b->multi_link.now = btinfo.hb1.multi_link;
  4961. /* parse raw info high-Byte2 */
  4962. btinfo.val = bt->raw_info[BTC_BTINFO_H2];
  4963. pan->exist = btinfo.hb2.pan_active;
  4964. b->profile_cnt.now += (u8)pan->exist;
  4965. cx->cnt_bt[BTC_BCNT_AFH] += !!(btinfo.hb2.afh_update && !b->afh_update);
  4966. b->afh_update = btinfo.hb2.afh_update;
  4967. a2dp->active = btinfo.hb2.a2dp_active;
  4968. b->slave_role = btinfo.hb2.slave;
  4969. hid->slot_info = btinfo.hb2.hid_slot;
  4970. hid->pair_cnt = btinfo.hb2.hid_cnt;
  4971. hid->type |= (hid->slot_info == BTC_HID_218 ?
  4972. BTC_HID_218 : BTC_HID_418);
  4973. /* parse raw info high-Byte3 */
  4974. btinfo.val = bt->raw_info[BTC_BTINFO_H3];
  4975. a2dp->bitpool = btinfo.hb3.a2dp_bitpool;
  4976. if (b->tx_3m != (u32)btinfo.hb3.tx_3m)
  4977. cx->cnt_bt[BTC_BCNT_RATECHG]++;
  4978. b->tx_3m = (u32)btinfo.hb3.tx_3m;
  4979. a2dp->sink = btinfo.hb3.a2dp_sink;
  4980. if (!a2dp->exist_last && a2dp->exist) {
  4981. a2dp->vendor_id = 0;
  4982. a2dp->flush_time = 0;
  4983. a2dp->play_latency = 1;
  4984. ieee80211_queue_delayed_work(rtwdev->hw,
  4985. &rtwdev->coex_bt_devinfo_work,
  4986. RTW89_COEX_BT_DEVINFO_WORK_PERIOD);
  4987. }
  4988. _run_coex(rtwdev, BTC_RSN_UPDATE_BT_INFO);
  4989. }
  4990. enum btc_wl_mode {
  4991. BTC_WL_MODE_HT = 0,
  4992. BTC_WL_MODE_VHT = 1,
  4993. BTC_WL_MODE_HE = 2,
  4994. BTC_WL_MODE_NUM,
  4995. };
  4996. void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
  4997. struct rtw89_sta *rtwsta, enum btc_role_state state)
  4998. {
  4999. const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
  5000. rtwvif->sub_entity_idx);
  5001. struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
  5002. struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta);
  5003. struct rtw89_btc *btc = &rtwdev->btc;
  5004. const struct rtw89_btc_ver *ver = btc->ver;
  5005. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  5006. struct rtw89_btc_wl_link_info r = {0};
  5007. struct rtw89_btc_wl_link_info *wlinfo = NULL;
  5008. u8 mode = 0;
  5009. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], state=%d\n", state);
  5010. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  5011. "[BTC], role is STA=%d\n",
  5012. vif->type == NL80211_IFTYPE_STATION);
  5013. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], port=%d\n", rtwvif->port);
  5014. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], band=%d ch=%d bw=%d\n",
  5015. chan->band_type, chan->channel, chan->band_width);
  5016. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], associated=%d\n",
  5017. state == BTC_ROLE_MSTS_STA_CONN_END);
  5018. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  5019. "[BTC], bcn_period=%d dtim_period=%d\n",
  5020. vif->bss_conf.beacon_int, vif->bss_conf.dtim_period);
  5021. if (rtwsta) {
  5022. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], STA mac_id=%d\n",
  5023. rtwsta->mac_id);
  5024. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  5025. "[BTC], STA support HE=%d VHT=%d HT=%d\n",
  5026. #if LINUX_VERSION_CODE < KERNEL_VERSION(5,19,0)
  5027. sta->he_cap.has_he,
  5028. sta->vht_cap.vht_supported,
  5029. sta->ht_cap.ht_supported);
  5030. if (sta->he_cap.has_he)
  5031. mode |= BIT(BTC_WL_MODE_HE);
  5032. if (sta->vht_cap.vht_supported)
  5033. mode |= BIT(BTC_WL_MODE_VHT);
  5034. if (sta->ht_cap.ht_supported)
  5035. mode |= BIT(BTC_WL_MODE_HT);
  5036. #else
  5037. sta->deflink.he_cap.has_he,
  5038. sta->deflink.vht_cap.vht_supported,
  5039. sta->deflink.ht_cap.ht_supported);
  5040. if (sta->deflink.he_cap.has_he)
  5041. mode |= BIT(BTC_WL_MODE_HE);
  5042. if (sta->deflink.vht_cap.vht_supported)
  5043. mode |= BIT(BTC_WL_MODE_VHT);
  5044. if (sta->deflink.ht_cap.ht_supported)
  5045. mode |= BIT(BTC_WL_MODE_HT);
  5046. #endif
  5047. r.mode = mode;
  5048. }
  5049. if (rtwvif->wifi_role >= RTW89_WIFI_ROLE_MLME_MAX)
  5050. return;
  5051. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  5052. "[BTC], wifi_role=%d\n", rtwvif->wifi_role);
  5053. r.role = rtwvif->wifi_role;
  5054. r.phy = rtwvif->phy_idx;
  5055. r.pid = rtwvif->port;
  5056. r.active = true;
  5057. r.connected = MLME_LINKED;
  5058. r.bcn_period = vif->bss_conf.beacon_int;
  5059. r.dtim_period = vif->bss_conf.dtim_period;
  5060. r.band = chan->band_type;
  5061. r.ch = chan->channel;
  5062. r.bw = chan->band_width;
  5063. ether_addr_copy(r.mac_addr, rtwvif->mac_addr);
  5064. if (rtwsta && vif->type == NL80211_IFTYPE_STATION)
  5065. r.mac_id = rtwsta->mac_id;
  5066. btc->dm.cnt_notify[BTC_NCNT_ROLE_INFO]++;
  5067. wlinfo = &wl->link_info[r.pid];
  5068. memcpy(wlinfo, &r, sizeof(*wlinfo));
  5069. if (ver->fwlrole == 0)
  5070. _update_wl_info(rtwdev);
  5071. else if (ver->fwlrole == 1)
  5072. _update_wl_info_v1(rtwdev);
  5073. else if (ver->fwlrole == 2)
  5074. _update_wl_info_v2(rtwdev);
  5075. if (wlinfo->role == RTW89_WIFI_ROLE_STATION &&
  5076. wlinfo->connected == MLME_NO_LINK)
  5077. btc->dm.leak_ap = 0;
  5078. if (state == BTC_ROLE_MSTS_STA_CONN_START)
  5079. wl->status.map.connecting = 1;
  5080. else
  5081. wl->status.map.connecting = 0;
  5082. if (state == BTC_ROLE_MSTS_STA_DIS_CONN)
  5083. wl->status.map._4way = false;
  5084. _run_coex(rtwdev, BTC_RSN_NTFY_ROLE_INFO);
  5085. }
  5086. void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_state)
  5087. {
  5088. const struct rtw89_chip_info *chip = rtwdev->chip;
  5089. struct rtw89_btc *btc = &rtwdev->btc;
  5090. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  5091. u32 val;
  5092. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): rf_state = %d\n",
  5093. __func__, rf_state);
  5094. btc->dm.cnt_notify[BTC_NCNT_RADIO_STATE]++;
  5095. switch (rf_state) {
  5096. case BTC_RFCTRL_WL_OFF:
  5097. wl->status.map.rf_off = 1;
  5098. wl->status.map.lps = BTC_LPS_OFF;
  5099. wl->status.map.busy = 0;
  5100. break;
  5101. case BTC_RFCTRL_FW_CTRL:
  5102. wl->status.map.rf_off = 0;
  5103. wl->status.map.lps = BTC_LPS_RF_OFF;
  5104. wl->status.map.busy = 0;
  5105. break;
  5106. case BTC_RFCTRL_LPS_WL_ON: /* LPS-Protocol (RFon) */
  5107. wl->status.map.rf_off = 0;
  5108. wl->status.map.lps = BTC_LPS_RF_ON;
  5109. wl->status.map.busy = 0;
  5110. break;
  5111. case BTC_RFCTRL_WL_ON:
  5112. default:
  5113. wl->status.map.rf_off = 0;
  5114. wl->status.map.lps = BTC_LPS_OFF;
  5115. break;
  5116. }
  5117. if (rf_state == BTC_RFCTRL_WL_ON) {
  5118. rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_MREG, true);
  5119. val = BTC_WSCB_ACTIVE | BTC_WSCB_ON | BTC_WSCB_BTLOG;
  5120. _write_scbd(rtwdev, val, true);
  5121. _update_bt_scbd(rtwdev, true);
  5122. chip->ops->btc_init_cfg(rtwdev);
  5123. } else {
  5124. rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_ALL, false);
  5125. if (rf_state == BTC_RFCTRL_WL_OFF)
  5126. _write_scbd(rtwdev, BTC_WSCB_ALL, false);
  5127. else if (rf_state == BTC_RFCTRL_LPS_WL_ON &&
  5128. wl->status.map.lps_pre != BTC_LPS_OFF)
  5129. _update_bt_scbd(rtwdev, true);
  5130. }
  5131. btc->dm.cnt_dm[BTC_DCNT_BTCNT_HANG] = 0;
  5132. if (wl->status.map.lps_pre == BTC_LPS_OFF &&
  5133. wl->status.map.lps_pre != wl->status.map.lps)
  5134. btc->dm.tdma_instant_excute = 1;
  5135. else
  5136. btc->dm.tdma_instant_excute = 0;
  5137. _run_coex(rtwdev, BTC_RSN_NTFY_RADIO_STATE);
  5138. btc->dm.tdma_instant_excute = 0;
  5139. wl->status.map.rf_off_pre = wl->status.map.rf_off;
  5140. wl->status.map.lps_pre = wl->status.map.lps;
  5141. }
  5142. static bool _ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_path,
  5143. enum btc_wl_rfk_type type,
  5144. enum btc_wl_rfk_state state)
  5145. {
  5146. struct rtw89_btc *btc = &rtwdev->btc;
  5147. struct rtw89_btc_cx *cx = &btc->cx;
  5148. struct rtw89_btc_wl_info *wl = &cx->wl;
  5149. bool result = BTC_WRFK_REJECT;
  5150. wl->rfk_info.type = type;
  5151. wl->rfk_info.path_map = FIELD_GET(BTC_RFK_PATH_MAP, phy_path);
  5152. wl->rfk_info.phy_map = FIELD_GET(BTC_RFK_PHY_MAP, phy_path);
  5153. wl->rfk_info.band = FIELD_GET(BTC_RFK_BAND_MAP, phy_path);
  5154. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  5155. "[BTC], %s()_start: phy=0x%x, path=0x%x, type=%d, state=%d\n",
  5156. __func__, wl->rfk_info.phy_map, wl->rfk_info.path_map,
  5157. type, state);
  5158. switch (state) {
  5159. case BTC_WRFK_START:
  5160. result = _chk_wl_rfk_request(rtwdev);
  5161. wl->rfk_info.state = result ? BTC_WRFK_START : BTC_WRFK_STOP;
  5162. _write_scbd(rtwdev, BTC_WSCB_WLRFK, result);
  5163. btc->dm.cnt_notify[BTC_NCNT_WL_RFK]++;
  5164. break;
  5165. case BTC_WRFK_ONESHOT_START:
  5166. case BTC_WRFK_ONESHOT_STOP:
  5167. if (wl->rfk_info.state == BTC_WRFK_STOP) {
  5168. result = BTC_WRFK_REJECT;
  5169. } else {
  5170. result = BTC_WRFK_ALLOW;
  5171. wl->rfk_info.state = state;
  5172. }
  5173. break;
  5174. case BTC_WRFK_STOP:
  5175. result = BTC_WRFK_ALLOW;
  5176. wl->rfk_info.state = BTC_WRFK_STOP;
  5177. _write_scbd(rtwdev, BTC_WSCB_WLRFK, false);
  5178. cancel_delayed_work(&rtwdev->coex_rfk_chk_work);
  5179. break;
  5180. default:
  5181. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  5182. "[BTC], %s() warning state=%d\n", __func__, state);
  5183. break;
  5184. }
  5185. if (result == BTC_WRFK_ALLOW) {
  5186. if (wl->rfk_info.state == BTC_WRFK_START ||
  5187. wl->rfk_info.state == BTC_WRFK_STOP)
  5188. _run_coex(rtwdev, BTC_RSN_NTFY_WL_RFK);
  5189. if (wl->rfk_info.state == BTC_WRFK_START)
  5190. ieee80211_queue_delayed_work(rtwdev->hw,
  5191. &rtwdev->coex_rfk_chk_work,
  5192. RTW89_COEX_RFK_CHK_WORK_PERIOD);
  5193. }
  5194. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  5195. "[BTC], %s()_finish: rfk_cnt=%d, result=%d\n",
  5196. __func__, btc->dm.cnt_notify[BTC_NCNT_WL_RFK], result);
  5197. return result == BTC_WRFK_ALLOW;
  5198. }
  5199. void rtw89_btc_ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_map,
  5200. enum btc_wl_rfk_type type,
  5201. enum btc_wl_rfk_state state)
  5202. {
  5203. u8 band;
  5204. bool allow;
  5205. int ret;
  5206. band = FIELD_GET(BTC_RFK_BAND_MAP, phy_map);
  5207. rtw89_debug(rtwdev, RTW89_DBG_RFK,
  5208. "[RFK] RFK notify (%s / PHY%u / K_type = %u / path_idx = %lu / process = %s)\n",
  5209. band == RTW89_BAND_2G ? "2G" :
  5210. band == RTW89_BAND_5G ? "5G" : "6G",
  5211. !!(FIELD_GET(BTC_RFK_PHY_MAP, phy_map) & BIT(RTW89_PHY_1)),
  5212. type,
  5213. FIELD_GET(BTC_RFK_PATH_MAP, phy_map),
  5214. state == BTC_WRFK_STOP ? "RFK_STOP" :
  5215. state == BTC_WRFK_START ? "RFK_START" :
  5216. state == BTC_WRFK_ONESHOT_START ? "ONE-SHOT_START" :
  5217. "ONE-SHOT_STOP");
  5218. if (state != BTC_WRFK_START || rtwdev->is_bt_iqk_timeout) {
  5219. _ntfy_wl_rfk(rtwdev, phy_map, type, state);
  5220. return;
  5221. }
  5222. ret = read_poll_timeout(_ntfy_wl_rfk, allow, allow, 40, 100000, false,
  5223. rtwdev, phy_map, type, state);
  5224. if (ret) {
  5225. rtw89_warn(rtwdev, "RFK notify timeout\n");
  5226. rtwdev->is_bt_iqk_timeout = true;
  5227. }
  5228. }
  5229. EXPORT_SYMBOL(rtw89_btc_ntfy_wl_rfk);
  5230. struct rtw89_btc_wl_sta_iter_data {
  5231. struct rtw89_dev *rtwdev;
  5232. u8 busy_all;
  5233. u8 dir_all;
  5234. u8 rssi_map_all;
  5235. bool is_sta_change;
  5236. bool is_traffic_change;
  5237. };
  5238. static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta)
  5239. {
  5240. struct rtw89_btc_wl_sta_iter_data *iter_data =
  5241. (struct rtw89_btc_wl_sta_iter_data *)data;
  5242. struct rtw89_dev *rtwdev = iter_data->rtwdev;
  5243. struct rtw89_btc *btc = &rtwdev->btc;
  5244. struct rtw89_btc_dm *dm = &btc->dm;
  5245. const struct rtw89_btc_ver *ver = btc->ver;
  5246. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  5247. struct rtw89_btc_wl_link_info *link_info = NULL;
  5248. struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
  5249. struct rtw89_traffic_stats *link_info_t = NULL;
  5250. struct rtw89_vif *rtwvif = rtwsta->rtwvif;
  5251. struct rtw89_traffic_stats *stats = &rtwvif->stats;
  5252. const struct rtw89_chip_info *chip = rtwdev->chip;
  5253. struct rtw89_btc_wl_role_info *r;
  5254. struct rtw89_btc_wl_role_info_v1 *r1;
  5255. u32 last_tx_rate, last_rx_rate;
  5256. u16 last_tx_lvl, last_rx_lvl;
  5257. u8 port = rtwvif->port;
  5258. u8 rssi;
  5259. u8 busy = 0;
  5260. u8 dir = 0;
  5261. u8 rssi_map = 0;
  5262. u8 i = 0;
  5263. bool is_sta_change = false, is_traffic_change = false;
  5264. rssi = ewma_rssi_read(&rtwsta->avg_rssi) >> RSSI_FACTOR;
  5265. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], rssi=%d\n", rssi);
  5266. link_info = &wl->link_info[port];
  5267. link_info->stat.traffic = rtwvif->stats;
  5268. link_info_t = &link_info->stat.traffic;
  5269. if (link_info->connected == MLME_NO_LINK) {
  5270. link_info->rx_rate_drop_cnt = 0;
  5271. return;
  5272. }
  5273. link_info->stat.rssi = rssi;
  5274. for (i = 0; i < BTC_WL_RSSI_THMAX; i++) {
  5275. link_info->rssi_state[i] =
  5276. _update_rssi_state(rtwdev,
  5277. link_info->rssi_state[i],
  5278. link_info->stat.rssi,
  5279. chip->wl_rssi_thres[i]);
  5280. if (BTC_RSSI_LOW(link_info->rssi_state[i]))
  5281. rssi_map |= BIT(i);
  5282. if (btc->mdinfo.ant.type == BTC_ANT_DEDICATED &&
  5283. BTC_RSSI_CHANGE(link_info->rssi_state[i]))
  5284. is_sta_change = true;
  5285. }
  5286. iter_data->rssi_map_all |= rssi_map;
  5287. last_tx_rate = link_info_t->tx_rate;
  5288. last_rx_rate = link_info_t->rx_rate;
  5289. last_tx_lvl = (u16)link_info_t->tx_tfc_lv;
  5290. last_rx_lvl = (u16)link_info_t->rx_tfc_lv;
  5291. if (stats->tx_tfc_lv != RTW89_TFC_IDLE ||
  5292. stats->rx_tfc_lv != RTW89_TFC_IDLE)
  5293. busy = 1;
  5294. if (stats->tx_tfc_lv > stats->rx_tfc_lv)
  5295. dir = RTW89_TFC_UL;
  5296. else
  5297. dir = RTW89_TFC_DL;
  5298. link_info = &wl->link_info[port];
  5299. if (link_info->busy != busy || link_info->dir != dir) {
  5300. is_sta_change = true;
  5301. link_info->busy = busy;
  5302. link_info->dir = dir;
  5303. }
  5304. iter_data->busy_all |= busy;
  5305. iter_data->dir_all |= BIT(dir);
  5306. if (rtwsta->rx_hw_rate <= RTW89_HW_RATE_CCK2 &&
  5307. last_rx_rate > RTW89_HW_RATE_CCK2 &&
  5308. link_info_t->rx_tfc_lv > RTW89_TFC_IDLE)
  5309. link_info->rx_rate_drop_cnt++;
  5310. if (last_tx_rate != rtwsta->ra_report.hw_rate ||
  5311. last_rx_rate != rtwsta->rx_hw_rate ||
  5312. last_tx_lvl != link_info_t->tx_tfc_lv ||
  5313. last_rx_lvl != link_info_t->rx_tfc_lv)
  5314. is_traffic_change = true;
  5315. link_info_t->tx_rate = rtwsta->ra_report.hw_rate;
  5316. link_info_t->rx_rate = rtwsta->rx_hw_rate;
  5317. if (link_info->role == RTW89_WIFI_ROLE_STATION ||
  5318. link_info->role == RTW89_WIFI_ROLE_P2P_CLIENT) {
  5319. dm->trx_info.tx_rate = link_info_t->tx_rate;
  5320. dm->trx_info.rx_rate = link_info_t->rx_rate;
  5321. }
  5322. if (ver->fwlrole == 0) {
  5323. r = &wl->role_info;
  5324. r->active_role[port].tx_lvl = stats->tx_tfc_lv;
  5325. r->active_role[port].rx_lvl = stats->rx_tfc_lv;
  5326. r->active_role[port].tx_rate = rtwsta->ra_report.hw_rate;
  5327. r->active_role[port].rx_rate = rtwsta->rx_hw_rate;
  5328. } else if (ver->fwlrole == 1) {
  5329. r1 = &wl->role_info_v1;
  5330. r1->active_role_v1[port].tx_lvl = stats->tx_tfc_lv;
  5331. r1->active_role_v1[port].rx_lvl = stats->rx_tfc_lv;
  5332. r1->active_role_v1[port].tx_rate = rtwsta->ra_report.hw_rate;
  5333. r1->active_role_v1[port].rx_rate = rtwsta->rx_hw_rate;
  5334. } else if (ver->fwlrole == 2) {
  5335. dm->trx_info.tx_lvl = stats->tx_tfc_lv;
  5336. dm->trx_info.rx_lvl = stats->rx_tfc_lv;
  5337. dm->trx_info.tx_rate = rtwsta->ra_report.hw_rate;
  5338. dm->trx_info.rx_rate = rtwsta->rx_hw_rate;
  5339. }
  5340. dm->trx_info.tx_tp = link_info_t->tx_throughput;
  5341. dm->trx_info.rx_tp = link_info_t->rx_throughput;
  5342. if (is_sta_change)
  5343. iter_data->is_sta_change = true;
  5344. if (is_traffic_change)
  5345. iter_data->is_traffic_change = true;
  5346. }
  5347. #define BTC_NHM_CHK_INTVL 20
  5348. void rtw89_btc_ntfy_wl_sta(struct rtw89_dev *rtwdev)
  5349. {
  5350. struct rtw89_btc *btc = &rtwdev->btc;
  5351. struct rtw89_btc_dm *dm = &btc->dm;
  5352. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  5353. struct rtw89_btc_wl_sta_iter_data data = {.rtwdev = rtwdev};
  5354. u8 i;
  5355. ieee80211_iterate_stations_atomic(rtwdev->hw,
  5356. rtw89_btc_ntfy_wl_sta_iter,
  5357. &data);
  5358. wl->rssi_level = 0;
  5359. btc->dm.cnt_notify[BTC_NCNT_WL_STA]++;
  5360. for (i = BTC_WL_RSSI_THMAX; i > 0; i--) {
  5361. /* set RSSI level 4 ~ 0 if rssi bit map match */
  5362. if (data.rssi_map_all & BIT(i - 1)) {
  5363. wl->rssi_level = i;
  5364. break;
  5365. }
  5366. }
  5367. if (dm->trx_info.wl_rssi != wl->rssi_level)
  5368. dm->trx_info.wl_rssi = wl->rssi_level;
  5369. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): busy=%d\n",
  5370. __func__, !!wl->status.map.busy);
  5371. _write_scbd(rtwdev, BTC_WSCB_WLBUSY, (!!wl->status.map.busy));
  5372. if (data.is_traffic_change)
  5373. _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE);
  5374. if (data.is_sta_change) {
  5375. wl->status.map.busy = data.busy_all;
  5376. wl->status.map.traffic_dir = data.dir_all;
  5377. _run_coex(rtwdev, BTC_RSN_NTFY_WL_STA);
  5378. } else if (btc->dm.cnt_notify[BTC_NCNT_WL_STA] >=
  5379. btc->dm.cnt_dm[BTC_DCNT_WL_STA_LAST] + BTC_NHM_CHK_INTVL) {
  5380. btc->dm.cnt_dm[BTC_DCNT_WL_STA_LAST] =
  5381. btc->dm.cnt_notify[BTC_NCNT_WL_STA];
  5382. } else if (btc->dm.cnt_notify[BTC_NCNT_WL_STA] <
  5383. btc->dm.cnt_dm[BTC_DCNT_WL_STA_LAST]) {
  5384. btc->dm.cnt_dm[BTC_DCNT_WL_STA_LAST] =
  5385. btc->dm.cnt_notify[BTC_NCNT_WL_STA];
  5386. }
  5387. }
  5388. void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
  5389. u32 len, u8 class, u8 func)
  5390. {
  5391. struct rtw89_btc *btc = &rtwdev->btc;
  5392. struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
  5393. u8 *buf = &skb->data[RTW89_C2H_HEADER_LEN];
  5394. len -= RTW89_C2H_HEADER_LEN;
  5395. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  5396. "[BTC], %s(): C2H BT len:%d class:%d fun:%d\n",
  5397. __func__, len, class, func);
  5398. if (class != BTFC_FW_EVENT)
  5399. return;
  5400. switch (func) {
  5401. case BTF_EVNT_RPT:
  5402. case BTF_EVNT_BUF_OVERFLOW:
  5403. pfwinfo->event[func]++;
  5404. /* Don't need rtw89_leave_ps_mode() */
  5405. btc_fw_event(rtwdev, func, buf, len);
  5406. break;
  5407. case BTF_EVNT_BT_INFO:
  5408. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  5409. "[BTC], handle C2H BT INFO with data %8ph\n", buf);
  5410. btc->cx.cnt_bt[BTC_BCNT_INFOUPDATE]++;
  5411. _update_bt_info(rtwdev, buf, len);
  5412. break;
  5413. case BTF_EVNT_BT_SCBD:
  5414. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  5415. "[BTC], handle C2H BT SCBD with data %8ph\n", buf);
  5416. btc->cx.cnt_bt[BTC_BCNT_SCBDUPDATE]++;
  5417. _update_bt_scbd(rtwdev, false);
  5418. break;
  5419. case BTF_EVNT_BT_PSD:
  5420. break;
  5421. case BTF_EVNT_BT_REG:
  5422. btc->dbg.rb_done = true;
  5423. btc->dbg.rb_val = le32_to_cpu(*((__le32 *)buf));
  5424. break;
  5425. case BTF_EVNT_C2H_LOOPBACK:
  5426. btc->dbg.rb_done = true;
  5427. btc->dbg.rb_val = buf[0];
  5428. break;
  5429. case BTF_EVNT_CX_RUNINFO:
  5430. btc->dm.cnt_dm[BTC_DCNT_CX_RUNINFO]++;
  5431. break;
  5432. }
  5433. }
  5434. #define BTC_CX_FW_OFFLOAD 0
  5435. static void _show_cx_info(struct rtw89_dev *rtwdev, struct seq_file *m)
  5436. {
  5437. const struct rtw89_chip_info *chip = rtwdev->chip;
  5438. struct rtw89_hal *hal = &rtwdev->hal;
  5439. struct rtw89_btc *btc = &rtwdev->btc;
  5440. struct rtw89_btc_dm *dm = &btc->dm;
  5441. struct rtw89_btc_bt_info *bt = &btc->cx.bt;
  5442. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  5443. u32 ver_main = 0, ver_sub = 0, ver_hotfix = 0, id_branch = 0;
  5444. if (!(dm->coex_info_map & BTC_COEX_INFO_CX))
  5445. return;
  5446. dm->cnt_notify[BTC_NCNT_SHOW_COEX_INFO]++;
  5447. seq_printf(m, "========== [BTC COEX INFO (%d)] ==========\n",
  5448. chip->chip_id);
  5449. ver_main = FIELD_GET(GENMASK(31, 24), RTW89_COEX_VERSION);
  5450. ver_sub = FIELD_GET(GENMASK(23, 16), RTW89_COEX_VERSION);
  5451. ver_hotfix = FIELD_GET(GENMASK(15, 8), RTW89_COEX_VERSION);
  5452. id_branch = FIELD_GET(GENMASK(7, 0), RTW89_COEX_VERSION);
  5453. seq_printf(m, " %-15s : Coex:%d.%d.%d(branch:%d), ",
  5454. "[coex_version]", ver_main, ver_sub, ver_hotfix, id_branch);
  5455. ver_main = FIELD_GET(GENMASK(31, 24), wl->ver_info.fw_coex);
  5456. ver_sub = FIELD_GET(GENMASK(23, 16), wl->ver_info.fw_coex);
  5457. ver_hotfix = FIELD_GET(GENMASK(15, 8), wl->ver_info.fw_coex);
  5458. id_branch = FIELD_GET(GENMASK(7, 0), wl->ver_info.fw_coex);
  5459. seq_printf(m, "WL_FW_coex:%d.%d.%d(branch:%d)",
  5460. ver_main, ver_sub, ver_hotfix, id_branch);
  5461. ver_main = FIELD_GET(GENMASK(31, 24), chip->wlcx_desired);
  5462. ver_sub = FIELD_GET(GENMASK(23, 16), chip->wlcx_desired);
  5463. ver_hotfix = FIELD_GET(GENMASK(15, 8), chip->wlcx_desired);
  5464. seq_printf(m, "(%s, desired:%d.%d.%d), ",
  5465. (wl->ver_info.fw_coex >= chip->wlcx_desired ?
  5466. "Match" : "Mismatch"), ver_main, ver_sub, ver_hotfix);
  5467. seq_printf(m, "BT_FW_coex:%d(%s, desired:%d)\n",
  5468. bt->ver_info.fw_coex,
  5469. (bt->ver_info.fw_coex >= chip->btcx_desired ?
  5470. "Match" : "Mismatch"), chip->btcx_desired);
  5471. if (bt->enable.now && bt->ver_info.fw == 0)
  5472. rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, true);
  5473. else
  5474. rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, false);
  5475. ver_main = FIELD_GET(GENMASK(31, 24), wl->ver_info.fw);
  5476. ver_sub = FIELD_GET(GENMASK(23, 16), wl->ver_info.fw);
  5477. ver_hotfix = FIELD_GET(GENMASK(15, 8), wl->ver_info.fw);
  5478. id_branch = FIELD_GET(GENMASK(7, 0), wl->ver_info.fw);
  5479. seq_printf(m, " %-15s : WL_FW:%d.%d.%d.%d, BT_FW:0x%x(%s)\n",
  5480. "[sub_module]",
  5481. ver_main, ver_sub, ver_hotfix, id_branch,
  5482. bt->ver_info.fw, bt->run_patch_code ? "patch" : "ROM");
  5483. seq_printf(m, " %-15s : cv:%x, rfe_type:0x%x, ant_iso:%d, ant_pg:%d, %s",
  5484. "[hw_info]", btc->mdinfo.cv, btc->mdinfo.rfe_type,
  5485. btc->mdinfo.ant.isolation, btc->mdinfo.ant.num,
  5486. (btc->mdinfo.ant.num > 1 ? "" : (btc->mdinfo.ant.single_pos ?
  5487. "1Ant_Pos:S1, " : "1Ant_Pos:S0, ")));
  5488. seq_printf(m, "3rd_coex:%d, dbcc:%d, tx_num:%d, rx_num:%d\n",
  5489. btc->cx.other.type, rtwdev->dbcc_en, hal->tx_nss,
  5490. hal->rx_nss);
  5491. }
  5492. static void _show_wl_role_info(struct rtw89_dev *rtwdev, struct seq_file *m)
  5493. {
  5494. struct rtw89_btc *btc = &rtwdev->btc;
  5495. struct rtw89_btc_wl_link_info *plink = NULL;
  5496. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  5497. struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
  5498. struct rtw89_traffic_stats *t;
  5499. u8 i;
  5500. if (rtwdev->dbcc_en) {
  5501. seq_printf(m,
  5502. " %-15s : PHY0_band(op:%d/scan:%d/real:%d), ",
  5503. "[dbcc_info]", wl_dinfo->op_band[RTW89_PHY_0],
  5504. wl_dinfo->scan_band[RTW89_PHY_0],
  5505. wl_dinfo->real_band[RTW89_PHY_0]);
  5506. seq_printf(m,
  5507. "PHY1_band(op:%d/scan:%d/real:%d)\n",
  5508. wl_dinfo->op_band[RTW89_PHY_1],
  5509. wl_dinfo->scan_band[RTW89_PHY_1],
  5510. wl_dinfo->real_band[RTW89_PHY_1]);
  5511. }
  5512. for (i = 0; i < RTW89_PORT_NUM; i++) {
  5513. plink = &btc->cx.wl.link_info[i];
  5514. if (!plink->active)
  5515. continue;
  5516. seq_printf(m,
  5517. " [port_%d] : role=%d(phy-%d), connect=%d(client_cnt=%d), mode=%d, center_ch=%d, bw=%d",
  5518. plink->pid, (u32)plink->role, plink->phy,
  5519. (u32)plink->connected, plink->client_cnt - 1,
  5520. (u32)plink->mode, plink->ch, (u32)plink->bw);
  5521. if (plink->connected == MLME_NO_LINK)
  5522. continue;
  5523. seq_printf(m,
  5524. ", mac_id=%d, max_tx_time=%dus, max_tx_retry=%d\n",
  5525. plink->mac_id, plink->tx_time, plink->tx_retry);
  5526. seq_printf(m,
  5527. " [port_%d] : rssi=-%ddBm(%d), busy=%d, dir=%s, ",
  5528. plink->pid, 110 - plink->stat.rssi,
  5529. plink->stat.rssi, plink->busy,
  5530. plink->dir == RTW89_TFC_UL ? "UL" : "DL");
  5531. t = &plink->stat.traffic;
  5532. seq_printf(m,
  5533. "tx[rate:%d/busy_level:%d], ",
  5534. (u32)t->tx_rate, t->tx_tfc_lv);
  5535. seq_printf(m, "rx[rate:%d/busy_level:%d/drop:%d]\n",
  5536. (u32)t->rx_rate,
  5537. t->rx_tfc_lv, plink->rx_rate_drop_cnt);
  5538. }
  5539. }
  5540. static void _show_wl_info(struct rtw89_dev *rtwdev, struct seq_file *m)
  5541. {
  5542. struct rtw89_btc *btc = &rtwdev->btc;
  5543. const struct rtw89_btc_ver *ver = btc->ver;
  5544. struct rtw89_btc_cx *cx = &btc->cx;
  5545. struct rtw89_btc_wl_info *wl = &cx->wl;
  5546. struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
  5547. struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1;
  5548. struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2;
  5549. u8 mode;
  5550. if (!(btc->dm.coex_info_map & BTC_COEX_INFO_WL))
  5551. return;
  5552. seq_puts(m, "========== [WL Status] ==========\n");
  5553. if (ver->fwlrole == 0)
  5554. mode = wl_rinfo->link_mode;
  5555. else if (ver->fwlrole == 1)
  5556. mode = wl_rinfo_v1->link_mode;
  5557. else if (ver->fwlrole == 2)
  5558. mode = wl_rinfo_v2->link_mode;
  5559. else
  5560. return;
  5561. seq_printf(m, " %-15s : link_mode:%d, ", "[status]", mode);
  5562. seq_printf(m,
  5563. "rf_off:%d, power_save:%d, scan:%s(band:%d/phy_map:0x%x), ",
  5564. wl->status.map.rf_off, wl->status.map.lps,
  5565. wl->status.map.scan ? "Y" : "N",
  5566. wl->scan_info.band[RTW89_PHY_0], wl->scan_info.phy_map);
  5567. seq_printf(m,
  5568. "connecting:%s, roam:%s, 4way:%s, init_ok:%s\n",
  5569. wl->status.map.connecting ? "Y" : "N",
  5570. wl->status.map.roaming ? "Y" : "N",
  5571. wl->status.map._4way ? "Y" : "N",
  5572. wl->status.map.init_ok ? "Y" : "N");
  5573. _show_wl_role_info(rtwdev, m);
  5574. }
  5575. enum btc_bt_a2dp_type {
  5576. BTC_A2DP_LEGACY = 0,
  5577. BTC_A2DP_TWS_SNIFF = 1,
  5578. BTC_A2DP_TWS_RELAY = 2,
  5579. };
  5580. static void _show_bt_profile_info(struct rtw89_dev *rtwdev, struct seq_file *m)
  5581. {
  5582. struct rtw89_btc *btc = &rtwdev->btc;
  5583. struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info;
  5584. struct rtw89_btc_bt_hfp_desc hfp = bt_linfo->hfp_desc;
  5585. struct rtw89_btc_bt_hid_desc hid = bt_linfo->hid_desc;
  5586. struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc;
  5587. struct rtw89_btc_bt_pan_desc pan = bt_linfo->pan_desc;
  5588. if (hfp.exist) {
  5589. seq_printf(m, " %-15s : type:%s, sut_pwr:%d, golden-rx:%d",
  5590. "[HFP]", (hfp.type == 0 ? "SCO" : "eSCO"),
  5591. bt_linfo->sut_pwr_level[0],
  5592. bt_linfo->golden_rx_shift[0]);
  5593. }
  5594. if (hid.exist) {
  5595. seq_printf(m,
  5596. "\n\r %-15s : type:%s%s%s%s%s pair-cnt:%d, sut_pwr:%d, golden-rx:%d\n",
  5597. "[HID]",
  5598. hid.type & BTC_HID_218 ? "2/18," : "",
  5599. hid.type & BTC_HID_418 ? "4/18," : "",
  5600. hid.type & BTC_HID_BLE ? "BLE," : "",
  5601. hid.type & BTC_HID_RCU ? "RCU," : "",
  5602. hid.type & BTC_HID_RCU_VOICE ? "RCU-Voice," : "",
  5603. hid.pair_cnt, bt_linfo->sut_pwr_level[1],
  5604. bt_linfo->golden_rx_shift[1]);
  5605. }
  5606. if (a2dp.exist) {
  5607. seq_printf(m,
  5608. " %-15s : type:%s, bit-pool:%d, flush-time:%d, ",
  5609. "[A2DP]",
  5610. a2dp.type == BTC_A2DP_LEGACY ? "Legacy" : "TWS",
  5611. a2dp.bitpool, a2dp.flush_time);
  5612. seq_printf(m,
  5613. "vid:0x%x, Dev-name:0x%x, sut_pwr:%d, golden-rx:%d\n",
  5614. a2dp.vendor_id, a2dp.device_name,
  5615. bt_linfo->sut_pwr_level[2],
  5616. bt_linfo->golden_rx_shift[2]);
  5617. }
  5618. if (pan.exist) {
  5619. seq_printf(m, " %-15s : sut_pwr:%d, golden-rx:%d\n",
  5620. "[PAN]",
  5621. bt_linfo->sut_pwr_level[3],
  5622. bt_linfo->golden_rx_shift[3]);
  5623. }
  5624. }
  5625. static void _show_bt_info(struct rtw89_dev *rtwdev, struct seq_file *m)
  5626. {
  5627. struct rtw89_btc *btc = &rtwdev->btc;
  5628. const struct rtw89_btc_ver *ver = btc->ver;
  5629. struct rtw89_btc_cx *cx = &btc->cx;
  5630. struct rtw89_btc_bt_info *bt = &cx->bt;
  5631. struct rtw89_btc_wl_info *wl = &cx->wl;
  5632. struct rtw89_btc_module *module = &btc->mdinfo;
  5633. struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info;
  5634. u8 *afh = bt_linfo->afh_map;
  5635. u8 *afh_le = bt_linfo->afh_map_le;
  5636. if (!(btc->dm.coex_info_map & BTC_COEX_INFO_BT))
  5637. return;
  5638. seq_puts(m, "========== [BT Status] ==========\n");
  5639. seq_printf(m, " %-15s : enable:%s, btg:%s%s, connect:%s, ",
  5640. "[status]", bt->enable.now ? "Y" : "N",
  5641. bt->btg_type ? "Y" : "N",
  5642. (bt->enable.now && (bt->btg_type != module->bt_pos) ?
  5643. "(efuse-mismatch!!)" : ""),
  5644. (bt_linfo->status.map.connect ? "Y" : "N"));
  5645. seq_printf(m, "igno_wl:%s, mailbox_avl:%s, rfk_state:0x%x\n",
  5646. bt->igno_wl ? "Y" : "N",
  5647. bt->mbx_avl ? "Y" : "N", bt->rfk_info.val);
  5648. seq_printf(m, " %-15s : profile:%s%s%s%s%s ",
  5649. "[profile]",
  5650. (bt_linfo->profile_cnt.now == 0) ? "None," : "",
  5651. bt_linfo->hfp_desc.exist ? "HFP," : "",
  5652. bt_linfo->hid_desc.exist ? "HID," : "",
  5653. bt_linfo->a2dp_desc.exist ?
  5654. (bt_linfo->a2dp_desc.sink ? "A2DP_sink," : "A2DP,") : "",
  5655. bt_linfo->pan_desc.exist ? "PAN," : "");
  5656. seq_printf(m,
  5657. "multi-link:%s, role:%s, ble-connect:%s, CQDDR:%s, A2DP_active:%s, PAN_active:%s\n",
  5658. bt_linfo->multi_link.now ? "Y" : "N",
  5659. bt_linfo->slave_role ? "Slave" : "Master",
  5660. bt_linfo->status.map.ble_connect ? "Y" : "N",
  5661. bt_linfo->cqddr ? "Y" : "N",
  5662. bt_linfo->a2dp_desc.active ? "Y" : "N",
  5663. bt_linfo->pan_desc.active ? "Y" : "N");
  5664. seq_printf(m,
  5665. " %-15s : rssi:%ddBm, tx_rate:%dM, %s%s%s",
  5666. "[link]", bt_linfo->rssi - 100,
  5667. bt_linfo->tx_3m ? 3 : 2,
  5668. bt_linfo->status.map.inq_pag ? " inq-page!!" : "",
  5669. bt_linfo->status.map.acl_busy ? " acl_busy!!" : "",
  5670. bt_linfo->status.map.mesh_busy ? " mesh_busy!!" : "");
  5671. seq_printf(m,
  5672. "%s afh_map[%02x%02x_%02x%02x_%02x%02x_%02x%02x_%02x%02x], ",
  5673. bt_linfo->relink.now ? " ReLink!!" : "",
  5674. afh[0], afh[1], afh[2], afh[3], afh[4],
  5675. afh[5], afh[6], afh[7], afh[8], afh[9]);
  5676. if (ver->fcxbtafh == 2 && bt_linfo->status.map.ble_connect)
  5677. seq_printf(m,
  5678. "LE[%02x%02x_%02x_%02x%02x]",
  5679. afh_le[0], afh_le[1], afh_le[2],
  5680. afh_le[3], afh_le[4]);
  5681. seq_printf(m, "wl_ch_map[en:%d/ch:%d/bw:%d]\n",
  5682. wl->afh_info.en, wl->afh_info.ch, wl->afh_info.bw);
  5683. seq_printf(m,
  5684. " %-15s : retry:%d, relink:%d, rate_chg:%d, reinit:%d, reenable:%d, ",
  5685. "[stat_cnt]", cx->cnt_bt[BTC_BCNT_RETRY],
  5686. cx->cnt_bt[BTC_BCNT_RELINK], cx->cnt_bt[BTC_BCNT_RATECHG],
  5687. cx->cnt_bt[BTC_BCNT_REINIT], cx->cnt_bt[BTC_BCNT_REENABLE]);
  5688. seq_printf(m,
  5689. "role-switch:%d, afh:%d, inq_page:%d(inq:%d/page:%d), igno_wl:%d\n",
  5690. cx->cnt_bt[BTC_BCNT_ROLESW], cx->cnt_bt[BTC_BCNT_AFH],
  5691. cx->cnt_bt[BTC_BCNT_INQPAG], cx->cnt_bt[BTC_BCNT_INQ],
  5692. cx->cnt_bt[BTC_BCNT_PAGE], cx->cnt_bt[BTC_BCNT_IGNOWL]);
  5693. _show_bt_profile_info(rtwdev, m);
  5694. seq_printf(m,
  5695. " %-15s : raw_data[%02x %02x %02x %02x %02x %02x] (type:%s/cnt:%d/same:%d)\n",
  5696. "[bt_info]", bt->raw_info[2], bt->raw_info[3],
  5697. bt->raw_info[4], bt->raw_info[5], bt->raw_info[6],
  5698. bt->raw_info[7],
  5699. bt->raw_info[0] == BTC_BTINFO_AUTO ? "auto" : "reply",
  5700. cx->cnt_bt[BTC_BCNT_INFOUPDATE],
  5701. cx->cnt_bt[BTC_BCNT_INFOSAME]);
  5702. seq_printf(m,
  5703. " %-15s : Hi-rx = %d, Hi-tx = %d, Lo-rx = %d, Lo-tx = %d (bt_polut_wl_tx = %d)",
  5704. "[trx_req_cnt]", cx->cnt_bt[BTC_BCNT_HIPRI_RX],
  5705. cx->cnt_bt[BTC_BCNT_HIPRI_TX], cx->cnt_bt[BTC_BCNT_LOPRI_RX],
  5706. cx->cnt_bt[BTC_BCNT_LOPRI_TX], cx->cnt_bt[BTC_BCNT_POLUT]);
  5707. if (!bt->scan_info_update) {
  5708. rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_SCAN_INFO, true);
  5709. seq_puts(m, "\n");
  5710. } else {
  5711. rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_SCAN_INFO, false);
  5712. if (ver->fcxbtscan == 1) {
  5713. seq_printf(m,
  5714. "(INQ:%d-%d/PAGE:%d-%d/LE:%d-%d/INIT:%d-%d)",
  5715. le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INQ].win),
  5716. le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INQ].intvl),
  5717. le16_to_cpu(bt->scan_info_v1[BTC_SCAN_PAGE].win),
  5718. le16_to_cpu(bt->scan_info_v1[BTC_SCAN_PAGE].intvl),
  5719. le16_to_cpu(bt->scan_info_v1[BTC_SCAN_BLE].win),
  5720. le16_to_cpu(bt->scan_info_v1[BTC_SCAN_BLE].intvl),
  5721. le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INIT].win),
  5722. le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INIT].intvl));
  5723. } else if (ver->fcxbtscan == 2) {
  5724. seq_printf(m,
  5725. "(BG:%d-%d/INIT:%d-%d/LE:%d-%d)",
  5726. le16_to_cpu(bt->scan_info_v2[CXSCAN_BG].win),
  5727. le16_to_cpu(bt->scan_info_v2[CXSCAN_BG].intvl),
  5728. le16_to_cpu(bt->scan_info_v2[CXSCAN_INIT].win),
  5729. le16_to_cpu(bt->scan_info_v2[CXSCAN_INIT].intvl),
  5730. le16_to_cpu(bt->scan_info_v2[CXSCAN_LE].win),
  5731. le16_to_cpu(bt->scan_info_v2[CXSCAN_LE].intvl));
  5732. }
  5733. seq_puts(m, "\n");
  5734. }
  5735. if (bt->enable.now && bt->ver_info.fw == 0)
  5736. rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, true);
  5737. else
  5738. rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, false);
  5739. if (bt_linfo->profile_cnt.now || bt_linfo->status.map.ble_connect)
  5740. rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP, true);
  5741. else
  5742. rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP, false);
  5743. if (ver->fcxbtafh == 2 && bt_linfo->status.map.ble_connect)
  5744. rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP_LE, true);
  5745. else
  5746. rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP_LE, false);
  5747. if (bt_linfo->a2dp_desc.exist &&
  5748. (bt_linfo->a2dp_desc.flush_time == 0 ||
  5749. bt_linfo->a2dp_desc.vendor_id == 0 ||
  5750. bt_linfo->a2dp_desc.play_latency == 1))
  5751. rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_DEVICE_INFO, true);
  5752. else
  5753. rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_DEVICE_INFO, false);
  5754. }
  5755. #define CASE_BTC_RSN_STR(e) case BTC_RSN_ ## e: return #e
  5756. #define CASE_BTC_ACT_STR(e) case BTC_ACT_ ## e | BTC_ACT_EXT_BIT: return #e
  5757. #define CASE_BTC_POLICY_STR(e) \
  5758. case BTC_CXP_ ## e | BTC_POLICY_EXT_BIT: return #e
  5759. #define CASE_BTC_SLOT_STR(e) case CXST_ ## e: return #e
  5760. #define CASE_BTC_EVT_STR(e) case CXEVNT_## e: return #e
  5761. static const char *steps_to_str(u16 step)
  5762. {
  5763. switch (step) {
  5764. CASE_BTC_RSN_STR(NONE);
  5765. CASE_BTC_RSN_STR(NTFY_INIT);
  5766. CASE_BTC_RSN_STR(NTFY_SWBAND);
  5767. CASE_BTC_RSN_STR(NTFY_WL_STA);
  5768. CASE_BTC_RSN_STR(NTFY_RADIO_STATE);
  5769. CASE_BTC_RSN_STR(UPDATE_BT_SCBD);
  5770. CASE_BTC_RSN_STR(NTFY_WL_RFK);
  5771. CASE_BTC_RSN_STR(UPDATE_BT_INFO);
  5772. CASE_BTC_RSN_STR(NTFY_SCAN_START);
  5773. CASE_BTC_RSN_STR(NTFY_SCAN_FINISH);
  5774. CASE_BTC_RSN_STR(NTFY_SPECIFIC_PACKET);
  5775. CASE_BTC_RSN_STR(NTFY_POWEROFF);
  5776. CASE_BTC_RSN_STR(NTFY_ROLE_INFO);
  5777. CASE_BTC_RSN_STR(CMD_SET_COEX);
  5778. CASE_BTC_RSN_STR(ACT1_WORK);
  5779. CASE_BTC_RSN_STR(BT_DEVINFO_WORK);
  5780. CASE_BTC_RSN_STR(RFK_CHK_WORK);
  5781. CASE_BTC_ACT_STR(NONE);
  5782. CASE_BTC_ACT_STR(WL_ONLY);
  5783. CASE_BTC_ACT_STR(WL_5G);
  5784. CASE_BTC_ACT_STR(WL_OTHER);
  5785. CASE_BTC_ACT_STR(WL_IDLE);
  5786. CASE_BTC_ACT_STR(WL_NC);
  5787. CASE_BTC_ACT_STR(WL_RFK);
  5788. CASE_BTC_ACT_STR(WL_INIT);
  5789. CASE_BTC_ACT_STR(WL_OFF);
  5790. CASE_BTC_ACT_STR(FREERUN);
  5791. CASE_BTC_ACT_STR(BT_WHQL);
  5792. CASE_BTC_ACT_STR(BT_RFK);
  5793. CASE_BTC_ACT_STR(BT_OFF);
  5794. CASE_BTC_ACT_STR(BT_IDLE);
  5795. CASE_BTC_ACT_STR(BT_HFP);
  5796. CASE_BTC_ACT_STR(BT_HID);
  5797. CASE_BTC_ACT_STR(BT_A2DP);
  5798. CASE_BTC_ACT_STR(BT_A2DPSINK);
  5799. CASE_BTC_ACT_STR(BT_PAN);
  5800. CASE_BTC_ACT_STR(BT_A2DP_HID);
  5801. CASE_BTC_ACT_STR(BT_A2DP_PAN);
  5802. CASE_BTC_ACT_STR(BT_PAN_HID);
  5803. CASE_BTC_ACT_STR(BT_A2DP_PAN_HID);
  5804. CASE_BTC_ACT_STR(WL_25G_MCC);
  5805. CASE_BTC_ACT_STR(WL_2G_MCC);
  5806. CASE_BTC_ACT_STR(WL_2G_SCC);
  5807. CASE_BTC_ACT_STR(WL_2G_AP);
  5808. CASE_BTC_ACT_STR(WL_2G_GO);
  5809. CASE_BTC_ACT_STR(WL_2G_GC);
  5810. CASE_BTC_ACT_STR(WL_2G_NAN);
  5811. CASE_BTC_POLICY_STR(OFF_BT);
  5812. CASE_BTC_POLICY_STR(OFF_WL);
  5813. CASE_BTC_POLICY_STR(OFF_EQ0);
  5814. CASE_BTC_POLICY_STR(OFF_EQ1);
  5815. CASE_BTC_POLICY_STR(OFF_EQ2);
  5816. CASE_BTC_POLICY_STR(OFF_EQ3);
  5817. CASE_BTC_POLICY_STR(OFF_BWB0);
  5818. CASE_BTC_POLICY_STR(OFF_BWB1);
  5819. CASE_BTC_POLICY_STR(OFF_BWB2);
  5820. CASE_BTC_POLICY_STR(OFF_BWB3);
  5821. CASE_BTC_POLICY_STR(OFFB_BWB0);
  5822. CASE_BTC_POLICY_STR(OFFE_DEF);
  5823. CASE_BTC_POLICY_STR(OFFE_DEF2);
  5824. CASE_BTC_POLICY_STR(OFFE_2GBWISOB);
  5825. CASE_BTC_POLICY_STR(OFFE_2GISOB);
  5826. CASE_BTC_POLICY_STR(OFFE_2GBWMIXB);
  5827. CASE_BTC_POLICY_STR(OFFE_WL);
  5828. CASE_BTC_POLICY_STR(OFFE_2GBWMIXB2);
  5829. CASE_BTC_POLICY_STR(FIX_TD3030);
  5830. CASE_BTC_POLICY_STR(FIX_TD5050);
  5831. CASE_BTC_POLICY_STR(FIX_TD2030);
  5832. CASE_BTC_POLICY_STR(FIX_TD4010);
  5833. CASE_BTC_POLICY_STR(FIX_TD7010);
  5834. CASE_BTC_POLICY_STR(FIX_TD2060);
  5835. CASE_BTC_POLICY_STR(FIX_TD3060);
  5836. CASE_BTC_POLICY_STR(FIX_TD2080);
  5837. CASE_BTC_POLICY_STR(FIX_TDW1B1);
  5838. CASE_BTC_POLICY_STR(FIX_TD4020);
  5839. CASE_BTC_POLICY_STR(FIX_TD4010ISO);
  5840. CASE_BTC_POLICY_STR(PFIX_TD3030);
  5841. CASE_BTC_POLICY_STR(PFIX_TD5050);
  5842. CASE_BTC_POLICY_STR(PFIX_TD2030);
  5843. CASE_BTC_POLICY_STR(PFIX_TD2060);
  5844. CASE_BTC_POLICY_STR(PFIX_TD3070);
  5845. CASE_BTC_POLICY_STR(PFIX_TD2080);
  5846. CASE_BTC_POLICY_STR(PFIX_TDW1B1);
  5847. CASE_BTC_POLICY_STR(AUTO_TD50B1);
  5848. CASE_BTC_POLICY_STR(AUTO_TD60B1);
  5849. CASE_BTC_POLICY_STR(AUTO_TD20B1);
  5850. CASE_BTC_POLICY_STR(AUTO_TDW1B1);
  5851. CASE_BTC_POLICY_STR(PAUTO_TD50B1);
  5852. CASE_BTC_POLICY_STR(PAUTO_TD60B1);
  5853. CASE_BTC_POLICY_STR(PAUTO_TD20B1);
  5854. CASE_BTC_POLICY_STR(PAUTO_TDW1B1);
  5855. CASE_BTC_POLICY_STR(AUTO2_TD3050);
  5856. CASE_BTC_POLICY_STR(AUTO2_TD3070);
  5857. CASE_BTC_POLICY_STR(AUTO2_TD5050);
  5858. CASE_BTC_POLICY_STR(AUTO2_TD6060);
  5859. CASE_BTC_POLICY_STR(AUTO2_TD2080);
  5860. CASE_BTC_POLICY_STR(AUTO2_TDW1B4);
  5861. CASE_BTC_POLICY_STR(PAUTO2_TD3050);
  5862. CASE_BTC_POLICY_STR(PAUTO2_TD3070);
  5863. CASE_BTC_POLICY_STR(PAUTO2_TD5050);
  5864. CASE_BTC_POLICY_STR(PAUTO2_TD6060);
  5865. CASE_BTC_POLICY_STR(PAUTO2_TD2080);
  5866. CASE_BTC_POLICY_STR(PAUTO2_TDW1B4);
  5867. default:
  5868. return "unknown step";
  5869. }
  5870. }
  5871. static const char *id_to_slot(u32 id)
  5872. {
  5873. switch (id) {
  5874. CASE_BTC_SLOT_STR(OFF);
  5875. CASE_BTC_SLOT_STR(B2W);
  5876. CASE_BTC_SLOT_STR(W1);
  5877. CASE_BTC_SLOT_STR(W2);
  5878. CASE_BTC_SLOT_STR(W2B);
  5879. CASE_BTC_SLOT_STR(B1);
  5880. CASE_BTC_SLOT_STR(B2);
  5881. CASE_BTC_SLOT_STR(B3);
  5882. CASE_BTC_SLOT_STR(B4);
  5883. CASE_BTC_SLOT_STR(LK);
  5884. CASE_BTC_SLOT_STR(BLK);
  5885. CASE_BTC_SLOT_STR(E2G);
  5886. CASE_BTC_SLOT_STR(E5G);
  5887. CASE_BTC_SLOT_STR(EBT);
  5888. CASE_BTC_SLOT_STR(ENULL);
  5889. CASE_BTC_SLOT_STR(WLK);
  5890. CASE_BTC_SLOT_STR(W1FDD);
  5891. CASE_BTC_SLOT_STR(B1FDD);
  5892. default:
  5893. return "unknown";
  5894. }
  5895. }
  5896. static const char *id_to_evt(u32 id)
  5897. {
  5898. switch (id) {
  5899. CASE_BTC_EVT_STR(TDMA_ENTRY);
  5900. CASE_BTC_EVT_STR(WL_TMR);
  5901. CASE_BTC_EVT_STR(B1_TMR);
  5902. CASE_BTC_EVT_STR(B2_TMR);
  5903. CASE_BTC_EVT_STR(B3_TMR);
  5904. CASE_BTC_EVT_STR(B4_TMR);
  5905. CASE_BTC_EVT_STR(W2B_TMR);
  5906. CASE_BTC_EVT_STR(B2W_TMR);
  5907. CASE_BTC_EVT_STR(BCN_EARLY);
  5908. CASE_BTC_EVT_STR(A2DP_EMPTY);
  5909. CASE_BTC_EVT_STR(LK_END);
  5910. CASE_BTC_EVT_STR(RX_ISR);
  5911. CASE_BTC_EVT_STR(RX_FC0);
  5912. CASE_BTC_EVT_STR(RX_FC1);
  5913. CASE_BTC_EVT_STR(BT_RELINK);
  5914. CASE_BTC_EVT_STR(BT_RETRY);
  5915. CASE_BTC_EVT_STR(E2G);
  5916. CASE_BTC_EVT_STR(E5G);
  5917. CASE_BTC_EVT_STR(EBT);
  5918. CASE_BTC_EVT_STR(ENULL);
  5919. CASE_BTC_EVT_STR(DRV_WLK);
  5920. CASE_BTC_EVT_STR(BCN_OK);
  5921. CASE_BTC_EVT_STR(BT_CHANGE);
  5922. CASE_BTC_EVT_STR(EBT_EXTEND);
  5923. CASE_BTC_EVT_STR(E2G_NULL1);
  5924. CASE_BTC_EVT_STR(B1FDD_TMR);
  5925. default:
  5926. return "unknown";
  5927. }
  5928. }
  5929. static
  5930. void seq_print_segment(struct seq_file *m, const char *prefix, u16 *data,
  5931. u8 len, u8 seg_len, u8 start_idx, u8 ring_len)
  5932. {
  5933. u8 i;
  5934. u8 cur_index;
  5935. for (i = 0; i < len ; i++) {
  5936. if ((i % seg_len) == 0)
  5937. seq_printf(m, " %-15s : ", prefix);
  5938. cur_index = (start_idx + i) % ring_len;
  5939. if (i % 3 == 0)
  5940. seq_printf(m, "-> %-20s",
  5941. steps_to_str(*(data + cur_index)));
  5942. else if (i % 3 == 1)
  5943. seq_printf(m, "-> %-15s",
  5944. steps_to_str(*(data + cur_index)));
  5945. else
  5946. seq_printf(m, "-> %-13s",
  5947. steps_to_str(*(data + cur_index)));
  5948. if (i == (len - 1) || (i % seg_len) == (seg_len - 1))
  5949. seq_puts(m, "\n");
  5950. }
  5951. }
  5952. static void _show_dm_step(struct rtw89_dev *rtwdev, struct seq_file *m)
  5953. {
  5954. struct rtw89_btc *btc = &rtwdev->btc;
  5955. struct rtw89_btc_dm *dm = &btc->dm;
  5956. u8 start_idx;
  5957. u8 len;
  5958. len = dm->dm_step.step_ov ? RTW89_BTC_DM_MAXSTEP : dm->dm_step.step_pos;
  5959. start_idx = dm->dm_step.step_ov ? dm->dm_step.step_pos : 0;
  5960. seq_print_segment(m, "[dm_steps]", dm->dm_step.step, len, 6, start_idx,
  5961. ARRAY_SIZE(dm->dm_step.step));
  5962. }
  5963. static void _show_dm_info(struct rtw89_dev *rtwdev, struct seq_file *m)
  5964. {
  5965. struct rtw89_btc *btc = &rtwdev->btc;
  5966. struct rtw89_btc_module *module = &btc->mdinfo;
  5967. struct rtw89_btc_dm *dm = &btc->dm;
  5968. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  5969. struct rtw89_btc_bt_info *bt = &btc->cx.bt;
  5970. if (!(dm->coex_info_map & BTC_COEX_INFO_DM))
  5971. return;
  5972. seq_printf(m, "========== [Mechanism Status %s] ==========\n",
  5973. (btc->ctrl.manual ? "(Manual)" : "(Auto)"));
  5974. seq_printf(m,
  5975. " %-15s : type:%s, reason:%s(), action:%s(), ant_path:%ld, run_cnt:%d\n",
  5976. "[status]",
  5977. module->ant.type == BTC_ANT_SHARED ? "shared" : "dedicated",
  5978. steps_to_str(dm->run_reason),
  5979. steps_to_str(dm->run_action | BTC_ACT_EXT_BIT),
  5980. FIELD_GET(GENMASK(7, 0), dm->set_ant_path),
  5981. dm->cnt_dm[BTC_DCNT_RUN]);
  5982. _show_dm_step(rtwdev, m);
  5983. seq_printf(m, " %-15s : wl_only:%d, bt_only:%d, igno_bt:%d, free_run:%d, wl_ps_ctrl:%d, wl_mimo_ps:%d, ",
  5984. "[dm_flag]", dm->wl_only, dm->bt_only, btc->ctrl.igno_bt,
  5985. dm->freerun, btc->lps, dm->wl_mimo_ps);
  5986. seq_printf(m, "leak_ap:%d, fw_offload:%s%s\n", dm->leak_ap,
  5987. (BTC_CX_FW_OFFLOAD ? "Y" : "N"),
  5988. (dm->wl_fw_cx_offload == BTC_CX_FW_OFFLOAD ?
  5989. "" : "(Mismatch!!)"));
  5990. if (dm->rf_trx_para.wl_tx_power == 0xff)
  5991. seq_printf(m,
  5992. " %-15s : wl_rssi_lvl:%d, para_lvl:%d, wl_tx_pwr:orig, ",
  5993. "[trx_ctrl]", wl->rssi_level, dm->trx_para_level);
  5994. else
  5995. seq_printf(m,
  5996. " %-15s : wl_rssi_lvl:%d, para_lvl:%d, wl_tx_pwr:%d, ",
  5997. "[trx_ctrl]", wl->rssi_level, dm->trx_para_level,
  5998. dm->rf_trx_para.wl_tx_power);
  5999. seq_printf(m,
  6000. "wl_rx_lvl:%d, bt_tx_pwr_dec:%d, bt_rx_lna:%d(%s-tbl), wl_btg_rx:%d\n",
  6001. dm->rf_trx_para.wl_rx_gain, dm->rf_trx_para.bt_tx_power,
  6002. dm->rf_trx_para.bt_rx_gain,
  6003. (bt->hi_lna_rx ? "Hi" : "Ori"), dm->wl_btg_rx);
  6004. seq_printf(m,
  6005. " %-15s : wl_tx_limit[en:%d/max_t:%dus/max_retry:%d], bt_slot_reg:%d-TU, bt_scan_rx_low_pri:%d\n",
  6006. "[dm_ctrl]", dm->wl_tx_limit.enable, dm->wl_tx_limit.tx_time,
  6007. dm->wl_tx_limit.tx_retry, btc->bt_req_len, bt->scan_rx_low_pri);
  6008. }
  6009. static void _show_error(struct rtw89_dev *rtwdev, struct seq_file *m)
  6010. {
  6011. struct rtw89_btc *btc = &rtwdev->btc;
  6012. const struct rtw89_btc_ver *ver = btc->ver;
  6013. struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
  6014. union rtw89_btc_fbtc_cysta_info *pcysta;
  6015. u32 except_cnt, exception_map;
  6016. pcysta = &pfwinfo->rpt_fbtc_cysta.finfo;
  6017. if (ver->fcxcysta == 2) {
  6018. pcysta->v2 = pfwinfo->rpt_fbtc_cysta.finfo.v2;
  6019. except_cnt = le32_to_cpu(pcysta->v2.except_cnt);
  6020. exception_map = le32_to_cpu(pcysta->v2.exception);
  6021. } else if (ver->fcxcysta == 3) {
  6022. pcysta->v3 = pfwinfo->rpt_fbtc_cysta.finfo.v3;
  6023. except_cnt = le32_to_cpu(pcysta->v3.except_cnt);
  6024. exception_map = le32_to_cpu(pcysta->v3.except_map);
  6025. } else if (ver->fcxcysta == 4) {
  6026. pcysta->v4 = pfwinfo->rpt_fbtc_cysta.finfo.v4;
  6027. except_cnt = pcysta->v4.except_cnt;
  6028. exception_map = le32_to_cpu(pcysta->v4.except_map);
  6029. } else if (ver->fcxcysta == 5) {
  6030. pcysta->v5 = pfwinfo->rpt_fbtc_cysta.finfo.v5;
  6031. except_cnt = pcysta->v5.except_cnt;
  6032. exception_map = le32_to_cpu(pcysta->v5.except_map);
  6033. } else {
  6034. return;
  6035. }
  6036. if (pfwinfo->event[BTF_EVNT_BUF_OVERFLOW] == 0 && except_cnt == 0 &&
  6037. !pfwinfo->len_mismch && !pfwinfo->fver_mismch)
  6038. return;
  6039. seq_printf(m, " %-15s : ", "[error]");
  6040. if (pfwinfo->event[BTF_EVNT_BUF_OVERFLOW]) {
  6041. seq_printf(m,
  6042. "overflow-cnt: %d, ",
  6043. pfwinfo->event[BTF_EVNT_BUF_OVERFLOW]);
  6044. }
  6045. if (pfwinfo->len_mismch) {
  6046. seq_printf(m,
  6047. "len-mismatch: 0x%x, ",
  6048. pfwinfo->len_mismch);
  6049. }
  6050. if (pfwinfo->fver_mismch) {
  6051. seq_printf(m,
  6052. "fver-mismatch: 0x%x, ",
  6053. pfwinfo->fver_mismch);
  6054. }
  6055. /* cycle statistics exceptions */
  6056. if (exception_map || except_cnt) {
  6057. seq_printf(m,
  6058. "exception-type: 0x%x, exception-cnt = %d",
  6059. exception_map, except_cnt);
  6060. }
  6061. seq_puts(m, "\n");
  6062. }
  6063. static void _show_fbtc_tdma(struct rtw89_dev *rtwdev, struct seq_file *m)
  6064. {
  6065. struct rtw89_btc *btc = &rtwdev->btc;
  6066. const struct rtw89_btc_ver *ver = btc->ver;
  6067. struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
  6068. struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
  6069. struct rtw89_btc_fbtc_tdma *t = NULL;
  6070. pcinfo = &pfwinfo->rpt_fbtc_tdma.cinfo;
  6071. if (!pcinfo->valid)
  6072. return;
  6073. if (ver->fcxtdma == 1)
  6074. t = &pfwinfo->rpt_fbtc_tdma.finfo.v1;
  6075. else
  6076. t = &pfwinfo->rpt_fbtc_tdma.finfo.v3.tdma;
  6077. seq_printf(m,
  6078. " %-15s : ", "[tdma_policy]");
  6079. seq_printf(m,
  6080. "type:%d, rx_flow_ctrl:%d, tx_pause:%d, ",
  6081. (u32)t->type,
  6082. t->rxflctrl, t->txpause);
  6083. seq_printf(m,
  6084. "wl_toggle_n:%d, leak_n:%d, ext_ctrl:%d, ",
  6085. t->wtgle_n, t->leak_n, t->ext_ctrl);
  6086. seq_printf(m,
  6087. "policy_type:%d",
  6088. (u32)btc->policy_type);
  6089. seq_puts(m, "\n");
  6090. }
  6091. static void _show_fbtc_slots(struct rtw89_dev *rtwdev, struct seq_file *m)
  6092. {
  6093. struct rtw89_btc *btc = &rtwdev->btc;
  6094. struct rtw89_btc_dm *dm = &btc->dm;
  6095. struct rtw89_btc_fbtc_slot *s;
  6096. u8 i = 0;
  6097. for (i = 0; i < CXST_MAX; i++) {
  6098. s = &dm->slot_now[i];
  6099. if (i % 5 == 0)
  6100. seq_printf(m,
  6101. " %-15s : %5s[%03d/0x%x/%d]",
  6102. "[slot_list]",
  6103. id_to_slot((u32)i),
  6104. s->dur, s->cxtbl, s->cxtype);
  6105. else
  6106. seq_printf(m,
  6107. ", %5s[%03d/0x%x/%d]",
  6108. id_to_slot((u32)i),
  6109. s->dur, s->cxtbl, s->cxtype);
  6110. if (i % 5 == 4)
  6111. seq_puts(m, "\n");
  6112. }
  6113. seq_puts(m, "\n");
  6114. }
  6115. static void _show_fbtc_cysta_v2(struct rtw89_dev *rtwdev, struct seq_file *m)
  6116. {
  6117. struct rtw89_btc *btc = &rtwdev->btc;
  6118. struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
  6119. struct rtw89_btc_dm *dm = &btc->dm;
  6120. struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc;
  6121. struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
  6122. struct rtw89_btc_fbtc_cysta_v2 *pcysta_le32 = NULL;
  6123. union rtw89_btc_fbtc_rxflct r;
  6124. u8 i, cnt = 0, slot_pair;
  6125. u16 cycle, c_begin, c_end, store_index;
  6126. pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo;
  6127. if (!pcinfo->valid)
  6128. return;
  6129. pcysta_le32 = &pfwinfo->rpt_fbtc_cysta.finfo.v2;
  6130. seq_printf(m,
  6131. " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]",
  6132. "[cycle_cnt]",
  6133. le16_to_cpu(pcysta_le32->cycles),
  6134. le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_ALL]),
  6135. le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_ALL_OK]),
  6136. le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_BT_SLOT]),
  6137. le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_BT_OK]));
  6138. for (i = 0; i < CXST_MAX; i++) {
  6139. if (!le32_to_cpu(pcysta_le32->slot_cnt[i]))
  6140. continue;
  6141. seq_printf(m, ", %s:%d", id_to_slot((u32)i),
  6142. le32_to_cpu(pcysta_le32->slot_cnt[i]));
  6143. }
  6144. if (dm->tdma_now.rxflctrl) {
  6145. seq_printf(m, ", leak_rx:%d",
  6146. le32_to_cpu(pcysta_le32->leakrx_cnt));
  6147. }
  6148. if (le32_to_cpu(pcysta_le32->collision_cnt)) {
  6149. seq_printf(m, ", collision:%d",
  6150. le32_to_cpu(pcysta_le32->collision_cnt));
  6151. }
  6152. if (le32_to_cpu(pcysta_le32->skip_cnt)) {
  6153. seq_printf(m, ", skip:%d",
  6154. le32_to_cpu(pcysta_le32->skip_cnt));
  6155. }
  6156. seq_puts(m, "\n");
  6157. seq_printf(m, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]",
  6158. "[cycle_time]",
  6159. le16_to_cpu(pcysta_le32->tavg_cycle[CXT_WL]),
  6160. le16_to_cpu(pcysta_le32->tavg_cycle[CXT_BT]),
  6161. le16_to_cpu(pcysta_le32->tavg_lk) / 1000,
  6162. le16_to_cpu(pcysta_le32->tavg_lk) % 1000);
  6163. seq_printf(m, ", max_t[wl:%d/bt:%d/lk:%d.%03d]",
  6164. le16_to_cpu(pcysta_le32->tmax_cycle[CXT_WL]),
  6165. le16_to_cpu(pcysta_le32->tmax_cycle[CXT_BT]),
  6166. le16_to_cpu(pcysta_le32->tmax_lk) / 1000,
  6167. le16_to_cpu(pcysta_le32->tmax_lk) % 1000);
  6168. seq_printf(m, ", maxdiff_t[wl:%d/bt:%d]\n",
  6169. le16_to_cpu(pcysta_le32->tmaxdiff_cycle[CXT_WL]),
  6170. le16_to_cpu(pcysta_le32->tmaxdiff_cycle[CXT_BT]));
  6171. if (le16_to_cpu(pcysta_le32->cycles) <= 1)
  6172. return;
  6173. /* 1 cycle record 1 wl-slot and 1 bt-slot */
  6174. slot_pair = BTC_CYCLE_SLOT_MAX / 2;
  6175. if (le16_to_cpu(pcysta_le32->cycles) <= slot_pair)
  6176. c_begin = 1;
  6177. else
  6178. c_begin = le16_to_cpu(pcysta_le32->cycles) - slot_pair + 1;
  6179. c_end = le16_to_cpu(pcysta_le32->cycles);
  6180. for (cycle = c_begin; cycle <= c_end; cycle++) {
  6181. cnt++;
  6182. store_index = ((cycle - 1) % slot_pair) * 2;
  6183. if (cnt % (BTC_CYCLE_SLOT_MAX / 4) == 1)
  6184. seq_printf(m,
  6185. " %-15s : ->b%02d->w%02d", "[cycle_step]",
  6186. le16_to_cpu(pcysta_le32->tslot_cycle[store_index]),
  6187. le16_to_cpu(pcysta_le32->tslot_cycle[store_index + 1]));
  6188. else
  6189. seq_printf(m,
  6190. "->b%02d->w%02d",
  6191. le16_to_cpu(pcysta_le32->tslot_cycle[store_index]),
  6192. le16_to_cpu(pcysta_le32->tslot_cycle[store_index + 1]));
  6193. if (cnt % (BTC_CYCLE_SLOT_MAX / 4) == 0 || cnt == c_end)
  6194. seq_puts(m, "\n");
  6195. }
  6196. if (a2dp->exist) {
  6197. seq_printf(m,
  6198. " %-15s : a2dp_ept:%d, a2dp_late:%d",
  6199. "[a2dp_t_sta]",
  6200. le16_to_cpu(pcysta_le32->a2dpept),
  6201. le16_to_cpu(pcysta_le32->a2dpeptto));
  6202. seq_printf(m,
  6203. ", avg_t:%d, max_t:%d",
  6204. le16_to_cpu(pcysta_le32->tavg_a2dpept),
  6205. le16_to_cpu(pcysta_le32->tmax_a2dpept));
  6206. r.val = dm->tdma_now.rxflctrl;
  6207. if (r.type && r.tgln_n) {
  6208. seq_printf(m,
  6209. ", cycle[PSTDMA:%d/TDMA:%d], ",
  6210. le16_to_cpu(pcysta_le32->cycles_a2dp[CXT_FLCTRL_ON]),
  6211. le16_to_cpu(pcysta_le32->cycles_a2dp[CXT_FLCTRL_OFF]));
  6212. seq_printf(m,
  6213. "avg_t[PSTDMA:%d/TDMA:%d], ",
  6214. le16_to_cpu(pcysta_le32->tavg_a2dp[CXT_FLCTRL_ON]),
  6215. le16_to_cpu(pcysta_le32->tavg_a2dp[CXT_FLCTRL_OFF]));
  6216. seq_printf(m,
  6217. "max_t[PSTDMA:%d/TDMA:%d]",
  6218. le16_to_cpu(pcysta_le32->tmax_a2dp[CXT_FLCTRL_ON]),
  6219. le16_to_cpu(pcysta_le32->tmax_a2dp[CXT_FLCTRL_OFF]));
  6220. }
  6221. seq_puts(m, "\n");
  6222. }
  6223. }
  6224. static void _show_fbtc_cysta_v3(struct rtw89_dev *rtwdev, struct seq_file *m)
  6225. {
  6226. struct rtw89_btc *btc = &rtwdev->btc;
  6227. struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc;
  6228. struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
  6229. struct rtw89_btc_dm *dm = &btc->dm;
  6230. struct rtw89_btc_fbtc_a2dp_trx_stat *a2dp_trx;
  6231. struct rtw89_btc_fbtc_cysta_v3 *pcysta;
  6232. struct rtw89_btc_rpt_cmn_info *pcinfo;
  6233. u8 i, cnt = 0, slot_pair, divide_cnt;
  6234. u16 cycle, c_begin, c_end, store_index;
  6235. pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo;
  6236. if (!pcinfo->valid)
  6237. return;
  6238. pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v3;
  6239. seq_printf(m,
  6240. " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]",
  6241. "[cycle_cnt]",
  6242. le16_to_cpu(pcysta->cycles),
  6243. le32_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]),
  6244. le32_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]),
  6245. le32_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]),
  6246. le32_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK]));
  6247. for (i = 0; i < CXST_MAX; i++) {
  6248. if (!le32_to_cpu(pcysta->slot_cnt[i]))
  6249. continue;
  6250. seq_printf(m, ", %s:%d", id_to_slot(i),
  6251. le32_to_cpu(pcysta->slot_cnt[i]));
  6252. }
  6253. if (dm->tdma_now.rxflctrl)
  6254. seq_printf(m, ", leak_rx:%d", le32_to_cpu(pcysta->leak_slot.cnt_rximr));
  6255. if (le32_to_cpu(pcysta->collision_cnt))
  6256. seq_printf(m, ", collision:%d", le32_to_cpu(pcysta->collision_cnt));
  6257. if (le32_to_cpu(pcysta->skip_cnt))
  6258. seq_printf(m, ", skip:%d", le32_to_cpu(pcysta->skip_cnt));
  6259. seq_puts(m, "\n");
  6260. seq_printf(m, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]",
  6261. "[cycle_time]",
  6262. le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]),
  6263. le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]),
  6264. le16_to_cpu(pcysta->leak_slot.tavg) / 1000,
  6265. le16_to_cpu(pcysta->leak_slot.tavg) % 1000);
  6266. seq_printf(m,
  6267. ", max_t[wl:%d/bt:%d/lk:%d.%03d]",
  6268. le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]),
  6269. le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]),
  6270. le16_to_cpu(pcysta->leak_slot.tmax) / 1000,
  6271. le16_to_cpu(pcysta->leak_slot.tmax) % 1000);
  6272. seq_printf(m,
  6273. ", maxdiff_t[wl:%d/bt:%d]\n",
  6274. le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_WL]),
  6275. le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_BT]));
  6276. cycle = le16_to_cpu(pcysta->cycles);
  6277. if (cycle <= 1)
  6278. return;
  6279. /* 1 cycle record 1 wl-slot and 1 bt-slot */
  6280. slot_pair = BTC_CYCLE_SLOT_MAX / 2;
  6281. if (cycle <= slot_pair)
  6282. c_begin = 1;
  6283. else
  6284. c_begin = cycle - slot_pair + 1;
  6285. c_end = cycle;
  6286. if (a2dp->exist)
  6287. divide_cnt = 3;
  6288. else
  6289. divide_cnt = BTC_CYCLE_SLOT_MAX / 4;
  6290. for (cycle = c_begin; cycle <= c_end; cycle++) {
  6291. cnt++;
  6292. store_index = ((cycle - 1) % slot_pair) * 2;
  6293. if (cnt % divide_cnt == 1)
  6294. seq_printf(m, " %-15s : ", "[cycle_step]");
  6295. seq_printf(m, "->b%02d",
  6296. le16_to_cpu(pcysta->slot_step_time[store_index]));
  6297. if (a2dp->exist) {
  6298. a2dp_trx = &pcysta->a2dp_trx[store_index];
  6299. seq_printf(m, "(%d/%d/%dM/%d/%d/%d)",
  6300. a2dp_trx->empty_cnt,
  6301. a2dp_trx->retry_cnt,
  6302. a2dp_trx->tx_rate ? 3 : 2,
  6303. a2dp_trx->tx_cnt,
  6304. a2dp_trx->ack_cnt,
  6305. a2dp_trx->nack_cnt);
  6306. }
  6307. seq_printf(m, "->w%02d",
  6308. le16_to_cpu(pcysta->slot_step_time[store_index + 1]));
  6309. if (a2dp->exist) {
  6310. a2dp_trx = &pcysta->a2dp_trx[store_index + 1];
  6311. seq_printf(m, "(%d/%d/%dM/%d/%d/%d)",
  6312. a2dp_trx->empty_cnt,
  6313. a2dp_trx->retry_cnt,
  6314. a2dp_trx->tx_rate ? 3 : 2,
  6315. a2dp_trx->tx_cnt,
  6316. a2dp_trx->ack_cnt,
  6317. a2dp_trx->nack_cnt);
  6318. }
  6319. if (cnt % divide_cnt == 0 || cnt == c_end)
  6320. seq_puts(m, "\n");
  6321. }
  6322. if (a2dp->exist) {
  6323. seq_printf(m, " %-15s : a2dp_ept:%d, a2dp_late:%d",
  6324. "[a2dp_t_sta]",
  6325. le16_to_cpu(pcysta->a2dp_ept.cnt),
  6326. le16_to_cpu(pcysta->a2dp_ept.cnt_timeout));
  6327. seq_printf(m, ", avg_t:%d, max_t:%d",
  6328. le16_to_cpu(pcysta->a2dp_ept.tavg),
  6329. le16_to_cpu(pcysta->a2dp_ept.tmax));
  6330. seq_puts(m, "\n");
  6331. }
  6332. }
  6333. static void _show_fbtc_cysta_v4(struct rtw89_dev *rtwdev, struct seq_file *m)
  6334. {
  6335. struct rtw89_btc *btc = &rtwdev->btc;
  6336. struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc;
  6337. struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
  6338. struct rtw89_btc_dm *dm = &btc->dm;
  6339. struct rtw89_btc_fbtc_a2dp_trx_stat_v4 *a2dp_trx;
  6340. struct rtw89_btc_fbtc_cysta_v4 *pcysta;
  6341. struct rtw89_btc_rpt_cmn_info *pcinfo;
  6342. u8 i, cnt = 0, slot_pair, divide_cnt;
  6343. u16 cycle, c_begin, c_end, store_index;
  6344. pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo;
  6345. if (!pcinfo->valid)
  6346. return;
  6347. pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v4;
  6348. seq_printf(m,
  6349. " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]",
  6350. "[cycle_cnt]",
  6351. le16_to_cpu(pcysta->cycles),
  6352. le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]),
  6353. le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]),
  6354. le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]),
  6355. le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK]));
  6356. for (i = 0; i < CXST_MAX; i++) {
  6357. if (!le16_to_cpu(pcysta->slot_cnt[i]))
  6358. continue;
  6359. seq_printf(m, ", %s:%d", id_to_slot(i),
  6360. le16_to_cpu(pcysta->slot_cnt[i]));
  6361. }
  6362. if (dm->tdma_now.rxflctrl)
  6363. seq_printf(m, ", leak_rx:%d",
  6364. le32_to_cpu(pcysta->leak_slot.cnt_rximr));
  6365. if (pcysta->collision_cnt)
  6366. seq_printf(m, ", collision:%d", pcysta->collision_cnt);
  6367. if (le16_to_cpu(pcysta->skip_cnt))
  6368. seq_printf(m, ", skip:%d",
  6369. le16_to_cpu(pcysta->skip_cnt));
  6370. seq_puts(m, "\n");
  6371. seq_printf(m, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]",
  6372. "[cycle_time]",
  6373. le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]),
  6374. le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]),
  6375. le16_to_cpu(pcysta->leak_slot.tavg) / 1000,
  6376. le16_to_cpu(pcysta->leak_slot.tavg) % 1000);
  6377. seq_printf(m,
  6378. ", max_t[wl:%d/bt:%d/lk:%d.%03d]",
  6379. le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]),
  6380. le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]),
  6381. le16_to_cpu(pcysta->leak_slot.tmax) / 1000,
  6382. le16_to_cpu(pcysta->leak_slot.tmax) % 1000);
  6383. seq_printf(m,
  6384. ", maxdiff_t[wl:%d/bt:%d]\n",
  6385. le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_WL]),
  6386. le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_BT]));
  6387. cycle = le16_to_cpu(pcysta->cycles);
  6388. if (cycle <= 1)
  6389. return;
  6390. /* 1 cycle record 1 wl-slot and 1 bt-slot */
  6391. slot_pair = BTC_CYCLE_SLOT_MAX / 2;
  6392. if (cycle <= slot_pair)
  6393. c_begin = 1;
  6394. else
  6395. c_begin = cycle - slot_pair + 1;
  6396. c_end = cycle;
  6397. if (a2dp->exist)
  6398. divide_cnt = 3;
  6399. else
  6400. divide_cnt = BTC_CYCLE_SLOT_MAX / 4;
  6401. for (cycle = c_begin; cycle <= c_end; cycle++) {
  6402. cnt++;
  6403. store_index = ((cycle - 1) % slot_pair) * 2;
  6404. if (cnt % divide_cnt == 1)
  6405. seq_printf(m, " %-15s : ", "[cycle_step]");
  6406. seq_printf(m, "->b%02d",
  6407. le16_to_cpu(pcysta->slot_step_time[store_index]));
  6408. if (a2dp->exist) {
  6409. a2dp_trx = &pcysta->a2dp_trx[store_index];
  6410. seq_printf(m, "(%d/%d/%dM/%d/%d/%d)",
  6411. a2dp_trx->empty_cnt,
  6412. a2dp_trx->retry_cnt,
  6413. a2dp_trx->tx_rate ? 3 : 2,
  6414. a2dp_trx->tx_cnt,
  6415. a2dp_trx->ack_cnt,
  6416. a2dp_trx->nack_cnt);
  6417. }
  6418. seq_printf(m, "->w%02d",
  6419. le16_to_cpu(pcysta->slot_step_time[store_index + 1]));
  6420. if (a2dp->exist) {
  6421. a2dp_trx = &pcysta->a2dp_trx[store_index + 1];
  6422. seq_printf(m, "(%d/%d/%dM/%d/%d/%d)",
  6423. a2dp_trx->empty_cnt,
  6424. a2dp_trx->retry_cnt,
  6425. a2dp_trx->tx_rate ? 3 : 2,
  6426. a2dp_trx->tx_cnt,
  6427. a2dp_trx->ack_cnt,
  6428. a2dp_trx->nack_cnt);
  6429. }
  6430. if (cnt % divide_cnt == 0 || cnt == c_end)
  6431. seq_puts(m, "\n");
  6432. }
  6433. if (a2dp->exist) {
  6434. seq_printf(m, " %-15s : a2dp_ept:%d, a2dp_late:%d",
  6435. "[a2dp_t_sta]",
  6436. le16_to_cpu(pcysta->a2dp_ept.cnt),
  6437. le16_to_cpu(pcysta->a2dp_ept.cnt_timeout));
  6438. seq_printf(m, ", avg_t:%d, max_t:%d",
  6439. le16_to_cpu(pcysta->a2dp_ept.tavg),
  6440. le16_to_cpu(pcysta->a2dp_ept.tmax));
  6441. seq_puts(m, "\n");
  6442. }
  6443. }
  6444. static void _show_fbtc_cysta_v5(struct rtw89_dev *rtwdev, struct seq_file *m)
  6445. {
  6446. struct rtw89_btc *btc = &rtwdev->btc;
  6447. struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc;
  6448. struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
  6449. struct rtw89_btc_dm *dm = &btc->dm;
  6450. struct rtw89_btc_fbtc_a2dp_trx_stat_v4 *a2dp_trx;
  6451. struct rtw89_btc_fbtc_cysta_v5 *pcysta;
  6452. struct rtw89_btc_rpt_cmn_info *pcinfo;
  6453. u8 i, cnt = 0, slot_pair, divide_cnt;
  6454. u16 cycle, c_begin, c_end, store_index;
  6455. pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo;
  6456. if (!pcinfo->valid)
  6457. return;
  6458. pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v5;
  6459. seq_printf(m,
  6460. " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]",
  6461. "[cycle_cnt]",
  6462. le16_to_cpu(pcysta->cycles),
  6463. le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]),
  6464. le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]),
  6465. le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]),
  6466. le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK]));
  6467. for (i = 0; i < CXST_MAX; i++) {
  6468. if (!le16_to_cpu(pcysta->slot_cnt[i]))
  6469. continue;
  6470. seq_printf(m, ", %s:%d", id_to_slot(i),
  6471. le16_to_cpu(pcysta->slot_cnt[i]));
  6472. }
  6473. if (dm->tdma_now.rxflctrl)
  6474. seq_printf(m, ", leak_rx:%d",
  6475. le32_to_cpu(pcysta->leak_slot.cnt_rximr));
  6476. if (pcysta->collision_cnt)
  6477. seq_printf(m, ", collision:%d", pcysta->collision_cnt);
  6478. if (le16_to_cpu(pcysta->skip_cnt))
  6479. seq_printf(m, ", skip:%d",
  6480. le16_to_cpu(pcysta->skip_cnt));
  6481. seq_puts(m, "\n");
  6482. seq_printf(m, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]",
  6483. "[cycle_time]",
  6484. le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]),
  6485. le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]),
  6486. le16_to_cpu(pcysta->leak_slot.tavg) / 1000,
  6487. le16_to_cpu(pcysta->leak_slot.tavg) % 1000);
  6488. seq_printf(m,
  6489. ", max_t[wl:%d/bt:%d/lk:%d.%03d]\n",
  6490. le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]),
  6491. le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]),
  6492. le16_to_cpu(pcysta->leak_slot.tmax) / 1000,
  6493. le16_to_cpu(pcysta->leak_slot.tmax) % 1000);
  6494. cycle = le16_to_cpu(pcysta->cycles);
  6495. if (cycle <= 1)
  6496. return;
  6497. /* 1 cycle record 1 wl-slot and 1 bt-slot */
  6498. slot_pair = BTC_CYCLE_SLOT_MAX / 2;
  6499. if (cycle <= slot_pair)
  6500. c_begin = 1;
  6501. else
  6502. c_begin = cycle - slot_pair + 1;
  6503. c_end = cycle;
  6504. if (a2dp->exist)
  6505. divide_cnt = 3;
  6506. else
  6507. divide_cnt = BTC_CYCLE_SLOT_MAX / 4;
  6508. if (c_begin > c_end)
  6509. return;
  6510. for (cycle = c_begin; cycle <= c_end; cycle++) {
  6511. cnt++;
  6512. store_index = ((cycle - 1) % slot_pair) * 2;
  6513. if (cnt % divide_cnt == 1)
  6514. seq_printf(m, " %-15s : ", "[cycle_step]");
  6515. seq_printf(m, "->b%02d",
  6516. le16_to_cpu(pcysta->slot_step_time[store_index]));
  6517. if (a2dp->exist) {
  6518. a2dp_trx = &pcysta->a2dp_trx[store_index];
  6519. seq_printf(m, "(%d/%d/%dM/%d/%d/%d)",
  6520. a2dp_trx->empty_cnt,
  6521. a2dp_trx->retry_cnt,
  6522. a2dp_trx->tx_rate ? 3 : 2,
  6523. a2dp_trx->tx_cnt,
  6524. a2dp_trx->ack_cnt,
  6525. a2dp_trx->nack_cnt);
  6526. }
  6527. seq_printf(m, "->w%02d",
  6528. le16_to_cpu(pcysta->slot_step_time[store_index + 1]));
  6529. if (a2dp->exist) {
  6530. a2dp_trx = &pcysta->a2dp_trx[store_index + 1];
  6531. seq_printf(m, "(%d/%d/%dM/%d/%d/%d)",
  6532. a2dp_trx->empty_cnt,
  6533. a2dp_trx->retry_cnt,
  6534. a2dp_trx->tx_rate ? 3 : 2,
  6535. a2dp_trx->tx_cnt,
  6536. a2dp_trx->ack_cnt,
  6537. a2dp_trx->nack_cnt);
  6538. }
  6539. if (cnt % divide_cnt == 0 || cnt == c_end)
  6540. seq_puts(m, "\n");
  6541. }
  6542. if (a2dp->exist) {
  6543. seq_printf(m, " %-15s : a2dp_ept:%d, a2dp_late:%d",
  6544. "[a2dp_t_sta]",
  6545. le16_to_cpu(pcysta->a2dp_ept.cnt),
  6546. le16_to_cpu(pcysta->a2dp_ept.cnt_timeout));
  6547. seq_printf(m, ", avg_t:%d, max_t:%d",
  6548. le16_to_cpu(pcysta->a2dp_ept.tavg),
  6549. le16_to_cpu(pcysta->a2dp_ept.tmax));
  6550. seq_puts(m, "\n");
  6551. }
  6552. }
  6553. static void _show_fbtc_nullsta(struct rtw89_dev *rtwdev, struct seq_file *m)
  6554. {
  6555. struct rtw89_btc *btc = &rtwdev->btc;
  6556. const struct rtw89_btc_ver *ver = btc->ver;
  6557. struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
  6558. struct rtw89_btc_rpt_cmn_info *pcinfo;
  6559. union rtw89_btc_fbtc_cynullsta_info *ns;
  6560. u8 i = 0;
  6561. if (!btc->dm.tdma_now.rxflctrl)
  6562. return;
  6563. pcinfo = &pfwinfo->rpt_fbtc_nullsta.cinfo;
  6564. if (!pcinfo->valid)
  6565. return;
  6566. ns = &pfwinfo->rpt_fbtc_nullsta.finfo;
  6567. if (ver->fcxnullsta == 1) {
  6568. for (i = 0; i < 2; i++) {
  6569. seq_printf(m, " %-15s : ", "[NULL-STA]");
  6570. seq_printf(m, "null-%d", i);
  6571. seq_printf(m, "[ok:%d/",
  6572. le32_to_cpu(ns->v1.result[i][1]));
  6573. seq_printf(m, "fail:%d/",
  6574. le32_to_cpu(ns->v1.result[i][0]));
  6575. seq_printf(m, "on_time:%d/",
  6576. le32_to_cpu(ns->v1.result[i][2]));
  6577. seq_printf(m, "retry:%d/",
  6578. le32_to_cpu(ns->v1.result[i][3]));
  6579. seq_printf(m, "avg_t:%d.%03d/",
  6580. le32_to_cpu(ns->v1.avg_t[i]) / 1000,
  6581. le32_to_cpu(ns->v1.avg_t[i]) % 1000);
  6582. seq_printf(m, "max_t:%d.%03d]\n",
  6583. le32_to_cpu(ns->v1.max_t[i]) / 1000,
  6584. le32_to_cpu(ns->v1.max_t[i]) % 1000);
  6585. }
  6586. } else {
  6587. for (i = 0; i < 2; i++) {
  6588. seq_printf(m, " %-15s : ", "[NULL-STA]");
  6589. seq_printf(m, "null-%d", i);
  6590. seq_printf(m, "[Tx:%d/",
  6591. le32_to_cpu(ns->v2.result[i][4]));
  6592. seq_printf(m, "[ok:%d/",
  6593. le32_to_cpu(ns->v2.result[i][1]));
  6594. seq_printf(m, "fail:%d/",
  6595. le32_to_cpu(ns->v2.result[i][0]));
  6596. seq_printf(m, "on_time:%d/",
  6597. le32_to_cpu(ns->v2.result[i][2]));
  6598. seq_printf(m, "retry:%d/",
  6599. le32_to_cpu(ns->v2.result[i][3]));
  6600. seq_printf(m, "avg_t:%d.%03d/",
  6601. le32_to_cpu(ns->v2.avg_t[i]) / 1000,
  6602. le32_to_cpu(ns->v2.avg_t[i]) % 1000);
  6603. seq_printf(m, "max_t:%d.%03d]\n",
  6604. le32_to_cpu(ns->v2.max_t[i]) / 1000,
  6605. le32_to_cpu(ns->v2.max_t[i]) % 1000);
  6606. }
  6607. }
  6608. }
  6609. static void _show_fbtc_step_v2(struct rtw89_dev *rtwdev, struct seq_file *m)
  6610. {
  6611. struct rtw89_btc *btc = &rtwdev->btc;
  6612. struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
  6613. struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
  6614. struct rtw89_btc_fbtc_steps_v2 *pstep = NULL;
  6615. u8 type, val, cnt = 0, state = 0;
  6616. bool outloop = false;
  6617. u16 i, diff_t, n_start = 0, n_stop = 0;
  6618. u16 pos_old, pos_new;
  6619. pcinfo = &pfwinfo->rpt_fbtc_step.cinfo;
  6620. if (!pcinfo->valid)
  6621. return;
  6622. pstep = &pfwinfo->rpt_fbtc_step.finfo.v2;
  6623. pos_old = le16_to_cpu(pstep->pos_old);
  6624. pos_new = le16_to_cpu(pstep->pos_new);
  6625. if (pcinfo->req_fver != pstep->fver)
  6626. return;
  6627. /* store step info by using ring instead of FIFO*/
  6628. do {
  6629. switch (state) {
  6630. case 0:
  6631. n_start = pos_old;
  6632. if (pos_new >= pos_old)
  6633. n_stop = pos_new;
  6634. else
  6635. n_stop = btc->ctrl.trace_step - 1;
  6636. state = 1;
  6637. break;
  6638. case 1:
  6639. for (i = n_start; i <= n_stop; i++) {
  6640. type = pstep->step[i].type;
  6641. val = pstep->step[i].val;
  6642. diff_t = le16_to_cpu(pstep->step[i].difft);
  6643. if (type == CXSTEP_NONE || type >= CXSTEP_MAX)
  6644. continue;
  6645. if (cnt % 10 == 0)
  6646. seq_printf(m, " %-15s : ", "[steps]");
  6647. seq_printf(m, "-> %s(%02d)(%02d)",
  6648. (type == CXSTEP_SLOT ? "SLT" :
  6649. "EVT"), (u32)val, diff_t);
  6650. if (cnt % 10 == 9)
  6651. seq_puts(m, "\n");
  6652. cnt++;
  6653. }
  6654. state = 2;
  6655. break;
  6656. case 2:
  6657. if (pos_new < pos_old && n_start != 0) {
  6658. n_start = 0;
  6659. n_stop = pos_new;
  6660. state = 1;
  6661. } else {
  6662. outloop = true;
  6663. }
  6664. break;
  6665. }
  6666. } while (!outloop);
  6667. }
  6668. static void _show_fbtc_step_v3(struct rtw89_dev *rtwdev, struct seq_file *m)
  6669. {
  6670. struct rtw89_btc *btc = &rtwdev->btc;
  6671. struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
  6672. struct rtw89_btc_rpt_cmn_info *pcinfo;
  6673. struct rtw89_btc_fbtc_steps_v3 *pstep;
  6674. u32 i, n_begin, n_end, array_idx, cnt = 0;
  6675. u8 type, val;
  6676. u16 diff_t;
  6677. if ((pfwinfo->rpt_en_map &
  6678. rtw89_btc_fw_rpt_ver(rtwdev, RPT_EN_FW_STEP_INFO)) == 0)
  6679. return;
  6680. pcinfo = &pfwinfo->rpt_fbtc_step.cinfo;
  6681. if (!pcinfo->valid)
  6682. return;
  6683. pstep = &pfwinfo->rpt_fbtc_step.finfo.v3;
  6684. if (pcinfo->req_fver != pstep->fver)
  6685. return;
  6686. if (le32_to_cpu(pstep->cnt) <= FCXDEF_STEP)
  6687. n_begin = 1;
  6688. else
  6689. n_begin = le32_to_cpu(pstep->cnt) - FCXDEF_STEP + 1;
  6690. n_end = le32_to_cpu(pstep->cnt);
  6691. if (n_begin > n_end)
  6692. return;
  6693. /* restore step info by using ring instead of FIFO */
  6694. for (i = n_begin; i <= n_end; i++) {
  6695. array_idx = (i - 1) % FCXDEF_STEP;
  6696. type = pstep->step[array_idx].type;
  6697. val = pstep->step[array_idx].val;
  6698. diff_t = le16_to_cpu(pstep->step[array_idx].difft);
  6699. if (type == CXSTEP_NONE || type >= CXSTEP_MAX)
  6700. continue;
  6701. if (cnt % 10 == 0)
  6702. seq_printf(m, " %-15s : ", "[steps]");
  6703. seq_printf(m, "-> %s(%02d)",
  6704. (type == CXSTEP_SLOT ?
  6705. id_to_slot((u32)val) :
  6706. id_to_evt((u32)val)), diff_t);
  6707. if (cnt % 10 == 9)
  6708. seq_puts(m, "\n");
  6709. cnt++;
  6710. }
  6711. }
  6712. static void _show_fw_dm_msg(struct rtw89_dev *rtwdev, struct seq_file *m)
  6713. {
  6714. struct rtw89_btc *btc = &rtwdev->btc;
  6715. const struct rtw89_btc_ver *ver = btc->ver;
  6716. if (!(btc->dm.coex_info_map & BTC_COEX_INFO_DM))
  6717. return;
  6718. _show_error(rtwdev, m);
  6719. _show_fbtc_tdma(rtwdev, m);
  6720. _show_fbtc_slots(rtwdev, m);
  6721. if (ver->fcxcysta == 2)
  6722. _show_fbtc_cysta_v2(rtwdev, m);
  6723. else if (ver->fcxcysta == 3)
  6724. _show_fbtc_cysta_v3(rtwdev, m);
  6725. else if (ver->fcxcysta == 4)
  6726. _show_fbtc_cysta_v4(rtwdev, m);
  6727. else if (ver->fcxcysta == 5)
  6728. _show_fbtc_cysta_v5(rtwdev, m);
  6729. _show_fbtc_nullsta(rtwdev, m);
  6730. if (ver->fcxstep == 2)
  6731. _show_fbtc_step_v2(rtwdev, m);
  6732. else if (ver->fcxstep == 3)
  6733. _show_fbtc_step_v3(rtwdev, m);
  6734. }
  6735. static void _get_gnt(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_coex_gnt *gnt_cfg)
  6736. {
  6737. const struct rtw89_chip_info *chip = rtwdev->chip;
  6738. struct rtw89_mac_ax_gnt *gnt;
  6739. u32 val, status;
  6740. if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B) {
  6741. rtw89_mac_read_lte(rtwdev, R_AX_LTE_SW_CFG_1, &val);
  6742. rtw89_mac_read_lte(rtwdev, R_AX_GNT_VAL, &status);
  6743. gnt = &gnt_cfg->band[0];
  6744. gnt->gnt_bt_sw_en = !!(val & B_AX_GNT_BT_RFC_S0_SW_CTRL);
  6745. gnt->gnt_bt = !!(status & B_AX_GNT_BT_RFC_S0_STA);
  6746. gnt->gnt_wl_sw_en = !!(val & B_AX_GNT_WL_RFC_S0_SW_CTRL);
  6747. gnt->gnt_wl = !!(status & B_AX_GNT_WL_RFC_S0_STA);
  6748. gnt = &gnt_cfg->band[1];
  6749. gnt->gnt_bt_sw_en = !!(val & B_AX_GNT_BT_RFC_S1_SW_CTRL);
  6750. gnt->gnt_bt = !!(status & B_AX_GNT_BT_RFC_S1_STA);
  6751. gnt->gnt_wl_sw_en = !!(val & B_AX_GNT_WL_RFC_S1_SW_CTRL);
  6752. gnt->gnt_wl = !!(status & B_AX_GNT_WL_RFC_S1_STA);
  6753. } else if (chip->chip_id == RTL8852C) {
  6754. val = rtw89_read32(rtwdev, R_AX_GNT_SW_CTRL);
  6755. status = rtw89_read32(rtwdev, R_AX_GNT_VAL_V1);
  6756. gnt = &gnt_cfg->band[0];
  6757. gnt->gnt_bt_sw_en = !!(val & B_AX_GNT_BT_RFC_S0_SWCTRL);
  6758. gnt->gnt_bt = !!(status & B_AX_GNT_BT_RFC_S0);
  6759. gnt->gnt_wl_sw_en = !!(val & B_AX_GNT_WL_RFC_S0_SWCTRL);
  6760. gnt->gnt_wl = !!(status & B_AX_GNT_WL_RFC_S0);
  6761. gnt = &gnt_cfg->band[1];
  6762. gnt->gnt_bt_sw_en = !!(val & B_AX_GNT_BT_RFC_S1_SWCTRL);
  6763. gnt->gnt_bt = !!(status & B_AX_GNT_BT_RFC_S1);
  6764. gnt->gnt_wl_sw_en = !!(val & B_AX_GNT_WL_RFC_S1_SWCTRL);
  6765. gnt->gnt_wl = !!(status & B_AX_GNT_WL_RFC_S1);
  6766. } else {
  6767. return;
  6768. }
  6769. }
  6770. static void _show_mreg_v1(struct rtw89_dev *rtwdev, struct seq_file *m)
  6771. {
  6772. const struct rtw89_chip_info *chip = rtwdev->chip;
  6773. struct rtw89_btc *btc = &rtwdev->btc;
  6774. struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
  6775. struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
  6776. struct rtw89_btc_fbtc_mreg_val_v1 *pmreg = NULL;
  6777. struct rtw89_btc_fbtc_gpio_dbg *gdbg = NULL;
  6778. struct rtw89_btc_cx *cx = &btc->cx;
  6779. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  6780. struct rtw89_btc_bt_info *bt = &btc->cx.bt;
  6781. struct rtw89_mac_ax_coex_gnt gnt_cfg = {};
  6782. struct rtw89_mac_ax_gnt gnt;
  6783. u8 i = 0, type = 0, cnt = 0;
  6784. u32 val, offset;
  6785. if (!(btc->dm.coex_info_map & BTC_COEX_INFO_MREG))
  6786. return;
  6787. seq_puts(m, "========== [HW Status] ==========\n");
  6788. seq_printf(m,
  6789. " %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)\n",
  6790. "[scoreboard]", wl->scbd, cx->cnt_wl[BTC_WCNT_SCBDUPDATE],
  6791. bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD],
  6792. cx->cnt_bt[BTC_BCNT_SCBDUPDATE]);
  6793. /* To avoid I/O if WL LPS or power-off */
  6794. if (!wl->status.map.lps && !wl->status.map.rf_off) {
  6795. btc->dm.pta_owner = rtw89_mac_get_ctrl_path(rtwdev);
  6796. _get_gnt(rtwdev, &gnt_cfg);
  6797. gnt = gnt_cfg.band[0];
  6798. seq_printf(m,
  6799. " %-15s : pta_owner:%s, phy-0[gnt_wl:%s-%d/gnt_bt:%s-%d], ",
  6800. "[gnt_status]",
  6801. chip->chip_id == RTL8852C ? "HW" :
  6802. btc->dm.pta_owner == BTC_CTRL_BY_WL ? "WL" : "BT",
  6803. gnt.gnt_wl_sw_en ? "SW" : "HW", gnt.gnt_wl,
  6804. gnt.gnt_bt_sw_en ? "SW" : "HW", gnt.gnt_bt);
  6805. gnt = gnt_cfg.band[1];
  6806. seq_printf(m, "phy-1[gnt_wl:%s-%d/gnt_bt:%s-%d]\n",
  6807. gnt.gnt_wl_sw_en ? "SW" : "HW",
  6808. gnt.gnt_wl,
  6809. gnt.gnt_bt_sw_en ? "SW" : "HW",
  6810. gnt.gnt_bt);
  6811. }
  6812. pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo;
  6813. if (!pcinfo->valid) {
  6814. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  6815. "[BTC], %s(): stop due rpt_fbtc_mregval.cinfo\n",
  6816. __func__);
  6817. return;
  6818. }
  6819. pmreg = &pfwinfo->rpt_fbtc_mregval.finfo.v1;
  6820. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  6821. "[BTC], %s(): rpt_fbtc_mregval reg_num = %d\n",
  6822. __func__, pmreg->reg_num);
  6823. for (i = 0; i < pmreg->reg_num; i++) {
  6824. type = (u8)le16_to_cpu(chip->mon_reg[i].type);
  6825. offset = le32_to_cpu(chip->mon_reg[i].offset);
  6826. val = le32_to_cpu(pmreg->mreg_val[i]);
  6827. if (cnt % 6 == 0)
  6828. seq_printf(m, " %-15s : %d_0x%04x=0x%08x",
  6829. "[reg]", (u32)type, offset, val);
  6830. else
  6831. seq_printf(m, ", %d_0x%04x=0x%08x", (u32)type,
  6832. offset, val);
  6833. if (cnt % 6 == 5)
  6834. seq_puts(m, "\n");
  6835. cnt++;
  6836. if (i >= pmreg->reg_num)
  6837. seq_puts(m, "\n");
  6838. }
  6839. pcinfo = &pfwinfo->rpt_fbtc_gpio_dbg.cinfo;
  6840. if (!pcinfo->valid) {
  6841. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  6842. "[BTC], %s(): stop due rpt_fbtc_gpio_dbg.cinfo\n",
  6843. __func__);
  6844. seq_puts(m, "\n");
  6845. return;
  6846. }
  6847. gdbg = &pfwinfo->rpt_fbtc_gpio_dbg.finfo;
  6848. if (!gdbg->en_map)
  6849. return;
  6850. seq_printf(m, " %-15s : enable_map:0x%08x",
  6851. "[gpio_dbg]", gdbg->en_map);
  6852. for (i = 0; i < BTC_DBG_MAX1; i++) {
  6853. if (!(gdbg->en_map & BIT(i)))
  6854. continue;
  6855. seq_printf(m, ", %d->GPIO%d", (u32)i, gdbg->gpio_map[i]);
  6856. }
  6857. seq_puts(m, "\n");
  6858. }
  6859. static void _show_mreg_v2(struct rtw89_dev *rtwdev, struct seq_file *m)
  6860. {
  6861. const struct rtw89_chip_info *chip = rtwdev->chip;
  6862. struct rtw89_btc *btc = &rtwdev->btc;
  6863. struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
  6864. struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
  6865. struct rtw89_btc_fbtc_mreg_val_v2 *pmreg = NULL;
  6866. struct rtw89_btc_fbtc_gpio_dbg *gdbg = NULL;
  6867. struct rtw89_btc_cx *cx = &btc->cx;
  6868. struct rtw89_btc_wl_info *wl = &btc->cx.wl;
  6869. struct rtw89_btc_bt_info *bt = &btc->cx.bt;
  6870. struct rtw89_mac_ax_coex_gnt gnt_cfg = {};
  6871. struct rtw89_mac_ax_gnt gnt;
  6872. u8 i = 0, type = 0, cnt = 0;
  6873. u32 val, offset;
  6874. if (!(btc->dm.coex_info_map & BTC_COEX_INFO_MREG))
  6875. return;
  6876. seq_puts(m, "========== [HW Status] ==========\n");
  6877. seq_printf(m,
  6878. " %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)\n",
  6879. "[scoreboard]", wl->scbd, cx->cnt_wl[BTC_WCNT_SCBDUPDATE],
  6880. bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD],
  6881. cx->cnt_bt[BTC_BCNT_SCBDUPDATE]);
  6882. /* To avoid I/O if WL LPS or power-off */
  6883. if (!wl->status.map.lps && !wl->status.map.rf_off) {
  6884. btc->dm.pta_owner = rtw89_mac_get_ctrl_path(rtwdev);
  6885. _get_gnt(rtwdev, &gnt_cfg);
  6886. gnt = gnt_cfg.band[0];
  6887. seq_printf(m,
  6888. " %-15s : pta_owner:%s, phy-0[gnt_wl:%s-%d/gnt_bt:%s-%d], ",
  6889. "[gnt_status]",
  6890. chip->chip_id == RTL8852C ? "HW" :
  6891. btc->dm.pta_owner == BTC_CTRL_BY_WL ? "WL" : "BT",
  6892. gnt.gnt_wl_sw_en ? "SW" : "HW", gnt.gnt_wl,
  6893. gnt.gnt_bt_sw_en ? "SW" : "HW", gnt.gnt_bt);
  6894. gnt = gnt_cfg.band[1];
  6895. seq_printf(m, "phy-1[gnt_wl:%s-%d/gnt_bt:%s-%d]\n",
  6896. gnt.gnt_wl_sw_en ? "SW" : "HW",
  6897. gnt.gnt_wl,
  6898. gnt.gnt_bt_sw_en ? "SW" : "HW",
  6899. gnt.gnt_bt);
  6900. }
  6901. pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo;
  6902. if (!pcinfo->valid) {
  6903. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  6904. "[BTC], %s(): stop due rpt_fbtc_mregval.cinfo\n",
  6905. __func__);
  6906. return;
  6907. }
  6908. pmreg = &pfwinfo->rpt_fbtc_mregval.finfo.v2;
  6909. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  6910. "[BTC], %s(): rpt_fbtc_mregval reg_num = %d\n",
  6911. __func__, pmreg->reg_num);
  6912. for (i = 0; i < pmreg->reg_num; i++) {
  6913. type = (u8)le16_to_cpu(chip->mon_reg[i].type);
  6914. offset = le32_to_cpu(chip->mon_reg[i].offset);
  6915. val = le32_to_cpu(pmreg->mreg_val[i]);
  6916. if (cnt % 6 == 0)
  6917. seq_printf(m, " %-15s : %d_0x%04x=0x%08x",
  6918. "[reg]", (u32)type, offset, val);
  6919. else
  6920. seq_printf(m, ", %d_0x%04x=0x%08x", (u32)type,
  6921. offset, val);
  6922. if (cnt % 6 == 5)
  6923. seq_puts(m, "\n");
  6924. cnt++;
  6925. if (i >= pmreg->reg_num)
  6926. seq_puts(m, "\n");
  6927. }
  6928. pcinfo = &pfwinfo->rpt_fbtc_gpio_dbg.cinfo;
  6929. if (!pcinfo->valid) {
  6930. rtw89_debug(rtwdev, RTW89_DBG_BTC,
  6931. "[BTC], %s(): stop due rpt_fbtc_gpio_dbg.cinfo\n",
  6932. __func__);
  6933. seq_puts(m, "\n");
  6934. return;
  6935. }
  6936. gdbg = &pfwinfo->rpt_fbtc_gpio_dbg.finfo;
  6937. if (!gdbg->en_map)
  6938. return;
  6939. seq_printf(m, " %-15s : enable_map:0x%08x",
  6940. "[gpio_dbg]", gdbg->en_map);
  6941. for (i = 0; i < BTC_DBG_MAX1; i++) {
  6942. if (!(gdbg->en_map & BIT(i)))
  6943. continue;
  6944. seq_printf(m, ", %d->GPIO%d", (u32)i, gdbg->gpio_map[i]);
  6945. }
  6946. seq_puts(m, "\n");
  6947. }
  6948. static void _show_summary_v1(struct rtw89_dev *rtwdev, struct seq_file *m)
  6949. {
  6950. struct rtw89_btc *btc = &rtwdev->btc;
  6951. struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
  6952. struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
  6953. struct rtw89_btc_fbtc_rpt_ctrl_v1 *prptctrl = NULL;
  6954. struct rtw89_btc_cx *cx = &btc->cx;
  6955. struct rtw89_btc_dm *dm = &btc->dm;
  6956. struct rtw89_btc_wl_info *wl = &cx->wl;
  6957. struct rtw89_btc_bt_info *bt = &cx->bt;
  6958. u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify;
  6959. u8 i;
  6960. if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY))
  6961. return;
  6962. seq_puts(m, "========== [Statistics] ==========\n");
  6963. pcinfo = &pfwinfo->rpt_ctrl.cinfo;
  6964. if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) {
  6965. prptctrl = &pfwinfo->rpt_ctrl.finfo.v1;
  6966. seq_printf(m,
  6967. " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d), ",
  6968. "[summary]", pfwinfo->cnt_h2c,
  6969. pfwinfo->cnt_h2c_fail, prptctrl->h2c_cnt,
  6970. pfwinfo->cnt_c2h, prptctrl->c2h_cnt);
  6971. seq_printf(m,
  6972. "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x, dm_error_map:0x%x",
  6973. pfwinfo->event[BTF_EVNT_RPT], prptctrl->rpt_cnt,
  6974. prptctrl->rpt_enable, dm->error.val);
  6975. if (dm->error.map.wl_fw_hang)
  6976. seq_puts(m, " (WL FW Hang!!)");
  6977. seq_puts(m, "\n");
  6978. seq_printf(m,
  6979. " %-15s : send_ok:%d, send_fail:%d, recv:%d",
  6980. "[mailbox]", prptctrl->mb_send_ok_cnt,
  6981. prptctrl->mb_send_fail_cnt, prptctrl->mb_recv_cnt);
  6982. seq_printf(m,
  6983. "(A2DP_empty:%d, A2DP_flowstop:%d, A2DP_full:%d)\n",
  6984. prptctrl->mb_a2dp_empty_cnt,
  6985. prptctrl->mb_a2dp_flct_cnt,
  6986. prptctrl->mb_a2dp_full_cnt);
  6987. seq_printf(m,
  6988. " %-15s : wl_rfk[req:%d/go:%d/reject:%d/timeout:%d]",
  6989. "[RFK]", cx->cnt_wl[BTC_WCNT_RFK_REQ],
  6990. cx->cnt_wl[BTC_WCNT_RFK_GO],
  6991. cx->cnt_wl[BTC_WCNT_RFK_REJECT],
  6992. cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]);
  6993. seq_printf(m,
  6994. ", bt_rfk[req:%d/go:%d/reject:%d/timeout:%d/fail:%d]\n",
  6995. prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_REQ],
  6996. prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_GO],
  6997. prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_REJECT],
  6998. prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_TIMEOUT],
  6999. prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_FAIL]);
  7000. if (prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_TIMEOUT] > 0)
  7001. bt->rfk_info.map.timeout = 1;
  7002. else
  7003. bt->rfk_info.map.timeout = 0;
  7004. dm->error.map.wl_rfk_timeout = bt->rfk_info.map.timeout;
  7005. } else {
  7006. seq_printf(m,
  7007. " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d, rpt_cnt=%d, rpt_map=0x%x",
  7008. "[summary]", pfwinfo->cnt_h2c,
  7009. pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h,
  7010. pfwinfo->event[BTF_EVNT_RPT],
  7011. btc->fwinfo.rpt_en_map);
  7012. seq_puts(m, " (WL FW report invalid!!)\n");
  7013. }
  7014. for (i = 0; i < BTC_NCNT_NUM; i++)
  7015. cnt_sum += dm->cnt_notify[i];
  7016. seq_printf(m,
  7017. " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ",
  7018. "[notify_cnt]", cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO],
  7019. cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]);
  7020. seq_printf(m,
  7021. "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d\n",
  7022. cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE],
  7023. cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK],
  7024. cnt[BTC_NCNT_WL_STA]);
  7025. seq_printf(m,
  7026. " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ",
  7027. "[notify_cnt]", cnt[BTC_NCNT_SCAN_START],
  7028. cnt[BTC_NCNT_SCAN_FINISH], cnt[BTC_NCNT_SWITCH_BAND],
  7029. cnt[BTC_NCNT_SPECIAL_PACKET]);
  7030. seq_printf(m,
  7031. "timer=%d, control=%d, customerize=%d\n",
  7032. cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL],
  7033. cnt[BTC_NCNT_CUSTOMERIZE]);
  7034. }
  7035. static void _show_summary_v4(struct rtw89_dev *rtwdev, struct seq_file *m)
  7036. {
  7037. struct rtw89_btc *btc = &rtwdev->btc;
  7038. struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
  7039. struct rtw89_btc_fbtc_rpt_ctrl_v4 *prptctrl;
  7040. struct rtw89_btc_rpt_cmn_info *pcinfo;
  7041. struct rtw89_btc_cx *cx = &btc->cx;
  7042. struct rtw89_btc_dm *dm = &btc->dm;
  7043. struct rtw89_btc_wl_info *wl = &cx->wl;
  7044. struct rtw89_btc_bt_info *bt = &cx->bt;
  7045. u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify;
  7046. u8 i;
  7047. if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY))
  7048. return;
  7049. seq_puts(m, "========== [Statistics] ==========\n");
  7050. pcinfo = &pfwinfo->rpt_ctrl.cinfo;
  7051. if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) {
  7052. prptctrl = &pfwinfo->rpt_ctrl.finfo.v4;
  7053. seq_printf(m,
  7054. " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d), ",
  7055. "[summary]", pfwinfo->cnt_h2c,
  7056. pfwinfo->cnt_h2c_fail,
  7057. le32_to_cpu(prptctrl->rpt_info.cnt_h2c),
  7058. pfwinfo->cnt_c2h,
  7059. le32_to_cpu(prptctrl->rpt_info.cnt_c2h));
  7060. seq_printf(m,
  7061. "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x, dm_error_map:0x%x",
  7062. pfwinfo->event[BTF_EVNT_RPT],
  7063. le32_to_cpu(prptctrl->rpt_info.cnt),
  7064. le32_to_cpu(prptctrl->rpt_info.en),
  7065. dm->error.val);
  7066. if (dm->error.map.wl_fw_hang)
  7067. seq_puts(m, " (WL FW Hang!!)");
  7068. seq_puts(m, "\n");
  7069. seq_printf(m,
  7070. " %-15s : send_ok:%d, send_fail:%d, recv:%d, ",
  7071. "[mailbox]",
  7072. le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok),
  7073. le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail),
  7074. le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv));
  7075. seq_printf(m,
  7076. "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n",
  7077. le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty),
  7078. le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl),
  7079. le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx),
  7080. le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack),
  7081. le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack));
  7082. seq_printf(m,
  7083. " %-15s : wl_rfk[req:%d/go:%d/reject:%d/timeout:%d]",
  7084. "[RFK]", cx->cnt_wl[BTC_WCNT_RFK_REQ],
  7085. cx->cnt_wl[BTC_WCNT_RFK_GO],
  7086. cx->cnt_wl[BTC_WCNT_RFK_REJECT],
  7087. cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]);
  7088. seq_printf(m,
  7089. ", bt_rfk[req:%d/go:%d/reject:%d/timeout:%d/fail:%d]\n",
  7090. le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ]),
  7091. le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_GO]),
  7092. le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REJECT]),
  7093. le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_TIMEOUT]),
  7094. le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_FAIL]));
  7095. if (le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_TIMEOUT]) > 0)
  7096. bt->rfk_info.map.timeout = 1;
  7097. else
  7098. bt->rfk_info.map.timeout = 0;
  7099. dm->error.map.wl_rfk_timeout = bt->rfk_info.map.timeout;
  7100. } else {
  7101. seq_printf(m,
  7102. " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d, rpt_cnt=%d, rpt_map=0x%x",
  7103. "[summary]", pfwinfo->cnt_h2c,
  7104. pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h,
  7105. pfwinfo->event[BTF_EVNT_RPT],
  7106. btc->fwinfo.rpt_en_map);
  7107. seq_puts(m, " (WL FW report invalid!!)\n");
  7108. }
  7109. for (i = 0; i < BTC_NCNT_NUM; i++)
  7110. cnt_sum += dm->cnt_notify[i];
  7111. seq_printf(m,
  7112. " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ",
  7113. "[notify_cnt]", cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO],
  7114. cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]);
  7115. seq_printf(m,
  7116. "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d\n",
  7117. cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE],
  7118. cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK],
  7119. cnt[BTC_NCNT_WL_STA]);
  7120. seq_printf(m,
  7121. " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ",
  7122. "[notify_cnt]", cnt[BTC_NCNT_SCAN_START],
  7123. cnt[BTC_NCNT_SCAN_FINISH], cnt[BTC_NCNT_SWITCH_BAND],
  7124. cnt[BTC_NCNT_SPECIAL_PACKET]);
  7125. seq_printf(m,
  7126. "timer=%d, control=%d, customerize=%d\n",
  7127. cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL],
  7128. cnt[BTC_NCNT_CUSTOMERIZE]);
  7129. }
  7130. static void _show_summary_v5(struct rtw89_dev *rtwdev, struct seq_file *m)
  7131. {
  7132. struct rtw89_btc *btc = &rtwdev->btc;
  7133. struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
  7134. struct rtw89_btc_fbtc_rpt_ctrl_v5 *prptctrl;
  7135. struct rtw89_btc_rpt_cmn_info *pcinfo;
  7136. struct rtw89_btc_cx *cx = &btc->cx;
  7137. struct rtw89_btc_dm *dm = &btc->dm;
  7138. struct rtw89_btc_wl_info *wl = &cx->wl;
  7139. u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify;
  7140. u8 i;
  7141. if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY))
  7142. return;
  7143. seq_puts(m, "========== [Statistics] ==========\n");
  7144. pcinfo = &pfwinfo->rpt_ctrl.cinfo;
  7145. if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) {
  7146. prptctrl = &pfwinfo->rpt_ctrl.finfo.v5;
  7147. seq_printf(m,
  7148. " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d), ",
  7149. "[summary]", pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail,
  7150. le16_to_cpu(prptctrl->rpt_info.cnt_h2c),
  7151. pfwinfo->cnt_c2h,
  7152. le16_to_cpu(prptctrl->rpt_info.cnt_c2h),
  7153. le16_to_cpu(prptctrl->rpt_info.len_c2h));
  7154. seq_printf(m,
  7155. "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x",
  7156. pfwinfo->event[BTF_EVNT_RPT],
  7157. le16_to_cpu(prptctrl->rpt_info.cnt),
  7158. le32_to_cpu(prptctrl->rpt_info.en));
  7159. if (dm->error.map.wl_fw_hang)
  7160. seq_puts(m, " (WL FW Hang!!)");
  7161. seq_puts(m, "\n");
  7162. seq_printf(m,
  7163. " %-15s : send_ok:%d, send_fail:%d, recv:%d, ",
  7164. "[mailbox]",
  7165. le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok),
  7166. le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail),
  7167. le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv));
  7168. seq_printf(m,
  7169. "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n",
  7170. le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty),
  7171. le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl),
  7172. le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx),
  7173. le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack),
  7174. le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack));
  7175. seq_printf(m,
  7176. " %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d]",
  7177. "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ],
  7178. cx->cnt_wl[BTC_WCNT_RFK_GO],
  7179. cx->cnt_wl[BTC_WCNT_RFK_REJECT],
  7180. cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]);
  7181. seq_printf(m,
  7182. ", bt_rfk[req:%d]",
  7183. le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ]));
  7184. seq_printf(m,
  7185. ", AOAC[RF_on:%d/RF_off:%d]",
  7186. le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on),
  7187. le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off));
  7188. } else {
  7189. seq_printf(m,
  7190. " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d",
  7191. "[summary]", pfwinfo->cnt_h2c,
  7192. pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h);
  7193. }
  7194. if (!pcinfo->valid || pfwinfo->len_mismch || pfwinfo->fver_mismch ||
  7195. pfwinfo->err[BTFRE_EXCEPTION]) {
  7196. seq_puts(m, "\n");
  7197. seq_printf(m,
  7198. " %-15s : WL FW rpt error!![rpt_ctrl_valid:%d/len:"
  7199. "0x%x/ver:0x%x/ex:%d/lps=%d/rf_off=%d]",
  7200. "[ERROR]", pcinfo->valid, pfwinfo->len_mismch,
  7201. pfwinfo->fver_mismch, pfwinfo->err[BTFRE_EXCEPTION],
  7202. wl->status.map.lps, wl->status.map.rf_off);
  7203. }
  7204. for (i = 0; i < BTC_NCNT_NUM; i++)
  7205. cnt_sum += dm->cnt_notify[i];
  7206. seq_puts(m, "\n");
  7207. seq_printf(m,
  7208. " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ",
  7209. "[notify_cnt]",
  7210. cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO],
  7211. cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]);
  7212. seq_printf(m,
  7213. "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d",
  7214. cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE],
  7215. cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK],
  7216. cnt[BTC_NCNT_WL_STA]);
  7217. seq_puts(m, "\n");
  7218. seq_printf(m,
  7219. " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ",
  7220. "[notify_cnt]",
  7221. cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH],
  7222. cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SPECIAL_PACKET]);
  7223. seq_printf(m,
  7224. "timer=%d, control=%d, customerize=%d",
  7225. cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL],
  7226. cnt[BTC_NCNT_CUSTOMERIZE]);
  7227. }
  7228. static void _show_summary_v105(struct rtw89_dev *rtwdev, struct seq_file *m)
  7229. {
  7230. struct rtw89_btc *btc = &rtwdev->btc;
  7231. struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
  7232. struct rtw89_btc_fbtc_rpt_ctrl_v105 *prptctrl;
  7233. struct rtw89_btc_rpt_cmn_info *pcinfo;
  7234. struct rtw89_btc_cx *cx = &btc->cx;
  7235. struct rtw89_btc_dm *dm = &btc->dm;
  7236. struct rtw89_btc_wl_info *wl = &cx->wl;
  7237. u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify;
  7238. u8 i;
  7239. if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY))
  7240. return;
  7241. seq_puts(m, "========== [Statistics] ==========\n");
  7242. pcinfo = &pfwinfo->rpt_ctrl.cinfo;
  7243. if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) {
  7244. prptctrl = &pfwinfo->rpt_ctrl.finfo.v105;
  7245. seq_printf(m,
  7246. " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d), ",
  7247. "[summary]", pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail,
  7248. le16_to_cpu(prptctrl->rpt_info.cnt_h2c),
  7249. pfwinfo->cnt_c2h,
  7250. le16_to_cpu(prptctrl->rpt_info.cnt_c2h),
  7251. le16_to_cpu(prptctrl->rpt_info.len_c2h));
  7252. seq_printf(m,
  7253. "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x",
  7254. pfwinfo->event[BTF_EVNT_RPT],
  7255. le16_to_cpu(prptctrl->rpt_info.cnt),
  7256. le32_to_cpu(prptctrl->rpt_info.en));
  7257. if (dm->error.map.wl_fw_hang)
  7258. seq_puts(m, " (WL FW Hang!!)");
  7259. seq_puts(m, "\n");
  7260. seq_printf(m,
  7261. " %-15s : send_ok:%d, send_fail:%d, recv:%d, ",
  7262. "[mailbox]",
  7263. le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok),
  7264. le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail),
  7265. le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv));
  7266. seq_printf(m,
  7267. "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n",
  7268. le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty),
  7269. le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl),
  7270. le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx),
  7271. le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack),
  7272. le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack));
  7273. seq_printf(m,
  7274. " %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d]",
  7275. "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ],
  7276. cx->cnt_wl[BTC_WCNT_RFK_GO],
  7277. cx->cnt_wl[BTC_WCNT_RFK_REJECT],
  7278. cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]);
  7279. seq_printf(m,
  7280. ", bt_rfk[req:%d]",
  7281. le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ]));
  7282. seq_printf(m,
  7283. ", AOAC[RF_on:%d/RF_off:%d]",
  7284. le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on),
  7285. le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off));
  7286. } else {
  7287. seq_printf(m,
  7288. " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d",
  7289. "[summary]", pfwinfo->cnt_h2c,
  7290. pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h);
  7291. }
  7292. if (!pcinfo->valid || pfwinfo->len_mismch || pfwinfo->fver_mismch ||
  7293. pfwinfo->err[BTFRE_EXCEPTION]) {
  7294. seq_puts(m, "\n");
  7295. seq_printf(m,
  7296. " %-15s : WL FW rpt error!![rpt_ctrl_valid:%d/len:"
  7297. "0x%x/ver:0x%x/ex:%d/lps=%d/rf_off=%d]",
  7298. "[ERROR]", pcinfo->valid, pfwinfo->len_mismch,
  7299. pfwinfo->fver_mismch, pfwinfo->err[BTFRE_EXCEPTION],
  7300. wl->status.map.lps, wl->status.map.rf_off);
  7301. }
  7302. for (i = 0; i < BTC_NCNT_NUM; i++)
  7303. cnt_sum += dm->cnt_notify[i];
  7304. seq_puts(m, "\n");
  7305. seq_printf(m,
  7306. " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ",
  7307. "[notify_cnt]",
  7308. cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO],
  7309. cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]);
  7310. seq_printf(m,
  7311. "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d",
  7312. cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE],
  7313. cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK],
  7314. cnt[BTC_NCNT_WL_STA]);
  7315. seq_puts(m, "\n");
  7316. seq_printf(m,
  7317. " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ",
  7318. "[notify_cnt]",
  7319. cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH],
  7320. cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SPECIAL_PACKET]);
  7321. seq_printf(m,
  7322. "timer=%d, control=%d, customerize=%d",
  7323. cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL],
  7324. cnt[BTC_NCNT_CUSTOMERIZE]);
  7325. }
  7326. void rtw89_btc_dump_info(struct rtw89_dev *rtwdev, struct seq_file *m)
  7327. {
  7328. struct rtw89_fw_suit *fw_suit = &rtwdev->fw.normal;
  7329. struct rtw89_btc *btc = &rtwdev->btc;
  7330. const struct rtw89_btc_ver *ver = btc->ver;
  7331. struct rtw89_btc_cx *cx = &btc->cx;
  7332. struct rtw89_btc_bt_info *bt = &cx->bt;
  7333. seq_puts(m, "=========================================\n");
  7334. seq_printf(m, "WL FW / BT FW %d.%d.%d.%d / NA\n",
  7335. fw_suit->major_ver, fw_suit->minor_ver,
  7336. fw_suit->sub_ver, fw_suit->sub_idex);
  7337. seq_printf(m, "manual %d\n", btc->ctrl.manual);
  7338. seq_puts(m, "=========================================\n");
  7339. seq_printf(m, "\n\r %-15s : raw_data[%02x %02x %02x %02x %02x %02x] (type:%s/cnt:%d/same:%d)",
  7340. "[bt_info]",
  7341. bt->raw_info[2], bt->raw_info[3],
  7342. bt->raw_info[4], bt->raw_info[5],
  7343. bt->raw_info[6], bt->raw_info[7],
  7344. bt->raw_info[0] == BTC_BTINFO_AUTO ? "auto" : "reply",
  7345. cx->cnt_bt[BTC_BCNT_INFOUPDATE],
  7346. cx->cnt_bt[BTC_BCNT_INFOSAME]);
  7347. seq_puts(m, "\n=========================================\n");
  7348. _show_cx_info(rtwdev, m);
  7349. _show_wl_info(rtwdev, m);
  7350. _show_bt_info(rtwdev, m);
  7351. _show_dm_info(rtwdev, m);
  7352. _show_fw_dm_msg(rtwdev, m);
  7353. if (ver->fcxmreg == 1)
  7354. _show_mreg_v1(rtwdev, m);
  7355. else if (ver->fcxmreg == 2)
  7356. _show_mreg_v2(rtwdev, m);
  7357. if (ver->fcxbtcrpt == 1)
  7358. _show_summary_v1(rtwdev, m);
  7359. else if (ver->fcxbtcrpt == 4)
  7360. _show_summary_v4(rtwdev, m);
  7361. else if (ver->fcxbtcrpt == 5)
  7362. _show_summary_v5(rtwdev, m);
  7363. else if (ver->fcxbtcrpt == 105)
  7364. _show_summary_v105(rtwdev, m);
  7365. }
  7366. void rtw89_coex_recognize_ver(struct rtw89_dev *rtwdev)
  7367. {
  7368. const struct rtw89_chip_info *chip = rtwdev->chip;
  7369. struct rtw89_btc *btc = &rtwdev->btc;
  7370. const struct rtw89_btc_ver *btc_ver_def;
  7371. const struct rtw89_fw_suit *fw_suit;
  7372. u32 suit_ver_code;
  7373. int i;
  7374. fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_NORMAL);
  7375. suit_ver_code = RTW89_FW_SUIT_VER_CODE(fw_suit);
  7376. for (i = 0; i < ARRAY_SIZE(rtw89_btc_ver_defs); i++) {
  7377. btc_ver_def = &rtw89_btc_ver_defs[i];
  7378. if (chip->chip_id != btc_ver_def->chip_id)
  7379. continue;
  7380. if (suit_ver_code >= btc_ver_def->fw_ver_code) {
  7381. btc->ver = btc_ver_def;
  7382. goto out;
  7383. }
  7384. }
  7385. btc->ver = &rtw89_btc_ver_defs[RTW89_DEFAULT_BTC_VER_IDX];
  7386. out:
  7387. rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC] use version def[%d] = 0x%08x\n",
  7388. (int)(btc->ver - rtw89_btc_ver_defs), btc->ver->fw_ver_code);
  7389. }