diff options
author | Francois Romieu <romieu@fr.zoreil.com> | 2006-05-14 06:18:44 -0400 |
---|---|---|
committer | Francois Romieu <romieu@electric-eye.fr.zoreil.com> | 2006-07-26 17:23:12 -0400 |
commit | a2b98a697fa4e7564f78905b83db122824916cf9 (patch) | |
tree | 993de4e76f22b8a0831c36abf7133c09615c6dbb /drivers/net/r8169.c | |
parent | 64821324ca49f24be1a66f2f432108f96a24e596 (diff) |
r8169: mac address change support
Fix for http://bugzilla.kernel.org/show_bug.cgi?id=6032.
Cc: Tim Mattox <tmattox@gmail.com>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Diffstat (limited to 'drivers/net/r8169.c')
-rw-r--r-- | drivers/net/r8169.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 4c2f575faad7..e8786c4fcac2 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -1382,6 +1382,41 @@ static void rtl8169_netpoll(struct net_device *dev) | |||
1382 | } | 1382 | } |
1383 | #endif | 1383 | #endif |
1384 | 1384 | ||
1385 | static void __rtl8169_set_mac_addr(struct net_device *dev, void __iomem *ioaddr) | ||
1386 | { | ||
1387 | unsigned int i, j; | ||
1388 | |||
1389 | RTL_W8(Cfg9346, Cfg9346_Unlock); | ||
1390 | for (i = 0; i < 2; i++) { | ||
1391 | __le32 l = 0; | ||
1392 | |||
1393 | for (j = 0; j < 4; j++) { | ||
1394 | l <<= 8; | ||
1395 | l |= dev->dev_addr[4*i + j]; | ||
1396 | } | ||
1397 | RTL_W32(MAC0 + 4*i, cpu_to_be32(l)); | ||
1398 | } | ||
1399 | RTL_W8(Cfg9346, Cfg9346_Lock); | ||
1400 | } | ||
1401 | |||
1402 | static int rtl8169_set_mac_addr(struct net_device *dev, void *p) | ||
1403 | { | ||
1404 | struct rtl8169_private *tp = netdev_priv(dev); | ||
1405 | struct sockaddr *addr = p; | ||
1406 | |||
1407 | if (!is_valid_ether_addr(addr->sa_data)) | ||
1408 | return -EINVAL; | ||
1409 | |||
1410 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); | ||
1411 | |||
1412 | if (netif_running(dev)) { | ||
1413 | spin_lock_irq(&tp->lock); | ||
1414 | __rtl8169_set_mac_addr(dev, tp->mmio_addr); | ||
1415 | spin_unlock_irq(&tp->lock); | ||
1416 | } | ||
1417 | return 0; | ||
1418 | } | ||
1419 | |||
1385 | static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev, | 1420 | static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev, |
1386 | void __iomem *ioaddr) | 1421 | void __iomem *ioaddr) |
1387 | { | 1422 | { |
@@ -1609,6 +1644,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1609 | dev->stop = rtl8169_close; | 1644 | dev->stop = rtl8169_close; |
1610 | dev->tx_timeout = rtl8169_tx_timeout; | 1645 | dev->tx_timeout = rtl8169_tx_timeout; |
1611 | dev->set_multicast_list = rtl8169_set_rx_mode; | 1646 | dev->set_multicast_list = rtl8169_set_rx_mode; |
1647 | dev->set_mac_address = rtl8169_set_mac_addr; | ||
1612 | dev->watchdog_timeo = RTL8169_TX_TIMEOUT; | 1648 | dev->watchdog_timeo = RTL8169_TX_TIMEOUT; |
1613 | dev->irq = pdev->irq; | 1649 | dev->irq = pdev->irq; |
1614 | dev->base_addr = (unsigned long) ioaddr; | 1650 | dev->base_addr = (unsigned long) ioaddr; |
@@ -1842,6 +1878,8 @@ rtl8169_hw_start(struct net_device *dev) | |||
1842 | /* Enable all known interrupts by setting the interrupt mask. */ | 1878 | /* Enable all known interrupts by setting the interrupt mask. */ |
1843 | RTL_W16(IntrMask, rtl8169_intr_mask); | 1879 | RTL_W16(IntrMask, rtl8169_intr_mask); |
1844 | 1880 | ||
1881 | __rtl8169_set_mac_addr(dev, ioaddr); | ||
1882 | |||
1845 | netif_start_queue(dev); | 1883 | netif_start_queue(dev); |
1846 | } | 1884 | } |
1847 | 1885 | ||