Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: pull request: bluetooth 2013-06-23
From: Marcel Holtmann @ 2013-06-25 20:49 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Gustavo Padovan, linville, linux-wireless, linux-bluetooth,
	linux-kernel, Rafael J. Wysocki
In-Reply-To: <20130625201217.GA13879@amd.pavel.ucw.cz>

Hi Pavel,

>> Jaganath Kanakkassery (1):
>>      Bluetooth: Fix invalid length check in l2cap_information_rsp()
> 
> Could we add the "3.10 vs. thinkpad x60" patch that fixes regression?
> It is from Johan Hedberg…

that one went into net-next tree. It is scheduled for 3.11 right now.

After 3.10 is out, maybe it can go into -stable, but otherwise I think it is bit late now. Unless someone wants to cherry-pick it.

Regards

Marcel


^ permalink raw reply

* [PATCH 5/5] wlcore: add device tree support to the sdio module
From: Luciano Coelho @ 2013-06-25 20:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, tony
In-Reply-To: <1372192406-29430-1-git-send-email-coelho@ti.com>

If platform data is not available, try to get the required information
from the device tree.  Register an OF match table and parse the
appropriate device tree nodes.

Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 drivers/net/wireless/ti/wlcore/sdio.c |   75 ++++++++++++++++++++++++++++++---
 1 file changed, 69 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c
index 4c7e8ac..1ddda84 100644
--- a/drivers/net/wireless/ti/wlcore/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -30,7 +30,7 @@
 #include <linux/mmc/sdio_ids.h>
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
-#include <linux/gpio.h>
+#include <linux/of_irq.h>
 #include <linux/wl12xx.h>
 #include <linux/pm_runtime.h>
 #include <linux/printk.h>
@@ -214,6 +214,49 @@ static struct wl1271_if_operations sdio_ops = {
 	.set_block_size = wl1271_sdio_set_block_size,
 };
 
+static struct wl12xx_platform_data *wlcore_get_pdata_from_of(struct device *dev)
+{
+	struct wl12xx_platform_data *pdata;
+	struct device_node *np = dev->of_node;
+
+	if (!np) {
+		np = of_find_matching_node(NULL, dev->driver->of_match_table);
+		if (!np) {
+			dev_notice(dev, "device tree node not available\n");
+			pdata = ERR_PTR(-ENODEV);
+			goto out;
+		}
+	}
+
+	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		dev_err(dev, "can't allocate platform data\n");
+		pdata = ERR_PTR(-ENODEV);
+		goto out;
+	}
+
+	pdata->irq = irq_of_parse_and_map(np, 0);
+	if (pdata->irq < 0) {
+		dev_err(dev, "can't get interrupt gpio from the device tree\n");
+		goto out_free;
+	}
+
+	/* TODO: make sure we have this when needed (ie. for WL6 and WL7) */
+	of_property_read_u32(np, "refclock", &pdata->board_ref_clock);
+
+	/* TODO: make sure we have this when needed (ie. for WL7) */
+	of_property_read_u32(np, "tcxoclock", &pdata->board_tcxo_clock);
+
+	goto out;
+
+out_free:
+	kfree(pdata);
+	pdata = ERR_PTR(-ENODEV);
+
+out:
+	return pdata;
+}
+
 static int wl1271_probe(struct sdio_func *func,
 				  const struct sdio_device_id *id)
 {
@@ -248,11 +291,22 @@ static int wl1271_probe(struct sdio_func *func,
 	/* Use block mode for transferring over one block size of data */
 	func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
 
+	/* The pdata allocated here is freed when the device is freed,
+	 * so we don't need an additional out label to free it in case
+	 * of error further on.
+	 */
+
+	/* Try to get legacy platform data from the board file */
 	pdev_data->pdata = wl12xx_get_platform_data();
 	if (IS_ERR(pdev_data->pdata)) {
-		ret = PTR_ERR(pdev_data->pdata);
-		dev_err(glue->dev, "missing wlan platform data: %d\n", ret);
-		goto out_free_glue;
+		dev_info(&func->dev,
+			 "legacy platform data not found, trying device tree\n");
+
+		pdev_data->pdata = wlcore_get_pdata_from_of(&func->dev);
+		if (IS_ERR(pdev_data->pdata)) {
+			dev_err(&func->dev, "can't get platform data\n");
+			goto out_free_glue;
+		}
 	}
 
 	/* if sdio can keep power while host is suspended, enable wow */
@@ -386,16 +440,25 @@ static const struct dev_pm_ops wl1271_sdio_pm_ops = {
 };
 #endif
 
+static const struct of_device_id wlcore_sdio_of_match_table[] = {
+	{ .compatible = "ti,wilink6" },
+	{ .compatible = "ti,wilink7" },
+	{ .compatible = "ti,wilink8" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, wlcore_sdio_of_match_table);
+
 static struct sdio_driver wl1271_sdio_driver = {
 	.name		= "wl1271_sdio",
 	.id_table	= wl1271_devices,
 	.probe		= wl1271_probe,
 	.remove		= wl1271_remove,
-#ifdef CONFIG_PM
 	.drv = {
+#ifdef CONFIG_PM
 		.pm = &wl1271_sdio_pm_ops,
-	},
 #endif
+		.of_match_table = of_match_ptr(wlcore_sdio_of_match_table),
+	},
 };
 
 static int __init wl1271_init(void)
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 4/5] wlcore: always use one-shot IRQ
From: Luciano Coelho @ 2013-06-25 20:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, tony
In-Reply-To: <1372192406-29430-1-git-send-email-coelho@ti.com>

Since we are now using threaded IRQs without the primary handler, we
need to set IRQF_ONESHOT, otherwise our request will fail.

Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 drivers/net/wireless/ti/wlcore/main.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index d306cd5..bc1cff3 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -5927,7 +5927,8 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
 
 	wl->irq = platform_get_irq(pdev, 0);
 	wl->if_ops = pdev_data->if_ops;
-	wl->irq_flags = pdata->irq_flags;
+	/* Since we don't use the primary handler, we must set ONESHOT */
+	wl->irq_flags = pdata->irq_flags | IRQF_ONESHOT;
 
 	ret = request_threaded_irq(wl->irq, NULL, wlcore_irq,
 				   wl->irq_flags, pdev->name, wl);
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 3/5] wlcore: remove pwr_in_suspend from platform data
From: Luciano Coelho @ 2013-06-25 20:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, tony
In-Reply-To: <1372192406-29430-1-git-send-email-coelho@ti.com>

The pwr_in_suspend flag depends on the MMC settings which can be
retrieved from the SDIO subsystem, so it doesn't need to be part of
the platform data structure.  Move it to the platform device data that
is passed from SDIO to wlcore.

Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 drivers/net/wireless/ti/wlcore/main.c     |    2 +-
 drivers/net/wireless/ti/wlcore/sdio.c     |    2 +-
 drivers/net/wireless/ti/wlcore/wlcore_i.h |    1 +
 include/linux/wl12xx.h                    |    1 -
 4 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index e7294b8..d306cd5 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -5941,7 +5941,7 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
 	if (!ret) {
 		wl->irq_wake_enabled = true;
 		device_init_wakeup(wl->dev, 1);
-		if (pdata->pwr_in_suspend)
+		if (pdev_data->pwr_in_suspend)
 			wl->hw->wiphy->wowlan = &wlcore_wowlan_support;
 	}
 #endif
diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c
index 29ef249..4c7e8ac 100644
--- a/drivers/net/wireless/ti/wlcore/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -260,7 +260,7 @@ static int wl1271_probe(struct sdio_func *func,
 	dev_dbg(glue->dev, "sdio PM caps = 0x%x\n", mmcflags);
 
 	if (mmcflags & MMC_PM_KEEP_POWER)
-		pdev_data->pdata->pwr_in_suspend = true;
+		pdev_data->pwr_in_suspend = true;
 
 	sdio_set_drvdata(func, glue);
 
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index e5e1464..f2c4227 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -209,6 +209,7 @@ struct wl1271_if_operations {
 struct wlcore_platdev_data {
 	struct wl12xx_platform_data *pdata;
 	struct wl1271_if_operations *if_ops;
+	bool pwr_in_suspend;
 };
 
 #define MAX_NUM_KEYS 14
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
index 04e3096..1e4ed6e 100644
--- a/include/linux/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -60,7 +60,6 @@ struct wl12xx_platform_data {
 	unsigned long irq_flags;
 	int board_ref_clock;
 	int board_tcxo_clock;
-	bool pwr_in_suspend;
 };
 
 #ifdef CONFIG_WILINK_PLATFORM_DATA
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 1/5] wl1251: split wl251 platform data to a separate structure
From: Luciano Coelho @ 2013-06-25 20:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, tony
In-Reply-To: <1372192406-29430-1-git-send-email-coelho@ti.com>

Move the wl1251 part of the wl12xx platform data structure into a new
structure specifically for wl1251.  Change the platform data built-in
block and board files accordingly.

Cc: Tony Lindgren <tony@atomide.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 arch/arm/mach-omap2/board-omap3pandora.c       |    4 +--
 arch/arm/mach-omap2/board-rx51-peripherals.c   |    2 +-
 drivers/net/wireless/ti/wilink_platform_data.c |   37 ++++++++++++++++++++----
 drivers/net/wireless/ti/wl1251/sdio.c          |   12 ++++----
 drivers/net/wireless/ti/wl1251/spi.c           |    2 +-
 include/linux/wl12xx.h                         |   22 +++++++++++++-
 6 files changed, 62 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 28133d5..bf06d95 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -540,7 +540,7 @@ static struct spi_board_info omap3pandora_spi_board_info[] __initdata = {
 
 static void __init pandora_wl1251_init(void)
 {
-	struct wl12xx_platform_data pandora_wl1251_pdata;
+	struct wl1251_platform_data pandora_wl1251_pdata;
 	int ret;
 
 	memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata));
@@ -554,7 +554,7 @@ static void __init pandora_wl1251_init(void)
 		goto fail_irq;
 
 	pandora_wl1251_pdata.use_eeprom = true;
-	ret = wl12xx_set_platform_data(&pandora_wl1251_pdata);
+	ret = wl1251_set_platform_data(&pandora_wl1251_pdata);
 	if (ret < 0)
 		goto fail_irq;
 
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 18ca61e..733f3f2 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -80,7 +80,7 @@ enum {
 	RX51_SPI_MIPID,		/* LCD panel */
 };
 
-static struct wl12xx_platform_data wl1251_pdata;
+static struct wl1251_platform_data wl1251_pdata;
 static struct tsc2005_platform_data tsc2005_pdata;
 
 #if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE)
diff --git a/drivers/net/wireless/ti/wilink_platform_data.c b/drivers/net/wireless/ti/wilink_platform_data.c
index 998e958..a92bd3e 100644
--- a/drivers/net/wireless/ti/wilink_platform_data.c
+++ b/drivers/net/wireless/ti/wilink_platform_data.c
@@ -23,17 +23,17 @@
 #include <linux/err.h>
 #include <linux/wl12xx.h>
 
-static struct wl12xx_platform_data *platform_data;
+static struct wl12xx_platform_data *wl12xx_platform_data;
 
 int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
 {
-	if (platform_data)
+	if (wl12xx_platform_data)
 		return -EBUSY;
 	if (!data)
 		return -EINVAL;
 
-	platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
-	if (!platform_data)
+	wl12xx_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
+	if (!wl12xx_platform_data)
 		return -ENOMEM;
 
 	return 0;
@@ -41,9 +41,34 @@ int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
 
 struct wl12xx_platform_data *wl12xx_get_platform_data(void)
 {
-	if (!platform_data)
+	if (!wl12xx_platform_data)
 		return ERR_PTR(-ENODEV);
 
-	return platform_data;
+	return wl12xx_platform_data;
 }
 EXPORT_SYMBOL(wl12xx_get_platform_data);
+
+static struct wl1251_platform_data *wl1251_platform_data;
+
+int __init wl1251_set_platform_data(const struct wl1251_platform_data *data)
+{
+	if (wl1251_platform_data)
+		return -EBUSY;
+	if (!data)
+		return -EINVAL;
+
+	wl1251_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
+	if (!wl1251_platform_data)
+		return -ENOMEM;
+
+	return 0;
+}
+
+struct wl1251_platform_data *wl1251_get_platform_data(void)
+{
+	if (!wl1251_platform_data)
+		return ERR_PTR(-ENODEV);
+
+	return wl1251_platform_data;
+}
+EXPORT_SYMBOL(wl1251_get_platform_data);
diff --git a/drivers/net/wireless/ti/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c
index e2b3d9c..b75a37a 100644
--- a/drivers/net/wireless/ti/wl1251/sdio.c
+++ b/drivers/net/wireless/ti/wl1251/sdio.c
@@ -227,7 +227,7 @@ static int wl1251_sdio_probe(struct sdio_func *func,
 	struct wl1251 *wl;
 	struct ieee80211_hw *hw;
 	struct wl1251_sdio *wl_sdio;
-	const struct wl12xx_platform_data *wl12xx_board_data;
+	const struct wl1251_platform_data *wl1251_board_data;
 
 	hw = wl1251_alloc_hw();
 	if (IS_ERR(hw))
@@ -254,11 +254,11 @@ static int wl1251_sdio_probe(struct sdio_func *func,
 	wl->if_priv = wl_sdio;
 	wl->if_ops = &wl1251_sdio_ops;
 
-	wl12xx_board_data = wl12xx_get_platform_data();
-	if (!IS_ERR(wl12xx_board_data)) {
-		wl->set_power = wl12xx_board_data->set_power;
-		wl->irq = wl12xx_board_data->irq;
-		wl->use_eeprom = wl12xx_board_data->use_eeprom;
+	wl1251_board_data = wl1251_get_platform_data();
+	if (!IS_ERR(wl1251_board_data)) {
+		wl->set_power = wl1251_board_data->set_power;
+		wl->irq = wl1251_board_data->irq;
+		wl->use_eeprom = wl1251_board_data->use_eeprom;
 	}
 
 	if (wl->irq) {
diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c
index c7dc6fe..6bbbfe6 100644
--- a/drivers/net/wireless/ti/wl1251/spi.c
+++ b/drivers/net/wireless/ti/wl1251/spi.c
@@ -238,7 +238,7 @@ static const struct wl1251_if_operations wl1251_spi_ops = {
 
 static int wl1251_spi_probe(struct spi_device *spi)
 {
-	struct wl12xx_platform_data *pdata;
+	struct wl1251_platform_data *pdata;
 	struct ieee80211_hw *hw;
 	struct wl1251 *wl;
 	int ret;
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
index a54fe82..b516b4f 100644
--- a/include/linux/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -48,11 +48,15 @@ enum {
 	WL12XX_TCXOCLOCK_33_6	= 7, /* 33.6 MHz */
 };
 
-struct wl12xx_platform_data {
+struct wl1251_platform_data {
 	void (*set_power)(bool enable);
 	/* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */
 	int irq;
 	bool use_eeprom;
+};
+
+struct wl12xx_platform_data {
+	int irq;
 	int board_ref_clock;
 	int board_tcxo_clock;
 	unsigned long platform_quirks;
@@ -68,6 +72,10 @@ int wl12xx_set_platform_data(const struct wl12xx_platform_data *data);
 
 struct wl12xx_platform_data *wl12xx_get_platform_data(void);
 
+int wl1251_set_platform_data(const struct wl1251_platform_data *data);
+
+struct wl1251_platform_data *wl1251_get_platform_data(void);
+
 #else
 
 static inline
@@ -82,6 +90,18 @@ struct wl12xx_platform_data *wl12xx_get_platform_data(void)
 	return ERR_PTR(-ENODATA);
 }
 
+static inline
+int wl1251_set_platform_data(const struct wl1251_platform_data *data)
+{
+	return -ENOSYS;
+}
+
+static inline
+struct wl1251_platform_data *wl1251_get_platform_data(void)
+{
+	return ERR_PTR(-ENODATA);
+}
+
 #endif
 
 #endif
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 2/5] wlcore: use irq_flags in pdata instead of hiding it behing a quirk
From: Luciano Coelho @ 2013-06-25 20:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, tony
In-Reply-To: <1372192406-29430-1-git-send-email-coelho@ti.com>

The platform_quirk element in the platform data was used to change the
way the IRQ is triggered.  When set, the EDGE_IRQ quirk would change
the irqflags used and treat edge trigger differently from the rest.

Instead of hiding this irq flag setting behind the quirk, export the
whole irq_flags element and let the board file define what to use.
This will be more meaningful than driver-specific quirks when we
switch to DT.

Cc: Tony Lindgren <tony@atomide.com>
Cc: Sekhar Nori <nsekhar@ti.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 arch/arm/mach-davinci/board-da850-evm.c      |    2 +-
 arch/arm/mach-omap2/board-4430sdp.c          |    1 +
 arch/arm/mach-omap2/board-omap3evm.c         |    1 +
 arch/arm/mach-omap2/board-omap4panda.c       |    1 +
 arch/arm/mach-omap2/board-zoom-peripherals.c |    1 +
 drivers/net/wireless/ti/wlcore/debugfs.c     |    2 +-
 drivers/net/wireless/ti/wlcore/main.c        |   13 +++----------
 drivers/net/wireless/ti/wlcore/wlcore.h      |    5 ++---
 include/linux/wl12xx.h                       |    5 +----
 9 files changed, 12 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 8a24b6c..d2a2a98 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -1377,8 +1377,8 @@ static const short da850_wl12xx_pins[] __initconst = {
 
 static struct wl12xx_platform_data da850_wl12xx_wlan_data __initdata = {
 	.irq			= -1,
+	.irq_flags		= IRQF_TRIGGER_RISING,
 	.board_ref_clock	= WL12XX_REFCLOCK_38,
-	.platform_quirks	= WL12XX_PLATFORM_QUIRK_EDGE_IRQ,
 };
 
 static __init int da850_wl12xx_init(void)
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 56a9a4f..c2334aa 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -693,6 +693,7 @@ static void __init omap4_sdp4430_wifi_mux_init(void)
 }
 
 static struct wl12xx_platform_data omap4_sdp4430_wlan_data __initdata = {
+	.irq_flags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
 	.board_ref_clock = WL12XX_REFCLOCK_26,
 	.board_tcxo_clock = WL12XX_TCXOCLOCK_26,
 };
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index f76d0de..a0c0adf 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -458,6 +458,7 @@ static struct platform_device omap3evm_wlan_regulator = {
 };
 
 struct wl12xx_platform_data omap3evm_wlan_data __initdata = {
+	.irq_flags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
 	.board_ref_clock = WL12XX_REFCLOCK_38, /* 38.4 MHz */
 };
 #endif
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 1e2c75e..ba00862 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -230,6 +230,7 @@ static struct platform_device omap_vwlan_device = {
 };
 
 static struct wl12xx_platform_data omap_panda_wlan_data  __initdata = {
+	.irq_flags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
 	.board_ref_clock = WL12XX_REFCLOCK_38, /* 38.4 MHz */
 };
 
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index a90375d..ced012c 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -244,6 +244,7 @@ static struct platform_device *zoom_devices[] __initdata = {
 };
 
 static struct wl12xx_platform_data omap_zoom_wlan_data __initdata = {
+	.irq_flags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
 	.board_ref_clock = WL12XX_REFCLOCK_26, /* 26 MHz */
 };
 
diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c
index c3e1f79..5eff663 100644
--- a/drivers/net/wireless/ti/wlcore/debugfs.c
+++ b/drivers/net/wireless/ti/wlcore/debugfs.c
@@ -486,7 +486,7 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
 	DRIVER_STATE_PRINT_HEX(irq);
 	/* TODO: ref_clock and tcxo_clock were moved to wl12xx priv */
 	DRIVER_STATE_PRINT_HEX(hw_pg_ver);
-	DRIVER_STATE_PRINT_HEX(platform_quirks);
+	DRIVER_STATE_PRINT_HEX(irq_flags);
 	DRIVER_STATE_PRINT_HEX(chip.id);
 	DRIVER_STATE_PRINT_STR(chip.fw_ver_str);
 	DRIVER_STATE_PRINT_STR(chip.phy_fw_ver_str);
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index b8db55c..e7294b8 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -516,7 +516,7 @@ static int wlcore_irq_locked(struct wl1271 *wl)
 	 * In case edge triggered interrupt must be used, we cannot iterate
 	 * more than once without introducing race conditions with the hardirq.
 	 */
-	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
+	if (wl->irq_flags & IRQF_TRIGGER_RISING)
 		loopcount = 1;
 
 	wl1271_debug(DEBUG_IRQ, "IRQ work");
@@ -5765,7 +5765,6 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size,
 	wl->ap_ps_map = 0;
 	wl->ap_fw_ps_map = 0;
 	wl->quirks = 0;
-	wl->platform_quirks = 0;
 	wl->system_hlid = WL12XX_SYSTEM_HLID;
 	wl->active_sta_count = 0;
 	wl->active_link_count = 0;
@@ -5901,7 +5900,6 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
 	struct platform_device *pdev = wl->pdev;
 	struct wlcore_platdev_data *pdev_data = pdev->dev.platform_data;
 	struct wl12xx_platform_data *pdata = pdev_data->pdata;
-	unsigned long irqflags;
 	int ret;
 
 	if (fw) {
@@ -5928,16 +5926,11 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
 	wlcore_adjust_conf(wl);
 
 	wl->irq = platform_get_irq(pdev, 0);
-	wl->platform_quirks = pdata->platform_quirks;
 	wl->if_ops = pdev_data->if_ops;
-
-	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
-		irqflags = IRQF_TRIGGER_RISING;
-	else
-		irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
+	wl->irq_flags = pdata->irq_flags;
 
 	ret = request_threaded_irq(wl->irq, NULL, wlcore_irq,
-				   irqflags, pdev->name, wl);
+				   wl->irq_flags, pdev->name, wl);
 	if (ret < 0) {
 		wl1271_error("request_irq() failed: %d", ret);
 		goto out_free_nvs;
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index 0034979..8306bde 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -185,6 +185,8 @@ struct wl1271 {
 
 	int irq;
 
+	int irq_flags;
+
 	spinlock_t wl_lock;
 
 	enum wlcore_state state;
@@ -384,9 +386,6 @@ struct wl1271 {
 	/* Quirks of specific hardware revisions */
 	unsigned int quirks;
 
-	/* Platform limitations */
-	unsigned int platform_quirks;
-
 	/* number of currently active RX BA sessions */
 	int ba_rx_session_count;
 
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
index b516b4f..04e3096 100644
--- a/include/linux/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -57,15 +57,12 @@ struct wl1251_platform_data {
 
 struct wl12xx_platform_data {
 	int irq;
+	unsigned long irq_flags;
 	int board_ref_clock;
 	int board_tcxo_clock;
-	unsigned long platform_quirks;
 	bool pwr_in_suspend;
 };
 
-/* Platform does not support level trigger interrupts */
-#define WL12XX_PLATFORM_QUIRK_EDGE_IRQ	BIT(0)
-
 #ifdef CONFIG_WILINK_PLATFORM_DATA
 
 int wl12xx_set_platform_data(const struct wl12xx_platform_data *data);
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 0/5] wilink: add device tree support
From: Luciano Coelho @ 2013-06-25 20:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, tony

Hi,

This patch series add device tree support to the wlcore_sdio driver,
which is used by WiLink6, WiLink7 and WiLink8.

The first patches do some clean-up to make the data needed in the
wilink device tree node smaller.  The last patch implements the actual
device tree node parsing in wlcore_sdio.

The DTS file changes will be sent separately, since they need to go
via different trees.

--
Luca.

Luciano Coelho (5):
  wl1251: split wl251 platform data to a separate structure
  wlcore: use irq_flags in pdata instead of hiding it behing a quirk
  wlcore: remove pwr_in_suspend from platform data
  wlcore: always use one-shot IRQ
  wlcore: add device tree support to the sdio module

 arch/arm/mach-davinci/board-da850-evm.c        |    2 +-
 arch/arm/mach-omap2/board-4430sdp.c            |    1 +
 arch/arm/mach-omap2/board-omap3evm.c           |    1 +
 arch/arm/mach-omap2/board-omap3pandora.c       |    4 +-
 arch/arm/mach-omap2/board-omap4panda.c         |    1 +
 arch/arm/mach-omap2/board-rx51-peripherals.c   |    2 +-
 arch/arm/mach-omap2/board-zoom-peripherals.c   |    1 +
 drivers/net/wireless/ti/wilink_platform_data.c |   37 ++++++++++--
 drivers/net/wireless/ti/wl1251/sdio.c          |   12 ++--
 drivers/net/wireless/ti/wl1251/spi.c           |    2 +-
 drivers/net/wireless/ti/wlcore/debugfs.c       |    2 +-
 drivers/net/wireless/ti/wlcore/main.c          |   16 ++---
 drivers/net/wireless/ti/wlcore/sdio.c          |   77 +++++++++++++++++++++---
 drivers/net/wireless/ti/wlcore/wlcore.h        |    5 +-
 drivers/net/wireless/ti/wlcore/wlcore_i.h      |    1 +
 include/linux/wl12xx.h                         |   28 +++++++--
 16 files changed, 147 insertions(+), 45 deletions(-)

-- 
1.7.10.4


^ permalink raw reply

* Re: pull request: bluetooth 2013-06-23
From: Pavel Machek @ 2013-06-25 20:12 UTC (permalink / raw)
  To: Gustavo Padovan, linville, linux-wireless, linux-bluetooth,
	linux-kernel
  Cc: Rafael J. Wysocki
In-Reply-To: <20130623021351.GA2327@joana>

Hi!

> Jaganath Kanakkassery (1):
>       Bluetooth: Fix invalid length check in l2cap_information_rsp()

Could we add the "3.10 vs. thinkpad x60" patch that fixes regression?
It is from Johan Hedberg...
									Pavel

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply

* Re: regression after, " ath9k_htc: Add support for mesh interfaces"
From: Thomas Pedersen @ 2013-06-25 20:05 UTC (permalink / raw)
  To: Oleksij Rempel
  Cc: ath9k-devel@lists.ath9k.org, linux-wireless@vger.kernel.org,
	Javier Cardona, Johannes Berg
In-Reply-To: <51C93538.4050304@rempel-privat.de>

On Mon, Jun 24, 2013 at 11:14 PM, Oleksij Rempel <linux@rempel-privat.de> wrote:
> Am 25.06.2013 02:54, schrieb Thomas Pedersen:
>
>> On Fri, Jun 21, 2013 at 9:56 PM, Oleksij Rempel <linux@rempel-privat.de>
>> wrote:
>>>
>>> Hi Javier,
>>>
>>> i warning after patch "ath9k_htc: Add support for mesh interfaces".
>>> I get this warning only on pc with CONFIG_MAC80211_MESH not set. Probably
>>> you missed config check some where.
>>
>>
>> Where do you hit the warning?
>>
>
> on adapter init.
> see attachment.

That warning is triggered by wiphy_verify_combinations():

                        if (WARN_ON((wiphy->interface_modes & types) != types))
                                return -EINVAL;

But before that, the mesh iftype bit is cleared in ieee80211_register_hw():

#ifndef CONFIG_MAC80211_MESH
        /* mesh depends on Kconfig, but drivers should set it if they want */
        local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT);
#endif

It seems the intention was to avoid an #ifdef CONFIG_MAC80211_MESH in
every driver, but then mac80211 also has to clear the MESH_POINT bit
for each ieee80211_iface_limit? I don't really see a cleaner way of
resolving this.

Johannes?

--
Thomas

^ permalink raw reply

* Re: [RFC][PATCH] b43: replace B43_BCMA_EXTRA with modparam allhwsupport
From: Rafał Miłecki @ 2013-06-25 19:51 UTC (permalink / raw)
  To: Jonas Gorski; +Cc: linux-wireless, John W. Linville, b43-dev
In-Reply-To: <CAOiHx=mHVhg93pRyq7Qg1H9iTnScGtCUeOoxBxpeHuH6pW2XYQ@mail.gmail.com>

2013/6/25 Jonas Gorski <jogo@openwrt.org>:
> On Tue, Jun 25, 2013 at 5:34 PM, Rafał Miłecki <zajec5@gmail.com> wrote:
>> This allows enabling support for extra hardware with just a module
>> param, without kernel/module recompilation.
>>
>> Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
>> ---
>>  drivers/net/wireless/b43/Kconfig |    6 ------
>>  drivers/net/wireless/b43/main.c  |   16 ++++++++++++++--
>>  2 files changed, 14 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
>> index 3f21e0b..51ff0b1 100644
>> --- a/drivers/net/wireless/b43/Kconfig
>> +++ b/drivers/net/wireless/b43/Kconfig
>> @@ -31,12 +31,6 @@ config B43_BCMA
>>         depends on B43 && (BCMA = y || BCMA = B43)
>>         default y
>>
>> -config B43_BCMA_EXTRA
>> -       bool "Hardware support that overlaps with the brcmsmac driver"
>> -       depends on B43_BCMA
>> -       default n if BRCMSMAC
>> -       default y
>> -
>>  config B43_SSB
>>         bool
>>         depends on B43 && (SSB = y || SSB = B43)
>> diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
>> index a95b77a..583993c 100644
>> --- a/drivers/net/wireless/b43/main.c
>> +++ b/drivers/net/wireless/b43/main.c
>> @@ -113,13 +113,19 @@ static int b43_modparam_pio = 0;
>>  module_param_named(pio, b43_modparam_pio, int, 0644);
>>  MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
>>
>> +#ifdef CONFIG_BRCMSMAC
>
> This is only defined if BRCMSMAC is built-in, but not if it is built
> as a module; then it's CONFIG_BRCMSMAC_MODULE, which is probably not
> what you want. To easily catch both, use IS_ENABLED(CONFIG_BRCMSMAC).
>
>> +static int modparam_allhwsupport;
>> +#else
>> +static int modparam_allhwsupport = 1;
>> +#endif
>
> And since IS_ENABLED returns 0 or 1 you should be able to reduce it to one line:
>
> static int modparam_allhwsupport = !IS_ENABLED(CONFIG_BRCMSMAC);

I love learning new tricks all the time :)

-- 
Rafał

^ permalink raw reply

* [PATCH] cfg80211/mac80211: fix doc compilation warnings
From: Michael Opdenacker @ 2013-06-25 19:48 UTC (permalink / raw)
  To: johannes, davem, linux-wireless, linux-kernel; +Cc: Michael Opdenacker

This patch fixes countless "No description found for parameter"
warnings generating documentation (running "make htmldocs"),
because the comments do not match the actual prototypes in the code.

This issue didn't exist in 3.9. It may we worth fixing in 3.10
(if it's not too late).

Signed-off-by: Michael Opdenacker <michael.opdenacker@free-electrons.com>
---
 include/net/cfg80211.h | 1 +
 include/net/mac80211.h | 4 ++--
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 26b5b69..3949642 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -4153,6 +4153,7 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
  * cfg80211_crit_proto_stopped() - indicate critical protocol stopped by driver.
  *
  * @wdev: the wireless device for which critical protocol is stopped.
+ * @gfp: the type of memory to allocate (see kmalloc).
  *
  * This function can be called by the driver to indicate it has reverted
  * operation back to normal. One reason could be that the duration given
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 885898a..79f5fa7 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1235,7 +1235,7 @@ enum ieee80211_sta_rx_bandwidth {
  * struct ieee80211_sta_rates - station rate selection table
  *
  * @rcu_head: RCU head used for freeing the table on update
- * @rates: transmit rates/flags to be used by default.
+ * @rate: transmit rates/flags to be used by default.
  *	Overriding entries per-packet is possible by using cb tx control.
  */
 struct ieee80211_sta_rates {
@@ -1276,7 +1276,7 @@ struct ieee80211_sta_rates {
  *	notifications and capabilities. The value is only valid after
  *	the station moves to associated state.
  * @smps_mode: current SMPS mode (off, static or dynamic)
- * @tx_rates: rate control selection table
+ * @rates: station rate selection table
  */
 struct ieee80211_sta {
 	u32 supp_rates[IEEE80211_NUM_BANDS];
-- 
1.8.1.2


^ permalink raw reply related

* Re: [PATCH] Documentation: dt: bindings: TI WiLink modules
From: Luciano Coelho @ 2013-06-25 19:37 UTC (permalink / raw)
  To: grant.likely, linux-doc, linux-kernel, linux-wireless,
	rob.herring, devicetree-discuss
  Cc: tony, linux-omap, linux-arm-kernel
In-Reply-To: <1372149330-24335-1-git-send-email-coelho@ti.com>

(oh crap, now *really* fixed the ARM mailing list address)

On Tue, 2013-06-25 at 11:35 +0300, Luciano Coelho wrote:
> Add device tree bindings documentation for the TI WiLink modules.
> Currently only the WLAN part of the WiLink6, WiLink7 and WiLink8
> modules is supported.
> 
> Signed-off-by: Luciano Coelho <coelho@ti.com>
> ---
> 
> I created a new directory under net to contain wireless bindings documentation.
> 
> The actual implementation in the driver will follow separately.
> 
>  .../devicetree/bindings/net/wireless/ti-wilink.txt |   46 ++++++++++++++++++++
>  1 file changed, 46 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/wireless/ti-wilink.txt
> 
> diff --git a/Documentation/devicetree/bindings/net/wireless/ti-wilink.txt b/Documentation/devicetree/bindings/net/wireless/ti-wilink.txt
> new file mode 100644
> index 0000000..d8e8bfbb
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/wireless/ti-wilink.txt
> @@ -0,0 +1,46 @@
> +TI WiLink Wireless Modules Device Tree Bindings
> +===============================================
> +
> +The WiLink modules provide wireless connectivity, such as WLAN,
> +Bluetooth, FM and NFC.
> +
> +There are several different modules available, which can be grouped by
> +their generation: WiLink6, WiLink7 and WiLink8.  WiLink4 is not
> +currently supported with device tree.
> +
> +Currently, only the WLAN portion of the modules is supported with
> +device tree.
> +
> +Required properties:
> +--------------------
> +
> +- compatible: should be "ti,wilink6", "ti,wilink7" or "ti,wilink8"
> +- interrupt-parent: the interrupt controller
> +- interrupts: out-of-band WLAN interrupt
> +	See the interrupt controller's bindings documentation for
> +	detailed definition.
> +
> +Optional properties:
> +--------------------
> +
> +- refclock: the internal WLAN reference clock frequency (required for
> +  WiLink6 and WiLink7; not used for WiLink8).  Must be one of the
> +  following:
> +	0 = 19.2 MHz
> +	1 = 26.0 MHz
> +	2 = 38.4 MHz
> +	3 = 52.0 MHz
> +	4 = 38.4 MHz, XTAL
> +	5 = 26.0 MHz, XTAL
> +
> +- tcxoclock: the internal WLAN TCXO clock frequency (required for
> +  WiLink7 not used for WiLink6 and WiLink8).  Must be one of the
> +  following:
> +	0 = 19.200 MHz
> +	1 = 26.000 MHz
> +	2 = 38.400 MHz
> +	3 = 52.000 MHz
> +	4 = 16.368 MHz
> +	5 = 32.736 MHz
> +	6 = 16.800 MHz
> +	7 = 33.600 MHz

If this is okay for everyone, can I push this via my tree (which goes to
linux-wireless->net->linus)? I think it makes more sense to send the
documentation together with the patch that actually implements the DT
node parsing in the driver.

--
Luca.



^ permalink raw reply

* Re: [PATCH] Documentation: dt: bindings: TI WiLink modules
From: Luciano Coelho @ 2013-06-25 19:35 UTC (permalink / raw)
  To: grant.likely, linux-doc, linux-kernel, linux-wireless,
	rob.herring, devicetree-discuss
  Cc: tony, tony, linux-omap, linux-arm-kernel
In-Reply-To: <1372149330-24335-1-git-send-email-coelho@ti.com>

(fixed the ARM mailing list address)

On Tue, 2013-06-25 at 11:35 +0300, Luciano Coelho wrote:
> Add device tree bindings documentation for the TI WiLink modules.
> Currently only the WLAN part of the WiLink6, WiLink7 and WiLink8
> modules is supported.
> 
> Signed-off-by: Luciano Coelho <coelho@ti.com>
> ---
> 
> I created a new directory under net to contain wireless bindings documentation.
> 
> The actual implementation in the driver will follow separately.
> 
>  .../devicetree/bindings/net/wireless/ti-wilink.txt |   46 ++++++++++++++++++++
>  1 file changed, 46 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/wireless/ti-wilink.txt
> 
> diff --git a/Documentation/devicetree/bindings/net/wireless/ti-wilink.txt b/Documentation/devicetree/bindings/net/wireless/ti-wilink.txt
> new file mode 100644
> index 0000000..d8e8bfbb
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/wireless/ti-wilink.txt
> @@ -0,0 +1,46 @@
> +TI WiLink Wireless Modules Device Tree Bindings
> +===============================================
> +
> +The WiLink modules provide wireless connectivity, such as WLAN,
> +Bluetooth, FM and NFC.
> +
> +There are several different modules available, which can be grouped by
> +their generation: WiLink6, WiLink7 and WiLink8.  WiLink4 is not
> +currently supported with device tree.
> +
> +Currently, only the WLAN portion of the modules is supported with
> +device tree.
> +
> +Required properties:
> +--------------------
> +
> +- compatible: should be "ti,wilink6", "ti,wilink7" or "ti,wilink8"
> +- interrupt-parent: the interrupt controller
> +- interrupts: out-of-band WLAN interrupt
> +	See the interrupt controller's bindings documentation for
> +	detailed definition.
> +
> +Optional properties:
> +--------------------
> +
> +- refclock: the internal WLAN reference clock frequency (required for
> +  WiLink6 and WiLink7; not used for WiLink8).  Must be one of the
> +  following:
> +	0 = 19.2 MHz
> +	1 = 26.0 MHz
> +	2 = 38.4 MHz
> +	3 = 52.0 MHz
> +	4 = 38.4 MHz, XTAL
> +	5 = 26.0 MHz, XTAL
> +
> +- tcxoclock: the internal WLAN TCXO clock frequency (required for
> +  WiLink7 not used for WiLink6 and WiLink8).  Must be one of the
> +  following:
> +	0 = 19.200 MHz
> +	1 = 26.000 MHz
> +	2 = 38.400 MHz
> +	3 = 52.000 MHz
> +	4 = 16.368 MHz
> +	5 = 32.736 MHz
> +	6 = 16.800 MHz
> +	7 = 33.600 MHz

If this is okay for everyone, can I push this via my tree (which goes to
linux-wireless->net->linus)? I think it makes more sense to send the
documentation together with the patch that actually implements the DT
node parsing in the driver.

--
Luca.


^ permalink raw reply

* Re: [rt2x00-users] [PATCH 0/3] rt2x00: rt2800: prepare for three-chain device support
From: Stanislaw Gruszka @ 2013-06-25 19:18 UTC (permalink / raw)
  To: Gabor Juhos; +Cc: John Linville, linux-wireless, users
In-Reply-To: <51C8994E.4040809@openwrt.org>

On Mon, Jun 24, 2013 at 09:09:02PM +0200, Gabor Juhos wrote:
> I'm testing these patches on a Linksys AE3000 device which also uses the RT3573
> chip. I have an almost complete patch-set which allows me to use the device in
> STA and in AP mode, however I still have to resolve a few problems.

Cool, waiting for the post ... :-)

Stanislaw

^ permalink raw reply

* [PATCH] wireless: vlan priority handling in WMM
From: cedric.voncken @ 2013-06-25 15:31 UTC (permalink / raw)
  To: linux-wireless; +Cc: Cedric Voncken

From: Cedric Voncken <cedric.voncken@acksys.fr>

If the VLAN priority is set in skb->vlan_tci use it to determine the WMM priority.

Signed-off-by: Cedric Voncken <cedric.voncken@acksys.fr>
---
 net/wireless/util.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/net/wireless/util.c b/net/wireless/util.c
index 74458b7..6f57ae7 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -685,6 +685,7 @@ EXPORT_SYMBOL(ieee80211_amsdu_to_8023s);
 unsigned int cfg80211_classify8021d(struct sk_buff *skb)
 {
 	unsigned int dscp;
+	unsigned char vlan_priority;
 
 	/* skb->priority values from 256->263 are magic values to
 	 * directly indicate a specific 802.1d priority.  This is used
@@ -694,6 +695,10 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb)
 	if (skb->priority >= 256 && skb->priority <= 263)
 		return skb->priority - 256;
 
+	vlan_priority = (skb->vlan_tci >> 13) & 0x07;
+		if (vlan_priority > 0)
+			return vlan_priority;
+
 	switch (skb->protocol) {
 	case htons(ETH_P_IP):
 		dscp = ipv4_get_dsfield(ip_hdr(skb)) & 0xfc;
-- 
1.7.2.5


^ permalink raw reply related

* Re: [RFC][PATCH] b43: replace B43_BCMA_EXTRA with modparam allhwsupport
From: Jonas Gorski @ 2013-06-25 18:01 UTC (permalink / raw)
  To: Rafał Miłecki; +Cc: linux-wireless, John W. Linville, b43-dev
In-Reply-To: <1372174495-14471-1-git-send-email-zajec5@gmail.com>

On Tue, Jun 25, 2013 at 5:34 PM, Rafał Miłecki <zajec5@gmail.com> wrote:
> This allows enabling support for extra hardware with just a module
> param, without kernel/module recompilation.
>
> Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
> ---
>  drivers/net/wireless/b43/Kconfig |    6 ------
>  drivers/net/wireless/b43/main.c  |   16 ++++++++++++++--
>  2 files changed, 14 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
> index 3f21e0b..51ff0b1 100644
> --- a/drivers/net/wireless/b43/Kconfig
> +++ b/drivers/net/wireless/b43/Kconfig
> @@ -31,12 +31,6 @@ config B43_BCMA
>         depends on B43 && (BCMA = y || BCMA = B43)
>         default y
>
> -config B43_BCMA_EXTRA
> -       bool "Hardware support that overlaps with the brcmsmac driver"
> -       depends on B43_BCMA
> -       default n if BRCMSMAC
> -       default y
> -
>  config B43_SSB
>         bool
>         depends on B43 && (SSB = y || SSB = B43)
> diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
> index a95b77a..583993c 100644
> --- a/drivers/net/wireless/b43/main.c
> +++ b/drivers/net/wireless/b43/main.c
> @@ -113,13 +113,19 @@ static int b43_modparam_pio = 0;
>  module_param_named(pio, b43_modparam_pio, int, 0644);
>  MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
>
> +#ifdef CONFIG_BRCMSMAC

This is only defined if BRCMSMAC is built-in, but not if it is built
as a module; then it's CONFIG_BRCMSMAC_MODULE, which is probably not
what you want. To easily catch both, use IS_ENABLED(CONFIG_BRCMSMAC).

> +static int modparam_allhwsupport;
> +#else
> +static int modparam_allhwsupport = 1;
> +#endif

And since IS_ENABLED returns 0 or 1 you should be able to reduce it to one line:

static int modparam_allhwsupport = !IS_ENABLED(CONFIG_BRCMSMAC);


Jonas

^ permalink raw reply

* pull request: wireless 2013-06-25
From: John W. Linville @ 2013-06-25 17:45 UTC (permalink / raw)
  To: dave; +Cc: linux-wireless, netdev, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 4001 bytes --]

Dave,

A few more late-breaking fixes hoping for 3.10...

Regarding the Bluetooth fix, Gustavo says:

"A important fix to 3.10, this patch fixes an issues that was preventing
the l2cap info response command to be handled properly."

Also for that Bluetooth fix, Johan adds:

"Once the code gives up parsing this PDU it also gives up essential
parts of the L2CAP connection creation process, i.e. without this
patch the stack will fail to establish connections properly."

Moving onto ath9k, Felix Fietkau fixes an RCU locking issue in
the transmit path.  As for ath9k_htc, Sujith Manoharan fixes some
authentication timeouts by ensuring that a chip reset is done when
IDLE is turned off.

I think these are all micro-fixes that shouldn't cause any trouble.
Please let me know if there are problems!

John

---

The following changes since commit f57da7a65b386dd4535daa4f7a3773a025fbb022:

  qlcnic: Do not sleep while holding spinlock (2013-06-24 00:28:28 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git for-davem

for you to fetch changes up to 9d5c34f568a8d80cb69cc89ebb426ceb1d1f4737:

  Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless into for-davem (2013-06-25 13:24:12 -0400)

----------------------------------------------------------------

Felix Fietkau (1):
      ath9k: fix an RCU issue in calling ieee80211_get_tx_rates

Jaganath Kanakkassery (1):
      Bluetooth: Fix invalid length check in l2cap_information_rsp()

John W. Linville (2):
      Merge branch 'master' of git://git.kernel.org/.../bluetooth/bluetooth
      Merge branch 'master' of git://git.kernel.org/.../linville/wireless into for-davem

Sujith Manoharan (1):
      ath9k_htc: Handle IDLE state transition properly

 drivers/net/wireless/ath/ath9k/htc_drv_main.c | 2 +-
 drivers/net/wireless/ath/ath9k/xmit.c         | 6 +++++-
 net/bluetooth/l2cap_core.c                    | 2 +-
 3 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 0743a47..62f1b76 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1174,7 +1174,7 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
 		mutex_lock(&priv->htc_pm_lock);
 
 		priv->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE);
-		if (priv->ps_idle)
+		if (!priv->ps_idle)
 			chip_reset = true;
 
 		mutex_unlock(&priv->htc_pm_lock);
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 1c9b1ba..83ab6be 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1570,6 +1570,8 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
 	    txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH)
 		return;
 
+	rcu_read_lock();
+
 	ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list);
 	last_ac = list_entry(txq->axq_acq.prev, struct ath_atx_ac, list);
 
@@ -1608,8 +1610,10 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
 
 		if (ac == last_ac ||
 		    txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH)
-			return;
+			break;
 	}
+
+	rcu_read_unlock();
 }
 
 /***********/
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 4be6a26..68843a2 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -4333,7 +4333,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn,
 	struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
 	u16 type, result;
 
-	if (cmd_len != sizeof(*rsp))
+	if (cmd_len < sizeof(*rsp))
 		return -EPROTO;
 
 	type   = __le16_to_cpu(rsp->type);
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply related

* Re: [RFC][PATCH] b43: replace B43_BCMA_EXTRA with modparam allhwsupport
From: John W. Linville @ 2013-06-25 17:23 UTC (permalink / raw)
  To: Rafał Miłecki; +Cc: linux-wireless, b43-dev
In-Reply-To: <1372174495-14471-1-git-send-email-zajec5@gmail.com>

Seems OK to me...

On Tue, Jun 25, 2013 at 05:34:55PM +0200, Rafał Miłecki wrote:
> This allows enabling support for extra hardware with just a module
> param, without kernel/module recompilation.
> 
> Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
> ---
>  drivers/net/wireless/b43/Kconfig |    6 ------
>  drivers/net/wireless/b43/main.c  |   16 ++++++++++++++--
>  2 files changed, 14 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
> index 3f21e0b..51ff0b1 100644
> --- a/drivers/net/wireless/b43/Kconfig
> +++ b/drivers/net/wireless/b43/Kconfig
> @@ -31,12 +31,6 @@ config B43_BCMA
>  	depends on B43 && (BCMA = y || BCMA = B43)
>  	default y
>  
> -config B43_BCMA_EXTRA
> -	bool "Hardware support that overlaps with the brcmsmac driver"
> -	depends on B43_BCMA
> -	default n if BRCMSMAC
> -	default y
> -
>  config B43_SSB
>  	bool
>  	depends on B43 && (SSB = y || SSB = B43)
> diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
> index a95b77a..583993c 100644
> --- a/drivers/net/wireless/b43/main.c
> +++ b/drivers/net/wireless/b43/main.c
> @@ -113,13 +113,19 @@ static int b43_modparam_pio = 0;
>  module_param_named(pio, b43_modparam_pio, int, 0644);
>  MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
>  
> +#ifdef CONFIG_BRCMSMAC
> +static int modparam_allhwsupport;
> +#else
> +static int modparam_allhwsupport = 1;
> +#endif
> +module_param_named(allhwsupport, modparam_allhwsupport, int, 0444);
> +MODULE_PARM_DESC(allhwsupport, "Enable support for all hardware (even it if overlaps with the brcmsmac driver)");
> +
>  #ifdef CONFIG_B43_BCMA
>  static const struct bcma_device_id b43_bcma_tbl[] = {
>  	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS),
> -#ifdef CONFIG_B43_BCMA_EXTRA
>  	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS),
>  	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS),
> -#endif
>  	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS),
>  	BCMA_CORETABLE_END
>  };
> @@ -5396,6 +5402,12 @@ static int b43_bcma_probe(struct bcma_device *core)
>  	struct b43_wl *wl;
>  	int err;
>  
> +	if (!modparam_allhwsupport &&
> +	    (core->id.rev == 0x17 || core->id.rev == 0x18)) {
> +		pr_err("Support for cores revisions 0x17 and 0x18 disabled by module param allhwsupport=0. Try b43.allhwsupport=1\n");
> +		return -ENOTSUPP;
> +	}
> +
>  	dev = b43_bus_dev_bcma_init(core);
>  	if (!dev)
>  		return -ENODEV;
> -- 
> 1.7.10.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply

* [RFC][PATCH] b43: replace B43_BCMA_EXTRA with modparam allhwsupport
From: Rafał Miłecki @ 2013-06-25 15:34 UTC (permalink / raw)
  To: linux-wireless, John W. Linville; +Cc: b43-dev, Rafał Miłecki

This allows enabling support for extra hardware with just a module
param, without kernel/module recompilation.

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
 drivers/net/wireless/b43/Kconfig |    6 ------
 drivers/net/wireless/b43/main.c  |   16 ++++++++++++++--
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 3f21e0b..51ff0b1 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -31,12 +31,6 @@ config B43_BCMA
 	depends on B43 && (BCMA = y || BCMA = B43)
 	default y
 
-config B43_BCMA_EXTRA
-	bool "Hardware support that overlaps with the brcmsmac driver"
-	depends on B43_BCMA
-	default n if BRCMSMAC
-	default y
-
 config B43_SSB
 	bool
 	depends on B43 && (SSB = y || SSB = B43)
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index a95b77a..583993c 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -113,13 +113,19 @@ static int b43_modparam_pio = 0;
 module_param_named(pio, b43_modparam_pio, int, 0644);
 MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
 
+#ifdef CONFIG_BRCMSMAC
+static int modparam_allhwsupport;
+#else
+static int modparam_allhwsupport = 1;
+#endif
+module_param_named(allhwsupport, modparam_allhwsupport, int, 0444);
+MODULE_PARM_DESC(allhwsupport, "Enable support for all hardware (even it if overlaps with the brcmsmac driver)");
+
 #ifdef CONFIG_B43_BCMA
 static const struct bcma_device_id b43_bcma_tbl[] = {
 	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS),
-#ifdef CONFIG_B43_BCMA_EXTRA
 	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS),
 	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS),
-#endif
 	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS),
 	BCMA_CORETABLE_END
 };
@@ -5396,6 +5402,12 @@ static int b43_bcma_probe(struct bcma_device *core)
 	struct b43_wl *wl;
 	int err;
 
+	if (!modparam_allhwsupport &&
+	    (core->id.rev == 0x17 || core->id.rev == 0x18)) {
+		pr_err("Support for cores revisions 0x17 and 0x18 disabled by module param allhwsupport=0. Try b43.allhwsupport=1\n");
+		return -ENOTSUPP;
+	}
+
 	dev = b43_bus_dev_bcma_init(core);
 	if (!dev)
 		return -ENODEV;
-- 
1.7.10.4


^ permalink raw reply related

* Re: [RFH][PATCH] bcma: add support for BCM43142
From: Rafał Miłecki @ 2013-06-25 15:32 UTC (permalink / raw)
  To: Michal Kazior; +Cc: linux-wireless, John W. Linville
In-Reply-To: <CA+BoTQnda59qziwwjVfH7zCmQipED7TuxsDg0RgWA7ZK78gALQ@mail.gmail.com>

2013/6/25 Michal Kazior <michal.kazior@tieto.com>:
> On 25 June 2013 16:52, Rafał Miłecki <zajec5@gmail.com> wrote:
>> I got following problem with the patch:
>>   CC [M]  drivers/bcma/driver_chipcommon_pmu.o
>> drivers/bcma/driver_chipcommon_pmu.c: In function ‘bcma_pmu2_pll_init0’:
>> drivers/bcma/driver_chipcommon_pmu.c:128:5: warning: large integer implicitly truncated to unsigned type [-Woverflow]
>>
>> This is caused by:
>> mask = ~(BCMA_RES_4314_HT_AVAIL |
>>          BCMA_RES_4314_MACPHY_CLK_AVAIL);
>>
>> Any idea why
>> u32 mask = ~(BIT(28) | BIT(29))
>> causes that? :|
>>
>> I could expect that in case of using BIT(31), but not 28/29...
>
> Are you perhaps compiling for a 64bit target? If so then I you're
> dealing with a 64bit bitmask here. Negating ends up as an overflow as
> you try to cram it into the 32bit var.

Ahh, thanks!

Is there any preferred solution for that?
u32 mask = (u32)~(BIT(28) | BIT(29))
u32 mask = ~(BIT(28) | BIT(29)) & 0xFFFF
? I guess the first one looks nicer?

-- 
Rafał

^ permalink raw reply

* Re: [RFH][PATCH] bcma: add support for BCM43142
From: Michal Kazior @ 2013-06-25 15:08 UTC (permalink / raw)
  To: Rafał Miłecki; +Cc: linux-wireless, John W. Linville
In-Reply-To: <1372171926-2686-1-git-send-email-zajec5@gmail.com>

On 25 June 2013 16:52, Rafał Miłecki <zajec5@gmail.com> wrote:
> I got following problem with the patch:
>   CC [M]  drivers/bcma/driver_chipcommon_pmu.o
> drivers/bcma/driver_chipcommon_pmu.c: In function ‘bcma_pmu2_pll_init0’:
> drivers/bcma/driver_chipcommon_pmu.c:128:5: warning: large integer implicitly truncated to unsigned type [-Woverflow]
>
> This is caused by:
> mask = ~(BCMA_RES_4314_HT_AVAIL |
>          BCMA_RES_4314_MACPHY_CLK_AVAIL);
>
> Any idea why
> u32 mask = ~(BIT(28) | BIT(29))
> causes that? :|
>
> I could expect that in case of using BIT(31), but not 28/29...

Are you perhaps compiling for a 64bit target? If so then I you're
dealing with a 64bit bitmask here. Negating ends up as an overflow as
you try to cram it into the 32bit var.

^ permalink raw reply

* [RFH][PATCH] bcma: add support for BCM43142
From: Rafał Miłecki @ 2013-06-25 14:52 UTC (permalink / raw)
  To: linux-wireless, John W. Linville; +Cc: Rafał Miłecki


Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
H in RFH stand for "HELP" ;)

I got following problem with the patch:
  CC [M]  drivers/bcma/driver_chipcommon_pmu.o
drivers/bcma/driver_chipcommon_pmu.c: In function ‘bcma_pmu2_pll_init0’:
drivers/bcma/driver_chipcommon_pmu.c:128:5: warning: large integer implicitly truncated to unsigned type [-Woverflow]

This is caused by:
mask = ~(BCMA_RES_4314_HT_AVAIL |
	 BCMA_RES_4314_MACPHY_CLK_AVAIL);

Any idea why
u32 mask = ~(BIT(28) | BIT(29))
causes that? :|

I could expect that in case of using BIT(31), but not 28/29...
---
 drivers/bcma/bcma_private.h                 |    2 +
 drivers/bcma/driver_chipcommon.c            |   11 ++-
 drivers/bcma/driver_chipcommon_pmu.c        |  123 +++++++++++++++++++++++++++
 drivers/bcma/host_pci.c                     |    1 +
 drivers/bcma/main.c                         |   19 +++++
 drivers/bcma/sprom.c                        |    1 +
 include/linux/bcma/bcma.h                   |    1 +
 include/linux/bcma/bcma_driver_chipcommon.h |   55 ++++++++++++
 8 files changed, 211 insertions(+), 2 deletions(-)

diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
index 79595a0..0215f9a 100644
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -22,6 +22,8 @@
 struct bcma_bus;
 
 /* main.c */
+bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value,
+		     int timeout);
 int bcma_bus_register(struct bcma_bus *bus);
 void bcma_bus_unregister(struct bcma_bus *bus);
 int __init bcma_bus_early_register(struct bcma_bus *bus,
diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c
index 036c674..b068f98 100644
--- a/drivers/bcma/driver_chipcommon.c
+++ b/drivers/bcma/driver_chipcommon.c
@@ -140,8 +140,15 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
 	bcma_core_chipcommon_early_init(cc);
 
 	if (cc->core->id.rev >= 20) {
-		bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0);
-		bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0);
+		u32 pullup = 0, pulldown = 0;
+
+		if (cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM43142) {
+			pullup = 0x402e0;
+			pulldown = 0x20500;
+		}
+
+		bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, pullup);
+		bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, pulldown);
 	}
 
 	if (cc->capabilities & BCMA_CC_CAP_PMU)
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c
index edca73a..2056316 100644
--- a/drivers/bcma/driver_chipcommon_pmu.c
+++ b/drivers/bcma/driver_chipcommon_pmu.c
@@ -56,6 +56,109 @@ void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
 }
 EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset);
 
