Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e9517fec authored by John W. Linville's avatar John W. Linville
Browse files
parents 274dede8 7578d575
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -1391,8 +1391,8 @@ struct ieee80211_vht_operation {
#define IEEE80211_VHT_CAP_RXSTBC_MASK				0x00000700
#define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE			0x00000800
#define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE			0x00001000
#define IEEE80211_VHT_CAP_BEAMFORMER_ANTENNAS_MAX		0x00006000
#define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MAX		0x00030000
#define IEEE80211_VHT_CAP_BEAMFORMEE_STS_MAX			0x0000e000
#define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MAX		0x00070000
#define IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE			0x00080000
#define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE			0x00100000
#define IEEE80211_VHT_CAP_VHT_TXOP_PS				0x00200000
+9 −0
Original line number Diff line number Diff line
@@ -436,6 +436,15 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
			     const struct cfg80211_chan_def *chandef,
			     u32 prohibited_flags);

/**
 * cfg80211_chandef_dfs_required - checks if radar detection is required
 * @wiphy: the wiphy to validate against
 * @chandef: the channel definition to check
 * Return: 1 if radar detection is required, 0 if it is not, < 0 on error
 */
int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
				  const struct cfg80211_chan_def *chandef);

/**
 * ieee80211_chandef_rate_flags - returns rate flags for a channel
 *
+42 −0
Original line number Diff line number Diff line
@@ -829,6 +829,15 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
 * @RX_FLAG_STBC_MASK: STBC 2 bit bitmask. 1 - Nss=1, 2 - Nss=2, 3 - Nss=3
 * @RX_FLAG_10MHZ: 10 MHz (half channel) was used
 * @RX_FLAG_5MHZ: 5 MHz (quarter channel) was used
 * @RX_FLAG_AMSDU_MORE: Some drivers may prefer to report separate A-MSDU
 *	subframes instead of a one huge frame for performance reasons.
 *	All, but the last MSDU from an A-MSDU should have this flag set. E.g.
 *	if an A-MSDU has 3 frames, the first 2 must have the flag set, while
 *	the 3rd (last) one must not have this flag set. The flag is used to
 *	deal with retransmission/duplication recovery properly since A-MSDU
 *	subframes share the same sequence number. Reported subframes can be
 *	either regular MSDU or singly A-MSDUs. Subframes must not be
 *	interleaved with other frames.
 */
