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
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
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 $
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 $");
61 # error "You need to define `pseudo-device sppp <N>' with options ISPPP"
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.
75 #include <sys/systm.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>
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
102 #include "bpfilter.h"
104 #if NBPFILTER > 0 || NBPF > 0
105 #include <sys/time.h>
110 #include <machine/i4b_ioctl.h>
111 #include <machine/i4b_cause.h>
112 #include <machine/i4b_debug.h>
114 #include <netisdn/i4b_ioctl.h>
115 #include <netisdn/i4b_cause.h>
116 #include <netisdn/i4b_debug.h>
119 #include <netisdn/i4b_global.h>
120 #include <netisdn/i4b_mbuf.h>
121 #include <netisdn/i4b_l3l4.h>
123 #include <netisdn/i4b_l4.h>
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
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
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
148 # error "What system are you using?"
152 PDEVSTATIC
void ipppattach(void *);
153 PSEUDO_SET(ipppattach
, i4b_isppp
);
155 PDEVSTATIC
void ipppattach(void);
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 */
170 int sc_unit
; /* unit number for Net/OpenBSD */
173 call_desc_t
*sc_cdp
; /* ptr to call descriptor */
174 isdn_link_t
*sc_ilt
; /* B channel driver and state */
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 */
186 #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001
187 struct callout_handle sc_ch
;
190 } i4bisppp_softc
[NIPPP
];
192 static int i4bisppp_ioctl(struct ifnet
*ifp
, IOCTL_CMD_T cmd
, void *data
);
195 static void i4bisppp_send(struct ifnet
*ifp
);
198 static void i4bisppp_start(struct ifnet
*ifp
);
200 #if 0 /* never used ??? */
201 static void i4bisppp_timeout(void *cookie
);
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
,
228 i4bisppp_dialresponse
,
230 /* Management functions */
232 i4bisppp_set_linktab
,
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 *---------------------------------------------------------------------------*/
253 ipppattach(void *dummy
)
258 struct i4bisppp_softc
*sc
= i4bisppp_softc
;
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
;
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
;
272 sc
->sc_sp
.pp_if
.if_unit
= i
;
274 snprintf(sc
->sc_sp
.pp_if
.if_xname
,
275 sizeof(sc
->sc_sp
.pp_if
.if_xname
), "ippp%d", i
);
279 sc
->sc_sp
.pp_if
.if_mtu
= PP_MTU
;
282 sc
->sc_sp
.pp_if
.if_flags
= IFF_SIMPLEX
| IFF_POINTOPOINT
|
285 sc
->sc_sp
.pp_if
.if_flags
= IFF_SIMPLEX
| IFF_POINTOPOINT
;
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;
316 sc
->sc_sp
.pp_if
.if_timer
= 0;
317 sc
->sc_sp
.pp_if
.if_watchdog
= i4bisppp_watchdog
;
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);
337 if_attach(&sc
->sc_sp
.pp_if
);
340 sppp_attach(&sc
->sc_sp
.pp_if
);
342 isppp_attach(&sc
->sc_sp
.pp_if
);
345 #if NBPFILTER > 0 || NBPF > 0
347 bpfattach(&sc
->sc_sp
.pp_if
, DLT_PPP
, PPP_HDRLEN
);
348 CALLOUT_INIT(&sc
->sc_ch
);
349 #endif /* __FreeBSD__ */
351 bpfattach(&sc
->sc_sp
.pp_if
, DLT_PPP
, sizeof(u_int
));
357 /*---------------------------------------------------------------------------*
359 *---------------------------------------------------------------------------*/
361 i4bisppp_ioctl(struct ifnet
*ifp
, unsigned long cmd
, void *data
)
363 struct i4bisppp_softc
*sc
= ifp
->if_softc
;
366 return sppp_ioctl(&sc
->sc_sp
.pp_if
, cmd
, data
);
368 return isppp_ioctl(&sc
->sc_sp
.pp_if
, cmd
, data
);
372 /*---------------------------------------------------------------------------*
373 * start output to ISDN B-channel
374 *---------------------------------------------------------------------------*/
376 i4bisppp_start(struct ifnet
*ifp
)
378 struct i4bisppp_softc
*sc
= ifp
->if_softc
;
382 if (sppp_isempty(ifp
))
384 if (isppp_isempty(ifp
))
388 if(sc
->sc_state
!= ST_CONNECTED
)
393 * ifp->if_flags |= IFF_OACTIVE; // - need to clear this somewhere
398 while ((m
= sppp_dequeue(&sc
->sc_sp
.pp_if
)) != NULL
)
400 while ((m
= isppp_dequeue(&sc
->sc_sp
.pp_if
)) != NULL
)
404 #if NBPFILTER > 0 || NBPF > 0
408 #endif /* __FreeBSD__ */
412 bpf_mtap(ifp
->if_bpf
, m
);
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
);
423 IF_ENQUEUE(sc
->sc_ilt
->tx_queue
, m
);
425 sc
->sc_sp
.pp_if
.if_obytes
+= m
->m_pkthdr
.len
;
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
);
436 /*---------------------------------------------------------------------------*
438 *---------------------------------------------------------------------------*/
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
))
461 sc
->sc_linb
= sc
->sc_iinb
;
462 sc
->sc_loutb
= sc
->sc_ioutb
;
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
));
475 #endif /* I4BISPPPACCT */
478 *===========================================================================*
479 * SyncPPP layer interface routines
480 *===========================================================================*
483 /*---------------------------------------------------------------------------*
484 * PPP this-layer-started action
485 *---------------------------------------------------------------------------*
488 i4bisppp_tls(struct sppp
*sp
)
490 struct i4bisppp_softc
*sc
= sp
->pp_if
.if_softc
;
492 if(sc
->sc_state
== ST_CONNECTED
)
495 i4b_l4_dialout(ippp_drvr_id
, sc
->sc_unit
);
498 /*---------------------------------------------------------------------------*
499 * PPP this-layer-finished action
500 *---------------------------------------------------------------------------*
503 i4bisppp_tlf(struct sppp
*sp
)
505 struct i4bisppp_softc
*sc
= sp
->pp_if
.if_softc
;
507 if(sc
->sc_state
!= ST_CONNECTED
)
510 i4b_l4_drvrdisc(sc
->sc_cdp
->cdid
);
512 /*---------------------------------------------------------------------------*
513 * PPP interface phase change
514 *---------------------------------------------------------------------------*
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 *---------------------------------------------------------------------------*
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 *---------------------------------------------------------------------------*/
544 i4bisppp_connect(void *softc
, void *cdp
)
546 struct i4bisppp_softc
*sc
= softc
;
547 struct sppp
*sp
= &sc
->sc_sp
;
550 sc
->sc_cdp
= (call_desc_t
*)cdp
;
551 sc
->sc_state
= ST_CONNECTED
;
560 sc
->sc_sp
.pp_if
.if_timer
= I4BISPPPACCTINTVL
;
563 #if 0 /* never used ??? */
564 UNTIMEOUT(i4bisppp_timeout
, (void *)sp
, sc
->sc_ch
);
567 sp
->pp_up(sp
); /* tell PPP we are ready */
569 sp
->pp_last_sent
= sp
->pp_last_recv
= SECOND
;
574 /*---------------------------------------------------------------------------*
575 * this routine is called from L4 handler at disconnect time
576 *---------------------------------------------------------------------------*/
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
;
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
,
596 sc
->sc_sp
.pp_if
.if_timer
= 0;
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
);
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 */
616 /*---------------------------------------------------------------------------*
617 * this routine is used to give a feedback from userland demon
618 * in case of dial problems
619 *---------------------------------------------------------------------------*/
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
)
631 NDBGL4(L4_ISPDBG
, "%s: clearing queues", sc
->sc_sp
.pp_if
.if_xname
);
634 if(!(sppp_isempty(&sc
->sc_sp
.pp_if
)))
636 if(!(isppp_isempty(&sc
->sc_sp
.pp_if
)))
640 while((m
= sppp_dequeue(&sc
->sc_sp
.pp_if
)) != NULL
)
642 while((m
= isppp_dequeue(&sc
->sc_sp
.pp_if
)) != NULL
)
649 /*---------------------------------------------------------------------------*
651 *---------------------------------------------------------------------------*/
653 i4bisppp_updown(void *softc
, int 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
664 *---------------------------------------------------------------------------*/
666 i4bisppp_rx_data_rdy(void *softc
)
668 struct i4bisppp_softc
*sc
= softc
;
672 if((m
= *sc
->sc_ilt
->rx_mbuf
) == NULL
)
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
++;
681 sc
->sc_inb
+= m
->m_pkthdr
.len
;
685 printf("i4bisppp_rx_data_ready: received packet!\n");
688 #if NBPFILTER > 0 || NBPF > 0
691 if(sc
->sc_sp
.pp_if
.if_bpf
)
692 bpf_mtap(&sc
->sc_sp
.pp_if
, m
);
693 #endif /* __FreeBSD__ */
696 if(sc
->sc_sp
.pp_if
.if_bpf
)
697 bpf_mtap(sc
->sc_sp
.pp_if
.if_bpf
, m
);
700 #endif /* NBPFILTER > 0 || NBPF > 0 */
705 sppp_input(&sc
->sc_sp
.pp_if
, m
);
707 isppp_input(&sc
->sc_sp
.pp_if
, m
);
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 *---------------------------------------------------------------------------*/
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 *---------------------------------------------------------------------------*/
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 *---------------------------------------------------------------------------*/
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 *---------------------------------------------------------------------------*/
757 i4bisppp_ret_softc(int unit
)
759 return &i4bisppp_softc
[unit
];
762 /*---------------------------------------------------------------------------*
763 * setup the isdn_linktab for this driver
764 *---------------------------------------------------------------------------*/
766 i4bisppp_set_linktab(void *softc
, isdn_link_t
*ilt
)
768 struct i4bisppp_softc
*sc
= softc
;
772 /*===========================================================================*/