diff options
author | Claudiu Manoil <claudiu.manoil@freescale.com> | 2014-04-03 15:51:27 (GMT) |
---|---|---|
committer | Jose Rivera <German.Rivera@freescale.com> | 2014-04-11 16:25:33 (GMT) |
commit | 44b712b2ef30281db929e6a427fae23bddacef0d (patch) | |
tree | 8d7992c7bd7abb300f0e5d6af3764301f5cda813 | |
parent | 990b140a53f828b3c0638636a469879f0b58e094 (diff) | |
download | linux-fsl-qoriq-44b712b2ef30281db929e6a427fae23bddacef0d.tar.xz |
gianfar: Add WAKE_UCAST wol support
Add wake-on-lan by L2 unicast packets.
This feature is based on the "wake-on-filer" support.
A filer rule was added to match the incoming UCAST
packets during system suspend state and to trigger
the FGPI interupt to wakeup the system.
Cc: Li Yang <leoli@freescale.com>
Cc: Zhao Chenhui <chenhui.zhao@freescale.com>
Change-Id: I04d4b4a9501ea2d8f75b3e0794c220ac95b0d679
Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>
Reviewed-on: http://git.am.freescale.net:8181/10731
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Yang Li <LeoLi@freescale.com>
Reviewed-by: Jose Rivera <German.Rivera@freescale.com>
-rw-r--r-- | drivers/net/ethernet/freescale/gianfar.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 7f9a2ed..a93f275 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -1400,7 +1400,7 @@ static int gfar_probe(struct platform_device *ofdev) if ((priv->device_flags & FSL_GIANFAR_DEV_HAS_WAKE_ON_FILER) && priv->rx_filer_enable) - priv->wol_supported |= 0; + priv->wol_supported |= GFAR_WOL_FILER_UCAST; device_set_wakeup_capable(&ofdev->dev, priv->wol_supported); @@ -1496,6 +1496,7 @@ static void gfar_filer_config_wol(struct gfar_private *priv) { u32 rqfcr, rqfpr; unsigned int i; + u8 rqfcr_queue; __gfar_filer_disable(priv); @@ -1505,6 +1506,32 @@ static void gfar_filer_config_wol(struct gfar_private *priv) for (i = 0; i <= MAX_FILER_IDX; i++) gfar_write_filer(priv, i, rqfcr, rqfpr); + i = 0; + /* select a rx queue in group 0 */ + rqfcr_queue = (u8)find_first_bit(&priv->gfargrp[0].rx_bit_map, + priv->num_rx_queues); + + if (priv->wol_opts & GFAR_WOL_FILER_UCAST) { + /* Unicast packet, accept it */ + struct net_device *ndev = priv->ndev; + u32 dest_mac_addr = (ndev->dev_addr[0] << 16) | + (ndev->dev_addr[1] << 8) | + ndev->dev_addr[2]; + + rqfcr = (rqfcr_queue << 10) | RQFCR_AND | + RQFCR_CMP_EXACT | RQFCR_PID_DAH; + rqfpr = dest_mac_addr; + gfar_write_filer(priv, i++, rqfcr, rqfpr); + + dest_mac_addr = (ndev->dev_addr[3] << 16) | + (ndev->dev_addr[4] << 8) | + ndev->dev_addr[5]; + rqfcr = (rqfcr_queue << 10) | RQFCR_GPI | + RQFCR_CMP_EXACT | RQFCR_PID_DAL; + rqfpr = dest_mac_addr; + gfar_write_filer(priv, i++, rqfcr, rqfpr); + } + __gfar_filer_enable(priv); } |