All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv3 0/2] [RESEND] add support for mcs masks
@ 2012-01-28 16:25 Simon Wunderlich
  2012-01-28 16:25 ` [PATCHv3 1/2] nl80211: " Simon Wunderlich
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Simon Wunderlich @ 2012-01-28 16:25 UTC (permalink / raw)
  To: linux-wireless
  Cc: linville, Johannes Berg, Simon Wunderlich, Mathias Kretschmer

This patchset is simply the rebased version of PATCHv2, which received
quite a few comments, but in the end we agreed to leave it as it is.
As the patchset has not been merged so far, I'm resending it. If there
are any comments/objections, please let me know. :)

(original) description:

This patchset adds support for fixed HT datarates. The configuration is
set through nl80211, and now accepts MCS masks next to the legacy masks.

A user may also choose to only use HT datarates and no legacy rates at all -
- as always when fiddling with datarates, he should know what he's doing,
and a fallback in the rate matching functions allow to use the rate controls
selected rate if no matching rate was found. The rate matching was enhanced
to consider MCS rates as well.

I have tested this feature in IBSS mode with ath9k devices and with and without
NoAcks, and (at least for me) it works as expected.

There is an iw patch as well to make use of this feature.

It should apply well on the latest wireless-testing kernel.

Changes to previous versions:
 * fix NL80211_MAX_SUPP_HT_RATES and add bug assertion
 * copy mcs rates from sband into mask
 * add sanity check for rate index
 * various formatting clean up

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>

Simon Wunderlich (2):
  nl80211: add support for mcs masks
  mac80211: add support for mcs masks

 include/linux/nl80211.h       |    4 +
 include/net/cfg80211.h        |    3 +-
 include/net/mac80211.h        |    1 +
 net/mac80211/cfg.c            |    5 +-
 net/mac80211/debugfs_netdev.c |   34 +++++++++++
 net/mac80211/ieee80211_i.h    |    1 +
 net/mac80211/iface.c          |    7 ++
 net/mac80211/rate.c           |  124 ++++++++++++++++++++++++++++++++++++++---
 net/mac80211/tx.c             |    5 ++
 net/wireless/nl80211.c        |   61 ++++++++++++++++++++-
 10 files changed, 233 insertions(+), 12 deletions(-)

-- 
1.7.8.3


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCHv3 1/2] nl80211: add support for mcs masks
  2012-01-28 16:25 [PATCHv3 0/2] [RESEND] add support for mcs masks Simon Wunderlich
@ 2012-01-28 16:25 ` Simon Wunderlich
  2020-11-12 10:38     ` Wen Gong
  2012-01-28 16:25 ` [PATCHv3 2/2] mac80211: " Simon Wunderlich
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 11+ messages in thread
From: Simon Wunderlich @ 2012-01-28 16:25 UTC (permalink / raw)
  To: linux-wireless
  Cc: linville, Johannes Berg, Simon Wunderlich, Mathias Kretschmer

Allow to set mcs masks through nl80211. We also allow to set MCS
rates but no legacy rates (and vice versa).

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
 include/linux/nl80211.h |    4 +++
 include/net/cfg80211.h  |    3 +-
 net/wireless/nl80211.c  |   61 ++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 4f98fae..ad56e21 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1475,6 +1475,7 @@ enum nl80211_attrs {
 #define NL80211_ATTR_FEATURE_FLAGS NL80211_ATTR_FEATURE_FLAGS
 
 #define NL80211_MAX_SUPP_RATES			32
+#define NL80211_MAX_SUPP_HT_RATES		77
 #define NL80211_MAX_SUPP_REG_RULES		32
 #define NL80211_TKIP_DATA_OFFSET_ENCR_KEY	0
 #define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY	16
@@ -2405,12 +2406,15 @@ enum nl80211_key_attributes {
  *	in an array of rates as defined in IEEE 802.11 7.3.2.2 (u8 values with
  *	1 = 500 kbps) but without the IE length restriction (at most
  *	%NL80211_MAX_SUPP_RATES in a single array).
+ * @NL80211_TXRATE_MCS: HT (MCS) rates allowed for TX rate selection
+ *	in an array of MCS numbers.
  * @__NL80211_TXRATE_AFTER_LAST: internal
  * @NL80211_TXRATE_MAX: highest TX rate attribute
  */
 enum nl80211_tx_rate_attributes {
 	__NL80211_TXRATE_INVALID,
 	NL80211_TXRATE_LEGACY,
+	NL80211_TXRATE_MCS,
 
 	/* keep last */
 	__NL80211_TXRATE_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 5bb3ed4..2964205 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1232,8 +1232,7 @@ enum wiphy_params_flags {
 struct cfg80211_bitrate_mask {
 	struct {
 		u32 legacy;
-		/* TODO: add support for masking MCS rates; e.g.: */
-		/* u8 mcs[IEEE80211_HT_MCS_MASK_LEN]; */
+		u8 mcs[IEEE80211_HT_MCS_MASK_LEN];
 	} control[IEEE80211_NUM_BANDS];
 };
 /**
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index c42173f..c910b07 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -5393,9 +5393,39 @@ static u32 rateset_to_mask(struct ieee80211_supported_band *sband,
 	return mask;
 }
 
+static bool ht_rateset_to_mask(struct ieee80211_supported_band *sband,
+			       u8 *rates, u8 rates_len,
+			       u8 mcs[IEEE80211_HT_MCS_MASK_LEN])
+{
+	u8 i;
+
+	memset(mcs, 0, IEEE80211_HT_MCS_MASK_LEN);
+
+	for (i = 0; i < rates_len; i++) {
+		int ridx, rbit;
+
+		ridx = rates[i] / 8;
+		rbit = BIT(rates[i] % 8);
+
+		/* check validity */
+		if ((ridx < 0) || (ridx > IEEE80211_HT_MCS_MASK_LEN))
+			return false;
+
+		/* check availability */
+		if (sband->ht_cap.mcs.rx_mask[ridx] & rbit)
+			mcs[ridx] |= rbit;
+		else
+			return false;
+	}
+
+	return true;
+}
+
 static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = {
 	[NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY,
 				    .len = NL80211_MAX_SUPP_RATES },
+	[NL80211_TXRATE_MCS] = { .type = NLA_BINARY,
+				 .len = NL80211_MAX_SUPP_HT_RATES },
 };
 
 static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
@@ -5421,12 +5451,20 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
 		sband = rdev->wiphy.bands[i];
 		mask.control[i].legacy =
 			sband ? (1 << sband->n_bitrates) - 1 : 0;
+		if (sband)
+			memcpy(mask.control[i].mcs,
+			       sband->ht_cap.mcs.rx_mask,
+			       sizeof(mask.control[i].mcs));
+		else
+			memset(mask.control[i].mcs, 0,
+			       sizeof(mask.control[i].mcs));
 	}
 
 	/*
 	 * The nested attribute uses enum nl80211_band as the index. This maps
 	 * directly to the enum ieee80211_band values used in cfg80211.
 	 */
+	BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8);
 	nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem)
 	{
 		enum ieee80211_band band = nla_type(tx_rates);
@@ -5442,7 +5480,28 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
 				sband,
 				nla_data(tb[NL80211_TXRATE_LEGACY]),
 				nla_len(tb[NL80211_TXRATE_LEGACY]));
