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