rtw.c revision 1.24
1/* $NetBSD: rtw.c,v 1.24 2004/12/26 22:59:41 dyoung Exp $ */
2/*-
3 * Copyright (c) 2004, 2005 David Young.  All rights reserved.
4 *
5 * Programmed for NetBSD by David Young.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. The name of David Young may not be used to endorse or promote
16 *    products derived from this software without specific prior
17 *    written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY David Young ``AS IS'' AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL David
23 * Young BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
25 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
30 * OF SUCH DAMAGE.
31 */
32/*
33 * Device driver for the Realtek RTL8180 802.11 MAC/BBP.
34 */
35
36#include <sys/cdefs.h>
37__KERNEL_RCSID(0, "$NetBSD: rtw.c,v 1.24 2004/12/26 22:59:41 dyoung Exp $");
38
39#include "bpfilter.h"
40
41#include <sys/param.h>
42#include <sys/sysctl.h>
43#include <sys/systm.h>
44#include <sys/callout.h>
45#include <sys/mbuf.h>
46#include <sys/malloc.h>
47#include <sys/kernel.h>
48#if 0
49#include <sys/socket.h>
50#include <sys/ioctl.h>
51#include <sys/errno.h>
52#include <sys/device.h>
53#endif
54#include <sys/time.h>
55#include <sys/types.h>
56
57#include <machine/endian.h>
58#include <machine/bus.h>
59#include <machine/intr.h>	/* splnet */
60
61#include <uvm/uvm_extern.h>
62
63#include <net/if.h>
64#include <net/if_media.h>
65#include <net/if_ether.h>
66
67#include <net80211/ieee80211_var.h>
68#include <net80211/ieee80211_compat.h>
69#include <net80211/ieee80211_radiotap.h>
70
71#if NBPFILTER > 0
72#include <net/bpf.h>
73#endif
74
75#include <dev/ic/rtwreg.h>
76#include <dev/ic/rtwvar.h>
77#include <dev/ic/rtwphyio.h>
78#include <dev/ic/rtwphy.h>
79
80#include <dev/ic/smc93cx6var.h>
81
82#define	KASSERT2(__cond, __msg)		\
83	do {				\
84		if (!(__cond))		\
85			panic __msg ;	\
86	} while (0)
87
88int rtw_rfprog_fallback = 0;
89int rtw_host_rfio = 0;
90int rtw_flush_rfio = 1;
91int rtw_rfio_delay = 0;
92
93#ifdef RTW_DEBUG
94int rtw_debug = 0;
95#endif /* RTW_DEBUG */
96
97#define NEXT_ATTACH_STATE(sc, state) do {			\
98	DPRINTF(sc, RTW_DEBUG_ATTACH,				\
99	    ("%s: attach state %s\n", __func__, #state));	\
100	sc->sc_attach_state = state;				\
101} while (0)
102
103int rtw_dwelltime = 1000;	/* milliseconds */
104
105static void rtw_start(struct ifnet *);
106
107static int rtw_sysctl_verify_rfio(SYSCTLFN_PROTO);
108static int rtw_sysctl_verify_rfio_delay(SYSCTLFN_PROTO);
109static int rtw_sysctl_verify_rfprog(SYSCTLFN_PROTO);
110#ifdef RTW_DEBUG
111static void rtw_print_txdesc(struct rtw_softc *, const char *,
112    struct rtw_txctl *, struct rtw_txdesc_blk *, int);
113static int rtw_sysctl_verify_debug(SYSCTLFN_PROTO);
114#endif /* RTW_DEBUG */
115
116/*
117 * Setup sysctl(3) MIB, hw.rtw.*
118 *
119 * TBD condition CTLFLAG_PERMANENT on being an LKM or not
120 */
121SYSCTL_SETUP(sysctl_rtw, "sysctl rtw(4) subtree setup")
122{
123	int rc;
124	struct sysctlnode *cnode, *rnode;
125
126	if ((rc = sysctl_createv(clog, 0, NULL, &rnode,
127	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL,
128	    NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0)
129		goto err;
130
131	if ((rc = sysctl_createv(clog, 0, &rnode, &rnode,
132	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "rtw",
133	    "Realtek RTL818x 802.11 controls",
134	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
135		goto err;
136
137#ifdef RTW_DEBUG
138	/* control debugging printfs */
139	if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
140	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
141	    "debug", SYSCTL_DESCR("Enable RTL818x debugging output"),
142	    rtw_sysctl_verify_debug, 0, &rtw_debug, 0,
143	    CTL_CREATE, CTL_EOL)) != 0)
144		goto err;
145#endif /* RTW_DEBUG */
146	/* set fallback RF programming method */
147	if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
148	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
149	    "rfprog_fallback",
150	    SYSCTL_DESCR("Set fallback RF programming method"),
151	    rtw_sysctl_verify_rfprog, 0, &rtw_rfprog_fallback, 0,
152	    CTL_CREATE, CTL_EOL)) != 0)
153		goto err;
154
155	/* force host to flush I/O by reading RTW_PHYADDR */
156	if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
157	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
158	    "flush_rfio", SYSCTL_DESCR("Enable RF I/O flushing"),
159	    rtw_sysctl_verify_rfio, 0, &rtw_flush_rfio, 0,
160	    CTL_CREATE, CTL_EOL)) != 0)
161		goto err;
162
163	/* force host to control RF I/O bus */
164	if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
165	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
166	    "host_rfio", SYSCTL_DESCR("Enable host control of RF I/O"),
167	    rtw_sysctl_verify_rfio, 0, &rtw_host_rfio, 0,
168	    CTL_CREATE, CTL_EOL)) != 0)
169		goto err;
170
171	/* control RF I/O delay */
172	if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
173	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
174	    "rfio_delay", SYSCTL_DESCR("Set RF I/O delay"),
175	    rtw_sysctl_verify_rfio_delay, 0, &rtw_rfio_delay, 0,
176	    CTL_CREATE, CTL_EOL)) != 0)
177		goto err;
178
179	return;
180err:
181	printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
182}
183
184static int
185rtw_sysctl_verify(SYSCTLFN_ARGS, int lower, int upper)
186{
187	int error, t;
188	struct sysctlnode node;
189
190	node = *rnode;
191	t = *(int*)rnode->sysctl_data;
192	node.sysctl_data = &t;
193	error = sysctl_lookup(SYSCTLFN_CALL(&node));
194	if (error || newp == NULL)
195		return (error);
196
197	if (t < lower || t > upper)
198		return (EINVAL);
199
200	*(int*)rnode->sysctl_data = t;
201
202	return (0);
203}
204
205static int
206rtw_sysctl_verify_rfio_delay(SYSCTLFN_ARGS)
207{
208	return rtw_sysctl_verify(SYSCTLFN_CALL(rnode), 0, 1000000);
209}
210
211static int
212rtw_sysctl_verify_rfprog(SYSCTLFN_ARGS)
213{
214	return rtw_sysctl_verify(SYSCTLFN_CALL(rnode), 0,
215	    MASK_AND_RSHIFT(RTW_CONFIG4_RFTYPE_MASK, RTW_CONFIG4_RFTYPE_MASK));
216}
217
218static int
219rtw_sysctl_verify_rfio(SYSCTLFN_ARGS)
220{
221	return rtw_sysctl_verify(SYSCTLFN_CALL(rnode), 0, 1);
222}
223
224#ifdef RTW_DEBUG
225static int
226rtw_sysctl_verify_debug(SYSCTLFN_ARGS)
227{
228	return rtw_sysctl_verify(SYSCTLFN_CALL(rnode), 0, RTW_DEBUG_MAX);
229}
230
231static void
232rtw_print_regs(struct rtw_regs *regs, const char *dvname, const char *where)
233{
234#define PRINTREG32(sc, reg)				\
235	RTW_DPRINTF(RTW_DEBUG_REGDUMP,			\
236	    ("%s: reg[ " #reg " / %03x ] = %08x\n",	\
237	    dvname, reg, RTW_READ(regs, reg)))
238
239#define PRINTREG16(sc, reg)				\
240	RTW_DPRINTF(RTW_DEBUG_REGDUMP,			\
241	    ("%s: reg[ " #reg " / %03x ] = %04x\n",	\
242	    dvname, reg, RTW_READ16(regs, reg)))
243
244#define PRINTREG8(sc, reg)				\
245	RTW_DPRINTF(RTW_DEBUG_REGDUMP,			\
246	    ("%s: reg[ " #reg " / %03x ] = %02x\n",	\
247	    dvname, reg, RTW_READ8(regs, reg)))
248
249	RTW_DPRINTF(RTW_DEBUG_REGDUMP, ("%s: %s\n", dvname, where));
250
251	PRINTREG32(regs, RTW_IDR0);
252	PRINTREG32(regs, RTW_IDR1);
253	PRINTREG32(regs, RTW_MAR0);
254	PRINTREG32(regs, RTW_MAR1);
255	PRINTREG32(regs, RTW_TSFTRL);
256	PRINTREG32(regs, RTW_TSFTRH);
257	PRINTREG32(regs, RTW_TLPDA);
258	PRINTREG32(regs, RTW_TNPDA);
259	PRINTREG32(regs, RTW_THPDA);
260	PRINTREG32(regs, RTW_TCR);
261	PRINTREG32(regs, RTW_RCR);
262	PRINTREG32(regs, RTW_TINT);
263	PRINTREG32(regs, RTW_TBDA);
264	PRINTREG32(regs, RTW_ANAPARM);
265	PRINTREG32(regs, RTW_BB);
266	PRINTREG32(regs, RTW_PHYCFG);
267	PRINTREG32(regs, RTW_WAKEUP0L);
268	PRINTREG32(regs, RTW_WAKEUP0H);
269	PRINTREG32(regs, RTW_WAKEUP1L);
270	PRINTREG32(regs, RTW_WAKEUP1H);
271	PRINTREG32(regs, RTW_WAKEUP2LL);
272	PRINTREG32(regs, RTW_WAKEUP2LH);
273	PRINTREG32(regs, RTW_WAKEUP2HL);
274	PRINTREG32(regs, RTW_WAKEUP2HH);
275	PRINTREG32(regs, RTW_WAKEUP3LL);
276	PRINTREG32(regs, RTW_WAKEUP3LH);
277	PRINTREG32(regs, RTW_WAKEUP3HL);
278	PRINTREG32(regs, RTW_WAKEUP3HH);
279	PRINTREG32(regs, RTW_WAKEUP4LL);
280	PRINTREG32(regs, RTW_WAKEUP4LH);
281	PRINTREG32(regs, RTW_WAKEUP4HL);
282	PRINTREG32(regs, RTW_WAKEUP4HH);
283	PRINTREG32(regs, RTW_DK0);
284	PRINTREG32(regs, RTW_DK1);
285	PRINTREG32(regs, RTW_DK2);
286	PRINTREG32(regs, RTW_DK3);
287	PRINTREG32(regs, RTW_RETRYCTR);
288	PRINTREG32(regs, RTW_RDSAR);
289	PRINTREG32(regs, RTW_FER);
290	PRINTREG32(regs, RTW_FEMR);
291	PRINTREG32(regs, RTW_FPSR);
292	PRINTREG32(regs, RTW_FFER);
293
294	/* 16-bit registers */
295	PRINTREG16(regs, RTW_BRSR);
296	PRINTREG16(regs, RTW_IMR);
297	PRINTREG16(regs, RTW_ISR);
298	PRINTREG16(regs, RTW_BCNITV);
299	PRINTREG16(regs, RTW_ATIMWND);
300	PRINTREG16(regs, RTW_BINTRITV);
301	PRINTREG16(regs, RTW_ATIMTRITV);
302	PRINTREG16(regs, RTW_CRC16ERR);
303	PRINTREG16(regs, RTW_CRC0);
304	PRINTREG16(regs, RTW_CRC1);
305	PRINTREG16(regs, RTW_CRC2);
306	PRINTREG16(regs, RTW_CRC3);
307	PRINTREG16(regs, RTW_CRC4);
308	PRINTREG16(regs, RTW_CWR);
309
310	/* 8-bit registers */
311	PRINTREG8(regs, RTW_CR);
312	PRINTREG8(regs, RTW_9346CR);
313	PRINTREG8(regs, RTW_CONFIG0);
314	PRINTREG8(regs, RTW_CONFIG1);
315	PRINTREG8(regs, RTW_CONFIG2);
316	PRINTREG8(regs, RTW_MSR);
317	PRINTREG8(regs, RTW_CONFIG3);
318	PRINTREG8(regs, RTW_CONFIG4);
319	PRINTREG8(regs, RTW_TESTR);
320	PRINTREG8(regs, RTW_PSR);
321	PRINTREG8(regs, RTW_SCR);
322	PRINTREG8(regs, RTW_PHYDELAY);
323	PRINTREG8(regs, RTW_CRCOUNT);
324	PRINTREG8(regs, RTW_PHYADDR);
325	PRINTREG8(regs, RTW_PHYDATAW);
326	PRINTREG8(regs, RTW_PHYDATAR);
327	PRINTREG8(regs, RTW_CONFIG5);
328	PRINTREG8(regs, RTW_TPPOLL);
329
330	PRINTREG16(regs, RTW_BSSID16);
331	PRINTREG32(regs, RTW_BSSID32);
332#undef PRINTREG32
333#undef PRINTREG16
334#undef PRINTREG8
335}
336#endif /* RTW_DEBUG */
337
338void
339rtw_continuous_tx_enable(struct rtw_softc *sc, int enable)
340{
341	struct rtw_regs *regs = &sc->sc_regs;
342
343	u_int32_t tcr;
344	tcr = RTW_READ(regs, RTW_TCR);
345	tcr &= ~RTW_TCR_LBK_MASK;
346	if (enable)
347		tcr |= RTW_TCR_LBK_CONT;
348	else
349		tcr |= RTW_TCR_LBK_NORMAL;
350	RTW_WRITE(regs, RTW_TCR, tcr);
351	RTW_SYNC(regs, RTW_TCR, RTW_TCR);
352	rtw_set_access(sc, RTW_ACCESS_ANAPARM);
353	rtw_txdac_enable(sc, !enable);
354	rtw_set_access(sc, RTW_ACCESS_ANAPARM);	/* XXX Voodoo from Linux. */
355	rtw_set_access(sc, RTW_ACCESS_NONE);
356}
357
358#ifdef RTW_DEBUG
359static const char *
360rtw_access_string(enum rtw_access access)
361{
362	switch (access) {
363	case RTW_ACCESS_NONE:
364		return "none";
365	case RTW_ACCESS_CONFIG:
366		return "config";
367	case RTW_ACCESS_ANAPARM:
368		return "anaparm";
369	default:
370		return "unknown";
371	}
372}
373#endif /* RTW_DEBUG */
374
375static void
376rtw_set_access1(struct rtw_regs *regs,
377    enum rtw_access oaccess, enum rtw_access naccess)
378{
379	KASSERT(naccess >= RTW_ACCESS_NONE && naccess <= RTW_ACCESS_ANAPARM);
380	KASSERT(oaccess >= RTW_ACCESS_NONE && oaccess <= RTW_ACCESS_ANAPARM);
381
382	if (naccess == oaccess)
383		return;
384
385	switch (naccess) {
386	case RTW_ACCESS_NONE:
387		switch (oaccess) {
388		case RTW_ACCESS_ANAPARM:
389			rtw_anaparm_enable(regs, 0);
390			/*FALLTHROUGH*/
391		case RTW_ACCESS_CONFIG:
392			rtw_config0123_enable(regs, 0);
393			/*FALLTHROUGH*/
394		case RTW_ACCESS_NONE:
395			break;
396		}
397		break;
398	case RTW_ACCESS_CONFIG:
399		switch (oaccess) {
400		case RTW_ACCESS_NONE:
401			rtw_config0123_enable(regs, 1);
402			/*FALLTHROUGH*/
403		case RTW_ACCESS_CONFIG:
404			break;
405		case RTW_ACCESS_ANAPARM:
406			rtw_anaparm_enable(regs, 0);
407			break;
408		}
409		break;
410	case RTW_ACCESS_ANAPARM:
411		switch (oaccess) {
412		case RTW_ACCESS_NONE:
413			rtw_config0123_enable(regs, 1);
414			/*FALLTHROUGH*/
415		case RTW_ACCESS_CONFIG:
416			rtw_anaparm_enable(regs, 1);
417			/*FALLTHROUGH*/
418		case RTW_ACCESS_ANAPARM:
419			break;
420		}
421		break;
422	}
423}
424
425void
426rtw_set_access(struct rtw_softc *sc, enum rtw_access access)
427{
428	rtw_set_access1(&sc->sc_regs, sc->sc_access, access);
429	RTW_DPRINTF(RTW_DEBUG_ACCESS,
430	    ("%s: access %s -> %s\n", sc->sc_dev.dv_xname,
431	    rtw_access_string(sc->sc_access),
432	    rtw_access_string(access)));
433	sc->sc_access = access;
434}
435
436/*
437 * Enable registers, switch register banks.
438 */
439void
440rtw_config0123_enable(struct rtw_regs *regs, int enable)
441{
442	u_int8_t ecr;
443	ecr = RTW_READ8(regs, RTW_9346CR);
444	ecr &= ~(RTW_9346CR_EEM_MASK | RTW_9346CR_EECS | RTW_9346CR_EESK);
445	if (enable)
446		ecr |= RTW_9346CR_EEM_CONFIG;
447	else {
448		RTW_WBW(regs, RTW_9346CR, MAX(RTW_CONFIG0, RTW_CONFIG3));
449		ecr |= RTW_9346CR_EEM_NORMAL;
450	}
451	RTW_WRITE8(regs, RTW_9346CR, ecr);
452	RTW_SYNC(regs, RTW_9346CR, RTW_9346CR);
453}
454
455/* requires rtw_config0123_enable(, 1) */
456void
457rtw_anaparm_enable(struct rtw_regs *regs, int enable)
458{
459	u_int8_t cfg3;
460
461	cfg3 = RTW_READ8(regs, RTW_CONFIG3);
462	cfg3 |= RTW_CONFIG3_CLKRUNEN;
463	if (enable)
464		cfg3 |= RTW_CONFIG3_PARMEN;
465	else
466		cfg3 &= ~RTW_CONFIG3_PARMEN;
467	RTW_WRITE8(regs, RTW_CONFIG3, cfg3);
468	RTW_SYNC(regs, RTW_CONFIG3, RTW_CONFIG3);
469}
470
471/* requires rtw_anaparm_enable(, 1) */
472void
473rtw_txdac_enable(struct rtw_softc *sc, int enable)
474{
475	u_int32_t anaparm;
476	struct rtw_regs *regs = &sc->sc_regs;
477
478	anaparm = RTW_READ(regs, RTW_ANAPARM);
479	if (enable)
480		anaparm &= ~RTW_ANAPARM_TXDACOFF;
481	else
482		anaparm |= RTW_ANAPARM_TXDACOFF;
483	RTW_WRITE(regs, RTW_ANAPARM, anaparm);
484	RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
485}
486
487static __inline int
488rtw_chip_reset1(struct rtw_regs *regs, const char *dvname)
489{
490	u_int8_t cr;
491	int i;
492
493	RTW_WRITE8(regs, RTW_CR, RTW_CR_RST);
494
495	RTW_WBR(regs, RTW_CR, RTW_CR);
496
497	for (i = 0; i < 1000; i++) {
498		if ((cr = RTW_READ8(regs, RTW_CR) & RTW_CR_RST) == 0) {
499			RTW_DPRINTF(RTW_DEBUG_RESET,
500			    ("%s: reset in %dus\n", dvname, i));
501			return 0;
502		}
503		RTW_RBR(regs, RTW_CR, RTW_CR);
504		DELAY(10); /* 10us */
505	}
506
507	printf("%s: reset failed\n", dvname);
508	return ETIMEDOUT;
509}
510
511static __inline int
512rtw_chip_reset(struct rtw_regs *regs, const char *dvname)
513{
514	uint32_t tcr;
515
516	/* from Linux driver */
517	tcr = RTW_TCR_CWMIN | RTW_TCR_MXDMA_2048 |
518	      LSHIFT(7, RTW_TCR_SRL_MASK) | LSHIFT(7, RTW_TCR_LRL_MASK);
519
520	RTW_WRITE(regs, RTW_TCR, tcr);
521
522	RTW_WBW(regs, RTW_CR, RTW_TCR);
523
524	return rtw_chip_reset1(regs, dvname);
525}
526
527static __inline int
528rtw_recall_eeprom(struct rtw_regs *regs, const char *dvname)
529{
530	int i;
531	u_int8_t ecr;
532
533	ecr = RTW_READ8(regs, RTW_9346CR);
534	ecr = (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_AUTOLOAD;
535	RTW_WRITE8(regs, RTW_9346CR, ecr);
536
537	RTW_WBR(regs, RTW_9346CR, RTW_9346CR);
538
539	/* wait 2.5ms for completion */
540	for (i = 0; i < 25; i++) {
541		ecr = RTW_READ8(regs, RTW_9346CR);
542		if ((ecr & RTW_9346CR_EEM_MASK) == RTW_9346CR_EEM_NORMAL) {
543			RTW_DPRINTF(RTW_DEBUG_RESET,
544			    ("%s: recall EEPROM in %dus\n", dvname, i * 100));
545			return 0;
546		}
547		RTW_RBR(regs, RTW_9346CR, RTW_9346CR);
548		DELAY(100);
549	}
550	printf("%s: recall EEPROM failed\n", dvname);
551	return ETIMEDOUT;
552}
553
554static __inline int
555rtw_reset(struct rtw_softc *sc)
556{
557	int rc;
558	uint8_t config1;
559
560	if ((rc = rtw_chip_reset(&sc->sc_regs, sc->sc_dev.dv_xname)) != 0)
561		return rc;
562
563	if ((rc = rtw_recall_eeprom(&sc->sc_regs, sc->sc_dev.dv_xname)) != 0)
564		;
565
566	config1 = RTW_READ8(&sc->sc_regs, RTW_CONFIG1);
567	RTW_WRITE8(&sc->sc_regs, RTW_CONFIG1, config1 & ~RTW_CONFIG1_PMEN);
568	/* TBD turn off maximum power saving? */
569
570	return 0;
571}
572
573static __inline int
574rtw_txdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_txctl *descs,
575    u_int ndescs)
576{
577	int i, rc = 0;
578	for (i = 0; i < ndescs; i++) {
579		rc = bus_dmamap_create(dmat, MCLBYTES, RTW_MAXPKTSEGS, MCLBYTES,
580		    0, 0, &descs[i].stx_dmamap);
581		if (rc != 0)
582			break;
583	}
584	return rc;
585}
586
587static __inline int
588rtw_rxdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_rxctl *descs,
589    u_int ndescs)
590{
591	int i, rc = 0;
592	for (i = 0; i < ndescs; i++) {
593		rc = bus_dmamap_create(dmat, MCLBYTES, 1, MCLBYTES, 0, 0,
594		    &descs[i].srx_dmamap);
595		if (rc != 0)
596			break;
597	}
598	return rc;
599}
600
601static __inline void
602rtw_rxctls_setup(struct rtw_rxctl *descs)
603{
604	int i;
605	for (i = 0; i < RTW_RXQLEN; i++)
606		descs[i].srx_mbuf = NULL;
607}
608
609static __inline void
610rtw_rxdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_rxctl *descs,
611    u_int ndescs)
612{
613	int i;
614	for (i = 0; i < ndescs; i++) {
615		if (descs[i].srx_dmamap != NULL)
616			bus_dmamap_destroy(dmat, descs[i].srx_dmamap);
617	}
618}
619
620static __inline void
621rtw_txdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_txctl *descs,
622    u_int ndescs)
623{
624	int i;
625	for (i = 0; i < ndescs; i++) {
626		if (descs[i].stx_dmamap != NULL)
627			bus_dmamap_destroy(dmat, descs[i].stx_dmamap);
628	}
629}
630
631static __inline void
632rtw_srom_free(struct rtw_srom *sr)
633{
634	sr->sr_size = 0;
635	if (sr->sr_content == NULL)
636		return;
637	free(sr->sr_content, M_DEVBUF);
638	sr->sr_content = NULL;
639}
640
641static void
642rtw_srom_defaults(struct rtw_srom *sr, u_int32_t *flags, u_int8_t *cs_threshold,
643    enum rtw_rfchipid *rfchipid, u_int32_t *rcr)
644{
645	*flags |= (RTW_F_DIGPHY|RTW_F_ANTDIV);
646	*cs_threshold = RTW_SR_ENERGYDETTHR_DEFAULT;
647	*rcr |= RTW_RCR_ENCS1;
648	*rfchipid = RTW_RFCHIPID_PHILIPS;
649}
650
651static int
652rtw_srom_parse(struct rtw_srom *sr, u_int32_t *flags, u_int8_t *cs_threshold,
653    enum rtw_rfchipid *rfchipid, u_int32_t *rcr, enum rtw_locale *locale,
654    const char *dvname)
655{
656	int i;
657	const char *rfname, *paname;
658	char scratch[sizeof("unknown 0xXX")];
659	u_int16_t version;
660	u_int8_t mac[IEEE80211_ADDR_LEN];
661
662	*flags &= ~(RTW_F_DIGPHY|RTW_F_DFLANTB|RTW_F_ANTDIV);
663	*rcr &= ~(RTW_RCR_ENCS1 | RTW_RCR_ENCS2);
664
665	version = RTW_SR_GET16(sr, RTW_SR_VERSION);
666	printf("%s: SROM version %d.%d", dvname, version >> 8, version & 0xff);
667
668	if (version <= 0x0101) {
669		printf(" is not understood, limping along with defaults\n");
670		rtw_srom_defaults(sr, flags, cs_threshold, rfchipid, rcr);
671		return 0;
672	}
673	printf("\n");
674
675	for (i = 0; i < IEEE80211_ADDR_LEN; i++)
676		mac[i] = RTW_SR_GET(sr, RTW_SR_MAC + i);
677
678	RTW_DPRINTF(RTW_DEBUG_ATTACH,
679	    ("%s: EEPROM MAC %s\n", dvname, ether_sprintf(mac)));
680
681	*cs_threshold = RTW_SR_GET(sr, RTW_SR_ENERGYDETTHR);
682
683	if ((RTW_SR_GET(sr, RTW_SR_CONFIG2) & RTW_CONFIG2_ANT) != 0)
684		*flags |= RTW_F_ANTDIV;
685
686	/* Note well: the sense of the RTW_SR_RFPARM_DIGPHY bit seems
687	 * to be reversed.
688	 */
689	if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DIGPHY) == 0)
690		*flags |= RTW_F_DIGPHY;
691	if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DFLANTB) != 0)
692		*flags |= RTW_F_DFLANTB;
693
694	*rcr |= LSHIFT(MASK_AND_RSHIFT(RTW_SR_GET(sr, RTW_SR_RFPARM),
695	    RTW_SR_RFPARM_CS_MASK), RTW_RCR_ENCS1);
696
697	*rfchipid = RTW_SR_GET(sr, RTW_SR_RFCHIPID);
698	switch (*rfchipid) {
699	case RTW_RFCHIPID_GCT:		/* this combo seen in the wild */
700		rfname = "GCT GRF5101";
701		paname = "Winspring WS9901";
702		break;
703	case RTW_RFCHIPID_MAXIM:
704		rfname = "Maxim MAX2820";	/* guess */
705		paname = "Maxim MAX2422";	/* guess */
706		break;
707	case RTW_RFCHIPID_INTERSIL:
708		rfname = "Intersil HFA3873";	/* guess */
709		paname = "Intersil <unknown>";
710		break;
711	case RTW_RFCHIPID_PHILIPS:	/* this combo seen in the wild */
712		rfname = "Philips SA2400A";
713		paname = "Philips SA2411";
714		break;
715	case RTW_RFCHIPID_RFMD:
716		/* this is the same front-end as an atw(4)! */
717		rfname = "RFMD RF2948B, "	/* mentioned in Realtek docs */
718			 "LNA: RFMD RF2494, "	/* mentioned in Realtek docs */
719			 "SYN: Silicon Labs Si4126";	/* inferred from
720			 				 * reference driver
721							 */
722		paname = "RFMD RF2189";		/* mentioned in Realtek docs */
723		break;
724	case RTW_RFCHIPID_RESERVED:
725		rfname = paname = "reserved";
726		break;
727	default:
728		snprintf(scratch, sizeof(scratch), "unknown 0x%02x", *rfchipid);
729		rfname = paname = scratch;
730	}
731	printf("%s: RF: %s, PA: %s\n", dvname, rfname, paname);
732
733	switch (RTW_SR_GET(sr, RTW_SR_CONFIG0) & RTW_CONFIG0_GL_MASK) {
734	case RTW_CONFIG0_GL_USA:
735		*locale = RTW_LOCALE_USA;
736		break;
737	case RTW_CONFIG0_GL_EUROPE:
738		*locale = RTW_LOCALE_EUROPE;
739		break;
740	case RTW_CONFIG0_GL_JAPAN:
741		*locale = RTW_LOCALE_JAPAN;
742		break;
743	default:
744		*locale = RTW_LOCALE_UNKNOWN;
745		break;
746	}
747	return 0;
748}
749
750/* Returns -1 on failure. */
751static int
752rtw_srom_read(struct rtw_regs *regs, u_int32_t flags, struct rtw_srom *sr,
753    const char *dvname)
754{
755	int rc;
756	struct seeprom_descriptor sd;
757	u_int8_t ecr;
758
759	(void)memset(&sd, 0, sizeof(sd));
760
761	ecr = RTW_READ8(regs, RTW_9346CR);
762
763	if ((flags & RTW_F_9356SROM) != 0) {
764		RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: 93c56 SROM\n", dvname));
765		sr->sr_size = 256;
766		sd.sd_chip = C56_66;
767	} else {
768		RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: 93c46 SROM\n", dvname));
769		sr->sr_size = 128;
770		sd.sd_chip = C46;
771	}
772
773	ecr &= ~(RTW_9346CR_EEDI | RTW_9346CR_EEDO | RTW_9346CR_EESK |
774	    RTW_9346CR_EEM_MASK);
775	ecr |= RTW_9346CR_EEM_PROGRAM;
776
777	RTW_WRITE8(regs, RTW_9346CR, ecr);
778
779	sr->sr_content = malloc(sr->sr_size, M_DEVBUF, M_NOWAIT);
780
781	if (sr->sr_content == NULL) {
782		printf("%s: unable to allocate SROM buffer\n", dvname);
783		return ENOMEM;
784	}
785
786	(void)memset(sr->sr_content, 0, sr->sr_size);
787
788	/* RTL8180 has a single 8-bit register for controlling the
789	 * 93cx6 SROM.  There is no "ready" bit. The RTL8180
790	 * input/output sense is the reverse of read_seeprom's.
791	 */
792	sd.sd_tag = regs->r_bt;
793	sd.sd_bsh = regs->r_bh;
794	sd.sd_regsize = 1;
795	sd.sd_control_offset = RTW_9346CR;
796	sd.sd_status_offset = RTW_9346CR;
797	sd.sd_dataout_offset = RTW_9346CR;
798	sd.sd_CK = RTW_9346CR_EESK;
799	sd.sd_CS = RTW_9346CR_EECS;
800	sd.sd_DI = RTW_9346CR_EEDO;
801	sd.sd_DO = RTW_9346CR_EEDI;
802	/* make read_seeprom enter EEPROM read/write mode */
803	sd.sd_MS = ecr;
804	sd.sd_RDY = 0;
805#if 0
806	sd.sd_clkdelay = 50;
807#endif
808
809	/* TBD bus barriers */
810	if (!read_seeprom(&sd, sr->sr_content, 0, sr->sr_size/2)) {
811		printf("%s: could not read SROM\n", dvname);
812		free(sr->sr_content, M_DEVBUF);
813		sr->sr_content = NULL;
814		return -1;	/* XXX */
815	}
816
817	/* end EEPROM read/write mode */
818	RTW_WRITE8(regs, RTW_9346CR,
819	    (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_NORMAL);
820	RTW_WBRW(regs, RTW_9346CR, RTW_9346CR);
821
822	if ((rc = rtw_recall_eeprom(regs, dvname)) != 0)
823		return rc;
824
825#ifdef RTW_DEBUG
826	{
827		int i;
828		RTW_DPRINTF(RTW_DEBUG_ATTACH,
829		    ("\n%s: serial ROM:\n\t", dvname));
830		for (i = 0; i < sr->sr_size/2; i++) {
831			if (((i % 8) == 0) && (i != 0))
832				RTW_DPRINTF(RTW_DEBUG_ATTACH, ("\n\t"));
833			RTW_DPRINTF(RTW_DEBUG_ATTACH,
834			    (" %04x", sr->sr_content[i]));
835		}
836		RTW_DPRINTF(RTW_DEBUG_ATTACH, ("\n"));
837	}
838#endif /* RTW_DEBUG */
839	return 0;
840}
841
842static void
843rtw_set_rfprog(struct rtw_regs *regs, enum rtw_rfchipid rfchipid,
844    const char *dvname)
845{
846	u_int8_t cfg4;
847	const char *method;
848
849	cfg4 = RTW_READ8(regs, RTW_CONFIG4) & ~RTW_CONFIG4_RFTYPE_MASK;
850
851	switch (rfchipid) {
852	default:
853		cfg4 |= LSHIFT(rtw_rfprog_fallback, RTW_CONFIG4_RFTYPE_MASK);
854		method = "fallback";
855		break;
856	case RTW_RFCHIPID_INTERSIL:
857		cfg4 |= RTW_CONFIG4_RFTYPE_INTERSIL;
858		method = "Intersil";
859		break;
860	case RTW_RFCHIPID_PHILIPS:
861		cfg4 |= RTW_CONFIG4_RFTYPE_PHILIPS;
862		method = "Philips";
863		break;
864	case RTW_RFCHIPID_RFMD:
865		cfg4 |= RTW_CONFIG4_RFTYPE_RFMD;
866		method = "RFMD";
867		break;
868	}
869
870	RTW_WRITE8(regs, RTW_CONFIG4, cfg4);
871
872	RTW_WBR(regs, RTW_CONFIG4, RTW_CONFIG4);
873
874	RTW_DPRINTF(RTW_DEBUG_INIT,
875	    ("%s: %s RF programming method, %#02x\n", dvname, method,
876	    RTW_READ8(regs, RTW_CONFIG4)));
877}
878
879#if 0
880static __inline int
881rtw_identify_rf(struct rtw_regs *regs, enum rtw_rftype *rftype,
882    const char *dvname)
883{
884	u_int8_t cfg4;
885	const char *name;
886
887	cfg4 = RTW_READ8(regs, RTW_CONFIG4);
888
889	switch (cfg4 & RTW_CONFIG4_RFTYPE_MASK) {
890	case RTW_CONFIG4_RFTYPE_PHILIPS:
891		*rftype = RTW_RFTYPE_PHILIPS;
892		name = "Philips";
893		break;
894	case RTW_CONFIG4_RFTYPE_INTERSIL:
895		*rftype = RTW_RFTYPE_INTERSIL;
896		name = "Intersil";
897		break;
898	case RTW_CONFIG4_RFTYPE_RFMD:
899		*rftype = RTW_RFTYPE_RFMD;
900		name = "RFMD";
901		break;
902	default:
903		name = "<unknown>";
904		return ENXIO;
905	}
906
907	printf("%s: RF prog type %s\n", dvname, name);
908	return 0;
909}
910#endif
911
912static __inline void
913rtw_init_channels(enum rtw_locale locale,
914    struct ieee80211_channel (*chans)[IEEE80211_CHAN_MAX+1],
915    const char *dvname)
916{
917	int i;
918	const char *name = NULL;
919#define ADD_CHANNEL(_chans, _chan) do {			\
920	(*_chans)[_chan].ic_flags = IEEE80211_CHAN_B;		\
921	(*_chans)[_chan].ic_freq =				\
922	    ieee80211_ieee2mhz(_chan, (*_chans)[_chan].ic_flags);\
923} while (0)
924
925	switch (locale) {
926	case RTW_LOCALE_USA:	/* 1-11 */
927		name = "USA";
928		for (i = 1; i <= 11; i++)
929			ADD_CHANNEL(chans, i);
930		break;
931	case RTW_LOCALE_JAPAN:	/* 1-14 */
932		name = "Japan";
933		ADD_CHANNEL(chans, 14);
934		for (i = 1; i <= 14; i++)
935			ADD_CHANNEL(chans, i);
936		break;
937	case RTW_LOCALE_EUROPE:	/* 1-13 */
938		name = "Europe";
939		for (i = 1; i <= 13; i++)
940			ADD_CHANNEL(chans, i);
941		break;
942	default:			/* 10-11 allowed by most countries */
943		name = "<unknown>";
944		for (i = 10; i <= 11; i++)
945			ADD_CHANNEL(chans, i);
946		break;
947	}
948	printf("%s: Geographic Location %s\n", dvname, name);
949#undef ADD_CHANNEL
950}
951
952static __inline void
953rtw_identify_country(struct rtw_regs *regs, enum rtw_locale *locale,
954    const char *dvname)
955{
956	u_int8_t cfg0 = RTW_READ8(regs, RTW_CONFIG0);
957
958	switch (cfg0 & RTW_CONFIG0_GL_MASK) {
959	case RTW_CONFIG0_GL_USA:
960		*locale = RTW_LOCALE_USA;
961		break;
962	case RTW_CONFIG0_GL_JAPAN:
963		*locale = RTW_LOCALE_JAPAN;
964		break;
965	case RTW_CONFIG0_GL_EUROPE:
966		*locale = RTW_LOCALE_EUROPE;
967		break;
968	default:
969		*locale = RTW_LOCALE_UNKNOWN;
970		break;
971	}
972}
973
974static __inline int
975rtw_identify_sta(struct rtw_regs *regs, u_int8_t (*addr)[IEEE80211_ADDR_LEN],
976    const char *dvname)
977{
978	static const u_int8_t empty_macaddr[IEEE80211_ADDR_LEN] = {
979		0x00, 0x00, 0x00, 0x00, 0x00, 0x00
980	};
981	u_int32_t idr0 = RTW_READ(regs, RTW_IDR0),
982	          idr1 = RTW_READ(regs, RTW_IDR1);
983
984	(*addr)[0] = MASK_AND_RSHIFT(idr0, BITS(0,  7));
985	(*addr)[1] = MASK_AND_RSHIFT(idr0, BITS(8,  15));
986	(*addr)[2] = MASK_AND_RSHIFT(idr0, BITS(16, 23));
987	(*addr)[3] = MASK_AND_RSHIFT(idr0, BITS(24 ,31));
988
989	(*addr)[4] = MASK_AND_RSHIFT(idr1, BITS(0,  7));
990	(*addr)[5] = MASK_AND_RSHIFT(idr1, BITS(8, 15));
991
992	if (IEEE80211_ADDR_EQ(addr, empty_macaddr)) {
993		printf("%s: could not get mac address, attach failed\n",
994		    dvname);
995		return ENXIO;
996	}
997
998	printf("%s: 802.11 address %s\n", dvname, ether_sprintf(*addr));
999
1000	return 0;
1001}
1002
1003static u_int8_t
1004rtw_chan2txpower(struct rtw_srom *sr, struct ieee80211com *ic,
1005    struct ieee80211_channel *chan)
1006{
1007	u_int idx = RTW_SR_TXPOWER1 + ieee80211_chan2ieee(ic, chan) - 1;
1008	KASSERT2(idx >= RTW_SR_TXPOWER1 && idx <= RTW_SR_TXPOWER14,
1009	    ("%s: channel %d out of range", __func__,
1010	     idx - RTW_SR_TXPOWER1 + 1));
1011	return RTW_SR_GET(sr, idx);
1012}
1013
1014static void
1015rtw_txdesc_blk_init_all(struct rtw_txdesc_blk *htcs)
1016{
1017	int pri;
1018	u_int ndesc[RTW_NTXPRI] =
1019	    {RTW_NTXDESCLO, RTW_NTXDESCMD, RTW_NTXDESCHI, RTW_NTXDESCBCN};
1020
1021	for (pri = 0; pri < RTW_NTXPRI; pri++) {
1022		htcs[pri].htc_nfree = ndesc[pri];
1023		htcs[pri].htc_next = 0;
1024	}
1025}
1026
1027static int
1028rtw_txctl_blk_init(struct rtw_txctl_blk *stc)
1029{
1030	int i;
1031	struct rtw_txctl *stx;
1032
1033	SIMPLEQ_INIT(&stc->stc_dirtyq);
1034	SIMPLEQ_INIT(&stc->stc_freeq);
1035	for (i = 0; i < stc->stc_ndesc; i++) {
1036		stx = &stc->stc_desc[i];
1037		stx->stx_mbuf = NULL;
1038		SIMPLEQ_INSERT_TAIL(&stc->stc_freeq, stx, stx_q);
1039	}
1040	return 0;
1041}
1042
1043static void
1044rtw_txctl_blk_init_all(struct rtw_txctl_blk *stcs)
1045{
1046	int pri;
1047	for (pri = 0; pri < RTW_NTXPRI; pri++)
1048		rtw_txctl_blk_init(&stcs[pri]);
1049}
1050
1051static __inline void
1052rtw_rxdescs_sync(bus_dma_tag_t dmat, bus_dmamap_t dmap, u_int desc0, u_int
1053    nsync, int ops)
1054{
1055	KASSERT(nsync <= RTW_RXQLEN);
1056	/* sync to end of ring */
1057	if (desc0 + nsync > RTW_RXQLEN) {
1058		bus_dmamap_sync(dmat, dmap,
1059		    offsetof(struct rtw_descs, hd_rx[desc0]),
1060		    sizeof(struct rtw_rxdesc) * (RTW_RXQLEN - desc0), ops);
1061		nsync -= (RTW_RXQLEN - desc0);
1062		desc0 = 0;
1063	}
1064
1065	KASSERT(desc0 < RTW_RXQLEN);
1066	KASSERT(nsync <= RTW_RXQLEN);
1067	KASSERT(desc0 + nsync <= RTW_RXQLEN);
1068
1069	/* sync what remains */
1070	bus_dmamap_sync(dmat, dmap,
1071	    offsetof(struct rtw_descs, hd_rx[desc0]),
1072	    sizeof(struct rtw_rxdesc) * nsync, ops);
1073}
1074
1075static void
1076rtw_txdescs_sync(bus_dma_tag_t dmat, bus_dmamap_t dmap,
1077    struct rtw_txdesc_blk *htc, u_int desc0, u_int nsync, int ops)
1078{
1079	/* sync to end of ring */
1080	if (desc0 + nsync > htc->htc_ndesc) {
1081		bus_dmamap_sync(dmat, dmap,
1082		    htc->htc_ofs + sizeof(struct rtw_txdesc) * desc0,
1083		    sizeof(struct rtw_txdesc) * (htc->htc_ndesc - desc0),
1084		    ops);
1085		nsync -= (htc->htc_ndesc - desc0);
1086		desc0 = 0;
1087	}
1088
1089	/* sync what remains */
1090	bus_dmamap_sync(dmat, dmap,
1091	    htc->htc_ofs + sizeof(struct rtw_txdesc) * desc0,
1092	    sizeof(struct rtw_txdesc) * nsync, ops);
1093}
1094
1095static void
1096rtw_txdescs_sync_all(bus_dma_tag_t dmat, bus_dmamap_t dmap,
1097    struct rtw_txdesc_blk *htcs)
1098{
1099	int pri;
1100	for (pri = 0; pri < RTW_NTXPRI; pri++) {
1101		rtw_txdescs_sync(dmat, dmap,
1102		    &htcs[pri], 0, htcs[pri].htc_ndesc,
1103		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1104	}
1105}
1106
1107static void
1108rtw_rxbufs_release(bus_dma_tag_t dmat, struct rtw_rxctl *desc)
1109{
1110	int i;
1111	struct rtw_rxctl *srx;
1112
1113	for (i = 0; i < RTW_RXQLEN; i++) {
1114		srx = &desc[i];
1115		bus_dmamap_sync(dmat, srx->srx_dmamap, 0,
1116		    srx->srx_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
1117		bus_dmamap_unload(dmat, srx->srx_dmamap);
1118		m_freem(srx->srx_mbuf);
1119		srx->srx_mbuf = NULL;
1120	}
1121}
1122
1123static __inline int
1124rtw_rxbuf_alloc(bus_dma_tag_t dmat, struct rtw_rxctl *srx)
1125{
1126	int rc;
1127	struct mbuf *m;
1128
1129	MGETHDR(m, M_DONTWAIT, MT_DATA);
1130	if (m == NULL)
1131		return ENOBUFS;
1132
1133	MCLGET(m, M_DONTWAIT);
1134	if (m == NULL)
1135		return ENOBUFS;
1136
1137	m->m_pkthdr.len = m->m_len = m->m_ext.ext_size;
1138
1139	if (srx->srx_mbuf != NULL)
1140		bus_dmamap_unload(dmat, srx->srx_dmamap);
1141
1142	srx->srx_mbuf = NULL;
1143
1144	rc = bus_dmamap_load_mbuf(dmat, srx->srx_dmamap, m, BUS_DMA_NOWAIT);
1145	if (rc != 0) {
1146		m_freem(m);
1147		return -1;
1148	}
1149
1150	srx->srx_mbuf = m;
1151
1152	return 0;
1153}
1154
1155static int
1156rtw_rxctl_init_all(bus_dma_tag_t dmat, struct rtw_rxctl *desc,
1157    u_int *next, const char *dvname)
1158{
1159	int i, rc;
1160	struct rtw_rxctl *srx;
1161
1162	for (i = 0; i < RTW_RXQLEN; i++) {
1163		srx = &desc[i];
1164		if ((rc = rtw_rxbuf_alloc(dmat, srx)) == 0)
1165			continue;
1166		printf("%s: failed rtw_rxbuf_alloc after %d buffers, rc = %d\n",
1167		    dvname, i, rc);
1168		if (i == 0) {
1169			rtw_rxbufs_release(dmat, desc);
1170			return rc;
1171		}
1172	}
1173	*next = 0;
1174	return 0;
1175}
1176
1177static __inline void
1178rtw_rxdesc_init(bus_dma_tag_t dmat, bus_dmamap_t dmam,
1179    struct rtw_rxdesc *hrx, struct rtw_rxctl *srx, int idx, int kick)
1180{
1181	int is_last = (idx == RTW_RXQLEN - 1);
1182	uint32_t ctl, octl, obuf;
1183
1184	obuf = hrx->hrx_buf;
1185	hrx->hrx_buf = htole32(srx->srx_dmamap->dm_segs[0].ds_addr);
1186
1187	ctl = LSHIFT(srx->srx_mbuf->m_len, RTW_RXCTL_LENGTH_MASK) |
1188	    RTW_RXCTL_OWN | RTW_RXCTL_FS | RTW_RXCTL_LS;
1189
1190	if (is_last)
1191		ctl |= RTW_RXCTL_EOR;
1192
1193	octl = hrx->hrx_ctl;
1194	hrx->hrx_ctl = htole32(ctl);
1195
1196	RTW_DPRINTF(
1197	    kick ? (RTW_DEBUG_RECV_DESC | RTW_DEBUG_IO_KICK)
1198	         : RTW_DEBUG_RECV_DESC,
1199	    ("%s: hrx %p buf %08x -> %08x ctl %08x -> %08x\n", __func__, hrx,
1200	     le32toh(obuf), le32toh(hrx->hrx_buf), le32toh(octl),
1201	     le32toh(hrx->hrx_ctl)));
1202
1203	/* sync the mbuf */
1204	bus_dmamap_sync(dmat, srx->srx_dmamap, 0, srx->srx_dmamap->dm_mapsize,
1205	    BUS_DMASYNC_PREREAD);
1206
1207	/* sync the descriptor */
1208	bus_dmamap_sync(dmat, dmam, RTW_DESC_OFFSET(hd_rx, idx),
1209	    sizeof(struct rtw_rxdesc),
1210	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1211}
1212
1213static void
1214rtw_rxdesc_init_all(bus_dma_tag_t dmat, bus_dmamap_t dmam,
1215    struct rtw_rxdesc *desc, struct rtw_rxctl *ctl, int kick)
1216{
1217	int i;
1218	struct rtw_rxdesc *hrx;
1219	struct rtw_rxctl *srx;
1220
1221	for (i = 0; i < RTW_RXQLEN; i++) {
1222		hrx = &desc[i];
1223		srx = &ctl[i];
1224		rtw_rxdesc_init(dmat, dmam, hrx, srx, i, kick);
1225	}
1226}
1227
1228static void
1229rtw_io_enable(struct rtw_regs *regs, u_int8_t flags, int enable)
1230{
1231	u_int8_t cr;
1232
1233	RTW_DPRINTF(RTW_DEBUG_IOSTATE, ("%s: %s 0x%02x\n", __func__,
1234	    enable ? "enable" : "disable", flags));
1235
1236	cr = RTW_READ8(regs, RTW_CR);
1237
1238	/* XXX reference source does not enable MULRW */
1239#if 0
1240	/* enable PCI Read/Write Multiple */
1241	cr |= RTW_CR_MULRW;
1242#endif
1243
1244	RTW_RBW(regs, RTW_CR, RTW_CR);	/* XXX paranoia? */
1245	if (enable)
1246		cr |= flags;
1247	else
1248		cr &= ~flags;
1249	RTW_WRITE8(regs, RTW_CR, cr);
1250	RTW_SYNC(regs, RTW_CR, RTW_CR);
1251}
1252
1253static void
1254rtw_intr_rx(struct rtw_softc *sc, u_int16_t isr)
1255{
1256	u_int next, nproc = 0;
1257	int len, rate, rssi;
1258	u_int32_t hrssi, hstat, htsfth, htsftl;
1259	struct rtw_rxdesc *hrx;
1260	struct rtw_rxctl *srx;
1261	struct mbuf *m;
1262
1263	struct ieee80211_node *ni;
1264	struct ieee80211_frame *wh;
1265
1266	KASSERT(sc->sc_rxnext < RTW_RXQLEN);
1267
1268	for (next = sc->sc_rxnext; ; next = (next + 1) % RTW_RXQLEN) {
1269		rtw_rxdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap,
1270		    next, 1, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1271		hrx = &sc->sc_rxdesc[next];
1272		srx = &sc->sc_rxctl[next];
1273
1274		hstat = le32toh(hrx->hrx_stat);
1275		hrssi = le32toh(hrx->hrx_rssi);
1276		htsfth = le32toh(hrx->hrx_tsfth);
1277		htsftl = le32toh(hrx->hrx_tsftl);
1278
1279		RTW_DPRINTF(RTW_DEBUG_RECV_DESC,
1280		    ("%s: rxdesc[%d] hstat %08x hrssi %08x htsft %08x%08x\n",
1281		    __func__, next, hstat, hrssi, htsfth, htsftl));
1282
1283		KASSERT((hstat & (RTW_RXSTAT_FS|RTW_RXSTAT_LS)) ==
1284		    (RTW_RXSTAT_FS|RTW_RXSTAT_LS));
1285
1286		++nproc;
1287
1288		/* still belongs to NIC */
1289		if ((hstat & RTW_RXSTAT_OWN) != 0) {
1290			if (nproc > 1)
1291				break;
1292
1293			/* sometimes the NIC skips to the 0th descriptor */
1294			rtw_rxdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap,
1295			    0, 1, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1296			hrx = &sc->sc_rxdesc[0];
1297			if ((hrx->hrx_stat & htole32(RTW_RXSTAT_OWN)) != 0)
1298				break;
1299			RTW_DPRINTF(RTW_DEBUG_BUGS,
1300			    ("%s: NIC skipped to rxdesc[0]\n",
1301			     sc->sc_dev.dv_xname));
1302			next = 0;
1303			continue;
1304		}
1305
1306		if ((hstat & RTW_RXSTAT_IOERROR) != 0) {
1307			printf("%s: DMA error/FIFO overflow %08x, "
1308			    "rx descriptor %d\n", sc->sc_dev.dv_xname,
1309			    hstat & RTW_RXSTAT_IOERROR, next);
1310			goto next;
1311		}
1312
1313		len = MASK_AND_RSHIFT(hstat, RTW_RXSTAT_LENGTH_MASK);
1314		if (len < IEEE80211_MIN_LEN) {
1315			sc->sc_ic.ic_stats.is_rx_tooshort++;
1316			goto next;
1317		}
1318
1319		switch (hstat & RTW_RXSTAT_RATE_MASK) {
1320		case RTW_RXSTAT_RATE_1MBPS:
1321			rate = 2;
1322			break;
1323		case RTW_RXSTAT_RATE_2MBPS:
1324			rate = 4;
1325			break;
1326		case RTW_RXSTAT_RATE_5MBPS:
1327			rate = 11;
1328			break;
1329		case RTW_RXSTAT_RATE_11MBPS:
1330			rate = 22;
1331			break;
1332		default:
1333			printf("%s: unknown rate #%d\n", sc->sc_dev.dv_xname,
1334			    MASK_AND_RSHIFT(hstat, RTW_RXSTAT_RATE_MASK));
1335			goto next;
1336		}
1337
1338#ifdef RTW_DEBUG
1339#define PRINTSTAT(flag) do { \
1340	if ((hstat & flag) != 0) { \
1341		printf("%s" #flag, delim); \
1342		delim = ","; \
1343	} \
1344} while (0)
1345		if ((rtw_debug & RTW_DEBUG_RECV_DESC) != 0) {
1346			const char *delim = "<";
1347			printf("%s: ", sc->sc_dev.dv_xname);
1348			if ((hstat & RTW_RXSTAT_DEBUG) != 0) {
1349				printf("status %08x", hstat);
1350				PRINTSTAT(RTW_RXSTAT_SPLCP);
1351				PRINTSTAT(RTW_RXSTAT_MAR);
1352				PRINTSTAT(RTW_RXSTAT_PAR);
1353				PRINTSTAT(RTW_RXSTAT_BAR);
1354				PRINTSTAT(RTW_RXSTAT_PWRMGT);
1355				PRINTSTAT(RTW_RXSTAT_CRC32);
1356				PRINTSTAT(RTW_RXSTAT_ICV);
1357				printf(">, ");
1358			}
1359			printf("rate %d.%d Mb/s, time %08x%08x\n",
1360			    (rate * 5) / 10, (rate * 5) % 10, htsfth, htsftl);
1361		}
1362#endif /* RTW_DEBUG */
1363
1364		if ((hstat & RTW_RXSTAT_RES) != 0 &&
1365		    sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR)
1366			goto next;
1367
1368		/* if bad flags, skip descriptor */
1369		if ((hstat & RTW_RXSTAT_ONESEG) != RTW_RXSTAT_ONESEG) {
1370			printf("%s: too many rx segments\n",
1371			    sc->sc_dev.dv_xname);
1372			goto next;
1373		}
1374
1375		bus_dmamap_sync(sc->sc_dmat, srx->srx_dmamap, 0,
1376		    srx->srx_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
1377
1378		m = srx->srx_mbuf;
1379
1380		/* if temporarily out of memory, re-use mbuf */
1381		switch (rtw_rxbuf_alloc(sc->sc_dmat, srx)) {
1382		case 0:
1383			break;
1384		case ENOBUFS:
1385			printf("%s: rtw_rxbuf_alloc(, %d) failed, "
1386			    "dropping this packet\n", sc->sc_dev.dv_xname,
1387			    next);
1388			goto next;
1389		default:
1390			/* XXX shorten rx ring, instead? */
1391			panic("%s: could not load DMA map\n",
1392			    sc->sc_dev.dv_xname);
1393		}
1394
1395		if (sc->sc_rfchipid == RTW_RFCHIPID_PHILIPS)
1396			rssi = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_RSSI);
1397		else {
1398			rssi = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_IMR_RSSI);
1399			/* TBD find out each front-end's LNA gain in the
1400			 * front-end's units
1401			 */
1402			if ((hrssi & RTW_RXRSSI_IMR_LNA) == 0)
1403				rssi |= 0x80;
1404		}
1405
1406		m->m_pkthdr.rcvif = &sc->sc_if;
1407		m->m_pkthdr.len = m->m_len = len;
1408		m->m_flags |= M_HASFCS;
1409
1410		wh = mtod(m, struct ieee80211_frame *);
1411		/* TBD use _MAR, _BAR, _PAR flags as hints to _find_rxnode? */
1412		ni = ieee80211_find_rxnode(&sc->sc_ic, wh);
1413
1414		sc->sc_tsfth = htsfth;
1415
1416#ifdef RTW_DEBUG
1417		if ((sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) ==
1418		    (IFF_DEBUG|IFF_LINK2)) {
1419			ieee80211_dump_pkt(mtod(m, uint8_t *), m->m_pkthdr.len,
1420			    rate, rssi);
1421		}
1422#endif /* RTW_DEBUG */
1423		ieee80211_input(&sc->sc_if, m, ni, rssi, htsftl);
1424		ieee80211_release_node(&sc->sc_ic, ni);
1425next:
1426		rtw_rxdesc_init(sc->sc_dmat, sc->sc_desc_dmamap,
1427		    hrx, srx, next, 0);
1428	}
1429	KASSERT(sc->sc_rxnext < RTW_RXQLEN);
1430
1431	sc->sc_rxnext = next;
1432
1433	return;
1434}
1435
1436static void
1437rtw_txbuf_release(bus_dma_tag_t dmat, struct ieee80211com *ic,
1438    struct rtw_txctl *stx)
1439{
1440	struct mbuf *m;
1441	struct ieee80211_node *ni;
1442
1443	m = stx->stx_mbuf;
1444	ni = stx->stx_ni;
1445	KASSERT(m != NULL);
1446	KASSERT(ni != NULL);
1447	stx->stx_mbuf = NULL;
1448	stx->stx_ni = NULL;
1449
1450	bus_dmamap_sync(dmat, stx->stx_dmamap, 0, stx->stx_dmamap->dm_mapsize,
1451	    BUS_DMASYNC_POSTWRITE);
1452	bus_dmamap_unload(dmat, stx->stx_dmamap);
1453	m_freem(m);
1454	ieee80211_release_node(ic, ni);
1455}
1456
1457static void
1458rtw_txbufs_release(bus_dma_tag_t dmat, bus_dmamap_t desc_dmamap,
1459    struct ieee80211com *ic, struct rtw_txctl_blk *stc,
1460    struct rtw_txdesc_blk *htc)
1461{
1462	int desc, i;
1463	struct rtw_txctl *stx;
1464
1465	while ((stx = SIMPLEQ_FIRST(&stc->stc_dirtyq)) != NULL) {
1466		rtw_txdescs_sync(dmat, desc_dmamap, htc, stx->stx_first,
1467		    stx->stx_dmamap->dm_nsegs,
1468		    BUS_DMASYNC_POSTWRITE|BUS_DMASYNC_POSTREAD);
1469		for (i = 0, desc = stx->stx_first;
1470		     i < stx->stx_dmamap->dm_nsegs;
1471		     i++, desc = RTW_NEXT_IDX(htc, desc)) {
1472			htc->htc_desc[desc].htx_ctl0 &=
1473			    ~htole32(RTW_TXCTL0_OWN);
1474		}
1475		rtw_txdescs_sync(dmat, desc_dmamap, htc, stx->stx_first,
1476		    stx->stx_dmamap->dm_nsegs,
1477		    BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
1478		htc->htc_nfree += stx->stx_dmamap->dm_nsegs;
1479		rtw_txbuf_release(dmat, ic, stx);
1480		SIMPLEQ_REMOVE_HEAD(&stc->stc_dirtyq, stx_q);
1481		SIMPLEQ_INSERT_TAIL(&stc->stc_freeq, stx, stx_q);
1482	}
1483	htc->htc_next = 0;
1484}
1485
1486static __inline void
1487rtw_collect_txpkt(struct rtw_softc *sc, struct rtw_txdesc_blk *htc,
1488    struct rtw_txctl *stx, int ndesc)
1489{
1490	uint32_t hstat;
1491	int data_retry, rts_retry;
1492	struct rtw_txdesc *htx0, *htxn;
1493	const char *condstring;
1494
1495	rtw_txbuf_release(sc->sc_dmat, &sc->sc_ic, stx);
1496
1497	htc->htc_nfree += ndesc;
1498
1499	htx0 = &htc->htc_desc[stx->stx_first];
1500	htxn = &htc->htc_desc[stx->stx_last];
1501
1502	hstat = le32toh(htx0->htx_stat);
1503	rts_retry = MASK_AND_RSHIFT(hstat, RTW_TXSTAT_RTSRETRY_MASK);
1504	data_retry = MASK_AND_RSHIFT(hstat, RTW_TXSTAT_DRC_MASK);
1505
1506	sc->sc_if.if_collisions += rts_retry + data_retry;
1507
1508	if ((hstat & RTW_TXSTAT_TOK) != 0)
1509		condstring = "ok";
1510	else {
1511		sc->sc_if.if_oerrors++;
1512		condstring = "error";
1513	}
1514
1515	DPRINTF(sc, RTW_DEBUG_XMIT_DESC,
1516	    ("%s: stx %p txdesc[%d, %d] %s tries rts %u data %u\n",
1517	    sc->sc_dev.dv_xname, stx, stx->stx_first, stx->stx_last,
1518	    condstring, rts_retry, data_retry));
1519}
1520
1521/* Collect transmitted packets. */
1522static __inline void
1523rtw_collect_txring(struct rtw_softc *sc, struct rtw_txctl_blk *stc,
1524    struct rtw_txdesc_blk *htc)
1525{
1526	int ndesc;
1527	struct rtw_txctl *stx;
1528
1529	while ((stx = SIMPLEQ_FIRST(&stc->stc_dirtyq)) != NULL) {
1530		ndesc = 1 + stx->stx_last - stx->stx_first;
1531		if (stx->stx_last < stx->stx_first)
1532			ndesc += htc->htc_ndesc;
1533
1534		KASSERT(ndesc > 0);
1535
1536		rtw_txdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap, htc,
1537		    stx->stx_first, ndesc,
1538		    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1539
1540		if ((htc->htc_desc[stx->stx_first].htx_stat &
1541		    htole32(RTW_TXSTAT_OWN)) != 0)
1542			break;
1543
1544		rtw_collect_txpkt(sc, htc, stx, ndesc);
1545		SIMPLEQ_REMOVE_HEAD(&stc->stc_dirtyq, stx_q);
1546		SIMPLEQ_INSERT_TAIL(&stc->stc_freeq, stx, stx_q);
1547		sc->sc_if.if_flags &= ~IFF_OACTIVE;
1548	}
1549	if (stx == NULL)
1550		stc->stc_tx_timer = 0;
1551}
1552
1553static void
1554rtw_intr_tx(struct rtw_softc *sc, u_int16_t isr)
1555{
1556	int pri;
1557	struct rtw_txctl_blk	*stc;
1558	struct rtw_txdesc_blk	*htc;
1559
1560	for (pri = 0; pri < RTW_NTXPRI; pri++) {
1561		stc = &sc->sc_txctl_blk[pri];
1562		htc = &sc->sc_txdesc_blk[pri];
1563
1564		rtw_collect_txring(sc, stc, htc);
1565
1566		if ((isr & RTW_INTR_TX) != 0)
1567			rtw_start(&sc->sc_if);
1568	}
1569
1570	/* TBD */
1571	return;
1572}
1573
1574static void
1575rtw_intr_beacon(struct rtw_softc *sc, u_int16_t isr)
1576{
1577	/* TBD */
1578	return;
1579}
1580
1581static void
1582rtw_intr_atim(struct rtw_softc *sc)
1583{
1584	/* TBD */
1585	return;
1586}
1587
1588#ifdef RTW_DEBUG
1589static void
1590rtw_dump_rings(struct rtw_softc *sc)
1591{
1592	struct rtw_txdesc_blk *htc;
1593	struct rtw_rxdesc *hrx;
1594	int desc, pri;
1595
1596	if ((rtw_debug & RTW_DEBUG_IO_KICK) == 0)
1597		return;
1598
1599	for (pri = 0; pri < RTW_NTXPRI; pri++) {
1600		htc = &sc->sc_txdesc_blk[pri];
1601		printf("%s: txpri %d ndesc %d nfree %d\n", __func__, pri,
1602		    htc->htc_ndesc, htc->htc_nfree);
1603		for (desc = 0; desc < htc->htc_ndesc; desc++)
1604			rtw_print_txdesc(sc, ".", NULL, htc, desc);
1605	}
1606
1607	for (desc = 0; desc < RTW_RXQLEN; desc++) {
1608		hrx = &sc->sc_rxdesc[desc];
1609		printf("%s: ctl %08x rsvd0/rssi %08x buf/tsftl %08x "
1610		    "rsvd1/tsfth %08x\n", __func__,
1611		    le32toh(hrx->hrx_ctl), le32toh(hrx->hrx_rssi),
1612		    le32toh(hrx->hrx_buf), le32toh(hrx->hrx_tsfth));
1613	}
1614}
1615#endif /* RTW_DEBUG */
1616
1617static void
1618rtw_hwring_setup(struct rtw_softc *sc)
1619{
1620	struct rtw_regs *regs = &sc->sc_regs;
1621	RTW_WRITE(regs, RTW_RDSAR, RTW_RING_BASE(sc, hd_rx));
1622	RTW_WRITE(regs, RTW_TLPDA, RTW_RING_BASE(sc, hd_txlo));
1623	RTW_WRITE(regs, RTW_TNPDA, RTW_RING_BASE(sc, hd_txmd));
1624	RTW_WRITE(regs, RTW_THPDA, RTW_RING_BASE(sc, hd_txhi));
1625	RTW_WRITE(regs, RTW_TBDA, RTW_RING_BASE(sc, hd_bcn));
1626	RTW_SYNC(regs, RTW_TLPDA, RTW_RDSAR);
1627	RTW_DPRINTF(RTW_DEBUG_XMIT_DESC,
1628	    ("%s: reg[TLPDA] <- %" PRIxPTR "\n", __func__,
1629	     (uintptr_t)RTW_RING_BASE(sc, hd_txlo)));
1630	RTW_DPRINTF(RTW_DEBUG_XMIT_DESC,
1631	    ("%s: reg[TNPDA] <- %" PRIxPTR "\n", __func__,
1632	     (uintptr_t)RTW_RING_BASE(sc, hd_txmd)));
1633	RTW_DPRINTF(RTW_DEBUG_XMIT_DESC,
1634	    ("%s: reg[THPDA] <- %" PRIxPTR "\n", __func__,
1635	     (uintptr_t)RTW_RING_BASE(sc, hd_txhi)));
1636	RTW_DPRINTF(RTW_DEBUG_XMIT_DESC,
1637	    ("%s: reg[TBDA] <- %" PRIxPTR "\n", __func__,
1638	     (uintptr_t)RTW_RING_BASE(sc, hd_bcn)));
1639	RTW_DPRINTF(RTW_DEBUG_RECV_DESC,
1640	    ("%s: reg[RDSAR] <- %" PRIxPTR "\n", __func__,
1641	     (uintptr_t)RTW_RING_BASE(sc, hd_rx)));
1642}
1643
1644static void
1645rtw_swring_setup(struct rtw_softc *sc)
1646{
1647	rtw_txdesc_blk_init_all(&sc->sc_txdesc_blk[0]);
1648
1649	rtw_txctl_blk_init_all(&sc->sc_txctl_blk[0]);
1650
1651	rtw_rxdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap,
1652	    0, RTW_RXQLEN, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1653	rtw_rxctl_init_all(sc->sc_dmat, sc->sc_rxctl, &sc->sc_rxnext,
1654	    sc->sc_dev.dv_xname);
1655	rtw_rxdesc_init_all(sc->sc_dmat, sc->sc_desc_dmamap,
1656	    sc->sc_rxdesc, sc->sc_rxctl, 1);
1657
1658	rtw_txdescs_sync_all(sc->sc_dmat, sc->sc_desc_dmamap,
1659	    &sc->sc_txdesc_blk[0]);
1660#if 0	/* redundant with rtw_rxdesc_init_all */
1661	rtw_rxdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap,
1662	    0, RTW_RXQLEN, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1663#endif
1664}
1665
1666static void
1667rtw_txdesc_blk_reset(struct rtw_txdesc_blk *htc)
1668{
1669	int i;
1670
1671	for (i = 0; i < htc->htc_ndesc; i++)
1672		htc->htc_desc[i].htx_next = htole32(RTW_NEXT_DESC(htc, i));
1673}
1674
1675static void
1676rtw_txdescs_reset(struct rtw_softc *sc)
1677{
1678	int pri;
1679	struct rtw_txdesc_blk *htc;
1680
1681	for (pri = 0; pri < RTW_NTXPRI; pri++) {
1682		htc = &sc->sc_txdesc_blk[pri];
1683		rtw_txbufs_release(sc->sc_dmat, sc->sc_desc_dmamap, &sc->sc_ic,
1684		    &sc->sc_txctl_blk[pri], htc);
1685		rtw_txdesc_blk_reset(htc);
1686		KASSERT(htc->htc_nfree == htc->htc_ndesc);
1687	}
1688}
1689
1690static void
1691rtw_rxdescs_reset(struct rtw_softc *sc)
1692{
1693	/* Re-initialize descriptors, just in case. */
1694	rtw_rxdesc_init_all(sc->sc_dmat, sc->sc_desc_dmamap, sc->sc_rxdesc,
1695	    &sc->sc_rxctl[0], 1);
1696
1697	/* Reset to start of ring. */
1698	sc->sc_rxnext = 0;
1699}
1700
1701static void
1702rtw_intr_ioerror(struct rtw_softc *sc, uint16_t isr)
1703{
1704	struct rtw_regs *regs = &sc->sc_regs;
1705
1706	if ((isr & RTW_INTR_TXFOVW) != 0)
1707		printf("%s: tx fifo overflow\n", sc->sc_dev.dv_xname);
1708
1709	if ((isr & (RTW_INTR_RDU|RTW_INTR_RXFOVW)) == 0)
1710		return;
1711
1712	RTW_DPRINTF(RTW_DEBUG_BUGS, ("%s: restarting xmit/recv\n",
1713	    sc->sc_dev.dv_xname));
1714
1715#ifdef RTW_DEBUG
1716	rtw_dump_rings(sc);
1717#endif /* RTW_DEBUG */
1718
1719	rtw_io_enable(regs, RTW_CR_RE | RTW_CR_TE, 0);
1720
1721	/* Collect rx'd packets.  Refresh rx buffers. */
1722	rtw_intr_rx(sc, 0);
1723	/* Collect tx'd packets. */
1724	rtw_intr_tx(sc, 0);
1725
1726	RTW_WRITE16(regs, RTW_IMR, 0);
1727	RTW_SYNC(regs, RTW_IMR, RTW_IMR);
1728
1729	rtw_chip_reset1(regs, sc->sc_dev.dv_xname);
1730
1731	rtw_rxdescs_reset(sc);
1732	rtw_txdescs_reset(sc);
1733
1734	rtw_hwring_setup(sc);
1735
1736#ifdef RTW_DEBUG
1737	rtw_dump_rings(sc);
1738#endif /* RTW_DEBUG */
1739
1740	RTW_WRITE16(regs, RTW_IMR, sc->sc_inten);
1741	RTW_SYNC(regs, RTW_IMR, RTW_IMR);
1742	rtw_io_enable(regs, RTW_CR_RE | RTW_CR_TE, 1);
1743}
1744
1745static __inline void
1746rtw_suspend_ticks(struct rtw_softc *sc)
1747{
1748	RTW_DPRINTF(RTW_DEBUG_TIMEOUT,
1749	    ("%s: suspending ticks\n", sc->sc_dev.dv_xname));
1750	sc->sc_do_tick = 0;
1751}
1752
1753static __inline void
1754rtw_resume_ticks(struct rtw_softc *sc)
1755{
1756	u_int32_t tsftrl0, tsftrl1, next_tick;
1757
1758	tsftrl0 = RTW_READ(&sc->sc_regs, RTW_TSFTRL);
1759
1760	tsftrl1 = RTW_READ(&sc->sc_regs, RTW_TSFTRL);
1761	next_tick = tsftrl1 + 1000000;
1762	RTW_WRITE(&sc->sc_regs, RTW_TINT, next_tick);
1763
1764	sc->sc_do_tick = 1;
1765
1766	RTW_DPRINTF(RTW_DEBUG_TIMEOUT,
1767	    ("%s: resume ticks delta %#08x now %#08x next %#08x\n",
1768	    sc->sc_dev.dv_xname, tsftrl1 - tsftrl0, tsftrl1, next_tick));
1769}
1770
1771static void
1772rtw_intr_timeout(struct rtw_softc *sc)
1773{
1774	RTW_DPRINTF(RTW_DEBUG_TIMEOUT, ("%s: timeout\n", sc->sc_dev.dv_xname));
1775	if (sc->sc_do_tick)
1776		rtw_resume_ticks(sc);
1777	return;
1778}
1779
1780int
1781rtw_intr(void *arg)
1782{
1783	int i;
1784	struct rtw_softc *sc = arg;
1785	struct rtw_regs *regs = &sc->sc_regs;
1786	u_int16_t isr;
1787
1788	/*
1789	 * If the interface isn't running, the interrupt couldn't
1790	 * possibly have come from us.
1791	 */
1792	if ((sc->sc_flags & RTW_F_ENABLED) == 0 ||
1793	    (sc->sc_if.if_flags & IFF_RUNNING) == 0 ||
1794	    (sc->sc_dev.dv_flags & DVF_ACTIVE) == 0) {
1795		RTW_DPRINTF(RTW_DEBUG_INTR, ("%s: stray interrupt\n", sc->sc_dev.dv_xname));
1796		return (0);
1797	}
1798
1799	for (i = 0; i < 10; i++) {
1800		isr = RTW_READ16(regs, RTW_ISR);
1801
1802		RTW_WRITE16(regs, RTW_ISR, isr);
1803		RTW_WBR(regs, RTW_ISR, RTW_ISR);
1804
1805		if (sc->sc_intr_ack != NULL)
1806			(*sc->sc_intr_ack)(regs);
1807
1808		if (isr == 0)
1809			break;
1810
1811#ifdef RTW_DEBUG
1812#define PRINTINTR(flag) do { \
1813	if ((isr & flag) != 0) { \
1814		printf("%s" #flag, delim); \
1815		delim = ","; \
1816	} \
1817} while (0)
1818
1819		if ((rtw_debug & RTW_DEBUG_INTR) != 0 && isr != 0) {
1820			const char *delim = "<";
1821
1822			printf("%s: reg[ISR] = %x", sc->sc_dev.dv_xname, isr);
1823
1824			PRINTINTR(RTW_INTR_TXFOVW);
1825			PRINTINTR(RTW_INTR_TIMEOUT);
1826			PRINTINTR(RTW_INTR_BCNINT);
1827			PRINTINTR(RTW_INTR_ATIMINT);
1828			PRINTINTR(RTW_INTR_TBDER);
1829			PRINTINTR(RTW_INTR_TBDOK);
1830			PRINTINTR(RTW_INTR_THPDER);
1831			PRINTINTR(RTW_INTR_THPDOK);
1832			PRINTINTR(RTW_INTR_TNPDER);
1833			PRINTINTR(RTW_INTR_TNPDOK);
1834			PRINTINTR(RTW_INTR_RXFOVW);
1835			PRINTINTR(RTW_INTR_RDU);
1836			PRINTINTR(RTW_INTR_TLPDER);
1837			PRINTINTR(RTW_INTR_TLPDOK);
1838			PRINTINTR(RTW_INTR_RER);
1839			PRINTINTR(RTW_INTR_ROK);
1840
1841			printf(">\n");
1842		}
1843#undef PRINTINTR
1844#endif /* RTW_DEBUG */
1845
1846		if ((isr & RTW_INTR_RX) != 0)
1847			rtw_intr_rx(sc, isr & RTW_INTR_RX);
1848		if ((isr & RTW_INTR_TX) != 0)
1849			rtw_intr_tx(sc, isr & RTW_INTR_TX);
1850		if ((isr & RTW_INTR_BEACON) != 0)
1851			rtw_intr_beacon(sc, isr & RTW_INTR_BEACON);
1852		if ((isr & RTW_INTR_ATIMINT) != 0)
1853			rtw_intr_atim(sc);
1854		if ((isr & RTW_INTR_IOERROR) != 0)
1855			rtw_intr_ioerror(sc, isr & RTW_INTR_IOERROR);
1856		if ((isr & RTW_INTR_TIMEOUT) != 0)
1857			rtw_intr_timeout(sc);
1858	}
1859
1860	return 1;
1861}
1862
1863/* Must be called at splnet. */
1864static void
1865rtw_stop(struct ifnet *ifp, int disable)
1866{
1867	int pri;
1868	struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc;
1869	struct ieee80211com *ic = &sc->sc_ic;
1870	struct rtw_regs *regs = &sc->sc_regs;
1871
1872	if ((sc->sc_flags & RTW_F_ENABLED) == 0)
1873		return;
1874
1875	rtw_suspend_ticks(sc);
1876
1877	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
1878
1879	if ((sc->sc_flags & RTW_F_INVALID) == 0) {
1880		/* Disable interrupts. */
1881		RTW_WRITE16(regs, RTW_IMR, 0);
1882
1883		RTW_WBW(regs, RTW_TPPOLL, RTW_IMR);
1884
1885		/* Stop the transmit and receive processes. First stop DMA,
1886		 * then disable receiver and transmitter.
1887		 */
1888		RTW_WRITE8(regs, RTW_TPPOLL,
1889		    RTW_TPPOLL_SBQ|RTW_TPPOLL_SHPQ|RTW_TPPOLL_SNPQ|
1890		    RTW_TPPOLL_SLPQ);
1891
1892		RTW_SYNC(regs, RTW_TPPOLL, RTW_IMR);
1893
1894		rtw_io_enable(&sc->sc_regs, RTW_CR_RE|RTW_CR_TE, 0);
1895	}
1896
1897	for (pri = 0; pri < RTW_NTXPRI; pri++) {
1898		rtw_txbufs_release(sc->sc_dmat, sc->sc_desc_dmamap, &sc->sc_ic,
1899		    &sc->sc_txctl_blk[pri], &sc->sc_txdesc_blk[pri]);
1900	}
1901
1902	if (disable) {
1903		rtw_disable(sc);
1904		rtw_rxbufs_release(sc->sc_dmat, &sc->sc_rxctl[0]);
1905	}
1906
1907	/* Mark the interface as not running.  Cancel the watchdog timer. */
1908	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1909	ifp->if_timer = 0;
1910
1911	return;
1912}
1913
1914const char *
1915rtw_pwrstate_string(enum rtw_pwrstate power)
1916{
1917	switch (power) {
1918	case RTW_ON:
1919		return "on";
1920	case RTW_SLEEP:
1921		return "sleep";
1922	case RTW_OFF:
1923		return "off";
1924	default:
1925		return "unknown";
1926	}
1927}
1928
1929/* XXX For Maxim, I am using the RFMD settings gleaned from the
1930 * reference driver, plus a magic Maxim "ON" value that comes from
1931 * the Realtek document "Windows PG for Rtl8180."
1932 */
1933static void
1934rtw_maxim_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
1935    int before_rf, int digphy)
1936{
1937	u_int32_t anaparm;
1938
1939	anaparm = RTW_READ(regs, RTW_ANAPARM);
1940	anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF);
1941
1942	switch (power) {
1943	case RTW_OFF:
1944		if (before_rf)
1945			return;
1946		anaparm |= RTW_ANAPARM_RFPOW_MAXIM_OFF;
1947		anaparm |= RTW_ANAPARM_TXDACOFF;
1948		break;
1949	case RTW_SLEEP:
1950		if (!before_rf)
1951			return;
1952		anaparm |= RTW_ANAPARM_RFPOW_MAXIM_SLEEP;
1953		anaparm |= RTW_ANAPARM_TXDACOFF;
1954		break;
1955	case RTW_ON:
1956		if (!before_rf)
1957			return;
1958		anaparm |= RTW_ANAPARM_RFPOW_MAXIM_ON;
1959		break;
1960	}
1961	RTW_DPRINTF(RTW_DEBUG_PWR,
1962	    ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n",
1963	    __func__, rtw_pwrstate_string(power),
1964	    (before_rf) ? "before" : "after", anaparm));
1965
1966	RTW_WRITE(regs, RTW_ANAPARM, anaparm);
1967	RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
1968}
1969
1970/* XXX I am using the RFMD settings gleaned from the reference
1971 * driver.  They agree
1972 */
1973static void
1974rtw_rfmd_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
1975    int before_rf, int digphy)
1976{
1977	u_int32_t anaparm;
1978
1979	anaparm = RTW_READ(regs, RTW_ANAPARM);
1980	anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF);
1981
1982	switch (power) {
1983	case RTW_OFF:
1984		if (before_rf)
1985			return;
1986		anaparm |= RTW_ANAPARM_RFPOW_RFMD_OFF;
1987		anaparm |= RTW_ANAPARM_TXDACOFF;
1988		break;
1989	case RTW_SLEEP:
1990		if (!before_rf)
1991			return;
1992		anaparm |= RTW_ANAPARM_RFPOW_RFMD_SLEEP;
1993		anaparm |= RTW_ANAPARM_TXDACOFF;
1994		break;
1995	case RTW_ON:
1996		if (!before_rf)
1997			return;
1998		anaparm |= RTW_ANAPARM_RFPOW_RFMD_ON;
1999		break;
2000	}
2001	RTW_DPRINTF(RTW_DEBUG_PWR,
2002	    ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n",
2003	    __func__, rtw_pwrstate_string(power),
2004	    (before_rf) ? "before" : "after", anaparm));
2005
2006	RTW_WRITE(regs, RTW_ANAPARM, anaparm);
2007	RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
2008}
2009
2010static void
2011rtw_philips_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
2012    int before_rf, int digphy)
2013{
2014	u_int32_t anaparm;
2015
2016	anaparm = RTW_READ(regs, RTW_ANAPARM);
2017	anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF);
2018
2019	switch (power) {
2020	case RTW_OFF:
2021		if (before_rf)
2022			return;
2023		anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_OFF;
2024		anaparm |= RTW_ANAPARM_TXDACOFF;
2025		break;
2026	case RTW_SLEEP:
2027		if (!before_rf)
2028			return;
2029		anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_SLEEP;
2030		anaparm |= RTW_ANAPARM_TXDACOFF;
2031		break;
2032	case RTW_ON:
2033		if (!before_rf)
2034			return;
2035		if (digphy) {
2036			anaparm |= RTW_ANAPARM_RFPOW_DIG_PHILIPS_ON;
2037			/* XXX guess */
2038			anaparm |= RTW_ANAPARM_TXDACOFF;
2039		} else
2040			anaparm |= RTW_ANAPARM_RFPOW_ANA_PHILIPS_ON;
2041		break;
2042	}
2043	RTW_DPRINTF(RTW_DEBUG_PWR,
2044	    ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n",
2045	    __func__, rtw_pwrstate_string(power),
2046	    (before_rf) ? "before" : "after", anaparm));
2047
2048	RTW_WRITE(regs, RTW_ANAPARM, anaparm);
2049	RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
2050}
2051
2052static void
2053rtw_pwrstate0(struct rtw_softc *sc, enum rtw_pwrstate power, int before_rf,
2054    int digphy)
2055{
2056	struct rtw_regs *regs = &sc->sc_regs;
2057
2058	rtw_set_access(sc, RTW_ACCESS_ANAPARM);
2059
2060	(*sc->sc_pwrstate_cb)(regs, power, before_rf, digphy);
2061
2062	rtw_set_access(sc, RTW_ACCESS_NONE);
2063
2064	return;
2065}
2066
2067static int
2068rtw_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power)
2069{
2070	int rc;
2071
2072	RTW_DPRINTF(RTW_DEBUG_PWR,
2073	    ("%s: %s->%s\n", __func__,
2074	    rtw_pwrstate_string(sc->sc_pwrstate), rtw_pwrstate_string(power)));
2075
2076	if (sc->sc_pwrstate == power)
2077		return 0;
2078
2079	rtw_pwrstate0(sc, power, 1, sc->sc_flags & RTW_F_DIGPHY);
2080	rc = rtw_rf_pwrstate(sc->sc_rf, power);
2081	rtw_pwrstate0(sc, power, 0, sc->sc_flags & RTW_F_DIGPHY);
2082
2083	switch (power) {
2084	case RTW_ON:
2085		/* TBD set LEDs */
2086		break;
2087	case RTW_SLEEP:
2088		/* TBD */
2089		break;
2090	case RTW_OFF:
2091		/* TBD */
2092		break;
2093	}
2094	if (rc == 0)
2095		sc->sc_pwrstate = power;
2096	else
2097		sc->sc_pwrstate = RTW_OFF;
2098	return rc;
2099}
2100
2101static int
2102rtw_tune(struct rtw_softc *sc)
2103{
2104	struct ieee80211com *ic = &sc->sc_ic;
2105	u_int chan;
2106	int rc;
2107	int antdiv = sc->sc_flags & RTW_F_ANTDIV,
2108	    dflantb = sc->sc_flags & RTW_F_DFLANTB;
2109
2110	KASSERT(ic->ic_bss->ni_chan != NULL);
2111
2112	chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
2113	if (chan == IEEE80211_CHAN_ANY)
2114		panic("%s: chan == IEEE80211_CHAN_ANY\n", __func__);
2115
2116	if (chan == sc->sc_cur_chan) {
2117		RTW_DPRINTF(RTW_DEBUG_TUNE,
2118		    ("%s: already tuned chan #%d\n", __func__, chan));
2119		return 0;
2120	}
2121
2122	rtw_suspend_ticks(sc);
2123
2124	rtw_io_enable(&sc->sc_regs, RTW_CR_RE | RTW_CR_TE, 0);
2125
2126	/* TBD wait for Tx to complete */
2127
2128	KASSERT((sc->sc_flags & RTW_F_ENABLED) != 0);
2129
2130	if ((rc = rtw_phy_init(&sc->sc_regs, sc->sc_rf,
2131	    rtw_chan2txpower(&sc->sc_srom, ic, ic->ic_bss->ni_chan),
2132	    sc->sc_csthr, ic->ic_bss->ni_chan->ic_freq, antdiv,
2133	    dflantb, RTW_ON)) != 0) {
2134		/* XXX condition on powersaving */
2135		printf("%s: phy init failed\n", sc->sc_dev.dv_xname);
2136	}
2137
2138	sc->sc_cur_chan = chan;
2139
2140	rtw_io_enable(&sc->sc_regs, RTW_CR_RE | RTW_CR_TE, 1);
2141
2142	rtw_resume_ticks(sc);
2143
2144	return rc;
2145}
2146
2147void
2148rtw_disable(struct rtw_softc *sc)
2149{
2150	int rc;
2151
2152	if ((sc->sc_flags & RTW_F_ENABLED) == 0)
2153		return;
2154
2155	/* turn off PHY */
2156	if ((rc = rtw_pwrstate(sc, RTW_OFF)) != 0)
2157		printf("%s: failed to turn off PHY (%d)\n",
2158		    sc->sc_dev.dv_xname, rc);
2159
2160	if (sc->sc_disable != NULL)
2161		(*sc->sc_disable)(sc);
2162
2163	sc->sc_flags &= ~RTW_F_ENABLED;
2164}
2165
2166int
2167rtw_enable(struct rtw_softc *sc)
2168{
2169	if ((sc->sc_flags & RTW_F_ENABLED) == 0) {
2170		if (sc->sc_enable != NULL && (*sc->sc_enable)(sc) != 0) {
2171			printf("%s: device enable failed\n",
2172			    sc->sc_dev.dv_xname);
2173			return (EIO);
2174		}
2175		sc->sc_flags |= RTW_F_ENABLED;
2176	}
2177	return (0);
2178}
2179
2180static void
2181rtw_transmit_config(struct rtw_regs *regs)
2182{
2183	u_int32_t tcr;
2184
2185	tcr = RTW_READ(regs, RTW_TCR);
2186
2187	tcr |= RTW_TCR_CWMIN;
2188	tcr &= ~RTW_TCR_MXDMA_MASK;
2189	tcr |= RTW_TCR_MXDMA_256;
2190	tcr |= RTW_TCR_SAT;		/* send ACK as fast as possible */
2191	tcr &= ~RTW_TCR_LBK_MASK;
2192	tcr |= RTW_TCR_LBK_NORMAL;	/* normal operating mode */
2193
2194	/* set short/long retry limits */
2195	tcr &= ~(RTW_TCR_SRL_MASK|RTW_TCR_LRL_MASK);
2196	tcr |= LSHIFT(4, RTW_TCR_SRL_MASK) | LSHIFT(4, RTW_TCR_LRL_MASK);
2197
2198	tcr &= ~RTW_TCR_CRC;	/* NIC appends CRC32 */
2199
2200	RTW_WRITE(regs, RTW_TCR, tcr);
2201	RTW_SYNC(regs, RTW_TCR, RTW_TCR);
2202}
2203
2204static __inline void
2205rtw_enable_interrupts(struct rtw_softc *sc)
2206{
2207	struct rtw_regs *regs = &sc->sc_regs;
2208
2209	sc->sc_inten = RTW_INTR_RX|RTW_INTR_TX|RTW_INTR_BEACON|RTW_INTR_ATIMINT;
2210	sc->sc_inten |= RTW_INTR_IOERROR|RTW_INTR_TIMEOUT;
2211
2212	RTW_WRITE16(regs, RTW_IMR, sc->sc_inten);
2213	RTW_WBW(regs, RTW_IMR, RTW_ISR);
2214	RTW_WRITE16(regs, RTW_ISR, 0xffff);
2215	RTW_SYNC(regs, RTW_IMR, RTW_ISR);
2216
2217	/* XXX necessary? */
2218	if (sc->sc_intr_ack != NULL)
2219		(*sc->sc_intr_ack)(regs);
2220}
2221
2222static void
2223rtw_set_nettype(struct rtw_softc *sc, enum ieee80211_opmode opmode)
2224{
2225	uint8_t msr;
2226
2227	/* I'm guessing that MSR is protected as CONFIG[0123] are. */
2228	rtw_set_access(sc, RTW_ACCESS_CONFIG);
2229
2230	msr = RTW_READ8(&sc->sc_regs, RTW_MSR) & ~RTW_MSR_NETYPE_MASK;
2231
2232	switch (opmode) {
2233	case IEEE80211_M_AHDEMO:
2234	case IEEE80211_M_IBSS:
2235		msr |= RTW_MSR_NETYPE_ADHOC_OK;
2236		break;
2237	case IEEE80211_M_HOSTAP:
2238		msr |= RTW_MSR_NETYPE_AP_OK;
2239		break;
2240	case IEEE80211_M_MONITOR:
2241		/* XXX */
2242		msr |= RTW_MSR_NETYPE_NOLINK;
2243		break;
2244	case IEEE80211_M_STA:
2245		msr |= RTW_MSR_NETYPE_INFRA_OK;
2246		break;
2247	}
2248	RTW_WRITE8(&sc->sc_regs, RTW_MSR, msr);
2249
2250	rtw_set_access(sc, RTW_ACCESS_NONE);
2251}
2252
2253/* XXX is the endianness correct? test. */
2254#define	rtw_calchash(addr) \
2255	(ether_crc32_le((addr), IEEE80211_ADDR_LEN) & BITS(5, 0))
2256
2257static void
2258rtw_pktfilt_load(struct rtw_softc *sc)
2259{
2260	struct rtw_regs *regs = &sc->sc_regs;
2261	struct ieee80211com *ic = &sc->sc_ic;
2262	struct ethercom *ec = &ic->ic_ec;
2263	struct ifnet *ifp = &sc->sc_ic.ic_if;
2264	int hash;
2265	u_int32_t hashes[2] = { 0, 0 };
2266	struct ether_multi *enm;
2267	struct ether_multistep step;
2268
2269	/* XXX might be necessary to stop Rx/Tx engines while setting filters */
2270
2271#define RTW_RCR_MONITOR (RTW_RCR_ACRC32|RTW_RCR_APM|RTW_RCR_AAP|RTW_RCR_AB|RTW_RCR_ACF | RTW_RCR_AICV | RTW_RCR_ACRC32)
2272
2273	if (ic->ic_opmode == IEEE80211_M_MONITOR)
2274		sc->sc_rcr |= RTW_RCR_MONITOR;
2275	else
2276		sc->sc_rcr &= ~RTW_RCR_MONITOR;
2277
2278	/* XXX reference sources BEGIN */
2279	sc->sc_rcr |= RTW_RCR_ENMARP;
2280	sc->sc_rcr |= RTW_RCR_AB | RTW_RCR_AM | RTW_RCR_APM;
2281#if 0
2282	/* receive broadcasts in our BSS */
2283	sc->sc_rcr |= RTW_RCR_ADD3;
2284#endif
2285	/* XXX reference sources END */
2286
2287	/* receive pwrmgmt frames. */
2288	sc->sc_rcr |= RTW_RCR_APWRMGT;
2289	/* receive mgmt/ctrl/data frames. */
2290	sc->sc_rcr |= RTW_RCR_ADF | RTW_RCR_AMF;
2291	/* initialize Rx DMA threshold, Tx DMA burst size */
2292	sc->sc_rcr |= RTW_RCR_RXFTH_WHOLE | RTW_RCR_MXDMA_1024;
2293
2294	ifp->if_flags &= ~IFF_ALLMULTI;
2295
2296	if (ifp->if_flags & IFF_PROMISC) {
2297		sc->sc_rcr |= RTW_RCR_AB;	/* accept all broadcast */
2298allmulti:
2299		ifp->if_flags |= IFF_ALLMULTI;
2300		goto setit;
2301	}
2302
2303	/*
2304	 * Program the 64-bit multicast hash filter.
2305	 */
2306	ETHER_FIRST_MULTI(step, ec, enm);
2307	while (enm != NULL) {
2308		/* XXX */
2309		if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
2310		    ETHER_ADDR_LEN) != 0)
2311			goto allmulti;
2312
2313		hash = rtw_calchash(enm->enm_addrlo);
2314		hashes[hash >> 5] |= 1 << (hash & 0x1f);
2315		ETHER_NEXT_MULTI(step, enm);
2316	}
2317
2318	if (ifp->if_flags & IFF_BROADCAST) {
2319		hash = rtw_calchash(etherbroadcastaddr);
2320		hashes[hash >> 5] |= 1 << (hash & 0x1f);
2321	}
2322
2323	/* all bits set => hash is useless */
2324	if (~(hashes[0] & hashes[1]) == 0)
2325		goto allmulti;
2326
2327 setit:
2328	if (ifp->if_flags & IFF_ALLMULTI)
2329		sc->sc_rcr |= RTW_RCR_AM;	/* accept all multicast */
2330
2331	if (ic->ic_state == IEEE80211_S_SCAN)
2332		sc->sc_rcr |= RTW_RCR_AB;	/* accept all broadcast */
2333
2334	hashes[0] = hashes[1] = 0xffffffff;
2335
2336	RTW_WRITE(regs, RTW_MAR0, hashes[0]);
2337	RTW_WRITE(regs, RTW_MAR1, hashes[1]);
2338	RTW_WRITE(regs, RTW_RCR, sc->sc_rcr);
2339	RTW_SYNC(regs, RTW_MAR0, RTW_RCR); /* RTW_MAR0 < RTW_MAR1 < RTW_RCR */
2340
2341	DPRINTF(sc, RTW_DEBUG_PKTFILT,
2342	    ("%s: RTW_MAR0 %08x RTW_MAR1 %08x RTW_RCR %08x\n",
2343	    sc->sc_dev.dv_xname, RTW_READ(regs, RTW_MAR0),
2344	    RTW_READ(regs, RTW_MAR1), RTW_READ(regs, RTW_RCR)));
2345
2346	return;
2347}
2348
2349/* Must be called at splnet. */
2350static int
2351rtw_init(struct ifnet *ifp)
2352{
2353	struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc;
2354	struct ieee80211com *ic = &sc->sc_ic;
2355	struct rtw_regs *regs = &sc->sc_regs;
2356	int rc = 0;
2357
2358	if ((rc = rtw_enable(sc)) != 0)
2359		goto out;
2360
2361	/* Cancel pending I/O and reset. */
2362	rtw_stop(ifp, 0);
2363
2364	ic->ic_bss->ni_chan = ic->ic_ibss_chan;
2365	DPRINTF(sc, RTW_DEBUG_TUNE, ("%s: channel %d freq %d flags 0x%04x\n",
2366	    __func__, ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan),
2367	    ic->ic_bss->ni_chan->ic_freq, ic->ic_bss->ni_chan->ic_flags));
2368
2369	if ((rc = rtw_pwrstate(sc, RTW_OFF)) != 0)
2370		goto out;
2371
2372	rtw_swring_setup(sc);
2373
2374	rtw_transmit_config(regs);
2375
2376	rtw_set_access(sc, RTW_ACCESS_CONFIG);
2377
2378	RTW_WRITE8(regs, RTW_MSR, 0x0);	/* no link */
2379	RTW_WBW(regs, RTW_MSR, RTW_BRSR);
2380
2381	/* long PLCP header, 1Mbps basic rate */
2382	RTW_WRITE16(regs, RTW_BRSR, 0x0f);
2383	RTW_SYNC(regs, RTW_BRSR, RTW_BRSR);
2384
2385	rtw_set_access(sc, RTW_ACCESS_ANAPARM);
2386	rtw_set_access(sc, RTW_ACCESS_NONE);
2387
2388#if 0
2389	RTW_WRITE(regs, RTW_FEMR, RTW_FEMR_GWAKE|RTW_FEMR_WKUP|RTW_FEMR_INTR);
2390#endif
2391	/* XXX from reference sources */
2392	RTW_WRITE(regs, RTW_FEMR, 0xffff);
2393	RTW_SYNC(regs, RTW_FEMR, RTW_FEMR);
2394
2395	rtw_set_rfprog(regs, sc->sc_rfchipid, sc->sc_dev.dv_xname);
2396
2397	RTW_WRITE8(regs, RTW_PHYDELAY, sc->sc_phydelay);
2398	/* from Linux driver */
2399	RTW_WRITE8(regs, RTW_CRCOUNT, RTW_CRCOUNT_MAGIC);
2400
2401	RTW_SYNC(regs, RTW_PHYDELAY, RTW_CRCOUNT);
2402
2403	rtw_enable_interrupts(sc);
2404
2405	rtw_pktfilt_load(sc);
2406
2407	rtw_hwring_setup(sc);
2408
2409	rtw_io_enable(regs, RTW_CR_RE|RTW_CR_TE, 1);
2410
2411	ifp->if_flags |= IFF_RUNNING;
2412	ic->ic_state = IEEE80211_S_INIT;
2413
2414	RTW_WRITE16(regs, RTW_BSSID16, 0x0);
2415	RTW_WRITE(regs, RTW_BSSID32, 0x0);
2416
2417	rtw_resume_ticks(sc);
2418
2419	rtw_set_nettype(sc, IEEE80211_M_MONITOR);
2420
2421	if (ic->ic_opmode == IEEE80211_M_MONITOR)
2422		return ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
2423	else
2424		return ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
2425
2426out:
2427	return rc;
2428}
2429
2430static int
2431rtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
2432{
2433	int rc = 0, s;
2434	struct rtw_softc *sc = ifp->if_softc;
2435	struct ifreq *ifr = (struct ifreq *)data;
2436
2437	s = splnet();
2438	switch (cmd) {
2439	case SIOCSIFFLAGS:
2440		if ((ifp->if_flags & IFF_UP) != 0) {
2441			if (0 && (sc->sc_flags & RTW_F_ENABLED) != 0) {
2442				rtw_pktfilt_load(sc);
2443			} else
2444				rc = rtw_init(ifp);
2445#ifdef RTW_DEBUG
2446			rtw_print_regs(&sc->sc_regs, ifp->if_xname, __func__);
2447#endif /* RTW_DEBUG */
2448		} else if ((sc->sc_flags & RTW_F_ENABLED) != 0) {
2449#ifdef RTW_DEBUG
2450			rtw_print_regs(&sc->sc_regs, ifp->if_xname, __func__);
2451#endif /* RTW_DEBUG */
2452			rtw_stop(ifp, 1);
2453		}
2454		break;
2455	case SIOCADDMULTI:
2456	case SIOCDELMULTI:
2457		if (cmd == SIOCADDMULTI)
2458			rc = ether_addmulti(ifr, &sc->sc_ic.ic_ec);
2459		else
2460			rc = ether_delmulti(ifr, &sc->sc_ic.ic_ec);
2461		if (rc == ENETRESET) {
2462			if (ifp->if_flags & IFF_RUNNING)
2463				rtw_pktfilt_load(sc);
2464			rc = 0;
2465		}
2466		break;
2467	default:
2468		if ((rc = ieee80211_ioctl(ifp, cmd, data)) == ENETRESET) {
2469			if ((sc->sc_flags & RTW_F_ENABLED) != 0)
2470				rc = rtw_init(ifp);
2471			else
2472				rc = 0;
2473		}
2474		break;
2475	}
2476	splx(s);
2477	return rc;
2478}
2479
2480/* Point *mp at the next 802.11 frame to transmit.  Point *stcp
2481 * at the driver's selection of transmit control block for the packet.
2482 */
2483static __inline int
2484rtw_dequeue(struct ifnet *ifp, struct rtw_txctl_blk **stcp,
2485    struct rtw_txdesc_blk **htcp, struct mbuf **mp,
2486    struct ieee80211_node **nip)
2487{
2488	struct rtw_txctl_blk *stc;
2489	struct rtw_txdesc_blk *htc;
2490	struct mbuf *m0;
2491	struct rtw_softc *sc;
2492	struct ieee80211com *ic;
2493
2494	sc = (struct rtw_softc *)ifp->if_softc;
2495
2496	DPRINTF(sc, RTW_DEBUG_XMIT,
2497	    ("%s: enter %s\n", sc->sc_dev.dv_xname, __func__));
2498	*mp = NULL;
2499
2500	stc = &sc->sc_txctl_blk[RTW_TXPRIMD];
2501	htc = &sc->sc_txdesc_blk[RTW_TXPRIMD];
2502
2503	if (SIMPLEQ_EMPTY(&stc->stc_freeq) || htc->htc_nfree == 0) {
2504		DPRINTF(sc, RTW_DEBUG_XMIT,
2505		    ("%s: out of descriptors\n", __func__));
2506		ifp->if_flags |= IFF_OACTIVE;
2507		return 0;
2508	}
2509
2510	ic = &sc->sc_ic;
2511
2512	if (!IF_IS_EMPTY(&ic->ic_mgtq)) {
2513		IF_DEQUEUE(&ic->ic_mgtq, m0);
2514		*nip = (struct ieee80211_node *)m0->m_pkthdr.rcvif;
2515		m0->m_pkthdr.rcvif = NULL;
2516		DPRINTF(sc, RTW_DEBUG_XMIT,
2517		    ("%s: dequeue mgt frame\n", __func__));
2518	} else if (ic->ic_state != IEEE80211_S_RUN) {
2519		DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: not running\n", __func__));
2520		return 0;
2521	} else if (!IF_IS_EMPTY(&ic->ic_pwrsaveq)) {
2522		IF_DEQUEUE(&ic->ic_pwrsaveq, m0);
2523		*nip = (struct ieee80211_node *)m0->m_pkthdr.rcvif;
2524		m0->m_pkthdr.rcvif = NULL;
2525		DPRINTF(sc, RTW_DEBUG_XMIT,
2526		    ("%s: dequeue pwrsave frame\n", __func__));
2527	} else {
2528		IFQ_POLL(&ifp->if_snd, m0);
2529		if (m0 == NULL) {
2530			DPRINTF(sc, RTW_DEBUG_XMIT,
2531			    ("%s: no frame\n", __func__));
2532			return 0;
2533		}
2534		DPRINTF(sc, RTW_DEBUG_XMIT,
2535		    ("%s: dequeue data frame\n", __func__));
2536		IFQ_DEQUEUE(&ifp->if_snd, m0);
2537		ifp->if_opackets++;
2538#if NBPFILTER > 0
2539		if (ifp->if_bpf)
2540			bpf_mtap(ifp->if_bpf, m0);
2541#endif
2542		if ((m0 = ieee80211_encap(ifp, m0, nip)) == NULL) {
2543			DPRINTF(sc, RTW_DEBUG_XMIT,
2544			    ("%s: encap error\n", __func__));
2545			ifp->if_oerrors++;
2546			return -1;
2547		}
2548	}
2549	DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: leave\n", __func__));
2550	*stcp = stc;
2551	*htcp = htc;
2552	*mp = m0;
2553	return 0;
2554}
2555
2556static int
2557rtw_seg_too_short(bus_dmamap_t dmamap)
2558{
2559	int i;
2560	for (i = 0; i < dmamap->dm_nsegs; i++) {
2561		if (dmamap->dm_segs[i].ds_len < 4) {
2562			printf("%s: segment too short\n", __func__);
2563			return 1;
2564		}
2565	}
2566	return 0;
2567}
2568
2569/* TBD factor with atw_start */
2570static struct mbuf *
2571rtw_dmamap_load_txbuf(bus_dma_tag_t dmat, bus_dmamap_t dmam, struct mbuf *chain,
2572    u_int ndescfree, short *ifflagsp, const char *dvname)
2573{
2574	int first, rc;
2575	struct mbuf *m, *m0;
2576
2577	m0 = chain;
2578
2579	/*
2580	 * Load the DMA map.  Copy and try (once) again if the packet
2581	 * didn't fit in the alloted number of segments.
2582	 */
2583	for (first = 1;
2584	     ((rc = bus_dmamap_load_mbuf(dmat, dmam, m0,
2585			  BUS_DMA_WRITE|BUS_DMA_NOWAIT)) != 0 ||
2586	      dmam->dm_nsegs > ndescfree || rtw_seg_too_short(dmam)) && first;
2587	     first = 0) {
2588		if (rc == 0)
2589			bus_dmamap_unload(dmat, dmam);
2590		MGETHDR(m, M_DONTWAIT, MT_DATA);
2591		if (m == NULL) {
2592			printf("%s: unable to allocate Tx mbuf\n",
2593			    dvname);
2594			break;
2595		}
2596		if (m0->m_pkthdr.len > MHLEN) {
2597			MCLGET(m, M_DONTWAIT);
2598			if ((m->m_flags & M_EXT) == 0) {
2599				printf("%s: cannot allocate Tx cluster\n",
2600				    dvname);
2601				m_freem(m);
2602				break;
2603			}
2604		}
2605		m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t));
2606		m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len;
2607		m_freem(m0);
2608		m0 = m;
2609		m = NULL;
2610	}
2611	if (rc != 0) {
2612		printf("%s: cannot load Tx buffer, rc = %d\n", dvname, rc);
2613		m_freem(m0);
2614		return NULL;
2615	} else if (rtw_seg_too_short(dmam)) {
2616		printf("%s: cannot load Tx buffer, segment too short\n",
2617		    dvname);
2618		bus_dmamap_unload(dmat, dmam);
2619		m_freem(m0);
2620		return NULL;
2621	} else if (dmam->dm_nsegs > ndescfree) {
2622		*ifflagsp |= IFF_OACTIVE;
2623		bus_dmamap_unload(dmat, dmam);
2624		m_freem(m0);
2625		return NULL;
2626	}
2627	return m0;
2628}
2629
2630#ifdef RTW_DEBUG
2631static void
2632rtw_print_txdesc(struct rtw_softc *sc, const char *action,
2633    struct rtw_txctl *stx, struct rtw_txdesc_blk *htc, int desc)
2634{
2635	struct rtw_txdesc *htx = &htc->htc_desc[desc];
2636	DPRINTF(sc, RTW_DEBUG_XMIT_DESC, ("%s: %p %s txdesc[%d] ctl0 %#08x "
2637	    "ctl1 %#08x buf %#08x len %#08x\n",
2638	    sc->sc_dev.dv_xname, stx, action, desc,
2639	    le32toh(htx->htx_ctl0),
2640	    le32toh(htx->htx_ctl1), le32toh(htx->htx_buf),
2641	    le32toh(htx->htx_len)));
2642}
2643#endif /* RTW_DEBUG */
2644
2645static void
2646rtw_start(struct ifnet *ifp)
2647{
2648	uint8_t tppoll;
2649	int desc, i, lastdesc, npkt, rate;
2650	uint32_t proto_ctl0, ctl0, ctl1;
2651	bus_dmamap_t		dmamap;
2652	struct ieee80211com	*ic;
2653	struct ieee80211_duration *d0;
2654	struct ieee80211_frame	*wh;
2655	struct ieee80211_node	*ni;
2656	struct mbuf		*m0;
2657	struct rtw_softc	*sc;
2658	struct rtw_txctl_blk	*stc;
2659	struct rtw_txdesc_blk	*htc;
2660	struct rtw_txctl	*stx;
2661	struct rtw_txdesc	*htx;
2662
2663	sc = (struct rtw_softc *)ifp->if_softc;
2664	ic = &sc->sc_ic;
2665
2666	DPRINTF(sc, RTW_DEBUG_XMIT,
2667	    ("%s: enter %s\n", sc->sc_dev.dv_xname, __func__));
2668
2669	/* XXX do real rate control */
2670	proto_ctl0 = RTW_TXCTL0_RTSRATE_1MBPS;
2671
2672	switch (rate = MAX(2, ieee80211_get_rate(ic))) {
2673	case 2:
2674		proto_ctl0 |= RTW_TXCTL0_RATE_1MBPS;
2675		break;
2676	case 4:
2677		proto_ctl0 |= RTW_TXCTL0_RATE_2MBPS;
2678		break;
2679	case 11:
2680		proto_ctl0 |= RTW_TXCTL0_RATE_5MBPS;
2681		break;
2682	case 22:
2683		proto_ctl0 |= RTW_TXCTL0_RATE_11MBPS;
2684		break;
2685	}
2686
2687	if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0)
2688		proto_ctl0 |= RTW_TXCTL0_SPLCP;
2689
2690	for (;;) {
2691		if (rtw_dequeue(ifp, &stc, &htc, &m0, &ni) == -1)
2692			continue;
2693		if (m0 == NULL)
2694			break;
2695		stx = SIMPLEQ_FIRST(&stc->stc_freeq);
2696
2697		dmamap = stx->stx_dmamap;
2698
2699		m0 = rtw_dmamap_load_txbuf(sc->sc_dmat, dmamap, m0,
2700		    htc->htc_nfree, &ifp->if_flags, sc->sc_dev.dv_xname);
2701
2702		if (m0 == NULL || dmamap->dm_nsegs == 0) {
2703			DPRINTF(sc, RTW_DEBUG_XMIT,
2704			    ("%s: fail dmamap load\n", __func__));
2705			goto post_dequeue_err;
2706		}
2707
2708#ifdef RTW_DEBUG
2709		if ((sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) ==
2710		    (IFF_DEBUG|IFF_LINK2)) {
2711			ieee80211_dump_pkt(mtod(m0, uint8_t *),
2712			    (dmamap->dm_nsegs == 1) ? m0->m_pkthdr.len
2713			                            : sizeof(wh),
2714			    rate, 0);
2715		}
2716#endif /* RTW_DEBUG */
2717		ctl0 = proto_ctl0 |
2718		    LSHIFT(m0->m_pkthdr.len, RTW_TXCTL0_TPKTSIZE_MASK);
2719
2720		wh = mtod(m0, struct ieee80211_frame *);
2721
2722		if (ieee80211_compute_duration(wh, m0->m_pkthdr.len,
2723		    ic->ic_flags, ic->ic_fragthreshold,
2724		    rate, &stx->stx_d0, &stx->stx_dn, &npkt,
2725		    (sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) ==
2726		    (IFF_DEBUG|IFF_LINK2)) == -1) {
2727			DPRINTF(sc, RTW_DEBUG_XMIT,
2728			    ("%s: fail compute duration\n", __func__));
2729			goto post_load_err;
2730		}
2731
2732		/* XXX >= ? */
2733		if (m0->m_pkthdr.len > ic->ic_rtsthreshold)
2734			ctl0 |= RTW_TXCTL0_RTSEN;
2735
2736		d0 = &stx->stx_d0;
2737
2738		*(uint16_t*)wh->i_dur = htole16(d0->d_data_dur);
2739
2740		ctl1 = LSHIFT(d0->d_plcp_len, RTW_TXCTL1_LENGTH_MASK) |
2741		    LSHIFT(d0->d_rts_dur, RTW_TXCTL1_RTSDUR_MASK);
2742
2743		if ((d0->d_plcp_svc & IEEE80211_PLCP_SERVICE_LENEXT) != 0)
2744			ctl1 |= RTW_TXCTL1_LENGEXT;
2745
2746		/* TBD fragmentation */
2747
2748		stx->stx_first = htc->htc_next;
2749
2750		rtw_txdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap,
2751		    htc, stx->stx_first, dmamap->dm_nsegs,
2752		    BUS_DMASYNC_PREWRITE);
2753
2754		KASSERT(stx->stx_first < htc->htc_ndesc);
2755
2756		for (i = 0, lastdesc = desc = stx->stx_first;
2757		     i < dmamap->dm_nsegs;
2758		     i++, desc = RTW_NEXT_IDX(htc, desc)) {
2759			if (dmamap->dm_segs[i].ds_len > RTW_TXLEN_LENGTH_MASK) {
2760				DPRINTF(sc, RTW_DEBUG_XMIT_DESC,
2761				    ("%s: seg too long\n", __func__));
2762				goto post_load_err;
2763			}
2764			htx = &htc->htc_desc[desc];
2765			htx->htx_ctl0 = htole32(ctl0);
2766			if (i != 0)
2767				htx->htx_ctl0 |= htole32(RTW_TXCTL0_OWN);
2768			htx->htx_ctl1 = htole32(ctl1);
2769			htx->htx_buf = htole32(dmamap->dm_segs[i].ds_addr);
2770			htx->htx_len = htole32(dmamap->dm_segs[i].ds_len);
2771			lastdesc = desc;
2772#ifdef RTW_DEBUG
2773			rtw_print_txdesc(sc, "load", stx, htc, desc);
2774#endif /* RTW_DEBUG */
2775		}
2776
2777		KASSERT(desc < htc->htc_ndesc);
2778
2779		stx->stx_ni = ni;
2780		stx->stx_mbuf = m0;
2781		stx->stx_last = lastdesc;
2782		htc->htc_desc[stx->stx_last].htx_ctl0 |= htole32(RTW_TXCTL0_LS);
2783		htc->htc_desc[stx->stx_first].htx_ctl0 |=
2784		   htole32(RTW_TXCTL0_FS);
2785
2786#ifdef RTW_DEBUG
2787		rtw_print_txdesc(sc, "FS on", stx, htc, stx->stx_first);
2788		rtw_print_txdesc(sc, "LS on", stx, htc, stx->stx_last);
2789#endif /* RTW_DEBUG */
2790
2791		htc->htc_nfree -= dmamap->dm_nsegs;
2792		htc->htc_next = desc;
2793
2794		rtw_txdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap,
2795		    htc, stx->stx_first, dmamap->dm_nsegs,
2796		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
2797
2798		htc->htc_desc[stx->stx_first].htx_ctl0 |=
2799		    htole32(RTW_TXCTL0_OWN);
2800
2801#ifdef RTW_DEBUG
2802		rtw_print_txdesc(sc, "OWN on", stx, htc, stx->stx_first);
2803#endif /* RTW_DEBUG */
2804
2805		rtw_txdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap,
2806		    htc, stx->stx_first, 1,
2807		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
2808
2809		SIMPLEQ_REMOVE_HEAD(&stc->stc_freeq, stx_q);
2810		SIMPLEQ_INSERT_TAIL(&stc->stc_dirtyq, stx, stx_q);
2811
2812		stc->stc_tx_timer = 5;
2813		ifp->if_timer = 1;
2814
2815		tppoll = RTW_READ8(&sc->sc_regs, RTW_TPPOLL);
2816
2817		/* TBD poke other queues. */
2818		RTW_WRITE8(&sc->sc_regs, RTW_TPPOLL, tppoll | RTW_TPPOLL_NPQ);
2819		RTW_SYNC(&sc->sc_regs, RTW_TPPOLL, RTW_TPPOLL);
2820	}
2821	DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: leave\n", __func__));
2822	return;
2823post_load_err:
2824	bus_dmamap_unload(sc->sc_dmat, dmamap);
2825	m_freem(m0);
2826post_dequeue_err:
2827	ieee80211_release_node(&sc->sc_ic, ni);
2828	return;
2829}
2830
2831static void
2832rtw_watchdog(struct ifnet *ifp)
2833{
2834	int pri;
2835	struct rtw_softc *sc;
2836	struct rtw_txctl_blk *stc;
2837
2838	sc = ifp->if_softc;
2839
2840	ifp->if_timer = 0;
2841
2842	if ((sc->sc_flags & RTW_F_ENABLED) == 0)
2843		return;
2844
2845	for (pri = 0; pri < RTW_NTXPRI; pri++) {
2846		stc = &sc->sc_txctl_blk[pri];
2847
2848		if (stc->stc_tx_timer == 0)
2849			continue;
2850
2851		if (--stc->stc_tx_timer == 0) {
2852			if (SIMPLEQ_EMPTY(&stc->stc_dirtyq))
2853				continue;
2854			printf("%s: transmit timeout, priority %d\n",
2855			    ifp->if_xname, pri);
2856			ifp->if_oerrors++;
2857			/* XXX do more? */
2858			rtw_intr_tx(sc, 0);
2859			rtw_txdescs_reset(sc);
2860			rtw_start(ifp);
2861		} else
2862			ifp->if_timer = 1;
2863	}
2864	ieee80211_watchdog(ifp);
2865	return;
2866}
2867
2868static void
2869rtw_start_beacon(struct rtw_softc *sc, int enable)
2870{
2871	/* TBD */
2872	return;
2873}
2874
2875static void
2876rtw_next_scan(void *arg)
2877{
2878	struct ieee80211com *ic = arg;
2879	int s;
2880
2881	/* don't call rtw_start w/o network interrupts blocked */
2882	s = splnet();
2883	if (ic->ic_state == IEEE80211_S_SCAN)
2884		ieee80211_next_scan(ic);
2885	splx(s);
2886}
2887
2888static void
2889rtw_join_bss(struct rtw_softc *sc, uint8_t *bssid, enum ieee80211_opmode opmode,
2890    uint16_t intval0)
2891{
2892	uint16_t bcnitv, intval;
2893	int i;
2894	struct rtw_regs *regs = &sc->sc_regs;
2895
2896	for (i = 0; i < IEEE80211_ADDR_LEN; i++)
2897		RTW_WRITE8(regs, RTW_BSSID + i, bssid[i]);
2898
2899	RTW_SYNC(regs, RTW_BSSID16, RTW_BSSID32);
2900
2901	rtw_set_access(sc, RTW_ACCESS_CONFIG);
2902
2903	intval = MIN(intval0, PRESHIFT(RTW_BCNITV_BCNITV_MASK));
2904
2905	bcnitv = RTW_READ16(regs, RTW_BCNITV) & ~RTW_BCNITV_BCNITV_MASK;
2906	bcnitv |= LSHIFT(intval, RTW_BCNITV_BCNITV_MASK);
2907	RTW_WRITE16(regs, RTW_BCNITV, bcnitv);
2908	/* magic from Linux */
2909	RTW_WRITE16(regs, RTW_ATIMWND, LSHIFT(1, RTW_ATIMWND_ATIMWND));
2910	RTW_WRITE16(regs, RTW_ATIMTRITV, LSHIFT(2, RTW_ATIMTRITV_ATIMTRITV));
2911
2912	rtw_set_nettype(sc, opmode);
2913
2914	rtw_set_access(sc, RTW_ACCESS_NONE);
2915
2916	/* TBD WEP */
2917	RTW_WRITE8(regs, RTW_SCR, 0);
2918
2919	rtw_io_enable(regs, RTW_CR_RE | RTW_CR_TE, 1);
2920}
2921
2922/* Synchronize the hardware state with the software state. */
2923static int
2924rtw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
2925{
2926	struct ifnet *ifp = &ic->ic_if;
2927	struct rtw_softc *sc = ifp->if_softc;
2928	enum ieee80211_state ostate;
2929	int error;
2930
2931	ostate = ic->ic_state;
2932
2933	if (nstate == IEEE80211_S_INIT) {
2934		callout_stop(&sc->sc_scan_ch);
2935		sc->sc_cur_chan = IEEE80211_CHAN_ANY;
2936		rtw_start_beacon(sc, 0);
2937		return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg);
2938	}
2939
2940	if (ostate == IEEE80211_S_INIT && nstate != IEEE80211_S_INIT)
2941		rtw_pwrstate(sc, RTW_ON);
2942
2943	if ((error = rtw_tune(sc)) != 0)
2944		return error;
2945
2946	switch (nstate) {
2947	case IEEE80211_S_ASSOC:
2948		rtw_join_bss(sc, ic->ic_bss->ni_bssid, ic->ic_opmode,
2949		    ic->ic_bss->ni_intval);
2950		break;
2951	case IEEE80211_S_INIT:
2952		panic("%s: unexpected state IEEE80211_S_INIT\n", __func__);
2953		break;
2954	case IEEE80211_S_SCAN:
2955		if (ostate != IEEE80211_S_SCAN) {
2956			(void)memset(ic->ic_bss->ni_bssid, 0,
2957			    IEEE80211_ADDR_LEN);
2958			rtw_join_bss(sc, ic->ic_bss->ni_bssid, ic->ic_opmode,
2959			    ic->ic_bss->ni_intval);
2960		}
2961
2962		callout_reset(&sc->sc_scan_ch, rtw_dwelltime * hz / 1000,
2963		    rtw_next_scan, ic);
2964
2965		break;
2966	case IEEE80211_S_RUN:
2967		if (ic->ic_opmode == IEEE80211_M_STA)
2968			break;
2969		/*FALLTHROUGH*/
2970	case IEEE80211_S_AUTH:
2971#if 0
2972		rtw_write_bcn_thresh(sc);
2973		rtw_write_ssid(sc);
2974		rtw_write_sup_rates(sc);
2975#endif
2976		if (ic->ic_opmode == IEEE80211_M_AHDEMO ||
2977		    ic->ic_opmode == IEEE80211_M_MONITOR)
2978			break;
2979
2980		/* TBD set listen interval */
2981
2982#if 0
2983		rtw_tsf(sc);
2984#endif
2985		break;
2986	}
2987
2988	if (nstate != IEEE80211_S_SCAN)
2989		callout_stop(&sc->sc_scan_ch);
2990
2991	if (nstate == IEEE80211_S_RUN &&
2992	    (ic->ic_opmode == IEEE80211_M_HOSTAP ||
2993	     ic->ic_opmode == IEEE80211_M_IBSS))
2994		rtw_start_beacon(sc, 1);
2995	else
2996		rtw_start_beacon(sc, 0);
2997
2998	return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg);
2999}
3000
3001static void
3002rtw_recv_beacon(struct rtw_softc *sc, struct mbuf *m,
3003    struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp)
3004{
3005	(*sc->sc_mtbl.mt_recv_mgmt)(&sc->sc_ic, m, ni, subtype, rssi, rstamp);
3006	return;
3007}
3008
3009static void
3010rtw_recv_mgmt(struct ieee80211com *ic, struct mbuf *m,
3011    struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp)
3012{
3013	struct rtw_softc *sc = (struct rtw_softc*)ic->ic_softc;
3014
3015	switch (subtype) {
3016	case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
3017		/* do nothing: hardware answers probe request XXX */
3018		break;
3019	case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
3020	case IEEE80211_FC0_SUBTYPE_BEACON:
3021		rtw_recv_beacon(sc, m, ni, subtype, rssi, rstamp);
3022		break;
3023	default:
3024		(*sc->sc_mtbl.mt_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp);
3025		break;
3026	}
3027	return;
3028}
3029
3030static struct ieee80211_node *
3031rtw_node_alloc(struct ieee80211com *ic)
3032{
3033	struct rtw_softc *sc = (struct rtw_softc *)ic->ic_if.if_softc;
3034	struct ieee80211_node *ni = (*sc->sc_mtbl.mt_node_alloc)(ic);
3035
3036	DPRINTF(sc, RTW_DEBUG_NODE,
3037	    ("%s: alloc node %p\n", sc->sc_dev.dv_xname, ni));
3038	return ni;
3039}
3040
3041static void
3042rtw_node_free(struct ieee80211com *ic, struct ieee80211_node *ni)
3043{
3044	struct rtw_softc *sc = (struct rtw_softc *)ic->ic_if.if_softc;
3045
3046	DPRINTF(sc, RTW_DEBUG_NODE,
3047	    ("%s: freeing node %p %s\n", sc->sc_dev.dv_xname, ni,
3048	    ether_sprintf(ni->ni_bssid)));
3049	(*sc->sc_mtbl.mt_node_free)(ic, ni);
3050}
3051
3052static int
3053rtw_media_change(struct ifnet *ifp)
3054{
3055	int error;
3056
3057	error = ieee80211_media_change(ifp);
3058	if (error == ENETRESET) {
3059		if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
3060		    (IFF_RUNNING|IFF_UP))
3061			rtw_init(ifp);		/* XXX lose error */
3062		error = 0;
3063	}
3064	return error;
3065}
3066
3067static void
3068rtw_media_status(struct ifnet *ifp, struct ifmediareq *imr)
3069{
3070	struct rtw_softc *sc = ifp->if_softc;
3071
3072	if ((sc->sc_flags & RTW_F_ENABLED) == 0) {
3073		imr->ifm_active = IFM_IEEE80211 | IFM_NONE;
3074		imr->ifm_status = 0;
3075		return;
3076	}
3077	ieee80211_media_status(ifp, imr);
3078}
3079
3080void
3081rtw_power(int why, void *arg)
3082{
3083	struct rtw_softc *sc = arg;
3084	struct ifnet *ifp = &sc->sc_ic.ic_if;
3085	int s;
3086
3087	DPRINTF(sc, RTW_DEBUG_PWR,
3088	    ("%s: rtw_power(%d,)\n", sc->sc_dev.dv_xname, why));
3089
3090	s = splnet();
3091	switch (why) {
3092	case PWR_STANDBY:
3093		/* XXX do nothing. */
3094		break;
3095	case PWR_SUSPEND:
3096		rtw_stop(ifp, 0);
3097		if (sc->sc_power != NULL)
3098			(*sc->sc_power)(sc, why);
3099		break;
3100	case PWR_RESUME:
3101		if (ifp->if_flags & IFF_UP) {
3102			if (sc->sc_power != NULL)
3103				(*sc->sc_power)(sc, why);
3104			rtw_init(ifp);
3105		}
3106		break;
3107	case PWR_SOFTSUSPEND:
3108	case PWR_SOFTSTANDBY:
3109	case PWR_SOFTRESUME:
3110		break;
3111	}
3112	splx(s);
3113}
3114
3115/* rtw_shutdown: make sure the interface is stopped at reboot time. */
3116void
3117rtw_shutdown(void *arg)
3118{
3119	struct rtw_softc *sc = arg;
3120
3121	rtw_stop(&sc->sc_ic.ic_if, 1);
3122}
3123
3124static __inline void
3125rtw_setifprops(struct ifnet *ifp, const char *dvname, void *softc)
3126{
3127	(void)memcpy(ifp->if_xname, dvname, IFNAMSIZ);
3128	ifp->if_softc = softc;
3129	ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST |
3130	    IFF_NOTRAILERS;
3131	ifp->if_ioctl = rtw_ioctl;
3132	ifp->if_start = rtw_start;
3133	ifp->if_watchdog = rtw_watchdog;
3134	ifp->if_init = rtw_init;
3135	ifp->if_stop = rtw_stop;
3136}
3137
3138static __inline void
3139rtw_set80211props(struct ieee80211com *ic)
3140{
3141	int nrate;
3142	ic->ic_phytype = IEEE80211_T_DS;
3143	ic->ic_opmode = IEEE80211_M_STA;
3144	ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_IBSS |
3145	    IEEE80211_C_HOSTAP | IEEE80211_C_MONITOR | IEEE80211_C_WEP;
3146
3147	nrate = 0;
3148	ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] =
3149	    IEEE80211_RATE_BASIC | 2;
3150	ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] =
3151	    IEEE80211_RATE_BASIC | 4;
3152	ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 11;
3153	ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 22;
3154	ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = nrate;
3155}
3156
3157static __inline void
3158rtw_set80211methods(struct rtw_mtbl *mtbl, struct ieee80211com *ic)
3159{
3160	mtbl->mt_newstate = ic->ic_newstate;
3161	ic->ic_newstate = rtw_newstate;
3162
3163	mtbl->mt_recv_mgmt = ic->ic_recv_mgmt;
3164	ic->ic_recv_mgmt = rtw_recv_mgmt;
3165
3166	mtbl->mt_node_free = ic->ic_node_free;
3167	ic->ic_node_free = rtw_node_free;
3168
3169	mtbl->mt_node_alloc = ic->ic_node_alloc;
3170	ic->ic_node_alloc = rtw_node_alloc;
3171}
3172
3173static __inline void
3174rtw_establish_hooks(struct rtw_hooks *hooks, const char *dvname,
3175    void *arg)
3176{
3177	/*
3178	 * Make sure the interface is shutdown during reboot.
3179	 */
3180	hooks->rh_shutdown = shutdownhook_establish(rtw_shutdown, arg);
3181	if (hooks->rh_shutdown == NULL)
3182		printf("%s: WARNING: unable to establish shutdown hook\n",
3183		    dvname);
3184
3185	/*
3186	 * Add a suspend hook to make sure we come back up after a
3187	 * resume.
3188	 */
3189	hooks->rh_power = powerhook_establish(rtw_power, arg);
3190	if (hooks->rh_power == NULL)
3191		printf("%s: WARNING: unable to establish power hook\n",
3192		    dvname);
3193}
3194
3195static __inline void
3196rtw_disestablish_hooks(struct rtw_hooks *hooks, const char *dvname,
3197    void *arg)
3198{
3199	if (hooks->rh_shutdown != NULL)
3200		shutdownhook_disestablish(hooks->rh_shutdown);
3201
3202	if (hooks->rh_power != NULL)
3203		powerhook_disestablish(hooks->rh_power);
3204}
3205
3206static __inline void
3207rtw_init_radiotap(struct rtw_softc *sc)
3208{
3209	memset(&sc->sc_rxtapu, 0, sizeof(sc->sc_rxtapu));
3210	sc->sc_rxtap.rr_ihdr.it_len = sizeof(sc->sc_rxtapu);
3211	sc->sc_rxtap.rr_ihdr.it_present = RTW_RX_RADIOTAP_PRESENT;
3212
3213	memset(&sc->sc_txtapu, 0, sizeof(sc->sc_txtapu));
3214	sc->sc_txtap.rt_ihdr.it_len = sizeof(sc->sc_txtapu);
3215	sc->sc_txtap.rt_ihdr.it_present = RTW_TX_RADIOTAP_PRESENT;
3216}
3217
3218static int
3219rtw_txctl_blk_setup(struct rtw_txctl_blk *stc, u_int qlen)
3220{
3221	SIMPLEQ_INIT(&stc->stc_dirtyq);
3222	SIMPLEQ_INIT(&stc->stc_freeq);
3223	stc->stc_ndesc = qlen;
3224	stc->stc_desc = malloc(qlen * sizeof(*stc->stc_desc), M_DEVBUF,
3225	    M_NOWAIT);
3226	if (stc->stc_desc == NULL)
3227		return ENOMEM;
3228	return 0;
3229}
3230
3231static void
3232rtw_txctl_blk_cleanup_all(struct rtw_softc *sc)
3233{
3234	int pri;
3235	struct rtw_txctl_blk *stc;
3236
3237	for (pri = 0; pri < RTW_NTXPRI; pri++) {
3238		stc = &sc->sc_txctl_blk[pri];
3239		free(stc->stc_desc, M_DEVBUF);
3240		stc->stc_desc = NULL;
3241	}
3242}
3243
3244static int
3245rtw_txctl_blk_setup_all(struct rtw_softc *sc)
3246{
3247	int pri, rc = 0;
3248	int qlen[RTW_NTXPRI] =
3249	     {RTW_TXQLENLO, RTW_TXQLENMD, RTW_TXQLENHI, RTW_TXQLENBCN};
3250
3251	for (pri = 0; pri < RTW_NTXPRI; pri++) {
3252		rc = rtw_txctl_blk_setup(&sc->sc_txctl_blk[pri], qlen[pri]);
3253		if (rc != 0)
3254			break;
3255	}
3256	return rc;
3257}
3258
3259static void
3260rtw_txdesc_blk_setup(struct rtw_txdesc_blk *htc, struct rtw_txdesc *desc,
3261    u_int ndesc, bus_addr_t ofs, bus_addr_t physbase)
3262{
3263	htc->htc_ndesc = ndesc;
3264	htc->htc_desc = desc;
3265	htc->htc_physbase = physbase;
3266	htc->htc_ofs = ofs;
3267
3268	(void)memset(htc->htc_desc, 0,
3269	    sizeof(htc->htc_desc[0]) * htc->htc_ndesc);
3270
3271	rtw_txdesc_blk_reset(htc);
3272}
3273
3274static void
3275rtw_txdesc_blk_setup_all(struct rtw_softc *sc)
3276{
3277	rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRILO],
3278	    &sc->sc_descs->hd_txlo[0], RTW_NTXDESCLO,
3279	    RTW_RING_OFFSET(hd_txlo), RTW_RING_BASE(sc, hd_txlo));
3280
3281	rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIMD],
3282	    &sc->sc_descs->hd_txmd[0], RTW_NTXDESCMD,
3283	    RTW_RING_OFFSET(hd_txmd), RTW_RING_BASE(sc, hd_txmd));
3284
3285	rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIHI],
3286	    &sc->sc_descs->hd_txhi[0], RTW_NTXDESCHI,
3287	    RTW_RING_OFFSET(hd_txhi), RTW_RING_BASE(sc, hd_txhi));
3288
3289	rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIBCN],
3290	    &sc->sc_descs->hd_bcn[0], RTW_NTXDESCBCN,
3291	    RTW_RING_OFFSET(hd_bcn), RTW_RING_BASE(sc, hd_bcn));
3292}
3293
3294static struct rtw_rf *
3295rtw_rf_attach(struct rtw_softc *sc, enum rtw_rfchipid rfchipid,
3296    rtw_rf_write_t rf_write, int digphy)
3297{
3298	struct rtw_rf *rf;
3299
3300	switch (rfchipid) {
3301	case RTW_RFCHIPID_MAXIM:
3302		rf = rtw_max2820_create(&sc->sc_regs, rf_write, 0);
3303		sc->sc_pwrstate_cb = rtw_maxim_pwrstate;
3304		break;
3305	case RTW_RFCHIPID_PHILIPS:
3306		rf = rtw_sa2400_create(&sc->sc_regs, rf_write, digphy);
3307		sc->sc_pwrstate_cb = rtw_philips_pwrstate;
3308		break;
3309	case RTW_RFCHIPID_RFMD:
3310		/* XXX RFMD has no RF constructor */
3311		sc->sc_pwrstate_cb = rtw_rfmd_pwrstate;
3312		/*FALLTHROUGH*/
3313	default:
3314		return NULL;
3315	}
3316	rf->rf_continuous_tx_cb =
3317	    (rtw_continuous_tx_cb_t)rtw_continuous_tx_enable;
3318	rf->rf_continuous_tx_arg = (void *)sc;
3319	return rf;
3320}
3321
3322/* Revision C and later use a different PHY delay setting than
3323 * revisions A and B.
3324 */
3325static u_int8_t
3326rtw_check_phydelay(struct rtw_regs *regs, u_int32_t rcr0)
3327{
3328#define REVAB (RTW_RCR_MXDMA_UNLIMITED | RTW_RCR_AICV)
3329#define REVC (REVAB | RTW_RCR_RXFTH_WHOLE)
3330
3331	u_int8_t phydelay = LSHIFT(0x6, RTW_PHYDELAY_PHYDELAY);
3332
3333	RTW_WRITE(regs, RTW_RCR, REVAB);
3334	RTW_WBW(regs, RTW_RCR, RTW_RCR);
3335	RTW_WRITE(regs, RTW_RCR, REVC);
3336
3337	RTW_WBR(regs, RTW_RCR, RTW_RCR);
3338	if ((RTW_READ(regs, RTW_RCR) & REVC) == REVC)
3339		phydelay |= RTW_PHYDELAY_REVC_MAGIC;
3340
3341	RTW_WRITE(regs, RTW_RCR, rcr0);	/* restore RCR */
3342	RTW_SYNC(regs, RTW_RCR, RTW_RCR);
3343
3344	return phydelay;
3345#undef REVC
3346}
3347
3348void
3349rtw_attach(struct rtw_softc *sc)
3350{
3351	rtw_rf_write_t rf_write;
3352	struct rtw_txctl_blk *stc;
3353	int pri, rc, vers;
3354
3355#if 0
3356	CASSERT(RTW_DESC_ALIGNMENT % sizeof(struct rtw_txdesc) == 0,
3357	    "RTW_DESC_ALIGNMENT is not a multiple of "
3358	    "sizeof(struct rtw_txdesc)");
3359
3360	CASSERT(RTW_DESC_ALIGNMENT % sizeof(struct rtw_rxdesc) == 0,
3361	    "RTW_DESC_ALIGNMENT is not a multiple of "
3362	    "sizeof(struct rtw_rxdesc)");
3363
3364	CASSERT(RTW_DESC_ALIGNMENT % RTW_MAXPKTSEGS == 0,
3365	    "RTW_DESC_ALIGNMENT is not a multiple of RTW_MAXPKTSEGS");
3366#endif
3367
3368	NEXT_ATTACH_STATE(sc, DETACHED);
3369
3370	switch (RTW_READ(&sc->sc_regs, RTW_TCR) & RTW_TCR_HWVERID_MASK) {
3371	case RTW_TCR_HWVERID_F:
3372		vers = 'F';
3373		rf_write = rtw_rf_hostwrite;
3374		break;
3375	case RTW_TCR_HWVERID_D:
3376		vers = 'D';
3377		if (rtw_host_rfio)
3378			rf_write = rtw_rf_hostwrite;
3379		else
3380			rf_write = rtw_rf_macwrite;
3381		break;
3382	default:
3383		vers = '?';
3384		rf_write = rtw_rf_macwrite;
3385		break;
3386	}
3387	printf("%s: hardware version %c\n", sc->sc_dev.dv_xname, vers);
3388
3389	rc = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct rtw_descs),
3390	    RTW_DESC_ALIGNMENT, 0, &sc->sc_desc_segs, 1, &sc->sc_desc_nsegs,
3391	    0);
3392
3393	if (rc != 0) {
3394		printf("%s: could not allocate hw descriptors, error %d\n",
3395		     sc->sc_dev.dv_xname, rc);
3396		goto err;
3397	}
3398
3399	NEXT_ATTACH_STATE(sc, FINISH_DESC_ALLOC);
3400
3401	rc = bus_dmamem_map(sc->sc_dmat, &sc->sc_desc_segs,
3402	    sc->sc_desc_nsegs, sizeof(struct rtw_descs),
3403	    (caddr_t*)&sc->sc_descs, BUS_DMA_COHERENT);
3404
3405	if (rc != 0) {
3406		printf("%s: could not map hw descriptors, error %d\n",
3407		    sc->sc_dev.dv_xname, rc);
3408		goto err;
3409	}
3410	NEXT_ATTACH_STATE(sc, FINISH_DESC_MAP);
3411
3412	rc = bus_dmamap_create(sc->sc_dmat, sizeof(struct rtw_descs), 1,
3413	    sizeof(struct rtw_descs), 0, 0, &sc->sc_desc_dmamap);
3414
3415	if (rc != 0) {
3416		printf("%s: could not create DMA map for hw descriptors, "
3417		    "error %d\n", sc->sc_dev.dv_xname, rc);
3418		goto err;
3419	}
3420	NEXT_ATTACH_STATE(sc, FINISH_DESCMAP_CREATE);
3421
3422	rc = bus_dmamap_load(sc->sc_dmat, sc->sc_desc_dmamap, sc->sc_descs,
3423	    sizeof(struct rtw_descs), NULL, 0);
3424
3425	if (rc != 0) {
3426		printf("%s: could not load DMA map for hw descriptors, "
3427		    "error %d\n", sc->sc_dev.dv_xname, rc);
3428		goto err;
3429	}
3430	NEXT_ATTACH_STATE(sc, FINISH_DESCMAP_LOAD);
3431
3432	if (rtw_txctl_blk_setup_all(sc) != 0)
3433		goto err;
3434	NEXT_ATTACH_STATE(sc, FINISH_TXCTLBLK_SETUP);
3435
3436	rtw_txdesc_blk_setup_all(sc);
3437
3438	NEXT_ATTACH_STATE(sc, FINISH_TXDESCBLK_SETUP);
3439
3440	sc->sc_rxdesc = &sc->sc_descs->hd_rx[0];
3441
3442	rtw_rxctls_setup(&sc->sc_rxctl[0]);
3443
3444	for (pri = 0; pri < RTW_NTXPRI; pri++) {
3445		stc = &sc->sc_txctl_blk[pri];
3446
3447		if ((rc = rtw_txdesc_dmamaps_create(sc->sc_dmat,
3448		    &stc->stc_desc[0], stc->stc_ndesc)) != 0) {
3449			printf("%s: could not load DMA map for "
3450			    "hw tx descriptors, error %d\n",
3451			    sc->sc_dev.dv_xname, rc);
3452			goto err;
3453		}
3454	}
3455
3456	NEXT_ATTACH_STATE(sc, FINISH_TXMAPS_CREATE);
3457	if ((rc = rtw_rxdesc_dmamaps_create(sc->sc_dmat, &sc->sc_rxctl[0],
3458	                                    RTW_RXQLEN)) != 0) {
3459		printf("%s: could not load DMA map for hw rx descriptors, "
3460		    "error %d\n", sc->sc_dev.dv_xname, rc);
3461		goto err;
3462	}
3463	NEXT_ATTACH_STATE(sc, FINISH_RXMAPS_CREATE);
3464
3465	/* Reset the chip to a known state. */
3466	if (rtw_reset(sc) != 0)
3467		goto err;
3468	NEXT_ATTACH_STATE(sc, FINISH_RESET);
3469
3470	sc->sc_rcr = RTW_READ(&sc->sc_regs, RTW_RCR);
3471
3472	if ((sc->sc_rcr & RTW_RCR_9356SEL) != 0)
3473		sc->sc_flags |= RTW_F_9356SROM;
3474
3475	if (rtw_srom_read(&sc->sc_regs, sc->sc_flags, &sc->sc_srom,
3476	    sc->sc_dev.dv_xname) != 0)
3477		goto err;
3478
3479	NEXT_ATTACH_STATE(sc, FINISH_READ_SROM);
3480
3481	if (rtw_srom_parse(&sc->sc_srom, &sc->sc_flags, &sc->sc_csthr,
3482	    &sc->sc_rfchipid, &sc->sc_rcr, &sc->sc_locale,
3483	    sc->sc_dev.dv_xname) != 0) {
3484		printf("%s: attach failed, malformed serial ROM\n",
3485		    sc->sc_dev.dv_xname);
3486		goto err;
3487	}
3488
3489	printf("%s: %s PHY\n", sc->sc_dev.dv_xname,
3490	    ((sc->sc_flags & RTW_F_DIGPHY) != 0) ? "digital" : "analog");
3491
3492	printf("%s: CS threshold %u\n", sc->sc_dev.dv_xname, sc->sc_csthr);
3493
3494	NEXT_ATTACH_STATE(sc, FINISH_PARSE_SROM);
3495
3496	sc->sc_rf = rtw_rf_attach(sc, sc->sc_rfchipid, rf_write,
3497	    sc->sc_flags & RTW_F_DIGPHY);
3498
3499	if (sc->sc_rf == NULL) {
3500		printf("%s: attach failed, could not attach RF\n",
3501		    sc->sc_dev.dv_xname);
3502		goto err;
3503	}
3504
3505#if 0
3506	if (rtw_identify_rf(&sc->sc_regs, &sc->sc_rftype,
3507	    sc->sc_dev.dv_xname) != 0) {
3508		printf("%s: attach failed, unknown RF unidentified\n",
3509		    sc->sc_dev.dv_xname);
3510		goto err;
3511	}
3512#endif
3513
3514	NEXT_ATTACH_STATE(sc, FINISH_RF_ATTACH);
3515
3516	sc->sc_phydelay = rtw_check_phydelay(&sc->sc_regs, sc->sc_rcr);
3517
3518	RTW_DPRINTF(RTW_DEBUG_ATTACH,
3519	    ("%s: PHY delay %d\n", sc->sc_dev.dv_xname, sc->sc_phydelay));
3520
3521	if (sc->sc_locale == RTW_LOCALE_UNKNOWN)
3522		rtw_identify_country(&sc->sc_regs, &sc->sc_locale,
3523		    sc->sc_dev.dv_xname);
3524
3525	rtw_init_channels(sc->sc_locale, &sc->sc_ic.ic_channels,
3526	    sc->sc_dev.dv_xname);
3527
3528	if (rtw_identify_sta(&sc->sc_regs, &sc->sc_ic.ic_myaddr,
3529	    sc->sc_dev.dv_xname) != 0)
3530		goto err;
3531	NEXT_ATTACH_STATE(sc, FINISH_ID_STA);
3532
3533	rtw_setifprops(&sc->sc_if, sc->sc_dev.dv_xname, (void*)sc);
3534
3535	IFQ_SET_READY(&sc->sc_if.if_snd);
3536
3537	rtw_set80211props(&sc->sc_ic);
3538
3539	/*
3540	 * Call MI attach routines.
3541	 */
3542	if_attach(&sc->sc_if);
3543	ieee80211_ifattach(&sc->sc_if);
3544
3545	rtw_set80211methods(&sc->sc_mtbl, &sc->sc_ic);
3546
3547	/* possibly we should fill in our own sc_send_prresp, since
3548	 * the RTL8180 is probably sending probe responses in ad hoc
3549	 * mode.
3550	 */
3551
3552	/* complete initialization */
3553	ieee80211_media_init(&sc->sc_if, rtw_media_change, rtw_media_status);
3554	callout_init(&sc->sc_scan_ch);
3555
3556#if NBPFILTER > 0
3557	bpfattach2(&sc->sc_if, DLT_IEEE802_11_RADIO,
3558	    sizeof(struct ieee80211_frame) + 64, &sc->sc_radiobpf);
3559#endif
3560
3561	rtw_establish_hooks(&sc->sc_hooks, sc->sc_dev.dv_xname, (void*)sc);
3562
3563	rtw_init_radiotap(sc);
3564
3565	NEXT_ATTACH_STATE(sc, FINISHED);
3566
3567	return;
3568err:
3569	rtw_detach(sc);
3570	return;
3571}
3572
3573int
3574rtw_detach(struct rtw_softc *sc)
3575{
3576	int pri;
3577
3578	switch (sc->sc_attach_state) {
3579	case FINISHED:
3580		rtw_stop(&sc->sc_if, 1);
3581
3582		rtw_disestablish_hooks(&sc->sc_hooks, sc->sc_dev.dv_xname,
3583		    (void*)sc);
3584		callout_stop(&sc->sc_scan_ch);
3585		ieee80211_ifdetach(&sc->sc_if);
3586		if_detach(&sc->sc_if);
3587		break;
3588	case FINISH_ID_STA:
3589	case FINISH_RF_ATTACH:
3590		rtw_rf_destroy(sc->sc_rf);
3591		sc->sc_rf = NULL;
3592		/*FALLTHROUGH*/
3593	case FINISH_PARSE_SROM:
3594	case FINISH_READ_SROM:
3595		rtw_srom_free(&sc->sc_srom);
3596		/*FALLTHROUGH*/
3597	case FINISH_RESET:
3598	case FINISH_RXMAPS_CREATE:
3599		rtw_rxdesc_dmamaps_destroy(sc->sc_dmat, &sc->sc_rxctl[0],
3600		    RTW_RXQLEN);
3601		/*FALLTHROUGH*/
3602	case FINISH_TXMAPS_CREATE:
3603		for (pri = 0; pri < RTW_NTXPRI; pri++) {
3604			rtw_txdesc_dmamaps_destroy(sc->sc_dmat,
3605			    sc->sc_txctl_blk[pri].stc_desc,
3606			    sc->sc_txctl_blk[pri].stc_ndesc);
3607		}
3608		/*FALLTHROUGH*/
3609	case FINISH_TXDESCBLK_SETUP:
3610	case FINISH_TXCTLBLK_SETUP:
3611		rtw_txctl_blk_cleanup_all(sc);
3612		/*FALLTHROUGH*/
3613	case FINISH_DESCMAP_LOAD:
3614		bus_dmamap_unload(sc->sc_dmat, sc->sc_desc_dmamap);
3615		/*FALLTHROUGH*/
3616	case FINISH_DESCMAP_CREATE:
3617		bus_dmamap_destroy(sc->sc_dmat, sc->sc_desc_dmamap);
3618		/*FALLTHROUGH*/
3619	case FINISH_DESC_MAP:
3620		bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_descs,
3621		    sizeof(struct rtw_descs));
3622		/*FALLTHROUGH*/
3623	case FINISH_DESC_ALLOC:
3624		bus_dmamem_free(sc->sc_dmat, &sc->sc_desc_segs,
3625		    sc->sc_desc_nsegs);
3626		/*FALLTHROUGH*/
3627	case DETACHED:
3628		NEXT_ATTACH_STATE(sc, DETACHED);
3629		break;
3630	}
3631	return 0;
3632}
3633
3634int
3635rtw_activate(struct device *self, enum devact act)
3636{
3637	struct rtw_softc *sc = (struct rtw_softc *)self;
3638	int rc = 0, s;
3639
3640	s = splnet();
3641	switch (act) {
3642	case DVACT_ACTIVATE:
3643		rc = EOPNOTSUPP;
3644		break;
3645
3646	case DVACT_DEACTIVATE:
3647		if_deactivate(&sc->sc_ic.ic_if);
3648		break;
3649	}
3650	splx(s);
3651	return rc;
3652}
3653