Subject: kern/12331: LMC1200P
To: None <gnats-bugs@gnats.netbsd.org>
From: None <hal@vailsys.com>
List: netbsd-bugs
Date: 03/05/2001 02:37:09
>Number:         12331
>Category:       kern
>Synopsis:       lmc driver does not recognize LMC1200P
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Mar 05 00:38:00 PST 2001
>Closed-Date:
>Last-Modified:
>Originator:     Hal Snyder
>Release:        NetBSD-1.5 release, 2000-11-19
>Organization:
Vail Systems
>Environment:
System:NetBSD 1.5 (GENERIC) #1: Sun Nov 19 21:42:11 MET 2000
    fvdl@sushi:/work/trees/netbsd-1-5/sys/arch/i386/compile/GENERIC
>Description:
The LMC1200P is the fourth in a series of PCI WAN cards made
by SBE (sbei.com), formerly Lan Media Corp. The lmc driver in NetBSD-1.5
does not recognize the card, misidentifying it as follows in dmesg:

de0 at pci0 dev 19 function 0: can't read ENET ROM (why=-4) (76130600000000000000000000000000af0000000060990021de000000000000)
de0: 21140A [10-100Mb/s] pass 2.2
de0: address unknown

>How-To-Repeat:
Install LMC1200P and boot NetBSD.
>Fix:
1. Chris Cappuccio merged SBE's latest Linux driver code into OpenBSD
(LMC/SBE has not updated their NetBSD driver support since 1999), and
fixed LED status indication.

2. SBE engineering staff supplied help getting the LMC1200P to send
packets. Unlike the earlier three cards by SBE, this one must have
transmit enable strobed on startup.

3. Changing bpfattach() DLT_ type allows tcpdump (from NetBSD CVS
2001-03-01) and filters to work with lmc devices, something previously
broken.

4. Replace the "lmcctl" utility with "lmccontrol", as per OpenBSD at
  http://www.openbsd.org/cgi-bin/cvsweb/src/sbin/lmccontrol/
It will compile once headers have been patched as below.

The patches below have been tested with LMC1200P and LMC5245P cards.

--- if_lmc.c.orig	Wed May  3 16:08:02 2000
+++ if_lmc.c	Fri Feb 16 01:32:19 2001
@@ -402,6 +402,36 @@
 
 	state = 0;
 
+	/*
+	 * Make sure the tx jabber and rx watchdog are off,
+	 * and the transmit and recieve processes are running.
+	 */
+	LMC_CSR_WRITE (sc, csr_15, 0x00000011);
+	sc->lmc_cmdmode |= TULIP_CMD_TXRUN | TULIP_CMD_RXRUN;
+	LMC_CSR_WRITE (sc, csr_command, sc->lmc_cmdmode);
+
+	/* Is the transmit clock still available? */
+	ticks = LMC_CSR_READ (sc, csr_gp_timer);
+	ticks = 0x0000ffff - (ticks & 0x0000ffff);
+
+	if (ticks == 0)
+	{
+		/* no clock found ? */
+		if (sc->tx_clockState != 0)
+		{
+			sc->tx_clockState = 0;
+			if (sc->lmc_cardtype == LMC_CARDTYPE_SSI)
+				lmc_led_on (sc, LMC_MII16_LED3); /* ON red */
+		}
+	else
+		if (sc->tx_clockState == 0)
+		{
+			sc->tx_clockState = 1;
+			if (sc->lmc_cardtype == LMC_CARDTYPE_SSI)
+				lmc_led_off (sc, LMC_MII16_LED3); /* OFF red */
+		}
+	}
+
 	link_status = sc->lmc_media->get_link_status(sc);
 	ostatus = ((sc->lmc_flags & LMC_MODEMOK) == LMC_MODEMOK);
 
@@ -409,27 +439,53 @@
 	 * hardware level link lost, but the interface is marked as up.
 	 * Mark it as down.
 	 */
