|
@@ -168,8 +168,8 @@ __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
|
|
|
netdev = __dev_get_by_index(netns, ifindex);
|
|
|
if (netdev) {
|
|
|
if (netdev->ieee80211_ptr)
|
|
|
- tmp = wiphy_to_dev(
|
|
|
- netdev->ieee80211_ptr->wiphy);
|
|
|
+ tmp = wiphy_to_rdev(
|
|
|
+ netdev->ieee80211_ptr->wiphy);
|
|
|
else
|
|
|
tmp = NULL;
|
|
|
|
|
@@ -385,6 +385,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
|
|
|
[NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN },
|
|
|
[NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
|
|
|
[NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
|
|
|
+ [NL80211_ATTR_IFACE_SOCKET_OWNER] = { .type = NLA_FLAG },
|
|
|
};
|
|
|
|
|
|
/* policy for the key attributes */
|
|
@@ -484,7 +485,7 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
|
|
|
err = PTR_ERR(*wdev);
|
|
|
goto out_unlock;
|
|
|
}
|
|
|
- *rdev = wiphy_to_dev((*wdev)->wiphy);
|
|
|
+ *rdev = wiphy_to_rdev((*wdev)->wiphy);
|
|
|
/* 0 is the first index - add 1 to parse only once */
|
|
|
cb->args[0] = (*rdev)->wiphy_idx + 1;
|
|
|
cb->args[1] = (*wdev)->identifier;
|
|
@@ -497,7 +498,7 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
|
|
|
err = -ENODEV;
|
|
|
goto out_unlock;
|
|
|
}
|
|
|
- *rdev = wiphy_to_dev(wiphy);
|
|
|
+ *rdev = wiphy_to_rdev(wiphy);
|
|
|
*wdev = NULL;
|
|
|
|
|
|
list_for_each_entry(tmp, &(*rdev)->wdev_list, list) {
|
|
@@ -566,6 +567,13 @@ static int nl80211_msg_put_channel(struct sk_buff *msg,
|
|
|
struct ieee80211_channel *chan,
|
|
|
bool large)
|
|
|
{
|
|
|
+ /* Some channels must be completely excluded from the
|
|
|
+ * list to protect old user-space tools from breaking
|
|
|
+ */
|
|
|
+ if (!large && chan->flags &
|
|
|
+ (IEEE80211_CHAN_NO_10MHZ | IEEE80211_CHAN_NO_20MHZ))
|
|
|
+ return 0;
|
|
|
+
|
|
|
if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_FREQ,
|
|
|
chan->center_freq))
|
|
|
goto nla_put_failure;
|
|
@@ -613,6 +621,18 @@ static int nl80211_msg_put_channel(struct sk_buff *msg,
|
|
|
if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) &&
|
|
|
nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ))
|
|
|
goto nla_put_failure;
|
|
|
+ if ((chan->flags & IEEE80211_CHAN_INDOOR_ONLY) &&
|
|
|
+ nla_put_flag(msg, NL80211_FREQUENCY_ATTR_INDOOR_ONLY))
|
|
|
+ goto nla_put_failure;
|
|
|
+ if ((chan->flags & IEEE80211_CHAN_GO_CONCURRENT) &&
|
|
|
+ nla_put_flag(msg, NL80211_FREQUENCY_ATTR_GO_CONCURRENT))
|
|
|
+ goto nla_put_failure;
|
|
|
+ if ((chan->flags & IEEE80211_CHAN_NO_20MHZ) &&
|
|
|
+ nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_20MHZ))
|
|
|
+ goto nla_put_failure;
|
|
|
+ if ((chan->flags & IEEE80211_CHAN_NO_10MHZ) &&
|
|
|
+ nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_10MHZ))
|
|
|
+ goto nla_put_failure;
|
|
|
}
|
|
|
|
|
|
if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
|
|
@@ -1006,42 +1026,42 @@ static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev,
|
|
|
}
|
|
|
|
|
|
static int nl80211_send_wowlan(struct sk_buff *msg,
|
|
|
- struct cfg80211_registered_device *dev,
|
|
|
+ struct cfg80211_registered_device *rdev,
|
|
|
bool large)
|
|
|
{
|
|
|
struct nlattr *nl_wowlan;
|
|
|
|
|
|
- if (!dev->wiphy.wowlan)
|
|
|
+ if (!rdev->wiphy.wowlan)
|
|
|
return 0;
|
|
|
|
|
|
nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED);
|
|
|
if (!nl_wowlan)
|
|
|
return -ENOBUFS;
|
|
|
|
|
|
- if (((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_ANY) &&
|
|
|
+ if (((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_ANY) &&
|
|
|
nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
|
|
|
- ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_DISCONNECT) &&
|
|
|
+ ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_DISCONNECT) &&
|
|
|
nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
|
|
|
- ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT) &&
|
|
|
+ ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT) &&
|
|
|
nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
|
|
|
- ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) &&
|
|
|
+ ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) &&
|
|
|
nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) ||
|
|
|
- ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
|
|
|
+ ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
|
|
|
nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
|
|
|
- ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) &&
|
|
|
+ ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) &&
|
|
|
nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
|
|
|
- ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) &&
|
|
|
+ ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) &&
|
|
|
nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
|
|
|
- ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE) &&
|
|
|
+ ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE) &&
|
|
|
nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
|
|
|
return -ENOBUFS;
|
|
|
|
|
|
- if (dev->wiphy.wowlan->n_patterns) {
|
|
|
+ if (rdev->wiphy.wowlan->n_patterns) {
|
|
|
struct nl80211_pattern_support pat = {
|
|
|
- .max_patterns = dev->wiphy.wowlan->n_patterns,
|
|
|
- .min_pattern_len = dev->wiphy.wowlan->pattern_min_len,
|
|
|
- .max_pattern_len = dev->wiphy.wowlan->pattern_max_len,
|
|
|
- .max_pkt_offset = dev->wiphy.wowlan->max_pkt_offset,
|
|
|
+ .max_patterns = rdev->wiphy.wowlan->n_patterns,
|
|
|
+ .min_pattern_len = rdev->wiphy.wowlan->pattern_min_len,
|
|
|
+ .max_pattern_len = rdev->wiphy.wowlan->pattern_max_len,
|
|
|
+ .max_pkt_offset = rdev->wiphy.wowlan->max_pkt_offset,
|
|
|
};
|
|
|
|
|
|
if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
|
|
@@ -1049,7 +1069,7 @@ static int nl80211_send_wowlan(struct sk_buff *msg,
|
|
|
return -ENOBUFS;
|
|
|
}
|
|
|
|
|
|
- if (large && nl80211_send_wowlan_tcp_caps(dev, msg))
|
|
|
+ if (large && nl80211_send_wowlan_tcp_caps(rdev, msg))
|
|
|
return -ENOBUFS;
|
|
|
|
|
|
nla_nest_end(msg, nl_wowlan);
|
|
@@ -1059,19 +1079,19 @@ static int nl80211_send_wowlan(struct sk_buff *msg,
|
|
|
#endif
|
|
|
|
|
|
static int nl80211_send_coalesce(struct sk_buff *msg,
|
|
|
- struct cfg80211_registered_device *dev)
|
|
|
+ struct cfg80211_registered_device *rdev)
|
|
|
{
|
|
|
struct nl80211_coalesce_rule_support rule;
|
|
|
|
|
|
- if (!dev->wiphy.coalesce)
|
|
|
+ if (!rdev->wiphy.coalesce)
|
|
|
return 0;
|
|
|
|
|
|
- rule.max_rules = dev->wiphy.coalesce->n_rules;
|
|
|
- rule.max_delay = dev->wiphy.coalesce->max_delay;
|
|
|
- rule.pat.max_patterns = dev->wiphy.coalesce->n_patterns;
|
|
|
- rule.pat.min_pattern_len = dev->wiphy.coalesce->pattern_min_len;
|
|
|
- rule.pat.max_pattern_len = dev->wiphy.coalesce->pattern_max_len;
|
|
|
- rule.pat.max_pkt_offset = dev->wiphy.coalesce->max_pkt_offset;
|
|
|
+ rule.max_rules = rdev->wiphy.coalesce->n_rules;
|
|
|
+ rule.max_delay = rdev->wiphy.coalesce->max_delay;
|
|
|
+ rule.pat.max_patterns = rdev->wiphy.coalesce->n_patterns;
|
|
|
+ rule.pat.min_pattern_len = rdev->wiphy.coalesce->pattern_min_len;
|
|
|
+ rule.pat.max_pattern_len = rdev->wiphy.coalesce->pattern_max_len;
|
|
|
+ rule.pat.max_pkt_offset = rdev->wiphy.coalesce->max_pkt_offset;
|
|
|
|
|
|
if (nla_put(msg, NL80211_ATTR_COALESCE_RULE, sizeof(rule), &rule))
|
|
|
return -ENOBUFS;
|
|
@@ -1202,7 +1222,7 @@ struct nl80211_dump_wiphy_state {
|
|
|
bool split;
|
|
|
};
|
|
|
|
|
|
-static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
|
|
|
+static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
|
|
|
struct sk_buff *msg, u32 portid, u32 seq,
|
|
|
int flags, struct nl80211_dump_wiphy_state *state)
|
|
|
{
|
|
@@ -1214,7 +1234,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
|
|
|
struct ieee80211_channel *chan;
|
|
|
int i;
|
|
|
const struct ieee80211_txrx_stypes *mgmt_stypes =
|
|
|
- dev->wiphy.mgmt_stypes;
|
|
|
+ rdev->wiphy.mgmt_stypes;
|
|
|
u32 features;
|
|
|
|
|
|
hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_WIPHY);
|
|
@@ -1224,9 +1244,9 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
|
|
|
if (WARN_ON(!state))
|
|
|
return -EINVAL;
|
|
|
|
|
|
- if (nla_put_u32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx) ||
|
|
|
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
|
|
|
nla_put_string(msg, NL80211_ATTR_WIPHY_NAME,
|
|
|
- wiphy_name(&dev->wiphy)) ||
|
|
|
+ wiphy_name(&rdev->wiphy)) ||
|
|
|
nla_put_u32(msg, NL80211_ATTR_GENERATION,
|
|
|
cfg80211_rdev_list_generation))
|
|
|
goto nla_put_failure;
|
|
@@ -1234,43 +1254,43 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
|
|
|
switch (state->split_start) {
|
|
|
case 0:
|
|
|
if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
|
|
|
- dev->wiphy.retry_short) ||
|
|
|
+ rdev->wiphy.retry_short) ||
|
|
|
nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
|
|
|
- dev->wiphy.retry_long) ||
|
|
|
+ rdev->wiphy.retry_long) ||
|
|
|
nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
|
|
|
- dev->wiphy.frag_threshold) ||
|
|
|
+ rdev->wiphy.frag_threshold) ||
|
|
|
nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
|
|
|
- dev->wiphy.rts_threshold) ||
|
|
|
+ rdev->wiphy.rts_threshold) ||
|
|
|
nla_put_u8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS,
|
|
|
- dev->wiphy.coverage_class) ||
|
|
|
+ rdev->wiphy.coverage_class) ||
|
|
|
nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
|
|
|
- dev->wiphy.max_scan_ssids) ||
|
|
|
+ rdev->wiphy.max_scan_ssids) ||
|
|
|
nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
|
|
|
- dev->wiphy.max_sched_scan_ssids) ||
|
|
|
+ rdev->wiphy.max_sched_scan_ssids) ||
|
|
|
nla_put_u16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
|
|
|
- dev->wiphy.max_scan_ie_len) ||
|
|
|
+ rdev->wiphy.max_scan_ie_len) ||
|
|
|
nla_put_u16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
|
|
|
- dev->wiphy.max_sched_scan_ie_len) ||
|
|
|
+ rdev->wiphy.max_sched_scan_ie_len) ||
|
|
|
nla_put_u8(msg, NL80211_ATTR_MAX_MATCH_SETS,
|
|
|
- dev->wiphy.max_match_sets))
|
|
|
+ rdev->wiphy.max_match_sets))
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
- if ((dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) &&
|
|
|
+ if ((rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) &&
|
|
|
nla_put_flag(msg, NL80211_ATTR_SUPPORT_IBSS_RSN))
|
|
|
goto nla_put_failure;
|
|
|
- if ((dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
|
|
|
+ if ((rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
|
|
|
nla_put_flag(msg, NL80211_ATTR_SUPPORT_MESH_AUTH))
|
|
|
goto nla_put_failure;
|
|
|
- if ((dev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
|
|
|
+ if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
|
|
|
nla_put_flag(msg, NL80211_ATTR_SUPPORT_AP_UAPSD))
|
|
|
goto nla_put_failure;
|
|
|
- if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) &&
|
|
|
+ if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) &&
|
|
|
nla_put_flag(msg, NL80211_ATTR_ROAM_SUPPORT))
|
|
|
goto nla_put_failure;
|
|
|
- if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
|
|
|
+ if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
|
|
|
nla_put_flag(msg, NL80211_ATTR_TDLS_SUPPORT))
|
|
|
goto nla_put_failure;
|
|
|
- if ((dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) &&
|
|
|
+ if ((rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) &&
|
|
|
nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP))
|
|
|
goto nla_put_failure;
|
|
|
state->split_start++;
|
|
@@ -1278,35 +1298,35 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
|
|
|
break;
|
|
|
case 1:
|
|
|
if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES,
|
|
|
- sizeof(u32) * dev->wiphy.n_cipher_suites,
|
|
|
- dev->wiphy.cipher_suites))
|
|
|
+ sizeof(u32) * rdev->wiphy.n_cipher_suites,
|
|
|
+ rdev->wiphy.cipher_suites))
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_PMKIDS,
|
|
|
- dev->wiphy.max_num_pmkids))
|
|
|
+ rdev->wiphy.max_num_pmkids))
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
- if ((dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
|
|
|
+ if ((rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
|
|
|
nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE))
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
|
|
|
- dev->wiphy.available_antennas_tx) ||
|
|
|
+ rdev->wiphy.available_antennas_tx) ||
|
|
|
nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
|
|
|
- dev->wiphy.available_antennas_rx))
|
|
|
+ rdev->wiphy.available_antennas_rx))
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
- if ((dev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) &&
|
|
|
+ if ((rdev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) &&
|
|
|
nla_put_u32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD,
|
|
|
- dev->wiphy.probe_resp_offload))
|
|
|
+ rdev->wiphy.probe_resp_offload))
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
- if ((dev->wiphy.available_antennas_tx ||
|
|
|
- dev->wiphy.available_antennas_rx) &&
|
|
|
- dev->ops->get_antenna) {
|
|
|
+ if ((rdev->wiphy.available_antennas_tx ||
|
|
|
+ rdev->wiphy.available_antennas_rx) &&
|
|
|
+ rdev->ops->get_antenna) {
|
|
|
u32 tx_ant = 0, rx_ant = 0;
|
|
|
int res;
|
|
|
- res = rdev_get_antenna(dev, &tx_ant, &rx_ant);
|
|
|
+ res = rdev_get_antenna(rdev, &tx_ant, &rx_ant);
|
|
|
if (!res) {
|
|
|
if (nla_put_u32(msg,
|
|
|
NL80211_ATTR_WIPHY_ANTENNA_TX,
|
|
@@ -1323,7 +1343,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
|
|
|
break;
|
|
|
case 2:
|
|
|
if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES,
|
|
|
- dev->wiphy.interface_modes))
|
|
|
+ rdev->wiphy.interface_modes))
|
|
|
goto nla_put_failure;
|
|
|
state->split_start++;
|
|
|
if (state->split)
|
|
@@ -1337,7 +1357,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
|
|
|
band < IEEE80211_NUM_BANDS; band++) {
|
|
|
struct ieee80211_supported_band *sband;
|
|
|
|
|
|
- sband = dev->wiphy.bands[band];
|
|
|
+ sband = rdev->wiphy.bands[band];
|
|
|
|
|
|
if (!sband)
|
|
|
continue;
|
|
@@ -1414,7 +1434,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
|
|
|
i = 0;
|
|
|
#define CMD(op, n) \
|
|
|
do { \
|
|
|
- if (dev->ops->op) { \
|
|
|
+ if (rdev->ops->op) { \
|
|
|
i++; \
|
|
|
if (nla_put_u32(msg, i, NL80211_CMD_ ## n)) \
|
|
|
goto nla_put_failure; \
|
|
@@ -1438,32 +1458,32 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
|
|
|
CMD(set_pmksa, SET_PMKSA);
|
|
|
CMD(del_pmksa, DEL_PMKSA);
|
|
|
CMD(flush_pmksa, FLUSH_PMKSA);
|
|
|
- if (dev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)
|
|
|
+ if (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)
|
|
|
CMD(remain_on_channel, REMAIN_ON_CHANNEL);
|
|
|
CMD(set_bitrate_mask, SET_TX_BITRATE_MASK);
|
|
|
CMD(mgmt_tx, FRAME);
|
|
|
CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL);
|
|
|
- if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
|
|
|
+ if (rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
|
|
|
i++;
|
|
|
if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS))
|
|
|
goto nla_put_failure;
|
|
|
}
|
|
|
- if (dev->ops->set_monitor_channel || dev->ops->start_ap ||
|
|
|
- dev->ops->join_mesh) {
|
|
|
+ if (rdev->ops->set_monitor_channel || rdev->ops->start_ap ||
|
|
|
+ rdev->ops->join_mesh) {
|
|
|
i++;
|
|
|
if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL))
|
|
|
goto nla_put_failure;
|
|
|
}
|
|
|
CMD(set_wds_peer, SET_WDS_PEER);
|
|
|
- if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) {
|
|
|
+ if (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) {
|
|
|
CMD(tdls_mgmt, TDLS_MGMT);
|
|
|
CMD(tdls_oper, TDLS_OPER);
|
|
|
}
|
|
|
- if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
|
|
|
+ if (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
|
|
|
CMD(sched_scan_start, START_SCHED_SCAN);
|
|
|
CMD(probe_client, PROBE_CLIENT);
|
|
|
CMD(set_noack_map, SET_NOACK_MAP);
|
|
|
- if (dev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) {
|
|
|
+ if (rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) {
|
|
|
i++;
|
|
|
if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS))
|
|
|
goto nla_put_failure;
|
|
@@ -1473,7 +1493,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
|
|
|
if (state->split) {
|
|
|
CMD(crit_proto_start, CRIT_PROTOCOL_START);
|
|
|
CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
|
|
|
- if (dev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)
|
|
|
+ if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)
|
|
|
CMD(channel_switch, CHANNEL_SWITCH);
|
|
|
}
|
|
|
CMD(set_qos_map, SET_QOS_MAP);
|
|
@@ -1484,13 +1504,13 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
|
|
|
|
|
|
#undef CMD
|
|
|
|
|
|
- if (dev->ops->connect || dev->ops->auth) {
|
|
|
+ if (rdev->ops->connect || rdev->ops->auth) {
|
|
|
i++;
|
|
|
if (nla_put_u32(msg, i, NL80211_CMD_CONNECT))
|
|
|
goto nla_put_failure;
|
|
|
}
|
|
|
|
|
|
- if (dev->ops->disconnect || dev->ops->deauth) {
|
|
|
+ if (rdev->ops->disconnect || rdev->ops->deauth) {
|
|
|
i++;
|
|
|
if (nla_put_u32(msg, i, NL80211_CMD_DISCONNECT))
|
|
|
goto nla_put_failure;
|
|
@@ -1501,14 +1521,14 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
|
|
|
if (state->split)
|
|
|
break;
|
|
|
case 5:
|
|
|
- if (dev->ops->remain_on_channel &&
|
|
|
- (dev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) &&
|
|
|
+ if (rdev->ops->remain_on_channel &&
|
|
|
+ (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) &&
|
|
|
nla_put_u32(msg,
|
|
|
NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
|
|
|
- dev->wiphy.max_remain_on_channel_duration))
|
|
|
+ rdev->wiphy.max_remain_on_channel_duration))
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
- if ((dev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX) &&
|
|
|
+ if ((rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX) &&
|
|
|
nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK))
|
|
|
goto nla_put_failure;
|
|
|
|
|
@@ -1519,7 +1539,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
|
|
|
break;
|
|
|
case 6:
|
|
|
#ifdef CONFIG_PM
|
|
|
- if (nl80211_send_wowlan(msg, dev, state->split))
|
|
|
+ if (nl80211_send_wowlan(msg, rdev, state->split))
|
|
|
goto nla_put_failure;
|
|
|
state->split_start++;
|
|
|
if (state->split)
|
|
@@ -1529,10 +1549,10 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
|
|
|
#endif
|
|
|
case 7:
|
|
|
if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES,
|
|
|
- dev->wiphy.software_iftypes))
|
|
|
+ rdev->wiphy.software_iftypes))
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
- if (nl80211_put_iface_combinations(&dev->wiphy, msg,
|
|
|
+ if (nl80211_put_iface_combinations(&rdev->wiphy, msg,
|
|
|
state->split))
|
|
|
goto nla_put_failure;
|
|
|
|
|
@@ -1540,12 +1560,12 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
|
|
|
if (state->split)
|
|
|
break;
|
|
|
case 8:
|
|
|
- if ((dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) &&
|
|
|
+ if ((rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) &&
|
|
|
nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME,
|
|
|
- dev->wiphy.ap_sme_capa))
|
|
|
+ rdev->wiphy.ap_sme_capa))
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
- features = dev->wiphy.features;
|
|
|
+ features = rdev->wiphy.features;
|
|
|
/*
|
|
|
* We can only add the per-channel limit information if the
|
|
|
* dump is split, otherwise it makes it too big. Therefore
|
|
@@ -1556,16 +1576,16 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
|
|
|
if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, features))
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
- if (dev->wiphy.ht_capa_mod_mask &&
|
|
|
+ if (rdev->wiphy.ht_capa_mod_mask &&
|
|
|
nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK,
|
|
|
- sizeof(*dev->wiphy.ht_capa_mod_mask),
|
|
|
- dev->wiphy.ht_capa_mod_mask))
|
|
|
+ sizeof(*rdev->wiphy.ht_capa_mod_mask),
|
|
|
+ rdev->wiphy.ht_capa_mod_mask))
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
- if (dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME &&
|
|
|
- dev->wiphy.max_acl_mac_addrs &&
|
|
|
+ if (rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME &&
|
|
|
+ rdev->wiphy.max_acl_mac_addrs &&
|
|
|
nla_put_u32(msg, NL80211_ATTR_MAC_ACL_MAX,
|
|
|
- dev->wiphy.max_acl_mac_addrs))
|
|
|
+ rdev->wiphy.max_acl_mac_addrs))
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
/*
|
|
@@ -1581,41 +1601,41 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
|
|
|
state->split_start++;
|
|
|
break;
|
|
|
case 9:
|
|
|
- if (dev->wiphy.extended_capabilities &&
|
|
|
+ if (rdev->wiphy.extended_capabilities &&
|
|
|
(nla_put(msg, NL80211_ATTR_EXT_CAPA,
|
|
|
- dev->wiphy.extended_capabilities_len,
|
|
|
- dev->wiphy.extended_capabilities) ||
|
|
|
+ rdev->wiphy.extended_capabilities_len,
|
|
|
+ rdev->wiphy.extended_capabilities) ||
|
|
|
nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
|
|
|
- dev->wiphy.extended_capabilities_len,
|
|
|
- dev->wiphy.extended_capabilities_mask)))
|
|
|
+ rdev->wiphy.extended_capabilities_len,
|
|
|
+ rdev->wiphy.extended_capabilities_mask)))
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
- if (dev->wiphy.vht_capa_mod_mask &&
|
|
|
+ if (rdev->wiphy.vht_capa_mod_mask &&
|
|
|
nla_put(msg, NL80211_ATTR_VHT_CAPABILITY_MASK,
|
|
|
- sizeof(*dev->wiphy.vht_capa_mod_mask),
|
|
|
- dev->wiphy.vht_capa_mod_mask))
|
|
|
+ sizeof(*rdev->wiphy.vht_capa_mod_mask),
|
|
|
+ rdev->wiphy.vht_capa_mod_mask))
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
state->split_start++;
|
|
|
break;
|
|
|
case 10:
|
|
|
- if (nl80211_send_coalesce(msg, dev))
|
|
|
+ if (nl80211_send_coalesce(msg, rdev))
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
- if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) &&
|
|
|
+ if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) &&
|
|
|
(nla_put_flag(msg, NL80211_ATTR_SUPPORT_5_MHZ) ||
|
|
|
nla_put_flag(msg, NL80211_ATTR_SUPPORT_10_MHZ)))
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
- if (dev->wiphy.max_ap_assoc_sta &&
|
|
|
+ if (rdev->wiphy.max_ap_assoc_sta &&
|
|
|
nla_put_u32(msg, NL80211_ATTR_MAX_AP_ASSOC_STA,
|
|
|
- dev->wiphy.max_ap_assoc_sta))
|
|
|
+ rdev->wiphy.max_ap_assoc_sta))
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
state->split_start++;
|
|
|
break;
|
|
|
case 11:
|
|
|
- if (dev->wiphy.n_vendor_commands) {
|
|
|
+ if (rdev->wiphy.n_vendor_commands) {
|
|
|
const struct nl80211_vendor_cmd_info *info;
|
|
|
struct nlattr *nested;
|
|
|
|
|
@@ -1623,15 +1643,15 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
|
|
|
if (!nested)
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
- for (i = 0; i < dev->wiphy.n_vendor_commands; i++) {
|
|
|
- info = &dev->wiphy.vendor_commands[i].info;
|
|
|
+ for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
|
|
|
+ info = &rdev->wiphy.vendor_commands[i].info;
|
|
|
if (nla_put(msg, i + 1, sizeof(*info), info))
|
|
|
goto nla_put_failure;
|
|
|
}
|
|
|
nla_nest_end(msg, nested);
|
|
|
}
|
|
|
|
|
|
- if (dev->wiphy.n_vendor_events) {
|
|
|
+ if (rdev->wiphy.n_vendor_events) {
|
|
|
const struct nl80211_vendor_cmd_info *info;
|
|
|
struct nlattr *nested;
|
|
|
|
|
@@ -1640,8 +1660,8 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
|
|
|
if (!nested)
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
- for (i = 0; i < dev->wiphy.n_vendor_events; i++) {
|
|
|
- info = &dev->wiphy.vendor_events[i];
|
|
|
+ for (i = 0; i < rdev->wiphy.n_vendor_events; i++) {
|
|
|
+ info = &rdev->wiphy.vendor_events[i];
|
|
|
if (nla_put(msg, i + 1, sizeof(*info), info))
|
|
|
goto nla_put_failure;
|
|
|
}
|
|
@@ -1684,7 +1704,7 @@ static int nl80211_dump_wiphy_parse(struct sk_buff *skb,
|
|
|
if (!netdev)
|
|
|
return -ENODEV;
|
|
|
if (netdev->ieee80211_ptr) {
|
|
|
- rdev = wiphy_to_dev(
|
|
|
+ rdev = wiphy_to_rdev(
|
|
|
netdev->ieee80211_ptr->wiphy);
|
|
|
state->filter_wiphy = rdev->wiphy_idx;
|
|
|
}
|
|
@@ -1697,7 +1717,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
|
|
|
{
|
|
|
int idx = 0, ret;
|
|
|
struct nl80211_dump_wiphy_state *state = (void *)cb->args[0];
|
|
|
- struct cfg80211_registered_device *dev;
|
|
|
+ struct cfg80211_registered_device *rdev;
|
|
|
|
|
|
rtnl_lock();
|
|
|
if (!state) {
|
|
@@ -1716,17 +1736,17 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
|
|
|
cb->args[0] = (long)state;
|
|
|
}
|
|
|
|
|
|
- list_for_each_entry(dev, &cfg80211_rdev_list, list) {
|
|
|
- if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk)))
|
|
|
+ list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
|
|
|
+ if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
|
|
|
continue;
|
|
|
if (++idx <= state->start)
|
|
|
continue;
|
|
|
if (state->filter_wiphy != -1 &&
|
|
|
- state->filter_wiphy != dev->wiphy_idx)
|
|
|
+ state->filter_wiphy != rdev->wiphy_idx)
|
|
|
continue;
|
|
|
/* attempt to fit multiple wiphy data chunks into the skb */
|
|
|
do {
|
|
|
- ret = nl80211_send_wiphy(dev, skb,
|
|
|
+ ret = nl80211_send_wiphy(rdev, skb,
|
|
|
NETLINK_CB(cb->skb).portid,
|
|
|
cb->nlh->nlmsg_seq,
|
|
|
NLM_F_MULTI, state);
|
|
@@ -1774,14 +1794,14 @@ static int nl80211_dump_wiphy_done(struct netlink_callback *cb)
|
|
|
static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
|
|
|
{
|
|
|
struct sk_buff *msg;
|
|
|
- struct cfg80211_registered_device *dev = info->user_ptr[0];
|
|
|
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
|
|
struct nl80211_dump_wiphy_state state = {};
|
|
|
|
|
|
msg = nlmsg_new(4096, GFP_KERNEL);
|
|
|
if (!msg)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
- if (nl80211_send_wiphy(dev, msg, info->snd_portid, info->snd_seq, 0,
|
|
|
+ if (nl80211_send_wiphy(rdev, msg, info->snd_portid, info->snd_seq, 0,
|
|
|
&state) < 0) {
|
|
|
nlmsg_free(msg);
|
|
|
return -ENOBUFS;
|
|
@@ -1908,18 +1928,20 @@ static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
|
|
|
}
|
|
|
|
|
|
static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
|
|
|
- struct wireless_dev *wdev,
|
|
|
+ struct net_device *dev,
|
|
|
struct genl_info *info)
|
|
|
{
|
|
|
struct cfg80211_chan_def chandef;
|
|
|
int result;
|
|
|
enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR;
|
|
|
+ struct wireless_dev *wdev = NULL;
|
|
|
|
|
|
- if (wdev)
|
|
|
- iftype = wdev->iftype;
|
|
|
-
|
|
|
+ if (dev)
|
|
|
+ wdev = dev->ieee80211_ptr;
|
|
|
if (!nl80211_can_set_dev_channel(wdev))
|
|
|
return -EOPNOTSUPP;
|
|
|
+ if (wdev)
|
|
|
+ iftype = wdev->iftype;
|
|
|
|
|
|
result = nl80211_parse_chandef(rdev, info, &chandef);
|
|
|
if (result)
|
|
@@ -1928,14 +1950,27 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
|
|
|
switch (iftype) {
|
|
|
case NL80211_IFTYPE_AP:
|
|
|
case NL80211_IFTYPE_P2P_GO:
|
|
|
- if (wdev->beacon_interval) {
|
|
|
- result = -EBUSY;
|
|
|
- break;
|
|
|
- }
|
|
|
- if (!cfg80211_reg_can_beacon(&rdev->wiphy, &chandef)) {
|
|
|
+ if (!cfg80211_reg_can_beacon(&rdev->wiphy, &chandef, iftype)) {
|
|
|
result = -EINVAL;
|
|
|
break;
|
|
|
}
|
|
|
+ if (wdev->beacon_interval) {
|
|
|
+ if (!dev || !rdev->ops->set_ap_chanwidth ||
|
|
|
+ !(rdev->wiphy.features &
|
|
|
+ NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE)) {
|
|
|
+ result = -EBUSY;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Only allow dynamic channel width changes */
|
|
|
+ if (chandef.chan != wdev->preset_chandef.chan) {
|
|
|
+ result = -EBUSY;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ result = rdev_set_ap_chanwidth(rdev, dev, &chandef);
|
|
|
+ if (result)
|
|
|
+ break;
|
|
|
+ }
|
|
|
wdev->preset_chandef = chandef;
|
|
|
result = 0;
|
|
|
break;
|
|
@@ -1957,7 +1992,7 @@ static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info)
|
|
|
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
|
|
struct net_device *netdev = info->user_ptr[1];
|
|
|
|
|
|
- return __nl80211_set_channel(rdev, netdev->ieee80211_ptr, info);
|
|
|
+ return __nl80211_set_channel(rdev, netdev, info);
|
|
|
}
|
|
|
|
|
|
static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info)
|
|
@@ -2013,7 +2048,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
|
|
|
|
|
|
netdev = __dev_get_by_index(genl_info_net(info), ifindex);
|
|
|
if (netdev && netdev->ieee80211_ptr)
|
|
|
- rdev = wiphy_to_dev(netdev->ieee80211_ptr->wiphy);
|
|
|
+ rdev = wiphy_to_rdev(netdev->ieee80211_ptr->wiphy);
|
|
|
else
|
|
|
netdev = NULL;
|
|
|
}
|
|
@@ -2079,9 +2114,10 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
|
|
|
}
|
|
|
|
|
|
if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
|
|
|
- result = __nl80211_set_channel(rdev,
|
|
|
- nl80211_can_set_dev_channel(wdev) ? wdev : NULL,
|
|
|
- info);
|
|
|
+ result = __nl80211_set_channel(
|
|
|
+ rdev,
|
|
|
+ nl80211_can_set_dev_channel(wdev) ? netdev : NULL,
|
|
|
+ info);
|
|
|
if (result)
|
|
|
return result;
|
|
|
}
|
|
@@ -2229,7 +2265,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
|
|
|
static inline u64 wdev_id(struct wireless_dev *wdev)
|
|
|
{
|
|
|
return (u64)wdev->identifier |
|
|
|
- ((u64)wiphy_to_dev(wdev->wiphy)->wiphy_idx << 32);
|
|
|
+ ((u64)wiphy_to_rdev(wdev->wiphy)->wiphy_idx << 32);
|
|
|
}
|
|
|
|
|
|
static int nl80211_send_chandef(struct sk_buff *msg,
|
|
@@ -2355,7 +2391,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
|
|
|
static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
|
|
|
{
|
|
|
struct sk_buff *msg;
|
|
|
- struct cfg80211_registered_device *dev = info->user_ptr[0];
|
|
|
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
|
|
struct wireless_dev *wdev = info->user_ptr[1];
|
|
|
|
|
|
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
|
@@ -2363,7 +2399,7 @@ static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
|
|
|
- dev, wdev) < 0) {
|
|
|
+ rdev, wdev) < 0) {
|
|
|
nlmsg_free(msg);
|
|
|
return -ENOBUFS;
|
|
|
}
|
|
@@ -2514,6 +2550,9 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
|
|
|
enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
|
|
|
u32 flags;
|
|
|
|
|
|
+ /* to avoid failing a new interface creation due to pending removal */
|
|
|
+ cfg80211_destroy_ifaces(rdev);
|
|
|
+
|
|
|
memset(¶ms, 0, sizeof(params));
|
|
|
|
|
|
if (!info->attrs[NL80211_ATTR_IFNAME])
|
|
@@ -2563,6 +2602,9 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
|
|
|
return PTR_ERR(wdev);
|
|
|
}
|
|
|
|
|
|
+ if (info->attrs[NL80211_ATTR_IFACE_SOCKET_OWNER])
|
|
|
+ wdev->owner_nlportid = info->snd_portid;
|
|
|
+
|
|
|
switch (type) {
|
|
|
case NL80211_IFTYPE_MESH_POINT:
|
|
|
if (!info->attrs[NL80211_ATTR_MESH_ID])
|
|
@@ -3142,7 +3184,6 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
|
|
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
|
struct cfg80211_ap_settings params;
|
|
|
int err;
|
|
|
- u8 radar_detect_width = 0;
|
|
|
|
|
|
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
|
|
|
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
|
|
@@ -3258,24 +3299,10 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
|
|
|
} else if (!nl80211_get_ap_channel(rdev, ¶ms))
|
|
|
return -EINVAL;
|
|
|
|
|
|
- if (!cfg80211_reg_can_beacon(&rdev->wiphy, ¶ms.chandef))
|
|
|
+ if (!cfg80211_reg_can_beacon(&rdev->wiphy, ¶ms.chandef,
|
|
|
+ wdev->iftype))
|
|
|
return -EINVAL;
|
|
|
|
|
|
- err = cfg80211_chandef_dfs_required(wdev->wiphy, ¶ms.chandef);
|
|
|
- if (err < 0)
|
|
|
- return err;
|
|
|
- if (err) {
|
|
|
- radar_detect_width = BIT(params.chandef.width);
|
|
|
- params.radar_required = true;
|
|
|
- }
|
|
|
-
|
|
|
- err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
|
|
|
- params.chandef.chan,
|
|
|
- CHAN_MODE_SHARED,
|
|
|
- radar_detect_width);
|
|
|
- if (err)
|
|
|
- return err;
|
|
|
-
|
|
|
if (info->attrs[NL80211_ATTR_ACL_POLICY]) {
|
|
|
params.acl = parse_acl_data(&rdev->wiphy, info);
|
|
|
if (IS_ERR(params.acl))
|
|
@@ -3675,13 +3702,13 @@ static int nl80211_dump_station(struct sk_buff *skb,
|
|
|
struct netlink_callback *cb)
|
|
|
{
|
|
|
struct station_info sinfo;
|
|
|
- struct cfg80211_registered_device *dev;
|
|
|
+ struct cfg80211_registered_device *rdev;
|
|
|
struct wireless_dev *wdev;
|
|
|
u8 mac_addr[ETH_ALEN];
|
|
|
int sta_idx = cb->args[2];
|
|
|
int err;
|
|
|
|
|
|
- err = nl80211_prepare_wdev_dump(skb, cb, &dev, &wdev);
|
|
|
+ err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
|
|
|
if (err)
|
|
|
return err;
|
|
|
|
|
@@ -3690,14 +3717,14 @@ static int nl80211_dump_station(struct sk_buff *skb,
|
|
|
goto out_err;
|
|
|
}
|
|
|
|
|
|
- if (!dev->ops->dump_station) {
|
|
|
+ if (!rdev->ops->dump_station) {
|
|
|
err = -EOPNOTSUPP;
|
|
|
goto out_err;
|
|
|
}
|
|
|
|
|
|
while (1) {
|
|
|
memset(&sinfo, 0, sizeof(sinfo));
|
|
|
- err = rdev_dump_station(dev, wdev->netdev, sta_idx,
|
|
|
+ err = rdev_dump_station(rdev, wdev->netdev, sta_idx,
|
|
|
mac_addr, &sinfo);
|
|
|
if (err == -ENOENT)
|
|
|
break;
|
|
@@ -3707,7 +3734,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
|
|
|
if (nl80211_send_station(skb,
|
|
|
NETLINK_CB(cb->skb).portid,
|
|
|
cb->nlh->nlmsg_seq, NLM_F_MULTI,
|
|
|
- dev, wdev->netdev, mac_addr,
|
|
|
+ rdev, wdev->netdev, mac_addr,
|
|
|
&sinfo) < 0)
|
|
|
goto out;
|
|
|
|
|
@@ -3719,7 +3746,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
|
|
|
cb->args[2] = sta_idx;
|
|
|
err = skb->len;
|
|
|
out_err:
|
|
|
- nl80211_finish_wdev_dump(dev);
|
|
|
+ nl80211_finish_wdev_dump(rdev);
|
|
|
|
|
|
return err;
|
|
|
}
|
|
@@ -4380,18 +4407,18 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
|
|
|
struct netlink_callback *cb)
|
|
|
{
|
|
|
struct mpath_info pinfo;
|
|
|
- struct cfg80211_registered_device *dev;
|
|
|
+ struct cfg80211_registered_device *rdev;
|
|
|
struct wireless_dev *wdev;
|
|
|
u8 dst[ETH_ALEN];
|
|
|
u8 next_hop[ETH_ALEN];
|
|
|
int path_idx = cb->args[2];
|
|
|
int err;
|
|
|
|
|
|
- err = nl80211_prepare_wdev_dump(skb, cb, &dev, &wdev);
|
|
|
+ err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
|
|
|
if (err)
|
|
|
return err;
|
|
|
|
|
|
- if (!dev->ops->dump_mpath) {
|
|
|
+ if (!rdev->ops->dump_mpath) {
|
|
|
err = -EOPNOTSUPP;
|
|
|
goto out_err;
|
|
|
}
|
|
@@ -4402,7 +4429,7 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
|
|
|
}
|
|
|
|
|
|
while (1) {
|
|
|
- err = rdev_dump_mpath(dev, wdev->netdev, path_idx, dst,
|
|
|
+ err = rdev_dump_mpath(rdev, wdev->netdev, path_idx, dst,
|
|
|
next_hop, &pinfo);
|
|
|
if (err == -ENOENT)
|
|
|
break;
|
|
@@ -4423,7 +4450,7 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
|
|
|
cb->args[2] = path_idx;
|
|
|
err = skb->len;
|
|
|
out_err:
|
|
|
- nl80211_finish_wdev_dump(dev);
|
|
|
+ nl80211_finish_wdev_dump(rdev);
|
|
|
return err;
|
|
|
}
|
|
|
|
|
@@ -4663,7 +4690,6 @@ static int parse_reg_rule(struct nlattr *tb[],
|
|
|
|
|
|
static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
|
|
|
{
|
|
|
- int r;
|
|
|
char *data = NULL;
|
|
|
enum nl80211_user_reg_hint_type user_reg_hint_type;
|
|
|
|
|
@@ -4676,11 +4702,6 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
|
|
|
if (unlikely(!rcu_access_pointer(cfg80211_regdomain)))
|
|
|
return -EINPROGRESS;
|
|
|
|
|
|
- if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
|
|
|
-
|
|
|
if (info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE])
|
|
|
user_reg_hint_type =
|
|
|
nla_get_u32(info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]);
|
|
@@ -4690,14 +4711,16 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
|
|
|
switch (user_reg_hint_type) {
|
|
|
case NL80211_USER_REG_HINT_USER:
|
|
|
case NL80211_USER_REG_HINT_CELL_BASE:
|
|
|
- break;
|
|
|
+ if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
|
|
|
+ return regulatory_hint_user(data, user_reg_hint_type);
|
|
|
+ case NL80211_USER_REG_HINT_INDOOR:
|
|
|
+ return regulatory_hint_indoor_user();
|
|
|
default:
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
-
|
|
|
- r = regulatory_hint_user(data, user_reg_hint_type);
|
|
|
-
|
|
|
- return r;
|
|
|
}
|
|
|
|
|
|
static int nl80211_get_mesh_config(struct sk_buff *skb,
|
|
@@ -5796,7 +5819,8 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
|
|
|
if (wdev->cac_started)
|
|
|
return -EBUSY;
|
|
|
|
|
|
- err = cfg80211_chandef_dfs_required(wdev->wiphy, &chandef);
|
|
|
+ err = cfg80211_chandef_dfs_required(wdev->wiphy, &chandef,
|
|
|
+ NL80211_IFTYPE_UNSPECIFIED);
|
|
|
if (err < 0)
|
|
|
return err;
|
|
|
|
|
@@ -5809,12 +5833,6 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
|
|
|
if (!rdev->ops->start_radar_detection)
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
|
- err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
|
|
|
- chandef.chan, CHAN_MODE_SHARED,
|
|
|
- BIT(chandef.width));
|
|
|
- if (err)
|
|
|
- return err;
|
|
|
-
|
|
|
cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef);
|
|
|
if (WARN_ON(!cac_time_ms))
|
|
|
cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
|
|
@@ -5928,27 +5946,25 @@ skip_beacons:
|
|
|
if (err)
|
|
|
return err;
|
|
|
|
|
|
- if (!cfg80211_reg_can_beacon(&rdev->wiphy, ¶ms.chandef))
|
|
|
+ if (!cfg80211_reg_can_beacon(&rdev->wiphy, ¶ms.chandef,
|
|
|
+ wdev->iftype))
|
|
|
return -EINVAL;
|
|
|
|
|
|
- switch (dev->ieee80211_ptr->iftype) {
|
|
|
- case NL80211_IFTYPE_AP:
|
|
|
- case NL80211_IFTYPE_P2P_GO:
|
|
|
- case NL80211_IFTYPE_ADHOC:
|
|
|
- case NL80211_IFTYPE_MESH_POINT:
|
|
|
- err = cfg80211_chandef_dfs_required(wdev->wiphy,
|
|
|
- ¶ms.chandef);
|
|
|
- if (err < 0)
|
|
|
- return err;
|
|
|
- if (err) {
|
|
|
- radar_detect_width = BIT(params.chandef.width);
|
|
|
- params.radar_required = true;
|
|
|
- }
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
+ err = cfg80211_chandef_dfs_required(wdev->wiphy,
|
|
|
+ ¶ms.chandef,
|
|
|
+ wdev->iftype);
|
|
|
+ if (err < 0)
|
|
|
+ return err;
|
|
|
+
|
|
|
+ if (err > 0) {
|
|
|
+ radar_detect_width = BIT(params.chandef.width);
|
|
|
+ params.radar_required = true;
|
|
|
}
|
|
|
|
|
|
+ /* TODO: I left this here for now. With channel switch, the
|
|
|
+ * verification is a bit more complicated, because we only do
|
|
|
+ * it later when the channel switch really happens.
|
|
|
+ */
|
|
|
err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
|
|
|
params.chandef.chan,
|
|
|
CHAN_MODE_SHARED,
|
|
@@ -6175,12 +6191,12 @@ static int nl80211_dump_survey(struct sk_buff *skb,
|
|
|
struct netlink_callback *cb)
|
|
|
{
|
|
|
struct survey_info survey;
|
|
|
- struct cfg80211_registered_device *dev;
|
|
|
+ struct cfg80211_registered_device *rdev;
|
|
|
struct wireless_dev *wdev;
|
|
|
int survey_idx = cb->args[2];
|
|
|
int res;
|
|
|
|
|
|
- res = nl80211_prepare_wdev_dump(skb, cb, &dev, &wdev);
|
|
|
+ res = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
|
|
|
if (res)
|
|
|
return res;
|
|
|
|
|
@@ -6189,7 +6205,7 @@ static int nl80211_dump_survey(struct sk_buff *skb,
|
|
|
goto out_err;
|
|
|
}
|
|
|
|
|
|
- if (!dev->ops->dump_survey) {
|
|
|
+ if (!rdev->ops->dump_survey) {
|
|
|
res = -EOPNOTSUPP;
|
|
|
goto out_err;
|
|
|
}
|
|
@@ -6197,7 +6213,7 @@ static int nl80211_dump_survey(struct sk_buff *skb,
|
|
|
while (1) {
|
|
|
struct ieee80211_channel *chan;
|
|
|
|
|
|
- res = rdev_dump_survey(dev, wdev->netdev, survey_idx, &survey);
|
|
|
+ res = rdev_dump_survey(rdev, wdev->netdev, survey_idx, &survey);
|
|
|
if (res == -ENOENT)
|
|
|
break;
|
|
|
if (res)
|
|
@@ -6209,7 +6225,7 @@ static int nl80211_dump_survey(struct sk_buff *skb,
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
- chan = ieee80211_get_channel(&dev->wiphy,
|
|
|
+ chan = ieee80211_get_channel(&rdev->wiphy,
|
|
|
survey.channel->center_freq);
|
|
|
if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) {
|
|
|
survey_idx++;
|
|
@@ -6228,7 +6244,7 @@ static int nl80211_dump_survey(struct sk_buff *skb,
|
|
|
cb->args[2] = survey_idx;
|
|
|
res = skb->len;
|
|
|
out_err:
|
|
|
- nl80211_finish_wdev_dump(dev);
|
|
|
+ nl80211_finish_wdev_dump(rdev);
|
|
|
return res;
|
|
|
}
|
|
|
|
|
@@ -6704,7 +6720,8 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
|
|
|
if (err)
|
|
|
return err;
|
|
|
|
|
|
- if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef))
|
|
|
+ if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef,
|
|
|
+ NL80211_IFTYPE_ADHOC))
|
|
|
return -EINVAL;
|
|
|
|
|
|
switch (ibss.chandef.width) {
|
|
@@ -6879,7 +6896,7 @@ struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy,
|
|
|
int vendor_event_idx,
|
|
|
int approxlen, gfp_t gfp)
|
|
|
{
|
|
|
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
|
|
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
|
|
const struct nl80211_vendor_cmd_info *info;
|
|
|
|
|
|
switch (cmd) {
|
|
@@ -8981,9 +8998,8 @@ static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
|
|
|
if (wdev->p2p_started)
|
|
|
return 0;
|
|
|
|
|
|
- err = cfg80211_can_add_interface(rdev, wdev->iftype);
|
|
|
- if (err)
|
|
|
- return err;
|
|
|
+ if (rfkill_blocked(rdev->rfkill))
|
|
|
+ return -ERFKILL;
|
|
|
|
|
|
err = rdev_start_p2p_device(rdev, wdev);
|
|
|
if (err)
|
|
@@ -9192,7 +9208,7 @@ struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy,
|
|
|
enum nl80211_attrs attr,
|
|
|
int approxlen)
|
|
|
{
|
|
|
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
|
|
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
|
|
|
|
|
if (WARN_ON(!rdev->cur_cmd_info))
|
|
|
return NULL;
|
|
@@ -9316,7 +9332,7 @@ static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
|
|
|
}
|
|
|
|
|
|
dev = wdev->netdev;
|
|
|
- rdev = wiphy_to_dev(wdev->wiphy);
|
|
|
+ rdev = wiphy_to_rdev(wdev->wiphy);
|
|
|
|
|
|
if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
|
|
|
if (!dev) {
|
|
@@ -10345,7 +10361,7 @@ void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
|
|
|
{
|
|
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
|
struct wiphy *wiphy = wdev->wiphy;
|
|
|
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
|
|
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
|
|
const struct ieee80211_mgmt *mgmt = (void *)buf;
|
|
|
u32 cmd;
|
|
|
|
|
@@ -10567,7 +10583,7 @@ void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
|
|
|
const u8* ie, u8 ie_len, gfp_t gfp)
|
|
|
{
|
|
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
|
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
|
|
|
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
|
|
|
struct sk_buff *msg;
|
|
|
void *hdr;
|
|
|
|
|
@@ -10747,7 +10763,7 @@ void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
|
|
|
unsigned int duration, gfp_t gfp)
|
|
|
{
|
|
|
struct wiphy *wiphy = wdev->wiphy;
|
|
|
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
|
|
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
|
|
|
|
|
trace_cfg80211_ready_on_channel(wdev, cookie, chan, duration);
|
|
|
nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
|
|
@@ -10761,7 +10777,7 @@ void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
|
|
|
gfp_t gfp)
|
|
|
{
|
|
|
struct wiphy *wiphy = wdev->wiphy;
|
|
|
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
|
|
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
|
|
|
|
|
trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan);
|
|
|
nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
|
|
@@ -10773,7 +10789,7 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
|
|
|
struct station_info *sinfo, gfp_t gfp)
|
|
|
{
|
|
|
struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
|
|
|
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
|
|
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
|
|
struct sk_buff *msg;
|
|
|
|
|
|
trace_cfg80211_new_sta(dev, mac_addr, sinfo);
|
|
@@ -10796,7 +10812,7 @@ EXPORT_SYMBOL(cfg80211_new_sta);
|
|
|
void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp)
|
|
|
{
|
|
|
struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
|
|
|
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
|
|
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
|
|
struct sk_buff *msg;
|
|
|
void *hdr;
|
|
|
|
|
@@ -10833,7 +10849,7 @@ void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
|
|
|
gfp_t gfp)
|
|
|
{
|
|
|
struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
|
|
|
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
|
|
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
|
|
struct sk_buff *msg;
|
|
|
void *hdr;
|
|
|
|
|
@@ -10868,7 +10884,7 @@ static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
|
|
|
const u8 *addr, gfp_t gfp)
|
|
|
{
|
|
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
|
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
|
|
|
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
|
|
|
struct sk_buff *msg;
|
|
|
void *hdr;
|
|
|
u32 nlportid = ACCESS_ONCE(wdev->ap_unexpected_nlportid);
|
|
@@ -10988,7 +11004,7 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
|
|
|
const u8 *buf, size_t len, bool ack, gfp_t gfp)
|
|
|
{
|
|
|
struct wiphy *wiphy = wdev->wiphy;
|
|
|
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
|
|
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
|
|
struct net_device *netdev = wdev->netdev;
|
|
|
struct sk_buff *msg;
|
|
|
void *hdr;
|
|
@@ -11032,7 +11048,7 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev,
|
|
|
{
|
|
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
|
struct wiphy *wiphy = wdev->wiphy;
|
|
|
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
|
|
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
|
|
struct sk_buff *msg;
|
|
|
struct nlattr *pinfoattr;
|
|
|
void *hdr;
|
|
@@ -11124,7 +11140,7 @@ void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
|
|
|
{
|
|
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
|
struct wiphy *wiphy = wdev->wiphy;
|
|
|
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
|
|
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
|
|
|
|
|
trace_cfg80211_gtk_rekey_notify(dev, bssid);
|
|
|
nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
|
|
@@ -11182,7 +11198,7 @@ void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
|
|
|
{
|
|
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
|
struct wiphy *wiphy = wdev->wiphy;
|
|
|
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
|
|
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
|
|
|
|
|
trace_cfg80211_pmksa_candidate_notify(dev, index, bssid, preauth);
|
|
|
nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
|
|
@@ -11229,7 +11245,7 @@ void cfg80211_ch_switch_notify(struct net_device *dev,
|
|
|
{
|
|
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
|
struct wiphy *wiphy = wdev->wiphy;
|
|
|
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
|
|
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
|
|
|
|
|
ASSERT_WDEV_LOCK(wdev);
|
|
|
|
|
@@ -11253,7 +11269,7 @@ void cfg80211_cqm_txe_notify(struct net_device *dev,
|
|
|
{
|
|
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
|
struct wiphy *wiphy = wdev->wiphy;
|
|
|
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
|
|
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
|
|
struct sk_buff *msg;
|
|
|
struct nlattr *pinfoattr;
|
|
|
void *hdr;
|
|
@@ -11353,7 +11369,7 @@ void cfg80211_cqm_pktloss_notify(struct net_device *dev,
|
|
|
{
|
|
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
|
struct wiphy *wiphy = wdev->wiphy;
|
|
|
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
|
|
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
|
|
struct sk_buff *msg;
|
|
|
struct nlattr *pinfoattr;
|
|
|
void *hdr;
|
|
@@ -11400,7 +11416,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
|
|
|
u64 cookie, bool acked, gfp_t gfp)
|
|
|
{
|
|
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
|
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
|
|
|
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
|
|
|
struct sk_buff *msg;
|
|
|
void *hdr;
|
|
|
|
|
@@ -11440,7 +11456,7 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy,
|
|
|
const u8 *frame, size_t len,
|
|
|
int freq, int sig_dbm)
|
|
|
{
|
|
|
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
|
|
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
|
|
struct sk_buff *msg;
|
|
|
void *hdr;
|
|
|
struct cfg80211_beacon_registration *reg;
|
|
@@ -11487,7 +11503,7 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
|
|
|
struct cfg80211_wowlan_wakeup *wakeup,
|
|
|
gfp_t gfp)
|
|
|
{
|
|
|
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
|
|
|
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
|
|
|
struct sk_buff *msg;
|
|
|
void *hdr;
|
|
|
int size = 200;
|
|
@@ -11597,7 +11613,7 @@ void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
|
|
|
u16 reason_code, gfp_t gfp)
|
|
|
{
|
|
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
|
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
|
|
|
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
|
|
|
struct sk_buff *msg;
|
|
|
void *hdr;
|
|
|
|
|
@@ -11649,9 +11665,15 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
|
|
|
rcu_read_lock();
|
|
|
|
|
|
list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
|
|
|
- list_for_each_entry_rcu(wdev, &rdev->wdev_list, list)
|
|
|
+ bool schedule_destroy_work = false;
|
|
|
+
|
|
|
+ list_for_each_entry_rcu(wdev, &rdev->wdev_list, list) {
|
|
|
cfg80211_mlme_unregister_socket(wdev, notify->portid);
|
|
|
|
|
|
+ if (wdev->owner_nlportid == notify->portid)
|
|
|
+ schedule_destroy_work = true;
|
|
|
+ }
|
|
|
+
|
|
|
spin_lock_bh(&rdev->beacon_registrations_lock);
|
|
|
list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations,
|
|
|
list) {
|
|
@@ -11662,11 +11684,24 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
|
|
|
}
|
|
|
}
|
|
|
spin_unlock_bh(&rdev->beacon_registrations_lock);
|
|
|
+
|
|
|
+ if (schedule_destroy_work) {
|
|
|
+ struct cfg80211_iface_destroy *destroy;
|
|
|
+
|
|
|
+ destroy = kzalloc(sizeof(*destroy), GFP_ATOMIC);
|
|
|
+ if (destroy) {
|
|
|
+ destroy->nlportid = notify->portid;
|
|
|
+ spin_lock(&rdev->destroy_list_lock);
|
|
|
+ list_add(&destroy->list, &rdev->destroy_list);
|
|
|
+ spin_unlock(&rdev->destroy_list_lock);
|
|
|
+ schedule_work(&rdev->destroy_work);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
rcu_read_unlock();
|
|
|
|
|
|
- return NOTIFY_DONE;
|
|
|
+ return NOTIFY_OK;
|
|
|
}
|
|
|
|
|
|
static struct notifier_block nl80211_netlink_notifier = {
|
|
@@ -11677,7 +11712,7 @@ void cfg80211_ft_event(struct net_device *netdev,
|
|
|
struct cfg80211_ft_event_params *ft_event)
|
|
|
{
|
|
|
struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
|
|
|
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
|
|
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
|
|
struct sk_buff *msg;
|
|
|
void *hdr;
|
|
|
|
|
@@ -11724,7 +11759,7 @@ void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp)
|
|
|
void *hdr;
|
|
|
u32 nlportid;
|
|
|
|
|
|
- rdev = wiphy_to_dev(wdev->wiphy);
|
|
|
+ rdev = wiphy_to_rdev(wdev->wiphy);
|
|
|
if (!rdev->crit_proto_nlportid)
|
|
|
return;
|
|
|
|
|
@@ -11759,7 +11794,7 @@ EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
|
|
|
void nl80211_send_ap_stopped(struct wireless_dev *wdev)
|
|
|
{
|
|
|
struct wiphy *wiphy = wdev->wiphy;
|
|
|
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
|
|
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
|
|
struct sk_buff *msg;
|
|
|
void *hdr;
|
|
|
|