Add support for the SMC91C111 chip, with its internal PHY.
This commit is contained in:
parent
3f3b3242de
commit
f95724bd6b
|
@ -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.
|
* Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||||
|
@ -78,7 +78,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#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_inet.h"
|
||||||
#include "opt_ccitt.h"
|
#include "opt_ccitt.h"
|
||||||
|
@ -165,7 +165,7 @@ const char *smc91cxx_idstrs[] = {
|
||||||
NULL, /* 6 */
|
NULL, /* 6 */
|
||||||
"SMC91C100", /* 7 */
|
"SMC91C100", /* 7 */
|
||||||
"SMC91C100FD", /* 8 */
|
"SMC91C100FD", /* 8 */
|
||||||
NULL, /* 9 */
|
"SMC91C111", /* 9 */
|
||||||
NULL, /* 10 */
|
NULL, /* 10 */
|
||||||
NULL, /* 11 */
|
NULL, /* 11 */
|
||||||
NULL, /* 12 */
|
NULL, /* 12 */
|
||||||
|
@ -245,7 +245,7 @@ smc91cxx_attach(sc, myea)
|
||||||
u_int32_t miicapabilities;
|
u_int32_t miicapabilities;
|
||||||
u_int16_t tmp;
|
u_int16_t tmp;
|
||||||
u_int8_t enaddr[ETHER_ADDR_LEN];
|
u_int8_t enaddr[ETHER_ADDR_LEN];
|
||||||
int i, aui, mult, memsize;
|
int i, aui, mult, scale, memsize;
|
||||||
char pbuf[9];
|
char pbuf[9];
|
||||||
|
|
||||||
/* Make sure the chip is stopped. */
|
/* Make sure the chip is stopped. */
|
||||||
|
@ -268,10 +268,19 @@ smc91cxx_attach(sc, myea)
|
||||||
printf("revision %d, ", RR_REV(tmp));
|
printf("revision %d, ", RR_REV(tmp));
|
||||||
|
|
||||||
SMC_SELECT_BANK(sc, 0);
|
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;
|
memsize = bus_space_read_2(bst, bsh, MEM_INFO_REG_W) & MIR_TOTAL_MASK;
|
||||||
if (memsize == 255) memsize++;
|
if (memsize == 255) memsize++;
|
||||||
memsize *= 256 * mult;
|
memsize *= scale * mult;
|
||||||
|
|
||||||
format_bytes(pbuf, sizeof(pbuf), memsize);
|
format_bytes(pbuf, sizeof(pbuf), memsize);
|
||||||
printf("buffer size: %s\n", pbuf);
|
printf("buffer size: %s\n", pbuf);
|
||||||
|
@ -325,8 +334,15 @@ smc91cxx_attach(sc, myea)
|
||||||
*/
|
*/
|
||||||
miicapabilities &= ~(BMSR_100TXFDX | BMSR_10TFDX);
|
miicapabilities &= ~(BMSR_100TXFDX | BMSR_10TFDX);
|
||||||
case CHIP_91100FD:
|
case CHIP_91100FD:
|
||||||
|
case CHIP_91C111:
|
||||||
if (tmp & CR_MII_SELECT) {
|
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_attach(&sc->sc_dev, &sc->sc_mii, miicapabilities,
|
||||||
MII_PHY_ANY, MII_OFFSET_ANY, 0);
|
MII_PHY_ANY, MII_OFFSET_ANY, 0);
|
||||||
if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
|
if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
|
||||||
|
@ -340,6 +356,14 @@ smc91cxx_attach(sc, myea)
|
||||||
}
|
}
|
||||||
sc->sc_flags |= SMC_FLAGS_HAS_MII;
|
sc->sc_flags |= SMC_FLAGS_HAS_MII;
|
||||||
break;
|
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*/
|
/*FALLTHROUGH*/
|
||||||
default:
|
default:
|
||||||
|
@ -510,6 +534,19 @@ smc91cxx_init(sc)
|
||||||
*/
|
*/
|
||||||
bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 0);
|
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.
|
* Set current media.
|
||||||
*/
|
*/
|
||||||
|
@ -551,8 +588,14 @@ smc91cxx_init(sc)
|
||||||
*/
|
*/
|
||||||
SMC_SELECT_BANK(sc, 2);
|
SMC_SELECT_BANK(sc, 2);
|
||||||
|
|
||||||
bus_space_write_1(bst, bsh, INTR_MASK_REG_B,
|
if (sc->sc_chipid == CHIP_91C111 && sc->sc_internal_phy) {
|
||||||
IM_EPH_INT | IM_RX_OVRN_INT | IM_RCV_INT | IM_TX_INT);
|
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. */
|
/* Interface is now running, with no output active. */
|
||||||
ifp->if_flags |= IFF_RUNNING;
|
ifp->if_flags |= IFF_RUNNING;
|
||||||
|
@ -996,6 +1039,14 @@ smc91cxx_intr(arg)
|
||||||
ifp->if_timer = 0;
|
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.
|
* Other errors. Reset the interface.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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>
|
* Copyright (c) 1996 Gardner Buchanan <gbuchanan@shl.com>
|
||||||
|
@ -172,16 +172,38 @@
|
||||||
|
|
||||||
#define MIR_FREE_MASK 0xff00 /* Free memory pages available */
|
#define MIR_FREE_MASK 0xff00 /* Free memory pages available */
|
||||||
#define MIR_TOTAL_MASK 0x00ff /* Total 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
|
* 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_MEM_MULT(x) (((x)>>9)&7) /* Memory size multiplier */
|
||||||
#define MCR_TXRSV_MASK 0x001f /* Count of pages reserved for transmit */
|
#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
|
* Bank 0, Register 0x0c is unused in the SMC91C92
|
||||||
|
@ -346,6 +368,7 @@
|
||||||
#define IM_RX_OVRN_INT 0x10 /* Receiver was overrun */
|
#define IM_RX_OVRN_INT 0x10 /* Receiver was overrun */
|
||||||
#define IM_EPH_INT 0x20 /* Misc. EPH conditions (see CONTROL_REG_W) */
|
#define IM_EPH_INT 0x20 /* Misc. EPH conditions (see CONTROL_REG_W) */
|
||||||
#define IM_ERCV_INT 0x40 /* not on SMC9192 */
|
#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_9195 5
|
||||||
#define CHIP_91100 7
|
#define CHIP_91100 7
|
||||||
#define CHIP_91100FD 8
|
#define CHIP_91100FD 8
|
||||||
|
#define CHIP_91C111 9
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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.
|
* Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||||
|
@ -63,6 +63,7 @@ struct smc91cxx_softc {
|
||||||
#define SMC_FLAGS_32BIT_READ 0x0008 /* reads are always 32-bits */
|
#define SMC_FLAGS_32BIT_READ 0x0008 /* reads are always 32-bits */
|
||||||
|
|
||||||
u_int8_t sc_chipid;
|
u_int8_t sc_chipid;
|
||||||
|
u_int8_t sc_internal_phy; /* 91C111 only */
|
||||||
|
|
||||||
#if NRND > 0
|
#if NRND > 0
|
||||||
rndsource_element_t rnd_source;
|
rndsource_element_t rnd_source;
|
||||||
|
|
Loading…
Reference in New Issue