Thread (20 messages) 20 messages, 2 authors, 2025-02-28

Re: [PATCH net-next v3 03/13] net: phy: phy_caps: Move phy_speeds to phy_caps

From: Maxime Chevallier <maxime.chevallier@bootlin.com>
Date: 2025-02-28 16:17:27
Also in: lkml, netdev

Hi Russell,

On Fri, 28 Feb 2025 16:10:35 +0000
"Russell King (Oracle)" [off-list ref] wrote:
On Fri, Feb 28, 2025 at 03:55:28PM +0100, Maxime Chevallier wrote:
quoted
Use the newly introduced link_capabilities array to derive the list of
possible speeds when given a combination of linkmodes. As
link_capabilities is indexed by speed, we don't have to iterate the
whole phy_settings array.

Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
[...]
quoted
+/**
+ * phy_caps_speeds() - Fill an array of supported SPEED_* values for given modes
+ * @speeds: Output array to store the speeds list into
+ * @size: Size of the output array
+ * @linkmodes: Linkmodes to get the speeds from
+ *
+ * Fills the speeds array with all possible speeds that can be achieved with
+ * the specified linkmodes.
+ *
+ * Returns: The number of speeds filled into the array. If the input array isn't
+ *	    big enough to store all speeds, fill it as much as possible.
+ */
+size_t phy_caps_speeds(unsigned int *speeds, size_t size,
+		       unsigned long *linkmodes)
+{
+	size_t count;
+	int capa;
+
+	for (capa = 0, count = 0; capa < __LINK_CAPA_MAX && count < size; capa++) {
+		if (linkmode_intersects(link_caps[capa].linkmodes, linkmodes) &&
+		    (count == 0 || speeds[count - 1] != link_caps[capa].speed))
+			speeds[count++] = link_caps[capa].speed;
+	}  
Having looked at several of these patches, there's a common pattern
emerging, which is we're walking over link_caps in either ascending
speed order or descending speed order. So I wonder whether it would
make sense to have:

#define for_each_link_caps_asc_speed(cap) \
	for (cap = link_caps; cap < &link_caps[__LINK_CAPA_MAX]; cap++)
#define for_each_link_caps_desc_speed(cap) \
	for (cap = &link_caps[__LINK_CAPA_MAX - 1]; cap >= link_caps; cap--)

for where iterating over in speed order is important. E.g. this would
make the above:

	struct link_capabilities *lcap;

	for_each_link_caps_asc_speed(lcap)
		if (linkmode_intersects(lcap->linkmodes, linkmodes) &&
		    (count == 0 || speeds[count - 1] != lcap->speed)) {
			speeds[count++] = lcap->speed;
			if (count >= size)
				break;
		}

which helps to make it explicit that speeds[] is in ascending value
order.
That makes a lot of sense indeed, I will definitely add that.

Thanks a lot for the review,

Maxime
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help