hfc_2bds0.c 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079
  1. /* $Id: hfc_2bds0.c,v 1.18.2.6 2004/02/11 13:21:33 keil Exp $
  2. *
  3. * specific routines for CCD's HFC 2BDS0
  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. #include <linux/init.h>
  13. #include <linux/sched.h>
  14. #include "hisax.h"
  15. #include "hfc_2bds0.h"
  16. #include "isdnl1.h"
  17. #include <linux/interrupt.h>
  18. /*
  19. #define KDEBUG_DEF
  20. #include "kdebug.h"
  21. */
  22. #define byteout(addr,val) outb(val,addr)
  23. #define bytein(addr) inb(addr)
  24. static void
  25. dummyf(struct IsdnCardState *cs, u_char * data, int size)
  26. {
  27. printk(KERN_WARNING "HiSax: hfcd dummy fifo called\n");
  28. }
  29. static inline u_char
  30. ReadReg(struct IsdnCardState *cs, int data, u_char reg)
  31. {
  32. register u_char ret;
  33. if (data) {
  34. if (cs->hw.hfcD.cip != reg) {
  35. cs->hw.hfcD.cip = reg;
  36. byteout(cs->hw.hfcD.addr | 1, reg);
  37. }
  38. ret = bytein(cs->hw.hfcD.addr);
  39. #ifdef HFC_REG_DEBUG
  40. if (cs->debug & L1_DEB_HSCX_FIFO && (data != 2))
  41. debugl1(cs, "t3c RD %02x %02x", reg, ret);
  42. #endif
  43. } else
  44. ret = bytein(cs->hw.hfcD.addr | 1);
  45. return (ret);
  46. }
  47. static inline void
  48. WriteReg(struct IsdnCardState *cs, int data, u_char reg, u_char value)
  49. {
  50. if (cs->hw.hfcD.cip != reg) {
  51. cs->hw.hfcD.cip = reg;
  52. byteout(cs->hw.hfcD.addr | 1, reg);
  53. }
  54. if (data)
  55. byteout(cs->hw.hfcD.addr, value);
  56. #ifdef HFC_REG_DEBUG
  57. if (cs->debug & L1_DEB_HSCX_FIFO && (data != HFCD_DATA_NODEB))
  58. debugl1(cs, "t3c W%c %02x %02x", data ? 'D' : 'C', reg, value);
  59. #endif
  60. }
  61. /* Interface functions */
  62. static u_char
  63. readreghfcd(struct IsdnCardState *cs, u_char offset)
  64. {
  65. return(ReadReg(cs, HFCD_DATA, offset));
  66. }
  67. static void
  68. writereghfcd(struct IsdnCardState *cs, u_char offset, u_char value)
  69. {
  70. WriteReg(cs, HFCD_DATA, offset, value);
  71. }
  72. static inline int
  73. WaitForBusy(struct IsdnCardState *cs)
  74. {
  75. int to = 130;
  76. while (!(ReadReg(cs, HFCD_DATA, HFCD_STAT) & HFCD_BUSY) && to) {
  77. udelay(1);
  78. to--;
  79. }
  80. if (!to)
  81. printk(KERN_WARNING "HiSax: WaitForBusy timeout\n");
  82. return (to);
  83. }
  84. static inline int
  85. WaitNoBusy(struct IsdnCardState *cs)
  86. {
  87. int to = 130;
  88. while ((ReadReg(cs, HFCD_STATUS, HFCD_STATUS) & HFCD_BUSY) && to) {
  89. udelay(1);
  90. to--;
  91. }
  92. if (!to)
  93. printk(KERN_WARNING "HiSax: WaitNoBusy timeout\n");
  94. return (to);
  95. }
  96. static int
  97. SelFiFo(struct IsdnCardState *cs, u_char FiFo)
  98. {
  99. u_char cip;
  100. if (cs->hw.hfcD.fifo == FiFo)
  101. return(1);
  102. switch(FiFo) {
  103. case 0: cip = HFCB_FIFO | HFCB_Z1 | HFCB_SEND | HFCB_B1;
  104. break;
  105. case 1: cip = HFCB_FIFO | HFCB_Z1 | HFCB_REC | HFCB_B1;
  106. break;
  107. case 2: cip = HFCB_FIFO | HFCB_Z1 | HFCB_SEND | HFCB_B2;
  108. break;
  109. case 3: cip = HFCB_FIFO | HFCB_Z1 | HFCB_REC | HFCB_B2;
  110. break;
  111. case 4: cip = HFCD_FIFO | HFCD_Z1 | HFCD_SEND;
  112. break;
  113. case 5: cip = HFCD_FIFO | HFCD_Z1 | HFCD_REC;
  114. break;
  115. default:
  116. debugl1(cs, "SelFiFo Error");
  117. return(0);
  118. }
  119. cs->hw.hfcD.fifo = FiFo;
  120. WaitNoBusy(cs);
  121. cs->BC_Write_Reg(cs, HFCD_DATA, cip, 0);
  122. WaitForBusy(cs);
  123. return(2);
  124. }
  125. static int
  126. GetFreeFifoBytes_B(struct BCState *bcs)
  127. {
  128. int s;
  129. if (bcs->hw.hfc.f1 == bcs->hw.hfc.f2)
  130. return (bcs->cs->hw.hfcD.bfifosize);
  131. s = bcs->hw.hfc.send[bcs->hw.hfc.f1] - bcs->hw.hfc.send[bcs->hw.hfc.f2];
  132. if (s <= 0)
  133. s += bcs->cs->hw.hfcD.bfifosize;
  134. s = bcs->cs->hw.hfcD.bfifosize - s;
  135. return (s);
  136. }
  137. static int
  138. GetFreeFifoBytes_D(struct IsdnCardState *cs)
  139. {
  140. int s;
  141. if (cs->hw.hfcD.f1 == cs->hw.hfcD.f2)
  142. return (cs->hw.hfcD.dfifosize);
  143. s = cs->hw.hfcD.send[cs->hw.hfcD.f1] - cs->hw.hfcD.send[cs->hw.hfcD.f2];
  144. if (s <= 0)
  145. s += cs->hw.hfcD.dfifosize;
  146. s = cs->hw.hfcD.dfifosize - s;
  147. return (s);
  148. }
  149. static int
  150. ReadZReg(struct IsdnCardState *cs, u_char reg)
  151. {
  152. int val;
  153. WaitNoBusy(cs);
  154. val = 256 * ReadReg(cs, HFCD_DATA, reg | HFCB_Z_HIGH);
  155. WaitNoBusy(cs);
  156. val += ReadReg(cs, HFCD_DATA, reg | HFCB_Z_LOW);
  157. return (val);
  158. }
  159. static struct sk_buff
  160. *hfc_empty_fifo(struct BCState *bcs, int count)
  161. {
  162. u_char *ptr;
  163. struct sk_buff *skb;
  164. struct IsdnCardState *cs = bcs->cs;
  165. int idx;
  166. int chksum;
  167. u_char stat, cip;
  168. if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
  169. debugl1(cs, "hfc_empty_fifo");
  170. idx = 0;
  171. if (count > HSCX_BUFMAX + 3) {
  172. if (cs->debug & L1_DEB_WARN)
  173. debugl1(cs, "hfc_empty_fifo: incoming packet too large");
  174. cip = HFCB_FIFO | HFCB_FIFO_OUT | HFCB_REC | HFCB_CHANNEL(bcs->channel);
  175. while (idx++ < count) {
  176. WaitNoBusy(cs);
  177. ReadReg(cs, HFCD_DATA_NODEB, cip);
  178. }
  179. skb = NULL;
  180. } else if (count < 4) {
  181. if (cs->debug & L1_DEB_WARN)
  182. debugl1(cs, "hfc_empty_fifo: incoming packet too small");
  183. cip = HFCB_FIFO | HFCB_FIFO_OUT | HFCB_REC | HFCB_CHANNEL(bcs->channel);
  184. #ifdef ERROR_STATISTIC
  185. bcs->err_inv++;
  186. #endif
  187. while ((idx++ < count) && WaitNoBusy(cs))
  188. ReadReg(cs, HFCD_DATA_NODEB, cip);
  189. skb = NULL;
  190. } else if (!(skb = dev_alloc_skb(count - 3)))
  191. printk(KERN_WARNING "HFC: receive out of memory\n");
  192. else {
  193. ptr = skb_put(skb, count - 3);
  194. idx = 0;
  195. cip = HFCB_FIFO | HFCB_FIFO_OUT | HFCB_REC | HFCB_CHANNEL(bcs->channel);
  196. while (idx < (count - 3)) {
  197. if (!WaitNoBusy(cs))
  198. break;
  199. *ptr = ReadReg(cs, HFCD_DATA_NODEB, cip);
  200. ptr++;
  201. idx++;
  202. }
  203. if (idx != count - 3) {
  204. debugl1(cs, "RFIFO BUSY error");
  205. printk(KERN_WARNING "HFC FIFO channel %d BUSY Error\n", bcs->channel);
  206. dev_kfree_skb_irq(skb);
  207. skb = NULL;
  208. } else {
  209. WaitNoBusy(cs);
  210. chksum = (ReadReg(cs, HFCD_DATA, cip) << 8);
  211. WaitNoBusy(cs);
  212. chksum += ReadReg(cs, HFCD_DATA, cip);
  213. WaitNoBusy(cs);
  214. stat = ReadReg(cs, HFCD_DATA, cip);
  215. if (cs->debug & L1_DEB_HSCX)
  216. debugl1(cs, "hfc_empty_fifo %d chksum %x stat %x",
  217. bcs->channel, chksum, stat);
  218. if (stat) {
  219. debugl1(cs, "FIFO CRC error");
  220. dev_kfree_skb_irq(skb);
  221. skb = NULL;
  222. #ifdef ERROR_STATISTIC
  223. bcs->err_crc++;
  224. #endif
  225. }
  226. }
  227. }
  228. WaitForBusy(cs);
  229. WaitNoBusy(cs);
  230. stat = ReadReg(cs, HFCD_DATA, HFCB_FIFO | HFCB_F2_INC |
  231. HFCB_REC | HFCB_CHANNEL(bcs->channel));
  232. WaitForBusy(cs);
  233. return (skb);
  234. }
  235. static void
  236. hfc_fill_fifo(struct BCState *bcs)
  237. {
  238. struct IsdnCardState *cs = bcs->cs;
  239. int idx, fcnt;
  240. int count;
  241. u_char cip;
  242. if (!bcs->tx_skb)
  243. return;
  244. if (bcs->tx_skb->len <= 0)
  245. return;
  246. SelFiFo(cs, HFCB_SEND | HFCB_CHANNEL(bcs->channel));
  247. cip = HFCB_FIFO | HFCB_F1 | HFCB_SEND | HFCB_CHANNEL(bcs->channel);
  248. WaitNoBusy(cs);
  249. bcs->hw.hfc.f1 = ReadReg(cs, HFCD_DATA, cip);
  250. WaitNoBusy(cs);
  251. cip = HFCB_FIFO | HFCB_F2 | HFCB_SEND | HFCB_CHANNEL(bcs->channel);
  252. WaitNoBusy(cs);
  253. bcs->hw.hfc.f2 = ReadReg(cs, HFCD_DATA, cip);
  254. bcs->hw.hfc.send[bcs->hw.hfc.f1] = ReadZReg(cs, HFCB_FIFO | HFCB_Z1 | HFCB_SEND | HFCB_CHANNEL(bcs->channel));
  255. if (cs->debug & L1_DEB_HSCX)
  256. debugl1(cs, "hfc_fill_fifo %d f1(%d) f2(%d) z1(%x)",
  257. bcs->channel, bcs->hw.hfc.f1, bcs->hw.hfc.f2,
  258. bcs->hw.hfc.send[bcs->hw.hfc.f1]);
  259. fcnt = bcs->hw.hfc.f1 - bcs->hw.hfc.f2;
  260. if (fcnt < 0)
  261. fcnt += 32;
  262. if (fcnt > 30) {
  263. if (cs->debug & L1_DEB_HSCX)
  264. debugl1(cs, "hfc_fill_fifo more as 30 frames");
  265. return;
  266. }
  267. count = GetFreeFifoBytes_B(bcs);
  268. if (cs->debug & L1_DEB_HSCX)
  269. debugl1(cs, "hfc_fill_fifo %d count(%ld/%d),%lx",
  270. bcs->channel, bcs->tx_skb->len,
  271. count, current->state);
  272. if (count < bcs->tx_skb->len) {
  273. if (cs->debug & L1_DEB_HSCX)
  274. debugl1(cs, "hfc_fill_fifo no fifo mem");
  275. return;
  276. }
  277. cip = HFCB_FIFO | HFCB_FIFO_IN | HFCB_SEND | HFCB_CHANNEL(bcs->channel);
  278. idx = 0;
  279. WaitForBusy(cs);
  280. WaitNoBusy(cs);
  281. WriteReg(cs, HFCD_DATA_NODEB, cip, bcs->tx_skb->data[idx++]);
  282. while (idx < bcs->tx_skb->len) {
  283. if (!WaitNoBusy(cs))
  284. break;
  285. WriteReg(cs, HFCD_DATA_NODEB, cip, bcs->tx_skb->data[idx]);
  286. idx++;
  287. }
  288. if (idx != bcs->tx_skb->len) {
  289. debugl1(cs, "FIFO Send BUSY error");
  290. printk(KERN_WARNING "HFC S FIFO channel %d BUSY Error\n", bcs->channel);
  291. } else {
  292. bcs->tx_cnt -= bcs->tx_skb->len;
  293. if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
  294. (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
  295. u_long flags;
  296. spin_lock_irqsave(&bcs->aclock, flags);
  297. bcs->ackcnt += bcs->tx_skb->len;
  298. spin_unlock_irqrestore(&bcs->aclock, flags);
  299. schedule_event(bcs, B_ACKPENDING);
  300. }
  301. dev_kfree_skb_any(bcs->tx_skb);
  302. bcs->tx_skb = NULL;
  303. }
  304. WaitForBusy(cs);
  305. WaitNoBusy(cs);
  306. ReadReg(cs, HFCD_DATA, HFCB_FIFO | HFCB_F1_INC | HFCB_SEND | HFCB_CHANNEL(bcs->channel));
  307. WaitForBusy(cs);
  308. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  309. return;
  310. }
  311. static void
  312. hfc_send_data(struct BCState *bcs)
  313. {
  314. struct IsdnCardState *cs = bcs->cs;
  315. if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
  316. hfc_fill_fifo(bcs);
  317. test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
  318. } else
  319. debugl1(cs,"send_data %d blocked", bcs->channel);
  320. }
  321. static void
  322. main_rec_2bds0(struct BCState *bcs)
  323. {
  324. struct IsdnCardState *cs = bcs->cs;
  325. int z1, z2, rcnt;
  326. u_char f1, f2, cip;
  327. int receive, count = 5;
  328. struct sk_buff *skb;
  329. Begin:
  330. count--;
  331. if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
  332. debugl1(cs,"rec_data %d blocked", bcs->channel);
  333. return;
  334. }
  335. SelFiFo(cs, HFCB_REC | HFCB_CHANNEL(bcs->channel));
  336. cip = HFCB_FIFO | HFCB_F1 | HFCB_REC | HFCB_CHANNEL(bcs->channel);
  337. WaitNoBusy(cs);
  338. f1 = ReadReg(cs, HFCD_DATA, cip);
  339. cip = HFCB_FIFO | HFCB_F2 | HFCB_REC | HFCB_CHANNEL(bcs->channel);
  340. WaitNoBusy(cs);
  341. f2 = ReadReg(cs, HFCD_DATA, cip);
  342. if (f1 != f2) {
  343. if (cs->debug & L1_DEB_HSCX)
  344. debugl1(cs, "hfc rec %d f1(%d) f2(%d)",
  345. bcs->channel, f1, f2);
  346. z1 = ReadZReg(cs, HFCB_FIFO | HFCB_Z1 | HFCB_REC | HFCB_CHANNEL(bcs->channel));
  347. z2 = ReadZReg(cs, HFCB_FIFO | HFCB_Z2 | HFCB_REC | HFCB_CHANNEL(bcs->channel));
  348. rcnt = z1 - z2;
  349. if (rcnt < 0)
  350. rcnt += cs->hw.hfcD.bfifosize;
  351. rcnt++;
  352. if (cs->debug & L1_DEB_HSCX)
  353. debugl1(cs, "hfc rec %d z1(%x) z2(%x) cnt(%d)",
  354. bcs->channel, z1, z2, rcnt);
  355. if ((skb = hfc_empty_fifo(bcs, rcnt))) {
  356. skb_queue_tail(&bcs->rqueue, skb);
  357. schedule_event(bcs, B_RCVBUFREADY);
  358. }
  359. rcnt = f1 -f2;
  360. if (rcnt<0)
  361. rcnt += 32;
  362. if (rcnt>1)
  363. receive = 1;
  364. else
  365. receive = 0;
  366. } else
  367. receive = 0;
  368. test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
  369. if (count && receive)
  370. goto Begin;
  371. return;
  372. }
  373. static void
  374. mode_2bs0(struct BCState *bcs, int mode, int bc)
  375. {
  376. struct IsdnCardState *cs = bcs->cs;
  377. if (cs->debug & L1_DEB_HSCX)
  378. debugl1(cs, "HFCD bchannel mode %d bchan %d/%d",
  379. mode, bc, bcs->channel);
  380. bcs->mode = mode;
  381. bcs->channel = bc;
  382. switch (mode) {
  383. case (L1_MODE_NULL):
  384. if (bc) {
  385. cs->hw.hfcD.conn |= 0x18;
  386. cs->hw.hfcD.sctrl &= ~SCTRL_B2_ENA;
  387. } else {
  388. cs->hw.hfcD.conn |= 0x3;
  389. cs->hw.hfcD.sctrl &= ~SCTRL_B1_ENA;
  390. }
  391. break;
  392. case (L1_MODE_TRANS):
  393. if (bc) {
  394. cs->hw.hfcD.ctmt |= 2;
  395. cs->hw.hfcD.conn &= ~0x18;
  396. cs->hw.hfcD.sctrl |= SCTRL_B2_ENA;
  397. } else {
  398. cs->hw.hfcD.ctmt |= 1;
  399. cs->hw.hfcD.conn &= ~0x3;
  400. cs->hw.hfcD.sctrl |= SCTRL_B1_ENA;
  401. }
  402. break;
  403. case (L1_MODE_HDLC):
  404. if (bc) {
  405. cs->hw.hfcD.ctmt &= ~2;
  406. cs->hw.hfcD.conn &= ~0x18;
  407. cs->hw.hfcD.sctrl |= SCTRL_B2_ENA;
  408. } else {
  409. cs->hw.hfcD.ctmt &= ~1;
  410. cs->hw.hfcD.conn &= ~0x3;
  411. cs->hw.hfcD.sctrl |= SCTRL_B1_ENA;
  412. }
  413. break;
  414. }
  415. WriteReg(cs, HFCD_DATA, HFCD_SCTRL, cs->hw.hfcD.sctrl);
  416. WriteReg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcD.ctmt);
  417. WriteReg(cs, HFCD_DATA, HFCD_CONN, cs->hw.hfcD.conn);
  418. }
  419. static void
  420. hfc_l2l1(struct PStack *st, int pr, void *arg)
  421. {
  422. struct BCState *bcs = st->l1.bcs;
  423. struct sk_buff *skb = arg;
  424. u_long flags;
  425. switch (pr) {
  426. case (PH_DATA | REQUEST):
  427. spin_lock_irqsave(&bcs->cs->lock, flags);
  428. if (bcs->tx_skb) {
  429. skb_queue_tail(&bcs->squeue, skb);
  430. } else {
  431. bcs->tx_skb = skb;
  432. // test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
  433. bcs->cs->BC_Send_Data(bcs);
  434. }
  435. spin_unlock_irqrestore(&bcs->cs->lock, flags);
  436. break;
  437. case (PH_PULL | INDICATION):
  438. spin_lock_irqsave(&bcs->cs->lock, flags);
  439. if (bcs->tx_skb) {
  440. printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n");
  441. } else {
  442. // test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
  443. bcs->tx_skb = skb;
  444. bcs->cs->BC_Send_Data(bcs);
  445. }
  446. spin_unlock_irqrestore(&bcs->cs->lock, flags);
  447. break;
  448. case (PH_PULL | REQUEST):
  449. if (!bcs->tx_skb) {
  450. test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
  451. st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
  452. } else
  453. test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
  454. break;
  455. case (PH_ACTIVATE | REQUEST):
  456. spin_lock_irqsave(&bcs->cs->lock, flags);
  457. test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
  458. mode_2bs0(bcs, st->l1.mode, st->l1.bc);
  459. spin_unlock_irqrestore(&bcs->cs->lock, flags);
  460. l1_msg_b(st, pr, arg);
  461. break;
  462. case (PH_DEACTIVATE | REQUEST):
  463. l1_msg_b(st, pr, arg);
  464. break;
  465. case (PH_DEACTIVATE | CONFIRM):
  466. spin_lock_irqsave(&bcs->cs->lock, flags);
  467. test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
  468. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  469. mode_2bs0(bcs, 0, st->l1.bc);
  470. spin_unlock_irqrestore(&bcs->cs->lock, flags);
  471. st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
  472. break;
  473. }
  474. }
  475. static void
  476. close_2bs0(struct BCState *bcs)
  477. {
  478. mode_2bs0(bcs, 0, bcs->channel);
  479. if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
  480. skb_queue_purge(&bcs->rqueue);
  481. skb_queue_purge(&bcs->squeue);
  482. if (bcs->tx_skb) {
  483. dev_kfree_skb_any(bcs->tx_skb);
  484. bcs->tx_skb = NULL;
  485. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  486. }
  487. }
  488. }
  489. static int
  490. open_hfcstate(struct IsdnCardState *cs, struct BCState *bcs)
  491. {
  492. if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
  493. skb_queue_head_init(&bcs->rqueue);
  494. skb_queue_head_init(&bcs->squeue);
  495. }
  496. bcs->tx_skb = NULL;
  497. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  498. bcs->event = 0;
  499. bcs->tx_cnt = 0;
  500. return (0);
  501. }
  502. static int
  503. setstack_2b(struct PStack *st, struct BCState *bcs)
  504. {
  505. bcs->channel = st->l1.bc;
  506. if (open_hfcstate(st->l1.hardware, bcs))
  507. return (-1);
  508. st->l1.bcs = bcs;
  509. st->l2.l2l1 = hfc_l2l1;
  510. setstack_manager(st);
  511. bcs->st = st;
  512. setstack_l1_B(st);
  513. return (0);
  514. }
  515. static void
  516. hfcd_bh(struct work_struct *work)
  517. {
  518. struct IsdnCardState *cs =
  519. container_of(work, struct IsdnCardState, tqueue);
  520. if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
  521. switch (cs->dc.hfcd.ph_state) {
  522. case (0):
  523. l1_msg(cs, HW_RESET | INDICATION, NULL);
  524. break;
  525. case (3):
  526. l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
  527. break;
  528. case (8):
  529. l1_msg(cs, HW_RSYNC | INDICATION, NULL);
  530. break;
  531. case (6):
  532. l1_msg(cs, HW_INFO2 | INDICATION, NULL);
  533. break;
  534. case (7):
  535. l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
  536. break;
  537. default:
  538. break;
  539. }
  540. }
  541. if (test_and_clear_bit(D_RCVBUFREADY, &cs->event))
  542. DChannel_proc_rcv(cs);
  543. if (test_and_clear_bit(D_XMTBUFREADY, &cs->event))
  544. DChannel_proc_xmt(cs);
  545. }
  546. static
  547. int receive_dmsg(struct IsdnCardState *cs)
  548. {
  549. struct sk_buff *skb;
  550. int idx;
  551. int rcnt, z1, z2;
  552. u_char stat, cip, f1, f2;
  553. int chksum;
  554. int count=5;
  555. u_char *ptr;
  556. if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
  557. debugl1(cs, "rec_dmsg blocked");
  558. return(1);
  559. }
  560. SelFiFo(cs, 4 | HFCD_REC);
  561. cip = HFCD_FIFO | HFCD_F1 | HFCD_REC;
  562. WaitNoBusy(cs);
  563. f1 = cs->readisac(cs, cip) & 0xf;
  564. cip = HFCD_FIFO | HFCD_F2 | HFCD_REC;
  565. WaitNoBusy(cs);
  566. f2 = cs->readisac(cs, cip) & 0xf;
  567. while ((f1 != f2) && count--) {
  568. z1 = ReadZReg(cs, HFCD_FIFO | HFCD_Z1 | HFCD_REC);
  569. z2 = ReadZReg(cs, HFCD_FIFO | HFCD_Z2 | HFCD_REC);
  570. rcnt = z1 - z2;
  571. if (rcnt < 0)
  572. rcnt += cs->hw.hfcD.dfifosize;
  573. rcnt++;
  574. if (cs->debug & L1_DEB_ISAC)
  575. debugl1(cs, "hfcd recd f1(%d) f2(%d) z1(%x) z2(%x) cnt(%d)",
  576. f1, f2, z1, z2, rcnt);
  577. idx = 0;
  578. cip = HFCD_FIFO | HFCD_FIFO_OUT | HFCD_REC;
  579. if (rcnt > MAX_DFRAME_LEN + 3) {
  580. if (cs->debug & L1_DEB_WARN)
  581. debugl1(cs, "empty_fifo d: incoming packet too large");
  582. while (idx < rcnt) {
  583. if (!(WaitNoBusy(cs)))
  584. break;
  585. ReadReg(cs, HFCD_DATA_NODEB, cip);
  586. idx++;
  587. }
  588. } else if (rcnt < 4) {
  589. if (cs->debug & L1_DEB_WARN)
  590. debugl1(cs, "empty_fifo d: incoming packet too small");
  591. while ((idx++ < rcnt) && WaitNoBusy(cs))
  592. ReadReg(cs, HFCD_DATA_NODEB, cip);
  593. } else if ((skb = dev_alloc_skb(rcnt - 3))) {
  594. ptr = skb_put(skb, rcnt - 3);
  595. while (idx < (rcnt - 3)) {
  596. if (!(WaitNoBusy(cs)))
  597. break;
  598. *ptr = ReadReg(cs, HFCD_DATA_NODEB, cip);
  599. idx++;
  600. ptr++;
  601. }
  602. if (idx != (rcnt - 3)) {
  603. debugl1(cs, "RFIFO D BUSY error");
  604. printk(KERN_WARNING "HFC DFIFO channel BUSY Error\n");
  605. dev_kfree_skb_irq(skb);
  606. skb = NULL;
  607. #ifdef ERROR_STATISTIC
  608. cs->err_rx++;
  609. #endif
  610. } else {
  611. WaitNoBusy(cs);
  612. chksum = (ReadReg(cs, HFCD_DATA, cip) << 8);
  613. WaitNoBusy(cs);
  614. chksum += ReadReg(cs, HFCD_DATA, cip);
  615. WaitNoBusy(cs);
  616. stat = ReadReg(cs, HFCD_DATA, cip);
  617. if (cs->debug & L1_DEB_ISAC)
  618. debugl1(cs, "empty_dfifo chksum %x stat %x",
  619. chksum, stat);
  620. if (stat) {
  621. debugl1(cs, "FIFO CRC error");
  622. dev_kfree_skb_irq(skb);
  623. skb = NULL;
  624. #ifdef ERROR_STATISTIC
  625. cs->err_crc++;
  626. #endif
  627. } else {
  628. skb_queue_tail(&cs->rq, skb);
  629. schedule_event(cs, D_RCVBUFREADY);
  630. }
  631. }
  632. } else
  633. printk(KERN_WARNING "HFC: D receive out of memory\n");
  634. WaitForBusy(cs);
  635. cip = HFCD_FIFO | HFCD_F2_INC | HFCD_REC;
  636. WaitNoBusy(cs);
  637. stat = ReadReg(cs, HFCD_DATA, cip);
  638. WaitForBusy(cs);
  639. cip = HFCD_FIFO | HFCD_F2 | HFCD_REC;
  640. WaitNoBusy(cs);
  641. f2 = cs->readisac(cs, cip) & 0xf;
  642. }
  643. test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
  644. return(1);
  645. }
  646. static void
  647. hfc_fill_dfifo(struct IsdnCardState *cs)
  648. {
  649. int idx, fcnt;
  650. int count;
  651. u_char cip;
  652. if (!cs->tx_skb)
  653. return;
  654. if (cs->tx_skb->len <= 0)
  655. return;
  656. SelFiFo(cs, 4 | HFCD_SEND);
  657. cip = HFCD_FIFO | HFCD_F1 | HFCD_SEND;
  658. WaitNoBusy(cs);
  659. cs->hw.hfcD.f1 = ReadReg(cs, HFCD_DATA, cip) & 0xf;
  660. WaitNoBusy(cs);
  661. cip = HFCD_FIFO | HFCD_F2 | HFCD_SEND;
  662. cs->hw.hfcD.f2 = ReadReg(cs, HFCD_DATA, cip) & 0xf;
  663. cs->hw.hfcD.send[cs->hw.hfcD.f1] = ReadZReg(cs, HFCD_FIFO | HFCD_Z1 | HFCD_SEND);
  664. if (cs->debug & L1_DEB_ISAC)
  665. debugl1(cs, "hfc_fill_Dfifo f1(%d) f2(%d) z1(%x)",
  666. cs->hw.hfcD.f1, cs->hw.hfcD.f2,
  667. cs->hw.hfcD.send[cs->hw.hfcD.f1]);
  668. fcnt = cs->hw.hfcD.f1 - cs->hw.hfcD.f2;
  669. if (fcnt < 0)
  670. fcnt += 16;
  671. if (fcnt > 14) {
  672. if (cs->debug & L1_DEB_HSCX)
  673. debugl1(cs, "hfc_fill_Dfifo more as 14 frames");
  674. return;
  675. }
  676. count = GetFreeFifoBytes_D(cs);
  677. if (cs->debug & L1_DEB_ISAC)
  678. debugl1(cs, "hfc_fill_Dfifo count(%ld/%d)",
  679. cs->tx_skb->len, count);
  680. if (count < cs->tx_skb->len) {
  681. if (cs->debug & L1_DEB_ISAC)
  682. debugl1(cs, "hfc_fill_Dfifo no fifo mem");
  683. return;
  684. }
  685. cip = HFCD_FIFO | HFCD_FIFO_IN | HFCD_SEND;
  686. idx = 0;
  687. WaitForBusy(cs);
  688. WaitNoBusy(cs);
  689. WriteReg(cs, HFCD_DATA_NODEB, cip, cs->tx_skb->data[idx++]);
  690. while (idx < cs->tx_skb->len) {
  691. if (!(WaitNoBusy(cs)))
  692. break;
  693. WriteReg(cs, HFCD_DATA_NODEB, cip, cs->tx_skb->data[idx]);
  694. idx++;
  695. }
  696. if (idx != cs->tx_skb->len) {
  697. debugl1(cs, "DFIFO Send BUSY error");
  698. printk(KERN_WARNING "HFC S DFIFO channel BUSY Error\n");
  699. }
  700. WaitForBusy(cs);
  701. WaitNoBusy(cs);
  702. ReadReg(cs, HFCD_DATA, HFCD_FIFO | HFCD_F1_INC | HFCD_SEND);
  703. dev_kfree_skb_any(cs->tx_skb);
  704. cs->tx_skb = NULL;
  705. WaitForBusy(cs);
  706. return;
  707. }
  708. static
  709. struct BCState *Sel_BCS(struct IsdnCardState *cs, int channel)
  710. {
  711. if (cs->bcs[0].mode && (cs->bcs[0].channel == channel))
  712. return(&cs->bcs[0]);
  713. else if (cs->bcs[1].mode && (cs->bcs[1].channel == channel))
  714. return(&cs->bcs[1]);
  715. else
  716. return(NULL);
  717. }
  718. void
  719. hfc2bds0_interrupt(struct IsdnCardState *cs, u_char val)
  720. {
  721. u_char exval;
  722. struct BCState *bcs;
  723. int count=15;
  724. if (cs->debug & L1_DEB_ISAC)
  725. debugl1(cs, "HFCD irq %x %s", val,
  726. test_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags) ?
  727. "locked" : "unlocked");
  728. val &= cs->hw.hfcD.int_m1;
  729. if (val & 0x40) { /* TE state machine irq */
  730. exval = cs->readisac(cs, HFCD_STATES) & 0xf;
  731. if (cs->debug & L1_DEB_ISAC)
  732. debugl1(cs, "ph_state chg %d->%d", cs->dc.hfcd.ph_state,
  733. exval);
  734. cs->dc.hfcd.ph_state = exval;
  735. schedule_event(cs, D_L1STATECHANGE);
  736. val &= ~0x40;
  737. }
  738. while (val) {
  739. if (test_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
  740. cs->hw.hfcD.int_s1 |= val;
  741. return;
  742. }
  743. if (cs->hw.hfcD.int_s1 & 0x18) {
  744. exval = val;
  745. val = cs->hw.hfcD.int_s1;
  746. cs->hw.hfcD.int_s1 = exval;
  747. }
  748. if (val & 0x08) {
  749. if (!(bcs=Sel_BCS(cs, 0))) {
  750. if (cs->debug)
  751. debugl1(cs, "hfcd spurious 0x08 IRQ");
  752. } else
  753. main_rec_2bds0(bcs);
  754. }
  755. if (val & 0x10) {
  756. if (!(bcs=Sel_BCS(cs, 1))) {
  757. if (cs->debug)
  758. debugl1(cs, "hfcd spurious 0x10 IRQ");
  759. } else
  760. main_rec_2bds0(bcs);
  761. }
  762. if (val & 0x01) {
  763. if (!(bcs=Sel_BCS(cs, 0))) {
  764. if (cs->debug)
  765. debugl1(cs, "hfcd spurious 0x01 IRQ");
  766. } else {
  767. if (bcs->tx_skb) {
  768. if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
  769. hfc_fill_fifo(bcs);
  770. test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
  771. } else
  772. debugl1(cs,"fill_data %d blocked", bcs->channel);
  773. } else {
  774. if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
  775. if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
  776. hfc_fill_fifo(bcs);
  777. test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
  778. } else
  779. debugl1(cs,"fill_data %d blocked", bcs->channel);
  780. } else {
  781. schedule_event(bcs, B_XMTBUFREADY);
  782. }
  783. }
  784. }
  785. }
  786. if (val & 0x02) {
  787. if (!(bcs=Sel_BCS(cs, 1))) {
  788. if (cs->debug)
  789. debugl1(cs, "hfcd spurious 0x02 IRQ");
  790. } else {
  791. if (bcs->tx_skb) {
  792. if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
  793. hfc_fill_fifo(bcs);
  794. test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
  795. } else
  796. debugl1(cs,"fill_data %d blocked", bcs->channel);
  797. } else {
  798. if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
  799. if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
  800. hfc_fill_fifo(bcs);
  801. test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
  802. } else
  803. debugl1(cs,"fill_data %d blocked", bcs->channel);
  804. } else {
  805. schedule_event(bcs, B_XMTBUFREADY);
  806. }
  807. }
  808. }
  809. }
  810. if (val & 0x20) { /* receive dframe */
  811. receive_dmsg(cs);
  812. }
  813. if (val & 0x04) { /* dframe transmitted */
  814. if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
  815. del_timer(&cs->dbusytimer);
  816. if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
  817. schedule_event(cs, D_CLEARBUSY);
  818. if (cs->tx_skb) {
  819. if (cs->tx_skb->len) {
  820. if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
  821. hfc_fill_dfifo(cs);
  822. test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
  823. } else {
  824. debugl1(cs, "hfc_fill_dfifo irq blocked");
  825. }
  826. goto afterXPR;
  827. } else {
  828. dev_kfree_skb_irq(cs->tx_skb);
  829. cs->tx_cnt = 0;
  830. cs->tx_skb = NULL;
  831. }
  832. }
  833. if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
  834. cs->tx_cnt = 0;
  835. if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
  836. hfc_fill_dfifo(cs);
  837. test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
  838. } else {
  839. debugl1(cs, "hfc_fill_dfifo irq blocked");
  840. }
  841. } else
  842. schedule_event(cs, D_XMTBUFREADY);
  843. }
  844. afterXPR:
  845. if (cs->hw.hfcD.int_s1 && count--) {
  846. val = cs->hw.hfcD.int_s1;
  847. cs->hw.hfcD.int_s1 = 0;
  848. if (cs->debug & L1_DEB_ISAC)
  849. debugl1(cs, "HFCD irq %x loop %d", val, 15-count);
  850. } else
  851. val = 0;
  852. }
  853. }
  854. static void
  855. HFCD_l1hw(struct PStack *st, int pr, void *arg)
  856. {
  857. struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
  858. struct sk_buff *skb = arg;
  859. u_long flags;
  860. switch (pr) {
  861. case (PH_DATA | REQUEST):
  862. if (cs->debug & DEB_DLOG_HEX)
  863. LogFrame(cs, skb->data, skb->len);
  864. if (cs->debug & DEB_DLOG_VERBOSE)
  865. dlogframe(cs, skb, 0);
  866. spin_lock_irqsave(&cs->lock, flags);
  867. if (cs->tx_skb) {
  868. skb_queue_tail(&cs->sq, skb);
  869. #ifdef L2FRAME_DEBUG /* psa */
  870. if (cs->debug & L1_DEB_LAPD)
  871. Logl2Frame(cs, skb, "PH_DATA Queued", 0);
  872. #endif
  873. } else {
  874. cs->tx_skb = skb;
  875. cs->tx_cnt = 0;
  876. #ifdef L2FRAME_DEBUG /* psa */
  877. if (cs->debug & L1_DEB_LAPD)
  878. Logl2Frame(cs, skb, "PH_DATA", 0);
  879. #endif
  880. if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
  881. hfc_fill_dfifo(cs);
  882. test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
  883. } else
  884. debugl1(cs, "hfc_fill_dfifo blocked");
  885. }
  886. spin_unlock_irqrestore(&cs->lock, flags);
  887. break;
  888. case (PH_PULL | INDICATION):
  889. spin_lock_irqsave(&cs->lock, flags);
  890. if (cs->tx_skb) {
  891. if (cs->debug & L1_DEB_WARN)
  892. debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
  893. skb_queue_tail(&cs->sq, skb);
  894. spin_unlock_irqrestore(&cs->lock, flags);
  895. break;
  896. }
  897. if (cs->debug & DEB_DLOG_HEX)
  898. LogFrame(cs, skb->data, skb->len);
  899. if (cs->debug & DEB_DLOG_VERBOSE)
  900. dlogframe(cs, skb, 0);
  901. cs->tx_skb = skb;
  902. cs->tx_cnt = 0;
  903. #ifdef L2FRAME_DEBUG /* psa */
  904. if (cs->debug & L1_DEB_LAPD)
  905. Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
  906. #endif
  907. if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
  908. hfc_fill_dfifo(cs);
  909. test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
  910. } else
  911. debugl1(cs, "hfc_fill_dfifo blocked");
  912. spin_unlock_irqrestore(&cs->lock, flags);
  913. break;
  914. case (PH_PULL | REQUEST):
  915. #ifdef L2FRAME_DEBUG /* psa */
  916. if (cs->debug & L1_DEB_LAPD)
  917. debugl1(cs, "-> PH_REQUEST_PULL");
  918. #endif
  919. if (!cs->tx_skb) {
  920. test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
  921. st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
  922. } else
  923. test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
  924. break;
  925. case (HW_RESET | REQUEST):
  926. spin_lock_irqsave(&cs->lock, flags);
  927. cs->writeisac(cs, HFCD_STATES, HFCD_LOAD_STATE | 3); /* HFC ST 3 */
  928. udelay(6);
  929. cs->writeisac(cs, HFCD_STATES, 3); /* HFC ST 2 */
  930. cs->hw.hfcD.mst_m |= HFCD_MASTER;
  931. cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m);
  932. cs->writeisac(cs, HFCD_STATES, HFCD_ACTIVATE | HFCD_DO_ACTION);
  933. spin_unlock_irqrestore(&cs->lock, flags);
  934. l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
  935. break;
  936. case (HW_ENABLE | REQUEST):
  937. spin_lock_irqsave(&cs->lock, flags);
  938. cs->writeisac(cs, HFCD_STATES, HFCD_ACTIVATE | HFCD_DO_ACTION);
  939. spin_unlock_irqrestore(&cs->lock, flags);
  940. break;
  941. case (HW_DEACTIVATE | REQUEST):
  942. spin_lock_irqsave(&cs->lock, flags);
  943. cs->hw.hfcD.mst_m &= ~HFCD_MASTER;
  944. cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m);
  945. spin_unlock_irqrestore(&cs->lock, flags);
  946. break;
  947. case (HW_INFO3 | REQUEST):
  948. spin_lock_irqsave(&cs->lock, flags);
  949. cs->hw.hfcD.mst_m |= HFCD_MASTER;
  950. cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m);
  951. spin_unlock_irqrestore(&cs->lock, flags);
  952. break;
  953. default:
  954. if (cs->debug & L1_DEB_WARN)
  955. debugl1(cs, "hfcd_l1hw unknown pr %4x", pr);
  956. break;
  957. }
  958. }
  959. static void
  960. setstack_hfcd(struct PStack *st, struct IsdnCardState *cs)
  961. {
  962. st->l1.l1hw = HFCD_l1hw;
  963. }
  964. static void
  965. hfc_dbusy_timer(struct IsdnCardState *cs)
  966. {
  967. }
  968. static unsigned int
  969. *init_send_hfcd(int cnt)
  970. {
  971. int i;
  972. unsigned *send;
  973. if (!(send = kmalloc(cnt * sizeof(unsigned int), GFP_ATOMIC))) {
  974. printk(KERN_WARNING
  975. "HiSax: No memory for hfcd.send\n");
  976. return(NULL);
  977. }
  978. for (i = 0; i < cnt; i++)
  979. send[i] = 0x1fff;
  980. return(send);
  981. }
  982. void
  983. init2bds0(struct IsdnCardState *cs)
  984. {
  985. cs->setstack_d = setstack_hfcd;
  986. if (!cs->hw.hfcD.send)
  987. cs->hw.hfcD.send = init_send_hfcd(16);
  988. if (!cs->bcs[0].hw.hfc.send)
  989. cs->bcs[0].hw.hfc.send = init_send_hfcd(32);
  990. if (!cs->bcs[1].hw.hfc.send)
  991. cs->bcs[1].hw.hfc.send = init_send_hfcd(32);
  992. cs->BC_Send_Data = &hfc_send_data;
  993. cs->bcs[0].BC_SetStack = setstack_2b;
  994. cs->bcs[1].BC_SetStack = setstack_2b;
  995. cs->bcs[0].BC_Close = close_2bs0;
  996. cs->bcs[1].BC_Close = close_2bs0;
  997. mode_2bs0(cs->bcs, 0, 0);
  998. mode_2bs0(cs->bcs + 1, 0, 1);
  999. }
  1000. void
  1001. release2bds0(struct IsdnCardState *cs)
  1002. {
  1003. kfree(cs->bcs[0].hw.hfc.send);
  1004. cs->bcs[0].hw.hfc.send = NULL;
  1005. kfree(cs->bcs[1].hw.hfc.send);
  1006. cs->bcs[1].hw.hfc.send = NULL;
  1007. kfree(cs->hw.hfcD.send);
  1008. cs->hw.hfcD.send = NULL;
  1009. }
  1010. void
  1011. set_cs_func(struct IsdnCardState *cs)
  1012. {
  1013. cs->readisac = &readreghfcd;
  1014. cs->writeisac = &writereghfcd;
  1015. cs->readisacfifo = &dummyf;
  1016. cs->writeisacfifo = &dummyf;
  1017. cs->BC_Read_Reg = &ReadReg;
  1018. cs->BC_Write_Reg = &WriteReg;
  1019. cs->dbusytimer.function = (void *) hfc_dbusy_timer;
  1020. cs->dbusytimer.data = (long) cs;
  1021. init_timer(&cs->dbusytimer);
  1022. INIT_WORK(&cs->tqueue, hfcd_bh);
  1023. }