aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/forcedeth.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/forcedeth.c')
-rw-r--r--drivers/net/forcedeth.c63
1 files changed, 52 insertions, 11 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 4d38acbac4ef..1e691024868f 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -90,6 +90,7 @@
90 * 0.38: 16 Jul 2005: tx irq rewrite: Use global flags instead of 90 * 0.38: 16 Jul 2005: tx irq rewrite: Use global flags instead of
91 * per-packet flags. 91 * per-packet flags.
92 * 0.39: 18 Jul 2005: Add 64bit descriptor support. 92 * 0.39: 18 Jul 2005: Add 64bit descriptor support.
93 * 0.40: 19 Jul 2005: Add support for mac address change.
93 * 94 *
94 * Known bugs: 95 * Known bugs:
95 * We suspect that on some hardware no TX done interrupts are generated. 96 * We suspect that on some hardware no TX done interrupts are generated.
@@ -101,7 +102,7 @@
101 * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few 102 * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
102 * superfluous timer interrupts from the nic. 103 * superfluous timer interrupts from the nic.
103 */ 104 */
104#define FORCEDETH_VERSION "0.39" 105#define FORCEDETH_VERSION "0.40"
105#define DRV_NAME "forcedeth" 106#define DRV_NAME "forcedeth"
106 107
107#include <linux/module.h> 108#include <linux/module.h>
@@ -1416,6 +1417,54 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu)
1416 return 0; 1417 return 0;
1417} 1418}
1418 1419
1420static void nv_copy_mac_to_hw(struct net_device *dev)
1421{
1422 u8 *base = get_hwbase(dev);
1423 u32 mac[2];
1424
1425 mac[0] = (dev->dev_addr[0] << 0) + (dev->dev_addr[1] << 8) +
1426 (dev->dev_addr[2] << 16) + (dev->dev_addr[3] << 24);
1427 mac[1] = (dev->dev_addr[4] << 0) + (dev->dev_addr[5] << 8);
1428
1429 writel(mac[0], base + NvRegMacAddrA);
1430 writel(mac[1], base + NvRegMacAddrB);
1431}
1432
1433/*
1434 * nv_set_mac_address: dev->set_mac_address function
1435 * Called with rtnl_lock() held.
1436 */
1437static int nv_set_mac_address(struct net_device *dev, void *addr)
1438{
1439 struct fe_priv *np = get_nvpriv(dev);
1440 struct sockaddr *macaddr = (struct sockaddr*)addr;
1441
1442 if(!is_valid_ether_addr(macaddr->sa_data))
1443 return -EADDRNOTAVAIL;
1444
1445 /* synchronized against open : rtnl_lock() held by caller */
1446 memcpy(dev->dev_addr, macaddr->sa_data, ETH_ALEN);
1447
1448 if (netif_running(dev)) {
1449 spin_lock_bh(&dev->xmit_lock);
1450 spin_lock_irq(&np->lock);
1451
1452 /* stop rx engine */
1453 nv_stop_rx(dev);
1454
1455 /* set mac address */
1456 nv_copy_mac_to_hw(dev);
1457
1458 /* restart rx engine */
1459 nv_start_rx(dev);
1460 spin_unlock_irq(&np->lock);
1461 spin_unlock_bh(&dev->xmit_lock);
1462 } else {
1463 nv_copy_mac_to_hw(dev);
1464 }
1465 return 0;
1466}
1467
1419/* 1468/*
1420 * nv_set_multicast: dev->set_multicast function 1469 * nv_set_multicast: dev->set_multicast function
1421 * Called with dev->xmit_lock held. 1470 * Called with dev->xmit_lock held.
@@ -2047,16 +2096,7 @@ static int nv_open(struct net_device *dev)
2047 np->in_shutdown = 0; 2096 np->in_shutdown = 0;
2048 2097
2049 /* 3) set mac address */ 2098 /* 3) set mac address */
2050 { 2099 nv_copy_mac_to_hw(dev);
2051 u32 mac[2];
2052
2053 mac[0] = (dev->dev_addr[0] << 0) + (dev->dev_addr[1] << 8) +
2054 (dev->dev_addr[2] << 16) + (dev->dev_addr[3] << 24);
2055 mac[1] = (dev->dev_addr[4] << 0) + (dev->dev_addr[5] << 8);
2056
2057 writel(mac[0], base + NvRegMacAddrA);
2058 writel(mac[1], base + NvRegMacAddrB);
2059 }
2060 2100
2061 /* 4) give hw rings */ 2101 /* 4) give hw rings */
2062 writel((u32) np->ring_addr, base + NvRegRxRingPhysAddr); 2102 writel((u32) np->ring_addr, base + NvRegRxRingPhysAddr);
@@ -2302,6 +2342,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
2302 dev->hard_start_xmit = nv_start_xmit; 2342 dev->hard_start_xmit = nv_start_xmit;
2303 dev->get_stats = nv_get_stats; 2343 dev->get_stats = nv_get_stats;
2304 dev->change_mtu = nv_change_mtu; 2344 dev->change_mtu = nv_change_mtu;
2345 dev->set_mac_address = nv_set_mac_address;
2305 dev->set_multicast_list = nv_set_multicast; 2346 dev->set_multicast_list = nv_set_multicast;
2306#ifdef CONFIG_NET_POLL_CONTROLLER 2347#ifdef CONFIG_NET_POLL_CONTROLLER
2307 dev->poll_controller = nv_poll_controller; 2348 dev->poll_controller = nv_poll_controller;