1/* $NetBSD: rtw.c,v 1.124 2016/09/15 21:45:37 jdolecek Exp $ */
2/*-
3 * Copyright (c) 2004, 2005, 2006, 2007 David Young. All rights
4 * reserved.
5 *
6 * Programmed for NetBSD by David Young.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY David Young ``AS IS'' AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David
21 * Young BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
23 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
28 * OF SUCH DAMAGE.
29 */
30/*
31 * Device driver for the Realtek RTL8180 802.11 MAC/BBP.
32 */
33
34#include <sys/cdefs.h>
35__KERNEL_RCSID(0, "$NetBSD: rtw.c,v 1.124 2016/09/15 21:45:37 jdolecek Exp $");
36
37
38#include <sys/param.h>
39#include <sys/sysctl.h>
40#include <sys/systm.h>
41#include <sys/callout.h>
42#include <sys/mbuf.h>
43#include <sys/malloc.h>
44#include <sys/kernel.h>
45#include <sys/time.h>
46#include <sys/types.h>
47#include <sys/device.h>
48#include <sys/sockio.h>
49
50#include <machine/endian.h>
51#include <sys/bus.h>
52#include <sys/intr.h> /* splnet */
53
54#include <net/if.h>
55#include <net/if_media.h>
56#include <net/if_ether.h>
57
58#include <net80211/ieee80211_netbsd.h>
59#include <net80211/ieee80211_var.h>
60#include <net80211/ieee80211_radiotap.h>
61
62#include <net/bpf.h>
63
64#include <dev/ic/rtwreg.h>
65#include <dev/ic/rtwvar.h>
66#include <dev/ic/rtwphyio.h>
67#include <dev/ic/rtwphy.h>
68
69#include <dev/ic/smc93cx6var.h>
70
71static int rtw_rfprog_fallback = 0;
72static int rtw_host_rfio = 0;
73
74#ifdef RTW_DEBUG
75int rtw_debug = 0;
76static int rtw_rxbufs_limit = RTW_RXQLEN;
77#endif /* RTW_DEBUG */
78
79#define NEXT_ATTACH_STATE(sc, state) do { \
80 DPRINTF(sc, RTW_DEBUG_ATTACH, \
81 ("%s: attach state %s\n", __func__, #state)); \
82 sc->sc_attach_state = state; \
83} while (0)
84
85int rtw_dwelltime = 200; /* milliseconds */
86static struct ieee80211_cipher rtw_cipher_wep;
87
88static void rtw_disable_interrupts(struct rtw_regs *);
89static void rtw_enable_interrupts(struct rtw_softc *);
90
91static int rtw_init(struct ifnet *);
92
93static void rtw_start(struct ifnet *);
94static void rtw_reset_oactive(struct rtw_softc *);
95static struct mbuf *rtw_beacon_alloc(struct rtw_softc *,
96 struct ieee80211_node *);
97static u_int rtw_txring_next(struct rtw_regs *, struct rtw_txdesc_blk *);
98
99static void rtw_io_enable(struct rtw_softc *, uint8_t, int);
100static int rtw_key_delete(struct ieee80211com *, const struct ieee80211_key *);
101static int rtw_key_set(struct ieee80211com *, const struct ieee80211_key *,
102 const u_int8_t[IEEE80211_ADDR_LEN]);
103static void rtw_key_update_end(struct ieee80211com *);
104static void rtw_key_update_begin(struct ieee80211com *);
105static int rtw_wep_decap(struct ieee80211_key *, struct mbuf *, int);
106static void rtw_wep_setkeys(struct rtw_softc *, struct ieee80211_key *, int);
107
108static void rtw_led_attach(struct rtw_led_state *, void *);
109static void rtw_led_detach(struct rtw_led_state *);
110static void rtw_led_init(struct rtw_regs *);
111static void rtw_led_slowblink(void *);
112static void rtw_led_fastblink(void *);
113static void rtw_led_set(struct rtw_led_state *, struct rtw_regs *, int);
114
115static int rtw_sysctl_verify_rfio(SYSCTLFN_PROTO);
116static int rtw_sysctl_verify_rfprog(SYSCTLFN_PROTO);
117#ifdef RTW_DEBUG
118static void rtw_dump_rings(struct rtw_softc *sc);
119static void rtw_print_txdesc(struct rtw_softc *, const char *,
120 struct rtw_txsoft *, struct rtw_txdesc_blk *, int);
121static int rtw_sysctl_verify_debug(SYSCTLFN_PROTO);
122static int rtw_sysctl_verify_rxbufs_limit(SYSCTLFN_PROTO);
123#endif /* RTW_DEBUG */
124#ifdef RTW_DIAG
125static void rtw_txring_fixup(struct rtw_softc *sc, const char *fn, int ln);
126#endif /* RTW_DIAG */
127
128/*
129 * Setup sysctl(3) MIB, hw.rtw.*
130 *
131 * TBD condition CTLFLAG_PERMANENT on being a module or not
132 */
133SYSCTL_SETUP(sysctl_rtw, "sysctl rtw(4) subtree setup")
134{
135 int rc;
136 const struct sysctlnode *cnode, *rnode;
137
138 if ((rc = sysctl_createv(clog, 0, NULL, &rnode,
139 CTLFLAG_PERMANENT, CTLTYPE_NODE, "rtw",
140 "Realtek RTL818x 802.11 controls",
141 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0)
142 goto err;
143
144#ifdef RTW_DEBUG
145 /* control debugging printfs */
146 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
147 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
148 "debug", SYSCTL_DESCR("Enable RTL818x debugging output"),
149 rtw_sysctl_verify_debug, 0, &rtw_debug, 0,
150 CTL_CREATE, CTL_EOL)) != 0)
151 goto err;
152
153 /* Limit rx buffers, for simulating resource exhaustion. */
154 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
155 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
156 "rxbufs_limit",
157 SYSCTL_DESCR("Set rx buffers limit"),
158 rtw_sysctl_verify_rxbufs_limit, 0, &rtw_rxbufs_limit, 0,
159 CTL_CREATE, CTL_EOL)) != 0)
160 goto err;
161
162#endif /* RTW_DEBUG */
163 /* set fallback RF programming method */
164 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
165 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
166 "rfprog_fallback",
167 SYSCTL_DESCR("Set fallback RF programming method"),
168 rtw_sysctl_verify_rfprog, 0, &rtw_rfprog_fallback, 0,
169 CTL_CREATE, CTL_EOL)) != 0)
170 goto err;
171
172 /* force host to control RF I/O bus */
173 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
174 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
175 "host_rfio", SYSCTL_DESCR("Enable host control of RF I/O"),
176 rtw_sysctl_verify_rfio, 0, &rtw_host_rfio, 0,
177 CTL_CREATE, CTL_EOL)) != 0)
178 goto err;
179
180 return;
181err:
182 printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
183}
184
185static int
186rtw_sysctl_verify(SYSCTLFN_ARGS, int lower, int upper)
187{
188 int error, t;
189 struct sysctlnode node;
190
191 node = *rnode;
192 t = *(int*)rnode->sysctl_data;
193 node.sysctl_data = &t;
194 error = sysctl_lookup(SYSCTLFN_CALL(&node));
195 if (error || newp == NULL)
196 return (error);
197
198 if (t < lower || t > upper)
199 return (EINVAL);
200
201 *(int*)rnode->sysctl_data = t;
202
203 return (0);
204}
205
206static int
207rtw_sysctl_verify_rfprog(SYSCTLFN_ARGS)
208{
209 return rtw_sysctl_verify(SYSCTLFN_CALL(__UNCONST(rnode)), 0,
210 __SHIFTOUT(RTW_CONFIG4_RFTYPE_MASK, RTW_CONFIG4_RFTYPE_MASK));
211}
212
213static int
214rtw_sysctl_verify_rfio(SYSCTLFN_ARGS)
215{
216 return rtw_sysctl_verify(SYSCTLFN_CALL(__UNCONST(rnode)), 0, 1);
217}
218
219#ifdef RTW_DEBUG
220static int
221rtw_sysctl_verify_debug(SYSCTLFN_ARGS)
222{
223 return rtw_sysctl_verify(SYSCTLFN_CALL(__UNCONST(rnode)),
224 0, RTW_DEBUG_MAX);
225}
226
227static int
228rtw_sysctl_verify_rxbufs_limit(SYSCTLFN_ARGS)
229{
230 return rtw_sysctl_verify(SYSCTLFN_CALL(__UNCONST(rnode)),
231 0, RTW_RXQLEN);
232}
233
234static void
235rtw_print_regs(struct rtw_regs *regs, const char *dvname, const char *where)
236{
237#define PRINTREG32(sc, reg) \
238 RTW_DPRINTF(RTW_DEBUG_REGDUMP, \
239 ("%s: reg[ " #reg " / %03x ] = %08x\n", \
240 dvname, reg, RTW_READ(regs, reg)))
241
242#define PRINTREG16(sc, reg) \
243 RTW_DPRINTF(RTW_DEBUG_REGDUMP, \
244 ("%s: reg[ " #reg " / %03x ] = %04x\n", \
245 dvname, reg, RTW_READ16(regs, reg)))
246
247#define PRINTREG8(sc, reg) \
248 RTW_DPRINTF(RTW_DEBUG_REGDUMP, \
249 ("%s: reg[ " #reg " / %03x ] = %02x\n", \
250 dvname, reg, RTW_READ8(regs, reg)))
251
252 RTW_DPRINTF(RTW_DEBUG_REGDUMP, ("%s: %s\n", dvname, where));
253
254 PRINTREG32(regs, RTW_IDR0);
255 PRINTREG32(regs, RTW_IDR1);
256 PRINTREG32(regs, RTW_MAR0);
257 PRINTREG32(regs, RTW_MAR1);
258 PRINTREG32(regs, RTW_TSFTRL);
259 PRINTREG32(regs, RTW_TSFTRH);
260 PRINTREG32(regs, RTW_TLPDA);
261 PRINTREG32(regs, RTW_TNPDA);
262 PRINTREG32(regs, RTW_THPDA);
263 PRINTREG32(regs, RTW_TCR);
264 PRINTREG32(regs, RTW_RCR);
265 PRINTREG32(regs, RTW_TINT);
266 PRINTREG32(regs, RTW_TBDA);
267 PRINTREG32(regs, RTW_ANAPARM);
268 PRINTREG32(regs, RTW_BB);
269 PRINTREG32(regs, RTW_PHYCFG);
270 PRINTREG32(regs, RTW_WAKEUP0L);
271 PRINTREG32(regs, RTW_WAKEUP0H);
272 PRINTREG32(regs, RTW_WAKEUP1L);
273 PRINTREG32(regs, RTW_WAKEUP1H);
274 PRINTREG32(regs, RTW_WAKEUP2LL);
275 PRINTREG32(regs, RTW_WAKEUP2LH);
276 PRINTREG32(regs, RTW_WAKEUP2HL);
277 PRINTREG32(regs, RTW_WAKEUP2HH);
278 PRINTREG32(regs, RTW_WAKEUP3LL);
279 PRINTREG32(regs, RTW_WAKEUP3LH);
280 PRINTREG32(regs, RTW_WAKEUP3HL);
281 PRINTREG32(regs, RTW_WAKEUP3HH);
282 PRINTREG32(regs, RTW_WAKEUP4LL);
283 PRINTREG32(regs, RTW_WAKEUP4LH);
284 PRINTREG32(regs, RTW_WAKEUP4HL);
285 PRINTREG32(regs, RTW_WAKEUP4HH);
286 PRINTREG32(regs, RTW_DK0);
287 PRINTREG32(regs, RTW_DK1);
288 PRINTREG32(regs, RTW_DK2);
289 PRINTREG32(regs, RTW_DK3);
290 PRINTREG32(regs, RTW_RETRYCTR);
291 PRINTREG32(regs, RTW_RDSAR);
292 PRINTREG32(regs, RTW_FER);
293 PRINTREG32(regs, RTW_FEMR);
294 PRINTREG32(regs, RTW_FPSR);
295 PRINTREG32(regs, RTW_FFER);
296
297 /* 16-bit registers */
298 PRINTREG16(regs, RTW_BRSR);
299 PRINTREG16(regs, RTW_IMR);
300 PRINTREG16(regs, RTW_ISR);
301 PRINTREG16(regs, RTW_BCNITV);
302 PRINTREG16(regs, RTW_ATIMWND);
303 PRINTREG16(regs, RTW_BINTRITV);
304 PRINTREG16(regs, RTW_ATIMTRITV);
305 PRINTREG16(regs, RTW_CRC16ERR);
306 PRINTREG16(regs, RTW_CRC0);
307 PRINTREG16(regs, RTW_CRC1);
308 PRINTREG16(regs, RTW_CRC2);
309 PRINTREG16(regs, RTW_CRC3);
310 PRINTREG16(regs, RTW_CRC4);
311 PRINTREG16(regs, RTW_CWR);
312
313 /* 8-bit registers */
314 PRINTREG8(regs, RTW_CR);
315 PRINTREG8(regs, RTW_9346CR);
316 PRINTREG8(regs, RTW_CONFIG0);
317 PRINTREG8(regs, RTW_CONFIG1);
318 PRINTREG8(regs, RTW_CONFIG2);
319 PRINTREG8(regs, RTW_MSR);
320 PRINTREG8(regs, RTW_CONFIG3);
321 PRINTREG8(regs, RTW_CONFIG4);
322 PRINTREG8(regs, RTW_TESTR);
323 PRINTREG8(regs, RTW_PSR);
324 PRINTREG8(regs, RTW_SCR);
325 PRINTREG8(regs, RTW_PHYDELAY);
326 PRINTREG8(regs, RTW_CRCOUNT);
327 PRINTREG8(regs, RTW_PHYADDR);
328 PRINTREG8(regs, RTW_PHYDATAW);
329 PRINTREG8(regs, RTW_PHYDATAR);
330 PRINTREG8(regs, RTW_CONFIG5);
331 PRINTREG8(regs, RTW_TPPOLL);
332
333 PRINTREG16(regs, RTW_BSSID16);
334 PRINTREG32(regs, RTW_BSSID32);
335#undef PRINTREG32
336#undef PRINTREG16
337#undef PRINTREG8
338}
339#endif /* RTW_DEBUG */
340
341void
342rtw_continuous_tx_enable(struct rtw_softc *sc, int enable)
343{
344 struct rtw_regs *regs = &sc->sc_regs;
345
346 uint32_t tcr;
347 tcr = RTW_READ(regs, RTW_TCR);
348 tcr &= ~RTW_TCR_LBK_MASK;
349 if (enable)
350 tcr |= RTW_TCR_LBK_CONT;
351 else
352 tcr |= RTW_TCR_LBK_NORMAL;
353 RTW_WRITE(regs, RTW_TCR, tcr);
354 RTW_SYNC(regs, RTW_TCR, RTW_TCR);
355 rtw_set_access(regs, RTW_ACCESS_ANAPARM);
356 rtw_txdac_enable(sc, !enable);
357 rtw_set_access(regs, RTW_ACCESS_ANAPARM);/* XXX Voodoo from Linux. */
358 rtw_set_access(regs, RTW_ACCESS_NONE);
359}
360
361#ifdef RTW_DEBUG
362static const char *
363rtw_access_string(enum rtw_access access)
364{
365 switch (access) {
366 case RTW_ACCESS_NONE:
367 return "none";
368 case RTW_ACCESS_CONFIG:
369 return "config";
370 case RTW_ACCESS_ANAPARM:
371 return "anaparm";
372 default:
373 return "unknown";
374 }
375}
376#endif /* RTW_DEBUG */
377
378static void
379rtw_set_access1(struct rtw_regs *regs, enum rtw_access naccess)
380{
381 KASSERT(/* naccess >= RTW_ACCESS_NONE && */
382 naccess <= RTW_ACCESS_ANAPARM);
383 KASSERT(/* regs->r_access >= RTW_ACCESS_NONE && */
384 regs->r_access <= RTW_ACCESS_ANAPARM);
385
386 if (naccess == regs->r_access)
387 return;
388
389 switch (naccess) {
390 case RTW_ACCESS_NONE:
391 switch (regs->r_access) {
392 case RTW_ACCESS_ANAPARM:
393 rtw_anaparm_enable(regs, 0);
394 /*FALLTHROUGH*/
395 case RTW_ACCESS_CONFIG:
396 rtw_config0123_enable(regs, 0);
397 /*FALLTHROUGH*/
398 case RTW_ACCESS_NONE:
399 break;
400 }
401 break;
402 case RTW_ACCESS_CONFIG:
403 switch (regs->r_access) {
404 case RTW_ACCESS_NONE:
405 rtw_config0123_enable(regs, 1);
406 /*FALLTHROUGH*/
407 case RTW_ACCESS_CONFIG:
408 break;
409 case RTW_ACCESS_ANAPARM:
410 rtw_anaparm_enable(regs, 0);
411 break;
412 }
413 break;
414 case RTW_ACCESS_ANAPARM:
415 switch (regs->r_access) {
416 case RTW_ACCESS_NONE:
417 rtw_config0123_enable(regs, 1);
418 /*FALLTHROUGH*/
419 case RTW_ACCESS_CONFIG:
420 rtw_anaparm_enable(regs, 1);
421 /*FALLTHROUGH*/
422 case RTW_ACCESS_ANAPARM:
423 break;
424 }
425 break;
426 }
427}
428
429void
430rtw_set_access(struct rtw_regs *regs, enum rtw_access access)
431{
432 rtw_set_access1(regs, access);
433 RTW_DPRINTF(RTW_DEBUG_ACCESS,
434 ("%s: access %s -> %s\n", __func__,
435 rtw_access_string(regs->r_access),
436 rtw_access_string(access)));
437 regs->r_access = access;
438}
439
440/*
441 * Enable registers, switch register banks.
442 */
443void
444rtw_config0123_enable(struct rtw_regs *regs, int enable)
445{
446 uint8_t ecr;
447 ecr = RTW_READ8(regs, RTW_9346CR);
448 ecr &= ~(RTW_9346CR_EEM_MASK | RTW_9346CR_EECS | RTW_9346CR_EESK);
449 if (enable)
450 ecr |= RTW_9346CR_EEM_CONFIG;
451 else {
452 RTW_WBW(regs, RTW_9346CR, MAX(RTW_CONFIG0, RTW_CONFIG3));
453 ecr |= RTW_9346CR_EEM_NORMAL;
454 }
455 RTW_WRITE8(regs, RTW_9346CR, ecr);
456 RTW_SYNC(regs, RTW_9346CR, RTW_9346CR);
457}
458
459/* requires rtw_config0123_enable(, 1) */
460void
461rtw_anaparm_enable(struct rtw_regs *regs, int enable)
462{
463 uint8_t cfg3;
464
465 cfg3 = RTW_READ8(regs, RTW_CONFIG3);
466 cfg3 |= RTW_CONFIG3_CLKRUNEN;
467 if (enable)
468 cfg3 |= RTW_CONFIG3_PARMEN;
469 else
470 cfg3 &= ~RTW_CONFIG3_PARMEN;
471 RTW_WRITE8(regs, RTW_CONFIG3, cfg3);
472 RTW_SYNC(regs, RTW_CONFIG3, RTW_CONFIG3);
473}
474
475/* requires rtw_anaparm_enable(, 1) */
476void
477rtw_txdac_enable(struct rtw_softc *sc, int enable)
478{
479 uint32_t anaparm;
480 struct rtw_regs *regs = &sc->sc_regs;
481
482 anaparm = RTW_READ(regs, RTW_ANAPARM);
483 if (enable)
484 anaparm &= ~RTW_ANAPARM_TXDACOFF;
485 else
486 anaparm |= RTW_ANAPARM_TXDACOFF;
487 RTW_WRITE(regs, RTW_ANAPARM, anaparm);
488 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
489}
490
491static inline int
492rtw_chip_reset1(struct rtw_regs *regs, device_t dev)
493{
494 uint8_t cr;
495 int i;
496
497 RTW_WRITE8(regs, RTW_CR, RTW_CR_RST);
498
499 RTW_WBR(regs, RTW_CR, RTW_CR);
500
501 for (i = 0; i < 1000; i++) {
502 if ((cr = RTW_READ8(regs, RTW_CR) & RTW_CR_RST) == 0) {
503 RTW_DPRINTF(RTW_DEBUG_RESET,
504 ("%s: reset in %dus\n", device_xname(dev), i));
505 return 0;
506 }
507 RTW_RBR(regs, RTW_CR, RTW_CR);
508 DELAY(10); /* 10us */
509 }
510
511 aprint_error_dev(dev, "reset failed\n");
512 return ETIMEDOUT;
513}
514
515static inline int
516rtw_chip_reset(struct rtw_regs *regs, device_t dev)
517{
518 uint32_t tcr;
519
520 /* from Linux driver */
521 tcr = RTW_TCR_CWMIN | RTW_TCR_MXDMA_2048 |
522 __SHIFTIN(7, RTW_TCR_SRL_MASK) | __SHIFTIN(7, RTW_TCR_LRL_MASK);
523
524 RTW_WRITE(regs, RTW_TCR, tcr);
525
526 RTW_WBW(regs, RTW_CR, RTW_TCR);
527
528 return rtw_chip_reset1(regs, dev);
529}
530
531static int
532rtw_wep_decap(struct ieee80211_key *k, struct mbuf *m, int hdrlen)
533{
534 struct ieee80211_key keycopy;
535
536 RTW_DPRINTF(RTW_DEBUG_KEY, ("%s:\n", __func__));
537
538 keycopy = *k;
539 keycopy.wk_flags &= ~IEEE80211_KEY_SWCRYPT;
540
541 return (*ieee80211_cipher_wep.ic_decap)(&keycopy, m, hdrlen);
542}
543
544static int
545rtw_key_delete(struct ieee80211com *ic, const struct ieee80211_key *k)
546{
547 struct rtw_softc *sc = ic->ic_ifp->if_softc;
548
549 DPRINTF(sc, RTW_DEBUG_KEY, ("%s: delete key %u\n", __func__,
550 k->wk_keyix));
551
552 KASSERT(k->wk_keyix < IEEE80211_WEP_NKID);
553
554 if (k->wk_keylen != 0 &&
555 k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP)
556 sc->sc_flags &= ~RTW_F_DK_VALID;
557
558 return 1;
559}
560
561static int
562rtw_key_set(struct ieee80211com *ic, const struct ieee80211_key *k,
563 const u_int8_t mac[IEEE80211_ADDR_LEN])
564{
565 struct rtw_softc *sc = ic->ic_ifp->if_softc;
566
567 DPRINTF(sc, RTW_DEBUG_KEY, ("%s: set key %u\n", __func__, k->wk_keyix));
568
569 KASSERT(k->wk_keyix < IEEE80211_WEP_NKID);
570
571 sc->sc_flags &= ~RTW_F_DK_VALID;
572
573 return 1;
574}
575
576static void
577rtw_key_update_begin(struct ieee80211com *ic)
578{
579#ifdef RTW_DEBUG
580 struct ifnet *ifp = ic->ic_ifp;
581 struct rtw_softc *sc = ifp->if_softc;
582#endif
583
584 DPRINTF(sc, RTW_DEBUG_KEY, ("%s:\n", __func__));
585}
586
587static void
588rtw_tx_kick(struct rtw_regs *regs, uint8_t ringsel)
589{
590 uint8_t tppoll;
591
592 tppoll = RTW_READ8(regs, RTW_TPPOLL);
593 tppoll &= ~RTW_TPPOLL_SALL;
594 tppoll |= ringsel & RTW_TPPOLL_ALL;
595 RTW_WRITE8(regs, RTW_TPPOLL, tppoll);
596 RTW_SYNC(regs, RTW_TPPOLL, RTW_TPPOLL);
597}
598
599static void
600rtw_key_update_end(struct ieee80211com *ic)
601{
602 struct ifnet *ifp = ic->ic_ifp;
603 struct rtw_softc *sc = ifp->if_softc;
604
605 DPRINTF(sc, RTW_DEBUG_KEY, ("%s:\n", __func__));
606
607 if ((sc->sc_flags & RTW_F_DK_VALID) != 0 ||
608 !device_is_active(sc->sc_dev))
609 return;
610
611 rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 0);
612 rtw_wep_setkeys(sc, ic->ic_nw_keys, ic->ic_def_txkey);
613 rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE,
614 (ifp->if_flags & IFF_RUNNING) != 0);
615}
616
617static bool
618rtw_key_hwsupp(uint32_t flags, const struct ieee80211_key *k)
619{
620 if (k->wk_cipher->ic_cipher != IEEE80211_CIPHER_WEP)
621 return false;
622
623 return ((flags & RTW_C_RXWEP_40) != 0 && k->wk_keylen == 5) ||
624 ((flags & RTW_C_RXWEP_104) != 0 && k->wk_keylen == 13);
625}
626
627static void
628rtw_wep_setkeys(struct rtw_softc *sc, struct ieee80211_key *wk, int txkey)
629{
630 uint8_t psr, scr;
631 int i, keylen = 0;
632 struct rtw_regs *regs;
633 union rtw_keys *rk;
634
635 regs = &sc->sc_regs;
636 rk = &sc->sc_keys;
637
638 (void)memset(rk, 0, sizeof(*rk));
639
640 /* Temporarily use software crypto for all keys. */
641 for (i = 0; i < IEEE80211_WEP_NKID; i++) {
642 if (wk[i].wk_cipher == &rtw_cipher_wep)
643 wk[i].wk_cipher = &ieee80211_cipher_wep;
644 }
645
646 rtw_set_access(regs, RTW_ACCESS_CONFIG);
647
648 psr = RTW_READ8(regs, RTW_PSR);
649 scr = RTW_READ8(regs, RTW_SCR);
650 scr &= ~(RTW_SCR_KM_MASK | RTW_SCR_TXSECON | RTW_SCR_RXSECON);
651
652 if ((sc->sc_ic.ic_flags & IEEE80211_F_PRIVACY) == 0)
653 goto out;
654
655 for (i = 0; i < IEEE80211_WEP_NKID; i++) {
656 if (!rtw_key_hwsupp(sc->sc_flags, &wk[i]))
657 continue;
658 if (i == txkey) {
659 keylen = wk[i].wk_keylen;
660 break;
661 }
662 keylen = MAX(keylen, wk[i].wk_keylen);
663 }
664
665 if (keylen == 5)
666 scr |= RTW_SCR_KM_WEP40 | RTW_SCR_RXSECON;
667 else if (keylen == 13)
668 scr |= RTW_SCR_KM_WEP104 | RTW_SCR_RXSECON;
669
670 for (i = 0; i < IEEE80211_WEP_NKID; i++) {
671 if (wk[i].wk_keylen != keylen ||
672 wk[i].wk_cipher->ic_cipher != IEEE80211_CIPHER_WEP)
673 continue;
674 /* h/w will decrypt, s/w still strips headers */
675 wk[i].wk_cipher = &rtw_cipher_wep;
676 (void)memcpy(rk->rk_keys[i], wk[i].wk_key, wk[i].wk_keylen);
677 }
678
679out:
680 RTW_WRITE8(regs, RTW_PSR, psr & ~RTW_PSR_PSEN);
681
682 bus_space_write_region_stream_4(regs->r_bt, regs->r_bh,
683 RTW_DK0, rk->rk_words, __arraycount(rk->rk_words));
684
685 bus_space_barrier(regs->r_bt, regs->r_bh, RTW_DK0, sizeof(rk->rk_words),
686 BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);
687
688 RTW_DPRINTF(RTW_DEBUG_KEY,
689 ("%s.%d: scr %02" PRIx8 ", keylen %d\n", __func__, __LINE__, scr,
690 keylen));
691
692 RTW_WBW(regs, RTW_DK0, RTW_PSR);
693 RTW_WRITE8(regs, RTW_PSR, psr);
694 RTW_WBW(regs, RTW_PSR, RTW_SCR);
695 RTW_WRITE8(regs, RTW_SCR, scr);
696 RTW_SYNC(regs, RTW_SCR, RTW_SCR);
697 rtw_set_access(regs, RTW_ACCESS_NONE);
698 sc->sc_flags |= RTW_F_DK_VALID;
699}
700
701static inline int
702rtw_recall_eeprom(struct rtw_regs *regs, device_t dev)
703{
704 int i;
705 uint8_t ecr;
706
707 ecr = RTW_READ8(regs, RTW_9346CR);
708 ecr = (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_AUTOLOAD;
709 RTW_WRITE8(regs, RTW_9346CR, ecr);
710
711 RTW_WBR(regs, RTW_9346CR, RTW_9346CR);
712
713 /* wait 25ms for completion */
714 for (i = 0; i < 250; i++) {
715 ecr = RTW_READ8(regs, RTW_9346CR);
716 if ((ecr & RTW_9346CR_EEM_MASK) == RTW_9346CR_EEM_NORMAL) {
717 RTW_DPRINTF(RTW_DEBUG_RESET,
718 ("%s: recall EEPROM in %dus\n", device_xname(dev),
719 i * 100));
720 return 0;
721 }
722 RTW_RBR(regs, RTW_9346CR, RTW_9346CR);
723 DELAY(100);
724 }
725 aprint_error_dev(dev, "recall EEPROM failed\n");
726 return ETIMEDOUT;
727}
728
729static inline int
730rtw_reset(struct rtw_softc *sc)
731{
732 int rc;
733 uint8_t config1;
734
735 sc->sc_flags &= ~RTW_F_DK_VALID;
736
737 if ((rc = rtw_chip_reset(&sc->sc_regs, sc->sc_dev)) != 0)
738 return rc;
739
740 rc = rtw_recall_eeprom(&sc->sc_regs, sc->sc_dev);
741
742 config1 = RTW_READ8(&sc->sc_regs, RTW_CONFIG1);
743 RTW_WRITE8(&sc->sc_regs, RTW_CONFIG1, config1 & ~RTW_CONFIG1_PMEN);
744 /* TBD turn off maximum power saving? */
745
746 return 0;
747}
748
749static inline int
750rtw_txdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_txsoft *descs,
751 u_int ndescs)
752{
753 int i, rc = 0;
754 for (i = 0; i < ndescs; i++) {
755 rc = bus_dmamap_create(dmat, MCLBYTES, RTW_MAXPKTSEGS, MCLBYTES,
756 0, 0, &descs[i].ts_dmamap);
757 if (rc != 0)
758 break;
759 }
760 return rc;
761}
762
763static inline int
764rtw_rxdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_rxsoft *descs,
765 u_int ndescs)
766{
767 int i, rc = 0;
768 for (i = 0; i < ndescs; i++) {
769 rc = bus_dmamap_create(dmat, MCLBYTES, 1, MCLBYTES, 0, 0,
770 &descs[i].rs_dmamap);
771 if (rc != 0)
772 break;
773 }
774 return rc;
775}
776
777static inline void
778rtw_rxdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_rxsoft *descs,
779 u_int ndescs)
780{
781 int i;
782 for (i = 0; i < ndescs; i++) {
783 if (descs[i].rs_dmamap != NULL)
784 bus_dmamap_destroy(dmat, descs[i].rs_dmamap);
785 }
786}
787
788static inline void
789rtw_txdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_txsoft *descs,
790 u_int ndescs)
791{
792 int i;
793 for (i = 0; i < ndescs; i++) {
794 if (descs[i].ts_dmamap != NULL)
795 bus_dmamap_destroy(dmat, descs[i].ts_dmamap);
796 }
797}
798
799static inline void
800rtw_srom_free(struct rtw_srom *sr)
801{
802 sr->sr_size = 0;
803 if (sr->sr_content == NULL)
804 return;
805 free(sr->sr_content, M_DEVBUF);
806 sr->sr_content = NULL;
807}
808
809static void
810rtw_srom_defaults(struct rtw_srom *sr, uint32_t *flags,
811 uint8_t *cs_threshold, enum rtw_rfchipid *rfchipid, uint32_t *rcr)
812{
813 *flags |= (RTW_F_DIGPHY|RTW_F_ANTDIV);
814 *cs_threshold = RTW_SR_ENERGYDETTHR_DEFAULT;
815 *rcr |= RTW_RCR_ENCS1;
816 *rfchipid = RTW_RFCHIPID_PHILIPS;
817}
818
819static int
820rtw_srom_parse(struct rtw_srom *sr, uint32_t *flags, uint8_t *cs_threshold,
821 enum rtw_rfchipid *rfchipid, uint32_t *rcr, enum rtw_locale *locale,
822 device_t dev)
823{
824 int i;
825 const char *rfname, *paname;
826 char scratch[sizeof("unknown 0xXX")];
827 uint16_t srom_version;
828
829 *flags &= ~(RTW_F_DIGPHY|RTW_F_DFLANTB|RTW_F_ANTDIV);
830 *rcr &= ~(RTW_RCR_ENCS1 | RTW_RCR_ENCS2);
831
832 srom_version = RTW_SR_GET16(sr, RTW_SR_VERSION);
833
834 if (srom_version <= 0x0101) {
835 aprint_error_dev(dev,
836 "SROM version %d.%d is not understood, "
837 "limping along with defaults\n",
838 srom_version >> 8, srom_version & 0xff);
839 rtw_srom_defaults(sr, flags, cs_threshold, rfchipid, rcr);
840 return 0;
841 } else {
842 aprint_verbose_dev(dev, "SROM version %d.%d\n",
843 srom_version >> 8, srom_version & 0xff);
844 }
845
846 uint8_t mac[IEEE80211_ADDR_LEN];
847 for (i = 0; i < IEEE80211_ADDR_LEN; i++)
848 mac[i] = RTW_SR_GET(sr, RTW_SR_MAC + i);
849 __USE(mac);
850
851 RTW_DPRINTF(RTW_DEBUG_ATTACH,
852 ("%s: EEPROM MAC %s\n", device_xname(dev), ether_sprintf(mac)));
853
854 *cs_threshold = RTW_SR_GET(sr, RTW_SR_ENERGYDETTHR);
855
856 if ((RTW_SR_GET(sr, RTW_SR_CONFIG2) & RTW_CONFIG2_ANT) != 0)
857 *flags |= RTW_F_ANTDIV;
858
859 /* Note well: the sense of the RTW_SR_RFPARM_DIGPHY bit seems
860 * to be reversed.
861 */
862 if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DIGPHY) == 0)
863 *flags |= RTW_F_DIGPHY;
864 if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DFLANTB) != 0)
865 *flags |= RTW_F_DFLANTB;
866
867 *rcr |= __SHIFTIN(__SHIFTOUT(RTW_SR_GET(sr, RTW_SR_RFPARM),
868 RTW_SR_RFPARM_CS_MASK), RTW_RCR_ENCS1);
869
870 if ((RTW_SR_GET(sr, RTW_SR_CONFIG0) & RTW_CONFIG0_WEP104) != 0)
871 *flags |= RTW_C_RXWEP_104;
872
873 *flags |= RTW_C_RXWEP_40; /* XXX */
874
875 *rfchipid = RTW_SR_GET(sr, RTW_SR_RFCHIPID);
876 switch (*rfchipid) {
877 case RTW_RFCHIPID_GCT: /* this combo seen in the wild */
878 rfname = "GCT GRF5101";
879 paname = "Winspring WS9901";
880 break;
881 case RTW_RFCHIPID_MAXIM:
882 rfname = "Maxim MAX2820"; /* guess */
883 paname = "Maxim MAX2422"; /* guess */
884 break;
885 case RTW_RFCHIPID_INTERSIL:
886 rfname = "Intersil HFA3873"; /* guess */
887 paname = "Intersil <unknown>";
888 break;
889 case RTW_RFCHIPID_PHILIPS: /* this combo seen in the wild */
890 rfname = "Philips SA2400A";
891 paname = "Philips SA2411";
892 break;
893 case RTW_RFCHIPID_RFMD:
894 /* this is the same front-end as an atw(4)! */
895 rfname = "RFMD RF2948B, " /* mentioned in Realtek docs */
896 "LNA: RFMD RF2494, " /* mentioned in Realtek docs */
897 "SYN: Silicon Labs Si4126"; /* inferred from
898 * reference driver
899 */
900 paname = "RFMD RF2189"; /* mentioned in Realtek docs */
901 break;
902 case RTW_RFCHIPID_RESERVED:
903 rfname = paname = "reserved";
904 break;
905 default:
906 snprintf(scratch, sizeof(scratch), "unknown 0x%02x", *rfchipid);
907 rfname = paname = scratch;
908 }
909 aprint_normal_dev(dev, "RF: %s, PA: %s\n", rfname, paname);
910
911 switch (RTW_SR_GET(sr, RTW_SR_CONFIG0) & RTW_CONFIG0_GL_MASK) {
912 case RTW_CONFIG0_GL_USA:
913 case _RTW_CONFIG0_GL_USA:
914 *locale = RTW_LOCALE_USA;
915 break;
916 case RTW_CONFIG0_GL_EUROPE:
917 *locale = RTW_LOCALE_EUROPE;
918 break;
919 case RTW_CONFIG0_GL_JAPAN:
920 *locale = RTW_LOCALE_JAPAN;
921 break;
922 default:
923 *locale = RTW_LOCALE_UNKNOWN;
924 break;
925 }
926 return 0;
927}
928
929/* Returns -1 on failure. */
930static int
931rtw_srom_read(struct rtw_regs *regs, uint32_t flags, struct rtw_srom *sr,
932 device_t dev)
933{
934 int rc;
935 struct seeprom_descriptor sd;
936 uint8_t ecr;
937
938 (void)memset(&sd, 0, sizeof(sd));
939
940 ecr = RTW_READ8(regs, RTW_9346CR);
941
942 if ((flags & RTW_F_9356SROM) != 0) {
943 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: 93c56 SROM\n",
944 device_xname(dev)));
945 sr->sr_size = 256;
946 sd.sd_chip = C56_66;
947 } else {
948 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: 93c46 SROM\n",
949 device_xname(dev)));
950 sr->sr_size = 128;
951 sd.sd_chip = C46;
952 }
953
954 ecr &= ~(RTW_9346CR_EEDI | RTW_9346CR_EEDO | RTW_9346CR_EESK |
955 RTW_9346CR_EEM_MASK | RTW_9346CR_EECS);
956 ecr |= RTW_9346CR_EEM_PROGRAM;
957
958 RTW_WRITE8(regs, RTW_9346CR, ecr);
959
960 sr->sr_content = malloc(sr->sr_size, M_DEVBUF, M_NOWAIT);
961
962 if (sr->sr_content == NULL) {
963 aprint_error_dev(dev, "unable to allocate SROM buffer\n");
964 return ENOMEM;
965 }
966
967 (void)memset(sr->sr_content, 0, sr->sr_size);
968
969 /* RTL8180 has a single 8-bit register for controlling the
970 * 93cx6 SROM. There is no "ready" bit. The RTL8180
971 * input/output sense is the reverse of read_seeprom's.
972 */
973 sd.sd_tag = regs->r_bt;
974 sd.sd_bsh = regs->r_bh;
975 sd.sd_regsize = 1;
976 sd.sd_control_offset = RTW_9346CR;
977 sd.sd_status_offset = RTW_9346CR;
978 sd.sd_dataout_offset = RTW_9346CR;
979 sd.sd_CK = RTW_9346CR_EESK;
980 sd.sd_CS = RTW_9346CR_EECS;
981 sd.sd_DI = RTW_9346CR_EEDO;
982 sd.sd_DO = RTW_9346CR_EEDI;
983 /* make read_seeprom enter EEPROM read/write mode */
984 sd.sd_MS = ecr;
985 sd.sd_RDY = 0;
986
987 /* TBD bus barriers */
988 if (!read_seeprom(&sd, sr->sr_content, 0, sr->sr_size/2)) {
989 aprint_error_dev(dev, "could not read SROM\n");
990 free(sr->sr_content, M_DEVBUF);
991 sr->sr_content = NULL;
992 return -1; /* XXX */
993 }
994
995 /* end EEPROM read/write mode */
996 RTW_WRITE8(regs, RTW_9346CR,
997 (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_NORMAL);
998 RTW_WBRW(regs, RTW_9346CR, RTW_9346CR);
999
1000 if ((rc = rtw_recall_eeprom(regs, dev)) != 0)
1001 return rc;
1002
1003#ifdef RTW_DEBUG
1004 {
1005 int i;
1006 RTW_DPRINTF(RTW_DEBUG_ATTACH,
1007 ("\n%s: serial ROM:\n\t", device_xname(dev)));
1008 for (i = 0; i < sr->sr_size/2; i++) {
1009 if (((i % 8) == 0) && (i != 0))
1010 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("\n\t"));
1011 RTW_DPRINTF(RTW_DEBUG_ATTACH,
1012 (" %04x", sr->sr_content[i]));
1013 }
1014 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("\n"));
1015 }
1016#endif /* RTW_DEBUG */
1017 return 0;
1018}
1019
1020static void
1021rtw_set_rfprog(struct rtw_regs *regs, enum rtw_rfchipid rfchipid,
1022 device_t dev)
1023{
1024 uint8_t cfg4;
1025 const char *method;
1026
1027 cfg4 = RTW_READ8(regs, RTW_CONFIG4) & ~RTW_CONFIG4_RFTYPE_MASK;
1028
1029 switch (rfchipid) {
1030 default:
1031 cfg4 |= __SHIFTIN(rtw_rfprog_fallback, RTW_CONFIG4_RFTYPE_MASK);
1032 method = "fallback";
1033 break;
1034 case RTW_RFCHIPID_INTERSIL:
1035 cfg4 |= RTW_CONFIG4_RFTYPE_INTERSIL;
1036 method = "Intersil";
1037 break;
1038 case RTW_RFCHIPID_PHILIPS:
1039 cfg4 |= RTW_CONFIG4_RFTYPE_PHILIPS;
1040 method = "Philips";
1041 break;
1042 case RTW_RFCHIPID_GCT: /* XXX a guess */
1043 case RTW_RFCHIPID_RFMD:
1044 cfg4 |= RTW_CONFIG4_RFTYPE_RFMD;
1045 method = "RFMD";
1046 break;
1047 }
1048
1049 RTW_WRITE8(regs, RTW_CONFIG4, cfg4);
1050
1051 RTW_WBR(regs, RTW_CONFIG4, RTW_CONFIG4);
1052
1053#ifdef RTW_DEBUG
1054 RTW_DPRINTF(RTW_DEBUG_INIT,
1055 ("%s: %s RF programming method, %#02x\n", device_xname(dev), method,
1056 RTW_READ8(regs, RTW_CONFIG4)));
1057#else
1058 __USE(method);
1059#endif
1060}
1061
1062static inline void
1063rtw_init_channels(enum rtw_locale locale,
1064 struct ieee80211_channel (*chans)[IEEE80211_CHAN_MAX+1], device_t dev)
1065{
1066 int i;
1067 const char *name = NULL;
1068#define ADD_CHANNEL(_chans, _chan) do { \
1069 (*_chans)[_chan].ic_flags = IEEE80211_CHAN_B; \
1070 (*_chans)[_chan].ic_freq = \
1071 ieee80211_ieee2mhz(_chan, (*_chans)[_chan].ic_flags);\
1072} while (0)
1073
1074 switch (locale) {
1075 case RTW_LOCALE_USA: /* 1-11 */
1076 name = "USA";
1077 for (i = 1; i <= 11; i++)
1078 ADD_CHANNEL(chans, i);
1079 break;
1080 case RTW_LOCALE_JAPAN: /* 1-14 */
1081 name = "Japan";
1082 ADD_CHANNEL(chans, 14);
1083 for (i = 1; i <= 14; i++)
1084 ADD_CHANNEL(chans, i);
1085 break;
1086 case RTW_LOCALE_EUROPE: /* 1-13 */
1087 name = "Europe";
1088 for (i = 1; i <= 13; i++)
1089 ADD_CHANNEL(chans, i);
1090 break;
1091 default: /* 10-11 allowed by most countries */
1092 name = "<unknown>";
1093 for (i = 10; i <= 11; i++)
1094 ADD_CHANNEL(chans, i);
1095 break;
1096 }
1097 aprint_normal_dev(dev, "Geographic Location %s\n", name);
1098#undef ADD_CHANNEL
1099}
1100
1101
1102static inline void
1103rtw_identify_country(struct rtw_regs *regs, enum rtw_locale *locale)
1104{
1105 uint8_t cfg0 = RTW_READ8(regs, RTW_CONFIG0);
1106
1107 switch (cfg0 & RTW_CONFIG0_GL_MASK) {
1108 case RTW_CONFIG0_GL_USA:
1109 case _RTW_CONFIG0_GL_USA:
1110 *locale = RTW_LOCALE_USA;
1111 break;
1112 case RTW_CONFIG0_GL_JAPAN:
1113 *locale = RTW_LOCALE_JAPAN;
1114 break;
1115 case RTW_CONFIG0_GL_EUROPE:
1116 *locale = RTW_LOCALE_EUROPE;
1117 break;
1118 default:
1119 *locale = RTW_LOCALE_UNKNOWN;
1120 break;
1121 }
1122}
1123
1124static inline int
1125rtw_identify_sta(struct rtw_regs *regs, uint8_t (*addr)[IEEE80211_ADDR_LEN],
1126 device_t dev)
1127{
1128 static const uint8_t empty_macaddr[IEEE80211_ADDR_LEN] = {
1129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1130 };
1131 uint32_t idr0 = RTW_READ(regs, RTW_IDR0),
1132 idr1 = RTW_READ(regs, RTW_IDR1);
1133
1134 (*addr)[0] = __SHIFTOUT(idr0, __BITS(0, 7));
1135 (*addr)[1] = __SHIFTOUT(idr0, __BITS(8, 15));
1136 (*addr)[2] = __SHIFTOUT(idr0, __BITS(16, 23));
1137 (*addr)[3] = __SHIFTOUT(idr0, __BITS(24 ,31));
1138
1139 (*addr)[4] = __SHIFTOUT(idr1, __BITS(0, 7));
1140 (*addr)[5] = __SHIFTOUT(idr1, __BITS(8, 15));
1141
1142 if (IEEE80211_ADDR_EQ(addr, empty_macaddr)) {
1143 aprint_error_dev(dev,
1144 "could not get mac address, attach failed\n");
1145 return ENXIO;
1146 }
1147
1148 aprint_normal_dev(dev, "802.11 address %s\n", ether_sprintf(*addr));
1149
1150 return 0;
1151}
1152
1153static uint8_t
1154rtw_chan2txpower(struct rtw_srom *sr, struct ieee80211com *ic,
1155 struct ieee80211_channel *chan)
1156{
1157 u_int idx = RTW_SR_TXPOWER1 + ieee80211_chan2ieee(ic, chan) - 1;
1158 KASSERT(idx >= RTW_SR_TXPOWER1 && idx <= RTW_SR_TXPOWER14);
1159 return RTW_SR_GET(sr, idx);
1160}
1161
1162static void
1163rtw_txdesc_blk_init_all(struct rtw_txdesc_blk *tdb)
1164{
1165 int pri;
1166 /* nfree: the number of free descriptors in each ring.
1167 * The beacon ring is a special case: I do not let the
1168 * driver use all of the descriptors on the beacon ring.
1169 * The reasons are two-fold:
1170 *
1171 * (1) A BEACON descriptor's OWN bit is (apparently) not
1172 * updated, so the driver cannot easily know if the descriptor
1173 * belongs to it, or if it is racing the NIC. If the NIC
1174 * does not OWN every descriptor, then the driver can safely
1175 * update the descriptors when RTW_TBDA points at tdb_next.
1176 *
1177 * (2) I hope that the NIC will process more than one BEACON
1178 * descriptor in a single beacon interval, since that will
1179 * enable multiple-BSS support. Since the NIC does not
1180 * clear the OWN bit, there is no natural place for it to
1181 * stop processing BEACON desciptors. Maybe it will *not*
1182 * stop processing them! I do not want to chance the NIC
1183 * looping around and around a saturated beacon ring, so
1184 * I will leave one descriptor unOWNed at all times.
1185 */
1186 u_int nfree[RTW_NTXPRI] =
1187 {RTW_NTXDESCLO, RTW_NTXDESCMD, RTW_NTXDESCHI,
1188 RTW_NTXDESCBCN - 1};
1189
1190 for (pri = 0; pri < RTW_NTXPRI; pri++) {
1191 tdb[pri].tdb_nfree = nfree[pri];
1192 tdb[pri].tdb_next = 0;
1193 }
1194}
1195
1196static int
1197rtw_txsoft_blk_init(struct rtw_txsoft_blk *tsb)
1198{
1199 int i;
1200 struct rtw_txsoft *ts;
1201
1202 SIMPLEQ_INIT(&tsb->tsb_dirtyq);
1203 SIMPLEQ_INIT(&tsb->tsb_freeq);
1204 for (i = 0; i < tsb->tsb_ndesc; i++) {
1205 ts = &tsb->tsb_desc[i];
1206 ts->ts_mbuf = NULL;
1207 SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q);
1208 }
1209 tsb->tsb_tx_timer = 0;
1210 return 0;
1211}
1212
1213static void
1214rtw_txsoft_blk_init_all(struct rtw_txsoft_blk *tsb)
1215{
1216 int pri;
1217 for (pri = 0; pri < RTW_NTXPRI; pri++)
1218 rtw_txsoft_blk_init(&tsb[pri]);
1219}
1220
1221static inline void
1222rtw_rxdescs_sync(struct rtw_rxdesc_blk *rdb, int desc0, int nsync, int ops)
1223{
1224 KASSERT(nsync <= rdb->rdb_ndesc);
1225 /* sync to end of ring */
1226 if (desc0 + nsync > rdb->rdb_ndesc) {
1227 bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap,
1228 offsetof(struct rtw_descs, hd_rx[desc0]),
1229 sizeof(struct rtw_rxdesc) * (rdb->rdb_ndesc - desc0), ops);
1230 nsync -= (rdb->rdb_ndesc - desc0);
1231 desc0 = 0;
1232 }
1233
1234 KASSERT(desc0 < rdb->rdb_ndesc);
1235 KASSERT(nsync <= rdb->rdb_ndesc);
1236 KASSERT(desc0 + nsync <= rdb->rdb_ndesc);
1237
1238 /* sync what remains */
1239 bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap,
1240 offsetof(struct rtw_descs, hd_rx[desc0]),
1241 sizeof(struct rtw_rxdesc) * nsync, ops);
1242}
1243
1244static void
1245rtw_txdescs_sync(struct rtw_txdesc_blk *tdb, u_int desc0, u_int nsync, int ops)
1246{
1247 /* sync to end of ring */
1248 if (desc0 + nsync > tdb->tdb_ndesc) {
1249 bus_dmamap_sync(tdb->tdb_dmat, tdb->tdb_dmamap,
1250 tdb->tdb_ofs + sizeof(struct rtw_txdesc) * desc0,
1251 sizeof(struct rtw_txdesc) * (tdb->tdb_ndesc - desc0),
1252 ops);
1253 nsync -= (tdb->tdb_ndesc - desc0);
1254 desc0 = 0;
1255 }
1256
1257 /* sync what remains */
1258 bus_dmamap_sync(tdb->tdb_dmat, tdb->tdb_dmamap,
1259 tdb->tdb_ofs + sizeof(struct rtw_txdesc) * desc0,
1260 sizeof(struct rtw_txdesc) * nsync, ops);
1261}
1262
1263static void
1264rtw_txdescs_sync_all(struct rtw_txdesc_blk *tdb)
1265{
1266 int pri;
1267 for (pri = 0; pri < RTW_NTXPRI; pri++) {
1268 rtw_txdescs_sync(&tdb[pri], 0, tdb[pri].tdb_ndesc,
1269 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1270 }
1271}
1272
1273static void
1274rtw_rxbufs_release(bus_dma_tag_t dmat, struct rtw_rxsoft *desc)
1275{
1276 int i;
1277 struct rtw_rxsoft *rs;
1278
1279 for (i = 0; i < RTW_RXQLEN; i++) {
1280 rs = &desc[i];
1281 if (rs->rs_mbuf == NULL)
1282 continue;
1283 bus_dmamap_sync(dmat, rs->rs_dmamap, 0,
1284 rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
1285 bus_dmamap_unload(dmat, rs->rs_dmamap);
1286 m_freem(rs->rs_mbuf);
1287 rs->rs_mbuf = NULL;
1288 }
1289}
1290
1291static inline int
1292rtw_rxsoft_alloc(bus_dma_tag_t dmat, struct rtw_rxsoft *rs)
1293{
1294 int rc;
1295 struct mbuf *m;
1296
1297 MGETHDR(m, M_DONTWAIT, MT_DATA);
1298 if (m == NULL)
1299 return ENOBUFS;
1300
1301 MCLGET(m, M_DONTWAIT);
1302 if ((m->m_flags & M_EXT) == 0) {
1303 m_freem(m);
1304 return ENOBUFS;
1305 }
1306
1307 m->m_pkthdr.len = m->m_len = m->m_ext.ext_size;
1308
1309 if (rs->rs_mbuf != NULL)
1310 bus_dmamap_unload(dmat, rs->rs_dmamap);
1311
1312 rs->rs_mbuf = NULL;
1313
1314 rc = bus_dmamap_load_mbuf(dmat, rs->rs_dmamap, m, BUS_DMA_NOWAIT);
1315 if (rc != 0) {
1316 m_freem(m);
1317 return -1;
1318 }
1319
1320 rs->rs_mbuf = m;
1321
1322 return 0;
1323}
1324
1325static int
1326rtw_rxsoft_init_all(bus_dma_tag_t dmat, struct rtw_rxsoft *desc,
1327 int *ndesc, device_t dev)
1328{
1329 int i, rc = 0;
1330 struct rtw_rxsoft *rs;
1331
1332 for (i = 0; i < RTW_RXQLEN; i++) {
1333 rs = &desc[i];
1334 /* we're in rtw_init, so there should be no mbufs allocated */
1335 KASSERT(rs->rs_mbuf == NULL);
1336#ifdef RTW_DEBUG
1337 if (i == rtw_rxbufs_limit) {
1338 aprint_error_dev(dev, "TEST hit %d-buffer limit\n", i);
1339 rc = ENOBUFS;
1340 break;
1341 }
1342#endif /* RTW_DEBUG */
1343 if ((rc = rtw_rxsoft_alloc(dmat, rs)) != 0) {
1344 aprint_error_dev(dev,
1345 "rtw_rxsoft_alloc failed, %d buffers, rc %d\n",
1346 i, rc);
1347 break;
1348 }
1349 }
1350 *ndesc = i;
1351 return rc;
1352}
1353
1354static inline void
1355rtw_rxdesc_init(struct rtw_rxdesc_blk *rdb, struct rtw_rxsoft *rs,
1356 int idx, int kick)
1357{
1358 int is_last = (idx == rdb->rdb_ndesc - 1);
1359 uint32_t ctl, octl, obuf;
1360 struct rtw_rxdesc *rd = &rdb->rdb_desc[idx];
1361
1362 /* sync the mbuf before the descriptor */
1363 bus_dmamap_sync(rdb->rdb_dmat, rs->rs_dmamap, 0,
1364 rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
1365
1366 obuf = rd->rd_buf;
1367 rd->rd_buf = htole32(rs->rs_dmamap->dm_segs[0].ds_addr);
1368
1369 ctl = __SHIFTIN(rs->rs_mbuf->m_len, RTW_RXCTL_LENGTH_MASK) |
1370 RTW_RXCTL_OWN | RTW_RXCTL_FS | RTW_RXCTL_LS;
1371
1372 if (is_last)
1373 ctl |= RTW_RXCTL_EOR;
1374
1375 octl = rd->rd_ctl;
1376 rd->rd_ctl = htole32(ctl);
1377
1378#ifdef RTW_DEBUG
1379 RTW_DPRINTF(
1380 kick ? (RTW_DEBUG_RECV_DESC | RTW_DEBUG_IO_KICK)
1381 : RTW_DEBUG_RECV_DESC,
1382 ("%s: rd %p buf %08x -> %08x ctl %08x -> %08x\n", __func__, rd,
1383 le32toh(obuf), le32toh(rd->rd_buf), le32toh(octl),
1384 le32toh(rd->rd_ctl)));
1385#else
1386 __USE(octl);
1387 __USE(obuf);
1388#endif
1389
1390 /* sync the descriptor */
1391 bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap,
1392 RTW_DESC_OFFSET(hd_rx, idx), sizeof(struct rtw_rxdesc),
1393 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1394}
1395
1396static void
1397rtw_rxdesc_init_all(struct rtw_rxdesc_blk *rdb, struct rtw_rxsoft *ctl, int kick)
1398{
1399 int i;
1400 struct rtw_rxsoft *rs;
1401
1402 for (i = 0; i < rdb->rdb_ndesc; i++) {
1403 rs = &ctl[i];
1404 rtw_rxdesc_init(rdb, rs, i, kick);
1405 }
1406}
1407
1408static void
1409rtw_io_enable(struct rtw_softc *sc, uint8_t flags, int enable)
1410{
1411 struct rtw_regs *regs = &sc->sc_regs;
1412 uint8_t cr;
1413
1414 RTW_DPRINTF(RTW_DEBUG_IOSTATE, ("%s: %s 0x%02x\n", __func__,
1415 enable ? "enable" : "disable", flags));
1416
1417 cr = RTW_READ8(regs, RTW_CR);
1418
1419 /* XXX reference source does not enable MULRW */
1420 /* enable PCI Read/Write Multiple */
1421 cr |= RTW_CR_MULRW;
1422
1423 /* The receive engine will always start at RDSAR. */
1424 if (enable && (flags & ~cr & RTW_CR_RE)) {
1425 struct rtw_rxdesc_blk *rdb;
1426 rdb = &sc->sc_rxdesc_blk;
1427 rdb->rdb_next = 0;
1428 }
1429
1430 RTW_RBW(regs, RTW_CR, RTW_CR); /* XXX paranoia? */
1431 if (enable)
1432 cr |= flags;
1433 else
1434 cr &= ~flags;
1435 RTW_WRITE8(regs, RTW_CR, cr);
1436 RTW_SYNC(regs, RTW_CR, RTW_CR);
1437
1438#ifdef RTW_DIAG
1439 if (cr & RTW_CR_TE)
1440 rtw_txring_fixup(sc, __func__, __LINE__);
1441#endif
1442 if (cr & RTW_CR_TE) {
1443 rtw_tx_kick(&sc->sc_regs,
1444 RTW_TPPOLL_HPQ | RTW_TPPOLL_NPQ | RTW_TPPOLL_LPQ);
1445 }
1446}
1447
1448static void
1449rtw_intr_rx(struct rtw_softc *sc, uint16_t isr)
1450{
1451#define IS_BEACON(__fc0) \
1452 ((__fc0 & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==\
1453 (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_BEACON))
1454
1455 static const int ratetbl[4] = {2, 4, 11, 22}; /* convert rates:
1456 * hardware -> net80211
1457 */
1458 u_int next, nproc = 0;
1459 int hwrate, len, rate, rssi, sq;
1460 uint32_t hrssi, hstat, htsfth, htsftl;
1461 struct rtw_rxdesc *rd;
1462 struct rtw_rxsoft *rs;
1463 struct rtw_rxdesc_blk *rdb;
1464 struct mbuf *m;
1465 struct ifnet *ifp = &sc->sc_if;
1466
1467 struct ieee80211_node *ni;
1468 struct ieee80211_frame_min *wh;
1469
1470 rdb = &sc->sc_rxdesc_blk;
1471
1472 for (next = rdb->rdb_next; ; next = rdb->rdb_next) {
1473 KASSERT(next < rdb->rdb_ndesc);
1474
1475 rtw_rxdescs_sync(rdb, next, 1,
1476 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1477 rd = &rdb->rdb_desc[next];
1478 rs = &sc->sc_rxsoft[next];
1479
1480 hstat = le32toh(rd->rd_stat);
1481 hrssi = le32toh(rd->rd_rssi);
1482 htsfth = le32toh(rd->rd_tsfth);
1483 htsftl = le32toh(rd->rd_tsftl);
1484
1485 RTW_DPRINTF(RTW_DEBUG_RECV_DESC,
1486 ("%s: rxdesc[%d] hstat %08x hrssi %08x htsft %08x%08x\n",
1487 __func__, next, hstat, hrssi, htsfth, htsftl));
1488
1489 ++nproc;
1490
1491 /* still belongs to NIC */
1492 if ((hstat & RTW_RXSTAT_OWN) != 0) {
1493 rtw_rxdescs_sync(rdb, next, 1, BUS_DMASYNC_PREREAD);
1494 break;
1495 }
1496
1497 /* ieee80211_input() might reset the receive engine
1498 * (e.g. by indirectly calling rtw_tune()), so save
1499 * the next pointer here and retrieve it again on
1500 * the next round.
1501 */
1502 rdb->rdb_next = (next + 1) % rdb->rdb_ndesc;
1503
1504#ifdef RTW_DEBUG
1505#define PRINTSTAT(flag) do { \
1506 if ((hstat & flag) != 0) { \
1507 printf("%s" #flag, delim); \
1508 delim = ","; \
1509 } \
1510} while (0)
1511 if ((rtw_debug & RTW_DEBUG_RECV_DESC) != 0) {
1512 const char *delim = "<";
1513 printf("%s: ", device_xname(sc->sc_dev));
1514 if ((hstat & RTW_RXSTAT_DEBUG) != 0) {
1515 printf("status %08x", hstat);
1516 PRINTSTAT(RTW_RXSTAT_SPLCP);
1517 PRINTSTAT(RTW_RXSTAT_MAR);
1518 PRINTSTAT(RTW_RXSTAT_PAR);
1519 PRINTSTAT(RTW_RXSTAT_BAR);
1520 PRINTSTAT(RTW_RXSTAT_PWRMGT);
1521 PRINTSTAT(RTW_RXSTAT_CRC32);
1522 PRINTSTAT(RTW_RXSTAT_ICV);
1523 printf(">, ");
1524 }
1525 }
1526#endif /* RTW_DEBUG */
1527
1528 if ((hstat & RTW_RXSTAT_IOERROR) != 0) {
1529 aprint_error_dev(sc->sc_dev,
1530 "DMA error/FIFO overflow %08" PRIx32 ", "
1531 "rx descriptor %d\n", hstat, next);
1532 ifp->if_ierrors++;
1533 goto next;
1534 }
1535
1536 len = __SHIFTOUT(hstat, RTW_RXSTAT_LENGTH_MASK);
1537 if (len < IEEE80211_MIN_LEN) {
1538 sc->sc_ic.ic_stats.is_rx_tooshort++;
1539 goto next;
1540 }
1541 if (len > rs->rs_mbuf->m_len) {
1542 aprint_error_dev(sc->sc_dev,
1543 "rx frame too long, %d > %d, %08" PRIx32
1544 ", desc %d\n",
1545 len, rs->rs_mbuf->m_len, hstat, next);
1546 ifp->if_ierrors++;
1547 goto next;
1548 }
1549
1550 hwrate = __SHIFTOUT(hstat, RTW_RXSTAT_RATE_MASK);
1551 if (hwrate >= __arraycount(ratetbl)) {
1552 aprint_error_dev(sc->sc_dev,
1553 "unknown rate #%" __PRIuBITS "\n",
1554 __SHIFTOUT(hstat, RTW_RXSTAT_RATE_MASK));
1555 ifp->if_ierrors++;
1556 goto next;
1557 }
1558 rate = ratetbl[hwrate];
1559
1560#ifdef RTW_DEBUG
1561 RTW_DPRINTF(RTW_DEBUG_RECV_DESC,
1562 ("rate %d.%d Mb/s, time %08x%08x\n", (rate * 5) / 10,
1563 (rate * 5) % 10, htsfth, htsftl));
1564#endif /* RTW_DEBUG */
1565
1566 /* if bad flags, skip descriptor */
1567 if ((hstat & RTW_RXSTAT_ONESEG) != RTW_RXSTAT_ONESEG) {
1568 aprint_error_dev(sc->sc_dev, "too many rx segments, "
1569 "next=%d, %08" PRIx32 "\n", next, hstat);
1570 goto next;
1571 }
1572
1573 bus_dmamap_sync(sc->sc_dmat, rs->rs_dmamap, 0,
1574 rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
1575
1576 m = rs->rs_mbuf;
1577
1578 /* if temporarily out of memory, re-use mbuf */
1579 switch (rtw_rxsoft_alloc(sc->sc_dmat, rs)) {
1580 case 0:
1581 break;
1582 case ENOBUFS:
1583 aprint_error_dev(sc->sc_dev,
1584 "rtw_rxsoft_alloc(, %d) failed, dropping packet\n",
1585 next);
1586 goto next;
1587 default:
1588 /* XXX shorten rx ring, instead? */
1589 aprint_error_dev(sc->sc_dev,
1590 "could not load DMA map\n");
1591 }
1592
1593 sq = __SHIFTOUT(hrssi, RTW_RXRSSI_SQ);
1594
1595 if (sc->sc_rfchipid == RTW_RFCHIPID_PHILIPS)
1596 rssi = UINT8_MAX - sq;
1597 else {
1598 rssi = __SHIFTOUT(hrssi, RTW_RXRSSI_IMR_RSSI);
1599 /* TBD find out each front-end's LNA gain in the
1600 * front-end's units
1601 */
1602 if ((hrssi & RTW_RXRSSI_IMR_LNA) == 0)
1603 rssi |= 0x80;
1604 }
1605
1606 /* Note well: now we cannot recycle the rs_mbuf unless
1607 * we restore its original length.
1608 */
1609 m_set_rcvif(m, ifp);
1610 m->m_pkthdr.len = m->m_len = len;
1611
1612 wh = mtod(m, struct ieee80211_frame_min *);
1613
1614 if (!IS_BEACON(wh->i_fc[0]))
1615 sc->sc_led_state.ls_event |= RTW_LED_S_RX;
1616
1617 sc->sc_tsfth = htsfth;
1618
1619#ifdef RTW_DEBUG
1620 if ((ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) ==
1621 (IFF_DEBUG|IFF_LINK2)) {
1622 ieee80211_dump_pkt(mtod(m, uint8_t *), m->m_pkthdr.len,
1623 rate, rssi);
1624 }
1625#endif /* RTW_DEBUG */
1626
1627 if (sc->sc_radiobpf != NULL) {
1628 struct rtw_rx_radiotap_header *rr = &sc->sc_rxtap;
1629
1630 rr->rr_tsft =
1631 htole64(((uint64_t)htsfth << 32) | htsftl);
1632
1633 rr->rr_flags = IEEE80211_RADIOTAP_F_FCS;
1634
1635 if ((hstat & RTW_RXSTAT_SPLCP) != 0)
1636 rr->rr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
1637 if ((hstat & RTW_RXSTAT_CRC32) != 0)
1638 rr->rr_flags |= IEEE80211_RADIOTAP_F_BADFCS;
1639
1640 rr->rr_rate = rate;
1641
1642 if (sc->sc_rfchipid == RTW_RFCHIPID_PHILIPS)
1643 rr->rr_u.u_philips.p_antsignal = rssi;
1644 else {
1645 rr->rr_u.u_other.o_antsignal = rssi;
1646 rr->rr_u.u_other.o_barker_lock =
1647 htole16(UINT8_MAX - sq);
1648 }
1649
1650 bpf_mtap2(sc->sc_radiobpf,
1651 rr, sizeof(sc->sc_rxtapu), m);
1652 }
1653
1654 if ((hstat & RTW_RXSTAT_RES) != 0) {
1655 m_freem(m);
1656 goto next;
1657 }
1658
1659 /* CRC is included with the packet; trim it off. */
1660 m_adj(m, -IEEE80211_CRC_LEN);
1661
1662 /* TBD use _MAR, _BAR, _PAR flags as hints to _find_rxnode? */
1663 ni = ieee80211_find_rxnode(&sc->sc_ic, wh);
1664 ieee80211_input(&sc->sc_ic, m, ni, rssi, htsftl);
1665 ieee80211_free_node(ni);
1666next:
1667 rtw_rxdesc_init(rdb, rs, next, 0);
1668 }
1669#undef IS_BEACON
1670}
1671
1672static void
1673rtw_txsoft_release(bus_dma_tag_t dmat, struct ieee80211com *ic,
1674 struct rtw_txsoft *ts)
1675{
1676 struct mbuf *m;
1677 struct ieee80211_node *ni;
1678
1679 m = ts->ts_mbuf;
1680 ni = ts->ts_ni;
1681 KASSERT(m != NULL);
1682 KASSERT(ni != NULL);
1683 ts->ts_mbuf = NULL;
1684 ts->ts_ni = NULL;
1685
1686 bus_dmamap_sync(dmat, ts->ts_dmamap, 0, ts->ts_dmamap->dm_mapsize,
1687 BUS_DMASYNC_POSTWRITE);
1688 bus_dmamap_unload(dmat, ts->ts_dmamap);
1689 m_freem(m);
1690 ieee80211_free_node(ni);
1691}
1692
1693static void
1694rtw_txsofts_release(bus_dma_tag_t dmat, struct ieee80211com *ic,
1695 struct rtw_txsoft_blk *tsb)
1696{
1697 struct rtw_txsoft *ts;
1698
1699 while ((ts = SIMPLEQ_FIRST(&tsb->tsb_dirtyq)) != NULL) {
1700 rtw_txsoft_release(dmat, ic, ts);
1701 SIMPLEQ_REMOVE_HEAD(&tsb->tsb_dirtyq, ts_q);
1702 SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q);
1703 }
1704 tsb->tsb_tx_timer = 0;
1705}
1706
1707static inline void
1708rtw_collect_txpkt(struct rtw_softc *sc, struct rtw_txdesc_blk *tdb,
1709 struct rtw_txsoft *ts, int ndesc)
1710{
1711 uint32_t hstat;
1712 int data_retry, rts_retry;
1713 struct rtw_txdesc *tdn;
1714 const char *condstring;
1715 struct ifnet *ifp = &sc->sc_if;
1716
1717 rtw_txsoft_release(sc->sc_dmat, &sc->sc_ic, ts);
1718
1719 tdb->tdb_nfree += ndesc;
1720
1721 tdn = &tdb->tdb_desc[ts->ts_last];
1722
1723 hstat = le32toh(tdn->td_stat);
1724 rts_retry = __SHIFTOUT(hstat, RTW_TXSTAT_RTSRETRY_MASK);
1725 data_retry = __SHIFTOUT(hstat, RTW_TXSTAT_DRC_MASK);
1726
1727 ifp->if_collisions += rts_retry + data_retry;
1728
1729 if ((hstat & RTW_TXSTAT_TOK) != 0)
1730 condstring = "ok";
1731 else {
1732 ifp->if_oerrors++;
1733 condstring = "error";
1734 }
1735
1736#ifdef RTW_DEBUG
1737 DPRINTF(sc, RTW_DEBUG_XMIT_DESC,
1738 ("%s: ts %p txdesc[%d, %d] %s tries rts %u data %u\n",
1739 device_xname(sc->sc_dev), ts, ts->ts_first, ts->ts_last,
1740 condstring, rts_retry, data_retry));
1741#else
1742 __USE(condstring);
1743#endif
1744}
1745
1746static void
1747rtw_reset_oactive(struct rtw_softc *sc)
1748{
1749 short oflags;
1750 int pri;
1751 struct rtw_txsoft_blk *tsb;
1752 struct rtw_txdesc_blk *tdb;
1753 oflags = sc->sc_if.if_flags;
1754 for (pri = 0; pri < RTW_NTXPRI; pri++) {
1755 tsb = &sc->sc_txsoft_blk[pri];
1756 tdb = &sc->sc_txdesc_blk[pri];
1757 if (!SIMPLEQ_EMPTY(&tsb->tsb_freeq) && tdb->tdb_nfree > 0)
1758 sc->sc_if.if_flags &= ~IFF_OACTIVE;
1759 }
1760 if (oflags != sc->sc_if.if_flags) {
1761 DPRINTF(sc, RTW_DEBUG_OACTIVE,
1762 ("%s: reset OACTIVE\n", __func__));
1763 }
1764}
1765
1766/* Collect transmitted packets. */
1767static bool
1768rtw_collect_txring(struct rtw_softc *sc, struct rtw_txsoft_blk *tsb,
1769 struct rtw_txdesc_blk *tdb, int force)
1770{
1771 bool collected = false;
1772 int ndesc;
1773 struct rtw_txsoft *ts;
1774
1775#ifdef RTW_DEBUG
1776 rtw_dump_rings(sc);
1777#endif
1778
1779 while ((ts = SIMPLEQ_FIRST(&tsb->tsb_dirtyq)) != NULL) {
1780 /* If we're clearing a failed transmission, only clear
1781 up to the last packet the hardware has processed. */
1782 if (ts->ts_first == rtw_txring_next(&sc->sc_regs, tdb))
1783 break;
1784
1785 ndesc = 1 + ts->ts_last - ts->ts_first;
1786 if (ts->ts_last < ts->ts_first)
1787 ndesc += tdb->tdb_ndesc;
1788
1789 KASSERT(ndesc > 0);
1790
1791 rtw_txdescs_sync(tdb, ts->ts_first, ndesc,
1792 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1793
1794 if (force) {
1795 int next;
1796#ifdef RTW_DIAG
1797 printf("%s: clearing packet, stats", __func__);
1798#endif
1799 for (next = ts->ts_first; ;
1800 next = RTW_NEXT_IDX(tdb, next)) {
1801#ifdef RTW_DIAG
1802 printf(" %" PRIx32 "/%" PRIx32 "/%" PRIx32 "/%" PRIu32 "/%" PRIx32, le32toh(tdb->tdb_desc[next].td_stat), le32toh(tdb->tdb_desc[next].td_ctl1), le32toh(tdb->tdb_desc[next].td_buf), le32toh(tdb->tdb_desc[next].td_len), le32toh(tdb->tdb_desc[next].td_next));
1803#endif
1804 tdb->tdb_desc[next].td_stat &=
1805 ~htole32(RTW_TXSTAT_OWN);
1806 if (next == ts->ts_last)
1807 break;
1808 }
1809 rtw_txdescs_sync(tdb, ts->ts_first, ndesc,
1810 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1811#ifdef RTW_DIAG
1812 next = RTW_NEXT_IDX(tdb, next);
1813 printf(" -> end %u stat %" PRIx32 ", was %u\n", next,
1814 le32toh(tdb->tdb_desc[next].td_stat),
1815 rtw_txring_next(&sc->sc_regs, tdb));
1816#endif
1817 } else if ((tdb->tdb_desc[ts->ts_last].td_stat &
1818 htole32(RTW_TXSTAT_OWN)) != 0) {
1819 rtw_txdescs_sync(tdb, ts->ts_last, 1,
1820 BUS_DMASYNC_PREREAD);
1821 break;
1822 }
1823
1824 collected = true;
1825
1826 rtw_collect_txpkt(sc, tdb, ts, ndesc);
1827 SIMPLEQ_REMOVE_HEAD(&tsb->tsb_dirtyq, ts_q);
1828 SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q);
1829 }
1830
1831 /* no more pending transmissions, cancel watchdog */
1832 if (ts == NULL)
1833 tsb->tsb_tx_timer = 0;
1834 rtw_reset_oactive(sc);
1835
1836 return collected;
1837}
1838
1839static void
1840rtw_intr_tx(struct rtw_softc *sc, uint16_t isr)
1841{
1842 int pri;
1843 struct rtw_txsoft_blk *tsb;
1844 struct rtw_txdesc_blk *tdb;
1845 struct ifnet *ifp = &sc->sc_if;
1846
1847 for (pri = 0; pri < RTW_NTXPRI; pri++) {
1848 tsb = &sc->sc_txsoft_blk[pri];
1849 tdb = &sc->sc_txdesc_blk[pri];
1850 rtw_collect_txring(sc, tsb, tdb, 0);
1851 }
1852
1853 if ((isr & RTW_INTR_TX) != 0)
1854 rtw_start(ifp);
1855
1856 return;
1857}
1858
1859static void
1860rtw_intr_beacon(struct rtw_softc *sc, uint16_t isr)
1861{
1862 u_int next;
1863 uint32_t tsfth, tsftl;
1864 struct ieee80211com *ic;
1865 struct rtw_txdesc_blk *tdb = &sc->sc_txdesc_blk[RTW_TXPRIBCN];
1866 struct rtw_txsoft_blk *tsb = &sc->sc_txsoft_blk[RTW_TXPRIBCN];
1867 struct mbuf *m;
1868
1869 tsfth = RTW_READ(&sc->sc_regs, RTW_TSFTRH);
1870 tsftl = RTW_READ(&sc->sc_regs, RTW_TSFTRL);
1871
1872 if ((isr & (RTW_INTR_TBDOK|RTW_INTR_TBDER)) != 0) {
1873 next = rtw_txring_next(&sc->sc_regs, tdb);
1874#ifdef RTW_DEBUG
1875 RTW_DPRINTF(RTW_DEBUG_BEACON,
1876 ("%s: beacon ring %sprocessed, isr = %#04" PRIx16
1877 ", next %u expected %u, %" PRIu64 "\n", __func__,
1878 (next == tdb->tdb_next) ? "" : "un", isr, next,
1879 tdb->tdb_next, (uint64_t)tsfth << 32 | tsftl));
1880#else
1881 __USE(next);
1882 __USE(tsfth);
1883 __USE(tsftl);
1884#endif
1885 if ((RTW_READ8(&sc->sc_regs, RTW_TPPOLL) & RTW_TPPOLL_BQ) == 0)
1886 rtw_collect_txring(sc, tsb, tdb, 1);
1887 }
1888 /* Start beacon transmission. */
1889
1890 if ((isr & RTW_INTR_BCNINT) != 0 &&
1891 sc->sc_ic.ic_state == IEEE80211_S_RUN &&
1892 SIMPLEQ_EMPTY(&tsb->tsb_dirtyq)) {
1893 RTW_DPRINTF(RTW_DEBUG_BEACON,
1894 ("%s: beacon prep. time, isr = %#04" PRIx16
1895 ", %16" PRIu64 "\n", __func__, isr,
1896 (uint64_t)tsfth << 32 | tsftl));
1897 ic = &sc->sc_ic;
1898 m = rtw_beacon_alloc(sc, ic->ic_bss);
1899
1900 if (m == NULL) {
1901 aprint_error_dev(sc->sc_dev,
1902 "could not allocate beacon\n");
1903 return;
1904 }
1905 M_SETCTX(m, ieee80211_ref_node(ic->ic_bss));
1906 IF_ENQUEUE(&sc->sc_beaconq, m);
1907 rtw_start(&sc->sc_if);
1908 }
1909}
1910
1911static void
1912rtw_intr_atim(struct rtw_softc *sc)
1913{
1914 /* TBD */
1915 return;
1916}
1917
1918#ifdef RTW_DEBUG
1919static void
1920rtw_dump_rings(struct rtw_softc *sc)
1921{
1922 struct rtw_txdesc_blk *tdb;
1923 struct rtw_rxdesc *rd;
1924 struct rtw_rxdesc_blk *rdb;
1925 int desc, pri;
1926
1927 if ((rtw_debug & RTW_DEBUG_IO_KICK) == 0)
1928 return;
1929
1930 for (pri = 0; pri < RTW_NTXPRI; pri++) {
1931 tdb = &sc->sc_txdesc_blk[pri];
1932 printf("%s: txpri %d ndesc %d nfree %d\n", __func__, pri,
1933 tdb->tdb_ndesc, tdb->tdb_nfree);
1934 for (desc = 0; desc < tdb->tdb_ndesc; desc++)
1935 rtw_print_txdesc(sc, ".", NULL, tdb, desc);
1936 }
1937
1938 rdb = &sc->sc_rxdesc_blk;
1939
1940 for (desc = 0; desc < RTW_RXQLEN; desc++) {
1941 rd = &rdb->rdb_desc[desc];
1942 printf("%s: %sctl %08x rsvd0/rssi %08x buf/tsftl %08x "
1943 "rsvd1/tsfth %08x\n", __func__,
1944 (desc >= rdb->rdb_ndesc) ? "UNUSED " : "",
1945 le32toh(rd->rd_ctl), le32toh(rd->rd_rssi),
1946 le32toh(rd->rd_buf), le32toh(rd->rd_tsfth));
1947 }
1948}
1949#endif /* RTW_DEBUG */
1950
1951static void
1952rtw_hwring_setup(struct rtw_softc *sc)
1953{
1954 int pri;
1955 struct rtw_regs *regs = &sc->sc_regs;
1956 struct rtw_txdesc_blk *tdb;
1957
1958 sc->sc_txdesc_blk[RTW_TXPRILO].tdb_basereg = RTW_TLPDA;
1959 sc->sc_txdesc_blk[RTW_TXPRILO].tdb_base = RTW_RING_BASE(sc, hd_txlo);
1960 sc->sc_txdesc_blk[RTW_TXPRIMD].tdb_basereg = RTW_TNPDA;
1961 sc->sc_txdesc_blk[RTW_TXPRIMD].tdb_base = RTW_RING_BASE(sc, hd_txmd);
1962 sc->sc_txdesc_blk[RTW_TXPRIHI].tdb_basereg = RTW_THPDA;
1963 sc->sc_txdesc_blk[RTW_TXPRIHI].tdb_base = RTW_RING_BASE(sc, hd_txhi);
1964 sc->sc_txdesc_blk[RTW_TXPRIBCN].tdb_basereg = RTW_TBDA;
1965 sc->sc_txdesc_blk[RTW_TXPRIBCN].tdb_base = RTW_RING_BASE(sc, hd_bcn);
1966
1967 for (pri = 0; pri < RTW_NTXPRI; pri++) {
1968 tdb = &sc->sc_txdesc_blk[pri];
1969 RTW_WRITE(regs, tdb->tdb_basereg, tdb->tdb_base);
1970 RTW_DPRINTF(RTW_DEBUG_XMIT_DESC,
1971 ("%s: reg[tdb->tdb_basereg] <- %" PRIxPTR "\n", __func__,
1972 (uintptr_t)tdb->tdb_base));
1973 }
1974
1975 RTW_WRITE(regs, RTW_RDSAR, RTW_RING_BASE(sc, hd_rx));
1976
1977 RTW_DPRINTF(RTW_DEBUG_RECV_DESC,
1978 ("%s: reg[RDSAR] <- %" PRIxPTR "\n", __func__,
1979 (uintptr_t)RTW_RING_BASE(sc, hd_rx)));
1980
1981 RTW_SYNC(regs, RTW_TLPDA, RTW_RDSAR);
1982
1983}
1984
1985static int
1986rtw_swring_setup(struct rtw_softc *sc)
1987{
1988 int rc;
1989 struct rtw_rxdesc_blk *rdb;
1990
1991 rtw_txdesc_blk_init_all(&sc->sc_txdesc_blk[0]);
1992
1993 rtw_txsoft_blk_init_all(&sc->sc_txsoft_blk[0]);
1994
1995 rdb = &sc->sc_rxdesc_blk;
1996 if ((rc = rtw_rxsoft_init_all(sc->sc_dmat, sc->sc_rxsoft, &rdb->rdb_ndesc,
1997 sc->sc_dev)) != 0 && rdb->rdb_ndesc == 0) {
1998 aprint_error_dev(sc->sc_dev, "could not allocate rx buffers\n");
1999 return rc;
2000 }
2001
2002 rdb = &sc->sc_rxdesc_blk;
2003 rtw_rxdescs_sync(rdb, 0, rdb->rdb_ndesc,
2004 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
2005 rtw_rxdesc_init_all(rdb, sc->sc_rxsoft, 1);
2006 rdb->rdb_next = 0;
2007
2008 rtw_txdescs_sync_all(&sc->sc_txdesc_blk[0]);
2009 return 0;
2010}
2011
2012static void
2013rtw_txdesc_blk_init(struct rtw_txdesc_blk *tdb)
2014{
2015 int i;
2016
2017 (void)memset(tdb->tdb_desc, 0,
2018 sizeof(tdb->tdb_desc[0]) * tdb->tdb_ndesc);
2019 for (i = 0; i < tdb->tdb_ndesc; i++)
2020 tdb->tdb_desc[i].td_next = htole32(RTW_NEXT_DESC(tdb, i));
2021}
2022
2023static u_int
2024rtw_txring_next(struct rtw_regs *regs, struct rtw_txdesc_blk *tdb)
2025{
2026 return (le32toh(RTW_READ(regs, tdb->tdb_basereg)) - tdb->tdb_base) /
2027 sizeof(struct rtw_txdesc);
2028}
2029
2030#ifdef RTW_DIAG
2031static void
2032rtw_txring_fixup(struct rtw_softc *sc, const char *fn, int ln)
2033{
2034 int pri;
2035 u_int next;
2036 struct rtw_txdesc_blk *tdb;
2037 struct rtw_regs *regs = &sc->sc_regs;
2038
2039 for (pri = 0; pri < RTW_NTXPRI; pri++) {
2040 int i;
2041 tdb = &sc->sc_txdesc_blk[pri];
2042 next = rtw_txring_next(regs, tdb);
2043 if (tdb->tdb_next == next)
2044 continue;
2045 for (i = 0; next != tdb->tdb_next;
2046 next = RTW_NEXT_IDX(tdb, next), i++) {
2047 if ((tdb->tdb_desc[next].td_stat & htole32(RTW_TXSTAT_OWN)) == 0)
2048 break;
2049 }
2050 printf("%s:%d: tx-ring %d expected next %u, read %u+%d -> %s\n", fn,
2051 ln, pri, tdb->tdb_next, next, i, tdb->tdb_next == next ? "okay" : "BAD");
2052 if (tdb->tdb_next == next)
2053 continue;
2054 tdb->tdb_next = MIN(next, tdb->tdb_ndesc - 1);
2055 }
2056}
2057#endif
2058
2059static void
2060rtw_txdescs_reset(struct rtw_softc *sc)
2061{
2062 int pri;
2063 struct rtw_txsoft_blk *tsb;
2064 struct rtw_txdesc_blk *tdb;
2065
2066 for (pri = 0; pri < RTW_NTXPRI; pri++) {
2067 tsb = &sc->sc_txsoft_blk[pri];
2068 tdb = &sc->sc_txdesc_blk[pri];
2069 rtw_collect_txring(sc, tsb, tdb, 1);
2070#ifdef RTW_DIAG
2071 if (!SIMPLEQ_EMPTY(&tsb->tsb_dirtyq))
2072 printf("%s: packets left in ring %d\n", __func__, pri);
2073#endif
2074 }
2075}
2076
2077static void
2078rtw_intr_ioerror(struct rtw_softc *sc, uint16_t isr)
2079{
2080 aprint_error_dev(sc->sc_dev, "tx fifo underflow\n");
2081
2082 RTW_DPRINTF(RTW_DEBUG_BUGS, ("%s: cleaning up xmit, isr %" PRIx16
2083 "\n", device_xname(sc->sc_dev), isr));
2084
2085#ifdef RTW_DEBUG
2086 rtw_dump_rings(sc);
2087#endif /* RTW_DEBUG */
2088
2089 /* Collect tx'd packets. XXX let's hope this stops the transmit
2090 * timeouts.
2091 */
2092 rtw_txdescs_reset(sc);
2093
2094#ifdef RTW_DEBUG
2095 rtw_dump_rings(sc);
2096#endif /* RTW_DEBUG */
2097}
2098
2099static inline void
2100rtw_suspend_ticks(struct rtw_softc *sc)
2101{
2102 RTW_DPRINTF(RTW_DEBUG_TIMEOUT,
2103 ("%s: suspending ticks\n", device_xname(sc->sc_dev)));
2104 sc->sc_do_tick = 0;
2105}
2106
2107static inline void
2108rtw_resume_ticks(struct rtw_softc *sc)
2109{
2110 uint32_t tsftrl0, tsftrl1, next_tint;
2111
2112 tsftrl0 = RTW_READ(&sc->sc_regs, RTW_TSFTRL);
2113
2114 tsftrl1 = RTW_READ(&sc->sc_regs, RTW_TSFTRL);
2115 next_tint = tsftrl1 + 1000000;
2116 RTW_WRITE(&sc->sc_regs, RTW_TINT, next_tint);
2117
2118 sc->sc_do_tick = 1;
2119
2120#ifdef RTW_DEBUG
2121 RTW_DPRINTF(RTW_DEBUG_TIMEOUT,
2122 ("%s: resume ticks delta %#08x now %#08x next %#08x\n",
2123 device_xname(sc->sc_dev), tsftrl1 - tsftrl0, tsftrl1, next_tint));
2124#else
2125 __USE(tsftrl0);
2126#endif
2127}
2128
2129static void
2130rtw_intr_timeout(struct rtw_softc *sc)
2131{
2132 RTW_DPRINTF(RTW_DEBUG_TIMEOUT, ("%s: timeout\n", device_xname(sc->sc_dev)));
2133 if (sc->sc_do_tick)
2134 rtw_resume_ticks(sc);
2135 return;
2136}
2137
2138int
2139rtw_intr(void *arg)
2140{
2141 int i;
2142 struct rtw_softc *sc = arg;
2143 struct rtw_regs *regs = &sc->sc_regs;
2144 uint16_t isr;
2145 struct ifnet *ifp = &sc->sc_if;
2146
2147 /*
2148 * If the interface isn't running, the interrupt couldn't
2149 * possibly have come from us.
2150 */
2151 if ((ifp->if_flags & IFF_RUNNING) == 0 ||
2152 !device_activation(sc->sc_dev, DEVACT_LEVEL_DRIVER)) {
2153 RTW_DPRINTF(RTW_DEBUG_INTR, ("%s: stray interrupt\n",
2154 device_xname(sc->sc_dev)));
2155 return (0);
2156 }
2157
2158 for (i = 0; i < 10; i++) {
2159 isr = RTW_READ16(regs, RTW_ISR);
2160
2161 RTW_WRITE16(regs, RTW_ISR, isr);
2162 RTW_WBR(regs, RTW_ISR, RTW_ISR);
2163
2164 if (sc->sc_intr_ack != NULL)
2165 (*sc->sc_intr_ack)(regs);
2166
2167 if (isr == 0)
2168 break;
2169
2170#ifdef RTW_DEBUG
2171#define PRINTINTR(flag) do { \
2172 if ((isr & flag) != 0) { \
2173 printf("%s" #flag, delim); \
2174 delim = ","; \
2175 } \
2176} while (0)
2177
2178 if ((rtw_debug & RTW_DEBUG_INTR) != 0 && isr != 0) {
2179 const char *delim = "<";
2180
2181 printf("%s: reg[ISR] = %x", device_xname(sc->sc_dev),
2182 isr);
2183
2184 PRINTINTR(RTW_INTR_TXFOVW);
2185 PRINTINTR(RTW_INTR_TIMEOUT);
2186 PRINTINTR(RTW_INTR_BCNINT);
2187 PRINTINTR(RTW_INTR_ATIMINT);
2188 PRINTINTR(RTW_INTR_TBDER);
2189 PRINTINTR(RTW_INTR_TBDOK);
2190 PRINTINTR(RTW_INTR_THPDER);
2191 PRINTINTR(RTW_INTR_THPDOK);
2192 PRINTINTR(RTW_INTR_TNPDER);
2193 PRINTINTR(RTW_INTR_TNPDOK);
2194 PRINTINTR(RTW_INTR_RXFOVW);
2195 PRINTINTR(RTW_INTR_RDU);
2196 PRINTINTR(RTW_INTR_TLPDER);
2197 PRINTINTR(RTW_INTR_TLPDOK);
2198 PRINTINTR(RTW_INTR_RER);
2199 PRINTINTR(RTW_INTR_ROK);
2200
2201 printf(">\n");
2202 }
2203#undef PRINTINTR
2204#endif /* RTW_DEBUG */
2205
2206 if ((isr & RTW_INTR_RX) != 0)
2207 rtw_intr_rx(sc, isr);
2208 if ((isr & RTW_INTR_TX) != 0)
2209 rtw_intr_tx(sc, isr);
2210 if ((isr & RTW_INTR_BEACON) != 0)
2211 rtw_intr_beacon(sc, isr);
2212 if ((isr & RTW_INTR_ATIMINT) != 0)
2213 rtw_intr_atim(sc);
2214 if ((isr & RTW_INTR_IOERROR) != 0)
2215 rtw_intr_ioerror(sc, isr);
2216 if ((isr & RTW_INTR_TIMEOUT) != 0)
2217 rtw_intr_timeout(sc);
2218 }
2219
2220 return 1;
2221}
2222
2223/* Must be called at splnet. */
2224static void
2225rtw_stop(struct ifnet *ifp, int disable)
2226{
2227 int pri;
2228 struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc;
2229 struct ieee80211com *ic = &sc->sc_ic;
2230 struct rtw_regs *regs = &sc->sc_regs;
2231
2232 rtw_suspend_ticks(sc);
2233
2234 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
2235
2236 if (device_has_power(sc->sc_dev)) {
2237 /* Disable interrupts. */
2238 RTW_WRITE16(regs, RTW_IMR, 0);
2239
2240 RTW_WBW(regs, RTW_TPPOLL, RTW_IMR);
2241
2242 /* Stop the transmit and receive processes. First stop DMA,
2243 * then disable receiver and transmitter.
2244 */
2245 RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL);
2246
2247 RTW_SYNC(regs, RTW_TPPOLL, RTW_IMR);
2248
2249 rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 0);
2250 }
2251
2252 for (pri = 0; pri < RTW_NTXPRI; pri++) {
2253 rtw_txsofts_release(sc->sc_dmat, &sc->sc_ic,
2254 &sc->sc_txsoft_blk[pri]);
2255 }
2256
2257 rtw_rxbufs_release(sc->sc_dmat, &sc->sc_rxsoft[0]);
2258
2259 /* Mark the interface as not running. Cancel the watchdog timer. */
2260 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
2261 ifp->if_timer = 0;
2262
2263 if (disable)
2264 pmf_device_suspend(sc->sc_dev, &sc->sc_qual);
2265
2266 return;
2267}
2268
2269const char *
2270rtw_pwrstate_string(enum rtw_pwrstate power)
2271{
2272 switch (power) {
2273 case RTW_ON:
2274 return "on";
2275 case RTW_SLEEP:
2276 return "sleep";
2277 case RTW_OFF:
2278 return "off";
2279 default:
2280 return "unknown";
2281 }
2282}
2283
2284/* XXX For Maxim, I am using the RFMD settings gleaned from the
2285 * reference driver, plus a magic Maxim "ON" value that comes from
2286 * the Realtek document "Windows PG for Rtl8180."
2287 */
2288static void
2289rtw_maxim_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
2290 int before_rf, int digphy)
2291{
2292 uint32_t anaparm;
2293
2294 anaparm = RTW_READ(regs, RTW_ANAPARM);
2295 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF);
2296
2297 switch (power) {
2298 case RTW_OFF:
2299 if (before_rf)
2300 return;
2301 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_OFF;
2302 anaparm |= RTW_ANAPARM_TXDACOFF;
2303 break;
2304 case RTW_SLEEP:
2305 if (!before_rf)
2306 return;
2307 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_SLEEP;
2308 anaparm |= RTW_ANAPARM_TXDACOFF;
2309 break;
2310 case RTW_ON:
2311 if (!before_rf)
2312 return;
2313 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_ON;
2314 break;
2315 }
2316 RTW_DPRINTF(RTW_DEBUG_PWR,
2317 ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n",
2318 __func__, rtw_pwrstate_string(power),
2319 (before_rf) ? "before" : "after", anaparm));
2320
2321 RTW_WRITE(regs, RTW_ANAPARM, anaparm);
2322 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
2323}
2324
2325/* XXX I am using the RFMD settings gleaned from the reference
2326 * driver. They agree
2327 */
2328static void
2329rtw_rfmd_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
2330 int before_rf, int digphy)
2331{
2332 uint32_t anaparm;
2333
2334 anaparm = RTW_READ(regs, RTW_ANAPARM);
2335 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF);
2336
2337 switch (power) {
2338 case RTW_OFF:
2339 if (before_rf)
2340 return;
2341 anaparm |= RTW_ANAPARM_RFPOW_RFMD_OFF;
2342 anaparm |= RTW_ANAPARM_TXDACOFF;
2343 break;
2344 case RTW_SLEEP:
2345 if (!before_rf)
2346 return;
2347 anaparm |= RTW_ANAPARM_RFPOW_RFMD_SLEEP;
2348 anaparm |= RTW_ANAPARM_TXDACOFF;
2349 break;
2350 case RTW_ON:
2351 if (!before_rf)
2352 return;
2353 anaparm |= RTW_ANAPARM_RFPOW_RFMD_ON;
2354 break;
2355 }
2356 RTW_DPRINTF(RTW_DEBUG_PWR,
2357 ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n",
2358 __func__, rtw_pwrstate_string(power),
2359 (before_rf) ? "before" : "after", anaparm));
2360
2361 RTW_WRITE(regs, RTW_ANAPARM, anaparm);
2362 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
2363}
2364
2365static void
2366rtw_philips_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
2367 int before_rf, int digphy)
2368{
2369 uint32_t anaparm;
2370
2371 anaparm = RTW_READ(regs, RTW_ANAPARM);
2372 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF);
2373
2374 switch (power) {
2375 case RTW_OFF:
2376 if (before_rf)
2377 return;
2378 anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_OFF;
2379 anaparm |= RTW_ANAPARM_TXDACOFF;
2380 break;
2381 case RTW_SLEEP:
2382 if (!before_rf)
2383 return;
2384 anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_SLEEP;
2385 anaparm |= RTW_ANAPARM_TXDACOFF;
2386 break;
2387 case RTW_ON:
2388 if (!before_rf)
2389 return;
2390 if (digphy) {
2391 anaparm |= RTW_ANAPARM_RFPOW_DIG_PHILIPS_ON;
2392 /* XXX guess */
2393 anaparm |= RTW_ANAPARM_TXDACOFF;
2394 } else
2395 anaparm |= RTW_ANAPARM_RFPOW_ANA_PHILIPS_ON;
2396 break;
2397 }
2398 RTW_DPRINTF(RTW_DEBUG_PWR,
2399 ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n",
2400 __func__, rtw_pwrstate_string(power),
2401 (before_rf) ? "before" : "after", anaparm));
2402
2403 RTW_WRITE(regs, RTW_ANAPARM, anaparm);
2404 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
2405}
2406
2407static void
2408rtw_pwrstate0(struct rtw_softc *sc, enum rtw_pwrstate power, int before_rf,
2409 int digphy)
2410{
2411 struct rtw_regs *regs = &sc->sc_regs;
2412
2413 rtw_set_access(regs, RTW_ACCESS_ANAPARM);
2414
2415 (*sc->sc_pwrstate_cb)(regs, power, before_rf, digphy);
2416
2417 rtw_set_access(regs, RTW_ACCESS_NONE);
2418
2419 return;
2420}
2421
2422static int
2423rtw_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power)
2424{
2425 int rc;
2426
2427 RTW_DPRINTF(RTW_DEBUG_PWR,
2428 ("%s: %s->%s\n", __func__,
2429 rtw_pwrstate_string(sc->sc_pwrstate), rtw_pwrstate_string(power)));
2430
2431 if (sc->sc_pwrstate == power)
2432 return 0;
2433
2434 rtw_pwrstate0(sc, power, 1, sc->sc_flags & RTW_F_DIGPHY);
2435 rc = rtw_rf_pwrstate(sc->sc_rf, power);
2436 rtw_pwrstate0(sc, power, 0, sc->sc_flags & RTW_F_DIGPHY);
2437
2438 switch (power) {
2439 case RTW_ON:
2440 /* TBD set LEDs */
2441 break;
2442 case RTW_SLEEP:
2443 /* TBD */
2444 break;
2445 case RTW_OFF:
2446 /* TBD */
2447 break;
2448 }
2449 if (rc == 0)
2450 sc->sc_pwrstate = power;
2451 else
2452 sc->sc_pwrstate = RTW_OFF;
2453 return rc;
2454}
2455
2456static int
2457rtw_tune(struct rtw_softc *sc)
2458{
2459 struct ieee80211com *ic = &sc->sc_ic;
2460 struct rtw_tx_radiotap_header *rt = &sc->sc_txtap;
2461 struct rtw_rx_radiotap_header *rr = &sc->sc_rxtap;
2462 u_int chan;
2463 int rc;
2464 int antdiv = sc->sc_flags & RTW_F_ANTDIV,
2465 dflantb = sc->sc_flags & RTW_F_DFLANTB;
2466
2467 chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
2468 KASSERT(chan != IEEE80211_CHAN_ANY);
2469
2470 rt->rt_chan_freq = htole16(ic->ic_curchan->ic_freq);
2471 rt->rt_chan_flags = htole16(ic->ic_curchan->ic_flags);
2472
2473 rr->rr_chan_freq = htole16(ic->ic_curchan->ic_freq);
2474 rr->rr_chan_flags = htole16(ic->ic_curchan->ic_flags);
2475
2476 if (chan == sc->sc_cur_chan) {
2477 RTW_DPRINTF(RTW_DEBUG_TUNE,
2478 ("%s: already tuned chan #%d\n", __func__, chan));
2479 return 0;
2480 }
2481
2482 rtw_suspend_ticks(sc);
2483
2484 rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 0);
2485
2486 /* TBD wait for Tx to complete */
2487
2488 KASSERT(device_has_power(sc->sc_dev));
2489
2490 if ((rc = rtw_phy_init(&sc->sc_regs, sc->sc_rf,
2491 rtw_chan2txpower(&sc->sc_srom, ic, ic->ic_curchan), sc->sc_csthr,
2492 ic->ic_curchan->ic_freq, antdiv, dflantb, RTW_ON)) != 0) {
2493 /* XXX condition on powersaving */
2494 aprint_error_dev(sc->sc_dev, "phy init failed\n");
2495 }
2496
2497 sc->sc_cur_chan = chan;
2498
2499 rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 1);
2500
2501 rtw_resume_ticks(sc);
2502
2503 return rc;
2504}
2505
2506bool
2507rtw_suspend(device_t self, const pmf_qual_t *qual)
2508{
2509 int rc;
2510 struct rtw_softc *sc = device_private(self);
2511
2512 sc->sc_flags &= ~RTW_F_DK_VALID;
2513
2514 if (!device_has_power(self))
2515 return false;
2516
2517 /* turn off PHY */
2518 if ((rc = rtw_pwrstate(sc, RTW_OFF)) != 0) {
2519 aprint_error_dev(self, "failed to turn off PHY (%d)\n", rc);
2520 return false;
2521 }
2522
2523 rtw_disable_interrupts(&sc->sc_regs);
2524
2525 return true;
2526}
2527
2528bool
2529rtw_resume(device_t self, const pmf_qual_t *qual)
2530{
2531 struct rtw_softc *sc = device_private(self);
2532
2533 /* Power may have been removed, resetting WEP keys.
2534 */
2535 sc->sc_flags &= ~RTW_F_DK_VALID;
2536 rtw_enable_interrupts(sc);
2537
2538 return true;
2539}
2540
2541static void
2542rtw_transmit_config(struct rtw_regs *regs)
2543{
2544 uint32_t tcr;
2545
2546 tcr = RTW_READ(regs, RTW_TCR);
2547
2548 tcr |= RTW_TCR_CWMIN;
2549 tcr &= ~RTW_TCR_MXDMA_MASK;
2550 tcr |= RTW_TCR_MXDMA_256;
2551 tcr |= RTW_TCR_SAT; /* send ACK as fast as possible */
2552 tcr &= ~RTW_TCR_LBK_MASK;
2553 tcr |= RTW_TCR_LBK_NORMAL; /* normal operating mode */
2554
2555 /* set short/long retry limits */
2556 tcr &= ~(RTW_TCR_SRL_MASK|RTW_TCR_LRL_MASK);
2557 tcr |= __SHIFTIN(4, RTW_TCR_SRL_MASK) | __SHIFTIN(4, RTW_TCR_LRL_MASK);
2558
2559 tcr &= ~RTW_TCR_CRC; /* NIC appends CRC32 */
2560
2561 RTW_WRITE(regs, RTW_TCR, tcr);
2562 RTW_SYNC(regs, RTW_TCR, RTW_TCR);
2563}
2564
2565static void
2566rtw_disable_interrupts(struct rtw_regs *regs)
2567{
2568 RTW_WRITE16(regs, RTW_IMR, 0);
2569 RTW_WBW(regs, RTW_IMR, RTW_ISR);
2570 RTW_WRITE16(regs, RTW_ISR, 0xffff);
2571 RTW_SYNC(regs, RTW_IMR, RTW_ISR);
2572}
2573
2574static void
2575rtw_enable_interrupts(struct rtw_softc *sc)
2576{
2577 struct rtw_regs *regs = &sc->sc_regs;
2578
2579 sc->sc_inten = RTW_INTR_RX|RTW_INTR_TX|RTW_INTR_BEACON|RTW_INTR_ATIMINT;
2580 sc->sc_inten |= RTW_INTR_IOERROR|RTW_INTR_TIMEOUT;
2581
2582 RTW_WRITE16(regs, RTW_IMR, sc->sc_inten);
2583 RTW_WBW(regs, RTW_IMR, RTW_ISR);
2584 RTW_WRITE16(regs, RTW_ISR, 0xffff);
2585 RTW_SYNC(regs, RTW_IMR, RTW_ISR);
2586
2587 /* XXX necessary? */
2588 if (sc->sc_intr_ack != NULL)
2589 (*sc->sc_intr_ack)(regs);
2590}
2591
2592static void
2593rtw_set_nettype(struct rtw_softc *sc, enum ieee80211_opmode opmode)
2594{
2595 uint8_t msr;
2596
2597 /* I'm guessing that MSR is protected as CONFIG[0123] are. */
2598 rtw_set_access(&sc->sc_regs, RTW_ACCESS_CONFIG);
2599
2600 msr = RTW_READ8(&sc->sc_regs, RTW_MSR) & ~RTW_MSR_NETYPE_MASK;
2601
2602 switch (opmode) {
2603 case IEEE80211_M_AHDEMO:
2604 case IEEE80211_M_IBSS:
2605 msr |= RTW_MSR_NETYPE_ADHOC_OK;
2606 break;
2607 case IEEE80211_M_HOSTAP:
2608 msr |= RTW_MSR_NETYPE_AP_OK;
2609 break;
2610 case IEEE80211_M_MONITOR:
2611 /* XXX */
2612 msr |= RTW_MSR_NETYPE_NOLINK;
2613 break;
2614 case IEEE80211_M_STA:
2615 msr |= RTW_MSR_NETYPE_INFRA_OK;
2616 break;
2617 }
2618 RTW_WRITE8(&sc->sc_regs, RTW_MSR, msr);
2619
2620 rtw_set_access(&sc->sc_regs, RTW_ACCESS_NONE);
2621}
2622
2623#define rtw_calchash(addr) \
2624 (ether_crc32_be((addr), IEEE80211_ADDR_LEN) >> 26)
2625
2626static void
2627rtw_pktfilt_load(struct rtw_softc *sc)
2628{
2629 struct rtw_regs *regs = &sc->sc_regs;
2630 struct ieee80211com *ic = &sc->sc_ic;
2631 struct ethercom *ec = &sc->sc_ec;
2632 struct ifnet *ifp = &sc->sc_if;
2633 int hash;
2634 uint32_t hashes[2] = { 0, 0 };
2635 struct ether_multi *enm;
2636 struct ether_multistep step;
2637
2638 /* XXX might be necessary to stop Rx/Tx engines while setting filters */
2639
2640 sc->sc_rcr &= ~RTW_RCR_PKTFILTER_MASK;
2641 sc->sc_rcr &= ~(RTW_RCR_MXDMA_MASK | RTW_RCR_RXFTH_MASK);
2642
2643 sc->sc_rcr |= RTW_RCR_PKTFILTER_DEFAULT;
2644 /* MAC auto-reset PHY (huh?) */
2645 sc->sc_rcr |= RTW_RCR_ENMARP;
2646 /* DMA whole Rx packets, only. Set Tx DMA burst size to 1024 bytes. */
2647 sc->sc_rcr |= RTW_RCR_MXDMA_1024 | RTW_RCR_RXFTH_WHOLE;
2648
2649 switch (ic->ic_opmode) {
2650 case IEEE80211_M_MONITOR:
2651 sc->sc_rcr |= RTW_RCR_MONITOR;
2652 break;
2653 case IEEE80211_M_AHDEMO:
2654 case IEEE80211_M_IBSS:
2655 /* receive broadcasts in our BSS */
2656 sc->sc_rcr |= RTW_RCR_ADD3;
2657 break;
2658 default:
2659 break;
2660 }
2661
2662 ifp->if_flags &= ~IFF_ALLMULTI;
2663
2664 /*
2665 * Program the 64-bit multicast hash filter.
2666 */
2667 ETHER_FIRST_MULTI(step, ec, enm);
2668 while (enm != NULL) {
2669 /* XXX */
2670 if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
2671 ETHER_ADDR_LEN) != 0) {
2672 ifp->if_flags |= IFF_ALLMULTI;
2673 break;
2674 }
2675
2676 hash = rtw_calchash(enm->enm_addrlo);
2677 hashes[hash >> 5] |= (1 << (hash & 0x1f));
2678 ETHER_NEXT_MULTI(step, enm);
2679 }
2680
2681 /* XXX accept all broadcast if scanning */
2682 if ((ifp->if_flags & IFF_BROADCAST) != 0)
2683 sc->sc_rcr |= RTW_RCR_AB; /* accept all broadcast */
2684
2685 if (ifp->if_flags & IFF_PROMISC) {
2686 sc->sc_rcr |= RTW_RCR_AB; /* accept all broadcast */
2687 sc->sc_rcr |= RTW_RCR_ACRC32; /* accept frames failing CRC */
2688 sc->sc_rcr |= RTW_RCR_AICV; /* accept frames failing ICV */
2689 ifp->if_flags |= IFF_ALLMULTI;
2690 }
2691
2692 if (ifp->if_flags & IFF_ALLMULTI)
2693 hashes[0] = hashes[1] = 0xffffffff;
2694
2695 if ((hashes[0] | hashes[1]) != 0)
2696 sc->sc_rcr |= RTW_RCR_AM; /* accept multicast */
2697
2698 RTW_WRITE(regs, RTW_MAR0, hashes[0]);
2699 RTW_WRITE(regs, RTW_MAR1, hashes[1]);
2700 RTW_WRITE(regs, RTW_RCR, sc->sc_rcr);
2701 RTW_SYNC(regs, RTW_MAR0, RTW_RCR); /* RTW_MAR0 < RTW_MAR1 < RTW_RCR */
2702
2703 DPRINTF(sc, RTW_DEBUG_PKTFILT,
2704 ("%s: RTW_MAR0 %08x RTW_MAR1 %08x RTW_RCR %08x\n",
2705 device_xname(sc->sc_dev), RTW_READ(regs, RTW_MAR0),
2706 RTW_READ(regs, RTW_MAR1), RTW_READ(regs, RTW_RCR)));
2707}
2708
2709static struct mbuf *
2710rtw_beacon_alloc(struct rtw_softc *sc, struct ieee80211_node *ni)
2711{
2712 struct ieee80211com *ic = &sc->sc_ic;
2713 struct mbuf *m;
2714 struct ieee80211_beacon_offsets boff;
2715
2716 if ((m = ieee80211_beacon_alloc(ic, ni, &boff)) != NULL) {
2717 RTW_DPRINTF(RTW_DEBUG_BEACON,
2718 ("%s: m %p len %u\n", __func__, m, m->m_len));
2719 }
2720 return m;
2721}
2722
2723/* Must be called at splnet. */
2724static int
2725rtw_init(struct ifnet *ifp)
2726{
2727 struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc;
2728 struct ieee80211com *ic = &sc->sc_ic;
2729 struct rtw_regs *regs = &sc->sc_regs;
2730 int rc;
2731
2732 if (device_is_active(sc->sc_dev)) {
2733 /* Cancel pending I/O and reset. */
2734 rtw_stop(ifp, 0);
2735 } else if (!pmf_device_resume(sc->sc_dev, &sc->sc_qual) ||
2736 !device_is_active(sc->sc_dev))
2737 return 0;
2738
2739 DPRINTF(sc, RTW_DEBUG_TUNE, ("%s: channel %d freq %d flags 0x%04x\n",
2740 __func__, ieee80211_chan2ieee(ic, ic->ic_curchan),
2741 ic->ic_curchan->ic_freq, ic->ic_curchan->ic_flags));
2742
2743 if ((rc = rtw_pwrstate(sc, RTW_OFF)) != 0)
2744 goto out;
2745
2746 if ((rc = rtw_swring_setup(sc)) != 0)
2747 goto out;
2748
2749 rtw_transmit_config(regs);
2750
2751 rtw_set_access(regs, RTW_ACCESS_CONFIG);
2752
2753 RTW_WRITE8(regs, RTW_MSR, 0x0); /* no link */
2754 RTW_WBW(regs, RTW_MSR, RTW_BRSR);
2755
2756 /* long PLCP header, 1Mb/2Mb basic rate */
2757 RTW_WRITE16(regs, RTW_BRSR, RTW_BRSR_MBR8180_2MBPS);
2758 RTW_SYNC(regs, RTW_BRSR, RTW_BRSR);
2759
2760 rtw_set_access(regs, RTW_ACCESS_ANAPARM);
2761 rtw_set_access(regs, RTW_ACCESS_NONE);
2762
2763 /* XXX from reference sources */
2764 RTW_WRITE(regs, RTW_FEMR, 0xffff);
2765 RTW_SYNC(regs, RTW_FEMR, RTW_FEMR);
2766
2767 rtw_set_rfprog(regs, sc->sc_rfchipid, sc->sc_dev);
2768
2769 RTW_WRITE8(regs, RTW_PHYDELAY, sc->sc_phydelay);
2770 /* from Linux driver */
2771 RTW_WRITE8(regs, RTW_CRCOUNT, RTW_CRCOUNT_MAGIC);
2772
2773 RTW_SYNC(regs, RTW_PHYDELAY, RTW_CRCOUNT);
2774
2775 rtw_enable_interrupts(sc);
2776
2777 rtw_pktfilt_load(sc);
2778
2779 rtw_hwring_setup(sc);
2780
2781 rtw_wep_setkeys(sc, ic->ic_nw_keys, ic->ic_def_txkey);
2782
2783 rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 1);
2784
2785 ifp->if_flags |= IFF_RUNNING;
2786 ic->ic_state = IEEE80211_S_INIT;
2787
2788 RTW_WRITE16(regs, RTW_BSSID16, 0x0);
2789 RTW_WRITE(regs, RTW_BSSID32, 0x0);
2790
2791 rtw_resume_ticks(sc);
2792
2793 rtw_set_nettype(sc, IEEE80211_M_MONITOR);
2794
2795 if (ic->ic_opmode == IEEE80211_M_MONITOR)
2796 return ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
2797 else
2798 return ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
2799
2800out:
2801 aprint_error_dev(sc->sc_dev, "interface not running\n");
2802 return rc;
2803}
2804
2805static inline void
2806rtw_led_init(struct rtw_regs *regs)
2807{
2808 uint8_t cfg0, cfg1;
2809
2810 rtw_set_access(regs, RTW_ACCESS_CONFIG);
2811
2812 cfg0 = RTW_READ8(regs, RTW_CONFIG0);
2813 cfg0 |= RTW_CONFIG0_LEDGPOEN;
2814 RTW_WRITE8(regs, RTW_CONFIG0, cfg0);
2815
2816 cfg1 = RTW_READ8(regs, RTW_CONFIG1);
2817 RTW_DPRINTF(RTW_DEBUG_LED,
2818 ("%s: read %" PRIx8 " from reg[CONFIG1]\n", __func__, cfg1));
2819
2820 cfg1 &= ~RTW_CONFIG1_LEDS_MASK;
2821 cfg1 |= RTW_CONFIG1_LEDS_TX_RX;
2822 RTW_WRITE8(regs, RTW_CONFIG1, cfg1);
2823
2824 rtw_set_access(regs, RTW_ACCESS_NONE);
2825}
2826
2827/*
2828 * IEEE80211_S_INIT: LED1 off
2829 *
2830 * IEEE80211_S_AUTH,
2831 * IEEE80211_S_ASSOC,
2832 * IEEE80211_S_SCAN: LED1 blinks @ 1 Hz, blinks at 5Hz for tx/rx
2833 *
2834 * IEEE80211_S_RUN: LED1 on, blinks @ 5Hz for tx/rx
2835 */
2836static void
2837rtw_led_newstate(struct rtw_softc *sc, enum ieee80211_state nstate)
2838{
2839 struct rtw_led_state *ls;
2840
2841 ls = &sc->sc_led_state;
2842
2843 switch (nstate) {
2844 case IEEE80211_S_INIT:
2845 rtw_led_init(&sc->sc_regs);
2846 aprint_debug_dev(sc->sc_dev, "stopping blink\n");
2847 callout_stop(&ls->ls_slow_ch);
2848 callout_stop(&ls->ls_fast_ch);
2849 ls->ls_slowblink = 0;
2850 ls->ls_actblink = 0;
2851 ls->ls_default = 0;
2852 break;
2853 case IEEE80211_S_SCAN:
2854 aprint_debug_dev(sc->sc_dev, "scheduling blink\n");
2855 callout_schedule(&ls->ls_slow_ch, RTW_LED_SLOW_TICKS);
2856 callout_schedule(&ls->ls_fast_ch, RTW_LED_FAST_TICKS);
2857 /*FALLTHROUGH*/
2858 case IEEE80211_S_AUTH:
2859 case IEEE80211_S_ASSOC:
2860 ls->ls_default = RTW_LED1;
2861 ls->ls_actblink = RTW_LED1;
2862 ls->ls_slowblink = RTW_LED1;
2863 break;
2864 case IEEE80211_S_RUN:
2865 ls->ls_slowblink = 0;
2866 break;
2867 }
2868 rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid);
2869}
2870
2871static void
2872rtw_led_set(struct rtw_led_state *ls, struct rtw_regs *regs, int hwverid)
2873{
2874 uint8_t led_condition;
2875 bus_size_t ofs;
2876 uint8_t mask, newval, val;
2877
2878 led_condition = ls->ls_default;
2879
2880 if (ls->ls_state & RTW_LED_S_SLOW)
2881 led_condition ^= ls->ls_slowblink;
2882 if (ls->ls_state & (RTW_LED_S_RX|RTW_LED_S_TX))
2883 led_condition ^= ls->ls_actblink;
2884
2885 RTW_DPRINTF(RTW_DEBUG_LED,
2886 ("%s: LED condition %" PRIx8 "\n", __func__, led_condition));
2887
2888 switch (hwverid) {
2889 default:
2890 case 'F':
2891 ofs = RTW_PSR;
2892 newval = mask = RTW_PSR_LEDGPO0 | RTW_PSR_LEDGPO1;
2893 if (led_condition & RTW_LED0)
2894 newval &= ~RTW_PSR_LEDGPO0;
2895 if (led_condition & RTW_LED1)
2896 newval &= ~RTW_PSR_LEDGPO1;
2897 break;
2898 case 'D':
2899 ofs = RTW_9346CR;
2900 mask = RTW_9346CR_EEM_MASK | RTW_9346CR_EEDI | RTW_9346CR_EECS;
2901 newval = RTW_9346CR_EEM_PROGRAM;
2902 if (led_condition & RTW_LED0)
2903 newval |= RTW_9346CR_EEDI;
2904 if (led_condition & RTW_LED1)
2905 newval |= RTW_9346CR_EECS;
2906 break;
2907 }
2908 val = RTW_READ8(regs, ofs);
2909 RTW_DPRINTF(RTW_DEBUG_LED,
2910 ("%s: read %" PRIx8 " from reg[%#02" PRIxPTR "]\n", __func__, val,
2911 (uintptr_t)ofs));
2912 val &= ~mask;
2913 val |= newval;
2914 RTW_WRITE8(regs, ofs, val);
2915 RTW_DPRINTF(RTW_DEBUG_LED,
2916 ("%s: wrote %" PRIx8 " to reg[%#02" PRIxPTR "]\n", __func__, val,
2917 (uintptr_t)ofs));
2918 RTW_SYNC(regs, ofs, ofs);
2919}
2920
2921static void
2922rtw_led_fastblink(void *arg)
2923{
2924 int ostate, s;
2925 struct rtw_softc *sc = (struct rtw_softc *)arg;
2926 struct rtw_led_state *ls = &sc->sc_led_state;
2927
2928 s = splnet();
2929 ostate = ls->ls_state;
2930 ls->ls_state ^= ls->ls_event;
2931
2932 if ((ls->ls_event & RTW_LED_S_TX) == 0)
2933 ls->ls_state &= ~RTW_LED_S_TX;
2934
2935 if ((ls->ls_event & RTW_LED_S_RX) == 0)
2936 ls->ls_state &= ~RTW_LED_S_RX;
2937
2938 ls->ls_event = 0;
2939
2940 if (ostate != ls->ls_state)
2941 rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid);
2942 splx(s);
2943
2944 aprint_debug_dev(sc->sc_dev, "scheduling fast blink\n");
2945 callout_schedule(&ls->ls_fast_ch, RTW_LED_FAST_TICKS);
2946}
2947
2948static void
2949rtw_led_slowblink(void *arg)
2950{
2951 int s;
2952 struct rtw_softc *sc = (struct rtw_softc *)arg;
2953 struct rtw_led_state *ls = &sc->sc_led_state;
2954
2955 s = splnet();
2956 ls->ls_state ^= RTW_LED_S_SLOW;
2957 rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid);
2958 splx(s);
2959 aprint_debug_dev(sc->sc_dev, "scheduling slow blink\n");
2960 callout_schedule(&ls->ls_slow_ch, RTW_LED_SLOW_TICKS);
2961}
2962
2963static void
2964rtw_led_detach(struct rtw_led_state *ls)
2965{
2966 callout_destroy(&ls->ls_fast_ch);
2967 callout_destroy(&ls->ls_slow_ch);
2968}
2969
2970static void
2971rtw_led_attach(struct rtw_led_state *ls, void *arg)
2972{
2973 callout_init(&ls->ls_fast_ch, 0);
2974 callout_init(&ls->ls_slow_ch, 0);
2975 callout_setfunc(&ls->ls_fast_ch, rtw_led_fastblink, arg);
2976 callout_setfunc(&ls->ls_slow_ch, rtw_led_slowblink, arg);
2977}
2978
2979static int
2980rtw_ioctl(struct ifnet *ifp, u_long cmd, void *data)
2981{
2982 int rc = 0, s;
2983 struct rtw_softc *sc = ifp->if_softc;
2984
2985 s = splnet();
2986 if (cmd == SIOCSIFFLAGS) {
2987 if ((rc = ifioctl_common(ifp, cmd, data)) != 0)
2988 ;
2989 else switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) {
2990 case IFF_UP:
2991 rc = rtw_init(ifp);
2992 RTW_PRINT_REGS(&sc->sc_regs, ifp->if_xname, __func__);
2993 break;
2994 case IFF_UP|IFF_RUNNING:
2995 if (device_activation(sc->sc_dev, DEVACT_LEVEL_DRIVER))
2996 rtw_pktfilt_load(sc);
2997 RTW_PRINT_REGS(&sc->sc_regs, ifp->if_xname, __func__);
2998 break;
2999 case IFF_RUNNING:
3000 RTW_PRINT_REGS(&sc->sc_regs, ifp->if_xname, __func__);
3001 rtw_stop(ifp, 1);
3002 break;
3003 default:
3004 break;
3005 }
3006 } else if ((rc = ieee80211_ioctl(&sc->sc_ic, cmd, data)) != ENETRESET)
3007 ; /* nothing to do */
3008 else if (cmd == SIOCADDMULTI || cmd == SIOCDELMULTI) {
3009 /* reload packet filter if running */
3010 if (ifp->if_flags & IFF_RUNNING)
3011 rtw_pktfilt_load(sc);
3012 rc = 0;
3013 } else if ((ifp->if_flags & IFF_UP) != 0)
3014 rc = rtw_init(ifp);
3015 else
3016 rc = 0;
3017 splx(s);
3018 return rc;
3019}
3020
3021/* Select a transmit ring with at least one h/w and s/w descriptor free.
3022 * Return 0 on success, -1 on failure.
3023 */
3024static inline int
3025rtw_txring_choose(struct rtw_softc *sc, struct rtw_txsoft_blk **tsbp,
3026 struct rtw_txdesc_blk **tdbp, int pri)
3027{
3028 struct rtw_txsoft_blk *tsb;
3029 struct rtw_txdesc_blk *tdb;
3030
3031 KASSERT(pri >= 0 && pri < RTW_NTXPRI);
3032
3033 tsb = &sc->sc_txsoft_blk[pri];
3034 tdb = &sc->sc_txdesc_blk[pri];
3035
3036 if (SIMPLEQ_EMPTY(&tsb->tsb_freeq) || tdb->tdb_nfree == 0) {
3037 if (tsb->tsb_tx_timer == 0)
3038 tsb->tsb_tx_timer = 5;
3039 *tsbp = NULL;
3040 *tdbp = NULL;
3041 return -1;
3042 }
3043 *tsbp = tsb;
3044 *tdbp = tdb;
3045 return 0;
3046}
3047
3048static inline struct mbuf *
3049rtw_80211_dequeue(struct rtw_softc *sc, struct ifqueue *ifq, int pri,
3050 struct rtw_txsoft_blk **tsbp, struct rtw_txdesc_blk **tdbp,
3051 struct ieee80211_node **nip, short *if_flagsp)
3052{
3053 struct mbuf *m;
3054
3055 if (IF_IS_EMPTY(ifq))
3056 return NULL;
3057 if (rtw_txring_choose(sc, tsbp, tdbp, pri) == -1) {
3058 DPRINTF(sc, RTW_DEBUG_XMIT_RSRC, ("%s: no ring %d descriptor\n",
3059 __func__, pri));
3060 *if_flagsp |= IFF_OACTIVE;
3061 sc->sc_if.if_timer = 1;
3062 return NULL;
3063 }
3064 IF_DEQUEUE(ifq, m);
3065 *nip = M_GETCTX(m, struct ieee80211_node *);
3066 M_SETCTX(m, NULL);
3067 KASSERT(*nip != NULL);
3068 return m;
3069}
3070
3071/* Point *mp at the next 802.11 frame to transmit. Point *tsbp
3072 * at the driver's selection of transmit control block for the packet.
3073 */
3074static inline int
3075rtw_dequeue(struct ifnet *ifp, struct rtw_txsoft_blk **tsbp,
3076 struct rtw_txdesc_blk **tdbp, struct mbuf **mp,
3077 struct ieee80211_node **nip)
3078{
3079 int pri;
3080 struct ether_header *eh;
3081 struct mbuf *m0;
3082 struct rtw_softc *sc;
3083 short *if_flagsp;
3084
3085 *mp = NULL;
3086
3087 sc = (struct rtw_softc *)ifp->if_softc;
3088
3089 DPRINTF(sc, RTW_DEBUG_XMIT,
3090 ("%s: enter %s\n", device_xname(sc->sc_dev), __func__));
3091
3092 if_flagsp = &ifp->if_flags;
3093
3094 if (sc->sc_ic.ic_state == IEEE80211_S_RUN &&
3095 (*mp = rtw_80211_dequeue(sc, &sc->sc_beaconq, RTW_TXPRIBCN, tsbp,
3096 tdbp, nip, if_flagsp)) != NULL) {
3097 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue beacon frame\n",
3098 __func__));
3099 return 0;
3100 }
3101
3102 if ((*mp = rtw_80211_dequeue(sc, &sc->sc_ic.ic_mgtq, RTW_TXPRIMD, tsbp,
3103 tdbp, nip, if_flagsp)) != NULL) {
3104 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue mgt frame\n",
3105 __func__));
3106 return 0;
3107 }
3108
3109 if (sc->sc_ic.ic_state != IEEE80211_S_RUN) {
3110 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: not running\n", __func__));
3111 return 0;
3112 }
3113
3114 IFQ_POLL(&ifp->if_snd, m0);
3115 if (m0 == NULL) {
3116 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: no frame ready\n",
3117 __func__));
3118 return 0;
3119 }
3120
3121 pri = ((m0->m_flags & M_PWR_SAV) != 0) ? RTW_TXPRIHI : RTW_TXPRIMD;
3122
3123 if (rtw_txring_choose(sc, tsbp, tdbp, pri) == -1) {
3124 DPRINTF(sc, RTW_DEBUG_XMIT_RSRC, ("%s: no ring %d descriptor\n",
3125 __func__, pri));
3126 *if_flagsp |= IFF_OACTIVE;
3127 sc->sc_if.if_timer = 1;
3128 return 0;
3129 }
3130
3131 IFQ_DEQUEUE(&ifp->if_snd, m0);
3132 if (m0 == NULL) {
3133 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: no frame ready\n",
3134 __func__));
3135 return 0;
3136 }
3137 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue data frame\n", __func__));
3138 ifp->if_opackets++;
3139 bpf_mtap(ifp, m0);
3140 eh = mtod(m0, struct ether_header *);
3141 *nip = ieee80211_find_txnode(&sc->sc_ic, eh->ether_dhost);
3142 if (*nip == NULL) {
3143 /* NB: ieee80211_find_txnode does stat+msg */
3144 m_freem(m0);
3145 return -1;
3146 }
3147 if ((m0 = ieee80211_encap(&sc->sc_ic, m0, *nip)) == NULL) {
3148 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: encap error\n", __func__));
3149 ifp->if_oerrors++;
3150 return -1;
3151 }
3152 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: leave\n", __func__));
3153 *mp = m0;
3154 return 0;
3155}
3156
3157static int
3158rtw_seg_too_short(bus_dmamap_t dmamap)
3159{
3160 int i;
3161 for (i = 0; i < dmamap->dm_nsegs; i++) {
3162 if (dmamap->dm_segs[i].ds_len < 4)
3163 return 1;
3164 }
3165 return 0;
3166}
3167
3168/* TBD factor with atw_start */
3169static struct mbuf *
3170rtw_dmamap_load_txbuf(bus_dma_tag_t dmat, bus_dmamap_t dmam, struct mbuf *chain,
3171 u_int ndescfree, device_t dev)
3172{
3173 int first, rc;
3174 struct mbuf *m, *m0;
3175
3176 m0 = chain;
3177
3178 /*
3179 * Load the DMA map. Copy and try (once) again if the packet
3180 * didn't fit in the alloted number of segments.
3181 */
3182 for (first = 1;
3183 ((rc = bus_dmamap_load_mbuf(dmat, dmam, m0,
3184 BUS_DMA_WRITE|BUS_DMA_NOWAIT)) != 0 ||
3185 dmam->dm_nsegs > ndescfree || rtw_seg_too_short(dmam)) && first;
3186 first = 0) {
3187 if (rc == 0) {
3188#ifdef RTW_DIAGxxx
3189 if (rtw_seg_too_short(dmam)) {
3190 printf("%s: short segment, mbuf lengths:", __func__);
3191 for (m = m0; m; m = m->m_next)
3192 printf(" %d", m->m_len);
3193 printf("\n");
3194 }
3195#endif
3196 bus_dmamap_unload(dmat, dmam);
3197 }
3198 MGETHDR(m, M_DONTWAIT, MT_DATA);
3199 if (m == NULL) {
3200 aprint_error_dev(dev, "unable to allocate Tx mbuf\n");
3201 break;
3202 }
3203 if (m0->m_pkthdr.len > MHLEN) {
3204 MCLGET(m, M_DONTWAIT);
3205 if ((m->m_flags & M_EXT) == 0) {
3206 aprint_error_dev(dev,
3207 "cannot allocate Tx cluster\n");
3208 m_freem(m);
3209 break;
3210 }
3211 }
3212 m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, void *));
3213 m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len;
3214 m_freem(m0);
3215 m0 = m;
3216 m = NULL;
3217 }
3218 if (rc != 0) {
3219 aprint_error_dev(dev, "cannot load Tx buffer, rc = %d\n", rc);
3220 m_freem(m0);
3221 return NULL;
3222 } else if (rtw_seg_too_short(dmam)) {
3223 aprint_error_dev(dev,
3224 "cannot load Tx buffer, segment too short\n");
3225 bus_dmamap_unload(dmat, dmam);
3226 m_freem(m0);
3227 return NULL;
3228 } else if (dmam->dm_nsegs > ndescfree) {
3229 aprint_error_dev(dev, "too many tx segments\n");
3230 bus_dmamap_unload(dmat, dmam);
3231 m_freem(m0);
3232 return NULL;
3233 }
3234 return m0;
3235}
3236
3237#ifdef RTW_DEBUG
3238static void
3239rtw_print_txdesc(struct rtw_softc *sc, const char *action,
3240 struct rtw_txsoft *ts, struct rtw_txdesc_blk *tdb, int desc)
3241{
3242 struct rtw_txdesc *td = &tdb->tdb_desc[desc];
3243 DPRINTF(sc, RTW_DEBUG_XMIT_DESC, ("%s: %p %s txdesc[%d] next %#08x "
3244 "buf %#08x ctl0 %#08x ctl1 %#08x len %#08x\n",
3245 device_xname(sc->sc_dev), ts, action, desc,
3246 le32toh(td->td_buf), le32toh(td->td_next),
3247 le32toh(td->td_ctl0), le32toh(td->td_ctl1),
3248 le32toh(td->td_len)));
3249}
3250#endif /* RTW_DEBUG */
3251
3252static void
3253rtw_start(struct ifnet *ifp)
3254{
3255 int desc, i, lastdesc, npkt, rate;
3256 uint32_t proto_ctl0, ctl0, ctl1;
3257 bus_dmamap_t dmamap;
3258 struct ieee80211com *ic;
3259 struct ieee80211_duration *d0;
3260 struct ieee80211_frame_min *wh;
3261 struct ieee80211_node *ni = NULL; /* XXX: GCC */
3262 struct mbuf *m0;
3263 struct rtw_softc *sc;
3264 struct rtw_txsoft_blk *tsb = NULL; /* XXX: GCC */
3265 struct rtw_txdesc_blk *tdb = NULL; /* XXX: GCC */
3266 struct rtw_txsoft *ts;
3267 struct rtw_txdesc *td;
3268 struct ieee80211_key *k;
3269
3270 sc = (struct rtw_softc *)ifp->if_softc;
3271 ic = &sc->sc_ic;
3272
3273 DPRINTF(sc, RTW_DEBUG_XMIT,
3274 ("%s: enter %s\n", device_xname(sc->sc_dev), __func__));
3275
3276 if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
3277 goto out;
3278
3279 /* XXX do real rate control */
3280 proto_ctl0 = RTW_TXCTL0_RTSRATE_1MBPS;
3281
3282 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0)
3283 proto_ctl0 |= RTW_TXCTL0_SPLCP;
3284
3285 for (;;) {
3286 if (rtw_dequeue(ifp, &tsb, &tdb, &m0, &ni) == -1)
3287 continue;
3288 if (m0 == NULL)
3289 break;
3290
3291 wh = mtod(m0, struct ieee80211_frame_min *);
3292
3293 if ((wh->i_fc[1] & IEEE80211_FC1_WEP) != 0 &&
3294 (k = ieee80211_crypto_encap(ic, ni, m0)) == NULL) {
3295 m_freem(m0);
3296 break;
3297 } else
3298 k = NULL;
3299
3300 ts = SIMPLEQ_FIRST(&tsb->tsb_freeq);
3301
3302 dmamap = ts->ts_dmamap;
3303
3304 m0 = rtw_dmamap_load_txbuf(sc->sc_dmat, dmamap, m0,
3305 tdb->tdb_nfree, sc->sc_dev);
3306
3307 if (m0 == NULL || dmamap->dm_nsegs == 0) {
3308 DPRINTF(sc, RTW_DEBUG_XMIT,
3309 ("%s: fail dmamap load\n", __func__));
3310 goto post_dequeue_err;
3311 }
3312
3313 /* Note well: rtw_dmamap_load_txbuf may have created
3314 * a new chain, so we must find the header once
3315 * more.
3316 */
3317 wh = mtod(m0, struct ieee80211_frame_min *);
3318
3319 /* XXX do real rate control */
3320 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
3321 IEEE80211_FC0_TYPE_MGT)
3322 rate = 2;
3323 else
3324 rate = MAX(2, ieee80211_get_rate(ni));
3325
3326#ifdef RTW_DEBUG
3327 if ((ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) ==
3328 (IFF_DEBUG|IFF_LINK2)) {
3329 ieee80211_dump_pkt(mtod(m0, uint8_t *),
3330 (dmamap->dm_nsegs == 1) ? m0->m_pkthdr.len
3331 : sizeof(wh),
3332 rate, 0);
3333 }
3334#endif /* RTW_DEBUG */
3335 ctl0 = proto_ctl0 |
3336 __SHIFTIN(m0->m_pkthdr.len, RTW_TXCTL0_TPKTSIZE_MASK);
3337
3338 switch (rate) {
3339 default:
3340 case 2:
3341 ctl0 |= RTW_TXCTL0_RATE_1MBPS;
3342 break;
3343 case 4:
3344 ctl0 |= RTW_TXCTL0_RATE_2MBPS;
3345 break;
3346 case 11:
3347 ctl0 |= RTW_TXCTL0_RATE_5MBPS;
3348 break;
3349 case 22:
3350 ctl0 |= RTW_TXCTL0_RATE_11MBPS;
3351 break;
3352 }
3353 /* XXX >= ? Compare after fragmentation? */
3354 if (m0->m_pkthdr.len > ic->ic_rtsthreshold)
3355 ctl0 |= RTW_TXCTL0_RTSEN;
3356
3357 /* XXX Sometimes writes a bogus keyid; h/w doesn't
3358 * seem to care, since we don't activate h/w Tx
3359 * encryption.
3360 */
3361 if (k != NULL &&
3362 k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP) {
3363 ctl0 |= __SHIFTIN(k->wk_keyix, RTW_TXCTL0_KEYID_MASK) &
3364 RTW_TXCTL0_KEYID_MASK;
3365 }
3366
3367 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
3368 IEEE80211_FC0_TYPE_MGT) {
3369 ctl0 &= ~(RTW_TXCTL0_SPLCP | RTW_TXCTL0_RTSEN);
3370 if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
3371 IEEE80211_FC0_SUBTYPE_BEACON)
3372 ctl0 |= RTW_TXCTL0_BEACON;
3373 }
3374
3375 if (ieee80211_compute_duration(wh, k, m0->m_pkthdr.len,
3376 ic->ic_flags, ic->ic_fragthreshold,
3377 rate, &ts->ts_d0, &ts->ts_dn, &npkt,
3378 (ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) ==
3379 (IFF_DEBUG|IFF_LINK2)) == -1) {
3380 DPRINTF(sc, RTW_DEBUG_XMIT,
3381 ("%s: fail compute duration\n", __func__));
3382 goto post_load_err;
3383 }
3384
3385 d0 = &ts->ts_d0;
3386
3387 *(uint16_t*)wh->i_dur = htole16(d0->d_data_dur);
3388
3389 ctl1 = __SHIFTIN(d0->d_plcp_len, RTW_TXCTL1_LENGTH_MASK) |
3390 __SHIFTIN(d0->d_rts_dur, RTW_TXCTL1_RTSDUR_MASK);
3391
3392 if (d0->d_residue)
3393 ctl1 |= RTW_TXCTL1_LENGEXT;
3394
3395 /* TBD fragmentation */
3396
3397 ts->ts_first = tdb->tdb_next;
3398
3399 rtw_txdescs_sync(tdb, ts->ts_first, dmamap->dm_nsegs,
3400 BUS_DMASYNC_PREWRITE);
3401
3402 KASSERT(ts->ts_first < tdb->tdb_ndesc);
3403
3404 bpf_mtap3(ic->ic_rawbpf, m0);
3405
3406 if (sc->sc_radiobpf != NULL) {
3407 struct rtw_tx_radiotap_header *rt = &sc->sc_txtap;
3408
3409 rt->rt_rate = rate;
3410
3411 bpf_mtap2(sc->sc_radiobpf, rt, sizeof(sc->sc_txtapu),
3412 m0);
3413 }
3414
3415 for (i = 0, lastdesc = desc = ts->ts_first;
3416 i < dmamap->dm_nsegs;
3417 i++, desc = RTW_NEXT_IDX(tdb, desc)) {
3418 if (dmamap->dm_segs[i].ds_len > RTW_TXLEN_LENGTH_MASK) {
3419 DPRINTF(sc, RTW_DEBUG_XMIT_DESC,
3420 ("%s: seg too long\n", __func__));
3421 goto post_load_err;
3422 }
3423 td = &tdb->tdb_desc[desc];
3424 td->td_ctl0 = htole32(ctl0);
3425 td->td_ctl1 = htole32(ctl1);
3426 td->td_buf = htole32(dmamap->dm_segs[i].ds_addr);
3427 td->td_len = htole32(dmamap->dm_segs[i].ds_len);
3428 td->td_next = htole32(RTW_NEXT_DESC(tdb, desc));
3429 if (i != 0)
3430 td->td_ctl0 |= htole32(RTW_TXCTL0_OWN);
3431 lastdesc = desc;
3432#ifdef RTW_DEBUG
3433 rtw_print_txdesc(sc, "load", ts, tdb, desc);
3434#endif /* RTW_DEBUG */
3435 }
3436
3437 KASSERT(desc < tdb->tdb_ndesc);
3438
3439 ts->ts_ni = ni;
3440 KASSERT(ni != NULL);
3441 ts->ts_mbuf = m0;
3442 ts->ts_last = lastdesc;
3443 tdb->tdb_desc[ts->ts_last].td_ctl0 |= htole32(RTW_TXCTL0_LS);
3444 tdb->tdb_desc[ts->ts_first].td_ctl0 |=
3445 htole32(RTW_TXCTL0_FS);
3446
3447#ifdef RTW_DEBUG
3448 rtw_print_txdesc(sc, "FS on", ts, tdb, ts->ts_first);
3449 rtw_print_txdesc(sc, "LS on", ts, tdb, ts->ts_last);
3450#endif /* RTW_DEBUG */
3451
3452 tdb->tdb_nfree -= dmamap->dm_nsegs;
3453 tdb->tdb_next = desc;
3454
3455 rtw_txdescs_sync(tdb, ts->ts_first, dmamap->dm_nsegs,
3456 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
3457
3458 tdb->tdb_desc[ts->ts_first].td_ctl0 |=
3459 htole32(RTW_TXCTL0_OWN);
3460
3461#ifdef RTW_DEBUG
3462 rtw_print_txdesc(sc, "OWN on", ts, tdb, ts->ts_first);
3463#endif /* RTW_DEBUG */
3464
3465 rtw_txdescs_sync(tdb, ts->ts_first, 1,
3466 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
3467
3468 SIMPLEQ_REMOVE_HEAD(&tsb->tsb_freeq, ts_q);
3469 SIMPLEQ_INSERT_TAIL(&tsb->tsb_dirtyq, ts, ts_q);
3470
3471 if (tsb != &sc->sc_txsoft_blk[RTW_TXPRIBCN])
3472 sc->sc_led_state.ls_event |= RTW_LED_S_TX;
3473 tsb->tsb_tx_timer = 5;
3474 ifp->if_timer = 1;
3475 rtw_tx_kick(&sc->sc_regs, tsb->tsb_poll);
3476 }
3477out:
3478 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: leave\n", __func__));
3479 return;
3480post_load_err:
3481 bus_dmamap_unload(sc->sc_dmat, dmamap);
3482 m_freem(m0);
3483post_dequeue_err:
3484 ieee80211_free_node(ni);
3485 return;
3486}
3487
3488static void
3489rtw_idle(struct rtw_regs *regs)
3490{
3491 int active;
3492 uint8_t tppoll;
3493
3494 /* request stop DMA; wait for packets to stop transmitting. */
3495
3496 RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL);
3497 RTW_WBR(regs, RTW_TPPOLL, RTW_TPPOLL);
3498
3499 for (active = 0; active < 300 &&
3500 (tppoll = RTW_READ8(regs, RTW_TPPOLL) & RTW_TPPOLL_ACTIVE) != 0;
3501 active++)
3502 DELAY(10);
3503 printf("%s: transmit DMA idle in %dus, tppoll %02" PRIx8 "\n", __func__,
3504 active * 10, tppoll);
3505}
3506
3507static void
3508rtw_watchdog(struct ifnet *ifp)
3509{
3510 int pri, tx_timeouts = 0;
3511 struct rtw_softc *sc;
3512 struct rtw_txsoft_blk *tsb;
3513
3514 sc = ifp->if_softc;
3515
3516 ifp->if_timer = 0;
3517
3518 if (!device_is_active(sc->sc_dev))
3519 return;
3520
3521 for (pri = 0; pri < RTW_NTXPRI; pri++) {
3522 tsb = &sc->sc_txsoft_blk[pri];
3523
3524 if (tsb->tsb_tx_timer == 0)
3525 continue;
3526 else if (--tsb->tsb_tx_timer == 0) {
3527 if (SIMPLEQ_EMPTY(&tsb->tsb_dirtyq))
3528 continue;
3529 else if (rtw_collect_txring(sc, tsb,
3530 &sc->sc_txdesc_blk[pri], 0))
3531 continue;
3532 printf("%s: transmit timeout, priority %d\n",
3533 ifp->if_xname, pri);
3534 ifp->if_oerrors++;
3535 if (pri != RTW_TXPRIBCN)
3536 tx_timeouts++;
3537 } else
3538 ifp->if_timer = 1;
3539 }
3540
3541 if (tx_timeouts > 0) {
3542 /* Stop Tx DMA, disable xmtr, flush Tx rings, enable xmtr,
3543 * reset s/w tx-ring pointers, and start transmission.
3544 *
3545 * TBD Stop/restart just the broken rings?
3546 */
3547 rtw_idle(&sc->sc_regs);
3548 rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 0);
3549 rtw_txdescs_reset(sc);
3550 rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 1);
3551 rtw_start(ifp);
3552 }
3553 ieee80211_watchdog(&sc->sc_ic);
3554 return;
3555}
3556
3557static void
3558rtw_next_scan(void *arg)
3559{
3560 struct ieee80211com *ic = arg;
3561 int s;
3562
3563 /* don't call rtw_start w/o network interrupts blocked */
3564 s = splnet();
3565 if (ic->ic_state == IEEE80211_S_SCAN)
3566 ieee80211_next_scan(ic);
3567 splx(s);
3568}
3569
3570static void
3571rtw_join_bss(struct rtw_softc *sc, uint8_t *bssid, uint16_t intval0)
3572{
3573 uint16_t bcnitv, bintritv, intval;
3574 int i;
3575 struct rtw_regs *regs = &sc->sc_regs;
3576
3577 for (i = 0; i < IEEE80211_ADDR_LEN; i++)
3578 RTW_WRITE8(regs, RTW_BSSID + i, bssid[i]);
3579
3580 RTW_SYNC(regs, RTW_BSSID16, RTW_BSSID32);
3581
3582 rtw_set_access(regs, RTW_ACCESS_CONFIG);
3583
3584 intval = MIN(intval0, __SHIFTOUT_MASK(RTW_BCNITV_BCNITV_MASK));
3585
3586 bcnitv = RTW_READ16(regs, RTW_BCNITV) & ~RTW_BCNITV_BCNITV_MASK;
3587 bcnitv |= __SHIFTIN(intval, RTW_BCNITV_BCNITV_MASK);
3588 RTW_WRITE16(regs, RTW_BCNITV, bcnitv);
3589 /* interrupt host 1ms before the TBTT */
3590 bintritv = RTW_READ16(regs, RTW_BINTRITV) & ~RTW_BINTRITV_BINTRITV;
3591 bintritv |= __SHIFTIN(1000, RTW_BINTRITV_BINTRITV);
3592 RTW_WRITE16(regs, RTW_BINTRITV, bintritv);
3593 /* magic from Linux */
3594 RTW_WRITE16(regs, RTW_ATIMWND, __SHIFTIN(1, RTW_ATIMWND_ATIMWND));
3595 RTW_WRITE16(regs, RTW_ATIMTRITV, __SHIFTIN(2, RTW_ATIMTRITV_ATIMTRITV));
3596 rtw_set_access(regs, RTW_ACCESS_NONE);
3597
3598 rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 1);
3599}
3600
3601/* Synchronize the hardware state with the software state. */
3602static int
3603rtw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
3604{
3605 struct ifnet *ifp = ic->ic_ifp;
3606 struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc;
3607 enum ieee80211_state ostate;
3608 int error;
3609
3610 ostate = ic->ic_state;
3611
3612 aprint_debug_dev(sc->sc_dev, "%s: l.%d\n", __func__, __LINE__);
3613 rtw_led_newstate(sc, nstate);
3614
3615 aprint_debug_dev(sc->sc_dev, "%s: l.%d\n", __func__, __LINE__);
3616 if (nstate == IEEE80211_S_INIT) {
3617 callout_stop(&sc->sc_scan_ch);
3618 sc->sc_cur_chan = IEEE80211_CHAN_ANY;
3619 return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg);
3620 }
3621
3622 if (ostate == IEEE80211_S_INIT && nstate != IEEE80211_S_INIT)
3623 rtw_pwrstate(sc, RTW_ON);
3624
3625 if ((error = rtw_tune(sc)) != 0)
3626 return error;
3627
3628 switch (nstate) {
3629 case IEEE80211_S_INIT:
3630 panic("%s: unexpected state IEEE80211_S_INIT\n", __func__);
3631 break;
3632 case IEEE80211_S_SCAN:
3633 if (ostate != IEEE80211_S_SCAN) {
3634 (void)memset(ic->ic_bss->ni_bssid, 0,
3635 IEEE80211_ADDR_LEN);
3636 rtw_set_nettype(sc, IEEE80211_M_MONITOR);
3637 }
3638
3639 callout_reset(&sc->sc_scan_ch, rtw_dwelltime * hz / 1000,
3640 rtw_next_scan, ic);
3641
3642 break;
3643 case IEEE80211_S_RUN:
3644 switch (ic->ic_opmode) {
3645 case IEEE80211_M_HOSTAP:
3646 case IEEE80211_M_IBSS:
3647 rtw_set_nettype(sc, IEEE80211_M_MONITOR);
3648 /*FALLTHROUGH*/
3649 case IEEE80211_M_AHDEMO:
3650 case IEEE80211_M_STA:
3651 rtw_join_bss(sc, ic->ic_bss->ni_bssid,
3652 ic->ic_bss->ni_intval);
3653 break;
3654 case IEEE80211_M_MONITOR:
3655 break;
3656 }
3657 rtw_set_nettype(sc, ic->ic_opmode);
3658 break;
3659 case IEEE80211_S_ASSOC:
3660 case IEEE80211_S_AUTH:
3661 break;
3662 }
3663
3664 if (nstate != IEEE80211_S_SCAN)
3665 callout_stop(&sc->sc_scan_ch);
3666
3667 return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg);
3668}
3669
3670/* Extend a 32-bit TSF timestamp to a 64-bit timestamp. */
3671static uint64_t
3672rtw_tsf_extend(struct rtw_regs *regs, uint32_t rstamp)
3673{
3674 uint32_t tsftl, tsfth;
3675
3676 tsfth = RTW_READ(regs, RTW_TSFTRH);
3677 tsftl = RTW_READ(regs, RTW_TSFTRL);
3678 if (tsftl < rstamp) /* Compensate for rollover. */
3679 tsfth--;
3680 return ((uint64_t)tsfth << 32) | rstamp;
3681}
3682
3683static void
3684rtw_recv_mgmt(struct ieee80211com *ic, struct mbuf *m,
3685 struct ieee80211_node *ni, int subtype, int rssi, uint32_t rstamp)
3686{
3687 struct ifnet *ifp = ic->ic_ifp;
3688 struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc;
3689
3690 (*sc->sc_mtbl.mt_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp);
3691
3692 switch (subtype) {
3693 case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
3694 case IEEE80211_FC0_SUBTYPE_BEACON:
3695 if (ic->ic_opmode == IEEE80211_M_IBSS &&
3696 ic->ic_state == IEEE80211_S_RUN &&
3697 device_is_active(sc->sc_dev)) {
3698 uint64_t tsf = rtw_tsf_extend(&sc->sc_regs, rstamp);
3699 if (le64toh(ni->ni_tstamp.tsf) >= tsf)
3700 (void)ieee80211_ibss_merge(ni);
3701 }
3702 break;
3703 default:
3704 break;
3705 }
3706 return;
3707}
3708
3709static struct ieee80211_node *
3710rtw_node_alloc(struct ieee80211_node_table *nt)
3711{
3712 struct ifnet *ifp = nt->nt_ic->ic_ifp;
3713 struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc;
3714 struct ieee80211_node *ni = (*sc->sc_mtbl.mt_node_alloc)(nt);
3715
3716 DPRINTF(sc, RTW_DEBUG_NODE,
3717 ("%s: alloc node %p\n", device_xname(sc->sc_dev), ni));
3718 return ni;
3719}
3720
3721static void
3722rtw_node_free(struct ieee80211_node *ni)
3723{
3724 struct ieee80211com *ic = ni->ni_ic;
3725 struct ifnet *ifp = ic->ic_ifp;
3726 struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc;
3727
3728 DPRINTF(sc, RTW_DEBUG_NODE,
3729 ("%s: freeing node %p %s\n", device_xname(sc->sc_dev), ni,
3730 ether_sprintf(ni->ni_bssid)));
3731 (*sc->sc_mtbl.mt_node_free)(ni);
3732}
3733
3734static int
3735rtw_media_change(struct ifnet *ifp)
3736{
3737 int error;
3738
3739 error = ieee80211_media_change(ifp);
3740 if (error == ENETRESET) {
3741 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
3742 (IFF_RUNNING|IFF_UP))
3743 rtw_init(ifp); /* XXX lose error */
3744 error = 0;
3745 }
3746 return error;
3747}
3748
3749static void
3750rtw_media_status(struct ifnet *ifp, struct ifmediareq *imr)
3751{
3752 struct rtw_softc *sc = ifp->if_softc;
3753
3754 if (!device_is_active(sc->sc_dev)) {
3755 imr->ifm_active = IFM_IEEE80211 | IFM_NONE;
3756 imr->ifm_status = 0;
3757 return;
3758 }
3759 ieee80211_media_status(ifp, imr);
3760}
3761
3762static inline void
3763rtw_setifprops(struct ifnet *ifp, const char *dvname, void *softc)
3764{
3765 (void)strlcpy(ifp->if_xname, dvname, IFNAMSIZ);
3766 ifp->if_softc = softc;
3767 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST |
3768 IFF_NOTRAILERS;
3769 ifp->if_ioctl = rtw_ioctl;
3770 ifp->if_start = rtw_start;
3771 ifp->if_watchdog = rtw_watchdog;
3772 ifp->if_init = rtw_init;
3773 ifp->if_stop = rtw_stop;
3774}
3775
3776static inline void
3777rtw_set80211props(struct ieee80211com *ic)
3778{
3779 int nrate;
3780 ic->ic_phytype = IEEE80211_T_DS;
3781 ic->ic_opmode = IEEE80211_M_STA;
3782 ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_IBSS |
3783 IEEE80211_C_HOSTAP | IEEE80211_C_MONITOR | IEEE80211_C_WEP;
3784
3785 nrate = 0;
3786 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] =
3787 IEEE80211_RATE_BASIC | 2;
3788 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] =
3789 IEEE80211_RATE_BASIC | 4;
3790 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 11;
3791 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 22;
3792 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = nrate;
3793}
3794
3795static inline void
3796rtw_set80211methods(struct rtw_mtbl *mtbl, struct ieee80211com *ic)
3797{
3798 mtbl->mt_newstate = ic->ic_newstate;
3799 ic->ic_newstate = rtw_newstate;
3800
3801 mtbl->mt_recv_mgmt = ic->ic_recv_mgmt;
3802 ic->ic_recv_mgmt = rtw_recv_mgmt;
3803
3804 mtbl->mt_node_free = ic->ic_node_free;
3805 ic->ic_node_free = rtw_node_free;
3806
3807 mtbl->mt_node_alloc = ic->ic_node_alloc;
3808 ic->ic_node_alloc = rtw_node_alloc;
3809
3810 ic->ic_crypto.cs_key_delete = rtw_key_delete;
3811 ic->ic_crypto.cs_key_set = rtw_key_set;
3812 ic->ic_crypto.cs_key_update_begin = rtw_key_update_begin;
3813 ic->ic_crypto.cs_key_update_end = rtw_key_update_end;
3814}
3815
3816static inline void
3817rtw_init_radiotap(struct rtw_softc *sc)
3818{
3819 uint32_t present;
3820
3821 memset(&sc->sc_rxtapu, 0, sizeof(sc->sc_rxtapu));
3822 sc->sc_rxtap.rr_ihdr.it_len = htole16(sizeof(sc->sc_rxtapu));
3823
3824 if (sc->sc_rfchipid == RTW_RFCHIPID_PHILIPS)
3825 present = htole32(RTW_PHILIPS_RX_RADIOTAP_PRESENT);
3826 else
3827 present = htole32(RTW_RX_RADIOTAP_PRESENT);
3828 sc->sc_rxtap.rr_ihdr.it_present = present;
3829
3830 memset(&sc->sc_txtapu, 0, sizeof(sc->sc_txtapu));
3831 sc->sc_txtap.rt_ihdr.it_len = htole16(sizeof(sc->sc_txtapu));
3832 sc->sc_txtap.rt_ihdr.it_present = htole32(RTW_TX_RADIOTAP_PRESENT);
3833}
3834
3835static int
3836rtw_txsoft_blk_setup(struct rtw_txsoft_blk *tsb, u_int qlen)
3837{
3838 SIMPLEQ_INIT(&tsb->tsb_dirtyq);
3839 SIMPLEQ_INIT(&tsb->tsb_freeq);
3840 tsb->tsb_ndesc = qlen;
3841 tsb->tsb_desc = malloc(qlen * sizeof(*tsb->tsb_desc), M_DEVBUF,
3842 M_NOWAIT);
3843 if (tsb->tsb_desc == NULL)
3844 return ENOMEM;
3845 return 0;
3846}
3847
3848static void
3849rtw_txsoft_blk_cleanup_all(struct rtw_softc *sc)
3850{
3851 int pri;
3852 struct rtw_txsoft_blk *tsb;
3853
3854 for (pri = 0; pri < RTW_NTXPRI; pri++) {
3855 tsb = &sc->sc_txsoft_blk[pri];
3856 free(tsb->tsb_desc, M_DEVBUF);
3857 tsb->tsb_desc = NULL;
3858 }
3859}
3860
3861static int
3862rtw_txsoft_blk_setup_all(struct rtw_softc *sc)
3863{
3864 int pri, rc = 0;
3865 int qlen[RTW_NTXPRI] =
3866 {RTW_TXQLENLO, RTW_TXQLENMD, RTW_TXQLENHI, RTW_TXQLENBCN};
3867 struct rtw_txsoft_blk *tsbs;
3868
3869 tsbs = sc->sc_txsoft_blk;
3870
3871 for (pri = 0; pri < RTW_NTXPRI; pri++) {
3872 rc = rtw_txsoft_blk_setup(&tsbs[pri], qlen[pri]);
3873 if (rc != 0)
3874 break;
3875 }
3876 tsbs[RTW_TXPRILO].tsb_poll = RTW_TPPOLL_LPQ | RTW_TPPOLL_SLPQ;
3877 tsbs[RTW_TXPRIMD].tsb_poll = RTW_TPPOLL_NPQ | RTW_TPPOLL_SNPQ;
3878 tsbs[RTW_TXPRIHI].tsb_poll = RTW_TPPOLL_HPQ | RTW_TPPOLL_SHPQ;
3879 tsbs[RTW_TXPRIBCN].tsb_poll = RTW_TPPOLL_BQ | RTW_TPPOLL_SBQ;
3880 return rc;
3881}
3882
3883static void
3884rtw_txdesc_blk_setup(struct rtw_txdesc_blk *tdb, struct rtw_txdesc *desc,
3885 u_int ndesc, bus_addr_t ofs, bus_addr_t physbase)
3886{
3887 tdb->tdb_ndesc = ndesc;
3888 tdb->tdb_desc = desc;
3889 tdb->tdb_physbase = physbase;
3890 tdb->tdb_ofs = ofs;
3891
3892 (void)memset(tdb->tdb_desc, 0,
3893 sizeof(tdb->tdb_desc[0]) * tdb->tdb_ndesc);
3894
3895 rtw_txdesc_blk_init(tdb);
3896 tdb->tdb_next = 0;
3897}
3898
3899static void
3900rtw_txdesc_blk_setup_all(struct rtw_softc *sc)
3901{
3902 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRILO],
3903 &sc->sc_descs->hd_txlo[0], RTW_NTXDESCLO,
3904 RTW_RING_OFFSET(hd_txlo), RTW_RING_BASE(sc, hd_txlo));
3905
3906 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIMD],
3907 &sc->sc_descs->hd_txmd[0], RTW_NTXDESCMD,
3908 RTW_RING_OFFSET(hd_txmd), RTW_RING_BASE(sc, hd_txmd));
3909
3910 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIHI],
3911 &sc->sc_descs->hd_txhi[0], RTW_NTXDESCHI,
3912 RTW_RING_OFFSET(hd_txhi), RTW_RING_BASE(sc, hd_txhi));
3913
3914 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIBCN],
3915 &sc->sc_descs->hd_bcn[0], RTW_NTXDESCBCN,
3916 RTW_RING_OFFSET(hd_bcn), RTW_RING_BASE(sc, hd_bcn));
3917}
3918
3919static struct rtw_rf *
3920rtw_rf_attach(struct rtw_softc *sc, enum rtw_rfchipid rfchipid, int digphy)
3921{
3922 rtw_rf_write_t rf_write;
3923 struct rtw_rf *rf;
3924
3925 switch (rfchipid) {
3926 default:
3927 rf_write = rtw_rf_hostwrite;
3928 break;
3929 case RTW_RFCHIPID_INTERSIL:
3930 case RTW_RFCHIPID_PHILIPS:
3931 case RTW_RFCHIPID_GCT: /* XXX a guess */
3932 case RTW_RFCHIPID_RFMD:
3933 rf_write = (rtw_host_rfio) ? rtw_rf_hostwrite : rtw_rf_macwrite;
3934 break;
3935 }
3936
3937 switch (rfchipid) {
3938 case RTW_RFCHIPID_GCT:
3939 rf = rtw_grf5101_create(&sc->sc_regs, rf_write, 0);
3940 sc->sc_pwrstate_cb = rtw_maxim_pwrstate;
3941 break;
3942 case RTW_RFCHIPID_MAXIM:
3943 rf = rtw_max2820_create(&sc->sc_regs, rf_write, 0);
3944 sc->sc_pwrstate_cb = rtw_maxim_pwrstate;
3945 break;
3946 case RTW_RFCHIPID_PHILIPS:
3947 rf = rtw_sa2400_create(&sc->sc_regs, rf_write, digphy);
3948 sc->sc_pwrstate_cb = rtw_philips_pwrstate;
3949 break;
3950 case RTW_RFCHIPID_RFMD:
3951 /* XXX RFMD has no RF constructor */
3952 sc->sc_pwrstate_cb = rtw_rfmd_pwrstate;
3953 /*FALLTHROUGH*/
3954 default:
3955 return NULL;
3956 }
3957 rf->rf_continuous_tx_cb =
3958 (rtw_continuous_tx_cb_t)rtw_continuous_tx_enable;
3959 rf->rf_continuous_tx_arg = (void *)sc;
3960 return rf;
3961}
3962
3963/* Revision C and later use a different PHY delay setting than
3964 * revisions A and B.
3965 */
3966static uint8_t
3967rtw_check_phydelay(struct rtw_regs *regs, uint32_t old_rcr)
3968{
3969#define REVAB (RTW_RCR_MXDMA_UNLIMITED | RTW_RCR_AICV)
3970#define REVC (REVAB | RTW_RCR_RXFTH_WHOLE)
3971
3972 uint8_t phydelay = __SHIFTIN(0x6, RTW_PHYDELAY_PHYDELAY);
3973
3974 RTW_WRITE(regs, RTW_RCR, REVAB);
3975 RTW_WBW(regs, RTW_RCR, RTW_RCR);
3976 RTW_WRITE(regs, RTW_RCR, REVC);
3977
3978 RTW_WBR(regs, RTW_RCR, RTW_RCR);
3979 if ((RTW_READ(regs, RTW_RCR) & REVC) == REVC)
3980 phydelay |= RTW_PHYDELAY_REVC_MAGIC;
3981
3982 RTW_WRITE(regs, RTW_RCR, old_rcr); /* restore RCR */
3983 RTW_SYNC(regs, RTW_RCR, RTW_RCR);
3984
3985 return phydelay;
3986#undef REVC
3987}
3988
3989void
3990rtw_attach(struct rtw_softc *sc)
3991{
3992 struct ifnet *ifp = &sc->sc_if;
3993 struct ieee80211com *ic = &sc->sc_ic;
3994 struct rtw_txsoft_blk *tsb;
3995 int pri, rc;
3996
3997 pmf_self_suspensor_init(sc->sc_dev, &sc->sc_suspensor, &sc->sc_qual);
3998
3999 rtw_cipher_wep = ieee80211_cipher_wep;
4000 rtw_cipher_wep.ic_decap = rtw_wep_decap;
4001
4002 NEXT_ATTACH_STATE(sc, DETACHED);
4003
4004 switch (RTW_READ(&sc->sc_regs, RTW_TCR) & RTW_TCR_HWVERID_MASK) {
4005 case RTW_TCR_HWVERID_F:
4006 sc->sc_hwverid = 'F';
4007 break;
4008 case RTW_TCR_HWVERID_D:
4009 sc->sc_hwverid = 'D';
4010 break;
4011 default:
4012 sc->sc_hwverid = '?';
4013 break;
4014 }
4015 aprint_verbose_dev(sc->sc_dev, "hardware version %c\n",
4016 sc->sc_hwverid);
4017
4018 rc = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct rtw_descs),
4019 RTW_DESC_ALIGNMENT, 0, &sc->sc_desc_segs, 1, &sc->sc_desc_nsegs,
4020 0);
4021
4022 if (rc != 0) {
4023 aprint_error_dev(sc->sc_dev,
4024 "could not allocate hw descriptors, error %d\n", rc);
4025 goto err;
4026 }
4027
4028 NEXT_ATTACH_STATE(sc, FINISH_DESC_ALLOC);
4029
4030 rc = bus_dmamem_map(sc->sc_dmat, &sc->sc_desc_segs,
4031 sc->sc_desc_nsegs, sizeof(struct rtw_descs),
4032 (void **)&sc->sc_descs, BUS_DMA_COHERENT);
4033
4034 if (rc != 0) {
4035 aprint_error_dev(sc->sc_dev,
4036 "could not map hw descriptors, error %d\n", rc);
4037 goto err;
4038 }
4039 NEXT_ATTACH_STATE(sc, FINISH_DESC_MAP);
4040
4041 rc = bus_dmamap_create(sc->sc_dmat, sizeof(struct rtw_descs), 1,
4042 sizeof(struct rtw_descs), 0, 0, &sc->sc_desc_dmamap);
4043
4044 if (rc != 0) {
4045 aprint_error_dev(sc->sc_dev,
4046 "could not create DMA map for hw descriptors, error %d\n",
4047 rc);
4048 goto err;
4049 }
4050 NEXT_ATTACH_STATE(sc, FINISH_DESCMAP_CREATE);
4051
4052 sc->sc_rxdesc_blk.rdb_dmat = sc->sc_dmat;
4053 sc->sc_rxdesc_blk.rdb_dmamap = sc->sc_desc_dmamap;
4054
4055 for (pri = 0; pri < RTW_NTXPRI; pri++) {
4056 sc->sc_txdesc_blk[pri].tdb_dmat = sc->sc_dmat;
4057 sc->sc_txdesc_blk[pri].tdb_dmamap = sc->sc_desc_dmamap;
4058 }
4059
4060 rc = bus_dmamap_load(sc->sc_dmat, sc->sc_desc_dmamap, sc->sc_descs,
4061 sizeof(struct rtw_descs), NULL, 0);
4062
4063 if (rc != 0) {
4064 aprint_error_dev(sc->sc_dev,
4065 "could not load DMA map for hw descriptors, error %d\n",
4066 rc);
4067 goto err;
4068 }
4069 NEXT_ATTACH_STATE(sc, FINISH_DESCMAP_LOAD);
4070
4071 if (rtw_txsoft_blk_setup_all(sc) != 0)
4072 goto err;
4073 NEXT_ATTACH_STATE(sc, FINISH_TXCTLBLK_SETUP);
4074
4075 rtw_txdesc_blk_setup_all(sc);
4076
4077 NEXT_ATTACH_STATE(sc, FINISH_TXDESCBLK_SETUP);
4078
4079 sc->sc_rxdesc_blk.rdb_desc = &sc->sc_descs->hd_rx[0];
4080
4081 for (pri = 0; pri < RTW_NTXPRI; pri++) {
4082 tsb = &sc->sc_txsoft_blk[pri];
4083
4084 if ((rc = rtw_txdesc_dmamaps_create(sc->sc_dmat,
4085 &tsb->tsb_desc[0], tsb->tsb_ndesc)) != 0) {
4086 aprint_error_dev(sc->sc_dev,
4087 "could not load DMA map for hw tx descriptors, "
4088 "error %d\n", rc);
4089 goto err;
4090 }
4091 }
4092
4093 NEXT_ATTACH_STATE(sc, FINISH_TXMAPS_CREATE);
4094 if ((rc = rtw_rxdesc_dmamaps_create(sc->sc_dmat, &sc->sc_rxsoft[0],
4095 RTW_RXQLEN)) != 0) {
4096 aprint_error_dev(sc->sc_dev,
4097 "could not load DMA map for hw rx descriptors, error %d\n",
4098 rc);
4099 goto err;
4100 }
4101 NEXT_ATTACH_STATE(sc, FINISH_RXMAPS_CREATE);
4102
4103 /* Reset the chip to a known state. */
4104 if (rtw_reset(sc) != 0)
4105 goto err;
4106 NEXT_ATTACH_STATE(sc, FINISH_RESET);
4107
4108 sc->sc_rcr = RTW_READ(&sc->sc_regs, RTW_RCR);
4109
4110 if ((sc->sc_rcr & RTW_RCR_9356SEL) != 0)
4111 sc->sc_flags |= RTW_F_9356SROM;
4112
4113 if (rtw_srom_read(&sc->sc_regs, sc->sc_flags, &sc->sc_srom,
4114 sc->sc_dev) != 0)
4115 goto err;
4116
4117 NEXT_ATTACH_STATE(sc, FINISH_READ_SROM);
4118
4119 if (rtw_srom_parse(&sc->sc_srom, &sc->sc_flags, &sc->sc_csthr,
4120 &sc->sc_rfchipid, &sc->sc_rcr, &sc->sc_locale,
4121 sc->sc_dev) != 0) {
4122 aprint_error_dev(sc->sc_dev,
4123 "attach failed, malformed serial ROM\n");
4124 goto err;
4125 }
4126
4127 aprint_verbose_dev(sc->sc_dev, "%s PHY\n",
4128 ((sc->sc_flags & RTW_F_DIGPHY) != 0) ? "digital" : "analog");
4129
4130 aprint_verbose_dev(sc->sc_dev, "carrier-sense threshold %u\n",
4131 sc->sc_csthr);
4132
4133 NEXT_ATTACH_STATE(sc, FINISH_PARSE_SROM);
4134
4135 sc->sc_rf = rtw_rf_attach(sc, sc->sc_rfchipid,
4136 sc->sc_flags & RTW_F_DIGPHY);
4137
4138 if (sc->sc_rf == NULL) {
4139 aprint_verbose_dev(sc->sc_dev,
4140 "attach failed, could not attach RF\n");
4141 goto err;
4142 }
4143
4144 NEXT_ATTACH_STATE(sc, FINISH_RF_ATTACH);
4145
4146 sc->sc_phydelay = rtw_check_phydelay(&sc->sc_regs, sc->sc_rcr);
4147
4148 RTW_DPRINTF(RTW_DEBUG_ATTACH,
4149 ("%s: PHY delay %d\n", device_xname(sc->sc_dev), sc->sc_phydelay));
4150
4151 if (sc->sc_locale == RTW_LOCALE_UNKNOWN)
4152 rtw_identify_country(&sc->sc_regs, &sc->sc_locale);
4153
4154 rtw_init_channels(sc->sc_locale, &sc->sc_ic.ic_channels, sc->sc_dev);
4155
4156 if (rtw_identify_sta(&sc->sc_regs, &sc->sc_ic.ic_myaddr,
4157 sc->sc_dev) != 0)
4158 goto err;
4159 NEXT_ATTACH_STATE(sc, FINISH_ID_STA);
4160
4161 rtw_setifprops(ifp, device_xname(sc->sc_dev), (void*)sc);
4162
4163 IFQ_SET_READY(&ifp->if_snd);
4164
4165 sc->sc_ic.ic_ifp = ifp;
4166 rtw_set80211props(&sc->sc_ic);
4167
4168 rtw_led_attach(&sc->sc_led_state, (void *)sc);
4169
4170 /*
4171 * Call MI attach routines.
4172 */
4173 if_attach(ifp);
4174 ieee80211_ifattach(&sc->sc_ic);
4175
4176 rtw_set80211methods(&sc->sc_mtbl, &sc->sc_ic);
4177
4178 /* possibly we should fill in our own sc_send_prresp, since
4179 * the RTL8180 is probably sending probe responses in ad hoc
4180 * mode.
4181 */
4182
4183 /* complete initialization */
4184 ieee80211_media_init(&sc->sc_ic, rtw_media_change, rtw_media_status);
4185 callout_init(&sc->sc_scan_ch, 0);
4186
4187 rtw_init_radiotap(sc);
4188
4189 bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
4190 sizeof(struct ieee80211_frame) + 64, &sc->sc_radiobpf);
4191
4192 NEXT_ATTACH_STATE(sc, FINISHED);
4193
4194 ieee80211_announce(ic);
4195 return;
4196err:
4197 rtw_detach(sc);
4198 return;
4199}
4200
4201int
4202rtw_detach(struct rtw_softc *sc)
4203{
4204 struct ifnet *ifp = &sc->sc_if;
4205 int pri, s;
4206
4207 s = splnet();
4208
4209 switch (sc->sc_attach_state) {
4210 case FINISHED:
4211 rtw_stop(ifp, 1);
4212
4213 pmf_device_deregister(sc->sc_dev);
4214 callout_stop(&sc->sc_scan_ch);
4215 ieee80211_ifdetach(&sc->sc_ic);
4216 if_detach(ifp);
4217 rtw_led_detach(&sc->sc_led_state);
4218 /*FALLTHROUGH*/
4219 case FINISH_ID_STA:
4220 case FINISH_RF_ATTACH:
4221 rtw_rf_destroy(sc->sc_rf);
4222 sc->sc_rf = NULL;
4223 /*FALLTHROUGH*/
4224 case FINISH_PARSE_SROM:
4225 case FINISH_READ_SROM:
4226 rtw_srom_free(&sc->sc_srom);
4227 /*FALLTHROUGH*/
4228 case FINISH_RESET:
4229 case FINISH_RXMAPS_CREATE:
4230 rtw_rxdesc_dmamaps_destroy(sc->sc_dmat, &sc->sc_rxsoft[0],
4231 RTW_RXQLEN);
4232 /*FALLTHROUGH*/
4233 case FINISH_TXMAPS_CREATE:
4234 for (pri = 0; pri < RTW_NTXPRI; pri++) {
4235 rtw_txdesc_dmamaps_destroy(sc->sc_dmat,
4236 sc->sc_txsoft_blk[pri].tsb_desc,
4237 sc->sc_txsoft_blk[pri].tsb_ndesc);
4238 }
4239 /*FALLTHROUGH*/
4240 case FINISH_TXDESCBLK_SETUP:
4241 case FINISH_TXCTLBLK_SETUP:
4242 rtw_txsoft_blk_cleanup_all(sc);
4243 /*FALLTHROUGH*/
4244 case FINISH_DESCMAP_LOAD:
4245 bus_dmamap_unload(sc->sc_dmat, sc->sc_desc_dmamap);
4246 /*FALLTHROUGH*/
4247 case FINISH_DESCMAP_CREATE:
4248 bus_dmamap_destroy(sc->sc_dmat, sc->sc_desc_dmamap);
4249 /*FALLTHROUGH*/
4250 case FINISH_DESC_MAP:
4251 bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_descs,
4252 sizeof(struct rtw_descs));
4253 /*FALLTHROUGH*/
4254 case FINISH_DESC_ALLOC:
4255 bus_dmamem_free(sc->sc_dmat, &sc->sc_desc_segs,
4256 sc->sc_desc_nsegs);
4257 /*FALLTHROUGH*/
4258 case DETACHED:
4259 NEXT_ATTACH_STATE(sc, DETACHED);
4260 break;
4261 }
4262 splx(s);
4263 return 0;
4264}
4265