aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/dm9000.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/dm9000.c')
-rw-r--r--drivers/net/dm9000.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index ee597e676ee5..8ef31dc4704d 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -24,6 +24,7 @@
24#include <linux/netdevice.h> 24#include <linux/netdevice.h>
25#include <linux/etherdevice.h> 25#include <linux/etherdevice.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/interrupt.h>
27#include <linux/skbuff.h> 28#include <linux/skbuff.h>
28#include <linux/spinlock.h> 29#include <linux/spinlock.h>
29#include <linux/crc32.h> 30#include <linux/crc32.h>
@@ -534,21 +535,35 @@ static int dm9000_set_eeprom(struct net_device *dev,
534 board_info_t *dm = to_dm9000_board(dev); 535 board_info_t *dm = to_dm9000_board(dev);
535 int offset = ee->offset; 536 int offset = ee->offset;
536 int len = ee->len; 537 int len = ee->len;
537 int i; 538 int done;
538 539
539 /* EEPROM access is aligned to two bytes */ 540 /* EEPROM access is aligned to two bytes */
540 541
541 if ((len & 1) != 0 || (offset & 1) != 0)
542 return -EINVAL;
543
544 if (dm->flags & DM9000_PLATF_NO_EEPROM) 542 if (dm->flags & DM9000_PLATF_NO_EEPROM)
545 return -ENOENT; 543 return -ENOENT;
546 544
547 if (ee->magic != DM_EEPROM_MAGIC) 545 if (ee->magic != DM_EEPROM_MAGIC)
548 return -EINVAL; 546 return -EINVAL;
549 547
550 for (i = 0; i < len; i += 2) 548 while (len > 0) {
551 dm9000_write_eeprom(dm, (offset + i) / 2, data + i); 549 if (len & 1 || offset & 1) {
550 int which = offset & 1;
551 u8 tmp[2];
552
553 dm9000_read_eeprom(dm, offset / 2, tmp);
554 tmp[which] = *data;
555 dm9000_write_eeprom(dm, offset / 2, tmp);
556
557 done = 1;
558 } else {
559 dm9000_write_eeprom(dm, offset / 2, data);
560 done = 2;
561 }
562
563 data += done;
564 offset += done;
565 len -= done;
566 }
552 567
553 return 0; 568 return 0;
554} 569}