diff options
Diffstat (limited to 'drivers/net/fec.c')
-rwxr-xr-x | drivers/net/fec.c | 73 |
1 files changed, 60 insertions, 13 deletions
diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 1ae6cb0f0210..b1fa4647f911 100755 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -156,6 +156,13 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address"); #define PKT_MINBUF_SIZE 64 #define PKT_MAXBLR_SIZE 1520 +/* Pause frame feild and FIFO threshold */ +#define FEC_ENET_FCE (1 << 5) +#define FEC_ENET_RSEM_V 0x84 +#define FEC_ENET_RSFL_V 16 +#define FEC_ENET_RAEM_V 0x8 +#define FEC_ENET_RAFL_V 0x8 +#define FEC_ENET_OPD_V 0xFFF0 /* * The 5270/5271/5280/5282/532x RX control register also contains maximum frame @@ -1449,6 +1456,28 @@ static const struct net_device_ops fec_netdev_ops = { #endif }; +/* Init TX buffer descriptors + */ +static void fec_enet_txbd_init(struct net_device *dev) +{ + struct fec_enet_private *fep = netdev_priv(dev); + struct bufdesc *bdp; + int i; + + /* ...and the same for transmit */ + bdp = fep->tx_bd_base; + for (i = 0; i < TX_RING_SIZE; i++) { + + /* Initialize the BD for every fragment in the page. */ + bdp->cbd_sc = 0; + bdp++; + } + + /* Set the last buffer to wrap */ + bdp--; + bdp->cbd_sc |= BD_SC_WRAP; +} + /* * XXX: We need to clean up on failure exits here. * @@ -1505,19 +1534,8 @@ static int fec_enet_init(struct net_device *ndev) bdp--; bdp->cbd_sc |= BD_SC_WRAP; - /* ...and the same for transmit */ - bdp = fep->tx_bd_base; - for (i = 0; i < TX_RING_SIZE; i++) { - - /* Initialize the BD for every fragment in the page. */ - bdp->cbd_sc = 0; - bdp->cbd_bufaddr = 0; - bdp++; - } - - /* Set the last buffer to wrap */ - bdp--; - bdp->cbd_sc |= BD_SC_WRAP; + /* Init transmit descriptors */ + fec_enet_txbd_init(ndev); fec_restart(ndev, 0); @@ -1568,6 +1586,8 @@ fec_restart(struct net_device *dev, int duplex) writel(fep->bd_dma, fep->hwp + FEC_R_DES_START); writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc) * RX_RING_SIZE, fep->hwp + FEC_X_DES_START); + /* Reinit transmit descriptors */ + fec_enet_txbd_init(dev); fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; fep->cur_rx = fep->rx_bd_base; @@ -1617,6 +1637,16 @@ fec_restart(struct net_device *dev, int duplex) else val |= (1 << 9); + /* Enable pause frame + * ENET pause frame has two issues as ticket TKT116501 + * The issues have been fixed on Rigel TO1.1 and Arik TO1.2 + */ + if ((cpu_is_mx6q() && + (mx6q_revision() >= IMX_CHIP_REVISION_1_2)) || + (cpu_is_mx6dl() && + (mx6dl_revision() >= IMX_CHIP_REVISION_1_1))) + val |= FEC_ENET_FCE; + writel(val, fep->hwp + FEC_R_CNTRL); } @@ -1670,6 +1700,23 @@ fec_restart(struct net_device *dev, int duplex) fep->phy_dev->speed == SPEED_1000) val |= (0x1 << 5); + /* RX FIFO threshold setting for ENET pause frame feature + * Only set the parameters after ticket TKT116501 fixed. + * The issue has been fixed on Rigel TO1.1 and Arik TO1.2 + */ + if ((cpu_is_mx6q() && + (mx6q_revision() >= IMX_CHIP_REVISION_1_2)) || + (cpu_is_mx6dl() && + (mx6dl_revision() >= IMX_CHIP_REVISION_1_1))) { + writel(FEC_ENET_RSEM_V, fep->hwp + FEC_R_FIFO_RSEM); + writel(FEC_ENET_RSFL_V, fep->hwp + FEC_R_FIFO_RSFL); + writel(FEC_ENET_RAEM_V, fep->hwp + FEC_R_FIFO_RAEM); + writel(FEC_ENET_RAFL_V, fep->hwp + FEC_R_FIFO_RAFL); + + /* OPD */ + writel(FEC_ENET_OPD_V, fep->hwp + FEC_OPD); + } + if (cpu_is_mx6q() || cpu_is_mx6dl()) { /* enable endian swap */ val |= (0x1 << 8); |