Martin Husemann <martin@NetBSD.org>
empirical fine tuningon various architectures that are not easily available for testing
Soon after me starting the work, we moved it to a mercurial “topic” to avoid CVS merges and for testing our (new) mercurial infrastructure.
This helped shake out the infrastructure a lot, but did not speed up the wifi project.
All relevant userland changes were made, ifconfig(8) needed special treatment.
We got a few PCI and USB based drivers converted.
Details are documted on the wiki:
https://wiki.netbsd.org/wifi_driver_state_matrix/
We found several differences between FreeBSD and NetBSD that had not been clear up front. Besides others:
struct ifnet
is separate from
struct ethercom
in NetBSD,
but some code assumes cast-equivalence:
struct ifnet *ifp;
struct ethercom *ec = (struct ethercom *)ifp;
We gave the VAP a struct ethercom for now.
Many NetBSD USB drivers have received empirical fine tuning on various architectures that are not easily available for testing
With one of the now supported devices we could boot a system, configure VAPs and have wifi connectivity.
[~] martin@h-pulse > ifconfig -a
enet0: flags=0x8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
capabilities=0x3ff00<IP4CSUM_Rx,IP4CSUM_Tx,TCP4CSUM_Rx,TCP4CSUM_Tx>
capabilities=0x3ff00<UDP4CSUM_Rx,UDP4CSUM_Tx,TCP6CSUM_Rx,TCP6CSUM_Tx>
capabilities=0x3ff00<UDP6CSUM_Rx,UDP6CSUM_Tx>
enabled=0
ec_capabilities=0x1<VLAN_MTU>
ec_enabled=0
address: 00:00:41:a7:3a:f1
media: Ethernet autoselect (1000baseT full-duplex)
status: active
inet6 fe80::200:41ff:fea7:3af1%enet0/64 flags 0 scopeid 0x1
inet 192.168.149.48/22 broadcast 192.168.151.255 flags 0
lo0: flags=0x8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 33624
status: active
inet6 ::1/128 flags 0x20<NODAD>
inet6 fe80::1%lo0/64 flags 0 scopeid 0x2
inet 127.0.0.1/8 flags 0
[~] martin@h-pulse > sysctl net.wlan
net.wlan.debug = 0
net.wlan.debug_console = 0
net.wlan.devices = urtwn0
[~] martin@h-pulse > su
Password:
[~] root@h-pulse # ifconfig wlan0 create wlandev urtwn0
[~] root@h-pulse # ifconfig wlan0
wlan0: flags=0x8802<BROADCAST,SIMPLEX,MULTICAST> mtu 1500
ssid ""
powersave on (100ms sleep)
address: 3c:33:00:5e:70:96
media: IEEE802.11 autoselect (autoselect mode 11b)
status: no network
[~] root@h-pulse # ifconfig wlan0 up
[~] root@h-pulse #
We documented the changes required from an “old” driver
to the new stack on the wiki:
https://wiki.netbsd.org/Converting_drivers_to_the_new_wifi_stack/
For USB ethernet interfaces we have usbnet(4), which is a bit simmilar to FreeBSD's iflib(4), but speciallized for USB devices.
We created a special version for USB wifi interfaces, usbwifi(9). This eases conversion of pure USB wifi device drivers, but it is (currently) unclear if it helps for mulit-bus devices like ath(9).
When testing the system more intensively / in real world use, we quickly found we are not there yet.
The locking differences in link state change handling and multicast ioctl handling caused various diagnostic assertion failures or deadlocks.
This took some serious amount of time to fully analyze and debug.
We moved a lot of events to task context (via a workqueue(9)) and are still dealing with structuring the ioctl locking systematically.
The big “IC-lock” was hold over usb calls that could sleep, which lead to various deadlock scenarios.
The IC lock is recursive in FreeBSD, so they do not see the same deadlocks - but it is unclear to me if they are just lucky most of the time or how their drivers avoid other fallout in this scenario.
We added additional locks to our drivers to protect different parts of the softc and hardware access.
This is worth another review pass when everything is ready to be merged!
After being a quite stable/quiet upstream for years, the FreeBSD wifi team started doing major work/enhancements again.
Recently they started improving locking and requiring more work from individual drivers. We expect this to help a lot, as we had to modify/extend the big-hammer “IC-lock” single lock per hardware model for link status changes and simmilar events in NetBSD already.
A while ago they decided to avoid re-doing fast changing Linux drivers and instead try to use their code as directly as possible.
Having used simmilar techniques in our DRM/KMS import project, we decided to follow.
Phil synced our hg topic with a newer FreeBSD version and started working on the LinuxKPI layer, reusing parts of DRM/KMS.
He also imported the iwlwifi(4) driver which uses the LinuxKPI shim.
This is close to working now.
We have two places where locking decisions are maded based on the mutex_owned()
predicate, which is a nonstarter. This happens:
Both cases will be fully analyzed and solved ASAP, we expect the result will be a actually mostly working state for all devices with already converted drivers.
If the top point can not be achieved quickly (or we have other reasons to branch netbsd-12 early, like a major DRM/KMS update ready for primetime) we may delay the merge for post-12.