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/dev/ieee1394/if_fw.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 /*      $NetBSD: if_fw.c,v 1.21 2004/04/30 01:31:43 lukem Exp $ */
    2 
    3 /* XXX ALTQ XXX */
    4 
    5 /*
    6  * Copyright (c) 2000 The NetBSD Foundation, Inc.
    7  * All rights reserved.
    8  *
    9  * This code is derived from software contributed to The NetBSD Foundation
   10  * by Atsushi Onoe.
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice, this list of conditions and the following disclaimer.
   17  * 2. Redistributions in binary form must reproduce the above copyright
   18  *    notice, this list of conditions and the following disclaimer in the
   19  *    documentation and/or other materials provided with the distribution.
   20  * 3. All advertising materials mentioning features or use of this software
   21  *    must display the following acknowledgement:
   22  *      This product includes software developed by the NetBSD
   23  *      Foundation, Inc. and its contributors.
   24  * 4. Neither the name of The NetBSD Foundation nor the names of its
   25  *    contributors may be used to endorse or promote products derived
   26  *    from this software without specific prior written permission.
   27  *
   28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   38  * POSSIBILITY OF SUCH DAMAGE.
   39  */
   40 
   41 #include <sys/cdefs.h>
   42 __KERNEL_RCSID(0, "$NetBSD: if_fw.c,v 1.21 2004/04/30 01:31:43 lukem Exp $");
   43 
   44 #include "opt_inet.h"
   45 #include "bpfilter.h"
   46 
   47 #include <sys/param.h>
   48 #include <sys/systm.h>
   49 #include <sys/socket.h>
   50 #include <sys/sockio.h>
   51 #include <sys/kernel.h>
   52 #include <sys/mbuf.h>
   53 #include <sys/device.h>
   54 
   55 #include <net/if.h>
   56 #include <net/if_dl.h>
   57 #include <net/if_ieee1394.h>
   58 #include <net/if_types.h>
   59 #include <net/if_media.h>
   60 #include <net/route.h>
   61 
   62 #ifdef INET
   63 #include <netinet/in.h>
   64 #endif /* INET */
   65 
   66 #ifdef INET6
   67 #include <netinet/in.h>
   68 #include <netinet6/in6_var.h>
   69 #endif /* INET6 */
   70 
   71 #if NBPFILTER > 0
   72 #include <net/bpf.h>
   73 #endif
   74 
   75 #include <machine/bus.h>
   76 
   77 #include <dev/ieee1394/ieee1394reg.h>
   78 #include <dev/ieee1394/ieee1394var.h>
   79 
   80 struct fw_softc {
   81         struct ieee1394_softc sc_sc1394;
   82         struct ieee1394com sc_ic;
   83 
   84         int sc_flags;
   85 
   86         int (*sc_enable)(struct fw_softc *);
   87         void (*sc_disable)(struct fw_softc *);
   88 };
   89 
   90 #define FWF_ATTACHED    0x0001
   91 #define FWF_ENABLED     0x0002
   92 
   93 int  fw_match(struct device *, struct cfdata *, void *);
   94 void fw_attach(struct device *, struct device *, void *);
   95 int  fw_detach(struct device *, int);
   96 int  fw_activate(struct device *, enum devact);
   97 
   98 void fw_input(struct device *, struct mbuf *);
   99 void fw_txint(struct device *, struct mbuf *);
  100 int  fw_ioctl(struct ifnet *, u_long, caddr_t);
  101 void fw_start(struct ifnet *);
  102 int  fw_init(struct ifnet *);
  103 void fw_stop(struct ifnet *, int);
  104 
  105 CFATTACH_DECL(fw, sizeof(struct fw_softc),
  106     fw_match, fw_attach, fw_detach, fw_activate);
  107 
  108 int
  109 fw_match(struct device *parent, struct cfdata *match, void *aux)
  110 {
  111         char *name = aux;
  112 
  113         if (strcmp(name, "fw") == 0)
  114                 return 1;
  115         return 0;
  116 }
  117 
  118 void
  119 fw_attach(struct device *parent, struct device *self, void *aux)
  120 {
  121         struct fw_softc *sc = (struct fw_softc *)self;
  122         struct ieee1394_softc *psc = (struct ieee1394_softc *)parent;
  123         struct ifnet *ifp = &sc->sc_ic.ic_if;
  124         int i, s;
  125 
  126         s = splnet();
  127 
  128         memcpy(&sc->sc_ic.ic_hwaddr.iha_uid, psc->sc1394_guid,
  129             IEEE1394_ADDR_LEN);
  130         sc->sc_ic.ic_hwaddr.iha_speed = psc->sc1394_link_speed;
  131         for (i = 0; i < 32; i++) {
  132                 if ((psc->sc1394_max_receive >> (i + 2)) == 0)
  133                         break;
  134         }
  135         sc->sc_ic.ic_hwaddr.iha_maxrec = i;
  136         sc->sc_ic.ic_hwaddr.iha_offset[0] = (FW_FIFO_HI >> 8) & 0xff;
  137         sc->sc_ic.ic_hwaddr.iha_offset[1] = FW_FIFO_HI & 0xff;
  138         sc->sc_ic.ic_hwaddr.iha_offset[2] = (FW_FIFO_LO >> 24) & 0xff;
  139         sc->sc_ic.ic_hwaddr.iha_offset[3] = (FW_FIFO_LO >> 16) & 0xff;
  140         sc->sc_ic.ic_hwaddr.iha_offset[4] = (FW_FIFO_LO >>  8) & 0xff;
  141         sc->sc_ic.ic_hwaddr.iha_offset[5] = FW_FIFO_LO & 0xff;
  142         printf(":");
  143         for (i = 0; i < sizeof(sc->sc_ic.ic_hwaddr); i++)
  144                 printf("%c%02x", (i == 0 ? ' ' : ':'),
  145                     ((u_int8_t *)&sc->sc_ic.ic_hwaddr)[i]);
  146         printf("\n");
  147         if (sc->sc_ic.ic_hwaddr.iha_maxrec < 8) {
  148                 printf("%s: maximum receive packet (%d) is too small\n",
  149                     sc->sc_sc1394.sc1394_dev.dv_xname, psc->sc1394_max_receive);
  150                 splx(s);
  151                 return;
  152         }
  153 
  154         strcpy(ifp->if_xname, sc->sc_sc1394.sc1394_dev.dv_xname);
  155         ifp->if_softc = sc;
  156 #if __NetBSD_Version__ >= 105080000
  157         ifp->if_init = fw_init;
  158         ifp->if_stop = fw_stop;
  159 #endif
  160         ifp->if_start = fw_start;
  161         ifp->if_ioctl = fw_ioctl;
  162         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
  163         ifp->if_baudrate = IF_Mbps(100 << sc->sc_ic.ic_hwaddr.iha_speed);
  164         ifp->if_addrlen = sizeof(struct ieee1394_hwaddr);
  165         IFQ_SET_READY(&ifp->if_snd);
  166 
  167         if_attach(ifp);
  168         ieee1394_ifattach(ifp, &sc->sc_ic.ic_hwaddr);
  169 
  170         sc->sc_flags |= FWF_ATTACHED;
  171 
  172         splx(s);
  173 }
  174 
  175 int
  176 fw_detach(struct device *self, int flags)
  177 {
  178         struct fw_softc *sc = (struct fw_softc *)self;
  179         struct ifnet *ifp = &sc->sc_ic.ic_if;
  180 
  181         /* Succeed if there is no work to do. */
  182         if ((sc->sc_flags & FWF_ATTACHED) == 0)
  183                 return 0;
  184 
  185         ieee1394_ifdetach(ifp);
  186         if_detach(ifp);
  187         if (sc->sc_flags & FWF_ENABLED) {
  188                 if (sc->sc_disable)
  189                         (*sc->sc_disable)(sc);
  190                 sc->sc_flags &= ~FWF_ENABLED;
  191         }
  192         return 0;
  193 }
  194 
  195 int
  196 fw_activate(struct device *self, enum devact act)
  197 {
  198         struct fw_softc *sc = (struct fw_softc *)self;
  199         int s, error = 0;
  200 
  201         s = splnet();
  202         switch (act) {
  203         case DVACT_ACTIVATE:
  204                 error = EOPNOTSUPP;
  205                 break;
  206 
  207         case DVACT_DEACTIVATE:
  208                 if_deactivate(&sc->sc_ic.ic_if);
  209                 break;
  210         }
  211         splx(s);
  212 
  213         return error;
  214 }
  215 
  216 int
  217 fw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
  218 {
  219         int s, error = 0;
  220 
  221         s = splnet();
  222 
  223         switch (cmd) {
  224         default:
  225                 error = ieee1394_ioctl(ifp, cmd, data);
  226                 break;
  227         }
  228         splx(s);
  229         return error;
  230 }
  231 
  232 void
  233 fw_start(struct ifnet *ifp)
  234 {
  235         struct fw_softc *sc = (struct fw_softc *)ifp->if_softc;
  236         struct ieee1394_softc *psc =
  237             (struct ieee1394_softc *)sc->sc_sc1394.sc1394_dev.dv_parent;
  238         struct mbuf *m0;
  239         int error;
  240 
  241         if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
  242                 return;
  243         for (;;) {
  244                 IFQ_DEQUEUE(&ifp->if_snd, m0);
  245                 if (m0 == NULL)
  246                         break;
  247                 error = (*psc->sc1394_ifoutput)
  248                     (sc->sc_sc1394.sc1394_dev.dv_parent, m0, fw_txint);
  249                 if (error)
  250                         break;
  251         }
  252         if (m0 != NULL)
  253                 ifp->if_flags |= IFF_OACTIVE;
  254 }
  255 
  256 void
  257 fw_txint(struct device *self, struct mbuf *m0)
  258 {
  259         struct fw_softc *sc = (struct fw_softc *)self;
  260         struct ifnet *ifp = &sc->sc_ic.ic_if;
  261 
  262         ifp->if_opackets++;
  263         m_freem(m0);
  264         if (ifp->if_flags & IFF_OACTIVE) {
  265                 ifp->if_flags &= ~IFF_OACTIVE;
  266                 fw_start(ifp);
  267         }
  268 }
  269 
  270 int
  271 fw_init(struct ifnet *ifp)
  272 {
  273         struct fw_softc *sc = (struct fw_softc *)ifp->if_softc;
  274         struct ieee1394_softc *psc =
  275             (struct ieee1394_softc *)sc->sc_sc1394.sc1394_dev.dv_parent;
  276 
  277         (*psc->sc1394_ifinreg)
  278             (sc->sc_sc1394.sc1394_dev.dv_parent, FW_FIFO_HI, FW_FIFO_LO,
  279             fw_input);
  280         ifp->if_flags |= IFF_RUNNING;
  281         return 0;
  282 }
  283 
  284 void
  285 fw_stop(struct ifnet *ifp, int disable)
  286 {
  287         struct fw_softc *sc = (struct fw_softc *)ifp->if_softc;
  288         struct ieee1394_softc *psc =
  289             (struct ieee1394_softc *)sc->sc_sc1394.sc1394_dev.dv_parent;
  290 
  291         (*psc->sc1394_ifinreg)
  292             (sc->sc_sc1394.sc1394_dev.dv_parent, FW_FIFO_HI, FW_FIFO_LO,
  293             NULL);
  294         IFQ_PURGE(&ifp->if_snd);
  295         ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
  296 }
  297 
  298 void
  299 fw_input(struct device *self, struct mbuf *m0)
  300 {
  301         struct fw_softc *sc = (struct fw_softc *)self;
  302         struct ifnet *ifp = &sc->sc_ic.ic_if;
  303 
  304         ifp->if_ipackets++;
  305         m0->m_pkthdr.rcvif = ifp;
  306         (*ifp->if_input)(ifp, m0);
  307 }

Cache object: 66826ee908d7f344665acb4aa95016c4


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