Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 290007
b: refs/heads/master
c: 24db78c
h: refs/heads/master
i:
  290005: f72fc42
  290003: 659f159
  289999: 74443ff
v: v3
  • Loading branch information
Simon Wunderlich authored and John W. Linville committed Jan 30, 2012
1 parent 6958b69 commit 4448f27
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d273bb20c00340748e3ca9730f87524ec5abbd64
refs/heads/master: 24db78c05b1e3ccb5a78aedd17aa1008c91dab5a
4 changes: 4 additions & 0 deletions trunk/include/linux/nl80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
3 changes: 1 addition & 2 deletions trunk/include/net/cfg80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -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];
};
/**
Expand Down
61 changes: 60 additions & 1 deletion trunk/net/wireless/nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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);
Expand All @@ -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;
}
}
Expand Down

0 comments on commit 4448f27

Please sign in to comment.