1 /*-
2  * DDK library for Cronyx-Tau adapters.
3  *
4  * Copyright (C) 1998-1999 Cronyx Engineering.
5  * Author: Alexander Kvitchenko, <aak@cronyx.ru>
6  *
7  * Copyright (C) 1999-2003 Cronyx Engineering.
8  * Author: Roman Kurakin, <rik@cronyx.ru>
9  *
10  * This source is derived from
11  * Diagnose utility for Cronyx-Tau adapter:
12  * by Serge Vakulenko, <vak@cronyx.ru>
13  *
14  * This software is distributed with NO WARRANTIES, not even the implied
15  * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  *
17  * Authors grant any other persons or organisations permission to use
18  * or modify this software as long as this message is kept with the software,
19  * all derivative works or modified versions.
20  *
21  * Cronyx Id: ctddk.c,v 1.1.2.3 2003/11/14 16:55:36 rik Exp $
22  */
23 #include <sys/cdefs.h>
24 __FBSDID("$FreeBSD: stable/10/sys/dev/ctau/ctddk.c 139749 2005-01-06 01:43:34Z imp $");
25 
26 #include <dev/cx/machdep.h>
27 #include <dev/ctau/ctddk.h>
28 #include <dev/ctau/ctaureg.h>
29 #include <dev/ctau/hdc64570.h>
30 #include <dev/ctau/ds2153.h>
31 #include <dev/ctau/am8530.h>
32 #include <dev/ctau/lxt318.h>
33 #include <dev/cx/cronyxfw.h>
34 #include <dev/ctau/ctaufw.h>
35 #include <dev/ctau/ctau2fw.h>
36 
37 #ifndef CT_DDK_NO_G703
38 #include <dev/ctau/ctaug7fw.h>
39 #endif
40 
41 #ifndef CT_DDK_NO_E1
42 #include <dev/ctau/ctaue1fw.h>
43 #endif
44 
45 static void ct_hdlc_interrupt (ct_chan_t *c, int imvr);
46 static void ct_e1_interrupt (ct_board_t *b);
47 static void ct_scc_interrupt (ct_board_t *b);
48 static void ct_e1timer_interrupt (ct_chan_t *c);
49 
50 static short porttab [] = {	       /* standard base port set */
51 	0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0,
52 	0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0x3c0, 0x3e0, 0
53 };
54 
ct_find(port_t * board_ports)55 int ct_find (port_t *board_ports)
56 {
57 	int i, n;
58 
59 	for (i=0, n=0; porttab[i] && n<NBRD; i++)
60 		if (ct_probe_board (porttab[i], -1, -1))
61 			board_ports[n++] = porttab[i];
62 	return n;
63 }
64 
ct_open_board(ct_board_t * b,int num,port_t port,int irq,int dma)65 int ct_open_board (ct_board_t *b, int num, port_t port, int irq, int dma)
66 {
67 	ct_chan_t *c;
68 	const unsigned char *fw;
69 	const cr_dat_tst_t *ft;
70 	long flen;
71 
72 	if (num >= NBRD || ! ct_probe_board (port, irq, dma))
73 		return 0;
74 
75 	/* init callback pointers */
76 	for (c=b->chan; c<b->chan+NCHAN; ++c) {
77 		c->call_on_tx = 0;
78 		c->call_on_rx = 0;
79 		c->call_on_msig = 0;
80 		c->call_on_scc = 0;
81 		c->call_on_err = 0;
82 	}
83 
84 	/* init DDK channel variables */
85 	for (c=b->chan; c<b->chan+NCHAN; ++c) {
86 		c->sccrx_empty = c->scctx_empty = 1;
87 		c->sccrx_b = c->sccrx_e = 0;
88 		c->scctx_b = c->scctx_e = 0;
89 		c->e1_first_int = 1;
90 	}
91 
92 	/* init board structure */
93 	ct_init (b, num, port, irq, dma, ctau_fw_data,
94 		ctau_fw_len, ctau_fw_tvec, ctau2_fw_data);
95 
96 	/* determine which firmware should be loaded */
97 	fw = ctau_fw_data;
98 	flen = ctau_fw_len;
99 	ft = ctau_fw_tvec;
100 	switch (b->type) {
101 	case B_TAU2:
102 	case B_TAU2_G703:
103 	case B_TAU2_E1:
104 	case B_TAU2_E1D:
105 		fw = ctau2_fw_data;
106 		flen = 0;
107 		ft = 0;
108 		break;
109 #ifndef CT_DDK_NO_G703
110 	case B_TAU_G703:
111 		fw = ctaug703_fw_data;
112 		flen = ctaug703_fw_len;
113 		ft = ctaug703_fw_tvec;
114 		break;
115 #endif
116 #ifndef CT_DDK_NO_E1
117 	case B_TAU_E1:
118 		fw = ctaue1_fw_data;
119 		flen = ctaue1_fw_len;
120 		ft = ctaue1_fw_tvec;
121 		break;
122 #endif
123 	}
124 	/* Load firmware and set up board */
125 	return ct_setup_board (b, fw, flen, ft);
126 }
127 
128 /*
129  * must be called on the exit
130  */
ct_close_board(ct_board_t * b)131 void ct_close_board (ct_board_t *b)
132 {
133 	ct_setup_board (b, 0, 0, 0);
134 
135 	/* Reset the controller. */
136 	outb (BCR0(b->port), 0);
137 
138 	/* Disable DMA channel. */
139 	ct_disable_dma (b);
140 
141 	ct_led (b, 0);
142 }
143 
ct_g703_rate(ct_chan_t * c,unsigned long rate)144 static void ct_g703_rate (ct_chan_t *c, unsigned long rate)
145 {
146 	c->gopt.rate = rate;
147 	ct_setup_g703 (c->board);
148 }
149 
150 /*
151  * Set up baud rate.
152  */
ct_chan_baud(ct_chan_t * c,unsigned long baud)153 static void ct_chan_baud (ct_chan_t *c, unsigned long baud)
154 {
155 	c->baud = baud;
156 	if (baud) {
157 		c->hopt.txs = CLK_INT;
158 	} else {
159 		ct_set_dpll (c, 0);
160 		c->hopt.txs = CLK_LINE;
161 	}
162 	ct_update_chan (c);
163 }
164 
ct_set_baud(ct_chan_t * c,unsigned long baud)165 void ct_set_baud (ct_chan_t *c, unsigned long baud)
166 {
167 	unsigned long r;
168 
169 	if (c->mode == M_E1)
170 		return;
171 	if (c->mode == M_G703) {
172 		if	(baud >= 2048000)  r = 2048;
173 		else if (baud >= 1024000)  r = 1024;
174 		else if (baud >= 512000)   r = 512;
175 		else if (baud >= 256000)   r = 256;
176 		else if (baud >= 128000)   r = 128;
177 		else			   r = 64;
178 		ct_g703_rate (c, r);
179 	} else
180 		ct_chan_baud (c, baud);
181 }
182 
183 /*
184  * Configure Tau/E1 board.
185  */
ct_e1_config(ct_board_t * b,unsigned char cfg)186 static void ct_e1_config (ct_board_t *b, unsigned char cfg)
187 {
188 	if (cfg == b->opt.cfg)
189 		return;
190 
191 	if (cfg == CFG_B)
192 		b->chan[1].mode = M_HDLC;
193 	else
194 		b->chan[1].mode = M_E1;
195 
196 	/* Recovering synchronization */
197 	if (b->opt.cfg == CFG_B) {
198 		ct_chan_baud (b->chan+1, 0);
199 		ct_set_invtxc (b->chan+1, 0);
200 		ct_set_invrxc (b->chan+1, 0);
201 		ct_set_nrzi (b->chan+1, 0);
202 	}
203 	b->opt.cfg = cfg;
204 	ct_setup_e1 (b);
205 }
206 
207 /*
208  * Config Tau/G.703 board
209  */
ct_g703_config(ct_board_t * b,unsigned char cfg)210 static void ct_g703_config (ct_board_t *b, unsigned char cfg)
211 {
212 	if (cfg == b->opt.cfg)
213 		return;
214 
215 	if (cfg == CFG_B)
216 		b->chan[1].mode = M_HDLC;
217 	else
218 		b->chan[1].mode = M_G703;
219 
220 	/* Recovering synchronization */
221 	if (b->opt.cfg == CFG_B) {
222 		ct_chan_baud (b->chan+1, 0);
223 		ct_set_invtxc (b->chan+1, 0);
224 		ct_set_invrxc (b->chan+1, 0);
225 		ct_set_nrzi (b->chan+1, 0);
226 	}
227 	b->opt.cfg = cfg;
228 	ct_setup_g703 (b);
229 }
230 
ct_set_clk(ct_chan_t * c,int clk)231 int ct_set_clk (ct_chan_t *c, int clk)
232 {
233 	if (c->num)
234 		c->board->opt.clk1 = clk;
235 	else
236 		c->board->opt.clk0 = clk;
237 	if (c->mode == M_E1) {
238 		ct_setup_e1 (c->board);
239 		return 0;
240 	} if (c->mode == M_G703) {
241 		ct_setup_g703 (c->board);
242 		return 0;
243 	} else
244 		return -1;
245 }
246 
ct_get_clk(ct_chan_t * c)247 int ct_get_clk (ct_chan_t *c)
248 {
249 	return c->num ? c->board->opt.clk1 : c->board->opt.clk0;
250 }
251 
ct_set_ts(ct_chan_t * c,unsigned long ts)252 int ct_set_ts (ct_chan_t *c, unsigned long ts)
253 {
254 	if (! (c->mode == M_E1))
255 		return -1;
256 	if (c->num)
257 		c->board->opt.s1 = ts;
258 	else
259 		c->board->opt.s0 = ts;
260 	ct_setup_e1 (c->board);
261 	return 0;
262 }
263 
ct_set_subchan(ct_board_t * b,unsigned long ts)264 int ct_set_subchan (ct_board_t *b, unsigned long ts)
265 {
266 	if (b->chan[0].mode != M_E1)
267 		return -1;
268 	b->opt.s2 = ts;
269 	ct_setup_e1 (b);
270 	return 0;
271 }
272 
ct_set_higain(ct_chan_t * c,int on)273 int ct_set_higain (ct_chan_t *c, int on)
274 {
275 	if (! (c->mode == M_E1))
276 		return -1;
277 	c->gopt.higain = on ? 1 : 0;
278 	ct_setup_e1 (c->board);
279 	return 0;
280 }
281 
282 /*
283  * Start service channel.
284  */
ct_start_scc(ct_chan_t * c,char * rxbuf,char * txbuf)285 void ct_start_scc (ct_chan_t *c, char *rxbuf, char *txbuf)
286 {
287 	c->sccrx = rxbuf;
288 	c->scctx = txbuf;
289 
290 	/* Enable interrupts from service channel. */
291 	if (c->board->type != B_TAU_E1 && c->board->type != B_TAU_E1C &&
292 	    c->board->type != B_TAU2_E1)
293 		return;
294 
295 	cte_out2 (c->board->port, c->num ? AM_IMR : AM_IMR | AM_A,
296 		 IMR_TX | IMR_RX_ALL);
297 	cte_out2 (c->board->port, AM_MICR, MICR_MIE);
298 }
299 
300 /*
301  * Start HDLC channel.
302  */
ct_start_chan(ct_chan_t * c,ct_buf_t * cb,unsigned long phys)303 void ct_start_chan (ct_chan_t *c, ct_buf_t *cb, unsigned long phys)
304 {
305 	int i, ier0;
306 	unsigned long bound;
307 
308 	if (cb) {
309 		/* Set up descriptors, align to 64k boundary.
310 		 * If 64k boundary is inside buffers
311 		 * buffers will begin on this boundary
312 		 * (there were allocated additional space for this) */
313 		c->tdesc = cb->descbuf;
314 		c->tdphys[0] = phys + ((char*)c->tdesc - (char*)cb);
315 		bound = ((c->tdphys[0] + 0xffff) & ~(0xffffUL));
316 		if (bound < c->tdphys[0] + 2*NBUF*sizeof(ct_desc_t)) {
317 			c->tdesc = (ct_desc_t*) ((char*) c->tdesc +
318 				(bound - c->tdphys[0]));
319 			c->tdphys[0] = bound;
320 		}
321 		c->rdesc = c->tdesc + NBUF;
322 
323 		/* Set buffers. */
324 		for (i=0; i<NBUF; ++i) {
325 			c->rbuf[i] = cb->rbuffer[i];
326 			c->tbuf[i] = cb->tbuffer[i];
327 		}
328 
329 		/* Set buffer physical addresses */
330 		for (i=0; i<NBUF; ++i) {
331 			c->rphys[i] = phys + ((char*)c->rbuf[i] - (char*)cb);
332 			c->tphys[i] = phys + ((char*)c->tbuf[i] - (char*)cb);
333 			c->rdphys[i] = phys + ((char*)(c->rdesc+i) - (char*)cb);
334 			c->tdphys[i] = phys + ((char*)(c->tdesc+i) - (char*)cb);
335 		}
336 	}
337 	/* Set up block chains. */
338 	/* receive buffers */
339 	for (i=0; i<NBUF; ++i) {
340 		B_NEXT (c->rdesc[i]) = c->rdphys[(i+1) % NBUF] & 0xffff;
341 		B_PTR (c->rdesc[i]) = c->rphys[i];
342 		B_LEN (c->rdesc[i]) = DMABUFSZ;
343 		B_STATUS (c->rdesc[i]) = 0;
344 	}
345 	/* transmit buffers */
346 	for (i=0; i<NBUF; ++i) {
347 		B_NEXT (c->tdesc[i]) = c->tdphys[(i+1) % NBUF] & 0xffff;
348 		B_PTR (c->tdesc[i]) = c->tphys[i];
349 		B_LEN (c->tdesc[i]) = DMABUFSZ;
350 		B_STATUS (c->tdesc[i]) = FST_EOM;
351 		c->attach[i] = 0;
352 	}
353 
354 	if (c->type & T_E1) {
355 		c->mode = M_E1;
356 		if (c->num && c->board->opt.cfg == CFG_B)
357 			c->mode = M_HDLC;
358 	}
359 	if (c->type & T_G703) {
360 		c->mode = M_G703;
361 		if (c->num && c->board->opt.cfg == CFG_B)
362 			c->mode = M_HDLC;
363 	}
364 	ct_update_chan (c);
365 
366 	/* enable receiver */
367 	c->rn = 0;
368 	ct_start_receiver (c, 1 , c->rphys[0], DMABUFSZ, c->rdphys[0],
369 		c->rdphys[NBUF-1]);
370 	outb (c->IE1, inb (c->IE1) | IE1_CDCDE);
371 	outb (c->IE0, inb (c->IE0) | IE0_RX_INTE);
372 	ier0 = inb (IER0(c->board->port));
373 	ier0 |= c->num ? IER0_RX_INTE_1 : IER0_RX_INTE_0;
374 	outb (IER0(c->board->port), ier0);
375 
376 	/* Enable transmitter */
377 	c->tn = 0;
378 	c->te = 0;
379 	ct_start_transmitter (c, 1 , c->tphys[0], DMABUFSZ, c->tdphys[0],
380 		c->tdphys[0]);
381 	outb (c->TX.DIR, DIR_CHAIN_EOME | DIR_CHAIN_BOFE | DIR_CHAIN_COFE);
382 
383 	/* Clear DTR and RTS */
384 	ct_set_dtr (c, 0);
385 	ct_set_rts (c, 0);
386 }
387 
388 /*
389  * Turn receiver on/off
390  */
ct_enable_receive(ct_chan_t * c,int on)391 void ct_enable_receive (ct_chan_t *c, int on)
392 {
393 	unsigned char st3, ier0, ier1;
394 
395 	st3 = inb (c->ST3);
396 	/* enable or disable receiver */
397 	if (on && ! (st3 & ST3_RX_ENABLED)) {
398 		c->rn = 0;
399 		ct_start_receiver (c, 1 , c->rphys[0], DMABUFSZ, c->rdphys[0],
400 			c->rdphys[NBUF-1]);
401 		/* enable status interrupt */
402 		outb (c->IE1, inb (c->IE1) | IE1_CDCDE);
403 		outb (c->IE0, inb (c->IE0) | IE0_RX_INTE);
404 		ier0 = inb (IER0(c->board->port));
405 		ier0 |= c->num ? IER0_RX_INTE_1 : IER0_RX_INTE_0;
406 		outb (IER0(c->board->port), ier0);
407 		ct_set_rts (c, 1);
408 	} else if (! on && (st3 & ST3_RX_ENABLED)) {
409 		ct_set_rts (c, 0);
410 		outb (c->CMD, CMD_RX_DISABLE);
411 
412 		ier0 = inb (IER0(c->board->port));
413 		ier0 &= c->num ? ~(IER0_RX_INTE_1 | IER0_RX_RDYE_1) :
414 			~(IER0_RX_INTE_0 | IER0_RX_RDYE_0);
415 		outb (IER0(c->board->port), ier0);
416 
417 		ier1 = inb (IER1(c->board->port));
418 		ier1 &= c->num ? ~(IER1_RX_DMERE_1 | IER1_RX_DME_1) :
419 			~(IER1_RX_DMERE_0 | IER1_RX_DME_0);
420 		outb (IER1(c->board->port), ier1);
421 	}
422 
423 }
424 
425 /*
426  * Turn transmitter on/off
427  */
ct_enable_transmit(ct_chan_t * c,int on)428 void ct_enable_transmit (ct_chan_t *c, int on)
429 {
430 	unsigned char st3, ier0, ier1;
431 
432 	st3 = inb (c->ST3);
433 	/* enable or disable receiver */
434 	if (on && ! (st3 & ST3_TX_ENABLED)) {
435 		c->tn = 0;
436 		c->te = 0;
437 		ct_start_transmitter (c, 1 , c->tphys[0], DMABUFSZ,
438 			c->tdphys[0], c->tdphys[0]);
439 		outb (c->TX.DIR,
440 			DIR_CHAIN_EOME | DIR_CHAIN_BOFE | DIR_CHAIN_COFE);
441 	} else if (! on && (st3 & ST3_TX_ENABLED)) {
442 		outb (c->CMD, CMD_TX_DISABLE);
443 
444 		ier0 = inb (IER0(c->board->port));
445 		ier0 &= c->num ? ~(IER0_TX_INTE_1 | IER0_TX_RDYE_1) :
446 			~(IER0_TX_INTE_0 | IER0_TX_RDYE_0);
447 		outb (IER0(c->board->port), ier0);
448 
449 		ier1 = inb (IER1(c->board->port));
450 		ier1 &= c->num ? ~(IER1_TX_DMERE_1 | IER1_TX_DME_1) :
451 			~(IER1_TX_DMERE_0 | IER1_TX_DME_0);
452 		outb (IER1(c->board->port), ier1);
453 	}
454 
455 }
456 
ct_set_config(ct_board_t * b,int cfg)457 int ct_set_config (ct_board_t *b, int cfg)
458 {
459 	if (b->opt.cfg == cfg)
460 		return 0;
461 	switch (b->type) {
462 	case B_TAU_G703:
463 	case B_TAU_G703C:
464 	case B_TAU2_G703:
465 		if (cfg == CFG_C)
466 			return -1;
467 		ct_g703_config (b, cfg);
468 		return 0;
469 	case B_TAU_E1:
470 	case B_TAU_E1C:
471 	case B_TAU_E1D:
472 	case B_TAU2_E1:
473 	case B_TAU2_E1D:
474 		ct_e1_config (b, cfg);
475 		return 0;
476 	default:
477 		return cfg == CFG_A ? 0 : -1;
478 	}
479 }
480 
ct_get_dpll(ct_chan_t * c)481 int ct_get_dpll (ct_chan_t *c)
482 {
483 	return (c->hopt.rxs == CLK_RXS_DPLL_INT);
484 }
485 
ct_set_dpll(ct_chan_t * c,int on)486 void ct_set_dpll (ct_chan_t *c, int on)
487 {
488 	if (on && ct_get_baud (c))
489 		c->hopt.rxs = CLK_RXS_DPLL_INT;
490 	else
491 		c->hopt.rxs = CLK_LINE;
492 	ct_update_chan (c);
493 }
494 
ct_get_nrzi(ct_chan_t * c)495 int ct_get_nrzi (ct_chan_t *c)
496 {
497 	return (c->opt.md2.encod == MD2_ENCOD_NRZI);
498 }
499 
500 /*
501  * Change line encoding to NRZI, default is NRZ
502  */
ct_set_nrzi(ct_chan_t * c,int on)503 void ct_set_nrzi (ct_chan_t *c, int on)
504 {
505 	c->opt.md2.encod = on ? MD2_ENCOD_NRZI : MD2_ENCOD_NRZ;
506 	outb (c->MD2, *(unsigned char*)&c->opt.md2);
507 }
508 
509 /*
510  * Transmit clock inversion
511  */
ct_set_invtxc(ct_chan_t * c,int on)512 void ct_set_invtxc (ct_chan_t *c, int on)
513 {
514 	if (on) c->board->bcr2 |=  (c->num ? BCR2_INVTXC1 : BCR2_INVTXC0);
515 	else	c->board->bcr2 &= ~(c->num ? BCR2_INVTXC1 : BCR2_INVTXC0);
516 	outb (BCR2(c->board->port), c->board->bcr2);
517 }
518 
ct_get_invtxc(ct_chan_t * c)519 int ct_get_invtxc (ct_chan_t *c)
520 {
521 	return (c->board->bcr2 & (c->num ? BCR2_INVTXC1 : BCR2_INVTXC0)) != 0;
522 }
523 
524 /*
525  * Receive clock inversion
526  */
ct_set_invrxc(ct_chan_t * c,int on)527 void ct_set_invrxc (ct_chan_t *c, int on)
528 {
529 	if (on) c->board->bcr2 |=  (c->num ? BCR2_INVRXC1 : BCR2_INVRXC0);
530 	else	c->board->bcr2 &= ~(c->num ? BCR2_INVRXC1 : BCR2_INVRXC0);
531 	outb (BCR2(c->board->port), c->board->bcr2);
532 }
533 
ct_get_invrxc(ct_chan_t * c)534 int ct_get_invrxc (ct_chan_t *c)
535 {
536 	return (c->board->bcr2 & (c->num ? BCR2_INVRXC1 : BCR2_INVRXC0)) != 0;
537 }
538 
539 /*
540  * Main interrupt handler
541  */
ct_int_handler(ct_board_t * b)542 void ct_int_handler (ct_board_t *b)
543 {
544 	unsigned char bsr0, imvr;
545 	ct_chan_t *c;
546 
547 	while ((bsr0 = inb (BSR0(b->port))) & BSR0_INTR) {
548 		if (bsr0 & BSR0_RDYERR) {
549 			outb (BCR1(b->port), b->bcr1);
550 		} else if (bsr0 & BSR0_GINT) {
551 			if (b->type == B_TAU_E1 || b->type == B_TAU_E1C ||
552 			    b->type == B_TAU_E1D || b->type == B_TAU2_E1 ||
553 			    b->type == B_TAU2_E1D)
554 				ct_e1_interrupt (b);
555 		} else if (bsr0 & BSR0_HDINT) {
556 			/* Read the interrupt modified vector register. */
557 			imvr = inb (IACK(b->port));
558 			c = b->chan + (imvr & IMVR_CHAN1 ? 1 : 0);
559 			ct_hdlc_interrupt (c, imvr);
560 		}
561 	}
562 }
563 
ct_e1_interrupt(ct_board_t * b)564 static void ct_e1_interrupt (ct_board_t *b)
565 {
566 	unsigned char sr;
567 
568 	sr = inb (E1SR(b->port));
569 
570 	if (sr & E1SR_SCC_IRQ) ct_scc_interrupt (b);
571 	if (sr & E1SR_E0_IRQ1) ct_e1timer_interrupt (b->chan + 0);
572 	if (sr & E1SR_E1_IRQ1) ct_e1timer_interrupt (b->chan + 1);
573 }
574 
ct_scc_interrupt(ct_board_t * b)575 static void ct_scc_interrupt (ct_board_t *b)
576 {
577 	unsigned char rsr;
578 	unsigned char ivr, a = AM_A;		/* assume channel A */
579 	ct_chan_t *c = b->chan;
580 
581 	ivr = cte_in2 (b->port, AM_IVR);
582 	if (! (ivr & IVR_A))
583 		++c, a = 0;			/* really channel B */
584 
585 	switch (ivr & IVR_REASON) {
586 	case IVR_TXRDY: 			/* transmitter empty */
587 		c->scctx_b = (c->scctx_b + 1) % SCCBUFSZ;
588 		if (c->scctx_b == c->scctx_e) {
589 			c->scctx_empty = 1;
590 			cte_out2c (c, AM_CR | CR_RST_TXINT);
591 		} else
592 			cte_out2d (c, c->scctx[c->scctx_b]);
593 		break;
594 
595 	case IVR_RXERR: 		/* receive error */
596 	case IVR_RX:			/* receive character available */
597 		rsr = cte_in2 (b->port, a|AM_RSR);
598 
599 		if (rsr & RSR_RXOVRN) { 	/* rx overrun */
600 			if (c->call_on_err)
601 				c->call_on_err (c, CT_SCC_OVERRUN);
602 		} else if (rsr & RSR_FRME) {	/* frame error */
603 			if (c->call_on_err)
604 				c->call_on_err (c, CT_SCC_FRAME);
605 		} else {
606 			c->sccrx[c->sccrx_e] = cte_in2d (c);
607 			c->sccrx_e = (c->sccrx_e + 1) % SCCBUFSZ;
608 			c->sccrx_empty &= 0;
609 			if (c->call_on_scc)
610 				c->call_on_scc (c);
611 			if (c->sccrx_e == c->sccrx_b && ! c->sccrx_empty)
612 				if (c->call_on_err)
613 					c->call_on_err (c, CT_SCC_OVERFLOW);
614 		}
615 		if (rsr)
616 			cte_out2c (c, CR_RST_ERROR);
617 		break;
618 
619 	case IVR_STATUS:		/* external status interrupt */
620 		/* Unexpected SCC status interrupt. */
621 		cte_out2c (c, CR_RST_EXTINT);
622 		break;
623 	}
624 }
625 
626 /*
627  * G.703 mode channel: process 1-second timer interrupts.
628  * Read error and request registers, and fill the status field.
629  */
ct_g703_timer(ct_chan_t * c)630 void ct_g703_timer (ct_chan_t *c)
631 {
632 	int bpv, cd, tsterr, tstreq;
633 
634 	/* Count seconds.
635 	 * During the first second after the channel startup
636 	 * the status registers are not stable yet,
637 	 * we will so skip the first second. */
638 	++c->cursec;
639 	if (c->mode != M_G703)
640 		return;
641 	if (c->totsec + c->cursec <= 1)
642 		return;
643 	c->status = 0;
644 
645 	cd = ct_get_cd (c);
646 
647 	bpv = inb (GERR (c->board->port)) & (c->num ? GERR_BPV1 : GERR_BPV0);
648 	outb (GERR (c->board->port), bpv);
649 
650 	tsterr = inb (GERR (c->board->port)) & (c->num ? GERR_ERR1 : GERR_ERR0);
651 	outb (GERR (c->board->port), tsterr);
652 
653 	tstreq = inb (GLDR (c->board->port)) &
654 		(c->num ? GLDR_LREQ1 : GLDR_LREQ0);
655 	outb (GLDR (c->board->port), tstreq);
656 
657 	/* Compute the SNMP-compatible channel status. */
658 	if (bpv)
659 		++c->currnt.bpv;	  /* bipolar violation */
660 	if (! cd)
661 		c->status |= ESTS_LOS;	  /* loss of signal */
662 	if (tsterr)
663 		c->status |= ESTS_TSTERR; /* test error */
664 	if (tstreq)
665 		c->status |= ESTS_TSTREQ; /* test code detected */
666 
667 	if (! c->status)
668 		c->status = ESTS_NOALARM;
669 
670 	/* Unavaiable second -- loss of carrier, or receiving test code. */
671 	if ((! cd) || tstreq)
672 		/* Unavailable second -- no other counters. */
673 		++c->currnt.uas;
674 	else {
675 		/* Line errored second -- any BPV. */
676 		if (bpv)
677 			++c->currnt.les;
678 
679 		/* Collect data for computing
680 		 * degraded minutes. */
681 		++c->degsec;
682 		if (cd && bpv)
683 			++c->degerr;
684 	}
685 
686 	/* Degraded minutes -- having more than 50% error intervals. */
687 	if (c->cursec / 60 == 0) {
688 		if (c->degerr*2 > c->degsec)
689 			++c->currnt.dm;
690 		c->degsec = 0;
691 		c->degerr = 0;
692 	}
693 
694 	/* Rotate statistics every 15 minutes. */
695 	if (c->cursec > 15*60) {
696 		int i;
697 
698 		for (i=47; i>0; --i)
699 			c->interval[i] = c->interval[i-1];
700 		c->interval[0] = c->currnt;
701 
702 		/* Accumulate total statistics. */
703 		c->total.bpv   += c->currnt.bpv;
704 		c->total.fse   += c->currnt.fse;
705 		c->total.crce  += c->currnt.crce;
706 		c->total.rcrce += c->currnt.rcrce;
707 		c->total.uas   += c->currnt.uas;
708 		c->total.les   += c->currnt.les;
709 		c->total.es    += c->currnt.es;
710 		c->total.bes   += c->currnt.bes;
711 		c->total.ses   += c->currnt.ses;
712 		c->total.oofs  += c->currnt.oofs;
713 		c->total.css   += c->currnt.css;
714 		c->total.dm    += c->currnt.dm;
715 		memset (&c->currnt, 0, sizeof (c->currnt));
716 
717 		c->totsec += c->cursec;
718 		c->cursec = 0;
719 	}
720 }
721 
ct_e1timer_interrupt(ct_chan_t * c)722 static void ct_e1timer_interrupt (ct_chan_t *c)
723 {
724 	unsigned short port;
725 	unsigned char sr1, sr2, ssr;
726 	unsigned long bpv, fas, crc4, ebit, pcv, oof;
727 
728 	port = c->num ? E1CS1(c->board->port) : E1CS0(c->board->port);
729 
730 	sr2 = cte_ins (port, DS_SR2, 0xff);
731 	/* is it timer interrupt ? */
732 	if (! (sr2 & SR2_SEC))
733 		return;
734 
735 	/* first interrupts should be ignored */
736 	if (c->e1_first_int > 0) {
737 		c->e1_first_int --;
738 		return;
739 	}
740 
741 	++c->cursec;
742 	c->status = 0;
743 
744 	/* Compute the SNMP-compatible channel status. */
745 	sr1 = cte_ins (port, DS_SR1, 0xff);
746 	ssr = cte_in (port, DS_SSR);
747 	oof = 0;
748 
749 	if (sr1 & (SR1_RCL | SR1_RLOS))
750 		c->status |= ESTS_LOS;		/* loss of signal */
751 	if (sr1 & SR1_RUA1)
752 		c->status |= ESTS_AIS;		/* receiving all ones */
753 	if (c->gopt.cas && (sr1 & SR1_RSA1))
754 		c->status |= ESTS_AIS16;	/* signaling all ones */
755 	if (c->gopt.cas && (sr1 & SR1_RDMA))
756 		c->status |= ESTS_FARLOMF;	/* alarm in timeslot 16 */
757 	if (sr1 & SR1_RRA)
758 		c->status |= ESTS_FARLOF;	/* far loss of framing */
759 
760 	/* Controlled slip second -- any slip event. */
761 	if (sr1 & SR1_RSLIP) {
762 		++c->currnt.css;
763 	}
764 
765 	if (ssr & SSR_SYNC) {
766 		c->status |= ESTS_LOF;		/* loss of framing */
767 		++oof;				/* out of framing */
768 	}
769 	if ((c->gopt.cas && (ssr & SSR_SYNC_CAS)) ||
770 	    (c->gopt.crc4 && (ssr & SSR_SYNC_CRC4))) {
771 		c->status |= ESTS_LOMF; 	/* loss of multiframing */
772 		++oof;				/* out of framing */
773 	}
774 
775 	if (! c->status)
776 		c->status = ESTS_NOALARM;
777 
778 	/* Get error counters. */
779 	bpv = VCR (cte_in (port, DS_VCR1), cte_in (port, DS_VCR2));
780 	fas = FASCR (cte_in (port, DS_FASCR1), cte_in (port, DS_FASCR2));
781 	crc4 = CRCCR (cte_in (port, DS_CRCCR1), cte_in (port, DS_CRCCR2));
782 	ebit = EBCR (cte_in (port, DS_EBCR1), cte_in (port, DS_EBCR2));
783 
784 	c->currnt.bpv += bpv;
785 	c->currnt.fse += fas;
786 	if (c->gopt.crc4) {
787 		c->currnt.crce += crc4;
788 		c->currnt.rcrce += ebit;
789 	}
790 
791 	/* Path code violation is frame sync error if CRC4 disabled,
792 	 * or CRC error if CRC4 enabled. */
793 	pcv = fas;
794 	if (c->gopt.crc4)
795 		pcv += crc4;
796 
797 	/* Unavaiable second -- receiving all ones, or
798 	 * loss of carrier, or loss of signal. */
799 	if (sr1 & (SR1_RUA1 | SR1_RCL | SR1_RLOS))
800 		/* Unavailable second -- no other counters. */
801 		++c->currnt.uas;
802 	else {
803 		/* Line errored second -- any BPV. */
804 		if (bpv)
805 			++c->currnt.les;
806 
807 		/* Errored second -- any PCV, or out of frame sync,
808 		 * or any slip events. */
809 		if (pcv || oof || (sr1 & SR1_RSLIP))
810 			++c->currnt.es;
811 
812 		/* Severely errored framing second -- out of frame sync. */
813 		if (oof)
814 			++c->currnt.oofs;
815 
816 		/* Severely errored seconds --
817 		 * 832 or more PCVs, or 2048 or more BPVs. */
818 		if (bpv >= 2048 || pcv >= 832)
819 			++c->currnt.ses;
820 		else {
821 			/* Bursty errored seconds --
822 			 * no SES and more than 1 PCV. */
823 			if (pcv > 1)
824 				++c->currnt.bes;
825 
826 			/* Collect data for computing
827 			 * degraded minutes. */
828 			++c->degsec;
829 			c->degerr += bpv + pcv;
830 		}
831 	}
832 
833 	/* Degraded minutes -- having error rate more than 10e-6,
834 	 * not counting unavailable and severely errored seconds. */
835 	if (c->cursec / 60 == 0) {
836 		if (c->degerr > c->degsec * 2048 / 1000)
837 			++c->currnt.dm;
838 		c->degsec = 0;
839 		c->degerr = 0;
840 	}
841 
842 	/* Rotate statistics every 15 minutes. */
843 	if (c->cursec > 15*60) {
844 		int i;
845 
846 		for (i=47; i>0; --i)
847 			c->interval[i] = c->interval[i-1];
848 		c->interval[0] = c->currnt;
849 
850 		/* Accumulate total statistics. */
851 		c->total.bpv   += c->currnt.bpv;
852 		c->total.fse   += c->currnt.fse;
853 		c->total.crce  += c->currnt.crce;
854 		c->total.rcrce += c->currnt.rcrce;
855 		c->total.uas   += c->currnt.uas;
856 		c->total.les   += c->currnt.les;
857 		c->total.es    += c->currnt.es;
858 		c->total.bes   += c->currnt.bes;
859 		c->total.ses   += c->currnt.ses;
860 		c->total.oofs  += c->currnt.oofs;
861 		c->total.css   += c->currnt.css;
862 		c->total.dm    += c->currnt.dm;
863 		for (i=0; i<sizeof (c->currnt); ++i)
864 			*(((char *)(&c->currnt))+i)=0;
865 
866 		c->totsec += c->cursec;
867 		c->cursec = 0;
868 	}
869 }
870 
ct_hdlc_interrupt(ct_chan_t * c,int imvr)871 static void ct_hdlc_interrupt (ct_chan_t *c, int imvr)
872 {
873 	int i, dsr, st1, st2, cda;
874 
875 	switch (imvr & IMVR_VECT_MASK) {
876 	case IMVR_RX_DMOK:		/* receive DMA normal end */
877 		dsr = inb (c->RX.DSR);
878 		cda = inw (c->RX.CDA);
879 		for (i=0; i<NBUF; ++i)
880 			if (cda == (unsigned short) c->rdphys[i])
881 				break;
882 		if (i >= NBUF)
883 			i = c->rn; /* cannot happen */
884 		while (c->rn != i) {
885 			int cst = B_STATUS (c->rdesc[c->rn]);
886 			if (cst == FST_EOM) {
887 				/* process data */
888 				if (c->call_on_rx)
889 					 c->call_on_rx (c, c->rbuf[c->rn],
890 						B_LEN(c->rdesc[c->rn]));
891 				++c->ipkts;
892 				c->ibytes += B_LEN(c->rdesc[c->rn]);
893 			} else if (cst & ST2_OVRN) {
894 				/* Receive overrun error */
895 				if (c->call_on_err)
896 					c->call_on_err (c, CT_OVERRUN);
897 				++c->ierrs;
898 			} else if (cst & (ST2_HDLC_RBIT |
899 				ST2_HDLC_ABT | ST2_HDLC_SHRT)) {
900 				/* Receive frame error */
901 				if (c->call_on_err)
902 					c->call_on_err (c, CT_FRAME);
903 				++c->ierrs;
904 			} else if ((cst & ST2_HDLC_EOM)
905 				&& (cst & ST2_HDLC_CRCE)) {
906 				/* Receive CRC error */
907 				if (c->call_on_err)
908 					c->call_on_err (c, CT_CRC);
909 				++c->ierrs;
910 			} else if (! (cst & ST2_HDLC_EOM)) {
911 				/* Frame dose not fit in the buffer.*/
912 				if (c->call_on_err)
913 					c->call_on_err (c, CT_OVERFLOW);
914 				++c->ierrs;
915 			}
916 
917 			B_NEXT (c->rdesc[c->rn]) =
918 				c->rdphys[(c->rn+1) % NBUF] & 0xffff;
919 			B_PTR (c->rdesc[c->rn]) = c->rphys[c->rn];
920 			B_LEN (c->rdesc[c->rn]) = DMABUFSZ;
921 			B_STATUS (c->rdesc[c->rn]) = 0;
922 			c->rn = (c->rn + 1) % NBUF;
923 		}
924 		outw (c->RX.EDA, (unsigned short) c->rdphys[(i+NBUF-1)%NBUF]);
925 		/* Clear DMA interrupt. */
926 		if (inb (c->RX.DSR) & DSR_DMA_ENABLE) {
927 			outb (c->RX.DSR, dsr);
928 		} else {
929 			outb (c->RX.DSR, (dsr & 0xfc) | DSR_DMA_ENABLE);
930 		}
931 		++c->rintr;
932 		break;
933 
934 	case IMVR_RX_INT:		/* receive status */
935 		st1 = inb (c->ST1);
936 		st2 = inb (c->ST2);
937 		if (st1 & ST1_CDCD){
938 			if (c->call_on_msig)
939 				c->call_on_msig (c);
940 			++c->mintr;
941 		}
942 		/* Clear interrupt. */
943 		outb (c->ST1, st1);
944 		outb (c->ST2, st2);
945 		++c->rintr;
946 		break;
947 
948 	case IMVR_RX_DMERR:		/* receive DMA error */
949 		dsr = inb (c->RX.DSR);
950 		if (dsr & (DSR_CHAIN_BOF | DSR_CHAIN_COF)) {
951 			if (c->call_on_err)
952 				c->call_on_err (c, CT_OVERFLOW);
953 			++c->ierrs;
954 			for (i=0; i<NBUF; ++i) {
955 				B_LEN (c->rdesc[i]) = DMABUFSZ;
956 				B_STATUS (c->rdesc[i]) = 0;
957 			}
958 			ct_start_receiver (c, 1, c->rphys[0], DMABUFSZ,
959 				c->rdphys[0], c->rdphys[NBUF-1]);
960 			c->rn = 0;
961 		}
962 		/* Clear DMA interrupt. */
963 		outb (c->RX.DSR, dsr);
964 		++c->rintr;
965 		break;
966 
967 	case IMVR_TX_DMOK:		/* transmit DMA normal end */
968 	case IMVR_TX_DMERR:		/* transmit DMA error	   */
969 		dsr = inb (c->TX.DSR);
970 		cda = inw (c->TX.CDA);
971 
972 		for (i=0; i<NBUF && cda != (unsigned short)c->tdphys[i]; ++i)
973 			continue;
974 		if (i >= NBUF)
975 			i = 1; /* cannot happen */
976 		if (dsr & DSR_CHAIN_COF) {
977 			if (c->call_on_err)
978 				c->call_on_err (c, CT_UNDERRUN);
979 			++c->oerrs;
980 		}
981 		while (c->tn != i) {
982 			if (c->call_on_tx)
983 				c->call_on_tx (c, c->attach[c->tn],
984 					B_LEN(c->tdesc[c->tn]));
985 			++c->opkts;
986 			c->obytes += B_LEN(c->tdesc[c->tn]);
987 
988 			c->tn = (c->tn + 1) % NBUF;
989 			/* Clear DMA interrupt. */
990 			outb (c->TX.DSR, DSR_CHAIN_EOM | DSR_DMA_CONTINUE);
991 		}
992 		outb (c->TX.DSR, dsr & ~DSR_CHAIN_EOM);
993 		++c->tintr;
994 		break;
995 
996 	case IMVR_TX_INT:		/* transmit error, HDLC only */
997 		st1 = inb (c->ST1);
998 		if (st1 & ST1_HDLC_UDRN) {
999 			if (c->call_on_err)
1000 				c->call_on_err (c, CT_UNDERRUN);
1001 			++c->oerrs;
1002 		}
1003 		outb (c->ST1, st1);
1004 		++c->tintr;
1005 		break;
1006 
1007 	default:
1008 		/* Unknown interrupt - cannot happen. */
1009 		break;
1010 	}
1011 }
1012 
ct_receive_enabled(ct_chan_t * c)1013 int ct_receive_enabled (ct_chan_t *c)
1014 {
1015 	int st3;
1016 
1017 	st3 = inb (c->ST3);
1018 	return (st3 & ST3_RX_ENABLED) ? 1 : 0;
1019 }
1020 
ct_transmit_enabled(ct_chan_t * c)1021 int ct_transmit_enabled (ct_chan_t *c)
1022 {
1023 	int st3;
1024 
1025 	st3 = inb (c->ST3);
1026 	return (st3 & ST3_TX_ENABLED) ? 1 : 0;
1027 }
1028 
ct_buf_free(ct_chan_t * c)1029 int ct_buf_free (ct_chan_t *c)
1030 {
1031 	return (NBUF + c->tn - c->te - 1) % NBUF;
1032 }
1033 
ct_send_packet(ct_chan_t * c,unsigned char * data,int len,void * attachment)1034 int ct_send_packet (ct_chan_t *c, unsigned char *data, int len,
1035 	void *attachment)
1036 {
1037 	int dsr, ne;
1038 
1039 	if (len > DMABUFSZ)
1040 		return -2;
1041 
1042 	/* Is it really free? */
1043 	ne = (c->te+1) % NBUF;
1044 	if (ne == c->tn)
1045 		return -1;
1046 
1047 	/* Set up the tx descriptor. */
1048 	B_LEN (c->tdesc[c->te]) = len;
1049 	B_STATUS (c->tdesc[c->te]) = FST_EOM;
1050 	c->attach[c->te] = attachment;
1051 	if (c->tbuf[c->te] != data)
1052 		memcpy (c->tbuf[c->te], data, len);
1053 
1054 	/* Start the transmitter. */
1055 	c->te = ne;
1056 	outw (c->TX.EDA, (unsigned short) c->tdphys[ne]);
1057 	dsr = inb (c->TX.DSR);
1058 	if (! (dsr & DSR_DMA_ENABLE))
1059 		outb (c->TX.DSR, DSR_DMA_ENABLE);
1060 	return 0;
1061 }
1062 
scc_write(ct_chan_t * c,unsigned char * d,int len)1063 int scc_write (ct_chan_t *c, unsigned char *d, int len)
1064 {
1065 	int i, free;
1066 
1067 	/* determining free place in buffer */
1068 	if (c->scctx_empty)
1069 		free = SCCBUFSZ;
1070 	else
1071 		free = (SCCBUFSZ + c->scctx_b - c->scctx_e) % SCCBUFSZ;
1072 
1073 	if (len > free)
1074 		return -1;
1075 
1076 	for (i=0; i<len; i++){
1077 		c->scctx[c->scctx_e] = d[i];
1078 		c->scctx_e = (c->scctx_e+1) % SCCBUFSZ;
1079 	}
1080 	if (c->scctx_empty && len) {
1081 		cte_out2d (c, c->scctx[c->scctx_b]);
1082 		c->scctx_empty = 0;
1083 	}
1084 	return 0;
1085 }
1086 
scc_read(ct_chan_t * c,unsigned char * d,int len)1087 int scc_read (ct_chan_t *c, unsigned char *d, int len)
1088 {
1089 	int i, bytes;
1090 
1091 	if (c->sccrx_empty)
1092 		bytes = 0;
1093 	else
1094 		bytes = (SCCBUFSZ + c->sccrx_e - 1 - c->sccrx_b) %
1095 				SCCBUFSZ + 1;
1096 	if (len > bytes)
1097 		return -1;
1098 
1099 	for (i=0; i<len; i++){
1100 		d[i] = c->sccrx[c->sccrx_b];
1101 		c->sccrx_b = (c->sccrx_b+1) % SCCBUFSZ;
1102 	}
1103 	if (c->sccrx_b==c->sccrx_e)
1104 		c->sccrx_empty = 1;
1105 	return 0;
1106 }
1107 
sccrx_check(ct_chan_t * c)1108 int sccrx_check (ct_chan_t *c)
1109 {
1110 	int bytes;
1111 
1112 	if (c->sccrx_empty)
1113 		bytes = 0;
1114 	else
1115 		bytes = (SCCBUFSZ + c->sccrx_e - 1 - c->sccrx_b) %
1116 				SCCBUFSZ + 1;
1117 	return bytes;
1118 }
1119 
scc_read_byte(ct_chan_t * c)1120 int scc_read_byte (ct_chan_t *c)
1121 {
1122 	unsigned char a;
1123 
1124 	if (scc_read (c, &a, 1) < 0)
1125 		return -1;
1126 	return a;
1127 }
1128 
scc_write_byte(ct_chan_t * c,unsigned char b)1129 int scc_write_byte (ct_chan_t *c, unsigned char b)
1130 {
1131 	if (scc_write (c, &b, 1) < 0)
1132 		return -1;
1133 	return b;
1134 }
1135 
1136 /*
1137  * Register event processing functions
1138  */
ct_register_transmit(ct_chan_t * c,void (* func)(ct_chan_t *,void *,int))1139 void ct_register_transmit (ct_chan_t *c, void (*func) (ct_chan_t*, void*, int))
1140 {
1141 	c->call_on_tx = func;
1142 }
1143 
ct_register_receive(ct_chan_t * c,void (* func)(ct_chan_t *,char *,int))1144 void ct_register_receive (ct_chan_t *c, void (*func) (ct_chan_t*, char*, int))
1145 {
1146 	c->call_on_rx = func;
1147 }
1148 
ct_register_error(ct_chan_t * c,void (* func)(ct_chan_t *,int))1149 void ct_register_error (ct_chan_t *c, void (*func) (ct_chan_t*, int))
1150 {
1151 	c->call_on_err = func;
1152 }
1153 
ct_register_scc(ct_chan_t * c,void (* func)(ct_chan_t *))1154 void ct_register_scc (ct_chan_t *c, void (*func) (ct_chan_t*))
1155 {
1156 	c->call_on_scc = func;
1157 }
1158 
ct_register_modem(ct_chan_t * c,void (* func)(ct_chan_t *))1159 void ct_register_modem (ct_chan_t *c, void (*func) (ct_chan_t*))
1160 {
1161 	c->call_on_msig = func;
1162 }
1163