Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
This commit is contained in:
commit
133eb82f09
|
@ -84,6 +84,15 @@ static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
|
|||
.types = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP),
|
||||
},
|
||||
{
|
||||
.max = 1,
|
||||
.types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
BIT(NL80211_IFTYPE_P2P_GO),
|
||||
},
|
||||
{
|
||||
.max = 1,
|
||||
.types = BIT(NL80211_IFTYPE_P2P_DEVICE),
|
||||
},
|
||||
};
|
||||
|
||||
static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = {
|
||||
|
@ -164,7 +173,10 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
|||
hw->chanctx_data_size = sizeof(u16);
|
||||
|
||||
hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP);
|
||||
BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
BIT(NL80211_IFTYPE_AP) |
|
||||
BIT(NL80211_IFTYPE_P2P_GO) |
|
||||
BIT(NL80211_IFTYPE_P2P_DEVICE);
|
||||
|
||||
hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
|
||||
WIPHY_FLAG_DISABLE_BEACON_HINTS |
|
||||
|
|
|
@ -2169,6 +2169,7 @@ static const struct ieee80211_iface_limit hwsim_if_limits[] = {
|
|||
#endif
|
||||
BIT(NL80211_IFTYPE_AP) |
|
||||
BIT(NL80211_IFTYPE_P2P_GO) },
|
||||
{ .max = 1, .types = BIT(NL80211_IFTYPE_P2P_DEVICE) },
|
||||
};
|
||||
|
||||
static struct ieee80211_iface_combination hwsim_if_comb = {
|
||||
|
@ -2294,7 +2295,8 @@ static int __init init_mac80211_hwsim(void)
|
|||
BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
BIT(NL80211_IFTYPE_P2P_GO) |
|
||||
BIT(NL80211_IFTYPE_ADHOC) |
|
||||
BIT(NL80211_IFTYPE_MESH_POINT);
|
||||
BIT(NL80211_IFTYPE_MESH_POINT) |
|
||||
BIT(NL80211_IFTYPE_P2P_DEVICE);
|
||||
|
||||
hw->flags = IEEE80211_HW_MFP_CAPABLE |
|
||||
IEEE80211_HW_SIGNAL_DBM |
|
||||
|
|
|
@ -961,6 +961,7 @@ struct station_info {
|
|||
* @MONITOR_FLAG_CONTROL: pass control frames
|
||||
* @MONITOR_FLAG_OTHER_BSS: disable BSSID filtering
|
||||
* @MONITOR_FLAG_COOK_FRAMES: report frames after processing
|
||||
* @MONITOR_FLAG_ACTIVE: active monitor, ACKs frames on its MAC address
|
||||
*/
|
||||
enum monitor_flags {
|
||||
MONITOR_FLAG_FCSFAIL = 1<<NL80211_MNTR_FLAG_FCSFAIL,
|
||||
|
@ -968,6 +969,7 @@ enum monitor_flags {
|
|||
MONITOR_FLAG_CONTROL = 1<<NL80211_MNTR_FLAG_CONTROL,
|
||||
MONITOR_FLAG_OTHER_BSS = 1<<NL80211_MNTR_FLAG_OTHER_BSS,
|
||||
MONITOR_FLAG_COOK_FRAMES = 1<<NL80211_MNTR_FLAG_COOK_FRAMES,
|
||||
MONITOR_FLAG_ACTIVE = 1<<NL80211_MNTR_FLAG_ACTIVE,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -2867,7 +2869,6 @@ struct cfg80211_cached_keys;
|
|||
* @mgmt_registrations_lock: lock for the list
|
||||
* @mtx: mutex used to lock data in this struct, may be used by drivers
|
||||
* and some API functions require it held
|
||||
* @cleanup_work: work struct used for cleanup that can't be done directly
|
||||
* @beacon_interval: beacon interval used on this device for transmitting
|
||||
* beacons, 0 when not valid
|
||||
* @address: The address for this device, valid only if @netdev is %NULL
|
||||
|
|
|
@ -2428,6 +2428,8 @@ enum nl80211_survey_info {
|
|||
* @NL80211_MNTR_FLAG_OTHER_BSS: disable BSSID filtering
|
||||
* @NL80211_MNTR_FLAG_COOK_FRAMES: report frames after processing.
|
||||
* overrides all other flags.
|
||||
* @NL80211_MNTR_FLAG_ACTIVE: use the configured MAC address
|
||||
* and ACK incoming unicast packets.
|
||||
*
|
||||
* @__NL80211_MNTR_FLAG_AFTER_LAST: internal use
|
||||
* @NL80211_MNTR_FLAG_MAX: highest possible monitor flag
|
||||
|
@ -2439,6 +2441,7 @@ enum nl80211_mntr_flags {
|
|||
NL80211_MNTR_FLAG_CONTROL,
|
||||
NL80211_MNTR_FLAG_OTHER_BSS,
|
||||
NL80211_MNTR_FLAG_COOK_FRAMES,
|
||||
NL80211_MNTR_FLAG_ACTIVE,
|
||||
|
||||
/* keep last */
|
||||
__NL80211_MNTR_FLAG_AFTER_LAST,
|
||||
|
@ -3595,6 +3598,7 @@ enum nl80211_feature_flags {
|
|||
NL80211_FEATURE_ADVERTISE_CHAN_LIMITS = 1 << 14,
|
||||
NL80211_FEATURE_FULL_AP_CLIENT_STATE = 1 << 15,
|
||||
NL80211_FEATURE_USERSPACE_MPM = 1 << 16,
|
||||
NL80211_FEATURE_ACTIVE_MONITOR = 1 << 17,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -73,16 +73,19 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
|
|||
struct ieee80211_local *local = sdata->local;
|
||||
|
||||
if (ieee80211_sdata_running(sdata)) {
|
||||
u32 mask = MONITOR_FLAG_COOK_FRAMES |
|
||||
MONITOR_FLAG_ACTIVE;
|
||||
|
||||
/*
|
||||
* Prohibit MONITOR_FLAG_COOK_FRAMES to be
|
||||
* changed while the interface is up.
|
||||
* Prohibit MONITOR_FLAG_COOK_FRAMES and
|
||||
* MONITOR_FLAG_ACTIVE to be changed while the
|
||||
* interface is up.
|
||||
* Else we would need to add a lot of cruft
|
||||
* to update everything:
|
||||
* cooked_mntrs, monitor and all fif_* counters
|
||||
* reconfigure hardware
|
||||
*/
|
||||
if ((*flags & MONITOR_FLAG_COOK_FRAMES) !=
|
||||
(sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES))
|
||||
if ((*flags & mask) != (sdata->u.mntr_flags & mask))
|
||||
return -EBUSY;
|
||||
|
||||
ieee80211_adjust_monitor_flags(sdata, -1);
|
||||
|
@ -2375,7 +2378,9 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
|
|||
local->dynamic_ps_forced_timeout = timeout;
|
||||
|
||||
/* no change, but if automatic follow powersave */
|
||||
sdata_lock(sdata);
|
||||
__ieee80211_request_smps(sdata, sdata->u.mgd.req_smps);
|
||||
sdata_unlock(sdata);
|
||||
|
||||
if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
|
||||
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
|
||||
|
|
|
@ -146,7 +146,8 @@ static inline int drv_add_interface(struct ieee80211_local *local,
|
|||
|
||||
if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
|
||||
(sdata->vif.type == NL80211_IFTYPE_MONITOR &&
|
||||
!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF))))
|
||||
!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF) &&
|
||||
!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))))
|
||||
return -EINVAL;
|
||||
|
||||
trace_drv_add_interface(local, sdata);
|
||||
|
|
|
@ -159,7 +159,8 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr)
|
||||
static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr,
|
||||
bool check_dup)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
u64 new, mask, tmp;
|
||||
|
@ -179,10 +180,13 @@ static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr)
|
|||
((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
|
||||
((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
|
||||
|
||||
if (!check_dup)
|
||||
return ret;
|
||||
|
||||
mutex_lock(&local->iflist_mtx);
|
||||
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||
if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
|
||||
if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
|
||||
!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
|
||||
continue;
|
||||
|
||||
m = sdata->vif.addr;
|
||||
|
@ -204,12 +208,17 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr)
|
|||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct sockaddr *sa = addr;
|
||||
bool check_dup = true;
|
||||
int ret;
|
||||
|
||||
if (ieee80211_sdata_running(sdata))
|
||||
return -EBUSY;
|
||||
|
||||
ret = ieee80211_verify_mac(sdata->local, sa->sa_data);
|
||||
if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
|
||||
!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
|
||||
check_dup = false;
|
||||
|
||||
ret = ieee80211_verify_mac(sdata->local, sa->sa_data, check_dup);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -541,7 +550,11 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
|
|||
break;
|
||||
}
|
||||
|
||||
if (local->monitors == 0 && local->open_count == 0) {
|
||||
if (sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE) {
|
||||
res = drv_add_interface(local, sdata);
|
||||
if (res)
|
||||
goto err_stop;
|
||||
} else if (local->monitors == 0 && local->open_count == 0) {
|
||||
res = ieee80211_add_virtual_monitor(local);
|
||||
if (res)
|
||||
goto err_stop;
|
||||
|
@ -919,7 +932,11 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
|
|||
mutex_lock(&local->mtx);
|
||||
ieee80211_recalc_idle(local);
|
||||
mutex_unlock(&local->mtx);
|
||||
break;
|
||||
|
||||
if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
|
||||
break;
|
||||
|
||||
/* fall through */
|
||||
default:
|
||||
if (going_down)
|
||||
drv_remove_interface(local, sdata);
|
||||
|
@ -1068,7 +1085,7 @@ static const struct net_device_ops ieee80211_monitorif_ops = {
|
|||
.ndo_start_xmit = ieee80211_monitor_start_xmit,
|
||||
.ndo_set_rx_mode = ieee80211_set_multicast_list,
|
||||
.ndo_change_mtu = ieee80211_change_mtu,
|
||||
.ndo_set_mac_address = eth_mac_addr,
|
||||
.ndo_set_mac_address = ieee80211_change_mac,
|
||||
.ndo_select_queue = ieee80211_monitor_select_queue,
|
||||
};
|
||||
|
||||
|
|
|
@ -398,13 +398,14 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
|
|||
if (ieee80211_has_order(hdr->frame_control))
|
||||
return TX_CONTINUE;
|
||||
|
||||
if (tx->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)
|
||||
info->hw_queue = tx->sdata->vif.cab_queue;
|
||||
|
||||
/* no stations in PS mode */
|
||||
if (!atomic_read(&ps->num_sta_ps))
|
||||
return TX_CONTINUE;
|
||||
|
||||
info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM;
|
||||
if (tx->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)
|
||||
info->hw_queue = tx->sdata->vif.cab_queue;
|
||||
|
||||
/* device releases frame after DTIM beacon */
|
||||
if (!(tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING))
|
||||
|
|
|
@ -560,6 +560,9 @@ void ieee80211_iterate_active_interfaces(
|
|||
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
|
||||
continue;
|
||||
break;
|
||||
case NL80211_IFTYPE_AP_VLAN:
|
||||
continue;
|
||||
default:
|
||||
|
@ -598,6 +601,9 @@ void ieee80211_iterate_active_interfaces_atomic(
|
|||
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
|
||||
continue;
|
||||
break;
|
||||
case NL80211_IFTYPE_AP_VLAN:
|
||||
continue;
|
||||
default:
|
||||
|
|
|
@ -2227,6 +2227,7 @@ static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
|
|||
[NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
|
||||
[NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
|
||||
[NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
|
||||
[NL80211_MNTR_FLAG_ACTIVE] = { .type = NLA_FLAG },
|
||||
};
|
||||
|
||||
static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
|
||||
|
@ -2338,6 +2339,10 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
|
|||
change = true;
|
||||
}
|
||||
|
||||
if (flags && (*flags & NL80211_MNTR_FLAG_ACTIVE) &&
|
||||
!(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (change)
|
||||
err = cfg80211_change_iface(rdev, dev, ntype, flags, ¶ms);
|
||||
else
|
||||
|
@ -2395,6 +2400,11 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
|
|||
err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
|
||||
info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
|
||||
&flags);
|
||||
|
||||
if (!err && (flags & NL80211_MNTR_FLAG_ACTIVE) &&
|
||||
!(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
wdev = rdev_add_virtual_intf(rdev,
|
||||
nla_data(info->attrs[NL80211_ATTR_IFNAME]),
|
||||
type, err ? NULL : &flags, ¶ms);
|
||||
|
|
Loading…
Reference in New Issue