mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-21 00:20:08 +07:00
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
This commit is contained in:
commit
c77986c78a
@ -98,6 +98,8 @@
|
||||
!Finclude/net/cfg80211.h priv_to_wiphy
|
||||
!Finclude/net/cfg80211.h set_wiphy_dev
|
||||
!Finclude/net/cfg80211.h wdev_priv
|
||||
!Finclude/net/cfg80211.h ieee80211_iface_limit
|
||||
!Finclude/net/cfg80211.h ieee80211_iface_combination
|
||||
</chapter>
|
||||
<chapter>
|
||||
<title>Actions and configuration</title>
|
||||
|
@ -1746,14 +1746,16 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
static int iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
iwl_mvm_sched_scan_stop(mvm);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
|
||||
|
@ -411,6 +411,7 @@ struct mac80211_hwsim_data {
|
||||
|
||||
struct mac_address addresses[2];
|
||||
int channels, idx;
|
||||
bool use_chanctx;
|
||||
|
||||
struct ieee80211_channel *tmp_chan;
|
||||
struct delayed_work roc_done;
|
||||
@ -1088,7 +1089,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
|
||||
return;
|
||||
}
|
||||
|
||||
if (data->channels == 1) {
|
||||
if (!data->use_chanctx) {
|
||||
channel = data->channel;
|
||||
} else if (txi->hw_queue == 4) {
|
||||
channel = data->tmp_chan;
|
||||
@ -1354,7 +1355,7 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
|
||||
|
||||
data->channel = conf->chandef.chan;
|
||||
|
||||
WARN_ON(data->channel && data->channels > 1);
|
||||
WARN_ON(data->channel && data->use_chanctx);
|
||||
|
||||
data->power_level = conf->power_level;
|
||||
if (!data->started || !data->beacon_int)
|
||||
@ -1940,7 +1941,8 @@ static struct ieee80211_ops mac80211_hwsim_mchan_ops;
|
||||
|
||||
static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2,
|
||||
const struct ieee80211_regdomain *regd,
|
||||
bool reg_strict, bool p2p_device)
|
||||
bool reg_strict, bool p2p_device,
|
||||
bool use_chanctx)
|
||||
{
|
||||
int err;
|
||||
u8 addr[ETH_ALEN];
|
||||
@ -1950,11 +1952,14 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2,
|
||||
const struct ieee80211_ops *ops = &mac80211_hwsim_ops;
|
||||
int idx;
|
||||
|
||||
if (WARN_ON(channels > 1 && !use_chanctx))
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_bh(&hwsim_radio_lock);
|
||||
idx = hwsim_radio_idx++;
|
||||
spin_unlock_bh(&hwsim_radio_lock);
|
||||
|
||||
if (channels > 1)
|
||||
if (use_chanctx)
|
||||
ops = &mac80211_hwsim_mchan_ops;
|
||||
hw = ieee80211_alloc_hw(sizeof(*data), ops);
|
||||
if (!hw) {
|
||||
@ -1995,20 +2000,21 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2,
|
||||
hw->wiphy->addresses = data->addresses;
|
||||
|
||||
data->channels = channels;
|
||||
data->use_chanctx = use_chanctx;
|
||||
data->idx = idx;
|
||||
|
||||
if (data->channels > 1) {
|
||||
if (data->use_chanctx) {
|
||||
hw->wiphy->max_scan_ssids = 255;
|
||||
hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
|
||||
hw->wiphy->max_remain_on_channel_duration = 1000;
|
||||
/* For channels > 1 DFS is not allowed */
|
||||
hw->wiphy->n_iface_combinations = 1;
|
||||
hw->wiphy->iface_combinations = &data->if_combination;
|
||||
data->if_combination.num_different_channels = data->channels;
|
||||
if (p2p_device)
|
||||
data->if_combination = hwsim_if_comb_p2p_dev[0];
|
||||
else
|
||||
data->if_combination = hwsim_if_comb[0];
|
||||
data->if_combination.num_different_channels = data->channels;
|
||||
} else if (p2p_device) {
|
||||
hw->wiphy->iface_combinations = hwsim_if_comb_p2p_dev;
|
||||
hw->wiphy->n_iface_combinations =
|
||||
@ -2156,7 +2162,7 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2,
|
||||
debugfs_create_file("ps", 0666, data->debugfs, data, &hwsim_fops_ps);
|
||||
debugfs_create_file("group", 0666, data->debugfs, data,
|
||||
&hwsim_fops_group);
|
||||
if (data->channels == 1)
|
||||
if (!data->use_chanctx)
|
||||
debugfs_create_file("dfs_simulate_radar", 0222,
|
||||
data->debugfs,
|
||||
data, &hwsim_simulate_radar);
|
||||
@ -2423,10 +2429,16 @@ static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info)
|
||||
const struct ieee80211_regdomain *regd = NULL;
|
||||
bool reg_strict = info->attrs[HWSIM_ATTR_REG_STRICT_REG];
|
||||
bool p2p_device = info->attrs[HWSIM_ATTR_SUPPORT_P2P_DEVICE];
|
||||
bool use_chanctx;
|
||||
|
||||
if (info->attrs[HWSIM_ATTR_CHANNELS])
|
||||
chans = nla_get_u32(info->attrs[HWSIM_ATTR_CHANNELS]);
|
||||
|
||||
if (info->attrs[HWSIM_ATTR_USE_CHANCTX])
|
||||
use_chanctx = true;
|
||||
else
|
||||
use_chanctx = (chans > 1);
|
||||
|
||||
if (info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2])
|
||||
alpha2 = nla_data(info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2]);
|
||||
|
||||
@ -2439,7 +2451,7 @@ static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info)
|
||||
}
|
||||
|
||||
return mac80211_hwsim_create_radio(chans, alpha2, regd, reg_strict,
|
||||
p2p_device);
|
||||
p2p_device, use_chanctx);
|
||||
}
|
||||
|
||||
static int hwsim_destroy_radio_nl(struct sk_buff *msg, struct genl_info *info)
|
||||
@ -2658,7 +2670,8 @@ static int __init init_mac80211_hwsim(void)
|
||||
|
||||
err = mac80211_hwsim_create_radio(channels, reg_alpha2,
|
||||
regd, reg_strict,
|
||||
support_p2p_device);
|
||||
support_p2p_device,
|
||||
channels > 1);
|
||||
if (err < 0)
|
||||
goto out_free_radios;
|
||||
}
|
||||
|
@ -108,6 +108,9 @@ enum {
|
||||
* @HWSIM_ATTR_REG_CUSTOM_REG: custom regulatory domain index (u32 attribute)
|
||||
* @HWSIM_ATTR_REG_STRICT_REG: request REGULATORY_STRICT_REG (flag attribute)
|
||||
* @HWSIM_ATTR_SUPPORT_P2P_DEVICE: support P2P Device virtual interface (flag)
|
||||
* @HWSIM_ATTR_USE_CHANCTX: used with the %HWSIM_CMD_CREATE_RADIO
|
||||
* command to force use of channel contexts even when only a
|
||||
* single channel is supported
|
||||
* @__HWSIM_ATTR_MAX: enum limit
|
||||
*/
|
||||
|
||||
@ -128,6 +131,7 @@ enum {
|
||||
HWSIM_ATTR_REG_CUSTOM_REG,
|
||||
HWSIM_ATTR_REG_STRICT_REG,
|
||||
HWSIM_ATTR_SUPPORT_P2P_DEVICE,
|
||||
HWSIM_ATTR_USE_CHANCTX,
|
||||
__HWSIM_ATTR_MAX,
|
||||
};
|
||||
#define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1)
|
||||
|
@ -2600,8 +2600,8 @@ static int mwifiex_cfg80211_set_coalesce(struct wiphy *wiphy,
|
||||
static int
|
||||
mwifiex_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
|
||||
u8 *peer, u8 action_code, u8 dialog_token,
|
||||
u16 status_code, const u8 *extra_ies,
|
||||
size_t extra_ies_len)
|
||||
u16 status_code, u32 peer_capability,
|
||||
const u8 *extra_ies, size_t extra_ies_len)
|
||||
{
|
||||
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
|
||||
int ret;
|
||||
|
@ -3668,8 +3668,8 @@ static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wl1271_op_sched_scan_stop(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
static int wl1271_op_sched_scan_stop(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct wl1271 *wl = hw->priv;
|
||||
struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
|
||||
@ -3691,6 +3691,8 @@ static void wl1271_op_sched_scan_stop(struct ieee80211_hw *hw,
|
||||
wl1271_ps_elp_sleep(wl);
|
||||
out:
|
||||
mutex_unlock(&wl->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
|
||||
|
@ -2206,7 +2206,12 @@ struct cfg80211_qos_map {
|
||||
* @set_cqm_txe_config: Configure connection quality monitor TX error
|
||||
* thresholds.
|
||||
* @sched_scan_start: Tell the driver to start a scheduled scan.
|
||||
* @sched_scan_stop: Tell the driver to stop an ongoing scheduled scan.
|
||||
* @sched_scan_stop: Tell the driver to stop an ongoing scheduled scan. This
|
||||
* call must stop the scheduled scan and be ready for starting a new one
|
||||
* before it returns, i.e. @sched_scan_start may be called immediately
|
||||
* after that again and should not fail in that case. The driver should
|
||||
* not call cfg80211_sched_scan_stopped() for a requested stop (when this
|
||||
* method returns 0.)
|
||||
*
|
||||
* @mgmt_frame_register: Notify driver that a management frame type was
|
||||
* registered. Note that this callback may not sleep, and cannot run
|
||||
@ -2465,7 +2470,8 @@ struct cfg80211_ops {
|
||||
|
||||
int (*tdls_mgmt)(struct wiphy *wiphy, struct net_device *dev,
|
||||
u8 *peer, u8 action_code, u8 dialog_token,
|
||||
u16 status_code, const u8 *buf, size_t len);
|
||||
u16 status_code, u32 peer_capability,
|
||||
const u8 *buf, size_t len);
|
||||
int (*tdls_oper)(struct wiphy *wiphy, struct net_device *dev,
|
||||
u8 *peer, enum nl80211_tdls_operation oper);
|
||||
|
||||
@ -2610,9 +2616,12 @@ struct ieee80211_iface_limit {
|
||||
* only in special cases.
|
||||
* @radar_detect_widths: bitmap of channel widths supported for radar detection
|
||||
*
|
||||
* These examples can be expressed as follows:
|
||||
* With this structure the driver can describe which interface
|
||||
* combinations it supports concurrently.
|
||||
*
|
||||
* Allow #STA <= 1, #AP <= 1, matching BI, channels = 1, 2 total:
|
||||
* Examples:
|
||||
*
|
||||
* 1. Allow #STA <= 1, #AP <= 1, matching BI, channels = 1, 2 total:
|
||||
*
|
||||
* struct ieee80211_iface_limit limits1[] = {
|
||||
* { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), },
|
||||
@ -2626,7 +2635,7 @@ struct ieee80211_iface_limit {
|
||||
* };
|
||||
*
|
||||
*
|
||||
* Allow #{AP, P2P-GO} <= 8, channels = 1, 8 total:
|
||||
* 2. Allow #{AP, P2P-GO} <= 8, channels = 1, 8 total:
|
||||
*
|
||||
* struct ieee80211_iface_limit limits2[] = {
|
||||
* { .max = 8, .types = BIT(NL80211_IFTYPE_AP) |
|
||||
@ -2640,7 +2649,8 @@ struct ieee80211_iface_limit {
|
||||
* };
|
||||
*
|
||||
*
|
||||
* Allow #STA <= 1, #{P2P-client,P2P-GO} <= 3 on two channels, 4 total.
|
||||
* 3. Allow #STA <= 1, #{P2P-client,P2P-GO} <= 3 on two channels, 4 total.
|
||||
*
|
||||
* This allows for an infrastructure connection and three P2P connections.
|
||||
*
|
||||
* struct ieee80211_iface_limit limits3[] = {
|
||||
@ -2790,7 +2800,7 @@ struct wiphy_vendor_command {
|
||||
* @perm_addr: permanent MAC address of this device
|
||||
* @addr_mask: If the device supports multiple MAC addresses by masking,
|
||||
* set this to a mask with variable bits set to 1, e.g. if the last
|
||||
* four bits are variable then set it to 00:...:00:0f. The actual
|
||||
* four bits are variable then set it to 00-00-00-00-00-0f. The actual
|
||||
* variable bits shall be determined by the interfaces added, with
|
||||
* interfaces not matching the mask being rejected to be brought up.
|
||||
* @n_addresses: number of addresses in @addresses.
|
||||
|
@ -66,10 +66,6 @@
|
||||
*
|
||||
* Secondly, when the hardware handles fragmentation, the frame handed to
|
||||
* the driver from mac80211 is the MSDU, not the MPDU.
|
||||
*
|
||||
* Finally, for received frames, the driver is able to indicate that it has
|
||||
* filled a radiotap header and put that in front of the frame; if it does
|
||||
* not do so then mac80211 may add this under certain circumstances.
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -1507,8 +1503,6 @@ struct ieee80211_tx_control {
|
||||
* @IEEE80211_HW_CONNECTION_MONITOR:
|
||||
* The hardware performs its own connection monitoring, including
|
||||
* periodic keep-alives to the AP and probing the AP on beacon loss.
|
||||
* When this flag is set, signaling beacon-loss will cause an immediate
|
||||
* change to disassociated state.
|
||||
*
|
||||
* @IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC:
|
||||
* This device needs to get data from beacon before association (i.e.
|
||||
@ -1644,10 +1638,6 @@ enum ieee80211_hw_flags {
|
||||
* the hw can report back.
|
||||
* @max_rate_tries: maximum number of tries for each stage
|
||||
*
|
||||
* @napi_weight: weight used for NAPI polling. You must specify an
|
||||
* appropriate value here if a napi_poll operation is provided
|
||||
* by your driver.
|
||||
*
|
||||
* @max_rx_aggregation_subframes: maximum buffer size (number of
|
||||
* sub-frames) to be used for A-MPDU block ack receiver
|
||||
* aggregation.
|
||||
@ -1701,7 +1691,6 @@ struct ieee80211_hw {
|
||||
int vif_data_size;
|
||||
int sta_data_size;
|
||||
int chanctx_data_size;
|
||||
int napi_weight;
|
||||
u16 queues;
|
||||
u16 max_listen_interval;
|
||||
s8 max_signal;
|
||||
@ -2471,6 +2460,7 @@ enum ieee80211_roc_type {
|
||||
* This process will continue until sched_scan_stop is called.
|
||||
*
|
||||
* @sched_scan_stop: Tell the hardware to stop an ongoing scheduled scan.
|
||||
* In this case, ieee80211_sched_scan_stopped() must not be called.
|
||||
*
|
||||
* @sw_scan_start: Notifier function that is called just before a software scan
|
||||
* is started. Can be NULL, if the driver doesn't need this notification.
|
||||
@ -2624,8 +2614,6 @@ enum ieee80211_roc_type {
|
||||
* callback. They must then call ieee80211_chswitch_done() to indicate
|
||||
* completion of the channel switch.
|
||||
*
|
||||
* @napi_poll: Poll Rx queue for incoming data frames.
|
||||
*
|
||||
* @set_antenna: Set antenna configuration (tx_ant, rx_ant) on the device.
|
||||
* Parameters are bitmaps of allowed antennas to use for TX/RX. Drivers may
|
||||
* reject TX/RX mask combinations they cannot support by returning -EINVAL
|
||||
@ -2820,7 +2808,7 @@ struct ieee80211_ops {
|
||||
struct ieee80211_vif *vif,
|
||||
struct cfg80211_sched_scan_request *req,
|
||||
struct ieee80211_sched_scan_ies *ies);
|
||||
void (*sched_scan_stop)(struct ieee80211_hw *hw,
|
||||
int (*sched_scan_stop)(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif);
|
||||
void (*sw_scan_start)(struct ieee80211_hw *hw);
|
||||
void (*sw_scan_complete)(struct ieee80211_hw *hw);
|
||||
@ -2884,7 +2872,6 @@ struct ieee80211_ops {
|
||||
void (*flush)(struct ieee80211_hw *hw, u32 queues, bool drop);
|
||||
void (*channel_switch)(struct ieee80211_hw *hw,
|
||||
struct ieee80211_channel_switch *ch_switch);
|
||||
int (*napi_poll)(struct ieee80211_hw *hw, int budget);
|
||||
int (*set_antenna)(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant);
|
||||
int (*get_antenna)(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
|
||||
|
||||
@ -3166,21 +3153,21 @@ void ieee80211_free_hw(struct ieee80211_hw *hw);
|
||||
*/
|
||||
void ieee80211_restart_hw(struct ieee80211_hw *hw);
|
||||
|
||||
/** ieee80211_napi_schedule - schedule NAPI poll
|
||||
/**
|
||||
* ieee80211_napi_add - initialize mac80211 NAPI context
|
||||
* @hw: the hardware to initialize the NAPI context on
|
||||
* @napi: the NAPI context to initialize
|
||||
* @napi_dev: dummy NAPI netdevice, here to not waste the space if the
|
||||
* driver doesn't use NAPI
|
||||
* @poll: poll function
|
||||
* @weight: default weight
|
||||
*
|
||||
* Use this function to schedule NAPI polling on a device.
|
||||
*
|
||||
* @hw: the hardware to start polling
|
||||
* See also netif_napi_add().
|
||||
*/
|
||||
void ieee80211_napi_schedule(struct ieee80211_hw *hw);
|
||||
|
||||
/** ieee80211_napi_complete - complete NAPI polling
|
||||
*
|
||||
* Use this function to finish NAPI polling on a device.
|
||||
*
|
||||
* @hw: the hardware to stop polling
|
||||
*/
|
||||
void ieee80211_napi_complete(struct ieee80211_hw *hw);
|
||||
void ieee80211_napi_add(struct ieee80211_hw *hw, struct napi_struct *napi,
|
||||
struct net_device *napi_dev,
|
||||
int (*poll)(struct napi_struct *, int),
|
||||
int weight);
|
||||
|
||||
/**
|
||||
* ieee80211_rx - receive frame
|
||||
|
@ -303,8 +303,9 @@
|
||||
* passed, all channels allowed for the current regulatory domain
|
||||
* are used. Extra IEs can also be passed from the userspace by
|
||||
* using the %NL80211_ATTR_IE attribute.
|
||||
* @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan. Returns -ENOENT
|
||||
* if scheduled scan is not running.
|
||||
* @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan. Returns -ENOENT if
|
||||
* scheduled scan is not running. The caller may assume that as soon
|
||||
* as the call returns, it is safe to start a new scheduled scan again.
|
||||
* @NL80211_CMD_SCHED_SCAN_RESULTS: indicates that there are scheduled scan
|
||||
* results available.
|
||||
* @NL80211_CMD_SCHED_SCAN_STOPPED: indicates that the scheduled scan has
|
||||
@ -1575,6 +1576,9 @@ enum nl80211_commands {
|
||||
* advertise values that cannot always be met. In such cases, an attempt
|
||||
* to add a new station entry with @NL80211_CMD_NEW_STATION may fail.
|
||||
*
|
||||
* @NL80211_ATTR_TDLS_PEER_CAPABILITY: flags for TDLS peer capabilities, u32.
|
||||
* As specified in the &enum nl80211_tdls_peer_capability.
|
||||
*
|
||||
* @NL80211_ATTR_MAX: highest attribute number currently defined
|
||||
* @__NL80211_ATTR_AFTER_LAST: internal use
|
||||
*/
|
||||
@ -1908,6 +1912,8 @@ enum nl80211_attrs {
|
||||
|
||||
NL80211_ATTR_MAX_AP_ASSOC_STA,
|
||||
|
||||
NL80211_ATTR_TDLS_PEER_CAPABILITY,
|
||||
|
||||
/* add attributes here, update the policy in nl80211.c */
|
||||
|
||||
__NL80211_ATTR_AFTER_LAST,
|
||||
@ -2437,10 +2443,7 @@ enum nl80211_reg_type {
|
||||
* in KHz. This is not a center a frequency but an actual regulatory
|
||||
* band edge.
|
||||
* @NL80211_ATTR_FREQ_RANGE_MAX_BW: maximum allowed bandwidth for this
|
||||
* frequency range, in KHz. If not present or 0, maximum available
|
||||
* bandwidth should be calculated base on contiguous rules and wider
|
||||
* channels will be allowed to cross multiple contiguous/overlapping
|
||||
* frequency ranges.
|
||||
* frequency range, in KHz.
|
||||
* @NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN: the maximum allowed antenna gain
|
||||
* for a given frequency range. The value is in mBi (100 * dBi).
|
||||
* If you don't have one then don't send this.
|
||||
@ -2511,6 +2514,9 @@ enum nl80211_sched_scan_match_attr {
|
||||
* @NL80211_RRF_NO_IR: no mechanisms that initiate radiation are allowed,
|
||||
* this includes probe requests or modes of operation that require
|
||||
* beaconing.
|
||||
* @NL80211_RRF_AUTO_BW: maximum available bandwidth should be calculated
|
||||
* base on contiguous rules and wider channels will be allowed to cross
|
||||
* multiple contiguous/overlapping frequency ranges.
|
||||
*/
|
||||
enum nl80211_reg_rule_flags {
|
||||
NL80211_RRF_NO_OFDM = 1<<0,
|
||||
@ -2522,6 +2528,7 @@ enum nl80211_reg_rule_flags {
|
||||
NL80211_RRF_PTMP_ONLY = 1<<6,
|
||||
NL80211_RRF_NO_IR = 1<<7,
|
||||
__NL80211_RRF_NO_IBSS = 1<<8,
|
||||
NL80211_RRF_AUTO_BW = 1<<11,
|
||||
};
|
||||
|
||||
#define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR
|
||||
@ -3843,11 +3850,6 @@ enum nl80211_ap_sme_features {
|
||||
* @NL80211_FEATURE_CELL_BASE_REG_HINTS: This driver has been tested
|
||||
* to work properly to suppport receiving regulatory hints from
|
||||
* cellular base stations.
|
||||
* @NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL: If this is set, an active
|
||||
* P2P Device (%NL80211_IFTYPE_P2P_DEVICE) requires its own channel
|
||||
* in the interface combinations, even when it's only used for scan
|
||||
* and remain-on-channel. This could be due to, for example, the
|
||||
* remain-on-channel implementation requiring a channel context.
|
||||
* @NL80211_FEATURE_SAE: This driver supports simultaneous authentication of
|
||||
* equals (SAE) with user space SME (NL80211_CMD_AUTHENTICATE) in station
|
||||
* mode
|
||||
@ -3889,7 +3891,7 @@ enum nl80211_feature_flags {
|
||||
NL80211_FEATURE_HT_IBSS = 1 << 1,
|
||||
NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2,
|
||||
NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3,
|
||||
NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL = 1 << 4,
|
||||
/* bit 4 is reserved - don't use */
|
||||
NL80211_FEATURE_SAE = 1 << 5,
|
||||
NL80211_FEATURE_LOW_PRIORITY_SCAN = 1 << 6,
|
||||
NL80211_FEATURE_SCAN_FLUSH = 1 << 7,
|
||||
@ -4079,4 +4081,20 @@ struct nl80211_vendor_cmd_info {
|
||||
__u32 subcmd;
|
||||
};
|
||||
|
||||
/**
|
||||
* enum nl80211_tdls_peer_capability - TDLS peer flags.
|
||||
*
|
||||
* Used by tdls_mgmt() to determine which conditional elements need
|
||||
* to be added to TDLS Setup frames.
|
||||
*
|
||||
* @NL80211_TDLS_PEER_HT: TDLS peer is HT capable.
|
||||
* @NL80211_TDLS_PEER_VHT: TDLS peer is VHT capable.
|
||||
* @NL80211_TDLS_PEER_WMM: TDLS peer is WMM capable.
|
||||
*/
|
||||
enum nl80211_tdls_peer_capability {
|
||||
NL80211_TDLS_PEER_HT = 1<<0,
|
||||
NL80211_TDLS_PEER_VHT = 1<<1,
|
||||
NL80211_TDLS_PEER_WMM = 1<<2,
|
||||
};
|
||||
|
||||
#endif /* __LINUX_NL80211_H */
|
||||
|
@ -1347,9 +1347,6 @@ static int sta_apply_parameters(struct ieee80211_local *local,
|
||||
params->vht_capa, sta);
|
||||
|
||||
if (params->opmode_notif_used) {
|
||||
enum ieee80211_band band =
|
||||
ieee80211_get_sdata_band(sdata);
|
||||
|
||||
/* returned value is only needed for rc update, but the
|
||||
* rc isn't initialized here yet, so ignore it
|
||||
*/
|
||||
@ -3647,8 +3644,8 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
|
||||
|
||||
static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
|
||||
u8 *peer, u8 action_code, u8 dialog_token,
|
||||
u16 status_code, const u8 *extra_ies,
|
||||
size_t extra_ies_len)
|
||||
u16 status_code, u32 peer_capability,
|
||||
const u8 *extra_ies, size_t extra_ies_len)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
|
@ -358,6 +358,18 @@ static ssize_t ieee80211_if_parse_tkip_mic_test(
|
||||
}
|
||||
IEEE80211_IF_FILE_W(tkip_mic_test);
|
||||
|
||||
static ssize_t ieee80211_if_parse_beacon_loss(
|
||||
struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
|
||||
{
|
||||
if (!ieee80211_sdata_running(sdata) || !sdata->vif.bss_conf.assoc)
|
||||
return -ENOTCONN;
|
||||
|
||||
ieee80211_beacon_loss(&sdata->vif);
|
||||
|
||||
return buflen;
|
||||
}
|
||||
IEEE80211_IF_FILE_W(beacon_loss);
|
||||
|
||||
static ssize_t ieee80211_if_fmt_uapsd_queues(
|
||||
const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
|
||||
{
|
||||
@ -569,6 +581,7 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
|
||||
DEBUGFS_ADD(beacon_timeout);
|
||||
DEBUGFS_ADD_MODE(smps, 0600);
|
||||
DEBUGFS_ADD_MODE(tkip_mic_test, 0200);
|
||||
DEBUGFS_ADD_MODE(beacon_loss, 0200);
|
||||
DEBUGFS_ADD_MODE(uapsd_queues, 0600);
|
||||
DEBUGFS_ADD_MODE(uapsd_max_sp_len, 0600);
|
||||
}
|
||||
|
@ -354,16 +354,20 @@ drv_sched_scan_start(struct ieee80211_local *local,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void drv_sched_scan_stop(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata)
|
||||
static inline int drv_sched_scan_stop(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
int ret;
|
||||
|
||||
might_sleep();
|
||||
|
||||
check_sdata_in_driver(sdata);
|
||||
|
||||
trace_drv_sched_scan_stop(local, sdata);
|
||||
local->ops->sched_scan_stop(&local->hw, &sdata->vif);
|
||||
trace_drv_return_void(local);
|
||||
ret = local->ops->sched_scan_stop(&local->hw, &sdata->vif);
|
||||
trace_drv_return_int(local, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void drv_sw_scan_start(struct ieee80211_local *local)
|
||||
|
@ -482,8 +482,6 @@ void ieee80211_request_smps(struct ieee80211_vif *vif,
|
||||
return;
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION) {
|
||||
if (WARN_ON(smps_mode == IEEE80211_SMPS_OFF))
|
||||
smps_mode = IEEE80211_SMPS_AUTOMATIC;
|
||||
if (sdata->u.mgd.driver_smps_mode == smps_mode)
|
||||
return;
|
||||
sdata->u.mgd.driver_smps_mode = smps_mode;
|
||||
|
@ -283,6 +283,11 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
err = cfg80211_chandef_dfs_required(sdata->local->hw.wiphy,
|
||||
&chandef);
|
||||
if (err < 0) {
|
||||
sdata_info(sdata,
|
||||
"Failed to join IBSS, invalid chandef\n");
|
||||
return;
|
||||
}
|
||||
if (err > 0) {
|
||||
if (!ifibss->userspace_handles_dfs) {
|
||||
sdata_info(sdata,
|
||||
|
@ -1242,6 +1242,8 @@ struct ieee80211_local {
|
||||
|
||||
struct ieee80211_sub_if_data __rcu *p2p_sdata;
|
||||
|
||||
struct napi_struct *napi;
|
||||
|
||||
/* virtual monitor interface */
|
||||
struct ieee80211_sub_if_data __rcu *monitor_sdata;
|
||||
struct cfg80211_chan_def monitor_chandef;
|
||||
|
@ -101,9 +101,8 @@ static u32 __ieee80211_idle_on(struct ieee80211_local *local)
|
||||
static u32 __ieee80211_recalc_idle(struct ieee80211_local *local,
|
||||
bool force_active)
|
||||
{
|
||||
bool working = false, scanning, active;
|
||||
bool working, scanning, active;
|
||||
unsigned int led_trig_start = 0, led_trig_stop = 0;
|
||||
struct ieee80211_roc_work *roc;
|
||||
|
||||
lockdep_assert_held(&local->mtx);
|
||||
|
||||
@ -111,12 +110,8 @@ static u32 __ieee80211_recalc_idle(struct ieee80211_local *local,
|
||||
!list_empty(&local->chanctx_list) ||
|
||||
local->monitors;
|
||||
|
||||
if (!local->ops->remain_on_channel) {
|
||||
list_for_each_entry(roc, &local->roc_list, list) {
|
||||
working = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
working = !local->ops->remain_on_channel &&
|
||||
!list_empty(&local->roc_list);
|
||||
|
||||
scanning = test_bit(SCAN_SW_SCANNING, &local->scanning) ||
|
||||
test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning);
|
||||
|
@ -1076,6 +1076,18 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_register_hw);
|
||||
|
||||
void ieee80211_napi_add(struct ieee80211_hw *hw, struct napi_struct *napi,
|
||||
struct net_device *napi_dev,
|
||||
int (*poll)(struct napi_struct *, int),
|
||||
int weight)
|
||||
{
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
|
||||
netif_napi_add(napi_dev, napi, poll, weight);
|
||||
local->napi = napi;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ieee80211_napi_add);
|
||||
|
||||
void ieee80211_unregister_hw(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
|
@ -131,13 +131,13 @@ void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata)
|
||||
if (unlikely(!sdata->u.mgd.associated))
|
||||
return;
|
||||
|
||||
ifmgd->probe_send_count = 0;
|
||||
|
||||
if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
|
||||
return;
|
||||
|
||||
mod_timer(&sdata->u.mgd.conn_mon_timer,
|
||||
round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME));
|
||||
|
||||
ifmgd->probe_send_count = 0;
|
||||
}
|
||||
|
||||
static int ecw2cw(int ecw)
|
||||
@ -2249,6 +2249,62 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
|
||||
/* ignore frame -- wait for timeout */
|
||||
}
|
||||
|
||||
#define case_WLAN(type) \
|
||||
case WLAN_REASON_##type: return #type
|
||||
|
||||
static const char *ieee80211_get_reason_code_string(u16 reason_code)
|
||||
{
|
||||
switch (reason_code) {
|
||||
case_WLAN(UNSPECIFIED);
|
||||
case_WLAN(PREV_AUTH_NOT_VALID);
|
||||
case_WLAN(DEAUTH_LEAVING);
|
||||
case_WLAN(DISASSOC_DUE_TO_INACTIVITY);
|
||||
case_WLAN(DISASSOC_AP_BUSY);
|
||||
case_WLAN(CLASS2_FRAME_FROM_NONAUTH_STA);
|
||||
case_WLAN(CLASS3_FRAME_FROM_NONASSOC_STA);
|
||||
case_WLAN(DISASSOC_STA_HAS_LEFT);
|
||||
case_WLAN(STA_REQ_ASSOC_WITHOUT_AUTH);
|
||||
case_WLAN(DISASSOC_BAD_POWER);
|
||||
case_WLAN(DISASSOC_BAD_SUPP_CHAN);
|
||||
case_WLAN(INVALID_IE);
|
||||
case_WLAN(MIC_FAILURE);
|
||||
case_WLAN(4WAY_HANDSHAKE_TIMEOUT);
|
||||
case_WLAN(GROUP_KEY_HANDSHAKE_TIMEOUT);
|
||||
case_WLAN(IE_DIFFERENT);
|
||||
case_WLAN(INVALID_GROUP_CIPHER);
|
||||
case_WLAN(INVALID_PAIRWISE_CIPHER);
|
||||
case_WLAN(INVALID_AKMP);
|
||||
case_WLAN(UNSUPP_RSN_VERSION);
|
||||
case_WLAN(INVALID_RSN_IE_CAP);
|
||||
case_WLAN(IEEE8021X_FAILED);
|
||||
case_WLAN(CIPHER_SUITE_REJECTED);
|
||||
case_WLAN(DISASSOC_UNSPECIFIED_QOS);
|
||||
case_WLAN(DISASSOC_QAP_NO_BANDWIDTH);
|
||||
case_WLAN(DISASSOC_LOW_ACK);
|
||||
case_WLAN(DISASSOC_QAP_EXCEED_TXOP);
|
||||
case_WLAN(QSTA_LEAVE_QBSS);
|
||||
case_WLAN(QSTA_NOT_USE);
|
||||
case_WLAN(QSTA_REQUIRE_SETUP);
|
||||
case_WLAN(QSTA_TIMEOUT);
|
||||
case_WLAN(QSTA_CIPHER_NOT_SUPP);
|
||||
case_WLAN(MESH_PEER_CANCELED);
|
||||
case_WLAN(MESH_MAX_PEERS);
|
||||
case_WLAN(MESH_CONFIG);
|
||||
case_WLAN(MESH_CLOSE);
|
||||
case_WLAN(MESH_MAX_RETRIES);
|
||||
case_WLAN(MESH_CONFIRM_TIMEOUT);
|
||||
case_WLAN(MESH_INVALID_GTK);
|
||||
case_WLAN(MESH_INCONSISTENT_PARAM);
|
||||
case_WLAN(MESH_INVALID_SECURITY);
|
||||
case_WLAN(MESH_PATH_ERROR);
|
||||
case_WLAN(MESH_PATH_NOFORWARD);
|
||||
case_WLAN(MESH_PATH_DEST_UNREACHABLE);
|
||||
case_WLAN(MAC_EXISTS_IN_MBSS);
|
||||
case_WLAN(MESH_CHAN_REGULATORY);
|
||||
case_WLAN(MESH_CHAN);
|
||||
default: return "<unknown>";
|
||||
}
|
||||
}
|
||||
|
||||
static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_mgmt *mgmt, size_t len)
|
||||
@ -2270,8 +2326,8 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
|
||||
|
||||
sdata_info(sdata, "deauthenticated from %pM (Reason: %u)\n",
|
||||
bssid, reason_code);
|
||||
sdata_info(sdata, "deauthenticated from %pM (Reason: %u=%s)\n",
|
||||
bssid, reason_code, ieee80211_get_reason_code_string(reason_code));
|
||||
|
||||
ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
|
||||
|
||||
@ -4340,8 +4396,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
|
||||
bool report_frame = false;
|
||||
|
||||
sdata_info(sdata,
|
||||
"deauthenticating from %pM by local choice (reason=%d)\n",
|
||||
req->bssid, req->reason_code);
|
||||
"deauthenticating from %pM by local choice (Reason: %u=%s)\n",
|
||||
req->bssid, req->reason_code, ieee80211_get_reason_code_string(req->reason_code));
|
||||
|
||||
if (ifmgd->auth_data) {
|
||||
drv_mgd_prepare_tx(sdata->local, sdata);
|
||||
@ -4387,8 +4443,8 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
|
||||
return -ENOLINK;
|
||||
|
||||
sdata_info(sdata,
|
||||
"disassociating from %pM by local choice (reason=%d)\n",
|
||||
req->bss->bssid, req->reason_code);
|
||||
"disassociating from %pM by local choice (Reason: %u=%s)\n",
|
||||
req->bss->bssid, req->reason_code, ieee80211_get_reason_code_string(req->reason_code));
|
||||
|
||||
memcpy(bssid, req->bss->bssid, ETH_ALEN);
|
||||
ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC,
|
||||
|
@ -1954,7 +1954,10 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
|
||||
/* deliver to local stack */
|
||||
skb->protocol = eth_type_trans(skb, dev);
|
||||
memset(skb->cb, 0, sizeof(skb->cb));
|
||||
netif_receive_skb(skb);
|
||||
if (rx->local->napi)
|
||||
napi_gro_receive(rx->local->napi, skb);
|
||||
else
|
||||
netif_receive_skb(skb);
|
||||
}
|
||||
|
||||
if (xmit_skb) {
|
||||
|
@ -472,9 +472,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
|
||||
if (local->ops->hw_scan) {
|
||||
u8 *ies;
|
||||
|
||||
local->hw_scan_ies_bufsize = 2 + IEEE80211_MAX_SSID_LEN +
|
||||
local->scan_ies_len +
|
||||
req->ie_len;
|
||||
local->hw_scan_ies_bufsize = local->scan_ies_len + req->ie_len;
|
||||
local->hw_scan_req = kmalloc(
|
||||
sizeof(*local->hw_scan_req) +
|
||||
req->n_channels * sizeof(req->channels[0]) +
|
||||
@ -979,8 +977,7 @@ int __ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
|
||||
struct cfg80211_chan_def chandef;
|
||||
int ret, i, iebufsz;
|
||||
|
||||
iebufsz = 2 + IEEE80211_MAX_SSID_LEN +
|
||||
local->scan_ies_len + req->ie_len;
|
||||
iebufsz = local->scan_ies_len + req->ie_len;
|
||||
|
||||
lockdep_assert_held(&local->mtx);
|
||||
|
||||
@ -1059,7 +1056,7 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata)
|
||||
local->sched_scan_req = NULL;
|
||||
|
||||
if (rcu_access_pointer(local->sched_scan_sdata))
|
||||
drv_sched_scan_stop(local, sdata);
|
||||
ret = drv_sched_scan_stop(local, sdata);
|
||||
|
||||
out:
|
||||
mutex_unlock(&local->mtx);
|
||||
|
@ -705,12 +705,8 @@ cfg80211_get_chan_state(struct wireless_dev *wdev,
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
case NL80211_IFTYPE_AP_VLAN:
|
||||
case NL80211_IFTYPE_WDS:
|
||||
/* these interface types don't really have a channel */
|
||||
return;
|
||||
case NL80211_IFTYPE_P2P_DEVICE:
|
||||
if (wdev->wiphy->features &
|
||||
NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL)
|
||||
*chanmode = CHAN_MODE_EXCLUSIVE;
|
||||
/* these interface types don't really have a channel */
|
||||
return;
|
||||
case NL80211_IFTYPE_UNSPECIFIED:
|
||||
case NUM_NL80211_IFTYPES:
|
||||
|
@ -105,6 +105,8 @@ function parse_reg_rule()
|
||||
flags = flags "\n\t\t\tNL80211_RRF_NO_IR | "
|
||||
} else if (flagarray[arg] == "NO-IR") {
|
||||
flags = flags "\n\t\t\tNL80211_RRF_NO_IR | "
|
||||
} else if (flagarray[arg] == "AUTO-BW") {
|
||||
flags = flags "\n\t\t\tNL80211_RRF_AUTO_BW | "
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -128,12 +128,11 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
|
||||
#endif
|
||||
check_chan = params->chandef.chan;
|
||||
if (params->userspace_handles_dfs) {
|
||||
/* use channel NULL to check for radar even if the current
|
||||
* channel is not a radar channel - it might decide to change
|
||||
* to DFS channel later.
|
||||
/* Check for radar even if the current channel is not
|
||||
* a radar channel - it might decide to change to DFS
|
||||
* channel later.
|
||||
*/
|
||||
radar_detect_width = BIT(params->chandef.width);
|
||||
check_chan = NULL;
|
||||
}
|
||||
|
||||
err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
|
||||
|
@ -236,6 +236,12 @@ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
|
||||
if (!netif_running(wdev->netdev))
|
||||
return -ENETDOWN;
|
||||
|
||||
/* cfg80211_can_use_chan() calls
|
||||
* cfg80211_can_use_iftype_chan() with no radar
|
||||
* detection, so if we're trying to use a radar
|
||||
* channel here, something is wrong.
|
||||
*/
|
||||
WARN_ON_ONCE(chandef->chan->flags & IEEE80211_CHAN_RADAR);
|
||||
err = cfg80211_can_use_chan(rdev, wdev, chandef->chan,
|
||||
CHAN_MODE_SHARED);
|
||||
if (err)
|
||||
|
@ -384,6 +384,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
|
||||
.len = IEEE80211_QOS_MAP_LEN_MAX },
|
||||
[NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN },
|
||||
[NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
/* policy for the key attributes */
|
||||
@ -4627,6 +4628,8 @@ static int parse_reg_rule(struct nlattr *tb[],
|
||||
return -EINVAL;
|
||||
if (!tb[NL80211_ATTR_FREQ_RANGE_END])
|
||||
return -EINVAL;
|
||||
if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
|
||||
return -EINVAL;
|
||||
if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
|
||||
return -EINVAL;
|
||||
|
||||
@ -4636,9 +4639,8 @@ static int parse_reg_rule(struct nlattr *tb[],
|
||||
nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
|
||||
freq_range->end_freq_khz =
|
||||
nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
|
||||
if (tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
|
||||
freq_range->max_bandwidth_khz =
|
||||
nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
|
||||
freq_range->max_bandwidth_khz =
|
||||
nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
|
||||
|
||||
power_rule->max_eirp =
|
||||
nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
|
||||
@ -5710,8 +5712,8 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
|
||||
request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF;
|
||||
}
|
||||
|
||||
if (info->attrs[NL80211_ATTR_IE]) {
|
||||
request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
|
||||
if (ie_len) {
|
||||
request->ie_len = ie_len;
|
||||
memcpy((void *)request->ie,
|
||||
nla_data(info->attrs[NL80211_ATTR_IE]),
|
||||
request->ie_len);
|
||||
@ -5911,17 +5913,22 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
|
||||
if (!cfg80211_reg_can_beacon(&rdev->wiphy, ¶ms.chandef))
|
||||
return -EINVAL;
|
||||
|
||||
if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP ||
|
||||
dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO ||
|
||||
dev->ieee80211_ptr->iftype == NL80211_IFTYPE_ADHOC) {
|
||||
switch (dev->ieee80211_ptr->iftype) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
err = cfg80211_chandef_dfs_required(wdev->wiphy,
|
||||
¶ms.chandef);
|
||||
if (err < 0) {
|
||||
if (err < 0)
|
||||
return err;
|
||||
} else if (err) {
|
||||
if (err) {
|
||||
radar_detect_width = BIT(params.chandef.width);
|
||||
params.radar_required = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
|
||||
@ -7269,6 +7276,7 @@ static int nl80211_tdls_mgmt(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];
|
||||
u8 action_code, dialog_token;
|
||||
u32 peer_capability = 0;
|
||||
u16 status_code;
|
||||
u8 *peer;
|
||||
|
||||
@ -7287,9 +7295,12 @@ static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
|
||||
action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]);
|
||||
status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
|
||||
dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]);
|
||||
if (info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY])
|
||||
peer_capability =
|
||||
nla_get_u32(info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]);
|
||||
|
||||
return rdev_tdls_mgmt(rdev, dev, peer, action_code,
|
||||
dialog_token, status_code,
|
||||
dialog_token, status_code, peer_capability,
|
||||
nla_data(info->attrs[NL80211_ATTR_IE]),
|
||||
nla_len(info->attrs[NL80211_ATTR_IE]));
|
||||
}
|
||||
|
@ -769,13 +769,16 @@ static inline int rdev_set_rekey_data(struct cfg80211_registered_device *rdev,
|
||||
static inline int rdev_tdls_mgmt(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev, u8 *peer,
|
||||
u8 action_code, u8 dialog_token,
|
||||
u16 status_code, const u8 *buf, size_t len)
|
||||
u16 status_code, u32 peer_capability,
|
||||
const u8 *buf, size_t len)
|
||||
{
|
||||
int ret;
|
||||
trace_rdev_tdls_mgmt(&rdev->wiphy, dev, peer, action_code,
|
||||
dialog_token, status_code, buf, len);
|
||||
dialog_token, status_code, peer_capability,
|
||||
buf, len);
|
||||
ret = rdev->ops->tdls_mgmt(&rdev->wiphy, dev, peer, action_code,
|
||||
dialog_token, status_code, buf, len);
|
||||
dialog_token, status_code, peer_capability,
|
||||
buf, len);
|
||||
trace_rdev_return_int(&rdev->wiphy, ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -563,9 +563,6 @@ unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd,
|
||||
if (freq_range_tmp->end_freq_khz < freq_range->start_freq_khz)
|
||||
break;
|
||||
|
||||
if (freq_range_tmp->max_bandwidth_khz)
|
||||
break;
|
||||
|
||||
freq_range = freq_range_tmp;
|
||||
}
|
||||
|
||||
@ -582,9 +579,6 @@ unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd,
|
||||
if (freq_range_tmp->start_freq_khz > freq_range->end_freq_khz)
|
||||
break;
|
||||
|
||||
if (freq_range_tmp->max_bandwidth_khz)
|
||||
break;
|
||||
|
||||
freq_range = freq_range_tmp;
|
||||
}
|
||||
|
||||
@ -729,21 +723,29 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1,
|
||||
max_bandwidth1 = freq_range1->max_bandwidth_khz;
|
||||
max_bandwidth2 = freq_range2->max_bandwidth_khz;
|
||||
|
||||
/*
|
||||
* In case max_bandwidth1 == 0 and max_bandwith2 == 0 set
|
||||
* output bandwidth as 0 (auto calculation). Next we will
|
||||
* calculate this correctly in handle_channel function.
|
||||
* In other case calculate output bandwidth here.
|
||||
*/
|
||||
if (max_bandwidth1 || max_bandwidth2) {
|
||||
if (!max_bandwidth1)
|
||||
max_bandwidth1 = reg_get_max_bandwidth(rd1, rule1);
|
||||
if (!max_bandwidth2)
|
||||
max_bandwidth2 = reg_get_max_bandwidth(rd2, rule2);
|
||||
}
|
||||
if (rule1->flags & NL80211_RRF_AUTO_BW)
|
||||
max_bandwidth1 = reg_get_max_bandwidth(rd1, rule1);
|
||||
if (rule2->flags & NL80211_RRF_AUTO_BW)
|
||||
max_bandwidth2 = reg_get_max_bandwidth(rd2, rule2);
|
||||
|
||||
freq_range->max_bandwidth_khz = min(max_bandwidth1, max_bandwidth2);
|
||||
|
||||
intersected_rule->flags = rule1->flags | rule2->flags;
|
||||
|
||||
/*
|
||||
* In case NL80211_RRF_AUTO_BW requested for both rules
|
||||
* set AUTO_BW in intersected rule also. Next we will
|
||||
* calculate BW correctly in handle_channel function.
|
||||
* In other case remove AUTO_BW flag while we calculate
|
||||
* maximum bandwidth correctly and auto calculation is
|
||||
* not required.
|
||||
*/
|
||||
if ((rule1->flags & NL80211_RRF_AUTO_BW) &&
|
||||
(rule2->flags & NL80211_RRF_AUTO_BW))
|
||||
intersected_rule->flags |= NL80211_RRF_AUTO_BW;
|
||||
else
|
||||
intersected_rule->flags &= ~NL80211_RRF_AUTO_BW;
|
||||
|
||||
freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;
|
||||
if (freq_range->max_bandwidth_khz > freq_diff)
|
||||
freq_range->max_bandwidth_khz = freq_diff;
|
||||
@ -753,8 +755,6 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1,
|
||||
power_rule->max_antenna_gain = min(power_rule1->max_antenna_gain,
|
||||
power_rule2->max_antenna_gain);
|
||||
|
||||
intersected_rule->flags = rule1->flags | rule2->flags;
|
||||
|
||||
if (!is_valid_reg_rule(intersected_rule))
|
||||
return -EINVAL;
|
||||
|
||||
@ -938,31 +938,42 @@ const char *reg_initiator_name(enum nl80211_reg_initiator initiator)
|
||||
EXPORT_SYMBOL(reg_initiator_name);
|
||||
|
||||
#ifdef CONFIG_CFG80211_REG_DEBUG
|
||||
static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan,
|
||||
static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd,
|
||||
struct ieee80211_channel *chan,
|
||||
const struct ieee80211_reg_rule *reg_rule)
|
||||
{
|
||||
const struct ieee80211_power_rule *power_rule;
|
||||
const struct ieee80211_freq_range *freq_range;
|
||||
char max_antenna_gain[32];
|
||||
char max_antenna_gain[32], bw[32];
|
||||
|
||||
power_rule = ®_rule->power_rule;
|
||||
freq_range = ®_rule->freq_range;
|
||||
|
||||
if (!power_rule->max_antenna_gain)
|
||||
snprintf(max_antenna_gain, 32, "N/A");
|
||||
snprintf(max_antenna_gain, sizeof(max_antenna_gain), "N/A");
|
||||
else
|
||||
snprintf(max_antenna_gain, 32, "%d", power_rule->max_antenna_gain);
|
||||
snprintf(max_antenna_gain, sizeof(max_antenna_gain), "%d",
|
||||
power_rule->max_antenna_gain);
|
||||
|
||||
if (reg_rule->flags & NL80211_RRF_AUTO_BW)
|
||||
snprintf(bw, sizeof(bw), "%d KHz, %d KHz AUTO",
|
||||
freq_range->max_bandwidth_khz,
|
||||
reg_get_max_bandwidth(regd, reg_rule));
|
||||
else
|
||||
snprintf(bw, sizeof(bw), "%d KHz",
|
||||
freq_range->max_bandwidth_khz);
|
||||
|
||||
REG_DBG_PRINT("Updating information on frequency %d MHz with regulatory rule:\n",
|
||||
chan->center_freq);
|
||||
|
||||
REG_DBG_PRINT("%d KHz - %d KHz @ %d KHz), (%s mBi, %d mBm)\n",
|
||||
REG_DBG_PRINT("%d KHz - %d KHz @ %s), (%s mBi, %d mBm)\n",
|
||||
freq_range->start_freq_khz, freq_range->end_freq_khz,
|
||||
freq_range->max_bandwidth_khz, max_antenna_gain,
|
||||
bw, max_antenna_gain,
|
||||
power_rule->max_eirp);
|
||||
}
|
||||
#else
|
||||
static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan,
|
||||
static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd,
|
||||
struct ieee80211_channel *chan,
|
||||
const struct ieee80211_reg_rule *reg_rule)
|
||||
{
|
||||
return;
|
||||
@ -1022,17 +1033,16 @@ static void handle_channel(struct wiphy *wiphy,
|
||||
return;
|
||||
}
|
||||
|
||||
chan_reg_rule_print_dbg(chan, reg_rule);
|
||||
regd = reg_get_regdomain(wiphy);
|
||||
chan_reg_rule_print_dbg(regd, chan, reg_rule);
|
||||
|
||||
power_rule = ®_rule->power_rule;
|
||||
freq_range = ®_rule->freq_range;
|
||||
|
||||
max_bandwidth_khz = freq_range->max_bandwidth_khz;
|
||||
/* Check if auto calculation requested */
|
||||
if (!max_bandwidth_khz) {
|
||||
regd = reg_get_regdomain(wiphy);
|
||||
if (reg_rule->flags & NL80211_RRF_AUTO_BW)
|
||||
max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule);
|
||||
}
|
||||
|
||||
if (max_bandwidth_khz < MHZ_TO_KHZ(40))
|
||||
bw_flags = IEEE80211_CHAN_NO_HT40;
|
||||
@ -1437,14 +1447,14 @@ static void handle_channel_custom(struct wiphy *wiphy,
|
||||
return;
|
||||
}
|
||||
|
||||
chan_reg_rule_print_dbg(chan, reg_rule);
|
||||
chan_reg_rule_print_dbg(regd, chan, reg_rule);
|
||||
|
||||
power_rule = ®_rule->power_rule;
|
||||
freq_range = ®_rule->freq_range;
|
||||
|
||||
max_bandwidth_khz = freq_range->max_bandwidth_khz;
|
||||
/* Check if auto calculation requested */
|
||||
if (!max_bandwidth_khz)
|
||||
if (reg_rule->flags & NL80211_RRF_AUTO_BW)
|
||||
max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule);
|
||||
|
||||
if (max_bandwidth_khz < MHZ_TO_KHZ(40))
|
||||
@ -2254,11 +2264,12 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
|
||||
freq_range = ®_rule->freq_range;
|
||||
power_rule = ®_rule->power_rule;
|
||||
|
||||
if (!freq_range->max_bandwidth_khz)
|
||||
snprintf(bw, 32, "%d KHz, AUTO",
|
||||
if (reg_rule->flags & NL80211_RRF_AUTO_BW)
|
||||
snprintf(bw, sizeof(bw), "%d KHz, %d KHz AUTO",
|
||||
freq_range->max_bandwidth_khz,
|
||||
reg_get_max_bandwidth(rd, reg_rule));
|
||||
else
|
||||
snprintf(bw, 32, "%d KHz",
|
||||
snprintf(bw, sizeof(bw), "%d KHz",
|
||||
freq_range->max_bandwidth_khz);
|
||||
|
||||
/*
|
||||
|
@ -1468,9 +1468,10 @@ TRACE_EVENT(rdev_sched_scan_start,
|
||||
TRACE_EVENT(rdev_tdls_mgmt,
|
||||
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
|
||||
u8 *peer, u8 action_code, u8 dialog_token,
|
||||
u16 status_code, const u8 *buf, size_t len),
|
||||
u16 status_code, u32 peer_capability,
|
||||
const u8 *buf, size_t len),
|
||||
TP_ARGS(wiphy, netdev, peer, action_code, dialog_token, status_code,
|
||||
buf, len),
|
||||
peer_capability, buf, len),
|
||||
TP_STRUCT__entry(
|
||||
WIPHY_ENTRY
|
||||
NETDEV_ENTRY
|
||||
@ -1478,6 +1479,7 @@ TRACE_EVENT(rdev_tdls_mgmt,
|
||||
__field(u8, action_code)
|
||||
__field(u8, dialog_token)
|
||||
__field(u16, status_code)
|
||||
__field(u32, peer_capability)
|
||||
__dynamic_array(u8, buf, len)
|
||||
),
|
||||
TP_fast_assign(
|
||||
@ -1487,13 +1489,15 @@ TRACE_EVENT(rdev_tdls_mgmt,
|
||||
__entry->action_code = action_code;
|
||||
__entry->dialog_token = dialog_token;
|
||||
__entry->status_code = status_code;
|
||||
__entry->peer_capability = peer_capability;
|
||||
memcpy(__get_dynamic_array(buf), buf, len);
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ", action_code: %u, "
|
||||
"dialog_token: %u, status_code: %u, buf: %#.2x ",
|
||||
"dialog_token: %u, status_code: %u, peer_capability: %u buf: %#.2x ",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer),
|
||||
__entry->action_code, __entry->dialog_token,
|
||||
__entry->status_code, ((u8 *)__get_dynamic_array(buf))[0])
|
||||
__entry->status_code, __entry->peer_capability,
|
||||
((u8 *)__get_dynamic_array(buf))[0])
|
||||
);
|
||||
|
||||
TRACE_EVENT(rdev_dump_survey,
|
||||
|
@ -1269,7 +1269,6 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
|
||||
enum cfg80211_chan_mode chmode;
|
||||
int num_different_channels = 0;
|
||||
int total = 1;
|
||||
bool radar_required = false;
|
||||
int i, j;
|
||||
|
||||
ASSERT_RTNL();
|
||||
@ -1277,35 +1276,7 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
|
||||
if (WARN_ON(hweight32(radar_detect) > 1))
|
||||
return -EINVAL;
|
||||
|
||||
switch (iftype) {
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
case NL80211_IFTYPE_AP:
|
||||
case NL80211_IFTYPE_AP_VLAN:
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
case NL80211_IFTYPE_WDS:
|
||||
/* if the interface could potentially choose a DFS channel,
|
||||
* then mark DFS as required.
|
||||
*/
|
||||
if (!chan) {
|
||||
if (chanmode != CHAN_MODE_UNDEFINED && radar_detect)
|
||||
radar_required = true;
|
||||
break;
|
||||
}
|
||||
radar_required = !!(chan->flags & IEEE80211_CHAN_RADAR);
|
||||
break;
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
case NL80211_IFTYPE_STATION:
|
||||
case NL80211_IFTYPE_P2P_DEVICE:
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
break;
|
||||
case NUM_NL80211_IFTYPES:
|
||||
case NL80211_IFTYPE_UNSPECIFIED:
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (radar_required && !radar_detect)
|
||||
if (WARN_ON(iftype >= NUM_NL80211_IFTYPES))
|
||||
return -EINVAL;
|
||||
|
||||
/* Always allow software iftypes */
|
||||
|
Loading…
Reference in New Issue
Block a user