+static u32 bcma_pmu_xtalfreq(struct bcma_drv_cc *cc)
+{
+	u32 ilp_ctl, alp_hz;
+
+	if (!(bcma_cc_read32(cc, BCMA_CC_PMU_STAT) &
+	      BCMA_CC_PMU_STAT_EXT_LPO_AVAIL))
+		return 0;
+
+	bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ,
+			BIT(BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT));
+	usleep_range(1000, 2000);
+
+	ilp_ctl = bcma_cc_read32(cc, BCMA_CC_PMU_XTAL_FREQ);
+	ilp_ctl &= BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK;
+
+	bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ, 0);
+
+	alp_hz = ilp_ctl * 32768 / 4;
+	return (alp_hz + 50000) / 100000 * 100;
+}
+
+static void bcma_pmu2_pll_init0(struct bcma_drv_cc *cc, u32 xtalfreq)
+{
+	struct bcma_bus *bus = cc->core->bus;
+	u32 freq_tgt_target = 0, freq_tgt_current;
+	u32 pll0, mask;
+
+	switch (bus->chipinfo.id) {
+	case BCMA_CHIP_ID_BCM43142:
+		/* pmu2_xtaltab0_adfll_485 */
+		switch (xtalfreq) {
+		case 12000:
+			freq_tgt_target = 0x50D52;
+			break;
+		case 20000:
+			freq_tgt_target = 0x307FE;
+			break;
+		case 26000:
+			freq_tgt_target = 0x254EA;
+			break;
+		case 37400:
+			freq_tgt_target = 0x19EF8;
+			break;
+		case 52000:
+			freq_tgt_target = 0x12A75;
+			break;
+		}
+		break;
+	}
+
+	if (!freq_tgt_target) {
+		bcma_err(bus, "Unknown TGT frequency for xtalfreq %d\n",
+			 xtalfreq);
+		return;
+	}
+
+	pll0 = bcma_chipco_pll_read(cc, BCMA_CC_PMU15_PLL_PLLCTL0);
+	freq_tgt_current = (pll0 & BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK) >>
+		BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT;
+
+	if (freq_tgt_current == freq_tgt_target) {
+		bcma_debug(bus, "Target TGT frequency already set\n");
+		return;
+	}
+
+	/* Turn off PLL */
+	switch (bus->chipinfo.id) {
+	case BCMA_CHIP_ID_BCM43142:
+		mask = ~(BCMA_RES_4314_HT_AVAIL |
+			 BCMA_RES_4314_MACPHY_CLK_AVAIL);
+
+		bcma_cc_mask32(cc, BCMA_CC_PMU_MINRES_MSK, mask);
+		bcma_cc_mask32(cc, BCMA_CC_PMU_MAXRES_MSK, mask);
+		bcma_wait_value(cc->core, BCMA_CLKCTLST,
+				BCMA_CLKCTLST_HAVEHT, 0, 20000);
+		break;
+	}
+
+	pll0 &= ~BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK;
+	pll0 |= freq_tgt_target << BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT;
+	bcma_chipco_pll_write(cc, BCMA_CC_PMU15_PLL_PLLCTL0, pll0);
+
+	/* Flush */
+	if (cc->pmu.rev >= 2)
+		bcma_cc_set32(cc, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_PLL_UPD);
+
+	/* TODO: Do we need to update OTP? */
+}
+
+static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
+{
+	struct bcma_bus *bus = cc->core->bus;
+	u32 xtalfreq = bcma_pmu_xtalfreq(cc);
+
+	switch (bus->chipinfo.id) {
+	case BCMA_CHIP_ID_BCM43142:
+		if (xtalfreq == 0)
+			xtalfreq = 20000;
+		bcma_pmu2_pll_init0(cc, xtalfreq);
+		break;
+	}
+}
+
 static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
 {
 	struct bcma_bus *bus = cc->core->bus;
@@ -66,6 +169,25 @@ static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
 		min_msk = 0x200D;
 		max_msk = 0xFFFF;
 		break;
+	case BCMA_CHIP_ID_BCM43142:
+		min_msk = BCMA_RES_4314_LPLDO_PU |
+			  BCMA_RES_4314_PMU_SLEEP_DIS |
+			  BCMA_RES_4314_PMU_BG_PU |
+			  BCMA_RES_4314_CBUCK_LPOM_PU |
+			  BCMA_RES_4314_CBUCK_PFM_PU |
+			  BCMA_RES_4314_CLDO_PU |
+			  BCMA_RES_4314_LPLDO2_LVM |
+			  BCMA_RES_4314_WL_PMU_PU |
+			  BCMA_RES_4314_LDO3P3_PU |
+			  BCMA_RES_4314_OTP_PU |
+			  BCMA_RES_4314_WL_PWRSW_PU |
+			  BCMA_RES_4314_LQ_AVAIL |
+			  BCMA_RES_4314_LOGIC_RET |
+			  BCMA_RES_4314_MEM_SLEEP |
+			  BCMA_RES_4314_MACPHY_RET |
+			  BCMA_RES_4314_WL_CORE_READY;
+		max_msk = 0x3FFFFFFF;
+		break;
 	default:
 		bcma_debug(bus, "PMU resource config unknown or not needed for device 0x%04X\n",
 			   bus->chipinfo.id);
@@ -165,6 +287,7 @@ void bcma_pmu_init(struct bcma_drv_cc *cc)
 		bcma_cc_set32(cc, BCMA_CC_PMU_CTL,
 			     BCMA_CC_PMU_CTL_NOILPONW);
 
+	bcma_pmu_pll_init(cc);
 	bcma_pmu_resources_init(cc);
 	bcma_pmu_workarounds(cc);
 }
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c
index fbf2759..a355e63 100644
--- a/drivers/bcma/host_pci.c
+++ b/drivers/bcma/host_pci.c
@@ -275,6 +275,7 @@ static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
 	{ 0, },
 };
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index f72f52b..0067422 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -93,6 +93,25 @@ struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
 	return NULL;
 }
 
+bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value,
+		     int timeout)
+{
+	unsigned long deadline = jiffies + timeout;
+	u32 val;
+
+	do {
+		val = bcma_read32(core, reg);
+		if ((val & mask) == value)
+			return true;
+		cpu_relax();
+		udelay(10);
+	} while (!time_after_eq(jiffies, deadline));
+
+	bcma_warn(core->bus, "Timeout waiting for register 0x%04X!\n", reg);
+
+	return false;
+}
+
 static void bcma_release_core_dev(struct device *dev)
 {
 	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c
index de15b4f..72bf454 100644
--- a/drivers/bcma/sprom.c
+++ b/drivers/bcma/sprom.c
@@ -503,6 +503,7 @@ static bool bcma_sprom_onchip_available(struct bcma_bus *bus)
 	case BCMA_CHIP_ID_BCM4331:
 		present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT;
 		break;
+	case BCMA_CHIP_ID_BCM43142:
 	case BCMA_CHIP_ID_BCM43224:
 	case BCMA_CHIP_ID_BCM43225:
 		/* for these chips OTP is always available */
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index 2e34db8..622fc50 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -144,6 +144,7 @@ struct bcma_host_ops {
 
 /* Chip IDs of PCIe devices */
 #define BCMA_CHIP_ID_BCM4313	0x4313
+#define BCMA_CHIP_ID_BCM43142	43142
 #define BCMA_CHIP_ID_BCM43224	43224
 #define  BCMA_PKG_ID_BCM43224_FAB_CSM	0x8
 #define  BCMA_PKG_ID_BCM43224_FAB_SMIC	0xa
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
index b8b09ea..c49e1a1 100644
--- a/include/linux/bcma/bcma_driver_chipcommon.h
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -330,6 +330,8 @@
 #define BCMA_CC_PMU_CAP			0x0604 /* PMU capabilities */
 #define  BCMA_CC_PMU_CAP_REVISION	0x000000FF /* Revision mask */
 #define BCMA_CC_PMU_STAT		0x0608 /* PMU status */
+#define  BCMA_CC_PMU_STAT_EXT_LPO_AVAIL	0x00000100
+#define  BCMA_CC_PMU_STAT_WDRESET	0x00000080
 #define  BCMA_CC_PMU_STAT_INTPEND	0x00000040 /* Interrupt pending */
 #define  BCMA_CC_PMU_STAT_SBCLKST	0x00000030 /* Backplane clock status? */
 #define  BCMA_CC_PMU_STAT_HAVEALP	0x00000008 /* ALP available */
@@ -355,6 +357,11 @@
 #define BCMA_CC_REGCTL_DATA		0x065C
 #define BCMA_CC_PLLCTL_ADDR		0x0660
 #define BCMA_CC_PLLCTL_DATA		0x0664
+#define BCMA_CC_PMU_STRAPOPT		0x0668 /* (corerev >= 28) */
+#define BCMA_CC_PMU_XTAL_FREQ		0x066C /* (pmurev >= 10) */
+#define  BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK	0x00001FFF
+#define  BCMA_CC_PMU_XTAL_FREQ_MEASURE_MASK	0x80000000
+#define  BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT	31
 #define BCMA_CC_SPROM			0x0800 /* SPROM beginning */
 /* NAND flash MLC controller registers (corerev >= 38) */
 #define BCMA_CC_NAND_REVISION		0x0C00
@@ -435,6 +442,23 @@
 #define  BCMA_CC_PMU6_4706_PROC_NDIV_MODE_MASK	0x00000007
 #define  BCMA_CC_PMU6_4706_PROC_NDIV_MODE_SHIFT	0
 
+/* PMU rev 15 */
+#define BCMA_CC_PMU15_PLL_PLLCTL0	0
+#define  BCMA_CC_PMU15_PLL_PC0_CLKSEL_MASK	0x00000003
+#define  BCMA_CC_PMU15_PLL_PC0_CLKSEL_SHIFT	0
+#define  BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK	0x003FFFFC
+#define  BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT	2
+#define  BCMA_CC_PMU15_PLL_PC0_PRESCALE_MASK	0x00C00000
+#define  BCMA_CC_PMU15_PLL_PC0_PRESCALE_SHIFT	22
+#define  BCMA_CC_PMU15_PLL_PC0_KPCTRL_MASK	0x07000000
+#define  BCMA_CC_PMU15_PLL_PC0_KPCTRL_SHIFT	24
+#define  BCMA_CC_PMU15_PLL_PC0_FCNTCTRL_MASK	0x38000000
+#define  BCMA_CC_PMU15_PLL_PC0_FCNTCTRL_SHIFT	27
+#define  BCMA_CC_PMU15_PLL_PC0_FDCMODE_MASK	0x40000000
+#define  BCMA_CC_PMU15_PLL_PC0_FDCMODE_SHIFT	30
+#define  BCMA_CC_PMU15_PLL_PC0_CTRLBIAS_MASK	0x80000000
+#define  BCMA_CC_PMU15_PLL_PC0_CTRLBIAS_SHIFT	31
+
 /* ALP clock on pre-PMU chips */
 #define BCMA_CC_PMU_ALP_CLOCK		20000000
 /* HT clock for systems with PMU-enabled chipcommon */
@@ -507,6 +531,37 @@
 #define BCMA_CHIPCTL_5357_I2S_PINS_ENABLE	BIT(18)
 #define BCMA_CHIPCTL_5357_I2CSPI_PINS_ENABLE	BIT(19)
 
+#define BCMA_RES_4314_LPLDO_PU			BIT(0)
+#define BCMA_RES_4314_PMU_SLEEP_DIS		BIT(1)
+#define BCMA_RES_4314_PMU_BG_PU			BIT(2)
+#define BCMA_RES_4314_CBUCK_LPOM_PU		BIT(3)
+#define BCMA_RES_4314_CBUCK_PFM_PU		BIT(4)
+#define BCMA_RES_4314_CLDO_PU			BIT(5)
+#define BCMA_RES_4314_LPLDO2_LVM		BIT(6)
+#define BCMA_RES_4314_WL_PMU_PU			BIT(7)
+#define BCMA_RES_4314_LNLDO_PU			BIT(8)
+#define BCMA_RES_4314_LDO3P3_PU			BIT(9)
+#define BCMA_RES_4314_OTP_PU			BIT(10)
+#define BCMA_RES_4314_XTAL_PU			BIT(11)
+#define BCMA_RES_4314_WL_PWRSW_PU		BIT(12)
+#define BCMA_RES_4314_LQ_AVAIL			BIT(13)
+#define BCMA_RES_4314_LOGIC_RET			BIT(14)
+#define BCMA_RES_4314_MEM_SLEEP			BIT(15)
+#define BCMA_RES_4314_MACPHY_RET		BIT(16)
+#define BCMA_RES_4314_WL_CORE_READY		BIT(17)
+#define BCMA_RES_4314_ILP_REQ			BIT(18)
+#define BCMA_RES_4314_ALP_AVAIL			BIT(19)
+#define BCMA_RES_4314_MISC_PWRSW_PU		BIT(20)
+#define BCMA_RES_4314_SYNTH_PWRSW_PU		BIT(21)
+#define BCMA_RES_4314_RX_PWRSW_PU		BIT(22)
+#define BCMA_RES_4314_RADIO_PU			BIT(23)
+#define BCMA_RES_4314_VCO_LDO_PU		BIT(24)
+#define BCMA_RES_4314_AFE_LDO_PU		BIT(25)
+#define BCMA_RES_4314_RX_LDO_PU			BIT(26)
+#define BCMA_RES_4314_TX_LDO_PU			BIT(27)
+#define BCMA_RES_4314_HT_AVAIL			BIT(28)
+#define BCMA_RES_4314_MACPHY_CLK_AVAIL		BIT(29)
+
 /* Data for the PMU, if available.
  * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
  */
-- 
1.7.10.4


^ permalink raw reply related

* Re: Power saving features for iwl4965
From: Stanislaw Gruszka @ 2013-06-25 14:25 UTC (permalink / raw)
  To: Pedro Francisco; +Cc: Tino Keitel, ML linux-wireless
In-Reply-To: <20130614131829.GA5125@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 2056 bytes --]

On Fri, Jun 14, 2013 at 03:18:29PM +0200, Stanislaw Gruszka wrote:
> > >> I also got a SYSASSERT:
> > >> (...)
> > >>
> > >> I disabled powersave (but kept running the same kernel) and none of
> > >> the errors appeared again.
> > >
> > > Yes, this seems to be iwlegacy PS issue and has to be fixed before
> > > this patch could be applied.
> > 
> > But is it a driver-only issue? I had assumed it was some sort of
> > fireware+driver issue...
> Looks like driver issue or firmware issue that can be workaround in 
> the driver.
> 
> > Will running with debug on help? Or is it easily reproducible on any
> > iwl3945 / iwl4465 ?
> > 
> > Because in my case (iwl3945) it happens after boot, no prior suspend
> > to RAM is required to trigger the issues.
> I can reproduce microcode error on iwl4965 by reloading modules. Looks
> like we put device in sleep mode and it can not be properly booted when
> driver initalize. I did not yet test patch on iwl3945. When I'll do
> this, I think I'll be able to reproduce problems you discovered. If not
> I'll ask for more debug info.

I found problem on 4965, we have to send power configuration command to
device earlier, before some other commands. Attached patch solved
microcode errors I have on 4965.

Regarding iwl3945. Display on my 3945 laptop no longer works. I took
3945 device from that laptop and installed it on two different machines.
Unfortunately on none of them device was detected by pci system :-/
I have figure out how to get working 3945 testing environment, but for
now, perhaps you could provide me some more debug information.

Pedro, please do the fallowing:

Add this line in /etc/rsyslog.conf: 
kern.*                                                  /var/log/kernel

Restart rsyslog services:
# systemctl restart rsyslog.service

Restart iwl3945 module with verbose debug enabled:
modprobe -r iwl3945
modprobe iwl3945 debug=0x47ffffff

Reproduce the problem.

Unload module:
modprobe -r iwl3945

Then provide me generated /var/log/kernel file (compressed if needed).

Thanks
Stanislaw


[-- Attachment #2: iwl4965-update-power-mode-early.patch --]
[-- Type: text/plain, Size: 730 bytes --]

diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c
index d287fd2..e7821f6 100644
--- a/drivers/net/wireless/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/iwlegacy/4965-mac.c
@@ -5334,6 +5334,9 @@ il4965_alive_start(struct il_priv *il)
 
 	il->active_rate = RATES_MASK;
 
+	il_power_update_mode(il, true);
+	D_INFO("Updated power mode\n");
+
 	if (il_is_associated(il)) {
 		struct il_rxon_cmd *active_rxon =
 		    (struct il_rxon_cmd *)&il->active;
@@ -5364,9 +5367,6 @@ il4965_alive_start(struct il_priv *il)
 	D_INFO("ALIVE processing complete.\n");
 	wake_up(&il->wait_command_queue);
 
-	il_power_update_mode(il, true);
-	D_INFO("Updated power mode\n");
-
 	return;
 
 restart:

^ permalink raw reply related

* [PATCH v12 2/2] cfg80211: P2P find phase offload
From: Vladimir Kondratiev @ 2013-06-25 13:42 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Vladimir Kondratiev, linux-wireless, Luis R . Rodriguez,
	John W . Linville, Jouni Malinen, Arend van Spriel, Peer, Ilan
In-Reply-To: <1372167756-17928-1-git-send-email-qca_vkondrat@qca.qualcomm.com>

Allow to implement P2P find phase in the driver/firmware.

Offload scheme designed as follows:

- Driver provide methods start_p2p_find and stop_p2p_find in the cfg80211_ops;
- Driver indicate firmware or driver responds to the probe requests by setting
  feature NL80211_FEATURE_P2P_PROBE_RESP_OFFLOAD
- wpa_supplicant analyses methods supported to discover p2p offload support;
- wpa_supplicant analyses feature flags to discover p2p probe response
  offload support;
to perform p2p scan, wpa_supplicant:
- perform legacy scan, through driver's cfg80211_ops 'scan' method
- configure rx management filter to get probe-request and probe-response frames
- start p2p find via driver's cfg80211_ops start_p2p_find method
- driver start p2p find with hardware and notify wpa_supplicant with
  cfg80211_p2p_find_notify_start()
- driver/firmware toggle search/listen states. Received probe-request and
  probe-response frames passed to the wpa_supplicant via cfg80211_rx_mgmt
- when wpa_supplicant wants to stop p2p find, it calls driver's
  cfg80211_ops stop_p2p_find method. Alternatively, driver/firmware may decide
  to stop p2p find. In all cases, driver notifies wpa_supplicant using
  cfg80211_p2p_find_notify_end()

All driver to user space communication done through nl80211 layer.

Offloaded P2P find does not support variations like progressive scan.

Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
---
 include/net/cfg80211.h       |  76 ++++++++++++++++++
 include/uapi/linux/nl80211.h |  14 ++++
 net/wireless/nl80211.c       | 180 +++++++++++++++++++++++++++++++++++++++++++
 net/wireless/rdev-ops.h      |  19 +++++
 net/wireless/trace.h         |  44 +++++++++++
 5 files changed, 333 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 8347500..e3cc49c 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1805,6 +1805,38 @@ struct cfg80211_update_ft_ies_params {
 };
 
 /**
+ * struct cfg80211_p2p_find_params - parameters for P2P find
+ * @probe_ie: extra IE's for probe frames
+ * @probe_ie_len: length, bytes, of @probe_ie
+ * @probe_resp_ie: extra IE's for probe response frames
+ * @probe_resp_ie_len: length, bytes, of @probe_resp_ie
+ *	Driver/firmware may add additional IE's as well as modify
+ *	provided ones; typical IE's to be added are
+ *	WLAN_EID_EXT_SUPP_RATES, WLAN_EID_DS_PARAMS,
+ *	WLAN_EID_HT_CAPABILITY.
+ * @min_discoverable_interval: and
+ * @max_discoverable_interval: min/max for random multiplier of 100TU's
+ *	for the listen state duration
+ * @listen_channel: channel to listen on; not NULL
+ * @n_channels: number of channels to operate on
+ * @channels: channels to operate on
+ *	may be NULL, in this case driver suppose to scan for all social
+ *	channels; or channel set should be non-empty (n_channels > 0)
+ */
+struct cfg80211_p2p_find_params {
+	const u8 *probe_ie;
+	size_t probe_ie_len;
+	const u8 *probe_resp_ie;
+	size_t probe_resp_ie_len;
+	u32 min_discoverable_interval;
+	u32 max_discoverable_interval;
+	struct ieee80211_channel *listen_channel;
+
+	int n_channels;
+	struct ieee80211_channel **channels;
+};
+
+/**
  * struct cfg80211_ops - backend description for wireless configuration
  *
  * This struct is registered by fullmac card drivers and/or wireless stacks
@@ -2043,6 +2075,24 @@ struct cfg80211_update_ft_ies_params {
  *	driver can take the most appropriate actions.
  * @crit_proto_stop: Indicates critical protocol no longer needs increased link
  *	reliability. This operation can not fail.
+ *
+ * @start_p2p_find: start P2P find phase
+ *	Parameters include IEs for probe/probe-resp frames;
+ *	and channels to operate on.
+ *	Parameters are not retained after call, driver need to copy data if
+ *	it need it later.
+ *	P2P find can't run concurrently with ROC or scan,
+ *	conflict with scan detected by cfg80211 and -EBUSY returned;
+ *	and driver should check for ROC and return -EBUSY to indicate conflict.
+ *	While performing P2P discovery, driver should report received
+ *	probe-request and probe-response frames via cfg80211_rx_mgmt
+ *	accordingly to the rx mgmt filter, as set by mgmt_frame_register().
+ *	If device indicates NL80211_FEATURE_P2P_PROBE_RESP_OFFLOAD, it may
+ *	reply some matching probes and replied probes may be not reported to
+ *	the upper layers; otherwise it must not reply any probe.
+ * @stop_p2p_find: stop P2P find phase
+ *	After stopping p2p find, driver should call
+ *	cfg80211_p2p_find_notify_end() to inform upper layers
  */
 struct cfg80211_ops {
 	int	(*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -2278,6 +2328,12 @@ struct cfg80211_ops {
 				    u16 duration);
 	void	(*crit_proto_stop)(struct wiphy *wiphy,
 				   struct wireless_dev *wdev);
+
+	int	(*start_p2p_find)(struct wiphy *wiphy,
+				  struct wireless_dev *wdev,
+				  struct cfg80211_p2p_find_params *params);
+	void	(*stop_p2p_find)(struct wiphy *wiphy,
+				 struct wireless_dev *wdev);
 };
 
 /*
@@ -4177,6 +4233,26 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
  */
 void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp);
 
+/**
+ * cfg80211_p2p_find_notify_start - report p2p find phase started
+ * @wdev: the wireless device reporting the event
+ * @gfp: allocation flags
+ */
+void cfg80211_p2p_find_notify_start(struct wireless_dev *wdev, gfp_t gfp);
+
+/**
+ * cfg80211_p2p_find_notify_end - report p2p find phase ended
+ * @wdev: the wireless device reporting the event
+ * @gfp: allocation flags
+ *
+ * p2p find phase may be ended either unsolicited or in response to
+ * ops->stop_p2p_find
+ *
+ * In any case, if @start_p2p_find from driver's struct cfg80211_ops called,
+ * @cfg80211_p2p_find_notify_end should be eventually called
+ */
+void cfg80211_p2p_find_notify_end(struct wireless_dev *wdev, gfp_t gfp);
+
 /* Logging, debugging and troubleshooting/diagnostic helpers. */
 
 /* wiphy_printk helpers, similar to dev_printk */
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index f125d2c..3a2f2b0 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -810,6 +810,9 @@ enum nl80211_commands {
 	NL80211_CMD_CRIT_PROTOCOL_START,
 	NL80211_CMD_CRIT_PROTOCOL_STOP,
 
+	NL80211_CMD_START_P2P_FIND,
+	NL80211_CMD_STOP_P2P_FIND,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
@@ -1438,6 +1441,10 @@ enum nl80211_commands {
  *
  * @NL80211_ATTR_RXMGMT_FLAGS: flags for cfg80211_rx_mgmt, u32
  *
+ * @NL80211_ATTR_MIN_DISCOVERABLE_INTERVAL:
+ * @NL80211_ATTR_MAX_DISCOVERABLE_INTERVAL: min/max discoverable interval
+ *	for the p2p find, multiple of 100 TUs, represented as u32
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1740,6 +1747,9 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_RXMGMT_FLAGS,
 
+	NL80211_ATTR_MIN_DISCOVERABLE_INTERVAL,
+	NL80211_ATTR_MAX_DISCOVERABLE_INTERVAL,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -3592,6 +3602,9 @@ enum nl80211_ap_sme_features {
  *	interface. An active monitor interface behaves like a normal monitor
  *	interface, but gets added to the driver. It ensures that incoming
  *	unicast packets directed at the configured interface address get ACKed.
+ * @NL80211_FEATURE_P2P_PROBE_RESP_OFFLOAD: When in P2P find phase,
+ *	the device may respond to some probe-requests in hardware;
+ *	replied probe-requests may be not reported to the upper layers.
  */
 enum nl80211_feature_flags {
 	NL80211_FEATURE_SK_TX_STATUS			= 1 << 0,
@@ -3612,6 +3625,7 @@ enum nl80211_feature_flags {
 	NL80211_FEATURE_FULL_AP_CLIENT_STATE		= 1 << 15,
 	NL80211_FEATURE_USERSPACE_MPM			= 1 << 16,
 	NL80211_FEATURE_ACTIVE_MONITOR			= 1 << 17,
+	NL80211_FEATURE_P2P_PROBE_RESP_OFFLOAD		= 1 << 18,
 };
 
 /**
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 65c5578..a36ff7e 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -349,6 +349,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
 	[NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
 				  .len = IEEE80211_MAX_DATA_LEN },
 	[NL80211_ATTR_PEER_AID] = { .type = NLA_U16 },
+	[NL80211_ATTR_MIN_DISCOVERABLE_INTERVAL] = { .type = NLA_U32 },
+	[NL80211_ATTR_MAX_DISCOVERABLE_INTERVAL] = { .type = NLA_U32 },
 };
 
 /* policy for the key attributes */
@@ -1387,6 +1389,8 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
 		if (split) {
 			CMD(crit_proto_start, CRIT_PROTOCOL_START);
 			CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
+			CMD(start_p2p_find, START_P2P_FIND);
+			CMD(stop_p2p_find, STOP_P2P_FIND);
 		}
 
 #ifdef CONFIG_NL80211_TESTMODE
@@ -8306,6 +8310,129 @@ static int nl80211_crit_protocol_stop(struct sk_buff *skb,
 	return 0;
 }
 
+static int nl80211_start_p2p_find(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg80211_registered_device *rdev = info->user_ptr[0];
+	struct wireless_dev *wdev = info->user_ptr[1];
+	struct wiphy *wiphy = &rdev->wiphy;
+	/*
+	 * Defaults, as defined in the spec
+	 * Ref: Wi-Fi Peer-to-Peer (P2P) Technical Specification v1.1
+	 * Clause: 3.1.2.1.3 Find Phase
+	 */
+	struct cfg80211_p2p_find_params params = {
+		.min_discoverable_interval = 1,
+		.max_discoverable_interval = 3,
+	};
+	struct nlattr *attr_freq = info->attrs[NL80211_ATTR_SCAN_FREQUENCIES];
+	struct nlattr *attr_l_freq = info->attrs[NL80211_ATTR_WIPHY_FREQ];
+	struct nlattr *attr;
+	int err, tmp, n_channels, i = 0;
+	struct ieee80211_channel **channels = NULL;
+	struct ieee80211_channel *chan;
+
+	if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
+		return -EOPNOTSUPP;
+
+	if (!rdev->ops->start_p2p_find || !rdev->ops->stop_p2p_find)
+		return -EOPNOTSUPP;
+
+	if (!attr_l_freq)
+		return -EINVAL;
+
+	if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
+		return -EINVAL;
+
+	if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_PROBE_RESP]))
+		return -EINVAL;
+
+	if (rdev->scan_req)
+		return -EBUSY;
+
+	chan = ieee80211_get_channel(wiphy, nla_get_u32(attr_l_freq));
+	if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED))
+		return -EINVAL;
+	params.listen_channel = chan;
+
+	if (attr_freq) {
+		n_channels = validate_scan_freqs(attr_freq);
+		if (!n_channels)
+			return -EINVAL;
+
+		channels = kzalloc(n_channels * sizeof(*channels), GFP_KERNEL);
+		if (!channels)
+			return -ENOMEM;
+
+		/* user specified, bail out if channel not found */
+		nla_for_each_nested(attr, attr_freq, tmp) {
+			chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
+
+			if (!chan) {
+				err = -EINVAL;
+				goto out_free;
+			}
+
+			/* ignore disabled channels */
+			if (chan->flags & IEEE80211_CHAN_DISABLED)
+				continue;
+
+			params.channels[i] = chan;
+			i++;
+		}
+		if (!i) {
+			err = -EINVAL;
+			goto out_free;
+		}
+
+		params.n_channels = i;
+		params.channels = channels;
+	}
+
+
+	attr = info->attrs[NL80211_ATTR_IE];
+	if (attr) {
+		params.probe_ie_len = nla_len(attr);
+		params.probe_ie = nla_data(attr);
+	}
+
+	attr = info->attrs[NL80211_ATTR_IE_PROBE_RESP];
+	if (attr) {
+		params.probe_resp_ie_len = nla_len(attr);
+		params.probe_resp_ie = nla_data(attr);
+	}
+
+	attr = info->attrs[NL80211_ATTR_MIN_DISCOVERABLE_INTERVAL];
+	if (attr)
+		params.min_discoverable_interval = nla_get_u32(attr);
+
+	attr = info->attrs[NL80211_ATTR_MAX_DISCOVERABLE_INTERVAL];
+	if (attr)
+		params.max_discoverable_interval = nla_get_u32(attr);
+
+	err = rdev_start_p2p_find(rdev, wdev, &params);
+
+out_free:
+	kfree(channels);
+
+	return err;
+}
+
+static int nl80211_stop_p2p_find(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg80211_registered_device *rdev = info->user_ptr[0];
+	struct wireless_dev *wdev = info->user_ptr[1];
+
+	if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
+		return -EOPNOTSUPP;
+
+	if (!rdev->ops->start_p2p_find || !rdev->ops->stop_p2p_find)
+		return -EOPNOTSUPP;
+
+	rdev_stop_p2p_find(rdev, wdev);
+
+	return 0;
+}
+
 #define NL80211_FLAG_NEED_WIPHY		0x01
 #define NL80211_FLAG_NEED_NETDEV	0x02
 #define NL80211_FLAG_NEED_RTNL		0x04
@@ -8978,6 +9105,22 @@ static struct genl_ops nl80211_ops[] = {
 				  NL80211_FLAG_NEED_RTNL,
 	},
 	{
+		.cmd = NL80211_CMD_START_P2P_FIND,
+		.doit = nl80211_start_p2p_find,
+		.policy = nl80211_policy,
+		.flags = GENL_ADMIN_PERM,
+		.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
+				  NL80211_FLAG_NEED_RTNL,
+	},
+	{
+		.cmd = NL80211_CMD_STOP_P2P_FIND,
+		.doit = nl80211_stop_p2p_find,
+		.policy = nl80211_policy,
+		.flags = GENL_ADMIN_PERM,
+		.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
+				  NL80211_FLAG_NEED_RTNL,
+	},
+	{
 		.cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
 		.doit = nl80211_get_protocol_features,
 		.policy = nl80211_policy,
@@ -10645,6 +10788,43 @@ void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
 }
 EXPORT_SYMBOL(cfg80211_tdls_oper_request);
 
+static
+void cfg80211_p2p_find_notify(struct wireless_dev *wdev, int cmd, gfp_t gfp)
+{
+	struct wiphy *wiphy = wdev->wiphy;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+	struct sk_buff *msg;
+	void *hdr;
+
+	trace_cfg80211_p2p_find_notify(wdev, cmd);
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg)
+		return;
+
+	hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
+	if (!hdr) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	genlmsg_end(msg, hdr);
+
+	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+				nl80211_scan_mcgrp.id, GFP_KERNEL);
+}
+
+void cfg80211_p2p_find_notify_start(struct wireless_dev *wdev, gfp_t gfp)
+{
+	cfg80211_p2p_find_notify(wdev, NL80211_CMD_START_P2P_FIND, gfp);
+}
+EXPORT_SYMBOL(cfg80211_p2p_find_notify_start);
+
+void cfg80211_p2p_find_notify_end(struct wireless_dev *wdev, gfp_t gfp)
+{
+	cfg80211_p2p_find_notify(wdev, NL80211_CMD_STOP_P2P_FIND, gfp);
+}
+EXPORT_SYMBOL(cfg80211_p2p_find_notify_end);
+
 static int nl80211_netlink_notify(struct notifier_block * nb,
 				  unsigned long state,
 				  void *_notify)
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 9f15f0a..94ff98a 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -923,4 +923,23 @@ static inline void rdev_crit_proto_stop(struct cfg80211_registered_device *rdev,
 	trace_rdev_return_void(&rdev->wiphy);
 }
 
