aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Glendinning <steve.glendinning@smsc.com>2009-01-27 01:51:12 -0500
committerDavid S. Miller <davem@davemloft.net>2009-02-01 03:37:22 -0500
commit31f4574774e98aa275aeeee94f41ce042285ed8e (patch)
treeb7e843691852eb3efd2b2409e791f7b77bf6ebb9
parentd23f028a4ddce8b783c212bfe911d1d307ff3617 (diff)
smsc911x: allow mac address to be saved before device reset
Some platforms (for example pcm037) do not have an EEPROM fitted, instead storing their mac address somewhere else. The bootloader fetches this and configures the ethernet adapter before the kernel is started. This patch allows a platform to indicate to the driver via the SMSC911X_SAVE_MAC_ADDRESS flag that the mac address has already been configured via such a mechanism, and should be saved before resetting the chip. Signed-off-by: Steve Glendinning <steve.glendinning@smsc.com> Acked-by: Sascha Hauer <s.hauer@pengutronix.de> Tested-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/smsc911x.c30
-rw-r--r--include/linux/smsc911x.h1
2 files changed, 23 insertions, 8 deletions
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index 27d2d7c45519..6e175e5555a1 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -1742,6 +1742,21 @@ static const struct net_device_ops smsc911x_netdev_ops = {
1742#endif 1742#endif
1743}; 1743};
1744 1744
1745/* copies the current mac address from hardware to dev->dev_addr */
1746static void __devinit smsc911x_read_mac_address(struct net_device *dev)
1747{
1748 struct smsc911x_data *pdata = netdev_priv(dev);
1749 u32 mac_high16 = smsc911x_mac_read(pdata, ADDRH);
1750 u32 mac_low32 = smsc911x_mac_read(pdata, ADDRL);
1751
1752 dev->dev_addr[0] = (u8)(mac_low32);
1753 dev->dev_addr[1] = (u8)(mac_low32 >> 8);
1754 dev->dev_addr[2] = (u8)(mac_low32 >> 16);
1755 dev->dev_addr[3] = (u8)(mac_low32 >> 24);
1756 dev->dev_addr[4] = (u8)(mac_high16);
1757 dev->dev_addr[5] = (u8)(mac_high16 >> 8);
1758}
1759
1745/* Initializing private device structures, only called from probe */ 1760/* Initializing private device structures, only called from probe */
1746static int __devinit smsc911x_init(struct net_device *dev) 1761static int __devinit smsc911x_init(struct net_device *dev)
1747{ 1762{
@@ -1829,6 +1844,12 @@ static int __devinit smsc911x_init(struct net_device *dev)
1829 SMSC_WARNING(PROBE, 1844 SMSC_WARNING(PROBE,
1830 "This driver is not intended for this chip revision"); 1845 "This driver is not intended for this chip revision");
1831 1846
1847 /* workaround for platforms without an eeprom, where the mac address
1848 * is stored elsewhere and set by the bootloader. This saves the
1849 * mac address before resetting the device */
1850 if (pdata->config.flags & SMSC911X_SAVE_MAC_ADDRESS)
1851 smsc911x_read_mac_address(dev);
1852
1832 /* Reset the LAN911x */ 1853 /* Reset the LAN911x */
1833 if (smsc911x_soft_reset(pdata)) 1854 if (smsc911x_soft_reset(pdata))
1834 return -ENODEV; 1855 return -ENODEV;
@@ -2009,14 +2030,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
2009 } else { 2030 } else {
2010 /* Try reading mac address from device. if EEPROM is present 2031 /* Try reading mac address from device. if EEPROM is present
2011 * it will already have been set */ 2032 * it will already have been set */
2012 u32 mac_high16 = smsc911x_mac_read(pdata, ADDRH); 2033 smsc911x_read_mac_address(dev);
2013 u32 mac_low32 = smsc911x_mac_read(pdata, ADDRL);
2014 dev->dev_addr[0] = (u8)(mac_low32);
2015 dev->dev_addr[1] = (u8)(mac_low32 >> 8);
2016 dev->dev_addr[2] = (u8)(mac_low32 >> 16);
2017 dev->dev_addr[3] = (u8)(mac_low32 >> 24);
2018 dev->dev_addr[4] = (u8)(mac_high16);
2019 dev->dev_addr[5] = (u8)(mac_high16 >> 8);
2020 2034
2021 if (is_valid_ether_addr(dev->dev_addr)) { 2035 if (is_valid_ether_addr(dev->dev_addr)) {
2022 /* eeprom values are valid so use them */ 2036 /* eeprom values are valid so use them */
diff --git a/include/linux/smsc911x.h b/include/linux/smsc911x.h
index 170c76b8f7a6..b32725075d71 100644
--- a/include/linux/smsc911x.h
+++ b/include/linux/smsc911x.h
@@ -45,5 +45,6 @@ struct smsc911x_platform_config {
45#define SMSC911X_USE_32BIT (BIT(1)) 45#define SMSC911X_USE_32BIT (BIT(1))
46#define SMSC911X_FORCE_INTERNAL_PHY (BIT(2)) 46#define SMSC911X_FORCE_INTERNAL_PHY (BIT(2))
47#define SMSC911X_FORCE_EXTERNAL_PHY (BIT(3)) 47#define SMSC911X_FORCE_EXTERNAL_PHY (BIT(3))
48#define SMSC911X_SAVE_MAC_ADDRESS (BIT(4))
48 49
49#endif /* __LINUX_SMSC911X_H__ */ 50#endif /* __LINUX_SMSC911X_H__ */