aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/forcedeth.c
diff options
context:
space:
mode:
authorAyaz Abdulla <aabdulla@nvidia.com>2009-04-30 21:41:50 -0400
committerDavid S. Miller <davem@davemloft.net>2009-05-01 18:30:45 -0400
commit88d7d8b00cdc3117150faab4c4ace6d464b71c22 (patch)
tree86e114a66f9fb2e76a892876101f8a5e4959ac20 /drivers/net/forcedeth.c
parent1aec5bdfed91b50aedbcad43393bcb05033c7ef3 (diff)
forcedeth: add clock gating feature <resend>
This patch adds new logic to support a clock gating feature found on the latest set of chipsets. The clock gating is performed on the tx/rx engines when the link is disconnected. Clock gating helps in reducing power consumption. * modified based on comments from netdev Signed-off-by: Ayaz Abdulla <aabdulla@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/forcedeth.c')
-rw-r--r--drivers/net/forcedeth.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index f9a846b1b92f..d0b1d9f17a5d 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -343,6 +343,7 @@ enum {
343#define NVREG_POWERSTATE2_POWERUP_MASK 0x0F15 343#define NVREG_POWERSTATE2_POWERUP_MASK 0x0F15
344#define NVREG_POWERSTATE2_POWERUP_REV_A3 0x0001 344#define NVREG_POWERSTATE2_POWERUP_REV_A3 0x0001
345#define NVREG_POWERSTATE2_PHY_RESET 0x0004 345#define NVREG_POWERSTATE2_PHY_RESET 0x0004
346#define NVREG_POWERSTATE2_GATE_CLOCKS 0x0F00
346}; 347};
347 348
348/* Big endian: should work, but is untested */ 349/* Big endian: should work, but is untested */
@@ -1017,6 +1018,23 @@ static int using_multi_irqs(struct net_device *dev)
1017 return 1; 1018 return 1;
1018} 1019}
1019 1020
1021static void nv_txrx_gate(struct net_device *dev, bool gate)
1022{
1023 struct fe_priv *np = get_nvpriv(dev);
1024 u8 __iomem *base = get_hwbase(dev);
1025 u32 powerstate;
1026
1027 if (!np->mac_in_use &&
1028 (np->driver_data & DEV_HAS_POWER_CNTRL)) {
1029 powerstate = readl(base + NvRegPowerState2);
1030 if (gate)
1031 powerstate |= NVREG_POWERSTATE2_GATE_CLOCKS;
1032 else
1033 powerstate &= ~NVREG_POWERSTATE2_GATE_CLOCKS;
1034 writel(powerstate, base + NvRegPowerState2);
1035 }
1036}
1037
1020static void nv_enable_irq(struct net_device *dev) 1038static void nv_enable_irq(struct net_device *dev)
1021{ 1039{
1022 struct fe_priv *np = get_nvpriv(dev); 1040 struct fe_priv *np = get_nvpriv(dev);
@@ -3394,12 +3412,14 @@ static void nv_linkchange(struct net_device *dev)
3394 if (!netif_carrier_ok(dev)) { 3412 if (!netif_carrier_ok(dev)) {
3395 netif_carrier_on(dev); 3413 netif_carrier_on(dev);
3396 printk(KERN_INFO "%s: link up.\n", dev->name); 3414 printk(KERN_INFO "%s: link up.\n", dev->name);
3415 nv_txrx_gate(dev, false);
3397 nv_start_rx(dev); 3416 nv_start_rx(dev);
3398 } 3417 }
3399 } else { 3418 } else {
3400 if (netif_carrier_ok(dev)) { 3419 if (netif_carrier_ok(dev)) {
3401 netif_carrier_off(dev); 3420 netif_carrier_off(dev);
3402 printk(KERN_INFO "%s: link down.\n", dev->name); 3421 printk(KERN_INFO "%s: link down.\n", dev->name);
3422 nv_txrx_gate(dev, true);
3403 nv_stop_rx(dev); 3423 nv_stop_rx(dev);
3404 } 3424 }
3405 } 3425 }
@@ -5327,6 +5347,7 @@ static int nv_open(struct net_device *dev)
5327 mii_rw(dev, np->phyaddr, MII_BMCR, 5347 mii_rw(dev, np->phyaddr, MII_BMCR,
5328 mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ) & ~BMCR_PDOWN); 5348 mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ) & ~BMCR_PDOWN);
5329 5349
5350 nv_txrx_gate(dev, false);
5330 /* erase previous misconfiguration */ 5351 /* erase previous misconfiguration */
5331 if (np->driver_data & DEV_HAS_POWER_CNTRL) 5352 if (np->driver_data & DEV_HAS_POWER_CNTRL)
5332 nv_mac_reset(dev); 5353 nv_mac_reset(dev);
@@ -5514,12 +5535,14 @@ static int nv_close(struct net_device *dev)
5514 nv_drain_rxtx(dev); 5535 nv_drain_rxtx(dev);
5515 5536
5516 if (np->wolenabled) { 5537 if (np->wolenabled) {
5538 nv_txrx_gate(dev, false);
5517 writel(NVREG_PFF_ALWAYS|NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags); 5539 writel(NVREG_PFF_ALWAYS|NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags);
5518 nv_start_rx(dev); 5540 nv_start_rx(dev);
5519 } else { 5541 } else {
5520 /* power down phy */ 5542 /* power down phy */
5521 mii_rw(dev, np->phyaddr, MII_BMCR, 5543 mii_rw(dev, np->phyaddr, MII_BMCR,
5522 mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ)|BMCR_PDOWN); 5544 mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ)|BMCR_PDOWN);
5545 nv_txrx_gate(dev, true);
5523 } 5546 }
5524 5547
5525 /* FIXME: power down nic */ 5548 /* FIXME: power down nic */