Page MenuHomeFreeBSD

Porting athn from OpenBSD
Needs ReviewPublic

Authored by farhan_farhan.codes on Fri, Apr 18, 3:39 AM.
Referenced Files
Unknown Object (File)
Thu, May 8, 4:20 PM
Unknown Object (File)
Thu, May 1, 8:26 PM
Unknown Object (File)
Tue, Apr 29, 10:01 AM
Unknown Object (File)
Sat, Apr 26, 12:58 AM
Unknown Object (File)
Fri, Apr 25, 2:58 AM
Unknown Object (File)
Fri, Apr 25, 1:59 AM
Unknown Object (File)
Wed, Apr 23, 10:34 AM
Unknown Object (File)
Wed, Apr 23, 8:57 AM
Subscribers

Details

Reviewers
adrian
Summary

Hi all,

I recently restarted my port of athn from OpenBSD. I began this effort in February 2022, forgot about it due to personal commitments, then restarted. I am working off USB device 0cf3:9271. I did not include OpenBSD's if_athn_pci.c, which I would not be able to test on. I kept the basic structure from OpenBSD, such as if_usb_attachhook, will flatten later.

Current state:

  • Attaches USB bus
  • Loads and processes firmware (ugh, that was tough)
  • Read/Write to registers work
  • athn_usb_attach -> athn_attach seem to work, though I may have made mistakes in porting.
  • Slowly uncommenting athn_parent -> athn_usb_init -> athn_init code, seems to work without a problem.

Current problems:

  • When I unload/unattach the driver, it causes the system to fully lock up only after athn_attach runs -- very frustrating, as it slows down development.
  • When I run ifconfig wlan0 up, it causes ifconfig to never end and Control-C does not terminate the process -- lower priority because I'm still working through the init code.
  • It's possible I messed up somewhere in the porting in athn_usb_attach and athn_attach.

My git repo is here: https://github.com/khanzf/freebsd-src/tree/ar9271-revived

Test Plan

Compile and load 3 modules in this order

make -C /usr/src/sys/modules/athnfw/ar9271fw load
make -C /usr/src/sys/modules/athn_usb unload
make -C /usr/src/sys/modules/athn unload

You should see debugging messages and the ieee80211_announce message.
Turn the device on with ifconfig wlan0 up but it will lock up the terminal.

Currently, unloading the module *will* cause your system to lock up. I do not know why yet.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

I think the current idea is avoiding directly import firmware file into repo. Perhaps we can separate the firmware out. The current approach is using firmware ports/pkg, before having that, we can just put it somewhere and ask people to grab it and put to the required place, for testing.

sys/contrib/dev/athn/LICENSE
1 โ†—(On Diff #153823)

Just be curious, is this a Realtek or Atheros product?

sys/contrib/dev/athn/LICENSE
1 โ†—(On Diff #153823)

Atheros device.

I think the current idea is avoiding directly import firmware file into repo. Perhaps we can separate the firmware out. The current approach is using firmware ports/pkg, before having that, we can just put it somewhere and ask people to grab it and put to the required place, for testing.

Or point them at the linux wireless firmware archive repo....

In D49884#1137462, @imp wrote:

I think the current idea is avoiding directly import firmware file into repo. Perhaps we can separate the firmware out. The current approach is using firmware ports/pkg, before having that, we can just put it somewhere and ask people to grab it and put to the required place, for testing.

Or point them at the linux wireless firmware archive repo....

Acknowledged. Might take me a bit of time.

farhan_farhan.codes marked an inline comment as done.

Working to update the athn_usb_init, currently working through the newstate handler.

Current Problem: Running into a recursive mutex based on FreeBSD/OpenBSD mutex styles.

Explanation:

Two things are necessary to understand the issue

HTC process

The Athn driver sends Host Target Communication (HTC) commands that must be sequential. The order is:
Thread A: Step 1) Lock the driver
Thread 1. Step 2) Send an HTC command via USB Tx interrupt and msleep() for a response
Thread 2, Step 1) Receive response via USB Rx interrupt and run wakeup()
Thread 1 , Step 3) Unlock the driver

Note that step 2.1 is Asynchronous of 1.1, 1.2 and 1.3. I cannot READ from a register until a desired result via the response is via USB Rx Interrupt.

Locking Differs between FreeBSD and OpenBSD

FreeBSD places a DRIVER_LOCK (ATHN_LOCK) at the start of the newstate handler. This prevents a state change collision. I copied this as follows:

It takes the form of:

athn_usb_newstate(....)
{
...
IEEE80211_UNLOCK(sc);
ATHN_LOCK(sc);
...

OpenBSD (seems to) only place a lock at critical points within the child function.

Combined

  • The first lock happens in the newstate call.
  • The second lock happens when a child process of newstate runs an HTC command, which itself runs a lock.

This creates a recursive lock

Proposed solution

What I will test out is having a separate HTC mutex that is independent of the rest of the device. So, the HTC will not run ATHN_LOCK/UNLOCK, but rather ATHN_HTC_LOCK/UNLOCK.

Thoughts/