qmi.c 84 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366
  1. // SPDX-License-Identifier: BSD-3-Clause-Clear
  2. /*
  3. * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
  5. * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
  6. */
  7. #include <linux/elf.h>
  8. #include <linux/export.h>
  9. #include "qmi.h"
  10. #include "core.h"
  11. #include "debug.h"
  12. #include "hif.h"
  13. #include <linux/of.h>
  14. #include <linux/of_reserved_mem.h>
  15. #include <linux/ioport.h>
  16. #include <linux/firmware.h>
  17. #include <linux/of_irq.h>
  18. #define SLEEP_CLOCK_SELECT_INTERNAL_BIT 0x02
  19. #define HOST_CSTATE_BIT 0x04
  20. #define PLATFORM_CAP_PCIE_GLOBAL_RESET 0x08
  21. #define PLATFORM_CAP_PCIE_PME_D3COLD 0x10
  22. #define FW_BUILD_ID_MASK "QC_IMAGE_VERSION_STRING="
  23. bool ath11k_cold_boot_cal = 1;
  24. EXPORT_SYMBOL(ath11k_cold_boot_cal);
  25. module_param_named(cold_boot_cal, ath11k_cold_boot_cal, bool, 0644);
  26. MODULE_PARM_DESC(cold_boot_cal,
  27. "Decrease the channel switch time but increase the driver load time (Default: true)");
  28. static const struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = {
  29. {
  30. .data_type = QMI_OPT_FLAG,
  31. .elem_len = 1,
  32. .elem_size = sizeof(u8),
  33. .array_type = NO_ARRAY,
  34. .tlv_type = 0x10,
  35. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  36. num_clients_valid),
  37. },
  38. {
  39. .data_type = QMI_UNSIGNED_4_BYTE,
  40. .elem_len = 1,
  41. .elem_size = sizeof(u32),
  42. .array_type = NO_ARRAY,
  43. .tlv_type = 0x10,
  44. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  45. num_clients),
  46. },
  47. {
  48. .data_type = QMI_OPT_FLAG,
  49. .elem_len = 1,
  50. .elem_size = sizeof(u8),
  51. .array_type = NO_ARRAY,
  52. .tlv_type = 0x11,
  53. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  54. wake_msi_valid),
  55. },
  56. {
  57. .data_type = QMI_UNSIGNED_4_BYTE,
  58. .elem_len = 1,
  59. .elem_size = sizeof(u32),
  60. .array_type = NO_ARRAY,
  61. .tlv_type = 0x11,
  62. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  63. wake_msi),
  64. },
  65. {
  66. .data_type = QMI_OPT_FLAG,
  67. .elem_len = 1,
  68. .elem_size = sizeof(u8),
  69. .array_type = NO_ARRAY,
  70. .tlv_type = 0x12,
  71. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  72. gpios_valid),
  73. },
  74. {
  75. .data_type = QMI_DATA_LEN,
  76. .elem_len = 1,
  77. .elem_size = sizeof(u8),
  78. .array_type = NO_ARRAY,
  79. .tlv_type = 0x12,
  80. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  81. gpios_len),
  82. },
  83. {
  84. .data_type = QMI_UNSIGNED_4_BYTE,
  85. .elem_len = QMI_WLFW_MAX_NUM_GPIO_V01,
  86. .elem_size = sizeof(u32),
  87. .array_type = VAR_LEN_ARRAY,
  88. .tlv_type = 0x12,
  89. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  90. gpios),
  91. },
  92. {
  93. .data_type = QMI_OPT_FLAG,
  94. .elem_len = 1,
  95. .elem_size = sizeof(u8),
  96. .array_type = NO_ARRAY,
  97. .tlv_type = 0x13,
  98. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  99. nm_modem_valid),
  100. },
  101. {
  102. .data_type = QMI_UNSIGNED_1_BYTE,
  103. .elem_len = 1,
  104. .elem_size = sizeof(u8),
  105. .array_type = NO_ARRAY,
  106. .tlv_type = 0x13,
  107. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  108. nm_modem),
  109. },
  110. {
  111. .data_type = QMI_OPT_FLAG,
  112. .elem_len = 1,
  113. .elem_size = sizeof(u8),
  114. .array_type = NO_ARRAY,
  115. .tlv_type = 0x14,
  116. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  117. bdf_support_valid),
  118. },
  119. {
  120. .data_type = QMI_UNSIGNED_1_BYTE,
  121. .elem_len = 1,
  122. .elem_size = sizeof(u8),
  123. .array_type = NO_ARRAY,
  124. .tlv_type = 0x14,
  125. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  126. bdf_support),
  127. },
  128. {
  129. .data_type = QMI_OPT_FLAG,
  130. .elem_len = 1,
  131. .elem_size = sizeof(u8),
  132. .array_type = NO_ARRAY,
  133. .tlv_type = 0x15,
  134. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  135. bdf_cache_support_valid),
  136. },
  137. {
  138. .data_type = QMI_UNSIGNED_1_BYTE,
  139. .elem_len = 1,
  140. .elem_size = sizeof(u8),
  141. .array_type = NO_ARRAY,
  142. .tlv_type = 0x15,
  143. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  144. bdf_cache_support),
  145. },
  146. {
  147. .data_type = QMI_OPT_FLAG,
  148. .elem_len = 1,
  149. .elem_size = sizeof(u8),
  150. .array_type = NO_ARRAY,
  151. .tlv_type = 0x16,
  152. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  153. m3_support_valid),
  154. },
  155. {
  156. .data_type = QMI_UNSIGNED_1_BYTE,
  157. .elem_len = 1,
  158. .elem_size = sizeof(u8),
  159. .array_type = NO_ARRAY,
  160. .tlv_type = 0x16,
  161. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  162. m3_support),
  163. },
  164. {
  165. .data_type = QMI_OPT_FLAG,
  166. .elem_len = 1,
  167. .elem_size = sizeof(u8),
  168. .array_type = NO_ARRAY,
  169. .tlv_type = 0x17,
  170. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  171. m3_cache_support_valid),
  172. },
  173. {
  174. .data_type = QMI_UNSIGNED_1_BYTE,
  175. .elem_len = 1,
  176. .elem_size = sizeof(u8),
  177. .array_type = NO_ARRAY,
  178. .tlv_type = 0x17,
  179. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  180. m3_cache_support),
  181. },
  182. {
  183. .data_type = QMI_OPT_FLAG,
  184. .elem_len = 1,
  185. .elem_size = sizeof(u8),
  186. .array_type = NO_ARRAY,
  187. .tlv_type = 0x18,
  188. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  189. cal_filesys_support_valid),
  190. },
  191. {
  192. .data_type = QMI_UNSIGNED_1_BYTE,
  193. .elem_len = 1,
  194. .elem_size = sizeof(u8),
  195. .array_type = NO_ARRAY,
  196. .tlv_type = 0x18,
  197. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  198. cal_filesys_support),
  199. },
  200. {
  201. .data_type = QMI_OPT_FLAG,
  202. .elem_len = 1,
  203. .elem_size = sizeof(u8),
  204. .array_type = NO_ARRAY,
  205. .tlv_type = 0x19,
  206. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  207. cal_cache_support_valid),
  208. },
  209. {
  210. .data_type = QMI_UNSIGNED_1_BYTE,
  211. .elem_len = 1,
  212. .elem_size = sizeof(u8),
  213. .array_type = NO_ARRAY,
  214. .tlv_type = 0x19,
  215. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  216. cal_cache_support),
  217. },
  218. {
  219. .data_type = QMI_OPT_FLAG,
  220. .elem_len = 1,
  221. .elem_size = sizeof(u8),
  222. .array_type = NO_ARRAY,
  223. .tlv_type = 0x1A,
  224. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  225. cal_done_valid),
  226. },
  227. {
  228. .data_type = QMI_UNSIGNED_1_BYTE,
  229. .elem_len = 1,
  230. .elem_size = sizeof(u8),
  231. .array_type = NO_ARRAY,
  232. .tlv_type = 0x1A,
  233. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  234. cal_done),
  235. },
  236. {
  237. .data_type = QMI_OPT_FLAG,
  238. .elem_len = 1,
  239. .elem_size = sizeof(u8),
  240. .array_type = NO_ARRAY,
  241. .tlv_type = 0x1B,
  242. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  243. mem_bucket_valid),
  244. },
  245. {
  246. .data_type = QMI_UNSIGNED_4_BYTE,
  247. .elem_len = 1,
  248. .elem_size = sizeof(u32),
  249. .array_type = NO_ARRAY,
  250. .tlv_type = 0x1B,
  251. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  252. mem_bucket),
  253. },
  254. {
  255. .data_type = QMI_OPT_FLAG,
  256. .elem_len = 1,
  257. .elem_size = sizeof(u8),
  258. .array_type = NO_ARRAY,
  259. .tlv_type = 0x1C,
  260. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  261. mem_cfg_mode_valid),
  262. },
  263. {
  264. .data_type = QMI_UNSIGNED_1_BYTE,
  265. .elem_len = 1,
  266. .elem_size = sizeof(u8),
  267. .array_type = NO_ARRAY,
  268. .tlv_type = 0x1C,
  269. .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
  270. mem_cfg_mode),
  271. },
  272. {
  273. .data_type = QMI_EOTI,
  274. .array_type = NO_ARRAY,
  275. .tlv_type = QMI_COMMON_TLV_TYPE,
  276. },
  277. };
  278. static const struct qmi_elem_info qmi_wlanfw_host_cap_resp_msg_v01_ei[] = {
  279. {
  280. .data_type = QMI_STRUCT,
  281. .elem_len = 1,
  282. .elem_size = sizeof(struct qmi_response_type_v01),
  283. .array_type = NO_ARRAY,
  284. .tlv_type = 0x02,
  285. .offset = offsetof(struct qmi_wlanfw_host_cap_resp_msg_v01, resp),
  286. .ei_array = qmi_response_type_v01_ei,
  287. },
  288. {
  289. .data_type = QMI_EOTI,
  290. .array_type = NO_ARRAY,
  291. .tlv_type = QMI_COMMON_TLV_TYPE,
  292. },
  293. };
  294. static const struct qmi_elem_info qmi_wlanfw_ind_register_req_msg_v01_ei[] = {
  295. {
  296. .data_type = QMI_OPT_FLAG,
  297. .elem_len = 1,
  298. .elem_size = sizeof(u8),
  299. .array_type = NO_ARRAY,
  300. .tlv_type = 0x10,
  301. .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
  302. fw_ready_enable_valid),
  303. },
  304. {
  305. .data_type = QMI_UNSIGNED_1_BYTE,
  306. .elem_len = 1,
  307. .elem_size = sizeof(u8),
  308. .array_type = NO_ARRAY,
  309. .tlv_type = 0x10,
  310. .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
  311. fw_ready_enable),
  312. },
  313. {
  314. .data_type = QMI_OPT_FLAG,
  315. .elem_len = 1,
  316. .elem_size = sizeof(u8),
  317. .array_type = NO_ARRAY,
  318. .tlv_type = 0x11,
  319. .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
  320. initiate_cal_download_enable_valid),
  321. },
  322. {
  323. .data_type = QMI_UNSIGNED_1_BYTE,
  324. .elem_len = 1,
  325. .elem_size = sizeof(u8),
  326. .array_type = NO_ARRAY,
  327. .tlv_type = 0x11,
  328. .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
  329. initiate_cal_download_enable),
  330. },
  331. {
  332. .data_type = QMI_OPT_FLAG,
  333. .elem_len = 1,
  334. .elem_size = sizeof(u8),
  335. .array_type = NO_ARRAY,
  336. .tlv_type = 0x12,
  337. .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
  338. initiate_cal_update_enable_valid),
  339. },
  340. {
  341. .data_type = QMI_UNSIGNED_1_BYTE,
  342. .elem_len = 1,
  343. .elem_size = sizeof(u8),
  344. .array_type = NO_ARRAY,
  345. .tlv_type = 0x12,
  346. .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
  347. initiate_cal_update_enable),
  348. },
  349. {
  350. .data_type = QMI_OPT_FLAG,
  351. .elem_len = 1,
  352. .elem_size = sizeof(u8),
  353. .array_type = NO_ARRAY,
  354. .tlv_type = 0x13,
  355. .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
  356. msa_ready_enable_valid),
  357. },
  358. {
  359. .data_type = QMI_UNSIGNED_1_BYTE,
  360. .elem_len = 1,
  361. .elem_size = sizeof(u8),
  362. .array_type = NO_ARRAY,
  363. .tlv_type = 0x13,
  364. .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
  365. msa_ready_enable),
  366. },
  367. {
  368. .data_type = QMI_OPT_FLAG,
  369. .elem_len = 1,
  370. .elem_size = sizeof(u8),
  371. .array_type = NO_ARRAY,
  372. .tlv_type = 0x14,
  373. .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
  374. pin_connect_result_enable_valid),
  375. },
  376. {
  377. .data_type = QMI_UNSIGNED_1_BYTE,
  378. .elem_len = 1,
  379. .elem_size = sizeof(u8),
  380. .array_type = NO_ARRAY,
  381. .tlv_type = 0x14,
  382. .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
  383. pin_connect_result_enable),
  384. },
  385. {
  386. .data_type = QMI_OPT_FLAG,
  387. .elem_len = 1,
  388. .elem_size = sizeof(u8),
  389. .array_type = NO_ARRAY,
  390. .tlv_type = 0x15,
  391. .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
  392. client_id_valid),
  393. },
  394. {
  395. .data_type = QMI_UNSIGNED_4_BYTE,
  396. .elem_len = 1,
  397. .elem_size = sizeof(u32),
  398. .array_type = NO_ARRAY,
  399. .tlv_type = 0x15,
  400. .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
  401. client_id),
  402. },
  403. {
  404. .data_type = QMI_OPT_FLAG,
  405. .elem_len = 1,
  406. .elem_size = sizeof(u8),
  407. .array_type = NO_ARRAY,
  408. .tlv_type = 0x16,
  409. .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
  410. request_mem_enable_valid),
  411. },
  412. {
  413. .data_type = QMI_UNSIGNED_1_BYTE,
  414. .elem_len = 1,
  415. .elem_size = sizeof(u8),
  416. .array_type = NO_ARRAY,
  417. .tlv_type = 0x16,
  418. .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
  419. request_mem_enable),
  420. },
  421. {
  422. .data_type = QMI_OPT_FLAG,
  423. .elem_len = 1,
  424. .elem_size = sizeof(u8),
  425. .array_type = NO_ARRAY,
  426. .tlv_type = 0x17,
  427. .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
  428. fw_mem_ready_enable_valid),
  429. },
  430. {
  431. .data_type = QMI_UNSIGNED_1_BYTE,
  432. .elem_len = 1,
  433. .elem_size = sizeof(u8),
  434. .array_type = NO_ARRAY,
  435. .tlv_type = 0x17,
  436. .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
  437. fw_mem_ready_enable),
  438. },
  439. {
  440. .data_type = QMI_OPT_FLAG,
  441. .elem_len = 1,
  442. .elem_size = sizeof(u8),
  443. .array_type = NO_ARRAY,
  444. .tlv_type = 0x18,
  445. .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
  446. fw_init_done_enable_valid),
  447. },
  448. {
  449. .data_type = QMI_UNSIGNED_1_BYTE,
  450. .elem_len = 1,
  451. .elem_size = sizeof(u8),
  452. .array_type = NO_ARRAY,
  453. .tlv_type = 0x18,
  454. .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
  455. fw_init_done_enable),
  456. },
  457. {
  458. .data_type = QMI_OPT_FLAG,
  459. .elem_len = 1,
  460. .elem_size = sizeof(u8),
  461. .array_type = NO_ARRAY,
  462. .tlv_type = 0x19,
  463. .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
  464. rejuvenate_enable_valid),
  465. },
  466. {
  467. .data_type = QMI_UNSIGNED_1_BYTE,
  468. .elem_len = 1,
  469. .elem_size = sizeof(u8),
  470. .array_type = NO_ARRAY,
  471. .tlv_type = 0x19,
  472. .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
  473. rejuvenate_enable),
  474. },
  475. {
  476. .data_type = QMI_OPT_FLAG,
  477. .elem_len = 1,
  478. .elem_size = sizeof(u8),
  479. .array_type = NO_ARRAY,
  480. .tlv_type = 0x1A,
  481. .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
  482. xo_cal_enable_valid),
  483. },
  484. {
  485. .data_type = QMI_UNSIGNED_1_BYTE,
  486. .elem_len = 1,
  487. .elem_size = sizeof(u8),
  488. .array_type = NO_ARRAY,
  489. .tlv_type = 0x1A,
  490. .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
  491. xo_cal_enable),
  492. },
  493. {
  494. .data_type = QMI_OPT_FLAG,
  495. .elem_len = 1,
  496. .elem_size = sizeof(u8),
  497. .array_type = NO_ARRAY,
  498. .tlv_type = 0x1B,
  499. .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
  500. cal_done_enable_valid),
  501. },
  502. {
  503. .data_type = QMI_UNSIGNED_1_BYTE,
  504. .elem_len = 1,
  505. .elem_size = sizeof(u8),
  506. .array_type = NO_ARRAY,
  507. .tlv_type = 0x1B,
  508. .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
  509. cal_done_enable),
  510. },
  511. {
  512. .data_type = QMI_EOTI,
  513. .array_type = NO_ARRAY,
  514. .tlv_type = QMI_COMMON_TLV_TYPE,
  515. },
  516. };
  517. static const struct qmi_elem_info qmi_wlanfw_ind_register_resp_msg_v01_ei[] = {
  518. {
  519. .data_type = QMI_STRUCT,
  520. .elem_len = 1,
  521. .elem_size = sizeof(struct qmi_response_type_v01),
  522. .array_type = NO_ARRAY,
  523. .tlv_type = 0x02,
  524. .offset = offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,
  525. resp),
  526. .ei_array = qmi_response_type_v01_ei,
  527. },
  528. {
  529. .data_type = QMI_OPT_FLAG,
  530. .elem_len = 1,
  531. .elem_size = sizeof(u8),
  532. .array_type = NO_ARRAY,
  533. .tlv_type = 0x10,
  534. .offset = offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,
  535. fw_status_valid),
  536. },
  537. {
  538. .data_type = QMI_UNSIGNED_8_BYTE,
  539. .elem_len = 1,
  540. .elem_size = sizeof(u64),
  541. .array_type = NO_ARRAY,
  542. .tlv_type = 0x10,
  543. .offset = offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,
  544. fw_status),
  545. },
  546. {
  547. .data_type = QMI_EOTI,
  548. .array_type = NO_ARRAY,
  549. .tlv_type = QMI_COMMON_TLV_TYPE,
  550. },
  551. };
  552. static const struct qmi_elem_info qmi_wlanfw_mem_cfg_s_v01_ei[] = {
  553. {
  554. .data_type = QMI_UNSIGNED_8_BYTE,
  555. .elem_len = 1,
  556. .elem_size = sizeof(u64),
  557. .array_type = NO_ARRAY,
  558. .tlv_type = 0,
  559. .offset = offsetof(struct qmi_wlanfw_mem_cfg_s_v01, offset),
  560. },
  561. {
  562. .data_type = QMI_UNSIGNED_4_BYTE,
  563. .elem_len = 1,
  564. .elem_size = sizeof(u32),
  565. .array_type = NO_ARRAY,
  566. .tlv_type = 0,
  567. .offset = offsetof(struct qmi_wlanfw_mem_cfg_s_v01, size),
  568. },
  569. {
  570. .data_type = QMI_UNSIGNED_1_BYTE,
  571. .elem_len = 1,
  572. .elem_size = sizeof(u8),
  573. .array_type = NO_ARRAY,
  574. .tlv_type = 0,
  575. .offset = offsetof(struct qmi_wlanfw_mem_cfg_s_v01, secure_flag),
  576. },
  577. {
  578. .data_type = QMI_EOTI,
  579. .array_type = NO_ARRAY,
  580. .tlv_type = QMI_COMMON_TLV_TYPE,
  581. },
  582. };
  583. static const struct qmi_elem_info qmi_wlanfw_mem_seg_s_v01_ei[] = {
  584. {
  585. .data_type = QMI_UNSIGNED_4_BYTE,
  586. .elem_len = 1,
  587. .elem_size = sizeof(u32),
  588. .array_type = NO_ARRAY,
  589. .tlv_type = 0,
  590. .offset = offsetof(struct qmi_wlanfw_mem_seg_s_v01,
  591. size),
  592. },
  593. {
  594. .data_type = QMI_SIGNED_4_BYTE_ENUM,
  595. .elem_len = 1,
  596. .elem_size = sizeof(enum qmi_wlanfw_mem_type_enum_v01),
  597. .array_type = NO_ARRAY,
  598. .tlv_type = 0,
  599. .offset = offsetof(struct qmi_wlanfw_mem_seg_s_v01, type),
  600. },
  601. {
  602. .data_type = QMI_DATA_LEN,
  603. .elem_len = 1,
  604. .elem_size = sizeof(u8),
  605. .array_type = NO_ARRAY,
  606. .tlv_type = 0,
  607. .offset = offsetof(struct qmi_wlanfw_mem_seg_s_v01, mem_cfg_len),
  608. },
  609. {
  610. .data_type = QMI_STRUCT,
  611. .elem_len = QMI_WLANFW_MAX_NUM_MEM_CFG_V01,
  612. .elem_size = sizeof(struct qmi_wlanfw_mem_cfg_s_v01),
  613. .array_type = VAR_LEN_ARRAY,
  614. .tlv_type = 0,
  615. .offset = offsetof(struct qmi_wlanfw_mem_seg_s_v01, mem_cfg),
  616. .ei_array = qmi_wlanfw_mem_cfg_s_v01_ei,
  617. },
  618. {
  619. .data_type = QMI_EOTI,
  620. .array_type = NO_ARRAY,
  621. .tlv_type = QMI_COMMON_TLV_TYPE,
  622. },
  623. };
  624. static const struct qmi_elem_info qmi_wlanfw_request_mem_ind_msg_v01_ei[] = {
  625. {
  626. .data_type = QMI_DATA_LEN,
  627. .elem_len = 1,
  628. .elem_size = sizeof(u8),
  629. .array_type = NO_ARRAY,
  630. .tlv_type = 0x01,
  631. .offset = offsetof(struct qmi_wlanfw_request_mem_ind_msg_v01,
  632. mem_seg_len),
  633. },
  634. {
  635. .data_type = QMI_STRUCT,
  636. .elem_len = ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01,
  637. .elem_size = sizeof(struct qmi_wlanfw_mem_seg_s_v01),
  638. .array_type = VAR_LEN_ARRAY,
  639. .tlv_type = 0x01,
  640. .offset = offsetof(struct qmi_wlanfw_request_mem_ind_msg_v01,
  641. mem_seg),
  642. .ei_array = qmi_wlanfw_mem_seg_s_v01_ei,
  643. },
  644. {
  645. .data_type = QMI_EOTI,
  646. .array_type = NO_ARRAY,
  647. .tlv_type = QMI_COMMON_TLV_TYPE,
  648. },
  649. };
  650. static const struct qmi_elem_info qmi_wlanfw_mem_seg_resp_s_v01_ei[] = {
  651. {
  652. .data_type = QMI_UNSIGNED_8_BYTE,
  653. .elem_len = 1,
  654. .elem_size = sizeof(u64),
  655. .array_type = NO_ARRAY,
  656. .tlv_type = 0,
  657. .offset = offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, addr),
  658. },
  659. {
  660. .data_type = QMI_UNSIGNED_4_BYTE,
  661. .elem_len = 1,
  662. .elem_size = sizeof(u32),
  663. .array_type = NO_ARRAY,
  664. .tlv_type = 0,
  665. .offset = offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, size),
  666. },
  667. {
  668. .data_type = QMI_SIGNED_4_BYTE_ENUM,
  669. .elem_len = 1,
  670. .elem_size = sizeof(enum qmi_wlanfw_mem_type_enum_v01),
  671. .array_type = NO_ARRAY,
  672. .tlv_type = 0,
  673. .offset = offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, type),
  674. },
  675. {
  676. .data_type = QMI_UNSIGNED_1_BYTE,
  677. .elem_len = 1,
  678. .elem_size = sizeof(u8),
  679. .array_type = NO_ARRAY,
  680. .tlv_type = 0,
  681. .offset = offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, restore),
  682. },
  683. {
  684. .data_type = QMI_EOTI,
  685. .array_type = NO_ARRAY,
  686. .tlv_type = QMI_COMMON_TLV_TYPE,
  687. },
  688. };
  689. static const struct qmi_elem_info qmi_wlanfw_respond_mem_req_msg_v01_ei[] = {
  690. {
  691. .data_type = QMI_DATA_LEN,
  692. .elem_len = 1,
  693. .elem_size = sizeof(u8),
  694. .array_type = NO_ARRAY,
  695. .tlv_type = 0x01,
  696. .offset = offsetof(struct qmi_wlanfw_respond_mem_req_msg_v01,
  697. mem_seg_len),
  698. },
  699. {
  700. .data_type = QMI_STRUCT,
  701. .elem_len = ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01,
  702. .elem_size = sizeof(struct qmi_wlanfw_mem_seg_resp_s_v01),
  703. .array_type = VAR_LEN_ARRAY,
  704. .tlv_type = 0x01,
  705. .offset = offsetof(struct qmi_wlanfw_respond_mem_req_msg_v01,
  706. mem_seg),
  707. .ei_array = qmi_wlanfw_mem_seg_resp_s_v01_ei,
  708. },
  709. {
  710. .data_type = QMI_EOTI,
  711. .array_type = NO_ARRAY,
  712. .tlv_type = QMI_COMMON_TLV_TYPE,
  713. },
  714. };
  715. static const struct qmi_elem_info qmi_wlanfw_respond_mem_resp_msg_v01_ei[] = {
  716. {
  717. .data_type = QMI_STRUCT,
  718. .elem_len = 1,
  719. .elem_size = sizeof(struct qmi_response_type_v01),
  720. .array_type = NO_ARRAY,
  721. .tlv_type = 0x02,
  722. .offset = offsetof(struct qmi_wlanfw_respond_mem_resp_msg_v01,
  723. resp),
  724. .ei_array = qmi_response_type_v01_ei,
  725. },
  726. {
  727. .data_type = QMI_EOTI,
  728. .array_type = NO_ARRAY,
  729. .tlv_type = QMI_COMMON_TLV_TYPE,
  730. },
  731. };
  732. static const struct qmi_elem_info qmi_wlanfw_cap_req_msg_v01_ei[] = {
  733. {
  734. .data_type = QMI_EOTI,
  735. .array_type = NO_ARRAY,
  736. .tlv_type = QMI_COMMON_TLV_TYPE,
  737. },
  738. };
  739. static const struct qmi_elem_info qmi_wlanfw_device_info_req_msg_v01_ei[] = {
  740. {
  741. .data_type = QMI_EOTI,
  742. .array_type = NO_ARRAY,
  743. .tlv_type = QMI_COMMON_TLV_TYPE,
  744. },
  745. };
  746. static const struct qmi_elem_info qmi_wlfw_device_info_resp_msg_v01_ei[] = {
  747. {
  748. .data_type = QMI_STRUCT,
  749. .elem_len = 1,
  750. .elem_size = sizeof(struct qmi_response_type_v01),
  751. .array_type = NO_ARRAY,
  752. .tlv_type = 0x02,
  753. .offset = offsetof(struct qmi_wlanfw_device_info_resp_msg_v01,
  754. resp),
  755. .ei_array = qmi_response_type_v01_ei,
  756. },
  757. {
  758. .data_type = QMI_OPT_FLAG,
  759. .elem_len = 1,
  760. .elem_size = sizeof(u8),
  761. .array_type = NO_ARRAY,
  762. .tlv_type = 0x10,
  763. .offset = offsetof(struct qmi_wlanfw_device_info_resp_msg_v01,
  764. bar_addr_valid),
  765. },
  766. {
  767. .data_type = QMI_UNSIGNED_8_BYTE,
  768. .elem_len = 1,
  769. .elem_size = sizeof(u64),
  770. .array_type = NO_ARRAY,
  771. .tlv_type = 0x10,
  772. .offset = offsetof(struct qmi_wlanfw_device_info_resp_msg_v01,
  773. bar_addr),
  774. },
  775. {
  776. .data_type = QMI_OPT_FLAG,
  777. .elem_len = 1,
  778. .elem_size = sizeof(u8),
  779. .array_type = NO_ARRAY,
  780. .tlv_type = 0x11,
  781. .offset = offsetof(struct qmi_wlanfw_device_info_resp_msg_v01,
  782. bar_size_valid),
  783. },
  784. {
  785. .data_type = QMI_UNSIGNED_4_BYTE,
  786. .elem_len = 1,
  787. .elem_size = sizeof(u32),
  788. .array_type = NO_ARRAY,
  789. .tlv_type = 0x11,
  790. .offset = offsetof(struct qmi_wlanfw_device_info_resp_msg_v01,
  791. bar_size),
  792. },
  793. {
  794. .data_type = QMI_EOTI,
  795. .array_type = NO_ARRAY,
  796. .tlv_type = QMI_COMMON_TLV_TYPE,
  797. },
  798. };
  799. static const struct qmi_elem_info qmi_wlanfw_rf_chip_info_s_v01_ei[] = {
  800. {
  801. .data_type = QMI_UNSIGNED_4_BYTE,
  802. .elem_len = 1,
  803. .elem_size = sizeof(u32),
  804. .array_type = NO_ARRAY,
  805. .tlv_type = 0,
  806. .offset = offsetof(struct qmi_wlanfw_rf_chip_info_s_v01,
  807. chip_id),
  808. },
  809. {
  810. .data_type = QMI_UNSIGNED_4_BYTE,
  811. .elem_len = 1,
  812. .elem_size = sizeof(u32),
  813. .array_type = NO_ARRAY,
  814. .tlv_type = 0,
  815. .offset = offsetof(struct qmi_wlanfw_rf_chip_info_s_v01,
  816. chip_family),
  817. },
  818. {
  819. .data_type = QMI_EOTI,
  820. .array_type = NO_ARRAY,
  821. .tlv_type = QMI_COMMON_TLV_TYPE,
  822. },
  823. };
  824. static const struct qmi_elem_info qmi_wlanfw_rf_board_info_s_v01_ei[] = {
  825. {
  826. .data_type = QMI_UNSIGNED_4_BYTE,
  827. .elem_len = 1,
  828. .elem_size = sizeof(u32),
  829. .array_type = NO_ARRAY,
  830. .tlv_type = 0,
  831. .offset = offsetof(struct qmi_wlanfw_rf_board_info_s_v01,
  832. board_id),
  833. },
  834. {
  835. .data_type = QMI_EOTI,
  836. .array_type = NO_ARRAY,
  837. .tlv_type = QMI_COMMON_TLV_TYPE,
  838. },
  839. };
  840. static const struct qmi_elem_info qmi_wlanfw_soc_info_s_v01_ei[] = {
  841. {
  842. .data_type = QMI_UNSIGNED_4_BYTE,
  843. .elem_len = 1,
  844. .elem_size = sizeof(u32),
  845. .array_type = NO_ARRAY,
  846. .tlv_type = 0,
  847. .offset = offsetof(struct qmi_wlanfw_soc_info_s_v01, soc_id),
  848. },
  849. {
  850. .data_type = QMI_EOTI,
  851. .array_type = NO_ARRAY,
  852. .tlv_type = QMI_COMMON_TLV_TYPE,
  853. },
  854. };
  855. static const struct qmi_elem_info qmi_wlanfw_fw_version_info_s_v01_ei[] = {
  856. {
  857. .data_type = QMI_UNSIGNED_4_BYTE,
  858. .elem_len = 1,
  859. .elem_size = sizeof(u32),
  860. .array_type = NO_ARRAY,
  861. .tlv_type = 0,
  862. .offset = offsetof(struct qmi_wlanfw_fw_version_info_s_v01,
  863. fw_version),
  864. },
  865. {
  866. .data_type = QMI_STRING,
  867. .elem_len = ATH11K_QMI_WLANFW_MAX_TIMESTAMP_LEN_V01 + 1,
  868. .elem_size = sizeof(char),
  869. .array_type = NO_ARRAY,
  870. .tlv_type = 0,
  871. .offset = offsetof(struct qmi_wlanfw_fw_version_info_s_v01,
  872. fw_build_timestamp),
  873. },
  874. {
  875. .data_type = QMI_EOTI,
  876. .array_type = NO_ARRAY,
  877. .tlv_type = QMI_COMMON_TLV_TYPE,
  878. },
  879. };
  880. static const struct qmi_elem_info qmi_wlanfw_cap_resp_msg_v01_ei[] = {
  881. {
  882. .data_type = QMI_STRUCT,
  883. .elem_len = 1,
  884. .elem_size = sizeof(struct qmi_response_type_v01),
  885. .array_type = NO_ARRAY,
  886. .tlv_type = 0x02,
  887. .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, resp),
  888. .ei_array = qmi_response_type_v01_ei,
  889. },
  890. {
  891. .data_type = QMI_OPT_FLAG,
  892. .elem_len = 1,
  893. .elem_size = sizeof(u8),
  894. .array_type = NO_ARRAY,
  895. .tlv_type = 0x10,
  896. .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
  897. chip_info_valid),
  898. },
  899. {
  900. .data_type = QMI_STRUCT,
  901. .elem_len = 1,
  902. .elem_size = sizeof(struct qmi_wlanfw_rf_chip_info_s_v01),
  903. .array_type = NO_ARRAY,
  904. .tlv_type = 0x10,
  905. .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
  906. chip_info),
  907. .ei_array = qmi_wlanfw_rf_chip_info_s_v01_ei,
  908. },
  909. {
  910. .data_type = QMI_OPT_FLAG,
  911. .elem_len = 1,
  912. .elem_size = sizeof(u8),
  913. .array_type = NO_ARRAY,
  914. .tlv_type = 0x11,
  915. .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
  916. board_info_valid),
  917. },
  918. {
  919. .data_type = QMI_STRUCT,
  920. .elem_len = 1,
  921. .elem_size = sizeof(struct qmi_wlanfw_rf_board_info_s_v01),
  922. .array_type = NO_ARRAY,
  923. .tlv_type = 0x11,
  924. .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
  925. board_info),
  926. .ei_array = qmi_wlanfw_rf_board_info_s_v01_ei,
  927. },
  928. {
  929. .data_type = QMI_OPT_FLAG,
  930. .elem_len = 1,
  931. .elem_size = sizeof(u8),
  932. .array_type = NO_ARRAY,
  933. .tlv_type = 0x12,
  934. .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
  935. soc_info_valid),
  936. },
  937. {
  938. .data_type = QMI_STRUCT,
  939. .elem_len = 1,
  940. .elem_size = sizeof(struct qmi_wlanfw_soc_info_s_v01),
  941. .array_type = NO_ARRAY,
  942. .tlv_type = 0x12,
  943. .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
  944. soc_info),
  945. .ei_array = qmi_wlanfw_soc_info_s_v01_ei,
  946. },
  947. {
  948. .data_type = QMI_OPT_FLAG,
  949. .elem_len = 1,
  950. .elem_size = sizeof(u8),
  951. .array_type = NO_ARRAY,
  952. .tlv_type = 0x13,
  953. .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
  954. fw_version_info_valid),
  955. },
  956. {
  957. .data_type = QMI_STRUCT,
  958. .elem_len = 1,
  959. .elem_size = sizeof(struct qmi_wlanfw_fw_version_info_s_v01),
  960. .array_type = NO_ARRAY,
  961. .tlv_type = 0x13,
  962. .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
  963. fw_version_info),
  964. .ei_array = qmi_wlanfw_fw_version_info_s_v01_ei,
  965. },
  966. {
  967. .data_type = QMI_OPT_FLAG,
  968. .elem_len = 1,
  969. .elem_size = sizeof(u8),
  970. .array_type = NO_ARRAY,
  971. .tlv_type = 0x14,
  972. .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
  973. fw_build_id_valid),
  974. },
  975. {
  976. .data_type = QMI_STRING,
  977. .elem_len = ATH11K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 + 1,
  978. .elem_size = sizeof(char),
  979. .array_type = NO_ARRAY,
  980. .tlv_type = 0x14,
  981. .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
  982. fw_build_id),
  983. },
  984. {
  985. .data_type = QMI_OPT_FLAG,
  986. .elem_len = 1,
  987. .elem_size = sizeof(u8),
  988. .array_type = NO_ARRAY,
  989. .tlv_type = 0x15,
  990. .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
  991. num_macs_valid),
  992. },
  993. {
  994. .data_type = QMI_UNSIGNED_1_BYTE,
  995. .elem_len = 1,
  996. .elem_size = sizeof(u8),
  997. .array_type = NO_ARRAY,
  998. .tlv_type = 0x15,
  999. .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
  1000. num_macs),
  1001. },
  1002. {
  1003. .data_type = QMI_OPT_FLAG,
  1004. .elem_len = 1,
  1005. .elem_size = sizeof(u8),
  1006. .array_type = NO_ARRAY,
  1007. .tlv_type = 0x16,
  1008. .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
  1009. voltage_mv_valid),
  1010. },
  1011. {
  1012. .data_type = QMI_UNSIGNED_4_BYTE,
  1013. .elem_len = 1,
  1014. .elem_size = sizeof(u32),
  1015. .array_type = NO_ARRAY,
  1016. .tlv_type = 0x16,
  1017. .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
  1018. voltage_mv),
  1019. },
  1020. {
  1021. .data_type = QMI_OPT_FLAG,
  1022. .elem_len = 1,
  1023. .elem_size = sizeof(u8),
  1024. .array_type = NO_ARRAY,
  1025. .tlv_type = 0x17,
  1026. .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
  1027. time_freq_hz_valid),
  1028. },
  1029. {
  1030. .data_type = QMI_UNSIGNED_4_BYTE,
  1031. .elem_len = 1,
  1032. .elem_size = sizeof(u32),
  1033. .array_type = NO_ARRAY,
  1034. .tlv_type = 0x17,
  1035. .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
  1036. time_freq_hz),
  1037. },
  1038. {
  1039. .data_type = QMI_OPT_FLAG,
  1040. .elem_len = 1,
  1041. .elem_size = sizeof(u8),
  1042. .array_type = NO_ARRAY,
  1043. .tlv_type = 0x18,
  1044. .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
  1045. otp_version_valid),
  1046. },
  1047. {
  1048. .data_type = QMI_UNSIGNED_4_BYTE,
  1049. .elem_len = 1,
  1050. .elem_size = sizeof(u32),
  1051. .array_type = NO_ARRAY,
  1052. .tlv_type = 0x18,
  1053. .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
  1054. otp_version),
  1055. },
  1056. {
  1057. .data_type = QMI_OPT_FLAG,
  1058. .elem_len = 1,
  1059. .elem_size = sizeof(u8),
  1060. .array_type = NO_ARRAY,
  1061. .tlv_type = 0x19,
  1062. .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
  1063. eeprom_read_timeout_valid),
  1064. },
  1065. {
  1066. .data_type = QMI_UNSIGNED_4_BYTE,
  1067. .elem_len = 1,
  1068. .elem_size = sizeof(u32),
  1069. .array_type = NO_ARRAY,
  1070. .tlv_type = 0x19,
  1071. .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
  1072. eeprom_read_timeout),
  1073. },
  1074. {
  1075. .data_type = QMI_EOTI,
  1076. .array_type = NO_ARRAY,
  1077. .tlv_type = QMI_COMMON_TLV_TYPE,
  1078. },
  1079. };
  1080. static const struct qmi_elem_info qmi_wlanfw_bdf_download_req_msg_v01_ei[] = {
  1081. {
  1082. .data_type = QMI_UNSIGNED_1_BYTE,
  1083. .elem_len = 1,
  1084. .elem_size = sizeof(u8),
  1085. .array_type = NO_ARRAY,
  1086. .tlv_type = 0x01,
  1087. .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
  1088. valid),
  1089. },
  1090. {
  1091. .data_type = QMI_OPT_FLAG,
  1092. .elem_len = 1,
  1093. .elem_size = sizeof(u8),
  1094. .array_type = NO_ARRAY,
  1095. .tlv_type = 0x10,
  1096. .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
  1097. file_id_valid),
  1098. },
  1099. {
  1100. .data_type = QMI_SIGNED_4_BYTE_ENUM,
  1101. .elem_len = 1,
  1102. .elem_size = sizeof(enum qmi_wlanfw_cal_temp_id_enum_v01),
  1103. .array_type = NO_ARRAY,
  1104. .tlv_type = 0x10,
  1105. .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
  1106. file_id),
  1107. },
  1108. {
  1109. .data_type = QMI_OPT_FLAG,
  1110. .elem_len = 1,
  1111. .elem_size = sizeof(u8),
  1112. .array_type = NO_ARRAY,
  1113. .tlv_type = 0x11,
  1114. .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
  1115. total_size_valid),
  1116. },
  1117. {
  1118. .data_type = QMI_UNSIGNED_4_BYTE,
  1119. .elem_len = 1,
  1120. .elem_size = sizeof(u32),
  1121. .array_type = NO_ARRAY,
  1122. .tlv_type = 0x11,
  1123. .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
  1124. total_size),
  1125. },
  1126. {
  1127. .data_type = QMI_OPT_FLAG,
  1128. .elem_len = 1,
  1129. .elem_size = sizeof(u8),
  1130. .array_type = NO_ARRAY,
  1131. .tlv_type = 0x12,
  1132. .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
  1133. seg_id_valid),
  1134. },
  1135. {
  1136. .data_type = QMI_UNSIGNED_4_BYTE,
  1137. .elem_len = 1,
  1138. .elem_size = sizeof(u32),
  1139. .array_type = NO_ARRAY,
  1140. .tlv_type = 0x12,
  1141. .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
  1142. seg_id),
  1143. },
  1144. {
  1145. .data_type = QMI_OPT_FLAG,
  1146. .elem_len = 1,
  1147. .elem_size = sizeof(u8),
  1148. .array_type = NO_ARRAY,
  1149. .tlv_type = 0x13,
  1150. .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
  1151. data_valid),
  1152. },
  1153. {
  1154. .data_type = QMI_DATA_LEN,
  1155. .elem_len = 1,
  1156. .elem_size = sizeof(u16),
  1157. .array_type = NO_ARRAY,
  1158. .tlv_type = 0x13,
  1159. .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
  1160. data_len),
  1161. },
  1162. {
  1163. .data_type = QMI_UNSIGNED_1_BYTE,
  1164. .elem_len = QMI_WLANFW_MAX_DATA_SIZE_V01,
  1165. .elem_size = sizeof(u8),
  1166. .array_type = VAR_LEN_ARRAY,
  1167. .tlv_type = 0x13,
  1168. .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
  1169. data),
  1170. },
  1171. {
  1172. .data_type = QMI_OPT_FLAG,
  1173. .elem_len = 1,
  1174. .elem_size = sizeof(u8),
  1175. .array_type = NO_ARRAY,
  1176. .tlv_type = 0x14,
  1177. .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
  1178. end_valid),
  1179. },
  1180. {
  1181. .data_type = QMI_UNSIGNED_1_BYTE,
  1182. .elem_len = 1,
  1183. .elem_size = sizeof(u8),
  1184. .array_type = NO_ARRAY,
  1185. .tlv_type = 0x14,
  1186. .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
  1187. end),
  1188. },
  1189. {
  1190. .data_type = QMI_OPT_FLAG,
  1191. .elem_len = 1,
  1192. .elem_size = sizeof(u8),
  1193. .array_type = NO_ARRAY,
  1194. .tlv_type = 0x15,
  1195. .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
  1196. bdf_type_valid),
  1197. },
  1198. {
  1199. .data_type = QMI_UNSIGNED_1_BYTE,
  1200. .elem_len = 1,
  1201. .elem_size = sizeof(u8),
  1202. .array_type = NO_ARRAY,
  1203. .tlv_type = 0x15,
  1204. .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
  1205. bdf_type),
  1206. },
  1207. {
  1208. .data_type = QMI_EOTI,
  1209. .array_type = NO_ARRAY,
  1210. .tlv_type = QMI_COMMON_TLV_TYPE,
  1211. },
  1212. };
  1213. static const struct qmi_elem_info qmi_wlanfw_bdf_download_resp_msg_v01_ei[] = {
  1214. {
  1215. .data_type = QMI_STRUCT,
  1216. .elem_len = 1,
  1217. .elem_size = sizeof(struct qmi_response_type_v01),
  1218. .array_type = NO_ARRAY,
  1219. .tlv_type = 0x02,
  1220. .offset = offsetof(struct qmi_wlanfw_bdf_download_resp_msg_v01,
  1221. resp),
  1222. .ei_array = qmi_response_type_v01_ei,
  1223. },
  1224. {
  1225. .data_type = QMI_EOTI,
  1226. .array_type = NO_ARRAY,
  1227. .tlv_type = QMI_COMMON_TLV_TYPE,
  1228. },
  1229. };
  1230. static const struct qmi_elem_info qmi_wlanfw_m3_info_req_msg_v01_ei[] = {
  1231. {
  1232. .data_type = QMI_UNSIGNED_8_BYTE,
  1233. .elem_len = 1,
  1234. .elem_size = sizeof(u64),
  1235. .array_type = NO_ARRAY,
  1236. .tlv_type = 0x01,
  1237. .offset = offsetof(struct qmi_wlanfw_m3_info_req_msg_v01, addr),
  1238. },
  1239. {
  1240. .data_type = QMI_UNSIGNED_4_BYTE,
  1241. .elem_len = 1,
  1242. .elem_size = sizeof(u32),
  1243. .array_type = NO_ARRAY,
  1244. .tlv_type = 0x02,
  1245. .offset = offsetof(struct qmi_wlanfw_m3_info_req_msg_v01, size),
  1246. },
  1247. {
  1248. .data_type = QMI_EOTI,
  1249. .array_type = NO_ARRAY,
  1250. .tlv_type = QMI_COMMON_TLV_TYPE,
  1251. },
  1252. };
  1253. static const struct qmi_elem_info qmi_wlanfw_m3_info_resp_msg_v01_ei[] = {
  1254. {
  1255. .data_type = QMI_STRUCT,
  1256. .elem_len = 1,
  1257. .elem_size = sizeof(struct qmi_response_type_v01),
  1258. .array_type = NO_ARRAY,
  1259. .tlv_type = 0x02,
  1260. .offset = offsetof(struct qmi_wlanfw_m3_info_resp_msg_v01, resp),
  1261. .ei_array = qmi_response_type_v01_ei,
  1262. },
  1263. {
  1264. .data_type = QMI_EOTI,
  1265. .array_type = NO_ARRAY,
  1266. .tlv_type = QMI_COMMON_TLV_TYPE,
  1267. },
  1268. };
  1269. static const struct qmi_elem_info qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei[] = {
  1270. {
  1271. .data_type = QMI_UNSIGNED_4_BYTE,
  1272. .elem_len = 1,
  1273. .elem_size = sizeof(u32),
  1274. .array_type = NO_ARRAY,
  1275. .tlv_type = 0,
  1276. .offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
  1277. pipe_num),
  1278. },
  1279. {
  1280. .data_type = QMI_SIGNED_4_BYTE_ENUM,
  1281. .elem_len = 1,
  1282. .elem_size = sizeof(enum qmi_wlanfw_pipedir_enum_v01),
  1283. .array_type = NO_ARRAY,
  1284. .tlv_type = 0,
  1285. .offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
  1286. pipe_dir),
  1287. },
  1288. {
  1289. .data_type = QMI_UNSIGNED_4_BYTE,
  1290. .elem_len = 1,
  1291. .elem_size = sizeof(u32),
  1292. .array_type = NO_ARRAY,
  1293. .tlv_type = 0,
  1294. .offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
  1295. nentries),
  1296. },
  1297. {
  1298. .data_type = QMI_UNSIGNED_4_BYTE,
  1299. .elem_len = 1,
  1300. .elem_size = sizeof(u32),
  1301. .array_type = NO_ARRAY,
  1302. .tlv_type = 0,
  1303. .offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
  1304. nbytes_max),
  1305. },
  1306. {
  1307. .data_type = QMI_UNSIGNED_4_BYTE,
  1308. .elem_len = 1,
  1309. .elem_size = sizeof(u32),
  1310. .array_type = NO_ARRAY,
  1311. .tlv_type = 0,
  1312. .offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
  1313. flags),
  1314. },
  1315. {
  1316. .data_type = QMI_EOTI,
  1317. .array_type = NO_ARRAY,
  1318. .tlv_type = QMI_COMMON_TLV_TYPE,
  1319. },
  1320. };
  1321. static const struct qmi_elem_info qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei[] = {
  1322. {
  1323. .data_type = QMI_UNSIGNED_4_BYTE,
  1324. .elem_len = 1,
  1325. .elem_size = sizeof(u32),
  1326. .array_type = NO_ARRAY,
  1327. .tlv_type = 0,
  1328. .offset = offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,
  1329. service_id),
  1330. },
  1331. {
  1332. .data_type = QMI_SIGNED_4_BYTE_ENUM,
  1333. .elem_len = 1,
  1334. .elem_size = sizeof(enum qmi_wlanfw_pipedir_enum_v01),
  1335. .array_type = NO_ARRAY,
  1336. .tlv_type = 0,
  1337. .offset = offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,
  1338. pipe_dir),
  1339. },
  1340. {
  1341. .data_type = QMI_UNSIGNED_4_BYTE,
  1342. .elem_len = 1,
  1343. .elem_size = sizeof(u32),
  1344. .array_type = NO_ARRAY,
  1345. .tlv_type = 0,
  1346. .offset = offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,
  1347. pipe_num),
  1348. },
  1349. {
  1350. .data_type = QMI_EOTI,
  1351. .array_type = NO_ARRAY,
  1352. .tlv_type = QMI_COMMON_TLV_TYPE,
  1353. },
  1354. };
  1355. static const struct qmi_elem_info qmi_wlanfw_shadow_reg_cfg_s_v01_ei[] = {
  1356. {
  1357. .data_type = QMI_UNSIGNED_2_BYTE,
  1358. .elem_len = 1,
  1359. .elem_size = sizeof(u16),
  1360. .array_type = NO_ARRAY,
  1361. .tlv_type = 0,
  1362. .offset = offsetof(struct qmi_wlanfw_shadow_reg_cfg_s_v01, id),
  1363. },
  1364. {
  1365. .data_type = QMI_UNSIGNED_2_BYTE,
  1366. .elem_len = 1,
  1367. .elem_size = sizeof(u16),
  1368. .array_type = NO_ARRAY,
  1369. .tlv_type = 0,
  1370. .offset = offsetof(struct qmi_wlanfw_shadow_reg_cfg_s_v01,
  1371. offset),
  1372. },
  1373. {
  1374. .data_type = QMI_EOTI,
  1375. .array_type = QMI_COMMON_TLV_TYPE,
  1376. },
  1377. };
  1378. static const struct qmi_elem_info qmi_wlanfw_shadow_reg_v2_cfg_s_v01_ei[] = {
  1379. {
  1380. .data_type = QMI_UNSIGNED_4_BYTE,
  1381. .elem_len = 1,
  1382. .elem_size = sizeof(u32),
  1383. .array_type = NO_ARRAY,
  1384. .tlv_type = 0,
  1385. .offset = offsetof(struct qmi_wlanfw_shadow_reg_v2_cfg_s_v01,
  1386. addr),
  1387. },
  1388. {
  1389. .data_type = QMI_EOTI,
  1390. .array_type = NO_ARRAY,
  1391. .tlv_type = QMI_COMMON_TLV_TYPE,
  1392. },
  1393. };
  1394. static const struct qmi_elem_info qmi_wlanfw_wlan_mode_req_msg_v01_ei[] = {
  1395. {
  1396. .data_type = QMI_UNSIGNED_4_BYTE,
  1397. .elem_len = 1,
  1398. .elem_size = sizeof(u32),
  1399. .array_type = NO_ARRAY,
  1400. .tlv_type = 0x01,
  1401. .offset = offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,
  1402. mode),
  1403. },
  1404. {
  1405. .data_type = QMI_OPT_FLAG,
  1406. .elem_len = 1,
  1407. .elem_size = sizeof(u8),
  1408. .array_type = NO_ARRAY,
  1409. .tlv_type = 0x10,
  1410. .offset = offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,
  1411. hw_debug_valid),
  1412. },
  1413. {
  1414. .data_type = QMI_UNSIGNED_1_BYTE,
  1415. .elem_len = 1,
  1416. .elem_size = sizeof(u8),
  1417. .array_type = NO_ARRAY,
  1418. .tlv_type = 0x10,
  1419. .offset = offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,
  1420. hw_debug),
  1421. },
  1422. {
  1423. .data_type = QMI_EOTI,
  1424. .array_type = NO_ARRAY,
  1425. .tlv_type = QMI_COMMON_TLV_TYPE,
  1426. },
  1427. };
  1428. static const struct qmi_elem_info qmi_wlanfw_wlan_mode_resp_msg_v01_ei[] = {
  1429. {
  1430. .data_type = QMI_STRUCT,
  1431. .elem_len = 1,
  1432. .elem_size = sizeof(struct qmi_response_type_v01),
  1433. .array_type = NO_ARRAY,
  1434. .tlv_type = 0x02,
  1435. .offset = offsetof(struct qmi_wlanfw_wlan_mode_resp_msg_v01,
  1436. resp),
  1437. .ei_array = qmi_response_type_v01_ei,
  1438. },
  1439. {
  1440. .data_type = QMI_EOTI,
  1441. .array_type = NO_ARRAY,
  1442. .tlv_type = QMI_COMMON_TLV_TYPE,
  1443. },
  1444. };
  1445. static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_req_msg_v01_ei[] = {
  1446. {
  1447. .data_type = QMI_OPT_FLAG,
  1448. .elem_len = 1,
  1449. .elem_size = sizeof(u8),
  1450. .array_type = NO_ARRAY,
  1451. .tlv_type = 0x10,
  1452. .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
  1453. host_version_valid),
  1454. },
  1455. {
  1456. .data_type = QMI_STRING,
  1457. .elem_len = QMI_WLANFW_MAX_STR_LEN_V01 + 1,
  1458. .elem_size = sizeof(char),
  1459. .array_type = NO_ARRAY,
  1460. .tlv_type = 0x10,
  1461. .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
  1462. host_version),
  1463. },
  1464. {
  1465. .data_type = QMI_OPT_FLAG,
  1466. .elem_len = 1,
  1467. .elem_size = sizeof(u8),
  1468. .array_type = NO_ARRAY,
  1469. .tlv_type = 0x11,
  1470. .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
  1471. tgt_cfg_valid),
  1472. },
  1473. {
  1474. .data_type = QMI_DATA_LEN,
  1475. .elem_len = 1,
  1476. .elem_size = sizeof(u8),
  1477. .array_type = NO_ARRAY,
  1478. .tlv_type = 0x11,
  1479. .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
  1480. tgt_cfg_len),
  1481. },
  1482. {
  1483. .data_type = QMI_STRUCT,
  1484. .elem_len = QMI_WLANFW_MAX_NUM_CE_V01,
  1485. .elem_size = sizeof(
  1486. struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01),
  1487. .array_type = VAR_LEN_ARRAY,
  1488. .tlv_type = 0x11,
  1489. .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
  1490. tgt_cfg),
  1491. .ei_array = qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei,
  1492. },
  1493. {
  1494. .data_type = QMI_OPT_FLAG,
  1495. .elem_len = 1,
  1496. .elem_size = sizeof(u8),
  1497. .array_type = NO_ARRAY,
  1498. .tlv_type = 0x12,
  1499. .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
  1500. svc_cfg_valid),
  1501. },
  1502. {
  1503. .data_type = QMI_DATA_LEN,
  1504. .elem_len = 1,
  1505. .elem_size = sizeof(u8),
  1506. .array_type = NO_ARRAY,
  1507. .tlv_type = 0x12,
  1508. .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
  1509. svc_cfg_len),
  1510. },
  1511. {
  1512. .data_type = QMI_STRUCT,
  1513. .elem_len = QMI_WLANFW_MAX_NUM_SVC_V01,
  1514. .elem_size = sizeof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01),
  1515. .array_type = VAR_LEN_ARRAY,
  1516. .tlv_type = 0x12,
  1517. .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
  1518. svc_cfg),
  1519. .ei_array = qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei,
  1520. },
  1521. {
  1522. .data_type = QMI_OPT_FLAG,
  1523. .elem_len = 1,
  1524. .elem_size = sizeof(u8),
  1525. .array_type = NO_ARRAY,
  1526. .tlv_type = 0x13,
  1527. .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
  1528. shadow_reg_valid),
  1529. },
  1530. {
  1531. .data_type = QMI_DATA_LEN,
  1532. .elem_len = 1,
  1533. .elem_size = sizeof(u8),
  1534. .array_type = NO_ARRAY,
  1535. .tlv_type = 0x13,
  1536. .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
  1537. shadow_reg_len),
  1538. },
  1539. {
  1540. .data_type = QMI_STRUCT,
  1541. .elem_len = QMI_WLANFW_MAX_NUM_SHADOW_REG_V01,
  1542. .elem_size = sizeof(struct qmi_wlanfw_shadow_reg_cfg_s_v01),
  1543. .array_type = VAR_LEN_ARRAY,
  1544. .tlv_type = 0x13,
  1545. .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
  1546. shadow_reg),
  1547. .ei_array = qmi_wlanfw_shadow_reg_cfg_s_v01_ei,
  1548. },
  1549. {
  1550. .data_type = QMI_OPT_FLAG,
  1551. .elem_len = 1,
  1552. .elem_size = sizeof(u8),
  1553. .array_type = NO_ARRAY,
  1554. .tlv_type = 0x14,
  1555. .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
  1556. shadow_reg_v2_valid),
  1557. },
  1558. {
  1559. .data_type = QMI_DATA_LEN,
  1560. .elem_len = 1,
  1561. .elem_size = sizeof(u8),
  1562. .array_type = NO_ARRAY,
  1563. .tlv_type = 0x14,
  1564. .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
  1565. shadow_reg_v2_len),
  1566. },
  1567. {
  1568. .data_type = QMI_STRUCT,
  1569. .elem_len = QMI_WLANFW_MAX_NUM_SHADOW_REG_V2_V01,
  1570. .elem_size = sizeof(struct qmi_wlanfw_shadow_reg_v2_cfg_s_v01),
  1571. .array_type = VAR_LEN_ARRAY,
  1572. .tlv_type = 0x14,
  1573. .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
  1574. shadow_reg_v2),
  1575. .ei_array = qmi_wlanfw_shadow_reg_v2_cfg_s_v01_ei,
  1576. },
  1577. {
  1578. .data_type = QMI_EOTI,
  1579. .array_type = NO_ARRAY,
  1580. .tlv_type = QMI_COMMON_TLV_TYPE,
  1581. },
  1582. };
  1583. static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_resp_msg_v01_ei[] = {
  1584. {
  1585. .data_type = QMI_STRUCT,
  1586. .elem_len = 1,
  1587. .elem_size = sizeof(struct qmi_response_type_v01),
  1588. .array_type = NO_ARRAY,
  1589. .tlv_type = 0x02,
  1590. .offset = offsetof(struct qmi_wlanfw_wlan_cfg_resp_msg_v01, resp),
  1591. .ei_array = qmi_response_type_v01_ei,
  1592. },
  1593. {
  1594. .data_type = QMI_EOTI,
  1595. .array_type = NO_ARRAY,
  1596. .tlv_type = QMI_COMMON_TLV_TYPE,
  1597. },
  1598. };
  1599. static const struct qmi_elem_info qmi_wlanfw_mem_ready_ind_msg_v01_ei[] = {
  1600. {
  1601. .data_type = QMI_EOTI,
  1602. .array_type = NO_ARRAY,
  1603. },
  1604. };
  1605. static const struct qmi_elem_info qmi_wlanfw_fw_ready_ind_msg_v01_ei[] = {
  1606. {
  1607. .data_type = QMI_EOTI,
  1608. .array_type = NO_ARRAY,
  1609. },
  1610. };
  1611. static const struct qmi_elem_info qmi_wlanfw_cold_boot_cal_done_ind_msg_v01_ei[] = {
  1612. {
  1613. .data_type = QMI_EOTI,
  1614. .array_type = NO_ARRAY,
  1615. },
  1616. };
  1617. static const struct qmi_elem_info qmi_wlanfw_wlan_ini_req_msg_v01_ei[] = {
  1618. {
  1619. .data_type = QMI_OPT_FLAG,
  1620. .elem_len = 1,
  1621. .elem_size = sizeof(u8),
  1622. .array_type = NO_ARRAY,
  1623. .tlv_type = 0x10,
  1624. .offset = offsetof(struct qmi_wlanfw_wlan_ini_req_msg_v01,
  1625. enablefwlog_valid),
  1626. },
  1627. {
  1628. .data_type = QMI_UNSIGNED_1_BYTE,
  1629. .elem_len = 1,
  1630. .elem_size = sizeof(u8),
  1631. .array_type = NO_ARRAY,
  1632. .tlv_type = 0x10,
  1633. .offset = offsetof(struct qmi_wlanfw_wlan_ini_req_msg_v01,
  1634. enablefwlog),
  1635. },
  1636. {
  1637. .data_type = QMI_EOTI,
  1638. .array_type = NO_ARRAY,
  1639. .tlv_type = QMI_COMMON_TLV_TYPE,
  1640. },
  1641. };
  1642. static const struct qmi_elem_info qmi_wlanfw_wlan_ini_resp_msg_v01_ei[] = {
  1643. {
  1644. .data_type = QMI_STRUCT,
  1645. .elem_len = 1,
  1646. .elem_size = sizeof(struct qmi_response_type_v01),
  1647. .array_type = NO_ARRAY,
  1648. .tlv_type = 0x02,
  1649. .offset = offsetof(struct qmi_wlanfw_wlan_ini_resp_msg_v01,
  1650. resp),
  1651. .ei_array = qmi_response_type_v01_ei,
  1652. },
  1653. {
  1654. .data_type = QMI_EOTI,
  1655. .array_type = NO_ARRAY,
  1656. .tlv_type = QMI_COMMON_TLV_TYPE,
  1657. },
  1658. };
  1659. static const struct qmi_elem_info qmi_wlfw_fw_init_done_ind_msg_v01_ei[] = {
  1660. {
  1661. .data_type = QMI_EOTI,
  1662. .array_type = NO_ARRAY,
  1663. },
  1664. };
  1665. /* clang stack usage explodes if this is inlined */
  1666. static noinline_for_stack
  1667. int ath11k_qmi_host_cap_send(struct ath11k_base *ab)
  1668. {
  1669. struct qmi_wlanfw_host_cap_req_msg_v01 req;
  1670. struct qmi_wlanfw_host_cap_resp_msg_v01 resp;
  1671. struct qmi_txn txn;
  1672. int ret = 0;
  1673. memset(&req, 0, sizeof(req));
  1674. memset(&resp, 0, sizeof(resp));
  1675. req.num_clients_valid = 1;
  1676. req.num_clients = 1;
  1677. req.mem_cfg_mode = ab->qmi.target_mem_mode;
  1678. req.mem_cfg_mode_valid = 1;
  1679. req.bdf_support_valid = 1;
  1680. req.bdf_support = 1;
  1681. if (ab->hw_params.m3_fw_support) {
  1682. req.m3_support_valid = 1;
  1683. req.m3_support = 1;
  1684. req.m3_cache_support_valid = 1;
  1685. req.m3_cache_support = 1;
  1686. } else {
  1687. req.m3_support_valid = 0;
  1688. req.m3_support = 0;
  1689. req.m3_cache_support_valid = 0;
  1690. req.m3_cache_support = 0;
  1691. }
  1692. req.cal_done_valid = 1;
  1693. req.cal_done = ab->qmi.cal_done;
  1694. if (ab->hw_params.internal_sleep_clock) {
  1695. req.nm_modem_valid = 1;
  1696. /* Notify firmware that this is non-qualcomm platform. */
  1697. req.nm_modem |= HOST_CSTATE_BIT;
  1698. /* Notify firmware about the sleep clock selection,
  1699. * nm_modem_bit[1] is used for this purpose. Host driver on
  1700. * non-qualcomm platforms should select internal sleep
  1701. * clock.
  1702. */
  1703. req.nm_modem |= SLEEP_CLOCK_SELECT_INTERNAL_BIT;
  1704. }
  1705. if (ab->hw_params.global_reset)
  1706. req.nm_modem |= PLATFORM_CAP_PCIE_GLOBAL_RESET;
  1707. req.nm_modem |= PLATFORM_CAP_PCIE_PME_D3COLD;
  1708. ath11k_dbg(ab, ATH11K_DBG_QMI, "host cap request\n");
  1709. ret = qmi_txn_init(&ab->qmi.handle, &txn,
  1710. qmi_wlanfw_host_cap_resp_msg_v01_ei, &resp);
  1711. if (ret < 0)
  1712. goto out;
  1713. ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
  1714. QMI_WLANFW_HOST_CAP_REQ_V01,
  1715. QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN,
  1716. qmi_wlanfw_host_cap_req_msg_v01_ei, &req);
  1717. if (ret < 0) {
  1718. qmi_txn_cancel(&txn);
  1719. ath11k_warn(ab, "failed to send host capability request: %d\n", ret);
  1720. goto out;
  1721. }
  1722. ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
  1723. if (ret < 0)
  1724. goto out;
  1725. if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
  1726. ath11k_warn(ab, "host capability request failed: %d %d\n",
  1727. resp.resp.result, resp.resp.error);
  1728. ret = -EINVAL;
  1729. goto out;
  1730. }
  1731. out:
  1732. return ret;
  1733. }
  1734. static int ath11k_qmi_fw_ind_register_send(struct ath11k_base *ab)
  1735. {
  1736. struct qmi_wlanfw_ind_register_req_msg_v01 *req;
  1737. struct qmi_wlanfw_ind_register_resp_msg_v01 *resp;
  1738. struct qmi_handle *handle = &ab->qmi.handle;
  1739. struct qmi_txn txn;
  1740. int ret;
  1741. req = kzalloc_obj(*req);
  1742. if (!req)
  1743. return -ENOMEM;
  1744. resp = kzalloc_obj(*resp);
  1745. if (!resp) {
  1746. ret = -ENOMEM;
  1747. goto resp_out;
  1748. }
  1749. req->client_id_valid = 1;
  1750. req->client_id = QMI_WLANFW_CLIENT_ID;
  1751. req->fw_ready_enable_valid = 1;
  1752. req->fw_ready_enable = 1;
  1753. req->cal_done_enable_valid = 1;
  1754. req->cal_done_enable = 1;
  1755. req->fw_init_done_enable_valid = 1;
  1756. req->fw_init_done_enable = 1;
  1757. req->pin_connect_result_enable_valid = 0;
  1758. req->pin_connect_result_enable = 0;
  1759. /* WCN6750 doesn't request for DDR memory via QMI,
  1760. * instead it uses a fixed 12MB reserved memory
  1761. * region in DDR.
  1762. */
  1763. if (!ab->hw_params.fixed_fw_mem) {
  1764. req->request_mem_enable_valid = 1;
  1765. req->request_mem_enable = 1;
  1766. req->fw_mem_ready_enable_valid = 1;
  1767. req->fw_mem_ready_enable = 1;
  1768. }
  1769. ret = qmi_txn_init(handle, &txn,
  1770. qmi_wlanfw_ind_register_resp_msg_v01_ei, resp);
  1771. if (ret < 0)
  1772. goto out;
  1773. ath11k_dbg(ab, ATH11K_DBG_QMI, "indication register request\n");
  1774. ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
  1775. QMI_WLANFW_IND_REGISTER_REQ_V01,
  1776. QMI_WLANFW_IND_REGISTER_REQ_MSG_V01_MAX_LEN,
  1777. qmi_wlanfw_ind_register_req_msg_v01_ei, req);
  1778. if (ret < 0) {
  1779. qmi_txn_cancel(&txn);
  1780. ath11k_warn(ab, "failed to send indication register request: %d\n",
  1781. ret);
  1782. goto out;
  1783. }
  1784. ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
  1785. if (ret < 0) {
  1786. ath11k_warn(ab, "failed to register fw indication: %d\n", ret);
  1787. goto out;
  1788. }
  1789. if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
  1790. ath11k_warn(ab, "firmware indication register request failed: %d %d\n",
  1791. resp->resp.result, resp->resp.error);
  1792. ret = -EINVAL;
  1793. goto out;
  1794. }
  1795. out:
  1796. kfree(resp);
  1797. resp_out:
  1798. kfree(req);
  1799. return ret;
  1800. }
  1801. static int ath11k_qmi_respond_fw_mem_request(struct ath11k_base *ab)
  1802. {
  1803. struct qmi_wlanfw_respond_mem_req_msg_v01 *req;
  1804. struct qmi_wlanfw_respond_mem_resp_msg_v01 resp;
  1805. struct qmi_txn txn;
  1806. int ret = 0, i;
  1807. bool delayed;
  1808. req = kzalloc_obj(*req);
  1809. if (!req)
  1810. return -ENOMEM;
  1811. memset(&resp, 0, sizeof(resp));
  1812. /* For QCA6390 by default FW requests a block of ~4M contiguous
  1813. * DMA memory, it's hard to allocate from OS. So host returns
  1814. * failure to FW and FW will then request multiple blocks of small
  1815. * chunk size memory.
  1816. */
  1817. if (!(ab->hw_params.fixed_mem_region ||
  1818. test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) &&
  1819. ab->qmi.target_mem_delayed) {
  1820. delayed = true;
  1821. ath11k_dbg(ab, ATH11K_DBG_QMI, "delays mem_request %d\n",
  1822. ab->qmi.mem_seg_count);
  1823. memset(req, 0, sizeof(*req));
  1824. } else {
  1825. delayed = false;
  1826. req->mem_seg_len = ab->qmi.mem_seg_count;
  1827. for (i = 0; i < req->mem_seg_len ; i++) {
  1828. req->mem_seg[i].addr = ab->qmi.target_mem[i].paddr;
  1829. req->mem_seg[i].size = ab->qmi.target_mem[i].size;
  1830. req->mem_seg[i].type = ab->qmi.target_mem[i].type;
  1831. ath11k_dbg(ab, ATH11K_DBG_QMI,
  1832. "req mem_seg[%d] %pad %u %u\n", i,
  1833. &ab->qmi.target_mem[i].paddr,
  1834. ab->qmi.target_mem[i].size,
  1835. ab->qmi.target_mem[i].type);
  1836. }
  1837. }
  1838. ret = qmi_txn_init(&ab->qmi.handle, &txn,
  1839. qmi_wlanfw_respond_mem_resp_msg_v01_ei, &resp);
  1840. if (ret < 0)
  1841. goto out;
  1842. ath11k_dbg(ab, ATH11K_DBG_QMI, "respond memory request delayed %i\n",
  1843. delayed);
  1844. ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
  1845. QMI_WLANFW_RESPOND_MEM_REQ_V01,
  1846. QMI_WLANFW_RESPOND_MEM_REQ_MSG_V01_MAX_LEN,
  1847. qmi_wlanfw_respond_mem_req_msg_v01_ei, req);
  1848. if (ret < 0) {
  1849. qmi_txn_cancel(&txn);
  1850. ath11k_warn(ab, "failed to respond qmi memory request: %d\n",
  1851. ret);
  1852. goto out;
  1853. }
  1854. ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
  1855. if (ret < 0) {
  1856. ath11k_warn(ab, "failed to wait qmi memory request: %d\n", ret);
  1857. goto out;
  1858. }
  1859. if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
  1860. /* the error response is expected when
  1861. * target_mem_delayed is true.
  1862. */
  1863. if (delayed && resp.resp.error == 0)
  1864. goto out;
  1865. ath11k_warn(ab, "qmi respond memory request failed: %d %d\n",
  1866. resp.resp.result, resp.resp.error);
  1867. ret = -EINVAL;
  1868. goto out;
  1869. }
  1870. out:
  1871. kfree(req);
  1872. return ret;
  1873. }
  1874. static void ath11k_qmi_free_target_mem_chunk(struct ath11k_base *ab)
  1875. {
  1876. int i;
  1877. for (i = 0; i < ab->qmi.mem_seg_count; i++) {
  1878. if (!ab->qmi.target_mem[i].anyaddr)
  1879. continue;
  1880. if (ab->hw_params.fixed_mem_region ||
  1881. test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) {
  1882. iounmap(ab->qmi.target_mem[i].iaddr);
  1883. ab->qmi.target_mem[i].iaddr = NULL;
  1884. continue;
  1885. }
  1886. dma_free_coherent(ab->dev,
  1887. ab->qmi.target_mem[i].prev_size,
  1888. ab->qmi.target_mem[i].vaddr,
  1889. ab->qmi.target_mem[i].paddr);
  1890. ab->qmi.target_mem[i].vaddr = NULL;
  1891. }
  1892. }
  1893. static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab)
  1894. {
  1895. int i;
  1896. struct target_mem_chunk *chunk;
  1897. ab->qmi.target_mem_delayed = false;
  1898. for (i = 0; i < ab->qmi.mem_seg_count; i++) {
  1899. chunk = &ab->qmi.target_mem[i];
  1900. /* Firmware reloads in coldboot/firmware recovery.
  1901. * in such case, no need to allocate memory for FW again.
  1902. */
  1903. if (chunk->vaddr) {
  1904. if (chunk->prev_type == chunk->type &&
  1905. chunk->prev_size == chunk->size)
  1906. continue;
  1907. if (ab->qmi.mem_seg_count <= ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT) {
  1908. ath11k_dbg(ab, ATH11K_DBG_QMI,
  1909. "size/type mismatch (current %d %u) (prev %d %u), try later with small size\n",
  1910. chunk->size, chunk->type,
  1911. chunk->prev_size, chunk->prev_type);
  1912. ab->qmi.target_mem_delayed = true;
  1913. return 0;
  1914. }
  1915. /* cannot reuse the existing chunk */
  1916. dma_free_coherent(ab->dev, chunk->prev_size,
  1917. chunk->vaddr, chunk->paddr);
  1918. chunk->vaddr = NULL;
  1919. }
  1920. chunk->vaddr = dma_alloc_coherent(ab->dev,
  1921. chunk->size,
  1922. &chunk->paddr,
  1923. GFP_KERNEL | __GFP_NOWARN);
  1924. if (!chunk->vaddr) {
  1925. if (ab->qmi.mem_seg_count <= ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT) {
  1926. ath11k_dbg(ab, ATH11K_DBG_QMI,
  1927. "dma allocation failed (%d B type %u), will try later with small size\n",
  1928. chunk->size,
  1929. chunk->type);
  1930. ath11k_qmi_free_target_mem_chunk(ab);
  1931. ab->qmi.target_mem_delayed = true;
  1932. return 0;
  1933. }
  1934. ath11k_err(ab, "failed to allocate dma memory for qmi (%d B type %u)\n",
  1935. chunk->size,
  1936. chunk->type);
  1937. return -EINVAL;
  1938. }
  1939. chunk->prev_type = chunk->type;
  1940. chunk->prev_size = chunk->size;
  1941. }
  1942. return 0;
  1943. }
  1944. static int ath11k_qmi_assign_target_mem_chunk(struct ath11k_base *ab)
  1945. {
  1946. struct device *dev = ab->dev;
  1947. struct resource res = {};
  1948. u32 host_ddr_sz;
  1949. int i, idx, ret;
  1950. for (i = 0, idx = 0; i < ab->qmi.mem_seg_count; i++) {
  1951. switch (ab->qmi.target_mem[i].type) {
  1952. case HOST_DDR_REGION_TYPE:
  1953. ret = of_reserved_mem_region_to_resource(dev->of_node, 0, &res);
  1954. if (ret) {
  1955. ath11k_dbg(ab, ATH11K_DBG_QMI,
  1956. "fail to get reg from hremote\n");
  1957. return ret;
  1958. }
  1959. if (res.end - res.start + 1 < ab->qmi.target_mem[i].size) {
  1960. ath11k_dbg(ab, ATH11K_DBG_QMI,
  1961. "fail to assign memory of sz\n");
  1962. return -EINVAL;
  1963. }
  1964. ab->qmi.target_mem[idx].paddr = res.start;
  1965. ab->qmi.target_mem[idx].iaddr =
  1966. ioremap(ab->qmi.target_mem[idx].paddr,
  1967. ab->qmi.target_mem[i].size);
  1968. if (!ab->qmi.target_mem[idx].iaddr)
  1969. return -EIO;
  1970. ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
  1971. host_ddr_sz = ab->qmi.target_mem[i].size;
  1972. ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
  1973. idx++;
  1974. break;
  1975. case BDF_MEM_REGION_TYPE:
  1976. ab->qmi.target_mem[idx].paddr = ab->hw_params.bdf_addr;
  1977. ab->qmi.target_mem[idx].iaddr = NULL;
  1978. ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
  1979. ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
  1980. idx++;
  1981. break;
  1982. case CALDB_MEM_REGION_TYPE:
  1983. if (ab->qmi.target_mem[i].size > ATH11K_QMI_CALDB_SIZE) {
  1984. ath11k_warn(ab, "qmi mem size is low to load caldata\n");
  1985. return -EINVAL;
  1986. }
  1987. if (ath11k_core_coldboot_cal_support(ab)) {
  1988. if (resource_size(&res)) {
  1989. ab->qmi.target_mem[idx].paddr =
  1990. res.start + host_ddr_sz;
  1991. ab->qmi.target_mem[idx].iaddr =
  1992. ioremap(ab->qmi.target_mem[idx].paddr,
  1993. ab->qmi.target_mem[i].size);
  1994. if (!ab->qmi.target_mem[idx].iaddr)
  1995. return -EIO;
  1996. } else {
  1997. ab->qmi.target_mem[idx].paddr =
  1998. ATH11K_QMI_CALDB_ADDRESS;
  1999. ab->qmi.target_mem[idx].iaddr = NULL;
  2000. }
  2001. } else {
  2002. ab->qmi.target_mem[idx].paddr = 0;
  2003. ab->qmi.target_mem[idx].iaddr = NULL;
  2004. }
  2005. ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
  2006. ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
  2007. idx++;
  2008. break;
  2009. default:
  2010. ath11k_warn(ab, "qmi ignore invalid mem req type %d\n",
  2011. ab->qmi.target_mem[i].type);
  2012. break;
  2013. }
  2014. }
  2015. ab->qmi.mem_seg_count = idx;
  2016. return 0;
  2017. }
  2018. static int ath11k_qmi_request_device_info(struct ath11k_base *ab)
  2019. {
  2020. struct qmi_wlanfw_device_info_req_msg_v01 req = {};
  2021. struct qmi_wlanfw_device_info_resp_msg_v01 resp = {};
  2022. struct qmi_txn txn;
  2023. void __iomem *bar_addr_va;
  2024. int ret;
  2025. /* device info message req is only sent for hybrid bus devices */
  2026. if (!ab->hw_params.hybrid_bus_type)
  2027. return 0;
  2028. ret = qmi_txn_init(&ab->qmi.handle, &txn,
  2029. qmi_wlfw_device_info_resp_msg_v01_ei, &resp);
  2030. if (ret < 0)
  2031. goto out;
  2032. ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
  2033. QMI_WLANFW_DEVICE_INFO_REQ_V01,
  2034. QMI_WLANFW_DEVICE_INFO_REQ_MSG_V01_MAX_LEN,
  2035. qmi_wlanfw_device_info_req_msg_v01_ei, &req);
  2036. if (ret < 0) {
  2037. qmi_txn_cancel(&txn);
  2038. ath11k_warn(ab, "failed to send qmi target device info request: %d\n",
  2039. ret);
  2040. goto out;
  2041. }
  2042. ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
  2043. if (ret < 0) {
  2044. ath11k_warn(ab, "failed to wait qmi target device info request: %d\n",
  2045. ret);
  2046. goto out;
  2047. }
  2048. if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
  2049. ath11k_warn(ab, "qmi device info request failed: %d %d\n",
  2050. resp.resp.result, resp.resp.error);
  2051. ret = -EINVAL;
  2052. goto out;
  2053. }
  2054. if (!resp.bar_addr_valid || !resp.bar_size_valid) {
  2055. ath11k_warn(ab, "qmi device info response invalid: %d %d\n",
  2056. resp.resp.result, resp.resp.error);
  2057. ret = -EINVAL;
  2058. goto out;
  2059. }
  2060. if (!resp.bar_addr ||
  2061. resp.bar_size != ATH11K_QMI_DEVICE_BAR_SIZE) {
  2062. ath11k_warn(ab, "qmi device info invalid address and size: %llu %u\n",
  2063. resp.bar_addr, resp.bar_size);
  2064. ret = -EINVAL;
  2065. goto out;
  2066. }
  2067. bar_addr_va = devm_ioremap(ab->dev, resp.bar_addr, resp.bar_size);
  2068. if (!bar_addr_va) {
  2069. ath11k_warn(ab, "qmi device info ioremap failed\n");
  2070. ab->mem_len = 0;
  2071. ret = -EIO;
  2072. goto out;
  2073. }
  2074. ab->mem = bar_addr_va;
  2075. ab->mem_len = resp.bar_size;
  2076. if (!ab->hw_params.ce_remap)
  2077. ab->mem_ce = ab->mem;
  2078. return 0;
  2079. out:
  2080. return ret;
  2081. }
  2082. static int ath11k_qmi_request_target_cap(struct ath11k_base *ab)
  2083. {
  2084. struct qmi_wlanfw_cap_req_msg_v01 req;
  2085. struct qmi_wlanfw_cap_resp_msg_v01 resp;
  2086. struct qmi_txn txn;
  2087. int ret = 0;
  2088. int r;
  2089. char *fw_build_id;
  2090. int fw_build_id_mask_len;
  2091. memset(&req, 0, sizeof(req));
  2092. memset(&resp, 0, sizeof(resp));
  2093. ret = qmi_txn_init(&ab->qmi.handle, &txn, qmi_wlanfw_cap_resp_msg_v01_ei,
  2094. &resp);
  2095. if (ret < 0)
  2096. goto out;
  2097. ath11k_dbg(ab, ATH11K_DBG_QMI, "target cap request\n");
  2098. ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
  2099. QMI_WLANFW_CAP_REQ_V01,
  2100. QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN,
  2101. qmi_wlanfw_cap_req_msg_v01_ei, &req);
  2102. if (ret < 0) {
  2103. qmi_txn_cancel(&txn);
  2104. ath11k_warn(ab, "failed to send qmi cap request: %d\n",
  2105. ret);
  2106. goto out;
  2107. }
  2108. ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
  2109. if (ret < 0) {
  2110. ath11k_warn(ab, "failed to wait qmi cap request: %d\n", ret);
  2111. goto out;
  2112. }
  2113. if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
  2114. ath11k_warn(ab, "qmi cap request failed: %d %d\n",
  2115. resp.resp.result, resp.resp.error);
  2116. ret = -EINVAL;
  2117. goto out;
  2118. }
  2119. if (resp.chip_info_valid) {
  2120. ab->qmi.target.chip_id = resp.chip_info.chip_id;
  2121. ab->qmi.target.chip_family = resp.chip_info.chip_family;
  2122. }
  2123. if (resp.board_info_valid)
  2124. ab->qmi.target.board_id = resp.board_info.board_id;
  2125. else
  2126. ab->qmi.target.board_id = 0xFF;
  2127. if (resp.soc_info_valid)
  2128. ab->qmi.target.soc_id = resp.soc_info.soc_id;
  2129. if (resp.fw_version_info_valid) {
  2130. ab->qmi.target.fw_version = resp.fw_version_info.fw_version;
  2131. strscpy(ab->qmi.target.fw_build_timestamp,
  2132. resp.fw_version_info.fw_build_timestamp,
  2133. sizeof(ab->qmi.target.fw_build_timestamp));
  2134. }
  2135. if (resp.fw_build_id_valid)
  2136. strscpy(ab->qmi.target.fw_build_id, resp.fw_build_id,
  2137. sizeof(ab->qmi.target.fw_build_id));
  2138. if (resp.eeprom_read_timeout_valid) {
  2139. ab->qmi.target.eeprom_caldata =
  2140. resp.eeprom_read_timeout;
  2141. ath11k_dbg(ab, ATH11K_DBG_QMI, "cal data supported from eeprom\n");
  2142. }
  2143. fw_build_id = ab->qmi.target.fw_build_id;
  2144. fw_build_id_mask_len = strlen(FW_BUILD_ID_MASK);
  2145. if (!strncmp(fw_build_id, FW_BUILD_ID_MASK, fw_build_id_mask_len))
  2146. fw_build_id = fw_build_id + fw_build_id_mask_len;
  2147. ath11k_info(ab, "chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x\n",
  2148. ab->qmi.target.chip_id, ab->qmi.target.chip_family,
  2149. ab->qmi.target.board_id, ab->qmi.target.soc_id);
  2150. ath11k_info(ab, "fw_version 0x%x fw_build_timestamp %s fw_build_id %s",
  2151. ab->qmi.target.fw_version,
  2152. ab->qmi.target.fw_build_timestamp,
  2153. fw_build_id);
  2154. r = ath11k_core_check_smbios(ab);
  2155. if (r)
  2156. ath11k_dbg(ab, ATH11K_DBG_QMI, "SMBIOS bdf variant name not set.\n");
  2157. r = ath11k_core_check_dt(ab);
  2158. if (r)
  2159. ath11k_dbg(ab, ATH11K_DBG_QMI, "DT bdf variant name not set.\n");
  2160. out:
  2161. return ret;
  2162. }
  2163. static int ath11k_qmi_load_file_target_mem(struct ath11k_base *ab,
  2164. const u8 *data, u32 len, u8 type)
  2165. {
  2166. struct qmi_wlanfw_bdf_download_req_msg_v01 *req;
  2167. struct qmi_wlanfw_bdf_download_resp_msg_v01 resp;
  2168. struct qmi_txn txn;
  2169. const u8 *temp = data;
  2170. void __iomem *bdf_addr = NULL;
  2171. int ret = 0;
  2172. u32 remaining = len;
  2173. req = kzalloc_obj(*req);
  2174. if (!req)
  2175. return -ENOMEM;
  2176. memset(&resp, 0, sizeof(resp));
  2177. if (ab->hw_params.fixed_bdf_addr) {
  2178. bdf_addr = ioremap(ab->hw_params.bdf_addr, ab->hw_params.fw.board_size);
  2179. if (!bdf_addr) {
  2180. ath11k_warn(ab, "qmi ioremap error for bdf_addr\n");
  2181. ret = -EIO;
  2182. goto err_free_req;
  2183. }
  2184. }
  2185. while (remaining) {
  2186. req->valid = 1;
  2187. req->file_id_valid = 1;
  2188. req->file_id = ab->qmi.target.board_id;
  2189. req->total_size_valid = 1;
  2190. req->total_size = remaining;
  2191. req->seg_id_valid = 1;
  2192. req->data_valid = 1;
  2193. req->bdf_type = type;
  2194. req->bdf_type_valid = 1;
  2195. req->end_valid = 1;
  2196. req->end = 0;
  2197. if (remaining > QMI_WLANFW_MAX_DATA_SIZE_V01) {
  2198. req->data_len = QMI_WLANFW_MAX_DATA_SIZE_V01;
  2199. } else {
  2200. req->data_len = remaining;
  2201. req->end = 1;
  2202. }
  2203. if (ab->hw_params.fixed_bdf_addr ||
  2204. type == ATH11K_QMI_FILE_TYPE_EEPROM) {
  2205. req->data_valid = 0;
  2206. req->end = 1;
  2207. req->data_len = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE;
  2208. } else {
  2209. memcpy(req->data, temp, req->data_len);
  2210. }
  2211. if (ab->hw_params.fixed_bdf_addr) {
  2212. if (type == ATH11K_QMI_FILE_TYPE_CALDATA)
  2213. bdf_addr += ab->hw_params.fw.cal_offset;
  2214. memcpy_toio(bdf_addr, temp, len);
  2215. }
  2216. ret = qmi_txn_init(&ab->qmi.handle, &txn,
  2217. qmi_wlanfw_bdf_download_resp_msg_v01_ei,
  2218. &resp);
  2219. if (ret < 0)
  2220. goto err_iounmap;
  2221. ath11k_dbg(ab, ATH11K_DBG_QMI, "bdf download req fixed addr type %d\n",
  2222. type);
  2223. ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
  2224. QMI_WLANFW_BDF_DOWNLOAD_REQ_V01,
  2225. QMI_WLANFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_LEN,
  2226. qmi_wlanfw_bdf_download_req_msg_v01_ei, req);
  2227. if (ret < 0) {
  2228. qmi_txn_cancel(&txn);
  2229. goto err_iounmap;
  2230. }
  2231. ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
  2232. if (ret < 0) {
  2233. ath11k_warn(ab, "failed to wait board file download request: %d\n",
  2234. ret);
  2235. goto err_iounmap;
  2236. }
  2237. if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
  2238. ath11k_warn(ab, "board file download request failed: %d %d\n",
  2239. resp.resp.result, resp.resp.error);
  2240. ret = -EINVAL;
  2241. goto err_iounmap;
  2242. }
  2243. if (ab->hw_params.fixed_bdf_addr ||
  2244. type == ATH11K_QMI_FILE_TYPE_EEPROM) {
  2245. remaining = 0;
  2246. } else {
  2247. remaining -= req->data_len;
  2248. temp += req->data_len;
  2249. req->seg_id++;
  2250. ath11k_dbg(ab, ATH11K_DBG_QMI, "bdf download request remaining %i\n",
  2251. remaining);
  2252. }
  2253. }
  2254. err_iounmap:
  2255. if (ab->hw_params.fixed_bdf_addr)
  2256. iounmap(bdf_addr);
  2257. err_free_req:
  2258. kfree(req);
  2259. return ret;
  2260. }
  2261. static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab,
  2262. bool regdb)
  2263. {
  2264. struct device *dev = ab->dev;
  2265. char filename[ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE];
  2266. const struct firmware *fw_entry;
  2267. struct ath11k_board_data bd;
  2268. u32 fw_size, file_type;
  2269. int ret = 0, bdf_type;
  2270. const u8 *tmp;
  2271. memset(&bd, 0, sizeof(bd));
  2272. if (regdb) {
  2273. ret = ath11k_core_fetch_regdb(ab, &bd);
  2274. } else {
  2275. ret = ath11k_core_fetch_bdf(ab, &bd);
  2276. if (ret)
  2277. ath11k_warn(ab, "qmi failed to fetch board file: %d\n", ret);
  2278. }
  2279. if (ret)
  2280. goto out;
  2281. if (regdb)
  2282. bdf_type = ATH11K_QMI_BDF_TYPE_REGDB;
  2283. else if (bd.len >= SELFMAG && memcmp(bd.data, ELFMAG, SELFMAG) == 0)
  2284. bdf_type = ATH11K_QMI_BDF_TYPE_ELF;
  2285. else
  2286. bdf_type = ATH11K_QMI_BDF_TYPE_BIN;
  2287. ath11k_dbg(ab, ATH11K_DBG_QMI, "bdf_type %d\n", bdf_type);
  2288. fw_size = min_t(u32, ab->hw_params.fw.board_size, bd.len);
  2289. ret = ath11k_qmi_load_file_target_mem(ab, bd.data, fw_size, bdf_type);
  2290. if (ret < 0) {
  2291. ath11k_warn(ab, "qmi failed to load bdf file\n");
  2292. goto out;
  2293. }
  2294. /* QCA6390/WCN6855 does not support cal data, skip it */
  2295. if (bdf_type == ATH11K_QMI_BDF_TYPE_ELF || bdf_type == ATH11K_QMI_BDF_TYPE_REGDB)
  2296. goto out;
  2297. if (ab->qmi.target.eeprom_caldata) {
  2298. file_type = ATH11K_QMI_FILE_TYPE_EEPROM;
  2299. tmp = filename;
  2300. fw_size = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE;
  2301. } else {
  2302. file_type = ATH11K_QMI_FILE_TYPE_CALDATA;
  2303. /* cal-<bus>-<id>.bin */
  2304. snprintf(filename, sizeof(filename), "cal-%s-%s.bin",
  2305. ath11k_bus_str(ab->hif.bus), dev_name(dev));
  2306. fw_entry = ath11k_core_firmware_request(ab, filename);
  2307. if (!IS_ERR(fw_entry))
  2308. goto success;
  2309. fw_entry = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_CAL_FILE);
  2310. if (IS_ERR(fw_entry)) {
  2311. /* Caldata may not be present during first time calibration in
  2312. * factory hence allow to boot without loading caldata in ftm mode
  2313. */
  2314. if (ath11k_ftm_mode) {
  2315. ath11k_info(ab,
  2316. "Booting without cal data file in factory test mode\n");
  2317. return 0;
  2318. }
  2319. ret = PTR_ERR(fw_entry);
  2320. ath11k_warn(ab,
  2321. "qmi failed to load CAL data file:%s\n",
  2322. filename);
  2323. goto out;
  2324. }
  2325. success:
  2326. fw_size = min_t(u32, ab->hw_params.fw.board_size, fw_entry->size);
  2327. tmp = fw_entry->data;
  2328. }
  2329. ret = ath11k_qmi_load_file_target_mem(ab, tmp, fw_size, file_type);
  2330. if (ret < 0) {
  2331. ath11k_warn(ab, "qmi failed to load caldata\n");
  2332. goto out_qmi_cal;
  2333. }
  2334. ath11k_dbg(ab, ATH11K_DBG_QMI, "caldata type: %u\n", file_type);
  2335. out_qmi_cal:
  2336. if (!ab->qmi.target.eeprom_caldata)
  2337. release_firmware(fw_entry);
  2338. out:
  2339. ath11k_core_free_bdf(ab, &bd);
  2340. ath11k_dbg(ab, ATH11K_DBG_QMI, "BDF download sequence completed\n");
  2341. return ret;
  2342. }
  2343. static int ath11k_qmi_m3_load(struct ath11k_base *ab)
  2344. {
  2345. struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
  2346. const struct firmware *fw = NULL;
  2347. const void *m3_data;
  2348. char path[100];
  2349. size_t m3_len;
  2350. int ret;
  2351. if (m3_mem->vaddr)
  2352. /* m3 firmware buffer is already available in the DMA buffer */
  2353. return 0;
  2354. if (ab->fw.m3_data && ab->fw.m3_len > 0) {
  2355. /* firmware-N.bin had a m3 firmware file so use that */
  2356. m3_data = ab->fw.m3_data;
  2357. m3_len = ab->fw.m3_len;
  2358. } else {
  2359. /* No m3 file in firmware-N.bin so try to request old
  2360. * separate m3.bin.
  2361. */
  2362. fw = ath11k_core_firmware_request(ab, ATH11K_M3_FILE);
  2363. if (IS_ERR(fw)) {
  2364. ret = PTR_ERR(fw);
  2365. ath11k_core_create_firmware_path(ab, ATH11K_M3_FILE,
  2366. path, sizeof(path));
  2367. ath11k_err(ab, "failed to load %s: %d\n", path, ret);
  2368. return ret;
  2369. }
  2370. m3_data = fw->data;
  2371. m3_len = fw->size;
  2372. }
  2373. m3_mem->vaddr = dma_alloc_coherent(ab->dev,
  2374. m3_len, &m3_mem->paddr,
  2375. GFP_KERNEL);
  2376. if (!m3_mem->vaddr) {
  2377. ath11k_err(ab, "failed to allocate memory for M3 with size %zu\n",
  2378. m3_len);
  2379. ret = -ENOMEM;
  2380. goto out;
  2381. }
  2382. memcpy(m3_mem->vaddr, m3_data, m3_len);
  2383. m3_mem->size = m3_len;
  2384. ret = 0;
  2385. out:
  2386. release_firmware(fw);
  2387. return ret;
  2388. }
  2389. static void ath11k_qmi_m3_free(struct ath11k_base *ab)
  2390. {
  2391. struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
  2392. if (!ab->hw_params.m3_fw_support || !m3_mem->vaddr)
  2393. return;
  2394. dma_free_coherent(ab->dev, m3_mem->size,
  2395. m3_mem->vaddr, m3_mem->paddr);
  2396. m3_mem->vaddr = NULL;
  2397. m3_mem->size = 0;
  2398. }
  2399. /* clang stack usage explodes if this is inlined */
  2400. static noinline_for_stack
  2401. int ath11k_qmi_wlanfw_m3_info_send(struct ath11k_base *ab)
  2402. {
  2403. struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
  2404. struct qmi_wlanfw_m3_info_req_msg_v01 req;
  2405. struct qmi_wlanfw_m3_info_resp_msg_v01 resp;
  2406. struct qmi_txn txn;
  2407. int ret = 0;
  2408. memset(&req, 0, sizeof(req));
  2409. memset(&resp, 0, sizeof(resp));
  2410. if (ab->hw_params.m3_fw_support) {
  2411. ret = ath11k_qmi_m3_load(ab);
  2412. if (ret) {
  2413. ath11k_err(ab, "failed to load m3 firmware: %d", ret);
  2414. return ret;
  2415. }
  2416. req.addr = m3_mem->paddr;
  2417. req.size = m3_mem->size;
  2418. } else {
  2419. req.addr = 0;
  2420. req.size = 0;
  2421. }
  2422. ret = qmi_txn_init(&ab->qmi.handle, &txn,
  2423. qmi_wlanfw_m3_info_resp_msg_v01_ei, &resp);
  2424. if (ret < 0)
  2425. goto out;
  2426. ath11k_dbg(ab, ATH11K_DBG_QMI, "m3 info req\n");
  2427. ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
  2428. QMI_WLANFW_M3_INFO_REQ_V01,
  2429. QMI_WLANFW_M3_INFO_REQ_MSG_V01_MAX_MSG_LEN,
  2430. qmi_wlanfw_m3_info_req_msg_v01_ei, &req);
  2431. if (ret < 0) {
  2432. qmi_txn_cancel(&txn);
  2433. ath11k_warn(ab, "failed to send m3 information request: %d\n",
  2434. ret);
  2435. goto out;
  2436. }
  2437. ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
  2438. if (ret < 0) {
  2439. ath11k_warn(ab, "failed to wait m3 information request: %d\n", ret);
  2440. goto out;
  2441. }
  2442. if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
  2443. ath11k_warn(ab, "m3 info request failed: %d %d\n",
  2444. resp.resp.result, resp.resp.error);
  2445. ret = -EINVAL;
  2446. goto out;
  2447. }
  2448. out:
  2449. return ret;
  2450. }
  2451. static int ath11k_qmi_wlanfw_mode_send(struct ath11k_base *ab,
  2452. u32 mode)
  2453. {
  2454. struct qmi_wlanfw_wlan_mode_req_msg_v01 req;
  2455. struct qmi_wlanfw_wlan_mode_resp_msg_v01 resp;
  2456. struct qmi_txn txn;
  2457. int ret = 0;
  2458. memset(&req, 0, sizeof(req));
  2459. memset(&resp, 0, sizeof(resp));
  2460. req.mode = mode;
  2461. req.hw_debug_valid = 1;
  2462. req.hw_debug = 0;
  2463. ret = qmi_txn_init(&ab->qmi.handle, &txn,
  2464. qmi_wlanfw_wlan_mode_resp_msg_v01_ei, &resp);
  2465. if (ret < 0)
  2466. goto out;
  2467. ath11k_dbg(ab, ATH11K_DBG_QMI, "wlan mode req mode %d\n", mode);
  2468. ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
  2469. QMI_WLANFW_WLAN_MODE_REQ_V01,
  2470. QMI_WLANFW_WLAN_MODE_REQ_MSG_V01_MAX_LEN,
  2471. qmi_wlanfw_wlan_mode_req_msg_v01_ei, &req);
  2472. if (ret < 0) {
  2473. qmi_txn_cancel(&txn);
  2474. ath11k_warn(ab, "failed to send wlan mode request (mode %d): %d\n",
  2475. mode, ret);
  2476. goto out;
  2477. }
  2478. ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
  2479. if (ret < 0) {
  2480. if (mode == ATH11K_FIRMWARE_MODE_OFF && ret == -ENETRESET) {
  2481. ath11k_warn(ab, "WLFW service is dis-connected\n");
  2482. return 0;
  2483. }
  2484. ath11k_warn(ab, "failed to wait wlan mode request (mode %d): %d\n",
  2485. mode, ret);
  2486. goto out;
  2487. }
  2488. if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
  2489. ath11k_warn(ab, "wlan mode request failed (mode: %d): %d %d\n",
  2490. mode, resp.resp.result, resp.resp.error);
  2491. ret = -EINVAL;
  2492. goto out;
  2493. }
  2494. out:
  2495. return ret;
  2496. }
  2497. static int ath11k_qmi_wlanfw_wlan_cfg_send(struct ath11k_base *ab)
  2498. {
  2499. struct qmi_wlanfw_wlan_cfg_req_msg_v01 *req;
  2500. struct qmi_wlanfw_wlan_cfg_resp_msg_v01 resp;
  2501. struct ce_pipe_config *ce_cfg;
  2502. struct service_to_pipe *svc_cfg;
  2503. struct qmi_txn txn;
  2504. int ret = 0, pipe_num;
  2505. ce_cfg = (struct ce_pipe_config *)ab->qmi.ce_cfg.tgt_ce;
  2506. svc_cfg = (struct service_to_pipe *)ab->qmi.ce_cfg.svc_to_ce_map;
  2507. req = kzalloc_obj(*req);
  2508. if (!req)
  2509. return -ENOMEM;
  2510. memset(&resp, 0, sizeof(resp));
  2511. req->host_version_valid = 1;
  2512. strscpy(req->host_version, ATH11K_HOST_VERSION_STRING,
  2513. sizeof(req->host_version));
  2514. req->tgt_cfg_valid = 1;
  2515. /* This is number of CE configs */
  2516. req->tgt_cfg_len = ab->qmi.ce_cfg.tgt_ce_len;
  2517. for (pipe_num = 0; pipe_num < req->tgt_cfg_len ; pipe_num++) {
  2518. req->tgt_cfg[pipe_num].pipe_num = ce_cfg[pipe_num].pipenum;
  2519. req->tgt_cfg[pipe_num].pipe_dir = ce_cfg[pipe_num].pipedir;
  2520. req->tgt_cfg[pipe_num].nentries = ce_cfg[pipe_num].nentries;
  2521. req->tgt_cfg[pipe_num].nbytes_max = ce_cfg[pipe_num].nbytes_max;
  2522. req->tgt_cfg[pipe_num].flags = ce_cfg[pipe_num].flags;
  2523. }
  2524. req->svc_cfg_valid = 1;
  2525. /* This is number of Service/CE configs */
  2526. req->svc_cfg_len = ab->qmi.ce_cfg.svc_to_ce_map_len;
  2527. for (pipe_num = 0; pipe_num < req->svc_cfg_len; pipe_num++) {
  2528. req->svc_cfg[pipe_num].service_id = svc_cfg[pipe_num].service_id;
  2529. req->svc_cfg[pipe_num].pipe_dir = svc_cfg[pipe_num].pipedir;
  2530. req->svc_cfg[pipe_num].pipe_num = svc_cfg[pipe_num].pipenum;
  2531. }
  2532. req->shadow_reg_valid = 0;
  2533. /* set shadow v2 configuration */
  2534. if (ab->hw_params.supports_shadow_regs) {
  2535. req->shadow_reg_v2_valid = 1;
  2536. req->shadow_reg_v2_len = min_t(u32,
  2537. ab->qmi.ce_cfg.shadow_reg_v2_len,
  2538. QMI_WLANFW_MAX_NUM_SHADOW_REG_V2_V01);
  2539. memcpy(&req->shadow_reg_v2, ab->qmi.ce_cfg.shadow_reg_v2,
  2540. sizeof(u32) * req->shadow_reg_v2_len);
  2541. } else {
  2542. req->shadow_reg_v2_valid = 0;
  2543. }
  2544. ret = qmi_txn_init(&ab->qmi.handle, &txn,
  2545. qmi_wlanfw_wlan_cfg_resp_msg_v01_ei, &resp);
  2546. if (ret < 0)
  2547. goto out;
  2548. ath11k_dbg(ab, ATH11K_DBG_QMI, "wlan cfg req\n");
  2549. ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
  2550. QMI_WLANFW_WLAN_CFG_REQ_V01,
  2551. QMI_WLANFW_WLAN_CFG_REQ_MSG_V01_MAX_LEN,
  2552. qmi_wlanfw_wlan_cfg_req_msg_v01_ei, req);
  2553. if (ret < 0) {
  2554. qmi_txn_cancel(&txn);
  2555. ath11k_warn(ab, "failed to send wlan config request: %d\n",
  2556. ret);
  2557. goto out;
  2558. }
  2559. ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
  2560. if (ret < 0) {
  2561. ath11k_warn(ab, "failed to wait wlan config request: %d\n", ret);
  2562. goto out;
  2563. }
  2564. if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
  2565. ath11k_warn(ab, "wlan config request failed: %d %d\n",
  2566. resp.resp.result, resp.resp.error);
  2567. ret = -EINVAL;
  2568. goto out;
  2569. }
  2570. out:
  2571. kfree(req);
  2572. return ret;
  2573. }
  2574. static int ath11k_qmi_wlanfw_wlan_ini_send(struct ath11k_base *ab, bool enable)
  2575. {
  2576. int ret;
  2577. struct qmi_txn txn;
  2578. struct qmi_wlanfw_wlan_ini_req_msg_v01 req = {};
  2579. struct qmi_wlanfw_wlan_ini_resp_msg_v01 resp = {};
  2580. req.enablefwlog_valid = true;
  2581. req.enablefwlog = enable ? 1 : 0;
  2582. ret = qmi_txn_init(&ab->qmi.handle, &txn,
  2583. qmi_wlanfw_wlan_ini_resp_msg_v01_ei, &resp);
  2584. if (ret < 0)
  2585. goto out;
  2586. ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
  2587. QMI_WLANFW_WLAN_INI_REQ_V01,
  2588. QMI_WLANFW_WLAN_INI_REQ_MSG_V01_MAX_LEN,
  2589. qmi_wlanfw_wlan_ini_req_msg_v01_ei, &req);
  2590. if (ret < 0) {
  2591. ath11k_warn(ab, "qmi failed to send wlan ini request, err = %d\n",
  2592. ret);
  2593. qmi_txn_cancel(&txn);
  2594. goto out;
  2595. }
  2596. ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
  2597. if (ret < 0) {
  2598. ath11k_warn(ab, "qmi failed wlan ini request, err = %d\n", ret);
  2599. goto out;
  2600. }
  2601. if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
  2602. ath11k_warn(ab, "qmi wlan ini request failed, result: %d, err: %d\n",
  2603. resp.resp.result, resp.resp.error);
  2604. ret = -EINVAL;
  2605. }
  2606. out:
  2607. return ret;
  2608. }
  2609. void ath11k_qmi_firmware_stop(struct ath11k_base *ab)
  2610. {
  2611. int ret;
  2612. ath11k_dbg(ab, ATH11K_DBG_QMI, "firmware stop\n");
  2613. ret = ath11k_qmi_wlanfw_mode_send(ab, ATH11K_FIRMWARE_MODE_OFF);
  2614. if (ret < 0) {
  2615. ath11k_warn(ab, "qmi failed to send wlan mode off: %d\n", ret);
  2616. return;
  2617. }
  2618. }
  2619. int ath11k_qmi_firmware_start(struct ath11k_base *ab,
  2620. u32 mode)
  2621. {
  2622. int ret;
  2623. ath11k_dbg(ab, ATH11K_DBG_QMI, "firmware start\n");
  2624. if (ab->hw_params.fw_wmi_diag_event) {
  2625. ret = ath11k_qmi_wlanfw_wlan_ini_send(ab, true);
  2626. if (ret < 0) {
  2627. ath11k_warn(ab, "qmi failed to send wlan fw ini:%d\n", ret);
  2628. return ret;
  2629. }
  2630. }
  2631. ret = ath11k_qmi_wlanfw_wlan_cfg_send(ab);
  2632. if (ret < 0) {
  2633. ath11k_warn(ab, "qmi failed to send wlan cfg: %d\n", ret);
  2634. return ret;
  2635. }
  2636. ret = ath11k_qmi_wlanfw_mode_send(ab, mode);
  2637. if (ret < 0) {
  2638. ath11k_warn(ab, "qmi failed to send wlan fw mode: %d\n", ret);
  2639. return ret;
  2640. }
  2641. return 0;
  2642. }
  2643. int ath11k_qmi_fwreset_from_cold_boot(struct ath11k_base *ab)
  2644. {
  2645. long time_left;
  2646. if (!ath11k_core_coldboot_cal_support(ab) ||
  2647. ab->hw_params.cbcal_restart_fw == 0)
  2648. return 0;
  2649. ath11k_dbg(ab, ATH11K_DBG_QMI, "wait for cold boot done\n");
  2650. time_left = wait_event_timeout(ab->qmi.cold_boot_waitq,
  2651. (ab->qmi.cal_done == 1),
  2652. ATH11K_COLD_BOOT_FW_RESET_DELAY);
  2653. if (time_left <= 0) {
  2654. ath11k_warn(ab, "Coldboot Calibration timed out\n");
  2655. return -ETIMEDOUT;
  2656. }
  2657. /* reset the firmware */
  2658. ath11k_hif_power_down(ab, false);
  2659. ath11k_hif_power_up(ab);
  2660. ath11k_dbg(ab, ATH11K_DBG_QMI, "exit wait for cold boot done\n");
  2661. return 0;
  2662. }
  2663. EXPORT_SYMBOL(ath11k_qmi_fwreset_from_cold_boot);
  2664. static int ath11k_qmi_process_coldboot_calibration(struct ath11k_base *ab)
  2665. {
  2666. long time_left;
  2667. int ret;
  2668. ret = ath11k_qmi_wlanfw_mode_send(ab, ATH11K_FIRMWARE_MODE_COLD_BOOT);
  2669. if (ret < 0) {
  2670. ath11k_warn(ab, "qmi failed to send wlan fw mode: %d\n", ret);
  2671. return ret;
  2672. }
  2673. ath11k_dbg(ab, ATH11K_DBG_QMI, "Coldboot calibration wait started\n");
  2674. time_left = wait_event_timeout(ab->qmi.cold_boot_waitq,
  2675. (ab->qmi.cal_done == 1),
  2676. ATH11K_COLD_BOOT_FW_RESET_DELAY);
  2677. if (time_left <= 0) {
  2678. ath11k_warn(ab, "coldboot calibration timed out\n");
  2679. return 0;
  2680. }
  2681. ath11k_dbg(ab, ATH11K_DBG_QMI, "Coldboot calibration done\n");
  2682. return 0;
  2683. }
  2684. static int
  2685. ath11k_qmi_driver_event_post(struct ath11k_qmi *qmi,
  2686. enum ath11k_qmi_event_type type,
  2687. void *data)
  2688. {
  2689. struct ath11k_qmi_driver_event *event;
  2690. event = kzalloc_obj(*event, GFP_ATOMIC);
  2691. if (!event)
  2692. return -ENOMEM;
  2693. event->type = type;
  2694. event->data = data;
  2695. spin_lock(&qmi->event_lock);
  2696. list_add_tail(&event->list, &qmi->event_list);
  2697. spin_unlock(&qmi->event_lock);
  2698. queue_work(qmi->event_wq, &qmi->event_work);
  2699. return 0;
  2700. }
  2701. static int ath11k_qmi_event_mem_request(struct ath11k_qmi *qmi)
  2702. {
  2703. struct ath11k_base *ab = qmi->ab;
  2704. int ret;
  2705. ret = ath11k_qmi_respond_fw_mem_request(ab);
  2706. if (ret < 0) {
  2707. ath11k_warn(ab, "qmi failed to respond fw mem req: %d\n", ret);
  2708. return ret;
  2709. }
  2710. return ret;
  2711. }
  2712. static int ath11k_qmi_event_load_bdf(struct ath11k_qmi *qmi)
  2713. {
  2714. struct ath11k_base *ab = qmi->ab;
  2715. int ret;
  2716. ret = ath11k_qmi_request_target_cap(ab);
  2717. if (ret < 0) {
  2718. ath11k_warn(ab, "failed to request qmi target capabilities: %d\n",
  2719. ret);
  2720. return ret;
  2721. }
  2722. ret = ath11k_qmi_request_device_info(ab);
  2723. if (ret < 0) {
  2724. ath11k_warn(ab, "failed to request qmi device info: %d\n", ret);
  2725. return ret;
  2726. }
  2727. if (ab->hw_params.supports_regdb)
  2728. ath11k_qmi_load_bdf_qmi(ab, true);
  2729. ret = ath11k_qmi_load_bdf_qmi(ab, false);
  2730. if (ret < 0) {
  2731. ath11k_warn(ab, "failed to load board data file: %d\n", ret);
  2732. return ret;
  2733. }
  2734. return 0;
  2735. }
  2736. static int ath11k_qmi_event_server_arrive(struct ath11k_qmi *qmi)
  2737. {
  2738. struct ath11k_base *ab = qmi->ab;
  2739. int ret;
  2740. ret = ath11k_qmi_fw_ind_register_send(ab);
  2741. if (ret < 0) {
  2742. ath11k_warn(ab, "failed to send qmi firmware indication: %d\n",
  2743. ret);
  2744. return ret;
  2745. }
  2746. ret = ath11k_qmi_host_cap_send(ab);
  2747. if (ret < 0) {
  2748. ath11k_warn(ab, "failed to send qmi host cap: %d\n", ret);
  2749. return ret;
  2750. }
  2751. if (!ab->hw_params.fixed_fw_mem)
  2752. return ret;
  2753. ret = ath11k_qmi_event_load_bdf(qmi);
  2754. if (ret < 0) {
  2755. ath11k_warn(ab, "qmi failed to download BDF:%d\n", ret);
  2756. return ret;
  2757. }
  2758. return ret;
  2759. }
  2760. static void ath11k_qmi_msg_mem_request_cb(struct qmi_handle *qmi_hdl,
  2761. struct sockaddr_qrtr *sq,
  2762. struct qmi_txn *txn,
  2763. const void *data)
  2764. {
  2765. struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
  2766. struct ath11k_base *ab = qmi->ab;
  2767. const struct qmi_wlanfw_request_mem_ind_msg_v01 *msg = data;
  2768. int i, ret;
  2769. ath11k_dbg(ab, ATH11K_DBG_QMI, "firmware request memory request\n");
  2770. if (msg->mem_seg_len == 0 ||
  2771. msg->mem_seg_len > ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01)
  2772. ath11k_warn(ab, "invalid memory segment length: %u\n",
  2773. msg->mem_seg_len);
  2774. ab->qmi.mem_seg_count = msg->mem_seg_len;
  2775. for (i = 0; i < qmi->mem_seg_count ; i++) {
  2776. ab->qmi.target_mem[i].type = msg->mem_seg[i].type;
  2777. ab->qmi.target_mem[i].size = msg->mem_seg[i].size;
  2778. ath11k_dbg(ab, ATH11K_DBG_QMI, "mem seg type %d size %d\n",
  2779. msg->mem_seg[i].type, msg->mem_seg[i].size);
  2780. }
  2781. if (ab->hw_params.fixed_mem_region ||
  2782. test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) {
  2783. ret = ath11k_qmi_assign_target_mem_chunk(ab);
  2784. if (ret) {
  2785. ath11k_warn(ab, "failed to assign qmi target memory: %d\n",
  2786. ret);
  2787. return;
  2788. }
  2789. } else {
  2790. ret = ath11k_qmi_alloc_target_mem_chunk(ab);
  2791. if (ret) {
  2792. ath11k_warn(ab, "failed to allocate qmi target memory: %d\n",
  2793. ret);
  2794. return;
  2795. }
  2796. }
  2797. ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_REQUEST_MEM, NULL);
  2798. }
  2799. static void ath11k_qmi_msg_mem_ready_cb(struct qmi_handle *qmi_hdl,
  2800. struct sockaddr_qrtr *sq,
  2801. struct qmi_txn *txn,
  2802. const void *decoded)
  2803. {
  2804. struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
  2805. struct ath11k_base *ab = qmi->ab;
  2806. ath11k_dbg(ab, ATH11K_DBG_QMI, "firmware memory ready indication\n");
  2807. ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_MEM_READY, NULL);
  2808. }
  2809. static void ath11k_qmi_msg_fw_ready_cb(struct qmi_handle *qmi_hdl,
  2810. struct sockaddr_qrtr *sq,
  2811. struct qmi_txn *txn,
  2812. const void *decoded)
  2813. {
  2814. struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
  2815. struct ath11k_base *ab = qmi->ab;
  2816. ath11k_dbg(ab, ATH11K_DBG_QMI, "firmware ready\n");
  2817. if (!ab->qmi.cal_done) {
  2818. ab->qmi.cal_done = 1;
  2819. wake_up(&ab->qmi.cold_boot_waitq);
  2820. }
  2821. ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_READY, NULL);
  2822. }
  2823. static void ath11k_qmi_msg_cold_boot_cal_done_cb(struct qmi_handle *qmi_hdl,
  2824. struct sockaddr_qrtr *sq,
  2825. struct qmi_txn *txn,
  2826. const void *decoded)
  2827. {
  2828. struct ath11k_qmi *qmi = container_of(qmi_hdl,
  2829. struct ath11k_qmi, handle);
  2830. struct ath11k_base *ab = qmi->ab;
  2831. ab->qmi.cal_done = 1;
  2832. wake_up(&ab->qmi.cold_boot_waitq);
  2833. ath11k_dbg(ab, ATH11K_DBG_QMI, "cold boot calibration done\n");
  2834. }
  2835. static void ath11k_qmi_msg_fw_init_done_cb(struct qmi_handle *qmi_hdl,
  2836. struct sockaddr_qrtr *sq,
  2837. struct qmi_txn *txn,
  2838. const void *decoded)
  2839. {
  2840. struct ath11k_qmi *qmi = container_of(qmi_hdl,
  2841. struct ath11k_qmi, handle);
  2842. struct ath11k_base *ab = qmi->ab;
  2843. ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_INIT_DONE, NULL);
  2844. ath11k_dbg(ab, ATH11K_DBG_QMI, "firmware init done\n");
  2845. }
  2846. static const struct qmi_msg_handler ath11k_qmi_msg_handlers[] = {
  2847. {
  2848. .type = QMI_INDICATION,
  2849. .msg_id = QMI_WLFW_REQUEST_MEM_IND_V01,
  2850. .ei = qmi_wlanfw_request_mem_ind_msg_v01_ei,
  2851. .decoded_size = sizeof(struct qmi_wlanfw_request_mem_ind_msg_v01),
  2852. .fn = ath11k_qmi_msg_mem_request_cb,
  2853. },
  2854. {
  2855. .type = QMI_INDICATION,
  2856. .msg_id = QMI_WLFW_FW_MEM_READY_IND_V01,
  2857. .ei = qmi_wlanfw_mem_ready_ind_msg_v01_ei,
  2858. .decoded_size = sizeof(struct qmi_wlanfw_fw_mem_ready_ind_msg_v01),
  2859. .fn = ath11k_qmi_msg_mem_ready_cb,
  2860. },
  2861. {
  2862. .type = QMI_INDICATION,
  2863. .msg_id = QMI_WLFW_FW_READY_IND_V01,
  2864. .ei = qmi_wlanfw_fw_ready_ind_msg_v01_ei,
  2865. .decoded_size = sizeof(struct qmi_wlanfw_fw_ready_ind_msg_v01),
  2866. .fn = ath11k_qmi_msg_fw_ready_cb,
  2867. },
  2868. {
  2869. .type = QMI_INDICATION,
  2870. .msg_id = QMI_WLFW_COLD_BOOT_CAL_DONE_IND_V01,
  2871. .ei = qmi_wlanfw_cold_boot_cal_done_ind_msg_v01_ei,
  2872. .decoded_size =
  2873. sizeof(struct qmi_wlanfw_fw_cold_cal_done_ind_msg_v01),
  2874. .fn = ath11k_qmi_msg_cold_boot_cal_done_cb,
  2875. },
  2876. {
  2877. .type = QMI_INDICATION,
  2878. .msg_id = QMI_WLFW_FW_INIT_DONE_IND_V01,
  2879. .ei = qmi_wlfw_fw_init_done_ind_msg_v01_ei,
  2880. .decoded_size =
  2881. sizeof(struct qmi_wlfw_fw_init_done_ind_msg_v01),
  2882. .fn = ath11k_qmi_msg_fw_init_done_cb,
  2883. },
  2884. /* end of list */
  2885. {},
  2886. };
  2887. static int ath11k_qmi_ops_new_server(struct qmi_handle *qmi_hdl,
  2888. struct qmi_service *service)
  2889. {
  2890. struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
  2891. struct ath11k_base *ab = qmi->ab;
  2892. struct sockaddr_qrtr *sq = &qmi->sq;
  2893. int ret;
  2894. sq->sq_family = AF_QIPCRTR;
  2895. sq->sq_node = service->node;
  2896. sq->sq_port = service->port;
  2897. ret = kernel_connect(qmi_hdl->sock, (struct sockaddr_unsized *)sq,
  2898. sizeof(*sq), 0);
  2899. if (ret) {
  2900. ath11k_warn(ab, "failed to connect to qmi remote service: %d\n", ret);
  2901. return ret;
  2902. }
  2903. ath11k_dbg(ab, ATH11K_DBG_QMI, "wifi fw qmi service connected\n");
  2904. ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_SERVER_ARRIVE, NULL);
  2905. return ret;
  2906. }
  2907. static void ath11k_qmi_ops_del_server(struct qmi_handle *qmi_hdl,
  2908. struct qmi_service *service)
  2909. {
  2910. struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
  2911. struct ath11k_base *ab = qmi->ab;
  2912. ath11k_dbg(ab, ATH11K_DBG_QMI, "wifi fw del server\n");
  2913. ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_SERVER_EXIT, NULL);
  2914. }
  2915. static const struct qmi_ops ath11k_qmi_ops = {
  2916. .new_server = ath11k_qmi_ops_new_server,
  2917. .del_server = ath11k_qmi_ops_del_server,
  2918. };
  2919. static void ath11k_qmi_driver_event_work(struct work_struct *work)
  2920. {
  2921. struct ath11k_qmi *qmi = container_of(work, struct ath11k_qmi,
  2922. event_work);
  2923. struct ath11k_qmi_driver_event *event;
  2924. struct ath11k_base *ab = qmi->ab;
  2925. int ret;
  2926. spin_lock(&qmi->event_lock);
  2927. while (!list_empty(&qmi->event_list)) {
  2928. event = list_first_entry(&qmi->event_list,
  2929. struct ath11k_qmi_driver_event, list);
  2930. list_del(&event->list);
  2931. spin_unlock(&qmi->event_lock);
  2932. if (test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)) {
  2933. kfree(event);
  2934. return;
  2935. }
  2936. switch (event->type) {
  2937. case ATH11K_QMI_EVENT_SERVER_ARRIVE:
  2938. ret = ath11k_qmi_event_server_arrive(qmi);
  2939. if (ret < 0)
  2940. set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);
  2941. break;
  2942. case ATH11K_QMI_EVENT_SERVER_EXIT:
  2943. set_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags);
  2944. set_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
  2945. if (!ab->is_reset)
  2946. ath11k_core_pre_reconfigure_recovery(ab);
  2947. break;
  2948. case ATH11K_QMI_EVENT_REQUEST_MEM:
  2949. ret = ath11k_qmi_event_mem_request(qmi);
  2950. if (ret < 0)
  2951. set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);
  2952. break;
  2953. case ATH11K_QMI_EVENT_FW_MEM_READY:
  2954. ret = ath11k_qmi_event_load_bdf(qmi);
  2955. if (ret < 0) {
  2956. set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);
  2957. break;
  2958. }
  2959. ret = ath11k_qmi_wlanfw_m3_info_send(ab);
  2960. if (ret < 0) {
  2961. ath11k_warn(ab,
  2962. "failed to send qmi m3 info req: %d\n", ret);
  2963. set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);
  2964. }
  2965. break;
  2966. case ATH11K_QMI_EVENT_FW_INIT_DONE:
  2967. clear_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);
  2968. if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) {
  2969. if (ab->is_reset)
  2970. ath11k_hal_dump_srng_stats(ab);
  2971. queue_work(ab->workqueue, &ab->restart_work);
  2972. break;
  2973. }
  2974. if (ab->qmi.cal_done == 0 &&
  2975. ath11k_core_coldboot_cal_support(ab)) {
  2976. ath11k_qmi_process_coldboot_calibration(ab);
  2977. } else {
  2978. clear_bit(ATH11K_FLAG_CRASH_FLUSH,
  2979. &ab->dev_flags);
  2980. clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
  2981. ret = ath11k_core_qmi_firmware_ready(ab);
  2982. if (ret) {
  2983. set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);
  2984. break;
  2985. }
  2986. set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags);
  2987. }
  2988. break;
  2989. case ATH11K_QMI_EVENT_FW_READY:
  2990. /* For targets requiring a FW restart upon cold
  2991. * boot completion, there is no need to process
  2992. * FW ready; such targets will receive FW init
  2993. * done message after FW restart.
  2994. */
  2995. if (ab->hw_params.cbcal_restart_fw)
  2996. break;
  2997. clear_bit(ATH11K_FLAG_CRASH_FLUSH,
  2998. &ab->dev_flags);
  2999. clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
  3000. ath11k_core_qmi_firmware_ready(ab);
  3001. set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags);
  3002. break;
  3003. case ATH11K_QMI_EVENT_COLD_BOOT_CAL_DONE:
  3004. break;
  3005. default:
  3006. ath11k_warn(ab, "invalid qmi event type: %d", event->type);
  3007. break;
  3008. }
  3009. kfree(event);
  3010. spin_lock(&qmi->event_lock);
  3011. }
  3012. spin_unlock(&qmi->event_lock);
  3013. }
  3014. int ath11k_qmi_init_service(struct ath11k_base *ab)
  3015. {
  3016. int ret;
  3017. memset(&ab->qmi.target, 0, sizeof(struct target_info));
  3018. memset(&ab->qmi.target_mem, 0, sizeof(struct target_mem_chunk));
  3019. ab->qmi.ab = ab;
  3020. ab->qmi.target_mem_mode = ab->hw_params.fw_mem_mode;
  3021. ret = qmi_handle_init(&ab->qmi.handle, ATH11K_QMI_RESP_LEN_MAX,
  3022. &ath11k_qmi_ops, ath11k_qmi_msg_handlers);
  3023. if (ret < 0) {
  3024. ath11k_warn(ab, "failed to initialize qmi handle: %d\n", ret);
  3025. return ret;
  3026. }
  3027. ab->qmi.event_wq = alloc_ordered_workqueue("ath11k_qmi_driver_event", 0);
  3028. if (!ab->qmi.event_wq) {
  3029. ath11k_err(ab, "failed to allocate workqueue\n");
  3030. return -EFAULT;
  3031. }
  3032. INIT_LIST_HEAD(&ab->qmi.event_list);
  3033. spin_lock_init(&ab->qmi.event_lock);
  3034. INIT_WORK(&ab->qmi.event_work, ath11k_qmi_driver_event_work);
  3035. ret = qmi_add_lookup(&ab->qmi.handle, ATH11K_QMI_WLFW_SERVICE_ID_V01,
  3036. ATH11K_QMI_WLFW_SERVICE_VERS_V01,
  3037. ab->qmi.service_ins_id);
  3038. if (ret < 0) {
  3039. ath11k_warn(ab, "failed to add qmi lookup: %d\n", ret);
  3040. destroy_workqueue(ab->qmi.event_wq);
  3041. return ret;
  3042. }
  3043. return ret;
  3044. }
  3045. void ath11k_qmi_deinit_service(struct ath11k_base *ab)
  3046. {
  3047. qmi_handle_release(&ab->qmi.handle);
  3048. cancel_work_sync(&ab->qmi.event_work);
  3049. destroy_workqueue(ab->qmi.event_wq);
  3050. ath11k_qmi_m3_free(ab);
  3051. ath11k_qmi_free_target_mem_chunk(ab);
  3052. }
  3053. EXPORT_SYMBOL(ath11k_qmi_deinit_service);
  3054. void ath11k_qmi_free_resource(struct ath11k_base *ab)
  3055. {
  3056. ath11k_qmi_free_target_mem_chunk(ab);
  3057. ath11k_qmi_m3_free(ab);
  3058. }