Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ic Add support for the SMC91C111 chip, with its inte...



details:   https://anonhg.NetBSD.org/src/rev/6c612945c3e0
branches:  trunk
changeset: 546440:6c612945c3e0
user:      scw <scw%NetBSD.org@localhost>
date:      Tue Apr 29 08:47:29 2003 +0000

description:
Add support for the SMC91C111 chip, with its internal PHY.

diffstat:

 sys/dev/ic/smc91cxx.c    |  69 +++++++++++++++++++++++++++++++++++++++++------
 sys/dev/ic/smc91cxxreg.h |  28 ++++++++++++++++++-
 sys/dev/ic/smc91cxxvar.h |   3 +-
 3 files changed, 88 insertions(+), 12 deletions(-)

diffs (224 lines):

diff -r b0b1780611f9 -r 6c612945c3e0 sys/dev/ic/smc91cxx.c
--- a/sys/dev/ic/smc91cxx.c     Tue Apr 29 07:45:23 2003 +0000
+++ b/sys/dev/ic/smc91cxx.c     Tue Apr 29 08:47:29 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: smc91cxx.c,v 1.44 2002/10/22 00:01:57 fair Exp $       */
+/*     $NetBSD: smc91cxx.c,v 1.45 2003/04/29 08:47:29 scw Exp $        */
 
 /*-
  * Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -78,7 +78,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: smc91cxx.c,v 1.44 2002/10/22 00:01:57 fair Exp $");
+__KERNEL_RCSID(0, "$NetBSD: smc91cxx.c,v 1.45 2003/04/29 08:47:29 scw Exp $");
 
 #include "opt_inet.h"
 #include "opt_ccitt.h"
@@ -165,7 +165,7 @@
        NULL,                           /* 6 */
        "SMC91C100",                    /* 7 */
        "SMC91C100FD",                  /* 8 */
-       NULL,                           /* 9 */
+       "SMC91C111",                    /* 9 */
        NULL,                           /* 10 */
        NULL,                           /* 11 */
        NULL,                           /* 12 */
@@ -245,7 +245,7 @@
        u_int32_t miicapabilities;
        u_int16_t tmp;
        u_int8_t enaddr[ETHER_ADDR_LEN];
-       int i, aui, mult, memsize;
+       int i, aui, mult, scale, memsize;
        char pbuf[9];
 
        /* Make sure the chip is stopped. */
@@ -268,10 +268,19 @@
        printf("revision %d, ", RR_REV(tmp));
 
        SMC_SELECT_BANK(sc, 0);
-       mult = MCR_MEM_MULT(bus_space_read_2(bst, bsh, MEM_CFG_REG_W));
+       switch (sc->sc_chipid) {
+       default:
+               mult = MCR_MEM_MULT(bus_space_read_2(bst, bsh, MEM_CFG_REG_W));
+               scale = MIR_SCALE_91C9x;
+               break;
+
+       case CHIP_91C111:
+               mult = MIR_MULT_91C111;
+               scale = MIR_SCALE_91C111;
+       }
        memsize = bus_space_read_2(bst, bsh, MEM_INFO_REG_W) & MIR_TOTAL_MASK;
        if (memsize == 255) memsize++;
-       memsize *= 256 * mult;
+       memsize *= scale * mult;
 
        format_bytes(pbuf, sizeof(pbuf), memsize);
        printf("buffer size: %s\n", pbuf);
@@ -325,8 +334,15 @@
                 */
                miicapabilities &= ~(BMSR_100TXFDX | BMSR_10TFDX);
        case CHIP_91100FD:
+       case CHIP_91C111:
                if (tmp & CR_MII_SELECT) {
-                       printf("default media MII\n");
+                       printf("default media MII");
+                       if (sc->sc_chipid == CHIP_91C111) {
+                               printf(" (%s PHY)\n", (tmp & CR_AUI_SELECT) ?
+                                   "external" : "internal");
+                               sc->sc_internal_phy = !(tmp & CR_AUI_SELECT);
+                       } else
+                               printf("\n");
                        mii_attach(&sc->sc_dev, &sc->sc_mii, miicapabilities,
                            MII_PHY_ANY, MII_OFFSET_ANY, 0);
                        if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
@@ -340,6 +356,14 @@
                        }
                        sc->sc_flags |= SMC_FLAGS_HAS_MII;
                        break;
+               } else
+               if (sc->sc_chipid == CHIP_91C111) {
+                       /*
+                        * XXX: Should bring it out of low-power mode
+                        */
+                       printf("EPH interface in low power mode\n");
+                       sc->sc_internal_phy = 0;
+                       return;
                }
                /*FALLTHROUGH*/
        default:
@@ -511,6 +535,19 @@
        bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 0);
 
        /*
+        * On the 91c111, enable auto-negotiation, and set the LED
+        * status pins to something sane.
+        * XXX: Should be some way for MD code to decide the latter.
+        */
+       SMC_SELECT_BANK(sc, 0);
+       if (sc->sc_chipid == CHIP_91C111) {
+               bus_space_write_2(bst, bsh, RX_PHY_CONTROL_REG_W,
+                   RPC_ANEG |
+                   (RPC_LS_LINK_DETECT << RPC_LSA_SHIFT) |
+                   (RPC_LS_TXRX << RPC_LSB_SHIFT));
+       }
+
+       /*
         * Set current media.
         */
        smc91cxx_set_media(sc, sc->sc_mii.mii_media.ifm_cur->ifm_media);
@@ -551,8 +588,14 @@
         */
        SMC_SELECT_BANK(sc, 2);
 