-        if (link_status == 0 && ostatus) {
+        if (link_status == LMC_LINK_DOWN && ostatus) {
 		printf(LMC_PRINTF_FMT ": physical link down\n",
 		       LMC_PRINTF_ARGS);
 		sc->lmc_flags &= ~LMC_MODEMOK;
-		lmc_led_off(sc, LMC_MII16_LED1);
+		if (sc->lmc_cardtype == LMC_CARDTYPE_DS3 ||
+		    sc->lmc_cardtype == LMC_CARDTYPE_T1)
+			lmc_led_on (sc, LMC_DS3_LED3 | LMC_DS3_LED2);
+							/* turn on red LED */
+		else {
+			lmc_led_off (sc, LMC_MII16_LED1);
+			lmc_led_on (sc, LMC_MII16_LED0);
+			if (sc->lmc_timing == LMC_CTL_CLOCK_SOURCE_EXT)
+				lmc_led_on (sc, LMC_MII16_LED3);
+		}
+
 	}
 
 	/*
 	 * hardware link is up, but the interface is marked as down.
 	 * Bring it back up again.
 	 */
-	if (link_status != 0 && !ostatus) {
+	if (link_status != LMC_LINK_DOWN && !ostatus) {
 		printf(LMC_PRINTF_FMT ": physical link up\n",
 		       LMC_PRINTF_ARGS);
 		if (sc->lmc_flags & LMC_IFUP)
 			lmc_ifup(sc);
 		sc->lmc_flags |= LMC_MODEMOK;
-		lmc_led_on(sc, LMC_MII16_LED1); 
+		if (sc->lmc_cardtype == LMC_CARDTYPE_DS3 ||
+		    sc->lmc_cardtype == LMC_CARDTYPE_T1)
+		{
+			sc->lmc_miireg16 |= LMC_DS3_LED3;
+			lmc_led_off (sc, LMC_DS3_LED3);
+							/* turn off red LED */
+			lmc_led_on (sc, LMC_DS3_LED2);
+		} else {
+			lmc_led_on (sc, LMC_MII16_LED0 | LMC_MII16_LED1
+				    | LMC_MII16_LED2);
+			if (sc->lmc_timing != LMC_CTL_CLOCK_SOURCE_EXT)
+				lmc_led_off (sc, LMC_MII16_LED3);
+		}
+
 		return;
 	}
 
+	/* Call media specific watchdog functions */
+	sc->lmc_media->watchdog(sc);
+
 	/*
 	 * remember the timer value
 	 */
@@ -452,12 +508,19 @@
 	lmc_dec_reset(sc);
 	lmc_reset(sc);
 
-	sc->lmc_media->set_link_status(sc, 1);
+	sc->lmc_media->set_link_status(sc, LMC_LINK_UP);
 	sc->lmc_media->set_status(sc, NULL);
 
 	sc->lmc_flags |= LMC_IFUP;
 
-	lmc_led_on(sc, LMC_MII16_LED1);
+	/*
+	 * for DS3 & DS1 adapters light the green light, led2
+	 */
+	if (sc->lmc_cardtype == LMC_CARDTYPE_DS3 ||
+	    sc->lmc_cardtype == LMC_CARDTYPE_T1)
+		lmc_led_on (sc, LMC_MII16_LED2);
+	else
+		lmc_led_on (sc, LMC_MII16_LED0 | LMC_MII16_LED2);
 
 	/*
 	 * select what interrupts we want to get
@@ -490,8 +553,8 @@
 	sc->lmc_if.if_timer = 0;
 	sc->lmc_flags &= ~LMC_IFUP;
 
-	sc->lmc_media->set_link_status(sc, 0);
-	lmc_led_off(sc, LMC_MII16_LED1);
+	sc->lmc_media->set_link_status(sc, LMC_LINK_DOWN);
+	lmc_led_off(sc, LMC_MII16_LED_ALL);
 
 	lmc_dec_reset(sc);
 	lmc_reset(sc);
@@ -1136,7 +1199,10 @@
 		if (ifr->ifr_mtu > LMC_MTU) {
 			error = EINVAL;
 			goto out;
+		} else {
+                        ifp->if_mtu = ifr->ifr_mtu;
 		}
+		break;
 #endif
 	}
 
--- if_lmc_common.c.orig	Wed May  3 16:08:02 2000
+++ if_lmc_common.c	Fri Feb 16 01:35:56 2001
@@ -228,8 +228,7 @@
 	/*
 	 * busy wait for the chip to reset
 	 */
-	while ((LMC_CSR_READ(sc, csr_gp) & LMC_GEP_DP) == 0)
-		;
+	while ((LMC_CSR_READ(sc, csr_gp) & LMC_GEP_DP) == 0);
 
 	/*
 	 * Call media specific init routine
--- if_lmc_media.c.orig	Wed May  3 16:08:02 2000
+++ if_lmc_media.c	Fri Feb 23 18:54:21 2001
@@ -5,6 +5,8 @@
  * All rights reserved.  www.lanmedia.com
  *
  * This code is written by Michael Graff <graff@vix.com> for LMC.
+ * The code is derived from permitted modifications to software created
+ * by Matt Thomas (matt@3am-software.com).
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -163,6 +165,7 @@
 static int	lmc_ds3_get_link_status(lmc_softc_t * const);
 static void	lmc_ds3_set_crc_length(lmc_softc_t * const, int);
 static void	lmc_ds3_set_scram(lmc_softc_t * const, int);
+static void	lmc_ds3_watchdog(lmc_softc_t * const);
 
 static void	lmc_hssi_init(lmc_softc_t * const);
 static void	lmc_hssi_default(lmc_softc_t * const);
@@ -171,15 +174,26 @@
 static int	lmc_hssi_get_link_status(lmc_softc_t * const);
 static void	lmc_hssi_set_link_status(lmc_softc_t * const, int);
 static void	lmc_hssi_set_crc_length(lmc_softc_t * const, int);
+static void	lmc_hssi_watchdog(lmc_softc_t * const);
+
+static void     lmc_ssi_init(lmc_softc_t * const);
+static void     lmc_ssi_default(lmc_softc_t * const);
+static void     lmc_ssi_set_status(lmc_softc_t * const, lmc_ctl_t *);
+static void     lmc_ssi_set_clock(lmc_softc_t * const, int);
+static void     lmc_ssi_set_speed(lmc_softc_t * const, lmc_ctl_t *);
+static int      lmc_ssi_get_link_status(lmc_softc_t * const);
+static void     lmc_ssi_set_link_status(lmc_softc_t * const, int);
+static void     lmc_ssi_set_crc_length(lmc_softc_t * const, int);
+static void	lmc_ssi_watchdog(lmc_softc_t * const);
 
 static void	lmc_t1_init(lmc_softc_t * const);
 static void	lmc_t1_default(lmc_softc_t * const);
 static void	lmc_t1_set_status(lmc_softc_t * const, lmc_ctl_t *);
-static void	lmc_t1_set_clock(lmc_softc_t * const, int);
-static void	lmc_t1_set_speed(lmc_softc_t * const, lmc_ctl_t *);
 static int	lmc_t1_get_link_status(lmc_softc_t * const);
-static void	lmc_t1_set_link_status(lmc_softc_t * const, int);
+static void     lmc_t1_set_circuit_type(lmc_softc_t * const, int);
 static void	lmc_t1_set_crc_length(lmc_softc_t * const, int);
+static void	lmc_t1_set_clock(lmc_softc_t * const, int);
+static void	lmc_t1_watchdog(lmc_softc_t * const);
 
 static void	lmc_dummy_set_1(lmc_softc_t * const, int);
 static void	lmc_dummy_set2_1(lmc_softc_t * const, lmc_ctl_t *);
@@ -199,6 +213,8 @@
 	lmc_ds3_get_link_status,	/* get link status */
 	lmc_dummy_set_1,		/* set link status */
 	lmc_ds3_set_crc_length,		/* set CRC length */
+	lmc_dummy_set_1,		/* set T1 or E1 circuit type */
+	lmc_ds3_watchdog
 };
 
 lmc_media_t lmc_hssi_media = {
@@ -212,19 +228,38 @@
 	lmc_hssi_get_link_status,	/* get link status */
 	lmc_hssi_set_link_status,	/* set link status */
 	lmc_hssi_set_crc_length,	/* set CRC length */
+	lmc_dummy_set_1,		/* set T1 or E1 circuit type */
+	lmc_hssi_watchdog
+};
+
+lmc_media_t lmc_ssi_media = {
+	lmc_ssi_init,			/* special media init stuff */
+        lmc_ssi_default,		/* reset to default state */
+        lmc_ssi_set_status,		/* reset status to state provided */
+        lmc_ssi_set_clock,		/* set clock source */
+        lmc_ssi_set_speed,		/* set line speed */
+        lmc_dummy_set_1,		/* set cable length */
+        lmc_dummy_set_1,		/* set scrambler */
+        lmc_ssi_get_link_status,	/* get link status */
+        lmc_ssi_set_link_status,	/* set link status */
+        lmc_ssi_set_crc_length,		/* set CRC length */
+        lmc_dummy_set_1,		/* set T1 or E1 circuit type */
+	lmc_ssi_watchdog
 };
 
 lmc_media_t lmc_t1_media = {
 	lmc_t1_init,			/* special media init stuff */
 	lmc_t1_default,			/* reset to default state */
 	lmc_t1_set_status,		/* reset status to state provided */
-	lmc_t1_set_clock,		/* set clock source */
-	lmc_t1_set_speed,		/* set line speed */
+        lmc_t1_set_clock,		/* set clock source */
+        lmc_dummy_set2_1,		/* set line speed */
 	lmc_dummy_set_1,		/* set cable length */
 	lmc_dummy_set_1,		/* set scrambler */
 	lmc_t1_get_link_status,		/* get link status */
-	lmc_t1_set_link_status,		/* set link status */
+        lmc_dummy_set_1,		/* set link status */
 	lmc_t1_set_crc_length,		/* set CRC length */
+        lmc_t1_set_circuit_type,	/* set T1 or E1 circuit type */
+	lmc_t1_watchdog
 };
 
 static void
@@ -276,10 +311,13 @@
 	/*
 	 * check for change in clock source
 	 */
-	if (ctl->clock_source && !sc->ictl.clock_source)
+	if (ctl->clock_source && !sc->ictl.clock_source) {
 		sc->lmc_media->set_clock_source(sc, LMC_CTL_CLOCK_SOURCE_INT);
-	else if (!ctl->clock_source && sc->ictl.clock_source)
+		sc->lmc_timing = LMC_CTL_CLOCK_SOURCE_INT;
+	} else if (!ctl->clock_source && sc->ictl.clock_source) {
+		sc->lmc_timing = LMC_CTL_CLOCK_SOURCE_EXT;
 		sc->lmc_media->set_clock_source(sc, LMC_CTL_CLOCK_SOURCE_EXT);
+	}
 
 	lmc_set_protocol(sc, ctl);
 }
@@ -352,6 +390,23 @@
 	lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
 }
 
+static void
+lmc_hssi_watchdog (lmc_softc_t * const sc)
+{
+	/* HSSI is blank */
+}
+
+static void
+lmc_ds3_watchdog (lmc_softc_t * const sc)
+{
+	sc->lmc_miireg16 = lmc_mii_readreg (sc, 0, 16);
+	if (sc->lmc_miireg16 & 0x0018)
+	{
+		printf("%s: AIS Recieved\n", sc->lmc_xname);
+		lmc_led_on (sc, LMC_DS3_LED1 | LMC_DS3_LED2);
+	}
+}
+
 
 /*
  *  DS3 methods
@@ -503,11 +558,11 @@
 
 
 /*
- *  T1 methods
+ *  SSI methods
  */
 
 static void
