From f0ae0c33f52ced89da080673ca89a3c5f2ea70e6 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Wed, 11 Nov 2015 20:54:01 +0000 Subject: net: designware: Don't hang in reset with powered down phy The dw MAC requires that all clock domains to be running for it to finish a MAC reset. This include the clock provided by the PHY. If the PHY is powered down, bit BMCR_PDOWN set, then it won't be generating a clock. And so the MAC never comes out of reset. On shutdown, Linux will put the PHY in powerdown mode, so it can easily be the case that the PHY is powered down on boot. See Linux kernel commit 2d871aa07136fe6e576bde63072cf33e2c664e95. Currently the MAC reset is done before the phy is probed. We can't power up the phy until it's probed, so the resets must be in the opposite order. The MAC reset is in device init but the PHY probe is in device open. Device init is done first, always, while open is done later, and only if the device is used. Rather than move the phy probe to init, this moves the MAC reset to open. It seems better to speed up boots that doesn't use ethernet by skipping MAC reset than to slow them down by adding PHY probe. Signed-off-by: Trent Piepho Signed-off-by: Sascha Hauer --- drivers/net/designware.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 800652760a..966f64f7b6 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -213,12 +213,34 @@ static void descs_init(struct eth_device *dev) rx_descs_init(dev); } +/* Get PHY out of power saving mode. If this is needed elsewhere then + * consider making it part of phy-core and adding a resume method to + * the phy device ops. */ +static int phy_resume(struct phy_device *phydev) +{ + int bmcr; + + bmcr = phy_read(phydev, MII_BMCR); + if (bmcr < 0) + return bmcr; + if (bmcr & BMCR_PDOWN) { + bmcr &= ~BMCR_PDOWN; + return phy_write(phydev, MII_BMCR, bmcr); + } + return 0; +} + static int dwc_ether_init(struct eth_device *dev) { struct dw_eth_dev *priv = dev->priv; struct eth_mac_regs *mac_p = priv->mac_regs_p; struct eth_dma_regs *dma_p = priv->dma_regs_p; + /* Before we reset the mac, we must insure the PHY is not powered down + * as the dw controller needs all clock domains to be running, including + * the PHY clock, to come out of a mac reset. */ + phy_resume(dev->phydev); + if (mac_reset(dev) < 0) return -1; @@ -275,6 +297,8 @@ static int dwc_ether_open(struct eth_device *dev) if (ret) return ret; + dwc_ether_init(dev); + descs_init(dev); /* @@ -468,7 +492,6 @@ static int dwc_ether_probe(struct device_d *dev) edev->priv = priv; edev->parent = dev; - edev->init = dwc_ether_init; edev->open = dwc_ether_open; edev->send = dwc_ether_send; edev->recv = dwc_ether_rx; -- cgit v1.2.3 From d22d68fca4c9caca13f4f6e627c75f84c768eba4 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Thu, 12 Nov 2015 20:25:20 +0100 Subject: net: rtl8169: get rid of DMA_ADDRESS_BROKEN Don't assume a 1:1 virt to phys mapping, but use the real physical address returned by the dma alloc function. Signed-off-by: Lucas Stach Signed-off-by: Sascha Hauer --- drivers/net/rtl8169.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c index 47d5e4a893..9ec0178386 100644 --- a/drivers/net/rtl8169.c +++ b/drivers/net/rtl8169.c @@ -51,10 +51,12 @@ struct rtl8169_priv { int chipset; volatile struct bufdesc *tx_desc; + dma_addr_t tx_desc_phys; void *tx_buf; unsigned int cur_tx; volatile struct bufdesc *rx_desc; + dma_addr_t rx_desc_phys; void *rx_buf; unsigned int cur_rx; @@ -228,10 +230,10 @@ static void rtl8169_init_ring(struct rtl8169_priv *priv) priv->cur_rx = priv->cur_tx = 0; priv->tx_desc = dma_alloc_coherent(NUM_TX_DESC * - sizeof(struct bufdesc), DMA_ADDRESS_BROKEN); + sizeof(struct bufdesc), &priv->tx_desc_phys); priv->tx_buf = malloc(NUM_TX_DESC * PKT_BUF_SIZE); priv->rx_desc = dma_alloc_coherent(NUM_RX_DESC * - sizeof(struct bufdesc), DMA_ADDRESS_BROKEN); + sizeof(struct bufdesc), &priv->rx_desc_phys); priv->rx_buf = malloc(NUM_RX_DESC * PKT_BUF_SIZE); dma_sync_single_for_device((unsigned long)priv->rx_buf, NUM_RX_DESC * PKT_BUF_SIZE, DMA_FROM_DEVICE); @@ -275,9 +277,9 @@ static void rtl8169_hw_start(struct rtl8169_priv *priv) /* Set DMA burst size and Interframe Gap Time */ RTL_W32(priv, TxConfig, (6 << TxDMAShift) | (3 << TxInterFrameGapShift)); - RTL_W32(priv, TxDescStartAddrLow, virt_to_phys(priv->tx_desc)); + RTL_W32(priv, TxDescStartAddrLow, priv->tx_desc_phys); RTL_W32(priv, TxDescStartAddrHigh, 0); - RTL_W32(priv, RxDescStartAddrLow, virt_to_phys(priv->rx_desc)); + RTL_W32(priv, RxDescStartAddrLow, priv->rx_desc_phys); RTL_W32(priv, RxDescStartAddrHigh, 0); /* RTL-8169sc/8110sc or later version */ -- cgit v1.2.3 From a63cb59c0178c90b22f1a3047f196f608dfaedcc Mon Sep 17 00:00:00 2001 From: Stefan Christ Date: Wed, 18 Nov 2015 10:08:43 +0100 Subject: net: fec: set phy reset time to 1ms According to the device tree bindings in dts/Bindings/net/fsl-fec.txt the default phy-reset time is 1ms. Signed-off-by: Stefan Christ Signed-off-by: Sascha Hauer --- drivers/net/fec_imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c index 78ccb85376..f19d046e24 100644 --- a/drivers/net/fec_imx.c +++ b/drivers/net/fec_imx.c @@ -692,7 +692,7 @@ static int fec_probe(struct device_d *dev) if (ret) goto err_free; - udelay(10); + mdelay(1); gpio_set_value(phy_reset, 1); } -- cgit v1.2.3 From e2747f710a34fbff84dcd709971a63ca3dfd0630 Mon Sep 17 00:00:00 2001 From: Stefan Christ Date: Wed, 18 Nov 2015 10:08:44 +0100 Subject: net: fec: implement dtb property phy-reset-duration Implement device tree property phy-reset-duration to adjust length of phy reset. Signed-off-by: Stefan Christ Signed-off-by: Sascha Hauer --- drivers/net/fec_imx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c index f19d046e24..70087adf90 100644 --- a/drivers/net/fec_imx.c +++ b/drivers/net/fec_imx.c @@ -654,6 +654,7 @@ static int fec_probe(struct device_d *dev) int ret; enum fec_type type; int phy_reset; + u32 msec = 1; ret = dev_get_drvdata(dev, (const void **)&type); if (ret) @@ -684,6 +685,8 @@ static int fec_probe(struct device_d *dev) phy_reset = of_get_named_gpio(dev->device_node, "phy-reset-gpios", 0); if (gpio_is_valid(phy_reset)) { + of_property_read_u32(dev->device_node, "phy-reset-duration", &msec); + ret = gpio_request(phy_reset, "phy-reset"); if (ret) goto err_free; @@ -692,7 +695,7 @@ static int fec_probe(struct device_d *dev) if (ret) goto err_free; - mdelay(1); + mdelay(msec); gpio_set_value(phy_reset, 1); } -- cgit v1.2.3 From 3ee195ec12481e0f47214f1f1641ba1b872fa12f Mon Sep 17 00:00:00 2001 From: Stefan Christ Date: Wed, 18 Nov 2015 10:08:45 +0100 Subject: net: fec: fix indentation and whitspaces Signed-off-by: Stefan Christ Signed-off-by: Sascha Hauer --- drivers/net/fec_imx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c index 70087adf90..5418034129 100644 --- a/drivers/net/fec_imx.c +++ b/drivers/net/fec_imx.c @@ -259,7 +259,7 @@ static int fec_set_hwaddr(struct eth_device *dev, const unsigned char *mac) writel((mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3], fec->regs + FEC_PADDR1); writel((mac[4] << 24) + (mac[5] << 16) + 0x8808, fec->regs + FEC_PADDR2); - return 0; + return 0; } static int fec_init(struct eth_device *dev) @@ -647,8 +647,8 @@ static int fec_probe_dt(struct device_d *dev, struct fec_priv *fec) #endif static int fec_probe(struct device_d *dev) { - struct fec_platform_data *pdata = (struct fec_platform_data *)dev->platform_data; - struct eth_device *edev; + struct fec_platform_data *pdata = (struct fec_platform_data *)dev->platform_data; + struct eth_device *edev; struct fec_priv *fec; void *base; int ret; @@ -778,7 +778,7 @@ static __maybe_unused struct of_device_id imx_fec_dt_ids[] = { }, { .compatible = "fsl,imx6q-fec", .data = (void *)FEC_TYPE_IMX6, - }, { + }, { .compatible = "fsl,imx6sx-fec", .data = (void *)FEC_TYPE_IMX6, }, { -- cgit v1.2.3 From 7454e176bbdfb68a39b728fbd3d0000aa183ddb1 Mon Sep 17 00:00:00 2001 From: Antony Pavlov Date: Sun, 22 Nov 2015 22:49:27 +0300 Subject: net: usb: asix: make rx_fixup ax_skb buffer aligned ax_skb receive buffer unalignment leads to consequent unalignment data access in network stack routines, especially in net_checksum(). By-turn unalignment data accesses lead to performance penalty. Moreover on classic MIPS CPUs without hardware unalignment access support this leads to undesirable exceptions. At the moment barebox on MIPS can't parry these unalignment access exceptions, so the Asix USB Ethernet chips, that need receive fixup workaround, are completely unusable on MIPS without this patch. Signed-off-by: Antony Pavlov Signed-off-by: Sascha Hauer --- drivers/net/usb/asix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 4c53a142f1..ff8039832f 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -158,7 +158,7 @@ struct asix_rx_fixup_info { u16 size; u16 offset; bool split_head; - unsigned char ax_skb[RX_FIXUP_SIZE]; + unsigned char ax_skb[RX_FIXUP_SIZE] __aligned(2); }; struct asix_common_private { -- cgit v1.2.3 From 28ab89ec815aacc7b4c598f7af1b9211c21cfb14 Mon Sep 17 00:00:00 2001 From: Antony Pavlov Date: Sun, 22 Nov 2015 22:49:52 +0300 Subject: net: usb: asix: fix 'no previous prototype' warning Here is the warning message: drivers/net/usb/asix.c:427:5: warning: no previous prototype for 'asix_rx_fixup_internal' [-Wmissing-prototypes] int asix_rx_fixup_internal(struct usbnet *dev, void *buf, int len, ^ Signed-off-by: Antony Pavlov Signed-off-by: Sascha Hauer --- drivers/net/usb/asix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index ff8039832f..3ca27ff027 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -424,7 +424,7 @@ static int ax88172_get_ethaddr(struct eth_device *edev, unsigned char *adr) return 0; } -int asix_rx_fixup_internal(struct usbnet *dev, void *buf, int len, +static int asix_rx_fixup_internal(struct usbnet *dev, void *buf, int len, struct asix_rx_fixup_info *rx) { int offset = 0; -- cgit v1.2.3 From c2fed64666b79f00fd00bdb3b6dd3407fda6cad8 Mon Sep 17 00:00:00 2001 From: Antony Pavlov Date: Thu, 3 Dec 2015 10:03:48 +0300 Subject: net: tap: make locally used functions static Signed-off-by: Antony Pavlov Signed-off-by: Sascha Hauer --- drivers/net/tap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/tap.c b/drivers/net/tap.c index ca53f12d92..dfa9bc28d4 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c @@ -29,7 +29,7 @@ struct tap_priv { char *name; }; -int tap_eth_send (struct eth_device *edev, void *packet, int length) +static int tap_eth_send(struct eth_device *edev, void *packet, int length) { struct tap_priv *priv = edev->priv; @@ -37,7 +37,7 @@ int tap_eth_send (struct eth_device *edev, void *packet, int length) return 0; } -int tap_eth_rx (struct eth_device *edev) +static int tap_eth_rx(struct eth_device *edev) { struct tap_priv *priv = edev->priv; int length; @@ -50,12 +50,12 @@ int tap_eth_rx (struct eth_device *edev) return 0; } -int tap_eth_open(struct eth_device *edev) +static int tap_eth_open(struct eth_device *edev) { return 0; } -void tap_eth_halt (struct eth_device *edev) +static void tap_eth_halt(struct eth_device *edev) { /* nothing to do here */ } @@ -70,7 +70,7 @@ static int tap_set_ethaddr(struct eth_device *edev, const unsigned char *adr) return 0; } -int tap_probe(struct device_d *dev) +static int tap_probe(struct device_d *dev) { struct eth_device *edev; struct tap_priv *priv; -- cgit v1.2.3 From 40d3331a3bb71edc4bdee51c22d81e926b93c7bb Mon Sep 17 00:00:00 2001 From: Antony Pavlov Date: Thu, 3 Dec 2015 10:03:49 +0300 Subject: net: tap: fix whitespaces Signed-off-by: Antony Pavlov Signed-off-by: Sascha Hauer --- drivers/net/tap.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/tap.c b/drivers/net/tap.c index dfa9bc28d4..4277956ed3 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c @@ -99,14 +99,15 @@ static int tap_probe(struct device_d *dev) eth_register(edev); - return 0; + return 0; + out: free(priv); return ret; } static struct driver_d tap_driver = { - .name = "tap", - .probe = tap_probe, + .name = "tap", + .probe = tap_probe, }; device_platform_driver(tap_driver); -- cgit v1.2.3