+static inline int rdev_start_p2p_find(struct cfg80211_registered_device *rdev,
+				      struct wireless_dev *wdev,
+				      struct cfg80211_p2p_find_params *params)
+{
+	int ret;
+	trace_rdev_start_p2p_find(&rdev->wiphy, wdev, params);
+	ret = rdev->ops->start_p2p_find(&rdev->wiphy, wdev, params);
+	trace_rdev_return_int(&rdev->wiphy, ret);
+	return ret;
+}
+
+static inline void rdev_stop_p2p_find(struct cfg80211_registered_device *rdev,
+				      struct wireless_dev *wdev)
+{
+	trace_rdev_stop_p2p_find(&rdev->wiphy, wdev);
+	rdev->ops->stop_p2p_find(&rdev->wiphy, wdev);
+	trace_rdev_return_void(&rdev->wiphy);
+}
+
 #endif /* __CFG80211_RDEV_OPS */
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index e1534baf..d4e4886 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -1841,6 +1841,36 @@ TRACE_EVENT(rdev_crit_proto_stop,
 		  WIPHY_PR_ARG, WDEV_PR_ARG)
 );
 
+TRACE_EVENT(rdev_start_p2p_find,
+	TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
+		 struct cfg80211_p2p_find_params *params),
+	TP_ARGS(wiphy, wdev, params),
+	TP_STRUCT__entry(
+		WIPHY_ENTRY
+		WDEV_ENTRY
+		__field(u32, min_di)
+		__field(u32, max_di)
+		__field(u32, listen_freq)
+		__field(int, n_channels)
+	),
+	TP_fast_assign(
+		WIPHY_ASSIGN;
+		WDEV_ASSIGN;
+		__entry->min_di = params->min_discoverable_interval;
+		__entry->max_di = params->max_discoverable_interval;
+		__entry->listen_freq = params->listen_channel->center_freq;
+		__entry->n_channels = params->n_channels;
+	),
+	TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", listen %d MHz, disc. int. [%d..%d], n_channels %d",
+		  WIPHY_PR_ARG, WDEV_PR_ARG, __entry->listen_freq,
+		  __entry->min_di, __entry->max_di, __entry->n_channels)
+);
+
+DEFINE_EVENT(wiphy_wdev_evt, rdev_stop_p2p_find,
+	TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev),
+	TP_ARGS(wiphy, wdev)
+);
+
 /*************************************************************
  *	     cfg80211 exported functions traces		     *
  *************************************************************/
