public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Piergiorgio Beruto <piergiorgio.beruto@gmail.com>
To: Andrew Lunn <andrew@lunn.ch>
Cc: Heiner Kallweit <hkallweit1@gmail.com>,
	Russell King <linux@armlinux.org.uk>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
	Oleksij Rempel <o.rempel@pengutronix.de>
Subject: Re: [PATCH v4 net-next 5/5] drivers/net/phy: add driver for the onsemi NCN26000 10BASE-T1S PHY
Date: Tue, 6 Dec 2022 15:35:10 +0100	[thread overview]
Message-ID: <Y49THkXZdLBR6Mxv@gvm01> (raw)
In-Reply-To: <Y49IBR8ByMQH6oVt@lunn.ch>

Hi Andrew,
thank you for your review. Please, see my answers below.

Thanks,
Piergiorgio

On Tue, Dec 06, 2022 at 02:47:49PM +0100, Andrew Lunn wrote:
> > +// module parameter: if set, the link status is derived from the PLCA status
> > +// default: false
> > +static bool link_status_plca;
> > +module_param(link_status_plca, bool, 0644);
> 
> No module parameters, they are considered a bad user interface.
OK, as you see I'm a bit "outdated" :-)
What would be the alternative? There is a bunch of vendor-specific PHY
features that I would like to expose at some point (e.g. regulation of
TX voltage levels). Thanks!
 
> > +static int ncn26000_get_features(struct phy_device *phydev)
> > +{
> > +	linkmode_zero(phydev->supported);
> > +	linkmode_set_bit(ETHTOOL_LINK_MODE_MII_BIT, phydev->supported);
> > +
> > +	linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT1S_P2MP_Half_BIT,
> > +			 phydev->supported);
> > +
> > +	linkmode_copy(phydev->advertising, phydev->supported);
> 
> That should not be needed.
> 
> Also, look at PHY_BASIC_T1_FEATURES, and how it is used in
> microchip_t1.c.
In principle, I agree. But I have a problem with this specific chip, two
actually...

1. The chip does -not- set the MDIO_PMA_EXTABLE while it should. This
has been fixed in new versions of the chip, but for now, the bit is 0
so genphy_c45_baset1_able() reports 'false'.

2. This PHY is one of the PHYs that emulates AN (we discussed about this
earlier), but it does not actually implement it.

Therefore, I thought to just force the capabilities. In the future, I
could read the chip ID/version and make a decision based on that (force
or use the standard c45 functions).

Doe it make sense to you?

> > +static int ncn26000_read_status(struct phy_device *phydev)
> > +{
> > +	// The NCN26000 reports NCN26000_LINK_STATUS_BIT if the link status of
> > +	// the PHY is up. It further reports the logical AND of the link status
> > +	// and the PLCA status in the BMSR_LSTATUS bit. Thus, report the link
> > +	// status by testing the appropriate BMSR bit according to the module's
> > +	// parameter configuration.
> > +	const int lstatus_flag = link_status_plca ?
> > +		BMSR_LSTATUS : NCN26000_BMSR_LINK_STATUS_BIT;
> > +
> > +	int ret;
> > +
> > +	ret = phy_read(phydev, MII_BMSR);
> > +	if (unlikely(ret < 0))
> > +		return ret;
> > +
> > +	// update link status
> > +	phydev->link = (ret & lstatus_flag) ? 1 : 0;
> 
> What about the latching behaviour of LSTATUS?
See further down.

> 
> https://elixir.bootlin.com/linux/latest/source/drivers/net/phy/phy_device.c#L2289
> 
> > +
> > +	// handle more IRQs here
> 
> You are not in an IRQ handler...
Right, this is just a left-over when I moved the code from the ISR to
this functions. Fixed.

> You should also be setting speed and duplex. I don't think they are
> guaranteed to have any specific value if you don't set them.
Ah, I got that before, but I removed it after comment from Russell
asking me not to do this. Testing on my HW, this seems to work, although
I'm not sure whether this is correct or it is working 'by chance' ?

> > +
> > +	return 0;
> > +}
> > +
> > +static irqreturn_t ncn26000_handle_interrupt(struct phy_device *phydev)
> > +{
> > +	const struct ncn26000_priv *const priv = phydev->priv;
> > +	int ret;
> > +
> > +	// clear the latched bits in MII_BMSR
> > +	phy_read(phydev, MII_BMSR);
> 
> Why?
That was my ugly handling of the status double-read...
See the pacth below! I copied part of the code you suggested.

> 
> > +
> > +	// read and aknowledge the IRQ status register
> > +	ret = phy_read(phydev, NCN26000_REG_IRQ_STATUS);
> > +
> > +	if (unlikely(ret < 0) || (ret & priv->enabled_irqs) == 0)
> 
> How does NCN26000_REG_IRQ_STATUS work? Can it have bits set which are
> not in NCN26000_REG_IRQ_CTL ? That does happen sometimes, but is
> pretty unusual. If not, you don't need to track priv->enabled_irqs,
> just ensure ret is not 0.
It has a single bit that is not maskable. That would be the reset event
bit, which is triggered if the chip goes through a spurious reset. Since
I did not want to handle this in this first version of the driver, I
just masked it this way.
Thoughts?


diff --git a/drivers/net/phy/ncn26000.c b/drivers/net/phy/ncn26000.c
index 9e02c5c55244..198539b7ee66 100644
--- a/drivers/net/phy/ncn26000.c
+++ b/drivers/net/phy/ncn26000.c
@@ -92,15 +92,27 @@ static int ncn26000_read_status(struct phy_device *phydev)

        int ret;

+       /* The link state is latched low so that momentary link
+        * drops can be detected. Do not double-read the status
+        * in polling mode to detect such short link drops except
+        * the link was already down.
+        */
+       if (!phy_polling_mode(phydev) || !phydev->link) {
+               ret = phy_read(phydev, MII_BMSR);
+               if (ret < 0)
+                       return ret;
+               else if (ret & lstatus_flag)
+                       goto upd_link;
+       }
+
        ret = phy_read(phydev, MII_BMSR);
        if (unlikely(ret < 0))
                return ret;

+upd_link:
        // update link status
        phydev->link = (ret & lstatus_flag) ? 1 : 0;

-       // handle more IRQs here
-
        return 0;
 }

