Do a major clean-up of the BUSDMA architecture. A large number of
[dragonfly.git] / sys / net / i4b / layer1 / itjc / i4b_itjc_pci.c
CommitLineData
984263bc
MD
1/*
2 * Copyright (c) 2000, 2001 Sergio Prallon. 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 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the author nor the names of any co-contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 * 4. Altered versions must be plainly marked as such, and must not be
17 * misrepresented as being the original software and/or documentation.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 *---------------------------------------------------------------------------
32 *
33 * i4b_itjc_pci.c: NetJet-S hardware driver
34 * ----------------------------------------
35 *
36 * $FreeBSD: src/sys/i4b/layer1/itjc/i4b_itjc_pci.c,v 1.1.2.1 2001/08/10 14:08:39 obrien Exp $
1f7ab7c9 37 * $DragonFly: src/sys/net/i4b/layer1/itjc/i4b_itjc_pci.c,v 1.16 2006/10/25 20:56:03 dillon Exp $
984263bc
MD
38 *
39 * last edit-date: [Thu Jan 11 11:29:38 2001]
40 *
41 *---------------------------------------------------------------------------*/
42
1f2de5d4
MD
43#include "use_itjc.h"
44#include "use_pci.h"
984263bc 45#include "opt_i4b.h"
984263bc
MD
46
47#if (NITJC > 0)
48
49#include <sys/param.h>
50#include <sys/kernel.h>
51#include <sys/systm.h>
52#include <sys/mbuf.h>
984263bc
MD
53#include <sys/bus.h>
54#include <sys/rman.h>
1f7ab7c9
MD
55#include <sys/socket.h>
56#include <sys/thread2.h>
57
58#include <machine/clock.h>
984263bc 59
1f2de5d4
MD
60#include <bus/pci/pcireg.h>
61#include <bus/pci/pcivar.h>
984263bc 62
984263bc 63#include <net/if.h>
1f2de5d4
MD
64#include <net/i4b/include/machine/i4b_debug.h>
65#include <net/i4b/include/machine/i4b_ioctl.h>
66#include <net/i4b/include/machine/i4b_trace.h>
984263bc 67
1f2de5d4
MD
68#include "../../include/i4b_global.h"
69#include "../../include/i4b_mbuf.h"
984263bc 70
1f2de5d4 71#include "../i4b_l1.h"
984263bc 72
1f2de5d4 73#include "i4b_hdlc.h" /* XXXXXXXXXXXXXXXXXXXXXXXX */
984263bc 74
1f2de5d4
MD
75#include "../isic/i4b_isic.h"
76#include "../isic/i4b_isac.h"
984263bc 77
1f2de5d4 78#include "i4b_itjc_ext.h"
984263bc
MD
79
80#define PCI_TJNET_VID (0xe159)
81#define PCI_TJ300_DID (0x0001)
82
83
84/*
85 * Function prototypes
86 */
87
88static int itjc_probe(device_t dev);
89static int itjc_attach(device_t dev);
90static void itjc_shutdown(device_t dev);
91static void itjc_intr(void *xsc);
92static int itjc_dma_start(struct l1_softc *sc);
93static void itjc_dma_stop(struct l1_softc *sc);
94static void itjc_isac_intr(struct l1_softc *sc);
95static void itjc_init_linktab(struct l1_softc *sc);
96static void itjc_bchannel_setup(int unit, int h_chan, int bprot,
97 int activate);
98static void itjc_bchannel_stat(int unit, int h_chan, bchan_statistics_t *bsp);
99
100
101/*
102 * Shorter names to bus resource manager routines.
103 */
104
105#define itjc_bus_setup(sc) \
106 bus_space_handle_t h = \
107 rman_get_bushandle((sc)->sc_resources.io_base[0]); \
108 bus_space_tag_t t = \
109 rman_get_bustag((sc)->sc_resources.io_base[0]);
110
111#define itjc_read_1(port) (bus_space_read_1(t, h, (port)))
112#define itjc_read_4(port) (bus_space_read_4(t, h, (port)))
113#define itjc_write_1(port, data) (bus_space_write_1(t, h, (port), (data)))
114#define itjc_write_4(port, data) (bus_space_write_4(t, h, (port), (data)))
115#define itjc_read_multi_1(port, buf, size) \
116 (bus_space_read_multi_1(t, h, (port), (buf), (size)))
117#define itjc_write_multi_1(port, buf, size) \
118 (bus_space_write_multi_1(t, h, (port), (buf), (size)))
119
120
121/*---------------------------------------------------------------------------*
122 * Glue data to register ourselves as a PCI device driver.
123 *---------------------------------------------------------------------------*/
124
125static device_method_t itjc_pci_methods[] =
126{
127 /* Device interface */
128 DEVMETHOD(device_probe, itjc_probe),
129 DEVMETHOD(device_attach, itjc_attach),
130 DEVMETHOD(device_shutdown, itjc_shutdown),
131
132 /* bus interface */
133 DEVMETHOD(bus_print_child, bus_generic_print_child),
134 DEVMETHOD(bus_driver_added, bus_generic_driver_added),
135
136 { 0, 0 }
137};
138
139static driver_t itjc_pci_driver =
140{
141 "itjc",
142 itjc_pci_methods,
143 sizeof(struct l1_softc)
144};
145
146static devclass_t itjc_pci_devclass;
147
148DRIVER_MODULE(netjet, pci, itjc_pci_driver, itjc_pci_devclass, 0, 0);
149
150/*
151 * Jump table for multiplex routines.
152 */
153
154struct i4b_l1mux_func itjc_l1mux_func =
155{
156 itjc_ret_linktab,
157 itjc_set_linktab,
158 itjc_mph_command_req,
159 itjc_ph_data_req,
160 itjc_ph_activate_req,
161};
162
163struct l1_softc *itjc_scp[ITJC_MAXUNIT];
164
165
166/*---------------------------------------------------------------------------*
167 * Tiger300/320 PCI ASIC registers.
168 *---------------------------------------------------------------------------*/
169
170/*
171 * Register offsets from i/o base.
172 */
173enum tiger_regs
174{
175 TIGER_RESET_PIB_CL_TIME = 0x00,
176 TIGER_DMA_OPER = 0x01,
177 TIGER_AUX_PORT_CNTL = 0x02,
178 TIGER_AUX_PORT_DATA = 0x03,
179 TIGER_INT0_MASK = 0x04,
180 TIGER_INT1_MASK = 0x05,
181 TIGER_INT0_STATUS = 0x06,
182 TIGER_INT1_STATUS = 0x07,
183 TIGER_DMA_WR_START_ADDR = 0x08,
184 TIGER_DMA_WR_INT_ADDR = 0x0C,
185 TIGER_DMA_WR_END_ADDR = 0x10,
186 TIGER_DMA_WR_CURR_ADDR = 0x14,
187 TIGER_DMA_RD_START_ADDR = 0x18,
188 TIGER_DMA_RD_INT_ADDR = 0x1C,
189 TIGER_DMA_RD_END_ADDR = 0x20,
190 TIGER_DMA_RD_CURR_ADDR = 0x24,
191 TIGER_PULSE_COUNTER = 0x28,
192};
193
194/*
195 * Bits on the above registers.
196 */
197
198enum tiger_reg_bits
199{
200/* Reset and PIB Cycle Timing */
201
202 TIGER_DMA_OP_MODE_MASK = 0x80,
203 TIGER_SELF_ADDR_DMA = 0x00, /* Wrap around ending addr */
204 TIGER_NORMAL_DMA = 0x80, /* Stop at ending addr */
205
206 TIGER_DMA_INT_MODE_MASK = 0x40,
207 TIGER_DONT_LATCH_DMA_INT= 0x00, /* Bits on int0 status will be
208 set only while curr addr
209 equals int or end addr */
210 TIGER_LATCH_DMA_INT = 0x40, /* Bits on int0 status remain
211 set until cleared by CPU */
212
213 TIGER_PIB_CYCLE_TIMING_MASK = 0x30,
214 TIGER_PIB_3_CYCLES = 0x00,
215 TIGER_PIB_5_CYCLES = 0x01,
216 TIGER_PIB_12_CYCLES = 0x10,
217
218 TIGER_RESET_MASK = 0x0F,
219 TIGER_RESET_PULSE_COUNT = 0x08,
220 TIGER_RESET_SERIAL_PORT = 0x04,
221 TIGER_RESET_DMA_LOGIC = 0x02,
222 TIGER_RESET_EXTERNAL = 0x01,
223 TIGER_RESET_ALL = 0x0F,
224
225/* DMA Operation */
226 TIGER_DMA_RESTART_MASK = 0x02,
227 TIGER_HOLD_DMA = 0x00,
228 TIGER_RESTART_DMA = 0x00,
229
230 TIGER_DMA_ENABLE_MASK = 0x01,
231 TIGER_ENABLE_DMA = 0x01,
232 TIGER_DISABLE_DMA = 0x00,
233
234/* AUX Port Control & Data plus Interrupt 1 Mask & Status */
235 TIGER_AUX_7_MASK = 0x80,
236 TIGER_AUX_6_MASK = 0x40,
237 TIGER_AUX_5_MASK = 0x20,
238 TIGER_AUX_4_MASK = 0x10,
239 TIGER_ISAC_INT_MASK = 0x10,
240 TIGER_AUX_3_MASK = 0x08,
241 TIGER_AUX_2_MASK = 0x04,
242 TIGER_AUX_1_MASK = 0x02,
243 TIGER_AUX_0_MASK = 0x01,
244
245/* AUX Port Control */
246 TIGER_AUX_7_IS_INPUT = 0x00,
247 TIGER_AUX_7_IS_OUTPUT = 0x80,
248 TIGER_AUX_6_IS_INPUT = 0x00,
249 TIGER_AUX_6_IS_OUTPUT = 0x40,
250 TIGER_AUX_5_IS_INPUT = 0x00,
251 TIGER_AUX_5_IS_OUTPUT = 0x20,
252 TIGER_AUX_4_IS_INPUT = 0x00,
253 TIGER_AUX_4_IS_OUTPUT = 0x10,
254 TIGER_AUX_3_IS_INPUT = 0x00,
255 TIGER_AUX_3_IS_OUTPUT = 0x80,
256 TIGER_AUX_2_IS_INPUT = 0x00,
257 TIGER_AUX_2_IS_OUTPUT = 0x40,
258 TIGER_AUX_1_IS_INPUT = 0x00,
259 TIGER_AUX_1_IS_OUTPUT = 0x20,
260 TIGER_AUX_0_IS_INPUT = 0x00,
261 TIGER_AUX_0_IS_OUTPUT = 0x10,
262 TIGER_AUX_NJ_DEFAULT = 0xEF, /* All but ISAC int is output */
263
264/* Interrupt 0 Mask & Status */
265 TIGER_PCI_TARGET_ABORT_INT_MASK = 0x20,
266 TIGER_NO_TGT_ABORT_INT = 0x00,
267 TIGER_TARGET_ABORT_INT = 0x20,
268 TIGER_PCI_MASTER_ABORT_INT_MASK = 0x10,
269 TIGER_NO_MST_ABORT_INT = 0x00,
270 TIGER_MASTER_ABORT_INT = 0x10,
271 TIGER_DMA_RD_END_INT_MASK = 0x08,
272 TIGER_NO_RD_END_INT = 0x00,
273 TIGER_RD_END_INT = 0x08,
274 TIGER_DMA_RD_INT_INT_MASK = 0x04,
275 TIGER_NO_RD_INT_INT = 0x00,
276 TIGER_RD_INT_INT = 0x04,
277 TIGER_DMA_WR_END_INT_MASK = 0x02,
278 TIGER_NO_WR_END_INT = 0x00,
279 TIGER_WR_END_INT = 0x02,
280 TIGER_DMA_WR_INT_INT_MASK = 0x01,
281 TIGER_NO_WR_INT_INT = 0x00,
282 TIGER_WR_INT_INT = 0x01,
283
284/* Interrupt 1 Mask & Status */
285 TIGER_NO_AUX_7_INT = 0x00,
286 TIGER_AUX_7_INT = 0x80,
287 TIGER_NO_AUX_6_INT = 0x00,
288 TIGER_AUX_6_INT = 0x40,
289 TIGER_NO_AUX_5_INT = 0x00,
290 TIGER_AUX_5_INT = 0x20,
291 TIGER_NO_AUX_4_INT = 0x00,
292 TIGER_AUX_4_INT = 0x10,
293 TIGER_NO_ISAC_INT = 0x00,
294 TIGER_ISAC_INT = 0x10,
295 TIGER_NO_AUX_3_INT = 0x00,
296 TIGER_AUX_3_INT = 0x08,
297 TIGER_NO_AUX_2_INT = 0x00,
298 TIGER_AUX_2_INT = 0x04,
299 TIGER_NO_AUX_1_INT = 0x00,
300 TIGER_AUX_1_INT = 0x02,
301 TIGER_NO_AUX_0_INT = 0x00,
302 TIGER_AUX_0_INT = 0x01
303};
304
305/*
306 * Peripheral Interface Bus definitions. This is an ISA like bus
307 * created by the Tiger ASIC to keep ISA chips like the ISAC happy
308 * on a PCI environment.
309 *
310 * Since the PIB only supplies 4 addressing lines, the 2 higher bits
311 * (A4 & A5) of the ISAC register addresses are wired on the 2 lower
312 * AUX lines. Another restriction is that all I/O to the PIB (8bit
313 * wide) is mapped on the PCI side as 32bit data. So the PCI address
314 * of a given ISAC register has to be multiplied by 4 before being
315 * added to the PIB base offset.
316 */
317enum tiger_pib_regs_defs
318{
319 /* Offset from the I/O base to the ISAC registers. */
320 PIB_OFFSET = 0xC0,
321 PIB_LO_ADDR_MASK = 0x0F,
322 PIB_HI_ADDR_MASK = 0x30,
323 PIB_LO_ADDR_SHIFT = 2, /* Align on dword boundary */
324 PIB_HI_ADDR_SHIFT = 4 /* Right shift to AUX_1 & AUX_0 */
325};
326
327
328#define itjc_set_pib_addr_msb(a) \
329( \
330 itjc_write_1(TIGER_AUX_PORT_DATA, \
331 ((a) & PIB_HI_ADDR_MASK) >> PIB_HI_ADDR_SHIFT) \
332)
333
334#define itjc_pib_2_pci(a) \
335( \
336 (((a) & PIB_LO_ADDR_MASK) << PIB_LO_ADDR_SHIFT) + PIB_OFFSET \
337)
338
339#define itjc_get_dma_offset(ctx,reg) \
340( \
341 (u_int16_t)((bus_addr_t)itjc_read_4((reg)) - (ctx)->bus_addr) \
342)
343
344
345/*
346 * IOM-2 serial channel 0 DMA data ring buffers.
347 *
348 * The Tiger300/320 ASIC do not nothing more than transfer via DMA the
349 * first 32 bits of every IOM-2 frame on the serial interface to the
350 * ISAC. So we have no framing/deframing facilities like we would have
351 * with an HSCX, having to do the job with CPU cycles. On the plus side
352 * we are able to specify large rings which can limit the occurrence of
353 * over/underruns.
354 */
355
356enum
357{
358 ITJC_RING_SLOT_WORDS = 64,
359 ITJC_RING_WORDS = 3 * ITJC_RING_SLOT_WORDS,
360 ITJC_RING_SLOT_BYTES = 4 * ITJC_RING_SLOT_WORDS,
361 ITJC_RING_BYTES = 4 * ITJC_RING_WORDS,
362 ITJC_DMA_POOL_WORDS = 2 * ITJC_RING_WORDS,
363 ITJC_DMA_POOL_BYTES = 4 * ITJC_DMA_POOL_WORDS
364};
365
366#define itjc_ring_add(x, d) (((x) + 4 * (d)) % ITJC_RING_BYTES)
367#define itjc_ring_sub(x, d) (((x) + ITJC_RING_BYTES - 4 * (d)) \
368 % ITJC_RING_BYTES)
369
370
371enum
372{
373 TIGER_CH_A = 0,
374 TIGER_CH_B = 1,
375
376 HSCX_CH_A = 0, /* For compatibility reasons. */
377 HSCX_CH_B = 1,
378};
379
380enum
381{
382 ITJC_TEL_SILENCE_BYTE = 0x00,
383 ITJC_HDLC_FLAG_BYTE = 0x7E,
384 ITJC_HDLC_ABORT_BYTE = 0xFF
385};
386
387/*
388 * Hardware DMA control block (one per card).
389 */
390typedef enum
391{
392 ITJC_DS_LOAD_FAILED = -1,
393 ITJC_DS_FREE = 0,
394 ITJC_DS_LOADING,
395 ITJC_DS_STOPPED,
396 ITJC_DS_RUNNING
397}
398 dma_state_t;
399
400typedef struct
401{
402 dma_state_t state;
403 u_int8_t *pool;
404 bus_addr_t bus_addr;
405 bus_dma_tag_t tag;
406 bus_dmamap_t map;
407 int error;
408}
409 dma_context_t;
410
411dma_context_t
412 dma_context [ ITJC_MAXUNIT ];
413
414/*
415 * B-channel DMA control blocks (4 per card -- 1 RX & 1 TX per channel).
416 */
417typedef enum
418{
419 ITJC_RS_IDLE = 0,
420 ITJC_RS_ACTIVE
421}
422 dma_rx_state_t;
423
424typedef enum
425{
426 ITJC_TS_IDLE = 0,
427 ITJC_TS_ACTIVE,
428 ITJC_TS_AFTER_XDU
429}
430 dma_tx_state_t;
431
432typedef struct
433{
434 u_int8_t *ring;
435 bus_addr_t bus_addr;
436 u_int16_t next_read;
437 u_int16_t hdlc_len;
438 u_int16_t hdlc_tmp;
439 u_int16_t hdlc_crc;
440 u_int16_t hdlc_ib;
441 u_int8_t hdlc_blevel;
442 u_int8_t hdlc_flag;
443 dma_rx_state_t state;
444}
445 dma_rx_context_t;
446
447typedef struct
448{
449 u_int8_t *ring;
450 bus_addr_t bus_addr;
451 u_int16_t next_write;
452 u_int32_t hdlc_tmp;
453 u_int16_t hdlc_blevel;
454 u_int16_t hdlc_crc;
455 u_int16_t hdlc_ib;
456 u_int16_t next_frame;
457 u_int16_t filled;
458 u_int8_t hdlc_flag;
459 dma_tx_state_t state;
460}
461 dma_tx_context_t;
462
463dma_rx_context_t
464 dma_rx_context [ ITJC_MAXUNIT ] [ 2 ];
465
466dma_tx_context_t
467 dma_tx_context [ ITJC_MAXUNIT ] [ 2 ];
468
469/*
470 * Used by the mbuf handling functions.
471 */
472typedef enum
473{
474 ITJC_MB_CURR = 0,
475 ITJC_MB_NEXT = 1,
476 ITJC_MB_NEW = 2
477}
478 which_mb_t;
479
480
481/*---------------------------------------------------------------------------*
482 * itjc_map_callback - get DMA bus address from resource mgr.
483 *---------------------------------------------------------------------------*/
484static void
485itjc_map_callback(void *arg, bus_dma_segment_t *segs, int nseg, int error)
486{
487 dma_context_t *ctx = (dma_context_t *)arg;
488
489 if (error)
490 {
491 ctx->error = error;
492 ctx->state = ITJC_DS_LOAD_FAILED;
493 return;
494 }
495
496 ctx->bus_addr = segs->ds_addr;
497 ctx->state = ITJC_DS_STOPPED;
498}
499
500
501/*---------------------------------------------------------------------------*
502 * itjc_dma_start - Complete DMA setup & start the Tiger DMA engine.
503 *---------------------------------------------------------------------------*/
504static int
505itjc_dma_start(struct l1_softc *sc)
506{
507 int unit = sc->sc_unit;
508 dma_context_t *ctx = &dma_context[unit];
509 dma_rx_context_t *rxc = &dma_rx_context[unit][0];
510 dma_tx_context_t *txc = &dma_tx_context[unit][0];
511 bus_addr_t ba;
512 u_int8_t i;
513 u_int32_t *pool_end,
514 *ip;
515
018cf6f8
JS
516 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
517 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
984263bc
MD
518
519 /* See if it is already running. */
520
521 if (ctx->state == ITJC_DS_RUNNING)
522 return 0;
523
524 if (ctx->state == ITJC_DS_LOAD_FAILED)
525 {
526 NDBGL1(L1_ERROR, "itjc%d: dma_start: DMA map loading "
527 "failed (error=%d).\n", unit, ctx->error);
528 return 1;
529 }
530
531 if (ctx->state != ITJC_DS_STOPPED)
532 {
533 NDBGL1(L1_ERROR, "itjc%d: dma_start: Unexpected DMA "
534 "state (%d).\n", unit, ctx->state);
535 return 1;
536 }
537
538 /*
539 * Initialize the DMA control structures (hardware & B-channel).
540 */
541 ba = ctx->bus_addr;
542
543 txc->ring = ctx->pool + TIGER_CH_A;
544 rxc->ring = ctx->pool + TIGER_CH_A + ITJC_RING_BYTES;
545
546 txc->bus_addr = ba;
547 rxc->bus_addr = ba + ITJC_RING_BYTES;
548
549 ++rxc; ++txc;
550
551 txc->ring = ctx->pool + TIGER_CH_B;
552 rxc->ring = ctx->pool + TIGER_CH_B + ITJC_RING_BYTES;
553
554 txc->bus_addr = ba;
555 rxc->bus_addr = ba + ITJC_RING_BYTES;
556
557 /*
558 * Fill the DMA ring buffers with IOM-2 channel 0 frames made of
559 * idle/abort sequences for the B & D channels and NOP for IOM-2
560 * cmd/ind, monitor handshake & data.
561 */
562 pool_end = (u_int32_t *)ctx->pool + ITJC_DMA_POOL_WORDS;
563 for (ip = (u_int32_t *)ctx->pool; ip < pool_end; ++ip)
564 *ip = 0xFFFFFFFF;
565
566 /*
567 * Program the Tiger DMA gears.
568 */
569
570 itjc_write_4(TIGER_DMA_WR_START_ADDR, ba);
571 itjc_write_4(TIGER_DMA_WR_INT_ADDR, ba + ITJC_RING_SLOT_BYTES - 4);
572 itjc_write_4(TIGER_DMA_WR_END_ADDR, ba + ITJC_RING_BYTES - 4);
573
574 ba += ITJC_RING_BYTES;
575
576 itjc_write_4(TIGER_DMA_RD_START_ADDR, ba);
577 itjc_write_4(TIGER_DMA_RD_INT_ADDR, ba + ITJC_RING_SLOT_BYTES * 2 - 4);
578 itjc_write_4(TIGER_DMA_RD_END_ADDR, ba + ITJC_RING_BYTES - 4);
579
580 itjc_write_1(TIGER_INT0_MASK,
581 TIGER_WR_END_INT | TIGER_WR_INT_INT | TIGER_RD_INT_INT);
582
583 itjc_write_1(TIGER_DMA_OPER, TIGER_ENABLE_DMA);
584
585 /*
586 * See if it really started.
587 */
588 ba = itjc_read_4(TIGER_DMA_RD_CURR_ADDR);
589 for (i = 0; i < 10; ++i)
590 {
591 DELAY(SEC_DELAY/1000);
592 if (ba != itjc_read_4(TIGER_DMA_RD_CURR_ADDR))
593 {
594 ctx->state = ITJC_DS_RUNNING;
595 return 0;
596 }
597 }
598
599 NDBGL1(L1_ERROR, "itjc%d: dma_start: DMA start failed.\n ", unit);
600 return 1;
601}
602
603
604/*---------------------------------------------------------------------------*
605 * itjc_dma_stop - Stop the Tiger DMA engine.
606 *---------------------------------------------------------------------------*/
607void
608itjc_dma_stop(struct l1_softc *sc)
609{
610 dma_context_t *ctx = &dma_context[sc->sc_unit];
611
018cf6f8
JS
612 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
613 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
984263bc
MD
614
615 /* Only stop the DMA if it is running. */
616
617 if (ctx->state != ITJC_DS_RUNNING)
618 return;
619
620 itjc_write_1(TIGER_DMA_OPER, TIGER_DISABLE_DMA);
621 DELAY(SEC_DELAY/1000);
622
623 ctx->state = ITJC_DS_STOPPED;
624}
625
626
627/*---------------------------------------------------------------------------*
628 * itjc_bchannel_dma_setup - The DMA side of itjc_bchannel_setup.
629 *---------------------------------------------------------------------------*/
630static void
631itjc_bchannel_dma_setup(struct l1_softc *sc, int h_chan, int activate)
632{
633 dma_rx_context_t *rxc = &dma_rx_context[sc->sc_unit][h_chan];
634 dma_tx_context_t *txc = &dma_tx_context[sc->sc_unit][h_chan];
635
636 l1_bchan_state_t *chan = &sc->sc_chan[h_chan];
637
638 u_int8_t fill_byte,
639 *ring_end,
640 *cp;
018cf6f8
JS
641 bus_space_handle_t h;
642 bus_space_tag_t t;
984263bc 643
817cdab6 644 crit_enter();
018cf6f8
JS
645 h = rman_get_bushandle(sc->sc_resources.io_base[0]);
646 t = rman_get_bustag(sc->sc_resources.io_base[0]);
984263bc
MD
647
648 if (activate)
649 {
650 /*
651 * Get the DMA engine going if it's not running already.
652 */
653 itjc_dma_start(sc);
654
655 rxc->hdlc_len = rxc->hdlc_tmp = rxc->hdlc_crc = 0;
656 rxc->hdlc_ib = rxc->hdlc_blevel = rxc->hdlc_flag = 0;
657
658 txc->hdlc_tmp = txc->hdlc_blevel = txc->hdlc_crc = 0;
659 txc->hdlc_ib = 0;
660 txc->hdlc_flag = 2;
661 txc->filled = 0;
662
663 if (chan->bprot == BPROT_NONE)
664 fill_byte = ITJC_TEL_SILENCE_BYTE;
665 else
666 fill_byte = ITJC_HDLC_ABORT_BYTE;
667
668 ring_end = rxc->ring + ITJC_RING_BYTES;
669 for (cp = rxc->ring; cp < ring_end; cp += 4)
670 *cp = fill_byte;
671
672 ring_end = txc->ring + ITJC_RING_BYTES;
673 for (cp = txc->ring; cp < ring_end; cp += 4)
674 *cp = fill_byte;
675
676 rxc->next_read =
677 itjc_get_dma_offset(rxc, TIGER_DMA_RD_CURR_ADDR);
678
679 txc->next_frame = txc->next_write =
680 itjc_get_dma_offset(txc, TIGER_DMA_WR_CURR_ADDR);
681
682 rxc->state = ITJC_RS_ACTIVE;
683 txc->state = ITJC_TS_AFTER_XDU;
684 }
685 else
686 {
687 dma_rx_context_t *rxc2;
688
689 txc->state = ITJC_TS_IDLE;
690 rxc->state = ITJC_RS_IDLE;
691
692 rxc2 = &dma_rx_context[sc->sc_unit][0];
693
694 if (rxc2->state == ITJC_RS_IDLE
695 && rxc2[1].state == ITJC_RS_IDLE)
696 itjc_dma_stop(sc);
697 }
698
817cdab6 699 crit_exit();
984263bc
MD
700}
701
702
703/*---------------------------------------------------------------------------*
704 * Mbuf & if_queues management routines.
705 *---------------------------------------------------------------------------*/
706
707static u_int8_t *
708itjc_get_rx_mbuf(l1_bchan_state_t *chan, u_int8_t **dst_end_p,
709which_mb_t which)
710{
711 struct mbuf *mbuf = chan->in_mbuf;
712
713 if (mbuf == NULL && which == ITJC_MB_NEW)
714 {
715 if ((mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL)
716 panic("itjc_get_rx_mbuf: cannot allocate mbuf!");
717
718 chan->in_mbuf = mbuf;
719 chan->in_cbptr = (u_int8_t *)mbuf->m_data;
720 chan->in_len = 0;
721 }
722
723 if (dst_end_p != NULL)
724 {
725 if (mbuf != NULL)
726 *dst_end_p = (u_int8_t *)(mbuf->m_data)
727 + BCH_MAX_DATALEN;
728 else
729 *dst_end_p = NULL;
730 }
731
732 return chan->in_cbptr;
733}
734
735
736static void
737itjc_save_rx_mbuf(l1_bchan_state_t *chan, u_int8_t * dst)
738{
739 struct mbuf *mbuf = chan->in_mbuf;
740
741 if (dst != NULL && mbuf != NULL)
742 {
743 chan->in_cbptr = dst;
744 chan->in_len = dst - (u_int8_t *)mbuf->m_data;
745 }
746 else if (dst == NULL && mbuf == NULL)
747 {
748 chan->in_cbptr = NULL;
749 chan->in_len = 0;
750 }
751 else
752 panic("itjc_save_rx_mbuf: stale pointer dst=%p mbuf=%p "
753 "in_cbptr=%p in_len=%d", dst, mbuf,
754 chan->in_cbptr, chan->in_len);
755}
756
757
758static void
759itjc_free_rx_mbuf(l1_bchan_state_t *chan)
760{
761 struct mbuf *mbuf = chan->in_mbuf;
762
763 if (mbuf != NULL)
764 i4b_Bfreembuf(mbuf);
765
766 chan->in_mbuf = NULL;
767 chan->in_cbptr = NULL;
768 chan->in_len = 0;
769}
770
771
772static void
773itjc_put_rx_mbuf(struct l1_softc *sc, l1_bchan_state_t *chan, u_int16_t len)
774{
775 i4b_trace_hdr_t hdr;
776 struct mbuf *mbuf = chan->in_mbuf;
777 u_int8_t *data = mbuf->m_data;
778 int activity = 1;
779
780 mbuf->m_pkthdr.len = mbuf->m_len = len;
781
782 if (sc->sc_trace & TRACE_B_RX)
783 {
784 hdr.unit = L0ITJCUNIT(sc->sc_unit);
785 hdr.type = (chan->channel == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
786 hdr.dir = FROM_NT;
787 hdr.count = ++sc->sc_trace_bcount;
788 MICROTIME(hdr.time);
789 i4b_l1_trace_ind(&hdr, len, data);
790 }
791
792 if (chan->bprot == BPROT_NONE)
793 {
794 activity = ! i4b_l1_bchan_tel_silence(data, len);
795
796 /* move rx'd data to rx queue */
797
fd81ccf9 798 if (!IF_QFULL(&chan->rx_queue))
984263bc
MD
799 {
800 IF_ENQUEUE(&chan->rx_queue, mbuf);
801 }
802 else
803 {
804 i4b_Bfreembuf(mbuf);
805 len = 0;
806 }
807 }
808
809 if (len != 0)
810 {
811 chan->rxcount += len;
812
813 (*chan->isic_drvr_linktab->bch_rx_data_ready)
814 (chan->isic_drvr_linktab->unit);
815 }
816
817 if (activity)
818 (*chan->isic_drvr_linktab->bch_activity)
819 (chan->isic_drvr_linktab->unit, ACT_RX);
820
821 chan->in_mbuf = NULL;
822 chan->in_cbptr = NULL;
823 chan->in_len = 0;
824}
825
826
827#define itjc_free_tx_mbufs(chan) \
828{ \
829 i4b_Bfreembuf((chan)->out_mbuf_head); \
830 (chan)->out_mbuf_cur = (chan)->out_mbuf_head = NULL; \
831 (chan)->out_mbuf_cur_ptr = NULL; \
832 (chan)->out_mbuf_cur_len = 0; \
833}
834
835
836static u_int16_t
837itjc_get_tx_mbuf(struct l1_softc *sc, l1_bchan_state_t *chan,
838 u_int8_t **src_p, which_mb_t which)
839{
840 i4b_trace_hdr_t hdr;
841 struct mbuf *mbuf = chan->out_mbuf_cur;
842 u_int8_t activity = 1;
843 u_int16_t len;
844 void *data;
845
846 switch (which)
847 {
848 case ITJC_MB_CURR:
849 if (mbuf != NULL)
850 {
851 *src_p = chan->out_mbuf_cur_ptr;
852 return chan->out_mbuf_cur_len;
853 }
854
855 break;
856
857 case ITJC_MB_NEXT:
858 if (mbuf != NULL)
859 {
860 chan->txcount += mbuf->m_len;
861
862 mbuf = mbuf->m_next;
863
864 if (mbuf != NULL)
865 goto new_mbuf;
866 }
867
868 chan->out_mbuf_cur_ptr = *src_p = NULL;
869 chan->out_mbuf_cur_len = 0;
870
871 if (chan->out_mbuf_head != NULL)
872 {
873 i4b_Bfreembuf(chan->out_mbuf_head);
874 chan->out_mbuf_head = NULL;
875 }
876
877 return 0;
878
879 case ITJC_MB_NEW:
880 if (mbuf != NULL)
881 chan->txcount += mbuf->m_len;
882 }
883
884 if (chan->out_mbuf_head != NULL)
885 i4b_Bfreembuf(chan->out_mbuf_head);
886
887 IF_DEQUEUE(&chan->tx_queue, mbuf);
888
889 if (mbuf == NULL)
890 {
891 chan->out_mbuf_cur = chan->out_mbuf_head = NULL;
892 chan->out_mbuf_cur_ptr = *src_p = NULL;
893 chan->out_mbuf_cur_len = 0;
894
895 chan->state &= ~(HSCX_TX_ACTIVE);
896
897 (*chan->isic_drvr_linktab->bch_tx_queue_empty)
898 (chan->isic_drvr_linktab->unit);
899
900 return 0;
901 }
902
903 chan->out_mbuf_head = mbuf;
904
905new_mbuf:
906 chan->out_mbuf_cur = mbuf;
907 chan->out_mbuf_cur_ptr = data = mbuf->m_data;
908 chan->out_mbuf_cur_len = len = mbuf->m_len;
909
910 chan->state |= HSCX_TX_ACTIVE;
911
912 if (sc->sc_trace & TRACE_B_TX)
913 {
914 hdr.unit = L0ITJCUNIT(sc->sc_unit);
915 hdr.type = (chan->channel == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
916 hdr.dir = FROM_TE;
917 hdr.count = ++sc->sc_trace_bcount;
918 MICROTIME(hdr.time);
919 i4b_l1_trace_ind(&hdr, len, data);
920 }
921
922 if (chan->bprot == BPROT_NONE)
923 activity = ! i4b_l1_bchan_tel_silence(data, len);
924
925 if (activity)
926 (*chan->isic_drvr_linktab->bch_activity)
927 (chan->isic_drvr_linktab->unit, ACT_TX);
928
929 *src_p = data;
930 return len;
931}
932
933
934#define itjc_save_tx_mbuf(chan, src, dst) \
935( \
936 (chan)->out_mbuf_cur != NULL ? \
937 ( \
938 (chan)->out_mbuf_cur_ptr = (src), \
939 (chan)->out_mbuf_cur_len = (len) \
940 ) \
941 : \
942 0 \
943)
944
945
946/*---------------------------------------------------------------------------*
947 * B-channel interrupt service routines.
948 *---------------------------------------------------------------------------*/
949
950/*
951 * Since the Tiger ASIC doesn't produce a XMIT underflow indication,
952 * we need to deduce it ourselves. This is somewhat tricky because we
953 * are dealing with modulo m arithmetic. The idea here is to have a
954 * "XDU zone" ahead of the writing pointer sized 1/3 of total ring
955 * length (a ring slot). If the hardware DMA pointer is found there we
956 * consider that a XDU has occurred. To complete the scheme, we never
957 * let the ring have more than 2 slots of (unsent) data and adjust the
958 * interrupt registers to cause an interrupt at every slot.
959 */
960static u_int8_t
961itjc_xdu(struct l1_softc *sc, l1_bchan_state_t *chan, dma_tx_context_t *ctx,
962u_int16_t *dst_p, u_int16_t *dst_end_p, u_int8_t tx_restart)
963{
964 u_int8_t xdu;
965
966 u_int16_t dst_end,
967 dst,
968 dma,
969 dma_l,
970 dma_h,
971 xdu_l,
972 xdu_h;
973
018cf6f8
JS
974 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
975 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
984263bc
MD
976
977 /*
978 * Since the hardware is running, be conservative and assume
979 * the pointer location has a `fuzy' error factor.
980 */
981 dma = itjc_get_dma_offset(ctx, TIGER_DMA_WR_CURR_ADDR);
982 dma_l = dma;
983 dma_h = itjc_ring_add(dma, 1);
984
985 dst_end = itjc_ring_sub(dma_l, ITJC_RING_SLOT_WORDS);
986
987 if (ctx->state != ITJC_TS_ACTIVE)
988 {
989 xdu = (ctx->state == ITJC_TS_AFTER_XDU);
990 dst = itjc_ring_add(dma_h, 4);
991 goto done;
992 }
993
994 /*
995 * Check for xmit underruns.
996 */
997 xdu_l = dst = ctx->next_write;
998 xdu_h = itjc_ring_add(dst, ITJC_RING_SLOT_WORDS);
999
1000 if (xdu_l < xdu_h)
1001 xdu = (xdu_l <= dma_l && dma_l < xdu_h)
1002 || (xdu_l <= dma_h && dma_h < xdu_h);
1003 else
1004 xdu = (xdu_l <= dma_l || dma_l < xdu_h)
1005 || (xdu_l <= dma_h || dma_h < xdu_h);
1006
1007 if (xdu)
1008 {
1009 ctx->state = ITJC_TS_AFTER_XDU;
1010
1011 dst = itjc_ring_add(dma_h, 4);
1012 }
1013 else if (tx_restart)
1014 {
1015 /*
1016 * See if we still can restart from immediately
1017 * after the last frame sent. It's a XDU test but
1018 * using the real data end on the comparsions. We
1019 * don't consider XDU an error here because we were
1020 * just trying to avoid send a filling gap between
1021 * frames. If it's already sent no harm is done.
1022 */
1023 xdu_l = dst = ctx->next_frame;
1024 xdu_h = itjc_ring_add(dst, ITJC_RING_SLOT_WORDS);
1025
1026 if (xdu_l < xdu_h)
1027 xdu = (xdu_l <= dma_l && dma_l < xdu_h)
1028 || (xdu_l <= dma_h && dma_h < xdu_h);
1029 else
1030 xdu = (xdu_l <= dma_l || dma_l < xdu_h)
1031 || (xdu_l <= dma_h || dma_h < xdu_h);
1032
1033 if (xdu)
1034 dst = itjc_ring_add(dma_h, 4);
1035
1036 xdu = 0;
1037 }
1038
1039done:
1040 if (dst_p != NULL)
1041 *dst_p = dst;
1042
1043 if (dst_end_p != NULL)
1044 *dst_end_p = dst_end;
1045
1046 ctx->next_write = dst_end;
1047
1048 return xdu;
1049}
1050
1051
1052#define itjc_rotate_hdlc_flag(blevel) \
1053 ((u_int8_t)(0x7E7E >> (8 - (u_int8_t)((blevel) >> 8))))
1054
1055
1056static void
1057itjc_dma_rx_intr(struct l1_softc *sc, l1_bchan_state_t *chan,
1058dma_rx_context_t *ctx)
1059{
1060 u_int8_t *ring,
1061 *dst,
1062 *dst_end,
1063 flag,
1064 blevel;
1065
1066 u_int16_t dma,
1067 src,
1068 tmp2,
1069 tmp,
1070 len,
1071 crc,
1072 ib;
1073
018cf6f8
JS
1074 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
1075 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
984263bc
MD
1076
1077
1078 if (ctx->state == ITJC_RS_IDLE)
1079 return;
1080
1081 ring = ctx->ring;
1082 dma = itjc_get_dma_offset(ctx, TIGER_DMA_RD_CURR_ADDR);
1083 dma = itjc_ring_sub(dma, 1);
1084 src = ctx->next_read;
1085
1086 if (chan->bprot == BPROT_NONE)
1087 {
1088 dst = itjc_get_rx_mbuf(chan, &dst_end, ITJC_MB_CURR);
1089
1090 while (src != dma)
1091 {
1092 if (dst == NULL)
1093 dst = itjc_get_rx_mbuf(chan, &dst_end,
1094 ITJC_MB_NEW);
1095
1096 *dst++ = ring[src];
1097 src = itjc_ring_add(src, 1);
1098
1099 if (dst >= dst_end)
1100 {
1101 itjc_put_rx_mbuf(sc, chan, BCH_MAX_DATALEN);
1102 dst = dst_end = NULL;
1103 }
1104 }
1105 ctx->next_read = src;
1106 itjc_save_rx_mbuf(chan, dst);
1107 return;
1108 }
1109
1110 blevel = ctx->hdlc_blevel;
1111 flag = ctx->hdlc_flag;
1112 len = ctx->hdlc_len;
1113 tmp = ctx->hdlc_tmp;
1114 crc = ctx->hdlc_crc;
1115 ib = ctx->hdlc_ib;
1116
1117 dst = itjc_get_rx_mbuf(chan, NULL, ITJC_MB_CURR);
1118
1119 while (src != dma)
1120 {
1121 HDLC_DECODE(*dst++, len, tmp, tmp2, blevel, ib, crc, flag,
1122 {/* rdd */
1123 tmp2 = ring[src];
1124 src = itjc_ring_add(src, 1);
1125 },
1126 {/* nfr */
1127 if (dst != NULL)
1128 panic("itjc_dma_rx_intr: nfrcmd with "
1129 "valid current frame");
1130
1131 dst = itjc_get_rx_mbuf(chan, &dst_end, ITJC_MB_NEW);
1132 len = dst_end - dst;
1133 },
1134 {/* cfr */
1135 len = BCH_MAX_DATALEN - len;
1136
1137 if ((!len) || (len > BCH_MAX_DATALEN))
1138 {
1139 /*
1140 * NOTE: frames without any data, only crc
1141 * field, should be silently discared.
1142 */
1143 NDBGL1(L1_S_MSG, "itjc_dma_rx_intr: "
1144 "bad frame (len=%d, unit=%d)",
1145 len, sc->sc_unit);
1146
1147 itjc_free_rx_mbuf(chan);
1148
1149 goto s0;
1150 }
1151
1152 if (crc)
1153 {
1154 NDBGL1(L1_S_ERR,
1155 "CRC (crc=0x%04x, len=%d, unit=%d)",
1156 crc, len, sc->sc_unit);
1157
1158 itjc_free_rx_mbuf(chan);
1159
1160 goto s0;
1161 }
1162
1163 itjc_put_rx_mbuf(sc, chan, len);
1164
1165 s0:
1166 dst = NULL;
1167 len = 0;
1168 },
1169 {/* rab */
1170 NDBGL1(L1_S_ERR, "Read Abort (unit=%d)", sc->sc_unit);
1171
1172 itjc_free_rx_mbuf(chan);
1173 dst = NULL;
1174 len = 0;
1175 },
1176 {/* rdo */
1177 NDBGL1(L1_S_ERR, "RDO (unit=%d) dma=%d src=%d",
1178 sc->sc_unit, dma, src);
1179
1180 itjc_free_rx_mbuf(chan);
1181 dst = NULL;
1182 len = 0;
1183 },
1184 continue,
1185 d);
1186 }
1187
1188 itjc_save_rx_mbuf(chan, dst);
1189
1190 ctx->next_read = src;
1191 ctx->hdlc_blevel= blevel;
1192 ctx->hdlc_flag = flag;
1193 ctx->hdlc_len = len;
1194 ctx->hdlc_tmp = tmp;
1195 ctx->hdlc_crc = crc;
1196 ctx->hdlc_ib = ib;
1197}
1198
1199
1200/*
1201 * The HDLC side of itjc_dma_tx_intr. We made a separate function
1202 * to improve readability and (perhaps) help the compiler with
1203 * register allocation.
1204 */
1205static void
1206itjc_hdlc_encode(struct l1_softc *sc, l1_bchan_state_t *chan,
1207dma_tx_context_t * ctx)
1208{
1209 u_int8_t *ring,
1210 *src,
1211 xdu,
1212 flag,
1213 flag_byte,
1214 tx_restart;
1215
1216 u_int16_t saved_len,
1217 dst_end,
1218 dst_end1,
1219 dst,
1220 filled,
1221 blevel,
1222 tmp2,
1223 len,
1224 crc,
1225 ib;
1226
1227 u_int32_t tmp;
1228
1229
1230 saved_len = len = itjc_get_tx_mbuf(sc, chan, &src, ITJC_MB_CURR);
1231
1232 filled = ctx->filled;
1233 flag = ctx->hdlc_flag;
1234
1235 if (src == NULL && flag == 2 && filled >= ITJC_RING_WORDS)
1236 return;
1237
1238 tx_restart = (flag == 2 && src != NULL);
1239 xdu = itjc_xdu(sc, chan, ctx, &dst, &dst_end, tx_restart);
1240
1241 ring = ctx->ring;
1242
1243 ib = ctx->hdlc_ib;
1244 crc = ctx->hdlc_crc;
1245 tmp = ctx->hdlc_tmp;
1246 blevel = ctx->hdlc_blevel;
1247
1248 if (xdu)
1249 {
1250 if (flag != 2)
1251 {
1252 NDBGL1(L1_H_XFRERR, "XDU");
1253 ++chan->stat_XDU;
1254
1255 /*
1256 * Abort the current frame and
1257 * prepare for a full restart.
1258 */
1259 itjc_free_tx_mbufs(chan);
1260 saved_len = len = filled = 0;
1261 flag = (u_int8_t)-2;
1262 }
1263 else if (filled < ITJC_RING_SLOT_WORDS)
1264 {
1265 /*
1266 * A little garbage may have been retransmitted.
1267 * Send an abort before any new data.
1268 */
1269 filled = 0;
1270 flag = (u_int8_t)-2;
1271 }
1272 }
1273
1274 if (flag != 3)
1275 len = 0;
1276
1277 while (dst != dst_end)
1278 {
1279 HDLC_ENCODE(
1280 *src++, len, tmp, tmp2, blevel, ib, crc, flag,
1281 {/* gfr */
1282 if ((len = saved_len) == 0)
1283 len = itjc_get_tx_mbuf(sc, chan, &src,
1284 ITJC_MB_NEW);
1285
1286 if (len == 0)
1287 {
1288 ctx->next_frame = dst;
1289
1290 flag_byte = itjc_rotate_hdlc_flag(blevel);
1291
1292 for (dst_end1 = itjc_ring_sub(dst_end, 1);
1293 dst != dst_end1;
1294 dst = itjc_ring_add(dst, 1))
1295 {
1296 ring[dst] = flag_byte;
1297 ++filled;
1298 }
1299 }
1300 else
1301 filled = 0;
1302
1303 ctx->state = ITJC_TS_ACTIVE;
1304 },
1305 {/* nmb */
1306 saved_len = 0;
1307 len = itjc_get_tx_mbuf(sc, chan, &src, ITJC_MB_NEXT);
1308 },
1309 {/* wrd */
1310 ring[dst] = (u_int8_t)tmp;
1311 dst = itjc_ring_add(dst, 1);
1312 },
1313 d1);
1314 }
1315
1316 ctx->hdlc_blevel = blevel;
1317 ctx->hdlc_flag = flag;
1318 ctx->hdlc_tmp = tmp;
1319 ctx->hdlc_crc = crc;
1320 ctx->hdlc_ib = ib;
1321
1322 ctx->filled = filled;
1323 ctx->next_write = dst;
1324
1325 itjc_save_tx_mbuf(chan, src, len);
1326}
1327
1328
1329static void
1330itjc_dma_tx_intr(struct l1_softc *sc, l1_bchan_state_t *chan,
1331dma_tx_context_t * ctx)
1332{
1333 u_int8_t *data_end,
1334 *ring,
1335 *src,
1336 xdu;
1337
1338 u_int16_t dst,
1339 dst_end,
1340 filled,
1341 len;
1342
1343
1344 if (ctx->state == ITJC_TS_IDLE)
1345 goto done;
1346
1347 if (chan->bprot != BPROT_NONE)
1348 {
1349 itjc_hdlc_encode(sc, chan, ctx);
1350 goto done;
1351 }
1352
1353 ring = ctx->ring;
1354 filled = ctx->filled;
1355
1356 len = itjc_get_tx_mbuf(sc, chan, &src, ITJC_MB_CURR);
1357
1358 if (len == 0 && filled >= ITJC_RING_WORDS)
1359 goto done;
1360
1361 xdu = itjc_xdu(sc, chan, ctx, &dst, &dst_end, len != 0);
1362
1363 if (xdu && filled < ITJC_RING_WORDS)
1364 {
1365 NDBGL1(L1_H_XFRERR, "XDU");
1366 ++chan->stat_XDU;
1367 filled = 0;
1368 }
1369
1370 if (len == 0)
1371 goto fill_ring;
1372
1373 ctx->state = ITJC_TS_ACTIVE;
1374
1375 data_end = src + len;
1376 while (dst != dst_end)
1377 {
1378 ring[dst] = *src++; --len;
1379
1380 dst = itjc_ring_add(dst, 1);
1381
1382 if (src >= data_end)
1383 {
1384 len = itjc_get_tx_mbuf(sc, chan, &src, ITJC_MB_NEXT);
1385 if (len == 0)
1386 len = itjc_get_tx_mbuf(sc, chan,
1387 &src, ITJC_MB_NEW);
1388
1389 if (len == 0)
1390 {
1391 data_end = NULL;
1392 break;
1393 }
1394 data_end = src + len;
1395 }
1396 }
1397
1398 itjc_save_tx_mbuf(chan, src, len);
1399
1400 filled = 0;
1401
1402fill_ring:
1403 ctx->next_frame = dst;
1404
1405 for (; dst != dst_end; dst = itjc_ring_add(dst, 1))
1406 {
1407 ring[dst] = ITJC_TEL_SILENCE_BYTE;
1408 ++filled;
1409 }
1410
1411 ctx->next_write = dst;
1412 ctx->filled = filled;
1413
1414done:
5b73dc76 1415 ;
984263bc
MD
1416}
1417
1418
1419/*---------------------------------------------------------------------------*
1420 * NetJet fifo read/write routines.
1421 *---------------------------------------------------------------------------*/
1422
1423static void
1424itjc_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size)
1425{
018cf6f8
JS
1426 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
1427 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
984263bc
MD
1428
1429 if (what != ISIC_WHAT_ISAC)
1430 panic("itjc_write_fifo: Trying to read from HSCX fifo.\n");
1431
1432 itjc_set_pib_addr_msb(0);
1433 itjc_read_multi_1(PIB_OFFSET, buf, size);
1434}
1435
1436
1437static void
1438itjc_write_fifo(struct l1_softc *sc, int what, void *buf, size_t size)
1439{
018cf6f8
JS
1440 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
1441 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
984263bc
MD
1442
1443 if (what != ISIC_WHAT_ISAC)
1444 panic("itjc_write_fifo: Trying to write to HSCX fifo.\n");
1445
1446 itjc_set_pib_addr_msb(0);
1447 itjc_write_multi_1(PIB_OFFSET, buf, size);
1448}
1449
1450
1451/*---------------------------------------------------------------------------*
1452 * Read an ISAC register.
1453 *---------------------------------------------------------------------------*/
1454static u_int8_t
1455itjc_read_reg(struct l1_softc *sc, int what, bus_size_t offs)
1456{
018cf6f8
JS
1457 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
1458 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
984263bc
MD
1459
1460 if (what != ISIC_WHAT_ISAC)
1461 {
1462 panic("itjc_read_reg: what(%d) != ISIC_WHAT_ISAC\n",
1463 what);
1464 return 0;
1465 }
1466
1467 itjc_set_pib_addr_msb(offs);
1468 return itjc_read_1(itjc_pib_2_pci(offs));
1469}
1470
1471
1472/*---------------------------------------------------------------------------*
1473 * Write an ISAC register.
1474 *---------------------------------------------------------------------------*/
1475static void
1476itjc_write_reg(struct l1_softc *sc, int what, bus_size_t offs, u_int8_t data)
1477{
018cf6f8
JS
1478 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
1479 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
984263bc
MD
1480
1481 if (what != ISIC_WHAT_ISAC)
1482 {
1483 panic("itjc_write_reg: what(%d) != ISIC_WHAT_ISAC\n",
1484 what);
1485 return;
1486 }
1487
1488 itjc_set_pib_addr_msb(offs);
1489 itjc_write_1(itjc_pib_2_pci(offs), data);
1490}
1491
1492
1493/*---------------------------------------------------------------------------*
1494 * itjc_probe - probe for a card.
1495 *---------------------------------------------------------------------------*/
3bf25ce1
SW
1496static int
1497itjc_probe(device_t dev)
984263bc
MD
1498{
1499 u_int16_t vid = pci_get_vendor(dev),
1500 did = pci_get_device(dev);
1501
1502 if ((vid == PCI_TJNET_VID) && (did == PCI_TJ300_DID))
1503 {
1504 device_set_desc(dev, "NetJet-S");
1505 return 0;
1506 }
1507
1508 return ENXIO;
1509}
1510
1511
1512/*---------------------------------------------------------------------------*
1513 * itjc_attach - attach a (previously probed) card.
1514 *---------------------------------------------------------------------------*/
1515int
1516itjc_attach(device_t dev)
1517{
1518 bus_space_handle_t h;
1519 bus_space_tag_t t;
1520
1521 struct l1_softc *sc = device_get_softc(dev);
1522
1523 u_int16_t vid = pci_get_vendor(dev),
1524 did = pci_get_device(dev);
1525
1526 int unit = device_get_unit(dev),
984263bc
MD
1527 res_init_level = 0,
1528 error = 0;
1529
1530 void *ih = 0;
1531
1532 dma_context_t *ctx = &dma_context[unit];
1533
817cdab6 1534 crit_enter();
984263bc
MD
1535 bzero(sc, sizeof(struct l1_softc));
1536
1537 /* Probably not really required. */
1538 if (unit > ITJC_MAXUNIT)
1539 {
1540 printf("itjc%d: Error, unit > ITJC_MAXUNIT!\n", unit);
817cdab6 1541 crit_exit();
984263bc
MD
1542 return ENXIO;
1543 }
1544
1545 if (!(vid == PCI_TJNET_VID && did == PCI_TJ300_DID))
1546 {
1547 printf("itjc%d: unknown device (%04X,%04X)!\n", unit, vid, did);
1548 goto fail;
1549 }
1550
1551 itjc_scp[unit] = sc;
1552
1553 sc->sc_resources.io_rid[0] = PCIR_MAPS+0;
1554 sc->sc_resources.io_base[0] = bus_alloc_resource(dev, SYS_RES_IOPORT,
1555 &sc->sc_resources.io_rid[0], 0, ~0, 1, RF_ACTIVE);
1556
1557 if (sc->sc_resources.io_base[0] == NULL)
1558 {
1559 printf("itjc%d: couldn't map IO port\n", unit);
1560 error = ENXIO;
1561 goto fail;
1562 }
1563
1564 h = rman_get_bushandle(sc->sc_resources.io_base[0]);
1565 t = rman_get_bustag(sc->sc_resources.io_base[0]);
1566
1567 ++res_init_level;
1568
1569 /* Allocate interrupt. */
1570 sc->sc_resources.irq_rid = 0;
1571 sc->sc_resources.irq = bus_alloc_resource(dev, SYS_RES_IRQ,
1572 &sc->sc_resources.irq_rid, 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE);
1573
1574 if (sc->sc_resources.irq == NULL)
1575 {
1576 printf("itjc%d: couldn't map interrupt\n", unit);
1577 error = ENXIO;
1578 goto fail;
1579 }
1580
1581 ++res_init_level;
1582
ee61f228 1583 error = bus_setup_intr(dev, sc->sc_resources.irq, 0,
e9cb6d99 1584 itjc_intr, sc, &ih, NULL);
984263bc
MD
1585
1586 if (error)
1587 {
1588 printf("itjc%d: couldn't set up irq handler\n", unit);
1589 error = ENXIO;
1590 goto fail;
1591 }
1592
1593 /*
1594 * Reset the ASIC & the ISAC.
1595 */
1596 itjc_write_1(TIGER_RESET_PIB_CL_TIME, TIGER_RESET_ALL);
1597
1598 DELAY(SEC_DELAY/100); /* Give it 10 ms to reset ...*/
1599
1600 itjc_write_1(TIGER_RESET_PIB_CL_TIME,
1601 TIGER_SELF_ADDR_DMA | TIGER_PIB_3_CYCLES);
1602
1603 DELAY(SEC_DELAY/100); /* ... and more 10 to recover. */
1604
1605 /*
1606 * First part of DMA initialization. Create & map the memory
1607 * pool that will be used to bear the rx & tx ring buffers.
1608 */
1609 ctx->state = ITJC_DS_LOADING;
1610
1611 error = bus_dma_tag_create(
1612 NULL, /* parent */
1613 4, /* alignment*/
1614 0, /* boundary*/
1615 BUS_SPACE_MAXADDR_32BIT, /* lowaddr*/
1616 BUS_SPACE_MAXADDR, /* highaddr*/
1617 NULL, /* filter*/
1618 NULL, /* filterarg*/
1619 ITJC_DMA_POOL_BYTES, /* maxsize*/
1620 1, /* nsegments*/
1621 ITJC_DMA_POOL_BYTES, /* maxsegsz*/
fef0fdf2 1622 BUS_DMA_ALLOCNOW | BUS_DMA_COHERENT, /* flags*/
984263bc
MD
1623 &ctx->tag);
1624
1625 if (error)
1626 {
1627 printf("itjc%d: couldn't create bus DMA tag.\n", unit);
1628 goto fail;
1629 }
1630
1631 ++res_init_level;
1632
1633 error = bus_dmamem_alloc(
1634 ctx->tag, /* DMA tag */
1635 (void **)&ctx->pool, /* KV addr of the allocated memory */
fef0fdf2 1636 BUS_DMA_NOWAIT | BUS_DMA_COHERENT, /* flags */
984263bc
MD
1637 &ctx->map); /* KV <-> PCI map */
1638
1639 if (error)
1640 goto fail;
1641
1642 /*
1643 * Load the KV <-> PCI map so the device sees the same
1644 * memory segment as pointed by pool. Note: since the
1645 * load may happen assyncronously (completion indicated by
1646 * the execution of the callback function) we have to
1647 * delay the initialization of the DMA engine to a moment we
1648 * actually have the proper bus addresses to feed the Tiger
1649 * and our DMA control blocks. This will be done in
1650 * itjc_bchannel_setup via a call to itjc_dma_start.
1651 */
1652 bus_dmamap_load(
1653 ctx->tag, /* DMA tag */
1654 ctx->map, /* DMA map */
1655 ctx->pool, /* KV addr of buffer */
1656 ITJC_DMA_POOL_BYTES, /* buffer size */
1657 itjc_map_callback, /* this receive the bus addr/error */
1658 ctx, /* callback aux arg */
1659 0); /* flags */
1660
1661 ++res_init_level;
1662
1663 /*
1664 * Setup the AUX port so we can talk to the ISAC.
1665 */
1666 itjc_write_1(TIGER_AUX_PORT_CNTL, TIGER_AUX_NJ_DEFAULT);
1667 itjc_write_1(TIGER_INT1_MASK, TIGER_ISAC_INT);
1668
1669 /*
1670 * From now on, almost like a `normal' ISIC driver.
1671 */
1672
1673 sc->sc_unit = unit;
1674
1675 ISAC_BASE = (caddr_t)ISIC_WHAT_ISAC;
1676
1677 HSCX_A_BASE = (caddr_t)ISIC_WHAT_HSCXA;
1678 HSCX_B_BASE = (caddr_t)ISIC_WHAT_HSCXB;
1679
1680 /* setup access routines */
1681
1682 sc->clearirq = NULL;
1683 sc->readreg = itjc_read_reg;
1684 sc->writereg = itjc_write_reg;
1685
1686 sc->readfifo = itjc_read_fifo;
1687 sc->writefifo = itjc_write_fifo;
1688
1689 /* setup card type */
1690
1691 sc->sc_cardtyp = CARD_TYPEP_NETJET_S;
1692
1693 /* setup IOM bus type */
1694
1695 sc->sc_bustyp = BUS_TYPE_IOM2;
1696
1697 /* set up some other miscellaneous things */
1698 sc->sc_ipac = 0;
1699 sc->sc_bfifolen = 2 * ITJC_RING_SLOT_WORDS;
1700
1701 printf("itjc%d: ISAC 2186 Version 1.1 (IOM-2)\n", unit);
1702
1703 /* init the ISAC */
1704 itjc_isac_init(sc);
1705
1706 /* init the "HSCX" */
1707 itjc_bchannel_setup(sc->sc_unit, HSCX_CH_A, BPROT_NONE, 0);
1708
1709 itjc_bchannel_setup(sc->sc_unit, HSCX_CH_B, BPROT_NONE, 0);
1710
1711 /* can't use the normal B-Channel stuff */
1712 itjc_init_linktab(sc);
1713
1714 /* set trace level */
1715
1716 sc->sc_trace = TRACE_OFF;
1717
1718 sc->sc_state = ISAC_IDLE;
1719
1720 sc->sc_ibuf = NULL;
1721 sc->sc_ib = NULL;
1722 sc->sc_ilen = 0;
1723
1724 sc->sc_obuf = NULL;
1725 sc->sc_op = NULL;
1726 sc->sc_ol = 0;
1727 sc->sc_freeflag = 0;
1728
1729 sc->sc_obuf2 = NULL;
1730 sc->sc_freeflag2 = 0;
1731
410d1df9
MD
1732 callout_init(&sc->sc_T3_timeout);
1733 callout_init(&sc->sc_T4_timeout);
984263bc
MD
1734
1735 /* init higher protocol layers */
1736
1737 i4b_l1_mph_status_ind(L0ITJCUNIT(sc->sc_unit), STI_ATTACH,
1738 sc->sc_cardtyp, &itjc_l1mux_func);
1739
817cdab6 1740 crit_exit();
984263bc
MD
1741 return 0;
1742
1743 fail:
1744 switch (res_init_level)
1745 {
1746 case 5:
1747 bus_dmamap_unload(ctx->tag, ctx->map);
1748 /* FALL TRHU */
1749
1750 case 4:
1751 bus_dmamem_free(ctx->tag, ctx->pool, ctx->map);
1752 bus_dmamap_destroy(ctx->tag, ctx->map);
1753 /* FALL TRHU */
1754
1755 case 3:
1756 bus_dma_tag_destroy(ctx->tag);
1757 /* FALL TRHU */
1758
1759 case 2:
1760 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_resources.irq);
1761 /* FALL TRHU */
1762
1763 case 1:
1764 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_MAPS+0,
1765 sc->sc_resources.io_base[0]);
1766 /* FALL TRHU */
1767
1768 case 0:
5b73dc76 1769 break;
984263bc
MD
1770 }
1771
1772 itjc_scp[unit] = NULL;
1773
817cdab6 1774 crit_exit();
984263bc
MD
1775 return error;
1776}
1777
1778
1779/*---------------------------------------------------------------------------*
1780 * itjc_intr - main interrupt service routine.
1781 *---------------------------------------------------------------------------*/
1782static void
1783itjc_intr(void *xsc)
1784{
1785 struct l1_softc *sc = xsc;
1786 l1_bchan_state_t *chan = &sc->sc_chan[0];
1787 dma_context_t *dma = &dma_context[sc->sc_unit];
1788 dma_rx_context_t *rxc = &dma_rx_context[sc->sc_unit][0];
1789 dma_tx_context_t *txc = &dma_tx_context[sc->sc_unit][0];
1790
018cf6f8
JS
1791 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
1792 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
984263bc
MD
1793
1794 /* Honor interrupts from successfully configured cards only. */
1795 if (dma->state < ITJC_DS_STOPPED)
1796 return;
1797
1798 /* First, we check the ISAC... */
1799 if (! (itjc_read_1(TIGER_AUX_PORT_DATA) & TIGER_ISAC_INT_MASK))
1800 {
1801 itjc_write_1(TIGER_INT1_STATUS, TIGER_ISAC_INT);
1802 NDBGL1(L1_H_IRQ, "ISAC");
1803 itjc_isac_intr(sc);
1804 }
1805
1806 /* ... after what we always have a look at the DMA rings. */
1807
1808 NDBGL1(L1_H_IRQ, "Tiger");
1809
1810 itjc_read_1(TIGER_INT0_STATUS);
1811 itjc_write_1(TIGER_INT0_STATUS, TIGER_TARGET_ABORT_INT
1812 | TIGER_MASTER_ABORT_INT | TIGER_RD_END_INT
1813 | TIGER_RD_INT_INT | TIGER_WR_END_INT | TIGER_WR_INT_INT);
1814
1815 itjc_dma_rx_intr(sc, chan, rxc);
1816 itjc_dma_tx_intr(sc, chan, txc);
1817
1818 ++chan; ++rxc; ++txc;
1819
1820 itjc_dma_rx_intr(sc, chan, rxc);
1821 itjc_dma_tx_intr(sc, chan, txc);
1822}
1823
1824
1825/*---------------------------------------------------------------------------*
1826 * itjc_bchannel_setup - (Re)initialize and start/stop a Bchannel.
1827 *---------------------------------------------------------------------------*/
1828static void
1829itjc_bchannel_setup(int unit, int h_chan, int bprot, int activate)
1830{
984263bc 1831 struct l1_softc *sc = itjc_scp[unit];
984263bc 1832 l1_bchan_state_t *chan = &sc->sc_chan[h_chan];
817cdab6
MD
1833
1834 crit_enter();
984263bc
MD
1835
1836 NDBGL1(L1_BCHAN, "unit=%d, channel=%d, %s",
1837 unit, h_chan, activate ? "activate" : "deactivate");
1838
1839 /*
1840 * If we are deactivating the channel, we have to stop
1841 * the DMA before we reset the channel control structures.
1842 */
1843 if (! activate)
1844 itjc_bchannel_dma_setup(sc, h_chan, activate);
1845
1846 /* general part */
1847
1848 chan->state = HSCX_IDLE;
1849
1850 chan->unit = sc->sc_unit; /* unit number */
1851 chan->channel = h_chan; /* B channel */
1852 chan->bprot = bprot; /* B channel protocol */
1853
1854 /* receiver part */
1855
1856 i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */
1857
1858 chan->rx_queue.ifq_maxlen = IFQ_MAXLEN;
1859
1860 chan->rxcount = 0; /* reset rx counter */
1861
1862 i4b_Bfreembuf(chan->in_mbuf); /* clean rx mbuf */
1863
1864 chan->in_mbuf = NULL; /* reset mbuf ptr */
1865 chan->in_cbptr = NULL; /* reset mbuf curr ptr */
1866 chan->in_len = 0; /* reset mbuf data len */
1867
1868 /* transmitter part */
1869
1870 i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */
1871
1872 chan->tx_queue.ifq_maxlen = IFQ_MAXLEN;
1873
1874 chan->txcount = 0; /* reset tx counter */
1875
1876 i4b_Bfreembuf(chan->out_mbuf_head); /* clean tx mbuf */
1877
1878 chan->out_mbuf_head = NULL; /* reset head mbuf ptr */
1879 chan->out_mbuf_cur = NULL; /* reset current mbuf ptr */
1880 chan->out_mbuf_cur_ptr = NULL; /* reset current mbuf data ptr */
1881 chan->out_mbuf_cur_len = 0; /* reset current mbuf data cnt */
1882
1883 /*
1884 * Only setup & start the DMA after all other channel
1885 * control structures are in place.
1886 */
1887 if (activate)
1888 itjc_bchannel_dma_setup(sc, h_chan, activate);
1889
817cdab6 1890 crit_exit();
984263bc
MD
1891}
1892
1893
1894/*---------------------------------------------------------------------------*
1895 * itjc_bchannel_start - Signal us we have more data to send.
1896 *---------------------------------------------------------------------------*/
1897static void
1898itjc_bchannel_start(int unit, int h_chan)
1899{
1900#if Buggy_code
1901 /*
1902 * I disabled this routine because it was causing crashes when
1903 * this driver was used with the ISP (kernel SPPP) protocol driver.
1904 * The scenario is reproductible:
1905 * Use the -link1 (dial on demand) ifconfig option.
1906 * Start an interactive TCP connection to somewhere.
1907 * Wait until the PPP connection times out and is dropped.
1908 * Try to send something on the TCP connection.
1909 * The machine will print some garbage and halt or reboot
1910 * (no panic messages).
1911 *
1912 * I've nailed down the problem to the fact that this routine
1913 * was being called before the B channel had been setup again.
1914 *
1915 * For now, I don't have a good solution other than this one.
1916 * But, don't despair. The impact of it is unnoticeable.
1917 */
1918
984263bc 1919 struct l1_softc *sc = itjc_scp[unit];
984263bc 1920 l1_bchan_state_t *chan = &sc->sc_chan[h_chan];
984263bc
MD
1921 dma_tx_context_t *txc = &dma_tx_context[unit][h_chan];
1922
817cdab6
MD
1923 crit_enter();
1924
984263bc
MD
1925 if (chan->state & HSCX_TX_ACTIVE)
1926 {
817cdab6 1927 crit_exit();
984263bc
MD
1928 return;
1929 }
1930
1931 itjc_dma_tx_intr(sc, chan, txc);
1932
817cdab6 1933 crit_exit();
984263bc
MD
1934#endif
1935}
1936
1937
1938/*---------------------------------------------------------------------------*
1939 * itjc_shutdown - Stop the driver and reset the card.
1940 *---------------------------------------------------------------------------*/
1941static void
1942itjc_shutdown(device_t dev)
1943{
1944 struct l1_softc *sc = device_get_softc(dev);
018cf6f8
JS
1945 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
1946 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
984263bc
MD
1947
1948 /*
1949 * Stop the DMA the nice and easy way.
1950 */
1951 itjc_bchannel_setup(sc->sc_unit, 0, BPROT_NONE, 0);
1952 itjc_bchannel_setup(sc->sc_unit, 1, BPROT_NONE, 0);
1953
1954 /*
1955 * Reset the card.
1956 */
1957 itjc_write_1(TIGER_RESET_PIB_CL_TIME, TIGER_RESET_ALL);
1958
1959 DELAY(SEC_DELAY/100); /* Give it 10 ms to reset ...*/
1960
1961 itjc_write_1(TIGER_RESET_PIB_CL_TIME,
1962 TIGER_SELF_ADDR_DMA | TIGER_LATCH_DMA_INT | TIGER_PIB_3_CYCLES);
1963
1964 DELAY(SEC_DELAY/100); /* ... and more 10 to recover */
1965}
1966
1967
1968/*---------------------------------------------------------------------------*
1969 * itjc_ret_linktab - Return the address of itjc drivers linktab.
1970 *---------------------------------------------------------------------------*/
1971isdn_link_t *
1972itjc_ret_linktab(int unit, int channel)
1973{
984263bc 1974 struct l1_softc *sc = itjc_scp[unit];
984263bc
MD
1975 l1_bchan_state_t *chan = &sc->sc_chan[channel];
1976
1977 return(&chan->isic_isdn_linktab);
1978}
1979
1980/*---------------------------------------------------------------------------*
1981 * itjc_set_linktab - Set the driver linktab in the b channel softc.
1982 *---------------------------------------------------------------------------*/
1983void
1984itjc_set_linktab(int unit, int channel, drvr_link_t *dlt)
1985{
984263bc 1986 struct l1_softc *sc = itjc_scp[unit];
984263bc
MD
1987 l1_bchan_state_t *chan = &sc->sc_chan[channel];
1988
1989 chan->isic_drvr_linktab = dlt;
1990}
1991
1992
1993/*---------------------------------------------------------------------------*
1994 * itjc_init_linktab - Initialize our local linktab.
1995 *---------------------------------------------------------------------------*/
1996static void
1997itjc_init_linktab(struct l1_softc *sc)
1998{
1999 l1_bchan_state_t *chan = &sc->sc_chan[HSCX_CH_A];
2000 isdn_link_t *lt = &chan->isic_isdn_linktab;
2001
2002 /* make sure the hardware driver is known to layer 4 */
2003 /* avoid overwriting if already set */
2004 if (ctrl_types[CTRL_PASSIVE].set_linktab == NULL)
2005 {
2006 ctrl_types[CTRL_PASSIVE].set_linktab = itjc_set_linktab;
2007 ctrl_types[CTRL_PASSIVE].get_linktab = itjc_ret_linktab;
2008 }
2009
2010 /* local setup */
2011 lt->unit = sc->sc_unit;
2012 lt->channel = HSCX_CH_A;
2013 lt->bch_config = itjc_bchannel_setup;
2014 lt->bch_tx_start = itjc_bchannel_start;
2015 lt->bch_stat = itjc_bchannel_stat;
2016 lt->tx_queue = &chan->tx_queue;
2017
2018 /* used by non-HDLC data transfers, i.e. telephony drivers */
2019 lt->rx_queue = &chan->rx_queue;
2020
2021 /* used by HDLC data transfers, i.e. ipr and isp drivers */
2022 lt->rx_mbuf = &chan->in_mbuf;
2023
2024 chan = &sc->sc_chan[HSCX_CH_B];
2025 lt = &chan->isic_isdn_linktab;
2026
2027 lt->unit = sc->sc_unit;
2028 lt->channel = HSCX_CH_B;
2029 lt->bch_config = itjc_bchannel_setup;
2030 lt->bch_tx_start = itjc_bchannel_start;
2031 lt->bch_stat = itjc_bchannel_stat;
2032 lt->tx_queue = &chan->tx_queue;
2033
2034 /* used by non-HDLC data transfers, i.e. telephony drivers */
2035 lt->rx_queue = &chan->rx_queue;
2036
2037 /* used by HDLC data transfers, i.e. ipr and isp drivers */
2038 lt->rx_mbuf = &chan->in_mbuf;
2039}
2040
2041
2042/*---------------------------------------------------------------------------*
2043 * itjc_bchannel_stat - Collect link statistics for a given B channel.
2044 *---------------------------------------------------------------------------*/
2045static void
2046itjc_bchannel_stat(int unit, int h_chan, bchan_statistics_t *bsp)
2047{
984263bc 2048 struct l1_softc *sc = itjc_scp[unit];
984263bc 2049 l1_bchan_state_t *chan = &sc->sc_chan[h_chan];
984263bc 2050
817cdab6 2051 crit_enter();
984263bc
MD
2052
2053 bsp->outbytes = chan->txcount;
2054 bsp->inbytes = chan->rxcount;
2055
2056 chan->txcount = 0;
2057 chan->rxcount = 0;
2058
817cdab6 2059 crit_exit();
984263bc
MD
2060}
2061
2062
2063/*---------------------------------------------------------------------------*
2064 * Netjet - ISAC interrupt routine.
2065 *---------------------------------------------------------------------------*/
2066static void
2067itjc_isac_intr(struct l1_softc *sc)
2068{
6de3da81 2069 u_char irq_stat;
984263bc
MD
2070
2071 do
2072 {
2073 /* get isac irq status */
2074 irq_stat = ISAC_READ(I_ISTA);
2075
2076 if(irq_stat)
2077 itjc_isac_irq(sc, irq_stat); /* isac handler */
2078 }
2079 while(irq_stat);
2080
2081 ISAC_WRITE(I_MASK, 0xff);
2082
2083 DELAY(100);
2084
2085 ISAC_WRITE(I_MASK, ISAC_IMASK);
2086}
2087
2088
2089/*---------------------------------------------------------------------------*
2090 * itjc_recover - Try to recover from ISAC irq lockup.
2091 *---------------------------------------------------------------------------*/
2092void
2093itjc_recover(struct l1_softc *sc)
2094{
2095 u_char byte;
2096
2097 /* get isac irq status */
2098
2099 byte = ISAC_READ(I_ISTA);
2100
2101 NDBGL1(L1_ERROR, " ISAC: ISTA = 0x%x", byte);
2102
2103 if(byte & ISAC_ISTA_EXI)
2104 NDBGL1(L1_ERROR, " ISAC: EXIR = 0x%x", (u_char)ISAC_READ(I_EXIR));
2105
2106 if(byte & ISAC_ISTA_CISQ)
2107 {
2108 byte = ISAC_READ(I_CIRR);
2109
2110 NDBGL1(L1_ERROR, " ISAC: CISQ = 0x%x", byte);
2111
2112 if(byte & ISAC_CIRR_SQC)
2113 NDBGL1(L1_ERROR, " ISAC: SQRR = 0x%x", (u_char)ISAC_READ(I_SQRR));
2114 }
2115
2116 NDBGL1(L1_ERROR, " ISAC: IMASK = 0x%x", ISAC_IMASK);
2117
2118 ISAC_WRITE(I_MASK, 0xff);
2119 DELAY(100);
2120 ISAC_WRITE(I_MASK, ISAC_IMASK);
2121}
2122
2123#endif /* NITJC > 0 */