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.c112
1 files changed, 82 insertions, 30 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 6dc3579c0ac5..63843e3e576a 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -150,7 +150,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
150 rcu_read_lock(); 150 rcu_read_lock();
151 151
152 if (mac_addr) { 152 if (mac_addr) {
153 sta = sta_info_get(sdata->local, mac_addr); 153 sta = sta_info_get(sdata, mac_addr);
154 if (!sta) { 154 if (!sta) {
155 ieee80211_key_free(key); 155 ieee80211_key_free(key);
156 err = -ENOENT; 156 err = -ENOENT;
@@ -181,7 +181,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
181 if (mac_addr) { 181 if (mac_addr) {
182 ret = -ENOENT; 182 ret = -ENOENT;
183 183
184 sta = sta_info_get(sdata->local, mac_addr); 184 sta = sta_info_get(sdata, mac_addr);
185 if (!sta) 185 if (!sta)
186 goto out_unlock; 186 goto out_unlock;
187 187
@@ -228,7 +228,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
228 rcu_read_lock(); 228 rcu_read_lock();
229 229
230 if (mac_addr) { 230 if (mac_addr) {
231 sta = sta_info_get(sdata->local, mac_addr); 231 sta = sta_info_get(sdata, mac_addr);
232 if (!sta) 232 if (!sta)
233 goto out; 233 goto out;
234 234
@@ -415,15 +415,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, 415static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
416 u8 *mac, struct station_info *sinfo) 416 u8 *mac, struct station_info *sinfo)
417{ 417{
418 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 418 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
419 struct sta_info *sta; 419 struct sta_info *sta;
420 int ret = -ENOENT; 420 int ret = -ENOENT;
421 421
422 rcu_read_lock(); 422 rcu_read_lock();
423 423
424 /* XXX: verify sta->dev == dev */ 424 sta = sta_info_get(sdata, mac);
425
426 sta = sta_info_get(local, mac);
427 if (sta) { 425 if (sta) {
428 ret = 0; 426 ret = 0;
429 sta_set_sinfo(sta, sinfo); 427 sta_set_sinfo(sta, sinfo);
@@ -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))
@@ -779,8 +777,7 @@ static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
779 if (mac) { 777 if (mac) {
780 rcu_read_lock(); 778 rcu_read_lock();
781 779
782 /* XXX: get sta belonging to dev */ 780 sta = sta_info_get(sdata, mac);
783 sta = sta_info_get(local, mac);
784 if (!sta) { 781 if (!sta) {
785 rcu_read_unlock(); 782 rcu_read_unlock();
786 return -ENOENT; 783 return -ENOENT;
@@ -801,14 +798,14 @@ static int ieee80211_change_station(struct wiphy *wiphy,
801 u8 *mac, 798 u8 *mac,
802 struct station_parameters *params) 799 struct station_parameters *params)
803{ 800{
801 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
804 struct ieee80211_local *local = wiphy_priv(wiphy); 802 struct ieee80211_local *local = wiphy_priv(wiphy);
805 struct sta_info *sta; 803 struct sta_info *sta;
806 struct ieee80211_sub_if_data *vlansdata; 804 struct ieee80211_sub_if_data *vlansdata;
807 805
808 rcu_read_lock(); 806 rcu_read_lock();
809 807
810 /* XXX: get sta belonging to dev */ 808 sta = sta_info_get(sdata, mac);
811 sta = sta_info_get(local, mac);
812 if (!sta) { 809 if (!sta) {
813 rcu_read_unlock(); 810 rcu_read_unlock();
814 return -ENOENT; 811 return -ENOENT;
@@ -847,7 +844,6 @@ static int ieee80211_change_station(struct wiphy *wiphy,
847static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev, 844static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
848 u8 *dst, u8 *next_hop) 845 u8 *dst, u8 *next_hop)
849{ 846{
850 struct ieee80211_local *local = wiphy_priv(wiphy);
851 struct ieee80211_sub_if_data *sdata; 847 struct ieee80211_sub_if_data *sdata;
852 struct mesh_path *mpath; 848 struct mesh_path *mpath;
853 struct sta_info *sta; 849 struct sta_info *sta;
@@ -856,7 +852,7 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
856 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 852 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
857 853
858 rcu_read_lock(); 854 rcu_read_lock();
859 sta = sta_info_get(local, next_hop); 855 sta = sta_info_get(sdata, next_hop);
860 if (!sta) { 856 if (!sta) {
861 rcu_read_unlock(); 857 rcu_read_unlock();
862 return -ENOENT; 858 return -ENOENT;
@@ -895,7 +891,6 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
895 struct net_device *dev, 891 struct net_device *dev,
896 u8 *dst, u8 *next_hop) 892 u8 *dst, u8 *next_hop)
897{ 893{
898 struct ieee80211_local *local = wiphy_priv(wiphy);
899 struct ieee80211_sub_if_data *sdata; 894 struct ieee80211_sub_if_data *sdata;
900 struct mesh_path *mpath; 895 struct mesh_path *mpath;
901 struct sta_info *sta; 896 struct sta_info *sta;
@@ -904,7 +899,7 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
904 899
905 rcu_read_lock(); 900 rcu_read_lock();
906 901
907 sta = sta_info_get(local, next_hop); 902 sta = sta_info_get(sdata, next_hop);
908 if (!sta) { 903 if (!sta) {
909 rcu_read_unlock(); 904 rcu_read_unlock();
910 return -ENOENT; 905 return -ENOENT;
@@ -1324,6 +1319,50 @@ static int ieee80211_testmode_cmd(struct wiphy *wiphy, void *data, int len)
1324} 1319}
1325#endif 1320#endif
1326 1321
1322int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
1323 enum ieee80211_smps_mode smps_mode)
1324{
1325 const u8 *ap;
1326 enum ieee80211_smps_mode old_req;
1327 int err;
1328
1329 old_req = sdata->u.mgd.req_smps;
1330 sdata->u.mgd.req_smps = smps_mode;
1331
1332 if (old_req == smps_mode &&
1333 smps_mode != IEEE80211_SMPS_AUTOMATIC)
1334 return 0;
1335
1336 /*
1337 * If not associated, or current association is not an HT
1338 * association, there's no need to send an action frame.
1339 */
1340 if (!sdata->u.mgd.associated ||
1341 sdata->local->oper_channel_type == NL80211_CHAN_NO_HT) {
1342 mutex_lock(&sdata->local->iflist_mtx);
1343 ieee80211_recalc_smps(sdata->local, sdata);
1344 mutex_unlock(&sdata->local->iflist_mtx);
1345 return 0;
1346 }
1347
1348 ap = sdata->u.mgd.associated->cbss.bssid;
1349
1350 if (smps_mode == IEEE80211_SMPS_AUTOMATIC) {
1351 if (sdata->u.mgd.powersave)
1352 smps_mode = IEEE80211_SMPS_DYNAMIC;
1353 else
1354 smps_mode = IEEE80211_SMPS_OFF;
1355 }
1356
1357 /* send SM PS frame to AP */
1358 err = ieee80211_send_smps_action(sdata, smps_mode,
1359 ap, ap);
1360 if (err)
1361 sdata->u.mgd.req_smps = old_req;
1362
1363 return err;
1364}
1365
1327static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, 1366static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1328 bool enabled, int timeout) 1367 bool enabled, int timeout)
1329{ 1368{
@@ -1341,6 +1380,11 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1341 sdata->u.mgd.powersave = enabled; 1380 sdata->u.mgd.powersave = enabled;
1342 conf->dynamic_ps_timeout = timeout; 1381 conf->dynamic_ps_timeout = timeout;
1343 1382
1383 /* no change, but if automatic follow powersave */
1384 mutex_lock(&sdata->u.mgd.mtx);
1385 __ieee80211_request_smps(sdata, sdata->u.mgd.req_smps);
1386 mutex_unlock(&sdata->u.mgd.mtx);
1387
1344 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) 1388 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
1345 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 1389 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
1346 1390
@@ -1356,15 +1400,25 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
1356{ 1400{
1357 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1401 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1358 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1402 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1359 int i, err = -EINVAL; 1403 int i;
1360 u32 target_rate; 1404 u32 target_rate;
1361 struct ieee80211_supported_band *sband; 1405 struct ieee80211_supported_band *sband;
1362 1406
1407 /*
1408 * This _could_ be supported by providing a hook for
1409 * drivers for this function, but at this point it
1410 * doesn't seem worth bothering.
1411 */
1412 if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)
1413 return -EOPNOTSUPP;
1414
1363 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 1415 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
1364 1416
1365 /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates 1417 /*
1418 * target_rate = -1, rate->fixed = 0 means auto only, so use all rates
1366 * target_rate = X, rate->fixed = 1 means only rate X 1419 * target_rate = X, rate->fixed = 1 means only rate X
1367 * target_rate = X, rate->fixed = 0 means all rates <= X */ 1420 * target_rate = X, rate->fixed = 0 means all rates <= X
1421 */
1368 sdata->max_ratectrl_rateidx = -1; 1422 sdata->max_ratectrl_rateidx = -1;
1369 sdata->force_unicast_rateidx = -1; 1423 sdata->force_unicast_rateidx = -1;
1370 1424
@@ -1375,20 +1429,18 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
1375 else 1429 else
1376 return 0; 1430 return 0;
1377 1431
1378 for (i=0; i< sband->n_bitrates; i++) { 1432 for (i = 0; i< sband->n_bitrates; i++) {
1379 struct ieee80211_rate *brate = &sband->bitrates[i]; 1433 if (target_rate != sband->bitrates[i].bitrate)
1380 int this_rate = brate->bitrate; 1434 continue;
1381 1435
1382 if (target_rate == this_rate) { 1436 /* requested bitrate found */
1383 sdata->max_ratectrl_rateidx = i; 1437 sdata->max_ratectrl_rateidx = i;
1384 if (mask->fixed) 1438 if (mask->fixed)
1385 sdata->force_unicast_rateidx = i; 1439 sdata->force_unicast_rateidx = i;
1386 err = 0; 1440 return 0;
1387 break;
1388 }
1389 } 1441 }
1390 1442
1391 return err; 1443 return -EINVAL;
1392} 1444}
1393 1445
1394struct cfg80211_ops mac80211_config_ops = { 1446struct cfg80211_ops mac80211_config_ops = {