From 38657c18e78d35d8706697bf43c0b98c8117ca77 Mon Sep 17 00:00:00 2001 From: Ayaz Abdulla Date: Fri, 1 May 2009 01:41:50 +0000 Subject: [PATCH] --- yaml --- r: 150079 b: refs/heads/master c: 88d7d8b00cdc3117150faab4c4ace6d464b71c22 h: refs/heads/master i: 150077: 9c035c82d9ddbb3560613ea4b03e363687383e6e 150075: 1f40c69861a4563785b2f70fb80f0eadb68f2ec9 150071: 097b8fefa61da86f80c42196e74f1d5adf40e549 150063: f0b180744491563399be7665f38e93bd6842669e 150047: f5d90eda764cd00d4cc6500c7c5e5509bd0de822 150015: 0aeba74286e2c71e4b0d2331d0292bccc0a1d7e4 v: v3 --- [refs] | 2 +- trunk/drivers/net/forcedeth.c | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index cb105509e776..c0e82c2f6d48 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 1aec5bdfed91b50aedbcad43393bcb05033c7ef3 +refs/heads/master: 88d7d8b00cdc3117150faab4c4ace6d464b71c22 diff --git a/trunk/drivers/net/forcedeth.c b/trunk/drivers/net/forcedeth.c index f9a846b1b92f..d0b1d9f17a5d 100644 --- a/trunk/drivers/net/forcedeth.c +++ b/trunk/drivers/net/forcedeth.c @@ -343,6 +343,7 @@ enum { #define NVREG_POWERSTATE2_POWERUP_MASK 0x0F15 #define NVREG_POWERSTATE2_POWERUP_REV_A3 0x0001 #define NVREG_POWERSTATE2_PHY_RESET 0x0004 +#define NVREG_POWERSTATE2_GATE_CLOCKS 0x0F00 }; /* Big endian: should work, but is untested */ @@ -1017,6 +1018,23 @@ static int using_multi_irqs(struct net_device *dev) return 1; } +static void nv_txrx_gate(struct net_device *dev, bool gate) +{ + struct fe_priv *np = get_nvpriv(dev); + u8 __iomem *base = get_hwbase(dev); + u32 powerstate; + + if (!np->mac_in_use && + (np->driver_data & DEV_HAS_POWER_CNTRL)) { + powerstate = readl(base + NvRegPowerState2); + if (gate) + powerstate |= NVREG_POWERSTATE2_GATE_CLOCKS; + else + powerstate &= ~NVREG_POWERSTATE2_GATE_CLOCKS; + writel(powerstate, base + NvRegPowerState2); + } +} + static void nv_enable_irq(struct net_device *dev) { struct fe_priv *np = get_nvpriv(dev); @@ -3394,12 +3412,14 @@ static void nv_linkchange(struct net_device *dev) if (!netif_carrier_ok(dev)) { netif_carrier_on(dev); printk(KERN_INFO "%s: link up.\n", dev->name); + nv_txrx_gate(dev, false); nv_start_rx(dev); } } else { if (netif_carrier_ok(dev)) { netif_carrier_off(dev); printk(KERN_INFO "%s: link down.\n", dev->name); + nv_txrx_gate(dev, true); nv_stop_rx(dev); } } @@ -5327,6 +5347,7 @@ static int nv_open(struct net_device *dev) mii_rw(dev, np->phyaddr, MII_BMCR, mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ) & ~BMCR_PDOWN); + nv_txrx_gate(dev, false); /* erase previous misconfiguration */ if (np->driver_data & DEV_HAS_POWER_CNTRL) nv_mac_reset(dev); @@ -5514,12 +5535,14 @@ static int nv_close(struct net_device *dev) nv_drain_rxtx(dev); if (np->wolenabled) { + nv_txrx_gate(dev, false); writel(NVREG_PFF_ALWAYS|NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags); nv_start_rx(dev); } else { /* power down phy */ mii_rw(dev, np->phyaddr, MII_BMCR, mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ)|BMCR_PDOWN); + nv_txrx_gate(dev, true); } /* FIXME: power down nic */