lmc_media.c 34 KB

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