jade.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. /* $Id: jade.c,v 1.9.2.4 2004/01/14 16:04:48 keil Exp $
  2. *
  3. * JADE stuff (derived from original hscx.c)
  4. *
  5. * Author Roland Klabunde
  6. * Copyright by Roland Klabunde <R.Klabunde@Berkom.de>
  7. *
  8. * This software may be used and distributed according to the terms
  9. * of the GNU General Public License, incorporated herein by reference.
  10. *
  11. */
  12. #include <linux/init.h>
  13. #include "hisax.h"
  14. #include "hscx.h"
  15. #include "jade.h"
  16. #include "isdnl1.h"
  17. #include <linux/interrupt.h>
  18. #include <linux/slab.h>
  19. int
  20. JadeVersion(struct IsdnCardState *cs, char *s)
  21. {
  22. int ver;
  23. int to = 50;
  24. cs->BC_Write_Reg(cs, -1, 0x50, 0x19);
  25. while (to) {
  26. udelay(1);
  27. ver = cs->BC_Read_Reg(cs, -1, 0x60);
  28. to--;
  29. if (ver)
  30. break;
  31. if (!to) {
  32. printk(KERN_INFO "%s JADE version not obtainable\n", s);
  33. return (0);
  34. }
  35. }
  36. /* Wait for the JADE */
  37. udelay(10);
  38. /* Read version */
  39. ver = cs->BC_Read_Reg(cs, -1, 0x60);
  40. printk(KERN_INFO "%s JADE version: %d\n", s, ver);
  41. return (1);
  42. }
  43. /* Write to indirect accessible jade register set */
  44. static void
  45. jade_write_indirect(struct IsdnCardState *cs, u_char reg, u_char value)
  46. {
  47. int to = 50;
  48. u_char ret;
  49. /* Write the data */
  50. cs->BC_Write_Reg(cs, -1, COMM_JADE + 1, value);
  51. /* Say JADE we wanna write indirect reg 'reg' */
  52. cs->BC_Write_Reg(cs, -1, COMM_JADE, reg);
  53. to = 50;
  54. /* Wait for RDY goes high */
  55. while (to) {
  56. udelay(1);
  57. ret = cs->BC_Read_Reg(cs, -1, COMM_JADE);
  58. to--;
  59. if (ret & 1)
  60. /* Got acknowledge */
  61. break;
  62. if (!to) {
  63. printk(KERN_INFO "Can not see ready bit from JADE DSP (reg=0x%X, value=0x%X)\n", reg, value);
  64. return;
  65. }
  66. }
  67. }
  68. static void
  69. modejade(struct BCState *bcs, int mode, int bc)
  70. {
  71. struct IsdnCardState *cs = bcs->cs;
  72. int jade = bcs->hw.hscx.hscx;
  73. if (cs->debug & L1_DEB_HSCX) {
  74. debugl1(cs, "jade %c mode %d ichan %d", 'A' + jade, mode, bc);
  75. }
  76. bcs->mode = mode;
  77. bcs->channel = bc;
  78. cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (mode == L1_MODE_TRANS ? jadeMODE_TMO : 0x00));
  79. cs->BC_Write_Reg(cs, jade, jade_HDLC_CCR0, (jadeCCR0_PU | jadeCCR0_ITF));
  80. cs->BC_Write_Reg(cs, jade, jade_HDLC_CCR1, 0x00);
  81. jade_write_indirect(cs, jade_HDLC1SERRXPATH, 0x08);
  82. jade_write_indirect(cs, jade_HDLC2SERRXPATH, 0x08);
  83. jade_write_indirect(cs, jade_HDLC1SERTXPATH, 0x00);
  84. jade_write_indirect(cs, jade_HDLC2SERTXPATH, 0x00);
  85. cs->BC_Write_Reg(cs, jade, jade_HDLC_XCCR, 0x07);
  86. cs->BC_Write_Reg(cs, jade, jade_HDLC_RCCR, 0x07);
  87. if (bc == 0) {
  88. cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAX, 0x00);
  89. cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAR, 0x00);
  90. } else {
  91. cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAX, 0x04);
  92. cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAR, 0x04);
  93. }
  94. switch (mode) {
  95. case (L1_MODE_NULL):
  96. cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, jadeMODE_TMO);
  97. break;
  98. case (L1_MODE_TRANS):
  99. cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (jadeMODE_TMO | jadeMODE_RAC | jadeMODE_XAC));
  100. break;
  101. case (L1_MODE_HDLC):
  102. cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (jadeMODE_RAC | jadeMODE_XAC));
  103. break;
  104. }
  105. if (mode) {
  106. cs->BC_Write_Reg(cs, jade, jade_HDLC_RCMD, (jadeRCMD_RRES | jadeRCMD_RMC));
  107. cs->BC_Write_Reg(cs, jade, jade_HDLC_XCMD, jadeXCMD_XRES);
  108. /* Unmask ints */
  109. cs->BC_Write_Reg(cs, jade, jade_HDLC_IMR, 0xF8);
  110. }
  111. else
  112. /* Mask ints */
  113. cs->BC_Write_Reg(cs, jade, jade_HDLC_IMR, 0x00);
  114. }
  115. static void
  116. jade_l2l1(struct PStack *st, int pr, void *arg)
  117. {
  118. struct BCState *bcs = st->l1.bcs;
  119. struct sk_buff *skb = arg;
  120. u_long flags;
  121. switch (pr) {
  122. case (PH_DATA | REQUEST):
  123. spin_lock_irqsave(&bcs->cs->lock, flags);
  124. if (bcs->tx_skb) {
  125. skb_queue_tail(&bcs->squeue, skb);
  126. } else {
  127. bcs->tx_skb = skb;
  128. test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
  129. bcs->hw.hscx.count = 0;
  130. bcs->cs->BC_Send_Data(bcs);
  131. }
  132. spin_unlock_irqrestore(&bcs->cs->lock, flags);
  133. break;
  134. case (PH_PULL | INDICATION):
  135. spin_lock_irqsave(&bcs->cs->lock, flags);
  136. if (bcs->tx_skb) {
  137. printk(KERN_WARNING "jade_l2l1: this shouldn't happen\n");
  138. } else {
  139. test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
  140. bcs->tx_skb = skb;
  141. bcs->hw.hscx.count = 0;
  142. bcs->cs->BC_Send_Data(bcs);
  143. }
  144. spin_unlock_irqrestore(&bcs->cs->lock, flags);
  145. break;
  146. case (PH_PULL | REQUEST):
  147. if (!bcs->tx_skb) {
  148. test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
  149. st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
  150. } else
  151. test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
  152. break;
  153. case (PH_ACTIVATE | REQUEST):
  154. spin_lock_irqsave(&bcs->cs->lock, flags);
  155. test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
  156. modejade(bcs, st->l1.mode, st->l1.bc);
  157. spin_unlock_irqrestore(&bcs->cs->lock, flags);
  158. l1_msg_b(st, pr, arg);
  159. break;
  160. case (PH_DEACTIVATE | REQUEST):
  161. l1_msg_b(st, pr, arg);
  162. break;
  163. case (PH_DEACTIVATE | CONFIRM):
  164. spin_lock_irqsave(&bcs->cs->lock, flags);
  165. test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
  166. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  167. modejade(bcs, 0, st->l1.bc);
  168. spin_unlock_irqrestore(&bcs->cs->lock, flags);
  169. st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
  170. break;
  171. }
  172. }
  173. static void
  174. close_jadestate(struct BCState *bcs)
  175. {
  176. modejade(bcs, 0, bcs->channel);
  177. if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
  178. kfree(bcs->hw.hscx.rcvbuf);
  179. bcs->hw.hscx.rcvbuf = NULL;
  180. kfree(bcs->blog);
  181. bcs->blog = NULL;
  182. skb_queue_purge(&bcs->rqueue);
  183. skb_queue_purge(&bcs->squeue);
  184. if (bcs->tx_skb) {
  185. dev_kfree_skb_any(bcs->tx_skb);
  186. bcs->tx_skb = NULL;
  187. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  188. }
  189. }
  190. }
  191. static int
  192. open_jadestate(struct IsdnCardState *cs, struct BCState *bcs)
  193. {
  194. if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
  195. if (!(bcs->hw.hscx.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
  196. printk(KERN_WARNING
  197. "HiSax: No memory for hscx.rcvbuf\n");
  198. test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
  199. return (1);
  200. }
  201. if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
  202. printk(KERN_WARNING
  203. "HiSax: No memory for bcs->blog\n");
  204. test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
  205. kfree(bcs->hw.hscx.rcvbuf);
  206. bcs->hw.hscx.rcvbuf = NULL;
  207. return (2);
  208. }
  209. skb_queue_head_init(&bcs->rqueue);
  210. skb_queue_head_init(&bcs->squeue);
  211. }
  212. bcs->tx_skb = NULL;
  213. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  214. bcs->event = 0;
  215. bcs->hw.hscx.rcvidx = 0;
  216. bcs->tx_cnt = 0;
  217. return (0);
  218. }
  219. static int
  220. setstack_jade(struct PStack *st, struct BCState *bcs)
  221. {
  222. bcs->channel = st->l1.bc;
  223. if (open_jadestate(st->l1.hardware, bcs))
  224. return (-1);
  225. st->l1.bcs = bcs;
  226. st->l2.l2l1 = jade_l2l1;
  227. setstack_manager(st);
  228. bcs->st = st;
  229. setstack_l1_B(st);
  230. return (0);
  231. }
  232. void
  233. clear_pending_jade_ints(struct IsdnCardState *cs)
  234. {
  235. int val;
  236. cs->BC_Write_Reg(cs, 0, jade_HDLC_IMR, 0x00);
  237. cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR, 0x00);
  238. val = cs->BC_Read_Reg(cs, 1, jade_HDLC_ISR);
  239. debugl1(cs, "jade B ISTA %x", val);
  240. val = cs->BC_Read_Reg(cs, 0, jade_HDLC_ISR);
  241. debugl1(cs, "jade A ISTA %x", val);
  242. val = cs->BC_Read_Reg(cs, 1, jade_HDLC_STAR);
  243. debugl1(cs, "jade B STAR %x", val);
  244. val = cs->BC_Read_Reg(cs, 0, jade_HDLC_STAR);
  245. debugl1(cs, "jade A STAR %x", val);
  246. /* Unmask ints */
  247. cs->BC_Write_Reg(cs, 0, jade_HDLC_IMR, 0xF8);
  248. cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR, 0xF8);
  249. }
  250. void
  251. initjade(struct IsdnCardState *cs)
  252. {
  253. cs->bcs[0].BC_SetStack = setstack_jade;
  254. cs->bcs[1].BC_SetStack = setstack_jade;
  255. cs->bcs[0].BC_Close = close_jadestate;
  256. cs->bcs[1].BC_Close = close_jadestate;
  257. cs->bcs[0].hw.hscx.hscx = 0;
  258. cs->bcs[1].hw.hscx.hscx = 1;
  259. /* Stop DSP audio tx/rx */
  260. jade_write_indirect(cs, 0x11, 0x0f);
  261. jade_write_indirect(cs, 0x17, 0x2f);
  262. /* Transparent Mode, RxTx inactive, No Test, No RFS/TFS */
  263. cs->BC_Write_Reg(cs, 0, jade_HDLC_MODE, jadeMODE_TMO);
  264. cs->BC_Write_Reg(cs, 1, jade_HDLC_MODE, jadeMODE_TMO);
  265. /* Power down, 1-Idle, RxTx least significant bit first */
  266. cs->BC_Write_Reg(cs, 0, jade_HDLC_CCR0, 0x00);
  267. cs->BC_Write_Reg(cs, 1, jade_HDLC_CCR0, 0x00);
  268. /* Mask all interrupts */
  269. cs->BC_Write_Reg(cs, 0, jade_HDLC_IMR, 0x00);
  270. cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR, 0x00);
  271. /* Setup host access to hdlc controller */
  272. jade_write_indirect(cs, jade_HDLCCNTRACCESS, (jadeINDIRECT_HAH1 | jadeINDIRECT_HAH2));
  273. /* Unmask HDLC int (don't forget DSP int later on)*/
  274. cs->BC_Write_Reg(cs, -1, jade_INT, (jadeINT_HDLC1 | jadeINT_HDLC2));
  275. /* once again TRANSPARENT */
  276. modejade(cs->bcs, 0, 0);
  277. modejade(cs->bcs + 1, 0, 0);
  278. }