cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

hw.c (32257B)


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