0001
0002
0003
0004
0005
0006
0007 #include <linux/module.h>
0008 #include <linux/slab.h>
0009 #include <linux/remoteproc.h>
0010 #include <linux/firmware.h>
0011 #include <linux/of.h>
0012
0013 #include "core.h"
0014 #include "dp_tx.h"
0015 #include "dp_rx.h"
0016 #include "debug.h"
0017 #include "hif.h"
0018 #include "wow.h"
0019
0020 unsigned int ath11k_debug_mask;
0021 EXPORT_SYMBOL(ath11k_debug_mask);
0022 module_param_named(debug_mask, ath11k_debug_mask, uint, 0644);
0023 MODULE_PARM_DESC(debug_mask, "Debugging mask");
0024
0025 static unsigned int ath11k_crypto_mode;
0026 module_param_named(crypto_mode, ath11k_crypto_mode, uint, 0644);
0027 MODULE_PARM_DESC(crypto_mode, "crypto mode: 0-hardware, 1-software");
0028
0029
0030 unsigned int ath11k_frame_mode = ATH11K_HW_TXRX_NATIVE_WIFI;
0031 module_param_named(frame_mode, ath11k_frame_mode, uint, 0644);
0032 MODULE_PARM_DESC(frame_mode,
0033 "Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)");
0034
0035 static const struct ath11k_hw_params ath11k_hw_params[] = {
0036 {
0037 .hw_rev = ATH11K_HW_IPQ8074,
0038 .name = "ipq8074 hw2.0",
0039 .fw = {
0040 .dir = "IPQ8074/hw2.0",
0041 .board_size = 256 * 1024,
0042 .cal_offset = 128 * 1024,
0043 },
0044 .max_radios = 3,
0045 .bdf_addr = 0x4B0C0000,
0046 .hw_ops = &ipq8074_ops,
0047 .ring_mask = &ath11k_hw_ring_mask_ipq8074,
0048 .internal_sleep_clock = false,
0049 .regs = &ipq8074_regs,
0050 .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074,
0051 .host_ce_config = ath11k_host_ce_config_ipq8074,
0052 .ce_count = 12,
0053 .target_ce_config = ath11k_target_ce_config_wlan_ipq8074,
0054 .target_ce_count = 11,
0055 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq8074,
0056 .svc_to_ce_map_len = 21,
0057 .single_pdev_only = false,
0058 .rxdma1_enable = true,
0059 .num_rxmda_per_pdev = 1,
0060 .rx_mac_buf_ring = false,
0061 .vdev_start_delay = false,
0062 .htt_peer_map_v2 = true,
0063
0064 .spectral = {
0065 .fft_sz = 2,
0066
0067
0068
0069 .fft_pad_sz = 2,
0070 .summary_pad_sz = 0,
0071 .fft_hdr_len = 16,
0072 .max_fft_bins = 512,
0073 },
0074
0075 .interface_modes = BIT(NL80211_IFTYPE_STATION) |
0076 BIT(NL80211_IFTYPE_AP) |
0077 BIT(NL80211_IFTYPE_MESH_POINT),
0078 .supports_monitor = true,
0079 .full_monitor_mode = false,
0080 .supports_shadow_regs = false,
0081 .idle_ps = false,
0082 .supports_sta_ps = false,
0083 .cold_boot_calib = true,
0084 .fw_mem_mode = 0,
0085 .num_vdevs = 16 + 1,
0086 .num_peers = 512,
0087 .supports_suspend = false,
0088 .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
0089 .supports_regdb = false,
0090 .fix_l1ss = true,
0091 .credit_flow = false,
0092 .max_tx_ring = DP_TCL_NUM_RING_MAX,
0093 .hal_params = &ath11k_hw_hal_params_ipq8074,
0094 .supports_dynamic_smps_6ghz = false,
0095 .alloc_cacheable_memory = true,
0096 .supports_rssi_stats = false,
0097 .fw_wmi_diag_event = false,
0098 .current_cc_support = false,
0099 .dbr_debug_support = true,
0100 .global_reset = false,
0101 .bios_sar_capa = NULL,
0102 .m3_fw_support = false,
0103 .fixed_bdf_addr = true,
0104 .fixed_mem_region = true,
0105 .static_window_map = false,
0106 .hybrid_bus_type = false,
0107 .fixed_fw_mem = false,
0108 .support_off_channel_tx = false,
0109 },
0110 {
0111 .hw_rev = ATH11K_HW_IPQ6018_HW10,
0112 .name = "ipq6018 hw1.0",
0113 .fw = {
0114 .dir = "IPQ6018/hw1.0",
0115 .board_size = 256 * 1024,
0116 .cal_offset = 128 * 1024,
0117 },
0118 .max_radios = 2,
0119 .bdf_addr = 0x4ABC0000,
0120 .hw_ops = &ipq6018_ops,
0121 .ring_mask = &ath11k_hw_ring_mask_ipq8074,
0122 .internal_sleep_clock = false,
0123 .regs = &ipq8074_regs,
0124 .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074,
0125 .host_ce_config = ath11k_host_ce_config_ipq8074,
0126 .ce_count = 12,
0127 .target_ce_config = ath11k_target_ce_config_wlan_ipq8074,
0128 .target_ce_count = 11,
0129 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq6018,
0130 .svc_to_ce_map_len = 19,
0131 .single_pdev_only = false,
0132 .rxdma1_enable = true,
0133 .num_rxmda_per_pdev = 1,
0134 .rx_mac_buf_ring = false,
0135 .vdev_start_delay = false,
0136 .htt_peer_map_v2 = true,
0137
0138 .spectral = {
0139 .fft_sz = 4,
0140 .fft_pad_sz = 0,
0141 .summary_pad_sz = 0,
0142 .fft_hdr_len = 16,
0143 .max_fft_bins = 512,
0144 },
0145
0146 .interface_modes = BIT(NL80211_IFTYPE_STATION) |
0147 BIT(NL80211_IFTYPE_AP) |
0148 BIT(NL80211_IFTYPE_MESH_POINT),
0149 .supports_monitor = true,
0150 .full_monitor_mode = false,
0151 .supports_shadow_regs = false,
0152 .idle_ps = false,
0153 .supports_sta_ps = false,
0154 .cold_boot_calib = true,
0155 .fw_mem_mode = 0,
0156 .num_vdevs = 16 + 1,
0157 .num_peers = 512,
0158 .supports_suspend = false,
0159 .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
0160 .supports_regdb = false,
0161 .fix_l1ss = true,
0162 .credit_flow = false,
0163 .max_tx_ring = DP_TCL_NUM_RING_MAX,
0164 .hal_params = &ath11k_hw_hal_params_ipq8074,
0165 .supports_dynamic_smps_6ghz = false,
0166 .alloc_cacheable_memory = true,
0167 .supports_rssi_stats = false,
0168 .fw_wmi_diag_event = false,
0169 .current_cc_support = false,
0170 .dbr_debug_support = true,
0171 .global_reset = false,
0172 .bios_sar_capa = NULL,
0173 .m3_fw_support = false,
0174 .fixed_bdf_addr = true,
0175 .fixed_mem_region = true,
0176 .static_window_map = false,
0177 .hybrid_bus_type = false,
0178 .fixed_fw_mem = false,
0179 .support_off_channel_tx = false,
0180 },
0181 {
0182 .name = "qca6390 hw2.0",
0183 .hw_rev = ATH11K_HW_QCA6390_HW20,
0184 .fw = {
0185 .dir = "QCA6390/hw2.0",
0186 .board_size = 256 * 1024,
0187 .cal_offset = 128 * 1024,
0188 },
0189 .max_radios = 3,
0190 .bdf_addr = 0x4B0C0000,
0191 .hw_ops = &qca6390_ops,
0192 .ring_mask = &ath11k_hw_ring_mask_qca6390,
0193 .internal_sleep_clock = true,
0194 .regs = &qca6390_regs,
0195 .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390,
0196 .host_ce_config = ath11k_host_ce_config_qca6390,
0197 .ce_count = 9,
0198 .target_ce_config = ath11k_target_ce_config_wlan_qca6390,
0199 .target_ce_count = 9,
0200 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
0201 .svc_to_ce_map_len = 14,
0202 .single_pdev_only = true,
0203 .rxdma1_enable = false,
0204 .num_rxmda_per_pdev = 2,
0205 .rx_mac_buf_ring = true,
0206 .vdev_start_delay = true,
0207 .htt_peer_map_v2 = false,
0208
0209 .spectral = {
0210 .fft_sz = 0,
0211 .fft_pad_sz = 0,
0212 .summary_pad_sz = 0,
0213 .fft_hdr_len = 0,
0214 .max_fft_bins = 0,
0215 },
0216
0217 .interface_modes = BIT(NL80211_IFTYPE_STATION) |
0218 BIT(NL80211_IFTYPE_AP),
0219 .supports_monitor = false,
0220 .full_monitor_mode = false,
0221 .supports_shadow_regs = true,
0222 .idle_ps = true,
0223 .supports_sta_ps = true,
0224 .cold_boot_calib = false,
0225 .fw_mem_mode = 0,
0226 .num_vdevs = 16 + 1,
0227 .num_peers = 512,
0228 .supports_suspend = true,
0229 .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
0230 .supports_regdb = false,
0231 .fix_l1ss = true,
0232 .credit_flow = true,
0233 .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
0234 .hal_params = &ath11k_hw_hal_params_qca6390,
0235 .supports_dynamic_smps_6ghz = false,
0236 .alloc_cacheable_memory = false,
0237 .supports_rssi_stats = true,
0238 .fw_wmi_diag_event = true,
0239 .current_cc_support = true,
0240 .dbr_debug_support = false,
0241 .global_reset = true,
0242 .bios_sar_capa = NULL,
0243 .m3_fw_support = true,
0244 .fixed_bdf_addr = false,
0245 .fixed_mem_region = false,
0246 .static_window_map = false,
0247 .hybrid_bus_type = false,
0248 .fixed_fw_mem = false,
0249 .support_off_channel_tx = true,
0250 },
0251 {
0252 .name = "qcn9074 hw1.0",
0253 .hw_rev = ATH11K_HW_QCN9074_HW10,
0254 .fw = {
0255 .dir = "QCN9074/hw1.0",
0256 .board_size = 256 * 1024,
0257 .cal_offset = 128 * 1024,
0258 },
0259 .max_radios = 1,
0260 .single_pdev_only = false,
0261 .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9074,
0262 .hw_ops = &qcn9074_ops,
0263 .ring_mask = &ath11k_hw_ring_mask_qcn9074,
0264 .internal_sleep_clock = false,
0265 .regs = &qcn9074_regs,
0266 .host_ce_config = ath11k_host_ce_config_qcn9074,
0267 .ce_count = 6,
0268 .target_ce_config = ath11k_target_ce_config_wlan_qcn9074,
0269 .target_ce_count = 9,
0270 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qcn9074,
0271 .svc_to_ce_map_len = 18,
0272 .rxdma1_enable = true,
0273 .num_rxmda_per_pdev = 1,
0274 .rx_mac_buf_ring = false,
0275 .vdev_start_delay = false,
0276 .htt_peer_map_v2 = true,
0277
0278 .spectral = {
0279 .fft_sz = 2,
0280 .fft_pad_sz = 0,
0281 .summary_pad_sz = 16,
0282 .fft_hdr_len = 24,
0283 .max_fft_bins = 1024,
0284 },
0285
0286 .interface_modes = BIT(NL80211_IFTYPE_STATION) |
0287 BIT(NL80211_IFTYPE_AP) |
0288 BIT(NL80211_IFTYPE_MESH_POINT),
0289 .supports_monitor = true,
0290 .full_monitor_mode = true,
0291 .supports_shadow_regs = false,
0292 .idle_ps = false,
0293 .supports_sta_ps = false,
0294 .cold_boot_calib = false,
0295 .fw_mem_mode = 2,
0296 .num_vdevs = 8,
0297 .num_peers = 128,
0298 .supports_suspend = false,
0299 .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
0300 .supports_regdb = false,
0301 .fix_l1ss = true,
0302 .credit_flow = false,
0303 .max_tx_ring = DP_TCL_NUM_RING_MAX,
0304 .hal_params = &ath11k_hw_hal_params_ipq8074,
0305 .supports_dynamic_smps_6ghz = true,
0306 .alloc_cacheable_memory = true,
0307 .supports_rssi_stats = false,
0308 .fw_wmi_diag_event = false,
0309 .current_cc_support = false,
0310 .dbr_debug_support = true,
0311 .global_reset = false,
0312 .bios_sar_capa = NULL,
0313 .m3_fw_support = true,
0314 .fixed_bdf_addr = false,
0315 .fixed_mem_region = false,
0316 .static_window_map = true,
0317 .hybrid_bus_type = false,
0318 .fixed_fw_mem = false,
0319 .support_off_channel_tx = false,
0320 },
0321 {
0322 .name = "wcn6855 hw2.0",
0323 .hw_rev = ATH11K_HW_WCN6855_HW20,
0324 .fw = {
0325 .dir = "WCN6855/hw2.0",
0326 .board_size = 256 * 1024,
0327 .cal_offset = 128 * 1024,
0328 },
0329 .max_radios = 3,
0330 .bdf_addr = 0x4B0C0000,
0331 .hw_ops = &wcn6855_ops,
0332 .ring_mask = &ath11k_hw_ring_mask_qca6390,
0333 .internal_sleep_clock = true,
0334 .regs = &wcn6855_regs,
0335 .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390,
0336 .host_ce_config = ath11k_host_ce_config_qca6390,
0337 .ce_count = 9,
0338 .target_ce_config = ath11k_target_ce_config_wlan_qca6390,
0339 .target_ce_count = 9,
0340 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
0341 .svc_to_ce_map_len = 14,
0342 .single_pdev_only = true,
0343 .rxdma1_enable = false,
0344 .num_rxmda_per_pdev = 2,
0345 .rx_mac_buf_ring = true,
0346 .vdev_start_delay = true,
0347 .htt_peer_map_v2 = false,
0348
0349 .spectral = {
0350 .fft_sz = 0,
0351 .fft_pad_sz = 0,
0352 .summary_pad_sz = 0,
0353 .fft_hdr_len = 0,
0354 .max_fft_bins = 0,
0355 },
0356
0357 .interface_modes = BIT(NL80211_IFTYPE_STATION) |
0358 BIT(NL80211_IFTYPE_AP),
0359 .supports_monitor = false,
0360 .full_monitor_mode = false,
0361 .supports_shadow_regs = true,
0362 .idle_ps = true,
0363 .supports_sta_ps = true,
0364 .cold_boot_calib = false,
0365 .fw_mem_mode = 0,
0366 .num_vdevs = 16 + 1,
0367 .num_peers = 512,
0368 .supports_suspend = true,
0369 .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
0370 .supports_regdb = true,
0371 .fix_l1ss = false,
0372 .credit_flow = true,
0373 .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
0374 .hal_params = &ath11k_hw_hal_params_qca6390,
0375 .supports_dynamic_smps_6ghz = false,
0376 .alloc_cacheable_memory = false,
0377 .supports_rssi_stats = true,
0378 .fw_wmi_diag_event = true,
0379 .current_cc_support = true,
0380 .dbr_debug_support = false,
0381 .global_reset = true,
0382 .bios_sar_capa = &ath11k_hw_sar_capa_wcn6855,
0383 .m3_fw_support = true,
0384 .fixed_bdf_addr = false,
0385 .fixed_mem_region = false,
0386 .static_window_map = false,
0387 .hybrid_bus_type = false,
0388 .fixed_fw_mem = false,
0389 .support_off_channel_tx = true,
0390 },
0391 {
0392 .name = "wcn6855 hw2.1",
0393 .hw_rev = ATH11K_HW_WCN6855_HW21,
0394 .fw = {
0395 .dir = "WCN6855/hw2.1",
0396 .board_size = 256 * 1024,
0397 .cal_offset = 128 * 1024,
0398 },
0399 .max_radios = 3,
0400 .bdf_addr = 0x4B0C0000,
0401 .hw_ops = &wcn6855_ops,
0402 .ring_mask = &ath11k_hw_ring_mask_qca6390,
0403 .internal_sleep_clock = true,
0404 .regs = &wcn6855_regs,
0405 .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390,
0406 .host_ce_config = ath11k_host_ce_config_qca6390,
0407 .ce_count = 9,
0408 .target_ce_config = ath11k_target_ce_config_wlan_qca6390,
0409 .target_ce_count = 9,
0410 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
0411 .svc_to_ce_map_len = 14,
0412 .single_pdev_only = true,
0413 .rxdma1_enable = false,
0414 .num_rxmda_per_pdev = 2,
0415 .rx_mac_buf_ring = true,
0416 .vdev_start_delay = true,
0417 .htt_peer_map_v2 = false,
0418
0419 .spectral = {
0420 .fft_sz = 0,
0421 .fft_pad_sz = 0,
0422 .summary_pad_sz = 0,
0423 .fft_hdr_len = 0,
0424 .max_fft_bins = 0,
0425 },
0426
0427 .interface_modes = BIT(NL80211_IFTYPE_STATION) |
0428 BIT(NL80211_IFTYPE_AP),
0429 .supports_monitor = false,
0430 .supports_shadow_regs = true,
0431 .idle_ps = true,
0432 .supports_sta_ps = true,
0433 .cold_boot_calib = false,
0434 .fw_mem_mode = 0,
0435 .num_vdevs = 16 + 1,
0436 .num_peers = 512,
0437 .supports_suspend = true,
0438 .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
0439 .supports_regdb = true,
0440 .fix_l1ss = false,
0441 .credit_flow = true,
0442 .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
0443 .hal_params = &ath11k_hw_hal_params_qca6390,
0444 .supports_dynamic_smps_6ghz = false,
0445 .alloc_cacheable_memory = false,
0446 .supports_rssi_stats = true,
0447 .fw_wmi_diag_event = true,
0448 .current_cc_support = true,
0449 .dbr_debug_support = false,
0450 .global_reset = true,
0451 .bios_sar_capa = &ath11k_hw_sar_capa_wcn6855,
0452 .m3_fw_support = true,
0453 .fixed_bdf_addr = false,
0454 .fixed_mem_region = false,
0455 .static_window_map = false,
0456 .hybrid_bus_type = false,
0457 .fixed_fw_mem = false,
0458 .support_off_channel_tx = true,
0459 },
0460 {
0461 .name = "wcn6750 hw1.0",
0462 .hw_rev = ATH11K_HW_WCN6750_HW10,
0463 .fw = {
0464 .dir = "WCN6750/hw1.0",
0465 .board_size = 256 * 1024,
0466 .cal_offset = 128 * 1024,
0467 },
0468 .max_radios = 1,
0469 .bdf_addr = 0x4B0C0000,
0470 .hw_ops = &wcn6750_ops,
0471 .ring_mask = &ath11k_hw_ring_mask_qca6390,
0472 .internal_sleep_clock = false,
0473 .regs = &wcn6750_regs,
0474 .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_WCN6750,
0475 .host_ce_config = ath11k_host_ce_config_qca6390,
0476 .ce_count = 9,
0477 .target_ce_config = ath11k_target_ce_config_wlan_qca6390,
0478 .target_ce_count = 9,
0479 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
0480 .svc_to_ce_map_len = 14,
0481 .single_pdev_only = true,
0482 .rxdma1_enable = false,
0483 .num_rxmda_per_pdev = 1,
0484 .rx_mac_buf_ring = true,
0485 .vdev_start_delay = true,
0486 .htt_peer_map_v2 = false,
0487
0488 .spectral = {
0489 .fft_sz = 0,
0490 .fft_pad_sz = 0,
0491 .summary_pad_sz = 0,
0492 .fft_hdr_len = 0,
0493 .max_fft_bins = 0,
0494 },
0495
0496 .interface_modes = BIT(NL80211_IFTYPE_STATION) |
0497 BIT(NL80211_IFTYPE_AP),
0498 .supports_monitor = false,
0499 .supports_shadow_regs = true,
0500 .idle_ps = true,
0501 .supports_sta_ps = true,
0502 .cold_boot_calib = false,
0503 .fw_mem_mode = 0,
0504 .num_vdevs = 16 + 1,
0505 .num_peers = 512,
0506 .supports_suspend = false,
0507 .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
0508 .supports_regdb = true,
0509 .fix_l1ss = false,
0510 .credit_flow = true,
0511 .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
0512 .hal_params = &ath11k_hw_hal_params_qca6390,
0513 .supports_dynamic_smps_6ghz = false,
0514 .alloc_cacheable_memory = false,
0515 .supports_rssi_stats = true,
0516 .fw_wmi_diag_event = false,
0517 .current_cc_support = true,
0518 .dbr_debug_support = false,
0519 .global_reset = false,
0520 .bios_sar_capa = NULL,
0521 .m3_fw_support = false,
0522 .fixed_bdf_addr = false,
0523 .fixed_mem_region = false,
0524 .static_window_map = true,
0525 .hybrid_bus_type = true,
0526 .fixed_fw_mem = true,
0527 .support_off_channel_tx = false,
0528 },
0529 };
0530
0531 static inline struct ath11k_pdev *ath11k_core_get_single_pdev(struct ath11k_base *ab)
0532 {
0533 WARN_ON(!ab->hw_params.single_pdev_only);
0534
0535 return &ab->pdevs[0];
0536 }
0537
0538 int ath11k_core_suspend(struct ath11k_base *ab)
0539 {
0540 int ret;
0541 struct ath11k_pdev *pdev;
0542 struct ath11k *ar;
0543
0544 if (!ab->hw_params.supports_suspend)
0545 return -EOPNOTSUPP;
0546
0547
0548
0549
0550 pdev = ath11k_core_get_single_pdev(ab);
0551 ar = pdev->ar;
0552 if (!ar || ar->state != ATH11K_STATE_OFF)
0553 return 0;
0554
0555 ret = ath11k_dp_rx_pktlog_stop(ab, true);
0556 if (ret) {
0557 ath11k_warn(ab, "failed to stop dp rx (and timer) pktlog during suspend: %d\n",
0558 ret);
0559 return ret;
0560 }
0561
0562 ret = ath11k_mac_wait_tx_complete(ar);
0563 if (ret) {
0564 ath11k_warn(ab, "failed to wait tx complete: %d\n", ret);
0565 return ret;
0566 }
0567
0568 ret = ath11k_wow_enable(ab);
0569 if (ret) {
0570 ath11k_warn(ab, "failed to enable wow during suspend: %d\n", ret);
0571 return ret;
0572 }
0573
0574 ret = ath11k_dp_rx_pktlog_stop(ab, false);
0575 if (ret) {
0576 ath11k_warn(ab, "failed to stop dp rx pktlog during suspend: %d\n",
0577 ret);
0578 return ret;
0579 }
0580
0581 ath11k_ce_stop_shadow_timers(ab);
0582 ath11k_dp_stop_shadow_timers(ab);
0583
0584 ath11k_hif_irq_disable(ab);
0585 ath11k_hif_ce_irq_disable(ab);
0586
0587 ret = ath11k_hif_suspend(ab);
0588 if (ret) {
0589 ath11k_warn(ab, "failed to suspend hif: %d\n", ret);
0590 return ret;
0591 }
0592
0593 return 0;
0594 }
0595 EXPORT_SYMBOL(ath11k_core_suspend);
0596
0597 int ath11k_core_resume(struct ath11k_base *ab)
0598 {
0599 int ret;
0600 struct ath11k_pdev *pdev;
0601 struct ath11k *ar;
0602
0603 if (!ab->hw_params.supports_suspend)
0604 return -EOPNOTSUPP;
0605
0606
0607
0608
0609 pdev = ath11k_core_get_single_pdev(ab);
0610 ar = pdev->ar;
0611 if (!ar || ar->state != ATH11K_STATE_OFF)
0612 return 0;
0613
0614 ret = ath11k_hif_resume(ab);
0615 if (ret) {
0616 ath11k_warn(ab, "failed to resume hif during resume: %d\n", ret);
0617 return ret;
0618 }
0619
0620 ath11k_hif_ce_irq_enable(ab);
0621 ath11k_hif_irq_enable(ab);
0622
0623 ret = ath11k_dp_rx_pktlog_start(ab);
0624 if (ret) {
0625 ath11k_warn(ab, "failed to start rx pktlog during resume: %d\n",
0626 ret);
0627 return ret;
0628 }
0629
0630 ret = ath11k_wow_wakeup(ab);
0631 if (ret) {
0632 ath11k_warn(ab, "failed to wakeup wow during resume: %d\n", ret);
0633 return ret;
0634 }
0635
0636 return 0;
0637 }
0638 EXPORT_SYMBOL(ath11k_core_resume);
0639
0640 static void ath11k_core_check_cc_code_bdfext(const struct dmi_header *hdr, void *data)
0641 {
0642 struct ath11k_base *ab = data;
0643 const char *magic = ATH11K_SMBIOS_BDF_EXT_MAGIC;
0644 struct ath11k_smbios_bdf *smbios = (struct ath11k_smbios_bdf *)hdr;
0645 ssize_t copied;
0646 size_t len;
0647 int i;
0648
0649 if (ab->qmi.target.bdf_ext[0] != '\0')
0650 return;
0651
0652 if (hdr->type != ATH11K_SMBIOS_BDF_EXT_TYPE)
0653 return;
0654
0655 if (hdr->length != ATH11K_SMBIOS_BDF_EXT_LENGTH) {
0656 ath11k_dbg(ab, ATH11K_DBG_BOOT,
0657 "wrong smbios bdf ext type length (%d).\n",
0658 hdr->length);
0659 return;
0660 }
0661
0662 spin_lock_bh(&ab->base_lock);
0663
0664 switch (smbios->country_code_flag) {
0665 case ATH11K_SMBIOS_CC_ISO:
0666 ab->new_alpha2[0] = (smbios->cc_code >> 8) & 0xff;
0667 ab->new_alpha2[1] = smbios->cc_code & 0xff;
0668 ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot smbios cc_code %c%c\n",
0669 ab->new_alpha2[0], ab->new_alpha2[1]);
0670 break;
0671 case ATH11K_SMBIOS_CC_WW:
0672 ab->new_alpha2[0] = '0';
0673 ab->new_alpha2[1] = '0';
0674 ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot smbios worldwide regdomain\n");
0675 break;
0676 default:
0677 ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot ignore smbios country code setting %d\n",
0678 smbios->country_code_flag);
0679 break;
0680 }
0681
0682 spin_unlock_bh(&ab->base_lock);
0683
0684 if (!smbios->bdf_enabled) {
0685 ath11k_dbg(ab, ATH11K_DBG_BOOT, "bdf variant name not found.\n");
0686 return;
0687 }
0688
0689
0690 if (memcmp(smbios->bdf_ext, magic, strlen(magic)) != 0) {
0691 ath11k_dbg(ab, ATH11K_DBG_BOOT,
0692 "bdf variant magic does not match.\n");
0693 return;
0694 }
0695
0696 len = min_t(size_t,
0697 strlen(smbios->bdf_ext), sizeof(ab->qmi.target.bdf_ext));
0698 for (i = 0; i < len; i++) {
0699 if (!isascii(smbios->bdf_ext[i]) || !isprint(smbios->bdf_ext[i])) {
0700 ath11k_dbg(ab, ATH11K_DBG_BOOT,
0701 "bdf variant name contains non ascii chars.\n");
0702 return;
0703 }
0704 }
0705
0706
0707 copied = strscpy(ab->qmi.target.bdf_ext, smbios->bdf_ext + strlen(magic),
0708 sizeof(ab->qmi.target.bdf_ext));
0709 if (copied < 0) {
0710 ath11k_dbg(ab, ATH11K_DBG_BOOT,
0711 "bdf variant string is longer than the buffer can accommodate\n");
0712 return;
0713 }
0714
0715 ath11k_dbg(ab, ATH11K_DBG_BOOT,
0716 "found and validated bdf variant smbios_type 0x%x bdf %s\n",
0717 ATH11K_SMBIOS_BDF_EXT_TYPE, ab->qmi.target.bdf_ext);
0718 }
0719
0720 int ath11k_core_check_smbios(struct ath11k_base *ab)
0721 {
0722 ab->qmi.target.bdf_ext[0] = '\0';
0723 dmi_walk(ath11k_core_check_cc_code_bdfext, ab);
0724
0725 if (ab->qmi.target.bdf_ext[0] == '\0')
0726 return -ENODATA;
0727
0728 return 0;
0729 }
0730
0731 int ath11k_core_check_dt(struct ath11k_base *ab)
0732 {
0733 size_t max_len = sizeof(ab->qmi.target.bdf_ext);
0734 const char *variant = NULL;
0735 struct device_node *node;
0736
0737 node = ab->dev->of_node;
0738 if (!node)
0739 return -ENOENT;
0740
0741 of_property_read_string(node, "qcom,ath11k-calibration-variant",
0742 &variant);
0743 if (!variant)
0744 return -ENODATA;
0745
0746 if (strscpy(ab->qmi.target.bdf_ext, variant, max_len) < 0)
0747 ath11k_dbg(ab, ATH11K_DBG_BOOT,
0748 "bdf variant string is longer than the buffer can accommodate (variant: %s)\n",
0749 variant);
0750
0751 return 0;
0752 }
0753
0754 static int __ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
0755 size_t name_len, bool with_variant)
0756 {
0757
0758 char variant[9 + ATH11K_QMI_BDF_EXT_STR_LENGTH] = { 0 };
0759
0760 if (with_variant && ab->qmi.target.bdf_ext[0] != '\0')
0761 scnprintf(variant, sizeof(variant), ",variant=%s",
0762 ab->qmi.target.bdf_ext);
0763
0764 switch (ab->id.bdf_search) {
0765 case ATH11K_BDF_SEARCH_BUS_AND_BOARD:
0766 scnprintf(name, name_len,
0767 "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x,qmi-chip-id=%d,qmi-board-id=%d%s",
0768 ath11k_bus_str(ab->hif.bus),
0769 ab->id.vendor, ab->id.device,
0770 ab->id.subsystem_vendor,
0771 ab->id.subsystem_device,
0772 ab->qmi.target.chip_id,
0773 ab->qmi.target.board_id,
0774 variant);
0775 break;
0776 default:
0777 scnprintf(name, name_len,
0778 "bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s",
0779 ath11k_bus_str(ab->hif.bus),
0780 ab->qmi.target.chip_id,
0781 ab->qmi.target.board_id, variant);
0782 break;
0783 }
0784
0785 ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot using board name '%s'\n", name);
0786
0787 return 0;
0788 }
0789
0790 static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
0791 size_t name_len)
0792 {
0793 return __ath11k_core_create_board_name(ab, name, name_len, true);
0794 }
0795
0796 static int ath11k_core_create_fallback_board_name(struct ath11k_base *ab, char *name,
0797 size_t name_len)
0798 {
0799 return __ath11k_core_create_board_name(ab, name, name_len, false);
0800 }
0801
0802 const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab,
0803 const char *file)
0804 {
0805 const struct firmware *fw;
0806 char path[100];
0807 int ret;
0808
0809 if (file == NULL)
0810 return ERR_PTR(-ENOENT);
0811
0812 ath11k_core_create_firmware_path(ab, file, path, sizeof(path));
0813
0814 ret = firmware_request_nowarn(&fw, path, ab->dev);
0815 if (ret)
0816 return ERR_PTR(ret);
0817
0818 ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot firmware request %s size %zu\n",
0819 path, fw->size);
0820
0821 return fw;
0822 }
0823
0824 void ath11k_core_free_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
0825 {
0826 if (!IS_ERR(bd->fw))
0827 release_firmware(bd->fw);
0828
0829 memset(bd, 0, sizeof(*bd));
0830 }
0831
0832 static int ath11k_core_parse_bd_ie_board(struct ath11k_base *ab,
0833 struct ath11k_board_data *bd,
0834 const void *buf, size_t buf_len,
0835 const char *boardname,
0836 int ie_id,
0837 int name_id,
0838 int data_id)
0839 {
0840 const struct ath11k_fw_ie *hdr;
0841 bool name_match_found;
0842 int ret, board_ie_id;
0843 size_t board_ie_len;
0844 const void *board_ie_data;
0845
0846 name_match_found = false;
0847
0848
0849 while (buf_len > sizeof(struct ath11k_fw_ie)) {
0850 hdr = buf;
0851 board_ie_id = le32_to_cpu(hdr->id);
0852 board_ie_len = le32_to_cpu(hdr->len);
0853 board_ie_data = hdr->data;
0854
0855 buf_len -= sizeof(*hdr);
0856 buf += sizeof(*hdr);
0857
0858 if (buf_len < ALIGN(board_ie_len, 4)) {
0859 ath11k_err(ab, "invalid %s length: %zu < %zu\n",
0860 ath11k_bd_ie_type_str(ie_id),
0861 buf_len, ALIGN(board_ie_len, 4));
0862 ret = -EINVAL;
0863 goto out;
0864 }
0865
0866 if (board_ie_id == name_id) {
0867 ath11k_dbg_dump(ab, ATH11K_DBG_BOOT, "board name", "",
0868 board_ie_data, board_ie_len);
0869
0870 if (board_ie_len != strlen(boardname))
0871 goto next;
0872
0873 ret = memcmp(board_ie_data, boardname, strlen(boardname));
0874 if (ret)
0875 goto next;
0876
0877 name_match_found = true;
0878 ath11k_dbg(ab, ATH11K_DBG_BOOT,
0879 "boot found match %s for name '%s'",
0880 ath11k_bd_ie_type_str(ie_id),
0881 boardname);
0882 } else if (board_ie_id == data_id) {
0883 if (!name_match_found)
0884
0885 goto next;
0886
0887 ath11k_dbg(ab, ATH11K_DBG_BOOT,
0888 "boot found %s for '%s'",
0889 ath11k_bd_ie_type_str(ie_id),
0890 boardname);
0891
0892 bd->data = board_ie_data;
0893 bd->len = board_ie_len;
0894
0895 ret = 0;
0896 goto out;
0897 } else {
0898 ath11k_warn(ab, "unknown %s id found: %d\n",
0899 ath11k_bd_ie_type_str(ie_id),
0900 board_ie_id);
0901 }
0902 next:
0903
0904 board_ie_len = ALIGN(board_ie_len, 4);
0905
0906 buf_len -= board_ie_len;
0907 buf += board_ie_len;
0908 }
0909
0910
0911 ret = -ENOENT;
0912
0913 out:
0914 return ret;
0915 }
0916
0917 static int ath11k_core_fetch_board_data_api_n(struct ath11k_base *ab,
0918 struct ath11k_board_data *bd,
0919 const char *boardname,
0920 int ie_id_match,
0921 int name_id,
0922 int data_id)
0923 {
0924 size_t len, magic_len;
0925 const u8 *data;
0926 char *filename, filepath[100];
0927 size_t ie_len;
0928 struct ath11k_fw_ie *hdr;
0929 int ret, ie_id;
0930
0931 filename = ATH11K_BOARD_API2_FILE;
0932
0933 if (!bd->fw)
0934 bd->fw = ath11k_core_firmware_request(ab, filename);
0935
0936 if (IS_ERR(bd->fw))
0937 return PTR_ERR(bd->fw);
0938
0939 data = bd->fw->data;
0940 len = bd->fw->size;
0941
0942 ath11k_core_create_firmware_path(ab, filename,
0943 filepath, sizeof(filepath));
0944
0945
0946 magic_len = strlen(ATH11K_BOARD_MAGIC) + 1;
0947 if (len < magic_len) {
0948 ath11k_err(ab, "failed to find magic value in %s, file too short: %zu\n",
0949 filepath, len);
0950 ret = -EINVAL;
0951 goto err;
0952 }
0953
0954 if (memcmp(data, ATH11K_BOARD_MAGIC, magic_len)) {
0955 ath11k_err(ab, "found invalid board magic\n");
0956 ret = -EINVAL;
0957 goto err;
0958 }
0959
0960
0961 magic_len = ALIGN(magic_len, 4);
0962 if (len < magic_len) {
0963 ath11k_err(ab, "failed: %s too small to contain board data, len: %zu\n",
0964 filepath, len);
0965 ret = -EINVAL;
0966 goto err;
0967 }
0968
0969 data += magic_len;
0970 len -= magic_len;
0971
0972 while (len > sizeof(struct ath11k_fw_ie)) {
0973 hdr = (struct ath11k_fw_ie *)data;
0974 ie_id = le32_to_cpu(hdr->id);
0975 ie_len = le32_to_cpu(hdr->len);
0976
0977 len -= sizeof(*hdr);
0978 data = hdr->data;
0979
0980 if (len < ALIGN(ie_len, 4)) {
0981 ath11k_err(ab, "invalid length for board ie_id %d ie_len %zu len %zu\n",
0982 ie_id, ie_len, len);
0983 ret = -EINVAL;
0984 goto err;
0985 }
0986
0987 if (ie_id == ie_id_match) {
0988 ret = ath11k_core_parse_bd_ie_board(ab, bd, data,
0989 ie_len,
0990 boardname,
0991 ie_id_match,
0992 name_id,
0993 data_id);
0994 if (ret == -ENOENT)
0995
0996 goto next;
0997 else if (ret)
0998
0999 goto err;
1000
1001 goto out;
1002 }
1003 next:
1004
1005 ie_len = ALIGN(ie_len, 4);
1006
1007 len -= ie_len;
1008 data += ie_len;
1009 }
1010
1011 out:
1012 if (!bd->data || !bd->len) {
1013 ath11k_dbg(ab, ATH11K_DBG_BOOT,
1014 "failed to fetch %s for %s from %s\n",
1015 ath11k_bd_ie_type_str(ie_id_match),
1016 boardname, filepath);
1017 ret = -ENODATA;
1018 goto err;
1019 }
1020
1021 return 0;
1022
1023 err:
1024 ath11k_core_free_bdf(ab, bd);
1025 return ret;
1026 }
1027
1028 int ath11k_core_fetch_board_data_api_1(struct ath11k_base *ab,
1029 struct ath11k_board_data *bd,
1030 const char *name)
1031 {
1032 bd->fw = ath11k_core_firmware_request(ab, name);
1033
1034 if (IS_ERR(bd->fw))
1035 return PTR_ERR(bd->fw);
1036
1037 bd->data = bd->fw->data;
1038 bd->len = bd->fw->size;
1039
1040 return 0;
1041 }
1042
1043 #define BOARD_NAME_SIZE 200
1044 int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
1045 {
1046 char boardname[BOARD_NAME_SIZE], fallback_boardname[BOARD_NAME_SIZE];
1047 char *filename, filepath[100];
1048 int ret;
1049
1050 filename = ATH11K_BOARD_API2_FILE;
1051
1052 ret = ath11k_core_create_board_name(ab, boardname, sizeof(boardname));
1053 if (ret) {
1054 ath11k_err(ab, "failed to create board name: %d", ret);
1055 return ret;
1056 }
1057
1058 ab->bd_api = 2;
1059 ret = ath11k_core_fetch_board_data_api_n(ab, bd, boardname,
1060 ATH11K_BD_IE_BOARD,
1061 ATH11K_BD_IE_BOARD_NAME,
1062 ATH11K_BD_IE_BOARD_DATA);
1063 if (!ret)
1064 goto success;
1065
1066 ret = ath11k_core_create_fallback_board_name(ab, fallback_boardname,
1067 sizeof(fallback_boardname));
1068 if (ret) {
1069 ath11k_err(ab, "failed to create fallback board name: %d", ret);
1070 return ret;
1071 }
1072
1073 ret = ath11k_core_fetch_board_data_api_n(ab, bd, fallback_boardname,
1074 ATH11K_BD_IE_BOARD,
1075 ATH11K_BD_IE_BOARD_NAME,
1076 ATH11K_BD_IE_BOARD_DATA);
1077 if (!ret)
1078 goto success;
1079
1080 ab->bd_api = 1;
1081 ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_DEFAULT_BOARD_FILE);
1082 if (ret) {
1083 ath11k_core_create_firmware_path(ab, filename,
1084 filepath, sizeof(filepath));
1085 ath11k_err(ab, "failed to fetch board data for %s from %s\n",
1086 boardname, filepath);
1087 if (memcmp(boardname, fallback_boardname, strlen(boardname)))
1088 ath11k_err(ab, "failed to fetch board data for %s from %s\n",
1089 fallback_boardname, filepath);
1090
1091 ath11k_err(ab, "failed to fetch board.bin from %s\n",
1092 ab->hw_params.fw.dir);
1093 return ret;
1094 }
1095
1096 success:
1097 ath11k_dbg(ab, ATH11K_DBG_BOOT, "using board api %d\n", ab->bd_api);
1098 return 0;
1099 }
1100
1101 int ath11k_core_fetch_regdb(struct ath11k_base *ab, struct ath11k_board_data *bd)
1102 {
1103 char boardname[BOARD_NAME_SIZE];
1104 int ret;
1105
1106 ret = ath11k_core_create_board_name(ab, boardname, BOARD_NAME_SIZE);
1107 if (ret) {
1108 ath11k_dbg(ab, ATH11K_DBG_BOOT,
1109 "failed to create board name for regdb: %d", ret);
1110 goto exit;
1111 }
1112
1113 ret = ath11k_core_fetch_board_data_api_n(ab, bd, boardname,
1114 ATH11K_BD_IE_REGDB,
1115 ATH11K_BD_IE_REGDB_NAME,
1116 ATH11K_BD_IE_REGDB_DATA);
1117 if (!ret)
1118 goto exit;
1119
1120 ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_REGDB_FILE_NAME);
1121 if (ret)
1122 ath11k_dbg(ab, ATH11K_DBG_BOOT, "failed to fetch %s from %s\n",
1123 ATH11K_REGDB_FILE_NAME, ab->hw_params.fw.dir);
1124
1125 exit:
1126 if (!ret)
1127 ath11k_dbg(ab, ATH11K_DBG_BOOT, "fetched regdb\n");
1128
1129 return ret;
1130 }
1131
1132 static void ath11k_core_stop(struct ath11k_base *ab)
1133 {
1134 if (!test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags))
1135 ath11k_qmi_firmware_stop(ab);
1136
1137 ath11k_hif_stop(ab);
1138 ath11k_wmi_detach(ab);
1139 ath11k_dp_pdev_reo_cleanup(ab);
1140
1141
1142 }
1143
1144 static int ath11k_core_soc_create(struct ath11k_base *ab)
1145 {
1146 int ret;
1147
1148 ret = ath11k_qmi_init_service(ab);
1149 if (ret) {
1150 ath11k_err(ab, "failed to initialize qmi :%d\n", ret);
1151 return ret;
1152 }
1153
1154 ret = ath11k_debugfs_soc_create(ab);
1155 if (ret) {
1156 ath11k_err(ab, "failed to create ath11k debugfs\n");
1157 goto err_qmi_deinit;
1158 }
1159
1160 ret = ath11k_hif_power_up(ab);
1161 if (ret) {
1162 ath11k_err(ab, "failed to power up :%d\n", ret);
1163 goto err_debugfs_reg;
1164 }
1165
1166 return 0;
1167
1168 err_debugfs_reg:
1169 ath11k_debugfs_soc_destroy(ab);
1170 err_qmi_deinit:
1171 ath11k_qmi_deinit_service(ab);
1172 return ret;
1173 }
1174
1175 static void ath11k_core_soc_destroy(struct ath11k_base *ab)
1176 {
1177 ath11k_debugfs_soc_destroy(ab);
1178 ath11k_dp_free(ab);
1179 ath11k_reg_free(ab);
1180 ath11k_qmi_deinit_service(ab);
1181 }
1182
1183 static int ath11k_core_pdev_create(struct ath11k_base *ab)
1184 {
1185 int ret;
1186
1187 ret = ath11k_debugfs_pdev_create(ab);
1188 if (ret) {
1189 ath11k_err(ab, "failed to create core pdev debugfs: %d\n", ret);
1190 return ret;
1191 }
1192
1193 ret = ath11k_dp_pdev_alloc(ab);
1194 if (ret) {
1195 ath11k_err(ab, "failed to attach DP pdev: %d\n", ret);
1196 goto err_pdev_debug;
1197 }
1198
1199 ret = ath11k_mac_register(ab);
1200 if (ret) {
1201 ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret);
1202 goto err_dp_pdev_free;
1203 }
1204
1205 ret = ath11k_thermal_register(ab);
1206 if (ret) {
1207 ath11k_err(ab, "could not register thermal device: %d\n",
1208 ret);
1209 goto err_mac_unregister;
1210 }
1211
1212 ret = ath11k_spectral_init(ab);
1213 if (ret) {
1214 ath11k_err(ab, "failed to init spectral %d\n", ret);
1215 goto err_thermal_unregister;
1216 }
1217
1218 return 0;
1219
1220 err_thermal_unregister:
1221 ath11k_thermal_unregister(ab);
1222 err_mac_unregister:
1223 ath11k_mac_unregister(ab);
1224 err_dp_pdev_free:
1225 ath11k_dp_pdev_free(ab);
1226 err_pdev_debug:
1227 ath11k_debugfs_pdev_destroy(ab);
1228
1229 return ret;
1230 }
1231
1232 static void ath11k_core_pdev_destroy(struct ath11k_base *ab)
1233 {
1234 ath11k_spectral_deinit(ab);
1235 ath11k_thermal_unregister(ab);
1236 ath11k_mac_unregister(ab);
1237 ath11k_hif_irq_disable(ab);
1238 ath11k_dp_pdev_free(ab);
1239 ath11k_debugfs_pdev_destroy(ab);
1240 }
1241
1242 static int ath11k_core_start(struct ath11k_base *ab)
1243 {
1244 int ret;
1245
1246 ret = ath11k_wmi_attach(ab);
1247 if (ret) {
1248 ath11k_err(ab, "failed to attach wmi: %d\n", ret);
1249 return ret;
1250 }
1251
1252 ret = ath11k_htc_init(ab);
1253 if (ret) {
1254 ath11k_err(ab, "failed to init htc: %d\n", ret);
1255 goto err_wmi_detach;
1256 }
1257
1258 ret = ath11k_hif_start(ab);
1259 if (ret) {
1260 ath11k_err(ab, "failed to start HIF: %d\n", ret);
1261 goto err_wmi_detach;
1262 }
1263
1264 ret = ath11k_htc_wait_target(&ab->htc);
1265 if (ret) {
1266 ath11k_err(ab, "failed to connect to HTC: %d\n", ret);
1267 goto err_hif_stop;
1268 }
1269
1270 ret = ath11k_dp_htt_connect(&ab->dp);
1271 if (ret) {
1272 ath11k_err(ab, "failed to connect to HTT: %d\n", ret);
1273 goto err_hif_stop;
1274 }
1275
1276 ret = ath11k_wmi_connect(ab);
1277 if (ret) {
1278 ath11k_err(ab, "failed to connect wmi: %d\n", ret);
1279 goto err_hif_stop;
1280 }
1281
1282 ret = ath11k_htc_start(&ab->htc);
1283 if (ret) {
1284 ath11k_err(ab, "failed to start HTC: %d\n", ret);
1285 goto err_hif_stop;
1286 }
1287
1288 ret = ath11k_wmi_wait_for_service_ready(ab);
1289 if (ret) {
1290 ath11k_err(ab, "failed to receive wmi service ready event: %d\n",
1291 ret);
1292 goto err_hif_stop;
1293 }
1294
1295 ret = ath11k_mac_allocate(ab);
1296 if (ret) {
1297 ath11k_err(ab, "failed to create new hw device with mac80211 :%d\n",
1298 ret);
1299 goto err_hif_stop;
1300 }
1301
1302 ath11k_dp_pdev_pre_alloc(ab);
1303
1304 ret = ath11k_dp_pdev_reo_setup(ab);
1305 if (ret) {
1306 ath11k_err(ab, "failed to initialize reo destination rings: %d\n", ret);
1307 goto err_mac_destroy;
1308 }
1309
1310 ret = ath11k_wmi_cmd_init(ab);
1311 if (ret) {
1312 ath11k_err(ab, "failed to send wmi init cmd: %d\n", ret);
1313 goto err_reo_cleanup;
1314 }
1315
1316 ret = ath11k_wmi_wait_for_unified_ready(ab);
1317 if (ret) {
1318 ath11k_err(ab, "failed to receive wmi unified ready event: %d\n",
1319 ret);
1320 goto err_reo_cleanup;
1321 }
1322
1323
1324 if (ab->hw_params.single_pdev_only && ab->hw_params.num_rxmda_per_pdev > 1) {
1325 ret = ath11k_wmi_set_hw_mode(ab, WMI_HOST_HW_MODE_DBS);
1326 if (ret) {
1327 ath11k_err(ab, "failed to send dbs mode: %d\n", ret);
1328 goto err_hif_stop;
1329 }
1330 }
1331
1332 ret = ath11k_dp_tx_htt_h2t_ver_req_msg(ab);
1333 if (ret) {
1334 ath11k_err(ab, "failed to send htt version request message: %d\n",
1335 ret);
1336 goto err_reo_cleanup;
1337 }
1338
1339 return 0;
1340
1341 err_reo_cleanup:
1342 ath11k_dp_pdev_reo_cleanup(ab);
1343 err_mac_destroy:
1344 ath11k_mac_destroy(ab);
1345 err_hif_stop:
1346 ath11k_hif_stop(ab);
1347 err_wmi_detach:
1348 ath11k_wmi_detach(ab);
1349
1350 return ret;
1351 }
1352
1353 static int ath11k_core_start_firmware(struct ath11k_base *ab,
1354 enum ath11k_firmware_mode mode)
1355 {
1356 int ret;
1357
1358 ath11k_ce_get_shadow_config(ab, &ab->qmi.ce_cfg.shadow_reg_v2,
1359 &ab->qmi.ce_cfg.shadow_reg_v2_len);
1360
1361 ret = ath11k_qmi_firmware_start(ab, mode);
1362 if (ret) {
1363 ath11k_err(ab, "failed to send firmware start: %d\n", ret);
1364 return ret;
1365 }
1366
1367 return ret;
1368 }
1369
1370 int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab)
1371 {
1372 int ret;
1373
1374 ret = ath11k_core_start_firmware(ab, ATH11K_FIRMWARE_MODE_NORMAL);
1375 if (ret) {
1376 ath11k_err(ab, "failed to start firmware: %d\n", ret);
1377 return ret;
1378 }
1379
1380 ret = ath11k_ce_init_pipes(ab);
1381 if (ret) {
1382 ath11k_err(ab, "failed to initialize CE: %d\n", ret);
1383 goto err_firmware_stop;
1384 }
1385
1386 ret = ath11k_dp_alloc(ab);
1387 if (ret) {
1388 ath11k_err(ab, "failed to init DP: %d\n", ret);
1389 goto err_firmware_stop;
1390 }
1391
1392 switch (ath11k_crypto_mode) {
1393 case ATH11K_CRYPT_MODE_SW:
1394 set_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
1395 set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
1396 break;
1397 case ATH11K_CRYPT_MODE_HW:
1398 clear_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
1399 clear_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
1400 break;
1401 default:
1402 ath11k_info(ab, "invalid crypto_mode: %d\n", ath11k_crypto_mode);
1403 return -EINVAL;
1404 }
1405
1406 if (ath11k_frame_mode == ATH11K_HW_TXRX_RAW)
1407 set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
1408
1409 mutex_lock(&ab->core_lock);
1410 ret = ath11k_core_start(ab);
1411 if (ret) {
1412 ath11k_err(ab, "failed to start core: %d\n", ret);
1413 goto err_dp_free;
1414 }
1415
1416 ret = ath11k_core_pdev_create(ab);
1417 if (ret) {
1418 ath11k_err(ab, "failed to create pdev core: %d\n", ret);
1419 goto err_core_stop;
1420 }
1421 ath11k_hif_irq_enable(ab);
1422 mutex_unlock(&ab->core_lock);
1423
1424 return 0;
1425
1426 err_core_stop:
1427 ath11k_core_stop(ab);
1428 ath11k_mac_destroy(ab);
1429 err_dp_free:
1430 ath11k_dp_free(ab);
1431 mutex_unlock(&ab->core_lock);
1432 err_firmware_stop:
1433 ath11k_qmi_firmware_stop(ab);
1434
1435 return ret;
1436 }
1437
1438 static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab)
1439 {
1440 int ret;
1441
1442 mutex_lock(&ab->core_lock);
1443 ath11k_thermal_unregister(ab);
1444 ath11k_hif_irq_disable(ab);
1445 ath11k_dp_pdev_free(ab);
1446 ath11k_spectral_deinit(ab);
1447 ath11k_hif_stop(ab);
1448 ath11k_wmi_detach(ab);
1449 ath11k_dp_pdev_reo_cleanup(ab);
1450 mutex_unlock(&ab->core_lock);
1451
1452 ath11k_dp_free(ab);
1453 ath11k_hal_srng_deinit(ab);
1454
1455 ab->free_vdev_map = (1LL << (ab->num_radios * TARGET_NUM_VDEVS(ab))) - 1;
1456
1457 ret = ath11k_hal_srng_init(ab);
1458 if (ret)
1459 return ret;
1460
1461 clear_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags);
1462
1463 ret = ath11k_core_qmi_firmware_ready(ab);
1464 if (ret)
1465 goto err_hal_srng_deinit;
1466
1467 clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
1468
1469 return 0;
1470
1471 err_hal_srng_deinit:
1472 ath11k_hal_srng_deinit(ab);
1473 return ret;
1474 }
1475
1476 void ath11k_core_halt(struct ath11k *ar)
1477 {
1478 struct ath11k_base *ab = ar->ab;
1479
1480 lockdep_assert_held(&ar->conf_mutex);
1481
1482 ar->num_created_vdevs = 0;
1483 ar->allocated_vdev_map = 0;
1484
1485 ath11k_mac_scan_finish(ar);
1486 ath11k_mac_peer_cleanup_all(ar);
1487 cancel_delayed_work_sync(&ar->scan.timeout);
1488 cancel_work_sync(&ar->regd_update_work);
1489 cancel_work_sync(&ab->update_11d_work);
1490
1491 rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], NULL);
1492 synchronize_rcu();
1493 INIT_LIST_HEAD(&ar->arvifs);
1494 idr_init(&ar->txmgmt_idr);
1495 }
1496
1497 static void ath11k_update_11d(struct work_struct *work)
1498 {
1499 struct ath11k_base *ab = container_of(work, struct ath11k_base, update_11d_work);
1500 struct ath11k *ar;
1501 struct ath11k_pdev *pdev;
1502 struct wmi_set_current_country_params set_current_param = {};
1503 int ret, i;
1504
1505 spin_lock_bh(&ab->base_lock);
1506 memcpy(&set_current_param.alpha2, &ab->new_alpha2, 2);
1507 spin_unlock_bh(&ab->base_lock);
1508
1509 ath11k_dbg(ab, ATH11K_DBG_WMI, "update 11d new cc %c%c\n",
1510 set_current_param.alpha2[0],
1511 set_current_param.alpha2[1]);
1512
1513 for (i = 0; i < ab->num_radios; i++) {
1514 pdev = &ab->pdevs[i];
1515 ar = pdev->ar;
1516
1517 memcpy(&ar->alpha2, &set_current_param.alpha2, 2);
1518 ret = ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param);
1519 if (ret)
1520 ath11k_warn(ar->ab,
1521 "pdev id %d failed set current country code: %d\n",
1522 i, ret);
1523 }
1524 }
1525
1526 static void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab)
1527 {
1528 struct ath11k *ar;
1529 struct ath11k_pdev *pdev;
1530 int i;
1531
1532 spin_lock_bh(&ab->base_lock);
1533 ab->stats.fw_crash_counter++;
1534 spin_unlock_bh(&ab->base_lock);
1535
1536 for (i = 0; i < ab->num_radios; i++) {
1537 pdev = &ab->pdevs[i];
1538 ar = pdev->ar;
1539 if (!ar || ar->state == ATH11K_STATE_OFF)
1540 continue;
1541
1542 ieee80211_stop_queues(ar->hw);
1543 ath11k_mac_drain_tx(ar);
1544 ar->state_11d = ATH11K_11D_IDLE;
1545 complete(&ar->completed_11d_scan);
1546 complete(&ar->scan.started);
1547 complete(&ar->scan.completed);
1548 complete(&ar->scan.on_channel);
1549 complete(&ar->peer_assoc_done);
1550 complete(&ar->peer_delete_done);
1551 complete(&ar->install_key_done);
1552 complete(&ar->vdev_setup_done);
1553 complete(&ar->vdev_delete_done);
1554 complete(&ar->bss_survey_done);
1555 complete(&ar->thermal.wmi_sync);
1556
1557 wake_up(&ar->dp.tx_empty_waitq);
1558 idr_for_each(&ar->txmgmt_idr,
1559 ath11k_mac_tx_mgmt_pending_free, ar);
1560 idr_destroy(&ar->txmgmt_idr);
1561 wake_up(&ar->txmgmt_empty_waitq);
1562 }
1563
1564 wake_up(&ab->wmi_ab.tx_credits_wq);
1565 wake_up(&ab->peer_mapping_wq);
1566 }
1567
1568 static void ath11k_core_post_reconfigure_recovery(struct ath11k_base *ab)
1569 {
1570 struct ath11k *ar;
1571 struct ath11k_pdev *pdev;
1572 int i;
1573
1574 for (i = 0; i < ab->num_radios; i++) {
1575 pdev = &ab->pdevs[i];
1576 ar = pdev->ar;
1577 if (!ar || ar->state == ATH11K_STATE_OFF)
1578 continue;
1579
1580 mutex_lock(&ar->conf_mutex);
1581
1582 switch (ar->state) {
1583 case ATH11K_STATE_ON:
1584 ar->state = ATH11K_STATE_RESTARTING;
1585 ath11k_core_halt(ar);
1586 ieee80211_restart_hw(ar->hw);
1587 break;
1588 case ATH11K_STATE_OFF:
1589 ath11k_warn(ab,
1590 "cannot restart radio %d that hasn't been started\n",
1591 i);
1592 break;
1593 case ATH11K_STATE_RESTARTING:
1594 break;
1595 case ATH11K_STATE_RESTARTED:
1596 ar->state = ATH11K_STATE_WEDGED;
1597 fallthrough;
1598 case ATH11K_STATE_WEDGED:
1599 ath11k_warn(ab,
1600 "device is wedged, will not restart radio %d\n", i);
1601 break;
1602 }
1603 mutex_unlock(&ar->conf_mutex);
1604 }
1605 complete(&ab->driver_recovery);
1606 }
1607
1608 static void ath11k_core_restart(struct work_struct *work)
1609 {
1610 struct ath11k_base *ab = container_of(work, struct ath11k_base, restart_work);
1611 int ret;
1612
1613 if (!ab->is_reset)
1614 ath11k_core_pre_reconfigure_recovery(ab);
1615
1616 ret = ath11k_core_reconfigure_on_crash(ab);
1617 if (ret) {
1618 ath11k_err(ab, "failed to reconfigure driver on crash recovery\n");
1619 return;
1620 }
1621
1622 if (ab->is_reset)
1623 complete_all(&ab->reconfigure_complete);
1624
1625 if (!ab->is_reset)
1626 ath11k_core_post_reconfigure_recovery(ab);
1627 }
1628
1629 static void ath11k_core_reset(struct work_struct *work)
1630 {
1631 struct ath11k_base *ab = container_of(work, struct ath11k_base, reset_work);
1632 int reset_count, fail_cont_count;
1633 long time_left;
1634
1635 if (!(test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))) {
1636 ath11k_warn(ab, "ignore reset dev flags 0x%lx\n", ab->dev_flags);
1637 return;
1638 }
1639
1640
1641
1642
1643 fail_cont_count = atomic_read(&ab->fail_cont_count);
1644
1645 if (fail_cont_count >= ATH11K_RESET_MAX_FAIL_COUNT_FINAL)
1646 return;
1647
1648 if (fail_cont_count >= ATH11K_RESET_MAX_FAIL_COUNT_FIRST &&
1649 time_before(jiffies, ab->reset_fail_timeout))
1650 return;
1651
1652 reset_count = atomic_inc_return(&ab->reset_count);
1653
1654 if (reset_count > 1) {
1655
1656
1657
1658
1659 ath11k_warn(ab, "already resetting count %d\n", reset_count);
1660
1661 reinit_completion(&ab->reset_complete);
1662 time_left = wait_for_completion_timeout(&ab->reset_complete,
1663 ATH11K_RESET_TIMEOUT_HZ);
1664
1665 if (time_left) {
1666 ath11k_dbg(ab, ATH11K_DBG_BOOT, "to skip reset\n");
1667 atomic_dec(&ab->reset_count);
1668 return;
1669 }
1670
1671 ab->reset_fail_timeout = jiffies + ATH11K_RESET_FAIL_TIMEOUT_HZ;
1672
1673 atomic_inc(&ab->fail_cont_count);
1674 }
1675
1676 ath11k_dbg(ab, ATH11K_DBG_BOOT, "reset starting\n");
1677
1678 ab->is_reset = true;
1679 atomic_set(&ab->recovery_count, 0);
1680 reinit_completion(&ab->recovery_start);
1681 atomic_set(&ab->recovery_start_count, 0);
1682
1683 ath11k_core_pre_reconfigure_recovery(ab);
1684
1685 reinit_completion(&ab->reconfigure_complete);
1686 ath11k_core_post_reconfigure_recovery(ab);
1687
1688 ath11k_dbg(ab, ATH11K_DBG_BOOT, "waiting recovery start...\n");
1689
1690 time_left = wait_for_completion_timeout(&ab->recovery_start,
1691 ATH11K_RECOVER_START_TIMEOUT_HZ);
1692
1693 ath11k_hif_power_down(ab);
1694 ath11k_hif_power_up(ab);
1695
1696 ath11k_dbg(ab, ATH11K_DBG_BOOT, "reset started\n");
1697 }
1698
1699 static int ath11k_init_hw_params(struct ath11k_base *ab)
1700 {
1701 const struct ath11k_hw_params *hw_params = NULL;
1702 int i;
1703
1704 for (i = 0; i < ARRAY_SIZE(ath11k_hw_params); i++) {
1705 hw_params = &ath11k_hw_params[i];
1706
1707 if (hw_params->hw_rev == ab->hw_rev)
1708 break;
1709 }
1710
1711 if (i == ARRAY_SIZE(ath11k_hw_params)) {
1712 ath11k_err(ab, "Unsupported hardware version: 0x%x\n", ab->hw_rev);
1713 return -EINVAL;
1714 }
1715
1716 ab->hw_params = *hw_params;
1717
1718 ath11k_info(ab, "%s\n", ab->hw_params.name);
1719
1720 return 0;
1721 }
1722
1723 int ath11k_core_pre_init(struct ath11k_base *ab)
1724 {
1725 int ret;
1726
1727 ret = ath11k_init_hw_params(ab);
1728 if (ret) {
1729 ath11k_err(ab, "failed to get hw params: %d\n", ret);
1730 return ret;
1731 }
1732
1733 return 0;
1734 }
1735 EXPORT_SYMBOL(ath11k_core_pre_init);
1736
1737 int ath11k_core_init(struct ath11k_base *ab)
1738 {
1739 int ret;
1740
1741 ret = ath11k_core_soc_create(ab);
1742 if (ret) {
1743 ath11k_err(ab, "failed to create soc core: %d\n", ret);
1744 return ret;
1745 }
1746
1747 return 0;
1748 }
1749 EXPORT_SYMBOL(ath11k_core_init);
1750
1751 void ath11k_core_deinit(struct ath11k_base *ab)
1752 {
1753 mutex_lock(&ab->core_lock);
1754
1755 ath11k_core_pdev_destroy(ab);
1756 ath11k_core_stop(ab);
1757
1758 mutex_unlock(&ab->core_lock);
1759
1760 ath11k_hif_power_down(ab);
1761 ath11k_mac_destroy(ab);
1762 ath11k_core_soc_destroy(ab);
1763 }
1764 EXPORT_SYMBOL(ath11k_core_deinit);
1765
1766 void ath11k_core_free(struct ath11k_base *ab)
1767 {
1768 destroy_workqueue(ab->workqueue_aux);
1769 destroy_workqueue(ab->workqueue);
1770
1771 kfree(ab);
1772 }
1773 EXPORT_SYMBOL(ath11k_core_free);
1774
1775 struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size,
1776 enum ath11k_bus bus)
1777 {
1778 struct ath11k_base *ab;
1779
1780 ab = kzalloc(sizeof(*ab) + priv_size, GFP_KERNEL);
1781 if (!ab)
1782 return NULL;
1783
1784 init_completion(&ab->driver_recovery);
1785
1786 ab->workqueue = create_singlethread_workqueue("ath11k_wq");
1787 if (!ab->workqueue)
1788 goto err_sc_free;
1789
1790 ab->workqueue_aux = create_singlethread_workqueue("ath11k_aux_wq");
1791 if (!ab->workqueue_aux)
1792 goto err_free_wq;
1793
1794 mutex_init(&ab->core_lock);
1795 mutex_init(&ab->tbl_mtx_lock);
1796 spin_lock_init(&ab->base_lock);
1797 mutex_init(&ab->vdev_id_11d_lock);
1798 init_completion(&ab->reset_complete);
1799 init_completion(&ab->reconfigure_complete);
1800 init_completion(&ab->recovery_start);
1801
1802 INIT_LIST_HEAD(&ab->peers);
1803 init_waitqueue_head(&ab->peer_mapping_wq);
1804 init_waitqueue_head(&ab->wmi_ab.tx_credits_wq);
1805 init_waitqueue_head(&ab->qmi.cold_boot_waitq);
1806 INIT_WORK(&ab->restart_work, ath11k_core_restart);
1807 INIT_WORK(&ab->update_11d_work, ath11k_update_11d);
1808 INIT_WORK(&ab->reset_work, ath11k_core_reset);
1809 timer_setup(&ab->rx_replenish_retry, ath11k_ce_rx_replenish_retry, 0);
1810 init_completion(&ab->htc_suspend);
1811 init_completion(&ab->wow.wakeup_completed);
1812
1813 ab->dev = dev;
1814 ab->hif.bus = bus;
1815
1816 return ab;
1817
1818 err_free_wq:
1819 destroy_workqueue(ab->workqueue);
1820 err_sc_free:
1821 kfree(ab);
1822 return NULL;
1823 }
1824 EXPORT_SYMBOL(ath11k_core_alloc);
1825
1826 MODULE_DESCRIPTION("Core module for Qualcomm Atheros 802.11ax wireless LAN cards.");
1827 MODULE_LICENSE("Dual BSD/GPL");