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/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 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 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 really 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 650void ce_register_transmit (ce_chan_t *c, 651 void (*func) (ce_chan_t*, void*, int)) 652{ 653 c->transmit = func; 654} 655 656void ce_register_receive (ce_chan_t *c, 657 void (*func) (ce_chan_t*, unsigned char*, int)) 658{ 659 c->receive = func; 660} 661 662void ce_register_error (ce_chan_t *c, 663 void (*func) (ce_chan_t*, int)) 664{ 665 c->error = func; 666} 667 668void 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 718void 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 735int 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 742int ce_get_cts (ce_chan_t *c) 743{ 744 return 0; 745} 746 747int ce_get_dsr (ce_chan_t *c) 748{ 749 return 0; 750} 751 752void 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 935void 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 983void 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 1010void 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 1037void 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 1064static 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 1176void 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 1198void 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 1264void 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 1314void 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 1341void 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 1368static 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 1388void 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 1450void 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 1477void 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 1502int 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 1511void 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