[BACK]Return to if_lmc_media.c CVS log [TXT][DIR] Up to [local] / sys / dev / pci

Annotation of sys/dev/pci/if_lmc_media.c, Revision 1.1

1.1     ! nbrk        1: /* $OpenBSD: if_lmc_media.c,v 1.16 2005/11/07 00:29:21 brad Exp $ */
        !             2: /* $Id: if_lmc_media.c,v 1.16 2005/11/07 00:29:21 brad Exp $ */
        !             3:
        !             4: /*-
        !             5:  * Copyright (c) 1997-1999 LAN Media Corporation (LMC)
        !             6:  * All rights reserved.  www.lanmedia.com
        !             7:  *
        !             8:  * This code is written by Michael Graff <graff@vix.com> for LMC.
        !             9:  * The code is derived from permitted modifications to software created
        !            10:  * by Matt Thomas (matt@3am-software.com).
        !            11:  *
        !            12:  * Redistribution and use in source and binary forms, with or without
        !            13:  * modification, are permitted provided that the following conditions
        !            14:  * are met:
        !            15:  * 1. Redistributions of source code must retain the above copyright
        !            16:  *    notice, this list of conditions and the following disclaimer.
        !            17:  * 2. Redistributions in binary form must reproduce the above
        !            18:  *    copyright notice, this list of conditions and the following disclaimer
        !            19:  *    in the documentation and/or other materials provided with the
        !            20:  *    distribution.
        !            21:  * 3. All marketing or advertising materials mentioning features or
        !            22:  *    use of this software must display the following acknowledgement:
        !            23:  *      This product includes software developed by LAN Media Corporation
        !            24:  *      and its contributors.
        !            25:  * 4. Neither the name of LAN Media Corporation nor the names of its
        !            26:  *    contributors may be used to endorse or promote products derived
        !            27:  *    from this software without specific prior written permission.
        !            28:  *
        !            29:  * THIS SOFTWARE IS PROVIDED BY LAN MEDIA CORPORATION AND CONTRIBUTORS
        !            30:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
        !            31:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        !            32:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
        !            33:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            34:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        !            35:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        !            36:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        !            37:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        !            38:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
        !            39:  * THE POSSIBILITY OF SUCH DAMAGE.
        !            40:  */
        !            41:
        !            42: #include "bpfilter.h"
        !            43:
        !            44: #include <sys/param.h>
        !            45: #include <sys/systm.h>
        !            46: #include <sys/mbuf.h>
        !            47: #include <sys/socket.h>
        !            48: #include <sys/ioctl.h>
        !            49: #include <sys/errno.h>
        !            50: #include <sys/malloc.h>
        !            51: #include <sys/kernel.h>
        !            52: #include <sys/proc.h>  /* only for declaration of wakeup() used by vm.h */
        !            53: #include <sys/device.h>
        !            54:
        !            55: #include <dev/pci/pcidevs.h>
        !            56:
        !            57: #include <net/if.h>
        !            58: #include <net/if_types.h>
        !            59: #include <net/if_dl.h>
        !            60: #include <net/netisr.h>
        !            61:
        !            62: #if NBPFILTER > 0
        !            63: #include <net/bpf.h>
        !            64: #endif
        !            65:
        !            66: #include <net/if_sppp.h>
        !            67:
        !            68: #include <machine/bus.h>
        !            69:
        !            70: #include <dev/pci/pcireg.h>
        !            71: #include <dev/pci/pcivar.h>
        !            72: #include <dev/ic/dc21040reg.h>
        !            73:
        !            74: #include <dev/pci/if_lmc_types.h>
        !            75: #include <dev/pci/if_lmcioctl.h>
        !            76: #include <dev/pci/if_lmcvar.h>
        !            77:
        !            78: /*
        !            79:  * For lack of a better place, put the T1 cable stuff here.
        !            80:  */
        !            81: char *lmc_t1_cables[] = {
        !            82:        "V.10/RS423", "EIA530A", "reserved", "X.21", "V.35",
        !            83:        "EIA449/EIA530/V.36", "V.28/EIA232", "none", NULL
        !            84: };
        !            85:
        !            86: /*
        !            87:  * protocol independent method.
        !            88:  */
        !            89: static void    lmc_set_protocol(lmc_softc_t * const, lmc_ctl_t *);
        !            90:
        !            91: /*
        !            92:  * media independent methods to check on media status, link, light LEDs,
        !            93:  * etc.
        !            94:  */
        !            95: static void    lmc_ds3_init(lmc_softc_t * const);
        !            96: static void    lmc_ds3_default(lmc_softc_t * const);
        !            97: static void    lmc_ds3_set_status(lmc_softc_t * const, lmc_ctl_t *);
        !            98: static void    lmc_ds3_set_100ft(lmc_softc_t * const, int);
        !            99: static int     lmc_ds3_get_link_status(lmc_softc_t * const);
        !           100: static void    lmc_ds3_set_crc_length(lmc_softc_t * const, int);
        !           101: static void    lmc_ds3_set_scram(lmc_softc_t * const, int);
        !           102: static void    lmc_ds3_watchdog(lmc_softc_t * const);
        !           103:
        !           104: static void    lmc_hssi_init(lmc_softc_t * const);
        !           105: static void    lmc_hssi_default(lmc_softc_t * const);
        !           106: static void    lmc_hssi_set_status(lmc_softc_t * const, lmc_ctl_t *);
        !           107: static void    lmc_hssi_set_clock(lmc_softc_t * const, int);
        !           108: static int     lmc_hssi_get_link_status(lmc_softc_t * const);
        !           109: static void    lmc_hssi_set_link_status(lmc_softc_t * const, int);
        !           110: static void    lmc_hssi_set_crc_length(lmc_softc_t * const, int);
        !           111: static void    lmc_hssi_watchdog(lmc_softc_t * const);
        !           112:
        !           113: static void     lmc_ssi_init(lmc_softc_t * const);
        !           114: static void     lmc_ssi_default(lmc_softc_t * const);
        !           115: static void     lmc_ssi_set_status(lmc_softc_t * const, lmc_ctl_t *);
        !           116: static void     lmc_ssi_set_clock(lmc_softc_t * const, int);
        !           117: static void     lmc_ssi_set_speed(lmc_softc_t * const, lmc_ctl_t *);
        !           118: static int      lmc_ssi_get_link_status(lmc_softc_t * const);
        !           119: static void     lmc_ssi_set_link_status(lmc_softc_t * const, int);
        !           120: static void     lmc_ssi_set_crc_length(lmc_softc_t * const, int);
        !           121: static void    lmc_ssi_watchdog(lmc_softc_t * const);
        !           122:
        !           123: static void    lmc_t1_init(lmc_softc_t * const);
        !           124: static void    lmc_t1_default(lmc_softc_t * const);
        !           125: static void    lmc_t1_set_status(lmc_softc_t * const, lmc_ctl_t *);
        !           126: static int     lmc_t1_get_link_status(lmc_softc_t * const);
        !           127: static void     lmc_t1_set_circuit_type(lmc_softc_t * const, int);
        !           128: static void    lmc_t1_set_crc_length(lmc_softc_t * const, int);
        !           129: static void    lmc_t1_set_clock(lmc_softc_t * const, int);
        !           130: static void    lmc_t1_watchdog(lmc_softc_t * const);
        !           131:
        !           132: static void    lmc_dummy_set_1(lmc_softc_t * const, int);
        !           133: static void    lmc_dummy_set2_1(lmc_softc_t * const, lmc_ctl_t *);
        !           134:
        !           135: static inline void write_av9110_bit(lmc_softc_t *, int);
        !           136: static void    write_av9110(lmc_softc_t *, u_int32_t, u_int32_t, u_int32_t,
        !           137:                             u_int32_t, u_int32_t);
        !           138:
        !           139: lmc_media_t lmc_ds3_media = {
        !           140:        lmc_ds3_init,                   /* special media init stuff */
        !           141:        lmc_ds3_default,                /* reset to default state */
        !           142:        lmc_ds3_set_status,             /* reset status to state provided */
        !           143:        lmc_dummy_set_1,                /* set clock source */
        !           144:        lmc_dummy_set2_1,               /* set line speed */
        !           145:        lmc_ds3_set_100ft,              /* set cable length */
        !           146:        lmc_ds3_set_scram,              /* set scrambler */
        !           147:        lmc_ds3_get_link_status,        /* get link status */
        !           148:        lmc_dummy_set_1,                /* set link status */
        !           149:        lmc_ds3_set_crc_length,         /* set CRC length */
        !           150:        lmc_dummy_set_1,                /* set T1 or E1 circuit type */
        !           151:        lmc_ds3_watchdog
        !           152: };
        !           153:
        !           154: lmc_media_t lmc_hssi_media = {
        !           155:        lmc_hssi_init,                  /* special media init stuff */
        !           156:        lmc_hssi_default,               /* reset to default state */
        !           157:        lmc_hssi_set_status,            /* reset status to state provided */
        !           158:        lmc_hssi_set_clock,             /* set clock source */
        !           159:        lmc_dummy_set2_1,               /* set line speed */
        !           160:        lmc_dummy_set_1,                /* set cable length */
        !           161:        lmc_dummy_set_1,                /* set scrambler */
        !           162:        lmc_hssi_get_link_status,       /* get link status */
        !           163:        lmc_hssi_set_link_status,       /* set link status */
        !           164:        lmc_hssi_set_crc_length,        /* set CRC length */
        !           165:        lmc_dummy_set_1,                /* set T1 or E1 circuit type */
        !           166:        lmc_hssi_watchdog
        !           167: };
        !           168:
        !           169: lmc_media_t lmc_ssi_media = {
        !           170:        lmc_ssi_init,                   /* special media init stuff */
        !           171:         lmc_ssi_default,               /* reset to default state */
        !           172:         lmc_ssi_set_status,            /* reset status to state provided */
        !           173:         lmc_ssi_set_clock,             /* set clock source */
        !           174:         lmc_ssi_set_speed,             /* set line speed */
        !           175:         lmc_dummy_set_1,               /* set cable length */
        !           176:         lmc_dummy_set_1,               /* set scrambler */
        !           177:         lmc_ssi_get_link_status,       /* get link status */
        !           178:         lmc_ssi_set_link_status,       /* set link status */
        !           179:         lmc_ssi_set_crc_length,                /* set CRC length */
        !           180:         lmc_dummy_set_1,               /* set T1 or E1 circuit type */
        !           181:        lmc_ssi_watchdog
        !           182: };
        !           183:
        !           184: lmc_media_t lmc_t1_media = {
        !           185:        lmc_t1_init,                    /* special media init stuff */
        !           186:        lmc_t1_default,                 /* reset to default state */
        !           187:        lmc_t1_set_status,              /* reset status to state provided */
        !           188:         lmc_t1_set_clock,              /* set clock source */
        !           189:         lmc_dummy_set2_1,              /* set line speed */
        !           190:        lmc_dummy_set_1,                /* set cable length */
        !           191:        lmc_dummy_set_1,                /* set scrambler */
        !           192:        lmc_t1_get_link_status,         /* get link status */
        !           193:         lmc_dummy_set_1,               /* set link status */
        !           194:        lmc_t1_set_crc_length,          /* set CRC length */
        !           195:         lmc_t1_set_circuit_type,       /* set T1 or E1 circuit type */
        !           196:        lmc_t1_watchdog
        !           197: };
        !           198:
        !           199: static void
        !           200: lmc_dummy_set_1(lmc_softc_t * const sc, int a)
        !           201: {
        !           202: }
        !           203:
        !           204: static void
        !           205: lmc_dummy_set2_1(lmc_softc_t * const sc, lmc_ctl_t *a)
        !           206: {
        !           207: }
        !           208:
        !           209: /*
        !           210:  *  HSSI methods
        !           211:  */
        !           212:
        !           213: static void
        !           214: lmc_hssi_init(lmc_softc_t * const sc)
        !           215: {
        !           216:        sc->ictl.cardtype = LMC_CTL_CARDTYPE_LMC5200;
        !           217:
        !           218:        lmc_gpio_mkoutput(sc, LMC_GEP_HSSI_CLOCK);
        !           219: }
        !           220:
        !           221: static void
        !           222: lmc_hssi_default(lmc_softc_t * const sc)
        !           223: {
        !           224:        sc->lmc_miireg16 = LMC_MII16_LED_ALL;
        !           225:
        !           226:        sc->lmc_media->set_link_status(sc, LMC_LINK_DOWN);
        !           227:        sc->lmc_media->set_clock_source(sc, LMC_CTL_CLOCK_SOURCE_EXT);
        !           228:        sc->lmc_media->set_crc_length(sc, LMC_CTL_CRC_LENGTH_16);
        !           229: }
        !           230:
        !           231: /*
        !           232:  * Given a user provided state, set ourselves up to match it.  This will
        !           233:  * always reset the card if needed.
        !           234:  */
        !           235: static void
        !           236: lmc_hssi_set_status(lmc_softc_t * const sc, lmc_ctl_t *ctl)
        !           237: {
        !           238:        if (ctl == NULL) {
        !           239:                sc->lmc_media->set_clock_source(sc, sc->ictl.clock_source);
        !           240:                lmc_set_protocol(sc, NULL);
        !           241:
        !           242:                return;
        !           243:        }
        !           244:
        !           245:        /*
        !           246:         * check for change in clock source
        !           247:         */
        !           248:        if (ctl->clock_source && !sc->ictl.clock_source) {
        !           249:                sc->lmc_media->set_clock_source(sc, LMC_CTL_CLOCK_SOURCE_INT);
        !           250:                sc->lmc_timing = LMC_CTL_CLOCK_SOURCE_INT;
        !           251:        } else if (!ctl->clock_source && sc->ictl.clock_source) {
        !           252:                sc->lmc_timing = LMC_CTL_CLOCK_SOURCE_EXT;
        !           253:                sc->lmc_media->set_clock_source(sc, LMC_CTL_CLOCK_SOURCE_EXT);
        !           254:        }
        !           255:
        !           256:        lmc_set_protocol(sc, ctl);
        !           257: }
        !           258:
        !           259: /*
        !           260:  * 1 == internal, 0 == external
        !           261:  */
        !           262: static void
        !           263: lmc_hssi_set_clock(lmc_softc_t * const sc, int ie)
        !           264: {
        !           265:        if (ie == LMC_CTL_CLOCK_SOURCE_EXT) {
        !           266:                sc->lmc_gpio |= LMC_GEP_HSSI_CLOCK;
        !           267:                LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
        !           268:                sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_EXT;
        !           269:                printf(LMC_PRINTF_FMT ": clock external\n",
        !           270:                       LMC_PRINTF_ARGS);
        !           271:        } else {
        !           272:                sc->lmc_gpio &= ~(LMC_GEP_HSSI_CLOCK);
        !           273:                LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
        !           274:                sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_INT;
        !           275:                printf(LMC_PRINTF_FMT ": clock internal\n",
        !           276:                       LMC_PRINTF_ARGS);
        !           277:        }
        !           278: }
        !           279:
        !           280: /*
        !           281:  * return hardware link status.
        !           282:  * 0 == link is down, 1 == link is up.
        !           283:  */
        !           284: static int
        !           285: lmc_hssi_get_link_status(lmc_softc_t * const sc)
        !           286: {
        !           287:        u_int16_t link_status;
        !           288:
        !           289:        link_status = lmc_mii_readreg(sc, 0, 16);
        !           290:
        !           291:        if ((link_status & LMC_MII16_HSSI_CA) == LMC_MII16_HSSI_CA)
        !           292:                return 1;
        !           293:        else
        !           294:                return 0;
        !           295: }
        !           296:
        !           297: static void
        !           298: lmc_hssi_set_link_status(lmc_softc_t * const sc, int state)
        !           299: {
        !           300:        if (state == LMC_LINK_UP)
        !           301:                sc->lmc_miireg16 |= LMC_MII16_HSSI_TA;
        !           302:        else
        !           303:                sc->lmc_miireg16 &= ~LMC_MII16_HSSI_TA;
        !           304:
        !           305:        lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
        !           306: }
        !           307:
        !           308: /*
        !           309:  * 0 == 16bit, 1 == 32bit
        !           310:  */
        !           311: static void
        !           312: lmc_hssi_set_crc_length(lmc_softc_t * const sc, int state)
        !           313: {
        !           314:        if (state == LMC_CTL_CRC_LENGTH_32) {
        !           315:                /* 32 bit */
        !           316:                sc->lmc_miireg16 |= LMC_MII16_HSSI_CRC;
        !           317:                sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_32;
        !           318:        } else {
        !           319:                /* 16 bit */
        !           320:                sc->lmc_miireg16 &= ~LMC_MII16_HSSI_CRC;
        !           321:                sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_16;
        !           322:        }
        !           323:
        !           324:        lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
        !           325: }
        !           326:
        !           327: static void
        !           328: lmc_hssi_watchdog (lmc_softc_t * const sc)
        !           329: {
        !           330:        /* HSSI is blank */
        !           331: }
        !           332:
        !           333: static void
        !           334: lmc_ds3_watchdog (lmc_softc_t * const sc)
        !           335: {
        !           336:        sc->lmc_miireg16 = lmc_mii_readreg (sc, 0, 16);
        !           337:        if (sc->lmc_miireg16 & 0x0018)
        !           338:        {
        !           339:                printf("%s: AIS Received\n", sc->lmc_xname);
        !           340:                lmc_led_on (sc, LMC_DS3_LED1 | LMC_DS3_LED2);
        !           341:        }
        !           342: }
        !           343:
        !           344: /*
        !           345:  *  DS3 methods
        !           346:  */
        !           347:
        !           348: /*
        !           349:  * Set cable length
        !           350:  */
        !           351: static void
        !           352: lmc_ds3_set_100ft(lmc_softc_t * const sc, int ie)
        !           353: {
        !           354:        if (ie == LMC_CTL_CABLE_LENGTH_GT_100FT) {
        !           355:                sc->lmc_miireg16 &= ~LMC_MII16_DS3_ZERO;
        !           356:                sc->ictl.cable_length = LMC_CTL_CABLE_LENGTH_GT_100FT;
        !           357:        } else if (ie == LMC_CTL_CABLE_LENGTH_LT_100FT) {
        !           358:                sc->lmc_miireg16 |= LMC_MII16_DS3_ZERO;
        !           359:                sc->ictl.cable_length = LMC_CTL_CABLE_LENGTH_LT_100FT;
        !           360:        }
        !           361:        lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
        !           362: }
        !           363:
        !           364: static void
        !           365: lmc_ds3_default(lmc_softc_t * const sc)
        !           366: {
        !           367:        sc->lmc_miireg16 = LMC_MII16_LED_ALL;
        !           368:
        !           369:        sc->lmc_media->set_link_status(sc, LMC_LINK_DOWN);
        !           370:        sc->lmc_media->set_cable_length(sc, LMC_CTL_CABLE_LENGTH_LT_100FT);
        !           371:        sc->lmc_media->set_scrambler(sc, LMC_CTL_OFF);
        !           372:        sc->lmc_media->set_crc_length(sc, LMC_CTL_CRC_LENGTH_16);
        !           373: }
        !           374:
        !           375: /*
        !           376:  * Given a user provided state, set ourselves up to match it.  This will
        !           377:  * always reset the card if needed.
        !           378:  */
        !           379: static void
        !           380: lmc_ds3_set_status(lmc_softc_t * const sc, lmc_ctl_t *ctl)
        !           381: {
        !           382:        if (ctl == NULL) {
        !           383:                sc->lmc_media->set_cable_length(sc, sc->ictl.cable_length);
        !           384:                sc->lmc_media->set_scrambler(sc, sc->ictl.scrambler_onoff);
        !           385:                lmc_set_protocol(sc, NULL);
        !           386:
        !           387:                return;
        !           388:        }
        !           389:
        !           390:        /*
        !           391:         * check for change in cable length setting
        !           392:         */
        !           393:        if (ctl->cable_length && !sc->ictl.cable_length)
        !           394:                lmc_ds3_set_100ft(sc, LMC_CTL_CABLE_LENGTH_GT_100FT);
        !           395:        else if (!ctl->cable_length && sc->ictl.cable_length)
        !           396:                lmc_ds3_set_100ft(sc, LMC_CTL_CABLE_LENGTH_LT_100FT);
        !           397:
        !           398:        /*
        !           399:         * Check for change in scrambler setting (requires reset)
        !           400:         */
        !           401:        if (ctl->scrambler_onoff && !sc->ictl.scrambler_onoff)
        !           402:                lmc_ds3_set_scram(sc, LMC_CTL_ON);
        !           403:        else if (!ctl->scrambler_onoff && sc->ictl.scrambler_onoff)
        !           404:                lmc_ds3_set_scram(sc, LMC_CTL_OFF);
        !           405:
        !           406:        lmc_set_protocol(sc, ctl);
        !           407: }
        !           408:
        !           409: static void
        !           410: lmc_ds3_init(lmc_softc_t * const sc)
        !           411: {
        !           412:        int i;
        !           413:
        !           414:        sc->ictl.cardtype = LMC_CTL_CARDTYPE_LMC5245;
        !           415:
        !           416:        /* writes zeros everywhere */
        !           417:        for (i = 0 ; i < 21 ; i++) {
        !           418:                lmc_mii_writereg(sc, 0, 17, i);
        !           419:                lmc_mii_writereg(sc, 0, 18, 0);
        !           420:        }
        !           421:
        !           422:        /* set some essential bits */
        !           423:        lmc_mii_writereg(sc, 0, 17, 1);
        !           424:        lmc_mii_writereg(sc, 0, 18, 0x05);      /* ser, xtx */
        !           425:
        !           426:        lmc_mii_writereg(sc, 0, 17, 5);
        !           427:        lmc_mii_writereg(sc, 0, 18, 0x80);      /* emode */
        !           428:
        !           429:        lmc_mii_writereg(sc, 0, 17, 14);
        !           430:        lmc_mii_writereg(sc, 0, 18, 0x30);      /* rcgen, tcgen */
        !           431:
        !           432:        /* clear counters and latched bits */
        !           433:        for (i = 0 ; i < 21 ; i++) {
        !           434:                lmc_mii_writereg(sc, 0, 17, i);
        !           435:                lmc_mii_readreg(sc, 0, 18);
        !           436:        }
        !           437: }
        !           438:
        !           439: /*
        !           440:  * 1 == DS3 payload scrambled, 0 == not scrambled
        !           441:  */
        !           442: static void
        !           443: lmc_ds3_set_scram(lmc_softc_t * const sc, int ie)
        !           444: {
        !           445:        if (ie == LMC_CTL_ON) {
        !           446:                sc->lmc_miireg16 |= LMC_MII16_DS3_SCRAM;
        !           447:                sc->ictl.scrambler_onoff = LMC_CTL_ON;
        !           448:        } else {
        !           449:                sc->lmc_miireg16 &= ~LMC_MII16_DS3_SCRAM;
        !           450:                sc->ictl.scrambler_onoff = LMC_CTL_OFF;
        !           451:        }
        !           452:        lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
        !           453: }
        !           454:
        !           455: /*
        !           456:  * return hardware link status.
        !           457:  * 0 == link is down, 1 == link is up.
        !           458:  */
        !           459: static int
        !           460: lmc_ds3_get_link_status(lmc_softc_t * const sc)
        !           461: {
        !           462:        u_int16_t link_status;
        !           463:
        !           464:        lmc_mii_writereg(sc, 0, 17, 7);
        !           465:        link_status = lmc_mii_readreg(sc, 0, 18);
        !           466:
        !           467:        if ((link_status & LMC_FRAMER_REG0_DLOS) == 0)
        !           468:                return 1;
        !           469:        else
        !           470:                return 0;
        !           471: }
        !           472:
        !           473: /*
        !           474:  * 0 == 16bit, 1 == 32bit
        !           475:  */
        !           476: static void
        !           477: lmc_ds3_set_crc_length(lmc_softc_t * const sc, int state)
        !           478: {
        !           479:        if (state == LMC_CTL_CRC_LENGTH_32) {
        !           480:                /* 32 bit */
        !           481:                sc->lmc_miireg16 |= LMC_MII16_DS3_CRC;
        !           482:                sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_32;
        !           483:        } else {
        !           484:                /* 16 bit */
        !           485:                sc->lmc_miireg16 &= ~LMC_MII16_DS3_CRC;
        !           486:                sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_16;
        !           487:        }
        !           488:
        !           489:        lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
        !           490: }
        !           491:
        !           492:
        !           493: /*
        !           494:  *  SSI methods
        !           495:  */
        !           496:
        !           497: static void
        !           498: lmc_ssi_init(lmc_softc_t * const sc)
        !           499: {
        !           500:        u_int16_t mii17;
        !           501:        int cable;
        !           502:
        !           503:        sc->ictl.cardtype = LMC_CTL_CARDTYPE_LMC1000;
        !           504:
        !           505:        mii17 = lmc_mii_readreg(sc, 0, 17);
        !           506:
        !           507:         cable = (mii17 & LMC_MII17_SSI_CABLE_MASK) >> LMC_MII17_SSI_CABLE_SHIFT;
        !           508:        sc->ictl.cable_type = cable;
        !           509:
        !           510:         lmc_gpio_mkoutput(sc, LMC_GEP_SSI_TXCLOCK);
        !           511: }
        !           512:
        !           513: static void
        !           514: lmc_ssi_default(lmc_softc_t * const sc)
        !           515: {
        !           516:        sc->lmc_miireg16 = LMC_MII16_LED_ALL;
        !           517:
        !           518:        /*
        !           519:         * make TXCLOCK always be an output
        !           520:         */
        !           521:         lmc_gpio_mkoutput(sc, LMC_GEP_SSI_TXCLOCK);
        !           522:
        !           523:        sc->lmc_media->set_link_status(sc, LMC_LINK_DOWN);
        !           524:        sc->lmc_media->set_clock_source(sc, LMC_CTL_CLOCK_SOURCE_EXT);
        !           525:        sc->lmc_media->set_speed(sc, NULL);
        !           526:        sc->lmc_media->set_crc_length(sc, LMC_CTL_CRC_LENGTH_16);
        !           527: }
        !           528:
        !           529: /*
        !           530:  * Given a user provided state, set ourselves up to match it.  This will
        !           531:  * always reset the card if needed.
        !           532:  */
        !           533: static void
        !           534: lmc_ssi_set_status(lmc_softc_t * const sc, lmc_ctl_t *ctl)
        !           535: {
        !           536:        if (ctl == NULL) {
        !           537:                sc->lmc_media->set_clock_source(sc, sc->ictl.clock_source);
        !           538:                sc->lmc_media->set_speed(sc, &sc->ictl);
        !           539:                lmc_set_protocol(sc, NULL);
        !           540:
        !           541:                return;
        !           542:        }
        !           543:
        !           544:        /*
        !           545:         * check for change in clock source
        !           546:         */
        !           547:        if (ctl->clock_source == LMC_CTL_CLOCK_SOURCE_INT
        !           548:             && sc->ictl.clock_source == LMC_CTL_CLOCK_SOURCE_EXT) {
        !           549:                sc->lmc_media->set_clock_source(sc, LMC_CTL_CLOCK_SOURCE_INT);
        !           550:                sc->lmc_timing = LMC_CTL_CLOCK_SOURCE_INT;
        !           551:         } else if (ctl->clock_source == LMC_CTL_CLOCK_SOURCE_EXT
        !           552:                  && sc->ictl.clock_source == LMC_CTL_CLOCK_SOURCE_INT) {
        !           553:                sc->lmc_media->set_clock_source(sc, LMC_CTL_CLOCK_SOURCE_EXT);
        !           554:                sc->lmc_timing = LMC_CTL_CLOCK_SOURCE_EXT;
        !           555:        }
        !           556:
        !           557:        if (ctl->clock_rate != sc->ictl.clock_rate)
        !           558:                sc->lmc_media->set_speed(sc, ctl);
        !           559:
        !           560:        lmc_set_protocol(sc, ctl);
        !           561: }
        !           562:
        !           563: /*
        !           564:  * 1 == internal, 0 == external
        !           565:  */
        !           566: static void
        !           567: lmc_ssi_set_clock(lmc_softc_t * const sc, int ie)
        !           568: {
        !           569:        if (ie == LMC_CTL_CLOCK_SOURCE_EXT) {
        !           570:                 sc->lmc_gpio &= ~(LMC_GEP_SSI_TXCLOCK);
        !           571:                LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
        !           572:                sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_EXT;
        !           573:                printf(LMC_PRINTF_FMT ": clock external\n",
        !           574:                       LMC_PRINTF_ARGS);
        !           575:        } else {
        !           576:                 sc->lmc_gpio |= LMC_GEP_SSI_TXCLOCK;
        !           577:                LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
        !           578:                sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_INT;
        !           579:                printf(LMC_PRINTF_FMT ": clock internal\n",
        !           580:                       LMC_PRINTF_ARGS);
        !           581:        }
        !           582: }
        !           583:
        !           584: static void
        !           585: lmc_ssi_set_speed(lmc_softc_t * const sc, lmc_ctl_t *ctl)
        !           586: {
        !           587:        lmc_ctl_t *ictl = &sc->ictl;
        !           588:        lmc_av9110_t *av;
        !           589:
        !           590:         /* original settings for clock rate of:
        !           591:          *  100 KHz (8,25,0,0,2) were incorrect
        !           592:          *  they should have been 80,125,1,3,3
        !           593:          *  There are 17 param combinations to produce this freq.
        !           594:          *  For 1.5 MHz use 120,100,1,1,2 (226 param. combinations)
        !           595:          */
        !           596:        if (ctl == NULL) {
        !           597:                 av = &ictl->cardspec.ssi;
        !           598:                 ictl->clock_rate = 1500000;
        !           599:                av->f = ictl->clock_rate;
        !           600:                 av->n = 120;
        !           601:                 av->m = 100;
        !           602:                 av->v = 1;
        !           603:                 av->x = 1;
        !           604:                av->r = 2;
        !           605:
        !           606:                write_av9110(sc, av->n, av->m, av->v, av->x, av->r);
        !           607:                return;
        !           608:        }
        !           609:
        !           610:         av = &ctl->cardspec.ssi;
        !           611:
        !           612:        if (av->f == 0)
        !           613:                return;
        !           614:
        !           615:        ictl->clock_rate = av->f;  /* really, this is the rate we are */
        !           616:         ictl->cardspec.ssi = *av;
        !           617:
        !           618:        write_av9110(sc, av->n, av->m, av->v, av->x, av->r);
        !           619: }
        !           620:
        !           621: /*
        !           622:  * return hardware link status.
        !           623:  * 0 == link is down, 1 == link is up.
        !           624:  */
        !           625: static int
        !           626: lmc_ssi_get_link_status(lmc_softc_t * const sc)
        !           627: {
        !           628:        u_int16_t link_status;
        !           629:
        !           630:        /*
        !           631:         * missing CTS?  Hmm.  If we require CTS on, we may never get the
        !           632:         * link to come up, so omit it in this test.
        !           633:         *
        !           634:         * Also, it seems that with a loopback cable, DCD isn't asserted,
        !           635:         * so just check for things like this:
        !           636:         *      DSR _must_ be asserted.
        !           637:         *      One of DCD or CTS must be asserted.
        !           638:         */
        !           639:
        !           640: #ifdef CONFIG_LMC_IGNORE_HARDWARE_HANDSHAKE
        !           641:         link_status = LMC_CSR_READ(sc, csr_gp_timer);
        !           642:         link_status = 0x0000ffff - ( link_status & 0x0000ffff);
        !           643:
        !           644:         return( link_status );
        !           645: #else
        !           646:
        !           647:        link_status = lmc_mii_readreg(sc, 0, 16);
        !           648:
        !           649:         if ((link_status & LMC_MII16_SSI_DSR) == 0)
        !           650:                return (0);
        !           651:
        !           652:         if ((link_status & (LMC_MII16_SSI_CTS | LMC_MII16_SSI_DCD)) == 0)
        !           653:                return (0);
        !           654:
        !           655:        return (1);
        !           656: #endif
        !           657: }
        !           658:
        !           659: static void
        !           660: lmc_ssi_set_link_status(lmc_softc_t * const sc, int state)
        !           661: {
        !           662:        if (state == LMC_LINK_UP) {
        !           663:                 sc->lmc_miireg16 |= (LMC_MII16_SSI_DTR | LMC_MII16_SSI_RTS);
        !           664:                printf(LMC_PRINTF_FMT ": asserting DTR and RTS\n",
        !           665:                       LMC_PRINTF_ARGS);
        !           666:        } else {
        !           667:                 sc->lmc_miireg16 &= ~(LMC_MII16_SSI_DTR | LMC_MII16_SSI_RTS);
        !           668:                printf(LMC_PRINTF_FMT ": deasserting DTR and RTS\n",
        !           669:                       LMC_PRINTF_ARGS);
        !           670:        }
        !           671:
        !           672:        lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
        !           673:
        !           674: }
        !           675:
        !           676: /*
        !           677:  * 0 == 16bit, 1 == 32bit
        !           678:  */
        !           679: static void
        !           680: lmc_ssi_set_crc_length(lmc_softc_t * const sc, int state)
        !           681: {
        !           682:        if (state == LMC_CTL_CRC_LENGTH_32) {
        !           683:                /* 32 bit */
        !           684:                 sc->lmc_miireg16 |= LMC_MII16_SSI_CRC;
        !           685:                sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_32;
        !           686:                 sc->lmc_crcSize = LMC_CTL_CRC_BYTESIZE_4;
        !           687:
        !           688:        } else {
        !           689:                /* 16 bit */
        !           690:                 sc->lmc_miireg16 &= ~LMC_MII16_SSI_CRC;
        !           691:                sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_16;
        !           692:                 sc->lmc_crcSize = LMC_CTL_CRC_BYTESIZE_2;
        !           693:        }
        !           694:
        !           695:        lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
        !           696: }
        !           697:
        !           698: /*
        !           699:  * These are bits to program the ssi frequency generator
        !           700:  */
        !           701: static inline void
        !           702: write_av9110_bit(lmc_softc_t *sc, int c)
        !           703: {
        !           704:        /*
        !           705:         * set the data bit as we need it.
        !           706:         */
        !           707:        sc->lmc_gpio &= ~(LMC_GEP_SERIALCLK);
        !           708:        if (c & 0x01)
        !           709:                sc->lmc_gpio |= LMC_GEP_SERIAL;
        !           710:        else
        !           711:                sc->lmc_gpio &= ~(LMC_GEP_SERIAL);
        !           712:        LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
        !           713:
        !           714:        /*
        !           715:         * set the clock to high
        !           716:         */
        !           717:        sc->lmc_gpio |= LMC_GEP_SERIALCLK;
        !           718:        LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
        !           719:
        !           720:        /*
        !           721:         * set the clock to low again.
        !           722:         */
        !           723:        sc->lmc_gpio &= ~(LMC_GEP_SERIALCLK);
        !           724:        LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
        !           725: }
        !           726:
        !           727: static void
        !           728: write_av9110(lmc_softc_t *sc, u_int32_t n, u_int32_t m, u_int32_t v,
        !           729:             u_int32_t x, u_int32_t r)
        !           730: {
        !           731:        int i;
        !           732:
        !           733: #if 0
        !           734:        printf(LMC_PRINTF_FMT ": speed %u, %d %d %d %d %d\n",
        !           735:               LMC_PRINTF_ARGS, sc->ictl.clock_rate,
        !           736:               n, m, v, x, r);
        !           737: #endif
        !           738:
        !           739:         sc->lmc_gpio |= LMC_GEP_SSI_GENERATOR;
        !           740:        sc->lmc_gpio &= ~(LMC_GEP_SERIAL | LMC_GEP_SERIALCLK);
        !           741:        LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
        !           742:
        !           743:        /*
        !           744:         * Set the TXCLOCK, GENERATOR, SERIAL, and SERIALCLK
        !           745:         * as outputs.
        !           746:         */
        !           747:        lmc_gpio_mkoutput(sc, (LMC_GEP_SERIAL | LMC_GEP_SERIALCLK
        !           748:                                | LMC_GEP_SSI_GENERATOR));
        !           749:
        !           750:         sc->lmc_gpio &= ~(LMC_GEP_SSI_GENERATOR);
        !           751:        LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
        !           752:
        !           753:        /*
        !           754:         * a shifting we will go...
        !           755:         */
        !           756:        for (i = 0 ; i < 7 ; i++)
        !           757:                write_av9110_bit(sc, n >> i);
        !           758:        for (i = 0 ; i < 7 ; i++)
        !           759:                write_av9110_bit(sc, m >> i);
        !           760:        for (i = 0 ; i < 1 ; i++)
        !           761:                write_av9110_bit(sc, v >> i);
        !           762:        for (i = 0 ; i < 2 ; i++)
        !           763:                write_av9110_bit(sc, x >> i);
        !           764:        for (i = 0 ; i < 2 ; i++)
        !           765:                write_av9110_bit(sc, r >> i);
        !           766:        for (i = 0 ; i < 5 ; i++)
        !           767:                write_av9110_bit(sc, 0x17 >> i);
        !           768:
        !           769:        /*
        !           770:         * stop driving serial-related signals
        !           771:         */
        !           772:        lmc_gpio_mkinput(sc,
        !           773:                         (LMC_GEP_SERIAL | LMC_GEP_SERIALCLK
        !           774:                           | LMC_GEP_SSI_GENERATOR));
        !           775: }
        !           776:
        !           777: static void
        !           778: lmc_ssi_watchdog (lmc_softc_t * const sc)
        !           779: {
        !           780:        u_int16_t mii17;
        !           781:        struct ssicsr2 {
        !           782:                unsigned short dtr:1, dsr:1, rts:1, cable:3, crc:1, led0:1,
        !           783:                led1:1, led2:1, led3:1, fifo:1, ll:1, rl:1, tm:1, loop:1;
        !           784:        };
        !           785:        struct ssicsr2 *ssicsr;
        !           786:        mii17 = lmc_mii_readreg (sc, 0, 17);
        !           787:        ssicsr = (struct ssicsr2 *) &mii17;
        !           788:        if (ssicsr->cable == 7) {
        !           789:                lmc_led_off (sc, LMC_MII16_LED2);
        !           790:        }
        !           791:        else {
        !           792:                lmc_led_on (sc, LMC_MII16_LED2);
        !           793:        }
        !           794:
        !           795: }
        !           796:
        !           797:
        !           798: /*
        !           799:  *  T1 methods
        !           800:  */
        !           801:
        !           802: /*
        !           803:  * The framer regs are multiplexed through MII regs 17 & 18
        !           804:  *  write the register address to MII reg 17 and the *  data to MII reg 18. */
        !           805: static void lmc_t1_write(lmc_softc_t * const sc, int a, int d)
        !           806: {
        !           807:         lmc_mii_writereg(sc, 0, 17, a);
        !           808:        lmc_mii_writereg(sc, 0, 18, d);
        !           809: }
        !           810:
        !           811: static int lmc_t1_read(lmc_softc_t * const sc, int a)
        !           812: {
        !           813:        lmc_mii_writereg(sc, 0, 17, a);
        !           814:        return lmc_mii_readreg(sc, 0, 18);
        !           815: }
        !           816:
        !           817: static void
        !           818:    lmc_t1_init(lmc_softc_t * const sc)
        !           819: {
        !           820:         u_int16_t mii16;
        !           821:         int     i;
        !           822:
        !           823:         sc->ictl.cardtype = LMC_CTL_CARDTYPE_LMC1200;
        !           824:         mii16 = lmc_mii_readreg(sc, 0, 16);
        !           825:
        !           826:        mii16 &= ~LMC_MII16_T1_XOE;
        !           827:        lmc_mii_writereg (sc, 0, 16, mii16);
        !           828:        sc->lmc_miireg16 = mii16;
        !           829:
        !           830:         /* reset 8370 */
        !           831:         mii16 &= ~LMC_MII16_T1_RST;
        !           832:         lmc_mii_writereg(sc, 0, 16, mii16 | LMC_MII16_T1_RST);
        !           833:         lmc_mii_writereg(sc, 0, 16, mii16);
        !           834:
        !           835:         /* set T1 or E1 line impedance */
        !           836:         /* mii16 &= ~LMC_MII16_T1_Z; */
        !           837:         mii16 |= LMC_MII16_T1_Z;
        !           838:         lmc_mii_writereg(sc, 0, 16, mii16);
        !           839:
        !           840:        /* Standard LMC1200 init code */
        !           841:         lmc_t1_write(sc, 0x01, 0x1B);  /* CR0     - primary control          */
        !           842:         lmc_t1_write(sc, 0x02, 0x42);  /* JAT_CR  - jitter atten config      */
        !           843:         lmc_t1_write(sc, 0x14, 0x00);  /* LOOP    - loopback config          */
        !           844:         lmc_t1_write(sc, 0x15, 0x00);  /* DL3_TS  - xtrnl datalink timeslot  */
        !           845:         lmc_t1_write(sc, 0x18, 0xFF);  /* PIO     - programmable I/O         */
        !           846:         lmc_t1_write(sc, 0x19, 0x30);  /* POE     - programmable OE          */
        !           847:         lmc_t1_write(sc, 0x1A, 0x0F);  /* CMUX    - clock input mux          */
        !           848:         lmc_t1_write(sc, 0x20, 0x41);  /* LIU_CR  - RX LIU config            */
        !           849:         lmc_t1_write(sc, 0x22, 0x76);  /* RLIU_CR - RX LIU config            */
        !           850:         lmc_t1_write(sc, 0x40, 0x03);  /* RCR0    - RX config                */
        !           851:         lmc_t1_write(sc, 0x45, 0x00);  /* RALM    - RX alarm config          */
        !           852:         lmc_t1_write(sc, 0x46, 0x05);  /* LATCH   - RX alarm/err/cntr latch  */
        !           853:         lmc_t1_write(sc, 0x68, 0x40);  /* TLIU_CR - TX LIU config            */
        !           854:         lmc_t1_write(sc, 0x70, 0x0D);  /* TCR0    - TX framer config         */
        !           855:         lmc_t1_write(sc, 0x71, 0x05);  /* TCR1    - TX config                */
        !           856:         lmc_t1_write(sc, 0x72, 0x0B);  /* TFRM    - TX frame format          */
        !           857:         lmc_t1_write(sc, 0x73, 0x00);  /* TERROR  - TX error insert          */
        !           858:         lmc_t1_write(sc, 0x74, 0x00);  /* TMAN    - TX manual Sa/FEBE config */
        !           859:         lmc_t1_write(sc, 0x75, 0x00);  /* TALM    - TX alarm signal config   */
        !           860:         lmc_t1_write(sc, 0x76, 0x00);  /* TPATT   - TX test pattern config   */
        !           861:         lmc_t1_write(sc, 0x77, 0x00);  /* TLB     - TX inband loopback confg */
        !           862:         lmc_t1_write(sc, 0x90, 0x05);  /* CLAD_CR - clock rate adapter confg */
        !           863:         lmc_t1_write(sc, 0x91, 0x05);  /* CSEL    - clad freq sel            */
        !           864:         lmc_t1_write(sc, 0xA6, 0x00);  /* DL1_CTL - DL1 control              */
        !           865:         lmc_t1_write(sc, 0xB1, 0x00);  /* DL2_CTL - DL2 control              */
        !           866:         lmc_t1_write(sc, 0xD0, 0x47);  /* SBI_CR  - sys bus iface config     */
        !           867:         lmc_t1_write(sc, 0xD1, 0x70);  /* RSB_CR  - RX sys bus config        */
        !           868:         lmc_t1_write(sc, 0xD4, 0x30);  /* TSB_CR  - TX sys bus config        */
        !           869:         for (i=0; i<32; i++)
        !           870:         {
        !           871:                 lmc_t1_write(sc, 0x0E0+i, 0x00); /*SBCn sysbus perchannel ctl */
        !           872:                 lmc_t1_write(sc, 0x100+i, 0x00); /* TPCn - TX per-channel ctl */
        !           873:                 lmc_t1_write(sc, 0x180+i, 0x00); /* RPCn - RX per-channel ctl */
        !           874:         }
        !           875:         for (i=1; i<25; i++)
        !           876:        {                lmc_t1_write(sc, 0x0E0+i, 0x0D);
        !           877:                                        /* SBCn - sys bus per-channel ctl    */
        !           878:        }
        !           879:
        !           880:        mii16 |= LMC_MII16_T1_XOE;
        !           881:        lmc_mii_writereg(sc, 0, 16, mii16);
        !           882:         sc->lmc_miireg16 = mii16;
        !           883: }
        !           884:
        !           885: static void   lmc_t1_default(lmc_softc_t * const sc)
        !           886: {
        !           887:         sc->lmc_miireg16 = LMC_MII16_LED_ALL;
        !           888:         sc->lmc_media->set_link_status(sc, LMC_LINK_DOWN);
        !           889:         sc->lmc_media->set_circuit_type(sc, LMC_CTL_CIRCUIT_TYPE_T1);
        !           890:         sc->lmc_media->set_crc_length(sc, LMC_CTL_CRC_LENGTH_16);
        !           891: }
        !           892:
        !           893: /*
        !           894:  * Given a user provided state, set ourselves up to match it.  This will
        !           895:  * always reset the card if needed.
        !           896:  */
        !           897:
        !           898: static void
        !           899: lmc_t1_set_status(lmc_softc_t * const sc, lmc_ctl_t *ctl){
        !           900:        if (ctl == NULL) {
        !           901:                sc->lmc_media->set_circuit_type(sc, sc->ictl.circuit_type);
        !           902:                lmc_set_protocol(sc, NULL);
        !           903:
        !           904:                return;
        !           905:        }
        !           906:
        !           907:         /*
        !           908:          * check for change in circuit type
        !           909:         */
        !           910:
        !           911:        if (ctl->circuit_type == LMC_CTL_CIRCUIT_TYPE_T1
        !           912:                && sc->ictl.circuit_type == LMC_CTL_CIRCUIT_TYPE_E1)
        !           913:                sc->lmc_media->set_circuit_type(sc,LMC_CTL_CIRCUIT_TYPE_E1 );
        !           914:        else if (ctl->circuit_type == LMC_CTL_CIRCUIT_TYPE_E1
        !           915:                && sc->ictl.circuit_type == LMC_CTL_CIRCUIT_TYPE_T1)
        !           916:                sc->lmc_media->set_circuit_type(sc, LMC_CTL_CIRCUIT_TYPE_T1);
        !           917:        lmc_set_protocol(sc, ctl);
        !           918: }
        !           919:
        !           920: /*
        !           921:  * return hardware link status.
        !           922:  * 0 == link is down, 1 == link is up.
        !           923:  */
        !           924:
        !           925: static int
        !           926: lmc_t1_get_link_status(lmc_softc_t * const sc){
        !           927:        u_int16_t link_status;
        !           928:        lmc_mii_writereg(sc, 0, 17, T1FRAMER_ALARM1_STATUS );
        !           929:        link_status = lmc_mii_readreg(sc, 0, 18);
        !           930:
        !           931:         /*
        !           932:         * LMC 1200 LED definitions
        !           933:          * led0 yellow = far-end adapter is in Red alarm condition
        !           934:         * led1 blue = received an Alarm Indication signal (upstream failure)
        !           935:          * led2 Green = power to adapter, Gate Array loaded & driver attached
        !           936:          * led3 red = Loss of Signal (LOS) or out of frame (OOF) conditions
        !           937:         * detected on T3 receive signal
        !           938:          */
        !           939:
        !           940:         /* detect a change in Blue alarm indication signal */
        !           941:
        !           942:         if( (sc->t1_alarm1_status & T1F_RAIS) != (link_status & T1F_RAIS) )
        !           943:         {
        !           944:                 if( link_status & T1F_RAIS )
        !           945:                 {                        /* turn on blue LED */
        !           946:                         printf("%s: link status: RAIS turn ON Blue %x\n", sc->lmc_xname, link_status); /* DEBUG */
        !           947:                         lmc_led_on(sc, LMC_DS3_LED1);
        !           948:                 }
        !           949:                 else
        !           950:                 {                        /* turn off blue LED */
        !           951:                         printf("%s: link status: RAIS turn OFF Blue %x\n", sc->lmc_xname, link_status ); /* DEBUG */
        !           952:                        lmc_led_off(sc, LMC_DS3_LED1);
        !           953:                 }
        !           954:        }
        !           955:         /*
        !           956:         * T1F_RYEL wiggles quite a bit,
        !           957:         *  taking it out until I understand why -baz 6/22/99
        !           958:          */
        !           959:                 /* Yellow alarm indication */
        !           960:                 if( (sc->t1_alarm1_status &  T1F_RMYEL) !=
        !           961:                         (link_status & T1F_RMYEL) )
        !           962:                 {
        !           963:                if( (link_status & (T1F_RYEL | T1F_RMYEL)) == 0 )
        !           964:                         {
        !           965:                                /* turn off yellow LED */
        !           966:                                        printf("%s: link status: RYEL turn OFF Yellow %x\n", sc->lmc_xname, link_status); /* DEBUG */
        !           967:                                lmc_led_off(sc, LMC_DS3_LED0);
        !           968:
        !           969:                         }
        !           970:                         else
        !           971:                         {
        !           972:                                 /* turn on yellow LED */
        !           973:                                 printf("%s: link status: RYEL turn ON Yellow %x\n", sc->lmc_xname, link_status); /* DEBUG */
        !           974:                                 lmc_led_on(sc, LMC_DS3_LED0);
        !           975:                         }
        !           976:                 }
        !           977:
        !           978:
        !           979:         sc->t1_alarm1_status = link_status;
        !           980:
        !           981:         lmc_mii_writereg(sc, 0, 17, T1FRAMER_ALARM2_STATUS );
        !           982:         sc->t1_alarm2_status = lmc_mii_readreg(sc, 0, 18);
        !           983:
        !           984:         /* link status based upon T1 receive loss of frame or
        !           985:          * loss of signal - RED alarm indication */
        !           986:         if ((link_status & (T1F_RLOF | T1F_RLOS)) == 0)
        !           987:                 return 1;
        !           988:         else
        !           989:                 return 0;
        !           990: }
        !           991:
        !           992: /*
        !           993:  * 1 == T1 Circuit Type , 0 == E1 Circuit Type
        !           994:  */
        !           995: static void
        !           996:    lmc_t1_set_circuit_type(lmc_softc_t * const sc, int ie)
        !           997: {
        !           998:         if (ie == LMC_CTL_CIRCUIT_TYPE_T1)
        !           999:         {
        !          1000:                 sc->lmc_miireg16 |= LMC_MII16_T1_Z;
        !          1001:                 sc->ictl.circuit_type = LMC_CTL_CIRCUIT_TYPE_T1;
        !          1002:         } else {                sc->lmc_miireg16 &= ~LMC_MII16_T1_Z;
        !          1003:                 sc->ictl.scrambler_onoff = LMC_CTL_CIRCUIT_TYPE_E1;
        !          1004:         }
        !          1005:         lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
        !          1006: }
        !          1007:
        !          1008: /*
        !          1009:  * 0 == 16bit, 1 == 32bit */
        !          1010: static void
        !          1011:    lmc_t1_set_crc_length(lmc_softc_t * const sc, int state)
        !          1012: {
        !          1013:         if (state == LMC_CTL_CRC_LENGTH_32) {
        !          1014:                 /* 32 bit */
        !          1015:                 sc->lmc_miireg16 |= LMC_MII16_T1_CRC;
        !          1016:                 sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_32;
        !          1017:                 sc->lmc_crcSize = LMC_CTL_CRC_BYTESIZE_4;
        !          1018:
        !          1019:         } else {
        !          1020:                 /* 16 bit */
        !          1021:                 sc->lmc_miireg16 &= ~LMC_MII16_T1_CRC;
        !          1022:                 sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_16;
        !          1023:                 sc->lmc_crcSize = LMC_CTL_CRC_BYTESIZE_2;
        !          1024:
        !          1025:         }
        !          1026:
        !          1027:         lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
        !          1028: }
        !          1029:
        !          1030: /*
        !          1031:  * 1 == internal, 0 == external
        !          1032:  */
        !          1033: static void
        !          1034: lmc_t1_set_clock (lmc_softc_t * const sc, int ie)
        !          1035: {
        !          1036:        if (ie == LMC_CTL_CLOCK_SOURCE_EXT) {
        !          1037:                sc->lmc_gpio &= ~(LMC_GEP_SSI_TXCLOCK);
        !          1038:                LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio);
        !          1039:                sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_EXT;
        !          1040:                printf (LMC_PRINTF_FMT ": clock external\n", LMC_PRINTF_ARGS);
        !          1041:        }
        !          1042:        else {
        !          1043:                sc->lmc_gpio |= LMC_GEP_SSI_TXCLOCK;
        !          1044:                LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio);
        !          1045:                sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_INT;
        !          1046:                printf (LMC_PRINTF_FMT ": clock internal\n", LMC_PRINTF_ARGS);
        !          1047:        }
        !          1048: }
        !          1049:
        !          1050: static void
        !          1051: lmc_t1_watchdog(lmc_softc_t * const sc)
        !          1052: {
        !          1053:        int t1stat;
        !          1054:
        !          1055:        /* read alarm 1 status (receive) */
        !          1056:        t1stat = lmc_t1_read (sc, 0x47);
        !          1057:        /* blue alarm -- RAIS */
        !          1058:        if (t1stat & 0x08) {
        !          1059:                if (sc->lmc_blue != 1)
        !          1060:                        printf ("%s: AIS Received\n", sc->lmc_xname);
        !          1061:                lmc_led_on (sc, LMC_DS3_LED1 | LMC_DS3_LED2);
        !          1062:                sc->lmc_blue = 1;
        !          1063:        } else {
        !          1064:                if (sc->lmc_blue == 1)
        !          1065:                        printf ("%s: AIS ok\n", sc->lmc_xname);
        !          1066:                lmc_led_off (sc, LMC_DS3_LED1);
        !          1067:                lmc_led_on (sc, LMC_DS3_LED2);
        !          1068:                sc->lmc_blue = 0;
        !          1069:        }
        !          1070:
        !          1071:        /* Red alarm -- LOS | LOF */
        !          1072:        if (t1stat & 0x04) {
        !          1073:                /* Only print the error once */
        !          1074:                if (sc->lmc_red != 1)
        !          1075:                        printf ("%s: Red Alarm\n", sc->lmc_xname);
        !          1076:                lmc_led_on (sc, LMC_DS3_LED2 | LMC_DS3_LED3);
        !          1077:                sc->lmc_red = 1;
        !          1078:        } else {
        !          1079:                if (sc->lmc_red == 1)
        !          1080:                        printf ("%s: Red Alarm ok\n", sc->lmc_xname);
        !          1081:        lmc_led_off (sc, LMC_DS3_LED3);
        !          1082:        lmc_led_on (sc, LMC_DS3_LED2);
        !          1083:        sc->lmc_red = 0;
        !          1084:        }
        !          1085:
        !          1086:        /* check for Receive Multiframe Yellow Alarm
        !          1087:         * Ignore Receive Yellow Alarm
        !          1088:         */
        !          1089:        if (t1stat & 0x80) {
        !          1090:                if (sc->lmc_yel != 1) {
        !          1091:                        printf ("%s: Receive Yellow Alarm\n", sc->lmc_xname);
        !          1092:                }
        !          1093:                        lmc_led_on (sc, LMC_DS3_LED0 | LMC_DS3_LED2);
        !          1094:                        sc->lmc_yel = 1;
        !          1095:        }
        !          1096:        else {
        !          1097:                if (sc->lmc_yel == 1)
        !          1098:                printf ("%s: Yellow Alarm ok\n", sc->lmc_xname);
        !          1099:                lmc_led_off (sc, LMC_DS3_LED0);
        !          1100:                lmc_led_on (sc, LMC_DS3_LED2);
        !          1101:                sc->lmc_yel = 0;
        !          1102:        }
        !          1103: }
        !          1104:
        !          1105:
        !          1106: static void
        !          1107: lmc_set_protocol(lmc_softc_t * const sc, lmc_ctl_t *ctl)
        !          1108: {
        !          1109:        if (ctl == 0) {
        !          1110:                sc->ictl.keepalive_onoff = LMC_CTL_ON;
        !          1111:
        !          1112:                return;
        !          1113:        }
        !          1114:
        !          1115:        if (ctl->keepalive_onoff != sc->ictl.keepalive_onoff) {
        !          1116:                switch (ctl->keepalive_onoff) {
        !          1117:                case LMC_CTL_ON:
        !          1118:                        printf(LMC_PRINTF_FMT ": enabling keepalive\n",
        !          1119:                               LMC_PRINTF_ARGS);
        !          1120:                        sc->ictl.keepalive_onoff = LMC_CTL_ON;
        !          1121:                        sc->lmc_sppp.pp_flags = PP_CISCO | PP_KEEPALIVE;
        !          1122:                        break;
        !          1123:                case LMC_CTL_OFF:
        !          1124:                        printf(LMC_PRINTF_FMT ": disabling keepalive\n",
        !          1125:                               LMC_PRINTF_ARGS);
        !          1126:                        sc->ictl.keepalive_onoff = LMC_CTL_OFF;
        !          1127:                        sc->lmc_sppp.pp_flags = PP_CISCO;
        !          1128:                }
        !          1129:        }
        !          1130: }

CVSweb