Fix up mix of man(7)/mdoc(7).
[netbsd-mini2440.git] / sys / netisdn / i4b_isppp.c
blob284569c2595d3fafd7ad4228b81dcee363ed48d1
1 /*
2 * Copyright (c) 1997 Joerg Wunsch. All rights reserved.
4 * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
28 *---------------------------------------------------------------------------
30 * i4b_isppp.c - isdn4bsd kernel SyncPPP driver
31 * --------------------------------------------
33 * Uses Serge Vakulenko's sppp backend (originally contributed with
34 * the "cx" driver for Cronyx's HDLC-in-hardware device). This driver
35 * is only the glue between sppp and i4b.
37 * $Id: i4b_isppp.c,v 1.25 2009/03/18 10:22:43 cegger Exp $
39 * $FreeBSD$
41 * last edit-date: [Fri Jan 5 11:33:47 2001]
43 *---------------------------------------------------------------------------*/
45 #include <sys/cdefs.h>
46 __KERNEL_RCSID(0, "$NetBSD: i4b_isppp.c,v 1.24 2008/05/23 14:10:50 he Exp $");
48 #ifndef __NetBSD__
49 #define USE_ISPPP
50 #endif
51 #include "ippp.h"
53 #ifndef USE_ISPPP
55 #ifdef __FreeBSD__
56 #include "sppp.h"
57 #endif
59 #ifndef __NetBSD__
60 #if NI4BISPPP == 0
61 # error "You need to define `pseudo-device sppp <N>' with options ISPPP"
62 #endif
63 #endif
65 #endif
67 #include <sys/param.h>
69 * XXX - sys/param.h on alpha (indirectly) includes sys/signal.h, which
70 * defines sc_sp - interfering with our use of this identifier.
71 * Just undef it for now.
73 #undef sc_sp
75 #include <sys/systm.h>
76 #include <sys/mbuf.h>
77 #include <sys/socket.h>
78 #include <sys/errno.h>
79 #include <sys/ioccom.h>
80 #include <sys/sockio.h>
81 #include <sys/kernel.h>
82 #include <sys/protosw.h>
83 #include <sys/callout.h>
85 #include <net/if.h>
86 #include <net/if_types.h>
87 #include <net/netisr.h>
88 #include <net/route.h>
90 #include <netinet/in.h>
91 #include <netinet/in_systm.h>
92 #include <netinet/in_var.h>
93 #include <netinet/ip.h>
95 #include <net/slcompress.h>
97 #include <net/if_spppvar.h>
99 #if defined(__FreeBSD_version) && __FreeBSD_version >= 400008
100 #include "bpf.h"
101 #else
102 #include "bpfilter.h"
103 #endif
104 #if NBPFILTER > 0 || NBPF > 0
105 #include <sys/time.h>
106 #include <net/bpf.h>
107 #endif
109 #ifdef __FreeBSD__
110 #include <machine/i4b_ioctl.h>
111 #include <machine/i4b_cause.h>
112 #include <machine/i4b_debug.h>
113 #else
114 #include <netisdn/i4b_ioctl.h>
115 #include <netisdn/i4b_cause.h>
116 #include <netisdn/i4b_debug.h>
117 #endif
119 #include <netisdn/i4b_global.h>
120 #include <netisdn/i4b_mbuf.h>
121 #include <netisdn/i4b_l3l4.h>
123 #include <netisdn/i4b_l4.h>
125 #ifdef __FreeBSD__
126 #define ISPPP_FMT "ippp%d: "
127 #define ISPPP_ARG(sc) ((sc)->sc_if.if_unit)
128 #define PDEVSTATIC static
130 # if __FreeBSD_version >= 300001
131 # define CALLOUT_INIT(chan) callout_handle_init(chan)
132 # define TIMEOUT(fun, arg, chan, tick) chan = timeout(fun, arg, tick)
133 # define UNTIMEOUT(fun, arg, chan) untimeout(fun, arg, chan)
134 # define IOCTL_CMD_T u_long
135 # else
136 # define CALLOUT_INIT(chan) do {} while(0)
137 # define TIMEOUT(fun, arg, chan, tick) timeout(fun, arg, tick)
138 # define UNTIMEOUT(fun, arg, chan) untimeout(fun, arg)
139 # define IOCTL_CMD_T int
140 # endif
142 #elif defined __NetBSD__ || defined __OpenBSD__
143 #define ISPPP_FMT "%s: "
144 #define ISPPP_ARG(sc) ((sc)->sc_sp.pp_if.if_xname)
145 #define PDEVSTATIC /* not static */
146 #define IOCTL_CMD_T u_long
147 #else
148 # error "What system are you using?"
149 #endif
151 #ifdef __FreeBSD__
152 PDEVSTATIC void ipppattach(void *);
153 PSEUDO_SET(ipppattach, i4b_isppp);
154 #else
155 PDEVSTATIC void ipppattach(void);
156 #endif
158 #define I4BISPPPACCT 1 /* enable accounting messages */
159 #define I4BISPPPACCTINTVL 2 /* accounting msg interval in secs */
160 #define I4BISPPPDISCDEBUG 1
162 #define PPP_HDRLEN 4 /* 4 octetts PPP header length */
164 struct i4bisppp_softc {
165 struct sppp sc_sp; /* we are derived from struct sppp */
167 int sc_state; /* state of the interface */
169 #ifndef __FreeBSD__
170 int sc_unit; /* unit number for Net/OpenBSD */
171 #endif
173 call_desc_t *sc_cdp; /* ptr to call descriptor */
174 isdn_link_t *sc_ilt; /* B channel driver and state */
176 #ifdef I4BISPPPACCT
177 int sc_iinb; /* isdn driver # of inbytes */
178 int sc_ioutb; /* isdn driver # of outbytes */
179 int sc_inb; /* # of bytes rx'd */
180 int sc_outb; /* # of bytes tx'd */
181 int sc_linb; /* last # of bytes rx'd */
182 int sc_loutb; /* last # of bytes tx'd */
183 int sc_fn; /* flag, first null acct */
184 #endif
186 #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001
187 struct callout_handle sc_ch;
188 #endif
190 } i4bisppp_softc[NIPPP];
192 static int i4bisppp_ioctl(struct ifnet *ifp, IOCTL_CMD_T cmd, void *data);
194 #if 0
195 static void i4bisppp_send(struct ifnet *ifp);
196 #endif
198 static void i4bisppp_start(struct ifnet *ifp);
200 #if 0 /* never used ??? */
201 static void i4bisppp_timeout(void *cookie);
202 #endif
204 static void i4bisppp_tls(struct sppp *sp);
205 static void i4bisppp_tlf(struct sppp *sp);
206 static void i4bisppp_state_changed(struct sppp *sp, int new_state);
207 static void i4bisppp_negotiation_complete(struct sppp *sp);
208 static void i4bisppp_watchdog(struct ifnet *ifp);
209 time_t i4bisppp_idletime(void *softc);
210 static void i4bisppp_rx_data_rdy(void *softc);
211 static void i4bisppp_tx_queue_empty(void *softc);
212 static void i4bisppp_activity(void *softc, int rxtx);
213 static void i4bisppp_connect(void *softc, void *cdp);
214 static void i4bisppp_disconnect(void *softc, void *cdp);
215 static void i4bisppp_dialresponse(void *softc, int status, cause_t cause);
216 static void i4bisppp_updown(void *softc, int updown);
217 static void* i4bisppp_ret_softc(int unit);
218 static void i4bisppp_set_linktab(void *softc, isdn_link_t *ilt);
220 static const struct isdn_l4_driver_functions
221 ippp_l4_functions = {
222 /* L4<->B-channel functions */
223 i4bisppp_rx_data_rdy,
224 i4bisppp_tx_queue_empty,
225 i4bisppp_activity,
226 i4bisppp_connect,
227 i4bisppp_disconnect,
228 i4bisppp_dialresponse,
229 i4bisppp_updown,
230 /* Management functions */
231 i4bisppp_ret_softc,
232 i4bisppp_set_linktab,
233 i4bisppp_idletime
236 static int ippp_drvr_id = -1;
238 enum i4bisppp_states {
239 ST_IDLE, /* initialized, ready, idle */
240 ST_DIALING, /* dialling out to remote */
241 ST_CONNECTED, /* connected to remote */
244 /*===========================================================================*
245 * DEVICE DRIVER ROUTINES
246 *===========================================================================*/
248 /*---------------------------------------------------------------------------*
249 * interface attach routine at kernel boot time
250 *---------------------------------------------------------------------------*/
251 PDEVSTATIC void
252 #ifdef __FreeBSD__
253 ipppattach(void *dummy)
254 #else
255 ipppattach(void)
256 #endif
258 struct i4bisppp_softc *sc = i4bisppp_softc;
259 int i;
261 ippp_drvr_id = isdn_l4_driver_attach("ippp", NIPPP, &ippp_l4_functions);
263 for(i = 0; i < NIPPP; sc++, i++) {
264 sc->sc_sp.pp_if.if_softc = sc;
265 sc->sc_ilt = NULL;
267 #ifdef __FreeBSD__
268 sc->sc_sp.pp_if.if_name = "ippp";
269 #if defined(__FreeBSD_version) && __FreeBSD_version < 300001
270 sc->sc_sp.pp_if.if_next = NULL;
271 #endif
272 sc->sc_sp.pp_if.if_unit = i;
273 #else
274 snprintf(sc->sc_sp.pp_if.if_xname,
275 sizeof(sc->sc_sp.pp_if.if_xname), "ippp%d", i);
276 sc->sc_unit = i;
277 #endif
279 sc->sc_sp.pp_if.if_mtu = PP_MTU;
281 #ifdef __NetBSD__
282 sc->sc_sp.pp_if.if_flags = IFF_SIMPLEX | IFF_POINTOPOINT |
283 IFF_MULTICAST;
284 #else
285 sc->sc_sp.pp_if.if_flags = IFF_SIMPLEX | IFF_POINTOPOINT;
286 #endif
288 sc->sc_sp.pp_if.if_type = IFT_ISDNBASIC;
289 sc->sc_state = ST_IDLE;
291 sc->sc_sp.pp_if.if_ioctl = i4bisppp_ioctl;
293 /* actually initialized by sppp_attach() */
294 /* sc->sc_sp.pp_if.if_output = sppp_output; */
296 sc->sc_sp.pp_if.if_start = i4bisppp_start;
298 sc->sc_sp.pp_if.if_hdrlen = 0;
299 sc->sc_sp.pp_if.if_addrlen = 0;
300 IFQ_SET_MAXLEN(&sc->sc_sp.pp_if.if_snd, IFQ_MAXLEN);
301 IFQ_SET_READY(&sc->sc_sp.pp_if.if_snd);
303 sc->sc_sp.pp_if.if_ipackets = 0;
304 sc->sc_sp.pp_if.if_ierrors = 0;
305 sc->sc_sp.pp_if.if_opackets = 0;
306 sc->sc_sp.pp_if.if_oerrors = 0;
307 sc->sc_sp.pp_if.if_collisions = 0;
308 sc->sc_sp.pp_if.if_ibytes = 0;
309 sc->sc_sp.pp_if.if_obytes = 0;
310 sc->sc_sp.pp_if.if_imcasts = 0;
311 sc->sc_sp.pp_if.if_omcasts = 0;
312 sc->sc_sp.pp_if.if_iqdrops = 0;
313 sc->sc_sp.pp_if.if_noproto = 0;
315 #if I4BISPPPACCT
316 sc->sc_sp.pp_if.if_timer = 0;
317 sc->sc_sp.pp_if.if_watchdog = i4bisppp_watchdog;
318 sc->sc_iinb = 0;
319 sc->sc_ioutb = 0;
320 sc->sc_inb = 0;
321 sc->sc_outb = 0;
322 sc->sc_linb = 0;
323 sc->sc_loutb = 0;
324 sc->sc_fn = 1;
325 #endif
327 sc->sc_sp.pp_tls = i4bisppp_tls;
328 sc->sc_sp.pp_tlf = i4bisppp_tlf;
329 sc->sc_sp.pp_con = i4bisppp_negotiation_complete;
330 sc->sc_sp.pp_chg = i4bisppp_state_changed;
331 sc->sc_sp.pp_framebytes = 0; /* no framing added by hardware */
333 #if defined(__FreeBSD_version) && ((__FreeBSD_version >= 500009) || (410000 <= __FreeBSD_version && __FreeBSD_version < 500000))
334 /* do not call bpfattach in ether_ifattach */
335 ether_ifattach(&sc->sc_sp.pp_if, 0);
336 #else
337 if_attach(&sc->sc_sp.pp_if);
338 #endif
339 #ifndef USE_ISPPP
340 sppp_attach(&sc->sc_sp.pp_if);
341 #else
342 isppp_attach(&sc->sc_sp.pp_if);
343 #endif
345 #if NBPFILTER > 0 || NBPF > 0
346 #ifdef __FreeBSD__
347 bpfattach(&sc->sc_sp.pp_if, DLT_PPP, PPP_HDRLEN);
348 CALLOUT_INIT(&sc->sc_ch);
349 #endif /* __FreeBSD__ */
350 #ifdef __NetBSD__
351 bpfattach(&sc->sc_sp.pp_if, DLT_PPP, sizeof(u_int));
352 #endif
353 #endif
357 /*---------------------------------------------------------------------------*
358 * process ioctl
359 *---------------------------------------------------------------------------*/
360 static int
361 i4bisppp_ioctl(struct ifnet *ifp, unsigned long cmd, void *data)
363 struct i4bisppp_softc *sc = ifp->if_softc;
365 #ifndef USE_ISPPP
366 return sppp_ioctl(&sc->sc_sp.pp_if, cmd, data);
367 #else
368 return isppp_ioctl(&sc->sc_sp.pp_if, cmd, data);
369 #endif
372 /*---------------------------------------------------------------------------*
373 * start output to ISDN B-channel
374 *---------------------------------------------------------------------------*/
375 static void
376 i4bisppp_start(struct ifnet *ifp)
378 struct i4bisppp_softc *sc = ifp->if_softc;
379 struct mbuf *m;
381 #ifndef USE_ISPPP
382 if (sppp_isempty(ifp))
383 #else
384 if (isppp_isempty(ifp))
385 #endif
386 return;
388 if(sc->sc_state != ST_CONNECTED)
389 return;
392 * s = splnet();
393 * ifp->if_flags |= IFF_OACTIVE; // - need to clear this somewhere
394 * splx(s);
397 #ifndef USE_ISPPP
398 while ((m = sppp_dequeue(&sc->sc_sp.pp_if)) != NULL)
399 #else
400 while ((m = isppp_dequeue(&sc->sc_sp.pp_if)) != NULL)
401 #endif
404 #if NBPFILTER > 0 || NBPF > 0
405 #ifdef __FreeBSD__
406 if (ifp->if_bpf)
407 bpf_mtap(ifp, m);
408 #endif /* __FreeBSD__ */
410 #ifdef __NetBSD__
411 if (ifp->if_bpf)
412 bpf_mtap(ifp->if_bpf, m);
413 #endif
414 #endif /* NBPFILTER > 0 || NBPF > 0 */
416 if(IF_QFULL(sc->sc_ilt->tx_queue))
418 NDBGL4(L4_ISPDBG, "%s, tx queue full!", sc->sc_sp.pp_if.if_xname);
419 m_freem(m);
421 else
423 IF_ENQUEUE(sc->sc_ilt->tx_queue, m);
424 #if 0
425 sc->sc_sp.pp_if.if_obytes += m->m_pkthdr.len;
426 #endif
427 sc->sc_outb += m->m_pkthdr.len;
428 sc->sc_sp.pp_if.if_opackets++;
431 sc->sc_ilt->bchannel_driver->bch_tx_start(sc->sc_ilt->l1token,
432 sc->sc_ilt->channel);
435 #ifdef I4BISPPPACCT
436 /*---------------------------------------------------------------------------*
437 * watchdog routine
438 *---------------------------------------------------------------------------*/
439 static void
440 i4bisppp_watchdog(struct ifnet *ifp)
442 struct i4bisppp_softc *sc = ifp->if_softc;
443 bchan_statistics_t bs;
445 (*sc->sc_ilt->bchannel_driver->bch_stat)
446 (sc->sc_ilt->l1token, sc->sc_ilt->channel, &bs);
448 sc->sc_ioutb += bs.outbytes;
449 sc->sc_iinb += bs.inbytes;
451 if((sc->sc_iinb != sc->sc_linb) || (sc->sc_ioutb != sc->sc_loutb) || sc->sc_fn)
453 int ri = (sc->sc_iinb - sc->sc_linb)/I4BISPPPACCTINTVL;
454 int ro = (sc->sc_ioutb - sc->sc_loutb)/I4BISPPPACCTINTVL;
456 if((sc->sc_iinb == sc->sc_linb) && (sc->sc_ioutb == sc->sc_loutb))
457 sc->sc_fn = 0;
458 else
459 sc->sc_fn = 1;
461 sc->sc_linb = sc->sc_iinb;
462 sc->sc_loutb = sc->sc_ioutb;
464 if (sc->sc_cdp)
465 i4b_l4_accounting(sc->sc_cdp->cdid, ACCT_DURING,
466 sc->sc_ioutb, sc->sc_iinb, ro, ri, sc->sc_outb, sc->sc_inb);
468 sc->sc_sp.pp_if.if_timer = I4BISPPPACCTINTVL;
470 #if 0 /* old stuff, keep it around */
471 printf(ISPPP_FMT "transmit timeout\n", ISPPP_ARG(sc));
472 i4bisppp_start(ifp);
473 #endif
475 #endif /* I4BISPPPACCT */
478 *===========================================================================*
479 * SyncPPP layer interface routines
480 *===========================================================================*
483 /*---------------------------------------------------------------------------*
484 * PPP this-layer-started action
485 *---------------------------------------------------------------------------*
487 static void
488 i4bisppp_tls(struct sppp *sp)
490 struct i4bisppp_softc *sc = sp->pp_if.if_softc;
492 if(sc->sc_state == ST_CONNECTED)
493 return;
495 i4b_l4_dialout(ippp_drvr_id, sc->sc_unit);
498 /*---------------------------------------------------------------------------*
499 * PPP this-layer-finished action
500 *---------------------------------------------------------------------------*
502 static void
503 i4bisppp_tlf(struct sppp *sp)
505 struct i4bisppp_softc *sc = sp->pp_if.if_softc;
507 if(sc->sc_state != ST_CONNECTED)
508 return;
510 i4b_l4_drvrdisc(sc->sc_cdp->cdid);
512 /*---------------------------------------------------------------------------*
513 * PPP interface phase change
514 *---------------------------------------------------------------------------*
516 static void
517 i4bisppp_state_changed(struct sppp *sp, int new_state)
519 struct i4bisppp_softc *sc = sp->pp_if.if_softc;
521 i4b_l4_ifstate_changed(sc->sc_cdp, new_state);
524 /*---------------------------------------------------------------------------*
525 * PPP control protocol negotiation complete (run ip-up script now)
526 *---------------------------------------------------------------------------*
528 static void
529 i4bisppp_negotiation_complete(struct sppp *sp)
531 struct i4bisppp_softc *sc = sp->pp_if.if_softc;
533 i4b_l4_negcomplete(sc->sc_cdp);
536 /*===========================================================================*
537 * ISDN INTERFACE ROUTINES
538 *===========================================================================*/
540 /*---------------------------------------------------------------------------*
541 * this routine is called from L4 handler at connect time
542 *---------------------------------------------------------------------------*/
543 static void
544 i4bisppp_connect(void *softc, void *cdp)
546 struct i4bisppp_softc *sc = softc;
547 struct sppp *sp = &sc->sc_sp;
548 int s = splnet();
550 sc->sc_cdp = (call_desc_t *)cdp;
551 sc->sc_state = ST_CONNECTED;
553 #if I4BISPPPACCT
554 sc->sc_iinb = 0;
555 sc->sc_ioutb = 0;
556 sc->sc_inb = 0;
557 sc->sc_outb = 0;
558 sc->sc_linb = 0;
559 sc->sc_loutb = 0;
560 sc->sc_sp.pp_if.if_timer = I4BISPPPACCTINTVL;
561 #endif
563 #if 0 /* never used ??? */
564 UNTIMEOUT(i4bisppp_timeout, (void *)sp, sc->sc_ch);
565 #endif
567 sp->pp_up(sp); /* tell PPP we are ready */
568 #ifndef __NetBSD__
569 sp->pp_last_sent = sp->pp_last_recv = SECOND;
570 #endif
571 splx(s);
574 /*---------------------------------------------------------------------------*
575 * this routine is called from L4 handler at disconnect time
576 *---------------------------------------------------------------------------*/
577 static void
578 i4bisppp_disconnect(void *softc, void *cdp)
580 call_desc_t *cd = (call_desc_t *)cdp;
581 struct i4bisppp_softc *sc = softc;
582 struct sppp *sp = &sc->sc_sp;
584 int s = splnet();
586 /* new stuff to check that the active channel is being closed */
587 if (cd != sc->sc_cdp)
589 NDBGL4(L4_ISPDBG, "%s: channel%d not active!", sp->pp_if.if_xname,
590 cd->channelid);
591 splx(s);
592 return;
595 #if I4BISPPPACCT
596 sc->sc_sp.pp_if.if_timer = 0;
597 #endif
599 i4b_l4_accounting(cd->cdid, ACCT_FINAL,
600 sc->sc_ioutb, sc->sc_iinb, 0, 0, sc->sc_outb, sc->sc_inb);
602 if (sc->sc_state == ST_CONNECTED)
604 #if 0 /* never used ??? */
605 UNTIMEOUT(i4bisppp_timeout, (void *)sp, sc->sc_ch);
606 #endif
607 sc->sc_cdp = (call_desc_t *)0;
608 /* do thhis here because pp_down calls i4bisppp_tlf */
609 sc->sc_state = ST_IDLE;
610 sp->pp_down(sp); /* tell PPP we have hung up */
613 splx(s);
616 /*---------------------------------------------------------------------------*
617 * this routine is used to give a feedback from userland demon
618 * in case of dial problems
619 *---------------------------------------------------------------------------*/
620 static void
621 i4bisppp_dialresponse(void *softc, int status, cause_t cause)
623 struct i4bisppp_softc *sc = softc;
625 NDBGL4(L4_ISPDBG, "%s: status=%d, cause=%d", sc->sc_sp.pp_if.if_xname, status, cause);
627 if(status != DSTAT_NONE)
629 struct mbuf *m;
631 NDBGL4(L4_ISPDBG, "%s: clearing queues", sc->sc_sp.pp_if.if_xname);
633 #ifndef USE_ISPPP
634 if(!(sppp_isempty(&sc->sc_sp.pp_if)))
635 #else
636 if(!(isppp_isempty(&sc->sc_sp.pp_if)))
637 #endif
639 #ifndef USE_ISPPP
640 while((m = sppp_dequeue(&sc->sc_sp.pp_if)) != NULL)
641 #else
642 while((m = isppp_dequeue(&sc->sc_sp.pp_if)) != NULL)
643 #endif
644 m_freem(m);
649 /*---------------------------------------------------------------------------*
650 * interface up/down
651 *---------------------------------------------------------------------------*/
652 static void
653 i4bisppp_updown(void *softc, int updown)
655 (void)softc;
656 (void)updown;
657 /* could probably do something useful here */
660 /*---------------------------------------------------------------------------*
661 * this routine is called from the HSCX interrupt handler
662 * when a new frame (mbuf) has been received and was put on
663 * the rx queue.
664 *---------------------------------------------------------------------------*/
665 static void
666 i4bisppp_rx_data_rdy(void *softc)
668 struct i4bisppp_softc *sc = softc;
669 struct mbuf *m;
670 int s;
672 if((m = *sc->sc_ilt->rx_mbuf) == NULL)
673 return;
675 m->m_pkthdr.rcvif = &sc->sc_sp.pp_if;
676 m->m_pkthdr.len = m->m_len;
678 sc->sc_sp.pp_if.if_ipackets++;
680 #if I4BISPPPACCT
681 sc->sc_inb += m->m_pkthdr.len;
682 #endif
684 #ifdef I4BISPPPDEBUG
685 printf("i4bisppp_rx_data_ready: received packet!\n");
686 #endif
688 #if NBPFILTER > 0 || NBPF > 0
690 #ifdef __FreeBSD__
691 if(sc->sc_sp.pp_if.if_bpf)
692 bpf_mtap(&sc->sc_sp.pp_if, m);
693 #endif /* __FreeBSD__ */
695 #ifdef __NetBSD__
696 if(sc->sc_sp.pp_if.if_bpf)
697 bpf_mtap(sc->sc_sp.pp_if.if_bpf, m);
698 #endif
700 #endif /* NBPFILTER > 0 || NBPF > 0 */
702 s = splnet();
704 #ifndef USE_ISPPP
705 sppp_input(&sc->sc_sp.pp_if, m);
706 #else
707 isppp_input(&sc->sc_sp.pp_if, m);
708 #endif
710 splx(s);
713 /*---------------------------------------------------------------------------*
714 * this routine is called from the HSCX interrupt handler
715 * when the last frame has been sent out and there is no
716 * further frame (mbuf) in the tx queue.
717 *---------------------------------------------------------------------------*/
718 static void
719 i4bisppp_tx_queue_empty(void *softc)
721 struct sppp *sp = &((struct i4bisppp_softc *)softc)->sc_sp;
722 i4bisppp_start(&sp->pp_if);
725 /*---------------------------------------------------------------------------*
726 * THIS should be used instead of last_active_time to implement
727 * an activity timeout mechanism.
729 * Sending back the time difference unneccessarily complicates the
730 * idletime checks in i4b_l4.c. Return the largest time instead.
731 * That way the code in i4b_l4.c needs only minimal changes.
732 *---------------------------------------------------------------------------*/
733 time_t
734 i4bisppp_idletime(void *softc)
736 struct sppp *sp = &((struct i4bisppp_softc *)softc)->sc_sp;
738 return sp->pp_last_activity;
741 /*---------------------------------------------------------------------------*
742 * this routine is called from the HSCX interrupt handler
743 * each time a packet is received or transmitted. It should
744 * be used to implement an activity timeout mechanism.
745 *---------------------------------------------------------------------------*/
746 static void
747 i4bisppp_activity(void *softc, int rxtx)
749 struct i4bisppp_softc *sc = softc;
750 sc->sc_cdp->last_active_time = SECOND;
753 /*---------------------------------------------------------------------------*
754 * return this drivers linktab address
755 *---------------------------------------------------------------------------*/
756 static void *
757 i4bisppp_ret_softc(int unit)
759 return &i4bisppp_softc[unit];
762 /*---------------------------------------------------------------------------*
763 * setup the isdn_linktab for this driver
764 *---------------------------------------------------------------------------*/
765 static void
766 i4bisppp_set_linktab(void *softc, isdn_link_t *ilt)
768 struct i4bisppp_softc *sc = softc;
769 sc->sc_ilt = ilt;
772 /*===========================================================================*/