FreeBSD/Linux Kernel Cross Reference
sys/dev/ce/ceddk.c
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: releng/9.0/sys/dev/ce/ceddk.c 154899 2006-01-27 09:02:09Z rik $");
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
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
201 void ce_set_dtr (ce_chan_t *c, int on)
202 {
203 c->dtr = on?1:0;
204 }
205
206 void ce_set_rts (ce_chan_t *c, int on)
207 {
208 c->rts = on?1:0;
209 }
210
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
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
311 int ce_transmit_space (ce_chan_t *c)
312 {
313 return c->tx_pending < (TAU32_IO_QUEUE);
314 }
315
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
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
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
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
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
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
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 comleteness, but for now I
625 * don't use it. So I just start to write and didn't finished it yet.
626 * It and it is VERY BUGGY!!! Do not use it. If you realy
627 * need it ask me to fix it or rewrite it by your self.
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
650 void ce_register_transmit (ce_chan_t *c,
651 void (*func) (ce_chan_t*, void*, int))
652 {
653 c->transmit = func;
654 }
655
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
662 void ce_register_error (ce_chan_t *c,
663 void (*func) (ce_chan_t*, int))
664 {
665 c->error = func;
666 }
667
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
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
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
742 int ce_get_cts (ce_chan_t *c)
743 {
744 return 0;
745 }
746
747 int ce_get_dsr (ce_chan_t *c)
748 {
749 return 0;
750 }
751
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
Cache object: 34e8bf83b1c2fde9f5848b8d8a3d599f
|