Subject: kern/30023: fxp_write_eeprom() will write the data into an incorrect address
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: None <tyama@mb.neweb.ne.jp>
List: netbsd-bugs
Date: 04/21/2005 17:15:00
>Number:         30023
>Category:       kern
>Synopsis:       fxp_write_eeprom() will write the data into an incorrect address
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Apr 21 17:15:00 +0000 2005
>Originator:     YAMAGUCHI Takahiro
>Release:        2.0 & 1.6.2
>Organization:
Anritsu Corporation
>Environment:
NetBSD tp1200.cichlid 1.6.2 NetBSD 1.6.2 (TP1200) #0: Mon Oct  4 11:53:58 JST 2004     tyama@tp1200.cichlid:/usr/src/sys/arch/i386/compile/TP1200 i386

>Description:
fxp_write_eeprom() (@src/sys/dev/ic/i82557.c) has a bug.
following the prototype of fxp_write_eeprom():

  void
  fxp_write_eeprom(struct fxp_softc *sc, u_int16_t *data,
                   int offset, int words);

this function will write the specified data
into an INCORRECT address,
when you assign a number larger than 1
into its argument "words".

but currently fxp_write_eeprom() is used with only
words=1 in the fresh NetBSD kernel,
so the problem will not occur at present.
>How-To-Repeat:
assign a number larger than 1 into its argument "words"
when you use fxp_write_eeprom().

EXAMPLE:  words=3
    fxp_write_eeprom(sc, myea, 0, 3);

>Fix:
fix fxp_write_eeprom() (@src/sys/dev/ic/i82557.c)

> diff -u i82557.c.org i82557.c
--- i82557.c.org        Fri Apr 22 02:09:11 2005
+++ i82557.c    Fri Apr 22 02:09:36 2005
@@ -759,7 +759,7 @@
                /* Shift in write opcode, address, data. */
                CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
                fxp_eeprom_shiftin(sc, FXP_EEPROM_OPC_WRITE, 3);
-               fxp_eeprom_shiftin(sc, offset, sc->sc_eeprom_size);
+               fxp_eeprom_shiftin(sc, i + offset, sc->sc_eeprom_size);
                fxp_eeprom_shiftin(sc, data[i], 16);
                CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
                DELAY(4);
>