-			if (mask.control[band].legacy == 0)
+		}
+		if (tb[NL80211_TXRATE_MCS]) {
+			if (!ht_rateset_to_mask(
+					sband,
+					nla_data(tb[NL80211_TXRATE_MCS]),
+					nla_len(tb[NL80211_TXRATE_MCS]),
+					mask.control[band].mcs))
+				return -EINVAL;
+		}
+
+		if (mask.control[band].legacy == 0) {
+			/* don't allow empty legacy rates if HT
+			 * is not even supported. */
+			if (!rdev->wiphy.bands[band]->ht_cap.ht_supported)
+				return -EINVAL;
+
+			for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
+				if (mask.control[band].mcs[i])
+					break;
+
+			/* legacy and mcs rates may not be both empty */
+			if (i == IEEE80211_HT_MCS_MASK_LEN)
 				return -EINVAL;
 		}
 	}
-- 
1.7.8.3


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCHv3 2/2] mac80211: add support for mcs masks
  2012-01-28 16:25 [PATCHv3 0/2] [RESEND] add support for mcs masks Simon Wunderlich
  2012-01-28 16:25 ` [PATCHv3 1/2] nl80211: " Simon Wunderlich
@ 2012-01-28 16:25 ` Simon Wunderlich
  2012-01-28 16:25 ` [PATCH 1/2] iw: add nl80211 bitrates Simon Wunderlich
  2012-01-28 16:25 ` [PATCH 2/2] iw: remove ifdefs for mcs mask Simon Wunderlich
  3 siblings, 0 replies; 11+ messages in thread
From: Simon Wunderlich @ 2012-01-28 16:25 UTC (permalink / raw)
  To: linux-wireless
  Cc: linville, Johannes Berg, Simon Wunderlich, Mathias Kretschmer

* Handle MCS masks set by the user.
* Match rates provided by the rate control algorithm to the mask set,
  also in HT mode, and switch back to legacy mode if necessary.
* add debugfs files to observate the rate selection

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
 include/net/mac80211.h        |    1 +
 net/mac80211/cfg.c            |    5 +-
 net/mac80211/debugfs_netdev.c |   34 +++++++++++
 net/mac80211/ieee80211_i.h    |    1 +
 net/mac80211/iface.c          |    7 ++
 net/mac80211/rate.c           |  124 ++++++++++++++++++++++++++++++++++++++---
 net/mac80211/tx.c             |    5 ++
 7 files changed, 168 insertions(+), 9 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 6501858..520eb4c 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -3551,6 +3551,7 @@ struct ieee80211_tx_rate_control {
 	bool rts, short_preamble;
 	u8 max_rate_idx;
 	u32 rate_idx_mask;
+	u8 rate_idx_mcs_mask[IEEE80211_HT_MCS_MASK_LEN];
 	bool bss;
 };
 
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 9846078..9c48db7 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1908,8 +1908,11 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
 			return ret;
 	}
 
-	for (i = 0; i < IEEE80211_NUM_BANDS; i++)
+	for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
 		sdata->rc_rateidx_mask[i] = mask->control[i].legacy;
+		memcpy(sdata->rc_rateidx_mcs_mask[i], mask->control[i].mcs,
+		       sizeof(mask->control[i].mcs));
+	}
 
 	return 0;
 }
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 81d12e6..510ed1d 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -87,6 +87,21 @@ static ssize_t ieee80211_if_fmt_##name(					\
 #define IEEE80211_IF_FMT_SIZE(name, field)				\
 		IEEE80211_IF_FMT(name, field, "%zd\n")
 
+#define IEEE80211_IF_FMT_HEXARRAY(name, field)				\
+static ssize_t ieee80211_if_fmt_##name(					\
+	const struct ieee80211_sub_if_data *sdata,			\
+	char *buf, int buflen)						\
+{									\
+	char *p = buf;							\
+	int i;								\
+	for (i = 0; i < sizeof(sdata->field); i++) {			\
+		p += scnprintf(p, buflen + buf - p, "%.2x ",		\
+				 sdata->field[i]);			\
+	}								\
+	p += scnprintf(p, buflen + buf - p, "\n");			\
+	return p - buf;							\
+}
+
 #define IEEE80211_IF_FMT_ATOMIC(name, field)				\
 static ssize_t ieee80211_if_fmt_##name(					\
 	const struct ieee80211_sub_if_data *sdata,			\
@@ -148,6 +163,11 @@ IEEE80211_IF_FILE(rc_rateidx_mask_2ghz, rc_rateidx_mask[IEEE80211_BAND_2GHZ],
 		  HEX);
 IEEE80211_IF_FILE(rc_rateidx_mask_5ghz, rc_rateidx_mask[IEEE80211_BAND_5GHZ],
 		  HEX);
+IEEE80211_IF_FILE(rc_rateidx_mcs_mask_2ghz,
+		  rc_rateidx_mcs_mask[IEEE80211_BAND_2GHZ], HEXARRAY);
+IEEE80211_IF_FILE(rc_rateidx_mcs_mask_5ghz,
+		  rc_rateidx_mcs_mask[IEEE80211_BAND_5GHZ], HEXARRAY);
+
 IEEE80211_IF_FILE(flags, flags, HEX);
 IEEE80211_IF_FILE(state, state, LHEX);
 IEEE80211_IF_FILE(channel_type, vif.bss_conf.channel_type, DEC);
@@ -442,6 +462,8 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
 	DEBUGFS_ADD(channel_type);
 	DEBUGFS_ADD(rc_rateidx_mask_2ghz);
 	DEBUGFS_ADD(rc_rateidx_mask_5ghz);
+	DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
+	DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz);
 
 	DEBUGFS_ADD(bssid);
 	DEBUGFS_ADD(aid);
@@ -459,6 +481,8 @@ static void add_ap_files(struct ieee80211_sub_if_data *sdata)
 	DEBUGFS_ADD(channel_type);
 	DEBUGFS_ADD(rc_rateidx_mask_2ghz);
 	DEBUGFS_ADD(rc_rateidx_mask_5ghz);
+	DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
+	DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz);
 
 	DEBUGFS_ADD(num_sta_authorized);
 	DEBUGFS_ADD(num_sta_ps);
@@ -469,6 +493,12 @@ static void add_ap_files(struct ieee80211_sub_if_data *sdata)
 
 static void add_ibss_files(struct ieee80211_sub_if_data *sdata)
 {
+	DEBUGFS_ADD(channel_type);
+	DEBUGFS_ADD(rc_rateidx_mask_2ghz);
+	DEBUGFS_ADD(rc_rateidx_mask_5ghz);
+	DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
+	DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz);
+
 	DEBUGFS_ADD_MODE(tsf, 0600);
 }
 
