Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [PATCH v2 3/3] brcmfmac: sdio: Disable auto-tuning around commands expected to fail
From: Doug Anderson @ 2019-06-07 18:00 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Ulf Hansson, Kalle Valo, Arend van Spriel, brcm80211-dev-list.pdl,
	open list:ARM/Rockchip SoC..., Double Lo, Brian Norris,
	linux-wireless, Naveen Gupta, Madhan Mohan R, Matthias Kaehlcke,
	Wright Feng, Chi-Hsien Lin, netdev, brcm80211-dev-list,
	David S. Miller, Franky Lin, LKML, Hante Meuleman, YueHaibing,
	Michael Trimarchi
In-Reply-To: <2e9f80af-aa26-5590-9ff0-9889400068d6@intel.com>

Hi,

On Fri, Jun 7, 2019 at 5:29 AM Adrian Hunter <adrian.hunter@intel.com> wrote:
>
> >> @@ -711,8 +720,16 @@ brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on)
> >>                         err_cnt = 0;
> >>                 }
> >>                 /* bail out upon subsequent access errors */
> >> -               if (err && (err_cnt++ > BRCMF_SDIO_MAX_ACCESS_ERRORS))
> >> -                       break;
> >> +               if (err && (err_cnt++ > BRCMF_SDIO_MAX_ACCESS_ERRORS)) {
> >> +                       if (!retune_release)
> >> +                               break;
> >> +                       /*
> >> +                        * Allow one more retry with re-tuning released in case
> >> +                        * it helps.
> >> +                        */
> >> +                       sdio_retune_release(bus->sdiodev->func1);
> >> +                       retune_release = false;
> >
> > I would be tempted to wait before adding this logic until we actually
> > see that it's needed.  Sure, doing one more transfer probably won't
> > really hurt, but until we know that it actually helps it seems like
> > we're just adding extra complexity?
>
> Depends, what is the downside of unnecessarily returning an error from
> brcmf_sdio_kso_control() in that case?

I'm not aware of any downside, but without any example of it being
needed it's just untested code that might or might not fix a problem.
For now I'm going to leave it out of my patch and if someone later
finds it needed or if you're convinced that we really need it we can
add it as a patch atop.

-Doug

^ permalink raw reply

* Re: [RFC PATCH 0/3] move WEP implementation to skcipher interface
From: Eric Biggers @ 2019-06-07 17:59 UTC (permalink / raw)
  To: Ard Biesheuvel; +Cc: linux-crypto, herbert, johannes, linux-wireless, davem
In-Reply-To: <20190607144944.13485-1-ard.biesheuvel@linaro.org>

On Fri, Jun 07, 2019 at 04:49:41PM +0200, Ard Biesheuvel wrote:
> One of the issues that I would like to see addressed in the crypto API
> is they way the cipher abstraction is used. In general, a cipher should
> never be used directly, and so it would be much better to clean up the
> existing uses of ciphers outside of the crypto subsystem itself, so that
> we can make the cipher abstraction part of the internal API, only to
> be used by templates or crypto drivers that require them as a callback.
> 
> As a first step, this series moves all users of the 'arc4' cipher to
> the ecb(arc4) skcipher, which happens to be implemented by the same
> driver, and is already a stream cipher, given that ARC4_BLOCK_SIZE
> actually evaluates to 1.
> 
> Next step would be to switch the users of the 'des' and 'aes' ciphers
> to other interfaces that are more appropriate, either ecb(...) or a
> library interface, which may be more appropriate in some cases. In any
> case, the end result should be that ciphers are no longer used outside
> of crypto/ and drivers/crypto/
> 
> This series is presented as an RFC, since I am mostly interested in
> discussing the above, but I prefer to do so in the context of actual
> patches rather than an abstract discussion.
> 
> Ard Biesheuvel (3):
>   net/mac80211: switch to skcipher interface for arc4
>   lib80211/tkip: switch to skcipher interface for arc4
>   lib80211/wep: switch to skcipher interface for arc4
> 

The way the crypto API exposes ARC4 is definitely broken.  It treats it as a
block cipher (with a block size of 1 byte...), when it's actually a stream
cipher.  Also, it violates the API by modifying the key during each encryption.

Since ARC4 is fast in software and is "legacy" crypto that people shouldn't be
using, and the users call it on virtual addresses, perhaps we should instead
remove it from the crypto API and provide a library function arc4_crypt()?  We'd
lose support for ARC4 in three hardware drivers, but are there real users who
really are using ARC4 and need those to get acceptable performance?  Note that
they aren't being used in the cases where the 'cipher' API is currently being
used, so it would only be the current 'skcipher' users that might matter.

Someone could theoretically be using "ecb(arc4)" via AF_ALG or dm-crypt, but it
seems unlikely...

As for removing the "cipher" API entirely, we'd have to consider how to convert
all the current users, not just ARC4, so that would be a somewhat different
discussion.  How do you propose to handle dm-crypt and fscrypt which use the
cipher API to do ESSIV?

- Eric

^ permalink raw reply

* [PATCH] wlcore/wl18xx: Add invert-irq OF property for physically inverted IRQ
From: Eugeniu Rosca @ 2019-06-07 17:29 UTC (permalink / raw)
  To: Geert Uytterhoeven, Simon Horman, Kalle Valo, David S. Miller,
	Greg Kroah-Hartman, Randy Dunlap, Tony Lindgren, Ulf Hansson,
	John Stultz, linux-wireless, netdev, linux-kernel,
	Spyridon Papageorgiou, Joshua Frkuska, George G . Davis,
	Andrey Gusakov, Linux-Renesas
  Cc: Eugeniu Rosca, Eugeniu Rosca

The wl1837mod datasheet [1] says about the WL_IRQ pin:

 ---8<---
SDIO available, interrupt out. Active high. [..]
Set to rising edge (active high) on powerup.
 ---8<---

That's the reason of seeing the interrupt configured as:
 - IRQ_TYPE_EDGE_RISING on HiKey 960/970
 - IRQ_TYPE_LEVEL_HIGH on a number of i.MX6 platforms

We assert that all those platforms have the WL_IRQ pin connected
to the SoC _directly_ (confirmed on HiKey 970 [2]).

That's not the case for R-Car Kingfisher extension target, which carries
a WL1837MODGIMOCT IC. There is an SN74LV1T04DBVR inverter present
between the WLAN_IRQ pin of the WL18* chip and the SoC, effectively
reversing the requirement quoted from [1]. IOW, in Kingfisher DTS
configuration we would need to use IRQ_TYPE_EDGE_FALLING or
IRQ_TYPE_LEVEL_LOW.

Unfortunately, v4.2-rc1 commit bd763482c82ea2 ("wl18xx: wlan_irq:
support platform dependent interrupt types") made a special case out
of these interrupt types. After this commit, it is impossible to provide
an IRQ configuration via DTS which would describe an inverter present
between the WL18* chip and the SoC, generating the need for workarounds
like [3].

Create a boolean OF property, called "invert-irq" to specify that
the WLAN_IRQ pin of WL18* is connected to the SoC via an inverter.

This solution has been successfully tested on R-Car H3ULCB-KF-M06 using
the DTS configuration [4] combined with the "invert-irq" property.

[1] http://www.ti.com/lit/ds/symlink/wl1837mod.pdf
[2] https://www.96boards.org/documentation/consumer/hikey/hikey970/hardware-docs/
[3] https://github.com/CogentEmbedded/meta-rcar/blob/289fbd4f8354/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0024-wl18xx-do-not-invert-IRQ-on-WLxxxx-side.patch
[4] https://patchwork.kernel.org/patch/10895879/
    ("arm64: dts: ulcb-kf: Add support for TI WL1837")

Signed-off-by: Eugeniu Rosca <erosca@de.adit-jv.com>
---
 drivers/net/wireless/ti/wl18xx/main.c     | 5 +++++
 drivers/net/wireless/ti/wlcore/sdio.c     | 2 ++
 drivers/net/wireless/ti/wlcore/wlcore_i.h | 4 ++++
 3 files changed, 11 insertions(+)

diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
index 496b9b63cea1..cea91d1aee98 100644
--- a/drivers/net/wireless/ti/wl18xx/main.c
+++ b/drivers/net/wireless/ti/wl18xx/main.c
@@ -877,6 +877,8 @@ static int wl18xx_pre_boot(struct wl1271 *wl)
 
 static int wl18xx_pre_upload(struct wl1271 *wl)
 {
+	struct platform_device *pdev = wl->pdev;
+	struct wlcore_platdev_data *pdata = dev_get_platdata(&pdev->dev);
 	u32 tmp;
 	int ret;
 	u16 irq_invert;
@@ -932,6 +934,9 @@ static int wl18xx_pre_upload(struct wl1271 *wl)
 	if (ret < 0)
 		goto out;
 
+	if (pdata->invert_irq)
+		goto out;
+
 	ret = irq_get_trigger_type(wl->irq);
 	if ((ret == IRQ_TYPE_LEVEL_LOW) || (ret == IRQ_TYPE_EDGE_FALLING)) {
 		wl1271_info("using inverted interrupt logic: %d", ret);
diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c
index 4d4b07701149..581f56b0b6a2 100644
--- a/drivers/net/wireless/ti/wlcore/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -266,6 +266,8 @@ static int wlcore_probe_of(struct device *dev, int *irq, int *wakeirq,
 	of_property_read_u32(np, "tcxo-clock-frequency",
 			     &pdev_data->tcxo_clock_freq);
 
+	pdev_data->invert_irq = of_property_read_bool(np, "invert-irq");
+
 	return 0;
 }
 #else
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index 32ec121ccac2..01679f9d7170 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -213,6 +213,10 @@ struct wlcore_platdev_data {
 	u32 ref_clock_freq;	/* in Hertz */
 	u32 tcxo_clock_freq;	/* in Hertz, tcxo is always XTAL */
 	bool pwr_in_suspend;
+	bool invert_irq;	/* specify if there is a physical IRQ inverter
+				 * between WL chip and SoC, like SN74LV1T04DBVR
+				 * in case of R-Car Kingfisher board
+				 */
 };
 
 #define MAX_NUM_KEYS 14
-- 
2.21.0


^ permalink raw reply related

* Re: [BISECTED REGRESSION] b43legacy broken on G4 PowerBook
From: Christoph Hellwig @ 2019-06-07 17:29 UTC (permalink / raw)
  To: Larry Finger
  Cc: Aaro Koskinen, Christoph Hellwig, Christian Zigotzky,
	Michael Ellerman, linux-kernel, linux-wireless, linuxppc-dev
In-Reply-To: <73da300c-871c-77ac-8a3a-deac226743ef@lwfinger.net>

I don't think we should work around this in the driver, we need to fix
it in the core.  I'm curious why my previous patch didn't work.  Can
you throw in a few printks what failed?  I.e. did dma_direct_supported
return false?  Did the actual allocation fail?

^ permalink raw reply

* Re: [BISECTED REGRESSION] b43legacy broken on G4 PowerBook
From: Larry Finger @ 2019-06-07 17:25 UTC (permalink / raw)
  To: Aaro Koskinen, Christoph Hellwig, Christian Zigotzky,
	Michael Ellerman
  Cc: linux-kernel, linux-wireless, linuxppc-dev
In-Reply-To: <20190605225059.GA9953@darkstar.musicnaut.iki.fi>

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

On 6/5/19 5:50 PM, Aaro Koskinen wrote:
> Hi,
> 
> When upgrading from v5.0 -> v5.1 on G4 PowerBook, I noticed WLAN does
> not work anymore:
> 
> [   42.004303] b43legacy-phy0: Loading firmware version 0x127, patch level 14 (2005-04-18 02:36:27)
> [   42.184837] b43legacy-phy0 debug: Chip initialized
> [   42.184873] b43legacy-phy0 ERROR: The machine/kernel does not support the required 30-bit DMA mask
> 
> The same happens with the current mainline.
> 
> Bisected to:
> 
> 	commit 65a21b71f948406201e4f62e41f06513350ca390
> 	Author: Christoph Hellwig <hch@lst.de>
> 	Date:   Wed Feb 13 08:01:26 2019 +0100
> 
> 	    powerpc/dma: remove dma_nommu_dma_supported
> 
> 	    This function is largely identical to the generic version used
> 	    everywhere else.  Replace it with the generic version.
> 
> 	    Signed-off-by: Christoph Hellwig <hch@lst.de>
> 	    Tested-by: Christian Zigotzky <chzigotzky@xenosoft.de>
> 	    Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>

Aaro,

Please try the attached patch. I'm not really pleased with it and I will 
continue to determine why the fallback to a 30-bit mask fails, but at least this 
one works for me.

Larry



[-- Attachment #2: 0001-b43legacy-Fix-DMA-breakage-from-commit-commit-65a21b.patch --]
[-- Type: text/x-patch, Size: 2674 bytes --]

From 25e2f50273e785598b6bd9a8aee28cf825d3fe9f Mon Sep 17 00:00:00 2001
From: Larry Finger <Larry.Finger@lwfinger.net>
Date: Fri, 7 Jun 2019 12:04:16 -0500
Subject: [PATCH] b43legacy: Fix DMA breakage from commit commit 65a21b71f948
To: kvalo@codeaurora.org
Cc: linux-wireless@vger.kernel.org,
    pkshih@realtek.com

Following commit 65a21b71f948 ("powerpc/dma: remove dma_nommu_dma_supported"),
this driver errors with a message that "The machine/kernel does not
support the required 30-bit DMA mask." Indeed, the hardware only allows
31-bit masks. This solution is to change the fallback mask from 30-
to 31-bits for 32-bit PPC systems.

Fixes: 65a21b71f948 ("powerpc/dma: remove dma_nommu_dma_supported")
Reported-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
---
 drivers/net/wireless/broadcom/b43legacy/dma.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/broadcom/b43legacy/dma.c b/drivers/net/wireless/broadcom/b43legacy/dma.c
index 1cc25f44dd9a..75613f516e50 100644
--- a/drivers/net/wireless/broadcom/b43legacy/dma.c
+++ b/drivers/net/wireless/broadcom/b43legacy/dma.c
@@ -27,6 +27,15 @@
 #include <linux/slab.h>
 #include <net/dst.h>
 
+/* Special handling for PPC32 - The maximum DMA mask is 31 bits, and
+ * the fallback to 30 bits fails. Set the fallback at 31.
+ */
+#ifdef CONFIG_PPC32
+#define FB_DMA	31
+#else
+#define FB_DMA	30
+#endif
+
 /* 32bit DMA ops. */
 static
 struct b43legacy_dmadesc32 *op32_idx2desc(struct b43legacy_dmaring *ring,
@@ -418,7 +427,7 @@ static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring,
 
 	switch (ring->type) {
 	case B43legacy_DMA_30BIT:
-		if ((u64)addr + buffersize > (1ULL << 30))
+		if ((u64)addr + buffersize > (1ULL << FB_DMA))
 			goto address_error;
 		break;
 	case B43legacy_DMA_32BIT:
@@ -617,12 +626,12 @@ static u64 supported_dma_mask(struct b43legacy_wldev *dev)
 	if (tmp & B43legacy_DMA32_TXADDREXT_MASK)
 		return DMA_BIT_MASK(32);
 
-	return DMA_BIT_MASK(30);
+	return DMA_BIT_MASK(FB_DMA);
 }
 
 static enum b43legacy_dmatype dma_mask_to_engine_type(u64 dmamask)
 {
-	if (dmamask == DMA_BIT_MASK(30))
+	if (dmamask == DMA_BIT_MASK(FB_DMA))
 		return B43legacy_DMA_30BIT;
 	if (dmamask == DMA_BIT_MASK(32))
 		return B43legacy_DMA_32BIT;
@@ -802,7 +811,7 @@ static int b43legacy_dma_set_mask(struct b43legacy_wldev *dev, u64 mask)
 			continue;
 		}
 		if (mask == DMA_BIT_MASK(32)) {
-			mask = DMA_BIT_MASK(30);
+			mask = DMA_BIT_MASK(FB_DMA);
 			fallback = true;
 			continue;
 		}
-- 
2.21.0


^ permalink raw reply related

* Re: [PATCH v2 0/2] mt7601u: do not schedule {rx,tx}_tasklet when the device has been disconnected
From: Jakub Kicinski @ 2019-06-07 17:07 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: linux-wireless, lorenzo.bianconi
In-Reply-To: <cover.1559906499.git.lorenzo@kernel.org>

On Fri,  7 Jun 2019 13:48:08 +0200, Lorenzo Bianconi wrote:
> Do not schedule {tx,rx}_tasklet when the usb dongle is disconnected in order to fix
> {TX,RX} urb mismatch warning
> Fix possible memory leak when the device is disconnected while passing traffic.

Acked-by: Jakub Kicinski <kubakici@wp.pl>

Thanks Lorenzo!

^ permalink raw reply

* Re: [PATCH] mt76: mt7615: remove key check in mt7615_mcu_set_wtbl_key
From: Felix Fietkau @ 2019-06-07 17:02 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: lorenzo.bianconi, linux-wireless, ryder.lee, royluo
In-Reply-To: <51396ab29d290f95caecbb7fd817c654b74b36dc.1559686202.git.lorenzo@kernel.org>

On 2019-06-05 00:12, Lorenzo Bianconi wrote:
> Do not check key pointer in mt7615_mcu_set_wtbl_key since if set_key_cmd
> is SET_KEY, key will be always not NULL. This patch will address a false
> positive reported by Coverity-Scan
> 
> Addresses-Coverity-ID: 1445463 ("Dereference after null check")
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>

Applied, thanks.

- Felix

^ permalink raw reply

* Re: [PATCH] mt76: mt7615: remove unused variable in mt7615_mcu_set_bcn
From: Felix Fietkau @ 2019-06-07 17:02 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: linux-wireless, lorenzo.bianconi, ryder.lee, royluo
In-Reply-To: <d2b9a68b797fbbd67fe8f3be0fe851113eaa1488.1559641771.git.lorenzo@kernel.org>

On 2019-06-04 12:06, Lorenzo Bianconi wrote:
> Remove tim_len in mt7615_mcu_set_bcn since it is not actually used
> and ieee80211_beacon_get_tim checks if tim_length is NULL
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>

Applied, thanks.

- Felix

^ permalink raw reply

* Re: [PATCH v3 2/2] mt76: mt7615: fix slow performance when enable encryption
From: Felix Fietkau @ 2019-06-07 17:02 UTC (permalink / raw)
  To: Ryder Lee, Lorenzo Bianconi
  Cc: Roy Luo, YF Luo, Yiwei Chung, Sean Wang, Chih-Min Chen,
	linux-wireless, linux-mediatek, linux-kernel
In-Reply-To: <429cf8c1421017b4030b8b6e4fa9e5cbea953d3c.1559541944.git.ryder.lee@mediatek.com>

On 2019-06-03 08:08, Ryder Lee wrote:
> Fix wrong WCID assignment and add RKV (RX Key of this entry is valid)
> flag to check if peer uses the same configuration with previous
> handshaking.
> 
> If the configuration is mismatch, WTBL indicates a “cipher mismatch”
> to stop SEC decryption to prevent the packet from damage.
> 
> Suggested-by: YF Luo <yf.luo@mediatek.com>
> Suggested-by: Yiwei Chung <yiwei.chung@mediatek.com>
> Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>

Applied, thanks.

- Felix

^ permalink raw reply

* Re: [PATCH] mt76: Remove set but not used variables 'pid' and 'final_mpdu'
From: Felix Fietkau @ 2019-06-07 17:01 UTC (permalink / raw)
  To: YueHaibing, lorenzo.bianconi83, ryder.lee, royluo, kvalo,
	matthias.bgg, sgruszka
  Cc: linux-kernel, netdev, linux-wireless, linux-arm-kernel,
	linux-mediatek, davem
In-Reply-To: <20190529145356.13872-1-yuehaibing@huawei.com>

On 2019-05-29 16:53, YueHaibing wrote:
> Fixes gcc '-Wunused-but-set-variable' warnings:
> 
> drivers/net/wireless/mediatek/mt76/mt7603/mac.c: In function mt7603_fill_txs:
> drivers/net/wireless/mediatek/mt76/mt7603/mac.c:969:5: warning: variable pid set but not used [-Wunused-but-set-variable]
> drivers/net/wireless/mediatek/mt76/mt7603/mac.c:961:7: warning: variable final_mpdu set but not used [-Wunused-but-set-variable]
> drivers/net/wireless/mediatek/mt76/mt7615/mac.c: In function mt7615_fill_txs:
> drivers/net/wireless/mediatek/mt76/mt7615/mac.c:555:5: warning: variable pid set but not used [-Wunused-but-set-variable]
> drivers/net/wireless/mediatek/mt76/mt7615/mac.c:552:19: warning: variable final_mpdu set but not used [-Wunused-but-set-variable]
> 
> They are never used, so can be removed.
> 
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>

Applied, thanks.

- Felix

^ permalink raw reply

* Re: [PATCH] mt76: move mt76_get_rate in mt76-module
From: Felix Fietkau @ 2019-06-07 17:01 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: lorenzo.bianconi, linux-wireless, ryder.lee, royluo
In-Reply-To: <d6b2de1b739a394d5dcdd686a7dff198a743669e.1559118081.git.lorenzo@kernel.org>

On 2019-05-29 10:25, Lorenzo Bianconi wrote:
> Move mt7603_get_rate in mac80211.c and rename it to mt76_get_rate
> since it is shared between mt7603 and mt7615 drivers
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
> This patch is based on 'mt76: move mt76_insert_ccmp_hdr in mt76-module'
> https://patchwork.kernel.org/patch/10942973/

Applied, thanks.

- Felix

^ permalink raw reply

* Re: [PATCH 0/4] add tx power configuration support to mt7615 driver
From: Felix Fietkau @ 2019-06-07 16:56 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: lorenzo.bianconi, linux-wireless, ryder.lee, royluo
In-Reply-To: <cover.1558879234.git.lorenzo@kernel.org>

On 2019-05-26 16:05, Lorenzo Bianconi wrote:
> Cap tx power according to the value configured by the user.
> Initialize get_txpower mac80211 callback in order to report the
> configured tx power to mac80211
> 
> Lorenzo Bianconi (4):
>   mt76: generalize mt76_get_txpower for 4x4:4 devices
>   mt76: mt7615: add the capability to configure tx power
>   mt76: mt7615: init get_txpower mac80211 callback
>   mt76: mt7615: rearrange locking in mt7615_config

Applied, thanks.

- Felix


^ permalink raw reply

* Re: [PATCH] mt76: mt7615: select wifi band according to eeprom
From: Felix Fietkau @ 2019-06-07 16:56 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: lorenzo.bianconi, linux-wireless, ryder.lee, royluo
In-Reply-To: <38aa977df45a92f60d78d9cb7e575289ccbaeef6.1558127930.git.lorenzo@kernel.org>

On 2019-05-17 23:32, Lorenzo Bianconi wrote:
> Select supported band according to the value read from
> eeprom mtd/otp partition
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>

Applied, thanks.

- Felix

^ permalink raw reply

* Re: [PATCH v2] mt76: mt7615: add support for mtd eeprom parsing
From: Felix Fietkau @ 2019-06-07 16:55 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: lorenzo.bianconi, linux-wireless, ryder.lee, royluo
In-Reply-To: <12c5ae00296007af2da0021cc0872dac9b6960dc.1558074163.git.lorenzo@kernel.org>

On 2019-05-17 08:26, Lorenzo Bianconi wrote:
> Calibration data are often available on a specific mtd partition on
> embedded devices. Take into account eeprom calibration data if
> available.
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
> Changes since v1:
> - remove TODO comment
> - take into account mtd partition even if otp one is empty

Applied, thanks.

- Felix

^ permalink raw reply

* Re: [PATCH] mt76: move mt76_insert_ccmp_hdr in mt76-module
From: Felix Fietkau @ 2019-06-07 16:55 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: lorenzo.bianconi, linux-wireless, ryder.lee, royluo
In-Reply-To: <99370eaa04916a871b6cc2413ae00e1370e09292.1557838049.git.lorenzo@kernel.org>

On 2019-05-14 14:48, Lorenzo Bianconi wrote:
> Move mt7615_insert_ccmp_hdr in mac80211.c and rename it in
> mt76_insert_ccmp_hdr since it is shared between mt7603 and mt7615
> drivers
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Applied, thanks.

- Felix

^ permalink raw reply

* [PATCH 1/4] mt7603: fix reading target tx power from eeprom
From: Felix Fietkau @ 2019-06-07 16:43 UTC (permalink / raw)
  To: linux-wireless

For the external PA (TSSI OFF) case, the target power needs to be read
from a different location in EEPROM

Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
 drivers/net/wireless/mediatek/mt76/mt7603/eeprom.h | 2 ++
 drivers/net/wireless/mediatek/mt76/mt7603/init.c   | 4 ++++
 2 files changed, 6 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.h b/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.h
index f27b99b7e359..b893facfba48 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.h
@@ -69,6 +69,8 @@ enum mt7603_eeprom_field {
 
 	MT_EE_CP_FT_VERSION =			0x0f0,
 
+	MT_EE_TX_POWER_TSSI_OFF =		0x0f2,
+
 	MT_EE_XTAL_FREQ_OFFSET =		0x0f4,
 	MT_EE_XTAL_TRIM_2_COMP =		0x0f5,
 	MT_EE_XTAL_TRIM_3_COMP =		0x0f6,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/init.c b/drivers/net/wireless/mediatek/mt76/mt7603/init.c
index 4e269044f8a4..2238e3daedc6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/init.c
@@ -465,9 +465,13 @@ mt7603_init_txpower(struct mt7603_dev *dev,
 	u8 *eeprom = (u8 *)dev->mt76.eeprom.data;
 	int target_power = eeprom[MT_EE_TX_POWER_0_START_2G + 2] & ~BIT(7);
 	u8 *rate_power = &eeprom[MT_EE_TX_POWER_CCK];
+	bool ext_pa = eeprom[MT_EE_NIC_CONF_0 + 1] & BIT(1);
 	int max_offset, cur_offset;
 	int i;
 
+	if (ext_pa)
+		target_power = eeprom[MT_EE_TX_POWER_TSSI_OFF] & ~BIT(7);
+
 	if (target_power & BIT(6))
 		target_power = -(target_power & GENMASK(5, 0));
 
-- 
2.17.0


^ permalink raw reply related

* [PATCH 3/4] mt76: mt76x02: fix tx status reporting issues
From: Felix Fietkau @ 2019-06-07 16:43 UTC (permalink / raw)
  To: linux-wireless
In-Reply-To: <20190607164355.51876-1-nbd@nbd.name>

When the hardware falls back to lower rates for a transmit attempt, only the
first status report will show the number of retries correctly. The frames
that follow will report the correct final rate, but number of retries set to 0.
This can cause the rate control module to vastly underestimate the number of
retransmissions per rate.

To fix this, we need to keep track of the initial requested tx rate per packet
and pass it to the status information.
For frames with tx status requested, this is simple: use the rate configured
in info->control.rates[0] as reference.
For no-skb tx status information, we have to encode the requested tx rate in
the packet id (and make it possible to distinguish it from real packet ids).

To do that, reduce the packet id field size by one bit, and use that bit to
indicate packet id vs rate.

This change also improves reporting by filling the status rate array with
rates from first rate to final rate, taking the same steps as the hardware
fallback table. This matters in corner cases like MCS8 on HT, where the
fallback target is MCS0, not MCS7.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
 drivers/net/wireless/mediatek/mt76/mt76.h     | 11 ++-
 .../net/wireless/mediatek/mt76/mt76x02_mac.c  | 88 ++++++++++++++++---
 .../net/wireless/mediatek/mt76/mt76x02_txrx.c |  7 +-
 .../wireless/mediatek/mt76/mt76x02_usb_core.c |  7 +-
 4 files changed, 97 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index fc4169c83e76..907bec9d5e4c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -258,10 +258,11 @@ struct mt76_rx_tid {
 #define MT_TX_CB_TXS_DONE		BIT(1)
 #define MT_TX_CB_TXS_FAILED		BIT(2)
 
-#define MT_PACKET_ID_MASK		GENMASK(7, 0)
+#define MT_PACKET_ID_MASK		GENMASK(6, 0)
 #define MT_PACKET_ID_NO_ACK		0
 #define MT_PACKET_ID_NO_SKB		1
 #define MT_PACKET_ID_FIRST		2
+#define MT_PACKET_ID_HAS_RATE		BIT(7)
 
 #define MT_TX_STATUS_SKB_TIMEOUT	HZ
 
@@ -689,6 +690,14 @@ static inline void mt76_insert_hdr_pad(struct sk_buff *skb)
 	skb->data[len + 1] = 0;
 }
 
+static inline bool mt76_is_skb_pktid(u8 pktid)
+{
+	if (pktid & MT_PACKET_ID_HAS_RATE)
+		return false;
+
+	return pktid >= MT_PACKET_ID_FIRST;
+}
+
 void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb);
 void mt76_tx(struct mt76_dev *dev, struct ieee80211_sta *sta,
 	     struct mt76_wcid *wcid, struct sk_buff *skb);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index ee4a86971be7..dd711bacc869 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -419,31 +419,87 @@ void mt76x02_mac_write_txwi(struct mt76x02_dev *dev, struct mt76x02_txwi *txwi,
 }
 EXPORT_SYMBOL_GPL(mt76x02_mac_write_txwi);
 
+static void
+mt76x02_tx_rate_fallback(struct ieee80211_tx_rate *rates, int idx, int phy)
+{
+	u8 mcs, nss;
+
+	if (!idx)
+		return;
+
+	rates += idx - 1;
+	rates[1] = rates[0];
+	switch (phy) {
+	case MT_PHY_TYPE_VHT:
+		mcs = ieee80211_rate_get_vht_mcs(rates);
+		nss = ieee80211_rate_get_vht_nss(rates);
+
+		if (mcs == 0)
+			nss = max_t(int, nss - 1, 1);
+		else
+			mcs--;
+
+		ieee80211_rate_set_vht(rates + 1, mcs, nss);
+		break;
+	case MT_PHY_TYPE_HT_GF:
+	case MT_PHY_TYPE_HT:
+		/* MCS 8 falls back to MCS 0 */
+		if (rates[0].idx == 8) {
+		    rates[1].idx = 0;
+		    break;
+		}
+		/* fall through */
+	default:
+		rates[1].idx = max_t(int, rates[0].idx - 1, 0);
+		break;
+	}
+}
+
 static void
 mt76x02_mac_fill_tx_status(struct mt76x02_dev *dev,
 			   struct ieee80211_tx_info *info,
 			   struct mt76x02_tx_status *st, int n_frames)
 {
 	struct ieee80211_tx_rate *rate = info->status.rates;
-	int cur_idx, last_rate;
+	struct ieee80211_tx_rate last_rate;
+	u16 first_rate;
+	int retry = st->retry;
+	int phy;
 	int i;
 
 	if (!n_frames)
 		return;
 
-	last_rate = min_t(int, st->retry, IEEE80211_TX_MAX_RATES - 1);
-	mt76x02_mac_process_tx_rate(&rate[last_rate], st->rate,
+	phy = FIELD_GET(MT_RXWI_RATE_PHY, st->rate);
+
+	if (st->pktid & MT_PACKET_ID_HAS_RATE) {
+		first_rate = st->rate & ~MT_RXWI_RATE_INDEX;
+		first_rate |= st->pktid & MT_RXWI_RATE_INDEX;
+
+		mt76x02_mac_process_tx_rate(&rate[0], first_rate,
+					    dev->mt76.chandef.chan->band);
+	}
+
+	mt76x02_mac_process_tx_rate(&last_rate, st->rate,
 				    dev->mt76.chandef.chan->band);
-	if (last_rate < IEEE80211_TX_MAX_RATES - 1)
-		rate[last_rate + 1].idx = -1;
-
-	cur_idx = rate[last_rate].idx + last_rate;
-	for (i = 0; i <= last_rate; i++) {
-		rate[i].flags = rate[last_rate].flags;
-		rate[i].idx = max_t(int, 0, cur_idx - i);
-		rate[i].count = 1;
+
+	for (i = 0; i < ARRAY_SIZE(info->status.rates); i++) {
+		retry--;
+		if (i + 1 == ARRAY_SIZE(info->status.rates)) {
+			info->status.rates[i] = last_rate;
+			info->status.rates[i].count = max_t(int, retry, 1);
+			break;
+		}
+
+		mt76x02_tx_rate_fallback(info->status.rates, i, phy);
+		if (info->status.rates[i].idx == last_rate.idx)
+			break;
+	}
+
+	if (i + 1 < ARRAY_SIZE(info->status.rates)) {
+		info->status.rates[i + 1].idx = -1;
+		info->status.rates[i + 1].count = 0;
 	}
-	rate[last_rate].count = st->retry + 1 - last_rate;
 
 	info->status.ampdu_len = n_frames;
 	info->status.ampdu_ack_len = st->success ? n_frames : 0;
@@ -489,13 +545,19 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev,
 	mt76_tx_status_lock(mdev, &list);
 
 	if (wcid) {
-		if (stat->pktid >= MT_PACKET_ID_FIRST)
+		if (mt76_is_skb_pktid(stat->pktid))
 			status.skb = mt76_tx_status_skb_get(mdev, wcid,
 							    stat->pktid, &list);
 		if (status.skb)
 			status.info = IEEE80211_SKB_CB(status.skb);
 	}
 
+	if (!status.skb && !(stat->pktid & MT_PACKET_ID_HAS_RATE)) {
+		mt76_tx_status_unlock(mdev, &list);
+		rcu_read_unlock();
+		return;
+	}
+
 	if (msta && stat->aggr && !status.skb) {
 		u32 stat_val, stat_cache;
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
index cf7abd9b7d2e..95c73049a68b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
@@ -164,9 +164,14 @@ int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
 	mt76x02_mac_write_txwi(dev, txwi, tx_info->skb, wcid, sta, len);
 
 	pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
+
+	/* encode packet rate for no-skb packet id to fix up status reporting */
+	if (pid == MT_PACKET_ID_NO_SKB)
+		pid = MT_PACKET_ID_HAS_RATE | (txwi->rate & MT_RXWI_RATE_INDEX);
+
 	txwi->pktid = pid;
 
-	if (pid >= MT_PACKET_ID_FIRST)
+	if (mt76_is_skb_pktid(pid))
 		qsel = MT_QSEL_MGMT;
 
 	tx_info->info = FIELD_PREP(MT_TXD_INFO_QSEL, qsel) |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
index 6b89f7eab26c..2436f14ca24a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
@@ -89,9 +89,14 @@ int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
 	skb_push(tx_info->skb, sizeof(*txwi));
 
 	pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
+
+	/* encode packet rate for no-skb packet id to fix up status reporting */
+	if (pid == MT_PACKET_ID_NO_SKB)
+		pid = MT_PACKET_ID_HAS_RATE | (txwi->rate & MT_RXWI_RATE_INDEX);
+
 	txwi->pktid = pid;
 
-	if (pid >= MT_PACKET_ID_FIRST || ep == MT_EP_OUT_HCCA)
+	if (mt76_is_skb_pktid(pid) || ep == MT_EP_OUT_HCCA)
 		qsel = MT_QSEL_MGMT;
 	else
 		qsel = MT_QSEL_EDCA;
-- 
2.17.0


^ permalink raw reply related

* [PATCH 4/4] mt76: mt76x02: fix tx reordering on rate control probing without a-mpdu
From: Felix Fietkau @ 2019-06-07 16:43 UTC (permalink / raw)
  To: linux-wireless
In-Reply-To: <20190607164355.51876-1-nbd@nbd.name>

To avoid aggregating rate control probing packets with other traffic, and to
ensure that the probing rate gets used, probing packets get assigned a different
internal queueing priority.
This causes packets to be transmitted in a different order, which is compensated
by the receiver side reordering.
However, if A-MPDU is disabled, this reordering can become visible to upper
layers on the receiver side. Disable the priority change if A-MPDU is disabled.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
 drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c     | 3 ++-
 drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
index 95c73049a68b..9f1c4e085380 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
@@ -154,6 +154,7 @@ int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
 	struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx_info->skb->data;
 	struct mt76x02_txwi *txwi = txwi_ptr;
+	bool ampdu = IEEE80211_SKB_CB(skb)->flags & IEEE80211_TX_CTL_AMPDU;
 	int hdrlen, len, pid, qsel = MT_QSEL_EDCA;
 
 	if (qid == MT_TXQ_PSD && wcid && wcid->idx < 128)
@@ -171,7 +172,7 @@ int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
 
 	txwi->pktid = pid;
 
-	if (mt76_is_skb_pktid(pid))
+	if (mt76_is_skb_pktid(pid) && ampdu)
 		qsel = MT_QSEL_MGMT;
 
 	tx_info->info = FIELD_PREP(MT_TXD_INFO_QSEL, qsel) |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
index 2436f14ca24a..04bfc923ac71 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
@@ -79,6 +79,7 @@ int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
 	struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
 	int pid, len = tx_info->skb->len, ep = q2ep(mdev->q_tx[qid].q->hw_idx);
 	struct mt76x02_txwi *txwi;
+	bool ampdu = IEEE80211_SKB_CB(skb)->flags & IEEE80211_TX_CTL_AMPDU;
 	enum mt76_qsel qsel;
 	u32 flags;
 
@@ -96,7 +97,7 @@ int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
 
 	txwi->pktid = pid;
 
-	if (mt76_is_skb_pktid(pid) || ep == MT_EP_OUT_HCCA)
+	if ((mt76_is_skb_pktid(pid) && ampdu) || ep == MT_EP_OUT_HCCA)
 		qsel = MT_QSEL_MGMT;
 	else
 		qsel = MT_QSEL_EDCA;
-- 
2.17.0


^ permalink raw reply related

* [PATCH 2/4] mt76: fix setting chan->max_power
From: Felix Fietkau @ 2019-06-07 16:43 UTC (permalink / raw)
  To: linux-wireless
In-Reply-To: <20190607164355.51876-1-nbd@nbd.name>

When setting chan->max_power after registering the wiphy, chan->max_reg_power
needs to be used as a limit

Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
 drivers/net/wireless/mediatek/mt76/mt7603/init.c | 2 +-
 drivers/net/wireless/mediatek/mt76/mt76x0/init.c | 5 +++--
 drivers/net/wireless/mediatek/mt76/mt76x2/init.c | 9 +++++----
 3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/init.c b/drivers/net/wireless/mediatek/mt76/mt7603/init.c
index 2238e3daedc6..bce51997ff3b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/init.c
@@ -494,7 +494,7 @@ mt7603_init_txpower(struct mt7603_dev *dev,
 
 	for (i = 0; i < sband->n_channels; i++) {
 		chan = &sband->channels[i];
-		chan->max_power = target_power;
+		chan->max_power = min_t(int, chan->max_reg_power, target_power);
 		chan->orig_mpwr = target_power;
 	}
 }
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
index 57e46d57b449..d67401f895ca 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
@@ -279,8 +279,9 @@ mt76x0_init_txpower(struct mt76x02_dev *dev,
 		mt76x0_get_tx_power_per_rate(dev, chan, &t);
 		mt76x0_get_power_info(dev, chan, &tp);
 
-		chan->max_power = (mt76x02_get_max_rate_power(&t) + tp) / 2;
-		chan->orig_mpwr = chan->max_power;
+		chan->orig_mpwr = (mt76x02_get_max_rate_power(&t) + tp) / 2;
+		chan->max_power = min_t(int, chan->max_reg_power,
+					chan->orig_mpwr);
 	}
 }
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/init.c b/drivers/net/wireless/mediatek/mt76/mt76x2/init.c
index c6078e90ca43..97c3543eed8a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/init.c
@@ -173,13 +173,14 @@ void mt76x2_init_txpower(struct mt76x02_dev *dev,
 		mt76x2_get_power_info(dev, &txp, chan);
 		mt76x2_get_rate_power(dev, &t, chan);
 
-		chan->max_power = mt76x02_get_max_rate_power(&t) +
+		chan->orig_mpwr = mt76x02_get_max_rate_power(&t) +
 				  txp.target_power;
-		chan->max_power = DIV_ROUND_UP(chan->max_power, 2);
+		chan->orig_mpwr = DIV_ROUND_UP(chan->orig_mpwr, 2);
 
 		/* convert to combined output power on 2x2 devices */
-		chan->max_power += 3;
-		chan->orig_mpwr = chan->max_power;
+		chan->orig_mpwr += 3;
+		chan->max_power = min_t(int, chan->max_reg_power,
+					chan->orig_mpwr);
 	}
 }
 EXPORT_SYMBOL_GPL(mt76x2_init_txpower);
-- 
2.17.0


^ permalink raw reply related

* Re: [PATCH] mt76: mt7615: stop mcu first in mt7615_unregister_device
From: Felix Fietkau @ 2019-06-07 16:34 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: lorenzo.bianconi, linux-wireless, ryder.lee, royluo
In-Reply-To: <e145d9f42b1cfcf525300d583c99773132381c34.1557836235.git.lorenzo@kernel.org>

On 2019-05-14 14:20, Lorenzo Bianconi wrote:
> Stop mcu engine and then dma one in mt7615_unregister_device
> in order to avoid a mcu hang in mt7615_unregister_device
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
> This patch ca be squashed with 'mt76: mt7615: rearrange cleanup operations in
> mt7615_unregister_device' since it is not upstream yet

Applied, thanks.

- Felix

^ permalink raw reply

* Re: [PATCH] mt76: mt7615: do not process rx packets if the device is not initialized
From: Felix Fietkau @ 2019-06-07 16:33 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: lorenzo.bianconi, linux-wireless, ryder.lee, royluo
In-Reply-To: <f3117ed5577bdcc2b0bf98c20d07e81f0f52476e.1557825294.git.lorenzo@kernel.org>

On 2019-05-14 11:18, Lorenzo Bianconi wrote:
> Fix following crash that occurs when the driver is processing rx packets
> while the device is not initialized yet
> 
> $ rmmod mt7615e
> [   67.210261] mt7615e 0000:01:00.0: Message -239 (seq 2) timeout
> $ modprobe mt7615e
> [   72.406937] bus=0x1, slot = 0x0, irq=0x16
> [   72.436590] CPU 0 Unable to handle kernel paging request at virtual address 00000004, epc == 8eec4240, ra == 8eec41e0
> [   72.450291] mt7615e 0000:01:00.0: Firmware is not ready for download
> [   72.457724] Oops[#1]:
> [   72.470494] mt7615e: probe of 0000:01:00.0 failed with error -5
> [   72.474829] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.14.114 #0
> [   72.498702] task: 805769e0 task.stack: 80564000
> [   72.507709] $ 0   : 00000000 00000001 00000000 00000001
> [   72.518106] $ 4   : 8f704dbc 00000000 00000000 8f7046c0
> [   72.528500] $ 8   : 00000024 8045e98c 81210008 11000000
> [   72.538895] $12   : 8fc09f60 00000008 00000019 00000033
> [   72.549289] $16   : 8f704d80 e00000ff 8f0c7800 3c182406
> [   72.559684] $20   : 00000006 8ee615a0 4e000108 00000000
> [   72.570078] $24   : 0000004c 8000cf94
> [   72.580474] $28   : 80564000 8fc09e38 00000001 8eec41e0
> [   72.590869] Hi    : 00000001
> [   72.596582] Lo    : 00000000
> [   72.602319] epc   : 8eec4240 mt7615_mac_fill_rx+0xac/0x494 [mt7615e]
> [   72.614953] ra    : 8eec41e0 mt7615_mac_fill_rx+0x4c/0x494 [mt7615e]
> [   72.627580] Status: 11008403 KERNEL EXL IE
> [   72.635899] Cause : 40800008 (ExcCode 02)
> [   72.643860] BadVA : 00000004
> [   72.649573] PrId  : 0001992f (MIPS 1004Kc)
> [   72.657704] Modules linked in: mt7615e pppoe ppp_async pppox ppp_generic nf_conntrack_ipv6 mt76x2e mt76x2_common mt76x02_lib mt7603e mt76 mac80211 iptable_nat ipt_REJECT ipt_MASQUERADE cfg80211 xt_time xt_tcpudp xt_state xt_nat xt_mu]
> [   72.792717] Process swapper/0 (pid: 0, threadinfo=80564000, task=805769e0, tls=00000000)
> [   72.808799] Stack : 8f0c7800 00000800 8f0c7800 8032b874 00000000 40000000 8f704d80 8ee615a0
> [   72.825428]         8dc88010 00000001 8ee615e0 8eec09b0 8dc88010 8032b914 8f3aee80 80567d20
> [   72.842055]         00000000 8ee615e0 40000000 8f0c7800 00000108 8eec9944 00000000 00000000
> [   72.858682]         80508f10 80510000 00000001 80567d20 8ee615a0 00000000 00000000 8ee61c00
> [   72.875308]         8ee61c40 00000040 80610000 80580000 00000000 8ee615dc 8ee61a68 00000001
> [   72.891936]         ...
> [   72.896793] Call Trace:
> [   72.901649] [<8eec4240>] mt7615_mac_fill_rx+0xac/0x494 [mt7615e]
> [   72.913602] [<8eec09b0>] mt7615_queue_rx_skb+0xe4/0x12c [mt7615e]
> [   72.925734] [<8eec9944>] mt76_dma_cleanup+0x390/0x42c [mt76]
> [   72.936988] Code: ae020018  8ea20004  24030001 <94420004> a602002a  8ea20004  90420000  14430003  a2020034
> [   72.956390]
> [   72.959676] ---[ end trace f176967739edb19f ]---
> 
> Fixes: 04b8e65922f6 ("mt76: add mac80211 driver for MT7615 PCIe-based chipsets")
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>

Applied, thanks.

- Felix

^ permalink raw reply

* Re: [PATCH] mt76: mt76x02: fix edcca file permission
From: Felix Fietkau @ 2019-06-07 16:32 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: lorenzo.bianconi, linux-wireless, sgruszka
In-Reply-To: <0e4f22246404d095de2a7e28ddf7572ff71bdb05.1557742856.git.lorenzo@kernel.org>

On 2019-05-13 12:23, Lorenzo Bianconi wrote:
> Use 0600 as edcca file permission in mt76x02 debugfs
> 
> Fixes: 643749d4a82b ("mt76: mt76x02: disable ED/CCA by default")
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>

Applied, thanks.

- Felix

^ permalink raw reply

* Re: [PATCH v2] mt76: mt7603: add debugfs knob to enable/disable edcca
From: Felix Fietkau @ 2019-06-07 16:32 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: lorenzo.bianconi, linux-wireless
In-Reply-To: <95b37b61ae24afe3bd3da2fb3fb0b14169dee05c.1557739809.git.lorenzo@kernel.org>

On 2019-05-13 12:19, Lorenzo Bianconi wrote:
> Introduce a knob in mt7603 debugfs in order to enable/disable
> energy detection based on CCA thresholds
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Applied, thanks.

- Felix

^ permalink raw reply

* Re: [PATCH v2 4/4] mt76: mt76x02: run mt76x02_edcca_init atomically in mt76_edcca_set
From: Felix Fietkau @ 2019-06-07 16:27 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: lorenzo.bianconi, linux-wireless, sgruszka
In-Reply-To: <fde3fda80e04bc1957f98ec48bb33485bb60e3c2.1557587336.git.lorenzo@kernel.org>

On 2019-05-11 17:30, Lorenzo Bianconi wrote:
> Run mt76x02_edcca_init atomically in mt76_edcca_set since it runs
> concurrently with calibration work and mt76x2_set_channel.
> Moreover perform phy calibration atomically
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Applied, thanks.

- Felix

^ permalink raw reply

* [RFC PATCH 2/3] lib80211/tkip: switch to skcipher interface for arc4
From: Ard Biesheuvel @ 2019-06-07 14:49 UTC (permalink / raw)
  To: linux-crypto
  Cc: herbert, ebiggers, johannes, linux-wireless, davem,
	Ard Biesheuvel
In-Reply-To: <20190607144944.13485-1-ard.biesheuvel@linaro.org>

The TKIP code uses the arc4 cipher interface, and invokes it byte by
byte. This is rather inefficient, and since the cipher interface in
general is not really suitable for use outside of the crypto subsystem,
move this code to use the skcipher interface instead.

Given that the only driver that provides a RC4 cipher also provides
a skcipher implementation, this is guaranteed to work. (Note that
ARC4_BLOCK_SIZE is #define'd as 1 so ecb(arc4) behaves as a stream
cipher, as is required in this case)

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 net/wireless/lib80211_crypt_tkip.c | 61 ++++++++++++++------
 1 file changed, 42 insertions(+), 19 deletions(-)

diff --git a/net/wireless/lib80211_crypt_tkip.c b/net/wireless/lib80211_crypt_tkip.c
index 11eaa5956f00..456c85b03b32 100644
--- a/net/wireless/lib80211_crypt_tkip.c
+++ b/net/wireless/lib80211_crypt_tkip.c
@@ -30,6 +30,7 @@
 #include <net/iw_handler.h>
 
 #include <crypto/hash.h>
+#include <crypto/skcipher.h>
 #include <linux/crypto.h>
 #include <linux/crc32.h>
 
@@ -64,9 +65,11 @@ struct lib80211_tkip_data {
 
 	int key_idx;
 
-	struct crypto_cipher *rx_tfm_arc4;
+	struct crypto_skcipher *rx_tfm_arc4;
+	struct skcipher_request *rx_req_arc4;
 	struct crypto_shash *rx_tfm_michael;
-	struct crypto_cipher *tx_tfm_arc4;
+	struct crypto_skcipher *tx_tfm_arc4;
+	struct skcipher_request *tx_req_arc4;
 	struct crypto_shash *tx_tfm_michael;
 
 	/* scratch buffers for virt_to_page() (crypto API) */
@@ -99,7 +102,8 @@ static void *lib80211_tkip_init(int key_idx)
 
 	priv->key_idx = key_idx;
 
-	priv->tx_tfm_arc4 = crypto_alloc_cipher("arc4", 0, 0);
+	priv->tx_tfm_arc4 = crypto_alloc_skcipher("ecb(arc4)", 0,
+						  CRYPTO_ALG_ASYNC);
 	if (IS_ERR(priv->tx_tfm_arc4)) {
 		priv->tx_tfm_arc4 = NULL;
 		goto fail;
@@ -111,7 +115,8 @@ static void *lib80211_tkip_init(int key_idx)
 		goto fail;
 	}
 
-	priv->rx_tfm_arc4 = crypto_alloc_cipher("arc4", 0, 0);
+	priv->rx_tfm_arc4 = crypto_alloc_skcipher("ecb(arc4)", 0,
+						  CRYPTO_ALG_ASYNC);
 	if (IS_ERR(priv->rx_tfm_arc4)) {
 		priv->rx_tfm_arc4 = NULL;
 		goto fail;
@@ -123,14 +128,26 @@ static void *lib80211_tkip_init(int key_idx)
 		goto fail;
 	}
 
+	priv->tx_req_arc4 = skcipher_request_alloc(priv->tx_tfm_arc4,
+						   GFP_KERNEL);
+	if (!priv->tx_req_arc4)
+		goto fail;
+
+	priv->rx_req_arc4 = skcipher_request_alloc(priv->rx_tfm_arc4,
+						   GFP_KERNEL);
+	if (!priv->rx_req_arc4)
+		goto fail;
+
 	return priv;
 
       fail:
 	if (priv) {
+		skcipher_request_free(priv->tx_req_arc4);
+		skcipher_request_free(priv->rx_req_arc4);
 		crypto_free_shash(priv->tx_tfm_michael);
-		crypto_free_cipher(priv->tx_tfm_arc4);
+		crypto_free_skcipher(priv->tx_tfm_arc4);
 		crypto_free_shash(priv->rx_tfm_michael);
-		crypto_free_cipher(priv->rx_tfm_arc4);
+		crypto_free_skcipher(priv->rx_tfm_arc4);
 		kfree(priv);
 	}
 
@@ -141,10 +158,12 @@ static void lib80211_tkip_deinit(void *priv)
 {
 	struct lib80211_tkip_data *_priv = priv;
 	if (_priv) {
+		skcipher_request_free(_priv->tx_req_arc4);
+		skcipher_request_free(_priv->rx_req_arc4);
 		crypto_free_shash(_priv->tx_tfm_michael);
-		crypto_free_cipher(_priv->tx_tfm_arc4);
+		crypto_free_skcipher(_priv->tx_tfm_arc4);
 		crypto_free_shash(_priv->rx_tfm_michael);
-		crypto_free_cipher(_priv->rx_tfm_arc4);
+		crypto_free_skcipher(_priv->rx_tfm_arc4);
 	}
 	kfree(priv);
 }
@@ -342,10 +361,10 @@ static int lib80211_tkip_hdr(struct sk_buff *skb, int hdr_len,
 static int lib80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 {
 	struct lib80211_tkip_data *tkey = priv;
+	struct scatterlist sg;
 	int len;
 	u8 rc4key[16], *pos, *icv;
 	u32 crc;
-	int i;
 
 	if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
 		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
@@ -370,10 +389,11 @@ static int lib80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	icv[2] = crc >> 16;
 	icv[3] = crc >> 24;
 
-	crypto_cipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
-	for (i = 0; i < len + 4; i++)
-		crypto_cipher_encrypt_one(tkey->tx_tfm_arc4, pos + i, pos + i);
-	return 0;
+	crypto_skcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
+	sg_init_one(&sg, pos, len + 4);
+	skcipher_request_set_crypt(tkey->tx_req_arc4, &sg, &sg, len + 4, NULL);
+
+	return crypto_skcipher_encrypt(tkey->tx_req_arc4);
 }
 
 /*
@@ -392,6 +412,7 @@ static inline int tkip_replay_check(u32 iv32_n, u16 iv16_n,
 static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 {
 	struct lib80211_tkip_data *tkey = priv;
+	struct scatterlist sg;
 	u8 rc4key[16];
 	u8 keyidx, *pos;
 	u32 iv32;
@@ -400,7 +421,6 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	u8 icv[4];
 	u32 crc;
 	int plen;
-	int i;
 
 	hdr = (struct ieee80211_hdr *)skb->data;
 
@@ -453,9 +473,12 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 
 	plen = skb->len - hdr_len - 12;
 
-	crypto_cipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
-	for (i = 0; i < plen + 4; i++)
-		crypto_cipher_decrypt_one(tkey->rx_tfm_arc4, pos + i, pos + i);
+	crypto_skcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
+	sg_init_one(&sg, pos, plen + 4);
+	skcipher_request_set_crypt(tkey->rx_req_arc4, &sg, &sg, plen + 4, NULL);
+
+	if (crypto_skcipher_decrypt(tkey->rx_req_arc4))
+		return -7;
 
 	crc = ~crc32_le(~0, pos, plen);
 	icv[0] = crc;
@@ -640,9 +663,9 @@ static int lib80211_tkip_set_key(void *key, int len, u8 * seq, void *priv)
 	struct lib80211_tkip_data *tkey = priv;
 	int keyidx;
 	struct crypto_shash *tfm = tkey->tx_tfm_michael;
-	struct crypto_cipher *tfm2 = tkey->tx_tfm_arc4;
+	struct crypto_skcipher *tfm2 = tkey->tx_tfm_arc4;
 	struct crypto_shash *tfm3 = tkey->rx_tfm_michael;
-	struct crypto_cipher *tfm4 = tkey->rx_tfm_arc4;
+	struct crypto_skcipher *tfm4 = tkey->rx_tfm_arc4;
 
 	keyidx = tkey->key_idx;
 	memset(tkey, 0, sizeof(*tkey));
-- 
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