Skip to content

Commit

Permalink
[TG3]: Remove reset during MAC address changes.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Michael Chan authored and David S. Miller committed May 5, 2007
1 parent a85feb8 commit 986e0ae
Showing 1 changed file with 18 additions and 17 deletions.
35 changes: 18 additions & 17 deletions drivers/net/tg3.c
Original file line number Diff line number Diff line change
Expand Up @@ -5934,7 +5934,7 @@ static int tg3_load_tso_firmware(struct tg3 *tp)


/* tp->lock is held. */
static void __tg3_set_mac_addr(struct tg3 *tp)
static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1)
{
u32 addr_high, addr_low;
int i;
Expand All @@ -5946,6 +5946,8 @@ static void __tg3_set_mac_addr(struct tg3 *tp)
(tp->dev->dev_addr[4] << 8) |
(tp->dev->dev_addr[5] << 0));
for (i = 0; i < 4; i++) {
if (i == 1 && skip_mac_1)
continue;
tw32(MAC_ADDR_0_HIGH + (i * 8), addr_high);
tw32(MAC_ADDR_0_LOW + (i * 8), addr_low);
}
Expand All @@ -5972,7 +5974,7 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p)
{
struct tg3 *tp = netdev_priv(dev);
struct sockaddr *addr = p;
int err = 0;
int err = 0, skip_mac_1 = 0;

if (!is_valid_ether_addr(addr->sa_data))
return -EINVAL;
Expand All @@ -5983,22 +5985,21 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p)
return 0;

if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
/* Reset chip so that ASF can re-init any MAC addresses it
* needs.
*/
tg3_netif_stop(tp);
tg3_full_lock(tp, 1);
u32 addr0_high, addr0_low, addr1_high, addr1_low;

tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
err = tg3_restart_hw(tp, 0);
if (!err)
tg3_netif_start(tp);
tg3_full_unlock(tp);
} else {
spin_lock_bh(&tp->lock);
__tg3_set_mac_addr(tp);
spin_unlock_bh(&tp->lock);
addr0_high = tr32(MAC_ADDR_0_HIGH);
addr0_low = tr32(MAC_ADDR_0_LOW);
addr1_high = tr32(MAC_ADDR_1_HIGH);
addr1_low = tr32(MAC_ADDR_1_LOW);

/* Skip MAC addr 1 if ASF is using it. */
if ((addr0_high != addr1_high || addr0_low != addr1_low) &&
!(addr1_high == 0 && addr1_low == 0))
skip_mac_1 = 1;
}
spin_lock_bh(&tp->lock);
__tg3_set_mac_addr(tp, skip_mac_1);
spin_unlock_bh(&tp->lock);

return err;
}
Expand Down Expand Up @@ -6315,7 +6316,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tp->rx_jumbo_ptr);

/* Initialize MAC address and backoff seed. */
__tg3_set_mac_addr(tp);
__tg3_set_mac_addr(tp, 0);

/* MTU + ethernet header + FCS + optional VLAN tag */
tw32(MAC_RX_MTU_SIZE, tp->dev->mtu + ETH_HLEN + 8);
Expand Down

0 comments on commit 986e0ae

Please sign in to comment.