]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/dev/arl/if_arl.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / dev / arl / if_arl.c
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/priv.h>
47 #include <sys/proc.h>
48 #include <sys/conf.h>
49
50 #include <sys/module.h>
51 #include <sys/bus.h>
52
53 #include <machine/bus.h>
54 #include <machine/resource.h>
55 #include <sys/rman.h>
56
57 #include <net/if.h>
58 #include <net/if_dl.h>
59 #include <net/if_media.h>
60 #include <net/if_types.h>
61 #include <net/ethernet.h>
62
63 #include <net80211/ieee80211_var.h>
64
65 #ifdef INET
66 #include <netinet/in.h>
67 #include <netinet/in_systm.h>
68 #include <netinet/in_var.h>
69 #include <netinet/ip.h>
70 #endif
71
72 #include <net/bpf.h>
73
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 = priv_check(td, PRIV_NET80211_MANAGE)))
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 (!priv_check(td, PRIV_DRIVER)) {
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 (priv_check(td, PRIV_DRIVER))
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, IF_LLADDR(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 }