aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/util.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-03-26 09:54:16 -0400
committerJohannes Berg <johannes.berg@intel.com>2013-04-16 09:29:45 -0400
commitb2e506bfc4d752b68a0ccaae1e977898263eba4c (patch)
tree1d5e3ea97c5a36de64f894d0a7232e861a10f201 /net/mac80211/util.c
parent1b3a2e494bc793445f576c5476e9767cf7621684 (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.c36
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}
662EXPORT_SYMBOL(ieee80211_queue_delayed_work); 662EXPORT_SYMBOL(ieee80211_queue_delayed_work);
663 663
664u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, 664u32 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;