Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: iwl_mvm_add_new_dqa_stream_wk BUG in lib/list_debug.c:56
From: Marc Haber @ 2019-06-25 13:03 UTC (permalink / raw)
  To: linux-kernel, linux-wireless, netdev
In-Reply-To: <20190602134842.GC3249@torres.zugschlus.de>

On Sun, Jun 02, 2019 at 03:48:42PM +0200, Marc Haber wrote:
> On Thu, May 30, 2019 at 10:12:57AM +0200, Marc Haber wrote:
> > on my primary notebook, a Lenovo X260, with an Intel Wireless 8260
> > (8086:24f3), running Debian unstable, I have started to see network
> > hangs since upgrading to kernel 5.1. In this situation, I cannot
> > restart Network-Manager (the call just hangs), I can log out of X, but
> > the system does not cleanly shut down and I need to Magic SysRq myself
> > out of the running system. This happens about once every two days.
> 
> The issue is also present in 5.1.5 and 5.1.6.

Almost a month later, 5.1.15 still crashes about twice a day on my
Notebook. The error message seems pretty clear to me, how can I go on
from there and may be identify a line number outside of a library?

Greetings
Marc

-- 
-----------------------------------------------------------------------------
Marc Haber         | "I don't trust Computers. They | Mailadresse im Header
Leimen, Germany    |  lose things."    Winona Ryder | Fon: *49 6224 1600402
Nordisch by Nature |  How to make an American Quilt | Fax: *49 6224 1600421

^ permalink raw reply

* Re: [PATCH v2] ath10k: fix failure to set multiple fixed rate
From: Kalle Valo @ 2019-06-25 13:02 UTC (permalink / raw)
  To: Miaoqing Pan; +Cc: ath10k, linux-wireless, Miaoqing Pan
In-Reply-To: <1559117608-11117-1-git-send-email-miaoqing@codeaurora.org>

Miaoqing Pan <miaoqing@codeaurora.org> wrote:

