diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index ed32f97496d3..ebb63d80ad51 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c @@ -248,6 +248,8 @@ /* LMS registers */ #define MVPP2_SRC_ADDR_MIDDLE 0x24 #define MVPP2_SRC_ADDR_HIGH 0x28 +#define MVPP2_PHY_AN_CFG0_REG 0x34 +#define MVPP2_PHY_AN_STOP_SMI0_MASK BIT(7) #define MVPP2_MIB_COUNTERS_BASE(port) (0x1000 + ((port) >> 1) * \ 0x400 + (port) * 0x400) #define MVPP2_MIB_LATE_COLLISION 0x7c @@ -278,6 +280,7 @@ #define MVPP2_GMAC_CONFIG_MII_SPEED BIT(5) #define MVPP2_GMAC_CONFIG_GMII_SPEED BIT(6) #define MVPP2_GMAC_AN_SPEED_EN BIT(7) +#define MVPP2_GMAC_FC_ADV_EN BIT(9) #define MVPP2_GMAC_CONFIG_FULL_DUPLEX BIT(12) #define MVPP2_GMAC_AN_DUPLEX_EN BIT(13) #define MVPP2_GMAC_PORT_FIFO_CFG_1_REG 0x1c @@ -3809,16 +3812,30 @@ static void mvpp2_interrupts_unmask(void *arg) static void mvpp2_port_mii_set(struct mvpp2_port *port) { - u32 reg, val = 0; + u32 val; - if (port->phy_interface == PHY_INTERFACE_MODE_SGMII) - val = MVPP2_GMAC_PCS_ENABLE_MASK | - MVPP2_GMAC_INBAND_AN_MASK; - else if (port->phy_interface == PHY_INTERFACE_MODE_RGMII) - val = MVPP2_GMAC_PORT_RGMII_MASK; + val = readl(port->base + MVPP2_GMAC_CTRL_2_REG); - reg = readl(port->base + MVPP2_GMAC_CTRL_2_REG); - writel(reg | val, port->base + MVPP2_GMAC_CTRL_2_REG); + switch (port->phy_interface) { + case PHY_INTERFACE_MODE_SGMII: + val |= MVPP2_GMAC_INBAND_AN_MASK; + break; + case PHY_INTERFACE_MODE_RGMII: + val |= MVPP2_GMAC_PORT_RGMII_MASK; + default: + val &= ~MVPP2_GMAC_PCS_ENABLE_MASK; + } + + writel(val, port->base + MVPP2_GMAC_CTRL_2_REG); +} + +static void mvpp2_port_fc_adv_enable(struct mvpp2_port *port) +{ + u32 val; + + val = readl(port->base + MVPP2_GMAC_AUTONEG_CONFIG); + val |= MVPP2_GMAC_FC_ADV_EN; + writel(val, port->base + MVPP2_GMAC_AUTONEG_CONFIG); } static void mvpp2_port_enable(struct mvpp2_port *port) @@ -5877,6 +5894,7 @@ static void mvpp2_port_power_up(struct mvpp2_port *port) { mvpp2_port_mii_set(port); mvpp2_port_periodic_xon_disable(port); + mvpp2_port_fc_adv_enable(port); mvpp2_port_reset(port); } @@ -6197,6 +6215,7 @@ static int mvpp2_init(struct platform_device *pdev, struct mvpp2 *priv) { const struct mbus_dram_target_info *dram_target_info; int err, i; + u32 val; /* Checks for hardware constraints */ if (rxq_number % 4 || (rxq_number > MVPP2_MAX_RXQ) || @@ -6210,6 +6229,11 @@ static int mvpp2_init(struct platform_device *pdev, struct mvpp2 *priv) if (dram_target_info) mvpp2_conf_mbus_windows(dram_target_info, priv); + /* Disable HW PHY polling */ + val = readl(priv->lms_base + MVPP2_PHY_AN_CFG0_REG); + val |= MVPP2_PHY_AN_STOP_SMI0_MASK; + writel(val, priv->lms_base + MVPP2_PHY_AN_CFG0_REG); + /* Allocate and initialize aggregated TXQs */ priv->aggr_txqs = devm_kcalloc(&pdev->dev, num_present_cpus(), sizeof(struct mvpp2_tx_queue),