mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-14 16:23:51 +08:00
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
This commit is contained in:
commit
62c8003ecb
@ -1074,15 +1074,18 @@ out:
|
||||
void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
|
||||
enum wmi_phy_mode mode)
|
||||
{
|
||||
enum nl80211_channel_type type;
|
||||
struct cfg80211_chan_def chandef;
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
|
||||
"channel switch notify nw_type %d freq %d mode %d\n",
|
||||
vif->nw_type, freq, mode);
|
||||
|
||||
type = (mode == WMI_11G_HT20) ? NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT;
|
||||
cfg80211_chandef_create(&chandef,
|
||||
ieee80211_get_channel(vif->ar->wiphy, freq),
|
||||
(mode == WMI_11G_HT20) ?
|
||||
NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT);
|
||||
|
||||
cfg80211_ch_switch_notify(vif->ndev, freq, type);
|
||||
cfg80211_ch_switch_notify(vif->ndev, &chandef);
|
||||
}
|
||||
|
||||
static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
|
||||
@ -1594,8 +1597,8 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
|
||||
vif->ssid_len = ibss_param->ssid_len;
|
||||
memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len);
|
||||
|
||||
if (ibss_param->channel)
|
||||
vif->ch_hint = ibss_param->channel->center_freq;
|
||||
if (ibss_param->chandef.chan)
|
||||
vif->ch_hint = ibss_param->chandef.chan->center_freq;
|
||||
|
||||
if (ibss_param->channel_fixed) {
|
||||
/*
|
||||
@ -2878,7 +2881,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
|
||||
p.ssid_len = vif->ssid_len;
|
||||
memcpy(p.ssid, vif->ssid, vif->ssid_len);
|
||||
p.dot11_auth_mode = vif->dot11_auth_mode;
|
||||
p.ch = cpu_to_le16(info->channel->center_freq);
|
||||
p.ch = cpu_to_le16(info->chandef.chan->center_freq);
|
||||
|
||||
/* Enable uAPSD support by default */
|
||||
res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true);
|
||||
@ -2909,8 +2912,9 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
|
||||
return res;
|
||||
}
|
||||
|
||||
if (ath6kl_set_htcap(vif, info->channel->band,
|
||||
info->channel_type != NL80211_CHAN_NO_HT))
|
||||
if (ath6kl_set_htcap(vif, info->chandef.chan->band,
|
||||
cfg80211_get_chandef_type(&info->chandef)
|
||||
!= NL80211_CHAN_NO_HT))
|
||||
return -EIO;
|
||||
|
||||
/*
|
||||
@ -3006,7 +3010,6 @@ static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
|
||||
static int ath6kl_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)
|
||||
{
|
||||
@ -3165,10 +3168,8 @@ static bool ath6kl_is_p2p_go_ssid(const u8 *buf, size_t len)
|
||||
|
||||
static int ath6kl_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 ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
|
||||
struct ath6kl *ar = ath6kl_priv(vif->ndev);
|
||||
|
@ -474,7 +474,7 @@ static int ath6kl_wmi_remain_on_chnl_event_rx(struct wmi *wmi, u8 *datap,
|
||||
return -EINVAL;
|
||||
}
|
||||
id = vif->last_roc_id;
|
||||
cfg80211_ready_on_channel(&vif->wdev, id, chan, NL80211_CHAN_NO_HT,
|
||||
cfg80211_ready_on_channel(&vif->wdev, id, chan,
|
||||
dur, GFP_ATOMIC);
|
||||
|
||||
return 0;
|
||||
@ -513,8 +513,7 @@ static int ath6kl_wmi_cancel_remain_on_chnl_event_rx(struct wmi *wmi,
|
||||
else
|
||||
id = vif->last_roc_id; /* timeout on uncanceled r-o-c */
|
||||
vif->last_cancel_roc_id = 0;
|
||||
cfg80211_remain_on_channel_expired(&vif->wdev, id, chan,
|
||||
NL80211_CHAN_NO_HT, GFP_ATOMIC);
|
||||
cfg80211_remain_on_channel_expired(&vif->wdev, id, chan, GFP_ATOMIC);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1013,8 +1013,8 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
|
||||
else
|
||||
WL_CONN("No BSSID specified\n");
|
||||
|
||||
if (params->channel)
|
||||
WL_CONN("channel: %d\n", params->channel->center_freq);
|
||||
if (params->chandef.chan)
|
||||
WL_CONN("channel: %d\n", params->chandef.chan->center_freq);
|
||||
else
|
||||
WL_CONN("no channel specified\n");
|
||||
|
||||
@ -1087,12 +1087,12 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
|
||||
}
|
||||
|
||||
/* Channel */
|
||||
if (params->channel) {
|
||||
if (params->chandef.chan) {
|
||||
u32 target_channel;
|
||||
|
||||
cfg->channel =
|
||||
ieee80211_frequency_to_channel(
|
||||
params->channel->center_freq);
|
||||
params->chandef.chan->center_freq);
|
||||
if (params->channel_fixed) {
|
||||
/* adding chanspec */
|
||||
brcmf_ch_to_chanspec(cfg->channel,
|
||||
@ -3506,7 +3506,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
|
||||
s32 bssidx = 0;
|
||||
|
||||
WL_TRACE("channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
|
||||
settings->channel_type, settings->beacon_interval,
|
||||
cfg80211_get_chandef_type(&settings->chandef),
|
||||
settings->beacon_interval,
|
||||
settings->dtim_period);
|
||||
WL_TRACE("ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
|
||||
settings->ssid, settings->ssid_len, settings->auth_type,
|
||||
|
@ -789,7 +789,6 @@ struct iwl_priv {
|
||||
/* remain-on-channel offload support */
|
||||
struct ieee80211_channel *hw_roc_channel;
|
||||
struct delayed_work hw_roc_disable_work;
|
||||
enum nl80211_channel_type hw_roc_chantype;
|
||||
int hw_roc_duration;
|
||||
bool hw_roc_setup, hw_roc_start_notified;
|
||||
|
||||
|
@ -1037,7 +1037,6 @@ done:
|
||||
static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_channel *channel,
|
||||
enum nl80211_channel_type channel_type,
|
||||
int duration)
|
||||
{
|
||||
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
|
||||
@ -1069,7 +1068,6 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
priv->hw_roc_channel = channel;
|
||||
priv->hw_roc_chantype = channel_type;
|
||||
/* convert from ms to TU */
|
||||
priv->hw_roc_duration = DIV_ROUND_UP(1000 * duration, 1024);
|
||||
priv->hw_roc_start_notified = false;
|
||||
|
@ -436,19 +436,19 @@ static int lbs_add_wpa_tlv(u8 *tlv, const u8 *ie, u8 ie_len)
|
||||
*/
|
||||
|
||||
static int lbs_cfg_set_monitor_channel(struct wiphy *wiphy,
|
||||
struct ieee80211_channel *channel,
|
||||
enum nl80211_channel_type channel_type)
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
struct lbs_private *priv = wiphy_priv(wiphy);
|
||||
int ret = -ENOTSUPP;
|
||||
|
||||
lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d",
|
||||
channel->center_freq, channel_type);
|
||||
chandef->chan->center_freq,
|
||||
cfg80211_get_chandef_type(chandef));
|
||||
|
||||
if (channel_type != NL80211_CHAN_NO_HT)
|
||||
if (cfg80211_get_chandef_type(chandef) != NL80211_CHAN_NO_HT)
|
||||
goto out;
|
||||
|
||||
ret = lbs_set_channel(priv, channel->hw_value);
|
||||
ret = lbs_set_channel(priv, chandef->chan->hw_value);
|
||||
|
||||
out:
|
||||
lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
|
||||
@ -1734,7 +1734,7 @@ static void lbs_join_post(struct lbs_private *priv,
|
||||
/* Fake DS channel IE */
|
||||
*fake++ = WLAN_EID_DS_PARAMS;
|
||||
*fake++ = 1;
|
||||
*fake++ = params->channel->hw_value;
|
||||
*fake++ = params->chandef.chan->hw_value;
|
||||
/* Fake IBSS params IE */
|
||||
*fake++ = WLAN_EID_IBSS_PARAMS;
|
||||
*fake++ = 2;
|
||||
@ -1755,7 +1755,7 @@ static void lbs_join_post(struct lbs_private *priv,
|
||||
lbs_deb_hex(LBS_DEB_CFG80211, "IE", fake_ie, fake - fake_ie);
|
||||
|
||||
bss = cfg80211_inform_bss(priv->wdev->wiphy,
|
||||
params->channel,
|
||||
params->chandef.chan,
|
||||
bssid,
|
||||
0,
|
||||
capability,
|
||||
@ -1833,7 +1833,7 @@ static int lbs_ibss_join_existing(struct lbs_private *priv,
|
||||
cmd.bss.beaconperiod = cpu_to_le16(params->beacon_interval);
|
||||
cmd.bss.ds.header.id = WLAN_EID_DS_PARAMS;
|
||||
cmd.bss.ds.header.len = 1;
|
||||
cmd.bss.ds.channel = params->channel->hw_value;
|
||||
cmd.bss.ds.channel = params->chandef.chan->hw_value;
|
||||
cmd.bss.ibss.header.id = WLAN_EID_IBSS_PARAMS;
|
||||
cmd.bss.ibss.header.len = 2;
|
||||
cmd.bss.ibss.atimwindow = 0;
|
||||
@ -1942,7 +1942,7 @@ static int lbs_ibss_start_new(struct lbs_private *priv,
|
||||
cmd.ibss.atimwindow = 0;
|
||||
cmd.ds.header.id = WLAN_EID_DS_PARAMS;
|
||||
cmd.ds.header.len = 1;
|
||||
cmd.ds.channel = params->channel->hw_value;
|
||||
cmd.ds.channel = params->chandef.chan->hw_value;
|
||||
/* Only v8 and below support setting probe delay */
|
||||
if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8)
|
||||
cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
|
||||
@ -1987,18 +1987,18 @@ static int lbs_join_ibss(struct wiphy *wiphy, struct net_device *dev,
|
||||
|
||||
lbs_deb_enter(LBS_DEB_CFG80211);
|
||||
|
||||
if (!params->channel) {
|
||||
if (!params->chandef.chan) {
|
||||
ret = -ENOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = lbs_set_channel(priv, params->channel->hw_value);
|
||||
ret = lbs_set_channel(priv, params->chandef.chan->hw_value);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
/* Search if someone is beaconing. This assumes that the
|
||||
* bss list is populated already */
|
||||
bss = cfg80211_get_bss(wiphy, params->channel, params->bssid,
|
||||
bss = cfg80211_get_bss(wiphy, params->chandef.chan, params->bssid,
|
||||
params->ssid, params->ssid_len,
|
||||
WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);
|
||||
|
||||
|
@ -681,7 +681,7 @@ static void mac80211_hwsim_tx_iter(void *_data, u8 *addr,
|
||||
return;
|
||||
|
||||
if (!hwsim_chans_compat(data->channel,
|
||||
rcu_dereference(vif->chanctx_conf)->channel))
|
||||
rcu_dereference(vif->chanctx_conf)->def.chan))
|
||||
return;
|
||||
|
||||
data->receive = true;
|
||||
@ -832,7 +832,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
|
||||
} else {
|
||||
chanctx_conf = rcu_dereference(txi->control.vif->chanctx_conf);
|
||||
if (chanctx_conf)
|
||||
channel = chanctx_conf->channel;
|
||||
channel = chanctx_conf->def.chan;
|
||||
else
|
||||
channel = NULL;
|
||||
}
|
||||
@ -977,7 +977,7 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
|
||||
return;
|
||||
|
||||
mac80211_hwsim_tx_frame(hw, skb,
|
||||
rcu_dereference(vif->chanctx_conf)->channel);
|
||||
rcu_dereference(vif->chanctx_conf)->def.chan);
|
||||
}
|
||||
|
||||
|
||||
@ -1107,9 +1107,8 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_HT) {
|
||||
wiphy_debug(hw->wiphy, " HT: op_mode=0x%x, chantype=%s\n",
|
||||
info->ht_operation_mode,
|
||||
hwsim_chantypes[info->channel_type]);
|
||||
wiphy_debug(hw->wiphy, " HT: op_mode=0x%x\n",
|
||||
info->ht_operation_mode);
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_BASIC_RATES) {
|
||||
@ -1368,7 +1367,6 @@ static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw,
|
||||
struct cfg80211_scan_request *req)
|
||||
{
|
||||
struct mac80211_hwsim_data *hwsim = hw->priv;
|
||||
int i;
|
||||
|
||||
mutex_lock(&hwsim->mutex);
|
||||
if (WARN_ON(hwsim->tmp_chan || hwsim->hw_scan_request)) {
|
||||
@ -1381,11 +1379,6 @@ static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw,
|
||||
mutex_unlock(&hwsim->mutex);
|
||||
|
||||
wiphy_debug(hw->wiphy, "hwsim hw_scan request\n");
|
||||
for (i = 0; i < req->n_channels; i++)
|
||||
printk(KERN_DEBUG "hwsim hw_scan freq %d\n",
|
||||
req->channels[i]->center_freq);
|
||||
print_hex_dump(KERN_DEBUG, "scan IEs: ", DUMP_PREFIX_OFFSET,
|
||||
16, 1, req->ie, req->ie_len, 1);
|
||||
|
||||
ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan, 0);
|
||||
|
||||
@ -1455,7 +1448,6 @@ static void hw_roc_done(struct work_struct *work)
|
||||
static int mac80211_hwsim_roc(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type,
|
||||
int duration)
|
||||
{
|
||||
struct mac80211_hwsim_data *hwsim = hw->priv;
|
||||
@ -1498,16 +1490,20 @@ static int mac80211_hwsim_add_chanctx(struct ieee80211_hw *hw,
|
||||
struct ieee80211_chanctx_conf *ctx)
|
||||
{
|
||||
hwsim_set_chanctx_magic(ctx);
|
||||
wiphy_debug(hw->wiphy, "add channel context %d MHz/%d\n",
|
||||
ctx->channel->center_freq, ctx->channel_type);
|
||||
wiphy_debug(hw->wiphy,
|
||||
"add channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
|
||||
ctx->def.chan->center_freq, ctx->def.width,
|
||||
ctx->def.center_freq1, ctx->def.center_freq2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mac80211_hwsim_remove_chanctx(struct ieee80211_hw *hw,
|
||||
struct ieee80211_chanctx_conf *ctx)
|
||||
{
|
||||
wiphy_debug(hw->wiphy, "remove channel context %d MHz/%d\n",
|
||||
ctx->channel->center_freq, ctx->channel_type);
|
||||
wiphy_debug(hw->wiphy,
|
||||
"remove channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
|
||||
ctx->def.chan->center_freq, ctx->def.width,
|
||||
ctx->def.center_freq1, ctx->def.center_freq2);
|
||||
hwsim_check_chanctx_magic(ctx);
|
||||
hwsim_clear_chanctx_magic(ctx);
|
||||
}
|
||||
@ -1517,8 +1513,10 @@ static void mac80211_hwsim_change_chanctx(struct ieee80211_hw *hw,
|
||||
u32 changed)
|
||||
{
|
||||
hwsim_check_chanctx_magic(ctx);
|
||||
wiphy_debug(hw->wiphy, "change channel context %#x (%d MHz/%d)\n",
|
||||
changed, ctx->channel->center_freq, ctx->channel_type);
|
||||
wiphy_debug(hw->wiphy,
|
||||
"change channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
|
||||
ctx->def.chan->center_freq, ctx->def.width,
|
||||
ctx->def.center_freq1, ctx->def.center_freq2);
|
||||
}
|
||||
|
||||
static int mac80211_hwsim_assign_vif_chanctx(struct ieee80211_hw *hw,
|
||||
@ -1640,7 +1638,7 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif)
|
||||
|
||||
rcu_read_lock();
|
||||
mac80211_hwsim_tx_frame(data->hw, skb,
|
||||
rcu_dereference(vif->chanctx_conf)->channel);
|
||||
rcu_dereference(vif->chanctx_conf)->def.chan);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
@ -1672,7 +1670,7 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
|
||||
|
||||
rcu_read_lock();
|
||||
mac80211_hwsim_tx_frame(data->hw, skb,
|
||||
rcu_dereference(vif->chanctx_conf)->channel);
|
||||
rcu_dereference(vif->chanctx_conf)->def.chan);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
@ -2204,6 +2202,34 @@ static int __init init_mac80211_hwsim(void)
|
||||
sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
|
||||
|
||||
hw->wiphy->bands[band] = sband;
|
||||
|
||||
if (channels == 1)
|
||||
continue;
|
||||
|
||||
sband->vht_cap.vht_supported = true;
|
||||
sband->vht_cap.cap =
|
||||
IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
|
||||
IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ |
|
||||
IEEE80211_VHT_CAP_RXLDPC |
|
||||
IEEE80211_VHT_CAP_SHORT_GI_80 |
|
||||
IEEE80211_VHT_CAP_SHORT_GI_160 |
|
||||
IEEE80211_VHT_CAP_TXSTBC |
|
||||
IEEE80211_VHT_CAP_RXSTBC_1 |
|
||||
IEEE80211_VHT_CAP_RXSTBC_2 |
|
||||
IEEE80211_VHT_CAP_RXSTBC_3 |
|
||||
IEEE80211_VHT_CAP_RXSTBC_4 |
|
||||
IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT;
|
||||
sband->vht_cap.vht_mcs.rx_mcs_map =
|
||||
cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_8 << 0 |
|
||||
IEEE80211_VHT_MCS_SUPPORT_0_8 << 2 |
|
||||
IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 |
|
||||
IEEE80211_VHT_MCS_SUPPORT_0_8 << 6 |
|
||||
IEEE80211_VHT_MCS_SUPPORT_0_8 << 8 |
|
||||
IEEE80211_VHT_MCS_SUPPORT_0_9 << 10 |
|
||||
IEEE80211_VHT_MCS_SUPPORT_0_9 << 12 |
|
||||
IEEE80211_VHT_MCS_SUPPORT_0_8 << 14);
|
||||
sband->vht_cap.vht_mcs.tx_mcs_map =
|
||||
sband->vht_cap.vht_mcs.rx_mcs_map;
|
||||
}
|
||||
/* By default all radios are belonging to the first group */
|
||||
data->group = 1;
|
||||
|
@ -180,10 +180,8 @@ mwifiex_form_mgmt_frame(struct sk_buff *skb, const u8 *buf, size_t len)
|
||||
static int
|
||||
mwifiex_cfg80211_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 sk_buff *skb;
|
||||
u16 pkt_len;
|
||||
@ -253,7 +251,6 @@ static int
|
||||
mwifiex_cfg80211_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)
|
||||
{
|
||||
struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
|
||||
@ -271,15 +268,14 @@ mwifiex_cfg80211_remain_on_channel(struct wiphy *wiphy,
|
||||
}
|
||||
|
||||
ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_SET, chan,
|
||||
&channel_type, duration);
|
||||
duration);
|
||||
|
||||
if (!ret) {
|
||||
*cookie = random32() | 1;
|
||||
priv->roc_cfg.cookie = *cookie;
|
||||
priv->roc_cfg.chan = *chan;
|
||||
priv->roc_cfg.chan_type = channel_type;
|
||||
|
||||
cfg80211_ready_on_channel(wdev, *cookie, chan, channel_type,
|
||||
cfg80211_ready_on_channel(wdev, *cookie, chan,
|
||||
duration, GFP_ATOMIC);
|
||||
|
||||
wiphy_dbg(wiphy, "info: ROC, cookie = 0x%llx\n", *cookie);
|
||||
@ -302,13 +298,11 @@ mwifiex_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
|
||||
return -ENOENT;
|
||||
|
||||
ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_REMOVE,
|
||||
&priv->roc_cfg.chan,
|
||||
&priv->roc_cfg.chan_type, 0);
|
||||
&priv->roc_cfg.chan, 0);
|
||||
|
||||
if (!ret) {
|
||||
cfg80211_remain_on_channel_expired(wdev, cookie,
|
||||
&priv->roc_cfg.chan,
|
||||
priv->roc_cfg.chan_type,
|
||||
GFP_ATOMIC);
|
||||
|
||||
memset(&priv->roc_cfg, 0, sizeof(struct mwifiex_roc_cfg));
|
||||
@ -1297,21 +1291,23 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bss_cfg->channel =
|
||||
(u8)ieee80211_frequency_to_channel(params->channel->center_freq);
|
||||
bss_cfg->channel = ieee80211_frequency_to_channel(
|
||||
params->chandef.chan->center_freq);
|
||||
|
||||
/* Set appropriate bands */
|
||||
if (params->channel->band == IEEE80211_BAND_2GHZ) {
|
||||
if (params->chandef.chan->band == IEEE80211_BAND_2GHZ) {
|
||||
bss_cfg->band_cfg = BAND_CONFIG_BG;
|
||||
|
||||
if (params->channel_type == NL80211_CHAN_NO_HT)
|
||||
if (cfg80211_get_chandef_type(¶ms->chandef) ==
|
||||
NL80211_CHAN_NO_HT)
|
||||
config_bands = BAND_B | BAND_G;
|
||||
else
|
||||
config_bands = BAND_B | BAND_G | BAND_GN;
|
||||
} else {
|
||||
bss_cfg->band_cfg = BAND_CONFIG_A;
|
||||
|
||||
if (params->channel_type == NL80211_CHAN_NO_HT)
|
||||
if (cfg80211_get_chandef_type(¶ms->chandef) ==
|
||||
NL80211_CHAN_NO_HT)
|
||||
config_bands = BAND_A;
|
||||
else
|
||||
config_bands = BAND_AN | BAND_A;
|
||||
@ -1684,7 +1680,7 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv,
|
||||
int index = 0, i;
|
||||
u8 config_bands = 0;
|
||||
|
||||
if (params->channel->band == IEEE80211_BAND_2GHZ) {
|
||||
if (params->chandef.chan->band == IEEE80211_BAND_2GHZ) {
|
||||
if (!params->basic_rates) {
|
||||
config_bands = BAND_B | BAND_G;
|
||||
} else {
|
||||
@ -1709,10 +1705,12 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv,
|
||||
}
|
||||
}
|
||||
|
||||
if (params->channel_type != NL80211_CHAN_NO_HT)
|
||||
if (cfg80211_get_chandef_type(¶ms->chandef) !=
|
||||
NL80211_CHAN_NO_HT)
|
||||
config_bands |= BAND_GN;
|
||||
} else {
|
||||
if (params->channel_type == NL80211_CHAN_NO_HT)
|
||||
if (cfg80211_get_chandef_type(¶ms->chandef) !=
|
||||
NL80211_CHAN_NO_HT)
|
||||
config_bands = BAND_A;
|
||||
else
|
||||
config_bands = BAND_AN | BAND_A;
|
||||
@ -1729,9 +1727,10 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv,
|
||||
}
|
||||
|
||||
adapter->sec_chan_offset =
|
||||
mwifiex_chan_type_to_sec_chan_offset(params->channel_type);
|
||||
priv->adhoc_channel =
|
||||
ieee80211_frequency_to_channel(params->channel->center_freq);
|
||||
mwifiex_chan_type_to_sec_chan_offset(
|
||||
cfg80211_get_chandef_type(¶ms->chandef));
|
||||
priv->adhoc_channel = ieee80211_frequency_to_channel(
|
||||
params->chandef.chan->center_freq);
|
||||
|
||||
wiphy_dbg(wiphy, "info: set ibss band %d, chan %d, chan offset %d\n",
|
||||
config_bands, priv->adhoc_channel, adapter->sec_chan_offset);
|
||||
@ -1765,7 +1764,8 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
|
||||
|
||||
ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid,
|
||||
params->bssid, priv->bss_mode,
|
||||
params->channel, NULL, params->privacy);
|
||||
params->chandef.chan, NULL,
|
||||
params->privacy);
|
||||
done:
|
||||
if (!ret) {
|
||||
cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL);
|
||||
|
@ -371,7 +371,6 @@ struct wps {
|
||||
struct mwifiex_roc_cfg {
|
||||
u64 cookie;
|
||||
struct ieee80211_channel chan;
|
||||
enum nl80211_channel_type chan_type;
|
||||
};
|
||||
|
||||
struct mwifiex_adapter;
|
||||
@ -1018,7 +1017,6 @@ int mwifiex_get_ver_ext(struct mwifiex_private *priv);
|
||||
|
||||
int mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type *channel_type,
|
||||
unsigned int duration);
|
||||
|
||||
int mwifiex_set_bss_role(struct mwifiex_private *priv, u8 bss_role);
|
||||
|
@ -421,7 +421,6 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
|
||||
cfg80211_remain_on_channel_expired(priv->wdev,
|
||||
priv->roc_cfg.cookie,
|
||||
&priv->roc_cfg.chan,
|
||||
priv->roc_cfg.chan_type,
|
||||
GFP_ATOMIC);
|
||||
|
||||
memset(&priv->roc_cfg, 0x00, sizeof(struct mwifiex_roc_cfg));
|
||||
|
@ -1044,7 +1044,6 @@ mwifiex_get_ver_ext(struct mwifiex_private *priv)
|
||||
int
|
||||
mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type *ct,
|
||||
unsigned int duration)
|
||||
{
|
||||
struct host_cmd_ds_remain_on_chan roc_cfg;
|
||||
@ -1054,7 +1053,7 @@ mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action,
|
||||
roc_cfg.action = cpu_to_le16(action);
|
||||
if (action == HostCmd_ACT_GEN_SET) {
|
||||
roc_cfg.band_cfg = chan->band;
|
||||
sc = mwifiex_chan_type_to_sec_chan_offset(*ct);
|
||||
sc = mwifiex_chan_type_to_sec_chan_offset(NL80211_CHAN_NO_HT);
|
||||
roc_cfg.band_cfg |= (sc << 2);
|
||||
|
||||
roc_cfg.channel =
|
||||
|
@ -161,24 +161,23 @@ static int orinoco_scan(struct wiphy *wiphy,
|
||||
}
|
||||
|
||||
static int orinoco_set_monitor_channel(struct wiphy *wiphy,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type)
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
struct orinoco_private *priv = wiphy_priv(wiphy);
|
||||
int err = 0;
|
||||
unsigned long flags;
|
||||
int channel;
|
||||
|
||||
if (!chan)
|
||||
if (!chandef->chan)
|
||||
return -EINVAL;
|
||||
|
||||
if (channel_type != NL80211_CHAN_NO_HT)
|
||||
if (cfg80211_get_chandef_type(chandef) != NL80211_CHAN_NO_HT)
|
||||
return -EINVAL;
|
||||
|
||||
if (chan->band != IEEE80211_BAND_2GHZ)
|
||||
if (chandef->chan->band != IEEE80211_BAND_2GHZ)
|
||||
return -EINVAL;
|
||||
|
||||
channel = ieee80211_freq_to_dsss_chan(chan->center_freq);
|
||||
channel = ieee80211_freq_to_dsss_chan(chandef->chan->center_freq);
|
||||
|
||||
if ((channel < 1) || (channel > NUM_CHANNELS) ||
|
||||
!(priv->channel_mask & (1 << (channel - 1))))
|
||||
|
@ -2293,7 +2293,7 @@ static int rndis_join_ibss(struct wiphy *wiphy, struct net_device *dev,
|
||||
{
|
||||
struct rndis_wlan_private *priv = wiphy_priv(wiphy);
|
||||
struct usbnet *usbdev = priv->usbdev;
|
||||
struct ieee80211_channel *channel = params->channel;
|
||||
struct ieee80211_channel *channel = params->chandef.chan;
|
||||
struct ndis_80211_ssid ssid;
|
||||
enum nl80211_auth_type auth_type;
|
||||
int ret, alg, length, chan = -1;
|
||||
|
@ -3791,7 +3791,7 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
|
||||
|
||||
/* Handle HT information change */
|
||||
if ((changed & BSS_CHANGED_HT) &&
|
||||
(bss_conf->channel_type != NL80211_CHAN_NO_HT)) {
|
||||
(bss_conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT)) {
|
||||
ret = wl1271_acx_set_ht_information(wl, wlvif,
|
||||
bss_conf->ht_operation_mode);
|
||||
if (ret < 0) {
|
||||
@ -3905,7 +3905,8 @@ sta_not_found:
|
||||
u32 rates;
|
||||
int ieoffset;
|
||||
wlvif->aid = bss_conf->aid;
|
||||
wlvif->channel_type = bss_conf->channel_type;
|
||||
wlvif->channel_type =
|
||||
cfg80211_get_chandef_type(&bss_conf->chandef);
|
||||
wlvif->beacon_int = bss_conf->beacon_int;
|
||||
do_join = true;
|
||||
set_assoc = true;
|
||||
@ -4071,7 +4072,7 @@ sta_not_found:
|
||||
/* Handle new association with HT. Do this after join. */
|
||||
if (sta_exists) {
|
||||
if ((changed & BSS_CHANGED_HT) &&
|
||||
(bss_conf->channel_type != NL80211_CHAN_NO_HT)) {
|
||||
(bss_conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT)) {
|
||||
ret = wl1271_acx_set_ht_capabilities(wl,
|
||||
&sta_ht_cap,
|
||||
true,
|
||||
@ -4098,7 +4099,7 @@ sta_not_found:
|
||||
|
||||
/* Handle HT information change. Done after join. */
|
||||
if ((changed & BSS_CHANGED_HT) &&
|
||||
(bss_conf->channel_type != NL80211_CHAN_NO_HT)) {
|
||||
(bss_conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT)) {
|
||||
ret = wl1271_acx_set_ht_information(wl, wlvif,
|
||||
bss_conf->ht_operation_mode);
|
||||
if (ret < 0) {
|
||||
|
@ -667,6 +667,21 @@ struct ieee80211_meshconf_ie {
|
||||
u8 meshconf_cap;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/**
|
||||
* enum mesh_config_capab_flags - Mesh Configuration IE capability field flags
|
||||
*
|
||||
* @IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS: STA is willing to establish
|
||||
* additional mesh peerings with other mesh STAs
|
||||
* @IEEE80211_MESHCONF_CAPAB_FORWARDING: the STA forwards MSDUs
|
||||
* @IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING: TBTT adjustment procedure
|
||||
* is ongoing
|
||||
*/
|
||||
enum mesh_config_capab_flags {
|
||||
IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS = 0x01,
|
||||
IEEE80211_MESHCONF_CAPAB_FORWARDING = 0x08,
|
||||
IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING = 0x20,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ieee80211_rann_ie
|
||||
*
|
||||
@ -1148,11 +1163,13 @@ struct ieee80211_ht_operation {
|
||||
* STA can receive. Rate expressed in units of 1 Mbps.
|
||||
* If this field is 0 this value should not be used to
|
||||
* consider the highest RX data rate supported.
|
||||
* The top 3 bits of this field are reserved.
|
||||
* @tx_mcs_map: TX MCS map 2 bits for each stream, total 8 streams
|
||||
* @tx_highest: Indicates highest long GI VHT PPDU data rate
|
||||
* STA can transmit. Rate expressed in units of 1 Mbps.
|
||||
* If this field is 0 this value should not be used to
|
||||
* consider the highest TX data rate supported.
|
||||
* The top 3 bits of this field are reserved.
|
||||
*/
|
||||
struct ieee80211_vht_mcs_info {
|
||||
__le16 rx_mcs_map;
|
||||
@ -1161,6 +1178,27 @@ struct ieee80211_vht_mcs_info {
|
||||
__le16 tx_highest;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* enum ieee80211_vht_mcs_support - VHT MCS support definitions
|
||||
* @IEEE80211_VHT_MCS_SUPPORT_0_7: MCSes 0-7 are supported for the
|
||||
* number of streams
|
||||
* @IEEE80211_VHT_MCS_SUPPORT_0_8: MCSes 0-8 are supported
|
||||
* @IEEE80211_VHT_MCS_SUPPORT_0_9: MCSes 0-9 are supported
|
||||
* @IEEE80211_VHT_MCS_NOT_SUPPORTED: This number of streams isn't supported
|
||||
*
|
||||
* These definitions are used in each 2-bit subfield of the @rx_mcs_map
|
||||
* and @tx_mcs_map fields of &struct ieee80211_vht_mcs_info, which are
|
||||
* both split into 8 subfields by number of streams. These values indicate
|
||||
* which MCSes are supported for the number of streams the value appears
|
||||
* for.
|
||||
*/
|
||||
enum ieee80211_vht_mcs_support {
|
||||
IEEE80211_VHT_MCS_SUPPORT_0_7 = 0,
|
||||
IEEE80211_VHT_MCS_SUPPORT_0_8 = 1,
|
||||
IEEE80211_VHT_MCS_SUPPORT_0_9 = 2,
|
||||
IEEE80211_VHT_MCS_NOT_SUPPORTED = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ieee80211_vht_cap - VHT capabilities
|
||||
*
|
||||
|
@ -305,6 +305,88 @@ struct key_params {
|
||||
u32 cipher;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cfg80211_chan_def - channel definition
|
||||
* @chan: the (control) channel
|
||||
* @width: channel width
|
||||
* @center_freq1: center frequency of first segment
|
||||
* @center_freq2: center frequency of second segment
|
||||
* (only with 80+80 MHz)
|
||||
*/
|
||||
struct cfg80211_chan_def {
|
||||
struct ieee80211_channel *chan;
|
||||
enum nl80211_chan_width width;
|
||||
u32 center_freq1;
|
||||
u32 center_freq2;
|
||||
};
|
||||
|
||||
/**
|
||||
* cfg80211_get_chandef_type - return old channel type from chandef
|
||||
* @chandef: the channel definition
|
||||
*
|
||||
* Returns the old channel type (NOHT, HT20, HT40+/-) from a given
|
||||
* chandef, which must have a bandwidth allowing this conversion.
|
||||
*/
|
||||
static inline enum nl80211_channel_type
|
||||
cfg80211_get_chandef_type(const struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
switch (chandef->width) {
|
||||
case NL80211_CHAN_WIDTH_20_NOHT:
|
||||
return NL80211_CHAN_NO_HT;
|
||||
case NL80211_CHAN_WIDTH_20:
|
||||
return NL80211_CHAN_HT20;
|
||||
case NL80211_CHAN_WIDTH_40:
|
||||
if (chandef->center_freq1 > chandef->chan->center_freq)
|
||||
return NL80211_CHAN_HT40PLUS;
|
||||
return NL80211_CHAN_HT40MINUS;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
return NL80211_CHAN_NO_HT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* cfg80211_chandef_create - create channel definition using channel type
|
||||
* @chandef: the channel definition struct to fill
|
||||
* @channel: the control channel
|
||||
* @chantype: the channel type
|
||||
*
|
||||
* Given a channel type, create a channel definition.
|
||||
*/
|
||||
void cfg80211_chandef_create(struct cfg80211_chan_def *chandef,
|
||||
struct ieee80211_channel *channel,
|
||||
enum nl80211_channel_type chantype);
|
||||
|
||||
/**
|
||||
* cfg80211_chandef_identical - check if two channel definitions are identical
|
||||
* @chandef1: first channel definition
|
||||
* @chandef2: second channel definition
|
||||
*
|
||||
* Returns %true if the channels defined by the channel definitions are
|
||||
* identical, %false otherwise.
|
||||
*/
|
||||
static inline bool
|
||||
cfg80211_chandef_identical(const struct cfg80211_chan_def *chandef1,
|
||||
const struct cfg80211_chan_def *chandef2)
|
||||
{
|
||||
return (chandef1->chan == chandef2->chan &&
|
||||
chandef1->width == chandef2->width &&
|
||||
chandef1->center_freq1 == chandef2->center_freq1 &&
|
||||
chandef1->center_freq2 == chandef2->center_freq2);
|
||||
}
|
||||
|
||||
/**
|
||||
* cfg80211_chandef_compatible - check if two channel definitions are compatible
|
||||
* @chandef1: first channel definition
|
||||
* @chandef2: second channel definition
|
||||
*
|
||||
* Returns %NULL if the given channel definitions are incompatible,
|
||||
* chandef1 or chandef2 otherwise.
|
||||
*/
|
||||
const struct cfg80211_chan_def *
|
||||
cfg80211_chandef_compatible(const struct cfg80211_chan_def *chandef1,
|
||||
const struct cfg80211_chan_def *chandef2);
|
||||
|
||||
/**
|
||||
* enum survey_info_flags - survey information flags
|
||||
*
|
||||
@ -426,8 +508,7 @@ struct cfg80211_beacon_data {
|
||||
*
|
||||
* Used to configure an AP interface.
|
||||
*
|
||||
* @channel: the channel to start the AP on
|
||||
* @channel_type: the channel type to use
|
||||
* @chandef: defines the channel to use
|
||||
* @beacon: beacon data
|
||||
* @beacon_interval: beacon interval
|
||||
* @dtim_period: DTIM period
|
||||
@ -441,8 +522,7 @@ struct cfg80211_beacon_data {
|
||||
* @inactivity_timeout: time in seconds to determine station's inactivity.
|
||||
*/
|
||||
struct cfg80211_ap_settings {
|
||||
struct ieee80211_channel *channel;
|
||||
enum nl80211_channel_type channel_type;
|
||||
struct cfg80211_chan_def chandef;
|
||||
|
||||
struct cfg80211_beacon_data beacon;
|
||||
|
||||
@ -582,16 +662,24 @@ enum station_info_flags {
|
||||
* Used by the driver to indicate the specific rate transmission
|
||||
* type for 802.11n transmissions.
|
||||
*
|
||||
* @RATE_INFO_FLAGS_MCS: @tx_bitrate_mcs filled
|
||||
* @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 Mhz width transmission
|
||||
* @RATE_INFO_FLAGS_MCS: mcs field filled with HT MCS
|
||||
* @RATE_INFO_FLAGS_VHT_MCS: mcs field filled with VHT MCS
|
||||
* @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 MHz width transmission
|
||||
* @RATE_INFO_FLAGS_80_MHZ_WIDTH: 80 MHz width transmission
|
||||
* @RATE_INFO_FLAGS_80P80_MHZ_WIDTH: 80+80 MHz width transmission
|
||||
* @RATE_INFO_FLAGS_160_MHZ_WIDTH: 160 MHz width transmission
|
||||
* @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval
|
||||
* @RATE_INFO_FLAGS_60G: 60gHz MCS
|
||||
* @RATE_INFO_FLAGS_60G: 60GHz MCS
|
||||
*/
|
||||
enum rate_info_flags {
|
||||
RATE_INFO_FLAGS_MCS = 1<<0,
|
||||
RATE_INFO_FLAGS_40_MHZ_WIDTH = 1<<1,
|
||||
RATE_INFO_FLAGS_SHORT_GI = 1<<2,
|
||||
RATE_INFO_FLAGS_60G = 1<<3,
|
||||
RATE_INFO_FLAGS_MCS = BIT(0),
|
||||
RATE_INFO_FLAGS_VHT_MCS = BIT(1),
|
||||
RATE_INFO_FLAGS_40_MHZ_WIDTH = BIT(2),
|
||||
RATE_INFO_FLAGS_80_MHZ_WIDTH = BIT(3),
|
||||
RATE_INFO_FLAGS_80P80_MHZ_WIDTH = BIT(4),
|
||||
RATE_INFO_FLAGS_160_MHZ_WIDTH = BIT(5),
|
||||
RATE_INFO_FLAGS_SHORT_GI = BIT(6),
|
||||
RATE_INFO_FLAGS_60G = BIT(7),
|
||||
};
|
||||
|
||||
/**
|
||||
@ -602,11 +690,13 @@ enum rate_info_flags {
|
||||
* @flags: bitflag of flags from &enum rate_info_flags
|
||||
* @mcs: mcs index if struct describes a 802.11n bitrate
|
||||
* @legacy: bitrate in 100kbit/s for 802.11abg
|
||||
* @nss: number of streams (VHT only)
|
||||
*/
|
||||
struct rate_info {
|
||||
u8 flags;
|
||||
u8 mcs;
|
||||
u16 legacy;
|
||||
u8 nss;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -909,8 +999,7 @@ struct mesh_config {
|
||||
|
||||
/**
|
||||
* struct mesh_setup - 802.11s mesh setup configuration
|
||||
* @channel: the channel to start the mesh network on
|
||||
* @channel_type: the channel type to use
|
||||
* @chandef: defines the channel to use
|
||||
* @mesh_id: the mesh ID
|
||||
* @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes
|
||||
* @sync_method: which synchronization method to use
|
||||
@ -925,8 +1014,7 @@ struct mesh_config {
|
||||
* These parameters are fixed when the mesh is created.
|
||||
*/
|
||||
struct mesh_setup {
|
||||
struct ieee80211_channel *channel;
|
||||
enum nl80211_channel_type channel_type;
|
||||
struct cfg80211_chan_def chandef;
|
||||
const u8 *mesh_id;
|
||||
u8 mesh_id_len;
|
||||
u8 sync_method;
|
||||
@ -1266,8 +1354,7 @@ struct cfg80211_disassoc_request {
|
||||
* @ssid_len: The length of the SSID, will always be non-zero.
|
||||
* @bssid: Fixed BSSID requested, maybe be %NULL, if set do not
|
||||
* search for IBSSs with a different BSSID.
|
||||
* @channel: The channel to use if no IBSS can be found to join.
|
||||
* @channel_type: channel type (HT mode)
|
||||
* @chandef: defines the channel to use if no other IBSS to join can be found
|
||||
* @channel_fixed: The channel should be fixed -- do not search for
|
||||
* IBSSs to join on other channels.
|
||||
* @ie: information element(s) to include in the beacon
|
||||
@ -1285,8 +1372,7 @@ struct cfg80211_disassoc_request {
|
||||
struct cfg80211_ibss_params {
|
||||
u8 *ssid;
|
||||
u8 *bssid;
|
||||
struct ieee80211_channel *channel;
|
||||
enum nl80211_channel_type channel_type;
|
||||
struct cfg80211_chan_def chandef;
|
||||
u8 *ie;
|
||||
u8 ssid_len, ie_len;
|
||||
u16 beacon_interval;
|
||||
@ -1728,8 +1814,7 @@ struct cfg80211_ops {
|
||||
struct ieee80211_channel *chan);
|
||||
|
||||
int (*set_monitor_channel)(struct wiphy *wiphy,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type);
|
||||
struct cfg80211_chan_def *chandef);
|
||||
|
||||
int (*scan)(struct wiphy *wiphy,
|
||||
struct cfg80211_scan_request *request);
|
||||
@ -1791,7 +1876,6 @@ struct cfg80211_ops {
|
||||
int (*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);
|
||||
int (*cancel_remain_on_channel)(struct wiphy *wiphy,
|
||||
@ -1800,10 +1884,8 @@ struct cfg80211_ops {
|
||||
|
||||
int (*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);
|
||||
int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev,
|
||||
u64 cookie);
|
||||
@ -1858,10 +1940,9 @@ struct cfg80211_ops {
|
||||
void (*get_et_strings)(struct wiphy *wiphy, struct net_device *dev,
|
||||
u32 sset, u8 *data);
|
||||
|
||||
struct ieee80211_channel *
|
||||
(*get_channel)(struct wiphy *wiphy,
|
||||
int (*get_channel)(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev,
|
||||
enum nl80211_channel_type *type);
|
||||
struct cfg80211_chan_def *chandef);
|
||||
|
||||
int (*start_p2p_device)(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev);
|
||||
@ -2469,8 +2550,7 @@ struct wireless_dev {
|
||||
spinlock_t event_lock;
|
||||
|
||||
struct cfg80211_internal_bss *current_bss; /* associated / joined */
|
||||
struct ieee80211_channel *preset_chan;
|
||||
enum nl80211_channel_type preset_chantype;
|
||||
struct cfg80211_chan_def preset_chandef;
|
||||
|
||||
/* for AP and mesh channel tracking */
|
||||
struct ieee80211_channel *channel;
|
||||
@ -3350,14 +3430,12 @@ void cfg80211_disconnected(struct net_device *dev, u16 reason,
|
||||
* @wdev: wireless device
|
||||
* @cookie: the request cookie
|
||||
* @chan: The current channel (from remain_on_channel request)
|
||||
* @channel_type: Channel type
|
||||
* @duration: Duration in milliseconds that the driver intents to remain on the
|
||||
* channel
|
||||
* @gfp: allocation flags
|
||||
*/
|
||||
void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type,
|
||||
unsigned int duration, gfp_t gfp);
|
||||
|
||||
/**
|
||||
@ -3365,12 +3443,10 @@ void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
|
||||
* @wdev: wireless device
|
||||
* @cookie: the request cookie
|
||||
* @chan: The current channel (from remain_on_channel request)
|
||||
* @channel_type: Channel type
|
||||
* @gfp: allocation flags
|
||||
*/
|
||||
void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type,
|
||||
gfp_t gfp);
|
||||
|
||||
|
||||
@ -3570,28 +3646,25 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy,
|
||||
int freq, int sig_dbm);
|
||||
|
||||
/**
|
||||
* cfg80211_can_beacon_sec_chan - test if ht40 on extension channel can be used
|
||||
* cfg80211_reg_can_beacon - check if beaconing is allowed
|
||||
* @wiphy: the wiphy
|
||||
* @chan: main channel
|
||||
* @channel_type: HT mode
|
||||
* @chandef: the channel definition
|
||||
*
|
||||
* This function returns true if there is no secondary channel or the secondary
|
||||
* channel can be used for beaconing (i.e. is not a radar channel etc.)
|
||||
* channel(s) can be used for beaconing (i.e. is not a radar channel etc.)
|
||||
*/
|
||||
bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type);
|
||||
bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
|
||||
struct cfg80211_chan_def *chandef);
|
||||
|
||||
/*
|
||||
* cfg80211_ch_switch_notify - update wdev channel and notify userspace
|
||||
* @dev: the device which switched channels
|
||||
* @freq: new channel frequency (in MHz)
|
||||
* @type: channel type
|
||||
* @chandef: the new channel definition
|
||||
*
|
||||
* Acquires wdev_lock, so must only be called from sleepable driver context!
|
||||
*/
|
||||
void cfg80211_ch_switch_notify(struct net_device *dev, int freq,
|
||||
enum nl80211_channel_type type);
|
||||
void cfg80211_ch_switch_notify(struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef);
|
||||
|
||||
/*
|
||||
* cfg80211_tdls_oper_request - request userspace to perform TDLS operation
|
||||
@ -3652,8 +3725,9 @@ void cfg80211_unregister_wdev(struct wireless_dev *wdev);
|
||||
* the data is malformed or the attribute can't be found (respectively),
|
||||
* or the length of the found attribute (which can be zero).
|
||||
*/
|
||||
unsigned int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len,
|
||||
u8 attr, u8 *buf, unsigned int bufsize);
|
||||
int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len,
|
||||
enum ieee80211_p2p_attr_id attr,
|
||||
u8 *buf, unsigned int bufsize);
|
||||
|
||||
/* Logging, debugging and troubleshooting/diagnostic helpers. */
|
||||
|
||||
|
@ -145,11 +145,11 @@ struct ieee80211_low_level_stats {
|
||||
|
||||
/**
|
||||
* enum ieee80211_chanctx_change - change flag for channel context
|
||||
* @IEEE80211_CHANCTX_CHANGE_CHANNEL_TYPE: The channel type was changed
|
||||
* @IEEE80211_CHANCTX_CHANGE_WIDTH: The channel width changed
|
||||
* @IEEE80211_CHANCTX_CHANGE_RX_CHAINS: The number of RX chains changed
|
||||
*/
|
||||
enum ieee80211_chanctx_change {
|
||||
IEEE80211_CHANCTX_CHANGE_CHANNEL_TYPE = BIT(0),
|
||||
IEEE80211_CHANCTX_CHANGE_WIDTH = BIT(0),
|
||||
IEEE80211_CHANCTX_CHANGE_RX_CHAINS = BIT(1),
|
||||
};
|
||||
|
||||
@ -159,8 +159,7 @@ enum ieee80211_chanctx_change {
|
||||
* This is the driver-visible part. The ieee80211_chanctx
|
||||
* that contains it is visible in mac80211 only.
|
||||
*
|
||||
* @channel: the channel to tune to
|
||||
* @channel_type: the channel (HT) type
|
||||
* @def: the channel definition
|
||||
* @rx_chains_static: The number of RX chains that must always be
|
||||
* active on the channel to receive MIMO transmissions
|
||||
* @rx_chains_dynamic: The number of RX chains that must be enabled
|
||||
@ -170,8 +169,7 @@ enum ieee80211_chanctx_change {
|
||||
* sizeof(void *), size is determined in hw information.
|
||||
*/
|
||||
struct ieee80211_chanctx_conf {
|
||||
struct ieee80211_channel *channel;
|
||||
enum nl80211_channel_type channel_type;
|
||||
struct cfg80211_chan_def def;
|
||||
|
||||
u8 rx_chains_static, rx_chains_dynamic;
|
||||
|
||||
@ -288,9 +286,8 @@ enum ieee80211_rssi_event {
|
||||
* @mcast_rate: per-band multicast rate index + 1 (0: disabled)
|
||||
* @bssid: The BSSID for this BSS
|
||||
* @enable_beacon: whether beaconing should be enabled or not
|
||||
* @channel_type: Channel type for this BSS -- the hardware might be
|
||||
* configured for HT40+ while this BSS only uses no-HT, for
|
||||
* example.
|
||||
* @chandef: Channel definition for this BSS -- the hardware might be
|
||||
* configured a higher bandwidth than this BSS uses, for example.
|
||||
* @ht_operation_mode: HT operation mode like in &struct ieee80211_ht_operation.
|
||||
* This field is only valid when the channel type is one of the HT types.
|
||||
* @cqm_rssi_thold: Connection quality monitor RSSI threshold, a zero value
|
||||
@ -339,7 +336,7 @@ struct ieee80211_bss_conf {
|
||||
u16 ht_operation_mode;
|
||||
s32 cqm_rssi_thold;
|
||||
u32 cqm_rssi_hyst;
|
||||
enum nl80211_channel_type channel_type;
|
||||
struct cfg80211_chan_def chandef;
|
||||
__be32 arp_addr_list[IEEE80211_BSS_ARP_ADDR_LIST_LEN];
|
||||
u8 arp_addr_cnt;
|
||||
bool arp_filter_enabled;
|
||||
@ -502,9 +499,14 @@ enum mac80211_tx_control_flags {
|
||||
* This is set if the current BSS requires ERP protection.
|
||||
* @IEEE80211_TX_RC_USE_SHORT_PREAMBLE: Use short preamble.
|
||||
* @IEEE80211_TX_RC_MCS: HT rate.
|
||||
* @IEEE80211_TX_RC_VHT_MCS: VHT MCS rate, in this case the idx field is split
|
||||
* into a higher 4 bits (Nss) and lower 4 bits (MCS number)
|
||||
* @IEEE80211_TX_RC_GREEN_FIELD: Indicates whether this rate should be used in
|
||||
* Greenfield mode.
|
||||
* @IEEE80211_TX_RC_40_MHZ_WIDTH: Indicates if the Channel Width should be 40 MHz.
|
||||
* @IEEE80211_TX_RC_80_MHZ_WIDTH: Indicates 80 MHz transmission
|
||||
* @IEEE80211_TX_RC_160_MHZ_WIDTH: Indicates 160 MHz transmission
|
||||
* (80+80 isn't supported yet)
|
||||
* @IEEE80211_TX_RC_DUP_DATA: The frame should be transmitted on both of the
|
||||
* adjacent 20 MHz channels, if the current channel type is
|
||||
* NL80211_CHAN_HT40MINUS or NL80211_CHAN_HT40PLUS.
|
||||
@ -515,12 +517,15 @@ enum mac80211_rate_control_flags {
|
||||
IEEE80211_TX_RC_USE_CTS_PROTECT = BIT(1),
|
||||
IEEE80211_TX_RC_USE_SHORT_PREAMBLE = BIT(2),
|
||||
|
||||
/* rate index is an MCS rate number instead of an index */
|
||||
/* rate index is an HT/VHT MCS instead of an index */
|
||||
IEEE80211_TX_RC_MCS = BIT(3),
|
||||
IEEE80211_TX_RC_GREEN_FIELD = BIT(4),
|
||||
IEEE80211_TX_RC_40_MHZ_WIDTH = BIT(5),
|
||||
IEEE80211_TX_RC_DUP_DATA = BIT(6),
|
||||
IEEE80211_TX_RC_SHORT_GI = BIT(7),
|
||||
IEEE80211_TX_RC_VHT_MCS = BIT(8),
|
||||
IEEE80211_TX_RC_80_MHZ_WIDTH = BIT(9),
|
||||
IEEE80211_TX_RC_160_MHZ_WIDTH = BIT(10),
|
||||
};
|
||||
|
||||
|
||||
@ -563,10 +568,32 @@ enum mac80211_rate_control_flags {
|
||||
*/
|
||||
struct ieee80211_tx_rate {
|
||||
s8 idx;
|
||||
u8 count;
|
||||
u8 flags;
|
||||
u16 count:5,
|
||||
flags:11;
|
||||
} __packed;
|
||||
|
||||
#define IEEE80211_MAX_TX_RETRY 31
|
||||
|
||||
static inline void ieee80211_rate_set_vht(struct ieee80211_tx_rate *rate,
|
||||
u8 mcs, u8 nss)
|
||||
{
|
||||
WARN_ON(mcs & ~0xF);
|
||||
WARN_ON(nss & ~0x7);
|
||||
rate->idx = (nss << 4) | mcs;
|
||||
}
|
||||
|
||||
static inline u8
|
||||
ieee80211_rate_get_vht_mcs(const struct ieee80211_tx_rate *rate)
|
||||
{
|
||||
return rate->idx & 0xF;
|
||||
}
|
||||
|
||||
static inline u8
|
||||
ieee80211_rate_get_vht_nss(const struct ieee80211_tx_rate *rate)
|
||||
{
|
||||
return rate->idx >> 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* struct ieee80211_tx_info - skb transmit information
|
||||
*
|
||||
@ -720,7 +747,11 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
|
||||
* (including FCS) was received.
|
||||
* @RX_FLAG_SHORTPRE: Short preamble was used for this frame
|
||||
* @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index
|
||||
* @RX_FLAG_VHT: VHT MCS was used and rate_index is MCS index
|
||||
* @RX_FLAG_40MHZ: HT40 (40 MHz) was used
|
||||
* @RX_FLAG_80MHZ: 80 MHz was used
|
||||
* @RX_FLAG_80P80MHZ: 80+80 MHz was used
|
||||
* @RX_FLAG_160MHZ: 160 MHz was used
|
||||
* @RX_FLAG_SHORT_GI: Short guard interval was used
|
||||
* @RX_FLAG_NO_SIGNAL_VAL: The signal strength value is not present.
|
||||
* Valid only for data frames (mainly A-MPDU)
|
||||
@ -763,6 +794,10 @@ enum mac80211_rx_flags {
|
||||
RX_FLAG_AMPDU_DELIM_CRC_ERROR = BIT(19),
|
||||
RX_FLAG_AMPDU_DELIM_CRC_KNOWN = BIT(20),
|
||||
RX_FLAG_MACTIME_END = BIT(21),
|
||||
RX_FLAG_VHT = BIT(22),
|
||||
RX_FLAG_80MHZ = BIT(23),
|
||||
RX_FLAG_80P80MHZ = BIT(24),
|
||||
RX_FLAG_160MHZ = BIT(25),
|
||||
};
|
||||
|
||||
/**
|
||||
@ -783,7 +818,8 @@ enum mac80211_rx_flags {
|
||||
* @IEEE80211_HW_SIGNAL_*
|
||||
* @antenna: antenna used
|
||||
* @rate_idx: index of data rate into band's supported rates or MCS index if
|
||||
* HT rates are use (RX_FLAG_HT)
|
||||
* HT or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT)
|
||||
* @vht_nss: number of streams (VHT only)
|
||||
* @flag: %RX_FLAG_*
|
||||
* @rx_flags: internal RX flags for mac80211
|
||||
* @ampdu_reference: A-MPDU reference number, must be a different value for
|
||||
@ -806,6 +842,7 @@ struct ieee80211_rx_status {
|
||||
u16 vendor_radiotap_len;
|
||||
u16 freq;
|
||||
u8 rate_idx;
|
||||
u8 vht_nss;
|
||||
u8 rx_flags;
|
||||
u8 band;
|
||||
u8 antenna;
|
||||
@ -2550,7 +2587,6 @@ struct ieee80211_ops {
|
||||
int (*remain_on_channel)(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type,
|
||||
int duration);
|
||||
int (*cancel_remain_on_channel)(struct ieee80211_hw *hw);
|
||||
int (*set_ringparam)(struct ieee80211_hw *hw, u32 tx, u32 rx);
|
||||
|
@ -118,8 +118,9 @@
|
||||
* to get a list of all present wiphys.
|
||||
* @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or
|
||||
* %NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME,
|
||||
* %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ,
|
||||
* %NL80211_ATTR_WIPHY_CHANNEL_TYPE, %NL80211_ATTR_WIPHY_RETRY_SHORT,
|
||||
* %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ (and the
|
||||
* attributes determining the channel width; this is used for setting
|
||||
* monitor mode channel), %NL80211_ATTR_WIPHY_RETRY_SHORT,
|
||||
* %NL80211_ATTR_WIPHY_RETRY_LONG, %NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
|
||||
* and/or %NL80211_ATTR_WIPHY_RTS_THRESHOLD.
|
||||
* However, for setting the channel, see %NL80211_CMD_SET_CHANNEL
|
||||
@ -171,7 +172,7 @@
|
||||
* %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY,
|
||||
* %NL80211_ATTR_AUTH_TYPE and %NL80211_ATTR_INACTIVITY_TIMEOUT.
|
||||
* The channel to use can be set on the interface or be given using the
|
||||
* %NL80211_ATTR_WIPHY_FREQ and %NL80211_ATTR_WIPHY_CHANNEL_TYPE attrs.
|
||||
* %NL80211_ATTR_WIPHY_FREQ and the attributes determining channel width.
|
||||
* @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP
|
||||
* @NL80211_CMD_STOP_AP: Stop AP operation on the given interface
|
||||
* @NL80211_CMD_DEL_BEACON: old alias for %NL80211_CMD_STOP_AP
|
||||
@ -401,8 +402,7 @@
|
||||
* a response while being associated to an AP on another channel.
|
||||
* %NL80211_ATTR_IFINDEX is used to specify which interface (and thus
|
||||
* radio) is used. %NL80211_ATTR_WIPHY_FREQ is used to specify the
|
||||
* frequency for the operation and %NL80211_ATTR_WIPHY_CHANNEL_TYPE may be
|
||||
* optionally used to specify additional channel parameters.
|
||||
* frequency for the operation.
|
||||
* %NL80211_ATTR_DURATION is used to specify the duration in milliseconds
|
||||
* to remain on the channel. This command is also used as an event to
|
||||
* notify when the requested duration starts (it may take a while for the
|
||||
@ -440,12 +440,11 @@
|
||||
* as an event indicating reception of a frame that was not processed in
|
||||
* kernel code, but is for us (i.e., which may need to be processed in a
|
||||
* user space application). %NL80211_ATTR_FRAME is used to specify the
|
||||
* frame contents (including header). %NL80211_ATTR_WIPHY_FREQ (and
|
||||
* optionally %NL80211_ATTR_WIPHY_CHANNEL_TYPE) is used to indicate on
|
||||
* which channel the frame is to be transmitted or was received. If this
|
||||
* channel is not the current channel (remain-on-channel or the
|
||||
* operational channel) the device will switch to the given channel and
|
||||
* transmit the frame, optionally waiting for a response for the time
|
||||
* frame contents (including header). %NL80211_ATTR_WIPHY_FREQ is used
|
||||
* to indicate on which channel the frame is to be transmitted or was
|
||||
* received. If this channel is not the current channel (remain-on-channel
|
||||
* or the operational channel) the device will switch to the given channel
|
||||
* and transmit the frame, optionally waiting for a response for the time
|
||||
* specified using %NL80211_ATTR_DURATION. When called, this operation
|
||||
* returns a cookie (%NL80211_ATTR_COOKIE) that will be included with the
|
||||
* TX status event pertaining to the TX request.
|
||||
@ -473,8 +472,8 @@
|
||||
* command is used as an event to indicate the that a trigger level was
|
||||
* reached.
|
||||
* @NL80211_CMD_SET_CHANNEL: Set the channel (using %NL80211_ATTR_WIPHY_FREQ
|
||||
* and %NL80211_ATTR_WIPHY_CHANNEL_TYPE) the given interface (identifed
|
||||
* by %NL80211_ATTR_IFINDEX) shall operate on.
|
||||
* and the attributes determining channel width) the given interface
|
||||
* (identifed by %NL80211_ATTR_IFINDEX) shall operate on.
|
||||
* In case multiple channels are supported by the device, the mechanism
|
||||
* with which it switches channels is implementation-defined.
|
||||
* When a monitor interface is given, it can only switch channel while
|
||||
@ -568,8 +567,8 @@
|
||||
*
|
||||
* @NL80211_CMD_CH_SWITCH_NOTIFY: An AP or GO may decide to switch channels
|
||||
* independently of the userspace SME, send this event indicating
|
||||
* %NL80211_ATTR_IFINDEX is now on %NL80211_ATTR_WIPHY_FREQ with
|
||||
* %NL80211_ATTR_WIPHY_CHANNEL_TYPE.
|
||||
* %NL80211_ATTR_IFINDEX is now on %NL80211_ATTR_WIPHY_FREQ and the
|
||||
* attributes determining channel width.
|
||||
*
|
||||
* @NL80211_CMD_START_P2P_DEVICE: Start the given P2P Device, identified by
|
||||
* its %NL80211_ATTR_WDEV identifier. It must have been created with
|
||||
@ -773,14 +772,26 @@ enum nl80211_commands {
|
||||
* /sys/class/ieee80211/<phyname>/index
|
||||
* @NL80211_ATTR_WIPHY_NAME: wiphy name (used for renaming)
|
||||
* @NL80211_ATTR_WIPHY_TXQ_PARAMS: a nested array of TX queue parameters
|
||||
* @NL80211_ATTR_WIPHY_FREQ: frequency of the selected channel in MHz
|
||||
* @NL80211_ATTR_WIPHY_FREQ: frequency of the selected channel in MHz,
|
||||
* defines the channel together with the (deprecated)
|
||||
* %NL80211_ATTR_WIPHY_CHANNEL_TYPE attribute or the attributes
|
||||
* %NL80211_ATTR_CHANNEL_WIDTH and if needed %NL80211_ATTR_CENTER_FREQ1
|
||||
* and %NL80211_ATTR_CENTER_FREQ2
|
||||
* @NL80211_ATTR_CHANNEL_WIDTH: u32 attribute containing one of the values
|
||||
* of &enum nl80211_chan_width, describing the channel width. See the
|
||||
* documentation of the enum for more information.
|
||||
* @NL80211_ATTR_CENTER_FREQ1: Center frequency of the first part of the
|
||||
* channel, used for anything but 20 MHz bandwidth
|
||||
* @NL80211_ATTR_CENTER_FREQ2: Center frequency of the second part of the
|
||||
* channel, used only for 80+80 MHz bandwidth
|
||||
* @NL80211_ATTR_WIPHY_CHANNEL_TYPE: included with NL80211_ATTR_WIPHY_FREQ
|
||||
* if HT20 or HT40 are allowed (i.e., 802.11n disabled if not included):
|
||||
* if HT20 or HT40 are to be used (i.e., HT disabled if not included):
|
||||
* NL80211_CHAN_NO_HT = HT not allowed (i.e., same as not including
|
||||
* this attribute)
|
||||
* NL80211_CHAN_HT20 = HT20 only
|
||||
* NL80211_CHAN_HT40MINUS = secondary channel is below the primary channel
|
||||
* NL80211_CHAN_HT40PLUS = secondary channel is above the primary channel
|
||||
* This attribute is now deprecated.
|
||||
* @NL80211_ATTR_WIPHY_RETRY_SHORT: TX retry limit for frames whose length is
|
||||
* less than or equal to the RTS threshold; allowed range: 1..255;
|
||||
* dot11ShortRetryLimit; u8
|
||||
@ -1555,6 +1566,10 @@ enum nl80211_attrs {
|
||||
|
||||
NL80211_ATTR_SCAN_FLAGS,
|
||||
|
||||
NL80211_ATTR_CHANNEL_WIDTH,
|
||||
NL80211_ATTR_CENTER_FREQ1,
|
||||
NL80211_ATTR_CENTER_FREQ2,
|
||||
|
||||
/* add attributes here, update the policy in nl80211.c */
|
||||
|
||||
__NL80211_ATTR_AFTER_LAST,
|
||||
@ -1719,10 +1734,15 @@ struct nl80211_sta_flag_update {
|
||||
* @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved
|
||||
* @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s)
|
||||
* @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8)
|
||||
* @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate
|
||||
* @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 MHz dualchannel bitrate
|
||||
* @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval
|
||||
* @NL80211_RATE_INFO_BITRATE32: total bitrate (u32, 100kbit/s)
|
||||
* @NL80211_RATE_INFO_MAX: highest rate_info number currently defined
|
||||
* @NL80211_RATE_INFO_VHT_MCS: MCS index for VHT (u8)
|
||||
* @NL80211_RATE_INFO_VHT_NSS: number of streams in VHT (u8)
|
||||
* @NL80211_RATE_INFO_80_MHZ_WIDTH: 80 MHz VHT rate
|
||||
* @NL80211_RATE_INFO_80P80_MHZ_WIDTH: 80+80 MHz VHT rate
|
||||
* @NL80211_RATE_INFO_160_MHZ_WIDTH: 160 MHz VHT rate
|
||||
* @__NL80211_RATE_INFO_AFTER_LAST: internal use
|
||||
*/
|
||||
enum nl80211_rate_info {
|
||||
@ -1732,6 +1752,11 @@ enum nl80211_rate_info {
|
||||
NL80211_RATE_INFO_40_MHZ_WIDTH,
|
||||
NL80211_RATE_INFO_SHORT_GI,
|
||||
NL80211_RATE_INFO_BITRATE32,
|
||||
NL80211_RATE_INFO_VHT_MCS,
|
||||
NL80211_RATE_INFO_VHT_NSS,
|
||||
NL80211_RATE_INFO_80_MHZ_WIDTH,
|
||||
NL80211_RATE_INFO_80P80_MHZ_WIDTH,
|
||||
NL80211_RATE_INFO_160_MHZ_WIDTH,
|
||||
|
||||
/* keep last */
|
||||
__NL80211_RATE_INFO_AFTER_LAST,
|
||||
@ -2440,6 +2465,15 @@ enum nl80211_ac {
|
||||
#define NL80211_TXQ_Q_BE NL80211_AC_BE
|
||||
#define NL80211_TXQ_Q_BK NL80211_AC_BK
|
||||
|
||||
/**
|
||||
* enum nl80211_channel_type - channel type
|
||||
* @NL80211_CHAN_NO_HT: 20 MHz, non-HT channel
|
||||
* @NL80211_CHAN_HT20: 20 MHz HT channel
|
||||
* @NL80211_CHAN_HT40MINUS: HT40 channel, secondary channel
|
||||
* below the control channel
|
||||
* @NL80211_CHAN_HT40PLUS: HT40 channel, secondary channel
|
||||
* above the control channel
|
||||
*/
|
||||
enum nl80211_channel_type {
|
||||
NL80211_CHAN_NO_HT,
|
||||
NL80211_CHAN_HT20,
|
||||
@ -2447,6 +2481,32 @@ enum nl80211_channel_type {
|
||||
NL80211_CHAN_HT40PLUS
|
||||
};
|
||||
|
||||
/**
|
||||
* enum nl80211_chan_width - channel width definitions
|
||||
*
|
||||
* These values are used with the %NL80211_ATTR_CHANNEL_WIDTH
|
||||
* attribute.
|
||||
*
|
||||
* @NL80211_CHAN_WIDTH_20_NOHT: 20 MHz, non-HT channel
|
||||
* @NL80211_CHAN_WIDTH_20: 20 MHz HT channel
|
||||
* @NL80211_CHAN_WIDTH_40: 40 MHz channel, the %NL80211_ATTR_CENTER_FREQ1
|
||||
* attribute must be provided as well
|
||||
* @NL80211_CHAN_WIDTH_80: 80 MHz channel, the %NL80211_ATTR_CENTER_FREQ1
|
||||
* attribute must be provided as well
|
||||
* @NL80211_CHAN_WIDTH_80P80: 80+80 MHz channel, the %NL80211_ATTR_CENTER_FREQ1
|
||||
* and %NL80211_ATTR_CENTER_FREQ2 attributes must be provided as well
|
||||
* @NL80211_CHAN_WIDTH_160: 160 MHz channel, the %NL80211_ATTR_CENTER_FREQ1
|
||||
* attribute must be provided as well
|
||||
*/
|
||||
enum nl80211_chan_width {
|
||||
NL80211_CHAN_WIDTH_20_NOHT,
|
||||
NL80211_CHAN_WIDTH_20,
|
||||
NL80211_CHAN_WIDTH_40,
|
||||
NL80211_CHAN_WIDTH_80,
|
||||
NL80211_CHAN_WIDTH_80P80,
|
||||
NL80211_CHAN_WIDTH_160,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum nl80211_bss - netlink attributes for a BSS
|
||||
*
|
||||
|
@ -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
|
||||
|
@ -8,93 +8,47 @@
|
||||
#include "ieee80211_i.h"
|
||||
#include "driver-ops.h"
|
||||
|
||||
static bool
|
||||
ieee80211_channel_types_are_compatible(enum nl80211_channel_type chantype1,
|
||||
enum nl80211_channel_type chantype2,
|
||||
enum nl80211_channel_type *compat)
|
||||
static void ieee80211_change_chandef(struct ieee80211_local *local,
|
||||
struct ieee80211_chanctx *ctx,
|
||||
const struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
/*
|
||||
* start out with chantype1 being the result,
|
||||
* overwriting later if needed
|
||||
*/
|
||||
if (compat)
|
||||
*compat = chantype1;
|
||||
|
||||
switch (chantype1) {
|
||||
case NL80211_CHAN_NO_HT:
|
||||
if (compat)
|
||||
*compat = chantype2;
|
||||
break;
|
||||
case NL80211_CHAN_HT20:
|
||||
/*
|
||||
* allow any change that doesn't go to no-HT
|
||||
* (if it already is no-HT no change is needed)
|
||||
*/
|
||||
if (chantype2 == NL80211_CHAN_NO_HT)
|
||||
break;
|
||||
if (compat)
|
||||
*compat = chantype2;
|
||||
break;
|
||||
case NL80211_CHAN_HT40PLUS:
|
||||
case NL80211_CHAN_HT40MINUS:
|
||||
/* allow smaller bandwidth and same */
|
||||
if (chantype2 == NL80211_CHAN_NO_HT)
|
||||
break;
|
||||
if (chantype2 == NL80211_CHAN_HT20)
|
||||
break;
|
||||
if (chantype2 == chantype1)
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ieee80211_change_chantype(struct ieee80211_local *local,
|
||||
struct ieee80211_chanctx *ctx,
|
||||
enum nl80211_channel_type chantype)
|
||||
{
|
||||
if (chantype == ctx->conf.channel_type)
|
||||
if (cfg80211_chandef_identical(&ctx->conf.def, chandef))
|
||||
return;
|
||||
|
||||
ctx->conf.channel_type = chantype;
|
||||
drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_CHANNEL_TYPE);
|
||||
WARN_ON(!cfg80211_chandef_compatible(&ctx->conf.def, chandef));
|
||||
|
||||
ctx->conf.def = *chandef;
|
||||
drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_WIDTH);
|
||||
|
||||
if (!local->use_chanctx) {
|
||||
local->_oper_channel_type = chantype;
|
||||
local->_oper_channel_type = cfg80211_get_chandef_type(chandef);
|
||||
ieee80211_hw_config(local, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static struct ieee80211_chanctx *
|
||||
ieee80211_find_chanctx(struct ieee80211_local *local,
|
||||
struct ieee80211_channel *channel,
|
||||
enum nl80211_channel_type channel_type,
|
||||
const struct cfg80211_chan_def *chandef,
|
||||
enum ieee80211_chanctx_mode mode)
|
||||
{
|
||||
struct ieee80211_chanctx *ctx;
|
||||
enum nl80211_channel_type compat_type;
|
||||
|
||||
lockdep_assert_held(&local->chanctx_mtx);
|
||||
|
||||
if (mode == IEEE80211_CHANCTX_EXCLUSIVE)
|
||||
return NULL;
|
||||
if (WARN_ON(!channel))
|
||||
return NULL;
|
||||
|
||||
list_for_each_entry(ctx, &local->chanctx_list, list) {
|
||||
compat_type = ctx->conf.channel_type;
|
||||
const struct cfg80211_chan_def *compat;
|
||||
|
||||
if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE)
|
||||
continue;
|
||||
if (ctx->conf.channel != channel)
|
||||
continue;
|
||||
if (!ieee80211_channel_types_are_compatible(ctx->conf.channel_type,
|
||||
channel_type,
|
||||
&compat_type))
|
||||
|
||||
compat = cfg80211_chandef_compatible(&ctx->conf.def, chandef);
|
||||
if (!compat)
|
||||
continue;
|
||||
|
||||
ieee80211_change_chantype(local, ctx, compat_type);
|
||||
ieee80211_change_chandef(local, ctx, compat);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
@ -104,8 +58,7 @@ ieee80211_find_chanctx(struct ieee80211_local *local,
|
||||
|
||||
static struct ieee80211_chanctx *
|
||||
ieee80211_new_chanctx(struct ieee80211_local *local,
|
||||
struct ieee80211_channel *channel,
|
||||
enum nl80211_channel_type channel_type,
|
||||
const struct cfg80211_chan_def *chandef,
|
||||
enum ieee80211_chanctx_mode mode)
|
||||
{
|
||||
struct ieee80211_chanctx *ctx;
|
||||
@ -117,15 +70,15 @@ ieee80211_new_chanctx(struct ieee80211_local *local,
|
||||
if (!ctx)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ctx->conf.channel = channel;
|
||||
ctx->conf.channel_type = channel_type;
|
||||
ctx->conf.def = *chandef;
|
||||
ctx->conf.rx_chains_static = 1;
|
||||
ctx->conf.rx_chains_dynamic = 1;
|
||||
ctx->mode = mode;
|
||||
|
||||
if (!local->use_chanctx) {
|
||||
local->_oper_channel_type = channel_type;
|
||||
local->_oper_channel = channel;
|
||||
local->_oper_channel_type =
|
||||
cfg80211_get_chandef_type(chandef);
|
||||
local->_oper_channel = chandef->chan;
|
||||
ieee80211_hw_config(local, 0);
|
||||
} else {
|
||||
err = drv_add_chanctx(local, ctx);
|
||||
@ -178,41 +131,37 @@ static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum nl80211_channel_type
|
||||
ieee80211_calc_chantype(struct ieee80211_local *local,
|
||||
struct ieee80211_chanctx *ctx)
|
||||
static void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local,
|
||||
struct ieee80211_chanctx *ctx)
|
||||
{
|
||||
struct ieee80211_chanctx_conf *conf = &ctx->conf;
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
enum nl80211_channel_type result = NL80211_CHAN_NO_HT;
|
||||
const struct cfg80211_chan_def *compat = NULL;
|
||||
|
||||
lockdep_assert_held(&local->chanctx_mtx);
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
|
||||
|
||||
if (!ieee80211_sdata_running(sdata))
|
||||
continue;
|
||||
if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf)
|
||||
continue;
|
||||
|
||||
WARN_ON_ONCE(!ieee80211_channel_types_are_compatible(
|
||||
sdata->vif.bss_conf.channel_type,
|
||||
result, &result));
|
||||
if (!compat)
|
||||
compat = &sdata->vif.bss_conf.chandef;
|
||||
|
||||
compat = cfg80211_chandef_compatible(
|
||||
&sdata->vif.bss_conf.chandef, compat);
|
||||
if (!compat)
|
||||
break;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
return result;
|
||||
}
|
||||
if (WARN_ON_ONCE(!compat))
|
||||
return;
|
||||
|
||||
static void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local,
|
||||
struct ieee80211_chanctx *ctx)
|
||||
{
|
||||
enum nl80211_channel_type chantype;
|
||||
|
||||
lockdep_assert_held(&local->chanctx_mtx);
|
||||
|
||||
chantype = ieee80211_calc_chantype(local, ctx);
|
||||
ieee80211_change_chantype(local, ctx, chantype);
|
||||
ieee80211_change_chandef(local, ctx, compat);
|
||||
}
|
||||
|
||||
static void ieee80211_unassign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
|
||||
@ -337,8 +286,7 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
|
||||
}
|
||||
|
||||
int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_channel *channel,
|
||||
enum nl80211_channel_type channel_type,
|
||||
const struct cfg80211_chan_def *chandef,
|
||||
enum ieee80211_chanctx_mode mode)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
@ -350,15 +298,15 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
|
||||
mutex_lock(&local->chanctx_mtx);
|
||||
__ieee80211_vif_release_channel(sdata);
|
||||
|
||||
ctx = ieee80211_find_chanctx(local, channel, channel_type, mode);
|
||||
ctx = ieee80211_find_chanctx(local, chandef, mode);
|
||||
if (!ctx)
|
||||
ctx = ieee80211_new_chanctx(local, channel, channel_type, mode);
|
||||
ctx = ieee80211_new_chanctx(local, chandef, mode);
|
||||
if (IS_ERR(ctx)) {
|
||||
ret = PTR_ERR(ctx);
|
||||
goto out;
|
||||
}
|
||||
|
||||
sdata->vif.bss_conf.channel_type = channel_type;
|
||||
sdata->vif.bss_conf.chandef = *chandef;
|
||||
|
||||
ret = ieee80211_assign_vif_chanctx(sdata, ctx);
|
||||
if (ret) {
|
||||
|
@ -168,7 +168,6 @@ IEEE80211_IF_FILE(rc_rateidx_mcs_mask_5ghz,
|
||||
|
||||
IEEE80211_IF_FILE(flags, flags, HEX);
|
||||
IEEE80211_IF_FILE(state, state, LHEX);
|
||||
IEEE80211_IF_FILE(channel_type, vif.bss_conf.channel_type, DEC);
|
||||
IEEE80211_IF_FILE(txpower, vif.bss_conf.txpower, DEC);
|
||||
IEEE80211_IF_FILE(ap_power_level, ap_power_level, DEC);
|
||||
IEEE80211_IF_FILE(user_power_level, user_power_level, DEC);
|
||||
@ -632,7 +631,6 @@ static void add_files(struct ieee80211_sub_if_data *sdata)
|
||||
|
||||
DEBUGFS_ADD(flags);
|
||||
DEBUGFS_ADD(state);
|
||||
DEBUGFS_ADD(channel_type);
|
||||
DEBUGFS_ADD(txpower);
|
||||
DEBUGFS_ADD(user_power_level);
|
||||
DEBUGFS_ADD(ap_power_level);
|
||||
|
@ -738,16 +738,15 @@ static inline int drv_get_antenna(struct ieee80211_local *local,
|
||||
static inline int drv_remain_on_channel(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type chantype,
|
||||
unsigned int duration)
|
||||
{
|
||||
int ret;
|
||||
|
||||
might_sleep();
|
||||
|
||||
trace_drv_remain_on_channel(local, sdata, chan, chantype, duration);
|
||||
trace_drv_remain_on_channel(local, sdata, chan, duration);
|
||||
ret = local->ops->remain_on_channel(&local->hw, &sdata->vif,
|
||||
chan, chantype, duration);
|
||||
chan, duration);
|
||||
trace_drv_return_int(local, ret);
|
||||
|
||||
return ret;
|
||||
|
@ -51,7 +51,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
|
||||
struct cfg80211_bss *bss;
|
||||
u32 bss_change;
|
||||
u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
|
||||
enum nl80211_channel_type channel_type;
|
||||
struct cfg80211_chan_def chandef;
|
||||
|
||||
lockdep_assert_held(&ifibss->mtx);
|
||||
|
||||
@ -79,12 +79,14 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
|
||||
|
||||
channel_type = ifibss->channel_type;
|
||||
if (!cfg80211_can_beacon_sec_chan(local->hw.wiphy, chan, channel_type))
|
||||
channel_type = NL80211_CHAN_HT20;
|
||||
cfg80211_chandef_create(&chandef, chan, ifibss->channel_type);
|
||||
if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) {
|
||||
chandef.width = NL80211_CHAN_WIDTH_20;
|
||||
chandef.center_freq1 = chan->center_freq;
|
||||
}
|
||||
|
||||
ieee80211_vif_release_channel(sdata);
|
||||
if (ieee80211_vif_use_channel(sdata, chan, channel_type,
|
||||
if (ieee80211_vif_use_channel(sdata, &chandef,
|
||||
ifibss->fixed_channel ?
|
||||
IEEE80211_CHANCTX_SHARED :
|
||||
IEEE80211_CHANCTX_EXCLUSIVE)) {
|
||||
@ -158,7 +160,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
|
||||
ifibss->ie, ifibss->ie_len);
|
||||
|
||||
/* add HT capability and information IEs */
|
||||
if (channel_type && sband->ht_cap.ht_supported) {
|
||||
if (chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
|
||||
sband->ht_cap.ht_supported) {
|
||||
pos = skb_put(skb, 4 +
|
||||
sizeof(struct ieee80211_ht_cap) +
|
||||
sizeof(struct ieee80211_ht_operation));
|
||||
@ -170,7 +173,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
|
||||
* keep them at 0
|
||||
*/
|
||||
pos = ieee80211_ie_build_ht_oper(pos, &sband->ht_cap,
|
||||
chan, channel_type, 0);
|
||||
&chandef, 0);
|
||||
}
|
||||
|
||||
if (local->hw.queues >= IEEE80211_NUM_ACS) {
|
||||
@ -326,7 +329,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
|
||||
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
||||
if (WARN_ON_ONCE(!chanctx_conf))
|
||||
return NULL;
|
||||
band = chanctx_conf->channel->band;
|
||||
band = chanctx_conf->def.chan->band;
|
||||
rcu_read_unlock();
|
||||
|
||||
sta = sta_info_alloc(sdata, addr, GFP_KERNEL);
|
||||
@ -374,11 +377,13 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
|
||||
auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
|
||||
auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
|
||||
|
||||
if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)
|
||||
return;
|
||||
ibss_dbg(sdata,
|
||||
"RX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=%d)\n",
|
||||
mgmt->sa, mgmt->da, mgmt->bssid, auth_transaction);
|
||||
|
||||
if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)
|
||||
return;
|
||||
|
||||
sta_info_destroy_addr(sdata, mgmt->sa);
|
||||
sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false);
|
||||
rcu_read_unlock();
|
||||
@ -473,9 +478,11 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
|
||||
sdata->u.ibss.channel_type != NL80211_CHAN_NO_HT) {
|
||||
/* we both use HT */
|
||||
struct ieee80211_sta_ht_cap sta_ht_cap_new;
|
||||
enum nl80211_channel_type channel_type =
|
||||
ieee80211_ht_oper_to_channel_type(
|
||||
elems->ht_operation);
|
||||
struct cfg80211_chan_def chandef;
|
||||
|
||||
ieee80211_ht_oper_to_chandef(channel,
|
||||
elems->ht_operation,
|
||||
&chandef);
|
||||
|
||||
ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
|
||||
elems->ht_cap_elem,
|
||||
@ -485,9 +492,9 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
|
||||
* fall back to HT20 if we don't use or use
|
||||
* the other extension channel
|
||||
*/
|
||||
if (!(channel_type == NL80211_CHAN_HT40MINUS ||
|
||||
channel_type == NL80211_CHAN_HT40PLUS) ||
|
||||
channel_type != sdata->u.ibss.channel_type)
|
||||
if (chandef.width != NL80211_CHAN_WIDTH_40 ||
|
||||
cfg80211_get_chandef_type(&chandef) !=
|
||||
sdata->u.ibss.channel_type)
|
||||
sta_ht_cap_new.cap &=
|
||||
~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
|
||||
|
||||
@ -611,7 +618,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
band = chanctx_conf->channel->band;
|
||||
band = chanctx_conf->def.chan->band;
|
||||
rcu_read_unlock();
|
||||
|
||||
sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
|
||||
@ -1076,8 +1083,9 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
sdata->vif.bss_conf.beacon_int = params->beacon_interval;
|
||||
|
||||
sdata->u.ibss.channel = params->channel;
|
||||
sdata->u.ibss.channel_type = params->channel_type;
|
||||
sdata->u.ibss.channel = params->chandef.chan;
|
||||
sdata->u.ibss.channel_type =
|
||||
cfg80211_get_chandef_type(¶ms->chandef);
|
||||
sdata->u.ibss.fixed_channel = params->channel_fixed;
|
||||
|
||||
if (params->ie) {
|
||||
|
@ -348,7 +348,6 @@ struct ieee80211_roc_work {
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
|
||||
struct ieee80211_channel *chan;
|
||||
enum nl80211_channel_type chan_type;
|
||||
|
||||
bool started, abort, hw_begun, notified;
|
||||
|
||||
@ -364,7 +363,7 @@ enum ieee80211_sta_flags {
|
||||
IEEE80211_STA_BEACON_POLL = BIT(0),
|
||||
IEEE80211_STA_CONNECTION_POLL = BIT(1),
|
||||
IEEE80211_STA_CONTROL_PORT = BIT(2),
|
||||
IEEE80211_STA_DISABLE_11N = BIT(4),
|
||||
IEEE80211_STA_DISABLE_HT = BIT(4),
|
||||
IEEE80211_STA_CSA_RECEIVED = BIT(5),
|
||||
IEEE80211_STA_MFP_ENABLED = BIT(6),
|
||||
IEEE80211_STA_UAPSD_ENABLED = BIT(7),
|
||||
@ -800,7 +799,7 @@ ieee80211_get_sdata_band(struct ieee80211_sub_if_data *sdata)
|
||||
rcu_read_lock();
|
||||
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
||||
if (!WARN_ON(!chanctx_conf))
|
||||
band = chanctx_conf->channel->band;
|
||||
band = chanctx_conf->def.chan->band;
|
||||
rcu_read_unlock();
|
||||
|
||||
return band;
|
||||
@ -1048,7 +1047,6 @@ struct ieee80211_local {
|
||||
|
||||
/* Temporary remain-on-channel for off-channel operations */
|
||||
struct ieee80211_channel *tmp_channel;
|
||||
enum nl80211_channel_type tmp_channel_type;
|
||||
|
||||
/* channel contexts */
|
||||
struct list_head chanctx_list;
|
||||
@ -1158,8 +1156,7 @@ struct ieee80211_local {
|
||||
|
||||
/* virtual monitor interface */
|
||||
struct ieee80211_sub_if_data __rcu *monitor_sdata;
|
||||
struct ieee80211_channel *monitor_channel;
|
||||
enum nl80211_channel_type monitor_channel_type;
|
||||
struct cfg80211_chan_def monitor_chandef;
|
||||
};
|
||||
|
||||
static inline struct ieee80211_sub_if_data *
|
||||
@ -1518,7 +1515,7 @@ static inline void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata,
|
||||
}
|
||||
|
||||
__ieee80211_tx_skb_tid_band(sdata, skb, tid,
|
||||
chanctx_conf->channel->band);
|
||||
chanctx_conf->def.chan->band);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
@ -1607,8 +1604,7 @@ size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset);
|
||||
u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
|
||||
u16 cap);
|
||||
u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
|
||||
struct ieee80211_channel *channel,
|
||||
enum nl80211_channel_type channel_type,
|
||||
const struct cfg80211_chan_def *chandef,
|
||||
u16 prot_mode);
|
||||
u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
|
||||
u32 cap);
|
||||
@ -1620,13 +1616,13 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
|
||||
enum ieee80211_band band);
|
||||
|
||||
/* channel management */
|
||||
enum nl80211_channel_type
|
||||
ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper);
|
||||
void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan,
|
||||
struct ieee80211_ht_operation *ht_oper,
|
||||
struct cfg80211_chan_def *chandef);
|
||||
|
||||
int __must_check
|
||||
ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_channel *channel,
|
||||
enum nl80211_channel_type channel_type,
|
||||
const struct cfg80211_chan_def *chandef,
|
||||
enum ieee80211_chanctx_mode mode);
|
||||
void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata);
|
||||
|
||||
|
@ -54,7 +54,7 @@ bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
|
||||
return false;
|
||||
}
|
||||
|
||||
power = chanctx_conf->channel->max_power;
|
||||
power = chanctx_conf->def.chan->max_power;
|
||||
rcu_read_unlock();
|
||||
|
||||
if (sdata->user_power_level != IEEE80211_UNSET_POWER_LEVEL)
|
||||
@ -415,8 +415,7 @@ static int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
ret = ieee80211_vif_use_channel(sdata, local->monitor_channel,
|
||||
local->monitor_channel_type,
|
||||
ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef,
|
||||
IEEE80211_CHANCTX_EXCLUSIVE);
|
||||
if (ret) {
|
||||
drv_remove_interface(local, sdata);
|
||||
|
@ -115,7 +115,7 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
|
||||
channel_type = NL80211_CHAN_NO_HT;
|
||||
} else if (local->tmp_channel) {
|
||||
chan = local->tmp_channel;
|
||||
channel_type = local->tmp_channel_type;
|
||||
channel_type = NL80211_CHAN_NO_HT;
|
||||
} else {
|
||||
chan = local->_oper_channel;
|
||||
channel_type = local->_oper_channel_type;
|
||||
@ -798,10 +798,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
|
||||
local->_oper_channel = &sband->channels[0];
|
||||
local->hw.conf.channel_type = NL80211_CHAN_NO_HT;
|
||||
}
|
||||
if (!local->monitor_channel) {
|
||||
local->monitor_channel = &sband->channels[0];
|
||||
local->monitor_channel_type = NL80211_CHAN_NO_HT;
|
||||
}
|
||||
cfg80211_chandef_create(&local->monitor_chandef,
|
||||
&sband->channels[0],
|
||||
NL80211_CHAN_NO_HT);
|
||||
channels += sband->n_channels;
|
||||
|
||||
if (max_bitrates < sband->n_bitrates)
|
||||
@ -884,10 +883,22 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
|
||||
if (supp_ht)
|
||||
local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap);
|
||||
|
||||
if (supp_vht)
|
||||
if (supp_vht) {
|
||||
local->scan_ies_len +=
|
||||
2 + sizeof(struct ieee80211_vht_cap);
|
||||
|
||||
/*
|
||||
* (for now at least), drivers wanting to use VHT must
|
||||
* support channel contexts, as they contain all the
|
||||
* necessary VHT information and the global hw config
|
||||
* doesn't (yet)
|
||||
*/
|
||||
if (WARN_ON(!local->use_chanctx)) {
|
||||
result = -EINVAL;
|
||||
goto fail_wiphy_register;
|
||||
}
|
||||
}
|
||||
|
||||
if (!local->ops->hw_scan) {
|
||||
/* For hw_scan, driver needs to set these up. */
|
||||
local->hw.wiphy->max_scan_ssids = 4;
|
||||
|
@ -76,7 +76,7 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
u32 basic_rates = 0;
|
||||
enum nl80211_channel_type sta_channel_type = NL80211_CHAN_NO_HT;
|
||||
struct cfg80211_chan_def sta_chan_def;
|
||||
|
||||
/*
|
||||
* As support for each feature is added, check for matching
|
||||
@ -103,17 +103,11 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
|
||||
if (sdata->vif.bss_conf.basic_rates != basic_rates)
|
||||
goto mismatch;
|
||||
|
||||
if (ie->ht_operation)
|
||||
sta_channel_type =
|
||||
ieee80211_ht_oper_to_channel_type(ie->ht_operation);
|
||||
ieee80211_ht_oper_to_chandef(sdata->vif.bss_conf.chandef.chan,
|
||||
ie->ht_operation, &sta_chan_def);
|
||||
|
||||
/* Disallow HT40+/- mismatch */
|
||||
if (ie->ht_operation &&
|
||||
(sdata->vif.bss_conf.channel_type == NL80211_CHAN_HT40MINUS ||
|
||||
sdata->vif.bss_conf.channel_type == NL80211_CHAN_HT40PLUS) &&
|
||||
(sta_channel_type == NL80211_CHAN_HT40MINUS ||
|
||||
sta_channel_type == NL80211_CHAN_HT40PLUS) &&
|
||||
sdata->vif.bss_conf.channel_type != sta_channel_type)
|
||||
if (!cfg80211_chandef_compatible(&sdata->vif.bss_conf.chandef,
|
||||
&sta_chan_def))
|
||||
goto mismatch;
|
||||
|
||||
return true;
|
||||
@ -129,7 +123,7 @@ mismatch:
|
||||
bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie)
|
||||
{
|
||||
return (ie->mesh_config->meshconf_cap &
|
||||
MESHCONF_CAPAB_ACCEPT_PLINKS) != 0;
|
||||
IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -269,11 +263,11 @@ mesh_add_meshconf_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
|
||||
neighbors = (neighbors > 15) ? 15 : neighbors;
|
||||
*pos++ = neighbors << 1;
|
||||
/* Mesh capability */
|
||||
*pos = MESHCONF_CAPAB_FORWARDING;
|
||||
*pos = IEEE80211_MESHCONF_CAPAB_FORWARDING;
|
||||
*pos |= ifmsh->accepting_plinks ?
|
||||
MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
|
||||
IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
|
||||
*pos++ |= ifmsh->adjusting_tbtt ?
|
||||
MESHCONF_CAPAB_TBTT_ADJUSTING : 0x00;
|
||||
IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING : 0x00;
|
||||
*pos++ = 0x00;
|
||||
|
||||
return 0;
|
||||
@ -368,7 +362,7 @@ int mesh_add_ds_params_ie(struct sk_buff *skb,
|
||||
rcu_read_unlock();
|
||||
return -EINVAL;
|
||||
}
|
||||
chan = chanctx_conf->channel;
|
||||
chan = chanctx_conf->def.chan;
|
||||
rcu_read_unlock();
|
||||
|
||||
sband = local->hw.wiphy->bands[chan->band];
|
||||
@ -392,7 +386,7 @@ int mesh_add_ht_cap_ie(struct sk_buff *skb,
|
||||
|
||||
sband = local->hw.wiphy->bands[band];
|
||||
if (!sband->ht_cap.ht_supported ||
|
||||
sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT)
|
||||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
|
||||
return 0;
|
||||
|
||||
if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap))
|
||||
@ -411,7 +405,7 @@ int mesh_add_ht_oper_ie(struct sk_buff *skb,
|
||||
struct ieee80211_chanctx_conf *chanctx_conf;
|
||||
struct ieee80211_channel *channel;
|
||||
enum nl80211_channel_type channel_type =
|
||||
sdata->vif.bss_conf.channel_type;
|
||||
cfg80211_get_chandef_type(&sdata->vif.bss_conf.chandef);
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_sta_ht_cap *ht_cap;
|
||||
u8 *pos;
|
||||
@ -422,7 +416,7 @@ int mesh_add_ht_oper_ie(struct sk_buff *skb,
|
||||
rcu_read_unlock();
|
||||
return -EINVAL;
|
||||
}
|
||||
channel = chanctx_conf->channel;
|
||||
channel = chanctx_conf->def.chan;
|
||||
rcu_read_unlock();
|
||||
|
||||
sband = local->hw.wiphy->bands[channel->band];
|
||||
@ -435,7 +429,7 @@ int mesh_add_ht_oper_ie(struct sk_buff *skb,
|
||||
return -ENOMEM;
|
||||
|
||||
pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_operation));
|
||||
ieee80211_ie_build_ht_oper(pos, ht_cap, channel, channel_type,
|
||||
ieee80211_ie_build_ht_oper(pos, ht_cap, &sdata->vif.bss_conf.chandef,
|
||||
sdata->vif.bss_conf.ht_operation_mode);
|
||||
|
||||
return 0;
|
||||
|
@ -18,20 +18,6 @@
|
||||
|
||||
/* Data structures */
|
||||
|
||||
/**
|
||||
* enum mesh_config_capab_flags - mesh config IE capability flags
|
||||
*
|
||||
* @MESHCONF_CAPAB_ACCEPT_PLINKS: STA is willing to establish
|
||||
* additional mesh peerings with other mesh STAs
|
||||
* @MESHCONF_CAPAB_FORWARDING: the STA forwards MSDUs
|
||||
* @MESHCONF_CAPAB_TBTT_ADJUSTING: TBTT adjustment procedure is ongoing
|
||||
*/
|
||||
enum mesh_config_capab_flags {
|
||||
MESHCONF_CAPAB_ACCEPT_PLINKS = BIT(0),
|
||||
MESHCONF_CAPAB_FORWARDING = BIT(3),
|
||||
MESHCONF_CAPAB_TBTT_ADJUSTING = BIT(5),
|
||||
};
|
||||
|
||||
/**
|
||||
* enum mesh_path_flags - mac80211 mesh path flags
|
||||
*
|
||||
|
@ -19,12 +19,6 @@
|
||||
#define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \
|
||||
jiffies + HZ * t / 1000))
|
||||
|
||||
#define dot11MeshMaxRetries(s) (s->u.mesh.mshcfg.dot11MeshMaxRetries)
|
||||
#define dot11MeshRetryTimeout(s) (s->u.mesh.mshcfg.dot11MeshRetryTimeout)
|
||||
#define dot11MeshConfirmTimeout(s) (s->u.mesh.mshcfg.dot11MeshConfirmTimeout)
|
||||
#define dot11MeshHoldingTimeout(s) (s->u.mesh.mshcfg.dot11MeshHoldingTimeout)
|
||||
#define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks)
|
||||
|
||||
/* We only need a valid sta if user configured a minimum rssi_threshold. */
|
||||
#define rssi_threshold_check(sta, sdata) \
|
||||
(sdata->u.mesh.mshcfg.rssi_threshold == 0 ||\
|
||||
@ -117,7 +111,7 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
|
||||
u16 ht_opmode;
|
||||
bool non_ht_sta = false, ht20_sta = false;
|
||||
|
||||
if (sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT)
|
||||
if (sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
|
||||
return 0;
|
||||
|
||||
rcu_read_lock();
|
||||
@ -126,14 +120,14 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
|
||||
sta->plink_state != NL80211_PLINK_ESTAB)
|
||||
continue;
|
||||
|
||||
switch (sta->ch_type) {
|
||||
case NL80211_CHAN_NO_HT:
|
||||
switch (sta->ch_width) {
|
||||
case NL80211_CHAN_WIDTH_20_NOHT:
|
||||
mpl_dbg(sdata,
|
||||
"mesh_plink %pM: nonHT sta (%pM) is present\n",
|
||||
sdata->vif.addr, sta->sta.addr);
|
||||
non_ht_sta = true;
|
||||
goto out;
|
||||
case NL80211_CHAN_HT20:
|
||||
case NL80211_CHAN_WIDTH_20:
|
||||
mpl_dbg(sdata,
|
||||
"mesh_plink %pM: HT20 sta (%pM) is present\n",
|
||||
sdata->vif.addr, sta->sta.addr);
|
||||
@ -148,7 +142,7 @@ out:
|
||||
if (non_ht_sta)
|
||||
ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED;
|
||||
else if (ht20_sta &&
|
||||
sdata->vif.bss_conf.channel_type > NL80211_CHAN_HT20)
|
||||
sdata->vif.bss_conf.chandef.width > NL80211_CHAN_WIDTH_20)
|
||||
ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_20MHZ;
|
||||
else
|
||||
ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
|
||||
@ -378,7 +372,7 @@ static struct sta_info *mesh_peer_init(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
sta->sta.supp_rates[band] = rates;
|
||||
if (elems->ht_cap_elem &&
|
||||
sdata->vif.bss_conf.channel_type != NL80211_CHAN_NO_HT)
|
||||
sdata->vif.bss_conf.chandef.width != NL80211_CHAN_WIDTH_20_NOHT)
|
||||
ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
|
||||
elems->ht_cap_elem,
|
||||
&sta->sta.ht_cap);
|
||||
@ -386,12 +380,15 @@ static struct sta_info *mesh_peer_init(struct ieee80211_sub_if_data *sdata,
|
||||
memset(&sta->sta.ht_cap, 0, sizeof(sta->sta.ht_cap));
|
||||
|
||||
if (elems->ht_operation) {
|
||||
struct cfg80211_chan_def chandef;
|
||||
|
||||
if (!(elems->ht_operation->ht_param &
|
||||
IEEE80211_HT_PARAM_CHAN_WIDTH_ANY))
|
||||
sta->sta.ht_cap.cap &=
|
||||
~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
|
||||
sta->ch_type =
|
||||
ieee80211_ht_oper_to_channel_type(elems->ht_operation);
|
||||
ieee80211_ht_oper_to_chandef(sdata->vif.bss_conf.chandef.chan,
|
||||
elems->ht_operation, &chandef);
|
||||
sta->ch_width = chandef.width;
|
||||
}
|
||||
|
||||
rate_control_rate_init(sta);
|
||||
@ -430,6 +427,7 @@ static void mesh_plink_timer(unsigned long data)
|
||||
struct sta_info *sta;
|
||||
__le16 llid, plid, reason;
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
struct mesh_config *mshcfg;
|
||||
|
||||
/*
|
||||
* This STA is valid because sta_info_destroy() will
|
||||
@ -456,12 +454,13 @@ static void mesh_plink_timer(unsigned long data)
|
||||
llid = sta->llid;
|
||||
plid = sta->plid;
|
||||
sdata = sta->sdata;
|
||||
mshcfg = &sdata->u.mesh.mshcfg;
|
||||
|
||||
switch (sta->plink_state) {
|
||||
case NL80211_PLINK_OPN_RCVD:
|
||||
case NL80211_PLINK_OPN_SNT:
|
||||
/* retry timer */
|
||||
if (sta->plink_retries < dot11MeshMaxRetries(sdata)) {
|
||||
if (sta->plink_retries < mshcfg->dot11MeshMaxRetries) {
|
||||
u32 rand;
|
||||
mpl_dbg(sta->sdata,
|
||||
"Mesh plink for %pM (retry, timeout): %d %d\n",
|
||||
@ -484,7 +483,7 @@ static void mesh_plink_timer(unsigned long data)
|
||||
if (!reason)
|
||||
reason = cpu_to_le16(WLAN_REASON_MESH_CONFIRM_TIMEOUT);
|
||||
sta->plink_state = NL80211_PLINK_HOLDING;
|
||||
mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
|
||||
mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
|
||||
spin_unlock_bh(&sta->lock);
|
||||
mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
|
||||
sta->sta.addr, llid, plid, reason);
|
||||
@ -543,7 +542,7 @@ int mesh_plink_open(struct sta_info *sta)
|
||||
return -EBUSY;
|
||||
}
|
||||
sta->plink_state = NL80211_PLINK_OPN_SNT;
|
||||
mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
|
||||
mesh_plink_timer_set(sta, sdata->u.mesh.mshcfg.dot11MeshRetryTimeout);
|
||||
spin_unlock_bh(&sta->lock);
|
||||
mpl_dbg(sdata,
|
||||
"Mesh plink: starting establishment with %pM\n",
|
||||
@ -570,6 +569,7 @@ void mesh_plink_block(struct sta_info *sta)
|
||||
void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt,
|
||||
size_t len, struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
|
||||
struct ieee802_11_elems elems;
|
||||
struct sta_info *sta;
|
||||
enum plink_event event;
|
||||
@ -777,7 +777,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
|
||||
sta->plid = plid;
|
||||
get_random_bytes(&llid, 2);
|
||||
sta->llid = llid;
|
||||
mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
|
||||
mesh_plink_timer_set(sta,
|
||||
mshcfg->dot11MeshRetryTimeout);
|
||||
spin_unlock_bh(&sta->lock);
|
||||
mesh_plink_frame_tx(sdata,
|
||||
WLAN_SP_MESH_PEERING_OPEN,
|
||||
@ -803,7 +804,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
|
||||
sta->reason = reason;
|
||||
sta->plink_state = NL80211_PLINK_HOLDING;
|
||||
if (!mod_plink_timer(sta,
|
||||
dot11MeshHoldingTimeout(sdata)))
|
||||
mshcfg->dot11MeshHoldingTimeout))
|
||||
sta->ignore_plink_timer = true;
|
||||
|
||||
llid = sta->llid;
|
||||
@ -825,7 +826,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
|
||||
case CNF_ACPT:
|
||||
sta->plink_state = NL80211_PLINK_CNF_RCVD;
|
||||
if (!mod_plink_timer(sta,
|
||||
dot11MeshConfirmTimeout(sdata)))
|
||||
mshcfg->dot11MeshConfirmTimeout))
|
||||
sta->ignore_plink_timer = true;
|
||||
|
||||
spin_unlock_bh(&sta->lock);
|
||||
@ -847,7 +848,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
|
||||
sta->reason = reason;
|
||||
sta->plink_state = NL80211_PLINK_HOLDING;
|
||||
if (!mod_plink_timer(sta,
|
||||
dot11MeshHoldingTimeout(sdata)))
|
||||
mshcfg->dot11MeshHoldingTimeout))
|
||||
sta->ignore_plink_timer = true;
|
||||
|
||||
llid = sta->llid;
|
||||
@ -888,7 +889,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
|
||||
sta->reason = reason;
|
||||
sta->plink_state = NL80211_PLINK_HOLDING;
|
||||
if (!mod_plink_timer(sta,
|
||||
dot11MeshHoldingTimeout(sdata)))
|
||||
mshcfg->dot11MeshHoldingTimeout))
|
||||
sta->ignore_plink_timer = true;
|
||||
|
||||
llid = sta->llid;
|
||||
@ -923,7 +924,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
|
||||
changed |= __mesh_plink_deactivate(sta);
|
||||
sta->plink_state = NL80211_PLINK_HOLDING;
|
||||
llid = sta->llid;
|
||||
mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
|
||||
mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
|
||||
spin_unlock_bh(&sta->lock);
|
||||
changed |= mesh_set_ht_prot_mode(sdata);
|
||||
mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
|
||||
|
@ -43,7 +43,7 @@ struct sync_method {
|
||||
static bool mesh_peer_tbtt_adjusting(struct ieee802_11_elems *ie)
|
||||
{
|
||||
return (ie->mesh_config->meshconf_cap &
|
||||
MESHCONF_CAPAB_TBTT_ADJUSTING) != 0;
|
||||
IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING) != 0;
|
||||
}
|
||||
|
||||
void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata)
|
||||
|
@ -191,17 +191,19 @@ static u32 ieee80211_config_ht_tx(struct ieee80211_sub_if_data *sdata,
|
||||
rcu_read_unlock();
|
||||
return 0;
|
||||
}
|
||||
chan = chanctx_conf->channel;
|
||||
chan = chanctx_conf->def.chan;
|
||||
rcu_read_unlock();
|
||||
sband = local->hw.wiphy->bands[chan->band];
|
||||
|
||||
switch (sdata->vif.bss_conf.channel_type) {
|
||||
case NL80211_CHAN_HT40PLUS:
|
||||
if (chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
|
||||
switch (sdata->vif.bss_conf.chandef.width) {
|
||||
case NL80211_CHAN_WIDTH_40:
|
||||
if (sdata->vif.bss_conf.chandef.chan->center_freq >
|
||||
sdata->vif.bss_conf.chandef.center_freq1 &&
|
||||
chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
|
||||
disable_40 = true;
|
||||
break;
|
||||
case NL80211_CHAN_HT40MINUS:
|
||||
if (chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
|
||||
if (sdata->vif.bss_conf.chandef.chan->center_freq <
|
||||
sdata->vif.bss_conf.chandef.center_freq1 &&
|
||||
chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
|
||||
disable_40 = true;
|
||||
break;
|
||||
default:
|
||||
@ -381,7 +383,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
chan = chanctx_conf->channel;
|
||||
chan = chanctx_conf->def.chan;
|
||||
rcu_read_unlock();
|
||||
sband = local->hw.wiphy->bands[chan->band];
|
||||
|
||||
@ -541,7 +543,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
|
||||
offset = noffset;
|
||||
}
|
||||
|
||||
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
|
||||
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
|
||||
ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param,
|
||||
sband, chan, sdata->smps_mode);
|
||||
|
||||
@ -1528,8 +1530,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
|
||||
changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT;
|
||||
ieee80211_bss_info_change_notify(sdata, changed);
|
||||
|
||||
ieee80211_vif_release_channel(sdata);
|
||||
|
||||
/* disassociated - set to defaults now */
|
||||
ieee80211_set_wmm_default(sdata, false);
|
||||
|
||||
@ -1539,6 +1539,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
|
||||
del_timer_sync(&sdata->u.mgd.chswitch_timer);
|
||||
|
||||
sdata->u.mgd.timers_running = 0;
|
||||
|
||||
ifmgd->flags = 0;
|
||||
ieee80211_vif_release_channel(sdata);
|
||||
}
|
||||
|
||||
void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
|
||||
@ -1864,6 +1867,7 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
memset(sdata->u.mgd.bssid, 0, ETH_ALEN);
|
||||
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
|
||||
sdata->u.mgd.flags = 0;
|
||||
ieee80211_vif_release_channel(sdata);
|
||||
}
|
||||
|
||||
@ -2106,6 +2110,7 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
memset(sdata->u.mgd.bssid, 0, ETH_ALEN);
|
||||
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
|
||||
sdata->u.mgd.flags = 0;
|
||||
ieee80211_vif_release_channel(sdata);
|
||||
}
|
||||
|
||||
@ -2170,7 +2175,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
sband = local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)];
|
||||
|
||||
if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
|
||||
if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
|
||||
ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
|
||||
elems.ht_cap_elem, &sta->sta.ht_cap);
|
||||
|
||||
@ -2222,7 +2227,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
||||
changed |= BSS_CHANGED_QOS;
|
||||
|
||||
if (elems.ht_operation && elems.wmm_param &&
|
||||
!(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
|
||||
!(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
|
||||
changed |= ieee80211_config_ht_tx(sdata, elems.ht_operation,
|
||||
cbss->bssid, false);
|
||||
|
||||
@ -2473,11 +2478,11 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
||||
return;
|
||||
}
|
||||
|
||||
if (rx_status->freq != chanctx_conf->channel->center_freq) {
|
||||
if (rx_status->freq != chanctx_conf->def.chan->center_freq) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
chan = chanctx_conf->channel;
|
||||
chan = chanctx_conf->def.chan;
|
||||
rcu_read_unlock();
|
||||
|
||||
if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon &&
|
||||
@ -2658,7 +2663,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
|
||||
if (elems.ht_cap_elem && elems.ht_operation && elems.wmm_param &&
|
||||
!(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
|
||||
!(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
|
||||
changed |= ieee80211_config_ht_tx(sdata, elems.ht_operation,
|
||||
bssid, true);
|
||||
|
||||
@ -3188,6 +3193,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
|
||||
const u8 *ht_oper_ie;
|
||||
const struct ieee80211_ht_operation *ht_oper = NULL;
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct cfg80211_chan_def chandef;
|
||||
|
||||
sband = local->hw.wiphy->bands[cbss->channel->band];
|
||||
|
||||
@ -3219,12 +3225,10 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
|
||||
ht_cfreq, ht_oper->primary_chan,
|
||||
cbss->channel->band);
|
||||
ht_oper = NULL;
|
||||
} else {
|
||||
channel_type = NL80211_CHAN_HT20;
|
||||
}
|
||||
}
|
||||
|
||||
if (ht_oper && sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
|
||||
if (ht_oper) {
|
||||
/*
|
||||
* cfg80211 already verified that the channel itself can
|
||||
* be used, but it didn't check that we can do the right
|
||||
@ -3237,19 +3241,26 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
channel_type = NL80211_CHAN_HT20;
|
||||
|
||||
switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
|
||||
case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
|
||||
if (cbss->channel->flags & IEEE80211_CHAN_NO_HT40PLUS)
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ;
|
||||
else
|
||||
channel_type = NL80211_CHAN_HT40PLUS;
|
||||
break;
|
||||
case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
|
||||
if (cbss->channel->flags & IEEE80211_CHAN_NO_HT40MINUS)
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ;
|
||||
else
|
||||
channel_type = NL80211_CHAN_HT40MINUS;
|
||||
break;
|
||||
if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
|
||||
switch (ht_oper->ht_param &
|
||||
IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
|
||||
case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
|
||||
if (cbss->channel->flags &
|
||||
IEEE80211_CHAN_NO_HT40PLUS)
|
||||
ifmgd->flags |=
|
||||
IEEE80211_STA_DISABLE_40MHZ;
|
||||
else
|
||||
channel_type = NL80211_CHAN_HT40PLUS;
|
||||
break;
|
||||
case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
|
||||
if (cbss->channel->flags &
|
||||
IEEE80211_CHAN_NO_HT40MINUS)
|
||||
ifmgd->flags |=
|
||||
IEEE80211_STA_DISABLE_40MHZ;
|
||||
else
|
||||
channel_type = NL80211_CHAN_HT40MINUS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ht_cap_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
|
||||
@ -3262,13 +3273,15 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
|
||||
sdata->needed_rx_chains = min(chains, local->rx_chains);
|
||||
} else {
|
||||
sdata->needed_rx_chains = 1;
|
||||
sdata->u.mgd.flags |= IEEE80211_STA_DISABLE_HT;
|
||||
}
|
||||
|
||||
/* will change later if needed */
|
||||
sdata->smps_mode = IEEE80211_SMPS_OFF;
|
||||
|
||||
ieee80211_vif_release_channel(sdata);
|
||||
return ieee80211_vif_use_channel(sdata, cbss->channel, channel_type,
|
||||
cfg80211_chandef_create(&chandef, cbss->channel, channel_type);
|
||||
return ieee80211_vif_use_channel(sdata, &chandef,
|
||||
IEEE80211_CHANCTX_SHARED);
|
||||
}
|
||||
|
||||
@ -3530,13 +3543,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
/* prepare assoc data */
|
||||
|
||||
/*
|
||||
* keep only the 40 MHz disable bit set as it might have
|
||||
* been set during authentication already, all other bits
|
||||
* should be reset for a new connection
|
||||
*/
|
||||
ifmgd->flags &= IEEE80211_STA_DISABLE_40MHZ;
|
||||
|
||||
ifmgd->beacon_crc_valid = false;
|
||||
|
||||
/*
|
||||
@ -3550,7 +3556,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
||||
if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||
|
||||
req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP ||
|
||||
req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) {
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
|
||||
netdev_info(sdata->dev,
|
||||
"disabling HT/VHT due to WEP/TKIP use\n");
|
||||
@ -3558,7 +3564,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
||||
}
|
||||
|
||||
if (req->flags & ASSOC_REQ_DISABLE_HT) {
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
|
||||
}
|
||||
|
||||
@ -3566,7 +3572,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
||||
sband = local->hw.wiphy->bands[req->bss->channel->band];
|
||||
if (!sband->ht_cap.ht_supported ||
|
||||
local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) {
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
|
||||
if (!bss->wmm_used)
|
||||
netdev_info(sdata->dev,
|
||||
"disabling HT as WMM/QoS is not supported by the AP\n");
|
||||
@ -3611,7 +3617,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
||||
assoc_data->ap_ht_param =
|
||||
((struct ieee80211_ht_operation *)(ht_ie + 2))->ht_param;
|
||||
else
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
|
||||
|
||||
if (bss->wmm_used && bss->uapsd_supported &&
|
||||
(sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) {
|
||||
|
@ -205,8 +205,8 @@ void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc)
|
||||
}
|
||||
} else {
|
||||
cfg80211_ready_on_channel(&roc->sdata->wdev, roc->cookie,
|
||||
roc->chan, roc->chan_type,
|
||||
roc->req_duration, GFP_KERNEL);
|
||||
roc->chan, roc->req_duration,
|
||||
GFP_KERNEL);
|
||||
}
|
||||
|
||||
roc->notified = true;
|
||||
@ -284,7 +284,6 @@ void ieee80211_start_next_roc(struct ieee80211_local *local)
|
||||
duration = 10;
|
||||
|
||||
ret = drv_remain_on_channel(local, roc->sdata, roc->chan,
|
||||
roc->chan_type,
|
||||
duration);
|
||||
|
||||
roc->started = true;
|
||||
@ -321,7 +320,7 @@ void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc)
|
||||
if (!roc->mgmt_tx_cookie)
|
||||
cfg80211_remain_on_channel_expired(&roc->sdata->wdev,
|
||||
roc->cookie, roc->chan,
|
||||
roc->chan_type, GFP_KERNEL);
|
||||
GFP_KERNEL);
|
||||
|
||||
list_for_each_entry_safe(dep, tmp, &roc->dependents, list)
|
||||
ieee80211_roc_notify_destroy(dep);
|
||||
@ -359,7 +358,6 @@ void ieee80211_sw_roc_work(struct work_struct *work)
|
||||
ieee80211_recalc_idle(local);
|
||||
|
||||
local->tmp_channel = roc->chan;
|
||||
local->tmp_channel_type = roc->chan_type;
|
||||
ieee80211_hw_config(local, 0);
|
||||
|
||||
/* tell userspace or send frame */
|
||||
|
@ -391,7 +391,7 @@ static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
|
||||
return;
|
||||
|
||||
/* if HT BSS, and we handle a data frame, also try HT rates */
|
||||
if (txrc->bss_conf->channel_type == NL80211_CHAN_NO_HT)
|
||||
if (txrc->bss_conf->chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
|
||||
return;
|
||||
|
||||
fc = hdr->frame_control;
|
||||
@ -408,8 +408,7 @@ static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
|
||||
|
||||
alt_rate.flags |= IEEE80211_TX_RC_MCS;
|
||||
|
||||
if ((txrc->bss_conf->channel_type == NL80211_CHAN_HT40MINUS) ||
|
||||
(txrc->bss_conf->channel_type == NL80211_CHAN_HT40PLUS))
|
||||
if (txrc->bss_conf->chandef.width == NL80211_CHAN_WIDTH_40)
|
||||
alt_rate.flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
|
||||
|
||||
if (rate_idx_match_mcs_mask(&alt_rate, mcs_mask)) {
|
||||
|
@ -65,7 +65,7 @@ static inline void rate_control_rate_init(struct sta_info *sta)
|
||||
return;
|
||||
}
|
||||
|
||||
sband = local->hw.wiphy->bands[chanctx_conf->channel->band];
|
||||
sband = local->hw.wiphy->bands[chanctx_conf->def.chan->band];
|
||||
rcu_read_unlock();
|
||||
|
||||
ref->ops->rate_init(ref->priv, sband, ista, priv_sta);
|
||||
|
@ -62,13 +62,16 @@ static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
|
||||
static inline int should_drop_frame(struct sk_buff *skb, int present_fcs_len)
|
||||
{
|
||||
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
struct ieee80211_hdr *hdr;
|
||||
|
||||
hdr = (void *)(skb->data + status->vendor_radiotap_len);
|
||||
|
||||
if (status->flag & (RX_FLAG_FAILED_FCS_CRC |
|
||||
RX_FLAG_FAILED_PLCP_CRC |
|
||||
RX_FLAG_AMPDU_IS_ZEROLEN))
|
||||
return 1;
|
||||
if (unlikely(skb->len < 16 + present_fcs_len))
|
||||
if (unlikely(skb->len < 16 + present_fcs_len +
|
||||
status->vendor_radiotap_len))
|
||||
return 1;
|
||||
if (ieee80211_is_ctl(hdr->frame_control) &&
|
||||
!ieee80211_is_pspoll(hdr->frame_control) &&
|
||||
@ -190,7 +193,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
|
||||
pos++;
|
||||
|
||||
/* IEEE80211_RADIOTAP_RATE */
|
||||
if (!rate || status->flag & RX_FLAG_HT) {
|
||||
if (!rate || status->flag & (RX_FLAG_HT | RX_FLAG_VHT)) {
|
||||
/*
|
||||
* Without rate information don't add it. If we have,
|
||||
* MCS information is a separate field in radiotap,
|
||||
@ -210,7 +213,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
|
||||
if (status->band == IEEE80211_BAND_5GHZ)
|
||||
put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ,
|
||||
pos);
|
||||
else if (status->flag & RX_FLAG_HT)
|
||||
else if (status->flag & (RX_FLAG_HT | RX_FLAG_VHT))
|
||||
put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ,
|
||||
pos);
|
||||
else if (rate && rate->flags & IEEE80211_RATE_ERP_G)
|
||||
@ -341,8 +344,8 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
|
||||
if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
|
||||
present_fcs_len = FCS_LEN;
|
||||
|
||||
/* make sure hdr->frame_control is on the linear part */
|
||||
if (!pskb_may_pull(origskb, 2)) {
|
||||
/* ensure hdr->frame_control and vendor radiotap data are in skb head */
|
||||
if (!pskb_may_pull(origskb, 2 + status->vendor_radiotap_len)) {
|
||||
dev_kfree_skb(origskb);
|
||||
return NULL;
|
||||
}
|
||||
@ -1338,17 +1341,22 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
|
||||
|
||||
/*
|
||||
* Update last_rx only for IBSS packets which are for the current
|
||||
* BSSID to avoid keeping the current IBSS network alive in cases
|
||||
* where other STAs start using different BSSID.
|
||||
* BSSID and for station already AUTHORIZED to avoid keeping the
|
||||
* current IBSS network alive in cases where other STAs start
|
||||
* using different BSSID. This will also give the station another
|
||||
* chance to restart the authentication/authorization in case
|
||||
* something went wrong the first time.
|
||||
*/
|
||||
if (rx->sdata->vif.type == NL80211_IFTYPE_ADHOC) {
|
||||
u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len,
|
||||
NL80211_IFTYPE_ADHOC);
|
||||
if (ether_addr_equal(bssid, rx->sdata->u.ibss.bssid)) {
|
||||
if (ether_addr_equal(bssid, rx->sdata->u.ibss.bssid) &&
|
||||
test_sta_flag(sta, WLAN_STA_AUTHORIZED)) {
|
||||
sta->last_rx = jiffies;
|
||||
if (ieee80211_is_data(hdr->frame_control)) {
|
||||
sta->last_rx_rate_idx = status->rate_idx;
|
||||
sta->last_rx_rate_flag = status->flag;
|
||||
sta->last_rx_rate_vht_nss = status->vht_nss;
|
||||
}
|
||||
}
|
||||
} else if (!is_multicast_ether_addr(hdr->addr1)) {
|
||||
@ -1360,6 +1368,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
|
||||
if (ieee80211_is_data(hdr->frame_control)) {
|
||||
sta->last_rx_rate_idx = status->rate_idx;
|
||||
sta->last_rx_rate_flag = status->flag;
|
||||
sta->last_rx_rate_vht_nss = status->vht_nss;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2703,7 +2712,8 @@ static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
|
||||
status = IEEE80211_SKB_RXCB((rx->skb));
|
||||
|
||||
sband = rx->local->hw.wiphy->bands[status->band];
|
||||
if (!(status->flag & RX_FLAG_HT))
|
||||
if (!(status->flag & RX_FLAG_HT) &&
|
||||
!(status->flag & RX_FLAG_VHT))
|
||||
rate = &sband->bitrates[status->rate_idx];
|
||||
|
||||
ieee80211_rx_cooked_monitor(rx, rate);
|
||||
@ -2870,8 +2880,8 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
|
||||
status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
|
||||
} else if (!rx->sta) {
|
||||
int rate_idx;
|
||||
if (status->flag & RX_FLAG_HT)
|
||||
rate_idx = 0; /* TODO: HT rates */
|
||||
if (status->flag & (RX_FLAG_HT | RX_FLAG_VHT))
|
||||
rate_idx = 0; /* TODO: HT/VHT rates */
|
||||
else
|
||||
rate_idx = status->rate_idx;
|
||||
ieee80211_ibss_rx_no_sta(sdata, bssid, hdr->addr2,
|
||||
@ -3147,6 +3157,13 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
status->rate_idx,
|
||||
status->rate_idx))
|
||||
goto drop;
|
||||
} else if (status->flag & RX_FLAG_VHT) {
|
||||
if (WARN_ONCE(status->rate_idx > 9 ||
|
||||
!status->vht_nss ||
|
||||
status->vht_nss > 8,
|
||||
"Rate marked as a VHT rate but data is invalid: MCS: %d, NSS: %d\n",
|
||||
status->rate_idx, status->vht_nss))
|
||||
goto drop;
|
||||
} else {
|
||||
if (WARN_ON(status->rate_idx >= sband->n_bitrates))
|
||||
goto drop;
|
||||
|
@ -174,7 +174,6 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
|
||||
u8 *elements;
|
||||
struct ieee80211_channel *channel;
|
||||
size_t baselen;
|
||||
int freq;
|
||||
bool beacon;
|
||||
struct ieee802_11_elems elems;
|
||||
|
||||
@ -209,13 +208,7 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
|
||||
|
||||
ieee802_11_parse_elems(elements, skb->len - baselen, &elems);
|
||||
|
||||
if (elems.ds_params && elems.ds_params_len == 1)
|
||||
freq = ieee80211_channel_to_frequency(elems.ds_params[0],
|
||||
rx_status->band);
|
||||
else
|
||||
freq = rx_status->freq;
|
||||
|
||||
channel = ieee80211_get_channel(local->hw.wiphy, freq);
|
||||
channel = ieee80211_get_channel(local->hw.wiphy, rx_status->freq);
|
||||
|
||||
if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
|
||||
return;
|
||||
|
@ -1092,7 +1092,7 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata,
|
||||
return;
|
||||
}
|
||||
|
||||
ieee80211_xmit(sdata, skb, chanctx_conf->channel->band);
|
||||
ieee80211_xmit(sdata, skb, chanctx_conf->def.chan->band);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
|
@ -227,6 +227,7 @@ struct sta_ampdu_mlme {
|
||||
* "the" transmit rate
|
||||
* @last_rx_rate_idx: rx status rate index of the last data packet
|
||||
* @last_rx_rate_flag: rx status flag of the last data packet
|
||||
* @last_rx_rate_vht_nss: rx status nss of last data packet
|
||||
* @lock: used for locking all fields that require locking, see comments
|
||||
* in the header file.
|
||||
* @drv_unblock_wk: used for driver PS unblocking
|
||||
@ -272,7 +273,7 @@ struct sta_ampdu_mlme {
|
||||
* @t_offset: timing offset relative to this host
|
||||
* @t_offset_setpoint: reference timing offset of this sta to be used when
|
||||
* calculating clockdrift
|
||||
* @ch_type: peer's channel type
|
||||
* @ch_width: peer's channel width
|
||||
* @debugfs: debug filesystem info
|
||||
* @dead: set to true when sta is unlinked
|
||||
* @uploaded: set to true when sta is uploaded to the driver
|
||||
@ -343,7 +344,8 @@ struct sta_info {
|
||||
unsigned long tx_fragments;
|
||||
struct ieee80211_tx_rate last_tx_rate;
|
||||
int last_rx_rate_idx;
|
||||
int last_rx_rate_flag;
|
||||
u32 last_rx_rate_flag;
|
||||
u8 last_rx_rate_vht_nss;
|
||||
u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1];
|
||||
|
||||
/*
|
||||
@ -368,7 +370,7 @@ struct sta_info {
|
||||
struct timer_list plink_timer;
|
||||
s64 t_offset;
|
||||
s64 t_offset_setpoint;
|
||||
enum nl80211_channel_type ch_type;
|
||||
enum nl80211_chan_width ch_width;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||
|
@ -28,16 +28,21 @@
|
||||
#define VIF_PR_FMT " vif:%s(%d%s)"
|
||||
#define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : ""
|
||||
|
||||
#define CHANCTX_ENTRY __field(int, freq) \
|
||||
__field(int, chantype) \
|
||||
#define CHANCTX_ENTRY __field(u32, control_freq) \
|
||||
__field(u32, chan_width) \
|
||||
__field(u32, center_freq1) \
|
||||
__field(u32, center_freq2) \
|
||||
__field(u8, rx_chains_static) \
|
||||
__field(u8, rx_chains_dynamic)
|
||||
#define CHANCTX_ASSIGN __entry->freq = ctx->conf.channel->center_freq; \
|
||||
__entry->chantype = ctx->conf.channel_type; \
|
||||
#define CHANCTX_ASSIGN __entry->control_freq = ctx->conf.def.chan->center_freq;\
|
||||
__entry->chan_width = ctx->conf.def.width; \
|
||||
__entry->center_freq1 = ctx->conf.def.center_freq1; \
|
||||
__entry->center_freq2 = ctx->conf.def.center_freq2; \
|
||||
__entry->rx_chains_static = ctx->conf.rx_chains_static; \
|
||||
__entry->rx_chains_dynamic = ctx->conf.rx_chains_dynamic
|
||||
#define CHANCTX_PR_FMT " freq:%d MHz chantype:%d chains:%d/%d"
|
||||
#define CHANCTX_PR_ARG __entry->freq, __entry->chantype, \
|
||||
#define CHANCTX_PR_FMT " control:%d MHz width:%d center: %d/%d MHz chains:%d/%d"
|
||||
#define CHANCTX_PR_ARG __entry->control_freq, __entry->chan_width, \
|
||||
__entry->center_freq1, __entry->center_freq2, \
|
||||
__entry->rx_chains_static, __entry->rx_chains_dynamic
|
||||
|
||||
|
||||
@ -334,7 +339,8 @@ TRACE_EVENT(drv_bss_info_changed,
|
||||
__field(u16, ht_operation_mode)
|
||||
__field(s32, cqm_rssi_thold);
|
||||
__field(s32, cqm_rssi_hyst);
|
||||
__field(u32, channel_type);
|
||||
__field(u32, channel_width);
|
||||
__field(u32, channel_cfreq1);
|
||||
__dynamic_array(u32, arp_addr_list, info->arp_addr_cnt);
|
||||
__field(bool, arp_filter_enabled);
|
||||
__field(bool, qos);
|
||||
@ -370,7 +376,8 @@ TRACE_EVENT(drv_bss_info_changed,
|
||||
__entry->ht_operation_mode = info->ht_operation_mode;
|
||||
__entry->cqm_rssi_thold = info->cqm_rssi_thold;
|
||||
__entry->cqm_rssi_hyst = info->cqm_rssi_hyst;
|
||||
__entry->channel_type = info->channel_type;
|
||||
__entry->channel_width = info->chandef.width;
|
||||
__entry->channel_cfreq1 = info->chandef.center_freq1;
|
||||
memcpy(__get_dynamic_array(arp_addr_list), info->arp_addr_list,
|
||||
sizeof(u32) * info->arp_addr_cnt);
|
||||
__entry->arp_filter_enabled = info->arp_filter_enabled;
|
||||
@ -1022,15 +1029,14 @@ TRACE_EVENT(drv_remain_on_channel,
|
||||
TP_PROTO(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type chantype, unsigned int duration),
|
||||
unsigned int duration),
|
||||
|
||||
TP_ARGS(local, sdata, chan, chantype, duration),
|
||||
TP_ARGS(local, sdata, chan, duration),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
LOCAL_ENTRY
|
||||
VIF_ENTRY
|
||||
__field(int, center_freq)
|
||||
__field(int, channel_type)
|
||||
__field(unsigned int, duration)
|
||||
),
|
||||
|
||||
@ -1038,7 +1044,6 @@ TRACE_EVENT(drv_remain_on_channel,
|
||||
LOCAL_ASSIGN;
|
||||
VIF_ASSIGN;
|
||||
__entry->center_freq = chan->center_freq;
|
||||
__entry->channel_type = chantype;
|
||||
__entry->duration = duration;
|
||||
),
|
||||
|
||||
|
@ -1676,7 +1676,7 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
|
||||
if (!chanctx_conf)
|
||||
goto fail_rcu;
|
||||
|
||||
chan = chanctx_conf->channel;
|
||||
chan = chanctx_conf->def.chan;
|
||||
|
||||
/*
|
||||
* Frame injection is not allowed if beaconing is not allowed
|
||||
@ -1779,7 +1779,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
chanctx_conf = rcu_dereference(ap_sdata->vif.chanctx_conf);
|
||||
if (!chanctx_conf)
|
||||
goto fail_rcu;
|
||||
band = chanctx_conf->channel->band;
|
||||
band = chanctx_conf->def.chan->band;
|
||||
if (sta)
|
||||
break;
|
||||
/* fall through */
|
||||
@ -1794,7 +1794,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
||||
if (!chanctx_conf)
|
||||
goto fail_rcu;
|
||||
band = chanctx_conf->channel->band;
|
||||
band = chanctx_conf->def.chan->band;
|
||||
break;
|
||||
case NL80211_IFTYPE_WDS:
|
||||
fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
|
||||
@ -1871,7 +1871,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
||||
if (!chanctx_conf)
|
||||
goto fail_rcu;
|
||||
band = chanctx_conf->channel->band;
|
||||
band = chanctx_conf->def.chan->band;
|
||||
break;
|
||||
#endif
|
||||
case NL80211_IFTYPE_STATION:
|
||||
@ -1930,7 +1930,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
||||
if (!chanctx_conf)
|
||||
goto fail_rcu;
|
||||
band = chanctx_conf->channel->band;
|
||||
band = chanctx_conf->def.chan->band;
|
||||
break;
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
/* DA SA BSSID */
|
||||
@ -1941,7 +1941,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
||||
if (!chanctx_conf)
|
||||
goto fail_rcu;
|
||||
band = chanctx_conf->channel->band;
|
||||
band = chanctx_conf->def.chan->band;
|
||||
break;
|
||||
default:
|
||||
goto fail_rcu;
|
||||
@ -2194,7 +2194,7 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
|
||||
return true;
|
||||
}
|
||||
result = ieee80211_tx(sdata, skb, true,
|
||||
chanctx_conf->channel->band);
|
||||
chanctx_conf->def.chan->band);
|
||||
} else {
|
||||
struct sk_buff_head skbs;
|
||||
|
||||
@ -2458,7 +2458,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
|
||||
*pos++ = WLAN_EID_SSID;
|
||||
*pos++ = 0x0;
|
||||
|
||||
band = chanctx_conf->channel->band;
|
||||
band = chanctx_conf->def.chan->band;
|
||||
|
||||
if (ieee80211_add_srates_ie(sdata, skb, true, band) ||
|
||||
mesh_add_ds_params_ie(skb, sdata) ||
|
||||
@ -2477,7 +2477,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
|
||||
goto out;
|
||||
}
|
||||
|
||||
band = chanctx_conf->channel->band;
|
||||
band = chanctx_conf->def.chan->band;
|
||||
|
||||
info = IEEE80211_SKB_CB(skb);
|
||||
|
||||
@ -2757,7 +2757,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
|
||||
info = IEEE80211_SKB_CB(skb);
|
||||
|
||||
tx.flags |= IEEE80211_TX_PS_BUFFERED;
|
||||
info->band = chanctx_conf->channel->band;
|
||||
info->band = chanctx_conf->def.chan->band;
|
||||
|
||||
if (invoke_tx_handlers(&tx))
|
||||
skb = NULL;
|
||||
|
@ -898,7 +898,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
|
||||
rcu_read_lock();
|
||||
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
||||
use_11b = (chanctx_conf &&
|
||||
chanctx_conf->channel->band == IEEE80211_BAND_2GHZ) &&
|
||||
chanctx_conf->def.chan->band == IEEE80211_BAND_2GHZ) &&
|
||||
!(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE);
|
||||
rcu_read_unlock();
|
||||
|
||||
@ -991,7 +991,7 @@ void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
|
||||
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
||||
|
||||
if (chanctx_conf &&
|
||||
chanctx_conf->channel->band == IEEE80211_BAND_2GHZ &&
|
||||
chanctx_conf->def.chan->band == IEEE80211_BAND_2GHZ &&
|
||||
have_higher_than_11mbit)
|
||||
sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
|
||||
else
|
||||
@ -1873,8 +1873,7 @@ u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
|
||||
}
|
||||
|
||||
u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
|
||||
struct ieee80211_channel *channel,
|
||||
enum nl80211_channel_type channel_type,
|
||||
const struct cfg80211_chan_def *chandef,
|
||||
u16 prot_mode)
|
||||
{
|
||||
struct ieee80211_ht_operation *ht_oper;
|
||||
@ -1882,23 +1881,25 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
|
||||
*pos++ = WLAN_EID_HT_OPERATION;
|
||||
*pos++ = sizeof(struct ieee80211_ht_operation);
|
||||
ht_oper = (struct ieee80211_ht_operation *)pos;
|
||||
ht_oper->primary_chan =
|
||||
ieee80211_frequency_to_channel(channel->center_freq);
|
||||
switch (channel_type) {
|
||||
case NL80211_CHAN_HT40MINUS:
|
||||
ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
|
||||
ht_oper->primary_chan = ieee80211_frequency_to_channel(
|
||||
chandef->chan->center_freq);
|
||||
switch (chandef->width) {
|
||||
case NL80211_CHAN_WIDTH_160:
|
||||
case NL80211_CHAN_WIDTH_80P80:
|
||||
case NL80211_CHAN_WIDTH_80:
|
||||
case NL80211_CHAN_WIDTH_40:
|
||||
if (chandef->center_freq1 > chandef->chan->center_freq)
|
||||
ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
|
||||
else
|
||||
ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
|
||||
break;
|
||||
case NL80211_CHAN_HT40PLUS:
|
||||
ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
|
||||
break;
|
||||
case NL80211_CHAN_HT20:
|
||||
default:
|
||||
ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE;
|
||||
break;
|
||||
}
|
||||
if (ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 &&
|
||||
channel_type != NL80211_CHAN_NO_HT &&
|
||||
channel_type != NL80211_CHAN_HT20)
|
||||
chandef->width != NL80211_CHAN_WIDTH_20_NOHT &&
|
||||
chandef->width != NL80211_CHAN_WIDTH_20)
|
||||
ht_oper->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;
|
||||
|
||||
ht_oper->operation_mode = cpu_to_le16(prot_mode);
|
||||
@ -1912,13 +1913,17 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
|
||||
return pos + sizeof(struct ieee80211_ht_operation);
|
||||
}
|
||||
|
||||
enum nl80211_channel_type
|
||||
ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper)
|
||||
void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan,
|
||||
struct ieee80211_ht_operation *ht_oper,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
enum nl80211_channel_type channel_type;
|
||||
|
||||
if (!ht_oper)
|
||||
return NL80211_CHAN_NO_HT;
|
||||
if (!ht_oper) {
|
||||
cfg80211_chandef_create(chandef, control_chan,
|
||||
NL80211_CHAN_NO_HT);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
|
||||
case IEEE80211_HT_PARAM_CHA_SEC_NONE:
|
||||
@ -1934,7 +1939,7 @@ ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper)
|
||||
channel_type = NL80211_CHAN_NO_HT;
|
||||
}
|
||||
|
||||
return channel_type;
|
||||
cfg80211_chandef_create(chandef, control_chan, channel_type);
|
||||
}
|
||||
|
||||
int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
|
||||
@ -2066,6 +2071,20 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
|
||||
ri.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
|
||||
if (status->flag & RX_FLAG_SHORT_GI)
|
||||
ri.flags |= RATE_INFO_FLAGS_SHORT_GI;
|
||||
} else if (status->flag & RX_FLAG_VHT) {
|
||||
ri.flags |= RATE_INFO_FLAGS_VHT_MCS;
|
||||
ri.mcs = status->rate_idx;
|
||||
ri.nss = status->vht_nss;
|
||||
if (status->flag & RX_FLAG_40MHZ)
|
||||
ri.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
|
||||
if (status->flag & RX_FLAG_80MHZ)
|
||||
ri.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
|
||||
if (status->flag & RX_FLAG_80P80MHZ)
|
||||
ri.flags |= RATE_INFO_FLAGS_80P80_MHZ_WIDTH;
|
||||
if (status->flag & RX_FLAG_160MHZ)
|
||||
ri.flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
|
||||
if (status->flag & RX_FLAG_SHORT_GI)
|
||||
ri.flags |= RATE_INFO_FLAGS_SHORT_GI;
|
||||
} else {
|
||||
struct ieee80211_supported_band *sband;
|
||||
|
||||
|
@ -160,31 +160,37 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
|
||||
return ieee80211_downgrade_queue(sdata, skb);
|
||||
}
|
||||
|
||||
/**
|
||||
* ieee80211_set_qos_hdr - Fill in the QoS header if there is one.
|
||||
*
|
||||
* @sdata: local subif
|
||||
* @skb: packet to be updated
|
||||
*/
|
||||
void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
u8 *p;
|
||||
u8 ack_policy, tid;
|
||||
|
||||
/* Fill in the QoS header if there is one. */
|
||||
if (ieee80211_is_data_qos(hdr->frame_control)) {
|
||||
u8 *p = ieee80211_get_qos_ctl(hdr);
|
||||
u8 ack_policy, tid;
|
||||
if (!ieee80211_is_data_qos(hdr->frame_control))
|
||||
return;
|
||||
|
||||
tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
|
||||
p = ieee80211_get_qos_ctl(hdr);
|
||||
tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
|
||||
|
||||
/* preserve EOSP bit */
|
||||
ack_policy = *p & IEEE80211_QOS_CTL_EOSP;
|
||||
/* preserve EOSP bit */
|
||||
ack_policy = *p & IEEE80211_QOS_CTL_EOSP;
|
||||
|
||||
if (is_multicast_ether_addr(hdr->addr1) ||
|
||||
sdata->noack_map & BIT(tid)) {
|
||||
ack_policy |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK;
|
||||
info->flags |= IEEE80211_TX_CTL_NO_ACK;
|
||||
}
|
||||
|
||||
/* qos header is 2 bytes */
|
||||
*p++ = ack_policy | tid;
|
||||
*p = ieee80211_vif_is_mesh(&sdata->vif) ?
|
||||
(IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT >> 8) : 0;
|
||||
if (is_multicast_ether_addr(hdr->addr1) ||
|
||||
sdata->noack_map & BIT(tid)) {
|
||||
ack_policy |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK;
|
||||
info->flags |= IEEE80211_TX_CTL_NO_ACK;
|
||||
}
|
||||
|
||||
/* qos header is 2 bytes */
|
||||
*p++ = ack_policy | tid;
|
||||
*p = ieee80211_vif_is_mesh(&sdata->vif) ?
|
||||
(IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT >> 8) : 0;
|
||||
}
|
||||
|
@ -11,96 +11,264 @@
|
||||
#include "core.h"
|
||||
#include "rdev-ops.h"
|
||||
|
||||
struct ieee80211_channel *
|
||||
rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
|
||||
int freq, enum nl80211_channel_type channel_type)
|
||||
void cfg80211_chandef_create(struct cfg80211_chan_def *chandef,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type chan_type)
|
||||
{
|
||||
struct ieee80211_channel *chan;
|
||||
struct ieee80211_sta_ht_cap *ht_cap;
|
||||
if (WARN_ON(!chan))
|
||||
return;
|
||||
|
||||
chan = ieee80211_get_channel(&rdev->wiphy, freq);
|
||||
chandef->chan = chan;
|
||||
chandef->center_freq2 = 0;
|
||||
|
||||
/* Primary channel not allowed */
|
||||
if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
|
||||
return NULL;
|
||||
|
||||
if (channel_type == NL80211_CHAN_HT40MINUS &&
|
||||
chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
|
||||
return NULL;
|
||||
else if (channel_type == NL80211_CHAN_HT40PLUS &&
|
||||
chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
|
||||
return NULL;
|
||||
|
||||
ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap;
|
||||
|
||||
if (channel_type != NL80211_CHAN_NO_HT) {
|
||||
if (!ht_cap->ht_supported)
|
||||
return NULL;
|
||||
|
||||
if (channel_type != NL80211_CHAN_HT20 &&
|
||||
(!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
|
||||
ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return chan;
|
||||
}
|
||||
|
||||
bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type)
|
||||
{
|
||||
struct ieee80211_channel *sec_chan;
|
||||
int diff;
|
||||
|
||||
trace_cfg80211_can_beacon_sec_chan(wiphy, chan, channel_type);
|
||||
|
||||
switch (channel_type) {
|
||||
switch (chan_type) {
|
||||
case NL80211_CHAN_NO_HT:
|
||||
chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
|
||||
chandef->center_freq1 = chan->center_freq;
|
||||
break;
|
||||
case NL80211_CHAN_HT20:
|
||||
chandef->width = NL80211_CHAN_WIDTH_20;
|
||||
chandef->center_freq1 = chan->center_freq;
|
||||
break;
|
||||
case NL80211_CHAN_HT40PLUS:
|
||||
diff = 20;
|
||||
chandef->width = NL80211_CHAN_WIDTH_40;
|
||||
chandef->center_freq1 = chan->center_freq + 10;
|
||||
break;
|
||||
case NL80211_CHAN_HT40MINUS:
|
||||
diff = -20;
|
||||
chandef->width = NL80211_CHAN_WIDTH_40;
|
||||
chandef->center_freq1 = chan->center_freq - 10;
|
||||
break;
|
||||
default:
|
||||
trace_cfg80211_return_bool(true);
|
||||
return true;
|
||||
WARN_ON(1);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_chandef_create);
|
||||
|
||||
sec_chan = ieee80211_get_channel(wiphy, chan->center_freq + diff);
|
||||
if (!sec_chan) {
|
||||
trace_cfg80211_return_bool(false);
|
||||
bool cfg80211_chan_def_valid(const struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
u32 control_freq;
|
||||
|
||||
if (!chandef->chan)
|
||||
return false;
|
||||
|
||||
control_freq = chandef->chan->center_freq;
|
||||
|
||||
switch (chandef->width) {
|
||||
case NL80211_CHAN_WIDTH_20:
|
||||
case NL80211_CHAN_WIDTH_20_NOHT:
|
||||
if (chandef->center_freq1 != control_freq)
|
||||
return false;
|
||||
if (chandef->center_freq2)
|
||||
return false;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_40:
|
||||
if (chandef->center_freq1 != control_freq + 10 &&
|
||||
chandef->center_freq1 != control_freq - 10)
|
||||
return false;
|
||||
if (chandef->center_freq2)
|
||||
return false;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_80P80:
|
||||
if (chandef->center_freq1 != control_freq + 30 &&
|
||||
chandef->center_freq1 != control_freq + 10 &&
|
||||
chandef->center_freq1 != control_freq - 10 &&
|
||||
chandef->center_freq1 != control_freq - 30)
|
||||
return false;
|
||||
if (!chandef->center_freq2)
|
||||
return false;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_80:
|
||||
if (chandef->center_freq1 != control_freq + 30 &&
|
||||
chandef->center_freq1 != control_freq + 10 &&
|
||||
chandef->center_freq1 != control_freq - 10 &&
|
||||
chandef->center_freq1 != control_freq - 30)
|
||||
return false;
|
||||
if (chandef->center_freq2)
|
||||
return false;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_160:
|
||||
if (chandef->center_freq1 != control_freq + 70 &&
|
||||
chandef->center_freq1 != control_freq + 50 &&
|
||||
chandef->center_freq1 != control_freq + 30 &&
|
||||
chandef->center_freq1 != control_freq + 10 &&
|
||||
chandef->center_freq1 != control_freq - 10 &&
|
||||
chandef->center_freq1 != control_freq - 30 &&
|
||||
chandef->center_freq1 != control_freq - 50 &&
|
||||
chandef->center_freq1 != control_freq - 70)
|
||||
return false;
|
||||
if (chandef->center_freq2)
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
/* we'll need a DFS capability later */
|
||||
if (sec_chan->flags & (IEEE80211_CHAN_DISABLED |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN |
|
||||
IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_RADAR)) {
|
||||
trace_cfg80211_return_bool(false);
|
||||
return false;
|
||||
}
|
||||
trace_cfg80211_return_bool(true);
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_can_beacon_sec_chan);
|
||||
|
||||
static void chandef_primary_freqs(const struct cfg80211_chan_def *c,
|
||||
int *pri40, int *pri80)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
switch (c->width) {
|
||||
case NL80211_CHAN_WIDTH_40:
|
||||
*pri40 = c->center_freq1;
|
||||
*pri80 = 0;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_80:
|
||||
case NL80211_CHAN_WIDTH_80P80:
|
||||
*pri80 = c->center_freq1;
|
||||
/* n_P20 */
|
||||
tmp = (30 + c->chan->center_freq - c->center_freq1)/20;
|
||||
/* n_P40 */
|
||||
tmp /= 2;
|
||||
/* freq_P40 */
|
||||
*pri40 = c->center_freq1 - 20 + 40 * tmp;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_160:
|
||||
/* n_P20 */
|
||||
tmp = (70 + c->chan->center_freq - c->center_freq1)/20;
|
||||
/* n_P40 */
|
||||
tmp /= 2;
|
||||
/* freq_P40 */
|
||||
*pri40 = c->center_freq1 - 60 + 40 * tmp;
|
||||
/* n_P80 */
|
||||
tmp /= 2;
|
||||
*pri80 = c->center_freq1 - 40 + 80 * tmp;
|
||||
break;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
}
|
||||
}
|
||||
|
||||
const struct cfg80211_chan_def *
|
||||
cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1,
|
||||
const struct cfg80211_chan_def *c2)
|
||||
{
|
||||
u32 c1_pri40, c1_pri80, c2_pri40, c2_pri80;
|
||||
|
||||
/* If they are identical, return */
|
||||
if (cfg80211_chandef_identical(c1, c2))
|
||||
return c1;
|
||||
|
||||
/* otherwise, must have same control channel */
|
||||
if (c1->chan != c2->chan)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* If they have the same width, but aren't identical,
|
||||
* then they can't be compatible.
|
||||
*/
|
||||
if (c1->width == c2->width)
|
||||
return NULL;
|
||||
|
||||
if (c1->width == NL80211_CHAN_WIDTH_20_NOHT ||
|
||||
c1->width == NL80211_CHAN_WIDTH_20)
|
||||
return c2;
|
||||
|
||||
if (c2->width == NL80211_CHAN_WIDTH_20_NOHT ||
|
||||
c2->width == NL80211_CHAN_WIDTH_20)
|
||||
return c1;
|
||||
|
||||
chandef_primary_freqs(c1, &c1_pri40, &c1_pri80);
|
||||
chandef_primary_freqs(c2, &c2_pri40, &c2_pri80);
|
||||
|
||||
if (c1_pri40 != c2_pri40)
|
||||
return NULL;
|
||||
|
||||
WARN_ON(!c1_pri80 && !c2_pri80);
|
||||
if (c1_pri80 && c2_pri80 && c1_pri80 != c2_pri80)
|
||||
return NULL;
|
||||
|
||||
if (c1->width > c2->width)
|
||||
return c1;
|
||||
return c2;
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_chandef_compatible);
|
||||
|
||||
bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
|
||||
u32 center_freq, u32 bandwidth,
|
||||
u32 prohibited_flags)
|
||||
{
|
||||
struct ieee80211_channel *c;
|
||||
u32 freq;
|
||||
|
||||
for (freq = center_freq - bandwidth/2 + 10;
|
||||
freq <= center_freq + bandwidth/2 - 10;
|
||||
freq += 20) {
|
||||
c = ieee80211_get_channel(wiphy, freq);
|
||||
if (!c || c->flags & prohibited_flags)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cfg80211_check_beacon_chans(struct wiphy *wiphy,
|
||||
u32 center_freq, u32 bw)
|
||||
{
|
||||
return cfg80211_secondary_chans_ok(wiphy, center_freq, bw,
|
||||
IEEE80211_CHAN_DISABLED |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN |
|
||||
IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_RADAR);
|
||||
}
|
||||
|
||||
bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
u32 width;
|
||||
bool res;
|
||||
|
||||
trace_cfg80211_reg_can_beacon(wiphy, chandef);
|
||||
|
||||
if (WARN_ON(!cfg80211_chan_def_valid(chandef))) {
|
||||
trace_cfg80211_return_bool(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (chandef->width) {
|
||||
case NL80211_CHAN_WIDTH_20_NOHT:
|
||||
case NL80211_CHAN_WIDTH_20:
|
||||
width = 20;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_40:
|
||||
width = 40;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_80:
|
||||
case NL80211_CHAN_WIDTH_80P80:
|
||||
width = 80;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_160:
|
||||
width = 160;
|
||||
break;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
trace_cfg80211_return_bool(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
res = cfg80211_check_beacon_chans(wiphy, chandef->center_freq1, width);
|
||||
|
||||
if (res && chandef->center_freq2)
|
||||
res = cfg80211_check_beacon_chans(wiphy, chandef->center_freq2,
|
||||
width);
|
||||
|
||||
trace_cfg80211_return_bool(res);
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_reg_can_beacon);
|
||||
|
||||
int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
|
||||
int freq, enum nl80211_channel_type chantype)
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
struct ieee80211_channel *chan;
|
||||
|
||||
if (!rdev->ops->set_monitor_channel)
|
||||
return -EOPNOTSUPP;
|
||||
if (!cfg80211_has_monitors_only(rdev))
|
||||
return -EBUSY;
|
||||
|
||||
chan = rdev_freq_to_chan(rdev, freq, chantype);
|
||||
if (!chan)
|
||||
return -EINVAL;
|
||||
|
||||
return rdev_set_monitor_channel(rdev, chan, chantype);
|
||||
return rdev_set_monitor_channel(rdev, chandef);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -309,9 +309,9 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
|
||||
const struct mesh_config *conf);
|
||||
int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev);
|
||||
int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev, int freq,
|
||||
enum nl80211_channel_type channel_type);
|
||||
int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev,
|
||||
struct cfg80211_chan_def *chandef);
|
||||
|
||||
/* AP */
|
||||
int cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
|
||||
@ -378,10 +378,8 @@ void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev);
|
||||
int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
|
||||
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);
|
||||
void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
|
||||
const struct ieee80211_ht_cap *ht_capa_mask);
|
||||
|
||||
@ -472,11 +470,8 @@ cfg80211_get_chan_state(struct wireless_dev *wdev,
|
||||
struct ieee80211_channel **chan,
|
||||
enum cfg80211_chan_mode *chanmode);
|
||||
|
||||
struct ieee80211_channel *
|
||||
rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
|
||||
int freq, enum nl80211_channel_type channel_type);
|
||||
int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
|
||||
int freq, enum nl80211_channel_type chantype);
|
||||
struct cfg80211_chan_def *chandef);
|
||||
|
||||
int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
|
||||
const u8 *rates, unsigned int n_rates,
|
||||
@ -488,6 +483,12 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
|
||||
void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
|
||||
enum nl80211_iftype iftype, int num);
|
||||
|
||||
bool cfg80211_chan_def_valid(const struct cfg80211_chan_def *chandef);
|
||||
|
||||
bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
|
||||
u32 center_freq, u32 bandwidth,
|
||||
u32 prohibited_flags);
|
||||
|
||||
#define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10
|
||||
|
||||
#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
|
||||
|
@ -100,9 +100,9 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
|
||||
* 11a for maximum compatibility.
|
||||
*/
|
||||
struct ieee80211_supported_band *sband =
|
||||
rdev->wiphy.bands[params->channel->band];
|
||||
rdev->wiphy.bands[params->chandef.chan->band];
|
||||
int j;
|
||||
u32 flag = params->channel->band == IEEE80211_BAND_5GHZ ?
|
||||
u32 flag = params->chandef.chan->band == IEEE80211_BAND_5GHZ ?
|
||||
IEEE80211_RATE_MANDATORY_A :
|
||||
IEEE80211_RATE_MANDATORY_B;
|
||||
|
||||
@ -118,11 +118,11 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
|
||||
|
||||
wdev->ibss_fixed = params->channel_fixed;
|
||||
#ifdef CONFIG_CFG80211_WEXT
|
||||
wdev->wext.ibss.channel = params->channel;
|
||||
wdev->wext.ibss.chandef = params->chandef;
|
||||
#endif
|
||||
wdev->sme_state = CFG80211_SME_CONNECTING;
|
||||
|
||||
err = cfg80211_can_use_chan(rdev, wdev, params->channel,
|
||||
err = cfg80211_can_use_chan(rdev, wdev, params->chandef.chan,
|
||||
params->channel_fixed
|
||||
? CHAN_MODE_SHARED
|
||||
: CHAN_MODE_EXCLUSIVE);
|
||||
@ -251,7 +251,9 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
|
||||
wdev->wext.ibss.beacon_interval = 100;
|
||||
|
||||
/* try to find an IBSS channel if none requested ... */
|
||||
if (!wdev->wext.ibss.channel) {
|
||||
if (!wdev->wext.ibss.chandef.chan) {
|
||||
wdev->wext.ibss.chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
|
||||
|
||||
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_channel *chan;
|
||||
@ -266,15 +268,15 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
|
||||
continue;
|
||||
if (chan->flags & IEEE80211_CHAN_DISABLED)
|
||||
continue;
|
||||
wdev->wext.ibss.channel = chan;
|
||||
wdev->wext.ibss.chandef.chan = chan;
|
||||
break;
|
||||
}
|
||||
|
||||
if (wdev->wext.ibss.channel)
|
||||
if (wdev->wext.ibss.chandef.chan)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!wdev->wext.ibss.channel)
|
||||
if (!wdev->wext.ibss.chandef.chan)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -336,7 +338,7 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (wdev->wext.ibss.channel == chan)
|
||||
if (wdev->wext.ibss.chandef.chan == chan)
|
||||
return 0;
|
||||
|
||||
wdev_lock(wdev);
|
||||
@ -349,7 +351,8 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
|
||||
return err;
|
||||
|
||||
if (chan) {
|
||||
wdev->wext.ibss.channel = chan;
|
||||
wdev->wext.ibss.chandef.chan = chan;
|
||||
wdev->wext.ibss.chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
|
||||
wdev->wext.ibss.channel_fixed = true;
|
||||
} else {
|
||||
/* cfg80211_ibss_wext_join will pick one if needed */
|
||||
@ -379,8 +382,8 @@ int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
|
||||
wdev_lock(wdev);
|
||||
if (wdev->current_bss)
|
||||
chan = wdev->current_bss->pub.channel;
|
||||
else if (wdev->wext.ibss.channel)
|
||||
chan = wdev->wext.ibss.channel;
|
||||
else if (wdev->wext.ibss.chandef.chan)
|
||||
chan = wdev->wext.ibss.chandef.chan;
|
||||
wdev_unlock(wdev);
|
||||
|
||||
if (chan) {
|
||||
|
@ -73,8 +73,6 @@ const struct mesh_config default_mesh_config = {
|
||||
|
||||
const struct mesh_setup default_mesh_setup = {
|
||||
/* cfg80211_join_mesh() will pick a channel if needed */
|
||||
.channel = NULL,
|
||||
.channel_type = NL80211_CHAN_NO_HT,
|
||||
.sync_method = IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET,
|
||||
.path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP,
|
||||
.path_metric = IEEE80211_PATH_METRIC_AIRTIME,
|
||||
@ -111,13 +109,12 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
|
||||
if (!rdev->ops->join_mesh)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!setup->channel) {
|
||||
if (!setup->chandef.chan) {
|
||||
/* if no channel explicitly given, use preset channel */
|
||||
setup->channel = wdev->preset_chan;
|
||||
setup->channel_type = wdev->preset_chantype;
|
||||
setup->chandef = wdev->preset_chandef;
|
||||
}
|
||||
|
||||
if (!setup->channel) {
|
||||
if (!setup->chandef.chan) {
|
||||
/* if we don't have that either, use the first usable channel */
|
||||
enum ieee80211_band band;
|
||||
|
||||
@ -137,26 +134,25 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
|
||||
IEEE80211_CHAN_DISABLED |
|
||||
IEEE80211_CHAN_RADAR))
|
||||
continue;
|
||||
setup->channel = chan;
|
||||
setup->chandef.chan = chan;
|
||||
break;
|
||||
}
|
||||
|
||||
if (setup->channel)
|
||||
if (setup->chandef.chan)
|
||||
break;
|
||||
}
|
||||
|
||||
/* no usable channel ... */
|
||||
if (!setup->channel)
|
||||
if (!setup->chandef.chan)
|
||||
return -EINVAL;
|
||||
|
||||
setup->channel_type = NL80211_CHAN_NO_HT;
|
||||
setup->chandef.width = NL80211_CHAN_WIDTH_20_NOHT;;
|
||||
}
|
||||
|
||||
if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, setup->channel,
|
||||
setup->channel_type))
|
||||
if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef))
|
||||
return -EINVAL;
|
||||
|
||||
err = cfg80211_can_use_chan(rdev, wdev, setup->channel,
|
||||
err = cfg80211_can_use_chan(rdev, wdev, setup->chandef.chan,
|
||||
CHAN_MODE_SHARED);
|
||||
if (err)
|
||||
return err;
|
||||
@ -165,7 +161,7 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
|
||||
if (!err) {
|
||||
memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len);
|
||||
wdev->mesh_id_len = setup->mesh_id_len;
|
||||
wdev->channel = setup->channel;
|
||||
wdev->channel = setup->chandef.chan;
|
||||
}
|
||||
|
||||
return err;
|
||||
@ -188,20 +184,12 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
|
||||
return err;
|
||||
}
|
||||
|
||||
int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev, int freq,
|
||||
enum nl80211_channel_type channel_type)
|
||||
int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
struct ieee80211_channel *channel;
|
||||
int err;
|
||||
|
||||
channel = rdev_freq_to_chan(rdev, freq, channel_type);
|
||||
if (!channel || !cfg80211_can_beacon_sec_chan(&rdev->wiphy,
|
||||
channel,
|
||||
channel_type)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Workaround for libertas (only!), it puts the interface
|
||||
* into mesh mode but doesn't implement join_mesh. Instead,
|
||||
@ -210,21 +198,21 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev,
|
||||
* compatible with 802.11 mesh.
|
||||
*/
|
||||
if (rdev->ops->libertas_set_mesh_channel) {
|
||||
if (channel_type != NL80211_CHAN_NO_HT)
|
||||
if (chandef->width != NL80211_CHAN_WIDTH_20_NOHT)
|
||||
return -EINVAL;
|
||||
|
||||
if (!netif_running(wdev->netdev))
|
||||
return -ENETDOWN;
|
||||
|
||||
err = cfg80211_can_use_chan(rdev, wdev, channel,
|
||||
err = cfg80211_can_use_chan(rdev, wdev, chandef->chan,
|
||||
CHAN_MODE_SHARED);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = rdev_libertas_set_mesh_channel(rdev, wdev->netdev,
|
||||
channel);
|
||||
chandef->chan);
|
||||
if (!err)
|
||||
wdev->channel = channel;
|
||||
wdev->channel = chandef->chan;
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -232,8 +220,7 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev,
|
||||
if (wdev->mesh_id_len)
|
||||
return -EBUSY;
|
||||
|
||||
wdev->preset_chan = channel;
|
||||
wdev->preset_chantype = channel_type;
|
||||
wdev->preset_chandef = *chandef;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -579,31 +579,25 @@ void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
|
||||
|
||||
void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type,
|
||||
unsigned int duration, gfp_t gfp)
|
||||
{
|
||||
struct wiphy *wiphy = wdev->wiphy;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
||||
|
||||
trace_cfg80211_ready_on_channel(wdev, cookie, chan, channel_type,
|
||||
duration);
|
||||
nl80211_send_remain_on_channel(rdev, wdev, cookie, chan, channel_type,
|
||||
duration, gfp);
|
||||
trace_cfg80211_ready_on_channel(wdev, cookie, chan, duration);
|
||||
nl80211_send_remain_on_channel(rdev, wdev, cookie, chan, duration, gfp);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_ready_on_channel);
|
||||
|
||||
void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type,
|
||||
gfp_t gfp)
|
||||
{
|
||||
struct wiphy *wiphy = wdev->wiphy;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
||||
|
||||
trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan,
|
||||
channel_type);
|
||||
nl80211_send_remain_on_channel_cancel(rdev, wdev, cookie, chan,
|
||||
channel_type, gfp);
|
||||
trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan);
|
||||
nl80211_send_remain_on_channel_cancel(rdev, wdev, cookie, chan, gfp);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
|
||||
|
||||
@ -758,10 +752,8 @@ void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
|
||||
int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
|
||||
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)
|
||||
{
|
||||
const struct ieee80211_mgmt *mgmt;
|
||||
u16 stype;
|
||||
@ -855,7 +847,6 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
|
||||
|
||||
/* Transmit the Action frame as requested by user space */
|
||||
return rdev_mgmt_tx(rdev, wdev, chan, offchan,
|
||||
channel_type, channel_type_valid,
|
||||
wait, buf, len, no_cck, dont_wait_for_ack,
|
||||
cookie);
|
||||
}
|
||||
@ -997,15 +988,14 @@ void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
|
||||
|
||||
void cfg80211_ch_switch_notify(struct net_device *dev, int freq,
|
||||
enum nl80211_channel_type type)
|
||||
void cfg80211_ch_switch_notify(struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct wiphy *wiphy = wdev->wiphy;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
||||
struct ieee80211_channel *chan;
|
||||
|
||||
trace_cfg80211_ch_switch_notify(dev, freq, type);
|
||||
trace_cfg80211_ch_switch_notify(dev, chandef);
|
||||
|
||||
wdev_lock(wdev);
|
||||
|
||||
@ -1013,12 +1003,8 @@ void cfg80211_ch_switch_notify(struct net_device *dev, int freq,
|
||||
wdev->iftype != NL80211_IFTYPE_P2P_GO))
|
||||
goto out;
|
||||
|
||||
chan = rdev_freq_to_chan(rdev, freq, type);
|
||||
if (WARN_ON(!chan))
|
||||
goto out;
|
||||
|
||||
wdev->channel = chan;
|
||||
nl80211_ch_switch_notify(rdev, dev, freq, type, GFP_KERNEL);
|
||||
wdev->channel = chandef->chan;
|
||||
nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL);
|
||||
out:
|
||||
wdev_unlock(wdev);
|
||||
return;
|
||||
|
@ -223,8 +223,13 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
|
||||
[NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
|
||||
.len = 20-1 },
|
||||
[NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
|
||||
|
||||
[NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 },
|
||||
|
||||
[NL80211_ATTR_WIPHY_RETRY_SHORT] = { .type = NLA_U8 },
|
||||
[NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 },
|
||||
[NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
|
||||
@ -1360,51 +1365,139 @@ static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
|
||||
wdev->iftype == NL80211_IFTYPE_P2P_GO;
|
||||
}
|
||||
|
||||
static bool nl80211_valid_channel_type(struct genl_info *info,
|
||||
enum nl80211_channel_type *channel_type)
|
||||
static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
|
||||
struct genl_info *info,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
enum nl80211_channel_type tmp;
|
||||
struct ieee80211_sta_ht_cap *ht_cap;
|
||||
struct ieee80211_sta_vht_cap *vht_cap;
|
||||
u32 control_freq, width;
|
||||
|
||||
if (!info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE])
|
||||
return false;
|
||||
if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
|
||||
return -EINVAL;
|
||||
|
||||
tmp = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
|
||||
if (tmp != NL80211_CHAN_NO_HT &&
|
||||
tmp != NL80211_CHAN_HT20 &&
|
||||
tmp != NL80211_CHAN_HT40PLUS &&
|
||||
tmp != NL80211_CHAN_HT40MINUS)
|
||||
return false;
|
||||
control_freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
|
||||
|
||||
if (channel_type)
|
||||
*channel_type = tmp;
|
||||
chandef->chan = ieee80211_get_channel(&rdev->wiphy, control_freq);
|
||||
chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
|
||||
chandef->center_freq1 = control_freq;
|
||||
chandef->center_freq2 = 0;
|
||||
|
||||
return true;
|
||||
/* Primary channel not allowed */
|
||||
if (!chandef->chan || chandef->chan->flags & IEEE80211_CHAN_DISABLED)
|
||||
return -EINVAL;
|
||||
|
||||
if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
|
||||
enum nl80211_channel_type chantype;
|
||||
|
||||
chantype = nla_get_u32(
|
||||
info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
|
||||
|
||||
switch (chantype) {
|
||||
case NL80211_CHAN_NO_HT:
|
||||
case NL80211_CHAN_HT20:
|
||||
case NL80211_CHAN_HT40PLUS:
|
||||
case NL80211_CHAN_HT40MINUS:
|
||||
cfg80211_chandef_create(chandef, chandef->chan,
|
||||
chantype);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
} else if (info->attrs[NL80211_ATTR_CHANNEL_WIDTH]) {
|
||||
chandef->width =
|
||||
nla_get_u32(info->attrs[NL80211_ATTR_CHANNEL_WIDTH]);
|
||||
if (info->attrs[NL80211_ATTR_CENTER_FREQ1])
|
||||
chandef->center_freq1 =
|
||||
nla_get_u32(
|
||||
info->attrs[NL80211_ATTR_CENTER_FREQ1]);
|
||||
if (info->attrs[NL80211_ATTR_CENTER_FREQ2])
|
||||
chandef->center_freq2 =
|
||||
nla_get_u32(
|
||||
info->attrs[NL80211_ATTR_CENTER_FREQ2]);
|
||||
}
|
||||
|
||||
ht_cap = &rdev->wiphy.bands[chandef->chan->band]->ht_cap;
|
||||
vht_cap = &rdev->wiphy.bands[chandef->chan->band]->vht_cap;
|
||||
|
||||
if (!cfg80211_chan_def_valid(chandef))
|
||||
return -EINVAL;
|
||||
|
||||
switch (chandef->width) {
|
||||
case NL80211_CHAN_WIDTH_20:
|
||||
if (!ht_cap->ht_supported)
|
||||
return -EINVAL;
|
||||
case NL80211_CHAN_WIDTH_20_NOHT:
|
||||
width = 20;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_40:
|
||||
width = 40;
|
||||
/* quick early regulatory check */
|
||||
if (chandef->center_freq1 < control_freq &&
|
||||
chandef->chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
|
||||
return -EINVAL;
|
||||
if (chandef->center_freq1 > control_freq &&
|
||||
chandef->chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
|
||||
return -EINVAL;
|
||||
if (!ht_cap->ht_supported)
|
||||
return -EINVAL;
|
||||
if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
|
||||
ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT)
|
||||
return -EINVAL;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_80:
|
||||
width = 80;
|
||||
if (!vht_cap->vht_supported)
|
||||
return -EINVAL;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_80P80:
|
||||
width = 80;
|
||||
if (!vht_cap->vht_supported)
|
||||
return -EINVAL;
|
||||
if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))
|
||||
return -EINVAL;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_160:
|
||||
width = 160;
|
||||
if (!vht_cap->vht_supported)
|
||||
return -EINVAL;
|
||||
if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ))
|
||||
return -EINVAL;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!cfg80211_secondary_chans_ok(&rdev->wiphy, chandef->center_freq1,
|
||||
width, IEEE80211_CHAN_DISABLED))
|
||||
return -EINVAL;
|
||||
if (chandef->center_freq2 &&
|
||||
!cfg80211_secondary_chans_ok(&rdev->wiphy, chandef->center_freq2,
|
||||
width, IEEE80211_CHAN_DISABLED))
|
||||
return -EINVAL;
|
||||
|
||||
/* TODO: missing regulatory check on bandwidth */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev,
|
||||
struct genl_info *info)
|
||||
{
|
||||
struct ieee80211_channel *channel;
|
||||
enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
|
||||
u32 freq;
|
||||
struct cfg80211_chan_def chandef;
|
||||
int result;
|
||||
enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR;
|
||||
|
||||
if (wdev)
|
||||
iftype = wdev->iftype;
|
||||
|
||||
if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
|
||||
return -EINVAL;
|
||||
|
||||
if (!nl80211_can_set_dev_channel(wdev))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] &&
|
||||
!nl80211_valid_channel_type(info, &channel_type))
|
||||
return -EINVAL;
|
||||
|
||||
freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
|
||||
result = nl80211_parse_chandef(rdev, info, &chandef);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
mutex_lock(&rdev->devlist_mtx);
|
||||
switch (iftype) {
|
||||
@ -1414,22 +1507,18 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
|
||||
result = -EBUSY;
|
||||
break;
|
||||
}
|
||||
channel = rdev_freq_to_chan(rdev, freq, channel_type);
|
||||
if (!channel || !cfg80211_can_beacon_sec_chan(&rdev->wiphy,
|
||||
channel,
|
||||
channel_type)) {
|
||||
if (!cfg80211_reg_can_beacon(&rdev->wiphy, &chandef)) {
|
||||
result = -EINVAL;
|
||||
break;
|
||||
}
|
||||
wdev->preset_chan = channel;
|
||||
wdev->preset_chantype = channel_type;
|
||||
wdev->preset_chandef = chandef;
|
||||
result = 0;
|
||||
break;
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
result = cfg80211_set_mesh_freq(rdev, wdev, freq, channel_type);
|
||||
result = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
|
||||
break;
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
result = cfg80211_set_monitor_channel(rdev, freq, channel_type);
|
||||
result = cfg80211_set_monitor_channel(rdev, &chandef);
|
||||
break;
|
||||
default:
|
||||
result = -EINVAL;
|
||||
@ -1749,6 +1838,35 @@ static inline u64 wdev_id(struct wireless_dev *wdev)
|
||||
((u64)wiphy_to_dev(wdev->wiphy)->wiphy_idx << 32);
|
||||
}
|
||||
|
||||
static int nl80211_send_chandef(struct sk_buff *msg,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
WARN_ON(!cfg80211_chan_def_valid(chandef));
|
||||
|
||||
if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
|
||||
chandef->chan->center_freq))
|
||||
return -ENOBUFS;
|
||||
switch (chandef->width) {
|
||||
case NL80211_CHAN_WIDTH_20_NOHT:
|
||||
case NL80211_CHAN_WIDTH_20:
|
||||
case NL80211_CHAN_WIDTH_40:
|
||||
if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
|
||||
cfg80211_get_chandef_type(chandef)))
|
||||
return -ENOBUFS;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, chandef->width))
|
||||
return -ENOBUFS;
|
||||
if (nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1, chandef->center_freq1))
|
||||
return -ENOBUFS;
|
||||
if (chandef->center_freq2 &&
|
||||
nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2, chandef->center_freq2))
|
||||
return -ENOBUFS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags,
|
||||
struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev)
|
||||
@ -1775,16 +1893,14 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag
|
||||
goto nla_put_failure;
|
||||
|
||||
if (rdev->ops->get_channel) {
|
||||
struct ieee80211_channel *chan;
|
||||
enum nl80211_channel_type channel_type;
|
||||
int ret;
|
||||
struct cfg80211_chan_def chandef;
|
||||
|
||||
chan = rdev_get_channel(rdev, wdev, &channel_type);
|
||||
if (chan &&
|
||||
(nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
|
||||
chan->center_freq) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
|
||||
channel_type)))
|
||||
goto nla_put_failure;
|
||||
ret = rdev_get_channel(rdev, wdev, &chandef);
|
||||
if (ret == 0) {
|
||||
if (nl80211_send_chandef(msg, &chandef))
|
||||
goto nla_put_failure;
|
||||
}
|
||||
}
|
||||
|
||||
if (wdev->ssid_len) {
|
||||
@ -2492,11 +2608,10 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
|
||||
wdev->iftype != NL80211_IFTYPE_P2P_GO)
|
||||
continue;
|
||||
|
||||
if (!wdev->preset_chan)
|
||||
if (!wdev->preset_chandef.chan)
|
||||
continue;
|
||||
|
||||
params->channel = wdev->preset_chan;
|
||||
params->channel_type = wdev->preset_chantype;
|
||||
params->chandef = wdev->preset_chandef;
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
@ -2618,30 +2733,19 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
|
||||
}
|
||||
|
||||
if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
|
||||
enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
|
||||
|
||||
if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] &&
|
||||
!nl80211_valid_channel_type(info, &channel_type))
|
||||
return -EINVAL;
|
||||
|
||||
params.channel = rdev_freq_to_chan(rdev,
|
||||
nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
|
||||
channel_type);
|
||||
if (!params.channel)
|
||||
return -EINVAL;
|
||||
params.channel_type = channel_type;
|
||||
} else if (wdev->preset_chan) {
|
||||
params.channel = wdev->preset_chan;
|
||||
params.channel_type = wdev->preset_chantype;
|
||||
err = nl80211_parse_chandef(rdev, info, ¶ms.chandef);
|
||||
if (err)
|
||||
return err;
|
||||
} else if (wdev->preset_chandef.chan) {
|
||||
params.chandef = wdev->preset_chandef;
|
||||
} else if (!nl80211_get_ap_channel(rdev, ¶ms))
|
||||
return -EINVAL;
|
||||
|
||||
if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, params.channel,
|
||||
params.channel_type))
|
||||
if (!cfg80211_reg_can_beacon(&rdev->wiphy, ¶ms.chandef))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&rdev->devlist_mtx);
|
||||
err = cfg80211_can_use_chan(rdev, wdev, params.channel,
|
||||
err = cfg80211_can_use_chan(rdev, wdev, params.chandef.chan,
|
||||
CHAN_MODE_SHARED);
|
||||
mutex_unlock(&rdev->devlist_mtx);
|
||||
|
||||
@ -2650,10 +2754,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
|
||||
|
||||
err = rdev_start_ap(rdev, dev, ¶ms);
|
||||
if (!err) {
|
||||
wdev->preset_chan = params.channel;
|
||||
wdev->preset_chantype = params.channel_type;
|
||||
wdev->preset_chandef = params.chandef;
|
||||
wdev->beacon_interval = params.beacon_interval;
|
||||
wdev->channel = params.channel;
|
||||
wdev->channel = params.chandef.chan;
|
||||
wdev->ssid_len = params.ssid_len;
|
||||
memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
|
||||
}
|
||||
@ -2787,29 +2890,52 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
|
||||
|
||||
rate = nla_nest_start(msg, attr);
|
||||
if (!rate)
|
||||
goto nla_put_failure;
|
||||
return false;
|
||||
|
||||
/* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
|
||||
bitrate = cfg80211_calculate_bitrate(info);
|
||||
/* report 16-bit bitrate only if we can */
|
||||
bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
|
||||
if ((bitrate > 0 &&
|
||||
nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate)) ||
|
||||
(bitrate_compat > 0 &&
|
||||
nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat)) ||
|
||||
((info->flags & RATE_INFO_FLAGS_MCS) &&
|
||||
nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs)) ||
|
||||
((info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) &&
|
||||
nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH)) ||
|
||||
((info->flags & RATE_INFO_FLAGS_SHORT_GI) &&
|
||||
nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI)))
|
||||
goto nla_put_failure;
|
||||
if (bitrate > 0 &&
|
||||
nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate))
|
||||
return false;
|
||||
if (bitrate_compat > 0 &&
|
||||
nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat))
|
||||
return false;
|
||||
|
||||
if (info->flags & RATE_INFO_FLAGS_MCS) {
|
||||
if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs))
|
||||
return false;
|
||||
if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH &&
|
||||
nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH))
|
||||
return false;
|
||||
if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
|
||||
nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
|
||||
return false;
|
||||
} else if (info->flags & RATE_INFO_FLAGS_VHT_MCS) {
|
||||
if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_MCS, info->mcs))
|
||||
return false;
|
||||
if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss))
|
||||
return false;
|
||||
if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH &&
|
||||
nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH))
|
||||
return false;
|
||||
if (info->flags & RATE_INFO_FLAGS_80_MHZ_WIDTH &&
|
||||
nla_put_flag(msg, NL80211_RATE_INFO_80_MHZ_WIDTH))
|
||||
return false;
|
||||
if (info->flags & RATE_INFO_FLAGS_80P80_MHZ_WIDTH &&
|
||||
nla_put_flag(msg, NL80211_RATE_INFO_80P80_MHZ_WIDTH))
|
||||
return false;
|
||||
if (info->flags & RATE_INFO_FLAGS_160_MHZ_WIDTH &&
|
||||
nla_put_flag(msg, NL80211_RATE_INFO_160_MHZ_WIDTH))
|
||||
return false;
|
||||
if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
|
||||
nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
|
||||
return false;
|
||||
}
|
||||
|
||||
nla_nest_end(msg, rate);
|
||||
return true;
|
||||
|
||||
nla_put_failure:
|
||||
return false;
|
||||
}
|
||||
|
||||
static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
|
||||
@ -5330,8 +5456,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
|
||||
if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
|
||||
return -EINVAL;
|
||||
|
||||
if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
|
||||
!info->attrs[NL80211_ATTR_SSID] ||
|
||||
if (!info->attrs[NL80211_ATTR_SSID] ||
|
||||
!nla_len(info->attrs[NL80211_ATTR_SSID]))
|
||||
return -EINVAL;
|
||||
|
||||
@ -5366,35 +5491,17 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
|
||||
ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
|
||||
}
|
||||
|
||||
if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
|
||||
enum nl80211_channel_type channel_type;
|
||||
err = nl80211_parse_chandef(rdev, info, &ibss.chandef);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!nl80211_valid_channel_type(info, &channel_type))
|
||||
return -EINVAL;
|
||||
|
||||
if (channel_type != NL80211_CHAN_NO_HT &&
|
||||
!(wiphy->features & NL80211_FEATURE_HT_IBSS))
|
||||
return -EINVAL;
|
||||
|
||||
ibss.channel_type = channel_type;
|
||||
} else {
|
||||
ibss.channel_type = NL80211_CHAN_NO_HT;
|
||||
}
|
||||
|
||||
ibss.channel = rdev_freq_to_chan(rdev,
|
||||
nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
|
||||
ibss.channel_type);
|
||||
if (!ibss.channel ||
|
||||
ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
|
||||
ibss.channel->flags & IEEE80211_CHAN_DISABLED)
|
||||
if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef))
|
||||
return -EINVAL;
|
||||
|
||||
/* Both channels should be able to initiate communication */
|
||||
if ((ibss.channel_type == NL80211_CHAN_HT40PLUS ||
|
||||
ibss.channel_type == NL80211_CHAN_HT40MINUS) &&
|
||||
!cfg80211_can_beacon_sec_chan(&rdev->wiphy, ibss.channel,
|
||||
ibss.channel_type))
|
||||
if (ibss.chandef.width > NL80211_CHAN_WIDTH_40)
|
||||
return -EINVAL;
|
||||
if (ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
|
||||
!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
|
||||
|
||||
ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
|
||||
ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
|
||||
@ -5405,7 +5512,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
|
||||
int n_rates =
|
||||
nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
|
||||
struct ieee80211_supported_band *sband =
|
||||
wiphy->bands[ibss.channel->band];
|
||||
wiphy->bands[ibss.chandef.chan->band];
|
||||
|
||||
err = ieee80211_get_ratemask(sband, rates, n_rates,
|
||||
&ibss.basic_rates);
|
||||
@ -5427,7 +5534,8 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
|
||||
if (IS_ERR(connkeys))
|
||||
return PTR_ERR(connkeys);
|
||||
|
||||
if ((ibss.channel_type != NL80211_CHAN_NO_HT) && no_ht) {
|
||||
if ((ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) &&
|
||||
no_ht) {
|
||||
kfree(connkeys);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -5948,12 +6056,11 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
struct wireless_dev *wdev = info->user_ptr[1];
|
||||
struct ieee80211_channel *chan;
|
||||
struct cfg80211_chan_def chandef;
|
||||
struct sk_buff *msg;
|
||||
void *hdr;
|
||||
u64 cookie;
|
||||
enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
|
||||
u32 freq, duration;
|
||||
u32 duration;
|
||||
int err;
|
||||
|
||||
if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
|
||||
@ -5974,14 +6081,9 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
|
||||
duration > rdev->wiphy.max_remain_on_channel_duration)
|
||||
return -EINVAL;
|
||||
|
||||
if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] &&
|
||||
!nl80211_valid_channel_type(info, &channel_type))
|
||||
return -EINVAL;
|
||||
|
||||
freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
|
||||
chan = rdev_freq_to_chan(rdev, freq, channel_type);
|
||||
if (chan == NULL)
|
||||
return -EINVAL;
|
||||
err = nl80211_parse_chandef(rdev, info, &chandef);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||
if (!msg)
|
||||
@ -5995,8 +6097,8 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
|
||||
goto free_msg;
|
||||
}
|
||||
|
||||
err = rdev_remain_on_channel(rdev, wdev, chan, channel_type, duration,
|
||||
&cookie);
|
||||
err = rdev_remain_on_channel(rdev, wdev, chandef.chan,
|
||||
duration, &cookie);
|
||||
|
||||
if (err)
|
||||
goto free_msg;
|
||||
@ -6215,10 +6317,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
struct wireless_dev *wdev = info->user_ptr[1];
|
||||
struct ieee80211_channel *chan;
|
||||
enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
|
||||
bool channel_type_valid = false;
|
||||
u32 freq;
|
||||
struct cfg80211_chan_def chandef;
|
||||
int err;
|
||||
void *hdr = NULL;
|
||||
u64 cookie;
|
||||
@ -6228,8 +6327,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
|
||||
|
||||
dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK];
|
||||
|
||||
if (!info->attrs[NL80211_ATTR_FRAME] ||
|
||||
!info->attrs[NL80211_ATTR_WIPHY_FREQ])
|
||||
if (!info->attrs[NL80211_ATTR_FRAME])
|
||||
return -EINVAL;
|
||||
|
||||
if (!rdev->ops->mgmt_tx)
|
||||
@ -6264,12 +6362,6 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
|
||||
|
||||
}
|
||||
|
||||
if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
|
||||
if (!nl80211_valid_channel_type(info, &channel_type))
|
||||
return -EINVAL;
|
||||
channel_type_valid = true;
|
||||
}
|
||||
|
||||
offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
|
||||
|
||||
if (offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
|
||||
@ -6277,10 +6369,9 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
|
||||
|
||||
no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
|
||||
|
||||
freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
|
||||
chan = rdev_freq_to_chan(rdev, freq, channel_type);
|
||||
if (chan == NULL)
|
||||
return -EINVAL;
|
||||
err = nl80211_parse_chandef(rdev, info, &chandef);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!dont_wait_for_ack) {
|
||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||
@ -6296,8 +6387,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
|
||||
}
|
||||
}
|
||||
|
||||
err = cfg80211_mlme_mgmt_tx(rdev, wdev, chan, offchan, channel_type,
|
||||
channel_type_valid, wait,
|
||||
err = cfg80211_mlme_mgmt_tx(rdev, wdev, chandef.chan, offchan, wait,
|
||||
nla_data(info->attrs[NL80211_ATTR_FRAME]),
|
||||
nla_len(info->attrs[NL80211_ATTR_FRAME]),
|
||||
no_cck, dont_wait_for_ack, &cookie);
|
||||
@ -6561,21 +6651,12 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
|
||||
}
|
||||
|
||||
if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
|
||||
enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
|
||||
|
||||
if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] &&
|
||||
!nl80211_valid_channel_type(info, &channel_type))
|
||||
return -EINVAL;
|
||||
|
||||
setup.channel = rdev_freq_to_chan(rdev,
|
||||
nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
|
||||
channel_type);
|
||||
if (!setup.channel)
|
||||
return -EINVAL;
|
||||
setup.channel_type = channel_type;
|
||||
err = nl80211_parse_chandef(rdev, info, &setup.chandef);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
/* cfg80211_join_mesh() will sort it out */
|
||||
setup.channel = NULL;
|
||||
setup.chandef.chan = NULL;
|
||||
}
|
||||
|
||||
return cfg80211_join_mesh(rdev, dev, &setup, &cfg);
|
||||
@ -8395,7 +8476,6 @@ static void nl80211_send_remain_on_chan_event(
|
||||
int cmd, struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev, u64 cookie,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type,
|
||||
unsigned int duration, gfp_t gfp)
|
||||
{
|
||||
struct sk_buff *msg;
|
||||
@ -8416,7 +8496,8 @@ static void nl80211_send_remain_on_chan_event(
|
||||
wdev->netdev->ifindex)) ||
|
||||
nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, channel_type) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
|
||||
NL80211_CHAN_NO_HT) ||
|
||||
nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie))
|
||||
goto nla_put_failure;
|
||||
|
||||
@ -8438,23 +8519,20 @@ static void nl80211_send_remain_on_chan_event(
|
||||
void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev, u64 cookie,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type,
|
||||
unsigned int duration, gfp_t gfp)
|
||||
{
|
||||
nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
|
||||
rdev, wdev, cookie, chan,
|
||||
channel_type, duration, gfp);
|
||||
duration, gfp);
|
||||
}
|
||||
|
||||
void nl80211_send_remain_on_channel_cancel(
|
||||
struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev,
|
||||
u64 cookie, struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type, gfp_t gfp)
|
||||
u64 cookie, struct ieee80211_channel *chan, gfp_t gfp)
|
||||
{
|
||||
nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
|
||||
rdev, wdev, cookie, chan,
|
||||
channel_type, 0, gfp);
|
||||
rdev, wdev, cookie, chan, 0, gfp);
|
||||
}
|
||||
|
||||
void nl80211_send_sta_event(struct cfg80211_registered_device *rdev,
|
||||
@ -8810,8 +8888,8 @@ void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
|
||||
}
|
||||
|
||||
void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev, int freq,
|
||||
enum nl80211_channel_type type, gfp_t gfp)
|
||||
struct net_device *netdev,
|
||||
struct cfg80211_chan_def *chandef, gfp_t gfp)
|
||||
{
|
||||
struct sk_buff *msg;
|
||||
void *hdr;
|
||||
@ -8826,9 +8904,10 @@ void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
|
||||
return;
|
||||
}
|
||||
|
||||
if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, type))
|
||||
if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (nl80211_send_chandef(msg, chandef))
|
||||
goto nla_put_failure;
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
|
@ -76,13 +76,11 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
|
||||
void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev, u64 cookie,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type,
|
||||
unsigned int duration, gfp_t gfp);
|
||||
void nl80211_send_remain_on_channel_cancel(
|
||||
struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev,
|
||||
u64 cookie, struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type, gfp_t gfp);
|
||||
u64 cookie, struct ieee80211_channel *chan, gfp_t gfp);
|
||||
|
||||
void nl80211_send_sta_event(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev, const u8 *mac_addr,
|
||||
@ -129,8 +127,8 @@ void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
|
||||
const u8 *bssid, bool preauth, gfp_t gfp);
|
||||
|
||||
void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev, int freq,
|
||||
enum nl80211_channel_type type, gfp_t gfp);
|
||||
struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef, gfp_t gfp);
|
||||
|
||||
bool nl80211_unexpected_frame(struct net_device *dev,
|
||||
const u8 *addr, gfp_t gfp);
|
||||
|
@ -359,12 +359,11 @@ rdev_libertas_set_mesh_channel(struct cfg80211_registered_device *rdev,
|
||||
|
||||
static inline int
|
||||
rdev_set_monitor_channel(struct cfg80211_registered_device *rdev,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type)
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
int ret;
|
||||
trace_rdev_set_monitor_channel(&rdev->wiphy, chan, channel_type);
|
||||
ret = rdev->ops->set_monitor_channel(&rdev->wiphy, chan, channel_type);
|
||||
trace_rdev_set_monitor_channel(&rdev->wiphy, chandef);
|
||||
ret = rdev->ops->set_monitor_channel(&rdev->wiphy, chandef);
|
||||
trace_rdev_return_int(&rdev->wiphy, ret);
|
||||
return ret;
|
||||
}
|
||||
@ -600,14 +599,12 @@ static inline int
|
||||
rdev_remain_on_channel(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type,
|
||||
unsigned int duration, u64 *cookie)
|
||||
{
|
||||
int ret;
|
||||
trace_rdev_remain_on_channel(&rdev->wiphy, wdev, chan, channel_type,
|
||||
duration);
|
||||
trace_rdev_remain_on_channel(&rdev->wiphy, wdev, chan, duration);
|
||||
ret = rdev->ops->remain_on_channel(&rdev->wiphy, wdev, chan,
|
||||
channel_type, duration, cookie);
|
||||
duration, cookie);
|
||||
trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie);
|
||||
return ret;
|
||||
}
|
||||
@ -626,17 +623,15 @@ rdev_cancel_remain_on_channel(struct cfg80211_registered_device *rdev,
|
||||
static inline int rdev_mgmt_tx(struct cfg80211_registered_device *rdev,
|
||||
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)
|
||||
{
|
||||
int ret;
|
||||
trace_rdev_mgmt_tx(&rdev->wiphy, wdev, chan, offchan, channel_type,
|
||||
channel_type_valid, wait, no_cck, dont_wait_for_ack);
|
||||
trace_rdev_mgmt_tx(&rdev->wiphy, wdev, chan, offchan,
|
||||
wait, no_cck, dont_wait_for_ack);
|
||||
ret = rdev->ops->mgmt_tx(&rdev->wiphy, wdev, chan, offchan,
|
||||
channel_type, channel_type_valid, wait, buf,
|
||||
len, no_cck, dont_wait_for_ack, cookie);
|
||||
wait, buf, len, no_cck,
|
||||
dont_wait_for_ack, cookie);
|
||||
trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie);
|
||||
return ret;
|
||||
}
|
||||
@ -848,14 +843,17 @@ static inline void rdev_get_et_strings(struct cfg80211_registered_device *rdev,
|
||||
trace_rdev_return_void(&rdev->wiphy);
|
||||
}
|
||||
|
||||
static inline struct ieee80211_channel
|
||||
*rdev_get_channel(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev, enum nl80211_channel_type *type)
|
||||
static inline int
|
||||
rdev_get_channel(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
struct ieee80211_channel *ret;
|
||||
int ret;
|
||||
|
||||
trace_rdev_get_channel(&rdev->wiphy, wdev);
|
||||
ret = rdev->ops->get_channel(&rdev->wiphy, wdev, type);
|
||||
trace_rdev_return_channel(&rdev->wiphy, ret, *type);
|
||||
ret = rdev->ops->get_channel(&rdev->wiphy, wdev, chandef);
|
||||
trace_rdev_return_chandef(&rdev->wiphy, ret, chandef);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -771,6 +771,38 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
|
||||
return found;
|
||||
}
|
||||
|
||||
static struct ieee80211_channel *
|
||||
cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen,
|
||||
struct ieee80211_channel *channel)
|
||||
{
|
||||
const u8 *tmp;
|
||||
u32 freq;
|
||||
int channel_number = -1;
|
||||
|
||||
tmp = cfg80211_find_ie(WLAN_EID_DS_PARAMS, ie, ielen);
|
||||
if (tmp && tmp[1] == 1) {
|
||||
channel_number = tmp[2];
|
||||
} else {
|
||||
tmp = cfg80211_find_ie(WLAN_EID_HT_OPERATION, ie, ielen);
|
||||
if (tmp && tmp[1] >= sizeof(struct ieee80211_ht_operation)) {
|
||||
struct ieee80211_ht_operation *htop = (void *)(tmp + 2);
|
||||
|
||||
channel_number = htop->primary_chan;
|
||||
}
|
||||
}
|
||||
|
||||
if (channel_number < 0)
|
||||
return channel;
|
||||
|
||||
freq = ieee80211_channel_to_frequency(channel_number, channel->band);
|
||||
channel = ieee80211_get_channel(wiphy, freq);
|
||||
if (!channel)
|
||||
return NULL;
|
||||
if (channel->flags & IEEE80211_CHAN_DISABLED)
|
||||
return NULL;
|
||||
return channel;
|
||||
}
|
||||
|
||||
struct cfg80211_bss*
|
||||
cfg80211_inform_bss(struct wiphy *wiphy,
|
||||
struct ieee80211_channel *channel,
|
||||
@ -790,6 +822,10 @@ cfg80211_inform_bss(struct wiphy *wiphy,
|
||||
(signal < 0 || signal > 100)))
|
||||
return NULL;
|
||||
|
||||
channel = cfg80211_get_bss_channel(wiphy, ie, ielen, channel);
|
||||
if (!channel)
|
||||
return NULL;
|
||||
|
||||
res = kzalloc(sizeof(*res) + privsz + ielen, gfp);
|
||||
if (!res)
|
||||
return NULL;
|
||||
@ -839,11 +875,13 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
|
||||
s32 signal, gfp_t gfp)
|
||||
{
|
||||
struct cfg80211_internal_bss *res;
|
||||
|
||||
size_t ielen = len - offsetof(struct ieee80211_mgmt,
|
||||
u.probe_resp.variable);
|
||||
size_t privsz;
|
||||
|
||||
BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) !=
|
||||
offsetof(struct ieee80211_mgmt, u.beacon.variable));
|
||||
|
||||
trace_cfg80211_inform_bss_frame(wiphy, channel, mgmt, len, signal);
|
||||
|
||||
if (WARN_ON(!mgmt))
|
||||
@ -861,6 +899,11 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
|
||||
|
||||
privsz = wiphy->bss_priv_size;
|
||||
|
||||
channel = cfg80211_get_bss_channel(wiphy, mgmt->u.beacon.variable,
|
||||
ielen, channel);
|
||||
if (!channel)
|
||||
return NULL;
|
||||
|
||||
res = kzalloc(sizeof(*res) + privsz + ielen, gfp);
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
@ -20,29 +20,26 @@
|
||||
#define MAC_PR_FMT "%pM"
|
||||
#define MAC_PR_ARG(entry_mac) (__entry->entry_mac)
|
||||
|
||||
#define WIPHY_ENTRY MAC_ENTRY(wiphy_mac)
|
||||
#define WIPHY_ASSIGN MAC_ASSIGN(wiphy_mac, wiphy->perm_addr)
|
||||
#define WIPHY_PR_FMT "wiphy " MAC_PR_FMT
|
||||
#define WIPHY_PR_ARG MAC_PR_ARG(wiphy_mac)
|
||||
#define MAXNAME 32
|
||||
#define WIPHY_ENTRY __array(char, wiphy_name, 32)
|
||||
#define WIPHY_ASSIGN strlcpy(__entry->wiphy_name, wiphy_name(wiphy), MAXNAME)
|
||||
#define WIPHY_PR_FMT "%s"
|
||||
#define WIPHY_PR_ARG __entry->wiphy_name
|
||||
|
||||
#define WDEV_ENTRY __field(u32, id)
|
||||
#define WDEV_ASSIGN (__entry->id) = (wdev ? wdev->identifier : 0)
|
||||
#define WDEV_PR_FMT ", wdev id: %u"
|
||||
#define WDEV_PR_ARG (__entry->id)
|
||||
#define WDEV_ENTRY __field(u32, id)
|
||||
#define WDEV_ASSIGN (__entry->id) = (wdev ? wdev->identifier : 0)
|
||||
#define WDEV_PR_FMT "wdev(%u)"
|
||||
#define WDEV_PR_ARG (__entry->id)
|
||||
|
||||
#define NETDEV_ENTRY __array(char, name, IFNAMSIZ) \
|
||||
MAC_ENTRY(netdev_addr) \
|
||||
__field(int, ifindex)
|
||||
#define NETDEV_ENTRY __array(char, name, IFNAMSIZ) \
|
||||
__field(int, ifindex)
|
||||
#define NETDEV_ASSIGN \
|
||||
do { \
|
||||
memcpy(__entry->name, netdev->name, IFNAMSIZ); \
|
||||
MAC_ASSIGN(netdev_addr, netdev->dev_addr); \
|
||||
(__entry->ifindex) = (netdev->ifindex); \
|
||||
} while (0)
|
||||
#define NETDEV_PR_FMT ", netdev - name: %s, addr: " MAC_PR_FMT \
|
||||
", intf index: %d"
|
||||
#define NETDEV_PR_ARG (__entry->name), MAC_PR_ARG(netdev_addr), \
|
||||
(__entry->ifindex)
|
||||
#define NETDEV_PR_FMT "netdev:%s(%d)"
|
||||
#define NETDEV_PR_ARG __entry->name, __entry->ifindex
|
||||
|
||||
#define MESH_CFG_ENTRY __field(u16, dot11MeshRetryTimeout) \
|
||||
__field(u16, dot11MeshConfirmTimeout) \
|
||||
@ -123,9 +120,37 @@
|
||||
__entry->center_freq = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
#define CHAN_PR_FMT ", band: %d, freq: %u"
|
||||
#define CHAN_PR_FMT "band: %d, freq: %u"
|
||||
#define CHAN_PR_ARG __entry->band, __entry->center_freq
|
||||
|
||||
#define CHAN_DEF_ENTRY __field(enum ieee80211_band, band) \
|
||||
__field(u32, control_freq) \
|
||||
__field(u32, width) \
|
||||
__field(u32, center_freq1) \
|
||||
__field(u32, center_freq2)
|
||||
#define CHAN_DEF_ASSIGN(chandef) \
|
||||
do { \
|
||||
if ((chandef) && (chandef)->chan) { \
|
||||
__entry->band = (chandef)->chan->band; \
|
||||
__entry->control_freq = \
|
||||
(chandef)->chan->center_freq; \
|
||||
__entry->width = (chandef)->width; \
|
||||
__entry->center_freq1 = (chandef)->center_freq1;\
|
||||
__entry->center_freq2 = (chandef)->center_freq2;\
|
||||
} else { \
|
||||
__entry->band = 0; \
|
||||
__entry->control_freq = 0; \
|
||||
__entry->width = 0; \
|
||||
__entry->center_freq1 = 0; \
|
||||
__entry->center_freq2 = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
#define CHAN_DEF_PR_FMT \
|
||||
"band: %d, control freq: %u, width: %d, cf1: %u, cf2: %u"
|
||||
#define CHAN_DEF_PR_ARG __entry->band, __entry->control_freq, \
|
||||
__entry->width, __entry->center_freq1, \
|
||||
__entry->center_freq2
|
||||
|
||||
#define SINFO_ENTRY __field(int, generation) \
|
||||
__field(u32, connected_time) \
|
||||
__field(u32, inactive_time) \
|
||||
@ -313,7 +338,7 @@ DECLARE_EVENT_CLASS(wiphy_wdev_evt,
|
||||
WIPHY_ASSIGN;
|
||||
WDEV_ASSIGN;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT WDEV_PR_FMT, WIPHY_PR_ARG, WDEV_PR_ARG)
|
||||
TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT, WIPHY_PR_ARG, WDEV_PR_ARG)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(wiphy_wdev_evt, rdev_return_wdev,
|
||||
@ -340,7 +365,7 @@ TRACE_EVENT(rdev_change_virtual_intf,
|
||||
NETDEV_ASSIGN;
|
||||
__entry->type = type;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", type: %d",
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", type: %d",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->type)
|
||||
);
|
||||
|
||||
@ -362,7 +387,7 @@ DECLARE_EVENT_CLASS(key_handle,
|
||||
__entry->key_index = key_index;
|
||||
__entry->pairwise = pairwise;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", key_index: %u, pairwise: %s, mac addr: " MAC_PR_FMT,
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", key_index: %u, pairwise: %s, mac addr: " MAC_PR_FMT,
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index,
|
||||
BOOL_TO_STR(__entry->pairwise), MAC_PR_ARG(mac_addr))
|
||||
);
|
||||
@ -403,7 +428,7 @@ TRACE_EVENT(rdev_set_default_key,
|
||||
__entry->unicast = unicast;
|
||||
__entry->multicast = multicast;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", key index: %u, unicast: %s, multicast: %s",
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", key index: %u, unicast: %s, multicast: %s",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index,
|
||||
BOOL_TO_STR(__entry->unicast),
|
||||
BOOL_TO_STR(__entry->multicast))
|
||||
@ -422,7 +447,7 @@ TRACE_EVENT(rdev_set_default_mgmt_key,
|
||||
NETDEV_ASSIGN;
|
||||
__entry->key_index = key_index;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", key index: %u",
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", key index: %u",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index)
|
||||
);
|
||||
|
||||
@ -433,7 +458,7 @@ TRACE_EVENT(rdev_start_ap,
|
||||
TP_STRUCT__entry(
|
||||
WIPHY_ENTRY
|
||||
NETDEV_ENTRY
|
||||
CHAN_ENTRY
|
||||
CHAN_DEF_ENTRY
|
||||
__field(int, beacon_interval)
|
||||
__field(int, dtim_period)
|
||||
__array(char, ssid, IEEE80211_MAX_SSID_LEN + 1)
|
||||
@ -446,7 +471,7 @@ TRACE_EVENT(rdev_start_ap,
|
||||
TP_fast_assign(
|
||||
WIPHY_ASSIGN;
|
||||
NETDEV_ASSIGN;
|
||||
CHAN_ASSIGN(settings->channel);
|
||||
CHAN_DEF_ASSIGN(&settings->chandef);
|
||||
__entry->beacon_interval = settings->beacon_interval;
|
||||
__entry->dtim_period = settings->dtim_period;
|
||||
__entry->hidden_ssid = settings->hidden_ssid;
|
||||
@ -457,11 +482,11 @@ TRACE_EVENT(rdev_start_ap,
|
||||
memset(__entry->ssid, 0, IEEE80211_MAX_SSID_LEN + 1);
|
||||
memcpy(__entry->ssid, settings->ssid, settings->ssid_len);
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", AP settings - ssid: %s, "
|
||||
CHAN_PR_FMT ", beacon interval: %d, dtim period: %d, "
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", AP settings - ssid: %s, "
|
||||
CHAN_DEF_PR_FMT ", beacon interval: %d, dtim period: %d, "
|
||||
"hidden ssid: %d, wpa versions: %u, privacy: %s, "
|
||||
"auth type: %d, inactivity timeout: %d",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->ssid, CHAN_PR_ARG,
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->ssid, CHAN_DEF_PR_ARG,
|
||||
__entry->beacon_interval, __entry->dtim_period,
|
||||
__entry->hidden_ssid, __entry->wpa_ver,
|
||||
BOOL_TO_STR(__entry->privacy), __entry->auth_type,
|
||||
@ -510,7 +535,7 @@ TRACE_EVENT(rdev_change_beacon,
|
||||
info->probe_resp, info->probe_resp_len);
|
||||
}
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG)
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(wiphy_netdev_evt,
|
||||
@ -524,7 +549,7 @@ DECLARE_EVENT_CLASS(wiphy_netdev_evt,
|
||||
WIPHY_ASSIGN;
|
||||
NETDEV_ASSIGN;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG)
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(wiphy_netdev_evt, rdev_stop_ap,
|
||||
@ -602,7 +627,7 @@ DECLARE_EVENT_CLASS(station_add_change,
|
||||
memcpy(__entry->ht_capa, params->ht_capa,
|
||||
sizeof(struct ieee80211_ht_cap));
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", station mac: " MAC_PR_FMT
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: " MAC_PR_FMT
|
||||
", station flags mask: %u, station flags set: %u, "
|
||||
"station modify mask: %u, listen interval: %d, aid: %u, "
|
||||
"plink action: %u, plink state: %u, uapsd queues: %u",
|
||||
@ -638,7 +663,7 @@ DECLARE_EVENT_CLASS(wiphy_netdev_mac_evt,
|
||||
NETDEV_ASSIGN;
|
||||
MAC_ASSIGN(sta_mac, mac);
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", mac: " MAC_PR_FMT,
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", mac: " MAC_PR_FMT,
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac))
|
||||
);
|
||||
|
||||
@ -678,7 +703,7 @@ TRACE_EVENT(rdev_dump_station,
|
||||
MAC_ASSIGN(sta_mac, mac);
|
||||
__entry->idx = idx;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", station mac: " MAC_PR_FMT ", idx: %d",
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: " MAC_PR_FMT ", idx: %d",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac),
|
||||
__entry->idx)
|
||||
);
|
||||
@ -716,7 +741,7 @@ DECLARE_EVENT_CLASS(mpath_evt,
|
||||
MAC_ASSIGN(dst, dst);
|
||||
MAC_ASSIGN(next_hop, next_hop);
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", destination: " MAC_PR_FMT ", next hop: " MAC_PR_FMT,
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", destination: " MAC_PR_FMT ", next hop: " MAC_PR_FMT,
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(dst),
|
||||
MAC_PR_ARG(next_hop))
|
||||
);
|
||||
@ -757,7 +782,7 @@ TRACE_EVENT(rdev_dump_mpath,
|
||||
MAC_ASSIGN(next_hop, next_hop);
|
||||
__entry->idx = idx;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", index: %d, destination: "
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", index: %d, destination: "
|
||||
MAC_PR_FMT ", next hop: " MAC_PR_FMT,
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx, MAC_PR_ARG(dst),
|
||||
MAC_PR_ARG(next_hop))
|
||||
@ -834,7 +859,7 @@ TRACE_EVENT(rdev_update_mesh_config,
|
||||
MESH_CFG_ASSIGN;
|
||||
__entry->mask = mask;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", mask: %u",
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", mask: %u",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->mask)
|
||||
);
|
||||
|
||||
@ -853,7 +878,7 @@ TRACE_EVENT(rdev_join_mesh,
|
||||
NETDEV_ASSIGN;
|
||||
MESH_CFG_ASSIGN;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT,
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT,
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG)
|
||||
);
|
||||
|
||||
@ -879,7 +904,7 @@ TRACE_EVENT(rdev_change_bss,
|
||||
__entry->ap_isolate = params->ap_isolate;
|
||||
__entry->ht_opmode = params->ht_opmode;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", use cts prot: %d, "
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", use cts prot: %d, "
|
||||
"use short preamble: %d, use short slot time: %d, "
|
||||
"ap isolate: %d, ht opmode: %d",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->use_cts_prot,
|
||||
@ -909,7 +934,7 @@ TRACE_EVENT(rdev_set_txq_params,
|
||||
__entry->cwmax = params->cwmax;
|
||||
__entry->aifs = params->aifs;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", ac: %d, txop: %u, cwmin: %u, cwmax: %u, aifs: %u",
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", ac: %d, txop: %u, cwmin: %u, cwmax: %u, aifs: %u",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->ac, __entry->txop,
|
||||
__entry->cwmin, __entry->cwmax, __entry->aifs)
|
||||
);
|
||||
@ -928,26 +953,24 @@ TRACE_EVENT(rdev_libertas_set_mesh_channel,
|
||||
NETDEV_ASSIGN;
|
||||
CHAN_ASSIGN(chan);
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT CHAN_PR_FMT, WIPHY_PR_ARG,
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " CHAN_PR_FMT, WIPHY_PR_ARG,
|
||||
NETDEV_PR_ARG, CHAN_PR_ARG)
|
||||
);
|
||||
|
||||
TRACE_EVENT(rdev_set_monitor_channel,
|
||||
TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type chan_type),
|
||||
TP_ARGS(wiphy, chan, chan_type),
|
||||
TP_PROTO(struct wiphy *wiphy,
|
||||
struct cfg80211_chan_def *chandef),
|
||||
TP_ARGS(wiphy, chandef),
|
||||
TP_STRUCT__entry(
|
||||
WIPHY_ENTRY
|
||||
CHAN_ENTRY
|
||||
__field(enum nl80211_channel_type, chan_type)
|
||||
CHAN_DEF_ENTRY
|
||||
),
|
||||
TP_fast_assign(
|
||||
WIPHY_ASSIGN;
|
||||
CHAN_ASSIGN(chan);
|
||||
__entry->chan_type = chan_type;
|
||||
CHAN_DEF_ASSIGN(chandef);
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT CHAN_PR_FMT ", channel type : %d",
|
||||
WIPHY_PR_ARG, CHAN_PR_ARG, __entry->chan_type)
|
||||
TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT,
|
||||
WIPHY_PR_ARG, CHAN_DEF_PR_ARG)
|
||||
);
|
||||
|
||||
TRACE_EVENT(rdev_auth,
|
||||
@ -969,7 +992,7 @@ TRACE_EVENT(rdev_auth,
|
||||
memset(__entry->bssid, 0, ETH_ALEN);
|
||||
__entry->auth_type = req->auth_type;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", auth type: %d, bssid: " MAC_PR_FMT,
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", auth type: %d, bssid: " MAC_PR_FMT,
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->auth_type,
|
||||
MAC_PR_ARG(bssid))
|
||||
);
|
||||
@ -997,7 +1020,7 @@ TRACE_EVENT(rdev_assoc,
|
||||
__entry->use_mfp = req->use_mfp;
|
||||
__entry->flags = req->flags;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT
|
||||
", previous bssid: " MAC_PR_FMT ", use mfp: %s, flags: %u",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid),
|
||||
MAC_PR_ARG(prev_bssid), BOOL_TO_STR(__entry->use_mfp),
|
||||
@ -1020,7 +1043,7 @@ TRACE_EVENT(rdev_deauth,
|
||||
MAC_ASSIGN(bssid, req->bssid);
|
||||
__entry->reason_code = req->reason_code;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", reason: %u",
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", reason: %u",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid),
|
||||
__entry->reason_code)
|
||||
);
|
||||
@ -1046,7 +1069,7 @@ TRACE_EVENT(rdev_disassoc,
|
||||
__entry->reason_code = req->reason_code;
|
||||
__entry->local_state_change = req->local_state_change;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT
|
||||
", reason: %u, local state change: %s",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid),
|
||||
__entry->reason_code,
|
||||
@ -1067,7 +1090,7 @@ TRACE_EVENT(rdev_mgmt_tx_cancel_wait,
|
||||
WDEV_ASSIGN;
|
||||
__entry->cookie = cookie;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT WDEV_PR_FMT ", cookie: %llu ",
|
||||
TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", cookie: %llu ",
|
||||
WIPHY_PR_ARG, WDEV_PR_ARG, __entry->cookie)
|
||||
);
|
||||
|
||||
@ -1087,7 +1110,7 @@ TRACE_EVENT(rdev_set_power_mgmt,
|
||||
__entry->enabled = enabled;
|
||||
__entry->timeout = timeout;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", %senabled, timeout: %d ",
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", %senabled, timeout: %d ",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG,
|
||||
__entry->enabled ? "" : "not ", __entry->timeout)
|
||||
);
|
||||
@ -1117,7 +1140,7 @@ TRACE_EVENT(rdev_connect,
|
||||
__entry->wpa_versions = sme->crypto.wpa_versions;
|
||||
__entry->flags = sme->flags;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT
|
||||
", ssid: %s, auth type: %d, privacy: %s, wpa versions: %u, "
|
||||
"flags: %u",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), __entry->ssid,
|
||||
@ -1142,7 +1165,7 @@ TRACE_EVENT(rdev_set_cqm_rssi_config,
|
||||
__entry->rssi_thold = rssi_thold;
|
||||
__entry->rssi_hyst = rssi_hyst;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT
|
||||
", rssi_thold: %d, rssi_hyst: %u ",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG,
|
||||
__entry->rssi_thold, __entry->rssi_hyst)
|
||||
@ -1166,7 +1189,7 @@ TRACE_EVENT(rdev_set_cqm_txe_config,
|
||||
__entry->pkts = pkts;
|
||||
__entry->intvl = intvl;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", rate: %u, packets: %u, interval: %u",
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", rate: %u, packets: %u, interval: %u",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->rate, __entry->pkts,
|
||||
__entry->intvl)
|
||||
);
|
||||
@ -1185,7 +1208,7 @@ TRACE_EVENT(rdev_disconnect,
|
||||
NETDEV_ASSIGN;
|
||||
__entry->reason_code = reason_code;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", reason code: %u", WIPHY_PR_ARG,
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", reason code: %u", WIPHY_PR_ARG,
|
||||
NETDEV_PR_ARG, __entry->reason_code)
|
||||
);
|
||||
|
||||
@ -1206,7 +1229,7 @@ TRACE_EVENT(rdev_join_ibss,
|
||||
memset(__entry->ssid, 0, IEEE80211_MAX_SSID_LEN + 1);
|
||||
memcpy(__entry->ssid, params->ssid, params->ssid_len);
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", ssid: %s",
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", ssid: %s",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), __entry->ssid)
|
||||
);
|
||||
|
||||
@ -1246,7 +1269,7 @@ TRACE_EVENT(rdev_set_tx_power,
|
||||
__entry->type = type;
|
||||
__entry->mbm = mbm;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT WDEV_PR_FMT ", type: %d, mbm: %d",
|
||||
TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", type: %u, mbm: %d",
|
||||
WIPHY_PR_ARG, WDEV_PR_ARG,__entry->type, __entry->mbm)
|
||||
);
|
||||
|
||||
@ -1307,7 +1330,7 @@ TRACE_EVENT(rdev_set_bitrate_mask,
|
||||
NETDEV_ASSIGN;
|
||||
MAC_ASSIGN(peer, peer);
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", peer: " MAC_PR_FMT,
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT,
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer))
|
||||
);
|
||||
|
||||
@ -1327,7 +1350,7 @@ TRACE_EVENT(rdev_mgmt_frame_register,
|
||||
__entry->frame_type = frame_type;
|
||||
__entry->reg = reg;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT WDEV_PR_FMT ", frame_type: %u, reg: %s ",
|
||||
TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", frame_type: 0x%.2x, reg: %s ",
|
||||
WIPHY_PR_ARG, WDEV_PR_ARG, __entry->frame_type,
|
||||
__entry->reg ? "true" : "false")
|
||||
);
|
||||
@ -1413,7 +1436,7 @@ TRACE_EVENT(rdev_sched_scan_start,
|
||||
WIPHY_ASSIGN;
|
||||
NETDEV_ASSIGN;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT,
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT,
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG)
|
||||
);
|
||||
|
||||
@ -1441,7 +1464,7 @@ TRACE_EVENT(rdev_tdls_mgmt,
|
||||
__entry->status_code = status_code;
|
||||
memcpy(__get_dynamic_array(buf), buf, len);
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT MAC_PR_FMT ", action_code: %u, "
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ", action_code: %u, "
|
||||
"dialog_token: %u, status_code: %u, buf: %#.2x ",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer),
|
||||
__entry->action_code, __entry->dialog_token,
|
||||
@ -1461,7 +1484,7 @@ TRACE_EVENT(rdev_dump_survey,
|
||||
NETDEV_ASSIGN;
|
||||
__entry->idx = idx;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", index: %d",
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", index: %d",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx)
|
||||
);
|
||||
|
||||
@ -1518,7 +1541,7 @@ TRACE_EVENT(rdev_tdls_oper,
|
||||
MAC_ASSIGN(peer, peer);
|
||||
__entry->oper = oper;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT MAC_PR_FMT ", oper: %d",
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ", oper: %d",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), __entry->oper)
|
||||
);
|
||||
|
||||
@ -1536,7 +1559,7 @@ DECLARE_EVENT_CLASS(rdev_pmksa,
|
||||
NETDEV_ASSIGN;
|
||||
MAC_ASSIGN(bssid, pmksa->bssid);
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT,
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT,
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid))
|
||||
);
|
||||
|
||||
@ -1554,7 +1577,7 @@ TRACE_EVENT(rdev_probe_client,
|
||||
NETDEV_ASSIGN;
|
||||
MAC_ASSIGN(peer, peer);
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT MAC_PR_FMT,
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT,
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer))
|
||||
);
|
||||
|
||||
@ -1573,25 +1596,22 @@ DEFINE_EVENT(rdev_pmksa, rdev_del_pmksa,
|
||||
TRACE_EVENT(rdev_remain_on_channel,
|
||||
TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type, unsigned int duration),
|
||||
TP_ARGS(wiphy, wdev, chan, channel_type, duration),
|
||||
unsigned int duration),
|
||||
TP_ARGS(wiphy, wdev, chan, duration),
|
||||
TP_STRUCT__entry(
|
||||
WIPHY_ENTRY
|
||||
WDEV_ENTRY
|
||||
CHAN_ENTRY
|
||||
__field(enum nl80211_channel_type, channel_type)
|
||||
__field(unsigned int, duration)
|
||||
),
|
||||
TP_fast_assign(
|
||||
WIPHY_ASSIGN;
|
||||
WDEV_ASSIGN;
|
||||
CHAN_ASSIGN(chan);
|
||||
__entry->channel_type = channel_type;
|
||||
__entry->duration = duration;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT WDEV_PR_FMT CHAN_PR_FMT ", channel type: %d, duration: %u",
|
||||
WIPHY_PR_ARG, WDEV_PR_ARG, CHAN_PR_ARG, __entry->channel_type,
|
||||
__entry->duration)
|
||||
TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", " CHAN_PR_FMT ", duration: %u",
|
||||
WIPHY_PR_ARG, WDEV_PR_ARG, CHAN_PR_ARG, __entry->duration)
|
||||
);
|
||||
|
||||
TRACE_EVENT(rdev_return_int_cookie,
|
||||
@ -1624,25 +1644,20 @@ TRACE_EVENT(rdev_cancel_remain_on_channel,
|
||||
WDEV_ASSIGN;
|
||||
__entry->cookie = cookie;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT WDEV_PR_FMT ", cookie: %llu",
|
||||
TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", cookie: %llu",
|
||||
WIPHY_PR_ARG, WDEV_PR_ARG, __entry->cookie)
|
||||
);
|
||||
|
||||
TRACE_EVENT(rdev_mgmt_tx,
|
||||
TP_PROTO(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, bool no_cck,
|
||||
bool dont_wait_for_ack),
|
||||
TP_ARGS(wiphy, wdev, chan, offchan, channel_type, channel_type_valid,
|
||||
wait, no_cck, dont_wait_for_ack),
|
||||
unsigned int wait, bool no_cck, bool dont_wait_for_ack),
|
||||
TP_ARGS(wiphy, wdev, chan, offchan, wait, no_cck, dont_wait_for_ack),
|
||||
TP_STRUCT__entry(
|
||||
WIPHY_ENTRY
|
||||
WDEV_ENTRY
|
||||
CHAN_ENTRY
|
||||
__field(bool, offchan)
|
||||
__field(enum nl80211_channel_type, channel_type)
|
||||
__field(bool, channel_type_valid)
|
||||
__field(unsigned int, wait)
|
||||
__field(bool, no_cck)
|
||||
__field(bool, dont_wait_for_ack)
|
||||
@ -1652,18 +1667,14 @@ TRACE_EVENT(rdev_mgmt_tx,
|
||||
WDEV_ASSIGN;
|
||||
CHAN_ASSIGN(chan);
|
||||
__entry->offchan = offchan;
|
||||
__entry->channel_type = channel_type;
|
||||
__entry->channel_type_valid = channel_type_valid;
|
||||
__entry->wait = wait;
|
||||
__entry->no_cck = no_cck;
|
||||
__entry->dont_wait_for_ack = dont_wait_for_ack;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT WDEV_PR_FMT CHAN_PR_FMT ", offchan: %s, "
|
||||
"channel type: %d, channel type valid: %s, wait: %u, "
|
||||
"no cck: %s, dont wait for ack: %s",
|
||||
TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", " CHAN_PR_FMT ", offchan: %s,"
|
||||
" wait: %u, no cck: %s, dont wait for ack: %s",
|
||||
WIPHY_PR_ARG, WDEV_PR_ARG, CHAN_PR_ARG,
|
||||
BOOL_TO_STR(__entry->offchan), __entry->channel_type,
|
||||
BOOL_TO_STR(__entry->channel_type_valid), __entry->wait,
|
||||
BOOL_TO_STR(__entry->offchan), __entry->wait,
|
||||
BOOL_TO_STR(__entry->no_cck),
|
||||
BOOL_TO_STR(__entry->dont_wait_for_ack))
|
||||
);
|
||||
@ -1682,7 +1693,7 @@ TRACE_EVENT(rdev_set_noack_map,
|
||||
NETDEV_ASSIGN;
|
||||
__entry->noack_map = noack_map;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", noack_map: %u",
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", noack_map: %u",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->noack_map)
|
||||
);
|
||||
|
||||
@ -1699,7 +1710,7 @@ TRACE_EVENT(rdev_get_et_sset_count,
|
||||
NETDEV_ASSIGN;
|
||||
__entry->sset = sset;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", sset: %d",
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", sset: %d",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sset)
|
||||
);
|
||||
|
||||
@ -1716,7 +1727,7 @@ TRACE_EVENT(rdev_get_et_strings,
|
||||
NETDEV_ASSIGN;
|
||||
__entry->sset = sset;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", sset: %u",
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", sset: %u",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sset)
|
||||
);
|
||||
|
||||
@ -1725,22 +1736,25 @@ DEFINE_EVENT(wiphy_wdev_evt, rdev_get_channel,
|
||||
TP_ARGS(wiphy, wdev)
|
||||
);
|
||||
|
||||
TRACE_EVENT(rdev_return_channel,
|
||||
TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type type),
|
||||
TP_ARGS(wiphy, chan, type),
|
||||
TRACE_EVENT(rdev_return_chandef,
|
||||
TP_PROTO(struct wiphy *wiphy, int ret,
|
||||
struct cfg80211_chan_def *chandef),
|
||||
TP_ARGS(wiphy, ret, chandef),
|
||||
TP_STRUCT__entry(
|
||||
WIPHY_ENTRY
|
||||
CHAN_ENTRY
|
||||
__field(enum nl80211_channel_type, type)
|
||||
__field(int, ret)
|
||||
CHAN_DEF_ENTRY
|
||||
),
|
||||
TP_fast_assign(
|
||||
WIPHY_ASSIGN;
|
||||
CHAN_ASSIGN(chan);
|
||||
__entry->type = type;
|
||||
if (ret == 0)
|
||||
CHAN_DEF_ASSIGN(chandef);
|
||||
else
|
||||
CHAN_DEF_ASSIGN((struct cfg80211_chan_def *)NULL);
|
||||
__entry->ret = ret;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT CHAN_PR_FMT ", channel type: %d",
|
||||
WIPHY_PR_ARG, CHAN_PR_ARG, __entry->type)
|
||||
TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT ", ret: %d",
|
||||
WIPHY_PR_ARG, CHAN_DEF_PR_ARG, __entry->ret)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(wiphy_wdev_evt, rdev_start_p2p_device,
|
||||
@ -1819,7 +1833,7 @@ TRACE_EVENT(cfg80211_send_rx_assoc,
|
||||
MAC_ASSIGN(bssid, bss->bssid);
|
||||
CHAN_ASSIGN(bss->channel);
|
||||
),
|
||||
TP_printk(NETDEV_PR_FMT MAC_PR_FMT CHAN_PR_FMT,
|
||||
TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT ", " CHAN_PR_FMT,
|
||||
NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG)
|
||||
);
|
||||
|
||||
@ -1886,7 +1900,7 @@ TRACE_EVENT(cfg80211_michael_mic_failure,
|
||||
__entry->key_id = key_id;
|
||||
memcpy(__entry->tsc, tsc, 6);
|
||||
),
|
||||
TP_printk(NETDEV_PR_FMT MAC_PR_FMT ", key type: %d, key id: %d, tsc: %pm",
|
||||
TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT ", key type: %d, key id: %d, tsc: %pm",
|
||||
NETDEV_PR_ARG, MAC_PR_ARG(addr), __entry->key_type,
|
||||
__entry->key_id, __entry->tsc)
|
||||
);
|
||||
@ -1894,47 +1908,41 @@ TRACE_EVENT(cfg80211_michael_mic_failure,
|
||||
TRACE_EVENT(cfg80211_ready_on_channel,
|
||||
TP_PROTO(struct wireless_dev *wdev, u64 cookie,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type, unsigned int duration),
|
||||
TP_ARGS(wdev, cookie, chan, channel_type, duration),
|
||||
unsigned int duration),
|
||||
TP_ARGS(wdev, cookie, chan, duration),
|
||||
TP_STRUCT__entry(
|
||||
WDEV_ENTRY
|
||||
__field(u64, cookie)
|
||||
CHAN_ENTRY
|
||||
__field(enum nl80211_channel_type, channel_type)
|
||||
__field(unsigned int, duration)
|
||||
),
|
||||
TP_fast_assign(
|
||||
WDEV_ASSIGN;
|
||||
__entry->cookie = cookie;
|
||||
CHAN_ASSIGN(chan);
|
||||
__entry->channel_type = channel_type;
|
||||
__entry->duration = duration;
|
||||
),
|
||||
TP_printk(WDEV_PR_FMT ", cookie: %llu, " CHAN_PR_FMT ", channel type: %d, duration: %u",
|
||||
TP_printk(WDEV_PR_FMT ", cookie: %llu, " CHAN_PR_FMT ", duration: %u",
|
||||
WDEV_PR_ARG, __entry->cookie, CHAN_PR_ARG,
|
||||
__entry->channel_type, __entry->duration)
|
||||
__entry->duration)
|
||||
);
|
||||
|
||||
TRACE_EVENT(cfg80211_ready_on_channel_expired,
|
||||
TP_PROTO(struct wireless_dev *wdev, u64 cookie,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type),
|
||||
TP_ARGS(wdev, cookie, chan, channel_type),
|
||||
struct ieee80211_channel *chan),
|
||||
TP_ARGS(wdev, cookie, chan),
|
||||
TP_STRUCT__entry(
|
||||
WDEV_ENTRY
|
||||
__field(u64, cookie)
|
||||
CHAN_ENTRY
|
||||
__field(enum nl80211_channel_type, channel_type)
|
||||
),
|
||||
TP_fast_assign(
|
||||
WDEV_ASSIGN;
|
||||
__entry->cookie = cookie;
|
||||
CHAN_ASSIGN(chan);
|
||||
__entry->channel_type = channel_type;
|
||||
),
|
||||
TP_printk(WDEV_PR_FMT ", cookie: %llu, " CHAN_PR_FMT ", channel type: %d",
|
||||
WDEV_PR_ARG, __entry->cookie, CHAN_PR_ARG,
|
||||
__entry->channel_type)
|
||||
TP_printk(WDEV_PR_FMT ", cookie: %llu, " CHAN_PR_FMT,
|
||||
WDEV_PR_ARG, __entry->cookie, CHAN_PR_ARG)
|
||||
);
|
||||
|
||||
TRACE_EVENT(cfg80211_new_sta,
|
||||
@ -1951,7 +1959,7 @@ TRACE_EVENT(cfg80211_new_sta,
|
||||
MAC_ASSIGN(mac_addr, mac_addr);
|
||||
SINFO_ASSIGN;
|
||||
),
|
||||
TP_printk(NETDEV_PR_FMT MAC_PR_FMT,
|
||||
TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT,
|
||||
NETDEV_PR_ARG, MAC_PR_ARG(mac_addr))
|
||||
);
|
||||
|
||||
@ -2010,40 +2018,35 @@ TRACE_EVENT(cfg80211_cqm_rssi_notify,
|
||||
NETDEV_PR_ARG, __entry->rssi_event)
|
||||
);
|
||||
|
||||
TRACE_EVENT(cfg80211_can_beacon_sec_chan,
|
||||
TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *channel,
|
||||
enum nl80211_channel_type channel_type),
|
||||
TP_ARGS(wiphy, channel, channel_type),
|
||||
TRACE_EVENT(cfg80211_reg_can_beacon,
|
||||
TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef),
|
||||
TP_ARGS(wiphy, chandef),
|
||||
TP_STRUCT__entry(
|
||||
WIPHY_ENTRY
|
||||
CHAN_ENTRY
|
||||
__field(enum nl80211_channel_type, channel_type)
|
||||
CHAN_DEF_ENTRY
|
||||
),
|
||||
TP_fast_assign(
|
||||
WIPHY_ASSIGN;
|
||||
CHAN_ASSIGN(channel);
|
||||
__entry->channel_type = channel_type;
|
||||
CHAN_DEF_ASSIGN(chandef);
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT CHAN_PR_FMT ", channel_type: %d",
|
||||
WIPHY_PR_ARG, CHAN_PR_ARG, __entry->channel_type)
|
||||
TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT,
|
||||
WIPHY_PR_ARG, CHAN_DEF_PR_ARG)
|
||||
);
|
||||
|
||||
TRACE_EVENT(cfg80211_ch_switch_notify,
|
||||
TP_PROTO(struct net_device *netdev, int freq,
|
||||
enum nl80211_channel_type type),
|
||||
TP_ARGS(netdev, freq, type),
|
||||
TP_PROTO(struct net_device *netdev,
|
||||
struct cfg80211_chan_def *chandef),
|
||||
TP_ARGS(netdev, chandef),
|
||||
TP_STRUCT__entry(
|
||||
NETDEV_ENTRY
|
||||
__field(int, freq)
|
||||
__field(enum nl80211_channel_type, type)
|
||||
CHAN_DEF_ENTRY
|
||||
),
|
||||
TP_fast_assign(
|
||||
NETDEV_ASSIGN;
|
||||
__entry->freq = freq;
|
||||
__entry->type = type;
|
||||
CHAN_DEF_ASSIGN(chandef);
|
||||
),
|
||||
TP_printk(NETDEV_PR_FMT ", freq: %d, type: %d", NETDEV_PR_ARG,
|
||||
__entry->freq, __entry->type)
|
||||
TP_printk(NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT,
|
||||
NETDEV_PR_ARG, CHAN_DEF_PR_ARG)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(cfg80211_rx_evt,
|
||||
@ -2057,7 +2060,7 @@ DECLARE_EVENT_CLASS(cfg80211_rx_evt,
|
||||
NETDEV_ASSIGN;
|
||||
MAC_ASSIGN(addr, addr);
|
||||
),
|
||||
TP_printk(NETDEV_PR_FMT MAC_PR_FMT, NETDEV_PR_ARG, MAC_PR_ARG(addr))
|
||||
TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT, NETDEV_PR_ARG, MAC_PR_ARG(addr))
|
||||
);
|
||||
|
||||
DEFINE_EVENT(cfg80211_rx_evt, cfg80211_ibss_joined,
|
||||
@ -2091,7 +2094,7 @@ TRACE_EVENT(cfg80211_probe_status,
|
||||
__entry->cookie = cookie;
|
||||
__entry->acked = acked;
|
||||
),
|
||||
TP_printk(NETDEV_PR_FMT MAC_PR_FMT ", cookie: %llu, acked: %s",
|
||||
TP_printk(NETDEV_PR_FMT " addr:" MAC_PR_FMT ", cookie: %llu, acked: %s",
|
||||
NETDEV_PR_ARG, MAC_PR_ARG(addr), __entry->cookie,
|
||||
BOOL_TO_STR(__entry->acked))
|
||||
);
|
||||
@ -2241,7 +2244,7 @@ TRACE_EVENT(cfg80211_get_bss,
|
||||
__entry->capa_mask = capa_mask;
|
||||
__entry->capa_val = capa_val;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT CHAN_PR_FMT MAC_PR_FMT ", buf: %#.2x, "
|
||||
TP_printk(WIPHY_PR_FMT ", " CHAN_PR_FMT ", " MAC_PR_FMT ", buf: %#.2x, "
|
||||
"capa_mask: %d, capa_val: %u", WIPHY_PR_ARG, CHAN_PR_ARG,
|
||||
MAC_PR_ARG(bssid), ((u8 *)__get_dynamic_array(ssid))[0],
|
||||
__entry->capa_mask, __entry->capa_val)
|
||||
@ -2265,7 +2268,7 @@ TRACE_EVENT(cfg80211_inform_bss_frame,
|
||||
memcpy(__get_dynamic_array(mgmt), mgmt, len);
|
||||
__entry->signal = signal;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT CHAN_PR_FMT "signal: %d",
|
||||
TP_printk(WIPHY_PR_FMT ", " CHAN_PR_FMT "signal: %d",
|
||||
WIPHY_PR_ARG, CHAN_PR_ARG, __entry->signal)
|
||||
);
|
||||
|
||||
@ -2280,7 +2283,7 @@ DECLARE_EVENT_CLASS(cfg80211_bss_evt,
|
||||
MAC_ASSIGN(bssid, pub->bssid);
|
||||
CHAN_ASSIGN(pub->channel);
|
||||
),
|
||||
TP_printk(MAC_PR_FMT CHAN_PR_FMT, MAC_PR_ARG(bssid), CHAN_PR_ARG)
|
||||
TP_printk(MAC_PR_FMT ", " CHAN_PR_FMT, MAC_PR_ARG(bssid), CHAN_PR_ARG)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(cfg80211_bss_evt, cfg80211_return_bss,
|
||||
|
@ -944,14 +944,86 @@ static u32 cfg80211_calculate_bitrate_60g(struct rate_info *rate)
|
||||
return __mcs2bitrate[rate->mcs];
|
||||
}
|
||||
|
||||
static u32 cfg80211_calculate_bitrate_vht(struct rate_info *rate)
|
||||
{
|
||||
static const u32 base[4][10] = {
|
||||
{ 6500000,
|
||||
13000000,
|
||||
19500000,
|
||||
26000000,
|
||||
39000000,
|
||||
52000000,
|
||||
58500000,
|
||||
65000000,
|
||||
78000000,
|
||||
0,
|
||||
},
|
||||
{ 13500000,
|
||||
27000000,
|
||||
40500000,
|
||||
54000000,
|
||||
81000000,
|
||||
108000000,
|
||||
121500000,
|
||||
135000000,
|
||||
162000000,
|
||||
180000000,
|
||||
},
|
||||
{ 29300000,
|
||||
58500000,
|
||||
87800000,
|
||||
117000000,
|
||||
175500000,
|
||||
234000000,
|
||||
263300000,
|
||||
292500000,
|
||||
351000000,
|
||||
390000000,
|
||||
},
|
||||
{ 58500000,
|
||||
117000000,
|
||||
175500000,
|
||||
234000000,
|
||||
351000000,
|
||||
468000000,
|
||||
526500000,
|
||||
585000000,
|
||||
702000000,
|
||||
780000000,
|
||||
},
|
||||
};
|
||||
u32 bitrate;
|
||||
int idx;
|
||||
|
||||
if (WARN_ON_ONCE(rate->mcs > 9))
|
||||
return 0;
|
||||
|
||||
idx = rate->flags & (RATE_INFO_FLAGS_160_MHZ_WIDTH |
|
||||
RATE_INFO_FLAGS_80P80_MHZ_WIDTH) ? 3 :
|
||||
rate->flags & RATE_INFO_FLAGS_80_MHZ_WIDTH ? 2 :
|
||||
rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH ? 1 : 0;
|
||||
|
||||
bitrate = base[idx][rate->mcs];
|
||||
bitrate *= rate->nss;
|
||||
|
||||
if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
|
||||
bitrate = (bitrate / 9) * 10;
|
||||
|
||||
/* do NOT round down here */
|
||||
return (bitrate + 50000) / 100000;
|
||||
}
|
||||
|
||||
u32 cfg80211_calculate_bitrate(struct rate_info *rate)
|
||||
{
|
||||
int modulation, streams, bitrate;
|
||||
|
||||
if (!(rate->flags & RATE_INFO_FLAGS_MCS))
|
||||
if (!(rate->flags & RATE_INFO_FLAGS_MCS) &&
|
||||
!(rate->flags & RATE_INFO_FLAGS_VHT_MCS))
|
||||
return rate->legacy;
|
||||
if (rate->flags & RATE_INFO_FLAGS_60G)
|
||||
return cfg80211_calculate_bitrate_60g(rate);
|
||||
if (rate->flags & RATE_INFO_FLAGS_VHT_MCS)
|
||||
return cfg80211_calculate_bitrate_vht(rate);
|
||||
|
||||
/* the formula below does only work for MCS values smaller than 32 */
|
||||
if (WARN_ON_ONCE(rate->mcs >= 32))
|
||||
@ -980,8 +1052,9 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate)
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_calculate_bitrate);
|
||||
|
||||
unsigned int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len,
|
||||
u8 attr, u8 *buf, unsigned int bufsize)
|
||||
int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len,
|
||||
enum ieee80211_p2p_attr_id attr,
|
||||
u8 *buf, unsigned int bufsize)
|
||||
{
|
||||
u8 *out = buf;
|
||||
u16 attr_remaining = 0;
|
||||
|
@ -784,6 +784,9 @@ static int cfg80211_wext_siwfreq(struct net_device *dev,
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
|
||||
struct cfg80211_chan_def chandef = {
|
||||
.width = NL80211_CHAN_WIDTH_20_NOHT,
|
||||
};
|
||||
int freq, err;
|
||||
|
||||
switch (wdev->iftype) {
|
||||
@ -797,8 +800,12 @@ static int cfg80211_wext_siwfreq(struct net_device *dev,
|
||||
return freq;
|
||||
if (freq == 0)
|
||||
return -EINVAL;
|
||||
chandef.center_freq1 = freq;
|
||||
chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
|
||||
if (!chandef.chan)
|
||||
return -EINVAL;
|
||||
mutex_lock(&rdev->devlist_mtx);
|
||||
err = cfg80211_set_monitor_channel(rdev, freq, NL80211_CHAN_NO_HT);
|
||||
err = cfg80211_set_monitor_channel(rdev, &chandef);
|
||||
mutex_unlock(&rdev->devlist_mtx);
|
||||
return err;
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
@ -807,9 +814,12 @@ static int cfg80211_wext_siwfreq(struct net_device *dev,
|
||||
return freq;
|
||||
if (freq == 0)
|
||||
return -EINVAL;
|
||||
chandef.center_freq1 = freq;
|
||||
chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
|
||||
if (!chandef.chan)
|
||||
return -EINVAL;
|
||||
mutex_lock(&rdev->devlist_mtx);
|
||||
err = cfg80211_set_mesh_freq(rdev, wdev, freq,
|
||||
NL80211_CHAN_NO_HT);
|
||||
err = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
|
||||
mutex_unlock(&rdev->devlist_mtx);
|
||||
return err;
|
||||
default:
|
||||
@ -823,8 +833,8 @@ static int cfg80211_wext_giwfreq(struct net_device *dev,
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
|
||||
struct ieee80211_channel *chan;
|
||||
enum nl80211_channel_type channel_type;
|
||||
struct cfg80211_chan_def chandef;
|
||||
int ret;
|
||||
|
||||
switch (wdev->iftype) {
|
||||
case NL80211_IFTYPE_STATION:
|
||||
@ -835,10 +845,10 @@ static int cfg80211_wext_giwfreq(struct net_device *dev,
|
||||
if (!rdev->ops->get_channel)
|
||||
return -EINVAL;
|
||||
|
||||
chan = rdev_get_channel(rdev, wdev, &channel_type);
|
||||
if (!chan)
|
||||
return -EINVAL;
|
||||
freq->m = chan->center_freq;
|
||||
ret = rdev_get_channel(rdev, wdev, &chandef);
|
||||
if (ret)
|
||||
return ret;
|
||||
freq->m = chandef.chan->center_freq;
|
||||
freq->e = 6;
|
||||
return 0;
|
||||
default:
|
||||
|
@ -119,7 +119,16 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
|
||||
* channel we disconnected above and reconnect below.
|
||||
*/
|
||||
if (chan && !wdev->wext.connect.ssid_len) {
|
||||
err = cfg80211_set_monitor_channel(rdev, freq, NL80211_CHAN_NO_HT);
|
||||
struct cfg80211_chan_def chandef = {
|
||||
.width = NL80211_CHAN_WIDTH_20_NOHT,
|
||||
.center_freq1 = freq,
|
||||
};
|
||||
|
||||
chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
|
||||
if (chandef.chan)
|
||||
err = cfg80211_set_monitor_channel(rdev, &chandef);
|
||||
else
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user