Linux wireless drivers development
 help / color / mirror / Atom feed
* RE: [PATCH v7 15/21] x86/split_lock: Add a sysfs interface to enable/disable split lock detection during run time
From: David Laight @ 2019-04-24 13:45 UTC (permalink / raw)
  To: 'Fenghua Yu', Thomas Gleixner
  Cc: Ingo Molnar, Borislav Petkov, H Peter Anvin, Paolo Bonzini,
	Dave Hansen, Ashok Raj, Peter Zijlstra, Ravi V Shankar,
	Xiaoyao Li, Christopherson Sean J, Kalle Valo, Michael Chan,
	linux-kernel, x86, kvm@vger.kernel.org, netdev@vger.kernel.org,
	linux-wireless@vger.kernel.org
In-Reply-To: <20190423204809.GD18776@romley-ivt3.sc.intel.com>

From: Fenghua Yu
> Sent: 23 April 2019 21:48
> 
> On Thu, Apr 18, 2019 at 08:41:30AM +0200, Thomas Gleixner wrote:
> > On Wed, 17 Apr 2019, Fenghua Yu wrote:
> > > On Thu, Apr 18, 2019 at 12:47:24AM +0200, Thomas Gleixner wrote:
> > > > On Wed, 17 Apr 2019, Fenghua Yu wrote:
> > > >
> > > > > The interface /sys/device/system/cpu/split_lock_detect is added
> > > > > to allow user to control split lock detection and show current split
> > > > > lock detection setting.
> > > > >
> > > > > Writing [yY1] or [oO][nN] to the file enables split lock detection and
> > > > > writing [nN0] or [oO][fF] disables split lock detection. Split lock
> > > > > detection is enabled or disabled on all CPUs.
> > > > >
> > > > > Reading the file returns current global split lock detection setting:
> > > > > 0: disabled
> > > > > 1: enabled
> > > >
> > > > Again, You explain WHAT this patch does and still there is zero
> > > > justification why this sysfs knob is needed at all. I still do not see any
> > > > reason why this knob should exist.
> > >
> > > An important application has split lock issues which are already discovered
> > > and need to be fixed. But before the issues are fixed, sysadmin still wants to
> > > run the application without rebooting the system, the sysfs knob can be useful
> > > to turn off split lock detection. After the application is done, split lock
> > > detection will be enabled again through the sysfs knob.
> >
> > Are you sure that you are talking about the real world? I might buy the
> > 'off' part somehow, but the 'on' part is beyond theoretical.
> >
> > Even the 'off' part is dubious on a multi user machine. I personally would
> > neither think about using the sysfs knob nor about rebooting the machine
> > simply because I'd consider a lock operation accross a cacheline an malicious
> > DoS attempt. Why would I allow that?
> >
> > So in reality the sysadmin will either move the workload to a machine w/o
> > the #AC magic or just tell the user to fix his crap.
> >
> > > Without the sysfs knob, sysadmin has to reboot the system with kernel option
> > > "no_split_lock_detect" to run the application before the split lock issues
> > > are fixed.
> > >
> > > Is this a valid justification why the sysfs knob is needed? If it is, I can
> > > add the justification in the next version.
> >
> > Why has this information not been in the changelog right away? I'm really
> > tired of asking the same questions and pointing you to
> > Documentation/process over and over.
> 
> So should I remove the sysfs knob patches in the next version?
> 
> Or add the following justification and still keep the sysfs knob patches?
> "To workaround or debug a split lock issue, the administrator may need to
> disable or enable split lock detection during run time without rebooting
> the system."

I've also not seen patches to fix all the places where 'lock bit' operations
get used on int [] data.
Testing had showed one structure that needed 'fixing', there are some others
that are in .bss/.data.
A kernel build could suddenly have them misaligned and crossing a cache line.

All the places that cast the pointer to the bit ops are suspect.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)


^ permalink raw reply

* [PATCH] brcm80211: potential NULL dereference in brcmf_cfg80211_vndr_cmds_dcmd_handler()
From: Dan Carpenter @ 2019-04-24  9:52 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: Franky Lin, Hante Meuleman, Chi-Hsien Lin, Wright Feng,
	Kalle Valo, linux-wireless, brcm80211-dev-list.pdl,
	brcm80211-dev-list, kernel-janitors

If "ret_len" is negative then it could lead to a NULL dereference.

The "ret_len" value comes from nl80211_vendor_cmd(), if it's negative
then we don't allocate the "dcmd_buf" buffer.  Then we pass "ret_len" to
brcmf_fil_cmd_data_set() where it is cast to a very high u32 value.
Most of the functions in that call tree check whether the buffer we pass
is NULL but there are at least a couple places which don't such as
brcmf_dbg_hex_dump() and brcmf_msgbuf_query_dcmd().  We memcpy() to and
from the buffer so it would result in a NULL dereference.

The fix is to change the types so that "ret_len" can't be negative.  (If
we memcpy() zero bytes to NULL, that's a no-op and doesn't cause an
issue).

Fixes: 1bacb0487d0e ("brcmfmac: replace cfg80211 testmode with vendor command")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c
index 8eff2753abad..d493021f6031 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c
@@ -35,9 +35,10 @@ static int brcmf_cfg80211_vndr_cmds_dcmd_handler(struct wiphy *wiphy,
 	struct brcmf_if *ifp;
 	const struct brcmf_vndr_dcmd_hdr *cmdhdr = data;
 	struct sk_buff *reply;
-	int ret, payload, ret_len;
+	unsigned int payload, ret_len;
 	void *dcmd_buf = NULL, *wr_pointer;
 	u16 msglen, maxmsglen = PAGE_SIZE - 0x100;
+	int ret;
 
 	if (len < sizeof(*cmdhdr)) {
 		brcmf_err("vendor command too short: %d\n", len);
@@ -65,7 +66,7 @@ static int brcmf_cfg80211_vndr_cmds_dcmd_handler(struct wiphy *wiphy,
 			brcmf_err("oversize return buffer %d\n", ret_len);
 			ret_len = BRCMF_DCMD_MAXLEN;
 		}
-		payload = max(ret_len, len) + 1;
+		payload = max_t(unsigned int, ret_len, len) + 1;
 		dcmd_buf = vzalloc(payload);
 		if (NULL == dcmd_buf)
 			return -ENOMEM;
-- 
2.18.0


^ permalink raw reply related

* Re: [PATCH] brcmfmac: remove the duplicate line of sending mail box interrupt
From: Arend Van Spriel @ 2019-04-24  8:46 UTC (permalink / raw)
  To: Wright Feng, franky.lin, hante.meuleman, kvalo, Chi-Hsien Lin
  Cc: linux-wireless, brcm80211-dev-list.pdl
In-Reply-To: <16a4dcd3418.2764.9b12b7fc0a3841636cfb5e919b41b954@broadcom.com>

On 4/24/2019 7:24 AM, Arend Van Spriel wrote:
> On April 22, 2019 4:47:31 AM Wright Feng <Wright.Feng@cypress.com> wrote:
> 
>> The line is duplicate so remove it from pcie.c. We don't need to send
>> host to dongle mail box interrupt twice after writing data.
> 
> Hi Wright,
> 
> Thanks for the patch. I am a bit early as it is not uncommon that 
> hardware requires an extra kick. Might be the case here for some chips. 
> Will follow-up on it.

Hi Wright,

I checked in our dhd driver code and it also does a double write. Turns 
out to be a hardware workaround so we need to keep this. It is worth a 
comment though.

Thanks,
Arend

^ permalink raw reply

* Re: [PATCH] mmc: dw_mmc: Disable SDIO interrupts while suspended to fix suspend/resume
From: Emil Renner Berthing @ 2019-04-24  8:19 UTC (permalink / raw)
  To: Douglas Anderson
  Cc: Jaehoon Chung, Ulf Hansson, Shawn Lin, Heiko Stuebner, linux-mmc,
	Brian Norris, linux-wireless, stable, Linux Kernel Mailing List,
	open list:ARM/Rockchip SoC..., Matthias Kaehlcke, ryandcase,
	Kalle Valo
In-Reply-To: <20190410221237.160856-1-dianders@chromium.org>

Hi Douglas,

Unfortunately this seems to beak resume on my rk3399-gru-kevin. I have
a semi-complicated setup with my rootfs as a btrfs on dmcrypt on
mmcblk0 which is the dw_mmc, so I'm guessing something goes wrong when
waking up the dm_mmc which probably wasn't suspended before this
patch. It's not 100% consistent though. Sometimes I see it resume the
first time I try suspending, but then 2nd time I suspend it won't come
back.

Let me know if I can do something to help debug this.

/Emil


On Thu, 11 Apr 2019 at 00:13, Douglas Anderson <dianders@chromium.org> wrote:
>
> Processing SDIO interrupts while dw_mmc is suspended (or partly
> suspended) seems like a bad idea.  We really don't want to be
> processing them until we've gotten ourselves fully powered up.
>
> You might be wondering how it's even possible to become suspended when
> an SDIO interrupt is active.  As can be seen in
> dw_mci_enable_sdio_irq(), we explicitly keep dw_mmc out of runtime
> suspend when the SDIO interrupt is enabled.  ...but even though we
> stop normal runtime suspend transitions when SDIO interrupts are
> enabled, the dw_mci_runtime_suspend() can still get called for a full
> system suspend.
>
> Let's handle all this by explicitly masking SDIO interrupts in the
> suspend call and unmasking them later in the resume call.  To do this
> cleanly I'll keep track of whether the client requested that SDIO
> interrupts be enabled so that we can reliably restore them regardless
> of whether we're masking them for one reason or another.
>
> Without this fix it can be seen that rk3288-veyron Chromebooks with
> Marvell WiFi would sometimes fail to resume WiFi even after picking my
> recent mwifiex patch [1].  Specifically you'd see messages like this:
>   mwifiex_sdio mmc1:0001:1: Firmware wakeup failed
>   mwifiex_sdio mmc1:0001:1: PREP_CMD: FW in reset state
>
> ...and tracing through the resume code in the failing cases showed
> that we were processing a SDIO interrupt really early in the resume
> call.
>
> NOTE: downstream in Chrome OS 3.14 and 3.18 kernels (both of which
> support the Marvell SDIO WiFi card) we had a patch ("CHROMIUM: sdio:
> Defer SDIO interrupt handling until after resume") [2].  Presumably
> this is the same problem that was solved by that patch.
>
> [1] https://lkml.kernel.org/r/20190404040106.40519-1-dianders@chromium.org
> [2] https://crrev.com/c/230765
>
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> ---
> I didn't put any "Fixes" tag here, but presumably this could be
> backported to whichever kernels folks found it useful for.  I have at
> least confirmed that kernels v4.14 and v4.19 (as well as v5.1-rc2)
> show the problem.  It is very easy to pick this to v4.19 and it
> definitely fixes the problem there.
>
> I haven't spent the time to pick this to 4.14 myself, but presumably
> it wouldn't be too hard to backport this as far as v4.13 since that
> contains commit 32dba73772f8 ("mmc: dw_mmc: Convert to use
> MMC_CAP2_SDIO_IRQ_NOTHREAD for SDIO IRQs").  Prior to that it might
> make sense for anyone experiencing this problem to just pick the old
> CHROMIUM patch to fix them.
>
>  drivers/mmc/host/dw_mmc.c | 24 ++++++++++++++++++++----
>  drivers/mmc/host/dw_mmc.h |  3 +++
>  2 files changed, 23 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 80dc2fd6576c..432f6e3ddd43 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -1664,7 +1664,8 @@ static void dw_mci_init_card(struct mmc_host *mmc, struct mmc_card *card)
>         }
>  }
>
> -static void __dw_mci_enable_sdio_irq(struct dw_mci_slot *slot, int enb)
> +static void __dw_mci_enable_sdio_irq(struct dw_mci_slot *slot, bool enb,
> +                                    bool client_requested)
>  {
>         struct dw_mci *host = slot->host;
>         unsigned long irqflags;
> @@ -1672,6 +1673,17 @@ static void __dw_mci_enable_sdio_irq(struct dw_mci_slot *slot, int enb)
>
>         spin_lock_irqsave(&host->irq_lock, irqflags);
>
> +       /*
> +        * If this was requested by the client save the request.  If this
> +        * wasn't required by the client then logically AND it with the
> +        * client request since we want to disable if either the client
> +        * disabled OR we have some other reason to disable.
> +        */
> +       if (client_requested)
> +               host->client_sdio_enb = enb;
> +       else if (!host->client_sdio_enb)
> +               enb = 0;
> +
>         /* Enable/disable Slot Specific SDIO interrupt */
>         int_mask = mci_readl(host, INTMASK);
>         if (enb)
> @@ -1688,7 +1700,7 @@ static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)
>         struct dw_mci_slot *slot = mmc_priv(mmc);
>         struct dw_mci *host = slot->host;
>
> -       __dw_mci_enable_sdio_irq(slot, enb);
> +       __dw_mci_enable_sdio_irq(slot, enb, true);
>
>         /* Avoid runtime suspending the device when SDIO IRQ is enabled */
>         if (enb)
> @@ -1701,7 +1713,7 @@ static void dw_mci_ack_sdio_irq(struct mmc_host *mmc)
>  {
>         struct dw_mci_slot *slot = mmc_priv(mmc);
>
> -       __dw_mci_enable_sdio_irq(slot, 1);
> +       __dw_mci_enable_sdio_irq(slot, true, false);
>  }
>
>  static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode)
> @@ -2734,7 +2746,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
>                 if (pending & SDMMC_INT_SDIO(slot->sdio_id)) {
>                         mci_writel(host, RINTSTS,
>                                    SDMMC_INT_SDIO(slot->sdio_id));
> -                       __dw_mci_enable_sdio_irq(slot, 0);
> +                       __dw_mci_enable_sdio_irq(slot, false, false);
>                         sdio_signal_irq(slot->mmc);
>                 }
>
> @@ -3424,6 +3436,8 @@ int dw_mci_runtime_suspend(struct device *dev)
>  {
>         struct dw_mci *host = dev_get_drvdata(dev);
>
> +       __dw_mci_enable_sdio_irq(host->slot, false, false);
> +
>         if (host->use_dma && host->dma_ops->exit)
>                 host->dma_ops->exit(host);
>
> @@ -3490,6 +3504,8 @@ int dw_mci_runtime_resume(struct device *dev)
>         /* Now that slots are all setup, we can enable card detect */
>         dw_mci_enable_cd(host);
>
> +       __dw_mci_enable_sdio_irq(host->slot, true, false);
> +
>         return 0;
>
>  err:
> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
> index 46e9f8ec5398..dfbace0f5043 100644
> --- a/drivers/mmc/host/dw_mmc.h
> +++ b/drivers/mmc/host/dw_mmc.h
> @@ -127,6 +127,7 @@ struct dw_mci_dma_slave {
>   * @cmd11_timer: Timer for SD3.0 voltage switch over scheme.
>   * @cto_timer: Timer for broken command transfer over scheme.
>   * @dto_timer: Timer for broken data transfer over scheme.
> + * @client_sdio_enb: The value last passed to enable_sdio_irq.
>   *
>   * Locking
>   * =======
> @@ -234,6 +235,8 @@ struct dw_mci {
>         struct timer_list       cmd11_timer;
>         struct timer_list       cto_timer;
>         struct timer_list       dto_timer;
> +
> +       bool                    client_sdio_enb;
>  };
>
>  /* DMA ops for Internal/External DMAC interface */
> --
> 2.21.0.392.gf8f6787159e-goog
>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip

^ permalink raw reply

* Re: Kali Linux 4.19.13 VM, Ralink RT3072 - Not Finding Wireless Networks
From: Stanislaw Gruszka @ 2019-04-24  7:55 UTC (permalink / raw)
  To: Kevan Salva; +Cc: linux-wireless
In-Reply-To: <CAAM6Ncf0=1wBbnomxH=o8r9-edhSk2zr_xzhJeA1uWdzRZ84Eg@mail.gmail.com>

On Wed, Apr 17, 2019 at 08:57:30PM -0500, Kevan Salva wrote:
> Hello All,
> 
> I am running Kali Linux (4.19.13) in a VM. I have a USB network
> adapter - a Ralink RT3072, passed through to the VM. However, it is
> not finding any wireless networks. This issue occurs on both VMware
> and on Virtualbox, but not on a live install of the same OS. This is
> the output I get from dmesg: pastebin.com/HaXUDNug . What may be the
> issue here?

Logs show we can not communicate with the device via USB bus. This is
problem in usb host driver or VM pass trough code or those two
combined. Eventually your motherboard firmware/BIOS issue.

Stanislaw

^ permalink raw reply

* [PATCH v2] rt2x00: add RT3883 support
From: Stanislaw Gruszka @ 2019-04-24  7:49 UTC (permalink / raw)
  To: linux-wireless
  Cc: Tomislav Požega, Daniel Golle, Felix Fietkau, Mathias Kresin,
	Gabor Juhos, Stanislaw Gruszka

From: Gabor Juhos <juhosg@openwrt.org>

Patch add support for RT3883 chip. Code was taken direclty
from openwrt project and merge into one patch.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
v1 -> v2 merge into one patch and add changelog

 drivers/net/wireless/ralink/rt2x00/rt2800.h    |  19 +-
 drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 598 ++++++++++++++++++++++++-
 drivers/net/wireless/ralink/rt2x00/rt2800soc.c |   9 +-
 3 files changed, 607 insertions(+), 19 deletions(-)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800.h b/drivers/net/wireless/ralink/rt2x00/rt2800.h
index b05ed2f3025a..06c38bafd2ca 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
@@ -48,7 +48,8 @@
  * RF2853 2.4G/5G 3T3R
  * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390)
  * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392)
- * RF3053 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662)
+ * RF3053 2.4G/5G 3T3R(RT3563/RT3573/RT3593)
+ * RF3853 2.4G/5G 3T3R(RT3883/RT3662)
  * RF5592 2.4G/5G 2T2R
  * RF3070 2.4G 1T1R
  * RF5360 2.4G 1T1R
@@ -72,6 +73,7 @@
 #define RF5592				0x000f
 #define RF3070				0x3070
 #define RF3290				0x3290
+#define RF3853				0x3853
 #define RF5350				0x5350
 #define RF5360				0x5360
 #define RF5362				0x5362
@@ -1726,6 +1728,20 @@
 #define TX_PWR_CFG_9B_STBC_MCS7		FIELD32(0x000000ff)
 
 /*
+ * TX_TXBF_CFG:
+ */
+#define TX_TXBF_CFG_0			0x138c
+#define TX_TXBF_CFG_1			0x13a4
+#define TX_TXBF_CFG_2			0x13a8
+#define TX_TXBF_CFG_3			0x13ac
+
+/*
+ * TX_FBK_CFG_3S:
+ */
+#define TX_FBK_CFG_3S_0			0x13c4
+#define TX_FBK_CFG_3S_1			0x13c8
+
+/*
  * RX_FILTER_CFG: RX configuration register.
  */
 #define RX_FILTER_CFG			0x1400
