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.c118
1 files changed, 105 insertions, 13 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 4bc8a9250cfd..334213571ad0 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -316,6 +316,17 @@ static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy,
316 return 0; 316 return 0;
317} 317}
318 318
319static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, int idx)
320{
321 if (!(rate->flags & RATE_INFO_FLAGS_MCS)) {
322 struct ieee80211_supported_band *sband;
323 sband = sta->local->hw.wiphy->bands[
324 sta->local->hw.conf.channel->band];
325 rate->legacy = sband->bitrates[idx].bitrate;
326 } else
327 rate->mcs = idx;
328}
329
319static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) 330static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
320{ 331{
321 struct ieee80211_sub_if_data *sdata = sta->sdata; 332 struct ieee80211_sub_if_data *sdata = sta->sdata;
@@ -330,6 +341,7 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
330 STATION_INFO_TX_RETRIES | 341 STATION_INFO_TX_RETRIES |
331 STATION_INFO_TX_FAILED | 342 STATION_INFO_TX_FAILED |
332 STATION_INFO_TX_BITRATE | 343 STATION_INFO_TX_BITRATE |
344 STATION_INFO_RX_BITRATE |
333 STATION_INFO_RX_DROP_MISC; 345 STATION_INFO_RX_DROP_MISC;
334 346
335 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); 347 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
@@ -355,15 +367,16 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
355 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; 367 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
356 if (sta->last_tx_rate.flags & IEEE80211_TX_RC_SHORT_GI) 368 if (sta->last_tx_rate.flags & IEEE80211_TX_RC_SHORT_GI)
357 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; 369 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
370 rate_idx_to_bitrate(&sinfo->txrate, sta, sta->last_tx_rate.idx);
358 371
359 if (!(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) { 372 sinfo->rxrate.flags = 0;
360 struct ieee80211_supported_band *sband; 373 if (sta->last_rx_rate_flag & RX_FLAG_HT)
361 sband = sta->local->hw.wiphy->bands[ 374 sinfo->rxrate.flags |= RATE_INFO_FLAGS_MCS;
362 sta->local->hw.conf.channel->band]; 375 if (sta->last_rx_rate_flag & RX_FLAG_40MHZ)
363 sinfo->txrate.legacy = 376 sinfo->rxrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
364 sband->bitrates[sta->last_tx_rate.idx].bitrate; 377 if (sta->last_rx_rate_flag & RX_FLAG_SHORT_GI)
365 } else 378 sinfo->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
366 sinfo->txrate.mcs = sta->last_tx_rate.idx; 379 rate_idx_to_bitrate(&sinfo->rxrate, sta, sta->last_rx_rate_idx);
367 380
368 if (ieee80211_vif_is_mesh(&sdata->vif)) { 381 if (ieee80211_vif_is_mesh(&sdata->vif)) {
369#ifdef CONFIG_MAC80211_MESH 382#ifdef CONFIG_MAC80211_MESH
@@ -821,6 +834,10 @@ static int ieee80211_change_station(struct wiphy *wiphy,
821 834
822 rcu_read_unlock(); 835 rcu_read_unlock();
823 836
837 if (sdata->vif.type == NL80211_IFTYPE_STATION &&
838 params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED))
839 ieee80211_recalc_ps(local, -1);
840
824 return 0; 841 return 0;
825} 842}
826 843
@@ -1215,6 +1232,9 @@ static int ieee80211_set_channel(struct wiphy *wiphy,
1215{ 1232{
1216 struct ieee80211_local *local = wiphy_priv(wiphy); 1233 struct ieee80211_local *local = wiphy_priv(wiphy);
1217 struct ieee80211_sub_if_data *sdata = NULL; 1234 struct ieee80211_sub_if_data *sdata = NULL;
1235 struct ieee80211_channel *old_oper;
1236 enum nl80211_channel_type old_oper_type;
1237 enum nl80211_channel_type old_vif_oper_type= NL80211_CHAN_NO_HT;
1218 1238
1219 if (netdev) 1239 if (netdev)
1220 sdata = IEEE80211_DEV_TO_SUB_IF(netdev); 1240 sdata = IEEE80211_DEV_TO_SUB_IF(netdev);
@@ -1232,13 +1252,23 @@ static int ieee80211_set_channel(struct wiphy *wiphy,
1232 break; 1252 break;
1233 } 1253 }
1234 1254
1235 local->oper_channel = chan; 1255 if (sdata)
1256 old_vif_oper_type = sdata->vif.bss_conf.channel_type;
1257 old_oper_type = local->_oper_channel_type;
1236 1258
1237 if (!ieee80211_set_channel_type(local, sdata, channel_type)) 1259 if (!ieee80211_set_channel_type(local, sdata, channel_type))
1238 return -EBUSY; 1260 return -EBUSY;
1239 1261
1240 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 1262 old_oper = local->oper_channel;
1241 if (sdata && sdata->vif.type != NL80211_IFTYPE_MONITOR) 1263 local->oper_channel = chan;
1264
1265 /* Update driver if changes were actually made. */
1266 if ((old_oper != local->oper_channel) ||
1267 (old_oper_type != local->_oper_channel_type))
1268 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
1269
1270 if ((sdata && sdata->vif.type != NL80211_IFTYPE_MONITOR) &&
1271 old_vif_oper_type != sdata->vif.bss_conf.channel_type)
1242 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT); 1272 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT);
1243 1273
1244 return 0; 1274 return 0;
@@ -1274,8 +1304,11 @@ static int ieee80211_scan(struct wiphy *wiphy,
1274 case NL80211_IFTYPE_P2P_GO: 1304 case NL80211_IFTYPE_P2P_GO:
1275 if (sdata->local->ops->hw_scan) 1305 if (sdata->local->ops->hw_scan)
1276 break; 1306 break;
1277 /* FIXME: implement NoA while scanning in software */ 1307 /*
1278 return -EOPNOTSUPP; 1308 * FIXME: implement NoA while scanning in software,
1309 * for now fall through to allow scanning only when
1310 * beaconing hasn't been configured yet
1311 */
1279 case NL80211_IFTYPE_AP: 1312 case NL80211_IFTYPE_AP:
1280 if (sdata->u.ap.beacon) 1313 if (sdata->u.ap.beacon)
1281 return -EOPNOTSUPP; 1314 return -EOPNOTSUPP;
@@ -1784,6 +1817,33 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1784 1817
1785 *cookie = (unsigned long) skb; 1818 *cookie = (unsigned long) skb;
1786 1819
1820 if (is_offchan && local->ops->offchannel_tx) {
1821 int ret;
1822
1823 IEEE80211_SKB_CB(skb)->band = chan->band;
1824
1825 mutex_lock(&local->mtx);
1826
1827 if (local->hw_offchan_tx_cookie) {
1828 mutex_unlock(&local->mtx);
1829 return -EBUSY;
1830 }
1831
1832 /* TODO: bitrate control, TX processing? */
1833 ret = drv_offchannel_tx(local, skb, chan, channel_type, wait);
1834
1835 if (ret == 0)
1836 local->hw_offchan_tx_cookie = *cookie;
1837 mutex_unlock(&local->mtx);
1838
1839 /*
1840 * Allow driver to return 1 to indicate it wants to have the
1841 * frame transmitted with a remain_on_channel + regular TX.
1842 */
1843 if (ret != 1)
1844 return ret;
1845 }
1846
1787 if (is_offchan && local->ops->remain_on_channel) { 1847 if (is_offchan && local->ops->remain_on_channel) {
1788 unsigned int duration; 1848 unsigned int duration;
1789 int ret; 1849 int ret;
@@ -1822,6 +1882,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1822 *cookie ^= 2; 1882 *cookie ^= 2;
1823 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_TX_OFFCHAN; 1883 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_TX_OFFCHAN;
1824 local->hw_roc_skb = skb; 1884 local->hw_roc_skb = skb;
1885 local->hw_roc_skb_for_status = skb;
1825 mutex_unlock(&local->mtx); 1886 mutex_unlock(&local->mtx);
1826 1887
1827 return 0; 1888 return 0;
@@ -1846,6 +1907,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1846 1907
1847 wk->type = IEEE80211_WORK_OFFCHANNEL_TX; 1908 wk->type = IEEE80211_WORK_OFFCHANNEL_TX;
1848 wk->chan = chan; 1909 wk->chan = chan;
1910 wk->chan_type = channel_type;
1849 wk->sdata = sdata; 1911 wk->sdata = sdata;
1850 wk->done = ieee80211_offchan_tx_done; 1912 wk->done = ieee80211_offchan_tx_done;
1851 wk->offchan_tx.frame = skb; 1913 wk->offchan_tx.frame = skb;
@@ -1868,6 +1930,18 @@ static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
1868 1930
1869 mutex_lock(&local->mtx); 1931 mutex_lock(&local->mtx);
1870 1932
1933 if (local->ops->offchannel_tx_cancel_wait &&
1934 local->hw_offchan_tx_cookie == cookie) {
1935 ret = drv_offchannel_tx_cancel_wait(local);
1936
1937 if (!ret)
1938 local->hw_offchan_tx_cookie = 0;
1939
1940 mutex_unlock(&local->mtx);
1941
1942 return ret;
1943 }
1944
1871 if (local->ops->cancel_remain_on_channel) { 1945 if (local->ops->cancel_remain_on_channel) {
1872 cookie ^= 2; 1946 cookie ^= 2;
1873 ret = ieee80211_cancel_remain_on_channel_hw(local, cookie); 1947 ret = ieee80211_cancel_remain_on_channel_hw(local, cookie);
@@ -1875,6 +1949,7 @@ static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
1875 if (ret == 0) { 1949 if (ret == 0) {
1876 kfree_skb(local->hw_roc_skb); 1950 kfree_skb(local->hw_roc_skb);
1877 local->hw_roc_skb = NULL; 1951 local->hw_roc_skb = NULL;
1952 local->hw_roc_skb_for_status = NULL;
1878 } 1953 }
1879 1954
1880 mutex_unlock(&local->mtx); 1955 mutex_unlock(&local->mtx);
@@ -1937,6 +2012,21 @@ static int ieee80211_get_antenna(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant)
1937 return drv_get_antenna(local, tx_ant, rx_ant); 2012 return drv_get_antenna(local, tx_ant, rx_ant);
1938} 2013}
1939 2014
2015static int ieee80211_set_ringparam(struct wiphy *wiphy, u32 tx, u32 rx)
2016{
2017 struct ieee80211_local *local = wiphy_priv(wiphy);
2018
2019 return drv_set_ringparam(local, tx, rx);
2020}
2021
2022static void ieee80211_get_ringparam(struct wiphy *wiphy,
2023 u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
2024{
2025 struct ieee80211_local *local = wiphy_priv(wiphy);
2026
2027 drv_get_ringparam(local, tx, tx_max, rx, rx_max);
2028}
2029
1940struct cfg80211_ops mac80211_config_ops = { 2030struct cfg80211_ops mac80211_config_ops = {
1941 .add_virtual_intf = ieee80211_add_iface, 2031 .add_virtual_intf = ieee80211_add_iface,
1942 .del_virtual_intf = ieee80211_del_iface, 2032 .del_virtual_intf = ieee80211_del_iface,
@@ -1994,4 +2084,6 @@ struct cfg80211_ops mac80211_config_ops = {
1994 .mgmt_frame_register = ieee80211_mgmt_frame_register, 2084 .mgmt_frame_register = ieee80211_mgmt_frame_register,
1995 .set_antenna = ieee80211_set_antenna, 2085 .set_antenna = ieee80211_set_antenna,
1996 .get_antenna = ieee80211_get_antenna, 2086 .get_antenna = ieee80211_get_antenna,
2087 .set_ringparam = ieee80211_set_ringparam,
2088 .get_ringparam = ieee80211_get_ringparam,
1997}; 2089};