[BACK]Return to if_xi.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / pcmcia

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/dev/pcmcia/if_xi.c between version 1.31.2.2 and 1.31.2.3

version 1.31.2.2, 2004/08/12 11:42:01 version 1.31.2.3, 2004/08/25 06:58:42
Line 54 
Line 54 
  * A driver for Xircom CreditCard PCMCIA Ethernet adapters.   * A driver for Xircom CreditCard PCMCIA Ethernet adapters.
  */   */
   
 /*  
  * Known Bugs:  
  *  
  * 1) Promiscuous mode doesn't work on at least the CE2.  
  * 2) Slow. ~450KB/s.  Memory access would be better.  
  */  
   
 #include <sys/cdefs.h>  #include <sys/cdefs.h>
 __KERNEL_RCSID(0, "$NetBSD$");  __KERNEL_RCSID(0, "$NetBSD$");
   
Line 75  __KERNEL_RCSID(0, "$NetBSD$");
Line 68  __KERNEL_RCSID(0, "$NetBSD$");
 #include <sys/mbuf.h>  #include <sys/mbuf.h>
 #include <sys/malloc.h>  #include <sys/malloc.h>
 #include <sys/socket.h>  #include <sys/socket.h>
   #include <sys/kernel.h>
   #include <sys/proc.h>
   
 #include <net/if.h>  #include <net/if.h>
 #include <net/if_dl.h>  #include <net/if_dl.h>
Line 335  xi_intr(arg)
Line 330  xi_intr(arg)
         PAGE(sc, 0);          PAGE(sc, 0);
         if (sc->sc_chipset >= XI_CHIPSET_MOHAWK) {          if (sc->sc_chipset >= XI_CHIPSET_MOHAWK) {
                 /* Disable interrupt (Linux does it). */                  /* Disable interrupt (Linux does it). */
                 bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + CR,                  bus_space_write_1(sc->sc_bst, sc->sc_bsh, CR, 0);
                     0);  
         }          }
   
         esr = bus_space_read_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + ESR);          esr = bus_space_read_1(sc->sc_bst, sc->sc_bsh, ESR);
         isr = bus_space_read_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + ISR0);          isr = bus_space_read_1(sc->sc_bst, sc->sc_bsh, ISR0);
         rsr = bus_space_read_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + RSR);          rsr = bus_space_read_1(sc->sc_bst, sc->sc_bsh, RSR);
   
         /* Check to see if card has been ejected. */          /* Check to see if card has been ejected. */
         if (isr == 0xff) {          if (isr == 0xff) {
Line 354  xi_intr(arg)
Line 348  xi_intr(arg)
   
         PAGE(sc, 0x40);          PAGE(sc, 0x40);
         rx_status =          rx_status =
             bus_space_read_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + RXST0);              bus_space_read_1(sc->sc_bst, sc->sc_bsh, RXST0);
         bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + RXST0,          bus_space_write_1(sc->sc_bst, sc->sc_bsh, RXST0, ~rx_status & 0xff);
             ~rx_status & 0xff);  
         tx_status =          tx_status =
             bus_space_read_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + TXST0);              bus_space_read_1(sc->sc_bst, sc->sc_bsh, TXST0);
         tx_status |=          tx_status |=
             bus_space_read_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + TXST1) << 8;              bus_space_read_1(sc->sc_bst, sc->sc_bsh, TXST1) << 8;
         bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + TXST0,0);          bus_space_write_1(sc->sc_bst, sc->sc_bsh, TXST0, 0);
         bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + TXST1,0);          bus_space_write_1(sc->sc_bst, sc->sc_bsh, TXST1, 0);
         DPRINTF(XID_INTR, ("xi: rx_status=%02x tx_status=%04x\n", rx_status,          DPRINTF(XID_INTR, ("xi: rx_status=%02x tx_status=%04x\n", rx_status,
             tx_status));              tx_status));
   
