Date: Fri, 21 Nov 2025 07:11:05 +0000 From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 4d29178e7154 - main - iwx: tag RX frames as A_MPDU RX; tag A-MSDU frames appropriately Message-ID: <69201089.282fe.733d52dc@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by adrian: URL: https://cgit.FreeBSD.org/src/commit/?id=4d29178e715449c25b94f115946dc4e021f41cdb commit 4d29178e715449c25b94f115946dc4e021f41cdb Author: Adrian Chadd <adrian@FreeBSD.org> AuthorDate: 2025-11-16 04:26:22 +0000 Commit: Adrian Chadd <adrian@FreeBSD.org> CommitDate: 2025-11-21 07:09:47 +0000 iwx: tag RX frames as A_MPDU RX; tag A-MSDU frames appropriately * tag packets for 11n/11ac associated nodes with A_MPDU so they get passed into the reordering logic * tag A-MSDU frames with AMSDU and AMSDU_MORE so they don't get dropped due to duplicate sequence numbers. Note: I haven't yet elicited A-MSDU in A-MPDU to fully test this, but I do see the net80211 reordering logic kick in (which you can see via wlanstats -i wlan0 -o ampdu 1). I've checked with Johannes Berg at Intel (who maintains the linux iwlwifi stuff); he replied saying none of the firmware versions are doing AMPDU reorder offloading. Differential Revision: https://reviews.freebsd.org/D53781 Locally tested: * AX210, STA mode, > 200mbit bidirectional traffic testing on 5GHz VHT/40. --- sys/dev/iwx/if_iwx.c | 62 +++++++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/sys/dev/iwx/if_iwx.c b/sys/dev/iwx/if_iwx.c index e317ff9e271c..3c953e522973 100644 --- a/sys/dev/iwx/if_iwx.c +++ b/sys/dev/iwx/if_iwx.c @@ -4607,37 +4607,39 @@ iwx_rx_mpdu_mq(struct iwx_softc *sc, struct mbuf *m, void *pktdata, pad = 1; } -// /* -// * Hardware de-aggregates A-MSDUs and copies the same MAC header -// * in place for each subframe. But it leaves the 'A-MSDU present' -// * bit set in the frame header. We need to clear this bit ourselves. -// * (XXX This workaround is not required on AX200/AX201 devices that -// * have been tested by me, but it's unclear when this problem was -// * fixed in the hardware. It definitely affects the 9k generation. -// * Leaving this in place for now since some 9k/AX200 hybrids seem -// * to exist that we may eventually add support for.) -// * -// * And we must allow the same CCMP PN for subframes following the -// * first subframe. Otherwise they would be discarded as replays. -// */ + /* If it's a HT node then perform re-order processing */ + if (ni->ni_flags & IEEE80211_NODE_HT) + m->m_flags |= M_AMPDU; + + /* + * Hardware de-aggregates A-MSDUs and copies the same MAC header + * in place for each subframe. But it leaves the 'A-MSDU present' + * bit set in the frame header. We need to clear this bit ourselves. + * (XXX This workaround is not required on AX200/AX201 devices that + * have been tested by me, but it's unclear when this problem was + * fixed in the hardware. It definitely affects the 9k generation. + * Leaving this in place for now since some 9k/AX200 hybrids seem + * to exist that we may eventually add support for.) + * + * And we must allow the same CCMP PN for subframes following the + * first subframe. Otherwise they would be discarded as replays. + */ if (desc->mac_flags2 & IWX_RX_MPDU_MFLG2_AMSDU) { - DPRINTF(("%s: === IWX_RX_MPDU_MFLG2_AMSDU\n", __func__)); -// struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *); -// uint8_t subframe_idx = (desc->amsdu_info & -// IWX_RX_MPDU_AMSDU_SUBFRAME_IDX_MASK); -// if (subframe_idx > 0) -// rxi.rxi_flags |= IEEE80211_RXI_HWDEC_SAME_PN; -// if (ieee80211_has_qos(wh) && ieee80211_has_addr4(wh) && -// m->m_len >= sizeof(struct ieee80211_qosframe_addr4)) { -// struct ieee80211_qosframe_addr4 *qwh4 = mtod(m, -// struct ieee80211_qosframe_addr4 *); -// qwh4->i_qos[0] &= htole16(~IEEE80211_QOS_AMSDU); -// } else if (ieee80211_has_qos(wh) && -// m->m_len >= sizeof(struct ieee80211_qosframe)) { -// struct ieee80211_qosframe *qwh = mtod(m, -// struct ieee80211_qosframe *); -// qwh->i_qos[0] &= htole16(~IEEE80211_QOS_AMSDU); -// } + struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *); + uint8_t subframe_idx = (desc->amsdu_info & + IWX_RX_MPDU_AMSDU_SUBFRAME_IDX_MASK); + uint8_t *qos; + + rxs.c_pktflags |= IEEE80211_RX_F_AMSDU; + if (subframe_idx > 0) + rxs.c_pktflags |= IEEE80211_RX_F_AMSDU_MORE; + + /* XXX should keep driver statistics about this */ + IWX_DPRINTF(sc, IWX_DEBUG_AMPDU_MGMT, + "%s: === IWX_RX_MPDU_MFLG2_AMSDU\n", __func__); + + qos = ieee80211_getqos(wh); + qos[0] &= ~IEEE80211_QOS_AMSDU; } /*help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69201089.282fe.733d52dc>
