aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorSunil Dutt <c_duttus@qti.qualcomm.com>2013-10-09 11:15:21 -0400
committerJohannes Berg <johannes.berg@intel.com>2013-10-11 09:26:58 -0400
commitc01fc9ada926aaad907989ca2eba40c2a2a73afe (patch)
treea63aa4a69475d7fe5265927d834c8b0fcd6eb493 /net/wireless
parent789fd03331aa1ec45cb58168e2d82525c97c7351 (diff)
cfg80211: pass station supported channel and oper class info
The information of the peer's supported channels and supported operating classes are required for the driver to perform TDLS off channel operations. This commit enhances the function nl80211_(new)set_station to pass this information of the peer to the driver. Signed-off-by: Sunil Dutt <c_duttus@qti.qualcomm.com> [return errors for malformed tuples] Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/nl80211.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 2838206ddad3..460638ac2d73 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -354,6 +354,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
354 [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED }, 354 [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED },
355 [NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_U16 }, 355 [NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_U16 },
356 [NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_U16 }, 356 [NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_U16 },
357 [NL80211_ATTR_STA_SUPPORTED_CHANNELS] = { .type = NLA_BINARY },
358 [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = { .type = NLA_BINARY },
357}; 359};
358 360
359/* policy for the key attributes */ 361/* policy for the key attributes */
@@ -3896,9 +3898,45 @@ static int nl80211_parse_sta_wme(struct genl_info *info,
3896 return 0; 3898 return 0;
3897} 3899}
3898 3900
3901static int nl80211_parse_sta_channel_info(struct genl_info *info,
3902 struct station_parameters *params)
3903{
3904 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]) {
3905 params->supported_channels =
3906 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
3907 params->supported_channels_len =
3908 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
3909 /*
3910 * Need to include at least one (first channel, number of
3911 * channels) tuple for each subband, and must have proper
3912 * tuples for the rest of the data as well.
3913 */
3914 if (params->supported_channels_len < 2)
3915 return -EINVAL;
3916 if (params->supported_channels_len % 2)
3917 return -EINVAL;
3918 }
3919
3920 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]) {
3921 params->supported_oper_classes =
3922 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
3923 params->supported_oper_classes_len =
3924 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
3925 /*
3926 * The value of the Length field of the Supported Operating
3927 * Classes element is between 2 and 253.
3928 */
3929 if (params->supported_oper_classes_len < 2 ||
3930 params->supported_oper_classes_len > 253)
3931 return -EINVAL;
3932 }
3933 return 0;
3934}
3935
3899static int nl80211_set_station_tdls(struct genl_info *info, 3936static int nl80211_set_station_tdls(struct genl_info *info,
3900 struct station_parameters *params) 3937 struct station_parameters *params)
3901{ 3938{
3939 int err;
3902 /* Dummy STA entry gets updated once the peer capabilities are known */ 3940 /* Dummy STA entry gets updated once the peer capabilities are known */
3903 if (info->attrs[NL80211_ATTR_PEER_AID]) 3941 if (info->attrs[NL80211_ATTR_PEER_AID])
3904 params->aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]); 3942 params->aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
@@ -3909,6 +3947,10 @@ static int nl80211_set_station_tdls(struct genl_info *info,
3909 params->vht_capa = 3947 params->vht_capa =
3910 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]); 3948 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
3911 3949
3950 err = nl80211_parse_sta_channel_info(info, params);
3951 if (err)
3952 return err;
3953
3912 return nl80211_parse_sta_wme(info, params); 3954 return nl80211_parse_sta_wme(info, params);
3913} 3955}
3914 3956
@@ -4089,6 +4131,10 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
4089 return -EINVAL; 4131 return -EINVAL;
4090 } 4132 }
4091 4133
4134 err = nl80211_parse_sta_channel_info(info, &params);
4135 if (err)
4136 return err;
4137
4092 err = nl80211_parse_sta_wme(info, &params); 4138 err = nl80211_parse_sta_wme(info, &params);
4093 if (err) 4139 if (err)
4094 return err; 4140 return err;