> Currently, below fixed rate commands are broken,
> iw wlanx set bitrates legacy-<2.4|5> ht-mcs-<2.4|5> vht-mcs-<2.4|5> \
> <NSS:MCSx>
> iw wlanx set bitrates legacy-<2.4|5> <legacy rate> ht-mcs-<2.4|5> \
> vht-mcs-<2.4|5> <NSS:MCSx>
> 
> There are two methods to set fixed rate, both failed,
> - Use vdev fixed rate command
>   This command only support one single rate, but it's broken due to
>   mac80211 change commit e8e4f5280ddd ("mac80211: reject/clear user
>   rate mask if not usable"), which requires user to specify at least
>   one legacy rate. So we can't use this command to set ht/vht single
>   rate any more.
> - Use peer_assoc command
>   This command can update rx capability for multiple rates, it will
>   work fine for ht mcs rates, as each supported mcs can be advertised
>   in ht_mcs index mask. But this will not work with vht rates because,
>   as per the vht mcs capability advertisement, there are only two bits
>   to indicate the supported mcs. E.g. only support 0-7, 0-8, 0-9.
> 
> So introduced new WMI command: WMI_PEER_PARAM_FIXED_RATE. After peer
> assoc, the peer fixed rate cmd will work for that specific peer.
> Remaining peers will use auto rate. If both vdev fixed rate and peer
> fixed rates are given, peer fixed rate will take effect to peers for
> which this cmd is given. Remaining peers in that vdev, will use vdev
> fixed rate.
> 
> Tested HW: QCA9984
> Tested FW: 10.4-3.9.0.2-00035
> 
> Signed-off-by: Miaoqing Pan <miaoqing@codeaurora.org>
> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>

Patch applied to ath-next branch of ath.git, thanks.

8b97b055dc9d ath10k: fix failure to set multiple fixed rate

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

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


^ permalink raw reply

* Re: [PATCH] ath10k: Change the warning message string
From: Kalle Valo @ 2019-06-25 13:00 UTC (permalink / raw)
  To: Fabio Estevam; +Cc: ath10k, andreyknvl, gregkh, linux-wireless, Fabio Estevam
In-Reply-To: <20190509121500.4730-1-festevam@gmail.com>

Fabio Estevam <festevam@gmail.com> wrote:

> The "WARNING" string confuses syzbot, which thinks it found
> a crash [1].
> 
> Change the string to avoid such problem.
> 
> [1] https://lkml.org/lkml/2019/5/9/243
> 
> Reported-by: syzbot+c1b25598aa60dcd47e78@syzkaller.appspotmail.com
> Suggested-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Fabio Estevam <festevam@gmail.com>
> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>

Patch applied to ath-next branch of ath.git, thanks.

265df32eae58 ath10k: Change the warning message string

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

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


^ permalink raw reply

* Re: [PATCH v2] ath10k: fix fw crash by moving chip reset after napi disabled
From: Kalle Valo @ 2019-06-25 12:59 UTC (permalink / raw)
  To: Miaoqing Pan; +Cc: ath10k, linux-wireless, Miaoqing Pan
In-Reply-To: <1558667782-10998-1-git-send-email-miaoqing@codeaurora.org>

Miaoqing Pan <miaoqing@codeaurora.org> wrote:

> On SMP platform, when continuously running wifi up/down, the napi
> poll can be scheduled during chip reset, which will call
> ath10k_pci_has_fw_crashed() to check the fw status. But in the reset
> period, the value from FW_INDICATOR_ADDRESS register will return
> 0xdeadbeef, which also be treated as fw crash. Fix the issue by
> moving chip reset after napi disabled.
> 
> ath10k_pci 0000:01:00.0: firmware crashed! (guid 73b30611-5b1e-4bdd-90b4-64c81eb947b6)
> ath10k_pci 0000:01:00.0: qca9984/qca9994 hw1.0 target 0x01000000 chip_id 0x00000000 sub 168c:cafe
> ath10k_pci 0000:01:00.0: htt-ver 2.2 wmi-op 6 htt-op 4 cal otp max-sta 512 raw 0 hwcrypto 1
> ath10k_pci 0000:01:00.0: failed to get memcpy hi address for firmware address 4: -16
> ath10k_pci 0000:01:00.0: failed to read firmware dump area: -16
> ath10k_pci 0000:01:00.0: Copy Engine register dump:
> ath10k_pci 0000:01:00.0: [00]: 0x0004a000   0   0   0   0
> ath10k_pci 0000:01:00.0: [01]: 0x0004a400   0   0   0   0
> ath10k_pci 0000:01:00.0: [02]: 0x0004a800   0   0   0   0
> ath10k_pci 0000:01:00.0: [03]: 0x0004ac00   0   0   0   0
> ath10k_pci 0000:01:00.0: [04]: 0x0004b000   0   0   0   0
> ath10k_pci 0000:01:00.0: [05]: 0x0004b400   0   0   0   0
> ath10k_pci 0000:01:00.0: [06]: 0x0004b800   0   0   0   0
> ath10k_pci 0000:01:00.0: [07]: 0x0004bc00   1   0   1   0
> ath10k_pci 0000:01:00.0: [08]: 0x0004c000   0   0   0   0
> ath10k_pci 0000:01:00.0: [09]: 0x0004c400   0   0   0   0
> ath10k_pci 0000:01:00.0: [10]: 0x0004c800   0   0   0   0
> ath10k_pci 0000:01:00.0: [11]: 0x0004cc00   0   0   0   0
> 
> Tested HW: QCA9984,QCA9887,WCN3990
> 
> Signed-off-by: Miaoqing Pan <miaoqing@codeaurora.org>
> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>

Patch applied to ath-next branch of ath.git, thanks.

08d80e4cd27b ath10k: fix fw crash by moving chip reset after napi disabled

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

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


^ permalink raw reply

* Re: [PATCH] ath10k: add missing error handling
From: Kalle Valo @ 2019-06-25 12:58 UTC (permalink / raw)
  To: Claire Chang; +Cc: ath10k, linux-wireless, wgong, Claire Chang
In-Reply-To: <20190523071534.254611-1-tientzu@chromium.org>

Claire Chang <tientzu@chromium.org> wrote:

> In function ath10k_sdio_mbox_rx_alloc() [sdio.c],
> ath10k_sdio_mbox_alloc_rx_pkt() is called without handling the error cases.
> This will make the driver think the allocation for skb is successful and
> try to access the skb. If we enable failslab, system will easily crash with
> NULL pointer dereferencing.
> 
> Call trace of CONFIG_FAILSLAB:
> ath10k_sdio_irq_handler+0x570/0xa88 [ath10k_sdio]
> process_sdio_pending_irqs+0x4c/0x174
> sdio_run_irqs+0x3c/0x64
> sdio_irq_work+0x1c/0x28
> 
> Fixes: d96db25d2025 ("ath10k: add initial SDIO support")
> Signed-off-by: Claire Chang <tientzu@chromium.org>
> Reviewed-by: Brian Norris <briannorris@chromium.org>
> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>

Patch applied to ath-next branch of ath.git, thanks.

4b553f3ca4cb ath10k: add missing error handling

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

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


^ permalink raw reply

* Re: [PATCH] ath10k: enabling tx stats support over pktlog
From: Kalle Valo @ 2019-06-25 12:56 UTC (permalink / raw)
  To: Balaji Pothunoori; +Cc: ath10k, linux-wireless, Balaji Pothunoori
In-Reply-To: <1557759187-23910-1-git-send-email-bpothuno@codeaurora.org>

Balaji Pothunoori <bpothuno@codeaurora.org> wrote:

> For QCA988X target, pktlog gives details of the tx bitrate
> which is used in the driver for station info.
> 
> Enabling pktlog by default will cause more interrupts
> in target to host CE pipe, which can impact more CPU usage
> for targets ex:WCN3990 and also not required for all other
> platforms (eg: WCN3990), for getting tx bitrate.
> 
> Enable pktlog only for QCA988X based on hardware params.
> 
> Tested HW : WCN3990
> Tested FW : WLAN.HL.3.1-00784-QCAHLSWMTPLZ-1
> 
> Fixes: e8123bb74c4e ("ath10k: add per peer tx stats support for 10.2.4")
> Signed-off-by: Balaji Pothunoori <bpothuno@codeaurora.org>
> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>

Patch applied to ath-next branch of ath.git, thanks.

4fa42adebe5b ath10k: enabling tx stats support over pktlog

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

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


^ permalink raw reply

* Re: [PATCH] ath10k: acquire lock to fix lockdep's warning
From: Kalle Valo @ 2019-06-25 12:55 UTC (permalink / raw)
  To: Claire Chang; +Cc: linux-wireless, ath10k, wgong, drinkcat, Claire Chang
In-Reply-To: <20190506073836.184059-1-tientzu@chromium.org>

Claire Chang <tientzu@chromium.org> wrote:

> Lockdep warns at lockdep_assert_held(&ar->data_lock) in
> ath10k_htt_rx_pn_check_replay_hl(). Acquire ar->data_lock before calling
> ath10k_htt_rx_pn_check_replay_hl() to fix it.
> 
> Call trace:
> ath10k_htt_rx_pn_check_replay_hl+0x118/0x134 [ath10k_core]
> ath10k_htt_rx_proc_rx_ind_hl+0xd8/0x250 [ath10k_core]
> ath10k_htt_t2h_msg_handler+0x148/0xf30 [ath10k_core]
> ath10k_htt_htc_t2h_msg_handler+0x24/0x40 [ath10k_core]
> ath10k_sdio_irq_handler+0x374/0xaa4 [ath10k_sdio]
> 
> Fixes: 130c77495708 ("ath10k: add PN replay protection for high latency devices")
> Signed-off-by: Claire Chang <tientzu@chromium.org>
> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>

Patch applied to ath-next branch of ath.git, thanks.

ef9cc0c44394 ath10k: acquire lock to fix lockdep's warning

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

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


^ permalink raw reply

* Re: [PATCH] ath10k: change firmware file name for UTF mode of SDIO/USB
From: Kalle Valo @ 2019-06-25 12:54 UTC (permalink / raw)
  To: Wen Gong; +Cc: ath10k, linux-wireless
In-Reply-To: <1557891047-16606-1-git-send-email-wgong@codeaurora.org>

Wen Gong <wgong@codeaurora.org> wrote:

> Firmware name for UTF mode of SDIO has changed from utf-2.bin to
> utf-sdio-2.bin, so it need to change in ath10k, otherwise it will
> fail for UTF mode.
> 
> After change the name in ath10k, it will success for UTF mode of
> SDIO/USB.
> 
> 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>

Patch applied to ath-next branch of ath.git, thanks.

54f6643bf19e ath10k: change firmware file name for UTF mode of SDIO/USB

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

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


^ permalink raw reply

* Re: [PATCH v3] ath10k: add support for firmware crash recovery on SDIO chip
From: Kalle Valo @ 2019-06-25 12:53 UTC (permalink / raw)
  To: Wen Gong; +Cc: ath10k, linux-wireless
In-Reply-To: <1558506776-19702-1-git-send-email-wgong@codeaurora.org>

Wen Gong <wgong@codeaurora.org> wrote:

> The command to simulate firmware crash:
> echo soft > /sys/kernel/debug/ieee80211/phy0/ath10k/simulate_fw_crash
> 
> It will send WMI_FORCE_FW_HANG_ASSERT to firmware, then it will trigger
> CPU interrupt status register for SDIO chip, ath10k driver need to
> configure it while enable SDIO interrupt, otherwise ath10k driver will
> not get the assert error info.
> 
> After this change, it will success for simulate firmware crash.
> 
> Tested with QCA6174 SDIO with firmware
> WLAN.RMH.4.4.1-00007-QCARMSWP-1.
> 
> Signed-off-by: Wen Gong <wgong@codeaurora.org>
> Tested-by: Claire Chang <tientzu@chromium.org>
> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>

Patch applied to ath-next branch of ath.git, thanks.

0f132ba7ac64 ath10k: add support for firmware crash recovery on SDIO chip

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

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


^ permalink raw reply

* Re: [PATCHv2] ath10k: Add wrapper function to ath10k debug
From: Kalle Valo @ 2019-06-25 12:49 UTC (permalink / raw)
  To: Venkateswara Naralasetty
  Cc: ath10k, linux-wireless, Venkateswara Naralasetty, Kan Yan
In-Reply-To: <1556283505-29539-1-git-send-email-vnaralas@codeaurora.org>

Venkateswara Naralasetty <vnaralas@codeaurora.org> wrote:

> ath10k_dbg() is called in ath10k_process_rx() with huge set of arguments
> which is causing CPU overhead even when debug_mask is not set.
> Good improvement was observed in the receive side performance when call
> to ath10k_dbg() is avoided in the RX path.
> 
> Since currently all debug messages are sent via tracing infrastructure,
> we cannot entirely avoid calling ath10k_dbg. Therefore, call to
> ath10k_dbg() is made conditional based on tracing config in the driver.
> 
> Trasmit performance remains unchanged with this patch; below are some
> experimental results with this patch and tracing disabled.
> 
> mesh mode:
> 
> 		w/o this patch          with this patch
> Traffic       TP      CPU Usage      TP      CPU usage
> 
> TCP          840Mbps    76.53%      960Mbps    78.14%
> UDP          1030Mbps   74.58%      1132Mbps   74.31%
> 
> Infra mode:
> 
> 		w/o this patch          with this patch
> Traffic        TP      CPU Usage      TP      CPU usage
> 
> TCP Rx       1241Mbps   80.89%      1270Mbps   73.50%
> UDP Rx       1433Mbps   81.77%      1472Mbps   72.80%
> 
> Tested platform	: IPQ8064
> hardware used	: QCA9984
> firmware ver	: ver 10.4-3.5.3-00057
> 
> Signed-off-by: Kan Yan <kyan@chromium.org>
> Signed-off-by: Venkateswara Naralasetty <vnaralas@codeaurora.org>
> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>

Patch applied to ath-next branch of ath.git, thanks.

9d740d6380e5 ath10k: Add wrapper function to ath10k debug

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

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


^ permalink raw reply

* Re: [PATCH 1/2] ath10k: add inline wrapper for htt_h2t_aggr_cfg_msg
From: Kalle Valo @ 2019-06-25 12:47 UTC (permalink / raw)
  To: Erik Stromdahl; +Cc: kvalo, linux-wireless, ath10k, Erik Stromdahl
In-Reply-To: <20190326162904.6737-1-erik.stromdahl@gmail.com>

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

> This is done in order to make the *htt_h2t_aggr_cfg_msg* op align better
> with the rest of the htt ops (whom all have inline wrappers).
> 
> It also adds support for the case when the op is missing (function
> pointer is NULL).
> 
> As a result of this, the name of the 32 bit implementation in htt_tx.c
> was changed and the function was made static.
> 
> 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.

74ee5715991f ath10k: add inline wrapper for htt_h2t_aggr_cfg_msg
bc31c2cfecc7 ath10k: add htt_h2t_aggr_cfg_msg op for high latency devices

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

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


^ permalink raw reply

* Re: [PATCH] ssb/gpio: Remove unnecessary WARN_ON from driver_gpio
From: Kalle Valo @ 2019-06-25 12:24 UTC (permalink / raw)
  To: Jonas Gorski; +Cc: Michael Büsch, H Buus, Larry Finger, linux-wireless
In-Reply-To: <CAOiHx=k_KPgXqJYjSeUFVS3pae1CGBGS9STnTuAfNyvak2k08w@mail.gmail.com>

Jonas Gorski <jonas.gorski@gmail.com> writes:

> On Tue, 25 Jun 2019 at 12:06, Kalle Valo <kvalo@codeaurora.org> wrote:
>>
>> Michael Büsch <m@bues.ch> writes:
>>
>> > The WARN_ON triggers on older BCM4401-B0 100Base-TX ethernet controllers.
>> > The warning serves no purpose. So let's just remove it.
>> >
>> > Reported-by: H Buus <ubuntu@hbuus.com>
>> > Signed-off-by: Michael Büsch <m@bues.ch>
>>
>> For some reason patchwork (or pwcli script) didn't like this patch so
>> manually applied to wireless-drivers-next:
>>
>> e73e43246da6 ssb/gpio: Remove unnecessary WARN_ON from driver_gpio
>>
>> I have a faint recollection that I had a similar problem with another
>> patch from Michael, did we ever conclude what was the issue?
>
> Yes [1], a bug in kernel.org's version of patchwork.

Ah, that was it. Thanks!

> The fix was included in v2.1.1; latest is v2.1.3. kernel.org is
> (still) at v2.1.0. Maybe it's time to poke helpdesk?

Indeed, that would be a good idea. Apparently v2.1.0 was released a year
ago:

https://github.com/getpatchwork/patchwork/releases

So if your or anyone else has time, please do report to kernel.org
helpdesk and hopefully they can help.

-- 
Kalle Valo

^ permalink raw reply

* Re: [PATCH] ssb/gpio: Remove unnecessary WARN_ON from driver_gpio
From: Jonas Gorski @ 2019-06-25 12:10 UTC (permalink / raw)
  To: Kalle Valo; +Cc: Michael Büsch, H Buus, Larry Finger, linux-wireless
In-Reply-To: <87v9wus164.fsf@kamboji.qca.qualcomm.com>

On Tue, 25 Jun 2019 at 12:06, Kalle Valo <kvalo@codeaurora.org> wrote:
>
> Michael Büsch <m@bues.ch> writes:
>
> > The WARN_ON triggers on older BCM4401-B0 100Base-TX ethernet controllers.
> > The warning serves no purpose. So let's just remove it.
> >
> > Reported-by: H Buus <ubuntu@hbuus.com>
> > Signed-off-by: Michael Büsch <m@bues.ch>
>
> For some reason patchwork (or pwcli script) didn't like this patch so
> manually applied to wireless-drivers-next:
>
> e73e43246da6 ssb/gpio: Remove unnecessary WARN_ON from driver_gpio
>
> I have a faint recollection that I had a similar problem with another
> patch from Michael, did we ever conclude what was the issue?

Yes [1], a bug in kernel.org's version of patchwork. The fix was
included in v2.1.1; latest is v2.1.3. kernel.org is (still) at v2.1.0.
Maybe it's time to poke helpdesk?

Regards
Jonas

[1] https://marc.info/?l=linux-wireless&m=153388992528252&w=2

^ permalink raw reply

* [RFC V2 2/8] cfg80211: add 6GHz UNII band definitions
From: Arend van Spriel @ 2019-06-25 11:10 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1561461027-10793-1-git-send-email-arend.vanspriel@broadcom.com>

For the new 6GHz there are new UNII band definitions as listed
in the FCC notice [1].

[1] https://docs.fcc.gov/public/attachments/FCC-18-147A1_Rcd.pdf

Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
Reviewed-by: Leon Zegers <leon.zegers@broadcom.com>
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
---
 net/wireless/reg.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 4831ad74..646107a 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -3806,8 +3806,9 @@ void wiphy_regulatory_deregister(struct wiphy *wiphy)
 }
 
 /*
- * See http://www.fcc.gov/document/5-ghz-unlicensed-spectrum-unii, for
- * UNII band definitions
+ * See FCC notices for UNII band definitions
+ *  5GHz: https://www.fcc.gov/document/5-ghz-unlicensed-spectrum-unii
+ *  6GHz: https://www.fcc.gov/document/fcc-proposes-more-spectrum-unlicensed-use-0
  */
 int cfg80211_get_unii(int freq)
 {
@@ -3831,6 +3832,22 @@ int cfg80211_get_unii(int freq)
 	if (freq > 5725 && freq <= 5825)
 		return 4;
 
+	/* UNII-5 */
+	if (freq > 5925 && freq <= 6425)
+		return 5;
+
+	/* UNII-6 */
+	if (freq > 6425 && freq <= 6525)
+		return 6;
+
+	/* UNII-7 */
+	if (freq > 6525 && freq <= 6875)
+		return 7;
+
+	/* UNII-8 */
+	if (freq > 6875 && freq <= 7125)
+		return 8;
+
 	return -EINVAL;
 }
 
