ipacx.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:29k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* 
  2.  *
  3.  * IPACX specific routines
  4.  *
  5.  * Author       Joerg Petersohn
  6.  * Derived from hisax_isac.c, isac.c, hscx.c and others
  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. #define __NO_VERSION__
  13. #include <linux/kernel.h>
  14. #include <linux/config.h>
  15. #include <linux/init.h>
  16. #include "hisax_if.h"
  17. #include "hisax.h"
  18. #include "isdnl1.h"
  19. #include "ipacx.h"
  20. #define DBUSY_TIMER_VALUE 80
  21. #define TIMER3_VALUE      7000
  22. #define MAX_DFRAME_LEN_L1 300
  23. #define B_FIFO_SIZE       64
  24. #define D_FIFO_SIZE       32
  25. // ipacx interrupt mask values    
  26. #define _MASK_IMASK     0x2E  // global mask
  27. #define _MASKB_IMASK    0x0B
  28. #define _MASKD_IMASK    0x03  // all on
  29. //----------------------------------------------------------
  30. // local function declarations
  31. //----------------------------------------------------------
  32. static void ph_command(struct IsdnCardState *cs, unsigned int command);
  33. static inline void cic_int(struct IsdnCardState *cs);
  34. static void dch_l2l1(struct PStack *st, int pr, void *arg);
  35. static void dbusy_timer_handler(struct IsdnCardState *cs);
  36. static void ipacx_new_ph(struct IsdnCardState *cs);
  37. static void dch_bh(struct IsdnCardState *cs);
  38. static void dch_sched_event(struct IsdnCardState *cs, int event);
  39. static void dch_empty_fifo(struct IsdnCardState *cs, int count);
  40. static void dch_fill_fifo(struct IsdnCardState *cs);
  41. static inline void dch_int(struct IsdnCardState *cs);
  42. static void __devinit dch_setstack(struct PStack *st, struct IsdnCardState *cs);
  43. static void __devinit dch_init(struct IsdnCardState *cs);
  44. static void bch_l2l1(struct PStack *st, int pr, void *arg);
  45. static void bch_sched_event(struct BCState *bcs, int event);
  46. static void bch_empty_fifo(struct BCState *bcs, int count);
  47. static void bch_fill_fifo(struct BCState *bcs);
  48. static void bch_int(struct IsdnCardState *cs, u_char hscx);
  49. static void bch_mode(struct BCState *bcs, int mode, int bc);
  50. static void bch_close_state(struct BCState *bcs);
  51. static int bch_open_state(struct IsdnCardState *cs, struct BCState *bcs);
  52. static int bch_setstack(struct PStack *st, struct BCState *bcs);
  53. static void __devinit bch_init(struct IsdnCardState *cs, int hscx);
  54. static void __init clear_pending_ints(struct IsdnCardState *cs);
  55. //----------------------------------------------------------
  56. // Issue Layer 1 command to chip
  57. //----------------------------------------------------------
  58. static void 
  59. ph_command(struct IsdnCardState *cs, unsigned int command)
  60. {
  61. if (cs->debug &L1_DEB_ISAC)
  62. debugl1(cs, "ph_command (%#x) in (%#x)", command,
  63. cs->dc.isac.ph_state);
  64. //###################################  
  65. // printk(KERN_INFO "ph_command (%#x)n", command);
  66. //###################################  
  67. cs->writeisac(cs, IPACX_CIX0, (command << 4) | 0x0E);
  68. }
  69. //----------------------------------------------------------
  70. // Transceiver interrupt handler
  71. //----------------------------------------------------------
  72. static inline void 
  73. cic_int(struct IsdnCardState *cs)
  74. {
  75. u_char event;
  76. event = cs->readisac(cs, IPACX_CIR0) >> 4;
  77. if (cs->debug &L1_DEB_ISAC) debugl1(cs, "cic_int(event=%#x)", event);
  78. //#########################################  
  79. // printk(KERN_INFO "cic_int(%x)n", event);
  80. //#########################################  
  81.   cs->dc.isac.ph_state = event;
  82.   dch_sched_event(cs, D_L1STATECHANGE);
  83. }
  84. //==========================================================
  85. // D channel functions
  86. //==========================================================
  87. //----------------------------------------------------------
  88. // Command entry point
  89. //----------------------------------------------------------
  90. static void
  91. dch_l2l1(struct PStack *st, int pr, void *arg)
  92. {
  93. struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
  94. struct sk_buff *skb = arg;
  95.   u_char cda1_cr, cda2_cr;
  96. switch (pr) {
  97. case (PH_DATA |REQUEST):
  98. if (cs->debug &DEB_DLOG_HEX)     LogFrame(cs, skb->data, skb->len);
  99. if (cs->debug &DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0);
  100. if (cs->tx_skb) {
  101. skb_queue_tail(&cs->sq, skb);
  102. #ifdef L2FRAME_DEBUG
  103. if (cs->debug &L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA Queued", 0);
  104. #endif
  105. } else {
  106. cs->tx_skb = skb;
  107. cs->tx_cnt = 0;
  108. #ifdef L2FRAME_DEBUG
  109. if (cs->debug &L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA", 0);
  110. #endif
  111. dch_fill_fifo(cs);
  112. }
  113. break;
  114.       
  115. case (PH_PULL |INDICATION):
  116. if (cs->tx_skb) {
  117. if (cs->debug & L1_DEB_WARN)
  118. debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
  119. skb_queue_tail(&cs->sq, skb);
  120. break;
  121. }
  122. if (cs->debug & DEB_DLOG_HEX)     LogFrame(cs, skb->data, skb->len);
  123. if (cs->debug & DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0);
  124. cs->tx_skb = skb;
  125. cs->tx_cnt = 0;
  126. #ifdef L2FRAME_DEBUG
  127. if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
  128. #endif
  129. dch_fill_fifo(cs);
  130. break;
  131.       
  132. case (PH_PULL | REQUEST):
  133. #ifdef L2FRAME_DEBUG
  134. if (cs->debug & L1_DEB_LAPD) debugl1(cs, "-> PH_REQUEST_PULL");
  135. #endif
  136. if (!cs->tx_skb) {
  137. clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
  138. st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
  139. } else
  140. set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
  141. break;
  142. case (HW_RESET | REQUEST):
  143. case (HW_ENABLE | REQUEST):
  144. ph_command(cs, IPACX_CMD_TIM);
  145. break;
  146. case (HW_INFO3 | REQUEST):
  147. ph_command(cs, IPACX_CMD_AR8);
  148. break;
  149. case (HW_TESTLOOP | REQUEST):
  150.       cs->writeisac(cs, IPACX_CDA_TSDP10, 0x80); // Timeslot 0 is B1
  151.       cs->writeisac(cs, IPACX_CDA_TSDP11, 0x81); // Timeslot 0 is B1
  152.       cda1_cr = cs->readisac(cs, IPACX_CDA1_CR);
  153.       cda2_cr = cs->readisac(cs, IPACX_CDA2_CR);
  154. if ((long)arg &1) { // loop B1
  155.         cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr |0x0a); 
  156.       }
  157.       else {  // B1 off
  158.         cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr &~0x0a); 
  159.       }
  160. if ((long)arg &2) { // loop B2
  161.         cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr |0x14); 
  162.       }
  163.       else {  // B2 off
  164.         cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr &~0x14); 
  165.       }
  166. break;
  167. case (HW_DEACTIVATE | RESPONSE):
  168. skb_queue_purge(&cs->rq);
  169. skb_queue_purge(&cs->sq);
  170. if (cs->tx_skb) {
  171. dev_kfree_skb_any(cs->tx_skb);
  172. cs->tx_skb = NULL;
  173. }
  174. if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
  175. del_timer(&cs->dbusytimer);
  176. break;
  177. default:
  178. if (cs->debug &L1_DEB_WARN) debugl1(cs, "dch_l2l1 unknown %04x", pr);
  179. break;
  180. }
  181. }
  182. //----------------------------------------------------------
  183. //----------------------------------------------------------
  184. static void
  185. dbusy_timer_handler(struct IsdnCardState *cs)
  186. {
  187. struct PStack *st;
  188. int rbchd, stard;
  189. if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
  190. rbchd = cs->readisac(cs, IPACX_RBCHD);
  191. stard = cs->readisac(cs, IPACX_STARD);
  192. if (cs->debug) 
  193.       debugl1(cs, "D-Channel Busy RBCHD %02x STARD %02x", rbchd, stard);
  194. if (!(stard &0x40)) { // D-Channel Busy
  195. set_bit(FLG_L1_DBUSY, &cs->HW_Flags);
  196.       for (st = cs->stlist; st; st = st->next) {
  197. st->l1.l1l2(st, PH_PAUSE | INDICATION, NULL); // flow control on
  198. }
  199. } else {
  200. // seems we lost an interrupt; reset transceiver */
  201. clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags);
  202. if (cs->tx_skb) {
  203. dev_kfree_skb_any(cs->tx_skb);
  204. cs->tx_cnt = 0;
  205. cs->tx_skb = NULL;
  206. } else {
  207. printk(KERN_WARNING "HiSax: ISAC D-Channel Busy no skbn");
  208. debugl1(cs, "D-Channel Busy no skb");
  209. }
  210. cs->writeisac(cs, IPACX_CMDRD, 0x01); // Tx reset, generates XPR
  211. }
  212. }
  213. }
  214. //----------------------------------------------------------
  215. // L1 state machine intermediate layer to isdnl1 module
  216. //----------------------------------------------------------
  217. static void
  218. ipacx_new_ph(struct IsdnCardState *cs)
  219. {
  220. switch (cs->dc.isac.ph_state) {
  221. case (IPACX_IND_RES):
  222. ph_command(cs, IPACX_CMD_DI);
  223. l1_msg(cs, HW_RESET | INDICATION, NULL);
  224. break;
  225.       
  226. case (IPACX_IND_DC):
  227. l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL);
  228. break;
  229.       
  230. case (IPACX_IND_DR):
  231. l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
  232. break;
  233.       
  234. case (IPACX_IND_PU):
  235. l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
  236. break;
  237. case (IPACX_IND_RSY):
  238. l1_msg(cs, HW_RSYNC | INDICATION, NULL);
  239. break;
  240. case (IPACX_IND_AR):
  241. l1_msg(cs, HW_INFO2 | INDICATION, NULL);
  242. break;
  243.       
  244. case (IPACX_IND_AI8):
  245. l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
  246. break;
  247.       
  248. case (IPACX_IND_AI10):
  249. l1_msg(cs, HW_INFO4_P10 | INDICATION, NULL);
  250. break;
  251.       
  252. default:
  253. break;
  254. }
  255. }
  256. //----------------------------------------------------------
  257. // bottom half handler for D channel
  258. //----------------------------------------------------------
  259. static void
  260. dch_bh(struct IsdnCardState *cs)
  261. {
  262. struct PStack *st;
  263. if (!cs) return;
  264.   
  265. if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
  266. if (cs->debug) debugl1(cs, "D-Channel Busy cleared");
  267. for (st = cs->stlist; st; st = st->next) {
  268. st->l1.l1l2(st, PH_PAUSE | CONFIRM, NULL);
  269. }
  270. }
  271.   
  272. if (test_and_clear_bit(D_RCVBUFREADY, &cs->event)) {
  273. DChannel_proc_rcv(cs);
  274.   }  
  275.   
  276. if (test_and_clear_bit(D_XMTBUFREADY, &cs->event)) {
  277. DChannel_proc_xmt(cs);
  278.   }  
  279.   
  280. if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
  281.     ipacx_new_ph(cs);
  282.   }  
  283. }
  284. //----------------------------------------------------------
  285. // proceed with bottom half handler dch_bh()
  286. //----------------------------------------------------------
  287. static void
  288. dch_sched_event(struct IsdnCardState *cs, int event)
  289. {
  290. set_bit(event, &cs->event);
  291. queue_task(&cs->tqueue, &tq_immediate);
  292. mark_bh(IMMEDIATE_BH);
  293. }
  294. //----------------------------------------------------------
  295. // Fill buffer from receive FIFO
  296. //----------------------------------------------------------
  297. static void 
  298. dch_empty_fifo(struct IsdnCardState *cs, int count)
  299. {
  300. long flags;
  301. u_char *ptr;
  302. if ((cs->debug &L1_DEB_ISAC) && !(cs->debug &L1_DEB_ISAC_FIFO))
  303. debugl1(cs, "dch_empty_fifo()");
  304.   // message too large, remove
  305. if ((cs->rcvidx + count) >= MAX_DFRAME_LEN_L1) {
  306. if (cs->debug &L1_DEB_WARN)
  307. debugl1(cs, "dch_empty_fifo() incoming message too large");
  308.   cs->writeisac(cs, IPACX_CMDRD, 0x80); // RMC
  309. cs->rcvidx = 0;
  310. return;
  311. }
  312.   
  313. ptr = cs->rcvbuf + cs->rcvidx;
  314. cs->rcvidx += count;
  315.   
  316. save_flags(flags);
  317. cli();
  318. cs->readisacfifo(cs, ptr, count);
  319. cs->writeisac(cs, IPACX_CMDRD, 0x80); // RMC
  320. restore_flags(flags);
  321.   
  322. if (cs->debug &L1_DEB_ISAC_FIFO) {
  323. char *t = cs->dlog;
  324. t += sprintf(t, "dch_empty_fifo() cnt %d", count);
  325. QuickHex(t, ptr, count);
  326. debugl1(cs, cs->dlog);
  327. }
  328. }
  329. //----------------------------------------------------------
  330. // Fill transmit FIFO
  331. //----------------------------------------------------------
  332. static void 
  333. dch_fill_fifo(struct IsdnCardState *cs)
  334. {
  335. long flags;
  336. int count;
  337. u_char cmd, *ptr;
  338. if ((cs->debug &L1_DEB_ISAC) && !(cs->debug &L1_DEB_ISAC_FIFO))
  339. debugl1(cs, "dch_fill_fifo()");
  340.     
  341. if (!cs->tx_skb) return;
  342. count = cs->tx_skb->len;
  343. if (count <= 0) return;
  344. if (count > D_FIFO_SIZE) {
  345. count = D_FIFO_SIZE;
  346. cmd   = 0x08; // XTF
  347. } else {
  348. cmd   = 0x0A; // XTF | XME
  349. }
  350.   
  351. save_flags(flags);
  352. cli();
  353. ptr = cs->tx_skb->data;
  354. skb_pull(cs->tx_skb, count);
  355. cs->tx_cnt += count;
  356. cs->writeisacfifo(cs, ptr, count);
  357. cs->writeisac(cs, IPACX_CMDRD, cmd);
  358.   
  359.   // set timeout for transmission contol
  360. if (test_and_set_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
  361. debugl1(cs, "dch_fill_fifo dbusytimer running");
  362. del_timer(&cs->dbusytimer);
  363. }
  364. init_timer(&cs->dbusytimer);
  365. cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
  366. add_timer(&cs->dbusytimer);
  367. restore_flags(flags);
  368.   
  369. if (cs->debug &L1_DEB_ISAC_FIFO) {
  370. char *t = cs->dlog;
  371. t += sprintf(t, "dch_fill_fifo() cnt %d", count);
  372. QuickHex(t, ptr, count);
  373. debugl1(cs, cs->dlog);
  374. }
  375. }
  376. //----------------------------------------------------------
  377. // D channel interrupt handler
  378. //----------------------------------------------------------
  379. static inline void 
  380. dch_int(struct IsdnCardState *cs)
  381. {
  382. struct sk_buff *skb;
  383. u_char istad, rstad;
  384. long flags;
  385. int count;
  386. istad = cs->readisac(cs, IPACX_ISTAD);
  387. //##############################################  
  388. // printk(KERN_WARNING "dch_int(istad=%02x)n", istad);
  389. //##############################################  
  390.   
  391. if (istad &0x80) {  // RME
  392.   rstad = cs->readisac(cs, IPACX_RSTAD);
  393. if ((rstad &0xf0) != 0xa0) { // !(VFR && !RDO && CRC && !RAB)
  394. if (!(rstad &0x80))
  395. if (cs->debug &L1_DEB_WARN) 
  396.           debugl1(cs, "dch_int(): invalid frame");
  397. if ((rstad &0x40))
  398. if (cs->debug &L1_DEB_WARN) 
  399.           debugl1(cs, "dch_int(): RDO");
  400. if (!(rstad &0x20))
  401. if (cs->debug &L1_DEB_WARN) 
  402.           debugl1(cs, "dch_int(): CRC error");
  403.     cs->writeisac(cs, IPACX_CMDRD, 0x80);  // RMC
  404. } else {  // received frame ok
  405. count = cs->readisac(cs, IPACX_RBCLD);
  406.       if (count) count--; // RSTAB is last byte
  407. count &= D_FIFO_SIZE-1;
  408. if (count == 0) count = D_FIFO_SIZE;
  409. dch_empty_fifo(cs, count);
  410. save_flags(flags);
  411. cli();
  412. if ((count = cs->rcvidx) > 0) {
  413.       cs->rcvidx = 0;
  414. if (!(skb = dev_alloc_skb(count)))
  415. printk(KERN_WARNING "HiSax dch_int(): receive out of memoryn");
  416. else {
  417. memcpy(skb_put(skb, count), cs->rcvbuf, count);
  418. skb_queue_tail(&cs->rq, skb);
  419. }
  420. }
  421. restore_flags(flags);
  422.     }
  423.   cs->rcvidx = 0;
  424. dch_sched_event(cs, D_RCVBUFREADY);
  425. }
  426. if (istad &0x40) {  // RPF
  427. dch_empty_fifo(cs, D_FIFO_SIZE);
  428. }
  429. if (istad &0x20) {  // RFO
  430. if (cs->debug &L1_DEB_WARN) debugl1(cs, "dch_int(): RFO");
  431.   cs->writeisac(cs, IPACX_CMDRD, 0x40); //RRES
  432. }
  433.   
  434.   if (istad &0x10) {  // XPR
  435. if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
  436. del_timer(&cs->dbusytimer);
  437. if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
  438. dch_sched_event(cs, D_CLEARBUSY);
  439.     if (cs->tx_skb) {
  440.       if (cs->tx_skb->len) {
  441.         dch_fill_fifo(cs);
  442.         goto afterXPR;
  443.       }
  444.       else {
  445.         dev_kfree_skb_irq(cs->tx_skb);
  446.         cs->tx_skb = NULL;
  447.         cs->tx_cnt = 0;
  448.       }
  449.     }
  450.     if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
  451.       cs->tx_cnt = 0;
  452.       dch_fill_fifo(cs);
  453.     } 
  454.     else {
  455.       dch_sched_event(cs, D_XMTBUFREADY);
  456.     }  
  457.   }  
  458.   afterXPR:
  459. if (istad &0x0C) {  // XDU or XMR
  460. if (cs->debug &L1_DEB_WARN) debugl1(cs, "dch_int(): XDU");
  461.   if (cs->tx_skb) {
  462.     skb_push(cs->tx_skb, cs->tx_cnt); // retransmit
  463.     cs->tx_cnt = 0;
  464. dch_fill_fifo(cs);
  465. } else {
  466. printk(KERN_WARNING "HiSax: ISAC XDU no skbn");
  467. debugl1(cs, "ISAC XDU no skb");
  468. }
  469.   }
  470. }
  471. //----------------------------------------------------------
  472. //----------------------------------------------------------
  473. static void __devinit
  474. dch_setstack(struct PStack *st, struct IsdnCardState *cs)
  475. {
  476. st->l1.l1hw = dch_l2l1;
  477. }
  478. //----------------------------------------------------------
  479. //----------------------------------------------------------
  480. static void __devinit
  481. dch_init(struct IsdnCardState *cs)
  482. {
  483. printk(KERN_INFO "HiSax: IPACX ISDN driver v0.1.0n");
  484. cs->tqueue.routine  = (void *)(void *) dch_bh;
  485. cs->setstack_d      = dch_setstack;
  486.   
  487. cs->dbusytimer.function = (void *) dbusy_timer_handler;
  488. cs->dbusytimer.data = (long) cs;
  489. init_timer(&cs->dbusytimer);
  490.   cs->writeisac(cs, IPACX_TR_CONF0, 0x00);  // clear LDD
  491.   cs->writeisac(cs, IPACX_TR_CONF2, 0x00);  // enable transmitter
  492.   cs->writeisac(cs, IPACX_MODED,    0xC9);  // transparent mode 0, RAC, stop/go
  493.   cs->writeisac(cs, IPACX_MON_CR,   0x00);  // disable monitor channel
  494. }
  495. //==========================================================
  496. // B channel functions
  497. //==========================================================
  498. //----------------------------------------------------------
  499. // Entry point for commands
  500. //----------------------------------------------------------
  501. static void
  502. bch_l2l1(struct PStack *st, int pr, void *arg)
  503. {
  504. struct sk_buff *skb = arg;
  505. long flags;
  506. switch (pr) {
  507. case (PH_DATA | REQUEST):
  508. save_flags(flags);
  509. cli();
  510. if (st->l1.bcs->tx_skb) {
  511. skb_queue_tail(&st->l1.bcs->squeue, skb);
  512. restore_flags(flags);
  513. } else {
  514. st->l1.bcs->tx_skb = skb;
  515. set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
  516. st->l1.bcs->hw.hscx.count = 0;
  517. restore_flags(flags);
  518.         bch_fill_fifo(st->l1.bcs);
  519. }
  520. break;
  521. case (PH_PULL | INDICATION):
  522. if (st->l1.bcs->tx_skb) {
  523. printk(KERN_WARNING "HiSax bch_l2l1(): this shouldn't happenn");
  524. break;
  525. }
  526. set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
  527. st->l1.bcs->tx_skb = skb;
  528. st->l1.bcs->hw.hscx.count = 0;
  529.       bch_fill_fifo(st->l1.bcs);
  530. break;
  531. case (PH_PULL | REQUEST):
  532. if (!st->l1.bcs->tx_skb) {
  533. clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
  534. st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
  535. } else
  536. set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
  537. break;
  538. case (PH_ACTIVATE | REQUEST):
  539. set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
  540. bch_mode(st->l1.bcs, st->l1.mode, st->l1.bc);
  541. l1_msg_b(st, pr, arg);
  542. break;
  543. case (PH_DEACTIVATE | REQUEST):
  544. l1_msg_b(st, pr, arg);
  545. break;
  546. case (PH_DEACTIVATE | CONFIRM):
  547. clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
  548. clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
  549. bch_mode(st->l1.bcs, 0, st->l1.bc);
  550. st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
  551. break;
  552. }
  553. }
  554. //----------------------------------------------------------
  555. // proceed with bottom half handler BChannel_bh()
  556. //----------------------------------------------------------
  557. static void
  558. bch_sched_event(struct BCState *bcs, int event)
  559. {
  560. bcs->event |= 1 << event;
  561. queue_task(&bcs->tqueue, &tq_immediate);
  562. mark_bh(IMMEDIATE_BH);
  563. }
  564. //----------------------------------------------------------
  565. // Read B channel fifo to receive buffer
  566. //----------------------------------------------------------
  567. static void
  568. bch_empty_fifo(struct BCState *bcs, int count)
  569. {
  570. u_char *ptr, hscx;
  571. struct IsdnCardState *cs;
  572. long flags;
  573. int cnt;
  574. cs = bcs->cs;
  575.   hscx = bcs->hw.hscx.hscx;
  576. if ((cs->debug &L1_DEB_HSCX) && !(cs->debug &L1_DEB_HSCX_FIFO))
  577. debugl1(cs, "bch_empty_fifo()");
  578.   // message too large, remove
  579. if (bcs->hw.hscx.rcvidx + count > HSCX_BUFMAX) {
  580. if (cs->debug &L1_DEB_WARN)
  581. debugl1(cs, "bch_empty_fifo() incoming packet too large");
  582.   cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x80);  // RMC
  583. bcs->hw.hscx.rcvidx = 0;
  584. return;
  585. }
  586.   
  587.   // Read data uninterruptible
  588. save_flags(flags);
  589. cli();
  590. ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx;
  591. cnt = count;
  592. while (cnt--) *ptr++ = cs->BC_Read_Reg(cs, hscx, IPACX_RFIFOB); 
  593. cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x80);  // RMC
  594.   
  595. ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx;
  596. bcs->hw.hscx.rcvidx += count;
  597. restore_flags(flags);
  598.   
  599. if (cs->debug &L1_DEB_HSCX_FIFO) {
  600. char *t = bcs->blog;
  601. t += sprintf(t, "bch_empty_fifo() B-%d cnt %d", hscx, count);
  602. QuickHex(t, ptr, count);
  603. debugl1(cs, bcs->blog);
  604. }
  605. }
  606. //----------------------------------------------------------
  607. // Fill buffer to transmit FIFO
  608. //----------------------------------------------------------
  609. static void
  610. bch_fill_fifo(struct BCState *bcs)
  611. {
  612. struct IsdnCardState *cs;
  613. int more, count, cnt;
  614. u_char *ptr, *p, hscx;
  615. long flags;
  616. cs = bcs->cs;
  617. if ((cs->debug &L1_DEB_HSCX) && !(cs->debug &L1_DEB_HSCX_FIFO))
  618. debugl1(cs, "bch_fill_fifo()");
  619. if (!bcs->tx_skb)           return;
  620. if (bcs->tx_skb->len <= 0)  return;
  621. hscx = bcs->hw.hscx.hscx;
  622. more = (bcs->mode == L1_MODE_TRANS) ? 1 : 0;
  623. if (bcs->tx_skb->len > B_FIFO_SIZE) {
  624. more  = 1;
  625. count = B_FIFO_SIZE;
  626. } else {
  627. count = bcs->tx_skb->len;
  628. }  
  629. cnt = count;
  630.     
  631. save_flags(flags);
  632. cli();
  633. p = ptr = bcs->tx_skb->data;
  634. skb_pull(bcs->tx_skb, count);
  635. bcs->tx_cnt -= count;
  636. bcs->hw.hscx.count += count;
  637. while (cnt--) cs->BC_Write_Reg(cs, hscx, IPACX_XFIFOB, *p++); 
  638. cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, (more ? 0x08 : 0x0a));
  639. restore_flags(flags);
  640.   
  641. if (cs->debug &L1_DEB_HSCX_FIFO) {
  642. char *t = bcs->blog;
  643. t += sprintf(t, "chb_fill_fifo() B-%d cnt %d", hscx, count);
  644. QuickHex(t, ptr, count);
  645. debugl1(cs, bcs->blog);
  646. }
  647. }
  648. //----------------------------------------------------------
  649. // B channel interrupt handler
  650. //----------------------------------------------------------
  651. static void
  652. bch_int(struct IsdnCardState *cs, u_char hscx)
  653. {
  654. u_char istab;
  655. struct BCState *bcs;
  656. struct sk_buff *skb;
  657. int count;
  658. u_char rstab;
  659. bcs = cs->bcs + hscx;
  660. istab = cs->BC_Read_Reg(cs, hscx, IPACX_ISTAB);
  661. //##############################################  
  662. // printk(KERN_WARNING "bch_int(istab=%02x)n", istab);
  663. //##############################################  
  664. if (!test_bit(BC_FLG_INIT, &bcs->Flag)) return;
  665. if (istab &0x80) { // RME
  666. rstab = cs->BC_Read_Reg(cs, hscx, IPACX_RSTAB);
  667. if ((rstab &0xf0) != 0xa0) { // !(VFR && !RDO && CRC && !RAB)
  668. if (!(rstab &0x80))
  669. if (cs->debug &L1_DEB_WARN) 
  670.           debugl1(cs, "bch_int() B-%d: invalid frame", hscx);
  671. if ((rstab &0x40) && (bcs->mode != L1_MODE_NULL))
  672. if (cs->debug &L1_DEB_WARN) 
  673.           debugl1(cs, "bch_int() B-%d: RDO mode=%d", hscx, bcs->mode);
  674. if (!(rstab &0x20))
  675. if (cs->debug &L1_DEB_WARN) 
  676.           debugl1(cs, "bch_int() B-%d: CRC error", hscx);
  677.     cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x80);  // RMC
  678.     else {  // received frame ok
  679. count = cs->BC_Read_Reg(cs, hscx, IPACX_RBCLB) &(B_FIFO_SIZE-1);
  680. if (count == 0) count = B_FIFO_SIZE;
  681. bch_empty_fifo(bcs, count);
  682. if ((count = bcs->hw.hscx.rcvidx - 1) > 0) {
  683. if (cs->debug &L1_DEB_HSCX_FIFO)
  684. debugl1(cs, "bch_int Frame %d", count);
  685. if (!(skb = dev_alloc_skb(count)))
  686. printk(KERN_WARNING "HiSax bch_int(): receive frame out of memoryn");
  687. else {
  688. memcpy(skb_put(skb, count), bcs->hw.hscx.rcvbuf, count);
  689. skb_queue_tail(&bcs->rqueue, skb);
  690. }
  691. }
  692. }
  693. bcs->hw.hscx.rcvidx = 0;
  694. bch_sched_event(bcs, B_RCVBUFREADY);
  695. }
  696.   
  697. if (istab &0x40) { // RPF
  698. bch_empty_fifo(bcs, B_FIFO_SIZE);
  699. if (bcs->mode == L1_MODE_TRANS) { // queue every chunk
  700. // receive transparent audio data
  701. if (!(skb = dev_alloc_skb(B_FIFO_SIZE)))
  702. printk(KERN_WARNING "HiSax bch_int(): receive transparent out of memoryn");
  703. else {
  704. memcpy(skb_put(skb, B_FIFO_SIZE), bcs->hw.hscx.rcvbuf, B_FIFO_SIZE);
  705. skb_queue_tail(&bcs->rqueue, skb);
  706. }
  707. bcs->hw.hscx.rcvidx = 0;
  708. bch_sched_event(bcs, B_RCVBUFREADY);
  709. }
  710. }
  711.   
  712. if (istab &0x20) { // RFO
  713. if (cs->debug &L1_DEB_WARN) 
  714.       debugl1(cs, "bch_int() B-%d: RFO error", hscx);
  715.   cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x40);  // RRES
  716. }
  717. if (istab &0x10) { // XPR
  718. if (bcs->tx_skb) {
  719. if (bcs->tx_skb->len) {
  720.     bch_fill_fifo(bcs);
  721.         goto afterXPR;
  722.       }
  723.       else {
  724. if (bcs->st->lli.l1writewakeup &&
  725.   (PACKET_NOACK != bcs->tx_skb->pkt_type)) {    
  726. bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hscx.count);
  727.         }  
  728.   dev_kfree_skb_irq(bcs->tx_skb);
  729.   bcs->hw.hscx.count = 0; 
  730.   bcs->tx_skb = NULL;
  731.       }
  732.     }    
  733.     if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
  734.       bcs->hw.hscx.count = 0;
  735.       set_bit(BC_FLG_BUSY, &bcs->Flag);
  736.       bch_fill_fifo(bcs);
  737.     } else {
  738.       clear_bit(BC_FLG_BUSY, &bcs->Flag);
  739.       bch_sched_event(bcs, B_XMTBUFREADY);
  740.     }
  741.   }
  742.   afterXPR:
  743. if (istab &0x04) { // XDU
  744.     if (bcs->mode == L1_MODE_TRANS) {
  745. bch_fill_fifo(bcs);
  746.     }  
  747.     else {
  748.       if (bcs->tx_skb) {  // restart transmitting the whole frame
  749.         skb_push(bcs->tx_skb, bcs->hw.hscx.count);
  750.         bcs->tx_cnt += bcs->hw.hscx.count;
  751.         bcs->hw.hscx.count = 0;
  752.       }
  753.     cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x01);  // XRES
  754.       if (cs->debug &L1_DEB_WARN)
  755.         debugl1(cs, "bch_int() B-%d XDU error", hscx);
  756.     }
  757. }
  758. }
  759. //----------------------------------------------------------
  760. //----------------------------------------------------------
  761. static void
  762. bch_mode(struct BCState *bcs, int mode, int bc)
  763. {
  764. struct IsdnCardState *cs = bcs->cs;
  765. int hscx = bcs->hw.hscx.hscx;
  766.         bc = bc ? 1 : 0;  // in case bc is greater than 1
  767. if (cs->debug & L1_DEB_HSCX)
  768. debugl1(cs, "mode_bch() switch B-% mode %d chan %d", hscx, mode, bc);
  769. bcs->mode = mode;
  770. bcs->channel = bc;
  771.   
  772.   // map controller to according timeslot
  773.   if (!hscx)
  774.   {
  775.     cs->writeisac(cs, IPACX_BCHA_TSDP_BC1, 0x80 | bc);
  776.     cs->writeisac(cs, IPACX_BCHA_CR,       0x88); 
  777.   }
  778.   else
  779.   {
  780.     cs->writeisac(cs, IPACX_BCHB_TSDP_BC1, 0x80 | bc);
  781.     cs->writeisac(cs, IPACX_BCHB_CR,       0x88); 
  782.   }
  783. switch (mode) {
  784. case (L1_MODE_NULL):
  785.     cs->BC_Write_Reg(cs, hscx, IPACX_MODEB, 0xC0);  // rec off
  786.     cs->BC_Write_Reg(cs, hscx, IPACX_EXMB,  0x30);  // std adj.
  787.     cs->BC_Write_Reg(cs, hscx, IPACX_MASKB, 0xFF);  // ints off
  788.     cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x41);  // validate adjustments
  789.     break;
  790. case (L1_MODE_TRANS):
  791.     cs->BC_Write_Reg(cs, hscx, IPACX_MODEB, 0x88);  // ext transp mode
  792.     cs->BC_Write_Reg(cs, hscx, IPACX_EXMB,  0x00);  // xxx00000
  793.     cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x41);  // validate adjustments
  794.     cs->BC_Write_Reg(cs, hscx, IPACX_MASKB, _MASKB_IMASK);
  795.     break;
  796. case (L1_MODE_HDLC):
  797.     cs->BC_Write_Reg(cs, hscx, IPACX_MODEB, 0xC8);  // transp mode 0
  798.     cs->BC_Write_Reg(cs, hscx, IPACX_EXMB,  0x01);  // idle=hdlc flags crc enabled
  799.     cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x41);  // validate adjustments
  800.     cs->BC_Write_Reg(cs, hscx, IPACX_MASKB, _MASKB_IMASK);
  801.     break;
  802. }
  803. }
  804. //----------------------------------------------------------
  805. //----------------------------------------------------------
  806. static void
  807. bch_close_state(struct BCState *bcs)
  808. {
  809. bch_mode(bcs, 0, bcs->channel);
  810. if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
  811. if (bcs->hw.hscx.rcvbuf) {
  812. kfree(bcs->hw.hscx.rcvbuf);
  813. bcs->hw.hscx.rcvbuf = NULL;
  814. }
  815. if (bcs->blog) {
  816. kfree(bcs->blog);
  817. bcs->blog = NULL;
  818. }
  819. skb_queue_purge(&bcs->rqueue);
  820. skb_queue_purge(&bcs->squeue);
  821. if (bcs->tx_skb) {
  822. dev_kfree_skb_any(bcs->tx_skb);
  823. bcs->tx_skb = NULL;
  824. clear_bit(BC_FLG_BUSY, &bcs->Flag);
  825. }
  826. }
  827. }
  828. //----------------------------------------------------------
  829. //----------------------------------------------------------
  830. static int
  831. bch_open_state(struct IsdnCardState *cs, struct BCState *bcs)
  832. {
  833. if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
  834. if (!(bcs->hw.hscx.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
  835. printk(KERN_WARNING
  836. "HiSax open_bchstate(): No memory for hscx.rcvbufn");
  837. clear_bit(BC_FLG_INIT, &bcs->Flag);
  838. return (1);
  839. }
  840. if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
  841. printk(KERN_WARNING
  842. "HiSax open_bchstate: No memory for bcs->blogn");
  843. clear_bit(BC_FLG_INIT, &bcs->Flag);
  844. kfree(bcs->hw.hscx.rcvbuf);
  845. bcs->hw.hscx.rcvbuf = NULL;
  846. return (2);
  847. }
  848. skb_queue_head_init(&bcs->rqueue);
  849. skb_queue_head_init(&bcs->squeue);
  850. }
  851. bcs->tx_skb = NULL;
  852. clear_bit(BC_FLG_BUSY, &bcs->Flag);
  853. bcs->event = 0;
  854. bcs->hw.hscx.rcvidx = 0;
  855. bcs->tx_cnt = 0;
  856. return (0);
  857. }
  858. //----------------------------------------------------------
  859. //----------------------------------------------------------
  860. static int
  861. bch_setstack(struct PStack *st, struct BCState *bcs)
  862. {
  863. bcs->channel = st->l1.bc;
  864. if (bch_open_state(st->l1.hardware, bcs)) return (-1);
  865. st->l1.bcs = bcs;
  866. st->l2.l2l1 = bch_l2l1;
  867. setstack_manager(st);
  868. bcs->st = st;
  869. setstack_l1_B(st);
  870. return (0);
  871. }
  872. //----------------------------------------------------------
  873. //----------------------------------------------------------
  874. static void __devinit
  875. bch_init(struct IsdnCardState *cs, int hscx)
  876. {
  877. cs->bcs[hscx].BC_SetStack   = bch_setstack;
  878. cs->bcs[hscx].BC_Close      = bch_close_state;
  879. cs->bcs[hscx].hw.hscx.hscx  = hscx;
  880. cs->bcs[hscx].cs            = cs;
  881. bch_mode(cs->bcs + hscx, 0, hscx);
  882. }
  883. //==========================================================
  884. // Shared functions
  885. //==========================================================
  886. //----------------------------------------------------------
  887. // Main interrupt handler
  888. //----------------------------------------------------------
  889. void 
  890. interrupt_ipacx(struct IsdnCardState *cs)
  891. {
  892. u_char ista;
  893.   
  894. while ((ista = cs->readisac(cs, IPACX_ISTA))) {
  895. //#################################################  
  896. // printk(KERN_WARNING "interrupt_ipacx(ista=%02x)n", ista);
  897. //#################################################  
  898.     if (ista &0x80) bch_int(cs, 0); // B channel interrupts
  899.     if (ista &0x40) bch_int(cs, 1);
  900.     
  901.     if (ista &0x01) dch_int(cs);    // D channel
  902.     if (ista &0x10) cic_int(cs);    // Layer 1 state
  903.   }  
  904. }
  905. //----------------------------------------------------------
  906. // Clears chip interrupt status
  907. //----------------------------------------------------------
  908. static void __init
  909. clear_pending_ints(struct IsdnCardState *cs)
  910. {
  911. int ista;
  912.   // all interrupts off
  913.   cs->writeisac(cs, IPACX_MASK, 0xff);
  914. cs->writeisac(cs, IPACX_MASKD, 0xff);
  915. cs->BC_Write_Reg(cs, 0, IPACX_MASKB, 0xff);
  916. cs->BC_Write_Reg(cs, 1, IPACX_MASKB, 0xff);
  917.   
  918.   ista = cs->readisac(cs, IPACX_ISTA); 
  919.   if (ista &0x80) cs->BC_Read_Reg(cs, 0, IPACX_ISTAB);
  920.   if (ista &0x40) cs->BC_Read_Reg(cs, 1, IPACX_ISTAB);
  921.   if (ista &0x10) cs->readisac(cs, IPACX_CIR0);
  922.   if (ista &0x01) cs->readisac(cs, IPACX_ISTAD); 
  923. }
  924. //----------------------------------------------------------
  925. // Does chip configuration work
  926. // Work to do depends on bit mask in part
  927. //----------------------------------------------------------
  928. void __init
  929. init_ipacx(struct IsdnCardState *cs, int part)
  930. {
  931. if (part &1) {  // initialise chip
  932. //##################################################  
  933. // printk(KERN_INFO "init_ipacx(%x)n", part);
  934. //##################################################  
  935. clear_pending_ints(cs);
  936. bch_init(cs, 0);
  937. bch_init(cs, 1);
  938. dch_init(cs);
  939. }
  940. if (part &2) {  // reenable all interrupts and start chip
  941. cs->BC_Write_Reg(cs, 0, IPACX_MASKB, _MASKB_IMASK);
  942. cs->BC_Write_Reg(cs, 1, IPACX_MASKB, _MASKB_IMASK);
  943. cs->writeisac(cs, IPACX_MASKD, _MASKD_IMASK);
  944. cs->writeisac(cs, IPACX_MASK, _MASK_IMASK); // global mask register
  945.     // reset HDLC Transmitters/receivers
  946. cs->writeisac(cs, IPACX_CMDRD, 0x41); 
  947.     cs->BC_Write_Reg(cs, 0, IPACX_CMDRB, 0x41);
  948.     cs->BC_Write_Reg(cs, 1, IPACX_CMDRB, 0x41);
  949.    ph_command(cs, IPACX_CMD_RES);
  950. }
  951. }
  952. //----------------- end of file -----------------------