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