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