Various updates across wireless.
One thing to note: I've included a new ethertype that wireless uses (ETH_P_PREAUTH) in if_ether.h. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEH1e1rEeCd0AIMq6MB8qZga/fl8QFAlqPJKcACgkQB8qZga/f l8TAUw/7BMKG4ofFYRgujmqS+mnSDJx9vgtFHIV3Ymcm9vgdQ6wbNe85ME8J6TpN Z/HqtWVhn7BEWqpiDgq0ADTEmU/Vt6AQvy6fJX80+Lz4yup8Dq9dI9/CJ7BlKP+t O7/jXkv2RykFv1IAG9US3Xx9rIwLJRP6XndksZMsK4QihdUYOqAqjZ+pLWCHQ7+a vFewlUV6t7IMq3R9scL4nf5EmgLWNDNCSOZ6xWDxfDgLHsErbCD9ojRsfAnQWPN0 1rwPC5kGm9tzGtiPVhA0/a4D0dgiYdv723ubs/waSYX5fimXDPSXsRizVp06ZWC+ lFW+Mw52WvxriO61MD99xH1O1/svy+YMMgECoPMjGk7QzgY+2xQ/8hUbo91fsj07 05+rGX3O0SJvB0une3m3ZsZz00DkZDU4Fw0kvO0aSCmE++O4vt/04wmMWxGVfnSo RtdrQNSAYrYqHSc+1kIzDAH2jCBBLj0cWdlZPYciYMTRUHOFZmMApyyXVLoOl3yn eqLgK8QBNpkjkf5FbF+m0ccHtQ8lkKiZDcqqIVN+dxKuuO9FEfblDty5bZEp8AaT Q2soararYeUcNVA2A+Gi1l3qtcj+wWay+CdDcU/QmYbXoxdRh64FBs//y6akIH9p p/cNgRP/MyEUEkvGmpva+MdtzCToWR4Asm4eErlsvvbIvKEFjPI= =A6XK -----END PGP SIGNATURE----- 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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
60772e48ec
|
@ -1599,7 +1599,8 @@ static void wil_probe_client_handle(struct wil6210_priv *wil,
|
|||
*/
|
||||
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)
|
||||
|
|
|
@ -493,6 +493,7 @@ static LIST_HEAD(hwsim_radios);
|
|||
static struct workqueue_struct *hwsim_wq;
|
||||
static struct rhashtable hwsim_radios_rht;
|
||||
static int hwsim_radio_idx;
|
||||
static int hwsim_radios_generation = 1;
|
||||
|
||||
static struct platform_driver mac80211_hwsim_driver = {
|
||||
.driver = {
|
||||
|
@ -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_NO_VIF] = { .type = NLA_FLAG },
|
||||
[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,
|
||||
|
@ -2408,6 +2410,7 @@ struct hwsim_new_radio_params {
|
|||
bool destroy_on_close;
|
||||
const char *hwname;
|
||||
bool no_vif;
|
||||
const u8 *perm_addr;
|
||||
};
|
||||
|
||||
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,
|
|||
skb_queue_head_init(&data->pending);
|
||||
|
||||
SET_IEEE80211_DEV(hw, data->dev);
|
||||
if (!param->perm_addr) {
|
||||
eth_zero_addr(addr);
|
||||
addr[0] = 0x02;
|
||||
addr[3] = idx >> 8;
|
||||
addr[4] = idx;
|
||||
memcpy(data->addresses[0].addr, addr, ETH_ALEN);
|
||||
memcpy(data->addresses[1].addr, addr, ETH_ALEN);
|
||||
/* Why need here second address ? */
|
||||
data->addresses[1].addr[0] |= 0x40;
|
||||
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->use_chanctx = param->use_chanctx;
|
||||
|
@ -2785,13 +2798,17 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
|
|||
err = rhashtable_insert_fast(&hwsim_radios_rht, &data->rht,
|
||||
hwsim_rht_params);
|
||||
if (err < 0) {
|
||||
pr_debug("mac80211_hwsim: radio index %d already present\n",
|
||||
idx);
|
||||
if (info) {
|
||||
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);
|
||||
goto failed_final_insert;
|
||||
}
|
||||
|
||||
list_add_tail(&data->list, &hwsim_radios);
|
||||
hwsim_radios_generation++;
|
||||
spin_unlock_bh(&hwsim_radio_lock);
|
||||
|
||||
if (idx > 0)
|
||||
|
@ -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];
|
||||
}
|
||||
|
||||
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, ¶m);
|
||||
kfree(hwname);
|
||||
return ret;
|
||||
|
@ -3249,6 +3279,7 @@ static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info)
|
|||
list_del(&data->list);
|
||||
rhashtable_remove_fast(&hwsim_radios_rht, &data->rht,
|
||||
hwsim_rht_params);
|
||||
hwsim_radios_generation++;
|
||||
spin_unlock_bh(&hwsim_radio_lock);
|
||||
mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy),
|
||||
info);
|
||||
|
@ -3305,17 +3336,19 @@ out_err:
|
|||
static int hwsim_dump_radio_nl(struct sk_buff *skb,
|
||||
struct netlink_callback *cb)
|
||||
{
|
||||
int idx = cb->args[0];
|
||||
int last_idx = cb->args[0];
|
||||
struct mac80211_hwsim_data *data = NULL;
|
||||
int res;
|
||||
int res = 0;
|
||||
void *hdr;
|
||||
|
||||
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;
|
||||
|
||||
list_for_each_entry(data, &hwsim_radios, list) {
|
||||
if (data->idx < idx)
|
||||
if (data->idx <= last_idx)
|
||||
continue;
|
||||
|
||||
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,
|
|||
if (res < 0)
|
||||
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:
|
||||
spin_unlock_bh(&hwsim_radio_lock);
|
||||
return skb->len;
|
||||
return res ?: skb->len;
|
||||
}
|
||||
|
||||
/* Generic Netlink operations array */
|
||||
|
@ -3393,6 +3437,7 @@ static void destroy_radio(struct work_struct *work)
|
|||
struct mac80211_hwsim_data *data =
|
||||
container_of(work, struct mac80211_hwsim_data, destroy_work);
|
||||
|
||||
hwsim_radios_generation++;
|
||||
mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy), NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,12 @@ enum hwsim_tx_control_flags {
|
|||
* %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE
|
||||
* @HWSIM_CMD_NEW_RADIO: create a new radio with the given parameters,
|
||||
* 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_GET_RADIO: fetch information about existing radios, uses:
|
||||
* %HWSIM_ATTR_RADIO_ID
|
||||
|
@ -126,6 +131,7 @@ enum {
|
|||
* @HWSIM_ATTR_FREQ: Frequency at which packet is transmitted or received.
|
||||
* @HWSIM_ATTR_TX_INFO_FLAGS: additional flags for corresponding
|
||||
* rates of %HWSIM_ATTR_TX_INFO
|
||||
* @HWSIM_ATTR_PERM_ADDR: permanent mac address of new radio
|
||||
* @__HWSIM_ATTR_MAX: enum limit
|
||||
*/
|
||||
|
||||
|
@ -153,6 +159,7 @@ enum {
|
|||
HWSIM_ATTR_FREQ,
|
||||
HWSIM_ATTR_PAD,
|
||||
HWSIM_ATTR_TX_INFO_FLAGS,
|
||||
HWSIM_ATTR_PERM_ADDR,
|
||||
__HWSIM_ATTR_MAX,
|
||||
};
|
||||
#define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1)
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
* Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
|
||||
* Copyright (c) 2013 - 2014 Intel Mobile Communications 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
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
@ -2111,7 +2112,7 @@ enum ieee80211_key_len {
|
|||
#define FILS_ERP_MAX_REALM_LEN 253
|
||||
#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) */
|
||||
enum ieee80211_pub_actioncode {
|
||||
|
@ -2501,6 +2502,17 @@ static inline u8 *ieee80211_get_qos_ctl(struct ieee80211_hdr *hdr)
|
|||
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
|
||||
* @hdr: the frame
|
||||
|
|
|
@ -1147,6 +1147,7 @@ struct cfg80211_tid_stats {
|
|||
* @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
|
||||
* (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 {
|
||||
u64 filled;
|
||||
|
@ -1191,6 +1192,7 @@ struct station_info {
|
|||
u64 rx_duration;
|
||||
u8 rx_beacon_signal_avg;
|
||||
struct cfg80211_tid_stats pertid[IEEE80211_NUM_TIDS + 1];
|
||||
s8 ack_signal;
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_CFG80211)
|
||||
|
@ -1905,11 +1907,16 @@ struct cfg80211_auth_request {
|
|||
* @ASSOC_REQ_DISABLE_HT: Disable HT (802.11n)
|
||||
* @ASSOC_REQ_DISABLE_VHT: Disable VHT
|
||||
* @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 {
|
||||
ASSOC_REQ_DISABLE_HT = BIT(0),
|
||||
ASSOC_REQ_DISABLE_VHT = BIT(1),
|
||||
ASSOC_REQ_USE_RRM = BIT(2),
|
||||
CONNECT_REQ_EXTERNAL_AUTH_SUPPORT = BIT(3),
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -2600,6 +2607,33 @@ struct cfg80211_pmk_conf {
|
|||
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
|
||||
*
|
||||
|
@ -2923,6 +2957,9 @@ struct cfg80211_pmk_conf {
|
|||
* (invoked with the wireless_dev mutex held)
|
||||
* @del_pmk: delete the previously configured PMK for the given authenticator.
|
||||
* (invoked with the wireless_dev mutex held)
|
||||
*
|
||||
* @external_auth: indicates result of offloaded authentication processing from
|
||||
* user space
|
||||
*/
|
||||
struct cfg80211_ops {
|
||||
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
|
||||
|
@ -3216,6 +3253,8 @@ struct cfg80211_ops {
|
|||
const struct cfg80211_pmk_conf *conf);
|
||||
int (*del_pmk)(struct wiphy *wiphy, struct net_device *dev,
|
||||
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 {
|
|||
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
|
||||
* @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);
|
|||
void cfg80211_radar_event(struct wiphy *wiphy,
|
||||
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
|
||||
* @netdev: network device
|
||||
|
@ -5758,10 +5840,13 @@ bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
|
|||
* @addr: the address of the peer
|
||||
* @cookie: the cookie filled in @probe_client previously
|
||||
* @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
|
||||
*/
|
||||
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
|
||||
|
@ -6202,6 +6287,17 @@ void cfg80211_nan_func_terminated(struct wireless_dev *wdev,
|
|||
/* ethtool helper */
|
||||
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. */
|
||||
|
||||
/* wiphy_printk helpers, similar to dev_printk */
|
||||
|
|
|
@ -149,6 +149,8 @@ enum ieee80211_radiotap_ampdu_flags {
|
|||
IEEE80211_RADIOTAP_AMPDU_IS_LAST = 0x0008,
|
||||
IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR = 0x0010,
|
||||
IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN = 0x0020,
|
||||
IEEE80211_RADIOTAP_AMPDU_EOF = 0x0040,
|
||||
IEEE80211_RADIOTAP_AMPDU_EOF_KNOWN = 0x0080,
|
||||
};
|
||||
|
||||
/* for IEEE80211_RADIOTAP_VHT */
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright 2013-2014 Intel Mobile Communications 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
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
@ -934,6 +935,7 @@ struct ieee80211_tx_info {
|
|||
u8 ampdu_len;
|
||||
u8 antenna;
|
||||
u16 tx_time;
|
||||
bool is_valid_ack_signal;
|
||||
void *status_driver_data[19 / sizeof(void *)];
|
||||
} status;
|
||||
struct {
|
||||
|
@ -1098,6 +1100,9 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
|
|||
* the first subframe.
|
||||
* @RX_FLAG_ICV_STRIPPED: The ICV is stripped from this frame. CRC checking must
|
||||
* 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 {
|
||||
RX_FLAG_MMIC_ERROR = BIT(0),
|
||||
|
@ -1124,6 +1129,8 @@ enum mac80211_rx_flags {
|
|||
RX_FLAG_MIC_STRIPPED = BIT(21),
|
||||
RX_FLAG_ALLOW_SAME_PN = BIT(22),
|
||||
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 {
|
|||
* @IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA: Hardware supports buffer STA on
|
||||
* 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
|
||||
*/
|
||||
enum ieee80211_hw_flags {
|
||||
|
@ -2106,6 +2121,7 @@ enum ieee80211_hw_flags {
|
|||
IEEE80211_HW_REPORTS_LOW_ACK,
|
||||
IEEE80211_HW_SUPPORTS_TX_FRAG,
|
||||
IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA,
|
||||
IEEE80211_HW_DEAUTH_NEED_MGD_TX_PREP,
|
||||
|
||||
/* keep last, obviously */
|
||||
NUM_IEEE80211_HW_FLAGS
|
||||
|
@ -3350,6 +3366,9 @@ enum ieee80211_reconfig_type {
|
|||
* management frame prior to having successfully associated to allow the
|
||||
* driver to give it channel time for the transmission, to get a response
|
||||
* 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
|
||||
* mac80211 will transmit the frame right away.
|
||||
* The callback is optional and can (should!) sleep.
|
||||
|
|
|
@ -88,6 +88,7 @@
|
|||
#define ETH_P_AOE 0x88A2 /* ATA over Ethernet */
|
||||
#define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */
|
||||
#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_MACSEC 0x88E5 /* 802.1ae MACsec */
|
||||
#define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */
|
||||
|
|
|
@ -992,6 +992,32 @@
|
|||
*
|
||||
* @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_AFTER_LAST: internal use
|
||||
*/
|
||||
|
@ -1198,6 +1224,10 @@ enum nl80211_commands {
|
|||
|
||||
NL80211_CMD_RELOAD_REGDB,
|
||||
|
||||
NL80211_CMD_EXTERNAL_AUTH,
|
||||
|
||||
NL80211_CMD_STA_OPMODE_CHANGED,
|
||||
|
||||
/* add new commands above here */
|
||||
|
||||
/* used to define NL80211_CMD_MAX below */
|
||||
|
@ -2153,6 +2183,19 @@ enum nl80211_commands {
|
|||
* @NL80211_ATTR_PMKR0_NAME: PMK-R0 Name for offloaded FT.
|
||||
* @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
|
||||
* @NL80211_ATTR_MAX: highest attribute number currently defined
|
||||
* @__NL80211_ATTR_AFTER_LAST: internal use
|
||||
|
@ -2579,6 +2622,12 @@ enum nl80211_attrs {
|
|||
NL80211_ATTR_PMKR0_NAME,
|
||||
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 */
|
||||
|
||||
__NL80211_ATTR_AFTER_LAST,
|
||||
|
@ -2899,6 +2948,7 @@ enum nl80211_sta_bss_param {
|
|||
* @NL80211_STA_INFO_RX_DURATION: aggregate PPDU duration for all frames
|
||||
* received from the station (u64, usec)
|
||||
* @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_MAX: highest possible station info attribute
|
||||
*/
|
||||
|
@ -2937,6 +2987,7 @@ enum nl80211_sta_info {
|
|||
NL80211_STA_INFO_TID_STATS,
|
||||
NL80211_STA_INFO_RX_DURATION,
|
||||
NL80211_STA_INFO_PAD,
|
||||
NL80211_STA_INFO_ACK_SIGNAL,
|
||||
|
||||
/* keep last */
|
||||
__NL80211_STA_INFO_AFTER_LAST,
|
||||
|
@ -4945,6 +4996,9 @@ enum nl80211_feature_flags {
|
|||
* probe request tx deferral and suppression
|
||||
* @NL80211_EXT_FEATURE_MFP_OPTIONAL: Driver supports the %NL80211_MFP_OPTIONAL
|
||||
* 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.
|
||||
* @MAX_NL80211_EXT_FEATURES: highest extended 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_DEFERRAL_SUPPRESSION,
|
||||
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 */
|
||||
NUM_NL80211_EXT_FEATURES,
|
||||
|
@ -5032,6 +5089,10 @@ enum nl80211_timeout_reason {
|
|||
* of NL80211_CMD_TRIGGER_SCAN and NL80211_CMD_START_SCHED_SCAN
|
||||
* 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_FLUSH: flush cache before scanning
|
||||
* @NL80211_SCAN_FLAG_AP: force a scan even if the interface is configured
|
||||
|
@ -5059,7 +5120,20 @@ enum nl80211_timeout_reason {
|
|||
* and suppression (if it has received a broadcast Probe Response frame,
|
||||
* Beacon frame or FILS Discovery frame from an AP that the STA considers
|
||||
* 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 {
|
||||
NL80211_SCAN_FLAG_LOW_PRIORITY = 1<<0,
|
||||
|
@ -5070,6 +5144,9 @@ enum nl80211_scan_flags {
|
|||
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_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 {
|
|||
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 */
|
||||
|
|
|
@ -212,6 +212,7 @@ static const char *hw_flag_names[] = {
|
|||
FLAG(REPORTS_LOW_ACK),
|
||||
FLAG(SUPPORTS_TX_FRAG),
|
||||
FLAG(SUPPORTS_TDLS_BUFFER_STA),
|
||||
FLAG(DEAUTH_NEED_MGD_TX_PREP),
|
||||
#undef FLAG
|
||||
};
|
||||
|
||||
|
|
|
@ -160,12 +160,12 @@ static ssize_t sta_aqm_read(struct file *file, char __user *userbuf,
|
|||
sta->cparams.ecn ? "yes" : "no");
|
||||
p += scnprintf(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++) {
|
||||
txqi = to_txq_info(sta->sta.txq[i]);
|
||||
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.ac,
|
||||
txqi->tin.backlog_bytes,
|
||||
|
@ -176,7 +176,11 @@ static ssize_t sta_aqm_read(struct file *file, char __user *userbuf,
|
|||
txqi->tin.overlimit,
|
||||
txqi->tin.collisions,
|
||||
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();
|
||||
|
|
|
@ -1324,8 +1324,7 @@ static void ieee80211_iface_work(struct work_struct *work)
|
|||
mutex_lock(&local->sta_mtx);
|
||||
sta = sta_info_get_bss(sdata, mgmt->sa);
|
||||
if (sta) {
|
||||
u16 tid = *ieee80211_get_qos_ctl(hdr) &
|
||||
IEEE80211_QOS_CTL_TID_MASK;
|
||||
u16 tid = ieee80211_get_tid(hdr);
|
||||
|
||||
__ieee80211_stop_rx_ba_session(
|
||||
sta, tid, WLAN_BACK_RECIPIENT,
|
||||
|
|
|
@ -35,7 +35,7 @@ static void michael_mic_hdr(struct michael_mic_ctx *mctx, const u8 *key,
|
|||
da = ieee80211_get_DA(hdr);
|
||||
sa = ieee80211_get_SA(hdr);
|
||||
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
|
||||
tid = 0;
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
* Copyright 2007, Michael Wu <flamingice@sourmilk.net>
|
||||
* Copyright 2013-2014 Intel Mobile Communications 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
|
||||
* 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,
|
|||
ieee80211_flush_queues(local, sdata, true);
|
||||
|
||||
/* 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,
|
||||
reason, tx, frame_buf);
|
||||
}
|
||||
|
||||
/* flush out frame - make sure the deauth was actually sent */
|
||||
if (tx)
|
||||
|
@ -2151,7 +2165,7 @@ static void ieee80211_sta_tx_wmm_ac_notify(struct ieee80211_sub_if_data *sdata,
|
|||
u16 tx_time)
|
||||
{
|
||||
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);
|
||||
struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac];
|
||||
unsigned long now = jiffies;
|
||||
|
|
|
@ -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)))
|
||||
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]))
|
||||
return;
|
||||
|
||||
|
|
|
@ -439,6 +439,10 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
|
|||
flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR;
|
||||
if (status->flag & RX_FLAG_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);
|
||||
pos += 2;
|
||||
if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN)
|
||||
|
@ -1185,7 +1189,7 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
|
|||
|
||||
ack_policy = *ieee80211_get_qos_ctl(hdr) &
|
||||
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]);
|
||||
if (!tid_agg_rx) {
|
||||
|
@ -1524,9 +1528,7 @@ ieee80211_rx_h_uapsd_and_pspoll(struct ieee80211_rx_data *rx)
|
|||
ieee80211_has_pm(hdr->frame_control) &&
|
||||
(ieee80211_is_data_qos(hdr->frame_control) ||
|
||||
ieee80211_is_qos_nullfunc(hdr->frame_control))) {
|
||||
u8 tid;
|
||||
|
||||
tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
|
||||
u8 tid = ieee80211_get_tid(hdr);
|
||||
|
||||
ieee80211_sta_uapsd_trigger(&rx->sta->sta, tid);
|
||||
}
|
||||
|
@ -2848,6 +2850,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
|
|||
case WLAN_HT_ACTION_SMPS: {
|
||||
struct ieee80211_supported_band *sband;
|
||||
enum ieee80211_smps_mode smps_mode;
|
||||
struct sta_opmode_info sta_opmode = {};
|
||||
|
||||
/* convert to HT capability */
|
||||
switch (mgmt->u.action.u.ht_smps.smps_control) {
|
||||
|
@ -2868,17 +2871,24 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
|
|||
if (rx->sta->sta.smps_mode == smps_mode)
|
||||
goto handled;
|
||||
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];
|
||||
|
||||
rate_control_rate_update(local, sband, rx->sta,
|
||||
IEEE80211_RC_SMPS_CHANGED);
|
||||
cfg80211_sta_opmode_change_notify(sdata->dev,
|
||||
rx->sta->addr,
|
||||
&sta_opmode,
|
||||
GFP_KERNEL);
|
||||
goto handled;
|
||||
}
|
||||
case WLAN_HT_ACTION_NOTIFY_CHANWIDTH: {
|
||||
struct ieee80211_supported_band *sband;
|
||||
u8 chanwidth = mgmt->u.action.u.ht_notify_cw.chanwidth;
|
||||
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 (!(rx->sta->sta.ht_cap.cap &
|
||||
|
@ -2899,9 +2909,15 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
|
|||
|
||||
rx->sta->sta.bandwidth = new_bw;
|
||||
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,
|
||||
IEEE80211_RC_BW_CHANGED);
|
||||
cfg80211_sta_opmode_change_notify(sdata->dev,
|
||||
rx->sta->addr,
|
||||
&sta_opmode,
|
||||
GFP_KERNEL);
|
||||
goto handled;
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -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->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)
|
||||
|
|
|
@ -548,6 +548,8 @@ struct sta_info {
|
|||
u64 msdu_retries[IEEE80211_NUM_TIDS + 1];
|
||||
u64 msdu_failed[IEEE80211_NUM_TIDS + 1];
|
||||
unsigned long last_ack;
|
||||
s8 last_ack_signal;
|
||||
bool ack_signal_filled;
|
||||
} status_stats;
|
||||
|
||||
/* 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)
|
|||
struct ieee80211_mgmt *mgmt = (void *) skb->data;
|
||||
struct ieee80211_local *local = sta->local;
|
||||
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;
|
||||
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)) {
|
||||
struct ieee80211_hdr *hdr = (void *) skb->data;
|
||||
|
@ -487,6 +494,8 @@ static void ieee80211_report_ack_skb(struct ieee80211_local *local,
|
|||
ieee80211_is_qos_nullfunc(hdr->frame_control))
|
||||
cfg80211_probe_status(sdata->dev, hdr->addr1,
|
||||
cookie, acked,
|
||||
info->status.ack_signal,
|
||||
info->status.is_valid_ack_signal,
|
||||
GFP_ATOMIC);
|
||||
else
|
||||
cfg80211_mgmt_tx_status(&sdata->wdev, cookie,
|
||||
|
|
|
@ -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_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
|
||||
u8 *qc;
|
||||
int tid;
|
||||
|
||||
/*
|
||||
|
@ -844,9 +843,7 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
|
|||
return TX_CONTINUE;
|
||||
|
||||
/* include per-STA, per-TID sequence counter */
|
||||
|
||||
qc = ieee80211_get_qos_ctl(hdr);
|
||||
tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
|
||||
tid = ieee80211_get_tid(hdr);
|
||||
tx->sta->tx_stats.msdu[tid]++;
|
||||
|
||||
hdr->seq_ctrl = ieee80211_tx_next_seq(tx->sta, tid);
|
||||
|
@ -1158,7 +1155,6 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
|
|||
struct ieee80211_hdr *hdr;
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
int tid;
|
||||
u8 *qc;
|
||||
|
||||
memset(tx, 0, sizeof(*tx));
|
||||
tx->skb = skb;
|
||||
|
@ -1198,8 +1194,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
|
|||
!ieee80211_hw_check(&local->hw, TX_AMPDU_SETUP_IN_HW)) {
|
||||
struct tid_ampdu_tx *tid_tx;
|
||||
|
||||
qc = ieee80211_get_qos_ctl(hdr);
|
||||
tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
|
||||
tid = ieee80211_get_tid(hdr);
|
||||
|
||||
tid_tx = rcu_dereference(tx->sta->ampdu_mlme.tid_tx[tid]);
|
||||
if (tid_tx) {
|
||||
|
@ -1921,7 +1916,7 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
|
|||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
||||
struct ieee80211_hdr *hdr;
|
||||
int headroom;
|
||||
bool may_encrypt;
|
||||
|
||||
|
|
|
@ -447,6 +447,7 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
|
|||
enum nl80211_band band)
|
||||
{
|
||||
enum ieee80211_sta_rx_bandwidth new_bw;
|
||||
struct sta_opmode_info sta_opmode = {};
|
||||
u32 changed = 0;
|
||||
u8 nss;
|
||||
|
||||
|
@ -460,7 +461,9 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
if (sta->sta.rx_nss != nss) {
|
||||
sta->sta.rx_nss = nss;
|
||||
sta_opmode.rx_nss = nss;
|
||||
changed |= IEEE80211_RC_NSS_CHANGED;
|
||||
sta_opmode.changed |= STA_OPMODE_N_SS_CHANGED;
|
||||
}
|
||||
|
||||
switch (opmode & IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK) {
|
||||
|
@ -481,9 +484,15 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
|
|||
new_bw = ieee80211_sta_cur_vht_bw(sta);
|
||||
if (new_bw != sta->sta.bandwidth) {
|
||||
sta->sta.bandwidth = new_bw;
|
||||
sta_opmode.bw = new_bw;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
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
|
||||
qos_tid = 0;
|
||||
|
||||
|
@ -601,8 +601,7 @@ static void gcmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *j_0, u8 *aad)
|
|||
aad[23] = 0;
|
||||
|
||||
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
|
||||
qos_tid = 0;
|
||||
|
||||
|
@ -867,8 +866,7 @@ ieee80211_crypto_cs_decrypt(struct ieee80211_rx_data *rx)
|
|||
return RX_DROP_UNUSABLE;
|
||||
|
||||
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
|
||||
qos_tid = 0;
|
||||
|
||||
|
|
|
@ -421,6 +421,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
|||
[NL80211_ATTR_FILS_CACHE_ID] = { .len = 2 },
|
||||
[NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN },
|
||||
[NL80211_ATTR_SCHED_SCAN_MULTI] = { .type = NLA_FLAG },
|
||||
[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT] = { .type = NLA_FLAG },
|
||||
};
|
||||
|
||||
/* policy for the key attributes */
|
||||
|
@ -3923,9 +3924,10 @@ static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
|
|||
return false;
|
||||
return true;
|
||||
case NL80211_CMD_CONNECT:
|
||||
/* SAE not supported yet */
|
||||
if (auth_type == NL80211_AUTHTYPE_SAE)
|
||||
if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
|
||||
auth_type == NL80211_AUTHTYPE_SAE)
|
||||
return false;
|
||||
|
||||
/* FILS with SK PFS or PK not supported yet */
|
||||
if (auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
|
||||
auth_type == NL80211_AUTHTYPE_FILS_PK)
|
||||
|
@ -4487,6 +4489,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
|
|||
PUT_SINFO_U64(RX_DROP_MISC, rx_dropped_misc);
|
||||
PUT_SINFO_U64(BEACON_RX, rx_beacon);
|
||||
PUT_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8);
|
||||
PUT_SINFO(ACK_SIGNAL, ack_signal, u8);
|
||||
|
||||
#undef PUT_SINFO
|
||||
#undef PUT_SINFO_U64
|
||||
|
@ -5848,7 +5851,6 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
|
|||
return genlmsg_reply(msg, info);
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
out:
|
||||
nlmsg_free(msg);
|
||||
return -ENOBUFS;
|
||||
|
@ -6329,7 +6331,6 @@ static int nl80211_get_reg_do(struct sk_buff *skb, struct genl_info *info)
|
|||
nla_put_failure_rcu:
|
||||
rcu_read_unlock();
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
put_failure:
|
||||
nlmsg_free(msg);
|
||||
return -EMSGSIZE;
|
||||
|
@ -6718,8 +6719,17 @@ nl80211_check_scan_flags(struct wiphy *wiphy, struct wireless_dev *wdev,
|
|||
|
||||
*flags = nla_get_u32(attrs[NL80211_ATTR_SCAN_FLAGS]);
|
||||
|
||||
if ((*flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
|
||||
!(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN))
|
||||
if (((*flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
|
||||
!(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) ||
|
||||
((*flags & NL80211_SCAN_FLAG_LOW_SPAN) &&
|
||||
!wiphy_ext_feature_isset(wiphy,
|
||||
NL80211_EXT_FEATURE_LOW_SPAN_SCAN)) ||
|
||||
((*flags & NL80211_SCAN_FLAG_LOW_POWER) &&
|
||||
!wiphy_ext_feature_isset(wiphy,
|
||||
NL80211_EXT_FEATURE_LOW_POWER_SCAN)) ||
|
||||
((*flags & NL80211_SCAN_FLAG_HIGH_ACCURACY) &&
|
||||
!wiphy_ext_feature_isset(wiphy,
|
||||
NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN)))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (*flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
|
||||
|
@ -9155,6 +9165,15 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (nla_get_flag(info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])) {
|
||||
if (!info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
|
||||
GENL_SET_ERR_MSG(info,
|
||||
"external auth requires connection ownership");
|
||||
return -EINVAL;
|
||||
}
|
||||
connect.flags |= CONNECT_REQ_EXTERNAL_AUTH_SUPPORT;
|
||||
}
|
||||
|
||||
wdev_lock(dev->ieee80211_ptr);
|
||||
|
||||
err = cfg80211_connect(rdev, dev, &connect, connkeys,
|
||||
|
@ -12463,6 +12482,41 @@ static int nl80211_del_pmk(struct sk_buff *skb, struct genl_info *info)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
struct net_device *dev = info->user_ptr[1];
|
||||
struct cfg80211_external_auth_params params;
|
||||
|
||||
if (!rdev->ops->external_auth)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!info->attrs[NL80211_ATTR_SSID])
|
||||
return -EINVAL;
|
||||
|
||||
if (!info->attrs[NL80211_ATTR_BSSID])
|
||||
return -EINVAL;
|
||||
|
||||
if (!info->attrs[NL80211_ATTR_STATUS_CODE])
|
||||
return -EINVAL;
|
||||
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
|
||||
params.ssid.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
|
||||
if (params.ssid.ssid_len == 0 ||
|
||||
params.ssid.ssid_len > IEEE80211_MAX_SSID_LEN)
|
||||
return -EINVAL;
|
||||
memcpy(params.ssid.ssid, nla_data(info->attrs[NL80211_ATTR_SSID]),
|
||||
params.ssid.ssid_len);
|
||||
|
||||
memcpy(params.bssid, nla_data(info->attrs[NL80211_ATTR_BSSID]),
|
||||
ETH_ALEN);
|
||||
|
||||
params.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
|
||||
|
||||
return rdev_external_auth(rdev, dev, ¶ms);
|
||||
}
|
||||
|
||||
#define NL80211_FLAG_NEED_WIPHY 0x01
|
||||
#define NL80211_FLAG_NEED_NETDEV 0x02
|
||||
#define NL80211_FLAG_NEED_RTNL 0x04
|
||||
|
@ -13358,6 +13412,14 @@ static const struct genl_ops nl80211_ops[] = {
|
|||
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
|
||||
NL80211_FLAG_NEED_RTNL,
|
||||
},
|
||||
{
|
||||
.cmd = NL80211_CMD_EXTERNAL_AUTH,
|
||||
.doit = nl80211_external_auth,
|
||||
.policy = nl80211_policy,
|
||||
.flags = GENL_ADMIN_PERM,
|
||||
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
|
||||
NL80211_FLAG_NEED_RTNL,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
|
@ -13672,7 +13734,6 @@ void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
|
|||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
|
@ -13720,7 +13781,6 @@ static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
|
|||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
|
@ -13808,7 +13868,6 @@ static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
|
|||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
|
@ -13884,7 +13943,6 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
|
|||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
|
@ -13924,7 +13982,6 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
|
|||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
|
@ -13954,7 +14011,6 @@ void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
|
|||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
|
@ -13991,7 +14047,6 @@ void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
|
|||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
|
@ -14024,7 +14079,6 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
|
|||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
|
@ -14065,7 +14119,6 @@ void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
|
|||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);
|
||||
|
@ -14104,7 +14157,6 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
|
|||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
|
@ -14159,7 +14211,6 @@ void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
|
|||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
|
@ -14205,7 +14256,6 @@ static void nl80211_send_remain_on_chan_event(
|
|||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
|
@ -14319,7 +14369,6 @@ void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
|
|||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_conn_failed);
|
||||
|
@ -14356,7 +14405,6 @@ static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
|
|||
return true;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
return true;
|
||||
}
|
||||
|
@ -14440,7 +14488,6 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
|
|||
return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
@ -14484,7 +14531,6 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
|
|||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
|
||||
|
@ -14693,7 +14739,6 @@ static void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
|
|||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
|
@ -14751,7 +14796,6 @@ nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
|
|||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
|
@ -14804,7 +14848,6 @@ static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
|
|||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
|
@ -14886,12 +14929,67 @@ nl80211_radar_notify(struct cfg80211_registered_device *rdev,
|
|||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac,
|
||||
struct sta_opmode_info *sta_opmode,
|
||||
gfp_t gfp)
|
||||
{
|
||||
struct sk_buff *msg;
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
|
||||
void *hdr;
|
||||
|
||||
if (WARN_ON(!mac))
|
||||
return;
|
||||
|
||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STA_OPMODE_CHANGED);
|
||||
if (!hdr) {
|
||||
nlmsg_free(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac))
|
||||
goto nla_put_failure;
|
||||
|
||||
if ((sta_opmode->changed & STA_OPMODE_SMPS_MODE_CHANGED) &&
|
||||
nla_put_u8(msg, NL80211_ATTR_SMPS_MODE, sta_opmode->smps_mode))
|
||||
goto nla_put_failure;
|
||||
|
||||
if ((sta_opmode->changed & STA_OPMODE_MAX_BW_CHANGED) &&
|
||||
nla_put_u8(msg, NL80211_ATTR_CHANNEL_WIDTH, sta_opmode->bw))
|
||||
goto nla_put_failure;
|
||||
|
||||
if ((sta_opmode->changed & STA_OPMODE_N_SS_CHANGED) &&
|
||||
nla_put_u8(msg, NL80211_ATTR_NSS, sta_opmode->rx_nss))
|
||||
goto nla_put_failure;
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
|
||||
genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
|
||||
NL80211_MCGRP_MLME, gfp);
|
||||
|
||||
return;
|
||||
|
||||
nla_put_failure:
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_sta_opmode_change_notify);
|
||||
|
||||
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)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
|
||||
|
@ -14916,7 +15014,9 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
|
|||
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
|
||||
nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
|
||||
NL80211_ATTR_PAD) ||
|
||||
(acked && nla_put_flag(msg, NL80211_ATTR_ACK)))
|
||||
(acked && nla_put_flag(msg, NL80211_ATTR_ACK)) ||
|
||||
(is_valid_ack_signal && nla_put_s32(msg, NL80211_ATTR_ACK_SIGNAL,
|
||||
ack_signal)))
|
||||
goto nla_put_failure;
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
|
@ -14926,7 +15026,6 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
|
|||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_probe_status);
|
||||
|
@ -14971,8 +15070,6 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy,
|
|||
|
||||
nla_put_failure:
|
||||
spin_unlock_bh(&rdev->beacon_registrations_lock);
|
||||
if (hdr)
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_report_obss_beacon);
|
||||
|
@ -15188,7 +15285,6 @@ void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
|
|||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_tdls_oper_request);
|
||||
|
@ -15333,8 +15429,6 @@ void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp)
|
|||
return;
|
||||
|
||||
nla_put_failure:
|
||||
if (hdr)
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
|
||||
|
@ -15369,6 +15463,47 @@ void nl80211_send_ap_stopped(struct wireless_dev *wdev)
|
|||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
int cfg80211_external_auth_request(struct net_device *dev,
|
||||
struct cfg80211_external_auth_params *params,
|
||||
gfp_t gfp)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
|
||||
struct sk_buff *msg;
|
||||
void *hdr;
|
||||
|
||||
if (!wdev->conn_owner_nlportid)
|
||||
return -EINVAL;
|
||||
|
||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
|
||||
hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_EXTERNAL_AUTH);
|
||||
if (!hdr)
|
||||
goto nla_put_failure;
|
||||
|
||||
if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_AKM_SUITES, params->key_mgmt_suite) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_EXTERNAL_AUTH_ACTION,
|
||||
params->action) ||
|
||||
nla_put(msg, NL80211_ATTR_BSSID, ETH_ALEN, params->bssid) ||
|
||||
nla_put(msg, NL80211_ATTR_SSID, params->ssid.ssid_len,
|
||||
params->ssid.ssid))
|
||||
goto nla_put_failure;
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
|
||||
wdev->conn_owner_nlportid);
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
nlmsg_free(msg);
|
||||
return -ENOBUFS;
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_external_auth_request);
|
||||
|
||||
/* initialisation/exit functions */
|
||||
|
||||
int __init nl80211_init(void)
|
||||
|
|
|
@ -1190,4 +1190,19 @@ static inline int rdev_del_pmk(struct cfg80211_registered_device *rdev,
|
|||
trace_rdev_return_int(&rdev->wiphy, 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 */
|
||||
|
|
|
@ -2319,6 +2319,29 @@ TRACE_EVENT(rdev_del_pmk,
|
|||
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 *
|
||||
*************************************************************/
|
||||
|
|
Loading…
Reference in New Issue