@@ -480,6 +510,8 @@ static void add_wds_files(struct ieee80211_sub_if_data *sdata)
 	DEBUGFS_ADD(channel_type);
 	DEBUGFS_ADD(rc_rateidx_mask_2ghz);
 	DEBUGFS_ADD(rc_rateidx_mask_5ghz);
+	DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
+	DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz);
 
 	DEBUGFS_ADD(peer);
 }
@@ -492,6 +524,8 @@ static void add_vlan_files(struct ieee80211_sub_if_data *sdata)
 	DEBUGFS_ADD(channel_type);
 	DEBUGFS_ADD(rc_rateidx_mask_2ghz);
 	DEBUGFS_ADD(rc_rateidx_mask_5ghz);
+	DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
+	DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz);
 }
 
 static void add_monitor_files(struct ieee80211_sub_if_data *sdata)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ca6486b..d47e8c1 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -646,6 +646,7 @@ struct ieee80211_sub_if_data {
 
 	/* bitmap of allowed (non-MCS) rate indexes for rate control */
 	u32 rc_rateidx_mask[IEEE80211_NUM_BANDS];
+	u8  rc_rateidx_mcs_mask[IEEE80211_NUM_BANDS][IEEE80211_HT_MCS_MASK_LEN];
 
 	union {
 		struct ieee80211_if_ap ap;
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 01a21c2..8c20ccb 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1181,6 +1181,13 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
 		sband = local->hw.wiphy->bands[i];
 		sdata->rc_rateidx_mask[i] =
 			sband ? (1 << sband->n_bitrates) - 1 : 0;
+		if (sband)
+			memcpy(sdata->rc_rateidx_mcs_mask[i],
+			       sband->ht_cap.mcs.rx_mask,
+			       sizeof(sdata->rc_rateidx_mcs_mask[i]));
+		else
+			memset(sdata->rc_rateidx_mcs_mask[i], 0,
+			       sizeof(sdata->rc_rateidx_mcs_mask[i]));
 	}
 
 	/* setup type-dependent data */
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index a21110a..3fef26d 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -289,8 +289,8 @@ bool rate_control_send_low(struct ieee80211_sta *sta,
 }
 EXPORT_SYMBOL(rate_control_send_low);
 
-static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
-				int n_bitrates, u32 mask)
+static bool rate_idx_match_legacy_mask(struct ieee80211_tx_rate *rate,
+				       int n_bitrates, u32 mask)
 {
 	int j;
 
@@ -299,7 +299,7 @@ static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
 		if (mask & (1 << j)) {
 			/* Okay, found a suitable rate. Use it. */
 			rate->idx = j;
-			return;
+			return true;
 		}
 	}
 
@@ -308,6 +308,112 @@ static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
 		if (mask & (1 << j)) {
 			/* Okay, found a suitable rate. Use it. */
 			rate->idx = j;
+			return true;
+		}
+	}
+	return false;
+}
+
+static bool rate_idx_match_mcs_mask(struct ieee80211_tx_rate *rate,
+				    u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
+{
+	int i, j;
+	int ridx, rbit;
+
+	ridx = rate->idx / 8;
+	rbit = rate->idx % 8;
+
+	/* sanity check */
+	if (ridx < 0 || ridx > IEEE80211_HT_MCS_MASK_LEN)
+		return false;
+
+	/* See whether the selected rate or anything below it is allowed. */
+	for (i = ridx; i >= 0; i--) {
+		for (j = rbit; j >= 0; j--)
+			if (mcs_mask[i] & BIT(j)) {
+				rate->idx = i * 8 + j;
+				return true;
+			}
+		rbit = 7;
+	}
+
+	/* Try to find a higher rate that would be allowed */
+	ridx = (rate->idx + 1) / 8;
+	rbit = (rate->idx + 1) % 8;
+
+	for (i = ridx; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
+		for (j = rbit; j < 8; j++)
+			if (mcs_mask[i] & BIT(j)) {
+				rate->idx = i * 8 + j;
+				return true;
+			}
+		rbit = 0;
+	}
+	return false;
+}
+
+
+
+static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
+				struct ieee80211_tx_rate_control *txrc,
+				u32 mask,
+				u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
+{
+	struct ieee80211_tx_rate alt_rate;
+
+	/* handle HT rates */
+	if (rate->flags & IEEE80211_TX_RC_MCS) {
+		if (rate_idx_match_mcs_mask(rate, mcs_mask))
+			return;
+
+		/* also try the legacy rates. */
+		alt_rate.idx = 0;
+		/* keep protection flags */
+		alt_rate.flags = rate->flags &
+				 (IEEE80211_TX_RC_USE_RTS_CTS |
+				  IEEE80211_TX_RC_USE_CTS_PROTECT |
+				  IEEE80211_TX_RC_USE_SHORT_PREAMBLE);
+		alt_rate.count = rate->count;
+		if (rate_idx_match_legacy_mask(&alt_rate,
+					       txrc->sband->n_bitrates,
+					       mask)) {
+			*rate = alt_rate;
+			return;
+		}
+	} else {
+		struct sk_buff *skb = txrc->skb;
+		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+		__le16 fc;
+
+		/* handle legacy rates */
+		if (rate_idx_match_legacy_mask(rate, txrc->sband->n_bitrates,
+					       mask))
+			return;
+
+		/* if HT BSS, and we handle a data frame, also try HT rates */
+		if (txrc->bss_conf->channel_type == NL80211_CHAN_NO_HT)
+			return;
+
+		fc = hdr->frame_control;
+		if (!ieee80211_is_data(fc))
+			return;
+
+		alt_rate.idx = 0;
+		/* keep protection flags */
+		alt_rate.flags = rate->flags &
+				 (IEEE80211_TX_RC_USE_RTS_CTS |
+				  IEEE80211_TX_RC_USE_CTS_PROTECT |
+				  IEEE80211_TX_RC_USE_SHORT_PREAMBLE);
+		alt_rate.count = rate->count;
+
+		alt_rate.flags |= IEEE80211_TX_RC_MCS;
+
+		if ((txrc->bss_conf->channel_type == NL80211_CHAN_HT40MINUS) ||
+		    (txrc->bss_conf->channel_type == NL80211_CHAN_HT40PLUS))
+			alt_rate.flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
+
+		if (rate_idx_match_mcs_mask(&alt_rate, mcs_mask)) {
+			*rate = alt_rate;
 			return;
 		}
 	}
@@ -331,6 +437,7 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);
 	int i;
 	u32 mask;
+	u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN];
 
 	if (sta) {
 		ista = &sta->sta;
@@ -354,10 +461,14 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
 	 * the common case.
 	 */
 	mask = sdata->rc_rateidx_mask[info->band];
+	memcpy(mcs_mask, sdata->rc_rateidx_mcs_mask[info->band],
+	       sizeof(mcs_mask));
 	if (mask != (1 << txrc->sband->n_bitrates) - 1) {
 		if (sta) {
 			/* Filter out rates that the STA does not support */
 			mask &= sta->sta.supp_rates[info->band];
+			for (i = 0; i < sizeof(mcs_mask); i++)
+				mcs_mask[i] &= sta->sta.ht_cap.mcs.rx_mask[i];
 		}
 		/*
 		 * Make sure the rate index selected for each TX rate is
@@ -368,11 +479,8 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
 			/* Skip invalid rates */
 			if (info->control.rates[i].idx < 0)
 				break;
-			/* Rate masking supports only legacy rates for now */
-			if (info->control.rates[i].flags & IEEE80211_TX_RC_MCS)
-				continue;
-			rate_idx_match_mask(&info->control.rates[i],
-					    txrc->sband->n_bitrates, mask);
+			rate_idx_match_mask(&info->control.rates[i], txrc,
+					    mask, mcs_mask);
 		}
 	}
 
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index e05667c..1be0ca2 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -635,6 +635,9 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
 		txrc.max_rate_idx = -1;
 	else
 		txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
+	memcpy(txrc.rate_idx_mcs_mask,
+	       tx->sdata->rc_rateidx_mcs_mask[tx->channel->band],
+	       sizeof(txrc.rate_idx_mcs_mask));
 	txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP ||
 		    tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
 		    tx->sdata->vif.type == NL80211_IFTYPE_ADHOC);
@@ -2431,6 +2434,8 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
 		txrc.max_rate_idx = -1;
 	else
 		txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
+	memcpy(txrc.rate_idx_mcs_mask, sdata->rc_rateidx_mcs_mask[band],
+	       sizeof(txrc.rate_idx_mcs_mask));
 	txrc.bss = true;
 	rate_control_get_rate(sdata, NULL, &txrc);
 
-- 
1.7.8.3


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 1/2] iw: add nl80211 bitrates
  2012-01-28 16:25 [PATCHv3 0/2] [RESEND] add support for mcs masks Simon Wunderlich
  2012-01-28 16:25 ` [PATCHv3 1/2] nl80211: " Simon Wunderlich
  2012-01-28 16:25 ` [PATCHv3 2/2] mac80211: " Simon Wunderlich
@ 2012-01-28 16:25 ` Simon Wunderlich
  2012-01-28 16:25 ` [PATCH 2/2] iw: remove ifdefs for mcs mask Simon Wunderlich
  3 siblings, 0 replies; 11+ messages in thread
From: Simon Wunderlich @ 2012-01-28 16:25 UTC (permalink / raw)
  To: linux-wireless
  Cc: linville, Johannes Berg, Simon Wunderlich, Mathias Kretschmer

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
 nl80211.h |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/nl80211.h b/nl80211.h
