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

Commit 9da8dbc9 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "cfg80211: Advertise extended capabilities per interface type to userspace"

parents 4c4eac84 9b3b73c1
Loading
Loading
Loading
Loading
+27 −1
Original line number Diff line number Diff line
@@ -2917,6 +2917,24 @@ struct wiphy_vendor_command {
		    const void *data, int data_len);
};

/**
 * struct wiphy_iftype_ext_capab - extended capabilities per interface type
 * @iftype: interface type
 * @extended_capabilities: extended capabilities supported by the driver,
 *	additional capabilities might be supported by userspace; these are the
 *	802.11 extended capabilities ("Extended Capabilities element") and are
 *	in the same format as in the information element. See IEEE Std
 *	802.11-2012 8.4.2.29 for the defined fields.
 * @extended_capabilities_mask: mask of the valid values
 * @extended_capabilities_len: length of the extended capabilities
 */
struct wiphy_iftype_ext_capab {
	enum nl80211_iftype iftype;
	const u8 *extended_capabilities;
	const u8 *extended_capabilities_mask;
	u8 extended_capabilities_len;
};

/**
 * struct wiphy - wireless hardware description
 * @reg_notifier: the driver's regulatory notification callback,
@@ -3026,9 +3044,14 @@ struct wiphy_vendor_command {
 *	additional capabilities might be supported by userspace; these are
 *	the 802.11 extended capabilities ("Extended Capabilities element")
 *	and are in the same format as in the information element. See
 *	802.11-2012 8.4.2.29 for the defined fields.
 *	802.11-2012 8.4.2.29 for the defined fields. These are the default
 *	extended capabilities to be used if the capabilities are not specified
 *	for a specific interface type in iftype_ext_capab.
 * @extended_capabilities_mask: mask of the valid values
 * @extended_capabilities_len: length of the extended capabilities
 * @iftype_ext_capab: array of extended capabilities per interface type
 * @num_iftype_ext_capab: number of interface types for which extended
 *	capabilities are specified separately.
 * @coalesce: packet coalescing support information
 *
 * @vendor_commands: array of vendor commands supported by the hardware
@@ -3121,6 +3144,9 @@ struct wiphy {
	const u8 *extended_capabilities, *extended_capabilities_mask;
	u8 extended_capabilities_len;

	const struct wiphy_iftype_ext_capab *iftype_ext_capab;
	unsigned int num_iftype_ext_capab;

	/* If multiple wiphys are registered and you're handed e.g.
	 * a regular netdev with assigned ieee80211_ptr, you won't
	 * know whether it points to a wiphy your driver has registered
+68 −0
Original line number Diff line number Diff line
@@ -1699,10 +1699,70 @@ enum nl80211_commands {
 * @NL80211_ATTR_SMPS_MODE: SMPS mode to use (ap mode). see
 *	&enum nl80211_smps_mode.
 *
 * @NL80211_ATTR_OPER_CLASS: operating class
 *
 * @NL80211_ATTR_MAC_MASK: MAC address mask
 *
 * @NL80211_ATTR_WIPHY_SELF_MANAGED_REG: flag attribute indicating this device
 *	is self-managing its regulatory information and any regulatory domain
 *	obtained from it is coming from the device's wiphy and not the global
 *	cfg80211 regdomain.
 *
 * @NL80211_ATTR_EXT_FEATURES: extended feature flags contained in a byte
 *	array. The feature flags are identified by their bit index (see &enum
 *	nl80211_ext_feature_index). The bit index is ordered starting at the
 *	least-significant bit of the first byte in the array, ie. bit index 0
 *	is located at bit 0 of byte 0. bit index 25 would be located at bit 1
 *	of byte 3 (u8 array).
 *
 * @NL80211_ATTR_SURVEY_RADIO_STATS: Request overall radio statistics to be
 *	returned along with other survey data. If set, @NL80211_CMD_GET_SURVEY
 *	may return a survey entry without a channel indicating global radio
 *	statistics (only some values are valid and make sense.)
 *	For devices that don't return such an entry even then, the information
 *	should be contained in the result as the sum of the respective counters
 *	over all channels.
 *
 * @NL80211_ATTR_SCHED_SCAN_DELAY: delay before the first cycle of a
 *	scheduled scan is started.  Or the delay before a WoWLAN
 *	net-detect scan is started, counting from the moment the
 *	system is suspended.  This value is a u32, in seconds.

 * @NL80211_ATTR_REG_INDOOR: flag attribute, if set indicates that the device
 *      is operating in an indoor environment.
 *
 * @NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS: maximum number of scan plans for
 *	scheduled scan supported by the device (u32), a wiphy attribute.
 * @NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL: maximum interval (in seconds) for
 *	a scan plan (u32), a wiphy attribute.
 * @NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS: maximum number of iterations in
 *	a scan plan (u32), a wiphy attribute.
 * @NL80211_ATTR_SCHED_SCAN_PLANS: a list of scan plans for scheduled scan.
 *	Each scan plan defines the number of scan iterations and the interval
 *	between scans. The last scan plan will always run infinitely,
 *	thus it must not specify the number of iterations, only the interval
 *	between scans. The scan plans are executed sequentially.
 *	Each scan plan is a nested attribute of &enum nl80211_sched_scan_plan.
 * @NL80211_ATTR_PBSS: flag attribute. If set it means operate
 *	in a PBSS. Specified in %NL80211_CMD_CONNECT to request
 *	connecting to a PCP, and in %NL80211_CMD_START_AP to start
 *	a PCP instead of AP. Relevant for DMG networks only.
 * @NL80211_ATTR_BSS_SELECT: nested attribute for driver supporting the
 *	BSS selection feature. When used with %NL80211_CMD_GET_WIPHY it contains
 *	attributes according &enum nl80211_bss_select_attr to indicate what
 *	BSS selection behaviours are supported. When used with %NL80211_CMD_CONNECT
 *	it contains the behaviour-specific attribute containing the parameters for
 *	BSS selection to be done by driver and/or firmware.
 *
 * @NL80211_ATTR_STA_SUPPORT_P2P_PS: whether P2P PS mechanism supported
 *	or not. u8, one of the values of &enum nl80211_sta_p2p_ps_status
 *
 * @NL80211_ATTR_PAD: attribute used for padding for 64-bit alignment
 *
 * @NL80211_ATTR_IFTYPE_EXT_CAPA: Nested attribute of the following attributes:
 *	%NL80211_ATTR_IFTYPE, %NL80211_ATTR_EXT_CAPA,
 *	%NL80211_ATTR_EXT_CAPA_MASK, to specify the extended capabilities per
 *	interface type.
 *
 * @NL80211_ATTR_MAX: highest attribute number currently defined
 * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2079,6 +2139,14 @@ enum nl80211_attrs {

	NL80211_ATTR_PBSS,

	NL80211_ATTR_BSS_SELECT,

	NL80211_ATTR_STA_SUPPORT_P2P_PS,

	NL80211_ATTR_PAD,

	NL80211_ATTR_IFTYPE_EXT_CAPA,

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

	__NL80211_ATTR_AFTER_LAST,
+30 −0
Original line number Diff line number Diff line
@@ -659,6 +659,36 @@ int wiphy_register(struct wiphy *wiphy)
		nl80211_send_reg_change_event(&request);
	}

	/* Check that nobody globally advertises any capabilities they do not
	 * advertise on all possible interface types.
	 */
	if (wiphy->extended_capabilities_len &&
	    wiphy->num_iftype_ext_capab &&
	    wiphy->iftype_ext_capab) {
		u8 supported_on_all, j;
		const struct wiphy_iftype_ext_capab *capab;

		capab = wiphy->iftype_ext_capab;
		for (j = 0; j < wiphy->extended_capabilities_len; j++) {
			if (capab[0].extended_capabilities_len > j)
				supported_on_all =
					capab[0].extended_capabilities[j];
			else
				supported_on_all = 0x00;
			for (i = 1; i < wiphy->num_iftype_ext_capab; i++) {
				if (j >= capab[i].extended_capabilities_len) {
					supported_on_all = 0x00;
					break;
				}
				supported_on_all &=
					capab[i].extended_capabilities[j];
			}
			if (WARN_ON(wiphy->extended_capabilities[j] &
				    ~supported_on_all))
				break;
		}
	}

	rdev->wiphy.registered = true;
	rtnl_unlock();