@@ -109,9 +121,6 @@ static irqreturn_t ncn26000_handle_interrupt(struct phy_device *phydev)
        const struct ncn26000_priv *const priv = phydev->priv;
        int ret;

-       // clear the latched bits in MII_BMSR
-       phy_read(phydev, MII_BMSR);
-
        // read and aknowledge the IRQ status register
        ret = phy_read(phydev, NCN26000_REG_IRQ_STATUS);

  reply	other threads:[~2022-12-06 14:35 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-06 12:52 [PATCH v4 net-next 0/5] add PLCA RS support and onsemi NCN26000 Piergiorgio Beruto
2022-12-06 12:52 ` [PATCH v4 net-next 1/5] net/ethtool: add netlink interface for the PLCA RS Piergiorgio Beruto
2022-12-06 12:52 ` [PATCH v4 net-next 2/5] drivers/net/phy: add the link modes for the 10BASE-T1S Ethernet PHY Piergiorgio Beruto
2022-12-06 12:53 ` [PATCH v4 net-next 3/5] drivers/net/phy: add connection between ethtool and phylib for PLCA Piergiorgio Beruto
2022-12-06 12:53 ` [PATCH v4 net-next 4/5] drivers/net/phy: add helpers to get/set PLCA configuration Piergiorgio Beruto
2022-12-06 13:59   ` Andrew Lunn
2022-12-06 18:07     ` Piergiorgio Beruto
2022-12-06 12:54 ` [PATCH v4 net-next 5/5] drivers/net/phy: add driver for the onsemi NCN26000 10BASE-T1S PHY Piergiorgio Beruto
2022-12-06 13:47   ` Andrew Lunn
2022-12-06 14:35     ` Piergiorgio Beruto [this message]
2022-12-06 14:57       ` Russell King (Oracle)
2022-12-06 18:06         ` Piergiorgio Beruto
2022-12-06 16:50       ` Andrew Lunn
2022-12-06 18:10         ` Piergiorgio Beruto
2022-12-06 19:12           ` Andrew Lunn
2022-12-07  0:33             ` Piergiorgio Beruto
2022-12-07 13:44               ` Andrew Lunn
  -- strict thread matches above, loose matches on Subject: below --
2023-01-09 16:59 [PATCH v4 net-next 0/5] add PLCA RS support and onsemi NCN26000 Piergiorgio Beruto
2023-01-09 17:00 ` [PATCH v4 net-next 5/5] drivers/net/phy: add driver for the onsemi NCN26000 10BASE-T1S PHY Piergiorgio Beruto

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Y49THkXZdLBR6Mxv@gvm01 \
    --to=piergiorgio.beruto@gmail.com \
    --cc=andrew@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=hkallweit1@gmail.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=netdev@vger.kernel.org \
    --cc=o.rempel@pengutronix.de \
    --cc=pabeni@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox