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 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_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 astruct usbwifi_intr
and set itsuwi_index
entry to the index of the interrupt endpoint in theuw_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 tousbwifi_ic_attach
(the second stage of the usbwifi attachment).Overwrite the default implementations for
uw_ic
callbacks that got setup by the framework inusbwifi_ic_attach
where needed. At leastic_getradiocaps
needs 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_rx
andusbwifi_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 callusbwifi_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 passedstruct usbwifi_chain *c
as the main work item andlen
as 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_ext
has theIEEE80211_FEXT_BPF
bit set) and passes each packet found in the chain to the framework via a call tousbwifi_enqueue
.uwo_tx_prepare
is called for each packet transmitted. Likeuwo_rx_loop
it gets astruct usbwifi_chain *c
as main work item, which includes (slightly unobvious) the mbuf to encode asuwc_mbuf
, the target of the transmission asuwc_ni
and 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_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.)