Commit 60772e48 authored by David S. Miller's avatar David S. Miller

Merge tag 'mac80211-next-for-davem-2018-02-22' of...

Merge tag 'mac80211-next-for-davem-2018-02-22' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next

Johannes Berg says:

====================
Various updates across wireless.

One thing to note: I've included a new ethertype
that wireless uses (ETH_P_PREAUTH) in if_ether.h.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 82e3be32 94ba9271
...@@ -1599,7 +1599,8 @@ static void wil_probe_client_handle(struct wil6210_priv *wil, ...@@ -1599,7 +1599,8 @@ static void wil_probe_client_handle(struct wil6210_priv *wil,
*/ */
bool alive = (sta->status == wil_sta_connected); bool alive = (sta->status == wil_sta_connected);
cfg80211_probe_status(ndev, sta->addr, req->cookie, alive, GFP_KERNEL); cfg80211_probe_status(ndev, sta->addr, req->cookie, alive,
0, false, GFP_KERNEL);
} }
static struct list_head *next_probe_client(struct wil6210_priv *wil) static struct list_head *next_probe_client(struct wil6210_priv *wil)
......
...@@ -493,6 +493,7 @@ static LIST_HEAD(hwsim_radios); ...@@ -493,6 +493,7 @@ static LIST_HEAD(hwsim_radios);
static struct workqueue_struct *hwsim_wq; static struct workqueue_struct *hwsim_wq;
static struct rhashtable hwsim_radios_rht; static struct rhashtable hwsim_radios_rht;
static int hwsim_radio_idx; static int hwsim_radio_idx;
static int hwsim_radios_generation = 1;
static struct platform_driver mac80211_hwsim_driver = { static struct platform_driver mac80211_hwsim_driver = {
.driver = { .driver = {
...@@ -637,6 +638,7 @@ static const struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = { ...@@ -637,6 +638,7 @@ static const struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = {
[HWSIM_ATTR_RADIO_NAME] = { .type = NLA_STRING }, [HWSIM_ATTR_RADIO_NAME] = { .type = NLA_STRING },
[HWSIM_ATTR_NO_VIF] = { .type = NLA_FLAG }, [HWSIM_ATTR_NO_VIF] = { .type = NLA_FLAG },
[HWSIM_ATTR_FREQ] = { .type = NLA_U32 }, [HWSIM_ATTR_FREQ] = { .type = NLA_U32 },
[HWSIM_ATTR_PERM_ADDR] = { .type = NLA_UNSPEC, .len = ETH_ALEN },
}; };
static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
...@@ -2408,6 +2410,7 @@ struct hwsim_new_radio_params { ...@@ -2408,6 +2410,7 @@ struct hwsim_new_radio_params {
bool destroy_on_close; bool destroy_on_close;
const char *hwname; const char *hwname;
bool no_vif; bool no_vif;
const u8 *perm_addr;
}; };
static void hwsim_mcast_config_msg(struct sk_buff *mcast_skb, static void hwsim_mcast_config_msg(struct sk_buff *mcast_skb,
...@@ -2572,15 +2575,25 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, ...@@ -2572,15 +2575,25 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
skb_queue_head_init(&data->pending); skb_queue_head_init(&data->pending);
SET_IEEE80211_DEV(hw, data->dev); SET_IEEE80211_DEV(hw, data->dev);
eth_zero_addr(addr); if (!param->perm_addr) {
addr[0] = 0x02; eth_zero_addr(addr);
addr[3] = idx >> 8; addr[0] = 0x02;
addr[4] = idx; addr[3] = idx >> 8;
memcpy(data->addresses[0].addr, addr, ETH_ALEN); addr[4] = idx;
memcpy(data->addresses[1].addr, addr, ETH_ALEN); memcpy(data->addresses[0].addr, addr, ETH_ALEN);
data->addresses[1].addr[0] |= 0x40; /* Why need here second address ? */
hw->wiphy->n_addresses = 2; data->addresses[1].addr[0] |= 0x40;
hw->wiphy->addresses = data->addresses; memcpy(data->addresses[1].addr, addr, ETH_ALEN);
hw->wiphy->n_addresses = 2;
hw->wiphy->addresses = data->addresses;
/* possible address clash is checked at hash table insertion */
} else {
memcpy(data->addresses[0].addr, param->perm_addr, ETH_ALEN);
/* compatibility with automatically generated mac addr */
memcpy(data->addresses[1].addr, param->perm_addr, ETH_ALEN);
hw->wiphy->n_addresses = 2;
hw->wiphy->addresses = data->addresses;
}
data->channels = param->channels; data->channels = param->channels;
data->use_chanctx = param->use_chanctx; data->use_chanctx = param->use_chanctx;
...@@ -2785,13 +2798,17 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, ...@@ -2785,13 +2798,17 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
err = rhashtable_insert_fast(&hwsim_radios_rht, &data->rht, err = rhashtable_insert_fast(&hwsim_radios_rht, &data->rht,
hwsim_rht_params); hwsim_rht_params);
if (err < 0) { if (err < 0) {
pr_debug("mac80211_hwsim: radio index %d already present\n", if (info) {
idx); GENL_SET_ERR_MSG(info, "perm addr already present");
NL_SET_BAD_ATTR(info->extack,
info->attrs[HWSIM_ATTR_PERM_ADDR]);
}
spin_unlock_bh(&hwsim_radio_lock); spin_unlock_bh(&hwsim_radio_lock);
goto failed_final_insert; goto failed_final_insert;
} }
list_add_tail(&data->list, &hwsim_radios); list_add_tail(&data->list, &hwsim_radios);
hwsim_radios_generation++;
spin_unlock_bh(&hwsim_radio_lock); spin_unlock_bh(&hwsim_radio_lock);
if (idx > 0) if (idx > 0)
...@@ -3210,6 +3227,19 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info) ...@@ -3210,6 +3227,19 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info)
param.regd = hwsim_world_regdom_custom[idx]; param.regd = hwsim_world_regdom_custom[idx];
} }
if (info->attrs[HWSIM_ATTR_PERM_ADDR]) {
if (!is_valid_ether_addr(
nla_data(info->attrs[HWSIM_ATTR_PERM_ADDR]))) {
GENL_SET_ERR_MSG(info,"MAC is no valid source addr");
NL_SET_BAD_ATTR(info->extack,
info->attrs[HWSIM_ATTR_PERM_ADDR]);
return -EINVAL;
}
param.perm_addr = nla_data(info->attrs[HWSIM_ATTR_PERM_ADDR]);
}
ret = mac80211_hwsim_new_radio(info, &param); ret = mac80211_hwsim_new_radio(info, &param);
kfree(hwname); kfree(hwname);
return ret; return ret;
...@@ -3249,6 +3279,7 @@ static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info) ...@@ -3249,6 +3279,7 @@ static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info)
list_del(&data->list); list_del(&data->list);
rhashtable_remove_fast(&hwsim_radios_rht, &data->rht, rhashtable_remove_fast(&hwsim_radios_rht, &data->rht,
hwsim_rht_params); hwsim_rht_params);
hwsim_radios_generation++;
spin_unlock_bh(&hwsim_radio_lock); spin_unlock_bh(&hwsim_radio_lock);
mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy), mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy),
info); info);
...@@ -3305,17 +3336,19 @@ static int hwsim_get_radio_nl(struct sk_buff *msg, struct genl_info *info) ...@@ -3305,17 +3336,19 @@ static int hwsim_get_radio_nl(struct sk_buff *msg, struct genl_info *info)
static int hwsim_dump_radio_nl(struct sk_buff *skb, static int hwsim_dump_radio_nl(struct sk_buff *skb,
struct netlink_callback *cb) struct netlink_callback *cb)
{ {
int idx = cb->args[0]; int last_idx = cb->args[0];
struct mac80211_hwsim_data *data = NULL; struct mac80211_hwsim_data *data = NULL;
int res; int res = 0;
void *hdr;
spin_lock_bh(&hwsim_radio_lock); spin_lock_bh(&hwsim_radio_lock);
cb->seq = hwsim_radios_generation;
if (idx == hwsim_radio_idx) if (last_idx >= hwsim_radio_idx-1)
goto done; goto done;
list_for_each_entry(data, &hwsim_radios, list) { list_for_each_entry(data, &hwsim_radios, list) {
if (data->idx < idx) if (data->idx <= last_idx)
continue; continue;
if (!net_eq(wiphy_net(data->hw->wiphy), sock_net(skb->sk))) if (!net_eq(wiphy_net(data->hw->wiphy), sock_net(skb->sk)))
...@@ -3328,14 +3361,25 @@ static int hwsim_dump_radio_nl(struct sk_buff *skb, ...@@ -3328,14 +3361,25 @@ static int hwsim_dump_radio_nl(struct sk_buff *skb,
if (res < 0) if (res < 0)
break; break;
idx = data->idx + 1; last_idx = data->idx;
} }
cb->args[0] = idx; cb->args[0] = last_idx;
/* list changed, but no new element sent, set interrupted flag */
if (skb->len == 0 && cb->prev_seq && cb->seq != cb->prev_seq) {
hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, &hwsim_genl_family,
NLM_F_MULTI, HWSIM_CMD_GET_RADIO);
if (!hdr)
res = -EMSGSIZE;
genl_dump_check_consistent(cb, hdr);
genlmsg_end(skb, hdr);
}
done: done:
spin_unlock_bh(&hwsim_radio_lock); spin_unlock_bh(&hwsim_radio_lock);
return skb->len; return res ?: skb->len;
} }
/* Generic Netlink operations array */ /* Generic Netlink operations array */
...@@ -3393,6 +3437,7 @@ static void destroy_radio(struct work_struct *work) ...@@ -3393,6 +3437,7 @@ static void destroy_radio(struct work_struct *work)
struct mac80211_hwsim_data *data = struct mac80211_hwsim_data *data =
container_of(work, struct mac80211_hwsim_data, destroy_work); container_of(work, struct mac80211_hwsim_data, destroy_work);
hwsim_radios_generation++;
mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy), NULL); mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy), NULL);
} }
......
...@@ -68,7 +68,12 @@ enum hwsim_tx_control_flags { ...@@ -68,7 +68,12 @@ enum hwsim_tx_control_flags {
* %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE * %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE
* @HWSIM_CMD_NEW_RADIO: create a new radio with the given parameters, * @HWSIM_CMD_NEW_RADIO: create a new radio with the given parameters,
* returns the radio ID (>= 0) or negative on errors, if successful * returns the radio ID (>= 0) or negative on errors, if successful
* then multicast the result * then multicast the result, uses optional parameter:
* %HWSIM_ATTR_REG_STRICT_REG, %HWSIM_ATTR_SUPPORT_P2P_DEVICE,
* %HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE, %HWSIM_ATTR_CHANNELS,
* %HWSIM_ATTR_NO_VIF, %HWSIM_ATTR_RADIO_NAME, %HWSIM_ATTR_USE_CHANCTX,
* %HWSIM_ATTR_REG_HINT_ALPHA2, %HWSIM_ATTR_REG_CUSTOM_REG,
* %HWSIM_ATTR_PERM_ADDR
* @HWSIM_CMD_DEL_RADIO: destroy a radio, reply is multicasted * @HWSIM_CMD_DEL_RADIO: destroy a radio, reply is multicasted
* @HWSIM_CMD_GET_RADIO: fetch information about existing radios, uses: * @HWSIM_CMD_GET_RADIO: fetch information about existing radios, uses:
* %HWSIM_ATTR_RADIO_ID * %HWSIM_ATTR_RADIO_ID
...@@ -126,6 +131,7 @@ enum { ...@@ -126,6 +131,7 @@ enum {
* @HWSIM_ATTR_FREQ: Frequency at which packet is transmitted or received. * @HWSIM_ATTR_FREQ: Frequency at which packet is transmitted or received.
* @HWSIM_ATTR_TX_INFO_FLAGS: additional flags for corresponding * @HWSIM_ATTR_TX_INFO_FLAGS: additional flags for corresponding
* rates of %HWSIM_ATTR_TX_INFO * rates of %HWSIM_ATTR_TX_INFO
* @HWSIM_ATTR_PERM_ADDR: permanent mac address of new radio
* @__HWSIM_ATTR_MAX: enum limit * @__HWSIM_ATTR_MAX: enum limit
*/ */
...@@ -153,6 +159,7 @@ enum { ...@@ -153,6 +159,7 @@ enum {
HWSIM_ATTR_FREQ, HWSIM_ATTR_FREQ,
HWSIM_ATTR_PAD, HWSIM_ATTR_PAD,
HWSIM_ATTR_TX_INFO_FLAGS, HWSIM_ATTR_TX_INFO_FLAGS,
HWSIM_ATTR_PERM_ADDR,
__HWSIM_ATTR_MAX, __HWSIM_ATTR_MAX,
}; };
#define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1) #define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1)
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net> * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
* Copyright (c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright (c) 2013 - 2014 Intel Mobile Communications GmbH
* Copyright (c) 2016 - 2017 Intel Deutschland GmbH * Copyright (c) 2016 - 2017 Intel Deutschland GmbH
* Copyright (c) 2018 Intel Corporation
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -2111,7 +2112,7 @@ enum ieee80211_key_len { ...@@ -2111,7 +2112,7 @@ enum ieee80211_key_len {
#define FILS_ERP_MAX_REALM_LEN 253 #define FILS_ERP_MAX_REALM_LEN 253
#define FILS_ERP_MAX_RRK_LEN 64 #define FILS_ERP_MAX_RRK_LEN 64
#define PMK_MAX_LEN 48 #define PMK_MAX_LEN 64
/* Public action codes (IEEE Std 802.11-2016, 9.6.8.1, Table 9-307) */ /* Public action codes (IEEE Std 802.11-2016, 9.6.8.1, Table 9-307) */
enum ieee80211_pub_actioncode { enum ieee80211_pub_actioncode {
...@@ -2501,6 +2502,17 @@ static inline u8 *ieee80211_get_qos_ctl(struct ieee80211_hdr *hdr) ...@@ -2501,6 +2502,17 @@ static inline u8 *ieee80211_get_qos_ctl(struct ieee80211_hdr *hdr)
return (u8 *)hdr + 24; return (u8 *)hdr + 24;
} }
/**
* ieee80211_get_tid - get qos TID
* @hdr: the frame
*/
static inline u8 ieee80211_get_tid(struct ieee80211_hdr *hdr)
{
u8 *qc = ieee80211_get_qos_ctl(hdr);
return qc[0] & IEEE80211_QOS_CTL_TID_MASK;
}
/** /**
* ieee80211_get_SA - get pointer to SA * ieee80211_get_SA - get pointer to SA
* @hdr: the frame * @hdr: the frame
......
...@@ -1147,6 +1147,7 @@ struct cfg80211_tid_stats { ...@@ -1147,6 +1147,7 @@ struct cfg80211_tid_stats {
* @rx_duration: aggregate PPDU duration(usecs) for all the frames from a peer * @rx_duration: aggregate PPDU duration(usecs) for all the frames from a peer
* @pertid: per-TID statistics, see &struct cfg80211_tid_stats, using the last * @pertid: per-TID statistics, see &struct cfg80211_tid_stats, using the last
* (IEEE80211_NUM_TIDS) index for MSDUs not encapsulated in QoS-MPDUs. * (IEEE80211_NUM_TIDS) index for MSDUs not encapsulated in QoS-MPDUs.
* @ack_signal: signal strength (in dBm) of the last ACK frame.
*/ */
struct station_info { struct station_info {
u64 filled; u64 filled;
...@@ -1191,6 +1192,7 @@ struct station_info { ...@@ -1191,6 +1192,7 @@ struct station_info {
u64 rx_duration; u64 rx_duration;
u8 rx_beacon_signal_avg; u8 rx_beacon_signal_avg;
struct cfg80211_tid_stats pertid[IEEE80211_NUM_TIDS + 1]; struct cfg80211_tid_stats pertid[IEEE80211_NUM_TIDS + 1];
s8 ack_signal;
}; };
#if IS_ENABLED(CONFIG_CFG80211) #if IS_ENABLED(CONFIG_CFG80211)
...@@ -1905,11 +1907,16 @@ struct cfg80211_auth_request { ...@@ -1905,11 +1907,16 @@ struct cfg80211_auth_request {
* @ASSOC_REQ_DISABLE_HT: Disable HT (802.11n) * @ASSOC_REQ_DISABLE_HT: Disable HT (802.11n)
* @ASSOC_REQ_DISABLE_VHT: Disable VHT * @ASSOC_REQ_DISABLE_VHT: Disable VHT
* @ASSOC_REQ_USE_RRM: Declare RRM capability in this association * @ASSOC_REQ_USE_RRM: Declare RRM capability in this association
* @CONNECT_REQ_EXTERNAL_AUTH_SUPPORT: User space indicates external
* authentication capability. Drivers can offload authentication to
* userspace if this flag is set. Only applicable for cfg80211_connect()
* request (connect callback).
*/ */
enum cfg80211_assoc_req_flags { enum cfg80211_assoc_req_flags {
ASSOC_REQ_DISABLE_HT = BIT(0), ASSOC_REQ_DISABLE_HT = BIT(0),
ASSOC_REQ_DISABLE_VHT = BIT(1), ASSOC_REQ_DISABLE_VHT = BIT(1),
ASSOC_REQ_USE_RRM = BIT(2), ASSOC_REQ_USE_RRM = BIT(2),
CONNECT_REQ_EXTERNAL_AUTH_SUPPORT = BIT(3),
}; };
/** /**
...@@ -2600,6 +2607,33 @@ struct cfg80211_pmk_conf { ...@@ -2600,6 +2607,33 @@ struct cfg80211_pmk_conf {
const u8 *pmk_r0_name; const u8 *pmk_r0_name;
}; };
/**
* struct cfg80211_external_auth_params - Trigger External authentication.
*
* Commonly used across the external auth request and event interfaces.
*
* @action: action type / trigger for external authentication. Only significant
* for the authentication request event interface (driver to user space).
* @bssid: BSSID of the peer with which the authentication has
* to happen. Used by both the authentication request event and
* authentication response command interface.
* @ssid: SSID of the AP. Used by both the authentication request event and
* authentication response command interface.
* @key_mgmt_suite: AKM suite of the respective authentication. Used by the
* authentication request event interface.
* @status: status code, %WLAN_STATUS_SUCCESS for successful authentication,
* use %WLAN_STATUS_UNSPECIFIED_FAILURE if user space cannot give you
* the real status code for failures. Used only for the authentication
* response command interface (user space to driver).
*/
struct cfg80211_external_auth_params {
enum nl80211_external_auth_action action;
u8 bssid[ETH_ALEN] __aligned(2);
struct cfg80211_ssid ssid;
unsigned int key_mgmt_suite;
u16 status;
};
/** /**
* struct cfg80211_ops - backend description for wireless configuration * struct cfg80211_ops - backend description for wireless configuration
* *
...@@ -2923,6 +2957,9 @@ struct cfg80211_pmk_conf { ...@@ -2923,6 +2957,9 @@ struct cfg80211_pmk_conf {
* (invoked with the wireless_dev mutex held) * (invoked with the wireless_dev mutex held)
* @del_pmk: delete the previously configured PMK for the given authenticator. * @del_pmk: delete the previously configured PMK for the given authenticator.
* (invoked with the wireless_dev mutex held) * (invoked with the wireless_dev mutex held)
*
* @external_auth: indicates result of offloaded authentication processing from
* user space
*/ */
struct cfg80211_ops { struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
...@@ -3216,6 +3253,8 @@ struct cfg80211_ops { ...@@ -3216,6 +3253,8 @@ struct cfg80211_ops {
const struct cfg80211_pmk_conf *conf); const struct cfg80211_pmk_conf *conf);
int (*del_pmk)(struct wiphy *wiphy, struct net_device *dev, int (*del_pmk)(struct wiphy *wiphy, struct net_device *dev,
const u8 *aa); const u8 *aa);
int (*external_auth)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_external_auth_params *params);
}; };
/* /*
...@@ -3516,6 +3555,35 @@ enum wiphy_vendor_command_flags { ...@@ -3516,6 +3555,35 @@ enum wiphy_vendor_command_flags {
WIPHY_VENDOR_CMD_NEED_RUNNING = BIT(2), WIPHY_VENDOR_CMD_NEED_RUNNING = BIT(2),
}; };
/**
* enum wiphy_opmode_flag - Station's ht/vht operation mode information flags
*
* @STA_OPMODE_MAX_BW_CHANGED: Max Bandwidth changed
* @STA_OPMODE_SMPS_MODE_CHANGED: SMPS mode changed
* @STA_OPMODE_N_SS_CHANGED: max N_SS (number of spatial streams) changed
*
*/
enum wiphy_opmode_flag {
STA_OPMODE_MAX_BW_CHANGED = BIT(0),
STA_OPMODE_SMPS_MODE_CHANGED = BIT(1),
STA_OPMODE_N_SS_CHANGED = BIT(2),
};
/**
* struct sta_opmode_info - Station's ht/vht operation mode information
* @changed: contains value from &enum wiphy_opmode_flag
* @smps_mode: New SMPS mode of a station
* @bw: new max bandwidth value of a station
* @rx_nss: new rx_nss value of a station
*/
struct sta_opmode_info {
u32 changed;
u8 smps_mode;
u8 bw;
u8 rx_nss;
};
/** /**
* struct wiphy_vendor_command - vendor command definition * struct wiphy_vendor_command - vendor command definition
* @info: vendor command identifying information, as used in nl80211 * @info: vendor command identifying information, as used in nl80211
...@@ -5684,6 +5752,20 @@ void cfg80211_cqm_beacon_loss_notify(struct net_device *dev, gfp_t gfp); ...@@ -5684,6 +5752,20 @@ void cfg80211_cqm_beacon_loss_notify(struct net_device *dev, gfp_t gfp);
void cfg80211_radar_event(struct wiphy *wiphy, void cfg80211_radar_event(struct wiphy *wiphy,
struct cfg80211_chan_def *chandef, gfp_t gfp); struct cfg80211_chan_def *chandef, gfp_t gfp);
/**
* cfg80211_sta_opmode_change_notify - STA's ht/vht operation mode change event
* @dev: network device
* @mac: MAC address of a station which opmode got modified
* @sta_opmode: station's current opmode value
* @gfp: context flags
*
* Driver should call this function when station's opmode modified via action
* frame.
*/
void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac,
struct sta_opmode_info *sta_opmode,
gfp_t gfp);
/** /**
* cfg80211_cac_event - Channel availability check (CAC) event * cfg80211_cac_event - Channel availability check (CAC) event
* @netdev: network device * @netdev: network device
...@@ -5758,10 +5840,13 @@ bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev, ...@@ -5758,10 +5840,13 @@ bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
* @addr: the address of the peer * @addr: the address of the peer
* @cookie: the cookie filled in @probe_client previously * @cookie: the cookie filled in @probe_client previously
* @acked: indicates whether probe was acked or not * @acked: indicates whether probe was acked or not
* @ack_signal: signal strength (in dBm) of the ACK frame.
* @is_valid_ack_signal: indicates the ack_signal is valid or not.
* @gfp: allocation flags * @gfp: allocation flags
*/ */
void cfg80211_probe_status(struct net_device *dev, const u8 *addr, void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
u64 cookie, bool acked, gfp_t gfp); u64 cookie, bool acked, s32 ack_signal,
bool is_valid_ack_signal, gfp_t gfp);
/** /**
* cfg80211_report_obss_beacon - report beacon from other APs * cfg80211_report_obss_beacon - report beacon from other APs
...@@ -6202,6 +6287,17 @@ void cfg80211_nan_func_terminated(struct wireless_dev *wdev, ...@@ -6202,6 +6287,17 @@ void cfg80211_nan_func_terminated(struct wireless_dev *wdev,
/* ethtool helper */ /* ethtool helper */
void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info); void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info);
/**
* cfg80211_external_auth_request - userspace request for authentication
* @netdev: network device
* @params: External authentication parameters
* @gfp: allocation flags
* Returns: 0 on success, < 0 on error
*/
int cfg80211_external_auth_request(struct net_device *netdev,
struct cfg80211_external_auth_params *params,
gfp_t gfp);
/* Logging, debugging and troubleshooting/diagnostic helpers. */ /* Logging, debugging and troubleshooting/diagnostic helpers. */
/* wiphy_printk helpers, similar to dev_printk */ /* wiphy_printk helpers, similar to dev_printk */
......
...@@ -149,6 +149,8 @@ enum ieee80211_radiotap_ampdu_flags { ...@@ -149,6 +149,8 @@ enum ieee80211_radiotap_ampdu_flags {
IEEE80211_RADIOTAP_AMPDU_IS_LAST = 0x0008, IEEE80211_RADIOTAP_AMPDU_IS_LAST = 0x0008,
IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR = 0x0010, IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR = 0x0010,
IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN = 0x0020, IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN = 0x0020,
IEEE80211_RADIOTAP_AMPDU_EOF = 0x0040,
IEEE80211_RADIOTAP_AMPDU_EOF_KNOWN = 0x0080,
}; };
/* for IEEE80211_RADIOTAP_VHT */ /* for IEEE80211_RADIOTAP_VHT */
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
* Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net> * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH * Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2015 - 2017 Intel Deutschland GmbH * Copyright (C) 2015 - 2017 Intel Deutschland GmbH
* Copyright (C) 2018 Intel Corporation
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -934,6 +935,7 @@ struct ieee80211_tx_info { ...@@ -934,6 +935,7 @@ struct ieee80211_tx_info {
u8 ampdu_len; u8 ampdu_len;
u8 antenna; u8 antenna;
u16 tx_time; u16 tx_time;
bool is_valid_ack_signal;
void *status_driver_data[19 / sizeof(void *)]; void *status_driver_data[19 / sizeof(void *)];
} status; } status;
struct { struct {
...@@ -1098,6 +1100,9 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) ...@@ -1098,6 +1100,9 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
* the first subframe. * the first subframe.
* @RX_FLAG_ICV_STRIPPED: The ICV is stripped from this frame. CRC checking must * @RX_FLAG_ICV_STRIPPED: The ICV is stripped from this frame. CRC checking must
* be done in the hardware. * be done in the hardware.
* @RX_FLAG_AMPDU_EOF_BIT: Value of the EOF bit in the A-MPDU delimiter for this
* frame
* @RX_FLAG_AMPDU_EOF_BIT_KNOWN: The EOF value is known
*/ */
enum mac80211_rx_flags { enum mac80211_rx_flags {
RX_FLAG_MMIC_ERROR = BIT(0), RX_FLAG_MMIC_ERROR = BIT(0),
...@@ -1124,6 +1129,8 @@ enum mac80211_rx_flags { ...@@ -1124,6 +1129,8 @@ enum mac80211_rx_flags {
RX_FLAG_MIC_STRIPPED = BIT(21), RX_FLAG_MIC_STRIPPED = BIT(21),
RX_FLAG_ALLOW_SAME_PN = BIT(22), RX_FLAG_ALLOW_SAME_PN = BIT(22),
RX_FLAG_ICV_STRIPPED = BIT(23), RX_FLAG_ICV_STRIPPED = BIT(23),
RX_FLAG_AMPDU_EOF_BIT = BIT(24),
RX_FLAG_AMPDU_EOF_BIT_KNOWN = BIT(25),
}; };
/** /**
...@@ -2063,6 +2070,14 @@ struct ieee80211_txq { ...@@ -2063,6 +2070,14 @@ struct ieee80211_txq {
* @IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA: Hardware supports buffer STA on * @IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA: Hardware supports buffer STA on
* TDLS links. * TDLS links.
* *
* @IEEE80211_HW_DEAUTH_NEED_MGD_TX_PREP: The driver requires the
* mgd_prepare_tx() callback to be called before transmission of a
* deauthentication frame in case the association was completed but no
* beacon was heard. This is required in multi-channel scenarios, where the
* virtual interface might not be given air time for the transmission of
* the frame, as it is not synced with the AP/P2P GO yet, and thus the
* deauthentication frame might not be transmitted.
*
* @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
*/ */
enum ieee80211_hw_flags { enum ieee80211_hw_flags {
...@@ -2106,6 +2121,7 @@ enum ieee80211_hw_flags { ...@@ -2106,6 +2121,7 @@ enum ieee80211_hw_flags {
IEEE80211_HW_REPORTS_LOW_ACK, IEEE80211_HW_REPORTS_LOW_ACK,
IEEE80211_HW_SUPPORTS_TX_FRAG, IEEE80211_HW_SUPPORTS_TX_FRAG,
IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA, IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA,
IEEE80211_HW_DEAUTH_NEED_MGD_TX_PREP,
/* keep last, obviously */ /* keep last, obviously */
NUM_IEEE80211_HW_FLAGS NUM_IEEE80211_HW_FLAGS
...@@ -3350,6 +3366,9 @@ enum ieee80211_reconfig_type { ...@@ -3350,6 +3366,9 @@ enum ieee80211_reconfig_type {
* management frame prior to having successfully associated to allow the * management frame prior to having successfully associated to allow the
* driver to give it channel time for the transmission, to get a response * driver to give it channel time for the transmission, to get a response
* and to be able to synchronize with the GO. * and to be able to synchronize with the GO.
* For drivers that set %IEEE80211_HW_DEAUTH_NEED_MGD_TX_PREP, mac80211
* would also call this function before transmitting a deauthentication
* frame in case that no beacon was heard from the AP/P2P GO.
* The callback will be called before each transmission and upon return * The callback will be called before each transmission and upon return
* mac80211 will transmit the frame right away. * mac80211 will transmit the frame right away.
* The callback is optional and can (should!) sleep. * The callback is optional and can (should!) sleep.
......
...@@ -88,6 +88,7 @@ ...@@ -88,6 +88,7 @@
#define ETH_P_AOE 0x88A2 /* ATA over Ethernet */ #define ETH_P_AOE 0x88A2 /* ATA over Ethernet */
#define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */ #define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */
#define ETH_P_802_EX1 0x88B5 /* 802.1 Local Experimental 1. */ #define ETH_P_802_EX1 0x88B5 /* 802.1 Local Experimental 1. */
#define ETH_P_PREAUTH 0x88C7 /* 802.11 Preauthentication */
#define ETH_P_TIPC 0x88CA /* TIPC */ #define ETH_P_TIPC 0x88CA /* TIPC */
#define ETH_P_MACSEC 0x88E5 /* 802.1ae MACsec */ #define ETH_P_MACSEC 0x88E5 /* 802.1ae MACsec */
#define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */ #define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */
......
...@@ -992,6 +992,32 @@ ...@@ -992,6 +992,32 @@
* *
* @NL80211_CMD_RELOAD_REGDB: Request that the regdb firmware file is reloaded. * @NL80211_CMD_RELOAD_REGDB: Request that the regdb firmware file is reloaded.
* *
* @NL80211_CMD_EXTERNAL_AUTH: This interface is exclusively defined for host
* drivers that do not define separate commands for authentication and
* association, but rely on user space for the authentication to happen.
* This interface acts both as the event request (driver to user space)
* to trigger the authentication and command response (userspace to
* driver) to indicate the authentication status.
*
* User space uses the %NL80211_CMD_CONNECT command to the host driver to
* trigger a connection. The host driver selects a BSS and further uses
* this interface to offload only the authentication part to the user
* space. Authentication frames are passed between the driver and user
* space through the %NL80211_CMD_FRAME interface. Host driver proceeds
* further with the association after getting successful authentication
* status. User space indicates the authentication status through
* %NL80211_ATTR_STATUS_CODE attribute in %NL80211_CMD_EXTERNAL_AUTH
* command interface.
*
* Host driver reports this status on an authentication failure to the
* user space through the connect result as the user space would have
* initiated the connection through the connect request.
*
* @NL80211_CMD_STA_OPMODE_CHANGED: An event that notify station's
* ht opmode or vht opmode changes using any of &NL80211_ATTR_SMPS_MODE,
* &NL80211_ATTR_CHANNEL_WIDTH,&NL80211_ATTR_NSS attributes with its
* address(specified in &NL80211_ATTR_MAC).
*
* @NL80211_CMD_MAX: highest used command number * @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use * @__NL80211_CMD_AFTER_LAST: internal use
*/ */
...@@ -1198,6 +1224,10 @@ enum nl80211_commands { ...@@ -1198,6 +1224,10 @@ enum nl80211_commands {
NL80211_CMD_RELOAD_REGDB, NL80211_CMD_RELOAD_REGDB,
NL80211_CMD_EXTERNAL_AUTH,
NL80211_CMD_STA_OPMODE_CHANGED,
/* add new commands above here */ /* add new commands above here */
/* used to define NL80211_CMD_MAX below */ /* used to define NL80211_CMD_MAX below */
...@@ -2153,6 +2183,19 @@ enum nl80211_commands { ...@@ -2153,6 +2183,19 @@ enum nl80211_commands {
* @NL80211_ATTR_PMKR0_NAME: PMK-R0 Name for offloaded FT. * @NL80211_ATTR_PMKR0_NAME: PMK-R0 Name for offloaded FT.
* @NL80211_ATTR_PORT_AUTHORIZED: (reserved) * @NL80211_ATTR_PORT_AUTHORIZED: (reserved)
* *
* @NL80211_ATTR_EXTERNAL_AUTH_ACTION: Identify the requested external
* authentication operation (u32 attribute with an
* &enum nl80211_external_auth_action value). This is used with the
* &NL80211_CMD_EXTERNAL_AUTH request event.
* @NL80211_ATTR_EXTERNAL_AUTH_SUPPORT: Flag attribute indicating that the user
* space supports external authentication. This attribute shall be used
* only with %NL80211_CMD_CONNECT request. The driver may offload
* authentication processing to user space if this capability is indicated
* in NL80211_CMD_CONNECT requests from the user space.
*
* @NL80211_ATTR_NSS: Station's New/updated RX_NSS value notified using this
* u8 attribute. This is used with %NL80211_CMD_STA_OPMODE_CHANGED.
*
* @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined * @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use * @__NL80211_ATTR_AFTER_LAST: internal use
...@@ -2579,6 +2622,12 @@ enum nl80211_attrs { ...@@ -2579,6 +2622,12 @@ enum nl80211_attrs {
NL80211_ATTR_PMKR0_NAME, NL80211_ATTR_PMKR0_NAME,
NL80211_ATTR_PORT_AUTHORIZED, NL80211_ATTR_PORT_AUTHORIZED,
NL80211_ATTR_EXTERNAL_AUTH_ACTION,
NL80211_ATTR_EXTERNAL_AUTH_SUPPORT,
NL80211_ATTR_NSS,
NL80211_ATTR_ACK_SIGNAL,
/* add attributes here, update the policy in nl80211.c */ /* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST, __NL80211_ATTR_AFTER_LAST,
...@@ -2899,6 +2948,7 @@ enum nl80211_sta_bss_param { ...@@ -2899,6 +2948,7 @@ enum nl80211_sta_bss_param {
* @NL80211_STA_INFO_RX_DURATION: aggregate PPDU duration for all frames * @NL80211_STA_INFO_RX_DURATION: aggregate PPDU duration for all frames
* received from the station (u64, usec) * received from the station (u64, usec)
* @NL80211_STA_INFO_PAD: attribute used for padding for 64-bit alignment * @NL80211_STA_INFO_PAD: attribute used for padding for 64-bit alignment
* @NL80211_STA_INFO_ACK_SIGNAL: signal strength of the last ACK frame(u8, dBm)
* @__NL80211_STA_INFO_AFTER_LAST: internal * @__NL80211_STA_INFO_AFTER_LAST: internal
* @NL80211_STA_INFO_MAX: highest possible station info attribute * @NL80211_STA_INFO_MAX: highest possible station info attribute
*/ */
...@@ -2937,6 +2987,7 @@ enum nl80211_sta_info { ...@@ -2937,6 +2987,7 @@ enum nl80211_sta_info {
NL80211_STA_INFO_TID_STATS, NL80211_STA_INFO_TID_STATS,
NL80211_STA_INFO_RX_DURATION, NL80211_STA_INFO_RX_DURATION,
NL80211_STA_INFO_PAD, NL80211_STA_INFO_PAD,
NL80211_STA_INFO_ACK_SIGNAL,
/* keep last */ /* keep last */
__NL80211_STA_INFO_AFTER_LAST, __NL80211_STA_INFO_AFTER_LAST,
...@@ -4945,6 +4996,9 @@ enum nl80211_feature_flags { ...@@ -4945,6 +4996,9 @@ enum nl80211_feature_flags {
* probe request tx deferral and suppression * probe request tx deferral and suppression
* @NL80211_EXT_FEATURE_MFP_OPTIONAL: Driver supports the %NL80211_MFP_OPTIONAL * @NL80211_EXT_FEATURE_MFP_OPTIONAL: Driver supports the %NL80211_MFP_OPTIONAL
* value in %NL80211_ATTR_USE_MFP. * value in %NL80211_ATTR_USE_MFP.
* @NL80211_EXT_FEATURE_LOW_SPAN_SCAN: Driver supports low span scan.
* @NL80211_EXT_FEATURE_LOW_POWER_SCAN: Driver supports low power scan.
* @NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN: Driver supports high accuracy scan.
* *
* @NUM_NL80211_EXT_FEATURES: number of extended features. * @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index. * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
...@@ -4972,6 +5026,9 @@ enum nl80211_ext_feature_index { ...@@ -4972,6 +5026,9 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE, NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE,
NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION, NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION,
NL80211_EXT_FEATURE_MFP_OPTIONAL, NL80211_EXT_FEATURE_MFP_OPTIONAL,
NL80211_EXT_FEATURE_LOW_SPAN_SCAN,
NL80211_EXT_FEATURE_LOW_POWER_SCAN,
NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN,
/* add new features before the definition below */ /* add new features before the definition below */
NUM_NL80211_EXT_FEATURES, NUM_NL80211_EXT_FEATURES,
...@@ -5032,6 +5089,10 @@ enum nl80211_timeout_reason { ...@@ -5032,6 +5089,10 @@ enum nl80211_timeout_reason {
* of NL80211_CMD_TRIGGER_SCAN and NL80211_CMD_START_SCHED_SCAN * of NL80211_CMD_TRIGGER_SCAN and NL80211_CMD_START_SCHED_SCAN
* requests. * requests.
* *
* NL80211_SCAN_FLAG_LOW_SPAN, NL80211_SCAN_FLAG_LOW_POWER, and
* NL80211_SCAN_FLAG_HIGH_ACCURACY flags are exclusive of each other, i.e., only
* one of them can be used in the request.
*
* @NL80211_SCAN_FLAG_LOW_PRIORITY: scan request has low priority * @NL80211_SCAN_FLAG_LOW_PRIORITY: scan request has low priority
* @NL80211_SCAN_FLAG_FLUSH: flush cache before scanning * @NL80211_SCAN_FLAG_FLUSH: flush cache before scanning
* @NL80211_SCAN_FLAG_AP: force a scan even if the interface is configured * @NL80211_SCAN_FLAG_AP: force a scan even if the interface is configured
...@@ -5059,7 +5120,20 @@ enum nl80211_timeout_reason { ...@@ -5059,7 +5120,20 @@ enum nl80211_timeout_reason {
* and suppression (if it has received a broadcast Probe Response frame, * and suppression (if it has received a broadcast Probe Response frame,
* Beacon frame or FILS Discovery frame from an AP that the STA considers * Beacon frame or FILS Discovery frame from an AP that the STA considers
* a suitable candidate for (re-)association - suitable in terms of * a suitable candidate for (re-)association - suitable in terms of
* SSID and/or RSSI * SSID and/or RSSI.
* @NL80211_SCAN_FLAG_LOW_SPAN: Span corresponds to the total time taken to
* accomplish the scan. Thus, this flag intends the driver to perform the
* scan request with lesser span/duration. It is specific to the driver
* implementations on how this is accomplished. Scan accuracy may get
* impacted with this flag.
* @NL80211_SCAN_FLAG_LOW_POWER: This flag intends the scan attempts to consume
* optimal possible power. Drivers can resort to their specific means to
* optimize the power. Scan accuracy may get impacted with this flag.
* @NL80211_SCAN_FLAG_HIGH_ACCURACY: Accuracy here intends to the extent of scan
* results obtained. Thus HIGH_ACCURACY scan flag aims to get maximum
* possible scan results. This flag hints the driver to use the best
* possible scan configuration to improve the accuracy in scanning.
* Latency and power use may get impacted with this flag.
*/ */
enum nl80211_scan_flags { enum nl80211_scan_flags {
NL80211_SCAN_FLAG_LOW_PRIORITY = 1<<0, NL80211_SCAN_FLAG_LOW_PRIORITY = 1<<0,
...@@ -5070,6 +5144,9 @@ enum nl80211_scan_flags { ...@@ -5070,6 +5144,9 @@ enum nl80211_scan_flags {
NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP = 1<<5, NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP = 1<<5,
NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE = 1<<6, NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE = 1<<6,
NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION = 1<<7, NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION = 1<<7,
NL80211_SCAN_FLAG_LOW_SPAN = 1<<8,
NL80211_SCAN_FLAG_LOW_POWER = 1<<9,
NL80211_SCAN_FLAG_HIGH_ACCURACY = 1<<10,
}; };
/** /**
...@@ -5469,4 +5546,15 @@ enum nl80211_nan_match_attributes { ...@@ -5469,4 +5546,15 @@ enum nl80211_nan_match_attributes {
NL80211_NAN_MATCH_ATTR_MAX = NUM_NL80211_NAN_MATCH_ATTR - 1 NL80211_NAN_MATCH_ATTR_MAX = NUM_NL80211_NAN_MATCH_ATTR - 1
}; };
/**
* nl80211_external_auth_action - Action to perform with external
* authentication request. Used by NL80211_ATTR_EXTERNAL_AUTH_ACTION.
* @NL80211_EXTERNAL_AUTH_START: Start the authentication.
* @NL80211_EXTERNAL_AUTH_ABORT: Abort the ongoing authentication.
*/
enum nl80211_external_auth_action {
NL80211_EXTERNAL_AUTH_START,
NL80211_EXTERNAL_AUTH_ABORT,
};
#endif /* __LINUX_NL80211_H */ #endif /* __LINUX_NL80211_H */
...@@ -212,6 +212,7 @@ static const char *hw_flag_names[] = { ...@@ -212,6 +212,7 @@ static const char *hw_flag_names[] = {
FLAG(REPORTS_LOW_ACK), FLAG(REPORTS_LOW_ACK),
FLAG(SUPPORTS_TX_FRAG), FLAG(SUPPORTS_TX_FRAG),
FLAG(SUPPORTS_TDLS_BUFFER_STA), FLAG(SUPPORTS_TDLS_BUFFER_STA),
FLAG(DEAUTH_NEED_MGD_TX_PREP),
#undef FLAG #undef FLAG
}; };
......
...@@ -160,12 +160,12 @@ static ssize_t sta_aqm_read(struct file *file, char __user *userbuf, ...@@ -160,12 +160,12 @@ static ssize_t sta_aqm_read(struct file *file, char __user *userbuf,
sta->cparams.ecn ? "yes" : "no"); sta->cparams.ecn ? "yes" : "no");
p += scnprintf(p, p += scnprintf(p,
bufsz+buf-p, bufsz+buf-p,
"tid ac backlog-bytes backlog-packets new-flows drops marks overlimit collisions tx-bytes tx-packets\n"); "tid ac backlog-bytes backlog-packets new-flows drops marks overlimit collisions tx-bytes tx-packets flags\n");
for (i = 0; i < IEEE80211_NUM_TIDS; i++) { for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
txqi = to_txq_info(sta->sta.txq[i]); txqi = to_txq_info(sta->sta.txq[i]);
p += scnprintf(p, bufsz+buf-p, p += scnprintf(p, bufsz+buf-p,
"%d %d %u %u %u %u %u %u %u %u %u\n", "%d %d %u %u %u %u %u %u %u %u %u 0x%lx(%s%s%s)\n",
txqi->txq.tid, txqi->txq.tid,
txqi->txq.ac, txqi->txq.ac,
txqi->tin.backlog_bytes, txqi->tin.backlog_bytes,
...@@ -176,7 +176,11 @@ static ssize_t sta_aqm_read(struct file *file, char __user *userbuf, ...@@ -176,7 +176,11 @@ static ssize_t sta_aqm_read(struct file *file, char __user *userbuf,
txqi->tin.overlimit, txqi->tin.overlimit,
txqi->tin.collisions, txqi->tin.collisions,
txqi->tin.tx_bytes, txqi->tin.tx_bytes,
txqi->tin.tx_packets); txqi->tin.tx_packets,
txqi->flags,
txqi->flags & (1<<IEEE80211_TXQ_STOP) ? "STOP" : "RUN",
txqi->flags & (1<<IEEE80211_TXQ_AMPDU) ? " AMPDU" : "",
txqi->flags & (1<<IEEE80211_TXQ_NO_AMSDU) ? " NO-AMSDU" : "");
} }
rcu_read_unlock(); rcu_read_unlock();
......
...@@ -1324,8 +1324,7 @@ static void ieee80211_iface_work(struct work_struct *work) ...@@ -1324,8 +1324,7 @@ static void ieee80211_iface_work(struct work_struct *work)
mutex_lock(&local->sta_mtx); mutex_lock(&local->sta_mtx);
sta = sta_info_get_bss(sdata, mgmt->sa); sta = sta_info_get_bss(sdata, mgmt->sa);
if (sta) { if (sta) {
u16 tid = *ieee80211_get_qos_ctl(hdr) & u16 tid = ieee80211_get_tid(hdr);
IEEE80211_QOS_CTL_TID_MASK;
__ieee80211_stop_rx_ba_session( __ieee80211_stop_rx_ba_session(
sta, tid, WLAN_BACK_RECIPIENT, sta, tid, WLAN_BACK_RECIPIENT,
......
...@@ -35,7 +35,7 @@ static void michael_mic_hdr(struct michael_mic_ctx *mctx, const u8 *key, ...@@ -35,7 +35,7 @@ static void michael_mic_hdr(struct michael_mic_ctx *mctx, const u8 *key,
da = ieee80211_get_DA(hdr); da = ieee80211_get_DA(hdr);
sa = ieee80211_get_SA(hdr); sa = ieee80211_get_SA(hdr);
if (ieee80211_is_data_qos(hdr->frame_control)) if (ieee80211_is_data_qos(hdr->frame_control))
tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; tid = ieee80211_get_tid(hdr);
else else
tid = 0; tid = 0;
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* Copyright 2007, Michael Wu <flamingice@sourmilk.net> * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH * Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2015 - 2017 Intel Deutschland GmbH * Copyright (C) 2015 - 2017 Intel Deutschland GmbH
* Copyright (C) 2018 Intel Corporation
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -2008,9 +2009,22 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, ...@@ -2008,9 +2009,22 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
ieee80211_flush_queues(local, sdata, true); ieee80211_flush_queues(local, sdata, true);
/* deauthenticate/disassociate now */ /* deauthenticate/disassociate now */
if (tx || frame_buf) if (tx || frame_buf) {
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
/*
* In multi channel scenarios guarantee that the virtual
* interface is granted immediate airtime to transmit the
* deauthentication frame by calling mgd_prepare_tx, if the
* driver requested so.
*/
if (ieee80211_hw_check(&local->hw, DEAUTH_NEED_MGD_TX_PREP) &&
!ifmgd->have_beacon)
drv_mgd_prepare_tx(sdata->local, sdata);
ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype, ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype,
reason, tx, frame_buf); reason, tx, frame_buf);
}
/* flush out frame - make sure the deauth was actually sent */ /* flush out frame - make sure the deauth was actually sent */
if (tx) if (tx)
...@@ -2151,7 +2165,7 @@ static void ieee80211_sta_tx_wmm_ac_notify(struct ieee80211_sub_if_data *sdata, ...@@ -2151,7 +2165,7 @@ static void ieee80211_sta_tx_wmm_ac_notify(struct ieee80211_sub_if_data *sdata,
u16 tx_time) u16 tx_time)
{ {
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
u16 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; u16 tid = ieee80211_get_tid(hdr);
int ac = ieee80211_ac_from_tid(tid); int ac = ieee80211_ac_from_tid(tid);
struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac]; struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac];
unsigned long now = jiffies; unsigned long now = jiffies;
......
...@@ -669,7 +669,7 @@ minstrel_aggr_check(struct ieee80211_sta *pubsta, struct sk_buff *skb) ...@@ -669,7 +669,7 @@ minstrel_aggr_check(struct ieee80211_sta *pubsta, struct sk_buff *skb)
if (unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE))) if (unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE)))
return; return;
tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; tid = ieee80211_get_tid(hdr);
if (likely(sta->ampdu_mlme.tid_tx[tid])) if (likely(sta->ampdu_mlme.tid_tx[tid]))
return; return;
......
...@@ -439,6 +439,10 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, ...@@ -439,6 +439,10 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR; flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR;
if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN) if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN)
flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN; flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN;
if (status->flag & RX_FLAG_AMPDU_EOF_BIT_KNOWN)
flags |= IEEE80211_RADIOTAP_AMPDU_EOF_KNOWN;
if (status->flag & RX_FLAG_AMPDU_EOF_BIT)
flags |= IEEE80211_RADIOTAP_AMPDU_EOF;
put_unaligned_le16(flags, pos); put_unaligned_le16(flags, pos);
pos += 2; pos += 2;
if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN) if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN)
...@@ -1185,7 +1189,7 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx, ...@@ -1185,7 +1189,7 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
ack_policy = *ieee80211_get_qos_ctl(hdr) & ack_policy = *ieee80211_get_qos_ctl(hdr) &
IEEE80211_QOS_CTL_ACK_POLICY_MASK; IEEE80211_QOS_CTL_ACK_POLICY_MASK;
tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; tid = ieee80211_get_tid(hdr);
tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]); tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]);
if (!tid_agg_rx) { if (!tid_agg_rx) {
...@@ -1524,9 +1528,7 @@ ieee80211_rx_h_uapsd_and_pspoll(struct ieee80211_rx_data *rx) ...@@ -1524,9 +1528,7 @@ ieee80211_rx_h_uapsd_and_pspoll(struct ieee80211_rx_data *rx)
ieee80211_has_pm(hdr->frame_control) && ieee80211_has_pm(hdr->frame_control) &&
(ieee80211_is_data_qos(hdr->frame_control) || (ieee80211_is_data_qos(hdr->frame_control) ||
ieee80211_is_qos_nullfunc(hdr->frame_control))) { ieee80211_is_qos_nullfunc(hdr->frame_control))) {
u8 tid; u8 tid = ieee80211_get_tid(hdr);
tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
ieee80211_sta_uapsd_trigger(&rx->sta->sta, tid); ieee80211_sta_uapsd_trigger(&rx->sta->sta, tid);
} }
...@@ -2848,6 +2850,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) ...@@ -2848,6 +2850,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
case WLAN_HT_ACTION_SMPS: { case WLAN_HT_ACTION_SMPS: {
struct ieee80211_supported_band *sband; struct ieee80211_supported_band *sband;
enum ieee80211_smps_mode smps_mode; enum ieee80211_smps_mode smps_mode;
struct sta_opmode_info sta_opmode = {};
/* convert to HT capability */ /* convert to HT capability */
switch (mgmt->u.action.u.ht_smps.smps_control) { switch (mgmt->u.action.u.ht_smps.smps_control) {
...@@ -2868,17 +2871,24 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) ...@@ -2868,17 +2871,24 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
if (rx->sta->sta.smps_mode == smps_mode) if (rx->sta->sta.smps_mode == smps_mode)
goto handled; goto handled;
rx->sta->sta.smps_mode = smps_mode; rx->sta->sta.smps_mode = smps_mode;
sta_opmode.smps_mode = smps_mode;
sta_opmode.changed = STA_OPMODE_SMPS_MODE_CHANGED;
sband = rx->local->hw.wiphy->bands[status->band]; sband = rx->local->hw.wiphy->bands[status->band];
rate_control_rate_update(local, sband, rx->sta, rate_control_rate_update(local, sband, rx->sta,
IEEE80211_RC_SMPS_CHANGED); IEEE80211_RC_SMPS_CHANGED);
cfg80211_sta_opmode_change_notify(sdata->dev,
rx->sta->addr,
&sta_opmode,
GFP_KERNEL);
goto handled; goto handled;
} }
case WLAN_HT_ACTION_NOTIFY_CHANWIDTH: { case WLAN_HT_ACTION_NOTIFY_CHANWIDTH: {
struct ieee80211_supported_band *sband; struct ieee80211_supported_band *sband;
u8 chanwidth = mgmt->u.action.u.ht_notify_cw.chanwidth; u8 chanwidth = mgmt->u.action.u.ht_notify_cw.chanwidth;
enum ieee80211_sta_rx_bandwidth max_bw, new_bw; enum ieee80211_sta_rx_bandwidth max_bw, new_bw;
struct sta_opmode_info sta_opmode = {};
/* If it doesn't support 40 MHz it can't change ... */ /* If it doesn't support 40 MHz it can't change ... */
if (!(rx->sta->sta.ht_cap.cap & if (!(rx->sta->sta.ht_cap.cap &
...@@ -2899,9 +2909,15 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) ...@@ -2899,9 +2909,15 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
rx->sta->sta.bandwidth = new_bw; rx->sta->sta.bandwidth = new_bw;
sband = rx->local->hw.wiphy->bands[status->band]; sband = rx->local->hw.wiphy->bands[status->band];
sta_opmode.bw = new_bw;
sta_opmode.changed = STA_OPMODE_MAX_BW_CHANGED;
rate_control_rate_update(local, sband, rx->sta, rate_control_rate_update(local, sband, rx->sta,
IEEE80211_RC_BW_CHANGED); IEEE80211_RC_BW_CHANGED);
cfg80211_sta_opmode_change_notify(sdata->dev,
rx->sta->addr,
&sta_opmode,
GFP_KERNEL);
goto handled; goto handled;
} }
default: default:
......
...@@ -2287,6 +2287,12 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) ...@@ -2287,6 +2287,12 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
sinfo->filled |= BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT); sinfo->filled |= BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT);
sinfo->expected_throughput = thr; sinfo->expected_throughput = thr;
} }
if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL)) &&
sta->status_stats.ack_signal_filled) {
sinfo->ack_signal = sta->status_stats.last_ack_signal;
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL);
}
} }
u32 sta_get_expected_throughput(struct sta_info *sta) u32 sta_get_expected_throughput(struct sta_info *sta)
......
...@@ -548,6 +548,8 @@ struct sta_info { ...@@ -548,6 +548,8 @@ struct sta_info {
u64 msdu_retries[IEEE80211_NUM_TIDS + 1]; u64 msdu_retries[IEEE80211_NUM_TIDS + 1];
u64 msdu_failed[IEEE80211_NUM_TIDS + 1]; u64 msdu_failed[IEEE80211_NUM_TIDS + 1];
unsigned long last_ack; unsigned long last_ack;
s8 last_ack_signal;
bool ack_signal_filled;
} status_stats; } status_stats;
/* Updated from TX path only, no locking requirements */ /* Updated from TX path only, no locking requirements */
......
...@@ -187,9 +187,16 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb) ...@@ -187,9 +187,16 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb)
struct ieee80211_mgmt *mgmt = (void *) skb->data; struct ieee80211_mgmt *mgmt = (void *) skb->data;
struct ieee80211_local *local = sta->local; struct ieee80211_local *local = sta->local;
struct ieee80211_sub_if_data *sdata = sta->sdata; struct ieee80211_sub_if_data *sdata = sta->sdata;
struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) {
sta->status_stats.last_ack = jiffies; sta->status_stats.last_ack = jiffies;
if (txinfo->status.is_valid_ack_signal) {
sta->status_stats.last_ack_signal =
(s8)txinfo->status.ack_signal;
sta->status_stats.ack_signal_filled = true;
}
}
if (ieee80211_is_data_qos(mgmt->frame_control)) { if (ieee80211_is_data_qos(mgmt->frame_control)) {
struct ieee80211_hdr *hdr = (void *) skb->data; struct ieee80211_hdr *hdr = (void *) skb->data;
...@@ -487,6 +494,8 @@ static void ieee80211_report_ack_skb(struct ieee80211_local *local, ...@@ -487,6 +494,8 @@ static void ieee80211_report_ack_skb(struct ieee80211_local *local,
ieee80211_is_qos_nullfunc(hdr->frame_control)) ieee80211_is_qos_nullfunc(hdr->frame_control))
cfg80211_probe_status(sdata->dev, hdr->addr1, cfg80211_probe_status(sdata->dev, hdr->addr1,
cookie, acked, cookie, acked,
info->status.ack_signal,
info->status.is_valid_ack_signal,
GFP_ATOMIC); GFP_ATOMIC);
else else
cfg80211_mgmt_tx_status(&sdata->wdev, cookie, cfg80211_mgmt_tx_status(&sdata->wdev, cookie,
......
...@@ -797,7 +797,6 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) ...@@ -797,7 +797,6 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
{ {
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
u8 *qc;
int tid; int tid;
/* /*
...@@ -844,9 +843,7 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) ...@@ -844,9 +843,7 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
return TX_CONTINUE; return TX_CONTINUE;
/* include per-STA, per-TID sequence counter */ /* include per-STA, per-TID sequence counter */
tid = ieee80211_get_tid(hdr);
qc = ieee80211_get_qos_ctl(hdr);
tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
tx->sta->tx_stats.msdu[tid]++; tx->sta->tx_stats.msdu[tid]++;
hdr->seq_ctrl = ieee80211_tx_next_seq(tx->sta, tid); hdr->seq_ctrl = ieee80211_tx_next_seq(tx->sta, tid);
...@@ -1158,7 +1155,6 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, ...@@ -1158,7 +1155,6 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
struct ieee80211_hdr *hdr; struct ieee80211_hdr *hdr;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
int tid; int tid;
u8 *qc;
memset(tx, 0, sizeof(*tx)); memset(tx, 0, sizeof(*tx));
tx->skb = skb; tx->skb = skb;
...@@ -1198,8 +1194,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, ...@@ -1198,8 +1194,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
!ieee80211_hw_check(&local->hw, TX_AMPDU_SETUP_IN_HW)) { !ieee80211_hw_check(&local->hw, TX_AMPDU_SETUP_IN_HW)) {
struct tid_ampdu_tx *tid_tx; struct tid_ampdu_tx *tid_tx;
qc = ieee80211_get_qos_ctl(hdr); tid = ieee80211_get_tid(hdr);
tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
tid_tx = rcu_dereference(tx->sta->ampdu_mlme.tid_tx[tid]); tid_tx = rcu_dereference(tx->sta->ampdu_mlme.tid_tx[tid]);
if (tid_tx) { if (tid_tx) {
...@@ -1921,7 +1916,7 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, ...@@ -1921,7 +1916,7 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
{ {
struct ieee80211_local *local = sdata->local; struct ieee80211_local *local = sdata->local;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; struct ieee80211_hdr *hdr;
int headroom; int headroom;
bool may_encrypt; bool may_encrypt;
......
...@@ -447,6 +447,7 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, ...@@ -447,6 +447,7 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
enum nl80211_band band) enum nl80211_band band)
{ {
enum ieee80211_sta_rx_bandwidth new_bw; enum ieee80211_sta_rx_bandwidth new_bw;
struct sta_opmode_info sta_opmode = {};
u32 changed = 0; u32 changed = 0;
u8 nss; u8 nss;
...@@ -460,7 +461,9 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, ...@@ -460,7 +461,9 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
if (sta->sta.rx_nss != nss) { if (sta->sta.rx_nss != nss) {
sta->sta.rx_nss = nss; sta->sta.rx_nss = nss;
sta_opmode.rx_nss = nss;
changed |= IEEE80211_RC_NSS_CHANGED; changed |= IEEE80211_RC_NSS_CHANGED;
sta_opmode.changed |= STA_OPMODE_N_SS_CHANGED;
} }
switch (opmode & IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK) { switch (opmode & IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK) {
...@@ -481,9 +484,15 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, ...@@ -481,9 +484,15 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
new_bw = ieee80211_sta_cur_vht_bw(sta); new_bw = ieee80211_sta_cur_vht_bw(sta);
if (new_bw != sta->sta.bandwidth) { if (new_bw != sta->sta.bandwidth) {
sta->sta.bandwidth = new_bw; sta->sta.bandwidth = new_bw;
sta_opmode.bw = new_bw;
changed |= IEEE80211_RC_BW_CHANGED; changed |= IEEE80211_RC_BW_CHANGED;
sta_opmode.changed |= STA_OPMODE_MAX_BW_CHANGED;
} }
if (sta_opmode.changed)
cfg80211_sta_opmode_change_notify(sdata->dev, sta->addr,
&sta_opmode, GFP_KERNEL);
return changed; return changed;
} }
......
...@@ -340,7 +340,7 @@ static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad) ...@@ -340,7 +340,7 @@ static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad)
a4_included = ieee80211_has_a4(hdr->frame_control); a4_included = ieee80211_has_a4(hdr->frame_control);
if (ieee80211_is_data_qos(hdr->frame_control)) if (ieee80211_is_data_qos(hdr->frame_control))
qos_tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; qos_tid = ieee80211_get_tid(hdr);
else else
qos_tid = 0; qos_tid = 0;
...@@ -601,8 +601,7 @@ static void gcmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *j_0, u8 *aad) ...@@ -601,8 +601,7 @@ static void gcmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *j_0, u8 *aad)
aad[23] = 0; aad[23] = 0;
if (ieee80211_is_data_qos(hdr->frame_control)) if (ieee80211_is_data_qos(hdr->frame_control))
qos_tid = *ieee80211_get_qos_ctl(hdr) & qos_tid = ieee80211_get_tid(hdr);
IEEE80211_QOS_CTL_TID_MASK;
else else
qos_tid = 0; qos_tid = 0;
...@@ -867,8 +866,7 @@ ieee80211_crypto_cs_decrypt(struct ieee80211_rx_data *rx) ...@@ -867,8 +866,7 @@ ieee80211_crypto_cs_decrypt(struct ieee80211_rx_data *rx)
return RX_DROP_UNUSABLE; return RX_DROP_UNUSABLE;
if (ieee80211_is_data_qos(hdr->frame_control)) if (ieee80211_is_data_qos(hdr->frame_control))
qos_tid = *ieee80211_get_qos_ctl(hdr) & qos_tid = ieee80211_get_tid(hdr);
IEEE80211_QOS_CTL_TID_MASK;
else else
qos_tid = 0; qos_tid = 0;
......
This diff is collapsed.
...@@ -1190,4 +1190,19 @@ static inline int rdev_del_pmk(struct cfg80211_registered_device *rdev, ...@@ -1190,4 +1190,19 @@ static inline int rdev_del_pmk(struct cfg80211_registered_device *rdev,
trace_rdev_return_int(&rdev->wiphy, ret); trace_rdev_return_int(&rdev->wiphy, ret);
return ret; return ret;
} }
static inline int
rdev_external_auth(struct cfg80211_registered_device *rdev,
struct net_device *dev,
struct cfg80211_external_auth_params *params)
{
int ret = -EOPNOTSUPP;
trace_rdev_external_auth(&rdev->wiphy, dev, params);
if (rdev->ops->external_auth)
ret = rdev->ops->external_auth(&rdev->wiphy, dev, params);
trace_rdev_return_int(&rdev->wiphy, ret);
return ret;
}
#endif /* __CFG80211_RDEV_OPS */ #endif /* __CFG80211_RDEV_OPS */
...@@ -2319,6 +2319,29 @@ TRACE_EVENT(rdev_del_pmk, ...@@ -2319,6 +2319,29 @@ TRACE_EVENT(rdev_del_pmk,
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(aa)) WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(aa))
); );
TRACE_EVENT(rdev_external_auth,
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
struct cfg80211_external_auth_params *params),
TP_ARGS(wiphy, netdev, params),
TP_STRUCT__entry(WIPHY_ENTRY
NETDEV_ENTRY
MAC_ENTRY(bssid)
__array(u8, ssid, IEEE80211_MAX_SSID_LEN + 1)
__field(u16, status)
),
TP_fast_assign(WIPHY_ASSIGN;
NETDEV_ASSIGN;
MAC_ASSIGN(bssid, params->bssid);
memset(__entry->ssid, 0, IEEE80211_MAX_SSID_LEN + 1);
memcpy(__entry->ssid, params->ssid.ssid,
params->ssid.ssid_len);
__entry->status = params->status;
),
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT
", ssid: %s, status: %u", WIPHY_PR_ARG, NETDEV_PR_ARG,
__entry->bssid, __entry->ssid, __entry->status)
);
/************************************************************* /*************************************************************
* cfg80211 exported functions traces * * cfg80211 exported functions traces *
*************************************************************/ *************************************************************/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment