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 usbwifiis the first member.Remove all parts of softc that are now in
struct usbwifiand 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 astruct 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_edarray 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 astruct usbwifi_intrand set itsuwi_indexentry to the index of the interrupt endpoint in theuw_edarray. 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 tousbwifi_ic_attach(the second stage of the usbwifi attachment).Overwrite the default implementations for
uw_iccallbacks that got setup by the framework inusbwifi_ic_attachwhere needed. At leastic_getradiocapsneeds to be implemented individually. When done, finish autoconfig attachment by a call tousbwifi_attach_finalize.Remove all cargo cult locking found in most drivers. Replace by
usbwifi_lock_ic,usbwifi_lock_rxandusbwifi_lock_tx. Think twice if you are tempted to use more locks.Create the callbacks needed for
struct usbwifi_opsuwo_stopis optional. It is used to power down the radio.uwo_initbrings up the radio starts the RX path. It needs to callusbwifi_rx_tx_initto get the rx/tx queues initialized.uwo_rx_loopif the core part of the RX handling (everything else will be handled by the framework). It gets passedstruct usbwifi_chain *cas the main work item andlenas the amount of data in the chain. It decodes the chip specific data, optionally updates the RX radio tap header with current data (ifuw_ic.ic_flags_exthas theIEEE80211_FEXT_BPFbit set) and passes each packet found in the chain to the framework via a call tousbwifi_enqueue.uwo_tx_prepareis called for each packet transmitted. Likeuwo_rx_loopit gets astruct usbwifi_chain *cas main work item, which includes (slightly unobvious) the mbuf to encode asuwc_mbuf, the target of the transmission asuwc_niand additionally is passed the "raw" priority/QOS asqid(one of the WME_AC_* constants). The function encapsulates the data as needed and copies it (with any padding and checksums needed) toc->uwc_bufand 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.)
