coex.c 200 KB

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