Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: ISC
0002 /*
0003  * Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
0004  */
0005 
0006 #include <linux/types.h>
0007 #include <linux/bitops.h>
0008 #include <linux/bitfield.h>
0009 #include "core.h"
0010 #include "hw.h"
0011 #include "hif.h"
0012 #include "wmi-ops.h"
0013 #include "bmi.h"
0014 #include "rx_desc.h"
0015 
0016 const struct ath10k_hw_regs qca988x_regs = {
0017     .rtc_soc_base_address       = 0x00004000,
0018     .rtc_wmac_base_address      = 0x00005000,
0019     .soc_core_base_address      = 0x00009000,
0020     .wlan_mac_base_address      = 0x00020000,
0021     .ce_wrapper_base_address    = 0x00057000,
0022     .ce0_base_address       = 0x00057400,
0023     .ce1_base_address       = 0x00057800,
0024     .ce2_base_address       = 0x00057c00,
0025     .ce3_base_address       = 0x00058000,
0026     .ce4_base_address       = 0x00058400,
0027     .ce5_base_address       = 0x00058800,
0028     .ce6_base_address       = 0x00058c00,
0029     .ce7_base_address       = 0x00059000,
0030     .soc_reset_control_si0_rst_mask = 0x00000001,
0031     .soc_reset_control_ce_rst_mask  = 0x00040000,
0032     .soc_chip_id_address        = 0x000000ec,
0033     .scratch_3_address      = 0x00000030,
0034     .fw_indicator_address       = 0x00009030,
0035     .pcie_local_base_address    = 0x00080000,
0036     .ce_wrap_intr_sum_host_msi_lsb  = 0x00000008,
0037     .ce_wrap_intr_sum_host_msi_mask = 0x0000ff00,
0038     .pcie_intr_fw_mask      = 0x00000400,
0039     .pcie_intr_ce_mask_all      = 0x0007f800,
0040     .pcie_intr_clr_address      = 0x00000014,
0041 };
0042 
0043 const struct ath10k_hw_regs qca6174_regs = {
0044     .rtc_soc_base_address           = 0x00000800,
0045     .rtc_wmac_base_address          = 0x00001000,
0046     .soc_core_base_address          = 0x0003a000,
0047     .wlan_mac_base_address          = 0x00010000,
0048     .ce_wrapper_base_address        = 0x00034000,
0049     .ce0_base_address           = 0x00034400,
0050     .ce1_base_address           = 0x00034800,
0051     .ce2_base_address           = 0x00034c00,
0052     .ce3_base_address           = 0x00035000,
0053     .ce4_base_address           = 0x00035400,
0054     .ce5_base_address           = 0x00035800,
0055     .ce6_base_address           = 0x00035c00,
0056     .ce7_base_address           = 0x00036000,
0057     .soc_reset_control_si0_rst_mask     = 0x00000000,
0058     .soc_reset_control_ce_rst_mask      = 0x00000001,
0059     .soc_chip_id_address            = 0x000000f0,
0060     .scratch_3_address          = 0x00000028,
0061     .fw_indicator_address           = 0x0003a028,
0062     .pcie_local_base_address        = 0x00080000,
0063     .ce_wrap_intr_sum_host_msi_lsb      = 0x00000008,
0064     .ce_wrap_intr_sum_host_msi_mask     = 0x0000ff00,
0065     .pcie_intr_fw_mask          = 0x00000400,
0066     .pcie_intr_ce_mask_all          = 0x0007f800,
0067     .pcie_intr_clr_address          = 0x00000014,
0068     .cpu_pll_init_address           = 0x00404020,
0069     .cpu_speed_address          = 0x00404024,
0070     .core_clk_div_address           = 0x00404028,
0071 };
0072 
0073 const struct ath10k_hw_regs qca99x0_regs = {
0074     .rtc_soc_base_address           = 0x00080000,
0075     .rtc_wmac_base_address          = 0x00000000,
0076     .soc_core_base_address          = 0x00082000,
0077     .wlan_mac_base_address          = 0x00030000,
0078     .ce_wrapper_base_address        = 0x0004d000,
0079     .ce0_base_address           = 0x0004a000,
0080     .ce1_base_address           = 0x0004a400,
0081     .ce2_base_address           = 0x0004a800,
0082     .ce3_base_address           = 0x0004ac00,
0083     .ce4_base_address           = 0x0004b000,
0084     .ce5_base_address           = 0x0004b400,
0085     .ce6_base_address           = 0x0004b800,
0086     .ce7_base_address           = 0x0004bc00,
0087     /* Note: qca99x0 supports upto 12 Copy Engines. Other than address of
0088      * CE0 and CE1 no other copy engine is directly referred in the code.
0089      * It is not really necessary to assign address for newly supported
0090      * CEs in this address table.
0091      *  Copy Engine     Address
0092      *  CE8         0x0004c000
0093      *  CE9         0x0004c400
0094      *  CE10            0x0004c800
0095      *  CE11            0x0004cc00
0096      */
0097     .soc_reset_control_si0_rst_mask     = 0x00000001,
0098     .soc_reset_control_ce_rst_mask      = 0x00000100,
0099     .soc_chip_id_address            = 0x000000ec,
0100     .scratch_3_address          = 0x00040050,
0101     .fw_indicator_address           = 0x00040050,
0102     .pcie_local_base_address        = 0x00000000,
0103     .ce_wrap_intr_sum_host_msi_lsb      = 0x0000000c,
0104     .ce_wrap_intr_sum_host_msi_mask     = 0x00fff000,
0105     .pcie_intr_fw_mask          = 0x00100000,
0106     .pcie_intr_ce_mask_all          = 0x000fff00,
0107     .pcie_intr_clr_address          = 0x00000010,
0108 };
0109 
0110 const struct ath10k_hw_regs qca4019_regs = {
0111     .rtc_soc_base_address                   = 0x00080000,
0112     .soc_core_base_address                  = 0x00082000,
0113     .wlan_mac_base_address                  = 0x00030000,
0114     .ce_wrapper_base_address                = 0x0004d000,
0115     .ce0_base_address                       = 0x0004a000,
0116     .ce1_base_address                       = 0x0004a400,
0117     .ce2_base_address                       = 0x0004a800,
0118     .ce3_base_address                       = 0x0004ac00,
0119     .ce4_base_address                       = 0x0004b000,
0120     .ce5_base_address                       = 0x0004b400,
0121     .ce6_base_address                       = 0x0004b800,
0122     .ce7_base_address                       = 0x0004bc00,
0123     /* qca4019 supports upto 12 copy engines. Since base address
0124      * of ce8 to ce11 are not directly referred in the code,
0125      * no need have them in separate members in this table.
0126      *      Copy Engine             Address
0127      *      CE8                     0x0004c000
0128      *      CE9                     0x0004c400
0129      *      CE10                    0x0004c800
0130      *      CE11                    0x0004cc00
0131      */
0132     .soc_reset_control_si0_rst_mask         = 0x00000001,
0133     .soc_reset_control_ce_rst_mask          = 0x00000100,
0134     .soc_chip_id_address                    = 0x000000ec,
0135     .fw_indicator_address                   = 0x0004f00c,
0136     .ce_wrap_intr_sum_host_msi_lsb          = 0x0000000c,
0137     .ce_wrap_intr_sum_host_msi_mask         = 0x00fff000,
0138     .pcie_intr_fw_mask                      = 0x00100000,
0139     .pcie_intr_ce_mask_all                  = 0x000fff00,
0140     .pcie_intr_clr_address                  = 0x00000010,
0141 };
0142 
0143 const struct ath10k_hw_values qca988x_values = {
0144     .rtc_state_val_on       = 3,
0145     .ce_count           = 8,
0146     .msi_assign_ce_max      = 7,
0147     .num_target_ce_config_wlan  = 7,
0148     .ce_desc_meta_data_mask     = 0xFFFC,
0149     .ce_desc_meta_data_lsb      = 2,
0150 };
0151 
0152 const struct ath10k_hw_values qca6174_values = {
0153     .rtc_state_val_on       = 3,
0154     .ce_count           = 8,
0155     .msi_assign_ce_max      = 7,
0156     .num_target_ce_config_wlan  = 7,
0157     .ce_desc_meta_data_mask     = 0xFFFC,
0158     .ce_desc_meta_data_lsb      = 2,
0159     .rfkill_pin         = 16,
0160     .rfkill_cfg         = 0,
0161     .rfkill_on_level        = 1,
0162 };
0163 
0164 const struct ath10k_hw_values qca99x0_values = {
0165     .rtc_state_val_on       = 7,
0166     .ce_count           = 12,
0167     .msi_assign_ce_max      = 12,
0168     .num_target_ce_config_wlan  = 10,
0169     .ce_desc_meta_data_mask     = 0xFFF0,
0170     .ce_desc_meta_data_lsb      = 4,
0171 };
0172 
0173 const struct ath10k_hw_values qca9888_values = {
0174     .rtc_state_val_on       = 3,
0175     .ce_count           = 12,
0176     .msi_assign_ce_max      = 12,
0177     .num_target_ce_config_wlan  = 10,
0178     .ce_desc_meta_data_mask     = 0xFFF0,
0179     .ce_desc_meta_data_lsb      = 4,
0180 };
0181 
0182 const struct ath10k_hw_values qca4019_values = {
0183     .ce_count                       = 12,
0184     .num_target_ce_config_wlan      = 10,
0185     .ce_desc_meta_data_mask         = 0xFFF0,
0186     .ce_desc_meta_data_lsb          = 4,
0187 };
0188 
0189 const struct ath10k_hw_regs wcn3990_regs = {
0190     .rtc_soc_base_address           = 0x00000000,
0191     .rtc_wmac_base_address          = 0x00000000,
0192     .soc_core_base_address          = 0x00000000,
0193     .ce_wrapper_base_address        = 0x0024C000,
0194     .ce0_base_address           = 0x00240000,
0195     .ce1_base_address           = 0x00241000,
0196     .ce2_base_address           = 0x00242000,
0197     .ce3_base_address           = 0x00243000,
0198     .ce4_base_address           = 0x00244000,
0199     .ce5_base_address           = 0x00245000,
0200     .ce6_base_address           = 0x00246000,
0201     .ce7_base_address           = 0x00247000,
0202     .ce8_base_address           = 0x00248000,
0203     .ce9_base_address           = 0x00249000,
0204     .ce10_base_address          = 0x0024A000,
0205     .ce11_base_address          = 0x0024B000,
0206     .soc_chip_id_address            = 0x000000f0,
0207     .soc_reset_control_si0_rst_mask     = 0x00000001,
0208     .soc_reset_control_ce_rst_mask      = 0x00000100,
0209     .ce_wrap_intr_sum_host_msi_lsb      = 0x0000000c,
0210     .ce_wrap_intr_sum_host_msi_mask     = 0x00fff000,
0211     .pcie_intr_fw_mask          = 0x00100000,
0212 };
0213 
0214 static struct ath10k_hw_ce_regs_addr_map wcn3990_src_ring = {
0215     .msb    = 0x00000010,
0216     .lsb    = 0x00000010,
0217     .mask   = GENMASK(17, 17),
0218 };
0219 
0220 static struct ath10k_hw_ce_regs_addr_map wcn3990_dst_ring = {
0221     .msb    = 0x00000012,
0222     .lsb    = 0x00000012,
0223     .mask   = GENMASK(18, 18),
0224 };
0225 
0226 static struct ath10k_hw_ce_regs_addr_map wcn3990_dmax = {
0227     .msb    = 0x00000000,
0228     .lsb    = 0x00000000,
0229     .mask   = GENMASK(15, 0),
0230 };
0231 
0232 static struct ath10k_hw_ce_ctrl1 wcn3990_ctrl1 = {
0233     .addr       = 0x00000018,
0234     .src_ring   = &wcn3990_src_ring,
0235     .dst_ring   = &wcn3990_dst_ring,
0236     .dmax       = &wcn3990_dmax,
0237 };
0238 
0239 static struct ath10k_hw_ce_regs_addr_map wcn3990_host_ie_cc = {
0240     .mask   = GENMASK(0, 0),
0241 };
0242 
0243 static struct ath10k_hw_ce_host_ie wcn3990_host_ie = {
0244     .copy_complete  = &wcn3990_host_ie_cc,
0245 };
0246 
0247 static struct ath10k_hw_ce_host_wm_regs wcn3990_wm_reg = {
0248     .dstr_lmask = 0x00000010,
0249     .dstr_hmask = 0x00000008,
0250     .srcr_lmask = 0x00000004,
0251     .srcr_hmask = 0x00000002,
0252     .cc_mask    = 0x00000001,
0253     .wm_mask    = 0x0000001E,
0254     .addr       = 0x00000030,
0255 };
0256 
0257 static struct ath10k_hw_ce_misc_regs wcn3990_misc_reg = {
0258     .axi_err    = 0x00000100,
0259     .dstr_add_err   = 0x00000200,
0260     .srcr_len_err   = 0x00000100,
0261     .dstr_mlen_vio  = 0x00000080,
0262     .dstr_overflow  = 0x00000040,
0263     .srcr_overflow  = 0x00000020,
0264     .err_mask   = 0x000003E0,
0265     .addr       = 0x00000038,
0266 };
0267 
0268 static struct ath10k_hw_ce_regs_addr_map wcn3990_src_wm_low = {
0269     .msb    = 0x00000000,
0270     .lsb    = 0x00000010,
0271     .mask   = GENMASK(31, 16),
0272 };
0273 
0274 static struct ath10k_hw_ce_regs_addr_map wcn3990_src_wm_high = {
0275     .msb    = 0x0000000f,
0276     .lsb    = 0x00000000,
0277     .mask   = GENMASK(15, 0),
0278 };
0279 
0280 static struct ath10k_hw_ce_dst_src_wm_regs wcn3990_wm_src_ring = {
0281     .addr       = 0x0000004c,
0282     .low_rst    = 0x00000000,
0283     .high_rst   = 0x00000000,
0284     .wm_low     = &wcn3990_src_wm_low,
0285     .wm_high    = &wcn3990_src_wm_high,
0286 };
0287 
0288 static struct ath10k_hw_ce_regs_addr_map wcn3990_dst_wm_low = {
0289     .lsb    = 0x00000010,
0290     .mask   = GENMASK(31, 16),
0291 };
0292 
0293 static struct ath10k_hw_ce_regs_addr_map wcn3990_dst_wm_high = {
0294     .msb    = 0x0000000f,
0295     .lsb    = 0x00000000,
0296     .mask   = GENMASK(15, 0),
0297 };
0298 
0299 static struct ath10k_hw_ce_dst_src_wm_regs wcn3990_wm_dst_ring = {
0300     .addr       = 0x00000050,
0301     .low_rst    = 0x00000000,
0302     .high_rst   = 0x00000000,
0303     .wm_low     = &wcn3990_dst_wm_low,
0304     .wm_high    = &wcn3990_dst_wm_high,
0305 };
0306 
0307 static struct ath10k_hw_ce_ctrl1_upd wcn3990_ctrl1_upd = {
0308     .shift = 19,
0309     .mask = 0x00080000,
0310     .enable = 0x00000000,
0311 };
0312 
0313 const struct ath10k_hw_ce_regs wcn3990_ce_regs = {
0314     .sr_base_addr_lo    = 0x00000000,
0315     .sr_base_addr_hi    = 0x00000004,
0316     .sr_size_addr       = 0x00000008,
0317     .dr_base_addr_lo    = 0x0000000c,
0318     .dr_base_addr_hi    = 0x00000010,
0319     .dr_size_addr       = 0x00000014,
0320     .misc_ie_addr       = 0x00000034,
0321     .sr_wr_index_addr   = 0x0000003c,
0322     .dst_wr_index_addr  = 0x00000040,
0323     .current_srri_addr  = 0x00000044,
0324     .current_drri_addr  = 0x00000048,
0325     .ce_rri_low     = 0x0024C004,
0326     .ce_rri_high        = 0x0024C008,
0327     .host_ie_addr       = 0x0000002c,
0328     .ctrl1_regs     = &wcn3990_ctrl1,
0329     .host_ie        = &wcn3990_host_ie,
0330     .wm_regs        = &wcn3990_wm_reg,
0331     .misc_regs      = &wcn3990_misc_reg,
0332     .wm_srcr        = &wcn3990_wm_src_ring,
0333     .wm_dstr        = &wcn3990_wm_dst_ring,
0334     .upd            = &wcn3990_ctrl1_upd,
0335 };
0336 
0337 const struct ath10k_hw_values wcn3990_values = {
0338     .rtc_state_val_on       = 5,
0339     .ce_count           = 12,
0340     .msi_assign_ce_max      = 12,
0341     .num_target_ce_config_wlan  = 12,
0342     .ce_desc_meta_data_mask     = 0xFFF0,
0343     .ce_desc_meta_data_lsb      = 4,
0344 };
0345 
0346 static struct ath10k_hw_ce_regs_addr_map qcax_src_ring = {
0347     .msb    = 0x00000010,
0348     .lsb    = 0x00000010,
0349     .mask   = GENMASK(16, 16),
0350 };
0351 
0352 static struct ath10k_hw_ce_regs_addr_map qcax_dst_ring = {
0353     .msb    = 0x00000011,
0354     .lsb    = 0x00000011,
0355     .mask   = GENMASK(17, 17),
0356 };
0357 
0358 static struct ath10k_hw_ce_regs_addr_map qcax_dmax = {
0359     .msb    = 0x0000000f,
0360     .lsb    = 0x00000000,
0361     .mask   = GENMASK(15, 0),
0362 };
0363 
0364 static struct ath10k_hw_ce_ctrl1 qcax_ctrl1 = {
0365     .addr       = 0x00000010,
0366     .hw_mask    = 0x0007ffff,
0367     .sw_mask    = 0x0007ffff,
0368     .hw_wr_mask = 0x00000000,
0369     .sw_wr_mask = 0x0007ffff,
0370     .reset_mask = 0xffffffff,
0371     .reset      = 0x00000080,
0372     .src_ring   = &qcax_src_ring,
0373     .dst_ring   = &qcax_dst_ring,
0374     .dmax       = &qcax_dmax,
0375 };
0376 
0377 static struct ath10k_hw_ce_regs_addr_map qcax_cmd_halt_status = {
0378     .msb    = 0x00000003,
0379     .lsb    = 0x00000003,
0380     .mask   = GENMASK(3, 3),
0381 };
0382 
0383 static struct ath10k_hw_ce_cmd_halt qcax_cmd_halt = {
0384     .msb        = 0x00000000,
0385     .mask       = GENMASK(0, 0),
0386     .status_reset   = 0x00000000,
0387     .status     = &qcax_cmd_halt_status,
0388 };
0389 
0390 static struct ath10k_hw_ce_regs_addr_map qcax_host_ie_cc = {
0391     .msb    = 0x00000000,
0392     .lsb    = 0x00000000,
0393     .mask   = GENMASK(0, 0),
0394 };
0395 
0396 static struct ath10k_hw_ce_host_ie qcax_host_ie = {
0397     .copy_complete_reset    = 0x00000000,
0398     .copy_complete      = &qcax_host_ie_cc,
0399 };
0400 
0401 static struct ath10k_hw_ce_host_wm_regs qcax_wm_reg = {
0402     .dstr_lmask = 0x00000010,
0403     .dstr_hmask = 0x00000008,
0404     .srcr_lmask = 0x00000004,
0405     .srcr_hmask = 0x00000002,
0406     .cc_mask    = 0x00000001,
0407     .wm_mask    = 0x0000001E,
0408     .addr       = 0x00000030,
0409 };
0410 
0411 static struct ath10k_hw_ce_misc_regs qcax_misc_reg = {
0412     .axi_err    = 0x00000400,
0413     .dstr_add_err   = 0x00000200,
0414     .srcr_len_err   = 0x00000100,
0415     .dstr_mlen_vio  = 0x00000080,
0416     .dstr_overflow  = 0x00000040,
0417     .srcr_overflow  = 0x00000020,
0418     .err_mask   = 0x000007E0,
0419     .addr       = 0x00000038,
0420 };
0421 
0422 static struct ath10k_hw_ce_regs_addr_map qcax_src_wm_low = {
0423     .msb    = 0x0000001f,
0424     .lsb    = 0x00000010,
0425     .mask   = GENMASK(31, 16),
0426 };
0427 
0428 static struct ath10k_hw_ce_regs_addr_map qcax_src_wm_high = {
0429     .msb    = 0x0000000f,
0430     .lsb    = 0x00000000,
0431     .mask   = GENMASK(15, 0),
0432 };
0433 
0434 static struct ath10k_hw_ce_dst_src_wm_regs qcax_wm_src_ring = {
0435     .addr       = 0x0000004c,
0436     .low_rst    = 0x00000000,
0437     .high_rst   = 0x00000000,
0438     .wm_low     = &qcax_src_wm_low,
0439     .wm_high        = &qcax_src_wm_high,
0440 };
0441 
0442 static struct ath10k_hw_ce_regs_addr_map qcax_dst_wm_low = {
0443     .lsb    = 0x00000010,
0444     .mask   = GENMASK(31, 16),
0445 };
0446 
0447 static struct ath10k_hw_ce_regs_addr_map qcax_dst_wm_high = {
0448     .msb    = 0x0000000f,
0449     .lsb    = 0x00000000,
0450     .mask   = GENMASK(15, 0),
0451 };
0452 
0453 static struct ath10k_hw_ce_dst_src_wm_regs qcax_wm_dst_ring = {
0454     .addr       = 0x00000050,
0455     .low_rst    = 0x00000000,
0456     .high_rst   = 0x00000000,
0457     .wm_low     = &qcax_dst_wm_low,
0458     .wm_high    = &qcax_dst_wm_high,
0459 };
0460 
0461 const struct ath10k_hw_ce_regs qcax_ce_regs = {
0462     .sr_base_addr_lo    = 0x00000000,
0463     .sr_size_addr       = 0x00000004,
0464     .dr_base_addr_lo    = 0x00000008,
0465     .dr_size_addr       = 0x0000000c,
0466     .ce_cmd_addr        = 0x00000018,
0467     .misc_ie_addr       = 0x00000034,
0468     .sr_wr_index_addr   = 0x0000003c,
0469     .dst_wr_index_addr  = 0x00000040,
0470     .current_srri_addr  = 0x00000044,
0471     .current_drri_addr  = 0x00000048,
0472     .host_ie_addr       = 0x0000002c,
0473     .ctrl1_regs     = &qcax_ctrl1,
0474     .cmd_halt       = &qcax_cmd_halt,
0475     .host_ie        = &qcax_host_ie,
0476     .wm_regs        = &qcax_wm_reg,
0477     .misc_regs      = &qcax_misc_reg,
0478     .wm_srcr        = &qcax_wm_src_ring,
0479     .wm_dstr                = &qcax_wm_dst_ring,
0480 };
0481 
0482 const struct ath10k_hw_clk_params qca6174_clk[ATH10K_HW_REFCLK_COUNT] = {
0483     {
0484         .refclk = 48000000,
0485         .div = 0xe,
0486         .rnfrac = 0x2aaa8,
0487         .settle_time = 2400,
0488         .refdiv = 0,
0489         .outdiv = 1,
0490     },
0491     {
0492         .refclk = 19200000,
0493         .div = 0x24,
0494         .rnfrac = 0x2aaa8,
0495         .settle_time = 960,
0496         .refdiv = 0,
0497         .outdiv = 1,
0498     },
0499     {
0500         .refclk = 24000000,
0501         .div = 0x1d,
0502         .rnfrac = 0x15551,
0503         .settle_time = 1200,
0504         .refdiv = 0,
0505         .outdiv = 1,
0506     },
0507     {
0508         .refclk = 26000000,
0509         .div = 0x1b,
0510         .rnfrac = 0x4ec4,
0511         .settle_time = 1300,
0512         .refdiv = 0,
0513         .outdiv = 1,
0514     },
0515     {
0516         .refclk = 37400000,
0517         .div = 0x12,
0518         .rnfrac = 0x34b49,
0519         .settle_time = 1870,
0520         .refdiv = 0,
0521         .outdiv = 1,
0522     },
0523     {
0524         .refclk = 38400000,
0525         .div = 0x12,
0526         .rnfrac = 0x15551,
0527         .settle_time = 1920,
0528         .refdiv = 0,
0529         .outdiv = 1,
0530     },
0531     {
0532         .refclk = 40000000,
0533         .div = 0x12,
0534         .rnfrac = 0x26665,
0535         .settle_time = 2000,
0536         .refdiv = 0,
0537         .outdiv = 1,
0538     },
0539     {
0540         .refclk = 52000000,
0541         .div = 0x1b,
0542         .rnfrac = 0x4ec4,
0543         .settle_time = 2600,
0544         .refdiv = 0,
0545         .outdiv = 1,
0546     },
0547 };
0548 
0549 void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
0550                 u32 cc, u32 rcc, u32 cc_prev, u32 rcc_prev)
0551 {
0552     u32 cc_fix = 0;
0553     u32 rcc_fix = 0;
0554     enum ath10k_hw_cc_wraparound_type wraparound_type;
0555 
0556     survey->filled |= SURVEY_INFO_TIME |
0557               SURVEY_INFO_TIME_BUSY;
0558 
0559     wraparound_type = ar->hw_params.cc_wraparound_type;
0560 
0561     if (cc < cc_prev || rcc < rcc_prev) {
0562         switch (wraparound_type) {
0563         case ATH10K_HW_CC_WRAP_SHIFTED_ALL:
0564             if (cc < cc_prev) {
0565                 cc_fix = 0x7fffffff;
0566                 survey->filled &= ~SURVEY_INFO_TIME_BUSY;
0567             }
0568             break;
0569         case ATH10K_HW_CC_WRAP_SHIFTED_EACH:
0570             if (cc < cc_prev)
0571                 cc_fix = 0x7fffffff;
0572 
0573             if (rcc < rcc_prev)
0574                 rcc_fix = 0x7fffffff;
0575             break;
0576         case ATH10K_HW_CC_WRAP_DISABLED:
0577             break;
0578         }
0579     }
0580 
0581     cc -= cc_prev - cc_fix;
0582     rcc -= rcc_prev - rcc_fix;
0583 
0584     survey->time = CCNT_TO_MSEC(ar, cc);
0585     survey->time_busy = CCNT_TO_MSEC(ar, rcc);
0586 }
0587 
0588 /* The firmware does not support setting the coverage class. Instead this
0589  * function monitors and modifies the corresponding MAC registers.
0590  */
0591 static void ath10k_hw_qca988x_set_coverage_class(struct ath10k *ar,
0592                          s16 value)
0593 {
0594     u32 slottime_reg;
0595     u32 slottime;
0596     u32 timeout_reg;
0597     u32 ack_timeout;
0598     u32 cts_timeout;
0599     u32 phyclk_reg;
0600     u32 phyclk;
0601     u64 fw_dbglog_mask;
0602     u32 fw_dbglog_level;
0603 
0604     mutex_lock(&ar->conf_mutex);
0605 
0606     /* Only modify registers if the core is started. */
0607     if ((ar->state != ATH10K_STATE_ON) &&
0608         (ar->state != ATH10K_STATE_RESTARTED)) {
0609         spin_lock_bh(&ar->data_lock);
0610         /* Store config value for when radio boots up */
0611         ar->fw_coverage.coverage_class = value;
0612         spin_unlock_bh(&ar->data_lock);
0613         goto unlock;
0614     }
0615 
0616     /* Retrieve the current values of the two registers that need to be
0617      * adjusted.
0618      */
0619     slottime_reg = ath10k_hif_read32(ar, WLAN_MAC_BASE_ADDRESS +
0620                          WAVE1_PCU_GBL_IFS_SLOT);
0621     timeout_reg = ath10k_hif_read32(ar, WLAN_MAC_BASE_ADDRESS +
0622                         WAVE1_PCU_ACK_CTS_TIMEOUT);
0623     phyclk_reg = ath10k_hif_read32(ar, WLAN_MAC_BASE_ADDRESS +
0624                        WAVE1_PHYCLK);
0625     phyclk = MS(phyclk_reg, WAVE1_PHYCLK_USEC) + 1;
0626 
0627     if (value < 0)
0628         value = ar->fw_coverage.coverage_class;
0629 
0630     /* Break out if the coverage class and registers have the expected
0631      * value.
0632      */
0633     if (value == ar->fw_coverage.coverage_class &&
0634         slottime_reg == ar->fw_coverage.reg_slottime_conf &&
0635         timeout_reg == ar->fw_coverage.reg_ack_cts_timeout_conf &&
0636         phyclk_reg == ar->fw_coverage.reg_phyclk)
0637         goto unlock;
0638 
0639     /* Store new initial register values from the firmware. */
0640     if (slottime_reg != ar->fw_coverage.reg_slottime_conf)
0641         ar->fw_coverage.reg_slottime_orig = slottime_reg;
0642     if (timeout_reg != ar->fw_coverage.reg_ack_cts_timeout_conf)
0643         ar->fw_coverage.reg_ack_cts_timeout_orig = timeout_reg;
0644     ar->fw_coverage.reg_phyclk = phyclk_reg;
0645 
0646     /* Calculate new value based on the (original) firmware calculation. */
0647     slottime_reg = ar->fw_coverage.reg_slottime_orig;
0648     timeout_reg = ar->fw_coverage.reg_ack_cts_timeout_orig;
0649 
0650     /* Do some sanity checks on the slottime register. */
0651     if (slottime_reg % phyclk) {
0652         ath10k_warn(ar,
0653                 "failed to set coverage class: expected integer microsecond value in register\n");
0654 
0655         goto store_regs;
0656     }
0657 
0658     slottime = MS(slottime_reg, WAVE1_PCU_GBL_IFS_SLOT);
0659     slottime = slottime / phyclk;
0660     if (slottime != 9 && slottime != 20) {
0661         ath10k_warn(ar,
0662                 "failed to set coverage class: expected slot time of 9 or 20us in HW register. It is %uus.\n",
0663                 slottime);
0664 
0665         goto store_regs;
0666     }
0667 
0668     /* Recalculate the register values by adding the additional propagation
0669      * delay (3us per coverage class).
0670      */
0671 
0672     slottime = MS(slottime_reg, WAVE1_PCU_GBL_IFS_SLOT);
0673     slottime += value * 3 * phyclk;
0674     slottime = min_t(u32, slottime, WAVE1_PCU_GBL_IFS_SLOT_MAX);
0675     slottime = SM(slottime, WAVE1_PCU_GBL_IFS_SLOT);
0676     slottime_reg = (slottime_reg & ~WAVE1_PCU_GBL_IFS_SLOT_MASK) | slottime;
0677 
0678     /* Update ack timeout (lower halfword). */
0679     ack_timeout = MS(timeout_reg, WAVE1_PCU_ACK_CTS_TIMEOUT_ACK);
0680     ack_timeout += 3 * value * phyclk;
0681     ack_timeout = min_t(u32, ack_timeout, WAVE1_PCU_ACK_CTS_TIMEOUT_MAX);
0682     ack_timeout = SM(ack_timeout, WAVE1_PCU_ACK_CTS_TIMEOUT_ACK);
0683 
0684     /* Update cts timeout (upper halfword). */
0685     cts_timeout = MS(timeout_reg, WAVE1_PCU_ACK_CTS_TIMEOUT_CTS);
0686     cts_timeout += 3 * value * phyclk;
0687     cts_timeout = min_t(u32, cts_timeout, WAVE1_PCU_ACK_CTS_TIMEOUT_MAX);
0688     cts_timeout = SM(cts_timeout, WAVE1_PCU_ACK_CTS_TIMEOUT_CTS);
0689 
0690     timeout_reg = ack_timeout | cts_timeout;
0691 
0692     ath10k_hif_write32(ar,
0693                WLAN_MAC_BASE_ADDRESS + WAVE1_PCU_GBL_IFS_SLOT,
0694                slottime_reg);
0695     ath10k_hif_write32(ar,
0696                WLAN_MAC_BASE_ADDRESS + WAVE1_PCU_ACK_CTS_TIMEOUT,
0697                timeout_reg);
0698 
0699     /* Ensure we have a debug level of WARN set for the case that the
0700      * coverage class is larger than 0. This is important as we need to
0701      * set the registers again if the firmware does an internal reset and
0702      * this way we will be notified of the event.
0703      */
0704     fw_dbglog_mask = ath10k_debug_get_fw_dbglog_mask(ar);
0705     fw_dbglog_level = ath10k_debug_get_fw_dbglog_level(ar);
0706 
0707     if (value > 0) {
0708         if (fw_dbglog_level > ATH10K_DBGLOG_LEVEL_WARN)
0709             fw_dbglog_level = ATH10K_DBGLOG_LEVEL_WARN;
0710         fw_dbglog_mask = ~0;
0711     }
0712 
0713     ath10k_wmi_dbglog_cfg(ar, fw_dbglog_mask, fw_dbglog_level);
0714 
0715 store_regs:
0716     /* After an error we will not retry setting the coverage class. */
0717     spin_lock_bh(&ar->data_lock);
0718     ar->fw_coverage.coverage_class = value;
0719     spin_unlock_bh(&ar->data_lock);
0720 
0721     ar->fw_coverage.reg_slottime_conf = slottime_reg;
0722     ar->fw_coverage.reg_ack_cts_timeout_conf = timeout_reg;
0723 
0724 unlock:
0725     mutex_unlock(&ar->conf_mutex);
0726 }
0727 
0728 /**
0729  * ath10k_hw_qca6174_enable_pll_clock() - enable the qca6174 hw pll clock
0730  * @ar: the ath10k blob
0731  *
0732  * This function is very hardware specific, the clock initialization
0733  * steps is very sensitive and could lead to unknown crash, so they
0734  * should be done in sequence.
0735  *
0736  * *** Be aware if you planned to refactor them. ***
0737  *
0738  * Return: 0 if successfully enable the pll, otherwise EINVAL
0739  */
0740 static int ath10k_hw_qca6174_enable_pll_clock(struct ath10k *ar)
0741 {
0742     int ret, wait_limit;
0743     u32 clk_div_addr, pll_init_addr, speed_addr;
0744     u32 addr, reg_val, mem_val;
0745     struct ath10k_hw_params *hw;
0746     const struct ath10k_hw_clk_params *hw_clk;
0747 
0748     hw = &ar->hw_params;
0749 
0750     if (ar->regs->core_clk_div_address == 0 ||
0751         ar->regs->cpu_pll_init_address == 0 ||
0752         ar->regs->cpu_speed_address == 0)
0753         return -EINVAL;
0754 
0755     clk_div_addr = ar->regs->core_clk_div_address;
0756     pll_init_addr = ar->regs->cpu_pll_init_address;
0757     speed_addr = ar->regs->cpu_speed_address;
0758 
0759     /* Read efuse register to find out the right hw clock configuration */
0760     addr = (RTC_SOC_BASE_ADDRESS | EFUSE_OFFSET);
0761     ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
0762     if (ret)
0763         return -EINVAL;
0764 
0765     /* sanitize if the hw refclk index is out of the boundary */
0766     if (MS(reg_val, EFUSE_XTAL_SEL) > ATH10K_HW_REFCLK_COUNT)
0767         return -EINVAL;
0768 
0769     hw_clk = &hw->hw_clk[MS(reg_val, EFUSE_XTAL_SEL)];
0770 
0771     /* Set the rnfrac and outdiv params to bb_pll register */
0772     addr = (RTC_SOC_BASE_ADDRESS | BB_PLL_CONFIG_OFFSET);
0773     ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
0774     if (ret)
0775         return -EINVAL;
0776 
0777     reg_val &= ~(BB_PLL_CONFIG_FRAC_MASK | BB_PLL_CONFIG_OUTDIV_MASK);
0778     reg_val |= (SM(hw_clk->rnfrac, BB_PLL_CONFIG_FRAC) |
0779             SM(hw_clk->outdiv, BB_PLL_CONFIG_OUTDIV));
0780     ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
0781     if (ret)
0782         return -EINVAL;
0783 
0784     /* Set the correct settle time value to pll_settle register */
0785     addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_SETTLE_OFFSET);
0786     ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
0787     if (ret)
0788         return -EINVAL;
0789 
0790     reg_val &= ~WLAN_PLL_SETTLE_TIME_MASK;
0791     reg_val |= SM(hw_clk->settle_time, WLAN_PLL_SETTLE_TIME);
0792     ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
0793     if (ret)
0794         return -EINVAL;
0795 
0796     /* Set the clock_ctrl div to core_clk_ctrl register */
0797     addr = (RTC_SOC_BASE_ADDRESS | SOC_CORE_CLK_CTRL_OFFSET);
0798     ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
0799     if (ret)
0800         return -EINVAL;
0801 
0802     reg_val &= ~SOC_CORE_CLK_CTRL_DIV_MASK;
0803     reg_val |= SM(1, SOC_CORE_CLK_CTRL_DIV);
0804     ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
0805     if (ret)
0806         return -EINVAL;
0807 
0808     /* Set the clock_div register */
0809     mem_val = 1;
0810     ret = ath10k_bmi_write_memory(ar, clk_div_addr, &mem_val,
0811                       sizeof(mem_val));
0812     if (ret)
0813         return -EINVAL;
0814 
0815     /* Configure the pll_control register */
0816     addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET);
0817     ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
0818     if (ret)
0819         return -EINVAL;
0820 
0821     reg_val |= (SM(hw_clk->refdiv, WLAN_PLL_CONTROL_REFDIV) |
0822             SM(hw_clk->div, WLAN_PLL_CONTROL_DIV) |
0823             SM(1, WLAN_PLL_CONTROL_NOPWD));
0824     ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
0825     if (ret)
0826         return -EINVAL;
0827 
0828     /* busy wait (max 1s) the rtc_sync status register indicate ready */
0829     wait_limit = 100000;
0830     addr = (RTC_WMAC_BASE_ADDRESS | RTC_SYNC_STATUS_OFFSET);
0831     do {
0832         ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
0833         if (ret)
0834             return -EINVAL;
0835 
0836         if (!MS(reg_val, RTC_SYNC_STATUS_PLL_CHANGING))
0837             break;
0838 
0839         wait_limit--;
0840         udelay(10);
0841 
0842     } while (wait_limit > 0);
0843 
0844     if (MS(reg_val, RTC_SYNC_STATUS_PLL_CHANGING))
0845         return -EINVAL;
0846 
0847     /* Unset the pll_bypass in pll_control register */
0848     addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET);
0849     ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
0850     if (ret)
0851         return -EINVAL;
0852 
0853     reg_val &= ~WLAN_PLL_CONTROL_BYPASS_MASK;
0854     reg_val |= SM(0, WLAN_PLL_CONTROL_BYPASS);
0855     ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
0856     if (ret)
0857         return -EINVAL;
0858 
0859     /* busy wait (max 1s) the rtc_sync status register indicate ready */
0860     wait_limit = 100000;
0861     addr = (RTC_WMAC_BASE_ADDRESS | RTC_SYNC_STATUS_OFFSET);
0862     do {
0863         ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
0864         if (ret)
0865             return -EINVAL;
0866 
0867         if (!MS(reg_val, RTC_SYNC_STATUS_PLL_CHANGING))
0868             break;
0869 
0870         wait_limit--;
0871         udelay(10);
0872 
0873     } while (wait_limit > 0);
0874 
0875     if (MS(reg_val, RTC_SYNC_STATUS_PLL_CHANGING))
0876         return -EINVAL;
0877 
0878     /* Enable the hardware cpu clock register */
0879     addr = (RTC_SOC_BASE_ADDRESS | SOC_CPU_CLOCK_OFFSET);
0880     ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
0881     if (ret)
0882         return -EINVAL;
0883 
0884     reg_val &= ~SOC_CPU_CLOCK_STANDARD_MASK;
0885     reg_val |= SM(1, SOC_CPU_CLOCK_STANDARD);
0886     ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
0887     if (ret)
0888         return -EINVAL;
0889 
0890     /* unset the nopwd from pll_control register */
0891     addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET);
0892     ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
0893     if (ret)
0894         return -EINVAL;
0895 
0896     reg_val &= ~WLAN_PLL_CONTROL_NOPWD_MASK;
0897     ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
0898     if (ret)
0899         return -EINVAL;
0900 
0901     /* enable the pll_init register */
0902     mem_val = 1;
0903     ret = ath10k_bmi_write_memory(ar, pll_init_addr, &mem_val,
0904                       sizeof(mem_val));
0905     if (ret)
0906         return -EINVAL;
0907 
0908     /* set the target clock frequency to speed register */
0909     ret = ath10k_bmi_write_memory(ar, speed_addr, &hw->target_cpu_freq,
0910                       sizeof(hw->target_cpu_freq));
0911     if (ret)
0912         return -EINVAL;
0913 
0914     return 0;
0915 }
0916 
0917 /* Program CPU_ADDR_MSB to allow different memory
0918  * region access.
0919  */
0920 static void ath10k_hw_map_target_mem(struct ath10k *ar, u32 msb)
0921 {
0922     u32 address = SOC_CORE_BASE_ADDRESS + FW_RAM_CONFIG_ADDRESS;
0923 
0924     ath10k_hif_write32(ar, address, msb);
0925 }
0926 
0927 /* 1. Write to memory region of target, such as IRAM adn DRAM.
0928  * 2. Target address( 0 ~ 00100000 & 0x00400000~0x00500000)
0929  *    can be written directly. See ath10k_pci_targ_cpu_to_ce_addr() too.
0930  * 3. In order to access the region other than the above,
0931  *    we need to set the value of register CPU_ADDR_MSB.
0932  * 4. Target memory access space is limited to 1M size. If the size is larger
0933  *    than 1M, need to split it and program CPU_ADDR_MSB accordingly.
0934  */
0935 static int ath10k_hw_diag_segment_msb_download(struct ath10k *ar,
0936                            const void *buffer,
0937                            u32 address,
0938                            u32 length)
0939 {
0940     u32 addr = address & REGION_ACCESS_SIZE_MASK;
0941     int ret, remain_size, size;
0942     const u8 *buf;
0943 
0944     ath10k_hw_map_target_mem(ar, CPU_ADDR_MSB_REGION_VAL(address));
0945 
0946     if (addr + length > REGION_ACCESS_SIZE_LIMIT) {
0947         size = REGION_ACCESS_SIZE_LIMIT - addr;
0948         remain_size = length - size;
0949 
0950         ret = ath10k_hif_diag_write(ar, address, buffer, size);
0951         if (ret) {
0952             ath10k_warn(ar,
0953                     "failed to download the first %d bytes segment to address:0x%x: %d\n",
0954                     size, address, ret);
0955             goto done;
0956         }
0957 
0958         /* Change msb to the next memory region*/
0959         ath10k_hw_map_target_mem(ar,
0960                      CPU_ADDR_MSB_REGION_VAL(address) + 1);
0961         buf = buffer +  size;
0962         ret = ath10k_hif_diag_write(ar,
0963                         address & ~REGION_ACCESS_SIZE_MASK,
0964                         buf, remain_size);
0965         if (ret) {
0966             ath10k_warn(ar,
0967                     "failed to download the second %d bytes segment to address:0x%x: %d\n",
0968                     remain_size,
0969                     address & ~REGION_ACCESS_SIZE_MASK,
0970                     ret);
0971             goto done;
0972         }
0973     } else {
0974         ret = ath10k_hif_diag_write(ar, address, buffer, length);
0975         if (ret) {
0976             ath10k_warn(ar,
0977                     "failed to download the only %d bytes segment to address:0x%x: %d\n",
0978                     length, address, ret);
0979             goto done;
0980         }
0981     }
0982 
0983 done:
0984     /* Change msb to DRAM */
0985     ath10k_hw_map_target_mem(ar,
0986                  CPU_ADDR_MSB_REGION_VAL(DRAM_BASE_ADDRESS));
0987     return ret;
0988 }
0989 
0990 static int ath10k_hw_diag_segment_download(struct ath10k *ar,
0991                        const void *buffer,
0992                        u32 address,
0993                        u32 length)
0994 {
0995     if (address >= DRAM_BASE_ADDRESS + REGION_ACCESS_SIZE_LIMIT)
0996         /* Needs to change MSB for memory write */
0997         return ath10k_hw_diag_segment_msb_download(ar, buffer,
0998                                address, length);
0999     else
1000         return ath10k_hif_diag_write(ar, address, buffer, length);
1001 }
1002 
1003 int 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 
1107 static 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 
1112 static 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 
1118 static 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 
1133 const 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 
1138 const struct ath10k_hw_ops qca99x0_ops = {
1139     .is_rssi_enable = ath10k_htt_tx_rssi_enable,
1140 };
1141 
1142 const 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 
1148 const struct ath10k_hw_ops qca6174_sdio_ops = {
1149     .enable_pll_clk = ath10k_hw_qca6174_enable_pll_clock,
1150 };
1151 
1152 const 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 };