summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudiu Manoil <claudiu.manoil@freescale.com>2014-04-03 15:51:27 (GMT)
committerJose Rivera <German.Rivera@freescale.com>2014-04-11 16:25:33 (GMT)
commit44b712b2ef30281db929e6a427fae23bddacef0d (patch)
tree8d7992c7bd7abb300f0e5d6af3764301f5cda813
parent990b140a53f828b3c0638636a469879f0b58e094 (diff)
downloadlinux-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.c29
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);
}