* [PATCH] mac80211: don't WARN on short WMM parameters from AP
From: Brian Norris @ 2019-07-26 22:47 UTC (permalink / raw)
To: Johannes Berg
Cc: linux-kernel, linux-wireless, Emmanuel Grumbach, Brian Norris
In a very similar spirit to commit c470bdc1aaf3 ("mac80211: don't WARN
on bad WMM parameters from buggy APs"), an AP may not transmit a
fully-formed WMM IE. For example, it may miss or repeat an Access
Category. The above loop won't catch that and will instead leave one of
the four ACs zeroed out. This triggers the following warning in
drv_conf_tx()
wlan0: invalid CW_min/CW_max: 0/0
and it may leave one of the hardware queues unconfigured. If we detect
such a case, let's just print a warning and fall back to the defaults.
Tested with a hacked version of hostapd, intentionally corrupting the
IEs in hostapd_eid_wmm().
Signed-off-by: Brian Norris <briannorris@chromium.org>
---
net/mac80211/mlme.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index a99ad0325309..4c888dc9bd81 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2042,6 +2042,16 @@ ieee80211_sta_wmm_params(struct ieee80211_local *local,
ieee80211_regulatory_limit_wmm_params(sdata, ¶ms[ac], ac);
}
+ /* WMM specification requires all 4 ACIs. */
+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
+ if (params[ac].cw_min == 0) {
+ sdata_info(sdata,
+ "AP has invalid WMM params (missing AC %d), using defaults\n",
+ ac);
+ return false;
+ }
+ }
+
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
mlme_dbg(sdata,
"WMM AC=%d acm=%d aifs=%d cWmin=%d cWmax=%d txop=%d uapsd=%d, downgraded=%d\n",
--
2.22.0.709.g102302147b-goog
^ permalink raw reply related
* [PATCH] Fix typo reigster to register
From: Pei Hsuan Hung @ 2019-07-27 14:21 UTC (permalink / raw)
Cc: afcidk, trivial, Russell Currey, Sam Bobroff,
Oliver O'Halloran, Benjamin Herrenschmidt, Paul Mackerras,
Michael Ellerman, Jeremy Kerr, Arnd Bergmann, MyungJoo Ham,
Chanwoo Choi, Liviu Dudau, Brian Starkey, David Airlie,
Daniel Vetter, Ping-Ke Shih, Kalle Valo, David S. Miller,
James Smart, Dick Kennedy, James E.J. Bottomley,
Martin K. Petersen, Alexander Viro, Larry Finger, linuxppc-dev,
linux-kernel, dri-devel, linux-wireless, netdev, linux-scsi,
linux-fsdevel
Signed-off-by: Pei Hsuan Hung <afcidk@gmail.com>
Cc: trivial@kernel.org
---
arch/powerpc/kernel/eeh.c | 2 +-
arch/powerpc/platforms/cell/spufs/switch.c | 4 ++--
drivers/extcon/extcon-rt8973a.c | 2 +-
drivers/gpu/drm/arm/malidp_regs.h | 2 +-
drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.h | 2 +-
drivers/scsi/lpfc/lpfc_hbadisc.c | 4 ++--
fs/userfaultfd.c | 2 +-
7 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index c0e4b73191f3..d75c9c24ec4d 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -1030,7 +1030,7 @@ int __init eeh_ops_register(struct eeh_ops *ops)
}
/**
- * eeh_ops_unregister - Unreigster platform dependent EEH operations
+ * eeh_ops_unregister - Unregister platform dependent EEH operations
* @name: name of EEH platform operations
*
* Unregister the platform dependent EEH operation callback
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c
index 5c3f5d088c3b..9548a086937b 100644
--- a/arch/powerpc/platforms/cell/spufs/switch.c
+++ b/arch/powerpc/platforms/cell/spufs/switch.c
@@ -574,7 +574,7 @@ static inline void save_mfc_rag(struct spu_state *csa, struct spu *spu)
{
/* Save, Step 38:
* Save RA_GROUP_ID register and the
- * RA_ENABLE reigster in the CSA.
+ * RA_ENABLE register in the CSA.
*/
csa->priv1.resource_allocation_groupID_RW =
spu_resource_allocation_groupID_get(spu);
@@ -1227,7 +1227,7 @@ static inline void restore_mfc_rag(struct spu_state *csa, struct spu *spu)
{
/* Restore, Step 29:
* Restore RA_GROUP_ID register and the
- * RA_ENABLE reigster from the CSA.
+ * RA_ENABLE register from the CSA.
*/
spu_resource_allocation_groupID_set(spu,
csa->priv1.resource_allocation_groupID_RW);
diff --git a/drivers/extcon/extcon-rt8973a.c b/drivers/extcon/extcon-rt8973a.c
index 40c07f4d656e..e75c03792398 100644
--- a/drivers/extcon/extcon-rt8973a.c
+++ b/drivers/extcon/extcon-rt8973a.c
@@ -270,7 +270,7 @@ static int rt8973a_muic_get_cable_type(struct rt8973a_muic_info *info)
}
cable_type = adc & RT8973A_REG_ADC_MASK;
- /* Read Device 1 reigster to identify correct cable type */
+ /* Read Device 1 register to identify correct cable type */
ret = regmap_read(info->regmap, RT8973A_REG_DEV1, &dev1);
if (ret) {
dev_err(info->dev, "failed to read DEV1 register\n");
diff --git a/drivers/gpu/drm/arm/malidp_regs.h b/drivers/gpu/drm/arm/malidp_regs.h
index 993031542fa1..0d81b34a4212 100644
--- a/drivers/gpu/drm/arm/malidp_regs.h
+++ b/drivers/gpu/drm/arm/malidp_regs.h
@@ -145,7 +145,7 @@
#define MALIDP_SE_COEFFTAB_DATA_MASK 0x3fff
#define MALIDP_SE_SET_COEFFTAB_DATA(x) \
((x) & MALIDP_SE_COEFFTAB_DATA_MASK)
-/* Enhance coeffents reigster offset */
+/* Enhance coeffents register offset */
#define MALIDP_SE_IMAGE_ENH 0x3C
/* ENH_LIMITS offset 0x0 */
#define MALIDP_SE_ENH_LOW_LEVEL 24
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.h
index 99c6f7eefd85..d03c8f12a15c 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.h
@@ -58,7 +58,7 @@ struct fw_priv {
/* 0x81: PCI-AP, 01:PCIe, 02: 92S-U,
* 0x82: USB-AP, 0x12: 72S-U, 03:SDIO */
u8 hci_sel;
- /* the same value as reigster value */
+ /* the same value as register value */
u8 chip_version;
/* customer ID low byte */
u8 customer_id_0;
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 28ecaa7fc715..9e116bd79836 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -6551,7 +6551,7 @@ lpfc_sli4_unregister_fcf(struct lpfc_hba *phba)
* lpfc_unregister_fcf_rescan - Unregister currently registered fcf and rescan
* @phba: Pointer to hba context object.
*
- * This function unregisters the currently reigstered FCF. This function
+ * This function unregisters the currently registered FCF. This function
* also tries to find another FCF for discovery by rescan the HBA FCF table.
*/
void
@@ -6609,7 +6609,7 @@ lpfc_unregister_fcf_rescan(struct lpfc_hba *phba)
* lpfc_unregister_fcf - Unregister the currently registered fcf record
* @phba: Pointer to hba context object.
*
- * This function just unregisters the currently reigstered FCF. It does not
+ * This function just unregisters the currently registered FCF. It does not
* try to find another FCF for discovery.
*/
void
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
index ccbdbd62f0d8..612dc1240f90 100644
--- a/fs/userfaultfd.c
+++ b/fs/userfaultfd.c
@@ -267,7 +267,7 @@ static inline bool userfaultfd_huge_must_wait(struct userfaultfd_ctx *ctx,
#endif /* CONFIG_HUGETLB_PAGE */
/*
- * Verify the pagetables are still not ok after having reigstered into
+ * Verify the pagetables are still not ok after having registered into
* the fault_pending_wqh to avoid userland having to UFFDIO_WAKE any
* userfault that has already been resolved, if userfaultfd_read and
* UFFDIO_COPY|ZEROPAGE are being run simultaneously on two different
--
2.17.1
^ permalink raw reply related
* brcmfmac: Probing regression in Linux 5.3-rc1
From: Stefan Wahren @ 2019-07-27 15:17 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Chen-Yu Tsai
Cc: linux-arm-kernel, Arend van Spriel, Franky Lin, Hante Meuleman,
Chi-Hsien Lin, Wright Feng, linux-wireless@vger.kernel.org,
brcm80211-dev-list, Johannes Berg
In-Reply-To: <ab7af8537ebcbc7a7bdf04d2c06152ba6821b333.camel@suse.de>
Hi,
Am 24.07.19 um 10:37 schrieb Nicolas Saenz Julienne:
>>>> Does it fix the wifi issue too?
>>> Well it works as long as I revert this: 901bb98918 ("nl80211: require and
>>> validate vendor command policy"). Which has nothing to do with DMA anyways.
>>>
>>> Was this the issue you where seeing?
>>>
>>> [ 4.969679] WARNING: CPU: 2 PID: 21 at net/wireless/core.c:868
>>> wiphy_register+0x8e8/0xbdc [cfg80211]
>>> [...]
>>> [ 4.969974] ieee80211 phy0: brcmf_cfg80211_attach: Could not register
>>> wiphy device (-22)
>> We're seeing this on different platforms (allwinner / rockchip / amlogic)
>> with Broadcom WiFi chips. So it's unlikely to be related with anything in
>> this series.
>>
>> I believe a fix for this has already been queued up:
>>
>>
> https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git/commit/?id=91046d6364afde646734c7ead1f649d253c386e9
>
> Thanks for pointing it out, it fixes the issue alright.
>
i cannot confirm. I still need to revert Johannes' commit "nl80211:
require and validate vendor command policy" to get brcmfmac probing on
Raspberry Pi 3B+ and 4B.
The commit "nl80211: fix VENDOR_CMD_RAW_DATA" didn't fix the probing
issue (see warning above).
Regards
Stefan
^ permalink raw reply
* Re: [PATCH] cfg80211: use parallel_ops for genl
From: Denis Kenzior @ 2019-07-26 0:16 UTC (permalink / raw)
To: Johannes Berg, linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20190726191621.5031-1-johannes@sipsolutions.net>
Hi Johannes,
On 7/26/19 2:16 PM, Johannes Berg wrote:
> From: Johannes Berg <johannes.berg@intel.com>
>
> Over time, we really need to get rid of all of our global locking.
> One of the things needed is to use parallel_ops. This isn't really
> the most important (RTNL is much more important) but OTOH we just
> keep adding uses of genl_family_attrbuf() now. Use .parallel_ops to
> disallow this.
>
> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
> ---
> net/wireless/nl80211.c | 112 +++++++++++++++++++++++++++++------------
> 1 file changed, 81 insertions(+), 31 deletions(-)
>
> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
> index 10b57aa10227..59aefcd7ccb6 100644
> --- a/net/wireless/nl80211.c
> +++ b/net/wireless/nl80211.c
> @@ -749,19 +749,29 @@ int nl80211_prepare_wdev_dump(struct netlink_callback *cb,
> int err;
>
> if (!cb->args[0]) {
> + struct nlattr **attrbuf;
> +
> + attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf),
> + GFP_KERNEL);
> + if (!attrbuf)
> + return -ENOMEM;
> +
> err = nlmsg_parse_deprecated(cb->nlh,
> GENL_HDRLEN + nl80211_fam.hdrsize,
> - genl_family_attrbuf(&nl80211_fam),
> - nl80211_fam.maxattr,
> + attrbuf, nl80211_fam.maxattr,
> nl80211_policy, NULL);
> - if (err)
> + if (err) {
> + kfree(attrbuf);
> return err;
> + }
>
> - *wdev = __cfg80211_wdev_from_attrs(
> - sock_net(cb->skb->sk),
> - genl_family_attrbuf(&nl80211_fam));
> - if (IS_ERR(*wdev))
> + *wdev = __cfg80211_wdev_from_attrs(sock_net(cb->skb->sk),
> + attrbuf);
> + kfree(attrbuf);
> + if (IS_ERR(*wdev)) {
> + kfree(attrbuf);
Hmm, you just freed attrbuf above?
> return PTR_ERR(*wdev);
> + }
> *rdev = wiphy_to_rdev((*wdev)->wiphy);
> /* 0 is the first index - add 1 to parse only once */
> cb->args[0] = (*rdev)->wiphy_idx + 1;
<snip>
> @@ -12846,24 +12880,32 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
> return 0;
> }
>
> + attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf), GFP_KERNEL);
> + if (!attrbuf)
> + return -ENOMEM;
> +
> err = nlmsg_parse_deprecated(cb->nlh,
> GENL_HDRLEN + nl80211_fam.hdrsize,
> attrbuf, nl80211_fam.maxattr,
> nl80211_policy, NULL);
> if (err)
> - return err;
> + goto out;
>
> if (!attrbuf[NL80211_ATTR_VENDOR_ID] ||
> - !attrbuf[NL80211_ATTR_VENDOR_SUBCMD])
> - return -EINVAL;
> + !attrbuf[NL80211_ATTR_VENDOR_SUBCMD]) {
> + err = -EINVAL;
> + goto out;
> + }
Might be nicer to just set err = -EINVAL before the if instead of using
{} here
>
> *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk), attrbuf);
> if (IS_ERR(*wdev))
> *wdev = NULL;
>
> *rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
> - if (IS_ERR(*rdev))
> - return PTR_ERR(*rdev);
> + if (IS_ERR(*rdev)) {
> + err = PTR_ERR(*rdev);
> + goto out;
> + }
>
> vid = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_ID]);
> subcmd = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_SUBCMD]);
> @@ -12876,15 +12918,19 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
> if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
> continue;
>
> - if (!vcmd->dumpit)
> - return -EOPNOTSUPP;
> + if (!vcmd->dumpit) {
> + err = -EOPNOTSUPP;
> + goto out;
> + }
Same thing here, setting err = -EOPNOTSUPP before the for...
>
> vcmd_idx = i;
> break;
> }
>
> - if (vcmd_idx < 0)
> - return -EOPNOTSUPP;
> + if (vcmd_idx < 0) {
> + err = -EOPNOTSUPP;
> + goto out;
> + }
>
> if (attrbuf[NL80211_ATTR_VENDOR_DATA]) {
> data = nla_data(attrbuf[NL80211_ATTR_VENDOR_DATA]);
<snip>
Otherwise LGTM.
Feel free to add: Reviewed-by: Denis Kenzior <denkenz@gmail.com>
Regards,
-Denis
^ permalink raw reply
* Re: [PATCH] cfg80211: use parallel_ops for genl
From: Johannes Berg @ 2019-07-27 18:41 UTC (permalink / raw)
To: Denis Kenzior, linux-wireless
In-Reply-To: <fe8ef214-5d02-da36-2680-6df3c683c154@gmail.com>
Hi Denis,
(huh, why did your mail make it to my inbox 3 hours ago ...? oh well)
> > + kfree(attrbuf);
> > + if (IS_ERR(*wdev)) {
> > + kfree(attrbuf);
>
> Hmm, you just freed attrbuf above?
Good catch.
I was being stupid, wrote the patch on one machine, then tested & fixed
it on another, and then sent out the original ...
> > if (!attrbuf[NL80211_ATTR_VENDOR_ID] ||
> > - !attrbuf[NL80211_ATTR_VENDOR_SUBCMD])
> > - return -EINVAL;
> > + !attrbuf[NL80211_ATTR_VENDOR_SUBCMD]) {
> > + err = -EINVAL;
> > + goto out;
> > + }
>
> Might be nicer to just set err = -EINVAL before the if instead of using
> {} here
Dunno. I don't generally like the values "leaking" out of where they're
intended, tends to hide compiler warnings when you forget to assign or
something ... I guess doing -EINVAL at least would fail safely :-)
I'll revise this then.
johannes
^ permalink raw reply
* [PATCH] ath10k: use ath10k_pci_soc_ functions for all warm_reset instances
From: Tomislav Požega @ 2019-07-28 9:11 UTC (permalink / raw)
To: linux-wireless; +Cc: kvalo
Use ath10k_pci_soc_read32 / ath10k_pci_soc_write32 functions for
the rest of warm_reset functions. Until now these have been used
only for ath10k_pci_warm_reset_si0, but since they already exist
it makes sense to simplify code a bit.
Runtime tested with QCA9862.
Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
---
drivers/net/wireless/ath/ath10k/pci.c | 26 +++++++++++---------------
1 files changed, 11 insertions(+), 15 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index a0b4d26..bf16f17 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -2567,35 +2567,31 @@ static void ath10k_pci_warm_reset_cpu(struct ath10k *ar)
ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS, 0);
- val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS +
- SOC_RESET_CONTROL_ADDRESS);
- ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + SOC_RESET_CONTROL_ADDRESS,
- val | SOC_RESET_CONTROL_CPU_WARM_RST_MASK);
+ val = ath10k_pci_soc_read32(ar, SOC_RESET_CONTROL_ADDRESS);
+ ath10k_pci_soc_write32(ar, SOC_RESET_CONTROL_ADDRESS,
+ val | SOC_RESET_CONTROL_CPU_WARM_RST_MASK);
}
static void ath10k_pci_warm_reset_ce(struct ath10k *ar)
{
u32 val;
- val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS +
- SOC_RESET_CONTROL_ADDRESS);
+ val = ath10k_pci_soc_read32(ar, SOC_RESET_CONTROL_ADDRESS);
- ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + SOC_RESET_CONTROL_ADDRESS,
- val | SOC_RESET_CONTROL_CE_RST_MASK);
+ ath10k_pci_soc_write32(ar, SOC_RESET_CONTROL_ADDRESS,
+ val | SOC_RESET_CONTROL_CE_RST_MASK);
msleep(10);
- ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + SOC_RESET_CONTROL_ADDRESS,
- val & ~SOC_RESET_CONTROL_CE_RST_MASK);
+ ath10k_pci_soc_write32(ar, SOC_RESET_CONTROL_ADDRESS,
+ val & ~SOC_RESET_CONTROL_CE_RST_MASK);
}
static void ath10k_pci_warm_reset_clear_lf(struct ath10k *ar)
{
u32 val;
- val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS +
- SOC_LF_TIMER_CONTROL0_ADDRESS);
- ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS +
- SOC_LF_TIMER_CONTROL0_ADDRESS,
- val & ~SOC_LF_TIMER_CONTROL0_ENABLE_MASK);
+ val = ath10k_pci_soc_read32(ar, SOC_LF_TIMER_CONTROL0_ADDRESS);
+ ath10k_pci_soc_write32(ar, SOC_LF_TIMER_CONTROL0_ADDRESS,
+ val & ~SOC_LF_TIMER_CONTROL0_ENABLE_MASK);
}
static int ath10k_pci_warm_reset(struct ath10k *ar)
--
1.7.0.4
^ permalink raw reply related
* [PATCH net-next] rt2800usb: Add new rt2800usb device PLANEX GW-USMicroN
From: Masanari Iida @ 2019-07-28 14:07 UTC (permalink / raw)
To: sgruszka, helmut.schaa, kvalo, davem, linux-wireless, netdev,
linux-kernel
Cc: Masanari Iida
This patch add a device ID for PLANEX GW-USMicroN.
Without this patch, I had to echo the device IDs in order to
recognize the device.
# lsusb |grep PLANEX
Bus 002 Device 005: ID 2019:ed14 PLANEX GW-USMicroN
Signed-off-by: Masanari Iida <standby24x7@gmail.com>
---
drivers/net/wireless/ralink/rt2x00/rt2800usb.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
index fdf0504b5f1d..0dfb55c69b73 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
@@ -1086,6 +1086,7 @@ static const struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x0846, 0x9013) },
{ USB_DEVICE(0x0846, 0x9019) },
/* Planex */
+ { USB_DEVICE(0x2019, 0xed14) },
{ USB_DEVICE(0x2019, 0xed19) },
/* Ralink */
{ USB_DEVICE(0x148f, 0x3573) },
--
2.22.0.545.g9c9b961d7eb1
^ permalink raw reply related
* [PATCH 0/2] mt7615: add Smart Carrier Sense support
From: Lorenzo Bianconi @ 2019-07-28 19:03 UTC (permalink / raw)
To: nbd; +Cc: lorenzo.bianconi, linux-wireless, ryder.lee, royluo
Add Smart Carrier Sense (SCS) algorithm in order to tune device
sensitivity to track long-range clients and cut-off possible
interferences using RTS error rate and False CCA reported by the
radio
Lorenzo Bianconi (2):
mt76: mt7615: rework locking scheme for mt7615_set_channel
mt76: mt7615: add Smart Carrier Sense support
drivers/net/wireless/mediatek/mt76/mt76.h | 9 +-
.../wireless/mediatek/mt76/mt7615/debugfs.c | 39 ++++
.../net/wireless/mediatek/mt76/mt7615/init.c | 1 +
.../net/wireless/mediatek/mt76/mt7615/mac.c | 176 ++++++++++++++++++
.../net/wireless/mediatek/mt76/mt7615/main.c | 15 +-
.../wireless/mediatek/mt76/mt7615/mt7615.h | 14 ++
.../net/wireless/mediatek/mt76/mt7615/regs.h | 36 ++++
7 files changed, 281 insertions(+), 9 deletions(-)
--
2.21.0
^ permalink raw reply
* [PATCH 1/2] mt76: mt7615: rework locking scheme for mt7615_set_channel
From: Lorenzo Bianconi @ 2019-07-28 19:03 UTC (permalink / raw)
To: nbd; +Cc: lorenzo.bianconi, linux-wireless, ryder.lee, royluo
In-Reply-To: <cover.1564340063.git.lorenzo@kernel.org>
As already done for mt7603 driver, move mt76.mutex lock inside
mt7615_set_channel since we need to grab mt76.mutex in mt7615_mac_work.
This is a preliminary patch to add Smart Carrier Sense (SCS) support
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt7615/main.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
index 900253e85db9..9138153f4686 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
@@ -135,6 +135,8 @@ static int mt7615_set_channel(struct mt7615_dev *dev)
int ret;
cancel_delayed_work_sync(&dev->mt76.mac_work);
+
+ mutex_lock(&dev->mt76.mutex);
set_bit(MT76_RESET, &dev->mt76.state);
mt7615_dfs_check_channel(dev);
@@ -143,18 +145,18 @@ static int mt7615_set_channel(struct mt7615_dev *dev)
ret = mt7615_mcu_set_channel(dev);
if (ret)
- return ret;
+ goto out;
ret = mt7615_dfs_init_radar_detector(dev);
- if (ret < 0)
- return ret;
+out:
clear_bit(MT76_RESET, &dev->mt76.state);
+ mutex_unlock(&dev->mt76.mutex);
mt76_txq_schedule_all(&dev->mt76);
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
MT7615_WATCHDOG_TIME);
- return 0;
+ return ret;
}
static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
@@ -213,14 +215,14 @@ static int mt7615_config(struct ieee80211_hw *hw, u32 changed)
struct mt7615_dev *dev = hw->priv;
int ret = 0;
- mutex_lock(&dev->mt76.mutex);
-
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
ieee80211_stop_queues(hw);
ret = mt7615_set_channel(dev);
ieee80211_wake_queues(hw);
}
+ mutex_lock(&dev->mt76.mutex);
+
if (changed & IEEE80211_CONF_CHANGE_POWER)
ret = mt7615_mcu_set_tx_power(dev);
--
2.21.0
^ permalink raw reply related
* [PATCH 2/2] mt76: mt7615: add Smart Carrier Sense support
From: Lorenzo Bianconi @ 2019-07-28 19:03 UTC (permalink / raw)
To: nbd; +Cc: lorenzo.bianconi, linux-wireless, ryder.lee, royluo
In-Reply-To: <cover.1564340063.git.lorenzo@kernel.org>
Introduce Smart Carrier Sense support in order to tune device
sensitivity according to RTS error rate and False CCA reported by the
radio
Tested-by: Ryder Lee <ryder.lee@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
This patch relies on 'mt76: mt7615: fix MT7615_WATCHDOG_TIME definition'
https://patchwork.kernel.org/patch/11049597/
---
drivers/net/wireless/mediatek/mt76/mt76.h | 9 +-
.../wireless/mediatek/mt76/mt7615/debugfs.c | 39 ++++
.../net/wireless/mediatek/mt76/mt7615/init.c | 1 +
.../net/wireless/mediatek/mt76/mt7615/mac.c | 176 ++++++++++++++++++
.../net/wireless/mediatek/mt76/mt7615/main.c | 1 +
.../wireless/mediatek/mt76/mt7615/mt7615.h | 14 ++
.../net/wireless/mediatek/mt76/mt7615/regs.h | 36 ++++
7 files changed, 273 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 80664e8234bd..20f83e5b9337 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -27,9 +27,12 @@
#include <net/mac80211.h>
#include "util.h"
-#define MT_TX_RING_SIZE 256
-#define MT_MCU_RING_SIZE 32
-#define MT_RX_BUF_SIZE 2048
+#define MT_TX_RING_SIZE 256
+#define MT_MCU_RING_SIZE 32
+#define MT_RX_BUF_SIZE 2048
+
+#define MT_FRAC_SCALE 12
+#define MT_FRAC(val, div) (((val) << MT_FRAC_SCALE) / (div))
struct mt76_dev;
struct mt76_wcid;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c
index ed605fcc99f9..4dbaf5047b37 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c
@@ -13,6 +13,42 @@ mt7615_radar_pattern_set(void *data, u64 val)
DEFINE_DEBUGFS_ATTRIBUTE(fops_radar_pattern, NULL,
mt7615_radar_pattern_set, "%lld\n");
+static int
+mt7615_scs_set(void *data, u64 val)
+{
+ struct mt7615_dev *dev = data;
+
+ mt7615_mac_set_scs(dev, val);
+
+ return 0;
+}
+
+static int
+mt7615_scs_get(void *data, u64 *val)
+{
+ struct mt7615_dev *dev = data;
+
+ *val = dev->scs_en;
+
+ return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(fops_scs, mt7615_scs_get,
+ mt7615_scs_set, "%lld\n");
+
+static int
+mt7615_radio_read(struct seq_file *s, void *data)
+{
+ struct mt7615_dev *dev = dev_get_drvdata(s->private);
+
+ seq_printf(s, "Sensitivity: ofdm=%d cck=%d\n",
+ dev->ofdm_sensitivity, dev->cck_sensitivity);
+ seq_printf(s, "False CCA: ofdm=%d cck=%d\n",
+ dev->false_cca_ofdm, dev->false_cca_cck);
+
+ return 0;
+}
+
int mt7615_init_debugfs(struct mt7615_dev *dev)
{
struct dentry *dir;
@@ -21,6 +57,9 @@ int mt7615_init_debugfs(struct mt7615_dev *dev)
if (!dir)
return -ENOMEM;
+ debugfs_create_file("scs", 0600, dir, dev, &fops_scs);
+ debugfs_create_devm_seqfile(dev->mt76.dev, "radio", dir,
+ mt7615_radio_read);
debugfs_create_u32("dfs_hw_pattern", 0400, dir, &dev->hw_pattern);
/* test pattern knobs */
debugfs_create_u8("pattern_len", 0600, dir,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/init.c b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
index be144e13fe4c..1104e4c8aaa6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
@@ -50,6 +50,7 @@ static void mt7615_mac_init(struct mt7615_dev *dev)
MT_TMAC_CTCR0_INS_DDLMT_EN);
mt7615_mcu_set_rts_thresh(dev, 0x92b);
+ mt7615_mac_set_scs(dev, false);
mt76_rmw(dev, MT_AGG_SCR, MT_AGG_SCR_NLNAV_MID_PTEC_DIS,
MT_AGG_SCR_NLNAV_MID_PTEC_DIS);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
index 6b3e6931b380..1ab4a189e5eb 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
@@ -1068,6 +1068,175 @@ void mt7615_mac_tx_free(struct mt7615_dev *dev, struct sk_buff *skb)
dev_kfree_skb(skb);
}
+static void
+mt7615_mac_set_default_sensitivity(struct mt7615_dev *dev)
+{
+ mt76_rmw(dev, MT_WF_PHY_B0_MIN_PRI_PWR,
+ MT_WF_PHY_B0_PD_OFDM_MASK,
+ MT_WF_PHY_B0_PD_OFDM(0x13c));
+ mt76_rmw(dev, MT_WF_PHY_B1_MIN_PRI_PWR,
+ MT_WF_PHY_B1_PD_OFDM_MASK,
+ MT_WF_PHY_B1_PD_OFDM(0x13c));
+
+ mt76_rmw(dev, MT_WF_PHY_B0_RXTD_CCK_PD,
+ MT_WF_PHY_B0_PD_CCK_MASK,
+ MT_WF_PHY_B0_PD_CCK(0x92));
+ mt76_rmw(dev, MT_WF_PHY_B1_RXTD_CCK_PD,
+ MT_WF_PHY_B1_PD_CCK_MASK,
+ MT_WF_PHY_B1_PD_CCK(0x92));
+
+ dev->ofdm_sensitivity = -98;
+ dev->cck_sensitivity = -110;
+ dev->last_cca_adj = jiffies;
+}
+
+void mt7615_mac_set_scs(struct mt7615_dev *dev, bool enable)
+{
+ mutex_lock(&dev->mt76.mutex);
+
+ if (dev->scs_en == enable)
+ goto out;
+
+ if (enable) {
+ /* DBDC not supported */
+ mt76_set(dev, MT_WF_PHY_B0_MIN_PRI_PWR,
+ MT_WF_PHY_B0_PD_BLK);
+ if (is_mt7622(&dev->mt76)) {
+ mt76_set(dev, MT_MIB_M0_MISC_CR, 0x7 << 8);
+ mt76_set(dev, MT_MIB_M0_MISC_CR, 0x7);
+ }
+ } else {
+ mt76_clear(dev, MT_WF_PHY_B0_MIN_PRI_PWR,
+ MT_WF_PHY_B0_PD_BLK);
+ mt76_clear(dev, MT_WF_PHY_B1_MIN_PRI_PWR,
+ MT_WF_PHY_B1_PD_BLK);
+ }
+
+ mt7615_mac_set_default_sensitivity(dev);
+ dev->scs_en = enable;
+
+out:
+ mutex_unlock(&dev->mt76.mutex);
+}
+
+void mt7615_mac_cca_stats_reset(struct mt7615_dev *dev)
+{
+ mt76_clear(dev, MT_WF_PHY_R0_B0_PHYMUX_5, GENMASK(22, 20));
+ mt76_set(dev, MT_WF_PHY_R0_B0_PHYMUX_5, BIT(22) | BIT(20));
+}
+
+static void
+mt7615_mac_adjust_sensitivity(struct mt7615_dev *dev,
+ u32 rts_err_rate, bool ofdm)
+{
+ int false_cca = ofdm ? dev->false_cca_ofdm : dev->false_cca_cck;
+ u16 def_th = ofdm ? -98 : -110;
+ bool update = false;
+ s8 *sensitivity;
+ int signal;
+
+ sensitivity = ofdm ? &dev->ofdm_sensitivity : &dev->cck_sensitivity;
+ signal = mt76_get_min_avg_rssi(&dev->mt76);
+ if (!signal) {
+ mt7615_mac_set_default_sensitivity(dev);
+ return;
+ }
+
+ signal = min(signal, -72);
+ if (false_cca > 500) {
+ if (rts_err_rate > MT_FRAC(40, 100))
+ return;
+
+ /* decrease coverage */
+ if (*sensitivity == def_th && signal > -90) {
+ *sensitivity = -90;
+ update = true;
+ } else if (*sensitivity + 2 < signal) {
+ *sensitivity += 2;
+ update = true;
+ }
+ } else if ((false_cca > 0 && false_cca < 50) ||
+ rts_err_rate > MT_FRAC(60, 100)) {
+ /* increase coverage */
+ if (*sensitivity - 2 >= def_th) {
+ *sensitivity -= 2;
+ update = true;
+ }
+ }
+
+ if (*sensitivity > signal) {
+ *sensitivity = signal;
+ update = true;
+ }
+
+ if (update) {
+ u16 val;
+
+ if (ofdm) {
+ /* DBDC not supported */
+ val = *sensitivity * 2 + 512;
+ mt76_rmw(dev, MT_WF_PHY_B0_MIN_PRI_PWR,
+ MT_WF_PHY_B0_PD_OFDM_MASK,
+ MT_WF_PHY_B0_PD_OFDM(val));
+ } else {
+ val = *sensitivity + 256;
+ mt76_rmw(dev, MT_WF_PHY_B0_RXTD_CCK_PD,
+ MT_WF_PHY_B0_PD_CCK_MASK,
+ MT_WF_PHY_B0_PD_CCK(val));
+ mt76_rmw(dev, MT_WF_PHY_B1_RXTD_CCK_PD,
+ MT_WF_PHY_B1_PD_CCK_MASK,
+ MT_WF_PHY_B1_PD_CCK(val));
+ }
+ dev->last_cca_adj = jiffies;
+ }
+}
+
+static void
+mt7615_mac_scs_check(struct mt7615_dev *dev)
+{
+ u32 val, rts_cnt = 0, rts_retries_cnt = 0, rts_err_rate = 0;
+ u32 mdrdy_cck, mdrdy_ofdm, pd_cck, pd_ofdm;
+ int i;
+
+ if (!dev->scs_en)
+ return;
+
+ for (i = 0; i < 4; i++) {
+ u32 data;
+
+ val = mt76_rr(dev, MT_MIB_MB_SDR0(i));
+ data = FIELD_GET(MT_MIB_RTS_RETRIES_COUNT_MASK, val);
+ if (data > rts_retries_cnt) {
+ rts_cnt = FIELD_GET(MT_MIB_RTS_COUNT_MASK, val);
+ rts_retries_cnt = data;
+ }
+ }
+
+ val = mt76_rr(dev, MT_WF_PHY_R0_B0_PHYCTRL_STS0);
+ pd_cck = FIELD_GET(MT_WF_PHYCTRL_STAT_PD_CCK, val);
+ pd_ofdm = FIELD_GET(MT_WF_PHYCTRL_STAT_PD_OFDM, val);
+
+ val = mt76_rr(dev, MT_WF_PHY_R0_B0_PHYCTRL_STS5);
+ mdrdy_cck = FIELD_GET(MT_WF_PHYCTRL_STAT_MDRDY_CCK, val);
+ mdrdy_ofdm = FIELD_GET(MT_WF_PHYCTRL_STAT_MDRDY_OFDM, val);
+
+ dev->false_cca_ofdm = pd_ofdm - mdrdy_ofdm;
+ dev->false_cca_cck = pd_cck - mdrdy_cck;
+ mt7615_mac_cca_stats_reset(dev);
+
+ if (rts_cnt + rts_retries_cnt)
+ rts_err_rate = MT_FRAC(rts_retries_cnt,
+ rts_cnt + rts_retries_cnt);
+
+ /* cck */
+ mt7615_mac_adjust_sensitivity(dev, rts_err_rate, false);
+ /* ofdm */
+ mt7615_mac_adjust_sensitivity(dev, rts_err_rate, true);
+
+ if (time_after(jiffies, dev->last_cca_adj + 10 * HZ))
+ mt7615_mac_set_default_sensitivity(dev);
+}
+
void mt7615_mac_work(struct work_struct *work)
{
struct mt7615_dev *dev;
@@ -1075,6 +1244,13 @@ void mt7615_mac_work(struct work_struct *work)
dev = (struct mt7615_dev *)container_of(work, struct mt76_dev,
mac_work.work);
+ mutex_lock(&dev->mt76.mutex);
+ if (++dev->mac_work_count == 5) {
+ mt7615_mac_scs_check(dev);
+ dev->mac_work_count = 0;
+ }
+ mutex_unlock(&dev->mt76.mutex);
+
mt76_tx_status_check(&dev->mt76, NULL, false);
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
MT7615_WATCHDOG_TIME);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
index 9138153f4686..6b881e862595 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
@@ -148,6 +148,7 @@ static int mt7615_set_channel(struct mt7615_dev *dev)
goto out;
ret = mt7615_dfs_init_radar_detector(dev);
+ mt7615_mac_cca_stats_reset(dev);
out:
clear_bit(MT76_RESET, &dev->mt76.state);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
index a014f7b17825..c83d1d212ac9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
@@ -86,6 +86,13 @@ struct mt7615_dev {
u32 hw_pattern;
int dfs_state;
+ int false_cca_ofdm, false_cca_cck;
+ unsigned long last_cca_adj;
+ u8 mac_work_count;
+ s8 ofdm_sensitivity;
+ s8 cck_sensitivity;
+ bool scs_en;
+
spinlock_t token_lock;
struct idr token;
};
@@ -191,6 +198,11 @@ int mt7615_dfs_start_radar_detector(struct mt7615_dev *dev);
int mt7615_dfs_stop_radar_detector(struct mt7615_dev *dev);
int mt7615_mcu_rdd_send_pattern(struct mt7615_dev *dev);
+static inline bool is_mt7622(struct mt76_dev *dev)
+{
+ return mt76_chip(dev) == 0x7622;
+}
+
static inline void mt7615_dfs_check_channel(struct mt7615_dev *dev)
{
enum nl80211_chan_width width = dev->mt76.chandef.width;
@@ -212,6 +224,8 @@ static inline void mt7615_irq_disable(struct mt7615_dev *dev, u32 mask)
mt76_set_irq_mask(&dev->mt76, MT_INT_MASK_CSR, mask, 0);
}
+void mt7615_mac_cca_stats_reset(struct mt7615_dev *dev);
+void mt7615_mac_set_scs(struct mt7615_dev *dev, bool enable);
int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta, int pid,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/regs.h b/drivers/net/wireless/mediatek/mt76/mt7615/regs.h
index 1dcd202746ef..12fc12edf78c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/regs.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/regs.h
@@ -71,6 +71,34 @@
#define MT_WF_PHY_WF2_RFCTRL0 MT_WF_PHY(0x1900)
#define MT_WF_PHY_WF2_RFCTRL0_LPBCN_EN BIT(9)
+#define MT_WF_PHY_R0_B0_PHYMUX_5 MT_WF_PHY(0x0614)
+
+#define MT_WF_PHY_R0_B0_PHYCTRL_STS0 MT_WF_PHY(0x020c)
+#define MT_WF_PHYCTRL_STAT_PD_OFDM GENMASK(31, 16)
+#define MT_WF_PHYCTRL_STAT_PD_CCK GENMASK(15, 0)
+
+#define MT_WF_PHY_R0_B0_PHYCTRL_STS5 MT_WF_PHY(0x0220)
+#define MT_WF_PHYCTRL_STAT_MDRDY_OFDM GENMASK(31, 16)
+#define MT_WF_PHYCTRL_STAT_MDRDY_CCK GENMASK(15, 0)
+
+#define MT_WF_PHY_B0_MIN_PRI_PWR MT_WF_PHY(0x229c)
+#define MT_WF_PHY_B0_PD_OFDM_MASK GENMASK(28, 20)
+#define MT_WF_PHY_B0_PD_OFDM(v) ((v) << 20)
+#define MT_WF_PHY_B0_PD_BLK BIT(19)
+
+#define MT_WF_PHY_B1_MIN_PRI_PWR MT_WF_PHY(0x084)
+#define MT_WF_PHY_B1_PD_OFDM_MASK GENMASK(24, 16)
+#define MT_WF_PHY_B1_PD_OFDM(v) ((v) << 16)
+#define MT_WF_PHY_B1_PD_BLK BIT(25)
+
+#define MT_WF_PHY_B0_RXTD_CCK_PD MT_WF_PHY(0x2310)
+#define MT_WF_PHY_B0_PD_CCK_MASK GENMASK(8, 1)
+#define MT_WF_PHY_B0_PD_CCK(v) ((v) << 1)
+
+#define MT_WF_PHY_B1_RXTD_CCK_PD MT_WF_PHY(0x2314)
+#define MT_WF_PHY_B1_PD_CCK_MASK GENMASK(31, 24)
+#define MT_WF_PHY_B1_PD_CCK(v) ((v) << 24)
+
#define MT_WF_CFG_BASE 0x20200
#define MT_WF_CFG(ofs) (MT_WF_CFG_BASE + (ofs))
@@ -219,6 +247,14 @@
#define MT_LPON_UTTR0 MT_LPON(0x018)
#define MT_LPON_UTTR1 MT_LPON(0x01c)
+#define MT_WF_MIB_BASE 0x24800
+#define MT_WF_MIB(ofs) (MT_WF_MIB_BASE + (ofs))
+
+#define MT_MIB_M0_MISC_CR MT_WF_MIB(0x00c)
+#define MT_MIB_MB_SDR0(n) MT_WF_MIB(0x100 + ((n) << 4))
+#define MT_MIB_RTS_RETRIES_COUNT_MASK GENMASK(31, 16)
+#define MT_MIB_RTS_COUNT_MASK GENMASK(15, 0)
+
#define MT_EFUSE_BASE 0x81070000
#define MT_EFUSE_BASE_CTRL 0x000
#define MT_EFUSE_BASE_CTRL_EMPTY BIT(30)
--
2.21.0
^ permalink raw reply related
* [PATCH] ath6kl: Fix a possible null-pointer dereference in ath6kl_htc_mbox_create()
From: Jia-Ju Bai @ 2019-07-29 3:03 UTC (permalink / raw)
To: kvalo, davem; +Cc: linux-wireless, netdev, linux-kernel, Jia-Ju Bai
In ath6kl_htc_mbox_create(), when kzalloc() on line 2855 fails,
target->dev is assigned to NULL, and ath6kl_htc_mbox_cleanup(target) is
called on line 2885.
In ath6kl_htc_mbox_cleanup(), target->dev is used on line 2895:
ath6kl_hif_cleanup_scatter(target->dev->ar);
Thus, a null-pointer dereference may occur.
To fix this bug, kfree(target) is called and NULL is returned when
kzalloc() on line 2855 fails.
This bug is found by a static analysis tool STCheck written by us.
Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com>
---
drivers/net/wireless/ath/ath6kl/htc_mbox.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath6kl/htc_mbox.c b/drivers/net/wireless/ath/ath6kl/htc_mbox.c
index 65c31da43c47..998947ef63b6 100644
--- a/drivers/net/wireless/ath/ath6kl/htc_mbox.c
+++ b/drivers/net/wireless/ath/ath6kl/htc_mbox.c
@@ -2855,8 +2855,8 @@ static void *ath6kl_htc_mbox_create(struct ath6kl *ar)
target->dev = kzalloc(sizeof(*target->dev), GFP_KERNEL);
if (!target->dev) {
ath6kl_err("unable to allocate memory\n");
- status = -ENOMEM;
- goto err_htc_cleanup;
+ kfree(target);
+ return NULL;
}
spin_lock_init(&target->htc_lock);
--
2.17.0
^ permalink raw reply related
* Re: brcmfmac: Probing regression in Linux 5.3-rc1
From: Stefan Wahren @ 2019-07-29 5:44 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Chen-Yu Tsai
Cc: linux-arm-kernel, Arend van Spriel, Franky Lin, Hante Meuleman,
Chi-Hsien Lin, Wright Feng, linux-wireless@vger.kernel.org,
brcm80211-dev-list, Johannes Berg
In-Reply-To: <3daef629-8baf-3c5c-16a4-73d67604d1e5@gmx.net>
Hi,
Am 27.07.19 um 17:17 schrieb Stefan Wahren:
> Hi,
>
> Am 24.07.19 um 10:37 schrieb Nicolas Saenz Julienne:
>>>>> Does it fix the wifi issue too?
>>>> Well it works as long as I revert this: 901bb98918 ("nl80211: require and
>>>> validate vendor command policy"). Which has nothing to do with DMA anyways.
>>>>
>>>> Was this the issue you where seeing?
>>>>
>>>> [ 4.969679] WARNING: CPU: 2 PID: 21 at net/wireless/core.c:868
>>>> wiphy_register+0x8e8/0xbdc [cfg80211]
>>>> [...]
>>>> [ 4.969974] ieee80211 phy0: brcmf_cfg80211_attach: Could not register
>>>> wiphy device (-22)
>>> We're seeing this on different platforms (allwinner / rockchip / amlogic)
>>> with Broadcom WiFi chips. So it's unlikely to be related with anything in
>>> this series.
>>>
>>> I believe a fix for this has already been queued up:
>>>
>>>
>> https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git/commit/?id=91046d6364afde646734c7ead1f649d253c386e9
>>
>> Thanks for pointing it out, it fixes the issue alright.
>>
> i cannot confirm. I still need to revert Johannes' commit "nl80211:
> require and validate vendor command policy" to get brcmfmac probing on
> Raspberry Pi 3B+ and 4B.
>
> The commit "nl80211: fix VENDOR_CMD_RAW_DATA" didn't fix the probing
> issue (see warning above).
i rebased my series on top of Linux 5.3-rc2 and issue disappeared. I
assume the commit "wireless: fix nl80211 vendor commands" is also required.
Sorry, for the noise.
>
> Regards
> Stefan
>
>
^ permalink raw reply
* [PATCH] cfg80211: fix dfs channels remain DFS_AVAILABLE after ch_switch
From: Michael Vassernis @ 2019-07-29 6:01 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org, Michael Vassernis
Depending on the regulatory domain, leaving a DFS channel requires
a new CAC to be performed when returning back to that channel.
If needed, update dfs states after a driver channel switch.
Signed-off-by: Michael Vassernis <michael.vassernis@tandemg.com>
---
net/wireless/nl80211.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index fc83dd179c1a..b8c51750ff32 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -16094,6 +16094,8 @@ void cfg80211_ch_switch_notify(struct net_device *dev,
!WARN_ON(!wdev->current_bss))
wdev->current_bss->pub.channel = chandef->chan;
+ cfg80211_sched_dfs_chan_update(rdev);
+
nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
NL80211_CMD_CH_SWITCH_NOTIFY, 0);
}
--
2.17.1
^ permalink raw reply related
* Re: [PATCH net-next] rt2800usb: Add new rt2800usb device PLANEX GW-USMicroN
From: Stanislaw Gruszka @ 2019-07-29 6:46 UTC (permalink / raw)
To: Masanari Iida
Cc: helmut.schaa, kvalo, davem, linux-wireless, netdev, linux-kernel
In-Reply-To: <20190728140742.3280-1-standby24x7@gmail.com>
On Sun, Jul 28, 2019 at 11:07:42PM +0900, Masanari Iida wrote:
> This patch add a device ID for PLANEX GW-USMicroN.
> Without this patch, I had to echo the device IDs in order to
> recognize the device.
>
> # lsusb |grep PLANEX
> Bus 002 Device 005: ID 2019:ed14 PLANEX GW-USMicroN
>
> Signed-off-by: Masanari Iida <standby24x7@gmail.com>
Acked-by: Stanislaw Gruszka <sgruszka@redhat.com>
^ permalink raw reply
* Re: [PATCH v2 5/5] rtw88: add BT co-existence support
From: Stanislaw Gruszka @ 2019-07-29 8:12 UTC (permalink / raw)
To: yhchuang; +Cc: kvalo, linux-wireless, briannorris
In-Reply-To: <1564023211-3138-6-git-send-email-yhchuang@realtek.com>
On Thu, Jul 25, 2019 at 10:53:31AM +0800, yhchuang@realtek.com wrote:
> +static struct sk_buff *rtw_coex_info_request(struct rtw_dev *rtwdev,
> + struct rtw_coex_info_req *req)
> +{
> + struct rtw_coex *coex = &rtwdev->coex;
> + struct sk_buff *skb_resp = NULL;
> +
> + mutex_lock(&coex->mutex);
> +
> + rtw_fw_query_bt_mp_info(rtwdev, req);
> +
> + if (!wait_event_timeout(coex->wait, !skb_queue_empty(&coex->queue),
> + COEX_REQUEST_TIMEOUT)) {
> + rtw_err(rtwdev, "coex request time out\n");
> + goto out;
> + }
> +
> + skb_resp = skb_dequeue(&coex->queue);
> + if (!skb_resp) {
> + rtw_err(rtwdev, "failed to get coex info response\n");
> + goto out;
> + }
> +
> +out:
> + mutex_unlock(&coex->mutex);
> + return skb_resp;
> +}
> +
> +static bool rtw_coex_get_bt_scan_type(struct rtw_dev *rtwdev, u8 *scan_type)
> +{
> + struct rtw_coex_info_req req = {0};
> + struct sk_buff *skb;
> + u8 *payload;
> + bool ret = false;
> +
> + req.op_code = BT_MP_INFO_OP_SCAN_TYPE;
> + skb = rtw_coex_info_request(rtwdev, &req);
> + if (!skb)
> + goto out;
> +
> + payload = get_payload_from_coex_resp(skb);
> + *scan_type = GET_COEX_RESP_BT_SCAN_TYPE(payload);
> + ret = true;
> +
> +out:
> + return ret;
> +}
> +
> +static bool rtw_coex_set_lna_constrain_level(struct rtw_dev *rtwdev,
> + u8 lna_constrain_level)
> +{
> + struct rtw_coex_info_req req = {0};
> + struct sk_buff *skb;
> + bool ret = false;
> +
> + req.op_code = BT_MP_INFO_OP_LNA_CONSTRAINT;
> + req.para1 = lna_constrain_level;
> + skb = rtw_coex_info_request(rtwdev, &req);
> + if (!skb)
> + goto out;
Those coex response skb buffers are allocated in rtw_pci_rx_isr(),
but I do not see where they are freed (seems we do not process
them in c2h_work which does dev_kfree_skb()).
Stanislaw
^ permalink raw reply
* [PATCH] mac80211_hwsim: Fix possible null-pointer dereferences in hwsim_dump_radio_nl()
From: Jia-Ju Bai @ 2019-07-29 8:23 UTC (permalink / raw)
To: johannes, kvalo, davem; +Cc: linux-wireless, netdev, linux-kernel, Jia-Ju Bai
In hwsim_dump_radio_nl(), when genlmsg_put() on line 3617 fails, hdr is
assigned to NULL. Then hdr is used on lines 3622 and 3623:
genl_dump_check_consistent(cb, hdr);
genlmsg_end(skb, hdr);
Thus, possible null-pointer dereferences may occur.
To fix these bugs, hdr is used here when it is not NULL.
This bug is found by a static analysis tool STCheck written by us.
Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com>
---
drivers/net/wireless/mac80211_hwsim.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 519b4ee88c5c..61a8b6429e09 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -3617,10 +3617,11 @@ static int hwsim_dump_radio_nl(struct sk_buff *skb,
hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, &hwsim_genl_family,
NLM_F_MULTI, HWSIM_CMD_GET_RADIO);
- if (!hdr)
+ if (hdr) {
+ genl_dump_check_consistent(cb, hdr);
+ genlmsg_end(skb, hdr);
+ } else
res = -EMSGSIZE;
- genl_dump_check_consistent(cb, hdr);
- genlmsg_end(skb, hdr);
}
done:
--
2.17.0
^ permalink raw reply related
* ath10k: Fix channel info parsing for non tlv target
From: Lukas Redlinger @ 2019-07-29 9:13 UTC (permalink / raw)
To: linux-wireless
My x86_64 system with Arch Linux 5.2.2 and a Compex WLE600VX card is
filling the log with "ath10k_pci 0000:01:00.0: failed to parse chan
info event: -71".
WiFi in general works, but wavemon is struggling as some packets seem
to be incomplete.
This seems to be the fix: https://patchwork.kernel.org/patch/10844513/
How/when will i get mainline? Can I speed up the process somehow?
Thanks,
Lukas
^ permalink raw reply
* Re: [PATCH] Fix typo reigster to register
From: Liviu Dudau @ 2019-07-29 9:38 UTC (permalink / raw)
To: Pei Hsuan Hung
Cc: trivial, Russell Currey, Sam Bobroff, Oliver O'Halloran,
Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
Jeremy Kerr, Arnd Bergmann, MyungJoo Ham, Chanwoo Choi,
Brian Starkey, David Airlie, Daniel Vetter, Ping-Ke Shih,
Kalle Valo, David S. Miller, James Smart, Dick Kennedy,
James E.J. Bottomley, Martin K. Petersen, Alexander Viro,
Larry Finger, linuxppc-dev, linux-kernel, dri-devel,
linux-wireless, netdev, linux-scsi, linux-fsdevel
In-Reply-To: <20190727142111.20039-1-afcidk@gmail.com>
Hi Pei,
On Sat, Jul 27, 2019 at 10:21:09PM +0800, Pei Hsuan Hung wrote:
> Signed-off-by: Pei Hsuan Hung <afcidk@gmail.com>
> Cc: trivial@kernel.org
> ---
> arch/powerpc/kernel/eeh.c | 2 +-
> arch/powerpc/platforms/cell/spufs/switch.c | 4 ++--
> drivers/extcon/extcon-rt8973a.c | 2 +-
> drivers/gpu/drm/arm/malidp_regs.h | 2 +-
> drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.h | 2 +-
> drivers/scsi/lpfc/lpfc_hbadisc.c | 4 ++--
> fs/userfaultfd.c | 2 +-
> 7 files changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
> index c0e4b73191f3..d75c9c24ec4d 100644
> --- a/arch/powerpc/kernel/eeh.c
> +++ b/arch/powerpc/kernel/eeh.c
> @@ -1030,7 +1030,7 @@ int __init eeh_ops_register(struct eeh_ops *ops)
> }
>
> /**
> - * eeh_ops_unregister - Unreigster platform dependent EEH operations
> + * eeh_ops_unregister - Unregister platform dependent EEH operations
> * @name: name of EEH platform operations
> *
> * Unregister the platform dependent EEH operation callback
> diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c
> index 5c3f5d088c3b..9548a086937b 100644
> --- a/arch/powerpc/platforms/cell/spufs/switch.c
> +++ b/arch/powerpc/platforms/cell/spufs/switch.c
> @@ -574,7 +574,7 @@ static inline void save_mfc_rag(struct spu_state *csa, struct spu *spu)
> {
> /* Save, Step 38:
> * Save RA_GROUP_ID register and the
> - * RA_ENABLE reigster in the CSA.
> + * RA_ENABLE register in the CSA.
> */
> csa->priv1.resource_allocation_groupID_RW =
> spu_resource_allocation_groupID_get(spu);
> @@ -1227,7 +1227,7 @@ static inline void restore_mfc_rag(struct spu_state *csa, struct spu *spu)
> {
> /* Restore, Step 29:
> * Restore RA_GROUP_ID register and the
> - * RA_ENABLE reigster from the CSA.
> + * RA_ENABLE register from the CSA.
> */
> spu_resource_allocation_groupID_set(spu,
> csa->priv1.resource_allocation_groupID_RW);
> diff --git a/drivers/extcon/extcon-rt8973a.c b/drivers/extcon/extcon-rt8973a.c
> index 40c07f4d656e..e75c03792398 100644
> --- a/drivers/extcon/extcon-rt8973a.c
> +++ b/drivers/extcon/extcon-rt8973a.c
> @@ -270,7 +270,7 @@ static int rt8973a_muic_get_cable_type(struct rt8973a_muic_info *info)
> }
> cable_type = adc & RT8973A_REG_ADC_MASK;
>
> - /* Read Device 1 reigster to identify correct cable type */
> + /* Read Device 1 register to identify correct cable type */
> ret = regmap_read(info->regmap, RT8973A_REG_DEV1, &dev1);
> if (ret) {
> dev_err(info->dev, "failed to read DEV1 register\n");
> diff --git a/drivers/gpu/drm/arm/malidp_regs.h b/drivers/gpu/drm/arm/malidp_regs.h
> index 993031542fa1..0d81b34a4212 100644
> --- a/drivers/gpu/drm/arm/malidp_regs.h
> +++ b/drivers/gpu/drm/arm/malidp_regs.h
> @@ -145,7 +145,7 @@
> #define MALIDP_SE_COEFFTAB_DATA_MASK 0x3fff
> #define MALIDP_SE_SET_COEFFTAB_DATA(x) \
> ((x) & MALIDP_SE_COEFFTAB_DATA_MASK)
> -/* Enhance coeffents reigster offset */
> +/* Enhance coeffents register offset */
Unless this patch was generated by a script I think it is worth correcting the
other spelling mistake on that line as well: coefficients rather than coeffents.
With that: Acked-by: Liviu Dudau <liviu.dudau@arm.com>
Best regards,
Liviu
> #define MALIDP_SE_IMAGE_ENH 0x3C
> /* ENH_LIMITS offset 0x0 */
> #define MALIDP_SE_ENH_LOW_LEVEL 24
> diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.h
> index 99c6f7eefd85..d03c8f12a15c 100644
> --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.h
> +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.h
> @@ -58,7 +58,7 @@ struct fw_priv {
> /* 0x81: PCI-AP, 01:PCIe, 02: 92S-U,
> * 0x82: USB-AP, 0x12: 72S-U, 03:SDIO */
> u8 hci_sel;
> - /* the same value as reigster value */
> + /* the same value as register value */
> u8 chip_version;
> /* customer ID low byte */
> u8 customer_id_0;
> diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
> index 28ecaa7fc715..9e116bd79836 100644
> --- a/drivers/scsi/lpfc/lpfc_hbadisc.c
> +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
> @@ -6551,7 +6551,7 @@ lpfc_sli4_unregister_fcf(struct lpfc_hba *phba)
> * lpfc_unregister_fcf_rescan - Unregister currently registered fcf and rescan
> * @phba: Pointer to hba context object.
> *
> - * This function unregisters the currently reigstered FCF. This function
> + * This function unregisters the currently registered FCF. This function
> * also tries to find another FCF for discovery by rescan the HBA FCF table.
> */
> void
> @@ -6609,7 +6609,7 @@ lpfc_unregister_fcf_rescan(struct lpfc_hba *phba)
> * lpfc_unregister_fcf - Unregister the currently registered fcf record
> * @phba: Pointer to hba context object.
> *
> - * This function just unregisters the currently reigstered FCF. It does not
> + * This function just unregisters the currently registered FCF. It does not
> * try to find another FCF for discovery.
> */
> void
> diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
> index ccbdbd62f0d8..612dc1240f90 100644
> --- a/fs/userfaultfd.c
> +++ b/fs/userfaultfd.c
> @@ -267,7 +267,7 @@ static inline bool userfaultfd_huge_must_wait(struct userfaultfd_ctx *ctx,
> #endif /* CONFIG_HUGETLB_PAGE */
>
> /*
> - * Verify the pagetables are still not ok after having reigstered into
> + * Verify the pagetables are still not ok after having registered into
> * the fault_pending_wqh to avoid userland having to UFFDIO_WAKE any
> * userfault that has already been resolved, if userfaultfd_read and
> * UFFDIO_COPY|ZEROPAGE are being run simultaneously on two different
> --
> 2.17.1
>
--
====================
| I would like to |
| fix the world, |
| but they're not |
| giving me the |
\ source code! /
---------------
¯\_(ツ)_/¯
^ permalink raw reply
* [PATCH] brcm80211: Avoid possible null-pointer dereferences in wlc_phy_radio_init_2056()
From: Jia-Ju Bai @ 2019-07-29 9:56 UTC (permalink / raw)
To: arend.vanspriel, franky.lin, hante.meuleman, chi-hsien.lin,
wright.feng, kvalo, davem, pieter-paul.giesberts, plaes,
rvarsha016
Cc: linux-wireless, brcm80211-dev-list.pdl, brcm80211-dev-list,
netdev, linux-kernel, Jia-Ju Bai
In wlc_phy_radio_init_2056(), regs_SYN_2056_ptr, regs_TX_2056_ptr and
regs_RX_2056_ptr may be not assigned, and thus they are still NULL.
Then, they are used on lines 20042-20050:
wlc_phy_init_radio_regs(pi, regs_SYN_2056_ptr, (u16) RADIO_2056_SYN);
wlc_phy_init_radio_regs(pi, regs_TX_2056_ptr, (u16) RADIO_2056_TX0);
wlc_phy_init_radio_regs(pi, regs_TX_2056_ptr, (u16) RADIO_2056_TX1);
wlc_phy_init_radio_regs(pi, regs_RX_2056_ptr, (u16) RADIO_2056_RX0);
wlc_phy_init_radio_regs(pi, regs_RX_2056_ptr, (u16) RADIO_2056_RX1);
Thus, possible null-pointer dereferences may occur.
To avoid these bugs, when these variables are not assigned,
wlc_phy_radio_init_2056() directly returns.
Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
index 07f61d6155ea..0c57d48f47b1 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
@@ -20035,7 +20035,7 @@ static void wlc_phy_radio_init_2056(struct brcms_phy *pi)
break;
default:
- break;
+ return;
}
}
--
2.17.0
^ permalink raw reply related
* [PATCH V6 1/2] mac80211: fix ieee80211_he_oper_size() comment
From: John Crispin @ 2019-07-29 10:23 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, John Crispin, Kalle Valo
Johannes mentioned that the comment should not reference mac80211 as other
subsystems might call the helper.
Signed-off-by: John Crispin <john@phrozen.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
include/linux/ieee80211.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index a656f31262f1..9c81895c63c1 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -2053,8 +2053,8 @@ ieee80211_he_ppe_size(u8 ppe_thres_hdr, const u8 *phy_cap_info)
* ieee80211_he_oper_size - calculate 802.11ax HE Operations IE size
* @he_oper_ie: byte data of the He Operations IE, stating from the the byte
* after the ext ID byte. It is assumed that he_oper_ie has at least
- * sizeof(struct ieee80211_he_operation) bytes, checked already in
- * ieee802_11_parse_elems_crc()
+ * sizeof(struct ieee80211_he_operation) bytes, the caller must have
+ * validated this.
* @return the actual size of the IE data (not including header), or 0 on error
*/
static inline u8
--
2.20.1
^ permalink raw reply related
* [PATCH V6 2/2] mac80211: propagate HE operation info into bss_conf
From: John Crispin @ 2019-07-29 10:23 UTC (permalink / raw)
To: Johannes Berg
Cc: linux-wireless, John Crispin, Shashidhar Lakkavalli, Kalle Valo
In-Reply-To: <20190729102342.8659-1-john@phrozen.org>
Upon a successful assoc a station shall store the content of the HE
operation element inside bss_conf so that the driver can setup the
hardware accordingly.
Signed-off-by: Shashidhar Lakkavalli <slakkavalli@datto.com>
Signed-off-by: John Crispin <john@phrozen.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
include/net/mac80211.h | 2 ++
net/mac80211/he.c | 14 ++++++++++++++
net/mac80211/ieee80211_i.h | 4 ++++
net/mac80211/mlme.c | 1 +
4 files changed, 21 insertions(+)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 9effd286c1ae..bd91388797fc 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -600,6 +600,7 @@ struct ieee80211_ftm_responder_params {
* nontransmitted BSSIDs
* @profile_periodicity: the least number of beacon frames need to be received
* in order to discover all the nontransmitted BSSIDs in the set.
+ * @he_operation: HE operation information of the AP we are connected to
*/
struct ieee80211_bss_conf {
const u8 *bssid;
@@ -661,6 +662,7 @@ struct ieee80211_bss_conf {
u8 bssid_indicator;
bool ema_ap;
u8 profile_periodicity;
+ struct ieee80211_he_operation he_operation;
};
/**
diff --git a/net/mac80211/he.c b/net/mac80211/he.c
index 219650591c79..5d3aa9c65fdf 100644
--- a/net/mac80211/he.c
+++ b/net/mac80211/he.c
@@ -50,3 +50,17 @@ ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,
he_cap->has_he = true;
}
+
+void
+ieee80211_he_op_ie_to_bss_conf(struct ieee80211_vif *vif,
+ const struct ieee80211_he_operation *he_op_ie_elem)
+{
+ struct ieee80211_he_operation *he_operation =
+ &vif->bss_conf.he_operation;
+
+ if (!he_op_ie_elem) {
+ memset(he_operation, 0, sizeof(*he_operation));
+ return;
+ }
+ memcpy(he_operation, he_op_ie_elem, sizeof(*he_operation));
+}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index a5818ff0e2a4..ba1bc245678e 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1873,6 +1873,10 @@ ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,
const u8 *he_cap_ie, u8 he_cap_len,
struct sta_info *sta);
+void
+ieee80211_he_op_ie_to_bss_conf(struct ieee80211_vif *vif,
+ const struct ieee80211_he_operation *he_op_ie_elem);
+
/* Spectrum management */
void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt,
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index a99ad0325309..2b8a7428973d 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3381,6 +3381,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
if (elems.uora_element)
bss_conf->uora_ocw_range = elems.uora_element[0];
+ ieee80211_he_op_ie_to_bss_conf(&sdata->vif, elems.he_operation);
/* TODO: OPEN: what happens if BSS color disable is set? */
}
--
2.20.1
^ permalink raw reply related
* [PATCH V2] mac80211: add support for the ADDBA extension element
From: John Crispin @ 2019-07-29 10:45 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, John Crispin, Shashidhar Lakkavalli
HE allows peers to negotiate the aggregation fragmentation level to be used
during transmission. The level can be 1-3. The Ext element is added behind
the ADDBA request inside the action frame. The responder will then reply
with the same level or a lower one if the requested one is not supported.
This patch only handles the negotiation part as the ADDBA frames get passed
to the ATH11k firmware, which does the rest of the magic for us aswell as
generating the requests.
Signed-off-by: Shashidhar Lakkavalli <slakkavalli@datto.com>
Signed-off-by: John Crispin <john@phrozen.org>
---
Changes in V2
* make use of bitfield.h
include/linux/ieee80211.h | 2 ++
net/mac80211/agg-rx.c | 70 +++++++++++++++++++++++++++++++++-----
net/mac80211/ht.c | 2 +-
net/mac80211/ieee80211_i.h | 3 +-
4 files changed, 66 insertions(+), 11 deletions(-)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 9c81895c63c1..7d3f2ced92d1 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -981,6 +981,8 @@ struct ieee80211_mgmt {
__le16 capab;
__le16 timeout;
__le16 start_seq_num;
+ /* followed by BA Extension */
+ u8 variable[0];
} __packed addba_req;
struct{
u8 action_code;
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 01b0dad24500..0e1bb43973b8 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -178,17 +178,52 @@ static void sta_rx_agg_reorder_timer_expired(struct timer_list *t)
rcu_read_unlock();
}
-static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid,
+static void ieee80211_add_addbaext(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb,
+ const struct ieee80211_addba_ext_ie *req)
+{
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_addba_ext_ie *resp;
+ const struct ieee80211_sta_he_cap *he_cap;
+ u8 frag_level, cap_frag_level;
+ u8 *pos;
+
+ sband = ieee80211_get_sband(sdata);
+ he_cap = ieee80211_get_he_iftype_cap(sband, sdata->vif.type);
+ if (!he_cap)
+ return;
+
+ pos = skb_put_zero(skb, 2 + sizeof(struct ieee80211_addba_ext_ie));
+ *pos++ = WLAN_EID_ADDBA_EXT;
+ *pos++ = sizeof(struct ieee80211_addba_ext_ie);
+ resp = (struct ieee80211_addba_ext_ie *)pos;
+ resp->data = req->data & IEEE80211_ADDBA_EXT_NO_FRAG;
+
+ frag_level = u32_get_bits(req->data,
+ IEEE80211_ADDBA_EXT_FRAG_LEVEL_MASK);
+ cap_frag_level = u32_get_bits(he_cap->he_cap_elem.mac_cap_info[0],
+ IEEE80211_HE_MAC_CAP0_DYNAMIC_FRAG_MASK);
+ if (frag_level > cap_frag_level)
+ frag_level = cap_frag_level;
+ resp->data |= u8_encode_bits(frag_level,
+ IEEE80211_ADDBA_EXT_FRAG_LEVEL_MASK);
+}
+
+static void ieee80211_send_addba_resp(struct sta_info *sta, u8 *da, u16 tid,
u8 dialog_token, u16 status, u16 policy,
- u16 buf_size, u16 timeout)
+ u16 buf_size, u16 timeout,
+ const struct ieee80211_addba_ext_ie *addbaext)
{
+ struct ieee80211_sub_if_data *sdata = sta->sdata;
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb;
struct ieee80211_mgmt *mgmt;
bool amsdu = ieee80211_hw_check(&local->hw, SUPPORTS_AMSDU_IN_AMPDU);
u16 capab;
- skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
+ skb = dev_alloc_skb(sizeof(*mgmt) +
+ 2 + sizeof(struct ieee80211_addba_ext_ie) +
+ local->hw.extra_tx_headroom);
if (!skb)
return;
@@ -222,13 +257,17 @@ static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *d
mgmt->u.action.u.addba_resp.timeout = cpu_to_le16(timeout);
mgmt->u.action.u.addba_resp.status = cpu_to_le16(status);
+ if (sta->sta.he_cap.has_he && addbaext)
+ ieee80211_add_addbaext(sdata, skb, addbaext);
+
ieee80211_tx_skb(sdata, skb);
}
void ___ieee80211_start_rx_ba_session(struct sta_info *sta,
u8 dialog_token, u16 timeout,
u16 start_seq_num, u16 ba_policy, u16 tid,
- u16 buf_size, bool tx, bool auto_seq)
+ u16 buf_size, bool tx, bool auto_seq,
+ const struct ieee80211_addba_ext_ie *addbaext)
{
struct ieee80211_local *local = sta->sdata->local;
struct tid_ampdu_rx *tid_agg_rx;
@@ -410,21 +449,22 @@ void ___ieee80211_start_rx_ba_session(struct sta_info *sta,
}
if (tx)
- ieee80211_send_addba_resp(sta->sdata, sta->sta.addr, tid,
+ ieee80211_send_addba_resp(sta, sta->sta.addr, tid,
dialog_token, status, 1, buf_size,
- timeout);
+ timeout, addbaext);
}
static void __ieee80211_start_rx_ba_session(struct sta_info *sta,
u8 dialog_token, u16 timeout,
u16 start_seq_num, u16 ba_policy,
u16 tid, u16 buf_size, bool tx,
- bool auto_seq)
+ bool auto_seq,
+ const struct ieee80211_addba_ext_ie *addbaext)
{
mutex_lock(&sta->ampdu_mlme.mtx);
___ieee80211_start_rx_ba_session(sta, dialog_token, timeout,
start_seq_num, ba_policy, tid,
- buf_size, tx, auto_seq);
+ buf_size, tx, auto_seq, addbaext);
mutex_unlock(&sta->ampdu_mlme.mtx);
}
@@ -434,7 +474,9 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
size_t len)
{
u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num;
+ struct ieee802_11_elems elems = { 0 };
u8 dialog_token;
+ int ies_len;
/* extract session parameters from addba request frame */
dialog_token = mgmt->u.action.u.addba_req.dialog_token;
@@ -447,9 +489,19 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6;
+ ies_len = len - offsetof(struct ieee80211_mgmt,
+ u.action.u.addba_req.variable);
+ if (ies_len) {
+ ieee802_11_parse_elems(mgmt->u.action.u.addba_req.variable,
+ ies_len, true, &elems, mgmt->bssid, NULL);
+ if (elems.parse_error)
+ return;
+ }
+
__ieee80211_start_rx_ba_session(sta, dialog_token, timeout,
start_seq_num, ba_policy, tid,
- buf_size, true, false);
+ buf_size, true, false,
+ elems.addba_ext_ie);
}
void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif,
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index d5a500b2a448..a2e4d6b8fd98 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -359,7 +359,7 @@ void ieee80211_ba_session_work(struct work_struct *work)
sta->ampdu_mlme.tid_rx_manage_offl))
___ieee80211_start_rx_ba_session(sta, 0, 0, 0, 1, tid,
IEEE80211_MAX_AMPDU_BUF_HT,
- false, true);
+ false, true, NULL);
if (test_and_clear_bit(tid + IEEE80211_NUM_TIDS,
sta->ampdu_mlme.tid_rx_manage_offl))
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ba1bc245678e..38769f5c3da4 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1807,7 +1807,8 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
void ___ieee80211_start_rx_ba_session(struct sta_info *sta,
u8 dialog_token, u16 timeout,
u16 start_seq_num, u16 ba_policy, u16 tid,
- u16 buf_size, bool tx, bool auto_seq);
+ u16 buf_size, bool tx, bool auto_seq,
+ const struct ieee80211_addba_ext_ie *addbaext);
void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta,
enum ieee80211_agg_stop_reason reason);
void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
--
2.20.1
^ permalink raw reply related
* Re: [RFC] mt76: fix tx hung regression on MT7630E
From: Stanislaw Gruszka @ 2019-07-29 12:53 UTC (permalink / raw)
To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Ryder Lee, Roy Luo
In-Reply-To: <1564143056-14610-1-git-send-email-sgruszka@redhat.com>
On Fri, Jul 26, 2019 at 02:10:56PM +0200, Stanislaw Gruszka wrote:
> Since 41634aa8d6db ("mt76: only schedule txqs from the tx tasklet")
> I can observe firmware hangs on MT7630E on station mode: tx stop
> functioning after minor activity (rx keep working) and on module
> unload device fail to stop with messages:
>
> [ 5446.141413] mt76x0e 0000:06:00.0: TX DMA did not stop
> [ 5449.176764] mt76x0e 0000:06:00.0: TX DMA did not stop
>
> Loading module again results in failure to associate with AP.
> Only machine power off / power on cycle can make device work again.
>
> I have no idea why the commit caused F/W hangs. Most likely some proper
> fix is needed of changing registers programming (or assuring proper order
> of actions), but so far I can not came up with any better fix than
> a partial revert of 41634aa8d6db.
The difference is that with 41634aa8d6db we can run mt76x02_poll_tx()
and mt76x02_tx_tasklet() in parallel on 2 different CPUs. Without
the commit, since tasklet is not scheduled from mt76_wake_tx_queue(),
it does not happen.
I'm not quite sure why, but MT7630E does not like when we poll tx status
on 2 cpus at once. Change like below:
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index 467b28379870..622251faa415 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -170,7 +170,7 @@ static int mt76x02_poll_tx(struct napi_struct *napi, int budget)
mt76.tx_napi);
int i;
- mt76x02_mac_poll_tx_status(dev, false);
+ mt76x02_mac_poll_tx_status(dev, true);
for (i = MT_TXQ_MCU; i >= 0; i--)
mt76_queue_tx_cleanup(dev, i, false);
is sufficient to avoid the hangs.
> diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
> index 5397827668b9..fefe0ee52584 100644
> --- a/drivers/net/wireless/mediatek/mt76/tx.c
> +++ b/drivers/net/wireless/mediatek/mt76/tx.c
> @@ -598,7 +598,7 @@ void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
> if (!test_bit(MT76_STATE_RUNNING, &dev->state))
> return;
>
> - tasklet_schedule(&dev->tx_tasklet);
> + mt76_txq_schedule(dev, txq->ac);
However I'm not sure if change to tasklet_schedule() is indeed correct,
since on tasklet we schedule all queues, hence queues that could
possibly be still blocked? And on mt76_wake_tx_queue() we schedule only
one queue.
Stanislaw
^ permalink raw reply related
* KASAN reporting bug in ath6kl
From: Oliver Neukum @ 2019-07-29 12:58 UTC (permalink / raw)
To: Kalle Valo; +Cc: linux-usb, linux-wireless
Hi,
I am looking at this report:
Title: general protection fault in
ath6kl_usb_alloc_urb_from_pipe
Last occurred: 0 days ago
Reported: 102 days ago
Branches: Mainline (with usb-fuzzer patches)
Dashboard link: https://syzkaller.appspot.com/bug?id=cd8b9cfe50a0bf
36ee19eda2d7e2e06843dfbeaf
Original thread: https://lkml.kernel.org/lkml/0000000000008e82510586
5615e3@google.com/T/#u
This bug has a C reproducer.
No one replied to the original thread for this bug.
This looks like a bug in a net/wireless USB driver.
If you fix this bug, please add the following tag to the commit:
Reported-by: syzbot+ead4037ec793e025e66f@syzkaller.appspotmail.com
--
It looks like a bug in
static int ath6kl_usb_setup_pipe_resources(struct ath6kl_usb *ar_usb)
to me, which happily does nothing if the device has no endpoints.
THis needs sanity checking, but it looks like the driver
really uses 8 endpoints. Can you confirm that all 8 of them
are indeed needed?
Regards
Oliver
^ permalink raw reply
* Re: [RFC] mt76: fix tx hung regression on MT7630E
From: Lorenzo Bianconi @ 2019-07-29 14:02 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: linux-wireless, Felix Fietkau, Ryder Lee, Roy Luo
In-Reply-To: <20190729125351.GA3086@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 3146 bytes --]
> On Fri, Jul 26, 2019 at 02:10:56PM +0200, Stanislaw Gruszka wrote:
> > Since 41634aa8d6db ("mt76: only schedule txqs from the tx tasklet")
> > I can observe firmware hangs on MT7630E on station mode: tx stop
> > functioning after minor activity (rx keep working) and on module
> > unload device fail to stop with messages:
> >
> > [ 5446.141413] mt76x0e 0000:06:00.0: TX DMA did not stop
> > [ 5449.176764] mt76x0e 0000:06:00.0: TX DMA did not stop
> >
> > Loading module again results in failure to associate with AP.
> > Only machine power off / power on cycle can make device work again.
> >
> > I have no idea why the commit caused F/W hangs. Most likely some proper
> > fix is needed of changing registers programming (or assuring proper order
> > of actions), but so far I can not came up with any better fix than
> > a partial revert of 41634aa8d6db.
>
> The difference is that with 41634aa8d6db we can run mt76x02_poll_tx()
> and mt76x02_tx_tasklet() in parallel on 2 different CPUs. Without
> the commit, since tasklet is not scheduled from mt76_wake_tx_queue(),
> it does not happen.
>
> I'm not quite sure why, but MT7630E does not like when we poll tx status
> on 2 cpus at once. Change like below:
Hi Stanislaw,
have you tried to look at the commit: 6fe533378795f87
("mt76: mt76x02: remove irqsave/restore in locking for tx status fifo")?
Could it be a race between a registermap update and a stats load? (we are using a
different lock now)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
> index 467b28379870..622251faa415 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
> @@ -170,7 +170,7 @@ static int mt76x02_poll_tx(struct napi_struct *napi, int budget)
> mt76.tx_napi);
> int i;
>
> - mt76x02_mac_poll_tx_status(dev, false);
> + mt76x02_mac_poll_tx_status(dev, true);
I am not sure if we really need mt76x02_mac_poll_tx_status() here since we run
it in mt76x02_tx_complete_skb() and in mt76x02_tx_tasklet(). Anyway the only
difference doing so is we do not run mt76x02_send_tx_status().
Regards,
Lorenzo
>
> for (i = MT_TXQ_MCU; i >= 0; i--)
> mt76_queue_tx_cleanup(dev, i, false);
>
> is sufficient to avoid the hangs.
>
> > diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
> > index 5397827668b9..fefe0ee52584 100644
> > --- a/drivers/net/wireless/mediatek/mt76/tx.c
> > +++ b/drivers/net/wireless/mediatek/mt76/tx.c
> > @@ -598,7 +598,7 @@ void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
> > if (!test_bit(MT76_STATE_RUNNING, &dev->state))
> > return;
> >
> > - tasklet_schedule(&dev->tx_tasklet);
> > + mt76_txq_schedule(dev, txq->ac);
>
> However I'm not sure if change to tasklet_schedule() is indeed correct,
> since on tasklet we schedule all queues, hence queues that could
> possibly be still blocked? And on mt76_wake_tx_queue() we schedule only
> one queue.
>
> Stanislaw
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox