1/* $Id: lmc_media.c,v 1.1.1.1 2007/08/03 18:52:49 Exp $ */ 2 3#include <linux/kernel.h> 4#include <linux/string.h> 5#include <linux/timer.h> 6#include <linux/ptrace.h> 7#include <linux/errno.h> 8#include <linux/ioport.h> 9#include <linux/slab.h> 10#include <linux/interrupt.h> 11#include <linux/in.h> 12#include <linux/if_arp.h> 13#include <linux/netdevice.h> 14#include <linux/etherdevice.h> 15#include <linux/skbuff.h> 16#include <linux/inet.h> 17#include <linux/bitops.h> 18 19#include <net/syncppp.h> 20 21#include <asm/processor.h> /* Processor type for cache alignment. */ 22#include <asm/io.h> 23#include <asm/dma.h> 24 25#include <asm/uaccess.h> 26 27#include "lmc.h" 28#include "lmc_var.h" 29#include "lmc_ioctl.h" 30#include "lmc_debug.h" 31 32#define CONFIG_LMC_IGNORE_HARDWARE_HANDSHAKE 1 33 34 /* 35 * Copyright (c) 1997-2000 LAN Media Corporation (LMC) 36 * All rights reserved. www.lanmedia.com 37 * 38 * This code is written by: 39 * Andrew Stanley-Jones (asj@cban.com) 40 * Rob Braun (bbraun@vix.com), 41 * Michael Graff (explorer@vix.com) and 42 * Matt Thomas (matt@3am-software.com). 43 * 44 * This software may be used and distributed according to the terms 45 * of the GNU General Public License version 2, incorporated herein by reference. 46 */ 47 48/* 49 * protocol independent method. 50 */ 51static void lmc_set_protocol (lmc_softc_t * const, lmc_ctl_t *); 52 53/* 54 * media independent methods to check on media status, link, light LEDs, 55 * etc. 56 */ 57static void lmc_ds3_init (lmc_softc_t * const); 58static void lmc_ds3_default (lmc_softc_t * const); 59static void lmc_ds3_set_status (lmc_softc_t * const, lmc_ctl_t *); 60static void lmc_ds3_set_100ft (lmc_softc_t * const, int); 61static int lmc_ds3_get_link_status (lmc_softc_t * const); 62static void lmc_ds3_set_crc_length (lmc_softc_t * const, int); 63static void lmc_ds3_set_scram (lmc_softc_t * const, int); 64static void lmc_ds3_watchdog (lmc_softc_t * const); 65 66static void lmc_hssi_init (lmc_softc_t * const); 67static void lmc_hssi_default (lmc_softc_t * const); 68static void lmc_hssi_set_status (lmc_softc_t * const, lmc_ctl_t *); 69static void lmc_hssi_set_clock (lmc_softc_t * const, int); 70static int lmc_hssi_get_link_status (lmc_softc_t * const); 71static void lmc_hssi_set_link_status (lmc_softc_t * const, int); 72static void lmc_hssi_set_crc_length (lmc_softc_t * const, int); 73static void lmc_hssi_watchdog (lmc_softc_t * const); 74 75static void lmc_ssi_init (lmc_softc_t * const); 76static void lmc_ssi_default (lmc_softc_t * const); 77static void lmc_ssi_set_status (lmc_softc_t * const, lmc_ctl_t *); 78static void lmc_ssi_set_clock (lmc_softc_t * const, int); 79static void lmc_ssi_set_speed (lmc_softc_t * const, lmc_ctl_t *); 80static int lmc_ssi_get_link_status (lmc_softc_t * const); 81static void lmc_ssi_set_link_status (lmc_softc_t * const, int); 82static void lmc_ssi_set_crc_length (lmc_softc_t * const, int); 83static void lmc_ssi_watchdog (lmc_softc_t * const); 84 85static void lmc_t1_init (lmc_softc_t * const); 86static void lmc_t1_default (lmc_softc_t * const); 87static void lmc_t1_set_status (lmc_softc_t * const, lmc_ctl_t *); 88static int lmc_t1_get_link_status (lmc_softc_t * const); 89static void lmc_t1_set_circuit_type (lmc_softc_t * const, int); 90static void lmc_t1_set_crc_length (lmc_softc_t * const, int); 91static void lmc_t1_set_clock (lmc_softc_t * const, int); 92static void lmc_t1_watchdog (lmc_softc_t * const); 93 94static void lmc_dummy_set_1 (lmc_softc_t * const, int); 95static void lmc_dummy_set2_1 (lmc_softc_t * const, lmc_ctl_t *); 96 97static inline void write_av9110_bit (lmc_softc_t *, int); 98static void write_av9110 (lmc_softc_t *, u_int32_t, u_int32_t, u_int32_t, 99 u_int32_t, u_int32_t); 100 101lmc_media_t lmc_ds3_media = { 102 lmc_ds3_init, /* special media init stuff */ 103 lmc_ds3_default, /* reset to default state */ 104 lmc_ds3_set_status, /* reset status to state provided */ 105 lmc_dummy_set_1, /* set clock source */ 106 lmc_dummy_set2_1, /* set line speed */ 107 lmc_ds3_set_100ft, /* set cable length */ 108 lmc_ds3_set_scram, /* set scrambler */ 109 lmc_ds3_get_link_status, /* get link status */ 110 lmc_dummy_set_1, /* set link status */ 111 lmc_ds3_set_crc_length, /* set CRC length */ 112 lmc_dummy_set_1, /* set T1 or E1 circuit type */ 113 lmc_ds3_watchdog 114}; 115 116lmc_media_t lmc_hssi_media = { 117 lmc_hssi_init, /* special media init stuff */ 118 lmc_hssi_default, /* reset to default state */ 119 lmc_hssi_set_status, /* reset status to state provided */ 120 lmc_hssi_set_clock, /* set clock source */ 121 lmc_dummy_set2_1, /* set line speed */ 122 lmc_dummy_set_1, /* set cable length */ 123 lmc_dummy_set_1, /* set scrambler */ 124 lmc_hssi_get_link_status, /* get link status */ 125 lmc_hssi_set_link_status, /* set link status */ 126 lmc_hssi_set_crc_length, /* set CRC length */ 127 lmc_dummy_set_1, /* set T1 or E1 circuit type */ 128 lmc_hssi_watchdog 129}; 130 131lmc_media_t lmc_ssi_media = { lmc_ssi_init, /* special media init stuff */ 132 lmc_ssi_default, /* reset to default state */ 133 lmc_ssi_set_status, /* reset status to state provided */ 134 lmc_ssi_set_clock, /* set clock source */ 135 lmc_ssi_set_speed, /* set line speed */ 136 lmc_dummy_set_1, /* set cable length */ 137 lmc_dummy_set_1, /* set scrambler */ 138 lmc_ssi_get_link_status, /* get link status */ 139 lmc_ssi_set_link_status, /* set link status */ 140 lmc_ssi_set_crc_length, /* set CRC length */ 141 lmc_dummy_set_1, /* set T1 or E1 circuit type */ 142 lmc_ssi_watchdog 143}; 144 145lmc_media_t lmc_t1_media = { 146 lmc_t1_init, /* special media init stuff */ 147 lmc_t1_default, /* reset to default state */ 148 lmc_t1_set_status, /* reset status to state provided */ 149 lmc_t1_set_clock, /* set clock source */ 150 lmc_dummy_set2_1, /* set line speed */ 151 lmc_dummy_set_1, /* set cable length */ 152 lmc_dummy_set_1, /* set scrambler */ 153 lmc_t1_get_link_status, /* get link status */ 154 lmc_dummy_set_1, /* set link status */ 155 lmc_t1_set_crc_length, /* set CRC length */ 156 lmc_t1_set_circuit_type, /* set T1 or E1 circuit type */ 157 lmc_t1_watchdog 158}; 159 160static void 161lmc_dummy_set_1 (lmc_softc_t * const sc, int a) 162{ 163} 164 165static void 166lmc_dummy_set2_1 (lmc_softc_t * const sc, lmc_ctl_t * a) 167{ 168} 169 170/* 171 * HSSI methods 172 */ 173 174static void 175lmc_hssi_init (lmc_softc_t * const sc) 176{ 177 sc->ictl.cardtype = LMC_CTL_CARDTYPE_LMC5200; 178 179 lmc_gpio_mkoutput (sc, LMC_GEP_HSSI_CLOCK); 180} 181 182static void 183lmc_hssi_default (lmc_softc_t * const sc) 184{ 185 sc->lmc_miireg16 = LMC_MII16_LED_ALL; 186 187 sc->lmc_media->set_link_status (sc, LMC_LINK_DOWN); 188 sc->lmc_media->set_clock_source (sc, LMC_CTL_CLOCK_SOURCE_EXT); 189 sc->lmc_media->set_crc_length (sc, LMC_CTL_CRC_LENGTH_16); 190} 191 192/* 193 * Given a user provided state, set ourselves up to match it. This will 194 * always reset the card if needed. 195 */ 196static void 197lmc_hssi_set_status (lmc_softc_t * const sc, lmc_ctl_t * ctl) 198{ 199 if (ctl == NULL) 200 { 201 sc->lmc_media->set_clock_source (sc, sc->ictl.clock_source); 202 lmc_set_protocol (sc, NULL); 203 204 return; 205 } 206 207 /* 208 * check for change in clock source 209 */ 210 if (ctl->clock_source && !sc->ictl.clock_source) 211 { 212 sc->lmc_media->set_clock_source (sc, LMC_CTL_CLOCK_SOURCE_INT); 213 sc->lmc_timing = LMC_CTL_CLOCK_SOURCE_INT; 214 } 215 else if (!ctl->clock_source && sc->ictl.clock_source) 216 { 217 sc->lmc_timing = LMC_CTL_CLOCK_SOURCE_EXT; 218 sc->lmc_media->set_clock_source (sc, LMC_CTL_CLOCK_SOURCE_EXT); 219 } 220 221 lmc_set_protocol (sc, ctl); 222} 223 224/* 225 * 1 == internal, 0 == external 226 */ 227static void 228lmc_hssi_set_clock (lmc_softc_t * const sc, int ie) 229{ 230 int old; 231 old = sc->ictl.clock_source; 232 if (ie == LMC_CTL_CLOCK_SOURCE_EXT) 233 { 234 sc->lmc_gpio |= LMC_GEP_HSSI_CLOCK; 235 LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio); 236 sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_EXT; 237 if(old != ie) 238 printk (LMC_PRINTF_FMT ": clock external\n", LMC_PRINTF_ARGS); 239 } 240 else 241 { 242 sc->lmc_gpio &= ~(LMC_GEP_HSSI_CLOCK); 243 LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio); 244 sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_INT; 245 if(old != ie) 246 printk (LMC_PRINTF_FMT ": clock internal\n", LMC_PRINTF_ARGS); 247 } 248} 249 250/* 251 * return hardware link status. 252 * 0 == link is down, 1 == link is up. 253 */ 254static int 255lmc_hssi_get_link_status (lmc_softc_t * const sc) 256{ 257 /* 258 * We're using the same code as SSI since 259 * they're practically the same 260 */ 261 return lmc_ssi_get_link_status(sc); 262} 263 264static void 265lmc_hssi_set_link_status (lmc_softc_t * const sc, int state) 266{ 267 if (state == LMC_LINK_UP) 268 sc->lmc_miireg16 |= LMC_MII16_HSSI_TA; 269 else 270 sc->lmc_miireg16 &= ~LMC_MII16_HSSI_TA; 271 272 lmc_mii_writereg (sc, 0, 16, sc->lmc_miireg16); 273} 274 275/* 276 * 0 == 16bit, 1 == 32bit 277 */ 278static void 279lmc_hssi_set_crc_length (lmc_softc_t * const sc, int state) 280{ 281 if (state == LMC_CTL_CRC_LENGTH_32) 282 { 283 /* 32 bit */ 284 sc->lmc_miireg16 |= LMC_MII16_HSSI_CRC; 285 sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_32; 286 } 287 else 288 { 289 /* 16 bit */ 290 sc->lmc_miireg16 &= ~LMC_MII16_HSSI_CRC; 291 sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_16; 292 } 293 294 lmc_mii_writereg (sc, 0, 16, sc->lmc_miireg16); 295} 296 297static void 298lmc_hssi_watchdog (lmc_softc_t * const sc) 299{ 300 /* HSSI is blank */ 301} 302 303/* 304 * DS3 methods 305 */ 306 307/* 308 * Set cable length 309 */ 310static void 311lmc_ds3_set_100ft (lmc_softc_t * const sc, int ie) 312{ 313 if (ie == LMC_CTL_CABLE_LENGTH_GT_100FT) 314 { 315 sc->lmc_miireg16 &= ~LMC_MII16_DS3_ZERO; 316 sc->ictl.cable_length = LMC_CTL_CABLE_LENGTH_GT_100FT; 317 } 318 else if (ie == LMC_CTL_CABLE_LENGTH_LT_100FT) 319 { 320 sc->lmc_miireg16 |= LMC_MII16_DS3_ZERO; 321 sc->ictl.cable_length = LMC_CTL_CABLE_LENGTH_LT_100FT; 322 } 323 lmc_mii_writereg (sc, 0, 16, sc->lmc_miireg16); 324} 325 326static void 327lmc_ds3_default (lmc_softc_t * const sc) 328{ 329 sc->lmc_miireg16 = LMC_MII16_LED_ALL; 330 331 sc->lmc_media->set_link_status (sc, LMC_LINK_DOWN); 332 sc->lmc_media->set_cable_length (sc, LMC_CTL_CABLE_LENGTH_LT_100FT); 333 sc->lmc_media->set_scrambler (sc, LMC_CTL_OFF); 334 sc->lmc_media->set_crc_length (sc, LMC_CTL_CRC_LENGTH_16); 335} 336 337/* 338 * Given a user provided state, set ourselves up to match it. This will 339 * always reset the card if needed. 340 */ 341static void 342lmc_ds3_set_status (lmc_softc_t * const sc, lmc_ctl_t * ctl) 343{ 344 if (ctl == NULL) 345 { 346 sc->lmc_media->set_cable_length (sc, sc->ictl.cable_length); 347 sc->lmc_media->set_scrambler (sc, sc->ictl.scrambler_onoff); 348 lmc_set_protocol (sc, NULL); 349 350 return; 351 } 352 353 /* 354 * check for change in cable length setting 355 */ 356 if (ctl->cable_length && !sc->ictl.cable_length) 357 lmc_ds3_set_100ft (sc, LMC_CTL_CABLE_LENGTH_GT_100FT); 358 else if (!ctl->cable_length && sc->ictl.cable_length) 359 lmc_ds3_set_100ft (sc, LMC_CTL_CABLE_LENGTH_LT_100FT); 360 361 /* 362 * Check for change in scrambler setting (requires reset) 363 */ 364 if (ctl->scrambler_onoff && !sc->ictl.scrambler_onoff) 365 lmc_ds3_set_scram (sc, LMC_CTL_ON); 366 else if (!ctl->scrambler_onoff && sc->ictl.scrambler_onoff) 367 lmc_ds3_set_scram (sc, LMC_CTL_OFF); 368 369 lmc_set_protocol (sc, ctl); 370} 371 372static void 373lmc_ds3_init (lmc_softc_t * const sc) 374{ 375 int i; 376 377 sc->ictl.cardtype = LMC_CTL_CARDTYPE_LMC5245; 378 379 /* writes zeros everywhere */ 380 for (i = 0; i < 21; i++) 381 { 382 lmc_mii_writereg (sc, 0, 17, i); 383 lmc_mii_writereg (sc, 0, 18, 0); 384 } 385 386 /* set some essential bits */ 387 lmc_mii_writereg (sc, 0, 17, 1); 388 lmc_mii_writereg (sc, 0, 18, 0x25); /* ser, xtx */ 389 390 lmc_mii_writereg (sc, 0, 17, 5); 391 lmc_mii_writereg (sc, 0, 18, 0x80); /* emode */ 392 393 lmc_mii_writereg (sc, 0, 17, 14); 394 lmc_mii_writereg (sc, 0, 18, 0x30); /* rcgen, tcgen */ 395 396 /* clear counters and latched bits */ 397 for (i = 0; i < 21; i++) 398 { 399 lmc_mii_writereg (sc, 0, 17, i); 400 lmc_mii_readreg (sc, 0, 18); 401 } 402} 403 404/* 405 * 1 == DS3 payload scrambled, 0 == not scrambled 406 */ 407static void 408lmc_ds3_set_scram (lmc_softc_t * const sc, int ie) 409{ 410 if (ie == LMC_CTL_ON) 411 { 412 sc->lmc_miireg16 |= LMC_MII16_DS3_SCRAM; 413 sc->ictl.scrambler_onoff = LMC_CTL_ON; 414 } 415 else 416 { 417 sc->lmc_miireg16 &= ~LMC_MII16_DS3_SCRAM; 418 sc->ictl.scrambler_onoff = LMC_CTL_OFF; 419 } 420 lmc_mii_writereg (sc, 0, 16, sc->lmc_miireg16); 421} 422 423/* 424 * return hardware link status. 425 * 0 == link is down, 1 == link is up. 426 */ 427static int 428lmc_ds3_get_link_status (lmc_softc_t * const sc) 429{ 430 u_int16_t link_status, link_status_11; 431 int ret = 1; 432 433 lmc_mii_writereg (sc, 0, 17, 7); 434 link_status = lmc_mii_readreg (sc, 0, 18); 435 436 /* LMC5245 (DS3) & LMC1200 (DS1) LED definitions 437 * led0 yellow = far-end adapter is in Red alarm condition 438 * led1 blue = received an Alarm Indication signal 439 * (upstream failure) 440 * led2 Green = power to adapter, Gate Array loaded & driver 441 * attached 442 * led3 red = Loss of Signal (LOS) or out of frame (OOF) 443 * conditions detected on T3 receive signal 444 */ 445 446 lmc_led_on(sc, LMC_DS3_LED2); 447 448 if ((link_status & LMC_FRAMER_REG0_DLOS) || 449 (link_status & LMC_FRAMER_REG0_OOFS)){ 450 ret = 0; 451 if(sc->last_led_err[3] != 1){ 452 u16 r1; 453 lmc_mii_writereg (sc, 0, 17, 01); /* Turn on Xbit error as our cisco does */ 454 r1 = lmc_mii_readreg (sc, 0, 18); 455 r1 &= 0xfe; 456 lmc_mii_writereg(sc, 0, 18, r1); 457 printk(KERN_WARNING "%s: Red Alarm - Loss of Signal or Loss of Framing\n", sc->name); 458 } 459 lmc_led_on(sc, LMC_DS3_LED3); /* turn on red LED */ 460 sc->last_led_err[3] = 1; 461 } 462 else { 463 lmc_led_off(sc, LMC_DS3_LED3); /* turn on red LED */ 464 if(sc->last_led_err[3] == 1){ 465 u16 r1; 466 lmc_mii_writereg (sc, 0, 17, 01); /* Turn off Xbit error */ 467 r1 = lmc_mii_readreg (sc, 0, 18); 468 r1 |= 0x01; 469 lmc_mii_writereg(sc, 0, 18, r1); 470 } 471 sc->last_led_err[3] = 0; 472 } 473 474 lmc_mii_writereg(sc, 0, 17, 0x10); 475 link_status_11 = lmc_mii_readreg(sc, 0, 18); 476 if((link_status & LMC_FRAMER_REG0_AIS) || 477 (link_status_11 & LMC_FRAMER_REG10_XBIT)) { 478 ret = 0; 479 if(sc->last_led_err[0] != 1){ 480 printk(KERN_WARNING "%s: AIS Alarm or XBit Error\n", sc->name); 481 printk(KERN_WARNING "%s: Remote end has loss of signal or framing\n", sc->name); 482 } 483 lmc_led_on(sc, LMC_DS3_LED0); 484 sc->last_led_err[0] = 1; 485 } 486 else { 487 lmc_led_off(sc, LMC_DS3_LED0); 488 sc->last_led_err[0] = 0; 489 } 490 491 lmc_mii_writereg (sc, 0, 17, 9); 492 link_status = lmc_mii_readreg (sc, 0, 18); 493 494 if(link_status & LMC_FRAMER_REG9_RBLUE){ 495 ret = 0; 496 if(sc->last_led_err[1] != 1){ 497 printk(KERN_WARNING "%s: Blue Alarm - Receiving all 1's\n", sc->name); 498 } 499 lmc_led_on(sc, LMC_DS3_LED1); 500 sc->last_led_err[1] = 1; 501 } 502 else { 503 lmc_led_off(sc, LMC_DS3_LED1); 504 sc->last_led_err[1] = 0; 505 } 506 507 return ret; 508} 509 510/* 511 * 0 == 16bit, 1 == 32bit 512 */ 513static void 514lmc_ds3_set_crc_length (lmc_softc_t * const sc, int state) 515{ 516 if (state == LMC_CTL_CRC_LENGTH_32) 517 { 518 /* 32 bit */ 519 sc->lmc_miireg16 |= LMC_MII16_DS3_CRC; 520 sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_32; 521 } 522 else 523 { 524 /* 16 bit */ 525 sc->lmc_miireg16 &= ~LMC_MII16_DS3_CRC; 526 sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_16; 527 } 528 529 lmc_mii_writereg (sc, 0, 16, sc->lmc_miireg16); 530} 531 532static void 533lmc_ds3_watchdog (lmc_softc_t * const sc) 534{ 535 536} 537 538 539/* 540 * SSI methods 541 */ 542 543static void 544lmc_ssi_init (lmc_softc_t * const sc) 545{ 546 u_int16_t mii17; 547 int cable; 548 549 sc->ictl.cardtype = LMC_CTL_CARDTYPE_LMC1000; 550 551 mii17 = lmc_mii_readreg (sc, 0, 17); 552 553 cable = (mii17 & LMC_MII17_SSI_CABLE_MASK) >> LMC_MII17_SSI_CABLE_SHIFT; 554 sc->ictl.cable_type = cable; 555 556 lmc_gpio_mkoutput (sc, LMC_GEP_SSI_TXCLOCK); 557} 558 559static void 560lmc_ssi_default (lmc_softc_t * const sc) 561{ 562 sc->lmc_miireg16 = LMC_MII16_LED_ALL; 563 564 /* 565 * make TXCLOCK always be an output 566 */ 567 lmc_gpio_mkoutput (sc, LMC_GEP_SSI_TXCLOCK); 568 569 sc->lmc_media->set_link_status (sc, LMC_LINK_DOWN); 570 sc->lmc_media->set_clock_source (sc, LMC_CTL_CLOCK_SOURCE_EXT); 571 sc->lmc_media->set_speed (sc, NULL); 572 sc->lmc_media->set_crc_length (sc, LMC_CTL_CRC_LENGTH_16); 573} 574 575/* 576 * Given a user provided state, set ourselves up to match it. This will 577 * always reset the card if needed. 578 */ 579static void 580lmc_ssi_set_status (lmc_softc_t * const sc, lmc_ctl_t * ctl) 581{ 582 if (ctl == NULL) 583 { 584 sc->lmc_media->set_clock_source (sc, sc->ictl.clock_source); 585 sc->lmc_media->set_speed (sc, &sc->ictl); 586 lmc_set_protocol (sc, NULL); 587 588 return; 589 } 590 591 /* 592 * check for change in clock source 593 */ 594 if (ctl->clock_source == LMC_CTL_CLOCK_SOURCE_INT 595 && sc->ictl.clock_source == LMC_CTL_CLOCK_SOURCE_EXT) 596 { 597 sc->lmc_media->set_clock_source (sc, LMC_CTL_CLOCK_SOURCE_INT); 598 sc->lmc_timing = LMC_CTL_CLOCK_SOURCE_INT; 599 } 600 else if (ctl->clock_source == LMC_CTL_CLOCK_SOURCE_EXT 601 && sc->ictl.clock_source == LMC_CTL_CLOCK_SOURCE_INT) 602 { 603 sc->lmc_media->set_clock_source (sc, LMC_CTL_CLOCK_SOURCE_EXT); 604 sc->lmc_timing = LMC_CTL_CLOCK_SOURCE_EXT; 605 } 606 607 if (ctl->clock_rate != sc->ictl.clock_rate) 608 sc->lmc_media->set_speed (sc, ctl); 609 610 lmc_set_protocol (sc, ctl); 611} 612 613/* 614 * 1 == internal, 0 == external 615 */ 616static void 617lmc_ssi_set_clock (lmc_softc_t * const sc, int ie) 618{ 619 int old; 620 old = ie; 621 if (ie == LMC_CTL_CLOCK_SOURCE_EXT) 622 { 623 sc->lmc_gpio &= ~(LMC_GEP_SSI_TXCLOCK); 624 LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio); 625 sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_EXT; 626 if(ie != old) 627 printk (LMC_PRINTF_FMT ": clock external\n", LMC_PRINTF_ARGS); 628 } 629 else 630 { 631 sc->lmc_gpio |= LMC_GEP_SSI_TXCLOCK; 632 LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio); 633 sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_INT; 634 if(ie != old) 635 printk (LMC_PRINTF_FMT ": clock internal\n", LMC_PRINTF_ARGS); 636 } 637} 638 639static void 640lmc_ssi_set_speed (lmc_softc_t * const sc, lmc_ctl_t * ctl) 641{ 642 lmc_ctl_t *ictl = &sc->ictl; 643 lmc_av9110_t *av; 644 645 /* original settings for clock rate of: 646 * 100 Khz (8,25,0,0,2) were incorrect 647 * they should have been 80,125,1,3,3 648 * There are 17 param combinations to produce this freq. 649 * For 1.5 Mhz use 120,100,1,1,2 (226 param. combinations) 650 */ 651 if (ctl == NULL) 652 { 653 av = &ictl->cardspec.ssi; 654 ictl->clock_rate = 1500000; 655 av->f = ictl->clock_rate; 656 av->n = 120; 657 av->m = 100; 658 av->v = 1; 659 av->x = 1; 660 av->r = 2; 661 662 write_av9110 (sc, av->n, av->m, av->v, av->x, av->r); 663 return; 664 } 665 666 av = &ctl->cardspec.ssi; 667 668 if (av->f == 0) 669 return; 670 671 ictl->clock_rate = av->f; /* really, this is the rate we are */ 672 ictl->cardspec.ssi = *av; 673 674 write_av9110 (sc, av->n, av->m, av->v, av->x, av->r); 675} 676 677/* 678 * return hardware link status. 679 * 0 == link is down, 1 == link is up. 680 */ 681static int 682lmc_ssi_get_link_status (lmc_softc_t * const sc) 683{ 684 u_int16_t link_status; 685 u_int32_t ticks; 686 int ret = 1; 687 int hw_hdsk = 1; 688 689 /* 690 * missing CTS? Hmm. If we require CTS on, we may never get the 691 * link to come up, so omit it in this test. 692 * 693 * Also, it seems that with a loopback cable, DCD isn't asserted, 694 * so just check for things like this: 695 * DSR _must_ be asserted. 696 * One of DCD or CTS must be asserted. 697 */ 698 699 /* LMC 1000 (SSI) LED definitions 700 * led0 Green = power to adapter, Gate Array loaded & 701 * driver attached 702 * led1 Green = DSR and DTR and RTS and CTS are set 703 * led2 Green = Cable detected 704 * led3 red = No timing is available from the 705 * cable or the on-board frequency 706 * generator. 707 */ 708 709 link_status = lmc_mii_readreg (sc, 0, 16); 710 711 /* Is the transmit clock still available */ 712 ticks = LMC_CSR_READ (sc, csr_gp_timer); 713 ticks = 0x0000ffff - (ticks & 0x0000ffff); 714 715 lmc_led_on (sc, LMC_MII16_LED0); 716 717 /* ====== transmit clock determination ===== */ 718 if (sc->lmc_timing == LMC_CTL_CLOCK_SOURCE_INT) { 719 lmc_led_off(sc, LMC_MII16_LED3); 720 } 721 else if (ticks == 0 ) { /* no clock found ? */ 722 ret = 0; 723 if(sc->last_led_err[3] != 1){ 724 sc->stats.tx_lossOfClockCnt++; 725 printk(KERN_WARNING "%s: Lost Clock, Link Down\n", sc->name); 726 } 727 sc->last_led_err[3] = 1; 728 lmc_led_on (sc, LMC_MII16_LED3); /* turn ON red LED */ 729 } 730 else { 731 if(sc->last_led_err[3] == 1) 732 printk(KERN_WARNING "%s: Clock Returned\n", sc->name); 733 sc->last_led_err[3] = 0; 734 lmc_led_off (sc, LMC_MII16_LED3); /* turn OFF red LED */ 735 } 736 737 if ((link_status & LMC_MII16_SSI_DSR) == 0) { /* Also HSSI CA */ 738 ret = 0; 739 hw_hdsk = 0; 740 } 741 742#ifdef CONFIG_LMC_IGNORE_HARDWARE_HANDSHAKE 743 if ((link_status & (LMC_MII16_SSI_CTS | LMC_MII16_SSI_DCD)) == 0){ 744 ret = 0; 745 hw_hdsk = 0; 746 } 747#endif 748 749 if(hw_hdsk == 0){ 750 if(sc->last_led_err[1] != 1) 751 printk(KERN_WARNING "%s: DSR not asserted\n", sc->name); 752 sc->last_led_err[1] = 1; 753 lmc_led_off(sc, LMC_MII16_LED1); 754 } 755 else { 756 if(sc->last_led_err[1] != 0) 757 printk(KERN_WARNING "%s: DSR now asserted\n", sc->name); 758 sc->last_led_err[1] = 0; 759 lmc_led_on(sc, LMC_MII16_LED1); 760 } 761 762 if(ret == 1) { 763 lmc_led_on(sc, LMC_MII16_LED2); /* Over all good status? */ 764 } 765 766 return ret; 767} 768 769static void 770lmc_ssi_set_link_status (lmc_softc_t * const sc, int state) 771{ 772 if (state == LMC_LINK_UP) 773 { 774 sc->lmc_miireg16 |= (LMC_MII16_SSI_DTR | LMC_MII16_SSI_RTS); 775 printk (LMC_PRINTF_FMT ": asserting DTR and RTS\n", LMC_PRINTF_ARGS); 776 } 777 else 778 { 779 sc->lmc_miireg16 &= ~(LMC_MII16_SSI_DTR | LMC_MII16_SSI_RTS); 780 printk (LMC_PRINTF_FMT ": deasserting DTR and RTS\n", LMC_PRINTF_ARGS); 781 } 782 783 lmc_mii_writereg (sc, 0, 16, sc->lmc_miireg16); 784 785} 786 787/* 788 * 0 == 16bit, 1 == 32bit 789 */ 790static void 791lmc_ssi_set_crc_length (lmc_softc_t * const sc, int state) 792{ 793 if (state == LMC_CTL_CRC_LENGTH_32) 794 { 795 /* 32 bit */ 796 sc->lmc_miireg16 |= LMC_MII16_SSI_CRC; 797 sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_32; 798 sc->lmc_crcSize = LMC_CTL_CRC_BYTESIZE_4; 799 800 } 801 else 802 { 803 /* 16 bit */ 804 sc->lmc_miireg16 &= ~LMC_MII16_SSI_CRC; 805 sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_16; 806 sc->lmc_crcSize = LMC_CTL_CRC_BYTESIZE_2; 807 } 808 809 lmc_mii_writereg (sc, 0, 16, sc->lmc_miireg16); 810} 811 812/* 813 * These are bits to program the ssi frequency generator 814 */ 815static inline void 816write_av9110_bit (lmc_softc_t * sc, int c) 817{ 818 /* 819 * set the data bit as we need it. 820 */ 821 sc->lmc_gpio &= ~(LMC_GEP_CLK); 822 if (c & 0x01) 823 sc->lmc_gpio |= LMC_GEP_DATA; 824 else 825 sc->lmc_gpio &= ~(LMC_GEP_DATA); 826 LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio); 827 828 /* 829 * set the clock to high 830 */ 831 sc->lmc_gpio |= LMC_GEP_CLK; 832 LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio); 833 834 /* 835 * set the clock to low again. 836 */ 837 sc->lmc_gpio &= ~(LMC_GEP_CLK); 838 LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio); 839} 840 841static void 842write_av9110 (lmc_softc_t * sc, u_int32_t n, u_int32_t m, u_int32_t v, 843 u_int32_t x, u_int32_t r) 844{ 845 int i; 846 847 848 sc->lmc_gpio |= LMC_GEP_SSI_GENERATOR; 849 sc->lmc_gpio &= ~(LMC_GEP_DATA | LMC_GEP_CLK); 850 LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio); 851 852 /* 853 * Set the TXCLOCK, GENERATOR, SERIAL, and SERIALCLK 854 * as outputs. 855 */ 856 lmc_gpio_mkoutput (sc, (LMC_GEP_DATA | LMC_GEP_CLK 857 | LMC_GEP_SSI_GENERATOR)); 858 859 sc->lmc_gpio &= ~(LMC_GEP_SSI_GENERATOR); 860 LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio); 861 862 /* 863 * a shifting we will go... 864 */ 865 for (i = 0; i < 7; i++) 866 write_av9110_bit (sc, n >> i); 867 for (i = 0; i < 7; i++) 868 write_av9110_bit (sc, m >> i); 869 for (i = 0; i < 1; i++) 870 write_av9110_bit (sc, v >> i); 871 for (i = 0; i < 2; i++) 872 write_av9110_bit (sc, x >> i); 873 for (i = 0; i < 2; i++) 874 write_av9110_bit (sc, r >> i); 875 for (i = 0; i < 5; i++) 876 write_av9110_bit (sc, 0x17 >> i); 877 878 /* 879 * stop driving serial-related signals 880 */ 881 lmc_gpio_mkinput (sc, 882 (LMC_GEP_DATA | LMC_GEP_CLK 883 | LMC_GEP_SSI_GENERATOR)); 884} 885 886static void 887lmc_ssi_watchdog (lmc_softc_t * const sc) 888{ 889 u_int16_t mii17; 890 struct ssicsr2 891 { 892 unsigned short dtr:1, dsr:1, rts:1, cable:3, crc:1, led0:1, led1:1, 893 led2:1, led3:1, fifo:1, ll:1, rl:1, tm:1, loop:1; 894 }; 895 struct ssicsr2 *ssicsr; 896 mii17 = lmc_mii_readreg (sc, 0, 17); 897 ssicsr = (struct ssicsr2 *) &mii17; 898 if (ssicsr->cable == 7) 899 { 900 lmc_led_off (sc, LMC_MII16_LED2); 901 } 902 else 903 { 904 lmc_led_on (sc, LMC_MII16_LED2); 905 } 906 907} 908 909/* 910 * T1 methods 911 */ 912 913/* 914 * The framer regs are multiplexed through MII regs 17 & 18 915 * write the register address to MII reg 17 and the * data to MII reg 18. */ 916static void 917lmc_t1_write (lmc_softc_t * const sc, int a, int d) 918{ 919 lmc_mii_writereg (sc, 0, 17, a); 920 lmc_mii_writereg (sc, 0, 18, d); 921} 922 923/* Save a warning 924static int 925lmc_t1_read (lmc_softc_t * const sc, int a) 926{ 927 lmc_mii_writereg (sc, 0, 17, a); 928 return lmc_mii_readreg (sc, 0, 18); 929} 930*/ 931 932 933static void 934lmc_t1_init (lmc_softc_t * const sc) 935{ 936 u_int16_t mii16; 937 int i; 938 939 sc->ictl.cardtype = LMC_CTL_CARDTYPE_LMC1200; 940 mii16 = lmc_mii_readreg (sc, 0, 16); 941 942 /* reset 8370 */ 943 mii16 &= ~LMC_MII16_T1_RST; 944 lmc_mii_writereg (sc, 0, 16, mii16 | LMC_MII16_T1_RST); 945 lmc_mii_writereg (sc, 0, 16, mii16); 946 947 /* set T1 or E1 line. Uses sc->lmcmii16 reg in function so update it */ 948 sc->lmc_miireg16 = mii16; 949 lmc_t1_set_circuit_type(sc, LMC_CTL_CIRCUIT_TYPE_T1); 950 mii16 = sc->lmc_miireg16; 951 952 lmc_t1_write (sc, 0x01, 0x1B); /* CR0 - primary control */ 953 lmc_t1_write (sc, 0x02, 0x42); /* JAT_CR - jitter atten config */ 954 lmc_t1_write (sc, 0x14, 0x00); /* LOOP - loopback config */ 955 lmc_t1_write (sc, 0x15, 0x00); /* DL3_TS - external data link timeslot */ 956 lmc_t1_write (sc, 0x18, 0xFF); /* PIO - programmable I/O */ 957 lmc_t1_write (sc, 0x19, 0x30); /* POE - programmable OE */ 958 lmc_t1_write (sc, 0x1A, 0x0F); /* CMUX - clock input mux */ 959 lmc_t1_write (sc, 0x20, 0x41); /* LIU_CR - RX LIU config */ 960 lmc_t1_write (sc, 0x22, 0x76); /* RLIU_CR - RX LIU config */ 961 lmc_t1_write (sc, 0x40, 0x03); /* RCR0 - RX config */ 962 lmc_t1_write (sc, 0x45, 0x00); /* RALM - RX alarm config */ 963 lmc_t1_write (sc, 0x46, 0x05); /* LATCH - RX alarm/err/cntr latch */ 964 lmc_t1_write (sc, 0x68, 0x40); /* TLIU_CR - TX LIU config */ 965 lmc_t1_write (sc, 0x70, 0x0D); /* TCR0 - TX framer config */ 966 lmc_t1_write (sc, 0x71, 0x05); /* TCR1 - TX config */ 967 lmc_t1_write (sc, 0x72, 0x0B); /* TFRM - TX frame format */ 968 lmc_t1_write (sc, 0x73, 0x00); /* TERROR - TX error insert */ 969 lmc_t1_write (sc, 0x74, 0x00); /* TMAN - TX manual Sa/FEBE config */ 970 lmc_t1_write (sc, 0x75, 0x00); /* TALM - TX alarm signal config */ 971 lmc_t1_write (sc, 0x76, 0x00); /* TPATT - TX test pattern config */ 972 lmc_t1_write (sc, 0x77, 0x00); /* TLB - TX inband loopback config */ 973 lmc_t1_write (sc, 0x90, 0x05); /* CLAD_CR - clock rate adapter config */ 974 lmc_t1_write (sc, 0x91, 0x05); /* CSEL - clad freq sel */ 975 lmc_t1_write (sc, 0xA6, 0x00); /* DL1_CTL - DL1 control */ 976 lmc_t1_write (sc, 0xB1, 0x00); /* DL2_CTL - DL2 control */ 977 lmc_t1_write (sc, 0xD0, 0x47); /* SBI_CR - sys bus iface config */ 978 lmc_t1_write (sc, 0xD1, 0x70); /* RSB_CR - RX sys bus config */ 979 lmc_t1_write (sc, 0xD4, 0x30); /* TSB_CR - TX sys bus config */ 980 for (i = 0; i < 32; i++) 981 { 982 lmc_t1_write (sc, 0x0E0 + i, 0x00); /* SBCn - sys bus per-channel ctl */ 983 lmc_t1_write (sc, 0x100 + i, 0x00); /* TPCn - TX per-channel ctl */ 984 lmc_t1_write (sc, 0x180 + i, 0x00); /* RPCn - RX per-channel ctl */ 985 } 986 for (i = 1; i < 25; i++) 987 { 988 lmc_t1_write (sc, 0x0E0 + i, 0x0D); /* SBCn - sys bus per-channel ctl */ 989 } 990 991 mii16 |= LMC_MII16_T1_XOE; 992 lmc_mii_writereg (sc, 0, 16, mii16); 993 sc->lmc_miireg16 = mii16; 994} 995 996static void 997lmc_t1_default (lmc_softc_t * const sc) 998{ 999 sc->lmc_miireg16 = LMC_MII16_LED_ALL; 1000 sc->lmc_media->set_link_status (sc, LMC_LINK_DOWN); 1001 sc->lmc_media->set_circuit_type (sc, LMC_CTL_CIRCUIT_TYPE_T1); 1002 sc->lmc_media->set_crc_length (sc, LMC_CTL_CRC_LENGTH_16); 1003 /* Right now we can only clock from out internal source */ 1004 sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_INT; 1005} 1006/* * Given a user provided state, set ourselves up to match it. This will * always reset the card if needed. 1007 */ 1008static void 1009lmc_t1_set_status (lmc_softc_t * const sc, lmc_ctl_t * ctl) 1010{ 1011 if (ctl == NULL) 1012 { 1013 sc->lmc_media->set_circuit_type (sc, sc->ictl.circuit_type); 1014 lmc_set_protocol (sc, NULL); 1015 1016 return; 1017 } 1018 /* 1019 * check for change in circuit type */ 1020 if (ctl->circuit_type == LMC_CTL_CIRCUIT_TYPE_T1 1021 && sc->ictl.circuit_type == 1022 LMC_CTL_CIRCUIT_TYPE_E1) sc->lmc_media->set_circuit_type (sc, 1023 LMC_CTL_CIRCUIT_TYPE_E1); 1024 else if (ctl->circuit_type == LMC_CTL_CIRCUIT_TYPE_E1 1025 && sc->ictl.circuit_type == LMC_CTL_CIRCUIT_TYPE_T1) 1026 sc->lmc_media->set_circuit_type (sc, LMC_CTL_CIRCUIT_TYPE_T1); 1027 lmc_set_protocol (sc, ctl); 1028} 1029/* 1030 * return hardware link status. 1031 * 0 == link is down, 1 == link is up. 1032 */ static int 1033lmc_t1_get_link_status (lmc_softc_t * const sc) 1034{ 1035 u_int16_t link_status; 1036 int ret = 1; 1037 1038 /* LMC5245 (DS3) & LMC1200 (DS1) LED definitions 1039 * led0 yellow = far-end adapter is in Red alarm condition 1040 * led1 blue = received an Alarm Indication signal 1041 * (upstream failure) 1042 * led2 Green = power to adapter, Gate Array loaded & driver 1043 * attached 1044 * led3 red = Loss of Signal (LOS) or out of frame (OOF) 1045 * conditions detected on T3 receive signal 1046 */ 1047 lmc_trace(sc->lmc_device, "lmc_t1_get_link_status in"); 1048 lmc_led_on(sc, LMC_DS3_LED2); 1049 1050 lmc_mii_writereg (sc, 0, 17, T1FRAMER_ALARM1_STATUS); 1051 link_status = lmc_mii_readreg (sc, 0, 18); 1052 1053 1054 if (link_status & T1F_RAIS) { /* turn on blue LED */ 1055 ret = 0; 1056 if(sc->last_led_err[1] != 1){ 1057 printk(KERN_WARNING "%s: Receive AIS/Blue Alarm. Far end in RED alarm\n", sc->name); 1058 } 1059 lmc_led_on(sc, LMC_DS3_LED1); 1060 sc->last_led_err[1] = 1; 1061 } 1062 else { 1063 if(sc->last_led_err[1] != 0){ 1064 printk(KERN_WARNING "%s: End AIS/Blue Alarm\n", sc->name); 1065 } 1066 lmc_led_off (sc, LMC_DS3_LED1); 1067 sc->last_led_err[1] = 0; 1068 } 1069 1070 /* 1071 * Yellow Alarm is nasty evil stuff, looks at data patterns 1072 * inside the channel and confuses it with HDLC framing 1073 * ignore all yellow alarms. 1074 * 1075 * Do listen to MultiFrame Yellow alarm which while implemented 1076 * different ways isn't in the channel and hence somewhat 1077 * more reliable 1078 */ 1079 1080 if (link_status & T1F_RMYEL) { 1081 ret = 0; 1082 if(sc->last_led_err[0] != 1){ 1083 printk(KERN_WARNING "%s: Receive Yellow AIS Alarm\n", sc->name); 1084 } 1085 lmc_led_on(sc, LMC_DS3_LED0); 1086 sc->last_led_err[0] = 1; 1087 } 1088 else { 1089 if(sc->last_led_err[0] != 0){ 1090 printk(KERN_WARNING "%s: End of Yellow AIS Alarm\n", sc->name); 1091 } 1092 lmc_led_off(sc, LMC_DS3_LED0); 1093 sc->last_led_err[0] = 0; 1094 } 1095 1096 /* 1097 * Loss of signal and los of frame 1098 * Use the green bit to identify which one lit the led 1099 */ 1100 if(link_status & T1F_RLOF){ 1101 ret = 0; 1102 if(sc->last_led_err[3] != 1){ 1103 printk(KERN_WARNING "%s: Local Red Alarm: Loss of Framing\n", sc->name); 1104 } 1105 lmc_led_on(sc, LMC_DS3_LED3); 1106 sc->last_led_err[3] = 1; 1107 1108 } 1109 else { 1110 if(sc->last_led_err[3] != 0){ 1111 printk(KERN_WARNING "%s: End Red Alarm (LOF)\n", sc->name); 1112 } 1113 if( ! (link_status & T1F_RLOS)) 1114 lmc_led_off(sc, LMC_DS3_LED3); 1115 sc->last_led_err[3] = 0; 1116 } 1117 1118 if(link_status & T1F_RLOS){ 1119 ret = 0; 1120 if(sc->last_led_err[2] != 1){ 1121 printk(KERN_WARNING "%s: Local Red Alarm: Loss of Signal\n", sc->name); 1122 } 1123 lmc_led_on(sc, LMC_DS3_LED3); 1124 sc->last_led_err[2] = 1; 1125 1126 } 1127 else { 1128 if(sc->last_led_err[2] != 0){ 1129 printk(KERN_WARNING "%s: End Red Alarm (LOS)\n", sc->name); 1130 } 1131 if( ! (link_status & T1F_RLOF)) 1132 lmc_led_off(sc, LMC_DS3_LED3); 1133 sc->last_led_err[2] = 0; 1134 } 1135 1136 sc->lmc_xinfo.t1_alarm1_status = link_status; 1137 1138 lmc_mii_writereg (sc, 0, 17, T1FRAMER_ALARM2_STATUS); 1139 sc->lmc_xinfo.t1_alarm2_status = lmc_mii_readreg (sc, 0, 18); 1140 1141 1142 lmc_trace(sc->lmc_device, "lmc_t1_get_link_status out"); 1143 1144 return ret; 1145} 1146 1147/* 1148 * 1 == T1 Circuit Type , 0 == E1 Circuit Type 1149 */ 1150static void 1151lmc_t1_set_circuit_type (lmc_softc_t * const sc, int ie) 1152{ 1153 if (ie == LMC_CTL_CIRCUIT_TYPE_T1) { 1154 sc->lmc_miireg16 |= LMC_MII16_T1_Z; 1155 sc->ictl.circuit_type = LMC_CTL_CIRCUIT_TYPE_T1; 1156 printk(KERN_INFO "%s: In T1 Mode\n", sc->name); 1157 } 1158 else { 1159 sc->lmc_miireg16 &= ~LMC_MII16_T1_Z; 1160 sc->ictl.circuit_type = LMC_CTL_CIRCUIT_TYPE_E1; 1161 printk(KERN_INFO "%s: In E1 Mode\n", sc->name); 1162 } 1163 1164 lmc_mii_writereg (sc, 0, 16, sc->lmc_miireg16); 1165 1166} 1167 1168/* 1169 * 0 == 16bit, 1 == 32bit */ 1170static void 1171lmc_t1_set_crc_length (lmc_softc_t * const sc, int state) 1172{ 1173 if (state == LMC_CTL_CRC_LENGTH_32) 1174 { 1175 /* 32 bit */ 1176 sc->lmc_miireg16 |= LMC_MII16_T1_CRC; 1177 sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_32; 1178 sc->lmc_crcSize = LMC_CTL_CRC_BYTESIZE_4; 1179 1180 } 1181 else 1182 { 1183 /* 16 bit */ sc->lmc_miireg16 &= ~LMC_MII16_T1_CRC; 1184 sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_16; 1185 sc->lmc_crcSize = LMC_CTL_CRC_BYTESIZE_2; 1186 1187 } 1188 1189 lmc_mii_writereg (sc, 0, 16, sc->lmc_miireg16); 1190} 1191 1192/* 1193 * 1 == internal, 0 == external 1194 */ 1195static void 1196lmc_t1_set_clock (lmc_softc_t * const sc, int ie) 1197{ 1198 int old; 1199 old = ie; 1200 if (ie == LMC_CTL_CLOCK_SOURCE_EXT) 1201 { 1202 sc->lmc_gpio &= ~(LMC_GEP_SSI_TXCLOCK); 1203 LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio); 1204 sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_EXT; 1205 if(old != ie) 1206 printk (LMC_PRINTF_FMT ": clock external\n", LMC_PRINTF_ARGS); 1207 } 1208 else 1209 { 1210 sc->lmc_gpio |= LMC_GEP_SSI_TXCLOCK; 1211 LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio); 1212 sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_INT; 1213 if(old != ie) 1214 printk (LMC_PRINTF_FMT ": clock internal\n", LMC_PRINTF_ARGS); 1215 } 1216} 1217 1218static void 1219lmc_t1_watchdog (lmc_softc_t * const sc) 1220{ 1221} 1222 1223static void 1224lmc_set_protocol (lmc_softc_t * const sc, lmc_ctl_t * ctl) 1225{ 1226 if (ctl == 0) 1227 { 1228 sc->ictl.keepalive_onoff = LMC_CTL_ON; 1229 1230 return; 1231 } 1232} 1233