All of lore.kernel.org
 help / color / mirror / Atom feed
From: saeedb@amazon.com (BSHARA, Said)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH net-next 4/8] net: ethernet: add the Alpine Ethernet driver
Date: Sun, 5 Nov 2017 12:29:06 +0000	[thread overview]
Message-ID: <1509884946.21689.10.camel@amazon.com> (raw)
In-Reply-To: <723d35ce-aaa2-9011-19d6-99e77eed846f@gmail.com>

On Thu, 2017-11-02 at 11:19 -0700, Florian Fainelli wrote:
> On 11/02/2017 09:05 AM, Chocron, Jonathan wrote:
> > 
> > ?-----Original Message-----
> > > 
> > > From: Andrew Lunn [mailto:andrew at lunn.ch]
> > > Sent: Monday, August 28, 2017 9:10 PM
> > > To: Chocron, Jonathan <jonnyc@amazon.com>
> > > Cc: Antoine Tenart <antoine.tenart@free-electrons.com>;
> > > netdev at vger.kernel.org; davem at davemloft.net; linux-arm-
> > > kernel at lists.infradead.org; thomas.petazzoni at free-electrons.com;
> > > arnd at arndb.de
> > > Subject: Re: [PATCH net-next 4/8] net: ethernet: add the Alpine
> > > Ethernet
> > > driver
> > > 
> > > On Sun, Aug 27, 2017 at 01:47:19PM +0000, Chocron, Jonathan
> > > wrote:
> > > > 
> > > > This is a fixed version of my previous response (using proper
> > > > indentation
> > > and leaving only the specific questions responded to).
> > > 
> > > Wow, this is old.??3 Feb 2017. I had to go dig into the archive
> > > to refresh my
> > > memory.
> > > 
> > > > 
> > > > > 
> > > > > > 
> > > > > > +/* MDIO */
> > > > > > +#define AL_ETH_MDIO_C45_DEV_MASK?????0x1f0000
> > > > > > +#define AL_ETH_MDIO_C45_DEV_SHIFT????16
> > > > > > +#define AL_ETH_MDIO_C45_REG_MASK?????0xffff
> > > > > > +
> > > > > > +static int al_mdio_read(struct mii_bus *bp, int mii_id,
> > > > > > int reg)
> > > > > > +{
> > > > > > +?????struct al_eth_adapter *adapter = bp->priv;
> > > > > > +?????u16 value = 0;
> > > > > > +?????int rc;
> > > > > > +?????int timeout = MDIO_TIMEOUT_MSEC;
> > > > > > +
> > > > > > +?????while (timeout > 0) {
> > > > > > +?????????????if (reg & MII_ADDR_C45) {
> > > > > > +?????????????????????netdev_dbg(adapter->netdev, "[c45]:
> > > > > > dev %x reg %x val
> > > %x\n",
> > > > 
> > > > > 
> > > > > > 
> > > > > > +????????????????????????????????((reg &
> > > > > > AL_ETH_MDIO_C45_DEV_MASK) >>
> > > AL_ETH_MDIO_C45_DEV_SHIFT),
> > > > 
> > > > > 
> > > > > > 
> > > > > > +????????????????????????????????(reg &
> > > > > > AL_ETH_MDIO_C45_REG_MASK), value);
> > > > > > +?????????????????????rc = al_eth_mdio_read(&adapter-
> > > > > > >hw_adapter, adapter-
> > > > phy_addr,
> > > > > 
> > > > > > 
> > > > > > +?????????????????????????????((reg &
> > > > > > AL_ETH_MDIO_C45_DEV_MASK) >>
> > > AL_ETH_MDIO_C45_DEV_SHIFT),
> > > > 
> > > > > 
> > > > > > 
> > > > > > +?????????????????????????????(reg &
> > > > > > AL_ETH_MDIO_C45_REG_MASK), &value);
> > > > > > +?????????????} else {
> > > > > > +?????????????????????rc = al_eth_mdio_read(&adapter-
> > > > > > >hw_adapter, adapter-
> > > > phy_addr,
> > > > > 
> > > > > > 
> > > > > > +???????????????????????????????????????????MDIO_DEVAD_NONE
> > > > > > , reg, &value);
> > > > > > +?????????????}
> > > > > > +
> > > > > > +?????????????if (rc == 0)
> > > > > > +?????????????????????return value;
> > > > > > +
> > > > > > +?????????????netdev_dbg(adapter->netdev,
> > > > > > +????????????????????????"mdio read failed. try again in 10
> > > > > > + msec\n");
> > > > > > +
> > > > > > +?????????????timeout -= 10;
> > > > > > +?????????????msleep(10);
> > > > > > +?????}
> > > > > This is rather unusual, retrying MDIO operations. Are you
> > > > > working
> > > > > around a hardware bug? I suspect this also opens up race
> > > > > conditions,
> > > > > in particular with PHY interrupts, which can be clear on
> > > > > read.
> > > > The MDIO bus is shared between the ethernet units. There is a
> > > > HW lock
> > > > used to arbitrate between different interfaces trying to access
> > > > the
> > > > bus, therefore there is a retry loop. The reg isn't accessed
> > > > before
> > > > obtaining the lock, so there shouldn't be any clear on read
> > > > issues.
> > > > 
> > > > > 
> > > > > > 
> > > > > > +/* al_eth_mdiobus_setup - initialize mdiobus and register
> > > > > > to
> > > > > > +kernel */ static int al_eth_mdiobus_setup(struct
> > > > > > al_eth_adapter
> > > > > > +*adapter) {
> > > > > > +?????struct phy_device *phydev;
> > > > > > +?????int i;
> > > > > > +?????int ret = 0;
> > > > > > +
> > > > > > +?????adapter->mdio_bus = mdiobus_alloc();
> > > > > > +?????if (!adapter->mdio_bus)
> > > > > > +?????????????return -ENOMEM;
> > > > > > +
> > > > > > +?????adapter->mdio_bus->name?????= "al mdio bus";
> > > > > > +?????snprintf(adapter->mdio_bus->id, MII_BUS_ID_SIZE,
> > > > > > "%x",
> > > > > > +??????????????(adapter->pdev->bus->number << 8) | adapter-
> > > > > > >pdev-
> > > > devfn);
> > > > > 
> > > > > > 
> > > > > > +?????adapter->mdio_bus->priv?????= adapter;
> > > > > > +?????adapter->mdio_bus->parent???= &adapter->pdev->dev;
> > > > > > +?????adapter->mdio_bus->read?????= &al_mdio_read;
> > > > > > +?????adapter->mdio_bus->write????= &al_mdio_write;
> > > > > > +?????adapter->mdio_bus->phy_mask = ~BIT(adapter-
> > > > > > >phy_addr);
> > > > > Why do this?
> > > > Since the MDIO bus is shared, we want each interface to probe
> > > > only for the
> > > PHY associated with it.
> > > 
> > > So i think this is the core of the problem. You have one physical
> > > MDIO bus,
> > > yet you register it twice with the MDIO framework.
> > > 
> > > How about you only register it once? A lot of the complexity then
> > > goes away.
> > > The mutex in the mdio core per bus means you don't need your
> > > hardware
> > > locking. All that code goes away. All the retry code goes away.
> > > Life is simple.
> > > 
> > > 	Andrew
> > We indeed have one physical MDIO bus, but have multiple masters on
> > it,
> > each "behind" a different internal PCIe device. Since the accesses
> > to the bus
> > are done "indirectly" through each master, we can't register the
> > bus only once.
> How do your multiple masters get arbitrated on the unique MDIO bus?
> Is
> there hardware automatically doing that, or do you have to semaphore
> those accesses at the software level?
hardware level.
> 
> > 
> > Think of the scenario that we register it in the driver context of
> > PCIe device A,
> > and then the driver is unbound from just this device. Device B
> > won't be able
> > to access the bus since it was registered with callbacks that use a
> > PCIe BAR of
> > device A, which is no longer valid.
> You can have one single physical MDIO bus that you register once
> throughout the SoC's power on lifecycle, and then you can create
> "virtual" MDIO bus instances which map 1:1 with the PCIe
> device/function
> and are nested from that single MDIO bus, this also gives you
> serialization of accesses and arbitration for free.
the problem is that physical MDIO controller actually belongs to one of
the pcie devices and it's not independent interface, as the registers
address belongs to that pcie device, also, a reset to that pcie device
will reset the "shared" mdio controller.
> 
> > 
> > 
> > Is it possible to register the mdio_bus struct as a global instance
> > at driver load,
> > and someway pass the offset to the specific device's MDIO master,
> > as part of
> > each read/write transaction towards the MDIO bus?
> You can register how many instances of the MDIO bus you want in a
> system, it can be a singleton for the purpose of supporting your
> specific hardware, or you can build a layer on top like I just
> suggested
> above.
> 
> > 
> > Or perhaps you have another suggestion which takes into account the
> > issues I've described?
> Considering that binding to a MDIO bus is done by MDIO bus name
> (bus->id) and/or Device Tree parent/child hierarchy, if there is only
> one, just have all instances reference the same MDIO bus when they
> want
> to bind to their devices (pure mdio_device, or phy_device) on that
> MDIO bus.

WARNING: multiple messages have this Message-ID (diff)
From: "BSHARA, Said" <saeedb@amazon.com>
To: "f.fainelli@gmail.com" <f.fainelli@gmail.com>,
	"Chocron, Jonathan" <jonnyc@amazon.com>,
	"andrew@lunn.ch" <andrew@lunn.ch>
Cc: "thomas.petazzoni@free-electrons.com"
	<thomas.petazzoni@free-electrons.com>,
	"arnd@arndb.de" <arnd@arndb.de>,
	"netdev@vger.kernel.org" <netdev@vger.kernel.org>,
	"antoine.tenart@free-electrons.com"
	<antoine.tenart@free-electrons.com>,
	"davem@davemloft.net" <davem@davemloft.net>,
	"linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH net-next 4/8] net: ethernet: add the Alpine Ethernet driver
Date: Sun, 5 Nov 2017 12:29:06 +0000	[thread overview]
Message-ID: <1509884946.21689.10.camel@amazon.com> (raw)
In-Reply-To: <723d35ce-aaa2-9011-19d6-99e77eed846f@gmail.com>

On Thu, 2017-11-02 at 11:19 -0700, Florian Fainelli wrote:
> On 11/02/2017 09:05 AM, Chocron, Jonathan wrote:
> > 
> >  -----Original Message-----
> > > 
> > > From: Andrew Lunn [mailto:andrew@lunn.ch]
> > > Sent: Monday, August 28, 2017 9:10 PM
> > > To: Chocron, Jonathan <jonnyc@amazon.com>
> > > Cc: Antoine Tenart <antoine.tenart@free-electrons.com>;
> > > netdev@vger.kernel.org; davem@davemloft.net; linux-arm-
> > > kernel@lists.infradead.org; thomas.petazzoni@free-electrons.com;
> > > arnd@arndb.de
> > > Subject: Re: [PATCH net-next 4/8] net: ethernet: add the Alpine
> > > Ethernet
> > > driver
> > > 
> > > On Sun, Aug 27, 2017 at 01:47:19PM +0000, Chocron, Jonathan
> > > wrote:
> > > > 
> > > > This is a fixed version of my previous response (using proper
> > > > indentation
> > > and leaving only the specific questions responded to).
> > > 
> > > Wow, this is old.  3 Feb 2017. I had to go dig into the archive
> > > to refresh my
> > > memory.
> > > 
> > > > 
> > > > > 
> > > > > > 
> > > > > > +/* MDIO */
> > > > > > +#define AL_ETH_MDIO_C45_DEV_MASK     0x1f0000
> > > > > > +#define AL_ETH_MDIO_C45_DEV_SHIFT    16
> > > > > > +#define AL_ETH_MDIO_C45_REG_MASK     0xffff
> > > > > > +
> > > > > > +static int al_mdio_read(struct mii_bus *bp, int mii_id,
> > > > > > int reg)
> > > > > > +{
> > > > > > +     struct al_eth_adapter *adapter = bp->priv;
> > > > > > +     u16 value = 0;
> > > > > > +     int rc;
> > > > > > +     int timeout = MDIO_TIMEOUT_MSEC;
> > > > > > +
> > > > > > +     while (timeout > 0) {
> > > > > > +             if (reg & MII_ADDR_C45) {
> > > > > > +                     netdev_dbg(adapter->netdev, "[c45]:
> > > > > > dev %x reg %x val
> > > %x\n",
> > > > 
> > > > > 
> > > > > > 
> > > > > > +                                ((reg &
> > > > > > AL_ETH_MDIO_C45_DEV_MASK) >>
> > > AL_ETH_MDIO_C45_DEV_SHIFT),
> > > > 
> > > > > 
> > > > > > 
> > > > > > +                                (reg &
> > > > > > AL_ETH_MDIO_C45_REG_MASK), value);
> > > > > > +                     rc = al_eth_mdio_read(&adapter-
> > > > > > >hw_adapter, adapter-
> > > > phy_addr,
> > > > > 
> > > > > > 
> > > > > > +                             ((reg &
> > > > > > AL_ETH_MDIO_C45_DEV_MASK) >>
> > > AL_ETH_MDIO_C45_DEV_SHIFT),
> > > > 
> > > > > 
> > > > > > 
> > > > > > +                             (reg &
> > > > > > AL_ETH_MDIO_C45_REG_MASK), &value);
> > > > > > +             } else {
> > > > > > +                     rc = al_eth_mdio_read(&adapter-
> > > > > > >hw_adapter, adapter-
> > > > phy_addr,
> > > > > 
> > > > > > 
> > > > > > +                                           MDIO_DEVAD_NONE
> > > > > > , reg, &value);
> > > > > > +             }
> > > > > > +
> > > > > > +             if (rc == 0)
> > > > > > +                     return value;
> > > > > > +
> > > > > > +             netdev_dbg(adapter->netdev,
> > > > > > +                        "mdio read failed. try again in 10
> > > > > > + msec\n");
> > > > > > +
> > > > > > +             timeout -= 10;
> > > > > > +             msleep(10);
> > > > > > +     }
> > > > > This is rather unusual, retrying MDIO operations. Are you
> > > > > working
> > > > > around a hardware bug? I suspect this also opens up race
> > > > > conditions,
> > > > > in particular with PHY interrupts, which can be clear on
> > > > > read.
> > > > The MDIO bus is shared between the ethernet units. There is a
> > > > HW lock
> > > > used to arbitrate between different interfaces trying to access
> > > > the
> > > > bus, therefore there is a retry loop. The reg isn't accessed
> > > > before
> > > > obtaining the lock, so there shouldn't be any clear on read
> > > > issues.
> > > > 
> > > > > 
> > > > > > 
> > > > > > +/* al_eth_mdiobus_setup - initialize mdiobus and register
> > > > > > to
> > > > > > +kernel */ static int al_eth_mdiobus_setup(struct
> > > > > > al_eth_adapter
> > > > > > +*adapter) {
> > > > > > +     struct phy_device *phydev;
> > > > > > +     int i;
> > > > > > +     int ret = 0;
> > > > > > +
> > > > > > +     adapter->mdio_bus = mdiobus_alloc();
> > > > > > +     if (!adapter->mdio_bus)
> > > > > > +             return -ENOMEM;
> > > > > > +
> > > > > > +     adapter->mdio_bus->name     = "al mdio bus";
> > > > > > +     snprintf(adapter->mdio_bus->id, MII_BUS_ID_SIZE,
> > > > > > "%x",
> > > > > > +              (adapter->pdev->bus->number << 8) | adapter-
> > > > > > >pdev-
> > > > devfn);
> > > > > 
> > > > > > 
> > > > > > +     adapter->mdio_bus->priv     = adapter;
> > > > > > +     adapter->mdio_bus->parent   = &adapter->pdev->dev;
> > > > > > +     adapter->mdio_bus->read     = &al_mdio_read;
> > > > > > +     adapter->mdio_bus->write    = &al_mdio_write;
> > > > > > +     adapter->mdio_bus->phy_mask = ~BIT(adapter-
> > > > > > >phy_addr);
> > > > > Why do this?
> > > > Since the MDIO bus is shared, we want each interface to probe
> > > > only for the
> > > PHY associated with it.
> > > 
> > > So i think this is the core of the problem. You have one physical
> > > MDIO bus,
> > > yet you register it twice with the MDIO framework.
> > > 
> > > How about you only register it once? A lot of the complexity then
> > > goes away.
> > > The mutex in the mdio core per bus means you don't need your
> > > hardware
> > > locking. All that code goes away. All the retry code goes away.
> > > Life is simple.
> > > 
> > > 	Andrew
> > We indeed have one physical MDIO bus, but have multiple masters on
> > it,
> > each "behind" a different internal PCIe device. Since the accesses
> > to the bus
> > are done "indirectly" through each master, we can't register the
> > bus only once.
> How do your multiple masters get arbitrated on the unique MDIO bus?
> Is
> there hardware automatically doing that, or do you have to semaphore
> those accesses at the software level?
hardware level.
> 
> > 
> > Think of the scenario that we register it in the driver context of
> > PCIe device A,
> > and then the driver is unbound from just this device. Device B
> > won't be able
> > to access the bus since it was registered with callbacks that use a
> > PCIe BAR of
> > device A, which is no longer valid.
> You can have one single physical MDIO bus that you register once
> throughout the SoC's power on lifecycle, and then you can create
> "virtual" MDIO bus instances which map 1:1 with the PCIe
> device/function
> and are nested from that single MDIO bus, this also gives you
> serialization of accesses and arbitration for free.
the problem is that physical MDIO controller actually belongs to one of
the pcie devices and it's not independent interface, as the registers
address belongs to that pcie device, also, a reset to that pcie device
will reset the "shared" mdio controller.
> 
> > 
> > 
> > Is it possible to register the mdio_bus struct as a global instance
> > at driver load,
> > and someway pass the offset to the specific device's MDIO master,
> > as part of
> > each read/write transaction towards the MDIO bus?
> You can register how many instances of the MDIO bus you want in a
> system, it can be a singleton for the purpose of supporting your
> specific hardware, or you can build a layer on top like I just
> suggested
> above.
> 
> > 
> > Or perhaps you have another suggestion which takes into account the
> > issues I've described?
> Considering that binding to a MDIO bus is done by MDIO bus name
> (bus->id) and/or Device Tree parent/child hierarchy, if there is only
> one, just have all instances reference the same MDIO bus when they
> want
> to bind to their devices (pure mdio_device, or phy_device) on that
> MDIO bus.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2017-11-05 12:29 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-03 18:12 [PATCH net-next 0/8] ARM: Alpine: Ethernet support Antoine Tenart
2017-02-03 18:12 ` Antoine Tenart
2017-02-03 18:12 ` [PATCH net-next 1/8] alpine: add I/O fabric interrupt controller (iofic) helpers Antoine Tenart
2017-02-03 18:12   ` Antoine Tenart
2017-02-03 18:12 ` [PATCH net-next 2/8] soc: alpine: add udma helpers Antoine Tenart
2017-02-03 18:12   ` Antoine Tenart
2017-02-03 18:12 ` [PATCH net-next 3/8] pci: add Annapurna Labs PCI id Antoine Tenart
2017-02-03 18:12   ` Antoine Tenart
2017-02-03 18:12 ` [PATCH net-next 4/8] net: ethernet: add the Alpine Ethernet driver Antoine Tenart
2017-02-03 20:58   ` Andrew Lunn
2017-02-03 20:58     ` Andrew Lunn
2017-08-07  7:39     ` Chocron, Jonathan
2017-08-07  7:39       ` Chocron, Jonathan
2017-08-27 13:47     ` Chocron, Jonathan
2017-08-27 13:47       ` Chocron, Jonathan
2017-08-28 18:09       ` Andrew Lunn
2017-08-28 18:09         ` Andrew Lunn
2017-11-02 16:05         ` Chocron, Jonathan
2017-11-02 16:05           ` Chocron, Jonathan
2017-11-02 18:19           ` Florian Fainelli
2017-11-02 18:19             ` Florian Fainelli
2017-11-05 12:29             ` BSHARA, Said [this message]
2017-11-05 12:29               ` BSHARA, Said
2017-11-05 15:22               ` Andrew Lunn
2017-11-05 15:22                 ` Andrew Lunn
2017-02-03 18:12 ` [PATCH net-next 5/8] net: ethernet: annapurna: add statistics helper Antoine Tenart
2017-02-03 18:12   ` Antoine Tenart
2017-02-03 19:34   ` Florian Fainelli
2017-02-03 19:34     ` Florian Fainelli
2017-02-03 21:24   ` kbuild test robot
2017-02-03 21:24     ` kbuild test robot
2017-02-03 18:12 ` [PATCH net-next 6/8] net: ethernet: annapurna: add wol helpers to the Alpine driver Antoine Tenart
2017-02-03 18:12   ` Antoine Tenart
2017-02-03 18:21   ` Sergei Shtylyov
2017-02-03 18:21     ` Sergei Shtylyov
2017-02-06 11:35     ` David Laight
2017-02-06 11:35       ` David Laight
2017-02-06 12:02       ` Sergei Shtylyov
2017-02-06 12:02         ` Sergei Shtylyov
2017-02-10 10:12       ` Antoine Tenart
2017-02-10 10:12         ` Antoine Tenart
2017-02-03 18:12 ` [PATCH net-next 7/8] net: ethernet: annapurna: add eee " Antoine Tenart
2017-02-03 18:12   ` Antoine Tenart
2017-02-03 19:01   ` Florian Fainelli
2017-02-03 19:01     ` Florian Fainelli
2017-02-03 18:12 ` [PATCH net-next 8/8] net: ethernet: annapurna: add the coalesce " Antoine Tenart
2017-02-03 18:12   ` Antoine Tenart

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=1509884946.21689.10.camel@amazon.com \
    --to=saeedb@amazon.com \
    --cc=linux-arm-kernel@lists.infradead.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.