Line 377  xi_intr(arg)
Line 370  xi_intr(arg)
                             ("xi: too many bytes this interrupt\n"));                              ("xi: too many bytes this interrupt\n"));
                         ifp->if_iqdrops++;                          ifp->if_iqdrops++;
                         /* Drop packet. */                          /* Drop packet. */
                         bus_space_write_2(sc->sc_bst, sc->sc_bsh,                          bus_space_write_2(sc->sc_bst, sc->sc_bsh, DO0,
                             sc->sc_offset + DO0, DO_SKIP_RX_PKT);                              DO_SKIP_RX_PKT);
                 }                  }
                 tempint = xi_get(sc);   /* XXX doesn't check the error! */                  tempint = xi_get(sc);   /* XXX doesn't check the error! */
                 recvcount += tempint;                  recvcount += tempint;
                 ifp->if_ibytes += tempint;                  ifp->if_ibytes += tempint;
                 esr = bus_space_read_1(sc->sc_bst, sc->sc_bsh,                  esr = bus_space_read_1(sc->sc_bst, sc->sc_bsh, ESR);
                     sc->sc_offset + ESR);                  rsr = bus_space_read_1(sc->sc_bst, sc->sc_bsh, RSR);
                 rsr = bus_space_read_1(sc->sc_bst, sc->sc_bsh,  
                     sc->sc_offset + RSR);  
         }          }
   
         /* Packet too long? */          /* Packet too long? */
Line 410  xi_intr(arg)
Line 401  xi_intr(arg)
         /* Check for rx overrun. */          /* Check for rx overrun. */
         if (rx_status & RX_OVERRUN) {          if (rx_status & RX_OVERRUN) {
                 ifp->if_ierrors++;                  ifp->if_ierrors++;
                 bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + CR,                  bus_space_write_1(sc->sc_bst, sc->sc_bsh, CR, CLR_RX_OVERRUN);
                     CLR_RX_OVERRUN);  
                 DPRINTF(XID_INTR, ("xi: overrun cleared\n"));                  DPRINTF(XID_INTR, ("xi: overrun cleared\n"));
         }          }
   
Line 422  xi_intr(arg)
Line 412  xi_intr(arg)
         /* Detected excessive collisions? */          /* Detected excessive collisions? */
         if ((tx_status & EXCESSIVE_COLL) && ifp->if_opackets > 0) {          if ((tx_status & EXCESSIVE_COLL) && ifp->if_opackets > 0) {
                 DPRINTF(XID_INTR, ("xi: excessive collisions\n"));                  DPRINTF(XID_INTR, ("xi: excessive collisions\n"));
                 bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + CR,                  bus_space_write_1(sc->sc_bst, sc->sc_bsh, CR, RESTART_TX);
                     RESTART_TX);  
                 ifp->if_oerrors++;                  ifp->if_oerrors++;
         }          }
   
Line 438  xi_intr(arg)
Line 427  xi_intr(arg)
 end:  end:
         /* Reenable interrupts. */          /* Reenable interrupts. */
         PAGE(sc, 0);          PAGE(sc, 0);
         bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + CR,          bus_space_write_1(sc->sc_bst, sc->sc_bsh, CR, ENABLE_INT);
             ENABLE_INT);  
   
         return (1);          return (1);
 }  }
Line 460  xi_get(sc)
Line 448  xi_get(sc)
   
         PAGE(sc, 0);          PAGE(sc, 0);
         pktlen =          pktlen =
             bus_space_read_2(sc->sc_bst, sc->sc_bsh, sc->sc_offset + RBC0) &              bus_space_read_2(sc->sc_bst, sc->sc_bsh, RBC0) & RBC_COUNT_MASK;
             RBC_COUNT_MASK;  
   
         DPRINTF(XID_CONFIG, ("xi_get: pktlen=%d\n", pktlen));          DPRINTF(XID_CONFIG, ("xi_get: pktlen=%d\n", pktlen));
   
Line 515  xi_get(sc)
Line 502  xi_get(sc)
                 data = mtod(m, u_int8_t *);                  data = mtod(m, u_int8_t *);
                 if (len > 1) {                  if (len > 1) {
                         len &= ~1;                          len &= ~1;
                         bus_space_read_multi_2(sc->sc_bst, sc->sc_bsh,                          bus_space_read_multi_2(sc->sc_bst, sc->sc_bsh, EDP,
                             sc->sc_offset + EDP, (u_int16_t *)data, len>>1);                              (u_int16_t *)data, len>>1);
                 } else                  } else
                         *data = bus_space_read_1(sc->sc_bst, sc->sc_bsh,                          *data = bus_space_read_1(sc->sc_bst, sc->sc_bsh, EDP);
                             sc->sc_offset + EDP);  
                 m->m_len = len;                  m->m_len = len;
                 pktlen -= len;                  pktlen -= len;
                 *mp = m;                  *mp = m;
