aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorFrancois Romieu <romieu@fr.zoreil.com>2006-05-14 06:18:44 -0400
committerFrancois Romieu <romieu@electric-eye.fr.zoreil.com>2006-07-26 17:23:12 -0400
commita2b98a697fa4e7564f78905b83db122824916cf9 (patch)
tree993de4e76f22b8a0831c36abf7133c09615c6dbb /drivers/net
parent64821324ca49f24be1a66f2f432108f96a24e596 (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')
-rw-r--r--drivers/net/r8169.c38
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
1385static 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
1402static 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
1385static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev, 1420static 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