* Re: KASAN: use-after-free Read in p54u_load_firmware_cb
From: Alan Stern @ 2019-05-18 16:32 UTC (permalink / raw)
To: syzbot
Cc: andreyknvl, chunkeey, chunkeey, davem, kvalo, linux-kernel,
linux-usb, linux-wireless, netdev, oneukum, syzkaller-bugs
In-Reply-To: <000000000000add98105892b73ec@google.com>
On Sat, 18 May 2019, syzbot wrote:
> Hello,
>
> syzbot has tested the proposed patch but the reproducer still triggered
> crash:
> KASAN: slab-out-of-bounds Read in p54u_load_firmware_cb
>
> usb 6-1: Direct firmware load for isl3887usb failed with error -2
> p54u_load_firmware_cb: priv->udev = ffff88809ad5bb80
> usb 6-1: Firmware not found.
> ==================================================================
> BUG: KASAN: slab-out-of-bounds in p54u_load_firmware_cb+0x3c9/0x45f
> drivers/net/wireless/intersil/p54/p54usb.c:937
> Read of size 8 at addr ffff88809abab588 by task kworker/1:8/5526
If you look at the full console log, you'll see that this address is
different from all the addresses printed out earlier. Not what you
would expect.
Which makes me wonder: Suppose a disconnect occurs before the firmware
loader callback runs? p54_disconnect() will get stuck waiting for the
priv->fw_load_wait completion to fire. But when the callback runs, the
first thing it does is activate the completion.
So now p54_disconnect() can finish doing its thing, including
deallocating all the private data structures. Then when
p54u_load_firmware_cb() tries to read the contents of priv, it ends up
accessing deallocated memory!
The patch below tries to do things the right way.
Alan Stern
#syz test: https://github.com/google/kasan.git usb-fuzzer
drivers/net/wireless/intersil/p54/p54usb.c | 37 +++++++++++------------------
1 file changed, 15 insertions(+), 22 deletions(-)
Index: usb-devel/drivers/net/wireless/intersil/p54/p54usb.c
===================================================================
--- usb-devel.orig/drivers/net/wireless/intersil/p54/p54usb.c
+++ usb-devel/drivers/net/wireless/intersil/p54/p54usb.c
@@ -33,6 +33,8 @@ MODULE_ALIAS("prism54usb");
MODULE_FIRMWARE("isl3886usb");
MODULE_FIRMWARE("isl3887usb");
+static struct usb_driver p54u_driver;
+
/*
* Note:
*
@@ -921,9 +923,9 @@ static void p54u_load_firmware_cb(const
{
struct p54u_priv *priv = context;
struct usb_device *udev = priv->udev;
+ struct usb_interface *intf = priv->intf;
int err;
- complete(&priv->fw_wait_load);
if (firmware) {
priv->fw = firmware;
err = p54u_start_ops(priv);
@@ -932,23 +934,19 @@ static void p54u_load_firmware_cb(const
dev_err(&udev->dev, "Firmware not found.\n");
}
- if (err) {
- struct device *parent = priv->udev->dev.parent;
-
- dev_err(&udev->dev, "failed to initialize device (%d)\n", err);
-
- if (parent)
- device_lock(parent);
+ complete(&priv->fw_wait_load);
+ /*
+ * At this point p54u_disconnect may have already freed
+ * the "priv" context. Do not use it anymore!
+ */
+ priv = NULL;
- device_release_driver(&udev->dev);
- /*
- * At this point p54u_disconnect has already freed
- * the "priv" context. Do not use it anymore!
- */
- priv = NULL;
+ if (err) {
+ dev_err(&intf->dev, "failed to initialize device (%d)\n", err);
- if (parent)
- device_unlock(parent);
+ usb_lock_device(udev);
+ usb_driver_release_interface(intf, &p54u_driver);
+ usb_unlock_device(udev);
}
usb_put_dev(udev);
@@ -1011,8 +1009,6 @@ static int p54u_probe(struct usb_interfa
skb_queue_head_init(&priv->rx_queue);
init_usb_anchor(&priv->submitted);
- usb_get_dev(udev);
-
/* really lazy and simple way of figuring out if we're a 3887 */
/* TODO: should just stick the identification in the device table */
i = intf->altsetting->desc.bNumEndpoints;
@@ -1053,10 +1049,8 @@ static int p54u_probe(struct usb_interfa
priv->upload_fw = p54u_upload_firmware_net2280;
}
err = p54u_load_firmware(dev, intf);
- if (err) {
- usb_put_dev(udev);
+ if (err)
p54_free_common(dev);
- }
return err;
}
@@ -1072,7 +1066,6 @@ static void p54u_disconnect(struct usb_i
wait_for_completion(&priv->fw_wait_load);
p54_unregister_common(dev);
- usb_put_dev(interface_to_usbdev(intf));
release_firmware(priv->fw);
p54_free_common(dev);
}
^ permalink raw reply
* Re: KASAN: use-after-free Read in p54u_load_firmware_cb
From: syzbot @ 2019-05-18 16:50 UTC (permalink / raw)
To: andreyknvl, chunkeey, chunkeey, davem, kvalo, linux-kernel,
linux-usb, linux-wireless, netdev, oneukum, stern, syzkaller-bugs
In-Reply-To: <Pine.LNX.4.44L0.1905181202500.7855-100000@netrider.rowland.org>
Hello,
syzbot tried to test the proposed patch but build/boot failed:
si/sg.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgv100.o
CC drivers/scsi/ch.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/roottu102.o
CC drivers/scsi/ses.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/changf119.o
CC drivers/scsi/scsi_sysfs.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/changv100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgv100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/basenv50.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/baseg84.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/basegf119.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/basegp102.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg84.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg94.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/coregk104.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/coregv100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlynv50.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlyg84.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygt200.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygf119.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygk104.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygp102.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/wimmgv100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/wndwgv100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgf119.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgp102.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/cursnv50.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgv100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmnv50.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgf119.o
CC drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgp102.o
CC drivers/gpu/drm/nouveau/nvkm/engine/dma/base.o
CC drivers/gpu/drm/nouveau/nvkm/engine/dma/nv04.o
CC drivers/gpu/drm/nouveau/nvkm/engine/dma/nv50.o
CC drivers/gpu/drm/nouveau/nvkm/engine/dma/gf100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/dma/gf119.o
CC drivers/gpu/drm/nouveau/nvkm/engine/dma/gv100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/dma/user.o
CC drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv04.o
CC drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv50.o
CC drivers/gpu/drm/nouveau/nvkm/engine/dma/usergf100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/dma/usergf119.o
CC drivers/gpu/drm/nouveau/nvkm/engine/dma/usergv100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv04.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv17.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv10.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv40.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv50.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmag84.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifonv50.o
AR drivers/net/ethernet/sun/built-in.a
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifog84.o
AR drivers/net/ethernet/built-in.a
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogv100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/usergv100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/base.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/usertu102.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/nv15.o
CC drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifotu102.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/nv17.o
scripts/Makefile.build:486: recipe for target 'drivers/net' failed
make[1]: *** [drivers/net] Error 2
make[1]: *** Waiting for unfinished jobs....
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/nv25.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/nv2a.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/nv30.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/nv34.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/nv35.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/nv44.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/g84.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/gt200.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/mcp79.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/gt215.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/mcp89.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/gv100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxnv40.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxnv50.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp104.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.o
CC drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgv100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.o
CC drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv40.o
CC drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.o
CC drivers/gpu/drm/nouveau/nvkm/engine/mspdec/base.o
CC drivers/gpu/drm/nouveau/nvkm/engine/mpeg/g84.o
CC drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv50.o
CC drivers/gpu/drm/nouveau/nvkm/engine/mspdec/g98.o
CC drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gt215.o
CC drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gf100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gk104.o
CC drivers/gpu/drm/nouveau/nvkm/engine/msppp/base.o
CC drivers/gpu/drm/nouveau/nvkm/engine/msppp/g98.o
CC drivers/gpu/drm/nouveau/nvkm/engine/msppp/gt215.o
CC drivers/gpu/drm/nouveau/nvkm/engine/msvld/base.o
CC drivers/gpu/drm/nouveau/nvkm/engine/msppp/gf100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/msvld/g98.o
CC drivers/gpu/drm/nouveau/nvkm/engine/msvld/mcp89.o
CC drivers/gpu/drm/nouveau/nvkm/engine/msvld/gt215.o
CC drivers/gpu/drm/nouveau/nvkm/engine/msvld/gf100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/msvld/gk104.o
CC drivers/gpu/drm/nouveau/nvkm/engine/nvdec/base.o
CC drivers/gpu/drm/nouveau/nvkm/engine/nvdec/gp102.o
CC drivers/gpu/drm/nouveau/nvkm/engine/pm/g84.o
CC drivers/gpu/drm/nouveau/nvkm/engine/pm/gt200.o
CC drivers/gpu/drm/nouveau/nvkm/engine/pm/gt215.o
CC drivers/gpu/drm/nouveau/nvkm/engine/pm/gf100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/pm/gf108.o
CC drivers/gpu/drm/nouveau/nvkm/engine/pm/nv40.o
CC drivers/gpu/drm/nouveau/nvkm/engine/pm/base.o
CC drivers/gpu/drm/nouveau/nvkm/engine/pm/gf117.o
CC drivers/gpu/drm/nouveau/nvkm/engine/pm/gk104.o
CC drivers/gpu/drm/nouveau/nvkm/engine/sec2/base.o
CC drivers/gpu/drm/nouveau/nvkm/engine/sec/g98.o
CC drivers/gpu/drm/nouveau/nvkm/engine/pm/nv50.o
CC drivers/gpu/drm/nouveau/nvkm/engine/sec2/gp102.o
CC drivers/gpu/drm/nouveau/nvkm/engine/sec2/tu102.o
CC drivers/gpu/drm/nouveau/nvkm/engine/sw/base.o
CC drivers/gpu/drm/nouveau/nvkm/engine/sw/nv04.o
CC drivers/gpu/drm/nouveau/nvkm/engine/sw/nv10.o
CC drivers/gpu/drm/nouveau/nvkm/engine/sw/nv50.o
CC drivers/gpu/drm/nouveau/nvkm/engine/sw/gf100.o
CC drivers/gpu/drm/nouveau/nvkm/engine/sw/chan.o
CC drivers/gpu/drm/nouveau/nouveau_acpi.o
CC drivers/gpu/drm/nouveau/nvkm/engine/vp/g84.o
CC drivers/gpu/drm/nouveau/nvkm/engine/sw/nvsw.o
CC drivers/gpu/drm/nouveau/nouveau_debugfs.o
CC drivers/gpu/drm/nouveau/nouveau_drm.o
CC drivers/gpu/drm/nouveau/nouveau_hwmon.o
CC drivers/gpu/drm/nouveau/nouveau_ioc32.o
CC drivers/gpu/drm/nouveau/nouveau_led.o
CC drivers/gpu/drm/nouveau/nouveau_nvif.o
CC drivers/gpu/drm/nouveau/nouveau_usif.o
CC drivers/gpu/drm/nouveau/nouveau_bo.o
CC drivers/gpu/drm/nouveau/nouveau_gem.o
CC drivers/gpu/drm/nouveau/nouveau_mem.o
CC drivers/gpu/drm/nouveau/nouveau_backlight.o
CC drivers/gpu/drm/nouveau/nouveau_vga.o
CC drivers/gpu/drm/nouveau/nouveau_vmm.o
CC drivers/gpu/drm/nouveau/nouveau_ttm.o
CC drivers/gpu/drm/nouveau/nouveau_bios.o
CC drivers/gpu/drm/nouveau/nouveau_prime.o
CC drivers/gpu/drm/nouveau/nouveau_connector.o
CC drivers/gpu/drm/nouveau/nouveau_sgdma.o
CC drivers/gpu/drm/nouveau/nouveau_dp.o
CC drivers/gpu/drm/nouveau/nouveau_display.o
CC drivers/gpu/drm/nouveau/nv04_fbcon.o
CC drivers/gpu/drm/nouveau/nv50_fbcon.o
CC drivers/gpu/drm/nouveau/nouveau_fbcon.o
CC drivers/gpu/drm/nouveau/nvc0_fbcon.o
CC drivers/gpu/drm/nouveau/dispnv04/arb.o
CC drivers/gpu/drm/nouveau/dispnv04/crtc.o
CC drivers/gpu/drm/nouveau/dispnv04/cursor.o
CC drivers/gpu/drm/nouveau/dispnv04/dac.o
CC drivers/gpu/drm/nouveau/dispnv04/dfp.o
CC drivers/gpu/drm/nouveau/dispnv04/disp.o
CC drivers/gpu/drm/nouveau/dispnv04/hw.o
CC drivers/gpu/drm/nouveau/dispnv04/overlay.o
CC drivers/gpu/drm/nouveau/dispnv04/tvmodesnv17.o
CC drivers/gpu/drm/nouveau/dispnv04/tvnv04.o
AR drivers/scsi/built-in.a
CC drivers/gpu/drm/nouveau/dispnv04/tvnv17.o
CC drivers/gpu/drm/nouveau/dispnv50/disp.o
CC drivers/gpu/drm/nouveau/dispnv50/lut.o
CC drivers/gpu/drm/nouveau/dispnv50/core507d.o
CC drivers/gpu/drm/nouveau/dispnv50/core.o
CC drivers/gpu/drm/nouveau/dispnv50/core907d.o
CC drivers/gpu/drm/nouveau/dispnv50/core827d.o
CC drivers/gpu/drm/nouveau/dispnv50/core917d.o
CC drivers/gpu/drm/nouveau/dispnv50/corec37d.o
CC drivers/gpu/drm/nouveau/dispnv50/corec57d.o
CC drivers/gpu/drm/nouveau/dispnv50/dac907d.o
CC drivers/gpu/drm/nouveau/dispnv50/dac507d.o
CC drivers/gpu/drm/nouveau/dispnv50/pior507d.o
CC drivers/gpu/drm/nouveau/dispnv50/sor507d.o
CC drivers/gpu/drm/nouveau/dispnv50/sor907d.o
CC drivers/gpu/drm/nouveau/dispnv50/sorc37d.o
CC drivers/gpu/drm/nouveau/dispnv50/head.o
CC drivers/gpu/drm/nouveau/dispnv50/head507d.o
CC drivers/gpu/drm/nouveau/dispnv50/head827d.o
CC drivers/gpu/drm/nouveau/dispnv50/head907d.o
CC drivers/gpu/drm/nouveau/dispnv50/headc37d.o
CC drivers/gpu/drm/nouveau/dispnv50/head917d.o
CC drivers/gpu/drm/nouveau/dispnv50/headc57d.o
CC drivers/gpu/drm/nouveau/dispnv50/wimm.o
CC drivers/gpu/drm/nouveau/dispnv50/wimmc37b.o
CC drivers/gpu/drm/nouveau/dispnv50/wndwc37e.o
CC drivers/gpu/drm/nouveau/dispnv50/base.o
CC drivers/gpu/drm/nouveau/dispnv50/wndwc57e.o
CC drivers/gpu/drm/nouveau/dispnv50/wndw.o
CC drivers/gpu/drm/nouveau/dispnv50/base907c.o
CC drivers/gpu/drm/nouveau/dispnv50/base827c.o
CC drivers/gpu/drm/nouveau/dispnv50/base507c.o
CC drivers/gpu/drm/nouveau/dispnv50/base917c.o
CC drivers/gpu/drm/nouveau/dispnv50/curs.o
CC drivers/gpu/drm/nouveau/dispnv50/curs507a.o
CC drivers/gpu/drm/nouveau/dispnv50/curs907a.o
CC drivers/gpu/drm/nouveau/dispnv50/cursc37a.o
CC drivers/gpu/drm/nouveau/dispnv50/oimm.o
CC drivers/gpu/drm/nouveau/dispnv50/oimm507b.o
CC drivers/gpu/drm/nouveau/dispnv50/ovly.o
CC drivers/gpu/drm/nouveau/dispnv50/ovly507e.o
CC drivers/gpu/drm/nouveau/dispnv50/ovly827e.o
CC drivers/gpu/drm/nouveau/dispnv50/ovly907e.o
CC drivers/gpu/drm/nouveau/dispnv50/ovly917e.o
CC drivers/gpu/drm/nouveau/nouveau_abi16.o
CC drivers/gpu/drm/nouveau/nouveau_chan.o
CC drivers/gpu/drm/nouveau/nv04_fence.o
CC drivers/gpu/drm/nouveau/nouveau_fence.o
CC drivers/gpu/drm/nouveau/nouveau_dma.o
CC drivers/gpu/drm/nouveau/nv10_fence.o
CC drivers/gpu/drm/nouveau/nv50_fence.o
CC drivers/gpu/drm/nouveau/nv17_fence.o
CC drivers/gpu/drm/nouveau/nv84_fence.o
CC drivers/gpu/drm/nouveau/nvc0_fence.o
AR drivers/gpu/drm/nouveau/built-in.a
AR drivers/gpu/drm/built-in.a
AR drivers/gpu/built-in.a
Makefile:1051: recipe for target 'drivers' failed
make: *** [drivers] Error 2
Error text is too large and was truncated, full error text is at:
https://syzkaller.appspot.com/x/error.txt?x=164a0108a00000
Tested on:
commit: 43151d6c usb-fuzzer: main usb gadget fuzzer driver
git tree: https://github.com/google/kasan.git usb-fuzzer
compiler: gcc (GCC) 9.0.0 20181231 (experimental)
patch: https://syzkaller.appspot.com/x/patch.diff?x=15d1ef02a00000
^ permalink raw reply
* Re: KASAN: use-after-free Read in p54u_load_firmware_cb
From: Alan Stern @ 2019-05-18 17:01 UTC (permalink / raw)
To: syzbot
Cc: andreyknvl, chunkeey, chunkeey, davem, kvalo, linux-kernel,
linux-usb, linux-wireless, netdev, oneukum, syzkaller-bugs
In-Reply-To: <00000000000043a1f905892c4a1f@google.com>
On Sat, 18 May 2019, syzbot wrote:
> Hello,
>
> syzbot tried to test the proposed patch but build/boot failed:
One of these times I'll get it right...
Alan Stern
#syz test: https://github.com/google/kasan.git usb-fuzzer
drivers/net/wireless/intersil/p54/p54usb.c | 37 +++++++++++------------------
1 file changed, 15 insertions(+), 22 deletions(-)
Index: usb-devel/drivers/net/wireless/intersil/p54/p54usb.c
===================================================================
--- usb-devel.orig/drivers/net/wireless/intersil/p54/p54usb.c
+++ usb-devel/drivers/net/wireless/intersil/p54/p54usb.c
@@ -33,6 +33,8 @@ MODULE_ALIAS("prism54usb");
MODULE_FIRMWARE("isl3886usb");
MODULE_FIRMWARE("isl3887usb");
+static struct usb_driver p54u_driver;
+
/*
* Note:
*
@@ -921,9 +923,9 @@ static void p54u_load_firmware_cb(const
{
struct p54u_priv *priv = context;
struct usb_device *udev = priv->udev;
+ struct usb_interface *intf = priv->intf;
int err;
- complete(&priv->fw_wait_load);
if (firmware) {
priv->fw = firmware;
err = p54u_start_ops(priv);
@@ -932,23 +934,19 @@ static void p54u_load_firmware_cb(const
dev_err(&udev->dev, "Firmware not found.\n");
}
- if (err) {
- struct device *parent = priv->udev->dev.parent;
-
- dev_err(&udev->dev, "failed to initialize device (%d)\n", err);
-
- if (parent)
- device_lock(parent);
+ complete(&priv->fw_wait_load);
+ /*
+ * At this point p54u_disconnect may have already freed
+ * the "priv" context. Do not use it anymore!
+ */
+ priv = NULL;
- device_release_driver(&udev->dev);
- /*
- * At this point p54u_disconnect has already freed
- * the "priv" context. Do not use it anymore!
- */
- priv = NULL;
+ if (err) {
+ dev_err(&intf->dev, "failed to initialize device (%d)\n", err);
- if (parent)
- device_unlock(parent);
+ usb_lock_device(udev);
+ usb_driver_release_interface(&p54u_driver, intf);
+ usb_unlock_device(udev);
}
usb_put_dev(udev);
@@ -1011,8 +1009,6 @@ static int p54u_probe(struct usb_interfa
skb_queue_head_init(&priv->rx_queue);
init_usb_anchor(&priv->submitted);
- usb_get_dev(udev);
-
/* really lazy and simple way of figuring out if we're a 3887 */
/* TODO: should just stick the identification in the device table */
i = intf->altsetting->desc.bNumEndpoints;
@@ -1053,10 +1049,8 @@ static int p54u_probe(struct usb_interfa
priv->upload_fw = p54u_upload_firmware_net2280;
}
err = p54u_load_firmware(dev, intf);
- if (err) {
- usb_put_dev(udev);
+ if (err)
p54_free_common(dev);
- }
return err;
}
@@ -1072,7 +1066,6 @@ static void p54u_disconnect(struct usb_i
wait_for_completion(&priv->fw_wait_load);
p54_unregister_common(dev);
- usb_put_dev(interface_to_usbdev(intf));
release_firmware(priv->fw);
p54_free_common(dev);
}
^ permalink raw reply
* Re: KASAN: use-after-free Read in p54u_load_firmware_cb
From: syzbot @ 2019-05-18 17:36 UTC (permalink / raw)
To: andreyknvl, chunkeey, chunkeey, davem, kvalo, linux-kernel,
linux-usb, linux-wireless, netdev, oneukum, stern, syzkaller-bugs
In-Reply-To: <Pine.LNX.4.44L0.1905181300440.10594-100000@netrider.rowland.org>
Hello,
syzbot has tested the proposed patch but the reproducer still triggered
crash:
KASAN: use-after-free Read in usb_driver_release_interface
usb 1-1: Loading firmware file isl3887usb
usb 1-1: Direct firmware load for isl3887usb failed with error -2
usb 1-1: Firmware not found.
p54usb 1-1:0.143: failed to initialize device (-2)
==================================================================
BUG: KASAN: use-after-free in usb_driver_release_interface+0x16b/0x190
drivers/usb/core/driver.c:584
Read of size 8 at addr ffff88808fc31218 by task kworker/0:1/12
CPU: 0 PID: 12 Comm: kworker/0:1 Not tainted 5.1.0-rc3-g43151d6-dirty #1
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
Workqueue: events request_firmware_work_func
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0xe8/0x16e lib/dump_stack.c:113
print_address_description+0x6c/0x236 mm/kasan/report.c:187
kasan_report.cold+0x1a/0x3c mm/kasan/report.c:317
usb_driver_release_interface+0x16b/0x190 drivers/usb/core/driver.c:584
p54u_load_firmware_cb+0x390/0x420
drivers/net/wireless/intersil/p54/p54usb.c:948
request_firmware_work_func+0x12d/0x249
drivers/base/firmware_loader/main.c:785
process_one_work+0x90f/0x1580 kernel/workqueue.c:2269
worker_thread+0x9b/0xe20 kernel/workqueue.c:2415
kthread+0x313/0x420 kernel/kthread.c:253
ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:352
Allocated by task 12:
set_track mm/kasan/common.c:87 [inline]
__kasan_kmalloc mm/kasan/common.c:497 [inline]
__kasan_kmalloc.constprop.0+0xbf/0xd0 mm/kasan/common.c:470
kmalloc include/linux/slab.h:547 [inline]
kzalloc include/linux/slab.h:742 [inline]
usb_set_configuration+0x2e0/0x1740 drivers/usb/core/message.c:1846
generic_probe+0xa2/0xda drivers/usb/core/generic.c:210
usb_probe_device+0xc0/0x150 drivers/usb/core/driver.c:266
really_probe+0x2da/0xb10 drivers/base/dd.c:509
driver_probe_device+0x21d/0x350 drivers/base/dd.c:671
__device_attach_driver+0x1d8/0x290 drivers/base/dd.c:778
bus_for_each_drv+0x163/0x1e0 drivers/base/bus.c:454
__device_attach+0x223/0x3a0 drivers/base/dd.c:844
bus_probe_device+0x1f1/0x2a0 drivers/base/bus.c:514
device_add+0xad2/0x16e0 drivers/base/core.c:2106
usb_new_device.cold+0x537/0xccf drivers/usb/core/hub.c:2534
hub_port_connect drivers/usb/core/hub.c:5089 [inline]
hub_port_connect_change drivers/usb/core/hub.c:5204 [inline]
port_event drivers/usb/core/hub.c:5350 [inline]
hub_event+0x138e/0x3b00 drivers/usb/core/hub.c:5432
process_one_work+0x90f/0x1580 kernel/workqueue.c:2269
worker_thread+0x9b/0xe20 kernel/workqueue.c:2415
kthread+0x313/0x420 kernel/kthread.c:253
ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:352
Freed by task 5394:
set_track mm/kasan/common.c:87 [inline]
__kasan_slab_free+0x130/0x180 mm/kasan/common.c:459
slab_free_hook mm/slub.c:1429 [inline]
slab_free_freelist_hook+0x5e/0x140 mm/slub.c:1456
slab_free mm/slub.c:3003 [inline]
kfree+0xce/0x290 mm/slub.c:3958
device_release+0x7d/0x210 drivers/base/core.c:1064
kobject_cleanup lib/kobject.c:662 [inline]
kobject_release lib/kobject.c:691 [inline]
kref_put include/linux/kref.h:67 [inline]
kobject_put+0x1df/0x4f0 lib/kobject.c:708
put_device+0x21/0x30 drivers/base/core.c:2205
usb_disable_device+0x309/0x790 drivers/usb/core/message.c:1244
usb_disconnect+0x298/0x870 drivers/usb/core/hub.c:2197
hub_port_connect drivers/usb/core/hub.c:4940 [inline]
hub_port_connect_change drivers/usb/core/hub.c:5204 [inline]
port_event drivers/usb/core/hub.c:5350 [inline]
hub_event+0xcd2/0x3b00 drivers/usb/core/hub.c:5432
process_one_work+0x90f/0x1580 kernel/workqueue.c:2269
worker_thread+0x9b/0xe20 kernel/workqueue.c:2415
kthread+0x313/0x420 kernel/kthread.c:253
ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:352
The buggy address belongs to the object at ffff88808fc31100
which belongs to the cache kmalloc-2k of size 2048
The buggy address is located 280 bytes inside of
2048-byte region [ffff88808fc31100, ffff88808fc31900)
The buggy address belongs to the page:
page:ffffea00023f0c00 count:1 mapcount:0 mapping:ffff88812c3f4800 index:0x0
compound_mapcount: 0
flags: 0xfff00000010200(slab|head)
raw: 00fff00000010200 dead000000000100 dead000000000200 ffff88812c3f4800
raw: 0000000000000000 00000000000f000f 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff88808fc31100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff88808fc31180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> ffff88808fc31200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff88808fc31280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff88808fc31300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================
Tested on:
commit: 43151d6c usb-fuzzer: main usb gadget fuzzer driver
git tree: https://github.com/google/kasan.git usb-fuzzer
console output: https://syzkaller.appspot.com/x/log.txt?x=148b9428a00000
kernel config: https://syzkaller.appspot.com/x/.config?x=4183eeef650d1234
compiler: gcc (GCC) 9.0.0 20181231 (experimental)
patch: https://syzkaller.appspot.com/x/patch.diff?x=17642018a00000
^ permalink raw reply
* Re: KASAN: use-after-free Read in p54u_load_firmware_cb
From: Alan Stern @ 2019-05-18 17:49 UTC (permalink / raw)
To: syzbot
Cc: andreyknvl, chunkeey, chunkeey, davem, kvalo, linux-kernel,
linux-usb, linux-wireless, netdev, oneukum, syzkaller-bugs
In-Reply-To: <000000000000b8203405892cee43@google.com>
On Sat, 18 May 2019, syzbot wrote:
> Hello,
>
> syzbot has tested the proposed patch but the reproducer still triggered
> crash:
> KASAN: use-after-free Read in usb_driver_release_interface
>
> usb 1-1: Loading firmware file isl3887usb
> usb 1-1: Direct firmware load for isl3887usb failed with error -2
> usb 1-1: Firmware not found.
> p54usb 1-1:0.143: failed to initialize device (-2)
> ==================================================================
> BUG: KASAN: use-after-free in usb_driver_release_interface+0x16b/0x190
> drivers/usb/core/driver.c:584
> Read of size 8 at addr ffff88808fc31218 by task kworker/0:1/12
Now the bad access is in a different place. That's a good sign.
In this case it indicates that although udev is still hanging around,
intf has already been freed. We really should acquire a reference to
it instead.
Alan Stern
#syz test: https://github.com/google/kasan.git usb-fuzzer
drivers/net/wireless/intersil/p54/p54usb.c | 43 ++++++++++++-----------------
1 file changed, 18 insertions(+), 25 deletions(-)
Index: usb-devel/drivers/net/wireless/intersil/p54/p54usb.c
===================================================================
--- usb-devel.orig/drivers/net/wireless/intersil/p54/p54usb.c
+++ usb-devel/drivers/net/wireless/intersil/p54/p54usb.c
@@ -33,6 +33,8 @@ MODULE_ALIAS("prism54usb");
MODULE_FIRMWARE("isl3886usb");
MODULE_FIRMWARE("isl3887usb");
+static struct usb_driver p54u_driver;
+
/*
* Note:
*
@@ -921,9 +923,9 @@ static void p54u_load_firmware_cb(const
{
struct p54u_priv *priv = context;
struct usb_device *udev = priv->udev;
+ struct usb_interface *intf = priv->intf;
int err;
- complete(&priv->fw_wait_load);
if (firmware) {
priv->fw = firmware;
err = p54u_start_ops(priv);
@@ -932,26 +934,22 @@ static void p54u_load_firmware_cb(const
dev_err(&udev->dev, "Firmware not found.\n");
}
- if (err) {
- struct device *parent = priv->udev->dev.parent;
-
- dev_err(&udev->dev, "failed to initialize device (%d)\n", err);
-
- if (parent)
- device_lock(parent);
+ complete(&priv->fw_wait_load);
+ /*
+ * At this point p54u_disconnect may have already freed
+ * the "priv" context. Do not use it anymore!
+ */
+ priv = NULL;
- device_release_driver(&udev->dev);
- /*
- * At this point p54u_disconnect has already freed
- * the "priv" context. Do not use it anymore!
- */
- priv = NULL;
+ if (err) {
+ dev_err(&intf->dev, "failed to initialize device (%d)\n", err);
- if (parent)
- device_unlock(parent);
+ usb_lock_device(udev);
+ usb_driver_release_interface(&p54u_driver, intf);
+ usb_unlock_device(udev);
}
- usb_put_dev(udev);
+ usb_put_intf(intf);
}
static int p54u_load_firmware(struct ieee80211_hw *dev,
@@ -972,14 +970,14 @@ static int p54u_load_firmware(struct iee
dev_info(&priv->udev->dev, "Loading firmware file %s\n",
p54u_fwlist[i].fw);
- usb_get_dev(udev);
+ usb_get_intf(intf);
err = request_firmware_nowait(THIS_MODULE, 1, p54u_fwlist[i].fw,
device, GFP_KERNEL, priv,
p54u_load_firmware_cb);
if (err) {
dev_err(&priv->udev->dev, "(p54usb) cannot load firmware %s "
"(%d)!\n", p54u_fwlist[i].fw, err);
- usb_put_dev(udev);
+ usb_put_intf(intf);
}
return err;
@@ -1011,8 +1009,6 @@ static int p54u_probe(struct usb_interfa
skb_queue_head_init(&priv->rx_queue);
init_usb_anchor(&priv->submitted);
- usb_get_dev(udev);
-
/* really lazy and simple way of figuring out if we're a 3887 */
/* TODO: should just stick the identification in the device table */
i = intf->altsetting->desc.bNumEndpoints;
@@ -1053,10 +1049,8 @@ static int p54u_probe(struct usb_interfa
priv->upload_fw = p54u_upload_firmware_net2280;
}
err = p54u_load_firmware(dev, intf);
- if (err) {
- usb_put_dev(udev);
+ if (err)
p54_free_common(dev);
- }
return err;
}
@@ -1072,7 +1066,6 @@ static void p54u_disconnect(struct usb_i
wait_for_completion(&priv->fw_wait_load);
p54_unregister_common(dev);
- usb_put_dev(interface_to_usbdev(intf));
release_firmware(priv->fw);
p54_free_common(dev);
}
^ permalink raw reply
* Re: [PATCH v2 2/2] qtnfmac: add support for Topaz chipsets
From: Jonas Gorski @ 2019-05-18 17:54 UTC (permalink / raw)
To: Sergey Matyukevich
Cc: linux-wireless@vger.kernel.org, Igor Mitsyanko, Andrey Shevchenko
In-Reply-To: <20181016102349.26544-3-sergey.matyukevich.os@quantenna.com>
Hi,
On Tue, 16 Oct 2018 at 12:25, Sergey Matyukevich
<sergey.matyukevich.os@quantenna.com> wrote:
>
> This patch adds support for QSR1000/QSR2000 family of chipsets
> to qtnfmac_pcie platform driver.
>
> QSR1000/QSR2000 (aka Topaz) is a family of 80MHz, 11ac Wave2,
> 4x4/2x4/2x2 chips, including single and dual band devices.
> Depending on specific chip model and firmware in use, either
> STA or both STA and AP modes are supported.
>
> Patch adds Topaz support to qtnfmac_pcie driver. Proper platform
> bus will be selected on probing based on chip ID.
>
> Signed-off-by: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
> Signed-off-by: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com>
> Signed-off-by: Andrey Shevchenko <ashevchenko@quantenna.com>
> ---
(snip)
> diff --git a/drivers/net/wireless/quantenna/qtnfmac/qtn_hw_ids.h b/drivers/net/wireless/quantenna/qtnfmac/qtn_hw_ids.h
> index 1fe798a9a667..40295a511224 100644
> --- a/drivers/net/wireless/quantenna/qtnfmac/qtn_hw_ids.h
> +++ b/drivers/net/wireless/quantenna/qtnfmac/qtn_hw_ids.h
> @@ -23,7 +23,7 @@
>
> /* PCIE Device IDs */
>
> -#define PCIE_DEVICE_ID_QTN_PEARL (0x0008)
> +#define PCIE_DEVICE_ID_QSR (0x0008)
>
> #define QTN_REG_SYS_CTRL_CSR 0x14
> #define QTN_CHIP_ID_MASK 0xF0
> @@ -35,6 +35,8 @@
> /* FW names */
>
> #define QTN_PCI_PEARL_FW_NAME "qtn/fmac_qsr10g.img"
> +#define QTN_PCI_TOPAZ_FW_NAME "qtn/fmac_qsr1000.img"
> +#define QTN_PCI_TOPAZ_BOOTLD_NAME "qtn/uboot_qsr1000.img"
A bit late of a review/question, but how does one obtain one of these
files? There's nothing in linux-firmware, and I see only one aborted
attempt for adding fmac_qsr10g.img from 2016, but none for the others.
Searching for these filenames also didn't reveal any external
locations.
Regards
Jonas
^ permalink raw reply
* Re: KASAN: use-after-free Read in p54u_load_firmware_cb
From: syzbot @ 2019-05-18 18:31 UTC (permalink / raw)
To: andreyknvl, chunkeey, chunkeey, davem, kvalo, linux-kernel,
linux-usb, linux-wireless, netdev, oneukum, stern, syzkaller-bugs
In-Reply-To: <Pine.LNX.4.44L0.1905181346380.10594-100000@netrider.rowland.org>
Hello,
syzbot has tested the proposed patch and the reproducer did not trigger
crash:
Reported-and-tested-by:
syzbot+200d4bb11b23d929335f@syzkaller.appspotmail.com
Tested on:
commit: 43151d6c usb-fuzzer: main usb gadget fuzzer driver
git tree: https://github.com/google/kasan.git usb-fuzzer
kernel config: https://syzkaller.appspot.com/x/.config?x=4183eeef650d1234
compiler: gcc (GCC) 9.0.0 20181231 (experimental)
patch: https://syzkaller.appspot.com/x/patch.diff?x=17e42018a00000
Note: testing is done by a robot and is best-effort only.
^ permalink raw reply
* [PATCH] net: wireless: p54: fix crash during initialization
From: Christian Lamparter @ 2019-05-18 20:05 UTC (permalink / raw)
To: linux-wireless; +Cc: David S . Miller, Kalle Valo
This patch fixes a crash that got introduced when the
mentioned patch replaced the direct list_head access
with skb_peek_tail(). When the device is starting up,
there are no entries in the queue, so previously to
"Use skb_peek_tail() instead..." the target_skb would
end up as the tail and head pointer which then could
be used by __skb_queue_after to fill the empty queue.
With skb_peek_tail() in its place will instead just
return NULL which then causes a crash in the
__skb_queue_after().
| BUG: unable to handle kernel NULL pointer dereference at 000000
| #PF error: [normal kernel read fault]
| PGD 0 P4D 0
| Oops: 0000 [#1] SMP PTI
| CPU: 0 PID: 12 Comm: kworker/0:1 Tainted: GO 5.1.0-rc7-wt+ #218
| Hardware name: MSI MS-7816/Z87-G43 (MS-7816), BIOS V1.11 05/09/2015
| Workqueue: events request_firmware_work_func
| RIP: 0010:p54_tx_pending+0x10f/0x1b0 [p54common]
| Code: 78 06 80 78 28 00 74 6d <48> 8b 07 49 89 7c 24 08 49 89 04 24 4
| RSP: 0018:ffffa81c81927d90 EFLAGS: 00010086
| RAX: ffff9bbaaf131048 RBX: 0000000000020670 RCX: 0000000000020264
| RDX: ffff9bbaa976d660 RSI: 0000000000000202 RDI: 0000000000000000
| RBP: ffff9bbaa976d620 R08: 00000000000006c0 R09: ffff9bbaa976d660
| R10: 0000000000000000 R11: ffffe8480dbc5900 R12: ffff9bbb45e87700
| R13: ffff9bbaa976d648 R14: ffff9bbaa976d674 R15: ffff9bbaaf131048
| FS: 0000000000000000(0000) GS:ffff9bbb5ec00000(0000) knlGS:00000
| CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
| CR2: 0000000000000000 CR3: 00000003695fc003 CR4: 00000000001606f0
| Call Trace:
| p54_download_eeprom+0xbe/0x120 [p54common]
| p54_read_eeprom+0x7f/0xc0 [p54common]
| p54u_load_firmware_cb+0xe0/0x160 [p54usb]
| request_firmware_work_func+0x42/0x80
| process_one_work+0x1f5/0x3f0
| worker_thread+0x28/0x3c0
Cc: stable@vger.kernel.org
Fixes: e3554197fc8f ("p54: Use skb_peek_tail() instead of direct head pointer accesses.")
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
---
drivers/net/wireless/intersil/p54/txrx.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intersil/p54/txrx.c b/drivers/net/wireless/intersil/p54/txrx.c
index 790784568ad2..5bf1c19ecced 100644
--- a/drivers/net/wireless/intersil/p54/txrx.c
+++ b/drivers/net/wireless/intersil/p54/txrx.c
@@ -142,7 +142,10 @@ static int p54_assign_address(struct p54_common *priv, struct sk_buff *skb)
unlikely(GET_HW_QUEUE(skb) == P54_QUEUE_BEACON))
priv->beacon_req_id = data->req_id;
- __skb_queue_after(&priv->tx_queue, target_skb, skb);
+ if (target_skb)
+ __skb_queue_after(&priv->tx_queue, target_skb, skb);
+ else
+ __skb_queue_head(&priv->tx_queue, skb);
spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
return 0;
}
--
2.20.1
^ permalink raw reply related
* Re: KASAN: use-after-free Read in p54u_load_firmware_cb
From: Christian Lamparter @ 2019-05-18 20:11 UTC (permalink / raw)
To: Alan Stern
Cc: syzbot, andreyknvl, chunkeey, davem, kvalo, linux-kernel,
linux-usb, linux-wireless, netdev, oneukum, syzkaller-bugs
In-Reply-To: <Pine.LNX.4.44L0.1905181346380.10594-100000@netrider.rowland.org>
Hello,
On Saturday, May 18, 2019 7:49:49 PM CEST you wrote:
> On Sat, 18 May 2019, syzbot wrote:
> >
> > syzbot has tested the proposed patch but the reproducer still triggered
> > crash:
> > KASAN: use-after-free Read in usb_driver_release_interface
> >
> > usb 1-1: Loading firmware file isl3887usb
> > usb 1-1: Direct firmware load for isl3887usb failed with error -2
> > usb 1-1: Firmware not found.
> > p54usb 1-1:0.143: failed to initialize device (-2)
> > ==================================================================
> > BUG: KASAN: use-after-free in usb_driver_release_interface+0x16b/0x190
> > drivers/usb/core/driver.c:584
> > Read of size 8 at addr ffff88808fc31218 by task kworker/0:1/12
>
> Now the bad access is in a different place. That's a good sign.
> In this case it indicates that although udev is still hanging around,
> intf has already been freed. We really should acquire a reference to
> it instead.
>
> Alan Stern
Thanks. I can confirm that it works with the real ISL3887
hardware as well. Can you please spin up a patch or how
should this be continued?
Cheers,
Christian
> drivers/net/wireless/intersil/p54/p54usb.c | 43 ++++++++++++-----------------
> 1 file changed, 18 insertions(+), 25 deletions(-)
>
> Index: usb-devel/drivers/net/wireless/intersil/p54/p54usb.c
> ===================================================================
> --- usb-devel.orig/drivers/net/wireless/intersil/p54/p54usb.c
> +++ usb-devel/drivers/net/wireless/intersil/p54/p54usb.c
> @@ -33,6 +33,8 @@ MODULE_ALIAS("prism54usb");
> MODULE_FIRMWARE("isl3886usb");
> MODULE_FIRMWARE("isl3887usb");
>
> +static struct usb_driver p54u_driver;
> +
> /*
> * Note:
> *
> @@ -921,9 +923,9 @@ static void p54u_load_firmware_cb(const
> {
> struct p54u_priv *priv = context;
> struct usb_device *udev = priv->udev;
> + struct usb_interface *intf = priv->intf;
> int err;
>
> - complete(&priv->fw_wait_load);
> if (firmware) {
> priv->fw = firmware;
> err = p54u_start_ops(priv);
> @@ -932,26 +934,22 @@ static void p54u_load_firmware_cb(const
> dev_err(&udev->dev, "Firmware not found.\n");
> }
>
> - if (err) {
> - struct device *parent = priv->udev->dev.parent;
> -
> - dev_err(&udev->dev, "failed to initialize device (%d)\n", err);
> -
> - if (parent)
> - device_lock(parent);
> + complete(&priv->fw_wait_load);
> + /*
> + * At this point p54u_disconnect may have already freed
> + * the "priv" context. Do not use it anymore!
> + */
> + priv = NULL;
>
> - device_release_driver(&udev->dev);
> - /*
> - * At this point p54u_disconnect has already freed
> - * the "priv" context. Do not use it anymore!
> - */
> - priv = NULL;
> + if (err) {
> + dev_err(&intf->dev, "failed to initialize device (%d)\n", err);
>
> - if (parent)
> - device_unlock(parent);
> + usb_lock_device(udev);
> + usb_driver_release_interface(&p54u_driver, intf);
> + usb_unlock_device(udev);
> }
>
> - usb_put_dev(udev);
> + usb_put_intf(intf);
> }
>
> static int p54u_load_firmware(struct ieee80211_hw *dev,
> @@ -972,14 +970,14 @@ static int p54u_load_firmware(struct iee
> dev_info(&priv->udev->dev, "Loading firmware file %s\n",
> p54u_fwlist[i].fw);
>
> - usb_get_dev(udev);
> + usb_get_intf(intf);
> err = request_firmware_nowait(THIS_MODULE, 1, p54u_fwlist[i].fw,
> device, GFP_KERNEL, priv,
> p54u_load_firmware_cb);
> if (err) {
> dev_err(&priv->udev->dev, "(p54usb) cannot load firmware %s "
> "(%d)!\n", p54u_fwlist[i].fw, err);
> - usb_put_dev(udev);
> + usb_put_intf(intf);
> }
>
> return err;
> @@ -1011,8 +1009,6 @@ static int p54u_probe(struct usb_interfa
> skb_queue_head_init(&priv->rx_queue);
> init_usb_anchor(&priv->submitted);
>
> - usb_get_dev(udev);
> -
> /* really lazy and simple way of figuring out if we're a 3887 */
> /* TODO: should just stick the identification in the device table */
> i = intf->altsetting->desc.bNumEndpoints;
> @@ -1053,10 +1049,8 @@ static int p54u_probe(struct usb_interfa
> priv->upload_fw = p54u_upload_firmware_net2280;
> }
> err = p54u_load_firmware(dev, intf);
> - if (err) {
> - usb_put_dev(udev);
> + if (err)
> p54_free_common(dev);
> - }
> return err;
> }
>
> @@ -1072,7 +1066,6 @@ static void p54u_disconnect(struct usb_i
> wait_for_completion(&priv->fw_wait_load);
> p54_unregister_common(dev);
>
> - usb_put_dev(interface_to_usbdev(intf));
> release_firmware(priv->fw);
> p54_free_common(dev);
> }
>
>
^ permalink raw reply
* Re: NXP NFC version and ACPI
From: Daniel Lezcano @ 2019-05-19 16:46 UTC (permalink / raw)
To: sedat.dilek
Cc: Samuel Ortiz, linux-wireless, linux-nfc, oleg.zhurakivskyy,
clement.perrochaud, charles.gorand, Andy Shevchenko
In-Reply-To: <CA+icZUVaBdswfmRfbRtdVJY8ymeDOwDSFEf7G6jneqEmpW84bg@mail.gmail.com>
FYI, when I tried to make the NFC work on my x280, I tried the module at:
https://github.com/jr64/nxp-pn5xx
AFAIR, it finally worked somehow.
May be you can cross check with your series and the change in this
module to find out what could be missing? (I can do that but it will be
certainly easier for you spot something in the code you wrote).
I can experiment your changes in my laptop if needed.
On 14/05/2019 16:59, Sedat Dilek wrote:
> On Tue, May 14, 2019 at 10:17 AM Daniel Lezcano
> <daniel.lezcano@linaro.org> wrote:
> [...]
>
> Just for the records:
>
> root@iniza:~# rfkill --output ID,TYPE
> ID TYPE
> 0 bluetooth
> 1 nfc
> 2 wlan
> 3 bluetooth
>
> root@iniza:~# rfkill list nfc
> 1: nfc0: NFC
> Soft blocked: no
> Hard blocked: no
>
> - Sedat -
>
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
^ permalink raw reply
* [PATCH] wireless: fix typos in code comments
From: Weitao Hou @ 2019-05-19 3:22 UTC (permalink / raw)
To: arend.vanspriel, franky.lin, hante.meuleman, chi-hsien.lin,
wright.feng, kvalo, davem, houweitaoo, rafal
Cc: linux-wireless, brcm80211-dev-list.pdl, brcm80211-dev-list,
netdev, linux-kernel
fix lengh to length
Signed-off-by: Weitao Hou <houweitaoo@gmail.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c
index 8ea27489734e..edd2f09613d8 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c
@@ -314,7 +314,7 @@ brcmf_create_bsscfg(s32 bsscfgidx, char *name, char *data, u32 datalen,
return brcmf_create_iovar(name, data, datalen, buf, buflen);
prefixlen = strlen(prefix);
- namelen = strlen(name) + 1; /* lengh of iovar name + null */
+ namelen = strlen(name) + 1; /* length of iovar name + null */
iolen = prefixlen + namelen + sizeof(bsscfgidx_le) + datalen;
if (buflen < iolen) {
--
2.18.0
^ permalink raw reply related
* [PATCH] wireless: fix intel typos in code comments
From: Weitao Hou @ 2019-05-19 3:31 UTC (permalink / raw)
To: stas.yakovlev, kvalo, davem
Cc: linux-wireless, netdev, linux-kernel, Weitao Hou
fix lengh to length
Signed-off-by: Weitao Hou <houweitaoo@gmail.com>
---
drivers/net/wireless/intel/ipw2x00/ipw2200.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
index fa400f92d7e2..807b2c11215a 100644
--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
@@ -774,7 +774,7 @@ static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, u32 * len)
*
* This table consist of six values, each containing
* - dword containing the starting offset of the data
- * - dword containing the lengh in the first 16bits
+ * - dword containing the length in the first 16bits
* and the count in the second 16bits
*/
--
2.18.0
^ permalink raw reply related
* [PATCH] net: fix typos in code comments
From: Weitao Hou @ 2019-05-19 3:09 UTC (permalink / raw)
To: nbd, lorenzo.bianconi83, ryder.lee, royluo, kvalo, davem,
matthias.bgg
Cc: linux-wireless, netdev, linux-arm-kernel, linux-mediatek,
linux-kernel, Weitao Hou
fix lenght to length
Signed-off-by: Weitao Hou <houweitaoo@gmail.com>
---
drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
index 6b89f7eab26c..e0f5e6202a27 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
@@ -53,7 +53,7 @@ int mt76x02u_skb_dma_info(struct sk_buff *skb, int port, u32 flags)
pad = round_up(skb->len, 4) + 4 - skb->len;
/* First packet of a A-MSDU burst keeps track of the whole burst
- * length, need to update lenght of it and the last packet.
+ * length, need to update length of it and the last packet.
*/
skb_walk_frags(skb, iter) {
last = iter;
--
2.18.0
^ permalink raw reply related
* Re: [PATCH 1/3] brcmfmac: re-enable command decode in sdio_aos for BRCM 4354
From: Arend Van Spriel @ 2019-05-20 8:09 UTC (permalink / raw)
To: Douglas Anderson, Ulf Hansson, Kalle Valo, Adrian Hunter
Cc: linux-rockchip, Double Lo, briannorris, Madhan Mohan R, mka,
Wright Feng, Chi-Hsien Lin, brcm80211-dev-list.pdl, Franky Lin,
netdev, linux-wireless, linux-kernel, Hante Meuleman,
Naveen Gupta, brcm80211-dev-list, YueHaibing, David S. Miller
In-Reply-To: <20190517225420.176893-2-dianders@chromium.org>
On 5/18/2019 12:54 AM, Douglas Anderson wrote:
> In commit 29f6589140a1 ("brcmfmac: disable command decode in
> sdio_aos") we disabled something called "command decode in sdio_aos"
> for a whole bunch of Broadcom SDIO WiFi parts.
>
> After that patch landed I find that my kernel log on
> rk3288-veyron-minnie and rk3288-veyron-speedy is filled with:
> brcmfmac: brcmf_sdio_bus_sleep: error while changing bus sleep state -110
>
> This seems to happen every time the Broadcom WiFi transitions out of
> sleep mode. Reverting the part of the commit that affects the WiFi on
> my boards fixes the problem for me, so that's what this patch does.
This sounds very similar to the issue we had during integration of wifi
on rk3288 chromebooks years ago.
> Note that, in general, the justification in the original commit seemed
> a little weak. It looked like someone was testing on a SD card
> controller that would sometimes die if there were CRC errors on the
> bus. This used to happen back in early days of dw_mmc (the controller
> on my boards), but we fixed it. Disabling a feature on all boards
> just because one SD card controller is broken seems bad. ...so
> instead of just this patch possibly the right thing to do is to fully
> revert the original commit.
I am leaning towards a full revert, but let's wait for more background info.
Regards,
Arend
^ permalink raw reply
* Re: [PATCH 3/3] iwlwifi: add support for quz firmwares
From: Bjørn Mork @ 2019-05-20 8:42 UTC (permalink / raw)
To: Luca Coelho; +Cc: kvalo, linux-wireless, Luca Coelho
In-Reply-To: <20190322124744.17924-4-luca@coelho.fi>
Luca Coelho <luca@coelho.fi> writes:
> --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
> +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
> @@ -549,6 +549,7 @@ extern const struct iwl_cfg iwl22000_2ac_cfg_hr;
> extern const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb;
> extern const struct iwl_cfg iwl22000_2ac_cfg_jf;
> extern const struct iwl_cfg iwl_ax101_cfg_qu_hr;
> +extern const struct iwl_cfg iwl_ax101_cfg_quz_hr;
> extern const struct iwl_cfg iwl22000_2ax_cfg_hr;
> extern const struct iwl_cfg iwl_ax200_cfg_cc;
> extern const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0;
> diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
> index aea6d03e545a..e539bc94eff7 100644
> --- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
> +++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
> @@ -327,6 +327,7 @@ enum {
> #define CSR_HW_REV_TYPE_NONE (0x00001F0)
> #define CSR_HW_REV_TYPE_QNJ (0x0000360)
> #define CSR_HW_REV_TYPE_QNJ_B0 (0x0000364)
> +#define CSR_HW_REV_TYPE_QUZ (0x0000354)
> #define CSR_HW_REV_TYPE_HR_CDB (0x0000340)
> #define CSR_HW_REV_TYPE_SO (0x0000370)
> #define CSR_HW_REV_TYPE_TY (0x0000420)
> diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
> index 1d6f3053f233..79c1dc05f948 100644
> --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
> +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
> @@ -3543,6 +3543,10 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
> }
> } else if (cfg == &iwl_ax101_cfg_qu_hr) {
> if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
> + CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) &&
> + trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0) {
> + trans->cfg = &iwl22000_2ax_cfg_qnj_hr_b0;
> + } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
> CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR)) {
> trans->cfg = &iwl_ax101_cfg_qu_hr;
> } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
Did you intend to use CSR_HW_REV_TYPE_QUZ and iwl_cfg
iwl_ax101_cfg_quz_hr here, or am I misunderstanding something?
Must admit that I didn't actually read the code. Just happend to look
at this patch briefly while glancing through linux-wireless... Sorry if
I'just adding noise.
Bjørn
^ permalink raw reply
* [PATCH V5 1/8] mac80211: propagate HE operation info into ieee80211_sta
From: John Crispin @ 2019-05-20 8:55 UTC (permalink / raw)
To: Kalle Valo; +Cc: ath11k, linux-wireless, John Crispin, Shashidhar Lakkavalli
In-Reply-To: <20190520085508.5888-1-john@phrozen.org>
Upon a successful assoc a station shall store the content of the HE
operation element inside ieee80211_sta 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>
---
include/net/mac80211.h | 2 ++
net/mac80211/he.c | 14 ++++++++++++++
net/mac80211/ieee80211_i.h | 5 +++++
net/mac80211/mlme.c | 1 +
4 files changed, 22 insertions(+)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 112dc18c658f..ba4a16f87364 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1903,6 +1903,7 @@ struct ieee80211_sta_rates {
* @ht_cap: HT capabilities of this STA; restricted to our own capabilities
* @vht_cap: VHT capabilities of this STA; restricted to our own capabilities
* @he_cap: HE capabilities of this STA
+ * @he_operation: HE operation information of the AP we are connected to
* @max_rx_aggregation_subframes: maximal amount of frames in a single AMPDU
* that this station is allowed to transmit to us.
* Can be modified by driver.
@@ -1941,6 +1942,7 @@ struct ieee80211_sta {
struct ieee80211_sta_ht_cap ht_cap;
struct ieee80211_sta_vht_cap vht_cap;
struct ieee80211_sta_he_cap he_cap;
+ struct ieee80211_he_operation he_operation;
u16 max_rx_aggregation_subframes;
bool wme;
u8 uapsd_queues;
diff --git a/net/mac80211/he.c b/net/mac80211/he.c
index 769078ed5a12..62ef029e5c48 100644
--- a/net/mac80211/he.c
+++ b/net/mac80211/he.c
@@ -53,3 +53,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_sta_he_op(struct ieee80211_sub_if_data *sdata,
+ const struct ieee80211_he_operation *he_op_ie_elem,
+ struct sta_info *sta)
+{
+ struct ieee80211_he_operation *he_operation = &sta->sta.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 e170f986d226..11bc1778bfd5 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1870,6 +1870,11 @@ 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_sta_he_op(struct ieee80211_sub_if_data *sdata,
+ const struct ieee80211_he_operation *he_op_ie_elem,
+ struct sta_info *sta);
+
/* 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 2dbcf5d5512e..5d8a8a0feaf9 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3364,6 +3364,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_sta_he_op(sdata, elems.he_operation, sta);
/* TODO: OPEN: what happens if BSS color disable is set? */
}
--
2.20.1
^ permalink raw reply related
* [PATCH V5 3/8] ath11k: move phymode selection from function to array lookup
From: John Crispin @ 2019-05-20 8:55 UTC (permalink / raw)
To: Kalle Valo; +Cc: ath11k, linux-wireless, John Crispin, Shashidhar Lakkavalli
In-Reply-To: <20190520085508.5888-1-john@phrozen.org>
With HE support getting added, the approach of using functions will quickly
get convoluted. Change the code to use an array lookup function instead.
Signed-off-by: Shashidhar Lakkavalli <slakkavalli@datto.com>
Signed-off-by: John Crispin <john@phrozen.org>
---
drivers/net/wireless/ath/ath11k/mac.c | 117 ++++++++++++--------------
include/uapi/linux/nl80211.h | 4 +
2 files changed, 57 insertions(+), 64 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index cb0de8e2aa60..c5a55fb893ae 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -105,6 +105,52 @@ static struct ieee80211_rate ath11k_legacy_rates[] = {
{ .bitrate = 540, .hw_value = ATH11K_HW_RATE_OFDM_54M },
};
+static const int
+ath11k_phymodes[NUM_NL80211_BANDS][2][__NL80211_CHAN_WIDTH_NUM] = {
+ [NL80211_BAND_2GHZ] = {
+ {
+ [NL80211_CHAN_WIDTH_5] = MODE_UNKNOWN,
+ [NL80211_CHAN_WIDTH_10] = MODE_UNKNOWN,
+ [NL80211_CHAN_WIDTH_20_NOHT] = MODE_11G,
+ [NL80211_CHAN_WIDTH_20] = MODE_11NG_HT20,
+ [NL80211_CHAN_WIDTH_40] = MODE_11NG_HT40,
+ [NL80211_CHAN_WIDTH_80] = MODE_UNKNOWN,
+ [NL80211_CHAN_WIDTH_80P80] = MODE_UNKNOWN,
+ [NL80211_CHAN_WIDTH_160] = MODE_UNKNOWN,
+ }, {
+ [NL80211_CHAN_WIDTH_5] = MODE_UNKNOWN,
+ [NL80211_CHAN_WIDTH_10] = MODE_UNKNOWN,
+ [NL80211_CHAN_WIDTH_20_NOHT] = MODE_11G,
+ [NL80211_CHAN_WIDTH_20] = MODE_11AX_HE20_2G,
+ [NL80211_CHAN_WIDTH_40] = MODE_11AX_HE40_2G,
+ [NL80211_CHAN_WIDTH_80] = MODE_11AX_HE80_2G,
+ [NL80211_CHAN_WIDTH_80P80] = MODE_UNKNOWN,
+ [NL80211_CHAN_WIDTH_160] = MODE_UNKNOWN,
+ },
+ },
+ [NL80211_BAND_5GHZ] = {
+ {
+ [NL80211_CHAN_WIDTH_5] = MODE_UNKNOWN,
+ [NL80211_CHAN_WIDTH_10] = MODE_UNKNOWN,
+ [NL80211_CHAN_WIDTH_20_NOHT] = MODE_11A,
+ [NL80211_CHAN_WIDTH_20] = MODE_11AC_VHT20,
+ [NL80211_CHAN_WIDTH_40] = MODE_11AC_VHT40,
+ [NL80211_CHAN_WIDTH_80] = MODE_11AC_VHT80,
+ [NL80211_CHAN_WIDTH_160] = MODE_11AC_VHT160,
+ [NL80211_CHAN_WIDTH_80P80] = MODE_11AC_VHT80_80,
+ }, {
+ [NL80211_CHAN_WIDTH_5] = MODE_UNKNOWN,
+ [NL80211_CHAN_WIDTH_10] = MODE_UNKNOWN,
+ [NL80211_CHAN_WIDTH_20_NOHT] = MODE_11A,
+ [NL80211_CHAN_WIDTH_20] = MODE_11AX_HE20,
+ [NL80211_CHAN_WIDTH_40] = MODE_11AX_HE40,
+ [NL80211_CHAN_WIDTH_80] = MODE_11AX_HE80,
+ [NL80211_CHAN_WIDTH_160] = MODE_11AX_HE160,
+ [NL80211_CHAN_WIDTH_80P80] = MODE_11AX_HE80_80,
+ },
+ },
+};
+
#define ATH11K_MAC_FIRST_OFDM_RATE_IDX 4
#define ath11k_g_rates ath11k_legacy_rates
#define ath11k_g_rates_size (ARRAY_SIZE(ath11k_legacy_rates))
@@ -151,69 +197,6 @@ static int get_num_chains(u32 mask)
return num_chains;
}
-static inline enum wmi_phy_mode
-chan_to_phymode(const struct cfg80211_chan_def *chandef)
-{
- enum wmi_phy_mode phymode = MODE_UNKNOWN;
-
- switch (chandef->chan->band) {
- case NL80211_BAND_2GHZ:
- switch (chandef->width) {
- case NL80211_CHAN_WIDTH_20_NOHT:
- if (chandef->chan->flags & IEEE80211_CHAN_NO_OFDM)
- phymode = MODE_11B;
- else
- phymode = MODE_11G;
- break;
- case NL80211_CHAN_WIDTH_20:
- phymode = MODE_11NG_HT20;
- break;
- case NL80211_CHAN_WIDTH_40:
- phymode = MODE_11NG_HT40;
- break;
- case NL80211_CHAN_WIDTH_5:
- case NL80211_CHAN_WIDTH_10:
- case NL80211_CHAN_WIDTH_80:
- case NL80211_CHAN_WIDTH_80P80:
- case NL80211_CHAN_WIDTH_160:
- phymode = MODE_UNKNOWN;
- break;
- }
- break;
- case NL80211_BAND_5GHZ:
- switch (chandef->width) {
- case NL80211_CHAN_WIDTH_20_NOHT:
- phymode = MODE_11A;
- break;
- case NL80211_CHAN_WIDTH_20:
- phymode = MODE_11AC_VHT20;
- break;
- case NL80211_CHAN_WIDTH_40:
- phymode = MODE_11AC_VHT40;
- break;
- case NL80211_CHAN_WIDTH_80:
- phymode = MODE_11AC_VHT80;
- break;
- case NL80211_CHAN_WIDTH_160:
- phymode = MODE_11AC_VHT160;
- break;
- case NL80211_CHAN_WIDTH_80P80:
- phymode = MODE_11AC_VHT80_80;
- break;
- case NL80211_CHAN_WIDTH_5:
- case NL80211_CHAN_WIDTH_10:
- phymode = MODE_UNKNOWN;
- break;
- }
- break;
- default:
- break;
- }
-
- WARN_ON(phymode == MODE_UNKNOWN);
- return phymode;
-}
-
u8 ath11k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband,
u32 bitrate)
{
@@ -3881,6 +3864,7 @@ ath11k_mac_vdev_start_restart(struct ath11k_vif *arvif,
struct ath11k_base *ab = ar->ab;
struct wmi_vdev_start_req_arg arg = {};
int ret = 0;
+ int he_support = arvif->vif->bss_conf.he_support;
lockdep_assert_held(&ar->conf_mutex);
@@ -3893,7 +3877,12 @@ ath11k_mac_vdev_start_restart(struct ath11k_vif *arvif,
arg.channel.freq = chandef->chan->center_freq;
arg.channel.band_center_freq1 = chandef->center_freq1;
arg.channel.band_center_freq2 = chandef->center_freq2;
- arg.channel.mode = chan_to_phymode(chandef);
+ arg.channel.mode =
+ ath11k_phymodes[chandef->chan->band][he_support][chandef->width];
+ if (arg.channel.mode == MODE_11G &&
+ chandef->chan->flags & IEEE80211_CHAN_NO_OFDM)
+ arg.channel.mode = MODE_11B;
+ WARN_ON(arg.channel.mode == MODE_UNKNOWN);
arg.channel.min_power = 0;
arg.channel.max_power = chandef->chan->max_power * 2;
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index dd4f86ee286e..b6e29161ec8b 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -4162,6 +4162,10 @@ enum nl80211_chan_width {
NL80211_CHAN_WIDTH_160,
NL80211_CHAN_WIDTH_5,
NL80211_CHAN_WIDTH_10,
+
+ /* keep last */
+ __NL80211_CHAN_WIDTH_NUM,
+ NL80211_CHAN_WIDTH_MAX = __NL80211_CHAN_WIDTH_NUM - 1,
};
/**
--
2.20.1
^ permalink raw reply related
* [PATCH V5 4/8] ath11k: add HE handling to the debug code
From: John Crispin @ 2019-05-20 8:55 UTC (permalink / raw)
To: Kalle Valo; +Cc: ath11k, linux-wireless, John Crispin, Shashidhar Lakkavalli
In-Reply-To: <20190520085508.5888-1-john@phrozen.org>
This patch allows the driver to also show the HE counters and stats.
Also extend the appropriate debug prints with HE info.
Signed-off-by: Shashidhar Lakkavalli <slakkavalli@datto.com>
Signed-off-by: John Crispin <john@phrozen.org>
---
drivers/net/wireless/ath/ath11k/core.h | 2 ++
drivers/net/wireless/ath/ath11k/debugfs_sta.c | 24 +++++++++++++++++--
drivers/net/wireless/ath/ath11k/dp_rx.c | 3 ++-
3 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
index 148c9a4c0978..994170e08cc5 100644
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -253,6 +253,7 @@ struct ath11k_peer {
struct dp_rx_tid rx_tid[IEEE80211_NUM_TIDS + 1];
};
+#define ATH11K_HE_MCS_NUM 12
#define ATH11K_VHT_MCS_NUM 10
#define ATH11K_BW_NUM 4
#define ATH11K_NSS_NUM 4
@@ -306,6 +307,7 @@ struct ath11k_htt_data_stats {
u64 legacy[ATH11K_COUNTER_TYPE_MAX][ATH11K_LEGACY_NUM];
u64 ht[ATH11K_COUNTER_TYPE_MAX][ATH11K_HT_MCS_NUM];
u64 vht[ATH11K_COUNTER_TYPE_MAX][ATH11K_VHT_MCS_NUM];
+ u64 he[ATH11K_COUNTER_TYPE_MAX][ATH11K_HE_MCS_NUM];
u64 bw[ATH11K_COUNTER_TYPE_MAX][ATH11K_BW_NUM];
u64 nss[ATH11K_COUNTER_TYPE_MAX][ATH11K_NSS_NUM];
u64 gi[ATH11K_COUNTER_TYPE_MAX][ATH11K_GI_NUM];
diff --git a/drivers/net/wireless/ath/ath11k/debugfs_sta.c b/drivers/net/wireless/ath/ath11k/debugfs_sta.c
index c39b6e1d22c3..cff6a3f048ea 100644
--- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c
+++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c
@@ -45,7 +45,14 @@ ath11k_accumulate_per_peer_tx_stats(struct ath11k_sta *arsta,
#define STATS_OP_FMT(name) tx_stats->stats[ATH11K_STATS_TYPE_##name]
- if (txrate->flags & RATE_INFO_FLAGS_VHT_MCS) {
+ if (txrate->flags & RATE_INFO_FLAGS_HE_MCS) {
+ STATS_OP_FMT(SUCC).he[0][mcs] += peer_stats->succ_bytes;
+ STATS_OP_FMT(SUCC).he[1][mcs] += peer_stats->succ_pkts;
+ STATS_OP_FMT(FAIL).he[0][mcs] += peer_stats->failed_bytes;
+ STATS_OP_FMT(FAIL).he[1][mcs] += peer_stats->failed_pkts;
+ STATS_OP_FMT(RETRY).he[0][mcs] += peer_stats->retry_bytes;
+ STATS_OP_FMT(RETRY).he[1][mcs] += peer_stats->retry_pkts;
+ } else if (txrate->flags & RATE_INFO_FLAGS_VHT_MCS) {
STATS_OP_FMT(SUCC).vht[0][mcs] += peer_stats->succ_bytes;
STATS_OP_FMT(SUCC).vht[1][mcs] += peer_stats->succ_pkts;
STATS_OP_FMT(FAIL).vht[0][mcs] += peer_stats->failed_bytes;
@@ -73,7 +80,12 @@ ath11k_accumulate_per_peer_tx_stats(struct ath11k_sta *arsta,
if (peer_stats->is_ampdu) {
tx_stats->ba_fails += peer_stats->ba_fails;
- if (txrate->flags & RATE_INFO_FLAGS_MCS) {
+ if (txrate->flags & RATE_INFO_FLAGS_HE_MCS) {
+ STATS_OP_FMT(AMPDU).he[0][mcs] +=
+ peer_stats->succ_bytes + peer_stats->retry_bytes;
+ STATS_OP_FMT(AMPDU).he[1][mcs] +=
+ peer_stats->succ_pkts + peer_stats->retry_pkts;
+ } else if (txrate->flags & RATE_INFO_FLAGS_MCS) {
STATS_OP_FMT(AMPDU).ht[0][mcs] +=
peer_stats->succ_bytes + peer_stats->retry_bytes;
STATS_OP_FMT(AMPDU).ht[1][mcs] +=
@@ -229,6 +241,14 @@ static ssize_t ath11k_dbg_sta_dump_tx_stats(struct file *file,
len += scnprintf(buf + len, size - len, "%s_%s\n",
str_name[k],
str[j]);
+ len += scnprintf(buf + len, size - len,
+ " HE MCS %s\n",
+ str[j]);
+ for (i = 0; i < ATH11K_HE_MCS_NUM; i++)
+ len += scnprintf(buf + len, size - len,
+ " %llu ",
+ stats->he[j][i]);
+ len += scnprintf(buf + len, size - len, "\n");
len += scnprintf(buf + len, size - len,
" VHT MCS %s\n",
str[j]);
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
index 73865ce2b3ab..62820c20f7c1 100644
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -1817,7 +1817,7 @@ static void ath11k_dp_rx_deliver_msdu(struct ath11k *ar, struct napi_struct *nap
status = IEEE80211_SKB_RXCB(msdu);
ath11k_dbg(ar->ab, ATH11K_DBG_DATA,
- "rx skb %pK len %u peer %pM %s %s sn %u %s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n",
+ "rx skb %pK len %u peer %pM %s %s sn %u %s%s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n",
msdu,
msdu->len,
ieee80211_get_SA(hdr),
@@ -1828,6 +1828,7 @@ static void ath11k_dp_rx_deliver_msdu(struct ath11k *ar, struct napi_struct *nap
(status->encoding == RX_ENC_LEGACY) ? "legacy" : "",
(status->encoding == RX_ENC_HT) ? "ht" : "",
(status->encoding == RX_ENC_VHT) ? "vht" : "",
+ (status->encoding == RX_ENC_HE) ? "he" : "",
(status->bw == RATE_INFO_BW_40) ? "40" : "",
(status->bw == RATE_INFO_BW_80) ? "80" : "",
(status->bw == RATE_INFO_BW_160) ? "160" : "",
--
2.20.1
^ permalink raw reply related
* [PATCH V5 7/8] ath11k: handle rx status for HE frames
From: John Crispin @ 2019-05-20 8:55 UTC (permalink / raw)
To: Kalle Valo; +Cc: ath11k, linux-wireless, John Crispin, Shashidhar Lakkavalli
In-Reply-To: <20190520085508.5888-1-john@phrozen.org>
The case clause handling HE frames was not handled yet in the code reading
the RX status. The new case is identical to VHT with the difference of the
higher maximum MCS rate.
Signed-off-by: Shashidhar Lakkavalli <slakkavalli@datto.com>
Signed-off-by: John Crispin <john@phrozen.org>
---
drivers/net/wireless/ath/ath11k/dp_rx.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
index e52a54cd2b79..71d385cf55d7 100644
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -1727,7 +1727,16 @@ static void ath11k_dp_rx_h_rate(struct ath11k *ar, void *rx_desc,
rx_status->bw = ath11k_bw_to_mac80211_bw(bw);
break;
case RX_MSDU_START_PKT_TYPE_11AX:
- ath11k_warn(ar->ab, "pkt_type %d not yet supported\n", pkt_type);
+ rx_status->rate_idx = rate_mcs;
+ if (rate_mcs > ATH11K_HE_MCS_MAX) {
+ ath11k_warn(ar->ab,
+ "Received with invalid mcs in HE mode %d\n",
+ rate_mcs);
+ break;
+ }
+ rx_status->encoding = RX_ENC_HE;
+ rx_status->nss = nss;
+ rx_status->bw = ath11k_bw_to_mac80211_bw(bw);
break;
}
}
--
2.20.1
^ permalink raw reply related
* [PATCH V5 5/8] ath11k: extend reading of FW capabilities
From: John Crispin @ 2019-05-20 8:55 UTC (permalink / raw)
To: Kalle Valo; +Cc: ath11k, linux-wireless, John Crispin, Shashidhar Lakkavalli
In-Reply-To: <20190520085508.5888-1-john@phrozen.org>
Read the additional mcs and extended mac capabilities field from the
service ready callback and store them inside the ath11k_pdev_cap
structure. This allows us to generate the sband_iftype_data dynamically.
Signed-off-by: Shashidhar Lakkavalli <slakkavalli@datto.com>
Signed-off-by: John Crispin <john@phrozen.org>
---
drivers/net/wireless/ath/ath11k/core.h | 3 ++-
drivers/net/wireless/ath/ath11k/wmi.c | 7 +++++--
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
index 994170e08cc5..a7c59ea0c228 100644
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -523,7 +523,7 @@ struct ath11k {
struct ath11k_band_cap {
u32 max_bw_supported;
u32 ht_cap_info;
- u32 he_cap_info;
+ u32 he_cap_info[2];
u32 he_mcs;
u32 he_cap_phy_info[PSOC_HOST_MAX_PHY_SIZE];
struct ath11k_ppe_threshold he_ppet;
@@ -534,6 +534,7 @@ struct ath11k_pdev_cap {
u32 ampdu_density;
u32 vht_cap;
u32 vht_mcs;
+ u32 he_mcs;
u32 tx_chain_mask;
u32 rx_chain_mask;
u32 tx_chain_mask_shift;
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
index 9ca44c4b24f8..807c42d5bb22 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -325,6 +325,7 @@ static int ath11k_pull_mac_phy_cap_service_ready_ext(
} else if (mac_phy_caps->supported_bands & WMI_HOST_WLAN_5G_CAP) {
pdev_cap->vht_cap = mac_phy_caps->vht_cap_info_5g;
pdev_cap->vht_mcs = mac_phy_caps->vht_supp_mcs_5g;
+ pdev_cap->he_mcs = mac_phy_caps->he_supp_mcs_5g;
pdev_cap->tx_chain_mask = mac_phy_caps->tx_chain_mask_5g;
pdev_cap->rx_chain_mask = mac_phy_caps->rx_chain_mask_5g;
} else {
@@ -347,7 +348,8 @@ static int ath11k_pull_mac_phy_cap_service_ready_ext(
cap_band = &pdev_cap->band[NL80211_BAND_2GHZ];
cap_band->max_bw_supported = mac_phy_caps->max_bw_supported_2g;
cap_band->ht_cap_info = mac_phy_caps->ht_cap_info_2g;
- cap_band->he_cap_info = mac_phy_caps->he_cap_info_2g;
+ cap_band->he_cap_info[0] = mac_phy_caps->he_cap_info_2g;
+ cap_band->he_cap_info[1] = mac_phy_caps->he_cap_info_2g_ext;
cap_band->he_mcs = mac_phy_caps->he_supp_mcs_2g;
memcpy(cap_band->he_cap_phy_info, &mac_phy_caps->he_cap_phy_info_2g,
sizeof(u32) * PSOC_HOST_MAX_PHY_SIZE);
@@ -357,7 +359,8 @@ static int ath11k_pull_mac_phy_cap_service_ready_ext(
cap_band = &pdev_cap->band[NL80211_BAND_5GHZ];
cap_band->max_bw_supported = mac_phy_caps->max_bw_supported_5g;
cap_band->ht_cap_info = mac_phy_caps->ht_cap_info_5g;
- cap_band->he_cap_info = mac_phy_caps->he_cap_info_5g;
+ cap_band->he_cap_info[0] = mac_phy_caps->he_cap_info_5g;
+ cap_band->he_cap_info[1] = mac_phy_caps->he_cap_info_5g_ext;
cap_band->he_mcs = mac_phy_caps->he_supp_mcs_5g;
memcpy(cap_band->he_cap_phy_info, &mac_phy_caps->he_cap_phy_info_5g,
sizeof(u32) * PSOC_HOST_MAX_PHY_SIZE);
--
2.20.1
^ permalink raw reply related
* [PATCH V5 8/8] ath11k: add HE support
From: John Crispin @ 2019-05-20 8:55 UTC (permalink / raw)
To: Kalle Valo; +Cc: ath11k, linux-wireless, John Crispin, Shashidhar Lakkavalli
In-Reply-To: <20190520085508.5888-1-john@phrozen.org>
Add basic HE support to the driver. The sband_iftype data is generated from
the capabilities read from the FW.
Signed-off-by: Shashidhar Lakkavalli <slakkavalli@datto.com>
Signed-off-by: John Crispin <john@phrozen.org>
---
drivers/net/wireless/ath/ath11k/core.h | 2 +
drivers/net/wireless/ath/ath11k/mac.c | 240 ++++++++++++++++++++++++-
drivers/net/wireless/ath/ath11k/reg.c | 1 +
drivers/net/wireless/ath/ath11k/wmi.c | 6 +-
drivers/net/wireless/ath/ath11k/wmi.h | 6 +-
5 files changed, 245 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
index d0d960b384e7..54b136a4d6e9 100644
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -443,6 +443,8 @@ struct ath11k {
struct {
struct ieee80211_supported_band sbands[NUM_NL80211_BANDS];
+ struct ieee80211_sband_iftype_data
+ iftype[NUM_NL80211_BANDS][NUM_NL80211_IFTYPES];
} mac;
unsigned long dev_flags;
unsigned int filter_flags;
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index c5a55fb893ae..b436e90f627a 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -1281,7 +1281,75 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar,
struct ieee80211_sta *sta,
struct peer_assoc_params *arg)
{
- /* TODO: Implementation */
+ const struct ieee80211_sta_he_cap *he_cap = &sta->he_cap;
+
+ if (!he_cap->has_he)
+ return;
+
+ arg->he_flag = true;
+
+ memcpy(&arg->peer_he_cap_macinfo, he_cap->he_cap_elem.mac_cap_info,
+ sizeof(arg->peer_he_cap_macinfo));
+ memcpy(&arg->peer_he_cap_phyinfo, he_cap->he_cap_elem.phy_cap_info,
+ sizeof(arg->peer_he_cap_phyinfo));
+ memcpy(&arg->peer_he_ops, &sta->he_operation, sizeof(arg->peer_he_ops));
+
+ if (he_cap->he_cap_elem.phy_cap_info[6] &
+ IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) {
+ int bit = 7;
+ int nss, ru;
+
+ arg->peer_ppet.numss_m1 = he_cap->ppe_thres[0] &
+ IEEE80211_PPE_THRES_NSS_MASK;
+ arg->peer_ppet.ru_bit_mask =
+ (he_cap->ppe_thres[0] &
+ IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK) >>
+ IEEE80211_PPE_THRES_RU_INDEX_BITMASK_POS;
+
+ for (nss = 0; nss <= arg->peer_ppet.numss_m1; nss++) {
+ for (ru = 0; ru < 4; ru++) {
+ u32 val = 0;
+ int i;
+
+ if ((arg->peer_ppet.ru_bit_mask & BIT(ru)) == 0)
+ continue;
+ for (i = 0; i < 6; i++) {
+ val >>= 1;
+ val |= ((he_cap->ppe_thres[bit / 8] >>
+ (bit % 8)) & 0x1) << 5;
+ bit++;
+ }
+ arg->peer_ppet.ppet16_ppet8_ru3_ru0[nss] |=
+ val << (ru * 6);
+ }
+ }
+ }
+
+ switch (sta->bandwidth) {
+ case IEEE80211_STA_RX_BW_160:
+ if (he_cap->he_cap_elem.phy_cap_info[0] &
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) {
+ arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80_80] =
+ he_cap->he_mcs_nss_supp.rx_mcs_80p80;
+ arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80_80] =
+ he_cap->he_mcs_nss_supp.tx_mcs_80p80;
+ arg->peer_he_mcs_count++;
+ }
+ arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] =
+ he_cap->he_mcs_nss_supp.rx_mcs_160;
+ arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] =
+ he_cap->he_mcs_nss_supp.tx_mcs_160;
+ arg->peer_he_mcs_count++;
+ /* drop through */
+
+ default:
+ arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] =
+ he_cap->he_mcs_nss_supp.rx_mcs_80;
+ arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] =
+ he_cap->he_mcs_nss_supp.tx_mcs_80;
+ arg->peer_he_mcs_count++;
+ break;
+ }
}
static void ath11k_peer_assoc_h_smps(struct ieee80211_sta *sta,
@@ -1448,6 +1516,32 @@ static enum wmi_phy_mode ath11k_mac_get_phymode_vht(struct ath11k *ar,
return MODE_UNKNOWN;
}
+static enum wmi_phy_mode ath11k_mac_get_phymode_he(struct ath11k *ar,
+ struct ieee80211_sta *sta)
+{
+ if (sta->bandwidth == IEEE80211_STA_RX_BW_160) {
+ if (sta->he_cap.he_cap_elem.phy_cap_info[0] &
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G)
+ return MODE_11AX_HE160;
+ else if (sta->he_cap.he_cap_elem.phy_cap_info[0] &
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
+ return MODE_11AX_HE80_80;
+ /* not sure if this is a valid case? */
+ return MODE_11AX_HE160;
+ }
+
+ if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
+ return MODE_11AX_HE80;
+
+ if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
+ return MODE_11AX_HE40;
+
+ if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
+ return MODE_11AX_HE20;
+
+ return MODE_UNKNOWN;
+}
+
static void ath11k_peer_assoc_h_phymode(struct ath11k *ar,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
@@ -1469,7 +1563,14 @@ static void ath11k_peer_assoc_h_phymode(struct ath11k *ar,
switch (band) {
case NL80211_BAND_2GHZ:
- if (sta->vht_cap.vht_supported &&
+ if (sta->he_cap.has_he) {
+ if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
+ phymode = MODE_11AX_HE80_2G;
+ else if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
+ phymode = MODE_11AX_HE40_2G;
+ else
+ phymode = MODE_11AX_HE20_2G;
+ } else if (sta->vht_cap.vht_supported &&
!ath11k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
phymode = MODE_11AC_VHT40;
@@ -1486,12 +1587,12 @@ static void ath11k_peer_assoc_h_phymode(struct ath11k *ar,
} else {
phymode = MODE_11B;
}
- /* TODO: HE */
-
break;
case NL80211_BAND_5GHZ:
- /* Check VHT first */
- if (sta->vht_cap.vht_supported &&
+ /* Check HE first */
+ if (sta->he_cap.has_he) {
+ phymode = ath11k_mac_get_phymode_he(ar, sta);
+ } else if (sta->vht_cap.vht_supported &&
!ath11k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
phymode = ath11k_mac_get_phymode_vht(ar, sta);
} else if (sta->ht_cap.ht_supported &&
@@ -1503,7 +1604,6 @@ static void ath11k_peer_assoc_h_phymode(struct ath11k *ar,
} else {
phymode = MODE_11A;
}
- /* TODO: HE Phymode */
break;
default:
break;
@@ -3077,6 +3177,128 @@ static int ath11k_check_chain_mask(struct ath11k *ar, u32 ant, bool is_tx_ant)
return 0;
}
+static void ath11k_gen_ppe_thresh(struct ath11k_ppe_threshold *fw_ppet,
+ u8 *he_ppet)
+{
+ int nss, ru;
+ u8 bit = 7;
+
+ he_ppet[0] = fw_ppet->numss_m1 & IEEE80211_PPE_THRES_NSS_MASK;
+ he_ppet[0] |= (fw_ppet->ru_bit_mask <<
+ IEEE80211_PPE_THRES_RU_INDEX_BITMASK_POS) &
+ IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK;
+ for (nss = 0; nss <= fw_ppet->numss_m1; nss++) {
+ for (ru = 0; ru < 4; ru++) {
+ u8 val;
+ int i;
+
+ if ((fw_ppet->ru_bit_mask & BIT(ru)) == 0)
+ continue;
+ val = (fw_ppet->ppet16_ppet8_ru3_ru0[nss] >> (ru * 6)) &
+ 0x3f;
+ val = ((val >> 3) & 0x7) | ((val & 0x7) << 3);
+ for (i = 5; i >= 0; i--) {
+ he_ppet[bit / 8] |=
+ ((val >> i) & 0x1) << ((bit % 8));
+ bit++;
+ }
+ }
+ }
+}
+
+static int ath11k_mac_copy_he_cap(struct ath11k_pdev_cap *cap,
+ struct ieee80211_sband_iftype_data *data,
+ int band)
+{
+ int i, idx = 0;
+
+ for (i = 0; i < NUM_NL80211_IFTYPES; i++) {
+ struct ieee80211_sta_he_cap *he_cap = &data[idx].he_cap;
+ struct ath11k_band_cap *band_cap = &cap->band[band];
+ struct ieee80211_he_cap_elem *he_cap_elem =
+ &he_cap->he_cap_elem;
+
+ switch (i) {
+ case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_AP:
+ break;
+
+ default:
+ continue;
+ }
+
+ data[idx].types_mask = BIT(i);
+ he_cap->has_he = true;
+ memcpy(he_cap_elem->mac_cap_info, band_cap->he_cap_info,
+ sizeof(he_cap_elem->mac_cap_info));
+ memcpy(he_cap_elem->phy_cap_info, band_cap->he_cap_phy_info,
+ sizeof(he_cap_elem->phy_cap_info));
+
+ he_cap_elem->mac_cap_info[1] |=
+ IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_MASK;
+ switch (i) {
+ case NL80211_IFTYPE_AP:
+ he_cap_elem->phy_cap_info[9] |=
+ IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU;
+ break;
+ case NL80211_IFTYPE_STATION:
+ he_cap_elem->mac_cap_info[0] &=
+ ~IEEE80211_HE_MAC_CAP0_TWT_RES;
+ he_cap_elem->mac_cap_info[0] |=
+ IEEE80211_HE_MAC_CAP0_TWT_REQ;
+ he_cap_elem->phy_cap_info[9] |=
+ IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU;
+ break;
+ }
+
+ he_cap->he_mcs_nss_supp.rx_mcs_80 =
+ cpu_to_le16(band_cap->he_mcs & 0xffff);
+ he_cap->he_mcs_nss_supp.tx_mcs_80 =
+ cpu_to_le16(band_cap->he_mcs & 0xffff);
+ he_cap->he_mcs_nss_supp.rx_mcs_160 =
+ cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
+ he_cap->he_mcs_nss_supp.tx_mcs_160 =
+ cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
+ he_cap->he_mcs_nss_supp.rx_mcs_80p80 =
+ cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
+ he_cap->he_mcs_nss_supp.tx_mcs_80p80 =
+ cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
+
+ memset(he_cap->ppe_thres, 0, sizeof(he_cap->ppe_thres));
+ if (he_cap_elem->phy_cap_info[6] &
+ IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT)
+ ath11k_gen_ppe_thresh(&band_cap->he_ppet, he_cap->ppe_thres);
+ idx++;
+ }
+
+ return idx;
+}
+
+static void ath11k_mac_setup_he_cap(struct ath11k *ar,
+ struct ath11k_pdev_cap *cap)
+{
+ struct ieee80211_supported_band *band = NULL;
+ int count = 0;
+
+ if (cap->supported_bands & WMI_HOST_WLAN_2G_CAP) {
+ count = ath11k_mac_copy_he_cap(cap,
+ ar->mac.iftype[NL80211_BAND_2GHZ],
+ NL80211_BAND_2GHZ);
+ band = &ar->mac.sbands[NL80211_BAND_2GHZ];
+ band->iftype_data = ar->mac.iftype[NL80211_BAND_2GHZ];
+ }
+
+ if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP) {
+ count = ath11k_mac_copy_he_cap(cap,
+ ar->mac.iftype[NL80211_BAND_5GHZ],
+ NL80211_BAND_5GHZ);
+ band = &ar->mac.sbands[NL80211_BAND_5GHZ];
+ band->iftype_data = ar->mac.iftype[NL80211_BAND_5GHZ];
+ }
+
+ band->n_iftype_data = count;
+}
+
static int __ath11k_set_antenna(struct ath11k *ar, u32 tx_ant, u32 rx_ant)
{
int ret;
@@ -3112,8 +3334,9 @@ static int __ath11k_set_antenna(struct ath11k *ar, u32 tx_ant, u32 rx_ant)
return ret;
}
- /* Reload HT/VHT capability */
+ /* Reload HT/VHT/HE capability */
ath11k_mac_setup_ht_vht_cap(ar, &ar->pdev->cap, NULL);
+ ath11k_mac_setup_he_cap(ar, &ar->pdev->cap);
return 0;
}
@@ -4976,6 +5199,7 @@ static int ath11k_mac_register(struct ath11k *ar)
goto err_free;
ath11k_mac_setup_ht_vht_cap(ar, cap, &ht_cap);
+ ath11k_mac_setup_he_cap(ar, cap);
ar->hw->wiphy->available_antennas_rx = cap->rx_chain_mask;
ar->hw->wiphy->available_antennas_tx = cap->tx_chain_mask;
diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c
index 1fef6886088f..d9ff9d631eea 100644
--- a/drivers/net/wireless/ath/ath11k/reg.c
+++ b/drivers/net/wireless/ath/ath11k/reg.c
@@ -138,6 +138,7 @@ int ath11k_reg_update_chan_list(struct ath11k *ar)
/* TODO: Set to true/false based on some condition? */
ch->allow_ht = true;
ch->allow_vht = true;
+ ch->allow_he = true;
ch->dfs_set =
!!(channel->flags & IEEE80211_CHAN_RADAR);
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
index 807c42d5bb22..05b955a9749f 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -741,6 +741,8 @@ static void ath11k_wmi_put_wmi_channel(struct wmi_channel *chan,
chan->info |= WMI_CHAN_INFO_ALLOW_HT;
if (arg->channel.allow_vht)
chan->info |= WMI_CHAN_INFO_ALLOW_VHT;
+ if (arg->channel.allow_he)
+ chan->info |= WMI_CHAN_INFO_ALLOW_HE;
if (arg->channel.ht40plus)
chan->info |= WMI_CHAN_INFO_HT40_PLUS;
if (arg->channel.chan_radar)
@@ -2193,7 +2195,9 @@ int ath11k_wmi_send_scan_chan_list_cmd(struct ath11k *ar,
if (tchan_info->is_chan_passive)
chan_info->info |= WMI_CHAN_INFO_PASSIVE;
- if (tchan_info->allow_vht)
+ if (tchan_info->allow_he)
+ chan_info->info |= WMI_CHAN_INFO_ALLOW_HE;
+ else if (tchan_info->allow_vht)
chan_info->info |= WMI_CHAN_INFO_ALLOW_VHT;
else if (tchan_info->allow_ht)
chan_info->info |= WMI_CHAN_INFO_ALLOW_HT;
diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
index 0fa33f38abdf..2e3e0cf866e9 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -2996,6 +2996,7 @@ struct channel_param {
is_chan_passive:1,
allow_ht:1,
allow_vht:1,
+ allow_he:1,
set_agile:1;
u32 phy_mode;
u32 cfreq1;
@@ -3841,7 +3842,10 @@ struct wmi_vdev_install_key_arg {
#define WMI_MAX_SUPPORTED_RATES 128
#define WMI_HOST_MAX_HECAP_PHY_SIZE 3
-#define WMI_HOST_MAX_HE_RATE_SET 1
+#define WMI_HOST_MAX_HE_RATE_SET 3
+#define WMI_HECAP_TXRX_MCS_NSS_IDX_80 0
+#define WMI_HECAP_TXRX_MCS_NSS_IDX_160 1
+#define WMI_HECAP_TXRX_MCS_NSS_IDX_80_80 2
struct wmi_rate_set_arg {
u32 num_rates;
--
2.20.1
^ permalink raw reply related
* [PATCH V5 2/8] ath11k: fix some whitespace errors
From: John Crispin @ 2019-05-20 8:55 UTC (permalink / raw)
To: Kalle Valo; +Cc: ath11k, linux-wireless, John Crispin, Shashidhar Lakkavalli
In-Reply-To: <20190520085508.5888-1-john@phrozen.org>
Signed-off-by: Shashidhar Lakkavalli <slakkavalli@datto.com>
Signed-off-by: John Crispin <john@phrozen.org>
---
drivers/net/wireless/ath/ath11k/wmi.h | 38 +++++++++++++--------------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
index 366a136e53ac..0fa33f38abdf 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -4139,28 +4139,28 @@ struct wmi_unit_test_cmd {
#define MAX_SUPPORTED_RATES 128
-#define WMI_PEER_AUTH 0x00000001
-#define WMI_PEER_QOS 0x00000002
-#define WMI_PEER_NEED_PTK_4_WAY 0x00000004
-#define WMI_PEER_NEED_GTK_2_WAY 0x00000010
-#define WMI_PEER_HE 0x00000400
-#define WMI_PEER_APSD 0x00000800
-#define WMI_PEER_HT 0x00001000
-#define WMI_PEER_40MHZ 0x00002000
-#define WMI_PEER_STBC 0x00008000
-#define WMI_PEER_LDPC 0x00010000
-#define WMI_PEER_DYN_MIMOPS 0x00020000
-#define WMI_PEER_STATIC_MIMOPS 0x00040000
-#define WMI_PEER_SPATIAL_MUX 0x00200000
-#define WMI_PEER_VHT 0x02000000
-#define WMI_PEER_80MHZ 0x04000000
-#define WMI_PEER_PMF 0x08000000
+#define WMI_PEER_AUTH 0x00000001
+#define WMI_PEER_QOS 0x00000002
+#define WMI_PEER_NEED_PTK_4_WAY 0x00000004
+#define WMI_PEER_NEED_GTK_2_WAY 0x00000010
+#define WMI_PEER_HE 0x00000400
+#define WMI_PEER_APSD 0x00000800
+#define WMI_PEER_HT 0x00001000
+#define WMI_PEER_40MHZ 0x00002000
+#define WMI_PEER_STBC 0x00008000
+#define WMI_PEER_LDPC 0x00010000
+#define WMI_PEER_DYN_MIMOPS 0x00020000
+#define WMI_PEER_STATIC_MIMOPS 0x00040000
+#define WMI_PEER_SPATIAL_MUX 0x00200000
+#define WMI_PEER_VHT 0x02000000
+#define WMI_PEER_80MHZ 0x04000000
+#define WMI_PEER_PMF 0x08000000
/* TODO: Place holder for WLAN_PEER_F_PS_PRESEND_REQUIRED = 0x10000000.
* Need to be cleaned up
*/
-#define WMI_PEER_IS_P2P_CAPABLE 0x20000000
-#define WMI_PEER_160MHZ 0x40000000
-#define WMI_PEER_SAFEMODE_EN 0x80000000
+#define WMI_PEER_IS_P2P_CAPABLE 0x20000000
+#define WMI_PEER_160MHZ 0x40000000
+#define WMI_PEER_SAFEMODE_EN 0x80000000
struct beacon_tmpl_params {
u8 vdev_id;
--
2.20.1
^ permalink raw reply related
* [PATCH V5 0/8] ath11k: add HE support
From: John Crispin @ 2019-05-20 8:55 UTC (permalink / raw)
To: Kalle Valo; +Cc: ath11k, linux-wireless, John Crispin
This series adds initial support for HE mode to the ath11k driver.
Things that still need to implemented
* ppe_threshold support
Changes in V2:
* generate sband_iftype data from FW provided capabilities
* properly handle rx_status for HE frames
* fix regression in basic VHF phymode
* various minor cleanups
Changes in V3
* make the he_cap generating code future-proof
* move phymode lookup to an array
Changes in V4
* remove dependency in local patch
Changes in V5
* populate he_oper field when preparing peer assoc
* populate ppet field when preparing peer assoc
* fix 80p80 phymode when preparing peer assoc
* address review comments
John Crispin (8):
mac80211: propagate HE operation info into ieee80211_sta
ath11k: fix some whitespace errors
ath11k: move phymode selection from function to array lookup
ath11k: add HE handling to the debug code
ath11k: extend reading of FW capabilities
ath11k: add defines for max MCS rates per phymode
ath11k: handle rx status for HE frames
ath11k: add HE support
drivers/net/wireless/ath/ath11k/core.h | 11 +-
drivers/net/wireless/ath/ath11k/debugfs_sta.c | 24 +-
drivers/net/wireless/ath/ath11k/dp_rx.c | 18 +-
drivers/net/wireless/ath/ath11k/mac.c | 357 ++++++++++++++----
drivers/net/wireless/ath/ath11k/reg.c | 1 +
drivers/net/wireless/ath/ath11k/wmi.c | 13 +-
drivers/net/wireless/ath/ath11k/wmi.h | 44 ++-
include/net/mac80211.h | 2 +
include/uapi/linux/nl80211.h | 4 +
net/mac80211/he.c | 14 +
net/mac80211/ieee80211_i.h | 5 +
net/mac80211/mlme.c | 1 +
12 files changed, 392 insertions(+), 102 deletions(-)
--
2.20.1
^ permalink raw reply
* [PATCH V5 6/8] ath11k: add defines for max MCS rates per phymode
From: John Crispin @ 2019-05-20 8:55 UTC (permalink / raw)
To: Kalle Valo; +Cc: ath11k, linux-wireless, John Crispin
In-Reply-To: <20190520085508.5888-1-john@phrozen.org>
Signed-off-by: John Crispin <john@phrozen.org>
---
drivers/net/wireless/ath/ath11k/core.h | 4 ++++
drivers/net/wireless/ath/ath11k/dp_rx.c | 4 ++--
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
index a7c59ea0c228..d0d960b384e7 100644
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -46,6 +46,10 @@ enum wme_ac {
WME_NUM_AC
};
+#define ATH11K_HT_MCS_MAX 7
+#define ATH11K_VHT_MCS_MAX 9
+#define ATH11K_HE_MCS_MAX 11
+
static inline enum wme_ac ath11k_tid_to_ac(u32 tid)
{
return (((tid == 0) || (tid == 3)) ? WME_AC_BE :
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
index 62820c20f7c1..e52a54cd2b79 100644
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -1705,7 +1705,7 @@ static void ath11k_dp_rx_h_rate(struct ath11k *ar, void *rx_desc,
break;
case RX_MSDU_START_PKT_TYPE_11N:
rx_status->encoding = RX_ENC_HT;
- if (rate_mcs > 7) {
+ if (rate_mcs > ATH11K_HT_MCS_MAX) {
ath11k_warn(ar->ab, "Received with invalid mcs in HT mode %d\n", rate_mcs);
break;
}
@@ -1717,7 +1717,7 @@ static void ath11k_dp_rx_h_rate(struct ath11k *ar, void *rx_desc,
case RX_MSDU_START_PKT_TYPE_11AC:
rx_status->encoding = RX_ENC_VHT;
rx_status->rate_idx = rate_mcs;
- if (rate_mcs > 9) {
+ if (rate_mcs > ATH11K_VHT_MCS_MAX) {
ath11k_warn(ar->ab, "Received with invalid mcs in VHT mode %d\n", rate_mcs);
break;
}
--
2.20.1
^ permalink raw reply related
* Re: [PATCH 0/3] brcmfmac: sdio: Deal better w/ transmission errors waking from sleep
From: Arend Van Spriel @ 2019-05-20 8:55 UTC (permalink / raw)
To: Douglas Anderson, Ulf Hansson, Kalle Valo, Adrian Hunter
Cc: linux-rockchip, Double Lo, briannorris, Madhan Mohan R, mka,
Wright Feng, Chi-Hsien Lin, linux-mmc, Shawn Lin,
brcm80211-dev-list, YueHaibing, Hante Meuleman, Martin Hicks,
Ritesh Harjani, Michael Trimarchi, Wolfram Sang, Franky Lin,
Jiong Wu, brcm80211-dev-list.pdl, David S. Miller, netdev,
linux-wireless, linux-kernel, Naveen Gupta, Avri Altman
In-Reply-To: <20190517225420.176893-1-dianders@chromium.org>
On 5/18/2019 12:54 AM, Douglas Anderson wrote:
> This series attempts to deal better with the expected transmission
> errors that we get when waking up the SDIO-based WiFi on
> rk3288-veyron-minnie, rk3288-veyron-speedy, and rk3288-veyron-mickey.
>
> Some details about those errors can be found in
> <https://crbug.com/960222>, but to summarize it here: if we try to
> send the wakeup command to the WiFi card at the same time it has
> decided to wake up itself then it will behave badly on the SDIO bus.
> This can cause timeouts or CRC errors.
>
> When I tested on 4.19 and 4.20 these CRC errors can be seen to cause
> re-tuning. Since I am currently developing on 4.19 this was the
> original problem I attempted to solve.
>
> On mainline it turns out that you don't see the retuning errors but
> you see tons of spam about timeouts trying to wakeup from sleep. I
> tracked down the commit that was causing that and have partially
> reverted it here. I have no real knowledge about Broadcom WiFi, but
> the commit that was causing problems sounds (from the descriptioin) to
> be a hack commit penalizing all Broadcom WiFi users because of a bug
> in a Cypress SD controller. I will let others comment if this is
> truly the case and, if so, what the right solution should be.
Let me give a bit of background. The brcmfmac driver implements its own
runtime-pm like functionality, ie. if the driver is idle for some time
it will put the device in a low-power state. When it does that it powers
down several cores in the chip among which the SDIO core. However, the
SDIO bus used be very bad at handling devices that do that so instead it
has the Always-On-Station (AOS) block take over the SDIO core in
handling the bus. Default is will send a R1 response, but only for CMD52
(and CMD14 but no host is using that cruft). In noCmdDecode it does not
respond and simply wakes up the SDIO core, which takes over again.
Because it does not respond timeouts (-110) are kinda expected in this mode.
Regards,
Arend
^ 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