Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [PATCH v2 3/3] mwifiex: Enable WoWLAN for both sdio and pcie
From: Brian Norris @ 2016-11-11 22:05 UTC (permalink / raw)
  To: Amitkumar Karwar
  Cc: linux-wireless, Cathy Luo, Nishant Sarmukadam, rajatja,
	dmitry.torokhov
In-Reply-To: <20161111204235.GB111624@google.com>

Hi,

One correction to my review:

On Fri, Nov 11, 2016 at 12:42:36PM -0800, Brian Norris wrote:
> On Fri, Nov 11, 2016 at 04:45:11PM +0530, Amitkumar Karwar wrote:
> > --- a/drivers/net/wireless/marvell/mwifiex/main.c
> > +++ b/drivers/net/wireless/marvell/mwifiex/main.c
> > @@ -1552,14 +1552,55 @@ void mwifiex_do_flr(struct mwifiex_adapter *adapter, bool prepare)
> >  }
> >  EXPORT_SYMBOL_GPL(mwifiex_do_flr);
> >  
> > +static irqreturn_t mwifiex_irq_wakeup_handler(int irq, void *priv)
> > +{
> > +	struct mwifiex_adapter *adapter = priv;
> > +
> > +	if (adapter->irq_wakeup >= 0) {
> > +		dev_dbg(adapter->dev, "%s: wake by wifi", __func__);
> > +		adapter->wake_by_wifi = true;
> 
> This flag is unecessary and buggy. IIUC, you're trying to avoid calling
> disable_irq() in resume(), if you've called it here?
> 
> > +		disable_irq_nosync(irq);
> 
> ...but this is unnecessary, I think, unless you're trying to make up for
> buggy wakeup interrupts that keep firing? See my suggestion below.

I think I figured out some of the logic here, and my suggestion was
somewhat wrong. This 'wake_by_wifi' flag seems to be used here to assist
with the fact that we're requesting a level-triggered interrupt, but
the card doesn't deassert the interrupt until much later -- when we
finish the wakeup handshake.

So I guess it is necessary (or at least, expedient) to disable the
interrupt here.

> > +	}
> > +
> > +	/* Notify PM core we are wakeup source */
> > +	pm_wakeup_event(adapter->dev, 0);
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> >  static void mwifiex_probe_of(struct mwifiex_adapter *adapter)
> >  {
> > +	int ret;
> >  	struct device *dev = adapter->dev;
> >  
> >  	if (!dev->of_node)
> >  		return;
> >  
> >  	adapter->dt_node = dev->of_node;
> > +	adapter->irq_wakeup = irq_of_parse_and_map(adapter->dt_node, 0);
> > +	if (!adapter->irq_wakeup) {
> > +		dev_info(dev, "fail to parse irq_wakeup from device tree\n");
> > +		return;
> > +	}
> > +
> > +	ret = devm_request_irq(dev, adapter->irq_wakeup,
> > +			       mwifiex_irq_wakeup_handler, IRQF_TRIGGER_LOW,
> > +			       "wifi_wake", adapter);
> > +	if (ret) {
> > +		dev_err(dev, "Failed to request irq_wakeup %d (%d)\n",
> > +			adapter->irq_wakeup, ret);
> > +		goto err_exit;
> > +	}
> > +
> > +	disable_irq(adapter->irq_wakeup);
> > +	if (device_init_wakeup(dev, true)) {
> > +		dev_err(dev, "fail to init wakeup for mwifiex\n");
> > +		goto err_exit;
> > +	}
> > +	return;
> > +
> > +err_exit:
> > +	adapter->irq_wakeup = 0;
> >  }
> >  
> >  /*
> > diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h
> > index 0c07434..11abc49 100644
> > --- a/drivers/net/wireless/marvell/mwifiex/main.h
> > +++ b/drivers/net/wireless/marvell/mwifiex/main.h
> > @@ -1011,6 +1011,10 @@ struct mwifiex_adapter {
> >  	bool usb_mc_setup;
> >  	struct cfg80211_wowlan_nd_info *nd_info;
> >  	struct ieee80211_regdomain *regd;
> > +
> > +	/* Wake-on-WLAN (WoWLAN) */
> > +	int irq_wakeup;
> > +	bool wake_by_wifi;
> >  };
> >  
> >  void mwifiex_process_tx_queue(struct mwifiex_adapter *adapter);
> > @@ -1410,6 +1414,27 @@ static inline u8 mwifiex_is_tdls_link_setup(u8 status)
> >  	return false;
> >  }
> >  
> > +/* Disable platform specific wakeup interrupt */
> > +static inline void mwifiex_disable_wake(struct mwifiex_adapter *adapter)
> > +{
> > +	if (adapter->irq_wakeup >= 0) {
> > +		disable_irq_wake(adapter->irq_wakeup);
> > +		if (!adapter->wake_by_wifi)
> 
> You're depending on the wake IRQ handler to set this flag, so you don't
> disable the IRQ twice (the calls nest). But what if the IRQ is being
> serviced concurrently with this? Then you'll double-disable the IRQ.
> 
> I believe you can just remove the disable_irq_nosync() from the handler,
> kill the above flag, and just unconditionally disable the IRQ.

So my suggestion here was wrong; we shouldn't completely kill the check
for ->wake_by_wifi I don't think, but we *should* wait for the interrupt
handler to complete before checking the flag. i.e., synchronize_irq():

diff --git a/drivers/net/wireless/marvell/mwifiex/util.c b/drivers/net/wireless/marvell/mwifiex/util.c
index 4063086ab5b8..e9446eeafb9d 100644
--- a/drivers/net/wireless/marvell/mwifiex/util.c
+++ b/drivers/net/wireless/marvell/mwifiex/util.c
@@ -841,6 +841,11 @@ void mwifiex_disable_wake(struct mwifiex_plt_wake_cfg *wake_cfg)
 {
 	if (wake_cfg && wake_cfg->irq_wifi >= 0) {
 		disable_irq_wake(wake_cfg->irq_wifi);
+		/*
+		 * Disable the wake IRQ only if it didn't already fire (and
+		 * disable itself).
+		 */
+		synchronize_irq(wake_cfg->irq_wifi);
 		if (!wake_cfg->wake_by_wifi)
 			disable_irq(wake_cfg->irq_wifi);
 	}

I'd appreciate if you bugfix this, either before or after this patch.

Brian

> > +			disable_irq(adapter->irq_wakeup);
> > +	}
> > +}
> > +
> > +/* Enable platform specific wakeup interrupt */
> > +static inline void mwifiex_enable_wake(struct mwifiex_adapter *adapter)
> > +{
> > +	/* Enable platform specific wakeup interrupt */
> > +	if (adapter->irq_wakeup >= 0) {
> > +		adapter->wake_by_wifi = false;
> > +		enable_irq(adapter->irq_wakeup);
> > +		enable_irq_wake(adapter->irq_wakeup);
> > +	}
> > +}
> > +
> >  int mwifiex_init_shutdown_fw(struct mwifiex_private *priv,
> >  			     u32 func_init_shutdown);
> >  int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8,

^ permalink raw reply related

* Re: [RFC] change mac80211_hwsim tx_rates to ieee80211_tx_rate
From: Johannes Berg @ 2016-11-12 21:08 UTC (permalink / raw)
  To: Benjamin Beichler, linux-wireless
In-Reply-To: <dcc2ec52-abe0-3182-e7f5-d1df40fd492b@uni-rostock.de>

> So I would propose to put the whole struct into the netlink messages,

This is a terrible idea, since internal changes to this struct would
break the userland API/ABI. hwsim seems perhaps less important than
most APIs, but there is wmediumd etc. already.

> but I think that will break up the communication to e.g. bob
> copelands
> wmediumd and similar simulations. I would like to have our
> Implementation working with mainline kernels and therefore ask how we
> could achieve this easily.
> 
> Obviously, we could define another field in the hwsim messages, but
> as bob copeland already stated, significantly more information within
> the netlink messages could  intensify the timing overhead of hwsim.

I don't think we have any other choice but add the relevant fields as
proper attributes.

johannes

^ permalink raw reply

* [PATCH] rtl8xxxu: Fix failure to reconnect to AP
From: Barry Day @ 2016-11-13 11:17 UTC (permalink / raw)
  To: Jes Sorensen; +Cc: Kalle Valo, linux-wireless

The rtl8192e and rtl8723 fail to reconnect to an AP after being
disconnected. Ths patch fixes that without affecting the rtl8192cu.
I don't have a rtl8723 to test but it has been tested on a rtl8192eu.
After going through the orginal realtek code for the rtl8723, I am
confident the patch is applicable to both.

Signed-off-by: Barry Day <briselec@gmail.com>
---
 rtl8xxxu_core.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/rtl8xxxu_core.c b/rtl8xxxu_core.c
index 04141e5..6ac10d2 100644
--- a/rtl8xxxu_core.c
+++ b/rtl8xxxu_core.c
@@ -4372,17 +4372,25 @@ void rtl8xxxu_gen1_report_connect(struct rtl8xxxu_priv *priv,
 void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv,
 				  u8 macid, bool connect)
 {
+	u8 val8;
 	struct h2c_cmd h2c;
 
 	memset(&h2c, 0, sizeof(struct h2c_cmd));
 
 	h2c.media_status_rpt.cmd = H2C_8723B_MEDIA_STATUS_RPT;
-	if (connect)
+	if (connect) {
 		h2c.media_status_rpt.parm |= BIT(0);
-	else
-		h2c.media_status_rpt.parm &= ~BIT(0);
+		rtl8xxxu_gen2_h2c_cmd(priv, &h2c,
+					sizeof(h2c.media_status_rpt));
+	} else {
+		val8 = rtl8xxxu_read8(priv, REG_BEACON_CTRL);
+		val8 &= ~BEACON_FUNCTION_ENABLE;
+
+		rtl8xxxu_write8(priv, REG_BEACON_CTRL, val8);
+		rtl8xxxu_write16(priv, REG_RXFLTMAP2, 0x00);
+		rtl8xxxu_write8(priv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
+	}
 
-	rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.media_status_rpt));
 }
 
 void rtl8xxxu_gen1_init_aggregation(struct rtl8xxxu_priv *priv)
@@ -4515,6 +4523,8 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 				sgi = 1;
 			rcu_read_unlock();
 
+			rtl8xxxu_write16(priv, REG_RXFLTMAP2, 0xffff);
+
 			priv->fops->update_rate_mask(priv, ramask, sgi);
 
 			rtl8xxxu_write8(priv, REG_BCN_MAX_ERR, 0xff);
-- 
2.9.2

^ permalink raw reply related

* Re: Problems getting mwifiex with sd8887 to work
From: Wolfram Sang @ 2016-11-13 14:13 UTC (permalink / raw)
  To: Amitkumar Karwar
  Cc: linux-wireless@vger.kernel.org, Nishant Sarmukadam, Kalle Valo
In-Reply-To: <507fff29bd2048c2b2295beb451943b5@SC-EXCH04.marvell.com>

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

> 0x242 command failure is expected for sd8887, as It's not supported.

Is the same true for 0x10f?

mwifiex_sdio mmc2:0001:1: CMD_RESP: cmd 0x10f error, result=0x2

Otherwise I can connect to the network and run performance tests now.


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply

