aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/cfg.c
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2012-11-26 14:46:41 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-11-26 14:46:41 -0500
commit62c8003ecb973986958e9dade4a7e598349caf48 (patch)
tree0e831639cd6449c2955234cfc37ef46481c788d1 /net/mac80211/cfg.c
parente4cb3ff9311e0817e65cda7bc53898348aab7527 (diff)
parentec816087e8978b74c1bd5fae0e335dd97d964e9f (diff)
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r--net/mac80211/cfg.c137
1 files changed, 73 insertions, 64 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 6733b374c821..4965aa6424ec 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -370,30 +370,32 @@ static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy,
370 return 0; 370 return 0;
371} 371}
372 372
373static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, int idx)
374{
375 enum ieee80211_band band = ieee80211_get_sdata_band(sta->sdata);
376
377 if (!(rate->flags & RATE_INFO_FLAGS_MCS)) {
378 struct ieee80211_supported_band *sband;
379 sband = sta->local->hw.wiphy->bands[band];
380 rate->legacy = sband->bitrates[idx].bitrate;
381 } else
382 rate->mcs = idx;
383}
384
385void sta_set_rate_info_tx(struct sta_info *sta, 373void sta_set_rate_info_tx(struct sta_info *sta,
386 const struct ieee80211_tx_rate *rate, 374 const struct ieee80211_tx_rate *rate,
387 struct rate_info *rinfo) 375 struct rate_info *rinfo)
388{ 376{
389 rinfo->flags = 0; 377 rinfo->flags = 0;
390 if (rate->flags & IEEE80211_TX_RC_MCS) 378 if (rate->flags & IEEE80211_TX_RC_MCS) {
391 rinfo->flags |= RATE_INFO_FLAGS_MCS; 379 rinfo->flags |= RATE_INFO_FLAGS_MCS;
380 rinfo->mcs = rate->idx;
381 } else if (rate->flags & IEEE80211_TX_RC_VHT_MCS) {
382 rinfo->flags |= RATE_INFO_FLAGS_VHT_MCS;
383 rinfo->mcs = ieee80211_rate_get_vht_mcs(rate);
384 rinfo->nss = ieee80211_rate_get_vht_nss(rate);
385 } else {
386 struct ieee80211_supported_band *sband;
387 sband = sta->local->hw.wiphy->bands[
388 ieee80211_get_sdata_band(sta->sdata)];
389 rinfo->legacy = sband->bitrates[rate->idx].bitrate;
390 }
392 if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) 391 if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
393 rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; 392 rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
393 if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
394 rinfo->flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
395 if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
396 rinfo->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
394 if (rate->flags & IEEE80211_TX_RC_SHORT_GI) 397 if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
395 rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; 398 rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
396 rate_idx_to_bitrate(rinfo, sta, rate->idx);
397} 399}
398 400
399static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) 401static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
@@ -444,13 +446,32 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
444 sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate); 446 sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
445 447
446 sinfo->rxrate.flags = 0; 448 sinfo->rxrate.flags = 0;
447 if (sta->last_rx_rate_flag & RX_FLAG_HT) 449 if (sta->last_rx_rate_flag & RX_FLAG_HT) {
448 sinfo->rxrate.flags |= RATE_INFO_FLAGS_MCS; 450 sinfo->rxrate.flags |= RATE_INFO_FLAGS_MCS;
451 sinfo->rxrate.mcs = sta->last_rx_rate_idx;
452 } else if (sta->last_rx_rate_flag & RX_FLAG_VHT) {
453 sinfo->rxrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
454 sinfo->rxrate.nss = sta->last_rx_rate_vht_nss;
455 sinfo->rxrate.mcs = sta->last_rx_rate_idx;
456 } else {
457 struct ieee80211_supported_band *sband;
458
459 sband = sta->local->hw.wiphy->bands[
460 ieee80211_get_sdata_band(sta->sdata)];
461 sinfo->rxrate.legacy =
462 sband->bitrates[sta->last_rx_rate_idx].bitrate;
463 }
464
449 if (sta->last_rx_rate_flag & RX_FLAG_40MHZ) 465 if (sta->last_rx_rate_flag & RX_FLAG_40MHZ)
450 sinfo->rxrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; 466 sinfo->rxrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
451 if (sta->last_rx_rate_flag & RX_FLAG_SHORT_GI) 467 if (sta->last_rx_rate_flag & RX_FLAG_SHORT_GI)
452 sinfo->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI; 468 sinfo->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
453 rate_idx_to_bitrate(&sinfo->rxrate, sta, sta->last_rx_rate_idx); 469 if (sta->last_rx_rate_flag & RX_FLAG_80MHZ)
470 sinfo->rxrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
471 if (sta->last_rx_rate_flag & RX_FLAG_80P80MHZ)
472 sinfo->rxrate.flags |= RATE_INFO_FLAGS_80P80_MHZ_WIDTH;
473 if (sta->last_rx_rate_flag & RX_FLAG_160MHZ)
474 sinfo->rxrate.flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
454 475
455 if (ieee80211_vif_is_mesh(&sdata->vif)) { 476 if (ieee80211_vif_is_mesh(&sdata->vif)) {
456#ifdef CONFIG_MAC80211_MESH 477#ifdef CONFIG_MAC80211_MESH
@@ -615,7 +636,7 @@ do_survey:
615 rcu_read_lock(); 636 rcu_read_lock();
616 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 637 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
617 if (chanctx_conf) 638 if (chanctx_conf)
618 channel = chanctx_conf->channel; 639 channel = chanctx_conf->def.chan;
619 else 640 else
620 channel = NULL; 641 channel = NULL;
621 rcu_read_unlock(); 642 rcu_read_unlock();
@@ -735,15 +756,13 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
735} 756}
736 757
737static int ieee80211_set_monitor_channel(struct wiphy *wiphy, 758static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
738 struct ieee80211_channel *chan, 759 struct cfg80211_chan_def *chandef)
739 enum nl80211_channel_type channel_type)
740{ 760{
741 struct ieee80211_local *local = wiphy_priv(wiphy); 761 struct ieee80211_local *local = wiphy_priv(wiphy);
742 struct ieee80211_sub_if_data *sdata; 762 struct ieee80211_sub_if_data *sdata;
743 int ret = 0; 763 int ret = 0;
744 764
745 if (local->monitor_channel == chan && 765 if (cfg80211_chandef_identical(&local->monitor_chandef, chandef))
746 local->monitor_channel_type == channel_type)
747 return 0; 766 return 0;
748 767
749 mutex_lock(&local->iflist_mtx); 768 mutex_lock(&local->iflist_mtx);
@@ -753,20 +772,17 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
753 lockdep_is_held(&local->iflist_mtx)); 772 lockdep_is_held(&local->iflist_mtx));
754 if (sdata) { 773 if (sdata) {
755 ieee80211_vif_release_channel(sdata); 774 ieee80211_vif_release_channel(sdata);
756 ret = ieee80211_vif_use_channel( 775 ret = ieee80211_vif_use_channel(sdata, chandef,
757 sdata, chan, channel_type,
758 IEEE80211_CHANCTX_EXCLUSIVE); 776 IEEE80211_CHANCTX_EXCLUSIVE);
759 } 777 }
760 } else if (local->open_count == local->monitors) { 778 } else if (local->open_count == local->monitors) {
761 local->_oper_channel = chan; 779 local->_oper_channel = chandef->chan;
762 local->_oper_channel_type = channel_type; 780 local->_oper_channel_type = cfg80211_get_chandef_type(chandef);
763 ieee80211_hw_config(local, 0); 781 ieee80211_hw_config(local, 0);
764 } 782 }
765 783
766 if (ret == 0) { 784 if (ret == 0)
767 local->monitor_channel = chan; 785 local->monitor_chandef = *chandef;
768 local->monitor_channel_type = channel_type;
769 }
770 mutex_unlock(&local->iflist_mtx); 786 mutex_unlock(&local->iflist_mtx);
771 787
772 return ret; 788 return ret;
@@ -888,8 +904,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
888 sdata->smps_mode = IEEE80211_SMPS_OFF; 904 sdata->smps_mode = IEEE80211_SMPS_OFF;
889 sdata->needed_rx_chains = sdata->local->rx_chains; 905 sdata->needed_rx_chains = sdata->local->rx_chains;
890 906
891 err = ieee80211_vif_use_channel(sdata, params->channel, 907 err = ieee80211_vif_use_channel(sdata, &params->chandef,
892 params->channel_type,
893 IEEE80211_CHANCTX_SHARED); 908 IEEE80211_CHANCTX_SHARED);
894 if (err) 909 if (err)
895 return err; 910 return err;
@@ -1707,8 +1722,7 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev,
1707 sdata->smps_mode = IEEE80211_SMPS_OFF; 1722 sdata->smps_mode = IEEE80211_SMPS_OFF;
1708 sdata->needed_rx_chains = sdata->local->rx_chains; 1723 sdata->needed_rx_chains = sdata->local->rx_chains;
1709 1724
1710 err = ieee80211_vif_use_channel(sdata, setup->channel, 1725 err = ieee80211_vif_use_channel(sdata, &setup->chandef,
1711 setup->channel_type,
1712 IEEE80211_CHANCTX_SHARED); 1726 IEEE80211_CHANCTX_SHARED);
1713 if (err) 1727 if (err)
1714 return err; 1728 return err;
@@ -1990,10 +2004,16 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1990 return err; 2004 return err;
1991 } 2005 }
1992 2006
1993 if (changed & WIPHY_PARAM_RETRY_SHORT) 2007 if (changed & WIPHY_PARAM_RETRY_SHORT) {
2008 if (wiphy->retry_short > IEEE80211_MAX_TX_RETRY)
2009 return -EINVAL;
1994 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; 2010 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
1995 if (changed & WIPHY_PARAM_RETRY_LONG) 2011 }
2012 if (changed & WIPHY_PARAM_RETRY_LONG) {
2013 if (wiphy->retry_long > IEEE80211_MAX_TX_RETRY)
2014 return -EINVAL;
1996 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; 2015 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
2016 }
1997 if (changed & 2017 if (changed &
1998 (WIPHY_PARAM_RETRY_SHORT | WIPHY_PARAM_RETRY_LONG)) 2018 (WIPHY_PARAM_RETRY_SHORT | WIPHY_PARAM_RETRY_LONG))
1999 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS); 2019 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS);
@@ -2129,7 +2149,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
2129 * the new value until we associate. 2149 * the new value until we associate.
2130 */ 2150 */
2131 if (!sdata->u.mgd.associated || 2151 if (!sdata->u.mgd.associated ||
2132 sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) 2152 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
2133 return 0; 2153 return 0;
2134 2154
2135 ap = sdata->u.mgd.associated->bssid; 2155 ap = sdata->u.mgd.associated->bssid;
@@ -2236,7 +2256,6 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
2236static int ieee80211_start_roc_work(struct ieee80211_local *local, 2256static int ieee80211_start_roc_work(struct ieee80211_local *local,
2237 struct ieee80211_sub_if_data *sdata, 2257 struct ieee80211_sub_if_data *sdata,
2238 struct ieee80211_channel *channel, 2258 struct ieee80211_channel *channel,
2239 enum nl80211_channel_type channel_type,
2240 unsigned int duration, u64 *cookie, 2259 unsigned int duration, u64 *cookie,
2241 struct sk_buff *txskb) 2260 struct sk_buff *txskb)
2242{ 2261{
@@ -2254,7 +2273,6 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2254 return -ENOMEM; 2273 return -ENOMEM;
2255 2274
2256 roc->chan = channel; 2275 roc->chan = channel;
2257 roc->chan_type = channel_type;
2258 roc->duration = duration; 2276 roc->duration = duration;
2259 roc->req_duration = duration; 2277 roc->req_duration = duration;
2260 roc->frame = txskb; 2278 roc->frame = txskb;
@@ -2287,8 +2305,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2287 if (!duration) 2305 if (!duration)
2288 duration = 10; 2306 duration = 10;
2289 2307
2290 ret = drv_remain_on_channel(local, sdata, channel, channel_type, 2308 ret = drv_remain_on_channel(local, sdata, channel, duration);
2291 duration);
2292 if (ret) { 2309 if (ret) {
2293 kfree(roc); 2310 kfree(roc);
2294 return ret; 2311 return ret;
@@ -2299,8 +2316,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2299 2316
2300 out_check_combine: 2317 out_check_combine:
2301 list_for_each_entry(tmp, &local->roc_list, list) { 2318 list_for_each_entry(tmp, &local->roc_list, list) {
2302 if (tmp->chan != channel || tmp->chan_type != channel_type || 2319 if (tmp->chan != channel || tmp->sdata != sdata)
2303 tmp->sdata != sdata)
2304 continue; 2320 continue;
2305 2321
2306 /* 2322 /*
@@ -2417,7 +2433,6 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2417static int ieee80211_remain_on_channel(struct wiphy *wiphy, 2433static int ieee80211_remain_on_channel(struct wiphy *wiphy,
2418 struct wireless_dev *wdev, 2434 struct wireless_dev *wdev,
2419 struct ieee80211_channel *chan, 2435 struct ieee80211_channel *chan,
2420 enum nl80211_channel_type channel_type,
2421 unsigned int duration, 2436 unsigned int duration,
2422 u64 *cookie) 2437 u64 *cookie)
2423{ 2438{
@@ -2426,7 +2441,7 @@ static int ieee80211_remain_on_channel(struct wiphy *wiphy,
2426 int ret; 2441 int ret;
2427 2442
2428 mutex_lock(&local->mtx); 2443 mutex_lock(&local->mtx);
2429 ret = ieee80211_start_roc_work(local, sdata, chan, channel_type, 2444 ret = ieee80211_start_roc_work(local, sdata, chan,
2430 duration, cookie, NULL); 2445 duration, cookie, NULL);
2431 mutex_unlock(&local->mtx); 2446 mutex_unlock(&local->mtx);
2432 2447
@@ -2519,10 +2534,8 @@ static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy,
2519 2534
2520static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 2535static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
2521 struct ieee80211_channel *chan, bool offchan, 2536 struct ieee80211_channel *chan, bool offchan,
2522 enum nl80211_channel_type channel_type, 2537 unsigned int wait, const u8 *buf, size_t len,
2523 bool channel_type_valid, unsigned int wait, 2538 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
2524 const u8 *buf, size_t len, bool no_cck,
2525 bool dont_wait_for_ack, u64 *cookie)
2526{ 2539{
2527 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); 2540 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
2528 struct ieee80211_local *local = sdata->local; 2541 struct ieee80211_local *local = sdata->local;
@@ -2591,14 +2604,10 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
2591 rcu_read_lock(); 2604 rcu_read_lock();
2592 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 2605 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
2593 2606
2594 if (chanctx_conf) { 2607 if (chanctx_conf)
2595 need_offchan = chan != chanctx_conf->channel; 2608 need_offchan = chan != chanctx_conf->def.chan;
2596 if (channel_type_valid && 2609 else
2597 channel_type != chanctx_conf->channel_type)
2598 need_offchan = true;
2599 } else {
2600 need_offchan = true; 2610 need_offchan = true;
2601 }
2602 rcu_read_unlock(); 2611 rcu_read_unlock();
2603 } 2612 }
2604 2613
@@ -2633,7 +2642,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
2633 local->hw.offchannel_tx_hw_queue; 2642 local->hw.offchannel_tx_hw_queue;
2634 2643
2635 /* This will handle all kinds of coalescing and immediate TX */ 2644 /* This will handle all kinds of coalescing and immediate TX */
2636 ret = ieee80211_start_roc_work(local, sdata, chan, channel_type, 2645 ret = ieee80211_start_roc_work(local, sdata, chan,
2637 wait, cookie, skb); 2646 wait, cookie, skb);
2638 if (ret) 2647 if (ret)
2639 kfree_skb(skb); 2648 kfree_skb(skb);
@@ -3067,7 +3076,7 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
3067 rcu_read_unlock(); 3076 rcu_read_unlock();
3068 return -EINVAL; 3077 return -EINVAL;
3069 } 3078 }
3070 band = chanctx_conf->channel->band; 3079 band = chanctx_conf->def.chan->band;
3071 sta = sta_info_get(sdata, peer); 3080 sta = sta_info_get(sdata, peer);
3072 if (sta) { 3081 if (sta) {
3073 qos = test_sta_flag(sta, WLAN_STA_WME); 3082 qos = test_sta_flag(sta, WLAN_STA_WME);
@@ -3124,23 +3133,23 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
3124 return 0; 3133 return 0;
3125} 3134}
3126 3135
3127static struct ieee80211_channel * 3136static int ieee80211_cfg_get_channel(struct wiphy *wiphy,
3128ieee80211_cfg_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev, 3137 struct wireless_dev *wdev,
3129 enum nl80211_channel_type *type) 3138 struct cfg80211_chan_def *chandef)
3130{ 3139{
3131 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); 3140 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
3132 struct ieee80211_chanctx_conf *chanctx_conf; 3141 struct ieee80211_chanctx_conf *chanctx_conf;
3133 struct ieee80211_channel *chan = NULL; 3142 int ret = -ENODATA;
3134 3143
3135 rcu_read_lock(); 3144 rcu_read_lock();
3136 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 3145 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
3137 if (chanctx_conf) { 3146 if (chanctx_conf) {
3138 *type = chanctx_conf->channel_type; 3147 *chandef = chanctx_conf->def;
3139 chan = chanctx_conf->channel; 3148 ret = 0;
3140 } 3149 }
3141 rcu_read_unlock(); 3150 rcu_read_unlock();
3142 3151
3143 return chan; 3152 return ret;
3144} 3153}
3145 3154
3146#ifdef CONFIG_PM 3155#ifdef CONFIG_PM