Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 19 Nov 2024 04:52:54 GMT
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 842a2c1ad396 - main - uath: flush data/commands to the firmware before changing channel / state
Message-ID:  <202411190452.4AJ4qsAe066472@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by adrian:

URL: https://cgit.FreeBSD.org/src/commit/?id=842a2c1ad39637e91547bf725e8b4ce8773c5935

commit 842a2c1ad39637e91547bf725e8b4ce8773c5935
Author:     Adrian Chadd <adrian@FreeBSD.org>
AuthorDate: 2024-11-18 05:12:10 +0000
Commit:     Adrian Chadd <adrian@FreeBSD.org>
CommitDate: 2024-11-19 04:50:41 +0000

    uath: flush data/commands to the firmware before changing channel / state
    
    The driver wasn't stable - it would start fine, but during scan
    it would eventually hang and no further command endpoint transfers
    would complete.
    
    After adding some debugging and looking at the logs I noticed that
    things went sideways once a /data/ frame was sent.  The channel
    change config happened between the data frame being sent and
    being completed.
    
    My guess is that the firmware doesn't like a channel change
    and reset whilst there's pending data frames.  Checking the Linux
    driver I found that it was doing a flush before a channel change,
    and we're doing it afterwards.  This acts like a fence around
    ensuring scheduled TX work has completed.  In net80211 the
    transmit path and the control path aren't serialised, so it's
    very often the case that ioctls, state changes, etc occur
    whilst in parallel there are frame transmits being scheduled.
    
    This seems to happen more frequently on a more recent, high core
    (8) machine with XHCI.  I remember testing this driver years ago
    on single and dual core CPU laptops with no problems.
    
    So, add some flushes - before a channel change, and during
    a transition to AUTH when the BSS config is being programmed into
    the firmware.  These two fences seem enough to reliably
    associate as a 2GHz and 5GHz STA.
    
    Note that this isn't entirely blocking all newly queued
    transmit work from occuring until after the NIC has finished
    configuration.  That will need some further investigation.
    
    Locally tested:
    
      * Wistron NuWeb AR5523 dual-band NIC, STA mode, 2/5GHz
    
    Differential Revision:  https://reviews.freebsd.org/D47655
---
 sys/dev/usb/wlan/if_uath.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/sys/dev/usb/wlan/if_uath.c b/sys/dev/usb/wlan/if_uath.c
index 580022f5a0c5..32e3c0325c6e 100644
--- a/sys/dev/usb/wlan/if_uath.c
+++ b/sys/dev/usb/wlan/if_uath.c
@@ -1831,6 +1831,8 @@ uath_set_channel(struct ieee80211com *ic)
 		UATH_UNLOCK(sc);
 		return;
 	}
+	/* flush data & control requests into the target  */
+	(void)uath_flush(sc);
 	(void)uath_switch_channel(sc, ic->ic_curchan);
 	UATH_UNLOCK(sc);
 }
@@ -2015,6 +2017,8 @@ uath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 		break;
 
 	case IEEE80211_S_AUTH:
+		/* flush data & control requests into the target  */
+		(void)uath_flush(sc);
 		/* XXX good place?  set RTS threshold  */
 		uath_config(sc, CFG_USER_RTS_THRESHOLD, vap->iv_rtsthreshold);
 		/* XXX bad place  */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202411190452.4AJ4qsAe066472>