-- 
1.9.1


^ permalink raw reply related

* [RFC V2 4/8] cfg80211: extend ieee80211_operating_class_to_band() for 6GHz
From: Arend van Spriel @ 2019-06-25 11:10 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1561461027-10793-1-git-send-email-arend.vanspriel@broadcom.com>

Add 6GHz operating class range as defined in 802.11ax D4.1 Annex E.

Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
Reviewed-by: Leon Zegers <leon.zegers@broadcom.com>
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
---
 net/wireless/util.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/net/wireless/util.c b/net/wireless/util.c
index 4e633d4..4462837 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1474,6 +1474,9 @@ bool ieee80211_operating_class_to_band(u8 operating_class,
 	case 128 ... 130:
 		*band = NL80211_BAND_5GHZ;
 		return true;
+	case 131 ... 135:
+		*band = NL80211_BAND_6GHZ;
+		return true;
 	case 81:
 	case 82:
 	case 83:
-- 
1.9.1


^ permalink raw reply related

* [RFC V2 7/8] cfg80211: ibss: use 11a mandatory rates for 6GHz band operation
From: Arend van Spriel @ 2019-06-25 11:10 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1561461027-10793-1-git-send-email-arend.vanspriel@broadcom.com>

The default mandatory rates, ie. when not specified by user-space, is
determined by the band. Select 11a rateset for 6GHz band.

Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
Reviewed-by: Leon Zegers <leon.zegers@broadcom.com>
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
---
 net/wireless/ibss.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index d1743e6..ae8fe66 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -104,13 +104,19 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
 		* use the mandatory rate set for 11b or
 		* 11a for maximum compatibility.
 		*/
-		struct ieee80211_supported_band *sband =
-			rdev->wiphy.bands[params->chandef.chan->band];
+		struct ieee80211_supported_band *sband;
+		enum nl80211_band band;
+		u32 flag;
 		int j;
-		u32 flag = params->chandef.chan->band == NL80211_BAND_5GHZ ?
-			IEEE80211_RATE_MANDATORY_A :
-			IEEE80211_RATE_MANDATORY_B;
 
+		band = params->chandef.chan->band;
+		if (band == NL80211_BAND_5GHZ ||
+		    band == NL80211_BAND_6GHZ)
+			flag = IEEE80211_RATE_MANDATORY_A;
+		else
+			flag = IEEE80211_RATE_MANDATORY_B;
+
+		sband = rdev->wiphy.bands[band];
 		for (j = 0; j < sband->n_bitrates; j++) {
 			if (sband->bitrates[j].flags & flag)
 				params->basic_rates |= BIT(j);
-- 
1.9.1


^ permalink raw reply related

* [RFC V2 1/8] nl80211: add 6GHz band definition to enum nl80211_band
From: Arend van Spriel @ 2019-06-25 11:10 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1561461027-10793-1-git-send-email-arend.vanspriel@broadcom.com>

In the 802.11ax specification a new band is introduced, which
is also proposed by FCC for unlicensed use. This band is referred
to as 6GHz spanning frequency range from 5925 to 7125 MHz.

Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
Reviewed-by: Leon Zegers <leon.zegers@broadcom.com>
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
---
changes:
  - V2
	fix ABI breakage by appending the new band definition.
---
 include/uapi/linux/nl80211.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 8fc3a43..45b9117 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -4536,6 +4536,7 @@ enum nl80211_txrate_gi {
  * @NL80211_BAND_2GHZ: 2.4 GHz ISM band
  * @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz)
  * @NL80211_BAND_60GHZ: around 60 GHz band (58.32 - 69.12 GHz)
+ * @NL80211_BAND_6GHZ: around 6 GHz band (5.9 - 7.2 GHz)
  * @NUM_NL80211_BANDS: number of bands, avoid using this in userspace
  *	since newer kernel versions may support more bands
  */
@@ -4543,6 +4544,7 @@ enum nl80211_band {
 	NL80211_BAND_2GHZ,
 	NL80211_BAND_5GHZ,
 	NL80211_BAND_60GHZ,
+	NL80211_BAND_6GHZ,
 
 	NUM_NL80211_BANDS,
 };
-- 
1.9.1


^ permalink raw reply related

* [RFC V2 5/8] cfg80211: add 6GHz in code handling array with NUM_NL80211_BANDS entries
From: Arend van Spriel @ 2019-06-25 11:10 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1561461027-10793-1-git-send-email-arend.vanspriel@broadcom.com>

In nl80211.c there is a policy for all bands in NUM_NL80211_BANDS and
in trace.h there is a callback trace for multicast rates which is per
band in NUM_NL80211_BANDS. Both need to be extended for the new
NL80211_BAND_6GHZ.

Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
Reviewed-by: Leon Zegers <leon.zegers@broadcom.com>
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
---
 net/wireless/nl80211.c | 1 +
 net/wireless/trace.h   | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index fc83dd1..57bc35a 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -667,6 +667,7 @@ static int validate_ie_attr(const struct nlattr *attr,
 nl80211_match_band_rssi_policy[NUM_NL80211_BANDS] = {
 	[NL80211_BAND_2GHZ] = { .type = NLA_S32 },
 	[NL80211_BAND_5GHZ] = { .type = NLA_S32 },
+	[NL80211_BAND_6GHZ] = { .type = NLA_S32 },
 	[NL80211_BAND_60GHZ] = { .type = NLA_S32 },
 };
 
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 4fbb91a..d98ad2b 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -2446,10 +2446,11 @@
 		       sizeof(int) * NUM_NL80211_BANDS);
 	),
 	TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", "
-		  "mcast_rates [2.4GHz=0x%x, 5.2GHz=0x%x, 60GHz=0x%x]",
+		  "mcast_rates [2.4GHz=0x%x, 5.2GHz=0x%x, 6GHz=0x%x, 60GHz=0x%x]",
 		  WIPHY_PR_ARG, NETDEV_PR_ARG,
 		  __entry->mcast_rate[NL80211_BAND_2GHZ],
 		  __entry->mcast_rate[NL80211_BAND_5GHZ],
+		  __entry->mcast_rate[NL80211_BAND_6GHZ],
 		  __entry->mcast_rate[NL80211_BAND_60GHZ])
 );
 
