summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/micrel/ks8851.c
diff options
context:
space:
mode:
authorTristram Ha <Tristram.Ha@micrel.com>2011-11-21 09:57:59 +0100
committerDavid S. Miller <davem@davemloft.net>2011-11-26 20:59:39 +0100
commit32f160d96514a15cc52b708d8a8b9742bc3acd5d (patch)
tree69dd57a9b0da0751d1fbece1e844b21225868416 /drivers/net/ethernet/micrel/ks8851.c
parentKSZ8851-SNL: Add support for EEPROM MAC address (diff)
downloadlinux-32f160d96514a15cc52b708d8a8b9742bc3acd5d.tar.xz
linux-32f160d96514a15cc52b708d8a8b9742bc3acd5d.zip
KSZ8851-SNL: Fix MAC address change problem
When device is off it is under power saving mode. Changing the MAC address in that situation will result in the device not communicating as the first write to the MAC address register is not executed. Signed-off-by: Tristram Ha <Tristram.Ha@micrel.com> [ben@simtec.co.uk: cleaned up header] Signed-off-by: Ben Dooks <ben@simtec.co.uk> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/micrel/ks8851.c')
-rw-r--r--drivers/net/ethernet/micrel/ks8851.c47
1 files changed, 27 insertions, 20 deletions
diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c
index d1669bcd4b4d..208e25a9e08c 100644
--- a/drivers/net/ethernet/micrel/ks8851.c
+++ b/drivers/net/ethernet/micrel/ks8851.c
@@ -343,6 +343,26 @@ static void ks8851_soft_reset(struct ks8851_net *ks, unsigned op)
}
/**
+ * ks8851_set_powermode - set power mode of the device
+ * @ks: The device state
+ * @pwrmode: The power mode value to write to KS_PMECR.
+ *
+ * Change the power mode of the chip.
+ */
+static void ks8851_set_powermode(struct ks8851_net *ks, unsigned pwrmode)
+{
+ unsigned pmecr;
+
+ netif_dbg(ks, hw, ks->netdev, "setting power mode %d\n", pwrmode);
+
+ pmecr = ks8851_rdreg16(ks, KS_PMECR);
+ pmecr &= ~PMECR_PM_MASK;
+ pmecr |= pwrmode;
+
+ ks8851_wrreg16(ks, KS_PMECR, pmecr);
+}
+
+/**
* ks8851_write_mac_addr - write mac address to device registers
* @dev: The network device
*
@@ -358,8 +378,15 @@ static int ks8851_write_mac_addr(struct net_device *dev)
mutex_lock(&ks->lock);
+ /*
+ * Wake up chip in case it was powered off when stopped; otherwise,
+ * the first write to the MAC address does not take effect.
+ */
+ ks8851_set_powermode(ks, PMECR_PM_NORMAL);
for (i = 0; i < ETH_ALEN; i++)
ks8851_wrreg8(ks, KS_MAR(i), dev->dev_addr[i]);
+ if (!netif_running(dev))
+ ks8851_set_powermode(ks, PMECR_PM_SOFTDOWN);
mutex_unlock(&ks->lock);
@@ -765,26 +792,6 @@ static void ks8851_tx_work(struct work_struct *work)
}
/**
- * ks8851_set_powermode - set power mode of the device
- * @ks: The device state
- * @pwrmode: The power mode value to write to KS_PMECR.
- *
- * Change the power mode of the chip.
- */
-static void ks8851_set_powermode(struct ks8851_net *ks, unsigned pwrmode)
-{
- unsigned pmecr;
-
- netif_dbg(ks, hw, ks->netdev, "setting power mode %d\n", pwrmode);
-
- pmecr = ks8851_rdreg16(ks, KS_PMECR);
- pmecr &= ~PMECR_PM_MASK;
- pmecr |= pwrmode;
-
- ks8851_wrreg16(ks, KS_PMECR, pmecr);
-}
-
-/**
* ks8851_net_open - open network device
* @dev: The network device being opened.
*