-lmc_t1_init(lmc_softc_t * const sc)
+lmc_ssi_init(lmc_softc_t * const sc)
 {
 	u_int16_t mii17;
 	int cable;
@@ -516,21 +571,21 @@
 
 	mii17 = lmc_mii_readreg(sc, 0, 17);
 
-	cable = (mii17 & LMC_MII17_T1_CABLE_MASK) >> LMC_MII17_T1_CABLE_SHIFT;
+        cable = (mii17 & LMC_MII17_SSI_CABLE_MASK) >> LMC_MII17_SSI_CABLE_SHIFT;
 	sc->ictl.cable_type = cable;
 
-	lmc_gpio_mkoutput(sc, LMC_GEP_T1_TXCLOCK);
+        lmc_gpio_mkoutput(sc, LMC_GEP_SSI_TXCLOCK);
 }
 
 static void
-lmc_t1_default(lmc_softc_t * const sc)
+lmc_ssi_default(lmc_softc_t * const sc)
 {
 	sc->lmc_miireg16 = LMC_MII16_LED_ALL;
 
 	/*
 	 * make TXCLOCK always be an output
 	 */
-	lmc_gpio_mkoutput(sc, LMC_GEP_T1_TXCLOCK);
+        lmc_gpio_mkoutput(sc, LMC_GEP_SSI_TXCLOCK);
 
 	sc->lmc_media->set_link_status(sc, 0);
 	sc->lmc_media->set_clock_source(sc, LMC_CTL_CLOCK_SOURCE_EXT);
@@ -543,7 +598,7 @@
  * always reset the card if needed.
  */
 static void
-lmc_t1_set_status(lmc_softc_t * const sc, lmc_ctl_t *ctl)
+lmc_ssi_set_status(lmc_softc_t * const sc, lmc_ctl_t *ctl)
 {
 	if (ctl == NULL) {
 		sc->lmc_media->set_clock_source(sc, sc->ictl.clock_source);
@@ -557,11 +612,14 @@
 	 * check for change in clock source
 	 */
 	if (ctl->clock_source == LMC_CTL_CLOCK_SOURCE_INT
-	    && sc->ictl.clock_source == LMC_CTL_CLOCK_SOURCE_EXT)
+            && sc->ictl.clock_source == LMC_CTL_CLOCK_SOURCE_EXT) {
 		sc->lmc_media->set_clock_source(sc, LMC_CTL_CLOCK_SOURCE_INT);
-	else if (ctl->clock_source == LMC_CTL_CLOCK_SOURCE_EXT
-		 && sc->ictl.clock_source == LMC_CTL_CLOCK_SOURCE_INT)
+		sc->lmc_timing = LMC_CTL_CLOCK_SOURCE_INT;
+        } else if (ctl->clock_source == LMC_CTL_CLOCK_SOURCE_EXT
+                 && sc->ictl.clock_source == LMC_CTL_CLOCK_SOURCE_INT) {
 		sc->lmc_media->set_clock_source(sc, LMC_CTL_CLOCK_SOURCE_EXT);
+		sc->lmc_timing = LMC_CTL_CLOCK_SOURCE_EXT;
+	}
 
 	if (ctl->clock_rate != sc->ictl.clock_rate)
 		sc->lmc_media->set_speed(sc, ctl);
@@ -573,16 +631,16 @@
  * 1 == internal, 0 == external
  */
 static void
-lmc_t1_set_clock(lmc_softc_t * const sc, int ie)
+lmc_ssi_set_clock(lmc_softc_t * const sc, int ie)
 {
 	if (ie == LMC_CTL_CLOCK_SOURCE_EXT) {
-		sc->lmc_gpio &= ~(LMC_GEP_T1_TXCLOCK);
+                sc->lmc_gpio &= ~(LMC_GEP_SSI_TXCLOCK);
 		LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
 		sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_EXT;
 		printf(LMC_PRINTF_FMT ": clock external\n",
 		       LMC_PRINTF_ARGS);
 	} else {
-		sc->lmc_gpio |= LMC_GEP_T1_TXCLOCK;
+                sc->lmc_gpio |= LMC_GEP_SSI_TXCLOCK;
 		LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
 		sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_INT;
 		printf(LMC_PRINTF_FMT ": clock internal\n",
@@ -591,32 +649,38 @@
 }
 
 static void
-lmc_t1_set_speed(lmc_softc_t * const sc, lmc_ctl_t *ctl)
+lmc_ssi_set_speed(lmc_softc_t * const sc, lmc_ctl_t *ctl)
 {
 	lmc_ctl_t *ictl = &sc->ictl;
 	lmc_av9110_t *av;
 
+        /* original settings for clock rate of:
+         *  100 Khz (8,25,0,0,2) were incorrect
+         *  they should have been 80,125,1,3,3
+         *  There are 17 param combinations to produce this freq.
+         *  For 1.5 Mhz use 120,100,1,1,2 (226 param. combinations)
+         */
 	if (ctl == NULL) {
-		av = &ictl->cardspec.t1;
-		ictl->clock_rate = 100000;
+                av = &ictl->cardspec.ssi;
+                ictl->clock_rate = 1500000;
 		av->f = ictl->clock_rate;
-		av->n = 8;
-		av->m = 25;
-		av->v = 0;
-		av->x = 0;
+                av->n = 120;
+                av->m = 100;
+                av->v = 1;
+                av->x = 1;
 		av->r = 2;
 
 		write_av9110(sc, av->n, av->m, av->v, av->x, av->r);
 		return;
 	}
 
-	av = &ctl->cardspec.t1;
+        av = &ctl->cardspec.ssi;
 
 	if (av->f == 0)
 		return;
 
 	ictl->clock_rate = av->f;  /* really, this is the rate we are */
-	ictl->cardspec.t1 = *av;
+        ictl->cardspec.ssi = *av;
 
 	write_av9110(sc, av->n, av->m, av->v, av->x, av->r);
 }
@@ -626,7 +690,7 @@
  * 0 == link is down, 1 == link is up.
  */
 static int
-lmc_t1_get_link_status(lmc_softc_t * const sc)
+lmc_ssi_get_link_status(lmc_softc_t * const sc)
 {
 	u_int16_t link_status;
 
@@ -639,54 +703,67 @@
 	 *	DSR _must_ be asserted.
 	 *	One of DCD or CTS must be asserted.
 	 */
+
+#ifdef CONFIG_LMC_IGNORE_HARDWARE_HANDSHAKE
+        link_status = LMC_CSR_READ(sc, csr_gp_timer);
+        link_status = 0x0000ffff - ( link_status & 0x0000ffff);
+
+        return( link_status );
+#else  
+
 	link_status = lmc_mii_readreg(sc, 0, 16);
 
-	if ((link_status & LMC_MII16_T1_DSR) == 0)
+        if ((link_status & LMC_MII16_SSI_DSR) == 0)
 		return (0);
 
-	if ((link_status & (LMC_MII16_T1_CTS | LMC_MII16_T1_DCD)) == 0)
+        if ((link_status & (LMC_MII16_SSI_CTS | LMC_MII16_SSI_DCD)) == 0)
 		return (0);
 
 	return (1);
+#endif
 }
 
 static void
-lmc_t1_set_link_status(lmc_softc_t * const sc, int state)
+lmc_ssi_set_link_status(lmc_softc_t * const sc, int state)
 {
 	if (state) {
-		sc->lmc_miireg16 |= (LMC_MII16_T1_DTR | LMC_MII16_T1_RTS);
+                sc->lmc_miireg16 |= (LMC_MII16_SSI_DTR | LMC_MII16_SSI_RTS);
 		printf(LMC_PRINTF_FMT ": asserting DTR and RTS\n",
 		       LMC_PRINTF_ARGS);
 	} else {
-		sc->lmc_miireg16 &= ~(LMC_MII16_T1_DTR | LMC_MII16_T1_RTS);
+                sc->lmc_miireg16 &= ~(LMC_MII16_SSI_DTR | LMC_MII16_SSI_RTS);
 		printf(LMC_PRINTF_FMT ": deasserting DTR and RTS\n",
 		       LMC_PRINTF_ARGS);
 	}
 
 	lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
+
 }
 
 /*
  * 0 == 16bit, 1 == 32bit
  */
 static void
-lmc_t1_set_crc_length(lmc_softc_t * const sc, int state)
+lmc_ssi_set_crc_length(lmc_softc_t * const sc, int state)
 {
 	if (state == LMC_CTL_CRC_LENGTH_32) {
 		/* 32 bit */
-		sc->lmc_miireg16 |= LMC_MII16_T1_CRC;
+                sc->lmc_miireg16 |= LMC_MII16_SSI_CRC;
 		sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_32;
+                sc->lmc_crcSize = LMC_CTL_CRC_BYTESIZE_4;
+
 	} else {
 		/* 16 bit */
-		sc->lmc_miireg16 &= ~LMC_MII16_T1_CRC;
+                sc->lmc_miireg16 &= ~LMC_MII16_SSI_CRC;
 		sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_16;
+                sc->lmc_crcSize = LMC_CTL_CRC_BYTESIZE_2;
 	}
 
 	lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
 }
 
 /*
- * These are bits to program the T1 frequency generator
+ * These are bits to program the ssi frequency generator
  */
 static inline void
 write_av9110_bit(lmc_softc_t *sc, int c)
@@ -726,7 +803,7 @@
 	       n, m, v, x, r);
 #endif
 
-	sc->lmc_gpio |= LMC_GEP_T1_GENERATOR;
+        sc->lmc_gpio |= LMC_GEP_SSI_GENERATOR;
 	sc->lmc_gpio &= ~(LMC_GEP_SERIAL | LMC_GEP_SERIALCLK);
 	LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
 
@@ -735,9 +812,9 @@
 	 * as outputs.
 	 */
 	lmc_gpio_mkoutput(sc, (LMC_GEP_SERIAL | LMC_GEP_SERIALCLK
-			       | LMC_GEP_T1_GENERATOR));
+                               | LMC_GEP_SSI_GENERATOR));
 
-	sc->lmc_gpio &= ~(LMC_GEP_T1_GENERATOR);
+        sc->lmc_gpio &= ~(LMC_GEP_SSI_GENERATOR);
 	LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
 
 	/*
@@ -761,8 +838,337 @@
 	 */
 	lmc_gpio_mkinput(sc,
 			 (LMC_GEP_SERIAL | LMC_GEP_SERIALCLK
-			  | LMC_GEP_T1_GENERATOR));
+                          | LMC_GEP_SSI_GENERATOR));
 }
