Commit d79e4164 authored by Alex Elder's avatar Alex Elder Committed by Jakub Kicinski
Browse files

net: ipa: add an endpoint device attribute group



Create a new attribute group meant to provide a single place that
defines endpoint IDs that might be needed by user space.  Not all
defined endpoints are presented, and only those that are defined
will be made visible.

The new attributes use "extended" device attributes to hold endpoint
IDs, which is a little more compact and efficient.  Reimplement the
existing modem endpoint ID attribute files using common code.

Signed-off-by: default avatarAlex Elder <elder@linaro.org>
Link: https://lore.kernel.org/r/20220719191639.373249-1-elder@linaro.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent f12b86c0
Loading
Loading
Loading
Loading
+49 −13
Original line number Diff line number Diff line
@@ -46,33 +46,69 @@ Description:
		that is supported by the hardware.  The possible values
		are "MAPv4" or "MAPv5".

What:		.../XXXXXXX.ipa/endpoint_id/
Date:		July 2022
KernelVersion:	v5.19
Contact:	Alex Elder <elder@kernel.org>
Description:
		The .../XXXXXXX.ipa/endpoint_id/ directory contains
		attributes that define IDs associated with IPA
		endpoints.  The "rx" or "tx" in an endpoint name is
		from the perspective of the AP.  An endpoint ID is a
		small unsigned integer.

What:		.../XXXXXXX.ipa/endpoint_id/modem_rx
Date:		July 2022
KernelVersion:	v5.19
Contact:	Alex Elder <elder@kernel.org>
Description:
		The .../XXXXXXX.ipa/endpoint_id/modem_rx file contains
		the ID of the AP endpoint on which packets originating
		from the embedded modem are received.

What:		.../XXXXXXX.ipa/endpoint_id/modem_tx
Date:		July 2022
KernelVersion:	v5.19
Contact:	Alex Elder <elder@kernel.org>
Description:
		The .../XXXXXXX.ipa/endpoint_id/modem_tx file contains
		the ID of the AP endpoint on which packets destined
		for the embedded modem are sent.

What:		.../XXXXXXX.ipa/endpoint_id/monitor_rx
Date:		July 2022
KernelVersion:	v5.19
Contact:	Alex Elder <elder@kernel.org>
Description:
		The .../XXXXXXX.ipa/endpoint_id/monitor_rx file contains
		the ID of the AP endpoint on which IPA "monitor" data is
		received.  The monitor endpoint supplies replicas of
		packets that enter the IPA hardware for processing.
		Each replicated packet is preceded by a fixed-size "ODL"
		header (see .../XXXXXXX.ipa/feature/monitor, above).
		Large packets are truncated, to reduce the bandwidth
		required to provide the monitor function.

What:		.../XXXXXXX.ipa/modem/
Date:		June 2021
KernelVersion:	v5.14
Contact:	Alex Elder <elder@kernel.org>
Description:
		The .../XXXXXXX.ipa/modem/ directory contains a set of
		attributes describing properties of the modem execution
		environment reachable by the IPA hardware.
		The .../XXXXXXX.ipa/modem/ directory contains attributes
		describing properties of the modem embedded in the SoC.

What:		.../XXXXXXX.ipa/modem/rx_endpoint_id
Date:		June 2021
KernelVersion:	v5.14
Contact:	Alex Elder <elder@kernel.org>
Description:
		The .../XXXXXXX.ipa/feature/rx_endpoint_id file contains
		the AP endpoint ID that receives packets originating from
		the modem execution environment.  The "rx" is from the
		perspective of the AP; this endpoint is considered an "IPA
		producer".  An endpoint ID is a small unsigned integer.
		The .../XXXXXXX.ipa/modem/rx_endpoint_id file duplicates
		the value found in .../XXXXXXX.ipa/endpoint_id/modem_rx.

What:		.../XXXXXXX.ipa/modem/tx_endpoint_id
Date:		June 2021
KernelVersion:	v5.14
Contact:	Alex Elder <elder@kernel.org>
Description:
		The .../XXXXXXX.ipa/feature/tx_endpoint_id file contains
		the AP endpoint ID used to transmit packets destined for
		the modem execution environment.  The "tx" is from the
		perspective of the AP; this endpoint is considered an "IPA
		consumer".  An endpoint ID is a small unsigned integer.
		The .../XXXXXXX.ipa/modem/tx_endpoint_id file duplicates
		the value found in .../XXXXXXX.ipa/endpoint_id/modem_tx.
