The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netisdn/i4b_isppp.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  *   Copyright (c) 1997 Joerg Wunsch. All rights reserved.
    3  *
    4  *   Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
    5  *
    6  *   Redistribution and use in source and binary forms, with or without
    7  *   modification, are permitted provided that the following conditions
    8  *   are met:
    9  *
   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.
   15  *
   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.
   27  *
   28  *---------------------------------------------------------------------------
   29  *
   30  *      i4b_isppp.c - isdn4bsd kernel SyncPPP driver
   31  *      --------------------------------------------
   32  *
   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.
   36  *
   37  *      $Id: i4b_isppp.c,v 1.24 2008/05/23 14:10:50 he Exp $
   38  *
   39  * $FreeBSD$
   40  *
   41  *      last edit-date: [Fri Jan  5 11:33:47 2001]
   42  *
   43  *---------------------------------------------------------------------------*/
   44 
   45 #include <sys/cdefs.h>
   46 __KERNEL_RCSID(0, "$NetBSD: i4b_isppp.c,v 1.24 2008/05/23 14:10:50 he Exp $");
   47 
   48 #ifndef __NetBSD__
   49 #define USE_ISPPP
   50 #endif
   51 #include "ippp.h"
   52 
   53 #ifndef USE_ISPPP
   54 
   55 #ifdef __FreeBSD__
   56 #include "sppp.h"
   57 #endif
   58 
   59 #ifndef __NetBSD__
   60 #if NI4BISPPP == 0
   61 # error "You need to define `pseudo-device sppp <N>' with options ISPPP"
   62 #endif
   63 #endif
   64 
   65 #endif
   66 
   67 #include <sys/param.h>
   68 /*
   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.
   72  */
   73 #undef sc_sp
   74 
   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>
   84 
   85 #include <net/if.h>
   86 #include <net/if_types.h>
   87 #include <net/netisr.h>
   88 #include <net/route.h>
   89 
   90 #include <netinet/in.h>
   91 #include <netinet/in_systm.h>
   92 #include <netinet/in_var.h>
   93 #include <netinet/ip.h>
   94 
   95 #include <net/slcompress.h>
   96 
   97 #include <net/if_spppvar.h>
   98 
   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
  108 
  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
  118 
  119 #include <netisdn/i4b_global.h>
  120 #include <netisdn/i4b_mbuf.h>
  121 #include <netisdn/i4b_l3l4.h>
  122 
  123 #include <netisdn/i4b_l4.h>
  124 
  125 #ifdef __FreeBSD__
  126 #define ISPPP_FMT       "ippp%d: "
  127 #define ISPPP_ARG(sc)   ((sc)->sc_if.if_unit)
  128 #define PDEVSTATIC      static
  129 
  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
  141 
  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
  150 
  151 #ifdef __FreeBSD__
  152 PDEVSTATIC void ipppattach(void *);
  153 PSEUDO_SET(ipppattach, i4b_isppp);
  154 #else
  155 PDEVSTATIC void ipppattach(void);
  156 #endif
  157 
  158 #define I4BISPPPACCT            1       /* enable accounting messages */
  159 #define I4BISPPPACCTINTVL       2       /* accounting msg interval in secs */
  160 #define I4BISPPPDISCDEBUG       1
  161 
  162 #define PPP_HDRLEN              4       /* 4 octetts PPP header length  */
  163 
  164 struct i4bisppp_softc {
  165         struct sppp sc_sp;      /* we are derived from struct sppp */
  166 
  167         int     sc_state;       /* state of the interface       */
  168 
  169 #ifndef __FreeBSD__
  170         int     sc_unit;        /* unit number for Net/OpenBSD  */
  171 #endif
  172 
  173         call_desc_t *sc_cdp;    /* ptr to call descriptor       */
  174         isdn_link_t *sc_ilt;    /* B channel driver and state   */
  175 
  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
  185 
  186 #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001
  187         struct callout_handle sc_ch;
  188 #endif
  189 
  190 } i4bisppp_softc[NIPPP];
  191 
  192 static int      i4bisppp_ioctl(struct ifnet *ifp, IOCTL_CMD_T cmd, void *data);
  193 
  194 #if 0
  195 static void     i4bisppp_send(struct ifnet *ifp);
  196 #endif
  197 
  198 static void     i4bisppp_start(struct ifnet *ifp);
  199 
  200 #if 0 /* never used ??? */
  201 static void     i4bisppp_timeout(void *cookie);
  202 #endif
  203 
  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);
  219 
  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
  234 };
  235 
  236 static int ippp_drvr_id = -1;
  237 
  238 enum i4bisppp_states {
  239         ST_IDLE,                        /* initialized, ready, idle     */
  240         ST_DIALING,                     /* dialling out to remote       */
  241         ST_CONNECTED,                   /* connected to remote          */
  242 };
  243 
  244 /*===========================================================================*
  245  *                      DEVICE DRIVER ROUTINES
  246  *===========================================================================*/
  247 
  248 /*---------------------------------------------------------------------------*
  249  *      interface attach routine at kernel boot time
  250  *---------------------------------------------------------------------------*/
  251 PDEVSTATIC void
  252 #ifdef __FreeBSD__
  253 ipppattach(void *dummy)
  254 #else
  255 ipppattach()
  256 #endif
  257 {
  258         struct i4bisppp_softc *sc = i4bisppp_softc;
  259         int i;
  260 
  261         ippp_drvr_id = isdn_l4_driver_attach("ippp", NIPPP, &ippp_l4_functions);
  262 
  263         for(i = 0; i < NIPPP; sc++, i++) {
  264                 sc->sc_sp.pp_if.if_softc = sc;
  265                 sc->sc_ilt = NULL;
  266 
  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
  278 
  279                 sc->sc_sp.pp_if.if_mtu = PP_MTU;
  280 
  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
  287 
  288                 sc->sc_sp.pp_if.if_type = IFT_ISDNBASIC;
  289                 sc->sc_state = ST_IDLE;
  290 
  291                 sc->sc_sp.pp_if.if_ioctl = i4bisppp_ioctl;
  292 
  293                 /* actually initialized by sppp_attach() */
  294                 /* sc->sc_sp.pp_if.if_output = sppp_output; */
  295 
  296                 sc->sc_sp.pp_if.if_start = i4bisppp_start;
  297 
  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);
  302 
  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;
  314 
  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
  326 
  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 */
  332 
  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
  344 
  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
  354         }
  355 }
  356 
  357 /*---------------------------------------------------------------------------*
  358  *      process ioctl
  359  *---------------------------------------------------------------------------*/
  360 static int
  361 i4bisppp_ioctl(struct ifnet *ifp, unsigned long cmd, void *data)
  362 {
  363         struct i4bisppp_softc *sc = ifp->if_softc;
  364 
  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
  370 }
  371 
  372 /*---------------------------------------------------------------------------*
  373  *      start output to ISDN B-channel
  374  *---------------------------------------------------------------------------*/
  375 static void
  376 i4bisppp_start(struct ifnet *ifp)
  377 {
  378         struct i4bisppp_softc *sc = ifp->if_softc;
  379         struct mbuf *m;
  380 
  381 #ifndef USE_ISPPP
  382         if (sppp_isempty(ifp))
  383 #else
  384         if (isppp_isempty(ifp))
  385 #endif
  386                 return;
  387 
  388         if(sc->sc_state != ST_CONNECTED)
  389                 return;
  390 
  391         /*
  392          * s = splnet();
  393          * ifp->if_flags |= IFF_OACTIVE; // - need to clear this somewhere
  394          * splx(s);
  395          */
  396 
  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
  402         {
  403 
  404 #if NBPFILTER > 0 || NBPF > 0
  405 #ifdef __FreeBSD__
  406                 if (ifp->if_bpf)
  407                         bpf_mtap(ifp, m);
  408 #endif /* __FreeBSD__ */
  409 
  410 #ifdef __NetBSD__
  411                 if (ifp->if_bpf)
  412                         bpf_mtap(ifp->if_bpf, m);
  413 #endif
  414 #endif /* NBPFILTER > 0 || NBPF > 0 */
  415 
  416                 if(IF_QFULL(sc->sc_ilt->tx_queue))
  417                 {
  418                         NDBGL4(L4_ISPDBG, "%s, tx queue full!", sc->sc_sp.pp_if.if_xname);
  419                         m_freem(m);
  420                 }
  421                 else
  422                 {
  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++;
  429                 }
  430         }
  431         sc->sc_ilt->bchannel_driver->bch_tx_start(sc->sc_ilt->l1token,
  432             sc->sc_ilt->channel);
  433 }
  434 
  435 #ifdef I4BISPPPACCT
  436 /*---------------------------------------------------------------------------*
  437  *      watchdog routine
  438  *---------------------------------------------------------------------------*/
  439 static void
  440 i4bisppp_watchdog(struct ifnet *ifp)
  441 {
  442         struct i4bisppp_softc *sc = ifp->if_softc;
  443         bchan_statistics_t bs;
  444 
  445         (*sc->sc_ilt->bchannel_driver->bch_stat)
  446                 (sc->sc_ilt->l1token, sc->sc_ilt->channel, &bs);
  447 
  448         sc->sc_ioutb += bs.outbytes;
  449         sc->sc_iinb += bs.inbytes;
  450 
  451         if((sc->sc_iinb != sc->sc_linb) || (sc->sc_ioutb != sc->sc_loutb) || sc->sc_fn)
  452         {
  453                 int ri = (sc->sc_iinb - sc->sc_linb)/I4BISPPPACCTINTVL;
  454                 int ro = (sc->sc_ioutb - sc->sc_loutb)/I4BISPPPACCTINTVL;
  455 
  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;
  460 
  461                 sc->sc_linb = sc->sc_iinb;
  462                 sc->sc_loutb = sc->sc_ioutb;
  463 
  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);
  467         }
  468         sc->sc_sp.pp_if.if_timer = I4BISPPPACCTINTVL;
  469 
  470 #if 0 /* old stuff, keep it around */
  471         printf(ISPPP_FMT "transmit timeout\n", ISPPP_ARG(sc));
  472         i4bisppp_start(ifp);
  473 #endif
  474 }
  475 #endif /* I4BISPPPACCT */
  476 
  477 /*
  478  *===========================================================================*
  479  *                      SyncPPP layer interface routines
  480  *===========================================================================*
  481  */
  482 
  483 /*---------------------------------------------------------------------------*
  484  *      PPP this-layer-started action
  485  *---------------------------------------------------------------------------*
  486  */
  487 static void
  488 i4bisppp_tls(struct sppp *sp)
  489 {
  490         struct i4bisppp_softc *sc = sp->pp_if.if_softc;
  491 
  492         if(sc->sc_state == ST_CONNECTED)
  493                 return;
  494 
  495         i4b_l4_dialout(ippp_drvr_id, sc->sc_unit);
  496 }
  497 
  498 /*---------------------------------------------------------------------------*
  499  *      PPP this-layer-finished action
  500  *---------------------------------------------------------------------------*
  501  */
  502 static void
  503 i4bisppp_tlf(struct sppp *sp)
  504 {
  505         struct i4bisppp_softc *sc = sp->pp_if.if_softc;
  506 
  507         if(sc->sc_state != ST_CONNECTED)
  508                 return;
  509 
  510         i4b_l4_drvrdisc(sc->sc_cdp->cdid);
  511 }
  512 /*---------------------------------------------------------------------------*
  513  *      PPP interface phase change
  514  *---------------------------------------------------------------------------*
  515  */
  516 static void
  517 i4bisppp_state_changed(struct sppp *sp, int new_state)
  518 {
  519         struct i4bisppp_softc *sc = sp->pp_if.if_softc;
  520 
  521         i4b_l4_ifstate_changed(sc->sc_cdp, new_state);
  522 }
  523 
  524 /*---------------------------------------------------------------------------*
  525  *      PPP control protocol negotiation complete (run ip-up script now)
  526  *---------------------------------------------------------------------------*
  527  */
  528 static void
  529 i4bisppp_negotiation_complete(struct sppp *sp)
  530 {
  531         struct i4bisppp_softc *sc = sp->pp_if.if_softc;
  532 
  533         i4b_l4_negcomplete(sc->sc_cdp);
  534 }
  535 
  536 /*===========================================================================*
  537  *                      ISDN INTERFACE ROUTINES
  538  *===========================================================================*/
  539 
  540 /*---------------------------------------------------------------------------*
  541  *      this routine is called from L4 handler at connect time
  542  *---------------------------------------------------------------------------*/
  543 static void
  544 i4bisppp_connect(void *softc, void *cdp)
  545 {
  546         struct i4bisppp_softc *sc = softc;
  547         struct sppp *sp = &sc->sc_sp;
  548         int s = splnet();
  549 
  550         sc->sc_cdp = (call_desc_t *)cdp;
  551         sc->sc_state = ST_CONNECTED;
  552 
  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
  562 
  563 #if 0 /* never used ??? */
  564         UNTIMEOUT(i4bisppp_timeout, (void *)sp, sc->sc_ch);
  565 #endif
  566 
  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);
  572 }
  573 
  574 /*---------------------------------------------------------------------------*
  575  *      this routine is called from L4 handler at disconnect time
  576  *---------------------------------------------------------------------------*/
  577 static void
  578 i4bisppp_disconnect(void *softc, void *cdp)
  579 {
  580         call_desc_t *cd = (call_desc_t *)cdp;
  581         struct i4bisppp_softc *sc = softc;
  582         struct sppp *sp = &sc->sc_sp;
  583 
  584         int s = splnet();
  585 
  586         /* new stuff to check that the active channel is being closed */
  587         if (cd != sc->sc_cdp)
  588         {
  589                 NDBGL4(L4_ISPDBG, "%s: channel%d not active!", sp->pp_if.if_xname,
  590                     cd->channelid);
  591                 splx(s);
  592                 return;
  593         }
  594 
  595 #if I4BISPPPACCT
  596         sc->sc_sp.pp_if.if_timer = 0;
  597 #endif
  598 
  599         i4b_l4_accounting(cd->cdid, ACCT_FINAL,
  600                  sc->sc_ioutb, sc->sc_iinb, 0, 0, sc->sc_outb, sc->sc_inb);
  601 
  602         if (sc->sc_state == ST_CONNECTED)
  603         {
  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 */
  611         }
  612 
  613         splx(s);
  614 }
  615 
  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)
  622 {
  623         struct i4bisppp_softc *sc = softc;
  624 
  625         NDBGL4(L4_ISPDBG, "%s: status=%d, cause=%d", sc->sc_sp.pp_if.if_xname, status, cause);
  626 
  627         if(status != DSTAT_NONE)
  628         {
  629                 struct mbuf *m;
  630 
  631                 NDBGL4(L4_ISPDBG, "%s: clearing queues", sc->sc_sp.pp_if.if_xname);
  632 
  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
  638                 {
  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);
  645                 }
  646         }
  647 }
  648 
  649 /*---------------------------------------------------------------------------*
  650  *      interface up/down
  651  *---------------------------------------------------------------------------*/
  652 static void
  653 i4bisppp_updown(void *softc, int updown)
  654 {
  655         (void)softc;
  656         (void)updown;
  657         /* could probably do something useful here */
  658 }
  659 
  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)
  667 {
  668         struct i4bisppp_softc *sc = softc;
  669         struct mbuf *m;
  670         int s;
  671 
  672         if((m = *sc->sc_ilt->rx_mbuf) == NULL)
  673                 return;
  674 
  675         m->m_pkthdr.rcvif = &sc->sc_sp.pp_if;
  676         m->m_pkthdr.len = m->m_len;
  677 
  678         sc->sc_sp.pp_if.if_ipackets++;
  679 
  680 #if I4BISPPPACCT
  681         sc->sc_inb += m->m_pkthdr.len;
  682 #endif
  683 
  684 #ifdef I4BISPPPDEBUG
  685         printf("i4bisppp_rx_data_ready: received packet!\n");
  686 #endif
  687 
  688 #if NBPFILTER > 0 || NBPF > 0
  689 
  690 #ifdef __FreeBSD__
  691         if(sc->sc_sp.pp_if.if_bpf)
  692                 bpf_mtap(&sc->sc_sp.pp_if, m);
  693 #endif /* __FreeBSD__ */
  694 
  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
  699 
  700 #endif /* NBPFILTER > 0  || NBPF > 0 */
  701 
  702         s = splnet();
  703 
  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
  709 
  710         splx(s);
  711 }
  712 
  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)
  720 {
  721         struct sppp *sp = &((struct i4bisppp_softc *)softc)->sc_sp;
  722         i4bisppp_start(&sp->pp_if);
  723 }
  724 
  725 /*---------------------------------------------------------------------------*
  726  *      THIS should be used instead of last_active_time to implement
  727  *      an activity timeout mechanism.
  728  *
  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)
  735 {
  736         struct sppp *sp = &((struct i4bisppp_softc *)softc)->sc_sp;
  737 
  738         return sp->pp_last_activity;
  739 }
  740 
  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)
  748 {
  749         struct i4bisppp_softc *sc = softc;
  750         sc->sc_cdp->last_active_time = SECOND;
  751 }
  752 
  753 /*---------------------------------------------------------------------------*
  754  *      return this drivers linktab address
  755  *---------------------------------------------------------------------------*/
  756 static void *
  757 i4bisppp_ret_softc(int unit)
  758 {
  759         return &i4bisppp_softc[unit];
  760 }
  761 
  762 /*---------------------------------------------------------------------------*
  763  *      setup the isdn_linktab for this driver
  764  *---------------------------------------------------------------------------*/
  765 static void
  766 i4bisppp_set_linktab(void *softc, isdn_link_t *ilt)
  767 {
  768         struct i4bisppp_softc *sc = softc;
  769         sc->sc_ilt = ilt;
  770 }
  771 
  772 /*===========================================================================*/

Cache object: 17ea2a2fb1d97b659ded0836b7ba9839


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.