From 20f10aa07d8d4d43ae8e129c39a84e1670b0d5ab Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Tue, 6 Jan 2009 10:55:10 -0800 Subject: dm9601: handle corrupt mac address Some cheap devices ship with dangling EEPROM pins! They always return invalid address ff:ff:ff:ff:ff:ff. Inherit the auto-generated address in this case, so that these products can work with zero configuration. Signed-off-by: Wu Fengguang Signed-off-by: Peter Korsgaard Signed-off-by: David S. Miller --- drivers/net/usb/dm9601.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/net/usb/dm9601.c') diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index edd244f3acb5..69a0436d3940 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -414,6 +414,7 @@ static int dm9601_set_mac_address(struct net_device *net, void *p) static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf) { int ret; + u8 mac[ETH_ALEN]; ret = usbnet_get_endpoints(dev, intf); if (ret) @@ -438,12 +439,18 @@ static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf) udelay(20); /* read MAC */ - if (dm_read(dev, DM_PHY_ADDR, ETH_ALEN, dev->net->dev_addr) < 0) { + if (dm_read(dev, DM_PHY_ADDR, ETH_ALEN, mac) < 0) { printk(KERN_ERR "Error reading MAC address\n"); ret = -ENODEV; goto out; } + /* + * Overwrite the auto-generated address only with good ones. + */ + if (is_valid_ether_addr(mac)) + memcpy(dev->net->dev_addr, mac, ETH_ALEN); + /* power up phy */ dm_write_reg(dev, DM_GPR_CTRL, 1); dm_write_reg(dev, DM_GPR_DATA, 0); -- cgit From 98658bc9dc37cfb7c3bf5585ca73ce44aeb05c9e Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Tue, 6 Jan 2009 10:56:07 -0800 Subject: dm9601: bring datasheet URL up to date Signed-off-by: Wu Fengguang Signed-off-by: Peter Korsgaard Signed-off-by: David S. Miller --- drivers/net/usb/dm9601.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/usb/dm9601.c') diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index 69a0436d3940..49a30bde7a89 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -23,7 +23,7 @@ #include /* datasheet: - http://www.davicom.com.tw/big5/download/Data%20Sheet/DM9601-DS-P01-930914.pdf + http://ptm2.cc.utu.fi/ftp/network/cards/DM9601/From_NET/DM9601-DS-P01-930914.pdf */ /* control requests */ -- cgit From 4b9f8ec6e5e98779e8b3806a5f58267378ef57eb Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Tue, 6 Jan 2009 18:52:58 +0000 Subject: dm9601: tell HW about random generated mac address Otherwise unicast RX will only work in promisc mode. Signed-off-by: Peter Korsgaard Signed-off-by: Wu Fengguang Signed-off-by: David S. Miller --- drivers/net/usb/dm9601.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/net/usb/dm9601.c') diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index 49a30bde7a89..63e97a387085 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -397,6 +397,11 @@ static void dm9601_set_multicast(struct net_device *net) dm_write_reg_async(dev, DM_RX_CTRL, rx_ctl); } +static void __dm9601_set_mac_address(struct usbnet *dev) +{ + dm_write_async(dev, DM_PHY_ADDR, ETH_ALEN, dev->net->dev_addr); +} + static int dm9601_set_mac_address(struct net_device *net, void *p) { struct sockaddr *addr = p; @@ -406,7 +411,7 @@ static int dm9601_set_mac_address(struct net_device *net, void *p) return -EINVAL; memcpy(net->dev_addr, addr->sa_data, net->addr_len); - dm_write_async(dev, DM_PHY_ADDR, net->addr_len, net->dev_addr); + __dm9601_set_mac_address(dev); return 0; } @@ -450,6 +455,8 @@ static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf) */ if (is_valid_ether_addr(mac)) memcpy(dev->net->dev_addr, mac, ETH_ALEN); + else + __dm9601_set_mac_address(dev); /* power up phy */ dm_write_reg(dev, DM_GPR_CTRL, 1); -- cgit From f52deb0e8408515ecf58c330c93fa99b8cb53cb4 Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Thu, 8 Jan 2009 10:47:01 -0800 Subject: dm9601: warn on invalid mac address Add warnings on invalid mac address to help disclose/debug problems. Signed-off-by: Wu Fengguang Acked-by: Peter Korsgaard Signed-off-by: David S. Miller --- drivers/net/usb/dm9601.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers/net/usb/dm9601.c') diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index 63e97a387085..5b67bbf1987e 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -407,8 +407,11 @@ static int dm9601_set_mac_address(struct net_device *net, void *p) struct sockaddr *addr = p; struct usbnet *dev = netdev_priv(net); - if (!is_valid_ether_addr(addr->sa_data)) + if (!is_valid_ether_addr(addr->sa_data)) { + dev_err(&net->dev, "not setting invalid mac address %pM\n", + addr->sa_data); return -EINVAL; + } memcpy(net->dev_addr, addr->sa_data, net->addr_len); __dm9601_set_mac_address(dev); @@ -455,8 +458,12 @@ static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf) */ if (is_valid_ether_addr(mac)) memcpy(dev->net->dev_addr, mac, ETH_ALEN); - else + else { + printk(KERN_WARNING + "dm9601: No valid MAC address in EEPROM, using %pM\n", + dev->net->dev_addr); __dm9601_set_mac_address(dev); + } /* power up phy */ dm_write_reg(dev, DM_GPR_CTRL, 1); -- cgit