* [PATCH 3.2 017/152] x86/quirks: Add early quirk to reset Apple AirPort card
From: Ben Hutchings @ 2016-11-14  0:14 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: akpm, Denys Vlasenko, linux-wireless, H. Peter Anvin,
	Andy Lutomirski, Thomas Gleixner, Matt Fleming, Peter Zijlstra,
	Konstantin Simanov, Borislav Petkov, linux-pci, Brian Gerst,
	Michael Buesch, Andrew Worsley, Lukas Wunner,
	Rafał Miłecki, Chris Bainbridge, b43-dev, Bryan Paradis,
	Linus Torvalds, Josh Poimboeuf, Chris Milsted, Matthew Garrett,
	Bjorn Helgaas, Yinghai Lu, Ingo Molnar
In-Reply-To: <lsq.1479082446.271293126@decadent.org.uk>

3.2.84-rc1 review patch.  If anyone has any objections, please let me know.

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

From: Lukas Wunner <lukas@wunner.de>

commit abb2bafd295fe962bbadc329dbfb2146457283ac upstream.

The EFI firmware on Macs contains a full-fledged network stack for
downloading OS X images from osrecovery.apple.com. Unfortunately
on Macs introduced 2011 and 2012, EFI brings up the Broadcom 4331
wireless card on every boot and leaves it enabled even after
ExitBootServices has been called. The card continues to assert its IRQ
line, causing spurious interrupts if the IRQ is shared. It also corrupts
memory by DMAing received packets, allowing for remote code execution
over the air. This only stops when a driver is loaded for the wireless
card, which may be never if the driver is not installed or blacklisted.

The issue seems to be constrained to the Broadcom 4331. Chris Milsted
has verified that the newer Broadcom 4360 built into the MacBookPro11,3
(2013/2014) does not exhibit this behaviour. The chances that Apple will
ever supply a firmware fix for the older machines appear to be zero.

