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.c198
1 files changed, 132 insertions, 66 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 9ae1a4760b58..b7116ef84a3b 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * mac80211 configuration hooks for cfg80211 2 * mac80211 configuration hooks for cfg80211
3 * 3 *
4 * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net> 4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
5 * 5 *
6 * This file is GPLv2 as found in COPYING. 6 * This file is GPLv2 as found in COPYING.
7 */ 7 */
@@ -78,17 +78,15 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
78 enum nl80211_iftype type, u32 *flags, 78 enum nl80211_iftype type, u32 *flags,
79 struct vif_params *params) 79 struct vif_params *params)
80{ 80{
81 struct ieee80211_sub_if_data *sdata; 81 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
82 int ret; 82 int ret;
83 83
84 if (netif_running(dev)) 84 if (ieee80211_sdata_running(sdata))
85 return -EBUSY; 85 return -EBUSY;
86 86
87 if (!nl80211_params_check(type, params)) 87 if (!nl80211_params_check(type, params))
88 return -EINVAL; 88 return -EINVAL;
89 89
90 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
91
92 ret = ieee80211_if_change_type(sdata, type); 90 ret = ieee80211_if_change_type(sdata, type);
93 if (ret) 91 if (ret)
94 return ret; 92 return ret;
@@ -150,7 +148,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
150 rcu_read_lock(); 148 rcu_read_lock();
151 149
152 if (mac_addr) { 150 if (mac_addr) {
153 sta = sta_info_get(sdata->local, mac_addr); 151 sta = sta_info_get_bss(sdata, mac_addr);
154 if (!sta) { 152 if (!sta) {
155 ieee80211_key_free(key); 153 ieee80211_key_free(key);
156 err = -ENOENT; 154 err = -ENOENT;
@@ -181,7 +179,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
181 if (mac_addr) { 179 if (mac_addr) {
182 ret = -ENOENT; 180 ret = -ENOENT;
183 181
184 sta = sta_info_get(sdata->local, mac_addr); 182 sta = sta_info_get_bss(sdata, mac_addr);
185 if (!sta) 183 if (!sta)
186 goto out_unlock; 184 goto out_unlock;
187 185
@@ -228,7 +226,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
228 rcu_read_lock(); 226 rcu_read_lock();
229 227
230 if (mac_addr) { 228 if (mac_addr) {
231 sta = sta_info_get(sdata->local, mac_addr); 229 sta = sta_info_get_bss(sdata, mac_addr);
232 if (!sta) 230 if (!sta)
233 goto out; 231 goto out;
234 232
@@ -415,15 +413,13 @@ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
415static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, 413static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
416 u8 *mac, struct station_info *sinfo) 414 u8 *mac, struct station_info *sinfo)
417{ 415{
418 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 416 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
419 struct sta_info *sta; 417 struct sta_info *sta;
420 int ret = -ENOENT; 418 int ret = -ENOENT;
421 419
422 rcu_read_lock(); 420 rcu_read_lock();
423 421
424 /* XXX: verify sta->dev == dev */ 422 sta = sta_info_get_bss(sdata, mac);
425
426 sta = sta_info_get(local, mac);
427 if (sta) { 423 if (sta) {
428 ret = 0; 424 ret = 0;
429 sta_set_sinfo(sta, sinfo); 425 sta_set_sinfo(sta, sinfo);
@@ -519,6 +515,8 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
519 if (old) 515 if (old)
520 memcpy(new->tail, old->tail, new_tail_len); 516 memcpy(new->tail, old->tail, new_tail_len);
521 517
518 sdata->vif.bss_conf.dtim_period = new->dtim_period;
519
522 rcu_assign_pointer(sdata->u.ap.beacon, new); 520 rcu_assign_pointer(sdata->u.ap.beacon, new);
523 521
524 synchronize_rcu(); 522 synchronize_rcu();
@@ -732,7 +730,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
732 } else 730 } else
733 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 731 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
734 732
735 if (compare_ether_addr(mac, dev->dev_addr) == 0) 733 if (compare_ether_addr(mac, sdata->vif.addr) == 0)
736 return -EINVAL; 734 return -EINVAL;
737 735
738 if (is_multicast_ether_addr(mac)) 736 if (is_multicast_ether_addr(mac))
@@ -751,9 +749,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
751 layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN || 749 layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
752 sdata->vif.type == NL80211_IFTYPE_AP; 750 sdata->vif.type == NL80211_IFTYPE_AP;
753 751
754 rcu_read_lock(); 752 err = sta_info_insert_rcu(sta);
755
756 err = sta_info_insert(sta);
757 if (err) { 753 if (err) {
758 rcu_read_unlock(); 754 rcu_read_unlock();
759 return err; 755 return err;
@@ -772,27 +768,13 @@ static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
772{ 768{
773 struct ieee80211_local *local = wiphy_priv(wiphy); 769 struct ieee80211_local *local = wiphy_priv(wiphy);
774 struct ieee80211_sub_if_data *sdata; 770 struct ieee80211_sub_if_data *sdata;
775 struct sta_info *sta;
776 771
777 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 772 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
778 773
779 if (mac) { 774 if (mac)
780 rcu_read_lock(); 775 return sta_info_destroy_addr_bss(sdata, mac);
781
782 /* XXX: get sta belonging to dev */
783 sta = sta_info_get(local, mac);
784 if (!sta) {
785 rcu_read_unlock();
786 return -ENOENT;
787 }
788
789 sta_info_unlink(&sta);
790 rcu_read_unlock();
791
792 sta_info_destroy(sta);
793 } else
794 sta_info_flush(local, sdata);
795 776
777 sta_info_flush(local, sdata);
796 return 0; 778 return 0;
797} 779}
798 780
@@ -801,14 +783,14 @@ static int ieee80211_change_station(struct wiphy *wiphy,
801 u8 *mac, 783 u8 *mac,
802 struct station_parameters *params) 784 struct station_parameters *params)
803{ 785{
786 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
804 struct ieee80211_local *local = wiphy_priv(wiphy); 787 struct ieee80211_local *local = wiphy_priv(wiphy);
805 struct sta_info *sta; 788 struct sta_info *sta;
806 struct ieee80211_sub_if_data *vlansdata; 789 struct ieee80211_sub_if_data *vlansdata;
807 790
808 rcu_read_lock(); 791 rcu_read_lock();
809 792
810 /* XXX: get sta belonging to dev */ 793 sta = sta_info_get_bss(sdata, mac);
811 sta = sta_info_get(local, mac);
812 if (!sta) { 794 if (!sta) {
813 rcu_read_unlock(); 795 rcu_read_unlock();
814 return -ENOENT; 796 return -ENOENT;
@@ -847,7 +829,6 @@ static int ieee80211_change_station(struct wiphy *wiphy,
847static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev, 829static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
848 u8 *dst, u8 *next_hop) 830 u8 *dst, u8 *next_hop)
849{ 831{
850 struct ieee80211_local *local = wiphy_priv(wiphy);
851 struct ieee80211_sub_if_data *sdata; 832 struct ieee80211_sub_if_data *sdata;
852 struct mesh_path *mpath; 833 struct mesh_path *mpath;
853 struct sta_info *sta; 834 struct sta_info *sta;
@@ -856,7 +837,7 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
856 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 837 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
857 838
858 rcu_read_lock(); 839 rcu_read_lock();
859 sta = sta_info_get(local, next_hop); 840 sta = sta_info_get(sdata, next_hop);
860 if (!sta) { 841 if (!sta) {
861 rcu_read_unlock(); 842 rcu_read_unlock();
862 return -ENOENT; 843 return -ENOENT;
@@ -895,7 +876,6 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
895 struct net_device *dev, 876 struct net_device *dev,
896 u8 *dst, u8 *next_hop) 877 u8 *dst, u8 *next_hop)
897{ 878{
898 struct ieee80211_local *local = wiphy_priv(wiphy);
899 struct ieee80211_sub_if_data *sdata; 879 struct ieee80211_sub_if_data *sdata;
900 struct mesh_path *mpath; 880 struct mesh_path *mpath;
901 struct sta_info *sta; 881 struct sta_info *sta;
@@ -904,7 +884,7 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
904 884
905 rcu_read_lock(); 885 rcu_read_lock();
906 886
907 sta = sta_info_get(local, next_hop); 887 sta = sta_info_get(sdata, next_hop);
908 if (!sta) { 888 if (!sta) {
909 rcu_read_unlock(); 889 rcu_read_unlock();
910 return -ENOENT; 890 return -ENOENT;
@@ -1092,6 +1072,13 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
1092 params->use_short_preamble; 1072 params->use_short_preamble;
1093 changed |= BSS_CHANGED_ERP_PREAMBLE; 1073 changed |= BSS_CHANGED_ERP_PREAMBLE;
1094 } 1074 }
1075
1076 if (!sdata->vif.bss_conf.use_short_slot &&
1077 sdata->local->hw.conf.channel->band == IEEE80211_BAND_5GHZ) {
1078 sdata->vif.bss_conf.use_short_slot = true;
1079 changed |= BSS_CHANGED_ERP_SLOT;
1080 }
1081
1095 if (params->use_short_slot_time >= 0) { 1082 if (params->use_short_slot_time >= 0) {
1096 sdata->vif.bss_conf.use_short_slot = 1083 sdata->vif.bss_conf.use_short_slot =
1097 params->use_short_slot_time; 1084 params->use_short_slot_time;
@@ -1135,6 +1122,13 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
1135 p.cw_max = params->cwmax; 1122 p.cw_max = params->cwmax;
1136 p.cw_min = params->cwmin; 1123 p.cw_min = params->cwmin;
1137 p.txop = params->txop; 1124 p.txop = params->txop;
1125
1126 /*
1127 * Setting tx queue params disables u-apsd because it's only
1128 * called in master mode.
1129 */
1130 p.uapsd = false;
1131
1138 if (drv_conf_tx(local, params->queue, &p)) { 1132 if (drv_conf_tx(local, params->queue, &p)) {
1139 printk(KERN_DEBUG "%s: failed to set TX queue " 1133 printk(KERN_DEBUG "%s: failed to set TX queue "
1140 "parameters for queue %d\n", 1134 "parameters for queue %d\n",
@@ -1237,6 +1231,13 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1237 struct ieee80211_local *local = wiphy_priv(wiphy); 1231 struct ieee80211_local *local = wiphy_priv(wiphy);
1238 int err; 1232 int err;
1239 1233
1234 if (changed & WIPHY_PARAM_COVERAGE_CLASS) {
1235 err = drv_set_coverage_class(local, wiphy->coverage_class);
1236
1237 if (err)
1238 return err;
1239 }
1240
1240 if (changed & WIPHY_PARAM_RTS_THRESHOLD) { 1241 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1241 err = drv_set_rts_threshold(local, wiphy->rts_threshold); 1242 err = drv_set_rts_threshold(local, wiphy->rts_threshold);
1242 1243
@@ -1324,6 +1325,50 @@ static int ieee80211_testmode_cmd(struct wiphy *wiphy, void *data, int len)
1324} 1325}
1325#endif 1326#endif
1326 1327
1328int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
1329 enum ieee80211_smps_mode smps_mode)
1330{
1331 const u8 *ap;
1332 enum ieee80211_smps_mode old_req;
1333 int err;
1334
1335 old_req = sdata->u.mgd.req_smps;
1336 sdata->u.mgd.req_smps = smps_mode;
1337
1338 if (old_req == smps_mode &&
1339 smps_mode != IEEE80211_SMPS_AUTOMATIC)
1340 return 0;
1341
1342 /*
1343 * If not associated, or current association is not an HT
1344 * association, there's no need to send an action frame.
1345 */
1346 if (!sdata->u.mgd.associated ||
1347 sdata->local->oper_channel_type == NL80211_CHAN_NO_HT) {
1348 mutex_lock(&sdata->local->iflist_mtx);
1349 ieee80211_recalc_smps(sdata->local, sdata);
1350 mutex_unlock(&sdata->local->iflist_mtx);
1351 return 0;
1352 }
1353
1354 ap = sdata->u.mgd.associated->bssid;
1355
1356 if (smps_mode == IEEE80211_SMPS_AUTOMATIC) {
1357 if (sdata->u.mgd.powersave)
1358 smps_mode = IEEE80211_SMPS_DYNAMIC;
1359 else
1360 smps_mode = IEEE80211_SMPS_OFF;
1361 }
1362
1363 /* send SM PS frame to AP */
1364 err = ieee80211_send_smps_action(sdata, smps_mode,
1365 ap, ap);
1366 if (err)
1367 sdata->u.mgd.req_smps = old_req;
1368
1369 return err;
1370}
1371
1327static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, 1372static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1328 bool enabled, int timeout) 1373 bool enabled, int timeout)
1329{ 1374{
@@ -1344,6 +1389,11 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1344 sdata->u.mgd.powersave = enabled; 1389 sdata->u.mgd.powersave = enabled;
1345 conf->dynamic_ps_timeout = timeout; 1390 conf->dynamic_ps_timeout = timeout;
1346 1391
1392 /* no change, but if automatic follow powersave */
1393 mutex_lock(&sdata->u.mgd.mtx);
1394 __ieee80211_request_smps(sdata, sdata->u.mgd.req_smps);
1395 mutex_unlock(&sdata->u.mgd.mtx);
1396
1347 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) 1397 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
1348 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 1398 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
1349 1399
@@ -1359,39 +1409,52 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
1359{ 1409{
1360 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1410 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1361 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1411 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1362 int i, err = -EINVAL; 1412 int i;
1363 u32 target_rate; 1413
1364 struct ieee80211_supported_band *sband; 1414 /*
1415 * This _could_ be supported by providing a hook for
1416 * drivers for this function, but at this point it
1417 * doesn't seem worth bothering.
1418 */
1419 if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)
1420 return -EOPNOTSUPP;
1365 1421
1366 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
1367 1422
1368 /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates 1423 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
1369 * target_rate = X, rate->fixed = 1 means only rate X 1424 sdata->rc_rateidx_mask[i] = mask->control[i].legacy;
1370 * target_rate = X, rate->fixed = 0 means all rates <= X */
1371 sdata->max_ratectrl_rateidx = -1;
1372 sdata->force_unicast_rateidx = -1;
1373 1425
1374 if (mask->fixed) 1426 return 0;
1375 target_rate = mask->fixed / 100; 1427}
1376 else if (mask->maxrate)
1377 target_rate = mask->maxrate / 100;
1378 else
1379 return 0;
1380 1428
1381 for (i=0; i< sband->n_bitrates; i++) { 1429static int ieee80211_remain_on_channel(struct wiphy *wiphy,
1382 struct ieee80211_rate *brate = &sband->bitrates[i]; 1430 struct net_device *dev,
1383 int this_rate = brate->bitrate; 1431 struct ieee80211_channel *chan,
1432 enum nl80211_channel_type channel_type,
1433 unsigned int duration,
1434 u64 *cookie)
1435{
1436 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1384 1437
1385 if (target_rate == this_rate) { 1438 return ieee80211_wk_remain_on_channel(sdata, chan, channel_type,
1386 sdata->max_ratectrl_rateidx = i; 1439 duration, cookie);
1387 if (mask->fixed) 1440}
1388 sdata->force_unicast_rateidx = i;
1389 err = 0;
1390 break;
1391 }
1392 }
1393 1441
1394 return err; 1442static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy,
1443 struct net_device *dev,
1444 u64 cookie)
1445{
1446 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1447
1448 return ieee80211_wk_cancel_remain_on_channel(sdata, cookie);
1449}
1450
1451static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev,
1452 struct ieee80211_channel *chan,
1453 enum nl80211_channel_type channel_type,
1454 const u8 *buf, size_t len, u64 *cookie)
1455{
1456 return ieee80211_mgd_action(IEEE80211_DEV_TO_SUB_IF(dev), chan,
1457 channel_type, buf, len, cookie);
1395} 1458}
1396 1459
1397struct cfg80211_ops mac80211_config_ops = { 1460struct cfg80211_ops mac80211_config_ops = {
@@ -1440,4 +1503,7 @@ struct cfg80211_ops mac80211_config_ops = {
1440 CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd) 1503 CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
1441 .set_power_mgmt = ieee80211_set_power_mgmt, 1504 .set_power_mgmt = ieee80211_set_power_mgmt,
1442 .set_bitrate_mask = ieee80211_set_bitrate_mask, 1505 .set_bitrate_mask = ieee80211_set_bitrate_mask,
1506 .remain_on_channel = ieee80211_remain_on_channel,
1507 .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,
1508 .action = ieee80211_action,
1443}; 1509};