diff options
Diffstat (limited to 'drivers/net/ethernet/ethoc.c')
-rw-r--r-- | drivers/net/ethernet/ethoc.c | 66 |
1 files changed, 44 insertions, 22 deletions
diff --git a/drivers/net/ethernet/ethoc.c b/drivers/net/ethernet/ethoc.c index c044667a0a25..23d82748f52b 100644 --- a/drivers/net/ethernet/ethoc.c +++ b/drivers/net/ethernet/ethoc.c @@ -23,6 +23,7 @@ #include <linux/sched.h> #include <linux/slab.h> #include <linux/of.h> +#include <linux/of_net.h> #include <linux/module.h> #include <net/ethoc.h> @@ -179,8 +180,6 @@ MODULE_PARM_DESC(buffer_size, "DMA buffer allocation size"); * struct ethoc - driver-private device structure * @iobase: pointer to I/O memory region * @membase: pointer to buffer memory region - * @dma_alloc: dma allocated buffer size - * @io_region_size: I/O memory region size * @num_bd: number of buffer descriptors * @num_tx: number of send buffers * @cur_tx: last send buffer written @@ -198,8 +197,6 @@ MODULE_PARM_DESC(buffer_size, "DMA buffer allocation size"); struct ethoc { void __iomem *iobase; void __iomem *membase; - int dma_alloc; - resource_size_t io_region_size; bool big_endian; unsigned int num_bd; @@ -221,6 +218,9 @@ struct ethoc { struct mii_bus *mdio; struct clk *clk; s8 phy_id; + + int old_link; + int old_duplex; }; /** @@ -572,7 +572,7 @@ static irqreturn_t ethoc_interrupt(int irq, void *dev_id) /* We always handle the dropped packet interrupt */ if (pending & INT_MASK_BUSY) { - dev_err(&dev->dev, "packet dropped\n"); + dev_dbg(&dev->dev, "packet dropped\n"); dev->stats.rx_dropped++; } @@ -614,7 +614,7 @@ static int ethoc_poll(struct napi_struct *napi, int budget) tx_work_done = ethoc_tx(priv->netdev, budget); if (rx_work_done < budget && tx_work_done < budget) { - napi_complete(napi); + napi_complete_done(napi, rx_work_done); ethoc_enable_irq(priv, INT_MASK_TX | INT_MASK_RX); } @@ -667,6 +667,32 @@ static int ethoc_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val) static void ethoc_mdio_poll(struct net_device *dev) { + struct ethoc *priv = netdev_priv(dev); + struct phy_device *phydev = dev->phydev; + bool changed = false; + u32 mode; + + if (priv->old_link != phydev->link) { + changed = true; + priv->old_link = phydev->link; + } + + if (priv->old_duplex != phydev->duplex) { + changed = true; + priv->old_duplex = phydev->duplex; + } + + if (!changed) + return; + + mode = ethoc_read(priv, MODER); + if (phydev->duplex == DUPLEX_FULL) + mode |= MODER_FULLD; + else + mode &= ~MODER_FULLD; + ethoc_write(priv, MODER, mode); + + phy_print_status(phydev); } static int ethoc_mdio_probe(struct net_device *dev) @@ -685,6 +711,9 @@ static int ethoc_mdio_probe(struct net_device *dev) return -ENXIO; } + priv->old_duplex = -1; + priv->old_link = -1; + err = phy_connect_direct(dev, phy, ethoc_mdio_poll, PHY_INTERFACE_MODE_GMII); if (err) { @@ -721,6 +750,9 @@ static int ethoc_open(struct net_device *dev) netif_start_queue(dev); } + priv->old_link = -1; + priv->old_duplex = -1; + phy_start(dev->phydev); napi_enable(&priv->napi); @@ -963,9 +995,10 @@ static int ethoc_set_ringparam(struct net_device *dev, return 0; } -const struct ethtool_ops ethoc_ethtool_ops = { +static const struct ethtool_ops ethoc_ethtool_ops = { .get_regs_len = ethoc_get_regs_len, .get_regs = ethoc_get_regs, + .nway_reset = phy_ethtool_nway_reset, .get_link = ethtool_op_get_link, .get_ringparam = ethoc_get_ringparam, .set_ringparam = ethoc_set_ringparam, @@ -998,7 +1031,6 @@ static int ethoc_probe(struct platform_device *pdev) struct ethoc *priv = NULL; int num_bd; int ret = 0; - bool random_mac = false; struct ethoc_platform_data *pdata = dev_get_platdata(&pdev->dev); u32 eth_clkfreq = pdata ? pdata->eth_clkfreq : 0; @@ -1059,8 +1091,6 @@ static int ethoc_probe(struct platform_device *pdev) /* setup driver-private data */ priv = netdev_priv(netdev); priv->netdev = netdev; - priv->dma_alloc = 0; - priv->io_region_size = resource_size(mmio); priv->iobase = devm_ioremap_nocache(&pdev->dev, netdev->base_addr, resource_size(mmio)); @@ -1090,7 +1120,6 @@ static int ethoc_probe(struct platform_device *pdev) goto free; } netdev->mem_end = netdev->mem_start + buffer_size; - priv->dma_alloc = buffer_size; } priv->big_endian = pdata ? pdata->big_endian : @@ -1122,11 +1151,9 @@ static int ethoc_probe(struct platform_device *pdev) memcpy(netdev->dev_addr, pdata->hwaddr, IFHWADDRLEN); priv->phy_id = pdata->phy_id; } else { - const uint8_t *mac; + const void *mac; - mac = of_get_property(pdev->dev.of_node, - "local-mac-address", - NULL); + mac = of_get_mac_address(pdev->dev.of_node); if (mac) memcpy(netdev->dev_addr, mac, IFHWADDRLEN); priv->phy_id = -1; @@ -1141,16 +1168,11 @@ static int ethoc_probe(struct platform_device *pdev) /* Check the MAC again for validity, if it still isn't choose and * program a random one. */ - if (!is_valid_ether_addr(netdev->dev_addr)) { - eth_random_addr(netdev->dev_addr); - random_mac = true; - } + if (!is_valid_ether_addr(netdev->dev_addr)) + eth_hw_addr_random(netdev); ethoc_do_set_mac_address(netdev); - if (random_mac) - netdev->addr_assign_type = NET_ADDR_RANDOM; - /* Allow the platform setup code to adjust MII management bus clock. */ if (!eth_clkfreq) { struct clk *clk = devm_clk_get(&pdev->dev, NULL); |