jade.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  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. char tmp[40];
  75. sprintf(tmp, "jade %c mode %d ichan %d",
  76. 'A' + jade, mode, bc);
  77. debugl1(cs, tmp);
  78. }
  79. bcs->mode = mode;
  80. bcs->channel = bc;
  81. cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (mode == L1_MODE_TRANS ? jadeMODE_TMO:0x00));
  82. cs->BC_Write_Reg(cs, jade, jade_HDLC_CCR0, (jadeCCR0_PU|jadeCCR0_ITF));
  83. cs->BC_Write_Reg(cs, jade, jade_HDLC_CCR1, 0x00);
  84. jade_write_indirect(cs, jade_HDLC1SERRXPATH, 0x08);
  85. jade_write_indirect(cs, jade_HDLC2SERRXPATH, 0x08);
  86. jade_write_indirect(cs, jade_HDLC1SERTXPATH, 0x00);
  87. jade_write_indirect(cs, jade_HDLC2SERTXPATH, 0x00);
  88. cs->BC_Write_Reg(cs, jade, jade_HDLC_XCCR, 0x07);
  89. cs->BC_Write_Reg(cs, jade, jade_HDLC_RCCR, 0x07);
  90. if (bc == 0) {
  91. cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAX, 0x00);
  92. cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAR, 0x00);
  93. } else {
  94. cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAX, 0x04);
  95. cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAR, 0x04);
  96. }
  97. switch (mode) {
  98. case (L1_MODE_NULL):
  99. cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, jadeMODE_TMO);
  100. break;
  101. case (L1_MODE_TRANS):
  102. cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (jadeMODE_TMO|jadeMODE_RAC|jadeMODE_XAC));
  103. break;
  104. case (L1_MODE_HDLC):
  105. cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (jadeMODE_RAC|jadeMODE_XAC));
  106. break;
  107. }
  108. if (mode) {
  109. cs->BC_Write_Reg(cs, jade, jade_HDLC_RCMD, (jadeRCMD_RRES|jadeRCMD_RMC));
  110. cs->BC_Write_Reg(cs, jade, jade_HDLC_XCMD, jadeXCMD_XRES);
  111. /* Unmask ints */
  112. cs->BC_Write_Reg(cs, jade, jade_HDLC_IMR, 0xF8);
  113. }
  114. else
  115. /* Mask ints */
  116. cs->BC_Write_Reg(cs, jade, jade_HDLC_IMR, 0x00);
  117. }
  118. static void
  119. jade_l2l1(struct PStack *st, int pr, void *arg)
  120. {
  121. struct BCState *bcs = st->l1.bcs;
  122. struct sk_buff *skb = arg;
  123. u_long flags;
  124. switch (pr) {
  125. case (PH_DATA | REQUEST):
  126. spin_lock_irqsave(&bcs->cs->lock, flags);
  127. if (bcs->tx_skb) {
  128. skb_queue_tail(&bcs->squeue, skb);
  129. } else {
  130. bcs->tx_skb = skb;
  131. test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
  132. bcs->hw.hscx.count = 0;
  133. bcs->cs->BC_Send_Data(bcs);
  134. }
  135. spin_unlock_irqrestore(&bcs->cs->lock, flags);
  136. break;
  137. case (PH_PULL | INDICATION):
  138. spin_lock_irqsave(&bcs->cs->lock, flags);
  139. if (bcs->tx_skb) {
  140. printk(KERN_WARNING "jade_l2l1: this shouldn't happen\n");
  141. } else {
  142. test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
  143. bcs->tx_skb = skb;
  144. bcs->hw.hscx.count = 0;
  145. bcs->cs->BC_Send_Data(bcs);
  146. }
  147. spin_unlock_irqrestore(&bcs->cs->lock, flags);
  148. break;
  149. case (PH_PULL | REQUEST):
  150. if (!bcs->tx_skb) {
  151. test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
  152. st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
  153. } else
  154. test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
  155. break;
  156. case (PH_ACTIVATE | REQUEST):
  157. spin_lock_irqsave(&bcs->cs->lock, flags);
  158. test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
  159. modejade(bcs, st->l1.mode, st->l1.bc);
  160. spin_unlock_irqrestore(&bcs->cs->lock, flags);
  161. l1_msg_b(st, pr, arg);
  162. break;
  163. case (PH_DEACTIVATE | REQUEST):
  164. l1_msg_b(st, pr, arg);
  165. break;
  166. case (PH_DEACTIVATE | CONFIRM):
  167. spin_lock_irqsave(&bcs->cs->lock, flags);
  168. test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
  169. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  170. modejade(bcs, 0, st->l1.bc);
  171. spin_unlock_irqrestore(&bcs->cs->lock, flags);
  172. st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
  173. break;
  174. }
  175. }
  176. static void
  177. close_jadestate(struct BCState *bcs)
  178. {
  179. modejade(bcs, 0, bcs->channel);
  180. if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
  181. kfree(bcs->hw.hscx.rcvbuf);
  182. bcs->hw.hscx.rcvbuf = NULL;
  183. kfree(bcs->blog);
  184. bcs->blog = NULL;
  185. skb_queue_purge(&bcs->rqueue);
  186. skb_queue_purge(&bcs->squeue);
  187. if (bcs->tx_skb) {
  188. dev_kfree_skb_any(bcs->tx_skb);
  189. bcs->tx_skb = NULL;
  190. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  191. }
  192. }
  193. }
  194. static int
  195. open_jadestate(struct IsdnCardState *cs, struct BCState *bcs)
  196. {
  197. if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
  198. if (!(bcs->hw.hscx.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
  199. printk(KERN_WARNING
  200. "HiSax: No memory for hscx.rcvbuf\n");
  201. test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
  202. return (1);
  203. }
  204. if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
  205. printk(KERN_WARNING
  206. "HiSax: No memory for bcs->blog\n");
  207. test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
  208. kfree(bcs->hw.hscx.rcvbuf);
  209. bcs->hw.hscx.rcvbuf = NULL;
  210. return (2);
  211. }
  212. skb_queue_head_init(&bcs->rqueue);
  213. skb_queue_head_init(&bcs->squeue);
  214. }
  215. bcs->tx_skb = NULL;
  216. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  217. bcs->event = 0;
  218. bcs->hw.hscx.rcvidx = 0;
  219. bcs->tx_cnt = 0;
  220. return (0);
  221. }
  222. static int
  223. setstack_jade(struct PStack *st, struct BCState *bcs)
  224. {
  225. bcs->channel = st->l1.bc;
  226. if (open_jadestate(st->l1.hardware, bcs))
  227. return (-1);
  228. st->l1.bcs = bcs;
  229. st->l2.l2l1 = jade_l2l1;
  230. setstack_manager(st);
  231. bcs->st = st;
  232. setstack_l1_B(st);
  233. return (0);
  234. }
  235. void
  236. clear_pending_jade_ints(struct IsdnCardState *cs)
  237. {
  238. int val;
  239. char tmp[64];
  240. cs->BC_Write_Reg(cs, 0, jade_HDLC_IMR, 0x00);
  241. cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR, 0x00);
  242. val = cs->BC_Read_Reg(cs, 1, jade_HDLC_ISR);
  243. sprintf(tmp, "jade B ISTA %x", val);
  244. debugl1(cs, tmp);
  245. val = cs->BC_Read_Reg(cs, 0, jade_HDLC_ISR);
  246. sprintf(tmp, "jade A ISTA %x", val);
  247. debugl1(cs, tmp);
  248. val = cs->BC_Read_Reg(cs, 1, jade_HDLC_STAR);
  249. sprintf(tmp, "jade B STAR %x", val);
  250. debugl1(cs, tmp);
  251. val = cs->BC_Read_Reg(cs, 0, jade_HDLC_STAR);
  252. sprintf(tmp, "jade A STAR %x", val);
  253. debugl1(cs, tmp);
  254. /* Unmask ints */
  255. cs->BC_Write_Reg(cs, 0, jade_HDLC_IMR, 0xF8);
  256. cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR, 0xF8);
  257. }
  258. void
  259. initjade(struct IsdnCardState *cs)
  260. {
  261. cs->bcs[0].BC_SetStack = setstack_jade;
  262. cs->bcs[1].BC_SetStack = setstack_jade;
  263. cs->bcs[0].BC_Close = close_jadestate;
  264. cs->bcs[1].BC_Close = close_jadestate;
  265. cs->bcs[0].hw.hscx.hscx = 0;
  266. cs->bcs[1].hw.hscx.hscx = 1;
  267. /* Stop DSP audio tx/rx */
  268. jade_write_indirect(cs, 0x11, 0x0f);
  269. jade_write_indirect(cs, 0x17, 0x2f);
  270. /* Transparent Mode, RxTx inactive, No Test, No RFS/TFS */
  271. cs->BC_Write_Reg(cs, 0, jade_HDLC_MODE, jadeMODE_TMO);
  272. cs->BC_Write_Reg(cs, 1, jade_HDLC_MODE, jadeMODE_TMO);
  273. /* Power down, 1-Idle, RxTx least significant bit first */
  274. cs->BC_Write_Reg(cs, 0, jade_HDLC_CCR0, 0x00);
  275. cs->BC_Write_Reg(cs, 1, jade_HDLC_CCR0, 0x00);
  276. /* Mask all interrupts */
  277. cs->BC_Write_Reg(cs, 0, jade_HDLC_IMR, 0x00);
  278. cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR, 0x00);
  279. /* Setup host access to hdlc controller */
  280. jade_write_indirect(cs, jade_HDLCCNTRACCESS, (jadeINDIRECT_HAH1|jadeINDIRECT_HAH2));
  281. /* Unmask HDLC int (don't forget DSP int later on)*/
  282. cs->BC_Write_Reg(cs, -1,jade_INT, (jadeINT_HDLC1|jadeINT_HDLC2));
  283. /* once again TRANSPARENT */
  284. modejade(cs->bcs, 0, 0);
  285. modejade(cs->bcs + 1, 0, 0);
  286. }