Line 527  xi_get(sc)
Line 513  xi_get(sc)
         }          }
   
         /* Skip Rx packet. */          /* Skip Rx packet. */
         bus_space_write_2(sc->sc_bst, sc->sc_bsh, sc->sc_offset + DO0,          bus_space_write_2(sc->sc_bst, sc->sc_bsh, DO0, DO_SKIP_RX_PKT);
             DO_SKIP_RX_PKT);  
   
         ifp->if_ipackets++;          ifp->if_ipackets++;
   
Line 556  xi_mdi_idle(sc)
Line 541  xi_mdi_idle(sc)
 {  {
         bus_space_tag_t bst = sc->sc_bst;          bus_space_tag_t bst = sc->sc_bst;
         bus_space_handle_t bsh = sc->sc_bsh;          bus_space_handle_t bsh = sc->sc_bsh;
         bus_size_t offset = sc->sc_offset;  
   
         /* Drive MDC low... */          /* Drive MDC low... */
         bus_space_write_1(bst, bsh, offset + GP2, MDC_LOW);          bus_space_write_1(bst, bsh, GP2, MDC_LOW);
         DELAY(1);          DELAY(1);
   
         /* and high again. */          /* and high again. */
         bus_space_write_1(bst, bsh, offset + GP2, MDC_HIGH);          bus_space_write_1(bst, bsh, GP2, MDC_HIGH);
         DELAY(1);          DELAY(1);
 }  }
   
Line 576  xi_mdi_pulse(sc, data)
Line 560  xi_mdi_pulse(sc, data)
 {  {
         bus_space_tag_t bst = sc->sc_bst;          bus_space_tag_t bst = sc->sc_bst;
         bus_space_handle_t bsh = sc->sc_bsh;          bus_space_handle_t bsh = sc->sc_bsh;
         bus_size_t offset = sc->sc_offset;  
         u_int8_t bit = data ? MDIO_HIGH : MDIO_LOW;          u_int8_t bit = data ? MDIO_HIGH : MDIO_LOW;
   
         /* First latch the data bit MDIO with clock bit MDC low...*/          /* First latch the data bit MDIO with clock bit MDC low...*/
         bus_space_write_1(bst, bsh, offset + GP2, bit | MDC_LOW);          bus_space_write_1(bst, bsh, GP2, bit | MDC_LOW);
         DELAY(1);          DELAY(1);
   
         /* then raise the clock again, preserving the data bit. */          /* then raise the clock again, preserving the data bit. */
         bus_space_write_1(bst, bsh, offset + GP2, bit | MDC_HIGH);          bus_space_write_1(bst, bsh, GP2, bit | MDC_HIGH);
         DELAY(1);          DELAY(1);
 }  }
   
