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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* $Id: netjet.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  2.  *
  3.  * low level stuff for Traverse Technologie NETJet ISDN cards
  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.  * Thanks to Traverse Technologies Australia for documents and information
  12.  *
  13.  * 16-Apr-2002 - led code added - Guy Ellis (guy@traverse.com.au)
  14.  *
  15.  */
  16. #define __NO_VERSION__
  17. #include <linux/init.h>
  18. #include "hisax.h"
  19. #include "isac.h"
  20. #include "hscx.h"
  21. #include "isdnl1.h"
  22. #include <linux/pci.h>
  23. #include <linux/interrupt.h>
  24. #include <linux/ppp_defs.h>
  25. #include <asm/io.h>
  26. #include "netjet.h"
  27. const char *NETjet_revision = "$Revision: 1.1.4.1 $";
  28. /* Interface functions */
  29. u_char
  30. NETjet_ReadIC(struct IsdnCardState *cs, u_char offset)
  31. {
  32. long flags;
  33. u_char ret;
  34. save_flags(flags);
  35. cli();
  36. cs->hw.njet.auxd &= 0xfc;
  37. cs->hw.njet.auxd |= (offset>>4) & 3;
  38. byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
  39. ret = bytein(cs->hw.njet.isac + ((offset & 0xf)<<2));
  40. restore_flags(flags);
  41. return(ret);
  42. }
  43. void
  44. NETjet_WriteIC(struct IsdnCardState *cs, u_char offset, u_char value)
  45. {
  46. long flags;
  47. save_flags(flags);
  48. cli();
  49. cs->hw.njet.auxd &= 0xfc;
  50. cs->hw.njet.auxd |= (offset>>4) & 3;
  51. byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
  52. byteout(cs->hw.njet.isac + ((offset & 0xf)<<2), value);
  53. restore_flags(flags);
  54. }
  55. void
  56. NETjet_ReadICfifo(struct IsdnCardState *cs, u_char *data, int size)
  57. {
  58. cs->hw.njet.auxd &= 0xfc;
  59. byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
  60. insb(cs->hw.njet.isac, data, size);
  61. }
  62. __u16 fcstab[256] =
  63. {
  64. 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
  65. 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
  66. 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
  67. 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
  68. 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
  69. 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
  70. 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
  71. 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
  72. 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
  73. 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
  74. 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
  75. 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
  76. 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
  77. 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
  78. 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
  79. 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
  80. 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
  81. 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
  82. 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
  83. 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
  84. 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
  85. 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
  86. 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
  87. 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
  88. 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
  89. 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
  90. 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
  91. 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
  92. 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
  93. 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
  94. 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
  95. 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
  96. };
  97. void 
  98. NETjet_WriteICfifo(struct IsdnCardState *cs, u_char *data, int size)
  99. {
  100. cs->hw.njet.auxd &= 0xfc;
  101. byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
  102. outsb(cs->hw.njet.isac, data, size);
  103. }
  104. void fill_mem(struct BCState *bcs, u_int *pos, u_int cnt, int chan, u_char fill)
  105. {
  106. u_int mask=0x000000ff, val = 0, *p=pos;
  107. u_int i;
  108. val |= fill;
  109. if (chan) {
  110. val  <<= 8;
  111. mask <<= 8;
  112. }
  113. mask ^= 0xffffffff;
  114. for (i=0; i<cnt; i++) {
  115. *p   &= mask;
  116. *p++ |= val;
  117. if (p > bcs->hw.tiger.s_end)
  118. p = bcs->hw.tiger.send;
  119. }
  120. }
  121. void
  122. mode_tiger(struct BCState *bcs, int mode, int bc)
  123. {
  124. struct IsdnCardState *cs = bcs->cs;
  125.         u_char led;
  126. if (cs->debug & L1_DEB_HSCX)
  127. debugl1(cs, "Tiger mode %d bchan %d/%d",
  128. mode, bc, bcs->channel);
  129. bcs->mode = mode;
  130. bcs->channel = bc;
  131. switch (mode) {
  132. case (L1_MODE_NULL):
  133. fill_mem(bcs, bcs->hw.tiger.send,
  134. NETJET_DMA_TXSIZE, bc, 0xff);
  135. if (cs->debug & L1_DEB_HSCX)
  136. debugl1(cs, "Tiger stat rec %d/%d send %d",
  137. bcs->hw.tiger.r_tot, bcs->hw.tiger.r_err,
  138. bcs->hw.tiger.s_tot); 
  139. if ((cs->bcs[0].mode == L1_MODE_NULL) &&
  140. (cs->bcs[1].mode == L1_MODE_NULL)) {
  141. cs->hw.njet.dmactrl = 0;
  142. byteout(cs->hw.njet.base + NETJET_DMACTRL,
  143. cs->hw.njet.dmactrl);
  144. byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0);
  145. }
  146.                         if (cs->typ == ISDN_CTYPE_NETJET_S)
  147.                         {
  148.                                 // led off
  149.                                 led = bc & 0x01;
  150.                                 led = 0x01 << (6 + led); // convert to mask
  151.                                 led = ~led;
  152.                                 cs->hw.njet.auxd &= led;
  153.                                 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
  154.                         }
  155. break;
  156. case (L1_MODE_TRANS):
  157. break;
  158. case (L1_MODE_HDLC_56K):
  159. case (L1_MODE_HDLC):
  160. fill_mem(bcs, bcs->hw.tiger.send,
  161. NETJET_DMA_TXSIZE, bc, 0xff);
  162. bcs->hw.tiger.r_state = HDLC_ZERO_SEARCH;
  163. bcs->hw.tiger.r_tot = 0;
  164. bcs->hw.tiger.r_bitcnt = 0;
  165. bcs->hw.tiger.r_one = 0;
  166. bcs->hw.tiger.r_err = 0;
  167. bcs->hw.tiger.s_tot = 0;
  168. if (! cs->hw.njet.dmactrl) {
  169. fill_mem(bcs, bcs->hw.tiger.send,
  170. NETJET_DMA_TXSIZE, !bc, 0xff);
  171. cs->hw.njet.dmactrl = 1;
  172. byteout(cs->hw.njet.base + NETJET_DMACTRL,
  173. cs->hw.njet.dmactrl);
  174. byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0x0f);
  175. /* was 0x3f now 0x0f for TJ300 and TJ320  GE 13/07/00 */
  176. }
  177. bcs->hw.tiger.sendp = bcs->hw.tiger.send;
  178. bcs->hw.tiger.free = NETJET_DMA_TXSIZE;
  179. test_and_set_bit(BC_FLG_EMPTY, &bcs->Flag);
  180.                         if (cs->typ == ISDN_CTYPE_NETJET_S)
  181.                         {
  182.                                 // led on
  183.                                 led = bc & 0x01;
  184.                                 led = 0x01 << (6 + led); // convert to mask
  185.                                 cs->hw.njet.auxd |= led;
  186.                                 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
  187.                         }
  188. break;
  189. }
  190. if (cs->debug & L1_DEB_HSCX)
  191. debugl1(cs, "tiger: set %x %x %x  %x/%x  pulse=%d",
  192. bytein(cs->hw.njet.base + NETJET_DMACTRL),
  193. bytein(cs->hw.njet.base + NETJET_IRQMASK0),
  194. bytein(cs->hw.njet.base + NETJET_IRQSTAT0),
  195. inl(cs->hw.njet.base + NETJET_DMA_READ_ADR),
  196. inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR),
  197. bytein(cs->hw.njet.base + NETJET_PULSE_CNT));
  198. }
  199. static void printframe(struct IsdnCardState *cs, u_char *buf, int count, char *s) {
  200. char tmp[128];
  201. char *t = tmp;
  202. int i=count,j;
  203. u_char *p = buf;
  204. t += sprintf(t, "tiger %s(%4d)", s, count);
  205. while (i>0) {
  206. if (i>16)
  207. j=16;
  208. else
  209. j=i;
  210. QuickHex(t, p, j);
  211. debugl1(cs, tmp);
  212. p += j;
  213. i -= j;
  214. t = tmp;
  215. t += sprintf(t, "tiger %s      ", s);
  216. }
  217. }
  218. // macro for 64k
  219. #define MAKE_RAW_BYTE for (j=0; j<8; j++) { 
  220. bitcnt++;
  221. s_val >>= 1;
  222. if (val & 1) {
  223. s_one++;
  224. s_val |= 0x80;
  225. } else {
  226. s_one = 0;
  227. s_val &= 0x7f;
  228. }
  229. if (bitcnt==8) {
  230. bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
  231. bitcnt = 0;
  232. }
  233. if (s_one == 5) {
  234. s_val >>= 1;
  235. s_val &= 0x7f;
  236. bitcnt++;
  237. s_one = 0;
  238. }
  239. if (bitcnt==8) {
  240. bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
  241. bitcnt = 0;
  242. }
  243. val >>= 1;
  244. }
  245. static int make_raw_data(struct BCState *bcs) {
  246. // this make_raw is for 64k
  247. register u_int i,s_cnt=0;
  248. register u_char j;
  249. register u_char val;
  250. register u_char s_one = 0;
  251. register u_char s_val = 0;
  252. register u_char bitcnt = 0;
  253. u_int fcs;
  254. if (!bcs->tx_skb) {
  255. debugl1(bcs->cs, "tiger make_raw: NULL skb");
  256. return(1);
  257. }
  258. bcs->hw.tiger.sendbuf[s_cnt++] = HDLC_FLAG_VALUE;
  259. fcs = PPP_INITFCS;
  260. for (i=0; i<bcs->tx_skb->len; i++) {
  261. val = bcs->tx_skb->data[i];
  262. fcs = PPP_FCS (fcs, val);
  263. MAKE_RAW_BYTE;
  264. }
  265. fcs ^= 0xffff;
  266. val = fcs & 0xff;
  267. MAKE_RAW_BYTE;
  268. val = (fcs>>8) & 0xff;
  269. MAKE_RAW_BYTE;
  270. val = HDLC_FLAG_VALUE;
  271. for (j=0; j<8; j++) { 
  272. bitcnt++;
  273. s_val >>= 1;
  274. if (val & 1)
  275. s_val |= 0x80;
  276. else
  277. s_val &= 0x7f;
  278. if (bitcnt==8) {
  279. bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
  280. bitcnt = 0;
  281. }
  282. val >>= 1;
  283. }
  284. if (bcs->cs->debug & L1_DEB_HSCX)
  285. debugl1(bcs->cs,"tiger make_raw: in %ld out %d.%d",
  286. bcs->tx_skb->len, s_cnt, bitcnt);
  287. if (bitcnt) {
  288. while (8>bitcnt++) {
  289. s_val >>= 1;
  290. s_val |= 0x80;
  291. }
  292. bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
  293. bcs->hw.tiger.sendbuf[s_cnt++] = 0xff; // NJ<->NJ thoughput bug fix
  294. }
  295. bcs->hw.tiger.sendcnt = s_cnt;
  296. bcs->tx_cnt -= bcs->tx_skb->len;
  297. bcs->hw.tiger.sp = bcs->hw.tiger.sendbuf;
  298. return(0);
  299. }
  300. // macro for 56k
  301. #define MAKE_RAW_BYTE_56K for (j=0; j<8; j++) { 
  302. bitcnt++;
  303. s_val >>= 1;
  304. if (val & 1) {
  305. s_one++;
  306. s_val |= 0x80;
  307. } else {
  308. s_one = 0;
  309. s_val &= 0x7f;
  310. }
  311. if (bitcnt==7) {
  312. s_val >>= 1;
  313. s_val |= 0x80;
  314. bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
  315. bitcnt = 0;
  316. }
  317. if (s_one == 5) {
  318. s_val >>= 1;
  319. s_val &= 0x7f;
  320. bitcnt++;
  321. s_one = 0;
  322. }
  323. if (bitcnt==7) {
  324. s_val >>= 1;
  325. s_val |= 0x80;
  326. bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
  327. bitcnt = 0;
  328. }
  329. val >>= 1;
  330. }
  331. static int make_raw_data_56k(struct BCState *bcs) {
  332. // this make_raw is for 56k
  333. register u_int i,s_cnt=0;
  334. register u_char j;
  335. register u_char val;
  336. register u_char s_one = 0;
  337. register u_char s_val = 0;
  338. register u_char bitcnt = 0;
  339. u_int fcs;
  340. if (!bcs->tx_skb) {
  341. debugl1(bcs->cs, "tiger make_raw_56k: NULL skb");
  342. return(1);
  343. }
  344. val = HDLC_FLAG_VALUE;
  345. for (j=0; j<8; j++) { 
  346. bitcnt++;
  347. s_val >>= 1;
  348. if (val & 1)
  349. s_val |= 0x80;
  350. else
  351. s_val &= 0x7f;
  352. if (bitcnt==7) {
  353. s_val >>= 1;
  354. s_val |= 0x80;
  355. bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
  356. bitcnt = 0;
  357. }
  358. val >>= 1;
  359. };
  360. fcs = PPP_INITFCS;
  361. for (i=0; i<bcs->tx_skb->len; i++) {
  362. val = bcs->tx_skb->data[i];
  363. fcs = PPP_FCS (fcs, val);
  364. MAKE_RAW_BYTE_56K;
  365. }
  366. fcs ^= 0xffff;
  367. val = fcs & 0xff;
  368. MAKE_RAW_BYTE_56K;
  369. val = (fcs>>8) & 0xff;
  370. MAKE_RAW_BYTE_56K;
  371. val = HDLC_FLAG_VALUE;
  372. for (j=0; j<8; j++) { 
  373. bitcnt++;
  374. s_val >>= 1;
  375. if (val & 1)
  376. s_val |= 0x80;
  377. else
  378. s_val &= 0x7f;
  379. if (bitcnt==7) {
  380. s_val >>= 1;
  381. s_val |= 0x80;
  382. bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
  383. bitcnt = 0;
  384. }
  385. val >>= 1;
  386. }
  387. if (bcs->cs->debug & L1_DEB_HSCX)
  388. debugl1(bcs->cs,"tiger make_raw_56k: in %ld out %d.%d",
  389. bcs->tx_skb->len, s_cnt, bitcnt);
  390. if (bitcnt) {
  391. while (8>bitcnt++) {
  392. s_val >>= 1;
  393. s_val |= 0x80;
  394. }
  395. bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
  396. bcs->hw.tiger.sendbuf[s_cnt++] = 0xff; // NJ<->NJ thoughput bug fix
  397. }
  398. bcs->hw.tiger.sendcnt = s_cnt;
  399. bcs->tx_cnt -= bcs->tx_skb->len;
  400. bcs->hw.tiger.sp = bcs->hw.tiger.sendbuf;
  401. return(0);
  402. }
  403. static void got_frame(struct BCState *bcs, int count) {
  404. struct sk_buff *skb;
  405. if (!(skb = dev_alloc_skb(count)))
  406. printk(KERN_WARNING "TIGER: receive out of memoryn");
  407. else {
  408. memcpy(skb_put(skb, count), bcs->hw.tiger.rcvbuf, count);
  409. skb_queue_tail(&bcs->rqueue, skb);
  410. }
  411. bcs->event |= 1 << B_RCVBUFREADY;
  412. queue_task(&bcs->tqueue, &tq_immediate);
  413. mark_bh(IMMEDIATE_BH);
  414. if (bcs->cs->debug & L1_DEB_RECEIVE_FRAME)
  415. printframe(bcs->cs, bcs->hw.tiger.rcvbuf, count, "rec");
  416. }
  417. static void read_raw(struct BCState *bcs, u_int *buf, int cnt){
  418. int i;
  419. register u_char j;
  420. register u_char val;
  421. u_int  *pend = bcs->hw.tiger.rec +NETJET_DMA_RXSIZE -1;
  422. register u_char state = bcs->hw.tiger.r_state;
  423. register u_char r_one = bcs->hw.tiger.r_one;
  424. register u_char r_val = bcs->hw.tiger.r_val;
  425. register u_int bitcnt = bcs->hw.tiger.r_bitcnt;
  426. u_int *p = buf;
  427. int bits;
  428. u_char mask;
  429.         if (bcs->mode == L1_MODE_HDLC) { // it's 64k
  430. mask = 0xff;
  431. bits = 8;
  432. }
  433. else { // it's 56K
  434. mask = 0x7f;
  435. bits = 7;
  436. };
  437. for (i=0;i<cnt;i++) {
  438. val = bcs->channel ? ((*p>>8) & 0xff) : (*p & 0xff);
  439. p++;
  440. if (p > pend)
  441. p = bcs->hw.tiger.rec;
  442. if ((val & mask) == mask) {
  443. state = HDLC_ZERO_SEARCH;
  444. bcs->hw.tiger.r_tot++;
  445. bitcnt = 0;
  446. r_one = 0;
  447. continue;
  448. }
  449. for (j=0;j<bits;j++) {
  450. if (state == HDLC_ZERO_SEARCH) {
  451. if (val & 1) {
  452. r_one++;
  453. } else {
  454. r_one=0;
  455. state= HDLC_FLAG_SEARCH;
  456. if (bcs->cs->debug & L1_DEB_HSCX)
  457. debugl1(bcs->cs,"tiger read_raw: zBit(%d,%d,%d) %x",
  458. bcs->hw.tiger.r_tot,i,j,val);
  459. }
  460. } else if (state == HDLC_FLAG_SEARCH) { 
  461. if (val & 1) {
  462. r_one++;
  463. if (r_one>6) {
  464. state=HDLC_ZERO_SEARCH;
  465. }
  466. } else {
  467. if (r_one==6) {
  468. bitcnt=0;
  469. r_val=0;
  470. state=HDLC_FLAG_FOUND;
  471. if (bcs->cs->debug & L1_DEB_HSCX)
  472. debugl1(bcs->cs,"tiger read_raw: flag(%d,%d,%d) %x",
  473. bcs->hw.tiger.r_tot,i,j,val);
  474. }
  475. r_one=0;
  476. }
  477. } else if (state ==  HDLC_FLAG_FOUND) {
  478. if (val & 1) {
  479. r_one++;
  480. if (r_one>6) {
  481. state=HDLC_ZERO_SEARCH;
  482. } else {
  483. r_val >>= 1;
  484. r_val |= 0x80;
  485. bitcnt++;
  486. }
  487. } else {
  488. if (r_one==6) {
  489. bitcnt=0;
  490. r_val=0;
  491. r_one=0;
  492. val >>= 1;
  493. continue;
  494. } else if (r_one!=5) {
  495. r_val >>= 1;
  496. r_val &= 0x7f;
  497. bitcnt++;
  498. }
  499. r_one=0;
  500. }
  501. if ((state != HDLC_ZERO_SEARCH) &&
  502. !(bitcnt & 7)) {
  503. state=HDLC_FRAME_FOUND;
  504. bcs->hw.tiger.r_fcs = PPP_INITFCS;
  505. bcs->hw.tiger.rcvbuf[0] = r_val;
  506. bcs->hw.tiger.r_fcs = PPP_FCS (bcs->hw.tiger.r_fcs, r_val);
  507. if (bcs->cs->debug & L1_DEB_HSCX)
  508. debugl1(bcs->cs,"tiger read_raw: byte1(%d,%d,%d) rval %x val %x i %x",
  509. bcs->hw.tiger.r_tot,i,j,r_val,val,
  510. bcs->cs->hw.njet.irqstat0);
  511. }
  512. } else if (state ==  HDLC_FRAME_FOUND) {
  513. if (val & 1) {
  514. r_one++;
  515. if (r_one>6) {
  516. state=HDLC_ZERO_SEARCH;
  517. bitcnt=0;
  518. } else {
  519. r_val >>= 1;
  520. r_val |= 0x80;
  521. bitcnt++;
  522. }
  523. } else {
  524. if (r_one==6) {
  525. r_val=0; 
  526. r_one=0;
  527. bitcnt++;
  528. if (bitcnt & 7) {
  529. debugl1(bcs->cs, "tiger: frame not byte aligned");
  530. state=HDLC_FLAG_SEARCH;
  531. bcs->hw.tiger.r_err++;
  532. #ifdef ERROR_STATISTIC
  533. bcs->err_inv++;
  534. #endif
  535. } else {
  536. if (bcs->cs->debug & L1_DEB_HSCX)
  537. debugl1(bcs->cs,"tiger frame end(%d,%d): fcs(%x) i %x",
  538. i,j,bcs->hw.tiger.r_fcs, bcs->cs->hw.njet.irqstat0);
  539. if (bcs->hw.tiger.r_fcs == PPP_GOODFCS) {
  540. got_frame(bcs, (bitcnt>>3)-3);
  541. } else {
  542. if (bcs->cs->debug) {
  543. debugl1(bcs->cs, "tiger FCS error");
  544. printframe(bcs->cs, bcs->hw.tiger.rcvbuf,
  545. (bitcnt>>3)-1, "rec");
  546. bcs->hw.tiger.r_err++;
  547. }
  548. #ifdef ERROR_STATISTIC
  549. bcs->err_crc++;
  550. #endif
  551. }
  552. state=HDLC_FLAG_FOUND;
  553. }
  554. bitcnt=0;
  555. } else if (r_one==5) {
  556. val >>= 1;
  557. r_one=0;
  558. continue;
  559. } else {
  560. r_val >>= 1;
  561. r_val &= 0x7f;
  562. bitcnt++;
  563. }
  564. r_one=0;
  565. }
  566. if ((state == HDLC_FRAME_FOUND) &&
  567. !(bitcnt & 7)) {
  568. if ((bitcnt>>3)>=HSCX_BUFMAX) {
  569. debugl1(bcs->cs, "tiger: frame too big");
  570. r_val=0; 
  571. state=HDLC_FLAG_SEARCH;
  572. bcs->hw.tiger.r_err++;
  573. #ifdef ERROR_STATISTIC
  574. bcs->err_inv++;
  575. #endif
  576. } else {
  577. bcs->hw.tiger.rcvbuf[(bitcnt>>3)-1] = r_val;
  578. bcs->hw.tiger.r_fcs = 
  579. PPP_FCS (bcs->hw.tiger.r_fcs, r_val);
  580. }
  581. }
  582. }
  583. val >>= 1;
  584. }
  585. bcs->hw.tiger.r_tot++;
  586. }
  587. bcs->hw.tiger.r_state = state;
  588. bcs->hw.tiger.r_one = r_one;
  589. bcs->hw.tiger.r_val = r_val;
  590. bcs->hw.tiger.r_bitcnt = bitcnt;
  591. }
  592. void read_tiger(struct IsdnCardState *cs) {
  593. u_int *p;
  594. int cnt = NETJET_DMA_RXSIZE/2;
  595. if ((cs->hw.njet.irqstat0 & cs->hw.njet.last_is0) & NETJET_IRQM0_READ) {
  596. debugl1(cs,"tiger warn read double dma %x/%x",
  597. cs->hw.njet.irqstat0, cs->hw.njet.last_is0);
  598. #ifdef ERROR_STATISTIC
  599. if (cs->bcs[0].mode)
  600. cs->bcs[0].err_rdo++;
  601. if (cs->bcs[1].mode)
  602. cs->bcs[1].err_rdo++;
  603. #endif
  604. return;
  605. } else {
  606. cs->hw.njet.last_is0 &= ~NETJET_IRQM0_READ;
  607. cs->hw.njet.last_is0 |= (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ);
  608. }
  609. if (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ_1)
  610. p = cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1;
  611. else
  612. p = cs->bcs[0].hw.tiger.rec + cnt - 1;
  613. if ((cs->bcs[0].mode == L1_MODE_HDLC) || (cs->bcs[0].mode == L1_MODE_HDLC_56K))
  614. read_raw(cs->bcs, p, cnt);
  615. if ((cs->bcs[1].mode == L1_MODE_HDLC) || (cs->bcs[1].mode == L1_MODE_HDLC_56K))
  616. read_raw(cs->bcs + 1, p, cnt);
  617. cs->hw.njet.irqstat0 &= ~NETJET_IRQM0_READ;
  618. }
  619. static void write_raw(struct BCState *bcs, u_int *buf, int cnt);
  620. void netjet_fill_dma(struct BCState *bcs)
  621. {
  622. register u_int *p, *sp;
  623. register int cnt;
  624. if (!bcs->tx_skb)
  625. return;
  626. if (bcs->cs->debug & L1_DEB_HSCX)
  627. debugl1(bcs->cs,"tiger fill_dma1: c%d %4x", bcs->channel,
  628. bcs->Flag);
  629. if (test_and_set_bit(BC_FLG_BUSY, &bcs->Flag))
  630. return;
  631. if (bcs->mode == L1_MODE_HDLC) { // it's 64k
  632. if (make_raw_data(bcs))
  633. return;
  634. }
  635. else { // it's 56k
  636. if (make_raw_data_56k(bcs))
  637. return;
  638. };
  639. if (bcs->cs->debug & L1_DEB_HSCX)
  640. debugl1(bcs->cs,"tiger fill_dma2: c%d %4x", bcs->channel,
  641. bcs->Flag);
  642. if (test_and_clear_bit(BC_FLG_NOFRAME, &bcs->Flag)) {
  643. write_raw(bcs, bcs->hw.tiger.sendp, bcs->hw.tiger.free);
  644. } else if (test_and_clear_bit(BC_FLG_HALF, &bcs->Flag)) {
  645. p = bus_to_virt(inl(bcs->cs->hw.njet.base + NETJET_DMA_READ_ADR));
  646. sp = bcs->hw.tiger.sendp;
  647. if (p == bcs->hw.tiger.s_end)
  648. p = bcs->hw.tiger.send -1;
  649. if (sp == bcs->hw.tiger.s_end)
  650. sp = bcs->hw.tiger.send -1;
  651. cnt = p - sp;
  652. if (cnt <0) {
  653. write_raw(bcs, bcs->hw.tiger.sendp, bcs->hw.tiger.free);
  654. } else {
  655. p++;
  656. cnt++;
  657. if (p > bcs->hw.tiger.s_end)
  658. p = bcs->hw.tiger.send;
  659. p++;
  660. cnt++;
  661. if (p > bcs->hw.tiger.s_end)
  662. p = bcs->hw.tiger.send;
  663. write_raw(bcs, p, bcs->hw.tiger.free - cnt);
  664. }
  665. } else if (test_and_clear_bit(BC_FLG_EMPTY, &bcs->Flag)) {
  666. p = bus_to_virt(inl(bcs->cs->hw.njet.base + NETJET_DMA_READ_ADR));
  667. cnt = bcs->hw.tiger.s_end - p;
  668. if (cnt < 2) {
  669. p = bcs->hw.tiger.send + 1;
  670. cnt = NETJET_DMA_TXSIZE/2 - 2;
  671. } else {
  672. p++;
  673. p++;
  674. if (cnt <= (NETJET_DMA_TXSIZE/2))
  675. cnt += NETJET_DMA_TXSIZE/2;
  676. cnt--;
  677. cnt--;
  678. }
  679. write_raw(bcs, p, cnt);
  680. }
  681. if (bcs->cs->debug & L1_DEB_HSCX)
  682. debugl1(bcs->cs,"tiger fill_dma3: c%d %4x", bcs->channel,
  683. bcs->Flag);
  684. }
  685. static void write_raw(struct BCState *bcs, u_int *buf, int cnt) {
  686. u_int mask, val, *p=buf;
  687. u_int i, s_cnt;
  688.         
  689.         if (cnt <= 0)
  690.          return;
  691. if (test_bit(BC_FLG_BUSY, &bcs->Flag)) {
  692. if (bcs->hw.tiger.sendcnt> cnt) {
  693. s_cnt = cnt;
  694. bcs->hw.tiger.sendcnt -= cnt;
  695. } else {
  696. s_cnt = bcs->hw.tiger.sendcnt;
  697. bcs->hw.tiger.sendcnt = 0;
  698. }
  699. if (bcs->channel)
  700. mask = 0xffff00ff;
  701. else
  702. mask = 0xffffff00;
  703. for (i=0; i<s_cnt; i++) {
  704. val = bcs->channel ? ((bcs->hw.tiger.sp[i] <<8) & 0xff00) :
  705. (bcs->hw.tiger.sp[i]);
  706. *p   &= mask;
  707. *p++ |= val;
  708. if (p>bcs->hw.tiger.s_end)
  709. p = bcs->hw.tiger.send;
  710. }
  711. bcs->hw.tiger.s_tot += s_cnt;
  712. if (bcs->cs->debug & L1_DEB_HSCX)
  713. debugl1(bcs->cs,"tiger write_raw: c%d %x-%x %d/%d %d %x", bcs->channel,
  714. (u_int)buf, (u_int)p, s_cnt, cnt,
  715. bcs->hw.tiger.sendcnt, bcs->cs->hw.njet.irqstat0);
  716. if (bcs->cs->debug & L1_DEB_HSCX_FIFO)
  717. printframe(bcs->cs, bcs->hw.tiger.sp, s_cnt, "snd");
  718. bcs->hw.tiger.sp += s_cnt;
  719. bcs->hw.tiger.sendp = p;
  720. if (!bcs->hw.tiger.sendcnt) {
  721. if (!bcs->tx_skb) {
  722. debugl1(bcs->cs,"tiger write_raw: NULL skb s_cnt %d", s_cnt);
  723. } else {
  724. if (bcs->st->lli.l1writewakeup &&
  725. (PACKET_NOACK != bcs->tx_skb->pkt_type))
  726. bcs->st->lli.l1writewakeup(bcs->st, bcs->tx_skb->len);
  727. dev_kfree_skb_any(bcs->tx_skb);
  728. bcs->tx_skb = NULL;
  729. }
  730. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  731. bcs->hw.tiger.free = cnt - s_cnt;
  732. if (bcs->hw.tiger.free > (NETJET_DMA_TXSIZE/2))
  733. test_and_set_bit(BC_FLG_HALF, &bcs->Flag);
  734. else {
  735. test_and_clear_bit(BC_FLG_HALF, &bcs->Flag);
  736. test_and_set_bit(BC_FLG_NOFRAME, &bcs->Flag);
  737. }
  738. if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
  739. netjet_fill_dma(bcs);
  740. } else {
  741. mask ^= 0xffffffff;
  742. if (s_cnt < cnt) {
  743. for (i=s_cnt; i<cnt;i++) {
  744. *p++ |= mask;
  745. if (p>bcs->hw.tiger.s_end)
  746. p = bcs->hw.tiger.send;
  747. }
  748. if (bcs->cs->debug & L1_DEB_HSCX)
  749. debugl1(bcs->cs, "tiger write_raw: fill rest %d",
  750. cnt - s_cnt);
  751. }
  752. bcs->event |= 1 << B_XMTBUFREADY;
  753. queue_task(&bcs->tqueue, &tq_immediate);
  754. mark_bh(IMMEDIATE_BH);
  755. }
  756. }
  757. } else if (test_and_clear_bit(BC_FLG_NOFRAME, &bcs->Flag)) {
  758. test_and_set_bit(BC_FLG_HALF, &bcs->Flag);
  759. fill_mem(bcs, buf, cnt, bcs->channel, 0xff);
  760. bcs->hw.tiger.free += cnt;
  761. if (bcs->cs->debug & L1_DEB_HSCX)
  762. debugl1(bcs->cs,"tiger write_raw: fill half");
  763. } else if (test_and_clear_bit(BC_FLG_HALF, &bcs->Flag)) {
  764. test_and_set_bit(BC_FLG_EMPTY, &bcs->Flag);
  765. fill_mem(bcs, buf, cnt, bcs->channel, 0xff);
  766. if (bcs->cs->debug & L1_DEB_HSCX)
  767. debugl1(bcs->cs,"tiger write_raw: fill full");
  768. }
  769. }
  770. void write_tiger(struct IsdnCardState *cs) {
  771. u_int *p, cnt = NETJET_DMA_TXSIZE/2;
  772. if ((cs->hw.njet.irqstat0 & cs->hw.njet.last_is0) & NETJET_IRQM0_WRITE) {
  773. debugl1(cs,"tiger warn write double dma %x/%x",
  774. cs->hw.njet.irqstat0, cs->hw.njet.last_is0);
  775. #ifdef ERROR_STATISTIC
  776. if (cs->bcs[0].mode)
  777. cs->bcs[0].err_tx++;
  778. if (cs->bcs[1].mode)
  779. cs->bcs[1].err_tx++;
  780. #endif
  781. return;
  782. } else {
  783. cs->hw.njet.last_is0 &= ~NETJET_IRQM0_WRITE;
  784. cs->hw.njet.last_is0 |= (cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE);
  785. }
  786. if (cs->hw.njet.irqstat0  & NETJET_IRQM0_WRITE_1)
  787. p = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1;
  788. else
  789. p = cs->bcs[0].hw.tiger.send + cnt - 1;
  790. if ((cs->bcs[0].mode == L1_MODE_HDLC) || (cs->bcs[0].mode == L1_MODE_HDLC_56K))
  791. write_raw(cs->bcs, p, cnt);
  792. if ((cs->bcs[1].mode == L1_MODE_HDLC) || (cs->bcs[1].mode == L1_MODE_HDLC_56K))
  793. write_raw(cs->bcs + 1, p, cnt);
  794. cs->hw.njet.irqstat0 &= ~NETJET_IRQM0_WRITE;
  795. }
  796. static void
  797. tiger_l2l1(struct PStack *st, int pr, void *arg)
  798. {
  799. struct sk_buff *skb = arg;
  800. long flags;
  801. switch (pr) {
  802. case (PH_DATA | REQUEST):
  803. save_flags(flags);
  804. cli();
  805. if (st->l1.bcs->tx_skb) {
  806. skb_queue_tail(&st->l1.bcs->squeue, skb);
  807. restore_flags(flags);
  808. } else {
  809. st->l1.bcs->tx_skb = skb;
  810. st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
  811. restore_flags(flags);
  812. }
  813. break;
  814. case (PH_PULL | INDICATION):
  815. if (st->l1.bcs->tx_skb) {
  816. printk(KERN_WARNING "tiger_l2l1: this shouldn't happenn");
  817. break;
  818. }
  819. save_flags(flags);
  820. cli();
  821. st->l1.bcs->tx_skb = skb;
  822. st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
  823. restore_flags(flags);
  824. break;
  825. case (PH_PULL | REQUEST):
  826. if (!st->l1.bcs->tx_skb) {
  827. test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
  828. st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
  829. } else
  830. test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
  831. break;
  832. case (PH_ACTIVATE | REQUEST):
  833. test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
  834. mode_tiger(st->l1.bcs, st->l1.mode, st->l1.bc);
  835. /* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG */
  836. st->l1.bcs->cs->cardmsg(st->l1.bcs->cs, MDL_BC_ASSIGN, (void *)(&st->l1.bc));
  837. l1_msg_b(st, pr, arg);
  838. break;
  839. case (PH_DEACTIVATE | REQUEST):
  840. /* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG */
  841. st->l1.bcs->cs->cardmsg(st->l1.bcs->cs, MDL_BC_RELEASE, (void *)(&st->l1.bc));
  842. l1_msg_b(st, pr, arg);
  843. break;
  844. case (PH_DEACTIVATE | CONFIRM):
  845. test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
  846. test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
  847. mode_tiger(st->l1.bcs, 0, st->l1.bc);
  848. st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
  849. break;
  850. }
  851. }
  852. void
  853. close_tigerstate(struct BCState *bcs)
  854. {
  855. mode_tiger(bcs, 0, bcs->channel);
  856. if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
  857. if (bcs->hw.tiger.rcvbuf) {
  858. kfree(bcs->hw.tiger.rcvbuf);
  859. bcs->hw.tiger.rcvbuf = NULL;
  860. }
  861. if (bcs->hw.tiger.sendbuf) {
  862. kfree(bcs->hw.tiger.sendbuf);
  863. bcs->hw.tiger.sendbuf = NULL;
  864. }
  865. skb_queue_purge(&bcs->rqueue);
  866. skb_queue_purge(&bcs->squeue);
  867. if (bcs->tx_skb) {
  868. dev_kfree_skb_any(bcs->tx_skb);
  869. bcs->tx_skb = NULL;
  870. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  871. }
  872. }
  873. }
  874. static int
  875. open_tigerstate(struct IsdnCardState *cs, struct BCState *bcs)
  876. {
  877. if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
  878. if (!(bcs->hw.tiger.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
  879. printk(KERN_WARNING
  880.        "HiSax: No memory for tiger.rcvbufn");
  881. return (1);
  882. }
  883. if (!(bcs->hw.tiger.sendbuf = kmalloc(RAW_BUFMAX, GFP_ATOMIC))) {
  884. printk(KERN_WARNING
  885.        "HiSax: No memory for tiger.sendbufn");
  886. return (1);
  887. }
  888. skb_queue_head_init(&bcs->rqueue);
  889. skb_queue_head_init(&bcs->squeue);
  890. }
  891. bcs->tx_skb = NULL;
  892. bcs->hw.tiger.sendcnt = 0;
  893. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  894. bcs->event = 0;
  895. bcs->tx_cnt = 0;
  896. return (0);
  897. }
  898. int
  899. setstack_tiger(struct PStack *st, struct BCState *bcs)
  900. {
  901. bcs->channel = st->l1.bc;
  902. if (open_tigerstate(st->l1.hardware, bcs))
  903. return (-1);
  904. st->l1.bcs = bcs;
  905. st->l2.l2l1 = tiger_l2l1;
  906. setstack_manager(st);
  907. bcs->st = st;
  908. setstack_l1_B(st);
  909. return (0);
  910. }
  911.  
  912. void __init
  913. inittiger(struct IsdnCardState *cs)
  914. {
  915. if (!(cs->bcs[0].hw.tiger.send = kmalloc(NETJET_DMA_TXSIZE * sizeof(unsigned int),
  916. GFP_KERNEL | GFP_DMA))) {
  917. printk(KERN_WARNING
  918.        "HiSax: No memory for tiger.sendn");
  919. return;
  920. }
  921. cs->bcs[0].hw.tiger.s_irq = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE/2 - 1;
  922. cs->bcs[0].hw.tiger.s_end = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1;
  923. cs->bcs[1].hw.tiger.send = cs->bcs[0].hw.tiger.send;
  924. cs->bcs[1].hw.tiger.s_irq = cs->bcs[0].hw.tiger.s_irq;
  925. cs->bcs[1].hw.tiger.s_end = cs->bcs[0].hw.tiger.s_end;
  926. memset(cs->bcs[0].hw.tiger.send, 0xff, NETJET_DMA_TXSIZE * sizeof(unsigned int));
  927. debugl1(cs, "tiger: send buf %x - %x", (u_int)cs->bcs[0].hw.tiger.send,
  928. (u_int)(cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1));
  929. outl(virt_to_bus(cs->bcs[0].hw.tiger.send),
  930. cs->hw.njet.base + NETJET_DMA_READ_START);
  931. outl(virt_to_bus(cs->bcs[0].hw.tiger.s_irq),
  932. cs->hw.njet.base + NETJET_DMA_READ_IRQ);
  933. outl(virt_to_bus(cs->bcs[0].hw.tiger.s_end),
  934. cs->hw.njet.base + NETJET_DMA_READ_END);
  935. if (!(cs->bcs[0].hw.tiger.rec = kmalloc(NETJET_DMA_RXSIZE * sizeof(unsigned int),
  936. GFP_KERNEL | GFP_DMA))) {
  937. printk(KERN_WARNING
  938.        "HiSax: No memory for tiger.recn");
  939. return;
  940. }
  941. debugl1(cs, "tiger: rec buf %x - %x", (u_int)cs->bcs[0].hw.tiger.rec,
  942. (u_int)(cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1));
  943. cs->bcs[1].hw.tiger.rec = cs->bcs[0].hw.tiger.rec;
  944. memset(cs->bcs[0].hw.tiger.rec, 0xff, NETJET_DMA_RXSIZE * sizeof(unsigned int));
  945. outl(virt_to_bus(cs->bcs[0].hw.tiger.rec),
  946. cs->hw.njet.base + NETJET_DMA_WRITE_START);
  947. outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE/2 - 1),
  948. cs->hw.njet.base + NETJET_DMA_WRITE_IRQ);
  949. outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1),
  950. cs->hw.njet.base + NETJET_DMA_WRITE_END);
  951. debugl1(cs, "tiger: dmacfg  %x/%x  pulse=%d",
  952. inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR),
  953. inl(cs->hw.njet.base + NETJET_DMA_READ_ADR),
  954. bytein(cs->hw.njet.base + NETJET_PULSE_CNT));
  955. cs->hw.njet.last_is0 = 0;
  956. cs->bcs[0].BC_SetStack = setstack_tiger;
  957. cs->bcs[1].BC_SetStack = setstack_tiger;
  958. cs->bcs[0].BC_Close = close_tigerstate;
  959. cs->bcs[1].BC_Close = close_tigerstate;
  960. }
  961. void
  962. releasetiger(struct IsdnCardState *cs)
  963. {
  964. if (cs->bcs[0].hw.tiger.send) {
  965. kfree(cs->bcs[0].hw.tiger.send);
  966. cs->bcs[0].hw.tiger.send = NULL;
  967. }
  968. if (cs->bcs[1].hw.tiger.send) {
  969. cs->bcs[1].hw.tiger.send = NULL;
  970. }
  971. if (cs->bcs[0].hw.tiger.rec) {
  972. kfree(cs->bcs[0].hw.tiger.rec);
  973. cs->bcs[0].hw.tiger.rec = NULL;
  974. }
  975. if (cs->bcs[1].hw.tiger.rec) {
  976. cs->bcs[1].hw.tiger.rec = NULL;
  977. }
  978. }
  979. void
  980. release_io_netjet(struct IsdnCardState *cs)
  981. {
  982. byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0);
  983. byteout(cs->hw.njet.base + NETJET_IRQMASK1, 0);
  984. releasetiger(cs);
  985. release_region(cs->hw.njet.base, 256);
  986. }