diff options
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r-- | net/mac80211/cfg.c | 58 |
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 | ||
1164 | static int ieee80211_set_channel(struct wiphy *wiphy, | 1164 | static 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, | |||
1214 | static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev, | 1238 | static 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, | |||
1236 | static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, | 1274 | static 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); |