enum mac80211_rx_flags {
	RX_FLAG_MMIC_ERROR		= BIT(0),
@@ -859,6 +868,7 @@ enum mac80211_rx_flags {
	RX_FLAG_STBC_MASK		= BIT(26) | BIT(27),
	RX_FLAG_10MHZ			= BIT(28),
	RX_FLAG_5MHZ			= BIT(29),
	RX_FLAG_AMSDU_MORE		= BIT(30),
};

#define RX_FLAG_STBC_SHIFT		26
@@ -1492,6 +1502,11 @@ struct ieee80211_tx_control {
 *
 * @IEEE80211_HW_TIMING_BEACON_ONLY: Use sync timing from beacon frames
 *	only, to allow getting TBTT of a DTIM beacon.
 *
 * @IEEE80211_HW_CHANCTX_STA_CSA: Support 802.11h based channel-switch (CSA)
 *	for a single active channel while using channel contexts. When support
 *	is not enabled the default action is to disconnect when getting the
 *	CSA frame.
 */
enum ieee80211_hw_flags {
	IEEE80211_HW_HAS_RATE_CONTROL			= 1<<0,
@@ -1522,6 +1537,7 @@ enum ieee80211_hw_flags {
	IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF		= 1<<25,
	IEEE80211_HW_TIMING_BEACON_ONLY			= 1<<26,
	IEEE80211_HW_SUPPORTS_HT_CCK_RATES		= 1<<27,
	IEEE80211_HW_CHANCTX_STA_CSA			= 1<<28,
};

/**
@@ -2666,6 +2682,10 @@ enum ieee80211_roc_type {
 *	zero using ieee80211_csa_is_complete() after the beacon has been
 *	transmitted and then call ieee80211_csa_finish().
 *
 * @join_ibss: Join an IBSS (on an IBSS interface); this is called after all
 *	information in bss_conf is set up and the beacon can be retrieved. A
 *	channel context is bound before this is called.
 * @leave_ibss: Leave the IBSS again.
 */
struct ieee80211_ops {
	void (*tx)(struct ieee80211_hw *hw,
@@ -2857,6 +2877,9 @@ struct ieee80211_ops {
	void (*channel_switch_beacon)(struct ieee80211_hw *hw,
				      struct ieee80211_vif *vif,
				      struct cfg80211_chan_def *chandef);

	int (*join_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
	void (*leave_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
};

/**
@@ -3919,6 +3942,25 @@ void ieee80211_iterate_active_interfaces_atomic(struct ieee80211_hw *hw,
						    struct ieee80211_vif *vif),
						void *data);

/**
 * ieee80211_iterate_active_interfaces_rtnl - iterate active interfaces
 *
 * This function iterates over the interfaces associated with a given
 * hardware that are currently active and calls the callback for them.
 * This version can only be used while holding the RTNL.
 *
 * @hw: the hardware struct of which the interfaces should be iterated over
 * @iter_flags: iteration flags, see &enum ieee80211_interface_iteration_flags
 * @iterator: the iterator function to call, cannot sleep
 * @data: first argument of the iterator function
 */
void ieee80211_iterate_active_interfaces_rtnl(struct ieee80211_hw *hw,
					      u32 iter_flags,
					      void (*iterator)(void *data,
						u8 *mac,
						struct ieee80211_vif *vif),
					      void *data);

/**
 * ieee80211_queue_work - add work onto the mac80211 workqueue
 *
+69 −23
Original line number Diff line number Diff line
@@ -2865,30 +2865,43 @@ void ieee80211_csa_finalize_work(struct work_struct *work)
	if (!ieee80211_sdata_running(sdata))
		return;

	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP))
		return;

	sdata->radar_required = sdata->csa_radar_required;
	err = ieee80211_vif_change_channel(sdata, &local->csa_chandef,
					   &changed);
	if (WARN_ON(err < 0))
		return;

	if (!local->use_chanctx) {
		local->_oper_chandef = local->csa_chandef;
		ieee80211_hw_config(local, 0);
	}

	ieee80211_bss_info_change_notify(sdata, changed);

	switch (sdata->vif.type) {
	case NL80211_IFTYPE_AP:
		err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon);
		if (err < 0)
			return;

		changed |= err;
		kfree(sdata->u.ap.next_beacon);
		sdata->u.ap.next_beacon = NULL;

		ieee80211_bss_info_change_notify(sdata, err);
		break;
	case NL80211_IFTYPE_ADHOC:
		ieee80211_ibss_finish_csa(sdata);
		break;
	default:
		WARN_ON(1);
		return;
	}
	sdata->vif.csa_active = false;

	ieee80211_wake_queues_by_reason(&sdata->local->hw,
					IEEE80211_MAX_QUEUE_MAP,
					IEEE80211_QUEUE_STOP_REASON_CSA);

	ieee80211_bss_info_change_notify(sdata, changed);

	cfg80211_ch_switch_notify(sdata->dev, &local->csa_chandef);
}

@@ -2936,20 +2949,56 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
	if (sdata->vif.csa_active)
		return -EBUSY;

	/* only handle AP for now. */
	switch (sdata->vif.type) {
	case NL80211_IFTYPE_AP:
		sdata->csa_counter_offset_beacon =
			params->counter_offset_beacon;
		sdata->csa_counter_offset_presp = params->counter_offset_presp;
		sdata->u.ap.next_beacon =
			cfg80211_beacon_dup(&params->beacon_after);
		if (!sdata->u.ap.next_beacon)
			return -ENOMEM;

		err = ieee80211_assign_beacon(sdata, &params->beacon_csa);
		if (err < 0) {
			kfree(sdata->u.ap.next_beacon);
			return err;
		}
		break;
	case NL80211_IFTYPE_ADHOC:
		if (!sdata->vif.bss_conf.ibss_joined)
			return -EINVAL;

		if (params->chandef.width != sdata->u.ibss.chandef.width)
			return -EINVAL;

		switch (params->chandef.width) {
		case NL80211_CHAN_WIDTH_40:
			if (cfg80211_get_chandef_type(&params->chandef) !=
			    cfg80211_get_chandef_type(&sdata->u.ibss.chandef))
				return -EINVAL;
		case NL80211_CHAN_WIDTH_5:
		case NL80211_CHAN_WIDTH_10:
		case NL80211_CHAN_WIDTH_20_NOHT:
		case NL80211_CHAN_WIDTH_20:
			break;
		default:
		return -EOPNOTSUPP;
			return -EINVAL;
		}

	sdata->u.ap.next_beacon = cfg80211_beacon_dup(&params->beacon_after);
	if (!sdata->u.ap.next_beacon)
		return -ENOMEM;
		/* changes into another band are not supported */
		if (sdata->u.ibss.chandef.chan->band !=
		    params->chandef.chan->band)
			return -EINVAL;

		err = ieee80211_ibss_csa_beacon(sdata, params);
		if (err < 0)
			return err;
		break;
	default:
		return -EOPNOTSUPP;
	}

	sdata->csa_counter_offset_beacon = params->counter_offset_beacon;
	sdata->csa_counter_offset_presp = params->counter_offset_presp;
	sdata->csa_radar_required = params->radar_required;

	if (params->block_tx)
@@ -2957,10 +3006,6 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
				IEEE80211_MAX_QUEUE_MAP,
				IEEE80211_QUEUE_STOP_REASON_CSA);

	err = ieee80211_assign_beacon(sdata, &params->beacon_csa);
	if (err < 0)
		return err;

	local->csa_chandef = params->chandef;
	sdata->vif.csa_active = true;

@@ -3014,7 +3059,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
			need_offchan = true;
		if (!ieee80211_is_action(mgmt->frame_control) ||
		    mgmt->u.action.category == WLAN_CATEGORY_PUBLIC ||
		    mgmt->u.action.category == WLAN_CATEGORY_SELF_PROTECTED)
		    mgmt->u.action.category == WLAN_CATEGORY_SELF_PROTECTED ||
		    mgmt->u.action.category == WLAN_CATEGORY_SPECTRUM_MGMT)
			break;
		rcu_read_lock();
		sta = sta_info_get(sdata, mgmt->da);
+0 −5
Original line number Diff line number Diff line
@@ -453,11 +453,6 @@ int ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata,
	chanctx_changed |= IEEE80211_CHANCTX_CHANGE_CHANNEL;
	drv_change_chanctx(local, ctx, chanctx_changed);

	if (!local->use_chanctx) {
		local->_oper_chandef = *chandef;
		ieee80211_hw_config(local, 0);
	}

	ieee80211_recalc_chanctx_chantype(local, ctx);
	ieee80211_recalc_smps_chanctx(local, ctx);
	ieee80211_recalc_radar_chanctx(local, ctx);
Loading