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