i4b(4): Reorder includes slightly to silence some compilation warnings.
[dragonfly.git] / sys / net / i4b / layer1 / ihfc / i4b_ihfc_drv.c
CommitLineData
984263bc
MD
1/*
2 * Copyright (c) 2000 Hans Petter Selasky. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 *
25 *---------------------------------------------------------------------------
26 *
27 * i4b_ihfc_drv.c - ihfc ISA PnP-bus interface
28 * -------------------------------------------
29 *
30 * Everything which has got anything to do with the
31 * HFC-1/S/SP chips has been put here.
32 *
33 * last edit-date: [Fri Jan 12 17:06:52 2001]
34 *
35 * $FreeBSD: src/sys/i4b/layer1/ihfc/i4b_ihfc_drv.c,v 1.9.2.1 2001/08/10 14:08:37 obrien Exp $
4b1cf444 36 * $DragonFly: src/sys/net/i4b/layer1/ihfc/i4b_ihfc_drv.c,v 1.9 2006/12/22 23:44:56 swildner Exp $
984263bc
MD
37 *
38 *---------------------------------------------------------------------------*/
39
1f2de5d4 40#include "use_ihfc.h"
984263bc
MD
41
42#if (NIHFC > 0)
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/socket.h>
984263bc 47#include <sys/mbuf.h>
1f7ab7c9
MD
48#include <sys/bus.h>
49#include <sys/rman.h>
50#include <sys/thread2.h>
984263bc 51
1f7ab7c9 52#include <net/if.h>
1f2de5d4
MD
53#include <net/i4b/include/machine/i4b_debug.h>
54#include <net/i4b/include/machine/i4b_ioctl.h>
55#include <net/i4b/include/machine/i4b_trace.h>
984263bc 56
d42db02e
SW
57#include "../../include/i4b_mbuf.h"
58
1f2de5d4
MD
59#include "../i4b_l1.h"
60#include "../i4b_hdlc.h"
61#include "i4b_ihfc.h"
62#include "i4b_ihfc_ext.h"
63#include "i4b_ihfc_drv.h"
984263bc 64
984263bc
MD
65/*---------------------------------------------------------------------------*
66 * Local prototypes
67 *---------------------------------------------------------------------------*/
68 void ihfc_loadconfig (ihfc_sc_t *sc);
69
70static void ihfc_trans_Bread (ihfc_sc_t *sc, u_char chan);
71static void ihfc_trans_Bwrite (ihfc_sc_t *sc, u_char chan);
72static void ihfc_hdlc_Bread (ihfc_sc_t *sc, u_char chan);
73static void ihfc_hdlc_Bwrite (ihfc_sc_t *sc, u_char chan);
74static void ihfc_hdlc_Dread (ihfc_sc_t *sc, u_char chan);
75static void ihfc_hdlc_Dwrite (ihfc_sc_t *sc, u_char chan);
76
77static void ihfc_isac_Dread (ihfc_sc_t *sc, u_char chan);
78static void ihfc_isac_Dwrite (ihfc_sc_t *sc, u_char chan);
79
80 void ihfc_cmdr_hdlr (ihfc_sc_t *sc, u_char cmdr);
81 void ihfc_exir_hdlr (ihfc_sc_t *sc, u_char exir);
82
83 void ihfc_sq (ihfc_sc_t *sc);
84
85static void ihfc_test_Bread (ihfc_sc_t *sc, u_char chan);
86static void ihfc_test_Bwrite (ihfc_sc_t *sc, u_char chan);
87
88u_short ihfc_Bsel_fifo (ihfc_sc_t *sc, u_char chan, u_char flag);
89u_int32_t ihfc_Dsel_fifo (ihfc_sc_t *sc, u_char chan, u_char flag);
90
91
92/*---------------------------------------------------------------------------*
93 * Commonly used ISA bus commands
94 *---------------------------------------------------------------------------*/
95#define IHFC_DATA_OFFSET 0
96#define IHFC_REG_OFFSET 1
97
98#define BUS_VAR bus_space_handle_t h = rman_get_bushandle(S_IOBASE[0]); \
99 bus_space_tag_t t = rman_get_bustag (S_IOBASE[0])
100
101#define SET_REG(reg) bus_space_write_1(t,h, IHFC_REG_OFFSET, reg)
102#define GET_STAT bus_space_read_1 (t,h, IHFC_REG_OFFSET)
103
104#define READ_DATA_1 bus_space_read_1 (t,h, IHFC_DATA_OFFSET)
105#define READ_BOTH_2 bus_space_read_2 (t,h, IHFC_DATA_OFFSET)
106
107#define WRITE_DATA_1(data) bus_space_write_1(t,h, IHFC_DATA_OFFSET, data)
108#define WRITE_BOTH_2(data) bus_space_write_2(t,h, IHFC_DATA_OFFSET, data)
109
110#define DISBUSY(okcmd, tocmd) \
111{ \
112 if (GET_STAT & 1) \
113 { \
94332c29
RG
114 u_char a; \
115 u_int to = IHFC_DISBUSYTO; \
984263bc
MD
116 \
117 while(((a = GET_STAT) & 1) && --to); \
118 \
119 if (!to) \
120 { \
121 NDBGL1(L1_ERROR, "DISBUSY-TIMEOUT! (a=%04x, " \
122 "unit=%d)", a, S_UNIT); \
123 tocmd; \
124 } \
125 else \
126 { \
127 okcmd; \
128 } \
129 } \
130 else \
131 { \
132 okcmd; \
133 } \
134}
135
136#define WAITBUSY_2(okcmd, tocmd) \
137 { \
94332c29
RG
138 u_short a; \
139 u_int to = IHFC_NONBUSYTO; \
984263bc
MD
140 \
141 while((~(a = READ_BOTH_2) & 0x100) && --to); \
142 \
143 if (!to) \
144 { \
145 NDBGL1(L1_ERROR, "NONBUSY-TIMEOUT! (a=%04x, " \
146 "unit=%d)", a, S_UNIT); \
147 tocmd; \
148 } \
149 else \
150 { \
151 okcmd; \
152 } \
153 }
154
155/*---------------------------------------------------------------------------*
156 * Control function (HFC-1/S/SP)
157 *
158 * Flag:
159 * 1: reset and unlock chip (at boot only)
160 * 2: prepare for shutdown (at shutdown only)
161 * 3: reset and resume
162 * 4: select TE-mode (boot default)
163 * 5: select NT-mode (only HFC-S/SP/PCI)
164 *
165 * Returns != 0 on errornous chip
166 *---------------------------------------------------------------------------*/
167int
168ihfc_control(ihfc_sc_t *sc, int flag)
169{
170 BUS_VAR;
171
172 if (flag == 3) goto reset0;
173 if (flag == 4)
174 {
175 S_NTMODE = 0;
176 goto mode0;
177 }
178 if (flag == 5)
179 {
180 S_NTMODE = 1;
181 goto mode0;
182 }
183 if (flag == 1)
184 {
185 WRITE_BOTH_2(0x5400 | S_IIO); /* enable IO (HFC-1/S) */
186
187 S_LAST_CHAN = -1;
188
189 /* HFC-S/SP configuration */
190
191 S_CIRM = S_IIRQ|0x10; /* IRQ, 8K fifo mode */
192 S_CLKDEL = 0x00; /* 12.288mhz */
193 S_CTMT = 0x03; /* transperant mode */
194 S_CONNECT = 0x00; /* B channel data flow */
195 S_INT_M1 = 0x40; /* interrupt mask */
196 S_INT_M2 = 0x08; /* enable interrupt output */
197 S_MST_MODE = 0x01; /* master mode */
198 S_SCTRL = 0x50; /* S/Q on, non cap. line mode */
199 S_SCTRL_R = 0x00; /* B channel receive disable */
200 S_TEST = 0x00; /* no need for awake enable */
201
202 if (S_HFC & (HFC_1 | HFC_S)) /* configure timer (50ms) */
203 {
204 S_CTMT |= 0x08;
205 }
206 else
207 {
208 S_CTMT |= 0x14;
209 }
210
211 /* HFC-1 ISAC configuration (IOM-2 mode) */
212
213 S_ADF1 = 0x00; /* */
214 S_ADF2 = 0x80; /* select mode IOM-2 */
215 S_SPCR = 0x00; /* B channel send disable (0x10 for test loop) */
216 S_MASK = 0xfb; /* enable CISQ */
217 S_MODE = 0xc9; /* receiver enabled */
218 S_SQXR = 0x0f; /* master, clock always active */
219 S_STCR = 0x70; /* TIC bus address = 7 */
220 S_STAR2 = 0x04; /* enable S/Q */
221
222 mode0:
223 if (S_NTMODE) /* configure NT- or TE-mode */
224 {
225 S_SCTRL |= 0x04; /* NT mode */
226 S_CLKDEL &= ~0x7f; /* clear delay */
227 S_CLKDEL |= 0x6c; /* set delay */
228 }
229 else
230 {
231 S_SCTRL &= ~0x04; /* TE mode */
232 S_STDEL &= 0x7f; /* use mask! */
233 S_CLKDEL &= ~0x7f; /* clear delay */
234 S_CLKDEL |= S_STDEL; /* set delay */
235 }
236 if (S_DLP) /* configure D-priority */
237 {
238 S_SCTRL |= 0x08; /* (10/11) */
239 }
240 else
241 {
242 S_SCTRL &= ~0x08; /* (8/9) */
243 }
244
245 reset0:
246 /* chip reset (HFC-1/S/SP) */
247
248 if (S_HFC & HFC_1)
249 {
250 SET_REG((S_CIRM | 0xc8) & 0xdf);
251
252 DELAY(10); /* HFC-2B manual recommends a 4 *
253 * clock cycle delay after CIRM *
254 * write with reset=1. A 1us *
255 * delay, should do for 7.68mhz,*
256 * but just in case I make that *
257 * 10us. */
258
259 SET_REG((S_CIRM | 0xc0) & 0xdf);
260
261 DELAY(250); /* ISAC manual says reset pulse *
262 * length is 125us. Accessing *
263 * ISAC before those 125us, we *
264 * may risk chip corruption and *
265 * irq failure. The HFC-2B also *
266 * needs some delay to recover, *
267 * so we add some us. */
268 }
269 else
270 {
271 SET_REG(0x18);
272
273 WRITE_DATA_1(S_CIRM | 8);
274
275 DELAY(10); /* HFC-2BDS0 manual recommends *
276 * a 4 clock cycle delay after *
277 * CIRM write with reset=1. *
278 * A 1us delay, should do for *
279 * 12.288mhz, but just in case *
280 * I make that 10us. */
281
282 WRITE_DATA_1(S_CIRM);
283
284 DELAY(25); /* HFC-2BDS0 needs some time to *
285 * recover after CIRM write *
286 * with reset=0. Experiments *
287 * show this delay should be *
288 * 8-9us. Just in case we make *
289 * that 25us. */
290 }
291
292 {
293 /* HFC-1/S/SP chip test *
294 * *
295 * NOTE: after reset the HFC-1/S/SP should be *
296 * in a mode where it is always non-busy/non- *
297 * processing, and bit[0] of STATUS/DISBUSY *
298 * register, should always return binary '0' *
299 * until we configure the chips for normal *
300 * operation. */
301#ifdef IHFC_DEBUG
4b1cf444 302 kprintf("ihfc: GET_STAT value is: 0x%x\n", GET_STAT);
984263bc
MD
303#endif
304 SET_REG(0x30);
305
306 if ((GET_STAT & 1) || (READ_DATA_1 & 0xf)) goto f0;
307 }
308
309 ihfc_loadconfig(sc);
310
311 if (S_HFC & HFC_1) ihfc_cmdr_hdlr(sc, 0x41); /* rres, xres */
312
313 S_PHSTATE = 0;
314 HFC_FSM(sc, 0);
315 }
316
317 if (flag == 2)
318 {
319 if (S_HFC & HFC_1) S_CIRM &= ~0x03; /* disable interrupt */
320
321 S_SQXR |= 0x40; /* power down */
322
323 S_INT_M2 &= ~0x01;
324 S_MASK |= 0x02;
325
326 S_SPCR &= ~0x0f; /* send 1's only */
327 S_SCTRL &= ~0x83; /* send 1's only + enable oscillator */
328
329 ihfc_loadconfig(sc);
330 }
331
332 return(0); /* success */
333
334 f0:
335 return(1); /* failure */
336}
337
338/*---------------------------------------------------------------------------*
339 * Softc initializer and hardware setup (HFC-1/S/SP)
340 *
341 * Returns: 0 on success
342 * 1 on failure
343 *---------------------------------------------------------------------------*/
344int
345ihfc_init (ihfc_sc_t *sc, u_char chan, int prot, int activate)
346{
347 if (chan > 5) goto f0;
348
349 chan &= ~1;
350
351 do
352 { if (chan < 2) /* D-Channel */
353 {
354 i4b_Dfreembuf(S_MBUF);
355 if (!IF_QEMPTY(&S_IFQUEUE)) i4b_Dcleanifq(&S_IFQUEUE);
356
357 RESET_SOFT_CHAN(sc, chan);
358
359 S_IFQUEUE.ifq_maxlen = IFQ_MAXLEN;
360
984263bc
MD
361 if (!activate) continue;
362
363 if (S_HFC & HFC_1)
364 {
365 S_FILTER = (chan & 1) ? ihfc_isac_Dread :
366 ihfc_isac_Dwrite;
367 }
368 else
369 {
370 S_FILTER = (chan & 1) ? ihfc_hdlc_Dread :
371 ihfc_hdlc_Dwrite;
372 }
373 }
374 else /* B-Channel */
375 {
376 i4b_Bfreembuf(S_MBUF);
377 if (!IF_QEMPTY(&S_IFQUEUE)) i4b_Bcleanifq(&S_IFQUEUE);
378
379 RESET_SOFT_CHAN(sc, chan);
380
381 S_IFQUEUE.ifq_maxlen = IFQ_MAXLEN;
382
984263bc
MD
383 S_PROT = prot;
384
385 if (!activate) continue;
386
387 switch(prot)
388 { case(BPROT_NONE):
389 S_FILTER = (chan & 1) ?
390 ihfc_trans_Bread :
391 ihfc_trans_Bwrite;
392 break;
393 case(BPROT_RHDLC):
394 S_FILTER = (chan & 1) ?
395 ihfc_hdlc_Bread :
396 ihfc_hdlc_Bwrite;
397 break;
398 case(5):
399 S_FILTER = (chan & 1) ?
400 ihfc_test_Bread :
401 ihfc_test_Bwrite;
402 break;
403 }
404 }
405 } while (++chan & 1);
406
407 S_MASK |= 0xfb; /* disable all, but CISQ interrupt (ISAC) */
408 S_INT_M1 &= 0x40; /* disable all, but TE/NT state machine (HFC) */
409 S_SCTRL &= ~0x03; /* B1/B2 send disable (HFC) */
410 S_SPCR &= ~0x0f; /* B1/B2 send disable (ISAC) */
411 S_SCTRL_R &= ~0x03; /* B1/B2 receive disable (HFC) */
412
413 chan = 0;
414 if (S_FILTER) /* D-Channel active */
415 {
416 S_MASK &= 0x2e; /* enable RME, RPF, XPR, EXI */
417 S_INT_M1 |= 0x24; /* enable D-receive, D-transmit */
418 }
419
420 chan = 2;
421 if (S_FILTER) /* B1-Channel active */
422 {
423 S_SCTRL |= 1; /* send enable (HFC) */
424 S_SPCR |= 8; /* send enable (ISAC) */
425 S_SCTRL_R |= 1; /* receive enable (HFC) */
426 S_INT_M1 |= 0x80; /* timer enable (HFC) */
427 S_INT_M1 &= ~0x04; /* let D-channel use timer too */
428 }
429
430 chan = 4;
431 if (S_FILTER) /* B2-Channel active */
432 {
433 S_SCTRL |= 2; /* send enable (HFC) */
434 S_SPCR |= 2; /* send enable (ISAC) */
435 S_SCTRL_R |= 2; /* receive enable (HFC) */
436 S_INT_M1 |= 0x80; /* timer enable (HFC) */
437 S_INT_M1 &= ~0x04; /* let D-channel use timer too */
438 }
439
440 ihfc_loadconfig(sc);
441
442 /* XXX reset timer? */
443
444 return 0; /* success */
445 f0:
446 return 1; /* failure */
447}
448
449/*---------------------------------------------------------------------------*
450 * Load configuration data (HFC-1/S/SP)
451 *---------------------------------------------------------------------------*/
452void
453ihfc_loadconfig(ihfc_sc_t *sc)
454{
455 BUS_VAR;
456
457 if (S_HFC & HFC_1)
458 {
459 /* HFC-1 chips w/ISAC: */
460
461 const u_char *src = (void *)&S_ISAC_CONFIG;
462 const u_char *dst = (void *)&isac_configtable;
463
464 SET_REG((S_CIRM | 0xc0) & 0xdf);
465
466 S_CTMT = (S_CTMT & ~0x14) | ((S_INT_M1 >> 5) & 0x4);
467
468 SET_REG((S_CTMT | 0xe0) & 0xff);
469
470 while(*dst)
471 {
472 SET_REG(*dst++); /* set register */
473
474 /* write configuration */
475 DISBUSY(WRITE_DATA_1(*src++), break);
476 }
477 }
478 else
479 {
480 /* HFC-S/SP chips: */
481
482 const u_char *src = (void *)&S_HFC_CONFIG;
483 const u_char *dst = (void *)&ihfc_configtable;
484
485 while(*dst)
486 {
487 SET_REG(*dst++); /* set register */
488 WRITE_DATA_1(*src++); /* write configuration */
489 }
490 }
491}
492
493/*---------------------------------------------------------------------------*
494 * Function State Machine handler (PH layer) (HFC-1/S/SP)
495 *
496 * Flag: 0 = Refresh softc S_PHSTATE + take hints
497 * 1 = Activate
498 * 2 = Deactivate
499 *
500 * NOTE: HFC-1 only supports TE mode.
501 *---------------------------------------------------------------------------*/
502void
503ihfc_fsm(ihfc_sc_t *sc, int flag)
504{
505 const struct ihfc_FSMtable *fsmtab;
506 u_char ihfc_cmd = 0;
507 u_char isac_cmd = 0;
508 u_char tmp;
509 BUS_VAR;
510
511 /* get current state (rx/downstream) */
512
513 if (S_HFC & HFC_1)
514 {
515 SET_REG(0x31); DISBUSY(tmp = (READ_DATA_1 >> 2) & 0xf, return);
516
517 fsmtab = (S_NTMODE) ? &ihfc_TEtable2[tmp]:
518 &ihfc_TEtable2[tmp];
519 }
520 else
521 {
522 SET_REG(0x30); tmp = READ_DATA_1 & 0xf;
523
524 fsmtab = (S_NTMODE) ? &ihfc_NTtable[tmp]:
525 &ihfc_TEtable[tmp];
526 }
527
528 if (fsmtab->string)
529 {
530 NDBGL1(L1_I_CICO, "%s (ind=0x%x, flag=%d, unit=%d).",
531 fsmtab->string, tmp, flag, S_UNIT);
532 }
533 else
534 {
535 NDBGL1(L1_I_ERR, "Illegal indicatation (ind=0x%x, "
536 "flag=%d, unit=%d).", tmp, flag, S_UNIT);
537 }
538
539 /* indication machine / state change *
540 * *
541 * Whenever the state of the S0-line changes, we check to see in which *
542 * direction the change went. Generally upwards means activate, and *
543 * downwards means deactivate. *
544 * The test signal is used to ensure proper syncronization. */
545
546 if (fsmtab->state == 0) /* deactivated indication */
547 {
548 if (S_PHSTATE != 0)
549 {
550 isac_cmd = 0x3c; /* deactivate DUI */
551
552 i4b_l1_ph_deactivate_ind(S_I4BUNIT);
553 }
554 }
555 if (fsmtab->state == 2) /* syncronized indication */
556 {
557 if (S_PHSTATE != 2)
558 {
559 if (S_NTMODE) ihfc_cmd = 0x80;
560 }
561 }
562 if (fsmtab->state == 3) /* activated indication */
563 {
564 if (S_PHSTATE != 3)
565 {
566 isac_cmd = (S_DLP) ? 0x24 /* activate AR10 */
567 : 0x20; /* activate AR8 */
568
569 i4b_l1_ph_activate_ind(S_I4BUNIT);
570 }
571 }
572 if (fsmtab->state == 4) /* error indication */
573 {
574 if (S_PHSTATE < 4)
575 {
576 isac_cmd = 0x3c; /* deactivate DUI */
577 }
578 }
579
580 S_PHSTATE = fsmtab->state;
581
582 if ((flag == 1) && (fsmtab->state != 3))
583 {
584 isac_cmd = (S_DLP) ? 0x24 : 0x20;
585 ihfc_cmd = 0x60;
586 }
587 if ((flag == 2) && (fsmtab->state != 0))
588 {
589 isac_cmd = 0x3c;
590 ihfc_cmd = 0x40;
591 }
592
593 /* set new state (tx / upstream) *
594 * *
595 * NOTE: HFC-S/SP and ISAC transmitters are always active when *
596 * activated state is reached. The bytes sent to the S0-bus are all *
597 * high impedance, so they do not disturb. *
598 * The HFC-1 has a separate SIEMENS S0-device. */
599
600 if (S_HFC & HFC_1)
601 {
602 if (isac_cmd)
603 {
604 if (S_IOM2) isac_cmd |= 3;
605
606 SET_REG(0x31); DISBUSY(WRITE_DATA_1(isac_cmd), );
607
608 NDBGL1(L1_I_CICO, "(isac_cmd=0x%x, unit=%d).",
609 isac_cmd, S_UNIT);
610 }
611 }
612 else
613 {
614 if (ihfc_cmd || (fsmtab->state == 5))
615 {
616 SET_REG(0x30); WRITE_DATA_1(ihfc_cmd);
617
618 NDBGL1(L1_I_CICO, "(ihfc_cmd=0x%x, unit=%d).",
619 ihfc_cmd, S_UNIT);
620 }
621 }
622}
623
624/*---------------------------------------------------------------------------*
625 * S/Q - channel handler (read) (HFC-S/SP)
626 *---------------------------------------------------------------------------*/
627void
628ihfc_sq (ihfc_sc_t *sc)
629{
630 const struct ihfc_SQtable *SQtab;
94332c29 631 u_char a = 0;
984263bc
MD
632 BUS_VAR;
633
634 if (S_HFC & HFC_1)
635 {
636 SET_REG(0x31);
637 DISBUSY(a = READ_DATA_1, a = 0);
638
639 if (a & 0x80)
640 {
641 SET_REG(0x3b);
642 DISBUSY(a = READ_DATA_1, a = 0);
643 }
644 }
645 else
646 {
647 SET_REG(0x34);
648 a = READ_DATA_1;
649 }
650
651 SQtab = (S_NTMODE) ? &ihfc_Qtable[a & 7]:
652 &ihfc_Stable[a & 7];
653
654 if (a & 0x10)
655 {
656 if (SQtab->string)
657 {
658 NDBGL1(L1_I_CICO, "%s (unit=%d, int=%x)",
659 SQtab->string, S_UNIT, S_INT_S1);
660 }
661 else
662 {
663 NDBGL1(L1_ERROR, "Unknown indication = %x (unit=%d)",
664 a & 7, S_UNIT);
665 }
666 }
667}
668
669/*---------------------------------------------------------------------------*
670 * Interrupt handler (HFC-1)
671 *---------------------------------------------------------------------------*/
672void
673ihfc_intr1 (ihfc_sc_t *sc)
674{
675 u_char chan;
676 u_char tmp;
677 BUS_VAR;
678 HFC_VAR;
679
680 HFC_BEG;
681
682 SET_REG(0x20); tmp = GET_STAT; DISBUSY(S_ISTA |= READ_DATA_1, );
683
684 if (S_ISTA & 0x04) /* CIRQ */
685 {
686 HFC_FSM(sc, 0);
687
688 ihfc_sq(sc);
689 }
690
691 S_INTR_ACTIVE = 1;
692
693 if (S_ISTA & 0xc0) /* RPF or RME */
694 {
695 chan = 1;
696 if (S_FILTER) S_FILTER(sc, chan);
697 }
698 if (S_ISTA & 0x10) /* XPR */
699 {
700 chan = 0;
701 if (S_FILTER) S_FILTER(sc, chan);
702 }
703 if (tmp & 0x04) /* Timer elapsed (50ms) */
704 {
705 SET_REG((S_CTMT | 0xf0) & 0xff);
706
707 chan = 6;
708 while(chan--)
709 {
710 if (chan == 1) break;
711 if (S_FILTER) S_FILTER(sc, chan);
712
713 HFC_END;
714 DELAY(10);
715 HFC_BEG;
716 }
717 }
718
719 S_INTR_ACTIVE = 0;
720
721 if (S_ISTA & 0x01) /* EXIR */
722 {
723 SET_REG(0x24); DISBUSY(ihfc_exir_hdlr(sc, READ_DATA_1), );
724 }
725
726 S_ISTA &= ~(0x1 | 0x4);
727
728 HFC_END;
729}
730
731/*---------------------------------------------------------------------------*
732 * Interrupt handler (HFC-S/SP)
733 *---------------------------------------------------------------------------*/
734void
735ihfc_intr2 (ihfc_sc_t *sc)
736{
737 u_char chan;
738 BUS_VAR;
739 HFC_VAR;
740
741 HFC_BEG;
742
743 SET_REG(0x1e); S_INT_S1 = READ_DATA_1; /* this will enable new interrupts! */
744
745 if (S_INT_S1 & 0x40)
746 {
747 HFC_FSM(sc, 0); /* statemachine changed */
748
749 ihfc_sq(sc);
750 }
751
752 S_INTR_ACTIVE = 1;
753
754 if (S_INT_S1 & 0x20) /* D-Channel frame (rx) */
755 {
756 chan = 1;
757 if (S_FILTER) S_FILTER(sc, chan);
758 }
759 if (S_INT_S1 & 0x04) /* D-Channel frame (tx) */
760 {
761 chan = 0;
762 if (S_FILTER && (~S_INT_S1 & 0x80)) S_FILTER(sc, chan);
763 }
764 if (S_INT_S1 & 0x80) /* Timer elapsed (50ms) */
765 {
766 chan = 6;
767 while(chan--)
768 {
769 if (chan == 1) continue;
770 if (S_FILTER) S_FILTER(sc, chan);
771
772 HFC_END;
773 DELAY(10);
774 HFC_BEG;
775 }
776 }
777
778 S_INTR_ACTIVE = 0;
779
780 HFC_END;
781}
782
783/*---------------------------------------------------------------------------*
784 * Select a Bfifo (HFC-1/S/SP)
785 * and return bytes in FIFO
786 *
787 * (this code is optimized)
788 *---------------------------------------------------------------------------*/
789u_short
790ihfc_Bsel_fifo(ihfc_sc_t *sc, u_char chan, u_char flag)
791{
94332c29
RG
792 u_char reg = 0x7e + chan;
793 u_short tmp = 0x100;
794 u_short z1;
795 u_short z2;
984263bc
MD
796
797 BUS_VAR;
798
799 if (S_HFC & (HFC_1 | HFC_S))
800 {
801 if (S_LAST_CHAN != chan)
802 {
803 SET_REG(reg);
804 DISBUSY(WAITBUSY_2( , return 0), return 0);
805
806 S_LAST_CHAN = chan;
807 }
808 }
809 else
810 {
811 SET_REG(0x10);
812 WRITE_DATA_1(chan - 2);
813 DISBUSY( , return 0);
814 }
815
816#define FAST_READ (u_char)(tmp = READ_BOTH_2)
817#define FAST_STAT if (tmp & 0x100) DISBUSY( , return 0);
818
819 SET_REG(reg ); FAST_STAT; z1 = FAST_READ;
820 SET_REG(reg += 4); FAST_STAT; z1 |= FAST_READ << 8;
821 SET_REG(reg += 4); FAST_STAT; z2 = FAST_READ;
822 SET_REG(reg += 4); FAST_STAT; z2 |= READ_DATA_1 << 8;
823
824#undef FAST_READ
825#undef FAST_STAT
826
827 z1 &= 0x1fff;
828 z2 &= 0x1fff;
829
830 z1 = 0x5ff - (z2 = z1 - z2 + ((z2 <= z1) ? 0 : 0x600));
831
832 if (chan & 1)
833 return(z2); /* receive channel */
834 else
835 return(z1); /* transmit channel */
836}
837
838/*---------------------------------------------------------------------------*
839 * Select a Dfifo (HFC-S/SP)
840 * and return bytes, and frames in FIFO
841 *
842 * Flag values:
843 * 0x00: select new fifo + update counters
844 * 0x10: increment f1 + update counters
845 * 0x20: increment f2 + update counters
846 *
847 * NOTE: The upper 16bits holds the number of frames in the FIFO.
848 * NOTE: FIFO has to be selected before you can use flags 0x10/0x20.
849 *---------------------------------------------------------------------------*/
850u_int32_t
851ihfc_Dsel_fifo(ihfc_sc_t *sc, u_char chan, u_char flag)
852{
94332c29
RG
853 u_char reg = 0x90 + chan;
854 u_short tmp = 0x100;
855 u_char f1;
856 u_char f2;
857 u_short z1;
858 u_short z2;
984263bc
MD
859
860 BUS_VAR;
861
862 if (S_HFC & (HFC_1 | HFC_S))
863 {
864 switch(flag)
865 {
866 case(0x10):
867 case(0x20):
868 SET_REG(reg);
869 if (~GET_STAT & 1)
870 WAITBUSY_2( , return 0);
871
872 SET_REG(0xa2 - (flag & 0x10) + chan);
873 DISBUSY(READ_DATA_1, return 0);
874
875 SET_REG(reg);
876 if (~GET_STAT & 1)
877 WAITBUSY_2( , return 0);
878 break;
879
880 default:
881 if (S_LAST_CHAN != chan)
882 {
883 SET_REG(reg);
884 DISBUSY(WAITBUSY_2( , return 0), return 0);
885
886 S_LAST_CHAN = chan;
887 }
888 break;
889 }
890 }
891 else
892 {
893 switch(flag)
894 {
895 case(0x10):
896 case(0x20):
897 SET_REG(0xb8 - (flag & 0x10) + chan);
898 READ_DATA_1;
899
900 DISBUSY( , return 0);
901
902 if (chan & 1)
903 {
904 /* Before reading a FIFO a change *
905 * FIFO operation must be done. *
906 * (see HFC-SP manual p.38) */
907
908 SET_REG(0x10);
909 WRITE_DATA_1(chan | 4);
910
911 DISBUSY( , return 0);
912 }
913 break;
914
915 default:
916 SET_REG(0x10);
917 WRITE_DATA_1(chan | 4);
918
919 DISBUSY( , return 0);
920 break;
921 }
922 }
923
924#define FAST_READ (u_char)(tmp = READ_BOTH_2)
925#define FAST_STAT if (tmp & 0x100) DISBUSY( , return 0);
926
927 if (S_HFC & HFC_SP) reg = 0x80 + chan;
928
929 SET_REG(reg ); FAST_STAT; z1 = FAST_READ;
930 SET_REG(reg += 4); FAST_STAT; z1 |= FAST_READ << 8;
931 SET_REG(reg += 4); FAST_STAT; z2 = FAST_READ;
932 SET_REG(reg += 4); FAST_STAT; z2 |= FAST_READ << 8;
933
934 if (S_HFC & HFC_SP) reg += 0x26;
935
936 SET_REG(reg -= 2); FAST_STAT; f1 = FAST_READ;
937 SET_REG(reg += 4); FAST_STAT; f2 = READ_DATA_1;
938
939#undef FAST_READ
940#undef FAST_STAT
941
942 if (~chan & 1)
943 { /* XXX was Z1 */
944 S_HDLC_DZ_TAB[f1 & 0xf] = z2; /* We keep track of the 'Z' *
945 * values for D-channel (tx),*
946 * so we may calculate the # *
947 * of FIFO bytes free when *
948 * f1 != f2. */
949 z2 = S_HDLC_DZ_TAB[f2 & 0xf];
950 }
951
952 z1 = 0x1ff - (z2 = (z1 - z2) & 0x1ff);
953 f1 = 0xf - (f2 = (f1 - f2) & 0xf);
954
955 if (chan & 1)
956 return(z2 | (f2 << 16)); /* receive channel */
957 else
958 return(z1 | (f1 << 16)); /* transmit channel */
959}
960
961
962/*---------------------------------------------------------------------------*
963 * Data handler for D channel(write) - chan 0 (HFC-S/SP)
964 *---------------------------------------------------------------------------*/
965void
966ihfc_hdlc_Dwrite (ihfc_sc_t *sc, u_char chan)
967{
94332c29
RG
968 u_int32_t sendlen;
969 u_short len;
970 u_char * src;
984263bc
MD
971
972 BUS_VAR;
973
974 if (!S_MBUF && IF_QEMPTY(&S_IFQUEUE)) return;
975
976 sendlen = ihfc_Dsel_fifo(sc, chan, 0); /* select new fifo *
977 * NOTE: the 16 higher bits *
978 * contain the # of frame- *
979 * etries free in the FIFO */
980 while (sendlen & ~0xffff)
981 {
982 if (!S_MBUF)
983 {
984 if (!(S_MBUF = ihfc_getmbuf(sc, chan))) goto j1;
985 }
986
987 src = S_MBUFDATA;
988 len = S_MBUFLEN;
989
990 if (len >= 0x1ff) goto j0; /* frame is too big: skip! */
991
992 sendlen &= 0xffff; /* only keep # of *
993 * bytes free */
994
995 SET_REG((S_HFC & HFC_SP) ? 0xac : 0x96);
996
997 while (sendlen--)
998 {
999 if (!len--) break;
1000
1001 DISBUSY(WRITE_DATA_1(*src++), sendlen = -1; len++; break);
1002 }
1003
1004 if (!++sendlen) /* out of fifo: suspend */
1005 {
1006 S_MBUFDATA = src;
1007 S_MBUFLEN = len;
1008 break;
1009 }
1010
1011 sendlen = ihfc_Dsel_fifo(sc, chan, 0x10); /* inc F1 */
1012 j0:
1013 i4b_Dfreembuf(S_MBUF);
1014 S_MBUF = NULL;
1015 }
1016 j1:
5b73dc76 1017 ;
984263bc
MD
1018}
1019
1020/*---------------------------------------------------------------------------*
1021 * Data handler for D channel(read) - chan 1 (HFC-S/SP)
1022 *
1023 * NOTE: Max framelength is (511 - 3) = 508 bytes, when only one frame
1024 * is received at a time.
1025 *---------------------------------------------------------------------------*/
1026void
1027ihfc_hdlc_Dread (ihfc_sc_t *sc, u_char chan)
1028{
94332c29
RG
1029 u_char tmp = -1;
1030 u_char to = 15;
1031 u_int32_t reclen;
1032 u_short crc;
1033 u_short len;
1034 u_char * dst;
984263bc
MD
1035
1036 BUS_VAR;
1037
1038 reclen = ihfc_Dsel_fifo(sc, chan, 0); /* select new fifo *
1039 * NOTE: the higher 16 bits *
1040 * contain the # of frames *
1041 * to receive. */
1042 while ((reclen & ~0xffff) && to--)
1043 {
1044 reclen &= 0xffff; /* only keep # of *
1045 * bytes to receive */
1046
1047 if (!(S_MBUF = i4b_Dgetmbuf(DCH_MAX_LEN)))
1048 panic("ihfc_hdlc_Dread: No mbufs(unit=%d)!\n", S_UNIT);
1049
1050 SET_REG((S_HFC & HFC_SP) ? 0xbd : 0xa7);
1051
1052 if ((reclen > 2) && (reclen <= (DCH_MAX_LEN+2)))
1053 {
1054 dst = S_MBUFDATA;
1055 len = S_MBUFLEN = (reclen += 1) - 3;
1056 }
1057 else
1058 {
1059 len = 0;
1060 dst = NULL;
1061 }
1062
1063 crc = -1; /* NOTE: after a "F1" or "Z1" hardware overflow *
1064 * it appears not to be necessary to reset the *
1065 * HFC-1/S or SP chips to continue proper *
1066 * operation, only and only, if we always read *
1067 * "Z1-Z2+1" bytes when F1!=F2 followed by a *
1068 * F2-counter increment. The bi-effect of doing *
1069 * this is the "STAT" field may say frame is ok *
1070 * when the frame is actually bad. *
1071 * The simple solution is to re-CRC the frame *
1072 * including "STAT" field to see if we get *
1073 * CRC == 0x3933. Then we're 99% sure all *
1074 * frames received are good. */
1075
1076 while(reclen--)
1077 {
1078 DISBUSY(tmp = READ_DATA_1, break);
1079 if (len) { len--; *dst++ = tmp; }
1080
1081 crc = (HDLC_FCS_TAB[(u_char)(tmp ^ crc)] ^ (u_char)(crc >> 8));
1082 }
1083
1084 crc ^= 0x3933;
1085
1086 if (!tmp && !crc)
1087 {
1088 ihfc_putmbuf(sc, chan, S_MBUF);
1089 S_MBUF = NULL;
1090 }
1091 else
1092 {
1093 NDBGL1(L1_ERROR, "Frame error (len=%d, stat=0x%x, "
1094 "crc=0x%x, unit=%d)", S_MBUFLEN, (u_char)tmp, crc,
1095 S_UNIT);
1096
1097 i4b_Dfreembuf(S_MBUF);
1098 S_MBUF = NULL;
1099 }
1100
1101 reclen = ihfc_Dsel_fifo(sc, chan, 0x20);
1102 }
1103}
1104
1105/*---------------------------------------------------------------------------*
1106 * EXIR error handler - ISAC (D - channel) (HFC-1)
1107 *---------------------------------------------------------------------------*/
1108void
1109ihfc_exir_hdlr (ihfc_sc_t *sc, u_char exir)
1110{
94332c29
RG
1111 u_char a;
1112 u_char cmd;
984263bc
MD
1113
1114 for (a = 0, cmd = 0; exir; a++, exir >>= 1)
1115 {
1116 if (exir & 1)
1117 {
1118 NDBGL1(L1_I_ERR, "%s. (unit=%d)",
1119 ihfc_EXIRtable[a].string, S_UNIT);
1120 cmd |= ihfc_EXIRtable[a].cmd;
1121 }
1122 }
1123
1124 if (cmd) ihfc_cmdr_hdlr(sc, cmd);
1125}
1126
1127/*---------------------------------------------------------------------------*
1128 * CMDR handler - ISAC (D - channel) (HFC-1)
1129 *---------------------------------------------------------------------------*/
1130void
1131ihfc_cmdr_hdlr (ihfc_sc_t *sc, u_char cmdr)
1132{
1133 BUS_VAR;
1134
1135 SET_REG(0x21); DISBUSY(WRITE_DATA_1(cmdr); DELAY(30), );
1136}
1137
1138/*---------------------------------------------------------------------------*
1139 * Data handler for D channel(write) - chan 0 (HFC-1)
1140 *---------------------------------------------------------------------------*/
1141void
1142ihfc_isac_Dwrite (ihfc_sc_t *sc, u_char chan)
1143{
94332c29
RG
1144 u_char sendlen = 32;
1145 u_char cmd = 0;
1146 u_short len;
1147 u_char * src;
984263bc
MD
1148
1149 BUS_VAR;
1150
1151 if (~S_ISTA & 0x10) goto j0;
1152
1153 if (!S_MBUF)
1154 if (!(S_MBUF = ihfc_getmbuf(sc, chan))) goto j0;
1155
1156 len = S_MBUFLEN;
1157 src = S_MBUFDATA;
1158
1159 SET_REG(0x00);
1160
1161 while(sendlen--) /* write data */
1162 {
1163 if (!len--) break;
1164 DISBUSY(WRITE_DATA_1(*src++), goto a0);
1165 }
1166
1167 cmd |= 0x08;
1168
1169 if (!++sendlen) /* suspend */
1170 {
1171 S_MBUFLEN = len;
1172 S_MBUFDATA = src;
1173 }
1174 else
1175 {
1176 a0:
1177 i4b_Dfreembuf(S_MBUF);
1178 S_MBUF = NULL;
1179
1180 cmd |= 0x02;
1181 }
1182
1183 if (cmd) ihfc_cmdr_hdlr(sc, cmd);
1184
1185 S_ISTA &= ~0x10;
1186 j0:
5b73dc76 1187 ;
984263bc
MD
1188}
1189
1190/*---------------------------------------------------------------------------*
1191 * Data handler for D channel(read) - chan 1 (HFC-1)
1192 *---------------------------------------------------------------------------*/
1193void
1194ihfc_isac_Dread (ihfc_sc_t *sc, u_char chan)
1195{
94332c29
RG
1196 u_char cmd = 0;
1197 u_char reclen;
1198 u_short tmp;
1199 u_short len;
1200 u_char * dst;
984263bc
MD
1201
1202 BUS_VAR;
1203
1204 if (!(S_ISTA & 0xc0)) goto j1; /* only receive data *
1205 * on interrupt */
1206
1207 if (!S_MBUF)
1208 {
1209 if (!(S_MBUF = i4b_Dgetmbuf(DCH_MAX_LEN)))
1210 panic("ihfc%d: (D) Out of mbufs!\n", S_UNIT);
1211 }
1212
1213 len = S_MBUFLEN;
1214 dst = S_MBUFDATA + (DCH_MAX_LEN - len);
1215
1216 if (S_ISTA & 0x80) /* RME */
1217 {
1218 SET_REG(0x27); DISBUSY(tmp = (READ_DATA_1 ^ 0x20), goto j0);
1219
1220 if (tmp & 0x70) goto j0; /* error */
1221
1222 SET_REG(0x25); DISBUSY(tmp = (READ_DATA_1 & 0x1f), goto j0);
1223
1224 reclen = (tmp) ? tmp : 32;
1225 }
1226 else /* RPF */
1227 {
1228 reclen = 32;
1229 }
1230
1231 if ((len -= reclen) <= DCH_MAX_LEN) /* get data */
1232 {
1233 SET_REG(0x00);
1234
1235 while(reclen--)
1236 {
1237 DISBUSY(*dst++ = READ_DATA_1, goto j0);
1238 }
1239 }
1240 else /* soft rdo or error */
1241 {
1242 j0: i4b_Dfreembuf(S_MBUF);
1243 S_MBUF = NULL;
1244
1245 cmd |= 0x40;
1246
1247 NDBGL1(L1_I_ERR, "Frame error (unit=%d)", S_UNIT);
1248 }
1249
1250 if (S_ISTA & 0x80) /* frame complete */
1251 {
1252 if (S_MBUF)
1253 {
1254 S_MBUFLEN = (DCH_MAX_LEN - len);
1255 ihfc_putmbuf(sc, chan, S_MBUF);
1256 S_MBUF = NULL;
1257 }
1258 }
1259
1260 if (S_MBUF) /* suspend */
1261 {
1262 S_MBUFLEN = len;
1263 }
1264
1265 ihfc_cmdr_hdlr(sc, cmd | 0x80);
1266
1267 S_ISTA &= ~0xc0;
1268 j1:
5b73dc76 1269 ;
984263bc
MD
1270}
1271
1272/*---------------------------------------------------------------------------*
1273 * Data handler for B channel(write) - chan 2 and 4 (HFC-1/S/SP)
1274 *
1275 * NOTE: No XDU checking!
1276 *---------------------------------------------------------------------------*/
1277void
1278ihfc_trans_Bwrite (ihfc_sc_t *sc, u_char chan)
1279{
94332c29
RG
1280 u_short sendlen;
1281 u_short len;
1282 u_char * src;
984263bc
MD
1283
1284 BUS_VAR;
1285
1286 if (!S_MBUF && IF_QEMPTY(&S_IFQUEUE)) return;
1287
1288 sendlen = (u_short)ihfc_Bsel_fifo(sc, chan, 0);
1289
1290 SET_REG(0xaa + chan);
1291
1292 while (1)
1293 {
1294 if (!S_MBUF)
1295 {
1296 S_MBUF = ihfc_getmbuf(sc, chan);
1297 if (!S_MBUF) break;
1298 }
1299
1300 src = S_MBUFDATA;
1301 len = S_MBUFLEN;
1302
1303 while (sendlen--)
1304 {
1305 if (!len--) break;
1306
1307 DISBUSY(WRITE_DATA_1(*src++), sendlen = -1; len++; break);
1308 }
1309
1310 if (!++sendlen) /* out of fifo: Suspend */
1311 {
1312 S_MBUFDATA = src;
1313 S_MBUFLEN = len;
1314 break;
1315 }
1316
1317 i4b_Dfreembuf(S_MBUF);
1318 S_MBUF = NULL;
1319 }
1320}
1321
1322/*---------------------------------------------------------------------------*
1323 * Data handler for B channel(read) - chan 3 and 5 (HFC-1/S/SP)
1324 * (this code is optimized)
1325 *---------------------------------------------------------------------------*/
1326void
1327ihfc_trans_Bread (ihfc_sc_t *sc, u_char chan)
1328{
94332c29
RG
1329 u_short reclen;
1330 u_short tmp;
1331 u_short len;
1332 u_char * dst;
984263bc
MD
1333
1334 BUS_VAR;
1335
1336 reclen = (u_short)ihfc_Bsel_fifo(sc, chan, 0);
1337
1338 while (1)
1339 {
1340 SET_REG(0xba + chan);
1341
1342 tmp = 0x100;
1343
1344 if (!S_MBUF)
1345 if (!(S_MBUF = i4b_Bgetmbuf(BCH_MAX_DATALEN)))
1346 panic("ihfc%d: (B) Out of mbufs!\n", S_UNIT);
1347
1348 len = S_MBUFLEN;
1349 dst = S_MBUFDATA + (BCH_MAX_DATALEN - len);
1350
1351 while (reclen--)
1352 {
1353 if (!len--) break;
1354
1355 if (tmp & 0x100) DISBUSY( , reclen = -1; len++; break);
1356 *dst++ = (u_char)(tmp = READ_BOTH_2);
1357 }
1358
1359 if (~tmp & 0x100)
1360 {
1361 SET_REG(0x30);
1362 READ_DATA_1; /* a read to the data port *
1363 * will disable the internal *
1364 * disbusy signal for HFC-1/S *
1365 * chips. This is neccessary *
1366 * to avvoid data loss. */
1367 }
1368
1369 if (!++reclen) /* out of fifo: suspend */
1370 {
1371 S_MBUFLEN = len;
1372 break;
1373 }
1374
1375 S_MBUFLEN = (BCH_MAX_DATALEN - ++len);
1376
1377 ihfc_putmbuf(sc, chan, S_MBUF);
1378
1379 S_MBUF = NULL;
1380 }
1381}
1382
1383/*---------------------------------------------------------------------------*
1384 * Data handler for B channel(write) - chan 2 and 4 (HFC-1/S/SP)
1385 *
1386 * NOTE: Software HDLC encoding!
1387 *---------------------------------------------------------------------------*/
1388void
1389ihfc_hdlc_Bwrite (ihfc_sc_t *sc, u_char chan)
1390{
94332c29
RG
1391 u_short blevel = S_HDLC_BLEVEL;
1392 u_char flag = S_HDLC_FLAG;
1393 u_int tmp = S_HDLC_TMP;
1394 u_short crc = S_HDLC_CRC;
1395 u_short ib = S_HDLC_IB;
1396 u_char * src = NULL;
1397 u_short len = 0;
1398 u_short sendlen;
1399 u_short tmp2;
984263bc
MD
1400
1401 BUS_VAR;
1402
1403 if (!S_MBUF && IF_QEMPTY(&S_IFQUEUE) && (flag == 2)) return;
1404
1405 sendlen = (u_short)ihfc_Bsel_fifo(sc, chan, 0);
1406
1407 SET_REG(0xaa + chan);
1408
1409 if (S_MBUF)
1410 {
1411 /* resume */
1412
1413 src = S_MBUFDATA;
1414 len = S_MBUFLEN;
1415
1416 if (sendlen == 0x5ff)
1417 {
1418 /* XDU */
1419
1420 flag = -2;
1421 len = 0;
1422
1423 NDBGL1(L1_S_ERR, "XDU (unit=%d)", S_UNIT);
1424 }
1425 }
1426
1427 while (sendlen--)
1428 {
1429 HDLC_ENCODE(*src++, len, tmp, tmp2, blevel, ib, crc, flag,
1430 {/* gfr */
1431 i4b_Bfreembuf(S_MBUF);
1432 S_MBUF = ihfc_getmbuf(sc, chan);
1433
1434 if (S_MBUF)
1435 {
1436 src = S_MBUFDATA;
1437 len = S_MBUFLEN;
1438 }
1439 else
1440 {
1441 sendlen = 0; /* Exit after final FS, *
1442 * else the buffer will *
1443 * only be filled with *
1444 * "0x7e"-bytes! */
1445 }
1446 },
1447 {/* wrd */
1448
1449 DISBUSY(WRITE_DATA_1((u_char)tmp), sendlen = 0);
1450 },
1451 d );
1452 }
1453
1454 if (S_MBUF) /* suspend */
1455 {
1456 S_MBUFDATA = src;
1457 S_MBUFLEN = len;
1458 }
1459
1460 S_HDLC_IB = ib;
1461 S_HDLC_BLEVEL = blevel;
1462 S_HDLC_TMP = tmp;
1463 S_HDLC_FLAG = flag;
1464 S_HDLC_CRC = crc;
1465}
1466
1467/*---------------------------------------------------------------------------*
1468 * Data handler for B channel(read) - chan 3 and 5 (HFC-1/S/SP)
1469 *
1470 * NOTE: Software HDLC decoding!
1471 *---------------------------------------------------------------------------*/
1472void
1473ihfc_hdlc_Bread (ihfc_sc_t *sc, u_char chan)
1474{
94332c29 1475 u_char blevel = S_HDLC_BLEVEL;
984263bc 1476 u_char flag = S_HDLC_FLAG;
94332c29
RG
1477 u_short crc = S_HDLC_CRC;
1478 u_int tmp = S_HDLC_TMP;
1479 u_short ib = S_HDLC_IB;
1480 u_char * dst = NULL;
1481 u_short tmp2 = 0x100;
1482 u_short len = 0;
1483 u_short reclen;
984263bc
MD
1484
1485 BUS_VAR;
1486
1487 if (S_MBUF)
1488 {
1489 /* resume */
1490
1491 len = S_MBUFLEN;
1492 dst = S_MBUFDATA + (BCH_MAX_DATALEN - len);
1493 }
1494
1495 reclen = (u_short)ihfc_Bsel_fifo(sc, chan, 0);
1496
1497 SET_REG(0xba + chan);
1498
1499 while (reclen--)
1500 {
1501 HDLC_DECODE(*dst++, len, tmp, tmp2, blevel, ib, crc, flag,
1502 {/* rdd */
1503 /* if (tmp2 & 0x100) while (GET_STAT & 1);
1504 * tmp2 = READ_BOTH_2;
1505 */
1506
1507 DISBUSY(tmp2 = READ_DATA_1, reclen = 0; tmp2 = 0);
1508 },
1509 {/* nfr */
1510 if (!(S_MBUF = i4b_Bgetmbuf(BCH_MAX_DATALEN)))
1511 panic("ihfc:(B) Out of mbufs!\n");
1512
1513 dst = S_MBUFDATA;
1514 len = BCH_MAX_DATALEN;
1515 },
1516 {/* cfr */
1517 len = (BCH_MAX_DATALEN - len);
1518
1519 if ((!len) || (len > BCH_MAX_DATALEN))
1520 {
1521 /* NOTE: frames without any data, *
1522 * only crc field, should be silently discared. */
1523
1524 i4b_Bfreembuf(S_MBUF);
1525 NDBGL1(L1_S_MSG, "Bad frame (len=%d, unit=%d)", len, S_UNIT);
1526 goto s0;
1527 }
1528
1529 if (crc)
1530 { i4b_Bfreembuf(S_MBUF);
1531 NDBGL1(L1_S_ERR, "CRC (crc=0x%04x, len=%d, unit=%d)", crc, len, S_UNIT);
1532 goto s0;
1533 }
1534
1535 S_MBUFLEN = len;
1536
1537 ihfc_putmbuf(sc, chan, S_MBUF);
1538 s0:
1539 S_MBUF = NULL;
1540 },
1541 {/* rab */
1542 i4b_Bfreembuf(S_MBUF);
1543 S_MBUF = NULL;
1544
1545 NDBGL1(L1_S_MSG, "Read Abort (unit=%d)", S_UNIT);
1546 },
1547 {/* rdo */
1548 i4b_Bfreembuf(S_MBUF);
1549 S_MBUF = NULL;
1550
1551 NDBGL1(L1_S_ERR, "RDO (unit=%d)", S_UNIT);
1552 },
1553 continue,
1554 d);
1555 }
1556
1557 /* SET_REG(0x30);
1558 * if (~tmp2 & 0x100) READ_DATA_1; kill disbusy signal
1559 */
1560
1561 if (S_MBUF) S_MBUFLEN = len; /* suspend */
1562
1563 S_HDLC_IB = ib;
1564 S_HDLC_CRC = crc;
1565 S_HDLC_TMP = tmp;
1566 S_HDLC_FLAG = flag;
1567 S_HDLC_BLEVEL = blevel;
1568}
1569
1570/*---------------------------------------------------------------------------*
1571 * Data handler for B channel(write) - chan 2 and 4 (HFC-1/S/SP)
1572 *
1573 * This filter generates a pattern which is recognized
1574 * and examinated and verified by ihfc_test_Bread.
1575 *
1576 * NOTE: This filter is only for testing purpose.
1577 *---------------------------------------------------------------------------*/
1578void
1579ihfc_test_Bwrite (ihfc_sc_t *sc, u_char chan)
1580{
1581 struct mbuf *m;
1582
94332c29
RG
1583 u_char fb;
1584 u_short sendlen, tlen;
1585 u_short xlen = S_HDLC_IB;
984263bc
MD
1586 BUS_VAR;
1587
1588 goto j0;
1589
1590 while((m = ihfc_getmbuf(sc, chan))) /* internal loop */
1591 {
1592 if (chan == 2)
1593 ihfc_putmbuf(sc, 5, m);
1594 else
1595 ihfc_putmbuf(sc, 3, m);
1596 }
1597
1598 j0:
1599
1600 sendlen = /* (u_short)ihfc_Bsel_fifo(sc, chan, 0); */ 0;
1601
4b1cf444 1602 if (sendlen == 0x5ff) kprintf("(send empty)");
984263bc
MD
1603
1604 SET_REG(0xaa + chan);
1605
1606 S_BYTES += sendlen;
1607
1608 tlen = S_HDLC_CRC;
1609
4b1cf444 1610 if (sendlen > 0x400) kprintf("(slow: %d)", sendlen);
984263bc
MD
1611
1612 fb = 0x80;
1613
1614 while (sendlen--)
1615 {
1616 if (!tlen--) fb |= 0x20;
1617
1618 if (!xlen--)
1619 {
1620 while(GET_STAT & 1);
1621 WRITE_DATA_1(0x3e);
1622 xlen = 200;
1623 }
1624 else
1625 {
1626 while(GET_STAT & 1);
1627 WRITE_DATA_1((xlen + 1) & 0xef);
1628 }
1629
1630 fb = 0;
1631 }
1632
1633 S_HDLC_IB = xlen;
1634}
1635
1636/*---------------------------------------------------------------------------*
1637 * Data handler for B channel(read) - chan 3 and 5 (HFC-1/S/SP)
1638 *
1639 * This filter examins and verifies the pattern
1640 * generated by ihfc_test_Bwrite.
1641 *
1642 * NOTE: This filter is only for testing purpose.
1643 *---------------------------------------------------------------------------*/
1644void
1645ihfc_test_Bread (ihfc_sc_t *sc, u_char chan)
1646{
1647 static u_short toterrors = 0;
1648
94332c29
RG
1649 u_short reclen, len, tlen;
1650 u_char fb, tmp;
984263bc 1651
94332c29
RG
1652 u_short xlen = S_HDLC_IB;
1653 u_char *dst = NULL;
1654 u_char error = S_HDLC_TMP;
1655 u_char ecount = S_HDLC_FLAG;
984263bc
MD
1656
1657 BUS_VAR;
1658
1659 if (S_UNIT != 0) return;
1660
1661 reclen = /* (u_short)ihfc_Bsel_fifo(sc, chan, 0); */ 0;
1662
1663 S_BYTES += reclen;
1664
1665 tlen = S_HDLC_CRC;
1666
1667 fb = 0x40;
1668
1669 if (S_MBUF)
1670 {
1671 len = S_MBUFLEN;
1672 dst = S_MBUFDATA + (BCH_MAX_DATALEN - len);
1673 }
1674 else
1675 {
1676 len = 0;
1677 }
1678
1679 SET_REG(0xba + chan);
1680
1681 while (reclen--)
1682 {
1683/* if (tmp2 & 0x100) while(GET_STAT & 1);
1684 * tmp = (u_char)(tmp2 = READ_BOTH_2);
1685 */
1686 if (GET_STAT & 1)
1687 {
1688 /* if (!(++busy % 4)) reclen++; */
1689 while(GET_STAT & 1);
1690 }
1691
1692 tmp = READ_DATA_1;
1693
1694 if ((tmp & 0x3f) == 0x3e)
1695 {
1696 if ((BCH_MAX_DATALEN - len) != 201) error |= 4;
1697
1698 if ((S_MBUF) && (error))
1699 {
1700 if (len) { len--; *dst++ = error; }
1701 if (len) { len--; *dst++ = xlen+1; }
1702 if (len) { len--; *dst++ = ecount; }
1703
1704 S_MBUFLEN = BCH_MAX_DATALEN - len;
1705
1706 if (S_TRACE & TRACE_B_RX)
1707 ihfc_putmbuf(sc, chan, S_MBUF);
1708 else
1709 i4b_Bfreembuf(S_MBUF);
1710
1711 S_MBUF = NULL;
4b1cf444 1712 kprintf("(error%d, %d, %d)", S_UNIT, ecount, toterrors++);
984263bc
MD
1713 }
1714
1715 i4b_Bfreembuf(S_MBUF);
1716 S_MBUF = i4b_Bgetmbuf(BCH_MAX_DATALEN);
1717
1718 dst = S_MBUFDATA;
1719 len = BCH_MAX_DATALEN;
1720
1721 xlen = 200;
1722 error = 0;
1723 ecount = 0;
1724
1725 /* SET_REG(0xba + chan); */
1726 }
1727 else
1728 {
1729 if (!xlen) error |= 2;
1730 if ((tmp ^ xlen--) & 0xef) { error |= 1; ecount++; }
1731 }
1732 if (!tlen--) fb |= 0x20;
1733
1734 if (len--)
1735 {
1736 *dst++ = (tmp | fb);
1737 }
1738 else
1739 {
1740 len++;
1741 }
1742
1743 fb = 0;
1744 }
1745
1746 if (S_MBUF)
1747 {
1748 S_MBUFLEN = len;
1749 }
1750
1751 S_HDLC_IB = xlen;
1752 S_HDLC_TMP = error;
1753 S_HDLC_FLAG = ecount;
1754}
1755
1756#endif /* NIHFC > 0 */