mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-03 19:24:02 +08:00
net: macb: add wake-on-lan support via magic packet
Tested on Acqua A5 SoM (http://www.acmesystems.it/acqua). Signed-off-by: Sergio Prado <sergio.prado@e-labworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
e651520320
commit
3e2a5e1539
@ -25,6 +25,8 @@ Required properties:
|
|||||||
|
|
||||||
Optional properties for PHY child node:
|
Optional properties for PHY child node:
|
||||||
- reset-gpios : Should specify the gpio for phy reset
|
- reset-gpios : Should specify the gpio for phy reset
|
||||||
|
- cdns,magic-packet : If present, indicates that the hardware supports waking
|
||||||
|
up via magic packet.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
|
@ -58,6 +58,9 @@
|
|||||||
|
|
||||||
#define GEM_MTU_MIN_SIZE 68
|
#define GEM_MTU_MIN_SIZE 68
|
||||||
|
|
||||||
|
#define MACB_WOL_HAS_MAGIC_PACKET (0x1 << 0)
|
||||||
|
#define MACB_WOL_ENABLED (0x1 << 1)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Graceful stop timeouts in us. We should allow up to
|
* Graceful stop timeouts in us. We should allow up to
|
||||||
* 1 frame time (10 Mbits/s, full-duplex, ignoring collisions)
|
* 1 frame time (10 Mbits/s, full-duplex, ignoring collisions)
|
||||||
@ -2124,6 +2127,39 @@ static void macb_get_regs(struct net_device *dev, struct ethtool_regs *regs,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void macb_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
|
||||||
|
{
|
||||||
|
struct macb *bp = netdev_priv(netdev);
|
||||||
|
|
||||||
|
wol->supported = 0;
|
||||||
|
wol->wolopts = 0;
|
||||||
|
|
||||||
|
if (bp->wol & MACB_WOL_HAS_MAGIC_PACKET) {
|
||||||
|
wol->supported = WAKE_MAGIC;
|
||||||
|
|
||||||
|
if (bp->wol & MACB_WOL_ENABLED)
|
||||||
|
wol->wolopts |= WAKE_MAGIC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int macb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
|
||||||
|
{
|
||||||
|
struct macb *bp = netdev_priv(netdev);
|
||||||
|
|
||||||
|
if (!(bp->wol & MACB_WOL_HAS_MAGIC_PACKET) ||
|
||||||
|
(wol->wolopts & ~WAKE_MAGIC))
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
if (wol->wolopts & WAKE_MAGIC)
|
||||||
|
bp->wol |= MACB_WOL_ENABLED;
|
||||||
|
else
|
||||||
|
bp->wol &= ~MACB_WOL_ENABLED;
|
||||||
|
|
||||||
|
device_set_wakeup_enable(&bp->pdev->dev, bp->wol & MACB_WOL_ENABLED);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct ethtool_ops macb_ethtool_ops = {
|
static const struct ethtool_ops macb_ethtool_ops = {
|
||||||
.get_settings = macb_get_settings,
|
.get_settings = macb_get_settings,
|
||||||
.set_settings = macb_set_settings,
|
.set_settings = macb_set_settings,
|
||||||
@ -2131,6 +2167,8 @@ static const struct ethtool_ops macb_ethtool_ops = {
|
|||||||
.get_regs = macb_get_regs,
|
.get_regs = macb_get_regs,
|
||||||
.get_link = ethtool_op_get_link,
|
.get_link = ethtool_op_get_link,
|
||||||
.get_ts_info = ethtool_op_get_ts_info,
|
.get_ts_info = ethtool_op_get_ts_info,
|
||||||
|
.get_wol = macb_get_wol,
|
||||||
|
.set_wol = macb_set_wol,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct ethtool_ops gem_ethtool_ops = {
|
static const struct ethtool_ops gem_ethtool_ops = {
|
||||||
@ -2890,6 +2928,11 @@ static int macb_probe(struct platform_device *pdev)
|
|||||||
if (macb_config)
|
if (macb_config)
|
||||||
bp->jumbo_max_len = macb_config->jumbo_max_len;
|
bp->jumbo_max_len = macb_config->jumbo_max_len;
|
||||||
|
|
||||||
|
bp->wol = 0;
|
||||||
|
if (of_get_property(np, "cdns,magic-packet", NULL))
|
||||||
|
bp->wol |= MACB_WOL_HAS_MAGIC_PACKET;
|
||||||
|
device_init_wakeup(&pdev->dev, bp->wol & MACB_WOL_HAS_MAGIC_PACKET);
|
||||||
|
|
||||||
spin_lock_init(&bp->lock);
|
spin_lock_init(&bp->lock);
|
||||||
|
|
||||||
/* setup capabilities */
|
/* setup capabilities */
|
||||||
@ -3006,9 +3049,15 @@ static int __maybe_unused macb_suspend(struct device *dev)
|
|||||||
netif_carrier_off(netdev);
|
netif_carrier_off(netdev);
|
||||||
netif_device_detach(netdev);
|
netif_device_detach(netdev);
|
||||||
|
|
||||||
clk_disable_unprepare(bp->tx_clk);
|
if (bp->wol & MACB_WOL_ENABLED) {
|
||||||
clk_disable_unprepare(bp->hclk);
|
macb_writel(bp, IER, MACB_BIT(WOL));
|
||||||
clk_disable_unprepare(bp->pclk);
|
macb_writel(bp, WOL, MACB_BIT(MAG));
|
||||||
|
enable_irq_wake(bp->queues[0].irq);
|
||||||
|
} else {
|
||||||
|
clk_disable_unprepare(bp->tx_clk);
|
||||||
|
clk_disable_unprepare(bp->hclk);
|
||||||
|
clk_disable_unprepare(bp->pclk);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -3019,9 +3068,15 @@ static int __maybe_unused macb_resume(struct device *dev)
|
|||||||
struct net_device *netdev = platform_get_drvdata(pdev);
|
struct net_device *netdev = platform_get_drvdata(pdev);
|
||||||
struct macb *bp = netdev_priv(netdev);
|
struct macb *bp = netdev_priv(netdev);
|
||||||
|
|
||||||
clk_prepare_enable(bp->pclk);
|
if (bp->wol & MACB_WOL_ENABLED) {
|
||||||
clk_prepare_enable(bp->hclk);
|
macb_writel(bp, IDR, MACB_BIT(WOL));
|
||||||
clk_prepare_enable(bp->tx_clk);
|
macb_writel(bp, WOL, 0);
|
||||||
|
disable_irq_wake(bp->queues[0].irq);
|
||||||
|
} else {
|
||||||
|
clk_prepare_enable(bp->pclk);
|
||||||
|
clk_prepare_enable(bp->hclk);
|
||||||
|
clk_prepare_enable(bp->tx_clk);
|
||||||
|
}
|
||||||
|
|
||||||
netif_device_attach(netdev);
|
netif_device_attach(netdev);
|
||||||
|
|
||||||
|
@ -312,6 +312,8 @@
|
|||||||
#define MACB_PFR_SIZE 1
|
#define MACB_PFR_SIZE 1
|
||||||
#define MACB_PTZ_OFFSET 13 /* Enable pause time zero interrupt */
|
#define MACB_PTZ_OFFSET 13 /* Enable pause time zero interrupt */
|
||||||
#define MACB_PTZ_SIZE 1
|
#define MACB_PTZ_SIZE 1
|
||||||
|
#define MACB_WOL_OFFSET 14 /* Enable wake-on-lan interrupt */
|
||||||
|
#define MACB_WOL_SIZE 1
|
||||||
|
|
||||||
/* Bitfields in MAN */
|
/* Bitfields in MAN */
|
||||||
#define MACB_DATA_OFFSET 0 /* data */
|
#define MACB_DATA_OFFSET 0 /* data */
|
||||||
@ -842,6 +844,8 @@ struct macb {
|
|||||||
|
|
||||||
unsigned int rx_frm_len_mask;
|
unsigned int rx_frm_len_mask;
|
||||||
unsigned int jumbo_max_len;
|
unsigned int jumbo_max_len;
|
||||||
|
|
||||||
|
u32 wol;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline bool macb_is_gem(struct macb *bp)
|
static inline bool macb_is_gem(struct macb *bp)
|
||||||
|
Loading…
Reference in New Issue
Block a user