diff options
author | Harvey Harrison <harvey.harrison@gmail.com> | 2008-06-11 23:21:57 +0200 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-06-14 18:18:13 +0200 |
commit | 6693be7124cb8e4f15f0d80ed6e3e50678771737 (patch) | |
tree | aadddb7a21250d1e7b76e0f4ba2ca124288515e3 /net/mac80211 | |
parent | mac80211: make ieee80211_get_hdrlen_from_skb return unsigned (diff) | |
download | linux-6693be7124cb8e4f15f0d80ed6e3e50678771737.tar.xz linux-6693be7124cb8e4f15f0d80ed6e3e50678771737.zip |
mac80211: add utility function to get header length
Take a __le16 directly rather than a host-endian value.
Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/util.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index f3c30d00b21e..9f365a3af96f 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -133,6 +133,38 @@ int ieee80211_get_hdrlen(u16 fc) } EXPORT_SYMBOL(ieee80211_get_hdrlen); +unsigned int ieee80211_hdrlen(__le16 fc) +{ + unsigned int hdrlen = 24; + + if (ieee80211_is_data(fc)) { + if (ieee80211_has_a4(fc)) + hdrlen = 30; + if (ieee80211_is_data_qos(fc)) + hdrlen += IEEE80211_QOS_CTL_LEN; + goto out; + } + + if (ieee80211_is_ctl(fc)) { + /* + * ACK and CTS are 10 bytes, all others 16. To see how + * to get this condition consider + * subtype mask: 0b0000000011110000 (0x00F0) + * ACK subtype: 0b0000000011010000 (0x00D0) + * CTS subtype: 0b0000000011000000 (0x00C0) + * bits that matter: ^^^ (0x00E0) + * value of those: 0b0000000011000000 (0x00C0) + */ + if ((fc & cpu_to_le16(0x00E0)) == cpu_to_le16(0x00C0)) + hdrlen = 10; + else + hdrlen = 16; + } +out: + return hdrlen; +} +EXPORT_SYMBOL(ieee80211_hdrlen); + unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb) { const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *)skb->data; |