hw.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155
  1. // SPDX-License-Identifier: ISC
  2. /*
  3. * Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
  4. */
  5. #include <linux/types.h>
  6. #include <linux/bitops.h>
  7. #include <linux/bitfield.h>
  8. #include "core.h"
  9. #include "hw.h"
  10. #include "hif.h"
  11. #include "wmi-ops.h"
  12. #include "bmi.h"
  13. #include "rx_desc.h"
  14. const struct ath10k_hw_regs qca988x_regs = {
  15. .rtc_soc_base_address = 0x00004000,
  16. .rtc_wmac_base_address = 0x00005000,
  17. .soc_core_base_address = 0x00009000,
  18. .wlan_mac_base_address = 0x00020000,
  19. .ce_wrapper_base_address = 0x00057000,
  20. .ce0_base_address = 0x00057400,
  21. .ce1_base_address = 0x00057800,
  22. .ce2_base_address = 0x00057c00,
  23. .ce3_base_address = 0x00058000,
  24. .ce4_base_address = 0x00058400,
  25. .ce5_base_address = 0x00058800,
  26. .ce6_base_address = 0x00058c00,
  27. .ce7_base_address = 0x00059000,
  28. .soc_reset_control_si0_rst_mask = 0x00000001,
  29. .soc_reset_control_ce_rst_mask = 0x00040000,
  30. .soc_chip_id_address = 0x000000ec,
  31. .scratch_3_address = 0x00000030,
  32. .fw_indicator_address = 0x00009030,
  33. .pcie_local_base_address = 0x00080000,
  34. .ce_wrap_intr_sum_host_msi_lsb = 0x00000008,
  35. .ce_wrap_intr_sum_host_msi_mask = 0x0000ff00,
  36. .pcie_intr_fw_mask = 0x00000400,
  37. .pcie_intr_ce_mask_all = 0x0007f800,
  38. .pcie_intr_clr_address = 0x00000014,
  39. };
  40. const struct ath10k_hw_regs qca6174_regs = {
  41. .rtc_soc_base_address = 0x00000800,
  42. .rtc_wmac_base_address = 0x00001000,
  43. .soc_core_base_address = 0x0003a000,
  44. .wlan_mac_base_address = 0x00010000,
  45. .ce_wrapper_base_address = 0x00034000,
  46. .ce0_base_address = 0x00034400,
  47. .ce1_base_address = 0x00034800,
  48. .ce2_base_address = 0x00034c00,
  49. .ce3_base_address = 0x00035000,
  50. .ce4_base_address = 0x00035400,
  51. .ce5_base_address = 0x00035800,
  52. .ce6_base_address = 0x00035c00,
  53. .ce7_base_address = 0x00036000,
  54. .soc_reset_control_si0_rst_mask = 0x00000000,
  55. .soc_reset_control_ce_rst_mask = 0x00000001,
  56. .soc_chip_id_address = 0x000000f0,
  57. .scratch_3_address = 0x00000028,
  58. .fw_indicator_address = 0x0003a028,
  59. .pcie_local_base_address = 0x00080000,
  60. .ce_wrap_intr_sum_host_msi_lsb = 0x00000008,
  61. .ce_wrap_intr_sum_host_msi_mask = 0x0000ff00,
  62. .pcie_intr_fw_mask = 0x00000400,
  63. .pcie_intr_ce_mask_all = 0x0007f800,
  64. .pcie_intr_clr_address = 0x00000014,
  65. .cpu_pll_init_address = 0x00404020,
  66. .cpu_speed_address = 0x00404024,
  67. .core_clk_div_address = 0x00404028,
  68. };
  69. const struct ath10k_hw_regs qca99x0_regs = {
  70. .rtc_soc_base_address = 0x00080000,
  71. .rtc_wmac_base_address = 0x00000000,
  72. .soc_core_base_address = 0x00082000,
  73. .wlan_mac_base_address = 0x00030000,
  74. .ce_wrapper_base_address = 0x0004d000,
  75. .ce0_base_address = 0x0004a000,
  76. .ce1_base_address = 0x0004a400,
  77. .ce2_base_address = 0x0004a800,
  78. .ce3_base_address = 0x0004ac00,
  79. .ce4_base_address = 0x0004b000,
  80. .ce5_base_address = 0x0004b400,
  81. .ce6_base_address = 0x0004b800,
  82. .ce7_base_address = 0x0004bc00,
  83. /* Note: qca99x0 supports up to 12 Copy Engines. Other than address of
  84. * CE0 and CE1 no other copy engine is directly referred in the code.
  85. * It is not really necessary to assign address for newly supported
  86. * CEs in this address table.
  87. * Copy Engine Address
  88. * CE8 0x0004c000
  89. * CE9 0x0004c400
  90. * CE10 0x0004c800
  91. * CE11 0x0004cc00
  92. */
  93. .soc_reset_control_si0_rst_mask = 0x00000001,
  94. .soc_reset_control_ce_rst_mask = 0x00000100,
  95. .soc_chip_id_address = 0x000000ec,
  96. .scratch_3_address = 0x00040050,
  97. .fw_indicator_address = 0x00040050,
  98. .pcie_local_base_address = 0x00000000,
  99. .ce_wrap_intr_sum_host_msi_lsb = 0x0000000c,
  100. .ce_wrap_intr_sum_host_msi_mask = 0x00fff000,
  101. .pcie_intr_fw_mask = 0x00100000,
  102. .pcie_intr_ce_mask_all = 0x000fff00,
  103. .pcie_intr_clr_address = 0x00000010,
  104. };
  105. const struct ath10k_hw_regs qca4019_regs = {
  106. .rtc_soc_base_address = 0x00080000,
  107. .soc_core_base_address = 0x00082000,
  108. .wlan_mac_base_address = 0x00030000,
  109. .ce_wrapper_base_address = 0x0004d000,
  110. .ce0_base_address = 0x0004a000,
  111. .ce1_base_address = 0x0004a400,
  112. .ce2_base_address = 0x0004a800,
  113. .ce3_base_address = 0x0004ac00,
  114. .ce4_base_address = 0x0004b000,
  115. .ce5_base_address = 0x0004b400,
  116. .ce6_base_address = 0x0004b800,
  117. .ce7_base_address = 0x0004bc00,
  118. /* qca4019 supports up to 12 copy engines. Since base address
  119. * of ce8 to ce11 are not directly referred in the code,
  120. * no need have them in separate members in this table.
  121. * Copy Engine Address
  122. * CE8 0x0004c000
  123. * CE9 0x0004c400
  124. * CE10 0x0004c800
  125. * CE11 0x0004cc00
  126. */
  127. .soc_reset_control_si0_rst_mask = 0x00000001,
  128. .soc_reset_control_ce_rst_mask = 0x00000100,
  129. .soc_chip_id_address = 0x000000ec,
  130. .fw_indicator_address = 0x0004f00c,
  131. .ce_wrap_intr_sum_host_msi_lsb = 0x0000000c,
  132. .ce_wrap_intr_sum_host_msi_mask = 0x00fff000,
  133. .pcie_intr_fw_mask = 0x00100000,
  134. .pcie_intr_ce_mask_all = 0x000fff00,
  135. .pcie_intr_clr_address = 0x00000010,
  136. };
  137. const struct ath10k_hw_values qca988x_values = {
  138. .rtc_state_val_on = 3,
  139. .ce_count = 8,
  140. .msi_assign_ce_max = 7,
  141. .num_target_ce_config_wlan = 7,
  142. .ce_desc_meta_data_mask = 0xFFFC,
  143. .ce_desc_meta_data_lsb = 2,
  144. };
  145. const struct ath10k_hw_values qca6174_values = {
  146. .rtc_state_val_on = 3,
  147. .ce_count = 8,
  148. .msi_assign_ce_max = 7,
  149. .num_target_ce_config_wlan = 7,
  150. .ce_desc_meta_data_mask = 0xFFFC,
  151. .ce_desc_meta_data_lsb = 2,
  152. .rfkill_pin = 16,
  153. .rfkill_cfg = 0,
  154. .rfkill_on_level = 1,
  155. };
  156. const struct ath10k_hw_values qca99x0_values = {
  157. .rtc_state_val_on = 7,
  158. .ce_count = 12,
  159. .msi_assign_ce_max = 12,
  160. .num_target_ce_config_wlan = 10,
  161. .ce_desc_meta_data_mask = 0xFFF0,
  162. .ce_desc_meta_data_lsb = 4,
  163. };
  164. const struct ath10k_hw_values qca9888_values = {
  165. .rtc_state_val_on = 3,
  166. .ce_count = 12,
  167. .msi_assign_ce_max = 12,
  168. .num_target_ce_config_wlan = 10,
  169. .ce_desc_meta_data_mask = 0xFFF0,
  170. .ce_desc_meta_data_lsb = 4,
  171. };
  172. const struct ath10k_hw_values qca4019_values = {
  173. .ce_count = 12,
  174. .num_target_ce_config_wlan = 10,
  175. .ce_desc_meta_data_mask = 0xFFF0,
  176. .ce_desc_meta_data_lsb = 4,
  177. };
  178. const struct ath10k_hw_regs wcn3990_regs = {
  179. .rtc_soc_base_address = 0x00000000,
  180. .rtc_wmac_base_address = 0x00000000,
  181. .soc_core_base_address = 0x00000000,
  182. .ce_wrapper_base_address = 0x0024C000,
  183. .ce0_base_address = 0x00240000,
  184. .ce1_base_address = 0x00241000,
  185. .ce2_base_address = 0x00242000,
  186. .ce3_base_address = 0x00243000,
  187. .ce4_base_address = 0x00244000,
  188. .ce5_base_address = 0x00245000,
  189. .ce6_base_address = 0x00246000,
  190. .ce7_base_address = 0x00247000,
  191. .ce8_base_address = 0x00248000,
  192. .ce9_base_address = 0x00249000,
  193. .ce10_base_address = 0x0024A000,
  194. .ce11_base_address = 0x0024B000,
  195. .soc_chip_id_address = 0x000000f0,
  196. .soc_reset_control_si0_rst_mask = 0x00000001,
  197. .soc_reset_control_ce_rst_mask = 0x00000100,
  198. .ce_wrap_intr_sum_host_msi_lsb = 0x0000000c,
  199. .ce_wrap_intr_sum_host_msi_mask = 0x00fff000,
  200. .pcie_intr_fw_mask = 0x00100000,
  201. };
  202. static struct ath10k_hw_ce_regs_addr_map wcn3990_src_ring = {
  203. .msb = 0x00000010,
  204. .lsb = 0x00000010,
  205. .mask = GENMASK(17, 17),
  206. };
  207. static struct ath10k_hw_ce_regs_addr_map wcn3990_dst_ring = {
  208. .msb = 0x00000012,
  209. .lsb = 0x00000012,
  210. .mask = GENMASK(18, 18),
  211. };
  212. static struct ath10k_hw_ce_regs_addr_map wcn3990_dmax = {
  213. .msb = 0x00000000,
  214. .lsb = 0x00000000,
  215. .mask = GENMASK(15, 0),
  216. };
  217. static struct ath10k_hw_ce_ctrl1 wcn3990_ctrl1 = {
  218. .addr = 0x00000018,
  219. .src_ring = &wcn3990_src_ring,
  220. .dst_ring = &wcn3990_dst_ring,
  221. .dmax = &wcn3990_dmax,
  222. };
  223. static struct ath10k_hw_ce_regs_addr_map wcn3990_host_ie_cc = {
  224. .mask = GENMASK(0, 0),
  225. };
  226. static struct ath10k_hw_ce_host_ie wcn3990_host_ie = {
  227. .copy_complete = &wcn3990_host_ie_cc,
  228. };
  229. static struct ath10k_hw_ce_host_wm_regs wcn3990_wm_reg = {
  230. .dstr_lmask = 0x00000010,
  231. .dstr_hmask = 0x00000008,
  232. .srcr_lmask = 0x00000004,
  233. .srcr_hmask = 0x00000002,
  234. .cc_mask = 0x00000001,
  235. .wm_mask = 0x0000001E,
  236. .addr = 0x00000030,
  237. };
  238. static struct ath10k_hw_ce_misc_regs wcn3990_misc_reg = {
  239. .axi_err = 0x00000100,
  240. .dstr_add_err = 0x00000200,
  241. .srcr_len_err = 0x00000100,
  242. .dstr_mlen_vio = 0x00000080,
  243. .dstr_overflow = 0x00000040,
  244. .srcr_overflow = 0x00000020,
  245. .err_mask = 0x000003E0,
  246. .addr = 0x00000038,
  247. };
  248. static struct ath10k_hw_ce_regs_addr_map wcn3990_src_wm_low = {
  249. .msb = 0x00000000,
  250. .lsb = 0x00000010,
  251. .mask = GENMASK(31, 16),
  252. };
  253. static struct ath10k_hw_ce_regs_addr_map wcn3990_src_wm_high = {
  254. .msb = 0x0000000f,
  255. .lsb = 0x00000000,
  256. .mask = GENMASK(15, 0),
  257. };
  258. static struct ath10k_hw_ce_dst_src_wm_regs wcn3990_wm_src_ring = {
  259. .addr = 0x0000004c,
  260. .low_rst = 0x00000000,
  261. .high_rst = 0x00000000,
  262. .wm_low = &wcn3990_src_wm_low,
  263. .wm_high = &wcn3990_src_wm_high,
  264. };
  265. static struct ath10k_hw_ce_regs_addr_map wcn3990_dst_wm_low = {
  266. .lsb = 0x00000010,
  267. .mask = GENMASK(31, 16),
  268. };
  269. static struct ath10k_hw_ce_regs_addr_map wcn3990_dst_wm_high = {
  270. .msb = 0x0000000f,
  271. .lsb = 0x00000000,
  272. .mask = GENMASK(15, 0),
  273. };
  274. static struct ath10k_hw_ce_dst_src_wm_regs wcn3990_wm_dst_ring = {
  275. .addr = 0x00000050,
  276. .low_rst = 0x00000000,
  277. .high_rst = 0x00000000,
  278. .wm_low = &wcn3990_dst_wm_low,
  279. .wm_high = &wcn3990_dst_wm_high,
  280. };
  281. static struct ath10k_hw_ce_ctrl1_upd wcn3990_ctrl1_upd = {
  282. .shift = 19,
  283. .mask = 0x00080000,
  284. .enable = 0x00000000,
  285. };
  286. const struct ath10k_hw_ce_regs wcn3990_ce_regs = {
  287. .sr_base_addr_lo = 0x00000000,
  288. .sr_base_addr_hi = 0x00000004,
  289. .sr_size_addr = 0x00000008,
  290. .dr_base_addr_lo = 0x0000000c,
  291. .dr_base_addr_hi = 0x00000010,
  292. .dr_size_addr = 0x00000014,
  293. .misc_ie_addr = 0x00000034,
  294. .sr_wr_index_addr = 0x0000003c,
  295. .dst_wr_index_addr = 0x00000040,
  296. .current_srri_addr = 0x00000044,
  297. .current_drri_addr = 0x00000048,
  298. .ce_rri_low = 0x0024C004,
  299. .ce_rri_high = 0x0024C008,
  300. .host_ie_addr = 0x0000002c,
  301. .ctrl1_regs = &wcn3990_ctrl1,
  302. .host_ie = &wcn3990_host_ie,
  303. .wm_regs = &wcn3990_wm_reg,
  304. .misc_regs = &wcn3990_misc_reg,
  305. .wm_srcr = &wcn3990_wm_src_ring,
  306. .wm_dstr = &wcn3990_wm_dst_ring,
  307. .upd = &wcn3990_ctrl1_upd,
  308. };
  309. const struct ath10k_hw_values wcn3990_values = {
  310. .rtc_state_val_on = 5,
  311. .ce_count = 12,
  312. .msi_assign_ce_max = 12,
  313. .num_target_ce_config_wlan = 12,
  314. .ce_desc_meta_data_mask = 0xFFF0,
  315. .ce_desc_meta_data_lsb = 4,
  316. };
  317. static struct ath10k_hw_ce_regs_addr_map qcax_src_ring = {
  318. .msb = 0x00000010,
  319. .lsb = 0x00000010,
  320. .mask = GENMASK(16, 16),
  321. };
  322. static struct ath10k_hw_ce_regs_addr_map qcax_dst_ring = {
  323. .msb = 0x00000011,
  324. .lsb = 0x00000011,
  325. .mask = GENMASK(17, 17),
  326. };
  327. static struct ath10k_hw_ce_regs_addr_map qcax_dmax = {
  328. .msb = 0x0000000f,
  329. .lsb = 0x00000000,
  330. .mask = GENMASK(15, 0),
  331. };
  332. static struct ath10k_hw_ce_ctrl1 qcax_ctrl1 = {
  333. .addr = 0x00000010,
  334. .hw_mask = 0x0007ffff,
  335. .sw_mask = 0x0007ffff,
  336. .hw_wr_mask = 0x00000000,
  337. .sw_wr_mask = 0x0007ffff,
  338. .reset_mask = 0xffffffff,
  339. .reset = 0x00000080,
  340. .src_ring = &qcax_src_ring,
  341. .dst_ring = &qcax_dst_ring,
  342. .dmax = &qcax_dmax,
  343. };
  344. static struct ath10k_hw_ce_regs_addr_map qcax_cmd_halt_status = {
  345. .msb = 0x00000003,
  346. .lsb = 0x00000003,
  347. .mask = GENMASK(3, 3),
  348. };
  349. static struct ath10k_hw_ce_cmd_halt qcax_cmd_halt = {
  350. .msb = 0x00000000,
  351. .mask = GENMASK(0, 0),
  352. .status_reset = 0x00000000,
  353. .status = &qcax_cmd_halt_status,
  354. };
  355. static struct ath10k_hw_ce_regs_addr_map qcax_host_ie_cc = {
  356. .msb = 0x00000000,
  357. .lsb = 0x00000000,
  358. .mask = GENMASK(0, 0),
  359. };
  360. static struct ath10k_hw_ce_host_ie qcax_host_ie = {
  361. .copy_complete_reset = 0x00000000,
  362. .copy_complete = &qcax_host_ie_cc,
  363. };
  364. static struct ath10k_hw_ce_host_wm_regs qcax_wm_reg = {
  365. .dstr_lmask = 0x00000010,
  366. .dstr_hmask = 0x00000008,
  367. .srcr_lmask = 0x00000004,
  368. .srcr_hmask = 0x00000002,
  369. .cc_mask = 0x00000001,
  370. .wm_mask = 0x0000001E,
  371. .addr = 0x00000030,
  372. };
  373. static struct ath10k_hw_ce_misc_regs qcax_misc_reg = {
  374. .axi_err = 0x00000400,
  375. .dstr_add_err = 0x00000200,
  376. .srcr_len_err = 0x00000100,
  377. .dstr_mlen_vio = 0x00000080,
  378. .dstr_overflow = 0x00000040,
  379. .srcr_overflow = 0x00000020,
  380. .err_mask = 0x000007E0,
  381. .addr = 0x00000038,
  382. };
  383. static struct ath10k_hw_ce_regs_addr_map qcax_src_wm_low = {
  384. .msb = 0x0000001f,
  385. .lsb = 0x00000010,
  386. .mask = GENMASK(31, 16),
  387. };
  388. static struct ath10k_hw_ce_regs_addr_map qcax_src_wm_high = {
  389. .msb = 0x0000000f,
  390. .lsb = 0x00000000,
  391. .mask = GENMASK(15, 0),
  392. };
  393. static struct ath10k_hw_ce_dst_src_wm_regs qcax_wm_src_ring = {
  394. .addr = 0x0000004c,
  395. .low_rst = 0x00000000,
  396. .high_rst = 0x00000000,
  397. .wm_low = &qcax_src_wm_low,
  398. .wm_high = &qcax_src_wm_high,
  399. };
  400. static struct ath10k_hw_ce_regs_addr_map qcax_dst_wm_low = {
  401. .lsb = 0x00000010,
  402. .mask = GENMASK(31, 16),
  403. };
  404. static struct ath10k_hw_ce_regs_addr_map qcax_dst_wm_high = {
  405. .msb = 0x0000000f,
  406. .lsb = 0x00000000,
  407. .mask = GENMASK(15, 0),
  408. };
  409. static struct ath10k_hw_ce_dst_src_wm_regs qcax_wm_dst_ring = {
  410. .addr = 0x00000050,
  411. .low_rst = 0x00000000,
  412. .high_rst = 0x00000000,
  413. .wm_low = &qcax_dst_wm_low,
  414. .wm_high = &qcax_dst_wm_high,
  415. };
  416. const struct ath10k_hw_ce_regs qcax_ce_regs = {
  417. .sr_base_addr_lo = 0x00000000,
  418. .sr_size_addr = 0x00000004,
  419. .dr_base_addr_lo = 0x00000008,
  420. .dr_size_addr = 0x0000000c,
  421. .ce_cmd_addr = 0x00000018,
  422. .misc_ie_addr = 0x00000034,
  423. .sr_wr_index_addr = 0x0000003c,
  424. .dst_wr_index_addr = 0x00000040,
  425. .current_srri_addr = 0x00000044,
  426. .current_drri_addr = 0x00000048,
  427. .host_ie_addr = 0x0000002c,
  428. .ctrl1_regs = &qcax_ctrl1,
  429. .cmd_halt = &qcax_cmd_halt,
  430. .host_ie = &qcax_host_ie,
  431. .wm_regs = &qcax_wm_reg,
  432. .misc_regs = &qcax_misc_reg,
  433. .wm_srcr = &qcax_wm_src_ring,
  434. .wm_dstr = &qcax_wm_dst_ring,
  435. };
  436. const struct ath10k_hw_clk_params qca6174_clk[ATH10K_HW_REFCLK_COUNT] = {
  437. {
  438. .refclk = 48000000,
  439. .div = 0xe,
  440. .rnfrac = 0x2aaa8,
  441. .settle_time = 2400,
  442. .refdiv = 0,
  443. .outdiv = 1,
  444. },
  445. {
  446. .refclk = 19200000,
  447. .div = 0x24,
  448. .rnfrac = 0x2aaa8,
  449. .settle_time = 960,
  450. .refdiv = 0,
  451. .outdiv = 1,
  452. },
  453. {
  454. .refclk = 24000000,
  455. .div = 0x1d,
  456. .rnfrac = 0x15551,
  457. .settle_time = 1200,
  458. .refdiv = 0,
  459. .outdiv = 1,
  460. },
  461. {
  462. .refclk = 26000000,
  463. .div = 0x1b,
  464. .rnfrac = 0x4ec4,
  465. .settle_time = 1300,
  466. .refdiv = 0,
  467. .outdiv = 1,
  468. },
  469. {
  470. .refclk = 37400000,
  471. .div = 0x12,
  472. .rnfrac = 0x34b49,
  473. .settle_time = 1870,
  474. .refdiv = 0,
  475. .outdiv = 1,
  476. },
  477. {
  478. .refclk = 38400000,
  479. .div = 0x12,
  480. .rnfrac = 0x15551,
  481. .settle_time = 1920,
  482. .refdiv = 0,
  483. .outdiv = 1,
  484. },
  485. {
  486. .refclk = 40000000,
  487. .div = 0x12,
  488. .rnfrac = 0x26665,
  489. .settle_time = 2000,
  490. .refdiv = 0,
  491. .outdiv = 1,
  492. },
  493. {
  494. .refclk = 52000000,
  495. .div = 0x1b,
  496. .rnfrac = 0x4ec4,
  497. .settle_time = 2600,
  498. .refdiv = 0,
  499. .outdiv = 1,
  500. },
  501. };
  502. void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
  503. u32 cc, u32 rcc, u32 cc_prev, u32 rcc_prev)
  504. {
  505. u32 cc_fix = 0;
  506. u32 rcc_fix = 0;
  507. enum ath10k_hw_cc_wraparound_type wraparound_type;
  508. survey->filled |= SURVEY_INFO_TIME |
  509. SURVEY_INFO_TIME_BUSY;
  510. wraparound_type = ar->hw_params.cc_wraparound_type;
  511. if (cc < cc_prev || rcc < rcc_prev) {
  512. switch (wraparound_type) {
  513. case ATH10K_HW_CC_WRAP_SHIFTED_ALL:
  514. if (cc < cc_prev) {
  515. cc_fix = 0x7fffffff;
  516. survey->filled &= ~SURVEY_INFO_TIME_BUSY;
  517. }
  518. break;
  519. case ATH10K_HW_CC_WRAP_SHIFTED_EACH:
  520. if (cc < cc_prev)
  521. cc_fix = 0x7fffffff;
  522. if (rcc < rcc_prev)
  523. rcc_fix = 0x7fffffff;
  524. break;
  525. case ATH10K_HW_CC_WRAP_DISABLED:
  526. break;
  527. }
  528. }
  529. cc -= cc_prev - cc_fix;
  530. rcc -= rcc_prev - rcc_fix;
  531. survey->time = CCNT_TO_MSEC(ar, cc);
  532. survey->time_busy = CCNT_TO_MSEC(ar, rcc);
  533. }
  534. /* The firmware does not support setting the coverage class. Instead this
  535. * function monitors and modifies the corresponding MAC registers.
  536. */
  537. static void ath10k_hw_qca988x_set_coverage_class(struct ath10k *ar,
  538. s16 value)
  539. {
  540. u32 slottime_reg;
  541. u32 slottime;
  542. u32 timeout_reg;
  543. u32 ack_timeout;
  544. u32 cts_timeout;
  545. u32 phyclk_reg;
  546. u32 phyclk;
  547. u64 fw_dbglog_mask;
  548. u32 fw_dbglog_level;
  549. mutex_lock(&ar->conf_mutex);
  550. /* Only modify registers if the core is started. */
  551. if ((ar->state != ATH10K_STATE_ON) &&
  552. (ar->state != ATH10K_STATE_RESTARTED)) {
  553. spin_lock_bh(&ar->data_lock);
  554. /* Store config value for when radio boots up */
  555. ar->fw_coverage.coverage_class = value;
  556. spin_unlock_bh(&ar->data_lock);
  557. goto unlock;
  558. }
  559. /* Retrieve the current values of the two registers that need to be
  560. * adjusted.
  561. */
  562. slottime_reg = ath10k_hif_read32(ar, WLAN_MAC_BASE_ADDRESS +
  563. WAVE1_PCU_GBL_IFS_SLOT);
  564. timeout_reg = ath10k_hif_read32(ar, WLAN_MAC_BASE_ADDRESS +
  565. WAVE1_PCU_ACK_CTS_TIMEOUT);
  566. phyclk_reg = ath10k_hif_read32(ar, WLAN_MAC_BASE_ADDRESS +
  567. WAVE1_PHYCLK);
  568. phyclk = MS(phyclk_reg, WAVE1_PHYCLK_USEC) + 1;
  569. if (value < 0)
  570. value = ar->fw_coverage.coverage_class;
  571. /* Break out if the coverage class and registers have the expected
  572. * value.
  573. */
  574. if (value == ar->fw_coverage.coverage_class &&
  575. slottime_reg == ar->fw_coverage.reg_slottime_conf &&
  576. timeout_reg == ar->fw_coverage.reg_ack_cts_timeout_conf &&
  577. phyclk_reg == ar->fw_coverage.reg_phyclk)
  578. goto unlock;
  579. /* Store new initial register values from the firmware. */
  580. if (slottime_reg != ar->fw_coverage.reg_slottime_conf)
  581. ar->fw_coverage.reg_slottime_orig = slottime_reg;
  582. if (timeout_reg != ar->fw_coverage.reg_ack_cts_timeout_conf)
  583. ar->fw_coverage.reg_ack_cts_timeout_orig = timeout_reg;
  584. ar->fw_coverage.reg_phyclk = phyclk_reg;
  585. /* Calculate new value based on the (original) firmware calculation. */
  586. slottime_reg = ar->fw_coverage.reg_slottime_orig;
  587. timeout_reg = ar->fw_coverage.reg_ack_cts_timeout_orig;
  588. /* Do some sanity checks on the slottime register. */
  589. if (slottime_reg % phyclk) {
  590. ath10k_warn(ar,
  591. "failed to set coverage class: expected integer microsecond value in register\n");
  592. goto store_regs;
  593. }
  594. slottime = MS(slottime_reg, WAVE1_PCU_GBL_IFS_SLOT);
  595. slottime = slottime / phyclk;
  596. if (slottime != 9 && slottime != 20) {
  597. ath10k_warn(ar,
  598. "failed to set coverage class: expected slot time of 9 or 20us in HW register. It is %uus.\n",
  599. slottime);
  600. goto store_regs;
  601. }
  602. /* Recalculate the register values by adding the additional propagation
  603. * delay (3us per coverage class).
  604. */
  605. slottime = MS(slottime_reg, WAVE1_PCU_GBL_IFS_SLOT);
  606. slottime += value * 3 * phyclk;
  607. slottime = min_t(u32, slottime, WAVE1_PCU_GBL_IFS_SLOT_MAX);
  608. slottime = SM(slottime, WAVE1_PCU_GBL_IFS_SLOT);
  609. slottime_reg = (slottime_reg & ~WAVE1_PCU_GBL_IFS_SLOT_MASK) | slottime;
  610. /* Update ack timeout (lower halfword). */
  611. ack_timeout = MS(timeout_reg, WAVE1_PCU_ACK_CTS_TIMEOUT_ACK);
  612. ack_timeout += 3 * value * phyclk;
  613. ack_timeout = min_t(u32, ack_timeout, WAVE1_PCU_ACK_CTS_TIMEOUT_MAX);
  614. ack_timeout = SM(ack_timeout, WAVE1_PCU_ACK_CTS_TIMEOUT_ACK);
  615. /* Update cts timeout (upper halfword). */
  616. cts_timeout = MS(timeout_reg, WAVE1_PCU_ACK_CTS_TIMEOUT_CTS);
  617. cts_timeout += 3 * value * phyclk;
  618. cts_timeout = min_t(u32, cts_timeout, WAVE1_PCU_ACK_CTS_TIMEOUT_MAX);
  619. cts_timeout = SM(cts_timeout, WAVE1_PCU_ACK_CTS_TIMEOUT_CTS);
  620. timeout_reg = ack_timeout | cts_timeout;
  621. ath10k_hif_write32(ar,
  622. WLAN_MAC_BASE_ADDRESS + WAVE1_PCU_GBL_IFS_SLOT,
  623. slottime_reg);
  624. ath10k_hif_write32(ar,
  625. WLAN_MAC_BASE_ADDRESS + WAVE1_PCU_ACK_CTS_TIMEOUT,
  626. timeout_reg);
  627. /* Ensure we have a debug level of WARN set for the case that the
  628. * coverage class is larger than 0. This is important as we need to
  629. * set the registers again if the firmware does an internal reset and
  630. * this way we will be notified of the event.
  631. */
  632. fw_dbglog_mask = ath10k_debug_get_fw_dbglog_mask(ar);
  633. fw_dbglog_level = ath10k_debug_get_fw_dbglog_level(ar);
  634. if (value > 0) {
  635. if (fw_dbglog_level > ATH10K_DBGLOG_LEVEL_WARN)
  636. fw_dbglog_level = ATH10K_DBGLOG_LEVEL_WARN;
  637. fw_dbglog_mask = ~0;
  638. }
  639. ath10k_wmi_dbglog_cfg(ar, fw_dbglog_mask, fw_dbglog_level);
  640. store_regs:
  641. /* After an error we will not retry setting the coverage class. */
  642. spin_lock_bh(&ar->data_lock);
  643. ar->fw_coverage.coverage_class = value;
  644. spin_unlock_bh(&ar->data_lock);
  645. ar->fw_coverage.reg_slottime_conf = slottime_reg;
  646. ar->fw_coverage.reg_ack_cts_timeout_conf = timeout_reg;
  647. unlock:
  648. mutex_unlock(&ar->conf_mutex);
  649. }
  650. /**
  651. * ath10k_hw_qca6174_enable_pll_clock() - enable the qca6174 hw pll clock
  652. * @ar: the ath10k blob
  653. *
  654. * This function is very hardware specific, the clock initialization
  655. * steps is very sensitive and could lead to unknown crash, so they
  656. * should be done in sequence.
  657. *
  658. * *** Be aware if you planned to refactor them. ***
  659. *
  660. * Return: 0 if successfully enable the pll, otherwise EINVAL
  661. */
  662. static int ath10k_hw_qca6174_enable_pll_clock(struct ath10k *ar)
  663. {
  664. int ret, wait_limit;
  665. u32 clk_div_addr, pll_init_addr, speed_addr;
  666. u32 addr, reg_val, mem_val;
  667. struct ath10k_hw_params *hw;
  668. const struct ath10k_hw_clk_params *hw_clk;
  669. hw = &ar->hw_params;
  670. if (ar->regs->core_clk_div_address == 0 ||
  671. ar->regs->cpu_pll_init_address == 0 ||
  672. ar->regs->cpu_speed_address == 0)
  673. return -EINVAL;
  674. clk_div_addr = ar->regs->core_clk_div_address;
  675. pll_init_addr = ar->regs->cpu_pll_init_address;
  676. speed_addr = ar->regs->cpu_speed_address;
  677. /* Read efuse register to find out the right hw clock configuration */
  678. addr = (RTC_SOC_BASE_ADDRESS | EFUSE_OFFSET);
  679. ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
  680. if (ret)
  681. return -EINVAL;
  682. /* sanitize if the hw refclk index is out of the boundary */
  683. if (MS(reg_val, EFUSE_XTAL_SEL) > ATH10K_HW_REFCLK_COUNT)
  684. return -EINVAL;
  685. hw_clk = &hw->hw_clk[MS(reg_val, EFUSE_XTAL_SEL)];
  686. /* Set the rnfrac and outdiv params to bb_pll register */
  687. addr = (RTC_SOC_BASE_ADDRESS | BB_PLL_CONFIG_OFFSET);
  688. ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
  689. if (ret)
  690. return -EINVAL;
  691. reg_val &= ~(BB_PLL_CONFIG_FRAC_MASK | BB_PLL_CONFIG_OUTDIV_MASK);
  692. reg_val |= (SM(hw_clk->rnfrac, BB_PLL_CONFIG_FRAC) |
  693. SM(hw_clk->outdiv, BB_PLL_CONFIG_OUTDIV));
  694. ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
  695. if (ret)
  696. return -EINVAL;
  697. /* Set the correct settle time value to pll_settle register */
  698. addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_SETTLE_OFFSET);
  699. ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
  700. if (ret)
  701. return -EINVAL;
  702. reg_val &= ~WLAN_PLL_SETTLE_TIME_MASK;
  703. reg_val |= SM(hw_clk->settle_time, WLAN_PLL_SETTLE_TIME);
  704. ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
  705. if (ret)
  706. return -EINVAL;
  707. /* Set the clock_ctrl div to core_clk_ctrl register */
  708. addr = (RTC_SOC_BASE_ADDRESS | SOC_CORE_CLK_CTRL_OFFSET);
  709. ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
  710. if (ret)
  711. return -EINVAL;
  712. reg_val &= ~SOC_CORE_CLK_CTRL_DIV_MASK;
  713. reg_val |= SM(1, SOC_CORE_CLK_CTRL_DIV);
  714. ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
  715. if (ret)
  716. return -EINVAL;
  717. /* Set the clock_div register */
  718. mem_val = 1;
  719. ret = ath10k_bmi_write_memory(ar, clk_div_addr, &mem_val,
  720. sizeof(mem_val));
  721. if (ret)
  722. return -EINVAL;
  723. /* Configure the pll_control register */
  724. addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET);
  725. ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
  726. if (ret)
  727. return -EINVAL;
  728. reg_val |= (SM(hw_clk->refdiv, WLAN_PLL_CONTROL_REFDIV) |
  729. SM(hw_clk->div, WLAN_PLL_CONTROL_DIV) |
  730. SM(1, WLAN_PLL_CONTROL_NOPWD));
  731. ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
  732. if (ret)
  733. return -EINVAL;
  734. /* busy wait (max 1s) the rtc_sync status register indicate ready */
  735. wait_limit = 100000;
  736. addr = (RTC_WMAC_BASE_ADDRESS | RTC_SYNC_STATUS_OFFSET);
  737. do {
  738. ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
  739. if (ret)
  740. return -EINVAL;
  741. if (!MS(reg_val, RTC_SYNC_STATUS_PLL_CHANGING))
  742. break;
  743. wait_limit--;
  744. udelay(10);
  745. } while (wait_limit > 0);
  746. if (MS(reg_val, RTC_SYNC_STATUS_PLL_CHANGING))
  747. return -EINVAL;
  748. /* Unset the pll_bypass in pll_control register */
  749. addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET);
  750. ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
  751. if (ret)
  752. return -EINVAL;
  753. reg_val &= ~WLAN_PLL_CONTROL_BYPASS_MASK;
  754. reg_val |= SM(0, WLAN_PLL_CONTROL_BYPASS);
  755. ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
  756. if (ret)
  757. return -EINVAL;
  758. /* busy wait (max 1s) the rtc_sync status register indicate ready */
  759. wait_limit = 100000;
  760. addr = (RTC_WMAC_BASE_ADDRESS | RTC_SYNC_STATUS_OFFSET);
  761. do {
  762. ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
  763. if (ret)
  764. return -EINVAL;
  765. if (!MS(reg_val, RTC_SYNC_STATUS_PLL_CHANGING))
  766. break;
  767. wait_limit--;
  768. udelay(10);
  769. } while (wait_limit > 0);
  770. if (MS(reg_val, RTC_SYNC_STATUS_PLL_CHANGING))
  771. return -EINVAL;
  772. /* Enable the hardware cpu clock register */
  773. addr = (RTC_SOC_BASE_ADDRESS | SOC_CPU_CLOCK_OFFSET);
  774. ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
  775. if (ret)
  776. return -EINVAL;
  777. reg_val &= ~SOC_CPU_CLOCK_STANDARD_MASK;
  778. reg_val |= SM(1, SOC_CPU_CLOCK_STANDARD);
  779. ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
  780. if (ret)
  781. return -EINVAL;
  782. /* unset the nopwd from pll_control register */
  783. addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET);
  784. ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
  785. if (ret)
  786. return -EINVAL;
  787. reg_val &= ~WLAN_PLL_CONTROL_NOPWD_MASK;
  788. ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
  789. if (ret)
  790. return -EINVAL;
  791. /* enable the pll_init register */
  792. mem_val = 1;
  793. ret = ath10k_bmi_write_memory(ar, pll_init_addr, &mem_val,
  794. sizeof(mem_val));
  795. if (ret)
  796. return -EINVAL;
  797. /* set the target clock frequency to speed register */
  798. ret = ath10k_bmi_write_memory(ar, speed_addr, &hw->target_cpu_freq,
  799. sizeof(hw->target_cpu_freq));
  800. if (ret)
  801. return -EINVAL;
  802. return 0;
  803. }
  804. /* Program CPU_ADDR_MSB to allow different memory
  805. * region access.
  806. */
  807. static void ath10k_hw_map_target_mem(struct ath10k *ar, u32 msb)
  808. {
  809. u32 address = SOC_CORE_BASE_ADDRESS + FW_RAM_CONFIG_ADDRESS;
  810. ath10k_hif_write32(ar, address, msb);
  811. }
  812. /* 1. Write to memory region of target, such as IRAM and DRAM.
  813. * 2. Target address( 0 ~ 00100000 & 0x00400000~0x00500000)
  814. * can be written directly. See ath10k_pci_targ_cpu_to_ce_addr() too.
  815. * 3. In order to access the region other than the above,
  816. * we need to set the value of register CPU_ADDR_MSB.
  817. * 4. Target memory access space is limited to 1M size. If the size is larger
  818. * than 1M, need to split it and program CPU_ADDR_MSB accordingly.
  819. */
  820. static int ath10k_hw_diag_segment_msb_download(struct ath10k *ar,
  821. const void *buffer,
  822. u32 address,
  823. u32 length)
  824. {
  825. u32 addr = address & REGION_ACCESS_SIZE_MASK;
  826. int ret, remain_size, size;
  827. const u8 *buf;
  828. ath10k_hw_map_target_mem(ar, CPU_ADDR_MSB_REGION_VAL(address));
  829. if (addr + length > REGION_ACCESS_SIZE_LIMIT) {
  830. size = REGION_ACCESS_SIZE_LIMIT - addr;
  831. remain_size = length - size;
  832. ret = ath10k_hif_diag_write(ar, address, buffer, size);
  833. if (ret) {
  834. ath10k_warn(ar,
  835. "failed to download the first %d bytes segment to address:0x%x: %d\n",
  836. size, address, ret);
  837. goto done;
  838. }
  839. /* Change msb to the next memory region*/
  840. ath10k_hw_map_target_mem(ar,
  841. CPU_ADDR_MSB_REGION_VAL(address) + 1);
  842. buf = buffer + size;
  843. ret = ath10k_hif_diag_write(ar,
  844. address & ~REGION_ACCESS_SIZE_MASK,
  845. buf, remain_size);
  846. if (ret) {
  847. ath10k_warn(ar,
  848. "failed to download the second %d bytes segment to address:0x%x: %d\n",
  849. remain_size,
  850. address & ~REGION_ACCESS_SIZE_MASK,
  851. ret);
  852. goto done;
  853. }
  854. } else {
  855. ret = ath10k_hif_diag_write(ar, address, buffer, length);
  856. if (ret) {
  857. ath10k_warn(ar,
  858. "failed to download the only %d bytes segment to address:0x%x: %d\n",
  859. length, address, ret);
  860. goto done;
  861. }
  862. }
  863. done:
  864. /* Change msb to DRAM */
  865. ath10k_hw_map_target_mem(ar,
  866. CPU_ADDR_MSB_REGION_VAL(DRAM_BASE_ADDRESS));
  867. return ret;
  868. }
  869. static int ath10k_hw_diag_segment_download(struct ath10k *ar,
  870. const void *buffer,
  871. u32 address,
  872. u32 length)
  873. {
  874. if (address >= DRAM_BASE_ADDRESS + REGION_ACCESS_SIZE_LIMIT)
  875. /* Needs to change MSB for memory write */
  876. return ath10k_hw_diag_segment_msb_download(ar, buffer,
  877. address, length);
  878. else
  879. return ath10k_hif_diag_write(ar, address, buffer, length);
  880. }
  881. int ath10k_hw_diag_fast_download(struct ath10k *ar,
  882. u32 address,
  883. const void *buffer,
  884. u32 length)
  885. {
  886. const u8 *buf = buffer;
  887. bool sgmt_end = false;
  888. u32 base_addr = 0;
  889. u32 base_len = 0;
  890. u32 left = 0;
  891. struct bmi_segmented_file_header *hdr;
  892. struct bmi_segmented_metadata *metadata;
  893. int ret = 0;
  894. if (length < sizeof(*hdr))
  895. return -EINVAL;
  896. /* check firmware header. If it has no correct magic number
  897. * or it's compressed, returns error.
  898. */
  899. hdr = (struct bmi_segmented_file_header *)buf;
  900. if (__le32_to_cpu(hdr->magic_num) != BMI_SGMTFILE_MAGIC_NUM) {
  901. ath10k_dbg(ar, ATH10K_DBG_BOOT,
  902. "Not a supported firmware, magic_num:0x%x\n",
  903. hdr->magic_num);
  904. return -EINVAL;
  905. }
  906. if (hdr->file_flags != 0) {
  907. ath10k_dbg(ar, ATH10K_DBG_BOOT,
  908. "Not a supported firmware, file_flags:0x%x\n",
  909. hdr->file_flags);
  910. return -EINVAL;
  911. }
  912. metadata = (struct bmi_segmented_metadata *)hdr->data;
  913. left = length - sizeof(*hdr);
  914. while (left > 0) {
  915. if (left < sizeof(*metadata)) {
  916. ath10k_warn(ar, "firmware segment is truncated: %d\n",
  917. left);
  918. ret = -EINVAL;
  919. break;
  920. }
  921. base_addr = __le32_to_cpu(metadata->addr);
  922. base_len = __le32_to_cpu(metadata->length);
  923. buf = metadata->data;
  924. left -= sizeof(*metadata);
  925. switch (base_len) {
  926. case BMI_SGMTFILE_BEGINADDR:
  927. /* base_addr is the start address to run */
  928. ret = ath10k_bmi_set_start(ar, base_addr);
  929. base_len = 0;
  930. break;
  931. case BMI_SGMTFILE_DONE:
  932. /* no more segment */
  933. base_len = 0;
  934. sgmt_end = true;
  935. ret = 0;
  936. break;
  937. case BMI_SGMTFILE_BDDATA:
  938. case BMI_SGMTFILE_EXEC:
  939. ath10k_warn(ar,
  940. "firmware has unsupported segment:%d\n",
  941. base_len);
  942. ret = -EINVAL;
  943. break;
  944. default:
  945. if (base_len > left) {
  946. /* sanity check */
  947. ath10k_warn(ar,
  948. "firmware has invalid segment length, %d > %d\n",
  949. base_len, left);
  950. ret = -EINVAL;
  951. break;
  952. }
  953. ret = ath10k_hw_diag_segment_download(ar,
  954. buf,
  955. base_addr,
  956. base_len);
  957. if (ret)
  958. ath10k_warn(ar,
  959. "failed to download firmware via diag interface:%d\n",
  960. ret);
  961. break;
  962. }
  963. if (ret || sgmt_end)
  964. break;
  965. metadata = (struct bmi_segmented_metadata *)(buf + base_len);
  966. left -= base_len;
  967. }
  968. if (ret == 0)
  969. ath10k_dbg(ar, ATH10K_DBG_BOOT,
  970. "boot firmware fast diag download successfully.\n");
  971. return ret;
  972. }
  973. static int ath10k_htt_tx_rssi_enable(struct htt_resp *resp)
  974. {
  975. return (resp->data_tx_completion.flags2 & HTT_TX_CMPL_FLAG_DATA_RSSI);
  976. }
  977. static int ath10k_htt_tx_rssi_enable_wcn3990(struct htt_resp *resp)
  978. {
  979. return (resp->data_tx_completion.flags2 &
  980. HTT_TX_DATA_RSSI_ENABLE_WCN3990);
  981. }
  982. static int ath10k_get_htt_tx_data_rssi_pad(struct htt_resp *resp)
  983. {
  984. struct htt_data_tx_completion_ext extd;
  985. int pad_bytes = 0;
  986. if (resp->data_tx_completion.flags2 & HTT_TX_DATA_APPEND_RETRIES)
  987. pad_bytes += sizeof(extd.a_retries) /
  988. sizeof(extd.msdus_rssi[0]);
  989. if (resp->data_tx_completion.flags2 & HTT_TX_DATA_APPEND_TIMESTAMP)
  990. pad_bytes += sizeof(extd.t_stamp) / sizeof(extd.msdus_rssi[0]);
  991. return pad_bytes;
  992. }
  993. const struct ath10k_hw_ops qca988x_ops = {
  994. .set_coverage_class = ath10k_hw_qca988x_set_coverage_class,
  995. .is_rssi_enable = ath10k_htt_tx_rssi_enable,
  996. };
  997. const struct ath10k_hw_ops qca99x0_ops = {
  998. .is_rssi_enable = ath10k_htt_tx_rssi_enable,
  999. };
  1000. const struct ath10k_hw_ops qca6174_ops = {
  1001. .set_coverage_class = ath10k_hw_qca988x_set_coverage_class,
  1002. .enable_pll_clk = ath10k_hw_qca6174_enable_pll_clock,
  1003. .is_rssi_enable = ath10k_htt_tx_rssi_enable,
  1004. };
  1005. const struct ath10k_hw_ops qca6174_sdio_ops = {
  1006. .enable_pll_clk = ath10k_hw_qca6174_enable_pll_clock,
  1007. };
  1008. const struct ath10k_hw_ops wcn3990_ops = {
  1009. .tx_data_rssi_pad_bytes = ath10k_get_htt_tx_data_rssi_pad,
  1010. .is_rssi_enable = ath10k_htt_tx_rssi_enable_wcn3990,
  1011. };