devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Gerhard Engleder <gerhard@engleder-embedded.com>
To: Andrew Lunn <andrew@lunn.ch>
Cc: David Miller <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>, netdev <netdev@vger.kernel.org>,
	devicetree@vger.kernel.org
Subject: Re: [PATCH net-next v2 3/3] tsnep: Add TSN endpoint Ethernet MAC driver
Date: Wed, 1 Sep 2021 22:18:45 +0200	[thread overview]
Message-ID: <CANr-f5zXWrqPxWV81CT6=4O6PoPRB0Qs0T=egJ3q8FMG16f6xw@mail.gmail.com> (raw)
In-Reply-To: <YS6lQejOJJCATMCp@lunn.ch>

> > +static int tsnep_ethtool_set_priv_flags(struct net_device *netdev,
> > +                                     u32 priv_flags)
> > +{
> > +     struct tsnep_adapter *adapter = netdev_priv(netdev);
> > +     int retval;
> > +
> > +     if (priv_flags & ~TSNEP_PRIV_FLAGS)
> > +             return -EINVAL;
> > +
> > +     if ((priv_flags & TSNEP_PRIV_FLAGS_LOOPBACK_100) &&
> > +         (priv_flags & TSNEP_PRIV_FLAGS_LOOPBACK_1000))
> > +             return -EINVAL;
> > +
> > +     if ((priv_flags & TSNEP_PRIV_FLAGS_LOOPBACK_100) &&
> > +         adapter->loopback != SPEED_100) {
> > +             if (adapter->loopback != SPEED_UNKNOWN)
> > +                     retval = phy_loopback(adapter->phydev, false);
> > +             else
> > +                     retval = 0;
> > +
> > +             if (!retval) {
> > +                     adapter->phydev->speed = SPEED_100;
> > +                     adapter->phydev->duplex = DUPLEX_FULL;
> > +                     retval = phy_loopback(adapter->phydev, true);
>
> This is a pretty unusual use of private flags, changing loopback at
> runtime. ethtool --test generally does that.
>
> What is your use case which requires loopback in normal operation, not
> during testing?

Yes it is unusual. I was searching for some user space interface for loopback
and found drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c which uses
private flags.

Use case is still testing and not normal operation. Testing is done mostly with
a user space application, because I don't want to overload the driver with test
code and test frameworks can be used in user space. With loopback it is
possible to execute a lot of tests like stressing the MAC with various frame
lengths and checking TX/RX time stamps. These tests are useful for every
integration of this IP core into an FPGA and not only for IP core development.

> > +static irqreturn_t tsnep_irq(int irq, void *arg)
> > +{
> > +     struct tsnep_adapter *adapter = arg;
> > +     u32 active = ioread32(adapter->addr + ECM_INT_ACTIVE);
> > +
> > +     /* acknowledge interrupt */
> > +     if (active != 0)
> > +             iowrite32(active, adapter->addr + ECM_INT_ACKNOWLEDGE);
> > +
> > +     /* handle management data interrupt */
> > +     if ((active & ECM_INT_MD) != 0) {
> > +             adapter->md_active = false;
> > +             wake_up_interruptible(&adapter->md_wait);
> > +     }
> > +
> > +     /* handle link interrupt */
> > +     if ((active & ECM_INT_LINK) != 0) {
> > +             if (adapter->netdev->phydev) {
> > +                     struct phy_device *phydev = adapter->netdev->phydev;
> > +                     u32 status = ioread32(adapter->addr + ECM_STATUS);
> > +                     int link = (status & ECM_NO_LINK) ? 0 : 1;
> > +                     u32 speed = status & ECM_SPEED_MASK;
>
> How does PHY link and speed get into this MAC register? Is the MAC
> polling the PHY over the MDIO bus? Is the PHY internal to the MAC and
> it has backdoor access to the PHY status?

PHY is external. The MAC expects additional signals for link status. These
signals can be derived from RGMII in band signaling of the link status or by
using PHY link and speed LED outputs. The MAC is using the link status for
a quick no link reaction to minimize the impact to real time applications.
EtherCAT for example also uses the link LED output for a no link reaction
within a few microseconds.

> > +static int tsnep_mdiobus_read(struct mii_bus *bus, int addr, int regnum)
> > +{
> > +     struct tsnep_adapter *adapter = bus->priv;
> > +     u32 md;
> > +     int retval;
> > +
> > +     if (regnum & MII_ADDR_C45)
> > +             return -EOPNOTSUPP;
> > +
> > +     /* management data frame without preamble */
> > +     md = ECM_MD_READ;
>
> I know some PHYs are happy to work without a preamble. But as far as i
> know, 802.3 c22 does not say it is optional. So this needs to be an
> opt-in feature, for when you know all the devices on the bus support
> it. We have a standard DT property for this. See mdio.yaml,
> suppress-preamble. Please look for this in the DT blob, and only
> suppress the pre-amble if it is present.

You are right, I will improve that.

> > +     md |= (regnum << ECM_MD_ADDR_SHIFT) & ECM_MD_ADDR_MASK;
> > +     md |= ECM_MD_PHY_ADDR_FLAG;
> > +     md |= (addr << ECM_MD_PHY_ADDR_SHIFT) & ECM_MD_PHY_ADDR_MASK;
> > +     adapter->md_active = true;
> > +     iowrite32(md, adapter->addr + ECM_MD_CONTROL);
> > +     retval = wait_event_interruptible(adapter->md_wait,
> > +                                       !adapter->md_active);
>
> It is pretty normal to have some sort of timeout here. So maybe use
> wait_event_interruptible_timeout()?

So far I could trust my hardware to generate the interrupt. But it makes
sense to not trust the hardware absolutely. I will add a timeout.

> > +static void tsnep_phy_link_status_change(struct net_device *netdev)
> > +{
> > +     phy_print_status(netdev->phydev);
> > +}
>
> There is normally something here, like telling the MAC what speed it
> should run at.

As explained above, the MAC knows the link speed due to additional signals
from the PHY. So there is no need to tell the MAC the link speed.

> > +     adapter->phydev->irq = PHY_MAC_INTERRUPT;
> > +     phy_start(adapter->phydev);
> > +     phy_start_aneg(adapter->phydev);
>
> No need to call phy_start_aneg().

Copied blindly from some other driver. I will fix that.
(drivers/net/ethernet/microchip/lan743x_main.c)

> > +static int tsnep_phy_init(struct tsnep_adapter *adapter)
> > +{
> > +     struct device_node *dn;
> > +     int retval;
> > +
> > +     retval = of_get_phy_mode(adapter->pdev->dev.of_node,
> > +                              &adapter->phy_mode);
> > +     if (retval)
> > +             adapter->phy_mode = PHY_INTERFACE_MODE_GMII;
> > +
> > +     dn = of_parse_phandle(adapter->pdev->dev.of_node, "phy-handle", 0);
> > +     adapter->phydev = of_phy_find_device(dn);
> > +     of_node_put(dn);
> > +     if (!adapter->phydev && adapter->mdiobus)
> > +             adapter->phydev = phy_find_first(adapter->mdiobus);
>
> Do you actually need phy_find_first()? It is better to have it in DT.

I thought it is a reasonable fallback, because then PHY can be ommited in
DT (lazy developer, unknown PHY address during development, ...). Driver
and IP core will be used also on x86 over PCIe without DT. In this case this
fallback also makes sense. But I must confess, the driver is not ready for
x86 use case yet.

> > +     return 0;
> > +
> > +     unregister_netdev(adapter->netdev);
>
> How do you get here? Is gcc is warning about unreachable code?

Left over for easy addition of goto labels. I will remove that.

Gerhard

  reply	other threads:[~2021-09-01 20:18 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-31 19:34 [PATCH net-next v2 0/3] TSN endpoint Ethernet MAC driver Gerhard Engleder
2021-08-31 19:34 ` [PATCH net-next v2 1/3] dt-bindings: Add vendor prefix for Engleder Gerhard Engleder
2021-09-01 12:32   ` Rob Herring
2021-08-31 19:34 ` [PATCH net-next v2 2/3] dt-bindings: net: Add tsnep Ethernet controller Gerhard Engleder
2021-09-01 12:33   ` Rob Herring
2021-08-31 19:34 ` [PATCH net-next v2 3/3] tsnep: Add TSN endpoint Ethernet MAC driver Gerhard Engleder
2021-08-31 21:55   ` Andrew Lunn
2021-09-01 20:18     ` Gerhard Engleder [this message]
2021-09-01 21:01       ` Andrew Lunn
2021-09-02 20:32         ` Gerhard Engleder
2021-09-02 21:21           ` Andrew Lunn
2021-09-03 19:53             ` Gerhard Engleder
2021-09-24 19:35         ` Gerhard Engleder
2021-08-31 23:12   ` kernel test robot
2021-09-02 23:17   ` Vinicius Costa Gomes
2021-09-03 20:14     ` Gerhard Engleder

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='CANr-f5zXWrqPxWV81CT6=4O6PoPRB0Qs0T=egJ3q8FMG16f6xw@mail.gmail.com' \
    --to=gerhard@engleder-embedded.com \
    --cc=andrew@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=kuba@kernel.org \
    --cc=netdev@vger.kernel.org \
    /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;
as well as URLs for NNTP newsgroup(s).