@@ -2296,6 +2312,7 @@ struct mac_iveiv_entry {
 /*
  * RFCSR 2:
  */
+#define RFCSR2_RESCAL_BP		FIELD8(0x40)
 #define RFCSR2_RESCAL_EN		FIELD8(0x80)
 #define RFCSR2_RX2_EN_MT7620		FIELD8(0x02)
 #define RFCSR2_TX2_EN_MT7620		FIELD8(0x20)
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index a03b5284a050..0e8e96075554 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -381,7 +381,8 @@ static unsigned int rt2800_eeprom_word_index(struct rt2x00_dev *rt2x00dev,
 		      wiphy_name(rt2x00dev->hw->wiphy), word))
 		return 0;
 
-	if (rt2x00_rt(rt2x00dev, RT3593))
+	if (rt2x00_rt(rt2x00dev, RT3593) ||
+	    rt2x00_rt(rt2x00dev, RT3883))
 		map = rt2800_eeprom_map_ext;
 	else
 		map = rt2800_eeprom_map;
@@ -590,6 +591,7 @@ void rt2800_get_txwi_rxwi_size(struct rt2x00_dev *rt2x00dev,
 {
 	switch (rt2x00dev->chip.rt) {
 	case RT3593:
+	case RT3883:
 		*txwi_size = TXWI_DESC_SIZE_4WORDS;
 		*rxwi_size = RXWI_DESC_SIZE_5WORDS;
 		break;
@@ -2172,7 +2174,8 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
 	rt2800_bbp_write(rt2x00dev, 3, r3);
 	rt2800_bbp_write(rt2x00dev, 1, r1);
 
-	if (rt2x00_rt(rt2x00dev, RT3593)) {
+	if (rt2x00_rt(rt2x00dev, RT3593) ||
+	    rt2x00_rt(rt2x00dev, RT3883)) {
 		if (ant->rx_chain_num == 1)
 			rt2800_bbp_write(rt2x00dev, 86, 0x00);
 		else
@@ -2194,7 +2197,8 @@ static void rt2800_config_lna_gain(struct rt2x00_dev *rt2x00dev,
 		eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_LNA);
 		lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0);
 	} else if (libconf->rf.channel <= 128) {
-		if (rt2x00_rt(rt2x00dev, RT3593)) {
+		if (rt2x00_rt(rt2x00dev, RT3593) ||
+		    rt2x00_rt(rt2x00dev, RT3883)) {
 			eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2);
 			lna_gain = rt2x00_get_field16(eeprom,
 						      EEPROM_EXT_LNA2_A1);
@@ -2204,7 +2208,8 @@ static void rt2800_config_lna_gain(struct rt2x00_dev *rt2x00dev,
 						      EEPROM_RSSI_BG2_LNA_A1);
 		}
 	} else {
-		if (rt2x00_rt(rt2x00dev, RT3593)) {
+		if (rt2x00_rt(rt2x00dev, RT3593) ||
+		    rt2x00_rt(rt2x00dev, RT3883)) {
 			eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2);
 			lna_gain = rt2x00_get_field16(eeprom,
 						      EEPROM_EXT_LNA2_A2);
@@ -2872,6 +2877,211 @@ static void rt2800_config_channel_rf3053(struct rt2x00_dev *rt2x00dev,
 	}
 }
 
+static void rt2800_config_channel_rf3853(struct rt2x00_dev *rt2x00dev,
+					 struct ieee80211_conf *conf,
+					 struct rf_channel *rf,
+					 struct channel_info *info)
+{
+	u8 rfcsr;
+	u8 bbp;
+	u8 pwr1, pwr2, pwr3;
+
+	const bool txbf_enabled = false; /* TODO */
+
+	/* TODO: add band selection */
+
+	if (rf->channel <= 14)
+		rt2800_rfcsr_write(rt2x00dev, 6, 0x40);
+	else if (rf->channel < 132)
+		rt2800_rfcsr_write(rt2x00dev, 6, 0x80);
+	else
+		rt2800_rfcsr_write(rt2x00dev, 6, 0x40);
+
+	rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1);
+	rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3);
+
+	if (rf->channel <= 14)
+		rt2800_rfcsr_write(rt2x00dev, 11, 0x46);
+	else
+		rt2800_rfcsr_write(rt2x00dev, 11, 0x48);
+
+	if (rf->channel <= 14)
+		rt2800_rfcsr_write(rt2x00dev, 12, 0x1a);
+	else
+		rt2800_rfcsr_write(rt2x00dev, 12, 0x52);
+
+	rt2800_rfcsr_write(rt2x00dev, 13, 0x12);
+
+	rfcsr = rt2800_rfcsr_read(rt2x00dev, 1);
+	rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0);
+	rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0);
+	rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0);
+	rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0);
+	rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0);
+	rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0);
+	rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
+	rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1);
+
+	switch (rt2x00dev->default_ant.tx_chain_num) {
+	case 3:
+		rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1);
+		/* fallthrough */
+	case 2:
+		rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1);
+		/* fallthrough */
+	case 1:
+		rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1);
+		break;
+	}
+
+	switch (rt2x00dev->default_ant.rx_chain_num) {
+	case 3:
+		rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1);
+		/* fallthrough */
+	case 2:
+		rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1);
+		/* fallthrough */
+	case 1:
+		rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1);
+		break;
+	}
+	rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
+
+	rt2800_freq_cal_mode1(rt2x00dev);
+
+	rfcsr = rt2800_rfcsr_read(rt2x00dev, 30);
+	if (!conf_is_ht40(conf))
+		rfcsr &= ~(0x06);
+	else
+		rfcsr |= 0x06;
+	rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
+
+	if (rf->channel <= 14)
+		rt2800_rfcsr_write(rt2x00dev, 31, 0xa0);
+	else
+		rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
+
+	if (conf_is_ht40(conf))
+		rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
+	else
+		rt2800_rfcsr_write(rt2x00dev, 32, 0xd8);
+
+	if (rf->channel <= 14)
+		rt2800_rfcsr_write(rt2x00dev, 34, 0x3c);
+	else
+		rt2800_rfcsr_write(rt2x00dev, 34, 0x20);
+
+	/* loopback RF_BS */
+	rfcsr = rt2800_rfcsr_read(rt2x00dev, 36);
+	if (rf->channel <= 14)
+		rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 1);
+	else
+		rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 0);
+	rt2800_rfcsr_write(rt2x00dev, 36, rfcsr);
+
+	if (rf->channel <= 14)
+		rfcsr = 0x23;
+	else if (rf->channel < 100)
+		rfcsr = 0x36;
+	else if (rf->channel < 132)
+		rfcsr = 0x32;
+	else
+		rfcsr = 0x30;
+
+	if (txbf_enabled)
+		rfcsr |= 0x40;
+
+	rt2800_rfcsr_write(rt2x00dev, 39, rfcsr);
+
+	if (rf->channel <= 14)
+		rt2800_rfcsr_write(rt2x00dev, 44, 0x93);
+	else
+		rt2800_rfcsr_write(rt2x00dev, 44, 0x9b);
+
+	if (rf->channel <= 14)
+		rfcsr = 0xbb;
+	else if (rf->channel < 100)
+		rfcsr = 0xeb;
+	else if (rf->channel < 132)
+		rfcsr = 0xb3;
+	else
+		rfcsr = 0x9b;
+	rt2800_rfcsr_write(rt2x00dev, 45, rfcsr);
+
+	if (rf->channel <= 14)
+		rfcsr = 0x8e;
+	else
+		rfcsr = 0x8a;
+
+	if (txbf_enabled)
+		rfcsr |= 0x20;
+
+	rt2800_rfcsr_write(rt2x00dev, 49, rfcsr);
+
+	rt2800_rfcsr_write(rt2x00dev, 50, 0x86);
+
+	rfcsr = rt2800_rfcsr_read(rt2x00dev, 51);
+	if (rf->channel <= 14)
+		rt2800_rfcsr_write(rt2x00dev, 51, 0x75);
+	else
+		rt2800_rfcsr_write(rt2x00dev, 51, 0x51);
+
+	rfcsr = rt2800_rfcsr_read(rt2x00dev, 52);
+	if (rf->channel <= 14)
+		rt2800_rfcsr_write(rt2x00dev, 52, 0x45);
+	else
+		rt2800_rfcsr_write(rt2x00dev, 52, 0x05);
+
+	if (rf->channel <= 14) {
+		pwr1 = info->default_power1 & 0x1f;
+		pwr2 = info->default_power2 & 0x1f;
+		pwr3 = info->default_power3 & 0x1f;
+	} else {
+		pwr1 = 0x48 | ((info->default_power1 & 0x18) << 1) |
+			(info->default_power1 & 0x7);
+		pwr2 = 0x48 | ((info->default_power2 & 0x18) << 1) |
+			(info->default_power2 & 0x7);
+		pwr3 = 0x48 | ((info->default_power3 & 0x18) << 1) |
+			(info->default_power3 & 0x7);
+	}
+
+	rt2800_rfcsr_write(rt2x00dev, 53, pwr1);
+	rt2800_rfcsr_write(rt2x00dev, 54, pwr2);
+	rt2800_rfcsr_write(rt2x00dev, 55, pwr3);
+
+	rt2x00_dbg(rt2x00dev, "Channel:%d, pwr1:%02x, pwr2:%02x, pwr3:%02x\n",
+		   rf->channel, pwr1, pwr2, pwr3);
+
+	bbp = (info->default_power1 >> 5) |
+	      ((info->default_power2 & 0xe0) >> 1);
+	rt2800_bbp_write(rt2x00dev, 109, bbp);
+
+	bbp = rt2800_bbp_read(rt2x00dev, 110);
+	bbp &= 0x0f;
+	bbp |= (info->default_power3 & 0xe0) >> 1;
+	rt2800_bbp_write(rt2x00dev, 110, bbp);
+
+	rfcsr = rt2800_rfcsr_read(rt2x00dev, 57);
+	if (rf->channel <= 14)
+		rt2800_rfcsr_write(rt2x00dev, 57, 0x6e);
+	else
+		rt2800_rfcsr_write(rt2x00dev, 57, 0x3e);
+
+	/* Enable RF tuning */
+	rfcsr = rt2800_rfcsr_read(rt2x00dev, 3);
+	rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1);
+	rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
+
+	udelay(2000);
+
+	bbp = rt2800_bbp_read(rt2x00dev, 49);
+	/* clear update flag */
+	rt2800_bbp_write(rt2x00dev, 49, bbp & 0xfe);
+	rt2800_bbp_write(rt2x00dev, 49, bbp);
+
+	/* TODO: add calibration for TxBF */
+}
+
 #define POWER_BOUND		0x27
 #define POWER_BOUND_5G		0x2b
 
@@ -3675,19 +3885,51 @@ static char rt2800_txpower_to_dev(struct rt2x00_dev *rt2x00dev,
 				  unsigned int channel,
 				  char txpower)
 {
-	if (rt2x00_rt(rt2x00dev, RT3593))
+	if (rt2x00_rt(rt2x00dev, RT3593) ||
+	    rt2x00_rt(rt2x00dev, RT3883))
 		txpower = rt2x00_get_field8(txpower, EEPROM_TXPOWER_ALC);
 
 	if (channel <= 14)
 		return clamp_t(char, txpower, MIN_G_TXPOWER, MAX_G_TXPOWER);
 
-	if (rt2x00_rt(rt2x00dev, RT3593))
+	if (rt2x00_rt(rt2x00dev, RT3593) ||
+	    rt2x00_rt(rt2x00dev, RT3883))
 		return clamp_t(char, txpower, MIN_A_TXPOWER_3593,
 			       MAX_A_TXPOWER_3593);
 	else
 		return clamp_t(char, txpower, MIN_A_TXPOWER, MAX_A_TXPOWER);
 }
 
+static void rt3883_bbp_adjust(struct rt2x00_dev *rt2x00dev,
+			      struct rf_channel *rf)
+{
+	u8 bbp;
+
+	bbp = (rf->channel > 14) ? 0x48 : 0x38;
+	rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, bbp);
+
+	rt2800_bbp_write(rt2x00dev, 69, 0x12);
+
+	if (rf->channel <= 14) {
+		rt2800_bbp_write(rt2x00dev, 70, 0x0a);
+	} else {
+		/* Disable CCK packet detection */
+		rt2800_bbp_write(rt2x00dev, 70, 0x00);
+	}
+
+	rt2800_bbp_write(rt2x00dev, 73, 0x10);
+
+	if (rf->channel > 14) {
+		rt2800_bbp_write(rt2x00dev, 62, 0x1d);
+		rt2800_bbp_write(rt2x00dev, 63, 0x1d);
+		rt2800_bbp_write(rt2x00dev, 64, 0x1d);
+	} else {
+		rt2800_bbp_write(rt2x00dev, 62, 0x2d);
+		rt2800_bbp_write(rt2x00dev, 63, 0x2d);
+		rt2800_bbp_write(rt2x00dev, 64, 0x2d);
+	}
+}
+
 static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
 				  struct ieee80211_conf *conf,
 				  struct rf_channel *rf,
@@ -3706,6 +3948,12 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
 			rt2800_txpower_to_dev(rt2x00dev, rf->channel,
 					      info->default_power3);
 
+	switch (rt2x00dev->chip.rt) {
+	case RT3883:
+		rt3883_bbp_adjust(rt2x00dev, rf);
+		break;
+	}
+
 	switch (rt2x00dev->chip.rf) {
 	case RF2020:
 	case RF3020:
@@ -3726,6 +3974,9 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
 	case RF3322:
 		rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info);
 		break;
+	case RF3853:
+		rt2800_config_channel_rf3853(rt2x00dev, conf, rf, info);
+		break;
 	case RF3070:
 	case RF5350:
 	case RF5360:
@@ -3807,6 +4058,15 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
 		rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
 		rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
 		rt2800_bbp_write(rt2x00dev, 77, 0x98);
+	} else if (rt2x00_rt(rt2x00dev, RT3883)) {
+		rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
+		rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
+		rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
+
+		if (rt2x00dev->default_ant.rx_chain_num > 1)
+			rt2800_bbp_write(rt2x00dev, 86, 0x46);
+		else
+			rt2800_bbp_write(rt2x00dev, 86, 0);
 	} else {
 		rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
 		rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
@@ -3820,6 +4080,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
 		    !rt2x00_rt(rt2x00dev, RT6352)) {
 			if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
 				rt2800_bbp_write(rt2x00dev, 82, 0x62);
+				rt2800_bbp_write(rt2x00dev, 82, 0x62);
 				rt2800_bbp_write(rt2x00dev, 75, 0x46);
 			} else {
 				if (rt2x00_rt(rt2x00dev, RT3593))
@@ -3828,19 +4089,22 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
 					rt2800_bbp_write(rt2x00dev, 82, 0x84);
 				rt2800_bbp_write(rt2x00dev, 75, 0x50);
 			}
-			if (rt2x00_rt(rt2x00dev, RT3593))
+			if (rt2x00_rt(rt2x00dev, RT3593) ||
+			    rt2x00_rt(rt2x00dev, RT3883))
 				rt2800_bbp_write(rt2x00dev, 83, 0x8a);
 		}
 
 	} else {
 		if (rt2x00_rt(rt2x00dev, RT3572))
 			rt2800_bbp_write(rt2x00dev, 82, 0x94);
-		else if (rt2x00_rt(rt2x00dev, RT3593))
+		else if (rt2x00_rt(rt2x00dev, RT3593) ||
+			 rt2x00_rt(rt2x00dev, RT3883))
 			rt2800_bbp_write(rt2x00dev, 82, 0x82);
 		else if (!rt2x00_rt(rt2x00dev, RT6352))
 			rt2800_bbp_write(rt2x00dev, 82, 0xf2);
 
-		if (rt2x00_rt(rt2x00dev, RT3593))
+		if (rt2x00_rt(rt2x00dev, RT3593) ||
+		    rt2x00_rt(rt2x00dev, RT3883))
 			rt2800_bbp_write(rt2x00dev, 83, 0x9a);
 
 		if (rt2x00_has_cap_external_lna_a(rt2x00dev))
@@ -3976,6 +4240,23 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
 		usleep_range(1000, 1500);
 	}
 
+	if (rt2x00_rt(rt2x00dev, RT3883)) {
+		if (!conf_is_ht40(conf))
+			rt2800_bbp_write(rt2x00dev, 105, 0x34);
+		else
+			rt2800_bbp_write(rt2x00dev, 105, 0x04);
+
+		/* AGC init */
+		if (rf->channel <= 14)
+			reg = 0x2e + rt2x00dev->lna_gain;
+		else
+			reg = 0x20 + ((rt2x00dev->lna_gain * 5) / 3);
+
+		rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
+
+		usleep_range(1000, 1500);
+	}
+
 	if (rt2x00_rt(rt2x00dev, RT5592) || rt2x00_rt(rt2x00dev, RT6352)) {
 		reg = 0x10;
 		if (!conf_is_ht40(conf)) {
@@ -4235,6 +4516,9 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b,
 	if (rt2x00_rt(rt2x00dev, RT3593))
 		return min_t(u8, txpower, 0xc);
 
+	if (rt2x00_rt(rt2x00dev, RT3883))
+		return min_t(u8, txpower, 0xf);
+
 	if (rt2x00_has_cap_power_limit(rt2x00dev)) {
 		/*
 		 * Check if eirp txpower exceed txpower_limit.
@@ -4996,7 +5280,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
 				  struct ieee80211_channel *chan,
 				  int power_level)
 {
-	if (rt2x00_rt(rt2x00dev, RT3593))
+	if (rt2x00_rt(rt2x00dev, RT3593) ||
+	    rt2x00_rt(rt2x00dev, RT3883))
 		rt2800_config_txpower_rt3593(rt2x00dev, chan, power_level);
 	else if (rt2x00_rt(rt2x00dev, RT6352))
 		rt2800_config_txpower_rt6352(rt2x00dev, chan, power_level);
@@ -5043,6 +5328,7 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev)
 	case RF3053:
 	case RF3070:
 	case RF3290:
+	case RF3853:
 	case RF5350:
 	case RF5360:
 	case RF5362:
@@ -5243,7 +5529,8 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev)
 		else
 			vgc = 0x2e + rt2x00dev->lna_gain;
 	} else { /* 5GHZ band */
-		if (rt2x00_rt(rt2x00dev, RT3593))
+		if (rt2x00_rt(rt2x00dev, RT3593) ||
+		    rt2x00_rt(rt2x00dev, RT3883))
 			vgc = 0x20 + (rt2x00dev->lna_gain * 5) / 3;
 		else if (rt2x00_rt(rt2x00dev, RT5592))
 			vgc = 0x24 + (2 * rt2x00dev->lna_gain);
@@ -5263,7 +5550,8 @@ static inline void rt2800_set_vgc(struct rt2x00_dev *rt2x00dev,
 {
 	if (qual->vgc_level != vgc_level) {
 		if (rt2x00_rt(rt2x00dev, RT3572) ||
-		    rt2x00_rt(rt2x00dev, RT3593)) {
+		    rt2x00_rt(rt2x00dev, RT3593) ||
+		    rt2x00_rt(rt2x00dev, RT3883)) {
 			rt2800_bbp_write_with_rx_chain(rt2x00dev, 66,
 						       vgc_level);
 		} else if (rt2x00_rt(rt2x00dev, RT5592)) {
@@ -5310,6 +5598,11 @@ void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual,
 		}
 		break;
 
+	case RT3883:
+		if (qual->rssi > -65)
+			vgc += 0x10;
+		break;
+
 	case RT5592:
 		if (qual->rssi > -65)
 			vgc += 0x20;
@@ -5462,6 +5755,12 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
 			rt2800_register_write(rt2x00dev, TX_SW_CFG2,
 					      0x00000000);
 		}
+	} else if (rt2x00_rt(rt2x00dev, RT3883)) {
+		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000402);
+		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
+		rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00040000);
+		rt2800_register_write(rt2x00dev, TX_TXBF_CFG_0, 0x8000fc21);
+		rt2800_register_write(rt2x00dev, TX_TXBF_CFG_3, 0x00009c40);
 	} else if (rt2x00_rt(rt2x00dev, RT5390) ||
 		   rt2x00_rt(rt2x00dev, RT5392) ||
 		   rt2x00_rt(rt2x00dev, RT6352)) {
@@ -5675,6 +5974,11 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
 	reg = rt2x00_rt(rt2x00dev, RT5592) ? 0x00000082 : 0x00000002;
 	rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, reg);
 
+	if (rt2x00_rt(rt2x00dev, RT3883)) {
+		rt2800_register_write(rt2x00dev, TX_FBK_CFG_3S_0, 0x12111008);
+		rt2800_register_write(rt2x00dev, TX_FBK_CFG_3S_1, 0x16151413);
+	}
+
 	reg = rt2800_register_read(rt2x00dev, TX_RTS_CFG);
 	rt2x00_set_field32(&reg, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 7);
 	rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_THRES,
@@ -6291,6 +6595,47 @@ static void rt2800_init_bbp_3593(struct rt2x00_dev *rt2x00dev)
 		rt2800_bbp_write(rt2x00dev, 103, 0xc0);
 }
 
+static void rt2800_init_bbp_3883(struct rt2x00_dev *rt2x00dev)
+{
+	rt2800_init_bbp_early(rt2x00dev);
+
+	rt2800_bbp_write(rt2x00dev, 4, 0x50);
+	rt2800_bbp_write(rt2x00dev, 47, 0x48);
+
+	rt2800_bbp_write(rt2x00dev, 86, 0x46);
+	rt2800_bbp_write(rt2x00dev, 88, 0x90);
+
+	rt2800_bbp_write(rt2x00dev, 92, 0x02);
+
+	rt2800_bbp_write(rt2x00dev, 103, 0xc0);
+	rt2800_bbp_write(rt2x00dev, 104, 0x92);
+	rt2800_bbp_write(rt2x00dev, 105, 0x34);
+	rt2800_bbp_write(rt2x00dev, 106, 0x12);
+	rt2800_bbp_write(rt2x00dev, 120, 0x50);
+	rt2800_bbp_write(rt2x00dev, 137, 0x0f);
+	rt2800_bbp_write(rt2x00dev, 163, 0x9d);
+
+	/* Set ITxBF timeout to 0x9C40=1000msec */
+	rt2800_bbp_write(rt2x00dev, 179, 0x02);
+	rt2800_bbp_write(rt2x00dev, 180, 0x00);
+	rt2800_bbp_write(rt2x00dev, 182, 0x40);
+	rt2800_bbp_write(rt2x00dev, 180, 0x01);
+	rt2800_bbp_write(rt2x00dev, 182, 0x9c);
+
+	rt2800_bbp_write(rt2x00dev, 179, 0x00);
+
+	/* Reprogram the inband interface to put right values in RXWI */
+	rt2800_bbp_write(rt2x00dev, 142, 0x04);
+	rt2800_bbp_write(rt2x00dev, 143, 0x3b);
+	rt2800_bbp_write(rt2x00dev, 142, 0x06);
+	rt2800_bbp_write(rt2x00dev, 143, 0xa0);
+	rt2800_bbp_write(rt2x00dev, 142, 0x07);
+	rt2800_bbp_write(rt2x00dev, 143, 0xa1);
+	rt2800_bbp_write(rt2x00dev, 142, 0x08);
+	rt2800_bbp_write(rt2x00dev, 143, 0xa2);
+	rt2800_bbp_write(rt2x00dev, 148, 0xc8);
+}
+
 static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
 {
 	int ant, div_mode;
@@ -6735,6 +7080,9 @@ static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
 	case RT3593:
 		rt2800_init_bbp_3593(rt2x00dev);
 		return;
+	case RT3883:
+		rt2800_init_bbp_3883(rt2x00dev);
+		return;
 	case RT5390:
 	case RT5392:
 		rt2800_init_bbp_53xx(rt2x00dev);
@@ -7606,6 +7954,144 @@ static void rt2800_init_rfcsr_5350(struct rt2x00_dev *rt2x00dev)
 	rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
 }
 
+static void rt2800_init_rfcsr_3883(struct rt2x00_dev *rt2x00dev)
+{
+	u8 rfcsr;
+
+	/* TODO: get the actual ECO value from the SoC */
+	const unsigned int eco = 5;
+
+	rt2800_rf_init_calibration(rt2x00dev, 2);
+
+	rt2800_rfcsr_write(rt2x00dev, 0, 0xe0);
+	rt2800_rfcsr_write(rt2x00dev, 1, 0x03);
+	rt2800_rfcsr_write(rt2x00dev, 2, 0x50);
+	rt2800_rfcsr_write(rt2x00dev, 3, 0x20);
+	rt2800_rfcsr_write(rt2x00dev, 4, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 5, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 6, 0x40);
+	rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 8, 0x5b);
+	rt2800_rfcsr_write(rt2x00dev, 9, 0x08);
+	rt2800_rfcsr_write(rt2x00dev, 10, 0xd3);
+	rt2800_rfcsr_write(rt2x00dev, 11, 0x48);
+	rt2800_rfcsr_write(rt2x00dev, 12, 0x1a);
+	rt2800_rfcsr_write(rt2x00dev, 13, 0x12);
+	rt2800_rfcsr_write(rt2x00dev, 14, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 16, 0x00);
+
+	/* RFCSR 17 will be initialized later based on the
+	 * frequency offset stored in the EEPROM
+	 */
+
+	rt2800_rfcsr_write(rt2x00dev, 18, 0x40);
+	rt2800_rfcsr_write(rt2x00dev, 19, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 20, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 21, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
+	rt2800_rfcsr_write(rt2x00dev, 23, 0xc0);
+	rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 25, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 26, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 29, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
+	rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
+	rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
+	rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 34, 0x20);
+	rt2800_rfcsr_write(rt2x00dev, 35, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 37, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 38, 0x86);
+	rt2800_rfcsr_write(rt2x00dev, 39, 0x23);
+	rt2800_rfcsr_write(rt2x00dev, 40, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 41, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 42, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 43, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 44, 0x93);
+	rt2800_rfcsr_write(rt2x00dev, 45, 0xbb);
+	rt2800_rfcsr_write(rt2x00dev, 46, 0x60);
+	rt2800_rfcsr_write(rt2x00dev, 47, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 48, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 49, 0x8e);
+	rt2800_rfcsr_write(rt2x00dev, 50, 0x86);
+	rt2800_rfcsr_write(rt2x00dev, 51, 0x51);
+	rt2800_rfcsr_write(rt2x00dev, 52, 0x05);
+	rt2800_rfcsr_write(rt2x00dev, 53, 0x76);
+	rt2800_rfcsr_write(rt2x00dev, 54, 0x76);
+	rt2800_rfcsr_write(rt2x00dev, 55, 0x76);
+	rt2800_rfcsr_write(rt2x00dev, 56, 0xdb);
+	rt2800_rfcsr_write(rt2x00dev, 57, 0x3e);
+	rt2800_rfcsr_write(rt2x00dev, 58, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 59, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 60, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 61, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 62, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
+
+	/* TODO: rx filter calibration? */
+
+	rt2800_bbp_write(rt2x00dev, 137, 0x0f);
+
+	rt2800_bbp_write(rt2x00dev, 163, 0x9d);
+
+	rt2800_bbp_write(rt2x00dev, 105, 0x05);
+
+	rt2800_bbp_write(rt2x00dev, 179, 0x02);
+	rt2800_bbp_write(rt2x00dev, 180, 0x00);
+	rt2800_bbp_write(rt2x00dev, 182, 0x40);
+	rt2800_bbp_write(rt2x00dev, 180, 0x01);
+	rt2800_bbp_write(rt2x00dev, 182, 0x9c);
+
+	rt2800_bbp_write(rt2x00dev, 179, 0x00);
+
+	rt2800_bbp_write(rt2x00dev, 142, 0x04);
+	rt2800_bbp_write(rt2x00dev, 143, 0x3b);
+	rt2800_bbp_write(rt2x00dev, 142, 0x06);
+	rt2800_bbp_write(rt2x00dev, 143, 0xa0);
+	rt2800_bbp_write(rt2x00dev, 142, 0x07);
+	rt2800_bbp_write(rt2x00dev, 143, 0xa1);
+	rt2800_bbp_write(rt2x00dev, 142, 0x08);
+	rt2800_bbp_write(rt2x00dev, 143, 0xa2);
+	rt2800_bbp_write(rt2x00dev, 148, 0xc8);
+
+	if (eco == 5) {
+		rt2800_rfcsr_write(rt2x00dev, 32, 0xd8);
+		rt2800_rfcsr_write(rt2x00dev, 33, 0x32);
+	}
+
+	rfcsr = rt2800_rfcsr_read(rt2x00dev, 2);
+	rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_BP, 0);
+	rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1);
+	rt2800_rfcsr_write(rt2x00dev, 2, rfcsr);
+	msleep(1);
+	rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 0);
+	rt2800_rfcsr_write(rt2x00dev, 2, rfcsr);
+
+	rfcsr = rt2800_rfcsr_read(rt2x00dev, 1);
+	rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
+	rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
+
+	rfcsr = rt2800_rfcsr_read(rt2x00dev, 6);
+	rfcsr |= 0xc0;
+	rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
+
+	rfcsr = rt2800_rfcsr_read(rt2x00dev, 22);
+	rfcsr |= 0x20;
+	rt2800_rfcsr_write(rt2x00dev, 22, rfcsr);
+
+	rfcsr = rt2800_rfcsr_read(rt2x00dev, 46);
+	rfcsr |= 0x20;
+	rt2800_rfcsr_write(rt2x00dev, 46, rfcsr);
+
+	rfcsr = rt2800_rfcsr_read(rt2x00dev, 20);
+	rfcsr &= ~0xee;
+	rt2800_rfcsr_write(rt2x00dev, 20, rfcsr);
+}
+
 static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
 {
 	rt2800_rf_init_calibration(rt2x00dev, 2);
@@ -8448,6 +8934,9 @@ static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
 	case RT3390:
 		rt2800_init_rfcsr_3390(rt2x00dev);
 		break;
+	case RT3883:
+		rt2800_init_rfcsr_3883(rt2x00dev);
+		break;
 	case RT3572:
 		rt2800_init_rfcsr_3572(rt2x00dev);
 		break;
@@ -8653,7 +9142,8 @@ static u8 rt2800_get_txmixer_gain_24g(struct rt2x00_dev *rt2x00dev)
 {
 	u16 word;
 
-	if (rt2x00_rt(rt2x00dev, RT3593))
+	if (rt2x00_rt(rt2x00dev, RT3593) ||
+	    rt2x00_rt(rt2x00dev, RT3883))
 		return 0;
 
 	word = rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG);
@@ -8667,7 +9157,8 @@ static u8 rt2800_get_txmixer_gain_5g(struct rt2x00_dev *rt2x00dev)
 {
 	u16 word;
 
-	if (rt2x00_rt(rt2x00dev, RT3593))
+	if (rt2x00_rt(rt2x00dev, RT3593) ||
+	    rt2x00_rt(rt2x00dev, RT3883))
 		return 0;
 
 	word = rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A);
@@ -8773,7 +9264,8 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
 	word = rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2);
 	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10)
 		rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0);
-	if (!rt2x00_rt(rt2x00dev, RT3593)) {
+	if (!rt2x00_rt(rt2x00dev, RT3593) &&
+	    !rt2x00_rt(rt2x00dev, RT3883)) {
 		if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 ||
 		    rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff)
 			rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1,
@@ -8793,7 +9285,8 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
 	word = rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2);
 	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10)
 		rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0);
-	if (!rt2x00_rt(rt2x00dev, RT3593)) {
+	if (!rt2x00_rt(rt2x00dev, RT3593) &&
+	    !rt2x00_rt(rt2x00dev, RT3883)) {
 		if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 ||
 		    rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff)
 			rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2,
@@ -8801,7 +9294,8 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
 	}
 	rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);
 
-	if (rt2x00_rt(rt2x00dev, RT3593)) {
+	if (rt2x00_rt(rt2x00dev, RT3593) ||
+	    rt2x00_rt(rt2x00dev, RT3883)) {
 		word = rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2);
 		if (rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0x00 ||
 		    rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0xff)
@@ -8840,6 +9334,8 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
 		rf = rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID);
 	else if (rt2x00_rt(rt2x00dev, RT3352))
 		rf = RF3322;
+	else if (rt2x00_rt(rt2x00dev, RT3883))
+		rf = RF3853;
 	else if (rt2x00_rt(rt2x00dev, RT5350))
 		rf = RF5350;
 	else
@@ -8860,6 +9356,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
 	case RF3290:
 	case RF3320:
 	case RF3322:
+	case RF3853:
 	case RF5350:
 	case RF5360:
 	case RF5362:
@@ -9146,6 +9643,66 @@ static const struct rf_channel rf_vals_3x_xtal20[] = {
 	{14,   0xF0,	 2,  0x18},
 };
 
