* [PATCH 2/2] iw: remove ifdefs for mcs mask
2011-12-19 14:14 [PATCH 0/2] add support for mcs masks Simon Wunderlich
@ 2011-12-19 14:14 ` Simon Wunderlich
0 siblings, 0 replies; 14+ messages in thread
From: Simon Wunderlich @ 2011-12-19 14:14 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] 14+ messages in thread
* [PATCHv2 0/2] add support for mcs masks
@ 2012-01-05 19:58 Simon Wunderlich
2012-01-05 19:58 ` [PATCHv2 1/2] nl80211: " Simon Wunderlich
` (3 more replies)
0 siblings, 4 replies; 14+ messages in thread
From: Simon Wunderlich @ 2012-01-05 19:58 UTC (permalink / raw)
To: linux-wireless
Cc: linville, Johannes Berg, Simon Wunderlich, Mathias Kretschmer
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.7.3
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCHv2 1/2] nl80211: add support for mcs masks
2012-01-05 19:58 [PATCHv2 0/2] add support for mcs masks Simon Wunderlich
@ 2012-01-05 19:58 ` Simon Wunderlich
2012-01-09 13:01 ` Johannes Berg
2012-01-05 19:58 ` [PATCHv2 2/2] mac80211: " Simon Wunderlich
` (2 subsequent siblings)
3 siblings, 1 reply; 14+ messages in thread
From: Simon Wunderlich @ 2012-01-05 19:58 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 0f5ff37..225272c 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
@@ -2401,12 +2402,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 15f4be7..2b23757 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1228,8 +1228,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 b3d3cf8..1f510fa 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -5364,9 +5364,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,
@@ -5392,12 +5422,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);
@@ -5413,7 +5451,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.7.3
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCHv2 2/2] mac80211: add support for mcs masks
2012-01-05 19:58 [PATCHv2 0/2] add support for mcs masks Simon Wunderlich
2012-01-05 19:58 ` [PATCHv2 1/2] nl80211: " Simon Wunderlich
@ 2012-01-05 19:58 ` Simon Wunderlich
2012-01-09 13:04 ` Johannes Berg
2012-01-05 19:58 ` [PATCH 1/2] iw: add nl80211 bitrates Simon Wunderlich
2012-01-05 19:58 ` [PATCH 2/2] iw: remove ifdefs for mcs mask Simon Wunderlich
3 siblings, 1 reply; 14+ messages in thread
From: Simon Wunderlich @ 2012-01-05 19:58 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 2a7523e..eaeaf56 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -3540,6 +3540,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 850bb96..cffcd92 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1907,8 +1907,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 176c08f..94987ac 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);
@@ -441,6 +461,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);
@@ -458,6 +480,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);
@@ -468,6 +492,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);
}
@@ -479,6 +509,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);
}
@@ -491,6 +523,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 c3f3e43..e040e90 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 e47768c..1094a58 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 5a5a776..ebec8e2 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -293,8 +293,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;
@@ -303,7 +303,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;
}
}
@@ -312,6 +312,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;
}
}
@@ -335,6 +441,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;
@@ -358,10 +465,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
@@ -372,11 +483,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 edcd1c7..23b3cf2 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);
@@ -2439,6 +2442,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.7.3
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 1/2] iw: add nl80211 bitrates
2012-01-05 19:58 [PATCHv2 0/2] add support for mcs masks Simon Wunderlich
2012-01-05 19:58 ` [PATCHv2 1/2] nl80211: " Simon Wunderlich
2012-01-05 19:58 ` [PATCHv2 2/2] mac80211: " Simon Wunderlich
@ 2012-01-05 19:58 ` Simon Wunderlich
2012-01-05 19:58 ` [PATCH 2/2] iw: remove ifdefs for mcs mask Simon Wunderlich
3 siblings, 0 replies; 14+ messages in thread
From: Simon Wunderlich @ 2012-01-05 19:58 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] 14+ messages in thread
* [PATCH 2/2] iw: remove ifdefs for mcs mask
2012-01-05 19:58 [PATCHv2 0/2] add support for mcs masks Simon Wunderlich
` (2 preceding siblings ...)
2012-01-05 19:58 ` [PATCH 1/2] iw: add nl80211 bitrates Simon Wunderlich
@ 2012-01-05 19:58 ` Simon Wunderlich
2012-01-09 13:05 ` Johannes Berg
3 siblings, 1 reply; 14+ messages in thread
From: Simon Wunderlich @ 2012-01-05 19:58 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] 14+ messages in thread
* Re: [PATCHv2 1/2] nl80211: add support for mcs masks
2012-01-05 19:58 ` [PATCHv2 1/2] nl80211: " Simon Wunderlich
@ 2012-01-09 13:01 ` Johannes Berg
0 siblings, 0 replies; 14+ messages in thread
From: Johannes Berg @ 2012-01-09 13:01 UTC (permalink / raw)
To: Simon Wunderlich
Cc: linux-wireless, linville, Simon Wunderlich, Mathias Kretschmer
On Thu, 2012-01-05 at 20:58 +0100, Simon Wunderlich wrote:
> @@ -5413,7 +5451,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;
Ok ... what if you now associate to a non-HT AP? I don't really care
what happens as long as we don't hit a ton of warnings?
johannes
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCHv2 2/2] mac80211: add support for mcs masks
2012-01-05 19:58 ` [PATCHv2 2/2] mac80211: " Simon Wunderlich
@ 2012-01-09 13:04 ` Johannes Berg
2012-01-10 17:28 ` Simon Wunderlich
0 siblings, 1 reply; 14+ messages in thread
From: Johannes Berg @ 2012-01-09 13:04 UTC (permalink / raw)
To: Simon Wunderlich
Cc: linux-wireless, linville, Simon Wunderlich, Mathias Kretschmer
On Thu, 2012-01-05 at 20:58 +0100, Simon Wunderlich wrote:
> +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;
All this logic is pretty complex, maybe we could translate the bitmap to
an array of unsigned longs and use test_bit() instead of open-coding it
for 8-bit words?
johannes
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/2] iw: remove ifdefs for mcs mask
2012-01-05 19:58 ` [PATCH 2/2] iw: remove ifdefs for mcs mask Simon Wunderlich
@ 2012-01-09 13:05 ` Johannes Berg
2012-01-10 18:29 ` Simon Wunderlich
0 siblings, 1 reply; 14+ messages in thread
From: Johannes Berg @ 2012-01-09 13:05 UTC (permalink / raw)
To: Simon Wunderlich
Cc: linux-wireless, linville, Simon Wunderlich, Mathias Kretschmer
On Thu, 2012-01-05 at 20:58 +0100, Simon Wunderlich wrote:
> These are enums, not defines. Therefore the ifdef check can never be
> true.
The original idea was that in nl80211.h you do
#define FOO FOO
(like we already have for a few things) to trigger the ifdef, but I
don't really care.
johannes
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCHv2 2/2] mac80211: add support for mcs masks
2012-01-09 13:04 ` Johannes Berg
@ 2012-01-10 17:28 ` Simon Wunderlich
2012-01-10 17:35 ` Johannes Berg
0 siblings, 1 reply; 14+ messages in thread
From: Simon Wunderlich @ 2012-01-10 17:28 UTC (permalink / raw)
To: Johannes Berg
Cc: Simon Wunderlich, linux-wireless, linville, Simon Wunderlich,
Mathias Kretschmer
[-- Attachment #1: Type: text/plain, Size: 1979 bytes --]
Hello Johannes,
On Mon, Jan 09, 2012 at 02:04:54PM +0100, Johannes Berg wrote:
> On Thu, 2012-01-05 at 20:58 +0100, Simon Wunderlich wrote:
>
> > +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;
>
> All this logic is pretty complex, maybe we could translate the bitmap to
> an array of unsigned longs and use test_bit() instead of open-coding it
> for 8-bit words?
Mhm, I would rather not add further copies into this fast path function, and
simply casting will result in bad behaviour (alignment, endianess). Generally
changing the mcs_mask to u32 is possible, but then we have inconsistent mcs
fields (rx_mask and others are u8 arrays too) - do we want this? Or am I missing
something obvious right now? :)
Maybe we can simplify it to something like this:
for (i = rate->idx + 1; i < IEEE80211_HT_MCS_MASK_LEN * 8; i++) {
ridx = i / 8;
rbit = i % 8;
if (mcs_mask[ridx] & BIT(rbit))) {
rate->idx = i;
return true;
}
}
What do you think?
Cheers,
Simon
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCHv2 2/2] mac80211: add support for mcs masks
2012-01-10 17:28 ` Simon Wunderlich
@ 2012-01-10 17:35 ` Johannes Berg
2012-01-10 18:42 ` Simon Wunderlich
0 siblings, 1 reply; 14+ messages in thread
From: Johannes Berg @ 2012-01-10 17:35 UTC (permalink / raw)
To: Simon Wunderlich
Cc: linux-wireless, linville, Simon Wunderlich, Mathias Kretschmer
On Tue, 2012-01-10 at 18:28 +0100, Simon Wunderlich wrote:
> Hello Johannes,
> > All this logic is pretty complex, maybe we could translate the bitmap to
> > an array of unsigned longs and use test_bit() instead of open-coding it
> > for 8-bit words?
>
> Mhm, I would rather not add further copies into this fast path function, and
> simply casting will result in bad behaviour (alignment, endianess).
Well you don't want to copy it, you want to maintain the data that way,
I think? Ok I think I see -- you're concerned about the masking etc.
Dunno. Maybe at least there's a way to abstract out all the
calculations?
> Generally
> changing the mcs_mask to u32 is possible,
No, u64 might work today but maybe somebody will want to use higher
MCSes in the future?
johannes
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/2] iw: remove ifdefs for mcs mask
2012-01-09 13:05 ` Johannes Berg
@ 2012-01-10 18:29 ` Simon Wunderlich
0 siblings, 0 replies; 14+ messages in thread
From: Simon Wunderlich @ 2012-01-10 18:29 UTC (permalink / raw)
To: Johannes Berg
Cc: Simon Wunderlich, linux-wireless, linville, Simon Wunderlich,
Mathias Kretschmer
[-- Attachment #1: Type: text/plain, Size: 733 bytes --]
Hey Johannes,
On Mon, Jan 09, 2012 at 02:05:39PM +0100, Johannes Berg wrote:
> On Thu, 2012-01-05 at 20:58 +0100, Simon Wunderlich wrote:
> > These are enums, not defines. Therefore the ifdef check can never be
> > true.
>
> The original idea was that in nl80211.h you do
>
> #define FOO FOO
Oh, ok, sorry, that's right, I haven't thought about this.
>
> (like we already have for a few things) to trigger the ifdef, but I
> don't really care.
I could as well add it into nl80211.h, and we skip this patch, or we remove
these ifdefs - your choice. :)
However, I don't think we really need the ifdefs as a copy of the nl80211.h
seems to be delivered with the iw source code anyway ...?
Cheers,
Simon
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCHv2 2/2] mac80211: add support for mcs masks
2012-01-10 17:35 ` Johannes Berg
@ 2012-01-10 18:42 ` Simon Wunderlich
0 siblings, 0 replies; 14+ messages in thread
From: Simon Wunderlich @ 2012-01-10 18:42 UTC (permalink / raw)
To: Johannes Berg
Cc: Simon Wunderlich, linux-wireless, linville, Simon Wunderlich,
Mathias Kretschmer
[-- Attachment #1: Type: text/plain, Size: 1547 bytes --]
On Tue, Jan 10, 2012 at 06:35:11PM +0100, Johannes Berg wrote:
> On Tue, 2012-01-10 at 18:28 +0100, Simon Wunderlich wrote:
> > Hello Johannes,
>
> > > All this logic is pretty complex, maybe we could translate the bitmap to
> > > an array of unsigned longs and use test_bit() instead of open-coding it
> > > for 8-bit words?
> >
> > Mhm, I would rather not add further copies into this fast path function, and
> > simply casting will result in bad behaviour (alignment, endianess).
>
> Well you don't want to copy it, you want to maintain the data that way,
> I think? Ok I think I see -- you're concerned about the masking etc.
> Dunno. Maybe at least there's a way to abstract out all the
> calculations?
>
I have looked into bitmap.h which offers a great set of functions for
unsigned long arrays, but unfortunately I couldn't find anything equivalent
for u8. Writing our own u8 bitmap function set would be overkill here (IMHO),
and abstracting/hiding these functions into defines or changing everything to
unsigned long to be consistent (including ht_caps.mcs.rx_mask) would be ugly
as well.
I also don't consider this piece of code to be beautiful, but would suggest
to keep it for now - or maybe someone else has a better idea.
> > Generally
> > changing the mcs_mask to u32 is possible,
>
> No, u64 might work today but maybe somebody will want to use higher
> MCSes in the future?
Yeah, u64 is possible on some architectures too - most of my routers are
32 bit however. :)
Cheers,
Simon
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 14+ 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
@ 2012-01-28 16:25 ` Simon Wunderlich
0 siblings, 0 replies; 14+ 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] 14+ messages in thread
end of thread, other threads:[~2012-01-28 16:25 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-01-05 19:58 [PATCHv2 0/2] add support for mcs masks Simon Wunderlich
2012-01-05 19:58 ` [PATCHv2 1/2] nl80211: " Simon Wunderlich
2012-01-09 13:01 ` Johannes Berg
2012-01-05 19:58 ` [PATCHv2 2/2] mac80211: " Simon Wunderlich
2012-01-09 13:04 ` Johannes Berg
2012-01-10 17:28 ` Simon Wunderlich
2012-01-10 17:35 ` Johannes Berg
2012-01-10 18:42 ` Simon Wunderlich
2012-01-05 19:58 ` [PATCH 1/2] iw: add nl80211 bitrates Simon Wunderlich
2012-01-05 19:58 ` [PATCH 2/2] iw: remove ifdefs for mcs mask Simon Wunderlich
2012-01-09 13:05 ` Johannes Berg
2012-01-10 18:29 ` Simon Wunderlich
-- strict thread matches above, loose matches on Subject: below --
2012-01-28 16:25 [PATCHv3 0/2] [RESEND] add support for mcs masks Simon Wunderlich
2012-01-28 16:25 ` [PATCH 2/2] iw: remove ifdefs for mcs mask Simon Wunderlich
2011-12-19 14:14 [PATCH 0/2] add support for mcs masks Simon Wunderlich
2011-12-19 14:14 ` [PATCH 2/2] iw: remove ifdefs for mcs mask Simon Wunderlich
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).