2 * Copyright (c) 2007 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Sepherosa Ziehau <sepherosa@gmail.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * $DragonFly: src/sys/dev/netif/bwi/if_bwi.c,v 1.5 2007/09/16 08:25:41 sephe Exp $
37 #include <sys/param.h>
38 #include <sys/endian.h>
39 #include <sys/kernel.h>
41 #include <sys/malloc.h>
44 #include <sys/serialize.h>
45 #include <sys/socket.h>
46 #include <sys/sockio.h>
47 #include <sys/sysctl.h>
49 #include <net/ethernet.h>
52 #include <net/if_arp.h>
53 #include <net/if_dl.h>
54 #include <net/if_media.h>
55 #include <net/ifq_var.h>
57 #include <netproto/802_11/ieee80211_radiotap.h>
58 #include <netproto/802_11/ieee80211_var.h>
60 #include <bus/pci/pcireg.h>
61 #include <bus/pci/pcivar.h>
62 #include <bus/pci/pcidevs.h>
65 #include "if_bwireg.h"
66 #include "if_bwivar.h"
70 struct bwi_clock_freq
{
75 struct bwi_myaddr_bssid
{
76 uint8_t myaddr
[IEEE80211_ADDR_LEN
];
77 uint8_t bssid
[IEEE80211_ADDR_LEN
];
80 static int bwi_probe(device_t
);
81 static int bwi_attach(device_t
);
82 static int bwi_detach(device_t
);
83 static int bwi_shutdown(device_t
);
85 static void bwi_init(void *);
86 static int bwi_ioctl(struct ifnet
*, u_long
, caddr_t
, struct ucred
*);
87 static void bwi_start(struct ifnet
*);
88 static void bwi_watchdog(struct ifnet
*);
89 static int bwi_newstate(struct ieee80211com
*, enum ieee80211_state
, int);
90 static void bwi_updateslot(struct ifnet
*);
91 static int bwi_media_change(struct ifnet
*);
93 static void bwi_next_scan(void *);
94 static void bwi_calibrate(void *);
96 static int bwi_stop(struct bwi_softc
*);
97 static int bwi_newbuf(struct bwi_softc
*, int, int);
98 static int bwi_encap(struct bwi_softc
*, int, struct mbuf
*,
99 struct ieee80211_node
*);
101 static void bwi_init_rxdesc_ring32(struct bwi_softc
*, uint32_t,
102 bus_addr_t
, int, int);
103 static void bwi_reset_rx_ring32(struct bwi_softc
*, uint32_t);
105 static int bwi_init_tx_ring32(struct bwi_softc
*, int);
106 static int bwi_init_rx_ring32(struct bwi_softc
*);
107 static int bwi_init_txstats32(struct bwi_softc
*);
108 static void bwi_free_tx_ring32(struct bwi_softc
*, int);
109 static void bwi_free_rx_ring32(struct bwi_softc
*);
110 static void bwi_free_txstats32(struct bwi_softc
*);
111 static void bwi_setup_rx_desc32(struct bwi_softc
*, int, bus_addr_t
, int);
112 static void bwi_setup_tx_desc32(struct bwi_softc
*, struct bwi_ring_data
*,
113 int, bus_addr_t
, int);
114 static void bwi_rxeof32(struct bwi_softc
*);
115 static void bwi_start_tx32(struct bwi_softc
*, uint32_t, int);
116 static void bwi_txeof_status32(struct bwi_softc
*);
118 static int bwi_init_tx_ring64(struct bwi_softc
*, int);
119 static int bwi_init_rx_ring64(struct bwi_softc
*);
120 static int bwi_init_txstats64(struct bwi_softc
*);
121 static void bwi_free_tx_ring64(struct bwi_softc
*, int);
122 static void bwi_free_rx_ring64(struct bwi_softc
*);
123 static void bwi_free_txstats64(struct bwi_softc
*);
124 static void bwi_setup_rx_desc64(struct bwi_softc
*, int, bus_addr_t
, int);
125 static void bwi_setup_tx_desc64(struct bwi_softc
*, struct bwi_ring_data
*,
126 int, bus_addr_t
, int);
127 static void bwi_rxeof64(struct bwi_softc
*);
128 static void bwi_start_tx64(struct bwi_softc
*, uint32_t, int);
129 static void bwi_txeof_status64(struct bwi_softc
*);
131 static void bwi_intr(void *);
132 static void bwi_rxeof(struct bwi_softc
*, int);
133 static void _bwi_txeof(struct bwi_softc
*, uint16_t, int, int);
134 static void bwi_txeof(struct bwi_softc
*);
135 static void bwi_txeof_status(struct bwi_softc
*, int);
136 static void bwi_enable_intrs(struct bwi_softc
*, uint32_t);
137 static void bwi_disable_intrs(struct bwi_softc
*, uint32_t);
138 static int bwi_calc_rssi(struct bwi_softc
*, const struct bwi_rxbuf_hdr
*);
139 static void bwi_rx_radiotap(struct bwi_softc
*, struct mbuf
*,
140 struct bwi_rxbuf_hdr
*, const void *, int);
142 static int bwi_dma_alloc(struct bwi_softc
*);
143 static void bwi_dma_free(struct bwi_softc
*);
144 static int bwi_dma_ring_alloc(struct bwi_softc
*, bus_dma_tag_t
,
145 struct bwi_ring_data
*, bus_size_t
,
147 static int bwi_dma_mbuf_create(struct bwi_softc
*);
148 static void bwi_dma_mbuf_destroy(struct bwi_softc
*, int, int);
149 static int bwi_dma_txstats_alloc(struct bwi_softc
*, uint32_t, bus_size_t
);
150 static void bwi_dma_txstats_free(struct bwi_softc
*);
151 static void bwi_dma_ring_addr(void *, bus_dma_segment_t
*, int, int);
152 static void bwi_dma_buf_addr(void *, bus_dma_segment_t
*, int,
155 static void bwi_power_on(struct bwi_softc
*, int);
156 static int bwi_power_off(struct bwi_softc
*, int);
157 static int bwi_set_clock_mode(struct bwi_softc
*, enum bwi_clock_mode
);
158 static int bwi_set_clock_delay(struct bwi_softc
*);
159 static void bwi_get_clock_freq(struct bwi_softc
*, struct bwi_clock_freq
*);
160 static int bwi_get_pwron_delay(struct bwi_softc
*sc
);
161 static void bwi_set_addr_filter(struct bwi_softc
*, uint16_t,
163 static void bwi_set_bssid(struct bwi_softc
*, const uint8_t *);
164 static int bwi_set_chan(struct bwi_softc
*, struct ieee80211_channel
*);
166 static void bwi_get_card_flags(struct bwi_softc
*);
167 static void bwi_get_eaddr(struct bwi_softc
*, uint16_t, uint8_t *);
169 static int bwi_bus_attach(struct bwi_softc
*);
170 static int bwi_bbp_attach(struct bwi_softc
*);
171 static int bwi_bbp_power_on(struct bwi_softc
*, enum bwi_clock_mode
);
172 static void bwi_bbp_power_off(struct bwi_softc
*);
174 static const char *bwi_regwin_name(const struct bwi_regwin
*);
175 static uint32_t bwi_regwin_disable_bits(struct bwi_softc
*);
176 static void bwi_regwin_info(struct bwi_softc
*, uint16_t *, uint8_t *);
177 static int bwi_regwin_select(struct bwi_softc
*, int);
179 static const struct bwi_dev
{
184 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM4301
,
185 "Broadcom BCM4301 802.11 Wireless Lan" },
187 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM4307
,
188 "Broadcom BCM4307 802.11 Wireless Lan" },
190 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM4311
,
191 "Broadcom BCM4311 802.11 Wireless Lan" },
193 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM4312
,
194 "Broadcom BCM4312 802.11 Wireless Lan" },
196 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM4306_1
,
197 "Broadcom BCM4306 802.11 Wireless Lan" },
199 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM4306_2
,
200 "Broadcom BCM4306 802.11 Wireless Lan" },
202 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM4306_3
,
203 "Broadcom BCM4306 802.11 Wireless Lan" },
205 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM4309
,
206 "Broadcom BCM4309 802.11 Wireless Lan" },
208 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM4318
,
209 "Broadcom BCM4318 802.11 Wireless Lan" },
211 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM4319
,
212 "Broadcom BCM4319 802.11 Wireless Lan" }
215 static device_method_t bwi_methods
[] = {
216 DEVMETHOD(device_probe
, bwi_probe
),
217 DEVMETHOD(device_attach
, bwi_attach
),
218 DEVMETHOD(device_detach
, bwi_detach
),
219 DEVMETHOD(device_shutdown
, bwi_shutdown
),
221 DEVMETHOD(device_suspend
, bwi_suspend
),
222 DEVMETHOD(device_resume
, bwi_resume
),
227 static driver_t bwi_driver
= {
230 sizeof(struct bwi_softc
)
233 static devclass_t bwi_devclass
;
235 DRIVER_MODULE(bwi
, pci
, bwi_driver
, bwi_devclass
, 0, 0);
236 DRIVER_MODULE(bwi
, cardbus
, bwi_driver
, bwi_devclass
, 0, 0);
238 MODULE_DEPEND(bwi
, wlan
, 1, 1, 1);
240 MODULE_DEPEND(bwi
, wlan_ratectl_onoe
, 1, 1, 1);
241 MODULE_DEPEND(bwi
, wlan_ratectl_amrr
, 1, 1, 1);
243 MODULE_DEPEND(bwi
, pci
, 1, 1, 1);
244 MODULE_DEPEND(bwi
, cardbus
, 1, 1, 1);
246 static const struct {
250 } bwi_bbpid_map
[] = {
251 { 0x4301, 0x4301, 0x4301 },
252 { 0x4305, 0x4307, 0x4307 },
253 { 0x4403, 0x4403, 0x4402 },
254 { 0x4610, 0x4615, 0x4610 },
255 { 0x4710, 0x4715, 0x4710 },
256 { 0x4720, 0x4725, 0x4309 }
259 static const struct {
262 } bwi_regwin_count
[] = {
275 #define CLKSRC(src) \
276 [BWI_CLKSRC_ ## src] = { \
277 .freq_min = BWI_CLKSRC_ ##src## _FMIN, \
278 .freq_max = BWI_CLKSRC_ ##src## _FMAX \
281 static const struct {
284 } bwi_clkfreq
[BWI_CLKSRC_MAX
] = {
292 static const uint8_t bwi_zero_addr
[IEEE80211_ADDR_LEN
];
294 static const struct ieee80211_rateset bwi_rateset_11b
=
295 { 4, { 2, 4, 11, 22 } };
296 static const struct ieee80211_rateset bwi_rateset_11g
=
297 { 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
300 bwi_read_sprom(struct bwi_softc
*sc
, uint16_t ofs
)
302 return CSR_READ_2(sc
, ofs
+ BWI_SPROM_START
);
306 bwi_setup_desc32(struct bwi_softc
*sc
, struct bwi_desc32
*desc_array
,
307 int ndesc
, int desc_idx
, bus_addr_t paddr
, int buf_len
,
310 struct bwi_desc32
*desc
= &desc_array
[desc_idx
];
311 uint32_t ctrl
, addr
, addr_hi
, addr_lo
;
313 addr_lo
= __SHIFTOUT(paddr
, BWI_DESC32_A_ADDR_MASK
);
314 addr_hi
= __SHIFTOUT(paddr
, BWI_DESC32_A_FUNC_MASK
);
316 addr
= __SHIFTIN(addr_lo
, BWI_DESC32_A_ADDR_MASK
) |
317 __SHIFTIN(BWI_DESC32_A_FUNC_TXRX
, BWI_DESC32_A_FUNC_MASK
);
319 ctrl
= __SHIFTIN(buf_len
, BWI_DESC32_C_BUFLEN_MASK
) |
320 __SHIFTIN(addr_hi
, BWI_DESC32_C_ADDRHI_MASK
);
321 if (desc_idx
== ndesc
- 1)
322 ctrl
|= BWI_DESC32_C_EOR
;
325 ctrl
|= BWI_DESC32_C_FRAME_START
|
326 BWI_DESC32_C_FRAME_END
|
330 desc
->addr
= htole32(addr
);
331 desc
->ctrl
= htole32(ctrl
);
335 bwi_probe(device_t dev
)
337 const struct bwi_dev
*b
;
340 did
= pci_get_device(dev
);
341 vid
= pci_get_vendor(dev
);
343 for (b
= bwi_devices
; b
->desc
!= NULL
; ++b
) {
344 if (b
->did
== did
&& b
->vid
== vid
) {
345 device_set_desc(dev
, b
->desc
);
353 bwi_attach(device_t dev
)
355 struct bwi_softc
*sc
= device_get_softc(dev
);
356 struct ieee80211com
*ic
= &sc
->sc_ic
;
357 struct ifnet
*ifp
= &ic
->ic_if
;
362 if_initname(ifp
, device_get_name(dev
), device_get_unit(dev
));
365 callout_init(&sc
->sc_scan_ch
);
366 callout_init(&sc
->sc_calib_ch
);
369 if (pci_get_powerstate(dev
) != PCI_POWERSTATE_D0
) {
372 /* XXX Save more PCIR */
373 irq
= pci_read_config(dev
, PCIR_INTLINE
, 4);
374 mem
= pci_read_config(dev
, BWI_PCIR_BAR
, 4);
376 device_printf(dev
, "chip is in D%d power mode "
377 "-- setting to D0\n", pci_get_powerstate(dev
));
379 pci_set_powerstate(dev
, PCI_POWERSTATE_D0
);
381 pci_write_config(dev
, PCIR_INTLINE
, irq
, 4);
382 pci_write_config(dev
, BWI_PCIR_BAR
, irq
, 4);
384 #endif /* !BURN_BRIDGE */
386 pci_enable_busmaster(dev
);
388 /* Get more PCI information */
389 sc
->sc_pci_revid
= pci_get_revid(dev
);
390 sc
->sc_pci_subvid
= pci_get_subvendor(dev
);
391 sc
->sc_pci_subdid
= pci_get_subdevice(dev
);
396 sc
->sc_mem_rid
= BWI_PCIR_BAR
;
397 sc
->sc_mem_res
= bus_alloc_resource_any(dev
, SYS_RES_MEMORY
,
398 &sc
->sc_mem_rid
, RF_ACTIVE
);
399 if (sc
->sc_mem_res
== NULL
) {
400 device_printf(dev
, "can't allocate IO memory\n");
403 sc
->sc_mem_bt
= rman_get_bustag(sc
->sc_mem_res
);
404 sc
->sc_mem_bh
= rman_get_bushandle(sc
->sc_mem_res
);
410 sc
->sc_irq_res
= bus_alloc_resource_any(dev
, SYS_RES_IRQ
,
412 RF_SHAREABLE
| RF_ACTIVE
);
413 if (sc
->sc_irq_res
== NULL
) {
414 device_printf(dev
, "can't allocate irq\n");
421 error
= bwi_bbp_attach(sc
);
425 error
= bwi_bbp_power_on(sc
, BWI_CLOCK_MODE_FAST
);
429 if (BWI_REGWIN_EXIST(&sc
->sc_com_regwin
)) {
430 error
= bwi_set_clock_delay(sc
);
434 error
= bwi_set_clock_mode(sc
, BWI_CLOCK_MODE_FAST
);
438 error
= bwi_get_pwron_delay(sc
);
443 error
= bwi_bus_attach(sc
);
447 bwi_get_card_flags(sc
);
451 for (i
= 0; i
< sc
->sc_nmac
; ++i
) {
452 struct bwi_regwin
*old
;
454 mac
= &sc
->sc_mac
[i
];
455 error
= bwi_regwin_switch(sc
, &mac
->mac_regwin
, &old
);
459 error
= bwi_mac_lateattach(mac
);
463 error
= bwi_regwin_switch(sc
, old
, NULL
);
469 * XXX First MAC is known to exist
472 mac
= &sc
->sc_mac
[0];
475 bwi_bbp_power_off(sc
);
477 error
= bwi_dma_alloc(sc
);
482 ifp
->if_flags
= IFF_BROADCAST
| IFF_SIMPLEX
| IFF_MULTICAST
;
483 ifp
->if_init
= bwi_init
;
484 ifp
->if_ioctl
= bwi_ioctl
;
485 ifp
->if_start
= bwi_start
;
486 ifp
->if_watchdog
= bwi_watchdog
;
487 ifq_set_maxlen(&ifp
->if_snd
, IFQ_MAXLEN
);
488 ifq_set_ready(&ifp
->if_snd
);
491 sc
->sc_locale
= __SHIFTOUT(bwi_read_sprom(sc
, BWI_SPROM_CARD_INFO
),
492 BWI_SPROM_CARD_INFO_LOCALE
);
493 DPRINTF(sc
, "locale: %d\n", sc
->sc_locale
);
496 * Setup ratesets, phytype, channels and get MAC address
498 if (phy
->phy_mode
== IEEE80211_MODE_11B
||
499 phy
->phy_mode
== IEEE80211_MODE_11G
) {
502 ic
->ic_sup_rates
[IEEE80211_MODE_11B
] = bwi_rateset_11b
;
504 if (phy
->phy_mode
== IEEE80211_MODE_11B
) {
505 chan_flags
= IEEE80211_CHAN_B
;
506 ic
->ic_phytype
= IEEE80211_T_DS
;
508 chan_flags
= IEEE80211_CHAN_CCK
|
509 IEEE80211_CHAN_OFDM
|
512 ic
->ic_phytype
= IEEE80211_T_OFDM
;
513 ic
->ic_sup_rates
[IEEE80211_MODE_11G
] =
517 /* XXX depend on locale */
518 for (i
= 1; i
<= 14; ++i
) {
519 ic
->ic_channels
[i
].ic_freq
=
520 ieee80211_ieee2mhz(i
, IEEE80211_CHAN_2GHZ
);
521 ic
->ic_channels
[i
].ic_flags
= chan_flags
;
524 bwi_get_eaddr(sc
, BWI_SPROM_11BG_EADDR
, ic
->ic_myaddr
);
525 if (IEEE80211_IS_MULTICAST(ic
->ic_myaddr
)) {
526 bwi_get_eaddr(sc
, BWI_SPROM_11A_EADDR
, ic
->ic_myaddr
);
527 if (IEEE80211_IS_MULTICAST(ic
->ic_myaddr
)) {
528 device_printf(dev
, "invalid MAC address: "
529 "%6D\n", ic
->ic_myaddr
, ":");
532 } else if (phy
->phy_mode
== IEEE80211_MODE_11A
) {
537 panic("unknown phymode %d\n", phy
->phy_mode
);
540 sc
->sc_fw_version
= BWI_FW_VERSION3
;
541 sc
->sc_dwell_time
= 200;
543 ic
->ic_caps
= IEEE80211_C_SHSLOT
|
544 IEEE80211_C_SHPREAMBLE
|
547 ic
->ic_state
= IEEE80211_S_INIT
;
548 ic
->ic_opmode
= IEEE80211_M_STA
;
550 ic
->ic_updateslot
= bwi_updateslot
;
552 ieee80211_ifattach(ic
);
554 ic
->ic_headroom
= sizeof(struct bwi_txbuf_hdr
);
555 ic
->ic_flags_ext
|= IEEE80211_FEXT_SWBMISS
;
557 sc
->sc_newstate
= ic
->ic_newstate
;
558 ic
->ic_newstate
= bwi_newstate
;
560 ieee80211_media_init(ic
, bwi_media_change
, ieee80211_media_status
);
565 bpfattach_dlt(ifp
, DLT_IEEE802_11_RADIO
,
566 sizeof(struct ieee80211_frame
) + sizeof(sc
->sc_tx_th
),
569 sc
->sc_tx_th_len
= roundup(sizeof(sc
->sc_tx_th
), sizeof(uint32_t));
570 sc
->sc_tx_th
.wt_ihdr
.it_len
= htole16(sc
->sc_tx_th_len
);
571 sc
->sc_tx_th
.wt_ihdr
.it_present
= htole32(BWI_TX_RADIOTAP_PRESENT
);
573 sc
->sc_rx_th_len
= roundup(sizeof(sc
->sc_rx_th
), sizeof(uint32_t));
574 sc
->sc_rx_th
.wr_ihdr
.it_len
= htole16(sc
->sc_rx_th_len
);
575 sc
->sc_rx_th
.wr_ihdr
.it_present
= htole32(BWI_RX_RADIOTAP_PRESENT
);
577 error
= bus_setup_intr(dev
, sc
->sc_irq_res
, INTR_MPSAFE
, bwi_intr
, sc
,
578 &sc
->sc_irq_handle
, ifp
->if_serializer
);
580 device_printf(dev
, "can't setup intr\n");
582 ieee80211_ifdetach(ic
);
587 ieee80211_announce(ic
);
596 bwi_detach(device_t dev
)
598 struct bwi_softc
*sc
= device_get_softc(dev
);
600 if (device_is_attached(dev
)) {
601 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
604 lwkt_serialize_enter(ifp
->if_serializer
);
606 bus_teardown_intr(dev
, sc
->sc_irq_res
, sc
->sc_irq_handle
);
607 lwkt_serialize_exit(ifp
->if_serializer
);
610 ieee80211_ifdetach(&sc
->sc_ic
);
612 for (i
= 0; i
< sc
->sc_nmac
; ++i
)
613 bwi_mac_detach(&sc
->sc_mac
[i
]);
616 if (sc
->sc_irq_res
!= NULL
) {
617 bus_release_resource(dev
, SYS_RES_IRQ
, sc
->sc_irq_rid
,
621 if (sc
->sc_mem_res
!= NULL
) {
622 bus_release_resource(dev
, SYS_RES_MEMORY
, sc
->sc_mem_rid
,
632 bwi_shutdown(device_t dev
)
634 struct bwi_softc
*sc
= device_get_softc(dev
);
635 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
637 lwkt_serialize_enter(ifp
->if_serializer
);
639 lwkt_serialize_exit(ifp
->if_serializer
);
644 bwi_power_on(struct bwi_softc
*sc
, int with_pll
)
646 uint32_t gpio_in
, gpio_out
, gpio_en
;
649 gpio_in
= pci_read_config(sc
->sc_dev
, BWI_PCIR_GPIO_IN
, 4);
650 if (gpio_in
& BWI_PCIM_GPIO_PWR_ON
)
653 gpio_out
= pci_read_config(sc
->sc_dev
, BWI_PCIR_GPIO_OUT
, 4);
654 gpio_en
= pci_read_config(sc
->sc_dev
, BWI_PCIR_GPIO_ENABLE
, 4);
656 gpio_out
|= BWI_PCIM_GPIO_PWR_ON
;
657 gpio_en
|= BWI_PCIM_GPIO_PWR_ON
;
659 /* Turn off PLL first */
660 gpio_out
|= BWI_PCIM_GPIO_PLL_PWR_OFF
;
661 gpio_en
|= BWI_PCIM_GPIO_PLL_PWR_OFF
;
664 pci_write_config(sc
->sc_dev
, BWI_PCIR_GPIO_OUT
, gpio_out
, 4);
665 pci_write_config(sc
->sc_dev
, BWI_PCIR_GPIO_ENABLE
, gpio_en
, 4);
670 gpio_out
&= ~BWI_PCIM_GPIO_PLL_PWR_OFF
;
671 pci_write_config(sc
->sc_dev
, BWI_PCIR_GPIO_OUT
, gpio_out
, 4);
676 /* Clear "Signaled Target Abort" */
677 status
= pci_read_config(sc
->sc_dev
, PCIR_STATUS
, 2);
678 status
&= ~PCIM_STATUS_STABORT
;
679 pci_write_config(sc
->sc_dev
, PCIR_STATUS
, status
, 2);
683 bwi_power_off(struct bwi_softc
*sc
, int with_pll
)
685 uint32_t gpio_out
, gpio_en
;
687 pci_read_config(sc
->sc_dev
, BWI_PCIR_GPIO_IN
, 4); /* dummy read */
688 gpio_out
= pci_read_config(sc
->sc_dev
, BWI_PCIR_GPIO_OUT
, 4);
689 gpio_en
= pci_read_config(sc
->sc_dev
, BWI_PCIR_GPIO_ENABLE
, 4);
691 gpio_out
&= ~BWI_PCIM_GPIO_PWR_ON
;
692 gpio_en
|= BWI_PCIM_GPIO_PWR_ON
;
694 gpio_out
|= BWI_PCIM_GPIO_PLL_PWR_OFF
;
695 gpio_en
|= BWI_PCIM_GPIO_PLL_PWR_OFF
;
698 pci_write_config(sc
->sc_dev
, BWI_PCIR_GPIO_OUT
, gpio_out
, 4);
699 pci_write_config(sc
->sc_dev
, BWI_PCIR_GPIO_ENABLE
, gpio_en
, 4);
704 bwi_regwin_switch(struct bwi_softc
*sc
, struct bwi_regwin
*rw
,
705 struct bwi_regwin
**old_rw
)
712 if (!BWI_REGWIN_EXIST(rw
))
715 if (sc
->sc_cur_regwin
!= rw
) {
716 error
= bwi_regwin_select(sc
, rw
->rw_id
);
718 if_printf(&sc
->sc_ic
.ic_if
, "can't select regwin %d\n",
725 *old_rw
= sc
->sc_cur_regwin
;
726 sc
->sc_cur_regwin
= rw
;
731 bwi_regwin_select(struct bwi_softc
*sc
, int id
)
733 uint32_t win
= BWI_PCIM_REGWIN(id
);
737 for (i
= 0; i
< RETRY_MAX
; ++i
) {
738 pci_write_config(sc
->sc_dev
, BWI_PCIR_SEL_REGWIN
, win
, 4);
739 if (pci_read_config(sc
->sc_dev
, BWI_PCIR_SEL_REGWIN
, 4) == win
)
749 bwi_regwin_info(struct bwi_softc
*sc
, uint16_t *type
, uint8_t *rev
)
753 val
= CSR_READ_4(sc
, BWI_ID_HI
);
754 *type
= BWI_ID_HI_REGWIN_TYPE(val
);
755 *rev
= BWI_ID_HI_REGWIN_REV(val
);
757 DPRINTF(sc
, "regwin: type 0x%03x, rev %d, vendor 0x%04x\n",
758 *type
, *rev
, __SHIFTOUT(val
, BWI_ID_HI_REGWIN_VENDOR_MASK
));
762 bwi_bbp_attach(struct bwi_softc
*sc
)
764 #define N(arr) (int)(sizeof(arr) / sizeof(arr[0]))
765 uint16_t bbp_id
, rw_type
;
768 int error
, nregwin
, i
;
771 * Get 0th regwin information
772 * NOTE: 0th regwin should exist
774 error
= bwi_regwin_select(sc
, 0);
776 device_printf(sc
->sc_dev
, "can't select regwin 0\n");
779 bwi_regwin_info(sc
, &rw_type
, &rw_rev
);
786 if (rw_type
== BWI_REGWIN_T_COM
) {
787 info
= CSR_READ_4(sc
, BWI_INFO
);
788 bbp_id
= __SHIFTOUT(info
, BWI_INFO_BBPID_MASK
);
790 BWI_CREATE_REGWIN(&sc
->sc_com_regwin
, 0, rw_type
, rw_rev
);
792 sc
->sc_cap
= CSR_READ_4(sc
, BWI_CAPABILITY
);
794 uint16_t did
= pci_get_device(sc
->sc_dev
);
795 uint8_t revid
= pci_get_revid(sc
->sc_dev
);
797 for (i
= 0; i
< N(bwi_bbpid_map
); ++i
) {
798 if (did
>= bwi_bbpid_map
[i
].did_min
&&
799 did
<= bwi_bbpid_map
[i
].did_max
) {
800 bbp_id
= bwi_bbpid_map
[i
].bbp_id
;
805 device_printf(sc
->sc_dev
, "no BBP id for device id "
810 info
= __SHIFTIN(revid
, BWI_INFO_BBPREV_MASK
) |
811 __SHIFTIN(0, BWI_INFO_BBPPKG_MASK
);
815 * Find out number of regwins
818 if (rw_type
== BWI_REGWIN_T_COM
&& rw_rev
>= 4) {
819 nregwin
= __SHIFTOUT(info
, BWI_INFO_NREGWIN_MASK
);
821 for (i
= 0; i
< N(bwi_regwin_count
); ++i
) {
822 if (bwi_regwin_count
[i
].bbp_id
== bbp_id
) {
823 nregwin
= bwi_regwin_count
[i
].nregwin
;
828 device_printf(sc
->sc_dev
, "no number of win for "
829 "BBP id 0x%04x\n", bbp_id
);
834 /* Record BBP id/rev for later using */
835 sc
->sc_bbp_id
= bbp_id
;
836 sc
->sc_bbp_rev
= __SHIFTOUT(info
, BWI_INFO_BBPREV_MASK
);
837 sc
->sc_bbp_pkg
= __SHIFTOUT(info
, BWI_INFO_BBPPKG_MASK
);
838 device_printf(sc
->sc_dev
, "BBP id 0x%04x, BBP rev 0x%x, BBP pkg %d\n",
839 sc
->sc_bbp_id
, sc
->sc_bbp_rev
, sc
->sc_bbp_pkg
);
841 DPRINTF(sc
, "nregwin %d, cap 0x%08x\n", nregwin
, sc
->sc_cap
);
844 * Create rest of the regwins
847 /* Don't re-create common regwin, if it is already created */
848 i
= BWI_REGWIN_EXIST(&sc
->sc_com_regwin
) ? 1 : 0;
850 for (; i
< nregwin
; ++i
) {
852 * Get regwin information
854 error
= bwi_regwin_select(sc
, i
);
856 device_printf(sc
->sc_dev
,
857 "can't select regwin %d\n", i
);
860 bwi_regwin_info(sc
, &rw_type
, &rw_rev
);
864 * 1) Bus (PCI/PCIE) regwin
866 * Ignore rest types of regwin
868 if (rw_type
== BWI_REGWIN_T_BUSPCI
||
869 rw_type
== BWI_REGWIN_T_BUSPCIE
) {
870 if (BWI_REGWIN_EXIST(&sc
->sc_bus_regwin
)) {
871 device_printf(sc
->sc_dev
,
872 "bus regwin already exists\n");
874 BWI_CREATE_REGWIN(&sc
->sc_bus_regwin
, i
,
877 } else if (rw_type
== BWI_REGWIN_T_MAC
) {
878 /* XXX ignore return value */
879 bwi_mac_attach(sc
, i
, rw_rev
);
883 /* At least one MAC shold exist */
884 if (!BWI_REGWIN_EXIST(&sc
->sc_mac
[0].mac_regwin
)) {
885 device_printf(sc
->sc_dev
, "no MAC was found\n");
888 KKASSERT(sc
->sc_nmac
> 0);
890 /* Bus regwin must exist */
891 if (!BWI_REGWIN_EXIST(&sc
->sc_bus_regwin
)) {
892 device_printf(sc
->sc_dev
, "no bus regwin was found\n");
896 /* Start with first MAC */
897 error
= bwi_regwin_switch(sc
, &sc
->sc_mac
[0].mac_regwin
, NULL
);
906 bwi_bus_init(struct bwi_softc
*sc
, struct bwi_mac
*mac
)
908 struct bwi_regwin
*old
, *bus
;
912 bus
= &sc
->sc_bus_regwin
;
913 KKASSERT(sc
->sc_cur_regwin
== &mac
->mac_regwin
);
916 * Tell bus to generate requested interrupts
918 if (bus
->rw_rev
< 6 && bus
->rw_type
== BWI_REGWIN_T_BUSPCI
) {
920 * NOTE: Read BWI_FLAGS from MAC regwin
922 val
= CSR_READ_4(sc
, BWI_FLAGS
);
924 error
= bwi_regwin_switch(sc
, bus
, &old
);
928 CSR_SETBITS_4(sc
, BWI_INTRVEC
, (val
& BWI_FLAGS_INTR_MASK
));
932 mac_mask
= 1 << mac
->mac_id
;
934 error
= bwi_regwin_switch(sc
, bus
, &old
);
938 val
= pci_read_config(sc
->sc_dev
, BWI_PCIR_INTCTL
, 4);
939 val
|= mac_mask
<< 8;
940 pci_write_config(sc
->sc_dev
, BWI_PCIR_INTCTL
, val
, 4);
943 if (sc
->sc_flags
& BWI_F_BUS_INITED
)
946 if (bus
->rw_type
== BWI_REGWIN_T_BUSPCI
) {
948 * Enable prefetch and burst
950 CSR_SETBITS_4(sc
, BWI_BUS_CONFIG
,
951 BWI_BUS_CONFIG_PREFETCH
| BWI_BUS_CONFIG_BURST
);
953 if (bus
->rw_rev
< 5) {
954 struct bwi_regwin
*com
= &sc
->sc_com_regwin
;
957 * Configure timeouts for bus operation
961 * Set service timeout and request timeout
963 CSR_SETBITS_4(sc
, BWI_CONF_LO
,
964 __SHIFTIN(BWI_CONF_LO_SERVTO
, BWI_CONF_LO_SERVTO_MASK
) |
965 __SHIFTIN(BWI_CONF_LO_REQTO
, BWI_CONF_LO_REQTO_MASK
));
968 * If there is common regwin, we switch to that regwin
969 * and switch back to bus regwin once we have done.
971 if (BWI_REGWIN_EXIST(com
)) {
972 error
= bwi_regwin_switch(sc
, com
, NULL
);
977 /* Let bus know what we have changed */
978 CSR_WRITE_4(sc
, BWI_BUS_ADDR
, BWI_BUS_ADDR_MAGIC
);
979 CSR_READ_4(sc
, BWI_BUS_ADDR
); /* Flush */
980 CSR_WRITE_4(sc
, BWI_BUS_DATA
, 0);
981 CSR_READ_4(sc
, BWI_BUS_DATA
); /* Flush */
983 if (BWI_REGWIN_EXIST(com
)) {
984 error
= bwi_regwin_switch(sc
, bus
, NULL
);
988 } else if (bus
->rw_rev
>= 11) {
990 * Enable memory read multiple
992 CSR_SETBITS_4(sc
, BWI_BUS_CONFIG
, BWI_BUS_CONFIG_MRM
);
998 sc
->sc_flags
|= BWI_F_BUS_INITED
;
1000 return bwi_regwin_switch(sc
, old
, NULL
);
1004 bwi_get_card_flags(struct bwi_softc
*sc
)
1006 sc
->sc_card_flags
= bwi_read_sprom(sc
, BWI_SPROM_CARD_FLAGS
);
1007 if (sc
->sc_card_flags
== 0xffff)
1008 sc
->sc_card_flags
= 0;
1010 if (sc
->sc_pci_subvid
== PCI_VENDOR_APPLE
&&
1011 sc
->sc_pci_subdid
== 0x4e && /* XXX */
1012 sc
->sc_pci_revid
> 0x40)
1013 sc
->sc_card_flags
|= BWI_CARD_F_PA_GPIO9
;
1015 DPRINTF(sc
, "card flags 0x%04x\n", sc
->sc_card_flags
);
1019 bwi_get_eaddr(struct bwi_softc
*sc
, uint16_t eaddr_ofs
, uint8_t *eaddr
)
1023 for (i
= 0; i
< 3; ++i
) {
1024 *((uint16_t *)eaddr
+ i
) =
1025 htobe16(bwi_read_sprom(sc
, eaddr_ofs
+ 2 * i
));
1030 bwi_get_clock_freq(struct bwi_softc
*sc
, struct bwi_clock_freq
*freq
)
1032 struct bwi_regwin
*com
;
1037 bzero(freq
, sizeof(*freq
));
1038 com
= &sc
->sc_com_regwin
;
1040 KKASSERT(BWI_REGWIN_EXIST(com
));
1041 KKASSERT(sc
->sc_cur_regwin
== com
);
1042 KKASSERT(sc
->sc_cap
& BWI_CAP_CLKMODE
);
1045 * Calculate clock frequency
1049 if (com
->rw_rev
< 6) {
1050 val
= pci_read_config(sc
->sc_dev
, BWI_PCIR_GPIO_OUT
, 4);
1051 if (val
& BWI_PCIM_GPIO_OUT_CLKSRC
) {
1052 src
= BWI_CLKSRC_PCI
;
1055 src
= BWI_CLKSRC_CS_OSC
;
1058 } else if (com
->rw_rev
< 10) {
1059 val
= CSR_READ_4(sc
, BWI_CLOCK_CTRL
);
1061 src
= __SHIFTOUT(val
, BWI_CLOCK_CTRL_CLKSRC
);
1062 if (src
== BWI_CLKSRC_LP_OSC
) {
1065 div
= (__SHIFTOUT(val
, BWI_CLOCK_CTRL_FDIV
) + 1) << 2;
1067 /* Unknown source */
1068 if (src
>= BWI_CLKSRC_MAX
)
1069 src
= BWI_CLKSRC_CS_OSC
;
1072 val
= CSR_READ_4(sc
, BWI_CLOCK_INFO
);
1074 src
= BWI_CLKSRC_CS_OSC
;
1075 div
= (__SHIFTOUT(val
, BWI_CLOCK_INFO_FDIV
) + 1) << 2;
1078 KKASSERT(src
>= 0 && src
< BWI_CLKSRC_MAX
);
1081 DPRINTF(sc
, "clksrc %s\n",
1082 src
== BWI_CLKSRC_PCI
? "PCI" :
1083 (src
== BWI_CLKSRC_LP_OSC
? "LP_OSC" : "CS_OSC"));
1085 freq
->clkfreq_min
= bwi_clkfreq
[src
].freq_min
/ div
;
1086 freq
->clkfreq_max
= bwi_clkfreq
[src
].freq_max
/ div
;
1088 DPRINTF(sc
, "clkfreq min %u, max %u\n",
1089 freq
->clkfreq_min
, freq
->clkfreq_max
);
1093 bwi_set_clock_mode(struct bwi_softc
*sc
, enum bwi_clock_mode clk_mode
)
1095 struct bwi_regwin
*old
, *com
;
1096 uint32_t clk_ctrl
, clk_src
;
1097 int error
, pwr_off
= 0;
1099 com
= &sc
->sc_com_regwin
;
1100 if (!BWI_REGWIN_EXIST(com
))
1103 if (com
->rw_rev
>= 10 || com
->rw_rev
< 6)
1107 * For common regwin whose rev is [6, 10), the chip
1108 * must be capable to change clock mode.
1110 if ((sc
->sc_cap
& BWI_CAP_CLKMODE
) == 0)
1113 error
= bwi_regwin_switch(sc
, com
, &old
);
1117 if (clk_mode
== BWI_CLOCK_MODE_FAST
)
1118 bwi_power_on(sc
, 0); /* Don't turn on PLL */
1120 clk_ctrl
= CSR_READ_4(sc
, BWI_CLOCK_CTRL
);
1121 clk_src
= __SHIFTOUT(clk_ctrl
, BWI_CLOCK_CTRL_CLKSRC
);
1124 case BWI_CLOCK_MODE_FAST
:
1125 clk_ctrl
&= ~BWI_CLOCK_CTRL_SLOW
;
1126 clk_ctrl
|= BWI_CLOCK_CTRL_IGNPLL
;
1128 case BWI_CLOCK_MODE_SLOW
:
1129 clk_ctrl
|= BWI_CLOCK_CTRL_SLOW
;
1131 case BWI_CLOCK_MODE_DYN
:
1132 clk_ctrl
&= ~(BWI_CLOCK_CTRL_SLOW
|
1133 BWI_CLOCK_CTRL_IGNPLL
|
1134 BWI_CLOCK_CTRL_NODYN
);
1135 if (clk_src
!= BWI_CLKSRC_CS_OSC
) {
1136 clk_ctrl
|= BWI_CLOCK_CTRL_NODYN
;
1141 CSR_WRITE_4(sc
, BWI_CLOCK_CTRL
, clk_ctrl
);
1144 bwi_power_off(sc
, 0); /* Leave PLL as it is */
1146 return bwi_regwin_switch(sc
, old
, NULL
);
1150 bwi_set_clock_delay(struct bwi_softc
*sc
)
1152 struct bwi_regwin
*old
, *com
;
1155 com
= &sc
->sc_com_regwin
;
1156 if (!BWI_REGWIN_EXIST(com
))
1159 error
= bwi_regwin_switch(sc
, com
, &old
);
1163 if (sc
->sc_bbp_id
== BWI_BBPID_BCM4321
) {
1164 if (sc
->sc_bbp_rev
== 0)
1165 CSR_WRITE_4(sc
, BWI_CONTROL
, BWI_CONTROL_MAGIC0
);
1166 else if (sc
->sc_bbp_rev
== 1)
1167 CSR_WRITE_4(sc
, BWI_CONTROL
, BWI_CONTROL_MAGIC1
);
1170 if (sc
->sc_cap
& BWI_CAP_CLKMODE
) {
1171 if (com
->rw_rev
>= 10) {
1172 CSR_FILT_SETBITS_4(sc
, BWI_CLOCK_INFO
, 0xffff, 0x40000);
1174 struct bwi_clock_freq freq
;
1176 bwi_get_clock_freq(sc
, &freq
);
1177 CSR_WRITE_4(sc
, BWI_PLL_ON_DELAY
,
1178 howmany(freq
.clkfreq_max
* 150, 1000000));
1179 CSR_WRITE_4(sc
, BWI_FREQ_SEL_DELAY
,
1180 howmany(freq
.clkfreq_max
* 15, 1000000));
1184 return bwi_regwin_switch(sc
, old
, NULL
);
1190 struct bwi_softc
*sc
= xsc
;
1191 struct ieee80211com
*ic
= &sc
->sc_ic
;
1192 struct ifnet
*ifp
= &ic
->ic_if
;
1193 struct bwi_mac
*mac
;
1196 ASSERT_SERIALIZED(ifp
->if_serializer
);
1198 DPRINTF(sc
, "%s\n", __func__
);
1200 error
= bwi_stop(sc
);
1202 if_printf(ifp
, "can't stop\n");
1206 bwi_bbp_power_on(sc
, BWI_CLOCK_MODE_FAST
);
1210 mac
= &sc
->sc_mac
[0];
1211 error
= bwi_regwin_switch(sc
, &mac
->mac_regwin
, NULL
);
1215 error
= bwi_mac_init(mac
);
1219 bwi_bbp_power_on(sc
, BWI_CLOCK_MODE_DYN
);
1221 bcopy(IF_LLADDR(ifp
), ic
->ic_myaddr
, sizeof(ic
->ic_myaddr
));
1223 bwi_set_bssid(sc
, bwi_zero_addr
); /* Clear BSSID */
1224 bwi_set_addr_filter(sc
, BWI_ADDR_FILTER_MYADDR
, ic
->ic_myaddr
);
1226 bwi_mac_reset_hwkeys(mac
);
1228 if ((mac
->mac_flags
& BWI_MAC_F_HAS_TXSTATS
) == 0) {
1233 * Drain any possible pending TX status
1235 for (i
= 0; i
< NRETRY
; ++i
) {
1236 if ((CSR_READ_4(sc
, BWI_TXSTATUS_0
) &
1237 BWI_TXSTATUS_0_MORE
) == 0)
1239 CSR_READ_4(sc
, BWI_TXSTATUS_1
);
1242 if_printf(ifp
, "can't drain TX status\n");
1246 if (mac
->mac_phy
.phy_mode
== IEEE80211_MODE_11G
)
1247 bwi_mac_updateslot(mac
, 1);
1250 error
= bwi_mac_start(mac
);
1255 bwi_enable_intrs(sc
, BWI_INIT_INTRS
);
1257 ifp
->if_flags
|= IFF_RUNNING
;
1258 ifp
->if_flags
&= ~IFF_OACTIVE
;
1260 if (ic
->ic_opmode
!= IEEE80211_M_MONITOR
) {
1261 if (ic
->ic_roaming
!= IEEE80211_ROAMING_MANUAL
)
1262 ieee80211_new_state(ic
, IEEE80211_S_SCAN
, -1);
1264 ieee80211_new_state(ic
, IEEE80211_S_RUN
, -1);
1272 bwi_ioctl(struct ifnet
*ifp
, u_long cmd
, caddr_t req
, struct ucred
*cr
)
1274 struct bwi_softc
*sc
= ifp
->if_softc
;
1277 ASSERT_SERIALIZED(ifp
->if_serializer
);
1281 if ((ifp
->if_flags
& (IFF_UP
| IFF_RUNNING
)) ==
1282 (IFF_UP
| IFF_RUNNING
)) {
1283 struct bwi_mac
*mac
;
1286 KKASSERT(sc
->sc_cur_regwin
->rw_type
==
1288 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
1290 if ((ifp
->if_flags
& IFF_PROMISC
) &&
1291 (sc
->sc_flags
& BWI_F_PROMISC
) == 0) {
1293 sc
->sc_flags
|= BWI_F_PROMISC
;
1294 } else if ((ifp
->if_flags
& IFF_PROMISC
) == 0 &&
1295 (sc
->sc_flags
& BWI_F_PROMISC
)) {
1297 sc
->sc_flags
&= ~BWI_F_PROMISC
;
1301 bwi_mac_set_promisc(mac
, promisc
);
1304 if (ifp
->if_flags
& IFF_UP
) {
1305 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
1308 if (ifp
->if_flags
& IFF_RUNNING
)
1313 error
= ieee80211_ioctl(&sc
->sc_ic
, cmd
, req
, cr
);
1317 if (error
== ENETRESET
) {
1318 if ((ifp
->if_flags
& (IFF_UP
| IFF_RUNNING
)) ==
1319 (IFF_UP
| IFF_RUNNING
))
1327 bwi_start(struct ifnet
*ifp
)
1329 struct bwi_softc
*sc
= ifp
->if_softc
;
1330 struct ieee80211com
*ic
= &sc
->sc_ic
;
1331 struct bwi_txbuf_data
*tbd
= &sc
->sc_tx_bdata
[BWI_TX_DATA_RING
];
1334 ASSERT_SERIALIZED(ifp
->if_serializer
);
1336 if ((ifp
->if_flags
& IFF_OACTIVE
) ||
1337 (ifp
->if_flags
& IFF_RUNNING
) == 0)
1343 while (tbd
->tbd_buf
[idx
].tb_mbuf
== NULL
) {
1344 struct ieee80211_frame
*wh
;
1345 struct ieee80211_node
*ni
;
1349 if (!IF_QEMPTY(&ic
->ic_mgtq
)) {
1350 IF_DEQUEUE(&ic
->ic_mgtq
, m
);
1352 ni
= (struct ieee80211_node
*)m
->m_pkthdr
.rcvif
;
1353 m
->m_pkthdr
.rcvif
= NULL
;
1356 } else if (!ifq_is_empty(&ifp
->if_snd
)) {
1357 struct ether_header
*eh
;
1359 if (ic
->ic_state
!= IEEE80211_S_RUN
)
1362 m
= ifq_dequeue(&ifp
->if_snd
, NULL
);
1366 if (m
->m_len
< sizeof(*eh
)) {
1367 m
= m_pullup(m
, sizeof(*eh
));
1373 eh
= mtod(m
, struct ether_header
*);
1375 ni
= ieee80211_find_txnode(ic
, eh
->ether_dhost
);
1386 m
= ieee80211_encap(ic
, m
, ni
);
1388 ieee80211_free_node(ni
);
1396 if (ic
->ic_rawbpf
!= NULL
)
1397 bpf_mtap(ic
->ic_rawbpf
, m
);
1399 wh
= mtod(m
, struct ieee80211_frame
*);
1400 if (wh
->i_fc
[1] & IEEE80211_FC1_WEP
) {
1401 if (ieee80211_crypto_encap(ic
, ni
, m
) == NULL
) {
1402 ieee80211_free_node(ni
);
1408 wh
= NULL
; /* Catch any invalid use */
1411 ieee80211_free_node(ni
);
1415 if (bwi_encap(sc
, idx
, m
, ni
) != 0) {
1416 /* 'm' is freed in bwi_encap() if we reach here */
1418 ieee80211_free_node(ni
);
1425 idx
= (idx
+ 1) % BWI_TX_NDESC
;
1427 if (tbd
->tbd_used
+ BWI_TX_NSPRDESC
>= BWI_TX_NDESC
) {
1428 ifp
->if_flags
|= IFF_OACTIVE
;
1435 sc
->sc_tx_timer
= 5;
1440 bwi_watchdog(struct ifnet
*ifp
)
1442 struct bwi_softc
*sc
= ifp
->if_softc
;
1444 ASSERT_SERIALIZED(ifp
->if_serializer
);
1448 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
1451 if (sc
->sc_tx_timer
) {
1452 if (--sc
->sc_tx_timer
== 0) {
1453 if_printf(ifp
, "watchdog timeout\n");
1460 ieee80211_watchdog(&sc
->sc_ic
);
1464 bwi_stop(struct bwi_softc
*sc
)
1466 struct ieee80211com
*ic
= &sc
->sc_ic
;
1467 struct ifnet
*ifp
= &ic
->ic_if
;
1468 struct bwi_mac
*mac
;
1469 int i
, error
, pwr_off
= 0;
1471 ASSERT_SERIALIZED(ifp
->if_serializer
);
1473 DPRINTF(sc
, "%s\n", __func__
);
1475 ieee80211_new_state(ic
, IEEE80211_S_INIT
, -1);
1477 if (ifp
->if_flags
& IFF_RUNNING
) {
1478 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
1479 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
1481 bwi_disable_intrs(sc
, BWI_ALL_INTRS
);
1482 CSR_READ_4(sc
, BWI_MAC_INTR_MASK
);
1486 for (i
= 0; i
< sc
->sc_nmac
; ++i
) {
1487 struct bwi_regwin
*old_rw
;
1489 mac
= &sc
->sc_mac
[i
];
1490 if ((mac
->mac_flags
& BWI_MAC_F_INITED
) == 0)
1493 error
= bwi_regwin_switch(sc
, &mac
->mac_regwin
, &old_rw
);
1497 bwi_mac_shutdown(mac
);
1500 bwi_regwin_switch(sc
, old_rw
, NULL
);
1504 bwi_bbp_power_off(sc
);
1506 sc
->sc_tx_timer
= 0;
1508 ifp
->if_flags
&= ~(IFF_RUNNING
| IFF_OACTIVE
);
1515 struct bwi_softc
*sc
= xsc
;
1516 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
1517 uint32_t intr_status
;
1518 uint32_t txrx_intr_status
[BWI_TXRX_NRING
];
1521 ASSERT_SERIALIZED(ifp
->if_serializer
);
1523 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
1527 * Get interrupt status
1529 intr_status
= CSR_READ_4(sc
, BWI_MAC_INTR_STATUS
);
1530 if (intr_status
== 0xffffffff) /* Not for us */
1534 if_printf(ifp
, "intr status 0x%08x\n", intr_status
);
1537 intr_status
&= CSR_READ_4(sc
, BWI_MAC_INTR_MASK
);
1538 if (intr_status
== 0) /* Nothing is interesting */
1543 if_printf(ifp
, "TX/RX intr");
1545 for (i
= 0; i
< BWI_TXRX_NRING
; ++i
) {
1548 if (BWI_TXRX_IS_RX(i
))
1549 mask
= BWI_TXRX_RX_INTRS
;
1551 mask
= BWI_TXRX_TX_INTRS
;
1553 txrx_intr_status
[i
] =
1554 CSR_READ_4(sc
, BWI_TXRX_INTR_STATUS(i
)) & mask
;
1557 kprintf(", %d 0x%08x", i
, txrx_intr_status
[i
]);
1560 if (txrx_intr_status
[i
] & BWI_TXRX_INTR_ERROR
) {
1561 if_printf(ifp
, "intr fatal TX/RX (%d) error 0x%08x\n",
1562 i
, txrx_intr_status
[i
]);
1571 * Acknowledge interrupt
1573 CSR_WRITE_4(sc
, BWI_MAC_INTR_STATUS
, intr_status
);
1575 for (i
= 0; i
< BWI_TXRX_NRING
; ++i
)
1576 CSR_WRITE_4(sc
, BWI_TXRX_INTR_STATUS(i
), txrx_intr_status
[i
]);
1578 /* Disable all interrupts */
1579 bwi_disable_intrs(sc
, BWI_ALL_INTRS
);
1581 if (intr_status
& BWI_INTR_PHY_TXERR
)
1582 if_printf(ifp
, "intr PHY TX error\n");
1585 /* TODO: reset device */
1588 if (intr_status
& BWI_INTR_TBTT
) {
1589 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
1590 bwi_mac_config_ps((struct bwi_mac
*)sc
->sc_cur_regwin
);
1593 if (intr_status
& BWI_INTR_EO_ATIM
)
1594 if_printf(ifp
, "EO_ATIM\n");
1596 if (intr_status
& BWI_INTR_PMQ
) {
1598 if ((CSR_READ_4(sc
, BWI_MAC_PS_STATUS
) & 0x8) == 0)
1601 CSR_WRITE_2(sc
, BWI_MAC_PS_STATUS
, 0x2);
1604 if (intr_status
& BWI_INTR_NOISE
)
1605 if_printf(ifp
, "intr noise\n");
1607 if (txrx_intr_status
[0] & BWI_TXRX_INTR_RX
)
1610 if (txrx_intr_status
[3] & BWI_TXRX_INTR_RX
)
1611 sc
->sc_txeof_status(sc
);
1613 if (intr_status
& BWI_INTR_TX_DONE
)
1618 /* Re-enable interrupts */
1619 bwi_enable_intrs(sc
, BWI_INIT_INTRS
);
1623 bwi_newstate(struct ieee80211com
*ic
, enum ieee80211_state nstate
, int arg
)
1625 struct bwi_softc
*sc
= ic
->ic_if
.if_softc
;
1626 struct ifnet
*ifp
= &ic
->ic_if
;
1629 ASSERT_SERIALIZED(ifp
->if_serializer
);
1631 callout_stop(&sc
->sc_scan_ch
);
1632 callout_stop(&sc
->sc_calib_ch
);
1634 if (nstate
== IEEE80211_S_INIT
)
1637 error
= bwi_set_chan(sc
, ic
->ic_curchan
);
1639 if_printf(ifp
, "can't set channel to %u\n",
1640 ieee80211_chan2ieee(ic
, ic
->ic_curchan
));
1644 if (ic
->ic_opmode
== IEEE80211_M_MONITOR
) {
1646 } else if (nstate
== IEEE80211_S_RUN
) {
1647 struct bwi_mac
*mac
;
1649 bwi_set_bssid(sc
, ic
->ic_bss
->ni_bssid
);
1651 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
1652 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
1654 /* Initial TX power calibration */
1655 bwi_mac_calibrate_txpower(mac
);
1657 bwi_set_bssid(sc
, bwi_zero_addr
);
1661 error
= sc
->sc_newstate(ic
, nstate
, arg
);
1663 if (nstate
== IEEE80211_S_SCAN
) {
1664 callout_reset(&sc
->sc_scan_ch
,
1665 (sc
->sc_dwell_time
* hz
) / 1000,
1667 } else if (nstate
== IEEE80211_S_RUN
) {
1668 /* XXX 15 seconds */
1669 callout_reset(&sc
->sc_calib_ch
, hz
* 15, bwi_calibrate
, sc
);
1675 bwi_media_change(struct ifnet
*ifp
)
1679 ASSERT_SERIALIZED(ifp
->if_serializer
);
1681 error
= ieee80211_media_change(ifp
);
1682 if (error
!= ENETRESET
)
1685 if ((ifp
->if_flags
& (IFF_UP
| IFF_RUNNING
)) == (IFF_UP
| IFF_RUNNING
))
1686 bwi_init(ifp
->if_softc
);
1691 bwi_dma_alloc(struct bwi_softc
*sc
)
1693 int error
, i
, has_txstats
;
1694 bus_addr_t lowaddr
= 0;
1695 bus_size_t tx_ring_sz
, rx_ring_sz
, desc_sz
= 0;
1696 uint32_t txrx_ctrl_step
= 0;
1699 for (i
= 0; i
< sc
->sc_nmac
; ++i
) {
1700 if (sc
->sc_mac
[i
].mac_flags
& BWI_MAC_F_HAS_TXSTATS
) {
1706 switch (sc
->sc_bus_space
) {
1707 case BWI_BUS_SPACE_30BIT
:
1708 case BWI_BUS_SPACE_32BIT
:
1709 if (sc
->sc_bus_space
== BWI_BUS_SPACE_30BIT
)
1710 lowaddr
= BWI_BUS_SPACE_MAXADDR
;
1712 lowaddr
= BUS_SPACE_MAXADDR_32BIT
;
1713 desc_sz
= sizeof(struct bwi_desc32
);
1714 txrx_ctrl_step
= 0x20;
1716 sc
->sc_init_tx_ring
= bwi_init_tx_ring32
;
1717 sc
->sc_free_tx_ring
= bwi_free_tx_ring32
;
1718 sc
->sc_init_rx_ring
= bwi_init_rx_ring32
;
1719 sc
->sc_free_rx_ring
= bwi_free_rx_ring32
;
1720 sc
->sc_setup_rxdesc
= bwi_setup_rx_desc32
;
1721 sc
->sc_setup_txdesc
= bwi_setup_tx_desc32
;
1722 sc
->sc_rxeof
= bwi_rxeof32
;
1723 sc
->sc_start_tx
= bwi_start_tx32
;
1725 sc
->sc_init_txstats
= bwi_init_txstats32
;
1726 sc
->sc_free_txstats
= bwi_free_txstats32
;
1727 sc
->sc_txeof_status
= bwi_txeof_status32
;
1731 case BWI_BUS_SPACE_64BIT
:
1732 lowaddr
= BUS_SPACE_MAXADDR
; /* XXX */
1733 desc_sz
= sizeof(struct bwi_desc64
);
1734 txrx_ctrl_step
= 0x40;
1736 sc
->sc_init_tx_ring
= bwi_init_tx_ring64
;
1737 sc
->sc_free_tx_ring
= bwi_free_tx_ring64
;
1738 sc
->sc_init_rx_ring
= bwi_init_rx_ring64
;
1739 sc
->sc_free_rx_ring
= bwi_free_rx_ring64
;
1740 sc
->sc_setup_rxdesc
= bwi_setup_rx_desc64
;
1741 sc
->sc_setup_txdesc
= bwi_setup_tx_desc64
;
1742 sc
->sc_rxeof
= bwi_rxeof64
;
1743 sc
->sc_start_tx
= bwi_start_tx64
;
1745 sc
->sc_init_txstats
= bwi_init_txstats64
;
1746 sc
->sc_free_txstats
= bwi_free_txstats64
;
1747 sc
->sc_txeof_status
= bwi_txeof_status64
;
1752 KKASSERT(lowaddr
!= 0);
1753 KKASSERT(desc_sz
!= 0);
1754 KKASSERT(txrx_ctrl_step
!= 0);
1756 tx_ring_sz
= roundup(desc_sz
* BWI_TX_NDESC
, BWI_RING_ALIGN
);
1757 rx_ring_sz
= roundup(desc_sz
* BWI_RX_NDESC
, BWI_RING_ALIGN
);
1760 * Create top level DMA tag
1762 error
= bus_dma_tag_create(NULL
, BWI_ALIGN
, 0,
1763 lowaddr
, BUS_SPACE_MAXADDR
,
1766 BUS_SPACE_UNRESTRICTED
,
1767 BUS_SPACE_MAXSIZE_32BIT
,
1768 0, &sc
->sc_parent_dtag
);
1770 device_printf(sc
->sc_dev
, "can't create parent DMA tag\n");
1774 #define TXRX_CTRL(idx) (BWI_TXRX_CTRL_BASE + (idx) * txrx_ctrl_step)
1777 * Create TX ring DMA stuffs
1779 error
= bus_dma_tag_create(sc
->sc_parent_dtag
, BWI_RING_ALIGN
, 0,
1780 BUS_SPACE_MAXADDR
, BUS_SPACE_MAXADDR
,
1782 tx_ring_sz
, 1, BUS_SPACE_MAXSIZE_32BIT
,
1783 0, &sc
->sc_txring_dtag
);
1785 device_printf(sc
->sc_dev
, "can't create TX ring DMA tag\n");
1789 for (i
= 0; i
< BWI_TX_NRING
; ++i
) {
1790 error
= bwi_dma_ring_alloc(sc
, sc
->sc_txring_dtag
,
1791 &sc
->sc_tx_rdata
[i
], tx_ring_sz
,
1794 device_printf(sc
->sc_dev
, "%dth TX ring "
1795 "DMA alloc failed\n", i
);
1801 * Create RX ring DMA stuffs
1803 error
= bus_dma_tag_create(sc
->sc_parent_dtag
, BWI_RING_ALIGN
, 0,
1804 BUS_SPACE_MAXADDR
, BUS_SPACE_MAXADDR
,
1806 rx_ring_sz
, 1, BUS_SPACE_MAXSIZE_32BIT
,
1807 0, &sc
->sc_rxring_dtag
);
1809 device_printf(sc
->sc_dev
, "can't create RX ring DMA tag\n");
1813 error
= bwi_dma_ring_alloc(sc
, sc
->sc_rxring_dtag
, &sc
->sc_rx_rdata
,
1814 rx_ring_sz
, TXRX_CTRL(0));
1816 device_printf(sc
->sc_dev
, "RX ring DMA alloc failed\n");
1821 error
= bwi_dma_txstats_alloc(sc
, TXRX_CTRL(3), desc_sz
);
1823 device_printf(sc
->sc_dev
,
1824 "TX stats DMA alloc failed\n");
1831 return bwi_dma_mbuf_create(sc
);
1835 bwi_dma_free(struct bwi_softc
*sc
)
1837 if (sc
->sc_txring_dtag
!= NULL
) {
1840 for (i
= 0; i
< BWI_TX_NRING
; ++i
) {
1841 struct bwi_ring_data
*rd
= &sc
->sc_tx_rdata
[i
];
1843 if (rd
->rdata_desc
!= NULL
) {
1844 bus_dmamap_unload(sc
->sc_txring_dtag
,
1846 bus_dmamem_free(sc
->sc_txring_dtag
,
1851 bus_dma_tag_destroy(sc
->sc_txring_dtag
);
1854 if (sc
->sc_rxring_dtag
!= NULL
) {
1855 struct bwi_ring_data
*rd
= &sc
->sc_rx_rdata
;
1857 if (rd
->rdata_desc
!= NULL
) {
1858 bus_dmamap_unload(sc
->sc_rxring_dtag
, rd
->rdata_dmap
);
1859 bus_dmamem_free(sc
->sc_rxring_dtag
, rd
->rdata_desc
,
1862 bus_dma_tag_destroy(sc
->sc_rxring_dtag
);
1865 bwi_dma_txstats_free(sc
);
1866 bwi_dma_mbuf_destroy(sc
, BWI_TX_NRING
, 1);
1868 if (sc
->sc_parent_dtag
!= NULL
)
1869 bus_dma_tag_destroy(sc
->sc_parent_dtag
);
1873 bwi_dma_ring_alloc(struct bwi_softc
*sc
, bus_dma_tag_t dtag
,
1874 struct bwi_ring_data
*rd
, bus_size_t size
,
1879 error
= bus_dmamem_alloc(dtag
, &rd
->rdata_desc
,
1880 BUS_DMA_WAITOK
| BUS_DMA_ZERO
,
1883 device_printf(sc
->sc_dev
, "can't allocate DMA mem\n");
1887 error
= bus_dmamap_load(dtag
, rd
->rdata_dmap
, rd
->rdata_desc
, size
,
1888 bwi_dma_ring_addr
, &rd
->rdata_paddr
,
1891 device_printf(sc
->sc_dev
, "can't load DMA mem\n");
1892 bus_dmamem_free(dtag
, rd
->rdata_desc
, rd
->rdata_dmap
);
1893 rd
->rdata_desc
= NULL
;
1897 rd
->rdata_txrx_ctrl
= txrx_ctrl
;
1902 bwi_dma_txstats_alloc(struct bwi_softc
*sc
, uint32_t ctrl_base
,
1905 struct bwi_txstats_data
*st
;
1906 bus_size_t dma_size
;
1909 st
= kmalloc(sizeof(*st
), M_DEVBUF
, M_WAITOK
| M_ZERO
);
1910 sc
->sc_txstats
= st
;
1913 * Create TX stats descriptor DMA stuffs
1915 dma_size
= roundup(desc_sz
* BWI_TXSTATS_NDESC
, BWI_RING_ALIGN
);
1917 error
= bus_dma_tag_create(sc
->sc_parent_dtag
, BWI_RING_ALIGN
, 0,
1918 BUS_SPACE_MAXADDR
, BUS_SPACE_MAXADDR
,
1920 dma_size
, 1, BUS_SPACE_MAXSIZE_32BIT
,
1921 0, &st
->stats_ring_dtag
);
1923 device_printf(sc
->sc_dev
, "can't create txstats ring "
1928 error
= bus_dmamem_alloc(st
->stats_ring_dtag
, &st
->stats_ring
,
1929 BUS_DMA_WAITOK
| BUS_DMA_ZERO
,
1930 &st
->stats_ring_dmap
);
1932 device_printf(sc
->sc_dev
, "can't allocate txstats ring "
1934 bus_dma_tag_destroy(st
->stats_ring_dtag
);
1935 st
->stats_ring_dtag
= NULL
;
1939 error
= bus_dmamap_load(st
->stats_ring_dtag
, st
->stats_ring_dmap
,
1940 st
->stats_ring
, dma_size
,
1941 bwi_dma_ring_addr
, &st
->stats_ring_paddr
,
1944 device_printf(sc
->sc_dev
, "can't load txstats ring DMA mem\n");
1945 bus_dmamem_free(st
->stats_ring_dtag
, st
->stats_ring
,
1946 st
->stats_ring_dmap
);
1947 bus_dma_tag_destroy(st
->stats_ring_dtag
);
1948 st
->stats_ring_dtag
= NULL
;
1953 * Create TX stats DMA stuffs
1955 dma_size
= roundup(sizeof(struct bwi_txstats
) * BWI_TXSTATS_NDESC
,
1958 error
= bus_dma_tag_create(sc
->sc_parent_dtag
, BWI_ALIGN
, 0,
1959 BUS_SPACE_MAXADDR
, BUS_SPACE_MAXADDR
,
1961 dma_size
, 1, BUS_SPACE_MAXSIZE_32BIT
,
1962 0, &st
->stats_dtag
);
1964 device_printf(sc
->sc_dev
, "can't create txstats DMA tag\n");
1968 error
= bus_dmamem_alloc(st
->stats_dtag
, (void **)&st
->stats
,
1969 BUS_DMA_WAITOK
| BUS_DMA_ZERO
,
1972 device_printf(sc
->sc_dev
, "can't allocate txstats DMA mem\n");
1973 bus_dma_tag_destroy(st
->stats_dtag
);
1974 st
->stats_dtag
= NULL
;
1978 error
= bus_dmamap_load(st
->stats_dtag
, st
->stats_dmap
, st
->stats
,
1979 dma_size
, bwi_dma_ring_addr
, &st
->stats_paddr
,
1982 device_printf(sc
->sc_dev
, "can't load txstats DMA mem\n");
1983 bus_dmamem_free(st
->stats_dtag
, st
->stats
, st
->stats_dmap
);
1984 bus_dma_tag_destroy(st
->stats_dtag
);
1985 st
->stats_dtag
= NULL
;
1989 st
->stats_ctrl_base
= ctrl_base
;
1994 bwi_dma_txstats_free(struct bwi_softc
*sc
)
1996 struct bwi_txstats_data
*st
;
1998 if (sc
->sc_txstats
== NULL
)
2000 st
= sc
->sc_txstats
;
2002 if (st
->stats_ring_dtag
!= NULL
) {
2003 bus_dmamap_unload(st
->stats_ring_dtag
, st
->stats_ring_dmap
);
2004 bus_dmamem_free(st
->stats_ring_dtag
, st
->stats_ring
,
2005 st
->stats_ring_dmap
);
2006 bus_dma_tag_destroy(st
->stats_ring_dtag
);
2009 if (st
->stats_dtag
!= NULL
) {
2010 bus_dmamap_unload(st
->stats_dtag
, st
->stats_dmap
);
2011 bus_dmamem_free(st
->stats_dtag
, st
->stats
, st
->stats_dmap
);
2012 bus_dma_tag_destroy(st
->stats_dtag
);
2015 kfree(st
, M_DEVBUF
);
2019 bwi_dma_ring_addr(void *arg
, bus_dma_segment_t
*seg
, int nseg
, int error
)
2021 KASSERT(nseg
== 1, ("too many segments\n"));
2022 *((bus_addr_t
*)arg
) = seg
->ds_addr
;
2026 bwi_dma_mbuf_create(struct bwi_softc
*sc
)
2028 struct bwi_rxbuf_data
*rbd
= &sc
->sc_rx_bdata
;
2029 int i
, j
, k
, ntx
, error
;
2032 * Create TX/RX mbuf DMA tag
2034 error
= bus_dma_tag_create(sc
->sc_parent_dtag
, 1, 0,
2035 BUS_SPACE_MAXADDR
, BUS_SPACE_MAXADDR
,
2036 NULL
, NULL
, MCLBYTES
, 1,
2037 BUS_SPACE_MAXSIZE_32BIT
,
2038 0, &sc
->sc_buf_dtag
);
2040 device_printf(sc
->sc_dev
, "can't create mbuf DMA tag\n");
2047 * Create TX mbuf DMA map
2049 for (i
= 0; i
< BWI_TX_NRING
; ++i
) {
2050 struct bwi_txbuf_data
*tbd
= &sc
->sc_tx_bdata
[i
];
2052 for (j
= 0; j
< BWI_TX_NDESC
; ++j
) {
2053 error
= bus_dmamap_create(sc
->sc_buf_dtag
, 0,
2054 &tbd
->tbd_buf
[j
].tb_dmap
);
2056 device_printf(sc
->sc_dev
, "can't create "
2057 "%dth tbd, %dth DMA map\n", i
, j
);
2060 for (k
= 0; k
< j
; ++k
) {
2061 bus_dmamap_destroy(sc
->sc_buf_dtag
,
2062 tbd
->tbd_buf
[k
].tb_dmap
);
2071 * Create RX mbuf DMA map and a spare DMA map
2073 error
= bus_dmamap_create(sc
->sc_buf_dtag
, 0,
2074 &rbd
->rbd_tmp_dmap
);
2076 device_printf(sc
->sc_dev
,
2077 "can't create spare RX buf DMA map\n");
2081 for (j
= 0; j
< BWI_RX_NDESC
; ++j
) {
2082 error
= bus_dmamap_create(sc
->sc_buf_dtag
, 0,
2083 &rbd
->rbd_buf
[j
].rb_dmap
);
2085 device_printf(sc
->sc_dev
, "can't create %dth "
2086 "RX buf DMA map\n", j
);
2088 for (k
= 0; k
< j
; ++k
) {
2089 bus_dmamap_destroy(sc
->sc_buf_dtag
,
2090 rbd
->rbd_buf
[j
].rb_dmap
);
2092 bus_dmamap_destroy(sc
->sc_buf_dtag
,
2100 bwi_dma_mbuf_destroy(sc
, ntx
, 0);
2105 bwi_dma_mbuf_destroy(struct bwi_softc
*sc
, int ntx
, int nrx
)
2109 if (sc
->sc_buf_dtag
== NULL
)
2112 for (i
= 0; i
< ntx
; ++i
) {
2113 struct bwi_txbuf_data
*tbd
= &sc
->sc_tx_bdata
[i
];
2115 for (j
= 0; j
< BWI_TX_NDESC
; ++j
) {
2116 struct bwi_txbuf
*tb
= &tbd
->tbd_buf
[j
];
2118 if (tb
->tb_mbuf
!= NULL
) {
2119 bus_dmamap_unload(sc
->sc_buf_dtag
,
2121 m_freem(tb
->tb_mbuf
);
2123 if (tb
->tb_ni
!= NULL
)
2124 ieee80211_free_node(tb
->tb_ni
);
2125 bus_dmamap_destroy(sc
->sc_buf_dtag
, tb
->tb_dmap
);
2130 struct bwi_rxbuf_data
*rbd
= &sc
->sc_rx_bdata
;
2132 bus_dmamap_destroy(sc
->sc_buf_dtag
, rbd
->rbd_tmp_dmap
);
2133 for (j
= 0; j
< BWI_RX_NDESC
; ++j
) {
2134 struct bwi_rxbuf
*rb
= &rbd
->rbd_buf
[j
];
2136 if (rb
->rb_mbuf
!= NULL
) {
2137 bus_dmamap_unload(sc
->sc_buf_dtag
,
2139 m_freem(rb
->rb_mbuf
);
2141 bus_dmamap_destroy(sc
->sc_buf_dtag
, rb
->rb_dmap
);
2145 bus_dma_tag_destroy(sc
->sc_buf_dtag
);
2146 sc
->sc_buf_dtag
= NULL
;
2150 bwi_enable_intrs(struct bwi_softc
*sc
, uint32_t enable_intrs
)
2152 CSR_SETBITS_4(sc
, BWI_MAC_INTR_MASK
, enable_intrs
);
2156 bwi_disable_intrs(struct bwi_softc
*sc
, uint32_t disable_intrs
)
2158 CSR_CLRBITS_4(sc
, BWI_MAC_INTR_MASK
, disable_intrs
);
2162 bwi_init_tx_ring32(struct bwi_softc
*sc
, int ring_idx
)
2164 struct bwi_ring_data
*rd
;
2165 struct bwi_txbuf_data
*tbd
;
2166 uint32_t val
, addr_hi
, addr_lo
;
2168 KKASSERT(ring_idx
< BWI_TX_NRING
);
2169 rd
= &sc
->sc_tx_rdata
[ring_idx
];
2170 tbd
= &sc
->sc_tx_bdata
[ring_idx
];
2175 bzero(rd
->rdata_desc
, sizeof(struct bwi_desc32
) * BWI_TX_NDESC
);
2176 bus_dmamap_sync(sc
->sc_txring_dtag
, rd
->rdata_dmap
,
2177 BUS_DMASYNC_PREWRITE
);
2179 addr_lo
= __SHIFTOUT(rd
->rdata_paddr
, BWI_TXRX32_RINGINFO_ADDR_MASK
);
2180 addr_hi
= __SHIFTOUT(rd
->rdata_paddr
, BWI_TXRX32_RINGINFO_FUNC_MASK
);
2182 val
= __SHIFTIN(addr_lo
, BWI_TXRX32_RINGINFO_ADDR_MASK
) |
2183 __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX
,
2184 BWI_TXRX32_RINGINFO_FUNC_MASK
);
2185 CSR_WRITE_4(sc
, rd
->rdata_txrx_ctrl
+ BWI_TX32_RINGINFO
, val
);
2187 val
= __SHIFTIN(addr_hi
, BWI_TXRX32_CTRL_ADDRHI_MASK
) |
2188 BWI_TXRX32_CTRL_ENABLE
;
2189 CSR_WRITE_4(sc
, rd
->rdata_txrx_ctrl
+ BWI_TX32_CTRL
, val
);
2195 bwi_init_rxdesc_ring32(struct bwi_softc
*sc
, uint32_t ctrl_base
,
2196 bus_addr_t paddr
, int hdr_size
, int ndesc
)
2198 uint32_t val
, addr_hi
, addr_lo
;
2200 addr_lo
= __SHIFTOUT(paddr
, BWI_TXRX32_RINGINFO_ADDR_MASK
);
2201 addr_hi
= __SHIFTOUT(paddr
, BWI_TXRX32_RINGINFO_FUNC_MASK
);
2203 val
= __SHIFTIN(addr_lo
, BWI_TXRX32_RINGINFO_ADDR_MASK
) |
2204 __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX
,
2205 BWI_TXRX32_RINGINFO_FUNC_MASK
);
2206 CSR_WRITE_4(sc
, ctrl_base
+ BWI_RX32_RINGINFO
, val
);
2208 val
= __SHIFTIN(hdr_size
, BWI_RX32_CTRL_HDRSZ_MASK
) |
2209 __SHIFTIN(addr_hi
, BWI_TXRX32_CTRL_ADDRHI_MASK
) |
2210 BWI_TXRX32_CTRL_ENABLE
;
2211 CSR_WRITE_4(sc
, ctrl_base
+ BWI_RX32_CTRL
, val
);
2213 CSR_WRITE_4(sc
, ctrl_base
+ BWI_RX32_INDEX
,
2214 (ndesc
- 1) * sizeof(struct bwi_desc32
));
2218 bwi_init_rx_ring32(struct bwi_softc
*sc
)
2220 struct bwi_ring_data
*rd
= &sc
->sc_rx_rdata
;
2223 sc
->sc_rx_bdata
.rbd_idx
= 0;
2225 for (i
= 0; i
< BWI_RX_NDESC
; ++i
) {
2226 error
= bwi_newbuf(sc
, i
, 1);
2228 if_printf(&sc
->sc_ic
.ic_if
,
2229 "can't allocate %dth RX buffer\n", i
);
2233 bus_dmamap_sync(sc
->sc_rxring_dtag
, rd
->rdata_dmap
,
2234 BUS_DMASYNC_PREWRITE
);
2236 bwi_init_rxdesc_ring32(sc
, rd
->rdata_txrx_ctrl
, rd
->rdata_paddr
,
2237 sizeof(struct bwi_rxbuf_hdr
), BWI_RX_NDESC
);
2242 bwi_init_txstats32(struct bwi_softc
*sc
)
2244 struct bwi_txstats_data
*st
= sc
->sc_txstats
;
2245 bus_addr_t stats_paddr
;
2248 bzero(st
->stats
, BWI_TXSTATS_NDESC
* sizeof(struct bwi_txstats
));
2249 bus_dmamap_sync(st
->stats_dtag
, st
->stats_dmap
, BUS_DMASYNC_PREWRITE
);
2253 stats_paddr
= st
->stats_paddr
;
2254 for (i
= 0; i
< BWI_TXSTATS_NDESC
; ++i
) {
2255 bwi_setup_desc32(sc
, st
->stats_ring
, BWI_TXSTATS_NDESC
, i
,
2256 stats_paddr
, sizeof(struct bwi_txstats
), 0);
2257 stats_paddr
+= sizeof(struct bwi_txstats
);
2259 bus_dmamap_sync(st
->stats_ring_dtag
, st
->stats_ring_dmap
,
2260 BUS_DMASYNC_PREWRITE
);
2262 bwi_init_rxdesc_ring32(sc
, st
->stats_ctrl_base
,
2263 st
->stats_ring_paddr
, 0, BWI_TXSTATS_NDESC
);
2268 bwi_setup_rx_desc32(struct bwi_softc
*sc
, int buf_idx
, bus_addr_t paddr
,
2271 struct bwi_ring_data
*rd
= &sc
->sc_rx_rdata
;
2273 KKASSERT(buf_idx
< BWI_RX_NDESC
);
2274 bwi_setup_desc32(sc
, rd
->rdata_desc
, BWI_RX_NDESC
, buf_idx
,
2279 bwi_setup_tx_desc32(struct bwi_softc
*sc
, struct bwi_ring_data
*rd
,
2280 int buf_idx
, bus_addr_t paddr
, int buf_len
)
2282 KKASSERT(buf_idx
< BWI_TX_NDESC
);
2283 bwi_setup_desc32(sc
, rd
->rdata_desc
, BWI_TX_NDESC
, buf_idx
,
2288 bwi_init_tx_ring64(struct bwi_softc
*sc
, int ring_idx
)
2295 bwi_init_rx_ring64(struct bwi_softc
*sc
)
2302 bwi_init_txstats64(struct bwi_softc
*sc
)
2309 bwi_setup_rx_desc64(struct bwi_softc
*sc
, int buf_idx
, bus_addr_t paddr
,
2316 bwi_setup_tx_desc64(struct bwi_softc
*sc
, struct bwi_ring_data
*rd
,
2317 int buf_idx
, bus_addr_t paddr
, int buf_len
)
2323 bwi_dma_buf_addr(void *arg
, bus_dma_segment_t
*seg
, int nseg
,
2324 bus_size_t mapsz __unused
, int error
)
2327 KASSERT(nseg
== 1, ("too many segments(%d)\n", nseg
));
2328 *((bus_addr_t
*)arg
) = seg
->ds_addr
;
2333 bwi_newbuf(struct bwi_softc
*sc
, int buf_idx
, int init
)
2335 struct bwi_rxbuf_data
*rbd
= &sc
->sc_rx_bdata
;
2336 struct bwi_rxbuf
*rxbuf
= &rbd
->rbd_buf
[buf_idx
];
2337 struct bwi_rxbuf_hdr
*hdr
;
2343 KKASSERT(buf_idx
< BWI_RX_NDESC
);
2345 m
= m_getcl(init
? MB_WAIT
: MB_DONTWAIT
, MT_DATA
, M_PKTHDR
);
2350 * If the NIC is up and running, we need to:
2351 * - Clear RX buffer's header.
2352 * - Restore RX descriptor settings.
2359 m
->m_len
= m
->m_pkthdr
.len
= MCLBYTES
;
2362 * Try to load RX buf into temporary DMA map
2364 error
= bus_dmamap_load_mbuf(sc
->sc_buf_dtag
, rbd
->rbd_tmp_dmap
, m
,
2365 bwi_dma_buf_addr
, &paddr
,
2366 init
? BUS_DMA_WAITOK
: BUS_DMA_NOWAIT
);
2371 * See the comment above
2380 bus_dmamap_unload(sc
->sc_buf_dtag
, rxbuf
->rb_dmap
);
2382 rxbuf
->rb_paddr
= paddr
;
2385 * Swap RX buf's DMA map with the loaded temporary one
2387 map
= rxbuf
->rb_dmap
;
2388 rxbuf
->rb_dmap
= rbd
->rbd_tmp_dmap
;
2389 rbd
->rbd_tmp_dmap
= map
;
2393 * Clear RX buf header
2395 hdr
= mtod(rxbuf
->rb_mbuf
, struct bwi_rxbuf_hdr
*);
2396 bzero(hdr
, sizeof(*hdr
));
2397 bus_dmamap_sync(sc
->sc_buf_dtag
, rxbuf
->rb_dmap
, BUS_DMASYNC_PREWRITE
);
2400 * Setup RX buf descriptor
2402 sc
->sc_setup_rxdesc(sc
, buf_idx
, rxbuf
->rb_paddr
,
2403 rxbuf
->rb_mbuf
->m_len
- sizeof(*hdr
));
2408 bwi_set_addr_filter(struct bwi_softc
*sc
, uint16_t addr_ofs
,
2409 const uint8_t *addr
)
2413 CSR_WRITE_2(sc
, BWI_ADDR_FILTER_CTRL
,
2414 BWI_ADDR_FILTER_CTRL_SET
| addr_ofs
);
2416 for (i
= 0; i
< (IEEE80211_ADDR_LEN
/ 2); ++i
) {
2419 addr_val
= (uint16_t)addr
[i
* 2] |
2420 (((uint16_t)addr
[(i
* 2) + 1]) << 8);
2421 CSR_WRITE_2(sc
, BWI_ADDR_FILTER_DATA
, addr_val
);
2426 bwi_set_chan(struct bwi_softc
*sc
, struct ieee80211_channel
*c
)
2428 struct ieee80211com
*ic
= &sc
->sc_ic
;
2429 struct ifnet
*ifp
= &ic
->ic_if
;
2430 struct bwi_mac
*mac
;
2434 ASSERT_SERIALIZED(ifp
->if_serializer
);
2436 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
2437 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
2439 chan
= ieee80211_chan2ieee(ic
, c
);
2441 bwi_rf_set_chan(mac
, chan
, 0);
2444 * Setup radio tap channel freq and flags
2446 if (IEEE80211_IS_CHAN_G(c
))
2447 flags
= IEEE80211_CHAN_G
;
2449 flags
= IEEE80211_CHAN_B
;
2451 sc
->sc_tx_th
.wt_chan_freq
= sc
->sc_rx_th
.wr_chan_freq
=
2452 htole16(c
->ic_freq
);
2453 sc
->sc_tx_th
.wt_chan_flags
= sc
->sc_rx_th
.wr_chan_flags
=
2460 bwi_next_scan(void *xsc
)
2462 struct bwi_softc
*sc
= xsc
;
2463 struct ieee80211com
*ic
= &sc
->sc_ic
;
2464 struct ifnet
*ifp
= &ic
->ic_if
;
2466 lwkt_serialize_enter(ifp
->if_serializer
);
2468 if (ic
->ic_state
== IEEE80211_S_SCAN
)
2469 ieee80211_next_scan(ic
);
2471 lwkt_serialize_exit(ifp
->if_serializer
);
2475 bwi_rxeof(struct bwi_softc
*sc
, int end_idx
)
2477 struct bwi_ring_data
*rd
= &sc
->sc_rx_rdata
;
2478 struct bwi_rxbuf_data
*rbd
= &sc
->sc_rx_bdata
;
2479 struct ieee80211com
*ic
= &sc
->sc_ic
;
2480 struct ifnet
*ifp
= &ic
->ic_if
;
2484 while (idx
!= end_idx
) {
2485 struct bwi_rxbuf
*rb
= &rbd
->rbd_buf
[idx
];
2486 struct bwi_rxbuf_hdr
*hdr
;
2487 struct ieee80211_frame_min
*wh
;
2488 struct ieee80211_node
*ni
;
2490 const uint8_t *plcp
;
2492 int buflen
, wh_ofs
, hdr_extra
, rssi
;
2495 bus_dmamap_sync(sc
->sc_buf_dtag
, rb
->rb_dmap
,
2496 BUS_DMASYNC_POSTREAD
);
2498 if (bwi_newbuf(sc
, idx
, 0)) {
2503 hdr
= mtod(m
, struct bwi_rxbuf_hdr
*);
2504 flags2
= le16toh(hdr
->rxh_flags2
);
2507 if (flags2
& BWI_RXH_F2_TYPE2FRAME
)
2509 wh_ofs
= hdr_extra
+ 6; /* XXX magic number */
2511 buflen
= le16toh(hdr
->rxh_buflen
);
2512 if (buflen
< BWI_FRAME_MIN_LEN(wh_ofs
)) {
2513 if_printf(ifp
, "short frame %d, hdr_extra %d\n",
2520 plcp
= ((const uint8_t *)(hdr
+ 1) + hdr_extra
);
2521 rssi
= bwi_calc_rssi(sc
, hdr
);
2523 m
->m_pkthdr
.rcvif
= ifp
;
2524 m
->m_len
= m
->m_pkthdr
.len
= buflen
+ sizeof(*hdr
);
2525 m_adj(m
, sizeof(*hdr
) + wh_ofs
);
2528 if (sc
->sc_drvbpf
!= NULL
)
2529 bwi_rx_radiotap(sc
, m
, hdr
, plcp
, rssi
);
2531 m_adj(m
, -IEEE80211_CRC_LEN
);
2533 wh
= mtod(m
, struct ieee80211_frame_min
*);
2534 ni
= ieee80211_find_rxnode(ic
, wh
);
2536 ieee80211_input(ic
, m
, ni
, rssi
- BWI_NOISE_FLOOR
,
2537 le16toh(hdr
->rxh_tsf
));
2538 ieee80211_free_node(ni
);
2540 idx
= (idx
+ 1) % BWI_RX_NDESC
;
2544 bus_dmamap_sync(sc
->sc_rxring_dtag
, rd
->rdata_dmap
,
2545 BUS_DMASYNC_PREWRITE
);
2549 bwi_rxeof32(struct bwi_softc
*sc
)
2551 uint32_t val
, rx_ctrl
;
2554 rx_ctrl
= sc
->sc_rx_rdata
.rdata_txrx_ctrl
;
2556 val
= CSR_READ_4(sc
, rx_ctrl
+ BWI_RX32_STATUS
);
2557 end_idx
= __SHIFTOUT(val
, BWI_RX32_STATUS_INDEX_MASK
) /
2558 sizeof(struct bwi_desc32
);
2560 bwi_rxeof(sc
, end_idx
);
2562 CSR_WRITE_4(sc
, rx_ctrl
+ BWI_RX32_INDEX
,
2563 end_idx
* sizeof(struct bwi_desc32
));
2567 bwi_rxeof64(struct bwi_softc
*sc
)
2573 bwi_reset_rx_ring32(struct bwi_softc
*sc
, uint32_t rx_ctrl
)
2577 CSR_WRITE_4(sc
, rx_ctrl
+ BWI_RX32_CTRL
, 0);
2581 for (i
= 0; i
< NRETRY
; ++i
) {
2584 status
= CSR_READ_4(sc
, rx_ctrl
+ BWI_RX32_STATUS
);
2585 if (__SHIFTOUT(status
, BWI_RX32_STATUS_STATE_MASK
) ==
2586 BWI_RX32_STATUS_STATE_DISABLED
)
2592 if_printf(&sc
->sc_ic
.ic_if
, "reset rx ring timedout\n");
2596 CSR_WRITE_4(sc
, rx_ctrl
+ BWI_RX32_RINGINFO
, 0);
2600 bwi_free_txstats32(struct bwi_softc
*sc
)
2602 bwi_reset_rx_ring32(sc
, sc
->sc_txstats
->stats_ctrl_base
);
2606 bwi_free_rx_ring32(struct bwi_softc
*sc
)
2608 struct bwi_ring_data
*rd
= &sc
->sc_rx_rdata
;
2609 struct bwi_rxbuf_data
*rbd
= &sc
->sc_rx_bdata
;
2612 bwi_reset_rx_ring32(sc
, rd
->rdata_txrx_ctrl
);
2614 for (i
= 0; i
< BWI_RX_NDESC
; ++i
) {
2615 struct bwi_rxbuf
*rb
= &rbd
->rbd_buf
[i
];
2617 if (rb
->rb_mbuf
!= NULL
) {
2618 bus_dmamap_unload(sc
->sc_buf_dtag
, rb
->rb_dmap
);
2619 m_freem(rb
->rb_mbuf
);
2626 bwi_free_tx_ring32(struct bwi_softc
*sc
, int ring_idx
)
2628 struct bwi_ring_data
*rd
;
2629 struct bwi_txbuf_data
*tbd
;
2630 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
2631 uint32_t state
, val
;
2634 KKASSERT(ring_idx
< BWI_TX_NRING
);
2635 rd
= &sc
->sc_tx_rdata
[ring_idx
];
2636 tbd
= &sc
->sc_tx_bdata
[ring_idx
];
2640 for (i
= 0; i
< NRETRY
; ++i
) {
2641 val
= CSR_READ_4(sc
, rd
->rdata_txrx_ctrl
+ BWI_TX32_STATUS
);
2642 state
= __SHIFTOUT(val
, BWI_TX32_STATUS_STATE_MASK
);
2643 if (state
== BWI_TX32_STATUS_STATE_DISABLED
||
2644 state
== BWI_TX32_STATUS_STATE_IDLE
||
2645 state
== BWI_TX32_STATUS_STATE_STOPPED
)
2651 if_printf(ifp
, "wait for TX ring(%d) stable timed out\n",
2655 CSR_WRITE_4(sc
, rd
->rdata_txrx_ctrl
+ BWI_TX32_CTRL
, 0);
2656 for (i
= 0; i
< NRETRY
; ++i
) {
2657 val
= CSR_READ_4(sc
, rd
->rdata_txrx_ctrl
+ BWI_TX32_STATUS
);
2658 state
= __SHIFTOUT(val
, BWI_TX32_STATUS_STATE_MASK
);
2659 if (state
== BWI_TX32_STATUS_STATE_DISABLED
)
2665 if_printf(ifp
, "reset TX ring (%d) timed out\n", ring_idx
);
2671 CSR_WRITE_4(sc
, rd
->rdata_txrx_ctrl
+ BWI_TX32_RINGINFO
, 0);
2673 for (i
= 0; i
< BWI_TX_NDESC
; ++i
) {
2674 struct bwi_txbuf
*tb
= &tbd
->tbd_buf
[i
];
2676 if (tb
->tb_mbuf
!= NULL
) {
2677 bus_dmamap_unload(sc
->sc_buf_dtag
, tb
->tb_dmap
);
2678 m_freem(tb
->tb_mbuf
);
2681 if (tb
->tb_ni
!= NULL
) {
2682 ieee80211_free_node(tb
->tb_ni
);
2689 bwi_free_txstats64(struct bwi_softc
*sc
)
2695 bwi_free_rx_ring64(struct bwi_softc
*sc
)
2701 bwi_free_tx_ring64(struct bwi_softc
*sc
, int ring_idx
)
2706 /* XXX does not belong here */
2708 bwi_rate2plcp(uint8_t rate
)
2710 rate
&= IEEE80211_RATE_VAL
;
2714 case 4: return 0x14;
2715 case 11: return 0x37;
2716 case 22: return 0x6e;
2717 case 44: return 0xdc;
2719 case 12: return 0xb;
2720 case 18: return 0xf;
2721 case 24: return 0xa;
2722 case 36: return 0xe;
2723 case 48: return 0x9;
2724 case 72: return 0xd;
2725 case 96: return 0x8;
2726 case 108: return 0xc;
2729 panic("unsupported rate %u\n", rate
);
2733 /* XXX does not belong here */
2734 #define IEEE80211_OFDM_PLCP_RATE_MASK __BITS(3, 0)
2735 #define IEEE80211_OFDM_PLCP_LEN_MASK __BITS(16, 5)
2737 static __inline
void
2738 bwi_ofdm_plcp_header(uint32_t *plcp0
, int pkt_len
, uint8_t rate
)
2742 plcp
= __SHIFTIN(bwi_rate2plcp(rate
), IEEE80211_OFDM_PLCP_RATE_MASK
) |
2743 __SHIFTIN(pkt_len
, IEEE80211_OFDM_PLCP_LEN_MASK
);
2744 *plcp0
= htole32(plcp
);
2747 /* XXX does not belong here */
2748 struct ieee80211_ds_plcp_hdr
{
2755 #define IEEE80211_DS_PLCP_SERVICE_LOCKED 0x04
2756 #define IEEE80211_DS_PLCL_SERVICE_PBCC 0x08
2757 #define IEEE80211_DS_PLCP_SERVICE_LENEXT5 0x20
2758 #define IEEE80211_DS_PLCP_SERVICE_LENEXT6 0x40
2759 #define IEEE80211_DS_PLCP_SERVICE_LENEXT7 0x80
2761 static __inline
void
2762 bwi_ds_plcp_header(struct ieee80211_ds_plcp_hdr
*plcp
, int pkt_len
,
2765 int len
, service
, pkt_bitlen
;
2767 pkt_bitlen
= pkt_len
* NBBY
;
2768 len
= howmany(pkt_bitlen
* 2, rate
);
2770 service
= IEEE80211_DS_PLCP_SERVICE_LOCKED
;
2771 if (rate
== (11 * 2)) {
2775 * PLCP service field needs to be adjusted,
2776 * if TX rate is 11Mbytes/s
2778 pkt_bitlen1
= len
* 11;
2779 if (pkt_bitlen1
- pkt_bitlen
>= NBBY
)
2780 service
|= IEEE80211_DS_PLCP_SERVICE_LENEXT7
;
2783 plcp
->i_signal
= bwi_rate2plcp(rate
);
2784 plcp
->i_service
= service
;
2785 plcp
->i_length
= htole16(len
);
2786 /* NOTE: do NOT touch i_crc */
2789 static __inline
void
2790 bwi_plcp_header(void *plcp
, int pkt_len
, uint8_t rate
)
2792 enum ieee80211_modtype modtype
;
2795 * Assume caller has zeroed 'plcp'
2798 modtype
= ieee80211_rate2modtype(rate
);
2799 if (modtype
== IEEE80211_MODTYPE_OFDM
)
2800 bwi_ofdm_plcp_header(plcp
, pkt_len
, rate
);
2801 else if (modtype
== IEEE80211_MODTYPE_DS
)
2802 bwi_ds_plcp_header(plcp
, pkt_len
, rate
);
2804 panic("unsupport modulation type %u\n", modtype
);
2808 bwi_encap(struct bwi_softc
*sc
, int idx
, struct mbuf
*m
,
2809 struct ieee80211_node
*ni
)
2811 struct ieee80211com
*ic
= &sc
->sc_ic
;
2812 struct bwi_ring_data
*rd
= &sc
->sc_tx_rdata
[BWI_TX_DATA_RING
];
2813 struct bwi_txbuf_data
*tbd
= &sc
->sc_tx_bdata
[BWI_TX_DATA_RING
];
2814 struct bwi_txbuf
*tb
= &tbd
->tbd_buf
[idx
];
2815 struct bwi_mac
*mac
;
2816 struct bwi_txbuf_hdr
*hdr
;
2817 struct ieee80211_frame
*wh
;
2818 uint8_t rate
, rate_fb
;
2828 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
2829 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
2831 wh
= mtod(m
, struct ieee80211_frame
*);
2833 /* Get 802.11 frame len before prepending TX header */
2834 pkt_len
= m
->m_pkthdr
.len
+ IEEE80211_CRC_LEN
;
2839 bzero(tb
->tb_rate_idx
, sizeof(tb
->tb_rate_idx
));
2841 if (ic
->ic_fixed_rate
!= IEEE80211_FIXED_RATE_NONE
) {
2844 rate
= IEEE80211_RS_RATE(&ni
->ni_rates
,
2847 if (ic
->ic_fixed_rate
>= 1)
2848 idx
= ic
->ic_fixed_rate
- 1;
2851 rate_fb
= IEEE80211_RS_RATE(&ni
->ni_rates
, idx
);
2853 /* TODO: TX rate control */
2854 rate
= rate_fb
= (1 * 2);
2857 /* Fixed at 1Mbits/s for mgt frames */
2858 rate
= rate_fb
= (1 * 2);
2861 if (IEEE80211_IS_MULTICAST(wh
->i_addr1
))
2862 rate
= rate_fb
= ic
->ic_mcast_rate
;
2864 if (rate
== 0 || rate_fb
== 0) {
2865 if_printf(&ic
->ic_if
, "invalid rate %u or fallback rate %u",
2867 rate
= rate_fb
= (1 * 2); /* Force 1Mbits/s */
2873 if (sc
->sc_drvbpf
!= NULL
) {
2874 sc
->sc_tx_th
.wt_flags
= 0;
2875 if (wh
->i_fc
[1] & IEEE80211_FC1_WEP
)
2876 sc
->sc_tx_th
.wt_flags
|= IEEE80211_RADIOTAP_F_WEP
;
2877 if (ieee80211_rate2modtype(rate
) == IEEE80211_MODTYPE_DS
&&
2878 (ic
->ic_flags
& IEEE80211_F_SHPREAMBLE
) &&
2880 sc
->sc_tx_th
.wt_flags
|= IEEE80211_RADIOTAP_F_SHORTPRE
;
2882 sc
->sc_tx_th
.wt_rate
= rate
;
2884 bpf_ptap(sc
->sc_drvbpf
, m
, &sc
->sc_tx_th
, sc
->sc_tx_th_len
);
2888 * Setup the embedded TX header
2890 M_PREPEND(m
, sizeof(*hdr
), MB_DONTWAIT
);
2892 if_printf(&ic
->ic_if
, "prepend TX header failed\n");
2895 hdr
= mtod(m
, struct bwi_txbuf_hdr
*);
2897 bzero(hdr
, sizeof(*hdr
));
2899 bcopy(wh
->i_fc
, hdr
->txh_fc
, sizeof(hdr
->txh_fc
));
2900 bcopy(wh
->i_addr1
, hdr
->txh_addr1
, sizeof(hdr
->txh_addr1
));
2902 if (ni
!= NULL
&& !IEEE80211_IS_MULTICAST(wh
->i_addr1
)) {
2906 ack_rate
= ieee80211_ack_rate(ni
, rate_fb
);
2907 dur
= ieee80211_txtime(ni
,
2908 sizeof(struct ieee80211_frame_ack
) + IEEE80211_CRC_LEN
,
2909 ack_rate
, ic
->ic_flags
& ~IEEE80211_F_SHPREAMBLE
);
2911 hdr
->txh_fb_duration
= htole16(dur
);
2914 hdr
->txh_id
= __SHIFTIN(BWI_TX_DATA_RING
, BWI_TXH_ID_RING_MASK
) |
2915 __SHIFTIN(idx
, BWI_TXH_ID_IDX_MASK
);
2917 bwi_plcp_header(hdr
->txh_plcp
, pkt_len
, rate
);
2918 bwi_plcp_header(hdr
->txh_fb_plcp
, pkt_len
, rate_fb
);
2920 phy_ctrl
= __SHIFTIN(mac
->mac_rf
.rf_ant_mode
,
2921 BWI_TXH_PHY_C_ANTMODE_MASK
);
2922 if (ieee80211_rate2modtype(rate
) == IEEE80211_MODTYPE_OFDM
)
2923 phy_ctrl
|= BWI_TXH_PHY_C_OFDM
;
2924 else if ((ic
->ic_flags
& IEEE80211_F_SHPREAMBLE
) && rate
!= (2 * 1))
2925 phy_ctrl
|= BWI_TXH_PHY_C_SHPREAMBLE
;
2927 mac_ctrl
= BWI_TXH_MAC_C_HWSEQ
| BWI_TXH_MAC_C_FIRST_FRAG
;
2928 if (!IEEE80211_IS_MULTICAST(wh
->i_addr1
))
2929 mac_ctrl
|= BWI_TXH_MAC_C_ACK
;
2930 if (ieee80211_rate2modtype(rate_fb
) == IEEE80211_MODTYPE_OFDM
)
2931 mac_ctrl
|= BWI_TXH_MAC_C_FB_OFDM
;
2933 hdr
->txh_mac_ctrl
= htole32(mac_ctrl
);
2934 hdr
->txh_phy_ctrl
= htole16(phy_ctrl
);
2936 /* Catch any further usage */
2941 error
= bus_dmamap_load_mbuf(sc
->sc_buf_dtag
, tb
->tb_dmap
, m
,
2942 bwi_dma_buf_addr
, &paddr
, BUS_DMA_NOWAIT
);
2943 if (error
&& error
!= EFBIG
) {
2944 if_printf(&ic
->ic_if
, "can't load TX buffer (1) %d\n", error
);
2948 if (error
) { /* error == EFBIG */
2951 m_new
= m_defrag(m
, MB_DONTWAIT
);
2952 if (m_new
== NULL
) {
2953 if_printf(&ic
->ic_if
, "can't defrag TX buffer\n");
2960 error
= bus_dmamap_load_mbuf(sc
->sc_buf_dtag
, tb
->tb_dmap
, m
,
2961 bwi_dma_buf_addr
, &paddr
,
2964 if_printf(&ic
->ic_if
, "can't load TX buffer (2) %d\n",
2971 bus_dmamap_sync(sc
->sc_buf_dtag
, tb
->tb_dmap
, BUS_DMASYNC_PREWRITE
);
2977 p
= mtod(m
, const uint8_t *);
2978 for (i
= 0; i
< m
->m_pkthdr
.len
; ++i
) {
2979 if (i
!= 0 && i
% 8 == 0)
2981 kprintf("%02x ", p
[i
]);
2985 if_printf(&ic
->ic_if
, "idx %d, pkt_len %d, buflen %d\n",
2986 idx
, pkt_len
, m
->m_pkthdr
.len
);
2989 /* Setup TX descriptor */
2990 sc
->sc_setup_txdesc(sc
, rd
, idx
, paddr
, m
->m_pkthdr
.len
);
2991 bus_dmamap_sync(sc
->sc_txring_dtag
, rd
->rdata_dmap
,
2992 BUS_DMASYNC_PREWRITE
);
2995 sc
->sc_start_tx(sc
, rd
->rdata_txrx_ctrl
, idx
);
3004 bwi_start_tx32(struct bwi_softc
*sc
, uint32_t tx_ctrl
, int idx
)
3006 idx
= (idx
+ 1) % BWI_TX_NDESC
;
3007 CSR_WRITE_4(sc
, tx_ctrl
+ BWI_TX32_INDEX
,
3008 idx
* sizeof(struct bwi_desc32
));
3012 bwi_start_tx64(struct bwi_softc
*sc
, uint32_t tx_ctrl
, int idx
)
3018 bwi_txeof_status32(struct bwi_softc
*sc
)
3020 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
3021 uint32_t val
, ctrl_base
;
3024 ctrl_base
= sc
->sc_txstats
->stats_ctrl_base
;
3026 val
= CSR_READ_4(sc
, ctrl_base
+ BWI_RX32_STATUS
);
3027 end_idx
= __SHIFTOUT(val
, BWI_RX32_STATUS_INDEX_MASK
) /
3028 sizeof(struct bwi_desc32
);
3030 bwi_txeof_status(sc
, end_idx
);
3032 CSR_WRITE_4(sc
, ctrl_base
+ BWI_RX32_INDEX
,
3033 end_idx
* sizeof(struct bwi_desc32
));
3035 if ((ifp
->if_flags
& IFF_OACTIVE
) == 0)
3040 bwi_txeof_status64(struct bwi_softc
*sc
)
3046 _bwi_txeof(struct bwi_softc
*sc
, uint16_t tx_id
, int acked
, int data_txcnt
)
3048 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
3049 struct bwi_txbuf_data
*tbd
;
3050 struct bwi_txbuf
*tb
;
3051 int ring_idx
, buf_idx
;
3054 if_printf(ifp
, "zero tx id\n");
3058 ring_idx
= __SHIFTOUT(tx_id
, BWI_TXH_ID_RING_MASK
);
3059 buf_idx
= __SHIFTOUT(tx_id
, BWI_TXH_ID_IDX_MASK
);
3061 KKASSERT(ring_idx
== BWI_TX_DATA_RING
);
3062 KKASSERT(buf_idx
< BWI_TX_NDESC
);
3064 if_printf(ifp
, "txeof idx %d\n", buf_idx
);
3067 tbd
= &sc
->sc_tx_bdata
[ring_idx
];
3068 KKASSERT(tbd
->tbd_used
> 0);
3071 tb
= &tbd
->tbd_buf
[buf_idx
];
3073 bus_dmamap_unload(sc
->sc_buf_dtag
, tb
->tb_dmap
);
3074 m_freem(tb
->tb_mbuf
);
3077 if (tb
->tb_ni
!= NULL
) {
3078 /* Feed back 'acked and data_txcnt' */
3079 ieee80211_free_node(tb
->tb_ni
);
3083 if (tbd
->tbd_used
== 0)
3084 sc
->sc_tx_timer
= 0;
3086 ifp
->if_flags
&= ~IFF_OACTIVE
;
3090 bwi_txeof_status(struct bwi_softc
*sc
, int end_idx
)
3092 struct bwi_txstats_data
*st
= sc
->sc_txstats
;
3095 bus_dmamap_sync(st
->stats_dtag
, st
->stats_dmap
, BUS_DMASYNC_POSTREAD
);
3097 idx
= st
->stats_idx
;
3098 while (idx
!= end_idx
) {
3099 const struct bwi_txstats
*stats
= &st
->stats
[idx
];
3101 if ((stats
->txs_flags
& BWI_TXS_F_PENDING
) == 0) {
3104 data_txcnt
= __SHIFTOUT(stats
->txs_txcnt
,
3105 BWI_TXS_TXCNT_DATA
);
3106 _bwi_txeof(sc
, le16toh(stats
->txs_id
),
3107 stats
->txs_flags
& BWI_TXS_F_ACKED
,
3110 idx
= (idx
+ 1) % BWI_TXSTATS_NDESC
;
3112 st
->stats_idx
= idx
;
3116 bwi_txeof(struct bwi_softc
*sc
)
3118 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
3121 uint32_t tx_status0
, tx_status1
;
3122 uint16_t tx_id
, tx_info
;
3124 tx_status0
= CSR_READ_4(sc
, BWI_TXSTATUS_0
);
3125 if (tx_status0
== 0)
3127 tx_status1
= CSR_READ_4(sc
, BWI_TXSTATUS_1
);
3129 tx_id
= __SHIFTOUT(tx_status0
, BWI_TXSTATUS_0_TXID_MASK
);
3130 tx_info
= BWI_TXSTATUS_0_INFO(tx_status0
);
3132 if (tx_info
& 0x30) /* XXX */
3135 _bwi_txeof(sc
, tx_id
, 0, 0);
3138 if ((ifp
->if_flags
& IFF_OACTIVE
) == 0)
3143 bwi_bbp_power_on(struct bwi_softc
*sc
, enum bwi_clock_mode clk_mode
)
3145 bwi_power_on(sc
, 1);
3146 return bwi_set_clock_mode(sc
, clk_mode
);
3150 bwi_bbp_power_off(struct bwi_softc
*sc
)
3152 bwi_set_clock_mode(sc
, BWI_CLOCK_MODE_SLOW
);
3153 bwi_power_off(sc
, 1);
3157 bwi_get_pwron_delay(struct bwi_softc
*sc
)
3159 struct bwi_regwin
*com
, *old
;
3160 struct bwi_clock_freq freq
;
3164 com
= &sc
->sc_com_regwin
;
3165 KKASSERT(BWI_REGWIN_EXIST(com
));
3167 if ((sc
->sc_cap
& BWI_CAP_CLKMODE
) == 0)
3170 error
= bwi_regwin_switch(sc
, com
, &old
);
3174 bwi_get_clock_freq(sc
, &freq
);
3176 val
= CSR_READ_4(sc
, BWI_PLL_ON_DELAY
);
3177 sc
->sc_pwron_delay
= howmany((val
+ 2) * 1000000, freq
.clkfreq_min
);
3178 DPRINTF(sc
, "power on delay %u\n", sc
->sc_pwron_delay
);
3180 return bwi_regwin_switch(sc
, old
, NULL
);
3184 bwi_bus_attach(struct bwi_softc
*sc
)
3186 struct bwi_regwin
*bus
, *old
;
3189 bus
= &sc
->sc_bus_regwin
;
3191 error
= bwi_regwin_switch(sc
, bus
, &old
);
3195 if (!bwi_regwin_is_enabled(sc
, bus
))
3196 bwi_regwin_enable(sc
, bus
, 0);
3198 /* Disable interripts */
3199 CSR_WRITE_4(sc
, BWI_INTRVEC
, 0);
3201 return bwi_regwin_switch(sc
, old
, NULL
);
3205 bwi_regwin_name(const struct bwi_regwin
*rw
)
3207 switch (rw
->rw_type
) {
3208 case BWI_REGWIN_T_COM
:
3210 case BWI_REGWIN_T_BUSPCI
:
3212 case BWI_REGWIN_T_MAC
:
3214 case BWI_REGWIN_T_BUSPCIE
:
3217 panic("unknown regwin type 0x%04x\n", rw
->rw_type
);
3222 bwi_regwin_disable_bits(struct bwi_softc
*sc
)
3226 /* XXX cache this */
3227 busrev
= __SHIFTOUT(CSR_READ_4(sc
, BWI_ID_LO
), BWI_ID_LO_BUSREV_MASK
);
3228 DPRINTF(sc
, "bus rev %u\n", busrev
);
3230 if (busrev
== BWI_BUSREV_0
)
3231 return BWI_STATE_LO_DISABLE1
;
3232 else if (busrev
== BWI_BUSREV_1
)
3233 return BWI_STATE_LO_DISABLE2
;
3235 return (BWI_STATE_LO_DISABLE1
| BWI_STATE_LO_DISABLE2
);
3239 bwi_regwin_is_enabled(struct bwi_softc
*sc
, struct bwi_regwin
*rw
)
3241 uint32_t val
, disable_bits
;
3243 disable_bits
= bwi_regwin_disable_bits(sc
);
3244 val
= CSR_READ_4(sc
, BWI_STATE_LO
);
3246 if ((val
& (BWI_STATE_LO_CLOCK
|
3247 BWI_STATE_LO_RESET
|
3248 disable_bits
)) == BWI_STATE_LO_CLOCK
) {
3249 DPRINTF(sc
, "%s is enabled\n", bwi_regwin_name(rw
));
3252 DPRINTF(sc
, "%s is disabled\n", bwi_regwin_name(rw
));
3258 bwi_regwin_disable(struct bwi_softc
*sc
, struct bwi_regwin
*rw
, uint32_t flags
)
3260 uint32_t state_lo
, disable_bits
;
3263 state_lo
= CSR_READ_4(sc
, BWI_STATE_LO
);
3266 * If current regwin is in 'reset' state, it was already disabled.
3268 if (state_lo
& BWI_STATE_LO_RESET
) {
3269 DPRINTF(sc
, "%s was already disabled\n", bwi_regwin_name(rw
));
3273 disable_bits
= bwi_regwin_disable_bits(sc
);
3276 * Disable normal clock
3278 state_lo
= BWI_STATE_LO_CLOCK
| disable_bits
;
3279 CSR_WRITE_4(sc
, BWI_STATE_LO
, state_lo
);
3282 * Wait until normal clock is disabled
3285 for (i
= 0; i
< NRETRY
; ++i
) {
3286 state_lo
= CSR_READ_4(sc
, BWI_STATE_LO
);
3287 if (state_lo
& disable_bits
)
3292 device_printf(sc
->sc_dev
, "%s disable clock timeout\n",
3293 bwi_regwin_name(rw
));
3296 for (i
= 0; i
< NRETRY
; ++i
) {
3299 state_hi
= CSR_READ_4(sc
, BWI_STATE_HI
);
3300 if ((state_hi
& BWI_STATE_HI_BUSY
) == 0)
3305 device_printf(sc
->sc_dev
, "%s wait BUSY unset timeout\n",
3306 bwi_regwin_name(rw
));
3311 * Reset and disable regwin with gated clock
3313 state_lo
= BWI_STATE_LO_RESET
| disable_bits
|
3314 BWI_STATE_LO_CLOCK
| BWI_STATE_LO_GATED_CLOCK
|
3315 __SHIFTIN(flags
, BWI_STATE_LO_FLAGS_MASK
);
3316 CSR_WRITE_4(sc
, BWI_STATE_LO
, state_lo
);
3318 /* Flush pending bus write */
3319 CSR_READ_4(sc
, BWI_STATE_LO
);
3322 /* Reset and disable regwin */
3323 state_lo
= BWI_STATE_LO_RESET
| disable_bits
|
3324 __SHIFTIN(flags
, BWI_STATE_LO_FLAGS_MASK
);
3325 CSR_WRITE_4(sc
, BWI_STATE_LO
, state_lo
);
3327 /* Flush pending bus write */
3328 CSR_READ_4(sc
, BWI_STATE_LO
);
3333 bwi_regwin_enable(struct bwi_softc
*sc
, struct bwi_regwin
*rw
, uint32_t flags
)
3335 uint32_t state_lo
, state_hi
, imstate
;
3337 bwi_regwin_disable(sc
, rw
, flags
);
3339 /* Reset regwin with gated clock */
3340 state_lo
= BWI_STATE_LO_RESET
|
3341 BWI_STATE_LO_CLOCK
|
3342 BWI_STATE_LO_GATED_CLOCK
|
3343 __SHIFTIN(flags
, BWI_STATE_LO_FLAGS_MASK
);
3344 CSR_WRITE_4(sc
, BWI_STATE_LO
, state_lo
);
3346 /* Flush pending bus write */
3347 CSR_READ_4(sc
, BWI_STATE_LO
);
3350 state_hi
= CSR_READ_4(sc
, BWI_STATE_HI
);
3351 if (state_hi
& BWI_STATE_HI_SERROR
)
3352 CSR_WRITE_4(sc
, BWI_STATE_HI
, 0);
3354 imstate
= CSR_READ_4(sc
, BWI_IMSTATE
);
3355 if (imstate
& (BWI_IMSTATE_INBAND_ERR
| BWI_IMSTATE_TIMEOUT
)) {
3356 imstate
&= ~(BWI_IMSTATE_INBAND_ERR
| BWI_IMSTATE_TIMEOUT
);
3357 CSR_WRITE_4(sc
, BWI_IMSTATE
, imstate
);
3360 /* Enable regwin with gated clock */
3361 state_lo
= BWI_STATE_LO_CLOCK
|
3362 BWI_STATE_LO_GATED_CLOCK
|
3363 __SHIFTIN(flags
, BWI_STATE_LO_FLAGS_MASK
);
3364 CSR_WRITE_4(sc
, BWI_STATE_LO
, state_lo
);
3366 /* Flush pending bus write */
3367 CSR_READ_4(sc
, BWI_STATE_LO
);
3370 /* Enable regwin with normal clock */
3371 state_lo
= BWI_STATE_LO_CLOCK
|
3372 __SHIFTIN(flags
, BWI_STATE_LO_FLAGS_MASK
);
3373 CSR_WRITE_4(sc
, BWI_STATE_LO
, state_lo
);
3375 /* Flush pending bus write */
3376 CSR_READ_4(sc
, BWI_STATE_LO
);
3381 bwi_set_bssid(struct bwi_softc
*sc
, const uint8_t *bssid
)
3383 struct ieee80211com
*ic
= &sc
->sc_ic
;
3384 struct bwi_mac
*mac
;
3385 struct bwi_myaddr_bssid buf
;
3390 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
3391 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
3393 bwi_set_addr_filter(sc
, BWI_ADDR_FILTER_BSSID
, bssid
);
3395 bcopy(ic
->ic_myaddr
, buf
.myaddr
, sizeof(buf
.myaddr
));
3396 bcopy(bssid
, buf
.bssid
, sizeof(buf
.bssid
));
3398 n
= sizeof(buf
) / sizeof(val
);
3399 p
= (const uint8_t *)&buf
;
3400 for (i
= 0; i
< n
; ++i
) {
3404 for (j
= 0; j
< sizeof(val
); ++j
)
3405 val
|= ((uint32_t)(*p
++)) << (j
* 8);
3407 TMPLT_WRITE_4(mac
, 0x20 + (i
* sizeof(val
)), val
);
3412 bwi_updateslot(struct ifnet
*ifp
)
3414 struct bwi_softc
*sc
= ifp
->if_softc
;
3415 struct ieee80211com
*ic
= &sc
->sc_ic
;
3416 struct bwi_mac
*mac
;
3418 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
3421 ASSERT_SERIALIZED(ifp
->if_serializer
);
3423 DPRINTF(sc
, "%s\n", __func__
);
3425 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
3426 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
3428 bwi_mac_updateslot(mac
, (ic
->ic_flags
& IEEE80211_F_SHSLOT
));
3432 bwi_calibrate(void *xsc
)
3434 struct bwi_softc
*sc
= xsc
;
3435 struct ieee80211com
*ic
= &sc
->sc_ic
;
3436 struct ifnet
*ifp
= &ic
->ic_if
;
3438 lwkt_serialize_enter(ifp
->if_serializer
);
3440 if (ic
->ic_state
== IEEE80211_S_RUN
) {
3441 struct bwi_mac
*mac
;
3443 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
3444 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
3446 if (ic
->ic_opmode
!= IEEE80211_M_MONITOR
)
3447 bwi_mac_calibrate_txpower(mac
);
3449 /* XXX 15 seconds */
3450 callout_reset(&sc
->sc_calib_ch
, hz
* 15, bwi_calibrate
, sc
);
3453 lwkt_serialize_exit(ifp
->if_serializer
);
3457 bwi_calc_rssi(struct bwi_softc
*sc
, const struct bwi_rxbuf_hdr
*hdr
)
3459 struct bwi_mac
*mac
;
3461 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
3462 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
3464 return bwi_rf_calc_rssi(mac
, hdr
);
3467 static __inline
uint8_t
3468 bwi_ofdm_plcp2rate(const uint32_t *plcp0
)
3473 plcp
= le32toh(*plcp0
);
3474 plcp_rate
= __SHIFTOUT(plcp
, IEEE80211_OFDM_PLCP_RATE_MASK
);
3475 return ieee80211_plcp2rate(plcp_rate
, 1);
3478 static __inline
uint8_t
3479 bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr
*hdr
)
3481 return ieee80211_plcp2rate(hdr
->i_signal
, 0);
3485 bwi_rx_radiotap(struct bwi_softc
*sc
, struct mbuf
*m
,
3486 struct bwi_rxbuf_hdr
*hdr
, const void *plcp
, int rssi
)
3488 const struct ieee80211_frame_min
*wh
;
3492 KKASSERT(sc
->sc_drvbpf
!= NULL
);
3494 flags1
= htole16(hdr
->rxh_flags1
);
3495 if (flags1
& BWI_RXH_F1_OFDM
)
3496 rate
= bwi_ofdm_plcp2rate(plcp
);
3498 rate
= bwi_ds_plcp2rate(plcp
);
3500 sc
->sc_rx_th
.wr_flags
= IEEE80211_RADIOTAP_F_FCS
;
3501 if (flags1
& BWI_RXH_F1_SHPREAMBLE
)
3502 sc
->sc_rx_th
.wr_flags
|= IEEE80211_RADIOTAP_F_SHORTPRE
;
3504 wh
= mtod(m
, const struct ieee80211_frame_min
*);
3505 if (wh
->i_fc
[1] & IEEE80211_FC1_WEP
)
3506 sc
->sc_rx_th
.wr_flags
|= IEEE80211_RADIOTAP_F_WEP
;
3508 sc
->sc_rx_th
.wr_tsf
= hdr
->rxh_tsf
; /* No endian convertion */
3509 sc
->sc_rx_th
.wr_rate
= rate
;
3510 sc
->sc_rx_th
.wr_antsignal
= rssi
;
3511 sc
->sc_rx_th
.wr_antnoise
= BWI_NOISE_FLOOR
;
3513 bpf_ptap(sc
->sc_drvbpf
, m
, &sc
->sc_rx_th
, sc
->sc_rx_th_len
);