diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index bfda297a53f20823b02ce66c15fdcd1e77f14ddb..08ba8d785f7518bbdaa829679e6635e0e957edeb 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -87,6 +87,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .num_peers = 512, .supports_suspend = false, .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), + .supports_regdb = false, .fix_l1ss = true, .credit_flow = false, .max_tx_ring = DP_TCL_NUM_RING_MAX, @@ -149,6 +150,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .num_peers = 512, .supports_suspend = false, .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), + .supports_regdb = false, .fix_l1ss = true, .credit_flow = false, .max_tx_ring = DP_TCL_NUM_RING_MAX, @@ -210,6 +212,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .num_peers = 512, .supports_suspend = true, .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), + .supports_regdb = true, .fix_l1ss = true, .credit_flow = true, .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, @@ -271,6 +274,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .num_peers = 128, .supports_suspend = false, .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074), + .supports_regdb = false, .fix_l1ss = true, .credit_flow = false, .max_tx_ring = DP_TCL_NUM_RING_MAX, @@ -332,6 +336,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .num_peers = 512, .supports_suspend = true, .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855), + .supports_regdb = true, .fix_l1ss = false, .credit_flow = true, .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, @@ -392,6 +397,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .num_peers = 512, .supports_suspend = true, .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855), + .supports_regdb = true, .fix_l1ss = false, .credit_flow = true, .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, @@ -760,10 +766,12 @@ static int ath11k_core_fetch_board_data_api_n(struct ath11k_base *ab, return ret; } -static int ath11k_core_fetch_board_data_api_1(struct ath11k_base *ab, - struct ath11k_board_data *bd) +int ath11k_core_fetch_board_data_api_1(struct ath11k_base *ab, + struct ath11k_board_data *bd, + const char *name) { - bd->fw = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_BOARD_FILE); + bd->fw = ath11k_core_firmware_request(ab, name); + if (IS_ERR(bd->fw)) return PTR_ERR(bd->fw); @@ -791,7 +799,7 @@ int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd) goto success; ab->bd_api = 1; - ret = ath11k_core_fetch_board_data_api_1(ab, bd); + ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_DEFAULT_BOARD_FILE); if (ret) { ath11k_err(ab, "failed to fetch board-2.bin or board.bin from %s\n", ab->hw_params.fw.dir); @@ -803,6 +811,18 @@ int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd) return 0; } +int ath11k_core_fetch_regdb(struct ath11k_base *ab, struct ath11k_board_data *bd) +{ + int ret; + + ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_REGDB_FILE_NAME); + if (ret) + ath11k_dbg(ab, ATH11K_DBG_BOOT, "failed to fetch %s from %s\n", + ATH11K_REGDB_FILE_NAME, ab->hw_params.fw.dir); + + return ret; +} + static void ath11k_core_stop(struct ath11k_base *ab) { if (!test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags)) diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 45aae41d917d469a21c39a9237829bfdee965c70..6d12995362e92675a8551ed18aaab6e4d58d790f 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -980,6 +980,10 @@ struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size, void ath11k_core_free(struct ath11k_base *ath11k); int ath11k_core_fetch_bdf(struct ath11k_base *ath11k, struct ath11k_board_data *bd); +int ath11k_core_fetch_regdb(struct ath11k_base *ab, struct ath11k_board_data *bd); +int ath11k_core_fetch_board_data_api_1(struct ath11k_base *ab, + struct ath11k_board_data *bd, + const char *name); void ath11k_core_free_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd); int ath11k_core_check_dt(struct ath11k_base *ath11k); diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index e4685c714579c5b40c0c8aeac9cf6fad551a0cbb..059b9f9bca95091d5b2cf8ebe01e72cb56ec89f2 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -77,6 +77,7 @@ #define ATH11K_DEFAULT_CAL_FILE "caldata.bin" #define ATH11K_AMSS_FILE "amss.bin" #define ATH11K_M3_FILE "m3.bin" +#define ATH11K_REGDB_FILE_NAME "regdb.bin" enum ath11k_hw_rate_cck { ATH11K_HW_RATE_CCK_LP_11M = 0, @@ -181,6 +182,7 @@ struct ath11k_hw_params { u32 num_peers; bool supports_suspend; u32 hal_desc_sz; + bool supports_regdb; bool fix_l1ss; bool credit_flow; u8 max_tx_ring; diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c index 3b9ba0e03a666f99639a06b80a7018ee01c31dd8..4c21d488bedab425498e1367d6fc553caef7431d 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c @@ -2161,7 +2161,8 @@ static int ath11k_qmi_load_file_target_mem(struct ath11k_base *ab, return ret; } -static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab) +static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab, + bool regdb) { struct device *dev = ab->dev; char filename[ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE]; @@ -2172,13 +2173,21 @@ static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab) const u8 *tmp; memset(&bd, 0, sizeof(bd)); - ret = ath11k_core_fetch_bdf(ab, &bd); - if (ret) { - ath11k_warn(ab, "qmi failed to fetch board file: %d\n", ret); - goto out; + + if (regdb) { + ret = ath11k_core_fetch_regdb(ab, &bd); + } else { + ret = ath11k_core_fetch_bdf(ab, &bd); + if (ret) + ath11k_warn(ab, "qmi failed to fetch board file: %d\n", ret); } - if (bd.len >= SELFMAG && memcmp(bd.data, ELFMAG, SELFMAG) == 0) + if (ret) + goto out; + + if (regdb) + bdf_type = ATH11K_QMI_BDF_TYPE_REGDB; + else if (bd.len >= SELFMAG && memcmp(bd.data, ELFMAG, SELFMAG) == 0) bdf_type = ATH11K_QMI_BDF_TYPE_ELF; else bdf_type = ATH11K_QMI_BDF_TYPE_BIN; @@ -2193,8 +2202,8 @@ static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab) goto out; } - /* QCA6390 does not support cal data, skip it */ - if (bdf_type == ATH11K_QMI_BDF_TYPE_ELF) + /* QCA6390/WCN6855 does not support cal data, skip it */ + if (bdf_type == ATH11K_QMI_BDF_TYPE_ELF || bdf_type == ATH11K_QMI_BDF_TYPE_REGDB) goto out; if (ab->qmi.target.eeprom_caldata) { @@ -2626,7 +2635,10 @@ static int ath11k_qmi_event_load_bdf(struct ath11k_qmi *qmi) return ret; } - ret = ath11k_qmi_load_bdf_qmi(ab); + if (ab->hw_params.supports_regdb) + ath11k_qmi_load_bdf_qmi(ab, true); + + ret = ath11k_qmi_load_bdf_qmi(ab, false); if (ret < 0) { ath11k_warn(ab, "failed to load board data file: %d\n", ret); return ret; diff --git a/drivers/net/wireless/ath/ath11k/qmi.h b/drivers/net/wireless/ath/ath11k/qmi.h index a6fb7d47ee8272b93e35f9f218a62c11c7119c7c..983b0b1480dc9ab1fc76e9159b111e4962bebe7c 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.h +++ b/drivers/net/wireless/ath/ath11k/qmi.h @@ -48,6 +48,7 @@ enum ath11k_qmi_file_type { enum ath11k_qmi_bdf_type { ATH11K_QMI_BDF_TYPE_BIN = 0, ATH11K_QMI_BDF_TYPE_ELF = 1, + ATH11K_QMI_BDF_TYPE_REGDB = 4, }; enum ath11k_qmi_event_type {