icc.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:18k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: icc.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  2.  *
  3.  * ICC specific routines
  4.  *
  5.  * Author       Matt Henderson & Guy Ellis
  6.  * Copyright    by Traverse Technologies Pty Ltd, www.travers.com.au
  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.  * 1999.6.25 Initial implementation of routines for Siemens ISDN
  12.  * Communication Controller PEB 2070 based on the ISAC routines
  13.  * written by Karsten Keil.
  14.  *
  15.  */
  16. #define __NO_VERSION__
  17. #include <linux/init.h>
  18. #include "hisax.h"
  19. #include "icc.h"
  20. // #include "arcofi.h"
  21. #include "isdnl1.h"
  22. #include <linux/interrupt.h>
  23. #define DBUSY_TIMER_VALUE 80
  24. #define ARCOFI_USE 0
  25. static char *ICCVer[] __initdata =
  26. {"2070 A1/A3", "2070 B1", "2070 B2/B3", "2070 V2.4"};
  27. void
  28. ICCVersion(struct IsdnCardState *cs, char *s)
  29. {
  30. int val;
  31. val = cs->readisac(cs, ICC_RBCH);
  32. printk(KERN_INFO "%s ICC version (%x): %sn", s, val, ICCVer[(val >> 5) & 3]);
  33. }
  34. static void
  35. ph_command(struct IsdnCardState *cs, unsigned int command)
  36. {
  37. if (cs->debug & L1_DEB_ISAC)
  38. debugl1(cs, "ph_command %x", command);
  39. cs->writeisac(cs, ICC_CIX0, (command << 2) | 3);
  40. }
  41. static void
  42. icc_new_ph(struct IsdnCardState *cs)
  43. {
  44. switch (cs->dc.icc.ph_state) {
  45. case (ICC_IND_EI1):
  46. ph_command(cs, ICC_CMD_DI);
  47. l1_msg(cs, HW_RESET | INDICATION, NULL);
  48. break;
  49. case (ICC_IND_DC):
  50. l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL);
  51. break;
  52. case (ICC_IND_DR):
  53. l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
  54. break;
  55. case (ICC_IND_PU):
  56. l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
  57. break;
  58. case (ICC_IND_FJ):
  59. l1_msg(cs, HW_RSYNC | INDICATION, NULL);
  60. break;
  61. case (ICC_IND_AR):
  62. l1_msg(cs, HW_INFO2 | INDICATION, NULL);
  63. break;
  64. case (ICC_IND_AI):
  65. l1_msg(cs, HW_INFO4 | INDICATION, NULL);
  66. break;
  67. default:
  68. break;
  69. }
  70. }
  71. static void
  72. icc_bh(struct IsdnCardState *cs)
  73. {
  74. struct PStack *stptr;
  75. if (!cs)
  76. return;
  77. if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
  78. if (cs->debug)
  79. debugl1(cs, "D-Channel Busy cleared");
  80. stptr = cs->stlist;
  81. while (stptr != NULL) {
  82. stptr->l1.l1l2(stptr, PH_PAUSE | CONFIRM, NULL);
  83. stptr = stptr->next;
  84. }
  85. }
  86. if (test_and_clear_bit(D_L1STATECHANGE, &cs->event))
  87. icc_new_ph(cs);
  88. if (test_and_clear_bit(D_RCVBUFREADY, &cs->event))
  89. DChannel_proc_rcv(cs);
  90. if (test_and_clear_bit(D_XMTBUFREADY, &cs->event))
  91. DChannel_proc_xmt(cs);
  92. #if ARCOFI_USE
  93. if (!test_bit(HW_ARCOFI, &cs->HW_Flags))
  94. return;
  95. if (test_and_clear_bit(D_RX_MON1, &cs->event))
  96. arcofi_fsm(cs, ARCOFI_RX_END, NULL);
  97. if (test_and_clear_bit(D_TX_MON1, &cs->event))
  98. arcofi_fsm(cs, ARCOFI_TX_END, NULL);
  99. #endif
  100. }
  101. void
  102. icc_empty_fifo(struct IsdnCardState *cs, int count)
  103. {
  104. u_char *ptr;
  105. long flags;
  106. if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO))
  107. debugl1(cs, "icc_empty_fifo");
  108. if ((cs->rcvidx + count) >= MAX_DFRAME_LEN_L1) {
  109. if (cs->debug & L1_DEB_WARN)
  110. debugl1(cs, "icc_empty_fifo overrun %d",
  111. cs->rcvidx + count);
  112. cs->writeisac(cs, ICC_CMDR, 0x80);
  113. cs->rcvidx = 0;
  114. return;
  115. }
  116. ptr = cs->rcvbuf + cs->rcvidx;
  117. cs->rcvidx += count;
  118. save_flags(flags);
  119. cli();
  120. cs->readisacfifo(cs, ptr, count);
  121. cs->writeisac(cs, ICC_CMDR, 0x80);
  122. restore_flags(flags);
  123. if (cs->debug & L1_DEB_ISAC_FIFO) {
  124. char *t = cs->dlog;
  125. t += sprintf(t, "icc_empty_fifo cnt %d", count);
  126. QuickHex(t, ptr, count);
  127. debugl1(cs, cs->dlog);
  128. }
  129. }
  130. static void
  131. icc_fill_fifo(struct IsdnCardState *cs)
  132. {
  133. int count, more;
  134. u_char *ptr;
  135. long flags;
  136. if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO))
  137. debugl1(cs, "icc_fill_fifo");
  138. if (!cs->tx_skb)
  139. return;
  140. count = cs->tx_skb->len;
  141. if (count <= 0)
  142. return;
  143. more = 0;
  144. if (count > 32) {
  145. more = !0;
  146. count = 32;
  147. }
  148. save_flags(flags);
  149. cli();
  150. ptr = cs->tx_skb->data;
  151. skb_pull(cs->tx_skb, count);
  152. cs->tx_cnt += count;
  153. cs->writeisacfifo(cs, ptr, count);
  154. cs->writeisac(cs, ICC_CMDR, more ? 0x8 : 0xa);
  155. if (test_and_set_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
  156. debugl1(cs, "icc_fill_fifo dbusytimer running");
  157. del_timer(&cs->dbusytimer);
  158. }
  159. init_timer(&cs->dbusytimer);
  160. cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
  161. add_timer(&cs->dbusytimer);
  162. restore_flags(flags);
  163. if (cs->debug & L1_DEB_ISAC_FIFO) {
  164. char *t = cs->dlog;
  165. t += sprintf(t, "icc_fill_fifo cnt %d", count);
  166. QuickHex(t, ptr, count);
  167. debugl1(cs, cs->dlog);
  168. }
  169. }
  170. void
  171. icc_sched_event(struct IsdnCardState *cs, int event)
  172. {
  173. test_and_set_bit(event, &cs->event);
  174. queue_task(&cs->tqueue, &tq_immediate);
  175. mark_bh(IMMEDIATE_BH);
  176. }
  177. void
  178. icc_interrupt(struct IsdnCardState *cs, u_char val)
  179. {
  180. u_char exval, v1;
  181. struct sk_buff *skb;
  182. unsigned int count;
  183. long flags;
  184. if (cs->debug & L1_DEB_ISAC)
  185. debugl1(cs, "ICC interrupt %x", val);
  186. if (val & 0x80) { /* RME */
  187. exval = cs->readisac(cs, ICC_RSTA);
  188. if ((exval & 0x70) != 0x20) {
  189. if (exval & 0x40) {
  190. if (cs->debug & L1_DEB_WARN)
  191. debugl1(cs, "ICC RDO");
  192. #ifdef ERROR_STATISTIC
  193. cs->err_rx++;
  194. #endif
  195. }
  196. if (!(exval & 0x20)) {
  197. if (cs->debug & L1_DEB_WARN)
  198. debugl1(cs, "ICC CRC error");
  199. #ifdef ERROR_STATISTIC
  200. cs->err_crc++;
  201. #endif
  202. }
  203. cs->writeisac(cs, ICC_CMDR, 0x80);
  204. } else {
  205. count = cs->readisac(cs, ICC_RBCL) & 0x1f;
  206. if (count == 0)
  207. count = 32;
  208. icc_empty_fifo(cs, count);
  209. save_flags(flags);
  210. cli();
  211. if ((count = cs->rcvidx) > 0) {
  212. cs->rcvidx = 0;
  213. if (!(skb = alloc_skb(count, GFP_ATOMIC)))
  214. printk(KERN_WARNING "HiSax: D receive out of memoryn");
  215. else {
  216. memcpy(skb_put(skb, count), cs->rcvbuf, count);
  217. skb_queue_tail(&cs->rq, skb);
  218. }
  219. }
  220. restore_flags(flags);
  221. }
  222. cs->rcvidx = 0;
  223. icc_sched_event(cs, D_RCVBUFREADY);
  224. }
  225. if (val & 0x40) { /* RPF */
  226. icc_empty_fifo(cs, 32);
  227. }
  228. if (val & 0x20) { /* RSC */
  229. /* never */
  230. if (cs->debug & L1_DEB_WARN)
  231. debugl1(cs, "ICC RSC interrupt");
  232. }
  233. if (val & 0x10) { /* XPR */
  234. if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
  235. del_timer(&cs->dbusytimer);
  236. if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
  237. icc_sched_event(cs, D_CLEARBUSY);
  238. if (cs->tx_skb) {
  239. if (cs->tx_skb->len) {
  240. icc_fill_fifo(cs);
  241. goto afterXPR;
  242. } else {
  243. dev_kfree_skb_irq(cs->tx_skb);
  244. cs->tx_cnt = 0;
  245. cs->tx_skb = NULL;
  246. }
  247. }
  248. if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
  249. cs->tx_cnt = 0;
  250. icc_fill_fifo(cs);
  251. } else
  252. icc_sched_event(cs, D_XMTBUFREADY);
  253. }
  254.       afterXPR:
  255. if (val & 0x04) { /* CISQ */
  256. exval = cs->readisac(cs, ICC_CIR0);
  257. if (cs->debug & L1_DEB_ISAC)
  258. debugl1(cs, "ICC CIR0 %02X", exval );
  259. if (exval & 2) {
  260. cs->dc.icc.ph_state = (exval >> 2) & 0xf;
  261. if (cs->debug & L1_DEB_ISAC)
  262. debugl1(cs, "ph_state change %x", cs->dc.icc.ph_state);
  263. icc_sched_event(cs, D_L1STATECHANGE);
  264. }
  265. if (exval & 1) {
  266. exval = cs->readisac(cs, ICC_CIR1);
  267. if (cs->debug & L1_DEB_ISAC)
  268. debugl1(cs, "ICC CIR1 %02X", exval );
  269. }
  270. }
  271. if (val & 0x02) { /* SIN */
  272. /* never */
  273. if (cs->debug & L1_DEB_WARN)
  274. debugl1(cs, "ICC SIN interrupt");
  275. }
  276. if (val & 0x01) { /* EXI */
  277. exval = cs->readisac(cs, ICC_EXIR);
  278. if (cs->debug & L1_DEB_WARN)
  279. debugl1(cs, "ICC EXIR %02x", exval);
  280. if (exval & 0x80) {  /* XMR */
  281. debugl1(cs, "ICC XMR");
  282. printk(KERN_WARNING "HiSax: ICC XMRn");
  283. }
  284. if (exval & 0x40) {  /* XDU */
  285. debugl1(cs, "ICC XDU");
  286. printk(KERN_WARNING "HiSax: ICC XDUn");
  287. #ifdef ERROR_STATISTIC
  288. cs->err_tx++;
  289. #endif
  290. if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
  291. del_timer(&cs->dbusytimer);
  292. if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
  293. icc_sched_event(cs, D_CLEARBUSY);
  294. if (cs->tx_skb) { /* Restart frame */
  295. skb_push(cs->tx_skb, cs->tx_cnt);
  296. cs->tx_cnt = 0;
  297. icc_fill_fifo(cs);
  298. } else {
  299. printk(KERN_WARNING "HiSax: ICC XDU no skbn");
  300. debugl1(cs, "ICC XDU no skb");
  301. }
  302. }
  303. if (exval & 0x04) {  /* MOS */
  304. v1 = cs->readisac(cs, ICC_MOSR);
  305. if (cs->debug & L1_DEB_MONITOR)
  306. debugl1(cs, "ICC MOSR %02x", v1);
  307. #if ARCOFI_USE
  308. if (v1 & 0x08) {
  309. if (!cs->dc.icc.mon_rx) {
  310. if (!(cs->dc.icc.mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC))) {
  311. if (cs->debug & L1_DEB_WARN)
  312. debugl1(cs, "ICC MON RX out of memory!");
  313. cs->dc.icc.mocr &= 0xf0;
  314. cs->dc.icc.mocr |= 0x0a;
  315. cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr);
  316. goto afterMONR0;
  317. } else
  318. cs->dc.icc.mon_rxp = 0;
  319. }
  320. if (cs->dc.icc.mon_rxp >= MAX_MON_FRAME) {
  321. cs->dc.icc.mocr &= 0xf0;
  322. cs->dc.icc.mocr |= 0x0a;
  323. cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr);
  324. cs->dc.icc.mon_rxp = 0;
  325. if (cs->debug & L1_DEB_WARN)
  326. debugl1(cs, "ICC MON RX overflow!");
  327. goto afterMONR0;
  328. }
  329. cs->dc.icc.mon_rx[cs->dc.icc.mon_rxp++] = cs->readisac(cs, ICC_MOR0);
  330. if (cs->debug & L1_DEB_MONITOR)
  331. debugl1(cs, "ICC MOR0 %02x", cs->dc.icc.mon_rx[cs->dc.icc.mon_rxp -1]);
  332. if (cs->dc.icc.mon_rxp == 1) {
  333. cs->dc.icc.mocr |= 0x04;
  334. cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr);
  335. }
  336. }
  337.       afterMONR0:
  338. if (v1 & 0x80) {
  339. if (!cs->dc.icc.mon_rx) {
  340. if (!(cs->dc.icc.mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC))) {
  341. if (cs->debug & L1_DEB_WARN)
  342. debugl1(cs, "ICC MON RX out of memory!");
  343. cs->dc.icc.mocr &= 0x0f;
  344. cs->dc.icc.mocr |= 0xa0;
  345. cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr);
  346. goto afterMONR1;
  347. } else
  348. cs->dc.icc.mon_rxp = 0;
  349. }
  350. if (cs->dc.icc.mon_rxp >= MAX_MON_FRAME) {
  351. cs->dc.icc.mocr &= 0x0f;
  352. cs->dc.icc.mocr |= 0xa0;
  353. cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr);
  354. cs->dc.icc.mon_rxp = 0;
  355. if (cs->debug & L1_DEB_WARN)
  356. debugl1(cs, "ICC MON RX overflow!");
  357. goto afterMONR1;
  358. }
  359. cs->dc.icc.mon_rx[cs->dc.icc.mon_rxp++] = cs->readisac(cs, ICC_MOR1);
  360. if (cs->debug & L1_DEB_MONITOR)
  361. debugl1(cs, "ICC MOR1 %02x", cs->dc.icc.mon_rx[cs->dc.icc.mon_rxp -1]);
  362. cs->dc.icc.mocr |= 0x40;
  363. cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr);
  364. }
  365.       afterMONR1:
  366. if (v1 & 0x04) {
  367. cs->dc.icc.mocr &= 0xf0;
  368. cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr);
  369. cs->dc.icc.mocr |= 0x0a;
  370. cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr);
  371. icc_sched_event(cs, D_RX_MON0);
  372. }
  373. if (v1 & 0x40) {
  374. cs->dc.icc.mocr &= 0x0f;
  375. cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr);
  376. cs->dc.icc.mocr |= 0xa0;
  377. cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr);
  378. icc_sched_event(cs, D_RX_MON1);
  379. }
  380. if (v1 & 0x02) {
  381. if ((!cs->dc.icc.mon_tx) || (cs->dc.icc.mon_txc && 
  382. (cs->dc.icc.mon_txp >= cs->dc.icc.mon_txc) && 
  383. !(v1 & 0x08))) {
  384. cs->dc.icc.mocr &= 0xf0;
  385. cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr);
  386. cs->dc.icc.mocr |= 0x0a;
  387. cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr);
  388. if (cs->dc.icc.mon_txc &&
  389. (cs->dc.icc.mon_txp >= cs->dc.icc.mon_txc))
  390. icc_sched_event(cs, D_TX_MON0);
  391. goto AfterMOX0;
  392. }
  393. if (cs->dc.icc.mon_txc && (cs->dc.icc.mon_txp >= cs->dc.icc.mon_txc)) {
  394. icc_sched_event(cs, D_TX_MON0);
  395. goto AfterMOX0;
  396. }
  397. cs->writeisac(cs, ICC_MOX0,
  398. cs->dc.icc.mon_tx[cs->dc.icc.mon_txp++]);
  399. if (cs->debug & L1_DEB_MONITOR)
  400. debugl1(cs, "ICC %02x -> MOX0", cs->dc.icc.mon_tx[cs->dc.icc.mon_txp -1]);
  401. }
  402.       AfterMOX0:
  403. if (v1 & 0x20) {
  404. if ((!cs->dc.icc.mon_tx) || (cs->dc.icc.mon_txc && 
  405. (cs->dc.icc.mon_txp >= cs->dc.icc.mon_txc) && 
  406. !(v1 & 0x80))) {
  407. cs->dc.icc.mocr &= 0x0f;
  408. cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr);
  409. cs->dc.icc.mocr |= 0xa0;
  410. cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr);
  411. if (cs->dc.icc.mon_txc &&
  412. (cs->dc.icc.mon_txp >= cs->dc.icc.mon_txc))
  413. icc_sched_event(cs, D_TX_MON1);
  414. goto AfterMOX1;
  415. }
  416. if (cs->dc.icc.mon_txc && (cs->dc.icc.mon_txp >= cs->dc.icc.mon_txc)) {
  417. icc_sched_event(cs, D_TX_MON1);
  418. goto AfterMOX1;
  419. }
  420. cs->writeisac(cs, ICC_MOX1,
  421. cs->dc.icc.mon_tx[cs->dc.icc.mon_txp++]);
  422. if (cs->debug & L1_DEB_MONITOR)
  423. debugl1(cs, "ICC %02x -> MOX1", cs->dc.icc.mon_tx[cs->dc.icc.mon_txp -1]);
  424. }
  425.       AfterMOX1:
  426. #endif
  427. }
  428. }
  429. }
  430. static void
  431. ICC_l1hw(struct PStack *st, int pr, void *arg)
  432. {
  433. struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
  434. struct sk_buff *skb = arg;
  435. int  val;
  436. switch (pr) {
  437. case (PH_DATA |REQUEST):
  438. if (cs->debug & DEB_DLOG_HEX)
  439. LogFrame(cs, skb->data, skb->len);
  440. if (cs->debug & DEB_DLOG_VERBOSE)
  441. dlogframe(cs, skb, 0);
  442. if (cs->tx_skb) {
  443. skb_queue_tail(&cs->sq, skb);
  444. #ifdef L2FRAME_DEBUG /* psa */
  445. if (cs->debug & L1_DEB_LAPD)
  446. Logl2Frame(cs, skb, "PH_DATA Queued", 0);
  447. #endif
  448. } else {
  449. cs->tx_skb = skb;
  450. cs->tx_cnt = 0;
  451. #ifdef L2FRAME_DEBUG /* psa */
  452. if (cs->debug & L1_DEB_LAPD)
  453. Logl2Frame(cs, skb, "PH_DATA", 0);
  454. #endif
  455. icc_fill_fifo(cs);
  456. }
  457. break;
  458. case (PH_PULL |INDICATION):
  459. if (cs->tx_skb) {
  460. if (cs->debug & L1_DEB_WARN)
  461. debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
  462. skb_queue_tail(&cs->sq, skb);
  463. break;
  464. }
  465. if (cs->debug & DEB_DLOG_HEX)
  466. LogFrame(cs, skb->data, skb->len);
  467. if (cs->debug & DEB_DLOG_VERBOSE)
  468. dlogframe(cs, skb, 0);
  469. cs->tx_skb = skb;
  470. cs->tx_cnt = 0;
  471. #ifdef L2FRAME_DEBUG /* psa */
  472. if (cs->debug & L1_DEB_LAPD)
  473. Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
  474. #endif
  475. icc_fill_fifo(cs);
  476. break;
  477. case (PH_PULL | REQUEST):
  478. #ifdef L2FRAME_DEBUG /* psa */
  479. if (cs->debug & L1_DEB_LAPD)
  480. debugl1(cs, "-> PH_REQUEST_PULL");
  481. #endif
  482. if (!cs->tx_skb) {
  483. test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
  484. st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
  485. } else
  486. test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
  487. break;
  488. case (HW_RESET | REQUEST):
  489. if ((cs->dc.icc.ph_state == ICC_IND_EI1) ||
  490. (cs->dc.icc.ph_state == ICC_IND_DR))
  491.         ph_command(cs, ICC_CMD_DI);
  492. else
  493. ph_command(cs, ICC_CMD_RES);
  494. break;
  495. case (HW_ENABLE | REQUEST):
  496. ph_command(cs, ICC_CMD_DI);
  497. break;
  498. case (HW_INFO1 | REQUEST):
  499. ph_command(cs, ICC_CMD_AR);
  500. break;
  501. case (HW_INFO3 | REQUEST):
  502. ph_command(cs, ICC_CMD_AI);
  503. break;
  504. case (HW_TESTLOOP | REQUEST):
  505. val = 0;
  506. if (1 & (long) arg)
  507. val |= 0x0c;
  508. if (2 & (long) arg)
  509. val |= 0x3;
  510. if (test_bit(HW_IOM1, &cs->HW_Flags)) {
  511. /* IOM 1 Mode */
  512. if (!val) {
  513. cs->writeisac(cs, ICC_SPCR, 0xa);
  514. cs->writeisac(cs, ICC_ADF1, 0x2);
  515. } else {
  516. cs->writeisac(cs, ICC_SPCR, val);
  517. cs->writeisac(cs, ICC_ADF1, 0xa);
  518. }
  519. } else {
  520. /* IOM 2 Mode */
  521. cs->writeisac(cs, ICC_SPCR, val);
  522. if (val)
  523. cs->writeisac(cs, ICC_ADF1, 0x8);
  524. else
  525. cs->writeisac(cs, ICC_ADF1, 0x0);
  526. }
  527. break;
  528. case (HW_DEACTIVATE | RESPONSE):
  529. skb_queue_purge(&cs->rq);
  530. skb_queue_purge(&cs->sq);
  531. if (cs->tx_skb) {
  532. dev_kfree_skb_any(cs->tx_skb);
  533. cs->tx_skb = NULL;
  534. }
  535. if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
  536. del_timer(&cs->dbusytimer);
  537. if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
  538. icc_sched_event(cs, D_CLEARBUSY);
  539. break;
  540. default:
  541. if (cs->debug & L1_DEB_WARN)
  542. debugl1(cs, "icc_l1hw unknown %04x", pr);
  543. break;
  544. }
  545. }
  546. void
  547. setstack_icc(struct PStack *st, struct IsdnCardState *cs)
  548. {
  549. st->l1.l1hw = ICC_l1hw;
  550. }
  551. void 
  552. DC_Close_icc(struct IsdnCardState *cs) {
  553. if (cs->dc.icc.mon_rx) {
  554. kfree(cs->dc.icc.mon_rx);
  555. cs->dc.icc.mon_rx = NULL;
  556. }
  557. if (cs->dc.icc.mon_tx) {
  558. kfree(cs->dc.icc.mon_tx);
  559. cs->dc.icc.mon_tx = NULL;
  560. }
  561. }
  562. static void
  563. dbusy_timer_handler(struct IsdnCardState *cs)
  564. {
  565. struct PStack *stptr;
  566. int rbch, star;
  567. if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
  568. rbch = cs->readisac(cs, ICC_RBCH);
  569. star = cs->readisac(cs, ICC_STAR);
  570. if (cs->debug) 
  571. debugl1(cs, "D-Channel Busy RBCH %02x STAR %02x",
  572. rbch, star);
  573. if (rbch & ICC_RBCH_XAC) { /* D-Channel Busy */
  574. test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags);
  575. stptr = cs->stlist;
  576. while (stptr != NULL) {
  577. stptr->l1.l1l2(stptr, PH_PAUSE | INDICATION, NULL);
  578. stptr = stptr->next;
  579. }
  580. } else {
  581. /* discard frame; reset transceiver */
  582. test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags);
  583. if (cs->tx_skb) {
  584. dev_kfree_skb_any(cs->tx_skb);
  585. cs->tx_cnt = 0;
  586. cs->tx_skb = NULL;
  587. } else {
  588. printk(KERN_WARNING "HiSax: ICC D-Channel Busy no skbn");
  589. debugl1(cs, "D-Channel Busy no skb");
  590. }
  591. cs->writeisac(cs, ICC_CMDR, 0x01); /* Transmitter reset */
  592. cs->irq_func(cs->irq, cs, NULL);
  593. }
  594. }
  595. }
  596. void __init
  597. initicc(struct IsdnCardState *cs)
  598. {
  599. cs->tqueue.routine = (void *) (void *) icc_bh;
  600. cs->setstack_d = setstack_icc;
  601. cs->DC_Close = DC_Close_icc;
  602. cs->dc.icc.mon_tx = NULL;
  603. cs->dc.icc.mon_rx = NULL;
  604. cs->dbusytimer.function = (void *) dbusy_timer_handler;
  605. cs->dbusytimer.data = (long) cs;
  606. init_timer(&cs->dbusytimer);
  607.    cs->writeisac(cs, ICC_MASK, 0xff);
  608.    cs->dc.icc.mocr = 0xaa;
  609. if (test_bit(HW_IOM1, &cs->HW_Flags)) {
  610. /* IOM 1 Mode */
  611. cs->writeisac(cs, ICC_ADF2, 0x0);
  612. cs->writeisac(cs, ICC_SPCR, 0xa);
  613. cs->writeisac(cs, ICC_ADF1, 0x2);
  614. cs->writeisac(cs, ICC_STCR, 0x70);
  615. cs->writeisac(cs, ICC_MODE, 0xc9);
  616. } else {
  617. /* IOM 2 Mode */
  618. if (!cs->dc.icc.adf2)
  619. cs->dc.icc.adf2 = 0x80;
  620. cs->writeisac(cs, ICC_ADF2, cs->dc.icc.adf2);
  621. cs->writeisac(cs, ICC_SQXR, 0xa0);
  622. cs->writeisac(cs, ICC_SPCR, 0x20);
  623. cs->writeisac(cs, ICC_STCR, 0x70);
  624. cs->writeisac(cs, ICC_MODE, 0xca);
  625. cs->writeisac(cs, ICC_TIMR, 0x00);
  626. cs->writeisac(cs, ICC_ADF1, 0x20);
  627. }
  628. ph_command(cs, ICC_CMD_RES);
  629. cs->writeisac(cs, ICC_MASK, 0x0);
  630. ph_command(cs, ICC_CMD_DI);
  631. }
  632. void __init
  633. clear_pending_icc_ints(struct IsdnCardState *cs)
  634. {
  635. int val, eval;
  636. val = cs->readisac(cs, ICC_STAR);
  637. debugl1(cs, "ICC STAR %x", val);
  638. val = cs->readisac(cs, ICC_MODE);
  639. debugl1(cs, "ICC MODE %x", val);
  640. val = cs->readisac(cs, ICC_ADF2);
  641. debugl1(cs, "ICC ADF2 %x", val);
  642. val = cs->readisac(cs, ICC_ISTA);
  643. debugl1(cs, "ICC ISTA %x", val);
  644. if (val & 0x01) {
  645. eval = cs->readisac(cs, ICC_EXIR);
  646. debugl1(cs, "ICC EXIR %x", eval);
  647. }
  648. val = cs->readisac(cs, ICC_CIR0);
  649. debugl1(cs, "ICC CIR0 %x", val);
  650. cs->dc.icc.ph_state = (val >> 2) & 0xf;
  651. icc_sched_event(cs, D_L1STATECHANGE);
  652. /* Disable all IRQ */
  653. cs->writeisac(cs, ICC_MASK, 0xFF);
  654. }