summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2011-06-10 00:50:32 +0000
committerDavid S. Miller <davem@davemloft.net>2011-06-11 15:54:52 -0700
commit40d15cd06e87722b1cc27d56c8274617580f2c56 (patch)
tree0069ec0f16f41b0369d10c35616444c7c8d9d21f
parent6d65e5eee6fc8fa9abef9e78e7e789c2cb06f95c (diff)
downloadlinux-40d15cd06e87722b1cc27d56c8274617580f2c56.tar.gz
linux-40d15cd06e87722b1cc27d56c8274617580f2c56.tar.bz2
linux-40d15cd06e87722b1cc27d56c8274617580f2c56.zip
net: DM9000: Add support for byte EEPROM access
Given many versions of ethtool's reluctance to do anything other than byte accesses to the EEPROM interface, it is easier to update the driver to support byte accesses so that all the ethtool versions that have been observed in Debian can write the EEPROM. Signed-off-by: Ben Dooks <ben-linux@fluff.org> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Reviewed-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/dm9000.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 863e9c459e65..8ef31dc4704d 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -535,21 +535,35 @@ static int dm9000_set_eeprom(struct net_device *dev,
board_info_t *dm = to_dm9000_board(dev);
int offset = ee->offset;
int len = ee->len;
- int i;
+ int done;
/* EEPROM access is aligned to two bytes */
- if ((len & 1) != 0 || (offset & 1) != 0)
- return -EINVAL;
-
if (dm->flags & DM9000_PLATF_NO_EEPROM)
return -ENOENT;
if (ee->magic != DM_EEPROM_MAGIC)
return -EINVAL;
- for (i = 0; i < len; i += 2)
- dm9000_write_eeprom(dm, (offset + i) / 2, data + i);
+ while (len > 0) {
+ if (len & 1 || offset & 1) {
+ int which = offset & 1;
+ u8 tmp[2];
+
+ dm9000_read_eeprom(dm, offset / 2, tmp);
+ tmp[which] = *data;
+ dm9000_write_eeprom(dm, offset / 2, tmp);
+
+ done = 1;
+ } else {
+ dm9000_write_eeprom(dm, offset / 2, data);
+ done = 2;
+ }
+
+ data += done;
+ offset += done;
+ len -= done;
+ }
return 0;
}