-       bus_space_write_1(bst, bsh, INTR_MASK_REG_B,
-           IM_EPH_INT | IM_RX_OVRN_INT | IM_RCV_INT | IM_TX_INT);
+       if (sc->sc_chipid == CHIP_91C111 && sc->sc_internal_phy) {
+               bus_space_write_1(bst, bsh, INTR_MASK_REG_B,
+                   IM_EPH_INT | IM_RX_OVRN_INT |
+                   IM_RCV_INT | IM_TX_INT | IM_MD_INT);
+       } else {
+               bus_space_write_1(bst, bsh, INTR_MASK_REG_B,
+                   IM_EPH_INT | IM_RX_OVRN_INT | IM_RCV_INT | IM_TX_INT);
+       }
 
        /* Interface is now running, with no output active. */
        ifp->if_flags |= IFF_RUNNING;
@@ -996,6 +1039,14 @@
                ifp->if_timer = 0;
        }
 
+       if (sc->sc_chipid == CHIP_91C111 && sc->sc_internal_phy &&
+           (status & IM_MD_INT)) {
+               /*
+                * Internal PHY status change
+                */
+               mii_tick(&sc->sc_mii);
+       }
+
        /*
         * Other errors.  Reset the interface.
         */
diff -r b0b1780611f9 -r 6c612945c3e0 sys/dev/ic/smc91cxxreg.h
--- a/sys/dev/ic/smc91cxxreg.h  Tue Apr 29 07:45:23 2003 +0000
+++ b/sys/dev/ic/smc91cxxreg.h  Tue Apr 29 08:47:29 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: smc91cxxreg.h,v 1.4 2001/06/12 15:17:23 wiz Exp $      */
+/*     $NetBSD: smc91cxxreg.h,v 1.5 2003/04/29 08:47:30 scw Exp $      */
 
 /*
  * Copyright (c) 1996 Gardner Buchanan <gbuchanan%shl.com@localhost>
@@ -172,16 +172,38 @@
 
 #define        MIR_FREE_MASK   0xff00  /* Free memory pages available */
 #define        MIR_TOTAL_MASK  0x00ff  /* Total memory pages available */
+#define         MIR_MULT_91C111  1
+#define  MIR_SCALE_91C9x  256
+#define  MIR_SCALE_91C111 2048
 
 
 /*
  * Memory Configuration
  */
-#define        MEM_CFG_REG_W   0x0a
+#define        MEM_CFG_REG_W           0x0a
 
 #define        MCR_MEM_MULT(x) (((x)>>9)&7)    /* Memory size multiplier */
 #define        MCR_TXRSV_MASK  0x001f  /* Count of pages reserved for transmit */
 
+/*
+ * Receive/PHY Control Register (SM91C111 only)
+ */
+#define        RX_PHY_CONTROL_REG_W    0x0a    /* 91C111 only */
+
+#define        RPC_LSB_SHIFT           2       /* Shift for LED-B select bits */
+#define        RPC_LSA_SHIFT           5       /* Shift for LED-A select bits */
+#define        RPC_LS_MASK             0x7     /* LED Select mask */
+#define        RPC_LS_LINK_DETECT      0x0     /* 10/100 link detected */
+#define        RPC_LS_LINK_10MBPS      0x2     /* 10 MBPS link detected */
+#define        RPC_LS_FULL_DUPLEX      0x3     /* Full duplex operation */
+#define        RPC_LS_TXRX             0x4     /* Tx/Rx packet */
+#define        RPC_LS_LINK_100MBPS     0x5     /* 100 MBPS link detected */
+#define        RPC_LS_RX               0x6     /* Rx packet */
+#define        RPC_LS_TX               0x7     /* Tx packet */
+#define        RPC_ANEG                0x0800  /* Autonegotiate enable */
+#define        RPC_DPLX                0x1000  /* Duplex select (set = Full) */
+#define        RPC_SPEED               0x2000  /* Speed (set = 100mbps) */
+
 
 /*
  * Bank 0, Register 0x0c is unused in the SMC91C92
@@ -346,6 +368,7 @@
 #define        IM_RX_OVRN_INT  0x10    /* Receiver was overrun */
 #define        IM_EPH_INT      0x20    /* Misc. EPH conditions (see CONTROL_REG_W) */
 #define        IM_ERCV_INT     0x40    /* not on SMC9192 */
+#define        IM_MD_INT       0x80    /* SMC91C111 Internal PHY status change */
 
 
 /*
@@ -396,6 +419,7 @@
 #define        CHIP_9195       5
 #define        CHIP_91100      7
 #define        CHIP_91100FD    8
+#define        CHIP_91C111     9
 
 
 /*
diff -r b0b1780611f9 -r 6c612945c3e0 sys/dev/ic/smc91cxxvar.h
--- a/sys/dev/ic/smc91cxxvar.h  Tue Apr 29 07:45:23 2003 +0000
+++ b/sys/dev/ic/smc91cxxvar.h  Tue Apr 29 08:47:29 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: smc91cxxvar.h,v 1.10 2002/09/04 14:54:37 scw Exp $     */
+/*     $NetBSD: smc91cxxvar.h,v 1.11 2003/04/29 08:47:30 scw Exp $     */
 
 /*-
  * Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -63,6 +63,7 @@
 #define SMC_FLAGS_32BIT_READ   0x0008          /* reads are always 32-bits */
 
        u_int8_t        sc_chipid;
+       u_int8_t        sc_internal_phy;        /* 91C111 only */
 
 #if NRND > 0
        rndsource_element_t rnd_source;



Home | Main Index | Thread Index | Old Index