summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/dlink/sundance.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-12 18:07:07 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-12 18:07:07 -0800
commit6be35c700f742e911ecedd07fcc43d4439922334 (patch)
treeca9f37214d204465fcc2d79c82efd291e357c53c /drivers/net/ethernet/dlink/sundance.c
parente37aa63e87bd581f9be5555ed0ba83f5295c92fc (diff)
parent520dfe3a3645257bf83660f672c47f8558f3d4c4 (diff)
downloadlinux-6be35c700f742e911ecedd07fcc43d4439922334.tar.bz2
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking changes from David Miller: 1) Allow to dump, monitor, and change the bridge multicast database using netlink. From Cong Wang. 2) RFC 5961 TCP blind data injection attack mitigation, from Eric Dumazet. 3) Networking user namespace support from Eric W. Biederman. 4) tuntap/virtio-net multiqueue support by Jason Wang. 5) Support for checksum offload of encapsulated packets (basically, tunneled traffic can still be checksummed by HW). From Joseph Gasparakis. 6) Allow BPF filter access to VLAN tags, from Eric Dumazet and Daniel Borkmann. 7) Bridge port parameters over netlink and BPDU blocking support from Stephen Hemminger. 8) Improve data access patterns during inet socket demux by rearranging socket layout, from Eric Dumazet. 9) TIPC protocol updates and cleanups from Ying Xue, Paul Gortmaker, and Jon Maloy. 10) Update TCP socket hash sizing to be more in line with current day realities. The existing heurstics were choosen a decade ago. From Eric Dumazet. 11) Fix races, queue bloat, and excessive wakeups in ATM and associated drivers, from Krzysztof Mazur and David Woodhouse. 12) Support DOVE (Distributed Overlay Virtual Ethernet) extensions in VXLAN driver, from David Stevens. 13) Add "oops_only" mode to netconsole, from Amerigo Wang. 14) Support set and query of VEB/VEPA bridge mode via PF_BRIDGE, also allow DCB netlink to work on namespaces other than the initial namespace. From John Fastabend. 15) Support PTP in the Tigon3 driver, from Matt Carlson. 16) tun/vhost zero copy fixes and improvements, plus turn it on by default, from Michael S. Tsirkin. 17) Support per-association statistics in SCTP, from Michele Baldessari. And many, many, driver updates, cleanups, and improvements. Too numerous to mention individually. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1722 commits) net/mlx4_en: Add support for destination MAC in steering rules net/mlx4_en: Use generic etherdevice.h functions. net: ethtool: Add destination MAC address to flow steering API bridge: add support of adding and deleting mdb entries bridge: notify mdb changes via netlink ndisc: Unexport ndisc_{build,send}_skb(). uapi: add missing netconf.h to export list pkt_sched: avoid requeues if possible solos-pci: fix double-free of TX skb in DMA mode bnx2: Fix accidental reversions. bna: Driver Version Updated to 3.1.2.1 bna: Firmware update bna: Add RX State bna: Rx Page Based Allocation bna: TX Intr Coalescing Fix bna: Tx and Rx Optimizations bna: Code Cleanup and Enhancements ath9k: check pdata variable before dereferencing it ath5k: RX timestamp is reported at end of frame ath9k_htc: RX timestamp is reported at end of frame ...
Diffstat (limited to 'drivers/net/ethernet/dlink/sundance.c')
-rw-r--r--drivers/net/ethernet/dlink/sundance.c95
1 files changed, 87 insertions, 8 deletions
diff --git a/drivers/net/ethernet/dlink/sundance.c b/drivers/net/ethernet/dlink/sundance.c
index 3b83588e51f6..28fc11b2f1ea 100644
--- a/drivers/net/ethernet/dlink/sundance.c
+++ b/drivers/net/ethernet/dlink/sundance.c
@@ -102,7 +102,7 @@ static char *media[MAX_UNITS];
#include <linux/mii.h>
/* These identify the driver base version and may not be removed. */
-static const char version[] __devinitconst =
+static const char version[] =
KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE
" Written by Donald Becker\n";
@@ -218,7 +218,7 @@ enum {
struct pci_id_info {
const char *name;
};
-static const struct pci_id_info pci_id_tbl[] __devinitconst = {
+static const struct pci_id_info pci_id_tbl[] = {
{"D-Link DFE-550TX FAST Ethernet Adapter"},
{"D-Link DFE-550FX 100Mbps Fiber-optics Adapter"},
{"D-Link DFE-580TX 4 port Server Adapter"},
@@ -259,6 +259,7 @@ enum alta_offsets {
EECtrl = 0x36,
FlashAddr = 0x40,
FlashData = 0x44,
+ WakeEvent = 0x45,
TxStatus = 0x46,
TxFrameId = 0x47,
DownCounter = 0x18,
@@ -333,6 +334,14 @@ enum mac_ctrl1_bits {
RxEnable=0x0800, RxDisable=0x1000, RxEnabled=0x2000,
};
+/* Bits in WakeEvent register. */
+enum wake_event_bits {
+ WakePktEnable = 0x01,
+ MagicPktEnable = 0x02,
+ LinkEventEnable = 0x04,
+ WolEnable = 0x80,
+};
+
/* The Rx and Tx buffer descriptors. */
/* Note that using only 32 bit fields simplifies conversion to big-endian
architectures. */
@@ -392,6 +401,7 @@ struct netdev_private {
unsigned int default_port:4; /* Last dev->if_port value. */
unsigned int an_enable:1;
unsigned int speed;
+ unsigned int wol_enabled:1; /* Wake on LAN enabled */
struct tasklet_struct rx_tasklet;
struct tasklet_struct tx_tasklet;
int budget;
@@ -472,8 +482,8 @@ static const struct net_device_ops netdev_ops = {
.ndo_validate_addr = eth_validate_addr,
};
-static int __devinit sundance_probe1 (struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int sundance_probe1(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
struct net_device *dev;
struct netdev_private *np;
@@ -701,7 +711,7 @@ static int change_mtu(struct net_device *dev, int new_mtu)
#define eeprom_delay(ee_addr) ioread32(ee_addr)
/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces. */
-static int __devinit eeprom_read(void __iomem *ioaddr, int location)
+static int eeprom_read(void __iomem *ioaddr, int location)
{
int boguscnt = 10000; /* Typical 1900 ticks. */
iowrite16(0x0200 | (location & 0xff), ioaddr + EECtrl);
@@ -829,7 +839,7 @@ static int netdev_open(struct net_device *dev)
unsigned long flags;
int i;
- /* Do we need to reset the chip??? */
+ sundance_reset(dev, 0x00ff << 16);
i = request_irq(irq, intr_handler, IRQF_SHARED, dev->name, dev);
if (i)
@@ -877,6 +887,10 @@ static int netdev_open(struct net_device *dev)
iowrite16 (StatsEnable | RxEnable | TxEnable, ioaddr + MACCtrl1);
+ /* Disable Wol */
+ iowrite8(ioread8(ioaddr + WakeEvent) | 0x00, ioaddr + WakeEvent);
+ np->wol_enabled = 0;
+
if (netif_msg_ifup(np))
printk(KERN_DEBUG "%s: Done netdev_open(), status: Rx %x Tx %x "
"MAC Control %x, %4.4x %4.4x.\n",
@@ -1715,6 +1729,60 @@ static void get_ethtool_stats(struct net_device *dev,
data[i++] = np->xstats.rx_mcasts;
}
+#ifdef CONFIG_PM
+
+static void sundance_get_wol(struct net_device *dev,
+ struct ethtool_wolinfo *wol)
+{
+ struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->base;
+ u8 wol_bits;
+
+ wol->wolopts = 0;
+
+ wol->supported = (WAKE_PHY | WAKE_MAGIC);
+ if (!np->wol_enabled)
+ return;
+
+ wol_bits = ioread8(ioaddr + WakeEvent);
+ if (wol_bits & MagicPktEnable)
+ wol->wolopts |= WAKE_MAGIC;
+ if (wol_bits & LinkEventEnable)
+ wol->wolopts |= WAKE_PHY;
+}
+
+static int sundance_set_wol(struct net_device *dev,
+ struct ethtool_wolinfo *wol)
+{
+ struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->base;
+ u8 wol_bits;
+
+ if (!device_can_wakeup(&np->pci_dev->dev))
+ return -EOPNOTSUPP;
+
+ np->wol_enabled = !!(wol->wolopts);
+ wol_bits = ioread8(ioaddr + WakeEvent);
+ wol_bits &= ~(WakePktEnable | MagicPktEnable |
+ LinkEventEnable | WolEnable);
+
+ if (np->wol_enabled) {
+ if (wol->wolopts & WAKE_MAGIC)
+ wol_bits |= (MagicPktEnable | WolEnable);
+ if (wol->wolopts & WAKE_PHY)
+ wol_bits |= (LinkEventEnable | WolEnable);
+ }
+ iowrite8(wol_bits, ioaddr + WakeEvent);
+
+ device_set_wakeup_enable(&np->pci_dev->dev, np->wol_enabled);
+
+ return 0;
+}
+#else
+#define sundance_get_wol NULL
+#define sundance_set_wol NULL
+#endif /* CONFIG_PM */
+
static const struct ethtool_ops ethtool_ops = {
.begin = check_if_running,
.get_drvinfo = get_drvinfo,
@@ -1722,6 +1790,8 @@ static const struct ethtool_ops ethtool_ops = {
.set_settings = set_settings,
.nway_reset = nway_reset,
.get_link = get_link,
+ .get_wol = sundance_get_wol,
+ .set_wol = sundance_set_wol,
.get_msglevel = get_msglevel,
.set_msglevel = set_msglevel,
.get_strings = get_strings,
@@ -1844,7 +1914,7 @@ static int netdev_close(struct net_device *dev)
return 0;
}
-static void __devexit sundance_remove1 (struct pci_dev *pdev)
+static void sundance_remove1(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
@@ -1867,6 +1937,8 @@ static void __devexit sundance_remove1 (struct pci_dev *pdev)
static int sundance_suspend(struct pci_dev *pci_dev, pm_message_t state)
{
struct net_device *dev = pci_get_drvdata(pci_dev);
+ struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->base;
if (!netif_running(dev))
return 0;
@@ -1875,6 +1947,12 @@ static int sundance_suspend(struct pci_dev *pci_dev, pm_message_t state)
netif_device_detach(dev);
pci_save_state(pci_dev);
+ if (np->wol_enabled) {
+ iowrite8(AcceptBroadcast | AcceptMyPhys, ioaddr + RxMode);
+ iowrite16(RxEnable, ioaddr + MACCtrl1);
+ }
+ pci_enable_wake(pci_dev, pci_choose_state(pci_dev, state),
+ np->wol_enabled);
pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
return 0;
@@ -1890,6 +1968,7 @@ static int sundance_resume(struct pci_dev *pci_dev)
pci_set_power_state(pci_dev, PCI_D0);
pci_restore_state(pci_dev);
+ pci_enable_wake(pci_dev, PCI_D0, 0);
err = netdev_open(dev);
if (err) {
@@ -1910,7 +1989,7 @@ static struct pci_driver sundance_driver = {
.name = DRV_NAME,
.id_table = sundance_pci_tbl,
.probe = sundance_probe1,
- .remove = __devexit_p(sundance_remove1),
+ .remove = sundance_remove1,
#ifdef CONFIG_PM
.suspend = sundance_suspend,
.resume = sundance_resume,