diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c index 07bb83710b1f..14ee696960c7 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.c +++ b/drivers/net/wireless/ath/ath12k/ahb.c @@ -704,7 +704,7 @@ static int ath12k_ahb_map_service_to_pipe(struct ath12k_base *ab, u16 service_id return 0; } -static const struct ath12k_hif_ops ath12k_ahb_hif_ops = { +const struct ath12k_hif_ops ath12k_ahb_hif_ops = { .start = ath12k_ahb_start, .stop = ath12k_ahb_stop, .read32 = ath12k_ahb_read32, @@ -715,6 +715,7 @@ static const struct ath12k_hif_ops ath12k_ahb_hif_ops = { .power_up = ath12k_ahb_power_up, .power_down = ath12k_ahb_power_down, }; +EXPORT_SYMBOL(ath12k_ahb_hif_ops); static irqreturn_t ath12k_userpd_irq_handler(int irq, void *data) { @@ -1038,7 +1039,6 @@ static int ath12k_ahb_probe(struct platform_device *pdev) ab_ahb = ath12k_ab_to_ahb(ab); ab_ahb->ab = ab; - ab->hif.ops = &ath12k_ahb_hif_ops; ab->pdev = pdev; platform_set_drvdata(pdev, ab); diff --git a/drivers/net/wireless/ath/ath12k/ahb.h b/drivers/net/wireless/ath/ath12k/ahb.h index a153db6cf1d3..037347ccd21b 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.h +++ b/drivers/net/wireless/ath/ath12k/ahb.h @@ -30,6 +30,24 @@ #define ATH12K_USERPD_ID_MASK GENMASK(10, 8) #define ATH12K_USERPD_FW_NAME_LEN 35 +enum ath12k_ahb_userpd_id { + ATH12K_AHB_USERPD_ID_0 = 1, + ATH12K_AHB_USERPD_ID_1, + ATH12K_AHB_USERPD_ID_2, +}; + +struct ath12k_ahb_userpd_map { + phys_addr_t io_start; + const char *node_name; + u32 upd_id; +}; + +struct ath12k_ahb_desc { + enum ath12k_hw_rev hw_rev; + bool auth_enabled; + const struct ath12k_hif_ops *ops; +}; + enum ath12k_ahb_smp2p_msg_id { ATH12K_AHB_POWER_SAVE_ENTER = 1, ATH12K_AHB_POWER_SAVE_EXIT, @@ -43,6 +61,7 @@ enum ath12k_ahb_userpd_irq { }; struct ath12k_base; +extern const struct ath12k_hif_ops ath12k_ahb_hif_ops; struct ath12k_ahb_device_family_ops { int (*probe)(struct platform_device *pdev); diff --git a/drivers/net/wireless/ath/ath12k/hw.h b/drivers/net/wireless/ath/ath12k/hw.h index 49cfd5dfc70a..3ed38f8f2b48 100644 --- a/drivers/net/wireless/ath/ath12k/hw.h +++ b/drivers/net/wireless/ath/ath12k/hw.h @@ -100,7 +100,6 @@ struct ieee80211_rx_status; #define ATH12K_REGDB_FILE_NAME "regdb.bin" #define ATH12K_PCIE_MAX_PAYLOAD_SIZE 128 -#define ATH12K_IPQ5332_USERPD_ID 1 enum ath12k_hw_rate_cck { ATH12K_HW_RATE_CCK_LP_11M = 0, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/ahb.c b/drivers/net/wireless/ath/ath12k/wifi7/ahb.c index 6a8b8b2a56f9..98a6606ffd76 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/ahb.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/ahb.c @@ -15,44 +15,100 @@ #include "dp.h" #include "core.h" +/* + * Node name to UserPD ID mapping + * + * The io_start field is used for additional validation when the reg + * property is present in the device tree. If io_start is 0, only + * node_name matching is performed. + * + * For platforms where not all WiFi nodes have a 'reg' property, set + * io_start to 0 for those entries. The driver will match purely by + * node name in such cases. + */ +static const struct ath12k_ahb_userpd_map ath12k_wifi7_ahb_userpd_map[] = { + { .io_start = 0x0c000000, .node_name = "wifi", .upd_id = ATH12K_AHB_USERPD_ID_0 }, +}; + +static const struct ath12k_ahb_desc ath12k_wifi7_ahb_desc[] = { + [ATH12K_HW_IPQ5332_HW10] = { + .hw_rev = ATH12K_HW_IPQ5332_HW10, + .auth_enabled = true, + .ops = &ath12k_ahb_hif_ops, + }, + [ATH12K_HW_IPQ5424_HW10] = { + .hw_rev = ATH12K_HW_IPQ5424_HW10, + .auth_enabled = false, + .ops = &ath12k_ahb_hif_ops, + }, +}; + static const struct of_device_id ath12k_wifi7_ahb_of_match[] = { { .compatible = "qcom,ipq5332-wifi", - .data = (void *)ATH12K_HW_IPQ5332_HW10, + .data = (void *)&ath12k_wifi7_ahb_desc[ATH12K_HW_IPQ5332_HW10], }, { .compatible = "qcom,ipq5424-wifi", - .data = (void *)ATH12K_HW_IPQ5424_HW10, + .data = (void *)&ath12k_wifi7_ahb_desc[ATH12K_HW_IPQ5424_HW10], }, { } }; MODULE_DEVICE_TABLE(of, ath12k_wifi7_ahb_of_match); +/* + * ath12k_wifi7_ahb_get_userpd_id - Resolve UserPD ID from DT properties + * @ab: ath12k base structure + * + * Returns: UserPD ID (1-based) on success, 0 on failure + * + * Resolution logic: + * 1. If reg property exist in DT, get userpd_id from io_start + * 2. If reg property is absent, get userpd_id from DT node name + * 3. Return 0 if no match found (probe will fail) + */ +static u32 ath12k_wifi7_ahb_get_userpd_id(struct ath12k_base *ab) +{ + const struct ath12k_ahb_userpd_map *map; + struct resource *res; + size_t i; + + res = platform_get_resource(ab->pdev, IORESOURCE_MEM, 0); + + for (i = 0; i < ARRAY_SIZE(ath12k_wifi7_ahb_userpd_map); i++) { + map = &ath12k_wifi7_ahb_userpd_map[i]; + + if (res) { + if (map->io_start && map->io_start == res->start) + return map->upd_id; + } else if (map->node_name && + of_node_name_eq(ab->dev->of_node, map->node_name)) { + return map->upd_id; + } + } + + return 0; +} + static int ath12k_wifi7_ahb_probe(struct platform_device *pdev) { + const struct ath12k_ahb_desc *desc; struct ath12k_ahb *ab_ahb; - enum ath12k_hw_rev hw_rev; struct ath12k_base *ab; int ret; ab = platform_get_drvdata(pdev); ab_ahb = ath12k_ab_to_ahb(ab); - - hw_rev = (enum ath12k_hw_rev)(kernel_ulong_t)of_device_get_match_data(&pdev->dev); - switch (hw_rev) { - case ATH12K_HW_IPQ5332_HW10: - ab_ahb->userpd_id = ATH12K_IPQ5332_USERPD_ID; - ab_ahb->scm_auth_enabled = true; - break; - case ATH12K_HW_IPQ5424_HW10: - ab_ahb->userpd_id = ATH12K_IPQ5332_USERPD_ID; - ab_ahb->scm_auth_enabled = false; - break; - default: + desc = of_device_get_match_data(&pdev->dev); + if (!desc) return -EOPNOTSUPP; - } ab->target_mem_mode = ATH12K_QMI_MEMORY_MODE_DEFAULT; - ab->hw_rev = hw_rev; + ab->hw_rev = desc->hw_rev; + ab->hif.ops = desc->ops; + ab_ahb->scm_auth_enabled = desc->auth_enabled; + ab_ahb->userpd_id = ath12k_wifi7_ahb_get_userpd_id(ab); + if (!ab_ahb->userpd_id) + return -EOPNOTSUPP; ret = ath12k_wifi7_hw_init(ab); if (ret) {