aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r--net/mac80211/main.c75
1 files changed, 37 insertions, 38 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index c6f81ecc36a1..52136fd5ba97 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -95,42 +95,47 @@ static void ieee80211_reconfig_filter(struct work_struct *work)
95static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local) 95static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
96{ 96{
97 struct ieee80211_sub_if_data *sdata; 97 struct ieee80211_sub_if_data *sdata;
98 struct ieee80211_channel *chan; 98 struct cfg80211_chan_def chandef = {};
99 u32 changed = 0; 99 u32 changed = 0;
100 int power; 100 int power;
101 enum nl80211_channel_type channel_type;
102 u32 offchannel_flag; 101 u32 offchannel_flag;
103 102
104 offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; 103 offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
104
105 if (local->scan_channel) { 105 if (local->scan_channel) {
106 chan = local->scan_channel; 106 chandef.chan = local->scan_channel;
107 /* If scanning on oper channel, use whatever channel-type 107 /* If scanning on oper channel, use whatever channel-type
108 * is currently in use. 108 * is currently in use.
109 */ 109 */
110 if (chan == local->_oper_channel) 110 if (chandef.chan == local->_oper_chandef.chan) {
111 channel_type = local->_oper_channel_type; 111 chandef = local->_oper_chandef;
112 else 112 } else {
113 channel_type = NL80211_CHAN_NO_HT; 113 chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
114 chandef.center_freq1 = chandef.chan->center_freq;
115 }
114 } else if (local->tmp_channel) { 116 } else if (local->tmp_channel) {
115 chan = local->tmp_channel; 117 chandef.chan = local->tmp_channel;
116 channel_type = NL80211_CHAN_NO_HT; 118 chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
117 } else { 119 chandef.center_freq1 = chandef.chan->center_freq;
118 chan = local->_oper_channel; 120 } else
119 channel_type = local->_oper_channel_type; 121 chandef = local->_oper_chandef;
120 } 122
121 123 WARN(!cfg80211_chandef_valid(&chandef),
122 if (chan != local->_oper_channel || 124 "control:%d MHz width:%d center: %d/%d MHz",
123 channel_type != local->_oper_channel_type) 125 chandef.chan->center_freq, chandef.width,
126 chandef.center_freq1, chandef.center_freq2);
127
128 if (!cfg80211_chandef_identical(&chandef, &local->_oper_chandef))
124 local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; 129 local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
125 else 130 else
126 local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL; 131 local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL;
127 132
128 offchannel_flag ^= local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; 133 offchannel_flag ^= local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
129 134
130 if (offchannel_flag || chan != local->hw.conf.channel || 135 if (offchannel_flag ||
131 channel_type != local->hw.conf.channel_type) { 136 !cfg80211_chandef_identical(&local->hw.conf.chandef,
132 local->hw.conf.channel = chan; 137 &local->_oper_chandef)) {
133 local->hw.conf.channel_type = channel_type; 138 local->hw.conf.chandef = chandef;
134 changed |= IEEE80211_CONF_CHANGE_CHANNEL; 139 changed |= IEEE80211_CONF_CHANGE_CHANNEL;
135 } 140 }
136 141
@@ -146,7 +151,7 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
146 changed |= IEEE80211_CONF_CHANGE_SMPS; 151 changed |= IEEE80211_CONF_CHANGE_SMPS;
147 } 152 }
148 153
149 power = chan->max_power; 154 power = chandef.chan->max_power;
150 155
151 rcu_read_lock(); 156 rcu_read_lock();
152 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 157 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
@@ -587,6 +592,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
587 IEEE80211_RADIOTAP_MCS_HAVE_BW; 592 IEEE80211_RADIOTAP_MCS_HAVE_BW;
588 local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI | 593 local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI |
589 IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH; 594 IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH;
595 local->hw.uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES;
596 local->hw.uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN;
590 local->user_power_level = IEEE80211_UNSET_POWER_LEVEL; 597 local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
591 wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; 598 wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask;
592 wiphy->vht_capa_mod_mask = &mac80211_vht_capa_mod_mask; 599 wiphy->vht_capa_mod_mask = &mac80211_vht_capa_mod_mask;
@@ -738,11 +745,15 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
738 sband = local->hw.wiphy->bands[band]; 745 sband = local->hw.wiphy->bands[band];
739 if (!sband) 746 if (!sband)
740 continue; 747 continue;
741 if (!local->use_chanctx && !local->_oper_channel) { 748 if (!local->use_chanctx && !local->_oper_chandef.chan) {
742 /* init channel we're on */ 749 /* init channel we're on */
743 local->hw.conf.channel = 750 struct cfg80211_chan_def chandef = {
744 local->_oper_channel = &sband->channels[0]; 751 .chan = &sband->channels[0],
745 local->hw.conf.channel_type = NL80211_CHAN_NO_HT; 752 .width = NL80211_CHAN_NO_HT,
753 .center_freq1 = sband->channels[0].center_freq,
754 .center_freq2 = 0
755 };
756 local->hw.conf.chandef = local->_oper_chandef = chandef;
746 } 757 }
747 cfg80211_chandef_create(&local->monitor_chandef, 758 cfg80211_chandef_create(&local->monitor_chandef,
748 &sband->channels[0], 759 &sband->channels[0],
@@ -829,22 +840,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
829 if (supp_ht) 840 if (supp_ht)
830 local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap); 841 local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap);
831 842
832 if (supp_vht) { 843 if (supp_vht)
833 local->scan_ies_len += 844 local->scan_ies_len +=
834 2 + sizeof(struct ieee80211_vht_cap); 845 2 + sizeof(struct ieee80211_vht_cap);
835 846
836 /*
837 * (for now at least), drivers wanting to use VHT must
838 * support channel contexts, as they contain all the
839 * necessary VHT information and the global hw config
840 * doesn't (yet)
841 */
842 if (WARN_ON(!local->use_chanctx)) {
843 result = -EINVAL;
844 goto fail_wiphy_register;
845 }
846 }
847
848 if (!local->ops->hw_scan) { 847 if (!local->ops->hw_scan) {
849 /* For hw_scan, driver needs to set these up. */ 848 /* For hw_scan, driver needs to set these up. */
850 local->hw.wiphy->max_scan_ssids = 4; 849 local->hw.wiphy->max_scan_ssids = 4;