Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=2eb3e621c4e07e9e7200dbb66f0433b4caafb8e7
Commit:     2eb3e621c4e07e9e7200dbb66f0433b4caafb8e7
Parent:     8ce5e3e45e01ffab38a9f03900181132b9068543
Author:     Stephen Hemminger <[EMAIL PROTECTED]>
AuthorDate: Mon Mar 12 15:16:26 2007 -0700
Committer:  Jeff Garzik <[EMAIL PROTECTED]>
CommitDate: Thu Mar 15 10:44:32 2007 -0400

    skge: set mac address bonding fix
    
    When bonding does fail over it calls set_mac_address.  When this happens
    as the result of another port going down, the phy_mutex that is common to
    both ports is held, so it deadlocks. Setting the address doesn't need to do
    anything that needs the phy_mutex, it already has the RTNL to protect 
against
    other admin actions.
    
    This change just disables the receiver to avoid any hardware confusion
    while address is changing.
    
    Signed-off-by: Stephen Hemminger <[EMAIL PROTECTED]>
    Signed-off-by: Jeff Garzik <[EMAIL PROTECTED]>
---
 drivers/net/skge.c |   28 +++++++++++++++++-----------
 1 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index eea75a4..8fecf1b 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -3275,24 +3275,30 @@ static int skge_set_mac_address(struct net_device *dev, 
void *p)
        struct skge_hw *hw = skge->hw;
        unsigned port = skge->port;
        const struct sockaddr *addr = p;
+       u16 ctrl;
 
        if (!is_valid_ether_addr(addr->sa_data))
                return -EADDRNOTAVAIL;
 
-       mutex_lock(&hw->phy_mutex);
        memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
-       memcpy_toio(hw->regs + B2_MAC_1 + port*8,
-                   dev->dev_addr, ETH_ALEN);
-       memcpy_toio(hw->regs + B2_MAC_2 + port*8,
-                   dev->dev_addr, ETH_ALEN);
 
-       if (hw->chip_id == CHIP_ID_GENESIS)
-               xm_outaddr(hw, port, XM_SA, dev->dev_addr);
-       else {
-               gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr);
-               gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr);
+       /* disable Rx */
+       ctrl = gma_read16(hw, port, GM_GP_CTRL);
+       gma_write16(hw, port, GM_GP_CTRL, ctrl & ~GM_GPCR_RX_ENA);
+
+       memcpy_toio(hw->regs + B2_MAC_1 + port*8, dev->dev_addr, ETH_ALEN);
+       memcpy_toio(hw->regs + B2_MAC_2 + port*8, dev->dev_addr, ETH_ALEN);
+
+       if (netif_running(dev)) {
+               if (hw->chip_id == CHIP_ID_GENESIS)
+                       xm_outaddr(hw, port, XM_SA, dev->dev_addr);
+               else {
+                       gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr);
+                       gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr);
+               }
        }
-       mutex_unlock(&hw->phy_mutex);
+
+       gma_write16(hw, port, GM_GP_CTRL, ctrl);
 
        return 0;
 }
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to