Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fe9940c4 authored by Naresh Jayaram's avatar Naresh Jayaram
Browse files

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.

CRs-fixed: 595620
Change-Id: Ibe49b92bb292209f9eaf13530026c1dfea1de052
Signed-off-by: default avatarNaresh Jayaram <njayar@codeaurora.org>
parent 84dce0d6
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -656,6 +656,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;
@@ -675,6 +679,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;
};

/**
+35 −0
Original line number Diff line number Diff line
@@ -1434,6 +1434,28 @@ enum nl80211_commands {
 *	allowed to be used with the first @NL80211_CMD_SET_STATION command to
 *	update a TDLS peer STA entry.
 *
 * @NL80211_ATTR_COALESCE_RULE: Coalesce rule information.
 *
 * @NL80211_ATTR_CH_SWITCH_COUNT: u32 attribute specifying the number of TBTT's
 *	until the channel switch event.
 * @NL80211_ATTR_CH_SWITCH_BLOCK_TX: flag attribute specifying that transmission
 *	must be blocked on the current channel (before the channel switch
 *	operation).
 * @NL80211_ATTR_CSA_IES: Nested set of attributes containing the IE information
 *	for the time while performing a channel switch.
 * @NL80211_ATTR_CSA_C_OFF_BEACON: Offset of the channel switch counter
 *	field in the beacons tail (%NL80211_ATTR_BEACON_TAIL).
 * @NL80211_ATTR_CSA_C_OFF_PRESP: Offset of the channel switch counter
 *	field in the probe response (%NL80211_ATTR_PROBE_RESP).
 *
 * @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
 */
@@ -1734,6 +1756,19 @@ enum nl80211_attrs {

	NL80211_ATTR_PEER_AID,

	NL80211_ATTR_COALESCE_RULE,

	NL80211_ATTR_CH_SWITCH_COUNT,
	NL80211_ATTR_CH_SWITCH_BLOCK_TX,
	NL80211_ATTR_CSA_IES,
	NL80211_ATTR_CSA_C_OFF_BEACON,
	NL80211_ATTR_CSA_C_OFF_PRESP,

	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,
+46 −0
Original line number Diff line number Diff line
@@ -379,6 +379,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
	[NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
				  .len = IEEE80211_MAX_DATA_LEN },
	[NL80211_ATTR_PEER_AID] = { .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 */
@@ -3798,6 +3800,41 @@ static struct net_device *get_vlan(struct genl_info *info,
	return ERR_PTR(ret);
}

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 struct nla_policy
nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] __read_mostly = {
	[NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
@@ -3841,6 +3878,7 @@ static int nl80211_parse_sta_wme(struct genl_info *info,
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]);
@@ -3851,6 +3889,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);
}

@@ -4031,6 +4073,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;