This source file includes following definitions.
- ray_match
- ray_attach
- ray_activate
- ray_detach
- ray_enable
- ray_disable
- ray_init
- ray_stop
- ray_reset
- ray_reset_resetloop
- ray_power
- ray_shutdown
- ray_ioctl
- ray_if_start
- ray_media_change
- ray_media_status
- ray_intr_start
- ray_recv
- ray_recv_auth
- ray_send_auth
- ray_find_free_tx_ccs
- ray_fill_in_tx_ccs
- ray_update_params_done
- ray_check_scheduled
- ray_check_ccs
- ray_update_error_counters
- ray_ccs_done
- ray_rccs_intr
- ray_intr
- ray_free_ccs_chain
- ray_free_ccs
- ray_alloc_ccs
- ray_set_pending
- ray_cmd_schedule
- ray_cmd_is_scheduled
- ray_cmd_cancel
- ray_cmd_ran
- ray_cmd_is_running
- ray_cmd_done
- ray_issue_cmd
- ray_simple_cmd
- ray_update_subcmd
- ray_report_params
- ray_start_assoc
- ray_download_params
- ray_start_join_net
- ray_start_join_timo
- ray_start_join_net_done
- ray_update_promisc
- ray_update_params
- ray_update_mcast
- ray_user_update_params
- ray_user_report_params
- ray_read_region
- ray_write_region
- hexdump
- ray_dump_mbuf
- ray_update_siglev
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 #include "bpfilter.h"
65
66 #include <sys/param.h>
67 #include <sys/systm.h>
68 #include <sys/timeout.h>
69 #include <sys/mbuf.h>
70 #include <sys/socket.h>
71 #include <sys/ioctl.h>
72 #include <sys/errno.h>
73 #include <sys/device.h>
74 #include <sys/kernel.h>
75 #include <sys/proc.h>
76
77 #include <net/if.h>
78 #include <net/if_dl.h>
79 #include <net/if_media.h>
80 #include <net/if_llc.h>
81
82 #ifdef INET
83 #include <netinet/in.h>
84 #include <netinet/in_systm.h>
85 #include <netinet/in_var.h>
86 #include <netinet/ip.h>
87 #include <netinet/if_ether.h>
88 #endif
89
90 #include <net80211/ieee80211.h>
91 #include <net80211/ieee80211_ioctl.h>
92
93 #if NBPFILTER > 0
94 #include <net/bpf.h>
95 #endif
96
97 #include <machine/cpu.h>
98 #include <machine/bus.h>
99 #include <machine/intr.h>
100
101 #include <dev/pcmcia/pcmciareg.h>
102 #include <dev/pcmcia/pcmciavar.h>
103 #include <dev/pcmcia/pcmciadevs.h>
104
105 #include <dev/pcmcia/if_rayreg.h>
106
107 #ifndef PCMCIA_WIDTH_MEM8
108 #define PCMCIA_WIDTH_MEM8 0
109 #endif
110
111 #ifndef offsetof
112 #define offsetof(type, member) ((size_t)(&((type *)0)->member))
113 #endif
114
115
116
117 #ifndef RAY_PID_COUNTRY_CODE_DEFAULT
118 #define RAY_PID_COUNTRY_CODE_DEFAULT RAY_PID_COUNTRY_CODE_USA
119 #endif
120
121
122 #ifndef RAY_CHECK_CCS_TIMEOUT
123 #define RAY_CHECK_CCS_TIMEOUT (hz / 2)
124 #endif
125
126
127 #ifndef RAY_START_TIMEOUT
128 #define RAY_START_TIMEOUT (10 * hz)
129 #endif
130
131
132 #ifndef RAY_RESET_TIMEOUT
133 #define RAY_RESET_TIMEOUT (10 * hz)
134 #endif
135
136
137
138
139
140
141 #ifndef RAY_CHECK_SCHED_TIMEOUT
142 #define RAY_CHECK_SCHED_TIMEOUT (hz)
143 #endif
144
145 #ifndef RAY_MODE_DEFAULT
146 #define RAY_MODE_DEFAULT SC_MODE_ADHOC
147 #endif
148
149 #ifndef RAY_DEF_NWID
150 #define RAY_DEF_NWID "NETWORK_NAME"
151 #endif
152
153
154
155
156
157
158 #ifndef RAY_MAX_RESETS
159 #define RAY_MAX_RESETS 10
160 #endif
161
162
163
164
165
166 struct ray_softc {
167 struct device sc_dev;
168 struct arpcom sc_ec;
169 struct ifmedia sc_media;
170
171 struct pcmcia_function *sc_pf;
172 struct pcmcia_mem_handle sc_mem;
173 int sc_window;
174 void *sc_ih;
175 void *sc_sdhook;
176 void *sc_pwrhook;
177 int sc_flags;
178 #define RAY_FLAGS_RESUMEINIT 0x01
179 #define RAY_FLAGS_ATTACHED 0x02
180 int sc_resetloop;
181
182 struct timeout sc_check_ccs_ch;
183 struct timeout sc_check_scheduled_ch;
184 struct timeout sc_reset_resetloop_ch;
185 struct timeout sc_disable_ch;
186 struct timeout sc_start_join_timo_ch;
187 #define callout_stop timeout_del
188 #define callout_reset(t,n,f,a) timeout_add((t), (n))
189
190 struct ray_ecf_startup sc_ecf_startup;
191 struct ray_startup_params_head sc_startup;
192 union {
193 struct ray_startup_params_tail_5 u_params_5;
194 struct ray_startup_params_tail_4 u_params_4;
195 } sc_u;
196
197 u_int8_t sc_ccsinuse[64];
198 u_int sc_txfree;
199
200 u_int8_t sc_bssid[ETHER_ADDR_LEN];
201 u_int8_t sc_authid[ETHER_ADDR_LEN];
202 struct ieee80211_nwid sc_cnwid;
203 struct ieee80211_nwid sc_dnwid;
204 u_int8_t sc_omode;
205 u_int8_t sc_mode;
206 u_int8_t sc_countrycode;
207 u_int8_t sc_dcountrycode;
208 int sc_havenet;
209 bus_size_t sc_txpad;
210 u_int8_t sc_deftxrate;
211 u_int8_t sc_encrypt;
212 u_int8_t sc_authstate;
213
214 int sc_promisc;
215 int sc_running;
216 int sc_scheduled;
217 int sc_timoneed;
218 int sc_timocheck;
219 bus_size_t sc_startccs;
220 u_int sc_startcmd;
221
222 int sc_checkcounters;
223 u_int64_t sc_rxoverflow;
224 u_int64_t sc_rxcksum;
225 u_int64_t sc_rxhcksum;
226 u_int8_t sc_rxnoise;
227
228
229 struct ray_param_req *sc_repreq;
230 struct ray_param_req *sc_updreq;
231 #ifdef RAY_DO_SIGLEV
232 struct ray_siglev sc_siglevs[RAY_NSIGLEVRECS];
233 #endif
234 };
235 #define sc_memt sc_mem.memt
236 #define sc_memh sc_mem.memh
237 #define sc_ccrt sc_pf->pf_ccrt
238 #define sc_ccrh sc_pf->pf_ccrh
239 #define sc_ccroff sc_pf->pf_ccr_offset
240 #define sc_startup_4 sc_u.u_params_4
241 #define sc_startup_5 sc_u.u_params_5
242 #define sc_version sc_ecf_startup.e_fw_build_string
243 #define sc_tibsize sc_ecf_startup.e_tib_size
244 #define sc_if sc_ec.ac_if
245 #define ec_multicnt ac_multicnt
246 #define memmove memcpy
247 #define sc_xname sc_dev.dv_xname
248
249
250 #define SC_MODE_ADHOC 0
251 #define SC_MODE_INFRA 1
252
253
254 #define SCP_FIRST 0x0001
255 #define SCP_UPDATESUBCMD 0x0001
256 #define SCP_STARTASSOC 0x0002
257 #define SCP_REPORTPARAMS 0x0004
258 #define SCP_IFSTART 0x0008
259
260
261 #define SCP_UPD_FIRST 0x0100
262 #define SCP_UPD_STARTUP 0x0100
263 #define SCP_UPD_STARTJOIN 0x0200
264 #define SCP_UPD_PROMISC 0x0400
265 #define SCP_UPD_MCAST 0x0800
266 #define SCP_UPD_UPDATEPARAMS 0x1000
267 #define SCP_UPD_SHIFT 8
268 #define SCP_UPD_MASK 0xff00
269
270
271 #define SCP_TIMOCHECK_CMD_MASK \
272 (SCP_UPD_UPDATEPARAMS | SCP_UPD_STARTUP | SCP_UPD_MCAST | \
273 SCP_UPD_PROMISC)
274
275
276 #define IFM_ADHOC \
277 IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_FH2, IFM_IEEE80211_ADHOC, 0)
278 #define IFM_INFRA \
279 IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_FH2, 0, 0)
280
281 typedef void (*ray_cmd_func_t)(struct ray_softc *);
282
283 #define SC_BUILD_5 0x5
284 #define SC_BUILD_4 0x55
285
286
287 #define RAY_AUTH_UNAUTH (0)
288 #define RAY_AUTH_WAITING (1)
289 #define RAY_AUTH_AUTH (2)
290 #define RAY_AUTH_NEEDED (3)
291
292 #define OPEN_AUTH_REQUEST (1)
293 #define OPEN_AUTH_RESPONSE (2)
294 #define BROADCAST_DEAUTH (0xc0)
295
296
297 int ray_alloc_ccs(struct ray_softc *, bus_size_t *, u_int, u_int);
298 bus_size_t ray_fill_in_tx_ccs(struct ray_softc *, size_t, u_int, u_int);
299 void ray_attach(struct device *, struct device *, void *);
300 ray_cmd_func_t ray_ccs_done(struct ray_softc *, bus_size_t);
301 void ray_check_ccs(void *);
302 void ray_check_scheduled(void *);
303 void ray_cmd_cancel(struct ray_softc *, int);
304 void ray_cmd_schedule(struct ray_softc *, int);
305 void ray_cmd_ran(struct ray_softc *, int);
306 int ray_cmd_is_running(struct ray_softc *, int);
307 int ray_cmd_is_scheduled(struct ray_softc *, int);
308 void ray_cmd_done(struct ray_softc *, int);
309 int ray_detach(struct device *, int);
310 int ray_activate(struct device *, enum devact);
311 void ray_disable(struct ray_softc *);
312 void ray_download_params(struct ray_softc *);
313 int ray_enable(struct ray_softc *);
314 u_int ray_find_free_tx_ccs(struct ray_softc *, u_int);
315 u_int8_t ray_free_ccs(struct ray_softc *, bus_size_t);
316 void ray_free_ccs_chain(struct ray_softc *, u_int);
317 void ray_if_start(struct ifnet *);
318 int ray_init(struct ray_softc *);
319 int ray_intr(void *);
320 void ray_intr_start(struct ray_softc *);
321 int ray_ioctl(struct ifnet *, u_long, caddr_t);
322 int ray_issue_cmd(struct ray_softc *, bus_size_t, u_int);
323 int ray_match(struct device *, struct cfdata *, void *);
324 int ray_media_change(struct ifnet *);
325 void ray_media_status(struct ifnet *, struct ifmediareq *);
326 void ray_power(int, void *);
327 ray_cmd_func_t ray_rccs_intr(struct ray_softc *, bus_size_t);
328 void ray_recv(struct ray_softc *, bus_size_t);
329 void ray_recv_auth(struct ray_softc *,struct ieee80211_frame*);
330 void ray_report_params(struct ray_softc *);
331 void ray_reset(struct ray_softc *);
332 void ray_reset_resetloop(void *);
333 int ray_send_auth(struct ray_softc *, u_int8_t *, u_int8_t);
334 void ray_set_pending(struct ray_softc *, u_int);
335 void ray_shutdown(void *);
336 int ray_simple_cmd(struct ray_softc *, u_int, u_int);
337 void ray_start_assoc(struct ray_softc *);
338 void ray_start_join_net(struct ray_softc *);
339 ray_cmd_func_t ray_start_join_net_done(struct ray_softc *,
340 u_int, bus_size_t, u_int);
341 void ray_start_join_timo(void *);
342 void ray_stop(struct ray_softc *);
343 void ray_update_error_counters(struct ray_softc *);
344 void ray_update_mcast(struct ray_softc *);
345 ray_cmd_func_t ray_update_params_done(struct ray_softc *,
346 bus_size_t, u_int);
347 void ray_update_params(struct ray_softc *);
348 void ray_update_promisc(struct ray_softc *);
349 void ray_update_subcmd(struct ray_softc *);
350 int ray_user_report_params(struct ray_softc *,
351 struct ray_param_req *);
352 int ray_user_update_params(struct ray_softc *,
353 struct ray_param_req *);
354
355 #define ray_read_region(sc,off,p,c) \
356 bus_space_read_region_1((sc)->sc_memt, (sc)->sc_memh, (off), (p), (c))
357 #define ray_write_region(sc,off,p,c) \
358 bus_space_write_region_1((sc)->sc_memt, (sc)->sc_memh, (off), (p), (c))
359
360 #ifdef RAY_DO_SIGLEV
361 void ray_update_siglev(struct ray_softc *, u_int8_t *, u_int8_t);
362 #endif
363
364 #ifdef RAY_DEBUG
365 int ray_debug = 0;
366 int ray_debug_xmit_sum = 0;
367 int ray_debug_dump_desc = 0;
368 int ray_debug_dump_rx = 0;
369 int ray_debug_dump_tx = 0;
370 struct timeval rtv, tv1, tv2, *ttp, *ltp;
371 #define RAY_DPRINTF(x) do { if (ray_debug) { \
372 struct timeval *tmp; \
373 microtime(ttp); \
374 timersub(ttp, ltp, &rtv); \
375 tmp = ttp; ttp = ltp; ltp = tmp; \
376 printf("%ld:%ld %ld:%06ld: ", ttp->tv_sec, ttp->tv_usec, rtv.tv_sec, rtv.tv_usec); \
377 printf x ; \
378 } } while (0)
379 #define RAY_DPRINTF_XMIT(x) do { if (ray_debug_xmit_sum) { \
380 struct timeval *tmp; \
381 microtime(ttp); \
382 timersub(ttp, ltp, &rtv); \
383 tmp = ttp; ttp = ltp; ltp = tmp; \
384 printf("%ld:%ld %ld:%06ld: ", ttp->tv_sec, ttp->tv_usec, rtv.tv_sec, rtv.tv_usec); \
385 printf x ; \
386 } } while (0)
387
388 #define HEXDF_NOCOMPRESS 0x1
389 #define HEXDF_NOOFFSET 0x2
390 #define HEXDF_NOASCII 0x4
391 void hexdump(const u_int8_t *, int, int, int, int);
392 void ray_dump_mbuf(struct ray_softc *, struct mbuf *);
393
394 #else
395
396 #define RAY_DPRINTF(x)
397 #define RAY_DPRINTF_XMIT(x)
398
399 #endif
400
401
402
403
404
405
406 #define REG_WRITE(sc, off, val) \
407 bus_space_write_1((sc)->sc_ccrt, (sc)->sc_ccrh, \
408 ((sc)->sc_ccroff + (off)), (val))
409
410 #define REG_READ(sc, off) \
411 bus_space_read_1((sc)->sc_ccrt, (sc)->sc_ccrh, \
412 ((sc)->sc_ccroff + (off)))
413
414 #define SRAM_READ_1(sc, off) \
415 ((u_int8_t)bus_space_read_1((sc)->sc_memt, (sc)->sc_memh, (off)))
416
417 #define SRAM_READ_FIELD_1(sc, off, s, f) \
418 SRAM_READ_1(sc, (off) + offsetof(struct s, f))
419
420 #define SRAM_READ_FIELD_2(sc, off, s, f) \
421 ((((u_int16_t)SRAM_READ_1(sc, (off) + offsetof(struct s, f)) << 8) \
422 |(SRAM_READ_1(sc, (off) + 1 + offsetof(struct s, f)))))
423
424 #define SRAM_READ_FIELD_N(sc, off, s, f, p, n) \
425 ray_read_region(sc, (off) + offsetof(struct s, f), (p), (n))
426
427 #define SRAM_WRITE_1(sc, off, val) \
428 bus_space_write_1((sc)->sc_memt, (sc)->sc_memh, (off), (val))
429
430 #define SRAM_WRITE_FIELD_1(sc, off, s, f, v) \
431 SRAM_WRITE_1(sc, (off) + offsetof(struct s, f), (v))
432
433 #define SRAM_WRITE_FIELD_2(sc, off, s, f, v) do { \
434 SRAM_WRITE_1(sc, (off) + offsetof(struct s, f), (((v) >> 8 ) & 0xff)); \
435 SRAM_WRITE_1(sc, (off) + 1 + offsetof(struct s, f), ((v) & 0xff)); \
436 } while (0)
437
438 #define SRAM_WRITE_FIELD_N(sc, off, s, f, p, n) \
439 ray_write_region(sc, (off) + offsetof(struct s, f), (p), (n))
440
441
442
443
444
445 #define M_PULLUP(m, s) do { \
446 if ((m)->m_len < (s)) \
447 (m) = m_pullup((m), (s)); \
448 } while (0)
449
450 #define RAY_ECF_READY(sc) (!(REG_READ(sc, RAY_ECFIR) & RAY_ECSIR_IRQ))
451 #define RAY_ECF_START_CMD(sc) REG_WRITE(sc, RAY_ECFIR, RAY_ECSIR_IRQ)
452 #define RAY_GET_INDEX(ccs) (((ccs) - RAY_CCS_BASE) / RAY_CCS_SIZE)
453 #define RAY_GET_CCS(i) (RAY_CCS_BASE + (i) * RAY_CCS_SIZE)
454
455
456
457
458
459 static const u_int8_t llc_snapid[6] = { LLC_SNAP_LSAP, LLC_SNAP_LSAP, LLC_UI };
460
461
462 static const ray_cmd_func_t ray_cmdtab[] = {
463 ray_update_subcmd,
464 ray_start_assoc,
465 ray_report_params,
466 ray_intr_start
467 };
468 static const int ray_ncmdtab = sizeof(ray_cmdtab) / sizeof(*ray_cmdtab);
469
470 static const ray_cmd_func_t ray_subcmdtab[] = {
471 ray_download_params,
472 ray_start_join_net,
473 ray_update_promisc,
474 ray_update_mcast,
475 ray_update_params
476 };
477 static const int ray_nsubcmdtab = sizeof(ray_subcmdtab) / sizeof(*ray_subcmdtab);
478
479 struct cfdriver ray_cd = {
480 NULL, "ray", DV_IFNET
481 };
482
483
484 struct cfattach ray_ca = {
485 sizeof(struct ray_softc), (cfmatch_t)ray_match, ray_attach, ray_detach,
486 ray_activate
487 };
488
489
490
491
492
493
494 int
495 ray_match(struct device *parent, struct cfdata *match, void *aux)
496 {
497 struct pcmcia_attach_args *pa = aux;
498
499 #ifdef RAY_DEBUG
500 if (!ltp) {
501
502 ttp = &tv1;
503 ltp = &tv2;
504 microtime(ltp);
505 }
506 #endif
507 return (pa->manufacturer == PCMCIA_VENDOR_RAYTHEON
508 && pa->product == PCMCIA_PRODUCT_RAYTHEON_WLAN);
509 }
510
511
512 void
513 ray_attach(struct device *parent, struct device *self, void *aux)
514 {
515 struct ray_ecf_startup *ep;
516 struct pcmcia_attach_args *pa;
517 struct ray_softc *sc;
518 struct ifnet *ifp;
519 bus_size_t memoff;
520
521 pa = aux;
522 sc = (struct ray_softc *)self;
523 sc->sc_pf = pa->pf;
524 ifp = &sc->sc_if;
525 sc->sc_window = -1;
526
527 printf("\n");
528
529
530 pcmcia_function_init(sc->sc_pf, SIMPLEQ_FIRST(&sc->sc_pf->cfe_head));
531 if (pcmcia_function_enable(sc->sc_pf)) {
532 printf(": failed to enable the card");
533 return;
534 }
535
536
537
538
539 if (pcmcia_mem_alloc(sc->sc_pf, RAY_SRAM_MEM_SIZE, &sc->sc_mem)) {
540 printf(": can\'t alloc shared memory\n");
541 goto fail;
542 }
543
544 if (pcmcia_mem_map(sc->sc_pf, PCMCIA_WIDTH_MEM8|PCMCIA_MEM_COMMON,
545 RAY_SRAM_MEM_BASE, RAY_SRAM_MEM_SIZE, &sc->sc_mem, &memoff,
546 &sc->sc_window)) {
547 printf(": can\'t map shared memory\n");
548 pcmcia_mem_free(sc->sc_pf, &sc->sc_mem);
549 goto fail;
550 }
551
552
553 ep = &sc->sc_ecf_startup;
554 ray_read_region(sc, RAY_ECF_TO_HOST_BASE, ep,
555 sizeof(sc->sc_ecf_startup));
556
557
558 if (ep->e_status != RAY_ECFS_CARD_OK) {
559 printf(": card failed self test: status %d\n",
560 sc->sc_ecf_startup.e_status);
561 goto fail;
562 }
563
564
565 if (sc->sc_version != SC_BUILD_4 && sc->sc_version != SC_BUILD_5) {
566 printf(": unsupported firmware version %d\n",
567 ep->e_fw_build_string);
568 goto fail;
569 }
570
571
572 REG_WRITE(sc, RAY_HCSIR, 0);
573
574
575
576
577 memset(&sc->sc_dnwid, 0, sizeof(sc->sc_dnwid));
578 sc->sc_dnwid.i_len = strlen(RAY_DEF_NWID);
579 if (sc->sc_dnwid.i_len > IEEE80211_NWID_LEN)
580 sc->sc_dnwid.i_len = IEEE80211_NWID_LEN;
581 if (sc->sc_dnwid.i_len > 0)
582 memcpy(sc->sc_dnwid.i_nwid, RAY_DEF_NWID, sc->sc_dnwid.i_len);
583 memcpy(&sc->sc_cnwid, &sc->sc_dnwid, sizeof(sc->sc_cnwid));
584 sc->sc_omode = sc->sc_mode = RAY_MODE_DEFAULT;
585 sc->sc_countrycode = sc->sc_dcountrycode =
586 RAY_PID_COUNTRY_CODE_DEFAULT;
587 sc->sc_flags &= ~RAY_FLAGS_RESUMEINIT;
588
589 timeout_set(&sc->sc_check_ccs_ch, ray_check_ccs, sc);
590 timeout_set(&sc->sc_check_scheduled_ch, ray_check_scheduled, sc);
591 timeout_set(&sc->sc_reset_resetloop_ch, ray_reset_resetloop, sc);
592 timeout_set(&sc->sc_disable_ch, (void (*)(void *))ray_disable, sc);
593 timeout_set(&sc->sc_start_join_timo_ch, ray_start_join_timo, sc);
594
595
596
597
598
599 printf("%s: firmware version %d, ", sc->sc_dev.dv_xname,
600 sc->sc_version);
601 #ifdef RAY_DEBUG
602 if (sc->sc_version != SC_BUILD_4)
603 printf("supported rates %0x:%0x:%0x:%0x:%0x:%0x:%0x:%0x, ",
604 ep->e_rates[0], ep->e_rates[1],
605 ep->e_rates[2], ep->e_rates[3], ep->e_rates[4],
606 ep->e_rates[5], ep->e_rates[6], ep->e_rates[7]);
607 #endif
608 printf("address %s\n", ether_sprintf(ep->e_station_addr));
609
610 memcpy(ifp->if_xname, sc->sc_xname, IFNAMSIZ);
611 ifp->if_softc = sc;
612 ifp->if_start = ray_if_start;
613 ifp->if_ioctl = ray_ioctl;
614 ifp->if_mtu = ETHERMTU;
615 ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST;
616 IFQ_SET_READY(&ifp->if_snd);
617 if_attach(ifp);
618 memcpy(&sc->sc_ec.ac_enaddr, ep->e_station_addr, ETHER_ADDR_LEN);
619 ether_ifattach(ifp);
620
621
622 ifp->if_hdrlen =
623 sizeof(struct ieee80211_frame) + sizeof(struct ether_header);
624
625 ifmedia_init(&sc->sc_media, 0, ray_media_change, ray_media_status);
626 ifmedia_add(&sc->sc_media, IFM_ADHOC, 0, 0);
627 ifmedia_add(&sc->sc_media, IFM_INFRA, 0, 0);
628 if (sc->sc_mode == SC_MODE_ADHOC)
629 ifmedia_set(&sc->sc_media, IFM_ADHOC);
630 else
631 ifmedia_set(&sc->sc_media, IFM_INFRA);
632
633
634 pcmcia_function_disable(sc->sc_pf);
635
636 sc->sc_sdhook = shutdownhook_establish(ray_shutdown, sc);
637 sc->sc_pwrhook = powerhook_establish(ray_power, sc);
638
639
640 sc->sc_flags |= RAY_FLAGS_ATTACHED;
641 return;
642 fail:
643
644 pcmcia_function_disable(sc->sc_pf);
645
646
647 if (sc->sc_window != -1) {
648 pcmcia_mem_unmap(sc->sc_pf, sc->sc_window);
649 pcmcia_mem_free(sc->sc_pf, &sc->sc_mem);
650 }
651 }
652
653 int
654 ray_activate(struct device *dev, enum devact act)
655 {
656 struct ray_softc *sc = (struct ray_softc *)dev;
657 struct ifnet *ifp = &sc->sc_if;
658 int s;
659
660 RAY_DPRINTF(("%s: activate\n", sc->sc_xname));
661
662 s = splnet();
663 switch (act) {
664 case DVACT_ACTIVATE:
665 pcmcia_function_enable(sc->sc_pf);
666 printf("%s:", sc->sc_dev.dv_xname);
667 ray_enable(sc);
668 printf("\n");
669 break;
670
671 case DVACT_DEACTIVATE:
672 if (ifp->if_flags & IFF_RUNNING)
673 ray_disable(sc);
674 if (sc->sc_ih) {
675 pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
676 sc->sc_ih = NULL;
677 }
678 pcmcia_function_disable(sc->sc_pf);
679 break;
680 }
681 splx(s);
682 return (0);
683 }
684
685 int
686 ray_detach(struct device *self, int flags)
687 {
688 struct ray_softc *sc;
689 struct ifnet *ifp;
690
691 sc = (struct ray_softc *)self;
692 ifp = &sc->sc_if;
693 RAY_DPRINTF(("%s: detach\n", sc->sc_xname));
694
695
696 if ((sc->sc_flags & RAY_FLAGS_ATTACHED) == 0)
697 return (0);
698
699 if (ifp->if_flags & IFF_RUNNING)
700 ray_disable(sc);
701
702
703 if (sc->sc_window != -1) {
704 pcmcia_mem_unmap(sc->sc_pf, sc->sc_window);
705 pcmcia_mem_free(sc->sc_pf, &sc->sc_mem);
706 }
707
708 ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY);
709
710 ether_ifdetach(ifp);
711 if_detach(ifp);
712 if (sc->sc_pwrhook != NULL)
713 powerhook_disestablish(sc->sc_pwrhook);
714 if (sc->sc_sdhook != NULL)
715 shutdownhook_disestablish(sc->sc_sdhook);
716
717 return (0);
718 }
719
720
721
722
723 int
724 ray_enable(struct ray_softc *sc)
725 {
726 int error;
727
728 RAY_DPRINTF(("%s: enable\n", sc->sc_xname));
729
730 if ((error = ray_init(sc)) == 0) {
731 sc->sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_NET,
732 ray_intr, sc, sc->sc_dev.dv_xname);
733 if (sc->sc_ih == NULL) {
734 ray_stop(sc);
735 return (EIO);
736 }
737 }
738 return (error);
739 }
740
741
742
743
744 void
745 ray_disable(struct ray_softc *sc)
746 {
747 RAY_DPRINTF(("%s: disable\n", sc->sc_xname));
748
749 if ((sc->sc_if.if_flags & IFF_RUNNING))
750 ray_stop(sc);
751
752 sc->sc_resetloop = 0;
753 sc->sc_rxoverflow = 0;
754 sc->sc_rxcksum = 0;
755 sc->sc_rxhcksum = 0;
756 sc->sc_rxnoise = 0;
757
758 if (sc->sc_ih)
759 pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
760 sc->sc_ih = NULL;
761 }
762
763
764
765
766 int
767 ray_init(struct ray_softc *sc)
768 {
769 struct ray_ecf_startup *ep;
770 bus_size_t ccs;
771 int i;
772
773 RAY_DPRINTF(("%s: init\n", sc->sc_xname));
774
775 if ((sc->sc_if.if_flags & IFF_RUNNING))
776 ray_stop(sc);
777
778 if (pcmcia_function_enable(sc->sc_pf))
779 return (EIO);
780
781 RAY_DPRINTF(("%s: init post-enable\n", sc->sc_xname));
782
783
784 memset(sc->sc_ccsinuse, 0, sizeof(sc->sc_ccsinuse));
785 sc->sc_havenet = 0;
786 memset(sc->sc_bssid, 0, sizeof(sc->sc_bssid));
787 sc->sc_deftxrate = 0;
788 sc->sc_encrypt = 0;
789 sc->sc_txpad = 0;
790 sc->sc_promisc = 0;
791 sc->sc_scheduled = 0;
792 sc->sc_running = 0;
793 sc->sc_txfree = RAY_CCS_NTX;
794 sc->sc_checkcounters = 0;
795 sc->sc_flags &= RAY_FLAGS_RESUMEINIT;
796 sc->sc_authstate = RAY_AUTH_UNAUTH;
797
798
799 ep = &sc->sc_ecf_startup;
800 ray_read_region(sc, RAY_ECF_TO_HOST_BASE, ep,
801 sizeof(sc->sc_ecf_startup));
802
803
804 if (ep->e_status != RAY_ECFS_CARD_OK) {
805 pcmcia_function_disable(sc->sc_pf);
806 printf("%s: card failed self test: status %d\n",
807 sc->sc_xname, sc->sc_ecf_startup.e_status);
808 return (EIO);
809 }
810
811
812 if (sc->sc_version == SC_BUILD_4 && sc->sc_tibsize == 0x55)
813 sc->sc_tibsize = 32;
814 sc->sc_txpad = sc->sc_tibsize;
815
816
817 ccs = RAY_GET_CCS(0);
818 for (i = 0; i < RAY_CCS_LAST; ccs += RAY_CCS_SIZE, i++)
819 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_status,
820 RAY_CCS_STATUS_FREE);
821
822
823 REG_WRITE(sc, RAY_HCSIR, 0);
824
825
826 sc->sc_if.if_flags |= IFF_RUNNING | IFF_OACTIVE;
827
828
829 sc->sc_promisc = !!(sc->sc_if.if_flags & (IFF_PROMISC|IFF_ALLMULTI));
830
831
832 ray_download_params(sc);
833
834 return (0);
835 }
836
837
838
839
840 void
841 ray_stop(struct ray_softc *sc)
842 {
843 RAY_DPRINTF(("%s: stop\n", sc->sc_xname));
844
845 callout_stop(&sc->sc_check_ccs_ch);
846 sc->sc_timocheck = 0;
847
848 callout_stop(&sc->sc_check_scheduled_ch);
849 sc->sc_timoneed = 0;
850
851 if (sc->sc_repreq) {
852 sc->sc_repreq->r_failcause = RAY_FAILCAUSE_EDEVSTOP;
853 wakeup(ray_report_params);
854 }
855 if (sc->sc_updreq) {
856 sc->sc_repreq->r_failcause = RAY_FAILCAUSE_EDEVSTOP;
857 wakeup(ray_update_params);
858 }
859
860 sc->sc_if.if_flags &= ~IFF_RUNNING;
861 pcmcia_function_disable(sc->sc_pf);
862 }
863
864
865
866
867 void
868 ray_reset(struct ray_softc *sc)
869 {
870 if (++sc->sc_resetloop >= RAY_MAX_RESETS) {
871 if (sc->sc_resetloop == RAY_MAX_RESETS) {
872 printf("%s: unable to correct, disabling\n",
873 sc->sc_xname);
874 callout_stop(&sc->sc_reset_resetloop_ch);
875 callout_reset(&sc->sc_disable_ch, 1,
876 (void (*)(void *))ray_disable, sc);
877 }
878 } else {
879 printf("%s: unexpected failure resetting hw [%d more]\n",
880 sc->sc_xname, RAY_MAX_RESETS - sc->sc_resetloop);
881 callout_stop(&sc->sc_reset_resetloop_ch);
882 ray_init(sc);
883 callout_reset(&sc->sc_reset_resetloop_ch, RAY_RESET_TIMEOUT,
884 ray_reset_resetloop, sc);
885 }
886 }
887
888
889
890
891
892
893
894 void
895 ray_reset_resetloop(void *arg)
896 {
897 struct ray_softc *sc;
898
899 sc = arg;
900 sc->sc_resetloop = 0;
901 }
902
903 void
904 ray_power(int why, void *arg)
905 {
906 #if 0
907 struct ray_softc *sc;
908
909
910 sc = arg;
911 switch (why) {
912 case PWR_RESUME:
913 if ((sc->sc_flags & RAY_FLAGS_RESUMEINIT))
914 ray_init(sc);
915 break;
916 case PWR_SUSPEND:
917 if ((sc->sc_if.if_flags & IFF_RUNNING)) {
918 ray_stop(sc);
919 sc->sc_flags |= RAY_FLAGS_RESUMEINIT;
920 }
921 break;
922 case PWR_STANDBY:
923 default:
924 break;
925 }
926 #endif
927 }
928
929 void
930 ray_shutdown(void *arg)
931 {
932 struct ray_softc *sc;
933
934 sc = arg;
935 ray_disable(sc);
936 }
937
938 int
939 ray_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
940 {
941 struct ieee80211_nwid nwid;
942 struct ray_param_req pr;
943 struct ray_softc *sc;
944 struct ifreq *ifr;
945 struct ifaddr *ifa;
946 int error, error2, s, i;
947
948 sc = ifp->if_softc;
949 error = 0;
950
951 ifr = (struct ifreq *)data;
952
953 s = splnet();
954
955 RAY_DPRINTF(("%s: ioctl: cmd 0x%lx data 0x%lx\n", ifp->if_xname,
956 cmd, (long)data));
957
958 if ((error = ether_ioctl(ifp, &sc->sc_ec, cmd, data)) > 0) {
959 splx(s);
960 return error;
961 }
962
963 switch (cmd) {
964 case SIOCSIFADDR:
965 RAY_DPRINTF(("%s: ioctl: cmd SIOCSIFADDR\n", ifp->if_xname));
966 if ((ifp->if_flags & IFF_RUNNING) == 0)
967 if ((error = ray_enable(sc)))
968 break;
969 ifp->if_flags |= IFF_UP;
970 ifa = (struct ifaddr *)data;
971 switch (ifa->ifa_addr->sa_family) {
972 #ifdef INET
973 case AF_INET:
974 arp_ifinit(&sc->sc_ec, ifa);
975 break;
976 #endif
977 default:
978 break;
979 }
980 break;
981 case SIOCSIFFLAGS:
982 RAY_DPRINTF(("%s: ioctl: cmd SIOCSIFFLAGS\n", ifp->if_xname));
983 if (ifp->if_flags & IFF_UP) {
984 if ((ifp->if_flags & IFF_RUNNING) == 0) {
985 if ((error = ray_enable(sc)))
986 break;
987 } else
988 ray_update_promisc(sc);
989 } else if (ifp->if_flags & IFF_RUNNING)
990 ray_disable(sc);
991 break;
992 case SIOCADDMULTI:
993 case SIOCDELMULTI:
994 if (cmd == SIOCADDMULTI) {
995 RAY_DPRINTF(("%s: ioctl: cmd SIOCADDMULTI\n",
996 ifp->if_xname));
997 error = ether_addmulti(ifr, &sc->sc_ec);
998 } else {
999 RAY_DPRINTF(("%s: ioctl: cmd SIOCDELMULTI\n",
1000 ifp->if_xname));
1001 error = ether_delmulti(ifr, &sc->sc_ec);
1002 }
1003 if (error == ENETRESET) {
1004 error = 0;
1005 ray_update_mcast(sc);
1006 }
1007 break;
1008 case SIOCSIFMEDIA:
1009 RAY_DPRINTF(("%s: ioctl: cmd SIOCSIFMEDIA\n", ifp->if_xname));
1010 case SIOCGIFMEDIA:
1011 if (cmd == SIOCGIFMEDIA)
1012 RAY_DPRINTF(("%s: ioctl: cmd SIOCGIFMEDIA\n",
1013 ifp->if_xname));
1014 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
1015 break;
1016 case SIOCSRAYPARAM:
1017 if ((error = suser(curproc, 0)) != 0)
1018 break;
1019 RAY_DPRINTF(("%s: ioctl: cmd SIOCSRAYPARAM\n", ifp->if_xname));
1020 if ((error = copyin(ifr->ifr_data, &pr, sizeof(pr))))
1021 break;
1022
1023 switch (pr.r_paramid) {
1024 case RAY_PID_NET_TYPE:
1025 case RAY_PID_AP_STATUS:
1026 case RAY_PID_SSID:
1027 case RAY_PID_MAC_ADDR:
1028 case RAY_PID_PROMISC:
1029 error = EINVAL;
1030 break;
1031 }
1032 error = ray_user_update_params(sc, &pr);
1033 error2 = copyout(&pr, ifr->ifr_data, sizeof(pr));
1034 error = error2 ? error2 : error;
1035 break;
1036 case SIOCGRAYPARAM:
1037 RAY_DPRINTF(("%s: ioctl: cmd SIOCGRAYPARAM\n", ifp->if_xname));
1038 if ((error = copyin(ifr->ifr_data, &pr, sizeof(pr))))
1039 break;
1040 error = ray_user_report_params(sc, &pr);
1041 error2 = copyout(&pr, ifr->ifr_data, sizeof(pr));
1042 error = error2 ? error2 : error;
1043 break;
1044 case SIOCS80211NWID:
1045 if ((error = suser(curproc, 0)) != 0)
1046 break;
1047 RAY_DPRINTF(("%s: ioctl: cmd SIOCS80211NWID\n", ifp->if_xname));
1048
1049
1050
1051
1052
1053 if ((error = copyin(ifr->ifr_data, &nwid, sizeof(nwid))))
1054 break;
1055 if (nwid.i_len > IEEE80211_NWID_LEN) {
1056 error = EINVAL;
1057 break;
1058 }
1059
1060 for (i = nwid.i_len; i < IEEE80211_NWID_LEN; i++)
1061 nwid.i_nwid[i] = 0;
1062 if (!memcmp(&sc->sc_dnwid, &nwid, sizeof(nwid)))
1063 break;
1064 memcpy(&sc->sc_dnwid, &nwid, sizeof(nwid));
1065 if (ifp->if_flags & IFF_RUNNING)
1066 ray_start_join_net(sc);
1067 break;
1068 case SIOCG80211NWID:
1069 RAY_DPRINTF(("%s: ioctl: cmd SIOCG80211NWID\n", ifp->if_xname));
1070 error = copyout(&sc->sc_cnwid, ifr->ifr_data,
1071 sizeof(sc->sc_cnwid));
1072 break;
1073 #ifdef RAY_DO_SIGLEV
1074 error = copyout(sc->sc_siglevs, ifr->ifr_data,
1075 sizeof sc->sc_siglevs);
1076 break;
1077 #endif
1078 default:
1079 RAY_DPRINTF(("%s: ioctl: unknown\n", ifp->if_xname));
1080 error = EINVAL;
1081 break;
1082 }
1083
1084 RAY_DPRINTF(("%s: ioctl: returns %d\n", ifp->if_xname, error));
1085
1086 splx(s);
1087
1088 return (error);
1089 }
1090
1091
1092
1093
1094 void
1095 ray_if_start(struct ifnet *ifp)
1096 {
1097 struct ray_softc *sc;
1098
1099 sc = ifp->if_softc;
1100 ray_intr_start(sc);
1101 }
1102
1103 int
1104 ray_media_change(struct ifnet *ifp)
1105 {
1106 struct ray_softc *sc;
1107
1108 sc = ifp->if_softc;
1109 RAY_DPRINTF(("%s: media change cur %d\n", ifp->if_xname,
1110 sc->sc_media.ifm_cur->ifm_media));
1111 if (sc->sc_media.ifm_cur->ifm_media & IFM_IEEE80211_ADHOC)
1112 sc->sc_mode = SC_MODE_ADHOC;
1113 else
1114 sc->sc_mode = SC_MODE_INFRA;
1115 if (sc->sc_mode != sc->sc_omode)
1116 ray_start_join_net(sc);
1117 return (0);
1118 }
1119
1120 void
1121 ray_media_status(struct ifnet *ifp, struct ifmediareq *imr)
1122 {
1123 struct ray_softc *sc;
1124
1125 sc = ifp->if_softc;
1126
1127 RAY_DPRINTF(("%s: media status\n", ifp->if_xname));
1128
1129 imr->ifm_status = IFM_AVALID;
1130 if (sc->sc_havenet)
1131 imr->ifm_status |= IFM_ACTIVE;
1132
1133 if (sc->sc_mode == SC_MODE_ADHOC)
1134 imr->ifm_active = IFM_ADHOC;
1135 else
1136 imr->ifm_active = IFM_INFRA;
1137 }
1138
1139
1140
1141
1142
1143 void
1144 ray_intr_start(struct ray_softc *sc)
1145 {
1146 struct ieee80211_frame *iframe;
1147 struct ether_header *eh;
1148 size_t len, pktlen, tmplen;
1149 bus_size_t bufp, ebufp;
1150 struct mbuf *m0, *m;
1151 struct ifnet *ifp;
1152 u_int firsti, hinti, previ, i, pcount;
1153 u_int16_t et;
1154 u_int8_t *d;
1155
1156 ifp = &sc->sc_if;
1157
1158 RAY_DPRINTF(("%s: start free %d qlen %d qmax %d\n",
1159 ifp->if_xname, sc->sc_txfree, ifp->if_snd.ifq_len,
1160 ifp->if_snd.ifq_maxlen));
1161
1162 ray_cmd_cancel(sc, SCP_IFSTART);
1163
1164 if ((ifp->if_flags & IFF_RUNNING) == 0 || !sc->sc_havenet) {
1165 RAY_DPRINTF(("%s: nonet.\n",ifp->if_xname));
1166 return;
1167 }
1168
1169 if (IFQ_IS_EMPTY(&ifp->if_snd)) {
1170 RAY_DPRINTF(("%s: nothing to send.\n",ifp->if_xname));
1171 return;
1172 }
1173
1174 firsti = i = previ = RAY_CCS_LINK_NULL;
1175 hinti = RAY_CCS_TX_FIRST;
1176
1177 if (!RAY_ECF_READY(sc)) {
1178 ray_cmd_schedule(sc, SCP_IFSTART);
1179 return;
1180 }
1181
1182
1183 if (sc->sc_authstate == RAY_AUTH_NEEDED) {
1184 RAY_DPRINTF(("%s: Sending auth request.\n",ifp->if_xname));
1185 sc->sc_authstate= RAY_AUTH_WAITING;
1186 ray_send_auth(sc,sc->sc_authid,OPEN_AUTH_REQUEST);
1187 return;
1188 }
1189
1190 pcount = 0;
1191 for (;;) {
1192
1193 if (i == RAY_CCS_LINK_NULL) {
1194 i = ray_find_free_tx_ccs(sc, hinti);
1195 if (i == RAY_CCS_LINK_NULL) {
1196 RAY_DPRINTF(("%s: no descriptors.\n",ifp->if_xname));
1197 ifp->if_flags |= IFF_OACTIVE;
1198 break;
1199 }
1200 }
1201
1202 IFQ_DEQUEUE(&ifp->if_snd, m0);
1203 if (!m0) {
1204 RAY_DPRINTF(("%s: dry queue.\n", ifp->if_xname));
1205 break;
1206 }
1207 RAY_DPRINTF(("%s: gotmbuf 0x%lx\n", ifp->if_xname, (long)m0));
1208 pktlen = m0->m_pkthdr.len;
1209 if (pktlen > ETHER_MAX_LEN - ETHER_CRC_LEN) {
1210 RAY_DPRINTF((
1211 "%s: mbuf too long %lu\n", ifp->if_xname,
1212 (u_long)pktlen));
1213 ifp->if_oerrors++;
1214 m_freem(m0);
1215 continue;
1216 }
1217 RAY_DPRINTF(("%s: mbuf.m_pkthdr.len %lu\n", ifp->if_xname,
1218 (u_long)pktlen));
1219
1220
1221 M_PULLUP(m0, sizeof(struct ether_header));
1222 if (!m0) {
1223 RAY_DPRINTF(( "%s: couldn\'t pullup ether header\n",
1224 ifp->if_xname));
1225 ifp->if_oerrors++;
1226 continue;
1227 }
1228 RAY_DPRINTF(("%s: got pulled up mbuf 0x%lx\n", ifp->if_xname,
1229 (long)m0));
1230
1231
1232 eh = mtod(m0, struct ether_header *);
1233 et = ntohs(eh->ether_type);
1234 if (ifp->if_flags & IFF_LINK0) {
1235
1236 if (et <= ETHERMTU) {
1237 m_freem(m0);
1238 ifp->if_oerrors++;
1239 continue;
1240 }
1241 tmplen = sizeof(struct ieee80211_frame);
1242 } else if (et > ETHERMTU) {
1243
1244 tmplen= sizeof(struct ieee80211_frame) - ETHER_ADDR_LEN;
1245 }
1246
1247 M_PREPEND(m0, tmplen, M_DONTWAIT);
1248 if (m0)
1249 M_PULLUP(m0, sizeof(struct ether_header) + tmplen);
1250 if (!m0) {
1251 RAY_DPRINTF(("%s: couldn\'t prepend header\n",
1252 ifp->if_xname));
1253 ifp->if_oerrors++;
1254 continue;
1255 }
1256
1257 iframe = mtod(m0, struct ieee80211_frame *);
1258 eh = (struct ether_header *)((u_int8_t *)iframe + tmplen);
1259 iframe->i_fc[0] =
1260 (IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA);
1261 if (sc->sc_mode == SC_MODE_ADHOC) {
1262 iframe->i_fc[1] = IEEE80211_FC1_DIR_NODS;
1263 memcpy(iframe->i_addr1, eh->ether_dhost,ETHER_ADDR_LEN);
1264 memcpy(iframe->i_addr2, eh->ether_shost,ETHER_ADDR_LEN);
1265 memcpy(iframe->i_addr3, sc->sc_bssid, ETHER_ADDR_LEN);
1266 } else {
1267 iframe->i_fc[1] = IEEE80211_FC1_DIR_TODS;
1268 memcpy(iframe->i_addr1, sc->sc_bssid,ETHER_ADDR_LEN);
1269 memcpy(iframe->i_addr2, eh->ether_shost,ETHER_ADDR_LEN);
1270 memmove(iframe->i_addr3,eh->ether_dhost,ETHER_ADDR_LEN);
1271 }
1272 iframe->i_dur[0] = iframe->i_dur[1] = 0;
1273 iframe->i_seq[0] = iframe->i_seq[1] = 0;
1274
1275
1276 if ((ifp->if_flags & IFF_LINK0) == 0 && et > ETHERMTU)
1277 memcpy(iframe + 1, llc_snapid, sizeof(llc_snapid));
1278
1279 RAY_DPRINTF(("%s: i %d previ %d\n", ifp->if_xname, i, previ));
1280
1281 if (firsti == RAY_CCS_LINK_NULL)
1282 firsti = i;
1283
1284 pktlen = m0->m_pkthdr.len;
1285 bufp = ray_fill_in_tx_ccs(sc, pktlen, i, previ);
1286 previ = hinti = i;
1287 i = RAY_CCS_LINK_NULL;
1288
1289 RAY_DPRINTF(("%s: bufp 0x%lx new pktlen %lu\n",
1290 ifp->if_xname, (long)bufp, (u_long)pktlen));
1291
1292
1293 for (m = m0; m; m = m->m_next) {
1294 if ((len = m->m_len) == 0)
1295 continue;
1296 RAY_DPRINTF((
1297 "%s: copying mbuf 0x%lx bufp 0x%lx len %d\n",
1298 ifp->if_xname, (long)m, (long)bufp, (int)len));
1299 d = mtod(m, u_int8_t *);
1300 ebufp = bufp + len;
1301 if (ebufp <= RAY_TX_END)
1302 ray_write_region(sc, bufp, d, len);
1303 else {
1304 panic("ray_intr_start");
1305
1306 tmplen = ebufp - bufp;
1307 len -= tmplen;
1308 ray_write_region(sc, bufp, d, tmplen);
1309 d += tmplen;
1310 bufp = RAY_TX_BASE;
1311 ray_write_region(sc, bufp, d, len);
1312 }
1313 bufp += len;
1314 }
1315 #if NBPFILTER > 0
1316 if (ifp->if_bpf) {
1317 if (ifp->if_flags & IFF_LINK0) {
1318 m0->m_data += sizeof(struct ieee80211_frame);
1319 m0->m_len -= sizeof(struct ieee80211_frame);
1320 m0->m_pkthdr.len -= sizeof(struct ieee80211_frame);
1321 }
1322 bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
1323 if (ifp->if_flags & IFF_LINK0) {
1324 m0->m_data -= sizeof(struct ieee80211_frame);
1325 m0->m_len += sizeof(struct ieee80211_frame);
1326 m0->m_pkthdr.len += sizeof(struct ieee80211_frame);
1327 }
1328 }
1329 #endif
1330
1331 #ifdef RAY_DEBUG
1332 if (ray_debug && ray_debug_dump_tx)
1333 ray_dump_mbuf(sc, m0);
1334 #endif
1335 pcount++;
1336 m_freem(m0);
1337 }
1338
1339 if (firsti == RAY_CCS_LINK_NULL)
1340 return;
1341 i = 0;
1342 if (!RAY_ECF_READY(sc)) {
1343
1344
1345
1346
1347
1348
1349 printf("%s: dropping tx packets device busy\n", sc->sc_xname);
1350 ray_free_ccs_chain(sc, firsti);
1351 ifp->if_oerrors += pcount;
1352 return;
1353 }
1354
1355
1356 RAY_DPRINTF(("%s: ray_start issueing %d \n", sc->sc_xname, firsti));
1357 SRAM_WRITE_1(sc, RAY_SCB_CCSI, firsti);
1358 RAY_ECF_START_CMD(sc);
1359
1360 RAY_DPRINTF_XMIT(("%s: sent packet: len %lu\n", sc->sc_xname,
1361 (u_long)pktlen));
1362
1363 ifp->if_opackets += pcount;
1364 }
1365
1366
1367
1368
1369 void
1370 ray_recv(struct ray_softc *sc, bus_size_t ccs)
1371 {
1372 struct ieee80211_frame *frame;
1373 struct ether_header *eh;
1374 struct mbuf *m;
1375 size_t pktlen, fudge, len, lenread;
1376 bus_size_t bufp, ebufp, tmp;
1377 struct ifnet *ifp;
1378 u_int8_t *src, *d;
1379 u_int frag, nofrag, ni, i, issnap, first;
1380 u_int8_t fc0;
1381 #ifdef RAY_DO_SIGLEV
1382 u_int8_t siglev;
1383 #endif
1384
1385 #ifdef RAY_DEBUG
1386
1387 if (ray_debug && ray_debug_dump_desc)
1388 hexdump((caddr_t)sc->sc_memh + RAY_RCS_BASE, 0x400,
1389 16, 4, 0);
1390 #endif
1391
1392 nofrag = 0;
1393 m = 0;
1394 ifp = &sc->sc_if;
1395
1396
1397
1398
1399
1400
1401
1402
1403 fudge = ifp->if_flags & IFF_LINK0? 2 : 0;
1404
1405
1406 first = RAY_GET_INDEX(ccs);
1407 pktlen = SRAM_READ_FIELD_2(sc, ccs, ray_cmd_rx, c_pktlen);
1408 #ifdef RAY_DO_SIGLEV
1409 siglev = SRAM_READ_FIELD_1(sc, ccs, ray_cmd_rx, c_siglev);
1410 #endif
1411 RAY_DPRINTF(("%s: recv pktlen %lu nofrag %d\n", sc->sc_xname,
1412 (u_long)pktlen, nofrag));
1413 RAY_DPRINTF_XMIT(("%s: received packet: len %lu\n", sc->sc_xname,
1414 (u_long)pktlen));
1415 if (pktlen > MCLBYTES || pktlen < (sizeof(*frame)) ) {
1416 RAY_DPRINTF(("%s: PKTLEN TOO BIG OR TOO SMALL\n",
1417 sc->sc_xname));
1418 ifp->if_ierrors++;
1419 goto done;
1420 }
1421 MGETHDR(m, M_DONTWAIT, MT_DATA);
1422 if (!m) {
1423 RAY_DPRINTF(("%s: MGETHDR FAILED\n", sc->sc_xname));
1424 ifp->if_ierrors++;
1425 goto done;
1426 }
1427 if ((pktlen + fudge) > MHLEN) {
1428
1429 MCLGET(m, M_DONTWAIT);
1430 if ((m->m_flags & M_EXT) == 0) {
1431 RAY_DPRINTF(("%s: MCLGET FAILED\n", sc->sc_xname));
1432 ifp->if_ierrors++;
1433 m_freem(m);
1434 m = 0;
1435 goto done;
1436 }
1437 }
1438 m->m_pkthdr.rcvif = ifp;
1439 m->m_pkthdr.len = pktlen;
1440 m->m_len = pktlen;
1441 m->m_data += fudge;
1442 d = mtod(m, u_int8_t *);
1443
1444 RAY_DPRINTF(("%s: recv ccs index %d\n", sc->sc_xname, first));
1445 frag = 0;
1446 lenread = 0;
1447 i = ni = first;
1448 while ((i = ni) && i != RAY_CCS_LINK_NULL) {
1449 ccs = RAY_GET_CCS(i);
1450 bufp = SRAM_READ_FIELD_2(sc, ccs, ray_cmd_rx, c_bufp);
1451 len = SRAM_READ_FIELD_2(sc, ccs, ray_cmd_rx, c_len);
1452
1453 #if 0
1454
1455 if (frag++ == 0)
1456 len -= 4;
1457 #endif
1458 ni = SRAM_READ_FIELD_1(sc, ccs, ray_cmd_rx, c_nextfrag);
1459 RAY_DPRINTF(("%s: recv frag index %d len %lu bufp %p ni %d\n",
1460 sc->sc_xname, i, (u_long)len, bufp, ni));
1461 if (len + lenread > pktlen) {
1462 RAY_DPRINTF(("%s: BAD LEN current %lu pktlen %lu\n",
1463 sc->sc_xname, (u_long)(len + lenread),
1464 (u_long)pktlen));
1465 ifp->if_ierrors++;
1466 m_freem(m);
1467 m = 0;
1468 goto done;
1469 }
1470 if (i < RAY_RCCS_FIRST) {
1471 printf("ray_recv: bad ccs index 0x%x\n", i);
1472 m_freem(m);
1473 m = 0;
1474 goto done;
1475 }
1476
1477 ebufp = bufp + len;
1478 if (ebufp <= RAY_RX_END)
1479 ray_read_region(sc, bufp, d, len);
1480 else {
1481
1482 ray_read_region(sc, bufp, d, (tmp = RAY_RX_END - bufp));
1483 ray_read_region(sc, RAY_RX_BASE, d + tmp, ebufp - RAY_RX_END);
1484 }
1485 d += len;
1486 lenread += len;
1487 }
1488 done:
1489
1490 RAY_DPRINTF(("%s: recv frag count %d\n", sc->sc_xname, frag));
1491
1492
1493 ni = first;
1494 while ((i = ni) && (i != RAY_CCS_LINK_NULL)) {
1495 ccs = RAY_GET_CCS(i);
1496 ni = SRAM_READ_FIELD_1(sc, ccs, ray_cmd_rx, c_nextfrag);
1497 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_status,
1498 RAY_CCS_STATUS_FREE);
1499 }
1500
1501 if (!m)
1502 return;
1503
1504 RAY_DPRINTF(("%s: recv got packet pktlen %lu actual %lu\n",
1505 sc->sc_xname, (u_long)pktlen, (u_long)lenread));
1506 #ifdef RAY_DEBUG
1507 if (ray_debug && ray_debug_dump_rx)
1508 ray_dump_mbuf(sc, m);
1509 #endif
1510
1511 frame = mtod(m, struct ieee80211_frame *);
1512 fc0 = frame->i_fc[0]
1513 & (IEEE80211_FC0_VERSION_MASK|IEEE80211_FC0_TYPE_MASK);
1514 if ((fc0 & IEEE80211_FC0_VERSION_MASK) != IEEE80211_FC0_VERSION_0) {
1515 RAY_DPRINTF(("%s: pkt not version 0 fc 0x%x\n",
1516 sc->sc_xname, fc0));
1517 m_freem(m);
1518 return;
1519 }
1520 if ((fc0 & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT) {
1521 switch (frame->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) {
1522 case IEEE80211_FC0_SUBTYPE_BEACON:
1523 break;
1524 case IEEE80211_FC0_SUBTYPE_AUTH:
1525 ray_recv_auth(sc,frame);
1526 break;
1527 case IEEE80211_FC0_SUBTYPE_DEAUTH:
1528 sc->sc_authstate= RAY_AUTH_UNAUTH;
1529 break;
1530 default:
1531 RAY_DPRINTF(("%s: mgt packet not supported\n",sc->sc_xname));
1532 #ifdef RAY_DEBUG
1533 hexdump((const u_int8_t*)frame, pktlen, 16,4,0);
1534 #endif
1535 RAY_DPRINTF(("\n"));
1536 break; }
1537 m_freem(m);
1538 return;
1539
1540 } else if ((fc0 & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA) {
1541 RAY_DPRINTF(("%s: pkt not type data fc0 0x%x fc1 0x%x\n",
1542 sc->sc_xname, frame->i_fc[0], frame->i_fc[1]));
1543 #ifdef RAY_DEBUG
1544 hexdump((const u_int8_t*)frame, pktlen, 16,4,0);
1545 #endif
1546 RAY_DPRINTF(("\n"));
1547
1548 m_freem(m);
1549 return;
1550 }
1551
1552 if (pktlen < sizeof(struct ieee80211_frame) + sizeof(struct llc))
1553 {
1554 RAY_DPRINTF(("%s: pkt not big enough to contain llc (%lu)\n",
1555 sc->sc_xname, (u_long)pktlen));
1556 m_freem(m);
1557 return;
1558 }
1559
1560 if (!memcmp(frame + 1, llc_snapid, sizeof(llc_snapid)))
1561 issnap = 1;
1562 else {
1563
1564
1565
1566
1567
1568 RAY_DPRINTF(("%s: pkt not snap 0\n", sc->sc_xname));
1569 if ((ifp->if_flags & IFF_LINK0) == 0) {
1570 m_freem(m);
1571 return;
1572 }
1573 issnap = 0;
1574 }
1575 switch (frame->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
1576 case IEEE80211_FC1_DIR_NODS:
1577 src = frame->i_addr2;
1578 break;
1579 case IEEE80211_FC1_DIR_FROMDS:
1580 src = frame->i_addr3;
1581 break;
1582 case IEEE80211_FC1_DIR_TODS:
1583 RAY_DPRINTF(("%s: pkt ap2ap\n", sc->sc_xname));
1584 m_freem(m);
1585 return;
1586 default:
1587 RAY_DPRINTF(("%s: pkt type unknown\n", sc->sc_xname));
1588 m_freem(m);
1589 return;
1590 }
1591
1592 #ifdef RAY_DO_SIGLEV
1593 ray_update_siglev(sc, src, siglev);
1594 #endif
1595
1596
1597
1598
1599 if (issnap) {
1600
1601 eh = (struct ether_header *)((caddr_t)(frame + 1) - 6);
1602 memcpy(eh->ether_shost, src, ETHER_ADDR_LEN);
1603 memcpy(eh->ether_dhost, frame->i_addr1, ETHER_ADDR_LEN);
1604 } else {
1605
1606 eh = (struct ether_header *)(frame + 1);
1607 }
1608 m_adj(m, (caddr_t)eh - (caddr_t)frame);
1609 #if NBPFILTER > 0
1610 if (ifp->if_bpf)
1611 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
1612 #endif
1613 ifp->if_ipackets++;
1614
1615 ether_input_mbuf(ifp, m);
1616 }
1617
1618
1619
1620
1621
1622 void
1623 ray_recv_auth(struct ray_softc *sc, struct ieee80211_frame *frame)
1624 {
1625
1626 u_int8_t *var= (u_int8_t*)(frame+1);
1627
1628
1629 if (sc->sc_mode == SC_MODE_ADHOC) {
1630 RAY_DPRINTF(("%s: recv auth. packet dump:\n",sc->sc_xname));
1631 #ifdef RAY_DEBUG
1632 hexdump((u_int8_t*)frame, sizeof(*frame)+6, 16,4,0);
1633 #endif
1634 RAY_DPRINTF(("\n"));
1635
1636 if (var[2] == OPEN_AUTH_REQUEST) {
1637 RAY_DPRINTF(("%s: Sending authentication response.\n",sc->sc_xname));
1638 if (!ray_send_auth(sc,frame->i_addr2,OPEN_AUTH_RESPONSE)) {
1639 sc->sc_authstate= RAY_AUTH_NEEDED;
1640 memcpy(sc->sc_authid, frame->i_addr2, ETHER_ADDR_LEN);
1641 }
1642 }
1643 else if (var[2] == OPEN_AUTH_RESPONSE) {
1644 RAY_DPRINTF(("%s: Authenticated!\n",sc->sc_xname));
1645 sc->sc_authstate= RAY_AUTH_AUTH;
1646 }
1647 }
1648 }
1649
1650
1651
1652
1653
1654
1655 int
1656 ray_send_auth(struct ray_softc *sc, u_int8_t *dest, u_int8_t auth_type)
1657 {
1658 u_int8_t packet[sizeof(struct ieee80211_frame) + 6];
1659 bus_size_t bufp;
1660 struct ieee80211_frame *frame= (struct ieee80211_frame*)packet;
1661 int ccsindex= RAY_CCS_LINK_NULL;
1662 ccsindex= ray_find_free_tx_ccs(sc,RAY_CCS_TX_FIRST);
1663 if (ccsindex == RAY_CCS_LINK_NULL) {
1664 RAY_DPRINTF(("%x: send authenticate - No free tx ccs\n"));
1665 return -1;
1666 }
1667 bufp= ray_fill_in_tx_ccs(sc,sizeof(packet),ccsindex,RAY_CCS_LINK_NULL);
1668 frame= (struct ieee80211_frame*) packet;
1669 frame->i_fc[0]= IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_SUBTYPE_AUTH;
1670 frame->i_fc[1]= 0;
1671 memcpy(frame->i_addr1,dest,ETHER_ADDR_LEN);
1672 memcpy(frame->i_addr2,sc->sc_ecf_startup.e_station_addr,ETHER_ADDR_LEN);
1673 memcpy(frame->i_addr3,sc->sc_bssid,ETHER_ADDR_LEN);
1674 memset(frame+1,0,6);
1675 ((u_int8_t*)(frame+1))[2]= auth_type;
1676
1677 ray_write_region(sc,bufp,packet,sizeof(packet));
1678
1679 SRAM_WRITE_1(sc, RAY_SCB_CCSI, ccsindex);
1680 RAY_ECF_START_CMD(sc);
1681
1682 RAY_DPRINTF_XMIT(("%s: sent auth packet: len %lu\n", sc->sc_xname,
1683 (u_long)sizeof(packet)));
1684 return 0;
1685 }
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695 u_int
1696 ray_find_free_tx_ccs(struct ray_softc *sc, u_int hint)
1697 {
1698 u_int i, stat;
1699
1700 for (i = hint; i <= RAY_CCS_TX_LAST; i++) {
1701 stat = SRAM_READ_FIELD_1(sc, RAY_GET_CCS(i), ray_cmd, c_status);
1702 if (stat == RAY_CCS_STATUS_FREE)
1703 return (i);
1704 }
1705
1706 if (hint == RAY_CCS_TX_FIRST)
1707 return (RAY_CCS_LINK_NULL);
1708
1709 for (i = RAY_CCS_TX_FIRST; i < hint; i++) {
1710 stat = SRAM_READ_FIELD_1(sc, RAY_GET_CCS(i), ray_cmd, c_status);
1711 if (stat == RAY_CCS_STATUS_FREE)
1712 return (i);
1713 }
1714 return (RAY_CCS_LINK_NULL);
1715 }
1716
1717
1718
1719
1720
1721 bus_size_t
1722 ray_fill_in_tx_ccs(struct ray_softc *sc, size_t pktlen, u_int i, u_int pi)
1723 {
1724 bus_size_t ccs, bufp;
1725
1726
1727 bufp = RAY_TX_BASE + i * RAY_TX_BUF_SIZE;
1728 bufp += sc->sc_txpad;
1729 ccs = RAY_GET_CCS(i);
1730 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_tx, c_status, RAY_CCS_STATUS_BUSY);
1731 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_tx, c_cmd, RAY_CMD_TX_REQ);
1732 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_tx, c_link, RAY_CCS_LINK_NULL);
1733 SRAM_WRITE_FIELD_2(sc, ccs, ray_cmd_tx, c_bufp, bufp);
1734 SRAM_WRITE_FIELD_2(sc, ccs, ray_cmd_tx, c_len, pktlen);
1735 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_tx, c_tx_rate, sc->sc_deftxrate);
1736 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_tx, c_apm_mode, 0);
1737 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_tx, c_antenna, 0);
1738
1739
1740 if (pi != RAY_CCS_LINK_NULL)
1741 SRAM_WRITE_FIELD_1(sc, RAY_GET_CCS(pi), ray_cmd_tx, c_link, i);
1742
1743 RAY_DPRINTF(("%s: ray_alloc_tx_ccs bufp 0x%lx idx %d pidx %d \n",
1744 sc->sc_xname, bufp, i, pi));
1745
1746 return (bufp + RAY_TX_PHY_SIZE);
1747 }
1748
1749
1750
1751
1752
1753 ray_cmd_func_t
1754 ray_update_params_done(struct ray_softc *sc, bus_size_t ccs, u_int stat)
1755 {
1756 ray_cmd_func_t rcmd;
1757
1758 rcmd = 0;
1759
1760 RAY_DPRINTF(("%s: ray_update_params_done stat %d\n",
1761 sc->sc_xname, stat));
1762
1763
1764 if (stat == RAY_CCS_STATUS_FAIL) {
1765 printf("%s: failed to update a promisc\n", sc->sc_xname);
1766
1767
1768 }
1769
1770 if (sc->sc_running & SCP_UPD_PROMISC) {
1771 ray_cmd_done(sc, SCP_UPD_PROMISC);
1772 sc->sc_promisc = SRAM_READ_1(sc, RAY_HOST_TO_ECF_BASE);
1773 RAY_DPRINTF(("%s: new promisc value %d\n", sc->sc_xname,
1774 sc->sc_promisc));
1775 } else if (sc->sc_updreq) {
1776 ray_cmd_done(sc, SCP_UPD_UPDATEPARAMS);
1777
1778 sc->sc_updreq->r_failcause =
1779 SRAM_READ_FIELD_1(sc, ccs, ray_cmd_update, c_failcause);
1780 sc->sc_updreq = 0;
1781 wakeup(ray_update_params);
1782
1783 rcmd = ray_start_join_net;
1784 }
1785 return (rcmd);
1786 }
1787
1788
1789
1790
1791 void
1792 ray_check_scheduled(void *arg)
1793 {
1794 struct ray_softc *sc;
1795 int s, i, mask;
1796
1797 s = splnet();
1798
1799 sc = arg;
1800 RAY_DPRINTF((
1801 "%s: ray_check_scheduled enter schd 0x%x running 0x%x ready %d\n",
1802 sc->sc_xname, sc->sc_scheduled, sc->sc_running, RAY_ECF_READY(sc)));
1803
1804 if (sc->sc_timoneed) {
1805 callout_stop(&sc->sc_check_scheduled_ch);
1806 sc->sc_timoneed = 0;
1807 }
1808
1809
1810 if (sc->sc_running & SCP_UPDATESUBCMD)
1811 sc->sc_scheduled &= ~SCP_UPDATESUBCMD;
1812
1813 mask = SCP_FIRST;
1814 for (i = 0; i < ray_ncmdtab; mask <<= 1, i++) {
1815 if ((sc->sc_scheduled & ~SCP_UPD_MASK) == 0)
1816 break;
1817 if (!RAY_ECF_READY(sc))
1818 break;
1819 if (sc->sc_scheduled & mask)
1820 (*ray_cmdtab[i])(sc);
1821 }
1822
1823 RAY_DPRINTF((
1824 "%s: ray_check_scheduled exit sched 0x%x running 0x%x ready %d\n",
1825 sc->sc_xname, sc->sc_scheduled, sc->sc_running, RAY_ECF_READY(sc)));
1826
1827 if (sc->sc_scheduled & ~SCP_UPD_MASK)
1828 ray_set_pending(sc, sc->sc_scheduled);
1829
1830 splx(s);
1831 }
1832
1833
1834
1835
1836
1837
1838
1839
1840 void
1841 ray_check_ccs(void *arg)
1842 {
1843 ray_cmd_func_t fp;
1844 struct ray_softc *sc;
1845 u_int i, cmd, stat;
1846 bus_size_t ccs;
1847 int s;
1848
1849 s = splnet();
1850 sc = arg;
1851
1852 RAY_DPRINTF(("%s: ray_check_ccs\n", sc->sc_xname));
1853
1854 sc->sc_timocheck = 0;
1855 for (i = RAY_CCS_CMD_FIRST; i <= RAY_CCS_CMD_LAST; i++) {
1856 if (!sc->sc_ccsinuse[i])
1857 continue;
1858 ccs = RAY_GET_CCS(i);
1859 cmd = SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_cmd);
1860 switch (cmd) {
1861 case RAY_CMD_START_PARAMS:
1862 case RAY_CMD_UPDATE_MCAST:
1863 case RAY_CMD_UPDATE_PARAMS:
1864 stat = SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_status);
1865 RAY_DPRINTF(("%s: check ccs idx %d ccs 0x%lx "
1866 "cmd 0x%x stat %d\n", sc->sc_xname, i,
1867 ccs, cmd, stat));
1868 goto breakout;
1869 }
1870 }
1871 breakout:
1872
1873 if (i > RAY_CCS_CMD_LAST)
1874 ;
1875 else if (stat == RAY_CCS_STATUS_FREE) {
1876 stat = RAY_CCS_STATUS_COMPLETE;
1877 if ((fp = ray_ccs_done(sc, ccs)))
1878 (*fp)(sc);
1879 } else if (stat != RAY_CCS_STATUS_BUSY) {
1880 if (sc->sc_ccsinuse[i] == 1) {
1881
1882 sc->sc_ccsinuse[i] = 2;
1883 if (!sc->sc_timocheck) {
1884 callout_reset(&sc->sc_check_ccs_ch, 1,
1885 ray_check_ccs, sc);
1886 sc->sc_timocheck = 1;
1887 }
1888 } else if ((fp = ray_ccs_done(sc, ccs)))
1889 (*fp)(sc);
1890 } else {
1891 callout_reset(&sc->sc_check_ccs_ch, RAY_CHECK_CCS_TIMEOUT,
1892 ray_check_ccs, sc);
1893 sc->sc_timocheck = 1;
1894 }
1895 splx(s);
1896 }
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906 void
1907 ray_update_error_counters(struct ray_softc *sc)
1908 {
1909 bus_size_t csc;
1910
1911
1912 csc = RAY_STATUS_BASE;
1913 if (SRAM_READ_FIELD_1(sc, csc, ray_csc, csc_mrxo_own)) {
1914 sc->sc_rxoverflow +=
1915 SRAM_READ_FIELD_2(sc, csc, ray_csc, csc_mrx_overflow);
1916 SRAM_WRITE_FIELD_1(sc, csc, ray_csc, csc_mrxo_own, 0);
1917 }
1918 if (SRAM_READ_FIELD_1(sc, csc, ray_csc, csc_mrxc_own)) {
1919 sc->sc_rxcksum +=
1920 SRAM_READ_FIELD_2(sc, csc, ray_csc, csc_mrx_overflow);
1921 SRAM_WRITE_FIELD_1(sc, csc, ray_csc, csc_mrxc_own, 0);
1922 }
1923 if (SRAM_READ_FIELD_1(sc, csc, ray_csc, csc_rxhc_own)) {
1924 sc->sc_rxhcksum +=
1925 SRAM_READ_FIELD_2(sc, csc, ray_csc, csc_rx_hcksum);
1926 SRAM_WRITE_FIELD_1(sc, csc, ray_csc, csc_rxhc_own, 0);
1927 }
1928 sc->sc_rxnoise = SRAM_READ_FIELD_1(sc, csc, ray_csc, csc_rx_noise);
1929 }
1930
1931
1932
1933
1934 ray_cmd_func_t
1935 ray_ccs_done(struct ray_softc *sc, bus_size_t ccs)
1936 {
1937 struct ifnet *ifp;
1938 ray_cmd_func_t rcmd;
1939 u_int cmd, stat;
1940
1941 ifp = &sc->sc_if;
1942 cmd = SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_cmd);
1943 stat = SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_status);
1944
1945 RAY_DPRINTF(("%s: ray_ccs_done idx %ld cmd 0x%x stat %d\n",
1946 sc->sc_xname, RAY_GET_INDEX(ccs), cmd, stat));
1947
1948 rcmd = 0;
1949 switch (cmd) {
1950
1951
1952
1953 case RAY_CMD_START_PARAMS:
1954
1955 ray_cmd_done(sc, SCP_UPD_STARTUP);
1956
1957
1958 sc->sc_if.if_flags &= ~IFF_OACTIVE;
1959
1960 sc->sc_omode = sc->sc_mode;
1961 memcpy(&sc->sc_cnwid, &sc->sc_dnwid, sizeof(sc->sc_cnwid));
1962
1963 rcmd = ray_start_join_net;
1964 break;
1965 case RAY_CMD_UPDATE_PARAMS:
1966 rcmd = ray_update_params_done(sc, ccs, stat);
1967 break;
1968 case RAY_CMD_REPORT_PARAMS:
1969
1970 ray_cmd_done(sc, SCP_REPORTPARAMS);
1971 if (!sc->sc_repreq)
1972 break;
1973 sc->sc_repreq->r_failcause =
1974 SRAM_READ_FIELD_1(sc, ccs, ray_cmd_report, c_failcause);
1975 sc->sc_repreq->r_len =
1976 SRAM_READ_FIELD_1(sc, ccs, ray_cmd_report, c_len);
1977 ray_read_region(sc, RAY_ECF_TO_HOST_BASE, sc->sc_repreq->r_data,
1978 sc->sc_repreq->r_len);
1979 sc->sc_repreq = 0;
1980 wakeup(ray_report_params);
1981 break;
1982 case RAY_CMD_UPDATE_MCAST:
1983 ray_cmd_done(sc, SCP_UPD_MCAST);
1984 if (stat == RAY_CCS_STATUS_FAIL)
1985 rcmd = ray_reset;
1986 break;
1987 case RAY_CMD_START_NET:
1988 case RAY_CMD_JOIN_NET:
1989 rcmd = ray_start_join_net_done(sc, cmd, ccs, stat);
1990 break;
1991 case RAY_CMD_TX_REQ:
1992 if (sc->sc_if.if_flags & IFF_OACTIVE) {
1993 sc->sc_if.if_flags &= ~IFF_OACTIVE;
1994
1995 rcmd = ray_intr_start;
1996 }
1997
1998 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_status,
1999 RAY_CCS_STATUS_FREE);
2000 goto done;
2001 case RAY_CMD_START_ASSOC:
2002 ray_cmd_done(sc, SCP_STARTASSOC);
2003 if (stat == RAY_CCS_STATUS_FAIL)
2004 rcmd = ray_start_join_net;
2005 else {
2006 sc->sc_havenet = 1;
2007 rcmd = ray_intr_start;
2008 }
2009 break;
2010 case RAY_CMD_UPDATE_APM:
2011 case RAY_CMD_TEST_MEM:
2012 case RAY_CMD_SHUTDOWN:
2013 case RAY_CMD_DUMP_MEM:
2014 case RAY_CMD_START_TIMER:
2015 break;
2016 default:
2017 printf("%s: intr: unknown command 0x%x\n",
2018 sc->sc_if.if_xname, cmd);
2019 break;
2020 }
2021 ray_free_ccs(sc, ccs);
2022 done:
2023
2024
2025
2026
2027 ray_check_scheduled(sc);
2028
2029 return (rcmd);
2030 }
2031
2032
2033
2034
2035 ray_cmd_func_t
2036 ray_rccs_intr(struct ray_softc *sc, bus_size_t ccs)
2037 {
2038 ray_cmd_func_t rcmd;
2039 u_int cmd, stat;
2040
2041 cmd = SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_cmd);
2042 stat = SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_status);
2043
2044 RAY_DPRINTF(("%s: ray_rccs_intr idx %ld cmd 0x%x stat %d\n",
2045 sc->sc_xname, RAY_GET_INDEX(ccs), cmd, stat));
2046
2047 rcmd = 0;
2048 switch (cmd) {
2049
2050
2051
2052 case RAY_ECMD_RX_DONE:
2053 ray_recv(sc, ccs);
2054 goto done;
2055 case RAY_ECMD_REJOIN_DONE:
2056 if (sc->sc_mode == SC_MODE_ADHOC)
2057 break;
2058
2059 SRAM_READ_FIELD_N(sc, ccs, ray_cmd_net, c_bss_id,
2060 sc->sc_bssid, sizeof(sc->sc_bssid));
2061 rcmd = ray_start_assoc;
2062 break;
2063 case RAY_ECMD_ROAM_START:
2064
2065 sc->sc_havenet = 0;
2066 break;
2067 case RAY_ECMD_JAPAN_CALL_SIGNAL:
2068 break;
2069 default:
2070 ray_update_error_counters(sc);
2071
2072
2073 if (sc->sc_version == SC_BUILD_4 && cmd == 0x55
2074 && RAY_GET_INDEX(ccs) == 0x55) {
2075 goto done;
2076 }
2077 printf("%s: intr: unknown command 0x%x\n",
2078 sc->sc_if.if_xname, cmd);
2079 break;
2080 }
2081
2082 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_status, RAY_CCS_STATUS_FREE);
2083 done:
2084 return (rcmd);
2085 }
2086
2087
2088
2089
2090 int
2091 ray_intr(void *arg)
2092 {
2093 struct ray_softc *sc;
2094 ray_cmd_func_t rcmd;
2095 u_int i, count;
2096
2097 sc = arg;
2098
2099 RAY_DPRINTF(("%s: ray_intr\n", sc->sc_xname));
2100
2101 if ((++sc->sc_checkcounters % 32) == 0)
2102 ray_update_error_counters(sc);
2103
2104 count = 0;
2105 rcmd = 0;
2106 if (!REG_READ(sc, RAY_HCSIR))
2107 count = 0;
2108 else {
2109 count = 1;
2110 i = SRAM_READ_1(sc, RAY_SCB_RCCSI);
2111 if (i <= RAY_CCS_LAST)
2112 rcmd = ray_ccs_done(sc, RAY_GET_CCS(i));
2113 else if (i <= RAY_RCCS_LAST)
2114 rcmd = ray_rccs_intr(sc, RAY_GET_CCS(i));
2115 else
2116 printf("%s: intr: bad cmd index %d\n", sc->sc_xname, i);
2117 }
2118
2119 if (rcmd)
2120 (*rcmd)(sc);
2121
2122 if (count)
2123 REG_WRITE(sc, RAY_HCSIR, 0);
2124
2125 RAY_DPRINTF(("%s: interrupt handled %d\n", sc->sc_xname, count));
2126
2127 return (count ? 1 : 0);
2128 }
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138 void
2139 ray_free_ccs_chain(struct ray_softc *sc, u_int ni)
2140 {
2141 u_int i;
2142
2143 while ((i = ni) != RAY_CCS_LINK_NULL) {
2144 ni = SRAM_READ_FIELD_1(sc, RAY_GET_CCS(i), ray_cmd, c_link);
2145 SRAM_WRITE_FIELD_1(sc, RAY_GET_CCS(i), ray_cmd, c_status,
2146 RAY_CCS_STATUS_FREE);
2147 }
2148 }
2149
2150
2151
2152
2153
2154 u_int8_t
2155 ray_free_ccs(struct ray_softc *sc, bus_size_t ccs)
2156 {
2157 u_int8_t stat;
2158
2159 RAY_DPRINTF(("%s: free_ccs idx %ld\n", sc->sc_xname,
2160 RAY_GET_INDEX(ccs)));
2161
2162 stat = SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_status);
2163 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_status, RAY_CCS_STATUS_FREE);
2164 if (ccs <= RAY_GET_CCS(RAY_CCS_LAST))
2165 sc->sc_ccsinuse[RAY_GET_INDEX(ccs)] = 0;
2166
2167 return (stat);
2168 }
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180 int
2181 ray_alloc_ccs(struct ray_softc *sc, bus_size_t *ccsp, u_int cmd, u_int track)
2182 {
2183 bus_size_t ccs;
2184 u_int i;
2185
2186 RAY_DPRINTF(("%s: alloc_ccs cmd %d\n", sc->sc_xname, cmd));
2187
2188
2189 if (track && !RAY_ECF_READY(sc)) {
2190 ray_cmd_schedule(sc, track);
2191 return (0);
2192 }
2193
2194
2195 for (i = RAY_CCS_CMD_FIRST; i <= RAY_CCS_CMD_LAST; i++) {
2196
2197 (void)SRAM_READ_FIELD_1(sc, RAY_GET_CCS(i), ray_cmd, c_status);
2198 if (!sc->sc_ccsinuse[i])
2199 break;
2200 }
2201 if (i > RAY_CCS_CMD_LAST) {
2202 if (track)
2203 ray_cmd_schedule(sc, track);
2204 return (0);
2205 }
2206 sc->sc_ccsinuse[i] = 1;
2207 ccs = RAY_GET_CCS(i);
2208 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_status, RAY_CCS_STATUS_BUSY);
2209 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_cmd, cmd);
2210 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_link, RAY_CCS_LINK_NULL);
2211
2212 *ccsp = ccs;
2213 return (1);
2214 }
2215
2216
2217
2218
2219
2220
2221
2222 void
2223 ray_set_pending(struct ray_softc *sc, u_int cmdf)
2224 {
2225 RAY_DPRINTF(("%s: ray_set_pending 0x%x\n", sc->sc_xname, cmdf));
2226
2227 sc->sc_scheduled |= cmdf;
2228 if (!sc->sc_timoneed) {
2229 RAY_DPRINTF(("%s: ray_set_pending new timo\n", sc->sc_xname));
2230 callout_reset(&sc->sc_check_scheduled_ch,
2231 RAY_CHECK_SCHED_TIMEOUT, ray_check_scheduled, sc);
2232 sc->sc_timoneed = 1;
2233 }
2234 }
2235
2236
2237
2238
2239 void
2240 ray_cmd_schedule(struct ray_softc *sc, int cmdf)
2241 {
2242 int track;
2243
2244 RAY_DPRINTF(("%s: ray_cmd_schedule 0x%x\n", sc->sc_xname, cmdf));
2245
2246 track = cmdf;
2247 if ((cmdf & SCP_UPD_MASK) == 0)
2248 ray_set_pending(sc, track);
2249 else if (ray_cmd_is_running(sc, SCP_UPDATESUBCMD)) {
2250
2251 sc->sc_scheduled |= cmdf;
2252 } else
2253 ray_set_pending(sc, cmdf | SCP_UPDATESUBCMD);
2254 }
2255
2256
2257
2258
2259 int
2260 ray_cmd_is_scheduled(struct ray_softc *sc, int cmdf)
2261 {
2262 RAY_DPRINTF(("%s: ray_cmd_is_scheduled 0x%x\n", sc->sc_xname, cmdf));
2263
2264 return ((sc->sc_scheduled & cmdf) ? 1 : 0);
2265 }
2266
2267
2268
2269
2270 void
2271 ray_cmd_cancel(struct ray_softc *sc, int cmdf)
2272 {
2273 RAY_DPRINTF(("%s: ray_cmd_cancel 0x%x\n", sc->sc_xname, cmdf));
2274
2275 sc->sc_scheduled &= ~cmdf;
2276 if ((cmdf & SCP_UPD_MASK) && (sc->sc_scheduled & SCP_UPD_MASK) == 0)
2277 sc->sc_scheduled &= ~SCP_UPDATESUBCMD;
2278
2279
2280 if (sc->sc_scheduled == 0 && sc->sc_timoneed) {
2281 callout_stop(&sc->sc_check_scheduled_ch);
2282 sc->sc_timoneed = 0;
2283 }
2284 }
2285
2286
2287
2288
2289 void
2290 ray_cmd_ran(struct ray_softc *sc, int cmdf)
2291 {
2292 RAY_DPRINTF(("%s: ray_cmd_ran 0x%x\n", sc->sc_xname, cmdf));
2293
2294 if (cmdf & SCP_UPD_MASK)
2295 sc->sc_running |= cmdf | SCP_UPDATESUBCMD;
2296 else
2297 sc->sc_running |= cmdf;
2298
2299 if ((cmdf & SCP_TIMOCHECK_CMD_MASK) && !sc->sc_timocheck) {
2300 callout_reset(&sc->sc_check_ccs_ch, RAY_CHECK_CCS_TIMEOUT,
2301 ray_check_ccs, sc);
2302 sc->sc_timocheck = 1;
2303 }
2304 }
2305
2306
2307
2308
2309 int
2310 ray_cmd_is_running(struct ray_softc *sc, int cmdf)
2311 {
2312 RAY_DPRINTF(("%s: ray_cmd_is_running 0x%x\n", sc->sc_xname, cmdf));
2313
2314 return ((sc->sc_running & cmdf) ? 1 : 0);
2315 }
2316
2317
2318
2319
2320 void
2321 ray_cmd_done(struct ray_softc *sc, int cmdf)
2322 {
2323 RAY_DPRINTF(("%s: ray_cmd_done 0x%x\n", sc->sc_xname, cmdf));
2324
2325 sc->sc_running &= ~cmdf;
2326 if (cmdf & SCP_UPD_MASK) {
2327 sc->sc_running &= ~SCP_UPDATESUBCMD;
2328 if (sc->sc_scheduled & SCP_UPD_MASK)
2329 ray_cmd_schedule(sc, sc->sc_scheduled & SCP_UPD_MASK);
2330 }
2331 if ((sc->sc_running & SCP_TIMOCHECK_CMD_MASK) == 0 && sc->sc_timocheck){
2332 callout_stop(&sc->sc_check_ccs_ch);
2333 sc->sc_timocheck = 0;
2334 }
2335 }
2336
2337
2338
2339
2340
2341 int
2342 ray_issue_cmd(struct ray_softc *sc, bus_size_t ccs, u_int track)
2343 {
2344 u_int i;
2345
2346 RAY_DPRINTF(("%s: ray_cmd_issue 0x%x\n", sc->sc_xname, track));
2347
2348
2349
2350
2351
2352
2353 i = 0;
2354 while (!RAY_ECF_READY(sc))
2355 if (++i > 50) {
2356 ray_free_ccs(sc, ccs);
2357 if (track)
2358 ray_cmd_schedule(sc, track);
2359 return (0);
2360 }
2361
2362 SRAM_WRITE_1(sc, RAY_SCB_CCSI, RAY_GET_INDEX(ccs));
2363 RAY_ECF_START_CMD(sc);
2364 ray_cmd_ran(sc, track);
2365
2366 return (1);
2367 }
2368
2369
2370
2371
2372 int
2373 ray_simple_cmd(struct ray_softc *sc, u_int cmd, u_int track)
2374 {
2375 bus_size_t ccs;
2376
2377 return (ray_alloc_ccs(sc, &ccs, cmd, track) &&
2378 ray_issue_cmd(sc, ccs, track));
2379 }
2380
2381
2382
2383
2384
2385
2386
2387
2388 void
2389 ray_update_subcmd(struct ray_softc *sc)
2390 {
2391 int submask, i;
2392
2393 RAY_DPRINTF(("%s: ray_update_subcmd\n", sc->sc_xname));
2394
2395 ray_cmd_cancel(sc, SCP_UPDATESUBCMD);
2396 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
2397 return;
2398 submask = SCP_UPD_FIRST;
2399 for (i = 0; i < ray_nsubcmdtab; submask <<= 1, i++) {
2400 if ((sc->sc_scheduled & SCP_UPD_MASK) == 0)
2401 break;
2402
2403 if (ray_cmd_is_running(sc, SCP_UPDATESUBCMD))
2404 break;
2405 if (!RAY_ECF_READY(sc))
2406 break;
2407
2408
2409
2410
2411
2412 if (sc->sc_scheduled & ((submask - 1) & SCP_UPD_MASK))
2413 break;
2414 if (sc->sc_scheduled & submask)
2415 (*ray_subcmdtab[i])(sc);
2416 }
2417 }
2418
2419
2420
2421
2422 void
2423 ray_report_params(struct ray_softc *sc)
2424 {
2425 bus_size_t ccs;
2426
2427 ray_cmd_cancel(sc, SCP_REPORTPARAMS);
2428
2429 if (!sc->sc_repreq)
2430 return;
2431
2432
2433 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
2434 return;
2435 else if (ray_cmd_is_running(sc, SCP_REPORTPARAMS)) {
2436 ray_cmd_schedule(sc, SCP_REPORTPARAMS);
2437 return;
2438 } else if (!ray_alloc_ccs(sc, &ccs, RAY_CMD_REPORT_PARAMS,
2439 SCP_REPORTPARAMS))
2440 return;
2441
2442 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_report, c_paramid,
2443 sc->sc_repreq->r_paramid);
2444 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_report, c_nparam, 1);
2445 (void)ray_issue_cmd(sc, ccs, SCP_REPORTPARAMS);
2446 }
2447
2448
2449
2450
2451 void
2452 ray_start_assoc(struct ray_softc *sc)
2453 {
2454 ray_cmd_cancel(sc, SCP_STARTASSOC);
2455 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
2456 return;
2457 else if (ray_cmd_is_running(sc, SCP_STARTASSOC))
2458 return;
2459 (void)ray_simple_cmd(sc, RAY_CMD_START_ASSOC, SCP_STARTASSOC);
2460 }
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471 void
2472 ray_download_params(struct ray_softc *sc)
2473 {
2474 struct ray_startup_params_head *sp;
2475 struct ray_startup_params_tail_5 *sp5;
2476 struct ray_startup_params_tail_4 *sp4;
2477 bus_size_t off;
2478
2479 RAY_DPRINTF(("%s: init_startup_params\n", sc->sc_xname));
2480
2481 ray_cmd_cancel(sc, SCP_UPD_STARTUP);
2482
2483 #define PUT2(p, v) \
2484 do { (p)[0] = ((v >> 8) & 0xff); (p)[1] = (v & 0xff); } while(0)
2485
2486 sp = &sc->sc_startup;
2487 sp4 = &sc->sc_startup_4;
2488 sp5 = &sc->sc_startup_5;
2489 memset(sp, 0, sizeof(*sp));
2490 if (sc->sc_version == SC_BUILD_4)
2491 memset(sp4, 0, sizeof(*sp4));
2492 else
2493 memset(sp5, 0, sizeof(*sp5));
2494
2495 memcpy(sp->sp_ssid, sc->sc_dnwid.i_nwid, sizeof(sp->sp_ssid));
2496 sp->sp_scan_mode = 0x1;
2497 memcpy(sp->sp_mac_addr, sc->sc_ecf_startup.e_station_addr,
2498 ETHER_ADDR_LEN);
2499 PUT2(sp->sp_frag_thresh, 0x7fff);
2500 if (sc->sc_version == SC_BUILD_4) {
2501 #if 1
2502
2503 PUT2(sp->sp_dwell_time, 0x200);
2504 PUT2(sp->sp_beacon_period, 1);
2505 #else
2506
2507 PUT2(sp->sp_dwell_time, 0x400);
2508 PUT2(sp->sp_beacon_period, 0);
2509 #endif
2510 } else {
2511 PUT2(sp->sp_dwell_time, 128);
2512 PUT2(sp->sp_beacon_period, 256);
2513 }
2514 sp->sp_dtim_interval = 1;
2515 #if 0
2516
2517 sp->sp_max_retry = 0x1f;
2518 sp->sp_ack_timo = 0x86;
2519 sp->sp_sifs = 0x1c;
2520 #elif 1
2521
2522 sp->sp_max_retry = 0x07;
2523
2524 sp->sp_ack_timo = 0xa3;
2525 sp->sp_sifs = 0x1d;
2526 #else
2527
2528 sp->sp_max_retry = 0x03;
2529
2530 sp->sp_ack_timo = 0xa3;
2531 sp->sp_sifs = 0x1d;
2532 #endif
2533 #if 0
2534
2535 sp->sp_difs = 0x82;
2536 sp->sp_pifs = 0;
2537 #else
2538
2539 sp->sp_difs = 0x82;
2540
2541 if (sc->sc_version == SC_BUILD_4)
2542 sp->sp_pifs = 0xce;
2543 else
2544 sp->sp_pifs = 0x4e;
2545 #endif
2546
2547 PUT2(sp->sp_rts_thresh, 0x7fff);
2548 if (sc->sc_version == SC_BUILD_4) {
2549 PUT2(sp->sp_scan_dwell, 0xfb1e);
2550 PUT2(sp->sp_scan_max_dwell, 0xc75c);
2551 } else {
2552 PUT2(sp->sp_scan_dwell, 0x4e2);
2553 PUT2(sp->sp_scan_max_dwell, 0x38a4);
2554 }
2555 sp->sp_assoc_timo = 0x5;
2556 if (sc->sc_version == SC_BUILD_4) {
2557 #if 1
2558
2559 sp->sp_adhoc_scan_cycle = 0x4;
2560 sp->sp_infra_scan_cycle = 0x2;
2561 sp->sp_infra_super_scan_cycle = 0x4;
2562 #else
2563
2564 sp->sp_adhoc_scan_cycle = 0x8;
2565 sp->sp_infra_scan_cycle = 0x1;
2566 sp->sp_infra_super_scan_cycle = 0x18;
2567 #endif
2568 } else {
2569 sp->sp_adhoc_scan_cycle = 0x8;
2570 sp->sp_infra_scan_cycle = 0x2;
2571 sp->sp_infra_super_scan_cycle = 0x8;
2572 }
2573 sp->sp_promisc = sc->sc_promisc;
2574 PUT2(sp->sp_uniq_word, 0x0cbd);
2575 if (sc->sc_version == SC_BUILD_4) {
2576
2577
2578 sp->sp_slot_time = 0x4e;
2579 #if 1
2580
2581 sp->sp_roam_low_snr_thresh = 0xff;
2582 #else
2583
2584 sp->sp_roam_low_snr_thresh = 0x30;
2585 #endif
2586 } else {
2587 sp->sp_slot_time = 0x32;
2588 sp->sp_roam_low_snr_thresh = 0xff;
2589 }
2590 #if 1
2591 sp->sp_low_snr_count = 0xff;
2592 #else
2593
2594 sp->sp_low_snr_count = 0x07;
2595 #endif
2596 #if 0
2597 sp->sp_infra_missed_beacon_count = 0x2;
2598 #elif 1
2599
2600 sp->sp_infra_missed_beacon_count = 0x5;
2601 #else
2602
2603 sp->sp_infra_missed_beacon_count = 0x7;
2604 #endif
2605 sp->sp_adhoc_missed_beacon_count = 0xff;
2606 sp->sp_country_code = sc->sc_dcountrycode;
2607 sp->sp_hop_seq = 0x0b;
2608 if (sc->sc_version == SC_BUILD_4) {
2609 sp->sp_hop_seq_len = 0x4e;
2610 sp4->sp_cw_max = 0x3f;
2611 sp4->sp_cw_min = 0x0f;
2612 sp4->sp_noise_filter_gain = 0x4;
2613 sp4->sp_noise_limit_offset = 0x8;
2614 sp4->sp_rssi_thresh_offset = 0x28;
2615 sp4->sp_busy_thresh_offset = 0x28;
2616 sp4->sp_sync_thresh = 0x07;
2617 sp4->sp_test_mode = 0x0;
2618 sp4->sp_test_min_chan = 0x2;
2619 sp4->sp_test_max_chan = 0x2;
2620 } else {
2621 sp->sp_hop_seq_len = 0x4f;
2622 PUT2(sp5->sp_cw_max, 0x3f);
2623 PUT2(sp5->sp_cw_min, 0x0f);
2624 sp5->sp_noise_filter_gain = 0x4;
2625 sp5->sp_noise_limit_offset = 0x8;
2626 sp5->sp_rssi_thresh_offset = 0x28;
2627 sp5->sp_busy_thresh_offset = 0x28;
2628 sp5->sp_sync_thresh = 0x07;
2629 sp5->sp_test_mode = 0x0;
2630 sp5->sp_test_min_chan = 0x2;
2631 sp5->sp_test_max_chan = 0x2;
2632 #if 0
2633 sp5->sp_allow_probe_resp = 0x1;
2634 #else
2635 sp5->sp_allow_probe_resp = 0x0;
2636 #endif
2637 sp5->sp_privacy_must_start = 0x0;
2638 sp5->sp_privacy_can_join = 0x0;
2639 sp5->sp_basic_rate_set[0] = 0x2;
2640
2641 }
2642
2643
2644 if (!RAY_ECF_READY(sc))
2645 panic("ray_download_params busy");
2646
2647
2648 off = RAY_HOST_TO_ECF_BASE;
2649 ray_write_region(sc, off, sp, sizeof(sc->sc_startup));
2650 off += sizeof(sc->sc_startup);
2651 if (sc->sc_version == SC_BUILD_4)
2652 ray_write_region(sc, off, sp4, sizeof(*sp4));
2653 else
2654 ray_write_region(sc, off, sp5, sizeof(*sp5));
2655 if (!ray_simple_cmd(sc, RAY_CMD_START_PARAMS, SCP_UPD_STARTUP))
2656 panic("ray_download_params issue");
2657 }
2658
2659
2660
2661
2662 void
2663 ray_start_join_net(struct ray_softc *sc)
2664 {
2665 struct ray_net_params np;
2666 bus_size_t ccs;
2667 int cmd;
2668
2669 ray_cmd_cancel(sc, SCP_UPD_STARTJOIN);
2670 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
2671 return;
2672
2673
2674 if (ray_cmd_is_running(sc, SCP_UPDATESUBCMD)) {
2675 ray_cmd_schedule(sc, SCP_UPD_STARTJOIN);
2676 return;
2677 }
2678
2679 if (sc->sc_mode == SC_MODE_ADHOC)
2680 cmd = RAY_CMD_START_NET;
2681 else
2682 cmd = RAY_CMD_JOIN_NET;
2683
2684 if (!ray_alloc_ccs(sc, &ccs, cmd, SCP_UPD_STARTJOIN))
2685 return;
2686 sc->sc_startccs = ccs;
2687 sc->sc_startcmd = cmd;
2688 if (!memcmp(&sc->sc_cnwid, &sc->sc_dnwid, sizeof(sc->sc_cnwid))
2689 && sc->sc_omode == sc->sc_mode)
2690 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_net, c_upd_param, 0);
2691 else {
2692 sc->sc_havenet = 0;
2693 memset(&np, 0, sizeof(np));
2694 np.p_net_type = sc->sc_mode;
2695 memcpy(np.p_ssid, sc->sc_dnwid.i_nwid, sizeof(np.p_ssid));
2696 ray_write_region(sc, RAY_HOST_TO_ECF_BASE, &np, sizeof(np));
2697 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_net, c_upd_param, 1);
2698 }
2699 if (ray_issue_cmd(sc, ccs, SCP_UPD_STARTJOIN))
2700 callout_reset(&sc->sc_start_join_timo_ch, RAY_START_TIMEOUT,
2701 ray_start_join_timo, sc);
2702 }
2703
2704 void
2705 ray_start_join_timo(void *arg)
2706 {
2707 struct ray_softc *sc;
2708 u_int stat;
2709
2710 sc = arg;
2711 stat = SRAM_READ_FIELD_1(sc, sc->sc_startccs, ray_cmd, c_status);
2712 ray_start_join_net_done(sc, sc->sc_startcmd, sc->sc_startccs, stat);
2713 }
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723 ray_cmd_func_t
2724 ray_start_join_net_done(struct ray_softc *sc, u_int cmd, bus_size_t ccs, u_int stat)
2725 {
2726 int i;
2727 struct ray_net_params np;
2728
2729 callout_stop(&sc->sc_start_join_timo_ch);
2730 ray_cmd_done(sc, SCP_UPD_STARTJOIN);
2731
2732 if (stat == RAY_CCS_STATUS_FAIL) {
2733
2734 sc->sc_havenet = 0;
2735 return (ray_start_join_net);
2736 }
2737 if (stat == RAY_CCS_STATUS_BUSY || stat == RAY_CCS_STATUS_FREE) {
2738
2739 callout_reset(&sc->sc_start_join_timo_ch, RAY_START_TIMEOUT,
2740 ray_start_join_timo, sc);
2741
2742
2743 if (!RAY_ECF_READY(sc))
2744 return (0);
2745
2746
2747 if (!memcmp(&sc->sc_cnwid, &sc->sc_dnwid, sizeof(sc->sc_cnwid))
2748 && sc->sc_omode == sc->sc_mode)
2749 SRAM_WRITE_FIELD_1(sc,ccs, ray_cmd_net, c_upd_param, 0);
2750 else {
2751 memset(&np, 0, sizeof(np));
2752 np.p_net_type = sc->sc_mode;
2753 memcpy(np.p_ssid, sc->sc_dnwid.i_nwid,
2754 sizeof(np.p_ssid));
2755 ray_write_region(sc, RAY_HOST_TO_ECF_BASE, &np,
2756 sizeof(np));
2757 SRAM_WRITE_FIELD_1(sc,ccs, ray_cmd_net, c_upd_param, 1);
2758 }
2759
2760 if (sc->sc_mode == SC_MODE_ADHOC)
2761 cmd = RAY_CMD_START_NET;
2762 else
2763 cmd = RAY_CMD_JOIN_NET;
2764 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_net, c_cmd,
2765 RAY_CCS_STATUS_BUSY);
2766 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_net, c_status,
2767 RAY_CCS_STATUS_BUSY);
2768
2769
2770 SRAM_WRITE_1(sc, RAY_SCB_CCSI, RAY_GET_INDEX(ccs));
2771 RAY_ECF_START_CMD(sc);
2772 ray_cmd_ran(sc, SCP_UPD_STARTJOIN);
2773 return (0);
2774 }
2775
2776 SRAM_READ_FIELD_N(sc, ccs, ray_cmd_net, c_bss_id, sc->sc_bssid,
2777 sizeof(sc->sc_bssid));
2778
2779 sc->sc_deftxrate = SRAM_READ_FIELD_1(sc, ccs, ray_cmd_net,c_def_txrate);
2780 sc->sc_encrypt = SRAM_READ_FIELD_1(sc, ccs, ray_cmd_net, c_encrypt);
2781
2782
2783 if (sc->sc_deftxrate == 0x55)
2784 sc->sc_deftxrate = RAY_PID_BASIC_RATE_1500K;
2785 if (sc->sc_encrypt == 0x55)
2786 sc->sc_encrypt = 0;
2787
2788 if (SRAM_READ_FIELD_1(sc, ccs, ray_cmd_net, c_upd_param)) {
2789 ray_read_region(sc, RAY_HOST_TO_ECF_BASE, &np, sizeof(np));
2790
2791 for (i = 0; i < sizeof(np.p_ssid); i++) {
2792 if (np.p_ssid[i] == '\0')
2793 break;
2794 }
2795 sc->sc_cnwid.i_len = i;
2796 memcpy(sc->sc_cnwid.i_nwid, np.p_ssid, sizeof(sc->sc_cnwid));
2797 sc->sc_omode = sc->sc_mode;
2798 if (np.p_net_type != sc->sc_mode)
2799 return (ray_start_join_net);
2800 }
2801 RAY_DPRINTF(("%s: net start/join nwid %.32s bssid %s inited %d\n",
2802 sc->sc_xname, sc->sc_cnwid.i_nwid, ether_sprintf(sc->sc_bssid),
2803 SRAM_READ_FIELD_1(sc, ccs, ray_cmd_net, c_inited)));
2804
2805
2806 ray_cmd_schedule(sc, SCP_UPD_MCAST|SCP_UPD_PROMISC);
2807 if (cmd == RAY_CMD_JOIN_NET)
2808 return (ray_start_assoc);
2809 else {
2810 sc->sc_havenet = 1;
2811 return (ray_intr_start);
2812 }
2813 }
2814
2815
2816
2817
2818 void
2819 ray_update_promisc(struct ray_softc *sc)
2820 {
2821 bus_size_t ccs;
2822 int promisc;
2823
2824 ray_cmd_cancel(sc, SCP_UPD_PROMISC);
2825
2826
2827 promisc = !!(sc->sc_if.if_flags & (IFF_PROMISC | IFF_ALLMULTI));
2828 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
2829 return;
2830 else if (ray_cmd_is_running(sc, SCP_UPDATESUBCMD)) {
2831 ray_cmd_schedule(sc, SCP_UPD_PROMISC);
2832 return;
2833 } else if (promisc == sc->sc_promisc)
2834 return;
2835 else if (!ray_alloc_ccs(sc,&ccs,RAY_CMD_UPDATE_PARAMS, SCP_UPD_PROMISC))
2836 return;
2837 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_update, c_paramid, RAY_PID_PROMISC);
2838 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_update, c_nparam, 1);
2839 SRAM_WRITE_1(sc, RAY_HOST_TO_ECF_BASE, promisc);
2840 (void)ray_issue_cmd(sc, ccs, SCP_UPD_PROMISC);
2841 }
2842
2843
2844
2845
2846 void
2847 ray_update_params(struct ray_softc *sc)
2848 {
2849 bus_size_t ccs;
2850
2851 ray_cmd_cancel(sc, SCP_UPD_UPDATEPARAMS);
2852 if (!sc->sc_updreq) {
2853
2854 return;
2855 }
2856
2857
2858 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
2859 return;
2860 else if (ray_cmd_is_running(sc, SCP_UPDATESUBCMD)) {
2861 ray_cmd_schedule(sc, SCP_UPD_UPDATEPARAMS);
2862 return;
2863 } else if (!ray_alloc_ccs(sc, &ccs, RAY_CMD_UPDATE_PARAMS,
2864 SCP_UPD_UPDATEPARAMS))
2865 return;
2866
2867 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_update, c_paramid,
2868 sc->sc_updreq->r_paramid);
2869 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_update, c_nparam, 1);
2870 ray_write_region(sc, RAY_HOST_TO_ECF_BASE, sc->sc_updreq->r_data,
2871 sc->sc_updreq->r_len);
2872
2873 (void)ray_issue_cmd(sc, ccs, SCP_UPD_UPDATEPARAMS);
2874 }
2875
2876
2877
2878
2879 void
2880 ray_update_mcast(struct ray_softc *sc)
2881 {
2882 bus_size_t ccs;
2883 struct ether_multistep step;
2884 struct ether_multi *enm;
2885 struct arpcom *ec;
2886 bus_size_t bufp;
2887 int count;
2888
2889 ec = &sc->sc_ec;
2890 ray_cmd_cancel(sc, SCP_UPD_MCAST);
2891
2892
2893 if ((count = sc->sc_ec.ec_multicnt) < 17) {
2894 ETHER_FIRST_MULTI(step, ec, enm);
2895 while (enm) {
2896
2897 if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
2898 ETHER_ADDR_LEN)) {
2899 count = 17;
2900 break;
2901 }
2902 ETHER_NEXT_MULTI(step, enm);
2903 }
2904 }
2905
2906
2907 if (count > 16) {
2908 sc->sc_if.if_flags |= IFF_ALLMULTI;
2909 ray_update_promisc(sc);
2910 return;
2911 } else if (sc->sc_if.if_flags & IFF_ALLMULTI) {
2912 sc->sc_if.if_flags &= ~IFF_ALLMULTI;
2913 ray_update_promisc(sc);
2914 }
2915
2916 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
2917 return;
2918 else if (ray_cmd_is_running(sc, SCP_UPDATESUBCMD)) {
2919 ray_cmd_schedule(sc, SCP_UPD_MCAST);
2920 return;
2921 } else if (!ray_alloc_ccs(sc,&ccs, RAY_CMD_UPDATE_MCAST, SCP_UPD_MCAST))
2922 return;
2923 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_update_mcast, c_nmcast, count);
2924 bufp = RAY_HOST_TO_ECF_BASE;
2925 ETHER_FIRST_MULTI(step, ec, enm);
2926 while (enm) {
2927 ray_write_region(sc, bufp, enm->enm_addrlo, ETHER_ADDR_LEN);
2928 bufp += ETHER_ADDR_LEN;
2929 ETHER_NEXT_MULTI(step, enm);
2930 }
2931 (void)ray_issue_cmd(sc, ccs, SCP_UPD_MCAST);
2932 }
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943 int
2944 ray_user_update_params(struct ray_softc *sc, struct ray_param_req *pr)
2945 {
2946 int rv;
2947
2948 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) {
2949 pr->r_failcause = RAY_FAILCAUSE_EDEVSTOP;
2950 return (EIO);
2951 }
2952
2953
2954 rv = 0;
2955 while (ray_cmd_is_running(sc, SCP_UPD_UPDATEPARAMS) ||
2956 ray_cmd_is_scheduled(sc, SCP_UPD_UPDATEPARAMS)) {
2957 rv = tsleep(ray_update_params, 0|PCATCH, "cmd in use", 0);
2958 if (rv)
2959 return (rv);
2960 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) {
2961 pr->r_failcause = RAY_FAILCAUSE_EDEVSTOP;
2962 return (EIO);
2963 }
2964 }
2965
2966 pr->r_failcause = RAY_FAILCAUSE_WAITING;
2967 sc->sc_updreq = pr;
2968 ray_cmd_schedule(sc, SCP_UPD_UPDATEPARAMS);
2969 ray_check_scheduled(sc);
2970
2971 while (pr->r_failcause == RAY_FAILCAUSE_WAITING)
2972 (void)tsleep(ray_update_params, 0, "waiting cmd", 0);
2973 wakeup(ray_update_params);
2974
2975 return (0);
2976 }
2977
2978
2979
2980
2981
2982
2983 int
2984 ray_user_report_params(struct ray_softc *sc, struct ray_param_req *pr)
2985 {
2986 int rv;
2987
2988 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) {
2989 pr->r_failcause = RAY_FAILCAUSE_EDEVSTOP;
2990 return (EIO);
2991 }
2992
2993
2994 rv = 0;
2995 while (ray_cmd_is_running(sc, SCP_REPORTPARAMS)
2996 || ray_cmd_is_scheduled(sc, SCP_REPORTPARAMS)) {
2997 rv = tsleep(ray_report_params, 0|PCATCH, "cmd in use", 0);
2998 if (rv)
2999 return (rv);
3000 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) {
3001 pr->r_failcause = RAY_FAILCAUSE_EDEVSTOP;
3002 return (EIO);
3003 }
3004 }
3005
3006 pr->r_failcause = RAY_FAILCAUSE_WAITING;
3007 sc->sc_repreq = pr;
3008 ray_cmd_schedule(sc, SCP_REPORTPARAMS);
3009 ray_check_scheduled(sc);
3010
3011 while (pr->r_failcause == RAY_FAILCAUSE_WAITING)
3012 (void)tsleep(ray_report_params, 0, "waiting cmd", 0);
3013 wakeup(ray_report_params);
3014
3015 return (0);
3016 }
3017
3018
3019
3020
3021
3022
3023
3024 #ifndef ray_read_region
3025 void
3026 ray_read_region(struct ray_softc *sc, bus_size_t off, void *vp, size_t c)
3027 {
3028 #ifdef RAY_USE_OPTIMIZED_COPY
3029 u_int n2, n4, tmp;
3030 u_int8_t *p;
3031
3032 p = vp;
3033
3034
3035 switch ((off|(bus_addr_t)p) & 0x03) {
3036 case 0:
3037 if ((n4 = c / 4)) {
3038 bus_space_read_region_4(sc->sc_memt, sc->sc_memh, off,
3039 p, n4);
3040 tmp = c & ~0x3;
3041 c &= 0x3;
3042 p += tmp;
3043 off += tmp;
3044 }
3045 switch (c) {
3046 case 3:
3047 *p = bus_space_read_1(sc->sc_memt,sc->sc_memh, off);
3048 p++, off++;
3049 case 2:
3050 *p = bus_space_read_1(sc->sc_memt,sc->sc_memh, off);
3051 p++, off++;
3052 case 1:
3053 *p = bus_space_read_1(sc->sc_memt,sc->sc_memh, off);
3054 }
3055 break;
3056 case 2:
3057 if ((n2 = (c >> 1)))
3058 bus_space_read_region_2(sc->sc_memt, sc->sc_memh, off,
3059 p, n2);
3060 if (c & 1) {
3061 c &= ~0x1;
3062 *(p + c) = bus_space_read_1(sc->sc_memt, sc->sc_memh,
3063 off + c);
3064 }
3065 break;
3066 case 1:
3067 case 3:
3068 bus_space_read_region_1(sc->sc_memt, sc->sc_memh, off, p, c);
3069 break;
3070 }
3071 #else
3072 bus_space_read_region_1(sc->sc_memt, sc->sc_memh, off, vp, c);
3073 #endif
3074 }
3075 #endif
3076
3077 #ifndef ray_write_region
3078
3079
3080
3081
3082
3083 void
3084 ray_write_region(struct ray_softc *sc, bus_size_t off, void *vp, size_t c)
3085 {
3086 #ifdef RAY_USE_OPTIMIZED_COPY
3087 size_t n2, n4, tmp;
3088 u_int8_t *p;
3089
3090 p = vp;
3091
3092 switch ((off|(bus_addr_t)p) & 0x03) {
3093 case 0:
3094 if ((n4 = (c >> 2))) {
3095 bus_space_write_region_4(sc->sc_memt, sc->sc_memh, off,
3096 p, n4);
3097 tmp = c & ~0x3;
3098 c &= 0x3;
3099 p += tmp;
3100 off += tmp;
3101 }
3102 switch (c) {
3103 case 3:
3104 bus_space_write_1(sc->sc_memt,sc->sc_memh, off, *p);
3105 p++, off++;
3106 case 2:
3107 bus_space_write_1(sc->sc_memt,sc->sc_memh, off, *p);
3108 p++, off++;
3109 case 1:
3110 bus_space_write_1(sc->sc_memt,sc->sc_memh, off, *p);
3111 }
3112 break;
3113 case 2:
3114 if ((n2 = (c >> 1)))
3115 bus_space_write_region_2(sc->sc_memt, sc->sc_memh, off,
3116 p, n2);
3117 if (c & 0x1) {
3118 c &= ~0x1;
3119 bus_space_write_1(sc->sc_memt, sc->sc_memh,
3120 off + c, *(p + c));
3121 }
3122 break;
3123 case 1:
3124 case 3:
3125 bus_space_write_region_1(sc->sc_memt, sc->sc_memh, off, p, c);
3126 break;
3127 }
3128 #else
3129 bus_space_write_region_1(sc->sc_memt, sc->sc_memh, off, vp, c);
3130 #endif
3131 }
3132 #endif
3133
3134 #ifdef RAY_DEBUG
3135
3136 #define PRINTABLE(c) ((c) >= 0x20 && (c) <= 0x7f)
3137
3138 void
3139 hexdump(const u_int8_t *d, int len, int br, int div, int fl)
3140 {
3141 int i, j, offw, first, tlen, ni, nj, sp;
3142
3143 sp = br / div;
3144 offw = 0;
3145 if (len && (fl & HEXDF_NOOFFSET) == 0) {
3146 tlen = len;
3147 do {
3148 offw++;
3149 } while (tlen /= br);
3150 }
3151 if (offw)
3152 printf("%0*x: ", offw, 0);
3153 for (i = 0; i < len; i++, d++) {
3154 if (i && (i % br) == 0) {
3155 if ((fl & HEXDF_NOASCII) == 0) {
3156 printf(" ");
3157 d -= br;
3158 for (j = 0; j < br; d++, j++) {
3159 if (j && (j % sp) == 0)
3160 printf(" ");
3161 if (PRINTABLE(*d))
3162 printf("%c", (int)*d);
3163 else
3164 printf(".");
3165 }
3166 }
3167 if (offw)
3168 printf("\n%0*x: ", offw, i);
3169 else
3170 printf("\n");
3171 if ((fl & HEXDF_NOCOMPRESS) == 0) {
3172 first = 1;
3173 while (len - i >= br) {
3174 if (memcmp(d, d - br, br))
3175 break;
3176 d += br;
3177 i += br;
3178 if (first) {
3179 printf("*");
3180 first = 0;
3181 }
3182 }
3183 if (len == i) {
3184 printf("\n%0*x", offw, i);
3185 return;
3186 }
3187 }
3188 } else if (i && (i % sp) == 0)
3189 printf(" ");
3190 printf("%02x ", *d);
3191 }
3192 if (len && (((i - 1) % br) || i == 1)) {
3193 if ((fl & HEXDF_NOASCII) == 0) {
3194 i = i % br ? i % br : br;
3195 ni = (br - i) % br;
3196 j = (i - 1) / sp;
3197 nj = (div - j - 1) % div;
3198 j = 3 * ni + nj + 3;
3199 printf("%*s", j, "");
3200 d -= i;
3201 for (j = 0; j < i; d++, j++) {
3202 if (j && (j % sp) == 0)
3203 printf(" ");
3204 if (PRINTABLE(*d))
3205 printf("%c", (int)*d);
3206 else
3207 printf(".");
3208 }
3209 }
3210 printf("\n");
3211 }
3212 }
3213
3214
3215
3216 void
3217 ray_dump_mbuf(struct ray_softc *sc, struct mbuf *m)
3218 {
3219 u_int8_t *d, *ed;
3220 u_int i;
3221
3222 printf("%s: pkt dump:", sc->sc_xname);
3223 i = 0;
3224 for (; m; m = m->m_next) {
3225 d = mtod(m, u_int8_t *);
3226 ed = d + m->m_len;
3227
3228 for (; d < ed; i++, d++) {
3229 if ((i % 16) == 0)
3230 printf("\n\t");
3231 else if ((i % 8) == 0)
3232 printf(" ");
3233 printf(" %02x", *d);
3234 }
3235 }
3236 if ((i - 1) % 16)
3237 printf("\n");
3238 }
3239 #endif
3240
3241 #ifdef RAY_DO_SIGLEV
3242 void
3243 ray_update_siglev(struct ray_softc *sc, u_int8_t *src, u_int8_t siglev)
3244 {
3245 int i, mini;
3246 struct timeval mint;
3247 struct ray_siglev *sl;
3248
3249
3250 for (i = 0; i < RAY_NSIGLEVRECS; i++) {
3251 sl = &sc->sc_siglevs[i];
3252 if (memcmp(sl->rsl_host, src, ETHER_ADDR_LEN) == 0)
3253 goto found;
3254 }
3255
3256 mini = 0;
3257 mint.tv_sec = LONG_MAX;
3258 mint.tv_usec = 0;
3259 for (i = 0; i < RAY_NSIGLEVRECS; i++) {
3260 sl = &sc->sc_siglevs[i];
3261 if (timercmp(&sl->rsl_time, &mint, <)) {
3262 mini = i;
3263 mint = sl->rsl_time;
3264 }
3265 }
3266 sl = &sc->sc_siglevs[mini];
3267 memset(sl->rsl_siglevs, 0, RAY_NSIGLEV);
3268 memcpy(sl->rsl_host, src, ETHER_ADDR_LEN);
3269
3270 found:
3271 microtime(&sl->rsl_time);
3272 memmove(&sl->rsl_siglevs[1], sl->rsl_siglevs, RAY_NSIGLEV-1);
3273 sl->rsl_siglevs[0] = siglev;
3274 }
3275 #endif