Skip site navigation (1)Skip section navigation (2)
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>