From 833cc67c7722e35863c6aaee9df56b442ef957ae Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 27 Apr 2009 21:32:16 +0000 Subject: smsc911x: add fifo byteswap support V2 This is V2 of the smsc911x fifo byteswap patch. The smsc911x hardware supports both big and little and endian hardware configurations, and the linux smsc911x driver currently detects word order. For correct operation on big endian platforms lacking swapped byte lanes the following patch is needed. Only fifo data is swapped, register data does not require any swapping. Signed-off-by: Magnus Damm Acked-by: Steve Glendinning Signed-off-by: David S. Miller --- drivers/net/smsc911x.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers/net/smsc911x.c') diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index eb7db032a78..5113b26fc2d 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include "smsc911x.h" @@ -175,6 +176,12 @@ static inline void smsc911x_tx_writefifo(struct smsc911x_data *pdata, unsigned int *buf, unsigned int wordcount) { + if (pdata->config.flags & SMSC911X_SWAP_FIFO) { + while (wordcount--) + smsc911x_reg_write(pdata, TX_DATA_FIFO, swab32(*buf++)); + return; + } + if (pdata->config.flags & SMSC911X_USE_32BIT) { writesl(pdata->ioaddr + TX_DATA_FIFO, buf, wordcount); return; @@ -194,6 +201,12 @@ static inline void smsc911x_rx_readfifo(struct smsc911x_data *pdata, unsigned int *buf, unsigned int wordcount) { + if (pdata->config.flags & SMSC911X_SWAP_FIFO) { + while (wordcount--) + *buf++ = swab32(smsc911x_reg_read(pdata, RX_DATA_FIFO)); + return; + } + if (pdata->config.flags & SMSC911X_USE_32BIT) { readsl(pdata->ioaddr + RX_DATA_FIFO, buf, wordcount); return; -- cgit v1.2.3-70-g09d2 From b6907b0c705b6db221f937b4d343e2a6b280c8c5 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Tue, 5 May 2009 12:22:53 -0700 Subject: net: smsc911x: add power management functions This adds a power management implementation for smsc911x.c which assumes the chips remains powered during suspend. The device is put in its D1 power saving mode. Signed-off-by: Daniel Mack Acked-by: Steve Glendinning Signed-off-by: David S. Miller --- drivers/net/smsc911x.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'drivers/net/smsc911x.c') diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index 5113b26fc2d..9a8528c5bb5 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -2109,12 +2109,58 @@ out_0: return retval; } +#ifdef CONFIG_PM +/* This implementation assumes the devices remains powered on its VDDVARIO + * pins during suspend. */ + +static int smsc911x_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct net_device *dev = platform_get_drvdata(pdev); + struct smsc911x_data *pdata = netdev_priv(dev); + + /* enable wake on LAN, energy detection and the external PME + * signal. */ + smsc911x_reg_write(pdata, PMT_CTRL, + PMT_CTRL_PM_MODE_D1_ | PMT_CTRL_WOL_EN_ | + PMT_CTRL_ED_EN_ | PMT_CTRL_PME_EN_); + + return 0; +} + +static int smsc911x_resume(struct platform_device *pdev) +{ + struct net_device *dev = platform_get_drvdata(pdev); + struct smsc911x_data *pdata = netdev_priv(dev); + unsigned int to = 100; + + /* Note 3.11 from the datasheet: + * "When the LAN9220 is in a power saving state, a write of any + * data to the BYTE_TEST register will wake-up the device." + */ + smsc911x_reg_write(pdata, BYTE_TEST, 0); + + /* poll the READY bit in PMT_CTRL. Any other access to the device is + * forbidden while this bit isn't set. Try for 100ms and return -EIO + * if it failed. */ + while (!(smsc911x_reg_read(pdata, PMT_CTRL) & PMT_CTRL_READY_) && --to) + udelay(1000); + + return (to == 0) ? -EIO : 0; +} + +#else +#define smsc911x_suspend NULL +#define smsc911x_resume NULL +#endif + static struct platform_driver smsc911x_driver = { .probe = smsc911x_drv_probe, .remove = smsc911x_drv_remove, .driver = { .name = SMSC_CHIPNAME, }, + .suspend = smsc911x_suspend, + .resume = smsc911x_resume, }; /* Entry point for loading the module */ -- cgit v1.2.3-70-g09d2 From 928f308f556f4943e50c5064b546f47bce301f02 Mon Sep 17 00:00:00 2001 From: Matthias Ludwig Date: Thu, 7 May 2009 15:00:12 -0700 Subject: smsc911x: fix calculation of res_size for ioremap fix size of remaped iomem, which is 1 byte to small (e.g. mappes only 0xff bytes instead of 0x100) Signed-off-by: Matthias Ludwig Acked-by: Steve Glendinning Signed-off-by: David S. Miller --- drivers/net/smsc911x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/smsc911x.c') diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index 9a8528c5bb5..3cff84078a9 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -1976,7 +1976,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) retval = -ENODEV; goto out_0; } - res_size = res->end - res->start; + res_size = res->end - res->start + 1; irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!irq_res) { -- cgit v1.2.3-70-g09d2 From df911e2dc4c59e259b65c502fe0679ade309b575 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 5 Jun 2009 14:37:20 +0000 Subject: netdev: smsc911x: add missing __devexit_p() usage The smsc911x_drv_remove() function is declared with __devexit, so the assignment to the driver structure needs __devexit_p() wrappings to prevent build failure when hotplug is disabled. Signed-off-by: Mike Frysinger Signed-off-by: David S. Miller --- drivers/net/smsc911x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/smsc911x.c') diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index 3cff84078a9..b60639bd181 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -2155,7 +2155,7 @@ static int smsc911x_resume(struct platform_device *pdev) static struct platform_driver smsc911x_driver = { .probe = smsc911x_drv_probe, - .remove = smsc911x_drv_remove, + .remove = __devexit_p(smsc911x_drv_remove), .driver = { .name = SMSC_CHIPNAME, }, -- cgit v1.2.3-70-g09d2