+static const struct rf_channel rf_vals_3853[] = {
+	{1,  241, 6, 2},
+	{2,  241, 6, 7},
+	{3,  242, 6, 2},
+	{4,  242, 6, 7},
+	{5,  243, 6, 2},
+	{6,  243, 6, 7},
+	{7,  244, 6, 2},
+	{8,  244, 6, 7},
+	{9,  245, 6, 2},
+	{10, 245, 6, 7},
+	{11, 246, 6, 2},
+	{12, 246, 6, 7},
+	{13, 247, 6, 2},
+	{14, 248, 6, 4},
+
+	{36, 0x56, 8, 4},
+	{38, 0x56, 8, 6},
+	{40, 0x56, 8, 8},
+	{44, 0x57, 8, 0},
+	{46, 0x57, 8, 2},
+	{48, 0x57, 8, 4},
+	{52, 0x57, 8, 8},
+	{54, 0x57, 8, 10},
+	{56, 0x58, 8, 0},
+	{60, 0x58, 8, 4},
+	{62, 0x58, 8, 6},
+	{64, 0x58, 8, 8},
+
+	{100, 0x5b, 8, 8},
+	{102, 0x5b, 8, 10},
+	{104, 0x5c, 8, 0},
+	{108, 0x5c, 8, 4},
+	{110, 0x5c, 8, 6},
+	{112, 0x5c, 8, 8},
+	{114, 0x5c, 8, 10},
+	{116, 0x5d, 8, 0},
+	{118, 0x5d, 8, 2},
+	{120, 0x5d, 8, 4},
+	{124, 0x5d, 8, 8},
+	{126, 0x5d, 8, 10},
+	{128, 0x5e, 8, 0},
+	{132, 0x5e, 8, 4},
+	{134, 0x5e, 8, 6},
+	{136, 0x5e, 8, 8},
+	{140, 0x5f, 8, 0},
+
+	{149, 0x5f, 8, 9},
+	{151, 0x5f, 8, 11},
+	{153, 0x60, 8, 1},
+	{157, 0x60, 8, 5},
+	{159, 0x60, 8, 7},
+	{161, 0x60, 8, 9},
+	{165, 0x61, 8, 1},
+	{167, 0x61, 8, 3},
+	{169, 0x61, 8, 5},
+	{171, 0x61, 8, 7},
+	{173, 0x61, 8, 9},
+};
+
 static const struct rf_channel rf_vals_5592_xtal20[] = {
 	/* Channel, N, K, mod, R */
 	{1, 482, 4, 10, 3},
@@ -9409,6 +9966,11 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 		spec->channels = rf_vals_3x;
 		break;
 
+	case RF3853:
+		spec->num_channels = ARRAY_SIZE(rf_vals_3853);
+		spec->channels = rf_vals_3853;
+		break;
+
 	case RF5592:
 		reg = rt2800_register_read(rt2x00dev, MAC_DEBUG_INDEX);
 		if (rt2x00_get_field32(reg, MAC_DEBUG_INDEX_XTAL)) {
@@ -9528,6 +10090,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 	case RF3053:
 	case RF3070:
 	case RF3290:
+	case RF3853:
 	case RF5350:
 	case RF5360:
 	case RF5362:
@@ -9570,6 +10133,7 @@ static int rt2800_probe_rt(struct rt2x00_dev *rt2x00dev)
 	case RT3390:
 	case RT3572:
 	case RT3593:
+	case RT3883:
 	case RT5350:
 	case RT5390:
 	case RT5392:
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
index a502816214ab..9c74be82e2be 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
@@ -51,9 +51,16 @@ static bool rt2800soc_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev)
 
 static void rt2800soc_disable_radio(struct rt2x00_dev *rt2x00dev)
 {
+	u32 reg;
+
 	rt2800_disable_radio(rt2x00dev);
 	rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0);
-	rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, 0);
+
+	reg = 0;
+	if (rt2x00_rt(rt2x00dev, RT3883))
+		rt2x00_set_field32(&reg, TX_PIN_CFG_RFTR_EN, 1);
+
+	rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, reg);
 }
 
 static int rt2800soc_set_device_state(struct rt2x00_dev *rt2x00dev,
-- 
2.7.5


^ permalink raw reply related

* Re: ath10k: issue with TX queue scheduling
From: Justin Capella @ 2019-04-24  6:13 UTC (permalink / raw)
  To: Erik Stromdahl
  Cc: ath10k@lists.infradead.org, linux-wireless@vger.kernel.org,
	Kalle Valo, Toke Høiland-Jørgensen, Niklas Cassel,
	johannes
In-Reply-To: <CAMrEMU85ydLqs-vG5r0nVSgDvdvLQaeKfBiaSnfB6XtMOauuXA@mail.gmail.com>

Sorry, I didn't say that correctly.

Does maybe the userspace notification of cfg80211 for sta opmode
changes support multiple simulateous changes, whereas rx only ever
need s to handle one at a time? Not sure where this might get
initialized / how long it is kept around but in one place its being
treated as an enum and in another like a bitset/flags.

Does the sta opmode change maybe sometimes cause the queue to be
handled in an unexpected manner?

On Tue, Apr 23, 2019 at 9:13 PM Justin Capella <justincapella@gmail.com> wrote:
>
> I was experiencing this as well, QCA988x-- it eventually lead to a fw
> crash / module unload, because it would cause reconfig to close the
> device, which I think wound up not existing later on.
>
> [257455.643737] WARNING: CPU: 0 PID: 708 at
> net/mac80211/driver-ops.c:39 drv_stop+0xdc/0xf0 [mac80211]
> [257455.643738] Modules linked in: cmac ccm arc4 xt_tcpudp
> xt_conntrack iptable_filter ipt_MASQUERADE iptable_nat nf_nat_ipv4
> nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 libcrc32c
> intel_powerclamp ath10k_pci coretemp kvm_intel ath10k_core kvm ath
> mac80211 irqbypass crct10dif_pclmul crc32_pclmul ofpart
> ghash_clmulni_intel cmdlinepart pcbc intel_spi_platform intel_spi
> spi_nor mtd iTCO_wdt iTCO_vendor_support cfg80211 igb aesni_intel
> aes_x86_64 crypto_simd lpc_ich uas cryptd glue_helper intel_cstate
> pcspkr i2c_i801 usb_storage i2c_algo_bit i2c_ismt dca rfkill evdev
> pcc_cpufreq mac_hid acpi_cpufreq ip_tables x_tables ext4
> crc32c_generic crc16 mbcache jbd2 fscrypto sd_mod ahci libahci libata
> scsi_mod crc32c_intel ehci_pci ehci_hcd
> [257455.643812] CPU: 0 PID: 708 Comm: kworker/0:0 Tainted: G        W
>        4.19.28-1-lts #1
> [257455.643813] Hardware name: ADI Engineering DFFv2/DFFv2, BIOS
> ADI_DFF2-01.00.00.12-nodebug 02/07/2017
> [257455.643846] Workqueue: events_freezable ieee80211_restart_work [mac80211]
> [257455.643879] RIP: 0010:drv_stop+0xdc/0xf0 [mac80211]
> [257455.643883] Code: 51 0b 00 48 85 ed 74 1d 48 8b 45 00 48 8b 7d 08
> 48 83 c5 18 48 89 de e8 b2 48 4c fb 48 8b 45 00 48 85 c0 75 e7 e9 58
> ff ff ff <0f> 0b 5b 5d c3 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00
> 0f 1f
> [257455.643884] RSP: 0018:ffffa8e680f3fca8 EFLAGS: 00010246
> [257455.643887] RAX: 0000000000000000 RBX: ffff941c378b68c0 RCX:
> 0000000000000000
> [257455.643889] RDX: ffff941c3c889c80 RSI: 0000000000000286 RDI:
> ffff941c378f0760
> [257455.643894] RBP: ffff941c378f0ff0 R08: 0000000000000000 R09:
> 0000000000000000
> [257455.643896] R10: ffff941c3cc00028 R11: 0000000000000000 R12:
> ffff941c378f0b88
> [257455.643898] R13: ffff941c378f0ee8 R14: ffff941c378f0760 R15:
> ffff941c378b73a0
> [257455.643900] FS:  0000000000000000(0000) GS:ffff941c3d600000(0000)
> knlGS:0000000000000000
> [257455.643902] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [257455.643904] CR2: 0000561e406179b0 CR3: 000000007a0ae000 CR4:
> 00000000001006f0
> [257455.643906] Call Trace:
> [257455.643943]  ieee80211_do_stop+0x5ab/0x850 [mac80211]
> [257455.643979]  ieee80211_stop+0x16/0x20 [mac80211]
> [257455.643983]  __dev_close_many+0x9c/0x110
> [257455.643987]  dev_close_many+0x88/0x140
> [257455.643994]  dev_close.part.18+0x44/0x70
> [257455.644032]  cfg80211_shutdown_all_interfaces+0x6d/0xc0 [cfg80211]
> [257455.644069]  ieee80211_reconfig+0xa5/0x1280 [mac80211]
> [257455.644074]  ? rcu_exp_wait_wake+0x240/0x240
> [257455.644077]  ? try_to_del_timer_sync+0x4d/0x80
> [257455.644112]  ieee80211_restart_work+0xbb/0xe0 [mac80211]
> [257455.644117]  process_one_work+0x1f4/0x3e0
> [257455.644121]  worker_thread+0x2d/0x3e0
> [257455.644125]  ? process_one_work+0x3e0/0x3e0
> [257455.644128]  kthread+0x112/0x130
> [257455.644131]  ? kthread_park+0x80/0x80
> [257455.644136]  ret_from_fork+0x35/0x40
> [257455.644139] ---[ end trace 535d7b67d6e7df8f ]---
>
> The one common thing I was seeing was that before the TX queue stall:
> Apr 12 00:21:09 archlinux kernel: ath10k_pci 0000:01:00.0: failed to
> flush transmit queue (skip 1 ar-state 0): 500
>
> Was that a station had set caused "STA_OPMODE_SMPS_MODE_CHANGED" / smps dynamic.
>
> I did notice there was recent additions regarding sending that up to
> userspace, I don't know if actually related or not, but it seemed to
> always happen prior. The other thing I noticed was that htt.c uses =
> (not |=) and rx.c uses a &. Maybe this is intentional / not an issue,
> but it got me scratching my head wondering if perhaps multiple such
> sta mgmt frames were being queued/processed and this somehow impacted
> how things were being TX'd, or processed. Not sure if maybe only ever
> one such chane occurs in a given frame, whereas the rx side may
> support multiple changes for other reasons.
>
> Let me know if I can help troubleshoot / provide any more info
>
> On Tue, Apr 23, 2019 at 7:59 AM Erik Stromdahl <erik.stromdahl@gmail.com> wrote:
> >
> > Hello ath10k and mac80211 developers!
> >
> > I have run into an issue with ath10k SDIO and iperf TX.
> >
> > When running an iperf test (ath10k as server, PC as client),
> > I get a totally stalled transmitter on the ath10k side after some time.
> >
> > [  3] 574.0-575.0 sec  3.25 MBytes  27.3 Mbits/sec
> > [  3] 575.0-576.0 sec   255 KBytes  2.09 Mbits/sec
> > [  3] 576.0-577.0 sec  0.00 Bytes  0.00 bits/sec
> > [  3] 577.0-578.0 sec  0.00 Bytes  0.00 bits/sec
> >
> > Niklas Cassel had the same issue ~1 year ago and he made a fix in commit
> > 3f04950f32d5
> >
> > After this everything has been working fine until lately when I ran into the
> > same issue again.
> >
> > The problem seems to have reappeared after the new mac80211 TX scheduling
> > was introduced. I have not bisected or anything, but last time I was doing
> > these tests was before the introduction of the new TX scheduling, and then
> > everything was working.
> >
> > Niklas fix was to add a call to ath10k_mac_tx_push_pending() in
> > ath10k_sdio_irq_handler() in order to make sure we never get into a situation
> > where we have messages in the ath10k internal queue, but with TX queuing stopped.
> >
> > Since the introduction of the new TX scheduling, the driver internal queue
> > has been removed (there used to be a txqs member in struct ath10k that was
> > removed in commit bb2edb733586 by Toke). So I am unsure if Niklas commit is
> > still needed. At least it does not seem to fix this issue anymore.
> >
> > Are there any nice mac80211 kernel config options available that could
> > ease debugging queuing related issues?
> > Some kind of tracing feature for the TX scheduling perhaps?
> >
> > All tips/hints are welcome!
> >
> > P.S.
> >
> > When I run into the error I also get the below RCU stall splat (~20 seconds after
> > the bitrate has dropped down to 0 bit/s):
> >
> > rcu: INFO: rcu_sched self-detected stall on CPU
> > rcu:    0-....: (2600 ticks this GP) idle=02a/1/0x40000002 softirq=1107/1107 fqs=1294
> > rcu:     (t=2602 jiffies g=633 q=102)
> > NMI backtrace for cpu 0
> > CPU: 0 PID: 120 Comm: irq/64-mmc0 Tainted: G      D           5.1.0-rc3-wt-ath+ #31
> > Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
> > Backtrace:
> > [<c010ecec>] (dump_backtrace) from [<c010efec>] (show_stack+0x20/0x24)
> >   r7:00000000 r6:60010193 r5:00000000 r4:c14e9ecc
> > [<c010efcc>] (show_stack) from [<c0cf5674>] (dump_stack+0xdc/0x114)
> > [<c0cf5598>] (dump_stack) from [<c0cfcd0c>] (nmi_cpu_backtrace+0xac/0xbc)
> >   r10:80010193 r9:c14149fc r8:c0e02fd8 r7:00000000 r6:c0112318 r5:00000000
> >   r4:00000000 r3:02fc7d23
> > [<c0cfcc60>] (nmi_cpu_backtrace) from [<c0cfce04>] (nmi_trigger_cpumask_backtrace+0xe8/0x13c)
> >   r5:c1418a30 r4:00000000
> > [<c0cfcd1c>] (nmi_trigger_cpumask_backtrace) from [<c01132cc>] (arch_trigger_cpumask_backtrace+0x1c/0x24)
> >   r9:c14149fc r8:c142a880 r7:00000240 r6:c0e02fd4 r5:c1414978 r4:c142a880
> > [<c01132b0>] (arch_trigger_cpumask_backtrace) from [<c01b6220>] (rcu_dump_cpu_stacks+0xb8/0xfc)
> > [<c01b6168>] (rcu_dump_cpu_stacks) from [<c01b42a8>] (rcu_sched_clock_irq+0x890/0x9c0)
> >   r10:00000066 r9:c142a880 r8:c1414970 r7:c14f30f0 r6:c1405900 r5:c1414ed4
> >   r4:e671b100
> > [<c01b3a18>] (rcu_sched_clock_irq) from [<c01be570>] (update_process_times+0x40/0x6c)
> >   r10:c14150fc r9:e6716740 r8:c1414970 r7:00000027 r6:00000000 r5:d261f2c0
> >   r4:ffffe000
> > [<c01be530>] (update_process_times) from [<c01d4d04>] (tick_sched_handle+0x64/0x68)
> >   r7:00000027 r6:97c52581 r5:d288fba8 r4:e6716c00
> > [<c01d4ca0>] (tick_sched_handle) from [<c01d4fd8>] (tick_sched_timer+0x6c/0xd0)
> > [<c01d4f6c>] (tick_sched_timer) from [<c01bf3e0>] (__hrtimer_run_queues+0x1a8/0x5ac)
> >   r7:c01d4f6c r6:e67167a0 r5:e6716740 r4:e6716c00
> > [<c01bf238>] (__hrtimer_run_queues) from [<c01c08c0>] (hrtimer_interrupt+0x124/0x2ec)
> >   r10:e6716880 r9:ffffffff r8:7fffffff r7:e6716840 r6:00000003 r5:20010193
> >   r4:e6716740
> > [<c01c079c>] (hrtimer_interrupt) from [<c0113cec>] (twd_handler+0x3c/0x50)
> >   r10:c14f2cf4 r9:c1414ed4 r8:00000010 r7:c1414970 r6:c1415110 r5:d20d4900
> >   r4:00000001
> > [<c0113cb0>] (twd_handler) from [<c019eb50>] (handle_percpu_devid_irq+0xec/0x394)
> >   r5:d20d4900 r4:d2037800
> > [<c019ea64>] (handle_percpu_devid_irq) from [<c0197e48>] (generic_handle_irq+0x30/0x44)
> >   r10:c146c114 r9:d2024400 r8:00000001 r7:00000000 r6:c1414ed4 r5:00000010
> >   r4:c13e4450
> > [<c0197e18>] (generic_handle_irq) from [<c0198554>] (__handle_domain_irq+0x74/0xf0)
> > [<c01984e0>] (__handle_domain_irq) from [<c01024b4>] (gic_handle_irq+0x68/0xcc)
> >   r9:d288fba8 r8:c1415110 r7:f4000100 r6:000003ff r5:000003eb r4:f400010c
> > [<c010244c>] (gic_handle_irq) from [<c0101a70>] (__irq_svc+0x70/0x98)
> > Exception stack(0xd288fba8 to 0xd288fbf0)
> > fba0:                   c013417c 00000000 60010093 d288e000 000001ff ffffe000
> > fbc0: c0cb7340 00000003 d2fd86a0 d28c2000 d2fd86a0 d288fc14 d288fbc8 d288fbf8
> > fbe0: c0213544 c0134180 60010013 ffffffff
> >   r10:d2fd86a0 r9:d288e000 r8:d2fd86a0 r7:d288fbdc r6:ffffffff r5:60010013
> >   r4:c0134180
> > [<c01340c8>] (__local_bh_enable_ip) from [<c0d18b84>] (_raw_spin_unlock_bh+0x40/0x44)
> >   r7:00000003 r6:d21a88c0 r5:d2fd873c r4:c0cb7340
> > [<c0d18b44>] (_raw_spin_unlock_bh) from [<c0cb7340>] (_ieee80211_wake_txqs+0x394/0x6d4)
> >   r5:d21a88c0 r4:00000000
> > [<c0cb6fac>] (_ieee80211_wake_txqs) from [<c0cba838>] (ieee80211_wake_txqs+0x44/0x70)
> >   r10:00000006 r9:00000000 r8:00000000 r7:e6711404 r6:d2fd86a0 r5:d2fd8b10
> >   r4:c1414948
> > [<c0cba7f4>] (ieee80211_wake_txqs) from [<c0134a04>] (tasklet_action_common.constprop.5+0x64/0xec)
> >   r6:00000000 r5:d2fd908c r4:d2fd9088
> > [<c01349a0>] (tasklet_action_common.constprop.5) from [<c0134ac8>] (tasklet_action+0x3c/0x48)
> >   r10:00000040 r9:00000101 r8:c1414970 r7:c14f2ca4 r6:00000006 r5:c1403098
> >   r4:00000007 r3:25336000
> > [<c0134a8c>] (tasklet_action) from [<c0102610>] (__do_softirq+0xf8/0x54c)
> > [<c0102518>] (__do_softirq) from [<c01340bc>] (do_softirq.part.4+0x78/0x84)
> >   r10:d21a87cc r9:00000000 r8:00000000 r7:d2fd9e30 r6:bf058104 r5:ffffe000
> >   r4:60010093
> > [<c0134044>] (do_softirq.part.4) from [<c01341fc>] (__local_bh_enable_ip+0x134/0x18c)
> >   r5:ffffe000 r4:000001ff
> > [<c01340c8>] (__local_bh_enable_ip) from [<c0d18b84>] (_raw_spin_unlock_bh+0x40/0x44)
> >   r7:d2fd9e30 r6:d2fd9d38 r5:d2fd9e30 r4:bf058104
> > [<c0d18b44>] (_raw_spin_unlock_bh) from [<bf058104>] (ath10k_mac_tx_push_txq+0x294/0x2a4 [ath10k_core])
> >   r5:d2fd9540 r4:d33220dc
> > [<bf057e70>] (ath10k_mac_tx_push_txq [ath10k_core]) from [<bf05820c>] (ath10k_mac_tx_push_pending+0xf8/0x1ec [ath10k_core])
> >   r10:ffffe8ed r9:d2d96540 r8:fffffffe r7:00000002 r6:00000002 r5:d33220dc
> >   r4:d2fd86a0
> > [<bf058114>] (ath10k_mac_tx_push_pending [ath10k_core]) from [<bf0e2544>] (ath10k_sdio_irq_handler+0x308/0x4d4 [ath10k_sdio])
> >   r8:01340202 r7:d2fde540 r6:d2fde87c r5:00000000 r4:d2fd9540
> > [<bf0e223c>] (ath10k_sdio_irq_handler [ath10k_sdio]) from [<c08e86c0>] (process_sdio_pending_irqs+0x4c/0x1bc)
> >   r10:d287bb80 r9:d22a7400 r8:00000001 r7:00000000 r6:d284c800 r5:c1414948
> >   r4:d2859000
> > [<c08e8674>] (process_sdio_pending_irqs) from [<c08e887c>] (sdio_run_irqs+0x4c/0x68)
> >   r10:d287bb80 r9:d22a7400 r8:00000001 r7:00000000 r6:d28596a0 r5:00000100
> >   r4:d2859000
> > [<c08e8830>] (sdio_run_irqs) from [<c08f3d00>] (sdhci_thread_irq+0x80/0xbc)
> >   r5:00000100 r4:d28594c0
> > [<c08f3c80>] (sdhci_thread_irq) from [<c019a718>] (irq_thread_fn+0x2c/0x88)
> >   r7:00000000 r6:d287bba4 r5:d22a7400 r4:d287bb80
> > [<c019a6ec>] (irq_thread_fn) from [<c019aa54>] (irq_thread+0x120/0x22c)
> >   r7:00000000 r6:d287bba4 r5:ffffe000 r4:00000000
> > [<c019a934>] (irq_thread) from [<c015526c>] (kthread+0x154/0x168)
> >   r10:d2101bd8 r9:c019a934 r8:d287bb80 r7:d288e000 r6:d287bbc0 r5:d2241400
> >   r4:00000000
> > [<c0155118>] (kthread) from [<c01010b4>] (ret_from_fork+0x14/0x20)
> > Exception stack(0xd288ffb0 to 0xd288fff8)
> > ffa0:                                     00000000 00000000 00000000 00000000
> > ffc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> > ffe0: 00000000 00000000 00000000 00000000 00000013 00000000
> >   r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0155118
> >   r4:d287bbc0
> >
> > I have a patch where I have rewritten ath10k_mac_tx_push_pending() somewhat in
> > order to reduce the time spent in the RCU critical read section.
> >
> > With this patch the RCU stall warning disappears and the transmitter "recovers"
> > after some time ( I still get the 0 bit/s drop though).
> >
> > Below is list of function calls of a potential scenario (derived from the above backtrace):
> >
> > ath10k_sdio_irq_handler()
> >         ath10k_mac_tx_push_pending()
> >                 rcu_read_lock()                              <- This RCU read lock causes the stall
> >                 ath10k_mac_schedule_txq()                    <- Called in a loop for each ac
> >                         ieee80211_txq_schedule_start()
> >                         ath10k_mac_tx_push_txq()                 <- Called in a loop where we iterate
> >                                                                     all queues using ieee80211_next_txq
> >                                 ...
> >                                 spin_lock_bh(&ar->htt.tx_lock)
> >                                 ...
> >                                 spin_unlock_bh(&ar->htt.tx_lock)     <- Here we have a switch to softirq
> >
> >                                 /* We are now executing softirq ..*/
> >                                 ...
> >                                 ieee80211_wake_txqs()
> >                                         _ieee80211_wake_txqs()
> >                                                 rcu_read_lock()              <- nested rcu_read_lock() (OK I suppose)
> >                                                 __ieee80211_wake_txqs()
> >                                                         spin_lock_bh(&fq->lock);
> >                                                         spin_unlock_bh(&fq->lock);
> >                                                                 ath10k_mac_op_wake_tx_queue() /* via local->ops->wake_tx_queue() */
> >                                                                         ath10k_mac_tx_push_txq()
> >                                                                         ...
> >                                                 rcu_read_unlock()
> >                                 ...
> >                 rcu_read_unlock()
> >
> > If, for some reason, ieee80211_next_txq() never returns NULL (the queues are
> > being refilled while we are iterating), we could potentially spend a very long
> > time in the loop with the RCU read lock held.
> >
> > Another reason could perhaps be that there are so many softirqs that we never
> > have time to exit the loop from where ath10k_mac_schedule_txq() is called.
> >
> > Since I still run into the problem even if the RCU stall is removed, the root
> > cause of the problem remains unknown.
> >
> > --
> > Erik

^ permalink raw reply

* Re: [PATCH] brcmfmac: remove the duplicate line of sending mail box interrupt
From: Arend Van Spriel @ 2019-04-24  5:24 UTC (permalink / raw)
  To: Wright Feng, franky.lin, hante.meuleman, kvalo, Chi-Hsien Lin
  Cc: linux-wireless, brcm80211-dev-list.pdl
In-Reply-To: <1555901236-145920-1-git-send-email-wright.feng@cypress.com>

On April 22, 2019 4:47:31 AM Wright Feng <Wright.Feng@cypress.com> wrote:

> The line is duplicate so remove it from pcie.c. We don't need to send
> host to dongle mail box interrupt twice after writing data.

Hi Wright,

Thanks for the patch. I am a bit early as it is not uncommon that hardware 
requires an extra kick. Might be the case here for some chips. Will 
follow-up on it.

Regards,
Arend

> Signed-off-by: Wright Feng <wright.feng@cypress.com>
> ---
>  drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 1 -
>  1 file changed, 1 deletion(-)



^ permalink raw reply

* Re: ath10k: issue with TX queue scheduling
From: Justin Capella @ 2019-04-24  4:13 UTC (permalink / raw)
  To: Erik Stromdahl
  Cc: ath10k@lists.infradead.org, linux-wireless@vger.kernel.org,
	Kalle Valo, Toke Høiland-Jørgensen, Niklas Cassel,
	johannes
In-Reply-To: <c8fc9821-3055-8110-fe57-34f06a6b0296@gmail.com>

I was experiencing this as well, QCA988x-- it eventually lead to a fw
crash / module unload, because it would cause reconfig to close the
device, which I think wound up not existing later on.

[257455.643737] WARNING: CPU: 0 PID: 708 at
net/mac80211/driver-ops.c:39 drv_stop+0xdc/0xf0 [mac80211]
[257455.643738] Modules linked in: cmac ccm arc4 xt_tcpudp
xt_conntrack iptable_filter ipt_MASQUERADE iptable_nat nf_nat_ipv4
nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 libcrc32c
intel_powerclamp ath10k_pci coretemp kvm_intel ath10k_core kvm ath
mac80211 irqbypass crct10dif_pclmul crc32_pclmul ofpart
ghash_clmulni_intel cmdlinepart pcbc intel_spi_platform intel_spi
spi_nor mtd iTCO_wdt iTCO_vendor_support cfg80211 igb aesni_intel
aes_x86_64 crypto_simd lpc_ich uas cryptd glue_helper intel_cstate
pcspkr i2c_i801 usb_storage i2c_algo_bit i2c_ismt dca rfkill evdev
pcc_cpufreq mac_hid acpi_cpufreq ip_tables x_tables ext4
crc32c_generic crc16 mbcache jbd2 fscrypto sd_mod ahci libahci libata
scsi_mod crc32c_intel ehci_pci ehci_hcd
[257455.643812] CPU: 0 PID: 708 Comm: kworker/0:0 Tainted: G        W
       4.19.28-1-lts #1
[257455.643813] Hardware name: ADI Engineering DFFv2/DFFv2, BIOS
ADI_DFF2-01.00.00.12-nodebug 02/07/2017
[257455.643846] Workqueue: events_freezable ieee80211_restart_work [mac80211]
[257455.643879] RIP: 0010:drv_stop+0xdc/0xf0 [mac80211]
[257455.643883] Code: 51 0b 00 48 85 ed 74 1d 48 8b 45 00 48 8b 7d 08
48 83 c5 18 48 89 de e8 b2 48 4c fb 48 8b 45 00 48 85 c0 75 e7 e9 58
ff ff ff <0f> 0b 5b 5d c3 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00
0f 1f
[257455.643884] RSP: 0018:ffffa8e680f3fca8 EFLAGS: 00010246
[257455.643887] RAX: 0000000000000000 RBX: ffff941c378b68c0 RCX:
0000000000000000
[257455.643889] RDX: ffff941c3c889c80 RSI: 0000000000000286 RDI:
ffff941c378f0760
[257455.643894] RBP: ffff941c378f0ff0 R08: 0000000000000000 R09:
0000000000000000
[257455.643896] R10: ffff941c3cc00028 R11: 0000000000000000 R12:
ffff941c378f0b88
[257455.643898] R13: ffff941c378f0ee8 R14: ffff941c378f0760 R15:
ffff941c378b73a0
[257455.643900] FS:  0000000000000000(0000) GS:ffff941c3d600000(0000)
knlGS:0000000000000000
[257455.643902] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[257455.643904] CR2: 0000561e406179b0 CR3: 000000007a0ae000 CR4:
00000000001006f0
[257455.643906] Call Trace:
[257455.643943]  ieee80211_do_stop+0x5ab/0x850 [mac80211]
[257455.643979]  ieee80211_stop+0x16/0x20 [mac80211]
[257455.643983]  __dev_close_many+0x9c/0x110
[257455.643987]  dev_close_many+0x88/0x140
[257455.643994]  dev_close.part.18+0x44/0x70
[257455.644032]  cfg80211_shutdown_all_interfaces+0x6d/0xc0 [cfg80211]
[257455.644069]  ieee80211_reconfig+0xa5/0x1280 [mac80211]
[257455.644074]  ? rcu_exp_wait_wake+0x240/0x240
[257455.644077]  ? try_to_del_timer_sync+0x4d/0x80
[257455.644112]  ieee80211_restart_work+0xbb/0xe0 [mac80211]
[257455.644117]  process_one_work+0x1f4/0x3e0
[257455.644121]  worker_thread+0x2d/0x3e0
[257455.644125]  ? process_one_work+0x3e0/0x3e0
[257455.644128]  kthread+0x112/0x130
[257455.644131]  ? kthread_park+0x80/0x80
[257455.644136]  ret_from_fork+0x35/0x40
[257455.644139] ---[ end trace 535d7b67d6e7df8f ]---

The one common thing I was seeing was that before the TX queue stall:
Apr 12 00:21:09 archlinux kernel: ath10k_pci 0000:01:00.0: failed to
flush transmit queue (skip 1 ar-state 0): 500

Was that a station had set caused "STA_OPMODE_SMPS_MODE_CHANGED" / smps dynamic.

I did notice there was recent additions regarding sending that up to
userspace, I don't know if actually related or not, but it seemed to
always happen prior. The other thing I noticed was that htt.c uses =
(not |=) and rx.c uses a &. Maybe this is intentional / not an issue,
but it got me scratching my head wondering if perhaps multiple such
sta mgmt frames were being queued/processed and this somehow impacted
how things were being TX'd, or processed. Not sure if maybe only ever
one such chane occurs in a given frame, whereas the rx side may
support multiple changes for other reasons.

Let me know if I can help troubleshoot / provide any more info

On Tue, Apr 23, 2019 at 7:59 AM Erik Stromdahl <erik.stromdahl@gmail.com> wrote:
>
> Hello ath10k and mac80211 developers!
>
> I have run into an issue with ath10k SDIO and iperf TX.
>
> When running an iperf test (ath10k as server, PC as client),
> I get a totally stalled transmitter on the ath10k side after some time.
>
> [  3] 574.0-575.0 sec  3.25 MBytes  27.3 Mbits/sec
> [  3] 575.0-576.0 sec   255 KBytes  2.09 Mbits/sec
> [  3] 576.0-577.0 sec  0.00 Bytes  0.00 bits/sec
> [  3] 577.0-578.0 sec  0.00 Bytes  0.00 bits/sec
>
> Niklas Cassel had the same issue ~1 year ago and he made a fix in commit
> 3f04950f32d5
>
> After this everything has been working fine until lately when I ran into the
> same issue again.
>
> The problem seems to have reappeared after the new mac80211 TX scheduling
> was introduced. I have not bisected or anything, but last time I was doing
> these tests was before the introduction of the new TX scheduling, and then
> everything was working.
>
> Niklas fix was to add a call to ath10k_mac_tx_push_pending() in
> ath10k_sdio_irq_handler() in order to make sure we never get into a situation
> where we have messages in the ath10k internal queue, but with TX queuing stopped.
>
> Since the introduction of the new TX scheduling, the driver internal queue
> has been removed (there used to be a txqs member in struct ath10k that was
> removed in commit bb2edb733586 by Toke). So I am unsure if Niklas commit is
> still needed. At least it does not seem to fix this issue anymore.
>
> Are there any nice mac80211 kernel config options available that could
> ease debugging queuing related issues?
> Some kind of tracing feature for the TX scheduling perhaps?
>
> All tips/hints are welcome!
>
> P.S.
>
> When I run into the error I also get the below RCU stall splat (~20 seconds after
> the bitrate has dropped down to 0 bit/s):
>
> rcu: INFO: rcu_sched self-detected stall on CPU
> rcu:    0-....: (2600 ticks this GP) idle=02a/1/0x40000002 softirq=1107/1107 fqs=1294
> rcu:     (t=2602 jiffies g=633 q=102)
> NMI backtrace for cpu 0
> CPU: 0 PID: 120 Comm: irq/64-mmc0 Tainted: G      D           5.1.0-rc3-wt-ath+ #31
> Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
> Backtrace:
> [<c010ecec>] (dump_backtrace) from [<c010efec>] (show_stack+0x20/0x24)
>   r7:00000000 r6:60010193 r5:00000000 r4:c14e9ecc
> [<c010efcc>] (show_stack) from [<c0cf5674>] (dump_stack+0xdc/0x114)
> [<c0cf5598>] (dump_stack) from [<c0cfcd0c>] (nmi_cpu_backtrace+0xac/0xbc)
>   r10:80010193 r9:c14149fc r8:c0e02fd8 r7:00000000 r6:c0112318 r5:00000000
>   r4:00000000 r3:02fc7d23
> [<c0cfcc60>] (nmi_cpu_backtrace) from [<c0cfce04>] (nmi_trigger_cpumask_backtrace+0xe8/0x13c)
>   r5:c1418a30 r4:00000000
> [<c0cfcd1c>] (nmi_trigger_cpumask_backtrace) from [<c01132cc>] (arch_trigger_cpumask_backtrace+0x1c/0x24)
>   r9:c14149fc r8:c142a880 r7:00000240 r6:c0e02fd4 r5:c1414978 r4:c142a880
> [<c01132b0>] (arch_trigger_cpumask_backtrace) from [<c01b6220>] (rcu_dump_cpu_stacks+0xb8/0xfc)
> [<c01b6168>] (rcu_dump_cpu_stacks) from [<c01b42a8>] (rcu_sched_clock_irq+0x890/0x9c0)
>   r10:00000066 r9:c142a880 r8:c1414970 r7:c14f30f0 r6:c1405900 r5:c1414ed4
>   r4:e671b100
> [<c01b3a18>] (rcu_sched_clock_irq) from [<c01be570>] (update_process_times+0x40/0x6c)
>   r10:c14150fc r9:e6716740 r8:c1414970 r7:00000027 r6:00000000 r5:d261f2c0
>   r4:ffffe000
> [<c01be530>] (update_process_times) from [<c01d4d04>] (tick_sched_handle+0x64/0x68)
>   r7:00000027 r6:97c52581 r5:d288fba8 r4:e6716c00
> [<c01d4ca0>] (tick_sched_handle) from [<c01d4fd8>] (tick_sched_timer+0x6c/0xd0)
> [<c01d4f6c>] (tick_sched_timer) from [<c01bf3e0>] (__hrtimer_run_queues+0x1a8/0x5ac)
>   r7:c01d4f6c r6:e67167a0 r5:e6716740 r4:e6716c00
> [<c01bf238>] (__hrtimer_run_queues) from [<c01c08c0>] (hrtimer_interrupt+0x124/0x2ec)
>   r10:e6716880 r9:ffffffff r8:7fffffff r7:e6716840 r6:00000003 r5:20010193
>   r4:e6716740
> [<c01c079c>] (hrtimer_interrupt) from [<c0113cec>] (twd_handler+0x3c/0x50)
>   r10:c14f2cf4 r9:c1414ed4 r8:00000010 r7:c1414970 r6:c1415110 r5:d20d4900
>   r4:00000001
> [<c0113cb0>] (twd_handler) from [<c019eb50>] (handle_percpu_devid_irq+0xec/0x394)
>   r5:d20d4900 r4:d2037800
> [<c019ea64>] (handle_percpu_devid_irq) from [<c0197e48>] (generic_handle_irq+0x30/0x44)
>   r10:c146c114 r9:d2024400 r8:00000001 r7:00000000 r6:c1414ed4 r5:00000010
>   r4:c13e4450
> [<c0197e18>] (generic_handle_irq) from [<c0198554>] (__handle_domain_irq+0x74/0xf0)
> [<c01984e0>] (__handle_domain_irq) from [<c01024b4>] (gic_handle_irq+0x68/0xcc)
>   r9:d288fba8 r8:c1415110 r7:f4000100 r6:000003ff r5:000003eb r4:f400010c
> [<c010244c>] (gic_handle_irq) from [<c0101a70>] (__irq_svc+0x70/0x98)
> Exception stack(0xd288fba8 to 0xd288fbf0)
> fba0:                   c013417c 00000000 60010093 d288e000 000001ff ffffe000
> fbc0: c0cb7340 00000003 d2fd86a0 d28c2000 d2fd86a0 d288fc14 d288fbc8 d288fbf8
> fbe0: c0213544 c0134180 60010013 ffffffff
>   r10:d2fd86a0 r9:d288e000 r8:d2fd86a0 r7:d288fbdc r6:ffffffff r5:60010013
>   r4:c0134180
> [<c01340c8>] (__local_bh_enable_ip) from [<c0d18b84>] (_raw_spin_unlock_bh+0x40/0x44)
>   r7:00000003 r6:d21a88c0 r5:d2fd873c r4:c0cb7340
> [<c0d18b44>] (_raw_spin_unlock_bh) from [<c0cb7340>] (_ieee80211_wake_txqs+0x394/0x6d4)
>   r5:d21a88c0 r4:00000000
> [<c0cb6fac>] (_ieee80211_wake_txqs) from [<c0cba838>] (ieee80211_wake_txqs+0x44/0x70)
>   r10:00000006 r9:00000000 r8:00000000 r7:e6711404 r6:d2fd86a0 r5:d2fd8b10
>   r4:c1414948
> [<c0cba7f4>] (ieee80211_wake_txqs) from [<c0134a04>] (tasklet_action_common.constprop.5+0x64/0xec)
>   r6:00000000 r5:d2fd908c r4:d2fd9088
> [<c01349a0>] (tasklet_action_common.constprop.5) from [<c0134ac8>] (tasklet_action+0x3c/0x48)
>   r10:00000040 r9:00000101 r8:c1414970 r7:c14f2ca4 r6:00000006 r5:c1403098
>   r4:00000007 r3:25336000
> [<c0134a8c>] (tasklet_action) from [<c0102610>] (__do_softirq+0xf8/0x54c)
> [<c0102518>] (__do_softirq) from [<c01340bc>] (do_softirq.part.4+0x78/0x84)
>   r10:d21a87cc r9:00000000 r8:00000000 r7:d2fd9e30 r6:bf058104 r5:ffffe000
>   r4:60010093
> [<c0134044>] (do_softirq.part.4) from [<c01341fc>] (__local_bh_enable_ip+0x134/0x18c)
>   r5:ffffe000 r4:000001ff
> [<c01340c8>] (__local_bh_enable_ip) from [<c0d18b84>] (_raw_spin_unlock_bh+0x40/0x44)
>   r7:d2fd9e30 r6:d2fd9d38 r5:d2fd9e30 r4:bf058104
> [<c0d18b44>] (_raw_spin_unlock_bh) from [<bf058104>] (ath10k_mac_tx_push_txq+0x294/0x2a4 [ath10k_core])
>   r5:d2fd9540 r4:d33220dc
> [<bf057e70>] (ath10k_mac_tx_push_txq [ath10k_core]) from [<bf05820c>] (ath10k_mac_tx_push_pending+0xf8/0x1ec [ath10k_core])
>   r10:ffffe8ed r9:d2d96540 r8:fffffffe r7:00000002 r6:00000002 r5:d33220dc
>   r4:d2fd86a0
> [<bf058114>] (ath10k_mac_tx_push_pending [ath10k_core]) from [<bf0e2544>] (ath10k_sdio_irq_handler+0x308/0x4d4 [ath10k_sdio])
>   r8:01340202 r7:d2fde540 r6:d2fde87c r5:00000000 r4:d2fd9540
> [<bf0e223c>] (ath10k_sdio_irq_handler [ath10k_sdio]) from [<c08e86c0>] (process_sdio_pending_irqs+0x4c/0x1bc)
>   r10:d287bb80 r9:d22a7400 r8:00000001 r7:00000000 r6:d284c800 r5:c1414948
>   r4:d2859000
> [<c08e8674>] (process_sdio_pending_irqs) from [<c08e887c>] (sdio_run_irqs+0x4c/0x68)
>   r10:d287bb80 r9:d22a7400 r8:00000001 r7:00000000 r6:d28596a0 r5:00000100
>   r4:d2859000
> [<c08e8830>] (sdio_run_irqs) from [<c08f3d00>] (sdhci_thread_irq+0x80/0xbc)
>   r5:00000100 r4:d28594c0
> [<c08f3c80>] (sdhci_thread_irq) from [<c019a718>] (irq_thread_fn+0x2c/0x88)
>   r7:00000000 r6:d287bba4 r5:d22a7400 r4:d287bb80
> [<c019a6ec>] (irq_thread_fn) from [<c019aa54>] (irq_thread+0x120/0x22c)
>   r7:00000000 r6:d287bba4 r5:ffffe000 r4:00000000
> [<c019a934>] (irq_thread) from [<c015526c>] (kthread+0x154/0x168)
>   r10:d2101bd8 r9:c019a934 r8:d287bb80 r7:d288e000 r6:d287bbc0 r5:d2241400
>   r4:00000000
> [<c0155118>] (kthread) from [<c01010b4>] (ret_from_fork+0x14/0x20)
> Exception stack(0xd288ffb0 to 0xd288fff8)
> ffa0:                                     00000000 00000000 00000000 00000000
> ffc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> ffe0: 00000000 00000000 00000000 00000000 00000013 00000000
>   r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0155118
>   r4:d287bbc0
>
> I have a patch where I have rewritten ath10k_mac_tx_push_pending() somewhat in
> order to reduce the time spent in the RCU critical read section.
>
> With this patch the RCU stall warning disappears and the transmitter "recovers"
> after some time ( I still get the 0 bit/s drop though).
>
> Below is list of function calls of a potential scenario (derived from the above backtrace):
>
> ath10k_sdio_irq_handler()
>         ath10k_mac_tx_push_pending()
>                 rcu_read_lock()                              <- This RCU read lock causes the stall
>                 ath10k_mac_schedule_txq()                    <- Called in a loop for each ac
>                         ieee80211_txq_schedule_start()
>                         ath10k_mac_tx_push_txq()                 <- Called in a loop where we iterate
>                                                                     all queues using ieee80211_next_txq
>                                 ...
>                                 spin_lock_bh(&ar->htt.tx_lock)
>                                 ...
>                                 spin_unlock_bh(&ar->htt.tx_lock)     <- Here we have a switch to softirq
>
>                                 /* We are now executing softirq ..*/
>                                 ...
>                                 ieee80211_wake_txqs()
>                                         _ieee80211_wake_txqs()
>                                                 rcu_read_lock()              <- nested rcu_read_lock() (OK I suppose)
>                                                 __ieee80211_wake_txqs()
>                                                         spin_lock_bh(&fq->lock);
>                                                         spin_unlock_bh(&fq->lock);
>                                                                 ath10k_mac_op_wake_tx_queue() /* via local->ops->wake_tx_queue() */
>                                                                         ath10k_mac_tx_push_txq()
>                                                                         ...
>                                                 rcu_read_unlock()
>                                 ...
>                 rcu_read_unlock()
>
> If, for some reason, ieee80211_next_txq() never returns NULL (the queues are
> being refilled while we are iterating), we could potentially spend a very long
> time in the loop with the RCU read lock held.
>
> Another reason could perhaps be that there are so many softirqs that we never
> have time to exit the loop from where ath10k_mac_schedule_txq() is called.
>
> Since I still run into the problem even if the RCU stall is removed, the root
> cause of the problem remains unknown.
>
> --
> Erik

^ permalink raw reply

* Re: [PATCH] mmc: dw_mmc: Disable SDIO interrupts while suspended to fix suspend/resume
From: Doug Anderson @ 2019-04-24  1:09 UTC (permalink / raw)
  To: Shawn Lin
  Cc: Jaehoon Chung, Ulf Hansson, Kalle Valo, Heiko Stübner,
	open list:ARM/Rockchip SoC..., Brian Norris, linux-wireless,
	Matthias Kaehlcke, Ryan Case, stable, Linux MMC List, LKML
In-Reply-To: <6e5c9395-51b0-7f28-ec91-de95cb54f58d@rock-chips.com>

Hi,

On Tue, Apr 23, 2019 at 5:57 PM Shawn Lin <shawn.lin@rock-chips.com> wrote:
>
> The intention seems reasonable to me, but just wonder if we need
> mask/unmask SDIO interrupt when it's never used?

I don't think we do.

Specifically "client_sdio_enb" starts out as false.  If nobody ever
calls dw_mci_enable_sdio_irq() then "client_sdio_enb" will always
continue to be false.

Now at suspend time we'll call "__dw_mci_enable_sdio_irq".  Because
"client_sdio_enb" is false then the local variable "enb" will always
be false.  Sure we'll clear the "SDMMC_INT_SDIO" from the "INTMASK"
register, but it should already have been cleared so this is a no-op.

...at resume time we'll have a similar situation where
"client_sdio_enb" is false and thus we'll (again) just clear the
"SDMMC_INT_SDIO" from the "INTMASK".

I could potentially optimize away the "mci_writel()" if we're not
changing anything if you're worried about that?


> It's the same
> situation for SDMMC_CLKEN_LOW_PWR that we couldn't stop providing
> clock for SDIO cards, so I guess we need to check MMC_CAP_SDIO_IRQ
> as well.

I think it might be a slightly different situation though.  In this
case I believe it's not just a problem with clock stoppage.  I believe
the problem is that the interrupt will be passed to the SDIO device
driver right away and that'll call back into dw_mmc.  dw_mmc is just
not in a state to handle it until we've more fully resumed things.

In any case with my patch the only way we'd ever end up unmasking the
SDIO IRQ here would be if dw_mci_enable_sdio_irq() was called.  That
will only happen if there's an SDIO card plugged in.


-Doug

^ permalink raw reply

* Re: [PATCH] mmc: dw_mmc: Disable SDIO interrupts while suspended to fix suspend/resume
From: Shawn Lin @ 2019-04-24  0:57 UTC (permalink / raw)
  To: Doug Anderson
  Cc: Jaehoon Chung, Ulf Hansson, shawn.lin, Kalle Valo,
	Heiko Stübner, open list:ARM/Rockchip SoC..., Brian Norris,
	linux-wireless, Matthias Kaehlcke, Ryan Case, stable,
	Linux MMC List, LKML
In-Reply-To: <CAD=FV=Wm+T+W=LWTSiwBT3UQWG7YKQdGuL2+BmAFQhk8CYY1mQ@mail.gmail.com>


On 2019/4/22 23:21, Doug Anderson wrote:
> Hi,
> 
> On Wed, Apr 10, 2019 at 3:13 PM Douglas Anderson <dianders@chromium.org> wrote:
>>
>> Processing SDIO interrupts while dw_mmc is suspended (or partly
>> suspended) seems like a bad idea.  We really don't want to be
>> processing them until we've gotten ourselves fully powered up.
>>
>> You might be wondering how it's even possible to become suspended when
>> an SDIO interrupt is active.  As can be seen in
>> dw_mci_enable_sdio_irq(), we explicitly keep dw_mmc out of runtime
>> suspend when the SDIO interrupt is enabled.  ...but even though we
>> stop normal runtime suspend transitions when SDIO interrupts are
>> enabled, the dw_mci_runtime_suspend() can still get called for a full
>> system suspend.
>>
>> Let's handle all this by explicitly masking SDIO interrupts in the
>> suspend call and unmasking them later in the resume call.  To do this
>> cleanly I'll keep track of whether the client requested that SDIO
>> interrupts be enabled so that we can reliably restore them regardless
>> of whether we're masking them for one reason or another.
>>
>> Without this fix it can be seen that rk3288-veyron Chromebooks with
>> Marvell WiFi would sometimes fail to resume WiFi even after picking my
>> recent mwifiex patch [1].  Specifically you'd see messages like this:
>>    mwifiex_sdio mmc1:0001:1: Firmware wakeup failed
>>    mwifiex_sdio mmc1:0001:1: PREP_CMD: FW in reset state
>>
>> ...and tracing through the resume code in the failing cases showed
>> that we were processing a SDIO interrupt really early in the resume
>> call.
>>
>> NOTE: downstream in Chrome OS 3.14 and 3.18 kernels (both of which
>> support the Marvell SDIO WiFi card) we had a patch ("CHROMIUM: sdio:
>> Defer SDIO interrupt handling until after resume") [2].  Presumably
>> this is the same problem that was solved by that patch.
>>
>> [1] https://lkml.kernel.org/r/20190404040106.40519-1-dianders@chromium.org
>> [2] https://crrev.com/c/230765
>>
>> Cc: <stable@vger.kernel.org>
>> Signed-off-by: Douglas Anderson <dianders@chromium.org>
>> ---
>> I didn't put any "Fixes" tag here, but presumably this could be
>> backported to whichever kernels folks found it useful for.  I have at
>> least confirmed that kernels v4.14 and v4.19 (as well as v5.1-rc2)
>> show the problem.  It is very easy to pick this to v4.19 and it
>> definitely fixes the problem there.
>>
>> I haven't spent the time to pick this to 4.14 myself, but presumably
>> it wouldn't be too hard to backport this as far as v4.13 since that
>> contains commit 32dba73772f8 ("mmc: dw_mmc: Convert to use
>> MMC_CAP2_SDIO_IRQ_NOTHREAD for SDIO IRQs").  Prior to that it might
>> make sense for anyone experiencing this problem to just pick the old
>> CHROMIUM patch to fix them.
>>
>>   drivers/mmc/host/dw_mmc.c | 24 ++++++++++++++++++++----
>>   drivers/mmc/host/dw_mmc.h |  3 +++
>>   2 files changed, 23 insertions(+), 4 deletions(-)
> 
> Jaehoon / Shawn: any thoughts on this patch?

The intention seems reasonable to me, but just wonder if we need
mask/unmask SDIO interrupt when it's never used?  It's the same
situation for SDMMC_CLKEN_LOW_PWR that we couldn't stop providing
clock for SDIO cards, so I guess we need to check MMC_CAP_SDIO_IRQ
as well.

> 
> -Doug
> 
> 
> 



^ permalink raw reply

* Re: [PATCH 1/2] mac80211: Fix Extended Key ID auto activation
From: Alexander Wetzel @ 2019-04-23 20:59 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless
In-Reply-To: <4464ea399dbbc1aca040ad8a4442a73f78cc38fb.camel@sipsolutions.net>

Am 23.04.19 um 14:14 schrieb Johannes Berg:
> On Mon, 2019-04-22 at 23:34 +0200, Alexander Wetzel wrote:
>> Only enable Extended Key ID support for drivers which are not supporting
>> crypto offload and also do not support A-MPDU.
>>
>> While any driver using SW crypto from mac80211 is generally able to also
>> support Extended Key ID these drivers are likely to mix keyIDs in
>> AMPDUs when rekeying.
>>
>> According to IEEE 802.11-2016 "9.7.3 A-MPDU contents" this is not
>> allowed.
>>
> 
> I applied this (with some changes), but please resend the other patch as
> two separate patches to mac80211/hwsim.

I've just dropped you the updated patch for hwsim Extended Key ID 
support. That's kind of critical for the attempt to get Extended Key ID 
support merged in hostapd/wpa_supplicant.

The patch to allow ptk0 rekeys with hwsim should follow soon. (The PTK0 
rekey patches I have for hostapd/wpa_supplicant still need serious work 
anyhow and are far away to be ready for merge.)

Alexander

^ permalink raw reply

* [PATCH] mac80211_hwsim: Extended Key ID support
From: Alexander Wetzel @ 2019-04-23 20:47 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Alexander Wetzel

Allow Extended Key ID to be used with hwsim.

Hwsim can only communicate with other hwsim cards, allowing it to bypass
creation of A-MPDUs in the first place.

Mixing keyIDs in an A-MPDU is therefore impossible and can never cause
interoperability issues with other cards.

Signed-off-by: Alexander Wetzel <alexander@wetzel-home.de>
---
 drivers/net/wireless/mac80211_hwsim.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 44cffd1f6dbf..7a0310715462 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2810,6 +2810,11 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
 	ieee80211_hw_set(hw, SIGNAL_DBM);
 	ieee80211_hw_set(hw, SUPPORTS_PS);
 	ieee80211_hw_set(hw, TDLS_WIDER_BW);
+
+	/* With only SW crypto support and only implementing the A-MPDU API
+	 * all requirements for Extended Key ID support are met.
+	 */
+	ieee80211_hw_set(hw, EXT_KEY_ID_NATIVE);
 	if (rctbl)
 		ieee80211_hw_set(hw, SUPPORTS_RC_TABLE);
 	ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID);
-- 
2.21.0


^ permalink raw reply related

* Re: [PATCH v7 15/21] x86/split_lock: Add a sysfs interface to enable/disable split lock detection during run time
From: Fenghua Yu @ 2019-04-23 20:48 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Ingo Molnar, Borislav Petkov, H Peter Anvin, Paolo Bonzini,
	Dave Hansen, Ashok Raj, Peter Zijlstra, Ravi V Shankar,
	Xiaoyao Li, Christopherson Sean J, Kalle Valo, Michael Chan,
	linux-kernel, x86, kvm, netdev, linux-wireless
In-Reply-To: <alpine.DEB.2.21.1904180832290.3174@nanos.tec.linutronix.de>

On Thu, Apr 18, 2019 at 08:41:30AM +0200, Thomas Gleixner wrote:
> On Wed, 17 Apr 2019, Fenghua Yu wrote:
> > On Thu, Apr 18, 2019 at 12:47:24AM +0200, Thomas Gleixner wrote:
> > > On Wed, 17 Apr 2019, Fenghua Yu wrote:
> > > 
> > > > The interface /sys/device/system/cpu/split_lock_detect is added
> > > > to allow user to control split lock detection and show current split
> > > > lock detection setting.
> > > > 
> > > > Writing [yY1] or [oO][nN] to the file enables split lock detection and
> > > > writing [nN0] or [oO][fF] disables split lock detection. Split lock
> > > > detection is enabled or disabled on all CPUs.
> > > > 
> > > > Reading the file returns current global split lock detection setting:
> > > > 0: disabled
> > > > 1: enabled
> > > 
> > > Again, You explain WHAT this patch does and still there is zero
> > > justification why this sysfs knob is needed at all. I still do not see any
> > > reason why this knob should exist.
> > 
> > An important application has split lock issues which are already discovered
> > and need to be fixed. But before the issues are fixed, sysadmin still wants to
> > run the application without rebooting the system, the sysfs knob can be useful
> > to turn off split lock detection. After the application is done, split lock
> > detection will be enabled again through the sysfs knob.
> 
> Are you sure that you are talking about the real world? I might buy the
> 'off' part somehow, but the 'on' part is beyond theoretical.
> 
> Even the 'off' part is dubious on a multi user machine. I personally would
> neither think about using the sysfs knob nor about rebooting the machine
> simply because I'd consider a lock operation accross a cacheline an malicious
> DoS attempt. Why would I allow that?
> 
> So in reality the sysadmin will either move the workload to a machine w/o
> the #AC magic or just tell the user to fix his crap.
> 
> > Without the sysfs knob, sysadmin has to reboot the system with kernel option
> > "no_split_lock_detect" to run the application before the split lock issues
> > are fixed.
> > 
> > Is this a valid justification why the sysfs knob is needed? If it is, I can
> > add the justification in the next version.
> 
> Why has this information not been in the changelog right away? I'm really
> tired of asking the same questions and pointing you to
> Documentation/process over and over.

So should I remove the sysfs knob patches in the next version?

Or add the following justification and still keep the sysfs knob patches?
"To workaround or debug a split lock issue, the administrator may need to
disable or enable split lock detection during run time without rebooting
the system."

Thanks.

-Fenghua

^ permalink raw reply

* Re: [wireless-regdb] [PATCH] wireless-regdb: Update regulatory rules for South Korea
From: b.K.il.h.u+tigbuh @ 2019-04-23 20:54 UTC (permalink / raw)
  Cc: linux-wireless@vger.kernel.org,
	wireless-regdb@lists.infradead.org
In-Reply-To: <af4d49d9-fc9e-ebe3-20ab-edef6c12a2eb@bowerswilkins.com>

Could you please convert the document in question to a more open
format so we could try machine translation on it? ODT, HTML, docx and
PDF would probably work as long as copy & pasting is enabled.

I found 1 offline and 2 online viewers, not sure which one works:
https://www.hancom.com/global/cs_center/csDownload.do
https://store.thinkfree.com/en/join
https://nid.naver.com/user2/V2Join.nhn?m=agree&lang=en_US&cpno=

The trial editor may also support exporting.

On Mon, Apr 22, 2019 at 8:05 PM Peter Oh <peter.oh@bowerswilkins.com> wrote:
> On 04/08/2019 05:41 AM, Seth Forshee wrote:
> > On Wed, Mar 27, 2019 at 06:34:29PM +0000, Peter Oh wrote:
> >> From: Peter Oh <peter.oh@bowerswilkins.com>
> >>
> >> Update power limit as documented in:
> >> https://www.rra.go.kr/FileDownSvl?file_type=LAWKR&file_parentseq=54&file_seq=27
> >> which revised on November 30, 2016.
> >>
> >> Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
> > I usually try to check the changes against the documents, but in this
> > case I haven't been able to get any English tranlation for the document
> > (or even view the contents it in any meaningful way). I don't suppose
> > you know where to find an English version of the document?
> Unfortunately there is no English version of the doc. Typically I use
> Google translation to understand foreign language, but in this case I
> contacted that department personally via phone call and directed to the
> doc by the responsible person from the department.
>
> Thanks,
> Peter

^ permalink raw reply

* ath10k: issue with TX queue scheduling
From: Erik Stromdahl @ 2019-04-23 14:58 UTC (permalink / raw)
  To: ath10k@lists.infradead.org, linux-wireless@vger.kernel.org
  Cc: Kalle Valo, Toke Høiland-Jørgensen, Niklas Cassel,
	johannes

Hello ath10k and mac80211 developers!

I have run into an issue with ath10k SDIO and iperf TX.

When running an iperf test (ath10k as server, PC as client),
I get a totally stalled transmitter on the ath10k side after some time.

[  3] 574.0-575.0 sec  3.25 MBytes  27.3 Mbits/sec
[  3] 575.0-576.0 sec   255 KBytes  2.09 Mbits/sec
[  3] 576.0-577.0 sec  0.00 Bytes  0.00 bits/sec
[  3] 577.0-578.0 sec  0.00 Bytes  0.00 bits/sec

Niklas Cassel had the same issue ~1 year ago and he made a fix in commit
3f04950f32d5

After this everything has been working fine until lately when I ran into the
same issue again.

The problem seems to have reappeared after the new mac80211 TX scheduling
was introduced. I have not bisected or anything, but last time I was doing
these tests was before the introduction of the new TX scheduling, and then
everything was working.

Niklas fix was to add a call to ath10k_mac_tx_push_pending() in
ath10k_sdio_irq_handler() in order to make sure we never get into a situation
where we have messages in the ath10k internal queue, but with TX queuing stopped.

Since the introduction of the new TX scheduling, the driver internal queue
has been removed (there used to be a txqs member in struct ath10k that was
removed in commit bb2edb733586 by Toke). So I am unsure if Niklas commit is
still needed. At least it does not seem to fix this issue anymore.

Are there any nice mac80211 kernel config options available that could
ease debugging queuing related issues?
Some kind of tracing feature for the TX scheduling perhaps?

All tips/hints are welcome!

P.S.

When I run into the error I also get the below RCU stall splat (~20 seconds after
the bitrate has dropped down to 0 bit/s):

rcu: INFO: rcu_sched self-detected stall on CPU
rcu: 	0-....: (2600 ticks this GP) idle=02a/1/0x40000002 softirq=1107/1107 fqs=1294
rcu: 	 (t=2602 jiffies g=633 q=102)
NMI backtrace for cpu 0
CPU: 0 PID: 120 Comm: irq/64-mmc0 Tainted: G      D           5.1.0-rc3-wt-ath+ #31
Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
Backtrace:
[<c010ecec>] (dump_backtrace) from [<c010efec>] (show_stack+0x20/0x24)
  r7:00000000 r6:60010193 r5:00000000 r4:c14e9ecc
[<c010efcc>] (show_stack) from [<c0cf5674>] (dump_stack+0xdc/0x114)
[<c0cf5598>] (dump_stack) from [<c0cfcd0c>] (nmi_cpu_backtrace+0xac/0xbc)
  r10:80010193 r9:c14149fc r8:c0e02fd8 r7:00000000 r6:c0112318 r5:00000000
  r4:00000000 r3:02fc7d23
[<c0cfcc60>] (nmi_cpu_backtrace) from [<c0cfce04>] (nmi_trigger_cpumask_backtrace+0xe8/0x13c)
  r5:c1418a30 r4:00000000
[<c0cfcd1c>] (nmi_trigger_cpumask_backtrace) from [<c01132cc>] (arch_trigger_cpumask_backtrace+0x1c/0x24)
  r9:c14149fc r8:c142a880 r7:00000240 r6:c0e02fd4 r5:c1414978 r4:c142a880
[<c01132b0>] (arch_trigger_cpumask_backtrace) from [<c01b6220>] (rcu_dump_cpu_stacks+0xb8/0xfc)
[<c01b6168>] (rcu_dump_cpu_stacks) from [<c01b42a8>] (rcu_sched_clock_irq+0x890/0x9c0)
  r10:00000066 r9:c142a880 r8:c1414970 r7:c14f30f0 r6:c1405900 r5:c1414ed4
  r4:e671b100
[<c01b3a18>] (rcu_sched_clock_irq) from [<c01be570>] (update_process_times+0x40/0x6c)
  r10:c14150fc r9:e6716740 r8:c1414970 r7:00000027 r6:00000000 r5:d261f2c0
  r4:ffffe000
[<c01be530>] (update_process_times) from [<c01d4d04>] (tick_sched_handle+0x64/0x68)
  r7:00000027 r6:97c52581 r5:d288fba8 r4:e6716c00
[<c01d4ca0>] (tick_sched_handle) from [<c01d4fd8>] (tick_sched_timer+0x6c/0xd0)
[<c01d4f6c>] (tick_sched_timer) from [<c01bf3e0>] (__hrtimer_run_queues+0x1a8/0x5ac)
  r7:c01d4f6c r6:e67167a0 r5:e6716740 r4:e6716c00
[<c01bf238>] (__hrtimer_run_queues) from [<c01c08c0>] (hrtimer_interrupt+0x124/0x2ec)
  r10:e6716880 r9:ffffffff r8:7fffffff r7:e6716840 r6:00000003 r5:20010193
  r4:e6716740
[<c01c079c>] (hrtimer_interrupt) from [<c0113cec>] (twd_handler+0x3c/0x50)
  r10:c14f2cf4 r9:c1414ed4 r8:00000010 r7:c1414970 r6:c1415110 r5:d20d4900
  r4:00000001
[<c0113cb0>] (twd_handler) from [<c019eb50>] (handle_percpu_devid_irq+0xec/0x394)
  r5:d20d4900 r4:d2037800
[<c019ea64>] (handle_percpu_devid_irq) from [<c0197e48>] (generic_handle_irq+0x30/0x44)
  r10:c146c114 r9:d2024400 r8:00000001 r7:00000000 r6:c1414ed4 r5:00000010
  r4:c13e4450
[<c0197e18>] (generic_handle_irq) from [<c0198554>] (__handle_domain_irq+0x74/0xf0)
[<c01984e0>] (__handle_domain_irq) from [<c01024b4>] (gic_handle_irq+0x68/0xcc)
  r9:d288fba8 r8:c1415110 r7:f4000100 r6:000003ff r5:000003eb r4:f400010c
[<c010244c>] (gic_handle_irq) from [<c0101a70>] (__irq_svc+0x70/0x98)
Exception stack(0xd288fba8 to 0xd288fbf0)
fba0:                   c013417c 00000000 60010093 d288e000 000001ff ffffe000
fbc0: c0cb7340 00000003 d2fd86a0 d28c2000 d2fd86a0 d288fc14 d288fbc8 d288fbf8
fbe0: c0213544 c0134180 60010013 ffffffff
  r10:d2fd86a0 r9:d288e000 r8:d2fd86a0 r7:d288fbdc r6:ffffffff r5:60010013
  r4:c0134180
[<c01340c8>] (__local_bh_enable_ip) from [<c0d18b84>] (_raw_spin_unlock_bh+0x40/0x44)
  r7:00000003 r6:d21a88c0 r5:d2fd873c r4:c0cb7340
[<c0d18b44>] (_raw_spin_unlock_bh) from [<c0cb7340>] (_ieee80211_wake_txqs+0x394/0x6d4)
  r5:d21a88c0 r4:00000000
[<c0cb6fac>] (_ieee80211_wake_txqs) from [<c0cba838>] (ieee80211_wake_txqs+0x44/0x70)
  r10:00000006 r9:00000000 r8:00000000 r7:e6711404 r6:d2fd86a0 r5:d2fd8b10
  r4:c1414948
[<c0cba7f4>] (ieee80211_wake_txqs) from [<c0134a04>] (tasklet_action_common.constprop.5+0x64/0xec)
  r6:00000000 r5:d2fd908c r4:d2fd9088
[<c01349a0>] (tasklet_action_common.constprop.5) from [<c0134ac8>] (tasklet_action+0x3c/0x48)
  r10:00000040 r9:00000101 r8:c1414970 r7:c14f2ca4 r6:00000006 r5:c1403098
  r4:00000007 r3:25336000
[<c0134a8c>] (tasklet_action) from [<c0102610>] (__do_softirq+0xf8/0x54c)
[<c0102518>] (__do_softirq) from [<c01340bc>] (do_softirq.part.4+0x78/0x84)
  r10:d21a87cc r9:00000000 r8:00000000 r7:d2fd9e30 r6:bf058104 r5:ffffe000
  r4:60010093
[<c0134044>] (do_softirq.part.4) from [<c01341fc>] (__local_bh_enable_ip+0x134/0x18c)
  r5:ffffe000 r4:000001ff
[<c01340c8>] (__local_bh_enable_ip) from [<c0d18b84>] (_raw_spin_unlock_bh+0x40/0x44)
  r7:d2fd9e30 r6:d2fd9d38 r5:d2fd9e30 r4:bf058104
[<c0d18b44>] (_raw_spin_unlock_bh) from [<bf058104>] (ath10k_mac_tx_push_txq+0x294/0x2a4 [ath10k_core])
  r5:d2fd9540 r4:d33220dc
[<bf057e70>] (ath10k_mac_tx_push_txq [ath10k_core]) from [<bf05820c>] (ath10k_mac_tx_push_pending+0xf8/0x1ec [ath10k_core])
  r10:ffffe8ed r9:d2d96540 r8:fffffffe r7:00000002 r6:00000002 r5:d33220dc
  r4:d2fd86a0
[<bf058114>] (ath10k_mac_tx_push_pending [ath10k_core]) from [<bf0e2544>] (ath10k_sdio_irq_handler+0x308/0x4d4 [ath10k_sdio])
  r8:01340202 r7:d2fde540 r6:d2fde87c r5:00000000 r4:d2fd9540
[<bf0e223c>] (ath10k_sdio_irq_handler [ath10k_sdio]) from [<c08e86c0>] (process_sdio_pending_irqs+0x4c/0x1bc)
  r10:d287bb80 r9:d22a7400 r8:00000001 r7:00000000 r6:d284c800 r5:c1414948
  r4:d2859000
[<c08e8674>] (process_sdio_pending_irqs) from [<c08e887c>] (sdio_run_irqs+0x4c/0x68)
  r10:d287bb80 r9:d22a7400 r8:00000001 r7:00000000 r6:d28596a0 r5:00000100
  r4:d2859000
[<c08e8830>] (sdio_run_irqs) from [<c08f3d00>] (sdhci_thread_irq+0x80/0xbc)
  r5:00000100 r4:d28594c0
[<c08f3c80>] (sdhci_thread_irq) from [<c019a718>] (irq_thread_fn+0x2c/0x88)
  r7:00000000 r6:d287bba4 r5:d22a7400 r4:d287bb80
[<c019a6ec>] (irq_thread_fn) from [<c019aa54>] (irq_thread+0x120/0x22c)
  r7:00000000 r6:d287bba4 r5:ffffe000 r4:00000000
[<c019a934>] (irq_thread) from [<c015526c>] (kthread+0x154/0x168)
  r10:d2101bd8 r9:c019a934 r8:d287bb80 r7:d288e000 r6:d287bbc0 r5:d2241400
  r4:00000000
[<c0155118>] (kthread) from [<c01010b4>] (ret_from_fork+0x14/0x20)
Exception stack(0xd288ffb0 to 0xd288fff8)
ffa0:                                     00000000 00000000 00000000 00000000
ffc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
ffe0: 00000000 00000000 00000000 00000000 00000013 00000000
  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0155118
  r4:d287bbc0

I have a patch where I have rewritten ath10k_mac_tx_push_pending() somewhat in
order to reduce the time spent in the RCU critical read section.

With this patch the RCU stall warning disappears and the transmitter "recovers"
after some time ( I still get the 0 bit/s drop though).

Below is list of function calls of a potential scenario (derived from the above backtrace):

ath10k_sdio_irq_handler()
	ath10k_mac_tx_push_pending()
		rcu_read_lock()                              <- This RCU read lock causes the stall
		ath10k_mac_schedule_txq()                    <- Called in a loop for each ac
			ieee80211_txq_schedule_start()
			ath10k_mac_tx_push_txq()                 <- Called in a loop where we iterate
			                                            all queues using ieee80211_next_txq
				...
				spin_lock_bh(&ar->htt.tx_lock)
				...
				spin_unlock_bh(&ar->htt.tx_lock)     <- Here we have a switch to softirq

				/* We are now executing softirq ..*/
				...
				ieee80211_wake_txqs()
					_ieee80211_wake_txqs()
						rcu_read_lock()              <- nested rcu_read_lock() (OK I suppose)
						__ieee80211_wake_txqs()
							spin_lock_bh(&fq->lock);
							spin_unlock_bh(&fq->lock);
								ath10k_mac_op_wake_tx_queue() /* via local->ops->wake_tx_queue() */
									ath10k_mac_tx_push_txq()
									...
						rcu_read_unlock()
				...
		rcu_read_unlock()

If, for some reason, ieee80211_next_txq() never returns NULL (the queues are
being refilled while we are iterating), we could potentially spend a very long
time in the loop with the RCU read lock held.

Another reason could perhaps be that there are so many softirqs that we never
have time to exit the loop from where ath10k_mac_schedule_txq() is called.

Since I still run into the problem even if the RCU stall is removed, the root
cause of the problem remains unknown.

--
Erik

^ permalink raw reply

* [PATCH] rtlwifi: rtl8192cu: remove set but not used variable 'turbo_scanoff'
From: Yue Haibing @ 2019-04-23 14:32 UTC (permalink / raw)
  To: pkshih, kvalo, Larry.Finger
  Cc: linux-kernel, netdev, linux-wireless, davem, YueHaibing

From: YueHaibing <yuehaibing@huawei.com>

Fixes gcc '-Wunused-but-set-variable' warning:

drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c: In function 'rtl92cu_phy_rf6052_set_cck_txpower':
drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c:45:7: warning: variable 'turbo_scanoff' set but not used [-Wunused-but-set-variable]

It is not used any more since
commit e9b0784bb9de ("rtlwifi: rtl8192cu: Fix some code in RF handling")

Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
 drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c
index f3a336e..d259794 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c
@@ -42,12 +42,9 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 	u32 tx_agc[2] = { 0, 0 }, tmpval = 0;
-	bool turbo_scanoff = false;
 	u8 idx1, idx2;
 	u8 *ptr;
 
-	if ((rtlefuse->eeprom_regulatory != 0) || (rtlefuse->external_pa))
-		turbo_scanoff = true;
 	if (mac->act_scanning) {
 		tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
 		tx_agc[RF90_PATH_B] = 0x3f3f3f3f;
-- 
2.7.0



^ permalink raw reply related

* Re: [PATCH] iwlwifi: don't panic in error path on non-msix systems
From: Luca Coelho @ 2019-04-23 13:27 UTC (permalink / raw)
  To: Kirtika Ruchandani, Michal Hocko
  Cc: kvalo, Johannes Berg, Grumbach, Emmanuel, linuxwifi, linux-kernel,
	linux-wireless, Shahar S Matityahu
In-Reply-To: <CAOXD1ic49hhkPb6ABPgBEim_iyxvDP82Hfn0yvz7vyFR4Rp53Q@mail.gmail.com>

On Mon, 2019-04-22 at 19:34 -0700, Kirtika Ruchandani wrote:
> On Mon, Apr 22, 2019 at 4:56 PM Kirtika Ruchandani <
> kirtika@google.com> wrote:
> > On Mon, Apr 22, 2019 at 11:07 AM Michal Hocko <mhocko@kernel.org>
> > wrote:
> > > On Wed 17-04-19 10:35:16, Luca Coelho wrote:
> > > > From: Shahar S Matityahu <shahar.s.matityahu@intel.com>
> > > > 
> > > > The driver uses msix causes-register to handle both msix and
> > > > non msix
> > > > interrupts when performing sync nmi.  On devices that do not
> > > > support
> > > > msix this register is unmapped and accessing it causes a kernel
> > > > panic.
> > > > 
> > > > Solve this by differentiating the two cases and accessing the
> > > > proper
> > > > causes-register in each case.
> > 
> > Are you sure reading CSR_INT from trans.c without explicitly
> > getting irq_lock.c
> > like rx.c does, is thread-safe? I don't claim to understand this
> > fully, but this
> > smells wrong from past experience with this driver. I'll see if I
> > can cook up
> > a test case with a race condition here.
> 
> Sorry for the typos. I meant "writing (not reading) to CSR_INT in
> iwl_trans_pcie_sync_nmi
> without explicitly getting trans_pcie->irq_lock like
> iwl_pcie_irq_handler does".
> I spent some time playing around this, and while I don't have a
> black-and-white
> test-case to show this patch has side-effects (at the very least), I
> have some notes:
> 
> 1. Repeatedly sending fw_nmi is a good test-case for the problem this
> patch
> is trying to solve. i.e.  I had
> $ cd /sys/kernel/debug/iwlwifi/${PCI_ID}/iwlmvm/
> $ while true; do echo 1 > fw_nmi ; done  # this is likely too harsh
> and needs a sleep in b/w
> 
> With the current ToT driver in wireless-drivers-next, this ramoops-es
> super quickly after hitting
> the problematic MSI-X read.
> 
> 2. With this patch applied, I hit an ADVANCED_SYSASSERT 0x0 and it
> took ~800ms
> and dozens of kernel warnings before the driver "recovered".
> I've sent the full dmesg to Luca off-list.
> It didn't get any better with adding spin_lock(&trans_pcie->irq_lock)
> / spin_unlock(&trans_pcie->irq_lock)
> around the problematic CSR_INT write in iwl_trans_sync_nmi.
> 
> So I still don't have any concrete reasoning or proof, except a dmesg
> after a test that doesn't look right.
> Apologies if this discussion is moot - FWIW, the thing that caused a
> code smell in the first place
> was that historically, nothing in trans.c had mucked with writing to
> CSR_INT, except when enabling interrupts again
> with a 0xFFFFFFFF at _initialization time_ (and we've seen race
> conditions there in the past).
> You can check this with `git grep -p -w CSR_INT trans.c`.


Hi Kirtika,

I think the SYSASSERT issue you found is unrelated.  Can we track that
separately? Again, it seems that we're doing something wrong during
recovery, which causes the many warnings and long time to recover...

Regarding the spinlock, I'm not sure.  It seems that we don't need it,
because we're just writing to the register.  Maybe some of the other
blocks that are spinlocked must have a guarantee that no one will
change the register in the middle of it.  But before we add the
spinlocks, we should check if that really is the case.

We'll check the dmesg you sent us, but I think it's better to create a
new issue in the tracker for it.

--
Cheers,
Luca.


^ permalink raw reply

* Re: [PATCH v2 1/5] ath10k: add initialization of HTC header
From: Kalle Valo @ 2019-04-23 13:26 UTC (permalink / raw)
  To: Erik Stromdahl
  Cc: kvalo, linux-wireless, ath10k, Alagu Sankar, Erik Stromdahl
In-Reply-To: <20190417191503.18814-2-erik.stromdahl@gmail.com>

Erik Stromdahl <erik.stromdahl@gmail.com> wrote:

> HTC header carries junk values that may be interpreted by the firmware
> differently. Enable credit update only if flow control is enabled for
> the corresponding endpoint.
> 
> Signed-off-by: Alagu Sankar <alagusankar@silex-india.com>
> Signed-off-by: Erik Stromdahl <erik.stromdahl@gmail.com>
> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>

2 patches applied to ath-next branch of ath.git, thanks.

fbd428a5b828 ath10k: add initialization of HTC header
f91b63b0e3b2 ath10k: sdio: add missing error check

-- 
https://patchwork.kernel.org/patch/10906001/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


^ permalink raw reply

* Re: [PATCH 1/6] ath10k: sdio: workaround firmware UART pin configuration bug
From: Kalle Valo @ 2019-04-23 13:25 UTC (permalink / raw)
  To: Kalle Valo; +Cc: ath10k, linux-wireless
In-Reply-To: <155507569645.32018.15231567732563770250.stgit@potku.adurom.net>

Kalle Valo <kvalo@codeaurora.org> wrote:

> On QCA6174 SDIO devices the SDIO interrupt will fail if UART is
> disabled from ath10k. SDIO firmware enables UART printouts by
> default. If ath10k will try to enable UART again the firmware
> will configure it's GPIO line incorrectly and SDIO interrupts
> won't work anymore. The workaround is to set UART pin again (19
> for QCA6174 SDIO) if uart_print is 0.
> 
> Tested with QCA6174 SDIO with firmware WLAN.RMH.4.4.1-00007-QCARMSWP-1.
> 
> Signed-off-by: Wen Gong <wgong@codeaurora.org>
> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>

6 patches applied to ath-next branch of ath.git, thanks.

4504f0e5b571 ath10k: sdio: workaround firmware UART pin configuration bug
70736b9753fd ath10k: don't disable interrupts in ath10k_sdio_remove()
e2a6b711282a ath10k: htt: don't use txdone_fifo with SDIO
6d084ac27ab4 ath10k: initialise struct ath10k_bus params to zero
8ea51e409eb0 ath10k: htt: support MSDU ids with SDIO
30382dd1cf3a ath10k: fix use-after-free on SDIO data frames

-- 
https://patchwork.kernel.org/patch/10898285/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


^ permalink raw reply

* Re: [PATCH 5/5] mac80211: set NETIF_F_LLTX when using intermediate tx queues
From: Johannes Berg @ 2019-04-23 12:41 UTC (permalink / raw)
  To: Toke Høiland-Jørgensen, Herbert Xu
  Cc: Arend Van Spriel, Felix Fietkau, linux-wireless, Eric Dumazet,
	netdev
In-Reply-To: <87tvexrnxm.fsf@toke.dk>

On Wed, 2019-04-17 at 10:17 +0100, Toke Høiland-Jørgensen wrote:
> Herbert Xu <herbert@gondor.apana.org.au> writes:
> 
> > On Tue, Apr 16, 2019 at 02:18:36PM +0100, Toke Høiland-Jørgensen wrote:
> > > 
> > > > The congestion control happens at two levels. You are right that the
> > > > socket buffer acts as one limit. However, other applications may also
> > > > rely on the TX queue being full as the throttle (by setting a
> > > > sufficiently large socket buffer size).
> > > 
> > > Do you happen to have an example of an application that does this that
> > > could be used for testing? :)
> > 
> > Have a look at
> > 
> > commit 6ce9e7b5fe3195d1ae6e3a0753d4ddcac5cd699e
> > Author: Eric Dumazet <eric.dumazet@gmail.com>
> > Date:   Wed Sep 2 18:05:33 2009 -0700
> > 
> >     ip: Report qdisc packet drops
> > 
> > You should be able to do a UDP flood while setting IP_RECVERR to
> > detect the packet drop due to a full queue which AFAICS will never
> > happen with the current mac80211 setup.
> 
> Also, looking at udp.c, it seems it uses net_xmit_errno() - which means
> that returning NET_XMIT_CN has the same effect as NET_XMIT_SUCCESS when
> propagated back to userspace? Which would kinda defeat the point of
> going to the trouble of propagating up the return code (the mac80211
> queue will never drop the most recently enqueued packet)...

I guess there might be value in returning NET_XMIT_CN anyway, but I
think you're right in that we can never return anything but
NET_XMIT_SUCCESS or NET_XMIT_CN since we never drop this new packet,
just older ones.

Which, btw, is exactly the same with net/sched/sch_fq_codel.c, AFAICT?

johannes


^ permalink raw reply

* KASAN: invalid-free in rsi_91x_deinit
From: syzbot @ 2019-04-23 12:36 UTC (permalink / raw)
  To: amitkarwar, andreyknvl, davem, kvalo, linux-kernel, linux-usb,
	linux-wireless, netdev, siva8118, syzkaller-bugs

Hello,

syzbot found the following crash on:

HEAD commit:    d34f9519 usb-fuzzer: main usb gadget fuzzer driver
git tree:       https://github.com/google/kasan/tree/usb-fuzzer
console output: https://syzkaller.appspot.com/x/log.txt?x=14a79403200000
kernel config:  https://syzkaller.appspot.com/x/.config?x=c73d1bb5aeaeae20
dashboard link: https://syzkaller.appspot.com/bug?extid=7c72edfb407b2bd866ce
compiler:       gcc (GCC) 9.0.0 20181231 (experimental)
syz repro:      https://syzkaller.appspot.com/x/repro.syz?x=17547247200000
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=147b3a1d200000

IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+7c72edfb407b2bd866ce@syzkaller.appspotmail.com

usb 1-1: config 252 interface 115 altsetting 0 has 1 endpoint descriptor,  
different from the interface descriptor's value: 4
usb 1-1: New USB device found, idVendor=1618, idProduct=9113,  
bcdDevice=32.21
usb 1-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
rsi_91x: rsi_probe: Failed to init usb interface
==================================================================
BUG: KASAN: double-free or invalid-free in slab_free mm/slub.c:3003 [inline]
BUG: KASAN: double-free or invalid-free in kfree+0xce/0x280 mm/slub.c:3958

CPU: 0 PID: 12 Comm: kworker/0:1 Not tainted 5.1.0-rc5-319617-gd34f951 #4
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS  
Google 01/01/2011
Workqueue: usb_hub_wq hub_event
Call Trace:
  __dump_stack lib/dump_stack.c:77 [inline]
  dump_stack+0xe8/0x16e lib/dump_stack.c:113
  print_address_description+0x6c/0x236 mm/kasan/report.c:187
  kasan_report_invalid_free+0x66/0xa0 mm/kasan/report.c:278
  __kasan_slab_free+0x162/0x180 mm/kasan/common.c:438
  slab_free_hook mm/slub.c:1429 [inline]
  slab_free_freelist_hook+0x5e/0x140 mm/slub.c:1456
  slab_free mm/slub.c:3003 [inline]
  kfree+0xce/0x280 mm/slub.c:3958
  rsi_91x_deinit+0x27b/0x300 drivers/net/wireless/rsi/rsi_91x_main.c:407
  rsi_probe+0xdf3/0x140d drivers/net/wireless/rsi/rsi_91x_sdio.c:1178
  usb_probe_interface+0x31d/0x820 drivers/usb/core/driver.c:361
  really_probe+0x2da/0xb10 drivers/base/dd.c:509
  driver_probe_device+0x21d/0x350 drivers/base/dd.c:671
  __device_attach_driver+0x1d8/0x290 drivers/base/dd.c:778
  bus_for_each_drv+0x163/0x1e0 drivers/base/bus.c:454
  __device_attach+0x223/0x3a0 drivers/base/dd.c:844
  bus_probe_device+0x1f1/0x2a0 drivers/base/bus.c:514
  device_add+0xad2/0x16e0 drivers/base/core.c:2106
  usb_set_configuration+0xdf7/0x1740 drivers/usb/core/message.c:2021
  generic_probe+0xa2/0xda drivers/usb/core/generic.c:210
  usb_probe_device+0xc0/0x150 drivers/usb/core/driver.c:266
  really_probe+0x2da/0xb10 drivers/base/dd.c:509
  driver_probe_device+0x21d/0x350 drivers/base/dd.c:671
  __device_attach_driver+0x1d8/0x290 drivers/base/dd.c:778
  bus_for_each_drv+0x163/0x1e0 drivers/base/bus.c:454
  __device_attach+0x223/0x3a0 drivers/base/dd.c:844
  bus_probe_device+0x1f1/0x2a0 drivers/base/bus.c:514
  device_add+0xad2/0x16e0 drivers/base/core.c:2106
  usb_new_device.cold+0x537/0xccf drivers/usb/core/hub.c:2534
  hub_port_connect drivers/usb/core/hub.c:5089 [inline]
  hub_port_connect_change drivers/usb/core/hub.c:5204 [inline]
  port_event drivers/usb/core/hub.c:5350 [inline]
  hub_event+0x1398/0x3b00 drivers/usb/core/hub.c:5432
  process_one_work+0x90f/0x1580 kernel/workqueue.c:2269
  worker_thread+0x9b/0xe20 kernel/workqueue.c:2415
  kthread+0x313/0x420 kernel/kthread.c:253
  ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:352

Allocated by task 12:
  set_track mm/kasan/common.c:87 [inline]
  __kasan_kmalloc mm/kasan/common.c:497 [inline]
  __kasan_kmalloc.constprop.0+0xbf/0xd0 mm/kasan/common.c:470
  rsi_init_sdio_interface drivers/net/wireless/rsi/rsi_91x_sdio.c:853  
[inline]
  rsi_probe+0x11a/0x140d drivers/net/wireless/rsi/rsi_91x_sdio.c:965
  usb_probe_interface+0x31d/0x820 drivers/usb/core/driver.c:361
  really_probe+0x2da/0xb10 drivers/base/dd.c:509
  driver_probe_device+0x21d/0x350 drivers/base/dd.c:671
  __device_attach_driver+0x1d8/0x290 drivers/base/dd.c:778
  bus_for_each_drv+0x163/0x1e0 drivers/base/bus.c:454
  __device_attach+0x223/0x3a0 drivers/base/dd.c:844
  bus_probe_device+0x1f1/0x2a0 drivers/base/bus.c:514
  device_add+0xad2/0x16e0 drivers/base/core.c:2106
  usb_set_configuration+0xdf7/0x1740 drivers/usb/core/message.c:2021
  generic_probe+0xa2/0xda drivers/usb/core/generic.c:210
  usb_probe_device+0xc0/0x150 drivers/usb/core/driver.c:266
  really_probe+0x2da/0xb10 drivers/base/dd.c:509
  driver_probe_device+0x21d/0x350 drivers/base/dd.c:671
  __device_attach_driver+0x1d8/0x290 drivers/base/dd.c:778
  bus_for_each_drv+0x163/0x1e0 drivers/base/bus.c:454
  __device_attach+0x223/0x3a0 drivers/base/dd.c:844
  bus_probe_device+0x1f1/0x2a0 drivers/base/bus.c:514
  device_add+0xad2/0x16e0 drivers/base/core.c:2106
  usb_new_device.cold+0x537/0xccf drivers/usb/core/hub.c:2534
  hub_port_connect drivers/usb/core/hub.c:5089 [inline]
  hub_port_connect_change drivers/usb/core/hub.c:5204 [inline]
  port_event drivers/usb/core/hub.c:5350 [inline]
  hub_event+0x1398/0x3b00 drivers/usb/core/hub.c:5432
  process_one_work+0x90f/0x1580 kernel/workqueue.c:2269
  worker_thread+0x9b/0xe20 kernel/workqueue.c:2415
  kthread+0x313/0x420 kernel/kthread.c:253
  ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:352

Freed by task 12:
  set_track mm/kasan/common.c:87 [inline]
  __kasan_slab_free+0x130/0x180 mm/kasan/common.c:459
  slab_free_hook mm/slub.c:1429 [inline]
  slab_free_freelist_hook+0x5e/0x140 mm/slub.c:1456
  slab_free mm/slub.c:3003 [inline]
  kfree+0xce/0x280 mm/slub.c:3958
  rsi_probe+0xf04/0x140d drivers/net/wireless/rsi/rsi_91x_sdio.c:1196
  usb_probe_interface+0x31d/0x820 drivers/usb/core/driver.c:361
  really_probe+0x2da/0xb10 drivers/base/dd.c:509
  driver_probe_device+0x21d/0x350 drivers/base/dd.c:671
  __device_attach_driver+0x1d8/0x290 drivers/base/dd.c:778
  bus_for_each_drv+0x163/0x1e0 drivers/base/bus.c:454
  __device_attach+0x223/0x3a0 drivers/base/dd.c:844
  bus_probe_device+0x1f1/0x2a0 drivers/base/bus.c:514
  device_add+0xad2/0x16e0 drivers/base/core.c:2106
  usb_set_configuration+0xdf7/0x1740 drivers/usb/core/message.c:2021
  generic_probe+0xa2/0xda drivers/usb/core/generic.c:210
  usb_probe_device+0xc0/0x150 drivers/usb/core/driver.c:266
  really_probe+0x2da/0xb10 drivers/base/dd.c:509
  driver_probe_device+0x21d/0x350 drivers/base/dd.c:671
  __device_attach_driver+0x1d8/0x290 drivers/base/dd.c:778
  bus_for_each_drv+0x163/0x1e0 drivers/base/bus.c:454
  __device_attach+0x223/0x3a0 drivers/base/dd.c:844
  bus_probe_device+0x1f1/0x2a0 drivers/base/bus.c:514
  device_add+0xad2/0x16e0 drivers/base/core.c:2106
  usb_new_device.cold+0x537/0xccf drivers/usb/core/hub.c:2534
  hub_port_connect drivers/usb/core/hub.c:5089 [inline]
  hub_port_connect_change drivers/usb/core/hub.c:5204 [inline]
  port_event drivers/usb/core/hub.c:5350 [inline]
  hub_event+0x1398/0x3b00 drivers/usb/core/hub.c:5432
  process_one_work+0x90f/0x1580 kernel/workqueue.c:2269
  worker_thread+0x9b/0xe20 kernel/workqueue.c:2415
  kthread+0x313/0x420 kernel/kthread.c:253
  ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:352

The buggy address belongs to the object at ffff888214af0c80
  which belongs to the cache kmalloc-512 of size 512
The buggy address is located 0 bytes inside of
  512-byte region [ffff888214af0c80, ffff888214af0e80)
The buggy address belongs to the page:
page:ffffea000852bc00 count:1 mapcount:0 mapping:ffff88812c3f4c00  
index:0xffff888214af1180 compound_mapcount: 0
flags: 0x57ff00000010200(slab|head)
raw: 057ff00000010200 ffffea00086b3780 0000000800000008 ffff88812c3f4c00
raw: ffff888214af1180 00000000800c000a 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
  ffff888214af0b80: 00 00 00 00 00 00 00 00 00 00 00 fc fc fc fc fc
  ffff888214af0c00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> ffff888214af0c80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
                    ^
  ffff888214af0d00: fb fb fb fb fb fb f


---
This bug is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.

syzbot will keep track of this bug report. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
syzbot can test patches for this bug, for details see:
https://goo.gl/tpsmEJ#testing-patches

^ permalink raw reply

* Re: question: crda timeout in cfg80211
From: Johannes Berg @ 2019-04-23 12:31 UTC (permalink / raw)
  To: Sergey Matyukevich
  Cc: linux-wireless@vger.kernel.org, Igor Mitsyanko, Luis Chamberlain
In-Reply-To: <20190411124030.3epjsukmgwfncz6d@bars>

Hi Sergey,

On Thu, 2019-04-11 at 12:40 +0000, Sergey Matyukevich wrote:
> Calling regulatory notifiers in parallel sounds like a good idea.
> But I haven't yet looked into the details as well. Before fixing
> the timeout issue, I was trying to figure out why that regulatory
> reset was needed at all.

:-)

