On Fri, Jun 12, 2020 at 11:42:08AM +0100, Russell King - ARM Linux admin wrote:
> On Fri, Jun 12, 2020 at 11:18:20AM +0100, Russell King - ARM Linux admin 
> wrote:
> > On Fri, Jun 12, 2020 at 11:01:15AM +0100, Russell King - ARM Linux admin 
> > wrote:
> > > On Fri, Jun 12, 2020 at 09:47:10AM +0100, Russell King - ARM Linux admin 
> > > wrote:
> > > > On Fri, Jun 12, 2020 at 10:38:47AM +0200, Sascha Hauer wrote:
> > > > > The Marvell MVNETA Ethernet controller supports a 2.5Gbps SGMII mode
> > > > > called DRSGMII. Depending on the Port MAC Control Register0 PortType
> > > > > setting this seems to be either an overclocked SGMII mode or 
> > > > > 2500BaseX.
> > > > > 
> > > > > This patch adds the necessary Serdes Configuration setting for the
> > > > > 2.5Gbps modes. There is no phy interface mode define for overclocked
> > > > > SGMII, so only 2500BaseX is handled for now.
> > > > > 
> > > > > As phy_interface_mode_is_8023z() returns true for both
> > > > > PHY_INTERFACE_MODE_1000BASEX and PHY_INTERFACE_MODE_2500BASEX we
> > > > > explicitly test for 1000BaseX instead of using
> > > > > phy_interface_mode_is_8023z() to differentiate the different
> > > > > possibilities.
> > > > > 
> > > > > Fixes: da58a931f248f ("net: mvneta: Add support for 2500Mbps SGMII")
> > > > > Signed-off-by: Sascha Hauer <s.ha...@pengutronix.de>
> > > > 
> > > > 2500base-X is used today on Armada 388 and Armada 3720 platforms and
> > > > works - it is known to interoperate with Marvell PP2.2 hardware, as
> > > > well was various SFPs such as the Huawei MA5671A at 2.5Gbps.  The way
> > > > it is handled on these platforms is via the COMPHY, requesting that
> > > > the serdes is upclocked from 1.25Gbps to 3.125Gbps.
> > > > 
> > > > This "DRSGMII" mode is not mentioned in the functional specs for either
> > > > the Armada 388 or Armada 3720, the value you poke into the register is
> > > > not mentioned either.  As I've already requested, some information on
> > > > exactly what this "DRSGMII" is would be very useful, it can't be
> > > > "double-rate SGMII" because that would give you 2Gbps instead of 1Gbps.
> > > > 
> > > > So, I suspect this breaks the platforms that are known to work.
> > > > 
> > > > We need a proper description of what DRSGMII is before we can consider
> > > > taking any patches for it.
> > > 
> > > Okay, having dug through the Armada XP, 370, 388, 3720 specs, I think
> > > this is fine after all - but something that will help for the future
> > > would be to document that this register does not exist on the 388 and
> > > 3720 devices (which brings up the question whether we should be writing
> > > it there.)  The field was moved into the comphy on those devices.
> > > 
> > > So, it looks like if we have a comphy, we should not be writing this
> > > register.
> > > 
> > > What's more, the write to MVNETA_SERDES_CFG should not be in
> > > mvneta_port_power_up(); it's likely that XP and 370 will not work
> > > properly with phylink.  It needs to be done in a similar location to
> > > mvneta_comphy_init(), so that phylink can switch between 1G and 2.5G
> > > speeds.
> > > 
> > > As you have an Armada XP system, you are best placed to test moving
> > > that write.
> > 
> > Here's my suggestion - it won't apply to mainline or net* trees, but
> > gives you the idea I'm proposing:
> > 
> > diff --git a/drivers/net/ethernet/marvell/mvneta.c 
> > b/drivers/net/ethernet/marvell/mvneta.c
> > index 9e25d608d856..17db74d61bc2 100644
> > --- a/drivers/net/ethernet/marvell/mvneta.c
> > +++ b/drivers/net/ethernet/marvell/mvneta.c
> > @@ -107,9 +107,11 @@
> >  #define      MVNETA_TX_IN_PRGRS                  BIT(1)
> >  #define      MVNETA_TX_FIFO_EMPTY                BIT(8)
> >  #define MVNETA_RX_MIN_FRAME_SIZE                 0x247c
> > +/* Only exists on Armada XP and Armada 370 */
> >  #define MVNETA_SERDES_CFG                   0x24A0
> > -#define      MVNETA_SGMII_SERDES_PROTO              0x0cc7
> >  #define      MVNETA_QSGMII_SERDES_PROTO             0x0667
> > +#define      MVNETA_SGMII_SERDES_PROTO              0x0cc7
> > +#define      MVNETA_HSGMII_SERDES_PROTO             0x1107
> >  #define MVNETA_TYPE_PRIO                         0x24bc
> >  #define      MVNETA_FORCE_UNI                    BIT(21)
> >  #define MVNETA_TXQ_CMD_1                         0x24e4
> > @@ -3457,9 +3459,6 @@ static int mvneta_comphy_init(struct mvneta_port *pp)
> >  {
> >     int ret;
> >  
> > -   if (!pp->comphy)
> > -           return 0;
> > -
> >     ret = phy_set_mode_ext(pp->comphy, PHY_MODE_ETHERNET,
> >                            pp->phy_interface);
> >     if (ret)
> > @@ -3468,11 +3467,47 @@ static int mvneta_comphy_init(struct mvneta_port 
> > *pp)
> >     return phy_power_on(pp->comphy);
> >  }
> >  
> > +static int mvneta_config_interface(struct mvneta_port *pp,i
> > +                              phy_interface_t interface)
> > +{
> > +   int ret = 0;
> > +
> > +   if (pp->comphy) {
> > +           if (interface == PHY_INTERFACE_MODE_SGMII ||
> > +               interface == PHY_INTERFACE_MODE_1000BASEX ||
> > +               interface == PHY_INTERFACE_MODE_2500BASEX) {
> > +                   ret = mvneta_comphy_init(pp);
> > +           }
> > +   } else {
> > +           switch (interface) {
> > +           case PHY_INTERFACE_MODE_QSGMII:
> > +                   mvreg_write(pp, MVNETA_SERDES_CFG,
> > +                               MVNETA_QSGMII_SERDES_PROTO);
> > +                   break;
> > +
> > +           case PHY_INTERFACE_MODE_SGMII:
> > +           case PHY_INTERFACE_MODE_1000BASEX:
> > +                   mvreg_write(pp, MVNETA_SERDES_CFG,
> > +                               MVNETA_SGMII_SERDES_PROTO);
> > +                   break;
> > +
> > +           case PHY_INTERFACE_MODE_2500BASEX:
> > +                   mvreg_write(pp, MVNETA_SERDES_CFG,
> > +                               MVNETA_HSGMII_SERDES_PROTO);
> > +                   break;
> > +           }
> > +   }
> > +
> > +   pp->phy_interface = interface;
> > +
> > +   return ret;
> > +}
> > +
> >  static void mvneta_start_dev(struct mvneta_port *pp)
> >  {
> >     int cpu;
> >  
> > -   WARN_ON(mvneta_comphy_init(pp));
> > +   WARN_ON(mvneta_config_interface(pp, pp->phy_interface));
> >  
> >     mvgmac_set_max_rx_size(&pp->gmac, pp->pkt_size);
> >     mvneta_txq_max_tx_size_set(pp, pp->pkt_size);
> > @@ -3702,14 +3737,9 @@ static int mvneta_pcs_config(struct phylink_config 
> > *config,
> >     /* We should never see Asym_Pause set */
> >     WARN_ON(phylink_test(advertising, Asym_Pause));
> >  
> > -   if (pp->comphy && pp->phy_interface != interface &&
> > -       (interface == PHY_INTERFACE_MODE_SGMII ||
> > -        interface == PHY_INTERFACE_MODE_1000BASEX ||
> > -        interface == PHY_INTERFACE_MODE_2500BASEX)) {
> > -           pp->phy_interface = interface;
> > -
> > +   if (pp->phy_interface != interface) {
> >             WARN_ON(phy_power_off(pp->comphy));
> > -           WARN_ON(mvneta_comphy_init(pp));
> > +           mvneta_config_interface(pp, interface);
> >     }
> >  
> >     if (want_1ms_clock) {
> > @@ -4794,12 +4824,10 @@ static int mvneta_port_power_up(struct mvneta_port 
> > *pp, int phy_mode)
> >     /* MAC Cause register should be cleared */
> >     mvreg_write(pp, MVNETA_UNIT_INTR_CAUSE, 0);
> >  
> > -   if (phy_mode == PHY_INTERFACE_MODE_QSGMII)
> > -           mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_QSGMII_SERDES_PROTO);
> > -   else if (phy_mode == PHY_INTERFACE_MODE_SGMII ||
> > -            phy_interface_mode_is_8023z(phy_mode))
> > -           mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO);
> > -   else if (!phy_interface_mode_is_rgmii(phy_mode))
> > +   if (phy_mode != PHY_INTERFACE_MODE_QSGMII &&
> > +       phy_mode != PHY_INTERFACE_MODE_SGMII &&
> > +       !phy_interface_mode_is_8023z(phy_mode) &&
> > +       !phy_interface_mode_is_rgmii(phy_mode))
> >             return -EINVAL;
> >  
> >     return 0;
> 
> With the obvious mistakes fixed (extraneous 'i' and lack of default
> case), it seems to still work on Armada 388 Clearfog Pro with 2.5G
> modules.

... and the other bug fixed - mvneta_comphy_init() needs to be passed
the interface mode.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

Reply via email to