+
+static void
+lmc_ssi_watchdog (lmc_softc_t * const sc)
+{
+	u_int16_t mii17;
+	struct ssicsr2 {
+		unsigned short dtr:1, dsr:1, rts:1, cable:3, crc:1, led0:1,
+		led1:1, led2:1, led3:1, fifo:1, ll:1, rl:1, tm:1, loop:1;
+	};
+	struct ssicsr2 *ssicsr;
+	mii17 = lmc_mii_readreg (sc, 0, 17);
+	ssicsr = (struct ssicsr2 *) &mii17;
+	if (ssicsr->cable == 7) {
+		lmc_led_off (sc, LMC_MII16_LED2);
+	}
+	else {
+		lmc_led_on (sc, LMC_MII16_LED2);
+	}
+
+}
+
+/*
+ *  T1 methods
+ */
+
+/*
+ * The framer regs are multiplexed through MII regs 17 & 18
+ *  write the register address to MII reg 17 and the *  data to MII reg 18. */
+static void lmc_t1_write(lmc_softc_t * const sc, int a, int d)
+{
+        lmc_mii_writereg(sc, 0, 17, a);        
+	lmc_mii_writereg(sc, 0, 18, d);
+}
+
+static int lmc_t1_read(lmc_softc_t * const sc, int a)
+{
+	lmc_mii_writereg(sc, 0, 17, a);
+	return lmc_mii_readreg(sc, 0, 18);
+}
+
+
+static void
+   lmc_t1_init(lmc_softc_t * const sc)
+{
+        u_int16_t mii16;
+        int     i;
+
+        sc->ictl.cardtype = LMC_CTL_CARDTYPE_LMC1200;
+        mii16 = lmc_mii_readreg(sc, 0, 16);
+
+	mii16 &= ~LMC_MII16_T1_XOE;
+	lmc_mii_writereg (sc, 0, 16, mii16);
+	sc->lmc_miireg16 = mii16;
+
+        /* reset 8370 */
+        mii16 &= ~LMC_MII16_T1_RST;
+        lmc_mii_writereg(sc, 0, 16, mii16 | LMC_MII16_T1_RST);
+        lmc_mii_writereg(sc, 0, 16, mii16);
+
+        /* set T1 or E1 line impedance */
+        /* mii16 &= ~LMC_MII16_T1_Z; */
+        mii16 |= LMC_MII16_T1_Z;
+        lmc_mii_writereg(sc, 0, 16, mii16);
+
+	/* Standard LMC1200 init code */
+        lmc_t1_write(sc, 0x01, 0x1B);  /* CR0     - primary control          */
+        lmc_t1_write(sc, 0x02, 0x42);  /* JAT_CR  - jitter atten config      */
+        lmc_t1_write(sc, 0x14, 0x00);  /* LOOP    - loopback config          */
+        lmc_t1_write(sc, 0x15, 0x00);  /* DL3_TS  - xtrnl datalink timeslot  */
+        lmc_t1_write(sc, 0x18, 0xFF);  /* PIO     - programmable I/O         */
+        lmc_t1_write(sc, 0x19, 0x30);  /* POE     - programmable OE          */
+        lmc_t1_write(sc, 0x1A, 0x0F);  /* CMUX    - clock input mux          */
+        lmc_t1_write(sc, 0x20, 0x41);  /* LIU_CR  - RX LIU config            */
+        lmc_t1_write(sc, 0x22, 0x76);  /* RLIU_CR - RX LIU config            */
+        lmc_t1_write(sc, 0x40, 0x03);  /* RCR0    - RX config                */
+        lmc_t1_write(sc, 0x45, 0x00);  /* RALM    - RX alarm config          */
+        lmc_t1_write(sc, 0x46, 0x05);  /* LATCH   - RX alarm/err/cntr latch  */
+        lmc_t1_write(sc, 0x68, 0x40);  /* TLIU_CR - TX LIU config            */
+        lmc_t1_write(sc, 0x70, 0x0D);  /* TCR0    - TX framer config         */
+        lmc_t1_write(sc, 0x71, 0x05);  /* TCR1    - TX config                */
+        lmc_t1_write(sc, 0x72, 0x0B);  /* TFRM    - TX frame format          */
+        lmc_t1_write(sc, 0x73, 0x00);  /* TERROR  - TX error insert          */
+        lmc_t1_write(sc, 0x74, 0x00);  /* TMAN    - TX manual Sa/FEBE config */
+        lmc_t1_write(sc, 0x75, 0x00);  /* TALM    - TX alarm signal config   */
+        lmc_t1_write(sc, 0x76, 0x00);  /* TPATT   - TX test pattern config   */
+        lmc_t1_write(sc, 0x77, 0x00);  /* TLB     - TX inband loopback confg */
+        lmc_t1_write(sc, 0x90, 0x05);  /* CLAD_CR - clock rate adapter confg */
+        lmc_t1_write(sc, 0x91, 0x05);  /* CSEL    - clad freq sel            */
+        lmc_t1_write(sc, 0xA6, 0x00);  /* DL1_CTL - DL1 control              */
+        lmc_t1_write(sc, 0xB1, 0x00);  /* DL2_CTL - DL2 control              */
+        lmc_t1_write(sc, 0xD0, 0x47);  /* SBI_CR  - sys bus iface config     */
+        lmc_t1_write(sc, 0xD1, 0x70);  /* RSB_CR  - RX sys bus config        */
+        lmc_t1_write(sc, 0xD4, 0x30);  /* TSB_CR  - TX sys bus config        */
+        for (i=0; i<32; i++)
+        {
+                lmc_t1_write(sc, 0x0E0+i, 0x00); /*SBCn sysbus perchannel ctl */
+                lmc_t1_write(sc, 0x100+i, 0x00); /* TPCn - TX per-channel ctl */
+                lmc_t1_write(sc, 0x180+i, 0x00); /* RPCn - RX per-channel ctl */
+        }
+        for (i=1; i<25; i++)
+	{                lmc_t1_write(sc, 0x0E0+i, 0x0D);
+					/* SBCn - sys bus per-channel ctl    */
+	}
+
+	mii16 |= LMC_MII16_T1_XOE;
+	lmc_mii_writereg (sc, 0, 16, mii16);
+	sc->lmc_miireg16 = mii16; 
+}
+
+static void   lmc_t1_default(lmc_softc_t * const sc)
+{
+        sc->lmc_miireg16 = LMC_MII16_LED_ALL;
+        sc->lmc_media->set_link_status(sc, LMC_LINK_DOWN);
+        sc->lmc_media->set_circuit_type(sc, LMC_CTL_CIRCUIT_TYPE_T1);
+        sc->lmc_media->set_crc_length(sc, LMC_CTL_CRC_LENGTH_16);
+}
+
+/*
+ * Given a user provided state, set ourselves up to match it.  This will
+ * always reset the card if needed.
+ */
+
+static void
+lmc_t1_set_status(lmc_softc_t * const sc, lmc_ctl_t *ctl){
+	if (ctl == NULL) {
+		sc->lmc_media->set_circuit_type(sc, sc->ictl.circuit_type);
+		lmc_set_protocol(sc, NULL);
+
+		return;
+	}
+
+        /*
+         * check for change in circuit type
+	 */
+
+	if (ctl->circuit_type == LMC_CTL_CIRCUIT_TYPE_T1
+		&& sc->ictl.circuit_type == LMC_CTL_CIRCUIT_TYPE_E1)
+		sc->lmc_media->set_circuit_type(sc,LMC_CTL_CIRCUIT_TYPE_E1 );
+	else if (ctl->circuit_type == LMC_CTL_CIRCUIT_TYPE_E1
+		&& sc->ictl.circuit_type == LMC_CTL_CIRCUIT_TYPE_T1)
+		sc->lmc_media->set_circuit_type(sc, LMC_CTL_CIRCUIT_TYPE_T1);
+	lmc_set_protocol(sc, ctl);
+}
+
+/*
+ * return hardware link status.
+ * 0 == link is down, 1 == link is up.
+ */
+
+static int
+lmc_t1_get_link_status(lmc_softc_t * const sc){
+	u_int16_t link_status;
+	lmc_mii_writereg(sc, 0, 17, T1FRAMER_ALARM1_STATUS );
+	link_status = lmc_mii_readreg(sc, 0, 18);
+
+        /*
+	 * LMC 1200 LED definitions
+         * led0 yellow = far-end adapter is in Red alarm condition
+  	 * led1 blue = received an Alarm Indication signal (upstream failure)
+         * led2 Green = power to adapter, Gate Array loaded & driver attached
+         * led3 red = Loss of Signal (LOS) or out of frame (OOF) conditions
+	 * detected on T3 receive signal
+         */
+
+        /* detect a change in Blue alarm indication signal */
+
+        if( (sc->t1_alarm1_status & T1F_RAIS) != (link_status & T1F_RAIS) )
+        {
+                if( link_status & T1F_RAIS )
+                {                        /* turn on blue LED */
+                        printf(" link status: RAIS turn ON Blue %x\n", link_status ); /* DEBUG */
+                        lmc_led_on(sc, LMC_DS3_LED1);
+                }
+                else
+                {                        /* turn off blue LED */
+                        printf(" link status: RAIS turn OFF Blue %x\n", link_status ); /* DEBUG */
+			lmc_led_off(sc, LMC_DS3_LED1);
+                }       
+	}
+        /*
+	 * T1F_RYEL wiggles quite a bit,
+	 *  taking it out until I understand why -baz 6/22/99
+         */
+                /* Yellow alarm indication */
+                if( (sc->t1_alarm1_status &  T1F_RMYEL) !=
+                        (link_status & T1F_RMYEL) )
+                {
+		if( (link_status & (T1F_RYEL | T1F_RMYEL)) == 0 )
+                        {
+				/* turn off yellow LED */
+       		                printf(" link status: RYEL turn OFF Yellow %x\n", link_status ); /* DEBUG */
+                    	        lmc_led_off(sc, LMC_DS3_LED0);
+
+                        }
+                        else
+                        {
+                                /* turn on yellow LED */                         
+                                printf(" link status: RYEL turn ON Yellow %x\n", link_status ); /* DEBUG */
+                                lmc_led_on(sc, LMC_DS3_LED0);
+                        }
+                }
+
+
+        sc->t1_alarm1_status = link_status;
+
+        lmc_mii_writereg(sc, 0, 17, T1FRAMER_ALARM2_STATUS );
+        sc->t1_alarm2_status = lmc_mii_readreg(sc, 0, 18);
+
+        /* link status based upon T1 receive loss of frame or
+         * loss of signal - RED alarm indication */
+        if ((link_status & (T1F_RLOF | T1F_RLOS)) == 0)
+                return 1;
+        else
+                return 0;
+}
+
+/*
+ * 1 == T1 Circuit Type , 0 == E1 Circuit Type
+ */
+static void
+   lmc_t1_set_circuit_type(lmc_softc_t * const sc, int ie)
+{
+        if (ie == LMC_CTL_CIRCUIT_TYPE_T1)
+        {
+                sc->lmc_miireg16 |= LMC_MII16_T1_Z;
+                sc->ictl.circuit_type = LMC_CTL_CIRCUIT_TYPE_T1;
+        } else {                sc->lmc_miireg16 &= ~LMC_MII16_T1_Z;
+                sc->ictl.scrambler_onoff = LMC_CTL_CIRCUIT_TYPE_E1;
+        }
+        lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
+}
+
+/*
+ * 0 == 16bit, 1 == 32bit */
+static void
+   lmc_t1_set_crc_length(lmc_softc_t * const sc, int state)
+{
+        if (state == LMC_CTL_CRC_LENGTH_32) {
+                /* 32 bit */
+                sc->lmc_miireg16 |= LMC_MII16_T1_CRC;
+                sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_32;
+                sc->lmc_crcSize = LMC_CTL_CRC_BYTESIZE_4;
+
+        } else {
+                /* 16 bit */
+                sc->lmc_miireg16 &= ~LMC_MII16_T1_CRC;
+                sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_16;
+                sc->lmc_crcSize = LMC_CTL_CRC_BYTESIZE_2;
+
+        }
+
+        lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
+}
+
+/*
+ * 1 == internal, 0 == external
+ */
+static void
+lmc_t1_set_clock (lmc_softc_t * const sc, int ie)
+{
+	if (ie == LMC_CTL_CLOCK_SOURCE_EXT) {
+		sc->lmc_gpio &= ~(LMC_GEP_SSI_TXCLOCK);
+		LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio);
+		sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_EXT;
+		printf (LMC_PRINTF_FMT ": clock external\n", LMC_PRINTF_ARGS);
+	}
+	else {
+		sc->lmc_gpio |= LMC_GEP_SSI_TXCLOCK;
+		LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio);
+		sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_INT;
+		printf (LMC_PRINTF_FMT ": clock internal\n", LMC_PRINTF_ARGS);
+	}
+}
+
+static void
+lmc_t1_watchdog(lmc_softc_t * const sc)
+{
+	int t1stat;
+
+	/* read alarm 1 status (recieve) */
+	t1stat = lmc_t1_read (sc, 0x47);
+	/* blue alarm -- RAIS */
+	if (t1stat & 0x08) {
+		if (sc->lmc_blue != 1)
+			printf ("%s: AIS Recieved\n", sc->lmc_xname);
+		lmc_led_on (sc, LMC_DS3_LED1 | LMC_DS3_LED2);
+		sc->lmc_blue = 1;
+	} else {
+		if (sc->lmc_blue == 1)
+			printf ("%s: AIS ok\n", sc->lmc_xname);
+		lmc_led_off (sc, LMC_DS3_LED1);
+		lmc_led_on (sc, LMC_DS3_LED2);
+		sc->lmc_blue = 0;
+	}
+
+	/* Red alarm -- LOS | LOF */
+	if (t1stat & 0x04) {
+		/* Only print the error once */
+		if (sc->lmc_red != 1)
+			printf ("%s: Red Alarm\n", sc->lmc_xname);
+		lmc_led_on (sc, LMC_DS3_LED2 | LMC_DS3_LED3);
+		sc->lmc_red = 1;
+	} else { 
+		if (sc->lmc_red == 1)
+			printf ("%s: Red Alarm ok\n", sc->lmc_xname);
+	lmc_led_off (sc, LMC_DS3_LED3);
+	lmc_led_on (sc, LMC_DS3_LED2);
+	sc->lmc_red = 0;
+	}
+
+	/* check for Recieve Multiframe Yellow Alarm
+	 * Ignore Recieve Yellow Alarm
+	 */
+	if (t1stat & 0x80) {
+		if (sc->lmc_yel != 1) {
+			printf ("%s: Recieve Yellow Alarm\n", sc->lmc_xname);
+		}
+			lmc_led_on (sc, LMC_DS3_LED0 | LMC_DS3_LED2);
+			sc->lmc_yel = 1;
+	}
+	else {
+		if (sc->lmc_yel == 1)
+		printf ("%s: Yellow Alarm ok\n", sc->lmc_xname);
+		lmc_led_off (sc, LMC_DS3_LED0);
+		lmc_led_on (sc, LMC_DS3_LED2);
+		sc->lmc_yel = 0;
+	}
+}
+
 
 static void
 lmc_set_protocol(lmc_softc_t * const sc, lmc_ctl_t *ctl)
