xref: /freebsd-12.1/sys/dev/ce/ceddk.c (revision e54226a3)
1 /*
2  * Middle-level code for Cronyx Tau32-PCI adapters.
3  *
4  * Copyright (C) 2004 Cronyx Engineering
5  * Copyright (C) 2004 Roman Kurakin <[email protected]>
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/cx/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 
142 static void _ce_set_ts (ce_chan_t *c, unsigned long ts);
143 static void _ce_submit_configure_e1 (ce_chan_t *c, char *rname);
144 
145 #ifdef CE_DDK_DEBUG_ENABLED
ce_err2str(unsigned long err)146 static 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 
ce_set_dtr(ce_chan_t * c,int on)201 void ce_set_dtr (ce_chan_t *c, int on)
202 {
203 	c->dtr = on?1:0;
204 }
205 
ce_set_rts(ce_chan_t * c,int on)206 void ce_set_rts (ce_chan_t *c, int on)
207 {
208 	c->rts = on?1:0;
209 }
210 
ce_on_receive(TAU32_UserContext * pContext,TAU32_UserRequest * req)211 static 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 
ce_on_transmit(TAU32_UserContext * pContext,TAU32_UserRequest * req)272 static 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 
ce_transmit_space(ce_chan_t * c)311 int ce_transmit_space (ce_chan_t *c)
312 {
313 	return c->tx_pending < (TAU32_IO_QUEUE);
314 }
315 
ce_send_packet(ce_chan_t * c,unsigned char * buf,int len,void * tag)316 int 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 
ce_on_config(TAU32_UserContext * pContext,TAU32_UserRequest * req)356 static 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 
ce_on_config_stop(TAU32_UserContext * pContext,TAU32_UserRequest * req)368 static 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 
ce_cfg_submit(ce_board_t * b)406 static 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 
ce_init_board(ce_board_t * b)431 void 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 
ce_start_chan(ce_chan_t * c,int tx,int rx,ce_buf_t * cb,unsigned long phys)527 void 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 
ce_stop_chan(ce_chan_t * c)618 void 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 
649 
ce_register_transmit(ce_chan_t * c,void (* func)(ce_chan_t *,void *,int))650 void ce_register_transmit (ce_chan_t *c,
651 	void (*func) (ce_chan_t*, void*, int))
652 {
653 	c->transmit = func;
654 }
655 
ce_register_receive(ce_chan_t * c,void (* func)(ce_chan_t *,unsigned char *,int))656 void ce_register_receive (ce_chan_t *c,
657 	void (*func) (ce_chan_t*, unsigned char*, int))
658 {
659 	c->receive = func;
660 }
661 
ce_register_error(ce_chan_t * c,void (* func)(ce_chan_t *,int))662 void ce_register_error (ce_chan_t *c,
663 	void (*func) (ce_chan_t*, int))
664 {
665 	c->error = func;
666 }
667 
ce_error_callback(TAU32_UserContext * pContext,int Item,unsigned NotifyBits)668 void TAU32_CALLBACK_TYPE ce_error_callback (TAU32_UserContext *pContext,
669 						int Item, unsigned NotifyBits)
670 {
671 	ce_board_t *b = (ce_board_t *) pContext;
672 	ENTER ();
673 	if (NotifyBits & (TAU32_ERROR_FAIL | TAU32_ERROR_TIMEOUT
674 		| TAU32_ERROR_INT_OVER_TX | TAU32_ERROR_INT_OVER_RX
675 		| TAU32_ERROR_INT_STORM)) {
676 		/* Fatal: adapter failure, need reset & restart */
677 		/* RIKXXX: probably I should add CE_FAILURE for ce_error */
678 		CE_DDK_DEBUG (b, (ce_chan_t *)0, ("Err, disable interrupts: %s\n",
679 				ce_err2str (NotifyBits)));
680 /*		TAU32_DisableInterrupts (b->ddk.pControllerObject);*/
681 		EXIT ();
682 	}
683 	if (Item >= 0) {
684 		/* channel error */
685 		ce_chan_t *c = b->chan + Item;
686 		if (NotifyBits & TAU32_ERROR_TX_UNDERFLOW) {
687 			c->underrun++;
688 			if (c->error)
689 				c->error (c, CE_UNDERRUN);
690 		}
691 		if (NotifyBits & TAU32_ERROR_RX_OVERFLOW) {
692 			c->overrun++;
693 			if (c->error)
694 				c->error (c, CE_OVERFLOW);
695 		}
696 		if (NotifyBits & (TAU32_ERROR_RX_FRAME | TAU32_ERROR_RX_ABORT |
697 		    TAU32_ERROR_RX_SHORT | TAU32_ERROR_RX_LONG |
698 		    TAU32_ERROR_RX_SYNC | TAU32_ERROR_RX_SPLIT |
699 		    TAU32_ERROR_RX_UNFIT)) {
700 			c->frame++;
701 			CE_DDK_DEBUG (b, c, ("Frame error: %x\n", NotifyBits));
702 			if (c->error)
703 				c->error (c, CE_FRAME);
704 		}
705 		if(NotifyBits & TAU32_ERROR_RX_CRC) {
706 			c->crc++;
707 			if (c->error)
708 				c->error (c, CE_CRC);
709 		}
710 	} else {
711 		CE_DDK_DEBUG (b, (ce_chan_t *)0, ("Another error: %x\n",
712 			      NotifyBits));
713 		/* Adapter error, do smth */
714 	}
715 	EXIT ();
716 }
717 
ce_status_callback(TAU32_UserContext * pContext,int Item,unsigned NotifyBits)718 void TAU32_CALLBACK_TYPE ce_status_callback(TAU32_UserContext *pContext,
719 						int Item, unsigned NotifyBits)
720 {
721 	ce_board_t *b = (ce_board_t *) pContext;
722 	ENTER ();
723 	if(Item >= 0) {
724 		/* e1 status */
725 		ce_chan_t *c = b->chan + Item;
726 		c->acc_status |= b->ddk.InterfacesInfo[Item].Status;
727 /*		CE_DDK_DEBUG (b, c, ("Current status: %x\n", c->acc_status));*/
728 	} else {
729 		CE_DDK_DEBUG (b, (ce_chan_t *)0, ("Another status: %x\n", NotifyBits));
730 		/* Adapter status, do smth. */
731 	}
732 	EXIT ();
733 }
734 
ce_get_cd(ce_chan_t * c)735 int ce_get_cd (ce_chan_t *c)
736 {
737 	unsigned int e1status = c->board->ddk.InterfacesInfo[c->dir].Status;
738 
739 	return (c->ts && !(e1status & (TAU32_RCL | TAU32_E1OFF)));
740 }
741 
ce_get_cts(ce_chan_t * c)742 int ce_get_cts (ce_chan_t *c)
743 {
744 	return 0;
745 }
746 
ce_get_dsr(ce_chan_t * c)747 int ce_get_dsr (ce_chan_t *c)
748 {
749 	return 0;
750 }
751 
ce_e1_timer(ce_chan_t * c)752 void ce_e1_timer (ce_chan_t *c)
753 {
754 	unsigned bpv, fas, crc4, ebit, pcv, oof, css;
755 	unsigned int acc_status;
756 	ce_board_t *b = c->board;
757 	TAU32_E1_State	*state;
758 
759 	if (c->num >= b->ddk.Interfaces)
760 		return;
761 
762 	state = &b->ddk.InterfacesInfo[c->num];
763 	acc_status = c->acc_status;
764 
765 	/* Clear acc_status */
766 	c->acc_status = b->ddk.InterfacesInfo[c->num].Status;
767 
768 	/* Count seconds.
769 	 * During the first second after the channel startup
770 	 * the status registers are not stable yet,
771 	 * we will so skip the first second. */
772 	++c->cursec;
773 	if (! c->totsec && c->cursec <= 1)
774 		return;
775 
776 	c->status = 0;
777 
778 	/* Compute the SNMP-compatible channel status. */
779 	oof = 0;
780 
781 	if (acc_status & TAU32_RCL)
782 		c->status |= ESTS_LOS;		/* loss of signal */
783 	if (acc_status & TAU32_RUA1)
784 		c->status |= ESTS_AIS;		/* receiving all ones */
785 
786 	/* Get error counters. */
787 	bpv = state->RxViolations;
788 	fas = 0;
789 	crc4 = 0;
790 	ebit = 0;
791 	css = 0;
792 
793 	if (! c->unfram) {
794 		if (! c->use16 && (acc_status & TAU32_RSA1))
795 			c->status |= ESTS_AIS16;	/* signaling all ones */
796 		if (! c->use16 && (acc_status & TAU32_RDMA))
797 			c->status |= ESTS_FARLOMF;	/* alarm in timeslot 16 */
798 		if (acc_status & TAU32_RRA)
799 			c->status |= ESTS_FARLOF;	/* far loss of framing */
800 
801 		if (acc_status & TAU32_RFAS) {
802 			c->status |= ESTS_LOF;		/* loss of framing */
803 			++oof;				/* out of framing */
804 		}
805 		if ((! c->use16 && (acc_status & TAU32_RCAS)) ||
806 		    (c->crc4 && (acc_status & TAU32_RCRC4))) {
807 			c->status |= ESTS_LOMF;		/* loss of multiframing */
808 			++oof;				/* out of framing */
809 		}
810 		fas = state->FasErrors;
811 		crc4 = state->Crc4Errors;
812 		ebit = state->FarEndBlockErrors;
813 
814 		/* Controlled slip second -- any slip event. */
815 		css = state->TransmitSlips + state->ReceiveSlips;
816 	}
817 
818 	/* Clear state */
819 	state->RxViolations		= 0;
820 	state->FasErrors		= 0;
821 	state->Crc4Errors		= 0;
822 	state->FarEndBlockErrors	= 0;
823 	state->TransmitSlips		= 0;
824 	state->ReceiveSlips		= 0;
825 
826 	if (c->status & ESTS_LOS)
827 		c->status = ESTS_LOS;
828 	else if (c->status & ESTS_AIS)
829 		c->status = ESTS_AIS;
830 	else if (c->status & ESTS_LOF)
831 		c->status = ESTS_LOF;
832 	else if (c->status & ESTS_LOMF)
833 		c->status &= ~(ESTS_FARLOMF | ESTS_AIS16);
834 
835 	if (! c->status)
836 		c->status = ESTS_NOALARM;
837 
838 	c->currnt.bpv += bpv;
839 	c->currnt.fse += fas;
840 	if (c->crc4) {
841 		c->currnt.crce += crc4;
842 		c->currnt.rcrce += ebit;
843 	}
844 
845 	/* Path code violation is frame sync error if CRC4 disabled,
846 	 * or CRC error if CRC4 enabled. */
847 	pcv = fas;
848 	if (c->crc4)
849 		pcv += crc4;
850 
851 	/* Unavaiable second -- receiving all ones, or
852 	 * loss of carrier, or loss of signal. */
853 	if (acc_status & (TAU32_RUA1 | TAU32_RCL))
854 		/* Unavailable second -- no other counters. */
855 		++c->currnt.uas;
856 	else {
857 		/* Line errored second -- any BPV. */
858 		if (bpv)
859 			++c->currnt.les;
860 
861 		/* Errored second -- any PCV, or out of frame sync,
862 		 * or any slip events. */
863 		if (pcv || oof || css)
864 			++c->currnt.es;
865 
866 		/* Severely errored framing second -- out of frame sync. */
867 		if (oof)
868 			++c->currnt.oofs;
869 
870 		/* Severely errored seconds --
871 		 * 832 or more PCVs, or 2048 or more BPVs. */
872 		if (bpv >= 2048 || pcv >= 832)
873 			++c->currnt.ses;
874 		else {
875 			/* Bursty errored seconds --
876 			 * no SES and more than 1 PCV. */
877 			if (pcv > 1)
878 				++c->currnt.bes;
879 
880 			/* Collect data for computing
881 			 * degraded minutes. */
882 			++c->degsec;
883 			c->degerr += bpv + pcv;
884 		}
885 	}
886 
887 	/* Degraded minutes -- having error rate more than 10e-6,
888 	 * not counting unavailable and severely errored seconds. */
889 	if (c->cursec % 60 == 0) {
890 		if (c->degerr > c->degsec * 2048 / 1000)
891 			++c->currnt.dm;
892 		c->degsec = 0;
893 		c->degerr = 0;
894 	}
895 
896 	/* Rotate statistics every 15 minutes. */
897 	if (c->cursec > 15*60) {
898 		int i;
899 
900 		for (i=47; i>0; --i)
901 			c->interval[i] = c->interval[i-1];
902 		c->interval[0] = c->currnt;
903 
904 		/* Accumulate total statistics. */
905 		c->total.bpv   += c->currnt.bpv;
906 		c->total.fse   += c->currnt.fse;
907 		c->total.crce  += c->currnt.crce;
908 		c->total.rcrce += c->currnt.rcrce;
909 		c->total.uas   += c->currnt.uas;
910 		c->total.les   += c->currnt.les;
911 		c->total.es    += c->currnt.es;
912 		c->total.bes   += c->currnt.bes;
913 		c->total.ses   += c->currnt.ses;
914 		c->total.oofs  += c->currnt.oofs;
915 		c->total.css   += c->currnt.css;
916 		c->total.dm    += c->currnt.dm;
917 		c->currnt.bpv	= 0;
918 		c->currnt.fse	= 0;
919 		c->currnt.crce	= 0;
920 		c->currnt.rcrce	= 0;
921 		c->currnt.uas	= 0;
922 		c->currnt.les	= 0;
923 		c->currnt.es	= 0;
924 		c->currnt.bes	= 0;
925 		c->currnt.ses	= 0;
926 		c->currnt.oofs	= 0;
927 		c->currnt.css	= 0;
928 		c->currnt.dm	= 0;
929 
930 		c->totsec += c->cursec;
931 		c->cursec = 0;
932 	}
933 }
934 
ce_set_baud(ce_chan_t * c,unsigned long baud)935 void ce_set_baud (ce_chan_t *c, unsigned long baud)
936 {
937 	TAU32_UserRequest *req;
938 	ce_board_t *b = c->board;
939 	unsigned long cfg = c->config & ~TAU32_framing_mode_mask;
940 	unsigned long ts;
941 	unsigned long kbps = (baud + 32000) / 64000 * 64;
942 
943 	if (!c->unfram || c->num != 0 ||
944 		baud == c->baud || b->cr.pending >= CONFREQSZ)
945 		return;
946 
947 	if (!kbps || kbps > 1024) {
948 		ts = 0xffffffffUL;
949 		cfg |= TAU32_unframed_2048;
950 	} else if (kbps > 512) {
951 		ts = 0x0000ffffUL;
952 		cfg |= TAU32_unframed_1024;
953 	} else if (kbps > 256) {
954 		ts = 0x000000ffUL;
955 		cfg |= TAU32_unframed_512;
956 	} else if (kbps > 128) {
957 		ts = 0x0000000fUL;
958 		cfg |= TAU32_unframed_256;
959 	} else if (kbps > 64) {
960 		ts = 0x00000003UL;
961 		cfg |= TAU32_unframed_128;
962 	} else {
963 		ts = 0x00000001UL;
964 		cfg |= TAU32_unframed_64;
965 	}
966 
967 	/* _ce_set_ts () will set proper baud */
968 	_ce_set_ts (c, ts);
969 	CE_PREREQUEST (b, c, b->cr.queue, req);
970 	if (!req)
971 		return;
972 	req->Command = TAU32_Configure_E1;
973 	req->Io.InterfaceConfig.Interface = TAU32_E1_A;
974 	req->Io.InterfaceConfig.Config = cfg;
975 	req->Io.InterfaceConfig.UnframedTsMask = ts;
976 	if (ce_cfg_submit (b)) {
977 		c->baud = baud;
978 		c->ts = ts;
979 		c->config = cfg;
980 	}
981 }
982 
ce_set_lloop(ce_chan_t * c,unsigned char on)983 void ce_set_lloop (ce_chan_t *c, unsigned char on)
984 {
985 	TAU32_UserRequest *req;
986 	unsigned long cfg = c->config & ~(TAU32_line_mode_mask | TAU32_ais_on_loss);
987 	ce_board_t *b = c->board;
988 
989 	if (c->num >= b->ddk.Interfaces || b->cr.pending >= CONFREQSZ)
990 		return;
991 	on = on ? 1 : 0;
992 	if (on == c->lloop)
993 		return;
994 
995 	cfg |= on ? TAU32_LineLoopInt : (TAU32_LineNormal | TAU32_ais_on_loss);
996 	CE_PREREQUEST (b, c, b->cr.queue, req);
997 	if (!req)
998 		return;
999 	req->Command = TAU32_Configure_E1;
1000 	req->Io.InterfaceConfig.Interface = c->num ? TAU32_E1_B : TAU32_E1_A;
1001 	req->Io.InterfaceConfig.Config = cfg;
1002 	req->Io.InterfaceConfig.UnframedTsMask = c->ts;
1003 	CE_DDK_DEBUG (b, c, ("Submit lloop\n"));
1004 	if (ce_cfg_submit (b)) {
1005 		c->lloop = on ? 1 : 0;
1006 		c->config = cfg;
1007 	}
1008 }
1009 
ce_set_rloop(ce_chan_t * c,unsigned char on)1010 void ce_set_rloop (ce_chan_t *c, unsigned char on)
1011 {
1012 	TAU32_UserRequest *req;
1013 	unsigned long cfg = c->config & ~TAU32_line_mode_mask;
1014 	ce_board_t *b = c->board;
1015 
1016 	if (c->num >= b->ddk.Interfaces || b->cr.pending >= CONFREQSZ)
1017 		return;
1018 	on = on ? 1 : 0;
1019 	if (on == c->rloop)
1020 		return;
1021 
1022 	cfg |= on ? TAU32_LineLoopExt : TAU32_LineNormal;
1023 	CE_PREREQUEST (b, c, b->cr.queue, req);
1024 	if (!req)
1025 		return;
1026 	req->Command = TAU32_Configure_E1;
1027 	req->Io.InterfaceConfig.Interface = c->num ? TAU32_E1_B : TAU32_E1_A;
1028 	req->Io.InterfaceConfig.Config = cfg;
1029 	req->Io.InterfaceConfig.UnframedTsMask = c->ts;
1030 	CE_DDK_DEBUG (b, c, ("Submit rloop\n"));
1031 	if (ce_cfg_submit (b)) {
1032 		c->rloop = on ? 1 : 0;
1033 		c->config = cfg;
1034 	}
1035 }
1036 
ce_set_higain(ce_chan_t * c,unsigned char on)1037 void ce_set_higain (ce_chan_t *c, unsigned char on)
1038 {
1039 	TAU32_UserRequest *req;
1040 	unsigned long cfg = c->config & ~TAU32_higain;
1041 	ce_board_t *b = c->board;
1042 
1043 	if (c->num >= b->ddk.Interfaces || b->cr.pending >= CONFREQSZ)
1044 		return;
1045 	on = on ? 1 : 0;
1046 	if (on == c->higain)
1047 		return;
1048 
1049 	cfg |= on ? TAU32_higain : 0;
1050 	CE_PREREQUEST (b, c, b->cr.queue, req);
1051 	if (!req)
1052 		return;
1053 	req->Command = TAU32_Configure_E1;
1054 	req->Io.InterfaceConfig.Interface = c->num ? TAU32_E1_B : TAU32_E1_A;
1055 	req->Io.InterfaceConfig.Config = cfg;
1056 	req->Io.InterfaceConfig.UnframedTsMask = c->ts;
1057 	CE_DDK_DEBUG (b, c, ("Submit higain\n"));
1058 	if (ce_cfg_submit (b)) {
1059 		c->higain = on ? 1 : 0;
1060 		c->config = cfg;
1061 	}
1062 }
1063 
_ce_set_ts(ce_chan_t * c,unsigned long ts)1064 static void _ce_set_ts (ce_chan_t *c, unsigned long ts)
1065 {
1066 	TAU32_UserRequest *req;
1067 	ce_board_t *b = c->board;
1068 	unsigned long mask = 0, omask = 0;
1069 	int nts = 0, ots = 0, pts = 0;
1070 	int i, k;
1071 
1072 	if (b->cr.pending >= CONFREQSZ)
1073 		return;
1074 
1075 	/*
1076 	 * pts - number of busy "peb" ts
1077 	 * ots - current (old) busy ts
1078 	 * nts - new busy ts
1079 	 */
1080 	for (i = 0; i < 32; i++) {
1081 		if (c->ts & (1ul << i))
1082 			ots++;
1083 		if (ts & (1ul << i))
1084 			nts++;
1085 		if (b->dxc[i] != TAU32_CROSS_OFF)
1086 			pts++;
1087 	}
1088 
1089 	CE_DDK_DEBUG (b, c, ("pts: %d ots: %d nts: %d ts: %lx\n", pts, ots, nts,
1090 		      ts));
1091 	/* 32 - all busy + my old busy == free */
1092 	if (32 - pts + ots - nts < 0)
1093 		return;
1094 
1095 	/* Ok. We have enougth "peb" ts. Clean old. */
1096 	/* We start from zero, cause this is peb cells */
1097 	for (i = 0; i < 32; i++) {
1098 		int tin = b->dxc[i];
1099 		int t = tin % 32;
1100 		if (tin < (c->dir?64:32) || tin > (c->dir?95:63))
1101 			continue;
1102 		if (c->ts & (1ul << t)) {
1103 			b->dxc[tin] = TAU32_CROSS_OFF;
1104 			b->dxc[i] = TAU32_CROSS_OFF;
1105 			if (b->dxc[t + 32] == TAU32_CROSS_OFF &&
1106 			    b->dxc[t + 64] == TAU32_CROSS_OFF) {
1107 				b->dxc[t + 32] = t + 64;
1108 				b->dxc[t + 64] = t + 32;
1109 			}
1110 			omask |= (1ul << t);
1111 		}
1112 	}
1113 
1114 	k = 0;
1115 	/* Set */
1116 	for (i = 0; i < 32; i++) {
1117 		if ((ts & (1ul << i)) == 0)
1118 			continue;
1119 		while (b->dxc[k] != TAU32_CROSS_OFF) {
1120 			k++;
1121 			/* Paranoic */
1122 			if (k >= 32) {
1123 				CE_DDK_DEBUG (b, c, ("TS count overflow\n"));
1124 				return;
1125 			}
1126 		}
1127 		b->dxc[k] = (c->dir?64:32) + i;
1128 		b->dxc[(c->dir?64:32) + i] = k;
1129 		if (b->dxc[(c->dir?32:64) + i] == (c->dir?64:32) + i)
1130 			b->dxc[(c->dir?32:64) + i] = TAU32_CROSS_OFF;
1131 		mask |= (1ul << k);
1132 	}
1133 
1134 	c->ts = ts;
1135 	c->baud = nts*64000;
1136 
1137 	CE_PREREQUEST (b, c, b->cr.queue, req);
1138 	if (!req)
1139 		return;
1140 
1141 	req->Command = TAU32_Timeslots_Channel | TAU32_Configure_Commit;
1142 	req->Io.ChannelNumber = c->num;
1143 	req->Io.ChannelConfig.AssignedTsMask = mask;
1144 
1145 	if (c->phony) {
1146 		b->pmask &= ~omask;
1147 		b->pmask |= mask;
1148 	}
1149 
1150 	CE_DDK_DEBUG (b, c, ("ts=%lx mask=%lx omask=%lx pmask=%lx\n", c->ts,
1151 		      mask, omask, b->pmask));
1152 	CE_DDK_DEBUG (b, c, ("Crossmatrix table:\n"));
1153 
1154 #ifdef CE_DDK_DEBUG_ENABLED
1155 	for (i = 0; i < 32*3; i++) {
1156 		printf ("%3d\t%s", b->dxc[i], (i%8==7)?"\n":"");
1157 		printf ("%s",(i%32==31)?"\n":"");
1158 	}
1159 #endif
1160 
1161 	CE_DDK_DEBUG (b, c, ("Submit tsmask\n"));
1162 	if (!ce_cfg_submit (b)) {
1163 		CE_DDK_DEBUG (b, c, ("Fail to submit tsmask\n"));
1164 		/* Do some error processing */
1165 		return;
1166 	}
1167 
1168 	CE_DDK_DEBUG (b, c, ("SetCrossMatrix\n"));
1169 	if (!TAU32_SetCrossMatrix(b->ddk.pControllerObject, b->dxc, b->pmask)) {
1170 		CE_DDK_DEBUG (b, c, ("Faild to SetCrossMatrix\n"));
1171 		/* Do some error processing */
1172 		return;
1173 	}
1174 }
1175 
ce_set_ts(ce_chan_t * c,unsigned long ts)1176 void ce_set_ts (ce_chan_t *c, unsigned long ts)
1177 {
1178 	ce_board_t *b = c->board;
1179 	ce_chan_t *x;
1180 
1181 	if (c->ts == ts || b->chan->unfram)
1182 		return;
1183 
1184 	ts &= ~(1ul);
1185 
1186 	if (!b->chan[c->dir].use16)
1187 		ts &= ~(1ul << 16);
1188 
1189 	for (x = b->chan; x < b->chan + NCHAN; x++) {
1190 		if (x == c || x->dir != c->dir)
1191 			continue;
1192 		ts &= ~x->ts;
1193 	}
1194 
1195 	_ce_set_ts (c, ts);
1196 }
1197 
ce_set_unfram(ce_chan_t * c,unsigned char on)1198 void ce_set_unfram (ce_chan_t *c, unsigned char on)
1199 {
1200 	TAU32_UserRequest *req;
1201 	ce_board_t *b = c->board;
1202 	unsigned long cfg = c->config & ~TAU32_framing_mode_mask;
1203 	unsigned long i;
1204 
1205 	if (c->num != 0 || b->cr.pending + 2*32 + 3>= CONFREQSZ)
1206 		return;
1207 
1208 	on = on ? 1 : 0;
1209 
1210 	if (on == c->unfram)
1211 		return;
1212 
1213 	if (on) {
1214 		ce_set_dir (c, 0);
1215 		for (i = 1; i < TAU32_CHANNELS; i++) {
1216 			ce_set_ts (b->chan + i, 0);
1217 			ce_set_phony (b->chan + i, 0);
1218 		}
1219 		ce_set_use16 (b->chan + 0, 0);
1220 		ce_set_use16 (b->chan + 1, 0);
1221 		/* Get current value, previous ce_set request may change it */
1222 		cfg = c->config & ~TAU32_framing_mode_mask;
1223 		cfg |= TAU32_unframed_2048;
1224 		c->unfram = on;
1225 		_ce_set_ts (b->chan, ~0ul);
1226 		c->config = cfg;
1227 		/* XXXRIK: Do extra checks on config queue size*/
1228 		if (b->ddk.Interfaces) {
1229 			CE_PREREQUEST (b, c, b->cr.queue, req);
1230 			if (!req)
1231 				return;
1232 			req->Command = TAU32_Configure_E1;
1233 			req->Io.InterfaceConfig.Interface = TAU32_E1_B;
1234 			req->Io.InterfaceConfig.Config = TAU32_LineOff;
1235 			req->Io.InterfaceConfig.UnframedTsMask = 0;
1236 			CE_DDK_DEBUG (b, c, ("unfram: B line off\n"));
1237 			ce_cfg_submit (b);
1238 		}
1239 		CE_PREREQUEST (b, c, b->cr.queue, req);
1240 		if (!req)
1241 			return;
1242 		req->Command = TAU32_Configure_E1;
1243 		req->Io.InterfaceConfig.Interface = TAU32_E1_A;
1244 		req->Io.InterfaceConfig.Config = cfg;
1245 		req->Io.InterfaceConfig.UnframedTsMask = c->ts;
1246 		CE_DDK_DEBUG (b, c, ("Submit unfram\n"));
1247 		ce_cfg_submit (b);
1248 	} else {
1249 		cfg |= TAU32_framed_cas_cross;
1250 		CE_PREREQUEST (b, c, b->cr.queue, req);
1251 		if (!req)
1252 			return;
1253 		req->Command = TAU32_Configure_E1;
1254 		req->Io.InterfaceConfig.Interface = TAU32_E1_ALL;
1255 		req->Io.InterfaceConfig.Config = cfg;
1256 		req->Io.InterfaceConfig.UnframedTsMask = 0;
1257 		CE_DDK_DEBUG (b, c, ("Submit framed\n"));
1258 		ce_cfg_submit (b);
1259 		ce_set_ts (c, 0);
1260 	}
1261 	c->unfram = on;
1262 }
1263 
ce_set_phony(ce_chan_t * c,unsigned char on)1264 void ce_set_phony (ce_chan_t *c, unsigned char on)
1265 {
1266 	TAU32_UserRequest *req;
1267 	ce_board_t *b = c->board;
1268 	unsigned long mask = 0;
1269 	int i;
1270 
1271 	if ((c->phony && on) || (c->phony == 0 && on == 0) ||
1272 	    b->cr.pending >= CONFREQSZ)
1273 		return;
1274 
1275 	CE_PREREQUEST (b, c, b->cr.queue, req);
1276 	if (!req)
1277 		return;
1278 
1279 	req->Command = TAU32_Configure_Channel;
1280 	req->Io.InterfaceConfig.Config = on ? TAU32_TMA :
1281 		(TAU32_HDLC | TAU32_fr_rx_splitcheck | TAU32_fr_rx_fitcheck);
1282 	req->Io.ChannelNumber = c->num;
1283 	CE_DDK_DEBUG (b, c, ("Submit phony\n"));
1284 	if (!ce_cfg_submit (b)) {
1285 		/* Do some error processing */
1286 		return;
1287 	}
1288 
1289 	for (i = 0; i < 32; i++) {
1290 		int t = b->dxc[i] % 32;
1291 		if (b->dxc[i] < (c->dir?64:32) || b->dxc[i] > (c->dir?95:63))
1292 			continue;
1293 		if (c->ts & (1ul << t))
1294 			mask |= (1ul << t);
1295 	}
1296 
1297 	CE_DDK_DEBUG (b, c, ("phony mask:%lx\n", mask));
1298 
1299 	if (on) {
1300 		b->pmask |= mask;
1301 	} else {
1302 		b->pmask &= ~mask;
1303 	}
1304 
1305 	c->phony = on ? 1 : 0;
1306 
1307 	CE_DDK_DEBUG (b, c, ("Submit (setcrosmatrix) phony\n"));
1308 	if (!TAU32_SetCrossMatrix(b->ddk.pControllerObject, b->dxc, b->pmask)) {
1309 		/* Do some error processing */
1310 		return;
1311 	}
1312 }
1313 
ce_set_scrambler(ce_chan_t * c,unsigned char on)1314 void ce_set_scrambler (ce_chan_t *c, unsigned char on)
1315 {
1316 	TAU32_UserRequest *req;
1317 	unsigned long cfg = c->config & ~TAU32_scrambler;
1318 	ce_board_t *b = c->board;
1319 
1320 	if (c->num != 0 || c->unfram == 0 || b->cr.pending >= CONFREQSZ)
1321 		return;
1322 	on = on ? 1 : 0;
1323 	if (on == c->scrambler)
1324 		return;
1325 
1326 	cfg |= on ? TAU32_scrambler : 0;
1327 	CE_PREREQUEST (b, c, b->cr.queue, req);
1328 	if (!req)
1329 		return;
1330 	req->Command = TAU32_Configure_E1;
1331 	req->Io.InterfaceConfig.Interface = c->num ? TAU32_E1_B : TAU32_E1_A;
1332 	req->Io.InterfaceConfig.Config = cfg;
1333 	req->Io.InterfaceConfig.UnframedTsMask = c->ts;
1334 	CE_DDK_DEBUG (b, c, ("Submit scrambler\n"));
1335 	if (ce_cfg_submit (b)) {
1336 		c->scrambler = on ? 1 : 0;
1337 		c->config = cfg;
1338 	}
1339 }
1340 
ce_set_monitor(ce_chan_t * c,unsigned char on)1341 void ce_set_monitor (ce_chan_t *c, unsigned char on)
1342 {
1343 	TAU32_UserRequest *req;
1344 	unsigned long cfg = c->config & ~TAU32_monitor;
1345 	ce_board_t *b = c->board;
1346 
1347 	if (c->num >= b->ddk.Interfaces || b->cr.pending >= CONFREQSZ)
1348 		return;
1349 	on = on ? 1 : 0;
1350 	if (on == c->monitor)
1351 		return;
1352 
1353 	cfg |= on ? TAU32_monitor : 0;
1354 	CE_PREREQUEST (b, c, b->cr.queue, req);
1355 	if (!req)
1356 		return;
1357 	req->Command = TAU32_Configure_E1;
1358 	req->Io.InterfaceConfig.Interface = c->num ? TAU32_E1_B : TAU32_E1_A;
1359 	req->Io.InterfaceConfig.Config = cfg;
1360 	req->Io.InterfaceConfig.UnframedTsMask = c->ts;
1361 	CE_DDK_DEBUG (b, c, ("Submit monitor\n"));
1362 	if (ce_cfg_submit (b)) {
1363 		c->monitor = on ? 1 : 0;
1364 		c->config = cfg;
1365 	}
1366 }
1367 
_ce_submit_configure_e1(ce_chan_t * c,char * rname)1368 static void _ce_submit_configure_e1 (ce_chan_t *c, char *rname)
1369 {
1370 	TAU32_UserRequest *req;
1371 	ce_board_t *b = c->board;
1372 
1373 	CE_PREREQUEST (b, c, b->cr.queue, req);
1374 	if (!req)
1375 		return;
1376 	req->Command = TAU32_Configure_E1;
1377 	req->Io.InterfaceConfig.Interface = c->num == 0 ? TAU32_E1_A : TAU32_E1_B;
1378 	req->Io.InterfaceConfig.Config = c->config;
1379 	req->Io.InterfaceConfig.UnframedTsMask = c->ts;
1380 	CE_DDK_DEBUG (b, c, ("Submit %s\n", rname ? rname : ""));
1381 	if (!ce_cfg_submit (b)) {
1382 		CE_DDK_DEBUG (b, c, ("Fail to submit %s\n", rname?rname:""));
1383 		/* Do some error processing */
1384 		return;
1385 	}
1386 }
1387 
ce_set_use16(ce_chan_t * c,unsigned char on)1388 void ce_set_use16 (ce_chan_t *c, unsigned char on)
1389 {
1390 	ce_board_t *b = c->board;
1391 	ce_chan_t *x;
1392 	unsigned long cfg[2];
1393 	int use[2];
1394 
1395 	if (c->num >= b->ddk.Interfaces || b->cr.pending + 2 >= CONFREQSZ)
1396 		return;
1397 
1398 	cfg[0] = b->chan[0].config & ~TAU32_framing_mode_mask;
1399 	cfg[1] = b->chan[1].config & ~TAU32_framing_mode_mask;
1400 
1401 	on = on ? 1 : 0;
1402 
1403 	if (c->use16 == on || b->chan->unfram)
1404 		return;
1405 
1406 	use[0] = b->chan[0].use16;
1407 	use[1] = b->chan[1].use16;
1408 
1409 	/* Correct value */
1410 	use[c->num] = on;
1411 
1412 	if (b->ddk.Interfaces == 1) {
1413 		cfg[0] |= on ? TAU32_framed_cas_set : TAU32_framed_no_cas;
1414 	} else {
1415 		if (use[0] == 0 && use[1] == 0) {
1416 			cfg[0] |= TAU32_framed_cas_cross;
1417 			cfg[1] |= TAU32_framed_cas_cross;
1418 		} else if (use[0] == 0) {
1419 			cfg[0] |= TAU32_framed_cas_set;
1420 			cfg[1] |= TAU32_framed_no_cas;
1421 		} else if (use[1] == 0) {
1422 			cfg[0] |= TAU32_framed_no_cas;
1423 			cfg[1] |= TAU32_framed_cas_set;
1424 		} else {
1425 			cfg[0] |= TAU32_framed_no_cas;
1426 			cfg[1] |= TAU32_framed_no_cas;
1427 		}
1428 	}
1429 
1430 	c->use16 = on;
1431 
1432 	for (x = b->chan; !on && x < b->chan + NCHAN; x++) {
1433 		if (x->dir == c->num && x->ts & (1ul<<16)) {
1434 			ce_set_ts (x, x->ts);
1435 			break;
1436 		}
1437 	}
1438 
1439 	if (cfg[0] != b->chan[0].config) {
1440 		b->chan[0].config = cfg[0];
1441 		_ce_submit_configure_e1 (b->chan + 0, "use16");
1442 	}
1443 
1444 	if (cfg[1] != b->chan[1].config) {
1445 		b->chan[1].config = cfg[1];
1446 		_ce_submit_configure_e1 (b->chan + 1, "use16");
1447 	}
1448 }
1449 
ce_set_crc4(ce_chan_t * c,unsigned char on)1450 void ce_set_crc4 (ce_chan_t *c, unsigned char on)
1451 {
1452 	TAU32_UserRequest *req;
1453 	unsigned long cfg = c->config & ~TAU32_crc4_mf;
1454 	ce_board_t *b = c->board;
1455 
1456 	if (c->num >= b->ddk.Interfaces || b->cr.pending >= CONFREQSZ)
1457 		return;
1458 	on = on ? 1 : 0;
1459 	if (on == c->crc4 || b->chan->unfram)
1460 		return;
1461 
1462 	cfg |= on ? TAU32_crc4_mf : 0;
1463 	CE_PREREQUEST (b, c, b->cr.queue, req);
1464 	if (!req)
1465 		return;
1466 	req->Command = TAU32_Configure_E1;
1467 	req->Io.InterfaceConfig.Interface = c->num ? TAU32_E1_B : TAU32_E1_A;
1468 	req->Io.InterfaceConfig.Config = cfg;
1469 	req->Io.InterfaceConfig.UnframedTsMask = c->ts;
1470 	CE_DDK_DEBUG (b, c, ("Submit crc4\n"));
1471 	if (ce_cfg_submit (b)) {
1472 		c->crc4 = on ? 1 : 0;
1473 		c->config = cfg;
1474 	}
1475 }
1476 
ce_set_gsyn(ce_chan_t * c,int syn)1477 void ce_set_gsyn (ce_chan_t *c, int syn)
1478 {
1479 	ce_board_t *b = c->board;
1480 	unsigned int mode;
1481 
1482 	if (c->num >= b->ddk.Interfaces)
1483 		return;
1484 
1485 	if (syn == GSYN_RCV)
1486 		syn = c->num ? GSYN_RCV1 : GSYN_RCV0;
1487 
1488 	switch (syn) {
1489 	default:	mode = TAU32_SYNC_INTERNAL;	break;
1490 	case GSYN_RCV0:	mode = TAU32_SYNC_RCV_A;	break;
1491 	case GSYN_RCV1:	mode = TAU32_SYNC_RCV_B;	break;
1492 	}
1493 
1494 	CE_DDK_DEBUG (b, c, ("Set Sync Mode\n"));
1495 	if (TAU32_SetSyncMode (b->ddk.pControllerObject, mode)) {
1496 		b->chan->gsyn = syn;
1497 		if (b->ddk.Interfaces > 1)
1498 			(b->chan + 1)->gsyn = syn;
1499 	}
1500 }
1501 
ce_get_cable(ce_chan_t * c)1502 int ce_get_cable (ce_chan_t *c)
1503 {
1504 	ce_board_t *b = c->board;
1505 	if (c->num >= b->ddk.Interfaces)
1506 		return 0;
1507 
1508 	return CABLE_TP;
1509 }
1510 
ce_set_dir(ce_chan_t * c,int dir)1511 void ce_set_dir (ce_chan_t *c, int dir)
1512 {
1513 	ce_board_t *b = c->board;
1514 	unsigned long ts;
1515 	if (b->cr.pending + 1>= CONFREQSZ || c->dir == dir)
1516 		return;
1517 
1518 	ts = c->ts;
1519 	ce_set_ts (c, 0);
1520 	c->dir = dir;
1521 	ce_set_ts (c, ts);
1522 }
1523