diff options
author | Johannes Berg <johannes.berg@intel.com> | 2018-08-31 04:31:18 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2018-09-05 04:03:14 -0400 |
commit | 7eb26df2972504ffe37da77612c0e5f714f0d6df (patch) | |
tree | 4c3044951104f8765a40e55ae651072f90a10473 /net/mac80211/util.c | |
parent | 09b4a4faf9d037990ac4f8110dd944b27b42d5df (diff) |
mac80211: add ability to parse CCFS2
With newer VHT implementations, it's necessary to look at the
HT operation's CCFS2 field to identify the actual bandwidth
used.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r-- | net/mac80211/util.c | 48 |
1 files changed, 32 insertions, 16 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index b51fdcb5adf9..36a3c2ada515 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -2757,49 +2757,65 @@ bool ieee80211_chandef_ht_oper(const struct ieee80211_ht_operation *ht_oper, | |||
2757 | return true; | 2757 | return true; |
2758 | } | 2758 | } |
2759 | 2759 | ||
2760 | bool ieee80211_chandef_vht_oper(const struct ieee80211_vht_operation *oper, | 2760 | bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw, |
2761 | const struct ieee80211_vht_operation *oper, | ||
2762 | const struct ieee80211_ht_operation *htop, | ||
2761 | struct cfg80211_chan_def *chandef) | 2763 | struct cfg80211_chan_def *chandef) |
2762 | { | 2764 | { |
2763 | struct cfg80211_chan_def new = *chandef; | 2765 | struct cfg80211_chan_def new = *chandef; |
2764 | int cf1, cf2; | 2766 | int cf0, cf1; |
2767 | int ccfs0, ccfs1, ccfs2; | ||
2768 | int ccf0, ccf1; | ||
2765 | 2769 | ||
2766 | if (!oper) | 2770 | if (!oper || !htop) |
2767 | return false; | 2771 | return false; |
2768 | 2772 | ||
2769 | cf1 = ieee80211_channel_to_frequency(oper->center_freq_seg0_idx, | 2773 | ccfs0 = oper->center_freq_seg0_idx; |
2770 | chandef->chan->band); | 2774 | ccfs1 = oper->center_freq_seg1_idx; |
2771 | cf2 = ieee80211_channel_to_frequency(oper->center_freq_seg1_idx, | 2775 | ccfs2 = (le16_to_cpu(htop->operation_mode) & |
2772 | chandef->chan->band); | 2776 | IEEE80211_HT_OP_MODE_CCFS2_MASK) |
2777 | >> IEEE80211_HT_OP_MODE_CCFS2_SHIFT; | ||
2778 | |||
2779 | /* when parsing (and we know how to) CCFS1 and CCFS2 are equivalent */ | ||
2780 | ccf0 = ccfs0; | ||
2781 | ccf1 = ccfs1; | ||
2782 | if (!ccfs1 && ieee80211_hw_check(hw, SUPPORTS_VHT_EXT_NSS_BW)) | ||
2783 | ccf1 = ccfs2; | ||
2784 | |||
2785 | cf0 = ieee80211_channel_to_frequency(ccf0, chandef->chan->band); | ||
2786 | cf1 = ieee80211_channel_to_frequency(ccf1, chandef->chan->band); | ||
2773 | 2787 | ||
2774 | switch (oper->chan_width) { | 2788 | switch (oper->chan_width) { |
2775 | case IEEE80211_VHT_CHANWIDTH_USE_HT: | 2789 | case IEEE80211_VHT_CHANWIDTH_USE_HT: |
2790 | /* just use HT information directly */ | ||
2776 | break; | 2791 | break; |
2777 | case IEEE80211_VHT_CHANWIDTH_80MHZ: | 2792 | case IEEE80211_VHT_CHANWIDTH_80MHZ: |
2778 | new.width = NL80211_CHAN_WIDTH_80; | 2793 | new.width = NL80211_CHAN_WIDTH_80; |
2779 | new.center_freq1 = cf1; | 2794 | new.center_freq1 = cf0; |
2780 | /* If needed, adjust based on the newer interop workaround. */ | 2795 | /* If needed, adjust based on the newer interop workaround. */ |
2781 | if (oper->center_freq_seg1_idx) { | 2796 | if (ccf1) { |
2782 | unsigned int diff; | 2797 | unsigned int diff; |
2783 | 2798 | ||
2784 | diff = abs(oper->center_freq_seg1_idx - | 2799 | diff = abs(ccf1 - ccf0); |
2785 | oper->center_freq_seg0_idx); | ||
2786 | if (diff == 8) { | 2800 | if (diff == 8) { |
2787 | new.width = NL80211_CHAN_WIDTH_160; | 2801 | new.width = NL80211_CHAN_WIDTH_160; |
2788 | new.center_freq1 = cf2; | 2802 | new.center_freq1 = cf1; |
2789 | } else if (diff > 8) { | 2803 | } else if (diff > 8) { |
2790 | new.width = NL80211_CHAN_WIDTH_80P80; | 2804 | new.width = NL80211_CHAN_WIDTH_80P80; |
2791 | new.center_freq2 = cf2; | 2805 | new.center_freq2 = cf1; |
2792 | } | 2806 | } |
2793 | } | 2807 | } |
2794 | break; | 2808 | break; |
2795 | case IEEE80211_VHT_CHANWIDTH_160MHZ: | 2809 | case IEEE80211_VHT_CHANWIDTH_160MHZ: |
2810 | /* deprecated encoding */ | ||
2796 | new.width = NL80211_CHAN_WIDTH_160; | 2811 | new.width = NL80211_CHAN_WIDTH_160; |
2797 | new.center_freq1 = cf1; | 2812 | new.center_freq1 = cf0; |
2798 | break; | 2813 | break; |
2799 | case IEEE80211_VHT_CHANWIDTH_80P80MHZ: | 2814 | case IEEE80211_VHT_CHANWIDTH_80P80MHZ: |
2815 | /* deprecated encoding */ | ||
2800 | new.width = NL80211_CHAN_WIDTH_80P80; | 2816 | new.width = NL80211_CHAN_WIDTH_80P80; |
2801 | new.center_freq1 = cf1; | 2817 | new.center_freq1 = cf0; |
2802 | new.center_freq2 = cf2; | 2818 | new.center_freq2 = cf1; |
2803 | break; | 2819 | break; |
2804 | default: | 2820 | default: |
2805 | return false; | 2821 | return false; |