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/arl/if_arl.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) 1999-2001, Ivan Sharov, Vitaly Belekhov.
    3  * Copyright (c) 2004 Stanislav Svirid.
    4  * 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  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 
   15  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  * 
   27  * $RISS: if_arl/dev/arl/if_arl.c,v 1.7 2004/03/16 04:43:27 count Exp $
   28  */
   29 
   30 #include <sys/cdefs.h>
   31 __FBSDID("$FreeBSD$");
   32 
   33 #include "opt_inet.h"
   34 
   35 #ifdef INET
   36 #define ARLCACHE
   37 #endif
   38 
   39 #include <sys/param.h>
   40 #include <sys/kernel.h>
   41 #include <sys/systm.h>
   42 #include <sys/malloc.h>
   43 #include <sys/mbuf.h>
   44 #include <sys/socket.h>
   45 #include <sys/sockio.h>
   46 #include <sys/proc.h>
   47 #include <sys/conf.h>
   48 
   49 #include <sys/module.h>
   50 #include <sys/bus.h>
   51 
   52 #include <machine/bus.h>
   53 #include <machine/resource.h>
   54 #include <sys/rman.h>
   55 
   56 #include <net/if.h>
   57 #include <net/if_arp.h>
   58 #include <net/if_media.h>
   59 #include <net/if_types.h>
   60 #include <net/ethernet.h>
   61 
   62 #include <net80211/ieee80211_var.h>
   63 
   64 #ifdef INET
   65 #include <netinet/in.h>
   66 #include <netinet/in_systm.h>
   67 #include <netinet/in_var.h>
   68 #include <netinet/ip.h>
   69 #endif
   70 
   71 #include <net/bpf.h>
   72 
   73 #include <machine/clock.h>
   74 
   75 #include <dev/arl/if_arlreg.h>
   76 
   77 /*#define DEBUG */
   78 #ifdef DEBUG
   79 #define D(x)    {printf("arl%d: ", sc->arl_unit); printf x; }
   80 #else
   81 #define D(x)
   82 #endif
   83 
   84 /*
   85  * channel attention
   86  */
   87 #define ARL_CHANNEL(sc) \
   88         { \
   89                 D(("channel ctrl %x reg %x\n", sc->arl_control, ar->controlRegister)); \
   90                 ar->controlRegister = (sc->arl_control ^= ARL_CHANNEL_ATTENTION); \
   91         }
   92 
   93 /*
   94  * Check registration
   95  */
   96 #define ARL_CHECKREG(sc) (ar->registrationMode && ar->registrationStatus == 0)
   97 
   98 #define GET_ARL_PARAM(name) (arcfg.name = ar->name)
   99 #define SET_ARL_PARAM(name) (ar->name = arcfg.name)
  100 
  101 #ifndef BPF_MTAP
  102 #define BPF_MTAP(_ifp,_m)                                       \
  103         do {                                                    \
  104                 if ((_ifp)->if_bpf)                             \
  105                         bpf_mtap((_ifp), (_m));                 \
  106         } while (0)
  107 #endif
  108 
  109 #if __FreeBSD_version < 500100
  110 #define BROADCASTADDR   (etherbroadcastaddr)
  111 #define _ARL_CURPROC    (curproc)
  112 #else
  113 #define BROADCASTADDR   (sc->arl_ifp->if_broadcastaddr)
  114 #define _ARL_CURPROC    (curthread)
  115 #endif
  116 
  117 static void     arl_hwreset     (struct arl_softc *);
  118 static void     arl_reset       (struct arl_softc *);
  119 static int      arl_ioctl       (struct ifnet *, u_long, caddr_t);
  120 static void     arl_init        (void *);
  121 static void     arl_start       (struct ifnet *);
  122 
  123 static void     arl_watchdog    (struct ifnet *);
  124 static void     arl_waitreg     (struct ifnet *);
  125 
  126 static void     arl_enable      (struct arl_softc *);
  127 static void     arl_config      (struct arl_softc *);
  128 static int      arl_command     (struct arl_softc *);
  129 static void     arl_put         (struct arl_softc *);
  130 
  131 static void     arl_read        (struct arl_softc *, caddr_t, int);
  132 static void     arl_recv        (struct arl_softc *);
  133 static struct mbuf* arl_get     (caddr_t, int, int, struct ifnet *);
  134 
  135 #ifdef ARLCACHE
  136 static void     arl_cache_store (struct arl_softc *, struct ether_header *,
  137                                         u_int8_t, u_int8_t, int);
  138 #endif
  139 
  140 static int  arl_media_change    (struct ifnet *);
  141 static void arl_media_status    (struct ifnet *, struct ifmediareq *);
  142 static void arl_read_config     (struct arl_softc *);
  143 
  144 devclass_t      arl_devclass;
  145 
  146 u_int8_t rate2media[4] = {
  147         IFM_IEEE80211_DS354k,
  148         IFM_IEEE80211_DS512k,
  149         IFM_IEEE80211_DS1,
  150         IFM_IEEE80211_DS2
  151 };
  152 
  153 /*
  154  * Copy config values to local cache
  155  */
  156 static void
  157 arl_read_config(sc)
  158         struct arl_softc *sc;
  159 {
  160         bzero(&arcfg, sizeof(arcfg));
  161 
  162         bcopy(ar->lanCardNodeId, arcfg.lanCardNodeId,
  163                 sizeof(ar->lanCardNodeId));
  164         bcopy(ar->specifiedRouter, arcfg.specifiedRouter,
  165                 sizeof(ar->specifiedRouter));
  166         GET_ARL_PARAM(hardwareType);
  167         GET_ARL_PARAM(majorHardwareVersion);
  168         GET_ARL_PARAM(minorHardwareVersion);
  169         GET_ARL_PARAM(radioModule);
  170         GET_ARL_PARAM(channelSet);
  171         if (!arcfg.channelSet)
  172                 arcfg.channelSet = ar->defaultChannelSet;
  173         GET_ARL_PARAM(channelNumber);
  174         GET_ARL_PARAM(spreadingCode);
  175         GET_ARL_PARAM(priority);
  176         GET_ARL_PARAM(receiveMode);
  177         arcfg.registrationMode = 1;     /* set default TMA mode */
  178         arcfg.txRetry = 0;
  179 
  180         bcopy(ar->name, arcfg.name, ARLAN_NAME_SIZE);
  181         bcopy(ar->systemId, arcfg.sid, 4 * sizeof(arcfg.sid[0]));
  182 }
  183 
  184 /*
  185  * Attach device
  186  */
  187 int
  188 arl_attach(dev)
  189         device_t        dev;
  190 {
  191         struct arl_softc* sc = device_get_softc(dev);
  192         struct ifnet *ifp;
  193         int             attached, configured = 0;
  194 
  195         D(("attach\n"));
  196 
  197         ifp = sc->arl_ifp = if_alloc(IFT_ETHER);
  198         if (ifp == NULL)
  199                 return (ENOSPC);
  200 
  201         configured = ar->configuredStatusFlag;
  202         attached = (ifp->if_softc != 0);
  203 
  204         if (!configured && bootverbose)
  205                 device_printf(dev, "card is not configured\n");
  206         else
  207                 arl_read_config(sc);
  208 
  209         arl_reset(sc);
  210 
  211         /* Read config for default values if card was not configured */
  212         if (!configured)
  213                 arl_read_config(sc);
  214 
  215         /* Initialize ifnet structure. */
  216         ifp->if_softc = sc;
  217 #if __FreeBSD_version < 502000
  218         ifp->if_unit = sc->arl_unit;
  219         ifp->if_name = "arl";
  220 #else
  221         if_initname(ifp, device_get_name(dev), device_get_unit(dev));
  222 #endif
  223         ifp->if_mtu = ETHERMTU;
  224         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
  225             IFF_NEEDSGIANT;
  226         ifp->if_start = arl_start;
  227         ifp->if_ioctl = arl_ioctl;
  228         ifp->if_watchdog = arl_watchdog;
  229         ifp->if_init = arl_init;
  230         ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
  231         ifp->if_baudrate = 2000000;
  232         ifp->if_timer = 0;
  233 
  234         ifmedia_init(&sc->arl_ifmedia, 0, arl_media_change, arl_media_status);
  235 #define ADD(s, o)       ifmedia_add(&sc->arl_ifmedia, \
  236         IFM_MAKEWORD(IFM_IEEE80211, (s), (o), 0), 0, NULL)
  237         ADD(IFM_IEEE80211_DS354k, 0);
  238         ADD(IFM_IEEE80211_DS354k, IFM_IEEE80211_ADHOC);
  239         ADD(IFM_IEEE80211_DS512k, 0);
  240         ADD(IFM_IEEE80211_DS512k, IFM_IEEE80211_ADHOC);
  241         ADD(IFM_IEEE80211_DS1, 0);
  242         ADD(IFM_IEEE80211_DS1, IFM_IEEE80211_ADHOC);
  243         ADD(IFM_IEEE80211_DS2, 0);
  244         ADD(IFM_IEEE80211_DS2, IFM_IEEE80211_ADHOC);
  245         ifmedia_set(&sc->arl_ifmedia, IFM_MAKEWORD(IFM_IEEE80211,
  246                 rate2media[arcfg.spreadingCode - 1], 0, 0));
  247 #undef ADD
  248 
  249         /*
  250          * Attach the interface
  251          */
  252         if (!attached) {
  253 #if __FreeBSD_version < 500100
  254                 ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
  255 #else
  256                 ether_ifattach(ifp, ar->lanCardNodeId);
  257 #endif
  258         }
  259 
  260         return (0);
  261 }
  262 
  263 /*
  264  * Hardware reset
  265  * reset all setting to default (setted ARLANDGS)
  266  */
  267 static void
  268 arl_hwreset(sc)
  269         struct arl_softc *sc;
  270 {
  271         D(("hw reset\n"));
  272 
  273         ar->controlRegister = 1;
  274         DELAY(ARDELAY1);
  275 
  276         if (arl_wait_reset(sc, 0x24, ARDELAY1))
  277                 arl_stop(sc);
  278 
  279         ar->controlRegister = (sc->arl_control = 1);
  280         DELAY(ARDELAY1);
  281 }
  282 
  283 
  284 /*
  285  * wait arlan command
  286  */
  287 static int
  288 arl_command(sc)
  289         struct arl_softc *sc;
  290 {
  291         int i;       /* long stuppid delay ??? */
  292 
  293         D(("commandByte %x\n", ar->commandByte));
  294 
  295         for (i = 100000; ar->commandByte && i; i--)
  296                 ;
  297 
  298         if (i == 0)
  299                 ar->commandByte = 0;
  300 
  301         return (i == 0);
  302 }
  303 
  304 /*
  305  * Enable for recieveng
  306  */
  307 static void
  308 arl_enable(sc)
  309         struct arl_softc *sc;
  310 {
  311         D(("enable\n"));
  312         sc->arl_control = (ARL_INTERRUPT_ENABLE | ARL_CLEAR_INTERRUPT);
  313         ar->controlRegister = sc->arl_control;
  314         arl_command(sc);
  315 
  316         ar->rxStatusVector = 0;
  317         ar->commandByte = 0x83;
  318         ar->commandParameter[0] = 1;
  319         ARL_CHANNEL(sc);
  320         arl_command(sc);
  321 }
  322 
  323 /*
  324  * reset and set user parameters
  325  */
  326 static void
  327 arl_reset(sc)
  328         struct arl_softc *sc;
  329 {
  330         D(("reset\n"));
  331         arl_hwreset(sc);
  332 
  333         ar->resetFlag1 = 1;
  334         bzero((ar), 0x1FF0);              /* fill memory board with 0 */
  335         ar->resetFlag1 = 0;
  336 
  337         sc->arl_control = 0;
  338 
  339 /*      if (arl_wait_reset(sc, 0x168, ARDELAY1))
  340                 return;
  341  */
  342 #if 1
  343         {
  344                 int cnt = 0x168;
  345                 int delay = ARDELAY1;
  346 
  347                 ar->resetFlag = 0xFF;           /* wish reset */
  348                 ar->controlRegister = 0;        /* unreeze - do it */
  349 
  350                 while (ar->resetFlag && cnt--)
  351                         DELAY(delay);
  352 
  353                 if (cnt == 0) {
  354                         printf("arl%d: reset timeout\n", sc->arl_unit);
  355                         return;
  356                 }
  357 
  358                 D(("reset wait %d\n", 0x168 - cnt));
  359         }
  360 #endif
  361 
  362         if (ar->diagnosticInfo != 0xff) {
  363                 printf("arl%d: reset error\n", sc->arl_unit);
  364                 return;
  365         }
  366         arl_config(sc);
  367 }
  368 
  369 /*
  370  * configure radio parameters
  371  */
  372 static void
  373 arl_config(sc)
  374         struct arl_softc *sc;
  375 {
  376         int i;
  377 
  378         D(("config\n"));
  379 
  380         SET_ARL_PARAM(spreadingCode);
  381         SET_ARL_PARAM(channelNumber);
  382         SET_ARL_PARAM(channelSet);
  383         SET_ARL_PARAM(registrationMode);
  384         SET_ARL_PARAM(priority);
  385         SET_ARL_PARAM(receiveMode);
  386 
  387         bcopy(arcfg.sid, ar->systemId, 4 * sizeof(ar->systemId[0]));
  388         bcopy(arcfg.specifiedRouter, ar->specifiedRouter, ETHER_ADDR_LEN);
  389         bcopy(arcfg.lanCardNodeId, ar->lanCardNodeId, ETHER_ADDR_LEN);
  390 
  391         bzero(ar->name, ARLAN_NAME_SIZE); /* clear name */
  392         strncpy(ar->name, arcfg.name, ARLAN_NAME_SIZE);
  393 
  394         ar->diagnosticInfo = 0;
  395         ar->commandByte = 1;
  396         ARL_CHANNEL(sc);
  397         DELAY(ARDELAY1);
  398 
  399         if (arl_command(sc)) {
  400                 D(("config failed\n"));
  401                 return;
  402         }
  403 
  404         for (i = 0x168; ar->diagnosticInfo == 0 && i; i--)
  405                 DELAY(ARDELAY1);
  406 
  407         if (i == 0) {
  408                 D(("config timeout\n"));
  409                 return;
  410         }
  411 
  412         if (ar->diagnosticInfo != 0xff) {
  413                 D(("config error\n"));
  414                 return;
  415         }
  416 
  417         D(("config lanCardNodeId %6D\n", ar->lanCardNodeId, ":"));
  418         D(("config channel set %d, frequency %d, spread %d, mode %d\n",
  419             ar->channelSet,
  420             ar->channelNumber,
  421             ar->spreadingCode,
  422             ar->registrationMode));
  423         /* clear quality stat */
  424         bzero(sc->arl_sigcache, MAXARLCACHE * sizeof(struct arl_sigcache));
  425 }
  426 
  427 /*
  428  * Socket Ioctl's.
  429  */
  430 static int
  431 arl_ioctl(ifp, cmd, data)
  432         register struct ifnet *ifp;
  433         u_long cmd;
  434         caddr_t data;
  435 {
  436         struct arl_softc *sc = ifp->if_softc;
  437         struct ifreq *ifr = (struct ifreq *)data;
  438         struct ieee80211req *ireq = (struct ieee80211req *)data;
  439         d_thread_t *td = _ARL_CURPROC;
  440         struct arl_req arlan_io;
  441         int count, s, error = 0;
  442         u_int8_t tmpstr[IEEE80211_NWID_LEN*2];
  443         u_int8_t *tmpptr;
  444         u_int32_t newsid;
  445         caddr_t user;
  446 
  447         D(("ioctl %lx\n", cmd));
  448         s = splimp();
  449 
  450         switch (cmd) {
  451         case SIOCSIFADDR:
  452         case SIOCGIFADDR:
  453         case SIOCSIFMTU:
  454                 error = ether_ioctl(ifp, cmd, data);
  455                 break;
  456 
  457         case SIOCSIFFLAGS:
  458                 if (ifp->if_flags & IFF_UP) {
  459                         if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
  460                                 arl_init(sc);
  461                 } else {
  462                         if (ifp->if_drv_flags & IFF_DRV_RUNNING)
  463                                 arl_stop(sc);
  464                 }
  465                 break;
  466         case SIOCSIFMEDIA:
  467         case SIOCGIFMEDIA:
  468                 error = ifmedia_ioctl(ifp, ifr, &sc->arl_ifmedia, cmd);
  469                 break;
  470 
  471         case SIOCG80211:
  472                 switch (ireq->i_type) {
  473                 case IEEE80211_IOC_SSID:
  474                         if (ireq->i_val != -1) {
  475                                 error = EINVAL;
  476                                 break;
  477                         }
  478                         bzero(tmpstr, IEEE80211_NWID_LEN);
  479                         snprintf(tmpstr, IEEE80211_NWID_LEN - 1, "0x%08x",
  480                                         *(int *)arcfg.sid);
  481                         ireq->i_len = IEEE80211_NWID_LEN;
  482                         error = copyout(tmpstr, ireq->i_data,
  483                                 IEEE80211_NWID_LEN);
  484                         break;
  485                 case IEEE80211_IOC_STATIONNAME:
  486                         ireq->i_len = sizeof(arcfg.name);
  487                         tmpptr = arcfg.name;
  488                         bzero(tmpstr, IEEE80211_NWID_LEN);
  489                         bcopy(tmpptr, tmpstr, ireq->i_len);
  490                         error = copyout(tmpstr, ireq->i_data,
  491                                 IEEE80211_NWID_LEN);
  492                         break;
  493                 case IEEE80211_IOC_CHANNEL:
  494                         ireq->i_val = arcfg.channelNumber;
  495                         break;
  496                 case IEEE80211_IOC_POWERSAVE:
  497                         ireq->i_val = (arcfg.registrationMode == 2 ?
  498                                 IEEE80211_POWERSAVE_PSP :
  499                                 IEEE80211_POWERSAVE_OFF);
  500                         break;
  501                 default:
  502                         error = EINVAL;
  503                         break;
  504                 }
  505                 break;
  506 
  507         case SIOCS80211:
  508                 if ((error = suser(td)))
  509                         break;
  510                 switch (ireq->i_type) {
  511                 case IEEE80211_IOC_SSID:
  512                         if (ireq->i_len > 4) {
  513                                 error = EINVAL;
  514                                 break;
  515                         }
  516                         bzero(&newsid, sizeof(newsid));
  517                         error = copyin(ireq->i_data,
  518                                 (u_char *)(&newsid) + 4 - ireq->i_len,
  519                                 ireq->i_len);
  520 
  521                         if (error)
  522                                 break;
  523 
  524                         newsid = htonl(newsid);
  525                         if (newsid < 0  || newsid % 2) {
  526                                 error = EINVAL;
  527                                 break;
  528                         }
  529 
  530                         bcopy(&newsid, arcfg.sid, sizeof(arcfg.sid));
  531                         break;
  532                 case IEEE80211_IOC_STATIONNAME:
  533                         if (ireq->i_len > ARLAN_NAME_SIZE) {
  534                                 error = EINVAL;
  535                                 break;
  536                         }
  537                         bzero(arcfg.name, ARLAN_NAME_SIZE);
  538                         error = copyin(ireq->i_data, arcfg.name, ireq->i_len);
  539                         break;
  540                 case IEEE80211_IOC_CHANNEL:
  541                         if (ireq->i_val < 0 || ireq->i_val > 5) {
  542                                 error = EINVAL;
  543                                 break;
  544                         }
  545                         arcfg.channelNumber = ireq->i_val;
  546                         break;
  547                 case IEEE80211_IOC_POWERSAVE:
  548                         switch (ireq->i_val) {
  549                         case IEEE80211_POWERSAVE_OFF:
  550                                 if (arcfg.registrationMode == 2)
  551                                         arcfg.registrationMode = 1;
  552                                 break;
  553                         case IEEE80211_POWERSAVE_ON:
  554                         case IEEE80211_POWERSAVE_PSP:
  555                                 arcfg.registrationMode = 2;
  556                                 break;
  557                         default:
  558                                 error = EINVAL;
  559                                 break;
  560                         }
  561                         break;
  562                 default:
  563                         error = EINVAL;
  564                         break;
  565                 }
  566 
  567                 if (!error)
  568                         arl_config(sc);
  569 
  570                 break;
  571 
  572 #define GET_PARAM(name) (arlan_io.cfg.name = arcfg.name)
  573 
  574 #define GET_COPY_PARAM(name)                                            \
  575         {                                                               \
  576                 bzero(arlan_io.cfg.name, sizeof(arlan_io.cfg.name));    \
  577                 bcopy(arcfg.name, arlan_io.cfg.name, sizeof(arlan_io.cfg.name)); \
  578         }
  579         case SIOCGARLALL:
  580                 bzero(&arlan_io, sizeof(arlan_io));
  581                 if (!suser(td)) {
  582                         bcopy(ar->systemId, arlan_io.cfg.sid, 4);
  583                 }
  584 
  585                 GET_COPY_PARAM(name);
  586                 GET_COPY_PARAM(lanCardNodeId);
  587                 GET_COPY_PARAM(specifiedRouter);
  588                 GET_PARAM(channelNumber);
  589                 GET_PARAM(channelSet);
  590                 GET_PARAM(spreadingCode);
  591                 GET_PARAM(registrationMode);
  592                 GET_PARAM(hardwareType);
  593                 GET_PARAM(majorHardwareVersion);
  594                 GET_PARAM(minorHardwareVersion);
  595                 GET_PARAM(radioModule);
  596                 GET_PARAM(priority);
  597                 GET_PARAM(receiveMode);
  598                 GET_PARAM(txRetry);
  599 
  600                 user = (void *)ifr->ifr_data;
  601                 for (count = 0; count < sizeof(arlan_io); count++)
  602                         if (subyte(user + count, ((char *)&arlan_io)[count]))
  603                                 return (EFAULT);
  604                 break;
  605 
  606 #define SET_PARAM(name)                                                 \
  607         do {                                                            \
  608                 if (arlan_io.what_set & ARLAN_SET_##name)               \
  609                         arcfg.name = arlan_io.cfg.name;                 \
  610         } while (0)
  611 #define SET_COPY_PARAM(name)                                            \
  612         do {                                                            \
  613                 if (arlan_io.what_set & ARLAN_SET_##name) {             \
  614                         bzero(arcfg.name, sizeof(arcfg.name));          \
  615                         bcopy(arlan_io.cfg.name, arcfg.name, sizeof(arcfg.name)); \
  616                 }                                                       \
  617         } while (0)
  618 
  619         case SIOCSARLALL:
  620                 if (suser(td))
  621                         break;
  622 
  623                 user = (void *)ifr->ifr_data;
  624                 for (count = 0; count < sizeof(arlan_io); count++) {
  625                         if (fubyte(user + count) < 0)
  626                                 return (EFAULT);
  627                 }
  628 
  629                 bcopy(user, (char *)&arlan_io, sizeof(arlan_io));
  630 
  631                 D(("need set 0x%04x\n", arlan_io.what_set));
  632 
  633                 if (arlan_io.what_set) {
  634                         SET_COPY_PARAM(name);
  635                         SET_COPY_PARAM(sid);
  636                         SET_COPY_PARAM(specifiedRouter);
  637                         SET_COPY_PARAM(lanCardNodeId);
  638                         SET_PARAM(channelSet);
  639                         SET_PARAM(channelNumber);
  640                         SET_PARAM(spreadingCode);
  641                         SET_PARAM(registrationMode);
  642                         SET_PARAM(priority);
  643                         SET_PARAM(receiveMode);
  644                         SET_PARAM(txRetry);
  645 
  646                         arl_config(sc);
  647                 }
  648 #undef SET_COPY_PARAM
  649 #undef SET_PARAM
  650 #undef GET_COPY_PARAM
  651 #undef GET_PARAM
  652                 break;
  653 #ifdef ARLCACHE
  654         case SIOCGARLQLT:
  655                 user = (void *)ifr->ifr_data;
  656                 for (count = 0; count < sizeof(sc->arl_sigcache); count++) {
  657                         if (fubyte(user + count) < 0)
  658                                 return (EFAULT);
  659                 }
  660                 while (ar->interruptInProgress) ; /* wait */
  661                 bcopy(&(sc->arl_sigcache), (void *)ifr->ifr_data, sizeof(sc->arl_sigcache));
  662                 break;
  663 #endif
  664         case SIOCGARLSTB:
  665                 user = (void *)ifr->ifr_data;
  666                 for (count = 0; count < sizeof(struct arl_stats); count++) {
  667                         if (fubyte(user + count) < 0)
  668                                 return (EFAULT);
  669                 }
  670 
  671                 while (ar->lancpuLock) ;
  672                 ar->hostcpuLock = 1;
  673                 bcopy(&(ar->stat), (void *)ifr->ifr_data, sizeof(struct arl_stats));
  674                 ar->hostcpuLock  = 0;
  675                 break;
  676 
  677         default:
  678                 error = EINVAL;
  679         }
  680 
  681         splx(s);
  682 
  683         return (error);
  684 }
  685 
  686 /*
  687  * Wait registration
  688  */
  689 static void
  690 arl_waitreg(ifp)
  691         struct ifnet            *ifp;
  692 {
  693         struct arl_softc        *sc = ifp->if_softc;
  694 
  695         D(("wait reg\n"));
  696 
  697         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
  698                 if (ARL_CHECKREG(sc)) {
  699                         /* wait registration */
  700                         D(("wait registration\n"));
  701                         ifp->if_watchdog = arl_waitreg;
  702                         ifp->if_timer = 2;
  703                 } else {
  704                         /* registration restored */
  705                         D(("registration restored\n"));
  706                         ifp->if_timer = 0;
  707                         arl_init(sc);
  708                 }
  709         }
  710 }
  711 
  712 /*
  713  * Handle transmit timeouts.
  714  */
  715 static void
  716 arl_watchdog(ifp)
  717         struct ifnet            *ifp;
  718 {
  719         struct arl_softc        *sc = ifp->if_softc;
  720 
  721         if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
  722                 return;
  723 
  724         D(("device timeout\n"));
  725 
  726         if (ARL_CHECKREG(sc)) {
  727                 /* Lost registratoin */
  728                 D(("timeout lost registration\n"));
  729                 ifp->if_watchdog = arl_waitreg;
  730                 ifp->if_timer = 2;
  731         }
  732 }
  733 
  734 /*
  735  * Initialize
  736  */
  737 static void
  738 arl_init(xsc)
  739         void *xsc;
  740 {
  741         struct arl_softc *sc = xsc;
  742         struct ifnet *ifp = sc->arl_ifp;
  743         int s;
  744 
  745         D(("init\n"));
  746 
  747         s = splimp();
  748 
  749         if (ARL_CHECKREG(sc))
  750                 arl_reset(sc);
  751 
  752         arl_enable(sc);
  753 
  754         /* set flags */
  755 
  756         ifp->if_drv_flags |= IFF_DRV_RUNNING;
  757         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
  758 
  759         arl_start(ifp);
  760 
  761         splx(s);
  762         D(("init done\n"));
  763 }
  764 
  765 /*
  766  * Put buffer into arlan buffer and start transmit
  767  */
  768 static void
  769 arl_put(sc)
  770         struct arl_softc *sc;
  771 {
  772         struct arl_tx_param txp;
  773         int i;
  774 
  775         if (ARL_CHECKREG(sc))
  776                 sc->arl_ifp->if_oerrors++;
  777 
  778         /* copy dst adr */
  779         for(i = 0; i < 6; i++)
  780                 txp.dest[i] = sc->arl_tx[i];
  781         txp.clear       = 0;
  782         txp.retries     = arcfg.txRetry;      /* use default value */
  783         txp.routing     = 1;
  784         txp.scrambled   = 0;
  785         txp.offset      = (intptr_t)ar->txBuffer - (intptr_t)(ar);
  786         txp.length      = sc->tx_len - ARLAN_HEADER_SIZE;
  787 
  788 #ifdef SEND_ARLAN_HEADER
  789         if (ar->registrationMode != 1)
  790                 txp.length = sc->tx_len;
  791 #endif
  792 
  793         /* copy from internal buffer to adapter memory */
  794 #ifdef SEND_ARLAN_HEADER
  795         if (ar->registrationMode)
  796 #endif
  797                 bcopy(sc->arl_tx + ARLAN_HEADER_SIZE,
  798                       ar->txBuffer,
  799                       sc->tx_len - ARLAN_HEADER_SIZE);
  800 #ifdef SEND_ARLAN_MODE
  801         else
  802                 bcopy(sc->arl_tx, ar->txBuffer, sc->tx_len);
  803 #endif
  804 
  805         /* copy command parametr */
  806         bcopy(&txp, ar->commandParameter, 14);
  807         ar->commandByte = 0x85;       /* send command */
  808         ARL_CHANNEL(sc);
  809         if (arl_command(sc))
  810                 sc->arl_ifp->if_oerrors++;
  811 }
  812 
  813 /*
  814  * start output
  815  */
  816 static void
  817 arl_start(ifp)
  818         struct ifnet            *ifp;
  819 {
  820         struct arl_softc        *sc;
  821         struct mbuf             *m;
  822         struct mbuf             *m0 = NULL;
  823 
  824         sc = ifp->if_softc;
  825 
  826         D(("start\n"));
  827 
  828         /* Don't do anything if output is active */
  829         if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
  830                 return;
  831 
  832         /* Dequeue the next datagram */
  833         IF_DEQUEUE(&ifp->if_snd, m0);
  834 
  835         /* If there's nothing to send, return. */
  836         if (m0 != NULL) {
  837                 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
  838 
  839                 /* Copy the datagram to the buffer. */
  840                 sc->tx_len = 0;
  841                 for(m = m0; m != NULL; m = m->m_next) {
  842                         if (m->m_len == 0)
  843                                 continue;
  844                         bcopy(mtod(m, caddr_t),
  845                               sc->arl_tx + sc->tx_len, m->m_len);
  846                         sc->tx_len += m->m_len;
  847                 }
  848 
  849                 /* if packet size is less than minimum ethernet frame size,
  850                  * pad it with zeroes to that size */
  851                 if (sc->tx_len < ETHER_MIN_LEN) {
  852                         bzero(sc->arl_tx + sc->tx_len, ETHER_MIN_LEN - sc->tx_len);
  853                         sc->tx_len = ETHER_MIN_LEN;
  854                 }
  855 
  856                 /* Give the packet to the bpf, if any */
  857                 BPF_MTAP(ifp, m0);
  858 
  859                 m_freem(m0);
  860 
  861                 /* Now transmit the datagram */
  862                 ifp->if_timer = 1;        /* wait 1 sec */
  863 
  864                 ifp->if_watchdog = arl_watchdog;
  865                 arl_put(sc);
  866         }
  867 }
  868 
  869 /*
  870  * stop interface
  871  */
  872 void
  873 arl_stop(sc)
  874         struct arl_softc *sc;
  875 {
  876         struct ifnet    *ifp;
  877         int             s;
  878 
  879         s = splimp();
  880 
  881         ifp = sc->arl_ifp;
  882 
  883         ifp->if_timer = 0;        /* disable timer */
  884         ifp->if_drv_flags &= ~(IFF_DRV_RUNNING|IFF_DRV_OACTIVE);
  885         /*  arl_hwreset(unit);  */
  886         sc->rx_len = 0;
  887         sc->tx_len = 0;
  888         /* disable interrupt */
  889         ar->controlRegister = 0;
  890 
  891         splx(s);
  892 }
  893 
  894 /*
  895  * Pull read data off a interface.
  896  * Len is length of data, with local net header stripped.
  897  */
  898 static struct mbuf*
  899 arl_get(buf, totlen, off0, ifp)
  900         caddr_t         buf;
  901         int             totlen;
  902         int             off0;
  903         struct ifnet *  ifp;
  904 {
  905         struct mbuf *top, **mp, *m;
  906         int off = off0, len;
  907         caddr_t cp = buf;
  908         char *epkt;
  909 
  910         cp = buf;
  911         epkt = cp + totlen;
  912 
  913         if (off) {
  914                 cp += off + 2 * sizeof(u_short);
  915                 totlen -= 2 * sizeof(u_short);
  916         }
  917 
  918         MGETHDR(m, M_DONTWAIT, MT_DATA);
  919         if (m == 0)
  920                 return (0);
  921         m->m_pkthdr.rcvif = ifp;
  922         m->m_pkthdr.len = totlen;
  923         m->m_len = MHLEN;
  924         top = 0;
  925         mp = &top;
  926         while (totlen > 0) {
  927                 if (top) {
  928                         MGET(m, M_DONTWAIT, MT_DATA);
  929                         if (m == 0) {
  930                                 m_freem(top);
  931                                 return (0);
  932                         }
  933                         m->m_len = MLEN;
  934                 }
  935                 len = min(totlen, epkt - cp);
  936                 if (len >= MINCLSIZE) {
  937                         MCLGET(m, M_DONTWAIT);
  938                         if (m->m_flags & M_EXT)
  939                                 m->m_len = len = min(len, MCLBYTES);
  940                         else
  941                                 len = m->m_len;
  942                 } else {
  943                         /*
  944                          *                        * Place initial small packet/header at end of mbuf.
  945                          *                                                 */
  946                         if (len < m->m_len) {
  947                                 if (top == 0 && len + max_linkhdr <= m->m_len)
  948                                         m->m_data += max_linkhdr;
  949                                 m->m_len = len;
  950                         } else
  951                                 len = m->m_len;
  952                 }
  953                 bcopy(cp, mtod(m, caddr_t), (unsigned)len);
  954                 cp += len;
  955                 *mp = m;
  956                 mp = &m->m_next;
  957                 totlen -= len;
  958                 if (cp == epkt)
  959                         cp = buf;
  960         }
  961 
  962         return (top);
  963 }
  964 
  965 /* ------------------------------------------------------------------
  966  *  * Pass a packet up to the higher levels.
  967  *   */
  968 static void
  969 arl_read(sc, buf, len)
  970         struct arl_softc        *sc;
  971         caddr_t                 buf;
  972         int                     len;
  973 {
  974         register struct ether_header *eh;
  975         struct ifnet *ifp = sc->arl_ifp;
  976         struct mbuf *m;
  977 
  978         eh = (struct ether_header *)buf;
  979         /*
  980          * Check if there's a bpf filter listening on this interface.
  981          * If so, hand off the raw packet to bpf.
  982          */
  983         if (bpf_peers_present(ifp->if_bpf)) {
  984                 /*
  985                  * Note that the interface cannot be in promiscuous mode if
  986                  * there are no bpf listeners.  And if el are in promiscuous
  987                  * mode, el have to check if this packet is really ours.
  988                  *
  989                  * This test does not support multicasts.
  990                  */
  991                 if ((ifp->if_flags & IFF_PROMISC)
  992                    && bcmp(eh->ether_dhost, IFP2ENADDR(sc->arl_ifp),
  993                            sizeof(eh->ether_dhost)) != 0
  994                    && bcmp(eh->ether_dhost, BROADCASTADDR,
  995                            sizeof(eh->ether_dhost)) != 0)
  996                         return;
  997         }
  998         /*
  999          * Pull packet off interface.
 1000          */
 1001 #if __FreeBSD_version < 500100
 1002         buf += sizeof(struct ether_header);
 1003         len -= sizeof(struct ether_header);
 1004 #endif
 1005         m = arl_get(buf, len, 0, ifp);
 1006         if (m == 0)
 1007                 return;
 1008 
 1009 #ifdef ARLCACHE
 1010         arl_cache_store(sc, eh, ar->rxQuality & 0x0f,
 1011                         (ar->rxQuality & 0xf0) >> 4, ARLCACHE_RX);
 1012 #endif
 1013 
 1014 #if __FreeBSD_version < 500100
 1015         ether_input(ifp, eh, m);
 1016 #else
 1017         (*ifp->if_input)(ifp, m);
 1018 #endif
 1019 }
 1020 
 1021 /*
 1022  * get packet from adapter
 1023  */
 1024 static void
 1025 arl_recv(sc)
 1026         struct arl_softc *sc;
 1027 {
 1028         sc->rx_len = ar->rxLength;
 1029 
 1030         if (sc->rx_len) {
 1031 #ifdef SEND_ARLAN_HEADER
 1032                 if (ar->registrationMode == 1) {
 1033 #endif
 1034                         bcopy(ar->ultimateDestAddress, sc->arl_rx, 6);
 1035                         bcopy(ar->rxSrc, (char*)sc->arl_rx + 6, 6);
 1036                         bcopy((char *)(ar) + ar->rxOffset,
 1037                               (char *)sc->arl_rx + 12,
 1038                               sc->rx_len);
 1039                         sc->rx_len += ARLAN_HEADER_SIZE;
 1040 #ifdef SEND_ARLAN_HEADER
 1041                 } else {
 1042                         bcopy((char *)(ar) + ar->rxOffset,
 1043                               (char *)sc->arl_rx, sc->rx_len);
 1044                 }
 1045 #endif
 1046         }
 1047 }
 1048 
 1049 /*
 1050  * Ethernet interface interrupt processor
 1051  */
 1052 void
 1053 arl_intr(arg)
 1054         void *arg;
 1055 {
 1056         register struct arl_softc *sc = (struct arl_softc *) arg;
 1057         struct ifnet *ifp = sc->arl_ifp;
 1058 
 1059         /* enable interrupt */
 1060         ar->controlRegister = (sc->arl_control & ~ARL_CLEAR_INTERRUPT);
 1061         ar->controlRegister = (sc->arl_control | ARL_CLEAR_INTERRUPT);
 1062 
 1063         if (ar->txStatusVector) {
 1064                 if (ar->txStatusVector != 1)
 1065                         sc->arl_ifp->if_collisions++;
 1066                 ifp->if_timer = 0;     /* disable timer */
 1067                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 1068                 arl_start(ifp);
 1069                 ar->txStatusVector = 0;
 1070 #ifdef ARLCACHE
 1071                 arl_cache_store(sc,
 1072                         (struct ether_header *)(sc->arl_tx),
 1073                         ar->txAckQuality & 0x0f,
 1074                         (ar->txAckQuality & 0xf0) >> 4, ARLCACHE_TX);
 1075 #endif
 1076         }
 1077 
 1078         if (ar->rxStatusVector) {
 1079                 if (ar->rxStatusVector == 1) {   /* it is data frame */
 1080                         arl_recv(sc);
 1081                         arl_read(sc, sc->arl_rx, sc->rx_len);
 1082                         ifp->if_opackets++;
 1083                 }
 1084                 ar->rxStatusVector = 0;
 1085 
 1086                 ar->commandByte = 0x83;
 1087                 ar->commandParameter[0] = 1;
 1088                 ARL_CHANNEL(sc);
 1089                 if (arl_command(sc))
 1090                         ifp->if_ierrors++;
 1091         }
 1092 
 1093         return;
 1094 }
 1095 
 1096 /*
 1097  * waiting for resetFlag dropped
 1098  */
 1099 int
 1100 arl_wait_reset(sc, cnt, delay)
 1101         struct arl_softc *sc;
 1102         int cnt;
 1103         int delay;
 1104 {
 1105         D(("wait_reset cnt=%d delay=%d\n", cnt, delay));
 1106 
 1107         ar->resetFlag = 1;              /* wish reset */
 1108         ar->controlRegister = 0;        /* unreeze - do it */
 1109 
 1110         while (ar->resetFlag && cnt--)
 1111                 DELAY(delay);
 1112 
 1113         D(("reset done. %d cycles left\n", cnt));
 1114 
 1115         if (cnt == 0)
 1116                 printf("arl%d: reset failed\n", sc->arl_unit);
 1117 
 1118         return (cnt == 0);
 1119 }
 1120 
 1121 /*
 1122  * Allocate an irq resource with the given resource id
 1123  */
 1124 int
 1125 arl_alloc_irq(dev, rid, flags)
 1126         device_t dev;
 1127         int rid;
 1128         int flags;
 1129 {
 1130         struct arl_softc *sc = device_get_softc(dev);
 1131         struct resource *res;
 1132 
 1133         res = bus_alloc_resource_any(
 1134             dev, SYS_RES_IRQ, &rid, (RF_ACTIVE | flags));
 1135         if (res) {
 1136                 sc->irq_rid = rid;
 1137                 sc->irq_res = res;
 1138                 return (0);
 1139         } else
 1140                 return (ENOENT);
 1141 }
 1142 
 1143 /*
 1144  * Allocate an memory resource with the given resource id
 1145  */
 1146 int
 1147 arl_alloc_memory(dev, rid, size)
 1148         device_t dev;
 1149         int rid;
 1150         int size;
 1151 {
 1152         struct arl_softc *sc = device_get_softc(dev);
 1153         struct resource *res;
 1154 
 1155         res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
 1156                                  0ul, ~0ul, size, RF_ACTIVE);
 1157         if (res) {
 1158                 sc->mem_rid = rid;
 1159                 sc->mem_res = res;
 1160                 return (0);
 1161         } else
 1162                 return (ENOENT);
 1163 }
 1164 
 1165 /*
 1166  * Release all resources
 1167  */
 1168 void
 1169 arl_release_resources(dev)
 1170         device_t dev;
 1171 {
 1172         struct arl_softc *sc = device_get_softc(dev);
 1173 
 1174         if (sc->mem_res) {
 1175                 bus_release_resource(dev, SYS_RES_MEMORY,
 1176                                      sc->mem_rid, sc->mem_res);
 1177                 sc->mem_res = 0;
 1178         }
 1179         if (sc->irq_res) {
 1180                 bus_release_resource(dev, SYS_RES_IRQ,
 1181                                      sc->irq_rid, sc->irq_res);
 1182                 sc->irq_res = 0;
 1183         }
 1184 }
 1185 
 1186 #ifdef ARLCACHE
 1187 static void
 1188 arl_cache_store(sc, eh, level, quality, dir)
 1189         struct arl_softc *sc;
 1190         struct ether_header *eh;
 1191         u_int8_t level;
 1192         u_int8_t quality;
 1193         int     dir;
 1194 {
 1195         int i;
 1196         static int cache_slot = 0;
 1197         static int wrapindex = 0;
 1198         u_int8_t zero[6] = {0, 0, 0, 0, 0, 0};
 1199         u_char *mac;
 1200 
 1201         if ((ntohs(eh->ether_type) != ETHERTYPE_IP)) {
 1202                 return;
 1203         }
 1204 
 1205         mac = (dir == ARLCACHE_RX ? eh->ether_shost : eh->ether_dhost);
 1206 
 1207         for (i = 0; i < MAXARLCACHE; i++) {
 1208                 if (!bcmp(zero, sc->arl_sigcache[i].macsrc, 6) ||
 1209                     !bcmp(mac, sc->arl_sigcache[i].macsrc, 6))
 1210                         break;
 1211         }
 1212 
 1213         if (i < MAXARLCACHE)
 1214                 cache_slot = i;
 1215         else {
 1216                 if (wrapindex == MAXARLCACHE)
 1217                         wrapindex = 0;
 1218                 cache_slot = wrapindex++;
 1219         }
 1220 
 1221         bcopy(dir == ARLCACHE_RX ? eh->ether_shost : eh->ether_dhost,
 1222             sc->arl_sigcache[cache_slot].macsrc, 6);
 1223 
 1224         sc->arl_sigcache[cache_slot].level[dir] = level;
 1225         sc->arl_sigcache[cache_slot].quality[dir] = quality;
 1226 }
 1227 #endif
 1228 
 1229 static int
 1230 arl_media_change(ifp)
 1231         struct ifnet    *ifp;
 1232 {
 1233         struct arl_softc *sc = ifp->if_softc;
 1234         int otype = arcfg.registrationMode;
 1235         int orate = arcfg.spreadingCode;
 1236         int nrate, i;
 1237 
 1238         nrate = IFM_SUBTYPE(sc->arl_ifmedia.ifm_cur->ifm_media);
 1239 
 1240         for(i = 1; i <= 4; i++) {
 1241                 if (rate2media[i - 1] == nrate)
 1242                         break;
 1243         }
 1244 
 1245         if (i == 5)
 1246                 return (EINVAL);
 1247 
 1248         arcfg.spreadingCode = i;
 1249 
 1250         /* XXX Need fix for PSP mode */
 1251         if ((sc->arl_ifmedia.ifm_cur->ifm_media & IFM_IEEE80211_ADHOC) != 0)
 1252                 arcfg.registrationMode = 0;
 1253         else
 1254                 arcfg.registrationMode = 1;
 1255 
 1256         if (otype != arcfg.registrationMode ||
 1257             orate != arcfg.spreadingCode)
 1258                 arl_config(sc);
 1259 
 1260         return (0);
 1261 }
 1262 
 1263 static void
 1264 arl_media_status(ifp, imr)
 1265         struct ifnet            *ifp;
 1266         struct ifmediareq       *imr;
 1267 {
 1268         struct arl_softc        *sc = ifp->if_softc;
 1269 
 1270         imr->ifm_active = IFM_IEEE80211;
 1271 
 1272         if (arcfg.registrationMode == 0)
 1273                 imr->ifm_active |= IFM_IEEE80211_ADHOC;
 1274 
 1275         imr->ifm_active |= IFM_MAKEWORD(IFM_IEEE80211,
 1276                                 rate2media[arcfg.spreadingCode - 1], 0, 0);
 1277         imr->ifm_status = IFM_AVALID;
 1278         if (!ARL_CHECKREG(sc))
 1279                 imr->ifm_status |= IFM_ACTIVE;
 1280 }

Cache object: cfd5181eab515d2fb6c3fd838f564b49


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