--- if_lmc_nbsd.c.orig	Wed May  3 16:08:03 2000
+++ if_lmc_nbsd.c	Fri Feb 16 01:51:56 2001
@@ -198,7 +198,8 @@
 		return 0;
 	if ((PCI_CHIPID(id) != PCI_PRODUCT_LMC_HSSI)
 	    && (PCI_CHIPID(id) != PCI_PRODUCT_LMC_DS3)
-	    && (PCI_CHIPID(id) != PCI_PRODUCT_LMC_SSI))
+	    && (PCI_CHIPID(id) != PCI_PRODUCT_LMC_SSI)
+	    && (PCI_CHIPID(id) != PCI_PRODUCT_LMC_DS1))
 		return 0;
 
 	return 10; /* must be > than any other tulip driver */
@@ -218,7 +219,7 @@
 	u_int32_t revinfo, cfdainfo, id, ssid;
 	pci_intr_handle_t intrhandle;
 	const char *intrstr;
-#if !defined(LMC_IOMAPPED)
+#if 0
 	vm_offset_t pa_csrs;
 #endif
 	unsigned csroffset = LMC_PCI_CSROFFSET;
@@ -231,6 +232,7 @@
 	extern lmc_media_t lmc_hssi_media;
 	extern lmc_media_t lmc_ds3_media;
 	extern lmc_media_t lmc_t1_media;
