aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGary Zambrano <zambrano@broadcom.com>2006-06-20 18:34:23 -0400
committerJeff Garzik <jeff@garzik.org>2006-06-22 23:16:13 -0400
commit52cafd965507b7a7bb962486539f6d7422552692 (patch)
tree629aa6883f073b1d28fad4340f3d4d3f5c124230
parent47b9c3b1e6afa3c40e3ac1822cd13946567b5955 (diff)
[PATCH] b44: add wol
Adds wol to the driver. This is a redo of a previous patch thanks to feedback from Francois Romieu. Signed-off-by Gary Zambrano <zambrano@broadcom.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/net/b44.c76
-rw-r--r--drivers/net/b44.h4
2 files changed, 80 insertions, 0 deletions
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 41b1618573c7..73ca729e4cd7 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -1450,6 +1450,41 @@ static void b44_poll_controller(struct net_device *dev)
1450} 1450}
1451#endif 1451#endif
1452 1452
1453
1454static void b44_setup_wol(struct b44 *bp)
1455{
1456 u32 val;
1457 u16 pmval;
1458
1459 bw32(bp, B44_RXCONFIG, RXCONFIG_ALLMULTI);
1460
1461 if (bp->flags & B44_FLAG_B0_ANDLATER) {
1462
1463 bw32(bp, B44_WKUP_LEN, WKUP_LEN_DISABLE);
1464
1465 val = bp->dev->dev_addr[2] << 24 |
1466 bp->dev->dev_addr[3] << 16 |
1467 bp->dev->dev_addr[4] << 8 |
1468 bp->dev->dev_addr[5];
1469 bw32(bp, B44_ADDR_LO, val);
1470
1471 val = bp->dev->dev_addr[0] << 8 |
1472 bp->dev->dev_addr[1];
1473 bw32(bp, B44_ADDR_HI, val);
1474
1475 val = br32(bp, B44_DEVCTRL);
1476 bw32(bp, B44_DEVCTRL, val | DEVCTRL_MPM | DEVCTRL_PFE);
1477
1478 }
1479
1480 val = br32(bp, B44_SBTMSLOW);
1481 bw32(bp, B44_SBTMSLOW, val | SBTMSLOW_PE);
1482
1483 pci_read_config_word(bp->pdev, SSB_PMCSR, &pmval);
1484 pci_write_config_word(bp->pdev, SSB_PMCSR, pmval | SSB_PE);
1485
1486}
1487
1453static int b44_close(struct net_device *dev) 1488static int b44_close(struct net_device *dev)
1454{ 1489{
1455 struct b44 *bp = netdev_priv(dev); 1490 struct b44 *bp = netdev_priv(dev);
@@ -1475,6 +1510,11 @@ static int b44_close(struct net_device *dev)
1475 1510
1476 netif_poll_enable(dev); 1511 netif_poll_enable(dev);
1477 1512
1513 if (bp->flags & B44_FLAG_WOL_ENABLE) {
1514 b44_init_hw(bp);
1515 b44_setup_wol(bp);
1516 }
1517
1478 b44_free_consistent(bp); 1518 b44_free_consistent(bp);
1479 1519
1480 return 0; 1520 return 0;
@@ -1831,12 +1871,40 @@ static void b44_get_ethtool_stats(struct net_device *dev,
1831 spin_unlock_irq(&bp->lock); 1871 spin_unlock_irq(&bp->lock);
1832} 1872}
1833 1873
1874static void b44_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1875{
1876 struct b44 *bp = netdev_priv(dev);
1877
1878 wol->supported = WAKE_MAGIC;
1879 if (bp->flags & B44_FLAG_WOL_ENABLE)
1880 wol->wolopts = WAKE_MAGIC;
1881 else
1882 wol->wolopts = 0;
1883 memset(&wol->sopass, 0, sizeof(wol->sopass));
1884}
1885
1886static int b44_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1887{
1888 struct b44 *bp = netdev_priv(dev);
1889
1890 spin_lock_irq(&bp->lock);
1891 if (wol->wolopts & WAKE_MAGIC)
1892 bp->flags |= B44_FLAG_WOL_ENABLE;
1893 else
1894 bp->flags &= ~B44_FLAG_WOL_ENABLE;
1895 spin_unlock_irq(&bp->lock);
1896
1897 return 0;
1898}
1899
1834static struct ethtool_ops b44_ethtool_ops = { 1900static struct ethtool_ops b44_ethtool_ops = {
1835 .get_drvinfo = b44_get_drvinfo, 1901 .get_drvinfo = b44_get_drvinfo,
1836 .get_settings = b44_get_settings, 1902 .get_settings = b44_get_settings,
1837 .set_settings = b44_set_settings, 1903 .set_settings = b44_set_settings,
1838 .nway_reset = b44_nway_reset, 1904 .nway_reset = b44_nway_reset,
1839 .get_link = ethtool_op_get_link, 1905 .get_link = ethtool_op_get_link,
1906 .get_wol = b44_get_wol,
1907 .set_wol = b44_set_wol,
1840 .get_ringparam = b44_get_ringparam, 1908 .get_ringparam = b44_get_ringparam,
1841 .set_ringparam = b44_set_ringparam, 1909 .set_ringparam = b44_set_ringparam,
1842 .get_pauseparam = b44_get_pauseparam, 1910 .get_pauseparam = b44_get_pauseparam,
@@ -1915,6 +1983,10 @@ static int __devinit b44_get_invariants(struct b44 *bp)
1915 /* XXX - really required? 1983 /* XXX - really required?
1916 bp->flags |= B44_FLAG_BUGGY_TXPTR; 1984 bp->flags |= B44_FLAG_BUGGY_TXPTR;
1917 */ 1985 */
1986
1987 if (ssb_get_core_rev(bp) >= 7)
1988 bp->flags |= B44_FLAG_B0_ANDLATER;
1989
1918out: 1990out:
1919 return err; 1991 return err;
1920} 1992}
@@ -2115,6 +2187,10 @@ static int b44_suspend(struct pci_dev *pdev, pm_message_t state)
2115 spin_unlock_irq(&bp->lock); 2187 spin_unlock_irq(&bp->lock);
2116 2188
2117 free_irq(dev->irq, dev); 2189 free_irq(dev->irq, dev);
2190 if (bp->flags & B44_FLAG_WOL_ENABLE) {
2191 b44_init_hw(bp);
2192 b44_setup_wol(bp);
2193 }
2118 pci_disable_device(pdev); 2194 pci_disable_device(pdev);
2119 return 0; 2195 return 0;
2120} 2196}
diff --git a/drivers/net/b44.h b/drivers/net/b44.h
index b178662978f3..1f47777b848b 100644
--- a/drivers/net/b44.h
+++ b/drivers/net/b44.h
@@ -264,6 +264,8 @@
264#define SBIDHIGH_VC_SHIFT 16 264#define SBIDHIGH_VC_SHIFT 16
265 265
266/* SSB PCI config space registers. */ 266/* SSB PCI config space registers. */
267#define SSB_PMCSR 0x44
268#define SSB_PE 0x100
267#define SSB_BAR0_WIN 0x80 269#define SSB_BAR0_WIN 0x80
268#define SSB_BAR1_WIN 0x84 270#define SSB_BAR1_WIN 0x84
269#define SSB_SPROM_CONTROL 0x88 271#define SSB_SPROM_CONTROL 0x88
@@ -420,6 +422,7 @@ struct b44 {
420 422
421 u32 dma_offset; 423 u32 dma_offset;
422 u32 flags; 424 u32 flags;
425#define B44_FLAG_B0_ANDLATER 0x00000001
423#define B44_FLAG_BUGGY_TXPTR 0x00000002 426#define B44_FLAG_BUGGY_TXPTR 0x00000002
424#define B44_FLAG_REORDER_BUG 0x00000004 427#define B44_FLAG_REORDER_BUG 0x00000004
425#define B44_FLAG_PAUSE_AUTO 0x00008000 428#define B44_FLAG_PAUSE_AUTO 0x00008000
@@ -435,6 +438,7 @@ struct b44 {
435#define B44_FLAG_INTERNAL_PHY 0x10000000 438#define B44_FLAG_INTERNAL_PHY 0x10000000
436#define B44_FLAG_RX_RING_HACK 0x20000000 439#define B44_FLAG_RX_RING_HACK 0x20000000
437#define B44_FLAG_TX_RING_HACK 0x40000000 440#define B44_FLAG_TX_RING_HACK 0x40000000
441#define B44_FLAG_WOL_ENABLE 0x80000000
438 442
439 u32 rx_offset; 443 u32 rx_offset;
440 444