aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2007-05-05 15:10:20 -0400
committerDavid S. Miller <davem@davemloft.net>2007-05-05 15:10:20 -0400
commit986e0aeb9ae09127b401c3baa66f15b7a31f354c (patch)
treeb2be088a6831cdc65668cf6788e39b91ca36291b /drivers
parenta85feb8cfc53c08b6f0d770f930ca9cc6885f414 (diff)
[TG3]: Remove reset during MAC address changes.
The reset was added a while back so that ASF could re-init whatever MAC address it wanted to use after the MAC address was changed. Instead of resetting, we can just keep MAC address 1 unchanged during MAC address changes if MAC address 1 is different from MAC address 0. This fixes 2 problems: 1. Bonding calls set_mac_address in contexts that cannot sleep. It no longer sleeps with the chip reset removed. 2. When ASF shares the same MAC address as the NIC, it needs to always do that even when the MAC address is changed. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/tg3.c35
1 files changed, 18 insertions, 17 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index e829262ded43..321121874c77 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -5934,7 +5934,7 @@ static int tg3_load_tso_firmware(struct tg3 *tp)
5934 5934
5935 5935
5936/* tp->lock is held. */ 5936/* tp->lock is held. */
5937static void __tg3_set_mac_addr(struct tg3 *tp) 5937static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1)
5938{ 5938{
5939 u32 addr_high, addr_low; 5939 u32 addr_high, addr_low;
5940 int i; 5940 int i;
@@ -5946,6 +5946,8 @@ static void __tg3_set_mac_addr(struct tg3 *tp)
5946 (tp->dev->dev_addr[4] << 8) | 5946 (tp->dev->dev_addr[4] << 8) |
5947 (tp->dev->dev_addr[5] << 0)); 5947 (tp->dev->dev_addr[5] << 0));
5948 for (i = 0; i < 4; i++) { 5948 for (i = 0; i < 4; i++) {
5949 if (i == 1 && skip_mac_1)
5950 continue;
5949 tw32(MAC_ADDR_0_HIGH + (i * 8), addr_high); 5951 tw32(MAC_ADDR_0_HIGH + (i * 8), addr_high);
5950 tw32(MAC_ADDR_0_LOW + (i * 8), addr_low); 5952 tw32(MAC_ADDR_0_LOW + (i * 8), addr_low);
5951 } 5953 }
@@ -5972,7 +5974,7 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p)
5972{ 5974{
5973 struct tg3 *tp = netdev_priv(dev); 5975 struct tg3 *tp = netdev_priv(dev);
5974 struct sockaddr *addr = p; 5976 struct sockaddr *addr = p;
5975 int err = 0; 5977 int err = 0, skip_mac_1 = 0;
5976 5978
5977 if (!is_valid_ether_addr(addr->sa_data)) 5979 if (!is_valid_ether_addr(addr->sa_data))
5978 return -EINVAL; 5980 return -EINVAL;
@@ -5983,22 +5985,21 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p)
5983 return 0; 5985 return 0;
5984 5986
5985 if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { 5987 if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
5986 /* Reset chip so that ASF can re-init any MAC addresses it 5988 u32 addr0_high, addr0_low, addr1_high, addr1_low;
5987 * needs.
5988 */
5989 tg3_netif_stop(tp);
5990 tg3_full_lock(tp, 1);
5991 5989
5992 tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); 5990 addr0_high = tr32(MAC_ADDR_0_HIGH);
5993 err = tg3_restart_hw(tp, 0); 5991 addr0_low = tr32(MAC_ADDR_0_LOW);
5994 if (!err) 5992 addr1_high = tr32(MAC_ADDR_1_HIGH);
5995 tg3_netif_start(tp); 5993 addr1_low = tr32(MAC_ADDR_1_LOW);
5996 tg3_full_unlock(tp); 5994
5997 } else { 5995 /* Skip MAC addr 1 if ASF is using it. */
5998 spin_lock_bh(&tp->lock); 5996 if ((addr0_high != addr1_high || addr0_low != addr1_low) &&
5999 __tg3_set_mac_addr(tp); 5997 !(addr1_high == 0 && addr1_low == 0))
6000 spin_unlock_bh(&tp->lock); 5998 skip_mac_1 = 1;
6001 } 5999 }
6000 spin_lock_bh(&tp->lock);
6001 __tg3_set_mac_addr(tp, skip_mac_1);
6002 spin_unlock_bh(&tp->lock);
6002 6003
6003 return err; 6004 return err;
6004} 6005}
@@ -6315,7 +6316,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
6315 tp->rx_jumbo_ptr); 6316 tp->rx_jumbo_ptr);
6316 6317
6317 /* Initialize MAC address and backoff seed. */ 6318 /* Initialize MAC address and backoff seed. */
6318 __tg3_set_mac_addr(tp); 6319 __tg3_set_mac_addr(tp, 0);
6319 6320
6320 /* MTU + ethernet header + FCS + optional VLAN tag */ 6321 /* MTU + ethernet header + FCS + optional VLAN tag */
6321 tw32(MAC_RX_MTU_SIZE, tp->dev->mtu + ETH_HLEN + 8); 6322 tw32(MAC_RX_MTU_SIZE, tp->dev->mtu + ETH_HLEN + 8);