aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/r8169.c
diff options
context:
space:
mode:
authorFrancois Romieu <romieu@fr.zoreil.com>2007-01-31 17:47:43 -0500
committerJeff Garzik <jeff@garzik.org>2007-07-08 22:16:45 -0400
commit773d202194be84cc17d35f62516eac6d8db833e6 (patch)
treec1b1b8414dbe6d18f4cab0f706be0f76339dd696 /drivers/net/r8169.c
parent96b9709c9b47c1f9e8fd80e756e8eddcba68e818 (diff)
r8169: mac address change support
Merged from Realtek's r8169-6.001 driver. I have added some locking to protect against the arp monitoring timer in the bonding driver. Accessing the configuration registers is otherwise performed under RTNL locking. Signed-off-by: Francois Romieu <romieu@fr.zoreil.com> Cc: Edward Hsu <edward_hsu@realtek.com.tw>
Diffstat (limited to 'drivers/net/r8169.c')
-rw-r--r--drivers/net/r8169.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index dc8f369006d6..7aa9cf4e9e98 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -182,6 +182,7 @@ static struct {
182 182
183enum rtl_registers { 183enum rtl_registers {
184 MAC0 = 0, /* Ethernet hardware address. */ 184 MAC0 = 0, /* Ethernet hardware address. */
185 MAC4 = 4,
185 MAR0 = 8, /* Multicast filter. */ 186 MAR0 = 8, /* Multicast filter. */
186 CounterAddrLow = 0x10, 187 CounterAddrLow = 0x10,
187 CounterAddrHigh = 0x14, 188 CounterAddrHigh = 0x14,
@@ -1379,6 +1380,40 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
1379 printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name); 1380 printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name);
1380} 1381}
1381 1382
1383static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
1384{
1385 void __iomem *ioaddr = tp->mmio_addr;
1386 u32 high;
1387 u32 low;
1388
1389 low = addr[0] | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24);
1390 high = addr[4] | (addr[5] << 8);
1391
1392 spin_lock_irq(&tp->lock);
1393
1394 RTL_W8(Cfg9346, Cfg9346_Unlock);
1395 RTL_W32(MAC0, low);
1396 RTL_W32(MAC4, high);
1397 RTL_W8(Cfg9346, Cfg9346_Lock);
1398
1399 spin_unlock_irq(&tp->lock);
1400}
1401
1402static int rtl_set_mac_address(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 -EADDRNOTAVAIL;
1409
1410 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
1411
1412 rtl_rar_set(tp, dev->dev_addr);
1413
1414 return 0;
1415}
1416
1382static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 1417static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1383{ 1418{
1384 struct rtl8169_private *tp = netdev_priv(dev); 1419 struct rtl8169_private *tp = netdev_priv(dev);
@@ -1610,6 +1645,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1610 dev->irq = pdev->irq; 1645 dev->irq = pdev->irq;
1611 dev->base_addr = (unsigned long) ioaddr; 1646 dev->base_addr = (unsigned long) ioaddr;
1612 dev->change_mtu = rtl8169_change_mtu; 1647 dev->change_mtu = rtl8169_change_mtu;
1648 dev->set_mac_address = rtl_set_mac_address;
1613 1649
1614#ifdef CONFIG_R8169_NAPI 1650#ifdef CONFIG_R8169_NAPI
1615 dev->poll = rtl8169_poll; 1651 dev->poll = rtl8169_poll;