@@ -2520,6 +2550,20 @@ TRACE_EVENT(cfg80211_ft_event,
 		  WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(target_ap))
 );
 
+TRACE_EVENT(cfg80211_p2p_find_notify,
+	TP_PROTO(struct wireless_dev *wdev, int cmd),
+	TP_ARGS(wdev, cmd),
+	TP_STRUCT__entry(
+		WDEV_ENTRY
+		__field(int, cmd)
+	),
+	TP_fast_assign(
+		WDEV_ASSIGN;
+		__entry->cmd = cmd;
+	),
+	TP_printk(WDEV_PR_FMT ", cmd: %d", WDEV_PR_ARG, __entry->cmd)
+);
+
 #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
 
 #undef TRACE_INCLUDE_PATH
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH v12 1/2] cfg80211: add 'flags' to cfg80211_rx_mgmt()
From: Vladimir Kondratiev @ 2013-06-25 13:42 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Vladimir Kondratiev, linux-wireless, Luis R . Rodriguez,
	John W . Linville, Jouni Malinen, Arend van Spriel, Peer, Ilan
In-Reply-To: <1372167756-17928-1-git-send-email-qca_vkondrat@qca.qualcomm.com>

Flags intended to report various auxiliary information.
Introduced flag NL80211_RXMGMT_FLAG_REPLIED to report
whether frame was replied by the device/driver.

Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/wmi.c         |  7 +++----
 drivers/net/wireless/ath/wil6210/wmi.c        |  2 +-
 drivers/net/wireless/brcm80211/brcmfmac/p2p.c |  4 ++--
 drivers/net/wireless/mwifiex/util.c           |  4 ++--
 include/net/cfg80211.h                        |  3 ++-
 include/uapi/linux/nl80211.h                  | 13 +++++++++++++
 net/mac80211/rx.c                             |  3 +--
 net/wireless/mlme.c                           |  4 ++--
 net/wireless/nl80211.c                        |  6 ++++--
 net/wireless/nl80211.h                        |  2 +-
 10 files changed, 31 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 87aefb4..546d5da 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -568,8 +568,8 @@ static int ath6kl_wmi_rx_probe_req_event_rx(struct wmi *wmi, u8 *datap, int len,
 		   dlen, freq, vif->probe_req_report);
 
 	if (vif->probe_req_report || vif->nw_type == AP_NETWORK)
