0001
0002
0003
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
0088
0089
0090
0091
0092
0093
0094
0095
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
0124
0125
0126
0127
0128
0129
0130
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
0589
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
0607 if ((ar->state != ATH10K_STATE_ON) &&
0608 (ar->state != ATH10K_STATE_RESTARTED)) {
0609 spin_lock_bh(&ar->data_lock);
0610
0611 ar->fw_coverage.coverage_class = value;
0612 spin_unlock_bh(&ar->data_lock);
0613 goto unlock;
0614 }
0615
0616
0617
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
0631
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
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
0647 slottime_reg = ar->fw_coverage.reg_slottime_orig;
0648 timeout_reg = ar->fw_coverage.reg_ack_cts_timeout_orig;
0649
0650
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
0669
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
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
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
0700
0701
0702
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
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
0730
0731
0732
0733
0734
0735
0736
0737
0738
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
0760 addr = (RTC_SOC_BASE_ADDRESS | EFUSE_OFFSET);
0761 ret = ath10k_bmi_read_soc_reg(ar, addr, ®_val);
0762 if (ret)
0763 return -EINVAL;
0764
0765
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
0772 addr = (RTC_SOC_BASE_ADDRESS | BB_PLL_CONFIG_OFFSET);
0773 ret = ath10k_bmi_read_soc_reg(ar, addr, ®_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
0785 addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_SETTLE_OFFSET);
0786 ret = ath10k_bmi_read_soc_reg(ar, addr, ®_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
0797 addr = (RTC_SOC_BASE_ADDRESS | SOC_CORE_CLK_CTRL_OFFSET);
0798 ret = ath10k_bmi_read_soc_reg(ar, addr, ®_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
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
0816 addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET);
0817 ret = ath10k_bmi_read_soc_reg(ar, addr, ®_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
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, ®_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
0848 addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET);
0849 ret = ath10k_bmi_read_soc_reg(ar, addr, ®_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
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, ®_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
0879 addr = (RTC_SOC_BASE_ADDRESS | SOC_CPU_CLOCK_OFFSET);
0880 ret = ath10k_bmi_read_soc_reg(ar, addr, ®_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
0891 addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET);
0892 ret = ath10k_bmi_read_soc_reg(ar, addr, ®_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
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
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
0918
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
0928
0929
0930
0931
0932
0933
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
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
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
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
1021
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
1056 ret = ath10k_bmi_set_start(ar, base_addr);
1057 base_len = 0;
1058 break;
1059 case BMI_SGMTFILE_DONE:
1060
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
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 };