Line 596  xi_mdi_probe(sc)
Line 579  xi_mdi_probe(sc)
 {  {
         bus_space_tag_t bst = sc->sc_bst;          bus_space_tag_t bst = sc->sc_bst;
         bus_space_handle_t bsh = sc->sc_bsh;          bus_space_handle_t bsh = sc->sc_bsh;
         bus_size_t offset = sc->sc_offset;  
         u_int8_t x;          u_int8_t x;
   
         /* Pull clock bit MDCK low... */          /* Pull clock bit MDCK low... */
         bus_space_write_1(bst, bsh, offset + GP2, MDC_LOW);          bus_space_write_1(bst, bsh, GP2, MDC_LOW);
         DELAY(1);          DELAY(1);
   
         /* Read data and drive clock high again. */          /* Read data and drive clock high again. */
         x = bus_space_read_1(bst, bsh, offset + GP2);          x = bus_space_read_1(bst, bsh, GP2);
         bus_space_write_1(bst, bsh, offset + GP2, MDC_HIGH);          bus_space_write_1(bst, bsh, GP2, MDC_HIGH);
         DELAY(1);          DELAY(1);
   
         return (x & MDIO);          return (x & MDIO);
Line 760  xi_stop(sc)
Line 742  xi_stop(sc)
 {  {
         bus_space_tag_t bst = sc->sc_bst;          bus_space_tag_t bst = sc->sc_bst;
         bus_space_handle_t bsh = sc->sc_bsh;          bus_space_handle_t bsh = sc->sc_bsh;
         bus_size_t offset = sc->sc_offset;  
   
         DPRINTF(XID_CONFIG, ("xi_stop()\n"));          DPRINTF(XID_CONFIG, ("xi_stop()\n"));
   
         PAGE(sc, 0x40);          PAGE(sc, 0x40);
         bus_space_write_1(bst, bsh, offset + CMD0, DISABLE_RX);          bus_space_write_1(bst, bsh, CMD0, DISABLE_RX);
   
         /* Disable interrupts. */          /* Disable interrupts. */
         PAGE(sc, 0);          PAGE(sc, 0);
         bus_space_write_1(bst, bsh, offset + CR, 0);          bus_space_write_1(bst, bsh, CR, 0);
   
         PAGE(sc, 1);          PAGE(sc, 1);
         bus_space_write_1(bst, bsh, offset + IMR0, 0);          bus_space_write_1(bst, bsh, IMR0, 0);
   
         /* Cancel watchdog timer. */          /* Cancel watchdog timer. */
         sc->sc_ethercom.ec_if.if_timer = 0;          sc->sc_ethercom.ec_if.if_timer = 0;
Line 812  xi_init(sc)
Line 793  xi_init(sc)
         struct ifnet *ifp = &sc->sc_ethercom.ec_if;          struct ifnet *ifp = &sc->sc_ethercom.ec_if;
         bus_space_tag_t bst = sc->sc_bst;          bus_space_tag_t bst = sc->sc_bst;
         bus_space_handle_t bsh = sc->sc_bsh;          bus_space_handle_t bsh = sc->sc_bsh;
         bus_size_t offset = sc->sc_offset;  
   
         DPRINTF(XID_CONFIG, ("xi_init()\n"));          DPRINTF(XID_CONFIG, ("xi_init()\n"));
   
         /* Setup the ethernet interrupt mask. */          /* Setup the ethernet interrupt mask. */
         PAGE(sc, 1);          PAGE(sc, 1);
         bus_space_write_1(bst, bsh, offset + IMR0,          bus_space_write_1(bst, bsh, IMR0,
             ISR_TX_OFLOW | ISR_PKT_TX | ISR_MAC_INT | /* ISR_RX_EARLY | */              ISR_TX_OFLOW | ISR_PKT_TX | ISR_MAC_INT | /* ISR_RX_EARLY | */
             ISR_RX_FULL | ISR_RX_PKT_REJ | ISR_FORCED_INT);              ISR_RX_FULL | ISR_RX_PKT_REJ | ISR_FORCED_INT);
         if (sc->sc_chipset < XI_CHIPSET_DINGO) {          if (sc->sc_chipset < XI_CHIPSET_DINGO) {
                 /* XXX What is this?  Not for Dingo at least. */                  /* XXX What is this?  Not for Dingo at least. */
                 /* Unmask TX underrun detection */                  /* Unmask TX underrun detection */
                 bus_space_write_1(bst, bsh, offset + IMR1, 1);                  bus_space_write_1(bst, bsh, IMR1, 1);
         }          }
   
         /* Enable interrupts. */          /* Enable interrupts. */
         PAGE(sc, 0);          PAGE(sc, 0);
         bus_space_write_1(bst, bsh, offset + CR, ENABLE_INT);          bus_space_write_1(bst, bsh, CR, ENABLE_INT);
   
         xi_set_address(sc);          xi_set_address(sc);
   
         PAGE(sc, 0x40);          PAGE(sc, 0x40);
         bus_space_write_1(bst, bsh, offset + CMD0, ENABLE_RX | ONLINE);          bus_space_write_1(bst, bsh, CMD0, ENABLE_RX | ONLINE);
   
         PAGE(sc, 0);          PAGE(sc, 0);
   
Line 858  xi_start(ifp)
Line 838  xi_start(ifp)
         struct xi_softc *sc = ifp->if_softc;          struct xi_softc *sc = ifp->if_softc;
         bus_space_tag_t bst = sc->sc_bst;          bus_space_tag_t bst = sc->sc_bst;
         bus_space_handle_t bsh = sc->sc_bsh;          bus_space_handle_t bsh = sc->sc_bsh;
         bus_size_t offset = sc->sc_offset;  
         unsigned int s, len, pad = 0;          unsigned int s, len, pad = 0;
         struct mbuf *m0, *m;          struct mbuf *m0, *m;
         u_int16_t space;          u_int16_t space;
Line 892  xi_start(ifp)
Line 871  xi_start(ifp)
   
         PAGE(sc, 0);          PAGE(sc, 0);
   
         bus_space_write_2(bst, bsh, offset + TRS, (u_int16_t)len + pad + 2);          bus_space_write_2(bst, bsh, TRS, (u_int16_t)len + pad + 2);
         space = bus_space_read_2(bst, bsh, offset + TSO) & 0x7fff;          space = bus_space_read_2(bst, bsh, TSO) & 0x7fff;
         if (len + pad + 2 > space) {          if (len + pad + 2 > space) {
                 DPRINTF(XID_FIFO,                  DPRINTF(XID_FIFO,
                     ("xi: not enough space in output FIFO (%d > %d)\n",                      ("xi: not enough space in output FIFO (%d > %d)\n",
Line 914  xi_start(ifp)
Line 893  xi_start(ifp)
          */           */
         s = splhigh();          s = splhigh();
   
         bus_space_write_2(bst, bsh, offset + EDP, (u_int16_t)len + pad);          bus_space_write_2(bst, bsh, EDP, (u_int16_t)len + pad);
         for (m = m0; m; ) {          for (m = m0; m; ) {
                 if (m->m_len > 1)                  if (m->m_len > 1)
                         bus_space_write_multi_2(bst, bsh, offset + EDP,                          bus_space_write_multi_2(bst, bsh, EDP,
                             mtod(m, u_int16_t *), m->m_len>>1);                              mtod(m, u_int16_t *), m->m_len>>1);
                 if (m->m_len & 1) {                  if (m->m_len & 1) {
                         DPRINTF(XID_CONFIG, ("xi: XXX odd!\n"));                          DPRINTF(XID_CONFIG, ("xi: XXX odd!\n"));
                         bus_space_write_1(bst, bsh, offset + EDP,                          bus_space_write_1(bst, bsh, EDP,
                             *(mtod(m, u_int8_t *) + m->m_len - 1));                              *(mtod(m, u_int8_t *) + m->m_len - 1));
                 }                  }
                 MFREE(m, m0);                  MFREE(m, m0);
Line 929  xi_start(ifp)
Line 908  xi_start(ifp)
         }          }
         DPRINTF(XID_CONFIG, ("xi: len=%d pad=%d total=%d\n", len, pad, len+pad+4));          DPRINTF(XID_CONFIG, ("xi: len=%d pad=%d total=%d\n", len, pad, len+pad+4));
         if (sc->sc_chipset >= XI_CHIPSET_MOHAWK)          if (sc->sc_chipset >= XI_CHIPSET_MOHAWK)
                 bus_space_write_1(bst, bsh, offset + CR, TX_PKT | ENABLE_INT);                  bus_space_write_1(bst, bsh, CR, TX_PKT | ENABLE_INT);
         else {          else {
                 for (; pad > 1; pad -= 2)                  for (; pad > 1; pad -= 2)
                         bus_space_write_2(bst, bsh, offset + EDP, 0);                          bus_space_write_2(bst, bsh, EDP, 0);
                 if (pad == 1)                  if (pad == 1)
                         bus_space_write_1(bst, bsh, offset + EDP, 0);                          bus_space_write_1(bst, bsh, EDP, 0);
         }          }
   
         splx(s);          splx(s);
Line 1087  xi_set_address(sc)
Line 1066  xi_set_address(sc)
 {  {
         bus_space_tag_t bst = sc->sc_bst;          bus_space_tag_t bst = sc->sc_bst;
         bus_space_handle_t bsh = sc->sc_bsh;          bus_space_handle_t bsh = sc->sc_bsh;
         bus_size_t offset = sc->sc_offset;  
         struct ethercom *ether = &sc->sc_ethercom;          struct ethercom *ether = &sc->sc_ethercom;
         struct ifnet *ifp = &sc->sc_ethercom.ec_if;          struct ifnet *ifp = &sc->sc_ethercom.ec_if;
         struct ether_multistep step;          struct ether_multistep step;
Line 1151  done:
Line 1129  done:
 #endif  #endif
   
                 PAGE(sc, 0x50 + page);                  PAGE(sc, 0x50 + page);
                 bus_space_write_region_1(bst, bsh, offset + IA,                  bus_space_write_region_1(bst, bsh, IA, &indaddr[page * 8],
                     &indaddr[page * 8], page == 7 ? 4 : 8);                      page == 7 ? 4 : 8);
                 /*                  /*
                  * XXX                   * XXX
                  * Without this delay, the address registers on my CE2 get                   * Without this delay, the address registers on my CE2 get
Line 1163  done:
Line 1141  done:
   
 #ifdef XIDEBUG  #ifdef XIDEBUG
                 if (xidebug & XID_MCAST) {                  if (xidebug & XID_MCAST) {
                         bus_space_read_region_1(bst, bsh, offset + IA,                          bus_space_read_region_1(bst, bsh, IA,
                             &indaddr[page * 8], page == 7 ? 4 : 8);                              &indaddr[page * 8], page == 7 ? 4 : 8);
                         printf("page %d after: ", page);                          printf("page %d after: ", page);
                         for (i = 0; i < 8; i++)                          for (i = 0; i < 8; i++)
Line 1181  done:
Line 1159  done:
                 x |= SWC1_MCAST_PROM;                  x |= SWC1_MCAST_PROM;
         if (!LIST_FIRST(&sc->sc_mii.mii_phys))          if (!LIST_FIRST(&sc->sc_mii.mii_phys))
                 x |= SWC1_AUTO_MEDIA;                  x |= SWC1_AUTO_MEDIA;
         bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + SWC1, x);          bus_space_write_1(sc->sc_bst, sc->sc_bsh, SWC1, x);
 }  }
   
 STATIC void  STATIC void
Line 1190  xi_cycle_power(sc)
Line 1168  xi_cycle_power(sc)
 {  {
         bus_space_tag_t bst = sc->sc_bst;          bus_space_tag_t bst = sc->sc_bst;
         bus_space_handle_t bsh = sc->sc_bsh;          bus_space_handle_t bsh = sc->sc_bsh;
         bus_size_t offset = sc->sc_offset;  
   
         DPRINTF(XID_CONFIG, ("xi_cycle_power()\n"));          DPRINTF(XID_CONFIG, ("xi_cycle_power()\n"));
   
         PAGE(sc, 4);          PAGE(sc, 4);
         DELAY(1);          DELAY(1);
         bus_space_write_1(bst, bsh, offset + GP1, 0);          bus_space_write_1(bst, bsh, GP1, 0);
         DELAY(40000);          tsleep(&xi_cycle_power, PWAIT, "xipwr1", hz * 40 / 1000);
         if (sc->sc_chipset >= XI_CHIPSET_MOHAWK)          if (sc->sc_chipset >= XI_CHIPSET_MOHAWK)
                 bus_space_write_1(bst, bsh, offset + GP1, POWER_UP);                  bus_space_write_1(bst, bsh, GP1, POWER_UP);
         else          else
                 /* XXX What is bit 2 (aka AIC)? */                  /* XXX What is bit 2 (aka AIC)? */
                 bus_space_write_1(bst, bsh, offset + GP1, POWER_UP | 4);                  bus_space_write_1(bst, bsh, GP1, POWER_UP | 4);
         DELAY(20000);          tsleep(&xi_cycle_power, PWAIT, "xipwr2", hz * 20 / 1000);
 }  }
   
 STATIC void  STATIC void
Line 1212  xi_full_reset(sc)
Line 1189  xi_full_reset(sc)
 {  {
         bus_space_tag_t bst = sc->sc_bst;          bus_space_tag_t bst = sc->sc_bst;
         bus_space_handle_t bsh = sc->sc_bsh;          bus_space_handle_t bsh = sc->sc_bsh;
         bus_size_t offset = sc->sc_offset;  
         u_int8_t x;          u_int8_t x;
   
         DPRINTF(XID_CONFIG, ("xi_full_reset()\n"));          DPRINTF(XID_CONFIG, ("xi_full_reset()\n"));
   
         /* Do an as extensive reset as possible on all functions. */          /* Do an as extensive reset as possible on all functions. */
         xi_cycle_power(sc);          xi_cycle_power(sc);
         bus_space_write_1(bst, bsh, offset + CR, SOFT_RESET);          bus_space_write_1(bst, bsh, CR, SOFT_RESET);
         DELAY(20000);          tsleep(&xi_full_reset, PWAIT, "xirst1", hz * 20 / 1000);
         bus_space_write_1(bst, bsh, offset + CR, 0);          bus_space_write_1(bst, bsh, CR, 0);
         DELAY(20000);          tsleep(&xi_full_reset, PWAIT, "xirst2", hz * 20 / 1000);
         PAGE(sc, 4);          PAGE(sc, 4);
         if (sc->sc_chipset >= XI_CHIPSET_MOHAWK) {          if (sc->sc_chipset >= XI_CHIPSET_MOHAWK) {
                 /*                  /*
                  * Drive GP1 low to power up ML6692 and GP2 high to power up                   * Drive GP1 low to power up ML6692 and GP2 high to power up
                  * the 10MHz chip.  XXX What chip is that?  The phy?                   * the 10MHz chip.  XXX What chip is that?  The phy?
                  */                   */
                 bus_space_write_1(bst, bsh, offset + GP0,                  bus_space_write_1(bst, bsh, GP0, GP1_OUT | GP2_OUT | GP2_WR);
                     GP1_OUT | GP2_OUT | GP2_WR);  
         }          }
         DELAY(500000);          tsleep(&xi_full_reset, PWAIT, "xirst3", hz * 500 / 1000);
   
         /* Get revision information.  XXX Symbolic constants. */          /* Get revision information.  XXX Symbolic constants. */
         sc->sc_rev = bus_space_read_1(bst, bsh, offset + BV) &          sc->sc_rev = bus_space_read_1(bst, bsh, BV) &
             ((sc->sc_chipset >= XI_CHIPSET_MOHAWK) ? 0x70 : 0x30) >> 4;              ((sc->sc_chipset >= XI_CHIPSET_MOHAWK) ? 0x70 : 0x30) >> 4;
         DPRINTF(XID_CONFIG, ("xi: rev=%02x\n", sc->sc_rev));          DPRINTF(XID_CONFIG, ("xi: rev=%02x\n", sc->sc_rev));
   
Line 1245  xi_full_reset(sc)
Line 1220  xi_full_reset(sc)
                  * XXX I have no idea what this really does, it is from the                   * XXX I have no idea what this really does, it is from the
                  * Linux driver.                   * Linux driver.
                  */                   */
                 bus_space_write_1(bst, bsh, offset + GP0, GP1_OUT);                  bus_space_write_1(bst, bsh, GP0, GP1_OUT);
         }          }
         DELAY(40000);          tsleep(&xi_full_reset, PWAIT, "xirst4", hz * 40 / 1000);
   
         /*          /*
          * Disable source insertion.           * Disable source insertion.
Line 1255  xi_full_reset(sc)
Line 1230  xi_full_reset(sc)
          */           */
         if (sc->sc_chipset < XI_CHIPSET_DINGO) {          if (sc->sc_chipset < XI_CHIPSET_DINGO) {
                 PAGE(sc, 0x42);                  PAGE(sc, 0x42);
                 bus_space_write_1(bst, bsh, offset + SWC0, 0x20);                  bus_space_write_1(bst, bsh, SWC0, 0x20);
         }          }
   
         /* Set the local memory dividing line. */          /* Set the local memory dividing line. */
         if (sc->sc_rev != 1) {          if (sc->sc_rev != 1) {
                 PAGE(sc, 2);                  PAGE(sc, 2);
                 /* XXX Symbolic constant preferrable. */                  /* XXX Symbolic constant preferrable. */
                 bus_space_write_2(bst, bsh, offset + RBS0, 0x2000);                  bus_space_write_2(bst, bsh, RBS0, 0x2000);
         }          }
   
         /*          /*
Line 1270  xi_full_reset(sc)
Line 1245  xi_full_reset(sc)
          * we hardwire it correctly.           * we hardwire it correctly.
          */           */
         PAGE(sc, 0);          PAGE(sc, 0);
         bus_space_write_2(bst, bsh, offset + DO0, DO_CHG_OFFSET);          bus_space_write_2(bst, bsh, DO0, DO_CHG_OFFSET);
   
         /* Setup ethernet MAC registers. XXX Symbolic constants. */          /* Setup ethernet MAC registers. XXX Symbolic constants. */
         PAGE(sc, 0x40);          PAGE(sc, 0x40);
         bus_space_write_1(bst, bsh, offset + RX0MSK,          bus_space_write_1(bst, bsh, RX0MSK,
             PKT_TOO_LONG | CRC_ERR | RX_OVERRUN | RX_ABORT | RX_OK);              PKT_TOO_LONG | CRC_ERR | RX_OVERRUN | RX_ABORT | RX_OK);
         bus_space_write_1(bst, bsh, offset + TX0MSK,          bus_space_write_1(bst, bsh, TX0MSK,
             CARRIER_LOST | EXCESSIVE_COLL | TX_UNDERRUN | LATE_COLLISION |              CARRIER_LOST | EXCESSIVE_COLL | TX_UNDERRUN | LATE_COLLISION |
             SQE | TX_ABORT | TX_OK);              SQE | TX_ABORT | TX_OK);
         if (sc->sc_chipset < XI_CHIPSET_DINGO)          if (sc->sc_chipset < XI_CHIPSET_DINGO)
                 /* XXX From Linux, dunno what 0xb0 means. */                  /* XXX From Linux, dunno what 0xb0 means. */
                 bus_space_write_1(bst, bsh, offset + TX1MSK, 0xb0);                  bus_space_write_1(bst, bsh, TX1MSK, 0xb0);
         bus_space_write_1(bst, bsh, offset + RXST0, 0);          bus_space_write_1(bst, bsh, RXST0, 0);
         bus_space_write_1(bst, bsh, offset + TXST0, 0);          bus_space_write_1(bst, bsh, TXST0, 0);
         bus_space_write_1(bst, bsh, offset + TXST1, 0);          bus_space_write_1(bst, bsh, TXST1, 0);
   
         PAGE(sc, 2);          PAGE(sc, 2);
   
Line 1292  xi_full_reset(sc)
Line 1267  xi_full_reset(sc)
         x = 0;          x = 0;
         if (LIST_FIRST(&sc->sc_mii.mii_phys))          if (LIST_FIRST(&sc->sc_mii.mii_phys))
                 x |= SELECT_MII;                  x |= SELECT_MII;
         bus_space_write_1(bst, bsh, offset + MSR, x);          bus_space_write_1(bst, bsh, MSR, x);
         DELAY(20000);          tsleep(&xi_full_reset, PWAIT, "xirst5", hz * 20 / 1000);
   
         /* Configure the LED registers. */          /* Configure the LED registers. */
         /* XXX This is not good for 10base2. */          /* XXX This is not good for 10base2. */
         bus_space_write_1(bst, bsh, offset + LED,          bus_space_write_1(bst, bsh, LED,
             (LED_TX_ACT << LED1_SHIFT) | (LED_10MB_LINK << LED0_SHIFT));              (LED_TX_ACT << LED1_SHIFT) | (LED_10MB_LINK << LED0_SHIFT));
         if (sc->sc_chipset >= XI_CHIPSET_DINGO)          if (sc->sc_chipset >= XI_CHIPSET_DINGO)
                 bus_space_write_1(bst, bsh, offset + LED3,                  bus_space_write_1(bst, bsh, LED3, LED_100MB_LINK << LED3_SHIFT);
                     LED_100MB_LINK << LED3_SHIFT);  
   
         /*          /*
          * The Linux driver says this:           * The Linux driver says this:

Legend:
Removed from v.1.31.2.2  
changed lines
  Added in v.1.31.2.3

CVSweb <webmaster@jp.NetBSD.org>