-		cfg80211_rx_mgmt(&vif->wdev, freq, 0,
-				 ev->data, dlen, GFP_ATOMIC);
+		cfg80211_rx_mgmt(&vif->wdev, freq, 0, ev->data, dlen, 0,
+				 GFP_ATOMIC);
 
 	return 0;
 }
@@ -608,8 +608,7 @@ static int ath6kl_wmi_rx_action_event_rx(struct wmi *wmi, u8 *datap, int len,
 		return -EINVAL;
 	}
 	ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq);
-	cfg80211_rx_mgmt(&vif->wdev, freq, 0,
-			 ev->data, dlen, GFP_ATOMIC);
+	cfg80211_rx_mgmt(&vif->wdev, freq, 0, ev->data, dlen, 0, GFP_ATOMIC);
 
 	return 0;
 }
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index dc8059a..21c791e 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -339,7 +339,7 @@ static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len)
 		}
 	} else {
 		cfg80211_rx_mgmt(wil->wdev, freq, signal,
-				 (void *)rx_mgmt_frame, d_len, GFP_KERNEL);
+				 (void *)rx_mgmt_frame, d_len, 0, GFP_KERNEL);
 	}
 }
 
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
index 79555f0..d7a9745 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
@@ -1430,7 +1430,7 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp,
 					      IEEE80211_BAND_5GHZ);
 
 	wdev = &ifp->vif->wdev;
