* [PATCH v4 1/2] wireless: Support ht-capabilities over-rides.
@ 2011-11-04 20:10 greearb
2011-11-04 20:10 ` [PATCH v4 2/2] mac80211: Support ht-cap over-rides greearb
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: greearb @ 2011-11-04 20:10 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
From: Ben Greear <greearb@candelatech.com>
This allows users to disable features such as HT, HT40,
and to modify the MCS, AMPDU, and AMSDU settings for
drivers that support it.
The MCS, AMPDU, and AMSDU features that may be disabled are
are reported in the phy-info netlink message as a mask.
Attemping to disable features that are not supported will
take no affect, but will not return errors. This is to aid
backwards compatibility in user-space apps that may not be
clever enough to deal with parsing the the capabilities mask.
This patch only enables the infrastructure. An additional
patch will enable the feature in mac80211.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 8049bf7... 9e9ed9d... M include/linux/nl80211.h
:100644 100644 92cf1c2... 9ae1122... M include/net/cfg80211.h
:100644 100644 220f3bd... 3db837b... M net/wireless/core.c
:100644 100644 b9ec306... dd6feda... M net/wireless/core.h
:100644 100644 21fc970... a37e4bc... M net/wireless/mlme.c
:100644 100644 48260c2... 3d5d9ae... M net/wireless/nl80211.c
:100644 100644 6e86d5a... d144e2d... M net/wireless/sme.c
include/linux/nl80211.h | 11 ++++++++++
include/net/cfg80211.h | 32 +++++++++++++++++++++++++++++
net/wireless/core.c | 3 ++
net/wireless/core.h | 8 +++++-
net/wireless/mlme.c | 17 ++++++++++++--
net/wireless/nl80211.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++-
net/wireless/sme.c | 4 ++-
7 files changed, 119 insertions(+), 7 deletions(-)
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 8049bf7..9e9ed9d 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1109,6 +1109,13 @@ enum nl80211_commands {
* %NL80211_CMD_TDLS_MGMT. Otherwise %NL80211_CMD_TDLS_OPER should be
* used for asking the driver to perform a TDLS operation.
*
+ * @NL80211_ATTR_DISABLE_HT: Force HT capable interfaces to disable
+ * this feature.
+ * @NL80211_ATTR_DISABLE_HT40: Disable HT-40 even if AP and hardware
+ * support it.
+ * @NL80211_ATTR_HT_CAPABILITY_MASK: Specify which bits of the HT_CAPs
+ * to pay attention to.
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -1337,6 +1344,10 @@ enum nl80211_attrs {
NL80211_ATTR_TDLS_SUPPORT,
NL80211_ATTR_TDLS_EXTERNAL_SETUP,
+ NL80211_ATTR_DISABLE_HT,
+ NL80211_ATTR_DISABLE_HT40,
+ NL80211_ATTR_HT_CAPABILITY_MASK,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 92cf1c2..9ae1122 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1036,6 +1036,17 @@ struct cfg80211_auth_request {
};
/**
+ * enum cfg80211_assoc_req_flags - Over-ride default behaviour in association.
+ *
+ * @ASSOC_REQ_DISABLE_HT: Disable HT (802.11n)
+ * @ASSOC_REQ_DISABLE_HT40: Disable HT40 (802.11n)
+ */
+enum cfg80211_assoc_req_flags {
+ ASSOC_REQ_DISABLE_HT = BIT(0),
+ ASSOC_REQ_DISABLE_HT40 = BIT(1),
+};
+
+/**
* struct cfg80211_assoc_request - (Re)Association request data
*
* This structure provides information needed to complete IEEE 802.11
@@ -1046,6 +1057,11 @@ struct cfg80211_auth_request {
* @use_mfp: Use management frame protection (IEEE 802.11w) in this association
* @crypto: crypto settings
* @prev_bssid: previous BSSID, if not %NULL use reassociate frame
+ * @flags: See &enum cfg80211_assoc_req_flags
+ * @ht_capa: HT Capabilities over-rides. Values set in ht_capa_mask
+ * will be used in ht_capa. Only the MCS rates, MPDU and MSDU
+ * are currently supported.
+ * @ht_capa_mask: The bits of ht_capa which are to be used.
*/
struct cfg80211_assoc_request {
struct cfg80211_bss *bss;
@@ -1053,6 +1069,9 @@ struct cfg80211_assoc_request {
size_t ie_len;
struct cfg80211_crypto_settings crypto;
bool use_mfp;
+ u32 flags;
+ struct ieee80211_ht_cap ht_capa;
+ struct ieee80211_ht_cap ht_capa_mask;
};
/**
@@ -1151,6 +1170,11 @@ struct cfg80211_ibss_params {
* @key_len: length of WEP key for shared key authentication
* @key_idx: index of WEP key for shared key authentication
* @key: WEP key for shared key authentication
+ * @flags: See &enum cfg80211_assoc_req_flags
+ * @ht_capa: HT Capabilities over-rides. Values set in ht_capa_mask
+ * will be used in ht_capa. Only the MCS rates, MPDU and MSDU
+ * are currently supported.
+ * @ht_capa_mask: The bits of ht_capa which are to be used.
*/
struct cfg80211_connect_params {
struct ieee80211_channel *channel;
@@ -1164,6 +1188,9 @@ struct cfg80211_connect_params {
struct cfg80211_crypto_settings crypto;
const u8 *key;
u8 key_len, key_idx;
+ u32 flags;
+ struct ieee80211_ht_cap ht_capa;
+ struct ieee80211_ht_cap ht_capa_mask;
};
/**
@@ -1903,6 +1930,9 @@ struct wiphy_wowlan_support {
* may request, if implemented.
*
* @wowlan: WoWLAN support information
+ *
+ * @ht_capa_mod_msk: Specify what ht_cap values can be over-ridden.
+ * If null, then none can be over-ridden.
*/
struct wiphy {
/* assign these fields before you register the wiphy */
@@ -1983,6 +2013,8 @@ struct wiphy {
/* dir in debugfs: ieee80211/<wiphyname> */
struct dentry *debugfsdir;
+ struct ieee80211_ht_cap *ht_capa_mod_mask;
+
#ifdef CONFIG_NET_NS
/* the network namespace this phy lives in currently */
struct net *_net;
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 220f3bd..3db837b 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -704,6 +704,9 @@ void wiphy_unregister(struct wiphy *wiphy)
flush_work(&rdev->scan_done_wk);
cancel_work_sync(&rdev->conn_work);
flush_work(&rdev->event_work);
+
+ kfree(rdev->wiphy.ht_capa_mod_mask);
+ rdev->wiphy.ht_capa_mod_mask = NULL;
}
EXPORT_SYMBOL(wiphy_unregister);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index b9ec306..dd6feda 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -339,13 +339,17 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
const u8 *bssid, const u8 *prev_bssid,
const u8 *ssid, int ssid_len,
const u8 *ie, int ie_len, bool use_mfp,
- struct cfg80211_crypto_settings *crypt);
+ struct cfg80211_crypto_settings *crypt,
+ u32 assoc_flags, struct ieee80211_ht_cap *ht_capa,
+ struct ieee80211_ht_cap *ht_capa_mask);
int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
struct net_device *dev, struct ieee80211_channel *chan,
const u8 *bssid, const u8 *prev_bssid,
const u8 *ssid, int ssid_len,
const u8 *ie, int ie_len, bool use_mfp,
- struct cfg80211_crypto_settings *crypt);
+ struct cfg80211_crypto_settings *crypt,
+ u32 assoc_flags, struct ieee80211_ht_cap *ht_capa,
+ struct ieee80211_ht_cap *ht_capa_mask);
int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
struct net_device *dev, const u8 *bssid,
const u8 *ie, int ie_len, u16 reason,
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 21fc970..a37e4bc 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -507,7 +507,9 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
const u8 *bssid, const u8 *prev_bssid,
const u8 *ssid, int ssid_len,
const u8 *ie, int ie_len, bool use_mfp,
- struct cfg80211_crypto_settings *crypt)
+ struct cfg80211_crypto_settings *crypt,
+ u32 assoc_flags, struct ieee80211_ht_cap *ht_capa,
+ struct ieee80211_ht_cap *ht_capa_mask)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct cfg80211_assoc_request req;
@@ -537,6 +539,12 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
memcpy(&req.crypto, crypt, sizeof(req.crypto));
req.use_mfp = use_mfp;
req.prev_bssid = prev_bssid;
+ req.flags = assoc_flags;
+ if (ht_capa)
+ memcpy(&req.ht_capa, ht_capa, sizeof(req.ht_capa));
+ if (ht_capa_mask)
+ memcpy(&req.ht_capa_mask, ht_capa_mask,
+ sizeof(req.ht_capa_mask));
req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
if (!req.bss) {
@@ -574,14 +582,17 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
const u8 *bssid, const u8 *prev_bssid,
const u8 *ssid, int ssid_len,
const u8 *ie, int ie_len, bool use_mfp,
- struct cfg80211_crypto_settings *crypt)
+ struct cfg80211_crypto_settings *crypt,
+ u32 assoc_flags, struct ieee80211_ht_cap *ht_capa,
+ struct ieee80211_ht_cap *ht_capa_mask)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
int err;
wdev_lock(wdev);
err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid,
- ssid, ssid_len, ie, ie_len, use_mfp, crypt);
+ ssid, ssid_len, ie, ie_len, use_mfp, crypt,
+ assoc_flags, ht_capa, ht_capa_mask);
wdev_unlock(wdev);
return err;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 48260c2..3d5d9ae 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -197,6 +197,11 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
[NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
[NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
+ [NL80211_ATTR_DISABLE_HT] = { .type = NLA_FLAG },
+ [NL80211_ATTR_DISABLE_HT40] = { .type = NLA_FLAG },
+ [NL80211_ATTR_HT_CAPABILITY_MASK] = {
+ .len = NL80211_HT_CAPABILITY_LEN
+ },
};
/* policy for the key attributes */
@@ -1008,6 +1013,11 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
if (nl80211_put_iface_combinations(&dev->wiphy, msg))
goto nla_put_failure;
+ if (dev->wiphy.ht_capa_mod_mask)
+ NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY_MASK,
+ sizeof(*dev->wiphy.ht_capa_mod_mask),
+ dev->wiphy.ht_capa_mod_mask);
+
return genlmsg_end(msg, hdr);
nla_put_failure:
@@ -4354,6 +4364,9 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL;
int err, ssid_len, ie_len = 0;
bool use_mfp = false;
+ u32 flags = 0;
+ struct ieee80211_ht_cap *ht_capa = NULL;
+ struct ieee80211_ht_cap *ht_capa_mask = NULL;
if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
return -EINVAL;
@@ -4397,11 +4410,28 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[NL80211_ATTR_PREV_BSSID])
prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
+ if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
+ flags |= ASSOC_REQ_DISABLE_HT;
+
+ if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT40]))
+ flags |= ASSOC_REQ_DISABLE_HT40;
+
+ if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
+ ht_capa_mask =
+ nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]);
+
+ if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
+ if (!ht_capa_mask)
+ return -EINVAL;
+ ht_capa = nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
+ }
+
err = nl80211_crypto_settings(rdev, info, &crypto, 1);
if (!err)
err = cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid,
ssid, ssid_len, ie, ie_len, use_mfp,
- &crypto);
+ &crypto, flags, ht_capa,
+ ht_capa_mask);
return err;
}
@@ -4891,6 +4921,25 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
return PTR_ERR(connkeys);
}
+ if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
+ connect.flags |= ASSOC_REQ_DISABLE_HT;
+
+ if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT40]))
+ connect.flags |= ASSOC_REQ_DISABLE_HT40;
+
+ if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
+ memcpy(&connect.ht_capa_mask,
+ nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
+ sizeof(connect.ht_capa_mask));
+
+ if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
+ if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
+ return -EINVAL;
+ memcpy(&connect.ht_capa,
+ nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
+ sizeof(connect.ht_capa));
+ }
+
err = cfg80211_connect(rdev, dev, &connect, connkeys);
if (err)
kfree(connkeys);
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 6e86d5a..d144e2d 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -189,7 +189,9 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
prev_bssid,
params->ssid, params->ssid_len,
params->ie, params->ie_len,
- false, ¶ms->crypto);
+ false, ¶ms->crypto,
+ params->flags, ¶ms->ht_capa,
+ ¶ms->ht_capa_mask);
if (err)
__cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
NULL, 0,
--
1.7.3.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 2/2] mac80211: Support ht-cap over-rides.
2011-11-04 20:10 [PATCH v4 1/2] wireless: Support ht-capabilities over-rides greearb
@ 2011-11-04 20:10 ` greearb
2011-11-07 9:13 ` Johannes Berg
2011-11-04 21:03 ` [PATCH v4 1/2] wireless: Support ht-capabilities over-rides Johannes Berg
2011-11-07 9:06 ` Johannes Berg
2 siblings, 1 reply; 12+ messages in thread
From: greearb @ 2011-11-04 20:10 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
From: Ben Greear <greearb@candelatech.com>
This implements ht-cap over-rides for mac80211 drivers.
HT may be disabled, making an /a/b/g/n station act like an
a/b/g station. HT40 may be disabled forcing the station to
be HT20 even if the AP and local hardware support HT40.
MAX-AMSDU may be disabled.
AMPDU-Density may be increased.
AMPDU-Factor may be decreased.
This has been successfully tested with ath9k using patched
wpa_supplicant and iw.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 48363c3... 25ea406... M include/linux/ieee80211.h
:100644 100644 a9ded52... 7f4389e... M net/mac80211/cfg.c
:100644 100644 f80a35c... 8031fe2... M net/mac80211/ht.c
:100644 100644 ea10a51... aa61189... M net/mac80211/ieee80211_i.h
:100644 100644 d4ee6d2... 764a5ee... M net/mac80211/main.c
:100644 100644 57fb58f... dc2e124... M net/mac80211/mlme.c
:100644 100644 6c53b6d... 3f318df... M net/mac80211/work.c
include/linux/ieee80211.h | 6 +++
net/mac80211/cfg.c | 2 +-
net/mac80211/ht.c | 76 +++++++++++++++++++++++++++++++++++++++++++-
net/mac80211/ieee80211_i.h | 10 +++++-
net/mac80211/main.c | 15 +++++++++
net/mac80211/mlme.c | 16 ++++++++-
net/mac80211/work.c | 35 ++++++++++++++------
7 files changed, 145 insertions(+), 15 deletions(-)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 48363c3..25ea406 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -906,6 +906,12 @@ struct ieee80211_mcs_info {
#define IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT 2
#define IEEE80211_HT_MCS_TX_MAX_STREAMS 4
#define IEEE80211_HT_MCS_TX_UNEQUAL_MODULATION 0x10
+/*
+ * Stations supporting 802.11n are required to support
+ * at least the first 8 MCS rates. See section 7.3.2.56.4
+ * and 20.1.1 of the 802.11n spec.
+ */
+#define IEEE80211_HT_MCS_REQ_RATES_STA 8
/*
* 802.11n D5.0 20.3.5 / 20.6 says:
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index a9ded52..7f4389e 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -778,7 +778,7 @@ static void sta_apply_parameters(struct ieee80211_local *local,
}
if (params->ht_capa)
- ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
+ ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
params->ht_capa,
&sta->sta.ht_cap);
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index f80a35c..8031fe2 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -18,7 +18,75 @@
#include "ieee80211_i.h"
#include "rate.h"
-void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
+void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_sta_ht_cap *ht_cap,
+ int min_rates)
+{
+ u8 *scaps = (u8 *)(&sdata->u.mgd.ht_capa.mcs.rx_mask);
+ u8 *smask = (u8 *)(&sdata->u.mgd.ht_capa_mask.mcs.rx_mask);
+ int i;
+
+ /* NOTE: If you add more over-rides here, update register_hw
+ * ht_capa_mod_msk logic in main.c as well.
+ */
+
+ /* check for HT over-rides, MCS rates first. */
+ for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
+ int q;
+ for (q = 0; q < 8; q++) {
+ /*
+ * We always need to advert at least MCS0-7, to
+ * be a compliant HT station, for instance
+ */
+ if (((i * 8 + q) >= min_rates) &&
+ (smask[i] & (1<<q))) {
+ if (!(scaps[i] & (1<<q))) {
+ /*
+ * Can only disable rates, not force
+ * new ones
+ */
+ ht_cap->mcs.rx_mask[i] &= ~(1<<q);
+ }
+ }
+ }
+ }
+
+ /* Force removal of HT-40 capabilities? */
+ if (sdata->u.mgd.flags & IEEE80211_STA_DISABLE_HT40) {
+ ht_cap->cap &= ~(IEEE80211_HT_CAP_SUP_WIDTH_20_40
+ | IEEE80211_HT_CAP_SGI_40);
+ }
+
+ /* Allow user to disable the max-AMSDU bit. */
+ if (sdata->u.mgd.ht_capa_mask.cap_info & IEEE80211_HT_CAP_MAX_AMSDU) {
+ if (!(sdata->u.mgd.ht_capa.cap_info
+ & IEEE80211_HT_CAP_MAX_AMSDU))
+ ht_cap->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU;
+ }
+
+ /* Allow user to decrease AMPDU factor */
+ if (sdata->u.mgd.ht_capa_mask.ampdu_params_info &
+ IEEE80211_HT_AMPDU_PARM_FACTOR) {
+ u16 n = sdata->u.mgd.ht_capa.ampdu_params_info
+ & IEEE80211_HT_AMPDU_PARM_FACTOR;
+ if (n < ht_cap->ampdu_factor)
+ ht_cap->ampdu_factor = n;
+ }
+
+ /* Allow the user to increase AMPDU density. */
+ if (sdata->u.mgd.ht_capa_mask.ampdu_params_info &
+ IEEE80211_HT_AMPDU_PARM_DENSITY) {
+ u16 n = (sdata->u.mgd.ht_capa.ampdu_params_info &
+ IEEE80211_HT_AMPDU_PARM_DENSITY)
+ >> IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT;
+ if (n > ht_cap->ampdu_density)
+ ht_cap->ampdu_density = n;
+ }
+}
+
+
+void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_supported_band *sband,
struct ieee80211_ht_cap *ht_cap_ie,
struct ieee80211_sta_ht_cap *ht_cap)
{
@@ -102,6 +170,12 @@ void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
/* handle MCS rate 32 too */
if (sband->ht_cap.mcs.rx_mask[32/8] & ht_cap_ie->mcs.rx_mask[32/8] & 1)
ht_cap->mcs.rx_mask[32/8] |= 1;
+
+ /*
+ * If user has specified capability over-rides, take care
+ * of that here.
+ */
+ ieee80211_apply_htcap_overrides(sdata, ht_cap, 0);
}
void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, bool tx)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ea10a51..aa61189 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -364,6 +364,7 @@ enum ieee80211_sta_flags {
IEEE80211_STA_UAPSD_ENABLED = BIT(7),
IEEE80211_STA_NULLFUNC_ACKED = BIT(8),
IEEE80211_STA_RESET_SIGNAL_AVE = BIT(9),
+ IEEE80211_STA_DISABLE_HT40 = BIT(10),
};
struct ieee80211_if_managed {
@@ -443,6 +444,9 @@ struct ieee80211_if_managed {
*/
int rssi_min_thold, rssi_max_thold;
int last_ave_beacon_signal;
+ struct ieee80211_ht_cap ht_capa; /* configured ht-cap over-rides */
+ struct ieee80211_ht_cap ht_capa_mask; /* Valid parts of ht_capa */
+
};
struct ieee80211_if_ibss {
@@ -1179,7 +1183,11 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
struct net_device *dev);
/* HT */
-void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
+void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_sta_ht_cap *ht_cap,
+ int min_rates);
+void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_supported_band *sband,
struct ieee80211_ht_cap *ht_cap_ie,
struct ieee80211_sta_ht_cap *ht_cap);
void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index d4ee6d2..764a5ee 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -881,6 +881,19 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
if (local->hw.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)
local->hw.wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
+ /* mac80211 allows over-riding some of the ht-capabilities */
+ local->hw.wiphy->ht_capa_mod_mask =
+ kzalloc(sizeof(*local->hw.wiphy->ht_capa_mod_mask),
+ GFP_KERNEL);
+ if (local->hw.wiphy->ht_capa_mod_mask) {
+ struct ieee80211_ht_cap *cm = local->hw.wiphy->ht_capa_mod_mask;
+ u8 *r = (u8 *)(&cm->mcs.rx_mask);
+ memset(r, 0xff, IEEE80211_HT_MCS_MASK_LEN);
+ cm->cap_info |= IEEE80211_HT_CAP_MAX_AMSDU;
+ cm->ampdu_params_info |= IEEE80211_HT_AMPDU_PARM_FACTOR;
+ cm->ampdu_params_info |= IEEE80211_HT_AMPDU_PARM_DENSITY;
+ }
+
result = wiphy_register(local->hw.wiphy);
if (result < 0)
goto fail_wiphy_register;
@@ -988,6 +1001,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
fail_wiphy_register:
if (local->wiphy_ciphers_allocated)
kfree(local->hw.wiphy->cipher_suites);
+ kfree(local->hw.wiphy->ht_capa_mod_mask);
+ local->hw.wiphy->ht_capa_mod_mask = NULL;
kfree(local->int_scan_req);
return result;
}
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 57fb58f..dc2e124 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -207,6 +207,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
channel_type = NL80211_CHAN_HT20;
if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
+ !(sdata->u.mgd.flags & IEEE80211_STA_DISABLE_HT40) &&
(sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
(hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
@@ -1584,7 +1585,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
- ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
+ ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
elems.ht_cap_elem, &sta->sta.ht_cap);
ap_ht_cap_flags = sta->sta.ht_cap.cap;
@@ -1953,7 +1954,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
- ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
+ ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
elems.ht_cap_elem, &sta->sta.ht_cap);
ap_ht_cap_flags = sta->sta.ht_cap.cap;
@@ -2601,6 +2602,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N;
ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
+ ifmgd->flags &= ~IEEE80211_STA_DISABLE_HT40;
ifmgd->beacon_crc_valid = false;
@@ -2611,6 +2613,16 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
+ if (req->flags & ASSOC_REQ_DISABLE_HT)
+ ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
+
+ if (req->flags & ASSOC_REQ_DISABLE_HT40)
+ ifmgd->flags |= IEEE80211_STA_DISABLE_HT40;
+
+ memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa));
+ memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask,
+ sizeof(ifmgd->ht_capa_mask));
+
if (req->ie && req->ie_len) {
memcpy(wk->ie, req->ie, req->ie_len);
wk->ie_len = req->ie_len;
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index 6c53b6d..3f318df 100644
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -94,7 +94,8 @@ static int ieee80211_compatible_rates(const u8 *supp_rates, int supp_rates_len,
/* frame sending functions */
-static void ieee80211_add_ht_ie(struct sk_buff *skb, const u8 *ht_info_ie,
+static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb, const u8 *ht_info_ie,
struct ieee80211_supported_band *sband,
struct ieee80211_channel *channel,
enum ieee80211_smps_mode smps)
@@ -102,11 +103,11 @@ static void ieee80211_add_ht_ie(struct sk_buff *skb, const u8 *ht_info_ie,
struct ieee80211_ht_info *ht_info;
u8 *pos;
u32 flags = channel->flags;
- u16 cap = sband->ht_cap.cap;
+ u16 cap;
__le16 tmp;
+ struct ieee80211_sta_ht_cap ht_cap;
- if (!sband->ht_cap.ht_supported)
- return;
+ BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap));
if (!ht_info_ie)
return;
@@ -114,6 +115,20 @@ static void ieee80211_add_ht_ie(struct sk_buff *skb, const u8 *ht_info_ie,
if (ht_info_ie[1] < sizeof(struct ieee80211_ht_info))
return;
+ memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap));
+ /*
+ * This is for an association attempt, and stations must
+ * support at least the first 8 MCS rates. See section 20.1.1
+ * of the 802.11n spec for details.
+ */
+ ieee80211_apply_htcap_overrides(sdata, &ht_cap,
+ IEEE80211_HT_MCS_REQ_RATES_STA);
+
+ cap = ht_cap.cap;
+
+ if (!ht_cap.ht_supported)
+ return;
+
ht_info = (struct ieee80211_ht_info *)(ht_info_ie + 2);
/* determine capability flags */
@@ -166,13 +181,13 @@ static void ieee80211_add_ht_ie(struct sk_buff *skb, const u8 *ht_info_ie,
pos += sizeof(u16);
/* AMPDU parameters */
- *pos++ = sband->ht_cap.ampdu_factor |
- (sband->ht_cap.ampdu_density <<
- IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
+ *pos++ = ht_cap.ampdu_factor |
+ (ht_cap.ampdu_density <<
+ IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
/* MCS set */
- memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
- pos += sizeof(sband->ht_cap.mcs);
+ memcpy(pos, &ht_cap.mcs, sizeof(ht_cap.mcs));
+ pos += sizeof(ht_cap.mcs);
/* extended capabilities */
pos += sizeof(__le16);
@@ -356,7 +371,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
if (wk->assoc.use_11n && wk->assoc.wmm_used &&
local->hw.queues >= 4)
- ieee80211_add_ht_ie(skb, wk->assoc.ht_information_ie,
+ ieee80211_add_ht_ie(sdata, skb, wk->assoc.ht_information_ie,
sband, wk->chan, wk->assoc.smps);
/* if present, add any custom non-vendor IEs that go after HT */
--
1.7.3.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v4 1/2] wireless: Support ht-capabilities over-rides.
2011-11-04 20:10 [PATCH v4 1/2] wireless: Support ht-capabilities over-rides greearb
2011-11-04 20:10 ` [PATCH v4 2/2] mac80211: Support ht-cap over-rides greearb
@ 2011-11-04 21:03 ` Johannes Berg
2011-11-07 9:06 ` Johannes Berg
2 siblings, 0 replies; 12+ messages in thread
From: Johannes Berg @ 2011-11-04 21:03 UTC (permalink / raw)
To: greearb; +Cc: linux-wireless
On Fri, 2011-11-04 at 13:10 -0700, greearb@candelatech.com wrote:
> From: Ben Greear <greearb@candelatech.com>
>
> This allows users to disable features such as HT, HT40,
> and to modify the MCS, AMPDU, and AMSDU settings for
> drivers that support it.
Thanks for your patience, I'll review this Monday.
johannes
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 1/2] wireless: Support ht-capabilities over-rides.
2011-11-04 20:10 [PATCH v4 1/2] wireless: Support ht-capabilities over-rides greearb
2011-11-04 20:10 ` [PATCH v4 2/2] mac80211: Support ht-cap over-rides greearb
2011-11-04 21:03 ` [PATCH v4 1/2] wireless: Support ht-capabilities over-rides Johannes Berg
@ 2011-11-07 9:06 ` Johannes Berg
2011-11-07 16:27 ` Ben Greear
2011-11-07 17:40 ` Ben Greear
2 siblings, 2 replies; 12+ messages in thread
From: Johannes Berg @ 2011-11-07 9:06 UTC (permalink / raw)
To: greearb; +Cc: linux-wireless
On Fri, 2011-11-04 at 13:10 -0700, greearb@candelatech.com wrote:
> + * @NL80211_ATTR_DISABLE_HT: Force HT capable interfaces to disable
> + * this feature.
I can see this, but
> + * @NL80211_ATTR_DISABLE_HT40: Disable HT-40 even if AP and hardware
> + * support it.
> + * @NL80211_ATTR_HT_CAPABILITY_MASK: Specify which bits of the HT_CAPs
> + * to pay attention to.
if you have the mask why do you still need the HT40? Isn't HT40 a flag
in the mask? Or do you want this to affect TX/RX separately? You should
spell that out more explicitly then.
> --- a/net/wireless/core.c
> +++ b/net/wireless/core.c
> @@ -704,6 +704,9 @@ void wiphy_unregister(struct wiphy *wiphy)
> flush_work(&rdev->scan_done_wk);
> cancel_work_sync(&rdev->conn_work);
> flush_work(&rdev->event_work);
> +
> + kfree(rdev->wiphy.ht_capa_mod_mask);
> + rdev->wiphy.ht_capa_mod_mask = NULL;
That doesn't seem right -- drivers should typically assign a static
const variable to this pointer that can't be freed.
> @@ -537,6 +539,12 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
> memcpy(&req.crypto, crypt, sizeof(req.crypto));
> req.use_mfp = use_mfp;
> req.prev_bssid = prev_bssid;
> + req.flags = assoc_flags;
> + if (ht_capa)
> + memcpy(&req.ht_capa, ht_capa, sizeof(req.ht_capa));
> + if (ht_capa_mask)
> + memcpy(&req.ht_capa_mask, ht_capa_mask,
> + sizeof(req.ht_capa_mask));
I think somewhere here you should mask this mask with the
ht_capa_mod_mask. That way, you force drivers to advertise a correct
ht_capa_mod_mask, if you don't do that we will certainly see drivers use
more of ht_capa than contained in ht_capa_mod_mask. Probably should be a
helper function since I think you might need it in more places.
johannes
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 2/2] mac80211: Support ht-cap over-rides.
2011-11-04 20:10 ` [PATCH v4 2/2] mac80211: Support ht-cap over-rides greearb
@ 2011-11-07 9:13 ` Johannes Berg
2011-11-07 16:19 ` Ben Greear
0 siblings, 1 reply; 12+ messages in thread
From: Johannes Berg @ 2011-11-07 9:13 UTC (permalink / raw)
To: greearb; +Cc: linux-wireless
On Fri, 2011-11-04 at 13:10 -0700, greearb@candelatech.com wrote:
> +/*
> + * Stations supporting 802.11n are required to support
> + * at least the first 8 MCS rates. See section 7.3.2.56.4
> + * and 20.1.1 of the 802.11n spec.
> + */
> +#define IEEE80211_HT_MCS_REQ_RATES_STA 8
I'd prefer if this was a validation on the input from userspace directly
in cfg80211, that way other drivers that want to implement this don't
have to bother.
That probably goes well with the validation of the supported mask that I
asked for.
> + /* mac80211 allows over-riding some of the ht-capabilities */
> + local->hw.wiphy->ht_capa_mod_mask =
> + kzalloc(sizeof(*local->hw.wiphy->ht_capa_mod_mask),
> + GFP_KERNEL);
> + if (local->hw.wiphy->ht_capa_mod_mask) {
> + struct ieee80211_ht_cap *cm = local->hw.wiphy->ht_capa_mod_mask;
> + u8 *r = (u8 *)(&cm->mcs.rx_mask);
> + memset(r, 0xff, IEEE80211_HT_MCS_MASK_LEN);
> + cm->cap_info |= IEEE80211_HT_CAP_MAX_AMSDU;
> + cm->ampdu_params_info |= IEEE80211_HT_AMPDU_PARM_FACTOR;
> + cm->ampdu_params_info |= IEEE80211_HT_AMPDU_PARM_DENSITY;
> + }
Why is this not just a static const that you fill manually? There's
nothing that's not constant here. So e.g.
static const struct ieee80211_ht_cap mac80211_ht_capa_mod_mask = {
.ampdu_params_info = IEEE80211_HT_AMPDU_PARM_FACTOR |
IEEE80211_HT_AMPDU_PARM_DENSITY,
.mcs = {
.rx_mask = { 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, },
},
/* etc */
};
> @@ -988,6 +1001,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
> fail_wiphy_register:
> if (local->wiphy_ciphers_allocated)
> kfree(local->hw.wiphy->cipher_suites);
> + kfree(local->hw.wiphy->ht_capa_mod_mask);
> + local->hw.wiphy->ht_capa_mod_mask = NULL;
No need for this then obviously.
Looks pretty good overall. This is _much_ more readable than the
previous series. :-)
johannes
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 2/2] mac80211: Support ht-cap over-rides.
2011-11-07 9:13 ` Johannes Berg
@ 2011-11-07 16:19 ` Ben Greear
2011-11-07 17:06 ` Johannes Berg
0 siblings, 1 reply; 12+ messages in thread
From: Ben Greear @ 2011-11-07 16:19 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
On 11/07/2011 01:13 AM, Johannes Berg wrote:
> On Fri, 2011-11-04 at 13:10 -0700, greearb@candelatech.com wrote:
>
>> +/*
>> + * Stations supporting 802.11n are required to support
>> + * at least the first 8 MCS rates. See section 7.3.2.56.4
>> + * and 20.1.1 of the 802.11n spec.
>> + */
>> +#define IEEE80211_HT_MCS_REQ_RATES_STA 8
>
> I'd prefer if this was a validation on the input from userspace directly
> in cfg80211, that way other drivers that want to implement this don't
> have to bother.
>
> That probably goes well with the validation of the supported mask that I
> asked for.
It is valid to request that the station use a lesser rate, it just
needs to advertise that it supports the first 8 rates. So, for the
rate-control logic, we use exactly what is passed in from user-space,
but when generating the HT-caps objects, we set a minimum of 8 MCS
rates.
So, if you want validation, then I'm going to have to add a second
mcs argument and mask to distinguish between what we should advertise
v/s what we should use to over-ride the local rate-control mechanism.
I will do this if you ask, but in my opinion, the current functionality
is good enough.
>> + /* mac80211 allows over-riding some of the ht-capabilities */
>> + local->hw.wiphy->ht_capa_mod_mask =
>> + kzalloc(sizeof(*local->hw.wiphy->ht_capa_mod_mask),
>> + GFP_KERNEL);
>> + if (local->hw.wiphy->ht_capa_mod_mask) {
>> + struct ieee80211_ht_cap *cm = local->hw.wiphy->ht_capa_mod_mask;
>> + u8 *r = (u8 *)(&cm->mcs.rx_mask);
>> + memset(r, 0xff, IEEE80211_HT_MCS_MASK_LEN);
>> + cm->cap_info |= IEEE80211_HT_CAP_MAX_AMSDU;
>> + cm->ampdu_params_info |= IEEE80211_HT_AMPDU_PARM_FACTOR;
>> + cm->ampdu_params_info |= IEEE80211_HT_AMPDU_PARM_DENSITY;
>> + }
>
> Why is this not just a static const that you fill manually? There's
> nothing that's not constant here. So e.g.
>
> static const struct ieee80211_ht_cap mac80211_ht_capa_mod_mask = {
> .ampdu_params_info = IEEE80211_HT_AMPDU_PARM_FACTOR |
> IEEE80211_HT_AMPDU_PARM_DENSITY,
> .mcs = {
> .rx_mask = { 0xff, 0xff, 0xff, 0xff, 0xff,
> 0xff, 0xff, 0xff, 0xff, 0xff, },
> },
> /* etc */
> };
Well, you suggested a pointer in the wiphy struct that was null
for non mac80211 interfaces. I'm not sure how to distinguish between
mac80211 and other wiphys when reporting the capabilities if I use
this global static. I also like that the non-static logic lets
us tweak this for individual drivers if that becomes an issue.
>> @@ -988,6 +1001,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
>> fail_wiphy_register:
>> if (local->wiphy_ciphers_allocated)
>> kfree(local->hw.wiphy->cipher_suites);
>> + kfree(local->hw.wiphy->ht_capa_mod_mask);
>> + local->hw.wiphy->ht_capa_mod_mask = NULL;
>
> No need for this then obviously.
>
>
> Looks pretty good overall. This is _much_ more readable than the
> previous series. :-)
Thanks...making progress :)
Ben
>
> johannes
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 1/2] wireless: Support ht-capabilities over-rides.
2011-11-07 9:06 ` Johannes Berg
@ 2011-11-07 16:27 ` Ben Greear
2011-11-07 17:02 ` Johannes Berg
2011-11-07 17:40 ` Ben Greear
1 sibling, 1 reply; 12+ messages in thread
From: Ben Greear @ 2011-11-07 16:27 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
On 11/07/2011 01:06 AM, Johannes Berg wrote:
> On Fri, 2011-11-04 at 13:10 -0700, greearb@candelatech.com wrote:
>
>> + * @NL80211_ATTR_DISABLE_HT: Force HT capable interfaces to disable
>> + * this feature.
>
> I can see this, but
>
>> + * @NL80211_ATTR_DISABLE_HT40: Disable HT-40 even if AP and hardware
>> + * support it.
>> + * @NL80211_ATTR_HT_CAPABILITY_MASK: Specify which bits of the HT_CAPs
>> + * to pay attention to.
>
> if you have the mask why do you still need the HT40? Isn't HT40 a flag
> in the mask? Or do you want this to affect TX/RX separately? You should
> spell that out more explicitly then.
I think it would work to just use the mask & ht-cap overrides to disable HT40.
I'll see if I can get that working properly.
>
>> --- a/net/wireless/core.c
>> +++ b/net/wireless/core.c
>> @@ -704,6 +704,9 @@ void wiphy_unregister(struct wiphy *wiphy)
>> flush_work(&rdev->scan_done_wk);
>> cancel_work_sync(&rdev->conn_work);
>> flush_work(&rdev->event_work);
>> +
>> + kfree(rdev->wiphy.ht_capa_mod_mask);
>> + rdev->wiphy.ht_capa_mod_mask = NULL;
>
> That doesn't seem right -- drivers should typically assign a static
> const variable to this pointer that can't be freed.
Earlier I think you argued that all of mac80211 drivers automatically supported
these features as long as I put in the limitations that certain values
could only be increased and certain only decreased, etc.
So, I put it in the mac80211 code instead of down in the drivers.
But, I can move it into ath9k if you prefer.
>> @@ -537,6 +539,12 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
>> memcpy(&req.crypto, crypt, sizeof(req.crypto));
>> req.use_mfp = use_mfp;
>> req.prev_bssid = prev_bssid;
>> + req.flags = assoc_flags;
>> + if (ht_capa)
>> + memcpy(&req.ht_capa, ht_capa, sizeof(req.ht_capa));
>> + if (ht_capa_mask)
>> + memcpy(&req.ht_capa_mask, ht_capa_mask,
>> + sizeof(req.ht_capa_mask));
>
> I think somewhere here you should mask this mask with the
> ht_capa_mod_mask. That way, you force drivers to advertise a correct
> ht_capa_mod_mask, if you don't do that we will certainly see drivers use
> more of ht_capa than contained in ht_capa_mod_mask. Probably should be a
> helper function since I think you might need it in more places.
Sure, I can add that.
Thanks,
Ben
>
> johannes
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 1/2] wireless: Support ht-capabilities over-rides.
2011-11-07 16:27 ` Ben Greear
@ 2011-11-07 17:02 ` Johannes Berg
0 siblings, 0 replies; 12+ messages in thread
From: Johannes Berg @ 2011-11-07 17:02 UTC (permalink / raw)
To: Ben Greear; +Cc: linux-wireless
On Mon, 2011-11-07 at 08:27 -0800, Ben Greear wrote:
> >> + kfree(rdev->wiphy.ht_capa_mod_mask);
> >> + rdev->wiphy.ht_capa_mod_mask = NULL;
> >
> > That doesn't seem right -- drivers should typically assign a static
> > const variable to this pointer that can't be freed.
>
> Earlier I think you argued that all of mac80211 drivers automatically supported
> these features as long as I put in the limitations that certain values
> could only be increased and certain only decreased, etc.
>
> So, I put it in the mac80211 code instead of down in the drivers.
> But, I can move it into ath9k if you prefer.
Err, no -- if I'm talking about "drivers" from cfg80211's point of view,
mac80211 is one of those "drivers"! This comment was only about the
weird way of freeing it and static const etc.
johannes
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 2/2] mac80211: Support ht-cap over-rides.
2011-11-07 16:19 ` Ben Greear
@ 2011-11-07 17:06 ` Johannes Berg
0 siblings, 0 replies; 12+ messages in thread
From: Johannes Berg @ 2011-11-07 17:06 UTC (permalink / raw)
To: Ben Greear; +Cc: linux-wireless
On Mon, 2011-11-07 at 08:19 -0800, Ben Greear wrote:
> > Why is this not just a static const that you fill manually? There's
> > nothing that's not constant here. So e.g.
> >
> > static const struct ieee80211_ht_cap mac80211_ht_capa_mod_mask = {
> > .ampdu_params_info = IEEE80211_HT_AMPDU_PARM_FACTOR |
> > IEEE80211_HT_AMPDU_PARM_DENSITY,
> > .mcs = {
> > .rx_mask = { 0xff, 0xff, 0xff, 0xff, 0xff,
> > 0xff, 0xff, 0xff, 0xff, 0xff, },
> > },
> > /* etc */
> > };
>
> Well, you suggested a pointer in the wiphy struct that was null
> for non mac80211 interfaces. I'm not sure how to distinguish between
> mac80211 and other wiphys when reporting the capabilities if I use
> this global static. I also like that the non-static logic lets
> us tweak this for individual drivers if that becomes an issue.
Right. So if you assign this pointer in alloc_hw() then the driver can
still override it before register_hw(). I don't see at all why it needs
to be dynamically allocated.
johannes
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 1/2] wireless: Support ht-capabilities over-rides.
2011-11-07 9:06 ` Johannes Berg
2011-11-07 16:27 ` Ben Greear
@ 2011-11-07 17:40 ` Ben Greear
2011-11-07 17:42 ` Johannes Berg
1 sibling, 1 reply; 12+ messages in thread
From: Ben Greear @ 2011-11-07 17:40 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
On 11/07/2011 01:06 AM, Johannes Berg wrote:
>> @@ -537,6 +539,12 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
>> memcpy(&req.crypto, crypt, sizeof(req.crypto));
>> req.use_mfp = use_mfp;
>> req.prev_bssid = prev_bssid;
>> + req.flags = assoc_flags;
>> + if (ht_capa)
>> + memcpy(&req.ht_capa, ht_capa, sizeof(req.ht_capa));
>> + if (ht_capa_mask)
>> + memcpy(&req.ht_capa_mask, ht_capa_mask,
>> + sizeof(req.ht_capa_mask));
>
> I think somewhere here you should mask this mask with the
> ht_capa_mod_mask. That way, you force drivers to advertise a correct
> ht_capa_mod_mask, if you don't do that we will certainly see drivers use
> more of ht_capa than contained in ht_capa_mod_mask. Probably should be a
> helper function since I think you might need it in more places.
This goes back to how hard we want to be on user-space. If we are lax,
and just ignore settings that are not (yet?) supported by the kernel,
then user-space becomes much easier to make backwards/forwards
compat. That is my preferred approach.
In order for drivers (I assume you mean mac80211 as a driver)
to support more stuff, then we will have to explicitly add
more code there. At that point, the ht-capa-mod-mask
will need to be updated to stay in sync. The mod-mask is going
to live in mac80211 as far as I can tell, it seems valid
to just keep them up to date in that manner and let user-space
be oblivious to the mask *if it prefers*.
If you feel strongly that we need to be very strict with
user-space in this case, then please say so, and I'll quite arguing
and code it up. It is going to make the hostapd code
more complex, however.
Thanks,
Ben
>
> johannes
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 1/2] wireless: Support ht-capabilities over-rides.
2011-11-07 17:40 ` Ben Greear
@ 2011-11-07 17:42 ` Johannes Berg
2011-11-07 17:45 ` Ben Greear
0 siblings, 1 reply; 12+ messages in thread
From: Johannes Berg @ 2011-11-07 17:42 UTC (permalink / raw)
To: Ben Greear; +Cc: linux-wireless
On Mon, 2011-11-07 at 09:40 -0800, Ben Greear wrote:
> On 11/07/2011 01:06 AM, Johannes Berg wrote:
>
> >> @@ -537,6 +539,12 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
> >> memcpy(&req.crypto, crypt, sizeof(req.crypto));
> >> req.use_mfp = use_mfp;
> >> req.prev_bssid = prev_bssid;
> >> + req.flags = assoc_flags;
> >> + if (ht_capa)
> >> + memcpy(&req.ht_capa, ht_capa, sizeof(req.ht_capa));
> >> + if (ht_capa_mask)
> >> + memcpy(&req.ht_capa_mask, ht_capa_mask,
> >> + sizeof(req.ht_capa_mask));
> >
> > I think somewhere here you should mask this mask with the
> > ht_capa_mod_mask. That way, you force drivers to advertise a correct
> > ht_capa_mod_mask, if you don't do that we will certainly see drivers use
> > more of ht_capa than contained in ht_capa_mod_mask. Probably should be a
> > helper function since I think you might need it in more places.
>
> This goes back to how hard we want to be on user-space. If we are lax,
> and just ignore settings that are not (yet?) supported by the kernel,
> then user-space becomes much easier to make backwards/forwards
> compat. That is my preferred approach.
No, not really -- I'm not saying reject it, I'm just saying don't let
userspace configure more than the driver said it could configure. if you
just do essentially "configured_masked &= advertised_mask" you still
keep this property you want, but you force drivers to advertise
everything users will be able to change otherwise it just doesn't take
effect.
johannes
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 1/2] wireless: Support ht-capabilities over-rides.
2011-11-07 17:42 ` Johannes Berg
@ 2011-11-07 17:45 ` Ben Greear
0 siblings, 0 replies; 12+ messages in thread
From: Ben Greear @ 2011-11-07 17:45 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
On 11/07/2011 09:42 AM, Johannes Berg wrote:
> On Mon, 2011-11-07 at 09:40 -0800, Ben Greear wrote:
>> On 11/07/2011 01:06 AM, Johannes Berg wrote:
>>
>>>> @@ -537,6 +539,12 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
>>>> memcpy(&req.crypto, crypt, sizeof(req.crypto));
>>>> req.use_mfp = use_mfp;
>>>> req.prev_bssid = prev_bssid;
>>>> + req.flags = assoc_flags;
>>>> + if (ht_capa)
>>>> + memcpy(&req.ht_capa, ht_capa, sizeof(req.ht_capa));
>>>> + if (ht_capa_mask)
>>>> + memcpy(&req.ht_capa_mask, ht_capa_mask,
>>>> + sizeof(req.ht_capa_mask));
>>>
>>> I think somewhere here you should mask this mask with the
>>> ht_capa_mod_mask. That way, you force drivers to advertise a correct
>>> ht_capa_mod_mask, if you don't do that we will certainly see drivers use
>>> more of ht_capa than contained in ht_capa_mod_mask. Probably should be a
>>> helper function since I think you might need it in more places.
>>
>> This goes back to how hard we want to be on user-space. If we are lax,
>> and just ignore settings that are not (yet?) supported by the kernel,
>> then user-space becomes much easier to make backwards/forwards
>> compat. That is my preferred approach.
>
> No, not really -- I'm not saying reject it, I'm just saying don't let
> userspace configure more than the driver said it could configure. if you
> just do essentially "configured_masked&= advertised_mask" you still
> keep this property you want, but you force drivers to advertise
> everything users will be able to change otherwise it just doesn't take
> effect.
Ok, I think I understand, and that sounds fine to me.
Thanks,
Ben
>
> johannes
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2011-11-07 17:45 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-04 20:10 [PATCH v4 1/2] wireless: Support ht-capabilities over-rides greearb
2011-11-04 20:10 ` [PATCH v4 2/2] mac80211: Support ht-cap over-rides greearb
2011-11-07 9:13 ` Johannes Berg
2011-11-07 16:19 ` Ben Greear
2011-11-07 17:06 ` Johannes Berg
2011-11-04 21:03 ` [PATCH v4 1/2] wireless: Support ht-capabilities over-rides Johannes Berg
2011-11-07 9:06 ` Johannes Berg
2011-11-07 16:27 ` Ben Greear
2011-11-07 17:02 ` Johannes Berg
2011-11-07 17:40 ` Ben Greear
2011-11-07 17:42 ` Johannes Berg
2011-11-07 17:45 ` Ben Greear
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).