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.c163
1 files changed, 116 insertions, 47 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 9ae1a4760b58..facf233843e0 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -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);
@@ -732,7 +728,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
732 } else 728 } else
733 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 729 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
734 730
735 if (compare_ether_addr(mac, dev->dev_addr) == 0) 731 if (compare_ether_addr(mac, sdata->vif.addr) == 0)
736 return -EINVAL; 732 return -EINVAL;
737 733
738 if (is_multicast_ether_addr(mac)) 734 if (is_multicast_ether_addr(mac))
@@ -779,8 +775,7 @@ static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
779 if (mac) { 775 if (mac) {
780 rcu_read_lock(); 776 rcu_read_lock();
781 777
782 /* XXX: get sta belonging to dev */ 778 sta = sta_info_get_bss(sdata, mac);
783 sta = sta_info_get(local, mac);
784 if (!sta) { 779 if (!sta) {
785 rcu_read_unlock(); 780 rcu_read_unlock();
786 return -ENOENT; 781 return -ENOENT;
@@ -801,14 +796,14 @@ static int ieee80211_change_station(struct wiphy *wiphy,
801 u8 *mac, 796 u8 *mac,
802 struct station_parameters *params) 797 struct station_parameters *params)
803{ 798{
799 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
804 struct ieee80211_local *local = wiphy_priv(wiphy); 800 struct ieee80211_local *local = wiphy_priv(wiphy);
805 struct sta_info *sta; 801 struct sta_info *sta;
806 struct ieee80211_sub_if_data *vlansdata; 802 struct ieee80211_sub_if_data *vlansdata;
807 803
808 rcu_read_lock(); 804 rcu_read_lock();
809 805
810 /* XXX: get sta belonging to dev */ 806 sta = sta_info_get_bss(sdata, mac);
811 sta = sta_info_get(local, mac);
812 if (!sta) { 807 if (!sta) {
813 rcu_read_unlock(); 808 rcu_read_unlock();
814 return -ENOENT; 809 return -ENOENT;
@@ -847,7 +842,6 @@ static int ieee80211_change_station(struct wiphy *wiphy,
847static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev, 842static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
848 u8 *dst, u8 *next_hop) 843 u8 *dst, u8 *next_hop)
849{ 844{
850 struct ieee80211_local *local = wiphy_priv(wiphy);
851 struct ieee80211_sub_if_data *sdata; 845 struct ieee80211_sub_if_data *sdata;
852 struct mesh_path *mpath; 846 struct mesh_path *mpath;
853 struct sta_info *sta; 847 struct sta_info *sta;
@@ -856,7 +850,7 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
856 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 850 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
857 851
858 rcu_read_lock(); 852 rcu_read_lock();
859 sta = sta_info_get(local, next_hop); 853 sta = sta_info_get(sdata, next_hop);
860 if (!sta) { 854 if (!sta) {
861 rcu_read_unlock(); 855 rcu_read_unlock();
862 return -ENOENT; 856 return -ENOENT;
@@ -895,7 +889,6 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
895 struct net_device *dev, 889 struct net_device *dev,
896 u8 *dst, u8 *next_hop) 890 u8 *dst, u8 *next_hop)
897{ 891{
898 struct ieee80211_local *local = wiphy_priv(wiphy);
899 struct ieee80211_sub_if_data *sdata; 892 struct ieee80211_sub_if_data *sdata;
900 struct mesh_path *mpath; 893 struct mesh_path *mpath;
901 struct sta_info *sta; 894 struct sta_info *sta;
@@ -904,7 +897,7 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
904 897
905 rcu_read_lock(); 898 rcu_read_lock();
906 899
907 sta = sta_info_get(local, next_hop); 900 sta = sta_info_get(sdata, next_hop);
908 if (!sta) { 901 if (!sta) {
909 rcu_read_unlock(); 902 rcu_read_unlock();
910 return -ENOENT; 903 return -ENOENT;
@@ -1092,6 +1085,13 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
1092 params->use_short_preamble; 1085 params->use_short_preamble;
1093 changed |= BSS_CHANGED_ERP_PREAMBLE; 1086 changed |= BSS_CHANGED_ERP_PREAMBLE;
1094 } 1087 }
1088
1089 if (!sdata->vif.bss_conf.use_short_slot &&
1090 sdata->local->hw.conf.channel->band == IEEE80211_BAND_5GHZ) {
1091 sdata->vif.bss_conf.use_short_slot = true;
1092 changed |= BSS_CHANGED_ERP_SLOT;
1093 }
1094
1095 if (params->use_short_slot_time >= 0) { 1095 if (params->use_short_slot_time >= 0) {
1096 sdata->vif.bss_conf.use_short_slot = 1096 sdata->vif.bss_conf.use_short_slot =
1097 params->use_short_slot_time; 1097 params->use_short_slot_time;
@@ -1135,6 +1135,13 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
1135 p.cw_max = params->cwmax; 1135 p.cw_max = params->cwmax;
1136 p.cw_min = params->cwmin; 1136 p.cw_min = params->cwmin;
1137 p.txop = params->txop; 1137 p.txop = params->txop;
1138
1139 /*
1140 * Setting tx queue params disables u-apsd because it's only
1141 * called in master mode.
1142 */
1143 p.uapsd = false;
1144
1138 if (drv_conf_tx(local, params->queue, &p)) { 1145 if (drv_conf_tx(local, params->queue, &p)) {
1139 printk(KERN_DEBUG "%s: failed to set TX queue " 1146 printk(KERN_DEBUG "%s: failed to set TX queue "
1140 "parameters for queue %d\n", 1147 "parameters for queue %d\n",
@@ -1237,6 +1244,13 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1237 struct ieee80211_local *local = wiphy_priv(wiphy); 1244 struct ieee80211_local *local = wiphy_priv(wiphy);
1238 int err; 1245 int err;
1239 1246
1247 if (changed & WIPHY_PARAM_COVERAGE_CLASS) {
1248 err = drv_set_coverage_class(local, wiphy->coverage_class);
1249
1250 if (err)
1251 return err;
1252 }
1253
1240 if (changed & WIPHY_PARAM_RTS_THRESHOLD) { 1254 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1241 err = drv_set_rts_threshold(local, wiphy->rts_threshold); 1255 err = drv_set_rts_threshold(local, wiphy->rts_threshold);
1242 1256
@@ -1324,6 +1338,50 @@ static int ieee80211_testmode_cmd(struct wiphy *wiphy, void *data, int len)
1324} 1338}
1325#endif 1339#endif
1326 1340
1341int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
1342 enum ieee80211_smps_mode smps_mode)
1343{
1344 const u8 *ap;
1345 enum ieee80211_smps_mode old_req;
1346 int err;
1347
1348 old_req = sdata->u.mgd.req_smps;
1349 sdata->u.mgd.req_smps = smps_mode;
1350
1351 if (old_req == smps_mode &&
1352 smps_mode != IEEE80211_SMPS_AUTOMATIC)
1353 return 0;
1354
1355 /*
1356 * If not associated, or current association is not an HT
1357 * association, there's no need to send an action frame.
1358 */
1359 if (!sdata->u.mgd.associated ||
1360 sdata->local->oper_channel_type == NL80211_CHAN_NO_HT) {
1361 mutex_lock(&sdata->local->iflist_mtx);
1362 ieee80211_recalc_smps(sdata->local, sdata);
1363 mutex_unlock(&sdata->local->iflist_mtx);
1364 return 0;
1365 }
1366
1367 ap = sdata->u.mgd.associated->bssid;
1368
1369 if (smps_mode == IEEE80211_SMPS_AUTOMATIC) {
1370 if (sdata->u.mgd.powersave)
1371 smps_mode = IEEE80211_SMPS_DYNAMIC;
1372 else
1373 smps_mode = IEEE80211_SMPS_OFF;
1374 }
1375
1376 /* send SM PS frame to AP */
1377 err = ieee80211_send_smps_action(sdata, smps_mode,
1378 ap, ap);
1379 if (err)
1380 sdata->u.mgd.req_smps = old_req;
1381
1382 return err;
1383}
1384
1327static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, 1385static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1328 bool enabled, int timeout) 1386 bool enabled, int timeout)
1329{ 1387{
@@ -1344,6 +1402,11 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1344 sdata->u.mgd.powersave = enabled; 1402 sdata->u.mgd.powersave = enabled;
1345 conf->dynamic_ps_timeout = timeout; 1403 conf->dynamic_ps_timeout = timeout;
1346 1404
1405 /* no change, but if automatic follow powersave */
1406 mutex_lock(&sdata->u.mgd.mtx);
1407 __ieee80211_request_smps(sdata, sdata->u.mgd.req_smps);
1408 mutex_unlock(&sdata->u.mgd.mtx);
1409
1347 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) 1410 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
1348 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 1411 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
1349 1412
@@ -1359,39 +1422,43 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
1359{ 1422{
1360 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1423 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1361 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1424 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1362 int i, err = -EINVAL; 1425 int i;
1363 u32 target_rate;
1364 struct ieee80211_supported_band *sband;
1365 1426
1366 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 1427 /*
1428 * This _could_ be supported by providing a hook for
1429 * drivers for this function, but at this point it
1430 * doesn't seem worth bothering.
1431 */
1432 if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)
1433 return -EOPNOTSUPP;
1367 1434
1368 /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates
1369 * target_rate = X, rate->fixed = 1 means only rate X
1370 * target_rate = X, rate->fixed = 0 means all rates <= X */
1371 sdata->max_ratectrl_rateidx = -1;
1372 sdata->force_unicast_rateidx = -1;
1373 1435
1374 if (mask->fixed) 1436 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
1375 target_rate = mask->fixed / 100; 1437 sdata->rc_rateidx_mask[i] = mask->control[i].legacy;
1376 else if (mask->maxrate)
1377 target_rate = mask->maxrate / 100;
1378 else
1379 return 0;
1380 1438
1381 for (i=0; i< sband->n_bitrates; i++) { 1439 return 0;
1382 struct ieee80211_rate *brate = &sband->bitrates[i]; 1440}
1383 int this_rate = brate->bitrate;
1384 1441
1385 if (target_rate == this_rate) { 1442static int ieee80211_remain_on_channel(struct wiphy *wiphy,
1386 sdata->max_ratectrl_rateidx = i; 1443 struct net_device *dev,
1387 if (mask->fixed) 1444 struct ieee80211_channel *chan,
1388 sdata->force_unicast_rateidx = i; 1445 enum nl80211_channel_type channel_type,
1389 err = 0; 1446 unsigned int duration,
1390 break; 1447 u64 *cookie)
1391 } 1448{
1392 } 1449 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1393 1450
1394 return err; 1451 return ieee80211_wk_remain_on_channel(sdata, chan, channel_type,
1452 duration, cookie);
1453}
1454
1455static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy,
1456 struct net_device *dev,
1457 u64 cookie)
1458{
1459 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1460
1461 return ieee80211_wk_cancel_remain_on_channel(sdata, cookie);
1395} 1462}
1396 1463
1397struct cfg80211_ops mac80211_config_ops = { 1464struct cfg80211_ops mac80211_config_ops = {
@@ -1440,4 +1507,6 @@ struct cfg80211_ops mac80211_config_ops = {
1440 CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd) 1507 CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
1441 .set_power_mgmt = ieee80211_set_power_mgmt, 1508 .set_power_mgmt = ieee80211_set_power_mgmt,
1442 .set_bitrate_mask = ieee80211_set_bitrate_mask, 1509 .set_bitrate_mask = ieee80211_set_bitrate_mask,
1510 .remain_on_channel = ieee80211_remain_on_channel,
1511 .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,
1443}; 1512};