-	cfg80211_rx_mgmt(wdev, freq, 0, (u8 *)mgmt_frame, mgmt_frame_len,
+	cfg80211_rx_mgmt(wdev, freq, 0, (u8 *)mgmt_frame, mgmt_frame_len, 0,
 			 GFP_ATOMIC);
 
 	kfree(mgmt_frame);
@@ -1895,7 +1895,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
 					      IEEE80211_BAND_2GHZ :
 					      IEEE80211_BAND_5GHZ);
 
-	cfg80211_rx_mgmt(&vif->wdev, freq, 0, mgmt_frame, mgmt_frame_len,
+	cfg80211_rx_mgmt(&vif->wdev, freq, 0, mgmt_frame, mgmt_frame_len, 0,
 			 GFP_ATOMIC);
 
 	brcmf_dbg(INFO, "mgmt_frame_len (%d) , e->datalen (%d), chanspec (%04x), freq (%d)\n",
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index e57ac0d..5d9e150 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -171,8 +171,8 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv,
 	rx_pd->rx_pkt_length = cpu_to_le16(pkt_len);
 
 	cfg80211_rx_mgmt(priv->wdev, priv->roc_cfg.chan.center_freq,
-			 CAL_RSSI(rx_pd->snr, rx_pd->nf),
-			 skb->data, pkt_len, GFP_ATOMIC);
+			 CAL_RSSI(rx_pd->snr, rx_pd->nf), skb->data, pkt_len,
+			 0, GFP_ATOMIC);
 
 	return 0;
 }
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 6a43c34..8347500 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -3856,6 +3856,7 @@ void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
  * @sig_dbm: signal strength in mBm, or 0 if unknown
  * @buf: Management frame (header + body)
  * @len: length of the frame data
+ * @flags: flags, as defined in enum nl80211_rxmgmt_flags
  * @gfp: context flags
  *
  * This function is called whenever an Action frame is received for a station
@@ -3867,7 +3868,7 @@ void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
  * driver is responsible for rejecting the frame.
  */
 bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_dbm,
-		      const u8 *buf, size_t len, gfp_t gfp);
+		      const u8 *buf, size_t len, u32 flags, gfp_t gfp);
 
 /**
  * cfg80211_mgmt_tx_status - notification of TX status for management frame
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index ca6facf..f125d2c 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1436,6 +1436,8 @@ enum nl80211_commands {
  *	allowed to be used with the first @NL80211_CMD_SET_STATION command to
  *	update a TDLS peer STA entry.
  *
+ * @NL80211_ATTR_RXMGMT_FLAGS: flags for cfg80211_rx_mgmt, u32
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1736,6 +1738,8 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_PEER_AID,
 
+	NL80211_ATTR_RXMGMT_FLAGS,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -3754,4 +3758,13 @@ enum nl80211_crit_proto_id {
 /* maximum duration for critical protocol measures */
 #define NL80211_CRIT_PROTO_MAX_DURATION		5000 /* msec */
 
+/**
+ * enum nl80211_rxmgmt_flags - flags for cfg80211_rx_mgmt
+ *
+ * @NL80211_RXMGMT_FLAG_REPLIED: frame was replied by device/driver.
+ */
+enum nl80211_rxmgmt_flags {
+	NL80211_RXMGMT_FLAG_REPLIED = (1 << 0),
+};
+
 #endif /* __LINUX_NL80211_H */
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 23dbcfc..3f7fa49 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2635,8 +2635,7 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx)
 		sig = status->signal;
 
 	if (cfg80211_rx_mgmt(&rx->sdata->wdev, status->freq, sig,
-			     rx->skb->data, rx->skb->len,
-			     GFP_ATOMIC)) {
+			     rx->skb->data, rx->skb->len, 0, GFP_ATOMIC)) {
 		if (rx->sta)
 			rx->sta->rx_packets++;
 		dev_kfree_skb(rx->skb);
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index a61a44b..74b1856 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -615,7 +615,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
 }
 
 bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm,
-		      const u8 *buf, size_t len, gfp_t gfp)
+		      const u8 *buf, size_t len, u32 flags, gfp_t gfp)
 {
 	struct wiphy *wiphy = wdev->wiphy;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
@@ -658,7 +658,7 @@ bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm,
 		/* Indicate the received Action frame to user space */
 		if (nl80211_send_mgmt(rdev, wdev, reg->nlportid,
 				      freq, sig_mbm,
-				      buf, len, gfp))
+				      buf, len, flags, gfp))
 			continue;
 
 		result = true;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 57be2f4..65c5578 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -9962,7 +9962,7 @@ EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame);
 int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
 		      struct wireless_dev *wdev, u32 nlportid,
 		      int freq, int sig_dbm,
-		      const u8 *buf, size_t len, gfp_t gfp)
+		      const u8 *buf, size_t len, u32 flags, gfp_t gfp)
 {
 	struct net_device *netdev = wdev->netdev;
 	struct sk_buff *msg;
@@ -9985,7 +9985,9 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
 	    nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
 	    (sig_dbm &&
 	     nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
-	    nla_put(msg, NL80211_ATTR_FRAME, len, buf))
+	    nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
+	    (flags &&
+	     nla_put_u32(msg, NL80211_ATTR_RXMGMT_FLAGS, flags)))
 		goto nla_put_failure;
 
 	genlmsg_end(msg, hdr);
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index a4073e8..3b51a76 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -66,7 +66,7 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
 int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
 		      struct wireless_dev *wdev, u32 nlpid,
 		      int freq, int sig_dbm,
-		      const u8 *buf, size_t len, gfp_t gfp);
+		      const u8 *buf, size_t len, u32 flags, gfp_t gfp);
 
 void
 nl80211_radar_notify(struct cfg80211_registered_device *rdev,
-- 
1.8.1.2


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox