Skip to content

Commit

Permalink
smsc911x: allow mac address to be saved before device reset
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Steve Glendinning authored and David S. Miller committed Feb 1, 2009
1 parent d23f028 commit 31f4574
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 8 deletions.
30 changes: 22 additions & 8 deletions drivers/net/smsc911x.c
Original file line number Diff line number Diff line change
Expand Up @@ -1742,6 +1742,21 @@ static const struct net_device_ops smsc911x_netdev_ops = {
#endif
};

/* copies the current mac address from hardware to dev->dev_addr */
static void __devinit smsc911x_read_mac_address(struct net_device *dev)
{
struct smsc911x_data *pdata = netdev_priv(dev);
u32 mac_high16 = smsc911x_mac_read(pdata, ADDRH);
u32 mac_low32 = smsc911x_mac_read(pdata, ADDRL);

dev->dev_addr[0] = (u8)(mac_low32);
dev->dev_addr[1] = (u8)(mac_low32 >> 8);
dev->dev_addr[2] = (u8)(mac_low32 >> 16);
dev->dev_addr[3] = (u8)(mac_low32 >> 24);
dev->dev_addr[4] = (u8)(mac_high16);
dev->dev_addr[5] = (u8)(mac_high16 >> 8);
}

/* Initializing private device structures, only called from probe */
static int __devinit smsc911x_init(struct net_device *dev)
{
Expand Down Expand Up @@ -1829,6 +1844,12 @@ static int __devinit smsc911x_init(struct net_device *dev)
SMSC_WARNING(PROBE,
"This driver is not intended for this chip revision");

/* workaround for platforms without an eeprom, where the mac address
* is stored elsewhere and set by the bootloader. This saves the
* mac address before resetting the device */
if (pdata->config.flags & SMSC911X_SAVE_MAC_ADDRESS)
smsc911x_read_mac_address(dev);

/* Reset the LAN911x */
if (smsc911x_soft_reset(pdata))
return -ENODEV;
Expand Down Expand Up @@ -2009,14 +2030,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
} else {
/* Try reading mac address from device. if EEPROM is present
* it will already have been set */
u32 mac_high16 = smsc911x_mac_read(pdata, ADDRH);
u32 mac_low32 = smsc911x_mac_read(pdata, ADDRL);
dev->dev_addr[0] = (u8)(mac_low32);
dev->dev_addr[1] = (u8)(mac_low32 >> 8);
dev->dev_addr[2] = (u8)(mac_low32 >> 16);
dev->dev_addr[3] = (u8)(mac_low32 >> 24);
dev->dev_addr[4] = (u8)(mac_high16);
dev->dev_addr[5] = (u8)(mac_high16 >> 8);
smsc911x_read_mac_address(dev);

if (is_valid_ether_addr(dev->dev_addr)) {
/* eeprom values are valid so use them */
Expand Down
1 change: 1 addition & 0 deletions include/linux/smsc911x.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,6 @@ struct smsc911x_platform_config {
#define SMSC911X_USE_32BIT (BIT(1))
#define SMSC911X_FORCE_INTERNAL_PHY (BIT(2))
#define SMSC911X_FORCE_EXTERNAL_PHY (BIT(3))
#define SMSC911X_SAVE_MAC_ADDRESS (BIT(4))

#endif /* __LINUX_SMSC911X_H__ */

0 comments on commit 31f4574

Please sign in to comment.