+	extern lmc_media_t lmc_ssi_media;
 
 	revinfo  = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CFRV) & 0xFF;
 	id       = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CFID);
@@ -248,6 +250,10 @@
 		break;
 	case PCI_PRODUCT_LMC_SSI:
 		printf(": Lan Media Corporation SSI\n");
+		sc->lmc_media = &lmc_ssi_media;
+		break;
+	case PCI_PRODUCT_LMC_DS1:
+		printf(": Lan Media Corporation T1\n");
 		sc->lmc_media = &lmc_t1_media;
 		break;
 	}
@@ -297,6 +303,11 @@
 			       sc->lmc_dev.dv_xname);
 			return;
 		}
+		/* Make sure bus mastering is enabled. */
+		pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
+			       pci_conf_read(pa->pa_pc, pa->pa_tag,
+					     PCI_COMMAND_STATUS_REG) |
+			       PCI_COMMAND_MASTER_ENABLE);
 	}
 
 	lmc_initcsrs(sc, csr_base + csroffset, csrsize);
@@ -310,7 +321,7 @@
 
 	sc->lmc_media->defaults(sc);
 
-	sc->lmc_media->set_link_status(sc, 0); /* down */
+	sc->lmc_media->set_link_status(sc, LMC_LINK_DOWN); /* down */
 
 	/*
 	 * Make sure there won't be any interrupts or such...
@@ -325,10 +336,6 @@
 	DELAY(100);
 
 	lmc_read_macaddr(sc);
-	printf("%s: pass %d.%d, serial " LMC_EADDR_FMT "\n",
-	       sc->lmc_dev.dv_xname,
-	       (sc->lmc_revinfo & 0xF0) >> 4, sc->lmc_revinfo & 0x0F,
-	       LMC_EADDR_ARGS(sc->lmc_enaddr));
 
 	if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
 			 pa->pa_intrline, &intrhandle)) {
@@ -347,8 +354,11 @@
 		printf("\n");
 		return;
 	}
-	printf("%s: interrupting at %s\n", sc->lmc_dev.dv_xname,
-	       intrstr);
+
+        printf("%s: pass %d.%d, serial " LMC_EADDR_FMT ", %s\n",
+               sc->lmc_dev.dv_xname,
+               (sc->lmc_revinfo & 0xF0) >> 4, sc->lmc_revinfo & 0x0F,
+               LMC_EADDR_ARGS(sc->lmc_enaddr), intrstr);
 
         sc->lmc_ats = shutdownhook_establish(lmc_shutdown, sc);
         if (sc->lmc_ats == NULL)
--- if_lmc_types.h.orig	Wed Mar 24 22:09:33 1999
+++ if_lmc_types.h	Thu Feb 15 22:52:13 2001
@@ -58,11 +58,7 @@
 #if defined(__NetBSD__)
 typedef bus_addr_t lmc_csrptr_t;
 #else
-#ifdef LMC_IOMAPPED
-typedef u_int16_t lmc_csrptr_t;
-#else
 typedef volatile u_int32_t *lmc_csrptr_t;
-#endif
 #endif
 
 #if defined(__NetBSD__)
--- if_lmcioctl.h.orig	Wed Mar 24 22:09:34 1999
+++ if_lmcioctl.h	Fri Feb 16 02:16:40 2001
@@ -82,13 +82,21 @@
 	u_int32_t	keepalive_onoff;	/* protocol */
 	u_int32_t	ticks;			/* ticks/sec */
 	union {
-		lmc_av9110_t	t1;
+		lmc_av9110_t	ssi;
 	} cardspec;
