Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 24 Mar 2007 16:18:47 GMT
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 116495 for review
Message-ID:  <200703241618.l2OGIlTu038786@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=116495

Change 116495 by sam@sam_ebb on 2007/03/24 16:18:40

	Add driver-specified headroom requirement:
	o change ieee80211_getmgtframe to take an additional parameter
	  that specifies the headroom required for prepending headers
	  and always backload the payload, even when allocating a cluster
	  (this also eliminate the builting knowledge that the payload
	  will be encapsulated with struct ieee80211_frame)
	o add ic_headroom to the com structure for drivers to specify
	  an additional headroom space requirement for outbound frames
	
	This eliminates potential copies for drivers that must prepend
	chip-specific crap at the front of outbound frames.

Affected files ...

.. //depot/projects/wifi/sys/net80211/ieee80211_freebsd.c#24 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_freebsd.h#25 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_output.c#70 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_var.h#53 edit

Differences ...

==== //depot/projects/wifi/sys/net80211/ieee80211_freebsd.c#24 (text+ko) ====

@@ -171,6 +171,15 @@
 }
 
 /*
+ * As above, for mbufs allocated with m_gethdr/MGETHDR
+ * or initialized by M_COPY_PKTHDR.
+ */
+#define	MC_ALIGN(m, len)						\
+do {									\
+	(m)->m_data += (MCLBYTES - (len)) &~ (sizeof(long) - 1);	\
+} while (/* CONSTCOND */ 0)
+
+/*
  * Allocate and setup a management frame of the specified
  * size.  We return the mbuf and a pointer to the start
  * of the contiguous data area that's been reserved based
@@ -180,7 +189,7 @@
  * can use this interface too.
  */
 struct mbuf *
-ieee80211_getmgtframe(u_int8_t **frm, u_int pktlen)
+ieee80211_getmgtframe(u_int8_t **frm, int headroom, int pktlen)
 {
 	struct mbuf *m;
 	u_int len;
@@ -189,8 +198,7 @@
 	 * NB: we know the mbuf routines will align the data area
 	 *     so we don't need to do anything special.
 	 */
-	/* XXX 4-address frame? */
-	len = roundup(sizeof(struct ieee80211_frame) + pktlen, 4);
+	len = roundup2(headroom + pktlen, 4);
 	KASSERT(len <= MCLBYTES, ("802.11 mgt frame too large: %u", len));
 	if (len < MINCLSIZE) {
 		m = m_gethdr(M_NOWAIT, MT_DATA);
@@ -202,8 +210,11 @@
 		 */
 		if (m != NULL)
 			MH_ALIGN(m, len);
-	} else
+	} else {
 		m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
+		if (m != NULL)
+			MC_ALIGN(m, len);
+	}
 	if (m != NULL) {
 		m->m_data += sizeof(struct ieee80211_frame);
 		*frm = m->m_data;

==== //depot/projects/wifi/sys/net80211/ieee80211_freebsd.h#25 (text+ko) ====

@@ -185,7 +185,7 @@
 #define time_after_eq(a,b)	((long)(a) - (long)(b) >= 0)
 #define time_before_eq(a,b)	time_after_eq(b,a)
 
-struct mbuf *ieee80211_getmgtframe(u_int8_t **frm, u_int pktlen);
+struct mbuf *ieee80211_getmgtframe(u_int8_t **frm, int headroom, int pktlen);
 #define	M_LINK0		M_PROTO1		/* WEP requested */
 #define	M_PWR_SAV	M_PROTO4		/* bypass PS handling */
 #define	M_MORE_DATA	M_PROTO5		/* more data frames to follow */

==== //depot/projects/wifi/sys/net80211/ieee80211_output.c#70 (text+ko) ====

@@ -359,6 +359,7 @@
 		ic->ic_stats.is_tx_nobuf++;
 		return ENOMEM;
 	}
+	MH_ALIGN(m, sizeof(struct ieee80211_frame));
 	m->m_pkthdr.rcvif = (void *) ni;
 
 	wh = mtod(m, struct ieee80211_frame *);
