diff options
author | Chris Cappuccio <chris@cvs.openbsd.org> | 1999-10-26 23:47:16 +0000 |
---|---|---|
committer | Chris Cappuccio <chris@cvs.openbsd.org> | 1999-10-26 23:47:16 +0000 |
commit | 06007bab37f86c536d988618cabb43b84d678880 (patch) | |
tree | 8c73bb8de0574ca57303f6d7b8efda3ceb2ef8c9 /sys | |
parent | 0ec85252a9ebb583d953ccaef52d2704e45ff2e9 (diff) |
Support LMC1200
Based on LMC's Linux code
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/if_lmc_common.c | 3 | ||||
-rw-r--r-- | sys/dev/pci/if_lmc_media.c | 372 | ||||
-rw-r--r-- | sys/dev/pci/if_lmc_obsd.c | 20 | ||||
-rw-r--r-- | sys/dev/pci/if_lmcioctl.h | 181 | ||||
-rw-r--r-- | sys/dev/pci/if_lmcvar.h | 5 |
5 files changed, 480 insertions, 101 deletions
diff --git a/sys/dev/pci/if_lmc_common.c b/sys/dev/pci/if_lmc_common.c index a005df8830c..af526451bd1 100644 --- a/sys/dev/pci/if_lmc_common.c +++ b/sys/dev/pci/if_lmc_common.c @@ -238,8 +238,7 @@ lmc_reset(lmc_softc_t * const sc) /* * 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 diff --git a/sys/dev/pci/if_lmc_media.c b/sys/dev/pci/if_lmc_media.c index 7bcfa3bff59..f162df45fa3 100644 --- a/sys/dev/pci/if_lmc_media.c +++ b/sys/dev/pci/if_lmc_media.c @@ -1,10 +1,13 @@ -/* $NetBSD: if_lmc_media.c,v 1.1 1999/03/25 03:32:43 explorer Exp $ */ +/* $OpenBSD $ */ +/* $Id: if_lmc_media.c,v 1.2 1999/10/26 23:47:14 chris Exp $ */ /*- * Copyright (c) 1997-1999 LAN Media Corporation (LMC) * 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 @@ -176,13 +179,20 @@ 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_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_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_dummy_set_1(lmc_softc_t * const, int); @@ -203,6 +213,7 @@ lmc_media_t lmc_ds3_media = { 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_media_t lmc_hssi_media = { @@ -216,19 +227,35 @@ lmc_media_t lmc_hssi_media = { 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_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_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_dummy_set_1, /* 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 */ }; static void @@ -280,10 +307,13 @@ lmc_hssi_set_status(lmc_softc_t * const sc, lmc_ctl_t *ctl) /* * 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); } @@ -507,11 +537,11 @@ lmc_ds3_set_crc_length(lmc_softc_t * const sc, int state) /* - * 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; @@ -520,21 +550,21 @@ lmc_t1_init(lmc_softc_t * const sc) 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); @@ -547,7 +577,7 @@ lmc_t1_default(lmc_softc_t * const sc) * 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); @@ -561,11 +591,14 @@ lmc_t1_set_status(lmc_softc_t * const sc, lmc_ctl_t *ctl) * 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); @@ -577,16 +610,16 @@ lmc_t1_set_status(lmc_softc_t * const sc, lmc_ctl_t *ctl) * 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", @@ -595,32 +628,38 @@ lmc_t1_set_clock(lmc_softc_t * const sc, int ie) } 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); } @@ -630,7 +669,7 @@ lmc_t1_set_speed(lmc_softc_t * const sc, lmc_ctl_t *ctl) * 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; @@ -643,54 +682,67 @@ lmc_t1_get_link_status(lmc_softc_t * const sc) * 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) @@ -730,7 +782,7 @@ write_av9110(lmc_softc_t *sc, u_int32_t n, u_int32_t m, u_int32_t v, 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); @@ -739,9 +791,9 @@ write_av9110(lmc_softc_t *sc, u_int32_t n, u_int32_t m, u_int32_t v, * 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); /* @@ -765,7 +817,237 @@ write_av9110(lmc_softc_t *sc, u_int32_t n, u_int32_t m, u_int32_t v, */ lmc_gpio_mkinput(sc, (LMC_GEP_SERIAL | LMC_GEP_SERIALCLK - | LMC_GEP_T1_GENERATOR)); + | LMC_GEP_SSI_GENERATOR)); +} + +/* + * 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); +} + +/* XXX future to be integtrated with if_lmc.c for alarms +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); + + /* 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 */ + } + /* XXX + 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, 0); + 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); } static void diff --git a/sys/dev/pci/if_lmc_obsd.c b/sys/dev/pci/if_lmc_obsd.c index 20e09df650c..9b1153f7c56 100644 --- a/sys/dev/pci/if_lmc_obsd.c +++ b/sys/dev/pci/if_lmc_obsd.c @@ -1,3 +1,4 @@ +/* $OpenBSD $ */ /* $NetBSD: if_lmc_nbsd.c,v 1.1 1999/03/25 03:32:43 explorer Exp $ */ /*- @@ -208,7 +209,8 @@ lmc_pci_probe(struct device *parent, 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 */ @@ -245,6 +247,7 @@ lmc_pci_attach(struct device * const parent, 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); @@ -262,6 +265,10 @@ lmc_pci_attach(struct device * const parent, 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; } @@ -344,10 +351,6 @@ lmc_pci_attach(struct device * const parent, 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)) { @@ -373,8 +376,11 @@ lmc_pci_attach(struct device * const parent, 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) diff --git a/sys/dev/pci/if_lmcioctl.h b/sys/dev/pci/if_lmcioctl.h index f1921d1f502..dbd98942bba 100644 --- a/sys/dev/pci/if_lmcioctl.h +++ b/sys/dev/pci/if_lmcioctl.h @@ -1,6 +1,6 @@ -/* $NetBSD: if_lmcioctl.h,v 1.2 1999/03/25 04:09:34 explorer Exp $ */ +/* $Id: if_lmcioctl.h,v 1.2 1999/10/26 23:47:15 chris Exp $ */ -/*- +/* * Copyright (c) 1997-1999 LAN Media Corporation (LMC) * All rights reserved. www.lanmedia.com * @@ -39,6 +39,7 @@ */ #if defined(linux) +#include <linux/types.h> /* * IOCTLs that we use for linux. The structures passed in really should * go into an OS inspecific file, since BSD will use these as well. @@ -46,8 +47,21 @@ * Under linux, the 16 reserved-for-device IOCTLs are numbered 0x89f0 * through 0x89ff. */ -#define LMCIOCGINFO 0x89f0 /* get current state */ -#define LMCIOCSINFO 0x89f1 /* set state to user provided values */ +#define LMCIOCGINFO SIOCDEVPRIVATE+3 /* get current state */ +#define LMCIOCSINFO SIOCDEVPRIVATE+4 /* set state to user values */ +#define LMCIOCSKEEPALIVE SIOCDEVPRIVATE+5 /* Turn keepalives on/off */ +#ifdef LMC_DEBUG_FILE +#define LMCIOCLEARSTATS LMCIOCSINFO + 1 /* Clear debug stats */ +#endif +#ifdef LMC_BAZ +#define LMCIOCGETLMCSTATS LMCIOCSINFO + 3 +#define LMCIOCCLEARLMCSTATS LMCIOCSINFO + 4 +#define LMCIOCDUMPEVENTLOG LMCIOCSINFO + 5 +#define LMCIOCGETXINFO LMCIOCSINFO + 6 +#define LMCIOCREADLEDS LMCIOCSINFO + 7 +#define LMCIOCSETLEDS LMCIOCSINFO + 8 +#define LMCIOCRESET LMCIOCSINFO + 9 +#endif #else /* @@ -82,13 +96,22 @@ struct lmc___ctl { 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 +121,16 @@ struct lmc___ctl { #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,29 +153,29 @@ struct lmc___ctl { /* * 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 */ -#define LMC_MII16_LED0 0x0080 -#define LMC_MII16_LED1 0x0100 -#define LMC_MII16_LED2 0x0200 -#define LMC_MII16_LED3 0x0400 /* Error, and the red one */ -#define LMC_MII16_LED_ALL 0x0780 /* LED bit mask */ -#define LMC_MII16_FIFO_RESET 0x0800 +#define LMC_MII16_LED0 0x0080 +#define LMC_MII16_LED1 0x0100 +#define LMC_MII16_LED2 0x0200 +#define LMC_MII16_LED3 0x0400 /* Error, and the red one */ +#define LMC_MII16_LED_ALL 0x0780 /* LED bit mask */ +#define LMC_MII16_FIFO_RESET 0x0800 /* * definitions for HSSI */ -#define LMC_MII16_HSSI_TA 0x0001 -#define LMC_MII16_HSSI_CA 0x0002 -#define LMC_MII16_HSSI_LA 0x0004 -#define LMC_MII16_HSSI_LB 0x0008 -#define LMC_MII16_HSSI_LC 0x0010 -#define LMC_MII16_HSSI_TM 0x0020 -#define LMC_MII16_HSSI_CRC 0x0040 +#define LMC_MII16_HSSI_TA 0x0001 +#define LMC_MII16_HSSI_CA 0x0002 +#define LMC_MII16_HSSI_LA 0x0004 +#define LMC_MII16_HSSI_LB 0x0008 +#define LMC_MII16_HSSI_LC 0x0010 +#define LMC_MII16_HSSI_TM 0x0020 +#define LMC_MII16_HSSI_CRC 0x0040 /* * assignments for the MII register 16 (DS3) @@ -161,50 +190,108 @@ struct lmc___ctl { #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 * 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_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 + -#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 */ +/* 8370 framer registers */ -#if defined(LMC_IS_KERNEL) /* defined in if_lmc_types.h */ +#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 + +/* + * OpenBSD, NetBSD uses _KERNEL, FreeBSD uses KERNEL. + */ +#if defined(_KERNEL) || defined(KERNEL) || defined(__KERNEL__) /* * media independent methods to check on media status, link, light LEDs, * etc. @@ -220,6 +307,7 @@ struct lmc___media { 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); }; u_int32_t lmc_mii_readreg(lmc_softc_t * const sc, u_int32_t devaddr, @@ -239,5 +327,4 @@ int lmc_read_macaddr(lmc_softc_t * const sc); void lmc_attach(lmc_softc_t * const sc); void lmc_initring(lmc_softc_t * const sc, lmc_ringinfo_t * const ri, tulip_desc_t *descs, int ndescs); - #endif /* LMC_IS_KERNEL */ diff --git a/sys/dev/pci/if_lmcvar.h b/sys/dev/pci/if_lmcvar.h index f1693079fcf..bd85a8e07ce 100644 --- a/sys/dev/pci/if_lmcvar.h +++ b/sys/dev/pci/if_lmcvar.h @@ -371,6 +371,11 @@ struct lmc___softc { #if defined(__NetBSD__) && NRND > 0 rndsource_element_t lmc_rndsource; #endif + + u_int32_t lmc_crcSize; + char lmc_timing; /* for HSSI and SSI */ + u_int16_t t1_alarm1_status; + u_int16_t t1_alarm2_status; }; /* |