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.c213
1 files changed, 157 insertions, 56 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index e677b751d468..3f47276caeb8 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -13,6 +13,7 @@
13#include <linux/rcupdate.h> 13#include <linux/rcupdate.h>
14#include <net/cfg80211.h> 14#include <net/cfg80211.h>
15#include "ieee80211_i.h" 15#include "ieee80211_i.h"
16#include "driver-ops.h"
16#include "cfg.h" 17#include "cfg.h"
17#include "rate.h" 18#include "rate.h"
18#include "mesh.h" 19#include "mesh.h"
@@ -111,7 +112,7 @@ static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
111} 112}
112 113
113static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, 114static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
114 u8 key_idx, u8 *mac_addr, 115 u8 key_idx, const u8 *mac_addr,
115 struct key_params *params) 116 struct key_params *params)
116{ 117{
117 struct ieee80211_sub_if_data *sdata; 118 struct ieee80211_sub_if_data *sdata;
@@ -140,7 +141,8 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
140 return -EINVAL; 141 return -EINVAL;
141 } 142 }
142 143
143 key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key); 144 key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key,
145 params->seq_len, params->seq);
144 if (!key) 146 if (!key)
145 return -ENOMEM; 147 return -ENOMEM;
146 148
@@ -165,7 +167,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
165} 167}
166 168
167static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, 169static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
168 u8 key_idx, u8 *mac_addr) 170 u8 key_idx, const u8 *mac_addr)
169{ 171{
170 struct ieee80211_sub_if_data *sdata; 172 struct ieee80211_sub_if_data *sdata;
171 struct sta_info *sta; 173 struct sta_info *sta;
@@ -207,7 +209,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
207} 209}
208 210
209static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, 211static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
210 u8 key_idx, u8 *mac_addr, void *cookie, 212 u8 key_idx, const u8 *mac_addr, void *cookie,
211 void (*callback)(void *cookie, 213 void (*callback)(void *cookie,
212 struct key_params *params)) 214 struct key_params *params))
213{ 215{
@@ -245,12 +247,10 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
245 iv32 = key->u.tkip.tx.iv32; 247 iv32 = key->u.tkip.tx.iv32;
246 iv16 = key->u.tkip.tx.iv16; 248 iv16 = key->u.tkip.tx.iv16;
247 249
248 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && 250 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
249 sdata->local->ops->get_tkip_seq) 251 drv_get_tkip_seq(sdata->local,
250 sdata->local->ops->get_tkip_seq( 252 key->conf.hw_key_idx,
251 local_to_hw(sdata->local), 253 &iv32, &iv16);
252 key->conf.hw_key_idx,
253 &iv32, &iv16);
254 254
255 seq[0] = iv16 & 0xff; 255 seq[0] = iv16 & 0xff;
256 seq[1] = (iv16 >> 8) & 0xff; 256 seq[1] = (iv16 >> 8) & 0xff;
@@ -451,18 +451,11 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
451 * This is a kludge. beacon interval should really be part 451 * This is a kludge. beacon interval should really be part
452 * of the beacon information. 452 * of the beacon information.
453 */ 453 */
454 if (params->interval && (sdata->local->hw.conf.beacon_int != 454 if (params->interval &&
455 params->interval)) { 455 (sdata->vif.bss_conf.beacon_int != params->interval)) {
456 sdata->local->hw.conf.beacon_int = params->interval; 456 sdata->vif.bss_conf.beacon_int = params->interval;
457 err = ieee80211_hw_config(sdata->local, 457 ieee80211_bss_info_change_notify(sdata,
458 IEEE80211_CONF_CHANGE_BEACON_INTERVAL); 458 BSS_CHANGED_BEACON_INT);
459 if (err < 0)
460 return err;
461 /*
462 * We updated some parameter so if below bails out
463 * it's not an error.
464 */
465 err = 0;
466 } 459 }
467 460
468 /* Need to have a beacon head if we don't have one yet */ 461 /* Need to have a beacon head if we don't have one yet */
@@ -528,8 +521,9 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
528 521
529 kfree(old); 522 kfree(old);
530 523
531 return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON | 524 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED |
532 IEEE80211_IFCC_BEACON_ENABLED); 525 BSS_CHANGED_BEACON);
526 return 0;
533} 527}
534 528
535static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, 529static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
@@ -580,7 +574,8 @@ static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
580 synchronize_rcu(); 574 synchronize_rcu();
581 kfree(old); 575 kfree(old);
582 576
583 return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON_ENABLED); 577 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
578 return 0;
584} 579}
585 580
586/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */ 581/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
@@ -635,34 +630,45 @@ static void sta_apply_parameters(struct ieee80211_local *local,
635 int i, j; 630 int i, j;
636 struct ieee80211_supported_band *sband; 631 struct ieee80211_supported_band *sband;
637 struct ieee80211_sub_if_data *sdata = sta->sdata; 632 struct ieee80211_sub_if_data *sdata = sta->sdata;
633 u32 mask, set;
638 634
639 sband = local->hw.wiphy->bands[local->oper_channel->band]; 635 sband = local->hw.wiphy->bands[local->oper_channel->band];
640 636
641 /* 637 spin_lock_bh(&sta->lock);
642 * FIXME: updating the flags is racy when this function is 638 mask = params->sta_flags_mask;
643 * called from ieee80211_change_station(), this will 639 set = params->sta_flags_set;
644 * be resolved in a future patch.
645 */
646 640
647 if (params->station_flags & STATION_FLAG_CHANGED) { 641 if (mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
648 spin_lock_bh(&sta->lock);
649 sta->flags &= ~WLAN_STA_AUTHORIZED; 642 sta->flags &= ~WLAN_STA_AUTHORIZED;
650 if (params->station_flags & STATION_FLAG_AUTHORIZED) 643 if (set & BIT(NL80211_STA_FLAG_AUTHORIZED))
651 sta->flags |= WLAN_STA_AUTHORIZED; 644 sta->flags |= WLAN_STA_AUTHORIZED;
645 }
652 646
647 if (mask & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) {
653 sta->flags &= ~WLAN_STA_SHORT_PREAMBLE; 648 sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
654 if (params->station_flags & STATION_FLAG_SHORT_PREAMBLE) 649 if (set & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE))
655 sta->flags |= WLAN_STA_SHORT_PREAMBLE; 650 sta->flags |= WLAN_STA_SHORT_PREAMBLE;
651 }
656 652
653 if (mask & BIT(NL80211_STA_FLAG_WME)) {
657 sta->flags &= ~WLAN_STA_WME; 654 sta->flags &= ~WLAN_STA_WME;
658 if (params->station_flags & STATION_FLAG_WME) 655 if (set & BIT(NL80211_STA_FLAG_WME))
659 sta->flags |= WLAN_STA_WME; 656 sta->flags |= WLAN_STA_WME;
657 }
660 658
659 if (mask & BIT(NL80211_STA_FLAG_MFP)) {
661 sta->flags &= ~WLAN_STA_MFP; 660 sta->flags &= ~WLAN_STA_MFP;
662 if (params->station_flags & STATION_FLAG_MFP) 661 if (set & BIT(NL80211_STA_FLAG_MFP))
663 sta->flags |= WLAN_STA_MFP; 662 sta->flags |= WLAN_STA_MFP;
664 spin_unlock_bh(&sta->lock);
665 } 663 }
664 spin_unlock_bh(&sta->lock);
665
666 /*
667 * cfg80211 validates this (1-2007) and allows setting the AID
668 * only when creating a new station entry
669 */
670 if (params->aid)
671 sta->sta.aid = params->aid;
666 672
667 /* 673 /*
668 * FIXME: updating the following information is racy when this 674 * FIXME: updating the following information is racy when this
@@ -671,12 +677,6 @@ static void sta_apply_parameters(struct ieee80211_local *local,
671 * maybe we should just reject attemps to change it. 677 * maybe we should just reject attemps to change it.
672 */ 678 */
673 679
674 if (params->aid) {
675 sta->sta.aid = params->aid;
676 if (sta->sta.aid > IEEE80211_MAX_AID)
677 sta->sta.aid = 0; /* XXX: should this be an error? */
678 }
679
680 if (params->listen_interval >= 0) 680 if (params->listen_interval >= 0)
681 sta->listen_interval = params->listen_interval; 681 sta->listen_interval = params->listen_interval;
682 682
@@ -1120,10 +1120,10 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
1120 p.cw_max = params->cwmax; 1120 p.cw_max = params->cwmax;
1121 p.cw_min = params->cwmin; 1121 p.cw_min = params->cwmin;
1122 p.txop = params->txop; 1122 p.txop = params->txop;
1123 if (local->ops->conf_tx(local_to_hw(local), params->queue, &p)) { 1123 if (drv_conf_tx(local, params->queue, &p)) {
1124 printk(KERN_DEBUG "%s: failed to set TX queue " 1124 printk(KERN_DEBUG "%s: failed to set TX queue "
1125 "parameters for queue %d\n", local->mdev->name, 1125 "parameters for queue %d\n",
1126 params->queue); 1126 wiphy_name(local->hw.wiphy), params->queue);
1127 return -EINVAL; 1127 return -EINVAL;
1128 } 1128 }
1129 1129
@@ -1167,7 +1167,8 @@ static int ieee80211_scan(struct wiphy *wiphy,
1167 1167
1168 if (sdata->vif.type != NL80211_IFTYPE_STATION && 1168 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
1169 sdata->vif.type != NL80211_IFTYPE_ADHOC && 1169 sdata->vif.type != NL80211_IFTYPE_ADHOC &&
1170 sdata->vif.type != NL80211_IFTYPE_MESH_POINT) 1170 sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
1171 (sdata->vif.type != NL80211_IFTYPE_AP || sdata->u.ap.beacon))
1171 return -EOPNOTSUPP; 1172 return -EOPNOTSUPP;
1172 1173
1173 return ieee80211_request_scan(sdata, req); 1174 return ieee80211_request_scan(sdata, req);
@@ -1255,9 +1256,22 @@ static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
1255 sdata->u.mgd.flags |= IEEE80211_STA_AUTO_SSID_SEL; 1256 sdata->u.mgd.flags |= IEEE80211_STA_AUTO_SSID_SEL;
1256 1257
1257 ret = ieee80211_sta_set_extra_ie(sdata, req->ie, req->ie_len); 1258 ret = ieee80211_sta_set_extra_ie(sdata, req->ie, req->ie_len);
1258 if (ret) 1259 if (ret && ret != -EALREADY)
1259 return ret; 1260 return ret;
1260 1261
1262 if (req->use_mfp) {
1263 sdata->u.mgd.mfp = IEEE80211_MFP_REQUIRED;
1264 sdata->u.mgd.flags |= IEEE80211_STA_MFP_ENABLED;
1265 } else {
1266 sdata->u.mgd.mfp = IEEE80211_MFP_DISABLED;
1267 sdata->u.mgd.flags &= ~IEEE80211_STA_MFP_ENABLED;
1268 }
1269
1270 if (req->control_port)
1271 sdata->u.mgd.flags |= IEEE80211_STA_CONTROL_PORT;
1272 else
1273 sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
1274
1261 sdata->u.mgd.flags |= IEEE80211_STA_EXT_SME; 1275 sdata->u.mgd.flags |= IEEE80211_STA_EXT_SME;
1262 sdata->u.mgd.state = IEEE80211_STA_MLME_ASSOCIATE; 1276 sdata->u.mgd.state = IEEE80211_STA_MLME_ASSOCIATE;
1263 ieee80211_sta_req_auth(sdata); 1277 ieee80211_sta_req_auth(sdata);
@@ -1267,25 +1281,106 @@ static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
1267static int ieee80211_deauth(struct wiphy *wiphy, struct net_device *dev, 1281static int ieee80211_deauth(struct wiphy *wiphy, struct net_device *dev,
1268 struct cfg80211_deauth_request *req) 1282 struct cfg80211_deauth_request *req)
1269{ 1283{
1270 struct ieee80211_sub_if_data *sdata; 1284 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1271
1272 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1273 1285
1274 /* TODO: req->ie */ 1286 /* TODO: req->ie, req->peer_addr */
1275 return ieee80211_sta_deauthenticate(sdata, req->reason_code); 1287 return ieee80211_sta_deauthenticate(sdata, req->reason_code);
1276} 1288}
1277 1289
1278static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev, 1290static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev,
1279 struct cfg80211_disassoc_request *req) 1291 struct cfg80211_disassoc_request *req)
1280{ 1292{
1281 struct ieee80211_sub_if_data *sdata; 1293 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1282
1283 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1284 1294
1285 /* TODO: req->ie */ 1295 /* TODO: req->ie, req->peer_addr */
1286 return ieee80211_sta_disassociate(sdata, req->reason_code); 1296 return ieee80211_sta_disassociate(sdata, req->reason_code);
1287} 1297}
1288 1298
1299static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1300 struct cfg80211_ibss_params *params)
1301{
1302 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1303
1304 return ieee80211_ibss_join(sdata, params);
1305}
1306
1307static int ieee80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1308{
1309 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1310
1311 return ieee80211_ibss_leave(sdata);
1312}
1313
1314static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1315{
1316 struct ieee80211_local *local = wiphy_priv(wiphy);
1317 int err;
1318
1319 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1320 err = drv_set_rts_threshold(local, wiphy->rts_threshold);
1321
1322 if (err)
1323 return err;
1324 }
1325
1326 if (changed & WIPHY_PARAM_RETRY_SHORT)
1327 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
1328 if (changed & WIPHY_PARAM_RETRY_LONG)
1329 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
1330 if (changed &
1331 (WIPHY_PARAM_RETRY_SHORT | WIPHY_PARAM_RETRY_LONG))
1332 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS);
1333
1334 return 0;
1335}
1336
1337static int ieee80211_set_tx_power(struct wiphy *wiphy,
1338 enum tx_power_setting type, int dbm)
1339{
1340 struct ieee80211_local *local = wiphy_priv(wiphy);
1341 struct ieee80211_channel *chan = local->hw.conf.channel;
1342 u32 changes = 0;
1343
1344 switch (type) {
1345 case TX_POWER_AUTOMATIC:
1346 local->user_power_level = -1;
1347 break;
1348 case TX_POWER_LIMITED:
1349 if (dbm < 0)
1350 return -EINVAL;
1351 local->user_power_level = dbm;
1352 break;
1353 case TX_POWER_FIXED:
1354 if (dbm < 0)
1355 return -EINVAL;
1356 /* TODO: move to cfg80211 when it knows the channel */
1357 if (dbm > chan->max_power)
1358 return -EINVAL;
1359 local->user_power_level = dbm;
1360 break;
1361 }
1362
1363 ieee80211_hw_config(local, changes);
1364
1365 return 0;
1366}
1367
1368static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm)
1369{
1370 struct ieee80211_local *local = wiphy_priv(wiphy);
1371
1372 *dbm = local->hw.conf.power_level;
1373
1374 return 0;
1375}
1376
1377static void ieee80211_rfkill_poll(struct wiphy *wiphy)
1378{
1379 struct ieee80211_local *local = wiphy_priv(wiphy);
1380
1381 drv_rfkill_poll(local);
1382}
1383
1289struct cfg80211_ops mac80211_config_ops = { 1384struct cfg80211_ops mac80211_config_ops = {
1290 .add_virtual_intf = ieee80211_add_iface, 1385 .add_virtual_intf = ieee80211_add_iface,
1291 .del_virtual_intf = ieee80211_del_iface, 1386 .del_virtual_intf = ieee80211_del_iface,
@@ -1322,4 +1417,10 @@ struct cfg80211_ops mac80211_config_ops = {
1322 .assoc = ieee80211_assoc, 1417 .assoc = ieee80211_assoc,
1323 .deauth = ieee80211_deauth, 1418 .deauth = ieee80211_deauth,
1324 .disassoc = ieee80211_disassoc, 1419 .disassoc = ieee80211_disassoc,
1420 .join_ibss = ieee80211_join_ibss,
1421 .leave_ibss = ieee80211_leave_ibss,
1422 .set_wiphy_params = ieee80211_set_wiphy_params,
1423 .set_tx_power = ieee80211_set_tx_power,
1424 .get_tx_power = ieee80211_get_tx_power,
1425 .rfkill_poll = ieee80211_rfkill_poll,
1325}; 1426};