qdf_trace.c 122 KB

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