From: Arnaud Patard Subject: Try to fix mvneta when compiled as module Forwarded: http://thread.gmane.org/gmane.linux.network/273997 - set "sgmii serdes configuration" register to magical value - enable clock earlier - move timer callback after setting timer.data [ discussions about this patch currently done with upstream ] Signed-off-by: Arnaud Patard --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -88,6 +88,8 @@ #define MVNETA_TX_IN_PRGRS BIT(1) #define MVNETA_TX_FIFO_EMPTY BIT(8) #define MVNETA_RX_MIN_FRAME_SIZE 0x247c +#define MVETH_SGMII_SERDES_CFG 0x24A0 +#define MVETH_SGMII_SERDES_STAT 0x24A4 #define MVNETA_TYPE_PRIO 0x24bc #define MVNETA_FORCE_UNI BIT(21) #define MVNETA_TXQ_CMD_1 0x24e4 @@ -655,6 +657,9 @@ static void mvneta_port_sgmii_config(str val = mvreg_read(pp, MVNETA_GMAC_CTRL_2); val |= MVNETA_GMAC2_PSC_ENABLE; mvreg_write(pp, MVNETA_GMAC_CTRL_2, val); + + /* magic value from https://github.com/yellowback/ubuntu-precise-armadaxp/blob/master/arch/arm/mach-armadaxp/armada_xp_family/ctrlEnv/mvCtrlEnvLib.c:2189 */ + mvreg_write(pp, MVETH_SGMII_SERDES_CFG, 0xcc7); } /* Start the Ethernet port RX and TX activity */ @@ -2728,20 +2733,10 @@ static int mvneta_probe(struct platform_ pp = netdev_priv(dev); - pp->tx_done_timer.function = mvneta_tx_done_timer_callback; - init_timer(&pp->tx_done_timer); - clear_bit(MVNETA_F_TX_DONE_TIMER_BIT, &pp->flags); - pp->weight = MVNETA_RX_POLL_WEIGHT; pp->phy_node = phy_node; pp->phy_interface = phy_mode; - pp->base = of_iomap(dn, 0); - if (pp->base == NULL) { - err = -ENOMEM; - goto err_free_irq; - } - pp->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(pp->clk)) { err = PTR_ERR(pp->clk); @@ -2765,7 +2760,16 @@ static int mvneta_probe(struct platform_ } } + pp->base = of_iomap(dn, 0); + if (pp->base == NULL) { + err = -ENOMEM; + goto err_free_irq; + } + pp->tx_done_timer.data = (unsigned long)dev; + pp->tx_done_timer.function = mvneta_tx_done_timer_callback; + init_timer(&pp->tx_done_timer); + clear_bit(MVNETA_F_TX_DONE_TIMER_BIT, &pp->flags); pp->tx_ring_size = MVNETA_MAX_TXD; pp->rx_ring_size = MVNETA_MAX_RXD;