From bc8a8387ba57db2275e717c19838a8d5a404c270 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Tue, 6 Mar 2007 02:41:53 -0800 Subject: dmfe: add support for suspend/resume This adds support for suspend resume [akpm@linux-foundation.org: fix CONFIG_PM=n, coding style] Signed-off-by: Maxim Levitsky Cc: Valerie Henson Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/tulip/dmfe.c | 52 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) (limited to 'drivers/net/tulip') diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index b3a64ca98634..e3a077977e4c 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c @@ -55,9 +55,6 @@ TODO - Implement pci_driver::suspend() and pci_driver::resume() - power management methods. - Check on 64 bit boxes. Check and fix on big endian boxes. @@ -2050,11 +2047,60 @@ static struct pci_device_id dmfe_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, dmfe_pci_tbl); +#ifdef CONFIG_PM +static int dmfe_suspend(struct pci_dev *pci_dev, pm_message_t state) +{ + struct net_device *dev = pci_get_drvdata(pci_dev); + struct dmfe_board_info *db = netdev_priv(dev); + + /* Disable upper layer interface */ + netif_device_detach(dev); + + /* Disable Tx/Rx */ + db->cr6_data &= ~(CR6_RXSC | CR6_TXSC); + update_cr6(db->cr6_data, dev->base_addr); + + /* Disable Interrupt */ + outl(0, dev->base_addr + DCR7); + outl(inl (dev->base_addr + DCR5), dev->base_addr + DCR5); + + /* Fre RX buffers */ + dmfe_free_rxbuffer(db); + + /* Power down device*/ + pci_set_power_state(pci_dev, pci_choose_state (pci_dev,state)); + pci_save_state(pci_dev); + + return 0; +} + +static int dmfe_resume(struct pci_dev *pci_dev) +{ + struct net_device *dev = pci_get_drvdata(pci_dev); + + pci_restore_state(pci_dev); + pci_set_power_state(pci_dev, PCI_D0); + + /* Re-initilize DM910X board */ + dmfe_init_dm910x(dev); + + /* Restart upper layer interface */ + netif_device_attach(dev); + + return 0; +} +#else +#define dmfe_suspend NULL +#define dmfe_resume NULL +#endif + static struct pci_driver dmfe_driver = { .name = "dmfe", .id_table = dmfe_pci_tbl, .probe = dmfe_init_one, .remove = __devexit_p(dmfe_remove_one), + .suspend = dmfe_suspend, + .resume = dmfe_resume }; MODULE_AUTHOR("Sten Wang, sten_wang@davicom.com.tw"); -- cgit v1.2.2 From f1069046b4c7a5750611305433646c1bff3686fd Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Tue, 6 Mar 2007 02:41:54 -0800 Subject: dmfe: add support for Wake on lan Add support for WOL on Magic Packet and on link change Signed-off-by: Maxim Levitsky Cc: Valerie Henson Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/tulip/dmfe.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) (limited to 'drivers/net/tulip') diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index e3a077977e4c..4ed67ff0e81e 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c @@ -122,6 +122,11 @@ #define DM9801_NOISE_FLOOR 8 #define DM9802_NOISE_FLOOR 5 +#define DMFE_WOL_LINKCHANGE 0x20000000 +#define DMFE_WOL_SAMPLEPACKET 0x10000000 +#define DMFE_WOL_MAGICPACKET 0x08000000 + + #define DMFE_10MHF 0 #define DMFE_100MHF 1 #define DMFE_10MFD 4 @@ -248,6 +253,7 @@ struct dmfe_board_info { u8 wait_reset; /* Hardware failed, need to reset */ u8 dm910x_chk_mode; /* Operating mode check */ u8 first_in_callback; /* Flag to record state */ + u8 wol_mode; /* user WOL settings */ struct timer_list timer; /* System defined statistic counter */ @@ -428,6 +434,7 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev, db->chip_id = ent->driver_data; db->ioaddr = pci_resource_start(pdev, 0); db->chip_revision = dev_rev; + db->wol_mode = 0; db->pdev = pdev; @@ -1062,7 +1069,11 @@ static void dmfe_set_filter_mode(struct DEVICE * dev) spin_unlock_irqrestore(&db->lock, flags); } -static void netdev_get_drvinfo(struct net_device *dev, +/* + * Ethtool interace + */ + +static void dmfe_ethtool_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { struct dmfe_board_info *np = netdev_priv(dev); @@ -1076,9 +1087,35 @@ static void netdev_get_drvinfo(struct net_device *dev, dev->base_addr, dev->irq); } +static int dmfe_ethtool_set_wol(struct net_device *dev, + struct ethtool_wolinfo *wolinfo) +{ + struct dmfe_board_info *db = netdev_priv(dev); + + if (wolinfo->wolopts & (WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | + WAKE_ARP | WAKE_MAGICSECURE)) + return -EOPNOTSUPP; + + db->wol_mode = wolinfo->wolopts; + return 0; +} + +static void dmfe_ethtool_get_wol(struct net_device *dev, + struct ethtool_wolinfo *wolinfo) +{ + struct dmfe_board_info *db = netdev_priv(dev); + + wolinfo->supported = WAKE_PHY | WAKE_MAGIC; + wolinfo->wolopts = db->wol_mode; + return; +} + + static const struct ethtool_ops netdev_ethtool_ops = { - .get_drvinfo = netdev_get_drvinfo, + .get_drvinfo = dmfe_ethtool_get_drvinfo, .get_link = ethtool_op_get_link, + .set_wol = dmfe_ethtool_set_wol, + .get_wol = dmfe_ethtool_get_wol, }; /* @@ -2052,6 +2089,7 @@ static int dmfe_suspend(struct pci_dev *pci_dev, pm_message_t state) { struct net_device *dev = pci_get_drvdata(pci_dev); struct dmfe_board_info *db = netdev_priv(dev); + u32 tmp; /* Disable upper layer interface */ netif_device_detach(dev); @@ -2067,6 +2105,20 @@ static int dmfe_suspend(struct pci_dev *pci_dev, pm_message_t state) /* Fre RX buffers */ dmfe_free_rxbuffer(db); + /* Enable WOL */ + pci_read_config_dword(pci_dev, 0x40, &tmp); + tmp &= ~(DMFE_WOL_LINKCHANGE|DMFE_WOL_MAGICPACKET); + + if (db->wol_mode & WAKE_PHY) + tmp |= DMFE_WOL_LINKCHANGE; + if (db->wol_mode & WAKE_MAGIC) + tmp |= DMFE_WOL_MAGICPACKET; + + pci_write_config_dword(pci_dev, 0x40, tmp); + + pci_enable_wake(pci_dev, PCI_D3hot, 1); + pci_enable_wake(pci_dev, PCI_D3cold, 1); + /* Power down device*/ pci_set_power_state(pci_dev, pci_choose_state (pci_dev,state)); pci_save_state(pci_dev); @@ -2077,6 +2129,7 @@ static int dmfe_suspend(struct pci_dev *pci_dev, pm_message_t state) static int dmfe_resume(struct pci_dev *pci_dev) { struct net_device *dev = pci_get_drvdata(pci_dev); + u32 tmp; pci_restore_state(pci_dev); pci_set_power_state(pci_dev, PCI_D0); @@ -2084,6 +2137,15 @@ static int dmfe_resume(struct pci_dev *pci_dev) /* Re-initilize DM910X board */ dmfe_init_dm910x(dev); + /* Disable WOL */ + pci_read_config_dword(pci_dev, 0x40, &tmp); + + tmp &= ~(DMFE_WOL_LINKCHANGE | DMFE_WOL_MAGICPACKET); + pci_write_config_dword(pci_dev, 0x40, tmp); + + pci_enable_wake(pci_dev, PCI_D3hot, 0); + pci_enable_wake(pci_dev, PCI_D3cold, 0); + /* Restart upper layer interface */ netif_device_attach(dev); -- cgit v1.2.2 From b3bff39a2b3574542f5007e19038393dfdd64c85 Mon Sep 17 00:00:00 2001 From: Valerie Henson Date: Mon, 12 Mar 2007 02:31:29 -0700 Subject: TULIP: Fix for 64-bit MIPS From: Jim Gifford , Grant Grundler , Peter Horton With Grant's help I was able to get the tulip driver to work with 64 bit MIPS. [VAL: I'm happy with the 1.5 ms max delay; it doesn't seem excessive.] Signed-off-by: Valerie Henson Signed-off-by: Andrew Morton Cc: Jeff Garzik Signed-off-by: Jeff Garzik --- drivers/net/tulip/media.c | 22 ++++++++++++++++++++-- drivers/net/tulip/tulip.h | 7 +++++-- 2 files changed, 25 insertions(+), 4 deletions(-) (limited to 'drivers/net/tulip') diff --git a/drivers/net/tulip/media.c b/drivers/net/tulip/media.c index 20bd52b86993..1594160a0f62 100644 --- a/drivers/net/tulip/media.c +++ b/drivers/net/tulip/media.c @@ -44,8 +44,10 @@ static const unsigned char comet_miireg2offset[32] = { /* MII transceiver control section. Read and write the MII registers using software-generated serial - MDIO protocol. See the MII specifications or DP83840A data sheet - for details. */ + MDIO protocol. + See IEEE 802.3-2002.pdf (Section 2, Chapter "22.2.4 Management functions") + or DP83840A data sheet for more details. + */ int tulip_mdio_read(struct net_device *dev, int phy_id, int location) { @@ -272,13 +274,29 @@ void tulip_select_media(struct net_device *dev, int startup) int reset_length = p[2 + init_length]; misc_info = (u16*)(reset_sequence + reset_length); if (startup) { + int timeout = 10; /* max 1 ms */ iowrite32(mtable->csr12dir | 0x100, ioaddr + CSR12); for (i = 0; i < reset_length; i++) iowrite32(reset_sequence[i], ioaddr + CSR12); + + /* flush posted writes */ + ioread32(ioaddr + CSR12); + + /* Sect 3.10.3 in DP83840A.pdf (p39) */ + udelay(500); + + /* Section 4.2 in DP83840A.pdf (p43) */ + /* and IEEE 802.3 "22.2.4.1.1 Reset" */ + while (timeout-- && + (tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET)) + udelay(100); } for (i = 0; i < init_length; i++) iowrite32(init_sequence[i], ioaddr + CSR12); + + ioread32(ioaddr + CSR12); /* flush posted writes */ } + tmp_info = get_u16(&misc_info[1]); if (tmp_info) tp->advertising[phy_num] = tmp_info | 1; diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h index 25f25da76917..ceac47e775ce 100644 --- a/drivers/net/tulip/tulip.h +++ b/drivers/net/tulip/tulip.h @@ -482,8 +482,11 @@ static inline void tulip_stop_rxtx(struct tulip_private *tp) udelay(10); if (!i) - printk(KERN_DEBUG "%s: tulip_stop_rxtx() failed\n", - pci_name(tp->pdev)); + printk(KERN_DEBUG "%s: tulip_stop_rxtx() failed" + " (CSR5 0x%x CSR6 0x%x)\n", + pci_name(tp->pdev), + ioread32(ioaddr + CSR5), + ioread32(ioaddr + CSR6)); } } -- cgit v1.2.2 From eb117b1786804f2e128b871879ffe8f6a2701378 Mon Sep 17 00:00:00 2001 From: Thibaut VARENE Date: Mon, 12 Mar 2007 02:31:30 -0700 Subject: TULIP: Natsemi dp83840a PHY fix Fix a problem with Tulip 21142 HP branded PCI cards (PN#: B5509-66001), which feature a NatSemi DP83840A PHY. Without that patch, it is impossible to properly initialize the card's PHY, and it's thus impossible to monitor/configure it. [VAL: I'm happy with the 1.5 ms max delay; it doesn't seem excessive.] Signed-off-by: Thibaut VARENE Cc: Jeff Garzik Acked-by: Grant Grundler Signed-off-by: Valerie Henson Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/tulip/media.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers/net/tulip') diff --git a/drivers/net/tulip/media.c b/drivers/net/tulip/media.c index 1594160a0f62..b56256636543 100644 --- a/drivers/net/tulip/media.c +++ b/drivers/net/tulip/media.c @@ -263,11 +263,27 @@ void tulip_select_media(struct net_device *dev, int startup) u16 *reset_sequence = &((u16*)(p+3))[init_length]; int reset_length = p[2 + init_length*2]; misc_info = reset_sequence + reset_length; - if (startup) + if (startup) { + int timeout = 10; /* max 1 ms */ for (i = 0; i < reset_length; i++) iowrite32(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15); + + /* flush posted writes */ + ioread32(ioaddr + CSR15); + + /* Sect 3.10.3 in DP83840A.pdf (p39) */ + udelay(500); + + /* Section 4.2 in DP83840A.pdf (p43) */ + /* and IEEE 802.3 "22.2.4.1.1 Reset" */ + while (timeout-- && + (tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET)) + udelay(100); + } for (i = 0; i < init_length; i++) iowrite32(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15); + + ioread32(ioaddr + CSR15); /* flush posted writes */ } else { u8 *init_sequence = p + 2; u8 *reset_sequence = p + 3 + init_length; -- cgit v1.2.2 From 1ddb98618d5b797cb5300f093c1df1f38f79d9ba Mon Sep 17 00:00:00 2001 From: Valerie Henson Date: Mon, 12 Mar 2007 02:31:33 -0700 Subject: Fix tulip SytemError typo Fix an annoying typo - SytemError -> SystemError Signed-off-by: Valerie Henson Cc: Jeff Garzik Signed-off-by: Jeff Garzik --- drivers/net/tulip/interrupt.c | 4 ++-- drivers/net/tulip/tulip.h | 2 +- drivers/net/tulip/winbond-840.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net/tulip') diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c index e86df07769a1..9b08afbd1f65 100644 --- a/drivers/net/tulip/interrupt.c +++ b/drivers/net/tulip/interrupt.c @@ -673,7 +673,7 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance) if (tp->link_change) (tp->link_change)(dev, csr5); } - if (csr5 & SytemError) { + if (csr5 & SystemError) { int error = (csr5 >> 23) & 7; /* oops, we hit a PCI error. The code produced corresponds * to the reason: @@ -743,7 +743,7 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance) TxFIFOUnderflow | TxJabber | TPLnkFail | - SytemError )) != 0); + SystemError )) != 0); #else } while ((csr5 & (NormalIntr|AbnormalIntr)) != 0); diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h index ceac47e775ce..c840d2e67b23 100644 --- a/drivers/net/tulip/tulip.h +++ b/drivers/net/tulip/tulip.h @@ -132,7 +132,7 @@ enum pci_cfg_driver_reg { /* The bits in the CSR5 status registers, mostly interrupt sources. */ enum status_bits { TimerInt = 0x800, - SytemError = 0x2000, + SystemError = 0x2000, TPLnkFail = 0x1000, TPLnkPass = 0x10, NormalIntr = 0x10000, diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c index 5b71ac78bca2..fa440706fb4a 100644 --- a/drivers/net/tulip/winbond-840.c +++ b/drivers/net/tulip/winbond-840.c @@ -1147,7 +1147,7 @@ static irqreturn_t intr_handler(int irq, void *dev_instance) } /* Abnormal error summary/uncommon events handlers. */ - if (intr_status & (AbnormalIntr | TxFIFOUnderflow | SytemError | + if (intr_status & (AbnormalIntr | TxFIFOUnderflow | SystemError | TimerInt | TxDied)) netdev_error(dev, intr_status); -- cgit v1.2.2 From 6bab99be917054736097b758489a9ea27fd44245 Mon Sep 17 00:00:00 2001 From: Valerie Henson Date: Mon, 12 Mar 2007 02:31:34 -0700 Subject: Rev tulip version Rev tulip version... things have changed since 2002! Signed-off-by: Valerie Henson Cc: Jeff Garzik Signed-off-by: Jeff Garzik --- drivers/net/tulip/tulip_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net/tulip') diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index e9bf526ec534..041af63f2811 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -17,11 +17,11 @@ #define DRV_NAME "tulip" #ifdef CONFIG_TULIP_NAPI -#define DRV_VERSION "1.1.14-NAPI" /* Keep at least for test */ +#define DRV_VERSION "1.1.15-NAPI" /* Keep at least for test */ #else -#define DRV_VERSION "1.1.14" +#define DRV_VERSION "1.1.15" #endif -#define DRV_RELDATE "May 11, 2002" +#define DRV_RELDATE "Feb 27, 2007" #include -- cgit v1.2.2