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