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