Date: Wed, 7 May 2025 04:22:38 GMT 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: 20d808f42860 - main - net80211: document the vap / device transmit paths, fragment node references Message-ID: <202505070422.5474McFk054858@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by adrian: URL: https://cgit.FreeBSD.org/src/commit/?id=20d808f428601c5122f8b394068dda04e5174bac commit 20d808f428601c5122f8b394068dda04e5174bac Author: Adrian Chadd <adrian@FreeBSD.org> AuthorDate: 2025-01-27 05:45:37 +0000 Commit: Adrian Chadd <adrian@FreeBSD.org> CommitDate: 2025-05-07 04:21:17 +0000 net80211: document the vap / device transmit paths, fragment node references * Document what the VAP and device transmit paths do. Take care to note down the 802.11 fragment handling and node references. * Almost none of the drivers (save ath(4), which I fixed a long time ago) implement 802.11 fragments after the big VAP rework done years and years ago. A few others announce support (mwl, ral, uath, wpi) but I haven't validated them. I'll be doing that as part of this work. * Add some comments in ieee80211_fragment() around how fragment node references work. Differential Revision: https://reviews.freebsd.org/D49765 --- sys/net80211/ieee80211_freebsd.c | 48 ++++++++++++++++++++++++++++++++++++++-- sys/net80211/ieee80211_output.c | 31 ++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c index d3c8352ab411..6979e601ce41 100644 --- a/sys/net80211/ieee80211_freebsd.c +++ b/sys/net80211/ieee80211_freebsd.c @@ -706,7 +706,37 @@ ieee80211_get_toa_params(struct mbuf *m, struct ieee80211_toa_params *p) } /* - * Transmit a frame to the parent interface. + * @brief Transmit a frame to the parent interface. + * + * Transmit an 802.11 or 802.3 frame to the parent interface. + * + * This is called as part of 802.11 processing to enqueue a frame + * from net80211 into the device for transmit. + * + * If the interface is marked as 802.3 via IEEE80211_C_8023ENCAP + * (ie, doing offload), then an 802.3 frame will be sent and the + * driver will need to understand what to do. + * + * If the interface is marked as 802.11 (ie, no offload), then + * an encapsulated 802.11 frame will be queued. In the case + * of an 802.11 fragmented frame this will be a list of frames + * representing the fragments making up the 802.11 frame, linked + * via m_nextpkt. + * + * A fragmented frame list will consist of: + * + only the first frame with M_SEQNO_SET() assigned the sequence number; + * + only the first frame with the node reference and node in rcvif; + * + all frames will have the sequence + fragment number populated in + * the 802.11 header. + * + * The driver must ensure it doesn't try releasing a node reference + * for each fragment in the list. + * + * The provided mbuf/list is consumed both upon success and error. + * + * @param ic struct ieee80211com device to enqueue frame to + * @param m struct mbuf chain / packet list to enqueue + * @returns 0 if successful, errno if error. */ int ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m) @@ -726,6 +756,8 @@ ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m) /* XXX number of fragments */ if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); + + /* Note: there's only one node reference for a fragment list */ ieee80211_free_node(ni); ieee80211_free_mbuf(m); } @@ -733,7 +765,19 @@ ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m) } /* - * Transmit a frame to the VAP interface. + * @brief Transmit an 802.3 frame to the VAP interface. + * + * This is the entry point for the wifi stack to enqueue 802.3 + * encapsulated frames for transmit to the given vap/ifnet instance. + * This is used in paths where 802.3 frames have been received + * or queued, and need to be pushed through the VAP encapsulation + * and transmit processing pipeline. + * + * The provided mbuf/list is consumed both upon success and error. + * + * @param vap struct ieee80211vap instance to transmit frame to + * @param m mbuf to transmit + * @returns 0 if OK, errno if error */ int ieee80211_vap_xmitpkt(struct ieee80211vap *vap, struct mbuf *m) diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c index e3cd73cd22d6..da7719b16dba 100644 --- a/sys/net80211/ieee80211_output.c +++ b/sys/net80211/ieee80211_output.c @@ -1889,6 +1889,10 @@ ieee80211_encap(struct ieee80211vap *vap, struct ieee80211_node *ni, * * If the hardware does fragmentation offload, then don't bother * doing it here. + * + * Don't send AMPDU/FF/AMSDU through fragmentation. + * + * 802.11-2016 10.2.7 (Fragmentation/defragmentation overview) */ if (IEEE80211_CONF_FRAG_OFFLOAD(ic)) txfrag = 0; @@ -1963,6 +1967,33 @@ ieee80211_free_mbuf(struct mbuf *m) * mbuf for each fragment and chain it through m_nextpkt; * we might be able to optimize this by reusing the original * packet's mbufs but that is significantly more complicated. + * + * A node reference is NOT acquired for each fragment in + * the list - the caller is assumed to have taken a node + * reference for the whole list. The fragment mbufs do not + * have a node pointer. + * + * Fragments will have the sequence number and fragment numbers + * assigned. However, Fragments will NOT have a sequence number + * assigned via M_SEQNO_SET. + * + * This must be called after assigning sequence numbers; it + * modifies the i_seq field in the 802.11 header to include + * the fragment number. + * + * @param vap ieee80211vap interface + * @param m0 pointer to mbuf list to fragment + * @param hdrsize header size to reserver + * @param ciphdrsize crypto cipher header size to reserve + * @param mtu maximum fragment size + * + * This implements the fragmentation part of 802.11-2016 10.2.7 + * (Fragmentation/defragmentation overview.) + * + * @retval 1 if successful, with the mbuf pointed at by m0 + * turned into an mbuf list of fragments (with the original + * mbuf being truncated.) + * @retval 0 if failure, the mbuf needs to be freed by the caller */ static int ieee80211_fragment(struct ieee80211vap *vap, struct mbuf *m0,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202505070422.5474McFk054858>