1/* $Id: hfc_2bs0.c,v 1.20.2.6 2004/02/11 13:21:33 keil Exp $ 2 * 3 * specific routines for CCD's HFC 2BS0 4 * 5 * Author Karsten Keil 6 * Copyright by Karsten Keil <keil@isdn4linux.de> 7 * 8 * This software may be used and distributed according to the terms 9 * of the GNU General Public License, incorporated herein by reference. 10 * 11 */ 12 13#include <linux/init.h> 14#include "hisax.h" 15#include "hfc_2bs0.h" 16#include "isac.h" 17#include "isdnl1.h" 18#include <linux/interrupt.h> 19#include <linux/slab.h> 20 21static inline int 22WaitForBusy(struct IsdnCardState *cs) 23{ 24 int to = 130; 25 u_char val; 26 27 while (!(cs->BC_Read_Reg(cs, HFC_STATUS, 0) & HFC_BUSY) && to) { 28 val = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2 | 29 (cs->hw.hfc.cip & 3)); 30 udelay(1); 31 to--; 32 } 33 if (!to) { 34 printk(KERN_WARNING "HiSax: %s timeout\n", __func__); 35 return (0); 36 } else 37 return (to); 38} 39 40static inline int 41WaitNoBusy(struct IsdnCardState *cs) 42{ 43 int to = 125; 44 45 while ((cs->BC_Read_Reg(cs, HFC_STATUS, 0) & HFC_BUSY) && to) { 46 udelay(1); 47 to--; 48 } 49 if (!to) { 50 printk(KERN_WARNING "HiSax: waitforBusy timeout\n"); 51 return (0); 52 } else 53 return (to); 54} 55 56static int 57GetFreeFifoBytes(struct BCState *bcs) 58{ 59 int s; 60 61 if (bcs->hw.hfc.f1 == bcs->hw.hfc.f2) 62 return (bcs->cs->hw.hfc.fifosize); 63 s = bcs->hw.hfc.send[bcs->hw.hfc.f1] - bcs->hw.hfc.send[bcs->hw.hfc.f2]; 64 if (s <= 0) 65 s += bcs->cs->hw.hfc.fifosize; 66 s = bcs->cs->hw.hfc.fifosize - s; 67 return (s); 68} 69 70static int 71ReadZReg(struct BCState *bcs, u_char reg) 72{ 73 int val; 74 75 WaitNoBusy(bcs->cs); 76 val = 256 * bcs->cs->BC_Read_Reg(bcs->cs, HFC_DATA, reg | HFC_CIP | HFC_Z_HIGH); 77 WaitNoBusy(bcs->cs); 78 val += bcs->cs->BC_Read_Reg(bcs->cs, HFC_DATA, reg | HFC_CIP | HFC_Z_LOW); 79 return (val); 80} 81 82static void 83hfc_clear_fifo(struct BCState *bcs) 84{ 85 struct IsdnCardState *cs = bcs->cs; 86 int idx, cnt; 87 int rcnt, z1, z2; 88 u_char cip, f1, f2; 89 90 if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) 91 debugl1(cs, "hfc_clear_fifo"); 92 cip = HFC_CIP | HFC_F1 | HFC_REC | HFC_CHANNEL(bcs->channel); 93 if ((cip & 0xc3) != (cs->hw.hfc.cip & 0xc3)) { 94 cs->BC_Write_Reg(cs, HFC_STATUS, cip, cip); 95 WaitForBusy(cs); 96 } 97 WaitNoBusy(cs); 98 f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip); 99 cip = HFC_CIP | HFC_F2 | HFC_REC | HFC_CHANNEL(bcs->channel); 100 WaitNoBusy(cs); 101 f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip); 102 z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel)); 103 z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel)); 104 cnt = 32; 105 while (((f1 != f2) || (z1 != z2)) && cnt--) { 106 if (cs->debug & L1_DEB_HSCX) 107 debugl1(cs, "hfc clear %d f1(%d) f2(%d)", 108 bcs->channel, f1, f2); 109 rcnt = z1 - z2; 110 if (rcnt < 0) 111 rcnt += cs->hw.hfc.fifosize; 112 if (rcnt) 113 rcnt++; 114 if (cs->debug & L1_DEB_HSCX) 115 debugl1(cs, "hfc clear %d z1(%x) z2(%x) cnt(%d)", 116 bcs->channel, z1, z2, rcnt); 117 cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel); 118 idx = 0; 119 while ((idx < rcnt) && WaitNoBusy(cs)) { 120 cs->BC_Read_Reg(cs, HFC_DATA_NODEB, cip); 121 idx++; 122 } 123 if (f1 != f2) { 124 WaitNoBusy(cs); 125 cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC | 126 HFC_CHANNEL(bcs->channel)); 127 WaitForBusy(cs); 128 } 129 cip = HFC_CIP | HFC_F1 | HFC_REC | HFC_CHANNEL(bcs->channel); 130 WaitNoBusy(cs); 131 f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip); 132 cip = HFC_CIP | HFC_F2 | HFC_REC | HFC_CHANNEL(bcs->channel); 133 WaitNoBusy(cs); 134 f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip); 135 z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel)); 136 z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel)); 137 } 138 return; 139} 140 141 142static struct sk_buff 143* 144hfc_empty_fifo(struct BCState *bcs, int count) 145{ 146 u_char *ptr; 147 struct sk_buff *skb; 148 struct IsdnCardState *cs = bcs->cs; 149 int idx; 150 int chksum; 151 u_char stat, cip; 152 153 if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) 154 debugl1(cs, "hfc_empty_fifo"); 155 idx = 0; 156 if (count > HSCX_BUFMAX + 3) { 157 if (cs->debug & L1_DEB_WARN) 158 debugl1(cs, "hfc_empty_fifo: incoming packet too large"); 159 cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel); 160 while ((idx++ < count) && WaitNoBusy(cs)) 161 cs->BC_Read_Reg(cs, HFC_DATA_NODEB, cip); 162 WaitNoBusy(cs); 163 stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC | 164 HFC_CHANNEL(bcs->channel)); 165 WaitForBusy(cs); 166 return (NULL); 167 } 168 if ((count < 4) && (bcs->mode != L1_MODE_TRANS)) { 169 if (cs->debug & L1_DEB_WARN) 170 debugl1(cs, "hfc_empty_fifo: incoming packet too small"); 171 cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel); 172 while ((idx++ < count) && WaitNoBusy(cs)) 173 cs->BC_Read_Reg(cs, HFC_DATA_NODEB, cip); 174 WaitNoBusy(cs); 175 stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC | 176 HFC_CHANNEL(bcs->channel)); 177 WaitForBusy(cs); 178#ifdef ERROR_STATISTIC 179 bcs->err_inv++; 180#endif 181 return (NULL); 182 } 183 if (bcs->mode == L1_MODE_TRANS) 184 count -= 1; 185 else 186 count -= 3; 187 if (!(skb = dev_alloc_skb(count))) 188 printk(KERN_WARNING "HFC: receive out of memory\n"); 189 else { 190 ptr = skb_put(skb, count); 191 idx = 0; 192 cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel); 193 while ((idx < count) && WaitNoBusy(cs)) { 194 *ptr++ = cs->BC_Read_Reg(cs, HFC_DATA_NODEB, cip); 195 idx++; 196 } 197 if (idx != count) { 198 debugl1(cs, "RFIFO BUSY error"); 199 printk(KERN_WARNING "HFC FIFO channel %d BUSY Error\n", bcs->channel); 200 dev_kfree_skb_any(skb); 201 if (bcs->mode != L1_MODE_TRANS) { 202 WaitNoBusy(cs); 203 stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC | 204 HFC_CHANNEL(bcs->channel)); 205 WaitForBusy(cs); 206 } 207 return (NULL); 208 } 209 if (bcs->mode != L1_MODE_TRANS) { 210 WaitNoBusy(cs); 211 chksum = (cs->BC_Read_Reg(cs, HFC_DATA, cip) << 8); 212 WaitNoBusy(cs); 213 chksum += cs->BC_Read_Reg(cs, HFC_DATA, cip); 214 WaitNoBusy(cs); 215 stat = cs->BC_Read_Reg(cs, HFC_DATA, cip); 216 if (cs->debug & L1_DEB_HSCX) 217 debugl1(cs, "hfc_empty_fifo %d chksum %x stat %x", 218 bcs->channel, chksum, stat); 219 if (stat) { 220 debugl1(cs, "FIFO CRC error"); 221 dev_kfree_skb_any(skb); 222 skb = NULL; 223#ifdef ERROR_STATISTIC 224 bcs->err_crc++; 225#endif 226 } 227 WaitNoBusy(cs); 228 stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC | 229 HFC_CHANNEL(bcs->channel)); 230 WaitForBusy(cs); 231 } 232 } 233 return (skb); 234} 235 236static void 237hfc_fill_fifo(struct BCState *bcs) 238{ 239 struct IsdnCardState *cs = bcs->cs; 240 int idx, fcnt; 241 int count; 242 int z1, z2; 243 u_char cip; 244 245 if (!bcs->tx_skb) 246 return; 247 if (bcs->tx_skb->len <= 0) 248 return; 249 250 cip = HFC_CIP | HFC_F1 | HFC_SEND | HFC_CHANNEL(bcs->channel); 251 if ((cip & 0xc3) != (cs->hw.hfc.cip & 0xc3)) { 252 cs->BC_Write_Reg(cs, HFC_STATUS, cip, cip); 253 WaitForBusy(cs); 254 } 255 WaitNoBusy(cs); 256 if (bcs->mode != L1_MODE_TRANS) { 257 bcs->hw.hfc.f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip); 258 cip = HFC_CIP | HFC_F2 | HFC_SEND | HFC_CHANNEL(bcs->channel); 259 WaitNoBusy(cs); 260 bcs->hw.hfc.f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip); 261 bcs->hw.hfc.send[bcs->hw.hfc.f1] = ReadZReg(bcs, HFC_Z1 | HFC_SEND | HFC_CHANNEL(bcs->channel)); 262 if (cs->debug & L1_DEB_HSCX) 263 debugl1(cs, "hfc_fill_fifo %d f1(%d) f2(%d) z1(%x)", 264 bcs->channel, bcs->hw.hfc.f1, bcs->hw.hfc.f2, 265 bcs->hw.hfc.send[bcs->hw.hfc.f1]); 266 fcnt = bcs->hw.hfc.f1 - bcs->hw.hfc.f2; 267 if (fcnt < 0) 268 fcnt += 32; 269 if (fcnt > 30) { 270 if (cs->debug & L1_DEB_HSCX) 271 debugl1(cs, "hfc_fill_fifo more as 30 frames"); 272 return; 273 } 274 count = GetFreeFifoBytes(bcs); 275 } 276 else { 277 WaitForBusy(cs); 278 z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel)); 279 z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel)); 280 count = z1 - z2; 281 if (count < 0) 282 count += cs->hw.hfc.fifosize; 283 } /* L1_MODE_TRANS */ 284 if (cs->debug & L1_DEB_HSCX) 285 debugl1(cs, "hfc_fill_fifo %d count(%u/%d)", 286 bcs->channel, bcs->tx_skb->len, 287 count); 288 if (count < bcs->tx_skb->len) { 289 if (cs->debug & L1_DEB_HSCX) 290 debugl1(cs, "hfc_fill_fifo no fifo mem"); 291 return; 292 } 293 cip = HFC_CIP | HFC_FIFO_IN | HFC_SEND | HFC_CHANNEL(bcs->channel); 294 idx = 0; 295 while ((idx < bcs->tx_skb->len) && WaitNoBusy(cs)) 296 cs->BC_Write_Reg(cs, HFC_DATA_NODEB, cip, bcs->tx_skb->data[idx++]); 297 if (idx != bcs->tx_skb->len) { 298 debugl1(cs, "FIFO Send BUSY error"); 299 printk(KERN_WARNING "HFC S FIFO channel %d BUSY Error\n", bcs->channel); 300 } else { 301 count = bcs->tx_skb->len; 302 bcs->tx_cnt -= count; 303 if (PACKET_NOACK == bcs->tx_skb->pkt_type) 304 count = -1; 305 dev_kfree_skb_any(bcs->tx_skb); 306 bcs->tx_skb = NULL; 307 if (bcs->mode != L1_MODE_TRANS) { 308 WaitForBusy(cs); 309 WaitNoBusy(cs); 310 cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F1_INC | HFC_SEND | HFC_CHANNEL(bcs->channel)); 311 } 312 if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) && 313 (count >= 0)) { 314 u_long flags; 315 spin_lock_irqsave(&bcs->aclock, flags); 316 bcs->ackcnt += count; 317 spin_unlock_irqrestore(&bcs->aclock, flags); 318 schedule_event(bcs, B_ACKPENDING); 319 } 320 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 321 } 322 return; 323} 324 325void 326main_irq_hfc(struct BCState *bcs) 327{ 328 struct IsdnCardState *cs = bcs->cs; 329 int z1, z2, rcnt; 330 u_char f1, f2, cip; 331 int receive, transmit, count = 5; 332 struct sk_buff *skb; 333 334Begin: 335 count--; 336 cip = HFC_CIP | HFC_F1 | HFC_REC | HFC_CHANNEL(bcs->channel); 337 if ((cip & 0xc3) != (cs->hw.hfc.cip & 0xc3)) { 338 cs->BC_Write_Reg(cs, HFC_STATUS, cip, cip); 339 WaitForBusy(cs); 340 } 341 WaitNoBusy(cs); 342 receive = 0; 343 if (bcs->mode == L1_MODE_HDLC) { 344 f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip); 345 cip = HFC_CIP | HFC_F2 | HFC_REC | HFC_CHANNEL(bcs->channel); 346 WaitNoBusy(cs); 347 f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip); 348 if (f1 != f2) { 349 if (cs->debug & L1_DEB_HSCX) 350 debugl1(cs, "hfc rec %d f1(%d) f2(%d)", 351 bcs->channel, f1, f2); 352 receive = 1; 353 } 354 } 355 if (receive || (bcs->mode == L1_MODE_TRANS)) { 356 WaitForBusy(cs); 357 z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel)); 358 z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel)); 359 rcnt = z1 - z2; 360 if (rcnt < 0) 361 rcnt += cs->hw.hfc.fifosize; 362 if ((bcs->mode == L1_MODE_HDLC) || (rcnt)) { 363 rcnt++; 364 if (cs->debug & L1_DEB_HSCX) 365 debugl1(cs, "hfc rec %d z1(%x) z2(%x) cnt(%d)", 366 bcs->channel, z1, z2, rcnt); 367 /* sti(); */ 368 if ((skb = hfc_empty_fifo(bcs, rcnt))) { 369 skb_queue_tail(&bcs->rqueue, skb); 370 schedule_event(bcs, B_RCVBUFREADY); 371 } 372 } 373 receive = 1; 374 } 375 if (bcs->tx_skb) { 376 transmit = 1; 377 test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); 378 hfc_fill_fifo(bcs); 379 if (test_bit(BC_FLG_BUSY, &bcs->Flag)) 380 transmit = 0; 381 } else { 382 if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { 383 transmit = 1; 384 test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); 385 hfc_fill_fifo(bcs); 386 if (test_bit(BC_FLG_BUSY, &bcs->Flag)) 387 transmit = 0; 388 } else { 389 transmit = 0; 390 schedule_event(bcs, B_XMTBUFREADY); 391 } 392 } 393 if ((receive || transmit) && count) 394 goto Begin; 395 return; 396} 397 398static void 399mode_hfc(struct BCState *bcs, int mode, int bc) 400{ 401 struct IsdnCardState *cs = bcs->cs; 402 403 if (cs->debug & L1_DEB_HSCX) 404 debugl1(cs, "HFC 2BS0 mode %d bchan %d/%d", 405 mode, bc, bcs->channel); 406 bcs->mode = mode; 407 bcs->channel = bc; 408 409 switch (mode) { 410 case (L1_MODE_NULL): 411 if (bc) { 412 cs->hw.hfc.ctmt &= ~1; 413 cs->hw.hfc.isac_spcr &= ~0x03; 414 } 415 else { 416 cs->hw.hfc.ctmt &= ~2; 417 cs->hw.hfc.isac_spcr &= ~0x0c; 418 } 419 break; 420 case (L1_MODE_TRANS): 421 cs->hw.hfc.ctmt &= ~(1 << bc); /* set HDLC mode */ 422 cs->BC_Write_Reg(cs, HFC_STATUS, cs->hw.hfc.ctmt, cs->hw.hfc.ctmt); 423 hfc_clear_fifo(bcs); /* complete fifo clear */ 424 if (bc) { 425 cs->hw.hfc.ctmt |= 1; 426 cs->hw.hfc.isac_spcr &= ~0x03; 427 cs->hw.hfc.isac_spcr |= 0x02; 428 } else { 429 cs->hw.hfc.ctmt |= 2; 430 cs->hw.hfc.isac_spcr &= ~0x0c; 431 cs->hw.hfc.isac_spcr |= 0x08; 432 } 433 break; 434 case (L1_MODE_HDLC): 435 if (bc) { 436 cs->hw.hfc.ctmt &= ~1; 437 cs->hw.hfc.isac_spcr &= ~0x03; 438 cs->hw.hfc.isac_spcr |= 0x02; 439 } else { 440 cs->hw.hfc.ctmt &= ~2; 441 cs->hw.hfc.isac_spcr &= ~0x0c; 442 cs->hw.hfc.isac_spcr |= 0x08; 443 } 444 break; 445 } 446 cs->BC_Write_Reg(cs, HFC_STATUS, cs->hw.hfc.ctmt, cs->hw.hfc.ctmt); 447 cs->writeisac(cs, ISAC_SPCR, cs->hw.hfc.isac_spcr); 448 if (mode == L1_MODE_HDLC) 449 hfc_clear_fifo(bcs); 450} 451 452static void 453hfc_l2l1(struct PStack *st, int pr, void *arg) 454{ 455 struct BCState *bcs = st->l1.bcs; 456 struct sk_buff *skb = arg; 457 u_long flags; 458 459 switch (pr) { 460 case (PH_DATA | REQUEST): 461 spin_lock_irqsave(&bcs->cs->lock, flags); 462 if (bcs->tx_skb) { 463 skb_queue_tail(&bcs->squeue, skb); 464 } else { 465 bcs->tx_skb = skb; 466 test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); 467 bcs->cs->BC_Send_Data(bcs); 468 } 469 spin_unlock_irqrestore(&bcs->cs->lock, flags); 470 break; 471 case (PH_PULL | INDICATION): 472 spin_lock_irqsave(&bcs->cs->lock, flags); 473 if (bcs->tx_skb) { 474 printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n"); 475 } else { 476 test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); 477 bcs->tx_skb = skb; 478 bcs->cs->BC_Send_Data(bcs); 479 } 480 spin_unlock_irqrestore(&bcs->cs->lock, flags); 481 break; 482 case (PH_PULL | REQUEST): 483 if (!bcs->tx_skb) { 484 test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); 485 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); 486 } else 487 test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); 488 break; 489 case (PH_ACTIVATE | REQUEST): 490 spin_lock_irqsave(&bcs->cs->lock, flags); 491 test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag); 492 mode_hfc(bcs, st->l1.mode, st->l1.bc); 493 spin_unlock_irqrestore(&bcs->cs->lock, flags); 494 l1_msg_b(st, pr, arg); 495 break; 496 case (PH_DEACTIVATE | REQUEST): 497 l1_msg_b(st, pr, arg); 498 break; 499 case (PH_DEACTIVATE | CONFIRM): 500 spin_lock_irqsave(&bcs->cs->lock, flags); 501 test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag); 502 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 503 mode_hfc(bcs, 0, st->l1.bc); 504 spin_unlock_irqrestore(&bcs->cs->lock, flags); 505 st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL); 506 break; 507 } 508} 509 510 511static void 512close_hfcstate(struct BCState *bcs) 513{ 514 mode_hfc(bcs, 0, bcs->channel); 515 if (test_bit(BC_FLG_INIT, &bcs->Flag)) { 516 skb_queue_purge(&bcs->rqueue); 517 skb_queue_purge(&bcs->squeue); 518 if (bcs->tx_skb) { 519 dev_kfree_skb_any(bcs->tx_skb); 520 bcs->tx_skb = NULL; 521 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 522 } 523 } 524 test_and_clear_bit(BC_FLG_INIT, &bcs->Flag); 525} 526 527static int 528open_hfcstate(struct IsdnCardState *cs, struct BCState *bcs) 529{ 530 if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { 531 skb_queue_head_init(&bcs->rqueue); 532 skb_queue_head_init(&bcs->squeue); 533 } 534 bcs->tx_skb = NULL; 535 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 536 bcs->event = 0; 537 bcs->tx_cnt = 0; 538 return (0); 539} 540 541static int 542setstack_hfc(struct PStack *st, struct BCState *bcs) 543{ 544 bcs->channel = st->l1.bc; 545 if (open_hfcstate(st->l1.hardware, bcs)) 546 return (-1); 547 st->l1.bcs = bcs; 548 st->l2.l2l1 = hfc_l2l1; 549 setstack_manager(st); 550 bcs->st = st; 551 setstack_l1_B(st); 552 return (0); 553} 554 555static void 556init_send(struct BCState *bcs) 557{ 558 int i; 559 560 if (!(bcs->hw.hfc.send = kmalloc(32 * sizeof(unsigned int), GFP_ATOMIC))) { 561 printk(KERN_WARNING 562 "HiSax: No memory for hfc.send\n"); 563 return; 564 } 565 for (i = 0; i < 32; i++) 566 bcs->hw.hfc.send[i] = 0x1fff; 567} 568 569void 570inithfc(struct IsdnCardState *cs) 571{ 572 init_send(&cs->bcs[0]); 573 init_send(&cs->bcs[1]); 574 cs->BC_Send_Data = &hfc_fill_fifo; 575 cs->bcs[0].BC_SetStack = setstack_hfc; 576 cs->bcs[1].BC_SetStack = setstack_hfc; 577 cs->bcs[0].BC_Close = close_hfcstate; 578 cs->bcs[1].BC_Close = close_hfcstate; 579 mode_hfc(cs->bcs, 0, 0); 580 mode_hfc(cs->bcs + 1, 0, 0); 581} 582 583void 584releasehfc(struct IsdnCardState *cs) 585{ 586 kfree(cs->bcs[0].hw.hfc.send); 587 cs->bcs[0].hw.hfc.send = NULL; 588 kfree(cs->bcs[1].hw.hfc.send); 589 cs->bcs[1].hw.hfc.send = NULL; 590} 591