qdf_trace.c 117 KB

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