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

Cache object: c555b8546327402d73de78d48fbe38df


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