diff options
Diffstat (limited to 'drivers/net/sundance.c')
-rw-r--r-- | drivers/net/sundance.c | 23 |
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 | |||
297 | enum ASICCtrl_HiWord_bit { | 300 | enum 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); | |||
431 | static void netdev_error(struct net_device *dev, int intr_status); | 434 | static void netdev_error(struct net_device *dev, int intr_status); |
432 | static void set_rx_mode(struct net_device *dev); | 435 | static void set_rx_mode(struct net_device *dev); |
433 | static int __set_mac_addr(struct net_device *dev); | 436 | static int __set_mac_addr(struct net_device *dev); |
437 | static int sundance_set_mac_addr(struct net_device *dev, void *data); | ||
434 | static struct net_device_stats *get_stats(struct net_device *dev); | 438 | static struct net_device_stats *get_stats(struct net_device *dev); |
435 | static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | 439 | static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); |
436 | static int netdev_close(struct net_device *dev); | 440 | static 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 */ | ||
1600 | static 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 | |||
1595 | static const struct { | 1612 | static 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 | } |