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.18 2005/02/26 22:39:49 perry 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.18 2005/02/26 22:39:49 perry 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, caddr_t 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, IOCTL_CMD_T cmd, caddr_t data)
  362 {
  363         struct i4bisppp_softc *sc = ifp->if_softc;
  364         int error;
  365 
  366 #ifndef USE_ISPPP
  367         error = sppp_ioctl(&sc->sc_sp.pp_if, cmd, data);
  368 #else
  369         error = isppp_ioctl(&sc->sc_sp.pp_if, cmd, data);
  370 #endif
  371         if (error)
  372                 return error;
  373 
  374         switch(cmd) {
  375         case SIOCSIFFLAGS:
  376 #if 0 /* never used ??? */
  377                 x = splnet();
  378                 if ((ifp->if_flags & IFF_UP) == 0)
  379                         UNTIMEOUT(i4bisppp_timeout, (void *)sp, sc->sc_ch);
  380                 splx(x);
  381 #endif
  382                 break;
  383         }
  384 
  385         return 0;
  386 }
  387 
  388 /*---------------------------------------------------------------------------*
  389  *      start output to ISDN B-channel
  390  *---------------------------------------------------------------------------*/
  391 static void
  392 i4bisppp_start(struct ifnet *ifp)
  393 {
  394         struct i4bisppp_softc *sc = ifp->if_softc;
  395         struct mbuf *m;
  396 
  397 #ifndef USE_ISPPP
  398         if (sppp_isempty(ifp))
  399 #else
  400         if (isppp_isempty(ifp))
  401 #endif
  402                 return;
  403 
  404         if(sc->sc_state != ST_CONNECTED)
  405                 return;
  406 
  407         /*
  408          * s = splnet();
  409          * ifp->if_flags |= IFF_OACTIVE; // - need to clear this somewhere
  410          * splx(s);
  411          */
  412 
  413 #ifndef USE_ISPPP
  414         while ((m = sppp_dequeue(&sc->sc_sp.pp_if)) != NULL)
  415 #else
  416         while ((m = isppp_dequeue(&sc->sc_sp.pp_if)) != NULL)
  417 #endif
  418         {
  419 
  420 #if NBPFILTER > 0 || NBPF > 0
  421 #ifdef __FreeBSD__
  422                 if (ifp->if_bpf)
  423                         bpf_mtap(ifp, m);
  424 #endif /* __FreeBSD__ */
  425 
  426 #ifdef __NetBSD__
  427                 if (ifp->if_bpf)
  428                         bpf_mtap(ifp->if_bpf, m);
  429 #endif
  430 #endif /* NBPFILTER > 0 || NBPF > 0 */
  431 
  432                 if(IF_QFULL(sc->sc_ilt->tx_queue))
  433                 {
  434                         NDBGL4(L4_ISPDBG, "%s, tx queue full!", sc->sc_sp.pp_if.if_xname);
  435                         m_freem(m);
  436                 }
  437                 else
  438                 {
  439                         IF_ENQUEUE(sc->sc_ilt->tx_queue, m);
  440 #if 0
  441                         sc->sc_sp.pp_if.if_obytes += m->m_pkthdr.len;
  442 #endif
  443                         sc->sc_outb += m->m_pkthdr.len;
  444                         sc->sc_sp.pp_if.if_opackets++;
  445                 }
  446         }
  447         sc->sc_ilt->bchannel_driver->bch_tx_start(sc->sc_ilt->l1token,
  448             sc->sc_ilt->channel);
  449 }
  450 
  451 #ifdef I4BISPPPACCT
  452 /*---------------------------------------------------------------------------*
  453  *      watchdog routine
  454  *---------------------------------------------------------------------------*/
  455 static void
  456 i4bisppp_watchdog(struct ifnet *ifp)
  457 {
  458         struct i4bisppp_softc *sc = ifp->if_softc;
  459         bchan_statistics_t bs;
  460 
  461         (*sc->sc_ilt->bchannel_driver->bch_stat)
  462                 (sc->sc_ilt->l1token, sc->sc_ilt->channel, &bs);
  463 
  464         sc->sc_ioutb += bs.outbytes;
  465         sc->sc_iinb += bs.inbytes;
  466 
  467         if((sc->sc_iinb != sc->sc_linb) || (sc->sc_ioutb != sc->sc_loutb) || sc->sc_fn)
  468         {
  469                 int ri = (sc->sc_iinb - sc->sc_linb)/I4BISPPPACCTINTVL;
  470                 int ro = (sc->sc_ioutb - sc->sc_loutb)/I4BISPPPACCTINTVL;
  471 
  472                 if((sc->sc_iinb == sc->sc_linb) && (sc->sc_ioutb == sc->sc_loutb))
  473                         sc->sc_fn = 0;
  474                 else
  475                         sc->sc_fn = 1;
  476 
  477                 sc->sc_linb = sc->sc_iinb;
  478                 sc->sc_loutb = sc->sc_ioutb;
  479 
  480                 if (sc->sc_cdp)
  481                         i4b_l4_accounting(sc->sc_cdp->cdid, ACCT_DURING,
  482                             sc->sc_ioutb, sc->sc_iinb, ro, ri, sc->sc_outb, sc->sc_inb);
  483         }
  484         sc->sc_sp.pp_if.if_timer = I4BISPPPACCTINTVL;
  485 
  486 #if 0 /* old stuff, keep it around */
  487         printf(ISPPP_FMT "transmit timeout\n", ISPPP_ARG(sc));
  488         i4bisppp_start(ifp);
  489 #endif
  490 }
  491 #endif /* I4BISPPPACCT */
  492 
  493 /*
  494  *===========================================================================*
  495  *                      SyncPPP layer interface routines
  496  *===========================================================================*
  497  */
  498 
  499 /*---------------------------------------------------------------------------*
  500  *      PPP this-layer-started action
  501  *---------------------------------------------------------------------------*
  502  */
  503 static void
  504 i4bisppp_tls(struct sppp *sp)
  505 {
  506         struct i4bisppp_softc *sc = sp->pp_if.if_softc;
  507 
  508         if(sc->sc_state == ST_CONNECTED)
  509                 return;
  510 
  511         i4b_l4_dialout(ippp_drvr_id, sc->sc_unit);
  512 }
  513 
  514 /*---------------------------------------------------------------------------*
  515  *      PPP this-layer-finished action
  516  *---------------------------------------------------------------------------*
  517  */
  518 static void
  519 i4bisppp_tlf(struct sppp *sp)
  520 {
  521         struct i4bisppp_softc *sc = sp->pp_if.if_softc;
  522 
  523         if(sc->sc_state != ST_CONNECTED)
  524                 return;
  525 
  526         i4b_l4_drvrdisc(sc->sc_cdp->cdid);
  527 }
  528 /*---------------------------------------------------------------------------*
  529  *      PPP interface phase change
  530  *---------------------------------------------------------------------------*
  531  */
  532 static void
  533 i4bisppp_state_changed(struct sppp *sp, int new_state)
  534 {
  535         struct i4bisppp_softc *sc = sp->pp_if.if_softc;
  536 
  537         i4b_l4_ifstate_changed(sc->sc_cdp, new_state);
  538 }
  539 
  540 /*---------------------------------------------------------------------------*
  541  *      PPP control protocol negotiation complete (run ip-up script now)
  542  *---------------------------------------------------------------------------*
  543  */
  544 static void
  545 i4bisppp_negotiation_complete(struct sppp *sp)
  546 {
  547         struct i4bisppp_softc *sc = sp->pp_if.if_softc;
  548 
  549         i4b_l4_negcomplete(sc->sc_cdp);
  550 }
  551 
  552 /*===========================================================================*
  553  *                      ISDN INTERFACE ROUTINES
  554  *===========================================================================*/
  555 
  556 /*---------------------------------------------------------------------------*
  557  *      this routine is called from L4 handler at connect time
  558  *---------------------------------------------------------------------------*/
  559 static void
  560 i4bisppp_connect(void *softc, void *cdp)
  561 {
  562         struct i4bisppp_softc *sc = softc;
  563         struct sppp *sp = &sc->sc_sp;
  564         int s = splnet();
  565 
  566         sc->sc_cdp = (call_desc_t *)cdp;
  567         sc->sc_state = ST_CONNECTED;
  568 
  569 #if I4BISPPPACCT
  570         sc->sc_iinb = 0;
  571         sc->sc_ioutb = 0;
  572         sc->sc_inb = 0;
  573         sc->sc_outb = 0;
  574         sc->sc_linb = 0;
  575         sc->sc_loutb = 0;
  576         sc->sc_sp.pp_if.if_timer = I4BISPPPACCTINTVL;
  577 #endif
  578 
  579 #if 0 /* never used ??? */
  580         UNTIMEOUT(i4bisppp_timeout, (void *)sp, sc->sc_ch);
  581 #endif
  582 
  583         sp->pp_up(sp);          /* tell PPP we are ready */
  584 #ifndef __NetBSD__
  585         sp->pp_last_sent = sp->pp_last_recv = SECOND;
  586 #endif
  587         splx(s);
  588 }
  589 
  590 /*---------------------------------------------------------------------------*
  591  *      this routine is called from L4 handler at disconnect time
  592  *---------------------------------------------------------------------------*/
  593 static void
  594 i4bisppp_disconnect(void *softc, void *cdp)
  595 {
  596         call_desc_t *cd = (call_desc_t *)cdp;
  597         struct i4bisppp_softc *sc = softc;
  598         struct sppp *sp = &sc->sc_sp;
  599 
  600         int s = splnet();
  601 
  602         /* new stuff to check that the active channel is being closed */
  603         if (cd != sc->sc_cdp)
  604         {
  605                 NDBGL4(L4_ISPDBG, "%s: channel%d not active!", sp->pp_if.if_xname,
  606                     cd->channelid);
  607                 splx(s);
  608                 return;
  609         }
  610 
  611 #if I4BISPPPACCT
  612         sc->sc_sp.pp_if.if_timer = 0;
  613 #endif
  614 
  615         i4b_l4_accounting(cd->cdid, ACCT_FINAL,
  616                  sc->sc_ioutb, sc->sc_iinb, 0, 0, sc->sc_outb, sc->sc_inb);
  617 
  618         if (sc->sc_state == ST_CONNECTED)
  619         {
  620 #if 0 /* never used ??? */
  621                 UNTIMEOUT(i4bisppp_timeout, (void *)sp, sc->sc_ch);
  622 #endif
  623                 sc->sc_cdp = (call_desc_t *)0;
  624                 /* do thhis here because pp_down calls i4bisppp_tlf */
  625                 sc->sc_state = ST_IDLE;
  626                 sp->pp_down(sp);        /* tell PPP we have hung up */
  627         }
  628 
  629         splx(s);
  630 }
  631 
  632 /*---------------------------------------------------------------------------*
  633  *      this routine is used to give a feedback from userland demon
  634  *      in case of dial problems
  635  *---------------------------------------------------------------------------*/
  636 static void
  637 i4bisppp_dialresponse(void *softc, int status, cause_t cause)
  638 {
  639         struct i4bisppp_softc *sc = softc;
  640 
  641         NDBGL4(L4_ISPDBG, "%s: status=%d, cause=%d", sc->sc_sp.pp_if.if_xname, status, cause);
  642 
  643         if(status != DSTAT_NONE)
  644         {
  645                 struct mbuf *m;
  646 
  647                 NDBGL4(L4_ISPDBG, "%s: clearing queues", sc->sc_sp.pp_if.if_xname);
  648 
  649 #ifndef USE_ISPPP
  650                 if(!(sppp_isempty(&sc->sc_sp.pp_if)))
  651 #else
  652                 if(!(isppp_isempty(&sc->sc_sp.pp_if)))
  653 #endif
  654                 {
  655 #ifndef USE_ISPPP
  656                         while((m = sppp_dequeue(&sc->sc_sp.pp_if)) != NULL)
  657 #else
  658                         while((m = isppp_dequeue(&sc->sc_sp.pp_if)) != NULL)
  659 #endif
  660                                 m_freem(m);
  661                 }
  662         }
  663 }
  664 
  665 /*---------------------------------------------------------------------------*
  666  *      interface up/down
  667  *---------------------------------------------------------------------------*/
  668 static void
  669 i4bisppp_updown(void *softc, int updown)
  670 {
  671         /* could probably do something useful here */
  672 }
  673 
  674 /*---------------------------------------------------------------------------*
  675  *      this routine is called from the HSCX interrupt handler
  676  *      when a new frame (mbuf) has been received and was put on
  677  *      the rx queue.
  678  *---------------------------------------------------------------------------*/
  679 static void
  680 i4bisppp_rx_data_rdy(void *softc)
  681 {
  682         struct i4bisppp_softc *sc = softc;
  683         struct mbuf *m;
  684         int s;
  685 
  686         if((m = *sc->sc_ilt->rx_mbuf) == NULL)
  687                 return;
  688 
  689         m->m_pkthdr.rcvif = &sc->sc_sp.pp_if;
  690         m->m_pkthdr.len = m->m_len;
  691 
  692         sc->sc_sp.pp_if.if_ipackets++;
  693 
  694 #if I4BISPPPACCT
  695         sc->sc_inb += m->m_pkthdr.len;
  696 #endif
  697 
  698 #ifdef I4BISPPPDEBUG
  699         printf("i4bisppp_rx_data_ready: received packet!\n");
  700 #endif
  701 
  702 #if NBPFILTER > 0 || NBPF > 0
  703 
  704 #ifdef __FreeBSD__
  705         if(sc->sc_sp.pp_if.if_bpf)
  706                 bpf_mtap(&sc->sc_sp.pp_if, m);
  707 #endif /* __FreeBSD__ */
  708 
  709 #ifdef __NetBSD__
  710         if(sc->sc_sp.pp_if.if_bpf)
  711                 bpf_mtap(sc->sc_sp.pp_if.if_bpf, m);
  712 #endif
  713 
  714 #endif /* NBPFILTER > 0  || NBPF > 0 */
  715 
  716         s = splnet();
  717 
  718 #ifndef USE_ISPPP
  719         sppp_input(&sc->sc_sp.pp_if, m);
  720 #else
  721         isppp_input(&sc->sc_sp.pp_if, m);
  722 #endif
  723 
  724         splx(s);
  725 }
  726 
  727 /*---------------------------------------------------------------------------*
  728  *      this routine is called from the HSCX interrupt handler
  729  *      when the last frame has been sent out and there is no
  730  *      further frame (mbuf) in the tx queue.
  731  *---------------------------------------------------------------------------*/
  732 static void
  733 i4bisppp_tx_queue_empty(void *softc)
  734 {
  735         struct sppp *sp = &((struct i4bisppp_softc *)softc)->sc_sp;
  736         i4bisppp_start(&sp->pp_if);
  737 }
  738 
  739 /*---------------------------------------------------------------------------*
  740  *      THIS should be used instead of last_active_time to implement
  741  *      an activity timeout mechanism.
  742  *
  743  *      Sending back the time difference unneccessarily complicates the
  744  *      idletime checks in i4b_l4.c. Return the largest time instead.
  745  *      That way the code in i4b_l4.c needs only minimal changes.
  746  *---------------------------------------------------------------------------*/
  747 time_t
  748 i4bisppp_idletime(void *softc)
  749 {
  750         struct sppp *sp = &((struct i4bisppp_softc *)softc)->sc_sp;
  751 
  752         return sp->pp_last_activity;
  753 }
  754 
  755 /*---------------------------------------------------------------------------*
  756  *      this routine is called from the HSCX interrupt handler
  757  *      each time a packet is received or transmitted. It should
  758  *      be used to implement an activity timeout mechanism.
  759  *---------------------------------------------------------------------------*/
  760 static void
  761 i4bisppp_activity(void *softc, int rxtx)
  762 {
  763         struct i4bisppp_softc *sc = softc;
  764         sc->sc_cdp->last_active_time = SECOND;
  765 }
  766 
  767 /*---------------------------------------------------------------------------*
  768  *      return this drivers linktab address
  769  *---------------------------------------------------------------------------*/
  770 static void *
  771 i4bisppp_ret_softc(int unit)
  772 {
  773         return &i4bisppp_softc[unit];
  774 }
  775 
  776 /*---------------------------------------------------------------------------*
  777  *      setup the isdn_linktab for this driver
  778  *---------------------------------------------------------------------------*/
  779 static void
  780 i4bisppp_set_linktab(void *softc, isdn_link_t *ilt)
  781 {
  782         struct i4bisppp_softc *sc = softc;
  783         sc->sc_ilt = ilt;
  784 }
  785 
  786 /*===========================================================================*/

Cache object: 652be2fb31f4d8aa69f7c9002288de14


[ 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.