+1 −0
Original line number Diff line number Diff line
@@ -851,6 +851,7 @@ static void ipa_shutdown(struct platform_device *pdev)
static const struct attribute_group *ipa_attribute_groups[] = {
	&ipa_attribute_group,
	&ipa_feature_attribute_group,
	&ipa_endpoint_id_attribute_group,
	&ipa_modem_attribute_group,
	NULL,
};
+51 −18
Original line number Diff line number Diff line
@@ -96,38 +96,71 @@ const struct attribute_group ipa_feature_attribute_group = {
	.attrs		= ipa_feature_attrs,
};

static ssize_t
ipa_endpoint_id_show(struct ipa *ipa, char *buf, enum ipa_endpoint_name name)
static umode_t ipa_endpoint_id_is_visible(struct kobject *kobj,
					  struct attribute *attr, int n)
{
	u32 endpoint_id = ipa->name_map[name]->endpoint_id;
	struct ipa *ipa = dev_get_drvdata(kobj_to_dev(kobj));
	struct device_attribute *dev_attr;
	struct dev_ext_attribute *ea;
	bool visible;

	/* An endpoint id attribute is only visible if it's defined */
	dev_attr = container_of(attr, struct device_attribute, attr);
	ea = container_of(dev_attr, struct dev_ext_attribute, attr);

	return scnprintf(buf, PAGE_SIZE, "%u\n", endpoint_id);
	visible = !!ipa->name_map[(enum ipa_endpoint_name)(uintptr_t)ea->var];

	return visible ? attr->mode : 0;
}

static ssize_t rx_endpoint_id_show(struct device *dev,
static ssize_t endpoint_id_attr_show(struct device *dev,
				     struct device_attribute *attr, char *buf)
{
	struct ipa *ipa = dev_get_drvdata(dev);
	struct ipa_endpoint *endpoint;
	struct dev_ext_attribute *ea;

	ea = container_of(attr, struct dev_ext_attribute, attr);
	endpoint = ipa->name_map[(enum ipa_endpoint_name)(uintptr_t)ea->var];

	return ipa_endpoint_id_show(ipa, buf, IPA_ENDPOINT_AP_MODEM_RX);
	return sysfs_emit(buf, "%u\n", endpoint->endpoint_id);
}

static DEVICE_ATTR_RO(rx_endpoint_id);
#define ENDPOINT_ID_ATTR(_n, _endpoint_name)				    \
	static struct dev_ext_attribute dev_attr_endpoint_id_ ## _n = {	    \
		.attr	= __ATTR(_n, 0444, endpoint_id_attr_show, NULL),    \
		.var	= (void *)(_endpoint_name),			    \
	}

static ssize_t tx_endpoint_id_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
{
	struct ipa *ipa = dev_get_drvdata(dev);
ENDPOINT_ID_ATTR(modem_rx, IPA_ENDPOINT_AP_MODEM_RX);
ENDPOINT_ID_ATTR(modem_tx, IPA_ENDPOINT_AP_MODEM_TX);

static struct attribute *ipa_endpoint_id_attrs[] = {
	&dev_attr_endpoint_id_modem_rx.attr.attr,
	&dev_attr_endpoint_id_modem_tx.attr.attr,
	NULL
};

	return ipa_endpoint_id_show(ipa, buf, IPA_ENDPOINT_AP_MODEM_TX);
const struct attribute_group ipa_endpoint_id_attribute_group = {
	.name		= "endpoint_id",
	.is_visible	= ipa_endpoint_id_is_visible,
	.attrs		= ipa_endpoint_id_attrs,
};

/* Reuse endpoint ID attributes for the legacy modem endpoint IDs */
#define MODEM_ATTR(_n, _endpoint_name)					    \
	static struct dev_ext_attribute dev_attr_modem_ ## _n = {	    \
		.attr	= __ATTR(_n, 0444, endpoint_id_attr_show, NULL),    \
		.var	= (void *)(_endpoint_name),			    \
	}

static DEVICE_ATTR_RO(tx_endpoint_id);
MODEM_ATTR(rx_endpoint_id, IPA_ENDPOINT_AP_MODEM_RX);
MODEM_ATTR(tx_endpoint_id, IPA_ENDPOINT_AP_MODEM_TX);

static struct attribute *ipa_modem_attrs[] = {
	&dev_attr_rx_endpoint_id.attr,
	&dev_attr_tx_endpoint_id.attr,
	NULL
	&dev_attr_modem_rx_endpoint_id.attr.attr,
	&dev_attr_modem_tx_endpoint_id.attr.attr,
	NULL,
};

const struct attribute_group ipa_modem_attribute_group = {
+1 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ struct attribute_group;

extern const struct attribute_group ipa_attribute_group;
extern const struct attribute_group ipa_feature_attribute_group;
extern const struct attribute_group ipa_endpoint_id_attribute_group;
extern const struct attribute_group ipa_modem_attribute_group;

#endif /* _IPA_SYSFS_H_ */