 db90c243a0
			
		
	
	db90c243a0
	
	
	
		
			
			This updates mac80211 to backports based on kernel 4.19-rc4. I plan to integrate all the patches which are in this tar into upstream backports soon. I used the backports generated from this code: https://github.com/hauke/backports/commits/wip2 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
		
			
				
	
	
		
			331 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			331 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| --- a/drivers/net/wireless/ath/ath9k/ahb.c
 | |
| +++ b/drivers/net/wireless/ath/ath9k/ahb.c
 | |
| @@ -20,7 +20,15 @@
 | |
|  #include <linux/platform_device.h>
 | |
|  #include <linux/module.h>
 | |
|  #include <linux/mod_devicetable.h>
 | |
| +#include <linux/of_device.h>
 | |
|  #include "ath9k.h"
 | |
| +#include <linux/ath9k_platform.h>
 | |
| +
 | |
| +#ifdef CONFIG_OF
 | |
| +#include <asm/mach-ath79/ath79.h>
 | |
| +#include <asm/mach-ath79/ar71xx_regs.h>
 | |
| +#include <linux/mtd/mtd.h>
 | |
| +#endif
 | |
|  
 | |
|  static const struct platform_device_id ath9k_platform_id_table[] = {
 | |
|  	{
 | |
| @@ -69,6 +77,235 @@ 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 of_get_wifi_cal(struct device_node *np, struct ath9k_platform_data *pdata)
 | |
| +{
 | |
| +#ifdef CONFIG_MTD
 | |
| +	struct device_node *mtd_np = NULL;
 | |
| +	size_t retlen;
 | |
| +	int size, ret;
 | |
| +	struct mtd_info *mtd;
 | |
| +	const char *part;
 | |
| +	const __be32 *list;
 | |
| +	phandle phandle;
 | |
| +
 | |
| +	list = of_get_property(np, "mtd-cal-data", &size);
 | |
| +	if (!list)
 | |
| +		return 0;
 | |
| +
 | |
| +	if (size != (2 * sizeof(*list)))
 | |
| +		return 1;
 | |
| +
 | |
| +	phandle = be32_to_cpup(list++);
 | |
| +	if (phandle)
 | |
| +		mtd_np = of_find_node_by_phandle(phandle);
 | |
| +
 | |
| +	if (!mtd_np)
 | |
| +		return 1;
 | |
| +
 | |
| +	part = of_get_property(mtd_np, "label", NULL);
 | |
| +	if (!part)
 | |
| +		part = mtd_np->name;
 | |
| +
 | |
| +	mtd = get_mtd_device_nm(part);
 | |
| +	if (IS_ERR(mtd))
 | |
| +		return 1;
 | |
| +
 | |
| +	ret = mtd_read(mtd, be32_to_cpup(list), sizeof(pdata->eeprom_data),
 | |
| +			&retlen, (u8*)pdata->eeprom_data);
 | |
| +	put_mtd_device(mtd);
 | |
| +
 | |
| +#endif
 | |
| +	return 0;
 | |
| +}
 | |
| +
 | |
| +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] },
 | |
| +	{},
 | |
| +};
 | |
| +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,disable-2ghz"))
 | |
| +		pdata->disable_2ghz = true;
 | |
| +
 | |
| +	if (of_property_read_bool(pdev->dev.of_node, "qca,disable-5ghz"))
 | |
| +		pdata->disable_5ghz = true;
 | |
| +
 | |
| +	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->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;
 | |
| +
 | |
| +	if (of_get_wifi_cal(pdev->dev.of_node, pdata))
 | |
| +		dev_err(&pdev->dev, "failed to load calibration data from mtd device\n");
 | |
| +
 | |
| +	return data->dev_id;
 | |
| +}
 | |
| +#endif
 | |
| +
 | |
|  static int ath_ahb_probe(struct platform_device *pdev)
 | |
|  {
 | |
|  	void __iomem *mem;
 | |
| @@ -80,6 +317,17 @@ static int ath_ahb_probe(struct platform
 | |
|  	int ret = 0;
 | |
|  	struct ath_hw *ah;
 | |
|  	char hw_name[64];
 | |
| +	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
 | |
|  
 | |
|  	if (!dev_get_platdata(&pdev->dev)) {
 | |
|  		dev_err(&pdev->dev, "no platform data specified\n");
 | |
| @@ -122,13 +370,16 @@ 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");
 | |
|  		goto err_free_hw;
 | |
|  	}
 | |
|  
 | |
| -	ret = ath9k_init_device(id->driver_data, sc, &ath_ahb_bus_ops);
 | |
| +	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;
 | |
| @@ -159,6 +410,9 @@ static int ath_ahb_remove(struct platfor
 | |
|  		free_irq(sc->irq, sc);
 | |
|  		ieee80211_free_hw(sc->hw);
 | |
|  	}
 | |
| +#ifdef CONFIG_OF
 | |
| +	pdev->dev.platform_data = NULL;
 | |
| +#endif
 | |
|  
 | |
|  	return 0;
 | |
|  }
 | |
| @@ -168,6 +422,9 @@ static struct platform_driver ath_ahb_dr
 | |
|  	.remove     = 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
 | |
| @@ -25,6 +25,7 @@
 | |
|  #include <linux/time.h>
 | |
|  #include <linux/hw_random.h>
 | |
|  #include <linux/gpio/driver.h>
 | |
| +#include <linux/reset.h>
 | |
|  
 | |
|  #include "common.h"
 | |
|  #include "debug.h"
 | |
| @@ -1023,6 +1024,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;
 |