avm_pci.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867
  1. /* $Id: avm_pci.c,v 1.29.2.4 2004/02/11 13:21:32 keil Exp $
  2. *
  3. * low level stuff for AVM Fritz!PCI and ISA PnP 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 AVM, Berlin for information
  12. *
  13. */
  14. #include <linux/config.h>
  15. #include <linux/init.h>
  16. #include "hisax.h"
  17. #include "isac.h"
  18. #include "isdnl1.h"
  19. #include <linux/pci.h>
  20. #include <linux/isapnp.h>
  21. #include <linux/interrupt.h>
  22. extern const char *CardType[];
  23. static const char *avm_pci_rev = "$Revision: 1.29.2.4 $";
  24. #define AVM_FRITZ_PCI 1
  25. #define AVM_FRITZ_PNP 2
  26. #define HDLC_FIFO 0x0
  27. #define HDLC_STATUS 0x4
  28. #define AVM_HDLC_1 0x00
  29. #define AVM_HDLC_2 0x01
  30. #define AVM_ISAC_FIFO 0x02
  31. #define AVM_ISAC_REG_LOW 0x04
  32. #define AVM_ISAC_REG_HIGH 0x06
  33. #define AVM_STATUS0_IRQ_ISAC 0x01
  34. #define AVM_STATUS0_IRQ_HDLC 0x02
  35. #define AVM_STATUS0_IRQ_TIMER 0x04
  36. #define AVM_STATUS0_IRQ_MASK 0x07
  37. #define AVM_STATUS0_RESET 0x01
  38. #define AVM_STATUS0_DIS_TIMER 0x02
  39. #define AVM_STATUS0_RES_TIMER 0x04
  40. #define AVM_STATUS0_ENA_IRQ 0x08
  41. #define AVM_STATUS0_TESTBIT 0x10
  42. #define AVM_STATUS1_INT_SEL 0x0f
  43. #define AVM_STATUS1_ENA_IOM 0x80
  44. #define HDLC_MODE_ITF_FLG 0x01
  45. #define HDLC_MODE_TRANS 0x02
  46. #define HDLC_MODE_CCR_7 0x04
  47. #define HDLC_MODE_CCR_16 0x08
  48. #define HDLC_MODE_TESTLOOP 0x80
  49. #define HDLC_INT_XPR 0x80
  50. #define HDLC_INT_XDU 0x40
  51. #define HDLC_INT_RPR 0x20
  52. #define HDLC_INT_MASK 0xE0
  53. #define HDLC_STAT_RME 0x01
  54. #define HDLC_STAT_RDO 0x10
  55. #define HDLC_STAT_CRCVFRRAB 0x0E
  56. #define HDLC_STAT_CRCVFR 0x06
  57. #define HDLC_STAT_RML_MASK 0x3f00
  58. #define HDLC_CMD_XRS 0x80
  59. #define HDLC_CMD_XME 0x01
  60. #define HDLC_CMD_RRS 0x20
  61. #define HDLC_CMD_XML_MASK 0x3f00
  62. /* Interface functions */
  63. static u_char
  64. ReadISAC(struct IsdnCardState *cs, u_char offset)
  65. {
  66. register u_char idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW;
  67. register u_char val;
  68. outb(idx, cs->hw.avm.cfg_reg + 4);
  69. val = inb(cs->hw.avm.isac + (offset & 0xf));
  70. return (val);
  71. }
  72. static void
  73. WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
  74. {
  75. register u_char idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW;
  76. outb(idx, cs->hw.avm.cfg_reg + 4);
  77. outb(value, cs->hw.avm.isac + (offset & 0xf));
  78. }
  79. static void
  80. ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
  81. {
  82. outb(AVM_ISAC_FIFO, cs->hw.avm.cfg_reg + 4);
  83. insb(cs->hw.avm.isac, data, size);
  84. }
  85. static void
  86. WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
  87. {
  88. outb(AVM_ISAC_FIFO, cs->hw.avm.cfg_reg + 4);
  89. outsb(cs->hw.avm.isac, data, size);
  90. }
  91. static inline u_int
  92. ReadHDLCPCI(struct IsdnCardState *cs, int chan, u_char offset)
  93. {
  94. register u_int idx = chan ? AVM_HDLC_2 : AVM_HDLC_1;
  95. register u_int val;
  96. outl(idx, cs->hw.avm.cfg_reg + 4);
  97. val = inl(cs->hw.avm.isac + offset);
  98. return (val);
  99. }
  100. static inline void
  101. WriteHDLCPCI(struct IsdnCardState *cs, int chan, u_char offset, u_int value)
  102. {
  103. register u_int idx = chan ? AVM_HDLC_2 : AVM_HDLC_1;
  104. outl(idx, cs->hw.avm.cfg_reg + 4);
  105. outl(value, cs->hw.avm.isac + offset);
  106. }
  107. static inline u_char
  108. ReadHDLCPnP(struct IsdnCardState *cs, int chan, u_char offset)
  109. {
  110. register u_char idx = chan ? AVM_HDLC_2 : AVM_HDLC_1;
  111. register u_char val;
  112. outb(idx, cs->hw.avm.cfg_reg + 4);
  113. val = inb(cs->hw.avm.isac + offset);
  114. return (val);
  115. }
  116. static inline void
  117. WriteHDLCPnP(struct IsdnCardState *cs, int chan, u_char offset, u_char value)
  118. {
  119. register u_char idx = chan ? AVM_HDLC_2 : AVM_HDLC_1;
  120. outb(idx, cs->hw.avm.cfg_reg + 4);
  121. outb(value, cs->hw.avm.isac + offset);
  122. }
  123. static u_char
  124. ReadHDLC_s(struct IsdnCardState *cs, int chan, u_char offset)
  125. {
  126. return(0xff & ReadHDLCPCI(cs, chan, offset));
  127. }
  128. static void
  129. WriteHDLC_s(struct IsdnCardState *cs, int chan, u_char offset, u_char value)
  130. {
  131. WriteHDLCPCI(cs, chan, offset, value);
  132. }
  133. static inline
  134. struct BCState *Sel_BCS(struct IsdnCardState *cs, int channel)
  135. {
  136. if (cs->bcs[0].mode && (cs->bcs[0].channel == channel))
  137. return(&cs->bcs[0]);
  138. else if (cs->bcs[1].mode && (cs->bcs[1].channel == channel))
  139. return(&cs->bcs[1]);
  140. else
  141. return(NULL);
  142. }
  143. static void
  144. write_ctrl(struct BCState *bcs, int which) {
  145. if (bcs->cs->debug & L1_DEB_HSCX)
  146. debugl1(bcs->cs, "hdlc %c wr%x ctrl %x",
  147. 'A' + bcs->channel, which, bcs->hw.hdlc.ctrl.ctrl);
  148. if (bcs->cs->subtyp == AVM_FRITZ_PCI) {
  149. WriteHDLCPCI(bcs->cs, bcs->channel, HDLC_STATUS, bcs->hw.hdlc.ctrl.ctrl);
  150. } else {
  151. if (which & 4)
  152. WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS + 2,
  153. bcs->hw.hdlc.ctrl.sr.mode);
  154. if (which & 2)
  155. WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS + 1,
  156. bcs->hw.hdlc.ctrl.sr.xml);
  157. if (which & 1)
  158. WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS,
  159. bcs->hw.hdlc.ctrl.sr.cmd);
  160. }
  161. }
  162. static void
  163. modehdlc(struct BCState *bcs, int mode, int bc)
  164. {
  165. struct IsdnCardState *cs = bcs->cs;
  166. int hdlc = bcs->channel;
  167. if (cs->debug & L1_DEB_HSCX)
  168. debugl1(cs, "hdlc %c mode %d --> %d ichan %d --> %d",
  169. 'A' + hdlc, bcs->mode, mode, hdlc, bc);
  170. bcs->hw.hdlc.ctrl.ctrl = 0;
  171. switch (mode) {
  172. case (-1): /* used for init */
  173. bcs->mode = 1;
  174. bcs->channel = bc;
  175. bc = 0;
  176. case (L1_MODE_NULL):
  177. if (bcs->mode == L1_MODE_NULL)
  178. return;
  179. bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS;
  180. bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_TRANS;
  181. write_ctrl(bcs, 5);
  182. bcs->mode = L1_MODE_NULL;
  183. bcs->channel = bc;
  184. break;
  185. case (L1_MODE_TRANS):
  186. bcs->mode = mode;
  187. bcs->channel = bc;
  188. bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS;
  189. bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_TRANS;
  190. write_ctrl(bcs, 5);
  191. bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS;
  192. write_ctrl(bcs, 1);
  193. bcs->hw.hdlc.ctrl.sr.cmd = 0;
  194. schedule_event(bcs, B_XMTBUFREADY);
  195. break;
  196. case (L1_MODE_HDLC):
  197. bcs->mode = mode;
  198. bcs->channel = bc;
  199. bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS;
  200. bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_ITF_FLG;
  201. write_ctrl(bcs, 5);
  202. bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS;
  203. write_ctrl(bcs, 1);
  204. bcs->hw.hdlc.ctrl.sr.cmd = 0;
  205. schedule_event(bcs, B_XMTBUFREADY);
  206. break;
  207. }
  208. }
  209. static inline void
  210. hdlc_empty_fifo(struct BCState *bcs, int count)
  211. {
  212. register u_int *ptr;
  213. u_char *p;
  214. u_char idx = bcs->channel ? AVM_HDLC_2 : AVM_HDLC_1;
  215. int cnt=0;
  216. struct IsdnCardState *cs = bcs->cs;
  217. if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
  218. debugl1(cs, "hdlc_empty_fifo %d", count);
  219. if (bcs->hw.hdlc.rcvidx + count > HSCX_BUFMAX) {
  220. if (cs->debug & L1_DEB_WARN)
  221. debugl1(cs, "hdlc_empty_fifo: incoming packet too large");
  222. return;
  223. }
  224. p = bcs->hw.hdlc.rcvbuf + bcs->hw.hdlc.rcvidx;
  225. ptr = (u_int *)p;
  226. bcs->hw.hdlc.rcvidx += count;
  227. if (cs->subtyp == AVM_FRITZ_PCI) {
  228. outl(idx, cs->hw.avm.cfg_reg + 4);
  229. while (cnt < count) {
  230. #ifdef __powerpc__
  231. #ifdef CONFIG_APUS
  232. *ptr++ = in_le32((unsigned *)(cs->hw.avm.isac +_IO_BASE));
  233. #else
  234. *ptr++ = in_be32((unsigned *)(cs->hw.avm.isac +_IO_BASE));
  235. #endif /* CONFIG_APUS */
  236. #else
  237. *ptr++ = inl(cs->hw.avm.isac);
  238. #endif /* __powerpc__ */
  239. cnt += 4;
  240. }
  241. } else {
  242. outb(idx, cs->hw.avm.cfg_reg + 4);
  243. while (cnt < count) {
  244. *p++ = inb(cs->hw.avm.isac);
  245. cnt++;
  246. }
  247. }
  248. if (cs->debug & L1_DEB_HSCX_FIFO) {
  249. char *t = bcs->blog;
  250. if (cs->subtyp == AVM_FRITZ_PNP)
  251. p = (u_char *) ptr;
  252. t += sprintf(t, "hdlc_empty_fifo %c cnt %d",
  253. bcs->channel ? 'B' : 'A', count);
  254. QuickHex(t, p, count);
  255. debugl1(cs, bcs->blog);
  256. }
  257. }
  258. static inline void
  259. hdlc_fill_fifo(struct BCState *bcs)
  260. {
  261. struct IsdnCardState *cs = bcs->cs;
  262. int count, cnt =0;
  263. int fifo_size = 32;
  264. u_char *p;
  265. u_int *ptr;
  266. if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
  267. debugl1(cs, "hdlc_fill_fifo");
  268. if (!bcs->tx_skb)
  269. return;
  270. if (bcs->tx_skb->len <= 0)
  271. return;
  272. bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_XME;
  273. if (bcs->tx_skb->len > fifo_size) {
  274. count = fifo_size;
  275. } else {
  276. count = bcs->tx_skb->len;
  277. if (bcs->mode != L1_MODE_TRANS)
  278. bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_XME;
  279. }
  280. if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
  281. debugl1(cs, "hdlc_fill_fifo %d/%ld", count, bcs->tx_skb->len);
  282. p = bcs->tx_skb->data;
  283. ptr = (u_int *)p;
  284. skb_pull(bcs->tx_skb, count);
  285. bcs->tx_cnt -= count;
  286. bcs->hw.hdlc.count += count;
  287. bcs->hw.hdlc.ctrl.sr.xml = ((count == fifo_size) ? 0 : count);
  288. write_ctrl(bcs, 3); /* sets the correct index too */
  289. if (cs->subtyp == AVM_FRITZ_PCI) {
  290. while (cnt<count) {
  291. #ifdef __powerpc__
  292. #ifdef CONFIG_APUS
  293. out_le32((unsigned *)(cs->hw.avm.isac +_IO_BASE), *ptr++);
  294. #else
  295. out_be32((unsigned *)(cs->hw.avm.isac +_IO_BASE), *ptr++);
  296. #endif /* CONFIG_APUS */
  297. #else
  298. outl(*ptr++, cs->hw.avm.isac);
  299. #endif /* __powerpc__ */
  300. cnt += 4;
  301. }
  302. } else {
  303. while (cnt<count) {
  304. outb(*p++, cs->hw.avm.isac);
  305. cnt++;
  306. }
  307. }
  308. if (cs->debug & L1_DEB_HSCX_FIFO) {
  309. char *t = bcs->blog;
  310. if (cs->subtyp == AVM_FRITZ_PNP)
  311. p = (u_char *) ptr;
  312. t += sprintf(t, "hdlc_fill_fifo %c cnt %d",
  313. bcs->channel ? 'B' : 'A', count);
  314. QuickHex(t, p, count);
  315. debugl1(cs, bcs->blog);
  316. }
  317. }
  318. static inline void
  319. HDLC_irq(struct BCState *bcs, u_int stat) {
  320. int len;
  321. struct sk_buff *skb;
  322. if (bcs->cs->debug & L1_DEB_HSCX)
  323. debugl1(bcs->cs, "ch%d stat %#x", bcs->channel, stat);
  324. if (stat & HDLC_INT_RPR) {
  325. if (stat & HDLC_STAT_RDO) {
  326. if (bcs->cs->debug & L1_DEB_HSCX)
  327. debugl1(bcs->cs, "RDO");
  328. else
  329. debugl1(bcs->cs, "ch%d stat %#x", bcs->channel, stat);
  330. bcs->hw.hdlc.ctrl.sr.xml = 0;
  331. bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_RRS;
  332. write_ctrl(bcs, 1);
  333. bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_RRS;
  334. write_ctrl(bcs, 1);
  335. bcs->hw.hdlc.rcvidx = 0;
  336. } else {
  337. if (!(len = (stat & HDLC_STAT_RML_MASK)>>8))
  338. len = 32;
  339. hdlc_empty_fifo(bcs, len);
  340. if ((stat & HDLC_STAT_RME) || (bcs->mode == L1_MODE_TRANS)) {
  341. if (((stat & HDLC_STAT_CRCVFRRAB)==HDLC_STAT_CRCVFR) ||
  342. (bcs->mode == L1_MODE_TRANS)) {
  343. if (!(skb = dev_alloc_skb(bcs->hw.hdlc.rcvidx)))
  344. printk(KERN_WARNING "HDLC: receive out of memory\n");
  345. else {
  346. memcpy(skb_put(skb, bcs->hw.hdlc.rcvidx),
  347. bcs->hw.hdlc.rcvbuf, bcs->hw.hdlc.rcvidx);
  348. skb_queue_tail(&bcs->rqueue, skb);
  349. }
  350. bcs->hw.hdlc.rcvidx = 0;
  351. schedule_event(bcs, B_RCVBUFREADY);
  352. } else {
  353. if (bcs->cs->debug & L1_DEB_HSCX)
  354. debugl1(bcs->cs, "invalid frame");
  355. else
  356. debugl1(bcs->cs, "ch%d invalid frame %#x", bcs->channel, stat);
  357. bcs->hw.hdlc.rcvidx = 0;
  358. }
  359. }
  360. }
  361. }
  362. if (stat & HDLC_INT_XDU) {
  363. /* Here we lost an TX interrupt, so
  364. * restart transmitting the whole frame.
  365. */
  366. if (bcs->tx_skb) {
  367. skb_push(bcs->tx_skb, bcs->hw.hdlc.count);
  368. bcs->tx_cnt += bcs->hw.hdlc.count;
  369. bcs->hw.hdlc.count = 0;
  370. if (bcs->cs->debug & L1_DEB_WARN)
  371. debugl1(bcs->cs, "ch%d XDU", bcs->channel);
  372. } else if (bcs->cs->debug & L1_DEB_WARN)
  373. debugl1(bcs->cs, "ch%d XDU without skb", bcs->channel);
  374. bcs->hw.hdlc.ctrl.sr.xml = 0;
  375. bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_XRS;
  376. write_ctrl(bcs, 1);
  377. bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_XRS;
  378. write_ctrl(bcs, 1);
  379. hdlc_fill_fifo(bcs);
  380. } else if (stat & HDLC_INT_XPR) {
  381. if (bcs->tx_skb) {
  382. if (bcs->tx_skb->len) {
  383. hdlc_fill_fifo(bcs);
  384. return;
  385. } else {
  386. if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
  387. (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
  388. u_long flags;
  389. spin_lock_irqsave(&bcs->aclock, flags);
  390. bcs->ackcnt += bcs->hw.hdlc.count;
  391. spin_unlock_irqrestore(&bcs->aclock, flags);
  392. schedule_event(bcs, B_ACKPENDING);
  393. }
  394. dev_kfree_skb_irq(bcs->tx_skb);
  395. bcs->hw.hdlc.count = 0;
  396. bcs->tx_skb = NULL;
  397. }
  398. }
  399. if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
  400. bcs->hw.hdlc.count = 0;
  401. test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
  402. hdlc_fill_fifo(bcs);
  403. } else {
  404. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  405. schedule_event(bcs, B_XMTBUFREADY);
  406. }
  407. }
  408. }
  409. static inline void
  410. HDLC_irq_main(struct IsdnCardState *cs)
  411. {
  412. u_int stat;
  413. struct BCState *bcs;
  414. if (cs->subtyp == AVM_FRITZ_PCI) {
  415. stat = ReadHDLCPCI(cs, 0, HDLC_STATUS);
  416. } else {
  417. stat = ReadHDLCPnP(cs, 0, HDLC_STATUS);
  418. if (stat & HDLC_INT_RPR)
  419. stat |= (ReadHDLCPnP(cs, 0, HDLC_STATUS+1))<<8;
  420. }
  421. if (stat & HDLC_INT_MASK) {
  422. if (!(bcs = Sel_BCS(cs, 0))) {
  423. if (cs->debug)
  424. debugl1(cs, "hdlc spurious channel 0 IRQ");
  425. } else
  426. HDLC_irq(bcs, stat);
  427. }
  428. if (cs->subtyp == AVM_FRITZ_PCI) {
  429. stat = ReadHDLCPCI(cs, 1, HDLC_STATUS);
  430. } else {
  431. stat = ReadHDLCPnP(cs, 1, HDLC_STATUS);
  432. if (stat & HDLC_INT_RPR)
  433. stat |= (ReadHDLCPnP(cs, 1, HDLC_STATUS+1))<<8;
  434. }
  435. if (stat & HDLC_INT_MASK) {
  436. if (!(bcs = Sel_BCS(cs, 1))) {
  437. if (cs->debug)
  438. debugl1(cs, "hdlc spurious channel 1 IRQ");
  439. } else
  440. HDLC_irq(bcs, stat);
  441. }
  442. }
  443. static void
  444. hdlc_l2l1(struct PStack *st, int pr, void *arg)
  445. {
  446. struct BCState *bcs = st->l1.bcs;
  447. struct sk_buff *skb = arg;
  448. u_long flags;
  449. switch (pr) {
  450. case (PH_DATA | REQUEST):
  451. spin_lock_irqsave(&bcs->cs->lock, flags);
  452. if (bcs->tx_skb) {
  453. skb_queue_tail(&bcs->squeue, skb);
  454. } else {
  455. bcs->tx_skb = skb;
  456. test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
  457. bcs->hw.hdlc.count = 0;
  458. bcs->cs->BC_Send_Data(bcs);
  459. }
  460. spin_unlock_irqrestore(&bcs->cs->lock, flags);
  461. break;
  462. case (PH_PULL | INDICATION):
  463. spin_lock_irqsave(&bcs->cs->lock, flags);
  464. if (bcs->tx_skb) {
  465. printk(KERN_WARNING "hdlc_l2l1: this shouldn't happen\n");
  466. } else {
  467. test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
  468. bcs->tx_skb = skb;
  469. bcs->hw.hdlc.count = 0;
  470. bcs->cs->BC_Send_Data(bcs);
  471. }
  472. spin_unlock_irqrestore(&bcs->cs->lock, flags);
  473. break;
  474. case (PH_PULL | REQUEST):
  475. if (!bcs->tx_skb) {
  476. test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
  477. st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
  478. } else
  479. test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
  480. break;
  481. case (PH_ACTIVATE | REQUEST):
  482. spin_lock_irqsave(&bcs->cs->lock, flags);
  483. test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
  484. modehdlc(bcs, st->l1.mode, st->l1.bc);
  485. spin_unlock_irqrestore(&bcs->cs->lock, flags);
  486. l1_msg_b(st, pr, arg);
  487. break;
  488. case (PH_DEACTIVATE | REQUEST):
  489. l1_msg_b(st, pr, arg);
  490. break;
  491. case (PH_DEACTIVATE | CONFIRM):
  492. spin_lock_irqsave(&bcs->cs->lock, flags);
  493. test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
  494. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  495. modehdlc(bcs, 0, st->l1.bc);
  496. spin_unlock_irqrestore(&bcs->cs->lock, flags);
  497. st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
  498. break;
  499. }
  500. }
  501. static void
  502. close_hdlcstate(struct BCState *bcs)
  503. {
  504. modehdlc(bcs, 0, 0);
  505. if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
  506. if (bcs->hw.hdlc.rcvbuf) {
  507. kfree(bcs->hw.hdlc.rcvbuf);
  508. bcs->hw.hdlc.rcvbuf = NULL;
  509. }
  510. if (bcs->blog) {
  511. kfree(bcs->blog);
  512. bcs->blog = NULL;
  513. }
  514. skb_queue_purge(&bcs->rqueue);
  515. skb_queue_purge(&bcs->squeue);
  516. if (bcs->tx_skb) {
  517. dev_kfree_skb_any(bcs->tx_skb);
  518. bcs->tx_skb = NULL;
  519. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  520. }
  521. }
  522. }
  523. static int
  524. open_hdlcstate(struct IsdnCardState *cs, struct BCState *bcs)
  525. {
  526. if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
  527. if (!(bcs->hw.hdlc.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
  528. printk(KERN_WARNING
  529. "HiSax: No memory for hdlc.rcvbuf\n");
  530. return (1);
  531. }
  532. if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
  533. printk(KERN_WARNING
  534. "HiSax: No memory for bcs->blog\n");
  535. test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
  536. kfree(bcs->hw.hdlc.rcvbuf);
  537. bcs->hw.hdlc.rcvbuf = NULL;
  538. return (2);
  539. }
  540. skb_queue_head_init(&bcs->rqueue);
  541. skb_queue_head_init(&bcs->squeue);
  542. }
  543. bcs->tx_skb = NULL;
  544. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  545. bcs->event = 0;
  546. bcs->hw.hdlc.rcvidx = 0;
  547. bcs->tx_cnt = 0;
  548. return (0);
  549. }
  550. static int
  551. setstack_hdlc(struct PStack *st, struct BCState *bcs)
  552. {
  553. bcs->channel = st->l1.bc;
  554. if (open_hdlcstate(st->l1.hardware, bcs))
  555. return (-1);
  556. st->l1.bcs = bcs;
  557. st->l2.l2l1 = hdlc_l2l1;
  558. setstack_manager(st);
  559. bcs->st = st;
  560. setstack_l1_B(st);
  561. return (0);
  562. }
  563. #if 0
  564. void __init
  565. clear_pending_hdlc_ints(struct IsdnCardState *cs)
  566. {
  567. u_int val;
  568. if (cs->subtyp == AVM_FRITZ_PCI) {
  569. val = ReadHDLCPCI(cs, 0, HDLC_STATUS);
  570. debugl1(cs, "HDLC 1 STA %x", val);
  571. val = ReadHDLCPCI(cs, 1, HDLC_STATUS);
  572. debugl1(cs, "HDLC 2 STA %x", val);
  573. } else {
  574. val = ReadHDLCPnP(cs, 0, HDLC_STATUS);
  575. debugl1(cs, "HDLC 1 STA %x", val);
  576. val = ReadHDLCPnP(cs, 0, HDLC_STATUS + 1);
  577. debugl1(cs, "HDLC 1 RML %x", val);
  578. val = ReadHDLCPnP(cs, 0, HDLC_STATUS + 2);
  579. debugl1(cs, "HDLC 1 MODE %x", val);
  580. val = ReadHDLCPnP(cs, 0, HDLC_STATUS + 3);
  581. debugl1(cs, "HDLC 1 VIN %x", val);
  582. val = ReadHDLCPnP(cs, 1, HDLC_STATUS);
  583. debugl1(cs, "HDLC 2 STA %x", val);
  584. val = ReadHDLCPnP(cs, 1, HDLC_STATUS + 1);
  585. debugl1(cs, "HDLC 2 RML %x", val);
  586. val = ReadHDLCPnP(cs, 1, HDLC_STATUS + 2);
  587. debugl1(cs, "HDLC 2 MODE %x", val);
  588. val = ReadHDLCPnP(cs, 1, HDLC_STATUS + 3);
  589. debugl1(cs, "HDLC 2 VIN %x", val);
  590. }
  591. }
  592. #endif /* 0 */
  593. static void __init
  594. inithdlc(struct IsdnCardState *cs)
  595. {
  596. cs->bcs[0].BC_SetStack = setstack_hdlc;
  597. cs->bcs[1].BC_SetStack = setstack_hdlc;
  598. cs->bcs[0].BC_Close = close_hdlcstate;
  599. cs->bcs[1].BC_Close = close_hdlcstate;
  600. modehdlc(cs->bcs, -1, 0);
  601. modehdlc(cs->bcs + 1, -1, 1);
  602. }
  603. static irqreturn_t
  604. avm_pcipnp_interrupt(int intno, void *dev_id, struct pt_regs *regs)
  605. {
  606. struct IsdnCardState *cs = dev_id;
  607. u_long flags;
  608. u_char val;
  609. u_char sval;
  610. spin_lock_irqsave(&cs->lock, flags);
  611. sval = inb(cs->hw.avm.cfg_reg + 2);
  612. if ((sval & AVM_STATUS0_IRQ_MASK) == AVM_STATUS0_IRQ_MASK) {
  613. /* possible a shared IRQ reqest */
  614. spin_unlock_irqrestore(&cs->lock, flags);
  615. return IRQ_NONE;
  616. }
  617. if (!(sval & AVM_STATUS0_IRQ_ISAC)) {
  618. val = ReadISAC(cs, ISAC_ISTA);
  619. isac_interrupt(cs, val);
  620. }
  621. if (!(sval & AVM_STATUS0_IRQ_HDLC)) {
  622. HDLC_irq_main(cs);
  623. }
  624. WriteISAC(cs, ISAC_MASK, 0xFF);
  625. WriteISAC(cs, ISAC_MASK, 0x0);
  626. spin_unlock_irqrestore(&cs->lock, flags);
  627. return IRQ_HANDLED;
  628. }
  629. static void
  630. reset_avmpcipnp(struct IsdnCardState *cs)
  631. {
  632. printk(KERN_INFO "AVM PCI/PnP: reset\n");
  633. outb(AVM_STATUS0_RESET | AVM_STATUS0_DIS_TIMER, cs->hw.avm.cfg_reg + 2);
  634. mdelay(10);
  635. outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER | AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2);
  636. outb(AVM_STATUS1_ENA_IOM | cs->irq, cs->hw.avm.cfg_reg + 3);
  637. mdelay(10);
  638. printk(KERN_INFO "AVM PCI/PnP: S1 %x\n", inb(cs->hw.avm.cfg_reg + 3));
  639. }
  640. static int
  641. AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
  642. {
  643. u_long flags;
  644. switch (mt) {
  645. case CARD_RESET:
  646. spin_lock_irqsave(&cs->lock, flags);
  647. reset_avmpcipnp(cs);
  648. spin_unlock_irqrestore(&cs->lock, flags);
  649. return(0);
  650. case CARD_RELEASE:
  651. outb(0, cs->hw.avm.cfg_reg + 2);
  652. release_region(cs->hw.avm.cfg_reg, 32);
  653. return(0);
  654. case CARD_INIT:
  655. spin_lock_irqsave(&cs->lock, flags);
  656. reset_avmpcipnp(cs);
  657. clear_pending_isac_ints(cs);
  658. initisac(cs);
  659. inithdlc(cs);
  660. outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER,
  661. cs->hw.avm.cfg_reg + 2);
  662. WriteISAC(cs, ISAC_MASK, 0);
  663. outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER |
  664. AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2);
  665. /* RESET Receiver and Transmitter */
  666. WriteISAC(cs, ISAC_CMDR, 0x41);
  667. spin_unlock_irqrestore(&cs->lock, flags);
  668. return(0);
  669. case CARD_TEST:
  670. return(0);
  671. }
  672. return(0);
  673. }
  674. #ifdef CONFIG_PCI
  675. static struct pci_dev *dev_avm __initdata = NULL;
  676. #endif
  677. #ifdef __ISAPNP__
  678. static struct pnp_card *pnp_avm_c __initdata = NULL;
  679. #endif
  680. int __init
  681. setup_avm_pcipnp(struct IsdnCard *card)
  682. {
  683. u_int val, ver;
  684. struct IsdnCardState *cs = card->cs;
  685. char tmp[64];
  686. strcpy(tmp, avm_pci_rev);
  687. printk(KERN_INFO "HiSax: AVM PCI driver Rev. %s\n", HiSax_getrev(tmp));
  688. if (cs->typ != ISDN_CTYPE_FRITZPCI)
  689. return (0);
  690. if (card->para[1]) {
  691. /* old manual method */
  692. cs->hw.avm.cfg_reg = card->para[1];
  693. cs->irq = card->para[0];
  694. cs->subtyp = AVM_FRITZ_PNP;
  695. goto ready;
  696. }
  697. #ifdef __ISAPNP__
  698. if (isapnp_present()) {
  699. struct pnp_dev *pnp_avm_d = NULL;
  700. if ((pnp_avm_c = pnp_find_card(
  701. ISAPNP_VENDOR('A', 'V', 'M'),
  702. ISAPNP_FUNCTION(0x0900), pnp_avm_c))) {
  703. if ((pnp_avm_d = pnp_find_dev(pnp_avm_c,
  704. ISAPNP_VENDOR('A', 'V', 'M'),
  705. ISAPNP_FUNCTION(0x0900), pnp_avm_d))) {
  706. int err;
  707. pnp_disable_dev(pnp_avm_d);
  708. err = pnp_activate_dev(pnp_avm_d);
  709. if (err<0) {
  710. printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n",
  711. __FUNCTION__, err);
  712. return(0);
  713. }
  714. cs->hw.avm.cfg_reg =
  715. pnp_port_start(pnp_avm_d, 0);
  716. cs->irq = pnp_irq(pnp_avm_d, 0);
  717. if (!cs->irq) {
  718. printk(KERN_ERR "FritzPnP:No IRQ\n");
  719. return(0);
  720. }
  721. if (!cs->hw.avm.cfg_reg) {
  722. printk(KERN_ERR "FritzPnP:No IO address\n");
  723. return(0);
  724. }
  725. cs->subtyp = AVM_FRITZ_PNP;
  726. goto ready;
  727. }
  728. }
  729. } else {
  730. printk(KERN_INFO "FritzPnP: no ISA PnP present\n");
  731. }
  732. #endif
  733. #ifdef CONFIG_PCI
  734. if ((dev_avm = pci_find_device(PCI_VENDOR_ID_AVM,
  735. PCI_DEVICE_ID_AVM_A1, dev_avm))) {
  736. if (pci_enable_device(dev_avm))
  737. return(0);
  738. cs->irq = dev_avm->irq;
  739. if (!cs->irq) {
  740. printk(KERN_ERR "FritzPCI: No IRQ for PCI card found\n");
  741. return(0);
  742. }
  743. cs->hw.avm.cfg_reg = pci_resource_start(dev_avm, 1);
  744. if (!cs->hw.avm.cfg_reg) {
  745. printk(KERN_ERR "FritzPCI: No IO-Adr for PCI card found\n");
  746. return(0);
  747. }
  748. cs->subtyp = AVM_FRITZ_PCI;
  749. } else {
  750. printk(KERN_WARNING "FritzPCI: No PCI card found\n");
  751. return(0);
  752. }
  753. cs->irq_flags |= SA_SHIRQ;
  754. #else
  755. printk(KERN_WARNING "FritzPCI: NO_PCI_BIOS\n");
  756. return (0);
  757. #endif /* CONFIG_PCI */
  758. ready:
  759. cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10;
  760. if (!request_region(cs->hw.avm.cfg_reg, 32,
  761. (cs->subtyp == AVM_FRITZ_PCI) ? "avm PCI" : "avm PnP")) {
  762. printk(KERN_WARNING
  763. "HiSax: %s config port %x-%x already in use\n",
  764. CardType[card->typ],
  765. cs->hw.avm.cfg_reg,
  766. cs->hw.avm.cfg_reg + 31);
  767. return (0);
  768. }
  769. switch (cs->subtyp) {
  770. case AVM_FRITZ_PCI:
  771. val = inl(cs->hw.avm.cfg_reg);
  772. printk(KERN_INFO "AVM PCI: stat %#x\n", val);
  773. printk(KERN_INFO "AVM PCI: Class %X Rev %d\n",
  774. val & 0xff, (val>>8) & 0xff);
  775. cs->BC_Read_Reg = &ReadHDLC_s;
  776. cs->BC_Write_Reg = &WriteHDLC_s;
  777. break;
  778. case AVM_FRITZ_PNP:
  779. val = inb(cs->hw.avm.cfg_reg);
  780. ver = inb(cs->hw.avm.cfg_reg + 1);
  781. printk(KERN_INFO "AVM PnP: Class %X Rev %d\n", val, ver);
  782. cs->BC_Read_Reg = &ReadHDLCPnP;
  783. cs->BC_Write_Reg = &WriteHDLCPnP;
  784. break;
  785. default:
  786. printk(KERN_WARNING "AVM unknown subtype %d\n", cs->subtyp);
  787. return(0);
  788. }
  789. printk(KERN_INFO "HiSax: %s config irq:%d base:0x%X\n",
  790. (cs->subtyp == AVM_FRITZ_PCI) ? "AVM Fritz!PCI" : "AVM Fritz!PnP",
  791. cs->irq, cs->hw.avm.cfg_reg);
  792. setup_isac(cs);
  793. cs->readisac = &ReadISAC;
  794. cs->writeisac = &WriteISAC;
  795. cs->readisacfifo = &ReadISACfifo;
  796. cs->writeisacfifo = &WriteISACfifo;
  797. cs->BC_Send_Data = &hdlc_fill_fifo;
  798. cs->cardmsg = &AVM_card_msg;
  799. cs->irq_func = &avm_pcipnp_interrupt;
  800. cs->writeisac(cs, ISAC_MASK, 0xFF);
  801. ISACVersion(cs, (cs->subtyp == AVM_FRITZ_PCI) ? "AVM PCI:" : "AVM PnP:");
  802. return (1);
  803. }