From: Peter Hessler Subject: Re: use dedicated allocations for qwx peer data structure To: tech@openbsd.org Date: Thu, 24 Jul 2025 14:33:09 +0200 OK you have some extra newlines in there, which cn be cleaned up after all of the patcheset goes in. -peter On 2025 Jul 24 (Thu) at 12:53:35 +0200 (+0200), Stefan Sperling wrote: :qwx currently stores ath11k_peer data in allocations of ieee80211_node. :This was an easy way to get this driver going. However, this approach :gets in the way of adding support for roaming to qwx. : :When roaming, we go through state transisions RUN->AUTH->ASSOC->RUN. :All state transitions already see the new AP's data in ic->ic_bss. : :Storing the peer data in the node (ic_bss) means have already lost :information about our previous AP during the RUN->AUTH transition. :But we need this information to tear down the connection to our :previous AP in firmware before we can configure the new connection. : :Storing peer information on a separate list makes it possible to send :the correct firmware commands for tearing things down. : :I have a working patch on top of this which implements roaming support. : :ok? : : :M sys/dev/ic/qwx.c | 160+ 55- :M sys/dev/ic/qwxvar.h | 39+ 38- : :2 files changed, 199 insertions(+), 93 deletions(-) : :commit - 4995bfa49b0aa3de3992e0d9a7faf4efb0942e4b :commit + ad210c4e352605626f2f729170a4039bccd2fa55 :blob - cf5a90c95a4be03f57030a23d6b9d3ef0e804a2c :blob + 92f731a791bad7cd6fea977c067802080cfd295a :--- sys/dev/ic/qwx.c :+++ sys/dev/ic/qwx.c :@@ -153,6 +153,7 @@ int qwx_dp_tx_send_reo_cmd(struct qwx_softc *, struct : void qwx_dp_rx_deliver_msdu(struct qwx_softc *, struct qwx_rx_msdu *); : void qwx_dp_service_mon_ring(void *); : void qwx_peer_frags_flush(struct qwx_softc *, struct ath11k_peer *); :+struct ath11k_peer *qwx_peer_find_by_id(struct qwx_softc *, uint16_t); : int qwx_wmi_vdev_install_key(struct qwx_softc *, : struct wmi_vdev_install_key_arg *, uint8_t); : int qwx_dp_peer_rx_pn_replay_config(struct qwx_softc *, struct qwx_vif *, :@@ -176,10 +177,48 @@ qwx_node_alloc(struct ieee80211com *ic) : : nq = malloc(sizeof(struct qwx_node), M_DEVBUF, M_NOWAIT | M_ZERO); : if (nq != NULL) :- nq->peer.peer_id = HAL_INVALID_PEERID; :+ nq->peer_id = HAL_INVALID_PEERID; : return (struct ieee80211_node *)nq; : } : :+void :+qwx_node_clear_peer_id(struct qwx_softc *sc, struct ath11k_peer *peer) :+{ :+ struct ieee80211com *ic = &sc->sc_ic; :+ struct ieee80211_node *ni = ic->ic_bss; :+ struct qwx_node *nq = (struct qwx_node *)ni; :+ int s; :+ :+ s = splnet(); :+ :+ if (nq->peer_id == peer->peer_id) :+ nq->peer_id = HAL_INVALID_PEERID; :+ :+ RBT_FOREACH(ni, ieee80211_tree, &ic->ic_tree) { :+ nq = (struct qwx_node *)ni; :+ if (nq->peer_id == peer->peer_id) :+ nq->peer_id = HAL_INVALID_PEERID; :+ } :+ :+ splx(s); :+} :+ :+void :+qwx_free_peers(struct qwx_softc *sc) :+{ :+ struct ath11k_peer *peer; :+ :+ while (!TAILQ_EMPTY(&sc->peers)) { :+ peer = TAILQ_FIRST(&sc->peers); :+ TAILQ_REMOVE(&sc->peers, peer, entry); :+ qwx_node_clear_peer_id(sc, peer); :+ free(peer, M_DEVBUF, sizeof(*peer)); :+ sc->num_peers--; :+ if (TAILQ_EMPTY(&sc->peers) || sc->num_peers == 0) :+ KASSERT(TAILQ_EMPTY(&sc->peers) && sc->num_peers == 0); :+ } :+} :+ : int : qwx_init(struct ifnet *ifp) : { :@@ -361,6 +400,8 @@ qwx_stop(struct ifnet *ifp) : sc->sc_newstate(ic, IEEE80211_S_INIT, -1); : } : refcnt_finalize(&sc->task_refs, "qwxstop"); :+ qwx_free_peers(sc); :+ sc->bss_peer_id = HAL_INVALID_PEERID; : } : : sc->scan.state = ATH11K_SCAN_IDLE; :@@ -714,13 +755,20 @@ qwx_add_sta_key(struct qwx_softc *sc, struct ieee80211 : { : struct ieee80211com *ic = &sc->sc_ic; : struct qwx_node *nq = (struct qwx_node *)ni; :- struct ath11k_peer *peer = &nq->peer; :+ struct ath11k_peer *peer; : struct qwx_vif *arvif = TAILQ_FIRST(&sc->vif_list); /* XXX */ : int ret = 0; : uint32_t flags = 0; : const int want_keymask = (QWX_NODE_FLAG_HAVE_PAIRWISE_KEY | : QWX_NODE_FLAG_HAVE_GROUP_KEY); : :+ peer = qwx_peer_find_by_id(sc, nq->peer_id); :+ if (peer == NULL) { :+ printf("%s: peer %d not found\n", sc->sc_dev.dv_xname, :+ nq->peer_id); :+ return EINVAL; :+ } :+ : /* : * Flush the fragments cache during key (re)install to : * ensure all frags in the new frag list belong to the same key. :@@ -14502,20 +14550,22 @@ qwx_peer_map_event(struct qwx_softc *sc, uint8_t vdev_ : #ifdef notyet : spin_lock_bh(&ab->base_lock); : #endif :+ peer = qwx_peer_find_by_id(sc, HAL_INVALID_PEERID); :+ if (peer == NULL) :+ return; :+ : ni = ieee80211_find_node(ic, mac_addr); : if (ni == NULL) : return; : nq = (struct qwx_node *)ni; :- peer = &nq->peer; : : peer->vdev_id = vdev_id; : peer->peer_id = peer_id; : peer->ast_hash = ast_hash; : peer->hw_peer_id = hw_peer_id; :-#if 0 :- ether_addr_copy(peer->addr, mac_addr); :- list_add(&peer->list, &ab->peers); :-#endif :+ IEEE80211_ADDR_COPY(peer->addr, mac_addr); :+ nq->peer_id = peer_id; :+ : sc->peer_mapped = 1; : wakeup(&sc->peer_mapped); : :@@ -14526,40 +14576,35 @@ qwx_peer_map_event(struct qwx_softc *sc, uint8_t vdev_ : #endif : } : :-struct ieee80211_node * :+struct ath11k_peer * : qwx_peer_find_by_id(struct qwx_softc *sc, uint16_t peer_id) : { :- struct ieee80211com *ic = &sc->sc_ic; :- struct ieee80211_node *ni = NULL; :- int s; :+ struct ath11k_peer *peer; : :- s = splnet(); :- RBT_FOREACH(ni, ieee80211_tree, &ic->ic_tree) { :- struct qwx_node *nq = (struct qwx_node *)ni; :- if (nq->peer.peer_id == peer_id) :- break; :+ TAILQ_FOREACH(peer, &sc->peers, entry) { :+ if (peer->peer_id == peer_id) :+ return peer; : } :- splx(s); : :- return ni; :+ return NULL; : } : : void : qwx_peer_unmap_event(struct qwx_softc *sc, uint16_t peer_id) : { :- struct ieee80211_node *ni; :+ struct ath11k_peer *peer; : #ifdef notyet : spin_lock_bh(&ab->base_lock); : #endif :- ni = qwx_peer_find_by_id(sc, peer_id); :- if (!ni) { :+ peer = qwx_peer_find_by_id(sc, peer_id); :+ if (!peer) { : printf("%s: peer-unmap-event: unknown peer id %d\n", : sc->sc_dev.dv_xname, peer_id); : goto exit; : } : : DNPRINTF(QWX_D_HTT, "%s: peer unmap peer %s id %d\n", :- __func__, ether_sprintf(ni->ni_macaddr), peer_id); :+ __func__, ether_sprintf(peer->addr), peer_id); : #if 0 : list_del(&peer->list); : kfree(peer); :@@ -23659,17 +23704,18 @@ qwx_mac_get_rate_hw_value(struct ieee80211com *ic, : : int : qwx_peer_delete(struct qwx_softc *sc, uint32_t vdev_id, uint8_t pdev_id, :- uint8_t *addr) :+ struct ath11k_peer *peer) : { : int ret; : : sc->peer_mapped = 0; : sc->peer_delete_done = 0; : :- ret = qwx_wmi_send_peer_delete_cmd(sc, addr, vdev_id, pdev_id); :+ ret = qwx_wmi_send_peer_delete_cmd(sc, peer->addr, vdev_id, pdev_id); : if (ret) { : printf("%s: failed to delete peer vdev_id %d addr %s ret %d\n", :- sc->sc_dev.dv_xname, vdev_id, ether_sprintf(addr), ret); :+ sc->sc_dev.dv_xname, vdev_id, ether_sprintf(peer->addr), :+ ret); : return ret; : } : :@@ -23693,7 +23739,10 @@ qwx_peer_delete(struct qwx_softc *sc, uint32_t vdev_id : } : } : :+ TAILQ_REMOVE(&sc->peers, peer, entry); : sc->num_peers--; :+ qwx_node_clear_peer_id(sc, peer); :+ free(peer, M_DEVBUF, sizeof(*peer)); : return 0; : } : :@@ -23717,7 +23766,7 @@ qwx_peer_create(struct qwx_softc *sc, struct qwx_vif * : mutex_lock(&ar->ab->tbl_mtx_lock); : spin_lock_bh(&ar->ab->base_lock); : #endif :- peer = &nq->peer; :+ peer = qwx_peer_find_by_id(sc, nq->peer_id); : if (peer) { : if (peer->peer_id != HAL_INVALID_PEERID && : peer->vdev_id == param->vdev_id) { :@@ -23733,6 +23782,14 @@ qwx_peer_create(struct qwx_softc *sc, struct qwx_vif * : */ : ath11k_peer_rhash_delete(ar->ab, peer); : #endif :+ } else { :+ peer = malloc(sizeof(*peer), M_DEVBUF, M_ZERO | M_NOWAIT); :+ if (peer == NULL) :+ return ENOMEM; :+ :+ peer->peer_id = HAL_INVALID_PEERID; :+ TAILQ_INSERT_TAIL(&sc->peers, peer, entry); :+ sc->num_peers++; : } : #ifdef notyet : spin_unlock_bh(&ar->ab->base_lock); :@@ -23742,6 +23799,9 @@ qwx_peer_create(struct qwx_softc *sc, struct qwx_vif * : : ret = qwx_wmi_send_peer_create_cmd(sc, pdev_id, param); : if (ret) { :+ TAILQ_REMOVE(&sc->peers, peer, entry); :+ sc->num_peers--; :+ free(peer, M_DEVBUF, sizeof(*peer)); : printf("%s: failed to send peer create vdev_id %d ret %d\n", : sc->sc_dev.dv_xname, param->vdev_id, ret); : return ret; :@@ -23751,12 +23811,17 @@ qwx_peer_create(struct qwx_softc *sc, struct qwx_vif * : ret = tsleep_nsec(&sc->peer_mapped, 0, "qwxpeer", : SEC_TO_NSEC(3)); : if (ret) { :+ TAILQ_REMOVE(&sc->peers, peer, entry); :+ sc->num_peers--; :+ free(peer, M_DEVBUF, sizeof(*peer)); : printf("%s: peer create command timeout\n", : sc->sc_dev.dv_xname); : return ret; : } : } : :+ nq->peer_id = peer->peer_id; :+ : #ifdef notyet : mutex_lock(&ar->ab->tbl_mtx_lock); : spin_lock_bh(&ar->ab->base_lock); :@@ -23802,7 +23867,6 @@ qwx_peer_create(struct qwx_softc *sc, struct qwx_vif * : arsta->tcl_metadata &= ~HTT_TCL_META_DATA_VALID_HTT; : } : #endif :- sc->num_peers++; : #ifdef notyet : spin_unlock_bh(&ar->ab->base_lock); : mutex_unlock(&ar->ab->tbl_mtx_lock); :@@ -24245,22 +24309,25 @@ qwx_dp_rx_tid_mem_free(struct qwx_softc *sc, struct ie : int vdev_id, uint8_t tid) : { : struct qwx_node *nq = (struct qwx_node *)ni; :- struct ath11k_peer *peer = &nq->peer; :+ struct ath11k_peer *peer; : struct dp_rx_tid *rx_tid; : #ifdef notyet : spin_lock_bh(&ab->base_lock); : #endif :- rx_tid = &peer->rx_tid[tid]; :+ peer = qwx_peer_find_by_id(sc, nq->peer_id); :+ if (peer) { :+ rx_tid = &peer->rx_tid[tid]; : :- if (rx_tid->mem) { :- qwx_dmamem_free(sc->sc_dmat, rx_tid->mem); :- rx_tid->mem = NULL; :- rx_tid->vaddr = NULL; :- rx_tid->paddr = 0ULL; :- rx_tid->size = 0; :+ if (rx_tid->mem) { :+ qwx_dmamem_free(sc->sc_dmat, rx_tid->mem); :+ rx_tid->mem = NULL; :+ rx_tid->vaddr = NULL; :+ rx_tid->paddr = 0ULL; :+ rx_tid->size = 0; :+ } :+ :+ rx_tid->active = 0; : } :- :- rx_tid->active = 0; : #ifdef notyet : spin_unlock_bh(&ab->base_lock); : #endif :@@ -24272,7 +24339,7 @@ qwx_peer_rx_tid_setup(struct qwx_softc *sc, struct iee : enum hal_pn_type pn_type) : { : struct qwx_node *nq = (struct qwx_node *)ni; :- struct ath11k_peer *peer = &nq->peer; :+ struct ath11k_peer *peer; : struct dp_rx_tid *rx_tid; : uint32_t hw_desc_sz; : void *vaddr; :@@ -24281,6 +24348,14 @@ qwx_peer_rx_tid_setup(struct qwx_softc *sc, struct iee : #ifdef notyet : spin_lock_bh(&ab->base_lock); : #endif :+ peer = qwx_peer_find_by_id(sc, nq->peer_id); :+ if (peer == NULL) { :+#ifdef notyet :+ spin_unlock_bh(&ab->base_lock); :+#endif :+ return EINVAL; :+ } :+ : rx_tid = &peer->rx_tid[tid]; : /* Update the tid queue if it is already setup */ : if (rx_tid->active) { :@@ -24357,12 +24432,20 @@ qwx_peer_rx_frag_setup(struct qwx_softc *sc, struct ie : int vdev_id) : { : struct qwx_node *nq = (struct qwx_node *)ni; :- struct ath11k_peer *peer = &nq->peer; :+ struct ath11k_peer *peer; : struct dp_rx_tid *rx_tid; : int i; : #ifdef notyet : spin_lock_bh(&ab->base_lock); : #endif :+ peer = qwx_peer_find_by_id(sc, nq->peer_id); :+ if (peer == NULL) { :+#ifdef notyet :+ spin_unlock_bh(&ab->base_lock); :+#endif :+ return EINVAL; :+ } :+ : for (i = 0; i <= nitems(peer->rx_tid); i++) { : rx_tid = &peer->rx_tid[i]; : #if 0 :@@ -24384,10 +24467,14 @@ qwx_dp_peer_setup(struct qwx_softc *sc, int vdev_id, i : struct ieee80211_node *ni) : { : struct qwx_node *nq = (struct qwx_node *)ni; :- struct ath11k_peer *peer = &nq->peer; :+ struct ath11k_peer *peer; : uint32_t reo_dest; : int ret = 0, tid; : :+ peer = qwx_peer_find_by_id(sc, nq->peer_id); :+ if (peer == NULL) :+ return EINVAL; :+ : /* reo_dest ring id starts from 1 unlike mac_id which starts from 0 */ : reo_dest = sc->pdev_dp.mac_id + 1; : ret = qwx_wmi_set_peer_param(sc, ni->ni_macaddr, vdev_id, pdev_id, :@@ -24447,7 +24534,7 @@ qwx_dp_peer_rx_pn_replay_config(struct qwx_softc *sc, : { : struct ath11k_hal_reo_cmd cmd = {0}; : struct qwx_node *nq = (struct qwx_node *)ni; :- struct ath11k_peer *peer = &nq->peer; :+ struct ath11k_peer *peer; : struct dp_rx_tid *rx_tid; : uint8_t tid; : int ret = 0; :@@ -24486,6 +24573,10 @@ qwx_dp_peer_rx_pn_replay_config(struct qwx_softc *sc, : return EOPNOTSUPP; : } : :+ peer = qwx_peer_find_by_id(sc, nq->peer_id); :+ if (peer == NULL) :+ return EINVAL; :+ : for (tid = 0; tid < IEEE80211_NUM_TID; tid++) { : rx_tid = &peer->rx_tid[tid]; : if (!rx_tid->active) :@@ -24783,15 +24874,13 @@ qwx_dp_tx(struct qwx_softc *sc, struct qwx_vif *arvif, : : int : qwx_mac_station_remove(struct qwx_softc *sc, struct qwx_vif *arvif, :- uint8_t pdev_id, struct ieee80211_node *ni) :+ uint8_t pdev_id, struct ath11k_peer *peer) : { :- struct qwx_node *nq = (struct qwx_node *)ni; :- struct ath11k_peer *peer = &nq->peer; : int ret; : : qwx_peer_rx_tid_cleanup(sc, peer); : :- ret = qwx_peer_delete(sc, arvif->vdev_id, pdev_id, ni->ni_macaddr); :+ ret = qwx_peer_delete(sc, arvif->vdev_id, pdev_id, peer); : if (ret) { : printf("%s: unable to delete BSS peer: %d\n", : sc->sc_dev.dv_xname, ret); :@@ -24827,17 +24916,19 @@ qwx_mac_station_add(struct qwx_softc *sc, struct qwx_v : : ret = qwx_dp_peer_setup(sc, arvif->vdev_id, pdev_id, ni); : if (ret) { :+ struct qwx_node *nq = (struct qwx_node *)ni; :+ struct ath11k_peer *peer; :+ : printf("%s: failed to setup dp for peer %s on vdev %d (%d)\n", : sc->sc_dev.dv_xname, ether_sprintf(ni->ni_macaddr), : arvif->vdev_id, ret); :- goto free_peer; :+ peer = qwx_peer_find_by_id(sc, nq->peer_id); :+ if (peer) :+ qwx_peer_delete(sc, arvif->vdev_id, pdev_id, peer); :+ return ret; : } : : return 0; :- :-free_peer: :- qwx_peer_delete(sc, arvif->vdev_id, pdev_id, ni->ni_macaddr); :- return ret; : } : : int :@@ -25520,12 +25611,17 @@ qwx_auth(struct qwx_softc *sc) : int : qwx_deauth(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? */ :+ struct ath11k_peer *peer; : int ret; : :+ peer = qwx_peer_find_by_id(sc, sc->bss_peer_id); :+ if (peer == NULL) { :+ printf("%s: BSS peer not found\n", sc->sc_dev.dv_xname); :+ return EINVAL; :+ } :+ : ret = qwx_mac_vdev_stop(sc, arvif, pdev_id); : if (ret) { : printf("%s: unable to stop vdev vdev_id %d: %d\n", :@@ -25533,7 +25629,8 @@ qwx_deauth(struct qwx_softc *sc) : return ret; : } : :- ret = qwx_wmi_set_peer_param(sc, ni->ni_macaddr, arvif->vdev_id, :+ :+ 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", :@@ -25541,12 +25638,15 @@ qwx_deauth(struct qwx_softc *sc) : return ret; : } : :- ret = qwx_mac_station_remove(sc, arvif, pdev_id, ni); :+ ret = qwx_mac_station_remove(sc, arvif, pdev_id, peer); : if (ret) : return ret; : :+ qwx_free_peers(sc); :+ sc->bss_peer_id = HAL_INVALID_PEERID; :+ : DNPRINTF(QWX_D_MAC, "%s: disassociated from bssid %s aid %d\n", :- __func__, ether_sprintf(ni->ni_bssid), arvif->aid); :+ __func__, ether_sprintf(arvif->bssid), arvif->aid); : : return 0; : } :@@ -25668,6 +25768,7 @@ qwx_run(struct qwx_softc *sc) : { : struct ieee80211com *ic = &sc->sc_ic; : struct ieee80211_node *ni = ic->ic_bss; :+ struct qwx_node *nq = (struct qwx_node *)ni; : struct qwx_vif *arvif = TAILQ_FIRST(&sc->vif_list); /* XXX */ : uint8_t pdev_id = 0; /* TODO: derive pdev ID somehow? */ : struct peer_assoc_params peer_arg; :@@ -25723,6 +25824,7 @@ qwx_run(struct qwx_softc *sc) : : arvif->aid = ni->ni_associd; : IEEE80211_ADDR_COPY(arvif->bssid, ni->ni_bssid); :+ sc->bss_peer_id = nq->peer_id; : : ret = qwx_wmi_vdev_up(sc, arvif->vdev_id, pdev_id, arvif->aid, : arvif->bssid, NULL, 0, 0); :@@ -25813,6 +25915,7 @@ qwx_attach(struct qwx_softc *sc) : sc->pdevs[i].sc = sc; : : TAILQ_INIT(&sc->vif_list); :+ TAILQ_INIT(&sc->peers); : : error = qwx_init(ifp); : if (error) :@@ -25827,6 +25930,8 @@ qwx_attach(struct qwx_softc *sc) : void : qwx_detach(struct qwx_softc *sc) : { :+ qwx_free_peers(sc); :+ : if (sc->fwmem) { : qwx_dmamem_free(sc->sc_dmat, sc->fwmem); : sc->fwmem = NULL; :blob - 6d6bdab09f074bfcb30b25131b139aa8f5a918b1 :blob + 1c1bb17d9afd88820f08059e05be0a0f75a1435e :--- sys/dev/ic/qwxvar.h :+++ sys/dev/ic/qwxvar.h :@@ -1755,6 +1755,42 @@ struct qwx_setkey_task_arg { : #define QWX_DEL_KEY 2 : }; : :+struct ath11k_peer { :+ TAILQ_ENTRY(ath11k_peer) entry; :+#if 0 :+ struct ieee80211_sta *sta; :+#endif :+ int vdev_id; :+ uint8_t addr[IEEE80211_ADDR_LEN]; :+ int peer_id; :+ uint16_t ast_hash; :+ uint8_t pdev_id; :+ uint16_t hw_peer_id; :+#if 0 :+ /* protected by ab->data_lock */ :+ struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; :+#endif :+ struct dp_rx_tid rx_tid[IEEE80211_NUM_TID + 1]; :+#if 0 :+ /* peer id based rhashtable list pointer */ :+ struct rhash_head rhash_id; :+ /* peer addr based rhashtable list pointer */ :+ struct rhash_head rhash_addr; :+ :+ /* Info used in MMIC verification of :+ * RX fragments :+ */ :+ struct crypto_shash *tfm_mmic; :+ u8 mcast_keyidx; :+ u8 ucast_keyidx; :+ u16 sec_type; :+ u16 sec_type_grp; :+ bool is_authorized; :+ bool dp_setup_done; :+#endif :+}; :+TAILQ_HEAD(qwx_peer_list, ath11k_peer); :+ : struct qwx_softc { : struct device sc_dev; : struct ieee80211com sc_ic; :@@ -1850,11 +1886,13 @@ struct qwx_softc { : int num_started_vdevs; : uint32_t allocated_vdev_map; : uint32_t free_vdev_map; :+ struct qwx_peer_list peers; : int num_peers; : int peer_mapped; : int peer_delete_done; : int vdev_setup_done; : int peer_assoc_done; :+ int bss_peer_id; : : struct qwx_dbring_cap *db_caps; : uint32_t num_db_cap; :@@ -1949,46 +1987,9 @@ void qwx_init_task(void *); : int qwx_newstate(struct ieee80211com *, enum ieee80211_state, int); : void qwx_newstate_task(void *); : :-struct ath11k_peer { :-#if 0 :- struct list_head list; :- struct ieee80211_sta *sta; :-#endif :- int vdev_id; :-#if 0 :- u8 addr[ETH_ALEN]; :-#endif :- int peer_id; :- uint16_t ast_hash; :- uint8_t pdev_id; :- uint16_t hw_peer_id; :-#if 0 :- /* protected by ab->data_lock */ :- struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; :-#endif :- struct dp_rx_tid rx_tid[IEEE80211_NUM_TID + 1]; :-#if 0 :- /* peer id based rhashtable list pointer */ :- struct rhash_head rhash_id; :- /* peer addr based rhashtable list pointer */ :- struct rhash_head rhash_addr; :- :- /* Info used in MMIC verification of :- * RX fragments :- */ :- struct crypto_shash *tfm_mmic; :- u8 mcast_keyidx; :- u8 ucast_keyidx; :- u16 sec_type; :- u16 sec_type_grp; :- bool is_authorized; :- bool dp_setup_done; :-#endif :-}; :- : struct qwx_node { : struct ieee80211_node ni; :- struct ath11k_peer peer; :+ int peer_id; : unsigned int flags; : #define QWX_NODE_FLAG_HAVE_PAIRWISE_KEY 0x01 : #define QWX_NODE_FLAG_HAVE_GROUP_KEY 0x02 : -- The only real way to look younger is not to be born so soon. -- Charles Schulz, "Things I've Had to Learn Over and Over and Over"