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