The solution is to reset the card on boot by writing to a reset bit in
its mmio space. This must be done as an early quirk and not as a plain
vanilla PCI quirk to successfully combat memory corruption by DMAed
packets: Matthew Garrett found out in 2012 that the packets are written
to EfiBootServicesData memory (http://mjg59.dreamwidth.org/11235.html).
This type of memory is made available to the page allocator by
efi_free_boot_services(). Plain vanilla PCI quirks run much later, in
subsys initcall level. In-between a time window would be open for memory
corruption. Random crashes occurring in this time window and attributed
to DMAed packets have indeed been observed in the wild by Chris
Bainbridge.

When Matthew Garrett analyzed the memory corruption issue in 2012, he
sought to fix it with a grub quirk which transitions the card to D3hot:
http://git.savannah.gnu.org/cgit/grub.git/commit/?id=9d34bb85da56

This approach does not help users with other bootloaders and while it
may prevent DMAed packets, it does not cure the spurious interrupts
emanating from the card. Unfortunately the card's mmio space is
inaccessible in D3hot, so to reset it, we have to undo the effect of
Matthew's grub patch and transition the card back to D0.

Note that the quirk takes a few shortcuts to reduce the amount of code:
The size of BAR 0 and the location of the PM capability is identical
on all affected machines and therefore hardcoded. Only the address of
BAR 0 differs between models. Also, it is assumed that the BCMA core
currently mapped is the 802.11 core. The EFI driver seems to always take
care of this.

Michael Büsch, Bjorn Helgaas and Matt Fleming contributed feedback
towards finding the best solution to this problem.

The following should be a comprehensive list of affected models:
    iMac13,1        2012  21.5"       [Root Port 00:1c.3 = 8086:1e16]
    iMac13,2        2012  27"         [Root Port 00:1c.3 = 8086:1e16]
    Macmini5,1      2011  i5 2.3 GHz  [Root Port 00:1c.1 = 8086:1c12]
    Macmini5,2      2011  i5 2.5 GHz  [Root Port 00:1c.1 = 8086:1c12]
    Macmini5,3      2011  i7 2.0 GHz  [Root Port 00:1c.1 = 8086:1c12]
    Macmini6,1      2012  i5 2.5 GHz  [Root Port 00:1c.1 = 8086:1e12]
    Macmini6,2      2012  i7 2.3 GHz  [Root Port 00:1c.1 = 8086:1e12]
    MacBookPro8,1   2011  13"         [Root Port 00:1c.1 = 8086:1c12]
    MacBookPro8,2   2011  15"         [Root Port 00:1c.1 = 8086:1c12]
    MacBookPro8,3   2011  17"         [Root Port 00:1c.1 = 8086:1c12]
    MacBookPro9,1   2012  15"         [Root Port 00:1c.1 = 8086:1e12]
    MacBookPro9,2   2012  13"         [Root Port 00:1c.1 = 8086:1e12]
    MacBookPro10,1  2012  15"         [Root Port 00:1c.1 = 8086:1e12]
    MacBookPro10,2  2012  13"         [Root Port 00:1c.1 = 8086:1e12]

For posterity, spurious interrupts caused by the Broadcom 4331 wireless
card resulted in splats like this (stacktrace omitted):

    irq 17: nobody cared (try booting with the "irqpoll" option)
    handlers:
    [<ffffffff81374370>] pcie_isr
    [<ffffffffc0704550>] sdhci_irq [sdhci] threaded [<ffffffffc07013c0>] sdhci_thread_irq [sdhci]
    [<ffffffffc0a0b960>] azx_interrupt [snd_hda_codec]
    Disabling IRQ #17

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=79301
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=111781
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=728916
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=895951#c16
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1009819
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1098621
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1149632#c5
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1279130
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1332732
Tested-by: Konstantin Simanov <k.simanov@stlk.ru>        # [MacBookPro8,1]
Tested-by: Lukas Wunner <lukas@wunner.de>                # [MacBookPro9,1]
Tested-by: Bryan Paradis <bryan.paradis@gmail.com>       # [MacBookPro9,2]
Tested-by: Andrew Worsley <amworsley@gmail.com>          # [MacBookPro10,1]
Tested-by: Chris Bainbridge <chris.bainbridge@gmail.com> # [MacBookPro10,2]
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Acked-by: Rafał Miłecki <zajec5@gmail.com>
Acked-by: Matt Fleming <matt@codeblueprint.co.uk>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Chris Milsted <cmilsted@redhat.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Matthew Garrett <mjg59@srcf.ucam.org>
Cc: Michael Buesch <m@bues.ch>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: b43-dev@lists.infradead.org
Cc: linux-pci@vger.kernel.org
Cc: linux-wireless@vger.kernel.org
Link: http://lkml.kernel.org/r/48d0972ac82a53d460e5fce77a07b2560db95203.1465690253.git.lukas@wunner.de
[ Did minor readability edits. ]
Signed-off-by: Ingo Molnar <mingo@kernel.org>
[bwh: Backported to 3.2:
 - early_ioremap() is declared in <asm/io.h> not <asm/early_ioremap.h>
 - Add definition of BCMA_RESET_ST
 - Adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
 arch/x86/kernel/early-quirks.c | 64 ++++++++++++++++++++++++++++++++++++++++++
 drivers/bcma/bcma_private.h    |  2 --
 include/linux/bcma/bcma.h      |  1 +
 3 files changed, 65 insertions(+), 2 deletions(-)

--- a/arch/x86/kernel/early-quirks.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -11,13 +11,20 @@
 
 #include <linux/pci.h>
 #include <linux/acpi.h>
+#include <linux/delay.h>
+#include <linux/dmi.h>
 #include <linux/pci_ids.h>
+#include <linux/bcma/bcma.h>
+#include <linux/bcma/bcma_regs.h>
 #include <asm/pci-direct.h>
 #include <asm/dma.h>
 #include <asm/io_apic.h>
 #include <asm/apic.h>
 #include <asm/iommu.h>
 #include <asm/gart.h>
+#include <asm/io.h>
+
+#define dev_err(msg)  pr_err("pci 0000:%02x:%02x.%d: %s", bus, slot, func, msg)
 
 static void __init fix_hypertransport_config(int num, int slot, int func)
 {
@@ -199,6 +206,62 @@ static void __init ati_bugs_contd(int nu
 }
 #endif
 
+#define BCM4331_MMIO_SIZE	16384
+#define BCM4331_PM_CAP		0x40
+#define bcma_aread32(reg)	ioread32(mmio + 1 * BCMA_CORE_SIZE + reg)
+#define bcma_awrite32(reg, val)	iowrite32(val, mmio + 1 * BCMA_CORE_SIZE + reg)
+
+static void __init apple_airport_reset(int bus, int slot, int func)
+{
+	void __iomem *mmio;
+	u16 pmcsr;
+	u64 addr;
+	int i;
+
+	if (!dmi_match(DMI_SYS_VENDOR, "Apple Inc."))
+		return;
+
+	/* Card may have been put into PCI_D3hot by grub quirk */
+	pmcsr = read_pci_config_16(bus, slot, func, BCM4331_PM_CAP + PCI_PM_CTRL);
+
+	if ((pmcsr & PCI_PM_CTRL_STATE_MASK) != PCI_D0) {
+		pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
+		write_pci_config_16(bus, slot, func, BCM4331_PM_CAP + PCI_PM_CTRL, pmcsr);
+		mdelay(10);
+
+		pmcsr = read_pci_config_16(bus, slot, func, BCM4331_PM_CAP + PCI_PM_CTRL);
+		if ((pmcsr & PCI_PM_CTRL_STATE_MASK) != PCI_D0) {
+			dev_err("Cannot power up Apple AirPort card\n");
+			return;
+		}
+	}
+
+	addr  =      read_pci_config(bus, slot, func, PCI_BASE_ADDRESS_0);
+	addr |= (u64)read_pci_config(bus, slot, func, PCI_BASE_ADDRESS_1) << 32;
+	addr &= PCI_BASE_ADDRESS_MEM_MASK;
+
+	mmio = early_ioremap(addr, BCM4331_MMIO_SIZE);
+	if (!mmio) {
+		dev_err("Cannot iomap Apple AirPort card\n");
+		return;
+	}
+
+	pr_info("Resetting Apple AirPort card (left enabled by EFI)\n");
+
+	for (i = 0; bcma_aread32(BCMA_RESET_ST) && i < 30; i++)
+		udelay(10);
+
+	bcma_awrite32(BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
+	bcma_aread32(BCMA_RESET_CTL);
+	udelay(1);
+
+	bcma_awrite32(BCMA_RESET_CTL, 0);
+	bcma_aread32(BCMA_RESET_CTL);
+	udelay(10);
+
+	early_iounmap(mmio, BCM4331_MMIO_SIZE);
+}
+
 #define QFLAG_APPLY_ONCE 	0x1
 #define QFLAG_APPLIED		0x2
 #define QFLAG_DONE		(QFLAG_APPLY_ONCE|QFLAG_APPLIED)
@@ -222,6 +285,8 @@ static struct chipset early_qrk[] __init
 	  PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs },
 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS,
 	  PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs_contd },
+	{ PCI_VENDOR_ID_BROADCOM, 0x4331,
+	  PCI_CLASS_NETWORK_OTHER, PCI_ANY_ID, 0, apple_airport_reset},
 	{}
 };
 
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -8,8 +8,6 @@
 #include <linux/bcma/bcma.h>
 #include <linux/delay.h>
 
-#define BCMA_CORE_SIZE		0x1000
-
 struct bcma_bus;
 
 /* main.c */
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -124,6 +124,7 @@ struct bcma_host_ops {
 #define BCMA_CORE_DEFAULT		0xFFF
 
 #define BCMA_MAX_NR_CORES		16
+#define BCMA_CORE_SIZE			0x1000
 
 struct bcma_device {
 	struct bcma_bus *bus;
--- a/include/linux/bcma/bcma_regs.h
+++ b/include/linux/bcma/bcma_regs.h
@@ -35,6 +35,7 @@
 #define  BCMA_IOST_BIST_DONE		0x8000
 #define BCMA_RESET_CTL			0x0800
 #define  BCMA_RESET_CTL_RESET		0x0001
+#define BCMA_RESET_ST			0x0804
 
 /* BCMA PCI config space registers. */
 #define BCMA_PCI_PMCSR			0x44

^ permalink raw reply

* [PATCH 3.16 057/346] x86/quirks: Add early quirk to reset Apple AirPort card
From: Ben Hutchings @ 2016-11-14  0:14 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: akpm, Denys Vlasenko, Peter Zijlstra, Brian Gerst, Michael Buesch,
	Lukas Wunner, Chris Milsted, Yinghai Lu, Linus Torvalds,
	H. Peter Anvin, Matthew Garrett, Rafał Miłecki,
	Thomas Gleixner, linux-pci, Ingo Molnar, linux-wireless,
	Borislav Petkov, Josh Poimboeuf, b43-dev, Matt Fleming,
	Konstantin Simanov, Andy Lutomirski, Andrew Worsley,
	Bryan Paradis, Chris Bainbridge, Bjorn Helgaas
In-Reply-To: <lsq.1479082458.755945576@decadent.org.uk>

3.16.39-rc1 review patch.  If anyone has any objections, please let me know.

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

From: Lukas Wunner <lukas@wunner.de>

commit abb2bafd295fe962bbadc329dbfb2146457283ac upstream.

The EFI firmware on Macs contains a full-fledged network stack for
downloading OS X images from osrecovery.apple.com. Unfortunately
on Macs introduced 2011 and 2012, EFI brings up the Broadcom 4331
wireless card on every boot and leaves it enabled even after
ExitBootServices has been called. The card continues to assert its IRQ
line, causing spurious interrupts if the IRQ is shared. It also corrupts
memory by DMAing received packets, allowing for remote code execution
over the air. This only stops when a driver is loaded for the wireless
card, which may be never if the driver is not installed or blacklisted.

The issue seems to be constrained to the Broadcom 4331. Chris Milsted
has verified that the newer Broadcom 4360 built into the MacBookPro11,3
(2013/2014) does not exhibit this behaviour. The chances that Apple will
ever supply a firmware fix for the older machines appear to be zero.

The solution is to reset the card on boot by writing to a reset bit in
its mmio space. This must be done as an early quirk and not as a plain
vanilla PCI quirk to successfully combat memory corruption by DMAed
packets: Matthew Garrett found out in 2012 that the packets are written
to EfiBootServicesData memory (http://mjg59.dreamwidth.org/11235.html).
This type of memory is made available to the page allocator by
efi_free_boot_services(). Plain vanilla PCI quirks run much later, in
subsys initcall level. In-between a time window would be open for memory
corruption. Random crashes occurring in this time window and attributed
to DMAed packets have indeed been observed in the wild by Chris
Bainbridge.

When Matthew Garrett analyzed the memory corruption issue in 2012, he
sought to fix it with a grub quirk which transitions the card to D3hot:
http://git.savannah.gnu.org/cgit/grub.git/commit/?id=9d34bb85da56

This approach does not help users with other bootloaders and while it
may prevent DMAed packets, it does not cure the spurious interrupts
emanating from the card. Unfortunately the card's mmio space is
inaccessible in D3hot, so to reset it, we have to undo the effect of
Matthew's grub patch and transition the card back to D0.

Note that the quirk takes a few shortcuts to reduce the amount of code:
The size of BAR 0 and the location of the PM capability is identical
on all affected machines and therefore hardcoded. Only the address of
BAR 0 differs between models. Also, it is assumed that the BCMA core
currently mapped is the 802.11 core. The EFI driver seems to always take
care of this.

Michael Büsch, Bjorn Helgaas and Matt Fleming contributed feedback
towards finding the best solution to this problem.

The following should be a comprehensive list of affected models:
    iMac13,1        2012  21.5"       [Root Port 00:1c.3 = 8086:1e16]
    iMac13,2        2012  27"         [Root Port 00:1c.3 = 8086:1e16]
    Macmini5,1      2011  i5 2.3 GHz  [Root Port 00:1c.1 = 8086:1c12]
    Macmini5,2      2011  i5 2.5 GHz  [Root Port 00:1c.1 = 8086:1c12]
    Macmini5,3      2011  i7 2.0 GHz  [Root Port 00:1c.1 = 8086:1c12]
    Macmini6,1      2012  i5 2.5 GHz  [Root Port 00:1c.1 = 8086:1e12]
    Macmini6,2      2012  i7 2.3 GHz  [Root Port 00:1c.1 = 8086:1e12]
    MacBookPro8,1   2011  13"         [Root Port 00:1c.1 = 8086:1c12]
    MacBookPro8,2   2011  15"         [Root Port 00:1c.1 = 8086:1c12]
    MacBookPro8,3   2011  17"         [Root Port 00:1c.1 = 8086:1c12]
    MacBookPro9,1   2012  15"         [Root Port 00:1c.1 = 8086:1e12]
    MacBookPro9,2   2012  13"         [Root Port 00:1c.1 = 8086:1e12]
    MacBookPro10,1  2012  15"         [Root Port 00:1c.1 = 8086:1e12]
    MacBookPro10,2  2012  13"         [Root Port 00:1c.1 = 8086:1e12]

For posterity, spurious interrupts caused by the Broadcom 4331 wireless
card resulted in splats like this (stacktrace omitted):

    irq 17: nobody cared (try booting with the "irqpoll" option)
    handlers:
    [<ffffffff81374370>] pcie_isr
    [<ffffffffc0704550>] sdhci_irq [sdhci] threaded [<ffffffffc07013c0>] sdhci_thread_irq [sdhci]
    [<ffffffffc0a0b960>] azx_interrupt [snd_hda_codec]
    Disabling IRQ #17

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=79301
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=111781
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=728916
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=895951#c16
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1009819
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1098621
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1149632#c5
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1279130
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1332732
Tested-by: Konstantin Simanov <k.simanov@stlk.ru>        # [MacBookPro8,1]
Tested-by: Lukas Wunner <lukas@wunner.de>                # [MacBookPro9,1]
Tested-by: Bryan Paradis <bryan.paradis@gmail.com>       # [MacBookPro9,2]
Tested-by: Andrew Worsley <amworsley@gmail.com>          # [MacBookPro10,1]
Tested-by: Chris Bainbridge <chris.bainbridge@gmail.com> # [MacBookPro10,2]
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Acked-by: Rafał Miłecki <zajec5@gmail.com>
Acked-by: Matt Fleming <matt@codeblueprint.co.uk>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Chris Milsted <cmilsted@redhat.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Matthew Garrett <mjg59@srcf.ucam.org>
Cc: Michael Buesch <m@bues.ch>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: b43-dev@lists.infradead.org
Cc: linux-pci@vger.kernel.org
Cc: linux-wireless@vger.kernel.org
Link: http://lkml.kernel.org/r/48d0972ac82a53d460e5fce77a07b2560db95203.1465690253.git.lukas@wunner.de
[ Did minor readability edits. ]
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
 arch/x86/kernel/early-quirks.c | 64 ++++++++++++++++++++++++++++++++++++++++++
 drivers/bcma/bcma_private.h    |  2 --
 include/linux/bcma/bcma.h      |  1 +
 3 files changed, 65 insertions(+), 2 deletions(-)

--- a/arch/x86/kernel/early-quirks.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -11,7 +11,11 @@
 
 #include <linux/pci.h>
 #include <linux/acpi.h>
+#include <linux/delay.h>
+#include <linux/dmi.h>
 #include <linux/pci_ids.h>
+#include <linux/bcma/bcma.h>
+#include <linux/bcma/bcma_regs.h>
 #include <drm/i915_drm.h>
 #include <asm/pci-direct.h>
 #include <asm/dma.h>
@@ -21,6 +25,9 @@
 #include <asm/iommu.h>
 #include <asm/gart.h>
 #include <asm/irq_remapping.h>
+#include <asm/early_ioremap.h>
+
+#define dev_err(msg)  pr_err("pci 0000:%02x:%02x.%d: %s", bus, slot, func, msg)
 
 static void __init fix_hypertransport_config(int num, int slot, int func)
 {
@@ -572,6 +579,61 @@ static void __init force_disable_hpet(in
 #endif
 }
 
+#define BCM4331_MMIO_SIZE	16384
+#define BCM4331_PM_CAP		0x40
+#define bcma_aread32(reg)	ioread32(mmio + 1 * BCMA_CORE_SIZE + reg)
+#define bcma_awrite32(reg, val)	iowrite32(val, mmio + 1 * BCMA_CORE_SIZE + reg)
+
+static void __init apple_airport_reset(int bus, int slot, int func)
+{
+	void __iomem *mmio;
+	u16 pmcsr;
+	u64 addr;
+	int i;
+
+	if (!dmi_match(DMI_SYS_VENDOR, "Apple Inc."))
+		return;
+
+	/* Card may have been put into PCI_D3hot by grub quirk */
+	pmcsr = read_pci_config_16(bus, slot, func, BCM4331_PM_CAP + PCI_PM_CTRL);
+
+	if ((pmcsr & PCI_PM_CTRL_STATE_MASK) != PCI_D0) {
+		pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
+		write_pci_config_16(bus, slot, func, BCM4331_PM_CAP + PCI_PM_CTRL, pmcsr);
+		mdelay(10);
+
+		pmcsr = read_pci_config_16(bus, slot, func, BCM4331_PM_CAP + PCI_PM_CTRL);
+		if ((pmcsr & PCI_PM_CTRL_STATE_MASK) != PCI_D0) {
+			dev_err("Cannot power up Apple AirPort card\n");
+			return;
+		}
+	}
+
+	addr  =      read_pci_config(bus, slot, func, PCI_BASE_ADDRESS_0);
+	addr |= (u64)read_pci_config(bus, slot, func, PCI_BASE_ADDRESS_1) << 32;
+	addr &= PCI_BASE_ADDRESS_MEM_MASK;
+
+	mmio = early_ioremap(addr, BCM4331_MMIO_SIZE);
+	if (!mmio) {
+		dev_err("Cannot iomap Apple AirPort card\n");
+		return;
+	}
+
+	pr_info("Resetting Apple AirPort card (left enabled by EFI)\n");
+
+	for (i = 0; bcma_aread32(BCMA_RESET_ST) && i < 30; i++)
+		udelay(10);
+
+	bcma_awrite32(BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
+	bcma_aread32(BCMA_RESET_CTL);
+	udelay(1);
+
+	bcma_awrite32(BCMA_RESET_CTL, 0);
+	bcma_aread32(BCMA_RESET_CTL);
+	udelay(10);
+
+	early_iounmap(mmio, BCM4331_MMIO_SIZE);
+}
 
 #define QFLAG_APPLY_ONCE 	0x1
 #define QFLAG_APPLIED		0x2
@@ -610,6 +672,8 @@ static struct chipset early_qrk[] __init
 	 */
 	{ PCI_VENDOR_ID_INTEL, 0x0f00,
 		PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
+	{ PCI_VENDOR_ID_BROADCOM, 0x4331,
+	  PCI_CLASS_NETWORK_OTHER, PCI_ANY_ID, 0, apple_airport_reset},
 	{}
 };
 
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -8,8 +8,6 @@
 #include <linux/bcma/bcma.h>
 #include <linux/delay.h>
 
-#define BCMA_CORE_SIZE		0x1000
-
 #define bcma_err(bus, fmt, ...) \
 	pr_err("bus%d: " fmt, (bus)->num, ##__VA_ARGS__)
 #define bcma_warn(bus, fmt, ...) \
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -153,6 +153,7 @@ struct bcma_host_ops {
 #define BCMA_CORE_DEFAULT		0xFFF
 
 #define BCMA_MAX_NR_CORES		16
+#define BCMA_CORE_SIZE			0x1000
 
 /* Chip IDs of PCIe devices */
 #define BCMA_CHIP_ID_BCM4313	0x4313

^ permalink raw reply

* RE: Problems getting mwifiex with sd8887 to work
From: Amitkumar Karwar @ 2016-11-14  5:01 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: linux-wireless@vger.kernel.org, Nishant Sarmukadam, Kalle Valo
In-Reply-To: <20161113141348.GA32086@katana>

> From: Wolfram Sang [mailto:wsa@the-dreams.de]
> Sent: Sunday, November 13, 2016 7:44 PM
> To: Amitkumar Karwar
> Cc: linux-wireless@vger.kernel.org; Nishant Sarmukadam; Kalle Valo
> Subject: Re: Problems getting mwifiex with sd8887 to work
> 
> > 0x242 command failure is expected for sd8887, as It's not supported.
> 
> Is the same true for 0x10f?
> 
> mwifiex_sdio mmc2:0001:1: CMD_RESP: cmd 0x10f error, result=0x2

Yes. Error code 2 here means command not supported by firmware.

Regards,
Amitkumar

^ permalink raw reply

* Re: Outdated wl12xx firmwares
From: Luca Coelho @ 2016-11-14  7:37 UTC (permalink / raw)
  To: Gary Bisson, linux-firmware, Maxim Altshul; +Cc: linux-wireless
In-Reply-To: <CAAMH-yvdCMMqMc5HBGtPTEYFS5s48hyRaBtQdEiM-GCDwbFcrA@mail.gmail.com>

Hi,
I'm CCing Maxim, since he seems to be the last developer from TI to
post patches for the WiLink drivers here.


On Thu, 2016-10-27 at 12:45 +0200, Gary Bisson wrote:
> Hi,
> 
> Adding linux-wireless in CC, hoping to get more traction.
> 
> Just checked the MAINTAINERS file of this driver and it is listed as
> 'Orphan', so is it ok if a non-TI person submits the up-to-date
> firmware files?

AFAICT, the license text in the github repository you pointed to is not
exactly the same as the one in linux-firmware.git.  So, not being a
lawyer, I don't know how you could handle that, since the license in
github explicitly says that you need to reproduce that license.


> Regards,
> Gary
> 
> On Fri, Oct 14, 2016 at 7:32 PM, Gary Bisson
> <gary.bisson@boundarydevices.com> wrote:
> > Hi,
> > 
> > I am wondering why the w127x and wl128x firmware files have not been
> > updated to their latest version (since Jan 2014)?
> > 
> > The current version in the linux-firmware repo are:
> > - 6.3.10.0.133 for single-role
> > - 6.5.7.0.42 for multi-role
> > 
> > Looking at TI's forum[1], they recommend using the latest one to avoid
> > issues like firmware reload:
> > - 6.3.10.0.139 for single-role
> > - 6.5.7.0.47 for multi-role
> > 
> > The up-to-date firmware files can be found in the following repo:
> > https://github.com/TI-OpenLink/ti-utils/tree/master/hw/firmware
> > 
> > What is the procedure to update them, does it need to be a TI employee
> > that sends the patch? The former wl12xx maintainer (Luciano Coelho)
> > seems to work for Intel now.

Right, I'm not working for TI anymore, so there's nothing that I can do
for you.  If I were you, I'd keep poking at current TI developers to
see if they can send these new FW versions to linux-firmware.git.  They
probably even have newer versions than the ones published in github.


> > Regards,
> > Gary
> > 
> > [1] https://e2e.ti.com/support/wireless_connectivity/wilink_wifi_bluetooth/f/307/p/350832/1236099#1236099


--
Cheers,
Luca.

^ permalink raw reply

* Re: [PATCH 04/10] rt2800: do not overwrite WPDMA_GLO_CFG_WP_DMA_BURST_SIZE
From: Stanislaw Gruszka @ 2016-11-14  8:42 UTC (permalink / raw)
  To: Mathias Kresin; +Cc: linux-wireless, Helmut Schaa
In-Reply-To: <48e4790b-7cb3-170e-eda1-11bce9934141@kresin.me>

On Sat, Nov 05, 2016 at 01:55:14PM +0100, Mathias Kresin wrote:
> 02.11.2016 15:10, Stanislaw Gruszka:
> >We already initlized WPDMA_GLO_CFG_WP_DMA_BURST_SIZE to 3 on
> >rt2800_init_registers().
> >
> >Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
> >---
> > drivers/net/wireless/ralink/rt2x00/rt2800lib.c |    1 -
> > 1 files changed, 0 insertions(+), 1 deletions(-)
> >
> >diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
> >index feceb13..9ecdc4c 100644
> >--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
> >+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
> >@@ -6756,7 +6756,6 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev)
> > 	rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
> > 	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1);
> > 	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1);
> >-	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 2);
> 
> More a notice than a potential issue since I don't have much
> knowledge about the driver/chip internals.
> 
> But WPDMA_GLO_CFG_WP_DMA_BURST_SIZE in rt2800_init_registers() is
> set conditionally for rt2x00_is_usb(rt2x00dev), where this one is
> set unconditionally. Not sure if this change has side effects.

Default HW setting of WP_DMA_BURTS_SIZE is 2, hence patch does not
change behaviour on PCI devices. However I looked at RT3290 and
RT5592 PCI vendor drivers and there this value is initialized to 3.
So I think we can remove is_usb condition in rt2800_init_registers().

Stanislaw

^ permalink raw reply

* Re: [PATCH 05/10] rt2800: make ba_size depend on ampdu_factor
From: Stanislaw Gruszka @ 2016-11-14  8:45 UTC (permalink / raw)
  To: Mathias Kresin; +Cc: linux-wireless, Helmut Schaa
In-Reply-To: <ebc4779b-a68b-f3b3-c8fc-87db9401a603@kresin.me>

On Sat, Nov 05, 2016 at 01:56:58PM +0100, Mathias Kresin wrote:
> 02.11.2016 15:11, Stanislaw Gruszka:
> >
> >-		sta_priv = sta_to_rt2x00_sta(sta);
> >+		txdesc->u.ht.mpdu_density = sta->ht_cap.ampdu_density;
> > 		txdesc->u.ht.wcid = sta_priv->wcid;
> >+
> >+		if (!(tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)) {
> >+			ba_size = IEEE80211_MIN_AMPDU_BUF;
> >+			ba_size <<= sta->ht_cap.ampdu_factor;
> >+			ba_size = min_t(int, 63, ba_size - 1);
> >+		}
> > 	}
> >
> > 	/*
> >@@ -345,7 +350,7 @@ static void rt2x00queue_create_tx_descriptor_ht(struct rt2x00_dev *rt2x00dev,
> > 		return;
> > 	}
> >
> >-	txdesc->u.ht.ba_size = 7;	/* FIXME: What value is needed? */
> >+	txdesc->u.ht.ba_size = ba_size;
> >
> > 	/*
> > 	 * Only one STBC stream is supported for now.
> >
> 
> Having this patch applied, the throughput on a vgv7510kw22 (RT3062F)
> in AP mode using LEDE head is decreased by somewhat around 10
> Mbits/sec. I'm using iperf3 for throughput tests and having this
> patch reverted the throughout is back to 80 Mbits/sec.
> 
> When bringing down the wifi interface the following messages are
> logged with the patch applied:
> 
> [  281.738373] ieee80211 phy0: rt2x00queue_flush_queue: Warning -
> Queue 2 failed to flush
> [  281.906380] ieee80211 phy0: rt2x00queue_flush_queue: Warning -
> Queue 2 failed to flush

Could you check below patch and see if it helps? If it does not,
could you printk sta->ht_cap.ampdu_density and ba_size values
and provide them here.

Thanks
Stanislaw 

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index 2515702..72c7948 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -4707,7 +4707,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
 	    rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070E))
 		rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 2);
 	else
-		rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 1);
+		rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 3;
 	rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_PSDU, 0);
 	rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_MPDU, 0);
 	rt2800_register_write(rt2x00dev, MAX_LEN_CFG, reg);

^ permalink raw reply related

* Re: [RFC] qtn: add FullMAC firmware for Quantenna QSR10G wifi device
From: Johannes Berg @ 2016-11-14  9:40 UTC (permalink / raw)
  To: IgorMitsyanko
  Cc: linux-wireless, btherthala, hwang, smaksimenko, dlebed,
	Igor Mitsyanko, Kamlesh Rath, Sergey Matyukevich, Avinash Patil,
	Ben Hutchings, Kyle McMartin
In-Reply-To: <a5075f50-25c6-18a1-bd5b-309927dacdab@quantenna.com>

On Mon, 2016-11-14 at 11:26 +0300, IgorMitsyanko wrote:
> Thanks, Johannes.
> 
> To clarify with you and Kalle, as persons involved with linux-
> wireless: is my understanding correct that submitting firmware into
> linux-fimware repository is a prerequisite to accepting new driver
> into linux-wireless?

I personally don't think it needs to be quite that strict, but I don't
think I've heard anyone else express an opinion either way.

Frankly, so far I only commented on the firmware patch because I
haven't had time to go over the driver code at all.

johannes

^ permalink raw reply

* Re: [PATCH 05/10] rt2800: make ba_size depend on ampdu_factor
From: Julian Calaby @ 2016-11-14  9:41 UTC (permalink / raw)
  To: Stanislaw Gruszka; +Cc: Mathias Kresin, linux-wireless, Helmut Schaa
In-Reply-To: <20161114084536.GB12372@redhat.com>

Hi Stainslaw,

On Mon, Nov 14, 2016 at 7:45 PM, Stanislaw Gruszka <sgruszka@redhat.com> wrote:
> On Sat, Nov 05, 2016 at 01:56:58PM +0100, Mathias Kresin wrote:
>> 02.11.2016 15:11, Stanislaw Gruszka:
>> >
>> >-            sta_priv = sta_to_rt2x00_sta(sta);
>> >+            txdesc->u.ht.mpdu_density = sta->ht_cap.ampdu_density;
>> >             txdesc->u.ht.wcid = sta_priv->wcid;
>> >+
>> >+            if (!(tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)) {
>> >+                    ba_size = IEEE80211_MIN_AMPDU_BUF;
>> >+                    ba_size <<= sta->ht_cap.ampdu_factor;
>> >+                    ba_size = min_t(int, 63, ba_size - 1);
>> >+            }
>> >     }
>> >
>> >     /*
>> >@@ -345,7 +350,7 @@ static void rt2x00queue_create_tx_descriptor_ht(struct rt2x00_dev *rt2x00dev,
>> >             return;
>> >     }
>> >
>> >-    txdesc->u.ht.ba_size = 7;       /* FIXME: What value is needed? */
>> >+    txdesc->u.ht.ba_size = ba_size;
>> >
>> >     /*
>> >      * Only one STBC stream is supported for now.
>> >
>>
>> Having this patch applied, the throughput on a vgv7510kw22 (RT3062F)
>> in AP mode using LEDE head is decreased by somewhat around 10
>> Mbits/sec. I'm using iperf3 for throughput tests and having this
>> patch reverted the throughout is back to 80 Mbits/sec.
>>
>> When bringing down the wifi interface the following messages are
>> logged with the patch applied:
>>
>> [  281.738373] ieee80211 phy0: rt2x00queue_flush_queue: Warning -
>> Queue 2 failed to flush
>> [  281.906380] ieee80211 phy0: rt2x00queue_flush_queue: Warning -
>> Queue 2 failed to flush
>
> Could you check below patch and see if it helps? If it does not,
> could you printk sta->ht_cap.ampdu_density and ba_size values
> and provide them here.
>
> Thanks
> Stanislaw
>
> diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
> index 2515702..72c7948 100644
> --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
> +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
> @@ -4707,7 +4707,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
>             rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070E))
>                 rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 2);
>         else
> -               rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 1);
> +               rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 3;

You're missing a closing parenthesis, so it isn't going to work unless
it's added back in.

>         rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_PSDU, 0);
>         rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_MPDU, 0);
>         rt2800_register_write(rt2x00dev, MAX_LEN_CFG, reg);

Thanks,

-- 
Julian Calaby

Email: julian.calaby@gmail.com
Profile: http://www.google.com/profiles/julian.calaby/

^ permalink raw reply

* Re: [PATCH 05/10] rt2800: make ba_size depend on ampdu_factor
From: Stanislaw Gruszka @ 2016-11-14  9:44 UTC (permalink / raw)
  To: Julian Calaby; +Cc: Mathias Kresin, linux-wireless, Helmut Schaa
In-Reply-To: <CAGRGNgU=3tRrdgzoiGjoGr6QguyYnQ2kadiaX+HWxm0jiKqaqw@mail.gmail.com>

Hi

On Mon, Nov 14, 2016 at 08:41:57PM +1100, Julian Calaby wrote:
> > -               rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 1);
> > +               rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 3;
> 
> You're missing a closing parenthesis, so it isn't going to work unless
> it's added back in.

Thanks for the notice, hopefully Mathias can fix that.

Stanislaw

^ permalink raw reply

* Re: [PATCH V3] qtnfmac: announcement of new FullMAC driver for Quantenna chipsets
From: Johannes Berg @ 2016-11-14  9:52 UTC (permalink / raw)
  To: igor.mitsyanko.os, linux-wireless
  Cc: btherthala, hwang, smaksimenko, dlebed, Sergey Matyukevich,
	Kamlesh Rath, Avinash Patil
In-Reply-To: <1478700000-11624-2-git-send-email-igor.mitsyanko.os@quantenna.com>


> +++ b/drivers/net/wireless/quantenna/qtnfmac/Kconfig
> @@ -0,0 +1,23 @@
> +config QTNFMAC
> +	tristate "Quantenna WiFi FullMAC WLAN driver"
> +	default n

No need to state that default explicitly, but it also doesn't really
matter.

> +	  it as a module, it will be called qtnfmac_pearl_pcie.ko.


Where did the "pearl" come from? You didn't mention that in the commit
log.

Also, are you planning to add any other things to this soon? It seems
to me that perhaps the PCIe option should be the only one that's user-
visible, selecting the other one internally?

> +	struct qtnf_bus_ops *bus_ops;

You should make that const and actually make all instances const, it's
better for security :)

> +/* Supported crypto cipher suits to be advertised to cfg80211 */
> +static const u32 qtnf_cipher_suites[] = {
> +	WLAN_CIPHER_SUITE_TKIP,
> +	WLAN_CIPHER_SUITE_CCMP,
> +	WLAN_CIPHER_SUITE_AES_CMAC,
> +};

I'm surprised - no WEP? No CMAC and GCMP/GMAC?


> +static int
> +qtnf_change_virtual_intf(struct wiphy *wiphy,
> +			 struct net_device *dev,
> +			 enum nl80211_iftype type, u32 *flags,
> +			 struct vif_params *params)
> +{
> +	struct qtnf_vif *vif;
> +	u8 *mac_addr;
> +
> +	vif = qtnf_netdev_get_priv(dev);
> +
> +	if (params)
> +		mac_addr = params->macaddr;
> +	else
> +		mac_addr = NULL;
> +
> +	if (qtnf_cmd_send_change_intf_type(vif, type, mac_addr)) {
> +		pr_err("failed to change interface type\n");
> +		return -EFAULT;

Maybe -EIO would be better.

> +struct wireless_dev *qtnf_add_virtual_intf(struct wiphy *wiphy,
> +					   const char *name,
> +					   unsigned char
> name_assign_type,
> +					   enum nl80211_iftype type,
> +					   u32 *flags,
> +					   struct vif_params
> *params)
> +{
> +	struct qtnf_wmac *mac;
> +	struct qtnf_vif *vif;
> +	u8 *mac_addr = NULL;
> +
> +	mac = wiphy_priv(wiphy);
> +
> +	if (!mac)
> +		return ERR_PTR(-EFAULT);
> +
> +	switch (type) {
> +	case NL80211_IFTYPE_STATION:
> +	case NL80211_IFTYPE_AP:
> +		vif = qtnf_get_free_vif(mac);
> +		if (!vif) {
> +			pr_err("could not get free private
> structure\n");
> +			return ERR_PTR(-EFAULT);
> +		}

This is probably fairly natural to do, and it's not the first driver to
do this (brcmfmac also does), but some users may assume that they can
add interfaces as much as they want, until they bring them up (netdev
open).

It's probably worth having a discussion about this behaviour difference
- not necessarily in the context of this driver submission though.

> +	if (qtnf_cmd_send_add_intf(vif, type, mac_addr)) {
> +		vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
> +		pr_err("failed to send add_intf command\n");
> +		return ERR_PTR(-EFAULT);

I can't really tell, does this leak "vif"?

OK I need to find another way to review this patch now, it's too big
for my email client to work responsively...

johannes

^ permalink raw reply

* Re: [RFC] qtn: add FullMAC firmware for Quantenna QSR10G wifi device
From: IgorMitsyanko @ 2016-11-14  8:26 UTC (permalink / raw)
  To: Johannes Berg
  Cc: linux-wireless, btherthala, hwang, smaksimenko, dlebed,
	Igor Mitsyanko, Kamlesh Rath, Sergey Matyukevich, Avinash Patil,
	Ben Hutchings, Kyle McMartin
In-Reply-To: <1478864146.4129.4.camel@sipsolutions.net>

Thanks, Johannes.

To clarify with you and Kalle, as persons involved with linux-wireless: 
is my understanding correct that submitting firmware into linux-fimware 
repository is a prerequisite to accepting new driver into linux-wireless?

There is an option to start Quantenna device from internal flash memory, 
no external binary files involved. If we will introduce this 
functionality and remove code handling external firmware for now (until 
firmware problem resolved), would that allow driver to be reviewed/accepted?

On 11/11/2016 02:35 PM, Johannes Berg wrote:
> Adding linux-firmware people to Cc, since presumably they don't
> necessarily read linux-wireless...
>
>> Johannes, from that perspective, who are the "redistributors"?
>> Specifically, is linux-firmware git repository considered a
>> redistributor or its just hosting files? I mean, at what moment
>> someone else other then Quantenna will start to be legally obliged to
>> make GPL code used in firmware available for others?
> Look, I don't know. I'd assume people who ship it, like any regular
> distro, would be (re)distributors thereof. "Normal" (non-GPL) firmware
> images come with a redistribution license, but that obviously can't
> work here.
>
> There's some info from Ben here regarding the carl9170 case:
> http://lkml.iu.edu/hypermail/linux/kernel/1605.3/01176.html
>
>> Personally I still hope that linux-firmware itself is not legally
>> concerned with what is the content of firmware its hosting, but looks
>> like there already was a precedent case  with carl9170 driver and
>> we have to somehow deal with it.
> That's really all I wanted to bring up. I'm not involved with the
> linux-firmware git tree.
>
>> There still may be a difference though: Quantenna is semiconductor
>> company only, software
>> used on actual products based on Quantenna chipsets is released by
>> other
>> companies.
>> I just want to present our legal team with a clear case (and position
>> of
>> Linux maintainers) so that they can
>> work with it and make decision on how to proceed.
>>
>>   From technical perspective, as I mentioned, SDK is quite huge and
>> include a lot of opensource
>> components including full Linux, I don't think its reasonable to have
>> it
>> inside linux-firmware tree.
>> What are the options to share it other then providing it on request
>> basis:
>> - git repository
>> - store tarball somewhere on official website
> Clearly that wasn't deemed appropriate for carl9170, so I don't see why
> it'd be different here.
>
> johannes

^ permalink raw reply

* Re: Problems with mwifiex_pcie firmware activation
From: Stanislaw Gruszka @ 2016-11-14 10:15 UTC (permalink / raw)
  To: Amitkumar Karwar; +Cc: Nishant Sarmukadam, linux-wireless@vger.kernel.org
In-Reply-To: <20160825150626.GA9256@redhat.com>

On Thu, Aug 25, 2016 at 05:06:26PM +0200, Stanislaw Gruszka wrote:
> On Fri, Aug 12, 2016 at 10:13:43AM +0200, Stanislaw Gruszka wrote:
> > On Fri, Aug 12, 2016 at 07:17:38AM +0000, Amitkumar Karwar wrote:
> > > The problem looks strange. The patch just splits mwifiex_check_fw_status() and increases poll count. It should not have any side-effects.
> > > Our code used to check winner status before this patch also.
> > 
> > Ok, I misread the patch. Anyway checking "winner status" seems
> > does not work well on some condition and prevent loading firmware
> > into device.
> 
> I debug this a bit more on latest wireless-testing-next tree + 3 patches
> I just posted and debug_mask=0x700000ff.
> 
> On broken system, we do not download FW to device when system is
> rebooted, due to PCI-E is not the winner. However if system is
> powered OFF and then powered ON, we do FW downloading. Hence
> download the new FW into device does not make it work as was
> my theory.
> 
> In attachments are full dmesgs of good/bad and reboot/power-off-on
> cases.
> 
> The difference is that on broken system FW (or HW) do not create
> new USB Bluetooth device (1286:2046) and do not report
> FIRMWARE_READY_PCIE. Additionally on reboot case there are errors
> from USB xhci.

It was discovered that not working device require pcie8897_uapsta.bin 
firmware from ubuntu package to work:
https://launchpad.net/~snappy-dev/+archive/ubuntu/snappy-devices/+sourcepub/5936055/+listing-archive-extra

Device initialize like this then:

[   15.374630] mwifiex_pcie 0000:02:00.0: info: FW download over, size 689624 bytes
[   16.101214] mwifiex_pcie 0000:02:00.0: WLAN FW is active
[   16.242825] mwifiex_pcie 0000:02:00.0: info: MWIFIEX VERSION: mwifiex 1.0 (15.150.13.p21) 
[   16.251231] mwifiex_pcie 0000:02:00.0: driver_version = mwifiex 1.0 (15.150.13.p21) 

I'm not sure where ubuntu get this 15.150.13.p21 version of firmware as
it seems it's not present nor in upstream linux-firmware repo not in
http://git.marvell.com/?p=mwifiex-firmware.git;a=summary

Anyway could you modify firmware to support this device or modify
driver to load 15.150.13.p21 if required and push this F/W image
upstream ?

Thanks
Stanislaw
 

^ permalink raw reply

* Re: [RFC] change mac80211_hwsim tx_rates to ieee80211_tx_rate
From: Benjamin Beichler @ 2016-11-14 10:20 UTC (permalink / raw)
  To: Johannes Berg, linux-wireless
In-Reply-To: <1478984929.4226.3.camel@sipsolutions.net>


>> So I would propose to put the whole struct into the netlink messages,
> This is a terrible idea, since internal changes to this struct would
> break the userland API/ABI. hwsim seems perhaps less important than
> most APIs, but there is wmediumd etc. already.
I agree with that, but there exist also other code in hwsim, which is
tightly coupled with the mac80211 API, as e.g., the usage of
IEEE80211_TX_MAX_RATES, which already broke older versions of wmediumd
or similar implementations. Maybe a review regarding such things would
be good to decouple the userspace daemon from the special kernel version.

>> but I think that will break up the communication to e.g. bob
>> copelands
>> wmediumd and similar simulations. I would like to have our
>> Implementation working with mainline kernels and therefore ask how we
>> could achieve this easily.
>>
>> Obviously, we could define another field in the hwsim messages, but
>> as bob copeland already stated, significantly more information within
>> the netlink messages could  intensify the timing overhead of hwsim.
> I don't think we have any other choice but add the relevant fields as
> proper attributes.

I'm totally fine with that. Nonetheless,  I would suggest to add the
flags to "struct hwsim_tx_rate", since the flags are also tightly
coupled to the rates and tries of a frame. To not break up things, we
could add the flags as a separate attribute in the struct and not as
part of the bitfield like in the original. This would be possible, due
to the "__packed" flag, but I'm also unsure, whether this is a really
good idea for a userspace API/ABI.


Benjamin

^ permalink raw reply

* [bug report] iwlwifi: mvm: use dev_coredumpsg()
From: Dan Carpenter @ 2016-11-14 11:20 UTC (permalink / raw)
  To: aviya.erenfeld; +Cc: linux-wireless

Hello Aviya Erenfeld,

The patch 7e62a699aafb: "iwlwifi: mvm: use dev_coredumpsg()" from Sep
20, 2016, leads to the following static checker warning:

	drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c:821 iwl_mvm_fw_error_dump()
	error: we previously assumed 'fw_error_dump->trans_ptr' could be null (see line 809)

drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c
   805  dump_trans_data:
   806          fw_error_dump->trans_ptr = iwl_trans_dump_data(mvm->trans,
   807                                                         mvm->fw_dump_trig);
   808          fw_error_dump->op_mode_len = file_len;
   809          if (fw_error_dump->trans_ptr)
   810                  file_len += fw_error_dump->trans_ptr->len;

We assume ->trans_ptr can be NULL.

   811          dump_file->file_len = cpu_to_le32(file_len);
   812  
   813          sg_dump_data = alloc_sgtable(file_len);

That probably means file_len is zero?  (didn't look).  That means
sg_dump_data is ZERO_SIZE_PTR (16).

   814          if (sg_dump_data) {
   815                  sg_pcopy_from_buffer(sg_dump_data,
   816                                       sg_nents(sg_dump_data),
   817                                       fw_error_dump->op_mode_ptr,
   818                                       fw_error_dump->op_mode_len, 0);
   819                  sg_pcopy_from_buffer(sg_dump_data,
   820                                       sg_nents(sg_dump_data),
   821                                       fw_error_dump->trans_ptr->data,

Leading to an oops.

   822                                       fw_error_dump->trans_ptr->len,
   823                                       fw_error_dump->op_mode_len);
   824                  dev_coredumpsg(mvm->trans->dev, sg_dump_data, file_len,
   825                                 GFP_KERNEL);
   826          }
   827          vfree(fw_error_dump->op_mode_ptr);
   828          vfree(fw_error_dump->trans_ptr);
   829          kfree(fw_error_dump);
   830  
   831  out:
   832          iwl_mvm_free_fw_dump_desc(mvm);
   833          mvm->fw_dump_trig = NULL;
   834          clear_bit(IWL_MVM_STATUS_DUMPING_FW_LOG, &mvm->status);
   835  }

regards,
dan carpenter

^ permalink raw reply

* Re: [PATCH] broadcom/brcm80211/brcmfmac/cfg80211 driver, bad regulatory domain frequency value
From: Arend Van Spriel @ 2016-11-14 11:22 UTC (permalink / raw)
  To: Gianfranco Costamagna, brcm80211-dev-list@broadcom.com,
	linux-wireless@vger.kernel.org
  Cc: nsmaldone@tierratelematics.com, Marco.Arlone@roj.com
In-Reply-To: <5474e850-1c52-c896-da9e-45720ed6d6ff@broadcom.com>

On 28-10-2016 22:41, Arend Van Spriel wrote:
> On 28-10-2016 18:15, Gianfranco Costamagna wrote:
>> (resending from my debian.org mail address, to avoid spam filtering)
>>
>> Hi Broadcom developers and linux wireless list.
>>
>> We found a possible issue in the cfg80211 implementation of the regulatory domain rules:
>>
>>         .reg_rules = {
>>                 /* IEEE 802.11b/g, channels 1..11 */
>>                 REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
>>
>>
>> the referred channel 11 has/should have a frequency of 2462, not 2472 (corresponding to channel 13).
>> Is this a typo in the code or the above comment?
>>
>> (I'm not sure why the override of reg.c is in place for 2.4 Ghz frequencies)
>>
>> Can you please double check and in case apply the attached patch?
> 
> checking.... stay tuned.

Hi Gianfranco,

Finally response. As it turns out the range was explcitly changed
enabling channels 12 and 13 to be used where applicable. They forgot to
update the comment.

Regards,
Arend

^ permalink raw reply

* Re: [PATCH] broadcom/brcm80211/brcmfmac/cfg80211 driver, bad regulatory domain frequency value
From: Arend Van Spriel @ 2016-11-14 11:36 UTC (permalink / raw)
  To: Gianfranco Costamagna, brcm80211-dev-list@broadcom.com,
	linux-wireless@vger.kernel.org
  Cc: nsmaldone@tierratelematics.com, Marco.Arlone@roj.com
In-Reply-To: <233918815.6357602.1479123253455@mail.yahoo.com>

On 14-11-2016 12:34, Gianfranco Costamagna wrote:
> Hi Arend,
> 
> 
>> Finally response. As it turns out the range was explcitly changed
> 
>> enabling channels 12 and 13 to be used where applicable. They forgot to
>> update the comment.
> 
> 
> so, the struct in net/wireless/reg.c is actually used in that case?
> 
> static const struct ieee80211_regdomain world_regdom = {
> 
> do you plan to update the comment?

Well, not before you pointed it out ;-). You are welcome to send a patch
fixing it. Otherwise, I will take care of it.

Regards,
Arend

^ permalink raw reply

* Re: [PATCH] broadcom/brcm80211/brcmfmac/cfg80211 driver, bad regulatory domain frequency value
From: Gianfranco Costamagna @ 2016-11-14 11:34 UTC (permalink / raw)
  To: Arend Van Spriel, brcm80211-dev-list@broadcom.com,
	linux-wireless@vger.kernel.org
  Cc: nsmaldone@tierratelematics.com, Marco.Arlone@roj.com
In-Reply-To: <0812c8f2-f0ce-c62c-5f09-fa46dafd630f@broadcom.com>

Hi Arend,


>Finally response. As it turns out the range was explcitly changed

>enabling channels 12 and 13 to be used where applicable. They forgot to
>update the comment.


so, the struct in net/wireless/reg.c is actually used in that case?

static const struct ieee80211_regdomain world_regdom = {

do you plan to update the comment?

thanks!

Gianfranco

^ permalink raw reply

* Re: [PATCH] broadcom/brcm80211/brcmfmac/cfg80211 driver, bad regulatory domain frequency value
From: Gianfranco Costamagna @ 2016-11-14 11:47 UTC (permalink / raw)
  To: Arend Van Spriel, brcm80211-dev-list@broadcom.com,
	linux-wireless@vger.kernel.org
  Cc: nsmaldone@tierratelematics.com, Marco.Arlone@roj.com
In-Reply-To: <fba3cf06-917f-f1c9-6735-f166a18aa222@broadcom.com>

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

Hi Arend,



>Well, not before you pointed it out ;-). You are welcome to send a patch
>fixing it. Otherwise, I will take care of it.


attaching a format-patch like version.
I don't think we need a Tested-by or whatever, because it is just a typo in a comment.
(this is my first contribution, feel free to rebase or change whatever you prefer
to make it in line with other styles)

(I gave authorship to Marco, the first one who discovered such typo)

thanks!

G.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-cfg80211-fix-typo-in-REG-channel-frequency-comment.patch --]
[-- Type: text/x-diff, Size: 1229 bytes --]

From bf0cdd8ad27833639447a3071d662f79a7219b1d Mon Sep 17 00:00:00 2001
From: Arlone Marco <marco.arlone@roj.com>
Date: Sat, 22 Oct 2016 15:08:35 +0200
Subject: [PATCH] broadcom cfg80211: fix typo in REG channel frequency comment

frequency 2472 corresponds to channel 13, not channel 11

Signed-off-by: Gianfranco Costamagna <gianfranco.costamagna@abinsula.com>
Signed-off-by: Nicola Smaldone <nicola.smaldone@tierraservice.com>
Signed-off-by: Arlone Marco <marco.arlone@roj.com>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index b777e1b..b4d8b1b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -203,7 +203,7 @@ static const struct ieee80211_regdomain brcmf_regdom = {
 	.n_reg_rules = 4,
 	.alpha2 =  "99",
 	.reg_rules = {
-		/* IEEE 802.11b/g, channels 1..11 */
+		/* IEEE 802.11b/g, channels 1..13 */
 		REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
 		/* If any */
 		/* IEEE 802.11 channel 14 - Only JP enables
-- 
2.7.4


^ permalink raw reply related

* [PATCH 1/5] rsi: Device configuration bootup parameters updated
From: Prameela Rani Garnepudi @ 2016-11-14 12:15 UTC (permalink / raw)
  To: linux-wireless
  Cc: kvalo, johannes.berg, hofrat, xypron.glpk, prameela.garnepudi,
	Prameela Rani Garnepudi

Switch clock info values are changed in the firmware for both 20MHZ
and 40MHZ modes. Hence these values which are configured through boot
parameters request frame are updated. Also three other power save
related parameters are added to boot up parameters.

Signed-off-by: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>
---
 drivers/net/wireless/rsi/rsi_91x_mgmt.c    | 30 +++++++++++++++++-------
 drivers/net/wireless/rsi/rsi_boot_params.h | 37 +++++++++++++++++++++++++++++-
 2 files changed, 58 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index 35c14cc..8db377b 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -18,6 +18,7 @@
 #include "rsi_mgmt.h"
 #include "rsi_common.h"
 
+/* Bootup Parameters for 20MHz */
 static struct bootup_params boot_params_20 = {
 	.magic_number = cpu_to_le16(0x5aa5),
 	.crystal_good_time = 0x0,
@@ -28,6 +29,7 @@ static struct bootup_params boot_params_20 = {
 	.rtls_timestamp_en = 0x0,
 	.host_spi_intr_cfg = 0x0,
 	.device_clk_info = {{
+		/* WLAN params */
 		.pll_config_g = {
 			.tapll_info_g = {
 				.pll_reg_1 = cpu_to_le16((TA_PLL_N_VAL_20 << 8)|
@@ -45,12 +47,13 @@ static struct bootup_params boot_params_20 = {
 			}
 		},
 		.switch_clk_g = {
-			.switch_clk_info = cpu_to_le16(BIT(3)),
-			.bbp_lmac_clk_reg_val = cpu_to_le16(0x121),
-			.umac_clock_reg_config = 0x0,
-			.qspi_uart_clock_reg_config = 0x0
+			.switch_clk_info = cpu_to_le16(0xB),
+			.bbp_lmac_clk_reg_val = cpu_to_le16(0x111),
+			.umac_clock_reg_config = cpu_to_le16(0x48),
+			.qspi_uart_clock_reg_config = cpu_to_le16(0x1211)
 		}
 	},
+	/* Bluetooth params */
 	{
 		.pll_config_g = {
 			.tapll_info_g = {
@@ -75,6 +78,7 @@ static struct bootup_params boot_params_20 = {
 			.qspi_uart_clock_reg_config = 0x0
 		}
 	},
+	/* Zigbee params */
 	{
 		.pll_config_g = {
 			.tapll_info_g = {
@@ -99,6 +103,7 @@ static struct bootup_params boot_params_20 = {
 			.qspi_uart_clock_reg_config = 0x0
 		}
 	} },
+	/* ULP Params */
 	.buckboost_wakeup_cnt = 0x0,
 	.pmu_wakeup_wait = 0x0,
 	.shutdown_wait_time = 0x0,
@@ -106,9 +111,13 @@ static struct bootup_params boot_params_20 = {
 	.wdt_prog_value = 0x0,
 	.wdt_soc_rst_delay = 0x0,
 	.dcdc_operation_mode = 0x0,
-	.soc_reset_wait_cnt = 0x0
+	.soc_reset_wait_cnt = 0x0,
+	.waiting_time_at_fresh_sleep = 0x0,
+	.max_threshold_to_avoid_sleep = 0x0,
+	.beacon_resedue_alg_en = 0,
 };
 
+/* Bootup parameters for 40MHz */
 static struct bootup_params boot_params_40 = {
 	.magic_number = cpu_to_le16(0x5aa5),
 	.crystal_good_time = 0x0,
@@ -136,12 +145,13 @@ static struct bootup_params boot_params_40 = {
 			}
 		},
 		.switch_clk_g = {
-			.switch_clk_info = cpu_to_le16(0x09),
+			.switch_clk_info = cpu_to_le16(0xB),
 			.bbp_lmac_clk_reg_val = cpu_to_le16(0x1121),
 			.umac_clock_reg_config = cpu_to_le16(0x48),
-			.qspi_uart_clock_reg_config = 0x0
+			.qspi_uart_clock_reg_config = cpu_to_le16(0x1211) 
 		}
 	},
+	/* Bluetooth Params */
 	{
 		.pll_config_g = {
 			.tapll_info_g = {
@@ -190,6 +200,7 @@ static struct bootup_params boot_params_40 = {
 			.qspi_uart_clock_reg_config = 0x0
 		}
 	} },
+	/* ULP Params */
 	.buckboost_wakeup_cnt = 0x0,
 	.pmu_wakeup_wait = 0x0,
 	.shutdown_wait_time = 0x0,
@@ -197,7 +208,10 @@ static struct bootup_params boot_params_40 = {
 	.wdt_prog_value = 0x0,
 	.wdt_soc_rst_delay = 0x0,
 	.dcdc_operation_mode = 0x0,
-	.soc_reset_wait_cnt = 0x0
+	.soc_reset_wait_cnt = 0x0,
+	.waiting_time_at_fresh_sleep = 0x0,
+	.max_threshold_to_avoid_sleep = 0x0,
+	.beacon_resedue_alg_en = 0,
 };
 
 static u16 mcs[] = {13, 26, 39, 52, 78, 104, 117, 130};
diff --git a/drivers/net/wireless/rsi/rsi_boot_params.h b/drivers/net/wireless/rsi/rsi_boot_params.h
index 5e2721f..0d77aeb 100644
--- a/drivers/net/wireless/rsi/rsi_boot_params.h
+++ b/drivers/net/wireless/rsi/rsi_boot_params.h
@@ -99,11 +99,43 @@ struct device_clk_info {
 
 struct bootup_params {
 	__le16 magic_number;
+#define LOADED_TOKEN  0x5AA5   /* Bootup params are installed by host
+				* or OTP/FLASH (Bootloader)
+				*/
+#define ROM_TOKEN     0x55AA   /* Bootup params are taken from ROM
+				* itself in MCU mode.
+				*/
 	__le16 crystal_good_time;
 	__le32 valid;
+#define CRYSTAL_GOOD_TIME                BIT(0)
+#define BOOTUP_MODE_INFO                 BIT(1)
+#define DIGITAL_LOOP_BACK_PARAMS         BIT(2)
+#define RTLS_TIMESTAMP_EN                BIT(3)
+#define HOST_SPI_INTR_CFG                BIT(4)
+#define WIFI_TAPLL_CONFIGS               BIT(5)
+#define WIFI_PLL960_CONFIGS              BIT(6)
+#define WIFI_AFEPLL_CONFIGS              BIT(7)
+#define WIFI_SWITCH_CLK_CONFIGS          BIT(8)
+#define BT_TAPLL_CONFIGS                 BIT(9)
+#define BT_PLL960_CONFIGS                BIT(10)
+#define BT_AFEPLL_CONFIGS                BIT(11)
+#define BT_SWITCH_CLK_CONFIGS            BIT(12)
+#define ZB_TAPLL_CONFIGS                 BIT(13)
+#define ZB_PLL960_CONFIGS                BIT(14)
+#define ZB_AFEPLL_CONFIGS                BIT(15)
+#define ZB_SWITCH_CLK_CONFIGS            BIT(16)
+#define BUCKBOOST_WAIT_INFO              BIT(17)
+#define PMU_WAKEUP_SHUTDOWN_W            BIT(18)
+#define WDT_PROG_VALUES                  BIT(19)
+#define WDT_RESET_DELAY_VALUE            BIT(20)
+#define DCDC_OPERATION_MODE_VALID        BIT(21)
+#define PMU_SLP_CLKOUT_SEL               BIT(22)
+#define SOC_RESET_WAIT_CNT               BIT(23)
 	__le32 reserved_for_valids;
 	__le16 bootup_mode_info;
-	/* configuration used for digital loop back */
+#define BT_COEXIST                       BIT(0)
+#define BOOTUP_MODE                     (BIT(2) | BIT(1))
+#define CUR_DEV_MODE                    (bootup_params.bootup_mode_info >> 1)
 	__le16 digital_loop_back_params;
 	__le16 rtls_timestamp_en;
 	__le16 host_spi_intr_cfg;
@@ -122,5 +154,8 @@ struct bootup_params {
 	/* dcdc modes configs */
 	__le32 dcdc_operation_mode;
 	__le32 soc_reset_wait_cnt;
+	__le32 waiting_time_at_fresh_sleep;
+	__le32 max_threshold_to_avoid_sleep;
+	u8 beacon_resedue_alg_en;
 } __packed;
 #endif
-- 
2.4.11

^ permalink raw reply related

* [PATCH 3/5] rsi: Added support for configuring tx power
From: Prameela Rani Garnepudi @ 2016-11-14 12:17 UTC (permalink / raw)
  To: linux-wireless
  Cc: kvalo, johannes.berg, hofrat, xypron.glpk, prameela.garnepudi,
	Prameela Rani Garnepudi

TX power can be configured from iwconfig, iw or from mac80211 when
regulatory changes are done. Hence support for configuring tx power
to device is added. This can be done by sending RADIO_PARAMS_UPDATE
command frame to device with upated tx power value.

Signed-off-by: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>
---
 drivers/net/wireless/rsi/rsi_91x_mac80211.c | 37 +++++++++++++++
 drivers/net/wireless/rsi/rsi_91x_mgmt.c     | 38 +++++++++++++++
 drivers/net/wireless/rsi/rsi_main.h         |  2 +
 drivers/net/wireless/rsi/rsi_mgmt.h         | 72 ++++++++++++++++++-----------
 4 files changed, 123 insertions(+), 26 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index fa9498d..ba21608 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -397,6 +397,37 @@ static int rsi_channel_change(struct ieee80211_hw *hw)
 }
 
 /**
+ * rsi_config_power() - This function configures tx power in device
+ * @hw: Pointer to the ieee80211_hw structure.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+static int rsi_config_power(struct ieee80211_hw *hw)
+{
+	struct rsi_hw *adapter = hw->priv;
+	struct rsi_common *common = adapter->priv;
+	struct ieee80211_conf *conf = &hw->conf;
+	int status;
+
+	if (adapter->sc_nvifs <= 0) {
+		rsi_dbg(ERR_ZONE, "%s: No virtual interface found\n", __func__);
+		return -EINVAL;
+	}
+
+	rsi_dbg(INFO_ZONE,
+		"%s: Set tx power: %d dBM\n", __func__, conf->power_level);
+
+	if (conf->power_level == common->tx_power)
+		return 0;
+
+	common->tx_power = conf->power_level;
+
+	status = rsi_send_radio_params_update(common);
+
+	return status;
+}
+
+/**
  * rsi_mac80211_config() - This function is a handler for configuration
  *			   requests. The stack calls this function to
  *			   change hardware configuration, e.g., channel.
@@ -417,6 +448,12 @@ static int rsi_mac80211_config(struct ieee80211_hw *hw,
 	if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
 		status = rsi_channel_change(hw);
 
+	/* tx power */
+	if (changed & IEEE80211_CONF_CHANGE_POWER) {
+		rsi_dbg(INFO_ZONE, "%s: Configuring Power\n", __func__);
+		status = rsi_config_power(hw);
+	}
+
 	mutex_unlock(&common->mutex);
 
 	return status;
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index ae4a814..2e8e5dc 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -964,6 +964,44 @@ int rsi_set_channel(struct rsi_common *common, u16 channel)
 }
 
 /**
+ * rsi_send_radio_params_update() - This function sends the radio
+ *				parameters update to device
+ * @common: Pointer to the driver private structure.
+ * @channel: Channel value to be set.
+ *
+ * Return: 0 on success, corresponding error code on failure.
+ */
+int rsi_send_radio_params_update(struct rsi_common *common)
+{
+	struct rsi_mac_frame *mgmt_frame;
+	struct sk_buff *skb = NULL;
+
+	rsi_dbg(MGMT_TX_ZONE,
+		"%s: Sending Radio Params update frame\n", __func__);
+
+	skb = dev_alloc_skb(FRAME_DESC_SZ);
+	if (!skb) {
+		rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
+			__func__);
+		return -ENOMEM;
+	}
+
+	memset(skb->data, 0, FRAME_DESC_SZ);
+	mgmt_frame = (struct rsi_mac_frame *)skb->data;
+
+	mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
+	mgmt_frame->desc_word[1] = cpu_to_le16(RADIO_PARAMS_UPDATE);
+	mgmt_frame->desc_word[3] = cpu_to_le16(BIT(0));
+
+	mgmt_frame->desc_word[3] |= cpu_to_le16(common->tx_power << 8);
+
+	skb_put(skb, FRAME_DESC_SZ);
+
+	return rsi_send_internal_mgmt_frame(common, skb);
+}
+
+
+/**
  * rsi_compare() - This function is used to compare two integers
  * @a: pointer to the first integer
  * @b: pointer to the second integer
diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h
index dcd0957..3938f13 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -204,6 +204,8 @@ struct rsi_common {
 	struct cqm_info cqm_info;
 
 	bool hw_data_qs_blocked;
+	
+	int tx_power;
 };
 
 struct rsi_hw {
diff --git a/drivers/net/wireless/rsi/rsi_mgmt.h b/drivers/net/wireless/rsi/rsi_mgmt.h
index 40e8f8e..6547ae7 100644
--- a/drivers/net/wireless/rsi/rsi_mgmt.h
+++ b/drivers/net/wireless/rsi/rsi_mgmt.h
@@ -169,32 +169,51 @@ enum sta_notify_events {
 
 /* Send Frames Types */
 enum cmd_frame_type {
-	TX_DOT11_MGMT,
-	RESET_MAC_REQ,
-	RADIO_CAPABILITIES,
-	BB_PROG_VALUES_REQUEST,
-	RF_PROG_VALUES_REQUEST,
-	WAKEUP_SLEEP_REQUEST,
-	SCAN_REQUEST,
-	TSF_UPDATE,
-	PEER_NOTIFY,
-	BLOCK_HW_QUEUE,
-	SET_KEY_REQ,
-	AUTO_RATE_IND,
-	BOOTUP_PARAMS_REQUEST,
-	VAP_CAPABILITIES,
-	EEPROM_READ_TYPE ,
-	EEPROM_WRITE,
-	GPIO_PIN_CONFIG ,
-	SET_RX_FILTER,
-	AMPDU_IND,
-	STATS_REQUEST_FRAME,
-	BB_BUF_PROG_VALUES_REQ,
-	BBP_PROG_IN_TA,
-	BG_SCAN_PARAMS,
-	BG_SCAN_PROBE_REQ,
-	CW_MODE_REQ,
-	PER_CMD_PKT
+	TX_DOT11_MGMT = 0,
+	RESET_MAC_REQ, /* 0x1 */
+	RADIO_CAPABILITIES, /* 0x2 */
+	BB_PROG_VALUES_REQUEST, /* 0x3 */
+	RF_PROG_VALUES_REQUEST, /* 0x4 */
+	WAKEUP_SLEEP_REQUEST, /* 0x5 */
+	SCAN_REQUEST, /* 0x6 */
+	TSF_UPDATE, /* 0x7 */
+	PEER_NOTIFY, /* 0x8 */
+	BLOCK_HW_QUEUE, /* 0x9 */
+	SET_KEY_REQ, /* 0xA */
+	AUTO_RATE_IND, /* 0xB */
+	BOOTUP_PARAMS_REQUEST, /* 0xC */
+	VAP_CAPABILITIES, /* 0xD */
+	EEPROM_READ_TYPE, /* 0xE */
+	EEPROM_WRITE, /* 0xF */
+	GPIO_PIN_CONFIG, /* 0x10 */
+	SET_RX_FILTER, /* 0x11 */
+	AMPDU_IND, /* 0x12 */
+	STATS_REQUEST, /* 0x13 */
+	BB_BUF_PROG_VALUES_REQ, /* 0x14 */
+	BBP_PROG_IN_TA, /* 0x15 */
+	BG_SCAN_PARAMS, /* 0x16 */
+	BG_SCAN_PROBE_REQ, /* 0x17 */
+	CW_MODE_REQ, /* 0x18 */
+	PER_CMD_PKT, /* 0x19 */
+	DEV_SLEEP_REQUEST, /* 0x1A */
+	DEV_WAKEUP_CNF,  /* 0x1B */
+	RF_LOOPBACK_REQ, /* 0x1C */
+	RF_LPBK_M3,  /* 0x1D */
+	RF_RESET_FRAME,  /* 0x1E */
+	LMAC_REG_OPS,  /* 0x1F */
+	ANT_SEL_FRAME, /* 0x20 */
+	CONFIRM, /* 0x21 */
+	WLAN_DE_REGISTER, /* 0x22 */
+	DEBUG_FRAME,  /* 0x23 */
+	HW_BMISS_HANDLE, /* 0x24 */
+	MULTICAST_ENABLE, /* 0x25 */
+	TX_MISC_IND, /* 0x26 */
+	VAP_DYNAMIC_UPDATE, /* 0x27 */
+	COMMON_DEV_CONFIG, /* 0x28 */
+	RADIO_PARAMS_UPDATE, /* 0x29 */
+	RADAR_REQUEST, /* 0x2A */
+	WOWLAN_CONFIG_PARAMS, /* 2B */
+	IAP_CONFIG, /* 0x2C */
 };
 
 struct rsi_mac_frame {
@@ -317,4 +336,5 @@ int rsi_send_mgmt_pkt(struct rsi_common *common, struct sk_buff *skb);
 int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb);
 int rsi_band_check(struct rsi_common *common);
 int rsi_send_rx_filter_frame(struct rsi_common *common, u16 rx_filter_word);
+int rsi_send_radio_params_update(struct rsi_common *common);
 #endif
-- 
2.4.11

^ permalink raw reply related

* [PATCH 4/5] rsi: Added support for antenna selection
From: Prameela Rani Garnepudi @ 2016-11-14 12:17 UTC (permalink / raw)
  To: linux-wireless
  Cc: kvalo, johannes.berg, hofrat, xypron.glpk, prameela.garnepudi,
	Prameela Rani Garnepudi

RSI 9113 device supports single antenna for tx and rx. Support for using
external is added. This can be configured from user space using iw.

Signed-off-by: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>
---
 drivers/net/wireless/rsi/rsi_91x_mac80211.c | 78 +++++++++++++++++++++++++++++
 drivers/net/wireless/rsi/rsi_91x_mgmt.c     | 33 ++++++++++++
 drivers/net/wireless/rsi/rsi_main.h         |  1 +
 drivers/net/wireless/rsi/rsi_mgmt.h         |  4 ++
 4 files changed, 116 insertions(+)

diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index ba21608..07314ea 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -1071,6 +1071,82 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw,
 	return 0;
 }
 
+/**
+ * rsi_mac80211_set_antenna() - This function is used to configure
+ *				tx and rx antennas.
+ * @hw: Pointer to the ieee80211_hw structure.
+ * @tx_ant: Bitmap for tx antenna
+ * @rx_ant: Bitmap for rx antenna
+ *
+ * Return: 0 on success, -1 on failure.
+ */
+static int rsi_mac80211_set_antenna(struct ieee80211_hw *hw,
+				    u32 tx_ant, u32 rx_ant)
+{
+	struct rsi_hw *adapter = hw->priv;
+	struct rsi_common *common = adapter->priv;
+	u32 antenna = 0;
+
+	if (tx_ant > 1 || rx_ant > 1) {
+		rsi_dbg(ERR_ZONE,
+			"Invalid antenna selection (tx: %d, rx:%d)\n",
+			tx_ant, rx_ant);
+		rsi_dbg(ERR_ZONE,
+			"Use 0 for int_ant, 1 for ext_ant\n");
+		return -EINVAL; 
+	}
+
+	rsi_dbg(INFO_ZONE, "%s: Antenna map Tx %x Rx %d\n",
+			__func__, tx_ant, rx_ant);
+
+	mutex_lock(&common->mutex);
+
+	antenna = tx_ant ? ANTENNA_SEL_UFL : ANTENNA_SEL_INT;
+	if (common->ant_in_use != antenna)
+		if (rsi_set_antenna(common, antenna))
+			goto fail_set_antenna;
+
+	rsi_dbg(INFO_ZONE, "(%s) Antenna path configured successfully\n",
+		tx_ant ? "UFL" : "INT");
+
+	common->ant_in_use = antenna;
+	
+	mutex_unlock(&common->mutex);
+	
+	return 0;
+
+fail_set_antenna:
+	rsi_dbg(ERR_ZONE, "%s: Failed.\n", __func__);
+	mutex_unlock(&common->mutex);
+	return -EINVAL;
+}
+
+/**
+ * rsi_mac80211_get_antenna() - This function is used to configure 
+ * 				tx and rx antennas.
+ *
+ * @hw: Pointer to the ieee80211_hw structure.
+ * @tx_ant: Bitmap for tx antenna
+ * @rx_ant: Bitmap for rx antenna
+ * 
+ * Return: 0 on success, -1 on failure.
+ */
+static int rsi_mac80211_get_antenna(struct ieee80211_hw *hw,
+				    u32 *tx_ant, u32 *rx_ant)
+{
+	struct rsi_hw *adapter = hw->priv;
+	struct rsi_common *common = adapter->priv;
+
+	mutex_lock(&common->mutex);
+
+	*tx_ant = (common->ant_in_use == ANTENNA_SEL_UFL) ? 1 : 0;
+	*rx_ant = 0;
+
+	mutex_unlock(&common->mutex);
+	
+	return 0;	
+}
+
 static struct ieee80211_ops mac80211_ops = {
 	.tx = rsi_mac80211_tx,
 	.start = rsi_mac80211_start,
@@ -1087,6 +1163,8 @@ static struct ieee80211_ops mac80211_ops = {
 	.ampdu_action = rsi_mac80211_ampdu_action,
 	.sta_add = rsi_mac80211_sta_add,
 	.sta_remove = rsi_mac80211_sta_remove,
+	.set_antenna = rsi_mac80211_set_antenna,
+	.get_antenna = rsi_mac80211_get_antenna,
 };
 
 /**
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index 2e8e5dc..16dc3ac 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -1326,6 +1326,39 @@ int rsi_send_rx_filter_frame(struct rsi_common *common, u16 rx_filter_word)
 }
 
 /**
+ * rsi_set_antenna() - This fuction handles antenna selection functionality.
+ *
+ * @common: Pointer to the driver private structure.
+ * @antenna: bitmap for tx antenna selection
+ *
+ * Return: 0 on Success, < 0 on failure
+ */
+int rsi_set_antenna(struct rsi_common *common,
+		    u8 antenna)
+{
+	struct rsi_mac_frame *mgmt_frame;
+	struct sk_buff *skb;
+
+	skb = dev_alloc_skb(FRAME_DESC_SZ);
+	if (!skb) {
+		rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
+			__func__);
+		return -ENOMEM;
+	}
+
+	memset(skb->data, 0, FRAME_DESC_SZ);
+	mgmt_frame = (struct rsi_mac_frame *)skb->data;
+
+	mgmt_frame->desc_word[1] = cpu_to_le16(ANT_SEL_FRAME);
+	mgmt_frame->desc_word[3] = cpu_to_le16(antenna & 0x00ff);
+	mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
+
+	skb_put(skb, FRAME_DESC_SZ);
+
+	return rsi_send_internal_mgmt_frame(common, skb);
+}
+
+/**
  * rsi_handle_ta_confirm_type() - This function handles the confirm frames.
  * @common: Pointer to the driver private structure.
  * @msg: Pointer to received packet.
diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h
index 3938f13..2405b30 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -206,6 +206,7 @@ struct rsi_common {
 	bool hw_data_qs_blocked;
 	
 	int tx_power;
+	u8 ant_in_use;
 };
 
 struct rsi_hw {
diff --git a/drivers/net/wireless/rsi/rsi_mgmt.h b/drivers/net/wireless/rsi/rsi_mgmt.h
index 6547ae7..1111c07 100644
--- a/drivers/net/wireless/rsi/rsi_mgmt.h
+++ b/drivers/net/wireless/rsi/rsi_mgmt.h
@@ -141,6 +141,9 @@
 #define RSI_SUPP_FILTERS	(FIF_ALLMULTI | FIF_PROBE_REQ |\
 				 FIF_BCN_PRBRESP_PROMISC)
 
+#define ANTENNA_SEL_INT			0x02 /* RF_OUT_2 / Integerated */
+#define ANTENNA_SEL_UFL			0x03 /* RF_OUT_1 / U.FL */
+
 /* Rx filter word definitions */
 #define PROMISCOUS_MODE			BIT(0)
 #define ALLOW_DATA_ASSOC_PEER		BIT(1)
@@ -337,4 +340,5 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb);
 int rsi_band_check(struct rsi_common *common);
 int rsi_send_rx_filter_frame(struct rsi_common *common, u16 rx_filter_word);
 int rsi_send_radio_params_update(struct rsi_common *common);
+int rsi_set_antenna(struct rsi_common *common, u8 antenna);
 #endif
-- 
2.4.11

^ 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