This source file includes following definitions.
- atw_activate
- atw_enable
- atw_disable
- atw_read_srom
- atw_print_regs
- atw_printmac
- atw_attach
- atw_node_alloc
- atw_node_free
- atw_test1_reset
- atw_reset
- atw_clear_sram
- atw_wcsr_init
- atw_cmdr_init
- atw_tofs2_init
- atw_nar_init
- atw_txlmt_init
- atw_test1_init
- atw_rf_reset
- atw_cfp_init
- atw_tofs0_init
- atw_ifs_init
- atw_response_times_init
- atw_bbp_io_init
- atw_si4126_init
- atw_init
- atw_bbp_io_enable
- atw_tune
- atw_si4126_print
- atw_si4126_tune
- atw_rf3000_init
- atw_rf3000_print
- atw_rf3000_tune
- atw_rf3000_write
- atw_rf3000_read
- atw_si4126_write
- atw_si4126_read
- atw_filter_setup
- atw_write_bssid
- atw_write_sram
- atw_write_wep
- atw_change_ibss
- atw_recv_mgmt
- atw_write_ssid
- atw_write_sup_rates
- atw_start_beacon
- atw_last_even_tsft
- atw_get_tsft
- atw_predict_beacon
- atw_next_scan
- atw_newstate
- atw_add_rxbuf
- atw_txdrain
- atw_stop
- atw_rxdrain
- atw_detach
- atw_shutdown
- atw_intr
- atw_idle
- atw_linkintr
- atw_hw_decrypted
- atw_rxintr
- atw_txintr
- atw_watchdog
- atw_compute_duration1
- atw_compute_duration
- atw_dump_pkt
- atw_start
- atw_power
- atw_ioctl
- atw_media_change
- atw_media_status
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 #include <sys/cdefs.h>
45 #if defined(__NetBSD__)
46 __KERNEL_RCSID(0, "$NetBSD: atw.c,v 1.69 2004/07/23 07:07:55 dyoung Exp $");
47 #endif
48
49 #include "bpfilter.h"
50
51 #include <sys/param.h>
52 #include <sys/systm.h>
53 #include <sys/mbuf.h>
54 #include <sys/malloc.h>
55 #include <sys/kernel.h>
56 #include <sys/socket.h>
57 #include <sys/ioctl.h>
58 #include <sys/errno.h>
59 #include <sys/device.h>
60 #include <sys/time.h>
61
62 #include <machine/endian.h>
63
64 #include <uvm/uvm_extern.h>
65
66 #include <net/if.h>
67 #include <net/if_dl.h>
68 #include <net/if_media.h>
69
70 #if NBPFILTER > 0
71 #include <net/bpf.h>
72 #endif
73
74 #ifdef INET
75 #include <netinet/in.h>
76 #include <netinet/if_ether.h>
77 #endif
78
79 #include <net80211/ieee80211_var.h>
80 #include <net80211/ieee80211_radiotap.h>
81
82 #include <machine/bus.h>
83 #include <machine/intr.h>
84
85 #include <dev/ic/atwreg.h>
86 #include <dev/ic/rf3000reg.h>
87 #include <dev/ic/si4136reg.h>
88 #include <dev/ic/atwvar.h>
89 #include <dev/ic/smc93cx6var.h>
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143 #define ATW_REFSLAVE
144
145 int atw_bbp_io_enable_delay = 20 * 1000;
146 int atw_bbp_io_disable_delay = 2 * 1000;
147 int atw_writewep_delay = 1000;
148 int atw_beacon_len_adjust = 4;
149 int atw_dwelltime = 200;
150 int atw_xindiv2 = 0;
151
152 #ifdef ATW_DEBUG
153 int atw_debug = 0;
154
155 #define ATW_DPRINTF(x) if (atw_debug > 0) printf x
156 #define ATW_DPRINTF2(x) if (atw_debug > 1) printf x
157 #define ATW_DPRINTF3(x) if (atw_debug > 2) printf x
158 #define DPRINTF(sc, x) if ((sc)->sc_ic.ic_if.if_flags & IFF_DEBUG) printf x
159 #define DPRINTF2(sc, x) if ((sc)->sc_ic.ic_if.if_flags & IFF_DEBUG) ATW_DPRINTF2(x)
160 #define DPRINTF3(sc, x) if ((sc)->sc_ic.ic_if.if_flags & IFF_DEBUG) ATW_DPRINTF3(x)
161 void atw_print_regs(struct atw_softc *, const char *);
162 void atw_dump_pkt(struct ifnet *, struct mbuf *);
163
164
165 # ifdef ATW_BBPDEBUG
166 int atw_rf3000_read(struct atw_softc *sc, u_int, u_int *);
167 void atw_rf3000_print(struct atw_softc *);
168 # endif
169
170 # ifdef ATW_SYNDEBUG
171 int atw_si4126_read(struct atw_softc *, u_int, u_int *);
172 void atw_si4126_print(struct atw_softc *);
173 # endif
174
175 #else
176 #define ATW_DPRINTF(x)
177 #define ATW_DPRINTF2(x)
178 #define ATW_DPRINTF3(x)
179 #define DPRINTF(sc, x)
180 #define DPRINTF2(sc, x)
181 #define DPRINTF3(sc, x)
182 #endif
183
184 #ifdef ATW_STATS
185 void atw_print_stats(struct atw_softc *);
186 #endif
187
188 const char *atw_printmac(u_int8_t);
189
190
191 void atw_start(struct ifnet *);
192 void atw_watchdog(struct ifnet *);
193 int atw_ioctl(struct ifnet *, u_long, caddr_t);
194 int atw_init(struct ifnet *);
195 void atw_stop(struct ifnet *, int);
196
197
198 void atw_rxdrain(struct atw_softc *);
199 void atw_txdrain(struct atw_softc *);
200 int atw_add_rxbuf(struct atw_softc *, int);
201 void atw_idle(struct atw_softc *, u_int32_t);
202
203
204 void atw_disable(struct atw_softc *);
205 void atw_reset(struct atw_softc *);
206
207
208 void atw_rxintr(struct atw_softc *);
209 void atw_txintr(struct atw_softc *);
210 void atw_linkintr(struct atw_softc *, u_int32_t);
211
212
213 int atw_newstate(struct ieee80211com *, enum ieee80211_state, int);
214 int atw_tune(struct atw_softc *);
215 void atw_recv_mgmt(struct ieee80211com *, struct mbuf *,
216 struct ieee80211_node *, int, int, u_int32_t);
217 void atw_next_scan(void *);
218
219
220 void atw_wcsr_init(struct atw_softc *);
221 void atw_cmdr_init(struct atw_softc *);
222 void atw_tofs2_init(struct atw_softc *);
223 void atw_txlmt_init(struct atw_softc *);
224 void atw_test1_init(struct atw_softc *);
225 void atw_rf_reset(struct atw_softc *);
226 void atw_cfp_init(struct atw_softc *);
227 void atw_tofs0_init(struct atw_softc *);
228 void atw_ifs_init(struct atw_softc *);
229 void atw_response_times_init(struct atw_softc *);
230 void atw_bbp_io_init(struct atw_softc *);
231 void atw_nar_init(struct atw_softc *);
232
233
234 void atw_clear_sram(struct atw_softc *);
235 void atw_write_sram(struct atw_softc *, u_int, u_int8_t *, u_int);
236 int atw_read_srom(struct atw_softc *);
237
238
239 void atw_predict_beacon(struct atw_softc *sc);
240 void atw_start_beacon(struct atw_softc *, int);
241 void atw_write_bssid(struct atw_softc *);
242 void atw_write_ssid(struct atw_softc *);
243 void atw_write_sup_rates(struct atw_softc *);
244 void atw_write_wep(struct atw_softc *);
245
246
247 int atw_media_change(struct ifnet *);
248 void atw_media_status(struct ifnet *, struct ifmediareq *);
249
250 void atw_filter_setup(struct atw_softc *);
251
252
253 struct ieee80211_node *atw_node_alloc(struct ieee80211com *);
254 void atw_node_free(struct ieee80211com *, struct ieee80211_node *);
255 static __inline uint32_t atw_last_even_tsft(uint32_t, uint32_t, uint32_t);
256 uint64_t atw_get_tsft(struct atw_softc *sc);
257 void atw_change_ibss(struct atw_softc *);
258 int atw_compute_duration1(int, int, uint32_t, int, struct atw_duration *);
259 int atw_compute_duration(struct ieee80211_frame *, int, uint32_t, int,
260 int, struct atw_duration *, struct atw_duration *, int *, int);
261
262
263
264
265 void atw_bbp_io_enable(struct atw_softc *, int);
266
267
268 int atw_rf3000_init(struct atw_softc *);
269 int atw_rf3000_tune(struct atw_softc *, u_int);
270 int atw_rf3000_write(struct atw_softc *, u_int, u_int);
271
272
273 void atw_si4126_tune(struct atw_softc *, u_int);
274 void atw_si4126_write(struct atw_softc *, u_int, u_int);
275 void atw_si4126_init(struct atw_softc *);
276
277 const struct atw_txthresh_tab atw_txthresh_tab_lo[] = ATW_TXTHRESH_TAB_LO_RATE;
278 const struct atw_txthresh_tab atw_txthresh_tab_hi[] = ATW_TXTHRESH_TAB_HI_RATE;
279
280 struct cfdriver atw_cd = {
281 NULL, "atw", DV_IFNET
282 };
283
284 static const u_int atw_rfmd2958_ifn[] = {
285 0x22bd, 0x22d2, 0x22e8, 0x22fe, 0x2314, 0x232a, 0x2340,
286 0x2355, 0x236b, 0x2381, 0x2397, 0x23ad, 0x23c2, 0x23f7
287 };
288
289 static const u_int atw_rfmd2958_rf1r[] = {
290 0x05d17, 0x3a2e8, 0x2e8ba, 0x22e8b, 0x1745d, 0x0ba2e, 0x00000,
291 0x345d1, 0x28ba2, 0x1d174, 0x11745, 0x05d17, 0x3a2e8, 0x11745
292 };
293
294
295 #ifdef ATW_DEBUG
296
297 const char *atw_tx_state[] = {
298 "STOPPED",
299 "RUNNING - read descriptor",
300 "RUNNING - transmitting",
301 "RUNNING - filling fifo",
302 "SUSPENDED",
303 "RUNNING -- write descriptor",
304 "RUNNING -- write last descriptor",
305 "RUNNING - fifo full"
306 };
307
308 const char *atw_rx_state[] = {
309 "STOPPED",
310 "RUNNING - read descriptor",
311 "RUNNING - check this packet, pre-fetch next",
312 "RUNNING - wait for reception",
313 "SUSPENDED",
314 "RUNNING - write descriptor",
315 "RUNNING - flush fifo",
316 "RUNNING - fifo drain"
317 };
318
319 #endif
320
321 #ifndef __OpenBSD__
322 int
323 atw_activate(struct device *self, enum devact act)
324 {
325 struct atw_softc *sc = (struct atw_softc *)self;
326 int rv = 0, s;
327
328 s = splnet();
329 switch (act) {
330 case DVACT_ACTIVATE:
331 break;
332
333 case DVACT_DEACTIVATE:
334 if_deactivate(&sc->sc_ic.ic_if);
335 break;
336 }
337 splx(s);
338 return rv;
339 }
340 #endif
341
342
343
344
345
346
347 int
348 atw_enable(struct atw_softc *sc)
349 {
350
351 if (ATW_IS_ENABLED(sc) == 0) {
352 if (sc->sc_enable != NULL && (*sc->sc_enable)(sc) != 0) {
353 printf("%s: device enable failed\n",
354 sc->sc_dev.dv_xname);
355 return (EIO);
356 }
357 sc->sc_flags |= ATWF_ENABLED;
358 }
359 return (0);
360 }
361
362
363
364
365
366
367 void
368 atw_disable(struct atw_softc *sc)
369 {
370 if (!ATW_IS_ENABLED(sc))
371 return;
372 if (sc->sc_disable != NULL)
373 (*sc->sc_disable)(sc);
374 sc->sc_flags &= ~ATWF_ENABLED;
375 }
376
377
378 int
379 atw_read_srom(struct atw_softc *sc)
380 {
381 struct seeprom_descriptor sd;
382 u_int32_t test0, fail_bits;
383
384 (void)memset(&sd, 0, sizeof(sd));
385
386 test0 = ATW_READ(sc, ATW_TEST0);
387
388 switch (sc->sc_rev) {
389 case ATW_REVISION_BA:
390 case ATW_REVISION_CA:
391 fail_bits = ATW_TEST0_EPNE;
392 break;
393 default:
394 fail_bits = ATW_TEST0_EPNE|ATW_TEST0_EPSNM;
395 break;
396 }
397 if ((test0 & fail_bits) != 0) {
398 printf("%s: bad or missing/bad SROM\n", sc->sc_dev.dv_xname);
399 return -1;
400 }
401
402 switch (test0 & ATW_TEST0_EPTYP_MASK) {
403 case ATW_TEST0_EPTYP_93c66:
404 ATW_DPRINTF(("%s: 93c66 SROM\n", sc->sc_dev.dv_xname));
405 sc->sc_sromsz = 512;
406 sd.sd_chip = C56_66;
407 break;
408 case ATW_TEST0_EPTYP_93c46:
409 ATW_DPRINTF(("%s: 93c46 SROM\n", sc->sc_dev.dv_xname));
410 sc->sc_sromsz = 128;
411 sd.sd_chip = C46;
412 break;
413 default:
414 printf("%s: unknown SROM type %d\n", sc->sc_dev.dv_xname,
415 MASK_AND_RSHIFT(test0, ATW_TEST0_EPTYP_MASK));
416 return -1;
417 }
418
419 sc->sc_srom = malloc(sc->sc_sromsz, M_DEVBUF, M_NOWAIT);
420 if (sc->sc_srom == NULL) {
421 printf("%s: unable to allocate SROM buffer\n",
422 sc->sc_dev.dv_xname);
423 return -1;
424 }
425
426 (void)memset(sc->sc_srom, 0, sc->sc_sromsz);
427
428
429
430
431
432 sd.sd_tag = sc->sc_st;
433 sd.sd_bsh = sc->sc_sh;
434 sd.sd_regsize = 4;
435 sd.sd_control_offset = ATW_SPR;
436 sd.sd_status_offset = ATW_SPR;
437 sd.sd_dataout_offset = ATW_SPR;
438 sd.sd_CK = ATW_SPR_SCLK;
439 sd.sd_CS = ATW_SPR_SCS;
440 sd.sd_DI = ATW_SPR_SDO;
441 sd.sd_DO = ATW_SPR_SDI;
442 sd.sd_MS = ATW_SPR_SRS;
443 sd.sd_RDY = 0;
444
445 if (!read_seeprom(&sd, sc->sc_srom, 0, sc->sc_sromsz/2)) {
446 printf("%s: could not read SROM\n", sc->sc_dev.dv_xname);
447 free(sc->sc_srom, M_DEVBUF);
448 return -1;
449 }
450 #ifdef ATW_DEBUG
451 {
452 int i;
453 ATW_DPRINTF(("\nSerial EEPROM:\n\t"));
454 for (i = 0; i < sc->sc_sromsz/2; i = i + 1) {
455 if (((i % 8) == 0) && (i != 0)) {
456 ATW_DPRINTF(("\n\t"));
457 }
458 ATW_DPRINTF((" 0x%x", sc->sc_srom[i]));
459 }
460 ATW_DPRINTF(("\n"));
461 }
462 #endif
463 return 0;
464 }
465
466 #ifdef ATW_DEBUG
467 void
468 atw_print_regs(struct atw_softc *sc, const char *where)
469 {
470 #define PRINTREG(sc, reg) \
471 ATW_DPRINTF2(("%s: reg[ " #reg " / %03x ] = %08x\n", \
472 sc->sc_dev.dv_xname, reg, ATW_READ(sc, reg)))
473
474 ATW_DPRINTF2(("%s: %s\n", sc->sc_dev.dv_xname, where));
475
476 PRINTREG(sc, ATW_PAR);
477 PRINTREG(sc, ATW_FRCTL);
478 PRINTREG(sc, ATW_TDR);
479 PRINTREG(sc, ATW_WTDP);
480 PRINTREG(sc, ATW_RDR);
481 PRINTREG(sc, ATW_WRDP);
482 PRINTREG(sc, ATW_RDB);
483 PRINTREG(sc, ATW_CSR3A);
484 PRINTREG(sc, ATW_TDBD);
485 PRINTREG(sc, ATW_TDBP);
486 PRINTREG(sc, ATW_STSR);
487 PRINTREG(sc, ATW_CSR5A);
488 PRINTREG(sc, ATW_NAR);
489 PRINTREG(sc, ATW_CSR6A);
490 PRINTREG(sc, ATW_IER);
491 PRINTREG(sc, ATW_CSR7A);
492 PRINTREG(sc, ATW_LPC);
493 PRINTREG(sc, ATW_TEST1);
494 PRINTREG(sc, ATW_SPR);
495 PRINTREG(sc, ATW_TEST0);
496 PRINTREG(sc, ATW_WCSR);
497 PRINTREG(sc, ATW_WPDR);
498 PRINTREG(sc, ATW_GPTMR);
499 PRINTREG(sc, ATW_GPIO);
500 PRINTREG(sc, ATW_BBPCTL);
501 PRINTREG(sc, ATW_SYNCTL);
502 PRINTREG(sc, ATW_PLCPHD);
503 PRINTREG(sc, ATW_MMIWADDR);
504 PRINTREG(sc, ATW_MMIRADDR1);
505 PRINTREG(sc, ATW_MMIRADDR2);
506 PRINTREG(sc, ATW_TXBR);
507 PRINTREG(sc, ATW_CSR15A);
508 PRINTREG(sc, ATW_ALCSTAT);
509 PRINTREG(sc, ATW_TOFS2);
510 PRINTREG(sc, ATW_CMDR);
511 PRINTREG(sc, ATW_PCIC);
512 PRINTREG(sc, ATW_PMCSR);
513 PRINTREG(sc, ATW_PAR0);
514 PRINTREG(sc, ATW_PAR1);
515 PRINTREG(sc, ATW_MAR0);
516 PRINTREG(sc, ATW_MAR1);
517 PRINTREG(sc, ATW_ATIMDA0);
518 PRINTREG(sc, ATW_ABDA1);
519 PRINTREG(sc, ATW_BSSID0);
520 PRINTREG(sc, ATW_TXLMT);
521 PRINTREG(sc, ATW_MIBCNT);
522 PRINTREG(sc, ATW_BCNT);
523 PRINTREG(sc, ATW_TSFTH);
524 PRINTREG(sc, ATW_TSC);
525 PRINTREG(sc, ATW_SYNRF);
526 PRINTREG(sc, ATW_BPLI);
527 PRINTREG(sc, ATW_CAP0);
528 PRINTREG(sc, ATW_CAP1);
529 PRINTREG(sc, ATW_RMD);
530 PRINTREG(sc, ATW_CFPP);
531 PRINTREG(sc, ATW_TOFS0);
532 PRINTREG(sc, ATW_TOFS1);
533 PRINTREG(sc, ATW_IFST);
534 PRINTREG(sc, ATW_RSPT);
535 PRINTREG(sc, ATW_TSFTL);
536 PRINTREG(sc, ATW_WEPCTL);
537 PRINTREG(sc, ATW_WESK);
538 PRINTREG(sc, ATW_WEPCNT);
539 PRINTREG(sc, ATW_MACTEST);
540 PRINTREG(sc, ATW_FER);
541 PRINTREG(sc, ATW_FEMR);
542 PRINTREG(sc, ATW_FPSR);
543 PRINTREG(sc, ATW_FFER);
544 #undef PRINTREG
545 }
546 #endif
547
548 const char*
549 atw_printmac(u_int8_t rev) {
550 switch (rev) {
551 case ATW_REVISION_AB:
552 return "ADM8211AB";
553 case ATW_REVISION_AF:
554 return "ADM8211AF";
555 case ATW_REVISION_BA:
556 return "ADM8211BA";
557 case ATW_REVISION_CA:
558 return "ADM8211CA";
559 default:
560 return "unknown";
561 }
562 }
563
564
565
566
567 void
568 atw_attach(struct atw_softc *sc)
569 {
570 static const u_int8_t empty_macaddr[IEEE80211_ADDR_LEN] = {
571 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
572 };
573 struct ieee80211com *ic = &sc->sc_ic;
574 struct ifnet *ifp = &ic->ic_if;
575 int country_code, error, i, srom_major;
576 u_int32_t reg;
577 static const char *type_strings[] = {"Intersil (not supported)",
578 "RFMD", "Marvel (not supported)"};
579
580 sc->sc_txth = atw_txthresh_tab_lo;
581
582 SIMPLEQ_INIT(&sc->sc_txfreeq);
583 SIMPLEQ_INIT(&sc->sc_txdirtyq);
584
585 #ifdef ATW_DEBUG
586 atw_print_regs(sc, "atw_attach");
587 #endif
588
589
590
591
592
593 if ((error = bus_dmamem_alloc(sc->sc_dmat,
594 sizeof(struct atw_control_data), PAGE_SIZE, 0, &sc->sc_cdseg,
595 1, &sc->sc_cdnseg, 0)) != 0) {
596 printf("%s: unable to allocate control data, error = %d\n",
597 sc->sc_dev.dv_xname, error);
598 goto fail_0;
599 }
600
601 if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg,
602 sizeof(struct atw_control_data), (caddr_t *)&sc->sc_control_data,
603 BUS_DMA_COHERENT)) != 0) {
604 printf("%s: unable to map control data, error = %d\n",
605 sc->sc_dev.dv_xname, error);
606 goto fail_1;
607 }
608
609 if ((error = bus_dmamap_create(sc->sc_dmat,
610 sizeof(struct atw_control_data), 1,
611 sizeof(struct atw_control_data), 0, 0, &sc->sc_cddmamap)) != 0) {
612 printf("%s: unable to create control data DMA map, "
613 "error = %d\n", sc->sc_dev.dv_xname, error);
614 goto fail_2;
615 }
616
617 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap,
618 sc->sc_control_data, sizeof(struct atw_control_data), NULL,
619 0)) != 0) {
620 printf("%s: unable to load control data DMA map, error = %d\n",
621 sc->sc_dev.dv_xname, error);
622 goto fail_3;
623 }
624
625
626
627
628 sc->sc_ntxsegs = ATW_NTXSEGS;
629 for (i = 0; i < ATW_TXQUEUELEN; i++) {
630 if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
631 sc->sc_ntxsegs, MCLBYTES, 0, 0,
632 &sc->sc_txsoft[i].txs_dmamap)) != 0) {
633 printf("%s: unable to create tx DMA map %d, "
634 "error = %d\n", sc->sc_dev.dv_xname, i, error);
635 goto fail_4;
636 }
637 }
638
639
640
641
642 for (i = 0; i < ATW_NRXDESC; i++) {
643 if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
644 MCLBYTES, 0, 0, &sc->sc_rxsoft[i].rxs_dmamap)) != 0) {
645 printf("%s: unable to create rx DMA map %d, "
646 "error = %d\n", sc->sc_dev.dv_xname, i, error);
647 goto fail_5;
648 }
649 }
650 for (i = 0; i < ATW_NRXDESC; i++) {
651 sc->sc_rxsoft[i].rxs_mbuf = NULL;
652 }
653
654 switch (sc->sc_rev) {
655 case ATW_REVISION_AB:
656 case ATW_REVISION_AF:
657 sc->sc_sramlen = ATW_SRAM_A_SIZE;
658 break;
659 case ATW_REVISION_BA:
660 case ATW_REVISION_CA:
661 sc->sc_sramlen = ATW_SRAM_B_SIZE;
662 break;
663 }
664
665
666 atw_reset(sc);
667
668 if (atw_read_srom(sc) == -1)
669 return;
670
671 sc->sc_rftype = MASK_AND_RSHIFT(sc->sc_srom[ATW_SR_CSR20],
672 ATW_SR_RFTYPE_MASK);
673
674 sc->sc_bbptype = MASK_AND_RSHIFT(sc->sc_srom[ATW_SR_CSR20],
675 ATW_SR_BBPTYPE_MASK);
676
677 if (sc->sc_rftype >= sizeof(type_strings)/sizeof(type_strings[0])) {
678 printf("%s: unknown RF\n", sc->sc_dev.dv_xname);
679 return;
680 }
681 if (sc->sc_bbptype >= sizeof(type_strings)/sizeof(type_strings[0])) {
682 printf("%s: unknown BBP\n", sc->sc_dev.dv_xname);
683 return;
684 }
685
686 printf("%s: MAC %s, BBP %s, RF %s", sc->sc_dev.dv_xname,
687 atw_printmac(sc->sc_rev), type_strings[sc->sc_bbptype],
688 type_strings[sc->sc_rftype]);
689
690
691
692
693
694 reg = LSHIFT(sc->sc_rftype, ATW_SYNCTL_RFTYPE_MASK);
695
696 switch (sc->sc_rftype) {
697 case ATW_RFTYPE_INTERSIL:
698 reg |= ATW_SYNCTL_CS1;
699 break;
700 case ATW_RFTYPE_RFMD:
701 reg |= ATW_SYNCTL_CS0;
702 break;
703 case ATW_RFTYPE_MARVEL:
704 break;
705 }
706
707 sc->sc_synctl_rd = reg | ATW_SYNCTL_RD;
708 sc->sc_synctl_wr = reg | ATW_SYNCTL_WR;
709
710 reg = LSHIFT(sc->sc_bbptype, ATW_BBPCTL_TYPE_MASK);
711
712 switch (sc->sc_bbptype) {
713 case ATW_BBPTYPE_INTERSIL:
714 reg |= ATW_BBPCTL_TWI;
715 break;
716 case ATW_BBPTYPE_RFMD:
717 reg |= ATW_BBPCTL_RF3KADDR_ADDR | ATW_BBPCTL_NEGEDGE_DO |
718 ATW_BBPCTL_CCA_ACTLO;
719 break;
720 case ATW_BBPTYPE_MARVEL:
721 break;
722 case ATW_C_BBPTYPE_RFMD:
723 printf("%s: ADM8211C MAC/RFMD BBP not supported yet.\n",
724 sc->sc_dev.dv_xname);
725 break;
726 }
727
728 sc->sc_bbpctl_wr = reg | ATW_BBPCTL_WR;
729 sc->sc_bbpctl_rd = reg | ATW_BBPCTL_RD;
730
731
732
733
734
735
736 sc->sc_flags |= ATWF_ATTACHED ;
737
738 ATW_DPRINTF((" SROM MAC %04x%04x%04x",
739 htole16(sc->sc_srom[ATW_SR_MAC00]),
740 htole16(sc->sc_srom[ATW_SR_MAC01]),
741 htole16(sc->sc_srom[ATW_SR_MAC10])));
742
743 srom_major = MASK_AND_RSHIFT(sc->sc_srom[ATW_SR_FORMAT_VERSION],
744 ATW_SR_MAJOR_MASK);
745
746 if (srom_major < 2)
747 sc->sc_rf3000_options1 = 0;
748 else if (sc->sc_rev == ATW_REVISION_BA) {
749 sc->sc_rf3000_options1 =
750 MASK_AND_RSHIFT(sc->sc_srom[ATW_SR_CR28_CR03],
751 ATW_SR_CR28_MASK);
752 } else
753 sc->sc_rf3000_options1 = 0;
754
755 sc->sc_rf3000_options2 = MASK_AND_RSHIFT(sc->sc_srom[ATW_SR_CTRY_CR29],
756 ATW_SR_CR29_MASK);
757
758 country_code = MASK_AND_RSHIFT(sc->sc_srom[ATW_SR_CTRY_CR29],
759 ATW_SR_CTRY_MASK);
760
761 #define ADD_CHANNEL(_ic, _chan) do { \
762 _ic->ic_channels[_chan].ic_flags = IEEE80211_CHAN_B; \
763 _ic->ic_channels[_chan].ic_freq = \
764 ieee80211_ieee2mhz(_chan, _ic->ic_channels[_chan].ic_flags);\
765 } while (0)
766
767
768 switch (country_code) {
769 case COUNTRY_MMK2:
770 ADD_CHANNEL(ic, 14);
771
772 case COUNTRY_ETSI:
773 for (i = 1; i <= 13; i++)
774 ADD_CHANNEL(ic, i);
775 break;
776 case COUNTRY_FCC:
777 case COUNTRY_IC:
778 for (i = 1; i <= 11; i++)
779 ADD_CHANNEL(ic, i);
780 break;
781 case COUNTRY_MMK:
782 ADD_CHANNEL(ic, 14);
783 break;
784 case COUNTRY_FRANCE:
785 for (i = 10; i <= 13; i++)
786 ADD_CHANNEL(ic, i);
787 break;
788 default:
789 case COUNTRY_SPAIN:
790 for (i = 10; i <= 11; i++)
791 ADD_CHANNEL(ic, i);
792 break;
793 }
794
795
796 reg = ATW_READ(sc, ATW_PAR0);
797 ic->ic_myaddr[0] = MASK_AND_RSHIFT(reg, ATW_PAR0_PAB0_MASK);
798 ic->ic_myaddr[1] = MASK_AND_RSHIFT(reg, ATW_PAR0_PAB1_MASK);
799 ic->ic_myaddr[2] = MASK_AND_RSHIFT(reg, ATW_PAR0_PAB2_MASK);
800 ic->ic_myaddr[3] = MASK_AND_RSHIFT(reg, ATW_PAR0_PAB3_MASK);
801 reg = ATW_READ(sc, ATW_PAR1);
802 ic->ic_myaddr[4] = MASK_AND_RSHIFT(reg, ATW_PAR1_PAB4_MASK);
803 ic->ic_myaddr[5] = MASK_AND_RSHIFT(reg, ATW_PAR1_PAB5_MASK);
804
805 if (IEEE80211_ADDR_EQ(ic->ic_myaddr, empty_macaddr)) {
806 printf(" could not get mac address, attach failed\n");
807 return;
808 }
809
810 printf(", address %s\n", ether_sprintf(ic->ic_myaddr));
811
812 memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
813 ifp->if_softc = sc;
814 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST |
815 IFF_NOTRAILERS;
816 ifp->if_ioctl = atw_ioctl;
817 ifp->if_start = atw_start;
818 ifp->if_watchdog = atw_watchdog;
819 #if !defined(__OpenBSD__)
820 ifp->if_init = atw_init;
821 ifp->if_stop = atw_stop;
822 #endif
823 IFQ_SET_READY(&ifp->if_snd);
824
825 ic->ic_phytype = IEEE80211_T_DS;
826 ic->ic_opmode = IEEE80211_M_STA;
827 ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_IBSS |
828 IEEE80211_C_HOSTAP | IEEE80211_C_MONITOR | IEEE80211_C_WEP;
829
830 ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
831
832
833
834
835
836 if_attach(ifp);
837 ieee80211_ifattach(ifp);
838
839 sc->sc_newstate = ic->ic_newstate;
840 ic->ic_newstate = atw_newstate;
841
842 sc->sc_recv_mgmt = ic->ic_recv_mgmt;
843 ic->ic_recv_mgmt = atw_recv_mgmt;
844
845 sc->sc_node_free = ic->ic_node_free;
846 ic->ic_node_free = atw_node_free;
847
848 sc->sc_node_alloc = ic->ic_node_alloc;
849 ic->ic_node_alloc = atw_node_alloc;
850
851
852
853
854
855
856
857 ieee80211_media_init(ifp, atw_media_change, atw_media_status);
858 timeout_set(&sc->sc_scan_to, atw_next_scan, sc);
859
860 #if NBPFILTER > 0
861 bpfattach(&sc->sc_radiobpf, ifp, DLT_IEEE802_11_RADIO,
862 sizeof(struct ieee80211_frame) + 64);
863 #endif
864
865
866
867
868 sc->sc_sdhook = shutdownhook_establish(atw_shutdown, sc);
869 if (sc->sc_sdhook == NULL)
870 printf("%s: WARNING: unable to establish shutdown hook\n",
871 sc->sc_dev.dv_xname);
872
873
874
875
876
877 sc->sc_powerhook = powerhook_establish(atw_power, sc);
878 if (sc->sc_powerhook == NULL)
879 printf("%s: WARNING: unable to establish power hook\n",
880 sc->sc_dev.dv_xname);
881
882 memset(&sc->sc_rxtapu, 0, sizeof(sc->sc_rxtapu));
883 sc->sc_rxtap.ar_ihdr.it_len = sizeof(sc->sc_rxtapu);
884 sc->sc_rxtap.ar_ihdr.it_present = ATW_RX_RADIOTAP_PRESENT;
885
886 memset(&sc->sc_txtapu, 0, sizeof(sc->sc_txtapu));
887 sc->sc_txtap.at_ihdr.it_len = sizeof(sc->sc_txtapu);
888 sc->sc_txtap.at_ihdr.it_present = ATW_TX_RADIOTAP_PRESENT;
889
890 return;
891
892
893
894
895
896 fail_5:
897 for (i = 0; i < ATW_NRXDESC; i++) {
898 if (sc->sc_rxsoft[i].rxs_dmamap == NULL)
899 continue;
900 bus_dmamap_destroy(sc->sc_dmat, sc->sc_rxsoft[i].rxs_dmamap);
901 }
902 fail_4:
903 for (i = 0; i < ATW_TXQUEUELEN; i++) {
904 if (sc->sc_txsoft[i].txs_dmamap == NULL)
905 continue;
906 bus_dmamap_destroy(sc->sc_dmat, sc->sc_txsoft[i].txs_dmamap);
907 }
908 bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
909 fail_3:
910 bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
911 fail_2:
912 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_control_data,
913 sizeof(struct atw_control_data));
914 fail_1:
915 bus_dmamem_free(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg);
916 fail_0:
917 return;
918 }
919
920 struct ieee80211_node *
921 atw_node_alloc(struct ieee80211com *ic)
922 {
923 struct atw_softc *sc = (struct atw_softc *)ic->ic_if.if_softc;
924 struct ieee80211_node *ni = (*sc->sc_node_alloc)(ic);
925
926 DPRINTF(sc, ("%s: alloc node %p\n", sc->sc_dev.dv_xname, ni));
927 return ni;
928 }
929
930 void
931 atw_node_free(struct ieee80211com *ic, struct ieee80211_node *ni)
932 {
933 struct atw_softc *sc = (struct atw_softc *)ic->ic_if.if_softc;
934
935 DPRINTF(sc, ("%s: freeing node %p %s\n", sc->sc_dev.dv_xname, ni,
936 ether_sprintf(ni->ni_bssid)));
937 (*sc->sc_node_free)(ic, ni);
938 }
939
940
941 static void
942 atw_test1_reset(struct atw_softc *sc)
943 {
944 switch (sc->sc_rev) {
945 case ATW_REVISION_BA:
946 if (1 ) {
947 ATW_SET(sc, ATW_TEST1, ATW_TEST1_TESTMODE_MONITOR);
948 }
949 break;
950 case ATW_REVISION_CA:
951 ATW_CLR(sc, ATW_TEST1, ATW_TEST1_TESTMODE_MASK);
952 break;
953 default:
954 break;
955 }
956 }
957
958
959
960
961
962
963 void
964 atw_reset(struct atw_softc *sc)
965 {
966 int i;
967 uint32_t lpc;
968
969 ATW_WRITE(sc, ATW_NAR, 0x0);
970 DELAY(20 * 1000);
971
972
973
974
975 ATW_WRITE(sc, ATW_FRCTL, 0x0);
976
977 ATW_WRITE(sc, ATW_PAR, ATW_PAR_SWR);
978
979 for (i = 0; i < 50; i++) {
980 if (ATW_READ(sc, ATW_PAR) == 0)
981 break;
982 DELAY(1000);
983 }
984
985
986 DELAY(100 * 1000);
987
988 DPRINTF2(sc, ("%s: atw_reset %d iterations\n", sc->sc_dev.dv_xname, i));
989
990 if (ATW_ISSET(sc, ATW_PAR, ATW_PAR_SWR))
991 printf("%s: reset failed to complete\n", sc->sc_dev.dv_xname);
992
993 atw_test1_reset(sc);
994
995
996
997 sc->sc_busmode = ATW_PAR_PBL_8DW;
998
999 ATW_WRITE(sc, ATW_PAR, sc->sc_busmode);
1000 DPRINTF(sc, ("%s: ATW_PAR %08x busmode %08x\n", sc->sc_dev.dv_xname,
1001 ATW_READ(sc, ATW_PAR), sc->sc_busmode));
1002
1003
1004
1005
1006
1007
1008 ATW_WRITE(sc, ATW_FRCTL, 0x0);
1009
1010 DELAY(100 * 1000);
1011
1012
1013 ATW_SET(sc, ATW_TEST0, ATW_TEST0_EPRLD);
1014
1015 DELAY(10 * 1000);
1016
1017 lpc = ATW_READ(sc, ATW_LPC);
1018
1019 DPRINTF(sc, ("%s: ATW_LPC %#08x\n", __func__, lpc));
1020
1021
1022
1023
1024 atw_clear_sram(sc);
1025
1026 memset(sc->sc_bssid, 0xff, sizeof(sc->sc_bssid));
1027 }
1028
1029 void
1030 atw_clear_sram(struct atw_softc *sc)
1031 {
1032 memset(sc->sc_sram, 0, sizeof(sc->sc_sram));
1033
1034 atw_write_sram(sc, 0, sc->sc_sram, sc->sc_sramlen);
1035 }
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048 void
1049 atw_wcsr_init(struct atw_softc *sc)
1050 {
1051 uint32_t wcsr;
1052
1053 wcsr = ATW_READ(sc, ATW_WCSR);
1054 wcsr &= ~(ATW_WCSR_BLN_MASK|ATW_WCSR_LSOE|ATW_WCSR_MPRE|ATW_WCSR_LSOE);
1055 wcsr |= LSHIFT(7, ATW_WCSR_BLN_MASK);
1056 ATW_WRITE(sc, ATW_WCSR, wcsr);
1057
1058 DPRINTF(sc, ("%s: %s reg[WCSR] = %08x\n",
1059 sc->sc_dev.dv_xname, __func__, ATW_READ(sc, ATW_WCSR)));
1060 }
1061
1062
1063 void
1064 atw_cmdr_init(struct atw_softc *sc)
1065 {
1066 uint32_t cmdr;
1067 cmdr = ATW_READ(sc, ATW_CMDR);
1068 cmdr &= ~ATW_CMDR_APM;
1069 cmdr |= ATW_CMDR_RTE;
1070 cmdr &= ~ATW_CMDR_DRT_MASK;
1071 cmdr |= ATW_CMDR_DRT_SF;
1072
1073 ATW_WRITE(sc, ATW_CMDR, cmdr);
1074 }
1075
1076 void
1077 atw_tofs2_init(struct atw_softc *sc)
1078 {
1079 uint32_t tofs2;
1080
1081 #ifndef ATW_REFSLAVE
1082 tofs2 = LSHIFT(4, ATW_TOFS2_PWR1UP_MASK) |
1083 LSHIFT(13, ATW_TOFS2_PWR0PAPE_MASK) |
1084 LSHIFT(8, ATW_TOFS2_PWR1PAPE_MASK) |
1085 LSHIFT(5, ATW_TOFS2_PWR0TRSW_MASK) |
1086 LSHIFT(12, ATW_TOFS2_PWR1TRSW_MASK) |
1087 LSHIFT(13, ATW_TOFS2_PWR0PE2_MASK) |
1088 LSHIFT(4, ATW_TOFS2_PWR1PE2_MASK) |
1089 LSHIFT(5, ATW_TOFS2_PWR0TXPE_MASK);
1090 #else
1091
1092 tofs2 = LSHIFT(8, ATW_TOFS2_PWR1UP_MASK) |
1093 LSHIFT(8, ATW_TOFS2_PWR0PAPE_MASK) |
1094 LSHIFT(1, ATW_TOFS2_PWR1PAPE_MASK) |
1095 LSHIFT(5, ATW_TOFS2_PWR0TRSW_MASK) |
1096 LSHIFT(12, ATW_TOFS2_PWR1TRSW_MASK) |
1097 LSHIFT(13, ATW_TOFS2_PWR0PE2_MASK) |
1098 LSHIFT(1, ATW_TOFS2_PWR1PE2_MASK) |
1099 LSHIFT(8, ATW_TOFS2_PWR0TXPE_MASK);
1100 #endif
1101 ATW_WRITE(sc, ATW_TOFS2, tofs2);
1102 }
1103
1104 void
1105 atw_nar_init(struct atw_softc *sc)
1106 {
1107 ATW_WRITE(sc, ATW_NAR, ATW_NAR_SF|ATW_NAR_PB);
1108 }
1109
1110 void
1111 atw_txlmt_init(struct atw_softc *sc)
1112 {
1113 ATW_WRITE(sc, ATW_TXLMT, LSHIFT(512, ATW_TXLMT_MTMLT_MASK) |
1114 LSHIFT(1, ATW_TXLMT_SRTYLIM_MASK));
1115 }
1116
1117 void
1118 atw_test1_init(struct atw_softc *sc)
1119 {
1120 uint32_t test1;
1121
1122 test1 = ATW_READ(sc, ATW_TEST1);
1123 test1 &= ~(ATW_TEST1_DBGREAD_MASK|ATW_TEST1_CONTROL);
1124
1125 test1 |= LSHIFT(0x1, ATW_TEST1_DBGREAD_MASK) | ATW_TEST1_CONTROL;
1126 ATW_WRITE(sc, ATW_TEST1, test1);
1127 }
1128
1129 void
1130 atw_rf_reset(struct atw_softc *sc)
1131 {
1132
1133
1134 ATW_WRITE(sc, ATW_SYNRF, ATW_SYNRF_INTERSIL_EN);
1135 DELAY(10 * 1000);
1136 ATW_WRITE(sc, ATW_SYNRF, 0);
1137 DELAY(5 * 1000);
1138 }
1139
1140
1141 void
1142 atw_cfp_init(struct atw_softc *sc)
1143 {
1144 uint32_t cfpp;
1145
1146 cfpp = ATW_READ(sc, ATW_CFPP);
1147 cfpp &= ~ATW_CFPP_CFPMD;
1148 cfpp |= LSHIFT(16, ATW_CFPP_CFPMD);
1149 ATW_WRITE(sc, ATW_CFPP, cfpp);
1150 }
1151
1152 void
1153 atw_tofs0_init(struct atw_softc *sc)
1154 {
1155
1156
1157
1158
1159
1160
1161
1162
1163 ATW_WRITE(sc, ATW_TOFS0,
1164 LSHIFT(22, ATW_TOFS0_USCNT_MASK) |
1165 ATW_TOFS0_TUCNT_MASK );
1166 }
1167
1168
1169 void
1170 atw_ifs_init(struct atw_softc *sc)
1171 {
1172 uint32_t ifst;
1173
1174
1175
1176 ifst = LSHIFT(IEEE80211_DUR_DS_SLOT, ATW_IFST_SLOT_MASK) |
1177 LSHIFT(22 * 5 ,
1178 ATW_IFST_SIFS_MASK) |
1179 LSHIFT(IEEE80211_DUR_DS_DIFS, ATW_IFST_DIFS_MASK) |
1180 LSHIFT(0x64 , ATW_IFST_EIFS_MASK);
1181
1182 ATW_WRITE(sc, ATW_IFST, ifst);
1183 }
1184
1185 void
1186 atw_response_times_init(struct atw_softc *sc)
1187 {
1188
1189
1190
1191
1192
1193
1194 ATW_WRITE(sc, ATW_RSPT, LSHIFT(0xffff, ATW_RSPT_MART_MASK) |
1195 LSHIFT(0xff, ATW_RSPT_MIRT_MASK));
1196 }
1197
1198
1199
1200
1201
1202 void
1203 atw_bbp_io_init(struct atw_softc *sc)
1204 {
1205 uint32_t mmiraddr2;
1206
1207
1208
1209
1210 switch (sc->sc_rev) {
1211 case ATW_REVISION_AB:
1212 case ATW_REVISION_AF:
1213 mmiraddr2 = 0x0;
1214 break;
1215 default:
1216 mmiraddr2 = ATW_READ(sc, ATW_MMIRADDR2);
1217 mmiraddr2 &=
1218 ~(ATW_MMIRADDR2_PROREXT|ATW_MMIRADDR2_PRORLEN_MASK);
1219 break;
1220 }
1221
1222 switch (sc->sc_bbptype) {
1223 case ATW_BBPTYPE_INTERSIL:
1224 ATW_WRITE(sc, ATW_MMIWADDR, ATW_MMIWADDR_INTERSIL);
1225 ATW_WRITE(sc, ATW_MMIRADDR1, ATW_MMIRADDR1_INTERSIL);
1226 mmiraddr2 |= ATW_MMIRADDR2_INTERSIL;
1227 break;
1228 case ATW_BBPTYPE_MARVEL:
1229
1230 break;
1231 case ATW_BBPTYPE_RFMD:
1232 default:
1233 ATW_WRITE(sc, ATW_MMIWADDR, ATW_MMIWADDR_RFMD);
1234 ATW_WRITE(sc, ATW_MMIRADDR1, ATW_MMIRADDR1_RFMD);
1235 mmiraddr2 |= ATW_MMIRADDR2_RFMD;
1236 break;
1237 }
1238 ATW_WRITE(sc, ATW_MMIRADDR2, mmiraddr2);
1239
1240 atw_si4126_init(sc);
1241
1242 ATW_WRITE(sc, ATW_MACTEST, ATW_MACTEST_MMI_USETXCLK);
1243 }
1244
1245 void
1246 atw_si4126_init(struct atw_softc *sc)
1247 {
1248 switch (sc->sc_rftype) {
1249 case ATW_RFTYPE_RFMD:
1250 if (sc->sc_rev >= ATW_REVISION_BA) {
1251 atw_si4126_write(sc, 0x1f, 0x00000);
1252 atw_si4126_write(sc, 0x0c, 0x3001f);
1253 atw_si4126_write(sc, SI4126_GAIN, 0x29c03);
1254 atw_si4126_write(sc, SI4126_RF1N, 0x1ff6f);
1255 atw_si4126_write(sc, SI4126_RF2N, 0x29403);
1256 atw_si4126_write(sc, SI4126_RF2R, 0x1456f);
1257 atw_si4126_write(sc, 0x09, 0x10050);
1258 atw_si4126_write(sc, SI4126_IFR, 0x3fff8);
1259 }
1260 break;
1261 default:
1262 break;
1263 }
1264 }
1265
1266
1267
1268
1269
1270
1271 int
1272 atw_init(struct ifnet *ifp)
1273 {
1274 struct atw_softc *sc = ifp->if_softc;
1275 struct ieee80211com *ic = &sc->sc_ic;
1276 struct atw_txsoft *txs;
1277 struct atw_rxsoft *rxs;
1278 int i, error = 0;
1279
1280 if ((error = atw_enable(sc)) != 0)
1281 goto out;
1282
1283
1284
1285
1286 atw_stop(ifp, 0);
1287
1288 ic->ic_bss->ni_chan = ic->ic_ibss_chan;
1289 DPRINTF(sc, ("%s: channel %d freq %d flags 0x%04x\n",
1290 __func__, ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan),
1291 ic->ic_bss->ni_chan->ic_freq, ic->ic_bss->ni_chan->ic_flags));
1292
1293 atw_wcsr_init(sc);
1294
1295 atw_cmdr_init(sc);
1296
1297
1298
1299
1300
1301 ATW_WRITE(sc, ATW_PLCPHD, LSHIFT(10, ATW_PLCPHD_SIGNAL_MASK) |
1302 LSHIFT(0xb0, ATW_PLCPHD_SERVICE_MASK));
1303
1304 atw_tofs2_init(sc);
1305
1306 atw_nar_init(sc);
1307
1308 atw_txlmt_init(sc);
1309
1310 atw_test1_init(sc);
1311
1312 atw_rf_reset(sc);
1313
1314 atw_cfp_init(sc);
1315
1316 atw_tofs0_init(sc);
1317
1318 atw_ifs_init(sc);
1319
1320
1321
1322
1323 ATW_WRITE(sc, ATW_RMD,
1324 LSHIFT(1, ATW_RMD_PCNT) | LSHIFT(0xffff, ATW_RMD_RMRD_MASK));
1325
1326 atw_response_times_init(sc);
1327
1328 atw_bbp_io_init(sc);
1329
1330 ATW_WRITE(sc, ATW_STSR, 0xffffffff);
1331
1332 if ((error = atw_rf3000_init(sc)) != 0)
1333 goto out;
1334
1335 ATW_WRITE(sc, ATW_PAR, sc->sc_busmode);
1336 DPRINTF(sc, ("%s: ATW_PAR %08x busmode %08x\n", sc->sc_dev.dv_xname,
1337 ATW_READ(sc, ATW_PAR), sc->sc_busmode));
1338
1339
1340
1341
1342 memset(sc->sc_txdescs, 0, sizeof(sc->sc_txdescs));
1343 for (i = 0; i < ATW_NTXDESC; i++) {
1344 sc->sc_txdescs[i].at_ctl = 0;
1345
1346 sc->sc_txdescs[i].at_flags = 0 ;
1347 sc->sc_txdescs[i].at_buf2 =
1348 htole32(ATW_CDTXADDR(sc, ATW_NEXTTX(i)));
1349 }
1350
1351 sc->sc_txdescs[ATW_NTXDESC - 1].at_flags |= htole32(ATW_TXFLAG_TER);
1352 ATW_CDTXSYNC(sc, 0, ATW_NTXDESC,
1353 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1354 sc->sc_txfree = ATW_NTXDESC;
1355 sc->sc_txnext = 0;
1356
1357
1358
1359
1360 SIMPLEQ_INIT(&sc->sc_txfreeq);
1361 SIMPLEQ_INIT(&sc->sc_txdirtyq);
1362 for (i = 0; i < ATW_TXQUEUELEN; i++) {
1363 txs = &sc->sc_txsoft[i];
1364 txs->txs_mbuf = NULL;
1365 SIMPLEQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q);
1366 }
1367
1368
1369
1370
1371
1372 for (i = 0; i < ATW_NRXDESC; i++) {
1373 rxs = &sc->sc_rxsoft[i];
1374 if (rxs->rxs_mbuf == NULL) {
1375 if ((error = atw_add_rxbuf(sc, i)) != 0) {
1376 printf("%s: unable to allocate or map rx "
1377 "buffer %d, error = %d\n",
1378 sc->sc_dev.dv_xname, i, error);
1379
1380
1381
1382
1383 atw_rxdrain(sc);
1384 goto out;
1385 }
1386 } else
1387 ATW_INIT_RXDESC(sc, i);
1388 }
1389 sc->sc_rxptr = 0;
1390
1391
1392
1393
1394
1395 sc->sc_inten = ATW_INTR_TCI | ATW_INTR_TDU | ATW_INTR_RCI |
1396 ATW_INTR_NISS | ATW_INTR_LINKON | ATW_INTR_BCNTC;
1397
1398
1399 sc->sc_inten |= ATW_INTR_TPS | ATW_INTR_TLT | ATW_INTR_TRT |
1400 ATW_INTR_TUF | ATW_INTR_RDU | ATW_INTR_RPS | ATW_INTR_AISS |
1401 ATW_INTR_FBE | ATW_INTR_LINKOFF | ATW_INTR_TSFTF | ATW_INTR_TSCZ;
1402
1403 sc->sc_linkint_mask = ATW_INTR_LINKON | ATW_INTR_LINKOFF |
1404 ATW_INTR_BCNTC | ATW_INTR_TSFTF | ATW_INTR_TSCZ;
1405 sc->sc_rxint_mask = ATW_INTR_RCI | ATW_INTR_RDU;
1406 sc->sc_txint_mask = ATW_INTR_TCI | ATW_INTR_TUF | ATW_INTR_TLT |
1407 ATW_INTR_TRT;
1408
1409 sc->sc_linkint_mask &= sc->sc_inten;
1410 sc->sc_rxint_mask &= sc->sc_inten;
1411 sc->sc_txint_mask &= sc->sc_inten;
1412
1413 ATW_WRITE(sc, ATW_IER, sc->sc_inten);
1414 ATW_WRITE(sc, ATW_STSR, 0xffffffff);
1415
1416 DPRINTF(sc, ("%s: ATW_IER %08x, inten %08x\n",
1417 sc->sc_dev.dv_xname, ATW_READ(sc, ATW_IER), sc->sc_inten));
1418
1419
1420
1421
1422 ATW_WRITE(sc, ATW_RDB, ATW_CDRXADDR(sc, sc->sc_rxptr));
1423 ATW_WRITE(sc, ATW_TDBD, ATW_CDTXADDR(sc, sc->sc_txnext));
1424
1425 sc->sc_txthresh = 0;
1426 sc->sc_opmode = ATW_NAR_SR | ATW_NAR_ST |
1427 sc->sc_txth[sc->sc_txthresh].txth_opmode;
1428
1429
1430 ic->ic_flags &= ~IEEE80211_F_IBSSON;
1431 switch (ic->ic_opmode) {
1432 case IEEE80211_M_STA:
1433 break;
1434 case IEEE80211_M_AHDEMO:
1435 case IEEE80211_M_IBSS:
1436 ic->ic_flags |= IEEE80211_F_IBSSON;
1437
1438 case IEEE80211_M_HOSTAP:
1439 break;
1440 case IEEE80211_M_MONITOR:
1441 break;
1442 }
1443
1444 switch (ic->ic_opmode) {
1445 case IEEE80211_M_AHDEMO:
1446 case IEEE80211_M_HOSTAP:
1447 ic->ic_bss->ni_intval = ic->ic_lintval;
1448 ic->ic_bss->ni_rssi = 0;
1449 ic->ic_bss->ni_rstamp = 0;
1450 break;
1451 default:
1452 break;
1453 }
1454
1455 sc->sc_wepctl = 0;
1456
1457 atw_write_ssid(sc);
1458 atw_write_sup_rates(sc);
1459 if (ic->ic_caps & IEEE80211_C_WEP)
1460 atw_write_wep(sc);
1461
1462 ic->ic_state = IEEE80211_S_INIT;
1463
1464
1465
1466
1467
1468 atw_filter_setup(sc);
1469
1470
1471
1472
1473 ATW_WRITE(sc, ATW_RDR, 0x1);
1474
1475
1476
1477
1478 ifp->if_flags |= IFF_RUNNING;
1479 ifp->if_flags &= ~IFF_OACTIVE;
1480
1481
1482 atw_start_beacon(sc, 0);
1483
1484 if (ic->ic_opmode == IEEE80211_M_MONITOR)
1485 error = ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
1486 else
1487 error = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
1488 out:
1489 if (error) {
1490 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1491 ifp->if_timer = 0;
1492 printf("%s: interface not running\n", sc->sc_dev.dv_xname);
1493 }
1494 #ifdef ATW_DEBUG
1495 atw_print_regs(sc, "end of init");
1496 #endif
1497
1498 return (error);
1499 }
1500
1501
1502
1503
1504
1505
1506
1507
1508 void
1509 atw_bbp_io_enable(struct atw_softc *sc, int enable)
1510 {
1511 if (enable) {
1512 ATW_WRITE(sc, ATW_SYNRF,
1513 ATW_SYNRF_SELRF|ATW_SYNRF_PE1|ATW_SYNRF_PHYRST);
1514 DELAY(atw_bbp_io_enable_delay);
1515 } else {
1516 ATW_WRITE(sc, ATW_SYNRF, 0);
1517 DELAY(atw_bbp_io_disable_delay);
1518 }
1519 }
1520
1521 int
1522 atw_tune(struct atw_softc *sc)
1523 {
1524 int rc;
1525 u_int chan;
1526 struct ieee80211com *ic = &sc->sc_ic;
1527
1528 chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
1529 if (chan == 0 || chan == IEEE80211_CHAN_ANY)
1530 return 0;
1531
1532 if (chan == sc->sc_cur_chan)
1533 return 0;
1534
1535 DPRINTF(sc, ("%s: chan %d -> %d\n", sc->sc_dev.dv_xname,
1536 sc->sc_cur_chan, chan));
1537
1538 atw_idle(sc, ATW_NAR_SR|ATW_NAR_ST);
1539
1540 atw_si4126_tune(sc, chan);
1541 if ((rc = atw_rf3000_tune(sc, chan)) != 0)
1542 printf("%s: failed to tune channel %d\n", sc->sc_dev.dv_xname,
1543 chan);
1544
1545 ATW_WRITE(sc, ATW_NAR, sc->sc_opmode);
1546 DELAY(20 * 1000);
1547 ATW_WRITE(sc, ATW_RDR, 0x1);
1548
1549 if (rc == 0)
1550 sc->sc_cur_chan = chan;
1551
1552 return rc;
1553 }
1554
1555 #ifdef ATW_SYNDEBUG
1556 void
1557 atw_si4126_print(struct atw_softc *sc)
1558 {
1559 struct ifnet *ifp = &sc->sc_ic.ic_if;
1560 u_int addr, val;
1561
1562 if (atw_debug < 3 || (ifp->if_flags & IFF_DEBUG) == 0)
1563 return;
1564
1565 for (addr = 0; addr <= 8; addr++) {
1566 printf("%s: synth[%d] = ", sc->sc_dev.dv_xname, addr);
1567 if (atw_si4126_read(sc, addr, &val) == 0) {
1568 printf("<unknown> (quitting print-out)\n");
1569 break;
1570 }
1571 printf("%05x\n", val);
1572 }
1573 }
1574 #endif
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593 void
1594 atw_si4126_tune(struct atw_softc *sc, u_int chan)
1595 {
1596 u_int mhz;
1597 u_int R;
1598 u_int32_t gpio;
1599 u_int16_t gain;
1600
1601 #ifdef ATW_SYNDEBUG
1602 atw_si4126_print(sc);
1603 #endif
1604
1605 if (sc->sc_rev >= ATW_REVISION_BA) {
1606 atw_si4126_write(sc, SI4126_MAIN, 0x04007);
1607 atw_si4126_write(sc, SI4126_POWER, 0x00033);
1608 atw_si4126_write(sc, SI4126_IFN,
1609 atw_rfmd2958_ifn[chan - 1]);
1610 atw_si4126_write(sc, SI4126_RF1R,
1611 atw_rfmd2958_rf1r[chan - 1]);
1612 #ifdef NOTYET
1613
1614 atw_si4126_write(sc, 0x0a,
1615 (sc->sc_srom[ATW_SR_CSR20] & mask) |
1616 power << 9);
1617 #endif
1618
1619 atw_si4126_write(sc, 0x09, 0x00050 |
1620 sc->sc_srom[ATW_SR_TXPOWER(chan - 1)]);
1621
1622 DELAY(100);
1623
1624 return;
1625 }
1626
1627 if (chan == 14)
1628 mhz = 2484;
1629 else
1630 mhz = 2412 + 5 * (chan - 1);
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641 if (atw_xindiv2)
1642 R = 44;
1643 else
1644 R = 88;
1645
1646
1647 atw_si4126_write(sc, SI4126_POWER,
1648 SI4126_POWER_PDIB|SI4126_POWER_PDRB);
1649
1650
1651 atw_si4126_write(sc, SI4126_MAIN,
1652 (atw_xindiv2) ? SI4126_MAIN_XINDIV2 : 0);
1653
1654
1655
1656
1657
1658
1659
1660 gain = LSHIFT(((mhz - 374) > 2047) ? 1 : 0, SI4126_GAIN_KP2_MASK);
1661
1662 atw_si4126_write(sc, SI4126_GAIN, gain);
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672 atw_si4126_write(sc, SI4126_IFN, 1496);
1673
1674 atw_si4126_write(sc, SI4126_IFR, R);
1675
1676 #ifndef ATW_REFSLAVE
1677
1678
1679
1680
1681 atw_si4126_write(sc, SI4126_RF1R, R);
1682
1683 atw_si4126_write(sc, SI4126_RF1N, mhz - 374);
1684 #endif
1685
1686
1687
1688
1689
1690 atw_si4126_write(sc, SI4126_RF2R, R);
1691
1692 atw_si4126_write(sc, SI4126_RF2N, mhz - 374);
1693
1694
1695 DELAY(100);
1696
1697 gpio = ATW_READ(sc, ATW_GPIO);
1698 gpio &= ~(ATW_GPIO_EN_MASK|ATW_GPIO_O_MASK|ATW_GPIO_I_MASK);
1699 gpio |= LSHIFT(1, ATW_GPIO_EN_MASK);
1700
1701 if ((sc->sc_if.if_flags & IFF_LINK1) != 0 && chan != 14) {
1702
1703
1704
1705
1706
1707 gpio |= LSHIFT(1, ATW_GPIO_O_MASK);
1708 }
1709 ATW_WRITE(sc, ATW_GPIO, gpio);
1710
1711 #ifdef ATW_SYNDEBUG
1712 atw_si4126_print(sc);
1713 #endif
1714 }
1715
1716
1717
1718
1719
1720
1721
1722
1723 int
1724 atw_rf3000_init(struct atw_softc *sc)
1725 {
1726 int rc = 0;
1727
1728 atw_bbp_io_enable(sc, 1);
1729
1730
1731 rc = atw_rf3000_write(sc, RF3000_CCACTL,
1732 LSHIFT(RF3000_CCACTL_MODE_BOTH, RF3000_CCACTL_MODE_MASK));
1733
1734 if (rc != 0)
1735 goto out;
1736
1737
1738 rc = atw_rf3000_write(sc, RF3000_DIVCTL, RF3000_DIVCTL_ENABLE);
1739
1740 if (rc != 0)
1741 goto out;
1742
1743
1744 rc = atw_rf3000_write(sc, RF3000_GAINCTL,
1745 LSHIFT(0x1d, RF3000_GAINCTL_TXVGC_MASK));
1746
1747 if (rc != 0)
1748 goto out;
1749
1750
1751 rc = atw_rf3000_write(sc, RF3000_LOGAINCAL,
1752 LSHIFT(0x38, RF3000_LOGAINCAL_CAL_MASK));
1753
1754 if (rc != 0)
1755 goto out;
1756
1757 rc = atw_rf3000_write(sc, RF3000_HIGAINCAL, RF3000_HIGAINCAL_DSSSPAD);
1758
1759 if (rc != 0)
1760 goto out;
1761
1762
1763
1764
1765
1766
1767 rc = atw_rf3000_write(sc, RF3000_OPTIONS1, sc->sc_rf3000_options1);
1768
1769 if (rc != 0)
1770 goto out;
1771
1772 rc = atw_rf3000_write(sc, RF3000_OPTIONS2, sc->sc_rf3000_options2);
1773
1774 if (rc != 0)
1775 goto out;
1776
1777 out:
1778 atw_bbp_io_enable(sc, 0);
1779 return rc;
1780 }
1781
1782 #ifdef ATW_BBPDEBUG
1783 void
1784 atw_rf3000_print(struct atw_softc *sc)
1785 {
1786 struct ifnet *ifp = &sc->sc_ic.ic_if;
1787 u_int addr, val;
1788
1789 if (atw_debug < 3 || (ifp->if_flags & IFF_DEBUG) == 0)
1790 return;
1791
1792 for (addr = 0x01; addr <= 0x15; addr++) {
1793 printf("%s: bbp[%d] = \n", sc->sc_dev.dv_xname, addr);
1794 if (atw_rf3000_read(sc, addr, &val) != 0) {
1795 printf("<unknown> (quitting print-out)\n");
1796 break;
1797 }
1798 printf("%08x\n", val);
1799 }
1800 }
1801 #endif
1802
1803
1804 int
1805 atw_rf3000_tune(struct atw_softc *sc, u_int chan)
1806 {
1807 int rc = 0;
1808 u_int32_t reg;
1809 u_int16_t txpower, lpf_cutoff, lna_gs_thresh;
1810
1811 txpower = sc->sc_srom[ATW_SR_TXPOWER(chan)];
1812 lpf_cutoff = sc->sc_srom[ATW_SR_LPF_CUTOFF(chan)];
1813 lna_gs_thresh = sc->sc_srom[ATW_SR_LNA_GS_THRESH(chan)];
1814
1815
1816 if (chan % 2 == 1) {
1817 txpower &= 0xFF;
1818 lpf_cutoff &= 0xFF;
1819 lna_gs_thresh &= 0xFF;
1820 } else {
1821 txpower >>= 8;
1822 lpf_cutoff >>= 8;
1823 lna_gs_thresh >>= 8;
1824 }
1825
1826 #ifdef ATW_BBPDEBUG
1827 atw_rf3000_print(sc);
1828 #endif
1829
1830 DPRINTF(sc, ("%s: chan %d txpower %02x, lpf_cutoff %02x, "
1831 "lna_gs_thresh %02x\n",
1832 sc->sc_dev.dv_xname, chan, txpower, lpf_cutoff, lna_gs_thresh));
1833
1834 atw_bbp_io_enable(sc, 1);
1835
1836 if ((rc = atw_rf3000_write(sc, RF3000_GAINCTL,
1837 LSHIFT(txpower, RF3000_GAINCTL_TXVGC_MASK))) != 0)
1838 goto out;
1839
1840 if ((rc = atw_rf3000_write(sc, RF3000_LOGAINCAL, lpf_cutoff)) != 0)
1841 goto out;
1842
1843 if ((rc = atw_rf3000_write(sc, RF3000_HIGAINCAL, lna_gs_thresh)) != 0)
1844 goto out;
1845
1846 if ((rc = atw_rf3000_write(sc, RF3000_OPTIONS1, 0x0)) != 0)
1847 goto out;
1848
1849 rc = atw_rf3000_write(sc, RF3000_OPTIONS2, RF3000_OPTIONS2_LNAGS_DELAY);
1850 if (rc != 0)
1851 goto out;
1852
1853 #ifdef ATW_BBPDEBUG
1854 atw_rf3000_print(sc);
1855 #endif
1856
1857 out:
1858 atw_bbp_io_enable(sc, 0);
1859
1860
1861 reg = ATW_READ(sc, ATW_PLCPHD);
1862 reg &= ~ATW_PLCPHD_SERVICE_MASK;
1863 reg |= LSHIFT(LSHIFT(txpower, RF3000_GAINCTL_TXVGC_MASK),
1864 ATW_PLCPHD_SERVICE_MASK);
1865 ATW_WRITE(sc, ATW_PLCPHD, reg);
1866 DELAY(2 * 1000);
1867
1868 return rc;
1869 }
1870
1871
1872
1873
1874
1875
1876 int
1877 atw_rf3000_write(struct atw_softc *sc, u_int addr, u_int val)
1878 {
1879 u_int32_t reg;
1880 int i;
1881
1882 reg = sc->sc_bbpctl_wr |
1883 LSHIFT(val & 0xff, ATW_BBPCTL_DATA_MASK) |
1884 LSHIFT(addr & 0x7f, ATW_BBPCTL_ADDR_MASK);
1885
1886 for (i = 10; --i >= 0; ) {
1887 ATW_WRITE(sc, ATW_BBPCTL, reg);
1888 DELAY(2000);
1889 if (ATW_ISSET(sc, ATW_BBPCTL, ATW_BBPCTL_WR) == 0)
1890 break;
1891 }
1892
1893 if (i < 0) {
1894 printf("%s: BBPCTL still busy\n", sc->sc_dev.dv_xname);
1895 return ETIMEDOUT;
1896 }
1897 return 0;
1898 }
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913 #ifdef ATW_BBPDEBUG
1914 int
1915 atw_rf3000_read(struct atw_softc *sc, u_int addr, u_int *val)
1916 {
1917 u_int32_t reg;
1918 int i;
1919
1920 for (i = 1000; --i >= 0; ) {
1921 if (ATW_ISSET(sc, ATW_BBPCTL, ATW_BBPCTL_RD|ATW_BBPCTL_WR) == 0)
1922 break;
1923 DELAY(100);
1924 }
1925
1926 if (i < 0) {
1927 printf("%s: start atw_rf3000_read, BBPCTL busy\n",
1928 sc->sc_dev.dv_xname);
1929 return ETIMEDOUT;
1930 }
1931
1932 reg = sc->sc_bbpctl_rd | LSHIFT(addr & 0x7f, ATW_BBPCTL_ADDR_MASK);
1933
1934 ATW_WRITE(sc, ATW_BBPCTL, reg);
1935
1936 for (i = 1000; --i >= 0; ) {
1937 DELAY(100);
1938 if (ATW_ISSET(sc, ATW_BBPCTL, ATW_BBPCTL_RD) == 0)
1939 break;
1940 }
1941
1942 ATW_CLR(sc, ATW_BBPCTL, ATW_BBPCTL_RD);
1943
1944 if (i < 0) {
1945 printf("%s: atw_rf3000_read wrote %08x; BBPCTL still busy\n",
1946 sc->sc_dev.dv_xname, reg);
1947 return ETIMEDOUT;
1948 }
1949 if (val != NULL)
1950 *val = MASK_AND_RSHIFT(reg, ATW_BBPCTL_DATA_MASK);
1951 return 0;
1952 }
1953 #endif
1954
1955
1956
1957
1958
1959
1960
1961
1962 void
1963 atw_si4126_write(struct atw_softc *sc, u_int addr, u_int val)
1964 {
1965 uint32_t bits, mask, reg;
1966 int nbits;
1967
1968 if (sc->sc_rev >= ATW_REVISION_BA) {
1969 nbits = 24;
1970
1971 val &= 0x3ffff;
1972 addr &= 0x1f;
1973 bits = val | (addr << 18);
1974 } else {
1975 nbits = 22;
1976
1977 KASSERT((addr & ~PRESHIFT(SI4126_TWI_ADDR_MASK)) == 0);
1978 KASSERT((val & ~PRESHIFT(SI4126_TWI_DATA_MASK)) == 0);
1979
1980 bits = LSHIFT(val, SI4126_TWI_DATA_MASK) |
1981 LSHIFT(addr, SI4126_TWI_ADDR_MASK);
1982 }
1983
1984 reg = ATW_SYNRF_SELSYN;
1985
1986
1987
1988 ATW_WRITE(sc, ATW_SYNRF, reg | ATW_SYNRF_LEIF);
1989 ATW_WRITE(sc, ATW_SYNRF, reg);
1990
1991 for (mask = BIT(nbits - 1); mask != 0; mask >>= 1) {
1992 if ((bits & mask) != 0)
1993 reg |= ATW_SYNRF_SYNDATA;
1994 else
1995 reg &= ~ATW_SYNRF_SYNDATA;
1996 ATW_WRITE(sc, ATW_SYNRF, reg);
1997 ATW_WRITE(sc, ATW_SYNRF, reg | ATW_SYNRF_SYNCLK);
1998 ATW_WRITE(sc, ATW_SYNRF, reg);
1999 }
2000 ATW_WRITE(sc, ATW_SYNRF, reg | ATW_SYNRF_LEIF);
2001 ATW_WRITE(sc, ATW_SYNRF, 0x0);
2002 }
2003
2004
2005
2006
2007
2008
2009
2010 #ifdef ATW_SYNDEBUG
2011 int
2012 atw_si4126_read(struct atw_softc *sc, u_int addr, u_int *val)
2013 {
2014 u_int32_t reg;
2015 int i;
2016
2017 KASSERT((addr & ~PRESHIFT(SI4126_TWI_ADDR_MASK)) == 0);
2018
2019 for (i = 1000; --i >= 0; ) {
2020 if (ATW_ISSET(sc, ATW_SYNCTL, ATW_SYNCTL_RD|ATW_SYNCTL_WR) == 0)
2021 break;
2022 DELAY(100);
2023 }
2024
2025 if (i < 0) {
2026 printf("%s: start atw_si4126_read, SYNCTL busy\n",
2027 sc->sc_dev.dv_xname);
2028 return ETIMEDOUT;
2029 }
2030
2031 reg = sc->sc_synctl_rd | LSHIFT(addr, ATW_SYNCTL_DATA_MASK);
2032
2033 ATW_WRITE(sc, ATW_SYNCTL, reg);
2034
2035 for (i = 1000; --i >= 0; ) {
2036 DELAY(100);
2037 if (ATW_ISSET(sc, ATW_SYNCTL, ATW_SYNCTL_RD) == 0)
2038 break;
2039 }
2040
2041 ATW_CLR(sc, ATW_SYNCTL, ATW_SYNCTL_RD);
2042
2043 if (i < 0) {
2044 printf("%s: atw_si4126_read wrote %#08x, SYNCTL still busy\n",
2045 sc->sc_dev.dv_xname, reg);
2046 return ETIMEDOUT;
2047 }
2048 if (val != NULL)
2049 *val = MASK_AND_RSHIFT(ATW_READ(sc, ATW_SYNCTL),
2050 ATW_SYNCTL_DATA_MASK);
2051 return 0;
2052 }
2053 #endif
2054
2055
2056 #define atw_calchash(addr) \
2057 (ether_crc32_le((addr), IEEE80211_ADDR_LEN) & BITS(5, 0))
2058
2059
2060
2061
2062
2063
2064 void
2065 atw_filter_setup(struct atw_softc *sc)
2066 {
2067 struct ieee80211com *ic = &sc->sc_ic;
2068 #if defined(__OpenBSD__)
2069 struct arpcom *ec = &ic->ic_ac;
2070 #else
2071 struct ethercom *ec = &ic->ic_ec;
2072 #endif
2073 struct ifnet *ifp = &sc->sc_ic.ic_if;
2074 int hash;
2075 u_int32_t hashes[2];
2076 struct ether_multi *enm;
2077 struct ether_multistep step;
2078
2079
2080
2081
2082
2083
2084 if ((ifp->if_flags & IFF_RUNNING) != 0)
2085 atw_idle(sc, ATW_NAR_SR);
2086
2087 sc->sc_opmode &= ~(ATW_NAR_PR|ATW_NAR_MM);
2088
2089
2090
2091
2092 if (ic->ic_state == IEEE80211_S_SCAN ||
2093 (ifp->if_flags & IFF_PROMISC) != 0) {
2094 sc->sc_opmode |= ATW_NAR_PR;
2095 goto allmulti;
2096 }
2097
2098 hashes[0] = hashes[1] = 0x0;
2099
2100
2101
2102
2103 ETHER_FIRST_MULTI(step, ec, enm);
2104 while (enm != NULL) {
2105 if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
2106 ETHER_ADDR_LEN) != 0)
2107 goto allmulti;
2108
2109 hash = atw_calchash(enm->enm_addrlo);
2110 hashes[hash >> 5] |= 1 << (hash & 0x1f);
2111 ETHER_NEXT_MULTI(step, enm);
2112 sc->sc_opmode |= ATW_NAR_MM;
2113 }
2114 ifp->if_flags &= ~IFF_ALLMULTI;
2115 goto setit;
2116
2117 allmulti:
2118 sc->sc_opmode |= ATW_NAR_MM;
2119 ifp->if_flags |= IFF_ALLMULTI;
2120 hashes[0] = hashes[1] = 0xffffffff;
2121
2122 setit:
2123 ATW_WRITE(sc, ATW_MAR0, hashes[0]);
2124 ATW_WRITE(sc, ATW_MAR1, hashes[1]);
2125 ATW_WRITE(sc, ATW_NAR, sc->sc_opmode);
2126 DELAY(20 * 1000);
2127 ATW_WRITE(sc, ATW_RDR, 0x1);
2128
2129 DPRINTF(sc, ("%s: ATW_NAR %08x opmode %08x\n", sc->sc_dev.dv_xname,
2130 ATW_READ(sc, ATW_NAR), sc->sc_opmode));
2131 }
2132
2133
2134
2135
2136
2137
2138
2139 void
2140 atw_write_bssid(struct atw_softc *sc)
2141 {
2142 struct ieee80211com *ic = &sc->sc_ic;
2143 u_int8_t *bssid;
2144
2145 bssid = ic->ic_bss->ni_bssid;
2146
2147 ATW_WRITE(sc, ATW_BSSID0,
2148 LSHIFT(bssid[0], ATW_BSSID0_BSSIDB0_MASK) |
2149 LSHIFT(bssid[1], ATW_BSSID0_BSSIDB1_MASK) |
2150 LSHIFT(bssid[2], ATW_BSSID0_BSSIDB2_MASK) |
2151 LSHIFT(bssid[3], ATW_BSSID0_BSSIDB3_MASK));
2152
2153 ATW_WRITE(sc, ATW_ABDA1,
2154 (ATW_READ(sc, ATW_ABDA1) &
2155 ~(ATW_ABDA1_BSSIDB4_MASK|ATW_ABDA1_BSSIDB5_MASK)) |
2156 LSHIFT(bssid[4], ATW_ABDA1_BSSIDB4_MASK) |
2157 LSHIFT(bssid[5], ATW_ABDA1_BSSIDB5_MASK));
2158
2159 DPRINTF(sc, ("%s: BSSID %s -> ", sc->sc_dev.dv_xname,
2160 ether_sprintf(sc->sc_bssid)));
2161 DPRINTF(sc, ("%s\n", ether_sprintf(bssid)));
2162
2163 memcpy(sc->sc_bssid, bssid, sizeof(sc->sc_bssid));
2164 }
2165
2166
2167
2168
2169 void
2170 atw_write_sram(struct atw_softc *sc, u_int ofs, u_int8_t *buf, u_int buflen)
2171 {
2172 u_int i;
2173 u_int8_t *ptr;
2174
2175 memcpy(&sc->sc_sram[ofs], buf, buflen);
2176
2177 KASSERT(ofs % 2 == 0 && buflen % 2 == 0);
2178
2179 KASSERT(buflen + ofs <= sc->sc_sramlen);
2180
2181 ptr = &sc->sc_sram[ofs];
2182
2183 for (i = 0; i < buflen; i += 2) {
2184 ATW_WRITE(sc, ATW_WEPCTL, ATW_WEPCTL_WR |
2185 LSHIFT((ofs + i) / 2, ATW_WEPCTL_TBLADD_MASK));
2186 DELAY(atw_writewep_delay);
2187
2188 ATW_WRITE(sc, ATW_WESK,
2189 LSHIFT((ptr[i + 1] << 8) | ptr[i], ATW_WESK_DATA_MASK));
2190 DELAY(atw_writewep_delay);
2191 }
2192 ATW_WRITE(sc, ATW_WEPCTL, sc->sc_wepctl);
2193
2194 if (sc->sc_if.if_flags & IFF_DEBUG) {
2195 int n_octets = 0;
2196 printf("%s: wrote %d bytes at 0x%x wepctl 0x%08x\n",
2197 sc->sc_dev.dv_xname, buflen, ofs, sc->sc_wepctl);
2198 for (i = 0; i < buflen; i++) {
2199 printf(" %02x", ptr[i]);
2200 if (++n_octets % 24 == 0)
2201 printf("\n");
2202 }
2203 if (n_octets % 24 != 0)
2204 printf("\n");
2205 }
2206 }
2207
2208
2209 void
2210 atw_write_wep(struct atw_softc *sc)
2211 {
2212 struct ieee80211com *ic = &sc->sc_ic;
2213 #if 0
2214 u_int32_t reg;
2215 int i;
2216 #endif
2217
2218 u_int8_t buf[IEEE80211_WEP_NKID]
2219 [1 + 1 + 12 ];
2220
2221 sc->sc_wepctl = 0;
2222 ATW_WRITE(sc, ATW_WEPCTL, sc->sc_wepctl);
2223
2224 if ((ic->ic_flags & IEEE80211_F_WEPON) == 0)
2225 return;
2226
2227 memset(&buf[0][0], 0, sizeof(buf));
2228
2229 #if 0
2230 for (i = 0; i < IEEE80211_WEP_NKID; i++) {
2231 if (ic->ic_nw_keys[i].k_len > 5) {
2232 buf[i][1] = ATW_WEP_ENABLED | ATW_WEP_104BIT;
2233 } else if (ic->ic_nw_keys[i].k_len != 0) {
2234 buf[i][1] = ATW_WEP_ENABLED;
2235 } else {
2236 buf[i][1] = 0;
2237 continue;
2238 }
2239 buf[i][0] = ic->ic_nw_keys[i].k_key[0];
2240 memcpy(&buf[i][2], &ic->ic_nw_keys[i].k_key[1],
2241 ic->ic_nw_keys[i].k_len - 1);
2242 }
2243
2244 reg = ATW_READ(sc, ATW_MACTEST);
2245 reg |= ATW_MACTEST_MMI_USETXCLK | ATW_MACTEST_FORCE_KEYID;
2246 reg &= ~ATW_MACTEST_KEYID_MASK;
2247 reg |= LSHIFT(ic->ic_wep_txkey, ATW_MACTEST_KEYID_MASK);
2248 ATW_WRITE(sc, ATW_MACTEST, reg);
2249
2250 sc->sc_wepctl = ATW_WEPCTL_WEPENABLE;
2251
2252 switch (sc->sc_rev) {
2253 case ATW_REVISION_AB:
2254 case ATW_REVISION_AF:
2255
2256 sc->sc_wepctl |= ATW_WEPCTL_WEPRXBYP;
2257 break;
2258 default:
2259 break;
2260 }
2261 #endif
2262
2263 atw_write_sram(sc, ATW_SRAM_ADDR_SHARED_KEY, (u_int8_t*)&buf[0][0],
2264 sizeof(buf));
2265 }
2266
2267 void
2268 atw_change_ibss(struct atw_softc *sc)
2269 {
2270 atw_predict_beacon(sc);
2271 atw_write_bssid(sc);
2272 atw_start_beacon(sc, 1);
2273 }
2274
2275 void
2276 atw_recv_mgmt(struct ieee80211com *ic, struct mbuf *m,
2277 struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp)
2278 {
2279 struct atw_softc *sc = (struct atw_softc*)ic->ic_softc;
2280
2281
2282 if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_REQ &&
2283 sc->sc_rev < ATW_REVISION_BA)
2284 return;
2285
2286 (*sc->sc_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp);
2287
2288 switch (subtype) {
2289 case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
2290 case IEEE80211_FC0_SUBTYPE_BEACON:
2291 if (ic->ic_opmode != IEEE80211_M_IBSS ||
2292 ic->ic_state != IEEE80211_S_RUN)
2293 break;
2294 if (ieee80211_ibss_merge(ic, ni, atw_get_tsft(sc)) == ENETRESET)
2295 atw_change_ibss(sc);
2296 break;
2297 default:
2298 break;
2299 }
2300 return;
2301 }
2302
2303
2304
2305
2306
2307
2308
2309 void
2310 atw_write_ssid(struct atw_softc *sc)
2311 {
2312 struct ieee80211com *ic = &sc->sc_ic;
2313
2314
2315
2316 u_int8_t buf[roundup(1 + IEEE80211_NWID_LEN, 2)];
2317
2318 memset(buf, 0, sizeof(buf));
2319 buf[0] = ic->ic_bss->ni_esslen;
2320 memcpy(&buf[1], ic->ic_bss->ni_essid, ic->ic_bss->ni_esslen);
2321
2322 atw_write_sram(sc, ATW_SRAM_ADDR_SSID, buf,
2323 roundup(1 + ic->ic_bss->ni_esslen, 2));
2324 }
2325
2326
2327
2328
2329
2330 void
2331 atw_write_sup_rates(struct atw_softc *sc)
2332 {
2333 struct ieee80211com *ic = &sc->sc_ic;
2334
2335
2336
2337 u_int8_t buf[roundup(1 + IEEE80211_RATE_SIZE, 2)];
2338
2339 memset(buf, 0, sizeof(buf));
2340 buf[0] = ic->ic_bss->ni_rates.rs_nrates;
2341 memcpy(&buf[1], ic->ic_bss->ni_rates.rs_rates,
2342 ic->ic_bss->ni_rates.rs_nrates);
2343
2344
2345
2346 atw_write_sram(sc, ATW_SRAM_ADDR_SUPRATES, buf, sizeof(buf));
2347 }
2348
2349
2350 void
2351 atw_start_beacon(struct atw_softc *sc, int start)
2352 {
2353 struct ieee80211com *ic = &sc->sc_ic;
2354 uint16_t chan;
2355 uint32_t bcnt, bpli, cap0, cap1, capinfo;
2356 size_t len;
2357
2358 if (ATW_IS_ENABLED(sc) == 0)
2359 return;
2360
2361
2362 len = sizeof(struct ieee80211_frame) +
2363 8 + 2 +
2364 2 +
2365 2 + ic->ic_bss->ni_esslen +
2366 2 + ic->ic_bss->ni_rates.rs_nrates +
2367 3 +
2368 IEEE80211_CRC_LEN;
2369
2370 bcnt = ATW_READ(sc, ATW_BCNT) & ~ATW_BCNT_BCNT_MASK;
2371 cap0 = ATW_READ(sc, ATW_CAP0) & ~ATW_CAP0_CHN_MASK;
2372 cap1 = ATW_READ(sc, ATW_CAP1) & ~ATW_CAP1_CAPI_MASK;
2373
2374 ATW_WRITE(sc, ATW_BCNT, bcnt);
2375 ATW_WRITE(sc, ATW_CAP1, cap1);
2376
2377 if (!start)
2378 return;
2379
2380
2381
2382 capinfo = 0;
2383 if (sc->sc_flags & ATWF_SHORT_PREAMBLE)
2384 capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
2385 if (ic->ic_flags & IEEE80211_F_WEPON)
2386 capinfo |= IEEE80211_CAPINFO_PRIVACY;
2387
2388 switch (ic->ic_opmode) {
2389 case IEEE80211_M_IBSS:
2390 len += 4;
2391 capinfo |= IEEE80211_CAPINFO_IBSS;
2392 break;
2393 case IEEE80211_M_HOSTAP:
2394
2395 len += atw_beacon_len_adjust;
2396 capinfo |= IEEE80211_CAPINFO_ESS;
2397 break;
2398 default:
2399 return;
2400 }
2401
2402
2403
2404
2405 bpli = LSHIFT(ic->ic_bss->ni_intval, ATW_BPLI_BP_MASK) |
2406 LSHIFT(ic->ic_lintval / ic->ic_bss->ni_intval, ATW_BPLI_LI_MASK);
2407
2408 chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
2409
2410 bcnt |= LSHIFT(len, ATW_BCNT_BCNT_MASK);
2411 cap0 |= LSHIFT(chan, ATW_CAP0_CHN_MASK);
2412 cap1 |= LSHIFT(capinfo, ATW_CAP1_CAPI_MASK);
2413
2414 ATW_WRITE(sc, ATW_BCNT, bcnt);
2415 ATW_WRITE(sc, ATW_BPLI, bpli);
2416 ATW_WRITE(sc, ATW_CAP0, cap0);
2417 ATW_WRITE(sc, ATW_CAP1, cap1);
2418
2419 DPRINTF(sc, ("%s: atw_start_beacon reg[ATW_BCNT] = %08x\n",
2420 sc->sc_dev.dv_xname, bcnt));
2421 DPRINTF(sc, ("%s: atw_start_beacon reg[ATW_CAP1] = %08x\n",
2422 sc->sc_dev.dv_xname, cap1));
2423 }
2424
2425
2426 static __inline uint32_t
2427 atw_last_even_tsft(uint32_t tsfth, uint32_t tsftl, uint32_t ival)
2428 {
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442 return ((0xFFFFFFFF % ival + 1) * tsfth + tsftl) % ival;
2443 }
2444
2445 uint64_t
2446 atw_get_tsft(struct atw_softc *sc)
2447 {
2448 int i;
2449 uint32_t tsfth, tsftl;
2450 for (i = 0; i < 2; i++) {
2451 tsfth = ATW_READ(sc, ATW_TSFTH);
2452 tsftl = ATW_READ(sc, ATW_TSFTL);
2453 if (ATW_READ(sc, ATW_TSFTH) == tsfth)
2454 break;
2455 }
2456 return ((uint64_t)tsfth << 32) | tsftl;
2457 }
2458
2459
2460
2461
2462
2463
2464
2465 void
2466 atw_predict_beacon(struct atw_softc *sc)
2467 {
2468 #define TBTTOFS 20
2469
2470 struct ieee80211com *ic = &sc->sc_ic;
2471 uint64_t tsft;
2472 uint32_t ival, past_even, tbtt, tsfth, tsftl;
2473 union {
2474 uint64_t word;
2475 uint8_t tstamp[8];
2476 } u;
2477
2478 if ((ic->ic_opmode == IEEE80211_M_HOSTAP) ||
2479 ((ic->ic_opmode == IEEE80211_M_IBSS) &&
2480 (ic->ic_flags & IEEE80211_F_SIBSS))) {
2481 tsft = atw_get_tsft(sc);
2482 u.word = htole64(tsft);
2483 (void)memcpy(&ic->ic_bss->ni_tstamp[0], &u.tstamp[0],
2484 sizeof(ic->ic_bss->ni_tstamp));
2485 } else {
2486 (void)memcpy(&u, &ic->ic_bss->ni_tstamp[0], sizeof(u));
2487 tsft = letoh64(u.word);
2488 }
2489
2490 ival = ic->ic_bss->ni_intval * IEEE80211_DUR_TU;
2491
2492 tsftl = tsft & 0xFFFFFFFF;
2493 tsfth = tsft >> 32;
2494
2495
2496
2497
2498 past_even = tsftl - atw_last_even_tsft(tsfth, tsftl, ival);
2499
2500
2501
2502
2503 tbtt = past_even + ival * 10;
2504
2505 ATW_WRITE(sc, ATW_TOFS1,
2506 LSHIFT(1, ATW_TOFS1_TSFTOFSR_MASK) |
2507 LSHIFT(TBTTOFS, ATW_TOFS1_TBTTOFS_MASK) |
2508 LSHIFT(MASK_AND_RSHIFT(tbtt - TBTTOFS * IEEE80211_DUR_TU,
2509 ATW_TBTTPRE_MASK), ATW_TOFS1_TBTTPRE_MASK));
2510 #undef TBTTOFS
2511 }
2512
2513 void
2514 atw_next_scan(void *arg)
2515 {
2516 struct atw_softc *sc = arg;
2517 struct ieee80211com *ic = &sc->sc_ic;
2518 struct ifnet *ifp = &ic->ic_if;
2519 int s;
2520
2521
2522 s = splnet();
2523 if (ic->ic_state == IEEE80211_S_SCAN)
2524 ieee80211_next_scan(ifp);
2525 splx(s);
2526 }
2527
2528
2529 int
2530 atw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
2531 {
2532 struct ifnet *ifp = &ic->ic_if;
2533 struct atw_softc *sc = ifp->if_softc;
2534 enum ieee80211_state ostate = ic->ic_state;
2535 int error;
2536
2537 if (nstate == IEEE80211_S_INIT) {
2538 timeout_del(&sc->sc_scan_to);
2539 sc->sc_cur_chan = IEEE80211_CHAN_ANY;
2540 atw_start_beacon(sc, 0);
2541 return (*sc->sc_newstate)(ic, nstate, arg);
2542 }
2543
2544 if ((error = atw_tune(sc)) != 0)
2545 return error;
2546
2547 switch (nstate) {
2548 case IEEE80211_S_ASSOC:
2549 break;
2550 case IEEE80211_S_INIT:
2551 panic("%s: unexpected state IEEE80211_S_INIT", __func__);
2552 break;
2553 case IEEE80211_S_SCAN:
2554 timeout_add(&sc->sc_scan_to, atw_dwelltime * hz / 1000);
2555 break;
2556 case IEEE80211_S_RUN:
2557 if (ic->ic_opmode == IEEE80211_M_STA)
2558 break;
2559
2560 case IEEE80211_S_AUTH:
2561 atw_write_bssid(sc);
2562 atw_write_ssid(sc);
2563 atw_write_sup_rates(sc);
2564
2565 if (ic->ic_opmode == IEEE80211_M_AHDEMO ||
2566 ic->ic_opmode == IEEE80211_M_MONITOR)
2567 break;
2568
2569
2570
2571
2572 ATW_WRITE(sc, ATW_BPLI,
2573 LSHIFT(ic->ic_bss->ni_intval, ATW_BPLI_BP_MASK) |
2574 LSHIFT(ic->ic_lintval / ic->ic_bss->ni_intval,
2575 ATW_BPLI_LI_MASK));
2576
2577 DPRINTF(sc, ("%s: reg[ATW_BPLI] = %08x\n",
2578 sc->sc_dev.dv_xname, ATW_READ(sc, ATW_BPLI)));
2579
2580 atw_predict_beacon(sc);
2581 break;
2582 }
2583
2584 if (nstate != IEEE80211_S_SCAN)
2585 timeout_del(&sc->sc_scan_to);
2586
2587 if (nstate == IEEE80211_S_RUN &&
2588 (ic->ic_opmode == IEEE80211_M_HOSTAP ||
2589 ic->ic_opmode == IEEE80211_M_IBSS))
2590 atw_start_beacon(sc, 1);
2591 else
2592 atw_start_beacon(sc, 0);
2593
2594 error = (*sc->sc_newstate)(ic, nstate, arg);
2595
2596 if (ostate == IEEE80211_S_INIT && nstate == IEEE80211_S_SCAN)
2597 atw_write_bssid(sc);
2598
2599 return error;
2600 }
2601
2602
2603
2604
2605
2606
2607 int
2608 atw_add_rxbuf(struct atw_softc *sc, int idx)
2609 {
2610 struct atw_rxsoft *rxs = &sc->sc_rxsoft[idx];
2611 struct mbuf *m;
2612 int error;
2613
2614 MGETHDR(m, M_DONTWAIT, MT_DATA);
2615 if (m == NULL)
2616 return (ENOBUFS);
2617
2618 MCLGET(m, M_DONTWAIT);
2619 if ((m->m_flags & M_EXT) == 0) {
2620 m_freem(m);
2621 return (ENOBUFS);
2622 }
2623
2624 if (rxs->rxs_mbuf != NULL)
2625 bus_dmamap_unload(sc->sc_dmat, rxs->rxs_dmamap);
2626
2627 rxs->rxs_mbuf = m;
2628
2629 error = bus_dmamap_load(sc->sc_dmat, rxs->rxs_dmamap,
2630 m->m_ext.ext_buf, m->m_ext.ext_size, NULL,
2631 BUS_DMA_READ|BUS_DMA_NOWAIT);
2632 if (error) {
2633 printf("%s: can't load rx DMA map %d, error = %d\n",
2634 sc->sc_dev.dv_xname, idx, error);
2635 panic("atw_add_rxbuf");
2636 }
2637
2638 bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
2639 rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
2640
2641 ATW_INIT_RXDESC(sc, idx);
2642
2643 return (0);
2644 }
2645
2646
2647
2648
2649 void
2650 atw_txdrain(struct atw_softc *sc)
2651 {
2652 struct atw_txsoft *txs;
2653
2654 while ((txs = SIMPLEQ_FIRST(&sc->sc_txdirtyq)) != NULL) {
2655 SIMPLEQ_REMOVE_HEAD(&sc->sc_txdirtyq, txs_q);
2656 if (txs->txs_mbuf != NULL) {
2657 bus_dmamap_unload(sc->sc_dmat, txs->txs_dmamap);
2658 m_freem(txs->txs_mbuf);
2659 txs->txs_mbuf = NULL;
2660 }
2661 SIMPLEQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q);
2662 }
2663 sc->sc_tx_timer = 0;
2664 }
2665
2666
2667
2668
2669
2670
2671 void
2672 atw_stop(struct ifnet *ifp, int disable)
2673 {
2674 struct atw_softc *sc = ifp->if_softc;
2675 struct ieee80211com *ic = &sc->sc_ic;
2676
2677 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
2678
2679
2680
2681
2682 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
2683 ifp->if_timer = 0;
2684
2685
2686 ATW_WRITE(sc, ATW_IER, 0);
2687
2688
2689 sc->sc_opmode = 0;
2690 ATW_WRITE(sc, ATW_NAR, 0);
2691 DELAY(20 * 1000);
2692 ATW_WRITE(sc, ATW_TDBD, 0);
2693 ATW_WRITE(sc, ATW_TDBP, 0);
2694 ATW_WRITE(sc, ATW_RDB, 0);
2695
2696 atw_txdrain(sc);
2697
2698 if (disable) {
2699 atw_rxdrain(sc);
2700 atw_disable(sc);
2701 }
2702
2703 if (!disable)
2704 atw_reset(sc);
2705 }
2706
2707
2708
2709
2710
2711
2712 void
2713 atw_rxdrain(struct atw_softc *sc)
2714 {
2715 struct atw_rxsoft *rxs;
2716 int i;
2717
2718 for (i = 0; i < ATW_NRXDESC; i++) {
2719 rxs = &sc->sc_rxsoft[i];
2720 if (rxs->rxs_mbuf == NULL)
2721 continue;
2722 bus_dmamap_unload(sc->sc_dmat, rxs->rxs_dmamap);
2723 m_freem(rxs->rxs_mbuf);
2724 rxs->rxs_mbuf = NULL;
2725 }
2726 }
2727
2728
2729
2730
2731
2732
2733 int
2734 atw_detach(struct atw_softc *sc)
2735 {
2736 struct ifnet *ifp = &sc->sc_ic.ic_if;
2737 struct atw_rxsoft *rxs;
2738 struct atw_txsoft *txs;
2739 int i;
2740
2741
2742
2743
2744 if ((sc->sc_flags & ATWF_ATTACHED) == 0)
2745 return (0);
2746
2747 timeout_del(&sc->sc_scan_to);
2748
2749 ieee80211_ifdetach(ifp);
2750 if_detach(ifp);
2751
2752 for (i = 0; i < ATW_NRXDESC; i++) {
2753 rxs = &sc->sc_rxsoft[i];
2754 if (rxs->rxs_mbuf != NULL) {
2755 bus_dmamap_unload(sc->sc_dmat, rxs->rxs_dmamap);
2756 m_freem(rxs->rxs_mbuf);
2757 rxs->rxs_mbuf = NULL;
2758 }
2759 bus_dmamap_destroy(sc->sc_dmat, rxs->rxs_dmamap);
2760 }
2761 for (i = 0; i < ATW_TXQUEUELEN; i++) {
2762 txs = &sc->sc_txsoft[i];
2763 if (txs->txs_mbuf != NULL) {
2764 bus_dmamap_unload(sc->sc_dmat, txs->txs_dmamap);
2765 m_freem(txs->txs_mbuf);
2766 txs->txs_mbuf = NULL;
2767 }
2768 bus_dmamap_destroy(sc->sc_dmat, txs->txs_dmamap);
2769 }
2770 bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
2771 bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
2772 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_control_data,
2773 sizeof(struct atw_control_data));
2774 bus_dmamem_free(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg);
2775
2776 if (sc->sc_sdhook != NULL)
2777 shutdownhook_disestablish(sc->sc_sdhook);
2778 if (sc->sc_powerhook != NULL)
2779 powerhook_disestablish(sc->sc_powerhook);
2780
2781 if (sc->sc_srom)
2782 free(sc->sc_srom, M_DEVBUF);
2783
2784 return (0);
2785 }
2786
2787
2788 void
2789 atw_shutdown(void *arg)
2790 {
2791 struct atw_softc *sc = arg;
2792
2793 atw_stop(&sc->sc_ic.ic_if, 1);
2794 }
2795
2796 int
2797 atw_intr(void *arg)
2798 {
2799 struct atw_softc *sc = arg;
2800 struct ifnet *ifp = &sc->sc_ic.ic_if;
2801 u_int32_t status, rxstatus, txstatus, linkstatus;
2802 int handled = 0, txthresh;
2803
2804 #ifdef DEBUG
2805 if (ATW_IS_ENABLED(sc) == 0)
2806 panic("%s: atw_intr: not enabled", sc->sc_dev.dv_xname);
2807 #endif
2808
2809
2810
2811
2812
2813 if ((ifp->if_flags & IFF_RUNNING) == 0 ||
2814 (sc->sc_dev.dv_flags & DVF_ACTIVE) == 0)
2815 return (0);
2816
2817 for (;;) {
2818 status = ATW_READ(sc, ATW_STSR);
2819
2820 if (status)
2821 ATW_WRITE(sc, ATW_STSR, status);
2822
2823 #ifdef ATW_DEBUG
2824 #define PRINTINTR(flag) do { \
2825 if ((status & flag) != 0) { \
2826 printf("%s" #flag, delim); \
2827 delim = ","; \
2828 } \
2829 } while (0)
2830
2831 if (atw_debug > 1 && status) {
2832 const char *delim = "<";
2833
2834 printf("%s: reg[STSR] = %x",
2835 sc->sc_dev.dv_xname, status);
2836
2837 PRINTINTR(ATW_INTR_FBE);
2838 PRINTINTR(ATW_INTR_LINKOFF);
2839 PRINTINTR(ATW_INTR_LINKON);
2840 PRINTINTR(ATW_INTR_RCI);
2841 PRINTINTR(ATW_INTR_RDU);
2842 PRINTINTR(ATW_INTR_REIS);
2843 PRINTINTR(ATW_INTR_RPS);
2844 PRINTINTR(ATW_INTR_TCI);
2845 PRINTINTR(ATW_INTR_TDU);
2846 PRINTINTR(ATW_INTR_TLT);
2847 PRINTINTR(ATW_INTR_TPS);
2848 PRINTINTR(ATW_INTR_TRT);
2849 PRINTINTR(ATW_INTR_TUF);
2850 PRINTINTR(ATW_INTR_BCNTC);
2851 PRINTINTR(ATW_INTR_ATIME);
2852 PRINTINTR(ATW_INTR_TBTT);
2853 PRINTINTR(ATW_INTR_TSCZ);
2854 PRINTINTR(ATW_INTR_TSFTF);
2855 printf(">\n");
2856 }
2857 #undef PRINTINTR
2858 #endif
2859
2860 if ((status & sc->sc_inten) == 0)
2861 break;
2862
2863 handled = 1;
2864
2865 rxstatus = status & sc->sc_rxint_mask;
2866 txstatus = status & sc->sc_txint_mask;
2867 linkstatus = status & sc->sc_linkint_mask;
2868
2869 if (linkstatus) {
2870 atw_linkintr(sc, linkstatus);
2871 }
2872
2873 if (rxstatus) {
2874
2875 atw_rxintr(sc);
2876
2877 if (rxstatus & ATW_INTR_RDU) {
2878 printf("%s: receive ring overrun\n",
2879 sc->sc_dev.dv_xname);
2880
2881 ATW_WRITE(sc, ATW_RDR, 0x1);
2882 break;
2883 }
2884 }
2885
2886 if (txstatus) {
2887
2888 atw_txintr(sc);
2889
2890 if (txstatus & ATW_INTR_TLT)
2891 DPRINTF(sc, ("%s: tx lifetime exceeded\n",
2892 sc->sc_dev.dv_xname));
2893
2894 if (txstatus & ATW_INTR_TRT)
2895 DPRINTF(sc, ("%s: tx retry limit exceeded\n",
2896 sc->sc_dev.dv_xname));
2897
2898
2899
2900
2901 txthresh = sc->sc_txthresh + 1;
2902 if ((txstatus & ATW_INTR_TUF) &&
2903 sc->sc_txth[txthresh].txth_name != NULL) {
2904
2905 atw_idle(sc, ATW_NAR_ST);
2906
2907 sc->sc_txthresh = txthresh;
2908 sc->sc_opmode &= ~(ATW_NAR_TR_MASK|ATW_NAR_SF);
2909 sc->sc_opmode |=
2910 sc->sc_txth[txthresh].txth_opmode;
2911 printf("%s: transmit underrun; new "
2912 "threshold: %s\n", sc->sc_dev.dv_xname,
2913 sc->sc_txth[txthresh].txth_name);
2914
2915
2916
2917
2918 ATW_WRITE(sc, ATW_NAR, sc->sc_opmode);
2919 DELAY(20 * 1000);
2920 ATW_WRITE(sc, ATW_RDR, 0x1);
2921
2922
2923
2924 }
2925 }
2926
2927 if (status & (ATW_INTR_TPS|ATW_INTR_RPS)) {
2928 if (status & ATW_INTR_TPS)
2929 printf("%s: transmit process stopped\n",
2930 sc->sc_dev.dv_xname);
2931 if (status & ATW_INTR_RPS)
2932 printf("%s: receive process stopped\n",
2933 sc->sc_dev.dv_xname);
2934 (void)atw_init(ifp);
2935 break;
2936 }
2937
2938 if (status & ATW_INTR_FBE) {
2939 printf("%s: fatal bus error\n", sc->sc_dev.dv_xname);
2940 (void)atw_init(ifp);
2941 break;
2942 }
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957 }
2958
2959
2960 atw_start(ifp);
2961
2962 return (handled);
2963 }
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976 void
2977 atw_idle(struct atw_softc *sc, u_int32_t bits)
2978 {
2979 u_int32_t ackmask = 0, opmode, stsr, test0;
2980 int i, s;
2981
2982 s = splnet();
2983
2984 opmode = sc->sc_opmode & ~bits;
2985
2986 if (bits & ATW_NAR_SR)
2987 ackmask |= ATW_INTR_RPS;
2988
2989 if (bits & ATW_NAR_ST) {
2990 ackmask |= ATW_INTR_TPS;
2991
2992 opmode |= ATW_NAR_HF;
2993 }
2994
2995 ATW_WRITE(sc, ATW_NAR, opmode);
2996 DELAY(20 * 1000);
2997
2998 for (i = 0; i < 10; i++) {
2999 stsr = ATW_READ(sc, ATW_STSR);
3000 if ((stsr & ackmask) == ackmask)
3001 break;
3002 DELAY(1000);
3003 }
3004
3005 ATW_WRITE(sc, ATW_STSR, stsr & ackmask);
3006
3007 if ((stsr & ackmask) == ackmask)
3008 goto out;
3009
3010 test0 = ATW_READ(sc, ATW_TEST0);
3011
3012 if ((bits & ATW_NAR_ST) != 0 && (stsr & ATW_INTR_TPS) == 0 &&
3013 (test0 & ATW_TEST0_TS_MASK) != ATW_TEST0_TS_STOPPED) {
3014 DPRINTF2(sc, ("%s: transmit process not idle [%s]\n",
3015 sc->sc_dev.dv_xname,
3016 atw_tx_state[MASK_AND_RSHIFT(test0, ATW_TEST0_TS_MASK)]));
3017 DPRINTF2(sc, ("%s: bits %08x test0 %08x stsr %08x\n",
3018 sc->sc_dev.dv_xname, bits, test0, stsr));
3019 }
3020
3021 if ((bits & ATW_NAR_SR) != 0 && (stsr & ATW_INTR_RPS) == 0 &&
3022 (test0 & ATW_TEST0_RS_MASK) != ATW_TEST0_RS_STOPPED) {
3023 DPRINTF2(sc, ("%s: receive process not idle [%s]\n",
3024 sc->sc_dev.dv_xname,
3025 atw_rx_state[MASK_AND_RSHIFT(test0, ATW_TEST0_RS_MASK)]));
3026 DPRINTF2(sc, ("%s: bits %08x test0 %08x stsr %08x\n",
3027 sc->sc_dev.dv_xname, bits, test0, stsr));
3028 }
3029 out:
3030 if ((bits & ATW_NAR_ST) != 0)
3031 atw_txdrain(sc);
3032 splx(s);
3033 return;
3034 }
3035
3036
3037
3038
3039
3040
3041 void
3042 atw_linkintr(struct atw_softc *sc, u_int32_t linkstatus)
3043 {
3044 struct ieee80211com *ic = &sc->sc_ic;
3045
3046 if (ic->ic_state != IEEE80211_S_RUN)
3047 return;
3048
3049 if (linkstatus & ATW_INTR_LINKON) {
3050 DPRINTF(sc, ("%s: link on\n", sc->sc_dev.dv_xname));
3051 sc->sc_rescan_timer = 0;
3052 } else if (linkstatus & ATW_INTR_LINKOFF) {
3053 DPRINTF(sc, ("%s: link off\n", sc->sc_dev.dv_xname));
3054 if (ic->ic_opmode != IEEE80211_M_STA)
3055 return;
3056 sc->sc_rescan_timer = 3;
3057 ic->ic_if.if_timer = 1;
3058 }
3059 }
3060
3061 static __inline int
3062 atw_hw_decrypted(struct atw_softc *sc, struct ieee80211_frame *wh)
3063 {
3064 if ((sc->sc_ic.ic_flags & IEEE80211_F_WEPON) == 0)
3065 return 0;
3066 if ((wh->i_fc[1] & IEEE80211_FC1_WEP) == 0)
3067 return 0;
3068 return (sc->sc_wepctl & ATW_WEPCTL_WEPRXBYP) == 0;
3069 }
3070
3071
3072
3073
3074
3075
3076 void
3077 atw_rxintr(struct atw_softc *sc)
3078 {
3079 static int rate_tbl[] = {2, 4, 11, 22, 44};
3080 struct ieee80211com *ic = &sc->sc_ic;
3081 struct ieee80211_node *ni;
3082 struct ieee80211_frame *wh;
3083 struct ifnet *ifp = &ic->ic_if;
3084 struct atw_rxsoft *rxs;
3085 struct mbuf *m;
3086 u_int32_t rxstat;
3087 int i, len, rate, rate0;
3088 u_int32_t rssi, rssi0;
3089
3090 for (i = sc->sc_rxptr;; i = ATW_NEXTRX(i)) {
3091 rxs = &sc->sc_rxsoft[i];
3092
3093 ATW_CDRXSYNC(sc, i, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
3094
3095 rxstat = letoh32(sc->sc_rxdescs[i].ar_stat);
3096 rssi0 = letoh32(sc->sc_rxdescs[i].ar_rssi);
3097 rate0 = MASK_AND_RSHIFT(rxstat, ATW_RXSTAT_RXDR_MASK);
3098
3099 if (rxstat & ATW_RXSTAT_OWN)
3100 break;
3101
3102 DPRINTF3(sc,
3103 ("%s: rx stat %08x rssi0 %08x buf1 %08x buf2 %08x\n",
3104 sc->sc_dev.dv_xname,
3105 rxstat, rssi0,
3106 letoh32(sc->sc_rxdescs[i].ar_buf1),
3107 letoh32(sc->sc_rxdescs[i].ar_buf2)));
3108
3109
3110
3111
3112
3113 if ((rxstat & (ATW_RXSTAT_FS|ATW_RXSTAT_LS)) !=
3114 (ATW_RXSTAT_FS|ATW_RXSTAT_LS)) {
3115 printf("%s: incoming packet spilled, resetting\n",
3116 sc->sc_dev.dv_xname);
3117 (void)atw_init(ifp);
3118 return;
3119 }
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129 if ((rxstat & ATW_RXSTAT_ES) != 0 &&
3130 #if defined(__OpenBSD__)
3131 ((sc->sc_ic.ic_if.if_capabilities & IFCAP_VLAN_MTU) == 0 ||
3132 #else
3133 ((sc->sc_ic.ic_ec.ec_capenable & ETHERCAP_VLAN_MTU) == 0 ||
3134 #endif
3135 (rxstat & (ATW_RXSTAT_DE | ATW_RXSTAT_SFDE |
3136 ATW_RXSTAT_SIGE | ATW_RXSTAT_CRC16E |
3137 ATW_RXSTAT_RXTOE | ATW_RXSTAT_CRC32E |
3138 ATW_RXSTAT_ICVE)) != 0)) {
3139 #define PRINTERR(bit, str) \
3140 if (rxstat & (bit)) \
3141 printf("%s: receive error: %s\n", \
3142 sc->sc_dev.dv_xname, str)
3143 ifp->if_ierrors++;
3144 PRINTERR(ATW_RXSTAT_DE, "descriptor error");
3145 PRINTERR(ATW_RXSTAT_SFDE, "PLCP SFD error");
3146 PRINTERR(ATW_RXSTAT_SIGE, "PLCP signal error");
3147 PRINTERR(ATW_RXSTAT_CRC16E, "PLCP CRC16 error");
3148 PRINTERR(ATW_RXSTAT_RXTOE, "time-out");
3149 PRINTERR(ATW_RXSTAT_CRC32E, "FCS error");
3150 PRINTERR(ATW_RXSTAT_ICVE, "WEP ICV error");
3151 #undef PRINTERR
3152 ATW_INIT_RXDESC(sc, i);
3153 continue;
3154 }
3155
3156 bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
3157 rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
3158
3159
3160
3161
3162
3163 len = MASK_AND_RSHIFT(rxstat, ATW_RXSTAT_FL_MASK);
3164
3165
3166
3167
3168
3169
3170 m = rxs->rxs_mbuf;
3171 if (atw_add_rxbuf(sc, i) != 0) {
3172 ifp->if_ierrors++;
3173 ATW_INIT_RXDESC(sc, i);
3174 bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
3175 rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
3176 continue;
3177 }
3178
3179 ifp->if_ipackets++;
3180 if (sc->sc_opmode & ATW_NAR_PR)
3181 len -= IEEE80211_CRC_LEN;
3182 m->m_pkthdr.rcvif = ifp;
3183 m->m_pkthdr.len = m->m_len = MIN(m->m_ext.ext_size, len);
3184
3185 if (rate0 >= sizeof(rate_tbl) / sizeof(rate_tbl[0]))
3186 rate = 0;
3187 else
3188 rate = rate_tbl[rate0];
3189
3190
3191
3192
3193
3194
3195
3196
3197 if (sc->sc_bbptype == ATW_BBPTYPE_RFMD)
3198 rssi = rssi0 & RF3000_RSSI_MASK;
3199 else
3200 rssi = rssi0;
3201
3202 #if NBPFILTER > 0
3203
3204 if (sc->sc_radiobpf != NULL) {
3205 struct mbuf mb;
3206
3207 struct atw_rx_radiotap_header *tap = &sc->sc_rxtap;
3208
3209 tap->ar_rate = rate;
3210 tap->ar_chan_freq = ic->ic_bss->ni_chan->ic_freq;
3211 tap->ar_chan_flags = ic->ic_bss->ni_chan->ic_flags;
3212
3213
3214 tap->ar_antsignal = (int)rssi;
3215
3216
3217 mb.m_data = (caddr_t)tap;
3218 mb.m_len = tap->ar_ihdr.it_len;
3219 mb.m_next = m;
3220 mb.m_nextpkt = NULL;
3221 mb.m_type = 0;
3222 mb.m_flags = 0;
3223 bpf_mtap(sc->sc_radiobpf, &mb, BPF_DIRECTION_IN);
3224 }
3225 #endif
3226
3227 wh = mtod(m, struct ieee80211_frame *);
3228 ni = ieee80211_find_rxnode(ic, wh);
3229 #if 0
3230 if (atw_hw_decrypted(sc, wh))
3231 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
3232 #endif
3233 ieee80211_input(ifp, m, ni, (int)rssi, 0);
3234
3235
3236
3237
3238
3239 ieee80211_release_node(ic, ni);
3240 }
3241
3242
3243 sc->sc_rxptr = i;
3244 }
3245
3246
3247
3248
3249
3250
3251 void
3252 atw_txintr(struct atw_softc *sc)
3253 {
3254 #define TXSTAT_ERRMASK (ATW_TXSTAT_TUF | ATW_TXSTAT_TLT | ATW_TXSTAT_TRT | \
3255 ATW_TXSTAT_TRO | ATW_TXSTAT_SOFBR)
3256 #define TXSTAT_FMT "\20\31ATW_TXSTAT_SOFBR\32ATW_TXSTAT_TRO\33ATW_TXSTAT_TUF" \
3257 "\34ATW_TXSTAT_TRT\35ATW_TXSTAT_TLT"
3258 struct ifnet *ifp = &sc->sc_ic.ic_if;
3259 struct atw_txsoft *txs;
3260 u_int32_t txstat;
3261
3262 DPRINTF3(sc, ("%s: atw_txintr: sc_flags 0x%08x\n",
3263 sc->sc_dev.dv_xname, sc->sc_flags));
3264
3265 ifp->if_flags &= ~IFF_OACTIVE;
3266
3267
3268
3269
3270
3271 while ((txs = SIMPLEQ_FIRST(&sc->sc_txdirtyq)) != NULL) {
3272 ATW_CDTXSYNC(sc, txs->txs_lastdesc, 1,
3273 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
3274
3275 #ifdef ATW_DEBUG
3276 if ((ifp->if_flags & IFF_DEBUG) != 0 && atw_debug > 2) {
3277 int i;
3278 printf(" txsoft %p transmit chain:\n", txs);
3279 ATW_CDTXSYNC(sc, txs->txs_firstdesc,
3280 txs->txs_ndescs - 1,
3281 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
3282 for (i = txs->txs_firstdesc;; i = ATW_NEXTTX(i)) {
3283 printf(" descriptor %d:\n", i);
3284 printf(" at_status: 0x%08x\n",
3285 letoh32(sc->sc_txdescs[i].at_stat));
3286 printf(" at_flags: 0x%08x\n",
3287 letoh32(sc->sc_txdescs[i].at_flags));
3288 printf(" at_buf1: 0x%08x\n",
3289 letoh32(sc->sc_txdescs[i].at_buf1));
3290 printf(" at_buf2: 0x%08x\n",
3291 letoh32(sc->sc_txdescs[i].at_buf2));
3292 if (i == txs->txs_lastdesc)
3293 break;
3294 }
3295 }
3296 #endif
3297
3298 txstat = letoh32(sc->sc_txdescs[txs->txs_lastdesc].at_stat);
3299 if (txstat & ATW_TXSTAT_OWN)
3300 break;
3301
3302 SIMPLEQ_REMOVE_HEAD(&sc->sc_txdirtyq, txs_q);
3303
3304 sc->sc_txfree += txs->txs_ndescs;
3305
3306 bus_dmamap_sync(sc->sc_dmat, txs->txs_dmamap,
3307 0, txs->txs_dmamap->dm_mapsize,
3308 BUS_DMASYNC_POSTWRITE);
3309 bus_dmamap_unload(sc->sc_dmat, txs->txs_dmamap);
3310 m_freem(txs->txs_mbuf);
3311 txs->txs_mbuf = NULL;
3312
3313 SIMPLEQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q);
3314
3315 if ((ifp->if_flags & IFF_DEBUG) != 0 &&
3316 (txstat & TXSTAT_ERRMASK) != 0) {
3317 #if defined(__OpenBSD__)
3318 printf("%s: txstat %b %d\n", sc->sc_dev.dv_xname,
3319 txstat & TXSTAT_ERRMASK, TXSTAT_FMT,
3320 MASK_AND_RSHIFT(txstat, ATW_TXSTAT_ARC_MASK));
3321 #else
3322 static char txstat_buf[sizeof("ffffffff<>" TXSTAT_FMT)];
3323 bitmask_snprintf(txstat & TXSTAT_ERRMASK, TXSTAT_FMT,
3324 txstat_buf, sizeof(txstat_buf));
3325 printf("%s: txstat %s %d\n", sc->sc_dev.dv_xname,
3326 txstat_buf,
3327 MASK_AND_RSHIFT(txstat, ATW_TXSTAT_ARC_MASK));
3328 #endif
3329 }
3330
3331
3332
3333
3334 if (txstat & ATW_TXSTAT_TUF)
3335 sc->sc_stats.ts_tx_tuf++;
3336 if (txstat & ATW_TXSTAT_TLT)
3337 sc->sc_stats.ts_tx_tlt++;
3338 if (txstat & ATW_TXSTAT_TRT)
3339 sc->sc_stats.ts_tx_trt++;
3340 if (txstat & ATW_TXSTAT_TRO)
3341 sc->sc_stats.ts_tx_tro++;
3342 if (txstat & ATW_TXSTAT_SOFBR) {
3343 sc->sc_stats.ts_tx_sofbr++;
3344 }
3345
3346 if ((txstat & ATW_TXSTAT_ES) == 0)
3347 ifp->if_collisions +=
3348 MASK_AND_RSHIFT(txstat, ATW_TXSTAT_ARC_MASK);
3349 else
3350 ifp->if_oerrors++;
3351
3352 ifp->if_opackets++;
3353 }
3354
3355
3356
3357
3358
3359 if (txs == NULL)
3360 sc->sc_tx_timer = 0;
3361 #undef TXSTAT_ERRMASK
3362 #undef TXSTAT_FMT
3363 }
3364
3365
3366
3367
3368
3369
3370 void
3371 atw_watchdog(struct ifnet *ifp)
3372 {
3373 struct atw_softc *sc = ifp->if_softc;
3374 struct ieee80211com *ic = &sc->sc_ic;
3375 uint32_t test1, rra, rwa;
3376
3377 ifp->if_timer = 0;
3378 if (ATW_IS_ENABLED(sc) == 0)
3379 return;
3380
3381 if (sc->sc_rescan_timer) {
3382 if (--sc->sc_rescan_timer == 0)
3383 (void)ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
3384 }
3385 if (sc->sc_tx_timer) {
3386 if (--sc->sc_tx_timer == 0 &&
3387 !SIMPLEQ_EMPTY(&sc->sc_txdirtyq)) {
3388 printf("%s: transmit timeout\n", ifp->if_xname);
3389 ifp->if_oerrors++;
3390 (void)atw_init(ifp);
3391 atw_start(ifp);
3392 }
3393 }
3394 if (sc->sc_tx_timer != 0 || sc->sc_rescan_timer != 0)
3395 ifp->if_timer = 1;
3396
3397
3398
3399
3400
3401
3402 if (sc->sc_rev == ATW_REVISION_BA) {
3403 test1 = ATW_READ(sc, ATW_TEST1);
3404 rra = (test1 >> 12) & 0x1ff;
3405 rwa = (test1 >> 2) & 0x1ff;
3406
3407 if ((rra != rwa) && !(test1 & 0x2)) {
3408 atw_init(ifp);
3409 atw_start(ifp);
3410 }
3411 }
3412
3413 ieee80211_watchdog(ifp);
3414 }
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435 int
3436 atw_compute_duration1(int len, int use_ack, uint32_t flags, int rate,
3437 struct atw_duration *d)
3438 {
3439 int pre, ctsrate;
3440 int ack, bitlen, data_dur, remainder;
3441
3442
3443
3444
3445
3446
3447
3448 bitlen = len * 8;
3449
3450 pre = IEEE80211_DUR_DS_SIFS;
3451 if ((flags & IEEE80211_F_SHPREAMBLE) != 0)
3452 pre += IEEE80211_DUR_DS_SHORT_PREAMBLE +
3453 IEEE80211_DUR_DS_FAST_PLCPHDR;
3454 else
3455 pre += IEEE80211_DUR_DS_LONG_PREAMBLE +
3456 IEEE80211_DUR_DS_SLOW_PLCPHDR;
3457
3458 d->d_residue = 0;
3459 data_dur = (bitlen * 2) / rate;
3460 remainder = (bitlen * 2) % rate;
3461 if (remainder != 0) {
3462 d->d_residue = (rate - remainder) / 16;
3463 data_dur++;
3464 }
3465
3466 switch (rate) {
3467 case 2:
3468 case 4:
3469
3470 ctsrate = 2;
3471 break;
3472 case 11:
3473 case 22:
3474 case 44:
3475
3476 ctsrate = 4;
3477 break;
3478 default:
3479
3480 return -1;
3481 }
3482
3483 d->d_plcp_len = data_dur;
3484
3485 ack = (use_ack) ? pre + (IEEE80211_DUR_DS_SLOW_ACK * 2) / ctsrate : 0;
3486
3487 d->d_rts_dur =
3488 pre + (IEEE80211_DUR_DS_SLOW_CTS * 2) / ctsrate +
3489 pre + data_dur +
3490 ack;
3491
3492 d->d_data_dur = ack;
3493
3494 return 0;
3495 }
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521 int
3522 atw_compute_duration(struct ieee80211_frame *wh, int len, uint32_t flags,
3523 int fraglen, int rate, struct atw_duration *d0, struct atw_duration *dn,
3524 int *npktp, int debug)
3525 {
3526 int ack, rc;
3527 int firstlen, hdrlen, lastlen, lastlen0, npkt, overlen, paylen;
3528
3529 if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
3530 hdrlen = sizeof(struct ieee80211_frame_addr4);
3531 else
3532 hdrlen = sizeof(struct ieee80211_frame);
3533
3534 paylen = len - hdrlen;
3535
3536 if ((flags & IEEE80211_F_WEPON) != 0)
3537 overlen = IEEE80211_WEP_TOTLEN + IEEE80211_CRC_LEN;
3538 else
3539 overlen = IEEE80211_CRC_LEN;
3540
3541 npkt = paylen / fraglen;
3542 lastlen0 = paylen % fraglen;
3543
3544 if (npkt == 0)
3545 lastlen = paylen + overlen;
3546 else if (lastlen0 != 0) {
3547 lastlen = lastlen0 + overlen;
3548 npkt++;
3549 } else
3550 lastlen = fraglen + overlen;
3551
3552 if (npktp != NULL)
3553 *npktp = npkt;
3554
3555 if (npkt > 1)
3556 firstlen = fraglen + overlen;
3557 else
3558 firstlen = paylen + overlen;
3559
3560 if (debug) {
3561 printf("%s: npkt %d firstlen %d lastlen0 %d lastlen %d "
3562 "fraglen %d overlen %d len %d rate %d flags %08x\n",
3563 __func__, npkt, firstlen, lastlen0, lastlen, fraglen,
3564 overlen, len, rate, flags);
3565 }
3566
3567 ack = !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
3568 (wh->i_fc[1] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_CTL;
3569
3570 rc = atw_compute_duration1(firstlen + hdrlen, ack, flags, rate, d0);
3571 if (rc == -1)
3572 return rc;
3573
3574 if (npkt <= 1) {
3575 *dn = *d0;
3576 return 0;
3577 }
3578 return atw_compute_duration1(lastlen + hdrlen, ack, flags, rate, dn);
3579 }
3580
3581 #ifdef ATW_DEBUG
3582 void
3583 atw_dump_pkt(struct ifnet *ifp, struct mbuf *m0)
3584 {
3585 struct atw_softc *sc = ifp->if_softc;
3586 struct mbuf *m;
3587 int i, noctets = 0;
3588
3589 printf("%s: %d-byte packet\n", sc->sc_dev.dv_xname,
3590 m0->m_pkthdr.len);
3591
3592 for (m = m0; m; m = m->m_next) {
3593 if (m->m_len == 0)
3594 continue;
3595 for (i = 0; i < m->m_len; i++) {
3596 printf(" %02x", ((u_int8_t*)m->m_data)[i]);
3597 if (++noctets % 24 == 0)
3598 printf("\n");
3599 }
3600 }
3601 printf("%s%s: %d bytes emitted\n",
3602 (noctets % 24 != 0) ? "\n" : "", sc->sc_dev.dv_xname, noctets);
3603 }
3604 #endif
3605
3606
3607
3608
3609
3610
3611 void
3612 atw_start(struct ifnet *ifp)
3613 {
3614 struct atw_softc *sc = ifp->if_softc;
3615 struct ieee80211com *ic = &sc->sc_ic;
3616 struct ieee80211_node *ni;
3617 struct ieee80211_frame *wh;
3618 struct atw_frame *hh;
3619 struct mbuf *m0, *m;
3620 struct atw_txsoft *txs, *last_txs;
3621 struct atw_txdesc *txd;
3622 int do_encrypt, npkt, rate;
3623 bus_dmamap_t dmamap;
3624 int ctl, error, firsttx, nexttx, lasttx = -1, first, ofree, seg;
3625
3626 DPRINTF2(sc, ("%s: atw_start: sc_flags 0x%08x, if_flags 0x%08x\n",
3627 sc->sc_dev.dv_xname, sc->sc_flags, ifp->if_flags));
3628
3629 if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
3630 return;
3631
3632
3633
3634
3635
3636 ofree = sc->sc_txfree;
3637 firsttx = sc->sc_txnext;
3638
3639 DPRINTF2(sc, ("%s: atw_start: txfree %d, txnext %d\n",
3640 sc->sc_dev.dv_xname, ofree, firsttx));
3641
3642
3643
3644
3645
3646
3647 while ((txs = SIMPLEQ_FIRST(&sc->sc_txfreeq)) != NULL &&
3648 sc->sc_txfree != 0) {
3649
3650
3651
3652
3653
3654 IF_DEQUEUE(&ic->ic_mgtq, m0);
3655 if (m0 != NULL) {
3656 ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif;
3657 m0->m_pkthdr.rcvif = NULL;
3658 } else {
3659
3660 if (ic->ic_state != IEEE80211_S_RUN)
3661 break;
3662 IFQ_DEQUEUE(&ifp->if_snd, m0);
3663 if (m0 == NULL)
3664 break;
3665 #if NBPFILTER > 0
3666 if (ifp->if_bpf != NULL)
3667 bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
3668 #endif
3669 if ((m0 = ieee80211_encap(ifp, m0, &ni)) == NULL) {
3670 ifp->if_oerrors++;
3671 break;
3672 }
3673
3674 if (sc->sc_ic.ic_flags & IEEE80211_F_WEPON) {
3675 if ((m0 = ieee80211_wep_crypt(ifp, m0, 1)) == NULL) {
3676 ifp->if_oerrors++;
3677 break;
3678 }
3679 }
3680 }
3681
3682 wh = mtod(m0, struct ieee80211_frame *);
3683
3684
3685 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
3686 IEEE80211_FC0_TYPE_MGT)
3687 rate = 2;
3688 else
3689 rate = MAX(2, ieee80211_get_rate(ic));
3690
3691 if (atw_compute_duration(wh, m0->m_pkthdr.len,
3692 ic->ic_flags & ~IEEE80211_F_WEPON, ic->ic_fragthreshold,
3693 rate, &txs->txs_d0, &txs->txs_dn, &npkt,
3694 (sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) ==
3695 (IFF_DEBUG|IFF_LINK2)) == -1) {
3696 DPRINTF2(sc, ("%s: fail compute duration\n", __func__));
3697 m_freem(m0);
3698 break;
3699 }
3700
3701
3702
3703
3704
3705 *(uint16_t *)wh->i_dur = htole16(txs->txs_d0.d_rts_dur);
3706
3707 #if NBPFILTER > 0
3708
3709
3710
3711 if (ic->ic_rawbpf != NULL)
3712 bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT);
3713
3714 if (sc->sc_radiobpf != NULL) {
3715 struct mbuf mb;
3716 struct atw_tx_radiotap_header *tap = &sc->sc_txtap;
3717
3718 tap->at_rate = rate;
3719 tap->at_chan_freq = ic->ic_bss->ni_chan->ic_freq;
3720 tap->at_chan_flags = ic->ic_bss->ni_chan->ic_flags;
3721
3722
3723
3724 mb.m_data = (caddr_t)tap;
3725 mb.m_len = tap->at_ihdr.it_len;
3726 mb.m_next = m0;
3727 mb.m_nextpkt = NULL;
3728 mb.m_type = 0;
3729 mb.m_flags = 0;
3730 bpf_mtap(sc->sc_radiobpf, &mb, BPF_DIRECTION_OUT);
3731 }
3732 #endif
3733
3734 M_PREPEND(m0, offsetof(struct atw_frame, atw_ihdr), M_DONTWAIT);
3735
3736 if (ni != NULL)
3737 ieee80211_release_node(ic, ni);
3738
3739 if (m0 == NULL) {
3740 ifp->if_oerrors++;
3741 break;
3742 }
3743
3744
3745 m0 = m_pullup(m0, sizeof(struct atw_frame));
3746
3747 if (m0 == NULL) {
3748 ifp->if_oerrors++;
3749 break;
3750 }
3751
3752 hh = mtod(m0, struct atw_frame *);
3753 wh = &hh->atw_ihdr;
3754
3755 do_encrypt = ((wh->i_fc[1] & IEEE80211_FC1_WEP) != 0) ? 1 : 0;
3756
3757
3758
3759
3760
3761 if (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) {
3762 if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS)
3763 panic("%s: illegal WDS frame",
3764 sc->sc_dev.dv_xname);
3765 memcpy(hh->atw_dst, wh->i_addr3, IEEE80211_ADDR_LEN);
3766 } else
3767 memcpy(hh->atw_dst, wh->i_addr1, IEEE80211_ADDR_LEN);
3768
3769 *(u_int16_t*)hh->atw_fc = *(u_int16_t*)wh->i_fc;
3770
3771
3772 memset(&hh->u, 0, sizeof(hh->u));
3773
3774 hh->atw_rate = rate * 5;
3775
3776
3777
3778
3779 hh->atw_service = IEEE80211_PLCP_SERVICE;
3780 hh->atw_paylen = htole16(m0->m_pkthdr.len -
3781 sizeof(struct atw_frame));
3782
3783 hh->atw_fragthr = htole16(ATW_FRAGTHR_FRAGTHR_MASK);
3784 hh->atw_rtylmt = 3;
3785 hh->atw_hdrctl = htole16(ATW_HDRCTL_UNKNOWN1);
3786 #if 0
3787 if (do_encrypt) {
3788 hh->atw_hdrctl |= htole16(ATW_HDRCTL_WEP);
3789 hh->atw_keyid = ic->ic_wep_txkey;
3790 }
3791 #endif
3792
3793 hh->atw_head_plcplen = htole16(txs->txs_d0.d_plcp_len);
3794 hh->atw_tail_plcplen = htole16(txs->txs_dn.d_plcp_len);
3795 if (txs->txs_d0.d_residue)
3796 hh->atw_head_plcplen |= htole16(0x8000);
3797 if (txs->txs_dn.d_residue)
3798 hh->atw_tail_plcplen |= htole16(0x8000);
3799 hh->atw_head_dur = htole16(txs->txs_d0.d_rts_dur);
3800 hh->atw_tail_dur = htole16(txs->txs_dn.d_rts_dur);
3801
3802
3803 if (IEEE80211_IS_MULTICAST(hh->atw_dst)) {
3804 hh->atw_fragthr = htole16(ATW_FRAGTHR_FRAGTHR_MASK);
3805 } else if (sc->sc_flags & ATWF_RTSCTS) {
3806 hh->atw_hdrctl |= htole16(ATW_HDRCTL_RTSCTS);
3807 }
3808
3809 #ifdef ATW_DEBUG
3810 hh->atw_fragnum = 0;
3811
3812 if ((ifp->if_flags & IFF_DEBUG) != 0 && atw_debug > 2) {
3813 printf("%s: dst = %s, rate = 0x%02x, "
3814 "service = 0x%02x, paylen = 0x%04x\n",
3815 sc->sc_dev.dv_xname, ether_sprintf(hh->atw_dst),
3816 hh->atw_rate, hh->atw_service, hh->atw_paylen);
3817
3818 printf("%s: fc[0] = 0x%02x, fc[1] = 0x%02x, "
3819 "dur1 = 0x%04x, dur2 = 0x%04x, "
3820 "dur3 = 0x%04x, rts_dur = 0x%04x\n",
3821 sc->sc_dev.dv_xname, hh->atw_fc[0], hh->atw_fc[1],
3822 hh->atw_tail_plcplen, hh->atw_head_plcplen,
3823 hh->atw_tail_dur, hh->atw_head_dur);
3824
3825 printf("%s: hdrctl = 0x%04x, fragthr = 0x%04x, "
3826 "fragnum = 0x%02x, rtylmt = 0x%04x\n",
3827 sc->sc_dev.dv_xname, hh->atw_hdrctl,
3828 hh->atw_fragthr, hh->atw_fragnum, hh->atw_rtylmt);
3829
3830 printf("%s: keyid = %d\n",
3831 sc->sc_dev.dv_xname, hh->atw_keyid);
3832
3833 atw_dump_pkt(ifp, m0);
3834 }
3835 #endif
3836
3837 dmamap = txs->txs_dmamap;
3838
3839
3840
3841
3842
3843 for (first = 1;
3844 (error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0,
3845 BUS_DMA_WRITE|BUS_DMA_NOWAIT)) != 0 && first;
3846 first = 0) {
3847 MGETHDR(m, M_DONTWAIT, MT_DATA);
3848 if (m == NULL) {
3849 printf("%s: unable to allocate Tx mbuf\n",
3850 sc->sc_dev.dv_xname);
3851 break;
3852 }
3853 if (m0->m_pkthdr.len > MHLEN) {
3854 MCLGET(m, M_DONTWAIT);
3855 if ((m->m_flags & M_EXT) == 0) {
3856 printf("%s: unable to allocate Tx "
3857 "cluster\n", sc->sc_dev.dv_xname);
3858 m_freem(m);
3859 break;
3860 }
3861 }
3862 m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t));
3863 m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len;
3864 m_freem(m0);
3865 m0 = m;
3866 m = NULL;
3867 }
3868 if (error != 0) {
3869 printf("%s: unable to load Tx buffer, "
3870 "error = %d\n", sc->sc_dev.dv_xname, error);
3871 m_freem(m0);
3872 break;
3873 }
3874
3875
3876
3877
3878
3879 if (dmamap->dm_nsegs > sc->sc_txfree) {
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889 ifp->if_flags |= IFF_OACTIVE;
3890 bus_dmamap_unload(sc->sc_dmat, dmamap);
3891 m_freem(m0);
3892 break;
3893 }
3894
3895
3896
3897
3898
3899
3900 bus_dmamap_sync(sc->sc_dmat, dmamap, 0, dmamap->dm_mapsize,
3901 BUS_DMASYNC_PREWRITE);
3902
3903
3904
3905
3906 ctl = htole32(LSHIFT(8, ATW_TXCTL_TL_MASK));
3907
3908 DPRINTF2(sc, ("%s: TXDR <- max(10, %d)\n",
3909 sc->sc_dev.dv_xname, rate * 5));
3910 ctl |= htole32(LSHIFT(MAX(10, rate * 5), ATW_TXCTL_TXDR_MASK));
3911
3912
3913
3914
3915 for (nexttx = sc->sc_txnext, seg = 0;
3916 seg < dmamap->dm_nsegs;
3917 seg++, nexttx = ATW_NEXTTX(nexttx)) {
3918
3919
3920
3921
3922
3923
3924 txd = &sc->sc_txdescs[nexttx];
3925 txd->at_ctl = ctl |
3926 ((nexttx == firsttx) ? 0 : htole32(ATW_TXCTL_OWN));
3927
3928 txd->at_buf1 = htole32(dmamap->dm_segs[seg].ds_addr);
3929 txd->at_flags =
3930 htole32(LSHIFT(dmamap->dm_segs[seg].ds_len,
3931 ATW_TXFLAG_TBS1_MASK)) |
3932 ((nexttx == (ATW_NTXDESC - 1))
3933 ? htole32(ATW_TXFLAG_TER) : 0);
3934 lasttx = nexttx;
3935 }
3936
3937 if (lasttx == -1)
3938 panic("%s: bad lastx", ifp->if_xname);
3939
3940 sc->sc_txdescs[sc->sc_txnext].at_flags |=
3941 htole32(ATW_TXFLAG_FS);
3942 sc->sc_txdescs[lasttx].at_flags |= htole32(ATW_TXFLAG_LS);
3943
3944 #ifdef ATW_DEBUG
3945 if ((ifp->if_flags & IFF_DEBUG) != 0 && atw_debug > 2) {
3946 printf(" txsoft %p transmit chain:\n", txs);
3947 for (seg = sc->sc_txnext;; seg = ATW_NEXTTX(seg)) {
3948 printf(" descriptor %d:\n", seg);
3949 printf(" at_ctl: 0x%08x\n",
3950 letoh32(sc->sc_txdescs[seg].at_ctl));
3951 printf(" at_flags: 0x%08x\n",
3952 letoh32(sc->sc_txdescs[seg].at_flags));
3953 printf(" at_buf1: 0x%08x\n",
3954 letoh32(sc->sc_txdescs[seg].at_buf1));
3955 printf(" at_buf2: 0x%08x\n",
3956 letoh32(sc->sc_txdescs[seg].at_buf2));
3957 if (seg == lasttx)
3958 break;
3959 }
3960 }
3961 #endif
3962
3963
3964 ATW_CDTXSYNC(sc, sc->sc_txnext, dmamap->dm_nsegs,
3965 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
3966
3967
3968
3969
3970
3971
3972 txs->txs_mbuf = m0;
3973 txs->txs_firstdesc = sc->sc_txnext;
3974 txs->txs_lastdesc = lasttx;
3975 txs->txs_ndescs = dmamap->dm_nsegs;
3976
3977
3978 sc->sc_txfree -= dmamap->dm_nsegs;
3979 sc->sc_txnext = nexttx;
3980
3981 SIMPLEQ_REMOVE_HEAD(&sc->sc_txfreeq, txs_q);
3982 SIMPLEQ_INSERT_TAIL(&sc->sc_txdirtyq, txs, txs_q);
3983
3984 last_txs = txs;
3985 }
3986
3987 if (txs == NULL || sc->sc_txfree == 0) {
3988
3989 ifp->if_flags |= IFF_OACTIVE;
3990 }
3991
3992 if (sc->sc_txfree != ofree) {
3993 DPRINTF2(sc, ("%s: packets enqueued, IC on %d, OWN on %d\n",
3994 sc->sc_dev.dv_xname, lasttx, firsttx));
3995
3996
3997
3998
3999 sc->sc_txdescs[lasttx].at_flags |= htole32(ATW_TXFLAG_IC);
4000 ATW_CDTXSYNC(sc, lasttx, 1,
4001 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
4002
4003
4004
4005
4006
4007 sc->sc_txdescs[firsttx].at_ctl |= htole32(ATW_TXCTL_OWN);
4008 ATW_CDTXSYNC(sc, firsttx, 1,
4009 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
4010
4011
4012 ATW_WRITE(sc, ATW_TDR, 0x1);
4013
4014
4015 sc->sc_tx_timer = 5;
4016 ifp->if_timer = 1;
4017 }
4018 }
4019
4020
4021
4022
4023
4024
4025 void
4026 atw_power(int why, void *arg)
4027 {
4028 struct atw_softc *sc = arg;
4029 struct ifnet *ifp = &sc->sc_ic.ic_if;
4030 int s;
4031
4032 DPRINTF(sc, ("%s: atw_power(%d,)\n", sc->sc_dev.dv_xname, why));
4033
4034 s = splnet();
4035 switch (why) {
4036 case PWR_STANDBY:
4037
4038 break;
4039 case PWR_SUSPEND:
4040 atw_stop(ifp, 1);
4041 if (sc->sc_power != NULL)
4042 (*sc->sc_power)(sc, why);
4043 break;
4044 case PWR_RESUME:
4045 if (ifp->if_flags & IFF_UP) {
4046 if (sc->sc_power != NULL)
4047 (*sc->sc_power)(sc, why);
4048 atw_init(ifp);
4049 }
4050 break;
4051 #if !defined(__OpenBSD__)
4052 case PWR_SOFTSUSPEND:
4053 case PWR_SOFTSTANDBY:
4054 case PWR_SOFTRESUME:
4055 break;
4056 #endif
4057 }
4058 splx(s);
4059 }
4060
4061
4062
4063
4064
4065
4066 int
4067 atw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
4068 {
4069 struct atw_softc *sc = ifp->if_softc;
4070 struct ieee80211com *ic = &sc->sc_ic;
4071 struct ifreq *ifr = (struct ifreq *)data;
4072 struct ifaddr *ifa = (struct ifaddr *)data;
4073 int s, error = 0;
4074
4075
4076 if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0)
4077 return ENXIO;
4078
4079 s = splnet();
4080
4081 switch (cmd) {
4082 case SIOCSIFMTU:
4083 if (ifr->ifr_mtu > ETHERMTU || ifr->ifr_mtu < ETHERMIN) {
4084 error = EINVAL;
4085 } else if (ifp->if_mtu != ifr->ifr_mtu) {
4086 ifp->if_mtu = ifr->ifr_mtu;
4087 }
4088 break;
4089 case SIOCSIFADDR:
4090 ifp->if_flags |= IFF_UP;
4091 #ifdef INET
4092 if (ifa->ifa_addr->sa_family == AF_INET) {
4093 arp_ifinit(&ic->ic_ac, ifa);
4094 }
4095 #endif
4096
4097 case SIOCSIFFLAGS:
4098 if (ifp->if_flags & IFF_UP) {
4099 if (ATW_IS_ENABLED(sc)) {
4100
4101
4102
4103
4104
4105 atw_filter_setup(sc);
4106 } else
4107 error = atw_init(ifp);
4108 } else if (ATW_IS_ENABLED(sc))
4109 atw_stop(ifp, 1);
4110 break;
4111 case SIOCADDMULTI:
4112 case SIOCDELMULTI:
4113 error = (cmd == SIOCADDMULTI) ?
4114 #if defined(__OpenBSD__)
4115 ether_addmulti(ifr, &sc->sc_ic.ic_ac) :
4116 ether_delmulti(ifr, &sc->sc_ic.ic_ac);
4117 #else
4118 ether_addmulti(ifr, &sc->sc_ic.ic_ec) :
4119 ether_delmulti(ifr, &sc->sc_ic.ic_ec);
4120 #endif
4121
4122 if (error == ENETRESET) {
4123 if (ifp->if_flags & IFF_RUNNING)
4124 atw_filter_setup(sc);
4125 error = 0;
4126 }
4127 break;
4128 default:
4129 error = ieee80211_ioctl(ifp, cmd, data);
4130 if (error == ENETRESET) {
4131 if (ATW_IS_ENABLED(sc))
4132 error = atw_init(ifp);
4133 else
4134 error = 0;
4135 }
4136 break;
4137 }
4138
4139
4140 if (ATW_IS_ENABLED(sc))
4141 atw_start(ifp);
4142
4143 splx(s);
4144 return (error);
4145 }
4146
4147 int
4148 atw_media_change(struct ifnet *ifp)
4149 {
4150 int error;
4151
4152 error = ieee80211_media_change(ifp);
4153 if (error == ENETRESET) {
4154 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
4155 (IFF_RUNNING|IFF_UP))
4156 atw_init(ifp);
4157 error = 0;
4158 }
4159 return error;
4160 }
4161
4162 void
4163 atw_media_status(struct ifnet *ifp, struct ifmediareq *imr)
4164 {
4165 struct atw_softc *sc = ifp->if_softc;
4166
4167 if (ATW_IS_ENABLED(sc) == 0) {
4168 imr->ifm_active = IFM_IEEE80211 | IFM_NONE;
4169 imr->ifm_status = 0;
4170 return;
4171 }
4172 ieee80211_media_status(ifp, imr);
4173 }