summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/ethoc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/ethoc.c')
-rw-r--r--drivers/net/ethernet/ethoc.c66
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);