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.c68
1 files changed, 60 insertions, 8 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 140503d4c97a..7b701dcddb50 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
@@ -1800,6 +1813,33 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1800 1813
1801 *cookie = (unsigned long) skb; 1814 *cookie = (unsigned long) skb;
1802 1815
1816 if (is_offchan && local->ops->offchannel_tx) {
1817 int ret;
1818
1819 IEEE80211_SKB_CB(skb)->band = chan->band;
1820
1821 mutex_lock(&local->mtx);
1822
1823 if (local->hw_offchan_tx_cookie) {
1824 mutex_unlock(&local->mtx);
1825 return -EBUSY;
1826 }
1827
1828 /* TODO: bitrate control, TX processing? */
1829 ret = drv_offchannel_tx(local, skb, chan, channel_type, wait);
1830
1831 if (ret == 0)
1832 local->hw_offchan_tx_cookie = *cookie;
1833 mutex_unlock(&local->mtx);
1834
1835 /*
1836 * Allow driver to return 1 to indicate it wants to have the
1837 * frame transmitted with a remain_on_channel + regular TX.
1838 */
1839 if (ret != 1)
1840 return ret;
1841 }
1842
1803 if (is_offchan && local->ops->remain_on_channel) { 1843 if (is_offchan && local->ops->remain_on_channel) {
1804 unsigned int duration; 1844 unsigned int duration;
1805 int ret; 1845 int ret;
@@ -1886,6 +1926,18 @@ static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
1886 1926
1887 mutex_lock(&local->mtx); 1927 mutex_lock(&local->mtx);
1888 1928
1929 if (local->ops->offchannel_tx_cancel_wait &&
1930 local->hw_offchan_tx_cookie == cookie) {
1931 ret = drv_offchannel_tx_cancel_wait(local);
1932
1933 if (!ret)
1934 local->hw_offchan_tx_cookie = 0;
1935
1936 mutex_unlock(&local->mtx);
1937
1938 return ret;
1939 }
1940
1889 if (local->ops->cancel_remain_on_channel) { 1941 if (local->ops->cancel_remain_on_channel) {
1890 cookie ^= 2; 1942 cookie ^= 2;
1891 ret = ieee80211_cancel_remain_on_channel_hw(local, cookie); 1943 ret = ieee80211_cancel_remain_on_channel_hw(local, cookie);