Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next

This commit is contained in:
John W. Linville 2014-02-24 15:03:32 -05:00
commit c77986c78a
29 changed files with 312 additions and 189 deletions

View File

@ -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>

View File

@ -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,

View File

@ -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;
}

View File

@ -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)

View File

@ -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;

View File

@ -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)

View File

@ -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.

View File

@ -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

View File

@ -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 */

View File

@ -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;

View File

@ -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);
}

View File

@ -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)

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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) {

View File

@ -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);

View File

@ -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:

View File

@ -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 | "
}
}

View File

@ -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,

View File

@ -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)

View File

@ -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, &params.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,
&params.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]));
}

View File

@ -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;
}

View File

@ -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 = &reg_rule->power_rule;
freq_range = &reg_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 = &reg_rule->power_rule;
freq_range = &reg_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 = &reg_rule->power_rule;
freq_range = &reg_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 = &reg_rule->freq_range;
power_rule = &reg_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);
/*

View File

@ -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,

View File

@ -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 */