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