Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
This commit is contained in:
		
				commit
				
					
						c77986c78a
					
				
			
		
					 29 changed files with 312 additions and 189 deletions
				
			
		| 
						 | 
				
			
			@ -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,7 +1746,7 @@ out:
 | 
			
		|||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw,
 | 
			
		||||
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);
 | 
			
		||||
| 
						 | 
				
			
			@ -1754,6 +1754,8 @@ static void iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *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,7 +3668,7 @@ out:
 | 
			
		|||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void wl1271_op_sched_scan_stop(struct ieee80211_hw *hw,
 | 
			
		||||
static int wl1271_op_sched_scan_stop(struct ieee80211_hw *hw,
 | 
			
		||||
				     struct ieee80211_vif *vif)
 | 
			
		||||
{
 | 
			
		||||
	struct wl1271 *wl = hw->priv;
 | 
			
		||||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
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,6 +1954,9 @@ 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));
 | 
			
		||||
		if (rx->local->napi)
 | 
			
		||||
			napi_gro_receive(rx->local->napi, skb);
 | 
			
		||||
		else
 | 
			
		||||
			netif_receive_skb(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,7 +4639,6 @@ 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]);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -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 @@ skip_beacons:
 | 
			
		|||
	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)
 | 
			
		||||
	if (rule1->flags & NL80211_RRF_AUTO_BW)
 | 
			
		||||
		max_bandwidth1 = reg_get_max_bandwidth(rd1, rule1);
 | 
			
		||||
		if (!max_bandwidth2)
 | 
			
		||||
	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…
	
	Add table
		Add a link
		
	
		Reference in a new issue