mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-23 07:12:09 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
This commit is contained in:
commit
40a10fd740
60 changed files with 1489 additions and 732 deletions
|
@ -6,8 +6,8 @@
|
|||
#include "rdev-ops.h"
|
||||
|
||||
|
||||
static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev, bool notify)
|
||||
int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev, bool notify)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
int err;
|
||||
|
|
|
@ -370,8 +370,8 @@ int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
|
|||
case NL80211_IFTYPE_AP_VLAN:
|
||||
case NL80211_IFTYPE_WDS:
|
||||
case NL80211_IFTYPE_P2P_DEVICE:
|
||||
case NL80211_IFTYPE_UNSPECIFIED:
|
||||
break;
|
||||
case NL80211_IFTYPE_UNSPECIFIED:
|
||||
case NUM_NL80211_IFTYPES:
|
||||
WARN_ON(1);
|
||||
}
|
||||
|
@ -796,8 +796,7 @@ bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
|
|||
!cfg80211_go_permissive_chan(rdev, chandef->chan))
|
||||
prohibited_flags |= IEEE80211_CHAN_NO_IR;
|
||||
|
||||
if (cfg80211_chandef_dfs_required(wiphy, chandef,
|
||||
NL80211_IFTYPE_UNSPECIFIED) > 0 &&
|
||||
if (cfg80211_chandef_dfs_required(wiphy, chandef, iftype) > 0 &&
|
||||
cfg80211_chandef_dfs_available(wiphy, chandef)) {
|
||||
/* We can skip IEEE80211_CHAN_NO_IR if chandef dfs available */
|
||||
prohibited_flags = IEEE80211_CHAN_DISABLED;
|
||||
|
|
|
@ -210,15 +210,12 @@ void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
|
|||
}
|
||||
}
|
||||
|
||||
static int cfg80211_rfkill_set_block(void *data, bool blocked)
|
||||
void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = data;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
||||
struct wireless_dev *wdev;
|
||||
|
||||
if (!blocked)
|
||||
return 0;
|
||||
|
||||
rtnl_lock();
|
||||
ASSERT_RTNL();
|
||||
|
||||
list_for_each_entry(wdev, &rdev->wdev_list, list) {
|
||||
if (wdev->netdev) {
|
||||
|
@ -234,7 +231,18 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked)
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cfg80211_shutdown_all_interfaces);
|
||||
|
||||
static int cfg80211_rfkill_set_block(void *data, bool blocked)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = data;
|
||||
|
||||
if (!blocked)
|
||||
return 0;
|
||||
|
||||
rtnl_lock();
|
||||
cfg80211_shutdown_all_interfaces(&rdev->wiphy);
|
||||
rtnl_unlock();
|
||||
|
||||
return 0;
|
||||
|
@ -394,6 +402,8 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
|
|||
rdev->wiphy.rts_threshold = (u32) -1;
|
||||
rdev->wiphy.coverage_class = 0;
|
||||
|
||||
rdev->wiphy.max_num_csa_counters = 1;
|
||||
|
||||
return &rdev->wiphy;
|
||||
}
|
||||
EXPORT_SYMBOL(wiphy_new);
|
||||
|
@ -690,7 +700,7 @@ void wiphy_unregister(struct wiphy *wiphy)
|
|||
rtnl_lock();
|
||||
rdev->wiphy.registered = false;
|
||||
|
||||
BUG_ON(!list_empty(&rdev->wdev_list));
|
||||
WARN_ON(!list_empty(&rdev->wdev_list));
|
||||
|
||||
/*
|
||||
* First remove the hardware from everywhere, this makes
|
||||
|
@ -792,23 +802,23 @@ void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
|
|||
rdev->num_running_monitor_ifaces += num;
|
||||
}
|
||||
|
||||
void cfg80211_leave(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev)
|
||||
void __cfg80211_leave(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev)
|
||||
{
|
||||
struct net_device *dev = wdev->netdev;
|
||||
|
||||
ASSERT_RTNL();
|
||||
ASSERT_WDEV_LOCK(wdev);
|
||||
|
||||
switch (wdev->iftype) {
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
cfg80211_leave_ibss(rdev, dev, true);
|
||||
__cfg80211_leave_ibss(rdev, dev, true);
|
||||
break;
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
case NL80211_IFTYPE_STATION:
|
||||
if (rdev->sched_scan_req && dev == rdev->sched_scan_req->dev)
|
||||
__cfg80211_stop_sched_scan(rdev, false);
|
||||
|
||||
wdev_lock(wdev);
|
||||
#ifdef CONFIG_CFG80211_WEXT
|
||||
kfree(wdev->wext.ie);
|
||||
wdev->wext.ie = NULL;
|
||||
|
@ -817,20 +827,49 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev,
|
|||
#endif
|
||||
cfg80211_disconnect(rdev, dev,
|
||||
WLAN_REASON_DEAUTH_LEAVING, true);
|
||||
wdev_unlock(wdev);
|
||||
break;
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
cfg80211_leave_mesh(rdev, dev);
|
||||
__cfg80211_leave_mesh(rdev, dev);
|
||||
break;
|
||||
case NL80211_IFTYPE_AP:
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
cfg80211_stop_ap(rdev, dev, true);
|
||||
__cfg80211_stop_ap(rdev, dev, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void cfg80211_leave(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev)
|
||||
{
|
||||
wdev_lock(wdev);
|
||||
__cfg80211_leave(rdev, wdev);
|
||||
wdev_unlock(wdev);
|
||||
}
|
||||
|
||||
void cfg80211_stop_iface(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
gfp_t gfp)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
||||
struct cfg80211_event *ev;
|
||||
unsigned long flags;
|
||||
|
||||
trace_cfg80211_stop_iface(wiphy, wdev);
|
||||
|
||||
ev = kzalloc(sizeof(*ev), gfp);
|
||||
if (!ev)
|
||||
return;
|
||||
|
||||
ev->type = EVENT_STOPPED;
|
||||
|
||||
spin_lock_irqsave(&wdev->event_lock, flags);
|
||||
list_add_tail(&ev->list, &wdev->event_list);
|
||||
spin_unlock_irqrestore(&wdev->event_lock, flags);
|
||||
queue_work(cfg80211_wq, &rdev->event_work);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_stop_iface);
|
||||
|
||||
static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
|
||||
unsigned long state, void *ptr)
|
||||
{
|
||||
|
|
|
@ -185,6 +185,7 @@ enum cfg80211_event_type {
|
|||
EVENT_ROAMED,
|
||||
EVENT_DISCONNECTED,
|
||||
EVENT_IBSS_JOINED,
|
||||
EVENT_STOPPED,
|
||||
};
|
||||
|
||||
struct cfg80211_event {
|
||||
|
@ -281,6 +282,8 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
|
|||
struct net_device *dev,
|
||||
struct mesh_setup *setup,
|
||||
const struct mesh_config *conf);
|
||||
int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev);
|
||||
int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev);
|
||||
int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
|
||||
|
@ -288,6 +291,8 @@ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
|
|||
struct cfg80211_chan_def *chandef);
|
||||
|
||||
/* AP */
|
||||
int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev, bool notify);
|
||||
int cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev, bool notify);
|
||||
|
||||
|
@ -441,6 +446,8 @@ 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);
|
||||
|
||||
void __cfg80211_leave(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev);
|
||||
void cfg80211_leave(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev);
|
||||
|
||||
|
|
|
@ -420,8 +420,8 @@ int cfg80211_ibss_wext_siwessid(struct net_device *dev,
|
|||
if (len > 0 && ssid[len - 1] == '\0')
|
||||
len--;
|
||||
|
||||
memcpy(wdev->ssid, ssid, len);
|
||||
wdev->wext.ibss.ssid = wdev->ssid;
|
||||
memcpy(wdev->wext.ibss.ssid, ssid, len);
|
||||
wdev->wext.ibss.ssid_len = len;
|
||||
|
||||
wdev_lock(wdev);
|
||||
|
|
|
@ -238,8 +238,8 @@ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev)
|
||||
int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
int err;
|
||||
|
|
|
@ -371,8 +371,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
|
|||
[NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG },
|
||||
[NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED },
|
||||
[NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_U16 },
|
||||
[NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_U16 },
|
||||
[NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_BINARY },
|
||||
[NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_BINARY },
|
||||
[NL80211_ATTR_STA_SUPPORTED_CHANNELS] = { .type = NLA_BINARY },
|
||||
[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = { .type = NLA_BINARY },
|
||||
[NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG },
|
||||
|
@ -386,6 +386,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
|
|||
[NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_IFACE_SOCKET_OWNER] = { .type = NLA_FLAG },
|
||||
[NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY },
|
||||
};
|
||||
|
||||
/* policy for the key attributes */
|
||||
|
@ -970,8 +971,10 @@ static int nl80211_put_iface_combinations(struct wiphy *wiphy,
|
|||
c->max_interfaces))
|
||||
goto nla_put_failure;
|
||||
if (large &&
|
||||
nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
|
||||
c->radar_detect_widths))
|
||||
(nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
|
||||
c->radar_detect_widths) ||
|
||||
nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
|
||||
c->radar_detect_regions)))
|
||||
goto nla_put_failure;
|
||||
|
||||
nla_nest_end(msg, nl_combi);
|
||||
|
@ -1667,6 +1670,13 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
|
|||
}
|
||||
nla_nest_end(msg, nested);
|
||||
}
|
||||
state->split_start++;
|
||||
break;
|
||||
case 12:
|
||||
if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH &&
|
||||
nla_put_u8(msg, NL80211_ATTR_MAX_CSA_COUNTERS,
|
||||
rdev->wiphy.max_num_csa_counters))
|
||||
goto nla_put_failure;
|
||||
|
||||
/* done */
|
||||
state->split_start = 0;
|
||||
|
@ -3640,6 +3650,10 @@ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
|
|||
nla_put_u32(msg, NL80211_STA_INFO_TX_FAILED,
|
||||
sinfo->tx_failed))
|
||||
goto nla_put_failure;
|
||||
if ((sinfo->filled & STATION_INFO_EXPECTED_THROUGHPUT) &&
|
||||
nla_put_u32(msg, NL80211_STA_INFO_EXPECTED_THROUGHPUT,
|
||||
sinfo->expected_throughput))
|
||||
goto nla_put_failure;
|
||||
if ((sinfo->filled & STATION_INFO_BEACON_LOSS_COUNT) &&
|
||||
nla_put_u32(msg, NL80211_STA_INFO_BEACON_LOSS,
|
||||
sinfo->beacon_loss_count))
|
||||
|
@ -5820,7 +5834,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
|
|||
return -EBUSY;
|
||||
|
||||
err = cfg80211_chandef_dfs_required(wdev->wiphy, &chandef,
|
||||
NL80211_IFTYPE_UNSPECIFIED);
|
||||
wdev->iftype);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -5861,6 +5875,7 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
|
|||
u8 radar_detect_width = 0;
|
||||
int err;
|
||||
bool need_new_beacon = false;
|
||||
int len, i;
|
||||
|
||||
if (!rdev->ops->channel_switch ||
|
||||
!(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH))
|
||||
|
@ -5919,26 +5934,55 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
|
|||
if (!csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON])
|
||||
return -EINVAL;
|
||||
|
||||
params.counter_offset_beacon =
|
||||
nla_get_u16(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]);
|
||||
if (params.counter_offset_beacon >= params.beacon_csa.tail_len)
|
||||
len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]);
|
||||
if (!len || (len % sizeof(u16)))
|
||||
return -EINVAL;
|
||||
|
||||
/* sanity check - counters should be the same */
|
||||
if (params.beacon_csa.tail[params.counter_offset_beacon] !=
|
||||
params.count)
|
||||
params.n_counter_offsets_beacon = len / sizeof(u16);
|
||||
if (rdev->wiphy.max_num_csa_counters &&
|
||||
(params.n_counter_offsets_beacon >
|
||||
rdev->wiphy.max_num_csa_counters))
|
||||
return -EINVAL;
|
||||
|
||||
params.counter_offsets_beacon =
|
||||
nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]);
|
||||
|
||||
/* sanity checks - counters should fit and be the same */
|
||||
for (i = 0; i < params.n_counter_offsets_beacon; i++) {
|
||||
u16 offset = params.counter_offsets_beacon[i];
|
||||
|
||||
if (offset >= params.beacon_csa.tail_len)
|
||||
return -EINVAL;
|
||||
|
||||
if (params.beacon_csa.tail[offset] != params.count)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]) {
|
||||
params.counter_offset_presp =
|
||||
nla_get_u16(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]);
|
||||
if (params.counter_offset_presp >=
|
||||
params.beacon_csa.probe_resp_len)
|
||||
len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]);
|
||||
if (!len || (len % sizeof(u16)))
|
||||
return -EINVAL;
|
||||
|
||||
if (params.beacon_csa.probe_resp[params.counter_offset_presp] !=
|
||||
params.count)
|
||||
params.n_counter_offsets_presp = len / sizeof(u16);
|
||||
if (rdev->wiphy.max_num_csa_counters &&
|
||||
(params.n_counter_offsets_beacon >
|
||||
rdev->wiphy.max_num_csa_counters))
|
||||
return -EINVAL;
|
||||
|
||||
params.counter_offsets_presp =
|
||||
nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]);
|
||||
|
||||
/* sanity checks - counters should fit and be the same */
|
||||
for (i = 0; i < params.n_counter_offsets_presp; i++) {
|
||||
u16 offset = params.counter_offsets_presp[i];
|
||||
|
||||
if (offset >= params.beacon_csa.probe_resp_len)
|
||||
return -EINVAL;
|
||||
|
||||
if (params.beacon_csa.probe_resp[offset] !=
|
||||
params.count)
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
skip_beacons:
|
||||
|
@ -7784,6 +7828,27 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
|
|||
if (!chandef.chan && params.offchan)
|
||||
return -EINVAL;
|
||||
|
||||
params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
|
||||
params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
|
||||
|
||||
if (info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]) {
|
||||
int len = nla_len(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
|
||||
int i;
|
||||
|
||||
if (len % sizeof(u16))
|
||||
return -EINVAL;
|
||||
|
||||
params.n_csa_offsets = len / sizeof(u16);
|
||||
params.csa_offsets =
|
||||
nla_data(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
|
||||
|
||||
/* check that all the offsets fit the frame */
|
||||
for (i = 0; i < params.n_csa_offsets; i++) {
|
||||
if (params.csa_offsets[i] >= params.len)
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!params.dont_wait_for_ack) {
|
||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||
if (!msg)
|
||||
|
@ -7797,8 +7862,6 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
|
|||
}
|
||||
}
|
||||
|
||||
params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
|
||||
params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
|
||||
params.chan = chandef.chan;
|
||||
err = cfg80211_mlme_mgmt_tx(rdev, wdev, ¶ms, &cookie);
|
||||
if (err)
|
||||
|
@ -8495,6 +8558,8 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
|
|||
|
||||
nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
|
||||
rem) {
|
||||
u8 *mask_pat;
|
||||
|
||||
nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat),
|
||||
nla_len(pat), NULL);
|
||||
err = -EINVAL;
|
||||
|
@ -8518,19 +8583,18 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
|
|||
goto error;
|
||||
new_triggers.patterns[i].pkt_offset = pkt_offset;
|
||||
|
||||
new_triggers.patterns[i].mask =
|
||||
kmalloc(mask_len + pat_len, GFP_KERNEL);
|
||||
if (!new_triggers.patterns[i].mask) {
|
||||
mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
|
||||
if (!mask_pat) {
|
||||
err = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
new_triggers.patterns[i].pattern =
|
||||
new_triggers.patterns[i].mask + mask_len;
|
||||
memcpy(new_triggers.patterns[i].mask,
|
||||
nla_data(pat_tb[NL80211_PKTPAT_MASK]),
|
||||
new_triggers.patterns[i].mask = mask_pat;
|
||||
memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
|
||||
mask_len);
|
||||
mask_pat += mask_len;
|
||||
new_triggers.patterns[i].pattern = mask_pat;
|
||||
new_triggers.patterns[i].pattern_len = pat_len;
|
||||
memcpy(new_triggers.patterns[i].pattern,
|
||||
memcpy(mask_pat,
|
||||
nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
|
||||
pat_len);
|
||||
i++;
|
||||
|
@ -8722,6 +8786,8 @@ static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev,
|
|||
|
||||
nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
|
||||
rem) {
|
||||
u8 *mask_pat;
|
||||
|
||||
nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat),
|
||||
nla_len(pat), NULL);
|
||||
if (!pat_tb[NL80211_PKTPAT_MASK] ||
|
||||
|
@ -8743,17 +8809,19 @@ static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev,
|
|||
return -EINVAL;
|
||||
new_rule->patterns[i].pkt_offset = pkt_offset;
|
||||
|
||||
new_rule->patterns[i].mask =
|
||||
kmalloc(mask_len + pat_len, GFP_KERNEL);
|
||||
if (!new_rule->patterns[i].mask)
|
||||
mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
|
||||
if (!mask_pat)
|
||||
return -ENOMEM;
|
||||
new_rule->patterns[i].pattern =
|
||||
new_rule->patterns[i].mask + mask_len;
|
||||
memcpy(new_rule->patterns[i].mask,
|
||||
nla_data(pat_tb[NL80211_PKTPAT_MASK]), mask_len);
|
||||
|
||||
new_rule->patterns[i].mask = mask_pat;
|
||||
memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
|
||||
mask_len);
|
||||
|
||||
mask_pat += mask_len;
|
||||
new_rule->patterns[i].pattern = mask_pat;
|
||||
new_rule->patterns[i].pattern_len = pat_len;
|
||||
memcpy(new_rule->patterns[i].pattern,
|
||||
nla_data(pat_tb[NL80211_PKTPAT_PATTERN]), pat_len);
|
||||
memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
|
||||
pat_len);
|
||||
i++;
|
||||
}
|
||||
|
||||
|
|
|
@ -199,7 +199,7 @@ static inline int rdev_change_station(struct cfg80211_registered_device *rdev,
|
|||
}
|
||||
|
||||
static inline int rdev_get_station(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev, u8 *mac,
|
||||
struct net_device *dev, const u8 *mac,
|
||||
struct station_info *sinfo)
|
||||
{
|
||||
int ret;
|
||||
|
|
|
@ -1876,7 +1876,8 @@ static void reg_process_hint(struct regulatory_request *reg_request)
|
|||
case NL80211_REGDOM_SET_BY_USER:
|
||||
treatment = reg_process_hint_user(reg_request);
|
||||
if (treatment == REG_REQ_IGNORE ||
|
||||
treatment == REG_REQ_ALREADY_SET)
|
||||
treatment == REG_REQ_ALREADY_SET ||
|
||||
treatment == REG_REQ_USER_HINT_HANDLED)
|
||||
return;
|
||||
queue_delayed_work(system_power_efficient_wq,
|
||||
®_timeout, msecs_to_jiffies(3142));
|
||||
|
|
|
@ -891,6 +891,7 @@ cfg80211_inform_bss_width(struct wiphy *wiphy,
|
|||
struct cfg80211_bss_ies *ies;
|
||||
struct ieee80211_channel *channel;
|
||||
struct cfg80211_internal_bss tmp = {}, *res;
|
||||
bool signal_valid;
|
||||
|
||||
if (WARN_ON(!wiphy))
|
||||
return NULL;
|
||||
|
@ -927,8 +928,9 @@ cfg80211_inform_bss_width(struct wiphy *wiphy,
|
|||
rcu_assign_pointer(tmp.pub.beacon_ies, ies);
|
||||
rcu_assign_pointer(tmp.pub.ies, ies);
|
||||
|
||||
res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp,
|
||||
rx_channel == channel);
|
||||
signal_valid = abs(rx_channel->center_freq - channel->center_freq) <=
|
||||
wiphy->max_adj_channel_rssi_comp;
|
||||
res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid);
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
|
@ -952,6 +954,7 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy,
|
|||
struct cfg80211_internal_bss tmp = {}, *res;
|
||||
struct cfg80211_bss_ies *ies;
|
||||
struct ieee80211_channel *channel;
|
||||
bool signal_valid;
|
||||
size_t ielen = len - offsetof(struct ieee80211_mgmt,
|
||||
u.probe_resp.variable);
|
||||
|
||||
|
@ -999,8 +1002,9 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy,
|
|||
tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
|
||||
tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
|
||||
|
||||
res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp,
|
||||
rx_channel == channel);
|
||||
signal_valid = abs(rx_channel->center_freq - channel->center_freq) <=
|
||||
wiphy->max_adj_channel_rssi_comp;
|
||||
res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid);
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -149,7 +149,8 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
|
|||
case CFG80211_CONN_SCAN_AGAIN:
|
||||
return cfg80211_conn_scan(wdev);
|
||||
case CFG80211_CONN_AUTHENTICATE_NEXT:
|
||||
BUG_ON(!rdev->ops->auth);
|
||||
if (WARN_ON(!rdev->ops->auth))
|
||||
return -EOPNOTSUPP;
|
||||
wdev->conn->state = CFG80211_CONN_AUTHENTICATING;
|
||||
return cfg80211_mlme_auth(rdev, wdev->netdev,
|
||||
params->channel, params->auth_type,
|
||||
|
@ -161,7 +162,8 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
|
|||
case CFG80211_CONN_AUTH_FAILED:
|
||||
return -ENOTCONN;
|
||||
case CFG80211_CONN_ASSOCIATE_NEXT:
|
||||
BUG_ON(!rdev->ops->assoc);
|
||||
if (WARN_ON(!rdev->ops->assoc))
|
||||
return -EOPNOTSUPP;
|
||||
wdev->conn->state = CFG80211_CONN_ASSOCIATING;
|
||||
if (wdev->conn->prev_bssid_valid)
|
||||
req.prev_bssid = wdev->conn->prev_bssid;
|
||||
|
@ -877,7 +879,7 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
|
|||
}
|
||||
|
||||
void cfg80211_disconnected(struct net_device *dev, u16 reason,
|
||||
u8 *ie, size_t ie_len, gfp_t gfp)
|
||||
const u8 *ie, size_t ie_len, gfp_t gfp)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
|
||||
|
|
|
@ -1876,29 +1876,33 @@ TRACE_EVENT(rdev_channel_switch,
|
|||
WIPHY_ENTRY
|
||||
NETDEV_ENTRY
|
||||
CHAN_DEF_ENTRY
|
||||
__field(u16, counter_offset_beacon)
|
||||
__field(u16, counter_offset_presp)
|
||||
__field(bool, radar_required)
|
||||
__field(bool, block_tx)
|
||||
__field(u8, count)
|
||||
__dynamic_array(u16, bcn_ofs, params->n_counter_offsets_beacon)
|
||||
__dynamic_array(u16, pres_ofs, params->n_counter_offsets_presp)
|
||||
),
|
||||
TP_fast_assign(
|
||||
WIPHY_ASSIGN;
|
||||
NETDEV_ASSIGN;
|
||||
CHAN_DEF_ASSIGN(¶ms->chandef);
|
||||
__entry->counter_offset_beacon = params->counter_offset_beacon;
|
||||
__entry->counter_offset_presp = params->counter_offset_presp;
|
||||
__entry->radar_required = params->radar_required;
|
||||
__entry->block_tx = params->block_tx;
|
||||
__entry->count = params->count;
|
||||
memcpy(__get_dynamic_array(bcn_ofs),
|
||||
params->counter_offsets_beacon,
|
||||
params->n_counter_offsets_beacon * sizeof(u16));
|
||||
|
||||
/* probe response offsets are optional */
|
||||
if (params->n_counter_offsets_presp)
|
||||
memcpy(__get_dynamic_array(pres_ofs),
|
||||
params->counter_offsets_presp,
|
||||
params->n_counter_offsets_presp * sizeof(u16));
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT
|
||||
", block_tx: %d, count: %u, radar_required: %d"
|
||||
", counter offsets (beacon/presp): %u/%u",
|
||||
", block_tx: %d, count: %u, radar_required: %d",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, CHAN_DEF_PR_ARG,
|
||||
__entry->block_tx, __entry->count, __entry->radar_required,
|
||||
__entry->counter_offset_beacon,
|
||||
__entry->counter_offset_presp)
|
||||
__entry->block_tx, __entry->count, __entry->radar_required)
|
||||
);
|
||||
|
||||
TRACE_EVENT(rdev_set_qos_map,
|
||||
|
@ -2636,6 +2640,21 @@ TRACE_EVENT(cfg80211_ft_event,
|
|||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(target_ap))
|
||||
);
|
||||
|
||||
TRACE_EVENT(cfg80211_stop_iface,
|
||||
TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev),
|
||||
TP_ARGS(wiphy, wdev),
|
||||
TP_STRUCT__entry(
|
||||
WIPHY_ENTRY
|
||||
WDEV_ENTRY
|
||||
),
|
||||
TP_fast_assign(
|
||||
WIPHY_ASSIGN;
|
||||
WDEV_ASSIGN;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT,
|
||||
WIPHY_PR_ARG, WDEV_PR_ARG)
|
||||
);
|
||||
|
||||
#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
||||
|
|
|
@ -476,7 +476,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
|
|||
EXPORT_SYMBOL(ieee80211_data_to_8023);
|
||||
|
||||
int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
|
||||
enum nl80211_iftype iftype, u8 *bssid, bool qos)
|
||||
enum nl80211_iftype iftype,
|
||||
const u8 *bssid, bool qos)
|
||||
{
|
||||
struct ieee80211_hdr hdr;
|
||||
u16 hdrlen, ethertype;
|
||||
|
@ -839,6 +840,9 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev)
|
|||
__cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid,
|
||||
ev->ij.channel);
|
||||
break;
|
||||
case EVENT_STOPPED:
|
||||
__cfg80211_leave(wiphy_to_rdev(wdev->wiphy), wdev);
|
||||
break;
|
||||
}
|
||||
wdev_unlock(wdev);
|
||||
|
||||
|
@ -1271,10 +1275,20 @@ int cfg80211_iter_combinations(struct wiphy *wiphy,
|
|||
void *data),
|
||||
void *data)
|
||||
{
|
||||
const struct ieee80211_regdomain *regdom;
|
||||
enum nl80211_dfs_regions region = 0;
|
||||
int i, j, iftype;
|
||||
int num_interfaces = 0;
|
||||
u32 used_iftypes = 0;
|
||||
|
||||
if (radar_detect) {
|
||||
rcu_read_lock();
|
||||
regdom = rcu_dereference(cfg80211_regdomain);
|
||||
if (regdom)
|
||||
region = regdom->dfs_region;
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) {
|
||||
num_interfaces += iftype_num[iftype];
|
||||
if (iftype_num[iftype] > 0 &&
|
||||
|
@ -1315,6 +1329,10 @@ int cfg80211_iter_combinations(struct wiphy *wiphy,
|
|||
if (radar_detect != (c->radar_detect_widths & radar_detect))
|
||||
goto cont;
|
||||
|
||||
if (radar_detect && c->radar_detect_regions &&
|
||||
!(c->radar_detect_regions & BIT(region)))
|
||||
goto cont;
|
||||
|
||||
/* Finally check that all iftypes that we're currently
|
||||
* using are actually part of this combination. If they
|
||||
* aren't then we can't use this combination and have
|
||||
|
@ -1528,6 +1546,24 @@ unsigned int ieee80211_get_num_supported_channels(struct wiphy *wiphy)
|
|||
}
|
||||
EXPORT_SYMBOL(ieee80211_get_num_supported_channels);
|
||||
|
||||
int cfg80211_get_station(struct net_device *dev, const u8 *mac_addr,
|
||||
struct station_info *sinfo)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev;
|
||||
struct wireless_dev *wdev;
|
||||
|
||||
wdev = dev->ieee80211_ptr;
|
||||
if (!wdev)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
rdev = wiphy_to_rdev(wdev->wiphy);
|
||||
if (!rdev->ops->get_station)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return rdev_get_station(rdev, dev, mac_addr, sinfo);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_get_station);
|
||||
|
||||
/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
|
||||
/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
|
||||
const unsigned char rfc1042_header[] __aligned(2) =
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue