FreeBSD/Linux Kernel Cross Reference
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/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 = ⊤
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
|