aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sundance.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sundance.c')
-rw-r--r--drivers/net/sundance.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index b409d7ec4ac1..4793df843c24 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -294,6 +294,9 @@ enum alta_offsets {
294 /* Aliased and bogus values! */ 294 /* Aliased and bogus values! */
295 RxStatus = 0x0c, 295 RxStatus = 0x0c,
296}; 296};
297
298#define ASIC_HI_WORD(x) ((x) + 2)
299
297enum ASICCtrl_HiWord_bit { 300enum ASICCtrl_HiWord_bit {
298 GlobalReset = 0x0001, 301 GlobalReset = 0x0001,
299 RxReset = 0x0002, 302 RxReset = 0x0002,
@@ -431,6 +434,7 @@ static void netdev_error(struct net_device *dev, int intr_status);
431static void netdev_error(struct net_device *dev, int intr_status); 434static void netdev_error(struct net_device *dev, int intr_status);
432static void set_rx_mode(struct net_device *dev); 435static void set_rx_mode(struct net_device *dev);
433static int __set_mac_addr(struct net_device *dev); 436static int __set_mac_addr(struct net_device *dev);
437static int sundance_set_mac_addr(struct net_device *dev, void *data);
434static struct net_device_stats *get_stats(struct net_device *dev); 438static struct net_device_stats *get_stats(struct net_device *dev);
435static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); 439static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
436static int netdev_close(struct net_device *dev); 440static int netdev_close(struct net_device *dev);
@@ -464,7 +468,7 @@ static const struct net_device_ops netdev_ops = {
464 .ndo_do_ioctl = netdev_ioctl, 468 .ndo_do_ioctl = netdev_ioctl,
465 .ndo_tx_timeout = tx_timeout, 469 .ndo_tx_timeout = tx_timeout,
466 .ndo_change_mtu = change_mtu, 470 .ndo_change_mtu = change_mtu,
467 .ndo_set_mac_address = eth_mac_addr, 471 .ndo_set_mac_address = sundance_set_mac_addr,
468 .ndo_validate_addr = eth_validate_addr, 472 .ndo_validate_addr = eth_validate_addr,
469}; 473};
470 474
@@ -1592,6 +1596,19 @@ static int __set_mac_addr(struct net_device *dev)
1592 return 0; 1596 return 0;
1593} 1597}
1594 1598
1599/* Invoked with rtnl_lock held */
1600static int sundance_set_mac_addr(struct net_device *dev, void *data)
1601{
1602 const struct sockaddr *addr = data;
1603
1604 if (!is_valid_ether_addr(addr->sa_data))
1605 return -EINVAL;
1606 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
1607 __set_mac_addr(dev);
1608
1609 return 0;
1610}
1611
1595static const struct { 1612static const struct {
1596 const char name[ETH_GSTRING_LEN]; 1613 const char name[ETH_GSTRING_LEN];
1597} sundance_stats[] = { 1614} sundance_stats[] = {
@@ -1772,10 +1789,10 @@ static int netdev_close(struct net_device *dev)
1772 } 1789 }
1773 1790
1774 iowrite16(GlobalReset | DMAReset | FIFOReset | NetworkReset, 1791 iowrite16(GlobalReset | DMAReset | FIFOReset | NetworkReset,
1775 ioaddr +ASICCtrl + 2); 1792 ioaddr + ASIC_HI_WORD(ASICCtrl));
1776 1793
1777 for (i = 2000; i > 0; i--) { 1794 for (i = 2000; i > 0; i--) {
1778 if ((ioread16(ioaddr + ASICCtrl +2) & ResetBusy) == 0) 1795 if ((ioread16(ioaddr + ASIC_HI_WORD(ASICCtrl)) & ResetBusy) == 0)
1779 break; 1796 break;
1780 mdelay(1); 1797 mdelay(1);
1781 } 1798 }