aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/main.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-07-26 11:24:39 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-10-17 05:02:09 -0400
commit55de908ab292c03f1eb280f51170ddb9c6b57e31 (patch)
treebc75bb5cea581cadf6fe8b4f121cce02d07c276a /net/mac80211/main.c
parentfe57d9f5c0a2c1ef97ba8cdc42cfda5743f287b8 (diff)
mac80211: use channel contexts
Instead of operating on a single channel only, use the new channel context infrastructure in all mac80211 code. This enables drivers that want to use the new channel context infrastructure to use multiple channels, while nothing should change for all the other drivers that don't support it. Right now this disables both TX power settings and spatial multiplexing powersave. Both need to be re-enabled on a channel context basis. Additionally, when channel contexts are used drop the connection when channel switch is received rather than trying to handle it. This will have to be improved later. [With fixes from Eliad and Emmanuel incorporated] Signed-off-by: Eliad Peller <eliad@wizery.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r--net/mac80211/main.c43
1 files changed, 27 insertions, 16 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 0dd1ea241c54..9cb6280aa2f2 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -93,23 +93,21 @@ static void ieee80211_reconfig_filter(struct work_struct *work)
93 ieee80211_configure_filter(local); 93 ieee80211_configure_filter(local);
94} 94}
95 95
96int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) 96static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
97{ 97{
98 struct ieee80211_channel *chan; 98 struct ieee80211_channel *chan;
99 int ret = 0; 99 u32 changed = 0;
100 int power; 100 int power;
101 enum nl80211_channel_type channel_type; 101 enum nl80211_channel_type channel_type;
102 u32 offchannel_flag; 102 u32 offchannel_flag;
103 103
104 might_sleep();
105
106 offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; 104 offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
107 if (local->scan_channel) { 105 if (local->scan_channel) {
108 chan = local->scan_channel; 106 chan = local->scan_channel;
109 /* If scanning on oper channel, use whatever channel-type 107 /* If scanning on oper channel, use whatever channel-type
110 * is currently in use. 108 * is currently in use.
111 */ 109 */
112 if (chan == local->oper_channel) 110 if (chan == local->_oper_channel)
113 channel_type = local->_oper_channel_type; 111 channel_type = local->_oper_channel_type;
114 else 112 else
115 channel_type = NL80211_CHAN_NO_HT; 113 channel_type = NL80211_CHAN_NO_HT;
@@ -117,11 +115,11 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
117 chan = local->tmp_channel; 115 chan = local->tmp_channel;
118 channel_type = local->tmp_channel_type; 116 channel_type = local->tmp_channel_type;
119 } else { 117 } else {
120 chan = local->oper_channel; 118 chan = local->_oper_channel;
121 channel_type = local->_oper_channel_type; 119 channel_type = local->_oper_channel_type;
122 } 120 }
123 121
124 if (chan != local->oper_channel || 122 if (chan != local->_oper_channel ||
125 channel_type != local->_oper_channel_type) 123 channel_type != local->_oper_channel_type)
126 local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; 124 local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
127 else 125 else
@@ -164,6 +162,21 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
164 local->hw.conf.power_level = power; 162 local->hw.conf.power_level = power;
165 } 163 }
166 164
165 return changed;
166}
167
168int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
169{
170 int ret = 0;
171
172 might_sleep();
173
174 if (!local->use_chanctx)
175 changed |= ieee80211_hw_conf_chan(local);
176 else
177 changed &= ~(IEEE80211_CONF_CHANGE_CHANNEL |
178 IEEE80211_CONF_CHANGE_POWER);
179
167 if (changed && local->open_count) { 180 if (changed && local->open_count) {
168 ret = drv_config(local, changed); 181 ret = drv_config(local, changed);
169 /* 182 /*
@@ -775,12 +788,16 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
775 sband = local->hw.wiphy->bands[band]; 788 sband = local->hw.wiphy->bands[band];
776 if (!sband) 789 if (!sband)
777 continue; 790 continue;
778 if (!local->oper_channel) { 791 if (!local->use_chanctx && !local->_oper_channel) {
779 /* init channel we're on */ 792 /* init channel we're on */
780 local->hw.conf.channel = 793 local->hw.conf.channel =
781 local->oper_channel = &sband->channels[0]; 794 local->_oper_channel = &sband->channels[0];
782 local->hw.conf.channel_type = NL80211_CHAN_NO_HT; 795 local->hw.conf.channel_type = NL80211_CHAN_NO_HT;
783 } 796 }
797 if (!local->monitor_channel) {
798 local->monitor_channel = &sband->channels[0];
799 local->monitor_channel_type = NL80211_CHAN_NO_HT;
800 }
784 channels += sband->n_channels; 801 channels += sband->n_channels;
785 802
786 if (max_bitrates < sband->n_bitrates) 803 if (max_bitrates < sband->n_bitrates)
@@ -810,19 +827,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
810 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); 827 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
811 hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR); 828 hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
812 829
813 /* 830 /* mac80211 doesn't support more than one IBSS interface right now */
814 * mac80211 doesn't support more than 1 channel, and also not more
815 * than one IBSS interface
816 */
817 for (i = 0; i < hw->wiphy->n_iface_combinations; i++) { 831 for (i = 0; i < hw->wiphy->n_iface_combinations; i++) {
818 const struct ieee80211_iface_combination *c; 832 const struct ieee80211_iface_combination *c;
819 int j; 833 int j;
820 834
821 c = &hw->wiphy->iface_combinations[i]; 835 c = &hw->wiphy->iface_combinations[i];
822 836
823 if (c->num_different_channels > 1)
824 return -EINVAL;
825
826 for (j = 0; j < c->n_limits; j++) 837 for (j = 0; j < c->n_limits; j++)
827 if ((c->limits[j].types & BIT(NL80211_IFTYPE_ADHOC)) && 838 if ((c->limits[j].types & BIT(NL80211_IFTYPE_ADHOC)) &&
828 c->limits[j].max > 1) 839 c->limits[j].max > 1)