diff mbox series

[net-next,3/4] net: phy: Add helper to derive the number of ports from a phy mode

Message ID 20220728145252.439201-4-maxime.chevallier@bootlin.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series net: Introduce QUSGMII phy mode | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for net-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Series has a cover letter
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 412 this patch: 412
netdev/cc_maintainers warning 3 maintainers not CCed: kuba@kernel.org pabeni@redhat.com edumazet@google.com
netdev/build_clang success Errors and warnings before: 299 this patch: 299
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 397 this patch: 397
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 66 lines checked
netdev/kdoc success Errors and warnings before: 1 this patch: 1
netdev/source_inline success Was 0 now: 0

Commit Message

Maxime Chevallier July 28, 2022, 2:52 p.m. UTC
Some phy modes such as QSGMII multiplex several MAC<->PHY links on one
single physical interface. QSGMII used to be the only one supported, but
other modes such as QUSGMII also carry multiple links.

This helper allows getting the number of links that are multiplexed
on a given interface.

Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
---
V1->V2 : New patch

 drivers/net/phy/phy-core.c | 52 ++++++++++++++++++++++++++++++++++++++
 include/linux/phy.h        |  2 ++
 2 files changed, 54 insertions(+)

Comments

Andrew Lunn July 28, 2022, 9:32 p.m. UTC | #1
> +int phy_interface_num_ports(phy_interface_t interface)
> +{
> +	switch (interface) {
> +	case PHY_INTERFACE_MODE_NA:
> +	case PHY_INTERFACE_MODE_INTERNAL:
> +		return 0;

I've not yet looked at how this is used. Returning 0 could have
interesting effects i guess? INTERNAL clearly does have some sort of
path between the MAC and the PHY, so i think 1 would be a better
value. NA is less clear, it generally means Don't touch. But again,
there still needs to be a path between the MAC and PHY, otherwise
there would not be any to touch.

Why did you pick 0?

> +
> +	case PHY_INTERFACE_MODE_MII:
> +	case PHY_INTERFACE_MODE_GMII:
> +	case PHY_INTERFACE_MODE_TBI:
> +	case PHY_INTERFACE_MODE_REVMII:
> +	case PHY_INTERFACE_MODE_RMII:
> +	case PHY_INTERFACE_MODE_REVRMII:
> +	case PHY_INTERFACE_MODE_RGMII:
> +	case PHY_INTERFACE_MODE_RGMII_ID:
> +	case PHY_INTERFACE_MODE_RGMII_RXID:
> +	case PHY_INTERFACE_MODE_RGMII_TXID:
> +	case PHY_INTERFACE_MODE_RTBI:
> +	case PHY_INTERFACE_MODE_XGMII:
> +	case PHY_INTERFACE_MODE_XLGMII:
> +	case PHY_INTERFACE_MODE_MOCA:
> +	case PHY_INTERFACE_MODE_TRGMII:
> +	case PHY_INTERFACE_MODE_USXGMII:
> +	case PHY_INTERFACE_MODE_SGMII:
> +	case PHY_INTERFACE_MODE_SMII:
> +	case PHY_INTERFACE_MODE_1000BASEX:
> +	case PHY_INTERFACE_MODE_2500BASEX:
> +	case PHY_INTERFACE_MODE_5GBASER:
> +	case PHY_INTERFACE_MODE_10GBASER:
> +	case PHY_INTERFACE_MODE_25GBASER:
> +	case PHY_INTERFACE_MODE_10GKR:
> +	case PHY_INTERFACE_MODE_100BASEX:
> +	case PHY_INTERFACE_MODE_RXAUI:
> +	case PHY_INTERFACE_MODE_XAUI:
> +		return 1;
> +	case PHY_INTERFACE_MODE_QSGMII:
> +	case PHY_INTERFACE_MODE_QUSGMII:
> +		return 4;
> +
> +	default:
> +		return 0;
> +	}
> +}

Have you tried without a default: ? I _think_ gcc will then warn about
missing enum values, which will help future developers when they add
further values to the enum.

	Andrew