-- 
1.9.1


^ permalink raw reply related

* [RFC V2 6/8] cfg80211: use same IR permissive rules for 6GHz band
From: Arend van Spriel @ 2019-06-25 11:10 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1561461027-10793-1-git-send-email-arend.vanspriel@broadcom.com>

The function cfg80211_ir_permissive_chan() is applicable for
6GHz band as well so make sure it is handled.

Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
Reviewed-by: Leon Zegers <leon.zegers@broadcom.com>
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
---
 net/wireless/chan.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 7dc1bbd..7c9d204 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -894,7 +894,8 @@ static bool cfg80211_ir_permissive_chan(struct wiphy *wiphy,
 		if (chan == other_chan)
 			return true;
 
-		if (chan->band != NL80211_BAND_5GHZ)
+		if (chan->band != NL80211_BAND_5GHZ &&
+		    chan->band != NL80211_BAND_6GHZ)
 			continue;
 
 		r1 = cfg80211_get_unii(chan->center_freq);
-- 
1.9.1


^ permalink raw reply related

* [RFC V2 8/8] cfg80211: apply same mandatory rate flags for 5GHz and 6GHz
From: Arend van Spriel @ 2019-06-25 11:10 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1561461027-10793-1-git-send-email-arend.vanspriel@broadcom.com>

For the new 6GHz band the same rules apply for mandatory rates so
add it to set_mandatory_flags_band() function.

Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
Reviewed-by: Leon Zegers <leon.zegers@broadcom.com>
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
---
 net/wireless/util.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/wireless/util.c b/net/wireless/util.c
index 4462837..f0558e7 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -156,6 +156,7 @@ static void set_mandatory_flags_band(struct ieee80211_supported_band *sband)
 
 	switch (sband->band) {
 	case NL80211_BAND_5GHZ:
+	case NL80211_BAND_6GHZ:
 		want = 3;
 		for (i = 0; i < sband->n_bitrates; i++) {
 			if (sband->bitrates[i].bitrate == 60 ||
-- 
1.9.1


^ permalink raw reply related

* [RFC V2 0/8] nl80211: add 6GHz band support
From: Arend van Spriel @ 2019-06-25 11:10 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Arend van Spriel

This is more or less a resend. The difference with the previous RFC is
in the nl80211 API as the previous RFC was breaking ABI.

In 802.11ax D4.0 a new band has been proposed. This series contains
changes to cfg80211 for supporting this band. With 2GHz and 5GHz there
was no overlap in channel number. However, this new band has channel
numbers with a range from 1 up to 253. The only place I could find an
issue with this is in cfg80211_wext_freq(). Not sure how to deal with
that so it is not part of this series.

The series applies to the master branch of the mac80211-next repository.

Arend van Spriel (8):
  nl80211: add 6GHz band definition to enum nl80211_band
  cfg80211: add 6GHz UNII band definitions
  cfg80211: util: add 6GHz channel to freq conversion and vice versa
  cfg80211: extend ieee80211_operating_class_to_band() for 6GHz
  cfg80211: add 6GHz in code handling array with NUM_NL80211_BANDS
    entries
  cfg80211: use same IR permissive rules for 6GHz band
  cfg80211: ibss: use 11a mandatory rates for 6GHz band operation
  cfg80211: apply same mandatory rate flags for 5GHz and 6GHz

 include/uapi/linux/nl80211.h |  2 ++
 net/wireless/chan.c          |  3 ++-
 net/wireless/ibss.c          | 16 +++++++++++-----
 net/wireless/nl80211.c       |  1 +
 net/wireless/reg.c           | 21 +++++++++++++++++++--
 net/wireless/trace.h         |  3 ++-
 net/wireless/util.c          | 14 +++++++++++++-
 7 files changed, 50 insertions(+), 10 deletions(-)

-- 
1.9.1


^ permalink raw reply

* [RFC V2 3/8] cfg80211: util: add 6GHz channel to freq conversion and vice versa
From: Arend van Spriel @ 2019-06-25 11:10 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1561461027-10793-1-git-send-email-arend.vanspriel@broadcom.com>

Extend the functions ieee80211_channel_to_frequency() and
ieee80211_frequency_to_channel() to support 6GHz band according
specification in 802.11ax D4.1 27.3.22.2.

Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
Reviewed-by: Leon Zegers <leon.zegers@broadcom.com>
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
---
 net/wireless/util.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/net/wireless/util.c b/net/wireless/util.c
index 1c39d6a..4e633d4 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -91,6 +91,11 @@ int ieee80211_channel_to_frequency(int chan, enum nl80211_band band)
 		else
 			return 5000 + chan * 5;
 		break;
+	case NL80211_BAND_6GHZ:
+		/* see 802.11ax D4.1 27.3.22.2 */
+		if (chan <= 253)
+			return 5940 + chan * 5;
+		break;
 	case NL80211_BAND_60GHZ:
 		if (chan < 7)
 			return 56160 + chan * 2160;
@@ -111,8 +116,11 @@ int ieee80211_frequency_to_channel(int freq)
 		return (freq - 2407) / 5;
 	else if (freq >= 4910 && freq <= 4980)
 		return (freq - 4000) / 5;
-	else if (freq <= 45000) /* DMG band lower limit */
+	else if (freq < 5940)
 		return (freq - 5000) / 5;
+	else if (freq <= 45000) /* DMG band lower limit */
+		/* see 802.11ax D4.1 27.3.22.2 */
+		return (freq - 5940) / 5;
 	else if (freq >= 58320 && freq <= 70200)
 		return (freq - 56160) / 2160;
 	else
-- 
1.9.1


^ permalink raw reply related

* [PATCH 1/2] mt76: mt7603: rework and fix tx status reporting
From: Felix Fietkau @ 2019-06-25 11:01 UTC (permalink / raw)
  To: linux-wireless

Tx status reporting on mt7603 has a number of issues:

- the hardware can alter the first rate index, but it is not reported to
  the driver
- probing is very imprecise, because it alters the per-client rate set,
  but only considers info->status.rates for rate selection of a single probe
  packet
- short/long GI selection has limitations, which are not accurately reported
  to mac80211
- if rates are changed while packets are in flight, tx status reports for
  the old rate set might be processed based on the new selection

This led to very suboptimal rate selection with minstrel_ht.

This patch completely reworks tx status reporting to get rid of these
limitations:

- Store the previous and current rate set in the driver + the TSF value
  at the time of the switch.
- Use the tx status TSF value to determine which rate set needs to be used
  as reference.
- Report only short or long GI rates for a single status event, not a mix.
- The hardware reports the last used rate index. Use it along with the
  retry count to figure out what rate was used for the first attempt.
- Use the same retry count value for all rate slots to make this calculation
  work.
- Derive the probe rate from the current rateset instead of the skb cb
- Do not wait for a status report for the probe frame before removing the
  probe rate from the rate table. Do it immediately after it was referenced
  in a tx status report.
- Use the first half of the first rate retry budget for the probe rate
  in order to avoid using too many retries on that rate

With this patch, throughput under bad link conditions is improved
significantly, and there is a lot less rate fluctuation going on.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
 .../net/wireless/mediatek/mt76/mt7603/init.c  |   5 +-
 .../net/wireless/mediatek/mt76/mt7603/mac.c   | 127 +++++++++++++-----
 .../wireless/mediatek/mt76/mt7603/mt7603.h    |  11 +-
 .../net/wireless/mediatek/mt76/mt7603/regs.h  |   6 +
 4 files changed, 108 insertions(+), 41 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/init.c b/drivers/net/wireless/mediatek/mt76/mt7603/init.c
index bce51997ff3b..d666e26afe90 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/init.c
@@ -229,9 +229,8 @@ mt7603_mac_init(struct mt7603_dev *dev)
 
 	mt76_wr(dev, MT_AGG_ARUCR, FIELD_PREP(MT_AGG_ARxCR_LIMIT(0), 7));
 	mt76_wr(dev, MT_AGG_ARDCR,
-		FIELD_PREP(MT_AGG_ARxCR_LIMIT(0), 0) |
-		FIELD_PREP(MT_AGG_ARxCR_LIMIT(1),
-			   max_t(int, 0, MT7603_RATE_RETRY - 2)) |
+		FIELD_PREP(MT_AGG_ARxCR_LIMIT(0), MT7603_RATE_RETRY - 1) |
+		FIELD_PREP(MT_AGG_ARxCR_LIMIT(1), MT7603_RATE_RETRY - 1) |
 		FIELD_PREP(MT_AGG_ARxCR_LIMIT(2), MT7603_RATE_RETRY - 1) |
 		FIELD_PREP(MT_AGG_ARxCR_LIMIT(3), MT7603_RATE_RETRY - 1) |
 		FIELD_PREP(MT_AGG_ARxCR_LIMIT(4), MT7603_RATE_RETRY - 1) |
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
index 6629dd64cc22..e2ad5c769072 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
@@ -591,6 +591,7 @@ void mt7603_wtbl_set_rates(struct mt7603_dev *dev, struct mt7603_sta *sta,
 			   struct ieee80211_tx_rate *probe_rate,
 			   struct ieee80211_tx_rate *rates)
 {
+	struct ieee80211_tx_rate *ref;
 	int wcid = sta->wcid.idx;
 	u32 addr = mt7603_wtbl2_addr(wcid);
 	bool stbc = false;
@@ -599,7 +600,8 @@ void mt7603_wtbl_set_rates(struct mt7603_dev *dev, struct mt7603_sta *sta,
 	u16 val[4];
 	u16 probe_val;
 	u32 w9 = mt76_rr(dev, addr + 9 * 4);
-	int i;
+	bool rateset;
+	int i, k;
 
 	if (!mt76_poll(dev, MT_WTBL_UPDATE, MT_WTBL_UPDATE_BUSY, 0, 5000))
 		return;
@@ -607,6 +609,41 @@ void mt7603_wtbl_set_rates(struct mt7603_dev *dev, struct mt7603_sta *sta,
 	for (i = n_rates; i < 4; i++)
 		rates[i] = rates[n_rates - 1];
 
+	rateset = !(sta->rate_set_tsf & BIT(0));
+	memcpy(sta->rateset[rateset].rates, rates,
+	       sizeof(sta->rateset[rateset].rates));
+	if (probe_rate) {
+		sta->rateset[rateset].probe_rate = *probe_rate;
+		ref = &sta->rateset[rateset].probe_rate;
+	} else {
+		sta->rateset[rateset].probe_rate.idx = -1;
+		ref = &sta->rateset[rateset].rates[0];
+	}
+
+	rates = sta->rateset[rateset].rates;
+	for (i = 0; i < ARRAY_SIZE(sta->rateset[rateset].rates); i++) {
+		/*
+		 * We don't support switching between short and long GI
+		 * within the rate set. For accurate tx status reporting, we
+		 * need to make sure that flags match.
+		 * For improved performance, avoid duplicate entries by
+		 * decrementing the MCS index if necessary
+		 */
+		if ((ref->flags ^ rates[i].flags) & IEEE80211_TX_RC_SHORT_GI)
+			rates[i].flags ^= IEEE80211_TX_RC_SHORT_GI;
+
+		for (k = 0; k < i; k++) {
+			if (rates[i].idx != rates[k].idx)
+				continue;
+			if ((rates[i].flags ^ rates[k].flags) &
+			    IEEE80211_TX_RC_40_MHZ_WIDTH)
+				continue;
+
+			rates[i].idx--;
+		}
+
+	}
+
 	w9 &= MT_WTBL2_W9_SHORT_GI_20 | MT_WTBL2_W9_SHORT_GI_40 |
 	      MT_WTBL2_W9_SHORT_GI_80;
 
@@ -650,19 +687,22 @@ void mt7603_wtbl_set_rates(struct mt7603_dev *dev, struct mt7603_sta *sta,
 	mt76_wr(dev, MT_WTBL_RIUCR1,
 		FIELD_PREP(MT_WTBL_RIUCR1_RATE0, probe_val) |
 		FIELD_PREP(MT_WTBL_RIUCR1_RATE1, val[0]) |
-		FIELD_PREP(MT_WTBL_RIUCR1_RATE2_LO, val[0]));
+		FIELD_PREP(MT_WTBL_RIUCR1_RATE2_LO, val[1]));
 
 	mt76_wr(dev, MT_WTBL_RIUCR2,
-		FIELD_PREP(MT_WTBL_RIUCR2_RATE2_HI, val[0] >> 8) |
+		FIELD_PREP(MT_WTBL_RIUCR2_RATE2_HI, val[1] >> 8) |
 		FIELD_PREP(MT_WTBL_RIUCR2_RATE3, val[1]) |
-		FIELD_PREP(MT_WTBL_RIUCR2_RATE4, val[1]) |
+		FIELD_PREP(MT_WTBL_RIUCR2_RATE4, val[2]) |
 		FIELD_PREP(MT_WTBL_RIUCR2_RATE5_LO, val[2]));
 
 	mt76_wr(dev, MT_WTBL_RIUCR3,
 		FIELD_PREP(MT_WTBL_RIUCR3_RATE5_HI, val[2] >> 4) |
-		FIELD_PREP(MT_WTBL_RIUCR3_RATE6, val[2]) |
+		FIELD_PREP(MT_WTBL_RIUCR3_RATE6, val[3]) |
 		FIELD_PREP(MT_WTBL_RIUCR3_RATE7, val[3]));
 
+	mt76_set(dev, MT_LPON_T0CR, MT_LPON_T0CR_MODE); /* TSF read */
+	sta->rate_set_tsf = (mt76_rr(dev, MT_LPON_UTTR0) & ~BIT(0)) | rateset;
+
 	mt76_wr(dev, MT_WTBL_UPDATE,
 		FIELD_PREP(MT_WTBL_UPDATE_WLAN_IDX, wcid) |
 		MT_WTBL_UPDATE_RATE_UPDATE |
@@ -889,9 +929,9 @@ int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
 
 	if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) {
 		spin_lock_bh(&dev->mt76.lock);
-		msta->rate_probe = true;
 		mt7603_wtbl_set_rates(dev, msta, &info->control.rates[0],
 				      msta->rates);
+		msta->rate_probe = true;
 		spin_unlock_bh(&dev->mt76.lock);
 	}
 
@@ -906,9 +946,12 @@ mt7603_fill_txs(struct mt7603_dev *dev, struct mt7603_sta *sta,
 		struct ieee80211_tx_info *info, __le32 *txs_data)
 {
 	struct ieee80211_supported_band *sband;
-	int final_idx = 0;
+	struct mt7603_rate_set *rs;
+	int first_idx = 0, last_idx;
+	u32 rate_set_tsf;
 	u32 final_rate;
 	u32 final_rate_flags;
+	bool rs_idx;
 	bool ack_timeout;
 	bool fixed_rate;
 	bool probe;
@@ -925,6 +968,7 @@ mt7603_fill_txs(struct mt7603_dev *dev, struct mt7603_sta *sta,
 	txs = le32_to_cpu(txs_data[4]);
 	ampdu = !fixed_rate && (txs & MT_TXS4_AMPDU);
 	count = FIELD_GET(MT_TXS4_TX_COUNT, txs);
+	last_idx = FIELD_GET(MT_TXS4_LAST_TX_RATE, txs);
 
 	txs = le32_to_cpu(txs_data[0]);
 	final_rate = FIELD_GET(MT_TXS0_TX_RATE, txs);
@@ -946,38 +990,57 @@ mt7603_fill_txs(struct mt7603_dev *dev, struct mt7603_sta *sta,
 	if (ampdu || (info->flags & IEEE80211_TX_CTL_AMPDU))
 		info->flags |= IEEE80211_TX_STAT_AMPDU | IEEE80211_TX_CTL_AMPDU;
 
+	first_idx = max_t(int, 0, last_idx - (count + 1) / MT7603_RATE_RETRY);
+
 	if (fixed_rate && !probe) {
 		info->status.rates[0].count = count;
+		i = 0;
 		goto out;
 	}
 
-	for (i = 0, idx = 0; i < ARRAY_SIZE(info->status.rates); i++) {
-		int cur_count = min_t(int, count, 2 * MT7603_RATE_RETRY);
+	rate_set_tsf = ACCESS_ONCE(sta->rate_set_tsf);
+	rs_idx = !((u32)(FIELD_GET(MT_TXS1_F0_TIMESTAMP, le32_to_cpu(txs_data[1])) -
+			 rate_set_tsf) < 1000000);
+	rs_idx ^= rate_set_tsf & BIT(0);
+	rs = &sta->rateset[rs_idx];
 
-		if (!i && probe) {
-			cur_count = 1;
-		} else {
-			info->status.rates[i] = sta->rates[idx];
-			idx++;
-		}
+	if (!first_idx && rs->probe_rate.idx >= 0) {
+		info->status.rates[0] = rs->probe_rate;
 
-		if (i && info->status.rates[i].idx < 0) {
-			info->status.rates[i - 1].count += count;
-			break;
+		spin_lock_bh(&dev->mt76.lock);
+		if (sta->rate_probe) {
+			mt7603_wtbl_set_rates(dev, sta, NULL,
+					      sta->rates);
+			sta->rate_probe = false;
 		}
+		spin_unlock_bh(&dev->mt76.lock);
+	} else
+		info->status.rates[0] = rs->rates[first_idx / 2];
+	info->status.rates[0].count = 0;
 
-		if (!count) {
-			info->status.rates[i].idx = -1;
-			break;
-		}
+	for (i = 0, idx = first_idx; count && idx <= last_idx; idx++) {
+		struct ieee80211_tx_rate *cur_rate;
+		int cur_count;
 
-		info->status.rates[i].count = cur_count;
-		final_idx = i;
+		cur_rate = &rs->rates[idx / 2];
+		cur_count = min_t(int, MT7603_RATE_RETRY, count);
 		count -= cur_count;
+
+		if (idx && (cur_rate->idx != info->status.rates[i].idx ||
+			    cur_rate->flags != info->status.rates[i].flags)) {
+			i++;
+			if (i == ARRAY_SIZE(info->status.rates))
+				break;
+
+			info->status.rates[i] = *cur_rate;
+			info->status.rates[i].count = 0;
+		}
+
+		info->status.rates[i].count += cur_count;
 	}
 
 out:
-	final_rate_flags = info->status.rates[final_idx].flags;
+	final_rate_flags = info->status.rates[i].flags;
 
 	switch (FIELD_GET(MT_TX_RATE_MODE, final_rate)) {
 	case MT_PHY_TYPE_CCK:
@@ -1004,8 +1067,8 @@ mt7603_fill_txs(struct mt7603_dev *dev, struct mt7603_sta *sta,
 		return false;
 	}
 
-	info->status.rates[final_idx].idx = final_rate;
-	info->status.rates[final_idx].flags = final_rate_flags;
+	info->status.rates[i].idx = final_rate;
+	info->status.rates[i].flags = final_rate_flags;
 
 	return true;
 }
@@ -1026,16 +1089,6 @@ mt7603_mac_add_txs_skb(struct mt7603_dev *dev, struct mt7603_sta *sta, int pid,
 	if (skb) {
 		struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
-		if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) {
-			spin_lock_bh(&dev->mt76.lock);
-			if (sta->rate_probe) {
-				mt7603_wtbl_set_rates(dev, sta, NULL,
-						      sta->rates);
-				sta->rate_probe = false;
-			}
-			spin_unlock_bh(&dev->mt76.lock);
-		}
-
 		if (!mt7603_fill_txs(dev, sta, info, txs_data)) {
 			ieee80211_tx_info_clear_status(info);
 			info->status.rates[0].idx = -1;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
index 944dc9a11a15..60f8269daae7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
@@ -51,6 +51,11 @@ enum mt7603_bw {
 	MT_BW_80,
 };
 
+struct mt7603_rate_set {
+	struct ieee80211_tx_rate probe_rate;
+	struct ieee80211_tx_rate rates[4];
+};
+
 struct mt7603_sta {
 	struct mt76_wcid wcid; /* must be first */
 
@@ -58,7 +63,11 @@ struct mt7603_sta {
 
 	struct sk_buff_head psq;
 
-	struct ieee80211_tx_rate rates[8];
+	struct ieee80211_tx_rate rates[4];
+
+	struct mt7603_rate_set rateset[2];
+	u32 rate_set_tsf;
+
 	u8 rate_count;
 	u8 n_rates;
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/regs.h b/drivers/net/wireless/mediatek/mt76/mt7603/regs.h
index 9d257d5c309d..eb9eefe8e125 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/regs.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/regs.h
@@ -480,6 +480,12 @@ enum {
 #define MT_LPON_BASE			0x24000
 #define MT_LPON(n)			(MT_LPON_BASE + (n))
 
+#define MT_LPON_T0CR			MT_LPON(0x010)
+#define MT_LPON_T0CR_MODE		GENMASK(1, 0)
+
+#define MT_LPON_UTTR0			MT_LPON(0x018)
+#define MT_LPON_UTTR1			MT_LPON(0x01c)
+
 #define MT_LPON_BTEIR			MT_LPON(0x020)
 #define MT_LPON_BTEIR_MBSS_MODE		GENMASK(31, 29)
 
-- 
2.17.0


^ permalink raw reply related

* [PATCH 2/2] mt76: mt7603: improve hardware rate switching configuration
From: Felix Fietkau @ 2019-06-25 11:01 UTC (permalink / raw)
  To: linux-wireless
In-Reply-To: <20190625110123.12979-1-nbd@nbd.name>

Now that tx status reporting can figure out the first attempted rate, we can
make switching from lower rates to higher rates more conservative.
This reduces retries under bad link conditions and ensures that fallback
rates get more test coverage

Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
 drivers/net/wireless/mediatek/mt76/mt7603/init.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/init.c b/drivers/net/wireless/mediatek/mt76/mt7603/init.c
index d666e26afe90..357db811ad32 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/init.c
@@ -227,7 +227,16 @@ mt7603_mac_init(struct mt7603_dev *dev)
 	mt76_rmw_field(dev, MT_LPON_BTEIR, MT_LPON_BTEIR_MBSS_MODE, 2);
 	mt76_rmw_field(dev, MT_WF_RMACDR, MT_WF_RMACDR_MBSSID_MASK, 2);
 
-	mt76_wr(dev, MT_AGG_ARUCR, FIELD_PREP(MT_AGG_ARxCR_LIMIT(0), 7));
+	mt76_wr(dev, MT_AGG_ARUCR,
+		FIELD_PREP(MT_AGG_ARxCR_LIMIT(0), 7) |
+		FIELD_PREP(MT_AGG_ARxCR_LIMIT(1), 2) |
+		FIELD_PREP(MT_AGG_ARxCR_LIMIT(2), 2) |
+		FIELD_PREP(MT_AGG_ARxCR_LIMIT(3), 2) |
+		FIELD_PREP(MT_AGG_ARxCR_LIMIT(4), 1) |
+		FIELD_PREP(MT_AGG_ARxCR_LIMIT(5), 1) |
+		FIELD_PREP(MT_AGG_ARxCR_LIMIT(6), 1) |
+		FIELD_PREP(MT_AGG_ARxCR_LIMIT(7), 1));
+
 	mt76_wr(dev, MT_AGG_ARDCR,
 		FIELD_PREP(MT_AGG_ARxCR_LIMIT(0), MT7603_RATE_RETRY - 1) |
 		FIELD_PREP(MT_AGG_ARxCR_LIMIT(1), MT7603_RATE_RETRY - 1) |
-- 
2.17.0


^ permalink raw reply related

* [PATCH v3 3/4] mt76: mt76x02: fix tx status reporting issues
From: Felix Fietkau @ 2019-06-25 10:58 UTC (permalink / raw)
  To: linux-wireless; +Cc: lorenzo
In-Reply-To: <20190612143833.51959-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>
---
v3: fix endian issue
v2: fix reporting of non-probing frames with tx status requested

 drivers/net/wireless/mediatek/mt76/mt76.h     |  11 +-
 .../net/wireless/mediatek/mt76/mt76x02_mac.c  | 102 +++++++++++++++---
 .../net/wireless/mediatek/mt76/mt76x02_txrx.c |   8 +-
 .../wireless/mediatek/mt76/mt76x02_usb_core.c |   8 +-
 4 files changed, 109 insertions(+), 20 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..82bafb5ac326 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -420,30 +420,92 @@ void mt76x02_mac_write_txwi(struct mt76x02_dev *dev, struct mt76x02_txwi *txwi,
 EXPORT_SYMBOL_GPL(mt76x02_mac_write_txwi);
 
 static void
-mt76x02_mac_fill_tx_status(struct mt76x02_dev *dev,
+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 mt76x02_sta *msta,
 			   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);
+	} else if (rate[0].idx < 0) {
+		if (!msta)
+			return;
+
+		mt76x02_mac_process_tx_rate(&rate[0], msta->wcid.tx_info,
+					    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 +551,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;
 
@@ -512,14 +580,14 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev,
 			return;
 		}
 
-		mt76x02_mac_fill_tx_status(dev, status.info, &msta->status,
-					   msta->n_frames);
+		mt76x02_mac_fill_tx_status(dev, msta, status.info,
+					   &msta->status, msta->n_frames);
 
 		msta->status = *stat;
 		msta->n_frames = 1;
 		*update = 0;
 	} else {
-		mt76x02_mac_fill_tx_status(dev, status.info, stat, 1);
+		mt76x02_mac_fill_tx_status(dev, msta, status.info, stat, 1);
 		*update = 1;
 	}
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
index cf7abd9b7d2e..7a1164a07ee7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
@@ -164,9 +164,15 @@ 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 |
+		      (le16_to_cpu(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..47386ca713cc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
@@ -89,9 +89,15 @@ 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 |
+		      (le16_to_cpu(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


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