nl80211/cfg80211: add STA WME parameters

Add new NL80211_ATTR_STA_WME nested attribute that contains
wme params needed by the low-level driver (uapsd_queues and
max_sp).

Add these params to the station_parameters struct as well.

Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Eliad Peller 2011-08-23 14:37:46 +03:00 committed by John W. Linville
parent a21fa87e3a
commit c75786c9ef
3 changed files with 52 additions and 0 deletions

View file

@ -1042,6 +1042,9 @@ enum nl80211_commands {
* (Re)Association Response frames when the driver (or firmware) replies to
* (Re)Association Request frames.
*
* @NL80211_ATTR_STA_WME: Nested attribute containing the wme configuration
* of the station, see &enum nl80211_sta_wme_attr.
*
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@ -1252,6 +1255,8 @@ enum nl80211_attrs {
NL80211_ATTR_IE_PROBE_RESP,
NL80211_ATTR_IE_ASSOC_RESP,
NL80211_ATTR_STA_WME,
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@ -2482,4 +2487,22 @@ enum nl80211_hidden_ssid {
NL80211_HIDDEN_SSID_ZERO_CONTENTS
};
/**
* enum nl80211_sta_wme_attr - station WME attributes
* @__NL80211_STA_WME_INVALID: invalid number for nested attribute
* @NL80211_STA_WME_QUEUES: bitmap of uapsd queues.
* @NL80211_STA_WME_MAX_SP: max service period.
* @__NL80211_STA_WME_AFTER_LAST: internal
* @NL80211_STA_WME_MAX: highest station WME attribute
*/
enum nl80211_sta_wme_attr {
__NL80211_STA_WME_INVALID,
NL80211_STA_WME_UAPSD_QUEUES,
NL80211_STA_WME_MAX_SP,
/* keep last */
__NL80211_STA_WME_AFTER_LAST,
NL80211_STA_WME_MAX = __NL80211_STA_WME_AFTER_LAST - 1
};
#endif /* __LINUX_NL80211_H */

View file

@ -452,6 +452,8 @@ struct station_parameters {
u8 plink_action;
u8 plink_state;
struct ieee80211_ht_cap *ht_capa;
u8 uapsd_queues;
u8 max_sp;
};
/**

View file

@ -2545,6 +2545,12 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
return err;
}
static struct nla_policy
nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] __read_mostly = {
[NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
[NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
};
static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
@ -2590,6 +2596,27 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
if (parse_station_flags(info, &params))
return -EINVAL;
/* parse WME attributes if sta is WME capable */
if ((params.sta_flags_set & NL80211_STA_FLAG_WME) &&
info->attrs[NL80211_ATTR_STA_WME]) {
struct nlattr *tb[NL80211_STA_WME_MAX + 1];
struct nlattr *nla;
nla = info->attrs[NL80211_ATTR_STA_WME];
err = nla_parse_nested(tb, NL80211_STA_WME_MAX, nla,
nl80211_sta_wme_policy);
if (err)
return err;
if (tb[NL80211_STA_WME_UAPSD_QUEUES])
params.uapsd_queues =
nla_get_u8(tb[NL80211_STA_WME_UAPSD_QUEUES]);
if (tb[NL80211_STA_WME_MAX_SP])
params.max_sp =
nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
}
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&