Download raw body.
qwx background scan and roaming support
tested on x13s. OK
On 2025 Jul 24 (Thu) at 15:46:42 +0200 (+0200), Stefan Sperling wrote:
:Add background scan and roaming support to qwx.
:
:This patch sits on top of the previous diffs I sent today, which
:have been now committed.
:
:M sys/dev/ic/qwx.c | 107+ 4-
:M sys/dev/ic/qwxvar.h | 2+ 0-
:M sys/dev/pci/if_qwx_pci.c | 2+ 0-
:
:3 files changed, 111 insertions(+), 4 deletions(-)
:
:commit - 25fdf95e122e33891e7ad3898002cfe29d094cc1
:commit + 3c01a782bb3d337863a438d785bb8fdfb8751d1c
:blob - f9996b63e8d39f993fea116ca38ca8179b471f61
:blob + 83c3f17a6a14062c7b61e273e5eabb7a12fc3943
:--- sys/dev/ic/qwx.c
:+++ sys/dev/ic/qwx.c
:@@ -163,7 +163,7 @@ void qwx_vif_free_all(struct qwx_softc *);
: void qwx_dp_stop_shadow_timers(struct qwx_softc *);
: void qwx_ce_stop_shadow_timers(struct qwx_softc *);
:
:-int qwx_scan(struct qwx_softc *);
:+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 *);
:@@ -373,6 +373,7 @@ qwx_stop(struct ifnet *ifp)
: task_del(systq, &sc->init_task);
: qwx_del_task(sc, sc->sc_nswq, &sc->newstate_task);
: qwx_del_task(sc, systq, &sc->setkey_task);
:+ qwx_del_task(sc, systq, &sc->bgscan_task);
: refcnt_finalize(&sc->task_refs, "qwxstop");
:
: qwx_setkey_clear(sc);
:@@ -868,6 +869,76 @@ qwx_setkey_task(void *arg)
: }
:
: void
:+qwx_clear_hwkeys(struct qwx_softc *sc, struct ath11k_peer *peer)
:+{
:+ struct qwx_vif *arvif = TAILQ_FIRST(&sc->vif_list); /* XXX */
:+ uint8_t pdev_id = 0; /* TODO: derive pdev ID somehow? */
:+ struct wmi_vdev_install_key_arg arg = {
:+ .vdev_id = arvif->vdev_id,
:+ .key_len = 0,
:+ .key_data = NULL,
:+ .key_cipher = WMI_CIPHER_NONE,
:+ .key_flags = 0,
:+ };
:+ int k_id = 0, ret;
:+
:+ arg.macaddr = peer->addr;
:+
:+ for (k_id = 0; k_id <= WMI_MAX_KEY_INDEX; k_id++) {
:+ arg.key_idx = k_id;
:+
:+ sc->install_key_done = 0;
:+ ret = qwx_wmi_vdev_install_key(sc, &arg, pdev_id);
:+ if (ret) {
:+ printf("%s: delete key %d failed: error %d\n",
:+ sc->sc_dev.dv_xname, k_id, ret);
:+ continue;
:+ }
:+
:+ while (!sc->install_key_done) {
:+ ret = tsleep_nsec(&sc->install_key_done, 0,
:+ "qwxinstkey", SEC_TO_NSEC(1));
:+ if (ret) {
:+ printf("%s: delete key %d timeout\n",
:+ sc->sc_dev.dv_xname, k_id);
:+ }
:+ }
:+ }
:+}
:+
:+void
:+qwx_clear_pn_replay_config(struct qwx_softc *sc, struct ath11k_peer *peer)
:+{
:+ struct ath11k_hal_reo_cmd cmd = {0};
:+ struct dp_rx_tid *rx_tid;
:+ uint8_t tid;
:+ int ret = 0;
:+
:+ cmd.flag |= HAL_REO_CMD_FLG_NEED_STATUS;
:+ cmd.upd0 |= HAL_REO_CMD_UPD0_PN |
:+ HAL_REO_CMD_UPD0_PN_SIZE |
:+ HAL_REO_CMD_UPD0_PN_VALID |
:+ HAL_REO_CMD_UPD0_PN_CHECK |
:+ HAL_REO_CMD_UPD0_SVLD;
:+
:+ for (tid = 0; tid < IEEE80211_NUM_TID; tid++) {
:+ rx_tid = &peer->rx_tid[tid];
:+ if (!rx_tid->active)
:+ continue;
:+ cmd.addr_lo = rx_tid->paddr & 0xffffffff;
:+ cmd.addr_hi = (rx_tid->paddr >> 32);
:+ ret = qwx_dp_tx_send_reo_cmd(sc, rx_tid,
:+ HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, NULL);
:+ if (ret) {
:+ printf("%s: failed to configure rx tid %d queue "
:+ "for pn replay detection %d\n",
:+ sc->sc_dev.dv_xname, tid, ret);
:+ break;
:+ }
:+ }
:+}
:+
:+void
: qwx_setkey_clear(struct qwx_softc *sc)
: {
: struct ieee80211com *ic = &sc->sc_ic;
:@@ -910,6 +981,8 @@ qwx_newstate(struct ieee80211com *ic, enum ieee80211_s
: #endif
: qwx_del_task(sc, systq, &sc->setkey_task);
: qwx_setkey_clear(sc);
:+
:+ qwx_del_task(sc, systq, &sc->bgscan_task);
: #if 0
: qwx_del_task(sc, systq, &sc->bgscan_done_task);
: #endif
:@@ -991,7 +1064,7 @@ qwx_newstate_task(void *arg)
:
: case IEEE80211_S_SCAN:
: next_scan:
:- err = qwx_scan(sc);
:+ err = qwx_scan(sc, 0);
: if (err)
: break;
: if (ifp->if_flags & IFF_DEBUG)
:@@ -25242,7 +25315,7 @@ qwx_start_scan(struct qwx_softc *sc, struct scan_req_p
: #define ATH11K_MAC_SCAN_CMD_EVT_OVERHEAD 200 /* in msecs */
:
: int
:-qwx_scan(struct qwx_softc *sc)
:+qwx_scan(struct qwx_softc *sc, int bgscan)
: {
: struct ieee80211com *ic = &sc->sc_ic;
: struct qwx_vif *arvif = TAILQ_FIRST(&sc->vif_list);
:@@ -25406,7 +25479,7 @@ qwx_scan(struct qwx_softc *sc)
: #ifdef notyet
: spin_unlock_bh(&ar->data_lock);
: #endif
:- } else {
:+ } else if (!bgscan) {
: /*
: * The current mode might have been fixed during association.
: * Ensure all channels get scanned.
:@@ -25474,6 +25547,31 @@ qwx_scan_abort(struct qwx_softc *sc)
: #endif
: }
:
:+void
:+qwx_bgscan_task(void *arg)
:+{
:+ struct qwx_softc *sc = arg;
:+ struct ieee80211com *ic = &sc->sc_ic;
:+
:+ if (ic->ic_state == IEEE80211_S_RUN &&
:+ sc->scan.state == ATH11K_SCAN_IDLE &&
:+ !test_bit(ATH11K_FLAG_CRASH_FLUSH, sc->sc_flags))
:+ qwx_scan(sc, 1);
:+
:+ refcnt_rele_wake(&sc->task_refs);
:+}
:+
:+int
:+qwx_bgscan(struct ieee80211com *ic)
:+{
:+ struct ifnet *ifp = &ic->ic_if;
:+ struct qwx_softc *sc = ifp->if_softc;
:+
:+ qwx_add_task(sc, systq, &sc->bgscan_task);
:+
:+ return 0;
:+}
:+
: /*
: * Find a pdev which corresponds to a given channel.
: * This doesn't exactly match the semantics of the Linux driver
:@@ -25627,6 +25725,9 @@ qwx_deauth(struct qwx_softc *sc)
: return ret;
: }
:
:+ qwx_clear_pn_replay_config(sc, peer);
:+ qwx_clear_hwkeys(sc, peer);
:+
: ret = qwx_mac_station_remove(sc, arvif, pdev_id, peer);
: if (ret)
: return ret;
:@@ -25839,6 +25940,7 @@ qwx_run(struct qwx_softc *sc)
: return ret;
: }
:
:+ sc->ops.irq_enable(sc);
: return 0;
: }
:
:@@ -25896,6 +25998,7 @@ qwx_attach(struct qwx_softc *sc)
: task_set(&sc->init_task, qwx_init_task, sc);
: task_set(&sc->newstate_task, qwx_newstate_task, sc);
: task_set(&sc->setkey_task, qwx_setkey_task, sc);
:+ task_set(&sc->bgscan_task, qwx_bgscan_task, sc);
: timeout_set_proc(&sc->scan.timeout, qwx_scan_timeout, sc);
: #if NBPFILTER > 0
: qwx_radiotap_attach(sc);
:blob - 1c1bb17d9afd88820f08059e05be0a0f75a1435e
:blob + 54f93cf120d314f92ed89b11c2dd917c7b7f7f64
:--- sys/dev/ic/qwxvar.h
:+++ sys/dev/ic/qwxvar.h
:@@ -1841,6 +1841,7 @@ struct qwx_softc {
: } scan;
: u_int scan_channel;
: struct qwx_survey_info survey[IEEE80211_CHAN_MAX];
:+ struct task bgscan_task;
:
: int attached;
: struct {
:@@ -1986,6 +1987,7 @@ int qwx_media_change(struct ifnet *);
: void qwx_init_task(void *);
: int qwx_newstate(struct ieee80211com *, enum ieee80211_state, int);
: void qwx_newstate_task(void *);
:+int qwx_bgscan(struct ieee80211com *);
:
: struct qwx_node {
: struct ieee80211_node ni;
:blob - fa91ce71bb49994fb8f625b56c9cf1d5487c2524
:blob + 017b9c18bde30549eaa3cda9de590652da021227
:--- sys/dev/pci/if_qwx_pci.c
:+++ sys/dev/pci/if_qwx_pci.c
:@@ -1119,6 +1119,8 @@ unsupported_wcn6855_soc:
: ic->ic_updateedca = qwx_updateedca;
: ic->ic_updatedtim = qwx_updatedtim;
: #endif
:+ ic->ic_bgscan_start = qwx_bgscan;
:+
: /*
: * We cannot read the MAC address without loading the
: * firmware from disk. Postpone until mountroot is done.
:
--
Health nuts are going to feel stupid someday, lying in hospitals dying
of nothing.
-- Redd Foxx
qwx background scan and roaming support