rtw.c revision 1.32 1 /* $NetBSD: rtw.c,v 1.32 2004/12/28 22:30:07 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.32 2004/12/28 22:30:07 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, sq;
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 sq = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_SQ);
1396
1397 /* Note well: now we cannot recycle the srx_mbuf unless
1398 * we restore its original length.
1399 */
1400 m->m_pkthdr.rcvif = &sc->sc_if;
1401 m->m_pkthdr.len = m->m_len = len;
1402 m->m_flags |= M_HASFCS;
1403
1404 wh = mtod(m, struct ieee80211_frame *);
1405 /* TBD use _MAR, _BAR, _PAR flags as hints to _find_rxnode? */
1406 ni = ieee80211_find_rxnode(&sc->sc_ic, wh);
1407
1408 sc->sc_tsfth = htsfth;
1409
1410 #ifdef RTW_DEBUG
1411 if ((sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) ==
1412 (IFF_DEBUG|IFF_LINK2)) {
1413 ieee80211_dump_pkt(mtod(m, uint8_t *), m->m_pkthdr.len,
1414 rate, rssi);
1415 }
1416 #endif /* RTW_DEBUG */
1417
1418 #if NBPFILTER > 0
1419 if (sc->sc_radiobpf != NULL) {
1420 struct ieee80211com *ic = &sc->sc_ic;
1421 struct rtw_rx_radiotap_header *rr = &sc->sc_rxtap;
1422
1423 rr->rr_tsft =
1424 htole64(((uint64_t)htsfth << 32) | htsftl);
1425
1426 if ((hstat & RTW_RXSTAT_SPLCP) != 0)
1427 rr->rr_flags = IEEE80211_RADIOTAP_F_SHORTPRE;
1428
1429 rr->rr_flags = 0;
1430 rr->rr_rate = rate;
1431 rr->rr_chan_freq =
1432 htole16(ic->ic_bss->ni_chan->ic_freq);
1433 rr->rr_chan_flags =
1434 htole16(ic->ic_bss->ni_chan->ic_flags);
1435 rr->rr_antsignal = rssi;
1436 rr->rr_barker_lock = sq;
1437
1438 bpf_mtap2(sc->sc_radiobpf, (caddr_t)rr,
1439 sizeof(sc->sc_rxtapu), m);
1440 }
1441 #endif /* NPBFILTER > 0 */
1442
1443 ieee80211_input(&sc->sc_if, m, ni, rssi, htsftl);
1444 ieee80211_release_node(&sc->sc_ic, ni);
1445 next:
1446 rtw_rxdesc_init(sc->sc_dmat, sc->sc_desc_dmamap,
1447 hrx, srx, next, sc->sc_nrxdesc, 0);
1448 }
1449 sc->sc_rxnext = next;
1450
1451 KASSERT(sc->sc_rxnext < sc->sc_nrxdesc);
1452
1453 return;
1454 }
1455
1456 static void
1457 rtw_txbuf_release(bus_dma_tag_t dmat, struct ieee80211com *ic,
1458 struct rtw_txctl *stx)
1459 {
1460 struct mbuf *m;
1461 struct ieee80211_node *ni;
1462
1463 m = stx->stx_mbuf;
1464 ni = stx->stx_ni;
1465 KASSERT(m != NULL);
1466 KASSERT(ni != NULL);
1467 stx->stx_mbuf = NULL;
1468 stx->stx_ni = NULL;
1469
1470 bus_dmamap_sync(dmat, stx->stx_dmamap, 0, stx->stx_dmamap->dm_mapsize,
1471 BUS_DMASYNC_POSTWRITE);
1472 bus_dmamap_unload(dmat, stx->stx_dmamap);
1473 m_freem(m);
1474 ieee80211_release_node(ic, ni);
1475 }
1476
1477 static void
1478 rtw_txbufs_release(bus_dma_tag_t dmat, bus_dmamap_t desc_dmamap,
1479 struct ieee80211com *ic, struct rtw_txctl_blk *stc)
1480 {
1481 struct rtw_txctl *stx;
1482
1483 while ((stx = SIMPLEQ_FIRST(&stc->stc_dirtyq)) != NULL) {
1484 rtw_txbuf_release(dmat, ic, stx);
1485 SIMPLEQ_REMOVE_HEAD(&stc->stc_dirtyq, stx_q);
1486 SIMPLEQ_INSERT_TAIL(&stc->stc_freeq, stx, stx_q);
1487 }
1488 }
1489
1490 static __inline void
1491 rtw_collect_txpkt(struct rtw_softc *sc, struct rtw_txdesc_blk *htc,
1492 struct rtw_txctl *stx, int ndesc)
1493 {
1494 uint32_t hstat;
1495 int data_retry, rts_retry;
1496 struct rtw_txdesc *htxn;
1497 const char *condstring;
1498
1499 rtw_txbuf_release(sc->sc_dmat, &sc->sc_ic, stx);
1500
1501 htc->htc_nfree += ndesc;
1502
1503 htxn = &htc->htc_desc[stx->stx_last];
1504
1505 hstat = le32toh(htxn->htx_stat);
1506 rts_retry = MASK_AND_RSHIFT(hstat, RTW_TXSTAT_RTSRETRY_MASK);
1507 data_retry = MASK_AND_RSHIFT(hstat, RTW_TXSTAT_DRC_MASK);
1508
1509 sc->sc_if.if_collisions += rts_retry + data_retry;
1510
1511 if ((hstat & RTW_TXSTAT_TOK) != 0)
1512 condstring = "ok";
1513 else {
1514 sc->sc_if.if_oerrors++;
1515 condstring = "error";
1516 }
1517
1518 DPRINTF(sc, RTW_DEBUG_XMIT_DESC,
1519 ("%s: stx %p txdesc[%d, %d] %s tries rts %u data %u\n",
1520 sc->sc_dev.dv_xname, stx, stx->stx_first, stx->stx_last,
1521 condstring, rts_retry, data_retry));
1522 }
1523
1524 /* Collect transmitted packets. */
1525 static __inline void
1526 rtw_collect_txring(struct rtw_softc *sc, struct rtw_txctl_blk *stc,
1527 struct rtw_txdesc_blk *htc)
1528 {
1529 int ndesc;
1530 struct rtw_txctl *stx;
1531
1532 while ((stx = SIMPLEQ_FIRST(&stc->stc_dirtyq)) != NULL) {
1533 ndesc = 1 + stx->stx_last - stx->stx_first;
1534 if (stx->stx_last < stx->stx_first)
1535 ndesc += htc->htc_ndesc;
1536
1537 KASSERT(ndesc > 0);
1538
1539 rtw_txdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap, htc,
1540 stx->stx_first, ndesc,
1541 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1542
1543 if ((htc->htc_desc[stx->stx_last].htx_stat &
1544 htole32(RTW_TXSTAT_OWN)) != 0)
1545 break;
1546
1547 rtw_collect_txpkt(sc, htc, stx, ndesc);
1548 SIMPLEQ_REMOVE_HEAD(&stc->stc_dirtyq, stx_q);
1549 SIMPLEQ_INSERT_TAIL(&stc->stc_freeq, stx, stx_q);
1550 sc->sc_if.if_flags &= ~IFF_OACTIVE;
1551 }
1552 if (stx == NULL)
1553 stc->stc_tx_timer = 0;
1554 }
1555
1556 static void
1557 rtw_intr_tx(struct rtw_softc *sc, u_int16_t isr)
1558 {
1559 int pri;
1560 struct rtw_txctl_blk *stc;
1561 struct rtw_txdesc_blk *htc;
1562
1563 for (pri = 0; pri < RTW_NTXPRI; pri++) {
1564 stc = &sc->sc_txctl_blk[pri];
1565 htc = &sc->sc_txdesc_blk[pri];
1566
1567 rtw_collect_txring(sc, stc, htc);
1568
1569 if ((isr & RTW_INTR_TX) != 0)
1570 rtw_start(&sc->sc_if);
1571 }
1572
1573 /* TBD */
1574 return;
1575 }
1576
1577 static void
1578 rtw_intr_beacon(struct rtw_softc *sc, u_int16_t isr)
1579 {
1580 /* TBD */
1581 return;
1582 }
1583
1584 static void
1585 rtw_intr_atim(struct rtw_softc *sc)
1586 {
1587 /* TBD */
1588 return;
1589 }
1590
1591 #ifdef RTW_DEBUG
1592 static void
1593 rtw_dump_rings(struct rtw_softc *sc)
1594 {
1595 struct rtw_txdesc_blk *htc;
1596 struct rtw_rxdesc *hrx;
1597 int desc, pri;
1598
1599 if ((rtw_debug & RTW_DEBUG_IO_KICK) == 0)
1600 return;
1601
1602 for (pri = 0; pri < RTW_NTXPRI; pri++) {
1603 htc = &sc->sc_txdesc_blk[pri];
1604 printf("%s: txpri %d ndesc %d nfree %d\n", __func__, pri,
1605 htc->htc_ndesc, htc->htc_nfree);
1606 for (desc = 0; desc < htc->htc_ndesc; desc++)
1607 rtw_print_txdesc(sc, ".", NULL, htc, desc);
1608 }
1609
1610 for (desc = 0; desc < RTW_RXQLEN; desc++) {
1611 hrx = &sc->sc_rxdesc[desc];
1612 printf("%s: %sctl %08x rsvd0/rssi %08x buf/tsftl %08x "
1613 "rsvd1/tsfth %08x\n", __func__,
1614 (desc >= sc->sc_nrxdesc) ? "UNUSED " : "",
1615 le32toh(hrx->hrx_ctl), le32toh(hrx->hrx_rssi),
1616 le32toh(hrx->hrx_buf), le32toh(hrx->hrx_tsfth));
1617 }
1618 }
1619 #endif /* RTW_DEBUG */
1620
1621 static void
1622 rtw_hwring_setup(struct rtw_softc *sc)
1623 {
1624 struct rtw_regs *regs = &sc->sc_regs;
1625 RTW_WRITE(regs, RTW_RDSAR, RTW_RING_BASE(sc, hd_rx));
1626 RTW_WRITE(regs, RTW_TLPDA, RTW_RING_BASE(sc, hd_txlo));
1627 RTW_WRITE(regs, RTW_TNPDA, RTW_RING_BASE(sc, hd_txmd));
1628 RTW_WRITE(regs, RTW_THPDA, RTW_RING_BASE(sc, hd_txhi));
1629 RTW_WRITE(regs, RTW_TBDA, RTW_RING_BASE(sc, hd_bcn));
1630 RTW_SYNC(regs, RTW_TLPDA, RTW_RDSAR);
1631 RTW_DPRINTF(RTW_DEBUG_XMIT_DESC,
1632 ("%s: reg[TLPDA] <- %" PRIxPTR "\n", __func__,
1633 (uintptr_t)RTW_RING_BASE(sc, hd_txlo)));
1634 RTW_DPRINTF(RTW_DEBUG_XMIT_DESC,
1635 ("%s: reg[TNPDA] <- %" PRIxPTR "\n", __func__,
1636 (uintptr_t)RTW_RING_BASE(sc, hd_txmd)));
1637 RTW_DPRINTF(RTW_DEBUG_XMIT_DESC,
1638 ("%s: reg[THPDA] <- %" PRIxPTR "\n", __func__,
1639 (uintptr_t)RTW_RING_BASE(sc, hd_txhi)));
1640 RTW_DPRINTF(RTW_DEBUG_XMIT_DESC,
1641 ("%s: reg[TBDA] <- %" PRIxPTR "\n", __func__,
1642 (uintptr_t)RTW_RING_BASE(sc, hd_bcn)));
1643 RTW_DPRINTF(RTW_DEBUG_RECV_DESC,
1644 ("%s: reg[RDSAR] <- %" PRIxPTR "\n", __func__,
1645 (uintptr_t)RTW_RING_BASE(sc, hd_rx)));
1646 }
1647
1648 static int
1649 rtw_swring_setup(struct rtw_softc *sc)
1650 {
1651 int rc;
1652 rtw_txdesc_blk_init_all(&sc->sc_txdesc_blk[0]);
1653
1654 rtw_txctl_blk_init_all(&sc->sc_txctl_blk[0]);
1655
1656 if ((rc = rtw_rxctl_init_all(sc->sc_dmat, sc->sc_rxctl, &sc->sc_nrxdesc,
1657 sc->sc_dev.dv_xname)) != 0 && sc->sc_nrxdesc == 0) {
1658 printf("%s: could not allocate rx buffers\n",
1659 sc->sc_dev.dv_xname);
1660 return rc;
1661 }
1662 rtw_rxdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap,
1663 0, sc->sc_nrxdesc, sc->sc_nrxdesc,
1664 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1665 sc->sc_rxnext = 0;
1666 rtw_rxdesc_init_all(sc->sc_dmat, sc->sc_desc_dmamap,
1667 sc->sc_rxdesc, sc->sc_rxctl, sc->sc_nrxdesc, 1);
1668
1669 rtw_txdescs_sync_all(sc->sc_dmat, sc->sc_desc_dmamap,
1670 &sc->sc_txdesc_blk[0]);
1671 return 0;
1672 }
1673
1674 static void
1675 rtw_txdesc_blk_reset(struct rtw_txdesc_blk *htc)
1676 {
1677 int i;
1678
1679 (void)memset(htc->htc_desc, 0,
1680 sizeof(htc->htc_desc[0]) * htc->htc_ndesc);
1681 for (i = 0; i < htc->htc_ndesc; i++)
1682 htc->htc_desc[i].htx_next = htole32(RTW_NEXT_DESC(htc, i));
1683 htc->htc_nfree = htc->htc_ndesc;
1684 htc->htc_next = 0;
1685 }
1686
1687 static void
1688 rtw_txdescs_reset(struct rtw_softc *sc)
1689 {
1690 int pri;
1691 struct rtw_txdesc_blk *htc;
1692
1693 for (pri = 0; pri < RTW_NTXPRI; pri++) {
1694 htc = &sc->sc_txdesc_blk[pri];
1695 rtw_txbufs_release(sc->sc_dmat, sc->sc_desc_dmamap, &sc->sc_ic,
1696 &sc->sc_txctl_blk[pri]);
1697 rtw_txdesc_blk_reset(htc);
1698 rtw_txdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap, htc,
1699 0, htc->htc_ndesc,
1700 BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
1701 }
1702 }
1703
1704 static void
1705 rtw_rxdescs_reset(struct rtw_softc *sc)
1706 {
1707 /* Re-initialize descriptors, just in case. */
1708 rtw_rxdesc_init_all(sc->sc_dmat, sc->sc_desc_dmamap, sc->sc_rxdesc,
1709 &sc->sc_rxctl[0], sc->sc_nrxdesc, 1);
1710
1711 /* Reset to start of ring. */
1712 sc->sc_rxnext = 0;
1713 }
1714
1715 static void
1716 rtw_intr_ioerror(struct rtw_softc *sc, uint16_t isr)
1717 {
1718 struct rtw_regs *regs = &sc->sc_regs;
1719
1720 if ((isr & RTW_INTR_TXFOVW) != 0)
1721 printf("%s: tx fifo overflow\n", sc->sc_dev.dv_xname);
1722
1723 if ((isr & (RTW_INTR_RDU|RTW_INTR_RXFOVW)) == 0)
1724 return;
1725
1726 RTW_DPRINTF(RTW_DEBUG_BUGS, ("%s: restarting xmit/recv\n",
1727 sc->sc_dev.dv_xname));
1728
1729 #ifdef RTW_DEBUG
1730 rtw_dump_rings(sc);
1731 #endif /* RTW_DEBUG */
1732
1733 rtw_io_enable(regs, RTW_CR_RE | RTW_CR_TE, 0);
1734
1735 /* Collect rx'd packets. Refresh rx buffers. */
1736 rtw_intr_rx(sc, 0);
1737 /* Collect tx'd packets. */
1738 rtw_intr_tx(sc, 0);
1739
1740 RTW_WRITE16(regs, RTW_IMR, 0);
1741 RTW_SYNC(regs, RTW_IMR, RTW_IMR);
1742
1743 rtw_chip_reset1(regs, sc->sc_dev.dv_xname);
1744
1745 rtw_rxdescs_reset(sc);
1746 rtw_txdescs_reset(sc);
1747
1748 rtw_hwring_setup(sc);
1749
1750 #ifdef RTW_DEBUG
1751 rtw_dump_rings(sc);
1752 #endif /* RTW_DEBUG */
1753
1754 RTW_WRITE16(regs, RTW_IMR, sc->sc_inten);
1755 RTW_SYNC(regs, RTW_IMR, RTW_IMR);
1756 rtw_io_enable(regs, RTW_CR_RE | RTW_CR_TE, 1);
1757 }
1758
1759 static __inline void
1760 rtw_suspend_ticks(struct rtw_softc *sc)
1761 {
1762 RTW_DPRINTF(RTW_DEBUG_TIMEOUT,
1763 ("%s: suspending ticks\n", sc->sc_dev.dv_xname));
1764 sc->sc_do_tick = 0;
1765 }
1766
1767 static __inline void
1768 rtw_resume_ticks(struct rtw_softc *sc)
1769 {
1770 u_int32_t tsftrl0, tsftrl1, next_tick;
1771
1772 tsftrl0 = RTW_READ(&sc->sc_regs, RTW_TSFTRL);
1773
1774 tsftrl1 = RTW_READ(&sc->sc_regs, RTW_TSFTRL);
1775 next_tick = tsftrl1 + 1000000;
1776 RTW_WRITE(&sc->sc_regs, RTW_TINT, next_tick);
1777
1778 sc->sc_do_tick = 1;
1779
1780 RTW_DPRINTF(RTW_DEBUG_TIMEOUT,
1781 ("%s: resume ticks delta %#08x now %#08x next %#08x\n",
1782 sc->sc_dev.dv_xname, tsftrl1 - tsftrl0, tsftrl1, next_tick));
1783 }
1784
1785 static void
1786 rtw_intr_timeout(struct rtw_softc *sc)
1787 {
1788 RTW_DPRINTF(RTW_DEBUG_TIMEOUT, ("%s: timeout\n", sc->sc_dev.dv_xname));
1789 if (sc->sc_do_tick)
1790 rtw_resume_ticks(sc);
1791 return;
1792 }
1793
1794 int
1795 rtw_intr(void *arg)
1796 {
1797 int i;
1798 struct rtw_softc *sc = arg;
1799 struct rtw_regs *regs = &sc->sc_regs;
1800 u_int16_t isr;
1801
1802 /*
1803 * If the interface isn't running, the interrupt couldn't
1804 * possibly have come from us.
1805 */
1806 if ((sc->sc_flags & RTW_F_ENABLED) == 0 ||
1807 (sc->sc_if.if_flags & IFF_RUNNING) == 0 ||
1808 (sc->sc_dev.dv_flags & DVF_ACTIVE) == 0) {
1809 RTW_DPRINTF(RTW_DEBUG_INTR, ("%s: stray interrupt\n", sc->sc_dev.dv_xname));
1810 return (0);
1811 }
1812
1813 for (i = 0; i < 10; i++) {
1814 isr = RTW_READ16(regs, RTW_ISR);
1815
1816 RTW_WRITE16(regs, RTW_ISR, isr);
1817 RTW_WBR(regs, RTW_ISR, RTW_ISR);
1818
1819 if (sc->sc_intr_ack != NULL)
1820 (*sc->sc_intr_ack)(regs);
1821
1822 if (isr == 0)
1823 break;
1824
1825 #ifdef RTW_DEBUG
1826 #define PRINTINTR(flag) do { \
1827 if ((isr & flag) != 0) { \
1828 printf("%s" #flag, delim); \
1829 delim = ","; \
1830 } \
1831 } while (0)
1832
1833 if ((rtw_debug & RTW_DEBUG_INTR) != 0 && isr != 0) {
1834 const char *delim = "<";
1835
1836 printf("%s: reg[ISR] = %x", sc->sc_dev.dv_xname, isr);
1837
1838 PRINTINTR(RTW_INTR_TXFOVW);
1839 PRINTINTR(RTW_INTR_TIMEOUT);
1840 PRINTINTR(RTW_INTR_BCNINT);
1841 PRINTINTR(RTW_INTR_ATIMINT);
1842 PRINTINTR(RTW_INTR_TBDER);
1843 PRINTINTR(RTW_INTR_TBDOK);
1844 PRINTINTR(RTW_INTR_THPDER);
1845 PRINTINTR(RTW_INTR_THPDOK);
1846 PRINTINTR(RTW_INTR_TNPDER);
1847 PRINTINTR(RTW_INTR_TNPDOK);
1848 PRINTINTR(RTW_INTR_RXFOVW);
1849 PRINTINTR(RTW_INTR_RDU);
1850 PRINTINTR(RTW_INTR_TLPDER);
1851 PRINTINTR(RTW_INTR_TLPDOK);
1852 PRINTINTR(RTW_INTR_RER);
1853 PRINTINTR(RTW_INTR_ROK);
1854
1855 printf(">\n");
1856 }
1857 #undef PRINTINTR
1858 #endif /* RTW_DEBUG */
1859
1860 if ((isr & RTW_INTR_RX) != 0)
1861 rtw_intr_rx(sc, isr & RTW_INTR_RX);
1862 if ((isr & RTW_INTR_TX) != 0)
1863 rtw_intr_tx(sc, isr & RTW_INTR_TX);
1864 if ((isr & RTW_INTR_BEACON) != 0)
1865 rtw_intr_beacon(sc, isr & RTW_INTR_BEACON);
1866 if ((isr & RTW_INTR_ATIMINT) != 0)
1867 rtw_intr_atim(sc);
1868 if ((isr & RTW_INTR_IOERROR) != 0)
1869 rtw_intr_ioerror(sc, isr & RTW_INTR_IOERROR);
1870 if ((isr & RTW_INTR_TIMEOUT) != 0)
1871 rtw_intr_timeout(sc);
1872 }
1873
1874 return 1;
1875 }
1876
1877 /* Must be called at splnet. */
1878 static void
1879 rtw_stop(struct ifnet *ifp, int disable)
1880 {
1881 int pri;
1882 struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc;
1883 struct ieee80211com *ic = &sc->sc_ic;
1884 struct rtw_regs *regs = &sc->sc_regs;
1885
1886 if ((sc->sc_flags & RTW_F_ENABLED) == 0)
1887 return;
1888
1889 rtw_suspend_ticks(sc);
1890
1891 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
1892
1893 if ((sc->sc_flags & RTW_F_INVALID) == 0) {
1894 /* Disable interrupts. */
1895 RTW_WRITE16(regs, RTW_IMR, 0);
1896
1897 RTW_WBW(regs, RTW_TPPOLL, RTW_IMR);
1898
1899 /* Stop the transmit and receive processes. First stop DMA,
1900 * then disable receiver and transmitter.
1901 */
1902 RTW_WRITE8(regs, RTW_TPPOLL,
1903 RTW_TPPOLL_SBQ|RTW_TPPOLL_SHPQ|RTW_TPPOLL_SNPQ|
1904 RTW_TPPOLL_SLPQ);
1905
1906 RTW_SYNC(regs, RTW_TPPOLL, RTW_IMR);
1907
1908 rtw_io_enable(&sc->sc_regs, RTW_CR_RE|RTW_CR_TE, 0);
1909 }
1910
1911 for (pri = 0; pri < RTW_NTXPRI; pri++) {
1912 rtw_txbufs_release(sc->sc_dmat, sc->sc_desc_dmamap, &sc->sc_ic,
1913 &sc->sc_txctl_blk[pri]);
1914 }
1915
1916 rtw_rxbufs_release(sc->sc_dmat, &sc->sc_rxctl[0]);
1917
1918 if (disable)
1919 rtw_disable(sc);
1920
1921 /* Mark the interface as not running. Cancel the watchdog timer. */
1922 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1923 ifp->if_timer = 0;
1924
1925 return;
1926 }
1927
1928 const char *
1929 rtw_pwrstate_string(enum rtw_pwrstate power)
1930 {
1931 switch (power) {
1932 case RTW_ON:
1933 return "on";
1934 case RTW_SLEEP:
1935 return "sleep";
1936 case RTW_OFF:
1937 return "off";
1938 default:
1939 return "unknown";
1940 }
1941 }
1942
1943 /* XXX For Maxim, I am using the RFMD settings gleaned from the
1944 * reference driver, plus a magic Maxim "ON" value that comes from
1945 * the Realtek document "Windows PG for Rtl8180."
1946 */
1947 static void
1948 rtw_maxim_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
1949 int before_rf, int digphy)
1950 {
1951 u_int32_t anaparm;
1952
1953 anaparm = RTW_READ(regs, RTW_ANAPARM);
1954 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF);
1955
1956 switch (power) {
1957 case RTW_OFF:
1958 if (before_rf)
1959 return;
1960 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_OFF;
1961 anaparm |= RTW_ANAPARM_TXDACOFF;
1962 break;
1963 case RTW_SLEEP:
1964 if (!before_rf)
1965 return;
1966 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_SLEEP;
1967 anaparm |= RTW_ANAPARM_TXDACOFF;
1968 break;
1969 case RTW_ON:
1970 if (!before_rf)
1971 return;
1972 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_ON;
1973 break;
1974 }
1975 RTW_DPRINTF(RTW_DEBUG_PWR,
1976 ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n",
1977 __func__, rtw_pwrstate_string(power),
1978 (before_rf) ? "before" : "after", anaparm));
1979
1980 RTW_WRITE(regs, RTW_ANAPARM, anaparm);
1981 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
1982 }
1983
1984 /* XXX I am using the RFMD settings gleaned from the reference
1985 * driver. They agree
1986 */
1987 static void
1988 rtw_rfmd_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
1989 int before_rf, int digphy)
1990 {
1991 u_int32_t anaparm;
1992
1993 anaparm = RTW_READ(regs, RTW_ANAPARM);
1994 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF);
1995
1996 switch (power) {
1997 case RTW_OFF:
1998 if (before_rf)
1999 return;
2000 anaparm |= RTW_ANAPARM_RFPOW_RFMD_OFF;
2001 anaparm |= RTW_ANAPARM_TXDACOFF;
2002 break;
2003 case RTW_SLEEP:
2004 if (!before_rf)
2005 return;
2006 anaparm |= RTW_ANAPARM_RFPOW_RFMD_SLEEP;
2007 anaparm |= RTW_ANAPARM_TXDACOFF;
2008 break;
2009 case RTW_ON:
2010 if (!before_rf)
2011 return;
2012 anaparm |= RTW_ANAPARM_RFPOW_RFMD_ON;
2013 break;
2014 }
2015 RTW_DPRINTF(RTW_DEBUG_PWR,
2016 ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n",
2017 __func__, rtw_pwrstate_string(power),
2018 (before_rf) ? "before" : "after", anaparm));
2019
2020 RTW_WRITE(regs, RTW_ANAPARM, anaparm);
2021 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
2022 }
2023
2024 static void
2025 rtw_philips_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
2026 int before_rf, int digphy)
2027 {
2028 u_int32_t anaparm;
2029
2030 anaparm = RTW_READ(regs, RTW_ANAPARM);
2031 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF);
2032
2033 switch (power) {
2034 case RTW_OFF:
2035 if (before_rf)
2036 return;
2037 anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_OFF;
2038 anaparm |= RTW_ANAPARM_TXDACOFF;
2039 break;
2040 case RTW_SLEEP:
2041 if (!before_rf)
2042 return;
2043 anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_SLEEP;
2044 anaparm |= RTW_ANAPARM_TXDACOFF;
2045 break;
2046 case RTW_ON:
2047 if (!before_rf)
2048 return;
2049 if (digphy) {
2050 anaparm |= RTW_ANAPARM_RFPOW_DIG_PHILIPS_ON;
2051 /* XXX guess */
2052 anaparm |= RTW_ANAPARM_TXDACOFF;
2053 } else
2054 anaparm |= RTW_ANAPARM_RFPOW_ANA_PHILIPS_ON;
2055 break;
2056 }
2057 RTW_DPRINTF(RTW_DEBUG_PWR,
2058 ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n",
2059 __func__, rtw_pwrstate_string(power),
2060 (before_rf) ? "before" : "after", anaparm));
2061
2062 RTW_WRITE(regs, RTW_ANAPARM, anaparm);
2063 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
2064 }
2065
2066 static void
2067 rtw_pwrstate0(struct rtw_softc *sc, enum rtw_pwrstate power, int before_rf,
2068 int digphy)
2069 {
2070 struct rtw_regs *regs = &sc->sc_regs;
2071
2072 rtw_set_access(sc, RTW_ACCESS_ANAPARM);
2073
2074 (*sc->sc_pwrstate_cb)(regs, power, before_rf, digphy);
2075
2076 rtw_set_access(sc, RTW_ACCESS_NONE);
2077
2078 return;
2079 }
2080
2081 static int
2082 rtw_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power)
2083 {
2084 int rc;
2085
2086 RTW_DPRINTF(RTW_DEBUG_PWR,
2087 ("%s: %s->%s\n", __func__,
2088 rtw_pwrstate_string(sc->sc_pwrstate), rtw_pwrstate_string(power)));
2089
2090 if (sc->sc_pwrstate == power)
2091 return 0;
2092
2093 rtw_pwrstate0(sc, power, 1, sc->sc_flags & RTW_F_DIGPHY);
2094 rc = rtw_rf_pwrstate(sc->sc_rf, power);
2095 rtw_pwrstate0(sc, power, 0, sc->sc_flags & RTW_F_DIGPHY);
2096
2097 switch (power) {
2098 case RTW_ON:
2099 /* TBD set LEDs */
2100 break;
2101 case RTW_SLEEP:
2102 /* TBD */
2103 break;
2104 case RTW_OFF:
2105 /* TBD */
2106 break;
2107 }
2108 if (rc == 0)
2109 sc->sc_pwrstate = power;
2110 else
2111 sc->sc_pwrstate = RTW_OFF;
2112 return rc;
2113 }
2114
2115 static int
2116 rtw_tune(struct rtw_softc *sc)
2117 {
2118 struct ieee80211com *ic = &sc->sc_ic;
2119 u_int chan;
2120 int rc;
2121 int antdiv = sc->sc_flags & RTW_F_ANTDIV,
2122 dflantb = sc->sc_flags & RTW_F_DFLANTB;
2123
2124 KASSERT(ic->ic_bss->ni_chan != NULL);
2125
2126 chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
2127 if (chan == IEEE80211_CHAN_ANY)
2128 panic("%s: chan == IEEE80211_CHAN_ANY\n", __func__);
2129
2130 if (chan == sc->sc_cur_chan) {
2131 RTW_DPRINTF(RTW_DEBUG_TUNE,
2132 ("%s: already tuned chan #%d\n", __func__, chan));
2133 return 0;
2134 }
2135
2136 rtw_suspend_ticks(sc);
2137
2138 rtw_io_enable(&sc->sc_regs, RTW_CR_RE | RTW_CR_TE, 0);
2139
2140 /* TBD wait for Tx to complete */
2141
2142 KASSERT((sc->sc_flags & RTW_F_ENABLED) != 0);
2143
2144 if ((rc = rtw_phy_init(&sc->sc_regs, sc->sc_rf,
2145 rtw_chan2txpower(&sc->sc_srom, ic, ic->ic_bss->ni_chan),
2146 sc->sc_csthr, ic->ic_bss->ni_chan->ic_freq, antdiv,
2147 dflantb, RTW_ON)) != 0) {
2148 /* XXX condition on powersaving */
2149 printf("%s: phy init failed\n", sc->sc_dev.dv_xname);
2150 }
2151
2152 sc->sc_cur_chan = chan;
2153
2154 rtw_io_enable(&sc->sc_regs, RTW_CR_RE | RTW_CR_TE, 1);
2155
2156 rtw_resume_ticks(sc);
2157
2158 return rc;
2159 }
2160
2161 void
2162 rtw_disable(struct rtw_softc *sc)
2163 {
2164 int rc;
2165
2166 if ((sc->sc_flags & RTW_F_ENABLED) == 0)
2167 return;
2168
2169 /* turn off PHY */
2170 if ((rc = rtw_pwrstate(sc, RTW_OFF)) != 0)
2171 printf("%s: failed to turn off PHY (%d)\n",
2172 sc->sc_dev.dv_xname, rc);
2173
2174 if (sc->sc_disable != NULL)
2175 (*sc->sc_disable)(sc);
2176
2177 sc->sc_flags &= ~RTW_F_ENABLED;
2178 }
2179
2180 int
2181 rtw_enable(struct rtw_softc *sc)
2182 {
2183 if ((sc->sc_flags & RTW_F_ENABLED) == 0) {
2184 if (sc->sc_enable != NULL && (*sc->sc_enable)(sc) != 0) {
2185 printf("%s: device enable failed\n",
2186 sc->sc_dev.dv_xname);
2187 return (EIO);
2188 }
2189 sc->sc_flags |= RTW_F_ENABLED;
2190 }
2191 return (0);
2192 }
2193
2194 static void
2195 rtw_transmit_config(struct rtw_regs *regs)
2196 {
2197 u_int32_t tcr;
2198
2199 tcr = RTW_READ(regs, RTW_TCR);
2200
2201 tcr |= RTW_TCR_CWMIN;
2202 tcr &= ~RTW_TCR_MXDMA_MASK;
2203 tcr |= RTW_TCR_MXDMA_256;
2204 tcr |= RTW_TCR_SAT; /* send ACK as fast as possible */
2205 tcr &= ~RTW_TCR_LBK_MASK;
2206 tcr |= RTW_TCR_LBK_NORMAL; /* normal operating mode */
2207
2208 /* set short/long retry limits */
2209 tcr &= ~(RTW_TCR_SRL_MASK|RTW_TCR_LRL_MASK);
2210 tcr |= LSHIFT(4, RTW_TCR_SRL_MASK) | LSHIFT(4, RTW_TCR_LRL_MASK);
2211
2212 tcr &= ~RTW_TCR_CRC; /* NIC appends CRC32 */
2213
2214 RTW_WRITE(regs, RTW_TCR, tcr);
2215 RTW_SYNC(regs, RTW_TCR, RTW_TCR);
2216 }
2217
2218 static __inline void
2219 rtw_enable_interrupts(struct rtw_softc *sc)
2220 {
2221 struct rtw_regs *regs = &sc->sc_regs;
2222
2223 sc->sc_inten = RTW_INTR_RX|RTW_INTR_TX|RTW_INTR_BEACON|RTW_INTR_ATIMINT;
2224 sc->sc_inten |= RTW_INTR_IOERROR|RTW_INTR_TIMEOUT;
2225
2226 RTW_WRITE16(regs, RTW_IMR, sc->sc_inten);
2227 RTW_WBW(regs, RTW_IMR, RTW_ISR);
2228 RTW_WRITE16(regs, RTW_ISR, 0xffff);
2229 RTW_SYNC(regs, RTW_IMR, RTW_ISR);
2230
2231 /* XXX necessary? */
2232 if (sc->sc_intr_ack != NULL)
2233 (*sc->sc_intr_ack)(regs);
2234 }
2235
2236 static void
2237 rtw_set_nettype(struct rtw_softc *sc, enum ieee80211_opmode opmode)
2238 {
2239 uint8_t msr;
2240
2241 /* I'm guessing that MSR is protected as CONFIG[0123] are. */
2242 rtw_set_access(sc, RTW_ACCESS_CONFIG);
2243
2244 msr = RTW_READ8(&sc->sc_regs, RTW_MSR) & ~RTW_MSR_NETYPE_MASK;
2245
2246 switch (opmode) {
2247 case IEEE80211_M_AHDEMO:
2248 case IEEE80211_M_IBSS:
2249 msr |= RTW_MSR_NETYPE_ADHOC_OK;
2250 break;
2251 case IEEE80211_M_HOSTAP:
2252 msr |= RTW_MSR_NETYPE_AP_OK;
2253 break;
2254 case IEEE80211_M_MONITOR:
2255 /* XXX */
2256 msr |= RTW_MSR_NETYPE_NOLINK;
2257 break;
2258 case IEEE80211_M_STA:
2259 msr |= RTW_MSR_NETYPE_INFRA_OK;
2260 break;
2261 }
2262 RTW_WRITE8(&sc->sc_regs, RTW_MSR, msr);
2263
2264 rtw_set_access(sc, RTW_ACCESS_NONE);
2265 }
2266
2267 /* XXX is the endianness correct? test. */
2268 #define rtw_calchash(addr) \
2269 (ether_crc32_le((addr), IEEE80211_ADDR_LEN) & BITS(5, 0))
2270
2271 static void
2272 rtw_pktfilt_load(struct rtw_softc *sc)
2273 {
2274 struct rtw_regs *regs = &sc->sc_regs;
2275 struct ieee80211com *ic = &sc->sc_ic;
2276 struct ethercom *ec = &ic->ic_ec;
2277 struct ifnet *ifp = &sc->sc_ic.ic_if;
2278 int hash;
2279 u_int32_t hashes[2] = { 0, 0 };
2280 struct ether_multi *enm;
2281 struct ether_multistep step;
2282
2283 /* XXX might be necessary to stop Rx/Tx engines while setting filters */
2284
2285 #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)
2286
2287 if (ic->ic_opmode == IEEE80211_M_MONITOR)
2288 sc->sc_rcr |= RTW_RCR_MONITOR;
2289 else
2290 sc->sc_rcr &= ~RTW_RCR_MONITOR;
2291
2292 /* XXX reference sources BEGIN */
2293 sc->sc_rcr |= RTW_RCR_ENMARP;
2294 sc->sc_rcr |= RTW_RCR_AB | RTW_RCR_AM | RTW_RCR_APM;
2295 #if 0
2296 /* receive broadcasts in our BSS */
2297 sc->sc_rcr |= RTW_RCR_ADD3;
2298 #endif
2299 /* XXX reference sources END */
2300
2301 /* receive pwrmgmt frames. */
2302 sc->sc_rcr |= RTW_RCR_APWRMGT;
2303 /* receive mgmt/ctrl/data frames. */
2304 sc->sc_rcr |= RTW_RCR_ADF | RTW_RCR_AMF;
2305 /* initialize Rx DMA threshold, Tx DMA burst size */
2306 sc->sc_rcr |= RTW_RCR_RXFTH_WHOLE | RTW_RCR_MXDMA_1024;
2307
2308 ifp->if_flags &= ~IFF_ALLMULTI;
2309
2310 if (ifp->if_flags & IFF_PROMISC) {
2311 sc->sc_rcr |= RTW_RCR_AB; /* accept all broadcast */
2312 allmulti:
2313 ifp->if_flags |= IFF_ALLMULTI;
2314 goto setit;
2315 }
2316
2317 /*
2318 * Program the 64-bit multicast hash filter.
2319 */
2320 ETHER_FIRST_MULTI(step, ec, enm);
2321 while (enm != NULL) {
2322 /* XXX */
2323 if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
2324 ETHER_ADDR_LEN) != 0)
2325 goto allmulti;
2326
2327 hash = rtw_calchash(enm->enm_addrlo);
2328 hashes[hash >> 5] |= 1 << (hash & 0x1f);
2329 ETHER_NEXT_MULTI(step, enm);
2330 }
2331
2332 if (ifp->if_flags & IFF_BROADCAST) {
2333 hash = rtw_calchash(etherbroadcastaddr);
2334 hashes[hash >> 5] |= 1 << (hash & 0x1f);
2335 }
2336
2337 /* all bits set => hash is useless */
2338 if (~(hashes[0] & hashes[1]) == 0)
2339 goto allmulti;
2340
2341 setit:
2342 if (ifp->if_flags & IFF_ALLMULTI)
2343 sc->sc_rcr |= RTW_RCR_AM; /* accept all multicast */
2344
2345 if (ic->ic_state == IEEE80211_S_SCAN)
2346 sc->sc_rcr |= RTW_RCR_AB; /* accept all broadcast */
2347
2348 hashes[0] = hashes[1] = 0xffffffff;
2349
2350 RTW_WRITE(regs, RTW_MAR0, hashes[0]);
2351 RTW_WRITE(regs, RTW_MAR1, hashes[1]);
2352 RTW_WRITE(regs, RTW_RCR, sc->sc_rcr);
2353 RTW_SYNC(regs, RTW_MAR0, RTW_RCR); /* RTW_MAR0 < RTW_MAR1 < RTW_RCR */
2354
2355 DPRINTF(sc, RTW_DEBUG_PKTFILT,
2356 ("%s: RTW_MAR0 %08x RTW_MAR1 %08x RTW_RCR %08x\n",
2357 sc->sc_dev.dv_xname, RTW_READ(regs, RTW_MAR0),
2358 RTW_READ(regs, RTW_MAR1), RTW_READ(regs, RTW_RCR)));
2359
2360 return;
2361 }
2362
2363 /* Must be called at splnet. */
2364 static int
2365 rtw_init(struct ifnet *ifp)
2366 {
2367 struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc;
2368 struct ieee80211com *ic = &sc->sc_ic;
2369 struct rtw_regs *regs = &sc->sc_regs;
2370 int rc = 0;
2371
2372 if ((rc = rtw_enable(sc)) != 0)
2373 goto out;
2374
2375 /* Cancel pending I/O and reset. */
2376 rtw_stop(ifp, 0);
2377
2378 ic->ic_bss->ni_chan = ic->ic_ibss_chan;
2379 DPRINTF(sc, RTW_DEBUG_TUNE, ("%s: channel %d freq %d flags 0x%04x\n",
2380 __func__, ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan),
2381 ic->ic_bss->ni_chan->ic_freq, ic->ic_bss->ni_chan->ic_flags));
2382
2383 if ((rc = rtw_pwrstate(sc, RTW_OFF)) != 0)
2384 goto out;
2385
2386 if ((rc = rtw_swring_setup(sc)) != 0)
2387 goto out;
2388
2389 rtw_transmit_config(regs);
2390
2391 rtw_set_access(sc, RTW_ACCESS_CONFIG);
2392
2393 RTW_WRITE8(regs, RTW_MSR, 0x0); /* no link */
2394 RTW_WBW(regs, RTW_MSR, RTW_BRSR);
2395
2396 /* long PLCP header, 1Mb/2Mb basic rate */
2397 RTW_WRITE16(regs, RTW_BRSR, RTW_BRSR_MBR8180_2MBPS);
2398 RTW_SYNC(regs, RTW_BRSR, RTW_BRSR);
2399
2400 rtw_set_access(sc, RTW_ACCESS_ANAPARM);
2401 rtw_set_access(sc, RTW_ACCESS_NONE);
2402
2403 #if 0
2404 RTW_WRITE(regs, RTW_FEMR, RTW_FEMR_GWAKE|RTW_FEMR_WKUP|RTW_FEMR_INTR);
2405 #endif
2406 /* XXX from reference sources */
2407 RTW_WRITE(regs, RTW_FEMR, 0xffff);
2408 RTW_SYNC(regs, RTW_FEMR, RTW_FEMR);
2409
2410 rtw_set_rfprog(regs, sc->sc_rfchipid, sc->sc_dev.dv_xname);
2411
2412 RTW_WRITE8(regs, RTW_PHYDELAY, sc->sc_phydelay);
2413 /* from Linux driver */
2414 RTW_WRITE8(regs, RTW_CRCOUNT, RTW_CRCOUNT_MAGIC);
2415
2416 RTW_SYNC(regs, RTW_PHYDELAY, RTW_CRCOUNT);
2417
2418 rtw_enable_interrupts(sc);
2419
2420 rtw_pktfilt_load(sc);
2421
2422 rtw_hwring_setup(sc);
2423
2424 rtw_io_enable(regs, RTW_CR_RE|RTW_CR_TE, 1);
2425
2426 ifp->if_flags |= IFF_RUNNING;
2427 ic->ic_state = IEEE80211_S_INIT;
2428
2429 RTW_WRITE16(regs, RTW_BSSID16, 0x0);
2430 RTW_WRITE(regs, RTW_BSSID32, 0x0);
2431
2432 rtw_resume_ticks(sc);
2433
2434 rtw_set_nettype(sc, IEEE80211_M_MONITOR);
2435
2436 if (ic->ic_opmode == IEEE80211_M_MONITOR)
2437 return ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
2438 else
2439 return ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
2440
2441 out:
2442 printf("%s: interface not running\n", sc->sc_dev.dv_xname);
2443 return rc;
2444 }
2445
2446 static int
2447 rtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
2448 {
2449 int rc = 0, s;
2450 struct rtw_softc *sc = ifp->if_softc;
2451 struct ifreq *ifr = (struct ifreq *)data;
2452
2453 s = splnet();
2454 switch (cmd) {
2455 case SIOCSIFFLAGS:
2456 if ((ifp->if_flags & IFF_UP) != 0) {
2457 if (0 && (sc->sc_flags & RTW_F_ENABLED) != 0) {
2458 rtw_pktfilt_load(sc);
2459 } else
2460 rc = rtw_init(ifp);
2461 #ifdef RTW_DEBUG
2462 rtw_print_regs(&sc->sc_regs, ifp->if_xname, __func__);
2463 #endif /* RTW_DEBUG */
2464 } else if ((sc->sc_flags & RTW_F_ENABLED) != 0) {
2465 #ifdef RTW_DEBUG
2466 rtw_print_regs(&sc->sc_regs, ifp->if_xname, __func__);
2467 #endif /* RTW_DEBUG */
2468 rtw_stop(ifp, 1);
2469 }
2470 break;
2471 case SIOCADDMULTI:
2472 case SIOCDELMULTI:
2473 if (cmd == SIOCADDMULTI)
2474 rc = ether_addmulti(ifr, &sc->sc_ic.ic_ec);
2475 else
2476 rc = ether_delmulti(ifr, &sc->sc_ic.ic_ec);
2477 if (rc == ENETRESET) {
2478 if (ifp->if_flags & IFF_RUNNING)
2479 rtw_pktfilt_load(sc);
2480 rc = 0;
2481 }
2482 break;
2483 default:
2484 if ((rc = ieee80211_ioctl(ifp, cmd, data)) == ENETRESET) {
2485 if ((sc->sc_flags & RTW_F_ENABLED) != 0)
2486 rc = rtw_init(ifp);
2487 else
2488 rc = 0;
2489 }
2490 break;
2491 }
2492 splx(s);
2493 return rc;
2494 }
2495
2496 /* Point *mp at the next 802.11 frame to transmit. Point *stcp
2497 * at the driver's selection of transmit control block for the packet.
2498 */
2499 static __inline int
2500 rtw_dequeue(struct ifnet *ifp, struct rtw_txctl_blk **stcp,
2501 struct rtw_txdesc_blk **htcp, struct mbuf **mp,
2502 struct ieee80211_node **nip)
2503 {
2504 struct rtw_txctl_blk *stc;
2505 struct rtw_txdesc_blk *htc;
2506 struct mbuf *m0;
2507 struct rtw_softc *sc;
2508 struct ieee80211com *ic;
2509
2510 sc = (struct rtw_softc *)ifp->if_softc;
2511
2512 DPRINTF(sc, RTW_DEBUG_XMIT,
2513 ("%s: enter %s\n", sc->sc_dev.dv_xname, __func__));
2514 *mp = NULL;
2515
2516 stc = &sc->sc_txctl_blk[RTW_TXPRIMD];
2517 htc = &sc->sc_txdesc_blk[RTW_TXPRIMD];
2518
2519 if (SIMPLEQ_EMPTY(&stc->stc_freeq) || htc->htc_nfree == 0) {
2520 DPRINTF(sc, RTW_DEBUG_XMIT,
2521 ("%s: out of descriptors\n", __func__));
2522 ifp->if_flags |= IFF_OACTIVE;
2523 return 0;
2524 }
2525
2526 ic = &sc->sc_ic;
2527
2528 if (!IF_IS_EMPTY(&ic->ic_mgtq)) {
2529 IF_DEQUEUE(&ic->ic_mgtq, m0);
2530 *nip = (struct ieee80211_node *)m0->m_pkthdr.rcvif;
2531 m0->m_pkthdr.rcvif = NULL;
2532 DPRINTF(sc, RTW_DEBUG_XMIT,
2533 ("%s: dequeue mgt frame\n", __func__));
2534 } else if (ic->ic_state != IEEE80211_S_RUN) {
2535 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: not running\n", __func__));
2536 return 0;
2537 } else if (!IF_IS_EMPTY(&ic->ic_pwrsaveq)) {
2538 IF_DEQUEUE(&ic->ic_pwrsaveq, m0);
2539 *nip = (struct ieee80211_node *)m0->m_pkthdr.rcvif;
2540 m0->m_pkthdr.rcvif = NULL;
2541 DPRINTF(sc, RTW_DEBUG_XMIT,
2542 ("%s: dequeue pwrsave frame\n", __func__));
2543 } else {
2544 IFQ_DEQUEUE(&ifp->if_snd, m0);
2545 if (m0 == NULL) {
2546 DPRINTF(sc, RTW_DEBUG_XMIT,
2547 ("%s: no frame\n", __func__));
2548 return 0;
2549 }
2550 DPRINTF(sc, RTW_DEBUG_XMIT,
2551 ("%s: dequeue data frame\n", __func__));
2552 ifp->if_opackets++;
2553 #if NBPFILTER > 0
2554 if (ifp->if_bpf)
2555 bpf_mtap(ifp->if_bpf, m0);
2556 #endif
2557 if ((m0 = ieee80211_encap(ifp, m0, nip)) == NULL) {
2558 DPRINTF(sc, RTW_DEBUG_XMIT,
2559 ("%s: encap error\n", __func__));
2560 ifp->if_oerrors++;
2561 return -1;
2562 }
2563 }
2564 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: leave\n", __func__));
2565 *stcp = stc;
2566 *htcp = htc;
2567 *mp = m0;
2568 return 0;
2569 }
2570
2571 static int
2572 rtw_seg_too_short(bus_dmamap_t dmamap)
2573 {
2574 int i;
2575 for (i = 0; i < dmamap->dm_nsegs; i++) {
2576 if (dmamap->dm_segs[i].ds_len < 4) {
2577 printf("%s: segment too short\n", __func__);
2578 return 1;
2579 }
2580 }
2581 return 0;
2582 }
2583
2584 /* TBD factor with atw_start */
2585 static struct mbuf *
2586 rtw_dmamap_load_txbuf(bus_dma_tag_t dmat, bus_dmamap_t dmam, struct mbuf *chain,
2587 u_int ndescfree, short *ifflagsp, const char *dvname)
2588 {
2589 int first, rc;
2590 struct mbuf *m, *m0;
2591
2592 m0 = chain;
2593
2594 /*
2595 * Load the DMA map. Copy and try (once) again if the packet
2596 * didn't fit in the alloted number of segments.
2597 */
2598 for (first = 1;
2599 ((rc = bus_dmamap_load_mbuf(dmat, dmam, m0,
2600 BUS_DMA_WRITE|BUS_DMA_NOWAIT)) != 0 ||
2601 dmam->dm_nsegs > ndescfree || rtw_seg_too_short(dmam)) && first;
2602 first = 0) {
2603 if (rc == 0)
2604 bus_dmamap_unload(dmat, dmam);
2605 MGETHDR(m, M_DONTWAIT, MT_DATA);
2606 if (m == NULL) {
2607 printf("%s: unable to allocate Tx mbuf\n",
2608 dvname);
2609 break;
2610 }
2611 if (m0->m_pkthdr.len > MHLEN) {
2612 MCLGET(m, M_DONTWAIT);
2613 if ((m->m_flags & M_EXT) == 0) {
2614 printf("%s: cannot allocate Tx cluster\n",
2615 dvname);
2616 m_freem(m);
2617 break;
2618 }
2619 }
2620 m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t));
2621 m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len;
2622 m_freem(m0);
2623 m0 = m;
2624 m = NULL;
2625 }
2626 if (rc != 0) {
2627 printf("%s: cannot load Tx buffer, rc = %d\n", dvname, rc);
2628 m_freem(m0);
2629 return NULL;
2630 } else if (rtw_seg_too_short(dmam)) {
2631 printf("%s: cannot load Tx buffer, segment too short\n",
2632 dvname);
2633 bus_dmamap_unload(dmat, dmam);
2634 m_freem(m0);
2635 return NULL;
2636 } else if (dmam->dm_nsegs > ndescfree) {
2637 *ifflagsp |= IFF_OACTIVE;
2638 bus_dmamap_unload(dmat, dmam);
2639 m_freem(m0);
2640 return NULL;
2641 }
2642 return m0;
2643 }
2644
2645 #ifdef RTW_DEBUG
2646 static void
2647 rtw_print_txdesc(struct rtw_softc *sc, const char *action,
2648 struct rtw_txctl *stx, struct rtw_txdesc_blk *htc, int desc)
2649 {
2650 struct rtw_txdesc *htx = &htc->htc_desc[desc];
2651 DPRINTF(sc, RTW_DEBUG_XMIT_DESC, ("%s: %p %s txdesc[%d] ctl0 %#08x "
2652 "ctl1 %#08x buf %#08x len %#08x\n",
2653 sc->sc_dev.dv_xname, stx, action, desc,
2654 le32toh(htx->htx_ctl0),
2655 le32toh(htx->htx_ctl1), le32toh(htx->htx_buf),
2656 le32toh(htx->htx_len)));
2657 }
2658 #endif /* RTW_DEBUG */
2659
2660 static void
2661 rtw_start(struct ifnet *ifp)
2662 {
2663 uint8_t tppoll;
2664 int desc, i, lastdesc, npkt, rate;
2665 uint32_t proto_ctl0, ctl0, ctl1;
2666 bus_dmamap_t dmamap;
2667 struct ieee80211com *ic;
2668 struct ieee80211_duration *d0;
2669 struct ieee80211_frame *wh;
2670 struct ieee80211_node *ni;
2671 struct mbuf *m0;
2672 struct rtw_softc *sc;
2673 struct rtw_txctl_blk *stc;
2674 struct rtw_txdesc_blk *htc;
2675 struct rtw_txctl *stx;
2676 struct rtw_txdesc *htx;
2677
2678 sc = (struct rtw_softc *)ifp->if_softc;
2679 ic = &sc->sc_ic;
2680
2681 DPRINTF(sc, RTW_DEBUG_XMIT,
2682 ("%s: enter %s\n", sc->sc_dev.dv_xname, __func__));
2683
2684 if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
2685 goto out;
2686
2687 /* XXX do real rate control */
2688 proto_ctl0 = RTW_TXCTL0_RTSRATE_1MBPS;
2689
2690 switch (rate = MAX(2, ieee80211_get_rate(ic))) {
2691 case 2:
2692 proto_ctl0 |= RTW_TXCTL0_RATE_1MBPS;
2693 break;
2694 case 4:
2695 proto_ctl0 |= RTW_TXCTL0_RATE_2MBPS;
2696 break;
2697 case 11:
2698 proto_ctl0 |= RTW_TXCTL0_RATE_5MBPS;
2699 break;
2700 case 22:
2701 proto_ctl0 |= RTW_TXCTL0_RATE_11MBPS;
2702 break;
2703 }
2704
2705 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0)
2706 proto_ctl0 |= RTW_TXCTL0_SPLCP;
2707
2708 for (;;) {
2709 if (rtw_dequeue(ifp, &stc, &htc, &m0, &ni) == -1)
2710 continue;
2711 if (m0 == NULL)
2712 break;
2713 stx = SIMPLEQ_FIRST(&stc->stc_freeq);
2714
2715 dmamap = stx->stx_dmamap;
2716
2717 m0 = rtw_dmamap_load_txbuf(sc->sc_dmat, dmamap, m0,
2718 htc->htc_nfree, &ifp->if_flags, sc->sc_dev.dv_xname);
2719
2720 if (m0 == NULL || dmamap->dm_nsegs == 0) {
2721 DPRINTF(sc, RTW_DEBUG_XMIT,
2722 ("%s: fail dmamap load\n", __func__));
2723 goto post_dequeue_err;
2724 }
2725
2726 #ifdef RTW_DEBUG
2727 if ((sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) ==
2728 (IFF_DEBUG|IFF_LINK2)) {
2729 ieee80211_dump_pkt(mtod(m0, uint8_t *),
2730 (dmamap->dm_nsegs == 1) ? m0->m_pkthdr.len
2731 : sizeof(wh),
2732 rate, 0);
2733 }
2734 #endif /* RTW_DEBUG */
2735 ctl0 = proto_ctl0 |
2736 LSHIFT(m0->m_pkthdr.len, RTW_TXCTL0_TPKTSIZE_MASK);
2737
2738 wh = mtod(m0, struct ieee80211_frame *);
2739
2740 if (ieee80211_compute_duration(wh, m0->m_pkthdr.len,
2741 ic->ic_flags, ic->ic_fragthreshold,
2742 rate, &stx->stx_d0, &stx->stx_dn, &npkt,
2743 (sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) ==
2744 (IFF_DEBUG|IFF_LINK2)) == -1) {
2745 DPRINTF(sc, RTW_DEBUG_XMIT,
2746 ("%s: fail compute duration\n", __func__));
2747 goto post_load_err;
2748 }
2749
2750 /* XXX >= ? */
2751 if (m0->m_pkthdr.len > ic->ic_rtsthreshold)
2752 ctl0 |= RTW_TXCTL0_RTSEN;
2753
2754 d0 = &stx->stx_d0;
2755
2756 *(uint16_t*)wh->i_dur = htole16(d0->d_data_dur);
2757
2758 ctl1 = LSHIFT(d0->d_plcp_len, RTW_TXCTL1_LENGTH_MASK) |
2759 LSHIFT(d0->d_rts_dur, RTW_TXCTL1_RTSDUR_MASK);
2760
2761 if (d0->d_residue)
2762 ctl1 |= RTW_TXCTL1_LENGEXT;
2763
2764 /* TBD fragmentation */
2765
2766 stx->stx_first = htc->htc_next;
2767
2768 rtw_txdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap,
2769 htc, stx->stx_first, dmamap->dm_nsegs,
2770 BUS_DMASYNC_PREWRITE);
2771
2772 KASSERT(stx->stx_first < htc->htc_ndesc);
2773
2774 #if NBPFILTER > 0
2775 if (ic->ic_rawbpf != NULL)
2776 bpf_mtap((caddr_t)ic->ic_rawbpf, m0);
2777
2778 if (sc->sc_radiobpf != NULL) {
2779 struct rtw_tx_radiotap_header *rt = &sc->sc_txtap;
2780
2781 rt->rt_flags = 0;
2782 rt->rt_rate = rate;
2783 rt->rt_chan_freq =
2784 htole16(ic->ic_bss->ni_chan->ic_freq);
2785 rt->rt_chan_flags =
2786 htole16(ic->ic_bss->ni_chan->ic_flags);
2787
2788 bpf_mtap2(sc->sc_radiobpf, (caddr_t)rt,
2789 sizeof(sc->sc_txtapu), m0);
2790 }
2791 #endif /* NPBFILTER > 0 */
2792
2793 for (i = 0, lastdesc = desc = stx->stx_first;
2794 i < dmamap->dm_nsegs;
2795 i++, desc = RTW_NEXT_IDX(htc, desc)) {
2796 if (dmamap->dm_segs[i].ds_len > RTW_TXLEN_LENGTH_MASK) {
2797 DPRINTF(sc, RTW_DEBUG_XMIT_DESC,
2798 ("%s: seg too long\n", __func__));
2799 goto post_load_err;
2800 }
2801 htx = &htc->htc_desc[desc];
2802 htx->htx_ctl0 = htole32(ctl0);
2803 if (i != 0)
2804 htx->htx_ctl0 |= htole32(RTW_TXCTL0_OWN);
2805 htx->htx_ctl1 = htole32(ctl1);
2806 htx->htx_buf = htole32(dmamap->dm_segs[i].ds_addr);
2807 htx->htx_len = htole32(dmamap->dm_segs[i].ds_len);
2808 lastdesc = desc;
2809 #ifdef RTW_DEBUG
2810 rtw_print_txdesc(sc, "load", stx, htc, desc);
2811 #endif /* RTW_DEBUG */
2812 }
2813
2814 KASSERT(desc < htc->htc_ndesc);
2815
2816 stx->stx_ni = ni;
2817 stx->stx_mbuf = m0;
2818 stx->stx_last = lastdesc;
2819 htc->htc_desc[stx->stx_last].htx_ctl0 |= htole32(RTW_TXCTL0_LS);
2820 htc->htc_desc[stx->stx_first].htx_ctl0 |=
2821 htole32(RTW_TXCTL0_FS);
2822
2823 #ifdef RTW_DEBUG
2824 rtw_print_txdesc(sc, "FS on", stx, htc, stx->stx_first);
2825 rtw_print_txdesc(sc, "LS on", stx, htc, stx->stx_last);
2826 #endif /* RTW_DEBUG */
2827
2828 htc->htc_nfree -= dmamap->dm_nsegs;
2829 htc->htc_next = desc;
2830
2831 rtw_txdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap,
2832 htc, stx->stx_first, dmamap->dm_nsegs,
2833 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
2834
2835 htc->htc_desc[stx->stx_first].htx_ctl0 |=
2836 htole32(RTW_TXCTL0_OWN);
2837
2838 #ifdef RTW_DEBUG
2839 rtw_print_txdesc(sc, "OWN on", stx, htc, stx->stx_first);
2840 #endif /* RTW_DEBUG */
2841
2842 rtw_txdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap,
2843 htc, stx->stx_first, 1,
2844 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
2845
2846 SIMPLEQ_REMOVE_HEAD(&stc->stc_freeq, stx_q);
2847 SIMPLEQ_INSERT_TAIL(&stc->stc_dirtyq, stx, stx_q);
2848
2849 stc->stc_tx_timer = 5;
2850 ifp->if_timer = 1;
2851
2852 tppoll = RTW_READ8(&sc->sc_regs, RTW_TPPOLL);
2853
2854 /* TBD poke other queues. */
2855 RTW_WRITE8(&sc->sc_regs, RTW_TPPOLL, tppoll | RTW_TPPOLL_NPQ);
2856 RTW_SYNC(&sc->sc_regs, RTW_TPPOLL, RTW_TPPOLL);
2857 }
2858 out:
2859 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: leave\n", __func__));
2860 return;
2861 post_load_err:
2862 bus_dmamap_unload(sc->sc_dmat, dmamap);
2863 m_freem(m0);
2864 post_dequeue_err:
2865 ieee80211_release_node(&sc->sc_ic, ni);
2866 return;
2867 }
2868
2869 static void
2870 rtw_watchdog(struct ifnet *ifp)
2871 {
2872 int pri;
2873 struct rtw_softc *sc;
2874 struct rtw_txctl_blk *stc;
2875
2876 sc = ifp->if_softc;
2877
2878 ifp->if_timer = 0;
2879
2880 if ((sc->sc_flags & RTW_F_ENABLED) == 0)
2881 return;
2882
2883 for (pri = 0; pri < RTW_NTXPRI; pri++) {
2884 stc = &sc->sc_txctl_blk[pri];
2885
2886 if (stc->stc_tx_timer == 0)
2887 continue;
2888
2889 if (--stc->stc_tx_timer == 0) {
2890 if (SIMPLEQ_EMPTY(&stc->stc_dirtyq))
2891 continue;
2892 printf("%s: transmit timeout, priority %d\n",
2893 ifp->if_xname, pri);
2894 ifp->if_oerrors++;
2895 /* Stop Tx DMA, disable transmitter, clear
2896 * Tx rings, and restart.
2897 */
2898 RTW_WRITE8(&sc->sc_regs, RTW_TPPOLL, RTW_TPPOLL_SNPQ);
2899 RTW_SYNC(&sc->sc_regs, RTW_TPPOLL, RTW_TPPOLL);
2900 rtw_io_enable(&sc->sc_regs, RTW_CR_TE, 0);
2901 rtw_txdescs_reset(sc);
2902 rtw_io_enable(&sc->sc_regs, RTW_CR_TE, 1);
2903 rtw_start(ifp);
2904 } else
2905 ifp->if_timer = 1;
2906 }
2907 ieee80211_watchdog(ifp);
2908 return;
2909 }
2910
2911 static void
2912 rtw_start_beacon(struct rtw_softc *sc, int enable)
2913 {
2914 /* TBD */
2915 return;
2916 }
2917
2918 static void
2919 rtw_next_scan(void *arg)
2920 {
2921 struct ieee80211com *ic = arg;
2922 int s;
2923
2924 /* don't call rtw_start w/o network interrupts blocked */
2925 s = splnet();
2926 if (ic->ic_state == IEEE80211_S_SCAN)
2927 ieee80211_next_scan(ic);
2928 splx(s);
2929 }
2930
2931 static void
2932 rtw_join_bss(struct rtw_softc *sc, uint8_t *bssid, enum ieee80211_opmode opmode,
2933 uint16_t intval0)
2934 {
2935 uint16_t bcnitv, intval;
2936 int i;
2937 struct rtw_regs *regs = &sc->sc_regs;
2938
2939 for (i = 0; i < IEEE80211_ADDR_LEN; i++)
2940 RTW_WRITE8(regs, RTW_BSSID + i, bssid[i]);
2941
2942 RTW_SYNC(regs, RTW_BSSID16, RTW_BSSID32);
2943
2944 rtw_set_access(sc, RTW_ACCESS_CONFIG);
2945
2946 intval = MIN(intval0, PRESHIFT(RTW_BCNITV_BCNITV_MASK));
2947
2948 bcnitv = RTW_READ16(regs, RTW_BCNITV) & ~RTW_BCNITV_BCNITV_MASK;
2949 bcnitv |= LSHIFT(intval, RTW_BCNITV_BCNITV_MASK);
2950 RTW_WRITE16(regs, RTW_BCNITV, bcnitv);
2951 /* magic from Linux */
2952 RTW_WRITE16(regs, RTW_ATIMWND, LSHIFT(1, RTW_ATIMWND_ATIMWND));
2953 RTW_WRITE16(regs, RTW_ATIMTRITV, LSHIFT(2, RTW_ATIMTRITV_ATIMTRITV));
2954
2955 rtw_set_nettype(sc, opmode);
2956
2957 rtw_set_access(sc, RTW_ACCESS_NONE);
2958
2959 /* TBD WEP */
2960 RTW_WRITE8(regs, RTW_SCR, 0);
2961
2962 rtw_io_enable(regs, RTW_CR_RE | RTW_CR_TE, 1);
2963 }
2964
2965 /* Synchronize the hardware state with the software state. */
2966 static int
2967 rtw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
2968 {
2969 struct ifnet *ifp = &ic->ic_if;
2970 struct rtw_softc *sc = ifp->if_softc;
2971 enum ieee80211_state ostate;
2972 int error;
2973
2974 ostate = ic->ic_state;
2975
2976 if (nstate == IEEE80211_S_INIT) {
2977 callout_stop(&sc->sc_scan_ch);
2978 sc->sc_cur_chan = IEEE80211_CHAN_ANY;
2979 rtw_start_beacon(sc, 0);
2980 return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg);
2981 }
2982
2983 if (ostate == IEEE80211_S_INIT && nstate != IEEE80211_S_INIT)
2984 rtw_pwrstate(sc, RTW_ON);
2985
2986 if ((error = rtw_tune(sc)) != 0)
2987 return error;
2988
2989 switch (nstate) {
2990 case IEEE80211_S_ASSOC:
2991 rtw_join_bss(sc, ic->ic_bss->ni_bssid, ic->ic_opmode,
2992 ic->ic_bss->ni_intval);
2993 break;
2994 case IEEE80211_S_INIT:
2995 panic("%s: unexpected state IEEE80211_S_INIT\n", __func__);
2996 break;
2997 case IEEE80211_S_SCAN:
2998 if (ostate != IEEE80211_S_SCAN) {
2999 (void)memset(ic->ic_bss->ni_bssid, 0,
3000 IEEE80211_ADDR_LEN);
3001 rtw_join_bss(sc, ic->ic_bss->ni_bssid, ic->ic_opmode,
3002 ic->ic_bss->ni_intval);
3003 }
3004
3005 callout_reset(&sc->sc_scan_ch, rtw_dwelltime * hz / 1000,
3006 rtw_next_scan, ic);
3007
3008 break;
3009 case IEEE80211_S_RUN:
3010 if (ic->ic_opmode == IEEE80211_M_STA)
3011 break;
3012 /*FALLTHROUGH*/
3013 case IEEE80211_S_AUTH:
3014 #if 0
3015 rtw_write_bcn_thresh(sc);
3016 rtw_write_ssid(sc);
3017 rtw_write_sup_rates(sc);
3018 #endif
3019 if (ic->ic_opmode == IEEE80211_M_AHDEMO ||
3020 ic->ic_opmode == IEEE80211_M_MONITOR)
3021 break;
3022
3023 /* TBD set listen interval */
3024
3025 #if 0
3026 rtw_tsf(sc);
3027 #endif
3028 break;
3029 }
3030
3031 if (nstate != IEEE80211_S_SCAN)
3032 callout_stop(&sc->sc_scan_ch);
3033
3034 if (nstate == IEEE80211_S_RUN &&
3035 (ic->ic_opmode == IEEE80211_M_HOSTAP ||
3036 ic->ic_opmode == IEEE80211_M_IBSS))
3037 rtw_start_beacon(sc, 1);
3038 else
3039 rtw_start_beacon(sc, 0);
3040
3041 return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg);
3042 }
3043
3044 static void
3045 rtw_recv_beacon(struct rtw_softc *sc, struct mbuf *m,
3046 struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp)
3047 {
3048 (*sc->sc_mtbl.mt_recv_mgmt)(&sc->sc_ic, m, ni, subtype, rssi, rstamp);
3049 return;
3050 }
3051
3052 static void
3053 rtw_recv_mgmt(struct ieee80211com *ic, struct mbuf *m,
3054 struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp)
3055 {
3056 struct rtw_softc *sc = (struct rtw_softc*)ic->ic_softc;
3057
3058 switch (subtype) {
3059 case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
3060 /* do nothing: hardware answers probe request XXX */
3061 break;
3062 case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
3063 case IEEE80211_FC0_SUBTYPE_BEACON:
3064 rtw_recv_beacon(sc, m, ni, subtype, rssi, rstamp);
3065 break;
3066 default:
3067 (*sc->sc_mtbl.mt_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp);
3068 break;
3069 }
3070 return;
3071 }
3072
3073 static struct ieee80211_node *
3074 rtw_node_alloc(struct ieee80211com *ic)
3075 {
3076 struct rtw_softc *sc = (struct rtw_softc *)ic->ic_if.if_softc;
3077 struct ieee80211_node *ni = (*sc->sc_mtbl.mt_node_alloc)(ic);
3078
3079 DPRINTF(sc, RTW_DEBUG_NODE,
3080 ("%s: alloc node %p\n", sc->sc_dev.dv_xname, ni));
3081 return ni;
3082 }
3083
3084 static void
3085 rtw_node_free(struct ieee80211com *ic, struct ieee80211_node *ni)
3086 {
3087 struct rtw_softc *sc = (struct rtw_softc *)ic->ic_if.if_softc;
3088
3089 DPRINTF(sc, RTW_DEBUG_NODE,
3090 ("%s: freeing node %p %s\n", sc->sc_dev.dv_xname, ni,
3091 ether_sprintf(ni->ni_bssid)));
3092 (*sc->sc_mtbl.mt_node_free)(ic, ni);
3093 }
3094
3095 static int
3096 rtw_media_change(struct ifnet *ifp)
3097 {
3098 int error;
3099
3100 error = ieee80211_media_change(ifp);
3101 if (error == ENETRESET) {
3102 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
3103 (IFF_RUNNING|IFF_UP))
3104 rtw_init(ifp); /* XXX lose error */
3105 error = 0;
3106 }
3107 return error;
3108 }
3109
3110 static void
3111 rtw_media_status(struct ifnet *ifp, struct ifmediareq *imr)
3112 {
3113 struct rtw_softc *sc = ifp->if_softc;
3114
3115 if ((sc->sc_flags & RTW_F_ENABLED) == 0) {
3116 imr->ifm_active = IFM_IEEE80211 | IFM_NONE;
3117 imr->ifm_status = 0;
3118 return;
3119 }
3120 ieee80211_media_status(ifp, imr);
3121 }
3122
3123 void
3124 rtw_power(int why, void *arg)
3125 {
3126 struct rtw_softc *sc = arg;
3127 struct ifnet *ifp = &sc->sc_ic.ic_if;
3128 int s;
3129
3130 DPRINTF(sc, RTW_DEBUG_PWR,
3131 ("%s: rtw_power(%d,)\n", sc->sc_dev.dv_xname, why));
3132
3133 s = splnet();
3134 switch (why) {
3135 case PWR_STANDBY:
3136 /* XXX do nothing. */
3137 break;
3138 case PWR_SUSPEND:
3139 rtw_stop(ifp, 0);
3140 if (sc->sc_power != NULL)
3141 (*sc->sc_power)(sc, why);
3142 break;
3143 case PWR_RESUME:
3144 if (ifp->if_flags & IFF_UP) {
3145 if (sc->sc_power != NULL)
3146 (*sc->sc_power)(sc, why);
3147 rtw_init(ifp);
3148 }
3149 break;
3150 case PWR_SOFTSUSPEND:
3151 case PWR_SOFTSTANDBY:
3152 case PWR_SOFTRESUME:
3153 break;
3154 }
3155 splx(s);
3156 }
3157
3158 /* rtw_shutdown: make sure the interface is stopped at reboot time. */
3159 void
3160 rtw_shutdown(void *arg)
3161 {
3162 struct rtw_softc *sc = arg;
3163
3164 rtw_stop(&sc->sc_ic.ic_if, 1);
3165 }
3166
3167 static __inline void
3168 rtw_setifprops(struct ifnet *ifp, const char *dvname, void *softc)
3169 {
3170 (void)memcpy(ifp->if_xname, dvname, IFNAMSIZ);
3171 ifp->if_softc = softc;
3172 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST |
3173 IFF_NOTRAILERS;
3174 ifp->if_ioctl = rtw_ioctl;
3175 ifp->if_start = rtw_start;
3176 ifp->if_watchdog = rtw_watchdog;
3177 ifp->if_init = rtw_init;
3178 ifp->if_stop = rtw_stop;
3179 }
3180
3181 static __inline void
3182 rtw_set80211props(struct ieee80211com *ic)
3183 {
3184 int nrate;
3185 ic->ic_phytype = IEEE80211_T_DS;
3186 ic->ic_opmode = IEEE80211_M_STA;
3187 ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_IBSS |
3188 IEEE80211_C_HOSTAP | IEEE80211_C_MONITOR | IEEE80211_C_WEP;
3189
3190 nrate = 0;
3191 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] =
3192 IEEE80211_RATE_BASIC | 2;
3193 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] =
3194 IEEE80211_RATE_BASIC | 4;
3195 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 11;
3196 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 22;
3197 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = nrate;
3198 }
3199
3200 static __inline void
3201 rtw_set80211methods(struct rtw_mtbl *mtbl, struct ieee80211com *ic)
3202 {
3203 mtbl->mt_newstate = ic->ic_newstate;
3204 ic->ic_newstate = rtw_newstate;
3205
3206 mtbl->mt_recv_mgmt = ic->ic_recv_mgmt;
3207 ic->ic_recv_mgmt = rtw_recv_mgmt;
3208
3209 mtbl->mt_node_free = ic->ic_node_free;
3210 ic->ic_node_free = rtw_node_free;
3211
3212 mtbl->mt_node_alloc = ic->ic_node_alloc;
3213 ic->ic_node_alloc = rtw_node_alloc;
3214 }
3215
3216 static __inline void
3217 rtw_establish_hooks(struct rtw_hooks *hooks, const char *dvname,
3218 void *arg)
3219 {
3220 /*
3221 * Make sure the interface is shutdown during reboot.
3222 */
3223 hooks->rh_shutdown = shutdownhook_establish(rtw_shutdown, arg);
3224 if (hooks->rh_shutdown == NULL)
3225 printf("%s: WARNING: unable to establish shutdown hook\n",
3226 dvname);
3227
3228 /*
3229 * Add a suspend hook to make sure we come back up after a
3230 * resume.
3231 */
3232 hooks->rh_power = powerhook_establish(rtw_power, arg);
3233 if (hooks->rh_power == NULL)
3234 printf("%s: WARNING: unable to establish power hook\n",
3235 dvname);
3236 }
3237
3238 static __inline void
3239 rtw_disestablish_hooks(struct rtw_hooks *hooks, const char *dvname,
3240 void *arg)
3241 {
3242 if (hooks->rh_shutdown != NULL)
3243 shutdownhook_disestablish(hooks->rh_shutdown);
3244
3245 if (hooks->rh_power != NULL)
3246 powerhook_disestablish(hooks->rh_power);
3247 }
3248
3249 static __inline void
3250 rtw_init_radiotap(struct rtw_softc *sc)
3251 {
3252 memset(&sc->sc_rxtapu, 0, sizeof(sc->sc_rxtapu));
3253 sc->sc_rxtap.rr_ihdr.it_len = htole16(sizeof(sc->sc_rxtapu));
3254 sc->sc_rxtap.rr_ihdr.it_present = htole32(RTW_RX_RADIOTAP_PRESENT);
3255
3256 memset(&sc->sc_txtapu, 0, sizeof(sc->sc_txtapu));
3257 sc->sc_txtap.rt_ihdr.it_len = htole16(sizeof(sc->sc_txtapu));
3258 sc->sc_txtap.rt_ihdr.it_present = htole32(RTW_TX_RADIOTAP_PRESENT);
3259 }
3260
3261 static int
3262 rtw_txctl_blk_setup(struct rtw_txctl_blk *stc, u_int qlen)
3263 {
3264 SIMPLEQ_INIT(&stc->stc_dirtyq);
3265 SIMPLEQ_INIT(&stc->stc_freeq);
3266 stc->stc_ndesc = qlen;
3267 stc->stc_desc = malloc(qlen * sizeof(*stc->stc_desc), M_DEVBUF,
3268 M_NOWAIT);
3269 if (stc->stc_desc == NULL)
3270 return ENOMEM;
3271 return 0;
3272 }
3273
3274 static void
3275 rtw_txctl_blk_cleanup_all(struct rtw_softc *sc)
3276 {
3277 int pri;
3278 struct rtw_txctl_blk *stc;
3279
3280 for (pri = 0; pri < RTW_NTXPRI; pri++) {
3281 stc = &sc->sc_txctl_blk[pri];
3282 free(stc->stc_desc, M_DEVBUF);
3283 stc->stc_desc = NULL;
3284 }
3285 }
3286
3287 static int
3288 rtw_txctl_blk_setup_all(struct rtw_softc *sc)
3289 {
3290 int pri, rc = 0;
3291 int qlen[RTW_NTXPRI] =
3292 {RTW_TXQLENLO, RTW_TXQLENMD, RTW_TXQLENHI, RTW_TXQLENBCN};
3293
3294 for (pri = 0; pri < RTW_NTXPRI; pri++) {
3295 rc = rtw_txctl_blk_setup(&sc->sc_txctl_blk[pri], qlen[pri]);
3296 if (rc != 0)
3297 break;
3298 }
3299 return rc;
3300 }
3301
3302 static void
3303 rtw_txdesc_blk_setup(struct rtw_txdesc_blk *htc, struct rtw_txdesc *desc,
3304 u_int ndesc, bus_addr_t ofs, bus_addr_t physbase)
3305 {
3306 htc->htc_ndesc = ndesc;
3307 htc->htc_desc = desc;
3308 htc->htc_physbase = physbase;
3309 htc->htc_ofs = ofs;
3310
3311 (void)memset(htc->htc_desc, 0,
3312 sizeof(htc->htc_desc[0]) * htc->htc_ndesc);
3313
3314 rtw_txdesc_blk_reset(htc);
3315 }
3316
3317 static void
3318 rtw_txdesc_blk_setup_all(struct rtw_softc *sc)
3319 {
3320 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRILO],
3321 &sc->sc_descs->hd_txlo[0], RTW_NTXDESCLO,
3322 RTW_RING_OFFSET(hd_txlo), RTW_RING_BASE(sc, hd_txlo));
3323
3324 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIMD],
3325 &sc->sc_descs->hd_txmd[0], RTW_NTXDESCMD,
3326 RTW_RING_OFFSET(hd_txmd), RTW_RING_BASE(sc, hd_txmd));
3327
3328 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIHI],
3329 &sc->sc_descs->hd_txhi[0], RTW_NTXDESCHI,
3330 RTW_RING_OFFSET(hd_txhi), RTW_RING_BASE(sc, hd_txhi));
3331
3332 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIBCN],
3333 &sc->sc_descs->hd_bcn[0], RTW_NTXDESCBCN,
3334 RTW_RING_OFFSET(hd_bcn), RTW_RING_BASE(sc, hd_bcn));
3335 }
3336
3337 static struct rtw_rf *
3338 rtw_rf_attach(struct rtw_softc *sc, enum rtw_rfchipid rfchipid,
3339 rtw_rf_write_t rf_write, int digphy)
3340 {
3341 struct rtw_rf *rf;
3342
3343 switch (rfchipid) {
3344 case RTW_RFCHIPID_MAXIM:
3345 rf = rtw_max2820_create(&sc->sc_regs, rf_write, 0);
3346 sc->sc_pwrstate_cb = rtw_maxim_pwrstate;
3347 break;
3348 case RTW_RFCHIPID_PHILIPS:
3349 rf = rtw_sa2400_create(&sc->sc_regs, rf_write, digphy);
3350 sc->sc_pwrstate_cb = rtw_philips_pwrstate;
3351 break;
3352 case RTW_RFCHIPID_RFMD:
3353 /* XXX RFMD has no RF constructor */
3354 sc->sc_pwrstate_cb = rtw_rfmd_pwrstate;
3355 /*FALLTHROUGH*/
3356 default:
3357 return NULL;
3358 }
3359 rf->rf_continuous_tx_cb =
3360 (rtw_continuous_tx_cb_t)rtw_continuous_tx_enable;
3361 rf->rf_continuous_tx_arg = (void *)sc;
3362 return rf;
3363 }
3364
3365 /* Revision C and later use a different PHY delay setting than
3366 * revisions A and B.
3367 */
3368 static u_int8_t
3369 rtw_check_phydelay(struct rtw_regs *regs, u_int32_t rcr0)
3370 {
3371 #define REVAB (RTW_RCR_MXDMA_UNLIMITED | RTW_RCR_AICV)
3372 #define REVC (REVAB | RTW_RCR_RXFTH_WHOLE)
3373
3374 u_int8_t phydelay = LSHIFT(0x6, RTW_PHYDELAY_PHYDELAY);
3375
3376 RTW_WRITE(regs, RTW_RCR, REVAB);
3377 RTW_WBW(regs, RTW_RCR, RTW_RCR);
3378 RTW_WRITE(regs, RTW_RCR, REVC);
3379
3380 RTW_WBR(regs, RTW_RCR, RTW_RCR);
3381 if ((RTW_READ(regs, RTW_RCR) & REVC) == REVC)
3382 phydelay |= RTW_PHYDELAY_REVC_MAGIC;
3383
3384 RTW_WRITE(regs, RTW_RCR, rcr0); /* restore RCR */
3385 RTW_SYNC(regs, RTW_RCR, RTW_RCR);
3386
3387 return phydelay;
3388 #undef REVC
3389 }
3390
3391 void
3392 rtw_attach(struct rtw_softc *sc)
3393 {
3394 rtw_rf_write_t rf_write;
3395 struct rtw_txctl_blk *stc;
3396 int pri, rc, vers;
3397
3398 #if 0
3399 CASSERT(RTW_DESC_ALIGNMENT % sizeof(struct rtw_txdesc) == 0,
3400 "RTW_DESC_ALIGNMENT is not a multiple of "
3401 "sizeof(struct rtw_txdesc)");
3402
3403 CASSERT(RTW_DESC_ALIGNMENT % sizeof(struct rtw_rxdesc) == 0,
3404 "RTW_DESC_ALIGNMENT is not a multiple of "
3405 "sizeof(struct rtw_rxdesc)");
3406
3407 CASSERT(RTW_DESC_ALIGNMENT % RTW_MAXPKTSEGS == 0,
3408 "RTW_DESC_ALIGNMENT is not a multiple of RTW_MAXPKTSEGS");
3409 #endif
3410
3411 NEXT_ATTACH_STATE(sc, DETACHED);
3412
3413 switch (RTW_READ(&sc->sc_regs, RTW_TCR) & RTW_TCR_HWVERID_MASK) {
3414 case RTW_TCR_HWVERID_F:
3415 vers = 'F';
3416 rf_write = rtw_rf_hostwrite;
3417 break;
3418 case RTW_TCR_HWVERID_D:
3419 vers = 'D';
3420 if (rtw_host_rfio)
3421 rf_write = rtw_rf_hostwrite;
3422 else
3423 rf_write = rtw_rf_macwrite;
3424 break;
3425 default:
3426 vers = '?';
3427 rf_write = rtw_rf_macwrite;
3428 break;
3429 }
3430 printf("%s: hardware version %c\n", sc->sc_dev.dv_xname, vers);
3431
3432 rc = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct rtw_descs),
3433 RTW_DESC_ALIGNMENT, 0, &sc->sc_desc_segs, 1, &sc->sc_desc_nsegs,
3434 0);
3435
3436 if (rc != 0) {
3437 printf("%s: could not allocate hw descriptors, error %d\n",
3438 sc->sc_dev.dv_xname, rc);
3439 goto err;
3440 }
3441
3442 NEXT_ATTACH_STATE(sc, FINISH_DESC_ALLOC);
3443
3444 rc = bus_dmamem_map(sc->sc_dmat, &sc->sc_desc_segs,
3445 sc->sc_desc_nsegs, sizeof(struct rtw_descs),
3446 (caddr_t*)&sc->sc_descs, BUS_DMA_COHERENT);
3447
3448 if (rc != 0) {
3449 printf("%s: could not map hw descriptors, error %d\n",
3450 sc->sc_dev.dv_xname, rc);
3451 goto err;
3452 }
3453 NEXT_ATTACH_STATE(sc, FINISH_DESC_MAP);
3454
3455 rc = bus_dmamap_create(sc->sc_dmat, sizeof(struct rtw_descs), 1,
3456 sizeof(struct rtw_descs), 0, 0, &sc->sc_desc_dmamap);
3457
3458 if (rc != 0) {
3459 printf("%s: could not create DMA map for hw descriptors, "
3460 "error %d\n", sc->sc_dev.dv_xname, rc);
3461 goto err;
3462 }
3463 NEXT_ATTACH_STATE(sc, FINISH_DESCMAP_CREATE);
3464
3465 rc = bus_dmamap_load(sc->sc_dmat, sc->sc_desc_dmamap, sc->sc_descs,
3466 sizeof(struct rtw_descs), NULL, 0);
3467
3468 if (rc != 0) {
3469 printf("%s: could not load DMA map for hw descriptors, "
3470 "error %d\n", sc->sc_dev.dv_xname, rc);
3471 goto err;
3472 }
3473 NEXT_ATTACH_STATE(sc, FINISH_DESCMAP_LOAD);
3474
3475 if (rtw_txctl_blk_setup_all(sc) != 0)
3476 goto err;
3477 NEXT_ATTACH_STATE(sc, FINISH_TXCTLBLK_SETUP);
3478
3479 rtw_txdesc_blk_setup_all(sc);
3480
3481 NEXT_ATTACH_STATE(sc, FINISH_TXDESCBLK_SETUP);
3482
3483 sc->sc_rxdesc = &sc->sc_descs->hd_rx[0];
3484
3485 for (pri = 0; pri < RTW_NTXPRI; pri++) {
3486 stc = &sc->sc_txctl_blk[pri];
3487
3488 if ((rc = rtw_txdesc_dmamaps_create(sc->sc_dmat,
3489 &stc->stc_desc[0], stc->stc_ndesc)) != 0) {
3490 printf("%s: could not load DMA map for "
3491 "hw tx descriptors, error %d\n",
3492 sc->sc_dev.dv_xname, rc);
3493 goto err;
3494 }
3495 }
3496
3497 NEXT_ATTACH_STATE(sc, FINISH_TXMAPS_CREATE);
3498 if ((rc = rtw_rxdesc_dmamaps_create(sc->sc_dmat, &sc->sc_rxctl[0],
3499 RTW_RXQLEN)) != 0) {
3500 printf("%s: could not load DMA map for hw rx descriptors, "
3501 "error %d\n", sc->sc_dev.dv_xname, rc);
3502 goto err;
3503 }
3504 NEXT_ATTACH_STATE(sc, FINISH_RXMAPS_CREATE);
3505
3506 /* Reset the chip to a known state. */
3507 if (rtw_reset(sc) != 0)
3508 goto err;
3509 NEXT_ATTACH_STATE(sc, FINISH_RESET);
3510
3511 sc->sc_rcr = RTW_READ(&sc->sc_regs, RTW_RCR);
3512
3513 if ((sc->sc_rcr & RTW_RCR_9356SEL) != 0)
3514 sc->sc_flags |= RTW_F_9356SROM;
3515
3516 if (rtw_srom_read(&sc->sc_regs, sc->sc_flags, &sc->sc_srom,
3517 sc->sc_dev.dv_xname) != 0)
3518 goto err;
3519
3520 NEXT_ATTACH_STATE(sc, FINISH_READ_SROM);
3521
3522 if (rtw_srom_parse(&sc->sc_srom, &sc->sc_flags, &sc->sc_csthr,
3523 &sc->sc_rfchipid, &sc->sc_rcr, &sc->sc_locale,
3524 sc->sc_dev.dv_xname) != 0) {
3525 printf("%s: attach failed, malformed serial ROM\n",
3526 sc->sc_dev.dv_xname);
3527 goto err;
3528 }
3529
3530 printf("%s: %s PHY\n", sc->sc_dev.dv_xname,
3531 ((sc->sc_flags & RTW_F_DIGPHY) != 0) ? "digital" : "analog");
3532
3533 printf("%s: CS threshold %u\n", sc->sc_dev.dv_xname, sc->sc_csthr);
3534
3535 NEXT_ATTACH_STATE(sc, FINISH_PARSE_SROM);
3536
3537 sc->sc_rf = rtw_rf_attach(sc, sc->sc_rfchipid, rf_write,
3538 sc->sc_flags & RTW_F_DIGPHY);
3539
3540 if (sc->sc_rf == NULL) {
3541 printf("%s: attach failed, could not attach RF\n",
3542 sc->sc_dev.dv_xname);
3543 goto err;
3544 }
3545
3546 #if 0
3547 if (rtw_identify_rf(&sc->sc_regs, &sc->sc_rftype,
3548 sc->sc_dev.dv_xname) != 0) {
3549 printf("%s: attach failed, unknown RF unidentified\n",
3550 sc->sc_dev.dv_xname);
3551 goto err;
3552 }
3553 #endif
3554
3555 NEXT_ATTACH_STATE(sc, FINISH_RF_ATTACH);
3556
3557 sc->sc_phydelay = rtw_check_phydelay(&sc->sc_regs, sc->sc_rcr);
3558
3559 RTW_DPRINTF(RTW_DEBUG_ATTACH,
3560 ("%s: PHY delay %d\n", sc->sc_dev.dv_xname, sc->sc_phydelay));
3561
3562 if (sc->sc_locale == RTW_LOCALE_UNKNOWN)
3563 rtw_identify_country(&sc->sc_regs, &sc->sc_locale,
3564 sc->sc_dev.dv_xname);
3565
3566 rtw_init_channels(sc->sc_locale, &sc->sc_ic.ic_channels,
3567 sc->sc_dev.dv_xname);
3568
3569 if (rtw_identify_sta(&sc->sc_regs, &sc->sc_ic.ic_myaddr,
3570 sc->sc_dev.dv_xname) != 0)
3571 goto err;
3572 NEXT_ATTACH_STATE(sc, FINISH_ID_STA);
3573
3574 rtw_setifprops(&sc->sc_if, sc->sc_dev.dv_xname, (void*)sc);
3575
3576 IFQ_SET_READY(&sc->sc_if.if_snd);
3577
3578 rtw_set80211props(&sc->sc_ic);
3579
3580 /*
3581 * Call MI attach routines.
3582 */
3583 if_attach(&sc->sc_if);
3584 ieee80211_ifattach(&sc->sc_if);
3585
3586 rtw_set80211methods(&sc->sc_mtbl, &sc->sc_ic);
3587
3588 /* possibly we should fill in our own sc_send_prresp, since
3589 * the RTL8180 is probably sending probe responses in ad hoc
3590 * mode.
3591 */
3592
3593 /* complete initialization */
3594 ieee80211_media_init(&sc->sc_if, rtw_media_change, rtw_media_status);
3595 callout_init(&sc->sc_scan_ch);
3596
3597 rtw_init_radiotap(sc);
3598
3599 #if NBPFILTER > 0
3600 bpfattach2(&sc->sc_if, DLT_IEEE802_11_RADIO,
3601 sizeof(struct ieee80211_frame) + 64, &sc->sc_radiobpf);
3602 #endif
3603
3604 rtw_establish_hooks(&sc->sc_hooks, sc->sc_dev.dv_xname, (void*)sc);
3605
3606 NEXT_ATTACH_STATE(sc, FINISHED);
3607
3608 return;
3609 err:
3610 rtw_detach(sc);
3611 return;
3612 }
3613
3614 int
3615 rtw_detach(struct rtw_softc *sc)
3616 {
3617 int pri;
3618
3619 switch (sc->sc_attach_state) {
3620 case FINISHED:
3621 rtw_stop(&sc->sc_if, 1);
3622
3623 rtw_disestablish_hooks(&sc->sc_hooks, sc->sc_dev.dv_xname,
3624 (void*)sc);
3625 callout_stop(&sc->sc_scan_ch);
3626 ieee80211_ifdetach(&sc->sc_if);
3627 if_detach(&sc->sc_if);
3628 break;
3629 case FINISH_ID_STA:
3630 case FINISH_RF_ATTACH:
3631 rtw_rf_destroy(sc->sc_rf);
3632 sc->sc_rf = NULL;
3633 /*FALLTHROUGH*/
3634 case FINISH_PARSE_SROM:
3635 case FINISH_READ_SROM:
3636 rtw_srom_free(&sc->sc_srom);
3637 /*FALLTHROUGH*/
3638 case FINISH_RESET:
3639 case FINISH_RXMAPS_CREATE:
3640 rtw_rxdesc_dmamaps_destroy(sc->sc_dmat, &sc->sc_rxctl[0],
3641 RTW_RXQLEN);
3642 /*FALLTHROUGH*/
3643 case FINISH_TXMAPS_CREATE:
3644 for (pri = 0; pri < RTW_NTXPRI; pri++) {
3645 rtw_txdesc_dmamaps_destroy(sc->sc_dmat,
3646 sc->sc_txctl_blk[pri].stc_desc,
3647 sc->sc_txctl_blk[pri].stc_ndesc);
3648 }
3649 /*FALLTHROUGH*/
3650 case FINISH_TXDESCBLK_SETUP:
3651 case FINISH_TXCTLBLK_SETUP:
3652 rtw_txctl_blk_cleanup_all(sc);
3653 /*FALLTHROUGH*/
3654 case FINISH_DESCMAP_LOAD:
3655 bus_dmamap_unload(sc->sc_dmat, sc->sc_desc_dmamap);
3656 /*FALLTHROUGH*/
3657 case FINISH_DESCMAP_CREATE:
3658 bus_dmamap_destroy(sc->sc_dmat, sc->sc_desc_dmamap);
3659 /*FALLTHROUGH*/
3660 case FINISH_DESC_MAP:
3661 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_descs,
3662 sizeof(struct rtw_descs));
3663 /*FALLTHROUGH*/
3664 case FINISH_DESC_ALLOC:
3665 bus_dmamem_free(sc->sc_dmat, &sc->sc_desc_segs,
3666 sc->sc_desc_nsegs);
3667 /*FALLTHROUGH*/
3668 case DETACHED:
3669 NEXT_ATTACH_STATE(sc, DETACHED);
3670 break;
3671 }
3672 return 0;
3673 }
3674
3675 int
3676 rtw_activate(struct device *self, enum devact act)
3677 {
3678 struct rtw_softc *sc = (struct rtw_softc *)self;
3679 int rc = 0, s;
3680
3681 s = splnet();
3682 switch (act) {
3683 case DVACT_ACTIVATE:
3684 rc = EOPNOTSUPP;
3685 break;
3686
3687 case DVACT_DEACTIVATE:
3688 if_deactivate(&sc->sc_ic.ic_if);
3689 break;
3690 }
3691 splx(s);
3692 return rc;
3693 }
3694