wct1xxp.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443
  1. /*
  2. * Digium, Inc. Wildcard T100P T1/PRI card Driver
  3. *
  4. * Written by Mark Spencer <markster@digium.com>
  5. * Matthew Fredrickson <creslin@digium.com>
  6. * William Meadows <wmeadows@digium.com>
  7. *
  8. * Copyright (C) 2001-2008, Digium, Inc.
  9. *
  10. * All rights reserved.
  11. *
  12. */
  13. /*
  14. * See http://www.asterisk.org for more information about
  15. * the Asterisk project. Please do not directly contact
  16. * any of the maintainers of this project for assistance;
  17. * the project provides a web site, mailing lists and IRC
  18. * channels for your use.
  19. *
  20. * This program is free software, distributed under the terms of
  21. * the GNU General Public License Version 2 as published by the
  22. * Free Software Foundation. See the LICENSE file included with
  23. * this program for more details.
  24. */
  25. #include <linux/kernel.h>
  26. #include <linux/errno.h>
  27. #include <linux/module.h>
  28. #include <linux/init.h>
  29. #include <linux/usb.h>
  30. #include <linux/errno.h>
  31. #include <linux/pci.h>
  32. #include <linux/spinlock.h>
  33. #include <linux/moduleparam.h>
  34. #include <dahdi/kernel.h>
  35. #define WC_MAX_CARDS 32
  36. /*
  37. #define TEST_REGS
  38. */
  39. /* Define to get more attention-grabbing but slightly more I/O using
  40. alarm status */
  41. #define FANCY_ALARM
  42. #define DELAY 0x0 /* 30 = 15 cycles, 10 = 8 cycles, 0 = 3 cycles */
  43. #define WC_CNTL 0x00
  44. #define WC_OPER 0x01
  45. #define WC_AUXC 0x02
  46. #define WC_AUXD 0x03
  47. #define WC_MASK0 0x04
  48. #define WC_MASK1 0x05
  49. #define WC_INTSTAT 0x06
  50. #define WC_DMAWS 0x08
  51. #define WC_DMAWI 0x0c
  52. #define WC_DMAWE 0x10
  53. #define WC_DMARS 0x18
  54. #define WC_DMARI 0x1c
  55. #define WC_DMARE 0x20
  56. #define WC_CURPOS 0x24
  57. #define WC_SERC 0x2d
  58. #define WC_FSCDELAY 0x2f
  59. #define WC_USERREG 0xc0
  60. #define WC_CLOCK 0x0
  61. #define WC_LEDTEST 0x1
  62. #define WC_VERSION 0x2
  63. /* Offset between transmit and receive */
  64. #define WC_OFFSET 4
  65. #define BIT_CS (1 << 7)
  66. #define BIT_ADDR (0xf << 3)
  67. #define BIT_LED0 (1 << 0)
  68. #define BIT_LED1 (1 << 1)
  69. #define BIT_TEST (1 << 2)
  70. static char *chips[] =
  71. {
  72. "DS2152",
  73. "DS21352",
  74. "DS21552",
  75. "Unknown Chip (3)",
  76. "DS2154",
  77. "DS21354",
  78. "DS21554",
  79. "Unknown Chip (7)",
  80. };
  81. static int chanmap_t1[] =
  82. { 2,1,0,
  83. 6,5,4,
  84. 10,9,8,
  85. 14,13,12,
  86. 18,17,16,
  87. 22,21,20,
  88. 26,25,24,
  89. 30,29,28 };
  90. static int chanmap_e1[] =
  91. { 2,1,0,
  92. 7,6,5,4,
  93. 11,10,9,8,
  94. 15,14,13,12,
  95. 19,18,17,16,
  96. 23,22,21,20,
  97. 27,26,25,24,
  98. 31,30,29,28 };
  99. #ifdef FANCY_ALARM
  100. static int altab[] = {
  101. 0, 0, 0, 1, 2, 3, 4, 6, 8, 9, 11, 13, 16, 18, 20, 22, 24, 25, 27, 28, 29, 30, 31, 31, 32, 31, 31, 30, 29, 28, 27, 25, 23, 22, 20, 18, 16, 13, 11, 9, 8, 6, 4, 3, 2, 1, 0, 0,
  102. };
  103. #endif
  104. struct t1xxp {
  105. struct pci_dev *dev;
  106. spinlock_t lock;
  107. int ise1;
  108. int num;
  109. /* Our offset for finding channel 1 */
  110. int offset;
  111. char *variety;
  112. unsigned int intcount;
  113. int usecount;
  114. int clocktimeout;
  115. int sync;
  116. int dead;
  117. int blinktimer;
  118. int alarmtimer;
  119. int loopupcnt;
  120. int loopdowncnt;
  121. int miss;
  122. int misslast;
  123. int *chanmap;
  124. #ifdef FANCY_ALARM
  125. int alarmpos;
  126. #endif
  127. unsigned char ledtestreg;
  128. unsigned char outbyte;
  129. unsigned long ioaddr;
  130. unsigned short canary;
  131. /* T1 signalling */
  132. unsigned char txsiga[3];
  133. unsigned char txsigb[3];
  134. dma_addr_t readdma;
  135. dma_addr_t writedma;
  136. volatile unsigned char *writechunk; /* Double-word aligned write memory */
  137. volatile unsigned char *readchunk; /* Double-word aligned read memory */
  138. unsigned char ec_chunk1[31][DAHDI_CHUNKSIZE];
  139. unsigned char ec_chunk2[31][DAHDI_CHUNKSIZE];
  140. unsigned char tempo[32];
  141. struct dahdi_span span; /* Span */
  142. struct dahdi_chan *chans[31]; /* Channels */
  143. };
  144. #define CANARY 0xca1e
  145. static int debug = 0; /* doesnt do anything */
  146. static struct t1xxp *cards[WC_MAX_CARDS];
  147. static inline void start_alarm(struct t1xxp *wc)
  148. {
  149. #ifdef FANCY_ALARM
  150. wc->alarmpos = 0;
  151. #endif
  152. wc->blinktimer = 0;
  153. }
  154. static inline void stop_alarm(struct t1xxp *wc)
  155. {
  156. #ifdef FANCY_ALARM
  157. wc->alarmpos = 0;
  158. #endif
  159. wc->blinktimer = 0;
  160. }
  161. static inline void __select_framer(struct t1xxp *wc, int reg)
  162. {
  163. /* Top four bits of address from AUX 6-3 */
  164. wc->outbyte &= ~BIT_CS;
  165. wc->outbyte &= ~BIT_ADDR;
  166. wc->outbyte |= (reg & 0xf0) >> 1;
  167. outb(wc->outbyte, wc->ioaddr + WC_AUXD);
  168. }
  169. static inline void __select_control(struct t1xxp *wc)
  170. {
  171. if (!(wc->outbyte & BIT_CS)) {
  172. wc->outbyte |= BIT_CS;
  173. outb(wc->outbyte, wc->ioaddr + WC_AUXD);
  174. }
  175. }
  176. static int t1xxp_open(struct dahdi_chan *chan)
  177. {
  178. struct t1xxp *wc = chan->pvt;
  179. if (wc->dead)
  180. return -ENODEV;
  181. wc->usecount++;
  182. return 0;
  183. }
  184. static int __t1_get_reg(struct t1xxp *wc, int reg)
  185. {
  186. unsigned char res;
  187. __select_framer(wc, reg);
  188. /* Get value */
  189. res = inb(wc->ioaddr + WC_USERREG + ((reg & 0xf) << 2));
  190. return res;
  191. }
  192. static int __t1_set_reg(struct t1xxp *wc, int reg, unsigned char val)
  193. {
  194. __select_framer(wc, reg);
  195. /* Send address */
  196. outb(val, wc->ioaddr + WC_USERREG + ((reg & 0xf) << 2));
  197. return 0;
  198. }
  199. static int __control_set_reg(struct t1xxp *wc, int reg, unsigned char val)
  200. {
  201. __select_control(wc);
  202. outb(val, wc->ioaddr + WC_USERREG + ((reg & 0xf) << 2));
  203. return 0;
  204. }
  205. static int control_set_reg(struct t1xxp *wc, int reg, unsigned char val)
  206. {
  207. unsigned long flags;
  208. int res;
  209. spin_lock_irqsave(&wc->lock, flags);
  210. res = __control_set_reg(wc, reg, val);
  211. spin_unlock_irqrestore(&wc->lock, flags);
  212. return res;
  213. }
  214. static int __control_get_reg(struct t1xxp *wc, int reg)
  215. {
  216. unsigned char res;
  217. /* The following makes UTTERLY no sense, but what was happening
  218. was that reads in some cases were not actually happening
  219. on the physical bus. Why, we dunno. But in debugging, we found
  220. that writing before reading (in this case to an unused position)
  221. seems to get rid of the problem */
  222. __control_set_reg(wc,3,0x69); /* do magic here */
  223. /* now get the read byte from the Xilinx part */
  224. res = inb(wc->ioaddr + WC_USERREG + ((reg & 0xf) << 2));
  225. return res;
  226. }
  227. static int control_get_reg(struct t1xxp *wc, int reg)
  228. {
  229. unsigned long flags;
  230. int res;
  231. spin_lock_irqsave(&wc->lock, flags);
  232. res = __control_get_reg(wc, reg);
  233. spin_unlock_irqrestore(&wc->lock, flags);
  234. return res;
  235. }
  236. static void t1xxp_release(struct t1xxp *wc)
  237. {
  238. unsigned int x;
  239. dahdi_unregister(&wc->span);
  240. for (x = 0; x < (wc->ise1 ? 31 : 24); x++) {
  241. kfree(wc->chans[x]);
  242. }
  243. kfree(wc);
  244. printk(KERN_INFO "Freed a Wildcard\n");
  245. }
  246. static int t1xxp_close(struct dahdi_chan *chan)
  247. {
  248. struct t1xxp *wc = chan->pvt;
  249. wc->usecount--;
  250. /* If we're dead, release us now */
  251. if (!wc->usecount && wc->dead)
  252. t1xxp_release(wc);
  253. return 0;
  254. }
  255. static void t1xxp_enable_interrupts(struct t1xxp *wc)
  256. {
  257. /* Clear interrupts */
  258. outb(0xff, wc->ioaddr + WC_INTSTAT);
  259. /* Enable interrupts (we care about all of them) */
  260. outb(0x3c /* 0x3f */, wc->ioaddr + WC_MASK0);
  261. /* No external interrupts */
  262. outb(0x00, wc->ioaddr + WC_MASK1);
  263. }
  264. static void t1xxp_start_dma(struct t1xxp *wc)
  265. {
  266. /* Reset Master and TDM */
  267. outb(DELAY | 0x0f, wc->ioaddr + WC_CNTL);
  268. set_current_state(TASK_INTERRUPTIBLE);
  269. schedule_timeout(1);
  270. outb(DELAY | 0x01, wc->ioaddr + WC_CNTL);
  271. outb(0x01, wc->ioaddr + WC_OPER);
  272. if (debug) printk(KERN_DEBUG "Started DMA\n");
  273. }
  274. static void __t1xxp_stop_dma(struct t1xxp *wc)
  275. {
  276. outb(0x00, wc->ioaddr + WC_OPER);
  277. }
  278. static void __t1xxp_disable_interrupts(struct t1xxp *wc)
  279. {
  280. outb(0x00, wc->ioaddr + WC_MASK0);
  281. outb(0x00, wc->ioaddr + WC_MASK1);
  282. }
  283. static void __t1xxp_set_clear(struct t1xxp *wc)
  284. {
  285. /* Setup registers */
  286. int x,y;
  287. unsigned char b;
  288. /* No such thing under E1 */
  289. if (wc->ise1) {
  290. printk(KERN_NOTICE "Can't set clear mode on an E1!\n");
  291. return;
  292. }
  293. for (x=0;x<3;x++) {
  294. b = 0;
  295. for (y=0;y<8;y++)
  296. if (wc->chans[x * 8 + y]->sig & DAHDI_SIG_CLEAR)
  297. b |= (1 << y);
  298. __t1_set_reg(wc, 0x39 + x, b);
  299. }
  300. }
  301. static void t1xxp_t1_framer_start(struct t1xxp *wc)
  302. {
  303. int i;
  304. char *coding, *framing;
  305. unsigned long endjiffies;
  306. int alreadyrunning = wc->span.flags & DAHDI_FLAG_RUNNING;
  307. unsigned long flags;
  308. spin_lock_irqsave(&wc->lock, flags);
  309. /* Build up config */
  310. i = 0x20;
  311. if (wc->span.lineconfig & DAHDI_CONFIG_ESF) {
  312. coding = "ESF";
  313. i = 0x88;
  314. } else {
  315. coding = "SF";
  316. }
  317. if (wc->span.lineconfig & DAHDI_CONFIG_B8ZS) {
  318. framing = "B8ZS";
  319. i |= 0x44;
  320. } else {
  321. framing = "AMI";
  322. }
  323. __t1_set_reg(wc, 0x38, i);
  324. if (!(wc->span.lineconfig & DAHDI_CONFIG_ESF)) {
  325. /* 1c in FDL bit */
  326. __t1_set_reg(wc, 0x7e, 0x1c);
  327. } else {
  328. __t1_set_reg(wc, 0x7e, 0x00);
  329. }
  330. /* Set outgoing LBO */
  331. __t1_set_reg(wc, 0x7c, wc->span.txlevel << 5);
  332. printk(KERN_DEBUG "Using %s/%s coding/framing\n", coding, framing);
  333. if (!alreadyrunning) {
  334. /* Setup the clear channels */
  335. __t1xxp_set_clear(wc);
  336. /* Set LIRST bit to 1 */
  337. __t1_set_reg(wc, 0x0a, 0x80);
  338. spin_unlock_irqrestore(&wc->lock, flags);
  339. /* Wait 100ms to give plenty of time for reset */
  340. endjiffies = jiffies + 10;
  341. while(endjiffies < jiffies);
  342. spin_lock_irqsave(&wc->lock, flags);
  343. /* Reset LIRST bit and reset elastic stores */
  344. __t1_set_reg(wc, 0xa, 0x30);
  345. wc->span.flags |= DAHDI_FLAG_RUNNING;
  346. }
  347. spin_unlock_irqrestore(&wc->lock, flags);
  348. }
  349. static void t1xxp_e1_framer_start(struct t1xxp *wc)
  350. {
  351. int i;
  352. char *coding, *framing;
  353. unsigned long endjiffies;
  354. int alreadyrunning = wc->span.flags & DAHDI_FLAG_RUNNING;
  355. unsigned long flags;
  356. char *crcing = "";
  357. unsigned char ccr1, tcr1, tcr2;
  358. spin_lock_irqsave(&wc->lock, flags);
  359. /* Build up config */
  360. ccr1 = 0;
  361. tcr1 = 8;
  362. tcr2 = 0;
  363. if (wc->span.lineconfig & DAHDI_CONFIG_CCS) {
  364. coding = "CCS"; /* Receive CCS */
  365. ccr1 |= 8;
  366. } else {
  367. tcr1 |= 0x20;
  368. coding = "CAS";
  369. }
  370. if (wc->span.lineconfig & DAHDI_CONFIG_HDB3) {
  371. ccr1 |= 0x44; /* TX/RX HDB3 */
  372. framing = "HDB3";
  373. } else {
  374. framing = "AMI";
  375. }
  376. if (wc->span.lineconfig & DAHDI_CONFIG_CRC4) {
  377. ccr1 |= 0x11;
  378. tcr2 |= 0x02;
  379. crcing = " with CRC4";
  380. }
  381. __t1_set_reg(wc, 0x12, tcr1);
  382. __t1_set_reg(wc, 0x13, tcr2);
  383. __t1_set_reg(wc, 0x14, ccr1);
  384. __t1_set_reg(wc, 0x18, 0x20); /* 120 Ohm */
  385. #if 0 /* XXX Does LBO Matter? XXX */
  386. /* Set outgoing LBO */
  387. __t1_set_reg(wc, 0x7c, wc->span.txlevel << 5);
  388. #endif
  389. printk(KERN_DEBUG "Using %s/%s coding/framing%s 120 Ohms\n", coding, framing,crcing);
  390. if (!alreadyrunning) {
  391. __t1_set_reg(wc,0x1b,0x8a); /* CCR3: LIRST & TSCLKM */
  392. __t1_set_reg(wc,0x20,0x1b); /* TAFR */
  393. __t1_set_reg(wc,0x21,0x5f); /* TNAFR */
  394. __t1_set_reg(wc,0x40,0xb); /* TSR1 */
  395. for(i = 0x41; i <= 0x4f; i++) __t1_set_reg(wc,i,0x55);
  396. for(i = 0x22; i <= 0x25; i++) __t1_set_reg(wc,i,0xff);
  397. spin_unlock_irqrestore(&wc->lock, flags);
  398. /* Wait 100ms to give plenty of time for reset */
  399. endjiffies = jiffies + 10;
  400. while(endjiffies < jiffies);
  401. spin_lock_irqsave(&wc->lock, flags);
  402. __t1_set_reg(wc, 0x1b, 0x9a); /* Set ESR */
  403. __t1_set_reg(wc, 0x1b, 0x82); /* TSCLKM only now */
  404. /* Reset LIRST bit and reset elastic stores */
  405. wc->span.flags |= DAHDI_FLAG_RUNNING;
  406. }
  407. spin_unlock_irqrestore(&wc->lock, flags);
  408. }
  409. static int t1xxp_framer_sanity_check(struct t1xxp *wc)
  410. {
  411. int res;
  412. int chipid;
  413. unsigned long flags;
  414. int x;
  415. /* Sanity check */
  416. spin_lock_irqsave(&wc->lock, flags);
  417. for (x=0x0;x<192;x++)
  418. __t1_set_reg(wc, x, 0);
  419. res = __t1_get_reg(wc, 0x0f);
  420. res = __t1_get_reg(wc, 0x0f);
  421. chipid = ((res & 0x80) >> 5) | ((res & 0x30) >> 4);
  422. wc->ise1 = (res & 0x80) ? (1 << 4) : 0;
  423. spin_unlock_irqrestore(&wc->lock, flags);
  424. printk(KERN_DEBUG "Framer: %s, Revision: %d (%s)\n", chips[chipid], res & 0xf, wc->ise1 ? "E1" : "T1");
  425. return 0;
  426. }
  427. static int t1xxp_framer_hard_reset(struct t1xxp *wc)
  428. {
  429. int x;
  430. unsigned long flags;
  431. spin_lock_irqsave(&wc->lock, flags);
  432. /* Initialize all registers to 0 */
  433. for (x=0x0;x<192;x++)
  434. __t1_set_reg(wc, x, 0);
  435. if (wc->ise1) {
  436. /* Set LOTCMC (switch to RCLCK if TCLK fails) */
  437. __t1_set_reg(wc, 0x1a, 0x04);
  438. /* RSYNC is an input */
  439. __t1_set_reg(wc, 0x10, 0x20);
  440. /* Rx elastic store enabled, 2.048 Mhz (in theory) */
  441. __t1_set_reg(wc, 0x11, 0x06);
  442. /* TSYNC is an input, Tsis mode */
  443. __t1_set_reg(wc, 0x12, 0x08);
  444. /* Tx elastic store enabled, 2.048 Mhz (in theory) */
  445. __t1_set_reg(wc, 0x1b, 0x82);
  446. } else {
  447. /* Full-on sync required for T1 */
  448. __t1_set_reg(wc, 0x2b, 0x08);
  449. /* RSYNC is an input */
  450. __t1_set_reg(wc, 0x2c, 0x08);
  451. /* Enable tx RBS bits */
  452. __t1_set_reg(wc, 0x35, 0x10);
  453. /* TSYNC is output */
  454. __t1_set_reg(wc, 0x36, 0x04);
  455. /* Tx and Rx elastic store enabled, 2.048 Mhz (in theory) */
  456. __t1_set_reg(wc, 0x37, 0x9c);
  457. /* Setup Loopup / Loopdown codes */
  458. __t1_set_reg(wc, 0x12, 0x22);
  459. __t1_set_reg(wc, 0x14, 0x80);
  460. __t1_set_reg(wc, 0x15, 0x80);
  461. }
  462. spin_unlock_irqrestore(&wc->lock, flags);
  463. return 0;
  464. }
  465. static int t1xxp_rbsbits(struct dahdi_chan *chan, int bits)
  466. {
  467. struct t1xxp *wc = chan->pvt;
  468. unsigned long flags;
  469. int b,o;
  470. unsigned char mask;
  471. /* Byte offset */
  472. spin_lock_irqsave(&wc->lock, flags);
  473. if (wc->ise1) {
  474. if (chan->chanpos < 16) {
  475. mask = ((bits << 4) | wc->chans[chan->chanpos - 1 + 16]->txsig);
  476. __t1_set_reg(wc, 0x40 + chan->chanpos, mask);
  477. }
  478. else if (chan->chanpos > 16) {
  479. mask = (bits | (wc->chans[chan->chanpos - 1 - 16]->txsig << 4));
  480. __t1_set_reg(wc, 0x40 + chan->chanpos - 16, mask);
  481. }
  482. wc->chans[chan->chanpos - 1]->txsig = bits;
  483. } else {
  484. b = (chan->chanpos - 1) / 8;
  485. o = (chan->chanpos - 1) % 8;
  486. mask = (1 << o);
  487. if (bits & DAHDI_ABIT) {
  488. /* Set A-bit */
  489. wc->txsiga[b] |= mask;
  490. } else {
  491. /* Clear A-bit */
  492. wc->txsiga[b] &= ~mask;
  493. }
  494. if (bits & DAHDI_BBIT) {
  495. /* Set B-bit */
  496. wc->txsigb[b] |= mask;
  497. } else {
  498. wc->txsigb[b] &= ~mask;
  499. }
  500. /* Output new values */
  501. __t1_set_reg(wc, 0x70 + b, wc->txsiga[b]);
  502. __t1_set_reg(wc, 0x73 + b, wc->txsigb[b]);
  503. __t1_set_reg(wc, 0x76 + b, wc->txsiga[b]);
  504. __t1_set_reg(wc, 0x79 + b, wc->txsigb[b]);
  505. }
  506. spin_unlock_irqrestore(&wc->lock, flags);
  507. return 0;
  508. }
  509. static int t1xxp_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data)
  510. {
  511. switch(cmd) {
  512. default:
  513. return -ENOTTY;
  514. }
  515. }
  516. static inline struct t1xxp *t1xxp_from_span(struct dahdi_span *span)
  517. {
  518. return container_of(span, struct t1xxp, span);
  519. }
  520. static int t1xxp_startup(struct dahdi_span *span)
  521. {
  522. struct t1xxp *wc = t1xxp_from_span(span);
  523. int i,alreadyrunning = span->flags & DAHDI_FLAG_RUNNING;
  524. /* initialize the start value for the entire chunk of last ec buffer */
  525. for(i = 0; i < span->channels; i++)
  526. {
  527. memset(wc->ec_chunk1[i],
  528. DAHDI_LIN2X(0,span->chans[i]),DAHDI_CHUNKSIZE);
  529. memset(wc->ec_chunk2[i],
  530. DAHDI_LIN2X(0,span->chans[i]),DAHDI_CHUNKSIZE);
  531. }
  532. /* Reset framer with proper parameters and start */
  533. if (wc->ise1)
  534. t1xxp_e1_framer_start(wc);
  535. else
  536. t1xxp_t1_framer_start(wc);
  537. printk(KERN_INFO "Calling startup (flags is %lu)\n", span->flags);
  538. if (!alreadyrunning) {
  539. /* Only if we're not already going */
  540. t1xxp_enable_interrupts(wc);
  541. t1xxp_start_dma(wc);
  542. span->flags |= DAHDI_FLAG_RUNNING;
  543. }
  544. return 0;
  545. }
  546. static int t1xxp_shutdown(struct dahdi_span *span)
  547. {
  548. struct t1xxp *wc = t1xxp_from_span(span);
  549. unsigned long flags;
  550. spin_lock_irqsave(&wc->lock, flags);
  551. __t1xxp_stop_dma(wc);
  552. __t1xxp_disable_interrupts(wc);
  553. span->flags &= ~DAHDI_FLAG_RUNNING;
  554. spin_unlock_irqrestore(&wc->lock, flags);
  555. t1xxp_framer_hard_reset(wc);
  556. return 0;
  557. }
  558. static int t1xxp_maint(struct dahdi_span *span, int cmd)
  559. {
  560. struct t1xxp *wc = t1xxp_from_span(span);
  561. int res = 0;
  562. unsigned long flags;
  563. spin_lock_irqsave(&wc->lock, flags);
  564. if (wc->ise1) {
  565. switch(cmd) {
  566. case DAHDI_MAINT_NONE:
  567. __t1_set_reg(wc,0xa8,0); /* no loops */
  568. break;
  569. case DAHDI_MAINT_LOCALLOOP:
  570. __t1_set_reg(wc,0xa8,0x40); /* local loop */
  571. break;
  572. case DAHDI_MAINT_REMOTELOOP:
  573. __t1_set_reg(wc,0xa8,0x80); /* remote loop */
  574. break;
  575. case DAHDI_MAINT_LOOPUP:
  576. case DAHDI_MAINT_LOOPDOWN:
  577. case DAHDI_MAINT_LOOPSTOP:
  578. res = -ENOSYS;
  579. break;
  580. default:
  581. printk(KERN_NOTICE "wct1xxp/E1: Unknown maint command: %d\n", cmd);
  582. res = -EINVAL;
  583. break;
  584. }
  585. } else {
  586. switch(cmd) {
  587. case DAHDI_MAINT_NONE:
  588. __t1_set_reg(wc,0x19,0); /* no local loop */
  589. __t1_set_reg(wc,0x0a,0); /* no remote loop */
  590. break;
  591. case DAHDI_MAINT_LOCALLOOP:
  592. __t1_set_reg(wc,0x19,0x40); /* local loop */
  593. __t1_set_reg(wc,0x0a,0); /* no remote loop */
  594. break;
  595. case DAHDI_MAINT_REMOTELOOP:
  596. __t1_set_reg(wc,0x1e,0); /* no local loop */
  597. __t1_set_reg(wc,0x0a,0x40); /* remote loop */
  598. break;
  599. case DAHDI_MAINT_LOOPUP:
  600. __t1_set_reg(wc,0x30,2); /* send loopup code */
  601. __t1_set_reg(wc,0x12,0x22); /* send loopup code */
  602. __t1_set_reg(wc,0x13,0x80); /* send loopup code */
  603. break;
  604. case DAHDI_MAINT_LOOPDOWN:
  605. __t1_set_reg(wc,0x30,2); /* send loopdown code */
  606. __t1_set_reg(wc,0x12,0x62); /* send loopdown code */
  607. __t1_set_reg(wc,0x13,0x90); /* send loopdown code */
  608. break;
  609. case DAHDI_MAINT_LOOPSTOP:
  610. __t1_set_reg(wc,0x30,0); /* stop sending loopup code */
  611. break;
  612. default:
  613. printk(KERN_NOTICE "wct1xxp/T1: Unknown maint command: %d\n", cmd);
  614. res = -EINVAL;
  615. }
  616. }
  617. spin_unlock_irqrestore(&wc->lock, flags);
  618. return res;
  619. }
  620. static int t1xxp_chanconfig(struct dahdi_chan *chan, int sigtype)
  621. {
  622. struct t1xxp *wc = chan->pvt;
  623. unsigned long flags;
  624. int alreadyrunning = chan->span->flags & DAHDI_FLAG_RUNNING;
  625. spin_lock_irqsave(&wc->lock, flags);
  626. if (alreadyrunning && !wc->ise1)
  627. __t1xxp_set_clear(wc);
  628. spin_unlock_irqrestore(&wc->lock, flags);
  629. return 0;
  630. }
  631. static int t1xxp_spanconfig(struct dahdi_span *span, struct dahdi_lineconfig *lc)
  632. {
  633. struct t1xxp *wc = t1xxp_from_span(span);
  634. /* Do we want to SYNC on receive or not */
  635. wc->sync = (lc->sync) ? 1 : 0;
  636. /* If already running, apply changes immediately */
  637. if (span->flags & DAHDI_FLAG_RUNNING)
  638. return t1xxp_startup(span);
  639. return 0;
  640. }
  641. static const struct dahdi_span_ops t1xxp_span_ops = {
  642. .owner = THIS_MODULE,
  643. .spanconfig = t1xxp_spanconfig,
  644. .chanconfig = t1xxp_chanconfig,
  645. .startup = t1xxp_startup,
  646. .shutdown = t1xxp_shutdown,
  647. .rbsbits = t1xxp_rbsbits,
  648. .maint = t1xxp_maint,
  649. .open = t1xxp_open,
  650. .close = t1xxp_close,
  651. .ioctl = t1xxp_ioctl,
  652. };
  653. static int t1xxp_software_init(struct t1xxp *wc)
  654. {
  655. int x;
  656. /* Find position */
  657. for (x=0;x<WC_MAX_CARDS;x++) {
  658. if (!cards[x]) {
  659. cards[x] = wc;
  660. break;
  661. }
  662. }
  663. if (x >= WC_MAX_CARDS)
  664. return -1;
  665. wc->num = x;
  666. sprintf(wc->span.name, "WCT1/%d", wc->num);
  667. snprintf(wc->span.desc, sizeof(wc->span.desc) - 1, "%s Card %d", wc->variety, wc->num);
  668. wc->span.manufacturer = "Digium";
  669. dahdi_copy_string(wc->span.devicetype, wc->variety, sizeof(wc->span.devicetype));
  670. snprintf(wc->span.location, sizeof(wc->span.location) - 1,
  671. "PCI Bus %02d Slot %02d", wc->dev->bus->number, PCI_SLOT(wc->dev->devfn) + 1);
  672. wc->span.irq = wc->dev->irq;
  673. wc->span.chans = wc->chans;
  674. wc->span.flags = DAHDI_FLAG_RBS;
  675. if (wc->ise1) {
  676. wc->span.channels = 31;
  677. wc->span.deflaw = DAHDI_LAW_ALAW;
  678. wc->span.linecompat = DAHDI_CONFIG_HDB3 | DAHDI_CONFIG_CCS | DAHDI_CONFIG_CRC4;
  679. wc->span.spantype = "E1";
  680. } else {
  681. wc->span.channels = 24;
  682. wc->span.deflaw = DAHDI_LAW_MULAW;
  683. wc->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_B8ZS | DAHDI_CONFIG_D4 | DAHDI_CONFIG_ESF;
  684. wc->span.spantype = "T1";
  685. }
  686. init_waitqueue_head(&wc->span.maintq);
  687. for (x=0;x<wc->span.channels;x++) {
  688. sprintf(wc->chans[x]->name, "WCT1/%d/%d", wc->num, x + 1);
  689. wc->chans[x]->sigcap = DAHDI_SIG_EM | DAHDI_SIG_CLEAR | DAHDI_SIG_EM_E1 |
  690. DAHDI_SIG_FXSLS | DAHDI_SIG_FXSGS |
  691. DAHDI_SIG_FXSKS | DAHDI_SIG_FXOLS | DAHDI_SIG_DACS_RBS |
  692. DAHDI_SIG_FXOGS | DAHDI_SIG_FXOKS | DAHDI_SIG_CAS | DAHDI_SIG_SF;
  693. wc->chans[x]->pvt = wc;
  694. wc->chans[x]->chanpos = x + 1;
  695. }
  696. wc->span.ops = &t1xxp_span_ops;
  697. if (dahdi_register(&wc->span, 0)) {
  698. printk(KERN_NOTICE "Unable to register span with DAHDI\n");
  699. return -1;
  700. }
  701. return 0;
  702. }
  703. static inline void __handle_leds(struct t1xxp *wc)
  704. {
  705. int oldreg;
  706. wc->blinktimer++;
  707. if (wc->span.alarms & (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE)) {
  708. /* Red/Blue alarm */
  709. #ifdef FANCY_ALARM
  710. if (wc->blinktimer == (altab[wc->alarmpos] >> 1)) {
  711. wc->ledtestreg = (wc->ledtestreg | BIT_LED1) & ~BIT_LED0;
  712. __control_set_reg(wc, WC_LEDTEST, wc->ledtestreg);
  713. }
  714. if (wc->blinktimer == 0xf) {
  715. wc->ledtestreg = wc->ledtestreg & ~(BIT_LED0 | BIT_LED1);
  716. __control_set_reg(wc, WC_LEDTEST, wc->ledtestreg);
  717. wc->blinktimer = -1;
  718. wc->alarmpos++;
  719. if (wc->alarmpos >= (sizeof(altab) / sizeof(altab[0])))
  720. wc->alarmpos = 0;
  721. }
  722. #else
  723. if (wc->blinktimer == 160) {
  724. wc->ledtestreg = (wc->ledtestreg | BIT_LED1) & ~BIT_LED0;
  725. __control_set_reg(wc, WC_LEDTEST, wc->ledtestreg);
  726. } else if (wc->blinktimer == 480) {
  727. wc->ledtestreg = wc->ledtestreg & ~(BIT_LED0 | BIT_LED1);
  728. __control_set_reg(wc, WC_LEDTEST, wc->ledtestreg);
  729. wc->blinktimer = 0;
  730. }
  731. #endif
  732. } else if (wc->span.alarms & DAHDI_ALARM_YELLOW) {
  733. /* Yellow Alarm */
  734. if (!(wc->blinktimer % 2))
  735. wc->ledtestreg = (wc->ledtestreg | BIT_LED1) & ~BIT_LED0;
  736. else
  737. wc->ledtestreg = (wc->ledtestreg | BIT_LED0) & ~BIT_LED1;
  738. __control_set_reg(wc, WC_LEDTEST, wc->ledtestreg);
  739. } else {
  740. /* No Alarm */
  741. oldreg = wc->ledtestreg;
  742. if (wc->span.maintstat != DAHDI_MAINT_NONE)
  743. wc->ledtestreg |= BIT_TEST;
  744. else
  745. wc->ledtestreg &= ~BIT_TEST;
  746. if (wc->span.flags & DAHDI_FLAG_RUNNING)
  747. wc->ledtestreg = (wc->ledtestreg | BIT_LED0) & ~BIT_LED1;
  748. else
  749. wc->ledtestreg = wc->ledtestreg & ~(BIT_LED0 | BIT_LED1);
  750. if (oldreg != wc->ledtestreg)
  751. __control_set_reg(wc, WC_LEDTEST, wc->ledtestreg);
  752. }
  753. }
  754. static void t1xxp_transmitprep(struct t1xxp *wc, int ints)
  755. {
  756. volatile unsigned char *txbuf;
  757. int x,y;
  758. int pos;
  759. if (ints & 0x04 /* 0x01 */) {
  760. /* We just finished sending the first buffer, start filling it
  761. now */
  762. txbuf = wc->writechunk;
  763. } else {
  764. /* Just finished sending second buffer, fill it now */
  765. txbuf = wc->writechunk + 32 * DAHDI_CHUNKSIZE;
  766. }
  767. dahdi_transmit(&wc->span);
  768. for (x=0;x<wc->offset;x++)
  769. txbuf[x] = wc->tempo[x];
  770. for (y=0;y<DAHDI_CHUNKSIZE;y++) {
  771. for (x=0;x<wc->span.channels;x++) {
  772. pos = y * 32 + wc->chanmap[x] + wc->offset;
  773. /* Put channel number as outgoing data */
  774. if (pos < 32 * DAHDI_CHUNKSIZE)
  775. txbuf[pos] = wc->chans[x]->writechunk[y];
  776. else
  777. wc->tempo[pos - 32 * DAHDI_CHUNKSIZE] = wc->chans[x]->writechunk[y];
  778. }
  779. }
  780. }
  781. static void t1xxp_receiveprep(struct t1xxp *wc, int ints)
  782. {
  783. volatile unsigned char *rxbuf;
  784. volatile unsigned int *canary;
  785. int x;
  786. int y;
  787. unsigned int oldcan;
  788. if (ints & 0x04) {
  789. /* Just received first buffer */
  790. rxbuf = wc->readchunk;
  791. canary = (unsigned int *)(wc->readchunk + DAHDI_CHUNKSIZE * 64 - 4);
  792. } else {
  793. rxbuf = wc->readchunk + DAHDI_CHUNKSIZE * 32;
  794. canary = (unsigned int *)(wc->readchunk + DAHDI_CHUNKSIZE * 32 - 4);
  795. }
  796. oldcan = *canary;
  797. if (((oldcan & 0xffff0000) >> 16) != CANARY) {
  798. /* Check top part */
  799. if (debug) printk(KERN_DEBUG "Expecting top %04x, got %04x\n", CANARY, (oldcan & 0xffff0000) >> 16);
  800. wc->span.irqmisses++;
  801. } else if ((oldcan & 0xffff) != ((wc->canary - 1) & 0xffff)) {
  802. if (debug) printk(KERN_DEBUG "Expecting bottom %d, got %d\n", wc->canary - 1, oldcan & 0xffff);
  803. wc->span.irqmisses++;
  804. }
  805. for (y=0;y<DAHDI_CHUNKSIZE;y++) {
  806. for (x=0;x<wc->span.channels;x++) {
  807. /* XXX Optimize, remove * and + XXX */
  808. /* Must map received channels into appropriate data */
  809. wc->chans[x]->readchunk[y] =
  810. rxbuf[32 * y + ((wc->chanmap[x] + WC_OFFSET + wc->offset) & 0x1f)];
  811. }
  812. if (!wc->ise1) {
  813. for (x=3;x<32;x+=4) {
  814. if (rxbuf[32 * y + ((x + WC_OFFSET) & 0x1f)] == 0x7f) {
  815. if (wc->offset != (x-3)) {
  816. /* Resync */
  817. control_set_reg(wc, WC_CLOCK, 0x02 | wc->sync | wc->ise1);
  818. wc->clocktimeout = 100;
  819. #if 1
  820. if (debug) printk(KERN_DEBUG "T1: Lost our place, resyncing\n");
  821. #endif
  822. }
  823. }
  824. }
  825. } else {
  826. if (!wc->clocktimeout && !wc->span.alarms) {
  827. if ((rxbuf[32 * y + ((3 + WC_OFFSET + wc->offset) & 0x1f)] & 0x7f) != 0x1b) {
  828. if (wc->miss) {
  829. if (debug) printk(KERN_DEBUG "Double miss (%d, %d)...\n", wc->misslast, rxbuf[32 * y + ((3 + WC_OFFSET + wc->offset) & 0x1f)]);
  830. control_set_reg(wc, WC_CLOCK, 0x02 | wc->sync | wc->ise1);
  831. wc->clocktimeout = 100;
  832. } else {
  833. wc->miss = 1;
  834. wc->misslast = rxbuf[32 * y + ((3 + WC_OFFSET + wc->offset) & 0x1f)];
  835. }
  836. } else {
  837. wc->miss = 0;
  838. }
  839. } else {
  840. wc->miss = 0;
  841. }
  842. }
  843. }
  844. /* Store the next canary */
  845. canary = (unsigned int *)(rxbuf + DAHDI_CHUNKSIZE * 32 - 4);
  846. *canary = (wc->canary++) | (CANARY << 16);
  847. for (x=0;x<wc->span.channels;x++) {
  848. dahdi_ec_chunk(wc->chans[x], wc->chans[x]->readchunk, wc->ec_chunk2[x]);
  849. memcpy(wc->ec_chunk2[x],wc->ec_chunk1[x],DAHDI_CHUNKSIZE);
  850. memcpy(wc->ec_chunk1[x],wc->chans[x]->writechunk,DAHDI_CHUNKSIZE);
  851. }
  852. dahdi_receive(&wc->span);
  853. }
  854. static void t1xxp_check_sigbits(struct t1xxp *wc, int x)
  855. {
  856. int a,b,i,y,rxs;
  857. unsigned long flags;
  858. spin_lock_irqsave(&wc->lock, flags);
  859. if (wc->ise1) {
  860. /* Read 5 registers at a time, loading 10 channels at a time */
  861. for (i = (x * 5); i < (x * 5) + 5; i++) {
  862. a = __t1_get_reg(wc, 0x31 + i);
  863. /* Get high channel in low bits */
  864. rxs = (a & 0xf);
  865. if (!(wc->chans[i+16]->sig & DAHDI_SIG_CLEAR)) {
  866. if (wc->chans[i+16]->rxsig != rxs) {
  867. spin_unlock_irqrestore(&wc->lock, flags);
  868. dahdi_rbsbits(wc->chans[i+16], rxs);
  869. spin_lock_irqsave(&wc->lock, flags);
  870. }
  871. }
  872. rxs = (a >> 4) & 0xf;
  873. if (!(wc->chans[i]->sig & DAHDI_SIG_CLEAR)) {
  874. if (wc->chans[i]->rxsig != rxs) {
  875. spin_unlock_irqrestore(&wc->lock, flags);
  876. dahdi_rbsbits(wc->chans[i], rxs);
  877. spin_lock_irqsave(&wc->lock, flags);
  878. }
  879. }
  880. }
  881. } else {
  882. a = __t1_get_reg(wc, 0x60 + x);
  883. b = __t1_get_reg(wc, 0x63 + x);
  884. for (y=0;y<8;y++) {
  885. i = x * 8 + y;
  886. rxs = 0;
  887. if (a & (1 << y))
  888. rxs |= DAHDI_ABIT;
  889. if (b & (1 << y))
  890. rxs |= DAHDI_BBIT;
  891. if (!(wc->chans[i]->sig & DAHDI_SIG_CLEAR)) {
  892. if (wc->chans[i]->rxsig != rxs) {
  893. spin_unlock_irqrestore(&wc->lock, flags);
  894. dahdi_rbsbits(wc->chans[i], rxs);
  895. spin_lock_irqsave(&wc->lock, flags);
  896. }
  897. }
  898. }
  899. }
  900. spin_unlock_irqrestore(&wc->lock, flags);
  901. }
  902. static void t1xxp_check_alarms(struct t1xxp *wc)
  903. {
  904. unsigned char c,d;
  905. int alarms;
  906. int x,j;
  907. unsigned long flags;
  908. spin_lock_irqsave(&wc->lock, flags);
  909. if (wc->ise1) {
  910. __t1_set_reg(wc, 0x06, 0xff);
  911. c = __t1_get_reg(wc, 0x6);
  912. } else {
  913. /* Get RIR2 */
  914. c = __t1_get_reg(wc, 0x31);
  915. wc->span.rxlevel = c >> 6;
  916. /* Get status register s*/
  917. __t1_set_reg(wc, 0x20, 0xff);
  918. c = __t1_get_reg(wc, 0x20);
  919. }
  920. /* Assume no alarms */
  921. alarms = 0;
  922. /* And consider only carrier alarms */
  923. wc->span.alarms &= (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE | DAHDI_ALARM_NOTOPEN);
  924. if (wc->ise1) {
  925. /* XXX Implement me XXX */
  926. } else {
  927. /* Detect loopup code if we're not sending one */
  928. if ((!wc->span.mainttimer) && (c & 0x80)) {
  929. /* Loop-up code detected */
  930. if ((wc->loopupcnt++ > 80) && (wc->span.maintstat != DAHDI_MAINT_REMOTELOOP)) {
  931. __t1_set_reg(wc, 0x1e, 0); /* No local loop */
  932. __t1_set_reg(wc, 0x0a, 0x40); /* Remote Loop */
  933. wc->span.maintstat = DAHDI_MAINT_REMOTELOOP;
  934. }
  935. } else {
  936. wc->loopupcnt = 0;
  937. }
  938. /* Same for loopdown code */
  939. if ((!wc->span.mainttimer) && (c & 0x40)) {
  940. /* Loop-down code detected */
  941. if ((wc->loopdowncnt++ > 80) && (wc->span.maintstat == DAHDI_MAINT_REMOTELOOP)) {
  942. __t1_set_reg(wc, 0x1e, 0); /* No local loop */
  943. __t1_set_reg(wc, 0x0a, 0x0); /* No remote Loop */
  944. wc->span.maintstat = DAHDI_MAINT_NONE;
  945. }
  946. } else
  947. wc->loopdowncnt = 0;
  948. }
  949. if (wc->span.lineconfig & DAHDI_CONFIG_NOTOPEN) {
  950. for (x=0,j=0;x < wc->span.channels;x++)
  951. if ((wc->chans[x]->flags & DAHDI_FLAG_OPEN) ||
  952. (wc->chans[x]->flags & DAHDI_FLAG_NETDEV))
  953. j++;
  954. if (!j)
  955. alarms |= DAHDI_ALARM_NOTOPEN;
  956. }
  957. if (wc->ise1) {
  958. if (c & 0x9)
  959. alarms |= DAHDI_ALARM_RED;
  960. if (c & 0x2)
  961. alarms |= DAHDI_ALARM_BLUE;
  962. } else {
  963. /* Check actual alarm status */
  964. if (c & 0x3)
  965. alarms |= DAHDI_ALARM_RED;
  966. if (c & 0x8)
  967. alarms |= DAHDI_ALARM_BLUE;
  968. }
  969. /* Keep track of recovering */
  970. if ((!alarms) && wc->span.alarms)
  971. wc->alarmtimer = DAHDI_ALARMSETTLE_TIME;
  972. /* If receiving alarms, go into Yellow alarm state */
  973. if (alarms && (!wc->span.alarms)) {
  974. #if 0
  975. printk(KERN_DEBUG "Going into yellow alarm\n");
  976. #endif
  977. if (wc->ise1)
  978. __t1_set_reg(wc, 0x21, 0x7f);
  979. else
  980. __t1_set_reg(wc, 0x35, 0x11);
  981. }
  982. if (wc->span.alarms != alarms) {
  983. d = __control_get_reg(wc, WC_CLOCK);
  984. start_alarm(wc);
  985. if (!(alarms & (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE | DAHDI_ALARM_LOOPBACK)) &&
  986. wc->sync) {
  987. /* Use the receive signalling */
  988. wc->span.syncsrc = wc->span.spanno;
  989. d |= 1;
  990. } else {
  991. wc->span.syncsrc = 0;
  992. d &= ~1;
  993. }
  994. __control_set_reg(wc, WC_CLOCK, d);
  995. }
  996. if (wc->alarmtimer)
  997. alarms |= DAHDI_ALARM_RECOVER;
  998. if (c & 0x4)
  999. alarms |= DAHDI_ALARM_YELLOW;
  1000. wc->span.alarms = alarms;
  1001. spin_unlock_irqrestore(&wc->lock, flags);
  1002. dahdi_alarm_notify(&wc->span);
  1003. }
  1004. static void t1xxp_do_counters(struct t1xxp *wc)
  1005. {
  1006. unsigned long flags;
  1007. spin_lock_irqsave(&wc->lock, flags);
  1008. if (wc->alarmtimer) {
  1009. if (!--wc->alarmtimer) {
  1010. wc->span.alarms &= ~(DAHDI_ALARM_RECOVER);
  1011. /* Clear yellow alarm */
  1012. #if 0
  1013. printk(KERN_DEBUG "Coming out of alarm\n");
  1014. #endif
  1015. if (wc->ise1)
  1016. __t1_set_reg(wc, 0x21, 0x5f);
  1017. else
  1018. __t1_set_reg(wc, 0x35, 0x10);
  1019. spin_unlock_irqrestore(&wc->lock, flags);
  1020. dahdi_alarm_notify(&wc->span);
  1021. spin_lock_irqsave(&wc->lock, flags);
  1022. }
  1023. }
  1024. spin_unlock_irqrestore(&wc->lock, flags);
  1025. }
  1026. DAHDI_IRQ_HANDLER(t1xxp_interrupt)
  1027. {
  1028. struct t1xxp *wc = dev_id;
  1029. unsigned char ints;
  1030. unsigned long flags;
  1031. int x;
  1032. ints = inb(wc->ioaddr + WC_INTSTAT);
  1033. if (!ints)
  1034. return IRQ_NONE;
  1035. outb(ints, wc->ioaddr + WC_INTSTAT);
  1036. if (!wc->intcount) {
  1037. if (debug) printk(KERN_DEBUG "Got interrupt: 0x%04x\n", ints);
  1038. }
  1039. wc->intcount++;
  1040. if (wc->clocktimeout && !--wc->clocktimeout)
  1041. control_set_reg(wc, WC_CLOCK, 0x00 | wc->sync | wc->ise1);
  1042. if (ints & 0x0f) {
  1043. t1xxp_receiveprep(wc, ints);
  1044. t1xxp_transmitprep(wc, ints);
  1045. }
  1046. spin_lock_irqsave(&wc->lock, flags);
  1047. #if 1
  1048. __handle_leds(wc);
  1049. #endif
  1050. spin_unlock_irqrestore(&wc->lock, flags);
  1051. /* Count down timers */
  1052. t1xxp_do_counters(wc);
  1053. /* Do some things that we don't have to do very often */
  1054. x = wc->intcount & 15 /* 63 */;
  1055. switch(x) {
  1056. case 0:
  1057. case 1:
  1058. case 2:
  1059. t1xxp_check_sigbits(wc, x);
  1060. break;
  1061. case 4:
  1062. /* Check alarms 1/4 as frequently */
  1063. if (!(wc->intcount & 0x30))
  1064. t1xxp_check_alarms(wc);
  1065. break;
  1066. }
  1067. if (ints & 0x10)
  1068. printk(KERN_INFO "PCI Master abort\n");
  1069. if (ints & 0x20)
  1070. printk(KERN_INFO "PCI Target abort\n");
  1071. return IRQ_RETVAL(1);
  1072. }
  1073. static int t1xxp_hardware_init(struct t1xxp *wc)
  1074. {
  1075. /* Hardware PCI stuff */
  1076. /* Reset chip and registers */
  1077. outb(DELAY | 0x0e, wc->ioaddr + WC_CNTL);
  1078. /* Set all outputs to 0 */
  1079. outb(0x00, wc->ioaddr + WC_AUXD);
  1080. /* Set all to outputs except AUX1 (TDO). */
  1081. outb(0xfd, wc->ioaddr + WC_AUXC);
  1082. /* Configure the serial port: double clock, 20ns width, no inversion,
  1083. MSB first */
  1084. outb(0xc8, wc->ioaddr + WC_SERC);
  1085. /* Internally delay FSC by one */
  1086. outb(0x01, wc->ioaddr + WC_FSCDELAY);
  1087. /* Back to normal, with automatic DMA wrap around */
  1088. outb(DELAY | 0x01, wc->ioaddr + WC_CNTL);
  1089. /* Make sure serial port and DMA are out of reset */
  1090. outb(inb(wc->ioaddr + WC_CNTL) & 0xf9, WC_CNTL);
  1091. /* Setup DMA Addresses */
  1092. /* Start at writedma */
  1093. outl(wc->writedma, wc->ioaddr + WC_DMAWS); /* Write start */
  1094. /* First frame */
  1095. outl(wc->writedma + DAHDI_CHUNKSIZE * 32 - 4, wc->ioaddr + WC_DMAWI); /* Middle (interrupt) */
  1096. /* Second frame */
  1097. outl(wc->writedma + DAHDI_CHUNKSIZE * 32 * 2 - 4, wc->ioaddr + WC_DMAWE); /* End */
  1098. outl(wc->readdma, wc->ioaddr + WC_DMARS); /* Read start */
  1099. /* First frame */
  1100. outl(wc->readdma + DAHDI_CHUNKSIZE * 32 - 4, wc->ioaddr + WC_DMARI); /* Middle (interrupt) */
  1101. /* Second frame */
  1102. outl(wc->readdma + DAHDI_CHUNKSIZE * 32 * 2 - 4, wc->ioaddr + WC_DMARE); /* End */
  1103. if (debug) printk(KERN_DEBUG "Setting up DMA (write/read = %08lx/%08lx)\n", (long)wc->writedma, (long)wc->readdma);
  1104. /* Check out the controller */
  1105. if (debug) printk(KERN_DEBUG "Controller version: %02x\n", control_get_reg(wc, WC_VERSION));
  1106. control_set_reg(wc, WC_LEDTEST, 0x00);
  1107. /* Sanity check also determines e1 or t1 */
  1108. if (t1xxp_framer_sanity_check(wc))
  1109. return -1;
  1110. if (wc->ise1)
  1111. wc->chanmap = chanmap_e1;
  1112. else
  1113. wc->chanmap = chanmap_t1;
  1114. /* Setup clock appropriately */
  1115. control_set_reg(wc, WC_CLOCK, 0x02 | wc->sync | wc->ise1);
  1116. wc->clocktimeout = 100;
  1117. /* Reset the T1 and report */
  1118. t1xxp_framer_hard_reset(wc);
  1119. start_alarm(wc);
  1120. return 0;
  1121. }
  1122. static int __devinit t1xxp_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
  1123. {
  1124. struct t1xxp *wc;
  1125. unsigned int *canary;
  1126. unsigned int x;
  1127. if (pci_enable_device(pdev)) {
  1128. printk(KERN_ERR "%s: pci_enable_device failed\n", __FUNCTION__);
  1129. return -EIO;
  1130. }
  1131. if (!(wc = kmalloc(sizeof(*wc), GFP_KERNEL))) {
  1132. printk(KERN_ERR "%s: Failed allocation a wc\n", __FUNCTION__);
  1133. return -ENOMEM;
  1134. }
  1135. memset(wc, 0x0, sizeof(*wc));
  1136. spin_lock_init(&wc->lock);
  1137. wc->ioaddr = pci_resource_start(pdev, 0);
  1138. wc->dev = pdev;
  1139. wc->offset = 28; /* And you thought 42 was the answer */
  1140. wc->writechunk =
  1141. /* 32 channels, Double-buffer, Read/Write */
  1142. (unsigned char *)pci_alloc_consistent(pdev, DAHDI_MAX_CHUNKSIZE * 32 * 2 * 2, &wc->writedma);
  1143. if (!wc->writechunk) {
  1144. printk(KERN_NOTICE "wct1xxp: Unable to allocate DMA-able memory\n");
  1145. return -ENOMEM;
  1146. }
  1147. /* Read is after the whole write piece (in bytes) */
  1148. wc->readchunk = wc->writechunk + DAHDI_CHUNKSIZE * 32 * 2;
  1149. /* Same thing... */
  1150. wc->readdma = wc->writedma + DAHDI_CHUNKSIZE * 32 * 2;
  1151. /* Initialize Write/Buffers to all blank data */
  1152. memset((void *)wc->writechunk,0x00,DAHDI_MAX_CHUNKSIZE * 2 * 2 * 32);
  1153. /* Initialize canary */
  1154. canary = (unsigned int *)(wc->readchunk + DAHDI_CHUNKSIZE * 64 - 4);
  1155. *canary = (CANARY << 16) | (0xffff);
  1156. /* Enable bus mastering */
  1157. pci_set_master(pdev);
  1158. /* Keep track of which device we are */
  1159. pci_set_drvdata(pdev, wc);
  1160. if (request_irq(pdev->irq, t1xxp_interrupt, DAHDI_IRQ_SHARED_DISABLED, "t1xxp", wc)) {
  1161. printk(KERN_NOTICE "t1xxp: Unable to request IRQ %d\n", pdev->irq);
  1162. kfree(wc);
  1163. return -EIO;
  1164. }
  1165. /* Initialize hardware */
  1166. t1xxp_hardware_init(wc);
  1167. /* We now know which version of card we have */
  1168. if (wc->ise1) {
  1169. wc->variety = "Digium Wildcard E100P E1/PRA";
  1170. } else {
  1171. wc->variety = "Digium Wildcard T100P T1/PRI";
  1172. }
  1173. for (x = 0; x < (wc->ise1 ? 31 : 24); x++) {
  1174. if (!(wc->chans[x] = kmalloc(sizeof(*wc->chans[x]), GFP_KERNEL))) {
  1175. while (x) {
  1176. kfree(wc->chans[--x]);
  1177. }
  1178. kfree(wc);
  1179. return -ENOMEM;
  1180. }
  1181. memset(wc->chans[x], 0, sizeof(*wc->chans[x]));
  1182. }
  1183. /* Misc. software stuff */
  1184. t1xxp_software_init(wc);
  1185. printk(KERN_INFO "Found a Wildcard: %s\n", wc->variety);
  1186. return 0;
  1187. }
  1188. static void t1xxp_stop_stuff(struct t1xxp *wc)
  1189. {
  1190. /* Kill clock */
  1191. control_set_reg(wc, WC_CLOCK, 0);
  1192. /* Turn off LED's */
  1193. control_set_reg(wc, WC_LEDTEST, 0);
  1194. /* Reset the T1 */
  1195. t1xxp_framer_hard_reset(wc);
  1196. }
  1197. static void __devexit t1xxp_remove_one(struct pci_dev *pdev)
  1198. {
  1199. struct t1xxp *wc = pci_get_drvdata(pdev);
  1200. if (wc) {
  1201. /* Stop any DMA */
  1202. __t1xxp_stop_dma(wc);
  1203. /* In case hardware is still there */
  1204. __t1xxp_disable_interrupts(wc);
  1205. t1xxp_stop_stuff(wc);
  1206. /* Immediately free resources */
  1207. pci_free_consistent(pdev, DAHDI_MAX_CHUNKSIZE * 2 * 2 * 32 * 4, (void *)wc->writechunk, wc->writedma);
  1208. free_irq(pdev->irq, wc);
  1209. /* Reset PCI chip and registers */
  1210. outb(DELAY | 0x0e, wc->ioaddr + WC_CNTL);
  1211. /* Release span, possibly delayed */
  1212. if (!wc->usecount)
  1213. t1xxp_release(wc);
  1214. else
  1215. wc->dead = 1;
  1216. }
  1217. }
  1218. static DEFINE_PCI_DEVICE_TABLE(t1xxp_pci_tbl) = {
  1219. { 0xe159, 0x0001, 0x6159, PCI_ANY_ID, 0, 0, (unsigned long) "Digium Wildcard T100P T1/PRI or E100P E1/PRA Board" },
  1220. { 0 }
  1221. };
  1222. MODULE_DEVICE_TABLE(pci,t1xxp_pci_tbl);
  1223. static struct pci_driver t1xxp_driver = {
  1224. .name = "t1xxp",
  1225. .probe = t1xxp_init_one,
  1226. .remove = __devexit_p(t1xxp_remove_one),
  1227. .suspend = NULL,
  1228. .resume = NULL,
  1229. . id_table = t1xxp_pci_tbl,
  1230. };
  1231. static int __init t1xxp_init(void)
  1232. {
  1233. int res;
  1234. res = dahdi_pci_module(&t1xxp_driver);
  1235. if (res)
  1236. return -ENODEV;
  1237. return 0;
  1238. }
  1239. static void __exit t1xxp_cleanup(void)
  1240. {
  1241. pci_unregister_driver(&t1xxp_driver);
  1242. }
  1243. module_param(debug, int, 0600);
  1244. MODULE_DESCRIPTION("Wildcard T100P/E100P Driver");
  1245. MODULE_AUTHOR("Mark Spencer <markster@digium.com>");
  1246. MODULE_LICENSE("GPL v2");
  1247. module_init(t1xxp_init);
  1248. module_exit(t1xxp_cleanup);