> Here is a simple usecase: Linux distro sets regulatory region to US,
> STA is connected to AP. Any STA disconnect (including an attempt to
> reconnect to another AP) leads to regulatory reset cycle: US -> 00 -> US.
> This reset cycle is not supposed to be done for the wireless cards that
> specify REGULATORY_COUNTRY_IE_IGNORE flag. However regulatory reset will
> be applied anyway if at least one card in the system does not specify
> that flag.
> 
> Hence two questions:
> Do we really need this kind of reset when we remain
> in the same regulatory domain ? 

Probably doesn't make sense. If I were to guess I'd say that was a
simplification, since in many cases we'd actually be doing something
like (intersected) -> 00 -> US?

Actually, in your example, we're probably doing "US->00" and "00->US"
separately since we don't really know that we're going to connect again
to a similar AP, right?

Adding Luis, just in case he remembers anything about this ...

> Does it make sense to track when restore_regulatory_settings performs
> reset, and to skip reset for the cards that specify
> REGULATORY_COUNTRY_IE_IGNORE ?

I guess that'd make some sense anyway?

I do think ultimately we need some kind of reset every once a while when
we're disconnected, otherwise we'll just carry around intersections and
other baggage forever.

johannes


^ permalink raw reply

* Re: [PATCH 1/2] mac80211: Fix Extended Key ID auto activation
From: Johannes Berg @ 2019-04-23 12:14 UTC (permalink / raw)
  To: Alexander Wetzel; +Cc: linux-wireless
