Subject: Re: kern/29925
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Mihai CHELARU <kefren@netbsd.ro>
List: netbsd-bugs
Date: 07/19/2005 18:12:02
The following reply was made to PR kern/29925; it has been noted by GNATS.

From: Mihai CHELARU <kefren@netbsd.ro>
To: gnats-bugs@NetBSD.org
Cc: christos@zoulas.com
Subject: Re: kern/29925
Date: Tue, 19 Jul 2005 21:11:02 +0300

 Hi and sorry, I totally forget about this one until today when I cvs 
 updated with C flag ;)
 
 So, here is the unified patch against the latest current. I introduced 
 stge_1023_bug and this is 1 if this type of card is attached. This is 
 the best idea I had. I could also modify stge_set_filter proto but also 
 its upper callers (stge_init and stge_ioctl) so this looked to me the 
 best idea as this state is only to remain until someone smarter than me 
 fix the driver.
 
 Cheers,
 Mihai
 
 Index: pcidevs
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/pci/pcidevs,v
 retrieving revision 1.725
 diff -u -r1.725 pcidevs
 --- pcidevs     1 Jul 2005 19:37:59 -0000       1.725
 +++ pcidevs     19 Jul 2005 17:58:46 -0000
 @@ -2717,6 +2717,7 @@
 
  /* Sundance Technology products */
  product SUNDANCETI ST201       0x0201  ST201 10/100 Ethernet
 +product        SUNDANCETI ST1023       0x1023  ST1023 Gigabit Ethernet
  product SUNDANCETI ST2021      0x2021  ST2021 Gigabit Ethernet
 
  /* Surecom Technology products */
 Index: if_stge.c
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/pci/if_stge.c,v
 retrieving revision 1.28
 diff -u -r1.28 if_stge.c
 --- if_stge.c   25 Jun 2005 21:43:38 -0000      1.28
 +++ if_stge.c   19 Jul 2005 17:58:48 -0000
 @@ -277,9 +277,7 @@
  static void    stge_reset(struct stge_softc *);
  static void    stge_rxdrain(struct stge_softc *);
  static int     stge_add_rxbuf(struct stge_softc *, int);
 -#if 0
  static void    stge_read_eeprom(struct stge_softc *, int, uint16_t *);
 -#endif
  static void    stge_tick(void *);
 
  static void    stge_stats_update(struct stge_softc *);
 @@ -301,6 +299,7 @@
  static void    stge_attach(struct device *, struct device *, void *);
 
  int    stge_copy_small = 0;
 +int    stge_1023_bug = 0;      /* XXX: ST1023 works only in promisc mode */
 
  CFATTACH_DECL(stge, sizeof(struct stge_softc),
      stge_match, stge_attach, NULL, NULL);
 @@ -328,6 +327,9 @@
         pci_product_id_t        stge_product;
         const char              *stge_name;
  } stge_products[] = {
 +       { PCI_VENDOR_SUNDANCETI,        PCI_PRODUCT_SUNDANCETI_ST1023,
 +         "Sundance ST-1023 Gigabit Ethernet" },
 +
         { PCI_VENDOR_SUNDANCETI,        PCI_PRODUCT_SUNDANCETI_ST2021,
           "Sundance ST-2021 Gigabit Ethernet" },
 
 @@ -398,6 +400,7 @@
         const struct stge_product *sp;
         pcireg_t pmode;
         uint8_t enaddr[ETHER_ADDR_LEN];
 +       uint16_t myaddr[ETHER_ADDR_LEN / 2];
         int pmreg;
 
         callout_init(&sc->sc_tick_ch);
 @@ -565,20 +568,30 @@
          * Reading the station address from the EEPROM doesn't seem
          * to work, at least on my sample boards.  Instead, since
          * the reset sequence does AutoInit, read it from the station
 -        * address registers.
 +        * address registers. For Sundance 1023 you can only read it
 +        * from EEPROM.
          */
 -       enaddr[0] = bus_space_read_2(sc->sc_st, sc->sc_sh,
 -           STGE_StationAddress0) & 0xff;
 -       enaddr[1] = bus_space_read_2(sc->sc_st, sc->sc_sh,
 -           STGE_StationAddress0) >> 8;
 -       enaddr[2] = bus_space_read_2(sc->sc_st, sc->sc_sh,
 -           STGE_StationAddress1) & 0xff;
 -       enaddr[3] = bus_space_read_2(sc->sc_st, sc->sc_sh,
 -           STGE_StationAddress1) >> 8;
 -       enaddr[4] = bus_space_read_2(sc->sc_st, sc->sc_sh,
 -           STGE_StationAddress2) & 0xff;
 -       enaddr[5] = bus_space_read_2(sc->sc_st, sc->sc_sh,
 -           STGE_StationAddress2) >> 8;
 +       if (sp->stge_product != PCI_PRODUCT_SUNDANCETI_ST1023) {
 +           enaddr[0] = bus_space_read_2(sc->sc_st, sc->sc_sh,
 +               STGE_StationAddress0) & 0xff;
 +           enaddr[1] = bus_space_read_2(sc->sc_st, sc->sc_sh,
 +               STGE_StationAddress0) >> 8;
 +           enaddr[2] = bus_space_read_2(sc->sc_st, sc->sc_sh,
 +               STGE_StationAddress1) & 0xff;
 +           enaddr[3] = bus_space_read_2(sc->sc_st, sc->sc_sh,
 +               STGE_StationAddress1) >> 8;
 +           enaddr[4] = bus_space_read_2(sc->sc_st, sc->sc_sh,
 +               STGE_StationAddress2) & 0xff;
 +           enaddr[5] = bus_space_read_2(sc->sc_st, sc->sc_sh,
 +               STGE_StationAddress2) >> 8;
 +       } else {                /* The EEPROM way */
 +           for ( i=0; i<ETHER_ADDR_LEN/2; i++) {
 +               stge_read_eeprom(sc, STGE_EEPROM_StationAddress0 + i, 
 &myaddr[i]);
 +               myaddr[i]=le16toh(myaddr[i]);
 +           }
 +           memcpy(enaddr, myaddr, sizeof(enaddr));
 +           stge_1023_bug = 1;
 +       }
 
         printf("%s: Ethernet address %s\n", sc->sc_dev.dv_xname,
             ether_sprintf(enaddr));
 @@ -1761,7 +1774,6 @@
         ifp->if_timer = 0;
  }
 
 -#if 0
  static int
  stge_eeprom_wait(struct stge_softc *sc)
  {
 @@ -1796,7 +1808,6 @@
                     sc->sc_dev.dv_xname);
         *data = bus_space_read_2(sc->sc_st, sc->sc_sh, STGE_EepromData);
  }
 -#endif /* 0 */
 
  /*
   * stge_add_rxbuf:
 @@ -1863,6 +1874,11 @@
         if (ifp->if_flags & IFF_BROADCAST)
                 sc->sc_ReceiveMode |= RM_ReceiveBroadcast;
 
 +       /* XXX: ST1023 only works in promiscuous mode */
 +
 +       if (stge_1023_bug)
 +               ifp->if_flags |= IFF_PROMISC;
 +
         if (ifp->if_flags & IFF_PROMISC) {
                 sc->sc_ReceiveMode |= RM_ReceiveAllFrames;
                 goto allmulti;