lmc_media.c 34 KB

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