index a187606..445e0e4 100644
--- a/nl80211.h
+++ b/nl80211.h
@@ -2395,12 +2395,15 @@ enum nl80211_key_attributes {
  *	in an array of rates as defined in IEEE 802.11 7.3.2.2 (u8 values with
  *	1 = 500 kbps) but without the IE length restriction (at most
  *	%NL80211_MAX_SUPP_RATES in a single array).
+ * @NL80211_TXRATE_MCS: HT (MCS) rates allowed for TX rate selection
+ *      in an array of MCS numbers.
  * @__NL80211_TXRATE_AFTER_LAST: internal
  * @NL80211_TXRATE_MAX: highest TX rate attribute
  */
 enum nl80211_tx_rate_attributes {
 	__NL80211_TXRATE_INVALID,
 	NL80211_TXRATE_LEGACY,
+	NL80211_TXRATE_MCS,
 
 	/* keep last */
 	__NL80211_TXRATE_AFTER_LAST,
-- 
1.7.7.3


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/2] iw: remove ifdefs for mcs mask
  2012-01-28 16:25 [PATCHv3 0/2] [RESEND] add support for mcs masks Simon Wunderlich
                   ` (2 preceding siblings ...)
  2012-01-28 16:25 ` [PATCH 1/2] iw: add nl80211 bitrates Simon Wunderlich
@ 2012-01-28 16:25 ` Simon Wunderlich
  3 siblings, 0 replies; 11+ messages in thread
From: Simon Wunderlich @ 2012-01-28 16:25 UTC (permalink / raw)
  To: linux-wireless
  Cc: linville, Johannes Berg, Simon Wunderlich, Mathias Kretschmer

These are enums, not defines. Therefore the ifdef check can never be
true.

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
 bitrate.c |   20 ++------------------
 1 files changed, 2 insertions(+), 18 deletions(-)

diff --git a/bitrate.c b/bitrate.c
index cefd150..22b863e 100644
--- a/bitrate.c
+++ b/bitrate.c
@@ -17,12 +17,10 @@ static int handle_bitrates(struct nl80211_state *state,
 	uint8_t *legacy = NULL;
 	int *n_legacy = NULL;
 	bool have_mcs_24 = false, have_mcs_5 = false;
-#ifdef NL80211_TXRATE_MCS
 	uint8_t mcs_24[77], mcs_5[77];
 	int n_mcs_24 = 0, n_mcs_5 = 0;
 	uint8_t *mcs = NULL;
 	int *n_mcs = NULL;
-#endif
 	enum {
 		S_NONE,
 		S_LEGACY,
@@ -32,9 +30,7 @@ static int handle_bitrates(struct nl80211_state *state,
 	for (i = 0; i < argc; i++) {
 		char *end;
 		double tmpd;
-#ifdef NL80211_TXRATE_MCS
 		long tmpl;
-#endif
 
 		if (strcmp(argv[i], "legacy-2.4") == 0) {
 			if (have_legacy_24)
@@ -51,7 +47,6 @@ static int handle_bitrates(struct nl80211_state *state,
 			n_legacy = &n_legacy_5;
 			have_legacy_5 = true;
 		}
-#ifdef NL80211_TXRATE_MCS
 		else if (strcmp(argv[i], "mcs-2.4") == 0) {
 			if (have_mcs_24)
 				return 1;
@@ -67,7 +62,6 @@ static int handle_bitrates(struct nl80211_state *state,
 			n_mcs = &n_mcs_5;
 			have_mcs_5 = true;
 		}
-#endif
 		else switch (parser_state) {
 		case S_LEGACY:
 			tmpd = strtod(argv[i], &end);
@@ -78,7 +72,6 @@ static int handle_bitrates(struct nl80211_state *state,
 			legacy[(*n_legacy)++] = tmpd * 2;
 			break;
 		case S_MCS:
-#ifdef NL80211_TXRATE_MCS
 			tmpl = strtol(argv[i], &end, 0);
 			if (*end != '\0')
 				return 1;
@@ -86,7 +79,6 @@ static int handle_bitrates(struct nl80211_state *state,
 				return 1;
 			mcs[(*n_mcs)++] = tmpl;
 			break;
-#endif
 		default:
 			return 1;
 		}
@@ -102,10 +94,8 @@ static int handle_bitrates(struct nl80211_state *state,
 			goto nla_put_failure;
 		if (have_legacy_24)
 			nla_put(msg, NL80211_TXRATE_LEGACY, n_legacy_24, legacy_24);
-#ifdef NL80211_TXRATE_MCS
 		if (have_mcs_24)
 			nla_put(msg, NL80211_TXRATE_MCS, n_mcs_24, mcs_24);
-#endif
 		nla_nest_end(msg, nl_band);
 	}
 
@@ -115,10 +105,8 @@ static int handle_bitrates(struct nl80211_state *state,
 			goto nla_put_failure;
 		if (have_legacy_5)
 			nla_put(msg, NL80211_TXRATE_LEGACY, n_legacy_5, legacy_5);
-#ifdef NL80211_TXRATE_MCS
 		if (have_mcs_5)
 			nla_put(msg, NL80211_TXRATE_MCS, n_mcs_5, mcs_5);
-#endif
 		nla_nest_end(msg, nl_band);
 	}
 
@@ -130,13 +118,9 @@ static int handle_bitrates(struct nl80211_state *state,
 }
 
 #define DESCR_LEGACY "[legacy-<2.4|5> <legacy rate in Mbps>*]"
-#ifdef NL80211_TXRATE_MCS
 #define DESCR DESCR_LEGACY " [mcs-<2.4|5> <MCS index>*]"
-#else
-#define DESCR DESCR_LEGACY
-#endif
 
-COMMAND(set, bitrates, DESCR, NL80211_CMD_SET_TX_BITRATE_MASK, 0, CIB_NETDEV,
-	handle_bitrates,
+COMMAND(set, bitrates, "[legacy-<2.4|5> <legacy rate in Mbps>*] [mcs-<2.4|5> <MCS index>*]",
+	NL80211_CMD_SET_TX_BITRATE_MASK, 0, CIB_NETDEV, handle_bitrates,
 	"Sets up the specified rate masks.\n"
 	"Not passing any arguments would clear the existing mask (if any).");
-- 
1.7.7.3


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCHv3 1/2] nl80211: add support for mcs masks
  2012-01-28 16:25 ` [PATCHv3 1/2] nl80211: " Simon Wunderlich
  2020-11-12 10:38     ` Wen Gong
@ 2020-11-12 10:38     ` Wen Gong
  0 siblings, 0 replies; 11+ messages in thread
From: Wen Gong @ 2020-11-12 10:38 UTC (permalink / raw)
  To: Simon Wunderlich, Johannes Berg
  Cc: linux-wireless, linville, Johannes Berg, Simon Wunderlich,
	Mathias Kretschmer, linux-wireless-owner, ath10k, ath11k

On 2012-01-29 00:25, Simon Wunderlich wrote:
> Allow to set mcs masks through nl80211. We also allow to set MCS
> rates but no legacy rates (and vice versa).
> 
> Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
> Signed-off-by: Mathias Kretschmer 
> <mathias.kretschmer@fokus.fraunhofer.de>
> ---
>  include/linux/nl80211.h |    4 +++
>  include/net/cfg80211.h  |    3 +-
>  net/wireless/nl80211.c  |   61 
> ++++++++++++++++++++++++++++++++++++++++++++++-
>  3 files changed, 65 insertions(+), 3 deletions(-)
> 
...
> @@ -5421,12 +5451,20 @@ static int nl80211_set_tx_bitrate_mask(struct
> sk_buff *skb,
>  		sband = rdev->wiphy.bands[i];
>  		mask.control[i].legacy =
>  			sband ? (1 << sband->n_bitrates) - 1 : 0;
> +		if (sband)
> +			memcpy(mask.control[i].mcs,
> +			       sband->ht_cap.mcs.rx_mask,
> +			       sizeof(mask.control[i].mcs));
when use command: "iw wlan0 set bitrates legacy-5 6", I want to set it 
fixed in 6M rate.
this copy mcs rate will add the mcs rate here and condition "if 
(tb[NL80211_TXRATE_MCS])"
is false, then mcs rate will not clear and lead a mistake result.
> +		else
> +			memset(mask.control[i].mcs, 0,
> +			       sizeof(mask.control[i].mcs));
>  	}
> 
>  	/*
>  	 * The nested attribute uses enum nl80211_band as the index. This 
> maps
>  	 * directly to the enum ieee80211_band values used in cfg80211.
>  	 */
> +	BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 
> 8);
>  	nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], 
> rem)
>  	{
>  		enum ieee80211_band band = nla_type(tx_rates);
> @@ -5442,7 +5480,28 @@ static int nl80211_set_tx_bitrate_mask(struct
> sk_buff *skb,
>  				sband,
>  				nla_data(tb[NL80211_TXRATE_LEGACY]),
>  				nla_len(tb[NL80211_TXRATE_LEGACY]));
> -			if (mask.control[band].legacy == 0)
> +		}
> +		if (tb[NL80211_TXRATE_MCS]) {

false for "iw wlan0 set bitrates legacy-5 6", so ht_rateset_to_mask will 
not enter and mcs rate will not clear.

> +			if (!ht_rateset_to_mask(
> +					sband,
> +					nla_data(tb[NL80211_TXRATE_MCS]),
> +					nla_len(tb[NL80211_TXRATE_MCS]),
> +					mask.control[band].mcs))
> +				return -EINVAL;
> +		}
> +
> +		if (mask.control[band].legacy == 0) {
> +			/* don't allow empty legacy rates if HT
> +			 * is not even supported. */
> +			if (!rdev->wiphy.bands[band]->ht_cap.ht_supported)
> +				return -EINVAL;
> +
> +			for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
> +				if (mask.control[band].mcs[i])
> +					break;
> +
> +			/* legacy and mcs rates may not be both empty */
> +			if (i == IEEE80211_HT_MCS_MASK_LEN)
>  				return -EINVAL;
>  		}
>  	}

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCHv3 1/2] nl80211: add support for mcs masks
@ 2020-11-12 10:38     ` Wen Gong
  0 siblings, 0 replies; 11+ messages in thread
From: Wen Gong @ 2020-11-12 10:38 UTC (permalink / raw)
  To: Simon Wunderlich, Johannes Berg
  Cc: Mathias Kretschmer, linux-wireless, linville, Simon Wunderlich,
	linux-wireless-owner, ath10k, ath11k

On 2012-01-29 00:25, Simon Wunderlich wrote:
> Allow to set mcs masks through nl80211. We also allow to set MCS
> rates but no legacy rates (and vice versa).
> 
> Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
> Signed-off-by: Mathias Kretschmer 
> <mathias.kretschmer@fokus.fraunhofer.de>
> ---
>  include/linux/nl80211.h |    4 +++
>  include/net/cfg80211.h  |    3 +-
>  net/wireless/nl80211.c  |   61 
> ++++++++++++++++++++++++++++++++++++++++++++++-
>  3 files changed, 65 insertions(+), 3 deletions(-)
> 
...
> @@ -5421,12 +5451,20 @@ static int nl80211_set_tx_bitrate_mask(struct
> sk_buff *skb,
>  		sband = rdev->wiphy.bands[i];
>  		mask.control[i].legacy =
>  			sband ? (1 << sband->n_bitrates) - 1 : 0;
> +		if (sband)
> +			memcpy(mask.control[i].mcs,
> +			       sband->ht_cap.mcs.rx_mask,
> +			       sizeof(mask.control[i].mcs));
when use command: "iw wlan0 set bitrates legacy-5 6", I want to set it 
fixed in 6M rate.
this copy mcs rate will add the mcs rate here and condition "if 
(tb[NL80211_TXRATE_MCS])"
is false, then mcs rate will not clear and lead a mistake result.
> +		else
> +			memset(mask.control[i].mcs, 0,
> +			       sizeof(mask.control[i].mcs));
>  	}
> 
>  	/*
>  	 * The nested attribute uses enum nl80211_band as the index. This 
> maps
>  	 * directly to the enum ieee80211_band values used in cfg80211.
>  	 */
> +	BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 
> 8);
>  	nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], 
> rem)
>  	{
>  		enum ieee80211_band band = nla_type(tx_rates);
> @@ -5442,7 +5480,28 @@ static int nl80211_set_tx_bitrate_mask(struct
> sk_buff *skb,
>  				sband,
>  				nla_data(tb[NL80211_TXRATE_LEGACY]),
>  				nla_len(tb[NL80211_TXRATE_LEGACY]));
> -			if (mask.control[band].legacy == 0)
> +		}
> +		if (tb[NL80211_TXRATE_MCS]) {

false for "iw wlan0 set bitrates legacy-5 6", so ht_rateset_to_mask will 
not enter and mcs rate will not clear.

> +			if (!ht_rateset_to_mask(
> +					sband,
> +					nla_data(tb[NL80211_TXRATE_MCS]),
> +					nla_len(tb[NL80211_TXRATE_MCS]),
> +					mask.control[band].mcs))
> +				return -EINVAL;
> +		}
> +
> +		if (mask.control[band].legacy == 0) {
> +			/* don't allow empty legacy rates if HT
> +			 * is not even supported. */
> +			if (!rdev->wiphy.bands[band]->ht_cap.ht_supported)
> +				return -EINVAL;
> +
> +			for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
> +				if (mask.control[band].mcs[i])
> +					break;
> +
> +			/* legacy and mcs rates may not be both empty */
> +			if (i == IEEE80211_HT_MCS_MASK_LEN)
>  				return -EINVAL;
>  		}
>  	}

-- 
ath11k mailing list
ath11k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath11k

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCHv3 1/2] nl80211: add support for mcs masks
@ 2020-11-12 10:38     ` Wen Gong
  0 siblings, 0 replies; 11+ messages in thread
