123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439 |
- Linux UWB + Wireless USB + WiNET
- (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).
- 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)
|