Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
This commit is contained in:
@@ -370,30 +370,32 @@ static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, int idx)
|
||||
{
|
||||
enum ieee80211_band band = ieee80211_get_sdata_band(sta->sdata);
|
||||
|
||||
if (!(rate->flags & RATE_INFO_FLAGS_MCS)) {
|
||||
struct ieee80211_supported_band *sband;
|
||||
sband = sta->local->hw.wiphy->bands[band];
|
||||
rate->legacy = sband->bitrates[idx].bitrate;
|
||||
} else
|
||||
rate->mcs = idx;
|
||||
}
|
||||
|
||||
void sta_set_rate_info_tx(struct sta_info *sta,
|
||||
const struct ieee80211_tx_rate *rate,
|
||||
struct rate_info *rinfo)
|
||||
{
|
||||
rinfo->flags = 0;
|
||||
if (rate->flags & IEEE80211_TX_RC_MCS)
|
||||
if (rate->flags & IEEE80211_TX_RC_MCS) {
|
||||
rinfo->flags |= RATE_INFO_FLAGS_MCS;
|
||||
rinfo->mcs = rate->idx;
|
||||
} else if (rate->flags & IEEE80211_TX_RC_VHT_MCS) {
|
||||
rinfo->flags |= RATE_INFO_FLAGS_VHT_MCS;
|
||||
rinfo->mcs = ieee80211_rate_get_vht_mcs(rate);
|
||||
rinfo->nss = ieee80211_rate_get_vht_nss(rate);
|
||||
} else {
|
||||
struct ieee80211_supported_band *sband;
|
||||
sband = sta->local->hw.wiphy->bands[
|
||||
ieee80211_get_sdata_band(sta->sdata)];
|
||||
rinfo->legacy = sband->bitrates[rate->idx].bitrate;
|
||||
}
|
||||
if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
|
||||
rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
|
||||
if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
|
||||
rinfo->flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
|
||||
if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
|
||||
rinfo->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
|
||||
if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
|
||||
rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
|
||||
rate_idx_to_bitrate(rinfo, sta, rate->idx);
|
||||
}
|
||||
|
||||
static 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)
|
||||
sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
|
||||
|
||||
sinfo->rxrate.flags = 0;
|
||||
if (sta->last_rx_rate_flag & RX_FLAG_HT)
|
||||
if (sta->last_rx_rate_flag & RX_FLAG_HT) {
|
||||
sinfo->rxrate.flags |= RATE_INFO_FLAGS_MCS;
|
||||
sinfo->rxrate.mcs = sta->last_rx_rate_idx;
|
||||
} else if (sta->last_rx_rate_flag & RX_FLAG_VHT) {
|
||||
sinfo->rxrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
|
||||
sinfo->rxrate.nss = sta->last_rx_rate_vht_nss;
|
||||
sinfo->rxrate.mcs = sta->last_rx_rate_idx;
|
||||
} else {
|
||||
struct ieee80211_supported_band *sband;
|
||||
|
||||
sband = sta->local->hw.wiphy->bands[
|
||||
ieee80211_get_sdata_band(sta->sdata)];
|
||||
sinfo->rxrate.legacy =
|
||||
sband->bitrates[sta->last_rx_rate_idx].bitrate;
|
||||
}
|
||||
|
||||
if (sta->last_rx_rate_flag & RX_FLAG_40MHZ)
|
||||
sinfo->rxrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
|
||||
if (sta->last_rx_rate_flag & RX_FLAG_SHORT_GI)
|
||||
sinfo->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
|
||||
rate_idx_to_bitrate(&sinfo->rxrate, sta, sta->last_rx_rate_idx);
|
||||
if (sta->last_rx_rate_flag & RX_FLAG_80MHZ)
|
||||
sinfo->rxrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
|
||||
if (sta->last_rx_rate_flag & RX_FLAG_80P80MHZ)
|
||||
sinfo->rxrate.flags |= RATE_INFO_FLAGS_80P80_MHZ_WIDTH;
|
||||
if (sta->last_rx_rate_flag & RX_FLAG_160MHZ)
|
||||
sinfo->rxrate.flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
|
||||
|
||||
if (ieee80211_vif_is_mesh(&sdata->vif)) {
|
||||
#ifdef CONFIG_MAC80211_MESH
|
||||
@@ -615,7 +636,7 @@ do_survey:
|
||||
rcu_read_lock();
|
||||
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
||||
if (chanctx_conf)
|
||||
channel = chanctx_conf->channel;
|
||||
channel = chanctx_conf->def.chan;
|
||||
else
|
||||
channel = NULL;
|
||||
rcu_read_unlock();
|
||||
@@ -735,15 +756,13 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
|
||||
}
|
||||
|
||||
static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type)
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
struct ieee80211_local *local = wiphy_priv(wiphy);
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
int ret = 0;
|
||||
|
||||
if (local->monitor_channel == chan &&
|
||||
local->monitor_channel_type == channel_type)
|
||||
if (cfg80211_chandef_identical(&local->monitor_chandef, chandef))
|
||||
return 0;
|
||||
|
||||
mutex_lock(&local->iflist_mtx);
|
||||
@@ -753,20 +772,17 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
|
||||
lockdep_is_held(&local->iflist_mtx));
|
||||
if (sdata) {
|
||||
ieee80211_vif_release_channel(sdata);
|
||||
ret = ieee80211_vif_use_channel(
|
||||
sdata, chan, channel_type,
|
||||
ret = ieee80211_vif_use_channel(sdata, chandef,
|
||||
IEEE80211_CHANCTX_EXCLUSIVE);
|
||||
}
|
||||
} else if (local->open_count == local->monitors) {
|
||||
local->_oper_channel = chan;
|
||||
local->_oper_channel_type = channel_type;
|
||||
local->_oper_channel = chandef->chan;
|
||||
local->_oper_channel_type = cfg80211_get_chandef_type(chandef);
|
||||
ieee80211_hw_config(local, 0);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
local->monitor_channel = chan;
|
||||
local->monitor_channel_type = channel_type;
|
||||
}
|
||||
if (ret == 0)
|
||||
local->monitor_chandef = *chandef;
|
||||
mutex_unlock(&local->iflist_mtx);
|
||||
|
||||
return ret;
|
||||
@@ -888,8 +904,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
|
||||
sdata->smps_mode = IEEE80211_SMPS_OFF;
|
||||
sdata->needed_rx_chains = sdata->local->rx_chains;
|
||||
|
||||
err = ieee80211_vif_use_channel(sdata, params->channel,
|
||||
params->channel_type,
|
||||
err = ieee80211_vif_use_channel(sdata, ¶ms->chandef,
|
||||
IEEE80211_CHANCTX_SHARED);
|
||||
if (err)
|
||||
return err;
|
||||
@@ -1707,8 +1722,7 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev,
|
||||
sdata->smps_mode = IEEE80211_SMPS_OFF;
|
||||
sdata->needed_rx_chains = sdata->local->rx_chains;
|
||||
|
||||
err = ieee80211_vif_use_channel(sdata, setup->channel,
|
||||
setup->channel_type,
|
||||
err = ieee80211_vif_use_channel(sdata, &setup->chandef,
|
||||
IEEE80211_CHANCTX_SHARED);
|
||||
if (err)
|
||||
return err;
|
||||
@@ -1990,10 +2004,16 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (changed & WIPHY_PARAM_RETRY_SHORT)
|
||||
if (changed & WIPHY_PARAM_RETRY_SHORT) {
|
||||
if (wiphy->retry_short > IEEE80211_MAX_TX_RETRY)
|
||||
return -EINVAL;
|
||||
local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
|
||||
if (changed & WIPHY_PARAM_RETRY_LONG)
|
||||
}
|
||||
if (changed & WIPHY_PARAM_RETRY_LONG) {
|
||||
if (wiphy->retry_long > IEEE80211_MAX_TX_RETRY)
|
||||
return -EINVAL;
|
||||
local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
|
||||
}
|
||||
if (changed &
|
||||
(WIPHY_PARAM_RETRY_SHORT | WIPHY_PARAM_RETRY_LONG))
|
||||
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS);
|
||||
@@ -2129,7 +2149,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
|
||||
* the new value until we associate.
|
||||
*/
|
||||
if (!sdata->u.mgd.associated ||
|
||||
sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT)
|
||||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
|
||||
return 0;
|
||||
|
||||
ap = sdata->u.mgd.associated->bssid;
|
||||
@@ -2236,7 +2256,6 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
|
||||
static int ieee80211_start_roc_work(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_channel *channel,
|
||||
enum nl80211_channel_type channel_type,
|
||||
unsigned int duration, u64 *cookie,
|
||||
struct sk_buff *txskb)
|
||||
{
|
||||
@@ -2254,7 +2273,6 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
|
||||
return -ENOMEM;
|
||||
|
||||
roc->chan = channel;
|
||||
roc->chan_type = channel_type;
|
||||
roc->duration = duration;
|
||||
roc->req_duration = duration;
|
||||
roc->frame = txskb;
|
||||
@@ -2287,8 +2305,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
|
||||
if (!duration)
|
||||
duration = 10;
|
||||
|
||||
ret = drv_remain_on_channel(local, sdata, channel, channel_type,
|
||||
duration);
|
||||
ret = drv_remain_on_channel(local, sdata, channel, duration);
|
||||
if (ret) {
|
||||
kfree(roc);
|
||||
return ret;
|
||||
@@ -2299,8 +2316,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
|
||||
|
||||
out_check_combine:
|
||||
list_for_each_entry(tmp, &local->roc_list, list) {
|
||||
if (tmp->chan != channel || tmp->chan_type != channel_type ||
|
||||
tmp->sdata != sdata)
|
||||
if (tmp->chan != channel || tmp->sdata != sdata)
|
||||
continue;
|
||||
|
||||
/*
|
||||
@@ -2417,7 +2433,6 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
|
||||
static int ieee80211_remain_on_channel(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type,
|
||||
unsigned int duration,
|
||||
u64 *cookie)
|
||||
{
|
||||
@@ -2426,7 +2441,7 @@ static int ieee80211_remain_on_channel(struct wiphy *wiphy,
|
||||
int ret;
|
||||
|
||||
mutex_lock(&local->mtx);
|
||||
ret = ieee80211_start_roc_work(local, sdata, chan, channel_type,
|
||||
ret = ieee80211_start_roc_work(local, sdata, chan,
|
||||
duration, cookie, NULL);
|
||||
mutex_unlock(&local->mtx);
|
||||
|
||||
@@ -2519,10 +2534,8 @@ static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy,
|
||||
|
||||
static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
struct ieee80211_channel *chan, bool offchan,
|
||||
enum nl80211_channel_type channel_type,
|
||||
bool channel_type_valid, unsigned int wait,
|
||||
const u8 *buf, size_t len, bool no_cck,
|
||||
bool dont_wait_for_ack, u64 *cookie)
|
||||
unsigned int wait, const u8 *buf, size_t len,
|
||||
bool no_cck, bool dont_wait_for_ack, u64 *cookie)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
@@ -2591,14 +2604,10 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
rcu_read_lock();
|
||||
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
||||
|
||||
if (chanctx_conf) {
|
||||
need_offchan = chan != chanctx_conf->channel;
|
||||
if (channel_type_valid &&
|
||||
channel_type != chanctx_conf->channel_type)
|
||||
need_offchan = true;
|
||||
} else {
|
||||
if (chanctx_conf)
|
||||
need_offchan = chan != chanctx_conf->def.chan;
|
||||
else
|
||||
need_offchan = true;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
@@ -2633,7 +2642,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
local->hw.offchannel_tx_hw_queue;
|
||||
|
||||
/* This will handle all kinds of coalescing and immediate TX */
|
||||
ret = ieee80211_start_roc_work(local, sdata, chan, channel_type,
|
||||
ret = ieee80211_start_roc_work(local, sdata, chan,
|
||||
wait, cookie, skb);
|
||||
if (ret)
|
||||
kfree_skb(skb);
|
||||
@@ -3067,7 +3076,7 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
|
||||
rcu_read_unlock();
|
||||
return -EINVAL;
|
||||
}
|
||||
band = chanctx_conf->channel->band;
|
||||
band = chanctx_conf->def.chan->band;
|
||||
sta = sta_info_get(sdata, peer);
|
||||
if (sta) {
|
||||
qos = test_sta_flag(sta, WLAN_STA_WME);
|
||||
@@ -3124,23 +3133,23 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ieee80211_channel *
|
||||
ieee80211_cfg_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
enum nl80211_channel_type *type)
|
||||
static int ieee80211_cfg_get_channel(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
|
||||
struct ieee80211_chanctx_conf *chanctx_conf;
|
||||
struct ieee80211_channel *chan = NULL;
|
||||
int ret = -ENODATA;
|
||||
|
||||
rcu_read_lock();
|
||||
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
||||
if (chanctx_conf) {
|
||||
*type = chanctx_conf->channel_type;
|
||||
chan = chanctx_conf->channel;
|
||||
*chandef = chanctx_conf->def;
|
||||
ret = 0;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
return chan;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
Reference in New Issue
Block a user