Skip to content

Commit

Permalink
Merge tag 'mac80211-next-for-davem-2016-06-09' of git://git.kernel.or…
Browse files Browse the repository at this point in the history
…g/pub/scm/linux/kernel/git/jberg/mac80211-next

Johannes Berg says:

====================
For the next cycle, we have the following:
 * the biggest change is Michał's work on integrating FQ/codel
   with the mac80211 internal software queues
 * cfg80211 connect result gets clarified for the
   "no connection at all" case
 * advertisement of per-interface type capabilities, in case
   they differ (which makes a lot of sense for some capabilities)
 * most of the nl80211 & hwsim unprivileged namespace operation
   changes
 * human-readable VHT capabilities in debugfs
 * some other cleanups, like spelling
====================

Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
davem330 committed Jun 11, 2016
2 parents 52a3d79 + 5caa328 commit d6cf3a8
Show file tree
Hide file tree
Showing 21 changed files with 955 additions and 263 deletions.
1 change: 1 addition & 0 deletions Documentation/DocBook/80211.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
!Finclude/net/cfg80211.h cfg80211_ibss_joined
!Finclude/net/cfg80211.h cfg80211_connect_result
!Finclude/net/cfg80211.h cfg80211_connect_bss
!Finclude/net/cfg80211.h cfg80211_connect_timeout
!Finclude/net/cfg80211.h cfg80211_roamed
!Finclude/net/cfg80211.h cfg80211_disconnected
!Finclude/net/cfg80211.h cfg80211_ready_on_channel
Expand Down
97 changes: 94 additions & 3 deletions drivers/net/wireless/mac80211_hwsim.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#include <linux/module.h>
#include <linux/ktime.h>
#include <net/genetlink.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
#include "mac80211_hwsim.h"

#define WARN_QUEUE 100
Expand Down Expand Up @@ -250,6 +252,28 @@ static inline void hwsim_clear_chanctx_magic(struct ieee80211_chanctx_conf *c)
cp->magic = 0;
}

static unsigned int hwsim_net_id;

static int hwsim_netgroup;

struct hwsim_net {
int netgroup;
};

static inline int hwsim_net_get_netgroup(struct net *net)
{
struct hwsim_net *hwsim_net = net_generic(net, hwsim_net_id);

return hwsim_net->netgroup;
}

static inline void hwsim_net_set_netgroup(struct net *net)
{
struct hwsim_net *hwsim_net = net_generic(net, hwsim_net_id);

hwsim_net->netgroup = hwsim_netgroup++;
}

static struct class *hwsim_class;

static struct net_device *hwsim_mon; /* global monitor netdev */
Expand Down Expand Up @@ -526,6 +550,9 @@ struct mac80211_hwsim_data {
*/
u64 group;

/* group shared by radios created in the same netns */
int netgroup;

int power_level;

/* difference between this hw's clock and the real clock, in usecs */
Expand Down Expand Up @@ -568,6 +595,7 @@ static struct genl_family hwsim_genl_family = {
.name = "MAC80211_HWSIM",
.version = 1,
.maxattr = HWSIM_ATTR_MAX,
.netnsok = true,
};

enum hwsim_multicast_groups {
Expand Down Expand Up @@ -1202,6 +1230,9 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
if (!(data->group & data2->group))
continue;

if (data->netgroup != data2->netgroup)
continue;

if (!hwsim_chans_compat(chan, data2->tmp_chan) &&
!hwsim_chans_compat(chan, data2->channel)) {
ieee80211_iterate_active_interfaces_atomic(
Expand Down Expand Up @@ -2349,6 +2380,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
struct ieee80211_hw *hw;
enum nl80211_band band;
const struct ieee80211_ops *ops = &mac80211_hwsim_ops;
struct net *net;
int idx;

if (WARN_ON(param->channels > 1 && !param->use_chanctx))
Expand All @@ -2366,6 +2398,13 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
err = -ENOMEM;
goto failed;
}

if (info)
net = genl_info_net(info);
else
net = &init_net;
wiphy_net_set(hw->wiphy, net);

data = hw->priv;
data->hw = hw;

Expand Down Expand Up @@ -2541,6 +2580,8 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
data->group = 1;
mutex_init(&data->mutex);

data->netgroup = hwsim_net_get_netgroup(net);

/* Enable frame retransmissions for lossy channels */
hw->max_rates = 4;
hw->max_rate_tries = 11;
Expand Down Expand Up @@ -3014,6 +3055,9 @@ static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info)
continue;
}

if (!net_eq(wiphy_net(data->hw->wiphy), genl_info_net(info)))
continue;

list_del(&data->list);
spin_unlock_bh(&hwsim_radio_lock);
mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy),
Expand All @@ -3040,6 +3084,9 @@ static int hwsim_get_radio_nl(struct sk_buff *msg, struct genl_info *info)
if (data->idx != idx)
continue;

