aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/cfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r--net/mac80211/cfg.c58
1 files changed, 55 insertions, 3 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index ae37270a0633..c7000a6ca379 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1162,15 +1162,39 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
1162} 1162}
1163 1163
1164static int ieee80211_set_channel(struct wiphy *wiphy, 1164static int ieee80211_set_channel(struct wiphy *wiphy,
1165 struct net_device *netdev,
1165 struct ieee80211_channel *chan, 1166 struct ieee80211_channel *chan,
1166 enum nl80211_channel_type channel_type) 1167 enum nl80211_channel_type channel_type)
1167{ 1168{
1168 struct ieee80211_local *local = wiphy_priv(wiphy); 1169 struct ieee80211_local *local = wiphy_priv(wiphy);
1170 struct ieee80211_sub_if_data *sdata = NULL;
1171
1172 if (netdev)
1173 sdata = IEEE80211_DEV_TO_SUB_IF(netdev);
1174
1175 switch (ieee80211_get_channel_mode(local, NULL)) {
1176 case CHAN_MODE_HOPPING:
1177 return -EBUSY;
1178 case CHAN_MODE_FIXED:
1179 if (local->oper_channel != chan)
1180 return -EBUSY;
1181 if (!sdata && local->_oper_channel_type == channel_type)
1182 return 0;
1183 break;
1184 case CHAN_MODE_UNDEFINED:
1185 break;
1186 }
1169 1187
1170 local->oper_channel = chan; 1188 local->oper_channel = chan;
1171 local->oper_channel_type = channel_type;
1172 1189
1173 return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 1190 if (!ieee80211_set_channel_type(local, sdata, channel_type))
1191 return -EBUSY;
1192
1193 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
1194 if (sdata && sdata->vif.type != NL80211_IFTYPE_MONITOR)
1195 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT);
1196
1197 return 0;
1174} 1198}
1175 1199
1176#ifdef CONFIG_PM 1200#ifdef CONFIG_PM
@@ -1214,6 +1238,20 @@ static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev,
1214static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev, 1238static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
1215 struct cfg80211_assoc_request *req) 1239 struct cfg80211_assoc_request *req)
1216{ 1240{
1241 struct ieee80211_local *local = wiphy_priv(wiphy);
1242 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1243
1244 switch (ieee80211_get_channel_mode(local, sdata)) {
1245 case CHAN_MODE_HOPPING:
1246 return -EBUSY;
1247 case CHAN_MODE_FIXED:
1248 if (local->oper_channel == req->bss->channel)
1249 break;
1250 return -EBUSY;
1251 case CHAN_MODE_UNDEFINED:
1252 break;
1253 }
1254
1217 return ieee80211_mgd_assoc(IEEE80211_DEV_TO_SUB_IF(dev), req); 1255 return ieee80211_mgd_assoc(IEEE80211_DEV_TO_SUB_IF(dev), req);
1218} 1256}
1219 1257
@@ -1236,8 +1274,22 @@ static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev,
1236static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, 1274static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1237 struct cfg80211_ibss_params *params) 1275 struct cfg80211_ibss_params *params)
1238{ 1276{
1277 struct ieee80211_local *local = wiphy_priv(wiphy);
1239 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1278 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1240 1279
1280 switch (ieee80211_get_channel_mode(local, sdata)) {
1281 case CHAN_MODE_HOPPING:
1282 return -EBUSY;
1283 case CHAN_MODE_FIXED:
1284 if (!params->channel_fixed)
1285 return -EBUSY;
1286 if (local->oper_channel == params->channel)
1287 break;
1288 return -EBUSY;
1289 case CHAN_MODE_UNDEFINED:
1290 break;
1291 }
1292
1241 return ieee80211_ibss_join(sdata, params); 1293 return ieee80211_ibss_join(sdata, params);
1242} 1294}
1243 1295
@@ -1366,7 +1418,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
1366 * association, there's no need to send an action frame. 1418 * association, there's no need to send an action frame.
1367 */ 1419 */
1368 if (!sdata->u.mgd.associated || 1420 if (!sdata->u.mgd.associated ||
1369 sdata->local->oper_channel_type == NL80211_CHAN_NO_HT) { 1421 sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) {
1370 mutex_lock(&sdata->local->iflist_mtx); 1422 mutex_lock(&sdata->local->iflist_mtx);
1371 ieee80211_recalc_smps(sdata->local, sdata); 1423 ieee80211_recalc_smps(sdata->local, sdata);
1372 mutex_unlock(&sdata->local->iflist_mtx); 1424 mutex_unlock(&sdata->local->iflist_mtx);