PERFORCE change 116495 for review
Sam Leffler
sam at FreeBSD.org
Sat Mar 24 16:18:48 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=116495
Change 116495 by sam at 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 */
More information about the p4-projects
mailing list