qdf_trace.c 130 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733
  1. /*
  2. * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
  3. * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for
  6. * any purpose with or without fee is hereby granted, provided that the
  7. * above copyright notice and this permission notice appear in all
  8. * copies.
  9. *
  10. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  11. * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  12. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  13. * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  14. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  15. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  16. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  17. * PERFORMANCE OF THIS SOFTWARE.
  18. */
  19. /**
  20. * DOC: qdf_trace
  21. * QCA driver framework (QDF) trace APIs
  22. * Trace, logging, and debugging definitions and APIs
  23. */
  24. /* Include Files */
  25. #include "qdf_str.h"
  26. #include <qdf_trace.h>
  27. #include <qdf_parse.h>
  28. #include <qdf_module.h>
  29. #include <qdf_util.h>
  30. #include <qdf_mem.h>
  31. /* macro to map qdf trace levels into the bitmask */
  32. #define QDF_TRACE_LEVEL_TO_MODULE_BITMASK(_level) ((1 << (_level)))
  33. #include <wlan_logging_sock_svc.h>
  34. #include <qdf_module.h>
  35. static int qdf_pidx = -1;
  36. static bool qdf_log_dump_at_kernel_enable = true;
  37. qdf_declare_param(qdf_log_dump_at_kernel_enable, bool);
  38. /* This value of 0 will disable the timer by default. */
  39. static uint32_t qdf_log_flush_timer_period;
  40. qdf_declare_param(qdf_log_flush_timer_period, uint);
  41. #include "qdf_time.h"
  42. #include "qdf_mc_timer.h"
  43. #include <host_diag_core_log.h>
  44. #if defined(WLAN_FEATURE_CONNECTIVITY_LOGGING) || \
  45. defined(CONNECTIVITY_DIAG_EVENT)
  46. #include <wlan_connectivity_logging.h>
  47. #include "i_host_diag_core_event.h"
  48. #endif
  49. /* Global qdf print id */
  50. /* Preprocessor definitions and constants */
  51. enum qdf_timestamp_unit qdf_log_timestamp_type = QDF_LOG_TIMESTAMP_UNIT;
  52. #define DP_TRACE_META_DATA_STRLEN 50
  53. #ifdef TRACE_RECORD
  54. /* Static and Global variables */
  55. static spinlock_t ltrace_lock;
  56. /* global qdf trace data */
  57. static t_qdf_trace_data g_qdf_trace_data;
  58. /*
  59. * all the call back functions for dumping MTRACE messages from ring buffer
  60. * are stored in qdf_trace_cb_table,these callbacks are initialized during init
  61. * only so, we will make a copy of these call back functions and maintain in to
  62. * qdf_trace_restore_cb_table. Incase if we make modifications to
  63. * qdf_trace_cb_table, we can certainly retrieve all the call back functions
  64. * back from Restore Table
  65. */
  66. static tp_qdf_trace_cb qdf_trace_cb_table[QDF_MODULE_ID_MAX];
  67. static tp_qdf_trace_cb qdf_trace_restore_cb_table[QDF_MODULE_ID_MAX];
  68. #ifdef WLAN_LOGGING_BUFFERS_DYNAMICALLY
  69. static qdf_trace_record_t *g_qdf_trace_tbl;
  70. #else
  71. static qdf_trace_record_t g_qdf_trace_tbl[MAX_QDF_TRACE_RECORDS];
  72. #endif
  73. #endif
  74. #ifdef WLAN_FEATURE_MEMDUMP_ENABLE
  75. static tp_qdf_state_info_cb qdf_state_info_table[QDF_MODULE_ID_MAX];
  76. #endif
  77. #ifdef CONFIG_DP_TRACE
  78. /* Static and Global variables */
  79. #ifdef WLAN_LOGGING_BUFFERS_DYNAMICALLY
  80. static struct qdf_dp_trace_record_s *g_qdf_dp_trace_tbl;
  81. #else
  82. static struct qdf_dp_trace_record_s
  83. g_qdf_dp_trace_tbl[MAX_QDF_DP_TRACE_RECORDS];
  84. #endif
  85. static spinlock_t l_dp_trace_lock;
  86. /*
  87. * all the options to configure/control DP trace are
  88. * defined in this structure
  89. */
  90. static struct s_qdf_dp_trace_data g_qdf_dp_trace_data;
  91. /*
  92. * all the call back functions for dumping DPTRACE messages from ring buffer
  93. * are stored in qdf_dp_trace_cb_table, callbacks are initialized during init
  94. */
  95. static tp_qdf_dp_trace_cb qdf_dp_trace_cb_table[QDF_DP_TRACE_MAX + 1];
  96. #endif
  97. #ifdef QCA_WIFI_MODULE_PARAMS_FROM_INI
  98. #define QDF_PARAM_STR_LENGTH 40
  99. enum qdf_num_module_param {
  100. MEM_DEBUG_DISABLED,
  101. QDF_DBG_MASK,
  102. PREALLOC_DISABLED,
  103. QDF_LOG_DUMP_AT_KERNEL_ENABLE,
  104. QDF_DBG_ARR,
  105. QDF_LOG_FLUSH_TIMER_PERIOD,
  106. QDF_PARAM_MAX,
  107. };
  108. static char qdf_module_param[QDF_PARAM_MAX][QDF_PARAM_STR_LENGTH] = {
  109. "mem_debug_disabled",
  110. "qdf_dbg_mask",
  111. "prealloc_disabled",
  112. "qdf_log_dump_at_kernel_enable",
  113. "qdf_dbg_arr",
  114. "qdf_log_flush_timer_period",
  115. };
  116. #endif
  117. /**
  118. * qdf_snprintf() - wrapper function to snprintf
  119. * @str_buffer: string Buffer
  120. * @size: defines the size of the data record
  121. * @str_format: Format string in which the message to be logged. This format
  122. * string contains printf-like replacement parameters, which follow
  123. * this parameter in the variable argument list.
  124. *
  125. * Return: num of bytes written to buffer
  126. */
  127. int qdf_snprintf(char *str_buffer, unsigned int size, char *str_format, ...)
  128. {
  129. va_list args;
  130. int i;
  131. va_start(args, str_format);
  132. i = vsnprintf(str_buffer, size, str_format, args);
  133. va_end(args);
  134. return i;
  135. }
  136. qdf_export_symbol(qdf_snprintf);
  137. #ifdef QDF_ENABLE_TRACING
  138. /**
  139. * qdf_trace_msg() - externally called trace function
  140. * @module: Module identifier a member of the QDF_MODULE_ID
  141. * enumeration that identifies the module issuing the trace message.
  142. * @level: Trace level a member of the QDF_TRACE_LEVEL enumeration
  143. * indicating the severity of the condition causing the trace message
  144. * to be issued. More severe conditions are more likely to be logged.
  145. * @str_format: Format string in which the message to be logged. This format
  146. * string contains printf-like replacement parameters, which follow
  147. * this parameter in the variable argument list.
  148. *
  149. * Checks the level of severity and accordingly prints the trace messages
  150. *
  151. * Return: None
  152. */
  153. void qdf_trace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level,
  154. const char *str_format, ...)
  155. {
  156. va_list val;
  157. va_start(val, str_format);
  158. qdf_trace_msg_cmn(qdf_pidx, module, level, str_format, val);
  159. va_end(val);
  160. }
  161. qdf_export_symbol(qdf_trace_msg);
  162. void qdf_vtrace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level,
  163. const char *str_format, va_list val)
  164. {
  165. qdf_trace_msg_cmn(qdf_pidx, module, level, str_format, val);
  166. }
  167. qdf_export_symbol(qdf_vtrace_msg);
  168. #define ROW_SIZE 16
  169. /* Buffer size = data bytes(2 hex chars plus space) + NULL */
  170. #define BUFFER_SIZE ((QDF_DP_TRACE_RECORD_SIZE * 3) + 1)
  171. static void __qdf_trace_hex_dump(QDF_MODULE_ID module, QDF_TRACE_LEVEL level,
  172. void *data, int buf_len, bool print_ascii)
  173. {
  174. const u8 *ptr = data;
  175. int i = 0;
  176. if (!qdf_print_is_verbose_enabled(qdf_pidx, module, level))
  177. return;
  178. while (buf_len > 0) {
  179. unsigned char linebuf[BUFFER_SIZE] = {0};
  180. int linelen = min(buf_len, ROW_SIZE);
  181. buf_len -= ROW_SIZE;
  182. hex_dump_to_buffer(ptr, linelen, ROW_SIZE, 1,
  183. linebuf, sizeof(linebuf), print_ascii);
  184. qdf_trace_msg(module, level, "%.8x: %s", i, linebuf);
  185. ptr += ROW_SIZE;
  186. i += ROW_SIZE;
  187. }
  188. }
  189. void qdf_trace_hex_dump(QDF_MODULE_ID module, QDF_TRACE_LEVEL level,
  190. void *data, int buf_len)
  191. {
  192. __qdf_trace_hex_dump(module, level, data, buf_len, false);
  193. }
  194. qdf_export_symbol(qdf_trace_hex_dump);
  195. void qdf_trace_hex_ascii_dump(QDF_MODULE_ID module, QDF_TRACE_LEVEL level,
  196. void *data, int buf_len)
  197. {
  198. __qdf_trace_hex_dump(module, level, data, buf_len, true);
  199. }
  200. qdf_export_symbol(qdf_trace_hex_ascii_dump);
  201. #endif
  202. #ifdef TRACE_RECORD
  203. #ifdef WLAN_LOGGING_BUFFERS_DYNAMICALLY
  204. static inline QDF_STATUS allocate_g_qdf_trace_tbl_buffer(void)
  205. {
  206. g_qdf_trace_tbl = qdf_mem_valloc(MAX_QDF_TRACE_RECORDS *
  207. sizeof(*g_qdf_trace_tbl));
  208. QDF_BUG(g_qdf_trace_tbl);
  209. return g_qdf_trace_tbl ? QDF_STATUS_SUCCESS : QDF_STATUS_E_NOMEM;
  210. }
  211. static inline void free_g_qdf_trace_tbl_buffer(void)
  212. {
  213. qdf_mem_vfree(g_qdf_trace_tbl);
  214. g_qdf_trace_tbl = NULL;
  215. }
  216. #else
  217. static inline QDF_STATUS allocate_g_qdf_trace_tbl_buffer(void)
  218. {
  219. return QDF_STATUS_SUCCESS;
  220. }
  221. static inline void free_g_qdf_trace_tbl_buffer(void)
  222. { }
  223. #endif
  224. /**
  225. * qdf_trace_enable() - Enable MTRACE for specific modules
  226. * @bitmask_of_module_id: Bitmask according to enum of the modules.
  227. * 32[dec] = 0010 0000 [bin] <enum of HDD is 5>
  228. * 64[dec] = 0100 0000 [bin] <enum of SME is 6>
  229. * 128[dec] = 1000 0000 [bin] <enum of PE is 7>
  230. * @enable: can be true or false true implies enabling MTRACE false implies
  231. * disabling MTRACE.
  232. *
  233. * Enable MTRACE for specific modules whose bits are set in bitmask and enable
  234. * is true. if enable is false it disables MTRACE for that module. set the
  235. * bitmask according to enum value of the modules.
  236. * This functions will be called when you issue ioctl as mentioned following
  237. * [iwpriv wlan0 setdumplog <value> <enable>].
  238. * <value> - Decimal number, i.e. 64 decimal value shows only SME module,
  239. * 128 decimal value shows only PE module, 192 decimal value shows PE and SME.
  240. *
  241. * Return: None
  242. */
  243. void qdf_trace_enable(uint32_t bitmask_of_module_id, uint8_t enable)
  244. {
  245. int i;
  246. if (bitmask_of_module_id) {
  247. for (i = 0; i < QDF_MODULE_ID_MAX; i++) {
  248. if (((bitmask_of_module_id >> i) & 1)) {
  249. if (enable) {
  250. if (NULL !=
  251. qdf_trace_restore_cb_table[i]) {
  252. qdf_trace_cb_table[i] =
  253. qdf_trace_restore_cb_table[i];
  254. }
  255. } else {
  256. qdf_trace_restore_cb_table[i] =
  257. qdf_trace_cb_table[i];
  258. qdf_trace_cb_table[i] = NULL;
  259. }
  260. }
  261. }
  262. } else {
  263. if (enable) {
  264. for (i = 0; i < QDF_MODULE_ID_MAX; i++) {
  265. if (qdf_trace_restore_cb_table[i]) {
  266. qdf_trace_cb_table[i] =
  267. qdf_trace_restore_cb_table[i];
  268. }
  269. }
  270. } else {
  271. for (i = 0; i < QDF_MODULE_ID_MAX; i++) {
  272. qdf_trace_restore_cb_table[i] =
  273. qdf_trace_cb_table[i];
  274. qdf_trace_cb_table[i] = NULL;
  275. }
  276. }
  277. }
  278. }
  279. qdf_export_symbol(qdf_trace_enable);
  280. /**
  281. * qdf_trace_init() - initializes qdf trace structures and variables
  282. *
  283. * Called immediately after cds_preopen, so that we can start recording HDD
  284. * events ASAP.
  285. *
  286. * Return: None
  287. */
  288. void qdf_trace_init(void)
  289. {
  290. uint8_t i;
  291. if (allocate_g_qdf_trace_tbl_buffer() != QDF_STATUS_SUCCESS)
  292. return;
  293. g_qdf_trace_data.head = INVALID_QDF_TRACE_ADDR;
  294. g_qdf_trace_data.tail = INVALID_QDF_TRACE_ADDR;
  295. g_qdf_trace_data.num = 0;
  296. g_qdf_trace_data.enable = true;
  297. g_qdf_trace_data.dump_count = DEFAULT_QDF_TRACE_DUMP_COUNT;
  298. g_qdf_trace_data.num_since_last_dump = 0;
  299. for (i = 0; i < QDF_MODULE_ID_MAX; i++) {
  300. qdf_trace_cb_table[i] = NULL;
  301. qdf_trace_restore_cb_table[i] = NULL;
  302. }
  303. }
  304. qdf_export_symbol(qdf_trace_init);
  305. /**
  306. * qdf_trace_deinit() - frees memory allocated dynamically
  307. *
  308. * Called from cds_deinit, so that we can free the memory and resets
  309. * the variables
  310. *
  311. * Return: None
  312. */
  313. void qdf_trace_deinit(void)
  314. {
  315. g_qdf_trace_data.enable = false;
  316. g_qdf_trace_data.num = 0;
  317. g_qdf_trace_data.head = INVALID_QDF_TRACE_ADDR;
  318. g_qdf_trace_data.tail = INVALID_QDF_TRACE_ADDR;
  319. free_g_qdf_trace_tbl_buffer();
  320. }
  321. qdf_export_symbol(qdf_trace_deinit);
  322. /**
  323. * qdf_trace() - puts the messages in to ring-buffer
  324. * @module: Enum of module, basically module id.
  325. * @code: Code to be recorded
  326. * @session: Session ID of the log
  327. * @data: Actual message contents
  328. *
  329. * This function will be called from each module who wants record the messages
  330. * in circular queue. Before calling this functions make sure you have
  331. * registered your module with qdf through qdf_trace_register function.
  332. *
  333. * Return: None
  334. */
  335. void qdf_trace(uint8_t module, uint16_t code, uint16_t session, uint32_t data)
  336. {
  337. tp_qdf_trace_record rec = NULL;
  338. unsigned long flags;
  339. char time[18];
  340. if (!g_qdf_trace_data.enable)
  341. return;
  342. /* if module is not registered, don't record for that module */
  343. if (!qdf_trace_cb_table[module])
  344. return;
  345. qdf_get_time_of_the_day_in_hr_min_sec_usec(time, sizeof(time));
  346. /* Aquire the lock so that only one thread at a time can fill the ring
  347. * buffer
  348. */
  349. spin_lock_irqsave(&ltrace_lock, flags);
  350. g_qdf_trace_data.num++;
  351. if (g_qdf_trace_data.num > MAX_QDF_TRACE_RECORDS)
  352. g_qdf_trace_data.num = MAX_QDF_TRACE_RECORDS;
  353. if (INVALID_QDF_TRACE_ADDR == g_qdf_trace_data.head) {
  354. /* first record */
  355. g_qdf_trace_data.head = 0;
  356. g_qdf_trace_data.tail = 0;
  357. } else {
  358. /* queue is not empty */
  359. uint32_t tail = g_qdf_trace_data.tail + 1;
  360. if (MAX_QDF_TRACE_RECORDS == tail)
  361. tail = 0;
  362. if (g_qdf_trace_data.head == tail) {
  363. /* full */
  364. if (MAX_QDF_TRACE_RECORDS == ++g_qdf_trace_data.head)
  365. g_qdf_trace_data.head = 0;
  366. }
  367. g_qdf_trace_data.tail = tail;
  368. }
  369. rec = &g_qdf_trace_tbl[g_qdf_trace_data.tail];
  370. rec->code = code;
  371. rec->session = session;
  372. rec->data = data;
  373. rec->qtime = qdf_get_log_timestamp();
  374. scnprintf(rec->time, sizeof(rec->time), "%s", time);
  375. rec->module = module;
  376. rec->pid = (in_interrupt() ? 0 : current->pid);
  377. g_qdf_trace_data.num_since_last_dump++;
  378. spin_unlock_irqrestore(&ltrace_lock, flags);
  379. }
  380. qdf_export_symbol(qdf_trace);
  381. #ifdef ENABLE_MTRACE_LOG
  382. void qdf_mtrace_log(QDF_MODULE_ID src_module, QDF_MODULE_ID dst_module,
  383. uint16_t message_id, uint8_t vdev_id)
  384. {
  385. uint32_t trace_log, payload;
  386. static uint16_t counter;
  387. trace_log = (src_module << 23) | (dst_module << 15) | message_id;
  388. payload = (vdev_id << 16) | counter++;
  389. QDF_TRACE(src_module, QDF_TRACE_LEVEL_TRACE, "%x %x",
  390. trace_log, payload);
  391. }
  392. qdf_export_symbol(qdf_mtrace_log);
  393. #endif
  394. void qdf_mtrace(QDF_MODULE_ID src_module, QDF_MODULE_ID dst_module,
  395. uint16_t message_id, uint8_t vdev_id, uint32_t data)
  396. {
  397. qdf_trace(src_module, message_id, vdev_id, data);
  398. qdf_mtrace_log(src_module, dst_module, message_id, vdev_id);
  399. }
  400. qdf_export_symbol(qdf_mtrace);
  401. /**
  402. * qdf_trace_spin_lock_init() - initializes the lock variable before use
  403. *
  404. * This function will be called from cds_alloc_global_context, we will have lock
  405. * available to use ASAP
  406. *
  407. * Return: None
  408. */
  409. QDF_STATUS qdf_trace_spin_lock_init(void)
  410. {
  411. spin_lock_init(&ltrace_lock);
  412. return QDF_STATUS_SUCCESS;
  413. }
  414. qdf_export_symbol(qdf_trace_spin_lock_init);
  415. /**
  416. * qdf_trace_register() - registers the call back functions
  417. * @module_iD: enum value of module
  418. * @qdf_trace_callback: call back functions to display the messages in
  419. * particular format.
  420. *
  421. * Registers the call back functions to display the messages in particular
  422. * format mentioned in these call back functions. This functions should be
  423. * called by interested module in their init part as we will be ready to
  424. * register as soon as modules are up.
  425. *
  426. * Return: None
  427. */
  428. void qdf_trace_register(QDF_MODULE_ID module_id,
  429. tp_qdf_trace_cb qdf_trace_callback)
  430. {
  431. qdf_trace_cb_table[module_id] = qdf_trace_callback;
  432. }
  433. qdf_export_symbol(qdf_trace_register);
  434. /**
  435. * qdf_trace_dump_all() - Dump data from ring buffer via call back functions
  436. * registered with QDF
  437. * @p_mac: Context of particular module
  438. * @code: Reason code
  439. * @session: Session id of log
  440. * @count: Number of lines to dump starting from tail to head
  441. *
  442. * This function will be called up on issueing ioctl call as mentioned following
  443. * [iwpriv wlan0 dumplog 0 0 <n> <bitmask_of_module>]
  444. *
  445. * <n> - number lines to dump starting from tail to head.
  446. *
  447. * <bitmask_of_module> - if anybody wants to know how many messages were
  448. * recorded for particular module/s mentioned by setbit in bitmask from last
  449. * <n> messages. It is optional, if you don't provide then it will dump
  450. * everything from buffer.
  451. *
  452. * Return: None
  453. */
  454. void qdf_trace_dump_all(void *p_mac, uint8_t code, uint8_t session,
  455. uint32_t count, uint32_t bitmask_of_module)
  456. {
  457. qdf_trace_record_t p_record;
  458. int32_t i, tail;
  459. if (!g_qdf_trace_data.enable) {
  460. QDF_TRACE(QDF_MODULE_ID_SYS,
  461. QDF_TRACE_LEVEL_ERROR, "Tracing Disabled");
  462. return;
  463. }
  464. QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_INFO,
  465. "DPT: Total Records: %d, Head: %d, Tail: %d",
  466. g_qdf_trace_data.num, g_qdf_trace_data.head,
  467. g_qdf_trace_data.tail);
  468. /* aquire the lock so that only one thread at a time can read
  469. * the ring buffer
  470. */
  471. spin_lock(&ltrace_lock);
  472. if (g_qdf_trace_data.head != INVALID_QDF_TRACE_ADDR) {
  473. i = g_qdf_trace_data.head;
  474. tail = g_qdf_trace_data.tail;
  475. if (count) {
  476. if (count > g_qdf_trace_data.num)
  477. count = g_qdf_trace_data.num;
  478. if (tail >= (count - 1))
  479. i = tail - count + 1;
  480. else if (count != MAX_QDF_TRACE_RECORDS)
  481. i = MAX_QDF_TRACE_RECORDS - ((count - 1) -
  482. tail);
  483. }
  484. p_record = g_qdf_trace_tbl[i];
  485. /* right now we are not using num_since_last_dump member but
  486. * in future we might re-visit and use this member to track
  487. * how many latest messages got added while we were dumping
  488. * from ring buffer
  489. */
  490. g_qdf_trace_data.num_since_last_dump = 0;
  491. spin_unlock(&ltrace_lock);
  492. for (;; ) {
  493. if ((code == 0 || (code == p_record.code)) &&
  494. (qdf_trace_cb_table[p_record.module])) {
  495. if (0 == bitmask_of_module) {
  496. qdf_trace_cb_table[p_record.
  497. module] (p_mac,
  498. &p_record,
  499. (uint16_t)
  500. i);
  501. } else {
  502. if (bitmask_of_module &
  503. (1 << p_record.module)) {
  504. qdf_trace_cb_table[p_record.
  505. module]
  506. (p_mac, &p_record,
  507. (uint16_t) i);
  508. }
  509. }
  510. }
  511. if (i == tail)
  512. break;
  513. i += 1;
  514. spin_lock(&ltrace_lock);
  515. if (MAX_QDF_TRACE_RECORDS == i) {
  516. i = 0;
  517. p_record = g_qdf_trace_tbl[0];
  518. } else {
  519. p_record = g_qdf_trace_tbl[i];
  520. }
  521. spin_unlock(&ltrace_lock);
  522. }
  523. } else {
  524. spin_unlock(&ltrace_lock);
  525. }
  526. }
  527. qdf_export_symbol(qdf_trace_dump_all);
  528. #endif
  529. #ifdef WLAN_FEATURE_MEMDUMP_ENABLE
  530. /**
  531. * qdf_register_debugcb_init() - initializes debug callbacks
  532. * to NULL
  533. *
  534. * Return: None
  535. */
  536. void qdf_register_debugcb_init(void)
  537. {
  538. uint8_t i;
  539. for (i = 0; i < QDF_MODULE_ID_MAX; i++)
  540. qdf_state_info_table[i] = NULL;
  541. }
  542. qdf_export_symbol(qdf_register_debugcb_init);
  543. /**
  544. * qdf_register_debug_callback() - stores callback handlers to print
  545. * state information
  546. * @module_id: module id of layer
  547. * @qdf_state_infocb: callback to be registered
  548. *
  549. * This function is used to store callback handlers to print
  550. * state information
  551. *
  552. * Return: None
  553. */
  554. void qdf_register_debug_callback(QDF_MODULE_ID module_id,
  555. tp_qdf_state_info_cb qdf_state_infocb)
  556. {
  557. qdf_state_info_table[module_id] = qdf_state_infocb;
  558. }
  559. qdf_export_symbol(qdf_register_debug_callback);
  560. /**
  561. * qdf_state_info_dump_all() - it invokes callback of layer which registered
  562. * its callback to print its state information.
  563. * @buf: buffer pointer to be passed
  564. * @size: size of buffer to be filled
  565. * @driver_dump_size: actual size of buffer used
  566. *
  567. * Return: QDF_STATUS_SUCCESS on success
  568. */
  569. QDF_STATUS qdf_state_info_dump_all(char *buf, uint16_t size,
  570. uint16_t *driver_dump_size)
  571. {
  572. uint8_t module, ret = QDF_STATUS_SUCCESS;
  573. uint16_t buf_len = size;
  574. char *buf_ptr = buf;
  575. for (module = 0; module < QDF_MODULE_ID_MAX; module++) {
  576. if (qdf_state_info_table[module]) {
  577. qdf_state_info_table[module](&buf_ptr, &buf_len);
  578. if (!buf_len) {
  579. ret = QDF_STATUS_E_NOMEM;
  580. break;
  581. }
  582. }
  583. }
  584. *driver_dump_size = size - buf_len;
  585. return ret;
  586. }
  587. qdf_export_symbol(qdf_state_info_dump_all);
  588. #endif
  589. #ifdef CONFIG_DP_TRACE
  590. #ifdef WLAN_LOGGING_BUFFERS_DYNAMICALLY
  591. static inline QDF_STATUS allocate_g_qdf_dp_trace_tbl_buffer(void)
  592. {
  593. g_qdf_dp_trace_tbl = qdf_mem_valloc(MAX_QDF_DP_TRACE_RECORDS *
  594. sizeof(*g_qdf_dp_trace_tbl));
  595. QDF_BUG(g_qdf_dp_trace_tbl);
  596. return g_qdf_dp_trace_tbl ? QDF_STATUS_SUCCESS : QDF_STATUS_E_NOMEM;
  597. }
  598. static inline void free_g_qdf_dp_trace_tbl_buffer(void)
  599. {
  600. qdf_mem_vfree(g_qdf_dp_trace_tbl);
  601. g_qdf_dp_trace_tbl = NULL;
  602. }
  603. #else
  604. static inline QDF_STATUS allocate_g_qdf_dp_trace_tbl_buffer(void)
  605. {
  606. return QDF_STATUS_SUCCESS;
  607. }
  608. static inline void free_g_qdf_dp_trace_tbl_buffer(void)
  609. { }
  610. #endif
  611. #define QDF_DP_TRACE_PREPEND_STR_SIZE 100
  612. /*
  613. * one dp trace record can't be greater than 300 bytes.
  614. * Max Size will be QDF_DP_TRACE_PREPEND_STR_SIZE(100) + BUFFER_SIZE(121).
  615. * Always make sure to change this QDF_DP_TRACE_MAX_RECORD_SIZE
  616. * value accordingly whenever above two mentioned MACRO value changes.
  617. */
  618. #define QDF_DP_TRACE_MAX_RECORD_SIZE 300
  619. static void qdf_dp_unused(struct qdf_dp_trace_record_s *record,
  620. uint16_t index, uint8_t pdev_id, uint8_t info)
  621. {
  622. qdf_print("%s: QDF_DP_TRACE_MAX event should not be generated",
  623. __func__);
  624. }
  625. /**
  626. * qdf_dp_trace_init() - enables the DP trace
  627. * @live_mode_config: live mode configuration
  628. * @thresh: high throughput threshold for disabling live mode
  629. * @thresh_time_limit: max time to wait before deciding if thresh is crossed
  630. * @verbosity: dptrace verbosity level
  631. * @proto_bitmap: bitmap to enable/disable specific protocols
  632. *
  633. * Called during driver load to init dptrace
  634. *
  635. * A brief note on the 'thresh' param -
  636. * Total # of packets received in a bandwidth timer interval beyond which
  637. * DP Trace logging for data packets (including ICMP) will be disabled.
  638. * In memory logging will still continue for these packets. Other packets for
  639. * which proto.bitmap is set will continue to be recorded in logs and in memory.
  640. * Return: None
  641. */
  642. void qdf_dp_trace_init(bool live_mode_config, uint8_t thresh,
  643. uint16_t time_limit, uint8_t verbosity,
  644. uint32_t proto_bitmap)
  645. {
  646. uint8_t i;
  647. if (allocate_g_qdf_dp_trace_tbl_buffer() != QDF_STATUS_SUCCESS) {
  648. QDF_TRACE_ERROR(QDF_MODULE_ID_QDF,
  649. "Failed!!! DP Trace buffer allocation");
  650. return;
  651. }
  652. qdf_dp_trace_spin_lock_init();
  653. qdf_dp_trace_clear_buffer();
  654. g_qdf_dp_trace_data.enable = true;
  655. g_qdf_dp_trace_data.no_of_record = 1;
  656. g_qdf_dp_trace_data.live_mode_config = live_mode_config;
  657. g_qdf_dp_trace_data.live_mode = live_mode_config;
  658. g_qdf_dp_trace_data.high_tput_thresh = thresh;
  659. g_qdf_dp_trace_data.thresh_time_limit = time_limit;
  660. g_qdf_dp_trace_data.proto_bitmap = proto_bitmap;
  661. g_qdf_dp_trace_data.verbosity = verbosity;
  662. g_qdf_dp_trace_data.ini_conf_verbosity = verbosity;
  663. for (i = 0; i < ARRAY_SIZE(qdf_dp_trace_cb_table); i++)
  664. qdf_dp_trace_cb_table[i] = qdf_dp_display_record;
  665. qdf_dp_trace_cb_table[QDF_DP_TRACE_HDD_TX_PACKET_RECORD] =
  666. qdf_dp_trace_cb_table[QDF_DP_TRACE_HDD_RX_PACKET_RECORD] =
  667. qdf_dp_trace_cb_table[QDF_DP_TRACE_TX_PACKET_RECORD] =
  668. qdf_dp_trace_cb_table[QDF_DP_TRACE_RX_PACKET_RECORD] =
  669. qdf_dp_trace_cb_table[QDF_DP_TRACE_DROP_PACKET_RECORD] =
  670. qdf_dp_trace_cb_table[QDF_DP_TRACE_LI_DP_TX_PACKET_RECORD] =
  671. qdf_dp_trace_cb_table[QDF_DP_TRACE_LI_DP_RX_PACKET_RECORD] =
  672. qdf_dp_display_data_pkt_record;
  673. qdf_dp_trace_cb_table[QDF_DP_TRACE_TXRX_PACKET_PTR_RECORD] =
  674. qdf_dp_trace_cb_table[QDF_DP_TRACE_TXRX_FAST_PACKET_PTR_RECORD] =
  675. qdf_dp_trace_cb_table[QDF_DP_TRACE_FREE_PACKET_PTR_RECORD] =
  676. qdf_dp_trace_cb_table[QDF_DP_TRACE_LI_DP_FREE_PACKET_PTR_RECORD] =
  677. qdf_dp_display_ptr_record;
  678. qdf_dp_trace_cb_table[QDF_DP_TRACE_EAPOL_PACKET_RECORD] =
  679. qdf_dp_trace_cb_table[QDF_DP_TRACE_DHCP_PACKET_RECORD] =
  680. qdf_dp_trace_cb_table[QDF_DP_TRACE_ARP_PACKET_RECORD] =
  681. qdf_dp_trace_cb_table[QDF_DP_TRACE_ICMP_PACKET_RECORD] =
  682. qdf_dp_trace_cb_table[QDF_DP_TRACE_ICMPv6_PACKET_RECORD] =
  683. qdf_dp_display_proto_pkt;
  684. qdf_dp_trace_cb_table[QDF_DP_TRACE_MGMT_PACKET_RECORD] =
  685. qdf_dp_display_mgmt_pkt;
  686. qdf_dp_trace_cb_table[QDF_DP_TRACE_TX_CREDIT_RECORD] =
  687. qdf_dp_display_credit_record;
  688. qdf_dp_trace_cb_table[QDF_DP_TRACE_EVENT_RECORD] =
  689. qdf_dp_display_event_record;
  690. qdf_dp_trace_cb_table[QDF_DP_TRACE_MAX] = qdf_dp_unused;
  691. }
  692. qdf_export_symbol(qdf_dp_trace_init);
  693. void qdf_dp_trace_deinit(void)
  694. {
  695. if (!g_qdf_dp_trace_data.enable)
  696. return;
  697. spin_lock_bh(&l_dp_trace_lock);
  698. g_qdf_dp_trace_data.enable = false;
  699. g_qdf_dp_trace_data.no_of_record = 0;
  700. spin_unlock_bh(&l_dp_trace_lock);
  701. free_g_qdf_dp_trace_tbl_buffer();
  702. }
  703. /**
  704. * qdf_dp_trace_set_value() - Configure the value to control DP trace
  705. * @proto_bitmap: defines the protocol to be tracked
  706. * @no_of_records: defines the nth packet which is traced
  707. * @verbosity: defines the verbosity level
  708. *
  709. * Return: None
  710. */
  711. void qdf_dp_trace_set_value(uint32_t proto_bitmap, uint8_t no_of_record,
  712. uint8_t verbosity)
  713. {
  714. g_qdf_dp_trace_data.proto_bitmap = proto_bitmap;
  715. g_qdf_dp_trace_data.no_of_record = no_of_record;
  716. g_qdf_dp_trace_data.verbosity = verbosity;
  717. g_qdf_dp_trace_data.dynamic_verbosity_modify = true;
  718. }
  719. qdf_export_symbol(qdf_dp_trace_set_value);
  720. /**
  721. * qdf_dp_trace_set_verbosity() - set verbosity value
  722. *
  723. * @val: Value to set
  724. *
  725. * Return: Null
  726. */
  727. void qdf_dp_trace_set_verbosity(uint32_t val)
  728. {
  729. g_qdf_dp_trace_data.verbosity = val;
  730. }
  731. qdf_export_symbol(qdf_dp_trace_set_verbosity);
  732. /**
  733. * qdf_dp_get_verbosity) - get verbosity value
  734. *
  735. * Return: int
  736. */
  737. uint8_t qdf_dp_get_verbosity(void)
  738. {
  739. return g_qdf_dp_trace_data.verbosity;
  740. }
  741. qdf_export_symbol(qdf_dp_get_verbosity);
  742. /**
  743. * qdf_dp_set_proto_bitmap() - set dp trace proto bitmap
  744. *
  745. * @val : unsigned bitmap to set
  746. *
  747. * Return: proto bitmap
  748. */
  749. void qdf_dp_set_proto_bitmap(uint32_t val)
  750. {
  751. g_qdf_dp_trace_data.proto_bitmap = val;
  752. }
  753. qdf_export_symbol(qdf_dp_set_proto_bitmap);
  754. void qdf_dp_set_proto_event_bitmap(uint32_t value)
  755. {
  756. g_qdf_dp_trace_data.proto_event_bitmap = value;
  757. }
  758. qdf_export_symbol(qdf_dp_set_proto_event_bitmap);
  759. static uint32_t qdf_dp_get_proto_event_bitmap(void)
  760. {
  761. return g_qdf_dp_trace_data.proto_event_bitmap;
  762. }
  763. /**
  764. * qdf_dp_set_no_of_record() - set dp trace no_of_record
  765. *
  766. * @val : unsigned no_of_record to set
  767. *
  768. * Return: null
  769. */
  770. void qdf_dp_set_no_of_record(uint32_t val)
  771. {
  772. g_qdf_dp_trace_data.no_of_record = val;
  773. }
  774. qdf_export_symbol(qdf_dp_set_no_of_record);
  775. /**
  776. * qdf_dp_get_no_of_record() - get dp trace no_of_record
  777. *
  778. * Return: number of records
  779. */
  780. uint8_t qdf_dp_get_no_of_record(void)
  781. {
  782. return g_qdf_dp_trace_data.no_of_record;
  783. }
  784. qdf_export_symbol(qdf_dp_get_no_of_record);
  785. /**
  786. * qdf_dp_trace_verbosity_check() - check whether verbosity level is enabled
  787. * @code: defines the event
  788. *
  789. * In High verbosity all codes are logged.
  790. * For Med/Low and Default case code which has
  791. * less value than corresponding verbosity codes
  792. * are logged.
  793. *
  794. * Return: true or false depends on whether tracing enabled
  795. */
  796. static bool qdf_dp_trace_verbosity_check(enum QDF_DP_TRACE_ID code)
  797. {
  798. switch (g_qdf_dp_trace_data.verbosity) {
  799. case QDF_DP_TRACE_VERBOSITY_HIGH:
  800. return true;
  801. case QDF_DP_TRACE_VERBOSITY_MEDIUM:
  802. if (code <= QDF_DP_TRACE_MED_VERBOSITY)
  803. return true;
  804. return false;
  805. case QDF_DP_TRACE_VERBOSITY_LOW:
  806. if (code <= QDF_DP_TRACE_LOW_VERBOSITY)
  807. return true;
  808. return false;
  809. case QDF_DP_TRACE_VERBOSITY_ULTRA_LOW:
  810. if (code <= QDF_DP_TRACE_ULTRA_LOW_VERBOSITY)
  811. return true;
  812. return false;
  813. case QDF_DP_TRACE_VERBOSITY_BASE:
  814. if (code <= QDF_DP_TRACE_BASE_VERBOSITY)
  815. return true;
  816. return false;
  817. default:
  818. return false;
  819. }
  820. }
  821. /**
  822. * qdf_dp_get_proto_bitmap() - get dp trace proto bitmap
  823. *
  824. * Return: proto bitmap
  825. */
  826. uint32_t qdf_dp_get_proto_bitmap(void)
  827. {
  828. if (g_qdf_dp_trace_data.enable)
  829. return g_qdf_dp_trace_data.proto_bitmap;
  830. else
  831. return 0;
  832. }
  833. /**
  834. * qdf_dp_trace_set_track() - Marks whether the packet needs to be traced
  835. * @nbuf: defines the netbuf
  836. * @dir: direction
  837. *
  838. * Return: None
  839. */
  840. void qdf_dp_trace_set_track(qdf_nbuf_t nbuf, enum qdf_proto_dir dir)
  841. {
  842. uint32_t count = 0;
  843. if (!g_qdf_dp_trace_data.enable)
  844. return;
  845. spin_lock_bh(&l_dp_trace_lock);
  846. if (QDF_TX == dir)
  847. count = ++g_qdf_dp_trace_data.tx_count;
  848. else if (QDF_RX == dir)
  849. count = ++g_qdf_dp_trace_data.rx_count;
  850. if ((g_qdf_dp_trace_data.no_of_record != 0) &&
  851. (count % g_qdf_dp_trace_data.no_of_record == 0)) {
  852. if (QDF_TX == dir)
  853. QDF_NBUF_CB_TX_DP_TRACE(nbuf) = 1;
  854. else if (QDF_RX == dir)
  855. QDF_NBUF_CB_RX_DP_TRACE(nbuf) = 1;
  856. }
  857. spin_unlock_bh(&l_dp_trace_lock);
  858. }
  859. qdf_export_symbol(qdf_dp_trace_set_track);
  860. /* Number of bytes to be grouped together while printing DP-Trace data */
  861. #define QDF_DUMP_DP_GROUP_SIZE 6
  862. /**
  863. * dump_dp_hex_trace() - Display the data in buffer
  864. * @prepend_str: string to prepend the hexdump with.
  865. * @inbuf: buffer which contains data to be displayed
  866. * @inbuf_len: defines the size of the data to be displayed
  867. *
  868. * Return: None
  869. */
  870. static void
  871. dump_dp_hex_trace(char *prepend_str, uint8_t *inbuf, uint8_t inbuf_len)
  872. {
  873. unsigned char outbuf[BUFFER_SIZE];
  874. const uint8_t *inbuf_ptr = inbuf;
  875. char *outbuf_ptr = outbuf;
  876. int outbytes_written = 0;
  877. qdf_mem_zero(outbuf, sizeof(outbuf));
  878. do {
  879. outbytes_written += scnprintf(outbuf_ptr,
  880. BUFFER_SIZE - outbytes_written,
  881. "%02x", *inbuf_ptr);
  882. outbuf_ptr = outbuf + outbytes_written;
  883. if ((inbuf_ptr - inbuf) &&
  884. (inbuf_ptr - inbuf + 1) % QDF_DUMP_DP_GROUP_SIZE == 0) {
  885. outbytes_written += scnprintf(outbuf_ptr,
  886. BUFFER_SIZE - outbytes_written,
  887. " ");
  888. outbuf_ptr = outbuf + outbytes_written;
  889. }
  890. inbuf_ptr++;
  891. } while (inbuf_ptr < (inbuf + inbuf_len));
  892. DPTRACE_PRINT("%s %s", prepend_str, outbuf);
  893. }
  894. /**
  895. * qdf_dp_code_to_string() - convert dptrace code to string
  896. * @code: dptrace code
  897. *
  898. * Return: string version of code
  899. */
  900. static
  901. const char *qdf_dp_code_to_string(enum QDF_DP_TRACE_ID code)
  902. {
  903. switch (code) {
  904. case QDF_DP_TRACE_DROP_PACKET_RECORD:
  905. return "DROP:";
  906. case QDF_DP_TRACE_EAPOL_PACKET_RECORD:
  907. return "EAPOL:";
  908. case QDF_DP_TRACE_DHCP_PACKET_RECORD:
  909. return "DHCP:";
  910. case QDF_DP_TRACE_ARP_PACKET_RECORD:
  911. return "ARP:";
  912. case QDF_DP_TRACE_ICMP_PACKET_RECORD:
  913. return "ICMP:";
  914. case QDF_DP_TRACE_ICMPv6_PACKET_RECORD:
  915. return "ICMPv6:";
  916. case QDF_DP_TRACE_MGMT_PACKET_RECORD:
  917. return "MGMT:";
  918. case QDF_DP_TRACE_TX_CREDIT_RECORD:
  919. return "CREDIT:";
  920. case QDF_DP_TRACE_EVENT_RECORD:
  921. return "EVENT:";
  922. case QDF_DP_TRACE_HDD_TX_PACKET_PTR_RECORD:
  923. return "HDD: TX: PTR:";
  924. case QDF_DP_TRACE_LI_DP_TX_PACKET_PTR_RECORD:
  925. return "LI_DP: TX: PTR:";
  926. case QDF_DP_TRACE_HDD_TX_PACKET_RECORD:
  927. return "HDD: TX: DATA:";
  928. case QDF_DP_TRACE_LI_DP_TX_PACKET_RECORD:
  929. case QDF_DP_TRACE_TX_PACKET_RECORD:
  930. return "TX:";
  931. case QDF_DP_TRACE_CE_PACKET_PTR_RECORD:
  932. return "CE: TX: PTR:";
  933. case QDF_DP_TRACE_CE_FAST_PACKET_PTR_RECORD:
  934. return "CE: TX: FAST: PTR:";
  935. case QDF_DP_TRACE_CE_FAST_PACKET_ERR_RECORD:
  936. return "CE: TX: FAST: ERR:";
  937. case QDF_DP_TRACE_LI_DP_FREE_PACKET_PTR_RECORD:
  938. case QDF_DP_TRACE_FREE_PACKET_PTR_RECORD:
  939. return "FREE: TX: PTR:";
  940. case QDF_DP_TRACE_RX_HTT_PACKET_PTR_RECORD:
  941. return "HTT: RX: PTR:";
  942. case QDF_DP_TRACE_RX_OFFLOAD_HTT_PACKET_PTR_RECORD:
  943. return "HTT: RX: OF: PTR:";
  944. case QDF_DP_TRACE_RX_HDD_PACKET_PTR_RECORD:
  945. return "HDD: RX: PTR:";
  946. case QDF_DP_TRACE_RX_LI_DP_PACKET_PTR_RECORD:
  947. return "LI_DP: RX: PTR:";
  948. case QDF_DP_TRACE_HDD_RX_PACKET_RECORD:
  949. return "HDD: RX: DATA:";
  950. case QDF_DP_TRACE_LI_DP_NULL_RX_PACKET_RECORD:
  951. return "LI_DP_NULL: RX: DATA:";
  952. case QDF_DP_TRACE_LI_DP_RX_PACKET_RECORD:
  953. case QDF_DP_TRACE_RX_PACKET_RECORD:
  954. return "RX:";
  955. case QDF_DP_TRACE_TXRX_QUEUE_PACKET_PTR_RECORD:
  956. return "TXRX: TX: Q: PTR:";
  957. case QDF_DP_TRACE_TXRX_PACKET_PTR_RECORD:
  958. return "TXRX: TX: PTR:";
  959. case QDF_DP_TRACE_TXRX_FAST_PACKET_PTR_RECORD:
  960. return "TXRX: TX: FAST: PTR:";
  961. case QDF_DP_TRACE_HTT_PACKET_PTR_RECORD:
  962. return "HTT: TX: PTR:";
  963. case QDF_DP_TRACE_HTC_PACKET_PTR_RECORD:
  964. return "HTC: TX: PTR:";
  965. case QDF_DP_TRACE_HIF_PACKET_PTR_RECORD:
  966. return "HIF: TX: PTR:";
  967. case QDF_DP_TRACE_RX_TXRX_PACKET_PTR_RECORD:
  968. return "TXRX: RX: PTR:";
  969. case QDF_DP_TRACE_HDD_TX_TIMEOUT:
  970. return "HDD: STA: TO:";
  971. case QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT:
  972. return "HDD: SAP: TO:";
  973. default:
  974. return "Invalid";
  975. }
  976. }
  977. /**
  978. * qdf_dp_dir_to_str() - convert direction to string
  979. * @dir: direction
  980. *
  981. * Return: string version of direction
  982. */
  983. static const char *qdf_dp_dir_to_str(enum qdf_proto_dir dir)
  984. {
  985. switch (dir) {
  986. case QDF_TX:
  987. return " --> ";
  988. case QDF_RX:
  989. return " <-- ";
  990. default:
  991. return "invalid";
  992. }
  993. }
  994. static const char *qdf_dp_credit_source_to_str(
  995. enum QDF_CREDIT_UPDATE_SOURCE source)
  996. {
  997. switch (source) {
  998. case QDF_TX_SCHED:
  999. return "TX SCHED";
  1000. case QDF_TX_COMP:
  1001. return "TX COMP";
  1002. case QDF_TX_CREDIT_UPDATE:
  1003. return "CREDIT UP";
  1004. case QDF_TX_HTT_MSG:
  1005. return "HTT TX MSG";
  1006. case QDF_HTT_ATTACH:
  1007. return "HTT ATTACH";
  1008. default:
  1009. return "invalid";
  1010. }
  1011. }
  1012. static const char *qdf_dp_operation_to_str(enum QDF_CREDIT_OPERATION op)
  1013. {
  1014. switch (op) {
  1015. case QDF_CREDIT_INC:
  1016. return "+";
  1017. case QDF_CREDIT_DEC:
  1018. return "-";
  1019. case QDF_CREDIT_ABS:
  1020. return "ABS";
  1021. default:
  1022. return "invalid";
  1023. }
  1024. }
  1025. /**
  1026. * qdf_dp_type_to_str() - convert packet type to string
  1027. * @type: type
  1028. *
  1029. * Return: string version of packet type
  1030. */
  1031. static const char *qdf_dp_type_to_str(enum qdf_proto_type type)
  1032. {
  1033. switch (type) {
  1034. case QDF_PROTO_TYPE_DHCP:
  1035. return "DHCP";
  1036. case QDF_PROTO_TYPE_EAPOL:
  1037. return "EAPOL";
  1038. case QDF_PROTO_TYPE_ARP:
  1039. return "ARP";
  1040. case QDF_PROTO_TYPE_ICMP:
  1041. return "ICMP";
  1042. case QDF_PROTO_TYPE_ICMPv6:
  1043. return "ICMPv6";
  1044. case QDF_PROTO_TYPE_MGMT:
  1045. return "MGMT";
  1046. case QDF_PROTO_TYPE_EVENT:
  1047. return "EVENT";
  1048. default:
  1049. return "invalid";
  1050. }
  1051. }
  1052. /**
  1053. * qdf_dp_subtype_to_str() - convert packet subtype to string
  1054. * @type: type
  1055. *
  1056. * Return: string version of packet subtype
  1057. */
  1058. static const char *qdf_dp_subtype_to_str(enum qdf_proto_subtype subtype)
  1059. {
  1060. switch (subtype) {
  1061. case QDF_PROTO_EAPOL_M1:
  1062. return "M1";
  1063. case QDF_PROTO_EAPOL_M2:
  1064. return "M2";
  1065. case QDF_PROTO_EAPOL_M3:
  1066. return "M3";
  1067. case QDF_PROTO_EAPOL_M4:
  1068. return "M4";
  1069. case QDF_PROTO_DHCP_DISCOVER:
  1070. return "DISC";
  1071. case QDF_PROTO_DHCP_REQUEST:
  1072. return "REQ";
  1073. case QDF_PROTO_DHCP_OFFER:
  1074. return "OFF";
  1075. case QDF_PROTO_DHCP_ACK:
  1076. return "ACK";
  1077. case QDF_PROTO_DHCP_NACK:
  1078. return "NACK";
  1079. case QDF_PROTO_DHCP_RELEASE:
  1080. return "REL";
  1081. case QDF_PROTO_DHCP_INFORM:
  1082. return "INFORM";
  1083. case QDF_PROTO_DHCP_DECLINE:
  1084. return "DECL";
  1085. case QDF_PROTO_ARP_REQ:
  1086. case QDF_PROTO_ICMP_REQ:
  1087. case QDF_PROTO_ICMPV6_REQ:
  1088. return "REQ";
  1089. case QDF_PROTO_ARP_RES:
  1090. case QDF_PROTO_ICMP_RES:
  1091. case QDF_PROTO_ICMPV6_RES:
  1092. return "RSP";
  1093. case QDF_PROTO_ICMPV6_RS:
  1094. return "RS";
  1095. case QDF_PROTO_ICMPV6_RA:
  1096. return "RA";
  1097. case QDF_PROTO_ICMPV6_NS:
  1098. return "NS";
  1099. case QDF_PROTO_ICMPV6_NA:
  1100. return "NA";
  1101. case QDF_PROTO_MGMT_ASSOC:
  1102. return "ASSOC";
  1103. case QDF_PROTO_MGMT_DISASSOC:
  1104. return "DISASSOC";
  1105. case QDF_PROTO_MGMT_AUTH:
  1106. return "AUTH";
  1107. case QDF_PROTO_MGMT_DEAUTH:
  1108. return "DEAUTH";
  1109. case QDF_ROAM_SYNCH:
  1110. return "ROAM SYNCH";
  1111. case QDF_ROAM_COMPLETE:
  1112. return "ROAM COMP";
  1113. case QDF_ROAM_EVENTID:
  1114. return "ROAM EVENTID";
  1115. default:
  1116. return "invalid";
  1117. }
  1118. }
  1119. /**
  1120. * qdf_dp_enable_check() - check if dptrace, TX/RX tracing is enabled
  1121. * @nbuf: nbuf
  1122. * @code: dptrace code
  1123. * @dir: TX or RX direction
  1124. *
  1125. * Return: true/false
  1126. */
  1127. static bool qdf_dp_enable_check(qdf_nbuf_t nbuf, enum QDF_DP_TRACE_ID code,
  1128. enum qdf_proto_dir dir)
  1129. {
  1130. /* Return when Dp trace is not enabled */
  1131. if (!g_qdf_dp_trace_data.enable)
  1132. return false;
  1133. if (qdf_dp_trace_verbosity_check(code) == false)
  1134. return false;
  1135. if (nbuf && (dir == QDF_TX && ((QDF_NBUF_CB_TX_DP_TRACE(nbuf) == 0) ||
  1136. (QDF_NBUF_CB_TX_PACKET_TRACK(nbuf) !=
  1137. QDF_NBUF_TX_PKT_DATA_TRACK))))
  1138. return false;
  1139. if (nbuf && (dir == QDF_RX && (QDF_NBUF_CB_RX_DP_TRACE(nbuf) == 0)))
  1140. return false;
  1141. /*
  1142. * Special packets called with NULL nbuf and this API is expected to
  1143. * return true
  1144. */
  1145. return true;
  1146. }
  1147. /**
  1148. * qdf_dp_trace_fill_meta_str() - fill up a common meta string
  1149. * @prepend_str: pointer to string
  1150. * @size: size of prepend_str
  1151. * @rec_index: index of record
  1152. * @info: info related to the record
  1153. * @record: pointer to the record
  1154. *
  1155. * Return: ret value from scnprintf
  1156. */
  1157. static inline
  1158. int qdf_dp_trace_fill_meta_str(char *prepend_str, int size,
  1159. int rec_index, uint8_t info,
  1160. struct qdf_dp_trace_record_s *record)
  1161. {
  1162. char buffer[20];
  1163. int ret = 0;
  1164. bool live = info & QDF_DP_TRACE_RECORD_INFO_LIVE ? true : false;
  1165. bool throttled = info & QDF_DP_TRACE_RECORD_INFO_THROTTLED ?
  1166. true : false;
  1167. scnprintf(buffer, sizeof(buffer), "%llu", record->time);
  1168. ret = scnprintf(prepend_str, size,
  1169. "%s DPT: %04d:%02d%s %s",
  1170. throttled ? "*" : "",
  1171. rec_index,
  1172. record->pdev_id,
  1173. live ? "" : buffer,
  1174. qdf_dp_code_to_string(record->code));
  1175. return ret;
  1176. }
  1177. /**
  1178. * qdf_dp_fill_record_data() - fill meta data and data into the record
  1179. * @rec: pointer to record data
  1180. * @data: pointer to data
  1181. * @data_size: size of the data
  1182. * @meta_data: pointer to metadata
  1183. * @metadata_size: size of metadata
  1184. *
  1185. * Should be called from within a spin_lock for the qdf record.
  1186. * Fills up rec->data with |metadata|data|
  1187. *
  1188. * Return: none
  1189. */
  1190. static void qdf_dp_fill_record_data
  1191. (struct qdf_dp_trace_record_s *rec,
  1192. uint8_t *data, uint8_t data_size,
  1193. uint8_t *meta_data, uint8_t metadata_size)
  1194. {
  1195. int32_t available = QDF_DP_TRACE_RECORD_SIZE;
  1196. uint8_t *rec_data = rec->data;
  1197. uint8_t data_to_copy = 0;
  1198. qdf_mem_zero(rec_data, QDF_DP_TRACE_RECORD_SIZE);
  1199. /* copy meta data */
  1200. if (meta_data) {
  1201. if (metadata_size > available) {
  1202. QDF_TRACE_WARN(QDF_MODULE_ID_QDF,
  1203. "%s: meta data does not fit into the record",
  1204. __func__);
  1205. goto end;
  1206. }
  1207. qdf_mem_copy(rec_data, meta_data, metadata_size);
  1208. available = available - metadata_size;
  1209. } else {
  1210. metadata_size = 0;
  1211. }
  1212. /* copy data */
  1213. if (data && (data_size > 0) && (available > 0)) {
  1214. data_to_copy = data_size;
  1215. if (data_size > available)
  1216. data_to_copy = available;
  1217. qdf_mem_copy(&rec_data[metadata_size], data, data_to_copy);
  1218. }
  1219. end:
  1220. rec->size = data_to_copy;
  1221. }
  1222. /**
  1223. * qdf_dp_add_record() - add dp trace record
  1224. * @code: dptrace code
  1225. * @pdev_id: pdev_id
  1226. * @print: true to print it in kmsg
  1227. * @data: data pointer
  1228. * @data_size: size of data to be copied
  1229. * @meta_data: meta data to be prepended to data
  1230. * @metadata_size: sizeof meta data
  1231. * @print: whether to print record
  1232. *
  1233. * Return: none
  1234. */
  1235. static void qdf_dp_add_record(enum QDF_DP_TRACE_ID code, uint8_t pdev_id,
  1236. uint8_t *data, uint8_t data_size,
  1237. uint8_t *meta_data, uint8_t metadata_size,
  1238. bool print)
  1239. {
  1240. struct qdf_dp_trace_record_s *rec = NULL;
  1241. int index;
  1242. bool print_this_record = false;
  1243. u8 info = 0;
  1244. if (code >= QDF_DP_TRACE_MAX) {
  1245. QDF_TRACE_ERROR(QDF_MODULE_ID_QDF,
  1246. "invalid record code %u, max code %u",
  1247. code, QDF_DP_TRACE_MAX);
  1248. return;
  1249. }
  1250. spin_lock_bh(&l_dp_trace_lock);
  1251. if (print || g_qdf_dp_trace_data.force_live_mode) {
  1252. print_this_record = true;
  1253. } else if (g_qdf_dp_trace_data.live_mode == 1) {
  1254. print_this_record = true;
  1255. g_qdf_dp_trace_data.print_pkt_cnt++;
  1256. if (g_qdf_dp_trace_data.print_pkt_cnt >
  1257. g_qdf_dp_trace_data.high_tput_thresh) {
  1258. g_qdf_dp_trace_data.live_mode = 0;
  1259. g_qdf_dp_trace_data.verbosity =
  1260. QDF_DP_TRACE_VERBOSITY_ULTRA_LOW;
  1261. info |= QDF_DP_TRACE_RECORD_INFO_THROTTLED;
  1262. }
  1263. }
  1264. g_qdf_dp_trace_data.num++;
  1265. if (g_qdf_dp_trace_data.num > MAX_QDF_DP_TRACE_RECORDS)
  1266. g_qdf_dp_trace_data.num = MAX_QDF_DP_TRACE_RECORDS;
  1267. if (INVALID_QDF_DP_TRACE_ADDR == g_qdf_dp_trace_data.head) {
  1268. /* first record */
  1269. g_qdf_dp_trace_data.head = 0;
  1270. g_qdf_dp_trace_data.tail = 0;
  1271. } else {
  1272. /* queue is not empty */
  1273. g_qdf_dp_trace_data.tail++;
  1274. if (MAX_QDF_DP_TRACE_RECORDS == g_qdf_dp_trace_data.tail)
  1275. g_qdf_dp_trace_data.tail = 0;
  1276. if (g_qdf_dp_trace_data.head == g_qdf_dp_trace_data.tail) {
  1277. /* full */
  1278. if (MAX_QDF_DP_TRACE_RECORDS ==
  1279. ++g_qdf_dp_trace_data.head)
  1280. g_qdf_dp_trace_data.head = 0;
  1281. }
  1282. }
  1283. rec = &g_qdf_dp_trace_tbl[g_qdf_dp_trace_data.tail];
  1284. index = g_qdf_dp_trace_data.tail;
  1285. rec->code = code;
  1286. rec->pdev_id = pdev_id;
  1287. rec->size = 0;
  1288. qdf_dp_fill_record_data(rec, data, data_size,
  1289. meta_data, metadata_size);
  1290. rec->time = qdf_get_log_timestamp();
  1291. rec->pid = (in_interrupt() ? 0 : current->pid);
  1292. if (rec->code >= QDF_DP_TRACE_MAX) {
  1293. QDF_TRACE_ERROR(QDF_MODULE_ID_QDF,
  1294. "invalid record code %u, max code %u",
  1295. rec->code, QDF_DP_TRACE_MAX);
  1296. return;
  1297. }
  1298. spin_unlock_bh(&l_dp_trace_lock);
  1299. info |= QDF_DP_TRACE_RECORD_INFO_LIVE;
  1300. if (print_this_record)
  1301. qdf_dp_trace_cb_table[rec->code] (rec, index,
  1302. QDF_TRACE_DEFAULT_PDEV_ID, info);
  1303. }
  1304. /**
  1305. * qdf_get_rate_limit_by_type() - Get the rate limit by pkt type
  1306. * @type: packet type
  1307. *
  1308. * Return: Rate limit value for a particular packet type
  1309. */
  1310. static inline
  1311. uint8_t qdf_get_rate_limit_by_type(uint8_t type)
  1312. {
  1313. switch (type) {
  1314. case QDF_PROTO_TYPE_DHCP:
  1315. return QDF_MAX_DHCP_PKTS_PER_SEC;
  1316. case QDF_PROTO_TYPE_EAPOL:
  1317. return QDF_MAX_EAPOL_PKTS_PER_SEC;
  1318. case QDF_PROTO_TYPE_ARP:
  1319. return QDF_MAX_ARP_PKTS_PER_SEC;
  1320. case QDF_PROTO_TYPE_DNS:
  1321. return QDF_MAX_DNS_PKTS_PER_SEC;
  1322. default:
  1323. return QDF_MAX_OTHER_PKTS_PER_SEC;
  1324. }
  1325. }
  1326. /**
  1327. * qdf_get_pkt_type_string() - Get the string based on pkt type
  1328. * @type: packet type
  1329. * @subtype: packet subtype
  1330. *
  1331. * Return: String based on pkt type
  1332. */
  1333. static
  1334. uint8_t *qdf_get_pkt_type_string(uint8_t type, uint8_t subtype)
  1335. {
  1336. switch (subtype) {
  1337. case QDF_PROTO_EAPOL_M1:
  1338. return "EAPOL-1";
  1339. case QDF_PROTO_EAPOL_M2:
  1340. return "EAPOL-2";
  1341. case QDF_PROTO_EAPOL_M3:
  1342. return "EAPOL-3";
  1343. case QDF_PROTO_EAPOL_M4:
  1344. return "EAPOL-4";
  1345. case QDF_PROTO_DHCP_DISCOVER:
  1346. return "DHCP-D";
  1347. case QDF_PROTO_DHCP_REQUEST:
  1348. return "DHCP-R";
  1349. case QDF_PROTO_DHCP_OFFER:
  1350. return "DHCP-O";
  1351. case QDF_PROTO_DHCP_ACK:
  1352. return "DHCP-A";
  1353. case QDF_PROTO_DHCP_NACK:
  1354. return "DHCP-NA";
  1355. case QDF_PROTO_DHCP_RELEASE:
  1356. return "DHCP-REL";
  1357. case QDF_PROTO_DHCP_INFORM:
  1358. return "DHCP-IN";
  1359. case QDF_PROTO_DHCP_DECLINE:
  1360. return "DHCP-DEC";
  1361. case QDF_PROTO_ARP_REQ:
  1362. return "ARP-RQ";
  1363. case QDF_PROTO_ARP_RES:
  1364. return "ARP-RS";
  1365. case QDF_PROTO_DNS_QUERY:
  1366. return "DNS_Q";
  1367. case QDF_PROTO_DNS_RES:
  1368. return "DNS_RS";
  1369. default:
  1370. switch (type) {
  1371. case QDF_PROTO_TYPE_EAPOL:
  1372. return "EAP";
  1373. case QDF_PROTO_TYPE_DHCP:
  1374. return "DHCP";
  1375. case QDF_PROTO_TYPE_ARP:
  1376. return "ARP";
  1377. case QDF_PROTO_TYPE_DNS:
  1378. return "DNS";
  1379. default:
  1380. return "UNKNOWN";
  1381. }
  1382. }
  1383. }
  1384. /**
  1385. * qdf_get_pkt_status_string() - Get the string based on pkt status
  1386. * @status: packet status
  1387. *
  1388. * Return: String based on pkt status
  1389. */
  1390. static
  1391. uint8_t *qdf_get_pkt_status_string(uint8_t status)
  1392. {
  1393. switch (status) {
  1394. case QDF_TX_RX_STATUS_INVALID:
  1395. return "inv";
  1396. case QDF_TX_RX_STATUS_OK:
  1397. return "succ";
  1398. case QDF_TX_RX_STATUS_FW_DISCARD:
  1399. return "disc";
  1400. case QDF_TX_RX_STATUS_NO_ACK:
  1401. return "nack";
  1402. case QDF_TX_RX_STATUS_DROP:
  1403. return "drop";
  1404. default:
  1405. return "unknown";
  1406. }
  1407. }
  1408. /**
  1409. * qdf_dp_log_proto_pkt_info() - Send diag log with pkt info
  1410. * @sa: Source MAC address
  1411. * @da: Destination MAC address
  1412. * @type: packet type
  1413. * @subtype: packet subtype
  1414. * @dir: tx or rx
  1415. * @msdu_id: MSDU id
  1416. * @status: status code
  1417. *
  1418. * Return: none
  1419. */
  1420. void qdf_dp_log_proto_pkt_info(uint8_t *sa, uint8_t *da, uint8_t type,
  1421. uint8_t subtype, uint8_t dir, uint16_t msdu_id,
  1422. uint8_t status)
  1423. {
  1424. uint8_t pkt_rate_limit;
  1425. static ulong last_ticks_tx[QDF_PROTO_SUBTYPE_MAX] = {0};
  1426. static ulong last_ticks_rx[QDF_PROTO_SUBTYPE_MAX] = {0};
  1427. ulong curr_ticks = jiffies;
  1428. pkt_rate_limit = qdf_get_rate_limit_by_type(type);
  1429. if ((dir == QDF_TX &&
  1430. !time_after(curr_ticks,
  1431. last_ticks_tx[subtype] + HZ / pkt_rate_limit)) ||
  1432. (dir == QDF_RX &&
  1433. !time_after(curr_ticks,
  1434. last_ticks_rx[subtype] + HZ / pkt_rate_limit)))
  1435. return;
  1436. if (dir == QDF_TX)
  1437. last_ticks_tx[subtype] = curr_ticks;
  1438. else
  1439. last_ticks_rx[subtype] = curr_ticks;
  1440. if (status == QDF_TX_RX_STATUS_INVALID)
  1441. qdf_nofl_info("%s %s: SA:" QDF_MAC_ADDR_FMT " DA:" QDF_MAC_ADDR_FMT,
  1442. qdf_get_pkt_type_string(type, subtype),
  1443. dir ? "RX" : "TX", QDF_MAC_ADDR_REF(sa),
  1444. QDF_MAC_ADDR_REF(da));
  1445. else
  1446. qdf_nofl_info("%s %s: SA:" QDF_MAC_ADDR_FMT " DA:" QDF_MAC_ADDR_FMT " msdu_id:%d status: %s",
  1447. qdf_get_pkt_type_string(type, subtype),
  1448. dir ? "RX" : "TX", QDF_MAC_ADDR_REF(sa),
  1449. QDF_MAC_ADDR_REF(da), msdu_id,
  1450. qdf_get_pkt_status_string(status));
  1451. }
  1452. qdf_export_symbol(qdf_dp_log_proto_pkt_info);
  1453. /**
  1454. * qdf_log_icmpv6_pkt() - log ICMPv6 packet
  1455. * @vdev_id: ID of the vdev
  1456. * @skb: skb pointer
  1457. * @dir: direction
  1458. * @pdev_id: ID of the pdev
  1459. *
  1460. * Return: true/false
  1461. */
  1462. static bool qdf_log_icmpv6_pkt(uint8_t vdev_id, struct sk_buff *skb,
  1463. enum qdf_proto_dir dir, uint8_t pdev_id)
  1464. {
  1465. enum qdf_proto_subtype subtype;
  1466. if ((qdf_dp_get_proto_bitmap() & QDF_NBUF_PKT_TRAC_TYPE_ICMPv6) &&
  1467. ((dir == QDF_TX && QDF_NBUF_CB_PACKET_TYPE_ICMPv6 ==
  1468. QDF_NBUF_CB_GET_PACKET_TYPE(skb)) ||
  1469. (dir == QDF_RX && qdf_nbuf_is_icmpv6_pkt(skb) == true))) {
  1470. subtype = qdf_nbuf_get_icmpv6_subtype(skb);
  1471. QDF_NBUF_CB_DP_TRACE_PRINT(skb) = false;
  1472. if (dir == QDF_TX)
  1473. QDF_NBUF_CB_TX_DP_TRACE(skb) = 1;
  1474. else if (dir == QDF_RX)
  1475. QDF_NBUF_CB_RX_DP_TRACE(skb) = 1;
  1476. DPTRACE(qdf_dp_trace_proto_pkt(
  1477. QDF_DP_TRACE_ICMPv6_PACKET_RECORD,
  1478. vdev_id, (skb->data + QDF_NBUF_SRC_MAC_OFFSET),
  1479. (skb->data + QDF_NBUF_DEST_MAC_OFFSET),
  1480. QDF_PROTO_TYPE_ICMPv6, subtype, dir, pdev_id, false, 0));
  1481. switch (subtype) {
  1482. case QDF_PROTO_ICMPV6_REQ:
  1483. g_qdf_dp_trace_data.icmpv6_req++;
  1484. break;
  1485. case QDF_PROTO_ICMPV6_RES:
  1486. g_qdf_dp_trace_data.icmpv6_resp++;
  1487. break;
  1488. case QDF_PROTO_ICMPV6_RS:
  1489. g_qdf_dp_trace_data.icmpv6_rs++;
  1490. break;
  1491. case QDF_PROTO_ICMPV6_RA:
  1492. g_qdf_dp_trace_data.icmpv6_ra++;
  1493. break;
  1494. case QDF_PROTO_ICMPV6_NS:
  1495. g_qdf_dp_trace_data.icmpv6_ns++;
  1496. break;
  1497. case QDF_PROTO_ICMPV6_NA:
  1498. g_qdf_dp_trace_data.icmpv6_na++;
  1499. break;
  1500. default:
  1501. break;
  1502. }
  1503. return true;
  1504. }
  1505. return false;
  1506. }
  1507. /**
  1508. * qdf_log_icmp_pkt() - log ICMP packet
  1509. * @vdev_id: ID of the vdev
  1510. * @skb: skb pointer
  1511. * @dir: direction
  1512. * @pdev_id: ID of the pdev
  1513. *
  1514. * Return: true/false
  1515. */
  1516. static bool qdf_log_icmp_pkt(uint8_t vdev_id, struct sk_buff *skb,
  1517. enum qdf_proto_dir dir, uint8_t pdev_id)
  1518. {
  1519. enum qdf_proto_subtype proto_subtype;
  1520. uint8_t *data = NULL;
  1521. uint16_t seq_num = 0;
  1522. uint16_t icmp_id = 0;
  1523. uint32_t proto_priv_data = 0;
  1524. if ((qdf_dp_get_proto_bitmap() & QDF_NBUF_PKT_TRAC_TYPE_ICMP) &&
  1525. (qdf_nbuf_is_icmp_pkt(skb) == true)) {
  1526. QDF_NBUF_CB_DP_TRACE_PRINT(skb) = false;
  1527. proto_subtype = qdf_nbuf_get_icmp_subtype(skb);
  1528. data = qdf_nbuf_data(skb);
  1529. icmp_id = qdf_cpu_to_be16(*(uint16_t *)(data + ICMP_ID_OFFSET));
  1530. seq_num = qdf_cpu_to_be16(*(uint16_t *)(data + ICMP_SEQ_NUM_OFFSET));
  1531. proto_priv_data |= ((proto_priv_data | ((uint32_t)icmp_id)) << 16);
  1532. proto_priv_data |= (uint32_t)seq_num;
  1533. if (QDF_TX == dir)
  1534. QDF_NBUF_CB_TX_DP_TRACE(skb) = 1;
  1535. else if (QDF_RX == dir)
  1536. QDF_NBUF_CB_RX_DP_TRACE(skb) = 1;
  1537. DPTRACE(qdf_dp_trace_proto_pkt(QDF_DP_TRACE_ICMP_PACKET_RECORD,
  1538. vdev_id,
  1539. skb->data +
  1540. QDF_NBUF_SRC_MAC_OFFSET,
  1541. skb->data +
  1542. QDF_NBUF_DEST_MAC_OFFSET,
  1543. QDF_PROTO_TYPE_ICMP,
  1544. proto_subtype, dir, pdev_id,
  1545. false, proto_priv_data));
  1546. if (proto_subtype == QDF_PROTO_ICMP_REQ)
  1547. g_qdf_dp_trace_data.icmp_req++;
  1548. else
  1549. g_qdf_dp_trace_data.icmp_resp++;
  1550. return true;
  1551. }
  1552. return false;
  1553. }
  1554. #ifdef CONNECTIVITY_DIAG_EVENT
  1555. enum diag_tx_status wlan_get_diag_tx_status(enum qdf_dp_tx_rx_status tx_status)
  1556. {
  1557. switch (tx_status) {
  1558. case DIAG_TX_RX_STATUS_FW_DISCARD:
  1559. case DIAG_TX_RX_STATUS_INVALID:
  1560. case DIAG_TX_RX_STATUS_DROP:
  1561. case DIAG_TX_RX_STATUS_DOWNLOAD_SUCC:
  1562. case DIAG_TX_RX_STATUS_DEFAULT:
  1563. default:
  1564. return DIAG_TX_STATUS_FAIL;
  1565. case DIAG_TX_RX_STATUS_NO_ACK:
  1566. return DIAG_TX_STATUS_NO_ACK;
  1567. case DIAG_TX_RX_STATUS_OK:
  1568. return DIAG_TX_STATUS_ACK;
  1569. }
  1570. return DIAG_TX_STATUS_FAIL;
  1571. }
  1572. /**
  1573. * qdf_subtype_to_wlan_main_tag() - Convert qdf subtype to wlan main tag
  1574. * @subtype: EAPoL key subtype
  1575. *
  1576. * Return: Wlan main tag subtype
  1577. */
  1578. static int qdf_subtype_to_wlan_main_tag(enum qdf_proto_subtype subtype)
  1579. {
  1580. switch (subtype) {
  1581. case QDF_PROTO_DHCP_DISCOVER:
  1582. return WLAN_CONN_DIAG_DHCP_DISC_EVENT;
  1583. case QDF_PROTO_DHCP_REQUEST:
  1584. return WLAN_CONN_DIAG_DHCP_REQUEST_EVENT;
  1585. case QDF_PROTO_DHCP_OFFER:
  1586. return WLAN_CONN_DIAG_DHCP_OFFER_EVENT;
  1587. case QDF_PROTO_DHCP_ACK:
  1588. return WLAN_CONN_DIAG_DHCP_ACK_EVENT;
  1589. case QDF_PROTO_DHCP_NACK:
  1590. return WLAN_CONN_DIAG_DHCP_NACK_EVENT;
  1591. case QDF_PROTO_EAPOL_M1:
  1592. return WLAN_CONN_DIAG_EAPOL_M1_EVENT;
  1593. case QDF_PROTO_EAPOL_M2:
  1594. return WLAN_CONN_DIAG_EAPOL_M2_EVENT;
  1595. case QDF_PROTO_EAPOL_M3:
  1596. return WLAN_CONN_DIAG_EAPOL_M3_EVENT;
  1597. case QDF_PROTO_EAPOL_M4:
  1598. return WLAN_CONN_DIAG_EAPOL_M4_EVENT;
  1599. default:
  1600. return WLAN_CONN_DIAG_MAX;
  1601. }
  1602. }
  1603. /**
  1604. * qdf_get_wlan_eap_code() - Get EAP code
  1605. * @data: skb data pointer
  1606. *
  1607. * Return: EAP code value
  1608. */
  1609. static int qdf_get_wlan_eap_code(uint8_t *data)
  1610. {
  1611. uint8_t code = *(data + EAP_CODE_OFFSET);
  1612. switch (code) {
  1613. case QDF_EAP_REQUEST:
  1614. return WLAN_CONN_DIAG_EAP_REQ_EVENT;
  1615. case QDF_EAP_RESPONSE:
  1616. return WLAN_CONN_DIAG_EAP_RESP_EVENT;
  1617. case QDF_EAP_SUCCESS:
  1618. return WLAN_CONN_DIAG_EAP_SUCC_EVENT;
  1619. case QDF_EAP_FAILURE:
  1620. return WLAN_CONN_DIAG_EAP_FAIL_EVENT;
  1621. default:
  1622. return WLAN_CONN_DIAG_MAX;
  1623. }
  1624. }
  1625. /**
  1626. * qdf_eapol_get_key_type() - Get EAPOL key type
  1627. * @data: skb data pointer
  1628. * @subtype: EAPoL key subtype
  1629. *
  1630. * Return: EAPOL key type
  1631. */
  1632. static
  1633. uint8_t qdf_eapol_get_key_type(uint8_t *data, enum qdf_proto_subtype subtype)
  1634. {
  1635. uint16_t key_info = *(uint16_t *)(data + EAPOL_KEY_INFO_OFFSET);
  1636. /* If key type is PTK, key type will be set in EAPOL Key info */
  1637. if (key_info & EAPOL_KEY_TYPE_MASK)
  1638. return qdf_subtype_to_wlan_main_tag(subtype);
  1639. else if (key_info & EAPOL_KEY_ENCRYPTED_MASK)
  1640. return WLAN_CONN_DIAG_GTK_M1_EVENT;
  1641. else
  1642. return WLAN_CONN_DIAG_GTK_M2_EVENT;
  1643. }
  1644. /**
  1645. * qdf_skip_wlan_connectivity_log() - Check if connectivity log need to skip
  1646. * @type: Protocol type
  1647. * @subtype: Protocol subtype
  1648. * @dir: Rx or Tx
  1649. *
  1650. * Return: true or false
  1651. */
  1652. static inline
  1653. bool qdf_skip_wlan_connectivity_log(enum qdf_proto_type type,
  1654. enum qdf_proto_subtype subtype,
  1655. enum qdf_proto_dir dir)
  1656. {
  1657. if (dir == QDF_RX && type == QDF_PROTO_TYPE_DHCP &&
  1658. (subtype == QDF_PROTO_DHCP_DISCOVER ||
  1659. subtype == QDF_PROTO_DHCP_REQUEST))
  1660. return true;
  1661. return false;
  1662. }
  1663. /**
  1664. * qdf_fill_wlan_connectivity_log() - Fill and queue protocol packet to logging
  1665. * the logging queue
  1666. * @type: Protocol type
  1667. * @subtype: Protocol subtype
  1668. * @dir: Rx or Tx
  1669. * @qdf_tx_status: Tx completion status
  1670. * @vdev_id: DP vdev ID
  1671. * @data: skb data pointer
  1672. *
  1673. * Return: None
  1674. */
  1675. static
  1676. void qdf_fill_wlan_connectivity_log(enum qdf_proto_type type,
  1677. enum qdf_proto_subtype subtype,
  1678. enum qdf_proto_dir dir,
  1679. enum qdf_dp_tx_rx_status qdf_tx_status,
  1680. uint8_t vdev_id, uint8_t *data)
  1681. {
  1682. uint8_t pkt_type;
  1683. WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_packet_info);
  1684. if (qdf_skip_wlan_connectivity_log(type, subtype, dir))
  1685. return;
  1686. qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event));
  1687. wlan_diag_event.diag_cmn.timestamp_us =
  1688. qdf_get_time_of_the_day_ms() * 1000;
  1689. wlan_diag_event.diag_cmn.ktime_us = qdf_ktime_to_us(qdf_ktime_get());
  1690. wlan_diag_event.diag_cmn.vdev_id = vdev_id;
  1691. wlan_diag_event.version = DIAG_MGMT_VERSION;
  1692. if (type == QDF_PROTO_TYPE_DHCP) {
  1693. wlan_diag_event.subtype =
  1694. qdf_subtype_to_wlan_main_tag(subtype);
  1695. } else if (type == QDF_PROTO_TYPE_EAPOL) {
  1696. pkt_type = *(data + EAPOL_PACKET_TYPE_OFFSET);
  1697. if (pkt_type == EAPOL_PACKET_TYPE_EAP) {
  1698. wlan_diag_event.subtype =
  1699. qdf_get_wlan_eap_code(data);
  1700. wlan_diag_event.eap_type =
  1701. *(data + EAP_TYPE_OFFSET);
  1702. wlan_diag_event.eap_len =
  1703. qdf_ntohs(*(uint16_t *)(data + EAP_LENGTH_OFFSET));
  1704. } else if (pkt_type == EAPOL_PACKET_TYPE_KEY) {
  1705. wlan_diag_event.subtype =
  1706. qdf_eapol_get_key_type(data, subtype);
  1707. } else {
  1708. return;
  1709. }
  1710. } else {
  1711. return;
  1712. }
  1713. /*Tx completion status needs to be logged*/
  1714. if (dir == QDF_TX)
  1715. wlan_diag_event.tx_status =
  1716. wlan_get_diag_tx_status(qdf_tx_status);
  1717. WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_CONN_DP);
  1718. }
  1719. #elif defined(WLAN_FEATURE_CONNECTIVITY_LOGGING)
  1720. /**
  1721. * qdf_subtype_to_wlan_main_tag() - Convert qdf subtype to wlan main tag
  1722. * @subtype: EAPoL key subtype
  1723. *
  1724. * Return: Wlan main tag subtype
  1725. */
  1726. static int qdf_subtype_to_wlan_main_tag(enum qdf_proto_subtype subtype)
  1727. {
  1728. switch (subtype) {
  1729. case QDF_PROTO_DHCP_DISCOVER:
  1730. return WLAN_DHCP_DISCOVER;
  1731. case QDF_PROTO_DHCP_REQUEST:
  1732. return WLAN_DHCP_REQUEST;
  1733. case QDF_PROTO_DHCP_OFFER:
  1734. return WLAN_DHCP_OFFER;
  1735. case QDF_PROTO_DHCP_ACK:
  1736. return WLAN_DHCP_ACK;
  1737. case QDF_PROTO_DHCP_NACK:
  1738. return WLAN_DHCP_NACK;
  1739. case QDF_PROTO_EAPOL_M1:
  1740. return WLAN_EAPOL_M1;
  1741. case QDF_PROTO_EAPOL_M2:
  1742. return WLAN_EAPOL_M2;
  1743. case QDF_PROTO_EAPOL_M3:
  1744. return WLAN_EAPOL_M3;
  1745. case QDF_PROTO_EAPOL_M4:
  1746. return WLAN_EAPOL_M4;
  1747. default:
  1748. return WLAN_TAG_MAX;
  1749. }
  1750. }
  1751. /**
  1752. * qdf_get_wlan_eap_code() - Get EAP code
  1753. * @data: skb data pointer
  1754. *
  1755. * Return: EAP code value
  1756. */
  1757. static int qdf_get_wlan_eap_code(uint8_t *data)
  1758. {
  1759. uint8_t code = *(data + EAP_CODE_OFFSET);
  1760. switch (code) {
  1761. case QDF_EAP_REQUEST:
  1762. return WLAN_EAP_REQUEST;
  1763. case QDF_EAP_RESPONSE:
  1764. return WLAN_EAP_RESPONSE;
  1765. case QDF_EAP_SUCCESS:
  1766. return WLAN_EAP_SUCCESS;
  1767. case QDF_EAP_FAILURE:
  1768. return WLAN_EAP_FAILURE;
  1769. default:
  1770. return WLAN_TAG_MAX;
  1771. }
  1772. }
  1773. /**
  1774. * qdf_eapol_get_key_type() - Get EAPOL key type
  1775. * @data: skb data pointer
  1776. * @subtype: EAPoL key subtype
  1777. *
  1778. * Return: EAPOL key type
  1779. */
  1780. static
  1781. uint8_t qdf_eapol_get_key_type(uint8_t *data, enum qdf_proto_subtype subtype)
  1782. {
  1783. uint16_t key_info = *(uint16_t *)(data + EAPOL_KEY_INFO_OFFSET);
  1784. /* If key type is PTK, key type will be set in EAPOL Key info */
  1785. if (key_info & EAPOL_KEY_TYPE_MASK)
  1786. return qdf_subtype_to_wlan_main_tag(subtype);
  1787. else if (key_info & EAPOL_KEY_ENCRYPTED_MASK)
  1788. return WLAN_GTK_M1;
  1789. else
  1790. return WLAN_GTK_M2;
  1791. }
  1792. /**
  1793. * qdf_skip_wlan_connectivity_log() - Check if connectivity log need to skip
  1794. * @type: Protocol type
  1795. * @subtype: Protocol subtype
  1796. * @dir: Rx or Tx
  1797. *
  1798. * Return: true or false
  1799. */
  1800. static inline
  1801. bool qdf_skip_wlan_connectivity_log(enum qdf_proto_type type,
  1802. enum qdf_proto_subtype subtype,
  1803. enum qdf_proto_dir dir)
  1804. {
  1805. if ((dir == QDF_RX) && (type == QDF_PROTO_TYPE_DHCP) &&
  1806. ((subtype == QDF_PROTO_DHCP_DISCOVER) ||
  1807. (subtype == QDF_PROTO_DHCP_REQUEST)))
  1808. return true;
  1809. return false;
  1810. }
  1811. static
  1812. void qdf_fill_wlan_connectivity_log(enum qdf_proto_type type,
  1813. enum qdf_proto_subtype subtype,
  1814. enum qdf_proto_dir dir,
  1815. enum qdf_dp_tx_rx_status qdf_tx_status,
  1816. uint8_t vdev_id, uint8_t *data)
  1817. {
  1818. struct wlan_log_record log_buf = {0};
  1819. uint8_t pkt_type;
  1820. if (qdf_skip_wlan_connectivity_log(type, subtype, dir))
  1821. return;
  1822. log_buf.timestamp_us = qdf_get_time_of_the_day_ms() * 1000;
  1823. log_buf.ktime_us = qdf_ktime_to_us(qdf_ktime_get());
  1824. log_buf.vdev_id = vdev_id;
  1825. if (type == QDF_PROTO_TYPE_DHCP) {
  1826. log_buf.log_subtype = qdf_subtype_to_wlan_main_tag(subtype);
  1827. } else if (type == QDF_PROTO_TYPE_EAPOL) {
  1828. pkt_type = *(data + EAPOL_PACKET_TYPE_OFFSET);
  1829. if (pkt_type == EAPOL_PACKET_TYPE_EAP) {
  1830. log_buf.log_subtype = qdf_get_wlan_eap_code(data);
  1831. log_buf.pkt_info.eap_type = *(data + EAP_TYPE_OFFSET);
  1832. log_buf.pkt_info.eap_len =
  1833. qdf_ntohs(*(uint16_t *)(data + EAP_LENGTH_OFFSET));
  1834. } else if (pkt_type == EAPOL_PACKET_TYPE_KEY) {
  1835. log_buf.log_subtype = qdf_eapol_get_key_type(data,
  1836. subtype);
  1837. } else {
  1838. return;
  1839. }
  1840. } else {
  1841. return;
  1842. }
  1843. /*Tx completion status needs to be logged*/
  1844. if (dir == QDF_TX)
  1845. log_buf.pkt_info.tx_status = qdf_tx_status;
  1846. wlan_connectivity_log_enqueue(&log_buf);
  1847. }
  1848. #else
  1849. static inline
  1850. void qdf_fill_wlan_connectivity_log(enum qdf_proto_type type,
  1851. enum qdf_proto_subtype subtype,
  1852. enum qdf_proto_dir dir,
  1853. enum qdf_dp_tx_rx_status qdf_tx_status,
  1854. uint8_t vdev_id, uint8_t *data)
  1855. {
  1856. }
  1857. #endif
  1858. /**
  1859. * qdf_log_eapol_pkt() - log EAPOL packet
  1860. * @vdev_id: ID of the vdev
  1861. * @skb: skb pointer
  1862. * @dir: direction
  1863. * @pdev_id: ID of the pdev
  1864. *
  1865. * Return: true/false
  1866. */
  1867. static bool qdf_log_eapol_pkt(uint8_t vdev_id, struct sk_buff *skb,
  1868. enum qdf_proto_dir dir, uint8_t pdev_id)
  1869. {
  1870. enum qdf_proto_subtype subtype;
  1871. uint32_t dp_eap_trace;
  1872. uint32_t dp_eap_event;
  1873. dp_eap_trace = qdf_dp_get_proto_bitmap() & QDF_NBUF_PKT_TRAC_TYPE_EAPOL;
  1874. dp_eap_event = qdf_dp_get_proto_event_bitmap() &
  1875. QDF_NBUF_PKT_TRAC_TYPE_EAPOL;
  1876. if (!dp_eap_trace && !dp_eap_event)
  1877. return false;
  1878. if (!((dir == QDF_TX && QDF_NBUF_CB_PACKET_TYPE_EAPOL ==
  1879. QDF_NBUF_CB_GET_PACKET_TYPE(skb)) ||
  1880. (dir == QDF_RX && qdf_nbuf_is_ipv4_eapol_pkt(skb) == true)))
  1881. return false;
  1882. subtype = qdf_nbuf_get_eapol_subtype(skb);
  1883. if (dp_eap_event && dir == QDF_RX) {
  1884. qdf_dp_log_proto_pkt_info(skb->data + QDF_NBUF_SRC_MAC_OFFSET,
  1885. skb->data + QDF_NBUF_DEST_MAC_OFFSET,
  1886. QDF_PROTO_TYPE_EAPOL, subtype, dir,
  1887. QDF_TRACE_DEFAULT_MSDU_ID,
  1888. QDF_TX_RX_STATUS_INVALID);
  1889. qdf_fill_wlan_connectivity_log(QDF_PROTO_TYPE_EAPOL, subtype,
  1890. QDF_RX, 0, vdev_id, skb->data);
  1891. }
  1892. if (dp_eap_trace) {
  1893. QDF_NBUF_CB_DP_TRACE_PRINT(skb) = true;
  1894. if (QDF_TX == dir)
  1895. QDF_NBUF_CB_TX_DP_TRACE(skb) = 1;
  1896. else if (QDF_RX == dir)
  1897. QDF_NBUF_CB_RX_DP_TRACE(skb) = 1;
  1898. DPTRACE(qdf_dp_trace_proto_pkt(QDF_DP_TRACE_EAPOL_PACKET_RECORD,
  1899. vdev_id,
  1900. skb->data +
  1901. QDF_NBUF_SRC_MAC_OFFSET,
  1902. skb->data +
  1903. QDF_NBUF_DEST_MAC_OFFSET,
  1904. QDF_PROTO_TYPE_EAPOL, subtype,
  1905. dir, pdev_id, true, 0));
  1906. switch (subtype) {
  1907. case QDF_PROTO_EAPOL_M1:
  1908. g_qdf_dp_trace_data.eapol_m1++;
  1909. break;
  1910. case QDF_PROTO_EAPOL_M2:
  1911. g_qdf_dp_trace_data.eapol_m2++;
  1912. break;
  1913. case QDF_PROTO_EAPOL_M3:
  1914. g_qdf_dp_trace_data.eapol_m3++;
  1915. break;
  1916. case QDF_PROTO_EAPOL_M4:
  1917. g_qdf_dp_trace_data.eapol_m4++;
  1918. break;
  1919. default:
  1920. g_qdf_dp_trace_data.eapol_others++;
  1921. break;
  1922. }
  1923. }
  1924. return true;
  1925. }
  1926. /**
  1927. * qdf_log_dhcp_pkt() - log DHCP packet
  1928. * @vdev_id: ID of the vdev
  1929. * @skb: skb pointer
  1930. * @dir: direction
  1931. * @pdev_id: ID of the pdev
  1932. *
  1933. * Return: true/false
  1934. */
  1935. static bool qdf_log_dhcp_pkt(uint8_t vdev_id, struct sk_buff *skb,
  1936. enum qdf_proto_dir dir, uint8_t pdev_id)
  1937. {
  1938. enum qdf_proto_subtype subtype = QDF_PROTO_INVALID;
  1939. uint32_t dp_dhcp_trace;
  1940. uint32_t dp_dhcp_event;
  1941. dp_dhcp_trace = qdf_dp_get_proto_bitmap() & QDF_NBUF_PKT_TRAC_TYPE_DHCP;
  1942. dp_dhcp_event = qdf_dp_get_proto_event_bitmap() &
  1943. QDF_NBUF_PKT_TRAC_TYPE_DHCP;
  1944. if (!dp_dhcp_trace && !dp_dhcp_event)
  1945. return false;
  1946. if (!((dir == QDF_TX && QDF_NBUF_CB_PACKET_TYPE_DHCP ==
  1947. QDF_NBUF_CB_GET_PACKET_TYPE(skb)) ||
  1948. (dir == QDF_RX && qdf_nbuf_is_ipv4_dhcp_pkt(skb) == true)))
  1949. return false;
  1950. subtype = qdf_nbuf_get_dhcp_subtype(skb);
  1951. if (dp_dhcp_event && dir == QDF_RX) {
  1952. qdf_dp_log_proto_pkt_info(skb->data + QDF_NBUF_SRC_MAC_OFFSET,
  1953. skb->data + QDF_NBUF_DEST_MAC_OFFSET,
  1954. QDF_PROTO_TYPE_DHCP, subtype, dir,
  1955. QDF_TRACE_DEFAULT_MSDU_ID,
  1956. QDF_TX_RX_STATUS_INVALID);
  1957. qdf_fill_wlan_connectivity_log(QDF_PROTO_TYPE_DHCP, subtype,
  1958. QDF_RX, 0, vdev_id, 0);
  1959. }
  1960. if (dp_dhcp_trace) {
  1961. QDF_NBUF_CB_DP_TRACE_PRINT(skb) = true;
  1962. if (QDF_TX == dir)
  1963. QDF_NBUF_CB_TX_DP_TRACE(skb) = 1;
  1964. else if (QDF_RX == dir)
  1965. QDF_NBUF_CB_RX_DP_TRACE(skb) = 1;
  1966. DPTRACE(qdf_dp_trace_proto_pkt(QDF_DP_TRACE_DHCP_PACKET_RECORD,
  1967. vdev_id,
  1968. skb->data +
  1969. QDF_NBUF_SRC_MAC_OFFSET,
  1970. skb->data +
  1971. QDF_NBUF_DEST_MAC_OFFSET,
  1972. QDF_PROTO_TYPE_DHCP, subtype,
  1973. dir, pdev_id, true, 0));
  1974. switch (subtype) {
  1975. case QDF_PROTO_DHCP_DISCOVER:
  1976. g_qdf_dp_trace_data.dhcp_disc++;
  1977. break;
  1978. case QDF_PROTO_DHCP_OFFER:
  1979. g_qdf_dp_trace_data.dhcp_off++;
  1980. break;
  1981. case QDF_PROTO_DHCP_REQUEST:
  1982. g_qdf_dp_trace_data.dhcp_req++;
  1983. break;
  1984. case QDF_PROTO_DHCP_ACK:
  1985. g_qdf_dp_trace_data.dhcp_ack++;
  1986. break;
  1987. case QDF_PROTO_DHCP_NACK:
  1988. g_qdf_dp_trace_data.dhcp_nack++;
  1989. break;
  1990. default:
  1991. g_qdf_dp_trace_data.eapol_others++;
  1992. break;
  1993. }
  1994. }
  1995. return true;
  1996. }
  1997. /**
  1998. * qdf_log_arp_pkt() - log ARP packet
  1999. * @vdev_id: ID of the vdev
  2000. * @skb: skb pointer
  2001. * @dir: direction
  2002. * @pdev_id: ID of the pdev
  2003. *
  2004. * Return: true/false
  2005. */
  2006. static bool qdf_log_arp_pkt(uint8_t vdev_id, struct sk_buff *skb,
  2007. enum qdf_proto_dir dir, uint8_t pdev_id)
  2008. {
  2009. enum qdf_proto_subtype proto_subtype;
  2010. if ((qdf_dp_get_proto_bitmap() & QDF_NBUF_PKT_TRAC_TYPE_ARP) &&
  2011. ((dir == QDF_TX && QDF_NBUF_CB_PACKET_TYPE_ARP ==
  2012. QDF_NBUF_CB_GET_PACKET_TYPE(skb)) ||
  2013. (dir == QDF_RX && qdf_nbuf_is_ipv4_arp_pkt(skb) == true))) {
  2014. proto_subtype = qdf_nbuf_get_arp_subtype(skb);
  2015. QDF_NBUF_CB_DP_TRACE_PRINT(skb) = true;
  2016. if (QDF_TX == dir)
  2017. QDF_NBUF_CB_TX_DP_TRACE(skb) = 1;
  2018. else if (QDF_RX == dir)
  2019. QDF_NBUF_CB_RX_DP_TRACE(skb) = 1;
  2020. DPTRACE(qdf_dp_trace_proto_pkt(QDF_DP_TRACE_ARP_PACKET_RECORD,
  2021. vdev_id,
  2022. skb->data +
  2023. QDF_NBUF_SRC_MAC_OFFSET,
  2024. skb->data +
  2025. QDF_NBUF_DEST_MAC_OFFSET,
  2026. QDF_PROTO_TYPE_ARP,
  2027. proto_subtype, dir, pdev_id,
  2028. true, 0));
  2029. if (QDF_PROTO_ARP_REQ == proto_subtype)
  2030. g_qdf_dp_trace_data.arp_req++;
  2031. else
  2032. g_qdf_dp_trace_data.arp_resp++;
  2033. return true;
  2034. }
  2035. return false;
  2036. }
  2037. bool qdf_dp_trace_log_pkt(uint8_t vdev_id, struct sk_buff *skb,
  2038. enum qdf_proto_dir dir, uint8_t pdev_id)
  2039. {
  2040. if (!qdf_dp_get_proto_bitmap() && !qdf_dp_get_proto_event_bitmap())
  2041. return false;
  2042. if (qdf_log_arp_pkt(vdev_id, skb, dir, pdev_id))
  2043. return true;
  2044. if (qdf_log_dhcp_pkt(vdev_id, skb, dir, pdev_id))
  2045. return true;
  2046. if (qdf_log_eapol_pkt(vdev_id, skb, dir, pdev_id))
  2047. return true;
  2048. if (qdf_log_icmp_pkt(vdev_id, skb, dir, pdev_id))
  2049. return true;
  2050. if (qdf_log_icmpv6_pkt(vdev_id, skb, dir, pdev_id))
  2051. return true;
  2052. return false;
  2053. }
  2054. qdf_export_symbol(qdf_dp_trace_log_pkt);
  2055. void qdf_dp_display_mgmt_pkt(struct qdf_dp_trace_record_s *record,
  2056. uint16_t index, uint8_t pdev_id, uint8_t info)
  2057. {
  2058. int loc;
  2059. char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
  2060. struct qdf_dp_trace_mgmt_buf *buf =
  2061. (struct qdf_dp_trace_mgmt_buf *)record->data;
  2062. qdf_mem_zero(prepend_str, sizeof(prepend_str));
  2063. loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
  2064. index, info, record);
  2065. DPTRACE_PRINT("%s [%d] [%s %s]",
  2066. prepend_str,
  2067. buf->vdev_id,
  2068. qdf_dp_type_to_str(buf->type),
  2069. qdf_dp_subtype_to_str(buf->subtype));
  2070. }
  2071. qdf_export_symbol(qdf_dp_display_mgmt_pkt);
  2072. void qdf_dp_trace_mgmt_pkt(enum QDF_DP_TRACE_ID code, uint8_t vdev_id,
  2073. uint8_t pdev_id, enum qdf_proto_type type,
  2074. enum qdf_proto_subtype subtype)
  2075. {
  2076. struct qdf_dp_trace_mgmt_buf buf;
  2077. int buf_size = sizeof(struct qdf_dp_trace_mgmt_buf);
  2078. if (qdf_dp_enable_check(NULL, code, QDF_NA) == false)
  2079. return;
  2080. if (buf_size > QDF_DP_TRACE_RECORD_SIZE)
  2081. QDF_BUG(0);
  2082. buf.type = type;
  2083. buf.subtype = subtype;
  2084. buf.vdev_id = vdev_id;
  2085. qdf_dp_add_record(code, pdev_id, (uint8_t *)&buf, buf_size,
  2086. NULL, 0, true);
  2087. }
  2088. qdf_export_symbol(qdf_dp_trace_mgmt_pkt);
  2089. static void
  2090. qdf_dpt_display_credit_record_debugfs(qdf_debugfs_file_t file,
  2091. struct qdf_dp_trace_record_s *record,
  2092. uint32_t index)
  2093. {
  2094. int loc;
  2095. char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
  2096. struct qdf_dp_trace_credit_record *buf =
  2097. (struct qdf_dp_trace_credit_record *)record->data;
  2098. loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
  2099. index, 0, record);
  2100. if (buf->operation == QDF_OP_NA)
  2101. qdf_debugfs_printf(file, "%s [%s] [T: %d G0: %d G1: %d]\n",
  2102. prepend_str,
  2103. qdf_dp_credit_source_to_str(buf->source),
  2104. buf->total_credits, buf->g0_credit,
  2105. buf->g1_credit);
  2106. else
  2107. qdf_debugfs_printf(file,
  2108. "%s [%s] [T: %d G0: %d G1: %d] [%s %d]\n",
  2109. prepend_str,
  2110. qdf_dp_credit_source_to_str(buf->source),
  2111. buf->total_credits, buf->g0_credit,
  2112. buf->g1_credit,
  2113. qdf_dp_operation_to_str(buf->operation),
  2114. buf->delta);
  2115. }
  2116. void qdf_dp_display_credit_record(struct qdf_dp_trace_record_s *record,
  2117. uint16_t index, uint8_t pdev_id, uint8_t info)
  2118. {
  2119. int loc;
  2120. char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
  2121. struct qdf_dp_trace_credit_record *buf =
  2122. (struct qdf_dp_trace_credit_record *)record->data;
  2123. loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
  2124. index, info, record);
  2125. if (buf->operation == QDF_OP_NA)
  2126. DPTRACE_PRINT("%s [%s] [T: %d G0: %d G1: %d]",
  2127. prepend_str,
  2128. qdf_dp_credit_source_to_str(buf->source),
  2129. buf->total_credits, buf->g0_credit,
  2130. buf->g1_credit);
  2131. else
  2132. DPTRACE_PRINT("%s [%s] [T: %d G0: %d G1: %d] [%s %d]",
  2133. prepend_str,
  2134. qdf_dp_credit_source_to_str(buf->source),
  2135. buf->total_credits, buf->g0_credit,
  2136. buf->g1_credit,
  2137. qdf_dp_operation_to_str(buf->operation),
  2138. buf->delta);
  2139. }
  2140. void qdf_dp_trace_credit_record(enum QDF_CREDIT_UPDATE_SOURCE source,
  2141. enum QDF_CREDIT_OPERATION operation,
  2142. int delta, int total_credits,
  2143. int g0_credit, int g1_credit)
  2144. {
  2145. struct qdf_dp_trace_credit_record buf;
  2146. int buf_size = sizeof(struct qdf_dp_trace_credit_record);
  2147. enum QDF_DP_TRACE_ID code = QDF_DP_TRACE_TX_CREDIT_RECORD;
  2148. if (qdf_dp_enable_check(NULL, code, QDF_NA) == false)
  2149. return;
  2150. if (!(qdf_dp_get_proto_bitmap() & QDF_HL_CREDIT_TRACKING))
  2151. return;
  2152. if (buf_size > QDF_DP_TRACE_RECORD_SIZE)
  2153. QDF_BUG(0);
  2154. buf.source = source;
  2155. buf.operation = operation;
  2156. buf.delta = delta;
  2157. buf.total_credits = total_credits;
  2158. buf.g0_credit = g0_credit;
  2159. buf.g1_credit = g1_credit;
  2160. qdf_dp_add_record(code, QDF_TRACE_DEFAULT_PDEV_ID, (uint8_t *)&buf,
  2161. buf_size, NULL, 0, false);
  2162. }
  2163. qdf_export_symbol(qdf_dp_trace_credit_record);
  2164. void qdf_dp_display_event_record(struct qdf_dp_trace_record_s *record,
  2165. uint16_t index, uint8_t pdev_id, uint8_t info)
  2166. {
  2167. char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
  2168. struct qdf_dp_trace_event_buf *buf =
  2169. (struct qdf_dp_trace_event_buf *)record->data;
  2170. qdf_mem_zero(prepend_str, sizeof(prepend_str));
  2171. qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
  2172. index, info, record);
  2173. DPTRACE_PRINT("%s [%d] [%s %s]",
  2174. prepend_str,
  2175. buf->vdev_id,
  2176. qdf_dp_type_to_str(buf->type),
  2177. qdf_dp_subtype_to_str(buf->subtype));
  2178. }
  2179. qdf_export_symbol(qdf_dp_display_event_record);
  2180. /**
  2181. * qdf_dp_trace_record_event() - record events
  2182. * @code: dptrace code
  2183. * @vdev_id: vdev id
  2184. * @pdev_id: pdev_id
  2185. * @type: proto type
  2186. * @subtype: proto subtype
  2187. *
  2188. * Return: none
  2189. */
  2190. void qdf_dp_trace_record_event(enum QDF_DP_TRACE_ID code, uint8_t vdev_id,
  2191. uint8_t pdev_id, enum qdf_proto_type type,
  2192. enum qdf_proto_subtype subtype)
  2193. {
  2194. struct qdf_dp_trace_event_buf buf;
  2195. int buf_size = sizeof(struct qdf_dp_trace_event_buf);
  2196. if (qdf_dp_enable_check(NULL, code, QDF_NA) == false)
  2197. return;
  2198. if (buf_size > QDF_DP_TRACE_RECORD_SIZE)
  2199. QDF_BUG(0);
  2200. buf.type = type;
  2201. buf.subtype = subtype;
  2202. buf.vdev_id = vdev_id;
  2203. qdf_dp_add_record(code, pdev_id,
  2204. (uint8_t *)&buf, buf_size, NULL, 0, true);
  2205. }
  2206. qdf_export_symbol(qdf_dp_trace_record_event);
  2207. void qdf_dp_display_proto_pkt(struct qdf_dp_trace_record_s *record,
  2208. uint16_t index, uint8_t pdev_id, uint8_t info)
  2209. {
  2210. int loc;
  2211. char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
  2212. struct qdf_dp_trace_proto_buf *buf =
  2213. (struct qdf_dp_trace_proto_buf *)record->data;
  2214. qdf_mem_zero(prepend_str, sizeof(prepend_str));
  2215. loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
  2216. index, info, record);
  2217. DPTRACE_PRINT("%s [%d] [%s] SA: "
  2218. QDF_MAC_ADDR_FMT " %s DA:"
  2219. QDF_MAC_ADDR_FMT " proto priv data = %08x",
  2220. prepend_str,
  2221. buf->vdev_id,
  2222. qdf_dp_subtype_to_str(buf->subtype),
  2223. QDF_MAC_ADDR_REF(buf->sa.bytes),
  2224. qdf_dp_dir_to_str(buf->dir),
  2225. QDF_MAC_ADDR_REF(buf->da.bytes),
  2226. buf->proto_priv_data);
  2227. }
  2228. qdf_export_symbol(qdf_dp_display_proto_pkt);
  2229. void qdf_dp_trace_proto_pkt(enum QDF_DP_TRACE_ID code, uint8_t vdev_id,
  2230. uint8_t *sa, uint8_t *da, enum qdf_proto_type type,
  2231. enum qdf_proto_subtype subtype, enum qdf_proto_dir dir,
  2232. uint8_t pdev_id, bool print, uint32_t proto_priv_data)
  2233. {
  2234. struct qdf_dp_trace_proto_buf buf;
  2235. int buf_size = sizeof(struct qdf_dp_trace_proto_buf);
  2236. if (qdf_dp_enable_check(NULL, code, dir) == false)
  2237. return;
  2238. if (buf_size > QDF_DP_TRACE_RECORD_SIZE)
  2239. QDF_BUG(0);
  2240. memcpy(&buf.sa, sa, QDF_NET_ETH_LEN);
  2241. memcpy(&buf.da, da, QDF_NET_ETH_LEN);
  2242. buf.dir = dir;
  2243. buf.type = type;
  2244. buf.subtype = subtype;
  2245. buf.vdev_id = vdev_id;
  2246. buf.proto_priv_data = proto_priv_data;
  2247. qdf_dp_add_record(code, pdev_id,
  2248. (uint8_t *)&buf, buf_size, NULL, 0, print);
  2249. }
  2250. qdf_export_symbol(qdf_dp_trace_proto_pkt);
  2251. void qdf_dp_display_ptr_record(struct qdf_dp_trace_record_s *record,
  2252. uint16_t index, uint8_t pdev_id, uint8_t info)
  2253. {
  2254. int loc;
  2255. char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
  2256. struct qdf_dp_trace_ptr_buf *buf =
  2257. (struct qdf_dp_trace_ptr_buf *)record->data;
  2258. bool is_free_pkt_ptr_record = false;
  2259. if ((record->code == QDF_DP_TRACE_FREE_PACKET_PTR_RECORD) ||
  2260. (record->code == QDF_DP_TRACE_LI_DP_FREE_PACKET_PTR_RECORD))
  2261. is_free_pkt_ptr_record = true;
  2262. qdf_mem_zero(prepend_str, sizeof(prepend_str));
  2263. loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
  2264. index, info, record);
  2265. if (loc < sizeof(prepend_str))
  2266. scnprintf(&prepend_str[loc], sizeof(prepend_str) - loc,
  2267. "[msdu id %d %s %d]",
  2268. buf->msdu_id,
  2269. is_free_pkt_ptr_record ? "status" : "vdev_id",
  2270. buf->status);
  2271. if (info & QDF_DP_TRACE_RECORD_INFO_LIVE) {
  2272. /* In live mode donot dump the contents of the cookie */
  2273. DPTRACE_PRINT("%s", prepend_str);
  2274. } else {
  2275. dump_dp_hex_trace(prepend_str, (uint8_t *)&buf->cookie,
  2276. sizeof(buf->cookie));
  2277. }
  2278. }
  2279. qdf_export_symbol(qdf_dp_display_ptr_record);
  2280. static
  2281. enum qdf_proto_type qdf_dp_get_pkt_proto_type(qdf_nbuf_t nbuf)
  2282. {
  2283. uint8_t pkt_type;
  2284. if (!nbuf)
  2285. return QDF_PROTO_TYPE_MAX;
  2286. if (qdf_nbuf_data_is_dns_query(nbuf) ||
  2287. qdf_nbuf_data_is_dns_response(nbuf))
  2288. return QDF_PROTO_TYPE_DNS;
  2289. pkt_type = QDF_NBUF_CB_GET_PACKET_TYPE(nbuf);
  2290. switch (pkt_type) {
  2291. case QDF_NBUF_CB_PACKET_TYPE_EAPOL:
  2292. return QDF_PROTO_TYPE_EAPOL;
  2293. case QDF_NBUF_CB_PACKET_TYPE_ARP:
  2294. return QDF_PROTO_TYPE_ARP;
  2295. case QDF_NBUF_CB_PACKET_TYPE_DHCP:
  2296. return QDF_PROTO_TYPE_DHCP;
  2297. default:
  2298. return QDF_PROTO_TYPE_MAX;
  2299. }
  2300. }
  2301. static
  2302. enum qdf_proto_subtype qdf_dp_get_pkt_subtype(qdf_nbuf_t nbuf,
  2303. enum qdf_proto_type pkt_type)
  2304. {
  2305. switch (pkt_type) {
  2306. case QDF_PROTO_TYPE_EAPOL:
  2307. return qdf_nbuf_get_eapol_subtype(nbuf);
  2308. case QDF_PROTO_TYPE_ARP:
  2309. return qdf_nbuf_get_arp_subtype(nbuf);
  2310. case QDF_PROTO_TYPE_DHCP:
  2311. return qdf_nbuf_get_dhcp_subtype(nbuf);
  2312. case QDF_PROTO_TYPE_DNS:
  2313. return (qdf_nbuf_data_is_dns_query(nbuf)) ?
  2314. QDF_PROTO_DNS_QUERY : QDF_PROTO_DNS_RES;
  2315. default:
  2316. return QDF_PROTO_INVALID;
  2317. }
  2318. }
  2319. static
  2320. bool qdf_dp_proto_log_enable_check(enum qdf_proto_type pkt_type,
  2321. uint16_t status)
  2322. {
  2323. if (pkt_type == QDF_PROTO_TYPE_MAX)
  2324. return false;
  2325. switch (pkt_type) {
  2326. case QDF_PROTO_TYPE_EAPOL:
  2327. return qdf_dp_get_proto_event_bitmap() &
  2328. QDF_NBUF_PKT_TRAC_TYPE_EAPOL;
  2329. case QDF_PROTO_TYPE_DHCP:
  2330. return qdf_dp_get_proto_event_bitmap() &
  2331. QDF_NBUF_PKT_TRAC_TYPE_DHCP;
  2332. case QDF_PROTO_TYPE_ARP:
  2333. if (status == QDF_TX_RX_STATUS_OK)
  2334. return false;
  2335. else
  2336. return qdf_dp_get_proto_event_bitmap() &
  2337. QDF_NBUF_PKT_TRAC_TYPE_ARP;
  2338. case QDF_PROTO_TYPE_DNS:
  2339. if (status == QDF_TX_RX_STATUS_OK)
  2340. return false;
  2341. else
  2342. return qdf_dp_get_proto_event_bitmap() &
  2343. QDF_NBUF_PKT_TRAC_TYPE_DNS;
  2344. default:
  2345. return false;
  2346. }
  2347. }
  2348. void qdf_dp_track_noack_check(qdf_nbuf_t nbuf, enum qdf_proto_subtype *subtype)
  2349. {
  2350. enum qdf_proto_type pkt_type = qdf_dp_get_pkt_proto_type(nbuf);
  2351. uint16_t dp_track = 0;
  2352. switch (pkt_type) {
  2353. case QDF_PROTO_TYPE_EAPOL:
  2354. dp_track = qdf_dp_get_proto_bitmap() &
  2355. QDF_NBUF_PKT_TRAC_TYPE_EAPOL;
  2356. break;
  2357. case QDF_PROTO_TYPE_DHCP:
  2358. dp_track = qdf_dp_get_proto_bitmap() &
  2359. QDF_NBUF_PKT_TRAC_TYPE_DHCP;
  2360. break;
  2361. case QDF_PROTO_TYPE_ARP:
  2362. dp_track = qdf_dp_get_proto_bitmap() &
  2363. QDF_NBUF_PKT_TRAC_TYPE_ARP;
  2364. break;
  2365. case QDF_PROTO_TYPE_DNS:
  2366. dp_track = qdf_dp_get_proto_bitmap() &
  2367. QDF_NBUF_PKT_TRAC_TYPE_DNS;
  2368. break;
  2369. default:
  2370. break;
  2371. }
  2372. if (!dp_track) {
  2373. *subtype = QDF_PROTO_INVALID;
  2374. return;
  2375. }
  2376. *subtype = qdf_dp_get_pkt_subtype(nbuf, pkt_type);
  2377. }
  2378. qdf_export_symbol(qdf_dp_track_noack_check);
  2379. enum qdf_dp_tx_rx_status qdf_dp_get_status_from_a_status(uint8_t status)
  2380. {
  2381. if (status == QDF_A_STATUS_ERROR)
  2382. return QDF_TX_RX_STATUS_INVALID;
  2383. else if (status == QDF_A_STATUS_OK)
  2384. return QDF_TX_RX_STATUS_OK;
  2385. else
  2386. return QDF_TX_RX_STATUS_MAX;
  2387. }
  2388. qdf_export_symbol(qdf_dp_get_status_from_a_status);
  2389. void qdf_dp_trace_ptr(qdf_nbuf_t nbuf, enum QDF_DP_TRACE_ID code,
  2390. uint8_t pdev_id, uint8_t *data, uint8_t size,
  2391. uint16_t msdu_id, uint16_t buf_arg_status,
  2392. enum qdf_dp_tx_rx_status qdf_tx_status)
  2393. {
  2394. struct qdf_dp_trace_ptr_buf buf;
  2395. int buf_size = sizeof(struct qdf_dp_trace_ptr_buf);
  2396. enum qdf_proto_type pkt_type;
  2397. enum qdf_proto_subtype subtype;
  2398. pkt_type = qdf_dp_get_pkt_proto_type(nbuf);
  2399. if ((code == QDF_DP_TRACE_FREE_PACKET_PTR_RECORD ||
  2400. code == QDF_DP_TRACE_LI_DP_FREE_PACKET_PTR_RECORD) &&
  2401. qdf_dp_proto_log_enable_check(pkt_type, qdf_tx_status)) {
  2402. subtype = qdf_dp_get_pkt_subtype(nbuf, pkt_type);
  2403. qdf_dp_log_proto_pkt_info(nbuf->data + QDF_NBUF_SRC_MAC_OFFSET,
  2404. nbuf->data + QDF_NBUF_DEST_MAC_OFFSET,
  2405. pkt_type, subtype,
  2406. QDF_TX, msdu_id, qdf_tx_status);
  2407. qdf_fill_wlan_connectivity_log(pkt_type, subtype,
  2408. QDF_TX, qdf_tx_status,
  2409. QDF_NBUF_CB_TX_VDEV_CTX(nbuf),
  2410. nbuf->data);
  2411. }
  2412. if (qdf_dp_enable_check(nbuf, code, QDF_TX) == false)
  2413. return;
  2414. if (buf_size > QDF_DP_TRACE_RECORD_SIZE)
  2415. QDF_BUG(0);
  2416. qdf_mem_copy(&buf.cookie, data, size);
  2417. buf.msdu_id = msdu_id;
  2418. buf.status = buf_arg_status;
  2419. qdf_dp_add_record(code, pdev_id, (uint8_t *)&buf, buf_size, NULL, 0,
  2420. QDF_NBUF_CB_DP_TRACE_PRINT(nbuf));
  2421. }
  2422. qdf_export_symbol(qdf_dp_trace_ptr);
  2423. void qdf_dp_trace_data_pkt(qdf_nbuf_t nbuf, uint8_t pdev_id,
  2424. enum QDF_DP_TRACE_ID code, uint16_t msdu_id,
  2425. enum qdf_proto_dir dir)
  2426. {
  2427. struct qdf_dp_trace_data_buf buf;
  2428. enum qdf_proto_type pkt_type;
  2429. pkt_type = qdf_dp_get_pkt_proto_type(nbuf);
  2430. if (code == QDF_DP_TRACE_DROP_PACKET_RECORD &&
  2431. qdf_dp_proto_log_enable_check(pkt_type, QDF_TX_RX_STATUS_DROP))
  2432. qdf_dp_log_proto_pkt_info(nbuf->data + QDF_NBUF_SRC_MAC_OFFSET,
  2433. nbuf->data + QDF_NBUF_DEST_MAC_OFFSET,
  2434. pkt_type,
  2435. qdf_dp_get_pkt_subtype(nbuf, pkt_type),
  2436. QDF_TX, msdu_id,
  2437. QDF_TX_RX_STATUS_DROP);
  2438. buf.msdu_id = msdu_id;
  2439. if (!qdf_dp_enable_check(nbuf, code, dir))
  2440. return;
  2441. qdf_dp_add_record(code, pdev_id,
  2442. nbuf ? qdf_nbuf_data(nbuf) : NULL,
  2443. nbuf ? nbuf->len - nbuf->data_len : 0,
  2444. (uint8_t *)&buf, sizeof(struct qdf_dp_trace_data_buf),
  2445. (nbuf) ? QDF_NBUF_CB_DP_TRACE_PRINT(nbuf) : false);
  2446. }
  2447. qdf_export_symbol(qdf_dp_trace_data_pkt);
  2448. void qdf_dp_display_record(struct qdf_dp_trace_record_s *record,
  2449. uint16_t index, uint8_t pdev_id, uint8_t info)
  2450. {
  2451. int loc;
  2452. char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
  2453. if (!(pdev_id == QDF_TRACE_DEFAULT_PDEV_ID ||
  2454. pdev_id == record->pdev_id))
  2455. return;
  2456. qdf_mem_zero(prepend_str, sizeof(prepend_str));
  2457. loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
  2458. index, info, record);
  2459. switch (record->code) {
  2460. case QDF_DP_TRACE_HDD_TX_TIMEOUT:
  2461. DPTRACE_PRINT(" %s: HDD TX Timeout", prepend_str);
  2462. break;
  2463. case QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT:
  2464. DPTRACE_PRINT(" %s: HDD SoftAP TX Timeout", prepend_str);
  2465. break;
  2466. case QDF_DP_TRACE_CE_FAST_PACKET_ERR_RECORD:
  2467. DPTRACE_PRINT(" %s: CE Fast Packet Error", prepend_str);
  2468. break;
  2469. case QDF_DP_TRACE_LI_DP_NULL_RX_PACKET_RECORD:
  2470. default:
  2471. dump_dp_hex_trace(prepend_str, record->data, record->size);
  2472. break;
  2473. };
  2474. }
  2475. qdf_export_symbol(qdf_dp_display_record);
  2476. void
  2477. qdf_dp_display_data_pkt_record(struct qdf_dp_trace_record_s *record,
  2478. uint16_t rec_index, uint8_t pdev_id,
  2479. uint8_t info)
  2480. {
  2481. int loc;
  2482. char prepend_str[DP_TRACE_META_DATA_STRLEN + 10];
  2483. struct qdf_dp_trace_data_buf *buf =
  2484. (struct qdf_dp_trace_data_buf *)record->data;
  2485. qdf_mem_zero(prepend_str, sizeof(prepend_str));
  2486. loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
  2487. rec_index, info, record);
  2488. if (loc < sizeof(prepend_str))
  2489. loc += snprintf(&prepend_str[loc], sizeof(prepend_str) - loc,
  2490. "[%d]", buf->msdu_id);
  2491. dump_dp_hex_trace(prepend_str,
  2492. &record->data[sizeof(struct qdf_dp_trace_data_buf)],
  2493. record->size);
  2494. }
  2495. /**
  2496. * qdf_dp_trace() - Stores the data in buffer
  2497. * @nbuf : defines the netbuf
  2498. * @code : defines the event
  2499. * @pdev_id: pdev_id
  2500. * @data : defines the data to be stored
  2501. * @size : defines the size of the data record
  2502. *
  2503. * Return: None
  2504. */
  2505. void qdf_dp_trace(qdf_nbuf_t nbuf, enum QDF_DP_TRACE_ID code, uint8_t pdev_id,
  2506. uint8_t *data, uint8_t size, enum qdf_proto_dir dir)
  2507. {
  2508. if (qdf_dp_enable_check(nbuf, code, dir) == false)
  2509. return;
  2510. qdf_dp_add_record(code, pdev_id, nbuf ? qdf_nbuf_data(nbuf) : NULL,
  2511. size, NULL, 0,
  2512. (nbuf) ? QDF_NBUF_CB_DP_TRACE_PRINT(nbuf) : false);
  2513. }
  2514. qdf_export_symbol(qdf_dp_trace);
  2515. /**
  2516. * qdf_dp_trace_spin_lock_init() - initializes the lock variable before use
  2517. * This function will be called from cds_alloc_global_context, we will have lock
  2518. * available to use ASAP
  2519. *
  2520. * Return: None
  2521. */
  2522. void qdf_dp_trace_spin_lock_init(void)
  2523. {
  2524. spin_lock_init(&l_dp_trace_lock);
  2525. }
  2526. qdf_export_symbol(qdf_dp_trace_spin_lock_init);
  2527. /**
  2528. * qdf_dp_trace_disable_live_mode - disable live mode for dptrace
  2529. *
  2530. * Return: none
  2531. */
  2532. void qdf_dp_trace_disable_live_mode(void)
  2533. {
  2534. g_qdf_dp_trace_data.force_live_mode = 0;
  2535. }
  2536. qdf_export_symbol(qdf_dp_trace_disable_live_mode);
  2537. /**
  2538. * qdf_dp_trace_enable_live_mode() - enable live mode for dptrace
  2539. *
  2540. * Return: none
  2541. */
  2542. void qdf_dp_trace_enable_live_mode(void)
  2543. {
  2544. g_qdf_dp_trace_data.force_live_mode = 1;
  2545. }
  2546. qdf_export_symbol(qdf_dp_trace_enable_live_mode);
  2547. /**
  2548. * qdf_dp_trace_clear_buffer() - clear dp trace buffer
  2549. *
  2550. * Return: none
  2551. */
  2552. void qdf_dp_trace_clear_buffer(void)
  2553. {
  2554. g_qdf_dp_trace_data.head = INVALID_QDF_DP_TRACE_ADDR;
  2555. g_qdf_dp_trace_data.tail = INVALID_QDF_DP_TRACE_ADDR;
  2556. g_qdf_dp_trace_data.num = 0;
  2557. g_qdf_dp_trace_data.dump_counter = 0;
  2558. g_qdf_dp_trace_data.num_records_to_dump = MAX_QDF_DP_TRACE_RECORDS;
  2559. if (g_qdf_dp_trace_data.enable)
  2560. memset(g_qdf_dp_trace_tbl, 0,
  2561. MAX_QDF_DP_TRACE_RECORDS *
  2562. sizeof(struct qdf_dp_trace_record_s));
  2563. }
  2564. qdf_export_symbol(qdf_dp_trace_clear_buffer);
  2565. void qdf_dp_trace_dump_stats(void)
  2566. {
  2567. DPTRACE_PRINT("STATS |DPT: tx %u rx %u icmp(%u %u) arp(%u %u) icmpv6(%u %u %u %u %u %u) dhcp(%u %u %u %u %u %u) eapol(%u %u %u %u %u)",
  2568. g_qdf_dp_trace_data.tx_count,
  2569. g_qdf_dp_trace_data.rx_count,
  2570. g_qdf_dp_trace_data.icmp_req,
  2571. g_qdf_dp_trace_data.icmp_resp,
  2572. g_qdf_dp_trace_data.arp_req,
  2573. g_qdf_dp_trace_data.arp_resp,
  2574. g_qdf_dp_trace_data.icmpv6_req,
  2575. g_qdf_dp_trace_data.icmpv6_resp,
  2576. g_qdf_dp_trace_data.icmpv6_ns,
  2577. g_qdf_dp_trace_data.icmpv6_na,
  2578. g_qdf_dp_trace_data.icmpv6_rs,
  2579. g_qdf_dp_trace_data.icmpv6_ra,
  2580. g_qdf_dp_trace_data.dhcp_disc,
  2581. g_qdf_dp_trace_data.dhcp_off,
  2582. g_qdf_dp_trace_data.dhcp_req,
  2583. g_qdf_dp_trace_data.dhcp_ack,
  2584. g_qdf_dp_trace_data.dhcp_nack,
  2585. g_qdf_dp_trace_data.dhcp_others,
  2586. g_qdf_dp_trace_data.eapol_m1,
  2587. g_qdf_dp_trace_data.eapol_m2,
  2588. g_qdf_dp_trace_data.eapol_m3,
  2589. g_qdf_dp_trace_data.eapol_m4,
  2590. g_qdf_dp_trace_data.eapol_others);
  2591. }
  2592. qdf_export_symbol(qdf_dp_trace_dump_stats);
  2593. /**
  2594. * qdf_dpt_dump_hex_trace_debugfs() - read data in file
  2595. * @file: file to read
  2596. * @str: string to prepend the hexdump with.
  2597. * @buf: buffer which contains data to be written
  2598. * @buf_len: defines the size of the data to be written
  2599. *
  2600. * Return: None
  2601. */
  2602. static void qdf_dpt_dump_hex_trace_debugfs(qdf_debugfs_file_t file,
  2603. char *str, uint8_t *buf, uint8_t buf_len)
  2604. {
  2605. unsigned char linebuf[BUFFER_SIZE];
  2606. const u8 *ptr = buf;
  2607. int i, linelen, remaining = buf_len;
  2608. /* Dump the bytes in the last line */
  2609. for (i = 0; i < buf_len; i += ROW_SIZE) {
  2610. linelen = min(remaining, ROW_SIZE);
  2611. remaining -= ROW_SIZE;
  2612. hex_dump_to_buffer(ptr + i, linelen, ROW_SIZE, 1,
  2613. linebuf, sizeof(linebuf), false);
  2614. qdf_debugfs_printf(file, "%s %s\n", str, linebuf);
  2615. }
  2616. }
  2617. /**
  2618. * qdf_dpt_display_proto_pkt_debugfs() - display proto packet
  2619. * @file: file to read
  2620. * @record: dptrace record
  2621. * @index: index
  2622. *
  2623. * Return: none
  2624. */
  2625. static void qdf_dpt_display_proto_pkt_debugfs(qdf_debugfs_file_t file,
  2626. struct qdf_dp_trace_record_s *record,
  2627. uint32_t index)
  2628. {
  2629. int loc;
  2630. char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
  2631. struct qdf_dp_trace_proto_buf *buf =
  2632. (struct qdf_dp_trace_proto_buf *)record->data;
  2633. loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
  2634. index, 0, record);
  2635. qdf_debugfs_printf(file, "%s [%d] [%s] SA: "
  2636. QDF_MAC_ADDR_FMT " %s DA: "
  2637. QDF_MAC_ADDR_FMT,
  2638. prepend_str,
  2639. buf->vdev_id,
  2640. qdf_dp_subtype_to_str(buf->subtype),
  2641. QDF_MAC_ADDR_REF(buf->sa.bytes),
  2642. qdf_dp_dir_to_str(buf->dir),
  2643. QDF_MAC_ADDR_REF(buf->da.bytes));
  2644. qdf_debugfs_printf(file, "\n");
  2645. }
  2646. /**
  2647. * qdf_dpt_display_mgmt_pkt_debugfs() - display mgmt packet
  2648. * @file: file to read
  2649. * @record: dptrace record
  2650. * @index: index
  2651. *
  2652. * Return: none
  2653. */
  2654. static void qdf_dpt_display_mgmt_pkt_debugfs(qdf_debugfs_file_t file,
  2655. struct qdf_dp_trace_record_s *record,
  2656. uint32_t index)
  2657. {
  2658. int loc;
  2659. char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
  2660. struct qdf_dp_trace_mgmt_buf *buf =
  2661. (struct qdf_dp_trace_mgmt_buf *)record->data;
  2662. loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
  2663. index, 0, record);
  2664. qdf_debugfs_printf(file, "%s [%d] [%s %s]\n",
  2665. prepend_str,
  2666. buf->vdev_id,
  2667. qdf_dp_type_to_str(buf->type),
  2668. qdf_dp_subtype_to_str(buf->subtype));
  2669. }
  2670. /**
  2671. * qdf_dpt_display_event_record_debugfs() - display event records
  2672. * @file: file to read
  2673. * @record: dptrace record
  2674. * @index: index
  2675. *
  2676. * Return: none
  2677. */
  2678. static void qdf_dpt_display_event_record_debugfs(qdf_debugfs_file_t file,
  2679. struct qdf_dp_trace_record_s *record,
  2680. uint32_t index)
  2681. {
  2682. char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
  2683. struct qdf_dp_trace_event_buf *buf =
  2684. (struct qdf_dp_trace_event_buf *)record->data;
  2685. qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
  2686. index, 0, record);
  2687. qdf_debugfs_printf(file, "%s [%d] [%s %s]\n",
  2688. prepend_str,
  2689. buf->vdev_id,
  2690. qdf_dp_type_to_str(buf->type),
  2691. qdf_dp_subtype_to_str(buf->subtype));
  2692. }
  2693. /**
  2694. * qdf_dpt_display_ptr_record_debugfs() - display record ptr
  2695. * @file: file to read
  2696. * @record: dptrace record
  2697. * @index: index
  2698. *
  2699. * Return: none
  2700. */
  2701. static void qdf_dpt_display_ptr_record_debugfs(qdf_debugfs_file_t file,
  2702. struct qdf_dp_trace_record_s *record,
  2703. uint32_t index)
  2704. {
  2705. char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
  2706. int loc;
  2707. struct qdf_dp_trace_ptr_buf *buf =
  2708. (struct qdf_dp_trace_ptr_buf *)record->data;
  2709. loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
  2710. index, 0, record);
  2711. if (loc < sizeof(prepend_str))
  2712. scnprintf(&prepend_str[loc], sizeof(prepend_str) - loc,
  2713. "[msdu id %d %s %d]",
  2714. buf->msdu_id,
  2715. (record->code ==
  2716. QDF_DP_TRACE_FREE_PACKET_PTR_RECORD) ?
  2717. "status" : "vdev_id",
  2718. buf->status);
  2719. qdf_dpt_dump_hex_trace_debugfs(file, prepend_str,
  2720. (uint8_t *)&buf->cookie,
  2721. sizeof(buf->cookie));
  2722. }
  2723. /**
  2724. * qdf_dpt_display_ptr_record_debugfs() - display record
  2725. * @file: file to read
  2726. * @record: dptrace record
  2727. * @index: index
  2728. *
  2729. * Return: none
  2730. */
  2731. static void qdf_dpt_display_record_debugfs(qdf_debugfs_file_t file,
  2732. struct qdf_dp_trace_record_s *record,
  2733. uint32_t index)
  2734. {
  2735. int loc;
  2736. char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
  2737. struct qdf_dp_trace_data_buf *buf =
  2738. (struct qdf_dp_trace_data_buf *)record->data;
  2739. loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
  2740. index, 0, record);
  2741. if (loc < sizeof(prepend_str))
  2742. loc += snprintf(&prepend_str[loc], sizeof(prepend_str) - loc,
  2743. "[%d]", buf->msdu_id);
  2744. qdf_dpt_dump_hex_trace_debugfs(file, prepend_str,
  2745. record->data, record->size);
  2746. }
  2747. uint32_t qdf_dpt_get_curr_pos_debugfs(qdf_debugfs_file_t file,
  2748. enum qdf_dpt_debugfs_state state)
  2749. {
  2750. uint32_t i = 0;
  2751. uint32_t tail;
  2752. uint32_t count = g_qdf_dp_trace_data.num;
  2753. if (!g_qdf_dp_trace_data.enable) {
  2754. QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG,
  2755. "%s: Tracing Disabled", __func__);
  2756. return QDF_STATUS_E_EMPTY;
  2757. }
  2758. if (!count) {
  2759. QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG,
  2760. "%s: no packets", __func__);
  2761. return QDF_STATUS_E_EMPTY;
  2762. }
  2763. if (state == QDF_DPT_DEBUGFS_STATE_SHOW_IN_PROGRESS)
  2764. return g_qdf_dp_trace_data.curr_pos;
  2765. qdf_debugfs_printf(file,
  2766. "DPT: config - bitmap 0x%x verb %u #rec %u rec_requested %u live_config %u thresh %u time_limit %u\n",
  2767. g_qdf_dp_trace_data.proto_bitmap,
  2768. g_qdf_dp_trace_data.verbosity,
  2769. g_qdf_dp_trace_data.no_of_record,
  2770. g_qdf_dp_trace_data.num_records_to_dump,
  2771. g_qdf_dp_trace_data.live_mode_config,
  2772. g_qdf_dp_trace_data.high_tput_thresh,
  2773. g_qdf_dp_trace_data.thresh_time_limit);
  2774. qdf_debugfs_printf(file,
  2775. "STATS |DPT: icmp(%u %u) arp(%u %u) icmpv6(%u %u %u %u %u %u) dhcp(%u %u %u %u %u %u) eapol(%u %u %u %u %u)\n",
  2776. g_qdf_dp_trace_data.icmp_req,
  2777. g_qdf_dp_trace_data.icmp_resp,
  2778. g_qdf_dp_trace_data.arp_req,
  2779. g_qdf_dp_trace_data.arp_resp,
  2780. g_qdf_dp_trace_data.icmpv6_req,
  2781. g_qdf_dp_trace_data.icmpv6_resp,
  2782. g_qdf_dp_trace_data.icmpv6_ns,
  2783. g_qdf_dp_trace_data.icmpv6_na,
  2784. g_qdf_dp_trace_data.icmpv6_rs,
  2785. g_qdf_dp_trace_data.icmpv6_ra,
  2786. g_qdf_dp_trace_data.dhcp_disc,
  2787. g_qdf_dp_trace_data.dhcp_off,
  2788. g_qdf_dp_trace_data.dhcp_req,
  2789. g_qdf_dp_trace_data.dhcp_ack,
  2790. g_qdf_dp_trace_data.dhcp_nack,
  2791. g_qdf_dp_trace_data.dhcp_others,
  2792. g_qdf_dp_trace_data.eapol_m1,
  2793. g_qdf_dp_trace_data.eapol_m2,
  2794. g_qdf_dp_trace_data.eapol_m3,
  2795. g_qdf_dp_trace_data.eapol_m4,
  2796. g_qdf_dp_trace_data.eapol_others);
  2797. qdf_debugfs_printf(file,
  2798. "DPT: Total Records: %d, Head: %d, Tail: %d\n",
  2799. g_qdf_dp_trace_data.num, g_qdf_dp_trace_data.head,
  2800. g_qdf_dp_trace_data.tail);
  2801. spin_lock_bh(&l_dp_trace_lock);
  2802. if (g_qdf_dp_trace_data.head != INVALID_QDF_DP_TRACE_ADDR) {
  2803. i = g_qdf_dp_trace_data.head;
  2804. tail = g_qdf_dp_trace_data.tail;
  2805. if (count > g_qdf_dp_trace_data.num)
  2806. count = g_qdf_dp_trace_data.num;
  2807. if (tail >= (count - 1))
  2808. i = tail - count + 1;
  2809. else if (count != MAX_QDF_DP_TRACE_RECORDS)
  2810. i = MAX_QDF_DP_TRACE_RECORDS - ((count - 1) -
  2811. tail);
  2812. g_qdf_dp_trace_data.curr_pos = 0;
  2813. g_qdf_dp_trace_data.saved_tail = tail;
  2814. }
  2815. spin_unlock_bh(&l_dp_trace_lock);
  2816. return g_qdf_dp_trace_data.saved_tail;
  2817. }
  2818. qdf_export_symbol(qdf_dpt_get_curr_pos_debugfs);
  2819. QDF_STATUS qdf_dpt_dump_stats_debugfs(qdf_debugfs_file_t file,
  2820. uint32_t curr_pos)
  2821. {
  2822. struct qdf_dp_trace_record_s p_record;
  2823. uint32_t i = curr_pos;
  2824. uint16_t num_records_to_dump = g_qdf_dp_trace_data.num_records_to_dump;
  2825. if (!g_qdf_dp_trace_data.enable) {
  2826. QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
  2827. "%s: Tracing Disabled", __func__);
  2828. return QDF_STATUS_E_FAILURE;
  2829. }
  2830. if (num_records_to_dump > g_qdf_dp_trace_data.num)
  2831. num_records_to_dump = g_qdf_dp_trace_data.num;
  2832. /*
  2833. * Max dp trace record size should always be less than
  2834. * QDF_DP_TRACE_PREPEND_STR_SIZE(100) + BUFFER_SIZE(121).
  2835. */
  2836. if (WARN_ON(QDF_DP_TRACE_MAX_RECORD_SIZE <
  2837. QDF_DP_TRACE_PREPEND_STR_SIZE + BUFFER_SIZE))
  2838. return QDF_STATUS_E_FAILURE;
  2839. spin_lock_bh(&l_dp_trace_lock);
  2840. p_record = g_qdf_dp_trace_tbl[i];
  2841. spin_unlock_bh(&l_dp_trace_lock);
  2842. for (;; ) {
  2843. /*
  2844. * Initially we get file as 1 page size, and
  2845. * if remaining size in file is less than one record max size,
  2846. * then return so that it gets an extra page.
  2847. */
  2848. if ((file->size - file->count) < QDF_DP_TRACE_MAX_RECORD_SIZE) {
  2849. spin_lock_bh(&l_dp_trace_lock);
  2850. g_qdf_dp_trace_data.curr_pos = i;
  2851. spin_unlock_bh(&l_dp_trace_lock);
  2852. return QDF_STATUS_E_FAILURE;
  2853. }
  2854. switch (p_record.code) {
  2855. case QDF_DP_TRACE_TXRX_PACKET_PTR_RECORD:
  2856. case QDF_DP_TRACE_TXRX_FAST_PACKET_PTR_RECORD:
  2857. case QDF_DP_TRACE_FREE_PACKET_PTR_RECORD:
  2858. qdf_dpt_display_ptr_record_debugfs(file, &p_record, i);
  2859. break;
  2860. case QDF_DP_TRACE_EAPOL_PACKET_RECORD:
  2861. case QDF_DP_TRACE_DHCP_PACKET_RECORD:
  2862. case QDF_DP_TRACE_ARP_PACKET_RECORD:
  2863. case QDF_DP_TRACE_ICMP_PACKET_RECORD:
  2864. case QDF_DP_TRACE_ICMPv6_PACKET_RECORD:
  2865. qdf_dpt_display_proto_pkt_debugfs(file, &p_record, i);
  2866. break;
  2867. case QDF_DP_TRACE_TX_CREDIT_RECORD:
  2868. qdf_dpt_display_credit_record_debugfs(file, &p_record,
  2869. i);
  2870. break;
  2871. case QDF_DP_TRACE_MGMT_PACKET_RECORD:
  2872. qdf_dpt_display_mgmt_pkt_debugfs(file, &p_record, i);
  2873. break;
  2874. case QDF_DP_TRACE_EVENT_RECORD:
  2875. qdf_dpt_display_event_record_debugfs(file, &p_record,
  2876. i);
  2877. break;
  2878. case QDF_DP_TRACE_HDD_TX_TIMEOUT:
  2879. qdf_debugfs_printf(
  2880. file, "DPT: %04d: %llu %s\n",
  2881. i, p_record.time,
  2882. qdf_dp_code_to_string(p_record.code));
  2883. qdf_debugfs_printf(file, "HDD TX Timeout\n");
  2884. break;
  2885. case QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT:
  2886. qdf_debugfs_printf(
  2887. file, "DPT: %04d: %llu %s\n",
  2888. i, p_record.time,
  2889. qdf_dp_code_to_string(p_record.code));
  2890. qdf_debugfs_printf(file, "HDD SoftAP TX Timeout\n");
  2891. break;
  2892. case QDF_DP_TRACE_CE_FAST_PACKET_ERR_RECORD:
  2893. qdf_debugfs_printf(
  2894. file, "DPT: %04d: %llu %s\n",
  2895. i, p_record.time,
  2896. qdf_dp_code_to_string(p_record.code));
  2897. qdf_debugfs_printf(file, "CE Fast Packet Error\n");
  2898. break;
  2899. case QDF_DP_TRACE_MAX:
  2900. qdf_debugfs_printf(file,
  2901. "%s: QDF_DP_TRACE_MAX event should not be generated\n",
  2902. __func__);
  2903. break;
  2904. case QDF_DP_TRACE_HDD_TX_PACKET_RECORD:
  2905. case QDF_DP_TRACE_HDD_RX_PACKET_RECORD:
  2906. case QDF_DP_TRACE_TX_PACKET_RECORD:
  2907. case QDF_DP_TRACE_RX_PACKET_RECORD:
  2908. case QDF_DP_TRACE_LI_DP_TX_PACKET_RECORD:
  2909. case QDF_DP_TRACE_LI_DP_RX_PACKET_RECORD:
  2910. default:
  2911. qdf_dpt_display_record_debugfs(file, &p_record, i);
  2912. break;
  2913. }
  2914. if (++g_qdf_dp_trace_data.dump_counter == num_records_to_dump)
  2915. break;
  2916. spin_lock_bh(&l_dp_trace_lock);
  2917. if (i == 0)
  2918. i = MAX_QDF_DP_TRACE_RECORDS;
  2919. i -= 1;
  2920. p_record = g_qdf_dp_trace_tbl[i];
  2921. spin_unlock_bh(&l_dp_trace_lock);
  2922. }
  2923. g_qdf_dp_trace_data.dump_counter = 0;
  2924. return QDF_STATUS_SUCCESS;
  2925. }
  2926. qdf_export_symbol(qdf_dpt_dump_stats_debugfs);
  2927. /**
  2928. * qdf_dpt_set_value_debugfs() - Configure the value to control DP trace
  2929. * @proto_bitmap: defines the protocol to be tracked
  2930. * @no_of_records: defines the nth packet which is traced
  2931. * @verbosity: defines the verbosity level
  2932. *
  2933. * Return: None
  2934. */
  2935. void qdf_dpt_set_value_debugfs(uint8_t proto_bitmap, uint8_t no_of_record,
  2936. uint8_t verbosity, uint16_t num_records_to_dump)
  2937. {
  2938. if (g_qdf_dp_trace_data.enable) {
  2939. g_qdf_dp_trace_data.proto_bitmap = proto_bitmap;
  2940. g_qdf_dp_trace_data.no_of_record = no_of_record;
  2941. g_qdf_dp_trace_data.verbosity = verbosity;
  2942. g_qdf_dp_trace_data.num_records_to_dump = num_records_to_dump;
  2943. }
  2944. }
  2945. qdf_export_symbol(qdf_dpt_set_value_debugfs);
  2946. /**
  2947. * qdf_dp_trace_dump_all() - Dump data from ring buffer via call back functions
  2948. * registered with QDF
  2949. * @count: Number of lines to dump starting from tail to head
  2950. * @pdev_id: pdev_id
  2951. *
  2952. * Return: None
  2953. */
  2954. void qdf_dp_trace_dump_all(uint32_t count, uint8_t pdev_id)
  2955. {
  2956. struct qdf_dp_trace_record_s p_record;
  2957. int32_t i, tail;
  2958. if (!g_qdf_dp_trace_data.enable) {
  2959. DPTRACE_PRINT("Tracing Disabled");
  2960. return;
  2961. }
  2962. DPTRACE_PRINT(
  2963. "DPT: config - bitmap 0x%x verb %u #rec %u live_config %u thresh %u time_limit %u",
  2964. g_qdf_dp_trace_data.proto_bitmap,
  2965. g_qdf_dp_trace_data.verbosity,
  2966. g_qdf_dp_trace_data.no_of_record,
  2967. g_qdf_dp_trace_data.live_mode_config,
  2968. g_qdf_dp_trace_data.high_tput_thresh,
  2969. g_qdf_dp_trace_data.thresh_time_limit);
  2970. qdf_dp_trace_dump_stats();
  2971. DPTRACE_PRINT("DPT: Total Records: %d, Head: %d, Tail: %d",
  2972. g_qdf_dp_trace_data.num, g_qdf_dp_trace_data.head,
  2973. g_qdf_dp_trace_data.tail);
  2974. /* aquire the lock so that only one thread at a time can read
  2975. * the ring buffer
  2976. */
  2977. spin_lock_bh(&l_dp_trace_lock);
  2978. if (g_qdf_dp_trace_data.head != INVALID_QDF_DP_TRACE_ADDR) {
  2979. i = g_qdf_dp_trace_data.head;
  2980. tail = g_qdf_dp_trace_data.tail;
  2981. if (count) {
  2982. if (count > g_qdf_dp_trace_data.num)
  2983. count = g_qdf_dp_trace_data.num;
  2984. if (tail >= (count - 1))
  2985. i = tail - count + 1;
  2986. else if (count != MAX_QDF_DP_TRACE_RECORDS)
  2987. i = MAX_QDF_DP_TRACE_RECORDS - ((count - 1) -
  2988. tail);
  2989. }
  2990. p_record = g_qdf_dp_trace_tbl[i];
  2991. spin_unlock_bh(&l_dp_trace_lock);
  2992. for (;; ) {
  2993. qdf_dp_trace_cb_table[p_record.code](&p_record,
  2994. (uint16_t)i, pdev_id, false);
  2995. if (i == tail)
  2996. break;
  2997. i += 1;
  2998. spin_lock_bh(&l_dp_trace_lock);
  2999. if (MAX_QDF_DP_TRACE_RECORDS == i)
  3000. i = 0;
  3001. p_record = g_qdf_dp_trace_tbl[i];
  3002. spin_unlock_bh(&l_dp_trace_lock);
  3003. }
  3004. } else {
  3005. spin_unlock_bh(&l_dp_trace_lock);
  3006. }
  3007. }
  3008. qdf_export_symbol(qdf_dp_trace_dump_all);
  3009. /**
  3010. * qdf_dp_trace_throttle_live_mode() - Throttle DP Trace live mode
  3011. * @high_bw_request: whether this is a high BW req or not
  3012. *
  3013. * The function tries to prevent excessive logging into the live buffer by
  3014. * having an upper limit on number of packets that can be logged per second.
  3015. *
  3016. * The intention is to allow occasional pings and data packets and really low
  3017. * throughput levels while suppressing bursts and higher throughput levels so
  3018. * that we donot hog the live buffer.
  3019. *
  3020. * If the number of packets printed in a particular second exceeds the thresh,
  3021. * disable printing in the next second.
  3022. *
  3023. * Return: None
  3024. */
  3025. void qdf_dp_trace_throttle_live_mode(bool high_bw_request)
  3026. {
  3027. static int bw_interval_counter;
  3028. if (g_qdf_dp_trace_data.enable == false ||
  3029. g_qdf_dp_trace_data.live_mode_config == false)
  3030. return;
  3031. if (high_bw_request) {
  3032. g_qdf_dp_trace_data.live_mode = 0;
  3033. bw_interval_counter = 0;
  3034. return;
  3035. }
  3036. bw_interval_counter++;
  3037. if (0 == (bw_interval_counter %
  3038. g_qdf_dp_trace_data.thresh_time_limit)) {
  3039. spin_lock_bh(&l_dp_trace_lock);
  3040. if (g_qdf_dp_trace_data.print_pkt_cnt <=
  3041. g_qdf_dp_trace_data.high_tput_thresh)
  3042. g_qdf_dp_trace_data.live_mode = 1;
  3043. g_qdf_dp_trace_data.print_pkt_cnt = 0;
  3044. spin_unlock_bh(&l_dp_trace_lock);
  3045. }
  3046. }
  3047. qdf_export_symbol(qdf_dp_trace_throttle_live_mode);
  3048. void qdf_dp_trace_apply_tput_policy(bool is_data_traffic)
  3049. {
  3050. if (g_qdf_dp_trace_data.dynamic_verbosity_modify) {
  3051. goto check_live_mode;
  3052. return;
  3053. }
  3054. if (is_data_traffic) {
  3055. g_qdf_dp_trace_data.verbosity =
  3056. QDF_DP_TRACE_VERBOSITY_ULTRA_LOW;
  3057. } else {
  3058. g_qdf_dp_trace_data.verbosity =
  3059. g_qdf_dp_trace_data.ini_conf_verbosity;
  3060. }
  3061. check_live_mode:
  3062. qdf_dp_trace_throttle_live_mode(is_data_traffic);
  3063. }
  3064. #endif
  3065. struct qdf_print_ctrl print_ctrl_obj[MAX_PRINT_CONFIG_SUPPORTED];
  3066. struct category_name_info g_qdf_category_name[MAX_SUPPORTED_CATEGORY] = {
  3067. [QDF_MODULE_ID_TDLS] = {"tdls"},
  3068. [QDF_MODULE_ID_ACS] = {"ACS"},
  3069. [QDF_MODULE_ID_SCAN_SM] = {"scan state machine"},
  3070. [QDF_MODULE_ID_SCANENTRY] = {"scan entry"},
  3071. [QDF_MODULE_ID_WDS] = {"WDS"},
  3072. [QDF_MODULE_ID_ACTION] = {"action"},
  3073. [QDF_MODULE_ID_ROAM] = {"STA roaming"},
  3074. [QDF_MODULE_ID_INACT] = {"inactivity"},
  3075. [QDF_MODULE_ID_DOTH] = {"11h"},
  3076. [QDF_MODULE_ID_IQUE] = {"IQUE"},
  3077. [QDF_MODULE_ID_WME] = {"WME"},
  3078. [QDF_MODULE_ID_ACL] = {"ACL"},
  3079. [QDF_MODULE_ID_WPA] = {"WPA/RSN"},
  3080. [QDF_MODULE_ID_RADKEYS] = {"dump 802.1x keys"},
  3081. [QDF_MODULE_ID_RADDUMP] = {"dump radius packet"},
  3082. [QDF_MODULE_ID_RADIUS] = {"802.1x radius client"},
  3083. [QDF_MODULE_ID_DOT1XSM] = {"802.1x state machine"},
  3084. [QDF_MODULE_ID_DOT1X] = {"802.1x authenticator"},
  3085. [QDF_MODULE_ID_POWER] = {"power save"},
  3086. [QDF_MODULE_ID_STATE] = {"state"},
  3087. [QDF_MODULE_ID_OUTPUT] = {"output"},
  3088. [QDF_MODULE_ID_SCAN] = {"scan"},
  3089. [QDF_MODULE_ID_AUTH] = {"authentication"},
  3090. [QDF_MODULE_ID_ASSOC] = {"association"},
  3091. [QDF_MODULE_ID_NODE] = {"node"},
  3092. [QDF_MODULE_ID_ELEMID] = {"element ID"},
  3093. [QDF_MODULE_ID_XRATE] = {"rate"},
  3094. [QDF_MODULE_ID_INPUT] = {"input"},
  3095. [QDF_MODULE_ID_CRYPTO] = {"crypto"},
  3096. [QDF_MODULE_ID_DUMPPKTS] = {"dump packet"},
  3097. [QDF_MODULE_ID_DEBUG] = {"debug"},
  3098. [QDF_MODULE_ID_MLME] = {"mlme"},
  3099. [QDF_MODULE_ID_RRM] = {"rrm"},
  3100. [QDF_MODULE_ID_WNM] = {"wnm"},
  3101. [QDF_MODULE_ID_P2P_PROT] = {"p2p_prot"},
  3102. [QDF_MODULE_ID_PROXYARP] = {"proxyarp"},
  3103. [QDF_MODULE_ID_L2TIF] = {"l2tif"},
  3104. [QDF_MODULE_ID_WIFIPOS] = {"wifipos"},
  3105. [QDF_MODULE_ID_WRAP] = {"wrap"},
  3106. [QDF_MODULE_ID_DFS] = {"dfs"},
  3107. [QDF_MODULE_ID_ATF] = {"atf"},
  3108. [QDF_MODULE_ID_SPLITMAC] = {"splitmac"},
  3109. [QDF_MODULE_ID_IOCTL] = {"ioctl"},
  3110. [QDF_MODULE_ID_NAC] = {"nac"},
  3111. [QDF_MODULE_ID_MESH] = {"mesh"},
  3112. [QDF_MODULE_ID_MBO] = {"mbo"},
  3113. [QDF_MODULE_ID_EXTIOCTL_CHANSWITCH] = {"extchanswitch"},
  3114. [QDF_MODULE_ID_EXTIOCTL_CHANSSCAN] = {"extchanscan"},
  3115. [QDF_MODULE_ID_TLSHIM] = {"tlshim"},
  3116. [QDF_MODULE_ID_WMI] = {"WMI"},
  3117. [QDF_MODULE_ID_HTT] = {"HTT"},
  3118. [QDF_MODULE_ID_HDD] = {"HDD"},
  3119. [QDF_MODULE_ID_SME] = {"SME"},
  3120. [QDF_MODULE_ID_PE] = {"PE"},
  3121. [QDF_MODULE_ID_WMA] = {"WMA"},
  3122. [QDF_MODULE_ID_SYS] = {"SYS"},
  3123. [QDF_MODULE_ID_QDF] = {"QDF"},
  3124. [QDF_MODULE_ID_SAP] = {"SAP"},
  3125. [QDF_MODULE_ID_HDD_SOFTAP] = {"HDD_SAP"},
  3126. [QDF_MODULE_ID_HDD_DATA] = {"DATA"},
  3127. [QDF_MODULE_ID_HDD_SAP_DATA] = {"SAP_DATA"},
  3128. [QDF_MODULE_ID_HIF] = {"HIF"},
  3129. [QDF_MODULE_ID_HTC] = {"HTC"},
  3130. [QDF_MODULE_ID_TXRX] = {"TXRX"},
  3131. [QDF_MODULE_ID_QDF_DEVICE] = {"QDF_DEV"},
  3132. [QDF_MODULE_ID_CFG] = {"CFG"},
  3133. [QDF_MODULE_ID_BMI] = {"BMI"},
  3134. [QDF_MODULE_ID_EPPING] = {"EPPING"},
  3135. [QDF_MODULE_ID_QVIT] = {"QVIT"},
  3136. [QDF_MODULE_ID_DP] = {"DP"},
  3137. [QDF_MODULE_ID_HAL] = {"HAL"},
  3138. [QDF_MODULE_ID_SOC] = {"SOC"},
  3139. [QDF_MODULE_ID_OS_IF] = {"OSIF"},
  3140. [QDF_MODULE_ID_TARGET_IF] = {"TIF"},
  3141. [QDF_MODULE_ID_SCHEDULER] = {"SCH"},
  3142. [QDF_MODULE_ID_MGMT_TXRX] = {"MGMT_TXRX"},
  3143. [QDF_MODULE_ID_PMO] = {"PMO"},
  3144. [QDF_MODULE_ID_POLICY_MGR] = {"POLICY_MGR"},
  3145. [QDF_MODULE_ID_SA_API] = {"SA_API"},
  3146. [QDF_MODULE_ID_NAN] = {"NAN"},
  3147. [QDF_MODULE_ID_SPECTRAL] = {"SPECTRAL"},
  3148. [QDF_MODULE_ID_P2P] = {"P2P"},
  3149. [QDF_MODULE_ID_OFFCHAN_TXRX] = {"OFFCHAN"},
  3150. [QDF_MODULE_ID_REGULATORY] = {"REGULATORY"},
  3151. [QDF_MODULE_ID_OBJ_MGR] = {"OBJMGR"},
  3152. [QDF_MODULE_ID_SERIALIZATION] = {"SER"},
  3153. [QDF_MODULE_ID_NSS] = {"NSS"},
  3154. [QDF_MODULE_ID_ROAM_DEBUG] = {"roam debug"},
  3155. [QDF_MODULE_ID_DIRECT_BUF_RX] = {"DIRECT_BUF_RX"},
  3156. [QDF_MODULE_ID_DISA] = {"disa"},
  3157. [QDF_MODULE_ID_GREEN_AP] = {"GREEN_AP"},
  3158. [QDF_MODULE_ID_FD] = {"FILS discovery"},
  3159. [QDF_MODULE_ID_FTM] = {"FTM"},
  3160. [QDF_MODULE_ID_OCB] = {"OCB"},
  3161. [QDF_MODULE_ID_CONFIG] = {"CONFIG"},
  3162. [QDF_MODULE_ID_IPA] = {"IPA"},
  3163. [QDF_MODULE_ID_CP_STATS] = {"CP_STATS"},
  3164. [QDF_MODULE_ID_DCS] = {"DCS"},
  3165. [QDF_MODULE_ID_ACTION_OUI] = {"action_oui"},
  3166. [QDF_MODULE_ID_TARGET] = {"TARGET"},
  3167. [QDF_MODULE_ID_MBSSIE] = {"MBSSIE"},
  3168. [QDF_MODULE_ID_FWOL] = {"fwol"},
  3169. [QDF_MODULE_ID_SM_ENGINE] = {"SM_ENG"},
  3170. [QDF_MODULE_ID_CMN_MLME] = {"CMN_MLME"},
  3171. [QDF_MODULE_ID_BSSCOLOR] = {"BSSCOLOR"},
  3172. [QDF_MODULE_ID_CFR] = {"CFR"},
  3173. [QDF_MODULE_ID_DP_TX_CAPTURE] = {"TX_CAPTURE_ENHANCE"},
  3174. [QDF_MODULE_ID_INTEROP_ISSUES_AP] = {"INTEROP_ISSUES_AP"},
  3175. [QDF_MODULE_ID_DENYLIST_MGR] = {"dlm"},
  3176. [QDF_MODULE_ID_QLD] = {"QLD"},
  3177. [QDF_MODULE_ID_DYNAMIC_MODE_CHG] = {"Dynamic Mode Change"},
  3178. [QDF_MODULE_ID_COEX] = {"COEX"},
  3179. [QDF_MODULE_ID_MON_FILTER] = {"Monitor Filter"},
  3180. [QDF_MODULE_ID_PKT_CAPTURE] = {"pkt_capture"},
  3181. [QDF_MODULE_ID_RPTR] = {"RPTR"},
  3182. [QDF_MODULE_ID_6GHZ] = {"6GHZ"},
  3183. [QDF_MODULE_ID_IOT_SIM] = {"IOT_SIM"},
  3184. [QDF_MODULE_ID_MSCS] = {"MSCS"},
  3185. [QDF_MODULE_ID_GPIO] = {"GPIO_CFG"},
  3186. [QDF_MODULE_ID_IFMGR] = {"IF_MGR"},
  3187. [QDF_MODULE_ID_DIAG] = {"DIAG"},
  3188. [QDF_MODULE_ID_DP_INIT] = {"DP_INIT"},
  3189. [QDF_MODULE_ID_DP_TX] = {"DP_TX"},
  3190. [QDF_MODULE_ID_DP_RX] = {"DP_RX"},
  3191. [QDF_MODULE_ID_DP_STATS] = {"DP_STATS"},
  3192. [QDF_MODULE_ID_DP_HTT] = {"DP_HTT"},
  3193. [QDF_MODULE_ID_DP_PEER] = {"DP_PEER"},
  3194. [QDF_MODULE_ID_DP_RX_ERROR] = {"DP_RX_ERROR"},
  3195. [QDF_MODULE_ID_DP_HTT_TX_STATS] = {"DP_HTT_TX_STATS"},
  3196. [QDF_MODULE_ID_DP_RX_MON_STATUS] = {"DP_RX_MON_STATUS"},
  3197. [QDF_MODULE_ID_DP_RX_MON_DEST] = {"DP_RX_MON_DEST"},
  3198. [QDF_MODULE_ID_DP_REO] = {"DP_REO"},
  3199. [QDF_MODULE_ID_DP_TX_COMP] = {"DP_TX_COMP"},
  3200. [QDF_MODULE_ID_DP_VDEV] = {"DP_VDEV"},
  3201. [QDF_MODULE_ID_DP_CDP] = {"DP_CDP"},
  3202. [QDF_MODULE_ID_TSO] = {"TSO"},
  3203. [QDF_MODULE_ID_ME] = {"ME"},
  3204. [QDF_MODULE_ID_QWRAP] = {"QWRAP"},
  3205. [QDF_MODULE_ID_DBDC_REP] = {"DBDC_REP"},
  3206. [QDF_MODULE_ID_EXT_AP] = {"EXT_AP"},
  3207. [QDF_MODULE_ID_MLO] = {"MLO_MGR"},
  3208. [QDF_MODULE_ID_MGMT_RX_REO] = {"MGMT_RX_REO"},
  3209. [QDF_MODULE_ID_MLOIE] = {"MLOIE"},
  3210. [QDF_MODULE_ID_MBSS] = {"MBSS"},
  3211. [QDF_MODULE_ID_MON] = {"MONITOR"},
  3212. [QDF_MODULE_ID_AFC] = {"AFC"},
  3213. [QDF_MODULE_ID_TWT] = {"TWT"},
  3214. [QDF_MODULE_ID_SON] = {"SON"},
  3215. [QDF_MODULE_ID_WLAN_PRE_CAC] = {"PRE_CAC"},
  3216. [QDF_MODULE_ID_T2LM] = {"T2LM"},
  3217. [QDF_MODULE_ID_DP_SAWF] = {"DP_SAWF"},
  3218. [QDF_MODULE_ID_SCS] = {"SCS"},
  3219. [QDF_MODULE_ID_DP_UMAC_RESET] = {"UMAC_HW_RESET"},
  3220. [QDF_MODULE_ID_COAP] = {"COAP"},
  3221. [QDF_MODULE_ID_ANY] = {"ANY"},
  3222. };
  3223. qdf_export_symbol(g_qdf_category_name);
  3224. /**
  3225. * qdf_trace_display() - Display trace
  3226. *
  3227. * Return: None
  3228. */
  3229. void qdf_trace_display(void)
  3230. {
  3231. QDF_MODULE_ID module_id;
  3232. pr_err(" 1)FATAL 2)ERROR 3)WARN 4)INFO 5)INFO_H 6)INFO_M 7)INFO_L 8)DEBUG\n");
  3233. for (module_id = 0; module_id < QDF_MODULE_ID_MAX; ++module_id) {
  3234. pr_err("%2d)%s %s %s %s %s %s %s %s %s\n",
  3235. (int)module_id,
  3236. g_qdf_category_name[module_id].category_name_str,
  3237. qdf_print_is_verbose_enabled(qdf_pidx, module_id,
  3238. QDF_TRACE_LEVEL_FATAL) ? "X" : " ",
  3239. qdf_print_is_verbose_enabled(qdf_pidx, module_id,
  3240. QDF_TRACE_LEVEL_ERROR) ? "X" : " ",
  3241. qdf_print_is_verbose_enabled(qdf_pidx, module_id,
  3242. QDF_TRACE_LEVEL_WARN) ? "X" : " ",
  3243. qdf_print_is_verbose_enabled(qdf_pidx, module_id,
  3244. QDF_TRACE_LEVEL_INFO) ? "X" : " ",
  3245. qdf_print_is_verbose_enabled(qdf_pidx, module_id,
  3246. QDF_TRACE_LEVEL_INFO_HIGH) ? "X" : " ",
  3247. qdf_print_is_verbose_enabled(qdf_pidx, module_id,
  3248. QDF_TRACE_LEVEL_INFO_MED) ? "X" : " ",
  3249. qdf_print_is_verbose_enabled(qdf_pidx, module_id,
  3250. QDF_TRACE_LEVEL_INFO_LOW) ? "X" : " ",
  3251. qdf_print_is_verbose_enabled(qdf_pidx, module_id,
  3252. QDF_TRACE_LEVEL_DEBUG) ? "X" : " ");
  3253. }
  3254. }
  3255. qdf_export_symbol(qdf_trace_display);
  3256. #ifdef WLAN_MAX_LOGS_PER_SEC
  3257. static qdf_time_t __log_window_end;
  3258. static qdf_atomic_t __log_window_count;
  3259. uint32_t qdf_rl_print_count = WLAN_MAX_LOGS_PER_SEC;
  3260. uint32_t qdf_rl_print_time = 1;
  3261. uint32_t qdf_rl_print_supressed;
  3262. /**
  3263. * qdf_detected_excessive_logging() - Excessive logging detected
  3264. *
  3265. * Track logging count using a quasi-tumbling window.
  3266. * If the max logging count for a given window is exceeded,
  3267. * return true else fails.
  3268. *
  3269. * Return: true/false
  3270. */
  3271. bool qdf_detected_excessive_logging(void)
  3272. {
  3273. qdf_time_t now = qdf_system_ticks();
  3274. bool excessive_prints = false;
  3275. /*
  3276. * If 'now' is more recent than the end of the window, reset.
  3277. *
  3278. * Note: This is not thread safe, and can result in more than one reset.
  3279. * For our purposes, this is fine.
  3280. */
  3281. if (!qdf_atomic_read(&__log_window_count)) {
  3282. __log_window_end = now + (qdf_system_ticks_per_sec * qdf_rl_print_time);
  3283. } else if (qdf_system_time_after(now, __log_window_end)) {
  3284. __log_window_end = now + (qdf_system_ticks_per_sec * qdf_rl_print_time);
  3285. qdf_atomic_set(&__log_window_count, 0);
  3286. }
  3287. if (qdf_atomic_inc_return(&__log_window_count) > qdf_rl_print_count)
  3288. excessive_prints = true;
  3289. return excessive_prints;
  3290. }
  3291. void qdf_rl_print_count_set(uint32_t rl_print_count)
  3292. {
  3293. qdf_rl_print_count = rl_print_count;
  3294. }
  3295. qdf_export_symbol(qdf_rl_print_count_set);
  3296. void qdf_rl_print_time_set(uint32_t rl_print_time)
  3297. {
  3298. qdf_rl_print_time = rl_print_time;
  3299. }
  3300. qdf_export_symbol(qdf_rl_print_time_set);
  3301. void qdf_rl_print_supressed_log(void)
  3302. {
  3303. if (qdf_rl_print_supressed) {
  3304. pr_err("QDF Ratelimiting: %d prints supressed",
  3305. qdf_rl_print_supressed);
  3306. qdf_rl_print_supressed = 0;
  3307. }
  3308. }
  3309. void qdf_rl_print_supressed_inc(void)
  3310. {
  3311. qdf_rl_print_supressed++;
  3312. }
  3313. #else
  3314. #define qdf_rl_print_supressed_log()
  3315. #define qdf_rl_print_supressed_inc()
  3316. #endif /* WLAN_MAX_LOGS_PER_SEC */
  3317. #ifdef QDF_TRACE_PRINT_ENABLE
  3318. static inline void print_to_console(char *str_buffer)
  3319. {
  3320. if (qdf_in_interrupt() && qdf_detected_excessive_logging()) {
  3321. qdf_rl_print_supressed_inc();
  3322. return;
  3323. }
  3324. qdf_rl_print_supressed_log();
  3325. pr_err("%s\n", str_buffer);
  3326. }
  3327. #else
  3328. #define print_to_console(str)
  3329. #endif
  3330. #ifdef MULTI_IF_NAME
  3331. static const char *qdf_trace_wlan_modname(void)
  3332. {
  3333. return MULTI_IF_NAME;
  3334. }
  3335. #else
  3336. static const char *qdf_trace_wlan_modname(void)
  3337. {
  3338. return "wlan";
  3339. }
  3340. #endif
  3341. void qdf_trace_msg_cmn(unsigned int idx,
  3342. QDF_MODULE_ID category,
  3343. QDF_TRACE_LEVEL verbose,
  3344. const char *str_format, va_list val)
  3345. {
  3346. char str_buffer[QDF_TRACE_BUFFER_SIZE];
  3347. int n;
  3348. /* Check if index passed is valid */
  3349. if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
  3350. pr_info("%s: Invalid index - %d\n", __func__, idx);
  3351. return;
  3352. }
  3353. /* Check if print control object is in use */
  3354. if (!print_ctrl_obj[idx].in_use) {
  3355. pr_info("%s: Invalid print control object\n", __func__);
  3356. return;
  3357. }
  3358. /* Check if category passed is valid */
  3359. if (category < 0 || category >= MAX_SUPPORTED_CATEGORY) {
  3360. vscnprintf(str_buffer, QDF_TRACE_BUFFER_SIZE, str_format, val);
  3361. pr_info("%s: Invalid category: %d, log: %s\n",
  3362. __func__, category, str_buffer);
  3363. return;
  3364. }
  3365. /* Check if verbose mask is valid */
  3366. if (verbose < 0 || verbose >= QDF_TRACE_LEVEL_MAX) {
  3367. vscnprintf(str_buffer, QDF_TRACE_BUFFER_SIZE, str_format, val);
  3368. pr_info("%s: Invalid verbose level %d, log: %s\n",
  3369. __func__, verbose, str_buffer);
  3370. return;
  3371. }
  3372. /*
  3373. * Print the trace message when the desired verbose level is set in
  3374. * the desired category for the print control object
  3375. */
  3376. if (print_ctrl_obj[idx].cat_info[category].category_verbose_mask &
  3377. QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose)) {
  3378. static const char * const VERBOSE_STR[] = {
  3379. [QDF_TRACE_LEVEL_NONE] = "",
  3380. [QDF_TRACE_LEVEL_FATAL] = "F",
  3381. [QDF_TRACE_LEVEL_ERROR] = "E",
  3382. [QDF_TRACE_LEVEL_WARN] = "W",
  3383. [QDF_TRACE_LEVEL_INFO] = "I",
  3384. [QDF_TRACE_LEVEL_INFO_HIGH] = "IH",
  3385. [QDF_TRACE_LEVEL_INFO_MED] = "IM",
  3386. [QDF_TRACE_LEVEL_INFO_LOW] = "IL",
  3387. [QDF_TRACE_LEVEL_DEBUG] = "D",
  3388. [QDF_TRACE_LEVEL_TRACE] = "T",
  3389. [QDF_TRACE_LEVEL_ALL] = "" };
  3390. /* print the prefix string into the string buffer... */
  3391. n = scnprintf(str_buffer, QDF_TRACE_BUFFER_SIZE,
  3392. "%s: [%d:%s:%s] ", qdf_trace_wlan_modname(),
  3393. in_interrupt() ? 0 : current->pid,
  3394. VERBOSE_STR[verbose],
  3395. g_qdf_category_name[category].category_name_str);
  3396. /* print the formatted log message after the prefix string */
  3397. vscnprintf(str_buffer + n, QDF_TRACE_BUFFER_SIZE - n,
  3398. str_format, val);
  3399. #if defined(WLAN_LOGGING_SOCK_SVC_ENABLE)
  3400. wlan_log_to_user(verbose, (char *)str_buffer,
  3401. strlen(str_buffer));
  3402. if (qdf_unlikely(qdf_log_dump_at_kernel_enable))
  3403. print_to_console(str_buffer);
  3404. #else
  3405. pr_err("%s\n", str_buffer);
  3406. #endif
  3407. }
  3408. }
  3409. qdf_export_symbol(qdf_trace_msg_cmn);
  3410. QDF_STATUS qdf_print_setup(void)
  3411. {
  3412. int i;
  3413. /* Loop through all print ctrl objects */
  3414. for (i = 0; i < MAX_PRINT_CONFIG_SUPPORTED; i++) {
  3415. if (qdf_print_ctrl_cleanup(i))
  3416. return QDF_STATUS_E_FAILURE;
  3417. }
  3418. return QDF_STATUS_SUCCESS;
  3419. }
  3420. qdf_export_symbol(qdf_print_setup);
  3421. QDF_STATUS qdf_print_ctrl_cleanup(unsigned int idx)
  3422. {
  3423. int i = 0;
  3424. if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
  3425. pr_info("%s: Invalid index - %d\n", __func__, idx);
  3426. return QDF_STATUS_E_FAILURE;
  3427. }
  3428. /* Clean up the print control object corresponding to that index
  3429. * If success, callee to change print control index to -1
  3430. */
  3431. for (i = 0; i < MAX_SUPPORTED_CATEGORY; i++) {
  3432. print_ctrl_obj[idx].cat_info[i].category_verbose_mask =
  3433. QDF_TRACE_LEVEL_NONE;
  3434. }
  3435. print_ctrl_obj[idx].custom_print = NULL;
  3436. print_ctrl_obj[idx].custom_ctxt = NULL;
  3437. qdf_print_clean_node_flag(idx);
  3438. print_ctrl_obj[idx].in_use = false;
  3439. return QDF_STATUS_SUCCESS;
  3440. }
  3441. qdf_export_symbol(qdf_print_ctrl_cleanup);
  3442. int qdf_print_ctrl_register(const struct category_info *cinfo,
  3443. void *custom_print_handler,
  3444. void *custom_ctx,
  3445. const char *pctrl_name)
  3446. {
  3447. int idx = -1;
  3448. int i = 0;
  3449. for (i = 0; i < MAX_PRINT_CONFIG_SUPPORTED; i++) {
  3450. if (!print_ctrl_obj[i].in_use) {
  3451. idx = i;
  3452. break;
  3453. }
  3454. }
  3455. /* Callee to handle idx -1 appropriately */
  3456. if (idx == -1) {
  3457. pr_info("%s: Allocation failed! No print control object free\n",
  3458. __func__);
  3459. return idx;
  3460. }
  3461. print_ctrl_obj[idx].in_use = true;
  3462. /*
  3463. * In case callee does not pass category info,
  3464. * custom print handler, custom context and print control name,
  3465. * we do not set any value here. Clean up for the print control
  3466. * getting allocated would have taken care of initializing
  3467. * default values.
  3468. *
  3469. * We need to only set in_use to 1 in such a case
  3470. */
  3471. if (pctrl_name) {
  3472. qdf_str_lcopy(print_ctrl_obj[idx].name, pctrl_name,
  3473. sizeof(print_ctrl_obj[idx].name));
  3474. }
  3475. if (custom_print_handler)
  3476. print_ctrl_obj[idx].custom_print = custom_print_handler;
  3477. if (custom_ctx)
  3478. print_ctrl_obj[idx].custom_ctxt = custom_ctx;
  3479. if (cinfo) {
  3480. for (i = 0; i < MAX_SUPPORTED_CATEGORY; i++) {
  3481. if (cinfo[i].category_verbose_mask ==
  3482. QDF_TRACE_LEVEL_ALL) {
  3483. print_ctrl_obj[idx].cat_info[i]
  3484. .category_verbose_mask = 0xFFFF;
  3485. } else if ((cinfo[i].category_verbose_mask ==
  3486. QDF_TRACE_LEVEL_NONE) ||
  3487. (cinfo[i].category_verbose_mask ==
  3488. QDF_TRACE_LEVEL_TO_MODULE_BITMASK(
  3489. QDF_TRACE_LEVEL_NONE))) {
  3490. print_ctrl_obj[idx].cat_info[i]
  3491. .category_verbose_mask = 0;
  3492. } else {
  3493. print_ctrl_obj[idx].cat_info[i]
  3494. .category_verbose_mask =
  3495. cinfo[i].category_verbose_mask;
  3496. }
  3497. }
  3498. }
  3499. return idx;
  3500. }
  3501. qdf_export_symbol(qdf_print_ctrl_register);
  3502. #ifdef QDF_TRACE_PRINT_ENABLE
  3503. void qdf_shared_print_ctrl_cleanup(void)
  3504. {
  3505. qdf_print_ctrl_cleanup(qdf_pidx);
  3506. }
  3507. qdf_export_symbol(qdf_shared_print_ctrl_cleanup);
  3508. /*
  3509. * Set this to invalid value to differentiate with user-provided
  3510. * value.
  3511. */
  3512. int qdf_dbg_mask = QDF_TRACE_LEVEL_MAX;
  3513. qdf_export_symbol(qdf_dbg_mask);
  3514. qdf_declare_param(qdf_dbg_mask, int);
  3515. /*
  3516. * QDF can be passed parameters which indicate the
  3517. * debug level for each module.
  3518. * an array of string values are passed, each string hold the following form
  3519. *
  3520. * <module name string>=<integer debug level value>
  3521. *
  3522. * The array qdf_dbg_arr will hold these module-string=value strings
  3523. * The variable qdf_dbg_arr_cnt will have the count of how many such
  3524. * string values were passed.
  3525. */
  3526. static char *qdf_dbg_arr[QDF_MODULE_ID_MAX];
  3527. static int qdf_dbg_arr_cnt;
  3528. qdf_declare_param_array(qdf_dbg_arr, charp, &qdf_dbg_arr_cnt);
  3529. static uint16_t set_cumulative_verbose_mask(QDF_TRACE_LEVEL max_level)
  3530. {
  3531. uint16_t category_verbose_mask = 0;
  3532. QDF_TRACE_LEVEL level;
  3533. for (level = QDF_TRACE_LEVEL_FATAL; level <= max_level; level++) {
  3534. category_verbose_mask |=
  3535. QDF_TRACE_LEVEL_TO_MODULE_BITMASK(level);
  3536. }
  3537. return category_verbose_mask;
  3538. }
  3539. static QDF_MODULE_ID find_qdf_module_from_string(char *str)
  3540. {
  3541. QDF_MODULE_ID mod_id;
  3542. for (mod_id = 0; mod_id < QDF_MODULE_ID_MAX; mod_id++) {
  3543. if (strcasecmp(str,
  3544. g_qdf_category_name[mod_id].category_name_str)
  3545. == 0) {
  3546. break;
  3547. }
  3548. }
  3549. return mod_id;
  3550. }
  3551. static void process_qdf_dbg_arr_param(struct category_info *cinfo,
  3552. int array_index)
  3553. {
  3554. char *mod_val_str, *mod_str, *val_str;
  3555. unsigned long dbg_level;
  3556. QDF_MODULE_ID mod_id;
  3557. mod_val_str = qdf_dbg_arr[array_index];
  3558. mod_str = strsep(&mod_val_str, "=");
  3559. val_str = mod_val_str;
  3560. if (!val_str) {
  3561. pr_info("qdf_dbg_arr: %s not in the <mod>=<val> form\n",
  3562. mod_str);
  3563. return;
  3564. }
  3565. mod_id = find_qdf_module_from_string(mod_str);
  3566. if (mod_id >= QDF_MODULE_ID_MAX) {
  3567. pr_info("ERROR!!Module name %s not in the list of modules\n",
  3568. mod_str);
  3569. return;
  3570. }
  3571. if (kstrtol(val_str, 10, &dbg_level) < 0) {
  3572. pr_info("ERROR!!Invalid debug level for module: %s\n",
  3573. mod_str);
  3574. return;
  3575. }
  3576. if (dbg_level >= QDF_TRACE_LEVEL_MAX) {
  3577. pr_info("ERROR!!Debug level for %s too high", mod_str);
  3578. pr_info("max: %d given %lu\n", QDF_TRACE_LEVEL_MAX,
  3579. dbg_level);
  3580. return;
  3581. }
  3582. pr_info("User passed setting module %s(%d) to level %lu\n",
  3583. mod_str,
  3584. mod_id,
  3585. dbg_level);
  3586. cinfo[mod_id].category_verbose_mask =
  3587. set_cumulative_verbose_mask((QDF_TRACE_LEVEL)dbg_level);
  3588. }
  3589. static void set_default_trace_levels(struct category_info *cinfo)
  3590. {
  3591. int i;
  3592. static QDF_TRACE_LEVEL module_trace_default_level[QDF_MODULE_ID_MAX] = {
  3593. [QDF_MODULE_ID_TDLS] = QDF_TRACE_LEVEL_NONE,
  3594. [QDF_MODULE_ID_ACS] = QDF_TRACE_LEVEL_NONE,
  3595. [QDF_MODULE_ID_SCAN_SM] = QDF_TRACE_LEVEL_NONE,
  3596. [QDF_MODULE_ID_SCANENTRY] = QDF_TRACE_LEVEL_NONE,
  3597. [QDF_MODULE_ID_WDS] = QDF_TRACE_LEVEL_NONE,
  3598. [QDF_MODULE_ID_ACTION] = QDF_TRACE_LEVEL_NONE,
  3599. [QDF_MODULE_ID_ROAM] = QDF_TRACE_LEVEL_NONE,
  3600. [QDF_MODULE_ID_INACT] = QDF_TRACE_LEVEL_NONE,
  3601. [QDF_MODULE_ID_DOTH] = QDF_TRACE_LEVEL_NONE,
  3602. [QDF_MODULE_ID_IQUE] = QDF_TRACE_LEVEL_NONE,
  3603. [QDF_MODULE_ID_WME] = QDF_TRACE_LEVEL_NONE,
  3604. [QDF_MODULE_ID_ACL] = QDF_TRACE_LEVEL_NONE,
  3605. [QDF_MODULE_ID_WPA] = QDF_TRACE_LEVEL_NONE,
  3606. [QDF_MODULE_ID_RADKEYS] = QDF_TRACE_LEVEL_NONE,
  3607. [QDF_MODULE_ID_RADDUMP] = QDF_TRACE_LEVEL_NONE,
  3608. [QDF_MODULE_ID_RADIUS] = QDF_TRACE_LEVEL_NONE,
  3609. [QDF_MODULE_ID_DOT1XSM] = QDF_TRACE_LEVEL_NONE,
  3610. [QDF_MODULE_ID_DOT1X] = QDF_TRACE_LEVEL_NONE,
  3611. [QDF_MODULE_ID_POWER] = QDF_TRACE_LEVEL_NONE,
  3612. [QDF_MODULE_ID_STATE] = QDF_TRACE_LEVEL_NONE,
  3613. [QDF_MODULE_ID_OUTPUT] = QDF_TRACE_LEVEL_NONE,
  3614. [QDF_MODULE_ID_SCAN] = QDF_TRACE_LEVEL_ERROR,
  3615. [QDF_MODULE_ID_AUTH] = QDF_TRACE_LEVEL_NONE,
  3616. [QDF_MODULE_ID_ASSOC] = QDF_TRACE_LEVEL_NONE,
  3617. [QDF_MODULE_ID_NODE] = QDF_TRACE_LEVEL_NONE,
  3618. [QDF_MODULE_ID_ELEMID] = QDF_TRACE_LEVEL_NONE,
  3619. [QDF_MODULE_ID_XRATE] = QDF_TRACE_LEVEL_NONE,
  3620. [QDF_MODULE_ID_INPUT] = QDF_TRACE_LEVEL_NONE,
  3621. [QDF_MODULE_ID_CRYPTO] = QDF_TRACE_LEVEL_NONE,
  3622. [QDF_MODULE_ID_DUMPPKTS] = QDF_TRACE_LEVEL_NONE,
  3623. [QDF_MODULE_ID_DEBUG] = QDF_TRACE_LEVEL_NONE,
  3624. [QDF_MODULE_ID_MLME] = QDF_TRACE_LEVEL_ERROR,
  3625. [QDF_MODULE_ID_RRM] = QDF_TRACE_LEVEL_NONE,
  3626. [QDF_MODULE_ID_WNM] = QDF_TRACE_LEVEL_NONE,
  3627. [QDF_MODULE_ID_P2P_PROT] = QDF_TRACE_LEVEL_NONE,
  3628. [QDF_MODULE_ID_PROXYARP] = QDF_TRACE_LEVEL_NONE,
  3629. [QDF_MODULE_ID_L2TIF] = QDF_TRACE_LEVEL_NONE,
  3630. [QDF_MODULE_ID_WIFIPOS] = QDF_TRACE_LEVEL_NONE,
  3631. [QDF_MODULE_ID_WRAP] = QDF_TRACE_LEVEL_NONE,
  3632. [QDF_MODULE_ID_DFS] = QDF_TRACE_LEVEL_NONE,
  3633. [QDF_MODULE_ID_ATF] = QDF_TRACE_LEVEL_ERROR,
  3634. [QDF_MODULE_ID_SPLITMAC] = QDF_TRACE_LEVEL_NONE,
  3635. [QDF_MODULE_ID_IOCTL] = QDF_TRACE_LEVEL_NONE,
  3636. [QDF_MODULE_ID_NAC] = QDF_TRACE_LEVEL_NONE,
  3637. [QDF_MODULE_ID_MESH] = QDF_TRACE_LEVEL_NONE,
  3638. [QDF_MODULE_ID_MBO] = QDF_TRACE_LEVEL_NONE,
  3639. [QDF_MODULE_ID_EXTIOCTL_CHANSWITCH] = QDF_TRACE_LEVEL_NONE,
  3640. [QDF_MODULE_ID_EXTIOCTL_CHANSSCAN] = QDF_TRACE_LEVEL_NONE,
  3641. [QDF_MODULE_ID_TLSHIM] = QDF_TRACE_LEVEL_NONE,
  3642. [QDF_MODULE_ID_WMI] = QDF_TRACE_LEVEL_ERROR,
  3643. [QDF_MODULE_ID_HTT] = QDF_TRACE_LEVEL_NONE,
  3644. [QDF_MODULE_ID_HDD] = QDF_TRACE_LEVEL_NONE,
  3645. [QDF_MODULE_ID_SME] = QDF_TRACE_LEVEL_NONE,
  3646. [QDF_MODULE_ID_PE] = QDF_TRACE_LEVEL_NONE,
  3647. [QDF_MODULE_ID_WMA] = QDF_TRACE_LEVEL_NONE,
  3648. [QDF_MODULE_ID_SYS] = QDF_TRACE_LEVEL_NONE,
  3649. [QDF_MODULE_ID_QDF] = QDF_TRACE_LEVEL_ERROR,
  3650. [QDF_MODULE_ID_SAP] = QDF_TRACE_LEVEL_NONE,
  3651. [QDF_MODULE_ID_HDD_SOFTAP] = QDF_TRACE_LEVEL_NONE,
  3652. [QDF_MODULE_ID_HDD_DATA] = QDF_TRACE_LEVEL_NONE,
  3653. [QDF_MODULE_ID_HDD_SAP_DATA] = QDF_TRACE_LEVEL_NONE,
  3654. [QDF_MODULE_ID_HIF] = QDF_TRACE_LEVEL_ERROR,
  3655. [QDF_MODULE_ID_HTC] = QDF_TRACE_LEVEL_NONE,
  3656. [QDF_MODULE_ID_TXRX] = QDF_TRACE_LEVEL_NONE,
  3657. [QDF_MODULE_ID_QDF_DEVICE] = QDF_TRACE_LEVEL_NONE,
  3658. [QDF_MODULE_ID_CFG] = QDF_TRACE_LEVEL_NONE,
  3659. [QDF_MODULE_ID_BMI] = QDF_TRACE_LEVEL_NONE,
  3660. [QDF_MODULE_ID_EPPING] = QDF_TRACE_LEVEL_NONE,
  3661. [QDF_MODULE_ID_QVIT] = QDF_TRACE_LEVEL_NONE,
  3662. [QDF_MODULE_ID_DP] = QDF_TRACE_LEVEL_FATAL,
  3663. [QDF_MODULE_ID_HAL] = QDF_TRACE_LEVEL_NONE,
  3664. [QDF_MODULE_ID_SOC] = QDF_TRACE_LEVEL_NONE,
  3665. [QDF_MODULE_ID_OS_IF] = QDF_TRACE_LEVEL_NONE,
  3666. [QDF_MODULE_ID_TARGET_IF] = QDF_TRACE_LEVEL_INFO,
  3667. [QDF_MODULE_ID_SCHEDULER] = QDF_TRACE_LEVEL_FATAL,
  3668. [QDF_MODULE_ID_MGMT_TXRX] = QDF_TRACE_LEVEL_NONE,
  3669. [QDF_MODULE_ID_SERIALIZATION] = QDF_TRACE_LEVEL_ERROR,
  3670. [QDF_MODULE_ID_PMO] = QDF_TRACE_LEVEL_NONE,
  3671. [QDF_MODULE_ID_P2P] = QDF_TRACE_LEVEL_NONE,
  3672. [QDF_MODULE_ID_POLICY_MGR] = QDF_TRACE_LEVEL_NONE,
  3673. [QDF_MODULE_ID_CONFIG] = QDF_TRACE_LEVEL_ERROR,
  3674. [QDF_MODULE_ID_REGULATORY] = QDF_TRACE_LEVEL_NONE,
  3675. [QDF_MODULE_ID_SA_API] = QDF_TRACE_LEVEL_NONE,
  3676. [QDF_MODULE_ID_NAN] = QDF_TRACE_LEVEL_NONE,
  3677. [QDF_MODULE_ID_OFFCHAN_TXRX] = QDF_TRACE_LEVEL_NONE,
  3678. [QDF_MODULE_ID_SON] = QDF_TRACE_LEVEL_NONE,
  3679. [QDF_MODULE_ID_SPECTRAL] = QDF_TRACE_LEVEL_ERROR,
  3680. [QDF_MODULE_ID_OBJ_MGR] = QDF_TRACE_LEVEL_FATAL,
  3681. [QDF_MODULE_ID_NSS] = QDF_TRACE_LEVEL_ERROR,
  3682. [QDF_MODULE_ID_ROAM_DEBUG] = QDF_TRACE_LEVEL_ERROR,
  3683. [QDF_MODULE_ID_CDP] = QDF_TRACE_LEVEL_NONE,
  3684. [QDF_MODULE_ID_DIRECT_BUF_RX] = QDF_TRACE_LEVEL_ERROR,
  3685. [QDF_MODULE_ID_DISA] = QDF_TRACE_LEVEL_NONE,
  3686. [QDF_MODULE_ID_GREEN_AP] = QDF_TRACE_LEVEL_ERROR,
  3687. [QDF_MODULE_ID_FTM] = QDF_TRACE_LEVEL_ERROR,
  3688. [QDF_MODULE_ID_FD] = QDF_TRACE_LEVEL_ERROR,
  3689. [QDF_MODULE_ID_OCB] = QDF_TRACE_LEVEL_ERROR,
  3690. [QDF_MODULE_ID_IPA] = QDF_TRACE_LEVEL_NONE,
  3691. [QDF_MODULE_ID_ACTION_OUI] = QDF_TRACE_LEVEL_NONE,
  3692. [QDF_MODULE_ID_CP_STATS] = QDF_TRACE_LEVEL_ERROR,
  3693. [QDF_MODULE_ID_DCS] = QDF_TRACE_LEVEL_ERROR,
  3694. [QDF_MODULE_ID_MBSSIE] = QDF_TRACE_LEVEL_INFO,
  3695. [QDF_MODULE_ID_FWOL] = QDF_TRACE_LEVEL_NONE,
  3696. [QDF_MODULE_ID_SM_ENGINE] = QDF_TRACE_LEVEL_ERROR,
  3697. [QDF_MODULE_ID_CMN_MLME] = QDF_TRACE_LEVEL_INFO,
  3698. [QDF_MODULE_ID_BSSCOLOR] = QDF_TRACE_LEVEL_ERROR,
  3699. [QDF_MODULE_ID_CFR] = QDF_TRACE_LEVEL_ERROR,
  3700. [QDF_MODULE_ID_DP_TX_CAPTURE] = QDF_TRACE_LEVEL_FATAL,
  3701. [QDF_MODULE_ID_INTEROP_ISSUES_AP] = QDF_TRACE_LEVEL_NONE,
  3702. [QDF_MODULE_ID_DENYLIST_MGR] = QDF_TRACE_LEVEL_NONE,
  3703. [QDF_MODULE_ID_QLD] = QDF_TRACE_LEVEL_ERROR,
  3704. [QDF_MODULE_ID_DYNAMIC_MODE_CHG] = QDF_TRACE_LEVEL_INFO,
  3705. [QDF_MODULE_ID_COEX] = QDF_TRACE_LEVEL_ERROR,
  3706. [QDF_MODULE_ID_MON_FILTER] = QDF_TRACE_LEVEL_INFO,
  3707. [QDF_MODULE_ID_PKT_CAPTURE] = QDF_TRACE_LEVEL_NONE,
  3708. [QDF_MODULE_ID_RPTR] = QDF_TRACE_LEVEL_INFO,
  3709. [QDF_MODULE_ID_6GHZ] = QDF_TRACE_LEVEL_ERROR,
  3710. [QDF_MODULE_ID_IOT_SIM] = QDF_TRACE_LEVEL_ERROR,
  3711. [QDF_MODULE_ID_MSCS] = QDF_TRACE_LEVEL_INFO,
  3712. [QDF_MODULE_ID_GPIO] = QDF_TRACE_LEVEL_NONE,
  3713. [QDF_MODULE_ID_IFMGR] = QDF_TRACE_LEVEL_ERROR,
  3714. [QDF_MODULE_ID_DIAG] = QDF_TRACE_LEVEL_ERROR,
  3715. [QDF_MODULE_ID_DP_INIT] = QDF_TRACE_LEVEL_FATAL,
  3716. [QDF_MODULE_ID_DP_TX] = QDF_TRACE_LEVEL_FATAL,
  3717. [QDF_MODULE_ID_DP_RX] = QDF_TRACE_LEVEL_FATAL,
  3718. [QDF_MODULE_ID_DP_STATS] = QDF_TRACE_LEVEL_FATAL,
  3719. [QDF_MODULE_ID_DP_HTT] = QDF_TRACE_LEVEL_FATAL,
  3720. [QDF_MODULE_ID_DP_PEER] = QDF_TRACE_LEVEL_FATAL,
  3721. [QDF_MODULE_ID_DP_RX_ERROR] = QDF_TRACE_LEVEL_FATAL,
  3722. [QDF_MODULE_ID_DP_HTT_TX_STATS] = QDF_TRACE_LEVEL_FATAL,
  3723. [QDF_MODULE_ID_DP_RX_MON_STATUS] = QDF_TRACE_LEVEL_FATAL,
  3724. [QDF_MODULE_ID_DP_RX_MON_DEST] = QDF_TRACE_LEVEL_FATAL,
  3725. [QDF_MODULE_ID_DP_REO] = QDF_TRACE_LEVEL_FATAL,
  3726. [QDF_MODULE_ID_DP_TX_COMP] = QDF_TRACE_LEVEL_FATAL,
  3727. [QDF_MODULE_ID_DP_VDEV] = QDF_TRACE_LEVEL_FATAL,
  3728. [QDF_MODULE_ID_DP_CDP] = QDF_TRACE_LEVEL_FATAL,
  3729. [QDF_MODULE_ID_TSO] = QDF_TRACE_LEVEL_FATAL,
  3730. [QDF_MODULE_ID_ME] = QDF_TRACE_LEVEL_INFO,
  3731. [QDF_MODULE_ID_QWRAP] = QDF_TRACE_LEVEL_FATAL,
  3732. [QDF_MODULE_ID_DBDC_REP] = QDF_TRACE_LEVEL_FATAL,
  3733. [QDF_MODULE_ID_EXT_AP] = QDF_TRACE_LEVEL_NONE,
  3734. [QDF_MODULE_ID_MLO] = QDF_TRACE_LEVEL_INFO,
  3735. [QDF_MODULE_ID_MLOIE] = QDF_TRACE_LEVEL_INFO,
  3736. [QDF_MODULE_ID_MBSS] = QDF_TRACE_LEVEL_ERROR,
  3737. [QDF_MODULE_ID_MON] = QDF_TRACE_LEVEL_ERROR,
  3738. [QDF_MODULE_ID_MGMT_RX_REO] = QDF_TRACE_LEVEL_ERROR,
  3739. [QDF_MODULE_ID_TWT] = QDF_TRACE_LEVEL_ERROR,
  3740. [QDF_MODULE_ID_WLAN_PRE_CAC] = QDF_TRACE_LEVEL_ERROR,
  3741. [QDF_MODULE_ID_T2LM] = QDF_TRACE_LEVEL_ERROR,
  3742. [QDF_MODULE_ID_DP_SAWF] = QDF_TRACE_LEVEL_ERROR,
  3743. [QDF_MODULE_ID_SCS] = QDF_TRACE_LEVEL_ERROR,
  3744. [QDF_MODULE_ID_DP_UMAC_RESET] = QDF_TRACE_LEVEL_ERROR,
  3745. [QDF_MODULE_ID_COAP] = QDF_TRACE_LEVEL_ERROR,
  3746. [QDF_MODULE_ID_ANY] = QDF_TRACE_LEVEL_INFO,
  3747. };
  3748. for (i = 0; i < MAX_SUPPORTED_CATEGORY; i++) {
  3749. cinfo[i].category_verbose_mask = set_cumulative_verbose_mask(
  3750. module_trace_default_level[i]);
  3751. }
  3752. }
  3753. void qdf_shared_print_ctrl_init(void)
  3754. {
  3755. int i;
  3756. struct category_info cinfo[MAX_SUPPORTED_CATEGORY];
  3757. set_default_trace_levels(cinfo);
  3758. /*
  3759. * User specified across-module single debug level
  3760. */
  3761. if ((qdf_dbg_mask >= 0) && (qdf_dbg_mask < QDF_TRACE_LEVEL_MAX)) {
  3762. pr_info("User specified module debug level of %d\n",
  3763. qdf_dbg_mask);
  3764. for (i = 0; i < MAX_SUPPORTED_CATEGORY; i++) {
  3765. cinfo[i].category_verbose_mask =
  3766. set_cumulative_verbose_mask(qdf_dbg_mask);
  3767. }
  3768. } else if (qdf_dbg_mask != QDF_TRACE_LEVEL_MAX) {
  3769. pr_info("qdf_dbg_mask value is invalid\n");
  3770. pr_info("Using the default module debug levels instead\n");
  3771. }
  3772. /*
  3773. * Module ID-Level specified as array during module load
  3774. */
  3775. for (i = 0; i < qdf_dbg_arr_cnt; i++) {
  3776. process_qdf_dbg_arr_param(cinfo, i);
  3777. }
  3778. qdf_pidx = qdf_print_ctrl_register(cinfo, NULL, NULL,
  3779. "LOG_SHARED_OBJ");
  3780. }
  3781. qdf_export_symbol(qdf_shared_print_ctrl_init);
  3782. #endif
  3783. #ifdef QCA_WIFI_MODULE_PARAMS_FROM_INI
  3784. QDF_STATUS qdf_module_param_handler(void *context, const char *str_param,
  3785. const char *str)
  3786. {
  3787. QDF_STATUS status = QDF_STATUS_E_FAILURE;
  3788. uint16_t param = 0;
  3789. uint32_t flush_tmr_prd;
  3790. bool dump_flag;
  3791. while (param < QDF_PARAM_MAX) {
  3792. if (qdf_str_eq(qdf_module_param[param], str_param)) {
  3793. switch (param) {
  3794. case MEM_DEBUG_DISABLED:
  3795. status = qdf_mem_debug_disabled_config_set(str);
  3796. break;
  3797. case QDF_DBG_MASK:
  3798. status = qdf_int32_parse(str, &qdf_dbg_mask);
  3799. break;
  3800. case PREALLOC_DISABLED:
  3801. status = qdf_prealloc_disabled_config_set(str);
  3802. break;
  3803. case QDF_LOG_DUMP_AT_KERNEL_ENABLE:
  3804. status = qdf_bool_parse(str, &dump_flag);
  3805. qdf_log_dump_at_kernel_enable = dump_flag;
  3806. break;
  3807. case QDF_DBG_ARR:
  3808. qdf_dbg_arr[0] = (char *)str;
  3809. status = QDF_STATUS_SUCCESS;
  3810. break;
  3811. case QDF_LOG_FLUSH_TIMER_PERIOD:
  3812. status = qdf_uint32_parse(str, &flush_tmr_prd);
  3813. qdf_log_flush_timer_period = flush_tmr_prd;
  3814. break;
  3815. default:
  3816. break;
  3817. }
  3818. return status;
  3819. }
  3820. param++;
  3821. }
  3822. return QDF_STATUS_SUCCESS;
  3823. }
  3824. void qdf_initialize_module_param_from_ini(void)
  3825. {
  3826. QDF_STATUS status;
  3827. char *path = QDF_WIFI_MODULE_PARAMS_FILE;
  3828. status = qdf_ini_parse(path, NULL, qdf_module_param_handler, NULL);
  3829. if (QDF_IS_STATUS_ERROR(status)) {
  3830. QDF_TRACE_ERROR(QDF_MODULE_ID_QDF,
  3831. "Failed to parse *.ini file @ %s; status:%d",
  3832. path, status);
  3833. return;
  3834. }
  3835. }
  3836. #endif
  3837. QDF_STATUS qdf_print_set_category_verbose(unsigned int idx,
  3838. QDF_MODULE_ID category,
  3839. QDF_TRACE_LEVEL verbose,
  3840. bool is_set)
  3841. {
  3842. /* Check if index passed is valid */
  3843. if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
  3844. pr_err("%s: Invalid index - %d\n", __func__, idx);
  3845. return QDF_STATUS_E_FAILURE;
  3846. }
  3847. /* Check if print control object is in use */
  3848. if (!print_ctrl_obj[idx].in_use) {
  3849. pr_err("%s: Invalid print control object\n", __func__);
  3850. return QDF_STATUS_E_FAILURE;
  3851. }
  3852. /* Check if category passed is valid */
  3853. if (category < 0 || category >= MAX_SUPPORTED_CATEGORY) {
  3854. pr_err("%s: Invalid category: %d\n", __func__, category);
  3855. return QDF_STATUS_E_FAILURE;
  3856. }
  3857. /* Check if verbose mask is valid */
  3858. if (verbose < 0 || verbose >= QDF_TRACE_LEVEL_MAX) {
  3859. pr_err("%s: Invalid verbose level %d\n", __func__, verbose);
  3860. return QDF_STATUS_E_FAILURE;
  3861. }
  3862. if (verbose == QDF_TRACE_LEVEL_ALL) {
  3863. print_ctrl_obj[idx].cat_info[category].category_verbose_mask =
  3864. 0xFFFF;
  3865. return QDF_STATUS_SUCCESS;
  3866. }
  3867. if (verbose == QDF_TRACE_LEVEL_NONE) {
  3868. print_ctrl_obj[idx].cat_info[category].category_verbose_mask =
  3869. QDF_TRACE_LEVEL_NONE;
  3870. return QDF_STATUS_SUCCESS;
  3871. }
  3872. if (!is_set) {
  3873. if (print_ctrl_obj[idx].cat_info[category].category_verbose_mask
  3874. & QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose)) {
  3875. print_ctrl_obj[idx].cat_info[category]
  3876. .category_verbose_mask &=
  3877. ~QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose);
  3878. }
  3879. } else {
  3880. print_ctrl_obj[idx].cat_info[category].category_verbose_mask |=
  3881. QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose);
  3882. }
  3883. pr_debug("%s: Print control object %d, Category %d, Verbose level %d\n",
  3884. __func__,
  3885. idx,
  3886. category,
  3887. print_ctrl_obj[idx].cat_info[category].category_verbose_mask);
  3888. return QDF_STATUS_SUCCESS;
  3889. }
  3890. qdf_export_symbol(qdf_print_set_category_verbose);
  3891. void qdf_log_dump_at_kernel_level(bool enable)
  3892. {
  3893. if (qdf_log_dump_at_kernel_enable == enable) {
  3894. QDF_TRACE_INFO(QDF_MODULE_ID_QDF,
  3895. "qdf_log_dump_at_kernel_enable is already %d\n",
  3896. enable);
  3897. }
  3898. qdf_log_dump_at_kernel_enable = enable;
  3899. }
  3900. qdf_export_symbol(qdf_log_dump_at_kernel_level);
  3901. bool qdf_print_is_category_enabled(unsigned int idx, QDF_MODULE_ID category)
  3902. {
  3903. QDF_TRACE_LEVEL verbose_mask;
  3904. /* Check if index passed is valid */
  3905. if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
  3906. pr_info("%s: Invalid index - %d\n", __func__, idx);
  3907. return false;
  3908. }
  3909. /* Check if print control object is in use */
  3910. if (!print_ctrl_obj[idx].in_use) {
  3911. pr_info("%s: Invalid print control object\n", __func__);
  3912. return false;
  3913. }
  3914. /* Check if category passed is valid */
  3915. if (category < 0 || category >= MAX_SUPPORTED_CATEGORY) {
  3916. pr_info("%s: Invalid category: %d\n", __func__, category);
  3917. return false;
  3918. }
  3919. verbose_mask =
  3920. print_ctrl_obj[idx].cat_info[category].category_verbose_mask;
  3921. if (verbose_mask == QDF_TRACE_LEVEL_NONE)
  3922. return false;
  3923. else
  3924. return true;
  3925. }
  3926. qdf_export_symbol(qdf_print_is_category_enabled);
  3927. bool qdf_print_is_verbose_enabled(unsigned int idx, QDF_MODULE_ID category,
  3928. QDF_TRACE_LEVEL verbose)
  3929. {
  3930. bool verbose_enabled = false;
  3931. /* Check if index passed is valid */
  3932. if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
  3933. pr_info("%s: Invalid index - %d\n", __func__, idx);
  3934. return verbose_enabled;
  3935. }
  3936. /* Check if print control object is in use */
  3937. if (!print_ctrl_obj[idx].in_use) {
  3938. pr_info("%s: Invalid print control object\n", __func__);
  3939. return verbose_enabled;
  3940. }
  3941. /* Check if category passed is valid */
  3942. if (category < 0 || category >= MAX_SUPPORTED_CATEGORY) {
  3943. pr_info("%s: Invalid category: %d\n", __func__, category);
  3944. return verbose_enabled;
  3945. }
  3946. if ((verbose == QDF_TRACE_LEVEL_NONE) ||
  3947. (verbose >= QDF_TRACE_LEVEL_MAX)) {
  3948. verbose_enabled = false;
  3949. } else if (verbose == QDF_TRACE_LEVEL_ALL) {
  3950. if (print_ctrl_obj[idx].cat_info[category]
  3951. .category_verbose_mask == 0xFFFF)
  3952. verbose_enabled = true;
  3953. } else {
  3954. verbose_enabled =
  3955. (print_ctrl_obj[idx].cat_info[category].category_verbose_mask &
  3956. QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose)) ? true : false;
  3957. }
  3958. return verbose_enabled;
  3959. }
  3960. qdf_export_symbol(qdf_print_is_verbose_enabled);
  3961. #ifdef DBG_LVL_MAC_FILTERING
  3962. QDF_STATUS qdf_print_set_node_flag(unsigned int idx, uint8_t enable)
  3963. {
  3964. /* Check if index passed is valid */
  3965. if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
  3966. pr_info("%s: Invalid index - %d\n", __func__, idx);
  3967. return QDF_STATUS_E_FAILURE;
  3968. }
  3969. /* Check if print control object is in use */
  3970. if (!print_ctrl_obj[idx].in_use) {
  3971. pr_info("%s: Invalid print control object\n", __func__);
  3972. return QDF_STATUS_E_FAILURE;
  3973. }
  3974. if (enable > 1) {
  3975. pr_info("%s: Incorrect input: Use 1 or 0 to enable or disable\n",
  3976. __func__);
  3977. return QDF_STATUS_E_FAILURE;
  3978. }
  3979. print_ctrl_obj[idx].dbglvlmac_on = enable;
  3980. pr_info("%s: DbgLVLmac feature %s\n",
  3981. __func__,
  3982. ((enable) ? "enabled" : "disabled"));
  3983. return QDF_STATUS_SUCCESS;
  3984. }
  3985. qdf_export_symbol(qdf_print_set_node_flag);
  3986. bool qdf_print_get_node_flag(unsigned int idx)
  3987. {
  3988. bool node_flag = false;
  3989. /* Check if index passed is valid */
  3990. if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
  3991. pr_info("%s: Invalid index - %d\n", __func__, idx);
  3992. return node_flag;
  3993. }
  3994. /* Check if print control object is in use */
  3995. if (!print_ctrl_obj[idx].in_use) {
  3996. pr_info("%s: Invalid print control object\n", __func__);
  3997. return node_flag;
  3998. }
  3999. if (print_ctrl_obj[idx].dbglvlmac_on)
  4000. node_flag = true;
  4001. return node_flag;
  4002. }
  4003. qdf_export_symbol(qdf_print_get_node_flag);
  4004. void qdf_print_clean_node_flag(unsigned int idx)
  4005. {
  4006. /* Disable dbglvlmac_on during cleanup */
  4007. print_ctrl_obj[idx].dbglvlmac_on = 0;
  4008. }
  4009. #else
  4010. void qdf_print_clean_node_flag(unsigned int idx)
  4011. {
  4012. /* No operation in case of no support for DBG_LVL_MAC_FILTERING */
  4013. return;
  4014. }
  4015. #endif
  4016. void QDF_PRINT_INFO(unsigned int idx, QDF_MODULE_ID module,
  4017. QDF_TRACE_LEVEL level,
  4018. char *str_format, ...)
  4019. {
  4020. va_list args;
  4021. /* Generic wrapper API will compile qdf_vprint in order to
  4022. * log the message. Once QDF converged debug framework is in
  4023. * place, this will be changed to adapt to the framework, compiling
  4024. * call to converged tracing API
  4025. */
  4026. va_start(args, str_format);
  4027. qdf_vprint(str_format, args);
  4028. va_end(args);
  4029. }
  4030. qdf_export_symbol(QDF_PRINT_INFO);
  4031. #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
  4032. void qdf_logging_init(void)
  4033. {
  4034. wlan_logging_sock_init_svc();
  4035. nl_srv_init(NULL, WLAN_NLINK_PROTO_FAMILY);
  4036. wlan_logging_notifier_init(qdf_log_dump_at_kernel_enable);
  4037. wlan_logging_set_flush_timer(qdf_log_flush_timer_period);
  4038. }
  4039. void qdf_logging_exit(void)
  4040. {
  4041. wlan_logging_notifier_deinit(qdf_log_dump_at_kernel_enable);
  4042. nl_srv_exit();
  4043. wlan_logging_sock_deinit_svc();
  4044. }
  4045. int qdf_logging_set_flush_timer(uint32_t milliseconds)
  4046. {
  4047. if (wlan_logging_set_flush_timer(milliseconds) == 0)
  4048. return QDF_STATUS_SUCCESS;
  4049. else
  4050. return QDF_STATUS_E_FAILURE;
  4051. }
  4052. void qdf_logging_flush_logs(void)
  4053. {
  4054. wlan_flush_host_logs_for_fatal();
  4055. }
  4056. #else
  4057. void qdf_logging_init(void)
  4058. {
  4059. nl_srv_init(NULL, WLAN_NLINK_PROTO_FAMILY);
  4060. }
  4061. void qdf_logging_exit(void)
  4062. {
  4063. nl_srv_exit();
  4064. }
  4065. int qdf_logging_set_flush_timer(uint32_t milliseconds)
  4066. {
  4067. return QDF_STATUS_E_FAILURE;
  4068. }
  4069. void qdf_logging_flush_logs(void)
  4070. {
  4071. }
  4072. #endif
  4073. qdf_export_symbol(qdf_logging_set_flush_timer);
  4074. qdf_export_symbol(qdf_logging_flush_logs);
  4075. #ifdef CONFIG_KALLSYMS
  4076. inline int qdf_sprint_symbol(char *buffer, void *addr)
  4077. {
  4078. return sprint_symbol(buffer, (unsigned long)addr);
  4079. }
  4080. #else
  4081. int qdf_sprint_symbol(char *buffer, void *addr)
  4082. {
  4083. if (!buffer)
  4084. return 0;
  4085. buffer[0] = '\0';
  4086. return 1;
  4087. }
  4088. #endif
  4089. qdf_export_symbol(qdf_sprint_symbol);
  4090. void qdf_set_pidx(int pidx)
  4091. {
  4092. qdf_pidx = pidx;
  4093. }
  4094. qdf_export_symbol(qdf_set_pidx);
  4095. int qdf_get_pidx(void)
  4096. {
  4097. return qdf_pidx;
  4098. }
  4099. qdf_export_symbol(qdf_get_pidx);
  4100. #ifdef PANIC_ON_BUG
  4101. #ifdef CONFIG_SLUB_DEBUG
  4102. void __qdf_bug(void)
  4103. {
  4104. BUG();
  4105. }
  4106. qdf_export_symbol(__qdf_bug);
  4107. #endif /* CONFIG_SLUB_DEBUG */
  4108. #endif /* PANIC_ON_BUG */
  4109. #ifdef WLAN_QCOM_VA_MINIDUMP
  4110. static bool qdf_va_md_initialized;
  4111. static qdf_list_t qdf_va_md_list;
  4112. static qdf_spinlock_t qdf_va_md_list_lock;
  4113. #define QDF_MINIDUMP_LIST_SIZE 128
  4114. struct qdf_va_md_entry {
  4115. qdf_list_node_t node;
  4116. struct va_md_entry data;
  4117. };
  4118. static int qdf_va_md_notif_handler(struct notifier_block *this,
  4119. unsigned long event, void *ptr)
  4120. {
  4121. struct qdf_va_md_entry *entry;
  4122. struct qdf_va_md_entry *next;
  4123. qdf_spin_lock_irqsave(&qdf_va_md_list_lock);
  4124. qdf_list_for_each_del(&qdf_va_md_list, entry, next, node) {
  4125. qcom_va_md_add_region(&entry->data);
  4126. }
  4127. qdf_spin_unlock_irqrestore(&qdf_va_md_list_lock);
  4128. return NOTIFY_OK;
  4129. }
  4130. static struct notifier_block qdf_va_md_notif_blk = {
  4131. .notifier_call = qdf_va_md_notif_handler,
  4132. .priority = INT_MAX,
  4133. };
  4134. void __qdf_minidump_init(void)
  4135. {
  4136. int ret;
  4137. if (qdf_va_md_initialized)
  4138. return;
  4139. qdf_spinlock_create(&qdf_va_md_list_lock);
  4140. qdf_list_create(&qdf_va_md_list, QDF_MINIDUMP_LIST_SIZE);
  4141. ret = qcom_va_md_register(qdf_trace_wlan_modname(),
  4142. &qdf_va_md_notif_blk);
  4143. qdf_va_md_initialized = !ret;
  4144. }
  4145. qdf_export_symbol(__qdf_minidump_init);
  4146. void __qdf_minidump_deinit(void)
  4147. {
  4148. struct qdf_va_md_entry *entry;
  4149. struct qdf_va_md_entry *next;
  4150. if (!qdf_va_md_initialized)
  4151. return;
  4152. qdf_va_md_initialized = false;
  4153. qcom_va_md_unregister(qdf_trace_wlan_modname(),
  4154. &qdf_va_md_notif_blk);
  4155. qdf_spin_lock_irqsave(&qdf_va_md_list_lock);
  4156. qdf_list_for_each_del(&qdf_va_md_list, entry, next, node) {
  4157. qdf_list_remove_node(&qdf_va_md_list, &entry->node);
  4158. qdf_mem_free(entry);
  4159. }
  4160. qdf_list_destroy(&qdf_va_md_list);
  4161. qdf_spin_unlock_irqrestore(&qdf_va_md_list_lock);
  4162. qdf_spinlock_destroy(&qdf_va_md_list_lock);
  4163. }
  4164. qdf_export_symbol(__qdf_minidump_deinit);
  4165. void __qdf_minidump_log(void *start_addr, size_t size, const char *name)
  4166. {
  4167. struct qdf_va_md_entry *entry;
  4168. QDF_STATUS status;
  4169. if (!qdf_va_md_initialized)
  4170. return;
  4171. entry = qdf_mem_malloc(sizeof(*entry));
  4172. if (!entry) {
  4173. qdf_err("malloc failed for %s: %pK, %zu",
  4174. name, start_addr, size);
  4175. return;
  4176. }
  4177. qdf_str_lcopy(entry->data.owner, name, sizeof(entry->data.owner));
  4178. entry->data.vaddr = (unsigned long)start_addr;
  4179. entry->data.size = size;
  4180. qdf_spin_lock_irqsave(&qdf_va_md_list_lock);
  4181. status = qdf_list_insert_front(&qdf_va_md_list, &entry->node);
  4182. qdf_spin_unlock_irqrestore(&qdf_va_md_list_lock);
  4183. if (QDF_IS_STATUS_ERROR(status)) {
  4184. qdf_err("Failed to insert qdf va md entry, status %d", status);
  4185. qdf_mem_free(entry);
  4186. }
  4187. }
  4188. qdf_export_symbol(__qdf_minidump_log);
  4189. void __qdf_minidump_remove(void *addr, size_t size, const char *name)
  4190. {
  4191. struct qdf_va_md_entry *entry;
  4192. struct qdf_va_md_entry *next;
  4193. if (!qdf_va_md_initialized)
  4194. return;
  4195. qdf_spin_lock_irqsave(&qdf_va_md_list_lock);
  4196. qdf_list_for_each_del(&qdf_va_md_list, entry, next, node) {
  4197. if (entry->data.vaddr == (unsigned long)addr &&
  4198. entry->data.size == size &&
  4199. !qdf_str_cmp(entry->data.owner, name)) {
  4200. qdf_list_remove_node(&qdf_va_md_list, &entry->node);
  4201. qdf_mem_free(entry);
  4202. break;
  4203. }
  4204. }
  4205. qdf_spin_unlock_irqrestore(&qdf_va_md_list_lock);
  4206. }
  4207. qdf_export_symbol(__qdf_minidump_remove);
  4208. #endif