+	u_int32_t       circuit_type;		/* T1 or E1 */
 };
 
+#define LMC_CARDTYPE_UNKNOWN	-1
+#define LMC_CARDTYPE_HSSI	 1	/* probed card is a HSSI card */
+#define LMC_CARDTYPE_DS3	 2	/* probed card is a DS3 card */
+#define LMC_CARDTYPE_SSI	 3	/* probed card is a SSI card */
+#define LMC_CARDTYPE_T1		 4	/* probed card is a T1 card */
+
 #define LMC_CTL_CARDTYPE_LMC5200	0	/* HSSI */
 #define LMC_CTL_CARDTYPE_LMC5245	1	/* DS3 */
-#define LMC_CTL_CARDTYPE_LMC1000	2	/* T1, E1, etc */
+#define LMC_CTL_CARDTYPE_LMC1000	2	/* SSI, V.35 */
+#define LMC_CTL_CARDTYPE_LMC1200	3	/* DS1 */
 
 #define LMC_CTL_OFF			0	/* generic OFF value */
 #define LMC_CTL_ON			1	/* generic ON value */
@@ -98,10 +106,15 @@
 
 #define LMC_CTL_CRC_LENGTH_16		16
 #define LMC_CTL_CRC_LENGTH_32		32
+#define LMC_CTL_CRC_BYTESIZE_2		2
+#define LMC_CTL_CRC_BYTESIZE_4		4
 
 #define LMC_CTL_CABLE_LENGTH_LT_100FT	0	/* DS3 cable < 100 feet */
 #define LMC_CTL_CABLE_LENGTH_GT_100FT	1	/* DS3 cable >= 100 feet */
 
+#define LMC_CTL_CIRCUIT_TYPE_E1		0
+#define LMC_CTL_CIRCUIT_TYPE_T1		1
+
 /*
  * These are not in the least IOCTL related, but I want them common.
  */
@@ -124,8 +137,8 @@
 /*
  * T1 GPIO assignments
  */
-#define LMC_GEP_T1_GENERATOR	0x04 /* 2: enable prog freq gen serial i/f */
-#define LMC_GEP_T1_TXCLOCK	0x08 /* 3: provide clock on TXCLOCK output */
+#define LMC_GEP_SSI_GENERATOR	0x04 /* 2: enable prog freq gen serial i/f */
+#define LMC_GEP_SSI_TXCLOCK	0x08 /* 3: provide clock on TXCLOCK output */
 
 /*
  * Common MII16 bits
@@ -161,47 +174,103 @@
 #define LMC_MII16_DS3_CRC	0x1000
 #define LMC_MII16_DS3_SCRAM	0x2000
 
+/* Note: 2 pairs of LEDs where swapped by mistake
+ * in Xilinx code for DS3 & DS1 adapters */
+#define LMC_DS3_LED0	0x0100		/* bit 08  yellow */
+#define LMC_DS3_LED1	0x0080		/* bit 07  blue   */
+#define LMC_DS3_LED2	0x0400		/* bit 10  green  */
+#define LMC_DS3_LED3	0x0200		/* bit 09  red    */
+
+/*
+ * framer register 0 and 7 (7 is latched and reset on read)
+ */
+#define LMC_FRAMER_REG0_DLOS	0x80	/* digital loss of service */
+#define LMC_FRAMER_REG0_OOFS	0x40	/* out of frame sync */
+#define LMC_FRAMER_REG0_AIS	0x20	/* alarm indication signal */
+#define LMC_FRAMER_REG0_CIS	0x10	/* channel idle */
+#define LMC_FRAMER_REG0_LOC	0x08	/* loss of clock */
+
+
 /*
- * And T1
+ * And SSI, LMC1000
  */
-#define LMC_MII16_T1_DTR	0x0001	/* DTR output RW */
-#define LMC_MII16_T1_DSR	0x0002	/* DSR input RO */
-#define LMC_MII16_T1_RTS	0x0004	/* RTS output RW */
-#define LMC_MII16_T1_CTS	0x0008	/* CTS input RO */
-#define LMC_MII16_T1_DCD	0x0010	/* DCD input RO */
-#define LMC_MII16_T1_RI		0x0020	/* RI input RO */
-#define LMC_MII16_T1_CRC	0x0040	/* CRC select */
+#define LMC_MII16_SSI_DTR	0x0001	/* DTR output RW */
+#define LMC_MII16_SSI_DSR	0x0002	/* DSR input RO */
+#define LMC_MII16_SSI_RTS	0x0004	/* RTS output RW */
+#define LMC_MII16_SSI_CTS	0x0008	/* CTS input RO */
+#define LMC_MII16_SSI_DCD	0x0010	/* DCD input RO */
+#define LMC_MII16_SSI_RI	0x0020	/* RI input RO */
+#define LMC_MII16_SSI_CRC	0x1000	/* CRC select - RW */
 
 /*
  * bits 0x0080 through 0x0800 are generic, and described
  * above with LMC_MII16_LED[0123] _LED_ALL, and _FIFO_RESET
  */
-#define LMC_MII16_T1_LL		0x1000	/* LL output RW */
-#define LMC_MII16_T1_RL		0x2000	/* RL output RW */
-#define LMC_MII16_T1_TM		0x4000	/* TM input RO */
-#define LMC_MII16_T1_LOOP	0x8000	/* loopback enable RW */
+#define LMC_MII16_SSI_LL	0x1000	/* LL output RW */
+#define LMC_MII16_SSI_RL	0x2000	/* RL output RW */
+#define LMC_MII16_SSI_TM	0x4000	/* TM input RO */
+#define LMC_MII16_SSI_LOOP	0x8000	/* loopback enable RW */
 
 /*
  * Some of the MII16 bits are mirrored in the MII17 register as well,
- * but let's keep thing seperate for now, and get only the cable from
+ * but let's keep thing separate for now, and get only the cable from
  * the MII17.
  */
-#define LMC_MII17_T1_CABLE_MASK	0x0038	/* mask to extract the cable type */
-#define LMC_MII17_T1_CABLE_SHIFT 3	/* shift to extract the cable type */
+#define LMC_MII17_SSI_CABLE_MASK	0x0038	/* mask to extract the cable type */
+#define LMC_MII17_SSI_CABLE_SHIFT 3	/* shift to extract the cable type */
 
 /*
- * framer register 0 and 7 (7 is latched and reset on read)
+ * And T1, LMC1200
  */
-#define LMC_FRAMER_REG0_DLOS	0x80	/* digital loss of service */
-#define LMC_FRAMER_REG0_OOFS	0x40	/* out of frame sync */
-#define LMC_FRAMER_REG0_AIS	0x20	/* alarm indication signal */
-#define LMC_FRAMER_REG0_CIS	0x10	/* channel idle */
-#define LMC_FRAMER_REG0_LOC	0x08	/* loss of clock */
+#define LMC_MII16_T1_UNUSED1    	0x0003
+#define LMC_MII16_T1_XOE                0x0004
+#define LMC_MII16_T1_RST                0x0008  /* T1 chip reset - RW */
+#define LMC_MII16_T1_Z                  0x0010  /* output impedance T1=1, E1=0 output - RW */
+#define LMC_MII16_T1_INTR               0x0020  /* interrupt from 8370 - RO */
+#define LMC_MII16_T1_ONESEC             0x0040  /* one second square wave - ro */
 
