diff -Naur ipw2200-1.0.3/ipw2200.c ipw2200-1.0.3-mod/ipw2200.c --- ipw2200-1.0.3/ipw2200.c 2005-04-28 16:56:47.000000000 +0200 +++ ipw2200-1.0.3-mod/ipw2200.c 2005-04-28 17:01:15.000000000 +0200 @@ -2051,6 +2051,8 @@ * NOTE: To better understand how these functions work (i.e what is a chip * select and why do have to keep driving the eeprom clock?), read * just about any data sheet for a Microwire compatible EEPROM. + * + * The chip is 93C66 in 16x256 mode. */ /* write a 32 bit value into the indirect accessor register */ @@ -2131,6 +2133,37 @@ return r; } +/* write 16 bits to the eeprom */ +static void eeprom_write_u16(struct ipw_priv* priv, u8 addr, u16 data) +{ + int i; + + printk(KERN_INFO DRV_NAME " eeprom_write_u16(%02x, %04x)\n", addr, data); + + /* write/erase enable */ + eeprom_op(priv, EEPROM_CMD_EWEN, EEPROM_CMD_EWEN_ADDR); + eeprom_disable_cs(priv); + + eeprom_op(priv, EEPROM_CMD_WRITE, addr); + + /* now the data bits follow */ + for ( i=15; i>=0; i-- ) { + eeprom_write_bit(priv, ( (data&(1<magic != IPW2200_EEPROM_MAGIC) + return -EINVAL; if (eeprom->offset + eeprom->len > CX2_EEPROM_IMAGE_SIZE) return -EINVAL; + + wordoffset = eeprom->offset / 2; + + /* TODO ethtool currently supports writing only 1 byte, + * take eeprom->len into account */ + + if (eeprom->offset % 2 == 0) /* LSB */ + w = (p->eeprom[(eeprom->offset)+1] << 8 ) | *bytes; + else /* MSB */ + w = p->eeprom[(eeprom->offset)-1] | (*bytes << 8); + down(&p->sem); + eeprom_write_u16(p, wordoffset, w); memcpy(&((u8 *)p->eeprom)[eeprom->offset], bytes, eeprom->len); - for (i = IPW_EEPROM_DATA; - i < IPW_EEPROM_DATA + CX2_EEPROM_IMAGE_SIZE; - i++) - ipw_write8(p, i, p->eeprom[i]); up(&p->sem); return 0; } diff -Naur ipw2200-1.0.3/ipw2200.h ipw2200-1.0.3-mod/ipw2200.h --- ipw2200-1.0.3/ipw2200.h 2005-04-28 16:56:48.000000000 +0200 +++ ipw2200-1.0.3-mod/ipw2200.h 2005-04-28 16:56:35.000000000 +0200 @@ -1451,12 +1451,19 @@ #define FW_MEM_REG_LOWER_BOUND 0x00300000 #define FW_MEM_REG_EEPROM_ACCESS (FW_MEM_REG_LOWER_BOUND + 0x40) #define CX2_EVENT_REG (FW_MEM_REG_LOWER_BOUND + 0x04) -#define EEPROM_BIT_SK (1<<0) -#define EEPROM_BIT_CS (1<<1) -#define EEPROM_BIT_DI (1<<2) -#define EEPROM_BIT_DO (1<<4) +#define EEPROM_BIT_SK (1<<0) /* serial clock */ +#define EEPROM_BIT_CS (1<<1) /* chip select */ +#define EEPROM_BIT_DI (1<<2) /* data in */ +#define EEPROM_BIT_DO (1<<4) /* data out */ #define EEPROM_CMD_READ 0x2 +#define EEPROM_CMD_WRITE 0x1 +#define EEPROM_CMD_EWEN 0x0 /* write/erase enable */ +#define EEPROM_CMD_EWDS 0x0 /* write/erase disable */ + +/* these latter two are distinguished by two upper bits in address */ +#define EEPROM_CMD_EWEN_ADDR 0xC0 +#define EEPROM_CMD_EWDS_ADDR 0x00 /* Defines a single bit in a by bit number (0-31) */