@@ -512,7 +513,7 @@
 	struct ieee80211_key *key, struct mbuf *m)
 {
 #define	TO_BE_RECLAIMED	(sizeof(struct ether_header) - sizeof(struct llc))
-	int needed_space = hdrsize;
+	int needed_space = ic->ic_headroom + hdrsize;
 
 	if (key != NULL) {
 		/* XXX belongs in crypto code? */
@@ -1464,6 +1465,7 @@
 	 *	[tlv] user-specified ie's
 	 */
 	m = ieee80211_getmgtframe(&frm,
+		 ic->ic_headroom + sizeof(struct ieee80211_frame),
 		 2 + IEEE80211_NWID_LEN
 	       + 2 + IEEE80211_RATE_SIZE
 	       + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
@@ -1584,6 +1586,7 @@
 		 *	[tlv] Atheros capabilities
 		 */
 		m = ieee80211_getmgtframe(&frm,
+			 ic->ic_headroom + sizeof(struct ieee80211_frame),
 			 8
 		       + sizeof(u_int16_t)
 		       + sizeof(u_int16_t)
@@ -1668,6 +1671,7 @@
 		      ic->ic_bss->ni_authmode == IEEE80211_AUTH_SHARED);
 
 		m = ieee80211_getmgtframe(&frm,
+			  ic->ic_headroom + sizeof(struct ieee80211_frame),
 			  3 * sizeof(u_int16_t)
 			+ (has_challenge && status == IEEE80211_STATUS_SUCCESS ?
 				sizeof(u_int16_t)+IEEE80211_CHALLENGE_LEN : 0)
@@ -1713,7 +1717,9 @@
 		IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
 			"[%s] send station deauthenticate (reason %d)\n",
 			ether_sprintf(ni->ni_macaddr), arg);
-		m = ieee80211_getmgtframe(&frm, sizeof(u_int16_t));
+		m = ieee80211_getmgtframe(&frm,
+			ic->ic_headroom + sizeof(struct ieee80211_frame),
+			sizeof(u_int16_t));
 		if (m == NULL)
 			senderr(ENOMEM, is_tx_nobuf);
 		*(u_int16_t *)frm = htole16(arg);	/* reason */
@@ -1740,6 +1746,7 @@
 		 *	[tlv] user-specified ie's
 		 */
 		m = ieee80211_getmgtframe(&frm,
+			 ic->ic_headroom + sizeof(struct ieee80211_frame),
 			 sizeof(u_int16_t)
 		       + sizeof(u_int16_t)
 		       + IEEE80211_ADDR_LEN
@@ -1817,6 +1824,7 @@
 		 *	[tlv] Atheros capabilities (if enabled and STA enabled)
 		 */
 		m = ieee80211_getmgtframe(&frm,
+			 ic->ic_headroom + sizeof(struct ieee80211_frame),
 			 sizeof(u_int16_t)
 		       + sizeof(u_int16_t)
 		       + sizeof(u_int16_t)
@@ -1857,7 +1865,9 @@
 		IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
 			"[%s] send station disassociate (reason %d)\n",
 			ether_sprintf(ni->ni_macaddr), arg);
-		m = ieee80211_getmgtframe(&frm, sizeof(u_int16_t));
+		m = ieee80211_getmgtframe(&frm,
+			ic->ic_headroom + sizeof(struct ieee80211_frame),
+			sizeof(u_int16_t));
 		if (m == NULL)
 			senderr(ENOMEM, is_tx_nobuf);
 		*(u_int16_t *)frm = htole16(arg);	/* reason */
@@ -1971,7 +1981,8 @@
 		 + (ic->ic_caps & IEEE80211_C_WPA ?	/* WPA 1+2 */
 			2*sizeof(struct ieee80211_ie_wpa) : 0)
 		 ;
-	m = ieee80211_getmgtframe(&frm, pktlen);
+	m = ieee80211_getmgtframe(&frm,
+		ic->ic_headroom + sizeof(struct ieee80211_frame), pktlen);
 	if (m == NULL) {
 		IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
 			"%s: cannot get buf; size %u\n", __func__, pktlen);

==== //depot/projects/wifi/sys/net80211/ieee80211_var.h#53 (text+ko) ====

@@ -103,6 +103,7 @@
 	struct sysctl_ctx_list	*ic_sysctl;	/* dynamic sysctl context */
 	u_int32_t		ic_debug;	/* debug msg flags */
 	int			ic_vap;		/* virtual AP index */
+	int			ic_headroom;	/* driver tx headroom needs */
 	enum ieee80211_phytype	ic_phytype;	/* XXX wrong for multi-mode */
 	enum ieee80211_opmode	ic_opmode;	/* operation mode */
 	struct ifmedia		ic_media;	/* interface media config */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200703241618.l2OGIlTu038786>