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