[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

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