avm_pci.c 23 KB

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