diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/b44.c | 76 | ||||
-rw-r--r-- | drivers/net/b44.h | 4 |
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 | |||
1454 | static 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 | |||
1453 | static int b44_close(struct net_device *dev) | 1488 | static 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 | ||
1874 | static 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 | |||
1886 | static 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 | |||
1834 | static struct ethtool_ops b44_ethtool_ops = { | 1900 | static 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 | |||
1918 | out: | 1990 | out: |
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 | ||