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