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_ipr.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, 2000 Hellmuth Michaelis. All rights reserved.
    3  *
    4  * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions
    6  * are met:
    7  * 1. Redistributions of source code must retain the above copyright
    8  *    notice, this list of conditions and the following disclaimer.
    9  * 2. Redistributions in binary form must reproduce the above copyright
   10  *    notice, this list of conditions and the following disclaimer in the
   11  *    documentation and/or other materials provided with the distribution.
   12  *
   13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   23  * SUCH DAMAGE.
   24  *
   25  *---------------------------------------------------------------------------
   26  *
   27  *      i4b_ipr.c - isdn4bsd IP over raw HDLC ISDN network driver
   28  *      ---------------------------------------------------------
   29  *
   30  *      $Id: i4b_ipr.c,v 1.24 2006/11/16 01:33:49 christos Exp $
   31  *
   32  * $FreeBSD$
   33  *
   34  *      last edit-date: [Fri Jan  5 11:33:47 2001]
   35  *
   36  *---------------------------------------------------------------------------*
   37  *
   38  *      statistics counter usage (interface lifetime):
   39  *      ----------------------------------------------
   40  *      sc->sc_if.if_ipackets   # of received packets
   41  *      sc->sc_if.if_ierrors    # of error packets not going to upper layers
   42  *      sc->sc_if.if_opackets   # of transmitted packets
   43  *      sc->sc_if.if_oerrors    # of error packets not being transmitted
   44  *      sc->sc_if.if_collisions # of invalid ip packets after VJ decompression
   45  *      sc->sc_if.if_ibytes     # of bytes coming in from the line (before VJ)
   46  *      sc->sc_if.if_obytes     # of bytes going out to the line (after VJ)
   47  *      sc->sc_if.if_imcasts      (currently unused)
   48  *      sc->sc_if.if_omcasts    # of frames sent out of the fastqueue
   49  *      sc->sc_if.if_iqdrops    # of frames dropped on input because queue full
   50  *      sc->sc_if.if_noproto    # of frames dropped on output because !AF_INET
   51  *
   52  *      statistics counter usage (connection lifetime):
   53  *      -----------------------------------------------
   54  *      sc->sc_iinb             # of ISDN incoming bytes from HSCX
   55  *      sc->sc_ioutb            # of ISDN outgoing bytes from HSCX
   56  *      sc->sc_inb              # of incoming bytes after decompression
   57  *      sc->sc_outb             # of outgoing bytes before compression
   58  *
   59  *---------------------------------------------------------------------------*/
   60 
   61 #include <sys/cdefs.h>
   62 __KERNEL_RCSID(0, "$NetBSD: i4b_ipr.c,v 1.24 2006/11/16 01:33:49 christos Exp $");
   63 
   64 #include "irip.h"
   65 #include "opt_irip.h"
   66 
   67 #if NIRIP > 0
   68 
   69 #ifdef __FreeBSD__
   70 #include "opt_i4b.h"
   71 #endif
   72 
   73 #include <sys/param.h>
   74 #include <sys/systm.h>
   75 #include <sys/mbuf.h>
   76 #include <sys/socket.h>
   77 #include <sys/errno.h>
   78 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
   79 #include <sys/ioccom.h>
   80 #include <sys/sockio.h>
   81 #ifdef IPR_VJ
   82 #include <sys/malloc.h>
   83 #endif
   84 #else
   85 #include <sys/ioctl.h>
   86 #endif
   87 
   88 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
   89 #include <sys/callout.h>
   90 #endif
   91 
   92 #include <sys/kernel.h>
   93 #include <sys/protosw.h>
   94 
   95 #include <net/if.h>
   96 #include <net/if_types.h>
   97 #include <net/netisr.h>
   98 #include <net/route.h>
   99 
  100 #include <netinet/in.h>
  101 #include <netinet/in_systm.h>
  102 #include <netinet/in_var.h>
  103 #include <netinet/ip.h>
  104 
  105 #ifdef IRIP_VJ
  106 #include <net/slcompress.h>
  107 #define IPR_COMPRESS IFF_LINK0  /* compress TCP traffic */
  108 #define IPR_AUTOCOMP IFF_LINK1  /* auto-enable TCP compression */
  109 
  110 /*---------------------------------------------------------------------------
  111  * NOTICE: using NO separate buffer relies on the assumption, that the HSCX
  112  * IRQ handler _always_ allocates a single, continuous mbuf cluster large
  113  * enough to hold the maximum MTU size if the ipr interface !
  114  *
  115  * CAUTION: i have re-defined IPR_VJ_USEBUFFER because it makes problems
  116  *          with 2 i4b's back to back running cvs over ssh, cvs simply
  117  *          aborts because it gets bad data. Everything else (telnet/ftp?etc)
  118  *          functions fine.
  119  *---------------------------------------------------------------------------*/
  120 #define IPR_VJ_USEBUFFER        /* define to use an allocated separate buffer*/
  121                                 /* undef to uncompress in the mbuf itself    */
  122 #endif /* IRIP_VJ */
  123 
  124 #if defined(__FreeBSD_version) &&  __FreeBSD_version >= 400008
  125 #include "bpf.h"
  126 #else
  127 #include "bpfilter.h"
  128 #endif
  129 #if NBPFILTER > 0 || NBPF > 0
  130 #include <sys/time.h>
  131 #include <net/bpf.h>
  132 #endif
  133 
  134 #ifdef __FreeBSD__
  135 #include <machine/i4b_ioctl.h>
  136 #include <machine/i4b_debug.h>
  137 #else
  138 #include <netisdn/i4b_debug.h>
  139 #include <netisdn/i4b_ioctl.h>
  140 #endif
  141 
  142 #include <netisdn/i4b_global.h>
  143 #include <netisdn/i4b_mbuf.h>
  144 #include <netisdn/i4b_l3l4.h>
  145 
  146 #include <netisdn/i4b_l4.h>
  147 
  148 #ifndef __FreeBSD__
  149 #include <machine/cpu.h> /* For softnet */
  150 #endif
  151 
  152 #ifdef __FreeBSD__
  153 #define IPR_FMT "irip%d: "
  154 #define IPR_ARG(sc)     ((sc)->sc_if.if_unit)
  155 #define PDEVSTATIC      static
  156 #elif defined(__bsdi__)
  157 #define IPR_FMT "irip%d: "
  158 #define IPR_ARG(sc)     ((sc)->sc_if.if_unit)
  159 #define PDEVSTATIC      /* not static */
  160 #else
  161 #define IPR_FMT "%s: "
  162 #define IPR_ARG(sc)     ((sc)->sc_if.if_xname)
  163 #define PDEVSTATIC      /* not static */
  164 #endif
  165 
  166 #define I4BIPRMTU       1500            /* regular MTU */
  167 #define I4BIPRMAXMTU    2000            /* max MTU */
  168 #define I4BIPRMINMTU    500             /* min MTU */
  169 
  170 #define I4BIPRMAXQLEN   50              /* max queue length */
  171 
  172 #define I4BIPRACCT      1               /* enable accounting messages */
  173 #define I4BIPRACCTINTVL 2               /* accounting msg interval in secs */
  174 #define I4BIPRADJFRXP   1               /* adjust 1st rxd packet */
  175 
  176 
  177 struct ipr_softc {
  178         struct ifnet    sc_if;          /* network-visible interface    */
  179         int             sc_state;       /* state of the interface       */
  180 
  181         call_desc_t     *sc_cdp;        /* ptr to call descriptor       */
  182         isdn_link_t     *sc_ilt;        /* ptr to B channel driver/state */
  183 
  184         int             sc_unit;        /* which instance are we?       */
  185         int             sc_updown;      /* soft state of interface      */
  186         struct ifqueue  sc_fastq;       /* interactive traffic          */
  187         int             sc_dialresp;    /* dialresponse                 */
  188         int             sc_lastdialresp;/* last dialresponse            */
  189 
  190 #if I4BIPRACCT
  191         int             sc_iinb;        /* isdn driver # of inbytes     */
  192         int             sc_ioutb;       /* isdn driver # of outbytes    */
  193         int             sc_inb;         /* # of bytes rx'd              */
  194         int             sc_outb;        /* # of bytes tx'd              */
  195         int             sc_linb;        /* last # of bytes rx'd         */
  196         int             sc_loutb;       /* last # of bytes tx'd         */
  197         int             sc_fn;          /* flag, first null acct        */
  198 #endif
  199 
  200 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
  201         struct callout  sc_callout;
  202 #endif
  203 #if defined(__FreeBSD__)
  204         struct callout_handle   sc_callout;
  205 #endif
  206 
  207 #ifdef I4BIPRADJFRXP
  208         int             sc_first_pkt;   /* flag, first rxd packet       */
  209 #endif
  210 #if IPR_LOG
  211         int             sc_log_first;   /* log first n packets          */
  212 #endif
  213 
  214 #ifdef IRIP_VJ
  215         struct slcompress sc_compr;     /* tcp compression data         */
  216 #ifdef IPR_VJ_USEBUFFER
  217         u_char          *sc_cbuf;       /* tcp decompression buffer     */
  218 #endif
  219 #endif
  220 
  221 } ipr_softc[NIRIP];
  222 
  223 enum ipr_states {
  224         ST_IDLE,                        /* initialized, ready, idle     */
  225         ST_DIALING,                     /* dialling out to remote       */
  226         ST_CONNECTED_W,                 /* connected to remote          */
  227         ST_CONNECTED_A,                 /* connected to remote          */
  228 };
  229 
  230 #if defined(__FreeBSD__) || defined(__bsdi__)
  231 #define THE_UNIT        sc->sc_if.if_unit
  232 #else
  233 #define THE_UNIT        sc->sc_unit
  234 #endif
  235 
  236 #ifdef __FreeBSD__
  237 #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001
  238 #  define IOCTL_CMD_T u_long
  239 #else
  240 #ifdef __NetBSD__
  241 #  define IOCTL_CMD_T u_long
  242 #else
  243 #  define IOCTL_CMD_T int
  244 #endif
  245 #endif
  246 PDEVSTATIC void iripattach(void *);
  247 PSEUDO_SET(iripattach, i4b_ipr);
  248 static int irpioctl(struct ifnet *ifp, IOCTL_CMD_T cmd, caddr_t data);
  249 #else
  250 PDEVSTATIC void iripattach __P((void));
  251 static int iripioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
  252 #endif
  253 
  254 #ifdef __bsdi__
  255 static int iprwatchdog(int unit);
  256 #else
  257 static void iprwatchdog(struct ifnet *ifp);
  258 #endif
  259 static void ipr_tx_queue_empty(void *);
  260 static int iripoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, struct rtentry *rtp);
  261 static void iripclearqueues(struct ipr_softc *sc);
  262 static void ipr_set_linktab(void *softc, isdn_link_t *ilt);
  263 static void ipr_activity(void *softc, int rxtx);
  264 static void ipr_rx_data_rdy(void *softc);
  265 static void ipr_disconnect(void *softc, void *cdp);
  266 static void ipr_connect(void *softc, void *cdp);
  267 static void ipr_dialresponse(void *softc, int status, cause_t cause);
  268 static void ipr_updown(void *softc, int updown);
  269 static void* ipr_get_softc(int unit);
  270 
  271 static const struct isdn_l4_driver_functions
  272 ipr_l4_functions = {
  273         ipr_rx_data_rdy,
  274         ipr_tx_queue_empty,
  275         ipr_activity,
  276         ipr_connect,
  277         ipr_disconnect,
  278         ipr_dialresponse,
  279         ipr_updown,
  280         ipr_get_softc,
  281         ipr_set_linktab,
  282         NULL
  283 };
  284 
  285 static int irip_driver_id = -1;
  286 
  287 /*===========================================================================*
  288  *                      DEVICE DRIVER ROUTINES
  289  *===========================================================================*/
  290 
  291 /*---------------------------------------------------------------------------*
  292  *      interface attach routine at kernel boot time
  293  *---------------------------------------------------------------------------*/
  294 PDEVSTATIC void
  295 #ifdef __FreeBSD__
  296 iripattach(void *dummy)
  297 #else
  298 iripattach()
  299 #endif
  300 {
  301         struct ipr_softc *sc = ipr_softc;
  302         int i;
  303 
  304         irip_driver_id = isdn_l4_driver_attach("irip", NIRIP, &ipr_l4_functions);
  305 
  306         for(i=0; i < NIRIP; sc++, i++)
  307         {
  308                 NDBGL4(L4_DIALST, "setting dial state to ST_IDLE");
  309 
  310                 sc->sc_state = ST_IDLE;
  311                 sc->sc_unit = i;
  312 
  313 #ifdef __FreeBSD__
  314                 sc->sc_if.if_name = "irip";
  315 #if __FreeBSD__ < 3
  316                 sc->sc_if.if_next = NULL;
  317 #endif
  318                 sc->sc_if.if_unit = i;
  319 #elif defined(__bsdi__)
  320                 sc->sc_if.if_name = "irip";
  321                 sc->sc_if.if_unit = i;
  322 #else
  323                 snprintf(sc->sc_if.if_xname, sizeof(sc->sc_if.if_xname),
  324                     "irip%d", i);
  325                 sc->sc_if.if_softc = sc;
  326 #endif
  327 
  328 #ifdef  IRIP_VJ
  329                 sc->sc_if.if_flags = IFF_POINTOPOINT | IFF_SIMPLEX | IPR_AUTOCOMP;
  330 #else
  331                 sc->sc_if.if_flags = IFF_POINTOPOINT | IFF_SIMPLEX;
  332 #endif
  333 
  334 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
  335                 callout_init(&sc->sc_callout);
  336 #endif
  337 
  338                 sc->sc_if.if_mtu = I4BIPRMTU;
  339                 sc->sc_if.if_type = IFT_ISDNBASIC;
  340                 sc->sc_if.if_ioctl = iripioctl;
  341                 sc->sc_if.if_output = iripoutput;
  342 
  343                 IFQ_SET_MAXLEN(&sc->sc_if.if_snd, I4BIPRMAXQLEN);
  344                 sc->sc_fastq.ifq_maxlen = I4BIPRMAXQLEN;
  345                 IFQ_SET_READY(&sc->sc_if.if_snd);
  346 
  347                 sc->sc_if.if_ipackets = 0;
  348                 sc->sc_if.if_ierrors = 0;
  349                 sc->sc_if.if_opackets = 0;
  350                 sc->sc_if.if_oerrors = 0;
  351                 sc->sc_if.if_collisions = 0;
  352                 sc->sc_if.if_ibytes = 0;
  353                 sc->sc_if.if_obytes = 0;
  354                 sc->sc_if.if_imcasts = 0;
  355                 sc->sc_if.if_omcasts = 0;
  356                 sc->sc_if.if_iqdrops = 0;
  357                 sc->sc_if.if_noproto = 0;
  358 
  359 #if I4BIPRACCT
  360                 sc->sc_if.if_timer = 0;
  361                 sc->sc_if.if_watchdog = iprwatchdog;
  362                 sc->sc_iinb = 0;
  363                 sc->sc_ioutb = 0;
  364                 sc->sc_inb = 0;
  365                 sc->sc_outb = 0;
  366                 sc->sc_linb = 0;
  367                 sc->sc_loutb = 0;
  368                 sc->sc_fn = 1;
  369 #endif
  370 #if IPR_LOG
  371                 sc->sc_log_first = IPR_LOG;
  372 #endif
  373 
  374 #ifdef  IRIP_VJ
  375 #ifdef __FreeBSD__
  376                 sl_compress_init(&sc->sc_compr, -1);
  377 #else
  378                 sl_compress_init(&sc->sc_compr);
  379 #endif
  380 
  381 #ifdef IPR_VJ_USEBUFFER
  382                 if(!((sc->sc_cbuf =
  383                    (u_char *)malloc(I4BIPRMAXMTU+128, M_DEVBUF, M_WAITOK))))
  384                 {
  385                         panic("if_ipr.c, ipr_attach: VJ malloc failed");
  386                 }
  387 #endif
  388 #endif
  389 
  390                 sc->sc_updown = SOFT_ENA;       /* soft enabled */
  391 
  392                 sc->sc_dialresp = DSTAT_NONE;   /* no response */
  393                 sc->sc_lastdialresp = DSTAT_NONE;
  394 
  395 #if defined(__FreeBSD_version) && ((__FreeBSD_version >= 500009) || (410000 <= __FreeBSD_version && __FreeBSD_version < 500000))
  396                 /* do not call bpfattach in ether_ifattach */
  397                 ether_ifattach(&sc->sc_if, 0);
  398 #else
  399                 if_attach(&sc->sc_if);
  400                 if_alloc_sadl(&sc->sc_if);
  401 #endif
  402 
  403 #if NBPFILTER > 0 || NBPF > 0
  404 #ifdef __FreeBSD__
  405                 bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int));
  406 #else
  407                 bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int));
  408 #endif
  409 #endif
  410         }
  411 }
  412 
  413 /*---------------------------------------------------------------------------*
  414  *      output a packet to the ISDN B-channel
  415  *---------------------------------------------------------------------------*/
  416 static int
  417 iripoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
  418          struct rtentry *rtp)
  419 {
  420         struct ipr_softc *sc;
  421         int s, rv;
  422         struct ifqueue *ifq = NULL;
  423         struct ip *ip;
  424         ALTQ_DECL(struct altq_pktattr pktattr;)
  425 
  426         s = splnet();
  427 
  428 #if defined(__FreeBSD__) || defined(__bsdi__)
  429         unit = ifp->if_unit;
  430         sc = &ipr_softc[unit];
  431 #else
  432         sc = ifp->if_softc;
  433 #endif
  434 
  435         /* check for IP */
  436 
  437         if(dst->sa_family != AF_INET)
  438         {
  439                 printf(IPR_FMT "af%d not supported\n", IPR_ARG(sc), dst->sa_family);
  440                 m_freem(m);
  441                 splx(s);
  442                 sc->sc_if.if_noproto++;
  443                 sc->sc_if.if_oerrors++;
  444                 return(EAFNOSUPPORT);
  445         }
  446 
  447         /* check interface state = UP */
  448 
  449         if(!(ifp->if_flags & IFF_UP))
  450         {
  451                 NDBGL4(L4_IPRDBG, "%s: interface is DOWN!", sc->sc_if.if_xname);
  452                 m_freem(m);
  453                 splx(s);
  454                 sc->sc_if.if_oerrors++;
  455                 return(ENETDOWN);
  456         }
  457 
  458         /* dial if necessary */
  459 
  460         if(sc->sc_state == ST_IDLE || sc->sc_state == ST_DIALING)
  461         {
  462 
  463 #ifdef NOTDEF
  464                 switch(sc->sc_dialresp)
  465                 {
  466                         case DSTAT_TFAIL:       /* transient failure */
  467                                 NDBGL4(L4_IPRDBG, "%s: transient dial failure!", sc->sc_if.if_xname);
  468                                 m_freem(m);
  469                                 iripclearqueues(sc);
  470                                 sc->sc_dialresp = DSTAT_NONE;
  471                                 splx(s);
  472                                 sc->sc_if.if_oerrors++;
  473                                 return(ENETUNREACH);
  474                                 break;
  475 
  476                         case DSTAT_PFAIL:       /* permanent failure */
  477                                 NDBGL4(L4_IPRDBG, "%s: permanent dial failure!", sc->sc_if.if_xname);
  478                                 m_freem(m);
  479                                 iripclearqueues(sc);
  480                                 sc->sc_dialresp = DSTAT_NONE;
  481                                 splx(s);
  482                                 sc->sc_if.if_oerrors++;
  483                                 return(EHOSTUNREACH);
  484                                 break;
  485 
  486                         case DSTAT_INONLY:      /* no dialout allowed*/
  487                                 NDBGL4(L4_IPRDBG, "%s: dialout not allowed failure!", sc->sc_if.if_xname);
  488                                 m_freem(m);
  489                                 iripclearqueues(sc);
  490                                 sc->sc_dialresp = DSTAT_NONE;
  491                                 splx(s);
  492                                 sc->sc_if.if_oerrors++;
  493                                 return(EHOSTUNREACH);
  494                                 break;
  495                 }
  496 #endif
  497 
  498                 NDBGL4(L4_IPRDBG, "%s: send dial request message!", sc->sc_if.if_xname);
  499                 NDBGL4(L4_DIALST, "%s: setting dial state to ST_DIALING", sc->sc_if.if_xname);
  500                 i4b_l4_dialout(irip_driver_id, sc->sc_unit);
  501                 sc->sc_state = ST_DIALING;
  502         }
  503 
  504 #if IPR_LOG
  505         if(sc->sc_log_first > 0)
  506         {
  507                 --(sc->sc_log_first);
  508                 i4b_l4_packet_ind(irip_driver_id, sc->sc_unit, 1, m );
  509         }
  510 #endif
  511 
  512         /*
  513          * check, if type of service indicates interactive, i.e. telnet,
  514          * traffic. in case it is interactive, put it into the fast queue,
  515          * else (i.e. ftp traffic) put it into the "normal" queue
  516          */
  517 
  518         IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family, &pktattr);
  519 
  520         ip = mtod(m, struct ip *);              /* get ptr to ip header */
  521 
  522         if(ip->ip_tos & IPTOS_LOWDELAY)
  523                 ifq = &sc->sc_fastq;
  524 
  525         /* check for space in choosen send queue */
  526 
  527         if ((ifq != NULL)
  528 #ifdef ALTQ
  529            && ALTQ_IS_ENABLED(&sc->sc_if.if_snd) == 0
  530 #endif
  531         ) {
  532                 if(IF_QFULL(ifq))
  533                 {
  534                         NDBGL4(L4_IPRDBG, "%s: send queue full!", sc->sc_if.if_xname);
  535                         IF_DROP(ifq);
  536                         m_freem(m);
  537                         sc->sc_if.if_oerrors++;
  538                         splx(s);
  539                         return(ENOBUFS);
  540                 }
  541                 IF_ENQUEUE(ifq, m);
  542         } else {
  543                 IFQ_ENQUEUE(&sc->sc_if.if_snd, m, &pktattr, rv);
  544                 if (rv != 0) {
  545                         sc->sc_if.if_oerrors++;
  546                         splx(s);
  547                         return rv;
  548                 }
  549         }
  550 
  551         NDBGL4(L4_IPRDBG, "%s: added packet to send queue!", sc->sc_if.if_xname);
  552 
  553         ipr_tx_queue_empty(sc);
  554 
  555         splx(s);
  556 
  557         return (0);
  558 }
  559 
  560 /*---------------------------------------------------------------------------*
  561  *      process ioctl
  562  *---------------------------------------------------------------------------*/
  563 #ifdef __FreeBSD__
  564 static int
  565 iripioctl(struct ifnet *ifp, IOCTL_CMD_T cmd, caddr_t data)
  566 #else
  567 static int
  568 iripioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
  569 #endif
  570 {
  571 #if defined(__FreeBSD__) || defined(__bsdi__)
  572         struct ipr_softc *sc = &ipr_softc[ifp->if_unit];
  573 #else
  574         struct ipr_softc *sc = ifp->if_softc;
  575 #endif
  576 
  577         struct ifreq *ifr = (struct ifreq *)data;
  578         struct ifaddr *ifa = (struct ifaddr *)data;
  579         int s;
  580         int error = 0;
  581 
  582         s = splnet();
  583 
  584         switch (cmd)
  585         {
  586                 case SIOCAIFADDR:       /* add interface address */
  587                 case SIOCSIFADDR:       /* set interface address */
  588                 case SIOCSIFDSTADDR:    /* set interface destination address */
  589                         if(ifa->ifa_addr->sa_family != AF_INET)
  590                                 error = EAFNOSUPPORT;
  591                         else
  592                                 sc->sc_if.if_flags |= IFF_UP;
  593                         break;
  594 
  595                 case SIOCSIFFLAGS:      /* set interface flags */
  596                         if(!(ifr->ifr_flags & IFF_UP))
  597                         {
  598                                 if(sc->sc_if.if_flags & IFF_RUNNING)
  599                                 {
  600                                         /* disconnect ISDN line */
  601                                         i4b_l4_drvrdisc(sc->sc_cdp->cdid);
  602                                         sc->sc_if.if_flags &= ~IFF_RUNNING;
  603                                 }
  604 
  605                                 sc->sc_state = ST_IDLE;
  606 
  607                                 /* empty queues */
  608 
  609                                 iripclearqueues(sc);
  610                         }
  611 
  612                         if(ifr->ifr_flags & IFF_DEBUG)
  613                         {
  614                                 /* enable debug messages */
  615                         }
  616 
  617                         break;
  618 
  619 #if !defined(__OpenBSD__)
  620                 case SIOCSIFMTU:        /* set interface MTU */
  621                         if(ifr->ifr_mtu > I4BIPRMAXMTU)
  622                                 error = EINVAL;
  623                         else if(ifr->ifr_mtu < I4BIPRMINMTU)
  624                                 error = EINVAL;
  625                         else
  626                                 ifp->if_mtu = ifr->ifr_mtu;
  627                         break;
  628 #endif /* __OPENBSD__ */
  629 
  630 #if 0
  631         /* not needed for FreeBSD, done in sl_compress_init() (-hm) */
  632 
  633                         /* need to add an ioctl:        set VJ max slot ID
  634                          * #define IPRIOCSMAXCID        _IOW('I', XXX, int)
  635                          */
  636 #ifdef IPR_VJ
  637                 case IPRIOCSMAXCID:
  638                         {
  639 #if defined(__FreeBSD_version) && __FreeBSD_version >= 400005
  640                         struct proc *p = curproc;       /* XXX */
  641 
  642                         if((error = suser(p)) != 0)
  643 #else
  644                         struct lwp *l = curlwp;         /* XXX */
  645 
  646                         if((error = kauth_authorize_network(l->l_cred,
  647                             KAUTH_NETWORK_INTERFACE,
  648                             KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp,
  649                             (void *)cmd, NULL)) != 0)
  650 #endif
  651                                 break;
  652                         sl_compress_setup(sc->sc_compr, *(int *)data);
  653                         }
  654                         break;
  655 #endif
  656 #endif
  657                 default:
  658                         error = EINVAL;
  659                         break;
  660         }
  661 
  662         splx(s);
  663 
  664         return(error);
  665 }
  666 
  667 /*---------------------------------------------------------------------------*
  668  *      clear the interface's send queues
  669  *---------------------------------------------------------------------------*/
  670 static void
  671 iripclearqueues(struct ipr_softc *sc)
  672 {
  673         int x;
  674         struct mbuf *m;
  675 
  676         for(;;)
  677         {
  678                 x = splnet();
  679                 IF_DEQUEUE(&sc->sc_fastq, m);
  680                 splx(x);
  681 
  682                 if(m)
  683                         m_freem(m);
  684                 else
  685                         break;
  686         }
  687 
  688         for(;;)
  689         {
  690                 x = splnet();
  691                 IFQ_DEQUEUE(&sc->sc_if.if_snd, m);
  692                 splx(x);
  693 
  694                 if(m)
  695                         m_freem(m);
  696                 else
  697                         break;
  698         }
  699 }
  700 
  701 #if I4BIPRACCT
  702 /*---------------------------------------------------------------------------*
  703  *      watchdog routine
  704  *---------------------------------------------------------------------------*/
  705 #ifdef __bsdi__
  706 static int
  707 iprwatchdog(int unit)
  708 {
  709 #else
  710 static void
  711 iprwatchdog(struct ifnet *ifp)
  712 {
  713 #endif
  714 #ifdef __FreeBSD__
  715         int unit = ifp->if_unit;
  716         struct ipr_softc *sc = &ipr_softc[unit];
  717 #elif defined(__bsdi__)
  718         struct ipr_softc *sc = &ipr_softc[unit];
  719         struct ifnet *ifp = &ipr_softc[unit].sc_if;
  720 #else
  721         struct ipr_softc *sc = ifp->if_softc;
  722 #endif
  723         bchan_statistics_t bs;
  724 
  725         /* get # of bytes in and out from the HSCX driver */
  726 
  727         (*sc->sc_ilt->bchannel_driver->bch_stat)
  728                 (sc->sc_ilt->l1token, sc->sc_ilt->channel, &bs);
  729 
  730         sc->sc_ioutb += bs.outbytes;
  731         sc->sc_iinb += bs.inbytes;
  732 
  733         if((sc->sc_iinb != sc->sc_linb) || (sc->sc_ioutb != sc->sc_loutb) || sc->sc_fn)
  734         {
  735                 int ri = (sc->sc_iinb - sc->sc_linb)/I4BIPRACCTINTVL;
  736                 int ro = (sc->sc_ioutb - sc->sc_loutb)/I4BIPRACCTINTVL;
  737 
  738                 if((sc->sc_iinb == sc->sc_linb) && (sc->sc_ioutb == sc->sc_loutb))
  739                         sc->sc_fn = 0;
  740                 else
  741                         sc->sc_fn = 1;
  742 
  743                 sc->sc_linb = sc->sc_iinb;
  744                 sc->sc_loutb = sc->sc_ioutb;
  745 
  746                 if (sc->sc_cdp)
  747                         i4b_l4_accounting(sc->sc_cdp->cdid, ACCT_DURING,
  748                             sc->sc_ioutb, sc->sc_iinb, ro, ri, sc->sc_outb, sc->sc_inb);
  749         }
  750         sc->sc_if.if_timer = I4BIPRACCTINTVL;
  751 #ifdef __bsdi__
  752         return 0;
  753 #endif
  754 }
  755 #endif /* I4BIPRACCT */
  756 
  757 /*===========================================================================*
  758  *                      ISDN INTERFACE ROUTINES
  759  *===========================================================================*/
  760 
  761 /*---------------------------------------------------------------------------*
  762  *      start transmitting after connect
  763  *---------------------------------------------------------------------------*/
  764 static void
  765 i4bipr_connect_startio(struct ipr_softc *sc)
  766 {
  767         int s = splnet();
  768 
  769         if(sc->sc_state == ST_CONNECTED_W)
  770         {
  771                 sc->sc_state = ST_CONNECTED_A;
  772                 ipr_tx_queue_empty(sc);
  773         }
  774 
  775         splx(s);
  776 }
  777 
  778 /*---------------------------------------------------------------------------*
  779  *      this routine is called from L4 handler at connect time
  780  *---------------------------------------------------------------------------*/
  781 static void
  782 ipr_connect(void *softc, void *cdp)
  783 {
  784         struct ipr_softc *sc = softc;
  785         int s;
  786 
  787         sc->sc_cdp = (call_desc_t *)cdp;
  788 
  789         s = splnet();
  790 
  791         NDBGL4(L4_DIALST, "%s: setting dial state to ST_CONNECTED", sc->sc_if.if_xname);
  792 
  793         sc->sc_if.if_flags |= IFF_RUNNING;
  794         sc->sc_state = ST_CONNECTED_W;
  795 
  796         sc->sc_dialresp = DSTAT_NONE;
  797         sc->sc_lastdialresp = DSTAT_NONE;
  798 
  799 #if I4BIPRACCT
  800         sc->sc_iinb = 0;
  801         sc->sc_ioutb = 0;
  802         sc->sc_inb = 0;
  803         sc->sc_outb = 0;
  804         sc->sc_linb = 0;
  805         sc->sc_loutb = 0;
  806         sc->sc_if.if_timer = I4BIPRACCTINTVL;
  807 #endif
  808 
  809 #ifdef I4BIPRADJFRXP
  810         sc->sc_first_pkt = 1;
  811 #endif
  812 
  813         /*
  814          * Sometimes ISDN B-channels are switched thru asymmetic. This
  815          * means that under such circumstances B-channel data (the first
  816          * three packets of a TCP connection in my case) may get lost,
  817          * causing a large delay until the connection is started.
  818          * When the sending of the very first packet of a TCP connection
  819          * is delayed for a to be empirically determined delay (close
  820          * to a second in my case) those packets go thru and the TCP
  821          * connection comes up "almost" immediately (-hm).
  822          */
  823 
  824         if(sc->sc_cdp->isdntxdelay > 0)
  825         {
  826                 int xdelay;
  827 
  828                 if (hz == 100) {
  829                         xdelay = sc->sc_cdp->isdntxdelay;       /* avoid any rounding */
  830                 } else {
  831                         xdelay = sc->sc_cdp->isdntxdelay*hz;
  832                         xdelay /= 100;
  833                 }
  834 
  835                 START_TIMER(sc->sc_callout, (TIMEOUT_FUNC_T)i4bipr_connect_startio, (void *)sc,  xdelay);
  836         }
  837         else
  838         {
  839                 sc->sc_state = ST_CONNECTED_A;
  840                 ipr_tx_queue_empty(sc);
  841         }
  842 
  843         splx(s);
  844 
  845         /* we don't need any negotiation - pass event back right now */
  846         i4b_l4_negcomplete(sc->sc_cdp);
  847 }
  848 
  849 /*---------------------------------------------------------------------------*
  850  *      this routine is called from L4 handler at disconnect time
  851  *---------------------------------------------------------------------------*/
  852 static void
  853 ipr_disconnect(void *softc, void *cdp)
  854 {
  855         call_desc_t *cd = (call_desc_t *)cdp;
  856         struct ipr_softc *sc = softc;
  857 
  858         /* new stuff to check that the active channel is being closed */
  859 
  860         if (cd != sc->sc_cdp)
  861         {
  862                 NDBGL4(L4_IPRDBG, "%s: channel %d not active",
  863                                 sc->sc_if.if_xname, cd->channelid);
  864                 return;
  865         }
  866 
  867 #if I4BIPRACCT
  868         sc->sc_if.if_timer = 0;
  869 #endif
  870 #if IPR_LOG
  871         /* show next IPR_LOG packets again */
  872         sc->sc_log_first = IPR_LOG;
  873 #endif
  874 
  875         i4b_l4_accounting(cd->cdid, ACCT_FINAL,
  876                  sc->sc_ioutb, sc->sc_iinb, 0, 0, sc->sc_outb, sc->sc_inb);
  877 
  878         sc->sc_cdp = NULL;
  879 
  880         NDBGL4(L4_DIALST, "setting dial state to ST_IDLE");
  881 
  882         sc->sc_dialresp = DSTAT_NONE;
  883         sc->sc_lastdialresp = DSTAT_NONE;
  884 
  885         sc->sc_if.if_flags &= ~IFF_RUNNING;
  886         sc->sc_state = ST_IDLE;
  887 }
  888 
  889 /*---------------------------------------------------------------------------*
  890  *      this routine is used to give a feedback from userland daemon
  891  *      in case of dial problems
  892  *---------------------------------------------------------------------------*/
  893 static void
  894 ipr_dialresponse(void *softc, int status, cause_t cause)
  895 {
  896         struct ipr_softc *sc = softc;
  897         sc->sc_dialresp = status;
  898 
  899         NDBGL4(L4_IPRDBG, "%s: last=%d, this=%d",
  900                 sc->sc_if.if_xname, sc->sc_lastdialresp, sc->sc_dialresp);
  901 
  902         if(status != DSTAT_NONE)
  903         {
  904                 NDBGL4(L4_IPRDBG, "%s: clearing queues", sc->sc_if.if_xname);
  905                 iripclearqueues(sc);
  906         }
  907 }
  908 
  909 /*---------------------------------------------------------------------------*
  910  *      interface soft up/down
  911  *---------------------------------------------------------------------------*/
  912 static void
  913 ipr_updown(void *softc, int updown)
  914 {
  915         struct ipr_softc *sc = softc;
  916         sc->sc_updown = updown;
  917 }
  918 
  919 /*---------------------------------------------------------------------------*
  920  *      this routine is called from the HSCX interrupt handler
  921  *      when a new frame (mbuf) has been received and was put on
  922  *      the rx queue. It is assumed that this routines runs at
  923  *      appropriate protection level! Keep it short !
  924  *---------------------------------------------------------------------------*/
  925 static void
  926 ipr_rx_data_rdy(void *softc)
  927 {
  928         register struct ipr_softc *sc = softc;
  929         register struct mbuf *m;
  930 #ifdef IRIP_VJ
  931 #ifdef IPR_VJ_USEBUFFER
  932         u_char *cp = sc->sc_cbuf;
  933 #endif
  934         int len, c;
  935 #endif
  936 
  937         if((m = *sc->sc_ilt->rx_mbuf) == NULL)
  938                 return;
  939 
  940         m->m_pkthdr.rcvif = &sc->sc_if;
  941 
  942         m->m_pkthdr.len = m->m_len;
  943 
  944 #ifdef I4BIPRADJFRXP
  945 
  946         /*
  947          * The very first packet after the B channel is switched thru
  948          * has very often several bytes of random data prepended. This
  949          * routine looks where the IP header starts and removes the
  950          * the bad data.
  951          */
  952 
  953         if(sc->sc_first_pkt)
  954         {
  955                 unsigned char *mp = m->m_data;
  956                 int i;
  957 
  958                 sc->sc_first_pkt = 0;
  959 
  960                 for(i = 0; i < m->m_len; i++, mp++)
  961                 {
  962                         if( ((*mp & 0xf0) == 0x40) &&
  963                             ((*mp & 0x0f) >= 0x05) )
  964                         {
  965                                 m->m_data = mp;
  966                                 m->m_pkthdr.len -= i;
  967                                 break;
  968                         }
  969                 }
  970         }
  971 #endif
  972 
  973         sc->sc_if.if_ipackets++;
  974         sc->sc_if.if_ibytes += m->m_pkthdr.len;
  975 
  976 #ifdef  IRIP_VJ
  977         if((c = (*(mtod(m, u_char *)) & 0xf0)) != (IPVERSION << 4))
  978         {
  979                 /* copy data to buffer */
  980 
  981                 len = m->m_len;
  982 
  983 #ifdef IPR_VJ_USEBUFFER
  984 /* XXX */       m_copydata(m, 0, len, cp);
  985 #endif
  986 
  987                 if(c & 0x80)
  988                 {
  989                         c = TYPE_COMPRESSED_TCP;
  990                 }
  991                 else if(c == TYPE_UNCOMPRESSED_TCP)
  992                 {
  993 #ifdef IPR_VJ_USEBUFFER
  994                         *cp &= 0x4f;            /* XXX */
  995 #else
  996                         *(mtod(m, u_char *)) &= 0x4f;
  997 #endif
  998                 }
  999 
 1000                 /*
 1001                  * We've got something that's not an IP packet.
 1002                  * If compression is enabled, try to decompress it.
 1003                  * Otherwise, if `auto-enable' compression is on and
 1004                  * it's a reasonable packet, decompress it and then
 1005                  * enable compression.  Otherwise, drop it.
 1006                  */
 1007                 if(sc->sc_if.if_flags & IPR_COMPRESS)
 1008                 {
 1009 #ifdef IPR_VJ_USEBUFFER
 1010                         len = sl_uncompress_tcp(&cp,len,(u_int)c,&sc->sc_compr);
 1011 #else
 1012                         len = sl_uncompress_tcp((u_char **)&m->m_data, len,
 1013                                         (u_int)c, &sc->sc_compr);
 1014 #endif
 1015 
 1016                         if(len <= 0)
 1017                         {
 1018 #ifdef DEBUG_IPR_VJ
 1019                                 printf("i4b_ipr, ipr_rx_data_rdy: len <= 0 IPR_COMPRESS!\n");
 1020 #endif
 1021                                 goto error;
 1022                         }
 1023                 }
 1024                 else if((sc->sc_if.if_flags & IPR_AUTOCOMP) &&
 1025                         (c == TYPE_UNCOMPRESSED_TCP) && (len >= 40))
 1026                 {
 1027 #ifdef IPR_VJ_USEBUFFER
 1028                         len = sl_uncompress_tcp(&cp,len,(u_int)c,&sc->sc_compr);
 1029 #else
 1030                         len = sl_uncompress_tcp((u_char **)&m->m_data, len,
 1031                                         (u_int)c, &sc->sc_compr);
 1032 #endif
 1033 
 1034                         if(len <= 0)
 1035                         {
 1036 #ifdef DEBUG_IPR_VJ
 1037                                 printf("i4b_ipr, ipr_rx_data_rdy: len <= 0 IPR_AUTOCOMP!\n");
 1038 #endif
 1039                                 goto error;
 1040                         }
 1041 
 1042                         sc->sc_if.if_flags |= IPR_COMPRESS;
 1043                 }
 1044                 else
 1045                 {
 1046 #ifdef DEBUG_IPR_VJ
 1047                         printf("i4b_ipr, ipr_input: invalid ip packet!\n");
 1048 #endif
 1049 
 1050 error:
 1051                         sc->sc_if.if_ierrors++;
 1052                         sc->sc_if.if_collisions++;
 1053                         m_freem(m);
 1054                         return;
 1055                 }
 1056 #ifdef IPR_VJ_USEBUFFER
 1057 /* XXX */       m_copyback(m, 0, len, cp);
 1058 #else
 1059                 m->m_len = m->m_pkthdr.len = len;
 1060 #endif
 1061         }
 1062 #endif
 1063 
 1064 #if I4BIPRACCT
 1065         /* NB. do the accounting after decompression!           */
 1066         sc->sc_inb += m->m_pkthdr.len;
 1067 #endif
 1068 #if IPR_LOG
 1069         if(sc->sc_log_first > 0)
 1070         {
 1071                 --(sc->sc_log_first);
 1072                 i4b_l4_packet_ind(irip_driver_id, sc->sc_unit, 0, m );
 1073         }
 1074 #endif
 1075 
 1076 #if NBPFILTER > 0 || NBPF > 0
 1077         if(sc->sc_if.if_bpf)
 1078         {
 1079                 /* prepend the address family as a four byte field */
 1080                 struct mbuf mm;
 1081                 u_int af = AF_INET;
 1082                 mm.m_next = m;
 1083                 mm.m_len = 4;
 1084                 mm.m_data = (char *)&af;
 1085 
 1086 #ifdef __FreeBSD__
 1087                 bpf_mtap(&sc->sc_if, &mm);
 1088 #else
 1089                 bpf_mtap(sc->sc_if.if_bpf, &mm);
 1090 #endif
 1091         }
 1092 #endif /* NBPFILTER > 0  || NBPF > 0 */
 1093 
 1094         if(IF_QFULL(&ipintrq))
 1095         {
 1096                 NDBGL4(L4_IPRDBG, "%s: ipintrq full!", sc->sc_if.if_xname);
 1097 
 1098                 IF_DROP(&ipintrq);
 1099                 sc->sc_if.if_ierrors++;
 1100                 sc->sc_if.if_iqdrops++;
 1101                 m_freem(m);
 1102         }
 1103         else
 1104         {
 1105                 IF_ENQUEUE(&ipintrq, m);
 1106                 schednetisr(NETISR_IP);
 1107         }
 1108 }
 1109 
 1110 /*---------------------------------------------------------------------------*
 1111  *      this routine is called from the HSCX interrupt handler
 1112  *      when the last frame has been sent out and there is no
 1113  *      further frame (mbuf) in the tx queue.
 1114  *---------------------------------------------------------------------------*/
 1115 static void
 1116 ipr_tx_queue_empty(void *softc)
 1117 {
 1118         register struct ipr_softc *sc = softc;
 1119         register struct mbuf *m;
 1120 #ifdef  IRIP_VJ
 1121         struct ip *ip;
 1122 #endif
 1123         int x = 0;
 1124 
 1125         if(sc->sc_state != ST_CONNECTED_A)
 1126                 return;
 1127 
 1128         for(;;)
 1129         {
 1130                 IF_DEQUEUE(&sc->sc_fastq, m);
 1131                 if(m)
 1132                 {
 1133                         sc->sc_if.if_omcasts++;
 1134                 }
 1135                 else
 1136                 {
 1137                         IFQ_DEQUEUE(&sc->sc_if.if_snd, m);
 1138                         if(m == NULL)
 1139                                 break;
 1140                 }
 1141 
 1142 #if NBPFILTER > 0 || NBPF > 0
 1143                 if(sc->sc_if.if_bpf)
 1144                 {
 1145                         /* prepend the address family as a four byte field */
 1146 
 1147                         struct mbuf mm;
 1148                         u_int af = AF_INET;
 1149                         mm.m_next = m;
 1150                         mm.m_len = 4;
 1151                         mm.m_data = (char *)&af;
 1152 
 1153 #ifdef __FreeBSD__
 1154                         bpf_mtap(&sc->sc_if, &mm);
 1155 #else
 1156                         bpf_mtap(sc->sc_if.if_bpf, &mm);
 1157 #endif
 1158                 }
 1159 #endif /* NBPFILTER */
 1160 
 1161 #if I4BIPRACCT
 1162                 sc->sc_outb += m->m_pkthdr.len; /* size before compression */
 1163 #endif
 1164 
 1165 #ifdef  IRIP_VJ
 1166                 if((ip = mtod(m, struct ip *))->ip_p == IPPROTO_TCP)
 1167                 {
 1168                         if(sc->sc_if.if_flags & IPR_COMPRESS)
 1169                         {
 1170                                 *mtod(m, u_char *) |= sl_compress_tcp(m, ip,
 1171                                         &sc->sc_compr, 1);
 1172                         }
 1173                 }
 1174 #endif
 1175                 x = 1;
 1176 
 1177                 if(IF_QFULL(sc->sc_ilt->tx_queue))
 1178                 {
 1179                         NDBGL4(L4_IPRDBG, "%s: tx queue full!", sc->sc_if.if_xname);
 1180                         m_freem(m);
 1181                 }
 1182                 else
 1183                 {
 1184                         IF_ENQUEUE(sc->sc_ilt->tx_queue, m);
 1185 
 1186                         sc->sc_if.if_obytes += m->m_pkthdr.len;
 1187 
 1188                         sc->sc_if.if_opackets++;
 1189                 }
 1190         }
 1191 
 1192         if(x)
 1193                 (*sc->sc_ilt->bchannel_driver->bch_tx_start)(sc->sc_ilt->l1token, sc->sc_ilt->channel);
 1194 }
 1195 
 1196 /*---------------------------------------------------------------------------*
 1197  *      this routine is called from the HSCX interrupt handler
 1198  *      each time a packet is received or transmitted. It should
 1199  *      be used to implement an activity timeout mechanism.
 1200  *---------------------------------------------------------------------------*/
 1201 static void
 1202 ipr_activity(void *softc, int rxtx)
 1203 {
 1204         struct ipr_softc *sc = softc;
 1205         sc->sc_cdp->last_active_time = SECOND;
 1206 }
 1207 
 1208 /*---------------------------------------------------------------------------*
 1209  *      return this drivers linktab address
 1210  *---------------------------------------------------------------------------*/
 1211 static void*
 1212 ipr_get_softc(int unit)
 1213 {
 1214         return &ipr_softc[unit];
 1215 }
 1216 
 1217 /*---------------------------------------------------------------------------*
 1218  *      setup the isdn_linktab for this driver
 1219  *---------------------------------------------------------------------------*/
 1220 static void
 1221 ipr_set_linktab(void *softc, isdn_link_t *ilt)
 1222 {
 1223         struct ipr_softc *sc = softc;
 1224         sc->sc_ilt = ilt;
 1225 }
 1226 
 1227 /*===========================================================================*/
 1228 
 1229 #endif /* NIRIP > 0 */

Cache object: 9395b87d5f7549c0ebf64f93c0c1300a


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