net: DM9000: Add support for byte EEPROM access
authorBen Dooks <ben-linux@fluff.org>
Fri, 10 Jun 2011 00:50:32 +0000 (00:50 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sat, 11 Jun 2011 22:54:52 +0000 (15:54 -0700)
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>
drivers/net/dm9000.c

index 863e9c459e65314cb942557ddb61ac21f753fa94..8ef31dc4704d89d8c68d24fd6a1e085824c7d019 100644 (file)
@@ -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;
 }