Before starting a driver conversion, you should have read the general instructions at [[Converting drivers to the new wifi stack]]. Many items there are marked as "not for usbwifi" though, so instead of a big list with lots of things to skip here is a todo list when converting a usb wifi driver from the old stack to usbwifi and the new stack. Note that the usbwifi(9) manual is only available in the hg branch sources! Similar to usbnet(9) the usb wifi driver to usbwifi(9) conversion is mostly an excercise in cleanup and deleting. Here is what is needed to be done: * Rearrange the softc so `struct usbwifi` is the first member. * Remove all parts of softc that are now in `struct usbwifi` and fixup references to them. This typically includes the common IEEE 802.11 ic strucuture, usb device and interface pointer. * Initialize the members of `struct usbwifi`, setup a `struct usbwifi_ops` (see below) and simplify the device attach function, detach function and driver declaration as described in the AUTOCONFIGURATION section in the usbwifi(9) manual page. Besides the pointer forward and backward referencing (`uw_sc`, `uw_dev`, `uw_udev`) make sure to setup buffer sizes and counts as well as usb transfer flags (`uw_*_xfer_flags`, `uw_*_bufsz`, `uw_*_list_cnt`). * The most tricky part of the step above is getting the endpoint handling correct. Fill the `uw_ed` array with the endpoint numbers properly sorted: all TX endpoints first (many wifi chips offer multiple TX endpoints), sorted by priority (highest quality of service first). Let the RX endpoints follow this. If there is an interrupt endpoint, it goes last and you need to setup a `struct usbwifi_intr` and set its `uwi_index` entry to the index of the interrupt endpoint in the `uw_ed` array. Next you need to assign TX indices to the uw_ac2id array. If your chipset only has a single TX queue, all indices in this array will be 0, if there are multiple QOS you can make some use queues/endpoints with lower priority. All WME QOS levels need to have a valid index (which happens by default, everything will use the first queue with highest priority). Pass the number of TX and RX queues to `usbwifi_ic_attach` (the second stage of the usbwifi attachment). * Overwrite the default implementations for `uw_ic` callbacks that got setup by the framework in `usbwifi_ic_attach` where needed. At least `ic_getradiocaps` needs to be implemented individually. When done, finish autoconfig attachment by a call to `usbwifi_attach_finalize`. * Remove all cargo cult locking found in most drivers. Replace by `usbwifi_lock_ic`, `usbwifi_lock_rx` and `usbwifi_lock_tx`. Think twice if you are tempted to use more locks. * Create the callbacks needed for `struct usbwifi_ops` * `uwo_stop` is optional. It is used to power down the radio. * `uwo_init` brings up the radio starts the RX path. It needs to call `usbwifi_rx_tx_init` to get the rx/tx queues initialized. * `uwo_rx_loop` if the core part of the RX handling (everything else will be handled by the framework). It gets passed `struct usbwifi_chain *c` as the main work item and `len` as the amount of data in the chain. It decodes the chip specific data, optionally updates the RX radio tap header with current data (if `uw_ic.ic_flags_ext` has the `IEEE80211_FEXT_BPF` bit set) and passes each packet found in the chain to the framework via a call to `usbwifi_enqueue`. * `uwo_tx_prepare` is called for each packet transmitted. Like `uwo_rx_loop` it gets a `struct usbwifi_chain *c` as main work item, which includes (slightly unobvious) the mbuf to encode as `uwc_mbuf`, the target of the transmission as `uwc_ni` and additionally is passed the "raw" priority/QOS as `qid` (one of the WME_AC_* constants). The function encapsulates the data as needed and copies it (with any padding and checksums needed) to `c->uwc_buf` and returns the number of bytes copied into the chain. Look at one of the converted usb drivers on the branch (see [[Driver state matrix]] for a list of usbwifi(9) drivers and their state.)