-#define LMC_CARDTYPE_UNKNOWN	-1
-#define LMC_CARDTYPE_HSSI	 1	/* probed card is a HSSI card */
-#define LMC_CARDTYPE_DS3	 2	/* probed card is a DS3 card */
-#define LMC_CARDTYPE_T1		 3	/* probed card is a T1 card */
+#define LMC_MII16_T1_LED0               0x0100
+#define LMC_MII16_T1_LED1               0x0080
+#define LMC_MII16_T1_LED2               0x0400
+#define LMC_MII16_T1_LED3               0x0200
+#define LMC_MII16_T1_FIFO_RESET 0x0800
+
+#define LMC_MII16_T1_CRC                0x1000  /* CRC select - RW */
+#define LMC_MII16_T1_UNUSED2    	0xe000
+
+
+/* 8370 framer registers  */
+
+#define T1FRAMER_ALARM1_STATUS  0x47
+#define T1FRAMER_ALARM2_STATUS  0x48
+#define T1FRAMER_FERR_LSB               0x50
+#define T1FRAMER_FERR_MSB               0x51    /* framing bit error counter */
+#define T1FRAMER_LCV_LSB                0x54
+#define T1FRAMER_LCV_MSB                0x55    /* line code violation counter */
+#define T1FRAMER_AERR                   0x5A
+
+/* mask for the above AERR register */
+#define T1FRAMER_LOF_MASK               (0x0f0) /* receive loss of frame */
+#define T1FRAMER_COFA_MASK              (0x0c0) /* change of frame alignment */
+#define T1FRAMER_SEF_MASK               (0x03)  /* severely errored frame  */
+
+/* 8370 framer register ALM1 (0x47) values
+ * used to determine link status
+ */
+
+#define T1F_SIGFRZ      0x01    /* signaling freeze */
+#define T1F_RLOF        0x02    /* receive loss of frame alignment */
+#define T1F_RLOS        0x04    /* receive loss of signal */
+#define T1F_RALOS       0x08    /* receive analog loss of signal or RCKI loss of clock */
+#define T1F_RAIS        0x10    /* receive alarm indication signal */
+#define T1F_UNUSED      0x20
+#define T1F_RYEL        0x40    /* receive yellow alarm */
+#define T1F_RMYEL       0x80    /* receive multiframe yellow alarm */
+
+/* ------------------ end T1 defs ------------------- */
+
+#define LMC_MII_LedMask                 0x0780
+#define LMC_MII_LedBitPos               7
 
 #if defined(LMC_IS_KERNEL) /* defined in if_lmc_types.h */
 
@@ -220,6 +289,8 @@
 	int	(* get_link_status)(lmc_softc_t * const);
 	void	(* set_link_status)(lmc_softc_t * const, int);
 	void	(* set_crc_length)(lmc_softc_t * const, int);
+	void    (* set_circuit_type)(lmc_softc_t * const, int);
+	void	(* watchdog)(lmc_softc_t * const);
 };
 
 u_int32_t lmc_mii_readreg(lmc_softc_t * const sc, u_int32_t devaddr,
--- if_lmcvar.h.orig	Wed May  3 16:08:03 2000
+++ if_lmcvar.h	Mon Mar  5 00:12:51 2001
@@ -127,6 +127,9 @@
 #include <sys/rnd.h>
 #endif
 
+#endif /* NetBSD */
+
+#if defined(__NetBSD__)
 #define LMC_CSR_READ(sc, csr) \
     bus_space_read_4((sc)->lmc_bustag, (sc)->lmc_bushandle, (sc)->lmc_csrs.csr)
 #define LMC_CSR_WRITE(sc, csr, val) \
@@ -138,22 +141,6 @@
     bus_space_write_1((sc)->lmc_bustag, (sc)->lmc_bushandle, (sc)->lmc_csrs.csr, (val))
 #endif /* __NetBSD__ */
 
-#ifdef LMC_IOMAPPED
-#define	LMC_EISA_CSRSIZE	16
-#define	LMC_EISA_CSROFFSET	0
-#define	LMC_PCI_CSRSIZE	8
-#define	LMC_PCI_CSROFFSET	0
-
-#if !defined(__NetBSD__)
-#define	LMC_CSR_READ(sc, csr)			(inl((sc)->lmc_csrs.csr))
-#define	LMC_CSR_WRITE(sc, csr, val)   	outl((sc)->lmc_csrs.csr, val)
-
-#define	LMC_CSR_READBYTE(sc, csr)		(inb((sc)->lmc_csrs.csr))
-#define	LMC_CSR_WRITEBYTE(sc, csr, val)	outb((sc)->lmc_csrs.csr, val)
-#endif /* __NetBSD__ */
-
-#else /* LMC_IOMAPPED */
-
 #define	LMC_PCI_CSRSIZE	8
 #define	LMC_PCI_CSROFFSET	0
 
@@ -167,8 +154,6 @@
 #define	LMC_CSR_WRITE(sc, csr, val)	((void)(*(sc)->lmc_csrs.csr = (val)))
 #endif /* __NetBSD__ */
 
-#endif /* LMC_IOMAPPED */
-
 /*
  * This structure contains "pointers" for the registers on
  * the various 21x4x chips.  CSR0 through CSR8 are common
@@ -255,11 +240,8 @@
 
 #define	LMC_RX_BUFLEN		((MCLBYTES < 2048 ? MCLBYTES : 2048) - 16)
 
-/*
- * The various controllers support.  Technically the DE425 is just
- * a 21040 on EISA.  But since it remarkably difference from normal
- * 21040s, we give it its own chip id.
- */
+#define	LMC_LINK_UP		1
+#define	LMC_LINK_DOWN		0
 
 typedef enum {
     LMC_21140, LMC_21140A,
@@ -368,6 +350,13 @@
 #if defined(__NetBSD__) && NRND > 0
     rndsource_element_t    lmc_rndsource;
 #endif
+
+    u_int32_t   lmc_crcSize;
+    u_int32_t   tx_clockState;
+    char        lmc_yel, lmc_blue, lmc_red;     /* for T1 and DS3 */
+    char        lmc_timing;                     /* for HSSI and SSI */
+    u_int16_t   t1_alarm1_status;
+    u_int16_t   t1_alarm2_status;
 };
 
 /*
@@ -578,7 +567,7 @@
 #if !defined(LMC_BPF_MTAP) && NBPFILTER > 0
 #define	LMC_BPF_MTAP(sc, m)	bpf_mtap((sc)->lmc_bpf, m)
 #define	LMC_BPF_TAP(sc, p, l)	bpf_tap((sc)->lmc_bpf, p, l)
-#define	LMC_BPF_ATTACH(sc)	bpfattach(&(sc)->lmc_bpf, &(sc)->lmc_sppp.pp_if, DLT_PPP_SERIAL, PPP_HEADER_LEN)
+#define	LMC_BPF_ATTACH(sc)	bpfattach(&(sc)->lmc_bpf, &(sc)->lmc_sppp.pp_if, DLT_HDLC, PPP_HEADER_LEN)
 #endif
 
 /*
--- pcidevs.orig	Mon Oct 30 17:27:35 2000
+++ pcidevs	Fri Feb 16 18:56:01 2001
@@ -1097,6 +1097,7 @@
 product	LMC HSSI	0x0003	HSSI Interface
 product	LMC DS3		0x0004	DS3 Interface
 product	LMC SSI		0x0005	SSI
+product	LMC DS1		0x0006	DS1
 
 /* LeadTek Research */
 product LEADTEK S3_805	0x0000	S3 805
>Release-Note:
>Audit-Trail:
>Unformatted: