Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 278239
b: refs/heads/master
c: 7e7c892
h: refs/heads/master
i:
  278237: 18fdffd
  278235: d9f520a
  278231: 46a56cf
  278223: 7fe4118
  278207: 3448c4a
v: v3
  • Loading branch information
Ben Greear authored and John W. Linville committed Nov 21, 2011
1 parent 924c2b7 commit 1104e4f
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 8 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: dd76986b0e398978ca32dd60c1b7dc50ab4e9ae1
refs/heads/master: 7e7c8926b2f4e3453b8aeb39cd814d2af3fec24f
14 changes: 14 additions & 0 deletions trunk/include/linux/nl80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -1169,6 +1169,17 @@ enum nl80211_commands {
* @NL80211_ATTR_PROBE_RESP: Probe Response template data. Contains the entire
* probe-response frame. The DA field in the 802.11 header is zero-ed out,
* to be filled by the FW.
* @NL80211_ATTR_DISABLE_HT: Force HT capable interfaces to disable
* this feature. Currently, only supported in mac80211 drivers.
* @NL80211_ATTR_HT_CAPABILITY_MASK: Specify which bits of the
* ATTR_HT_CAPABILITY to which attention should be paid.
* Currently, only mac80211 NICs support this feature.
* The values that may be configured are:
* MCS rates, MAX-AMSDU, HT-20-40 and HT_CAP_SGI_40
* AMPDU density and AMPDU factor.
* All values are treated as suggestions and may be ignored
* by the driver as required. The actual values may be seen in
* the station debugfs ht_caps file.
*
* @NL80211_ATTR_DFS_REGION: region for regulatory rules which this country
* abides to when initiating radiation on DFS channels. A country maps
Expand Down Expand Up @@ -1414,6 +1425,9 @@ enum nl80211_attrs {

NL80211_ATTR_DFS_REGION,

NL80211_ATTR_DISABLE_HT,
NL80211_ATTR_HT_CAPABILITY_MASK,

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

__NL80211_ATTR_AFTER_LAST,
Expand Down
27 changes: 27 additions & 0 deletions trunk/include/net/cfg80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -1043,6 +1043,15 @@ struct cfg80211_auth_request {
bool local_state_change;
};

/**
* enum cfg80211_assoc_req_flags - Over-ride default behaviour in association.
*
* @ASSOC_REQ_DISABLE_HT: Disable HT (802.11n)
*/
enum cfg80211_assoc_req_flags {
ASSOC_REQ_DISABLE_HT = BIT(0),
};

/**
* struct cfg80211_assoc_request - (Re)Association request data
*
Expand All @@ -1054,13 +1063,20 @@ 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. Un-supported values will be ignored.
* @ht_capa_mask: The bits of ht_capa which are to be used.
*/
struct cfg80211_assoc_request {
struct cfg80211_bss *bss;
const u8 *ie, *prev_bssid;
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;
};

/**
Expand Down Expand Up @@ -1159,6 +1175,10 @@ 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. Un-supported values will be ignored.
* @ht_capa_mask: The bits of ht_capa which are to be used.
*/
struct cfg80211_connect_params {
struct ieee80211_channel *channel;
Expand All @@ -1172,6 +1192,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;
};

/**
Expand Down Expand Up @@ -1938,6 +1961,8 @@ struct wiphy_wowlan_support {
* @wowlan: WoWLAN support information
*
* @ap_sme_capa: AP SME capabilities, flags from &enum nl80211_ap_sme_features.
* @ht_capa_mod_mask: 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 */
Expand Down Expand Up @@ -2027,6 +2052,8 @@ struct wiphy {
/* dir in debugfs: ieee80211/<wiphyname> */
struct dentry *debugfsdir;

const struct ieee80211_ht_cap *ht_capa_mod_mask;

#ifdef CONFIG_NET_NS
/* the network namespace this phy lives in currently */
struct net *_net;
Expand Down
10 changes: 8 additions & 2 deletions trunk/net/wireless/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -341,13 +341,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,
Expand Down Expand Up @@ -379,6 +383,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
bool channel_type_valid, unsigned int wait,
const u8 *buf, size_t len, bool no_cck,
bool dont_wait_for_ack, u64 *cookie);
void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
const struct ieee80211_ht_cap *ht_capa_mask);

/* SME */
int __cfg80211_connect(struct cfg80211_registered_device *rdev,
Expand Down
37 changes: 34 additions & 3 deletions trunk/net/wireless/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -501,13 +501,32 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
return err;
}

/* Do a logical ht_capa &= ht_capa_mask. */
void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
const struct ieee80211_ht_cap *ht_capa_mask)
{
int i;
u8 *p1, *p2;
if (!ht_capa_mask) {
memset(ht_capa, 0, sizeof(*ht_capa));
return;
}

p1 = (u8*)(ht_capa);
p2 = (u8*)(ht_capa_mask);
for (i = 0; i<sizeof(*ht_capa); i++)
p1[i] &= p2[i];
}

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)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct cfg80211_assoc_request req;
Expand Down Expand Up @@ -537,6 +556,15 @@ 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));
cfg80211_oper_and_ht_capa(&req.ht_capa_mask,
rdev->wiphy.ht_capa_mod_mask);

req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
if (!req.bss) {
Expand Down Expand Up @@ -574,14 +602,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;
Expand Down
44 changes: 43 additions & 1 deletion trunk/net/wireless/nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,10 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY,
.len = IEEE80211_MAX_DATA_LEN },
[NL80211_ATTR_DFS_REGION] = { .type = NLA_U8 },
[NL80211_ATTR_DISABLE_HT] = { .type = NLA_FLAG },
[NL80211_ATTR_HT_CAPABILITY_MASK] = {
.len = NL80211_HT_CAPABILITY_LEN
},
};

/* policy for the key attributes */
Expand Down Expand Up @@ -1032,6 +1036,11 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,

NLA_PUT_U32(msg, NL80211_ATTR_FEATURE_FLAGS, dev->wiphy.features);

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:
Expand Down Expand Up @@ -4413,6 +4422,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;
Expand Down Expand Up @@ -4456,11 +4468,25 @@ 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 (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;
}
Expand Down Expand Up @@ -4950,6 +4976,22 @@ 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 (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);
Expand Down
7 changes: 6 additions & 1 deletion trunk/net/wireless/sme.c
Original file line number Diff line number Diff line change
Expand Up @@ -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, &params->crypto);
false, &params->crypto,
params->flags, &params->ht_capa,
&params->ht_capa_mask);
if (err)
__cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
NULL, 0,
Expand Down Expand Up @@ -773,6 +775,9 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev,
wdev->connect_keys = NULL;
}

cfg80211_oper_and_ht_capa(&connect->ht_capa_mask,
rdev->wiphy.ht_capa_mod_mask);

if (connkeys && connkeys->def >= 0) {
int idx;
u32 cipher;
Expand Down

0 comments on commit 1104e4f

Please sign in to comment.