1154899Srik/* 2154899Srik * Middle-level code for Cronyx Tau32-PCI adapters. 3154899Srik * 4154899Srik * Copyright (C) 2004 Cronyx Engineering 5154899Srik * Copyright (C) 2004 Roman Kurakin <rik@FreeBSD.org> 6154899Srik * 7154899Srik * This software is distributed with NO WARRANTIES, not even the implied 8154899Srik * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 9154899Srik * 10154899Srik * Authors grant any other persons or organisations a permission to use, 11154899Srik * modify and redistribute this software in source and binary forms, 12154899Srik * as long as this message is kept with the software, all derivative 13154899Srik * works or modified versions. 14154899Srik * 15154899Srik * $Cronyx: ceddk.c,v 1.2.6.2 2005/11/17 16:04:13 rik Exp $ 16154899Srik */ 17154899Srik 18154899Srik#include <sys/cdefs.h> 19154899Srik__FBSDID("$FreeBSD$"); 20154899Srik 21154899Srik#include <dev/cx/machdep.h> 22154899Srik#include <dev/ce/ceddk.h> 23154899Srik 24154899Srik#undef CE_DDK_DEBUG_ENABLED 25154899Srik#ifdef CE_DDK_DEBUG_ENABLED 26154899Srik#ifdef __FreeBSD__ 27154899Srik# define CE_DDK_DEBUG(b,c,s) \ 28154899Srik do { \ 29154899Srik if (c) { \ 30154899Srik printf("ce%d-%d: ",(b)->num,(c)->num); \ 31154899Srik } else { \ 32154899Srik printf("ce%d-*: ",(b)->num); \ 33154899Srik } \ 34154899Srik printf s; \ 35154899Srik } while (0) 36154899Srik#else 37154899Srik# define CE_DDK_DEBUG(b,c,s) do {} while (0) 38154899Srik#endif 39154899Srik#else 40154899Srik# define CE_DDK_DEBUG(b,c,s) do {} while (0) 41154899Srik#endif 42154899Srik 43154899Srik#if 0 44154899Srik#define ENTER() \ 45154899Srik static int enter=0; \ 46154899Srik do { \ 47154899Srik enter++; \ 48154899Srik printf ("%s: >> enter (%16llx) %d\n", __FUNCTION__, rdtsc (), enter); \ 49154899Srik } while (0) 50154899Srik 51154899Srik#define EXIT(val...) \ 52154899Srik do { \ 53154899Srik enter--; \ 54154899Srik printf ("%s: << exit (%16llx) %d line %d\n", __FUNCTION__, rdtsc (), enter, __LINE__); \ 55154899Srik return val; \ 56154899Srik } while (0) 57154899Srik#else 58154899Srik#define ENTER() \ 59154899Srik do {} while (0) 60154899Srik 61154899Srik#define EXIT(val...) \ 62154899Srik do {return val;} while (0) 63154899Srik#endif 64154899Srik 65154899Srik#define CE_ENQUEUE(list,item) \ 66154899Srik do { \ 67154899Srik TAU32_UserRequest **last; \ 68154899Srik last = &(list); \ 69154899Srik while (*last) { \ 70154899Srik last = &(*last)->next; \ 71154899Srik } \ 72154899Srik (*last) = (item); \ 73154899Srik (item)->next = NULL; \ 74154899Srik } while (0) 75154899Srik 76154899Srik#define CE_ENQUEUE_HEAD(list,item) \ 77154899Srik do { \ 78154899Srik (item)->next = list; \ 79154899Srik list = item; \ 80154899Srik } while (0) 81154899Srik 82154899Srik#define CE_DEQUEUE(list,item) \ 83154899Srik do { \ 84154899Srik item = list; \ 85154899Srik if (list) { \ 86154899Srik list = (item)->next; \ 87154899Srik } \ 88154899Srik } while (0) 89154899Srik 90154899Srik#define CE_PREREQUEST(b,c,list,item) \ 91154899Srik do { \ 92154899Srik item = list; \ 93154899Srik if (!item) { \ 94154899Srik CE_DDK_DEBUG (b, c, ("Fatal error, no free structs " \ 95154899Srik "for UserRequest (%s:%d)\n", \ 96154899Srik __FUNCTION__, __LINE__)); \ 97154899Srik } \ 98154899Srik } while (0) 99154899Srik 100154899Srik#define CE_DUMP_QUEUE(list) \ 101154899Srik do { \ 102154899Srik TAU32_UserRequest *item; \ 103154899Srik int i = 0; \ 104154899Srik item = list; \ 105154899Srik while (item) { \ 106154899Srik printf ("item%d: %p\n", i, item); \ 107154899Srik item = item->next; \ 108154899Srik i++; \ 109154899Srik } \ 110154899Srik } while (0) 111154899Srik 112154899Srik#define CE_FIND_ITEM(list,item,flag) \ 113154899Srik do { \ 114154899Srik TAU32_UserRequest *citem; \ 115154899Srik flag = 0; \ 116154899Srik for (citem = list; citem; citem = citem->next) { \ 117154899Srik if (citem == item) { \ 118154899Srik flag = 1; \ 119154899Srik break; \ 120154899Srik } \ 121154899Srik } \ 122154899Srik } while (0) 123154899Srik 124154899Srik#define CE_LAST_ITEM(list,item) \ 125154899Srik do { \ 126154899Srik TAU32_UserRequest **last; \ 127154899Srik last = &(list); \ 128154899Srik while ((*last) && (*last)->next) { \ 129154899Srik last = &(*last)->next; \ 130154899Srik } \ 131154899Srik (item) = (*last); \ 132154899Srik } while (0) 133154899Srik 134154899Srik#define CE_ASSERT(a) \ 135154899Srik do { \ 136154899Srik if (!(a)) { \ 137154899Srik printf ("ASSERT: %d %s\n", __LINE__, #a); \ 138154899Srik __asm __volatile ("int $3"); \ 139154899Srik } \ 140154899Srik } while (0) 141154899Srik 142154899Srikstatic void _ce_set_ts (ce_chan_t *c, unsigned long ts); 143154899Srikstatic void _ce_submit_configure_e1 (ce_chan_t *c, char *rname); 144154899Srik 145154899Srik#ifdef CE_DDK_DEBUG_ENABLED 146154899Srikstatic char *ce_err2str (unsigned long err) 147154899Srik{ 148154899Srik switch (err) { 149154899Srik case TAU32_SUCCESSFUL: 150154899Srik return "Successful"; 151154899Srik case TAU32_ERROR_ALLOCATION: 152154899Srik return "Allocation error, not enough tx/rx descriptors"; 153154899Srik case TAU32_ERROR_BUS: 154154899Srik return "PEB could not access to host memory by PCI bus for load/store information"; 155154899Srik case TAU32_ERROR_FAIL: 156154899Srik return "PEB action request failed"; 157154899Srik case TAU32_ERROR_TIMEOUT: 158154899Srik return "PEB action request timeout"; 159154899Srik case TAU32_ERROR_CANCELLED: 160154899Srik return "request has been canceled"; 161154899Srik case TAU32_ERROR_TX_UNDERFLOW: 162154899Srik return "transmission underflow"; 163154899Srik case TAU32_ERROR_TX_PROTOCOL: 164154899Srik return "TX_PROTOCOL"; 165154899Srik case TAU32_ERROR_RX_OVERFLOW: 166154899Srik return "RX_OVERFLOW"; 167154899Srik case TAU32_ERROR_RX_ABORT: 168154899Srik return "RX_ABORT"; 169154899Srik case TAU32_ERROR_RX_CRC: 170154899Srik return "RX_CRC"; 171154899Srik case TAU32_ERROR_RX_SHORT: 172154899Srik return "RX_SHORT"; 173154899Srik case TAU32_ERROR_RX_SYNC: 174154899Srik return "RX_SYNC"; 175154899Srik case TAU32_ERROR_RX_FRAME: 176154899Srik return "RX_FRAME"; 177154899Srik case TAU32_ERROR_RX_LONG: 178154899Srik return "RX_LONG"; 179154899Srik case TAU32_ERROR_RX_SPLIT: 180154899Srik return "frame has splitted between two requests due rx-gap allocation"; 181154899Srik case TAU32_ERROR_RX_UNFIT: 182154899Srik return "frame can't be fit into request buffer"; 183154899Srik case TAU32_ERROR_TSP: 184154899Srik return "ERROR_TSP"; 185154899Srik case TAU32_ERROR_RSP: 186154899Srik return "ERROR_RSP"; 187154899Srik case TAU32_ERROR_INT_OVER_TX: 188154899Srik return "ERROR INT OVER TX"; 189154899Srik case TAU32_ERROR_INT_OVER_RX: 190154899Srik return "ERROR INT OVER RX"; 191154899Srik case TAU32_ERROR_INT_STORM: 192154899Srik return "irq storm"; 193154899Srik case TAU32_ERROR_INT_E1LOST: 194154899Srik return "ERROR_E1LOST"; 195154899Srik default: 196154899Srik return ("Unknown error"); 197154899Srik } 198154899Srik} 199154899Srik#endif 200154899Srik 201154899Srikvoid ce_set_dtr (ce_chan_t *c, int on) 202154899Srik{ 203154899Srik c->dtr = on?1:0; 204154899Srik} 205154899Srik 206154899Srikvoid ce_set_rts (ce_chan_t *c, int on) 207154899Srik{ 208154899Srik c->rts = on?1:0; 209154899Srik} 210154899Srik 211154899Srikstatic void TAU32_CALLBACK_TYPE ce_on_receive 212154899Srik (TAU32_UserContext *pContext, TAU32_UserRequest *req) 213154899Srik{ 214154899Srik ce_buf_item_t *item = (ce_buf_item_t *)req; 215154899Srik ce_chan_t *c; 216154899Srik ce_board_t *b; 217154899Srik unsigned int error; 218154899Srik int len; 219154899Srik 220154899Srik ENTER (); 221154899Srik if (!req || !req->sys) { 222154899Srik EXIT (); 223154899Srik } 224154899Srik 225154899Srik c = (ce_chan_t *)req->sys; 226154899Srik b = c->board; 227154899Srik 228154899Srik len = req->Io.Rx.Received; 229154899Srik error = req->ErrorCode; 230154899Srik 231154899Srik c->rintr++; 232154899Srik if (error == TAU32_SUCCESSFUL) { 233154899Srik if (req->Io.Rx.FrameEnd) { 234154899Srik c->ipkts++; 235154899Srik } else { 236154899Srik CE_DDK_DEBUG (b, c, ("No FrameEnd\n")); 237154899Srik /* probably do something in some cases*/ 238154899Srik } 239154899Srik c->ibytes += len; 240154899Srik if (c->receive) 241154899Srik c->receive (c, item->buf, len); 242154899Srik } else if (error & TAU32_ERROR_BUS) { 243154899Srik c->overrun++; 244154899Srik if (c->error) 245154899Srik c->error (c, CE_OVERRUN); 246154899Srik } else { 247154899Srik CE_DDK_DEBUG (b, c, ("Another receive error: %x\n", error)); 248154899Srik /* Do some procesing */ 249154899Srik } 250154899Srik 251154899Srik CE_ASSERT (!req->pInternal); 252154899Srik CE_ENQUEUE (c->rx_queue, req); 253154899Srik while (c->rx_queue) { 254154899Srik CE_DEQUEUE (c->rx_queue, req); 255154899Srik CE_ASSERT (req); 256154899Srik item = (ce_buf_item_t *)req; 257154899Srik req->Command = TAU32_Rx_Data; 258154899Srik req->Io.Rx.Channel = c->num; 259154899Srik req->pCallback = ce_on_receive; 260154899Srik req->Io.Rx.BufferLength = BUFSZ+4; 261154899Srik req->Io.Rx.PhysicalDataAddress = item->phys; 262154899Srik if (!TAU32_SubmitRequest (b->ddk.pControllerObject, req)) { 263154899Srik CE_DDK_DEBUG (b, c, ("RX submition failure\n")); 264154899Srik c->rx_pending--; 265154899Srik CE_ENQUEUE_HEAD (c->rx_queue, req); 266154899Srik break; 267154899Srik } 268154899Srik } 269154899Srik EXIT (); 270154899Srik} 271154899Srik 272154899Srikstatic void TAU32_CALLBACK_TYPE ce_on_transmit 273154899Srik (TAU32_UserContext *pContext, TAU32_UserRequest *req) 274154899Srik{ 275154899Srik int len; 276154899Srik unsigned int error; 277154899Srik ce_chan_t *c; 278154899Srik ENTER (); 279154899Srik 280154899Srik if (!req || !req->sys) { 281154899Srik EXIT (); 282154899Srik } 283154899Srik 284154899Srik c = (ce_chan_t *)req->sys; 285154899Srik 286154899Srik len = req->Io.Tx.Transmitted; 287154899Srik error = req->ErrorCode; 288154899Srik 289154899Srik c->tintr++; 290154899Srik if (error == TAU32_SUCCESSFUL) { 291154899Srik c->obytes += len; 292154899Srik c->opkts++; 293154899Srik } else if (error & TAU32_ERROR_BUS) { 294154899Srik c->underrun++; 295154899Srik if (c->error) 296154899Srik c->error (c, CE_UNDERRUN); 297154899Srik } else { 298154899Srik CE_DDK_DEBUG (c->board, c, ("Another transmit error: %x\n", 299154899Srik error)); 300154899Srik /* Do some procesing */ 301154899Srik } 302154899Srik 303154899Srik CE_ENQUEUE (c->tx_queue, req); 304154899Srik c->tx_pending--; 305154899Srik 306154899Srik if (c->transmit) 307154899Srik c->transmit (c, 0, len); 308154899Srik EXIT (); 309154899Srik} 310154899Srik 311154899Srikint ce_transmit_space (ce_chan_t *c) 312154899Srik{ 313154899Srik return c->tx_pending < (TAU32_IO_QUEUE); 314154899Srik} 315154899Srik 316154899Srikint ce_send_packet (ce_chan_t *c, unsigned char *buf, int len, void *tag) 317154899Srik{ 318154899Srik TAU32_UserRequest *req; 319154899Srik ce_buf_item_t *item; 320154899Srik 321154899Srik ENTER (); 322154899Srik 323154899Srik if (!ce_transmit_space (c)) { 324154899Srik EXIT (-1); 325154899Srik } 326154899Srik 327154899Srik if (len <= 0 || len > BUFSZ) { 328154899Srik EXIT (-2); 329154899Srik } 330154899Srik 331154899Srik CE_DEQUEUE (c->tx_queue, req); 332154899Srik CE_ASSERT (req); 333154899Srik item = (ce_buf_item_t *)req; 334154899Srik 335154899Srik if (buf != item->buf) 336154899Srik memcpy (item->buf, buf, len); 337154899Srik 338154899Srik CE_ASSERT (!req->pInternal); 339154899Srik 340154899Srik req->Command = TAU32_Tx_Data | TAU32_Tx_FrameEnd; 341154899Srik req->Io.Tx.Channel = c->num; 342154899Srik req->pCallback = ce_on_transmit; 343154899Srik req->Io.Tx.DataLength = len; 344154899Srik req->Io.Tx.PhysicalDataAddress = item->phys; 345154899Srik c->tx_pending++; 346154899Srik if (!TAU32_SubmitRequest (c->board->ddk.pControllerObject, req)) { 347154899Srik CE_DDK_DEBUG (c->board, c, ("Can't submit packet for " 348154899Srik "transmission\n")); 349154899Srik CE_ENQUEUE_HEAD (c->tx_queue, req); 350154899Srik c->tx_pending--; 351154899Srik EXIT (-3); 352154899Srik } 353154899Srik EXIT (0); 354154899Srik} 355154899Srik 356154899Srikstatic void TAU32_CALLBACK_TYPE ce_on_config 357154899Srik (TAU32_UserContext *pContext, TAU32_UserRequest *req) 358154899Srik{ 359154899Srik ce_board_t *b = (ce_board_t *) pContext; 360154899Srik ENTER (); 361154899Srik b->cr.pending--; 362154899Srik if (req->ErrorCode) 363154899Srik CE_DDK_DEBUG (b, (ce_chan_t*)0, ("Config request failure: %lx\n", 364154899Srik req->ErrorCode)); 365154899Srik EXIT (); 366154899Srik} 367154899Srik 368154899Srikstatic void TAU32_CALLBACK_TYPE ce_on_config_stop 369154899Srik (TAU32_UserContext *pContext, TAU32_UserRequest *req) 370154899Srik{ 371154899Srik int i, first; 372154899Srik TAU32_UserRequest *rreq; 373154899Srik ce_board_t *b = (ce_board_t *) pContext; 374154899Srik ce_chan_t *c = b->chan + req->Io.ChannelNumber; 375154899Srik 376154899Srik ENTER (); 377154899Srik /* Stop all requests */ 378154899Srik CE_ASSERT (0);/* Buggy */ 379154899Srik CE_LAST_ITEM (c->rx_queue, rreq); 380154899Srik /* A little hacky, try to guess which is a first */ 381154899Srik first = rreq ? (c->rx_item - (ce_buf_item_t *)rreq) + 1 : 0; 382154899Srik for (i = 0; i < TAU32_IO_QUEUE; i++) { 383154899Srik int is_pending; 384154899Srik rreq = &c->rx_item[(i + first) % TAU32_IO_QUEUE].req; 385154899Srik CE_FIND_ITEM (c->rx_queue, rreq, is_pending); 386154899Srik if (!is_pending) 387154899Srik continue; 388154899Srik TAU32_CancelRequest (b->ddk.pControllerObject, rreq, 1); 389154899Srik rreq->Command = TAU32_Rx_Data; 390154899Srik rreq->Io.Rx.Channel = c->num; 391154899Srik rreq->Io.Rx.BufferLength = BUFSZ+4; 392154899Srik rreq->Io.Rx.PhysicalDataAddress = ((ce_buf_item_t *)rreq)->phys; 393154899Srik c->rx_pending++; 394154899Srik if (!TAU32_SubmitRequest (b->ddk.pControllerObject, rreq)) { 395154899Srik CE_ASSERT (0);/* Buggy */ 396154899Srik c->rx_pending--; 397154899Srik break; 398154899Srik } 399154899Srik } 400154899Srik 401154899Srik c->tx_pending = 0; 402154899Srik/* c->rx_pending = 0;*/ 403154899Srik EXIT (); 404154899Srik} 405154899Srik 406154899Srikstatic int ce_cfg_submit (ce_board_t *b) 407154899Srik{ 408154899Srik TAU32_UserRequest *req; 409154899Srik ENTER (); 410154899Srik 411154899Srik CE_DEQUEUE (b->cr.queue, req); 412154899Srik CE_ASSERT (req); 413154899Srik CE_ASSERT (!req->pInternal); 414154899Srik 415154899Srik req->pCallback = ce_on_config; 416154899Srik b->cr.pending++; 417154899Srik 418154899Srik CE_DDK_DEBUG (b, (ce_chan_t *)0, ("config request pending: %d\n", 419154899Srik b->cr.pending)); 420154899Srik 421154899Srik if (!TAU32_SubmitRequest (b->ddk.pControllerObject, req)) { 422154899Srik CE_ENQUEUE_HEAD (b->cr.queue, req); 423154899Srik CE_DDK_DEBUG (b, (ce_chan_t *)0, ("Fail to submit config request\n")); 424154899Srik b->cr.pending--; 425154899Srik EXIT (0); 426154899Srik } 427154899Srik 428154899Srik EXIT (1); 429154899Srik} 430154899Srik 431154899Srikvoid ce_init_board (ce_board_t *b) 432154899Srik{ 433154899Srik int i; 434154899Srik 435154899Srik b->cr.queue = NULL; 436154899Srik 437154899Srik for (i = 0; i < CONFREQSZ; i++) { 438154899Srik CE_ENQUEUE (b->cr.queue, b->cr.req + i); 439154899Srik } 440154899Srik 441154899Srik b->chan[0].config = TAU32_ais_on_loss; 442154899Srik 443154899Srik /* lloop = off, rloop = off */ 444154899Srik b->chan[0].config |= TAU32_LineNormal; 445154899Srik b->chan[0].lloop = 0; 446154899Srik b->chan[0].rloop = 0; 447154899Srik 448154899Srik /* unfram=off, scrambler=off, use16=off, crc4=off, 449154899Srik higain=off, monitor=off*/ 450154899Srik b->chan[0].config |= (b->ddk.Interfaces == 2 ? TAU32_framed_cas_cross : 451154899Srik TAU32_framed_cas_set); 452154899Srik b->chan[0].unfram = 0; 453154899Srik b->chan[0].scrambler = 0; 454154899Srik b->chan[0].use16 = 0; 455154899Srik b->chan[0].crc4 = 0; 456154899Srik b->chan[0].higain = 0; 457154899Srik b->chan[0].monitor = 0; 458154899Srik 459154899Srik if (b->ddk.Interfaces == 2) { 460154899Srik b->chan[1].config = TAU32_ais_on_loss; 461154899Srik /* lloop = off, rloop = off */ 462154899Srik b->chan[1].config |= TAU32_LineNormal; 463154899Srik /* unfram=off, scrambler=off, use16=off, crc4=off, 464154899Srik higain=off, monitor=off*/ 465154899Srik b->chan[1].config |= TAU32_framed_cas_cross; 466154899Srik b->chan[1].unfram = 0; 467154899Srik b->chan[1].scrambler = 0; 468154899Srik b->chan[1].use16 = 0; 469154899Srik b->chan[1].crc4 = 0; 470154899Srik b->chan[1].higain = 0; 471154899Srik b->chan[1].monitor = 0; 472154899Srik } 473154899Srik 474154899Srik for (i = 0; i < NCHAN; i++) { 475154899Srik /* Chan0 ts=1-15,17-31, Chan1 ts=1-2 */ 476154899Srik b->chan[i].type = i < b->ddk.Interfaces ? T_E1 : T_DATA; 477154899Srik b->chan[i].ts = (i == 0 ? 0xfffefffe : 478154899Srik (i != 1 ? 0 : 479154899Srik (b->ddk.Interfaces == 2 ? 0x6: 0))); 480154899Srik b->chan[i].dir = (b->ddk.Interfaces == 2) ? (i%2) : 0; 481154899Srik b->chan[i].mtu = 1504; 482154899Srik } 483154899Srik#if 0 484154899Srik /* c->num == 0 */ 485154899Srik req = b->cr.queue; 486154899Srik /* We must have some here */ 487154899Srik CE_ASSERT (req); 488154899Srik req->Command = TAU32_Configure_E1; 489154899Srik req->Io.InterfaceConfig.Interface = TAU32_E1_A; 490154899Srik req->Io.InterfaceConfig.Config = b->chan[0].config; 491154899Srik req->Io.InterfaceConfig.UnframedTsMask = 0; 492154899Srik if (!ce_cfg_submit (b)) { 493154899Srik CE_DDK_DEBUG (b, b->chan + 0, 494154899Srik ("Submit request failure, line %d\n", 495154899Srik __LINE__)); 496154899Srik } 497154899Srik /* c->num == 1 */ 498154899Srik if (b->ddk.Interfaces == 2) { 499154899Srik req = b->cr.queue; 500154899Srik /* We must have some here */ 501154899Srik CE_ASSERT (req); 502154899Srik req->Command = TAU32_Configure_E1; 503154899Srik req->Io.InterfaceConfig.Interface = TAU32_E1_B; 504154899Srik req->Io.InterfaceConfig.Config = b->chan[1].config; 505154899Srik req->Io.InterfaceConfig.UnframedTsMask = 0; 506154899Srik if (!ce_cfg_submit (b)) { 507154899Srik CE_DDK_DEBUG (b, b->chan + 1, 508154899Srik ("Submit request failure, line %d\n", 509154899Srik __LINE__)); 510154899Srik } 511154899Srik } 512154899Srik#endif 513154899Srik /* Set default cross matrix */ 514154899Srik for (i = 0; i < 32; i++) { 515154899Srik /* -X-> Peb */ 516154899Srik b->dxc[i] = TAU32_CROSS_OFF; 517154899Srik /* Link2 -> Link1 */ 518154899Srik b->dxc[i + 32] = i + 64; 519154899Srik /* Link1 -> Link2 */ 520154899Srik b->dxc[i + 64] = i + 32; 521154899Srik } 522154899Srik 523154899Srik /* We have only mux mode for now. Later we will also have cross mode */ 524154899Srik b->mux = 1; 525154899Srik} 526154899Srik 527154899Srikvoid ce_start_chan (ce_chan_t *c, int tx, int rx, ce_buf_t *cb, 528154899Srik unsigned long phys) 529154899Srik{ 530154899Srik int i; 531154899Srik ce_board_t *b = c->board; 532154899Srik 533154899Srik/* c->config = TAU32_ais_on_loss | TAU32_framed_cas_cross;*/ 534154899Srik 535154899Srik if (cb) { 536154899Srik CE_DDK_DEBUG (b, c, ("ce_buf_t virt:%p phys:%p\n", cb, 537154899Srik (void *)phys)); 538154899Srik c->tx_item = cb->tx_item; 539154899Srik c->rx_item = cb->rx_item; 540154899Srik c->tx_queue = NULL; 541154899Srik c->rx_queue = NULL; 542154899Srik for (i = 0; i < TAU32_IO_QUEUE; i++) { 543154899Srik c->tx_item[i].phys = phys + 544154899Srik ((char *)(c->tx_item[i].buf)-(char *)cb); 545154899Srik c->rx_item[i].phys = phys + 546154899Srik ((char *)(c->rx_item[i].buf)-(char *)cb); 547154899Srik cb->tx_item[i].req.sys = c; 548154899Srik cb->rx_item[i].req.sys = c; 549154899Srik CE_DDK_DEBUG (b, c, ("tx_item[%d].buf virt:%p phys:%p\n", 550154899Srik i, c->tx_item[i].buf, 551154899Srik (void *)c->tx_item[i].phys)); 552154899Srik CE_DDK_DEBUG (b, c, ("rx_item[%d].buf virt:%p phys:%p\n", 553154899Srik i, c->rx_item[i].buf, 554154899Srik (void *)c->rx_item[i].phys)); 555154899Srik CE_ENQUEUE (c->rx_queue, &c->rx_item[i].req); 556154899Srik CE_ENQUEUE (c->tx_queue, &c->tx_item[i].req); 557154899Srik } 558154899Srik c->tx_pending = 0; 559154899Srik c->rx_pending = 0; 560154899Srik } 561154899Srik 562154899Srik /* submit rx */ 563154899Srik while (1) { 564154899Srik ce_buf_item_t *item; 565154899Srik TAU32_UserRequest *req; 566154899Srik 567154899Srik CE_DEQUEUE (c->rx_queue, req); 568154899Srik if (!req) 569154899Srik break; 570154899Srik item = (ce_buf_item_t *) req; 571154899Srik CE_ASSERT (c->rx_pending < TAU32_IO_QUEUE); 572154899Srik req->Command = TAU32_Rx_Data; 573154899Srik req->Io.Rx.Channel = c->num; 574154899Srik req->pCallback = ce_on_receive; 575154899Srik req->Io.Rx.BufferLength = c->mtu + (c->phony ? 0 : 4); 576154899Srik req->Io.Rx.PhysicalDataAddress = item->phys; 577154899Srik c->rx_pending++; 578154899Srik if (!TAU32_SubmitRequest (b->ddk.pControllerObject, req)) { 579154899Srik CE_DDK_DEBUG (b, c, ("Faild to submit rx request\n")); 580154899Srik /*XXXRIK: shouldn't happen, but ... */ 581154899Srik CE_ASSERT (0); 582154899Srik c->rx_pending--; 583154899Srik break; 584154899Srik } 585154899Srik } 586154899Srik 587154899Srik if (tx | rx) { 588154899Srik TAU32_UserRequest *req; 589154899Srik CE_PREREQUEST (b, c, b->cr.queue, req); 590154899Srik if (!req) 591154899Srik return; 592154899Srik req->Command = TAU32_Configure_Commit | 593154899Srik (tx ? TAU32_Tx_Start : 0) | 594154899Srik (rx ? TAU32_Rx_Start : 0); 595154899Srik req->Io.ChannelNumber = c->num; 596154899Srik if (!ce_cfg_submit (b)) { 597154899Srik CE_DDK_DEBUG (b, c, ("Can't start chan\n")); 598154899Srik /* Do some error processing */ 599154899Srik return; 600154899Srik } 601154899Srik } 602154899Srik 603154899Srik /* If we run just after ce_board_init we have prope values. 604154899Srik * Else I hope you didn't set ts to incorrect value. 605154899Srik */ 606154899Srik _ce_set_ts (c, c->ts); 607154899Srik if (c->num < b->ddk.Interfaces) { 608154899Srik /* The same for other modes. We don't check them. 609154899Srik * We hope that config is correctly set. Just as we have 610154899Srik * after ce_board_init. If channel was stoped we hope that 611154899Srik * it's config was not broken just after it and we didn't 612154899Srik * brake it before start. 613154899Srik */ 614154899Srik _ce_submit_configure_e1 (c, "start_init"); 615154899Srik } 616154899Srik} 617154899Srik 618154899Srikvoid ce_stop_chan (ce_chan_t *c) 619154899Srik{ 620154899Srik ce_board_t *b = c->board; 621154899Srik TAU32_UserRequest *req; 622154899Srik CE_DEQUEUE (b->cr.queue, req); 623154899Srik 624154899Srik /* XXXRIK: This function should be for comleteness, but for now I 625154899Srik * don't use it. So I just start to write and didn't finished it yet. 626298955Spfg * It and it is VERY BUGGY!!! Do not use it. If you really 627154899Srik * need it ask me to fix it or rewrite it by your self. 628154899Srik * Note: most buggy part of it in ce_on_config_stop! 629154899Srik */ 630154899Srik if (!req) { 631154899Srik CE_DDK_DEBUG (b, c, ("Fatal error, no free structs for " 632154899Srik "UserRequest (%s:%d)\n", __FUNCTION__, __LINE__)); 633154899Srik return; 634154899Srik } 635154899Srik req->Command = TAU32_Configure_Commit | 636154899Srik TAU32_Tx_Stop | TAU32_Rx_Stop; 637154899Srik req->Command = 0; 638154899Srik req->Io.ChannelNumber = c->num; 639154899Srik req->pCallback = ce_on_config_stop; 640154899Srik b->cr.pending++; 641154899Srik 642154899Srik if (!TAU32_SubmitRequest (b->ddk.pControllerObject, req)) { 643154899Srik CE_ENQUEUE_HEAD (b->cr.queue, req); 644154899Srik CE_DDK_DEBUG (b, c, ("Can't stop chan\n")); 645154899Srik b->cr.pending--; 646154899Srik } 647154899Srik} 648154899Srik 649154899Srik 650154899Srikvoid ce_register_transmit (ce_chan_t *c, 651154899Srik void (*func) (ce_chan_t*, void*, int)) 652154899Srik{ 653154899Srik c->transmit = func; 654154899Srik} 655154899Srik 656154899Srikvoid ce_register_receive (ce_chan_t *c, 657154899Srik void (*func) (ce_chan_t*, unsigned char*, int)) 658154899Srik{ 659154899Srik c->receive = func; 660154899Srik} 661154899Srik 662154899Srikvoid ce_register_error (ce_chan_t *c, 663154899Srik void (*func) (ce_chan_t*, int)) 664154899Srik{ 665154899Srik c->error = func; 666154899Srik} 667154899Srik 668154899Srikvoid TAU32_CALLBACK_TYPE ce_error_callback (TAU32_UserContext *pContext, 669154899Srik int Item, unsigned NotifyBits) 670154899Srik{ 671154899Srik ce_board_t *b = (ce_board_t *) pContext; 672154899Srik ENTER (); 673154899Srik if (NotifyBits & (TAU32_ERROR_FAIL | TAU32_ERROR_TIMEOUT 674154899Srik | TAU32_ERROR_INT_OVER_TX | TAU32_ERROR_INT_OVER_RX 675154899Srik | TAU32_ERROR_INT_STORM)) { 676154899Srik /* Fatal: adapter failure, need reset & restart */ 677154899Srik /* RIKXXX: probably I should add CE_FAILURE for ce_error */ 678154899Srik CE_DDK_DEBUG (b, (ce_chan_t *)0, ("Err, disable interrupts: %s\n", 679154899Srik ce_err2str (NotifyBits))); 680154899Srik/* TAU32_DisableInterrupts (b->ddk.pControllerObject);*/ 681154899Srik EXIT (); 682154899Srik } 683154899Srik if (Item >= 0) { 684154899Srik /* channel error */ 685154899Srik ce_chan_t *c = b->chan + Item; 686154899Srik if (NotifyBits & TAU32_ERROR_TX_UNDERFLOW) { 687154899Srik c->underrun++; 688154899Srik if (c->error) 689154899Srik c->error (c, CE_UNDERRUN); 690154899Srik } 691154899Srik if (NotifyBits & TAU32_ERROR_RX_OVERFLOW) { 692154899Srik c->overrun++; 693154899Srik if (c->error) 694154899Srik c->error (c, CE_OVERFLOW); 695154899Srik } 696154899Srik if (NotifyBits & (TAU32_ERROR_RX_FRAME | TAU32_ERROR_RX_ABORT | 697154899Srik TAU32_ERROR_RX_SHORT | TAU32_ERROR_RX_LONG | 698154899Srik TAU32_ERROR_RX_SYNC | TAU32_ERROR_RX_SPLIT | 699154899Srik TAU32_ERROR_RX_UNFIT)) { 700154899Srik c->frame++; 701154899Srik CE_DDK_DEBUG (b, c, ("Frame error: %x\n", NotifyBits)); 702154899Srik if (c->error) 703154899Srik c->error (c, CE_FRAME); 704154899Srik } 705154899Srik if(NotifyBits & TAU32_ERROR_RX_CRC) { 706154899Srik c->crc++; 707154899Srik if (c->error) 708154899Srik c->error (c, CE_CRC); 709154899Srik } 710154899Srik } else { 711154899Srik CE_DDK_DEBUG (b, (ce_chan_t *)0, ("Another error: %x\n", 712154899Srik NotifyBits)); 713154899Srik /* Adapter error, do smth */ 714154899Srik } 715154899Srik EXIT (); 716154899Srik} 717154899Srik 718154899Srikvoid TAU32_CALLBACK_TYPE ce_status_callback(TAU32_UserContext *pContext, 719154899Srik int Item, unsigned NotifyBits) 720154899Srik{ 721154899Srik ce_board_t *b = (ce_board_t *) pContext; 722154899Srik ENTER (); 723154899Srik if(Item >= 0) { 724154899Srik /* e1 status */ 725154899Srik ce_chan_t *c = b->chan + Item; 726154899Srik c->acc_status |= b->ddk.InterfacesInfo[Item].Status; 727154899Srik/* CE_DDK_DEBUG (b, c, ("Current status: %x\n", c->acc_status));*/ 728154899Srik } else { 729154899Srik CE_DDK_DEBUG (b, (ce_chan_t *)0, ("Another status: %x\n", NotifyBits)); 730154899Srik /* Adapter status, do smth. */ 731154899Srik } 732154899Srik EXIT (); 733154899Srik} 734154899Srik 735154899Srikint ce_get_cd (ce_chan_t *c) 736154899Srik{ 737154899Srik unsigned int e1status = c->board->ddk.InterfacesInfo[c->dir].Status; 738154899Srik 739154899Srik return (c->ts && !(e1status & (TAU32_RCL | TAU32_E1OFF))); 740154899Srik} 741154899Srik 742154899Srikint ce_get_cts (ce_chan_t *c) 743154899Srik{ 744154899Srik return 0; 745154899Srik} 746154899Srik 747154899Srikint ce_get_dsr (ce_chan_t *c) 748154899Srik{ 749154899Srik return 0; 750154899Srik} 751154899Srik 752154899Srikvoid ce_e1_timer (ce_chan_t *c) 753154899Srik{ 754154899Srik unsigned bpv, fas, crc4, ebit, pcv, oof, css; 755154899Srik unsigned int acc_status; 756154899Srik ce_board_t *b = c->board; 757154899Srik TAU32_E1_State *state; 758154899Srik 759154899Srik if (c->num >= b->ddk.Interfaces) 760154899Srik return; 761154899Srik 762154899Srik state = &b->ddk.InterfacesInfo[c->num]; 763154899Srik acc_status = c->acc_status; 764154899Srik 765154899Srik /* Clear acc_status */ 766154899Srik c->acc_status = b->ddk.InterfacesInfo[c->num].Status; 767154899Srik 768154899Srik /* Count seconds. 769154899Srik * During the first second after the channel startup 770154899Srik * the status registers are not stable yet, 771154899Srik * we will so skip the first second. */ 772154899Srik ++c->cursec; 773154899Srik if (! c->totsec && c->cursec <= 1) 774154899Srik return; 775154899Srik 776154899Srik c->status = 0; 777154899Srik 778154899Srik /* Compute the SNMP-compatible channel status. */ 779154899Srik oof = 0; 780154899Srik 781154899Srik if (acc_status & TAU32_RCL) 782154899Srik c->status |= ESTS_LOS; /* loss of signal */ 783154899Srik if (acc_status & TAU32_RUA1) 784154899Srik c->status |= ESTS_AIS; /* receiving all ones */ 785154899Srik 786154899Srik /* Get error counters. */ 787154899Srik bpv = state->RxViolations; 788154899Srik fas = 0; 789154899Srik crc4 = 0; 790154899Srik ebit = 0; 791154899Srik css = 0; 792154899Srik 793154899Srik if (! c->unfram) { 794154899Srik if (! c->use16 && (acc_status & TAU32_RSA1)) 795154899Srik c->status |= ESTS_AIS16; /* signaling all ones */ 796154899Srik if (! c->use16 && (acc_status & TAU32_RDMA)) 797154899Srik c->status |= ESTS_FARLOMF; /* alarm in timeslot 16 */ 798154899Srik if (acc_status & TAU32_RRA) 799154899Srik c->status |= ESTS_FARLOF; /* far loss of framing */ 800154899Srik 801154899Srik if (acc_status & TAU32_RFAS) { 802154899Srik c->status |= ESTS_LOF; /* loss of framing */ 803154899Srik ++oof; /* out of framing */ 804154899Srik } 805154899Srik if ((! c->use16 && (acc_status & TAU32_RCAS)) || 806154899Srik (c->crc4 && (acc_status & TAU32_RCRC4))) { 807154899Srik c->status |= ESTS_LOMF; /* loss of multiframing */ 808154899Srik ++oof; /* out of framing */ 809154899Srik } 810154899Srik fas = state->FasErrors; 811154899Srik crc4 = state->Crc4Errors; 812154899Srik ebit = state->FarEndBlockErrors; 813154899Srik 814154899Srik /* Controlled slip second -- any slip event. */ 815154899Srik css = state->TransmitSlips + state->ReceiveSlips; 816154899Srik } 817154899Srik 818154899Srik /* Clear state */ 819154899Srik state->RxViolations = 0; 820154899Srik state->FasErrors = 0; 821154899Srik state->Crc4Errors = 0; 822154899Srik state->FarEndBlockErrors = 0; 823154899Srik state->TransmitSlips = 0; 824154899Srik state->ReceiveSlips = 0; 825154899Srik 826154899Srik if (c->status & ESTS_LOS) 827154899Srik c->status = ESTS_LOS; 828154899Srik else if (c->status & ESTS_AIS) 829154899Srik c->status = ESTS_AIS; 830154899Srik else if (c->status & ESTS_LOF) 831154899Srik c->status = ESTS_LOF; 832154899Srik else if (c->status & ESTS_LOMF) 833154899Srik c->status &= ~(ESTS_FARLOMF | ESTS_AIS16); 834154899Srik 835154899Srik if (! c->status) 836154899Srik c->status = ESTS_NOALARM; 837154899Srik 838154899Srik c->currnt.bpv += bpv; 839154899Srik c->currnt.fse += fas; 840154899Srik if (c->crc4) { 841154899Srik c->currnt.crce += crc4; 842154899Srik c->currnt.rcrce += ebit; 843154899Srik } 844154899Srik 845154899Srik /* Path code violation is frame sync error if CRC4 disabled, 846154899Srik * or CRC error if CRC4 enabled. */ 847154899Srik pcv = fas; 848154899Srik if (c->crc4) 849154899Srik pcv += crc4; 850154899Srik 851154899Srik /* Unavaiable second -- receiving all ones, or 852154899Srik * loss of carrier, or loss of signal. */ 853154899Srik if (acc_status & (TAU32_RUA1 | TAU32_RCL)) 854154899Srik /* Unavailable second -- no other counters. */ 855154899Srik ++c->currnt.uas; 856154899Srik else { 857154899Srik /* Line errored second -- any BPV. */ 858154899Srik if (bpv) 859154899Srik ++c->currnt.les; 860154899Srik 861154899Srik /* Errored second -- any PCV, or out of frame sync, 862154899Srik * or any slip events. */ 863154899Srik if (pcv || oof || css) 864154899Srik ++c->currnt.es; 865154899Srik 866154899Srik /* Severely errored framing second -- out of frame sync. */ 867154899Srik if (oof) 868154899Srik ++c->currnt.oofs; 869154899Srik 870154899Srik /* Severely errored seconds -- 871154899Srik * 832 or more PCVs, or 2048 or more BPVs. */ 872154899Srik if (bpv >= 2048 || pcv >= 832) 873154899Srik ++c->currnt.ses; 874154899Srik else { 875154899Srik /* Bursty errored seconds -- 876154899Srik * no SES and more than 1 PCV. */ 877154899Srik if (pcv > 1) 878154899Srik ++c->currnt.bes; 879154899Srik 880154899Srik /* Collect data for computing 881154899Srik * degraded minutes. */ 882154899Srik ++c->degsec; 883154899Srik c->degerr += bpv + pcv; 884154899Srik } 885154899Srik } 886154899Srik 887154899Srik /* Degraded minutes -- having error rate more than 10e-6, 888154899Srik * not counting unavailable and severely errored seconds. */ 889154899Srik if (c->cursec % 60 == 0) { 890154899Srik if (c->degerr > c->degsec * 2048 / 1000) 891154899Srik ++c->currnt.dm; 892154899Srik c->degsec = 0; 893154899Srik c->degerr = 0; 894154899Srik } 895154899Srik 896154899Srik /* Rotate statistics every 15 minutes. */ 897154899Srik if (c->cursec > 15*60) { 898154899Srik int i; 899154899Srik 900154899Srik for (i=47; i>0; --i) 901154899Srik c->interval[i] = c->interval[i-1]; 902154899Srik c->interval[0] = c->currnt; 903154899Srik 904154899Srik /* Accumulate total statistics. */ 905154899Srik c->total.bpv += c->currnt.bpv; 906154899Srik c->total.fse += c->currnt.fse; 907154899Srik c->total.crce += c->currnt.crce; 908154899Srik c->total.rcrce += c->currnt.rcrce; 909154899Srik c->total.uas += c->currnt.uas; 910154899Srik c->total.les += c->currnt.les; 911154899Srik c->total.es += c->currnt.es; 912154899Srik c->total.bes += c->currnt.bes; 913154899Srik c->total.ses += c->currnt.ses; 914154899Srik c->total.oofs += c->currnt.oofs; 915154899Srik c->total.css += c->currnt.css; 916154899Srik c->total.dm += c->currnt.dm; 917154899Srik c->currnt.bpv = 0; 918154899Srik c->currnt.fse = 0; 919154899Srik c->currnt.crce = 0; 920154899Srik c->currnt.rcrce = 0; 921154899Srik c->currnt.uas = 0; 922154899Srik c->currnt.les = 0; 923154899Srik c->currnt.es = 0; 924154899Srik c->currnt.bes = 0; 925154899Srik c->currnt.ses = 0; 926154899Srik c->currnt.oofs = 0; 927154899Srik c->currnt.css = 0; 928154899Srik c->currnt.dm = 0; 929154899Srik 930154899Srik c->totsec += c->cursec; 931154899Srik c->cursec = 0; 932154899Srik } 933154899Srik} 934154899Srik 935154899Srikvoid ce_set_baud (ce_chan_t *c, unsigned long baud) 936154899Srik{ 937154899Srik TAU32_UserRequest *req; 938154899Srik ce_board_t *b = c->board; 939154899Srik unsigned long cfg = c->config & ~TAU32_framing_mode_mask; 940154899Srik unsigned long ts; 941154899Srik unsigned long kbps = (baud + 32000) / 64000 * 64; 942154899Srik 943154899Srik if (!c->unfram || c->num != 0 || 944154899Srik baud == c->baud || b->cr.pending >= CONFREQSZ) 945154899Srik return; 946154899Srik 947154899Srik if (!kbps || kbps > 1024) { 948154899Srik ts = 0xffffffffUL; 949154899Srik cfg |= TAU32_unframed_2048; 950154899Srik } else if (kbps > 512) { 951154899Srik ts = 0x0000ffffUL; 952154899Srik cfg |= TAU32_unframed_1024; 953154899Srik } else if (kbps > 256) { 954154899Srik ts = 0x000000ffUL; 955154899Srik cfg |= TAU32_unframed_512; 956154899Srik } else if (kbps > 128) { 957154899Srik ts = 0x0000000fUL; 958154899Srik cfg |= TAU32_unframed_256; 959154899Srik } else if (kbps > 64) { 960154899Srik ts = 0x00000003UL; 961154899Srik cfg |= TAU32_unframed_128; 962154899Srik } else { 963154899Srik ts = 0x00000001UL; 964154899Srik cfg |= TAU32_unframed_64; 965154899Srik } 966154899Srik 967154899Srik /* _ce_set_ts () will set proper baud */ 968154899Srik _ce_set_ts (c, ts); 969154899Srik CE_PREREQUEST (b, c, b->cr.queue, req); 970154899Srik if (!req) 971154899Srik return; 972154899Srik req->Command = TAU32_Configure_E1; 973154899Srik req->Io.InterfaceConfig.Interface = TAU32_E1_A; 974154899Srik req->Io.InterfaceConfig.Config = cfg; 975154899Srik req->Io.InterfaceConfig.UnframedTsMask = ts; 976154899Srik if (ce_cfg_submit (b)) { 977154899Srik c->baud = baud; 978154899Srik c->ts = ts; 979154899Srik c->config = cfg; 980154899Srik } 981154899Srik} 982154899Srik 983154899Srikvoid ce_set_lloop (ce_chan_t *c, unsigned char on) 984154899Srik{ 985154899Srik TAU32_UserRequest *req; 986154899Srik unsigned long cfg = c->config & ~(TAU32_line_mode_mask | TAU32_ais_on_loss); 987154899Srik ce_board_t *b = c->board; 988154899Srik 989154899Srik if (c->num >= b->ddk.Interfaces || b->cr.pending >= CONFREQSZ) 990154899Srik return; 991154899Srik on = on ? 1 : 0; 992154899Srik if (on == c->lloop) 993154899Srik return; 994154899Srik 995154899Srik cfg |= on ? TAU32_LineLoopInt : (TAU32_LineNormal | TAU32_ais_on_loss); 996154899Srik CE_PREREQUEST (b, c, b->cr.queue, req); 997154899Srik if (!req) 998154899Srik return; 999154899Srik req->Command = TAU32_Configure_E1; 1000154899Srik req->Io.InterfaceConfig.Interface = c->num ? TAU32_E1_B : TAU32_E1_A; 1001154899Srik req->Io.InterfaceConfig.Config = cfg; 1002154899Srik req->Io.InterfaceConfig.UnframedTsMask = c->ts; 1003154899Srik CE_DDK_DEBUG (b, c, ("Submit lloop\n")); 1004154899Srik if (ce_cfg_submit (b)) { 1005154899Srik c->lloop = on ? 1 : 0; 1006154899Srik c->config = cfg; 1007154899Srik } 1008154899Srik} 1009154899Srik 1010154899Srikvoid ce_set_rloop (ce_chan_t *c, unsigned char on) 1011154899Srik{ 1012154899Srik TAU32_UserRequest *req; 1013154899Srik unsigned long cfg = c->config & ~TAU32_line_mode_mask; 1014154899Srik ce_board_t *b = c->board; 1015154899Srik 1016154899Srik if (c->num >= b->ddk.Interfaces || b->cr.pending >= CONFREQSZ) 1017154899Srik return; 1018154899Srik on = on ? 1 : 0; 1019154899Srik if (on == c->rloop) 1020154899Srik return; 1021154899Srik 1022154899Srik cfg |= on ? TAU32_LineLoopExt : TAU32_LineNormal; 1023154899Srik CE_PREREQUEST (b, c, b->cr.queue, req); 1024154899Srik if (!req) 1025154899Srik return; 1026154899Srik req->Command = TAU32_Configure_E1; 1027154899Srik req->Io.InterfaceConfig.Interface = c->num ? TAU32_E1_B : TAU32_E1_A; 1028154899Srik req->Io.InterfaceConfig.Config = cfg; 1029154899Srik req->Io.InterfaceConfig.UnframedTsMask = c->ts; 1030154899Srik CE_DDK_DEBUG (b, c, ("Submit rloop\n")); 1031154899Srik if (ce_cfg_submit (b)) { 1032154899Srik c->rloop = on ? 1 : 0; 1033154899Srik c->config = cfg; 1034154899Srik } 1035154899Srik} 1036154899Srik 1037154899Srikvoid ce_set_higain (ce_chan_t *c, unsigned char on) 1038154899Srik{ 1039154899Srik TAU32_UserRequest *req; 1040154899Srik unsigned long cfg = c->config & ~TAU32_higain; 1041154899Srik ce_board_t *b = c->board; 1042154899Srik 1043154899Srik if (c->num >= b->ddk.Interfaces || b->cr.pending >= CONFREQSZ) 1044154899Srik return; 1045154899Srik on = on ? 1 : 0; 1046154899Srik if (on == c->higain) 1047154899Srik return; 1048154899Srik 1049154899Srik cfg |= on ? TAU32_higain : 0; 1050154899Srik CE_PREREQUEST (b, c, b->cr.queue, req); 1051154899Srik if (!req) 1052154899Srik return; 1053154899Srik req->Command = TAU32_Configure_E1; 1054154899Srik req->Io.InterfaceConfig.Interface = c->num ? TAU32_E1_B : TAU32_E1_A; 1055154899Srik req->Io.InterfaceConfig.Config = cfg; 1056154899Srik req->Io.InterfaceConfig.UnframedTsMask = c->ts; 1057154899Srik CE_DDK_DEBUG (b, c, ("Submit higain\n")); 1058154899Srik if (ce_cfg_submit (b)) { 1059154899Srik c->higain = on ? 1 : 0; 1060154899Srik c->config = cfg; 1061154899Srik } 1062154899Srik} 1063154899Srik 1064154899Srikstatic void _ce_set_ts (ce_chan_t *c, unsigned long ts) 1065154899Srik{ 1066154899Srik TAU32_UserRequest *req; 1067154899Srik ce_board_t *b = c->board; 1068154899Srik unsigned long mask = 0, omask = 0; 1069154899Srik int nts = 0, ots = 0, pts = 0; 1070154899Srik int i, k; 1071154899Srik 1072154899Srik if (b->cr.pending >= CONFREQSZ) 1073154899Srik return; 1074154899Srik 1075154899Srik /* 1076154899Srik * pts - number of busy "peb" ts 1077154899Srik * ots - current (old) busy ts 1078154899Srik * nts - new busy ts 1079154899Srik */ 1080154899Srik for (i = 0; i < 32; i++) { 1081154899Srik if (c->ts & (1ul << i)) 1082154899Srik ots++; 1083154899Srik if (ts & (1ul << i)) 1084154899Srik nts++; 1085154899Srik if (b->dxc[i] != TAU32_CROSS_OFF) 1086154899Srik pts++; 1087154899Srik } 1088154899Srik 1089154899Srik CE_DDK_DEBUG (b, c, ("pts: %d ots: %d nts: %d ts: %lx\n", pts, ots, nts, 1090154899Srik ts)); 1091154899Srik /* 32 - all busy + my old busy == free */ 1092154899Srik if (32 - pts + ots - nts < 0) 1093154899Srik return; 1094154899Srik 1095154899Srik /* Ok. We have enougth "peb" ts. Clean old. */ 1096154899Srik /* We start from zero, cause this is peb cells */ 1097154899Srik for (i = 0; i < 32; i++) { 1098154899Srik int tin = b->dxc[i]; 1099154899Srik int t = tin % 32; 1100154899Srik if (tin < (c->dir?64:32) || tin > (c->dir?95:63)) 1101154899Srik continue; 1102154899Srik if (c->ts & (1ul << t)) { 1103154899Srik b->dxc[tin] = TAU32_CROSS_OFF; 1104154899Srik b->dxc[i] = TAU32_CROSS_OFF; 1105154899Srik if (b->dxc[t + 32] == TAU32_CROSS_OFF && 1106154899Srik b->dxc[t + 64] == TAU32_CROSS_OFF) { 1107154899Srik b->dxc[t + 32] = t + 64; 1108154899Srik b->dxc[t + 64] = t + 32; 1109154899Srik } 1110154899Srik omask |= (1ul << t); 1111154899Srik } 1112154899Srik } 1113154899Srik 1114154899Srik k = 0; 1115154899Srik /* Set */ 1116154899Srik for (i = 0; i < 32; i++) { 1117154899Srik if ((ts & (1ul << i)) == 0) 1118154899Srik continue; 1119154899Srik while (b->dxc[k] != TAU32_CROSS_OFF) { 1120154899Srik k++; 1121154899Srik /* Paranoic */ 1122154899Srik if (k >= 32) { 1123154899Srik CE_DDK_DEBUG (b, c, ("TS count overflow\n")); 1124154899Srik return; 1125154899Srik } 1126154899Srik } 1127154899Srik b->dxc[k] = (c->dir?64:32) + i; 1128154899Srik b->dxc[(c->dir?64:32) + i] = k; 1129154899Srik if (b->dxc[(c->dir?32:64) + i] == (c->dir?64:32) + i) 1130154899Srik b->dxc[(c->dir?32:64) + i] = TAU32_CROSS_OFF; 1131154899Srik mask |= (1ul << k); 1132154899Srik } 1133154899Srik 1134154899Srik c->ts = ts; 1135154899Srik c->baud = nts*64000; 1136154899Srik 1137154899Srik CE_PREREQUEST (b, c, b->cr.queue, req); 1138154899Srik if (!req) 1139154899Srik return; 1140154899Srik 1141154899Srik req->Command = TAU32_Timeslots_Channel | TAU32_Configure_Commit; 1142154899Srik req->Io.ChannelNumber = c->num; 1143154899Srik req->Io.ChannelConfig.AssignedTsMask = mask; 1144154899Srik 1145154899Srik if (c->phony) { 1146154899Srik b->pmask &= ~omask; 1147154899Srik b->pmask |= mask; 1148154899Srik } 1149154899Srik 1150154899Srik CE_DDK_DEBUG (b, c, ("ts=%lx mask=%lx omask=%lx pmask=%lx\n", c->ts, 1151154899Srik mask, omask, b->pmask)); 1152154899Srik CE_DDK_DEBUG (b, c, ("Crossmatrix table:\n")); 1153154899Srik 1154154899Srik#ifdef CE_DDK_DEBUG_ENABLED 1155154899Srik for (i = 0; i < 32*3; i++) { 1156154899Srik printf ("%3d\t%s", b->dxc[i], (i%8==7)?"\n":""); 1157154899Srik printf ("%s",(i%32==31)?"\n":""); 1158154899Srik } 1159154899Srik#endif 1160154899Srik 1161154899Srik CE_DDK_DEBUG (b, c, ("Submit tsmask\n")); 1162154899Srik if (!ce_cfg_submit (b)) { 1163154899Srik CE_DDK_DEBUG (b, c, ("Fail to submit tsmask\n")); 1164154899Srik /* Do some error processing */ 1165154899Srik return; 1166154899Srik } 1167154899Srik 1168154899Srik CE_DDK_DEBUG (b, c, ("SetCrossMatrix\n")); 1169154899Srik if (!TAU32_SetCrossMatrix(b->ddk.pControllerObject, b->dxc, b->pmask)) { 1170154899Srik CE_DDK_DEBUG (b, c, ("Faild to SetCrossMatrix\n")); 1171154899Srik /* Do some error processing */ 1172154899Srik return; 1173154899Srik } 1174154899Srik} 1175154899Srik 1176154899Srikvoid ce_set_ts (ce_chan_t *c, unsigned long ts) 1177154899Srik{ 1178154899Srik ce_board_t *b = c->board; 1179154899Srik ce_chan_t *x; 1180154899Srik 1181154899Srik if (c->ts == ts || b->chan->unfram) 1182154899Srik return; 1183154899Srik 1184154899Srik ts &= ~(1ul); 1185154899Srik 1186154899Srik if (!b->chan[c->dir].use16) 1187154899Srik ts &= ~(1ul << 16); 1188154899Srik 1189154899Srik for (x = b->chan; x < b->chan + NCHAN; x++) { 1190154899Srik if (x == c || x->dir != c->dir) 1191154899Srik continue; 1192154899Srik ts &= ~x->ts; 1193154899Srik } 1194154899Srik 1195154899Srik _ce_set_ts (c, ts); 1196154899Srik} 1197154899Srik 1198154899Srikvoid ce_set_unfram (ce_chan_t *c, unsigned char on) 1199154899Srik{ 1200154899Srik TAU32_UserRequest *req; 1201154899Srik ce_board_t *b = c->board; 1202154899Srik unsigned long cfg = c->config & ~TAU32_framing_mode_mask; 1203154899Srik unsigned long i; 1204154899Srik 1205154899Srik if (c->num != 0 || b->cr.pending + 2*32 + 3>= CONFREQSZ) 1206154899Srik return; 1207154899Srik 1208154899Srik on = on ? 1 : 0; 1209154899Srik 1210154899Srik if (on == c->unfram) 1211154899Srik return; 1212154899Srik 1213154899Srik if (on) { 1214154899Srik ce_set_dir (c, 0); 1215154899Srik for (i = 1; i < TAU32_CHANNELS; i++) { 1216154899Srik ce_set_ts (b->chan + i, 0); 1217154899Srik ce_set_phony (b->chan + i, 0); 1218154899Srik } 1219154899Srik ce_set_use16 (b->chan + 0, 0); 1220154899Srik ce_set_use16 (b->chan + 1, 0); 1221154899Srik /* Get current value, previous ce_set request may change it */ 1222154899Srik cfg = c->config & ~TAU32_framing_mode_mask; 1223154899Srik cfg |= TAU32_unframed_2048; 1224154899Srik c->unfram = on; 1225154899Srik _ce_set_ts (b->chan, ~0ul); 1226154899Srik c->config = cfg; 1227154899Srik /* XXXRIK: Do extra checks on config queue size*/ 1228154899Srik if (b->ddk.Interfaces) { 1229154899Srik CE_PREREQUEST (b, c, b->cr.queue, req); 1230154899Srik if (!req) 1231154899Srik return; 1232154899Srik req->Command = TAU32_Configure_E1; 1233154899Srik req->Io.InterfaceConfig.Interface = TAU32_E1_B; 1234154899Srik req->Io.InterfaceConfig.Config = TAU32_LineOff; 1235154899Srik req->Io.InterfaceConfig.UnframedTsMask = 0; 1236154899Srik CE_DDK_DEBUG (b, c, ("unfram: B line off\n")); 1237154899Srik ce_cfg_submit (b); 1238154899Srik } 1239154899Srik CE_PREREQUEST (b, c, b->cr.queue, req); 1240154899Srik if (!req) 1241154899Srik return; 1242154899Srik req->Command = TAU32_Configure_E1; 1243154899Srik req->Io.InterfaceConfig.Interface = TAU32_E1_A; 1244154899Srik req->Io.InterfaceConfig.Config = cfg; 1245154899Srik req->Io.InterfaceConfig.UnframedTsMask = c->ts; 1246154899Srik CE_DDK_DEBUG (b, c, ("Submit unfram\n")); 1247154899Srik ce_cfg_submit (b); 1248154899Srik } else { 1249154899Srik cfg |= TAU32_framed_cas_cross; 1250154899Srik CE_PREREQUEST (b, c, b->cr.queue, req); 1251154899Srik if (!req) 1252154899Srik return; 1253154899Srik req->Command = TAU32_Configure_E1; 1254154899Srik req->Io.InterfaceConfig.Interface = TAU32_E1_ALL; 1255154899Srik req->Io.InterfaceConfig.Config = cfg; 1256154899Srik req->Io.InterfaceConfig.UnframedTsMask = 0; 1257154899Srik CE_DDK_DEBUG (b, c, ("Submit framed\n")); 1258154899Srik ce_cfg_submit (b); 1259154899Srik ce_set_ts (c, 0); 1260154899Srik } 1261154899Srik c->unfram = on; 1262154899Srik} 1263154899Srik 1264154899Srikvoid ce_set_phony (ce_chan_t *c, unsigned char on) 1265154899Srik{ 1266154899Srik TAU32_UserRequest *req; 1267154899Srik ce_board_t *b = c->board; 1268154899Srik unsigned long mask = 0; 1269154899Srik int i; 1270154899Srik 1271154899Srik if ((c->phony && on) || (c->phony == 0 && on == 0) || 1272154899Srik b->cr.pending >= CONFREQSZ) 1273154899Srik return; 1274154899Srik 1275154899Srik CE_PREREQUEST (b, c, b->cr.queue, req); 1276154899Srik if (!req) 1277154899Srik return; 1278154899Srik 1279154899Srik req->Command = TAU32_Configure_Channel; 1280154899Srik req->Io.InterfaceConfig.Config = on ? TAU32_TMA : 1281154899Srik (TAU32_HDLC | TAU32_fr_rx_splitcheck | TAU32_fr_rx_fitcheck); 1282154899Srik req->Io.ChannelNumber = c->num; 1283154899Srik CE_DDK_DEBUG (b, c, ("Submit phony\n")); 1284154899Srik if (!ce_cfg_submit (b)) { 1285154899Srik /* Do some error processing */ 1286154899Srik return; 1287154899Srik } 1288154899Srik 1289154899Srik for (i = 0; i < 32; i++) { 1290154899Srik int t = b->dxc[i] % 32; 1291154899Srik if (b->dxc[i] < (c->dir?64:32) || b->dxc[i] > (c->dir?95:63)) 1292154899Srik continue; 1293154899Srik if (c->ts & (1ul << t)) 1294154899Srik mask |= (1ul << t); 1295154899Srik } 1296154899Srik 1297154899Srik CE_DDK_DEBUG (b, c, ("phony mask:%lx\n", mask)); 1298154899Srik 1299154899Srik if (on) { 1300154899Srik b->pmask |= mask; 1301154899Srik } else { 1302154899Srik b->pmask &= ~mask; 1303154899Srik } 1304154899Srik 1305154899Srik c->phony = on ? 1 : 0; 1306154899Srik 1307154899Srik CE_DDK_DEBUG (b, c, ("Submit (setcrosmatrix) phony\n")); 1308154899Srik if (!TAU32_SetCrossMatrix(b->ddk.pControllerObject, b->dxc, b->pmask)) { 1309154899Srik /* Do some error processing */ 1310154899Srik return; 1311154899Srik } 1312154899Srik} 1313154899Srik 1314154899Srikvoid ce_set_scrambler (ce_chan_t *c, unsigned char on) 1315154899Srik{ 1316154899Srik TAU32_UserRequest *req; 1317154899Srik unsigned long cfg = c->config & ~TAU32_scrambler; 1318154899Srik ce_board_t *b = c->board; 1319154899Srik 1320154899Srik if (c->num != 0 || c->unfram == 0 || b->cr.pending >= CONFREQSZ) 1321154899Srik return; 1322154899Srik on = on ? 1 : 0; 1323154899Srik if (on == c->scrambler) 1324154899Srik return; 1325154899Srik 1326154899Srik cfg |= on ? TAU32_scrambler : 0; 1327154899Srik CE_PREREQUEST (b, c, b->cr.queue, req); 1328154899Srik if (!req) 1329154899Srik return; 1330154899Srik req->Command = TAU32_Configure_E1; 1331154899Srik req->Io.InterfaceConfig.Interface = c->num ? TAU32_E1_B : TAU32_E1_A; 1332154899Srik req->Io.InterfaceConfig.Config = cfg; 1333154899Srik req->Io.InterfaceConfig.UnframedTsMask = c->ts; 1334154899Srik CE_DDK_DEBUG (b, c, ("Submit scrambler\n")); 1335154899Srik if (ce_cfg_submit (b)) { 1336154899Srik c->scrambler = on ? 1 : 0; 1337154899Srik c->config = cfg; 1338154899Srik } 1339154899Srik} 1340154899Srik 1341154899Srikvoid ce_set_monitor (ce_chan_t *c, unsigned char on) 1342154899Srik{ 1343154899Srik TAU32_UserRequest *req; 1344154899Srik unsigned long cfg = c->config & ~TAU32_monitor; 1345154899Srik ce_board_t *b = c->board; 1346154899Srik 1347154899Srik if (c->num >= b->ddk.Interfaces || b->cr.pending >= CONFREQSZ) 1348154899Srik return; 1349154899Srik on = on ? 1 : 0; 1350154899Srik if (on == c->monitor) 1351154899Srik return; 1352154899Srik 1353154899Srik cfg |= on ? TAU32_monitor : 0; 1354154899Srik CE_PREREQUEST (b, c, b->cr.queue, req); 1355154899Srik if (!req) 1356154899Srik return; 1357154899Srik req->Command = TAU32_Configure_E1; 1358154899Srik req->Io.InterfaceConfig.Interface = c->num ? TAU32_E1_B : TAU32_E1_A; 1359154899Srik req->Io.InterfaceConfig.Config = cfg; 1360154899Srik req->Io.InterfaceConfig.UnframedTsMask = c->ts; 1361154899Srik CE_DDK_DEBUG (b, c, ("Submit monitor\n")); 1362154899Srik if (ce_cfg_submit (b)) { 1363154899Srik c->monitor = on ? 1 : 0; 1364154899Srik c->config = cfg; 1365154899Srik } 1366154899Srik} 1367154899Srik 1368154899Srikstatic void _ce_submit_configure_e1 (ce_chan_t *c, char *rname) 1369154899Srik{ 1370154899Srik TAU32_UserRequest *req; 1371154899Srik ce_board_t *b = c->board; 1372154899Srik 1373154899Srik CE_PREREQUEST (b, c, b->cr.queue, req); 1374154899Srik if (!req) 1375154899Srik return; 1376154899Srik req->Command = TAU32_Configure_E1; 1377154899Srik req->Io.InterfaceConfig.Interface = c->num == 0 ? TAU32_E1_A : TAU32_E1_B; 1378154899Srik req->Io.InterfaceConfig.Config = c->config; 1379154899Srik req->Io.InterfaceConfig.UnframedTsMask = c->ts; 1380154899Srik CE_DDK_DEBUG (b, c, ("Submit %s\n", rname ? rname : "")); 1381154899Srik if (!ce_cfg_submit (b)) { 1382154899Srik CE_DDK_DEBUG (b, c, ("Fail to submit %s\n", rname?rname:"")); 1383154899Srik /* Do some error processing */ 1384154899Srik return; 1385154899Srik } 1386154899Srik} 1387154899Srik 1388154899Srikvoid ce_set_use16 (ce_chan_t *c, unsigned char on) 1389154899Srik{ 1390154899Srik ce_board_t *b = c->board; 1391154899Srik ce_chan_t *x; 1392154899Srik unsigned long cfg[2]; 1393154899Srik int use[2]; 1394154899Srik 1395154899Srik if (c->num >= b->ddk.Interfaces || b->cr.pending + 2 >= CONFREQSZ) 1396154899Srik return; 1397154899Srik 1398154899Srik cfg[0] = b->chan[0].config & ~TAU32_framing_mode_mask; 1399154899Srik cfg[1] = b->chan[1].config & ~TAU32_framing_mode_mask; 1400154899Srik 1401154899Srik on = on ? 1 : 0; 1402154899Srik 1403154899Srik if (c->use16 == on || b->chan->unfram) 1404154899Srik return; 1405154899Srik 1406154899Srik use[0] = b->chan[0].use16; 1407154899Srik use[1] = b->chan[1].use16; 1408154899Srik 1409154899Srik /* Correct value */ 1410154899Srik use[c->num] = on; 1411154899Srik 1412154899Srik if (b->ddk.Interfaces == 1) { 1413154899Srik cfg[0] |= on ? TAU32_framed_cas_set : TAU32_framed_no_cas; 1414154899Srik } else { 1415154899Srik if (use[0] == 0 && use[1] == 0) { 1416154899Srik cfg[0] |= TAU32_framed_cas_cross; 1417154899Srik cfg[1] |= TAU32_framed_cas_cross; 1418154899Srik } else if (use[0] == 0) { 1419154899Srik cfg[0] |= TAU32_framed_cas_set; 1420154899Srik cfg[1] |= TAU32_framed_no_cas; 1421154899Srik } else if (use[1] == 0) { 1422154899Srik cfg[0] |= TAU32_framed_no_cas; 1423154899Srik cfg[1] |= TAU32_framed_cas_set; 1424154899Srik } else { 1425154899Srik cfg[0] |= TAU32_framed_no_cas; 1426154899Srik cfg[1] |= TAU32_framed_no_cas; 1427154899Srik } 1428154899Srik } 1429154899Srik 1430154899Srik c->use16 = on; 1431154899Srik 1432154899Srik for (x = b->chan; !on && x < b->chan + NCHAN; x++) { 1433154899Srik if (x->dir == c->num && x->ts & (1ul<<16)) { 1434154899Srik ce_set_ts (x, x->ts); 1435154899Srik break; 1436154899Srik } 1437154899Srik } 1438154899Srik 1439154899Srik if (cfg[0] != b->chan[0].config) { 1440154899Srik b->chan[0].config = cfg[0]; 1441154899Srik _ce_submit_configure_e1 (b->chan + 0, "use16"); 1442154899Srik } 1443154899Srik 1444154899Srik if (cfg[1] != b->chan[1].config) { 1445154899Srik b->chan[1].config = cfg[1]; 1446154899Srik _ce_submit_configure_e1 (b->chan + 1, "use16"); 1447154899Srik } 1448154899Srik} 1449154899Srik 1450154899Srikvoid ce_set_crc4 (ce_chan_t *c, unsigned char on) 1451154899Srik{ 1452154899Srik TAU32_UserRequest *req; 1453154899Srik unsigned long cfg = c->config & ~TAU32_crc4_mf; 1454154899Srik ce_board_t *b = c->board; 1455154899Srik 1456154899Srik if (c->num >= b->ddk.Interfaces || b->cr.pending >= CONFREQSZ) 1457154899Srik return; 1458154899Srik on = on ? 1 : 0; 1459154899Srik if (on == c->crc4 || b->chan->unfram) 1460154899Srik return; 1461154899Srik 1462154899Srik cfg |= on ? TAU32_crc4_mf : 0; 1463154899Srik CE_PREREQUEST (b, c, b->cr.queue, req); 1464154899Srik if (!req) 1465154899Srik return; 1466154899Srik req->Command = TAU32_Configure_E1; 1467154899Srik req->Io.InterfaceConfig.Interface = c->num ? TAU32_E1_B : TAU32_E1_A; 1468154899Srik req->Io.InterfaceConfig.Config = cfg; 1469154899Srik req->Io.InterfaceConfig.UnframedTsMask = c->ts; 1470154899Srik CE_DDK_DEBUG (b, c, ("Submit crc4\n")); 1471154899Srik if (ce_cfg_submit (b)) { 1472154899Srik c->crc4 = on ? 1 : 0; 1473154899Srik c->config = cfg; 1474154899Srik } 1475154899Srik} 1476154899Srik 1477154899Srikvoid ce_set_gsyn (ce_chan_t *c, int syn) 1478154899Srik{ 1479154899Srik ce_board_t *b = c->board; 1480154899Srik unsigned int mode; 1481154899Srik 1482154899Srik if (c->num >= b->ddk.Interfaces) 1483154899Srik return; 1484154899Srik 1485154899Srik if (syn == GSYN_RCV) 1486154899Srik syn = c->num ? GSYN_RCV1 : GSYN_RCV0; 1487154899Srik 1488154899Srik switch (syn) { 1489154899Srik default: mode = TAU32_SYNC_INTERNAL; break; 1490154899Srik case GSYN_RCV0: mode = TAU32_SYNC_RCV_A; break; 1491154899Srik case GSYN_RCV1: mode = TAU32_SYNC_RCV_B; break; 1492154899Srik } 1493154899Srik 1494154899Srik CE_DDK_DEBUG (b, c, ("Set Sync Mode\n")); 1495154899Srik if (TAU32_SetSyncMode (b->ddk.pControllerObject, mode)) { 1496154899Srik b->chan->gsyn = syn; 1497154899Srik if (b->ddk.Interfaces > 1) 1498154899Srik (b->chan + 1)->gsyn = syn; 1499154899Srik } 1500154899Srik} 1501154899Srik 1502154899Srikint ce_get_cable (ce_chan_t *c) 1503154899Srik{ 1504154899Srik ce_board_t *b = c->board; 1505154899Srik if (c->num >= b->ddk.Interfaces) 1506154899Srik return 0; 1507154899Srik 1508154899Srik return CABLE_TP; 1509154899Srik} 1510154899Srik 1511154899Srikvoid ce_set_dir (ce_chan_t *c, int dir) 1512154899Srik{ 1513154899Srik ce_board_t *b = c->board; 1514154899Srik unsigned long ts; 1515154899Srik if (b->cr.pending + 1>= CONFREQSZ || c->dir == dir) 1516154899Srik return; 1517154899Srik 1518154899Srik ts = c->ts; 1519154899Srik ce_set_ts (c, 0); 1520154899Srik c->dir = dir; 1521154899Srik ce_set_ts (c, ts); 1522154899Srik} 1523