diff options
author | Johannes Berg <johannes.berg@intel.com> | 2013-03-26 09:54:16 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-04-16 09:29:45 -0400 |
commit | b2e506bfc4d752b68a0ccaae1e977898263eba4c (patch) | |
tree | 1d5e3ea97c5a36de64f894d0a7232e861a10f201 /net/mac80211/util.c | |
parent | 1b3a2e494bc793445f576c5476e9767cf7621684 (diff) |
mac80211: parse VHT channel switch IEs
VHT introduces multiple IEs that need to be parsed for a
wide bandwidth channel switch. Two are (currently) needed
in mac80211:
* wide bandwidth channel switch element
* channel switch wrapper element
The former is contained in the latter for beacons and probe
responses, but not for the spectrum management action frames
so the IE parser needs a new argument to differentiate them.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r-- | net/mac80211/util.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 155056c90edf..3f87fa468b1f 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -661,7 +661,7 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw, | |||
661 | } | 661 | } |
662 | EXPORT_SYMBOL(ieee80211_queue_delayed_work); | 662 | EXPORT_SYMBOL(ieee80211_queue_delayed_work); |
663 | 663 | ||
664 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | 664 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, bool action, |
665 | struct ieee802_11_elems *elems, | 665 | struct ieee802_11_elems *elems, |
666 | u64 filter, u32 crc) | 666 | u64 filter, u32 crc) |
667 | { | 667 | { |
@@ -669,6 +669,7 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | |||
669 | u8 *pos = start; | 669 | u8 *pos = start; |
670 | bool calc_crc = filter != 0; | 670 | bool calc_crc = filter != 0; |
671 | DECLARE_BITMAP(seen_elems, 256); | 671 | DECLARE_BITMAP(seen_elems, 256); |
672 | const u8 *ie; | ||
672 | 673 | ||
673 | bitmap_zero(seen_elems, 256); | 674 | bitmap_zero(seen_elems, 256); |
674 | memset(elems, 0, sizeof(*elems)); | 675 | memset(elems, 0, sizeof(*elems)); |
@@ -717,6 +718,11 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | |||
717 | case WLAN_EID_PWR_CONSTRAINT: | 718 | case WLAN_EID_PWR_CONSTRAINT: |
718 | case WLAN_EID_TIMEOUT_INTERVAL: | 719 | case WLAN_EID_TIMEOUT_INTERVAL: |
719 | case WLAN_EID_SECONDARY_CHANNEL_OFFSET: | 720 | case WLAN_EID_SECONDARY_CHANNEL_OFFSET: |
721 | case WLAN_EID_WIDE_BW_CHANNEL_SWITCH: | ||
722 | /* | ||
723 | * not listing WLAN_EID_CHANNEL_SWITCH_WRAPPER -- it seems possible | ||
724 | * that if the content gets bigger it might be needed more than once | ||
725 | */ | ||
720 | if (test_bit(id, seen_elems)) { | 726 | if (test_bit(id, seen_elems)) { |
721 | elems->parse_error = true; | 727 | elems->parse_error = true; |
722 | left -= elen; | 728 | left -= elen; |
@@ -878,6 +884,34 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | |||
878 | } | 884 | } |
879 | elems->sec_chan_offs = (void *)pos; | 885 | elems->sec_chan_offs = (void *)pos; |
880 | break; | 886 | break; |
887 | case WLAN_EID_WIDE_BW_CHANNEL_SWITCH: | ||
888 | if (!action || | ||
889 | elen != sizeof(*elems->wide_bw_chansw_ie)) { | ||
890 | elem_parse_failed = true; | ||
891 | break; | ||
892 | } | ||
893 | elems->wide_bw_chansw_ie = (void *)pos; | ||
894 | break; | ||
895 | case WLAN_EID_CHANNEL_SWITCH_WRAPPER: | ||
896 | if (action) { | ||
897 | elem_parse_failed = true; | ||
898 | break; | ||
899 | } | ||
900 | /* | ||
901 | * This is a bit tricky, but as we only care about | ||
902 | * the wide bandwidth channel switch element, so | ||
903 | * just parse it out manually. | ||
904 | */ | ||
905 | ie = cfg80211_find_ie(WLAN_EID_WIDE_BW_CHANNEL_SWITCH, | ||
906 | pos, elen); | ||
907 | if (ie) { | ||
908 | if (ie[1] == sizeof(*elems->wide_bw_chansw_ie)) | ||
909 | elems->wide_bw_chansw_ie = | ||
910 | (void *)(ie + 2); | ||
911 | else | ||
912 | elem_parse_failed = true; | ||
913 | } | ||
914 | break; | ||
881 | case WLAN_EID_COUNTRY: | 915 | case WLAN_EID_COUNTRY: |
882 | elems->country_elem = pos; | 916 | elems->country_elem = pos; |
883 | elems->country_elem_len = elen; | 917 | elems->country_elem_len = elen; |