lmc_media.c 34 KB

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