From 12913c3c5658992985e13f4395dee86e5450154d Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Fri, 9 May 2025 15:20:08 -0700 Subject: [PATCH] mac80211: move OF stuff to ath9k_of_init It's the proper function to handle this stuff in. The original patch abused the fact that the ath9k driver in init called ath9k_init_platform to populate all the needed configuration. This is the wrong place to do so and it also goes away in 6.13. Move 553-ath9k_of_gpio_mask.patch contents to ath9k_of_init where they belong. Signed-off-by: Rosen Penev Link: https://github.com/openwrt/openwrt/pull/18764 Signed-off-by: Robert Marko --- .../mac80211/patches/ath9k/550-ath9k-of.patch | 155 ++++++++++ .../patches/ath9k/552-ath9k-ahb_of.patch | 276 ++---------------- .../ath9k/553-ath9k_of_gpio_mask.patch | 25 -- 3 files changed, 185 insertions(+), 271 deletions(-) create mode 100644 package/kernel/mac80211/patches/ath9k/550-ath9k-of.patch delete mode 100644 package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch diff --git a/package/kernel/mac80211/patches/ath9k/550-ath9k-of.patch b/package/kernel/mac80211/patches/ath9k/550-ath9k-of.patch new file mode 100644 index 00000000000..5cb70b40a70 --- /dev/null +++ b/package/kernel/mac80211/patches/ath9k/550-ath9k-of.patch @@ -0,0 +1,155 @@ +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -29,6 +29,11 @@ + + #include "ath9k.h" + ++#ifdef CONFIG_ATH79 ++#include ++#include ++#endif ++ + struct ath9k_eeprom_ctx { + struct completion complete; + struct ath_hw *ah; +@@ -243,6 +248,81 @@ static unsigned int ath9k_reg_rmw(void * + return val; + } + ++#ifdef CONFIG_ATH79 ++#define QCA955X_DDR_CTL_CONFIG 0x108 ++#define QCA955X_DDR_CTL_CONFIG_ACT_WMAC BIT(23) ++ ++static int ar913x_wmac_reset(void) ++{ ++ ath79_device_reset_set(AR913X_RESET_AMBA2WMAC); ++ mdelay(10); ++ ++ ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC); ++ mdelay(10); ++ ++ return 0; ++} ++ ++static int ar933x_wmac_reset(void) ++{ ++ int retries = 20; ++ ++ ath79_device_reset_set(AR933X_RESET_WMAC); ++ ath79_device_reset_clear(AR933X_RESET_WMAC); ++ ++ while (1) { ++ u32 bootstrap; ++ ++ bootstrap = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); ++ if ((bootstrap & AR933X_BOOTSTRAP_EEPBUSY) == 0) ++ return 0; ++ ++ if (retries-- == 0) ++ break; ++ ++ udelay(10000); ++ } ++ ++ pr_err("ar933x: WMAC reset timed out"); ++ return -ETIMEDOUT; ++} ++ ++static int qca955x_wmac_reset(void) ++{ ++ int i; ++ ++ /* Try to wait for WMAC DDR activity to stop */ ++ for (i = 0; i < 10; i++) { ++ if (!(__raw_readl(ath79_ddr_base + QCA955X_DDR_CTL_CONFIG) & ++ QCA955X_DDR_CTL_CONFIG_ACT_WMAC)) ++ break; ++ ++ udelay(10); ++ } ++ ++ ath79_device_reset_set(QCA955X_RESET_RTC); ++ udelay(10); ++ ath79_device_reset_clear(QCA955X_RESET_RTC); ++ udelay(10); ++ ++ return 0; ++} ++ ++ ++static int ar9330_get_soc_revision(void) ++{ ++ if (ath79_soc_rev == 1) ++ return ath79_soc_rev; ++ ++ return 0; ++} ++ ++static int ath79_get_soc_revision(void) ++{ ++ return ath79_soc_rev; ++} ++#endif ++ + /**************************/ + /* Initialization */ + /**************************/ +@@ -670,6 +750,8 @@ static int ath9k_of_init(struct ath_soft + struct ath_common *common = ath9k_hw_common(ah); + enum ath_bus_type bus_type = common->bus_ops->ath_bus_type; + char eeprom_name[100]; ++ u8 led_pin; ++ u32 mask; + int ret; + + if (!of_device_is_available(np)) +@@ -677,6 +759,49 @@ static int ath9k_of_init(struct ath_soft + + ath_dbg(common, CONFIG, "parsing configuration from OF node\n"); + ++ if (!of_property_read_u8(np, "qca,led-pin", &led_pin)) ++ ah->led_pin = led_pin; ++ ++ if (!of_property_read_u32(np, "qca,gpio-mask", &mask)) ++ ah->caps.gpio_mask = mask; ++ ++ if (of_property_read_bool(np, "qca,tx-gain-buffalo")) ++ ah->config.tx_gain_buffalo = true; ++ ++#ifdef CONFIG_ATH79 ++ if (ah->hw_version.devid == AR5416_AR9100_DEVID) { ++ ah->external_reset = ar913x_wmac_reset; ++ ah->external_reset(); ++ } else if (ah->hw_version.devid == AR9300_DEVID_AR9330) { ++ ah->get_mac_revision = ar9330_get_soc_revision; ++ u32 t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); ++ ah->is_clk_25mhz = !(t & AR933X_BOOTSTRAP_REF_CLK_40); ++ ah->external_reset = ar933x_wmac_reset; ++ ah->external_reset(); ++ } else if (ah->hw_version.devid == AR9300_DEVID_AR9340) { ++ ah->get_mac_revision = ath79_get_soc_revision; ++ u32 t = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); ++ ah->is_clk_25mhz = !(t & AR933X_BOOTSTRAP_REF_CLK_40); ++ } else if (ah->hw_version.devid == AR9300_DEVID_AR953X) { ++ ah->get_mac_revision = ath79_get_soc_revision; ++ /* ++ * QCA953x only supports 25MHz refclk. ++ * Some vendors have an invalid bootstrap option ++ * set, which would break the WMAC here. ++ */ ++ ah->is_clk_25mhz = true; ++ } else if (ah->hw_version.devid == AR9300_DEVID_QCA955X) { ++ u32 t = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP); ++ ah->is_clk_25mhz = !(t & QCA955X_BOOTSTRAP_REF_CLK_40); ++ ah->external_reset = qca955x_wmac_reset; ++ ah->external_reset(); ++ } else if (ah->hw_version.devid == AR9300_DEVID_QCA956X) { ++ ah->get_mac_revision = ath79_get_soc_revision; ++ u32 t = ath79_reset_rr(QCA956X_RESET_REG_BOOTSTRAP); ++ ah->is_clk_25mhz = !(t & QCA956X_BOOTSTRAP_REF_CLK_40); ++ } ++#endif ++ + if (of_property_read_bool(np, "qca,no-eeprom")) { + /* ath9k-eeprom--.bin */ + scnprintf(eeprom_name, sizeof(eeprom_name), diff --git a/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch b/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch index 6ec8824a1bc..cb92f30aae7 100644 --- a/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch +++ b/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch @@ -1,284 +1,68 @@ --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c -@@ -20,7 +20,15 @@ +@@ -20,6 +20,7 @@ #include #include #include +#include #include "ath9k.h" -+#include -+ -+#ifdef CONFIG_OF -+#include -+#include -+#include -+#endif static const struct platform_device_id ath9k_platform_id_table[] = { - { -@@ -69,6 +77,192 @@ static const struct ath_bus_ops ath_ahb_ +@@ -69,21 +70,28 @@ static const struct ath_bus_ops ath_ahb_ .eeprom_read = ath_ahb_eeprom_read, }; -+#ifdef CONFIG_OF -+ -+#define QCA955X_DDR_CTL_CONFIG 0x108 -+#define QCA955X_DDR_CTL_CONFIG_ACT_WMAC BIT(23) -+ -+static int ar913x_wmac_reset(void) -+{ -+ ath79_device_reset_set(AR913X_RESET_AMBA2WMAC); -+ mdelay(10); -+ -+ ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC); -+ mdelay(10); -+ -+ return 0; -+} -+ -+static int ar933x_wmac_reset(void) -+{ -+ int retries = 20; -+ -+ ath79_device_reset_set(AR933X_RESET_WMAC); -+ ath79_device_reset_clear(AR933X_RESET_WMAC); -+ -+ while (1) { -+ u32 bootstrap; -+ -+ bootstrap = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); -+ if ((bootstrap & AR933X_BOOTSTRAP_EEPBUSY) == 0) -+ return 0; -+ -+ if (retries-- == 0) -+ break; -+ -+ udelay(10000); -+ } -+ -+ pr_err("ar933x: WMAC reset timed out"); -+ return -ETIMEDOUT; -+} -+ -+static int qca955x_wmac_reset(void) -+{ -+ int i; -+ -+ /* Try to wait for WMAC DDR activity to stop */ -+ for (i = 0; i < 10; i++) { -+ if (!(__raw_readl(ath79_ddr_base + QCA955X_DDR_CTL_CONFIG) & -+ QCA955X_DDR_CTL_CONFIG_ACT_WMAC)) -+ break; -+ -+ udelay(10); -+ } -+ -+ ath79_device_reset_set(QCA955X_RESET_RTC); -+ udelay(10); -+ ath79_device_reset_clear(QCA955X_RESET_RTC); -+ udelay(10); -+ -+ return 0; -+} -+ -+enum { -+ AR913X_WMAC = 0, -+ AR933X_WMAC, -+ AR934X_WMAC, -+ QCA953X_WMAC, -+ QCA955X_WMAC, -+ QCA956X_WMAC, -+}; -+ -+static int ar9330_get_soc_revision(void) -+{ -+ if (ath79_soc_rev == 1) -+ return ath79_soc_rev; -+ -+ return 0; -+} -+ -+static int ath79_get_soc_revision(void) -+{ -+ return ath79_soc_rev; -+} -+ -+static const struct of_ath_ahb_data { -+ u16 dev_id; -+ u32 bootstrap_reg; -+ u32 bootstrap_ref; -+ -+ int (*soc_revision)(void); -+ int (*wmac_reset)(void); -+} of_ath_ahb_data[] = { -+ [AR913X_WMAC] = { -+ .dev_id = AR5416_AR9100_DEVID, -+ .wmac_reset = ar913x_wmac_reset, -+ -+ }, -+ [AR933X_WMAC] = { -+ .dev_id = AR9300_DEVID_AR9330, -+ .bootstrap_reg = AR933X_RESET_REG_BOOTSTRAP, -+ .bootstrap_ref = AR933X_BOOTSTRAP_REF_CLK_40, -+ .soc_revision = ar9330_get_soc_revision, -+ .wmac_reset = ar933x_wmac_reset, -+ }, -+ [AR934X_WMAC] = { -+ .dev_id = AR9300_DEVID_AR9340, -+ .bootstrap_reg = AR934X_RESET_REG_BOOTSTRAP, -+ .bootstrap_ref = AR934X_BOOTSTRAP_REF_CLK_40, -+ .soc_revision = ath79_get_soc_revision, -+ }, -+ [QCA953X_WMAC] = { -+ .dev_id = AR9300_DEVID_AR953X, -+ .bootstrap_reg = QCA953X_RESET_REG_BOOTSTRAP, -+ .bootstrap_ref = QCA953X_BOOTSTRAP_REF_CLK_40, -+ .soc_revision = ath79_get_soc_revision, -+ }, -+ [QCA955X_WMAC] = { -+ .dev_id = AR9300_DEVID_QCA955X, -+ .bootstrap_reg = QCA955X_RESET_REG_BOOTSTRAP, -+ .bootstrap_ref = QCA955X_BOOTSTRAP_REF_CLK_40, -+ .wmac_reset = qca955x_wmac_reset, -+ }, -+ [QCA956X_WMAC] = { -+ .dev_id = AR9300_DEVID_QCA956X, -+ .bootstrap_reg = QCA956X_RESET_REG_BOOTSTRAP, -+ .bootstrap_ref = QCA956X_BOOTSTRAP_REF_CLK_40, -+ .soc_revision = ath79_get_soc_revision, -+ }, -+}; -+ +const struct of_device_id of_ath_ahb_match[] = { -+ { .compatible = "qca,ar9130-wmac", .data = &of_ath_ahb_data[AR913X_WMAC] }, -+ { .compatible = "qca,ar9330-wmac", .data = &of_ath_ahb_data[AR933X_WMAC] }, -+ { .compatible = "qca,ar9340-wmac", .data = &of_ath_ahb_data[AR934X_WMAC] }, -+ { .compatible = "qca,qca9530-wmac", .data = &of_ath_ahb_data[QCA953X_WMAC] }, -+ { .compatible = "qca,qca9550-wmac", .data = &of_ath_ahb_data[QCA955X_WMAC] }, -+ { .compatible = "qca,qca9560-wmac", .data = &of_ath_ahb_data[QCA956X_WMAC] }, ++ { .compatible = "qca,ar9130-wmac", .data = (void *)AR5416_AR9100_DEVID }, ++ { .compatible = "qca,ar9330-wmac", .data = (void *)AR9300_DEVID_AR9330 }, ++ { .compatible = "qca,ar9340-wmac", .data = (void *)AR9300_DEVID_AR9340 }, ++ { .compatible = "qca,qca9530-wmac", .data = (void *)AR9300_DEVID_AR953X }, ++ { .compatible = "qca,qca9550-wmac", .data = (void *)AR9300_DEVID_QCA955X }, ++ { .compatible = "qca,qca9560-wmac", .data = (void *)AR9300_DEVID_QCA956X }, + {}, +}; +MODULE_DEVICE_TABLE(of, of_ath_ahb_match); -+ -+static int of_ath_ahb_probe(struct platform_device *pdev) -+{ -+ struct ath9k_platform_data *pdata; -+ const struct of_device_id *match; -+ const struct of_ath_ahb_data *data; -+ u8 led_pin; -+ -+ match = of_match_device(of_ath_ahb_match, &pdev->dev); -+ data = (const struct of_ath_ahb_data *)match->data; -+ -+ pdata = dev_get_platdata(&pdev->dev); -+ -+ if (!of_property_read_u8(pdev->dev.of_node, "qca,led-pin", &led_pin)) -+ pdata->led_pin = led_pin; -+ else -+ pdata->led_pin = -1; -+ -+ if (of_property_read_bool(pdev->dev.of_node, "qca,tx-gain-buffalo")) -+ pdata->tx_gain_buffalo = true; -+ -+ if (data->wmac_reset) { -+ data->wmac_reset(); -+ pdata->external_reset = data->wmac_reset; -+ } -+ -+ if (data->dev_id == AR9300_DEVID_AR953X) { -+ /* -+ * QCA953x only supports 25MHz refclk. -+ * Some vendors have an invalid bootstrap option -+ * set, which would break the WMAC here. -+ */ -+ pdata->is_clk_25mhz = true; -+ } else if (data->bootstrap_reg && data->bootstrap_ref) { -+ u32 t = ath79_reset_rr(data->bootstrap_reg); -+ if (t & data->bootstrap_ref) -+ pdata->is_clk_25mhz = false; -+ else -+ pdata->is_clk_25mhz = true; -+ } -+ -+ pdata->get_mac_revision = data->soc_revision; -+ -+ return data->dev_id; -+} -+#endif + static int ath_ahb_probe(struct platform_device *pdev) { - void __iomem *mem; -@@ -79,6 +273,17 @@ static int ath_ahb_probe(struct platform - int ret = 0; +- void __iomem *mem; +- struct ath_softc *sc; ++ const struct of_device_id *match; + struct ieee80211_hw *hw; +- const struct platform_device_id *id = platform_get_device_id(pdev); +- int irq; +- int ret = 0; ++ struct ath_softc *sc; ++ void __iomem *mem; struct ath_hw *ah; char hw_name[64]; +- +- if (!dev_get_platdata(&pdev->dev)) { +- dev_err(&pdev->dev, "no platform data specified\n"); +- return -EINVAL; +- } + u16 dev_id; -+ -+ if (id) -+ dev_id = id->driver_data; -+ -+#ifdef CONFIG_OF -+ if (pdev->dev.of_node) -+ pdev->dev.platform_data = devm_kzalloc(&pdev->dev, -+ sizeof(struct ath9k_platform_data), -+ GFP_KERNEL); -+#endif ++ int irq; ++ int ret; - if (!dev_get_platdata(&pdev->dev)) { - dev_err(&pdev->dev, "no platform data specified\n"); -@@ -111,17 +316,23 @@ static int ath_ahb_probe(struct platform - sc->mem = mem; - sc->irq = irq; - -+#ifdef CONFIG_OF -+ dev_id = of_ath_ahb_probe(pdev); -+#endif - ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc); - if (ret) { - dev_err(&pdev->dev, "request_irq failed\n"); + mem = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(mem)) { +@@ -117,7 +125,9 @@ static int ath_ahb_probe(struct platform goto err_free_hw; } - ret = ath9k_init_device(id->driver_data, sc, &ath_ahb_bus_ops); ++ match = of_match_device(of_ath_ahb_match, &pdev->dev); ++ dev_id = (uintptr_t)match->data; + ret = ath9k_init_device(dev_id, sc, &ath_ahb_bus_ops); if (ret) { dev_err(&pdev->dev, "failed to initialize device\n"); goto err_irq; - } -+#ifdef CONFIG_OF -+ pdev->dev.platform_data = NULL; -+#endif - - ah = sc->sc_ah; - ath9k_hw_name(ah, hw_name, sizeof(hw_name)); -@@ -155,6 +366,9 @@ static struct platform_driver ath_ahb_dr +@@ -155,6 +165,7 @@ static struct platform_driver ath_ahb_dr .remove_new = ath_ahb_remove, .driver = { .name = "ath9k", -+#ifdef CONFIG_OF + .of_match_table = of_ath_ahb_match, -+#endif }, .id_table = ath9k_platform_id_table, }; ---- a/drivers/net/wireless/ath/ath9k/ath9k.h -+++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - - #include "common.h" - #include "debug.h" -@@ -1006,6 +1007,9 @@ struct ath_softc { - struct ath_hw *sc_ah; - void __iomem *mem; - int irq; -+#ifdef CONFIG_OF -+ struct reset_control *reset; -+#endif - spinlock_t sc_serial_rw; - spinlock_t sc_pm_lock; - spinlock_t sc_pcu_lock; diff --git a/package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch b/package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch deleted file mode 100644 index 752a4980a40..00000000000 --- a/package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- a/drivers/net/wireless/ath/ath9k/init.c -+++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -696,6 +696,12 @@ static int ath9k_of_init(struct ath_soft - return 0; - } - -+static void ath9k_of_gpio_mask(struct ath_softc *sc) -+{ -+ of_property_read_u32(sc->dev->of_node, "qca,gpio-mask", -+ &sc->sc_ah->caps.gpio_mask); -+} -+ - static int ath9k_init_softc(u16 devid, struct ath_softc *sc, - const struct ath_bus_ops *bus_ops) - { -@@ -804,6 +810,9 @@ static int ath9k_init_softc(u16 devid, s - if (ret) - goto err_hw; - -+ /* GPIO mask quirk */ -+ ath9k_of_gpio_mask(sc); -+ - ret = ath9k_init_queues(sc); - if (ret) - goto err_queues; -- 2.47.2