aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/smsc911x.c
diff options
context:
space:
mode:
authorSteve Glendinning <steve.glendinning@smsc.com>2009-03-18 20:24:46 -0400
committerDavid S. Miller <davem@davemloft.net>2009-03-20 02:59:28 -0400
commit225ddf498cc99ead1d11ed1aaf1887e24e1007fa (patch)
treeb44939a61efcfb160ded2089ed4df58abb47fb9f /drivers/net/smsc911x.c
parent63a2ebb079d72f10ea7b89b85c2cd4ecc60edc61 (diff)
smsc911x: allow setting of mac address
This patch replaces the generic eth_mac_addr function with one that also updates the hardware mac address registers. It also renames the existing smsc911x_set_mac_address function to smsc911x_hw_set_mac_address for clarity. Newer LAN911x and all LAN921x devices also support changing the mac address while the device is running, which is useful for some bonding modes. Signed-off-by: Steve Glendinning <steve.glendinning@smsc.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/smsc911x.c')
-rw-r--r--drivers/net/smsc911x.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index 7df8f6e4f86a..d61514698bb3 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -1119,7 +1119,7 @@ static int smsc911x_soft_reset(struct smsc911x_data *pdata)
1119 1119
1120/* Sets the device MAC address to dev_addr, called with mac_lock held */ 1120/* Sets the device MAC address to dev_addr, called with mac_lock held */
1121static void 1121static void
1122smsc911x_set_mac_address(struct smsc911x_data *pdata, u8 dev_addr[6]) 1122smsc911x_set_hw_mac_address(struct smsc911x_data *pdata, u8 dev_addr[6])
1123{ 1123{
1124 u32 mac_high16 = (dev_addr[5] << 8) | dev_addr[4]; 1124 u32 mac_high16 = (dev_addr[5] << 8) | dev_addr[4];
1125 u32 mac_low32 = (dev_addr[3] << 24) | (dev_addr[2] << 16) | 1125 u32 mac_low32 = (dev_addr[3] << 24) | (dev_addr[2] << 16) |
@@ -1174,7 +1174,7 @@ static int smsc911x_open(struct net_device *dev)
1174 /* The soft reset above cleared the device's MAC address, 1174 /* The soft reset above cleared the device's MAC address,
1175 * restore it from local copy (set in probe) */ 1175 * restore it from local copy (set in probe) */
1176 spin_lock_irq(&pdata->mac_lock); 1176 spin_lock_irq(&pdata->mac_lock);
1177 smsc911x_set_mac_address(pdata, dev->dev_addr); 1177 smsc911x_set_hw_mac_address(pdata, dev->dev_addr);
1178 spin_unlock_irq(&pdata->mac_lock); 1178 spin_unlock_irq(&pdata->mac_lock);
1179 1179
1180 /* Initialise irqs, but leave all sources disabled */ 1180 /* Initialise irqs, but leave all sources disabled */
@@ -1504,6 +1504,31 @@ static void smsc911x_poll_controller(struct net_device *dev)
1504} 1504}
1505#endif /* CONFIG_NET_POLL_CONTROLLER */ 1505#endif /* CONFIG_NET_POLL_CONTROLLER */
1506 1506
1507static int smsc911x_set_mac_address(struct net_device *dev, void *p)
1508{
1509 struct smsc911x_data *pdata = netdev_priv(dev);
1510 struct sockaddr *addr = p;
1511
1512 /* On older hardware revisions we cannot change the mac address
1513 * registers while receiving data. Newer devices can safely change
1514 * this at any time. */
1515 if (pdata->generation <= 1 && netif_running(dev))
1516 return -EBUSY;
1517
1518 if (!is_valid_ether_addr(addr->sa_data))
1519 return -EADDRNOTAVAIL;
1520
1521 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
1522
1523 spin_lock_irq(&pdata->mac_lock);
1524 smsc911x_set_hw_mac_address(pdata, dev->dev_addr);
1525 spin_unlock_irq(&pdata->mac_lock);
1526
1527 dev_info(&dev->dev, "MAC Address: %pM\n", dev->dev_addr);
1528
1529 return 0;
1530}
1531
1507/* Standard ioctls for mii-tool */ 1532/* Standard ioctls for mii-tool */
1508static int smsc911x_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 1533static int smsc911x_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1509{ 1534{
@@ -1734,7 +1759,7 @@ static const struct net_device_ops smsc911x_netdev_ops = {
1734 .ndo_set_multicast_list = smsc911x_set_multicast_list, 1759 .ndo_set_multicast_list = smsc911x_set_multicast_list,
1735 .ndo_do_ioctl = smsc911x_do_ioctl, 1760 .ndo_do_ioctl = smsc911x_do_ioctl,
1736 .ndo_validate_addr = eth_validate_addr, 1761 .ndo_validate_addr = eth_validate_addr,
1737 .ndo_set_mac_address = eth_mac_addr, 1762 .ndo_set_mac_address = smsc911x_set_mac_address,
1738#ifdef CONFIG_NET_POLL_CONTROLLER 1763#ifdef CONFIG_NET_POLL_CONTROLLER
1739 .ndo_poll_controller = smsc911x_poll_controller, 1764 .ndo_poll_controller = smsc911x_poll_controller,
1740#endif 1765#endif
@@ -2022,7 +2047,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
2022 2047
2023 /* Check if mac address has been specified when bringing interface up */ 2048 /* Check if mac address has been specified when bringing interface up */
2024 if (is_valid_ether_addr(dev->dev_addr)) { 2049 if (is_valid_ether_addr(dev->dev_addr)) {
2025 smsc911x_set_mac_address(pdata, dev->dev_addr); 2050 smsc911x_set_hw_mac_address(pdata, dev->dev_addr);
2026 SMSC_TRACE(PROBE, "MAC Address is specified by configuration"); 2051 SMSC_TRACE(PROBE, "MAC Address is specified by configuration");
2027 } else { 2052 } else {
2028 /* Try reading mac address from device. if EEPROM is present 2053 /* Try reading mac address from device. if EEPROM is present
@@ -2036,7 +2061,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
2036 } else { 2061 } else {
2037 /* eeprom values are invalid, generate random MAC */ 2062 /* eeprom values are invalid, generate random MAC */
2038 random_ether_addr(dev->dev_addr); 2063 random_ether_addr(dev->dev_addr);
2039 smsc911x_set_mac_address(pdata, dev->dev_addr); 2064 smsc911x_set_hw_mac_address(pdata, dev->dev_addr);
2040 SMSC_TRACE(PROBE, 2065 SMSC_TRACE(PROBE,
2041 "MAC Address is set to random_ether_addr"); 2066 "MAC Address is set to random_ether_addr");
2042 } 2067 }