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

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: hfc_2bs0.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  2.  *
  3.  * specific routines for CCD's HFC 2BS0
  4.  *
  5.  * Author       Karsten Keil
  6.  * Copyright    by Karsten Keil      <keil@isdn4linux.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. #define __NO_VERSION__
  13. #include <linux/init.h>
  14. #include "hisax.h"
  15. #include "hfc_2bs0.h"
  16. #include "isac.h"
  17. #include "isdnl1.h"
  18. #include <linux/interrupt.h>
  19. static inline int
  20. WaitForBusy(struct IsdnCardState *cs)
  21. {
  22. int to = 130;
  23. long flags;
  24. u_char val;
  25. save_flags(flags);
  26. cli();
  27. while (!(cs->BC_Read_Reg(cs, HFC_STATUS, 0) & HFC_BUSY) && to) {
  28. val = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2 |
  29.       (cs->hw.hfc.cip & 3));
  30. udelay(1);
  31. to--;
  32. }
  33. restore_flags(flags);
  34. if (!to) {
  35. printk(KERN_WARNING "HiSax: waitforBusy timeoutn");
  36. return (0);
  37. } else
  38. return (to);
  39. }
  40. static inline int
  41. WaitNoBusy(struct IsdnCardState *cs)
  42. {
  43. int to = 125;
  44. while ((cs->BC_Read_Reg(cs, HFC_STATUS, 0) & HFC_BUSY) && to) {
  45. udelay(1);
  46. to--;
  47. }
  48. if (!to) {
  49. printk(KERN_WARNING "HiSax: waitforBusy timeoutn");
  50. return (0);
  51. } else
  52. return (to);
  53. }
  54. int
  55. GetFreeFifoBytes(struct BCState *bcs)
  56. {
  57. int s;
  58. if (bcs->hw.hfc.f1 == bcs->hw.hfc.f2)
  59. return (bcs->cs->hw.hfc.fifosize);
  60. s = bcs->hw.hfc.send[bcs->hw.hfc.f1] - bcs->hw.hfc.send[bcs->hw.hfc.f2];
  61. if (s <= 0)
  62. s += bcs->cs->hw.hfc.fifosize;
  63. s = bcs->cs->hw.hfc.fifosize - s;
  64. return (s);
  65. }
  66. int
  67. ReadZReg(struct BCState *bcs, u_char reg)
  68. {
  69. int val;
  70. WaitNoBusy(bcs->cs);
  71. val = 256 * bcs->cs->BC_Read_Reg(bcs->cs, HFC_DATA, reg | HFC_CIP | HFC_Z_HIGH);
  72. WaitNoBusy(bcs->cs);
  73. val += bcs->cs->BC_Read_Reg(bcs->cs, HFC_DATA, reg | HFC_CIP | HFC_Z_LOW);
  74. return (val);
  75. }
  76. void
  77. hfc_sched_event(struct BCState *bcs, int event)
  78. {
  79. bcs->event |= 1 << event;
  80. queue_task(&bcs->tqueue, &tq_immediate);
  81. mark_bh(IMMEDIATE_BH);
  82. }
  83. static void
  84. hfc_clear_fifo(struct BCState *bcs)
  85. {
  86. struct IsdnCardState *cs = bcs->cs;
  87. long flags;
  88. int idx, cnt;
  89. int rcnt, z1, z2;
  90. u_char cip, f1, f2;
  91. if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
  92. debugl1(cs, "hfc_clear_fifo");
  93. save_flags(flags);
  94. cli();
  95. cip = HFC_CIP | HFC_F1 | HFC_REC | HFC_CHANNEL(bcs->channel);
  96. if ((cip & 0xc3) != (cs->hw.hfc.cip & 0xc3)) {
  97. cs->BC_Write_Reg(cs, HFC_STATUS, cip, cip);
  98. WaitForBusy(cs);
  99. }
  100. WaitNoBusy(cs);
  101. f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
  102. cip = HFC_CIP | HFC_F2 | HFC_REC | HFC_CHANNEL(bcs->channel);
  103. WaitNoBusy(cs);
  104. f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
  105. z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel));
  106. z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel));
  107. cnt = 32;
  108. while (((f1 != f2) || (z1 != z2)) && cnt--) {
  109. if (cs->debug & L1_DEB_HSCX)
  110. debugl1(cs, "hfc clear %d f1(%d) f2(%d)",
  111. bcs->channel, f1, f2);
  112. rcnt = z1 - z2;
  113. if (rcnt < 0)
  114. rcnt += cs->hw.hfc.fifosize;
  115. if (rcnt)
  116. rcnt++;
  117. if (cs->debug & L1_DEB_HSCX)
  118. debugl1(cs, "hfc clear %d z1(%x) z2(%x) cnt(%d)",
  119. bcs->channel, z1, z2, rcnt);
  120. cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel);
  121. idx = 0;
  122. while ((idx < rcnt) && WaitNoBusy(cs)) {
  123. cs->BC_Read_Reg(cs, HFC_DATA_NODEB, cip);
  124. idx++;
  125. }
  126. if (f1 != f2) {
  127. WaitNoBusy(cs);
  128. cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
  129. HFC_CHANNEL(bcs->channel));
  130. WaitForBusy(cs);
  131. }
  132. cip = HFC_CIP | HFC_F1 | HFC_REC | HFC_CHANNEL(bcs->channel);
  133. WaitNoBusy(cs);
  134. f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
  135. cip = HFC_CIP | HFC_F2 | HFC_REC | HFC_CHANNEL(bcs->channel);
  136. WaitNoBusy(cs);
  137. f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
  138. z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel));
  139. z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel));
  140. }
  141. restore_flags(flags);
  142. return;
  143. }
  144. static struct sk_buff
  145. *
  146. hfc_empty_fifo(struct BCState *bcs, int count)
  147. {
  148. u_char *ptr;
  149. struct sk_buff *skb;
  150. struct IsdnCardState *cs = bcs->cs;
  151. int idx;
  152. int chksum;
  153. u_char stat, cip;
  154. if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
  155. debugl1(cs, "hfc_empty_fifo");
  156. idx = 0;
  157. if (count > HSCX_BUFMAX + 3) {
  158. if (cs->debug & L1_DEB_WARN)
  159. debugl1(cs, "hfc_empty_fifo: incoming packet too large");
  160. cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel);
  161. while ((idx++ < count) && WaitNoBusy(cs))
  162. cs->BC_Read_Reg(cs, HFC_DATA_NODEB, cip);
  163. WaitNoBusy(cs);
  164. stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
  165.        HFC_CHANNEL(bcs->channel));
  166. WaitForBusy(cs);
  167. return (NULL);
  168. }
  169. if ((count < 4) && (bcs->mode != L1_MODE_TRANS)) {
  170. if (cs->debug & L1_DEB_WARN)
  171. debugl1(cs, "hfc_empty_fifo: incoming packet too small");
  172. cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel);
  173. while ((idx++ < count) && WaitNoBusy(cs))
  174. cs->BC_Read_Reg(cs, HFC_DATA_NODEB, cip);
  175. WaitNoBusy(cs);
  176. stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
  177.        HFC_CHANNEL(bcs->channel));
  178. WaitForBusy(cs);
  179. #ifdef ERROR_STATISTIC
  180. bcs->err_inv++;
  181. #endif
  182. return (NULL);
  183. }
  184. if (bcs->mode == L1_MODE_TRANS)
  185.   count -= 1;
  186. else
  187.   count -= 3;
  188. if (!(skb = dev_alloc_skb(count)))
  189. printk(KERN_WARNING "HFC: receive out of memoryn");
  190. else {
  191. ptr = skb_put(skb, count);
  192. idx = 0;
  193. cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel);
  194. while ((idx < count) && WaitNoBusy(cs)) {
  195. *ptr++ = cs->BC_Read_Reg(cs, HFC_DATA_NODEB, cip);
  196. idx++;
  197. }
  198. if (idx != count) {
  199. debugl1(cs, "RFIFO BUSY error");
  200. printk(KERN_WARNING "HFC FIFO channel %d BUSY Errorn", bcs->channel);
  201. dev_kfree_skb_any(skb);
  202. if (bcs->mode != L1_MODE_TRANS) {
  203.   WaitNoBusy(cs);
  204.   stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
  205.  HFC_CHANNEL(bcs->channel));
  206.   WaitForBusy(cs);
  207. }
  208. return (NULL);
  209. }
  210. if (bcs->mode != L1_MODE_TRANS) {
  211.   WaitNoBusy(cs);
  212.   chksum = (cs->BC_Read_Reg(cs, HFC_DATA, cip) << 8);
  213.   WaitNoBusy(cs);
  214.   chksum += cs->BC_Read_Reg(cs, HFC_DATA, cip);
  215.   WaitNoBusy(cs);
  216.   stat = cs->BC_Read_Reg(cs, HFC_DATA, cip);
  217.   if (cs->debug & L1_DEB_HSCX)
  218.     debugl1(cs, "hfc_empty_fifo %d chksum %x stat %x",
  219.     bcs->channel, chksum, stat);
  220.   if (stat) {
  221.     debugl1(cs, "FIFO CRC error");
  222.     dev_kfree_skb_any(skb);
  223.     skb = NULL;
  224. #ifdef ERROR_STATISTIC
  225.     bcs->err_crc++;
  226. #endif
  227.   }
  228.   WaitNoBusy(cs);
  229.   stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
  230.  HFC_CHANNEL(bcs->channel));
  231.   WaitForBusy(cs);
  232. }
  233. }
  234. return (skb);
  235. }
  236. static void
  237. hfc_fill_fifo(struct BCState *bcs)
  238. {
  239. struct IsdnCardState *cs = bcs->cs;
  240. long flags;
  241. int idx, fcnt;
  242. int count;
  243. int z1, z2;
  244. u_char cip;
  245. if (!bcs->tx_skb)
  246. return;
  247. if (bcs->tx_skb->len <= 0)
  248. return;
  249. save_flags(flags);
  250. cli();
  251. cip = HFC_CIP | HFC_F1 | HFC_SEND | HFC_CHANNEL(bcs->channel);
  252. if ((cip & 0xc3) != (cs->hw.hfc.cip & 0xc3)) {
  253.   cs->BC_Write_Reg(cs, HFC_STATUS, cip, cip);
  254.   WaitForBusy(cs);
  255. }
  256. WaitNoBusy(cs);
  257. if (bcs->mode != L1_MODE_TRANS) {
  258.   bcs->hw.hfc.f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
  259.   cip = HFC_CIP | HFC_F2 | HFC_SEND | HFC_CHANNEL(bcs->channel);
  260.   WaitNoBusy(cs);
  261.   bcs->hw.hfc.f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
  262.   bcs->hw.hfc.send[bcs->hw.hfc.f1] = ReadZReg(bcs, HFC_Z1 | HFC_SEND | HFC_CHANNEL(bcs->channel));
  263.   if (cs->debug & L1_DEB_HSCX)
  264.     debugl1(cs, "hfc_fill_fifo %d f1(%d) f2(%d) z1(%x)",
  265.     bcs->channel, bcs->hw.hfc.f1, bcs->hw.hfc.f2,
  266.     bcs->hw.hfc.send[bcs->hw.hfc.f1]);
  267.   fcnt = bcs->hw.hfc.f1 - bcs->hw.hfc.f2;
  268.   if (fcnt < 0)
  269.     fcnt += 32;
  270.   if (fcnt > 30) {
  271.     if (cs->debug & L1_DEB_HSCX)
  272.       debugl1(cs, "hfc_fill_fifo more as 30 frames");
  273.     restore_flags(flags);
  274.     return;
  275.   }
  276.   count = GetFreeFifoBytes(bcs);
  277. else {
  278.   WaitForBusy(cs);
  279.   z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel));
  280.   z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel));
  281.   count = z1 - z2;
  282.   if (count < 0)
  283.     count += cs->hw.hfc.fifosize; 
  284. } /* L1_MODE_TRANS */
  285. if (cs->debug & L1_DEB_HSCX)
  286. debugl1(cs, "hfc_fill_fifo %d count(%ld/%d)",
  287. bcs->channel, bcs->tx_skb->len,
  288. count);
  289. if (count < bcs->tx_skb->len) {
  290. if (cs->debug & L1_DEB_HSCX)
  291. debugl1(cs, "hfc_fill_fifo no fifo mem");
  292. restore_flags(flags);
  293. return;
  294. }
  295. cip = HFC_CIP | HFC_FIFO_IN | HFC_SEND | HFC_CHANNEL(bcs->channel);
  296. idx = 0;
  297. while ((idx < bcs->tx_skb->len) && WaitNoBusy(cs))
  298. cs->BC_Write_Reg(cs, HFC_DATA_NODEB, cip, bcs->tx_skb->data[idx++]);
  299. if (idx != bcs->tx_skb->len) {
  300. debugl1(cs, "FIFO Send BUSY error");
  301. printk(KERN_WARNING "HFC S FIFO channel %d BUSY Errorn", bcs->channel);
  302. } else {
  303. count =  bcs->tx_skb->len;
  304. bcs->tx_cnt -= count;
  305. if (PACKET_NOACK == bcs->tx_skb->pkt_type)
  306. count = -1;
  307. dev_kfree_skb_any(bcs->tx_skb);
  308. bcs->tx_skb = NULL;
  309. if (bcs->mode != L1_MODE_TRANS) {
  310.   WaitForBusy(cs);
  311.   WaitNoBusy(cs);
  312.   cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F1_INC | HFC_SEND | HFC_CHANNEL(bcs->channel));
  313. }
  314. if (bcs->st->lli.l1writewakeup && (count >= 0))
  315. bcs->st->lli.l1writewakeup(bcs->st, count);
  316. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  317. }
  318. restore_flags(flags);
  319. return;
  320. }
  321. void
  322. main_irq_hfc(struct BCState *bcs)
  323. {
  324. long flags;
  325. struct IsdnCardState *cs = bcs->cs;
  326. int z1, z2, rcnt;
  327. u_char f1, f2, cip;
  328. int receive, transmit, count = 5;
  329. struct sk_buff *skb;
  330. save_flags(flags);
  331.       Begin:
  332. cli();
  333. count--;
  334. cip = HFC_CIP | HFC_F1 | HFC_REC | HFC_CHANNEL(bcs->channel);
  335. if ((cip & 0xc3) != (cs->hw.hfc.cip & 0xc3)) {
  336. cs->BC_Write_Reg(cs, HFC_STATUS, cip, cip);
  337. WaitForBusy(cs);
  338. }
  339. WaitNoBusy(cs);
  340. receive = 0;
  341. if (bcs->mode == L1_MODE_HDLC) {
  342. f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
  343. cip = HFC_CIP | HFC_F2 | HFC_REC | HFC_CHANNEL(bcs->channel);
  344. WaitNoBusy(cs);
  345. f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
  346. if (f1 != f2) {
  347. if (cs->debug & L1_DEB_HSCX)
  348. debugl1(cs, "hfc rec %d f1(%d) f2(%d)",
  349. bcs->channel, f1, f2);
  350. receive = 1; 
  351. }
  352. }
  353. if (receive || (bcs->mode == L1_MODE_TRANS)) {
  354. WaitForBusy(cs);
  355. z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel));
  356. z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel));
  357. rcnt = z1 - z2;
  358. if (rcnt < 0)
  359. rcnt += cs->hw.hfc.fifosize;
  360. if ((bcs->mode == L1_MODE_HDLC) || (rcnt)) {
  361. rcnt++;
  362. if (cs->debug & L1_DEB_HSCX)
  363. debugl1(cs, "hfc rec %d z1(%x) z2(%x) cnt(%d)",
  364. bcs->channel, z1, z2, rcnt);
  365. /*              sti(); */
  366. if ((skb = hfc_empty_fifo(bcs, rcnt))) {
  367. skb_queue_tail(&bcs->rqueue, skb);
  368. hfc_sched_event(bcs, B_RCVBUFREADY);
  369. }
  370. }
  371. receive = 1;
  372. }
  373. restore_flags(flags);
  374. udelay(1);
  375. cli();
  376. if (bcs->tx_skb) {
  377. transmit = 1;
  378. test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
  379. hfc_fill_fifo(bcs);
  380. if (test_bit(BC_FLG_BUSY, &bcs->Flag))
  381. transmit = 0;
  382. } else {
  383. if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
  384. transmit = 1;
  385. test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
  386. hfc_fill_fifo(bcs);
  387. if (test_bit(BC_FLG_BUSY, &bcs->Flag))
  388. transmit = 0;
  389. } else {
  390. transmit = 0;
  391. hfc_sched_event(bcs, B_XMTBUFREADY);
  392. }
  393. }
  394. restore_flags(flags);
  395. if ((receive || transmit) && count)
  396. goto Begin;
  397. return;
  398. }
  399. void
  400. mode_hfc(struct BCState *bcs, int mode, int bc)
  401. {
  402. struct IsdnCardState *cs = bcs->cs;
  403. if (cs->debug & L1_DEB_HSCX)
  404. debugl1(cs, "HFC 2BS0 mode %d bchan %d/%d",
  405. mode, bc, bcs->channel);
  406. bcs->mode = mode;
  407. bcs->channel = bc;
  408. switch (mode) {
  409. case (L1_MODE_NULL):
  410.         if (bc) {
  411. cs->hw.hfc.ctmt &= ~1;
  412. cs->hw.hfc.isac_spcr &= ~0x03;
  413. }
  414. else {
  415. cs->hw.hfc.ctmt &= ~2;
  416. cs->hw.hfc.isac_spcr &= ~0x0c;
  417. }
  418. break;
  419. case (L1_MODE_TRANS):
  420.         cs->hw.hfc.ctmt &= ~(1 << bc); /* set HDLC mode */ 
  421. cs->BC_Write_Reg(cs, HFC_STATUS, cs->hw.hfc.ctmt, cs->hw.hfc.ctmt);
  422. hfc_clear_fifo(bcs); /* complete fifo clear */ 
  423. if (bc) {
  424. cs->hw.hfc.ctmt |= 1;
  425. cs->hw.hfc.isac_spcr &= ~0x03;
  426. cs->hw.hfc.isac_spcr |= 0x02;
  427. } else {
  428. cs->hw.hfc.ctmt |= 2;
  429. cs->hw.hfc.isac_spcr &= ~0x0c;
  430. cs->hw.hfc.isac_spcr |= 0x08;
  431. }
  432. break;
  433. case (L1_MODE_HDLC):
  434. if (bc) {
  435. cs->hw.hfc.ctmt &= ~1;
  436. cs->hw.hfc.isac_spcr &= ~0x03;
  437. cs->hw.hfc.isac_spcr |= 0x02;
  438. } else {
  439. cs->hw.hfc.ctmt &= ~2;
  440. cs->hw.hfc.isac_spcr &= ~0x0c;
  441. cs->hw.hfc.isac_spcr |= 0x08;
  442. }
  443. break;
  444. }
  445. cs->BC_Write_Reg(cs, HFC_STATUS, cs->hw.hfc.ctmt, cs->hw.hfc.ctmt);
  446. cs->writeisac(cs, ISAC_SPCR, cs->hw.hfc.isac_spcr);
  447. if (mode == L1_MODE_HDLC)
  448. hfc_clear_fifo(bcs);
  449. }
  450. static void
  451. hfc_l2l1(struct PStack *st, int pr, void *arg)
  452. {
  453. struct sk_buff *skb = arg;
  454. long flags;
  455. switch (pr) {
  456. case (PH_DATA | REQUEST):
  457. save_flags(flags);
  458. cli();
  459. if (st->l1.bcs->tx_skb) {
  460. skb_queue_tail(&st->l1.bcs->squeue, skb);
  461. restore_flags(flags);
  462. } else {
  463. st->l1.bcs->tx_skb = skb;
  464. test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
  465. st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
  466. restore_flags(flags);
  467. }
  468. break;
  469. case (PH_PULL | INDICATION):
  470. if (st->l1.bcs->tx_skb) {
  471. printk(KERN_WARNING "hfc_l2l1: this shouldn't happenn");
  472. break;
  473. }
  474. save_flags(flags);
  475. cli();
  476. test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
  477. st->l1.bcs->tx_skb = skb;
  478. st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
  479. restore_flags(flags);
  480. break;
  481. case (PH_PULL | REQUEST):
  482. if (!st->l1.bcs->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 (PH_ACTIVATE | REQUEST):
  489. test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
  490. mode_hfc(st->l1.bcs, st->l1.mode, st->l1.bc);
  491. l1_msg_b(st, pr, arg);
  492. break;
  493. case (PH_DEACTIVATE | REQUEST):
  494. l1_msg_b(st, pr, arg);
  495. break;
  496. case (PH_DEACTIVATE | CONFIRM):
  497. test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
  498. test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
  499. mode_hfc(st->l1.bcs, 0, st->l1.bc);
  500. st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
  501. break;
  502. }
  503. }
  504. void
  505. close_hfcstate(struct BCState *bcs)
  506. {
  507. mode_hfc(bcs, 0, bcs->channel);
  508. if (test_bit(BC_FLG_INIT, &bcs->Flag)) {
  509. skb_queue_purge(&bcs->rqueue);
  510. skb_queue_purge(&bcs->squeue);
  511. if (bcs->tx_skb) {
  512. dev_kfree_skb_any(bcs->tx_skb);
  513. bcs->tx_skb = NULL;
  514. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  515. }
  516. }
  517. test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
  518. }
  519. static int
  520. open_hfcstate(struct IsdnCardState *cs, struct BCState *bcs)
  521. {
  522. if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
  523. skb_queue_head_init(&bcs->rqueue);
  524. skb_queue_head_init(&bcs->squeue);
  525. }
  526. bcs->tx_skb = NULL;
  527. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  528. bcs->event = 0;
  529. bcs->tx_cnt = 0;
  530. return (0);
  531. }
  532. int
  533. setstack_hfc(struct PStack *st, struct BCState *bcs)
  534. {
  535. bcs->channel = st->l1.bc;
  536. if (open_hfcstate(st->l1.hardware, bcs))
  537. return (-1);
  538. st->l1.bcs = bcs;
  539. st->l2.l2l1 = hfc_l2l1;
  540. setstack_manager(st);
  541. bcs->st = st;
  542. setstack_l1_B(st);
  543. return (0);
  544. }
  545. void __init
  546. init_send(struct BCState *bcs)
  547. {
  548. int i;
  549. if (!(bcs->hw.hfc.send = kmalloc(32 * sizeof(unsigned int), GFP_ATOMIC))) {
  550. printk(KERN_WARNING
  551.        "HiSax: No memory for hfc.sendn");
  552. return;
  553. }
  554. for (i = 0; i < 32; i++)
  555. bcs->hw.hfc.send[i] = 0x1fff;
  556. }
  557. void __init
  558. inithfc(struct IsdnCardState *cs)
  559. {
  560. init_send(&cs->bcs[0]);
  561. init_send(&cs->bcs[1]);
  562. cs->BC_Send_Data = &hfc_fill_fifo;
  563. cs->bcs[0].BC_SetStack = setstack_hfc;
  564. cs->bcs[1].BC_SetStack = setstack_hfc;
  565. cs->bcs[0].BC_Close = close_hfcstate;
  566. cs->bcs[1].BC_Close = close_hfcstate;
  567. mode_hfc(cs->bcs, 0, 0);
  568. mode_hfc(cs->bcs + 1, 0, 0);
  569. }
  570. void
  571. releasehfc(struct IsdnCardState *cs)
  572. {
  573. if (cs->bcs[0].hw.hfc.send) {
  574. kfree(cs->bcs[0].hw.hfc.send);
  575. cs->bcs[0].hw.hfc.send = NULL;
  576. }
  577. if (cs->bcs[1].hw.hfc.send) {
  578. kfree(cs->bcs[1].hw.hfc.send);
  579. cs->bcs[1].hw.hfc.send = NULL;
  580. }
  581. }