Commit d7c1a9a0 authored by Aloka Dixit's avatar Aloka Dixit Committed by Johannes Berg
Browse files

wifi: nl80211: validate and configure puncturing bitmap



- New feature flag, NL80211_EXT_FEATURE_PUNCT, to advertise
  driver support for preamble puncturing in AP mode.
- New attribute, NL80211_ATTR_PUNCT_BITMAP, to receive a puncturing
  bitmap from the userspace during AP bring up (NL80211_CMD_START_AP)
  and channel switch (NL80211_CMD_CHANNEL_SWITCH) operations. Each bit
  corresponds to a 20 MHz channel in the operating bandwidth, lowest
  bit for the lowest channel. Bit set to 1 indicates that the channel
  is punctured. Higher 16 bits are reserved.
- New members added to structures cfg80211_ap_settings and
  cfg80211_csa_settings to propagate the bitmap to the driver after
  validation.

Signed-off-by: default avatarAloka Dixit <quic_alokad@quicinc.com>
Signed-off-by: default avatarMuna Sinada <quic_msinada@quicinc.com>
Link: https://lore.kernel.org/r/20230131001227.25014-3-quic_alokad@quicinc.com


[move validation against 0xffff into policy]
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent b25413fe
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -1316,6 +1316,9 @@ struct cfg80211_unsol_bcast_probe_resp {
 * @fils_discovery: FILS discovery transmission parameters
 * @unsol_bcast_probe_resp: Unsolicited broadcast probe response parameters
 * @mbssid_config: AP settings for multiple bssid
 * @punct_bitmap: Preamble puncturing bitmap. Each bit represents
 *	a 20 MHz channel, lowest bit corresponding to the lowest channel.
 *	Bit set to 1 indicates that the channel is punctured.
 */
struct cfg80211_ap_settings {
	struct cfg80211_chan_def chandef;
@@ -1350,6 +1353,7 @@ struct cfg80211_ap_settings {
	struct cfg80211_fils_discovery fils_discovery;
	struct cfg80211_unsol_bcast_probe_resp unsol_bcast_probe_resp;
	struct cfg80211_mbssid_config mbssid_config;
	u16 punct_bitmap;
};

/**
@@ -1367,6 +1371,9 @@ struct cfg80211_ap_settings {
 * @radar_required: whether radar detection is required on the new channel
 * @block_tx: whether transmissions should be blocked while changing
 * @count: number of beacons until switch
 * @punct_bitmap: Preamble puncturing bitmap. Each bit represents
 *	a 20 MHz channel, lowest bit corresponding to the lowest channel.
 *	Bit set to 1 indicates that the channel is punctured.
 */
struct cfg80211_csa_settings {
	struct cfg80211_chan_def chandef;
@@ -1379,6 +1386,7 @@ struct cfg80211_csa_settings {
	bool radar_required;
	bool block_tx;
	u8 count;
	u16 punct_bitmap;
};

/**
+11 −0
Original line number Diff line number Diff line
@@ -2769,6 +2769,12 @@ enum nl80211_commands {
 *	the incoming frame RX timestamp.
 * @NL80211_ATTR_TD_BITMAP: Transition Disable bitmap, for subsequent
 *	(re)associations.
 *
 * @NL80211_ATTR_PUNCT_BITMAP: (u32) Preamble puncturing bitmap, lowest
 *	bit corresponds to the lowest 20 MHz channel. Each bit set to 1
 *	indicates that the sub-channel is punctured. Higher 16 bits are
 *	reserved.
 *
 * @NUM_NL80211_ATTR: total number of nl80211_attrs available
 * @NL80211_ATTR_MAX: highest attribute number currently defined
 * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3298,6 +3304,8 @@ enum nl80211_attrs {
	NL80211_ATTR_RX_HW_TIMESTAMP,
	NL80211_ATTR_TD_BITMAP,

	NL80211_ATTR_PUNCT_BITMAP,

	/* add attributes here, update the policy in nl80211.c */

	__NL80211_ATTR_AFTER_LAST,
@@ -6313,6 +6321,8 @@ enum nl80211_feature_flags {
 *	might apply, e.g. no scans in progress, no offchannel operations
 *	in progress, and no active connections.
 *
 * @NL80211_EXT_FEATURE_PUNCT: Driver supports preamble puncturing in AP mode.
 *
 * @NUM_NL80211_EXT_FEATURES: number of extended features.
 * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
 */
@@ -6381,6 +6391,7 @@ enum nl80211_ext_feature_index {
	NL80211_EXT_FEATURE_FILS_CRYPTO_OFFLOAD,
	NL80211_EXT_FEATURE_RADAR_BACKGROUND,
	NL80211_EXT_FEATURE_POWERED_ADDR_CHANGE,
	NL80211_EXT_FEATURE_PUNCT,

	/* add new features before the definition below */
	NUM_NL80211_EXT_FEATURES,
+32 −0
Original line number Diff line number Diff line
@@ -805,6 +805,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
	[NL80211_ATTR_MLD_ADDR] = NLA_POLICY_EXACT_LEN(ETH_ALEN),
	[NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG },
	[NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT },
	[NL80211_ATTR_PUNCT_BITMAP] = NLA_POLICY_RANGE(NLA_U8, 0, 0xffff),
};
/* policy for the key attributes */
@@ -3173,6 +3174,21 @@ static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
		wdev->iftype == NL80211_IFTYPE_P2P_GO;
}
static int nl80211_parse_punct_bitmap(struct cfg80211_registered_device *rdev,
				      struct genl_info *info,
				      const struct cfg80211_chan_def *chandef,
				      u16 *punct_bitmap)
{
	if (!wiphy_ext_feature_isset(&rdev->wiphy, NL80211_EXT_FEATURE_PUNCT))
		return -EINVAL;
	*punct_bitmap = nla_get_u32(info->attrs[NL80211_ATTR_PUNCT_BITMAP]);
	if (!cfg80211_valid_disable_subchannel_bitmap(punct_bitmap, chandef))
		return -EINVAL;
	return 0;
}
int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
			  struct genl_info *info,
			  struct cfg80211_chan_def *chandef)
@@ -5957,6 +5973,14 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
		goto out;
	}
	if (info->attrs[NL80211_ATTR_PUNCT_BITMAP]) {
		err = nl80211_parse_punct_bitmap(rdev, info,
						 &params->chandef,
						 &params->punct_bitmap);
		if (err)
			goto out;
	}
	if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params->chandef,
					   wdev->iftype)) {
		err = -EINVAL;
@@ -10114,6 +10138,14 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
	if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
		params.block_tx = true;
	if (info->attrs[NL80211_ATTR_PUNCT_BITMAP]) {
		err = nl80211_parse_punct_bitmap(rdev, info,
						 &params.chandef,
						 &params.punct_bitmap);
		if (err)
			goto free;
	}
	wdev_lock(wdev);
	err = rdev_channel_switch(rdev, dev, &params);
	wdev_unlock(wdev);