Inaky Perez-Gonzalez | 99d368b | 2008-09-17 16:34:04 +0100 | [diff] [blame] | 1 | |
| 2 | Linux UWB + Wireless USB + WiNET |
| 3 | |
| 4 | (C) 2005-2006 Intel Corporation |
| 5 | Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> |
| 6 | |
| 7 | This program is free software; you can redistribute it and/or |
| 8 | modify it under the terms of the GNU General Public License version |
| 9 | 2 as published by the Free Software Foundation. |
| 10 | |
| 11 | This program is distributed in the hope that it will be useful, |
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | GNU General Public License for more details. |
| 15 | |
| 16 | You should have received a copy of the GNU General Public License |
| 17 | along with this program; if not, write to the Free Software |
| 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
| 19 | 02110-1301, USA. |
| 20 | |
| 21 | |
| 22 | Please visit http://bughost.org/thewiki/Design-overview.txt-1.8 for |
| 23 | updated content. |
| 24 | |
| 25 | * Design-overview.txt-1.8 |
| 26 | |
| 27 | This code implements a Ultra Wide Band stack for Linux, as well as |
| 28 | drivers for the the USB based UWB radio controllers defined in the |
| 29 | Wireless USB 1.0 specification (including Wireless USB host controller |
| 30 | and an Intel WiNET controller). |
| 31 | |
| 32 | 1. Introduction |
| 33 | 1. HWA: Host Wire adapters, your Wireless USB dongle |
| 34 | |
| 35 | 2. DWA: Device Wired Adaptor, a Wireless USB hub for wired |
| 36 | devices |
| 37 | 3. WHCI: Wireless Host Controller Interface, the PCI WUSB host |
| 38 | adapter |
| 39 | 2. The UWB stack |
| 40 | 1. Devices and hosts: the basic structure |
| 41 | |
| 42 | 2. Host Controller life cycle |
| 43 | |
| 44 | 3. On the air: beacons and enumerating the radio neighborhood |
| 45 | |
| 46 | 4. Device lists |
| 47 | 5. Bandwidth allocation |
| 48 | |
| 49 | 3. Wireless USB Host Controller drivers |
| 50 | |
| 51 | 4. Glossary |
| 52 | |
| 53 | |
| 54 | Introduction |
| 55 | |
| 56 | UWB is a wide-band communication protocol that is to serve also as the |
| 57 | low-level protocol for others (much like TCP sits on IP). Currently |
| 58 | these others are Wireless USB and TCP/IP, but seems Bluetooth and |
| 59 | Firewire/1394 are coming along. |
| 60 | |
| 61 | UWB uses a band from roughly 3 to 10 GHz, transmitting at a max of |
| 62 | ~-41dB (or 0.074 uW/MHz--geography specific data is still being |
| 63 | negotiated w/ regulators, so watch for changes). That band is divided in |
| 64 | a bunch of ~1.5 GHz wide channels (or band groups) composed of three |
| 65 | subbands/subchannels (528 MHz each). Each channel is independent of each |
| 66 | other, so you could consider them different "busses". Initially this |
| 67 | driver considers them all a single one. |
| 68 | |
| 69 | Radio time is divided in 65536 us long /superframes/, each one divided |
| 70 | in 256 256us long /MASs/ (Media Allocation Slots), which are the basic |
| 71 | time/media allocation units for transferring data. At the beginning of |
| 72 | each superframe there is a Beacon Period (BP), where every device |
| 73 | transmit its beacon on a single MAS. The length of the BP depends on how |
| 74 | many devices are present and the length of their beacons. |
| 75 | |
| 76 | Devices have a MAC (fixed, 48 bit address) and a device (changeable, 16 |
| 77 | bit address) and send periodic beacons to advertise themselves and pass |
| 78 | info on what they are and do. They advertise their capabilities and a |
| 79 | bunch of other stuff. |
| 80 | |
| 81 | The different logical parts of this driver are: |
| 82 | |
| 83 | * |
| 84 | |
| 85 | *UWB*: the Ultra-Wide-Band stack -- manages the radio and |
| 86 | associated spectrum to allow for devices sharing it. Allows to |
| 87 | control bandwidth assingment, beaconing, scanning, etc |
| 88 | |
| 89 | * |
| 90 | |
| 91 | *WUSB*: the layer that sits on top of UWB to provide Wireless USB. |
| 92 | The Wireless USB spec defines means to control a UWB radio and to |
| 93 | do the actual WUSB. |
| 94 | |
| 95 | |
| 96 | HWA: Host Wire adapters, your Wireless USB dongle |
| 97 | |
| 98 | WUSB also defines a device called a Host Wire Adaptor (HWA), which in |
| 99 | mere terms is a USB dongle that enables your PC to have UWB and Wireless |
| 100 | USB. The Wireless USB Host Controller in a HWA looks to the host like a |
| 101 | [Wireless] USB controller connected via USB (!) |
| 102 | |
| 103 | The HWA itself is broken in two or three main interfaces: |
| 104 | |
| 105 | * |
| 106 | |
| 107 | *RC*: Radio control -- this implements an interface to the |
| 108 | Ultra-Wide-Band radio controller. The driver for this implements a |
| 109 | USB-based UWB Radio Controller to the UWB stack. |
| 110 | |
| 111 | * |
| 112 | |
| 113 | *HC*: the wireless USB host controller. It looks like a USB host |
| 114 | whose root port is the radio and the WUSB devices connect to it. |
| 115 | To the system it looks like a separate USB host. The driver (will) |
| 116 | implement a USB host controller (similar to UHCI, OHCI or EHCI) |
| 117 | for which the root hub is the radio...To reiterate: it is a USB |
| 118 | controller that is connected via USB instead of PCI. |
| 119 | |
| 120 | * |
| 121 | |
| 122 | *WINET*: some HW provide a WiNET interface (IP over UWB). This |
| 123 | package provides a driver for it (it looks like a network |
| 124 | interface, winetX). The driver detects when there is a link up for |
| 125 | their type and kick into gear. |
| 126 | |
| 127 | |
| 128 | DWA: Device Wired Adaptor, a Wireless USB hub for wired devices |
| 129 | |
| 130 | These are the complement to HWAs. They are a USB host for connecting |
| 131 | wired devices, but it is connected to your PC connected via Wireless |
| 132 | USB. To the system it looks like yet another USB host. To the untrained |
| 133 | eye, it looks like a hub that connects upstream wirelessly. |
| 134 | |
| 135 | We still offer no support for this; however, it should share a lot of |
| 136 | code with the HWA-RC driver; there is a bunch of factorization work that |
| 137 | has been done to support that in upcoming releases. |
| 138 | |
| 139 | |
| 140 | WHCI: Wireless Host Controller Interface, the PCI WUSB host adapter |
| 141 | |
| 142 | This is your usual PCI device that implements WHCI. Similar in concept |
| 143 | to EHCI, it allows your wireless USB devices (including DWAs) to connect |
| 144 | to your host via a PCI interface. As in the case of the HWA, it has a |
| 145 | Radio Control interface and the WUSB Host Controller interface per se. |
| 146 | |
| 147 | There is still no driver support for this, but will be in upcoming |
| 148 | releases. |
| 149 | |
| 150 | |
| 151 | The UWB stack |
| 152 | |
| 153 | The main mission of the UWB stack is to keep a tally of which devices |
| 154 | are in radio proximity to allow drivers to connect to them. As well, it |
| 155 | provides an API for controlling the local radio controllers (RCs from |
| 156 | now on), such as to start/stop beaconing, scan, allocate bandwidth, etc. |
| 157 | |
| 158 | |
| 159 | Devices and hosts: the basic structure |
| 160 | |
| 161 | The main building block here is the UWB device (struct uwb_dev). For |
| 162 | each device that pops up in radio presence (ie: the UWB host receives a |
| 163 | beacon from it) you get a struct uwb_dev that will show up in |
| 164 | /sys/class/uwb and in /sys/bus/uwb/devices. |
| 165 | |
| 166 | For each RC that is detected, a new struct uwb_rc is created. In turn, a |
| 167 | RC is also a device, so they also show in /sys/class/uwb and |
| 168 | /sys/bus/uwb/devices, but at the same time, only radio controllers show |
| 169 | up in /sys/class/uwb_rc. |
| 170 | |
| 171 | * |
| 172 | |
| 173 | [*] The reason for RCs being also devices is that not only we can |
| 174 | see them while enumerating the system device tree, but also on the |
| 175 | radio (their beacons and stuff), so the handling has to be |
| 176 | likewise to that of a device. |
| 177 | |
| 178 | Each RC driver is implemented by a separate driver that plugs into the |
| 179 | interface that the UWB stack provides through a struct uwb_rc_ops. The |
| 180 | spec creators have been nice enough to make the message format the same |
| 181 | for HWA and WHCI RCs, so the driver is really a very thin transport that |
| 182 | moves the requests from the UWB API to the device [/uwb_rc_ops->cmd()/] |
| 183 | and sends the replies and notifications back to the API |
| 184 | [/uwb_rc_neh_grok()/]. Notifications are handled to the UWB daemon, that |
| 185 | is chartered, among other things, to keep the tab of how the UWB radio |
| 186 | neighborhood looks, creating and destroying devices as they show up or |
| 187 | dissapear. |
| 188 | |
| 189 | Command execution is very simple: a command block is sent and a event |
| 190 | block or reply is expected back. For sending/receiving command/events, a |
| 191 | handle called /neh/ (Notification/Event Handle) is opened with |
| 192 | /uwb_rc_neh_open()/. |
| 193 | |
| 194 | The HWA-RC (USB dongle) driver (drivers/uwb/hwa-rc.c) does this job for |
| 195 | the USB connected HWA. Eventually, drivers/whci-rc.c will do the same |
| 196 | for the PCI connected WHCI controller. |
| 197 | |
| 198 | |
| 199 | Host Controller life cycle |
| 200 | |
| 201 | So let's say we connect a dongle to the system: it is detected and |
| 202 | firmware uploaded if needed [for Intel's i1480 |
| 203 | /drivers/uwb/ptc/usb.c:ptc_usb_probe()/] and then it is reenumerated. |
| 204 | Now we have a real HWA device connected and |
| 205 | /drivers/uwb/hwa-rc.c:hwarc_probe()/ picks it up, that will set up the |
| 206 | Wire-Adaptor environment and then suck it into the UWB stack's vision of |
| 207 | the world [/drivers/uwb/lc-rc.c:uwb_rc_add()/]. |
| 208 | |
| 209 | * |
| 210 | |
| 211 | [*] The stack should put a new RC to scan for devices |
| 212 | [/uwb_rc_scan()/] so it finds what's available around and tries to |
| 213 | connect to them, but this is policy stuff and should be driven |
| 214 | from user space. As of now, the operator is expected to do it |
| 215 | manually; see the release notes for documentation on the procedure. |
| 216 | |
| 217 | When a dongle is disconnected, /drivers/uwb/hwa-rc.c:hwarc_disconnect()/ |
| 218 | takes time of tearing everything down safely (or not...). |
| 219 | |
| 220 | |
| 221 | On the air: beacons and enumerating the radio neighborhood |
| 222 | |
| 223 | So assuming we have devices and we have agreed for a channel to connect |
| 224 | on (let's say 9), we put the new RC to beacon: |
| 225 | |
| 226 | * |
| 227 | |
| 228 | $ echo 9 0 > /sys/class/uwb_rc/uwb0/beacon |
| 229 | |
| 230 | Now it is visible. If there were other devices in the same radio channel |
| 231 | and beacon group (that's what the zero is for), the dongle's radio |
| 232 | control interface will send beacon notifications on its |
| 233 | notification/event endpoint (NEEP). The beacon notifications are part of |
| 234 | the event stream that is funneled into the API with |
| 235 | /drivers/uwb/neh.c:uwb_rc_neh_grok()/ and delivered to the UWBD, the UWB |
| 236 | daemon through a notification list. |
| 237 | |
| 238 | UWBD wakes up and scans the event list; finds a beacon and adds it to |
| 239 | the BEACON CACHE (/uwb_beca/). If he receives a number of beacons from |
| 240 | the same device, he considers it to be 'onair' and creates a new device |
| 241 | [/drivers/uwb/lc-dev.c:uwbd_dev_onair()/]. Similarly, when no beacons |
| 242 | are received in some time, the device is considered gone and wiped out |
| 243 | [uwbd calls periodically /uwb/beacon.c:uwb_beca_purge()/ that will purge |
| 244 | the beacon cache of dead devices]. |
| 245 | |
| 246 | |
| 247 | Device lists |
| 248 | |
| 249 | All UWB devices are kept in the list of the struct bus_type uwb_bus. |
| 250 | |
| 251 | |
| 252 | Bandwidth allocation |
| 253 | |
| 254 | The UWB stack maintains a local copy of DRP availability through |
| 255 | processing of incoming *DRP Availability Change* notifications. This |
| 256 | local copy is currently used to present the current bandwidth |
| 257 | availability to the user through the sysfs file |
| 258 | /sys/class/uwb_rc/uwbx/bw_avail. In the future the bandwidth |
| 259 | availability information will be used by the bandwidth reservation |
| 260 | routines. |
| 261 | |
| 262 | The bandwidth reservation routines are in progress and are thus not |
| 263 | present in the current release. When completed they will enable a user |
| 264 | to initiate DRP reservation requests through interaction with sysfs. DRP |
| 265 | reservation requests from remote UWB devices will also be handled. The |
| 266 | bandwidth management done by the UWB stack will include callbacks to the |
| 267 | higher layers will enable the higher layers to use the reservations upon |
| 268 | completion. [Note: The bandwidth reservation work is in progress and |
| 269 | subject to change.] |
| 270 | |
| 271 | |
| 272 | Wireless USB Host Controller drivers |
| 273 | |
| 274 | *WARNING* This section needs a lot of work! |
| 275 | |
| 276 | As explained above, there are three different types of HCs in the WUSB |
| 277 | world: HWA-HC, DWA-HC and WHCI-HC. |
| 278 | |
| 279 | HWA-HC and DWA-HC share that they are Wire-Adapters (USB or WUSB |
| 280 | connected controllers), and their transfer management system is almost |
| 281 | identical. So is their notification delivery system. |
| 282 | |
| 283 | HWA-HC and WHCI-HC share that they are both WUSB host controllers, so |
| 284 | they have to deal with WUSB device life cycle and maintenance, wireless |
| 285 | root-hub |
| 286 | |
| 287 | HWA exposes a Host Controller interface (HWA-HC 0xe0/02/02). This has |
| 288 | three endpoints (Notifications, Data Transfer In and Data Transfer |
| 289 | Out--known as NEP, DTI and DTO in the code). |
| 290 | |
| 291 | We reserve UWB bandwidth for our Wireless USB Cluster, create a Cluster |
| 292 | ID and tell the HC to use all that. Then we start it. This means the HC |
| 293 | starts sending MMCs. |
| 294 | |
| 295 | * |
| 296 | |
| 297 | The MMCs are blocks of data defined somewhere in the WUSB1.0 spec |
| 298 | that define a stream in the UWB channel time allocated for sending |
| 299 | WUSB IEs (host to device commands/notifications) and Device |
| 300 | Notifications (device initiated to host). Each host defines a |
| 301 | unique Wireless USB cluster through MMCs. Devices can connect to a |
| 302 | single cluster at the time. The IEs are Information Elements, and |
| 303 | among them are the bandwidth allocations that tell each device |
| 304 | when can they transmit or receive. |
| 305 | |
| 306 | Now it all depends on external stimuli. |
| 307 | |
| 308 | *New device connection* |
| 309 | |
| 310 | A new device pops up, it scans the radio looking for MMCs that give out |
| 311 | the existence of Wireless USB channels. Once one (or more) are found, |
| 312 | selects which one to connect to. Sends a /DN_Connect/ (device |
| 313 | notification connect) during the DNTS (Device Notification Time |
| 314 | Slot--announced in the MMCs |
| 315 | |
| 316 | HC picks the /DN_Connect/ out (nep module sends to notif.c for delivery |
| 317 | into /devconnect/). This process starts the authentication process for |
| 318 | the device. First we allocate a /fake port/ and assign an |
| 319 | unauthenticated address (128 to 255--what we really do is |
| 320 | 0x80 | fake_port_idx). We fiddle with the fake port status and /khubd/ |
| 321 | sees a new connection, so he moves on to enable the fake port with a reset. |
| 322 | |
| 323 | So now we are in the reset path -- we know we have a non-yet enumerated |
| 324 | device with an unauthorized address; we ask user space to authenticate |
| 325 | (FIXME: not yet done, similar to bluetooth pairing), then we do the key |
| 326 | exchange (FIXME: not yet done) and issue a /set address 0/ to bring the |
| 327 | device to the default state. Device is authenticated. |
| 328 | |
| 329 | From here, the USB stack takes control through the usb_hcd ops. khubd |
| 330 | has seen the port status changes, as we have been toggling them. It will |
| 331 | start enumerating and doing transfers through usb_hcd->urb_enqueue() to |
| 332 | read descriptors and move our data. |
| 333 | |
| 334 | *Device life cycle and keep alives* |
| 335 | |
| 336 | Everytime there is a succesful transfer to/from a device, we update a |
| 337 | per-device activity timestamp. If not, every now and then we check and |
| 338 | if the activity timestamp gets old, we ping the device by sending it a |
| 339 | Keep Alive IE; it responds with a /DN_Alive/ pong during the DNTS (this |
| 340 | arrives to us as a notification through |
| 341 | devconnect.c:wusb_handle_dn_alive(). If a device times out, we |
| 342 | disconnect it from the system (cleaning up internal information and |
| 343 | toggling the bits in the fake hub port, which kicks khubd into removing |
| 344 | the rest of the stuff). |
| 345 | |
| 346 | This is done through devconnect:__wusb_check_devs(), which will scan the |
| 347 | device list looking for whom needs refreshing. |
| 348 | |
| 349 | If the device wants to disconnect, it will either die (ugly) or send a |
| 350 | /DN_Disconnect/ that will prompt a disconnection from the system. |
| 351 | |
| 352 | *Sending and receiving data* |
| 353 | |
| 354 | Data is sent and received through /Remote Pipes/ (rpipes). An rpipe is |
| 355 | /aimed/ at an endpoint in a WUSB device. This is the same for HWAs and |
| 356 | DWAs. |
| 357 | |
| 358 | Each HC has a number of rpipes and buffers that can be assigned to them; |
| 359 | when doing a data transfer (xfer), first the rpipe has to be aimed and |
| 360 | prepared (buffers assigned), then we can start queueing requests for |
| 361 | data in or out. |
| 362 | |
| 363 | Data buffers have to be segmented out before sending--so we send first a |
| 364 | header (segment request) and then if there is any data, a data buffer |
| 365 | immediately after to the DTI interface (yep, even the request). If our |
| 366 | buffer is bigger than the max segment size, then we just do multiple |
| 367 | requests. |
| 368 | |
| 369 | [This sucks, because doing USB scatter gatter in Linux is resource |
| 370 | intensive, if any...not that the current approach is not. It just has to |
| 371 | be cleaned up a lot :)]. |
| 372 | |
| 373 | If reading, we don't send data buffers, just the segment headers saying |
| 374 | we want to read segments. |
| 375 | |
| 376 | When the xfer is executed, we receive a notification that says data is |
| 377 | ready in the DTI endpoint (handled through |
| 378 | xfer.c:wa_handle_notif_xfer()). In there we read from the DTI endpoint a |
| 379 | descriptor that gives us the status of the transfer, its identification |
| 380 | (given when we issued it) and the segment number. If it was a data read, |
| 381 | we issue another URB to read into the destination buffer the chunk of |
| 382 | data coming out of the remote endpoint. Done, wait for the next guy. The |
| 383 | callbacks for the URBs issued from here are the ones that will declare |
| 384 | the xfer complete at some point and call it's callback. |
| 385 | |
| 386 | Seems simple, but the implementation is not trivial. |
| 387 | |
| 388 | * |
| 389 | |
| 390 | *WARNING* Old!! |
| 391 | |
| 392 | The main xfer descriptor, wa_xfer (equivalent to a URB) contains an |
| 393 | array of segments, tallys on segments and buffers and callback |
| 394 | information. Buried in there is a lot of URBs for executing the segments |
| 395 | and buffer transfers. |
| 396 | |
| 397 | For OUT xfers, there is an array of segments, one URB for each, another |
| 398 | one of buffer URB. When submitting, we submit URBs for segment request |
| 399 | 1, buffer 1, segment 2, buffer 2...etc. Then we wait on the DTI for xfer |
| 400 | result data; when all the segments are complete, we call the callback to |
| 401 | finalize the transfer. |
| 402 | |
| 403 | For IN xfers, we only issue URBs for the segments we want to read and |
| 404 | then wait for the xfer result data. |
| 405 | |
| 406 | *URB mapping into xfers* |
| 407 | |
| 408 | This is done by hwahc_op_urb_[en|de]queue(). In enqueue() we aim an |
| 409 | rpipe to the endpoint where we have to transmit, create a transfer |
| 410 | context (wa_xfer) and submit it. When the xfer is done, our callback is |
| 411 | called and we assign the status bits and release the xfer resources. |
| 412 | |
| 413 | In dequeue() we are basically cancelling/aborting the transfer. We issue |
| 414 | a xfer abort request to the HC, cancell all the URBs we had submitted |
| 415 | and not yet done and when all that is done, the xfer callback will be |
| 416 | called--this will call the URB callback. |
| 417 | |
| 418 | |
| 419 | Glossary |
| 420 | |
| 421 | *DWA* -- Device Wire Adapter |
| 422 | |
| 423 | USB host, wired for downstream devices, upstream connects wirelessly |
| 424 | with Wireless USB. |
| 425 | |
| 426 | *EVENT* -- Response to a command on the NEEP |
| 427 | |
| 428 | *HWA* -- Host Wire Adapter / USB dongle for UWB and Wireless USB |
| 429 | |
| 430 | *NEH* -- Notification/Event Handle |
| 431 | |
| 432 | Handle/file descriptor for receiving notifications or events. The WA |
| 433 | code requires you to get one of this to listen for notifications or |
| 434 | events on the NEEP. |
| 435 | |
| 436 | *NEEP* -- Notification/Event EndPoint |
| 437 | |
| 438 | Stuff related to the management of the first endpoint of a HWA USB |
| 439 | dongle that is used to deliver an stream of events and notifications to |
| 440 | the host. |
| 441 | |
| 442 | *NOTIFICATION* -- Message coming in the NEEP as response to something. |
| 443 | |
| 444 | *RC* -- Radio Control |
| 445 | |
| 446 | Design-overview.txt-1.8 (last edited 2006-11-04 12:22:24 by |
| 447 | InakyPerezGonzalez) |
| 448 | |