• Thomas Petazzoni's avatar
    net: mvneta: properly disable HW PHY polling and ensure adjust_link() works · 71408602
    Thomas Petazzoni authored
    This commit fixes a long-standing bug that has been reported by many
    users: on some Armada 370 platforms, only the network interface that
    has been used in U-Boot to tftp the kernel works properly in
    Linux. The other network interfaces can see a 'link up', but are
    unable to transmit data. The reports were generally made on the Armada
    370-based Mirabox, but have also been given on the Armada 370-RD
    board.
    
    The network MAC in the Armada 370/XP (supported by the mvneta driver
    in Linux) has a functionality that allows it to continuously poll the
    PHY and directly update the MAC configuration accordingly (speed,
    duplex, etc.). The very first versions of the driver submitted for
    review were using this hardware mechanism, but due to this, the driver
    was not integrated with the kernel phylib. Following reviews, the
    driver was changed to use the phylib, and therefore a software based
    polling. In software based polling, Linux regularly talks to the PHY
    over the MDIO bus, and sees if the link status has changed. If it's
    the case then the adjust_link() callback of the driver is called to
    update the MAC configuration accordingly.
    
    However, it turns out that the adjust_link() callback was not
    configuring the hardware in a completely correct way: while it was
    setting the speed and duplex bits correctly, it wasn't telling the
    hardware to actually take into account those bits rather than what the
    hardware-based PHY polling mechanism has concluded. So, in fact the
    adjust_link() callback was basically a no-op.
    
    However, the network happened to be working because on the network
    interfaces used by U-Boot for tftp on Armada 370 platforms because the
    hardware PHY polling was enabled by the bootloader, and left enabled
    by Linux. However, the second network interface not used for tftp (or
    both network interfaces if the kernel is loaded from USB, NAND or SD
    card) didn't had the hardware PHY polling enabled.
    
    This patch fixes this situation by:
    
     (1) Making sure that the hardware PHY polling is disabled by clearing
         the MVNETA_PHY_POLLING_ENABLE bit in the MVNETA_UNIT_CONTROL
         register in the driver ->probe() function.
    
     (2) Making sure that the duplex and speed selections made by the
         adjust_link() callback are taken into account by clearing the
         MVNETA_GMAC_AN_SPEED_EN and MVNETA_GMAC_AN_DUPLEX_EN bits in the
         MVNETA_GMAC_AUTONEG_CONFIG register.
    
    This patch has been tested on Armada 370 Mirabox, and now both network
    interfaces are usable after boot.
    
    [ Problem introduced by commit c5aff182 ("net: mvneta: driver for
      Marvell Armada 370/XP network unit") ]
    Signed-off-by: default avatarThomas Petazzoni <thomas.petazzoni@free-electrons.com>
    Cc: Willy Tarreau <w@1wt.eu>
    Cc: Jochen De Smet <jochen.armkernel@leahnim.org>
    Cc: Peter Sanford <psanford@nearbuy.io>
    Cc: Ethan Tuttle <ethan@ethantuttle.com>
    Cc: Chény Yves-Gael <yves@cheny.fr>
    Cc: Ryan Press <ryan@presslab.us>
    Cc: Simon Guinot <simon.guinot@sequanux.org>
    Cc: vdonnefort@lacie.com
    Cc: stable@vger.kernel.org
    Acked-by: default avatarJason Cooper <jason@lakedaemon.net>
    Tested-by: default avatarVincent Donnefort <vdonnefort@gmail.com>
    Tested-by: default avatarYves-Gael Cheny <yves@cheny.fr>
    Tested-by: default avatarGregory CLEMENT <gregory.clement@free-electrons.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    71408602
mvneta.c 75.8 KB