if (!net_eq(wiphy_net(data->hw->wiphy), genl_info_net(info)))
continue;

skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!skb) {
res = -ENOMEM;
Expand Down Expand Up @@ -3079,6 +3126,9 @@ static int hwsim_dump_radio_nl(struct sk_buff *skb,
if (data->idx < idx)
continue;

if (!net_eq(wiphy_net(data->hw->wiphy), sock_net(skb->sk)))
continue;

res = mac80211_hwsim_get_radio(skb, data,
NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, cb,
Expand Down Expand Up @@ -3118,13 +3168,13 @@ static const struct genl_ops hwsim_ops[] = {
.cmd = HWSIM_CMD_NEW_RADIO,
.policy = hwsim_genl_policy,
.doit = hwsim_new_radio_nl,
.flags = GENL_ADMIN_PERM,
.flags = GENL_UNS_ADMIN_PERM,
},
{
.cmd = HWSIM_CMD_DEL_RADIO,
.policy = hwsim_genl_policy,
.doit = hwsim_del_radio_nl,
.flags = GENL_ADMIN_PERM,
.flags = GENL_UNS_ADMIN_PERM,
},
{
.cmd = HWSIM_CMD_GET_RADIO,
Expand Down Expand Up @@ -3206,6 +3256,40 @@ static int hwsim_init_netlink(void)
return -EINVAL;
}

static __net_init int hwsim_init_net(struct net *net)
{
hwsim_net_set_netgroup(net);

return 0;
}

static void __net_exit hwsim_exit_net(struct net *net)
{
struct mac80211_hwsim_data *data, *tmp;

spin_lock_bh(&hwsim_radio_lock);
list_for_each_entry_safe(data, tmp, &hwsim_radios, list) {
if (!net_eq(wiphy_net(data->hw->wiphy), net))
continue;

/* Radios created in init_net are returned to init_net. */
if (data->netgroup == hwsim_net_get_netgroup(&init_net))
continue;

list_del(&data->list);
INIT_WORK(&data->destroy_work, destroy_radio);
schedule_work(&data->destroy_work);
}
spin_unlock_bh(&hwsim_radio_lock);
}

static struct pernet_operations hwsim_net_ops = {
.init = hwsim_init_net,
.exit = hwsim_exit_net,
.id = &hwsim_net_id,
.size = sizeof(struct hwsim_net),
};

static void hwsim_exit_netlink(void)
{
/* unregister the notifier */
Expand Down Expand Up @@ -3242,10 +3326,14 @@ static int __init init_mac80211_hwsim(void)
spin_lock_init(&hwsim_radio_lock);
INIT_LIST_HEAD(&hwsim_radios);

err = platform_driver_register(&mac80211_hwsim_driver);
err = register_pernet_device(&hwsim_net_ops);
if (err)
return err;

err = platform_driver_register(&mac80211_hwsim_driver);
if (err)
goto out_unregister_pernet;

hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim");
if (IS_ERR(hwsim_class)) {
err = PTR_ERR(hwsim_class);
Expand Down Expand Up @@ -3363,6 +3451,8 @@ static int __init init_mac80211_hwsim(void)
mac80211_hwsim_free();
out_unregister_driver:
platform_driver_unregister(&mac80211_hwsim_driver);
out_unregister_pernet:
unregister_pernet_device(&hwsim_net_ops);
return err;
}
module_init(init_mac80211_hwsim);
Expand All @@ -3376,5 +3466,6 @@ static void __exit exit_mac80211_hwsim(void)
mac80211_hwsim_free();
unregister_netdev(hwsim_mon);
platform_driver_unregister(&mac80211_hwsim_driver);
unregister_pernet_device(&hwsim_net_ops);
}
module_exit(exit_mac80211_hwsim);
81 changes: 67 additions & 14 deletions include/net/cfg80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -2367,19 +2367,23 @@ struct cfg80211_qos_map {
* (invoked with the wireless_dev mutex held)
*
* @connect: Connect to the ESS with the specified parameters. When connected,
* call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
* If the connection fails for some reason, call cfg80211_connect_result()
* with the status from the AP. The driver is allowed to roam to other
* BSSes within the ESS when the other BSS matches the connect parameters.
* When such roaming is initiated by the driver, the driver is expected to
* verify that the target matches the configured security parameters and
* to use Reassociation Request frame instead of Association Request frame.
* The connect function can also be used to request the driver to perform
* a specific roam when connected to an ESS. In that case, the prev_bssid
* call cfg80211_connect_result()/cfg80211_connect_bss() with status code
* %WLAN_STATUS_SUCCESS. If the connection fails for some reason, call
* cfg80211_connect_result()/cfg80211_connect_bss() with the status code
* from the AP or cfg80211_connect_timeout() if no frame with status code
* was received.
* The driver is allowed to roam to other BSSes within the ESS when the
* other BSS matches the connect parameters. When such roaming is initiated
* by the driver, the driver is expected to verify that the target matches
* the configured security parameters and to use Reassociation Request
* frame instead of Association Request frame.
* The connect function can also be used to request the driver to perform a
* specific roam when connected to an ESS. In that case, the prev_bssid
* parameter is set to the BSSID of the currently associated BSS as an
* indication of requesting reassociation. In both the driver-initiated and
* new connect() call initiated roaming cases, the result of roaming is
* indicated with a call to cfg80211_roamed() or cfg80211_roamed_bss().
* indication of requesting reassociation.
* In both the driver-initiated and new connect() call initiated roaming
* cases, the result of roaming is indicated with a call to
* cfg80211_roamed() or cfg80211_roamed_bss().
* (invoked with the wireless_dev mutex held)
* @disconnect: Disconnect from the BSS/ESS.
* (invoked with the wireless_dev mutex held)
Expand Down Expand Up @@ -3079,6 +3083,24 @@ struct wiphy_vendor_command {
unsigned long *storage);
};

/**
* struct wiphy_iftype_ext_capab - extended capabilities per interface type
* @iftype: interface type
* @extended_capabilities: extended capabilities supported by the driver,
* additional capabilities might be supported by userspace; these are the
* 802.11 extended capabilities ("Extended Capabilities element") and are
* in the same format as in the information element. See IEEE Std
* 802.11-2012 8.4.2.29 for the defined fields.
* @extended_capabilities_mask: mask of the valid values
* @extended_capabilities_len: length of the extended capabilities
*/
struct wiphy_iftype_ext_capab {
enum nl80211_iftype iftype;
const u8 *extended_capabilities;
const u8 *extended_capabilities_mask;
u8 extended_capabilities_len;
};

/**
* struct wiphy - wireless hardware description
* @reg_notifier: the driver's regulatory notification callback,
Expand Down Expand Up @@ -3199,9 +3221,14 @@ struct wiphy_vendor_command {
* additional capabilities might be supported by userspace; these are
* the 802.11 extended capabilities ("Extended Capabilities element")
* and are in the same format as in the information element. See
* 802.11-2012 8.4.2.29 for the defined fields.
* 802.11-2012 8.4.2.29 for the defined fields. These are the default
* extended capabilities to be used if the capabilities are not specified
* for a specific interface type in iftype_ext_capab.
* @extended_capabilities_mask: mask of the valid values
* @extended_capabilities_len: length of the extended capabilities
* @iftype_ext_capab: array of extended capabilities per interface type
* @num_iftype_ext_capab: number of interface types for which extended
* capabilities are specified separately.
* @coalesce: packet coalescing support information
*
* @vendor_commands: array of vendor commands supported by the hardware
Expand Down Expand Up @@ -3301,6 +3328,9 @@ struct wiphy {
const u8 *extended_capabilities, *extended_capabilities_mask;
u8 extended_capabilities_len;

const struct wiphy_iftype_ext_capab *iftype_ext_capab;
unsigned int num_iftype_ext_capab;

/* If multiple wiphys are registered and you're handed e.g.
* a regular netdev with assigned ieee80211_ptr, you won't
* know whether it points to a wiphy your driver has registered
Expand Down Expand Up @@ -4680,7 +4710,7 @@ static inline void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp)
void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
struct cfg80211_bss *bss, const u8 *req_ie,
size_t req_ie_len, const u8 *resp_ie,
size_t resp_ie_len, u16 status, gfp_t gfp);
size_t resp_ie_len, int status, gfp_t gfp);

/**
* cfg80211_connect_result - notify cfg80211 of connection result
Expand Down Expand Up @@ -4709,6 +4739,29 @@ cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
resp_ie_len, status, gfp);
}

/**
* cfg80211_connect_timeout - notify cfg80211 of connection timeout
*
* @dev: network device
* @bssid: the BSSID of the AP
* @req_ie: association request IEs (maybe be %NULL)
* @req_ie_len: association request IEs length
* @gfp: allocation flags
*
* It should be called by the underlying driver whenever connect() has failed
* in a sequence where no explicit authentication/association rejection was
* received from the AP. This could happen, e.g., due to not being able to send
* out the Authentication or Association Request frame or timing out while
* waiting for the response.
*/
static inline void
cfg80211_connect_timeout(struct net_device *dev, const u8 *bssid,
const u8 *req_ie, size_t req_ie_len, gfp_t gfp)
{
cfg80211_connect_bss(dev, bssid, NULL, req_ie, req_ie_len, NULL, 0, -1,
gfp);
}

/**
* cfg80211_roamed - notify cfg80211 of roaming
*
Expand Down
18 changes: 13 additions & 5 deletions include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <linux/skbuff.h>
#include <linux/ieee80211.h>
#include <net/cfg80211.h>
#include <net/codel.h>
#include <asm/unaligned.h>

/**
Expand Down Expand Up @@ -895,7 +896,18 @@ struct ieee80211_tx_info {
unsigned long jiffies;
};
/* NB: vif can be NULL for injected frames */
struct ieee80211_vif *vif;
union {
/* NB: vif can be NULL for injected frames */
struct ieee80211_vif *vif;

/* When packets are enqueued on txq it's easy
* to re-construct the vif pointer. There's no
* more space in tx_info so it can be used to
* store the necessary enqueue time for packet
* sojourn time computation.
*/
codel_time_t enqueue_time;
};
struct ieee80211_key_conf *hw_key;
u32 flags;
/* 4 bytes free */
Expand Down Expand Up @@ -2147,9 +2159,6 @@ enum ieee80211_hw_flags {
* @n_cipher_schemes: a size of an array of cipher schemes definitions.
* @cipher_schemes: a pointer to an array of cipher scheme definitions
* supported by HW.
*
* @txq_ac_max_pending: maximum number of frames per AC pending in all txq
* entries for a vif.
*/
struct ieee80211_hw {
struct ieee80211_conf conf;
Expand Down Expand Up @@ -2180,7 +2189,6 @@ struct ieee80211_hw {
u8 uapsd_max_sp_len;
u8 n_cipher_schemes;
const struct ieee80211_cipher_scheme *cipher_schemes;
int txq_ac_max_pending;
};

static inline bool _ieee80211_hw_check(struct ieee80211_hw *hw,
Expand Down
Loading

0 comments on commit d6cf3a8

Please sign in to comment.