Merge tag 'mac80211-next-for-davem-2018-06-29' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Small merge conflict in net/mac80211/scan.c, I preserved the kcalloc() conversion. -DaveM Johannes Berg says: ==================== This round's updates: * finally some of the promised HE code, but it turns out to be small - but everything kept changing, so one part I did in the driver was >30 patches for what was ultimately <200 lines of code ... similar here for this code. * improved scan privacy support - can now specify scan flags for randomizing the sequence number as well as reducing the probe request element content * rfkill cleanups * a timekeeping cleanup from Arnd * various other cleanups ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -428,6 +428,8 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
||||
[NL80211_ATTR_TXQ_LIMIT] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_TXQ_MEMORY_LIMIT] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_TXQ_QUANTUM] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_HE_CAPABILITY] = { .type = NLA_BINARY,
|
||||
.len = NL80211_HE_MAX_CAPABILITY_LEN },
|
||||
};
|
||||
|
||||
/* policy for the key attributes */
|
||||
@@ -1324,6 +1326,34 @@ static int nl80211_send_coalesce(struct sk_buff *msg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nl80211_send_iftype_data(struct sk_buff *msg,
|
||||
const struct ieee80211_sband_iftype_data *iftdata)
|
||||
{
|
||||
const struct ieee80211_sta_he_cap *he_cap = &iftdata->he_cap;
|
||||
|
||||
if (nl80211_put_iftypes(msg, NL80211_BAND_IFTYPE_ATTR_IFTYPES,
|
||||
iftdata->types_mask))
|
||||
return -ENOBUFS;
|
||||
|
||||
if (he_cap->has_he) {
|
||||
if (nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC,
|
||||
sizeof(he_cap->he_cap_elem.mac_cap_info),
|
||||
he_cap->he_cap_elem.mac_cap_info) ||
|
||||
nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY,
|
||||
sizeof(he_cap->he_cap_elem.phy_cap_info),
|
||||
he_cap->he_cap_elem.phy_cap_info) ||
|
||||
nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET,
|
||||
sizeof(he_cap->he_mcs_nss_supp),
|
||||
&he_cap->he_mcs_nss_supp) ||
|
||||
nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE,
|
||||
sizeof(he_cap->ppe_thres), he_cap->ppe_thres))
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nl80211_send_band_rateinfo(struct sk_buff *msg,
|
||||
struct ieee80211_supported_band *sband)
|
||||
{
|
||||
@@ -1353,6 +1383,32 @@ static int nl80211_send_band_rateinfo(struct sk_buff *msg,
|
||||
sband->vht_cap.cap)))
|
||||
return -ENOBUFS;
|
||||
|
||||
if (sband->n_iftype_data) {
|
||||
struct nlattr *nl_iftype_data =
|
||||
nla_nest_start(msg, NL80211_BAND_ATTR_IFTYPE_DATA);
|
||||
int err;
|
||||
|
||||
if (!nl_iftype_data)
|
||||
return -ENOBUFS;
|
||||
|
||||
for (i = 0; i < sband->n_iftype_data; i++) {
|
||||
struct nlattr *iftdata;
|
||||
|
||||
iftdata = nla_nest_start(msg, i + 1);
|
||||
if (!iftdata)
|
||||
return -ENOBUFS;
|
||||
|
||||
err = nl80211_send_iftype_data(msg,
|
||||
&sband->iftype_data[i]);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
nla_nest_end(msg, iftdata);
|
||||
}
|
||||
|
||||
nla_nest_end(msg, nl_iftype_data);
|
||||
}
|
||||
|
||||
/* add bitrates */
|
||||
nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES);
|
||||
if (!nl_rates)
|
||||
@@ -2757,7 +2813,8 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag
|
||||
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, wdev_address(wdev)) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_GENERATION,
|
||||
rdev->devlist_generation ^
|
||||
(cfg80211_rdev_list_generation << 2)))
|
||||
(cfg80211_rdev_list_generation << 2)) ||
|
||||
nla_put_u8(msg, NL80211_ATTR_4ADDR, wdev->use_4addr))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (rdev->ops->get_channel) {
|
||||
@@ -4471,6 +4528,9 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
|
||||
case RATE_INFO_BW_160:
|
||||
rate_flg = NL80211_RATE_INFO_160_MHZ_WIDTH;
|
||||
break;
|
||||
case RATE_INFO_BW_HE_RU:
|
||||
rate_flg = 0;
|
||||
WARN_ON(!(info->flags & RATE_INFO_FLAGS_HE_MCS));
|
||||
}
|
||||
|
||||
if (rate_flg && nla_put_flag(msg, rate_flg))
|
||||
@@ -4490,6 +4550,19 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
|
||||
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_HE_MCS) {
|
||||
if (nla_put_u8(msg, NL80211_RATE_INFO_HE_MCS, info->mcs))
|
||||
return false;
|
||||
if (nla_put_u8(msg, NL80211_RATE_INFO_HE_NSS, info->nss))
|
||||
return false;
|
||||
if (nla_put_u8(msg, NL80211_RATE_INFO_HE_GI, info->he_gi))
|
||||
return false;
|
||||
if (nla_put_u8(msg, NL80211_RATE_INFO_HE_DCM, info->he_dcm))
|
||||
return false;
|
||||
if (info->bw == RATE_INFO_BW_HE_RU &&
|
||||
nla_put_u8(msg, NL80211_RATE_INFO_HE_RU_ALLOC,
|
||||
info->he_ru_alloc))
|
||||
return false;
|
||||
}
|
||||
|
||||
nla_nest_end(msg, rate);
|
||||
@@ -4546,13 +4619,13 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
|
||||
|
||||
#define PUT_SINFO(attr, memb, type) do { \
|
||||
BUILD_BUG_ON(sizeof(type) == sizeof(u64)); \
|
||||
if (sinfo->filled & (1ULL << NL80211_STA_INFO_ ## attr) && \
|
||||
if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \
|
||||
nla_put_ ## type(msg, NL80211_STA_INFO_ ## attr, \
|
||||
sinfo->memb)) \
|
||||
goto nla_put_failure; \
|
||||
} while (0)
|
||||
#define PUT_SINFO_U64(attr, memb) do { \
|
||||
if (sinfo->filled & (1ULL << NL80211_STA_INFO_ ## attr) && \
|
||||
if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \
|
||||
nla_put_u64_64bit(msg, NL80211_STA_INFO_ ## attr, \
|
||||
sinfo->memb, NL80211_STA_INFO_PAD)) \
|
||||
goto nla_put_failure; \
|
||||
@@ -4561,14 +4634,14 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
|
||||
PUT_SINFO(CONNECTED_TIME, connected_time, u32);
|
||||
PUT_SINFO(INACTIVE_TIME, inactive_time, u32);
|
||||
|
||||
if (sinfo->filled & (BIT(NL80211_STA_INFO_RX_BYTES) |
|
||||
BIT(NL80211_STA_INFO_RX_BYTES64)) &&
|
||||
if (sinfo->filled & (BIT_ULL(NL80211_STA_INFO_RX_BYTES) |
|
||||
BIT_ULL(NL80211_STA_INFO_RX_BYTES64)) &&
|
||||
nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES,
|
||||
(u32)sinfo->rx_bytes))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (sinfo->filled & (BIT(NL80211_STA_INFO_TX_BYTES) |
|
||||
BIT(NL80211_STA_INFO_TX_BYTES64)) &&
|
||||
if (sinfo->filled & (BIT_ULL(NL80211_STA_INFO_TX_BYTES) |
|
||||
BIT_ULL(NL80211_STA_INFO_TX_BYTES64)) &&
|
||||
nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES,
|
||||
(u32)sinfo->tx_bytes))
|
||||
goto nla_put_failure;
|
||||
@@ -4588,24 +4661,24 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (sinfo->filled & BIT(NL80211_STA_INFO_CHAIN_SIGNAL)) {
|
||||
if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL)) {
|
||||
if (!nl80211_put_signal(msg, sinfo->chains,
|
||||
sinfo->chain_signal,
|
||||
NL80211_STA_INFO_CHAIN_SIGNAL))
|
||||
goto nla_put_failure;
|
||||
}
|
||||
if (sinfo->filled & BIT(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) {
|
||||
if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) {
|
||||
if (!nl80211_put_signal(msg, sinfo->chains,
|
||||
sinfo->chain_signal_avg,
|
||||
NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
|
||||
goto nla_put_failure;
|
||||
}
|
||||
if (sinfo->filled & BIT(NL80211_STA_INFO_TX_BITRATE)) {
|
||||
if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) {
|
||||
if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
|
||||
NL80211_STA_INFO_TX_BITRATE))
|
||||
goto nla_put_failure;
|
||||
}
|
||||
if (sinfo->filled & BIT(NL80211_STA_INFO_RX_BITRATE)) {
|
||||
if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) {
|
||||
if (!nl80211_put_sta_rate(msg, &sinfo->rxrate,
|
||||
NL80211_STA_INFO_RX_BITRATE))
|
||||
goto nla_put_failure;
|
||||
@@ -4621,7 +4694,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
|
||||
PUT_SINFO(PEER_PM, peer_pm, u32);
|
||||
PUT_SINFO(NONPEER_PM, nonpeer_pm, u32);
|
||||
|
||||
if (sinfo->filled & BIT(NL80211_STA_INFO_BSS_PARAM)) {
|
||||
if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_BSS_PARAM)) {
|
||||
bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM);
|
||||
if (!bss_param)
|
||||
goto nla_put_failure;
|
||||
@@ -4640,7 +4713,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
|
||||
|
||||
nla_nest_end(msg, bss_param);
|
||||
}
|
||||
if ((sinfo->filled & BIT(NL80211_STA_INFO_STA_FLAGS)) &&
|
||||
if ((sinfo->filled & BIT_ULL(NL80211_STA_INFO_STA_FLAGS)) &&
|
||||
nla_put(msg, NL80211_STA_INFO_STA_FLAGS,
|
||||
sizeof(struct nl80211_sta_flag_update),
|
||||
&sinfo->sta_flags))
|
||||
@@ -4886,7 +4959,8 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
|
||||
return -EINVAL;
|
||||
if (params->supported_rates)
|
||||
return -EINVAL;
|
||||
if (params->ext_capab || params->ht_capa || params->vht_capa)
|
||||
if (params->ext_capab || params->ht_capa || params->vht_capa ||
|
||||
params->he_capa)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -5092,6 +5166,15 @@ static int nl80211_set_station_tdls(struct genl_info *info,
|
||||
if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
|
||||
params->vht_capa =
|
||||
nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
|
||||
if (info->attrs[NL80211_ATTR_HE_CAPABILITY]) {
|
||||
params->he_capa =
|
||||
nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
|
||||
params->he_capa_len =
|
||||
nla_len(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
|
||||
|
||||
if (params->he_capa_len < NL80211_HE_MIN_CAPABILITY_LEN)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = nl80211_parse_sta_channel_info(info, params);
|
||||
if (err)
|
||||
@@ -5319,6 +5402,17 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
|
||||
params.vht_capa =
|
||||
nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
|
||||
|
||||
if (info->attrs[NL80211_ATTR_HE_CAPABILITY]) {
|
||||
params.he_capa =
|
||||
nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
|
||||
params.he_capa_len =
|
||||
nla_len(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
|
||||
|
||||
/* max len is validated in nla policy */
|
||||
if (params.he_capa_len < NL80211_HE_MIN_CAPABILITY_LEN)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
|
||||
params.opmode_notif_used = true;
|
||||
params.opmode_notif =
|
||||
@@ -5351,6 +5445,10 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
|
||||
if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME))) {
|
||||
params.ht_capa = NULL;
|
||||
params.vht_capa = NULL;
|
||||
|
||||
/* HE requires WME */
|
||||
if (params.he_capa_len)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* When you run into this, adjust the code below for the new flag */
|
||||
@@ -6861,6 +6959,16 @@ static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev)
|
||||
return regulatory_pre_cac_allowed(wdev->wiphy);
|
||||
}
|
||||
|
||||
static bool nl80211_check_scan_feat(struct wiphy *wiphy, u32 flags, u32 flag,
|
||||
enum nl80211_ext_feature_index feat)
|
||||
{
|
||||
if (!(flags & flag))
|
||||
return true;
|
||||
if (wiphy_ext_feature_isset(wiphy, feat))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static int
|
||||
nl80211_check_scan_flags(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
void *request, struct nlattr **attrs,
|
||||
@@ -6895,15 +7003,33 @@ nl80211_check_scan_flags(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
|
||||
if (((*flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
|
||||
!(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) ||
|
||||
((*flags & NL80211_SCAN_FLAG_LOW_SPAN) &&
|
||||
!wiphy_ext_feature_isset(wiphy,
|
||||
NL80211_EXT_FEATURE_LOW_SPAN_SCAN)) ||
|
||||
((*flags & NL80211_SCAN_FLAG_LOW_POWER) &&
|
||||
!wiphy_ext_feature_isset(wiphy,
|
||||
NL80211_EXT_FEATURE_LOW_POWER_SCAN)) ||
|
||||
((*flags & NL80211_SCAN_FLAG_HIGH_ACCURACY) &&
|
||||
!wiphy_ext_feature_isset(wiphy,
|
||||
NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN)))
|
||||
!nl80211_check_scan_feat(wiphy, *flags,
|
||||
NL80211_SCAN_FLAG_LOW_SPAN,
|
||||
NL80211_EXT_FEATURE_LOW_SPAN_SCAN) ||
|
||||
!nl80211_check_scan_feat(wiphy, *flags,
|
||||
NL80211_SCAN_FLAG_LOW_POWER,
|
||||
NL80211_EXT_FEATURE_LOW_POWER_SCAN) ||
|
||||
!nl80211_check_scan_feat(wiphy, *flags,
|
||||
NL80211_SCAN_FLAG_HIGH_ACCURACY,
|
||||
NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN) ||
|
||||
!nl80211_check_scan_feat(wiphy, *flags,
|
||||
NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME,
|
||||
NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME) ||
|
||||
!nl80211_check_scan_feat(wiphy, *flags,
|
||||
NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP,
|
||||
NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP) ||
|
||||
!nl80211_check_scan_feat(wiphy, *flags,
|
||||
NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION,
|
||||
NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION) ||
|
||||
!nl80211_check_scan_feat(wiphy, *flags,
|
||||
NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE,
|
||||
NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE) ||
|
||||
!nl80211_check_scan_feat(wiphy, *flags,
|
||||
NL80211_SCAN_FLAG_RANDOM_SN,
|
||||
NL80211_EXT_FEATURE_SCAN_RANDOM_SN) ||
|
||||
!nl80211_check_scan_feat(wiphy, *flags,
|
||||
NL80211_SCAN_FLAG_MIN_PREQ_CONTENT,
|
||||
NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (*flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
|
||||
@@ -6918,26 +7044,6 @@ nl80211_check_scan_flags(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((*flags & NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME) &&
|
||||
!wiphy_ext_feature_isset(wiphy,
|
||||
NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if ((*flags & NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP) &&
|
||||
!wiphy_ext_feature_isset(wiphy,
|
||||
NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if ((*flags & NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION) &&
|
||||
!wiphy_ext_feature_isset(wiphy,
|
||||
NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if ((*flags & NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE) &&
|
||||
!wiphy_ext_feature_isset(wiphy,
|
||||
NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -10160,7 +10266,7 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (sinfo.filled & BIT(NL80211_STA_INFO_BEACON_SIGNAL_AVG))
|
||||
if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG))
|
||||
wdev->cqm_config->last_rssi_event_value =
|
||||
(s8) sinfo.rx_beacon_signal_avg;
|
||||
}
|
||||
|
Reference in New Issue
Block a user