diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-08-06 12:15:09 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-08-08 07:52:01 +0200 |
commit | 71ed79b0e4be0db254640c3beb9a1a0316eb5f61 (patch) | |
tree | aac2f4f0527802478b29c2e7897e56994b6ad759 /drivers | |
parent | 7d9c1d2f7aca2651b3821947bf928ee131df102a (diff) | |
download | linux-71ed79b0e4be0db254640c3beb9a1a0316eb5f61.tar.bz2 |
USB: Move wusbcore and UWB to staging as it is obsolete
The UWB and wusbcore code is long obsolete, so let us just move the code
out of the real part of the kernel and into the drivers/staging/
location with plans to remove it entirely in a few releases.
Link: https://lore.kernel.org/r/20190806101509.GA11280@kroah.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/Kconfig | 2 | ||||
-rw-r--r-- | drivers/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/Kconfig | 3 | ||||
-rw-r--r-- | drivers/staging/Makefile | 2 | ||||
-rw-r--r-- | drivers/staging/uwb/Kconfig (renamed from drivers/uwb/Kconfig) | 0 | ||||
-rw-r--r-- | drivers/staging/uwb/Makefile (renamed from drivers/uwb/Makefile) | 0 | ||||
-rw-r--r-- | drivers/staging/uwb/TODO | 8 | ||||
-rw-r--r-- | drivers/staging/uwb/address.c (renamed from drivers/uwb/address.c) | 0 | ||||
-rw-r--r-- | drivers/staging/uwb/allocator.c (renamed from drivers/uwb/allocator.c) | 2 | ||||
-rw-r--r-- | drivers/staging/uwb/beacon.c (renamed from drivers/uwb/beacon.c) | 0 | ||||
-rw-r--r-- | drivers/staging/uwb/driver.c (renamed from drivers/uwb/driver.c) | 0 | ||||
-rw-r--r-- | drivers/staging/uwb/drp-avail.c (renamed from drivers/uwb/drp-avail.c) | 0 | ||||
-rw-r--r-- | drivers/staging/uwb/drp-ie.c (renamed from drivers/uwb/drp-ie.c) | 2 | ||||
-rw-r--r-- | drivers/staging/uwb/drp.c (renamed from drivers/uwb/drp.c) | 0 | ||||
-rw-r--r-- | drivers/staging/uwb/est.c (renamed from drivers/uwb/est.c) | 0 | ||||
-rw-r--r-- | drivers/staging/uwb/hwa-rc.c (renamed from drivers/uwb/hwa-rc.c) | 6 | ||||
-rw-r--r-- | drivers/staging/uwb/i1480/Makefile (renamed from drivers/uwb/i1480/Makefile) | 0 | ||||
-rw-r--r-- | drivers/staging/uwb/i1480/dfu/Makefile (renamed from drivers/uwb/i1480/dfu/Makefile) | 0 | ||||
-rw-r--r-- | drivers/staging/uwb/i1480/dfu/dfu.c (renamed from drivers/uwb/i1480/dfu/dfu.c) | 2 | ||||
-rw-r--r-- | drivers/staging/uwb/i1480/dfu/i1480-dfu.h (renamed from drivers/uwb/i1480/dfu/i1480-dfu.h) | 2 | ||||
-rw-r--r-- | drivers/staging/uwb/i1480/dfu/mac.c (renamed from drivers/uwb/i1480/dfu/mac.c) | 2 | ||||
-rw-r--r-- | drivers/staging/uwb/i1480/dfu/phy.c (renamed from drivers/uwb/i1480/dfu/phy.c) | 2 | ||||
-rw-r--r-- | drivers/staging/uwb/i1480/dfu/usb.c (renamed from drivers/uwb/i1480/dfu/usb.c) | 6 | ||||
-rw-r--r-- | drivers/staging/uwb/i1480/i1480-est.c (renamed from drivers/uwb/i1480/i1480-est.c) | 2 | ||||
-rw-r--r-- | drivers/staging/uwb/ie-rcv.c (renamed from drivers/uwb/ie-rcv.c) | 0 | ||||
-rw-r--r-- | drivers/staging/uwb/ie.c (renamed from drivers/uwb/ie.c) | 0 | ||||
-rw-r--r-- | drivers/staging/uwb/include/debug-cmd.h | 57 | ||||
-rw-r--r-- | drivers/staging/uwb/include/spec.h | 767 | ||||
-rw-r--r-- | drivers/staging/uwb/include/umc.h | 192 | ||||
-rw-r--r-- | drivers/staging/uwb/include/whci.h | 102 | ||||
-rw-r--r-- | drivers/staging/uwb/lc-dev.c (renamed from drivers/uwb/lc-dev.c) | 0 | ||||
-rw-r--r-- | drivers/staging/uwb/lc-rc.c (renamed from drivers/uwb/lc-rc.c) | 0 | ||||
-rw-r--r-- | drivers/staging/uwb/neh.c (renamed from drivers/uwb/neh.c) | 0 | ||||
-rw-r--r-- | drivers/staging/uwb/pal.c (renamed from drivers/uwb/pal.c) | 2 | ||||
-rw-r--r-- | drivers/staging/uwb/radio.c (renamed from drivers/uwb/radio.c) | 2 | ||||
-rw-r--r-- | drivers/staging/uwb/reset.c (renamed from drivers/uwb/reset.c) | 0 | ||||
-rw-r--r-- | drivers/staging/uwb/rsv.c (renamed from drivers/uwb/rsv.c) | 2 | ||||
-rw-r--r-- | drivers/staging/uwb/scan.c (renamed from drivers/uwb/scan.c) | 0 | ||||
-rw-r--r-- | drivers/staging/uwb/umc-bus.c (renamed from drivers/uwb/umc-bus.c) | 2 | ||||
-rw-r--r-- | drivers/staging/uwb/umc-dev.c (renamed from drivers/uwb/umc-dev.c) | 2 | ||||
-rw-r--r-- | drivers/staging/uwb/umc-drv.c (renamed from drivers/uwb/umc-drv.c) | 2 | ||||
-rw-r--r-- | drivers/staging/uwb/uwb-debug.c (renamed from drivers/uwb/uwb-debug.c) | 3 | ||||
-rw-r--r-- | drivers/staging/uwb/uwb-internal.h (renamed from drivers/uwb/uwb-internal.h) | 2 | ||||
-rw-r--r-- | drivers/staging/uwb/uwb.h | 817 | ||||
-rw-r--r-- | drivers/staging/uwb/uwbd.c (renamed from drivers/uwb/uwbd.c) | 0 | ||||
-rw-r--r-- | drivers/staging/uwb/whc-rc.c (renamed from drivers/uwb/whc-rc.c) | 6 | ||||
-rw-r--r-- | drivers/staging/uwb/whci.c (renamed from drivers/uwb/whci.c) | 4 | ||||
-rw-r--r-- | drivers/staging/wusbcore/Documentation/wusb-cbaf | 130 | ||||
-rw-r--r-- | drivers/staging/wusbcore/Documentation/wusb-design-overview.rst | 457 | ||||
-rw-r--r-- | drivers/staging/wusbcore/Kconfig (renamed from drivers/usb/wusbcore/Kconfig) | 1 | ||||
-rw-r--r-- | drivers/staging/wusbcore/Makefile (renamed from drivers/usb/wusbcore/Makefile) | 2 | ||||
-rw-r--r-- | drivers/staging/wusbcore/TODO | 8 | ||||
-rw-r--r-- | drivers/staging/wusbcore/cbaf.c (renamed from drivers/usb/wusbcore/cbaf.c) | 6 | ||||
-rw-r--r-- | drivers/staging/wusbcore/crypto.c (renamed from drivers/usb/wusbcore/crypto.c) | 4 | ||||
-rw-r--r-- | drivers/staging/wusbcore/dev-sysfs.c (renamed from drivers/usb/wusbcore/dev-sysfs.c) | 0 | ||||
-rw-r--r-- | drivers/staging/wusbcore/devconnect.c (renamed from drivers/usb/wusbcore/devconnect.c) | 0 | ||||
-rw-r--r-- | drivers/staging/wusbcore/host/Kconfig | 28 | ||||
-rw-r--r-- | drivers/staging/wusbcore/host/Makefile | 3 | ||||
-rw-r--r-- | drivers/staging/wusbcore/host/hwa-hc.c (renamed from drivers/usb/host/hwa-hc.c) | 4 | ||||
-rw-r--r-- | drivers/staging/wusbcore/host/whci/Makefile (renamed from drivers/usb/host/whci/Makefile) | 0 | ||||
-rw-r--r-- | drivers/staging/wusbcore/host/whci/asl.c (renamed from drivers/usb/host/whci/asl.c) | 4 | ||||
-rw-r--r-- | drivers/staging/wusbcore/host/whci/debug.c (renamed from drivers/usb/host/whci/debug.c) | 2 | ||||
-rw-r--r-- | drivers/staging/wusbcore/host/whci/hcd.c (renamed from drivers/usb/host/whci/hcd.c) | 4 | ||||
-rw-r--r-- | drivers/staging/wusbcore/host/whci/hw.c (renamed from drivers/usb/host/whci/hw.c) | 4 | ||||
-rw-r--r-- | drivers/staging/wusbcore/host/whci/init.c (renamed from drivers/usb/host/whci/init.c) | 4 | ||||
-rw-r--r-- | drivers/staging/wusbcore/host/whci/int.c (renamed from drivers/usb/host/whci/int.c) | 4 | ||||
-rw-r--r-- | drivers/staging/wusbcore/host/whci/pzl.c (renamed from drivers/usb/host/whci/pzl.c) | 4 | ||||
-rw-r--r-- | drivers/staging/wusbcore/host/whci/qset.c (renamed from drivers/usb/host/whci/qset.c) | 4 | ||||
-rw-r--r-- | drivers/staging/wusbcore/host/whci/whcd.h (renamed from drivers/usb/host/whci/whcd.h) | 4 | ||||
-rw-r--r-- | drivers/staging/wusbcore/host/whci/whci-hc.h (renamed from drivers/usb/host/whci/whci-hc.h) | 0 | ||||
-rw-r--r-- | drivers/staging/wusbcore/host/whci/wusb.c (renamed from drivers/usb/host/whci/wusb.c) | 4 | ||||
-rw-r--r-- | drivers/staging/wusbcore/include/association.h | 151 | ||||
-rw-r--r-- | drivers/staging/wusbcore/include/wusb-wa.h | 304 | ||||
-rw-r--r-- | drivers/staging/wusbcore/include/wusb.h | 362 | ||||
-rw-r--r-- | drivers/staging/wusbcore/mmc.c (renamed from drivers/usb/wusbcore/mmc.c) | 2 | ||||
-rw-r--r-- | drivers/staging/wusbcore/pal.c (renamed from drivers/usb/wusbcore/pal.c) | 0 | ||||
-rw-r--r-- | drivers/staging/wusbcore/reservation.c (renamed from drivers/usb/wusbcore/reservation.c) | 2 | ||||
-rw-r--r-- | drivers/staging/wusbcore/rh.c (renamed from drivers/usb/wusbcore/rh.c) | 0 | ||||
-rw-r--r-- | drivers/staging/wusbcore/security.c (renamed from drivers/usb/wusbcore/security.c) | 0 | ||||
-rw-r--r-- | drivers/staging/wusbcore/wa-hc.c (renamed from drivers/usb/wusbcore/wa-hc.c) | 0 | ||||
-rw-r--r-- | drivers/staging/wusbcore/wa-hc.h (renamed from drivers/usb/wusbcore/wa-hc.h) | 6 | ||||
-rw-r--r-- | drivers/staging/wusbcore/wa-nep.c (renamed from drivers/usb/wusbcore/wa-nep.c) | 0 | ||||
-rw-r--r-- | drivers/staging/wusbcore/wa-rpipe.c (renamed from drivers/usb/wusbcore/wa-rpipe.c) | 0 | ||||
-rw-r--r-- | drivers/staging/wusbcore/wa-xfer.c (renamed from drivers/usb/wusbcore/wa-xfer.c) | 0 | ||||
-rw-r--r-- | drivers/staging/wusbcore/wusbhc.c (renamed from drivers/usb/wusbcore/wusbhc.c) | 0 | ||||
-rw-r--r-- | drivers/staging/wusbcore/wusbhc.h (renamed from drivers/usb/wusbcore/wusbhc.h) | 4 | ||||
-rw-r--r-- | drivers/usb/Kconfig | 2 | ||||
-rw-r--r-- | drivers/usb/Makefile | 2 | ||||
-rw-r--r-- | drivers/usb/host/Kconfig | 26 | ||||
-rw-r--r-- | drivers/usb/host/Makefile | 3 |
90 files changed, 3453 insertions, 96 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig index 61cf4ea2c229..e8852c09184b 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -108,8 +108,6 @@ source "drivers/hid/Kconfig" source "drivers/usb/Kconfig" -source "drivers/uwb/Kconfig" - source "drivers/mmc/Kconfig" source "drivers/memstick/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index 6d37564e783c..cf046e9bd88c 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -100,7 +100,6 @@ obj-$(CONFIG_ZORRO) += zorro/ obj-$(CONFIG_ATA_OVER_ETH) += block/aoe/ obj-$(CONFIG_PARIDE) += block/paride/ obj-$(CONFIG_TC) += tc/ -obj-$(CONFIG_UWB) += uwb/ obj-$(CONFIG_USB_PHY) += usb/ obj-$(CONFIG_USB) += usb/ obj-$(CONFIG_USB_SUPPORT) += usb/ diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 7c96a01eef6c..cf419d9c942d 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -120,4 +120,7 @@ source "drivers/staging/kpc2000/Kconfig" source "drivers/staging/isdn/Kconfig" +source "drivers/staging/wusbcore/Kconfig" +source "drivers/staging/uwb/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index fcaac9693b83..38179bc842a8 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -50,3 +50,5 @@ obj-$(CONFIG_EROFS_FS) += erofs/ obj-$(CONFIG_FIELDBUS_DEV) += fieldbus/ obj-$(CONFIG_KPC2000) += kpc2000/ obj-$(CONFIG_ISDN_CAPI) += isdn/ +obj-$(CONFIG_UWB) += uwb/ +obj-$(CONFIG_USB_WUSB) += wusbcore/ diff --git a/drivers/uwb/Kconfig b/drivers/staging/uwb/Kconfig index 259e053e1e09..259e053e1e09 100644 --- a/drivers/uwb/Kconfig +++ b/drivers/staging/uwb/Kconfig diff --git a/drivers/uwb/Makefile b/drivers/staging/uwb/Makefile index 32f4de7afbd6..32f4de7afbd6 100644 --- a/drivers/uwb/Makefile +++ b/drivers/staging/uwb/Makefile diff --git a/drivers/staging/uwb/TODO b/drivers/staging/uwb/TODO new file mode 100644 index 000000000000..abae57000534 --- /dev/null +++ b/drivers/staging/uwb/TODO @@ -0,0 +1,8 @@ +TODO: Remove in late 2019 unless there are users + +There seems to not be any real wireless USB devices anywhere in the wild +anymore. It turned out to be a failed technology :( + +This will be removed from the tree if no one objects. + +Greg Kroah-Hartman <gregkh@linuxfoundation.org> diff --git a/drivers/uwb/address.c b/drivers/staging/uwb/address.c index 857d5cd56a95..857d5cd56a95 100644 --- a/drivers/uwb/address.c +++ b/drivers/staging/uwb/address.c diff --git a/drivers/uwb/allocator.c b/drivers/staging/uwb/allocator.c index 2e1590124d5f..1f429fba20b7 100644 --- a/drivers/uwb/allocator.c +++ b/drivers/staging/uwb/allocator.c @@ -6,7 +6,7 @@ */ #include <linux/kernel.h> #include <linux/slab.h> -#include <linux/uwb.h> +#include "uwb.h" #include "uwb-internal.h" diff --git a/drivers/uwb/beacon.c b/drivers/staging/uwb/beacon.c index c483c19c5ef8..c483c19c5ef8 100644 --- a/drivers/uwb/beacon.c +++ b/drivers/staging/uwb/beacon.c diff --git a/drivers/uwb/driver.c b/drivers/staging/uwb/driver.c index 5755c2e49ffc..5755c2e49ffc 100644 --- a/drivers/uwb/driver.c +++ b/drivers/staging/uwb/driver.c diff --git a/drivers/uwb/drp-avail.c b/drivers/staging/uwb/drp-avail.c index 02392ab82a7d..02392ab82a7d 100644 --- a/drivers/uwb/drp-avail.c +++ b/drivers/staging/uwb/drp-avail.c diff --git a/drivers/uwb/drp-ie.c b/drivers/staging/uwb/drp-ie.c index 4b545b41161c..b2a862cf76de 100644 --- a/drivers/uwb/drp-ie.c +++ b/drivers/staging/uwb/drp-ie.c @@ -8,8 +8,8 @@ #include <linux/kernel.h> #include <linux/random.h> #include <linux/slab.h> -#include <linux/uwb.h> +#include "uwb.h" #include "uwb-internal.h" diff --git a/drivers/uwb/drp.c b/drivers/staging/uwb/drp.c index 869987bede7b..869987bede7b 100644 --- a/drivers/uwb/drp.c +++ b/drivers/staging/uwb/drp.c diff --git a/drivers/uwb/est.c b/drivers/staging/uwb/est.c index d4141ffdd775..d4141ffdd775 100644 --- a/drivers/uwb/est.c +++ b/drivers/staging/uwb/est.c diff --git a/drivers/uwb/hwa-rc.c b/drivers/staging/uwb/hwa-rc.c index cd03b7f827c1..b6effad749d7 100644 --- a/drivers/uwb/hwa-rc.c +++ b/drivers/staging/uwb/hwa-rc.c @@ -38,9 +38,9 @@ #include <linux/module.h> #include <linux/slab.h> #include <linux/usb.h> -#include <linux/usb/wusb.h> -#include <linux/usb/wusb-wa.h> -#include <linux/uwb.h> +#include "../wusbcore/include/wusb.h" +#include "../wusbcore/include/wusb-wa.h" +#include "uwb.h" #include "uwb-internal.h" diff --git a/drivers/uwb/i1480/Makefile b/drivers/staging/uwb/i1480/Makefile index d26fb9b845ae..d26fb9b845ae 100644 --- a/drivers/uwb/i1480/Makefile +++ b/drivers/staging/uwb/i1480/Makefile diff --git a/drivers/uwb/i1480/dfu/Makefile b/drivers/staging/uwb/i1480/dfu/Makefile index 4739fdac5922..4739fdac5922 100644 --- a/drivers/uwb/i1480/dfu/Makefile +++ b/drivers/staging/uwb/i1480/dfu/Makefile diff --git a/drivers/uwb/i1480/dfu/dfu.c b/drivers/staging/uwb/i1480/dfu/dfu.c index ec1af858ead9..9d51ce8faad1 100644 --- a/drivers/uwb/i1480/dfu/dfu.c +++ b/drivers/staging/uwb/i1480/dfu/dfu.c @@ -17,9 +17,9 @@ #include <linux/delay.h> #include <linux/pci.h> #include <linux/device.h> -#include <linux/uwb.h> #include <linux/random.h> #include <linux/export.h> +#include "../../uwb.h" /* * i1480_rceb_check - Check RCEB for expected field values diff --git a/drivers/uwb/i1480/dfu/i1480-dfu.h b/drivers/staging/uwb/i1480/dfu/i1480-dfu.h index 9dd567d174b3..b21d058ecc23 100644 --- a/drivers/uwb/i1480/dfu/i1480-dfu.h +++ b/drivers/staging/uwb/i1480/dfu/i1480-dfu.h @@ -50,9 +50,9 @@ #ifndef __i1480_DFU_H__ #define __i1480_DFU_H__ -#include <linux/uwb/spec.h> #include <linux/types.h> #include <linux/completion.h> +#include "../../include/spec.h" #define i1480_FW_UPLOAD_MODE_MASK (cpu_to_le32(0x00000018)) diff --git a/drivers/uwb/i1480/dfu/mac.c b/drivers/staging/uwb/i1480/dfu/mac.c index ddc224f01a7f..6e4d6c9cecf5 100644 --- a/drivers/uwb/i1480/dfu/mac.c +++ b/drivers/staging/uwb/i1480/dfu/mac.c @@ -15,7 +15,7 @@ #include <linux/delay.h> #include <linux/firmware.h> #include <linux/slab.h> -#include <linux/uwb.h> +#include "../../uwb.h" #include "i1480-dfu.h" /* diff --git a/drivers/uwb/i1480/dfu/phy.c b/drivers/staging/uwb/i1480/dfu/phy.c index 50da4527c113..13512c7dda0b 100644 --- a/drivers/uwb/i1480/dfu/phy.c +++ b/drivers/staging/uwb/i1480/dfu/phy.c @@ -15,7 +15,7 @@ #include <linux/delay.h> #include <linux/device.h> #include <linux/firmware.h> -#include <linux/usb/wusb.h> +#include "../../../wusbcore/include/wusb.h" #include "i1480-dfu.h" diff --git a/drivers/uwb/i1480/dfu/usb.c b/drivers/staging/uwb/i1480/dfu/usb.c index 6129a8f4b5f2..d41086bdd783 100644 --- a/drivers/uwb/i1480/dfu/usb.c +++ b/drivers/staging/uwb/i1480/dfu/usb.c @@ -25,9 +25,9 @@ #include <linux/interrupt.h> #include <linux/slab.h> #include <linux/delay.h> -#include <linux/uwb.h> -#include <linux/usb/wusb.h> -#include <linux/usb/wusb-wa.h> +#include "../../uwb.h" +#include "../../../wusbcore/include/wusb.h" +#include "../../../wusbcore/include/wusb-wa.h" #include "i1480-dfu.h" struct i1480_usb { diff --git a/drivers/uwb/i1480/i1480-est.c b/drivers/staging/uwb/i1480/i1480-est.c index 1346c409d10e..106e0a44b138 100644 --- a/drivers/uwb/i1480/i1480-est.c +++ b/drivers/staging/uwb/i1480/i1480-est.c @@ -12,7 +12,7 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/usb.h> -#include <linux/uwb.h> +#include "../uwb.h" #include "dfu/i1480-dfu.h" diff --git a/drivers/uwb/ie-rcv.c b/drivers/staging/uwb/ie-rcv.c index 51a4706e0dd3..51a4706e0dd3 100644 --- a/drivers/uwb/ie-rcv.c +++ b/drivers/staging/uwb/ie-rcv.c diff --git a/drivers/uwb/ie.c b/drivers/staging/uwb/ie.c index b11678dd0380..b11678dd0380 100644 --- a/drivers/uwb/ie.c +++ b/drivers/staging/uwb/ie.c diff --git a/drivers/staging/uwb/include/debug-cmd.h b/drivers/staging/uwb/include/debug-cmd.h new file mode 100644 index 000000000000..f97db6c3bcc0 --- /dev/null +++ b/drivers/staging/uwb/include/debug-cmd.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Ultra Wide Band + * Debug interface commands + * + * Copyright (C) 2008 Cambridge Silicon Radio Ltd. + */ +#ifndef __LINUX__UWB__DEBUG_CMD_H__ +#define __LINUX__UWB__DEBUG_CMD_H__ + +#include <linux/types.h> + +/* + * Debug interface commands + * + * UWB_DBG_CMD_RSV_ESTABLISH: Establish a new unicast reservation. + * + * UWB_DBG_CMD_RSV_TERMINATE: Terminate the Nth reservation. + */ + +enum uwb_dbg_cmd_type { + UWB_DBG_CMD_RSV_ESTABLISH = 1, + UWB_DBG_CMD_RSV_TERMINATE = 2, + UWB_DBG_CMD_IE_ADD = 3, + UWB_DBG_CMD_IE_RM = 4, + UWB_DBG_CMD_RADIO_START = 5, + UWB_DBG_CMD_RADIO_STOP = 6, +}; + +struct uwb_dbg_cmd_rsv_establish { + __u8 target[6]; + __u8 type; + __u16 max_mas; + __u16 min_mas; + __u8 max_interval; +}; + +struct uwb_dbg_cmd_rsv_terminate { + int index; +}; + +struct uwb_dbg_cmd_ie { + __u8 data[128]; + int len; +}; + +struct uwb_dbg_cmd { + __u32 type; + union { + struct uwb_dbg_cmd_rsv_establish rsv_establish; + struct uwb_dbg_cmd_rsv_terminate rsv_terminate; + struct uwb_dbg_cmd_ie ie_add; + struct uwb_dbg_cmd_ie ie_rm; + }; +}; + +#endif /* #ifndef __LINUX__UWB__DEBUG_CMD_H__ */ diff --git a/drivers/staging/uwb/include/spec.h b/drivers/staging/uwb/include/spec.h new file mode 100644 index 000000000000..5f75caf7b4ba --- /dev/null +++ b/drivers/staging/uwb/include/spec.h @@ -0,0 +1,767 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Ultra Wide Band + * UWB Standard definitions + * + * Copyright (C) 2005-2006 Intel Corporation + * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> + * + * All these definitions are based on the ECMA-368 standard. + * + * Note all definitions are Little Endian in the wire, and we will + * convert them to host order before operating on the bitfields (that + * yes, we use extensively). + */ + +#ifndef __LINUX__UWB_SPEC_H__ +#define __LINUX__UWB_SPEC_H__ + +#include <linux/types.h> +#include <linux/bitmap.h> +#include <linux/if_ether.h> + +#define i1480_FW 0x00000303 +/* #define i1480_FW 0x00000302 */ + +/** + * Number of Medium Access Slots in a superframe. + * + * UWB divides time in SuperFrames, each one divided in 256 pieces, or + * Medium Access Slots. See MBOA MAC[5.4.5] for details. The MAS is the + * basic bandwidth allocation unit in UWB. + */ +enum { UWB_NUM_MAS = 256 }; + +/** + * Number of Zones in superframe. + * + * UWB divides the superframe into zones with numbering starting from BPST. + * See MBOA MAC[16.8.6] + */ +enum { UWB_NUM_ZONES = 16 }; + +/* + * Number of MAS in a zone. + */ +#define UWB_MAS_PER_ZONE (UWB_NUM_MAS / UWB_NUM_ZONES) + +/* + * Number of MAS required before a row can be considered available. + */ +#define UWB_USABLE_MAS_PER_ROW (UWB_NUM_ZONES - 1) + +/* + * Number of streams per DRP reservation between a pair of devices. + * + * [ECMA-368] section 16.8.6. + */ +enum { UWB_NUM_STREAMS = 8 }; + +/* + * mMasLength + * + * The length of a MAS in microseconds. + * + * [ECMA-368] section 17.16. + */ +enum { UWB_MAS_LENGTH_US = 256 }; + +/* + * mBeaconSlotLength + * + * The length of the beacon slot in microseconds. + * + * [ECMA-368] section 17.16 + */ +enum { UWB_BEACON_SLOT_LENGTH_US = 85 }; + +/* + * mMaxLostBeacons + * + * The number beacons missing in consecutive superframes before a + * device can be considered as unreachable. + * + * [ECMA-368] section 17.16 + */ +enum { UWB_MAX_LOST_BEACONS = 3 }; + +/* + * mDRPBackOffWinMin + * + * The minimum number of superframes to wait before trying to reserve + * extra MAS. + * + * [ECMA-368] section 17.16 + */ +enum { UWB_DRP_BACKOFF_WIN_MIN = 2 }; + +/* + * mDRPBackOffWinMax + * + * The maximum number of superframes to wait before trying to reserve + * extra MAS. + * + * [ECMA-368] section 17.16 + */ +enum { UWB_DRP_BACKOFF_WIN_MAX = 16 }; + +/* + * Length of a superframe in microseconds. + */ +#define UWB_SUPERFRAME_LENGTH_US (UWB_MAS_LENGTH_US * UWB_NUM_MAS) + +/** + * UWB MAC address + * + * It is *imperative* that this struct is exactly 6 packed bytes (as + * it is also used to define headers sent down and up the wire/radio). + */ +struct uwb_mac_addr { + u8 data[ETH_ALEN]; +} __attribute__((packed)); + + +/** + * UWB device address + * + * It is *imperative* that this struct is exactly 6 packed bytes (as + * it is also used to define headers sent down and up the wire/radio). + */ +struct uwb_dev_addr { + u8 data[2]; +} __attribute__((packed)); + + +/** + * Types of UWB addresses + * + * Order matters (by size). + */ +enum uwb_addr_type { + UWB_ADDR_DEV = 0, + UWB_ADDR_MAC = 1, +}; + + +/** Size of a char buffer for printing a MAC/device address */ +enum { UWB_ADDR_STRSIZE = 32 }; + + +/** UWB WiMedia protocol IDs. */ +enum uwb_prid { + UWB_PRID_WLP_RESERVED = 0x0000, + UWB_PRID_WLP = 0x0001, + UWB_PRID_WUSB_BOT = 0x0010, + UWB_PRID_WUSB = 0x0010, + UWB_PRID_WUSB_TOP = 0x001F, +}; + + +/** PHY Rate (MBOA MAC[7.8.12, Table 61]) */ +enum uwb_phy_rate { + UWB_PHY_RATE_53 = 0, + UWB_PHY_RATE_80, + UWB_PHY_RATE_106, + UWB_PHY_RATE_160, + UWB_PHY_RATE_200, + UWB_PHY_RATE_320, + UWB_PHY_RATE_400, + UWB_PHY_RATE_480, + UWB_PHY_RATE_INVALID +}; + + +/** + * Different ways to scan (MBOA MAC[6.2.2, Table 8], WUSB[Table 8-78]) + */ +enum uwb_scan_type { + UWB_SCAN_ONLY = 0, + UWB_SCAN_OUTSIDE_BP, + UWB_SCAN_WHILE_INACTIVE, + UWB_SCAN_DISABLED, + UWB_SCAN_ONLY_STARTTIME, + UWB_SCAN_TOP +}; + + +/** ACK Policy types (MBOA MAC[7.2.1.3]) */ +enum uwb_ack_pol { + UWB_ACK_NO = 0, + UWB_ACK_INM = 1, + UWB_ACK_B = 2, + UWB_ACK_B_REQ = 3, +}; + + +/** DRP reservation types ([ECMA-368 table 106) */ +enum uwb_drp_type { + UWB_DRP_TYPE_ALIEN_BP = 0, + UWB_DRP_TYPE_HARD, + UWB_DRP_TYPE_SOFT, + UWB_DRP_TYPE_PRIVATE, + UWB_DRP_TYPE_PCA, +}; + + +/** DRP Reason Codes ([ECMA-368] table 107) */ +enum uwb_drp_reason { + UWB_DRP_REASON_ACCEPTED = 0, + UWB_DRP_REASON_CONFLICT, + UWB_DRP_REASON_PENDING, + UWB_DRP_REASON_DENIED, + UWB_DRP_REASON_MODIFIED, +}; + +/** Relinquish Request Reason Codes ([ECMA-368] table 113) */ +enum uwb_relinquish_req_reason { + UWB_RELINQUISH_REQ_REASON_NON_SPECIFIC = 0, + UWB_RELINQUISH_REQ_REASON_OVER_ALLOCATION, +}; + +/** + * DRP Notification Reason Codes (WHCI 0.95 [3.1.4.9]) + */ +enum uwb_drp_notif_reason { + UWB_DRP_NOTIF_DRP_IE_RCVD = 0, + UWB_DRP_NOTIF_CONFLICT, + UWB_DRP_NOTIF_TERMINATE, +}; + + +/** Allocation of MAS slots in a DRP request MBOA MAC[7.8.7] */ +struct uwb_drp_alloc { + __le16 zone_bm; + __le16 mas_bm; +} __attribute__((packed)); + + +/** General MAC Header format (ECMA-368[16.2]) */ +struct uwb_mac_frame_hdr { + __le16 Frame_Control; + struct uwb_dev_addr DestAddr; + struct uwb_dev_addr SrcAddr; + __le16 Sequence_Control; + __le16 Access_Information; +} __attribute__((packed)); + + +/** + * uwb_beacon_frame - a beacon frame including MAC headers + * + * [ECMA] section 16.3. + */ +struct uwb_beacon_frame { + struct uwb_mac_frame_hdr hdr; + struct uwb_mac_addr Device_Identifier; /* may be a NULL EUI-48 */ + u8 Beacon_Slot_Number; + u8 Device_Control; + u8 IEData[]; +} __attribute__((packed)); + + +/** Information Element codes (MBOA MAC[T54]) */ +enum uwb_ie { + UWB_PCA_AVAILABILITY = 2, + UWB_IE_DRP_AVAILABILITY = 8, + UWB_IE_DRP = 9, + UWB_BP_SWITCH_IE = 11, + UWB_MAC_CAPABILITIES_IE = 12, + UWB_PHY_CAPABILITIES_IE = 13, + UWB_APP_SPEC_PROBE_IE = 15, + UWB_IDENTIFICATION_IE = 19, + UWB_MASTER_KEY_ID_IE = 20, + UWB_RELINQUISH_REQUEST_IE = 21, + UWB_IE_WLP = 250, /* WiMedia Logical Link Control Protocol WLP 0.99 */ + UWB_APP_SPEC_IE = 255, +}; + + +/** + * Header common to all Information Elements (IEs) + */ +struct uwb_ie_hdr { + u8 element_id; /* enum uwb_ie */ + u8 length; +} __attribute__((packed)); + + +/** Dynamic Reservation Protocol IE (MBOA MAC[7.8.6]) */ +struct uwb_ie_drp { + struct uwb_ie_hdr hdr; + __le16 drp_control; + struct uwb_dev_addr dev_addr; + struct uwb_drp_alloc allocs[]; +} __attribute__((packed)); + +static inline int uwb_ie_drp_type(struct uwb_ie_drp *ie) +{ + return (le16_to_cpu(ie->drp_control) >> 0) & 0x7; +} + +static inline int uwb_ie_drp_stream_index(struct uwb_ie_drp *ie) +{ + return (le16_to_cpu(ie->drp_control) >> 3) & 0x7; +} + +static inline int uwb_ie_drp_reason_code(struct uwb_ie_drp *ie) +{ + return (le16_to_cpu(ie->drp_control) >> 6) & 0x7; +} + +static inline int uwb_ie_drp_status(struct uwb_ie_drp *ie) +{ + return (le16_to_cpu(ie->drp_control) >> 9) & 0x1; +} + +static inline int uwb_ie_drp_owner(struct uwb_ie_drp *ie) +{ + return (le16_to_cpu(ie->drp_control) >> 10) & 0x1; +} + +static inline int uwb_ie_drp_tiebreaker(struct uwb_ie_drp *ie) +{ + return (le16_to_cpu(ie->drp_control) >> 11) & 0x1; +} + +static inline int uwb_ie_drp_unsafe(struct uwb_ie_drp *ie) +{ + return (le16_to_cpu(ie->drp_control) >> 12) & 0x1; +} + +static inline void uwb_ie_drp_set_type(struct uwb_ie_drp *ie, enum uwb_drp_type type) +{ + u16 drp_control = le16_to_cpu(ie->drp_control); + drp_control = (drp_control & ~(0x7 << 0)) | (type << 0); + ie->drp_control = cpu_to_le16(drp_control); +} + +static inline void uwb_ie_drp_set_stream_index(struct uwb_ie_drp *ie, int stream_index) +{ + u16 drp_control = le16_to_cpu(ie->drp_control); + drp_control = (drp_control & ~(0x7 << 3)) | (stream_index << 3); + ie->drp_control = cpu_to_le16(drp_control); +} + +static inline void uwb_ie_drp_set_reason_code(struct uwb_ie_drp *ie, + enum uwb_drp_reason reason_code) +{ + u16 drp_control = le16_to_cpu(ie->drp_control); + drp_control = (ie->drp_control & ~(0x7 << 6)) | (reason_code << 6); + ie->drp_control = cpu_to_le16(drp_control); +} + +static inline void uwb_ie_drp_set_status(struct uwb_ie_drp *ie, int status) +{ + u16 drp_control = le16_to_cpu(ie->drp_control); + drp_control = (drp_control & ~(0x1 << 9)) | (status << 9); + ie->drp_control = cpu_to_le16(drp_control); +} + +static inline void uwb_ie_drp_set_owner(struct uwb_ie_drp *ie, int owner) +{ + u16 drp_control = le16_to_cpu(ie->drp_control); + drp_control = (drp_control & ~(0x1 << 10)) | (owner << 10); + ie->drp_control = cpu_to_le16(drp_control); +} + +static inline void uwb_ie_drp_set_tiebreaker(struct uwb_ie_drp *ie, int tiebreaker) +{ + u16 drp_control = le16_to_cpu(ie->drp_control); + drp_control = (drp_control & ~(0x1 << 11)) | (tiebreaker << 11); + ie->drp_control = cpu_to_le16(drp_control); +} + +static inline void uwb_ie_drp_set_unsafe(struct uwb_ie_drp *ie, int unsafe) +{ + u16 drp_control = le16_to_cpu(ie->drp_control); + drp_control = (drp_control & ~(0x1 << 12)) | (unsafe << 12); + ie->drp_control = cpu_to_le16(drp_control); +} + +/** Dynamic Reservation Protocol IE (MBOA MAC[7.8.7]) */ +struct uwb_ie_drp_avail { + struct uwb_ie_hdr hdr; + DECLARE_BITMAP(bmp, UWB_NUM_MAS); +} __attribute__((packed)); + +/* Relinqish Request IE ([ECMA-368] section 16.8.19). */ +struct uwb_relinquish_request_ie { + struct uwb_ie_hdr hdr; + __le16 relinquish_req_control; + struct uwb_dev_addr dev_addr; + struct uwb_drp_alloc allocs[]; +} __attribute__((packed)); + +static inline int uwb_ie_relinquish_req_reason_code(struct uwb_relinquish_request_ie *ie) +{ + return (le16_to_cpu(ie->relinquish_req_control) >> 0) & 0xf; +} + +static inline void uwb_ie_relinquish_req_set_reason_code(struct uwb_relinquish_request_ie *ie, + int reason_code) +{ + u16 ctrl = le16_to_cpu(ie->relinquish_req_control); + ctrl = (ctrl & ~(0xf << 0)) | (reason_code << 0); + ie->relinquish_req_control = cpu_to_le16(ctrl); +} + +/** + * The Vendor ID is set to an OUI that indicates the vendor of the device. + * ECMA-368 [16.8.10] + */ +struct uwb_vendor_id { + u8 data[3]; +} __attribute__((packed)); + +/** + * The device type ID + * FIXME: clarify what this means + * ECMA-368 [16.8.10] + */ +struct uwb_device_type_id { + u8 data[3]; +} __attribute__((packed)); + + +/** + * UWB device information types + * ECMA-368 [16.8.10] + */ +enum uwb_dev_info_type { + UWB_DEV_INFO_VENDOR_ID = 0, + UWB_DEV_INFO_VENDOR_TYPE, + UWB_DEV_INFO_NAME, +}; + +/** + * UWB device information found in Identification IE + * ECMA-368 [16.8.10] + */ +struct uwb_dev_info { + u8 type; /* enum uwb_dev_info_type */ + u8 length; + u8 data[]; +} __attribute__((packed)); + +/** + * UWB Identification IE + * ECMA-368 [16.8.10] + */ +struct uwb_identification_ie { + struct uwb_ie_hdr hdr; + struct uwb_dev_info info[]; +} __attribute__((packed)); + +/* + * UWB Radio Controller + * + * These definitions are common to the Radio Control layers as + * exported by the WUSB1.0 HWA and WHCI interfaces. + */ + +/** Radio Control Command Block (WUSB1.0[Table 8-65] and WHCI 0.95) */ +struct uwb_rccb { + u8 bCommandType; /* enum hwa_cet */ + __le16 wCommand; /* Command code */ + u8 bCommandContext; /* Context ID */ +} __attribute__((packed)); + + +/** Radio Control Event Block (WUSB[table 8-66], WHCI 0.95) */ +struct uwb_rceb { + u8 bEventType; /* enum hwa_cet */ + __le16 wEvent; /* Event code */ + u8 bEventContext; /* Context ID */ +} __attribute__((packed)); + + +enum { + UWB_RC_CET_GENERAL = 0, /* General Command/Event type */ + UWB_RC_CET_EX_TYPE_1 = 1, /* Extended Type 1 Command/Event type */ +}; + +/* Commands to the radio controller */ +enum uwb_rc_cmd { + UWB_RC_CMD_CHANNEL_CHANGE = 16, + UWB_RC_CMD_DEV_ADDR_MGMT = 17, /* Device Address Management */ + UWB_RC_CMD_GET_IE = 18, /* GET Information Elements */ + UWB_RC_CMD_RESET = 19, + UWB_RC_CMD_SCAN = 20, /* Scan management */ + UWB_RC_CMD_SET_BEACON_FILTER = 21, + UWB_RC_CMD_SET_DRP_IE = 22, /* Dynamic Reservation Protocol IEs */ + UWB_RC_CMD_SET_IE = 23, /* Information Element management */ + UWB_RC_CMD_SET_NOTIFICATION_FILTER = 24, + UWB_RC_CMD_SET_TX_POWER = 25, + UWB_RC_CMD_SLEEP = 26, + UWB_RC_CMD_START_BEACON = 27, + UWB_RC_CMD_STOP_BEACON = 28, + UWB_RC_CMD_BP_MERGE = 29, + UWB_RC_CMD_SEND_COMMAND_FRAME = 30, + UWB_RC_CMD_SET_ASIE_NOTIF = 31, +}; + +/* Notifications from the radio controller */ +enum uwb_rc_evt { + UWB_RC_EVT_IE_RCV = 0, + UWB_RC_EVT_BEACON = 1, + UWB_RC_EVT_BEACON_SIZE = 2, + UWB_RC_EVT_BPOIE_CHANGE = 3, + UWB_RC_EVT_BP_SLOT_CHANGE = 4, + UWB_RC_EVT_BP_SWITCH_IE_RCV = 5, + UWB_RC_EVT_DEV_ADDR_CONFLICT = 6, + UWB_RC_EVT_DRP_AVAIL = 7, + UWB_RC_EVT_DRP = 8, + UWB_RC_EVT_BP_SWITCH_STATUS = 9, + UWB_RC_EVT_CMD_FRAME_RCV = 10, + UWB_RC_EVT_CHANNEL_CHANGE_IE_RCV = 11, + /* Events (command responses) use the same code as the command */ + UWB_RC_EVT_UNKNOWN_CMD_RCV = 65535, +}; + +enum uwb_rc_extended_type_1_cmd { + UWB_RC_SET_DAA_ENERGY_MASK = 32, + UWB_RC_SET_NOTIFICATION_FILTER_EX = 33, +}; + +enum uwb_rc_extended_type_1_evt { + UWB_RC_DAA_ENERGY_DETECTED = 0, +}; + +/* Radio Control Result Code. [WHCI] table 3-3. */ +enum { + UWB_RC_RES_SUCCESS = 0, + UWB_RC_RES_FAIL, + UWB_RC_RES_FAIL_HARDWARE, + UWB_RC_RES_FAIL_NO_SLOTS, + UWB_RC_RES_FAIL_BEACON_TOO_LARGE, + UWB_RC_RES_FAIL_INVALID_PARAMETER, + UWB_RC_RES_FAIL_UNSUPPORTED_PWR_LEVEL, + UWB_RC_RES_FAIL_INVALID_IE_DATA, + UWB_RC_RES_FAIL_BEACON_SIZE_EXCEEDED, + UWB_RC_RES_FAIL_CANCELLED, + UWB_RC_RES_FAIL_INVALID_STATE, + UWB_RC_RES_FAIL_INVALID_SIZE, + UWB_RC_RES_FAIL_ACK_NOT_RECEIVED, + UWB_RC_RES_FAIL_NO_MORE_ASIE_NOTIF, + UWB_RC_RES_FAIL_TIME_OUT = 255, +}; + +/* Confirm event. [WHCI] section 3.1.3.1 etc. */ +struct uwb_rc_evt_confirm { + struct uwb_rceb rceb; + u8 bResultCode; +} __attribute__((packed)); + +/* Device Address Management event. [WHCI] section 3.1.3.2. */ +struct uwb_rc_evt_dev_addr_mgmt { + struct uwb_rceb rceb; + u8 baAddr[ETH_ALEN]; + u8 bResultCode; +} __attribute__((packed)); + + +/* Get IE Event. [WHCI] section 3.1.3.3. */ +struct uwb_rc_evt_get_ie { + struct uwb_rceb rceb; + __le16 wIELength; + u8 IEData[]; +} __attribute__((packed)); + +/* Set DRP IE Event. [WHCI] section 3.1.3.7. */ +struct uwb_rc_evt_set_drp_ie { + struct uwb_rceb rceb; + __le16 wRemainingSpace; + u8 bResultCode; +} __attribute__((packed)); + +/* Set IE Event. [WHCI] section 3.1.3.8. */ +struct uwb_rc_evt_set_ie { + struct uwb_rceb rceb; + __le16 RemainingSpace; + u8 bResultCode; +} __attribute__((packed)); + +/* Scan command. [WHCI] 3.1.3.5. */ +struct uwb_rc_cmd_scan { + struct uwb_rccb rccb; + u8 bChannelNumber; + u8 bScanState; + __le16 wStartTime; +} __attribute__((packed)); + +/* Set DRP IE command. [WHCI] section 3.1.3.7. */ +struct uwb_rc_cmd_set_drp_ie { + struct uwb_rccb rccb; + __le16 wIELength; + struct uwb_ie_drp IEData[]; +} __attribute__((packed)); + +/* Set IE command. [WHCI] section 3.1.3.8. */ +struct uwb_rc_cmd_set_ie { + struct uwb_rccb rccb; + __le16 wIELength; + u8 IEData[]; +} __attribute__((packed)); + +/* Set DAA Energy Mask event. [WHCI 0.96] section 3.1.3.17. */ +struct uwb_rc_evt_set_daa_energy_mask { + struct uwb_rceb rceb; + __le16 wLength; + u8 result; +} __attribute__((packed)); + +/* Set Notification Filter Extended event. [WHCI 0.96] section 3.1.3.18. */ +struct uwb_rc_evt_set_notification_filter_ex { + struct uwb_rceb rceb; + __le16 wLength; + u8 result; +} __attribute__((packed)); + +/* IE Received notification. [WHCI] section 3.1.4.1. */ +struct uwb_rc_evt_ie_rcv { + struct uwb_rceb rceb; + struct uwb_dev_addr SrcAddr; + __le16 wIELength; + u8 IEData[]; +} __attribute__((packed)); + +/* Type of the received beacon. [WHCI] section 3.1.4.2. */ +enum uwb_rc_beacon_type { + UWB_RC_BEACON_TYPE_SCAN = 0, + UWB_RC_BEACON_TYPE_NEIGHBOR, + UWB_RC_BEACON_TYPE_OL_ALIEN, + UWB_RC_BEACON_TYPE_NOL_ALIEN, +}; + +/* Beacon received notification. [WHCI] 3.1.4.2. */ +struct uwb_rc_evt_beacon { + struct uwb_rceb rceb; + u8 bChannelNumber; + u8 bBeaconType; + __le16 wBPSTOffset; + u8 bLQI; + u8 bRSSI; + __le16 wBeaconInfoLength; + u8 BeaconInfo[]; +} __attribute__((packed)); + + +/* Beacon Size Change notification. [WHCI] section 3.1.4.3 */ +struct uwb_rc_evt_beacon_size { + struct uwb_rceb rceb; + __le16 wNewBeaconSize; +} __attribute__((packed)); + + +/* BPOIE Change notification. [WHCI] section 3.1.4.4. */ +struct uwb_rc_evt_bpoie_change { + struct uwb_rceb rceb; + __le16 wBPOIELength; + u8 BPOIE[]; +} __attribute__((packed)); + + +/* Beacon Slot Change notification. [WHCI] section 3.1.4.5. */ +struct uwb_rc_evt_bp_slot_change { + struct uwb_rceb rceb; + u8 slot_info; +} __attribute__((packed)); + +static inline int uwb_rc_evt_bp_slot_change_slot_num( + const struct uwb_rc_evt_bp_slot_change *evt) +{ + return evt->slot_info & 0x7f; +} + +static inline int uwb_rc_evt_bp_slot_change_no_slot( + const struct uwb_rc_evt_bp_slot_change *evt) +{ + return (evt->slot_info & 0x80) >> 7; +} + +/* BP Switch IE Received notification. [WHCI] section 3.1.4.6. */ +struct uwb_rc_evt_bp_switch_ie_rcv { + struct uwb_rceb rceb; + struct uwb_dev_addr wSrcAddr; + __le16 wIELength; + u8 IEData[]; +} __attribute__((packed)); + +/* DevAddr Conflict notification. [WHCI] section 3.1.4.7. */ +struct uwb_rc_evt_dev_addr_conflict { + struct uwb_rceb rceb; +} __attribute__((packed)); + +/* DRP notification. [WHCI] section 3.1.4.9. */ +struct uwb_rc_evt_drp { + struct uwb_rceb rceb; + struct uwb_dev_addr src_addr; + u8 reason; + u8 beacon_slot_number; + __le16 ie_length; + u8 ie_data[]; +} __attribute__((packed)); + +static inline enum uwb_drp_notif_reason uwb_rc_evt_drp_reason(struct uwb_rc_evt_drp *evt) +{ + return evt->reason & 0x0f; +} + + +/* DRP Availability Change notification. [WHCI] section 3.1.4.8. */ +struct uwb_rc_evt_drp_avail { + struct uwb_rceb rceb; + DECLARE_BITMAP(bmp, UWB_NUM_MAS); +} __attribute__((packed)); + +/* BP switch status notification. [WHCI] section 3.1.4.10. */ +struct uwb_rc_evt_bp_switch_status { + struct uwb_rceb rceb; + u8 status; + u8 slot_offset; + __le16 bpst_offset; + u8 move_countdown; +} __attribute__((packed)); + +/* Command Frame Received notification. [WHCI] section 3.1.4.11. */ +struct uwb_rc_evt_cmd_frame_rcv { + struct uwb_rceb rceb; + __le16 receive_time; + struct uwb_dev_addr wSrcAddr; + struct uwb_dev_addr wDstAddr; + __le16 control; + __le16 reserved; + __le16 dataLength; + u8 data[]; +} __attribute__((packed)); + +/* Channel Change IE Received notification. [WHCI] section 3.1.4.12. */ +struct uwb_rc_evt_channel_change_ie_rcv { + struct uwb_rceb rceb; + struct uwb_dev_addr wSrcAddr; + __le16 wIELength; + u8 IEData[]; +} __attribute__((packed)); + +/* DAA Energy Detected notification. [WHCI 0.96] section 3.1.4.14. */ +struct uwb_rc_evt_daa_energy_detected { + struct uwb_rceb rceb; + __le16 wLength; + u8 bandID; + u8 reserved; + u8 toneBmp[16]; +} __attribute__((packed)); + + +/** + * Radio Control Interface Class Descriptor + * + * WUSB 1.0 [8.6.1.2] + */ +struct uwb_rc_control_intf_class_desc { + u8 bLength; + u8 bDescriptorType; + __le16 bcdRCIVersion; +} __attribute__((packed)); + +#endif /* #ifndef __LINUX__UWB_SPEC_H__ */ diff --git a/drivers/staging/uwb/include/umc.h b/drivers/staging/uwb/include/umc.h new file mode 100644 index 000000000000..ddbceb39ad15 --- /dev/null +++ b/drivers/staging/uwb/include/umc.h @@ -0,0 +1,192 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * UWB Multi-interface Controller support. + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * UMC (UWB Multi-interface Controller) capabilities (e.g., radio + * controller, host controller) are presented as devices on the "umc" + * bus. + * + * The radio controller is not strictly a UMC capability but it's + * useful to present it as such. + * + * References: + * + * [WHCI] Wireless Host Controller Interface Specification for + * Certified Wireless Universal Serial Bus, revision 0.95. + * + * How this works is kind of convoluted but simple. The whci.ko driver + * loads when WHCI devices are detected. These WHCI devices expose + * many devices in the same PCI function (they couldn't have reused + * functions, no), so for each PCI function that exposes these many + * devices, whci ceates a umc_dev [whci_probe() -> whci_add_cap()] + * with umc_device_create() and adds it to the bus with + * umc_device_register(). + * + * umc_device_register() calls device_register() which will push the + * bus management code to load your UMC driver's somehting_probe() + * that you have registered for that capability code. + * + * Now when the WHCI device is removed, whci_remove() will go over + * each umc_dev assigned to each of the PCI function's capabilities + * and through whci_del_cap() call umc_device_unregister() each + * created umc_dev. Of course, if you are bound to the device, your + * driver's something_remove() will be called. + */ + +#ifndef _LINUX_UWB_UMC_H_ +#define _LINUX_UWB_UMC_H_ + +#include <linux/device.h> +#include <linux/pci.h> + +/* + * UMC capability IDs. + * + * 0x00 is reserved so use it for the radio controller device. + * + * [WHCI] table 2-8 + */ +#define UMC_CAP_ID_WHCI_RC 0x00 /* radio controller */ +#define UMC_CAP_ID_WHCI_WUSB_HC 0x01 /* WUSB host controller */ + +/** + * struct umc_dev - UMC capability device + * + * @version: version of the specification this capability conforms to. + * @cap_id: capability ID. + * @bar: PCI Bar (64 bit) where the resource lies + * @resource: register space resource. + * @irq: interrupt line. + */ +struct umc_dev { + u16 version; + u8 cap_id; + u8 bar; + struct resource resource; + unsigned irq; + struct device dev; +}; + +#define to_umc_dev(d) container_of(d, struct umc_dev, dev) + +/** + * struct umc_driver - UMC capability driver + * @cap_id: supported capability ID. + * @match: driver specific capability matching function. + * @match_data: driver specific data for match() (e.g., a + * table of pci_device_id's if umc_match_pci_id() is used). + */ +struct umc_driver { + char *name; + u8 cap_id; + int (*match)(struct umc_driver *, struct umc_dev *); + const void *match_data; + + int (*probe)(struct umc_dev *); + void (*remove)(struct umc_dev *); + int (*pre_reset)(struct umc_dev *); + int (*post_reset)(struct umc_dev *); + + struct device_driver driver; +}; + +#define to_umc_driver(d) container_of(d, struct umc_driver, driver) + +extern struct bus_type umc_bus_type; + +struct umc_dev *umc_device_create(struct device *parent, int n); +int __must_check umc_device_register(struct umc_dev *umc); +void umc_device_unregister(struct umc_dev *umc); + +int __must_check __umc_driver_register(struct umc_driver *umc_drv, + struct module *mod, + const char *mod_name); + +/** + * umc_driver_register - register a UMC capabiltity driver. + * @umc_drv: pointer to the driver. + */ +#define umc_driver_register(umc_drv) \ + __umc_driver_register(umc_drv, THIS_MODULE, KBUILD_MODNAME) + +void umc_driver_unregister(struct umc_driver *umc_drv); + +/* + * Utility function you can use to match (umc_driver->match) against a + * null-terminated array of 'struct pci_device_id' in + * umc_driver->match_data. + */ +int umc_match_pci_id(struct umc_driver *umc_drv, struct umc_dev *umc); + +/** + * umc_parent_pci_dev - return the UMC's parent PCI device or NULL if none + * @umc_dev: UMC device whose parent PCI device we are looking for + * + * DIRTY!!! DON'T RELY ON THIS + * + * FIXME: This is as dirty as it gets, but we need some way to check + * the correct type of umc_dev->parent (so that for example, we can + * cast to pci_dev). Casting to pci_dev is necessary because at some + * point we need to request resources from the device. Mapping is + * easily over come (ioremap and stuff are bus agnostic), but hooking + * up to some error handlers (such as pci error handlers) might need + * this. + * + * THIS might (probably will) be removed in the future, so don't count + * on it. + */ +static inline struct pci_dev *umc_parent_pci_dev(struct umc_dev *umc_dev) +{ + struct pci_dev *pci_dev = NULL; + if (dev_is_pci(umc_dev->dev.parent)) + pci_dev = to_pci_dev(umc_dev->dev.parent); + return pci_dev; +} + +/** + * umc_dev_get() - reference a UMC device. + * @umc_dev: Pointer to UMC device. + * + * NOTE: we are assuming in this whole scheme that the parent device + * is referenced at _probe() time and unreferenced at _remove() + * time by the parent's subsystem. + */ +static inline struct umc_dev *umc_dev_get(struct umc_dev *umc_dev) +{ + get_device(&umc_dev->dev); + return umc_dev; +} + +/** + * umc_dev_put() - unreference a UMC device. + * @umc_dev: Pointer to UMC device. + */ +static inline void umc_dev_put(struct umc_dev *umc_dev) +{ + put_device(&umc_dev->dev); +} + +/** + * umc_set_drvdata - set UMC device's driver data. + * @umc_dev: Pointer to UMC device. + * @data: Data to set. + */ +static inline void umc_set_drvdata(struct umc_dev *umc_dev, void *data) +{ + dev_set_drvdata(&umc_dev->dev, data); +} + +/** + * umc_get_drvdata - recover UMC device's driver data. + * @umc_dev: Pointer to UMC device. + */ +static inline void *umc_get_drvdata(struct umc_dev *umc_dev) +{ + return dev_get_drvdata(&umc_dev->dev); +} + +int umc_controller_reset(struct umc_dev *umc); + +#endif /* #ifndef _LINUX_UWB_UMC_H_ */ diff --git a/drivers/staging/uwb/include/whci.h b/drivers/staging/uwb/include/whci.h new file mode 100644 index 000000000000..1a5c2cc2b008 --- /dev/null +++ b/drivers/staging/uwb/include/whci.h @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Wireless Host Controller Interface for Ultra-Wide-Band and Wireless USB + * + * Copyright (C) 2005-2006 Intel Corporation + * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> + * + * References: + * [WHCI] Wireless Host Controller Interface Specification for + * Certified Wireless Universal Serial Bus, revision 0.95. + */ +#ifndef _LINUX_UWB_WHCI_H_ +#define _LINUX_UWB_WHCI_H_ + +#include <linux/pci.h> + +/* + * UWB interface capability registers (offsets from UWBBASE) + * + * [WHCI] section 2.2 + */ +#define UWBCAPINFO 0x00 /* == UWBCAPDATA(0) */ +# define UWBCAPINFO_TO_N_CAPS(c) (((c) >> 0) & 0xFull) +#define UWBCAPDATA(n) (8*(n)) +# define UWBCAPDATA_TO_VERSION(c) (((c) >> 32) & 0xFFFFull) +# define UWBCAPDATA_TO_OFFSET(c) (((c) >> 18) & 0x3FFFull) +# define UWBCAPDATA_TO_BAR(c) (((c) >> 16) & 0x3ull) +# define UWBCAPDATA_TO_SIZE(c) ((((c) >> 8) & 0xFFull) * sizeof(u32)) +# define UWBCAPDATA_TO_CAP_ID(c) (((c) >> 0) & 0xFFull) + +/* Size of the WHCI capability data (including the RC capability) for + a device with n capabilities. */ +#define UWBCAPDATA_SIZE(n) (8 + 8*(n)) + + +/* + * URC registers (offsets from URCBASE) + * + * [WHCI] section 2.3 + */ +#define URCCMD 0x00 +# define URCCMD_RESET (1 << 31) /* UMC Hardware reset */ +# define URCCMD_RS (1 << 30) /* Run/Stop */ +# define URCCMD_EARV (1 << 29) /* Event Address Register Valid */ +# define URCCMD_ACTIVE (1 << 15) /* Command is active */ +# define URCCMD_IWR (1 << 14) /* Interrupt When Ready */ +# define URCCMD_SIZE_MASK 0x00000fff /* Command size mask */ +#define URCSTS 0x04 +# define URCSTS_EPS (1 << 17) /* Event Processing Status */ +# define URCSTS_HALTED (1 << 16) /* RC halted */ +# define URCSTS_HSE (1 << 10) /* Host System Error...fried */ +# define URCSTS_ER (1 << 9) /* Event Ready */ +# define URCSTS_RCI (1 << 8) /* Ready for Command Interrupt */ +# define URCSTS_INT_MASK 0x00000700 /* URC interrupt sources */ +# define URCSTS_ISI 0x000000ff /* Interrupt Source Identification */ +#define URCINTR 0x08 +# define URCINTR_EN_ALL 0x000007ff /* Enable all interrupt sources */ +#define URCCMDADDR 0x10 +#define URCEVTADDR 0x18 +# define URCEVTADDR_OFFSET_MASK 0xfff /* Event pointer offset mask */ + + +/** Write 32 bit @value to little endian register at @addr */ +static inline +void le_writel(u32 value, void __iomem *addr) +{ + iowrite32(value, addr); +} + + +/** Read from 32 bit little endian register at @addr */ +static inline +u32 le_readl(void __iomem *addr) +{ + return ioread32(addr); +} + + +/** Write 64 bit @value to little endian register at @addr */ +static inline +void le_writeq(u64 value, void __iomem *addr) +{ + iowrite32(value, addr); + iowrite32(value >> 32, addr + 4); +} + + +/** Read from 64 bit little endian register at @addr */ +static inline +u64 le_readq(void __iomem *addr) +{ + u64 value; + value = ioread32(addr); + value |= (u64)ioread32(addr + 4) << 32; + return value; +} + +extern int whci_wait_for(struct device *dev, u32 __iomem *reg, + u32 mask, u32 result, + unsigned long max_ms, const char *tag); + +#endif /* #ifndef _LINUX_UWB_WHCI_H_ */ diff --git a/drivers/uwb/lc-dev.c b/drivers/staging/uwb/lc-dev.c index 3e5c07fd6b10..3e5c07fd6b10 100644 --- a/drivers/uwb/lc-dev.c +++ b/drivers/staging/uwb/lc-dev.c diff --git a/drivers/uwb/lc-rc.c b/drivers/staging/uwb/lc-rc.c index ee31b221cdc2..ee31b221cdc2 100644 --- a/drivers/uwb/lc-rc.c +++ b/drivers/staging/uwb/lc-rc.c diff --git a/drivers/uwb/neh.c b/drivers/staging/uwb/neh.c index 1695584be412..1695584be412 100644 --- a/drivers/uwb/neh.c +++ b/drivers/staging/uwb/neh.c diff --git a/drivers/uwb/pal.c b/drivers/staging/uwb/pal.c index 765fd426dbd1..a541e646a603 100644 --- a/drivers/uwb/pal.c +++ b/drivers/staging/uwb/pal.c @@ -6,9 +6,9 @@ */ #include <linux/kernel.h> #include <linux/debugfs.h> -#include <linux/uwb.h> #include <linux/export.h> +#include "uwb.h" #include "uwb-internal.h" /** diff --git a/drivers/uwb/radio.c b/drivers/staging/uwb/radio.c index 240dd755927e..6afb75ce1b5f 100644 --- a/drivers/uwb/radio.c +++ b/drivers/staging/uwb/radio.c @@ -5,9 +5,9 @@ * Copyright (C) 2008 Cambridge Silicon Radio Ltd. */ #include <linux/kernel.h> -#include <linux/uwb.h> #include <linux/export.h> +#include "uwb.h" #include "uwb-internal.h" diff --git a/drivers/uwb/reset.c b/drivers/staging/uwb/reset.c index 8fc7c14d903e..8fc7c14d903e 100644 --- a/drivers/uwb/reset.c +++ b/drivers/staging/uwb/reset.c diff --git a/drivers/uwb/rsv.c b/drivers/staging/uwb/rsv.c index ec924deb0a32..f45a04ff7275 100644 --- a/drivers/uwb/rsv.c +++ b/drivers/staging/uwb/rsv.c @@ -5,11 +5,11 @@ * Copyright (C) 2008 Cambridge Silicon Radio Ltd. */ #include <linux/kernel.h> -#include <linux/uwb.h> #include <linux/slab.h> #include <linux/random.h> #include <linux/export.h> +#include "uwb.h" #include "uwb-internal.h" static void uwb_rsv_timer(struct timer_list *t); diff --git a/drivers/uwb/scan.c b/drivers/staging/uwb/scan.c index ffc3f452302d..ffc3f452302d 100644 --- a/drivers/uwb/scan.c +++ b/drivers/staging/uwb/scan.c diff --git a/drivers/uwb/umc-bus.c b/drivers/staging/uwb/umc-bus.c index 0fdc38078eee..8b931f66a720 100644 --- a/drivers/uwb/umc-bus.c +++ b/drivers/staging/uwb/umc-bus.c @@ -8,8 +8,8 @@ #include <linux/sysfs.h> #include <linux/workqueue.h> #include <linux/module.h> -#include <linux/uwb/umc.h> #include <linux/pci.h> +#include "include/umc.h" static int umc_bus_pre_reset_helper(struct device *dev, void *data) { diff --git a/drivers/uwb/umc-dev.c b/drivers/staging/uwb/umc-dev.c index c845ca414bb2..0c71caae00be 100644 --- a/drivers/uwb/umc-dev.c +++ b/drivers/staging/uwb/umc-dev.c @@ -7,7 +7,7 @@ #include <linux/kernel.h> #include <linux/export.h> #include <linux/slab.h> -#include <linux/uwb/umc.h> +#include "include/umc.h" static void umc_device_release(struct device *dev) { diff --git a/drivers/uwb/umc-drv.c b/drivers/staging/uwb/umc-drv.c index b141d520efbf..ed3bd220e8c2 100644 --- a/drivers/uwb/umc-drv.c +++ b/drivers/staging/uwb/umc-drv.c @@ -6,7 +6,7 @@ */ #include <linux/kernel.h> #include <linux/export.h> -#include <linux/uwb/umc.h> +#include "include/umc.h" int __umc_driver_register(struct umc_driver *umc_drv, struct module *module, const char *mod_name) diff --git a/drivers/uwb/uwb-debug.c b/drivers/staging/uwb/uwb-debug.c index 5457b6d42387..dd14df219ef8 100644 --- a/drivers/uwb/uwb-debug.c +++ b/drivers/staging/uwb/uwb-debug.c @@ -19,8 +19,7 @@ #include <linux/uaccess.h> #include <linux/seq_file.h> -#include <linux/uwb/debug-cmd.h> - +#include "include/debug-cmd.h" #include "uwb-internal.h" /* diff --git a/drivers/uwb/uwb-internal.h b/drivers/staging/uwb/uwb-internal.h index 00de0a5333d2..4c2fdac7f610 100644 --- a/drivers/uwb/uwb-internal.h +++ b/drivers/staging/uwb/uwb-internal.h @@ -17,8 +17,8 @@ #include <linux/kernel.h> #include <linux/device.h> -#include <linux/uwb.h> #include <linux/mutex.h> +#include "uwb.h" struct uwb_beca_e; diff --git a/drivers/staging/uwb/uwb.h b/drivers/staging/uwb/uwb.h new file mode 100644 index 000000000000..6a59706ba3a0 --- /dev/null +++ b/drivers/staging/uwb/uwb.h @@ -0,0 +1,817 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Ultra Wide Band + * UWB API + * + * Copyright (C) 2005-2006 Intel Corporation + * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> + * + * FIXME: doc: overview of the API, different parts and pointers + */ + +#ifndef __LINUX__UWB_H__ +#define __LINUX__UWB_H__ + +#include <linux/limits.h> +#include <linux/device.h> +#include <linux/mutex.h> +#include <linux/timer.h> +#include <linux/wait.h> +#include <linux/workqueue.h> +#include <asm/page.h> +#include "include/spec.h" + +struct uwb_dev; +struct uwb_beca_e; +struct uwb_rc; +struct uwb_rsv; +struct uwb_dbg; + +/** + * struct uwb_dev - a UWB Device + * @rc: UWB Radio Controller that discovered the device (kind of its + * parent). + * @bce: a beacon cache entry for this device; or NULL if the device + * is a local radio controller. + * @mac_addr: the EUI-48 address of this device. + * @dev_addr: the current DevAddr used by this device. + * @beacon_slot: the slot number the beacon is using. + * @streams: bitmap of streams allocated to reservations targeted at + * this device. For an RC, this is the streams allocated for + * reservations targeted at DevAddrs. + * + * A UWB device may either by a neighbor or part of a local radio + * controller. + */ +struct uwb_dev { + struct mutex mutex; + struct list_head list_node; + struct device dev; + struct uwb_rc *rc; /* radio controller */ + struct uwb_beca_e *bce; /* Beacon Cache Entry */ + + struct uwb_mac_addr mac_addr; + struct uwb_dev_addr dev_addr; + int beacon_slot; + DECLARE_BITMAP(streams, UWB_NUM_STREAMS); + DECLARE_BITMAP(last_availability_bm, UWB_NUM_MAS); +}; +#define to_uwb_dev(d) container_of(d, struct uwb_dev, dev) + +/** + * UWB HWA/WHCI Radio Control {Command|Event} Block context IDs + * + * RC[CE]Bs have a 'context ID' field that matches the command with + * the event received to confirm it. + * + * Maximum number of context IDs + */ +enum { UWB_RC_CTX_MAX = 256 }; + + +/** Notification chain head for UWB generated events to listeners */ +struct uwb_notifs_chain { + struct list_head list; + struct mutex mutex; +}; + +/* Beacon cache list */ +struct uwb_beca { + struct list_head list; + size_t entries; + struct mutex mutex; +}; + +/* Event handling thread. */ +struct uwbd { + int pid; + struct task_struct *task; + wait_queue_head_t wq; + struct list_head event_list; + spinlock_t event_list_lock; +}; + +/** + * struct uwb_mas_bm - a bitmap of all MAS in a superframe + * @bm: a bitmap of length #UWB_NUM_MAS + */ +struct uwb_mas_bm { + DECLARE_BITMAP(bm, UWB_NUM_MAS); + DECLARE_BITMAP(unsafe_bm, UWB_NUM_MAS); + int safe; + int unsafe; +}; + +/** + * uwb_rsv_state - UWB Reservation state. + * + * NONE - reservation is not active (no DRP IE being transmitted). + * + * Owner reservation states: + * + * INITIATED - owner has sent an initial DRP request. + * PENDING - target responded with pending Reason Code. + * MODIFIED - reservation manager is modifying an established + * reservation with a different MAS allocation. + * ESTABLISHED - the reservation has been successfully negotiated. + * + * Target reservation states: + * + * DENIED - request is denied. + * ACCEPTED - request is accepted. + * PENDING - PAL has yet to make a decision to whether to accept or + * deny. + * + * FIXME: further target states TBD. + */ +enum uwb_rsv_state { + UWB_RSV_STATE_NONE = 0, + UWB_RSV_STATE_O_INITIATED, + UWB_RSV_STATE_O_PENDING, + UWB_RSV_STATE_O_MODIFIED, + UWB_RSV_STATE_O_ESTABLISHED, + UWB_RSV_STATE_O_TO_BE_MOVED, + UWB_RSV_STATE_O_MOVE_EXPANDING, + UWB_RSV_STATE_O_MOVE_COMBINING, + UWB_RSV_STATE_O_MOVE_REDUCING, + UWB_RSV_STATE_T_ACCEPTED, + UWB_RSV_STATE_T_DENIED, + UWB_RSV_STATE_T_CONFLICT, + UWB_RSV_STATE_T_PENDING, + UWB_RSV_STATE_T_EXPANDING_ACCEPTED, + UWB_RSV_STATE_T_EXPANDING_CONFLICT, + UWB_RSV_STATE_T_EXPANDING_PENDING, + UWB_RSV_STATE_T_EXPANDING_DENIED, + UWB_RSV_STATE_T_RESIZED, + + UWB_RSV_STATE_LAST, +}; + +enum uwb_rsv_target_type { + UWB_RSV_TARGET_DEV, + UWB_RSV_TARGET_DEVADDR, +}; + +/** + * struct uwb_rsv_target - the target of a reservation. + * + * Reservations unicast and targeted at a single device + * (UWB_RSV_TARGET_DEV); or (e.g., in the case of WUSB) targeted at a + * specific (private) DevAddr (UWB_RSV_TARGET_DEVADDR). + */ +struct uwb_rsv_target { + enum uwb_rsv_target_type type; + union { + struct uwb_dev *dev; + struct uwb_dev_addr devaddr; + }; +}; + +struct uwb_rsv_move { + struct uwb_mas_bm final_mas; + struct uwb_ie_drp *companion_drp_ie; + struct uwb_mas_bm companion_mas; +}; + +/* + * Number of streams reserved for reservations targeted at DevAddrs. + */ +#define UWB_NUM_GLOBAL_STREAMS 1 + +typedef void (*uwb_rsv_cb_f)(struct uwb_rsv *rsv); + +/** + * struct uwb_rsv - a DRP reservation + * + * Data structure management: + * + * @rc: the radio controller this reservation is for + * (as target or owner) + * @rc_node: a list node for the RC + * @pal_node: a list node for the PAL + * + * Owner and target parameters: + * + * @owner: the UWB device owning this reservation + * @target: the target UWB device + * @type: reservation type + * + * Owner parameters: + * + * @max_mas: maxiumum number of MAS + * @min_mas: minimum number of MAS + * @sparsity: owner selected sparsity + * @is_multicast: true iff multicast + * + * @callback: callback function when the reservation completes + * @pal_priv: private data for the PAL making the reservation + * + * Reservation status: + * + * @status: negotiation status + * @stream: stream index allocated for this reservation + * @tiebreaker: conflict tiebreaker for this reservation + * @mas: reserved MAS + * @drp_ie: the DRP IE + * @ie_valid: true iff the DRP IE matches the reservation parameters + * + * DRP reservations are uniquely identified by the owner, target and + * stream index. However, when using a DevAddr as a target (e.g., for + * a WUSB cluster reservation) the responses may be received from + * devices with different DevAddrs. In this case, reservations are + * uniquely identified by just the stream index. A number of stream + * indexes (UWB_NUM_GLOBAL_STREAMS) are reserved for this. + */ +struct uwb_rsv { + struct uwb_rc *rc; + struct list_head rc_node; + struct list_head pal_node; + struct kref kref; + + struct uwb_dev *owner; + struct uwb_rsv_target target; + enum uwb_drp_type type; + int max_mas; + int min_mas; + int max_interval; + bool is_multicast; + + uwb_rsv_cb_f callback; + void *pal_priv; + + enum uwb_rsv_state state; + bool needs_release_companion_mas; + u8 stream; + u8 tiebreaker; + struct uwb_mas_bm mas; + struct uwb_ie_drp *drp_ie; + struct uwb_rsv_move mv; + bool ie_valid; + struct timer_list timer; + struct work_struct handle_timeout_work; +}; + +static const +struct uwb_mas_bm uwb_mas_bm_zero = { .bm = { 0 } }; + +static inline void uwb_mas_bm_copy_le(void *dst, const struct uwb_mas_bm *mas) +{ + bitmap_copy_le(dst, mas->bm, UWB_NUM_MAS); +} + +/** + * struct uwb_drp_avail - a radio controller's view of MAS usage + * @global: MAS unused by neighbors (excluding reservations targeted + * or owned by the local radio controller) or the beaon period + * @local: MAS unused by local established reservations + * @pending: MAS unused by local pending reservations + * @ie: DRP Availability IE to be included in the beacon + * @ie_valid: true iff @ie is valid and does not need to regenerated from + * @global and @local + * + * Each radio controller maintains a view of MAS usage or + * availability. MAS available for a new reservation are determined + * from the intersection of @global, @local, and @pending. + * + * The radio controller must transmit a DRP Availability IE that's the + * intersection of @global and @local. + * + * A set bit indicates the MAS is unused and available. + * + * rc->rsvs_mutex should be held before accessing this data structure. + * + * [ECMA-368] section 17.4.3. + */ +struct uwb_drp_avail { + DECLARE_BITMAP(global, UWB_NUM_MAS); + DECLARE_BITMAP(local, UWB_NUM_MAS); + DECLARE_BITMAP(pending, UWB_NUM_MAS); + struct uwb_ie_drp_avail ie; + bool ie_valid; +}; + +struct uwb_drp_backoff_win { + u8 window; + u8 n; + int total_expired; + struct timer_list timer; + bool can_reserve_extra_mases; +}; + +const char *uwb_rsv_state_str(enum uwb_rsv_state state); +const char *uwb_rsv_type_str(enum uwb_drp_type type); + +struct uwb_rsv *uwb_rsv_create(struct uwb_rc *rc, uwb_rsv_cb_f cb, + void *pal_priv); +void uwb_rsv_destroy(struct uwb_rsv *rsv); + +int uwb_rsv_establish(struct uwb_rsv *rsv); +int uwb_rsv_modify(struct uwb_rsv *rsv, + int max_mas, int min_mas, int sparsity); +void uwb_rsv_terminate(struct uwb_rsv *rsv); + +void uwb_rsv_accept(struct uwb_rsv *rsv, uwb_rsv_cb_f cb, void *pal_priv); + +void uwb_rsv_get_usable_mas(struct uwb_rsv *orig_rsv, struct uwb_mas_bm *mas); + +/** + * Radio Control Interface instance + * + * + * Life cycle rules: those of the UWB Device. + * + * @index: an index number for this radio controller, as used in the + * device name. + * @version: version of protocol supported by this device + * @priv: Backend implementation; rw with uwb_dev.dev.sem taken. + * @cmd: Backend implementation to execute commands; rw and call + * only with uwb_dev.dev.sem taken. + * @reset: Hardware reset of radio controller and any PAL controllers. + * @filter: Backend implementation to manipulate data to and from device + * to be compliant to specification assumed by driver (WHCI + * 0.95). + * + * uwb_dev.dev.mutex is used to execute commands and update + * the corresponding structures; can't use a spinlock + * because rc->cmd() can sleep. + * @ies: This is a dynamically allocated array cacheing the + * IEs (settable by the host) that the beacon of this + * radio controller is currently sending. + * + * In reality, we store here the full command we set to + * the radio controller (which is basically a command + * prefix followed by all the IEs the beacon currently + * contains). This way we don't have to realloc and + * memcpy when setting it. + * + * We set this up in uwb_rc_ie_setup(), where we alloc + * this struct, call get_ie() [so we know which IEs are + * currently being sent, if any]. + * + * @ies_capacity:Amount of space (in bytes) allocated in @ies. The + * amount used is given by sizeof(*ies) plus ies->wIELength + * (which is a little endian quantity all the time). + * @ies_mutex: protect the IE cache + * @dbg: information for the debug interface + */ +struct uwb_rc { + struct uwb_dev uwb_dev; + int index; + u16 version; + + struct module *owner; + void *priv; + int (*start)(struct uwb_rc *rc); + void (*stop)(struct uwb_rc *rc); + int (*cmd)(struct uwb_rc *, const struct uwb_rccb *, size_t); + int (*reset)(struct uwb_rc *rc); + int (*filter_cmd)(struct uwb_rc *, struct uwb_rccb **, size_t *); + int (*filter_event)(struct uwb_rc *, struct uwb_rceb **, const size_t, + size_t *, size_t *); + + spinlock_t neh_lock; /* protects neh_* and ctx_* */ + struct list_head neh_list; /* Open NE handles */ + unsigned long ctx_bm[UWB_RC_CTX_MAX / 8 / sizeof(unsigned long)]; + u8 ctx_roll; + + int beaconing; /* Beaconing state [channel number] */ + int beaconing_forced; + int scanning; + enum uwb_scan_type scan_type:3; + unsigned ready:1; + struct uwb_notifs_chain notifs_chain; + struct uwb_beca uwb_beca; + + struct uwbd uwbd; + + struct uwb_drp_backoff_win bow; + struct uwb_drp_avail drp_avail; + struct list_head reservations; + struct list_head cnflt_alien_list; + struct uwb_mas_bm cnflt_alien_bitmap; + struct mutex rsvs_mutex; + spinlock_t rsvs_lock; + struct workqueue_struct *rsv_workq; + + struct delayed_work rsv_update_work; + struct delayed_work rsv_alien_bp_work; + int set_drp_ie_pending; + struct mutex ies_mutex; + struct uwb_rc_cmd_set_ie *ies; + size_t ies_capacity; + + struct list_head pals; + int active_pals; + + struct uwb_dbg *dbg; +}; + + +/** + * struct uwb_pal - a UWB PAL + * @name: descriptive name for this PAL (wusbhc, wlp, etc.). + * @device: a device for the PAL. Used to link the PAL and the radio + * controller in sysfs. + * @rc: the radio controller the PAL uses. + * @channel_changed: called when the channel used by the radio changes. + * A channel of -1 means the channel has been stopped. + * @new_rsv: called when a peer requests a reservation (may be NULL if + * the PAL cannot accept reservation requests). + * @channel: channel being used by the PAL; 0 if the PAL isn't using + * the radio; -1 if the PAL wishes to use the radio but + * cannot. + * @debugfs_dir: a debugfs directory which the PAL can use for its own + * debugfs files. + * + * A Protocol Adaptation Layer (PAL) is a user of the WiMedia UWB + * radio platform (e.g., WUSB, WLP or Bluetooth UWB AMP). + * + * The PALs using a radio controller must register themselves to + * permit the UWB stack to coordinate usage of the radio between the + * various PALs or to allow PALs to response to certain requests from + * peers. + * + * A struct uwb_pal should be embedded in a containing structure + * belonging to the PAL and initialized with uwb_pal_init()). Fields + * should be set appropriately by the PAL before registering the PAL + * with uwb_pal_register(). + */ +struct uwb_pal { + struct list_head node; + const char *name; + struct device *device; + struct uwb_rc *rc; + + void (*channel_changed)(struct uwb_pal *pal, int channel); + void (*new_rsv)(struct uwb_pal *pal, struct uwb_rsv *rsv); + + int channel; + struct dentry *debugfs_dir; +}; + +void uwb_pal_init(struct uwb_pal *pal); +int uwb_pal_register(struct uwb_pal *pal); +void uwb_pal_unregister(struct uwb_pal *pal); + +int uwb_radio_start(struct uwb_pal *pal); +void uwb_radio_stop(struct uwb_pal *pal); + +/* + * General public API + * + * This API can be used by UWB device drivers or by those implementing + * UWB Radio Controllers + */ +struct uwb_dev *uwb_dev_get_by_devaddr(struct uwb_rc *rc, + const struct uwb_dev_addr *devaddr); +struct uwb_dev *uwb_dev_get_by_rc(struct uwb_dev *, struct uwb_rc *); +static inline void uwb_dev_get(struct uwb_dev *uwb_dev) +{ + get_device(&uwb_dev->dev); +} +static inline void uwb_dev_put(struct uwb_dev *uwb_dev) +{ + put_device(&uwb_dev->dev); +} +struct uwb_dev *uwb_dev_try_get(struct uwb_rc *rc, struct uwb_dev *uwb_dev); + +/** + * Callback function for 'uwb_{dev,rc}_foreach()'. + * + * @dev: Linux device instance + * 'uwb_dev = container_of(dev, struct uwb_dev, dev)' + * @priv: Data passed by the caller to 'uwb_{dev,rc}_foreach()'. + * + * @returns: 0 to continue the iterations, any other val to stop + * iterating and return the value to the caller of + * _foreach(). + */ +typedef int (*uwb_dev_for_each_f)(struct device *dev, void *priv); +int uwb_dev_for_each(struct uwb_rc *rc, uwb_dev_for_each_f func, void *priv); + +struct uwb_rc *uwb_rc_alloc(void); +struct uwb_rc *uwb_rc_get_by_dev(const struct uwb_dev_addr *); +struct uwb_rc *uwb_rc_get_by_grandpa(const struct device *); +void uwb_rc_put(struct uwb_rc *rc); + +typedef void (*uwb_rc_cmd_cb_f)(struct uwb_rc *rc, void *arg, + struct uwb_rceb *reply, ssize_t reply_size); + +int uwb_rc_cmd_async(struct uwb_rc *rc, const char *cmd_name, + struct uwb_rccb *cmd, size_t cmd_size, + u8 expected_type, u16 expected_event, + uwb_rc_cmd_cb_f cb, void *arg); +ssize_t uwb_rc_cmd(struct uwb_rc *rc, const char *cmd_name, + struct uwb_rccb *cmd, size_t cmd_size, + struct uwb_rceb *reply, size_t reply_size); +ssize_t uwb_rc_vcmd(struct uwb_rc *rc, const char *cmd_name, + struct uwb_rccb *cmd, size_t cmd_size, + u8 expected_type, u16 expected_event, + struct uwb_rceb **preply); + +size_t __uwb_addr_print(char *, size_t, const unsigned char *, int); + +int uwb_rc_dev_addr_set(struct uwb_rc *, const struct uwb_dev_addr *); +int uwb_rc_dev_addr_get(struct uwb_rc *, struct uwb_dev_addr *); +int uwb_rc_mac_addr_set(struct uwb_rc *, const struct uwb_mac_addr *); +int uwb_rc_mac_addr_get(struct uwb_rc *, struct uwb_mac_addr *); +int __uwb_mac_addr_assigned_check(struct device *, void *); +int __uwb_dev_addr_assigned_check(struct device *, void *); + +/* Print in @buf a pretty repr of @addr */ +static inline size_t uwb_dev_addr_print(char *buf, size_t buf_size, + const struct uwb_dev_addr *addr) +{ + return __uwb_addr_print(buf, buf_size, addr->data, 0); +} + +/* Print in @buf a pretty repr of @addr */ +static inline size_t uwb_mac_addr_print(char *buf, size_t buf_size, + const struct uwb_mac_addr *addr) +{ + return __uwb_addr_print(buf, buf_size, addr->data, 1); +} + +/* @returns 0 if device addresses @addr2 and @addr1 are equal */ +static inline int uwb_dev_addr_cmp(const struct uwb_dev_addr *addr1, + const struct uwb_dev_addr *addr2) +{ + return memcmp(addr1, addr2, sizeof(*addr1)); +} + +/* @returns 0 if MAC addresses @addr2 and @addr1 are equal */ +static inline int uwb_mac_addr_cmp(const struct uwb_mac_addr *addr1, + const struct uwb_mac_addr *addr2) +{ + return memcmp(addr1, addr2, sizeof(*addr1)); +} + +/* @returns !0 if a MAC @addr is a broadcast address */ +static inline int uwb_mac_addr_bcast(const struct uwb_mac_addr *addr) +{ + struct uwb_mac_addr bcast = { + .data = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } + }; + return !uwb_mac_addr_cmp(addr, &bcast); +} + +/* @returns !0 if a MAC @addr is all zeroes*/ +static inline int uwb_mac_addr_unset(const struct uwb_mac_addr *addr) +{ + struct uwb_mac_addr unset = { + .data = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }; + return !uwb_mac_addr_cmp(addr, &unset); +} + +/* @returns !0 if the address is in use. */ +static inline unsigned __uwb_dev_addr_assigned(struct uwb_rc *rc, + struct uwb_dev_addr *addr) +{ + return uwb_dev_for_each(rc, __uwb_dev_addr_assigned_check, addr); +} + +/* + * UWB Radio Controller API + * + * This API is used (in addition to the general API) to implement UWB + * Radio Controllers. + */ +void uwb_rc_init(struct uwb_rc *); +int uwb_rc_add(struct uwb_rc *, struct device *dev, void *rc_priv); +void uwb_rc_rm(struct uwb_rc *); +void uwb_rc_neh_grok(struct uwb_rc *, void *, size_t); +void uwb_rc_neh_error(struct uwb_rc *, int); +void uwb_rc_reset_all(struct uwb_rc *rc); +void uwb_rc_pre_reset(struct uwb_rc *rc); +int uwb_rc_post_reset(struct uwb_rc *rc); + +/** + * uwb_rsv_is_owner - is the owner of this reservation the RC? + * @rsv: the reservation + */ +static inline bool uwb_rsv_is_owner(struct uwb_rsv *rsv) +{ + return rsv->owner == &rsv->rc->uwb_dev; +} + +/** + * enum uwb_notifs - UWB events that can be passed to any listeners + * @UWB_NOTIF_ONAIR: a new neighbour has joined the beacon group. + * @UWB_NOTIF_OFFAIR: a neighbour has left the beacon group. + * + * Higher layers can register callback functions with the radio + * controller using uwb_notifs_register(). The radio controller + * maintains a list of all registered handlers and will notify all + * nodes when an event occurs. + */ +enum uwb_notifs { + UWB_NOTIF_ONAIR, + UWB_NOTIF_OFFAIR, +}; + +/* Callback function registered with UWB */ +struct uwb_notifs_handler { + struct list_head list_node; + void (*cb)(void *, struct uwb_dev *, enum uwb_notifs); + void *data; +}; + +int uwb_notifs_register(struct uwb_rc *, struct uwb_notifs_handler *); +int uwb_notifs_deregister(struct uwb_rc *, struct uwb_notifs_handler *); + + +/** + * UWB radio controller Event Size Entry (for creating entry tables) + * + * WUSB and WHCI define events and notifications, and they might have + * fixed or variable size. + * + * Each event/notification has a size which is not necessarily known + * in advance based on the event code. As well, vendor specific + * events/notifications will have a size impossible to determine + * unless we know about the device's specific details. + * + * It was way too smart of the spec writers not to think that it would + * be impossible for a generic driver to skip over vendor specific + * events/notifications if there are no LENGTH fields in the HEADER of + * each message...the transaction size cannot be counted on as the + * spec does not forbid to pack more than one event in a single + * transaction. + * + * Thus, we guess sizes with tables (or for events, when you know the + * size ahead of time you can use uwb_rc_neh_extra_size*()). We + * register tables with the known events and their sizes, and then we + * traverse those tables. For those with variable length, we provide a + * way to lookup the size inside the event/notification's + * payload. This allows device-specific event size tables to be + * registered. + * + * @size: Size of the payload + * + * @offset: if != 0, at offset @offset-1 starts a field with a length + * that has to be added to @size. The format of the field is + * given by @type. + * + * @type: Type and length of the offset field. Most common is LE 16 + * bits (that's why that is zero); others are there mostly to + * cover for bugs and weirdos. + */ +struct uwb_est_entry { + size_t size; + unsigned offset; + enum { UWB_EST_16 = 0, UWB_EST_8 = 1 } type; +}; + +int uwb_est_register(u8 type, u8 code_high, u16 vendor, u16 product, + const struct uwb_est_entry *, size_t entries); +int uwb_est_unregister(u8 type, u8 code_high, u16 vendor, u16 product, + const struct uwb_est_entry *, size_t entries); +ssize_t uwb_est_find_size(struct uwb_rc *rc, const struct uwb_rceb *rceb, + size_t len); + +/* -- Misc */ + +enum { + EDC_MAX_ERRORS = 10, + EDC_ERROR_TIMEFRAME = HZ, +}; + +/* error density counter */ +struct edc { + unsigned long timestart; + u16 errorcount; +}; + +static inline +void edc_init(struct edc *edc) +{ + edc->timestart = jiffies; +} + +/* Called when an error occurred. + * This is way to determine if the number of acceptable errors per time + * period has been exceeded. It is not accurate as there are cases in which + * this scheme will not work, for example if there are periodic occurrences + * of errors that straddle updates to the start time. This scheme is + * sufficient for our usage. + * + * @returns 1 if maximum acceptable errors per timeframe has been exceeded. + */ +static inline int edc_inc(struct edc *err_hist, u16 max_err, u16 timeframe) +{ + unsigned long now; + + now = jiffies; + if (now - err_hist->timestart > timeframe) { + err_hist->errorcount = 1; + err_hist->timestart = now; + } else if (++err_hist->errorcount > max_err) { + err_hist->errorcount = 0; + err_hist->timestart = now; + return 1; + } + return 0; +} + + +/* Information Element handling */ + +struct uwb_ie_hdr *uwb_ie_next(void **ptr, size_t *len); +int uwb_rc_ie_add(struct uwb_rc *uwb_rc, const struct uwb_ie_hdr *ies, size_t size); +int uwb_rc_ie_rm(struct uwb_rc *uwb_rc, enum uwb_ie element_id); + +/* + * Transmission statistics + * + * UWB uses LQI and RSSI (one byte values) for reporting radio signal + * strength and line quality indication. We do quick and dirty + * averages of those. They are signed values, btw. + * + * For 8 bit quantities, we keep the min, the max, an accumulator + * (@sigma) and a # of samples. When @samples gets to 255, we compute + * the average (@sigma / @samples), place it in @sigma and reset + * @samples to 1 (so we use it as the first sample). + * + * Now, statistically speaking, probably I am kicking the kidneys of + * some books I have in my shelves collecting dust, but I just want to + * get an approx, not the Nobel. + * + * LOCKING: there is no locking per se, but we try to keep a lockless + * schema. Only _add_samples() modifies the values--as long as you + * have other locking on top that makes sure that no two calls of + * _add_sample() happen at the same time, then we are fine. Now, for + * resetting the values we just set @samples to 0 and that makes the + * next _add_sample() to start with defaults. Reading the values in + * _show() currently can race, so you need to make sure the calls are + * under the same lock that protects calls to _add_sample(). FIXME: + * currently unlocked (It is not ultraprecise but does the trick. Bite + * me). + */ +struct stats { + s8 min, max; + s16 sigma; + atomic_t samples; +}; + +static inline +void stats_init(struct stats *stats) +{ + atomic_set(&stats->samples, 0); + wmb(); +} + +static inline +void stats_add_sample(struct stats *stats, s8 sample) +{ + s8 min, max; + s16 sigma; + unsigned samples = atomic_read(&stats->samples); + if (samples == 0) { /* it was zero before, so we initialize */ + min = 127; + max = -128; + sigma = 0; + } else { + min = stats->min; + max = stats->max; + sigma = stats->sigma; + } + + if (sample < min) /* compute new values */ + min = sample; + else if (sample > max) + max = sample; + sigma += sample; + + stats->min = min; /* commit */ + stats->max = max; + stats->sigma = sigma; + if (atomic_add_return(1, &stats->samples) > 255) { + /* wrapped around! reset */ + stats->sigma = sigma / 256; + atomic_set(&stats->samples, 1); + } +} + +static inline ssize_t stats_show(struct stats *stats, char *buf) +{ + int min, max, avg; + int samples = atomic_read(&stats->samples); + if (samples == 0) + min = max = avg = 0; + else { + min = stats->min; + max = stats->max; + avg = stats->sigma / samples; + } + return scnprintf(buf, PAGE_SIZE, "%d %d %d\n", min, max, avg); +} + +static inline ssize_t stats_store(struct stats *stats, const char *buf, + size_t size) +{ + stats_init(stats); + return size; +} + +#endif /* #ifndef __LINUX__UWB_H__ */ diff --git a/drivers/uwb/uwbd.c b/drivers/staging/uwb/uwbd.c index dc5c743d4f5f..dc5c743d4f5f 100644 --- a/drivers/uwb/uwbd.c +++ b/drivers/staging/uwb/uwbd.c diff --git a/drivers/uwb/whc-rc.c b/drivers/staging/uwb/whc-rc.c index 22397f70dee2..34020ed351ab 100644 --- a/drivers/uwb/whc-rc.c +++ b/drivers/staging/uwb/whc-rc.c @@ -33,9 +33,9 @@ #include <linux/interrupt.h> #include <linux/slab.h> #include <linux/workqueue.h> -#include <linux/uwb.h> -#include <linux/uwb/whci.h> -#include <linux/uwb/umc.h> +#include "uwb.h" +#include "include/whci.h" +#include "include/umc.h" #include "uwb-internal.h" diff --git a/drivers/uwb/whci.c b/drivers/staging/uwb/whci.c index be8a8b8e857b..a8832f64d708 100644 --- a/drivers/uwb/whci.c +++ b/drivers/staging/uwb/whci.c @@ -10,8 +10,8 @@ #include <linux/pci.h> #include <linux/dma-mapping.h> #include <linux/slab.h> -#include <linux/uwb/whci.h> -#include <linux/uwb/umc.h> +#include "include/whci.h" +#include "include/umc.h" struct whci_card { struct pci_dev *pci; diff --git a/drivers/staging/wusbcore/Documentation/wusb-cbaf b/drivers/staging/wusbcore/Documentation/wusb-cbaf new file mode 100644 index 000000000000..8b3d43efce90 --- /dev/null +++ b/drivers/staging/wusbcore/Documentation/wusb-cbaf @@ -0,0 +1,130 @@ +#! /bin/bash +# + +set -e + +progname=$(basename $0) +function help +{ + cat <<EOF +Usage: $progname COMMAND DEVICEs [ARGS] + +Command for manipulating the pairing/authentication credentials of a +Wireless USB device that supports wired-mode Cable-Based-Association. + +Works in conjunction with the wusb-cba.ko driver from http://linuxuwb.org. + + +DEVICE + + sysfs path to the device to authenticate; for example, both this + guys are the same: + + /sys/devices/pci0000:00/0000:00:1d.7/usb1/1-4/1-4.4/1-4.4:1.1 + /sys/bus/usb/drivers/wusb-cbaf/1-4.4:1.1 + +COMMAND/ARGS are + + start + + Start a WUSB host controller (by setting up a CHID) + + set-chid DEVICE HOST-CHID HOST-BANDGROUP HOST-NAME + + Sets host information in the device; after this you can call the + get-cdid to see how does this device report itself to us. + + get-cdid DEVICE + + Get the device ID associated to the HOST-CHID we sent with + 'set-chid'. We might not know about it. + + set-cc DEVICE + + If we allow the device to connect, set a random new CDID and CK + (connection key). Device saves them for the next time it wants to + connect wireless. We save them for that next time also so we can + authenticate the device (when we see the CDID he uses to id + itself) and the CK to crypto talk to it. + +CHID is always 16 hex bytes in 'XX YY ZZ...' form +BANDGROUP is almost always 0001 + +Examples: + + You can default most arguments to '' to get a sane value: + + $ $progname set-chid '' '' '' "My host name" + + A full sequence: + + $ $progname set-chid '' '' '' "My host name" + $ $progname get-cdid '' + $ $progname set-cc '' + +EOF +} + + +# Defaults +# FIXME: CHID should come from a database :), band group from the host +host_CHID="00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff" +host_band_group="0001" +host_name=$(hostname) + +devs="$(echo /sys/bus/usb/drivers/wusb-cbaf/[0-9]*)" +hdevs="$(for h in /sys/class/uwb_rc/*/wusbhc; do readlink -f $h; done)" + +result=0 +case $1 in + start) + for dev in ${2:-$hdevs} + do + echo $host_CHID > $dev/wusb_chid + echo I: started host $(basename $dev) >&2 + done + ;; + stop) + for dev in ${2:-$hdevs} + do + echo 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > $dev/wusb_chid + echo I: stopped host $(basename $dev) >&2 + done + ;; + set-chid) + shift + for dev in ${2:-$devs}; do + echo "${4:-$host_name}" > $dev/wusb_host_name + echo "${3:-$host_band_group}" > $dev/wusb_host_band_groups + echo ${2:-$host_CHID} > $dev/wusb_chid + done + ;; + get-cdid) + for dev in ${2:-$devs} + do + cat $dev/wusb_cdid + done + ;; + set-cc) + for dev in ${2:-$devs}; do + shift + CDID="$(head --bytes=16 /dev/urandom | od -tx1 -An)" + CK="$(head --bytes=16 /dev/urandom | od -tx1 -An)" + echo "$CDID" > $dev/wusb_cdid + echo "$CK" > $dev/wusb_ck + + echo I: CC set >&2 + echo "CHID: $(cat $dev/wusb_chid)" + echo "CDID:$CDID" + echo "CK: $CK" + done + ;; + help|h|--help|-h) + help + ;; + *) + echo "E: Unknown usage" 1>&2 + help 1>&2 + result=1 +esac +exit $result diff --git a/drivers/staging/wusbcore/Documentation/wusb-design-overview.rst b/drivers/staging/wusbcore/Documentation/wusb-design-overview.rst new file mode 100644 index 000000000000..dc5e21609bb5 --- /dev/null +++ b/drivers/staging/wusbcore/Documentation/wusb-design-overview.rst @@ -0,0 +1,457 @@ +================================ +Linux UWB + Wireless USB + WiNET +================================ + + Copyright (C) 2005-2006 Intel Corporation + + Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License version + 2 as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. + + +Please visit http://bughost.org/thewiki/Design-overview.txt-1.8 for +updated content. + + * Design-overview.txt-1.8 + +This code implements a Ultra Wide Band stack for Linux, as well as +drivers for the USB based UWB radio controllers defined in the +Wireless USB 1.0 specification (including Wireless USB host controller +and an Intel WiNET controller). + +.. Contents + 1. Introduction + 1. HWA: Host Wire adapters, your Wireless USB dongle + + 2. DWA: Device Wired Adaptor, a Wireless USB hub for wired + devices + 3. WHCI: Wireless Host Controller Interface, the PCI WUSB host + adapter + 2. The UWB stack + 1. Devices and hosts: the basic structure + + 2. Host Controller life cycle + + 3. On the air: beacons and enumerating the radio neighborhood + + 4. Device lists + 5. Bandwidth allocation + + 3. Wireless USB Host Controller drivers + + 4. Glossary + + +Introduction +============ + +UWB is a wide-band communication protocol that is to serve also as the +low-level protocol for others (much like TCP sits on IP). Currently +these others are Wireless USB and TCP/IP, but seems Bluetooth and +Firewire/1394 are coming along. + +UWB uses a band from roughly 3 to 10 GHz, transmitting at a max of +~-41dB (or 0.074 uW/MHz--geography specific data is still being +negotiated w/ regulators, so watch for changes). That band is divided in +a bunch of ~1.5 GHz wide channels (or band groups) composed of three +subbands/subchannels (528 MHz each). Each channel is independent of each +other, so you could consider them different "busses". Initially this +driver considers them all a single one. + +Radio time is divided in 65536 us long /superframes/, each one divided +in 256 256us long /MASs/ (Media Allocation Slots), which are the basic +time/media allocation units for transferring data. At the beginning of +each superframe there is a Beacon Period (BP), where every device +transmit its beacon on a single MAS. The length of the BP depends on how +many devices are present and the length of their beacons. + +Devices have a MAC (fixed, 48 bit address) and a device (changeable, 16 +bit address) and send periodic beacons to advertise themselves and pass +info on what they are and do. They advertise their capabilities and a +bunch of other stuff. + +The different logical parts of this driver are: + + * + + *UWB*: the Ultra-Wide-Band stack -- manages the radio and + associated spectrum to allow for devices sharing it. Allows to + control bandwidth assignment, beaconing, scanning, etc + + * + + *WUSB*: the layer that sits on top of UWB to provide Wireless USB. + The Wireless USB spec defines means to control a UWB radio and to + do the actual WUSB. + + +HWA: Host Wire adapters, your Wireless USB dongle +------------------------------------------------- + +WUSB also defines a device called a Host Wire Adaptor (HWA), which in +mere terms is a USB dongle that enables your PC to have UWB and Wireless +USB. The Wireless USB Host Controller in a HWA looks to the host like a +[Wireless] USB controller connected via USB (!) + +The HWA itself is broken in two or three main interfaces: + + * + + *RC*: Radio control -- this implements an interface to the + Ultra-Wide-Band radio controller. The driver for this implements a + USB-based UWB Radio Controller to the UWB stack. + + * + + *HC*: the wireless USB host controller. It looks like a USB host + whose root port is the radio and the WUSB devices connect to it. + To the system it looks like a separate USB host. The driver (will) + implement a USB host controller (similar to UHCI, OHCI or EHCI) + for which the root hub is the radio...To reiterate: it is a USB + controller that is connected via USB instead of PCI. + + * + + *WINET*: some HW provide a WiNET interface (IP over UWB). This + package provides a driver for it (it looks like a network + interface, winetX). The driver detects when there is a link up for + their type and kick into gear. + + +DWA: Device Wired Adaptor, a Wireless USB hub for wired devices +--------------------------------------------------------------- + +These are the complement to HWAs. They are a USB host for connecting +wired devices, but it is connected to your PC connected via Wireless +USB. To the system it looks like yet another USB host. To the untrained +eye, it looks like a hub that connects upstream wirelessly. + +We still offer no support for this; however, it should share a lot of +code with the HWA-RC driver; there is a bunch of factorization work that +has been done to support that in upcoming releases. + + +WHCI: Wireless Host Controller Interface, the PCI WUSB host adapter +------------------------------------------------------------------- + +This is your usual PCI device that implements WHCI. Similar in concept +to EHCI, it allows your wireless USB devices (including DWAs) to connect +to your host via a PCI interface. As in the case of the HWA, it has a +Radio Control interface and the WUSB Host Controller interface per se. + +There is still no driver support for this, but will be in upcoming +releases. + + +The UWB stack +============= + +The main mission of the UWB stack is to keep a tally of which devices +are in radio proximity to allow drivers to connect to them. As well, it +provides an API for controlling the local radio controllers (RCs from +now on), such as to start/stop beaconing, scan, allocate bandwidth, etc. + + +Devices and hosts: the basic structure +-------------------------------------- + +The main building block here is the UWB device (struct uwb_dev). For +each device that pops up in radio presence (ie: the UWB host receives a +beacon from it) you get a struct uwb_dev that will show up in +/sys/bus/uwb/devices. + +For each RC that is detected, a new struct uwb_rc and struct uwb_dev are +created. An entry is also created in /sys/class/uwb_rc for each RC. + +Each RC driver is implemented by a separate driver that plugs into the +interface that the UWB stack provides through a struct uwb_rc_ops. The +spec creators have been nice enough to make the message format the same +for HWA and WHCI RCs, so the driver is really a very thin transport that +moves the requests from the UWB API to the device [/uwb_rc_ops->cmd()/] +and sends the replies and notifications back to the API +[/uwb_rc_neh_grok()/]. Notifications are handled to the UWB daemon, that +is chartered, among other things, to keep the tab of how the UWB radio +neighborhood looks, creating and destroying devices as they show up or +disappear. + +Command execution is very simple: a command block is sent and a event +block or reply is expected back. For sending/receiving command/events, a +handle called /neh/ (Notification/Event Handle) is opened with +/uwb_rc_neh_open()/. + +The HWA-RC (USB dongle) driver (drivers/uwb/hwa-rc.c) does this job for +the USB connected HWA. Eventually, drivers/whci-rc.c will do the same +for the PCI connected WHCI controller. + + +Host Controller life cycle +-------------------------- + +So let's say we connect a dongle to the system: it is detected and +firmware uploaded if needed [for Intel's i1480 +/drivers/uwb/ptc/usb.c:ptc_usb_probe()/] and then it is reenumerated. +Now we have a real HWA device connected and +/drivers/uwb/hwa-rc.c:hwarc_probe()/ picks it up, that will set up the +Wire-Adaptor environment and then suck it into the UWB stack's vision of +the world [/drivers/uwb/lc-rc.c:uwb_rc_add()/]. + + * + + [*] The stack should put a new RC to scan for devices + [/uwb_rc_scan()/] so it finds what's available around and tries to + connect to them, but this is policy stuff and should be driven + from user space. As of now, the operator is expected to do it + manually; see the release notes for documentation on the procedure. + +When a dongle is disconnected, /drivers/uwb/hwa-rc.c:hwarc_disconnect()/ +takes time of tearing everything down safely (or not...). + + +On the air: beacons and enumerating the radio neighborhood +---------------------------------------------------------- + +So assuming we have devices and we have agreed for a channel to connect +on (let's say 9), we put the new RC to beacon: + + * + + $ echo 9 0 > /sys/class/uwb_rc/uwb0/beacon + +Now it is visible. If there were other devices in the same radio channel +and beacon group (that's what the zero is for), the dongle's radio +control interface will send beacon notifications on its +notification/event endpoint (NEEP). The beacon notifications are part of +the event stream that is funneled into the API with +/drivers/uwb/neh.c:uwb_rc_neh_grok()/ and delivered to the UWBD, the UWB +daemon through a notification list. + +UWBD wakes up and scans the event list; finds a beacon and adds it to +the BEACON CACHE (/uwb_beca/). If he receives a number of beacons from +the same device, he considers it to be 'onair' and creates a new device +[/drivers/uwb/lc-dev.c:uwbd_dev_onair()/]. Similarly, when no beacons +are received in some time, the device is considered gone and wiped out +[uwbd calls periodically /uwb/beacon.c:uwb_beca_purge()/ that will purge +the beacon cache of dead devices]. + + +Device lists +------------ + +All UWB devices are kept in the list of the struct bus_type uwb_bus_type. + + +Bandwidth allocation +-------------------- + +The UWB stack maintains a local copy of DRP availability through +processing of incoming *DRP Availability Change* notifications. This +local copy is currently used to present the current bandwidth +availability to the user through the sysfs file +/sys/class/uwb_rc/uwbx/bw_avail. In the future the bandwidth +availability information will be used by the bandwidth reservation +routines. + +The bandwidth reservation routines are in progress and are thus not +present in the current release. When completed they will enable a user +to initiate DRP reservation requests through interaction with sysfs. DRP +reservation requests from remote UWB devices will also be handled. The +bandwidth management done by the UWB stack will include callbacks to the +higher layers will enable the higher layers to use the reservations upon +completion. [Note: The bandwidth reservation work is in progress and +subject to change.] + + +Wireless USB Host Controller drivers +==================================== + +*WARNING* This section needs a lot of work! + +As explained above, there are three different types of HCs in the WUSB +world: HWA-HC, DWA-HC and WHCI-HC. + +HWA-HC and DWA-HC share that they are Wire-Adapters (USB or WUSB +connected controllers), and their transfer management system is almost +identical. So is their notification delivery system. + +HWA-HC and WHCI-HC share that they are both WUSB host controllers, so +they have to deal with WUSB device life cycle and maintenance, wireless +root-hub + +HWA exposes a Host Controller interface (HWA-HC 0xe0/02/02). This has +three endpoints (Notifications, Data Transfer In and Data Transfer +Out--known as NEP, DTI and DTO in the code). + +We reserve UWB bandwidth for our Wireless USB Cluster, create a Cluster +ID and tell the HC to use all that. Then we start it. This means the HC +starts sending MMCs. + + * + + The MMCs are blocks of data defined somewhere in the WUSB1.0 spec + that define a stream in the UWB channel time allocated for sending + WUSB IEs (host to device commands/notifications) and Device + Notifications (device initiated to host). Each host defines a + unique Wireless USB cluster through MMCs. Devices can connect to a + single cluster at the time. The IEs are Information Elements, and + among them are the bandwidth allocations that tell each device + when can they transmit or receive. + +Now it all depends on external stimuli. + +New device connection +--------------------- + +A new device pops up, it scans the radio looking for MMCs that give out +the existence of Wireless USB channels. Once one (or more) are found, +selects which one to connect to. Sends a /DN_Connect/ (device +notification connect) during the DNTS (Device Notification Time +Slot--announced in the MMCs + +HC picks the /DN_Connect/ out (nep module sends to notif.c for delivery +into /devconnect/). This process starts the authentication process for +the device. First we allocate a /fake port/ and assign an +unauthenticated address (128 to 255--what we really do is +0x80 | fake_port_idx). We fiddle with the fake port status and /hub_wq/ +sees a new connection, so he moves on to enable the fake port with a reset. + +So now we are in the reset path -- we know we have a non-yet enumerated +device with an unauthorized address; we ask user space to authenticate +(FIXME: not yet done, similar to bluetooth pairing), then we do the key +exchange (FIXME: not yet done) and issue a /set address 0/ to bring the +device to the default state. Device is authenticated. + +From here, the USB stack takes control through the usb_hcd ops. hub_wq +has seen the port status changes, as we have been toggling them. It will +start enumerating and doing transfers through usb_hcd->urb_enqueue() to +read descriptors and move our data. + +Device life cycle and keep alives +--------------------------------- + +Every time there is a successful transfer to/from a device, we update a +per-device activity timestamp. If not, every now and then we check and +if the activity timestamp gets old, we ping the device by sending it a +Keep Alive IE; it responds with a /DN_Alive/ pong during the DNTS (this +arrives to us as a notification through +devconnect.c:wusb_handle_dn_alive(). If a device times out, we +disconnect it from the system (cleaning up internal information and +toggling the bits in the fake hub port, which kicks hub_wq into removing +the rest of the stuff). + +This is done through devconnect:__wusb_check_devs(), which will scan the +device list looking for whom needs refreshing. + +If the device wants to disconnect, it will either die (ugly) or send a +/DN_Disconnect/ that will prompt a disconnection from the system. + +Sending and receiving data +-------------------------- + +Data is sent and received through /Remote Pipes/ (rpipes). An rpipe is +/aimed/ at an endpoint in a WUSB device. This is the same for HWAs and +DWAs. + +Each HC has a number of rpipes and buffers that can be assigned to them; +when doing a data transfer (xfer), first the rpipe has to be aimed and +prepared (buffers assigned), then we can start queueing requests for +data in or out. + +Data buffers have to be segmented out before sending--so we send first a +header (segment request) and then if there is any data, a data buffer +immediately after to the DTI interface (yep, even the request). If our +buffer is bigger than the max segment size, then we just do multiple +requests. + +[This sucks, because doing USB scatter gatter in Linux is resource +intensive, if any...not that the current approach is not. It just has to +be cleaned up a lot :)]. + +If reading, we don't send data buffers, just the segment headers saying +we want to read segments. + +When the xfer is executed, we receive a notification that says data is +ready in the DTI endpoint (handled through +xfer.c:wa_handle_notif_xfer()). In there we read from the DTI endpoint a +descriptor that gives us the status of the transfer, its identification +(given when we issued it) and the segment number. If it was a data read, +we issue another URB to read into the destination buffer the chunk of +data coming out of the remote endpoint. Done, wait for the next guy. The +callbacks for the URBs issued from here are the ones that will declare +the xfer complete at some point and call its callback. + +Seems simple, but the implementation is not trivial. + + * + + *WARNING* Old!! + +The main xfer descriptor, wa_xfer (equivalent to a URB) contains an +array of segments, tallys on segments and buffers and callback +information. Buried in there is a lot of URBs for executing the segments +and buffer transfers. + +For OUT xfers, there is an array of segments, one URB for each, another +one of buffer URB. When submitting, we submit URBs for segment request +1, buffer 1, segment 2, buffer 2...etc. Then we wait on the DTI for xfer +result data; when all the segments are complete, we call the callback to +finalize the transfer. + +For IN xfers, we only issue URBs for the segments we want to read and +then wait for the xfer result data. + +URB mapping into xfers +^^^^^^^^^^^^^^^^^^^^^^ + +This is done by hwahc_op_urb_[en|de]queue(). In enqueue() we aim an +rpipe to the endpoint where we have to transmit, create a transfer +context (wa_xfer) and submit it. When the xfer is done, our callback is +called and we assign the status bits and release the xfer resources. + +In dequeue() we are basically cancelling/aborting the transfer. We issue +a xfer abort request to the HC, cancel all the URBs we had submitted +and not yet done and when all that is done, the xfer callback will be +called--this will call the URB callback. + + +Glossary +======== + +*DWA* -- Device Wire Adapter + +USB host, wired for downstream devices, upstream connects wirelessly +with Wireless USB. + +*EVENT* -- Response to a command on the NEEP + +*HWA* -- Host Wire Adapter / USB dongle for UWB and Wireless USB + +*NEH* -- Notification/Event Handle + +Handle/file descriptor for receiving notifications or events. The WA +code requires you to get one of this to listen for notifications or +events on the NEEP. + +*NEEP* -- Notification/Event EndPoint + +Stuff related to the management of the first endpoint of a HWA USB +dongle that is used to deliver an stream of events and notifications to +the host. + +*NOTIFICATION* -- Message coming in the NEEP as response to something. + +*RC* -- Radio Control + +Design-overview.txt-1.8 (last edited 2006-11-04 12:22:24 by +InakyPerezGonzalez) diff --git a/drivers/usb/wusbcore/Kconfig b/drivers/staging/wusbcore/Kconfig index abc0f361021f..056c60b4d57f 100644 --- a/drivers/usb/wusbcore/Kconfig +++ b/drivers/staging/wusbcore/Kconfig @@ -36,3 +36,4 @@ config USB_WUSB_CBAF_DEBUG to the system log. Select this if you are having a problem with CBA support and want to see more of what is going on. +source "drivers/staging/wusbcore/host/Kconfig" diff --git a/drivers/usb/wusbcore/Makefile b/drivers/staging/wusbcore/Makefile index d604ccdd916f..b47b874268ac 100644 --- a/drivers/usb/wusbcore/Makefile +++ b/drivers/staging/wusbcore/Makefile @@ -24,3 +24,5 @@ wusb-wa-y := \ wa-nep.o \ wa-rpipe.o \ wa-xfer.o + +obj-y += host/ diff --git a/drivers/staging/wusbcore/TODO b/drivers/staging/wusbcore/TODO new file mode 100644 index 000000000000..abae57000534 --- /dev/null +++ b/drivers/staging/wusbcore/TODO @@ -0,0 +1,8 @@ +TODO: Remove in late 2019 unless there are users + +There seems to not be any real wireless USB devices anywhere in the wild +anymore. It turned out to be a failed technology :( + +This will be removed from the tree if no one objects. + +Greg Kroah-Hartman <gregkh@linuxfoundation.org> diff --git a/drivers/usb/wusbcore/cbaf.c b/drivers/staging/wusbcore/cbaf.c index af77064c7456..57062eaf7558 100644 --- a/drivers/usb/wusbcore/cbaf.c +++ b/drivers/staging/wusbcore/cbaf.c @@ -80,9 +80,9 @@ #include <linux/random.h> #include <linux/slab.h> #include <linux/mutex.h> -#include <linux/uwb.h> -#include <linux/usb/wusb.h> -#include <linux/usb/association.h> +#include "../uwb/uwb.h" +#include "include/wusb.h" +#include "include/association.h" #define CBA_NAME_LEN 0x40 /* [WUSB-AM] table 4-7 */ diff --git a/drivers/usb/wusbcore/crypto.c b/drivers/staging/wusbcore/crypto.c index 9ee66483ee54..d7d55ed19a98 100644 --- a/drivers/usb/wusbcore/crypto.c +++ b/drivers/staging/wusbcore/crypto.c @@ -38,10 +38,10 @@ #include <linux/crypto.h> #include <linux/module.h> #include <linux/err.h> -#include <linux/uwb.h> #include <linux/slab.h> -#include <linux/usb/wusb.h> #include <linux/scatterlist.h> +#include "../uwb/uwb.h" +#include "include/wusb.h" static int debug_crypto_verify; diff --git a/drivers/usb/wusbcore/dev-sysfs.c b/drivers/staging/wusbcore/dev-sysfs.c index 67b0a4c412b2..67b0a4c412b2 100644 --- a/drivers/usb/wusbcore/dev-sysfs.c +++ b/drivers/staging/wusbcore/dev-sysfs.c diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/staging/wusbcore/devconnect.c index 1170f8baf608..1170f8baf608 100644 --- a/drivers/usb/wusbcore/devconnect.c +++ b/drivers/staging/wusbcore/devconnect.c diff --git a/drivers/staging/wusbcore/host/Kconfig b/drivers/staging/wusbcore/host/Kconfig new file mode 100644 index 000000000000..9a73f9360a08 --- /dev/null +++ b/drivers/staging/wusbcore/host/Kconfig @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: GPL-2.0 + +config USB_WHCI_HCD + tristate "Wireless USB Host Controller Interface (WHCI) driver" + depends on USB_PCI && USB && UWB + select USB_WUSB + select UWB_WHCI + help + A driver for PCI-based Wireless USB Host Controllers that are + compliant with the WHCI specification. + + To compile this driver a module, choose M here: the module + will be called "whci-hcd". + +config USB_HWA_HCD + tristate "Host Wire Adapter (HWA) driver" + depends on USB && UWB + select USB_WUSB + select UWB_HWA + help + This driver enables you to connect Wireless USB devices to + your system using a Host Wire Adaptor USB dongle. This is an + UWB Radio Controller and WUSB Host Controller connected to + your machine via USB (specified in WUSB1.0). + + To compile this driver a module, choose M here: the module + will be called "hwa-hc". + diff --git a/drivers/staging/wusbcore/host/Makefile b/drivers/staging/wusbcore/host/Makefile new file mode 100644 index 000000000000..d65ee8a73e21 --- /dev/null +++ b/drivers/staging/wusbcore/host/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_USB_WHCI_HCD) += whci/ +obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o diff --git a/drivers/usb/host/hwa-hc.c b/drivers/staging/wusbcore/host/hwa-hc.c index 6968b9f2b76b..8d959e91fe27 100644 --- a/drivers/usb/host/hwa-hc.c +++ b/drivers/staging/wusbcore/host/hwa-hc.c @@ -45,8 +45,8 @@ #include <linux/workqueue.h> #include <linux/wait.h> #include <linux/completion.h> -#include "../wusbcore/wa-hc.h" -#include "../wusbcore/wusbhc.h" +#include "../wa-hc.h" +#include "../wusbhc.h" struct hwahc { struct wusbhc wusbhc; /* has to be 1st */ diff --git a/drivers/usb/host/whci/Makefile b/drivers/staging/wusbcore/host/whci/Makefile index 859d20079df6..859d20079df6 100644 --- a/drivers/usb/host/whci/Makefile +++ b/drivers/staging/wusbcore/host/whci/Makefile diff --git a/drivers/usb/host/whci/asl.c b/drivers/staging/wusbcore/host/whci/asl.c index 276fb34c8efd..a2b9a50cfb80 100644 --- a/drivers/usb/host/whci/asl.c +++ b/drivers/staging/wusbcore/host/whci/asl.c @@ -7,10 +7,10 @@ #include <linux/kernel.h> #include <linux/gfp.h> #include <linux/dma-mapping.h> -#include <linux/uwb/umc.h> #include <linux/usb.h> -#include "../../wusbcore/wusbhc.h" +#include "../../../uwb/include/umc.h" +#include "../../wusbhc.h" #include "whcd.h" diff --git a/drivers/usb/host/whci/debug.c b/drivers/staging/wusbcore/host/whci/debug.c index 8ddfe3f1f693..443da6719147 100644 --- a/drivers/usb/host/whci/debug.c +++ b/drivers/staging/wusbcore/host/whci/debug.c @@ -10,7 +10,7 @@ #include <linux/seq_file.h> #include <linux/export.h> -#include "../../wusbcore/wusbhc.h" +#include "../../wusbhc.h" #include "whcd.h" diff --git a/drivers/usb/host/whci/hcd.c b/drivers/staging/wusbcore/host/whci/hcd.c index 8af9dcfea127..bee1ff2d35be 100644 --- a/drivers/usb/host/whci/hcd.c +++ b/drivers/staging/wusbcore/host/whci/hcd.c @@ -7,9 +7,9 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> -#include <linux/uwb/umc.h> -#include "../../wusbcore/wusbhc.h" +#include "../../../uwb/include/umc.h" +#include "../../wusbhc.h" #include "whcd.h" diff --git a/drivers/usb/host/whci/hw.c b/drivers/staging/wusbcore/host/whci/hw.c index 22b3b7f7419d..e4e8914abf42 100644 --- a/drivers/usb/host/whci/hw.c +++ b/drivers/staging/wusbcore/host/whci/hw.c @@ -6,9 +6,9 @@ */ #include <linux/kernel.h> #include <linux/dma-mapping.h> -#include <linux/uwb/umc.h> -#include "../../wusbcore/wusbhc.h" +#include "../../../uwb/include/umc.h" +#include "../../wusbhc.h" #include "whcd.h" diff --git a/drivers/usb/host/whci/init.c b/drivers/staging/wusbcore/host/whci/init.c index 82416973f773..55fd458a8f30 100644 --- a/drivers/usb/host/whci/init.c +++ b/drivers/staging/wusbcore/host/whci/init.c @@ -7,9 +7,9 @@ #include <linux/kernel.h> #include <linux/gfp.h> #include <linux/dma-mapping.h> -#include <linux/uwb/umc.h> -#include "../../wusbcore/wusbhc.h" +#include "../../../uwb/include/umc.h" +#include "../../wusbhc.h" #include "whcd.h" diff --git a/drivers/usb/host/whci/int.c b/drivers/staging/wusbcore/host/whci/int.c index 7e4ad1b8f3e3..bdbe35e9366f 100644 --- a/drivers/usb/host/whci/int.c +++ b/drivers/staging/wusbcore/host/whci/int.c @@ -5,9 +5,9 @@ * Copyright (C) 2007 Cambridge Silicon Radio Ltd. */ #include <linux/kernel.h> -#include <linux/uwb/umc.h> -#include "../../wusbcore/wusbhc.h" +#include "../../../uwb/include/umc.h" +#include "../../wusbhc.h" #include "whcd.h" diff --git a/drivers/usb/host/whci/pzl.c b/drivers/staging/wusbcore/host/whci/pzl.c index ef52aeb02fde..6dfc075f5798 100644 --- a/drivers/usb/host/whci/pzl.c +++ b/drivers/staging/wusbcore/host/whci/pzl.c @@ -7,10 +7,10 @@ #include <linux/kernel.h> #include <linux/gfp.h> #include <linux/dma-mapping.h> -#include <linux/uwb/umc.h> #include <linux/usb.h> -#include "../../wusbcore/wusbhc.h" +#include "../../../uwb/include/umc.h" +#include "../../wusbhc.h" #include "whcd.h" diff --git a/drivers/usb/host/whci/qset.c b/drivers/staging/wusbcore/host/whci/qset.c index 925166a207aa..66459b77dc77 100644 --- a/drivers/usb/host/whci/qset.c +++ b/drivers/staging/wusbcore/host/whci/qset.c @@ -7,10 +7,10 @@ #include <linux/kernel.h> #include <linux/dma-mapping.h> #include <linux/slab.h> -#include <linux/uwb/umc.h> #include <linux/usb.h> -#include "../../wusbcore/wusbhc.h" +#include "../../../uwb/include/umc.h" +#include "../../wusbhc.h" #include "whcd.h" diff --git a/drivers/usb/host/whci/whcd.h b/drivers/staging/wusbcore/host/whci/whcd.h index 139476997e7c..a442a2589e83 100644 --- a/drivers/usb/host/whci/whcd.h +++ b/drivers/staging/wusbcore/host/whci/whcd.h @@ -7,10 +7,10 @@ #ifndef __WHCD_H #define __WHCD_H -#include <linux/uwb/whci.h> -#include <linux/uwb/umc.h> #include <linux/workqueue.h> +#include "../../../uwb/include/whci.h" +#include "../../../uwb/include/umc.h" #include "whci-hc.h" /* Generic command timeout. */ diff --git a/drivers/usb/host/whci/whci-hc.h b/drivers/staging/wusbcore/host/whci/whci-hc.h index 5a86a57a80cc..5a86a57a80cc 100644 --- a/drivers/usb/host/whci/whci-hc.h +++ b/drivers/staging/wusbcore/host/whci/whci-hc.h diff --git a/drivers/usb/host/whci/wusb.c b/drivers/staging/wusbcore/host/whci/wusb.c index 8a4d805ff63a..6d0068ab35e4 100644 --- a/drivers/usb/host/whci/wusb.c +++ b/drivers/staging/wusbcore/host/whci/wusb.c @@ -5,9 +5,9 @@ * Copyright (C) 2007 Cambridge Silicon Radio Ltd. */ #include <linux/kernel.h> -#include <linux/uwb/umc.h> -#include "../../wusbcore/wusbhc.h" +#include "../../../uwb/include/umc.h" +#include "../../wusbhc.h" #include "whcd.h" diff --git a/drivers/staging/wusbcore/include/association.h b/drivers/staging/wusbcore/include/association.h new file mode 100644 index 000000000000..d7f3cb9b9db5 --- /dev/null +++ b/drivers/staging/wusbcore/include/association.h @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Wireless USB - Cable Based Association + * + * Copyright (C) 2006 Intel Corporation + * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + */ +#ifndef __LINUX_USB_ASSOCIATION_H +#define __LINUX_USB_ASSOCIATION_H + + +/* + * Association attributes + * + * Association Models Supplement to WUSB 1.0 T[3-1] + * + * Each field in the structures has it's ID, it's length and then the + * value. This is the actual definition of the field's ID and its + * length. + */ +struct wusb_am_attr { + __u8 id; + __u8 len; +}; + +/* Different fields defined by the spec */ +#define WUSB_AR_AssociationTypeId { .id = cpu_to_le16(0x0000), .len = cpu_to_le16(2) } +#define WUSB_AR_AssociationSubTypeId { .id = cpu_to_le16(0x0001), .len = cpu_to_le16(2) } +#define WUSB_AR_Length { .id = cpu_to_le16(0x0002), .len = cpu_to_le16(4) } +#define WUSB_AR_AssociationStatus { .id = cpu_to_le16(0x0004), .len = cpu_to_le16(4) } +#define WUSB_AR_LangID { .id = cpu_to_le16(0x0008), .len = cpu_to_le16(2) } +#define WUSB_AR_DeviceFriendlyName { .id = cpu_to_le16(0x000b), .len = cpu_to_le16(64) } /* max */ +#define WUSB_AR_HostFriendlyName { .id = cpu_to_le16(0x000c), .len = cpu_to_le16(64) } /* max */ +#define WUSB_AR_CHID { .id = cpu_to_le16(0x1000), .len = cpu_to_le16(16) } +#define WUSB_AR_CDID { .id = cpu_to_le16(0x1001), .len = cpu_to_le16(16) } +#define WUSB_AR_ConnectionContext { .id = cpu_to_le16(0x1002), .len = cpu_to_le16(48) } +#define WUSB_AR_BandGroups { .id = cpu_to_le16(0x1004), .len = cpu_to_le16(2) } + +/* CBAF Control Requests (AMS1.0[T4-1] */ +enum { + CBAF_REQ_GET_ASSOCIATION_INFORMATION = 0x01, + CBAF_REQ_GET_ASSOCIATION_REQUEST, + CBAF_REQ_SET_ASSOCIATION_RESPONSE +}; + +/* + * CBAF USB-interface defitions + * + * No altsettings, one optional interrupt endpoint. + */ +enum { + CBAF_IFACECLASS = 0xef, + CBAF_IFACESUBCLASS = 0x03, + CBAF_IFACEPROTOCOL = 0x01, +}; + +/* Association Information (AMS1.0[T4-3]) */ +struct wusb_cbaf_assoc_info { + __le16 Length; + __u8 NumAssociationRequests; + __le16 Flags; + __u8 AssociationRequestsArray[]; +} __attribute__((packed)); + +/* Association Request (AMS1.0[T4-4]) */ +struct wusb_cbaf_assoc_request { + __u8 AssociationDataIndex; + __u8 Reserved; + __le16 AssociationTypeId; + __le16 AssociationSubTypeId; + __le32 AssociationTypeInfoSize; +} __attribute__((packed)); + +enum { + AR_TYPE_WUSB = 0x0001, + AR_TYPE_WUSB_RETRIEVE_HOST_INFO = 0x0000, + AR_TYPE_WUSB_ASSOCIATE = 0x0001, +}; + +/* Association Attribute header (AMS1.0[3.8]) */ +struct wusb_cbaf_attr_hdr { + __le16 id; + __le16 len; +} __attribute__((packed)); + +/* Host Info (AMS1.0[T4-7]) (yeah, more headers and fields...) */ +struct wusb_cbaf_host_info { + struct wusb_cbaf_attr_hdr AssociationTypeId_hdr; + __le16 AssociationTypeId; + struct wusb_cbaf_attr_hdr AssociationSubTypeId_hdr; + __le16 AssociationSubTypeId; + struct wusb_cbaf_attr_hdr CHID_hdr; + struct wusb_ckhdid CHID; + struct wusb_cbaf_attr_hdr LangID_hdr; + __le16 LangID; + struct wusb_cbaf_attr_hdr HostFriendlyName_hdr; + __u8 HostFriendlyName[]; +} __attribute__((packed)); + +/* Device Info (AMS1.0[T4-8]) + * + * I still don't get this tag'n'header stuff for each goddamn + * field... + */ +struct wusb_cbaf_device_info { + struct wusb_cbaf_attr_hdr Length_hdr; + __le32 Length; + struct wusb_cbaf_attr_hdr CDID_hdr; + struct wusb_ckhdid CDID; + struct wusb_cbaf_attr_hdr BandGroups_hdr; + __le16 BandGroups; + struct wusb_cbaf_attr_hdr LangID_hdr; + __le16 LangID; + struct wusb_cbaf_attr_hdr DeviceFriendlyName_hdr; + __u8 DeviceFriendlyName[]; +} __attribute__((packed)); + +/* Connection Context; CC_DATA - Success case (AMS1.0[T4-9]) */ +struct wusb_cbaf_cc_data { + struct wusb_cbaf_attr_hdr AssociationTypeId_hdr; + __le16 AssociationTypeId; + struct wusb_cbaf_attr_hdr AssociationSubTypeId_hdr; + __le16 AssociationSubTypeId; + struct wusb_cbaf_attr_hdr Length_hdr; + __le32 Length; + struct wusb_cbaf_attr_hdr ConnectionContext_hdr; + struct wusb_ckhdid CHID; + struct wusb_ckhdid CDID; + struct wusb_ckhdid CK; + struct wusb_cbaf_attr_hdr BandGroups_hdr; + __le16 BandGroups; +} __attribute__((packed)); + +/* CC_DATA - Failure case (AMS1.0[T4-10]) */ +struct wusb_cbaf_cc_data_fail { + struct wusb_cbaf_attr_hdr AssociationTypeId_hdr; + __le16 AssociationTypeId; + struct wusb_cbaf_attr_hdr AssociationSubTypeId_hdr; + __le16 AssociationSubTypeId; + struct wusb_cbaf_attr_hdr Length_hdr; + __le16 Length; + struct wusb_cbaf_attr_hdr AssociationStatus_hdr; + __u32 AssociationStatus; +} __attribute__((packed)); + +#endif /* __LINUX_USB_ASSOCIATION_H */ diff --git a/drivers/staging/wusbcore/include/wusb-wa.h b/drivers/staging/wusbcore/include/wusb-wa.h new file mode 100644 index 000000000000..64a840b5106e --- /dev/null +++ b/drivers/staging/wusbcore/include/wusb-wa.h @@ -0,0 +1,304 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Wireless USB Wire Adapter constants and structures. + * + * Copyright (C) 2005-2006 Intel Corporation. + * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * + * FIXME: docs + * FIXME: organize properly, group logically + * + * All the event structures are defined in uwb/spec.h, as they are + * common to the WHCI and WUSB radio control interfaces. + * + * References: + * [WUSB] Wireless Universal Serial Bus Specification, revision 1.0, ch8 + */ +#ifndef __LINUX_USB_WUSB_WA_H +#define __LINUX_USB_WUSB_WA_H + +/** + * Radio Command Request for the Radio Control Interface + * + * Radio Control Interface command and event codes are the same as + * WHCI, and listed in include/linux/uwb.h:UWB_RC_{CMD,EVT}_* + */ +enum { + WA_EXEC_RC_CMD = 40, /* Radio Control command Request */ +}; + +/* Wireless Adapter Requests ([WUSB] table 8-51) */ +enum { + WUSB_REQ_ADD_MMC_IE = 20, + WUSB_REQ_REMOVE_MMC_IE = 21, + WUSB_REQ_SET_NUM_DNTS = 22, + WUSB_REQ_SET_CLUSTER_ID = 23, + WUSB_REQ_SET_DEV_INFO = 24, + WUSB_REQ_GET_TIME = 25, + WUSB_REQ_SET_STREAM_IDX = 26, + WUSB_REQ_SET_WUSB_MAS = 27, + WUSB_REQ_CHAN_STOP = 28, +}; + + +/* Wireless Adapter WUSB Channel Time types ([WUSB] table 8-52) */ +enum { + WUSB_TIME_ADJ = 0, + WUSB_TIME_BPST = 1, + WUSB_TIME_WUSB = 2, +}; + +enum { + WA_ENABLE = 0x01, + WA_RESET = 0x02, + RPIPE_PAUSE = 0x1, + RPIPE_STALL = 0x2, +}; + +/* Responses from Get Status request ([WUSB] section 8.3.1.6) */ +enum { + WA_STATUS_ENABLED = 0x01, + WA_STATUS_RESETTING = 0x02 +}; + +enum rpipe_crs { + RPIPE_CRS_CTL = 0x01, + RPIPE_CRS_ISO = 0x02, + RPIPE_CRS_BULK = 0x04, + RPIPE_CRS_INTR = 0x08 +}; + +/** + * RPipe descriptor ([WUSB] section 8.5.2.11) + * + * FIXME: explain rpipes + */ +struct usb_rpipe_descriptor { + u8 bLength; + u8 bDescriptorType; + __le16 wRPipeIndex; + __le16 wRequests; + __le16 wBlocks; /* rw if 0 */ + __le16 wMaxPacketSize; /* rw */ + union { + u8 dwa_bHSHubAddress; /* rw: DWA. */ + u8 hwa_bMaxBurst; /* rw: HWA. */ + }; + union { + u8 dwa_bHSHubPort; /* rw: DWA. */ + u8 hwa_bDeviceInfoIndex; /* rw: HWA. */ + }; + u8 bSpeed; /* rw: xfer rate 'enum uwb_phy_rate' */ + union { + u8 dwa_bDeviceAddress; /* rw: DWA Target device address. */ + u8 hwa_reserved; /* rw: HWA. */ + }; + u8 bEndpointAddress; /* rw: Target EP address */ + u8 bDataSequence; /* ro: Current Data sequence */ + __le32 dwCurrentWindow; /* ro */ + u8 bMaxDataSequence; /* ro?: max supported seq */ + u8 bInterval; /* rw: */ + u8 bOverTheAirInterval; /* rw: */ + u8 bmAttribute; /* ro? */ + u8 bmCharacteristics; /* ro? enum rpipe_attr, supported xsactions */ + u8 bmRetryOptions; /* rw? */ + __le16 wNumTransactionErrors; /* rw */ +} __attribute__ ((packed)); + +/** + * Wire Adapter Notification types ([WUSB] sections 8.4.5 & 8.5.4) + * + * These are the notifications coming on the notification endpoint of + * an HWA and a DWA. + */ +enum wa_notif_type { + DWA_NOTIF_RWAKE = 0x91, + DWA_NOTIF_PORTSTATUS = 0x92, + WA_NOTIF_TRANSFER = 0x93, + HWA_NOTIF_BPST_ADJ = 0x94, + HWA_NOTIF_DN = 0x95, +}; + +/** + * Wire Adapter notification header + * + * Notifications coming from a wire adapter use a common header + * defined in [WUSB] sections 8.4.5 & 8.5.4. + */ +struct wa_notif_hdr { + u8 bLength; + u8 bNotifyType; /* enum wa_notif_type */ +} __packed; + +/** + * HWA DN Received notification [(WUSB] section 8.5.4.2) + * + * The DNData is specified in WUSB1.0[7.6]. For each device + * notification we received, we just need to dispatch it. + * + * @dndata: this is really an array of notifications, but all start + * with the same header. + */ +struct hwa_notif_dn { + struct wa_notif_hdr hdr; + u8 bSourceDeviceAddr; /* from errata 2005/07 */ + u8 bmAttributes; + struct wusb_dn_hdr dndata[]; +} __packed; + +/* [WUSB] section 8.3.3 */ +enum wa_xfer_type { + WA_XFER_TYPE_CTL = 0x80, + WA_XFER_TYPE_BI = 0x81, /* bulk/interrupt */ + WA_XFER_TYPE_ISO = 0x82, + WA_XFER_RESULT = 0x83, + WA_XFER_ABORT = 0x84, + WA_XFER_ISO_PACKET_INFO = 0xA0, + WA_XFER_ISO_PACKET_STATUS = 0xA1, +}; + +/* [WUSB] section 8.3.3 */ +struct wa_xfer_hdr { + u8 bLength; /* 0x18 */ + u8 bRequestType; /* 0x80 WA_REQUEST_TYPE_CTL */ + __le16 wRPipe; /* RPipe index */ + __le32 dwTransferID; /* Host-assigned ID */ + __le32 dwTransferLength; /* Length of data to xfer */ + u8 bTransferSegment; +} __packed; + +struct wa_xfer_ctl { + struct wa_xfer_hdr hdr; + u8 bmAttribute; + __le16 wReserved; + struct usb_ctrlrequest baSetupData; +} __packed; + +struct wa_xfer_bi { + struct wa_xfer_hdr hdr; + u8 bReserved; + __le16 wReserved; +} __packed; + +/* [WUSB] section 8.5.5 */ +struct wa_xfer_hwaiso { + struct wa_xfer_hdr hdr; + u8 bReserved; + __le16 wPresentationTime; + __le32 dwNumOfPackets; +} __packed; + +struct wa_xfer_packet_info_hwaiso { + __le16 wLength; + u8 bPacketType; + u8 bReserved; + __le16 PacketLength[0]; +} __packed; + +struct wa_xfer_packet_status_len_hwaiso { + __le16 PacketLength; + __le16 PacketStatus; +} __packed; + +struct wa_xfer_packet_status_hwaiso { + __le16 wLength; + u8 bPacketType; + u8 bReserved; + struct wa_xfer_packet_status_len_hwaiso PacketStatus[0]; +} __packed; + +/* [WUSB] section 8.3.3.5 */ +struct wa_xfer_abort { + u8 bLength; + u8 bRequestType; + __le16 wRPipe; /* RPipe index */ + __le32 dwTransferID; /* Host-assigned ID */ +} __packed; + +/** + * WA Transfer Complete notification ([WUSB] section 8.3.3.3) + * + */ +struct wa_notif_xfer { + struct wa_notif_hdr hdr; + u8 bEndpoint; + u8 Reserved; +} __packed; + +/** Transfer result basic codes [WUSB] table 8-15 */ +enum { + WA_XFER_STATUS_SUCCESS, + WA_XFER_STATUS_HALTED, + WA_XFER_STATUS_DATA_BUFFER_ERROR, + WA_XFER_STATUS_BABBLE, + WA_XFER_RESERVED, + WA_XFER_STATUS_NOT_FOUND, + WA_XFER_STATUS_INSUFFICIENT_RESOURCE, + WA_XFER_STATUS_TRANSACTION_ERROR, + WA_XFER_STATUS_ABORTED, + WA_XFER_STATUS_RPIPE_NOT_READY, + WA_XFER_INVALID_FORMAT, + WA_XFER_UNEXPECTED_SEGMENT_NUMBER, + WA_XFER_STATUS_RPIPE_TYPE_MISMATCH, +}; + +/** [WUSB] section 8.3.3.4 */ +struct wa_xfer_result { + struct wa_notif_hdr hdr; + __le32 dwTransferID; + __le32 dwTransferLength; + u8 bTransferSegment; + u8 bTransferStatus; + __le32 dwNumOfPackets; +} __packed; + +/** + * Wire Adapter Class Descriptor ([WUSB] section 8.5.2.7). + * + * NOTE: u16 fields are read Little Endian from the hardware. + * + * @bNumPorts is the original max number of devices that the host can + * connect; we might chop this so the stack can handle + * it. In case you need to access it, use wusbhc->ports_max + * if it is a Wireless USB WA. + */ +struct usb_wa_descriptor { + u8 bLength; + u8 bDescriptorType; + __le16 bcdWAVersion; + u8 bNumPorts; /* don't use!! */ + u8 bmAttributes; /* Reserved == 0 */ + __le16 wNumRPipes; + __le16 wRPipeMaxBlock; + u8 bRPipeBlockSize; + u8 bPwrOn2PwrGood; + u8 bNumMMCIEs; + u8 DeviceRemovable; /* FIXME: in DWA this is up to 16 bytes */ +} __packed; + +/** + * HWA Device Information Buffer (WUSB1.0[T8.54]) + */ +struct hwa_dev_info { + u8 bmDeviceAvailability[32]; /* FIXME: ignored for now */ + u8 bDeviceAddress; + __le16 wPHYRates; + u8 bmDeviceAttribute; +} __packed; + +#endif /* #ifndef __LINUX_USB_WUSB_WA_H */ diff --git a/drivers/staging/wusbcore/include/wusb.h b/drivers/staging/wusbcore/include/wusb.h new file mode 100644 index 000000000000..09771d1da7bc --- /dev/null +++ b/drivers/staging/wusbcore/include/wusb.h @@ -0,0 +1,362 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Wireless USB Standard Definitions + * Event Size Tables + * + * Copyright (C) 2005-2006 Intel Corporation + * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * + * FIXME: docs + * FIXME: organize properly, group logically + * + * All the event structures are defined in uwb/spec.h, as they are + * common to the WHCI and WUSB radio control interfaces. + */ + +#ifndef __WUSB_H__ +#define __WUSB_H__ + +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/usb/ch9.h> +#include <linux/param.h> +#include "../../uwb/include/spec.h" + +/** + * WUSB Information Element header + * + * I don't know why, they decided to make it different to the MBOA MAC + * IE Header; beats me. + */ +struct wuie_hdr { + u8 bLength; + u8 bIEIdentifier; +} __attribute__((packed)); + +enum { + WUIE_ID_WCTA = 0x80, + WUIE_ID_CONNECTACK, + WUIE_ID_HOST_INFO, + WUIE_ID_CHANGE_ANNOUNCE, + WUIE_ID_DEVICE_DISCONNECT, + WUIE_ID_HOST_DISCONNECT, + WUIE_ID_KEEP_ALIVE = 0x89, + WUIE_ID_ISOCH_DISCARD, + WUIE_ID_RESET_DEVICE, +}; + +/** + * Maximum number of array elements in a WUSB IE. + * + * WUSB1.0[7.5 before table 7-38] says that in WUSB IEs that + * are "arrays" have to limited to 4 elements. So we define it + * like that to ease up and submit only the neeed size. + */ +#define WUIE_ELT_MAX 4 + +/** + * Wrapper for the data that defines a CHID, a CDID or a CK + * + * WUSB defines that CHIDs, CDIDs and CKs are a 16 byte string of + * data. In order to avoid confusion and enforce types, we wrap it. + * + * Make it packed, as we use it in some hw definitions. + */ +struct wusb_ckhdid { + u8 data[16]; +} __attribute__((packed)); + +static const struct wusb_ckhdid wusb_ckhdid_zero = { .data = { 0 } }; + +#define WUSB_CKHDID_STRSIZE (3 * sizeof(struct wusb_ckhdid) + 1) + +/** + * WUSB IE: Host Information (WUSB1.0[7.5.2]) + * + * Used to provide information about the host to the Wireless USB + * devices in range (CHID can be used as an ASCII string). + */ +struct wuie_host_info { + struct wuie_hdr hdr; + __le16 attributes; + struct wusb_ckhdid CHID; +} __attribute__((packed)); + +/** + * WUSB IE: Connect Ack (WUSB1.0[7.5.1]) + * + * Used to acknowledge device connect requests. See note for + * WUIE_ELT_MAX. + */ +struct wuie_connect_ack { + struct wuie_hdr hdr; + struct { + struct wusb_ckhdid CDID; + u8 bDeviceAddress; /* 0 means unused */ + u8 bReserved; + } blk[WUIE_ELT_MAX]; +} __attribute__((packed)); + +/** + * WUSB IE Host Information Element, Connect Availability + * + * WUSB1.0[7.5.2], bmAttributes description + */ +enum { + WUIE_HI_CAP_RECONNECT = 0, + WUIE_HI_CAP_LIMITED, + WUIE_HI_CAP_RESERVED, + WUIE_HI_CAP_ALL, +}; + +/** + * WUSB IE: Channel Stop (WUSB1.0[7.5.8]) + * + * Tells devices the host is going to stop sending MMCs and will disappear. + */ +struct wuie_channel_stop { + struct wuie_hdr hdr; + u8 attributes; + u8 timestamp[3]; +} __attribute__((packed)); + +/** + * WUSB IE: Keepalive (WUSB1.0[7.5.9]) + * + * Ask device(s) to send keepalives. + */ +struct wuie_keep_alive { + struct wuie_hdr hdr; + u8 bDeviceAddress[WUIE_ELT_MAX]; +} __attribute__((packed)); + +/** + * WUSB IE: Reset device (WUSB1.0[7.5.11]) + * + * Tell device to reset; in all truth, we can fit 4 CDIDs, but we only + * use it for one at the time... + * + * In any case, this request is a wee bit silly: why don't they target + * by address?? + */ +struct wuie_reset { + struct wuie_hdr hdr; + struct wusb_ckhdid CDID; +} __attribute__((packed)); + +/** + * WUSB IE: Disconnect device (WUSB1.0[7.5.11]) + * + * Tell device to disconnect; we can fit 4 addresses, but we only use + * it for one at the time... + */ +struct wuie_disconnect { + struct wuie_hdr hdr; + u8 bDeviceAddress; + u8 padding; +} __attribute__((packed)); + +/** + * WUSB IE: Host disconnect ([WUSB] section 7.5.5) + * + * Tells all connected devices to disconnect. + */ +struct wuie_host_disconnect { + struct wuie_hdr hdr; +} __attribute__((packed)); + +/** + * WUSB Device Notification header (WUSB1.0[7.6]) + */ +struct wusb_dn_hdr { + u8 bType; + u8 notifdata[]; +} __attribute__((packed)); + +/** Device Notification codes (WUSB1.0[Table 7-54]) */ +enum WUSB_DN { + WUSB_DN_CONNECT = 0x01, + WUSB_DN_DISCONNECT = 0x02, + WUSB_DN_EPRDY = 0x03, + WUSB_DN_MASAVAILCHANGED = 0x04, + WUSB_DN_RWAKE = 0x05, + WUSB_DN_SLEEP = 0x06, + WUSB_DN_ALIVE = 0x07, +}; + +/** WUSB Device Notification Connect */ +struct wusb_dn_connect { + struct wusb_dn_hdr hdr; + __le16 attributes; + struct wusb_ckhdid CDID; +} __attribute__((packed)); + +static inline int wusb_dn_connect_prev_dev_addr(const struct wusb_dn_connect *dn) +{ + return le16_to_cpu(dn->attributes) & 0xff; +} + +static inline int wusb_dn_connect_new_connection(const struct wusb_dn_connect *dn) +{ + return (le16_to_cpu(dn->attributes) >> 8) & 0x1; +} + +static inline int wusb_dn_connect_beacon_behavior(const struct wusb_dn_connect *dn) +{ + return (le16_to_cpu(dn->attributes) >> 9) & 0x03; +} + +/** Device is alive (aka: pong) (WUSB1.0[7.6.7]) */ +struct wusb_dn_alive { + struct wusb_dn_hdr hdr; +} __attribute__((packed)); + +/** Device is disconnecting (WUSB1.0[7.6.2]) */ +struct wusb_dn_disconnect { + struct wusb_dn_hdr hdr; +} __attribute__((packed)); + +/* General constants */ +enum { + WUSB_TRUST_TIMEOUT_MS = 4000, /* [WUSB] section 4.15.1 */ +}; + +/* + * WUSB Crypto stuff (WUSB1.0[6]) + */ + +extern const char *wusb_et_name(u8); + +/** + * WUSB key index WUSB1.0[7.3.2.4], for usage when setting keys for + * the host or the device. + */ +static inline u8 wusb_key_index(int index, int type, int originator) +{ + return (originator << 6) | (type << 4) | index; +} + +#define WUSB_KEY_INDEX_TYPE_PTK 0 /* for HWA only */ +#define WUSB_KEY_INDEX_TYPE_ASSOC 1 +#define WUSB_KEY_INDEX_TYPE_GTK 2 +#define WUSB_KEY_INDEX_ORIGINATOR_HOST 0 +#define WUSB_KEY_INDEX_ORIGINATOR_DEVICE 1 +/* bits 0-3 used for the key index. */ +#define WUSB_KEY_INDEX_MAX 15 + +/* A CCM Nonce, defined in WUSB1.0[6.4.1] */ +struct aes_ccm_nonce { + u8 sfn[6]; /* Little Endian */ + u8 tkid[3]; /* LE */ + struct uwb_dev_addr dest_addr; + struct uwb_dev_addr src_addr; +} __attribute__((packed)); + +/* A CCM operation label, defined on WUSB1.0[6.5.x] */ +struct aes_ccm_label { + u8 data[14]; +} __attribute__((packed)); + +/* + * Input to the key derivation sequence defined in + * WUSB1.0[6.5.1]. Rest of the data is in the CCM Nonce passed to the + * PRF function. + */ +struct wusb_keydvt_in { + u8 hnonce[16]; + u8 dnonce[16]; +} __attribute__((packed)); + +/* + * Output from the key derivation sequence defined in + * WUSB1.0[6.5.1]. + */ +struct wusb_keydvt_out { + u8 kck[16]; + u8 ptk[16]; +} __attribute__((packed)); + +/* Pseudo Random Function WUSB1.0[6.5] */ +extern int wusb_crypto_init(void); +extern void wusb_crypto_exit(void); +extern ssize_t wusb_prf(void *out, size_t out_size, + const u8 key[16], const struct aes_ccm_nonce *_n, + const struct aes_ccm_label *a, + const void *b, size_t blen, size_t len); + +static inline int wusb_prf_64(void *out, size_t out_size, const u8 key[16], + const struct aes_ccm_nonce *n, + const struct aes_ccm_label *a, + const void *b, size_t blen) +{ + return wusb_prf(out, out_size, key, n, a, b, blen, 64); +} + +static inline int wusb_prf_128(void *out, size_t out_size, const u8 key[16], + const struct aes_ccm_nonce *n, + const struct aes_ccm_label *a, + const void *b, size_t blen) +{ + return wusb_prf(out, out_size, key, n, a, b, blen, 128); +} + +static inline int wusb_prf_256(void *out, size_t out_size, const u8 key[16], + const struct aes_ccm_nonce *n, + const struct aes_ccm_label *a, + const void *b, size_t blen) +{ + return wusb_prf(out, out_size, key, n, a, b, blen, 256); +} + +/* Key derivation WUSB1.0[6.5.1] */ +static inline int wusb_key_derive(struct wusb_keydvt_out *keydvt_out, + const u8 key[16], + const struct aes_ccm_nonce *n, + const struct wusb_keydvt_in *keydvt_in) +{ + const struct aes_ccm_label a = { .data = "Pair-wise keys" }; + return wusb_prf_256(keydvt_out, sizeof(*keydvt_out), key, n, &a, + keydvt_in, sizeof(*keydvt_in)); +} + +/* + * Out-of-band MIC Generation WUSB1.0[6.5.2] + * + * Compute the MIC over @key, @n and @hs and place it in @mic_out. + * + * @mic_out: Where to place the 8 byte MIC tag + * @key: KCK from the derivation process + * @n: CCM nonce, n->sfn == 0, TKID as established in the + * process. + * @hs: Handshake struct for phase 2 of the 4-way. + * hs->bStatus and hs->bReserved are zero. + * hs->bMessageNumber is 2 (WUSB1.0[7.3.2.5.2] + * hs->dest_addr is the device's USB address padded with 0 + * hs->src_addr is the hosts's UWB device address + * hs->mic is ignored (as we compute that value). + */ +static inline int wusb_oob_mic(u8 mic_out[8], const u8 key[16], + const struct aes_ccm_nonce *n, + const struct usb_handshake *hs) +{ + const struct aes_ccm_label a = { .data = "out-of-bandMIC" }; + return wusb_prf_64(mic_out, 8, key, n, &a, + hs, sizeof(*hs) - sizeof(hs->MIC)); +} + +#endif /* #ifndef __WUSB_H__ */ diff --git a/drivers/usb/wusbcore/mmc.c b/drivers/staging/wusbcore/mmc.c index acce0d551eb2..881e1f20d718 100644 --- a/drivers/usb/wusbcore/mmc.c +++ b/drivers/staging/wusbcore/mmc.c @@ -22,9 +22,9 @@ * FIXME: * - add timers that autoremove intervalled IEs? */ -#include <linux/usb/wusb.h> #include <linux/slab.h> #include <linux/export.h> +#include "include/wusb.h" #include "wusbhc.h" /* Initialize the MMCIEs handling mechanism */ diff --git a/drivers/usb/wusbcore/pal.c b/drivers/staging/wusbcore/pal.c index 30f569131471..30f569131471 100644 --- a/drivers/usb/wusbcore/pal.c +++ b/drivers/staging/wusbcore/pal.c diff --git a/drivers/usb/wusbcore/reservation.c b/drivers/staging/wusbcore/reservation.c index 6dcfc6825f55..b921faac698b 100644 --- a/drivers/usb/wusbcore/reservation.c +++ b/drivers/staging/wusbcore/reservation.c @@ -5,8 +5,8 @@ * Copyright (C) 2007 Cambridge Silicon Radio Ltd. */ #include <linux/kernel.h> -#include <linux/uwb.h> +#include "../uwb/uwb.h" #include "wusbhc.h" /* diff --git a/drivers/usb/wusbcore/rh.c b/drivers/staging/wusbcore/rh.c index 20c08cd9dcbf..20c08cd9dcbf 100644 --- a/drivers/usb/wusbcore/rh.c +++ b/drivers/staging/wusbcore/rh.c diff --git a/drivers/usb/wusbcore/security.c b/drivers/staging/wusbcore/security.c index 14ac8c98ac9e..14ac8c98ac9e 100644 --- a/drivers/usb/wusbcore/security.c +++ b/drivers/staging/wusbcore/security.c diff --git a/drivers/usb/wusbcore/wa-hc.c b/drivers/staging/wusbcore/wa-hc.c index 6827075fb8a1..6827075fb8a1 100644 --- a/drivers/usb/wusbcore/wa-hc.c +++ b/drivers/staging/wusbcore/wa-hc.c diff --git a/drivers/usb/wusbcore/wa-hc.h b/drivers/staging/wusbcore/wa-hc.h index ec90fff21deb..5a38465724c2 100644 --- a/drivers/usb/wusbcore/wa-hc.h +++ b/drivers/staging/wusbcore/wa-hc.h @@ -70,9 +70,9 @@ #include <linux/usb.h> #include <linux/mutex.h> #include <linux/spinlock.h> -#include <linux/uwb.h> -#include <linux/usb/wusb.h> -#include <linux/usb/wusb-wa.h> +#include "../uwb/uwb.h" +#include "include/wusb.h" +#include "include/wusb-wa.h" struct wusbhc; struct wahc; diff --git a/drivers/usb/wusbcore/wa-nep.c b/drivers/staging/wusbcore/wa-nep.c index 5f0656db5482..5f0656db5482 100644 --- a/drivers/usb/wusbcore/wa-nep.c +++ b/drivers/staging/wusbcore/wa-nep.c diff --git a/drivers/usb/wusbcore/wa-rpipe.c b/drivers/staging/wusbcore/wa-rpipe.c index a5734cbcd5ad..a5734cbcd5ad 100644 --- a/drivers/usb/wusbcore/wa-rpipe.c +++ b/drivers/staging/wusbcore/wa-rpipe.c diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/staging/wusbcore/wa-xfer.c index abf88cea37bb..abf88cea37bb 100644 --- a/drivers/usb/wusbcore/wa-xfer.c +++ b/drivers/staging/wusbcore/wa-xfer.c diff --git a/drivers/usb/wusbcore/wusbhc.c b/drivers/staging/wusbcore/wusbhc.c index d0b404d258e8..d0b404d258e8 100644 --- a/drivers/usb/wusbcore/wusbhc.c +++ b/drivers/staging/wusbcore/wusbhc.c diff --git a/drivers/usb/wusbcore/wusbhc.h b/drivers/staging/wusbcore/wusbhc.h index 7681d796ca5b..716244a2ec44 100644 --- a/drivers/usb/wusbcore/wusbhc.h +++ b/drivers/staging/wusbcore/wusbhc.h @@ -45,8 +45,8 @@ #include <linux/kref.h> #include <linux/workqueue.h> #include <linux/usb/hcd.h> -#include <linux/uwb.h> -#include <linux/usb/wusb.h> +#include "../uwb/uwb.h" +#include "include/wusb.h" /* * Time from a WUSB channel stop request to the last transmitted MMC. diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 6e59d370ef81..9987c399819f 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -98,8 +98,6 @@ source "drivers/usb/core/Kconfig" source "drivers/usb/mon/Kconfig" -source "drivers/usb/wusbcore/Kconfig" - source "drivers/usb/host/Kconfig" source "drivers/usb/renesas_usbhs/Kconfig" diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index ecc2de1ffaae..db064dd59e08 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -35,8 +35,6 @@ obj-$(CONFIG_USB_MAX3421_HCD) += host/ obj-$(CONFIG_USB_C67X00_HCD) += c67x00/ -obj-$(CONFIG_USB_WUSB) += wusbcore/ - obj-$(CONFIG_USB_ACM) += class/ obj-$(CONFIG_USB_PRINTER) += class/ obj-$(CONFIG_USB_WDM) += class/ diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 40b5de597112..d040408f5baa 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -717,32 +717,6 @@ config USB_RENESAS_USBHS_HCD To compile this driver as a module, choose M here: the module will be called renesas-usbhs. -config USB_WHCI_HCD - tristate "Wireless USB Host Controller Interface (WHCI) driver" - depends on USB_PCI && USB && UWB - select USB_WUSB - select UWB_WHCI - help - A driver for PCI-based Wireless USB Host Controllers that are - compliant with the WHCI specification. - - To compile this driver a module, choose M here: the module - will be called "whci-hcd". - -config USB_HWA_HCD - tristate "Host Wire Adapter (HWA) driver" - depends on USB && UWB - select USB_WUSB - select UWB_HWA - help - This driver enables you to connect Wireless USB devices to - your system using a Host Wire Adaptor USB dongle. This is an - UWB Radio Controller and WUSB Host Controller connected to - your machine via USB (specified in WUSB1.0). - - To compile this driver a module, choose M here: the module - will be called "hwa-hc". - config USB_IMX21_HCD tristate "i.MX21 HCD support" depends on ARM && ARCH_MXC diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 84514f71ae44..59b39e6b350b 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -35,8 +35,6 @@ ifneq ($(CONFIG_DEBUG_FS),) xhci-hcd-y += xhci-debugfs.o endif -obj-$(CONFIG_USB_WHCI_HCD) += whci/ - obj-$(CONFIG_USB_PCI) += pci-quirks.o obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o @@ -82,7 +80,6 @@ obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o -obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o obj-$(CONFIG_USB_FSL_USB2) += fsl-mph-dr-of.o obj-$(CONFIG_USB_EHCI_FSL) += fsl-mph-dr-of.o |