+42 −1
Original line number Diff line number Diff line
@@ -1230,7 +1230,7 @@ nl80211_send_mgmt_stypes(struct sk_buff *msg,
struct nl80211_dump_wiphy_state {
	s64 filter_wiphy;
	long start;
	long split_start, band_start, chan_start;
	long split_start, band_start, chan_start, capa_start;
	bool split;
};

@@ -1693,6 +1693,47 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
			       rdev->wiphy.max_num_csa_counters))
			goto nla_put_failure;

		state->split_start++;
		break;
	case 13:
		if (rdev->wiphy.num_iftype_ext_capab &&
		    rdev->wiphy.iftype_ext_capab) {
			struct nlattr *nested_ext_capab, *nested;

			nested = nla_nest_start(msg,
						NL80211_ATTR_IFTYPE_EXT_CAPA);
			if (!nested)
				goto nla_put_failure;

			for (i = state->capa_start;
			     i < rdev->wiphy.num_iftype_ext_capab; i++) {
				const struct wiphy_iftype_ext_capab *capab;

				capab = &rdev->wiphy.iftype_ext_capab[i];

				nested_ext_capab = nla_nest_start(msg, i);
				if (!nested_ext_capab ||
				    nla_put_u32(msg, NL80211_ATTR_IFTYPE,
						capab->iftype) ||
				    nla_put(msg, NL80211_ATTR_EXT_CAPA,
					    capab->extended_capabilities_len,
					    capab->extended_capabilities) ||
				    nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
					    capab->extended_capabilities_len,
					    capab->extended_capabilities_mask))
					goto nla_put_failure;

				nla_nest_end(msg, nested_ext_capab);
				if (state->split)
					break;
			}
			nla_nest_end(msg, nested);
			if (i < rdev->wiphy.num_iftype_ext_capab) {
				state->capa_start = i + 1;
				break;
			}
		}

		/* done */
		state->split_start = 0;
		break;