root/dev/pci/if_lmc_media.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. lmc_dummy_set_1
  2. lmc_dummy_set2_1
  3. lmc_hssi_init
  4. lmc_hssi_default
  5. lmc_hssi_set_status
  6. lmc_hssi_set_clock
  7. lmc_hssi_get_link_status
  8. lmc_hssi_set_link_status
  9. lmc_hssi_set_crc_length
  10. lmc_hssi_watchdog
  11. lmc_ds3_watchdog
  12. lmc_ds3_set_100ft
  13. lmc_ds3_default
  14. lmc_ds3_set_status
  15. lmc_ds3_init
  16. lmc_ds3_set_scram
  17. lmc_ds3_get_link_status
  18. lmc_ds3_set_crc_length
  19. lmc_ssi_init
  20. lmc_ssi_default
  21. lmc_ssi_set_status
  22. lmc_ssi_set_clock
  23. lmc_ssi_set_speed
  24. lmc_ssi_get_link_status
  25. lmc_ssi_set_link_status
  26. lmc_ssi_set_crc_length
  27. write_av9110_bit
  28. write_av9110
  29. lmc_ssi_watchdog
  30. lmc_t1_write
  31. lmc_t1_read
  32. lmc_t1_init
  33. lmc_t1_default
  34. lmc_t1_set_status
  35. lmc_t1_get_link_status
  36. lmc_t1_set_circuit_type
  37. lmc_t1_set_crc_length
  38. lmc_t1_set_clock
  39. lmc_t1_watchdog
  40. lmc_set_protocol

    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 }

/* [<][>][^][v][top][bottom][index][help] */