From: Wen Gong @ 2020-11-12 10:38 UTC (permalink / raw)
  To: Simon Wunderlich, Johannes Berg
  Cc: Mathias Kretschmer, linux-wireless, linville, Simon Wunderlich,
	linux-wireless-owner, ath10k, ath11k

On 2012-01-29 00:25, Simon Wunderlich wrote:
> Allow to set mcs masks through nl80211. We also allow to set MCS
> rates but no legacy rates (and vice versa).
> 
> Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
> Signed-off-by: Mathias Kretschmer 
> <mathias.kretschmer@fokus.fraunhofer.de>
> ---
>  include/linux/nl80211.h |    4 +++
>  include/net/cfg80211.h  |    3 +-
>  net/wireless/nl80211.c  |   61 
> ++++++++++++++++++++++++++++++++++++++++++++++-
>  3 files changed, 65 insertions(+), 3 deletions(-)
> 
...
> @@ -5421,12 +5451,20 @@ static int nl80211_set_tx_bitrate_mask(struct
> sk_buff *skb,
>  		sband = rdev->wiphy.bands[i];
>  		mask.control[i].legacy =
>  			sband ? (1 << sband->n_bitrates) - 1 : 0;
> +		if (sband)
> +			memcpy(mask.control[i].mcs,
> +			       sband->ht_cap.mcs.rx_mask,
> +			       sizeof(mask.control[i].mcs));
when use command: "iw wlan0 set bitrates legacy-5 6", I want to set it 
fixed in 6M rate.
this copy mcs rate will add the mcs rate here and condition "if 
(tb[NL80211_TXRATE_MCS])"
is false, then mcs rate will not clear and lead a mistake result.
> +		else
> +			memset(mask.control[i].mcs, 0,
> +			       sizeof(mask.control[i].mcs));
>  	}
> 
>  	/*
>  	 * The nested attribute uses enum nl80211_band as the index. This 
> maps
>  	 * directly to the enum ieee80211_band values used in cfg80211.
>  	 */
> +	BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 
> 8);
>  	nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], 
> rem)
>  	{
>  		enum ieee80211_band band = nla_type(tx_rates);
> @@ -5442,7 +5480,28 @@ static int nl80211_set_tx_bitrate_mask(struct
> sk_buff *skb,
>  				sband,
>  				nla_data(tb[NL80211_TXRATE_LEGACY]),
>  				nla_len(tb[NL80211_TXRATE_LEGACY]));
> -			if (mask.control[band].legacy == 0)
> +		}
> +		if (tb[NL80211_TXRATE_MCS]) {

false for "iw wlan0 set bitrates legacy-5 6", so ht_rateset_to_mask will 
not enter and mcs rate will not clear.

> +			if (!ht_rateset_to_mask(
> +					sband,
> +					nla_data(tb[NL80211_TXRATE_MCS]),
> +					nla_len(tb[NL80211_TXRATE_MCS]),
> +					mask.control[band].mcs))
> +				return -EINVAL;
> +		}
> +
> +		if (mask.control[band].legacy == 0) {
> +			/* don't allow empty legacy rates if HT
> +			 * is not even supported. */
> +			if (!rdev->wiphy.bands[band]->ht_cap.ht_supported)
> +				return -EINVAL;
> +
> +			for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
> +				if (mask.control[band].mcs[i])
> +					break;
> +
> +			/* legacy and mcs rates may not be both empty */
> +			if (i == IEEE80211_HT_MCS_MASK_LEN)
>  				return -EINVAL;
>  		}
>  	}

_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCHv3 1/2] nl80211: add support for mcs masks
  2020-11-12 10:38     ` Wen Gong
  (?)
@ 2020-11-13  8:55       ` Wen Gong
  -1 siblings, 0 replies; 11+ messages in thread