In-Reply-To: <20190422213412.16533-1-alexander@wetzel-home.de>

On Mon, 2019-04-22 at 23:34 +0200, Alexander Wetzel wrote:
> Only enable Extended Key ID support for drivers which are not supporting
> crypto offload and also do not support A-MPDU.
> 
> While any driver using SW crypto from mac80211 is generally able to also
> support Extended Key ID these drivers are likely to mix keyIDs in
> AMPDUs when rekeying.
> 
> According to IEEE 802.11-2016 "9.7.3 A-MPDU contents" this is not
> allowed.
> 

I applied this (with some changes), but please resend the other patch as
two separate patches to mac80211/hwsim.

johannes


^ permalink raw reply

* [PATCH v2 3/3] mt76x02: remove bogus mutex usage
From: Stanislaw Gruszka @ 2019-04-23 10:37 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi
In-Reply-To: <20190423103709.7272-1-sgruszka@redhat.com>

mac80211 .start(), .stop() callbacks are never called concurrently with
other callbacks. The only concurencly is with mt76 works which we cancel
on stop() and schedule on start().

This fixes possible deadlock on cancel_delayed_work_sync(&dev->mac_work)
as mac_work also take mutex.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 .../net/wireless/mediatek/mt76/mt76x0/pci.c   |  6 -----
 .../net/wireless/mediatek/mt76/mt76x0/usb.c   | 22 +++++--------------
 .../wireless/mediatek/mt76/mt76x2/pci_main.c  | 13 +++--------
 .../wireless/mediatek/mt76/mt76x2/usb_main.c  | 10 ++-------
 4 files changed, 10 insertions(+), 41 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
