ipacx.c 27 KB

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