Download raw body.
qwx wpa handshake race
On 2025 Nov 19 (Wed) at 12:00:20 +0100 (+0100), Stefan Sperling wrote:
:Improve chances of qwx receiving the initial WPA handshake message.
:
:Run some qwx firmware commands earlier during the association sequence.
:We need to wait for these commands to complete, and timing is much less
:critical before we have sent our association request. Once we have sent
:this request, the AP may try to send the first WPA handshake message
:immediately after sending the association response frame. And we could miss
:the first WPA message while still setting up firmware state for association.
:In the case I observed, losing this race would result in a loop of failed
:attempts to join the network.
:
:ok?
:
OK
:M sys/dev/ic/qwx.c | 32+ 12-
:
:1 file changed, 32 insertions(+), 12 deletions(-)
:
:commit - fac7d93c02bbab40f1f2e9b9118ae92fcaad733d
:commit + e22c289135c2e5adcf38aacb10e888e3d7ba7562
:blob - ad3588d5c0f88b8de4171f7617551bfc058e6a36
:blob + dac4cfd24dabbbce8ff50e7596797c687257cd77
:--- sys/dev/ic/qwx.c
:+++ sys/dev/ic/qwx.c
:@@ -178,6 +178,7 @@ int qwx_scan(struct qwx_softc *, int);
: void qwx_scan_abort(struct qwx_softc *);
: int qwx_auth(struct qwx_softc *);
: int qwx_deauth(struct qwx_softc *);
:+int qwx_assoc(struct qwx_softc *);
: int qwx_run(struct qwx_softc *);
: int qwx_run_stop(struct qwx_softc *);
:
:@@ -1148,6 +1149,7 @@ next_scan:
: break;
:
: case IEEE80211_S_ASSOC:
:+ err = qwx_assoc(sc);
: break;
:
: case IEEE80211_S_RUN:
:@@ -26057,15 +26059,6 @@ qwx_deauth(struct qwx_softc *sc)
: return ret;
: }
:
:-
:- ret = qwx_wmi_set_peer_param(sc, peer->addr, arvif->vdev_id,
:- pdev_id, WMI_PEER_AUTHORIZE, 0);
:- if (ret) {
:- printf("%s: unable to deauthorize BSS peer: %d\n",
:- sc->sc_dev.dv_xname, ret);
:- return ret;
:- }
:-
: qwx_clear_pn_replay_config(sc, peer);
: qwx_clear_hwkeys(sc, peer);
:
:@@ -26472,7 +26465,7 @@ qwx_setup_peer_smps(struct qwx_softc *sc, uint8_t pdev
: }
:
: int
:-qwx_run(struct qwx_softc *sc)
:+qwx_assoc(struct qwx_softc *sc)
: {
: struct ieee80211com *ic = &sc->sc_ic;
: struct ieee80211_node *ni = ic->ic_bss;
:@@ -26535,6 +26528,25 @@ qwx_run(struct qwx_softc *sc)
: IEEE80211_ADDR_COPY(arvif->bssid, ni->ni_bssid);
: sc->bss_peer_id = nq->peer_id;
:
:+ /*
:+ * Enable reception of data frames now, if not already enabled.
:+ * We may need to receive EAPOL data frames very soon after the
:+ * AP sends a response to our assoc request.
:+ */
:+ sc->ops.irq_enable(sc);
:+
:+ return 0;
:+}
:+
:+int
:+qwx_run(struct qwx_softc *sc)
:+{
:+ struct ieee80211com *ic = &sc->sc_ic;
:+ struct ieee80211_node *ni = ic->ic_bss;
:+ struct qwx_vif *arvif = TAILQ_FIRST(&sc->vif_list); /* XXX */
:+ uint8_t pdev_id = 0; /* TODO: derive pdev ID somehow? */
:+ int ret;
:+
: ret = qwx_wmi_vdev_up(sc, arvif->vdev_id, pdev_id, arvif->aid,
: arvif->bssid, NULL, 0, 0);
: if (ret) {
:@@ -26559,7 +26571,6 @@ qwx_run(struct qwx_softc *sc)
: return ret;
: }
:
:- sc->ops.irq_enable(sc);
: return 0;
: }
:
:@@ -26569,11 +26580,20 @@ qwx_run_stop(struct qwx_softc *sc)
: struct ieee80211com *ic = &sc->sc_ic;
: struct qwx_vif *arvif = TAILQ_FIRST(&sc->vif_list); /* XXX */
: uint8_t pdev_id = 0; /* TODO: derive pdev ID somehow? */
:- struct qwx_node *nq = (void *)ic->ic_bss;
:+ struct ieee80211_node *ni = ic->ic_bss;
:+ struct qwx_node *nq = (void *)ni;
: int ret;
:
: sc->ops.irq_disable(sc);
:
:+ ret = qwx_wmi_set_peer_param(sc, ni->ni_macaddr, arvif->vdev_id,
:+ pdev_id, WMI_PEER_AUTHORIZE, 0);
:+ if (ret) {
:+ printf("%s: unable to deauthorize BSS peer: %d\n",
:+ sc->sc_dev.dv_xname, ret);
:+ return ret;
:+ }
:+
: if (ic->ic_opmode == IEEE80211_M_STA) {
: ic->ic_bss->ni_txrate = 0;
: nq->flags = 0;
:
--
In Corning, Iowa, it's a misdemeanor for a man to ask his wife to ride
in any motor vehicle.
qwx wpa handshake race