index 156d3d064ba0..ac979128386a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
@@ -25,8 +25,6 @@ static int mt76x0e_start(struct ieee80211_hw *hw)
 {
 	struct mt76x02_dev *dev = hw->priv;
 
-	mutex_lock(&dev->mt76.mutex);
-
 	mt76x02_mac_start(dev);
 	mt76x0_phy_calibrate(dev, true);
 	ieee80211_queue_delayed_work(dev->mt76.hw, &dev->mac_work,
@@ -35,8 +33,6 @@ static int mt76x0e_start(struct ieee80211_hw *hw)
 				     MT_CALIBRATE_INTERVAL);
 	set_bit(MT76_STATE_RUNNING, &dev->mt76.state);
 
-	mutex_unlock(&dev->mt76.mutex);
-
 	return 0;
 }
 
@@ -62,10 +58,8 @@ static void mt76x0e_stop(struct ieee80211_hw *hw)
 {
 	struct mt76x02_dev *dev = hw->priv;
 
-	mutex_lock(&dev->mt76.mutex);
 	clear_bit(MT76_STATE_RUNNING, &dev->mt76.state);
 	mt76x0e_stop_hw(dev);
-	mutex_unlock(&dev->mt76.mutex);
 }
 
 static void
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
index 22c10722019d..494b9f35f80d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
@@ -81,8 +81,10 @@ static void mt76x0u_cleanup(struct mt76x02_dev *dev)
 	mt76u_queues_deinit(&dev->mt76);
 }
 
