Download raw body.
qwx background scan and roaming support
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.
qwx background scan and roaming support