Skip to content

Commit

Permalink
cfg80211: pass station supported channel and oper class info
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Sunil Dutt authored and Johannes Berg committed Oct 11, 2013
1 parent 789fd03 commit c01fc9a
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 0 deletions.
8 changes: 8 additions & 0 deletions include/net/cfg80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,10 @@ enum station_parameters_apply_mask {
* @capability: station capability
* @ext_capab: extended capabilities of the station
* @ext_capab_len: number of extended capabilities
* @supported_channels: supported channels in IEEE 802.11 format
* @supported_channels_len: number of supported channels
* @supported_oper_classes: supported oper classes in IEEE 802.11 format
* @supported_oper_classes_len: number of supported operating classes
*/
struct station_parameters {
const u8 *supported_rates;
Expand All @@ -763,6 +767,10 @@ struct station_parameters {
u16 capability;
const u8 *ext_capab;
u8 ext_capab_len;
const u8 *supported_channels;
u8 supported_channels_len;
const u8 *supported_oper_classes;
u8 supported_oper_classes_len;
};

/**
Expand Down
9 changes: 9 additions & 0 deletions include/uapi/linux/nl80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -1496,6 +1496,11 @@ enum nl80211_commands {
* @NL80211_ATTR_RXMGMT_FLAGS: flags for nl80211_send_mgmt(), u32.
* As specified in the &enum nl80211_rxmgmt_flags.
*
* @NL80211_ATTR_STA_SUPPORTED_CHANNELS: array of supported channels.
*
* @NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES: array of supported
* supported operating classes.
*
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
Expand Down Expand Up @@ -1806,6 +1811,10 @@ enum nl80211_attrs {

NL80211_ATTR_RXMGMT_FLAGS,

NL80211_ATTR_STA_SUPPORTED_CHANNELS,

NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES,

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

__NL80211_ATTR_AFTER_LAST,
Expand Down
46 changes: 46 additions & 0 deletions net/wireless/nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED },
[NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_U16 },
[NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_U16 },
[NL80211_ATTR_STA_SUPPORTED_CHANNELS] = { .type = NLA_BINARY },
[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = { .type = NLA_BINARY },
};

/* policy for the key attributes */
Expand Down Expand Up @@ -3896,9 +3898,45 @@ static int nl80211_parse_sta_wme(struct genl_info *info,
return 0;
}

static int nl80211_parse_sta_channel_info(struct genl_info *info,
struct station_parameters *params)
{
if (info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]) {
params->supported_channels =
nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
params->supported_channels_len =
nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
/*
* Need to include at least one (first channel, number of
* channels) tuple for each subband, and must have proper
* tuples for the rest of the data as well.
*/
if (params->supported_channels_len < 2)
return -EINVAL;
if (params->supported_channels_len % 2)
return -EINVAL;
}

if (info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]) {
params->supported_oper_classes =
nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
params->supported_oper_classes_len =
nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
/*
* The value of the Length field of the Supported Operating
* Classes element is between 2 and 253.
*/
if (params->supported_oper_classes_len < 2 ||
params->supported_oper_classes_len > 253)
return -EINVAL;
}
return 0;
}

static int nl80211_set_station_tdls(struct genl_info *info,
struct station_parameters *params)
{
int err;
/* Dummy STA entry gets updated once the peer capabilities are known */
if (info->attrs[NL80211_ATTR_PEER_AID])
params->aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
Expand All @@ -3909,6 +3947,10 @@ static int nl80211_set_station_tdls(struct genl_info *info,
params->vht_capa =
nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);

err = nl80211_parse_sta_channel_info(info, params);
if (err)
return err;

return nl80211_parse_sta_wme(info, params);
}

Expand Down Expand Up @@ -4089,6 +4131,10 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
return -EINVAL;
}

err = nl80211_parse_sta_channel_info(info, &params);
if (err)
return err;

err = nl80211_parse_sta_wme(info, &params);
if (err)
return err;
Expand Down

0 comments on commit c01fc9a

Please sign in to comment.