mac80211/cfg80211: HT capabilities for NEW_STA
authorJouni Malinen <j@w1.fi>
Mon, 25 Aug 2008 08:58:58 +0000 (11:58 +0300)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 29 Aug 2008 20:24:09 +0000 (16:24 -0400)
Allow userspace (e.g., hostapd) to set HT capabilities for associated
STAs. This is based on a patch from Zhu Yi <yi.zhu@intel.com> (only
the NL80211_ATTR_HT_CAPABILITY for NEW_STA part is included here).

Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
include/linux/nl80211.h
include/net/cfg80211.h
net/mac80211/cfg.c
net/wireless/nl80211.c

index 447c02a..0c1147d 100644 (file)
@@ -207,6 +207,9 @@ enum nl80211_commands {
  * @NL80211_ATTR_BSS_SHORT_SLOT_TIME: whether short slot time enabled
  *     (u8, 0 or 1)
  *
+ * @NL80211_ATTR_HT_CAPABILITY: HT Capability information element (from
+ *     association request when used with NL80211_CMD_NEW_STATION)
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -254,16 +257,25 @@ enum nl80211_attrs {
        NL80211_ATTR_BSS_SHORT_PREAMBLE,
        NL80211_ATTR_BSS_SHORT_SLOT_TIME,
 
+       NL80211_ATTR_HT_CAPABILITY,
+
        /* add attributes here, update the policy in nl80211.c */
 
        __NL80211_ATTR_AFTER_LAST,
        NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
 };
 
+/*
+ * Allow user space programs to use #ifdef on new attributes by defining them
+ * here
+ */
+#define NL80211_ATTR_HT_CAPABILITY NL80211_ATTR_HT_CAPABILITY
+
 #define NL80211_MAX_SUPP_RATES                 32
 #define NL80211_TKIP_DATA_OFFSET_ENCR_KEY      0
 #define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY    16
 #define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY    24
+#define NL80211_HT_CAPABILITY_LEN              26
 
 /**
  * enum nl80211_iftype - (virtual) interface types
index 7afef14..0a72d1e 100644 (file)
@@ -152,6 +152,7 @@ struct station_parameters {
        u16 aid;
        u8 supported_rates_len;
        u8 plink_action;
+       struct ieee80211_ht_cap *ht_capa;
 };
 
 /**
index 2b19532..928813c 100644 (file)
@@ -674,6 +674,11 @@ static void sta_apply_parameters(struct ieee80211_local *local,
                sta->supp_rates[local->oper_channel->band] = rates;
        }
 
+       if (params->ht_capa) {
+               ieee80211_ht_cap_ie_to_ht_info(params->ht_capa,
+                                              &sta->ht_info);
+       }
+
        if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) {
                switch (params->plink_action) {
                case PLINK_ACTION_OPEN:
index 47542ee..4d6c02a 100644 (file)
@@ -91,6 +91,9 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
        [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
        [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
        [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
+
+       [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
+                                        .len = NL80211_HT_CAPABILITY_LEN },
 };
 
 /* message building helper */
@@ -1129,6 +1132,10 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
                params.listen_interval =
                    nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
 
+       if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
+               params.ht_capa =
+                       nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
+
        if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
                                &params.station_flags))
                return -EINVAL;
@@ -1192,6 +1199,9 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
        params.listen_interval =
                nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
        params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
+       if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
+               params.ht_capa =
+                       nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
 
        if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
                                &params.station_flags))