]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/wireless/nl80211.c
nl80211: Add support for EDMG channels
[linux.git] / net / wireless / nl80211.c
index cacd967046472e0a29c2b2b918a5f8380c1d8694..4565d7385884fdcdc10c8e29c43e7917cb684603 100644 (file)
@@ -298,6 +298,13 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
 
        [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
        [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
+       [NL80211_ATTR_WIPHY_EDMG_CHANNELS] = NLA_POLICY_RANGE(NLA_U8,
+                                               NL80211_EDMG_CHANNELS_MIN,
+                                               NL80211_EDMG_CHANNELS_MAX),
+       [NL80211_ATTR_WIPHY_EDMG_BW_CONFIG] = NLA_POLICY_RANGE(NLA_U8,
+                                               NL80211_EDMG_BW_CONFIG_MIN,
+                                               NL80211_EDMG_BW_CONFIG_MAX),
+
        [NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 },
        [NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 },
        [NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 },
@@ -1574,6 +1581,15 @@ static int nl80211_send_band_rateinfo(struct sk_buff *msg,
                nla_nest_end(msg, nl_iftype_data);
        }
 
+       /* add EDMG info */
+       if (sband->edmg_cap.channels &&
+           (nla_put_u8(msg, NL80211_BAND_ATTR_EDMG_CHANNELS,
+                      sband->edmg_cap.channels) ||
+           nla_put_u8(msg, NL80211_BAND_ATTR_EDMG_BW_CONFIG,
+                      sband->edmg_cap.bw_config)))
+
+               return -ENOBUFS;
+
        /* add bitrates */
        nl_rates = nla_nest_start_noflag(msg, NL80211_BAND_ATTR_RATES);
        if (!nl_rates)
@@ -2677,6 +2693,18 @@ int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
                                nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ2]);
        }
 
+       if (info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]) {
+               chandef->edmg.channels =
+                     nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]);
+
+               if (info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG])
+                       chandef->edmg.bw_config =
+                    nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG]);
+       } else {
+               chandef->edmg.bw_config = 0;
+               chandef->edmg.channels = 0;
+       }
+
        if (!cfg80211_chandef_valid(chandef)) {
                NL_SET_ERR_MSG(extack, "invalid channel definition");
                return -EINVAL;
@@ -9894,6 +9922,15 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
                        return -EINVAL;
        }
 
+       if (info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]) {
+               connect.edmg.channels =
+                     nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]);
+
+               if (info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG])
+                       connect.edmg.bw_config =
+                               nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG]);
+       }
+
        if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {
                connkeys = nl80211_parse_connkeys(rdev, info, NULL);
                if (IS_ERR(connkeys))