Florian Fainelli July 28, 2022, 9:44 p.m. UTC | #2
On 7/28/22 14:32, Andrew Lunn wrote:
>> +int phy_interface_num_ports(phy_interface_t interface)
>> +{
>> +	switch (interface) {
>> +	case PHY_INTERFACE_MODE_NA:
>> +	case PHY_INTERFACE_MODE_INTERNAL:
>> +		return 0;
> 
> I've not yet looked at how this is used. Returning 0 could have
> interesting effects i guess? INTERNAL clearly does have some sort of
> path between the MAC and the PHY, so i think 1 would be a better
> value. NA is less clear, it generally means Don't touch. But again,
> there still needs to be a path between the MAC and PHY, otherwise
> there would not be any to touch.
> 
> Why did you pick 0?

I would agree that returning 1 is a more sensible default to avoid breaking users of that function. However this makes me wonder, in what case will we break the following common meaning:

- Q -> quad
- P -> penta
- O -> octal

Is the helper really needed in the sense that the phy_interface_t enumeration is explicit enough thanks to or because of its name?
--
Florian
Maxime Chevallier July 29, 2022, 6:50 a.m. UTC | #3
Hello Florian, Andrew,

On Thu, 28 Jul 2022 14:44:47 -0700
Florian Fainelli <f.fainelli@gmail.com> wrote:

> On 7/28/22 14:32, Andrew Lunn wrote:
> >> +int phy_interface_num_ports(phy_interface_t interface)
> >> +{
> >> +	switch (interface) {
> >> +	case PHY_INTERFACE_MODE_NA:
> >> +	case PHY_INTERFACE_MODE_INTERNAL:
> >> +		return 0;  
> > 
> > I've not yet looked at how this is used. Returning 0 could have
> > interesting effects i guess? INTERNAL clearly does have some sort of
> > path between the MAC and the PHY, so i think 1 would be a better
> > value. NA is less clear, it generally means Don't touch. But again,
> > there still needs to be a path between the MAC and PHY, otherwise
> > there would not be any to touch.
> > 
> > Why did you pick 0?  

My reasonning was that PHY_INTERNAL is likely a custom solution to link
IPs existing on the same die, so nothing prevents vendors from
multiplexing links on that interface. But it's a far-fetched
reasonning, so 1 can be good, as other interfaces that are meant to be
used on-die like XGMII.

> I would agree that returning 1 is a more sensible default to avoid
> breaking users of that function. However this makes me wonder, in
> what case will we break the following common meaning:
> 
> - Q -> quad
> - P -> penta
> - O -> octal
> 
> Is the helper really needed in the sense that the phy_interface_t
> enumeration is explicit enough thanks to or because of its name? --
> Florian

Good question actually ! It started as a point from Russell proposing a
helper to get the number of serdes lanes for a given interface, but
this sisn't quite fit the use-case, which was simply to simplify

	if (interface == PHY_INTERFACE_MODE_QSGMII ||
	    interface == PHY_INTERFACE_MODE_QUSGMII)

into

	if (phy_interface_num_ports(interface) == 4)

But this a slim simplification at the cost of a new helper to maintain,
so I can repove that if you want.

Thanks for the reviews,

Maxime
Maxime Chevallier July 29, 2022, 7:32 a.m. UTC | #4
On Thu, 28 Jul 2022 23:32:36 +0200
Andrew Lunn <andrew@lunn.ch> wrote:

> > +int phy_interface_num_ports(phy_interface_t interface)
> > +{
> > +	switch (interface) {
> > +	case PHY_INTERFACE_MODE_NA:
> > +	case PHY_INTERFACE_MODE_INTERNAL:
> > +		return 0;  
> 
> I've not yet looked at how this is used. Returning 0 could have
> interesting effects i guess? INTERNAL clearly does have some sort of
> path between the MAC and the PHY, so i think 1 would be a better
> value. NA is less clear, it generally means Don't touch. But again,
> there still needs to be a path between the MAC and PHY, otherwise
> there would not be any to touch.
> 
> Why did you pick 0?
> 
> > +
> > +	case PHY_INTERFACE_MODE_MII:
> > +	case PHY_INTERFACE_MODE_GMII:
> > +	case PHY_INTERFACE_MODE_TBI:
> > +	case PHY_INTERFACE_MODE_REVMII:
> > +	case PHY_INTERFACE_MODE_RMII:
> > +	case PHY_INTERFACE_MODE_REVRMII:
> > +	case PHY_INTERFACE_MODE_RGMII:
> > +	case PHY_INTERFACE_MODE_RGMII_ID:
> > +	case PHY_INTERFACE_MODE_RGMII_RXID:
> > +	case PHY_INTERFACE_MODE_RGMII_TXID:
> > +	case PHY_INTERFACE_MODE_RTBI:
> > +	case PHY_INTERFACE_MODE_XGMII:
> > +	case PHY_INTERFACE_MODE_XLGMII:
> > +	case PHY_INTERFACE_MODE_MOCA:
> > +	case PHY_INTERFACE_MODE_TRGMII:
> > +	case PHY_INTERFACE_MODE_USXGMII:
> > +	case PHY_INTERFACE_MODE_SGMII:
> > +	case PHY_INTERFACE_MODE_SMII:
> > +	case PHY_INTERFACE_MODE_1000BASEX:
> > +	case PHY_INTERFACE_MODE_2500BASEX:
> > +	case PHY_INTERFACE_MODE_5GBASER:
> > +	case PHY_INTERFACE_MODE_10GBASER:
> > +	case PHY_INTERFACE_MODE_25GBASER:
> > +	case PHY_INTERFACE_MODE_10GKR:
> > +	case PHY_INTERFACE_MODE_100BASEX:
> > +	case PHY_INTERFACE_MODE_RXAUI:
> > +	case PHY_INTERFACE_MODE_XAUI:
> > +		return 1;
> > +	case PHY_INTERFACE_MODE_QSGMII:
> > +	case PHY_INTERFACE_MODE_QUSGMII:
> > +		return 4;
> > +
> > +	default:
> > +		return 0;
> > +	}
> > +}  
> 
> Have you tried without a default: ? I _think_ gcc will then warn about
> missing enum values, which will help future developers when they add
> further values to the enum.

Without the default clause, I get an error about the missing
PHY_INTERFACE_MODE_MAX case, which I don't think belongs here...

Too bad :/

> 	Andrew
Andrew Lunn July 29, 2022, 1 p.m. UTC | #5
On Fri, Jul 29, 2022 at 09:32:52AM +0200, Maxime Chevallier wrote:
> On Thu, 28 Jul 2022 23:32:36 +0200
> Andrew Lunn <andrew@lunn.ch> wrote:
> 
> > > +int phy_interface_num_ports(phy_interface_t interface)
> > > +{
> > > +	switch (interface) {
> > > +	case PHY_INTERFACE_MODE_NA:
> > > +	case PHY_INTERFACE_MODE_INTERNAL:
> > > +		return 0;  
> > 
> > I've not yet looked at how this is used. Returning 0 could have
> > interesting effects i guess? INTERNAL clearly does have some sort of
> > path between the MAC and the PHY, so i think 1 would be a better
> > value. NA is less clear, it generally means Don't touch. But again,
> > there still needs to be a path between the MAC and PHY, otherwise
> > there would not be any to touch.
> > 
> > Why did you pick 0?
> > 
> > > +
> > > +	case PHY_INTERFACE_MODE_MII:
> > > +	case PHY_INTERFACE_MODE_GMII:
> > > +	case PHY_INTERFACE_MODE_TBI:
> > > +	case PHY_INTERFACE_MODE_REVMII:
> > > +	case PHY_INTERFACE_MODE_RMII:
> > > +	case PHY_INTERFACE_MODE_REVRMII:
> > > +	case PHY_INTERFACE_MODE_RGMII:
> > > +	case PHY_INTERFACE_MODE_RGMII_ID:
> > > +	case PHY_INTERFACE_MODE_RGMII_RXID:
> > > +	case PHY_INTERFACE_MODE_RGMII_TXID:
> > > +	case PHY_INTERFACE_MODE_RTBI:
> > > +	case PHY_INTERFACE_MODE_XGMII:
> > > +	case PHY_INTERFACE_MODE_XLGMII:
> > > +	case PHY_INTERFACE_MODE_MOCA:
> > > +	case PHY_INTERFACE_MODE_TRGMII:
> > > +	case PHY_INTERFACE_MODE_USXGMII:
> > > +	case PHY_INTERFACE_MODE_SGMII:
> > > +	case PHY_INTERFACE_MODE_SMII:
> > > +	case PHY_INTERFACE_MODE_1000BASEX:
> > > +	case PHY_INTERFACE_MODE_2500BASEX:
> > > +	case PHY_INTERFACE_MODE_5GBASER:
> > > +	case PHY_INTERFACE_MODE_10GBASER:
> > > +	case PHY_INTERFACE_MODE_25GBASER:
> > > +	case PHY_INTERFACE_MODE_10GKR:
> > > +	case PHY_INTERFACE_MODE_100BASEX:
> > > +	case PHY_INTERFACE_MODE_RXAUI:
> > > +	case PHY_INTERFACE_MODE_XAUI:
> > > +		return 1;
> > > +	case PHY_INTERFACE_MODE_QSGMII:
> > > +	case PHY_INTERFACE_MODE_QUSGMII:
> > > +		return 4;
> > > +
> > > +	default:
> > > +		return 0;
> > > +	}
> > > +}  
> > 
> > Have you tried without a default: ? I _think_ gcc will then warn about
> > missing enum values, which will help future developers when they add
> > further values to the enum.
> 
> Without the default clause, I get an error about the missing
> PHY_INTERFACE_MODE_MAX case, which I don't think belongs here...

  case PHY_INTERFACE_MODE_MAX:
	WARN_ONCE()
	return 0;
	break;

Being passed PHY_INTERFACE_MODE_MAX is a bug in itself, so warning
seems sensible.

      Andrew
diff mbox series

Patch

diff --git a/drivers/net/phy/phy-core.c b/drivers/net/phy/phy-core.c
index 1f2531a1a876..6029583f367d 100644
--- a/drivers/net/phy/phy-core.c
+++ b/drivers/net/phy/phy-core.c
@@ -74,6 +74,58 @@  const char *phy_duplex_to_str(unsigned int duplex)
 }
 EXPORT_SYMBOL_GPL(phy_duplex_to_str);
 
+/**
+ * phy_interface_num_ports - Return the number of links that can be carried by
+ *			     a given MAC-PHY physical link. Returns 0 if this is
+ *			     unknown, the number of links else.
+ *
+ * @interface: The interface mode we want to get the number of ports
+ */
+int phy_interface_num_ports(phy_interface_t interface)
+{
+	switch (interface) {
+	case PHY_INTERFACE_MODE_NA:
+	case PHY_INTERFACE_MODE_INTERNAL:
+		return 0;
+
+	case PHY_INTERFACE_MODE_MII:
+	case PHY_INTERFACE_MODE_GMII:
+	case PHY_INTERFACE_MODE_TBI:
+	case PHY_INTERFACE_MODE_REVMII:
+	case PHY_INTERFACE_MODE_RMII:
+	case PHY_INTERFACE_MODE_REVRMII:
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+	case PHY_INTERFACE_MODE_RTBI:
+	case PHY_INTERFACE_MODE_XGMII:
+	case PHY_INTERFACE_MODE_XLGMII:
+	case PHY_INTERFACE_MODE_MOCA:
+	case PHY_INTERFACE_MODE_TRGMII:
+	case PHY_INTERFACE_MODE_USXGMII:
+	case PHY_INTERFACE_MODE_SGMII:
+	case PHY_INTERFACE_MODE_SMII:
+	case PHY_INTERFACE_MODE_1000BASEX:
+	case PHY_INTERFACE_MODE_2500BASEX:
+	case PHY_INTERFACE_MODE_5GBASER:
+	case PHY_INTERFACE_MODE_10GBASER:
+	case PHY_INTERFACE_MODE_25GBASER:
+	case PHY_INTERFACE_MODE_10GKR:
+	case PHY_INTERFACE_MODE_100BASEX:
+	case PHY_INTERFACE_MODE_RXAUI:
+	case PHY_INTERFACE_MODE_XAUI:
+		return 1;
+	case PHY_INTERFACE_MODE_QSGMII:
+	case PHY_INTERFACE_MODE_QUSGMII:
+		return 4;
+
+	default:
+		return 0;
+	}
+}
+EXPORT_SYMBOL_GPL(phy_interface_num_ports);
+
 /* A mapping of all SUPPORTED settings to speed/duplex.  This table
  * must be grouped by speed and sorted in descending match priority
  * - iow, descending speed.
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 6b96b810a4d8..77e4b60bb9ab 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -967,6 +967,8 @@  struct phy_fixup {
 const char *phy_speed_to_str(int speed);
 const char *phy_duplex_to_str(unsigned int duplex);
 
+int phy_interface_num_ports(phy_interface_t interface);
+
 /* A structure for mapping a particular speed and duplex
  * combination to a particular SUPPORTED and ADVERTISED value
  */