-static void mt76x0u_mac_stop(struct mt76x02_dev *dev)
+static void mt76x0u_stop(struct ieee80211_hw *hw)
 {
+	struct mt76x02_dev *dev = hw->priv;
+
 	clear_bit(MT76_STATE_RUNNING, &dev->mt76.state);
 	cancel_delayed_work_sync(&dev->cal_work);
 	cancel_delayed_work_sync(&dev->mac_work);
@@ -106,11 +108,9 @@ static int mt76x0u_start(struct ieee80211_hw *hw)
 	struct mt76x02_dev *dev = hw->priv;
 	int ret;
 
-	mutex_lock(&dev->mt76.mutex);
-
 	ret = mt76x0_mac_start(dev);
 	if (ret)
-		goto out;
+		return ret;
 
 	mt76x0_phy_calibrate(dev, true);
 	ieee80211_queue_delayed_work(dev->mt76.hw, &dev->mac_work,
@@ -118,19 +118,7 @@ static int mt76x0u_start(struct ieee80211_hw *hw)
 	ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work,
 				     MT_CALIBRATE_INTERVAL);
 	set_bit(MT76_STATE_RUNNING, &dev->mt76.state);
-
-out:
-	mutex_unlock(&dev->mt76.mutex);
-	return ret;
-}
-
-static void mt76x0u_stop(struct ieee80211_hw *hw)
-{
-	struct mt76x02_dev *dev = hw->priv;
-
-	mutex_lock(&dev->mt76.mutex);
-	mt76x0u_mac_stop(dev);
-	mutex_unlock(&dev->mt76.mutex);
+	return 0;
 }
 
 static const struct ieee80211_ops mt76x0u_ops = {
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
index 16dc8e2451b5..3947e8ba486e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
@@ -22,15 +22,13 @@ mt76x2_start(struct ieee80211_hw *hw)
 	struct mt76x02_dev *dev = hw->priv;
 	int ret;
 
-	mutex_lock(&dev->mt76.mutex);
-
 	ret = mt76x2_mac_start(dev);
 	if (ret)
-		goto out;
+		return ret;
 
 	ret = mt76x2_phy_start(dev);
 	if (ret)
-		goto out;
+		return ret;
 
 	ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mac_work,
 				     MT_MAC_WORK_INTERVAL);
@@ -38,10 +36,7 @@ mt76x2_start(struct ieee80211_hw *hw)
 				     MT_WATCHDOG_TIME);
 
 	set_bit(MT76_STATE_RUNNING, &dev->mt76.state);
-
-out:
-	mutex_unlock(&dev->mt76.mutex);
-	return ret;
+	return 0;
 }
 
 static void
@@ -49,10 +44,8 @@ mt76x2_stop(struct ieee80211_hw *hw)
 {
 	struct mt76x02_dev *dev = hw->priv;
 
-	mutex_lock(&dev->mt76.mutex);
 	clear_bit(MT76_STATE_RUNNING, &dev->mt76.state);
 	mt76x2_stop_hardware(dev);
-	mutex_unlock(&dev->mt76.mutex);
 }
 
 static int
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
index 0771de210c6a..32726b4906ea 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
@@ -21,30 +21,24 @@ static int mt76x2u_start(struct ieee80211_hw *hw)
 	struct mt76x02_dev *dev = hw->priv;
 	int ret;
 
-	mutex_lock(&dev->mt76.mutex);
-
 	ret = mt76x2u_mac_start(dev);
 	if (ret)
-		goto out;
+		return ret;
 
 	ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mac_work,
 				     MT_MAC_WORK_INTERVAL);
 	set_bit(MT76_STATE_RUNNING, &dev->mt76.state);
 
-out:
-	mutex_unlock(&dev->mt76.mutex);
-	return ret;
+	return 0;
 }
 
 static void mt76x2u_stop(struct ieee80211_hw *hw)
 {
 	struct mt76x02_dev *dev = hw->priv;
 
-	mutex_lock(&dev->mt76.mutex);
 	clear_bit(MT76_STATE_RUNNING, &dev->mt76.state);
 	mt76u_stop_tx(&dev->mt76);
 	mt76x2u_stop_hw(dev);
-	mutex_unlock(&dev->mt76.mutex);
 }
 
 static int
-- 
2.20.1


^ 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