From: Wen Gong @ 2020-11-13  8:55 UTC (permalink / raw)
  To: Simon Wunderlich, Johannes Berg
  Cc: linux-wireless, linville, Simon Wunderlich, Mathias Kretschmer,
	linux-wireless-owner, ath10k, ath11k

On 2020-11-12 18:38, Wen Gong wrote:
> On 2012-01-29 00:25, Simon Wunderlich wrote:
>> Allow to set mcs masks through nl80211. We also allow to set MCS
>> rates but no legacy rates (and vice versa).
>> 
>> Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
>> Signed-off-by: Mathias Kretschmer 
>> <mathias.kretschmer@fokus.fraunhofer.de>
>> ---
>>  include/linux/nl80211.h |    4 +++
>>  include/net/cfg80211.h  |    3 +-
>>  net/wireless/nl80211.c  |   61 
>> ++++++++++++++++++++++++++++++++++++++++++++++-
>>  3 files changed, 65 insertions(+), 3 deletions(-)
>> 
> ...
>> @@ -5421,12 +5451,20 @@ static int nl80211_set_tx_bitrate_mask(struct
>> sk_buff *skb,
>>  		sband = rdev->wiphy.bands[i];
>>  		mask.control[i].legacy =
>>  			sband ? (1 << sband->n_bitrates) - 1 : 0;
>> +		if (sband)
>> +			memcpy(mask.control[i].mcs,
>> +			       sband->ht_cap.mcs.rx_mask,
>> +			       sizeof(mask.control[i].mcs));
> when use command: "iw wlan0 set bitrates legacy-5 6", I want to set it
> fixed in 6M rate.
> this copy mcs rate will add the mcs rate here and condition "if
> (tb[NL80211_TXRATE_MCS])"
> is false, then mcs rate will not clear and lead a mistake result.
>> +		else
>> +			memset(mask.control[i].mcs, 0,
>> +			       sizeof(mask.control[i].mcs));
>>  	}
>> 
>>  	/*
>>  	 * The nested attribute uses enum nl80211_band as the index. This 
>> maps
>>  	 * directly to the enum ieee80211_band values used in cfg80211.
>>  	 */
>> +	BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 
>> 8);
>>  	nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], 
>> rem)
>>  	{
>>  		enum ieee80211_band band = nla_type(tx_rates);
>> @@ -5442,7 +5480,28 @@ static int nl80211_set_tx_bitrate_mask(struct
>> sk_buff *skb,
>>  				sband,
>>  				nla_data(tb[NL80211_TXRATE_LEGACY]),
>>  				nla_len(tb[NL80211_TXRATE_LEGACY]));
>> -			if (mask.control[band].legacy == 0)
>> +		}
>> +		if (tb[NL80211_TXRATE_MCS]) {
> 
> false for "iw wlan0 set bitrates legacy-5 6", so ht_rateset_to_mask
> will not enter and mcs rate will not clear.
If no tb[NL80211_TXRATE_HT]/tb[NL80211_TXRATE_VHT], it should clear the 
data like this:
memset(mcs, 0, IEEE80211_HT_MCS_MASK_LEN) which is in ht_rateset_to_mask 
and
memset(mcs, 0, sizeof(u16) * NL80211_VHT_NSS_MAX) which is in 
vht_set_mcs_mask.
> 
>> +			if (!ht_rateset_to_mask(
>> +					sband,
>> +					nla_data(tb[NL80211_TXRATE_MCS]),
>> +					nla_len(tb[NL80211_TXRATE_MCS]),
>> +					mask.control[band].mcs))
>> +				return -EINVAL;
>> +		}
>> +
>> +		if (mask.control[band].legacy == 0) {
>> +			/* don't allow empty legacy rates if HT
>> +			 * is not even supported. */
>> +			if (!rdev->wiphy.bands[band]->ht_cap.ht_supported)
>> +				return -EINVAL;
>> +
>> +			for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
>> +				if (mask.control[band].mcs[i])
>> +					break;
>> +
>> +			/* legacy and mcs rates may not be both empty */
>> +			if (i == IEEE80211_HT_MCS_MASK_LEN)
>>  				return -EINVAL;
>>  		}
>>  	}

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCHv3 1/2] nl80211: add support for mcs masks
@ 2020-11-13  8:55       ` Wen Gong
  0 siblings, 0 replies; 11+ messages in thread
From: Wen Gong @ 2020-11-13  8:55 UTC (permalink / raw)
  To: Simon Wunderlich, Johannes Berg
  Cc: Mathias Kretschmer, linux-wireless, linville, ath10k,
	linux-wireless-owner, Simon Wunderlich, ath11k

On 2020-11-12 18:38, Wen Gong wrote:
> On 2012-01-29 00:25, Simon Wunderlich wrote:
>> Allow to set mcs masks through nl80211. We also allow to set MCS
>> rates but no legacy rates (and vice versa).
>> 
>> Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
>> Signed-off-by: Mathias Kretschmer 
>> <mathias.kretschmer@fokus.fraunhofer.de>
>> ---
>>  include/linux/nl80211.h |    4 +++
>>  include/net/cfg80211.h  |    3 +-
>>  net/wireless/nl80211.c  |   61 
>> ++++++++++++++++++++++++++++++++++++++++++++++-
>>  3 files changed, 65 insertions(+), 3 deletions(-)
>> 
> ...
>> @@ -5421,12 +5451,20 @@ static int nl80211_set_tx_bitrate_mask(struct
>> sk_buff *skb,
>>  		sband = rdev->wiphy.bands[i];
>>  		mask.control[i].legacy =
>>  			sband ? (1 << sband->n_bitrates) - 1 : 0;
>> +		if (sband)
>> +			memcpy(mask.control[i].mcs,
>> +			       sband->ht_cap.mcs.rx_mask,
>> +			       sizeof(mask.control[i].mcs));
> when use command: "iw wlan0 set bitrates legacy-5 6", I want to set it
> fixed in 6M rate.
> this copy mcs rate will add the mcs rate here and condition "if
> (tb[NL80211_TXRATE_MCS])"
> is false, then mcs rate will not clear and lead a mistake result.
>> +		else
>> +			memset(mask.control[i].mcs, 0,
>> +			       sizeof(mask.control[i].mcs));
>>  	}
>> 
>>  	/*
>>  	 * The nested attribute uses enum nl80211_band as the index. This 
>> maps
>>  	 * directly to the enum ieee80211_band values used in cfg80211.
>>  	 */
>> +	BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 
>> 8);
>>  	nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], 
>> rem)
>>  	{
>>  		enum ieee80211_band band = nla_type(tx_rates);
>> @@ -5442,7 +5480,28 @@ static int nl80211_set_tx_bitrate_mask(struct
>> sk_buff *skb,
>>  				sband,
>>  				nla_data(tb[NL80211_TXRATE_LEGACY]),
>>  				nla_len(tb[NL80211_TXRATE_LEGACY]));
>> -			if (mask.control[band].legacy == 0)
>> +		}
>> +		if (tb[NL80211_TXRATE_MCS]) {
> 
> false for "iw wlan0 set bitrates legacy-5 6", so ht_rateset_to_mask
> will not enter and mcs rate will not clear.
If no tb[NL80211_TXRATE_HT]/tb[NL80211_TXRATE_VHT], it should clear the 
data like this:
memset(mcs, 0, IEEE80211_HT_MCS_MASK_LEN) which is in ht_rateset_to_mask 
and
memset(mcs, 0, sizeof(u16) * NL80211_VHT_NSS_MAX) which is in 
vht_set_mcs_mask.
> 
>> +			if (!ht_rateset_to_mask(
>> +					sband,
>> +					nla_data(tb[NL80211_TXRATE_MCS]),
>> +					nla_len(tb[NL80211_TXRATE_MCS]),
>> +					mask.control[band].mcs))
>> +				return -EINVAL;
>> +		}
>> +
>> +		if (mask.control[band].legacy == 0) {
>> +			/* don't allow empty legacy rates if HT
>> +			 * is not even supported. */
>> +			if (!rdev->wiphy.bands[band]->ht_cap.ht_supported)
>> +				return -EINVAL;
>> +
>> +			for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
>> +				if (mask.control[band].mcs[i])
>> +					break;
>> +
>> +			/* legacy and mcs rates may not be both empty */
>> +			if (i == IEEE80211_HT_MCS_MASK_LEN)
>>  				return -EINVAL;
>>  		}
>>  	}

-- 
ath11k mailing list
ath11k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath11k

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCHv3 1/2] nl80211: add support for mcs masks
@ 2020-11-13  8:55       ` Wen Gong
  0 siblings, 0 replies; 11+ messages in thread
From: Wen Gong @ 2020-11-13  8:55 UTC (permalink / raw)
  To: Simon Wunderlich, Johannes Berg
  Cc: Mathias Kretschmer, linux-wireless, linville, ath10k,
	linux-wireless-owner, Simon Wunderlich, ath11k

On 2020-11-12 18:38, Wen Gong wrote:
> On 2012-01-29 00:25, Simon Wunderlich wrote:
>> Allow to set mcs masks through nl80211. We also allow to set MCS
>> rates but no legacy rates (and vice versa).
>> 
>> Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
>> Signed-off-by: Mathias Kretschmer 
>> <mathias.kretschmer@fokus.fraunhofer.de>
>> ---
>>  include/linux/nl80211.h |    4 +++
>>  include/net/cfg80211.h  |    3 +-
>>  net/wireless/nl80211.c  |   61 
>> ++++++++++++++++++++++++++++++++++++++++++++++-
>>  3 files changed, 65 insertions(+), 3 deletions(-)
>> 
> ...
>> @@ -5421,12 +5451,20 @@ static int nl80211_set_tx_bitrate_mask(struct
>> sk_buff *skb,
>>  		sband = rdev->wiphy.bands[i];
>>  		mask.control[i].legacy =
>>  			sband ? (1 << sband->n_bitrates) - 1 : 0;
>> +		if (sband)
>> +			memcpy(mask.control[i].mcs,
>> +			       sband->ht_cap.mcs.rx_mask,
>> +			       sizeof(mask.control[i].mcs));
> when use command: "iw wlan0 set bitrates legacy-5 6", I want to set it
> fixed in 6M rate.
> this copy mcs rate will add the mcs rate here and condition "if
> (tb[NL80211_TXRATE_MCS])"
> is false, then mcs rate will not clear and lead a mistake result.
>> +		else
>> +			memset(mask.control[i].mcs, 0,
>> +			       sizeof(mask.control[i].mcs));
>>  	}
>> 
>>  	/*
>>  	 * The nested attribute uses enum nl80211_band as the index. This 
>> maps
>>  	 * directly to the enum ieee80211_band values used in cfg80211.
>>  	 */
>> +	BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 
>> 8);
>>  	nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], 
>> rem)
>>  	{
>>  		enum ieee80211_band band = nla_type(tx_rates);
>> @@ -5442,7 +5480,28 @@ static int nl80211_set_tx_bitrate_mask(struct
>> sk_buff *skb,
>>  				sband,
>>  				nla_data(tb[NL80211_TXRATE_LEGACY]),
>>  				nla_len(tb[NL80211_TXRATE_LEGACY]));
>> -			if (mask.control[band].legacy == 0)
>> +		}
>> +		if (tb[NL80211_TXRATE_MCS]) {
> 
> false for "iw wlan0 set bitrates legacy-5 6", so ht_rateset_to_mask
> will not enter and mcs rate will not clear.
If no tb[NL80211_TXRATE_HT]/tb[NL80211_TXRATE_VHT], it should clear the 
data like this:
memset(mcs, 0, IEEE80211_HT_MCS_MASK_LEN) which is in ht_rateset_to_mask 
and
memset(mcs, 0, sizeof(u16) * NL80211_VHT_NSS_MAX) which is in 
vht_set_mcs_mask.
> 
>> +			if (!ht_rateset_to_mask(
>> +					sband,
>> +					nla_data(tb[NL80211_TXRATE_MCS]),
>> +					nla_len(tb[NL80211_TXRATE_MCS]),
>> +					mask.control[band].mcs))
>> +				return -EINVAL;
>> +		}
>> +
>> +		if (mask.control[band].legacy == 0) {
>> +			/* don't allow empty legacy rates if HT
>> +			 * is not even supported. */
>> +			if (!rdev->wiphy.bands[band]->ht_cap.ht_supported)
>> +				return -EINVAL;
>> +
>> +			for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
>> +				if (mask.control[band].mcs[i])
>> +					break;
>> +
>> +			/* legacy and mcs rates may not be both empty */
>> +			if (i == IEEE80211_HT_MCS_MASK_LEN)
>>  				return -EINVAL;
>>  		}
>>  	}

_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2020-11-13  8:55 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-01-28 16:25 [PATCHv3 0/2] [RESEND] add support for mcs masks Simon Wunderlich
2012-01-28 16:25 ` [PATCHv3 1/2] nl80211: " Simon Wunderlich
2020-11-12 10:38   ` Wen Gong
2020-11-12 10:38     ` Wen Gong
2020-11-12 10:38     ` Wen Gong
2020-11-13  8:55     ` Wen Gong
2020-11-13  8:55       ` Wen Gong
2020-11-13  8:55       ` Wen Gong
2012-01-28 16:25 ` [PATCHv3 2/2] mac80211: " Simon Wunderlich
2012-01-28 16:25 ` [PATCH 1/2] iw: add nl80211 bitrates Simon Wunderlich
2012-01-28 16:25 ` [PATCH 2/2] iw: remove ifdefs for mcs mask Simon Wunderlich

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.