1/*
2 * Middle-level code for Cronyx Tau32-PCI adapters.
3 *
4 * Copyright (C) 2004 Cronyx Engineering
5 * Copyright (C) 2004 Roman Kurakin <rik@FreeBSD.org>
6 *
7 * This software is distributed with NO WARRANTIES, not even the implied
8 * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9 *
10 * Authors grant any other persons or organisations a permission to use,
11 * modify and redistribute this software in source and binary forms,
12 * as long as this message is kept with the software, all derivative
13 * works or modified versions.
14 *
15 * $Cronyx: ceddk.c,v 1.2.6.2 2005/11/17 16:04:13 rik Exp $
16 */
17
18#include <sys/cdefs.h>
19__FBSDID("$FreeBSD$");
20
21#include <dev/ce/machdep.h>
22#include <dev/ce/ceddk.h>
23
24#undef CE_DDK_DEBUG_ENABLED
25#ifdef CE_DDK_DEBUG_ENABLED
26#ifdef __FreeBSD__
27# define CE_DDK_DEBUG(b,c,s) \
28	do { \
29		if (c) { \
30			printf("ce%d-%d: ",(b)->num,(c)->num); \
31		} else { \
32			printf("ce%d-*: ",(b)->num); \
33		} \
34		printf s; \
35	} while (0)
36#else
37# define CE_DDK_DEBUG(b,c,s)	do {} while (0)
38#endif
39#else
40# define CE_DDK_DEBUG(b,c,s)	do {} while (0)
41#endif
42
43#if 0
44#define ENTER() \
45	static int enter=0; \
46	do { \
47	enter++; \
48	printf ("%s: >> enter (%16llx) %d\n", __FUNCTION__, rdtsc (), enter); \
49	} while (0)
50
51#define EXIT(val...) \
52	do { \
53	enter--; \
54	printf ("%s: << exit  (%16llx) %d line %d\n", __FUNCTION__, rdtsc (), enter, __LINE__); \
55	return val; \
56	} while (0)
57#else
58#define ENTER() \
59	do {} while (0)
60
61#define EXIT(val...) \
62	do {return val;} while (0)
63#endif
64
65#define CE_ENQUEUE(list,item) \
66	do { \
67		TAU32_UserRequest **last; \
68		last = &(list); \
69		while (*last) { \
70			last = &(*last)->next; \
71		} \
72		(*last) = (item); \
73		(item)->next = NULL; \
74	} while (0)
75
76#define CE_ENQUEUE_HEAD(list,item) \
77	do { \
78		(item)->next = list; \
79		list = item; \
80	} while (0)
81
82#define CE_DEQUEUE(list,item) \
83	do { \
84		item = list; \
85		if (list) { \
86			list = (item)->next; \
87		} \
88	} while (0)
89
90#define CE_PREREQUEST(b,c,list,item) \
91	do { \
92		item = list; \
93		if (!item) { \
94			CE_DDK_DEBUG (b, c, ("Fatal error, no free structs " \
95					     "for UserRequest (%s:%d)\n", \
96					     __FUNCTION__, __LINE__)); \
97		} \
98	} while (0)
99
100#define CE_DUMP_QUEUE(list) \
101	do { \
102		TAU32_UserRequest *item; \
103		int i = 0; \
104		item = list; \
105		while (item) { \
106			printf ("item%d: %p\n", i, item); \
107			item = item->next; \
108			i++; \
109		} \
110	} while (0)
111
112#define CE_FIND_ITEM(list,item,flag) \
113	do { \
114		TAU32_UserRequest *citem; \
115		flag = 0; \
116		for (citem = list; citem; citem = citem->next) { \
117			if (citem == item) { \
118				flag = 1; \
119				break; \
120			} \
121		} \
122	} while (0)
123
124#define CE_LAST_ITEM(list,item) \
125	do { \
126		TAU32_UserRequest **last; \
127		last = &(list); \
128		while ((*last) && (*last)->next) { \
129			last = &(*last)->next; \
130		} \
131		(item) = (*last); \
132	} while (0)
133
134#define CE_ASSERT(a) \
135	do { \
136		if (!(a)) { \
137			printf ("ASSERT: %d %s\n", __LINE__, #a); \
138			__asm __volatile ("int $3"); \
139		} \
140	} while (0)
141
142static void _ce_set_ts (ce_chan_t *c, unsigned long ts);
143static void _ce_submit_configure_e1 (ce_chan_t *c, char *rname);
144
145#ifdef CE_DDK_DEBUG_ENABLED
146static char *ce_err2str (unsigned long err)
147{
148	switch (err) {
149	case TAU32_SUCCESSFUL:
150		return "Successful";
151	case TAU32_ERROR_ALLOCATION:
152		return "Allocation error, not enough tx/rx descriptors";
153	case TAU32_ERROR_BUS:
154		return "PEB could not access to host memory by PCI bus for load/store information";
155	case TAU32_ERROR_FAIL:
156		return "PEB action request failed";
157	case TAU32_ERROR_TIMEOUT:
158		return "PEB action request timeout";
159	case TAU32_ERROR_CANCELLED:
160		return "request has been canceled";
161	case TAU32_ERROR_TX_UNDERFLOW:
162		return "transmission underflow";
163	case TAU32_ERROR_TX_PROTOCOL:
164		return "TX_PROTOCOL";
165	case TAU32_ERROR_RX_OVERFLOW:
166		return "RX_OVERFLOW";
167	case TAU32_ERROR_RX_ABORT:
168		return "RX_ABORT";
169	case TAU32_ERROR_RX_CRC:
170		return "RX_CRC";
171	case TAU32_ERROR_RX_SHORT:
172		return "RX_SHORT";
173	case TAU32_ERROR_RX_SYNC:
174		return "RX_SYNC";
175	case TAU32_ERROR_RX_FRAME:
176		return "RX_FRAME";
177	case TAU32_ERROR_RX_LONG:
178		return "RX_LONG";
179	case TAU32_ERROR_RX_SPLIT:
180		return "frame has splitted between two requests due rx-gap allocation";
181	case TAU32_ERROR_RX_UNFIT:
182		return "frame can't be fit into request buffer";
183	case TAU32_ERROR_TSP:
184		return "ERROR_TSP";
185	case TAU32_ERROR_RSP:
186		return "ERROR_RSP";
187	case TAU32_ERROR_INT_OVER_TX:
188		return "ERROR INT OVER TX";
189	case TAU32_ERROR_INT_OVER_RX:
190		return "ERROR INT OVER RX";
191	case TAU32_ERROR_INT_STORM:
192		return "irq storm";
193	case TAU32_ERROR_INT_E1LOST:
194		return "ERROR_E1LOST";
195	default:
196		return ("Unknown error");
197	}
198}
199#endif
200
201void ce_set_dtr (ce_chan_t *c, int on)
202{
203	c->dtr = on?1:0;
204}
205
206void ce_set_rts (ce_chan_t *c, int on)
207{
208	c->rts = on?1:0;
209}
210
211static void TAU32_CALLBACK_TYPE ce_on_receive
212	(TAU32_UserContext *pContext, TAU32_UserRequest *req)
213{
214	ce_buf_item_t *item = (ce_buf_item_t *)req;
215	ce_chan_t *c;
216	ce_board_t *b;
217	unsigned int error;
218	int len;
219
220	ENTER ();
221	if (!req || !req->sys) {
222		EXIT ();
223	}
224
225	c = (ce_chan_t *)req->sys;
226	b = c->board;
227
228	len = req->Io.Rx.Received;
229	error = req->ErrorCode;
230
231	c->rintr++;
232	if (error == TAU32_SUCCESSFUL) {
233		if (req->Io.Rx.FrameEnd) {
234			c->ipkts++;
235		} else {
236			CE_DDK_DEBUG (b, c, ("No FrameEnd\n"));
237			/* probably do something in some cases*/
238		}
239		c->ibytes += len;
240		if (c->receive)
241			c->receive (c, item->buf, len);
242	} else if (error & TAU32_ERROR_BUS) {
243		c->overrun++;
244		if (c->error)
245			c->error (c, CE_OVERRUN);
246	} else {
247		CE_DDK_DEBUG (b, c, ("Another receive error: %x\n", error));
248		/* Do some procesing */
249	}
250
251	CE_ASSERT (!req->pInternal);
252	CE_ENQUEUE (c->rx_queue, req);
253	while (c->rx_queue) {
254		CE_DEQUEUE (c->rx_queue, req);
255		CE_ASSERT (req);
256		item = (ce_buf_item_t *)req;
257		req->Command = TAU32_Rx_Data;
258		req->Io.Rx.Channel = c->num;
259		req->pCallback = ce_on_receive;
260		req->Io.Rx.BufferLength = BUFSZ+4;
261		req->Io.Rx.PhysicalDataAddress = item->phys;
262		if (!TAU32_SubmitRequest (b->ddk.pControllerObject, req)) {
263			CE_DDK_DEBUG (b, c, ("RX submition failure\n"));
264			c->rx_pending--;
265			CE_ENQUEUE_HEAD (c->rx_queue, req);
266			break;
267		}
268	}
269	EXIT ();
270}
271
272static void TAU32_CALLBACK_TYPE ce_on_transmit
273	(TAU32_UserContext *pContext, TAU32_UserRequest *req)
274{
275	int len;
276	unsigned int error;
277	ce_chan_t *c;
278	ENTER ();
279
280	if (!req || !req->sys) {
281		EXIT ();
282	}
283
284	c = (ce_chan_t *)req->sys;
285
286	len = req->Io.Tx.Transmitted;
287	error = req->ErrorCode;
288
289	c->tintr++;
290	if (error == TAU32_SUCCESSFUL) {
291		c->obytes += len;
292		c->opkts++;
293	} else if (error & TAU32_ERROR_BUS) {
294		c->underrun++;
295		if (c->error)
296			c->error (c, CE_UNDERRUN);
297	} else {
298		CE_DDK_DEBUG (c->board, c, ("Another transmit error: %x\n",
299				error));
300		/* Do some procesing */
301	}
302
303	CE_ENQUEUE (c->tx_queue, req);
304	c->tx_pending--;
305
306	if (c->transmit)
307		c->transmit (c, 0, len);
308	EXIT ();
309}
310
311int ce_transmit_space (ce_chan_t *c)
312{
313	return c->tx_pending < (TAU32_IO_QUEUE);
314}
315
316int ce_send_packet (ce_chan_t *c, unsigned char *buf, int len, void *tag)
317{
318	TAU32_UserRequest *req;
319	ce_buf_item_t *item;
320
321	ENTER ();
322
323	if (!ce_transmit_space (c)) {
324		EXIT (-1);
325	}
326
327	if (len <= 0 || len > BUFSZ) {
328		EXIT (-2);
329	}
330
331	CE_DEQUEUE (c->tx_queue, req);
332	CE_ASSERT (req);
333	item = (ce_buf_item_t *)req;
334
335	if (buf != item->buf)
336		memcpy (item->buf, buf, len);
337
338	CE_ASSERT (!req->pInternal);
339
340	req->Command = TAU32_Tx_Data | TAU32_Tx_FrameEnd;
341	req->Io.Tx.Channel = c->num;
342	req->pCallback = ce_on_transmit;
343	req->Io.Tx.DataLength = len;
344	req->Io.Tx.PhysicalDataAddress = item->phys;
345	c->tx_pending++;
346	if (!TAU32_SubmitRequest (c->board->ddk.pControllerObject, req)) {
347		CE_DDK_DEBUG (c->board, c, ("Can't submit packet for "
348					    "transmission\n"));
349		CE_ENQUEUE_HEAD (c->tx_queue, req);
350		c->tx_pending--;
351		EXIT (-3);
352	}
353	EXIT (0);
354}
355
356static void TAU32_CALLBACK_TYPE ce_on_config
357	(TAU32_UserContext *pContext, TAU32_UserRequest *req)
358{
359	ce_board_t *b = (ce_board_t *) pContext;
360	ENTER ();
361	b->cr.pending--;
362	if (req->ErrorCode)
363		CE_DDK_DEBUG (b, (ce_chan_t*)0, ("Config request failure: %lx\n",
364			      req->ErrorCode));
365	EXIT ();
366}
367
368static void TAU32_CALLBACK_TYPE ce_on_config_stop
369	(TAU32_UserContext *pContext, TAU32_UserRequest *req)
370{
371	int i, first;
372	TAU32_UserRequest *rreq;
373	ce_board_t *b = (ce_board_t *) pContext;
374	ce_chan_t *c = b->chan + req->Io.ChannelNumber;
375
376	ENTER ();
377	/* Stop all requests */
378	CE_ASSERT (0);/* Buggy */
379	CE_LAST_ITEM (c->rx_queue, rreq);
380	/* A little hacky, try to guess which is a first */
381	first = rreq ? (c->rx_item - (ce_buf_item_t *)rreq) + 1 : 0;
382	for (i = 0; i < TAU32_IO_QUEUE; i++) {
383		int is_pending;
384		rreq = &c->rx_item[(i + first) % TAU32_IO_QUEUE].req;
385		CE_FIND_ITEM (c->rx_queue, rreq, is_pending);
386		if (!is_pending)
387			continue;
388		TAU32_CancelRequest (b->ddk.pControllerObject, rreq, 1);
389		rreq->Command = TAU32_Rx_Data;
390		rreq->Io.Rx.Channel = c->num;
391		rreq->Io.Rx.BufferLength = BUFSZ+4;
392		rreq->Io.Rx.PhysicalDataAddress = ((ce_buf_item_t *)rreq)->phys;
393		c->rx_pending++;
394		if (!TAU32_SubmitRequest (b->ddk.pControllerObject, rreq)) {
395			CE_ASSERT (0);/* Buggy */
396			c->rx_pending--;
397			break;
398		}
399	}
400
401	c->tx_pending = 0;
402/*	c->rx_pending = 0;*/
403	EXIT ();
404}
405
406static int ce_cfg_submit (ce_board_t *b)
407{
408	TAU32_UserRequest *req;
409	ENTER ();
410
411	CE_DEQUEUE (b->cr.queue, req);
412	CE_ASSERT (req);
413	CE_ASSERT (!req->pInternal);
414
415	req->pCallback = ce_on_config;
416	b->cr.pending++;
417
418	CE_DDK_DEBUG (b, (ce_chan_t *)0, ("config request pending: %d\n",
419		      b->cr.pending));
420
421	if (!TAU32_SubmitRequest (b->ddk.pControllerObject, req)) {
422		CE_ENQUEUE_HEAD (b->cr.queue, req);
423		CE_DDK_DEBUG (b, (ce_chan_t *)0, ("Fail to submit config request\n"));
424		b->cr.pending--;
425		EXIT (0);
426	}
427
428	EXIT (1);
429}
430
431void ce_init_board (ce_board_t *b)
432{
433	int i;
434
435	b->cr.queue = NULL;
436
437	for (i = 0; i < CONFREQSZ; i++) {
438		CE_ENQUEUE (b->cr.queue, b->cr.req + i);
439	}
440
441	b->chan[0].config = TAU32_ais_on_loss;
442
443	/* lloop = off, rloop = off */
444	b->chan[0].config |= TAU32_LineNormal;
445	b->chan[0].lloop = 0;
446	b->chan[0].rloop = 0;
447
448	/* unfram=off, scrambler=off, use16=off, crc4=off,
449	   higain=off, monitor=off*/
450	b->chan[0].config |= (b->ddk.Interfaces == 2 ? TAU32_framed_cas_cross :
451						       TAU32_framed_cas_set);
452	b->chan[0].unfram = 0;
453	b->chan[0].scrambler = 0;
454	b->chan[0].use16 = 0;
455	b->chan[0].crc4 = 0;
456	b->chan[0].higain = 0;
457	b->chan[0].monitor = 0;
458
459	if (b->ddk.Interfaces == 2) {
460		b->chan[1].config = TAU32_ais_on_loss;
461		/* lloop = off, rloop = off */
462		b->chan[1].config |= TAU32_LineNormal;
463		/* unfram=off, scrambler=off, use16=off, crc4=off,
464		   higain=off, monitor=off*/
465		b->chan[1].config |= TAU32_framed_cas_cross;
466		b->chan[1].unfram = 0;
467		b->chan[1].scrambler = 0;
468		b->chan[1].use16 = 0;
469		b->chan[1].crc4 = 0;
470		b->chan[1].higain = 0;
471		b->chan[1].monitor = 0;
472	}
473
474	for (i = 0; i < NCHAN; i++) {
475		/* Chan0 ts=1-15,17-31, Chan1 ts=1-2 */
476		b->chan[i].type = i < b->ddk.Interfaces ? T_E1 : T_DATA;
477		b->chan[i].ts = (i == 0 ? 0xfffefffe :
478				(i != 1 ? 0 :
479				(b->ddk.Interfaces == 2 ? 0x6: 0)));
480		b->chan[i].dir = (b->ddk.Interfaces == 2) ? (i%2) : 0;
481		b->chan[i].mtu = 1504;
482	}
483#if 0
484	/* c->num == 0 */
485	req = b->cr.queue;
486	/* We must have some here */
487	CE_ASSERT (req);
488	req->Command = TAU32_Configure_E1;
489	req->Io.InterfaceConfig.Interface = TAU32_E1_A;
490	req->Io.InterfaceConfig.Config = b->chan[0].config;
491	req->Io.InterfaceConfig.UnframedTsMask = 0;
492	if (!ce_cfg_submit (b)) {
493		CE_DDK_DEBUG (b, b->chan + 0,
494			      ("Submit request failure, line %d\n",
495			      __LINE__));
496	}
497	/* c->num == 1 */
498	if (b->ddk.Interfaces == 2) {
499		req = b->cr.queue;
500		/* We must have some here */
501		CE_ASSERT (req);
502		req->Command = TAU32_Configure_E1;
503		req->Io.InterfaceConfig.Interface = TAU32_E1_B;
504		req->Io.InterfaceConfig.Config = b->chan[1].config;
505		req->Io.InterfaceConfig.UnframedTsMask = 0;
506		if (!ce_cfg_submit (b)) {
507			CE_DDK_DEBUG (b, b->chan + 1,
508				      ("Submit request failure, line %d\n",
509				      __LINE__));
510		}
511	}
512#endif
513	/* Set default cross matrix */
514	for (i = 0; i < 32; i++) {
515		/* -X-> Peb */
516		b->dxc[i] = TAU32_CROSS_OFF;
517		/* Link2 -> Link1 */
518		b->dxc[i + 32] = i + 64;
519		/* Link1 -> Link2 */
520		b->dxc[i + 64] = i + 32;
521	}
522
523	/* We have only mux mode for now. Later we will also have cross mode */
524	b->mux = 1;
525}
526
527void ce_start_chan (ce_chan_t *c, int tx, int rx, ce_buf_t *cb,
528	unsigned long phys)
529{
530	int i;
531	ce_board_t *b = c->board;
532
533/*	c->config = TAU32_ais_on_loss | TAU32_framed_cas_cross;*/
534
535	if (cb) {
536		CE_DDK_DEBUG (b, c, ("ce_buf_t virt:%p phys:%p\n", cb,
537			      (void *)phys));
538		c->tx_item = cb->tx_item;
539		c->rx_item = cb->rx_item;
540		c->tx_queue = NULL;
541		c->rx_queue = NULL;
542		for (i = 0; i < TAU32_IO_QUEUE; i++) {
543			c->tx_item[i].phys = phys +
544				((char *)(c->tx_item[i].buf)-(char *)cb);
545			c->rx_item[i].phys = phys +
546				((char *)(c->rx_item[i].buf)-(char *)cb);
547			cb->tx_item[i].req.sys = c;
548			cb->rx_item[i].req.sys = c;
549			CE_DDK_DEBUG (b, c, ("tx_item[%d].buf virt:%p phys:%p\n",
550				      i, c->tx_item[i].buf,
551				      (void *)c->tx_item[i].phys));
552			CE_DDK_DEBUG (b, c, ("rx_item[%d].buf virt:%p phys:%p\n",
553				      i, c->rx_item[i].buf,
554				      (void *)c->rx_item[i].phys));
555			CE_ENQUEUE (c->rx_queue, &c->rx_item[i].req);
556			CE_ENQUEUE (c->tx_queue, &c->tx_item[i].req);
557		}
558		c->tx_pending = 0;
559		c->rx_pending = 0;
560	}
561
562	/* submit rx */
563	while (1) {
564		ce_buf_item_t *item;
565		TAU32_UserRequest *req;
566
567		CE_DEQUEUE (c->rx_queue, req);
568		if (!req)
569			break;
570		item = (ce_buf_item_t *) req;
571		CE_ASSERT (c->rx_pending < TAU32_IO_QUEUE);
572		req->Command = TAU32_Rx_Data;
573		req->Io.Rx.Channel = c->num;
574		req->pCallback = ce_on_receive;
575		req->Io.Rx.BufferLength = c->mtu + (c->phony ? 0 : 4);
576		req->Io.Rx.PhysicalDataAddress = item->phys;
577		c->rx_pending++;
578		if (!TAU32_SubmitRequest (b->ddk.pControllerObject, req)) {
579			CE_DDK_DEBUG (b, c, ("Faild to submit rx request\n"));
580			/*XXXRIK: shouldn't happen, but ... */
581			CE_ASSERT (0);
582			c->rx_pending--;
583			break;
584		}
585	}
586
587	if (tx | rx) {
588		TAU32_UserRequest *req;
589		CE_PREREQUEST (b, c, b->cr.queue, req);
590		if (!req)
591 			return;
592		req->Command = TAU32_Configure_Commit |
593			       (tx ? TAU32_Tx_Start : 0) |
594			       (rx ? TAU32_Rx_Start : 0);
595		req->Io.ChannelNumber = c->num;
596		if (!ce_cfg_submit (b)) {
597			CE_DDK_DEBUG (b, c, ("Can't start chan\n"));
598			/* Do some error processing */
599			return;
600		}
601	}
602
603	/* If we run just after ce_board_init we have prope values.
604	 * Else I hope you didn't set ts to incorrect value.
605	 */
606	_ce_set_ts (c, c->ts);
607	if (c->num < b->ddk.Interfaces) {
608		/* The same for other modes. We don't check them.
609		 * We hope that config is correctly set. Just as we have
610		 * after ce_board_init. If channel was stoped we hope that
611		 * it's config was not broken just after it and we didn't
612		 * brake it before start.
613		 */
614		_ce_submit_configure_e1 (c, "start_init");
615	}
616}
617
618void ce_stop_chan (ce_chan_t *c)
619{
620	ce_board_t *b = c->board;
621	TAU32_UserRequest *req;
622	CE_DEQUEUE (b->cr.queue, req);
623
624	/* XXXRIK: This function should be for completeness, but for now I
625	 * don't use it. I just started to write and haven't finished it yet.
626	 * It is VERY BUGGY!!! Do not use it. If you really need
627	 * it ask me to fix it or rewrite it by yourself.
628	 * Note: most buggy part of it in ce_on_config_stop!
629	 */
630	if (!req) {
631		CE_DDK_DEBUG (b, c, ("Fatal error, no free structs for "
632			      "UserRequest (%s:%d)\n", __FUNCTION__, __LINE__));
633		return;
634	}
635//	req->Command = TAU32_Configure_Commit |
636//		       TAU32_Tx_Stop | TAU32_Rx_Stop;
637	req->Command = 0;
638	req->Io.ChannelNumber = c->num;
639	req->pCallback = ce_on_config_stop;
640	b->cr.pending++;
641
642	if (!TAU32_SubmitRequest (b->ddk.pControllerObject, req)) {
643		CE_ENQUEUE_HEAD (b->cr.queue, req);
644		CE_DDK_DEBUG (b, c, ("Can't stop chan\n"));
645		b->cr.pending--;
646	}
647}
648
649void ce_register_transmit (ce_chan_t *c,
650	void (*func) (ce_chan_t*, void*, int))
651{
652	c->transmit = func;
653}
654
655void ce_register_receive (ce_chan_t *c,
656	void (*func) (ce_chan_t*, unsigned char*, int))
657{
658	c->receive = func;
659}
660
661void ce_register_error (ce_chan_t *c,
662	void (*func) (ce_chan_t*, int))
663{
664	c->error = func;
665}
666
667void TAU32_CALLBACK_TYPE ce_error_callback (TAU32_UserContext *pContext,
668						int Item, unsigned NotifyBits)
669{
670	ce_board_t *b = (ce_board_t *) pContext;
671	ENTER ();
672	if (NotifyBits & (TAU32_ERROR_FAIL | TAU32_ERROR_TIMEOUT
673		| TAU32_ERROR_INT_OVER_TX | TAU32_ERROR_INT_OVER_RX
674		| TAU32_ERROR_INT_STORM)) {
675		/* Fatal: adapter failure, need reset & restart */
676		/* RIKXXX: probably I should add CE_FAILURE for ce_error */
677		CE_DDK_DEBUG (b, (ce_chan_t *)0, ("Err, disable interrupts: %s\n",
678				ce_err2str (NotifyBits)));
679/*		TAU32_DisableInterrupts (b->ddk.pControllerObject);*/
680		EXIT ();
681	}
682	if (Item >= 0) {
683		/* channel error */
684		ce_chan_t *c = b->chan + Item;
685		if (NotifyBits & TAU32_ERROR_TX_UNDERFLOW) {
686			c->underrun++;
687			if (c->error)
688				c->error (c, CE_UNDERRUN);
689		}
690		if (NotifyBits & TAU32_ERROR_RX_OVERFLOW) {
691			c->overrun++;
692			if (c->error)
693				c->error (c, CE_OVERFLOW);
694		}
695		if (NotifyBits & (TAU32_ERROR_RX_FRAME | TAU32_ERROR_RX_ABORT |
696		    TAU32_ERROR_RX_SHORT | TAU32_ERROR_RX_LONG |
697		    TAU32_ERROR_RX_SYNC | TAU32_ERROR_RX_SPLIT |
698		    TAU32_ERROR_RX_UNFIT)) {
699			c->frame++;
700			CE_DDK_DEBUG (b, c, ("Frame error: %x\n", NotifyBits));
701			if (c->error)
702				c->error (c, CE_FRAME);
703		}
704		if(NotifyBits & TAU32_ERROR_RX_CRC) {
705			c->crc++;
706			if (c->error)
707				c->error (c, CE_CRC);
708		}
709	} else {
710		CE_DDK_DEBUG (b, (ce_chan_t *)0, ("Another error: %x\n",
711			      NotifyBits));
712		/* Adapter error, do smth */
713	}
714	EXIT ();
715}
716
717void TAU32_CALLBACK_TYPE ce_status_callback(TAU32_UserContext *pContext,
718						int Item, unsigned NotifyBits)
719{
720	ce_board_t *b = (ce_board_t *) pContext;
721	ENTER ();
722	if(Item >= 0) {
723		/* e1 status */
724		ce_chan_t *c = b->chan + Item;
725		c->acc_status |= b->ddk.InterfacesInfo[Item].Status;
726/*		CE_DDK_DEBUG (b, c, ("Current status: %x\n", c->acc_status));*/
727	} else {
728		CE_DDK_DEBUG (b, (ce_chan_t *)0, ("Another status: %x\n", NotifyBits));
729		/* Adapter status, do smth. */
730	}
731	EXIT ();
732}
733
734int ce_get_cd (ce_chan_t *c)
735{
736	unsigned int e1status = c->board->ddk.InterfacesInfo[c->dir].Status;
737
738	return (c->ts && !(e1status & (TAU32_RCL | TAU32_E1OFF)));
739}
740
741int ce_get_cts (ce_chan_t *c)
742{
743	return 0;
744}
745
746int ce_get_dsr (ce_chan_t *c)
747{
748	return 0;
749}
750
751void ce_e1_timer (ce_chan_t *c)
752{
753	unsigned bpv, fas, crc4, ebit, pcv, oof, css;
754	unsigned int acc_status;
755	ce_board_t *b = c->board;
756	TAU32_E1_State	*state;
757
758	if (c->num >= b->ddk.Interfaces)
759		return;
760
761	state = &b->ddk.InterfacesInfo[c->num];
762	acc_status = c->acc_status;
763
764	/* Clear acc_status */
765	c->acc_status = b->ddk.InterfacesInfo[c->num].Status;
766
767	/* Count seconds.
768	 * During the first second after the channel startup
769	 * the status registers are not stable yet,
770	 * we will so skip the first second. */
771	++c->cursec;
772	if (! c->totsec && c->cursec <= 1)
773		return;
774
775	c->status = 0;
776
777	/* Compute the SNMP-compatible channel status. */
778	oof = 0;
779
780	if (acc_status & TAU32_RCL)
781		c->status |= ESTS_LOS;		/* loss of signal */
782	if (acc_status & TAU32_RUA1)
783		c->status |= ESTS_AIS;		/* receiving all ones */
784
785	/* Get error counters. */
786	bpv = state->RxViolations;
787	fas = 0;
788	crc4 = 0;
789	ebit = 0;
790	css = 0;
791
792	if (! c->unfram) {
793		if (! c->use16 && (acc_status & TAU32_RSA1))
794			c->status |= ESTS_AIS16;	/* signaling all ones */
795		if (! c->use16 && (acc_status & TAU32_RDMA))
796			c->status |= ESTS_FARLOMF;	/* alarm in timeslot 16 */
797		if (acc_status & TAU32_RRA)
798			c->status |= ESTS_FARLOF;	/* far loss of framing */
799
800		if (acc_status & TAU32_RFAS) {
801			c->status |= ESTS_LOF;		/* loss of framing */
802			++oof;				/* out of framing */
803		}
804		if ((! c->use16 && (acc_status & TAU32_RCAS)) ||
805		    (c->crc4 && (acc_status & TAU32_RCRC4))) {
806			c->status |= ESTS_LOMF;		/* loss of multiframing */
807			++oof;				/* out of framing */
808		}
809		fas = state->FasErrors;
810		crc4 = state->Crc4Errors;
811		ebit = state->FarEndBlockErrors;
812
813		/* Controlled slip second -- any slip event. */
814		css = state->TransmitSlips + state->ReceiveSlips;
815	}
816
817	/* Clear state */
818	state->RxViolations		= 0;
819	state->FasErrors		= 0;
820	state->Crc4Errors		= 0;
821	state->FarEndBlockErrors	= 0;
822	state->TransmitSlips		= 0;
823	state->ReceiveSlips		= 0;
824
825	if (c->status & ESTS_LOS)
826		c->status = ESTS_LOS;
827	else if (c->status & ESTS_AIS)
828		c->status = ESTS_AIS;
829	else if (c->status & ESTS_LOF)
830		c->status = ESTS_LOF;
831	else if (c->status & ESTS_LOMF)
832		c->status &= ~(ESTS_FARLOMF | ESTS_AIS16);
833
834	if (! c->status)
835		c->status = ESTS_NOALARM;
836
837	c->currnt.bpv += bpv;
838	c->currnt.fse += fas;
839	if (c->crc4) {
840		c->currnt.crce += crc4;
841		c->currnt.rcrce += ebit;
842	}
843
844	/* Path code violation is frame sync error if CRC4 disabled,
845	 * or CRC error if CRC4 enabled. */
846	pcv = fas;
847	if (c->crc4)
848		pcv += crc4;
849
850	/* Unavaiable second -- receiving all ones, or
851	 * loss of carrier, or loss of signal. */
852	if (acc_status & (TAU32_RUA1 | TAU32_RCL))
853		/* Unavailable second -- no other counters. */
854		++c->currnt.uas;
855	else {
856		/* Line errored second -- any BPV. */
857		if (bpv)
858			++c->currnt.les;
859
860		/* Errored second -- any PCV, or out of frame sync,
861		 * or any slip events. */
862		if (pcv || oof || css)
863			++c->currnt.es;
864
865		/* Severely errored framing second -- out of frame sync. */
866		if (oof)
867			++c->currnt.oofs;
868
869		/* Severely errored seconds --
870		 * 832 or more PCVs, or 2048 or more BPVs. */
871		if (bpv >= 2048 || pcv >= 832)
872			++c->currnt.ses;
873		else {
874			/* Bursty errored seconds --
875			 * no SES and more than 1 PCV. */
876			if (pcv > 1)
877				++c->currnt.bes;
878
879			/* Collect data for computing
880			 * degraded minutes. */
881			++c->degsec;
882			c->degerr += bpv + pcv;
883		}
884	}
885
886	/* Degraded minutes -- having error rate more than 10e-6,
887	 * not counting unavailable and severely errored seconds. */
888	if (c->cursec % 60 == 0) {
889		if (c->degerr > c->degsec * 2048 / 1000)
890			++c->currnt.dm;
891		c->degsec = 0;
892		c->degerr = 0;
893	}
894
895	/* Rotate statistics every 15 minutes. */
896	if (c->cursec > 15*60) {
897		int i;
898
899		for (i=47; i>0; --i)
900			c->interval[i] = c->interval[i-1];
901		c->interval[0] = c->currnt;
902
903		/* Accumulate total statistics. */
904		c->total.bpv   += c->currnt.bpv;
905		c->total.fse   += c->currnt.fse;
906		c->total.crce  += c->currnt.crce;
907		c->total.rcrce += c->currnt.rcrce;
908		c->total.uas   += c->currnt.uas;
909		c->total.les   += c->currnt.les;
910		c->total.es    += c->currnt.es;
911		c->total.bes   += c->currnt.bes;
912		c->total.ses   += c->currnt.ses;
913		c->total.oofs  += c->currnt.oofs;
914		c->total.css   += c->currnt.css;
915		c->total.dm    += c->currnt.dm;
916		c->currnt.bpv	= 0;
917		c->currnt.fse	= 0;
918		c->currnt.crce	= 0;
919		c->currnt.rcrce	= 0;
920		c->currnt.uas	= 0;
921		c->currnt.les	= 0;
922		c->currnt.es	= 0;
923		c->currnt.bes	= 0;
924		c->currnt.ses	= 0;
925		c->currnt.oofs	= 0;
926		c->currnt.css	= 0;
927		c->currnt.dm	= 0;
928
929		c->totsec += c->cursec;
930		c->cursec = 0;
931	}
932}
933
934void ce_set_baud (ce_chan_t *c, unsigned long baud)
935{
936	TAU32_UserRequest *req;
937	ce_board_t *b = c->board;
938	unsigned long cfg = c->config & ~TAU32_framing_mode_mask;
939	unsigned long ts;
940	unsigned long kbps = (baud + 32000) / 64000 * 64;
941
942	if (!c->unfram || c->num != 0 ||
943		baud == c->baud || b->cr.pending >= CONFREQSZ)
944		return;
945
946	if (!kbps || kbps > 1024) {
947		ts = 0xffffffffUL;
948		cfg |= TAU32_unframed_2048;
949	} else if (kbps > 512) {
950		ts = 0x0000ffffUL;
951		cfg |= TAU32_unframed_1024;
952	} else if (kbps > 256) {
953		ts = 0x000000ffUL;
954		cfg |= TAU32_unframed_512;
955	} else if (kbps > 128) {
956		ts = 0x0000000fUL;
957		cfg |= TAU32_unframed_256;
958	} else if (kbps > 64) {
959		ts = 0x00000003UL;
960		cfg |= TAU32_unframed_128;
961	} else {
962		ts = 0x00000001UL;
963		cfg |= TAU32_unframed_64;
964	}
965
966	/* _ce_set_ts () will set proper baud */
967	_ce_set_ts (c, ts);
968	CE_PREREQUEST (b, c, b->cr.queue, req);
969	if (!req)
970		return;
971	req->Command = TAU32_Configure_E1;
972	req->Io.InterfaceConfig.Interface = TAU32_E1_A;
973	req->Io.InterfaceConfig.Config = cfg;
974	req->Io.InterfaceConfig.UnframedTsMask = ts;
975	if (ce_cfg_submit (b)) {
976		c->baud = baud;
977		c->ts = ts;
978		c->config = cfg;
979	}
980}
981
982void ce_set_lloop (ce_chan_t *c, unsigned char on)
983{
984	TAU32_UserRequest *req;
985	unsigned long cfg = c->config & ~(TAU32_line_mode_mask | TAU32_ais_on_loss);
986	ce_board_t *b = c->board;
987
988	if (c->num >= b->ddk.Interfaces || b->cr.pending >= CONFREQSZ)
989		return;
990	on = on ? 1 : 0;
991	if (on == c->lloop)
992		return;
993
994	cfg |= on ? TAU32_LineLoopInt : (TAU32_LineNormal | TAU32_ais_on_loss);
995	CE_PREREQUEST (b, c, b->cr.queue, req);
996	if (!req)
997		return;
998	req->Command = TAU32_Configure_E1;
999	req->Io.InterfaceConfig.Interface = c->num ? TAU32_E1_B : TAU32_E1_A;
1000	req->Io.InterfaceConfig.Config = cfg;
1001	req->Io.InterfaceConfig.UnframedTsMask = c->ts;
1002	CE_DDK_DEBUG (b, c, ("Submit lloop\n"));
1003	if (ce_cfg_submit (b)) {
1004		c->lloop = on ? 1 : 0;
1005		c->config = cfg;
1006	}
1007}
1008
1009void ce_set_rloop (ce_chan_t *c, unsigned char on)
1010{
1011	TAU32_UserRequest *req;
1012	unsigned long cfg = c->config & ~TAU32_line_mode_mask;
1013	ce_board_t *b = c->board;
1014
1015	if (c->num >= b->ddk.Interfaces || b->cr.pending >= CONFREQSZ)
1016		return;
1017	on = on ? 1 : 0;
1018	if (on == c->rloop)
1019		return;
1020
1021	cfg |= on ? TAU32_LineLoopExt : TAU32_LineNormal;
1022	CE_PREREQUEST (b, c, b->cr.queue, req);
1023	if (!req)
1024		return;
1025	req->Command = TAU32_Configure_E1;
1026	req->Io.InterfaceConfig.Interface = c->num ? TAU32_E1_B : TAU32_E1_A;
1027	req->Io.InterfaceConfig.Config = cfg;
1028	req->Io.InterfaceConfig.UnframedTsMask = c->ts;
1029	CE_DDK_DEBUG (b, c, ("Submit rloop\n"));
1030	if (ce_cfg_submit (b)) {
1031		c->rloop = on ? 1 : 0;
1032		c->config = cfg;
1033	}
1034}
1035
1036void ce_set_higain (ce_chan_t *c, unsigned char on)
1037{
1038	TAU32_UserRequest *req;
1039	unsigned long cfg = c->config & ~TAU32_higain;
1040	ce_board_t *b = c->board;
1041
1042	if (c->num >= b->ddk.Interfaces || b->cr.pending >= CONFREQSZ)
1043		return;
1044	on = on ? 1 : 0;
1045	if (on == c->higain)
1046		return;
1047
1048	cfg |= on ? TAU32_higain : 0;
1049	CE_PREREQUEST (b, c, b->cr.queue, req);
1050	if (!req)
1051		return;
1052	req->Command = TAU32_Configure_E1;
1053	req->Io.InterfaceConfig.Interface = c->num ? TAU32_E1_B : TAU32_E1_A;
1054	req->Io.InterfaceConfig.Config = cfg;
1055	req->Io.InterfaceConfig.UnframedTsMask = c->ts;
1056	CE_DDK_DEBUG (b, c, ("Submit higain\n"));
1057	if (ce_cfg_submit (b)) {
1058		c->higain = on ? 1 : 0;
1059		c->config = cfg;
1060	}
1061}
1062
1063static void _ce_set_ts (ce_chan_t *c, unsigned long ts)
1064{
1065	TAU32_UserRequest *req;
1066	ce_board_t *b = c->board;
1067	unsigned long mask = 0, omask = 0;
1068	int nts = 0, ots = 0, pts = 0;
1069	int i, k;
1070
1071	if (b->cr.pending >= CONFREQSZ)
1072		return;
1073
1074	/*
1075	 * pts - number of busy "peb" ts
1076	 * ots - current (old) busy ts
1077	 * nts - new busy ts
1078	 */
1079	for (i = 0; i < 32; i++) {
1080		if (c->ts & (1ul << i))
1081			ots++;
1082		if (ts & (1ul << i))
1083			nts++;
1084		if (b->dxc[i] != TAU32_CROSS_OFF)
1085			pts++;
1086	}
1087
1088	CE_DDK_DEBUG (b, c, ("pts: %d ots: %d nts: %d ts: %lx\n", pts, ots, nts,
1089		      ts));
1090	/* 32 - all busy + my old busy == free */
1091	if (32 - pts + ots - nts < 0)
1092		return;
1093
1094	/* Ok. We have enougth "peb" ts. Clean old. */
1095	/* We start from zero, cause this is peb cells */
1096	for (i = 0; i < 32; i++) {
1097		int tin = b->dxc[i];
1098		int t = tin % 32;
1099		if (tin < (c->dir?64:32) || tin > (c->dir?95:63))
1100			continue;
1101		if (c->ts & (1ul << t)) {
1102			b->dxc[tin] = TAU32_CROSS_OFF;
1103			b->dxc[i] = TAU32_CROSS_OFF;
1104			if (b->dxc[t + 32] == TAU32_CROSS_OFF &&
1105			    b->dxc[t + 64] == TAU32_CROSS_OFF) {
1106				b->dxc[t + 32] = t + 64;
1107				b->dxc[t + 64] = t + 32;
1108			}
1109			omask |= (1ul << t);
1110		}
1111	}
1112
1113	k = 0;
1114	/* Set */
1115	for (i = 0; i < 32; i++) {
1116		if ((ts & (1ul << i)) == 0)
1117			continue;
1118		while (b->dxc[k] != TAU32_CROSS_OFF) {
1119			k++;
1120			/* Paranoic */
1121			if (k >= 32) {
1122				CE_DDK_DEBUG (b, c, ("TS count overflow\n"));
1123				return;
1124			}
1125		}
1126		b->dxc[k] = (c->dir?64:32) + i;
1127		b->dxc[(c->dir?64:32) + i] = k;
1128		if (b->dxc[(c->dir?32:64) + i] == (c->dir?64:32) + i)
1129			b->dxc[(c->dir?32:64) + i] = TAU32_CROSS_OFF;
1130		mask |= (1ul << k);
1131	}
1132
1133	c->ts = ts;
1134	c->baud = nts*64000;
1135
1136	CE_PREREQUEST (b, c, b->cr.queue, req);
1137	if (!req)
1138		return;
1139
1140	req->Command = TAU32_Timeslots_Channel | TAU32_Configure_Commit;
1141	req->Io.ChannelNumber = c->num;
1142	req->Io.ChannelConfig.AssignedTsMask = mask;
1143
1144	if (c->phony) {
1145		b->pmask &= ~omask;
1146		b->pmask |= mask;
1147	}
1148
1149	CE_DDK_DEBUG (b, c, ("ts=%lx mask=%lx omask=%lx pmask=%lx\n", c->ts,
1150		      mask, omask, b->pmask));
1151	CE_DDK_DEBUG (b, c, ("Crossmatrix table:\n"));
1152
1153#ifdef CE_DDK_DEBUG_ENABLED
1154	for (i = 0; i < 32*3; i++) {
1155		printf ("%3d\t%s", b->dxc[i], (i%8==7)?"\n":"");
1156		printf ("%s",(i%32==31)?"\n":"");
1157	}
1158#endif
1159
1160	CE_DDK_DEBUG (b, c, ("Submit tsmask\n"));
1161	if (!ce_cfg_submit (b)) {
1162		CE_DDK_DEBUG (b, c, ("Fail to submit tsmask\n"));
1163		/* Do some error processing */
1164		return;
1165	}
1166
1167	CE_DDK_DEBUG (b, c, ("SetCrossMatrix\n"));
1168	if (!TAU32_SetCrossMatrix(b->ddk.pControllerObject, b->dxc, b->pmask)) {
1169		CE_DDK_DEBUG (b, c, ("Faild to SetCrossMatrix\n"));
1170		/* Do some error processing */
1171		return;
1172	}
1173}
1174
1175void ce_set_ts (ce_chan_t *c, unsigned long ts)
1176{
1177	ce_board_t *b = c->board;
1178	ce_chan_t *x;
1179
1180	if (c->ts == ts || b->chan->unfram)
1181		return;
1182
1183	ts &= ~(1ul);
1184
1185	if (!b->chan[c->dir].use16)
1186		ts &= ~(1ul << 16);
1187
1188	for (x = b->chan; x < b->chan + NCHAN; x++) {
1189		if (x == c || x->dir != c->dir)
1190			continue;
1191		ts &= ~x->ts;
1192	}
1193
1194	_ce_set_ts (c, ts);
1195}
1196
1197void ce_set_unfram (ce_chan_t *c, unsigned char on)
1198{
1199	TAU32_UserRequest *req;
1200	ce_board_t *b = c->board;
1201	unsigned long cfg = c->config & ~TAU32_framing_mode_mask;
1202	unsigned long i;
1203
1204	if (c->num != 0 || b->cr.pending + 2*32 + 3>= CONFREQSZ)
1205		return;
1206
1207	on = on ? 1 : 0;
1208
1209	if (on == c->unfram)
1210		return;
1211
1212	if (on) {
1213		ce_set_dir (c, 0);
1214		for (i = 1; i < TAU32_CHANNELS; i++) {
1215			ce_set_ts (b->chan + i, 0);
1216			ce_set_phony (b->chan + i, 0);
1217		}
1218		ce_set_use16 (b->chan + 0, 0);
1219		ce_set_use16 (b->chan + 1, 0);
1220		/* Get current value, previous ce_set request may change it */
1221		cfg = c->config & ~TAU32_framing_mode_mask;
1222		cfg |= TAU32_unframed_2048;
1223		c->unfram = on;
1224		_ce_set_ts (b->chan, ~0ul);
1225		c->config = cfg;
1226		/* XXXRIK: Do extra checks on config queue size*/
1227		if (b->ddk.Interfaces) {
1228			CE_PREREQUEST (b, c, b->cr.queue, req);
1229			if (!req)
1230				return;
1231			req->Command = TAU32_Configure_E1;
1232			req->Io.InterfaceConfig.Interface = TAU32_E1_B;
1233			req->Io.InterfaceConfig.Config = TAU32_LineOff;
1234			req->Io.InterfaceConfig.UnframedTsMask = 0;
1235			CE_DDK_DEBUG (b, c, ("unfram: B line off\n"));
1236			ce_cfg_submit (b);
1237		}
1238		CE_PREREQUEST (b, c, b->cr.queue, req);
1239		if (!req)
1240			return;
1241		req->Command = TAU32_Configure_E1;
1242		req->Io.InterfaceConfig.Interface = TAU32_E1_A;
1243		req->Io.InterfaceConfig.Config = cfg;
1244		req->Io.InterfaceConfig.UnframedTsMask = c->ts;
1245		CE_DDK_DEBUG (b, c, ("Submit unfram\n"));
1246		ce_cfg_submit (b);
1247	} else {
1248		cfg |= TAU32_framed_cas_cross;
1249		CE_PREREQUEST (b, c, b->cr.queue, req);
1250		if (!req)
1251			return;
1252		req->Command = TAU32_Configure_E1;
1253		req->Io.InterfaceConfig.Interface = TAU32_E1_ALL;
1254		req->Io.InterfaceConfig.Config = cfg;
1255		req->Io.InterfaceConfig.UnframedTsMask = 0;
1256		CE_DDK_DEBUG (b, c, ("Submit framed\n"));
1257		ce_cfg_submit (b);
1258		ce_set_ts (c, 0);
1259	}
1260	c->unfram = on;
1261}
1262
1263void ce_set_phony (ce_chan_t *c, unsigned char on)
1264{
1265	TAU32_UserRequest *req;
1266	ce_board_t *b = c->board;
1267	unsigned long mask = 0;
1268	int i;
1269
1270	if ((c->phony && on) || (c->phony == 0 && on == 0) ||
1271	    b->cr.pending >= CONFREQSZ)
1272		return;
1273
1274	CE_PREREQUEST (b, c, b->cr.queue, req);
1275	if (!req)
1276		return;
1277
1278	req->Command = TAU32_Configure_Channel;
1279	req->Io.InterfaceConfig.Config = on ? TAU32_TMA :
1280		(TAU32_HDLC | TAU32_fr_rx_splitcheck | TAU32_fr_rx_fitcheck);
1281	req->Io.ChannelNumber = c->num;
1282	CE_DDK_DEBUG (b, c, ("Submit phony\n"));
1283	if (!ce_cfg_submit (b)) {
1284		/* Do some error processing */
1285		return;
1286	}
1287
1288	for (i = 0; i < 32; i++) {
1289		int t = b->dxc[i] % 32;
1290		if (b->dxc[i] < (c->dir?64:32) || b->dxc[i] > (c->dir?95:63))
1291			continue;
1292		if (c->ts & (1ul << t))
1293			mask |= (1ul << t);
1294	}
1295
1296	CE_DDK_DEBUG (b, c, ("phony mask:%lx\n", mask));
1297
1298	if (on) {
1299		b->pmask |= mask;
1300	} else {
1301		b->pmask &= ~mask;
1302	}
1303
1304	c->phony = on ? 1 : 0;
1305
1306	CE_DDK_DEBUG (b, c, ("Submit (setcrosmatrix) phony\n"));
1307	if (!TAU32_SetCrossMatrix(b->ddk.pControllerObject, b->dxc, b->pmask)) {
1308		/* Do some error processing */
1309		return;
1310	}
1311}
1312
1313void ce_set_scrambler (ce_chan_t *c, unsigned char on)
1314{
1315	TAU32_UserRequest *req;
1316	unsigned long cfg = c->config & ~TAU32_scrambler;
1317	ce_board_t *b = c->board;
1318
1319	if (c->num != 0 || c->unfram == 0 || b->cr.pending >= CONFREQSZ)
1320		return;
1321	on = on ? 1 : 0;
1322	if (on == c->scrambler)
1323		return;
1324
1325	cfg |= on ? TAU32_scrambler : 0;
1326	CE_PREREQUEST (b, c, b->cr.queue, req);
1327	if (!req)
1328		return;
1329	req->Command = TAU32_Configure_E1;
1330	req->Io.InterfaceConfig.Interface = c->num ? TAU32_E1_B : TAU32_E1_A;
1331	req->Io.InterfaceConfig.Config = cfg;
1332	req->Io.InterfaceConfig.UnframedTsMask = c->ts;
1333	CE_DDK_DEBUG (b, c, ("Submit scrambler\n"));
1334	if (ce_cfg_submit (b)) {
1335		c->scrambler = on ? 1 : 0;
1336		c->config = cfg;
1337	}
1338}
1339
1340void ce_set_monitor (ce_chan_t *c, unsigned char on)
1341{
1342	TAU32_UserRequest *req;
1343	unsigned long cfg = c->config & ~TAU32_monitor;
1344	ce_board_t *b = c->board;
1345
1346	if (c->num >= b->ddk.Interfaces || b->cr.pending >= CONFREQSZ)
1347		return;
1348	on = on ? 1 : 0;
1349	if (on == c->monitor)
1350		return;
1351
1352	cfg |= on ? TAU32_monitor : 0;
1353	CE_PREREQUEST (b, c, b->cr.queue, req);
1354	if (!req)
1355		return;
1356	req->Command = TAU32_Configure_E1;
1357	req->Io.InterfaceConfig.Interface = c->num ? TAU32_E1_B : TAU32_E1_A;
1358	req->Io.InterfaceConfig.Config = cfg;
1359	req->Io.InterfaceConfig.UnframedTsMask = c->ts;
1360	CE_DDK_DEBUG (b, c, ("Submit monitor\n"));
1361	if (ce_cfg_submit (b)) {
1362		c->monitor = on ? 1 : 0;
1363		c->config = cfg;
1364	}
1365}
1366
1367static void _ce_submit_configure_e1 (ce_chan_t *c, char *rname)
1368{
1369	TAU32_UserRequest *req;
1370	ce_board_t *b = c->board;
1371
1372	CE_PREREQUEST (b, c, b->cr.queue, req);
1373	if (!req)
1374		return;
1375	req->Command = TAU32_Configure_E1;
1376	req->Io.InterfaceConfig.Interface = c->num == 0 ? TAU32_E1_A : TAU32_E1_B;
1377	req->Io.InterfaceConfig.Config = c->config;
1378	req->Io.InterfaceConfig.UnframedTsMask = c->ts;
1379	CE_DDK_DEBUG (b, c, ("Submit %s\n", rname ? rname : ""));
1380	if (!ce_cfg_submit (b)) {
1381		CE_DDK_DEBUG (b, c, ("Fail to submit %s\n", rname?rname:""));
1382		/* Do some error processing */
1383		return;
1384	}
1385}
1386
1387void ce_set_use16 (ce_chan_t *c, unsigned char on)
1388{
1389	ce_board_t *b = c->board;
1390	ce_chan_t *x;
1391	unsigned long cfg[2];
1392	int use[2];
1393
1394	if (c->num >= b->ddk.Interfaces || b->cr.pending + 2 >= CONFREQSZ)
1395		return;
1396
1397	cfg[0] = b->chan[0].config & ~TAU32_framing_mode_mask;
1398	cfg[1] = b->chan[1].config & ~TAU32_framing_mode_mask;
1399
1400	on = on ? 1 : 0;
1401
1402	if (c->use16 == on || b->chan->unfram)
1403		return;
1404
1405	use[0] = b->chan[0].use16;
1406	use[1] = b->chan[1].use16;
1407
1408	/* Correct value */
1409	use[c->num] = on;
1410
1411	if (b->ddk.Interfaces == 1) {
1412		cfg[0] |= on ? TAU32_framed_cas_set : TAU32_framed_no_cas;
1413	} else {
1414		if (use[0] == 0 && use[1] == 0) {
1415			cfg[0] |= TAU32_framed_cas_cross;
1416			cfg[1] |= TAU32_framed_cas_cross;
1417		} else if (use[0] == 0) {
1418			cfg[0] |= TAU32_framed_cas_set;
1419			cfg[1] |= TAU32_framed_no_cas;
1420		} else if (use[1] == 0) {
1421			cfg[0] |= TAU32_framed_no_cas;
1422			cfg[1] |= TAU32_framed_cas_set;
1423		} else {
1424			cfg[0] |= TAU32_framed_no_cas;
1425			cfg[1] |= TAU32_framed_no_cas;
1426		}
1427	}
1428
1429	c->use16 = on;
1430
1431	for (x = b->chan; !on && x < b->chan + NCHAN; x++) {
1432		if (x->dir == c->num && x->ts & (1ul<<16)) {
1433			ce_set_ts (x, x->ts);
1434			break;
1435		}
1436	}
1437
1438	if (cfg[0] != b->chan[0].config) {
1439		b->chan[0].config = cfg[0];
1440		_ce_submit_configure_e1 (b->chan + 0, "use16");
1441	}
1442
1443	if (cfg[1] != b->chan[1].config) {
1444		b->chan[1].config = cfg[1];
1445		_ce_submit_configure_e1 (b->chan + 1, "use16");
1446	}
1447}
1448
1449void ce_set_crc4 (ce_chan_t *c, unsigned char on)
1450{
1451	TAU32_UserRequest *req;
1452	unsigned long cfg = c->config & ~TAU32_crc4_mf;
1453	ce_board_t *b = c->board;
1454
1455	if (c->num >= b->ddk.Interfaces || b->cr.pending >= CONFREQSZ)
1456		return;
1457	on = on ? 1 : 0;
1458	if (on == c->crc4 || b->chan->unfram)
1459		return;
1460
1461	cfg |= on ? TAU32_crc4_mf : 0;
1462	CE_PREREQUEST (b, c, b->cr.queue, req);
1463	if (!req)
1464		return;
1465	req->Command = TAU32_Configure_E1;
1466	req->Io.InterfaceConfig.Interface = c->num ? TAU32_E1_B : TAU32_E1_A;
1467	req->Io.InterfaceConfig.Config = cfg;
1468	req->Io.InterfaceConfig.UnframedTsMask = c->ts;
1469	CE_DDK_DEBUG (b, c, ("Submit crc4\n"));
1470	if (ce_cfg_submit (b)) {
1471		c->crc4 = on ? 1 : 0;
1472		c->config = cfg;
1473	}
1474}
1475
1476void ce_set_gsyn (ce_chan_t *c, int syn)
1477{
1478	ce_board_t *b = c->board;
1479	unsigned int mode;
1480
1481	if (c->num >= b->ddk.Interfaces)
1482		return;
1483
1484	if (syn == GSYN_RCV)
1485		syn = c->num ? GSYN_RCV1 : GSYN_RCV0;
1486
1487	switch (syn) {
1488	default:	mode = TAU32_SYNC_INTERNAL;	break;
1489	case GSYN_RCV0:	mode = TAU32_SYNC_RCV_A;	break;
1490	case GSYN_RCV1:	mode = TAU32_SYNC_RCV_B;	break;
1491	}
1492
1493	CE_DDK_DEBUG (b, c, ("Set Sync Mode\n"));
1494	if (TAU32_SetSyncMode (b->ddk.pControllerObject, mode)) {
1495		b->chan->gsyn = syn;
1496		if (b->ddk.Interfaces > 1)
1497			(b->chan + 1)->gsyn = syn;
1498	}
1499}
1500
1501int ce_get_cable (ce_chan_t *c)
1502{
1503	ce_board_t *b = c->board;
1504	if (c->num >= b->ddk.Interfaces)
1505		return 0;
1506
1507	return CABLE_TP;
1508}
1509
1510void ce_set_dir (ce_chan_t *c, int dir)
1511{
1512	ce_board_t *b = c->board;
1513	unsigned long ts;
1514	if (b->cr.pending + 1>= CONFREQSZ || c->dir == dir)
1515		return;
1516
1517	ts = c->ts;
1518	ce_set_ts (c, 0);
1519	c->dir = dir;
1520	ce_set_ts (c, ts);
1521}
1522