diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2019-02-13 20:31:47 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2019-02-13 20:31:47 +0100 |
commit | 2a17e75a976d11c1712972d29813094b8020ac35 (patch) | |
tree | ea0e991c927752937803d72a5411f7159365aa83 /drivers/net | |
parent | a5f75fe8175aefec5b7cefaadc5359096c8eb22c (diff) | |
parent | 7185b353c96e1e831533eeaaada06ad9bebf84a2 (diff) | |
download | barebox-2a17e75a976d11c1712972d29813094b8020ac35.tar.gz barebox-2a17e75a976d11c1712972d29813094b8020ac35.tar.xz |
Merge branch 'for-next/misc'
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/designware.c | 42 | ||||
-rw-r--r-- | drivers/net/phy/micrel.c | 32 |
2 files changed, 65 insertions, 9 deletions
diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 3c9bca981c..0ee6d3d78a 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -328,24 +328,48 @@ static int dwc_ether_rx(struct eth_device *dev) u32 status = desc_p->txrx_status; int length = 0; + int ret = 0; /* Check if the owner is the CPU */ if (status & DESC_RXSTS_OWNBYDMA) return 0; - length = (status & DESC_RXSTS_FRMLENMSK) >> - DESC_RXSTS_FRMLENSHFT; + if ((status & (DESC_RXSTS_ERROR | DESC_RXSTS_DAFILTERFAIL | + DESC_RXSTS_SAFILTERFAIL)) || + (status & (DESC_RXSTS_RXIPC_GIANTFRAME | + DESC_RXSTS_RXFRAMEETHER)) == + DESC_RXSTS_RXIPC_GIANTFRAME) { + /* Error in packet - discard it */ + dev_warn(&dev->dev, "Rx error status (%x)\n", + status & (DESC_RXSTS_DAFILTERFAIL | + DESC_RXSTS_ERROR | + DESC_RXSTS_RXTRUNCATED | + DESC_RXSTS_SAFILTERFAIL | + DESC_RXSTS_RXIPC_GIANTFRAME | + DESC_RXSTS_RXDAMAGED | + DESC_RXSTS_RXIPC_GIANT | + DESC_RXSTS_RXCOLLISION | + DESC_RXSTS_RXFRAMEETHER | + DESC_RXSTS_RXWATCHDOG | + DESC_RXSTS_RXMIIERROR | + DESC_RXSTS_RXCRC)); + ret = -EIO; + } else { + length = (status & DESC_RXSTS_FRMLENMSK) >> + DESC_RXSTS_FRMLENSHFT; + + dma_sync_single_for_cpu((unsigned long)desc_p->dmamac_addr, + length, DMA_FROM_DEVICE); + net_receive(dev, desc_p->dmamac_addr, length); + dma_sync_single_for_device((unsigned long)desc_p->dmamac_addr, + length, DMA_FROM_DEVICE); + ret = length; + } /* * Make the current descriptor valid again and go to * the next one */ - dma_sync_single_for_cpu((unsigned long)desc_p->dmamac_addr, length, - DMA_FROM_DEVICE); - net_receive(dev, desc_p->dmamac_addr, length); - dma_sync_single_for_device((unsigned long)desc_p->dmamac_addr, length, - DMA_FROM_DEVICE); - desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA; /* Test the wrap-around condition. */ @@ -354,7 +378,7 @@ static int dwc_ether_rx(struct eth_device *dev) priv->rx_currdescnum = desc_num; - return length; + return ret; } static void dwc_ether_halt (struct eth_device *dev) diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 67c2ca9d54..8f0b81d8fa 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -220,6 +220,7 @@ static int ksz9031_config_init(struct phy_device *phydev) "txd2-skew-ps", "txd3-skew-ps" }; static const char *control_skews[2] = {"txen-skew-ps", "rxdv-skew-ps"}; + int ret; if (!of_node && dev->parent->device_node) of_node = dev->parent->device_node; @@ -240,9 +241,40 @@ static int ksz9031_config_init(struct phy_device *phydev) ksz9031_of_load_skew_values(phydev, of_node, MII_KSZ9031RN_TX_DATA_PAD_SKEW, 4, tx_data_skews, 4); + + /* Silicon Errata Sheet (DS80000691D or DS80000692D): + * When the device links in the 1000BASE-T slave mode only, + * the optional 125MHz reference output clock (CLK125_NDO) + * has wide duty cycle variation. + * + * The optional CLK125_NDO clock does not meet the RGMII + * 45/55 percent (min/max) duty cycle requirement and therefore + * cannot be used directly by the MAC side for clocking + * applications that have setup/hold time requirements on + * rising and falling clock edges. + * + * Workaround: + * Force the phy to be the master to receive a stable clock + * which meets the duty cycle requirement. + */ + if (of_property_read_bool(of_node, "micrel,force-master")) { + ret = phy_read(phydev, MII_CTRL1000); + if (ret < 0) + goto err_force_master; + + /* enable master mode, config & prefer master */ + ret |= CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER; + ret = phy_write(phydev, MII_CTRL1000, ret); + if (ret < 0) + goto err_force_master; + } } return ksz9031_center_flp_timing(phydev); + +err_force_master: + dev_err(dev, "failed to force the phy to master mode\n"); + return ret; } #define KSZ8873MLL_GLOBAL_CONTROL_4 0x06 |