Index | Thread | Search

From:
Peter Hessler <phessler@theapt.org>
Subject:
Re: use dedicated allocations for qwx peer data structure
To:
tech@openbsd.org
Date:
Thu, 24 Jul 2025 14:33:09 +0200

Download raw body.

Thread
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"