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.10 2007/09/17 12:13:24 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
**, int);
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
] = {
293 static uint32_t bwi_debug
= BWI_DBG_ATTACH
| BWI_DBG_INIT
| BWI_DBG_TXPOWER
;
294 TUNABLE_INT("hw.bwi.debug", (int *)&bwi_debug
);
297 static const uint8_t bwi_zero_addr
[IEEE80211_ADDR_LEN
];
299 static const struct ieee80211_rateset bwi_rateset_11b
=
300 { 4, { 2, 4, 11, 22 } };
301 static const struct ieee80211_rateset bwi_rateset_11g
=
302 { 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
305 bwi_read_sprom(struct bwi_softc
*sc
, uint16_t ofs
)
307 return CSR_READ_2(sc
, ofs
+ BWI_SPROM_START
);
311 bwi_setup_desc32(struct bwi_softc
*sc
, struct bwi_desc32
*desc_array
,
312 int ndesc
, int desc_idx
, bus_addr_t paddr
, int buf_len
,
315 struct bwi_desc32
*desc
= &desc_array
[desc_idx
];
316 uint32_t ctrl
, addr
, addr_hi
, addr_lo
;
318 addr_lo
= __SHIFTOUT(paddr
, BWI_DESC32_A_ADDR_MASK
);
319 addr_hi
= __SHIFTOUT(paddr
, BWI_DESC32_A_FUNC_MASK
);
321 addr
= __SHIFTIN(addr_lo
, BWI_DESC32_A_ADDR_MASK
) |
322 __SHIFTIN(BWI_DESC32_A_FUNC_TXRX
, BWI_DESC32_A_FUNC_MASK
);
324 ctrl
= __SHIFTIN(buf_len
, BWI_DESC32_C_BUFLEN_MASK
) |
325 __SHIFTIN(addr_hi
, BWI_DESC32_C_ADDRHI_MASK
);
326 if (desc_idx
== ndesc
- 1)
327 ctrl
|= BWI_DESC32_C_EOR
;
330 ctrl
|= BWI_DESC32_C_FRAME_START
|
331 BWI_DESC32_C_FRAME_END
|
335 desc
->addr
= htole32(addr
);
336 desc
->ctrl
= htole32(ctrl
);
340 bwi_probe(device_t dev
)
342 const struct bwi_dev
*b
;
345 did
= pci_get_device(dev
);
346 vid
= pci_get_vendor(dev
);
348 for (b
= bwi_devices
; b
->desc
!= NULL
; ++b
) {
349 if (b
->did
== did
&& b
->vid
== vid
) {
350 device_set_desc(dev
, b
->desc
);
358 bwi_attach(device_t dev
)
360 struct bwi_softc
*sc
= device_get_softc(dev
);
361 struct ieee80211com
*ic
= &sc
->sc_ic
;
362 struct ifnet
*ifp
= &ic
->ic_if
;
367 if_initname(ifp
, device_get_name(dev
), device_get_unit(dev
));
371 * Initialize sysctl variables
373 sc
->sc_fw_version
= BWI_FW_VERSION3
;
374 sc
->sc_dwell_time
= 200;
376 sc
->sc_debug
= bwi_debug
;
379 callout_init(&sc
->sc_scan_ch
);
380 callout_init(&sc
->sc_calib_ch
);
383 if (pci_get_powerstate(dev
) != PCI_POWERSTATE_D0
) {
386 /* XXX Save more PCIR */
387 irq
= pci_read_config(dev
, PCIR_INTLINE
, 4);
388 mem
= pci_read_config(dev
, BWI_PCIR_BAR
, 4);
390 device_printf(dev
, "chip is in D%d power mode "
391 "-- setting to D0\n", pci_get_powerstate(dev
));
393 pci_set_powerstate(dev
, PCI_POWERSTATE_D0
);
395 pci_write_config(dev
, PCIR_INTLINE
, irq
, 4);
396 pci_write_config(dev
, BWI_PCIR_BAR
, irq
, 4);
398 #endif /* !BURN_BRIDGE */
400 pci_enable_busmaster(dev
);
402 /* Get more PCI information */
403 sc
->sc_pci_revid
= pci_get_revid(dev
);
404 sc
->sc_pci_subvid
= pci_get_subvendor(dev
);
405 sc
->sc_pci_subdid
= pci_get_subdevice(dev
);
410 sc
->sc_mem_rid
= BWI_PCIR_BAR
;
411 sc
->sc_mem_res
= bus_alloc_resource_any(dev
, SYS_RES_MEMORY
,
412 &sc
->sc_mem_rid
, RF_ACTIVE
);
413 if (sc
->sc_mem_res
== NULL
) {
414 device_printf(dev
, "can't allocate IO memory\n");
417 sc
->sc_mem_bt
= rman_get_bustag(sc
->sc_mem_res
);
418 sc
->sc_mem_bh
= rman_get_bushandle(sc
->sc_mem_res
);
424 sc
->sc_irq_res
= bus_alloc_resource_any(dev
, SYS_RES_IRQ
,
426 RF_SHAREABLE
| RF_ACTIVE
);
427 if (sc
->sc_irq_res
== NULL
) {
428 device_printf(dev
, "can't allocate irq\n");
436 sysctl_ctx_init(&sc
->sc_sysctl_ctx
);
437 sc
->sc_sysctl_tree
= SYSCTL_ADD_NODE(&sc
->sc_sysctl_ctx
,
438 SYSCTL_STATIC_CHILDREN(_hw
),
440 device_get_nameunit(dev
),
442 if (sc
->sc_sysctl_tree
== NULL
) {
443 device_printf(dev
, "can't add sysctl node\n");
448 SYSCTL_ADD_UINT(&sc
->sc_sysctl_ctx
,
449 SYSCTL_CHILDREN(sc
->sc_sysctl_tree
), OID_AUTO
,
450 "dwell_time", CTLFLAG_RW
, &sc
->sc_dwell_time
, 0,
451 "Channel dwell time during scan (msec)");
452 SYSCTL_ADD_UINT(&sc
->sc_sysctl_ctx
,
453 SYSCTL_CHILDREN(sc
->sc_sysctl_tree
), OID_AUTO
,
454 "fw_version", CTLFLAG_RD
, &sc
->sc_fw_version
, 0,
457 SYSCTL_ADD_UINT(&sc
->sc_sysctl_ctx
,
458 SYSCTL_CHILDREN(sc
->sc_sysctl_tree
), OID_AUTO
,
459 "debug", CTLFLAG_RW
, &sc
->sc_debug
, 0, "Debug flags");
464 error
= bwi_bbp_attach(sc
);
468 error
= bwi_bbp_power_on(sc
, BWI_CLOCK_MODE_FAST
);
472 if (BWI_REGWIN_EXIST(&sc
->sc_com_regwin
)) {
473 error
= bwi_set_clock_delay(sc
);
477 error
= bwi_set_clock_mode(sc
, BWI_CLOCK_MODE_FAST
);
481 error
= bwi_get_pwron_delay(sc
);
486 error
= bwi_bus_attach(sc
);
490 bwi_get_card_flags(sc
);
494 for (i
= 0; i
< sc
->sc_nmac
; ++i
) {
495 struct bwi_regwin
*old
;
497 mac
= &sc
->sc_mac
[i
];
498 error
= bwi_regwin_switch(sc
, &mac
->mac_regwin
, &old
);
502 error
= bwi_mac_lateattach(mac
);
506 error
= bwi_regwin_switch(sc
, old
, NULL
);
512 * XXX First MAC is known to exist
515 mac
= &sc
->sc_mac
[0];
518 bwi_bbp_power_off(sc
);
520 error
= bwi_dma_alloc(sc
);
525 ifp
->if_flags
= IFF_BROADCAST
| IFF_SIMPLEX
| IFF_MULTICAST
;
526 ifp
->if_init
= bwi_init
;
527 ifp
->if_ioctl
= bwi_ioctl
;
528 ifp
->if_start
= bwi_start
;
529 ifp
->if_watchdog
= bwi_watchdog
;
530 ifq_set_maxlen(&ifp
->if_snd
, IFQ_MAXLEN
);
531 ifq_set_ready(&ifp
->if_snd
);
534 sc
->sc_locale
= __SHIFTOUT(bwi_read_sprom(sc
, BWI_SPROM_CARD_INFO
),
535 BWI_SPROM_CARD_INFO_LOCALE
);
536 DPRINTF(sc
, BWI_DBG_ATTACH
, "locale: %d\n", sc
->sc_locale
);
539 * Setup ratesets, phytype, channels and get MAC address
541 if (phy
->phy_mode
== IEEE80211_MODE_11B
||
542 phy
->phy_mode
== IEEE80211_MODE_11G
) {
545 ic
->ic_sup_rates
[IEEE80211_MODE_11B
] = bwi_rateset_11b
;
547 if (phy
->phy_mode
== IEEE80211_MODE_11B
) {
548 chan_flags
= IEEE80211_CHAN_B
;
549 ic
->ic_phytype
= IEEE80211_T_DS
;
551 chan_flags
= IEEE80211_CHAN_CCK
|
552 IEEE80211_CHAN_OFDM
|
555 ic
->ic_phytype
= IEEE80211_T_OFDM
;
556 ic
->ic_sup_rates
[IEEE80211_MODE_11G
] =
560 /* XXX depend on locale */
561 for (i
= 1; i
<= 14; ++i
) {
562 ic
->ic_channels
[i
].ic_freq
=
563 ieee80211_ieee2mhz(i
, IEEE80211_CHAN_2GHZ
);
564 ic
->ic_channels
[i
].ic_flags
= chan_flags
;
567 bwi_get_eaddr(sc
, BWI_SPROM_11BG_EADDR
, ic
->ic_myaddr
);
568 if (IEEE80211_IS_MULTICAST(ic
->ic_myaddr
)) {
569 bwi_get_eaddr(sc
, BWI_SPROM_11A_EADDR
, ic
->ic_myaddr
);
570 if (IEEE80211_IS_MULTICAST(ic
->ic_myaddr
)) {
571 device_printf(dev
, "invalid MAC address: "
572 "%6D\n", ic
->ic_myaddr
, ":");
575 } else if (phy
->phy_mode
== IEEE80211_MODE_11A
) {
580 panic("unknown phymode %d\n", phy
->phy_mode
);
583 ic
->ic_caps
= IEEE80211_C_SHSLOT
|
584 IEEE80211_C_SHPREAMBLE
|
587 ic
->ic_state
= IEEE80211_S_INIT
;
588 ic
->ic_opmode
= IEEE80211_M_STA
;
590 ic
->ic_updateslot
= bwi_updateslot
;
592 ieee80211_ifattach(ic
);
594 ic
->ic_headroom
= sizeof(struct bwi_txbuf_hdr
);
595 ic
->ic_flags_ext
|= IEEE80211_FEXT_SWBMISS
;
597 sc
->sc_newstate
= ic
->ic_newstate
;
598 ic
->ic_newstate
= bwi_newstate
;
600 ieee80211_media_init(ic
, bwi_media_change
, ieee80211_media_status
);
605 bpfattach_dlt(ifp
, DLT_IEEE802_11_RADIO
,
606 sizeof(struct ieee80211_frame
) + sizeof(sc
->sc_tx_th
),
609 sc
->sc_tx_th_len
= roundup(sizeof(sc
->sc_tx_th
), sizeof(uint32_t));
610 sc
->sc_tx_th
.wt_ihdr
.it_len
= htole16(sc
->sc_tx_th_len
);
611 sc
->sc_tx_th
.wt_ihdr
.it_present
= htole32(BWI_TX_RADIOTAP_PRESENT
);
613 sc
->sc_rx_th_len
= roundup(sizeof(sc
->sc_rx_th
), sizeof(uint32_t));
614 sc
->sc_rx_th
.wr_ihdr
.it_len
= htole16(sc
->sc_rx_th_len
);
615 sc
->sc_rx_th
.wr_ihdr
.it_present
= htole32(BWI_RX_RADIOTAP_PRESENT
);
617 error
= bus_setup_intr(dev
, sc
->sc_irq_res
, INTR_MPSAFE
, bwi_intr
, sc
,
618 &sc
->sc_irq_handle
, ifp
->if_serializer
);
620 device_printf(dev
, "can't setup intr\n");
622 ieee80211_ifdetach(ic
);
627 ieee80211_announce(ic
);
636 bwi_detach(device_t dev
)
638 struct bwi_softc
*sc
= device_get_softc(dev
);
640 if (device_is_attached(dev
)) {
641 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
644 lwkt_serialize_enter(ifp
->if_serializer
);
646 bus_teardown_intr(dev
, sc
->sc_irq_res
, sc
->sc_irq_handle
);
647 lwkt_serialize_exit(ifp
->if_serializer
);
650 ieee80211_ifdetach(&sc
->sc_ic
);
652 for (i
= 0; i
< sc
->sc_nmac
; ++i
)
653 bwi_mac_detach(&sc
->sc_mac
[i
]);
656 if (sc
->sc_sysctl_tree
!= NULL
)
657 sysctl_ctx_free(&sc
->sc_sysctl_ctx
);
659 if (sc
->sc_irq_res
!= NULL
) {
660 bus_release_resource(dev
, SYS_RES_IRQ
, sc
->sc_irq_rid
,
664 if (sc
->sc_mem_res
!= NULL
) {
665 bus_release_resource(dev
, SYS_RES_MEMORY
, sc
->sc_mem_rid
,
675 bwi_shutdown(device_t dev
)
677 struct bwi_softc
*sc
= device_get_softc(dev
);
678 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
680 lwkt_serialize_enter(ifp
->if_serializer
);
682 lwkt_serialize_exit(ifp
->if_serializer
);
687 bwi_power_on(struct bwi_softc
*sc
, int with_pll
)
689 uint32_t gpio_in
, gpio_out
, gpio_en
;
692 gpio_in
= pci_read_config(sc
->sc_dev
, BWI_PCIR_GPIO_IN
, 4);
693 if (gpio_in
& BWI_PCIM_GPIO_PWR_ON
)
696 gpio_out
= pci_read_config(sc
->sc_dev
, BWI_PCIR_GPIO_OUT
, 4);
697 gpio_en
= pci_read_config(sc
->sc_dev
, BWI_PCIR_GPIO_ENABLE
, 4);
699 gpio_out
|= BWI_PCIM_GPIO_PWR_ON
;
700 gpio_en
|= BWI_PCIM_GPIO_PWR_ON
;
702 /* Turn off PLL first */
703 gpio_out
|= BWI_PCIM_GPIO_PLL_PWR_OFF
;
704 gpio_en
|= BWI_PCIM_GPIO_PLL_PWR_OFF
;
707 pci_write_config(sc
->sc_dev
, BWI_PCIR_GPIO_OUT
, gpio_out
, 4);
708 pci_write_config(sc
->sc_dev
, BWI_PCIR_GPIO_ENABLE
, gpio_en
, 4);
713 gpio_out
&= ~BWI_PCIM_GPIO_PLL_PWR_OFF
;
714 pci_write_config(sc
->sc_dev
, BWI_PCIR_GPIO_OUT
, gpio_out
, 4);
719 /* Clear "Signaled Target Abort" */
720 status
= pci_read_config(sc
->sc_dev
, PCIR_STATUS
, 2);
721 status
&= ~PCIM_STATUS_STABORT
;
722 pci_write_config(sc
->sc_dev
, PCIR_STATUS
, status
, 2);
726 bwi_power_off(struct bwi_softc
*sc
, int with_pll
)
728 uint32_t gpio_out
, gpio_en
;
730 pci_read_config(sc
->sc_dev
, BWI_PCIR_GPIO_IN
, 4); /* dummy read */
731 gpio_out
= pci_read_config(sc
->sc_dev
, BWI_PCIR_GPIO_OUT
, 4);
732 gpio_en
= pci_read_config(sc
->sc_dev
, BWI_PCIR_GPIO_ENABLE
, 4);
734 gpio_out
&= ~BWI_PCIM_GPIO_PWR_ON
;
735 gpio_en
|= BWI_PCIM_GPIO_PWR_ON
;
737 gpio_out
|= BWI_PCIM_GPIO_PLL_PWR_OFF
;
738 gpio_en
|= BWI_PCIM_GPIO_PLL_PWR_OFF
;
741 pci_write_config(sc
->sc_dev
, BWI_PCIR_GPIO_OUT
, gpio_out
, 4);
742 pci_write_config(sc
->sc_dev
, BWI_PCIR_GPIO_ENABLE
, gpio_en
, 4);
747 bwi_regwin_switch(struct bwi_softc
*sc
, struct bwi_regwin
*rw
,
748 struct bwi_regwin
**old_rw
)
755 if (!BWI_REGWIN_EXIST(rw
))
758 if (sc
->sc_cur_regwin
!= rw
) {
759 error
= bwi_regwin_select(sc
, rw
->rw_id
);
761 if_printf(&sc
->sc_ic
.ic_if
, "can't select regwin %d\n",
768 *old_rw
= sc
->sc_cur_regwin
;
769 sc
->sc_cur_regwin
= rw
;
774 bwi_regwin_select(struct bwi_softc
*sc
, int id
)
776 uint32_t win
= BWI_PCIM_REGWIN(id
);
780 for (i
= 0; i
< RETRY_MAX
; ++i
) {
781 pci_write_config(sc
->sc_dev
, BWI_PCIR_SEL_REGWIN
, win
, 4);
782 if (pci_read_config(sc
->sc_dev
, BWI_PCIR_SEL_REGWIN
, 4) == win
)
792 bwi_regwin_info(struct bwi_softc
*sc
, uint16_t *type
, uint8_t *rev
)
796 val
= CSR_READ_4(sc
, BWI_ID_HI
);
797 *type
= BWI_ID_HI_REGWIN_TYPE(val
);
798 *rev
= BWI_ID_HI_REGWIN_REV(val
);
800 DPRINTF(sc
, BWI_DBG_ATTACH
, "regwin: type 0x%03x, rev %d, "
801 "vendor 0x%04x\n", *type
, *rev
,
802 __SHIFTOUT(val
, BWI_ID_HI_REGWIN_VENDOR_MASK
));
806 bwi_bbp_attach(struct bwi_softc
*sc
)
808 #define N(arr) (int)(sizeof(arr) / sizeof(arr[0]))
809 uint16_t bbp_id
, rw_type
;
812 int error
, nregwin
, i
;
815 * Get 0th regwin information
816 * NOTE: 0th regwin should exist
818 error
= bwi_regwin_select(sc
, 0);
820 device_printf(sc
->sc_dev
, "can't select regwin 0\n");
823 bwi_regwin_info(sc
, &rw_type
, &rw_rev
);
830 if (rw_type
== BWI_REGWIN_T_COM
) {
831 info
= CSR_READ_4(sc
, BWI_INFO
);
832 bbp_id
= __SHIFTOUT(info
, BWI_INFO_BBPID_MASK
);
834 BWI_CREATE_REGWIN(&sc
->sc_com_regwin
, 0, rw_type
, rw_rev
);
836 sc
->sc_cap
= CSR_READ_4(sc
, BWI_CAPABILITY
);
838 uint16_t did
= pci_get_device(sc
->sc_dev
);
839 uint8_t revid
= pci_get_revid(sc
->sc_dev
);
841 for (i
= 0; i
< N(bwi_bbpid_map
); ++i
) {
842 if (did
>= bwi_bbpid_map
[i
].did_min
&&
843 did
<= bwi_bbpid_map
[i
].did_max
) {
844 bbp_id
= bwi_bbpid_map
[i
].bbp_id
;
849 device_printf(sc
->sc_dev
, "no BBP id for device id "
854 info
= __SHIFTIN(revid
, BWI_INFO_BBPREV_MASK
) |
855 __SHIFTIN(0, BWI_INFO_BBPPKG_MASK
);
859 * Find out number of regwins
862 if (rw_type
== BWI_REGWIN_T_COM
&& rw_rev
>= 4) {
863 nregwin
= __SHIFTOUT(info
, BWI_INFO_NREGWIN_MASK
);
865 for (i
= 0; i
< N(bwi_regwin_count
); ++i
) {
866 if (bwi_regwin_count
[i
].bbp_id
== bbp_id
) {
867 nregwin
= bwi_regwin_count
[i
].nregwin
;
872 device_printf(sc
->sc_dev
, "no number of win for "
873 "BBP id 0x%04x\n", bbp_id
);
878 /* Record BBP id/rev for later using */
879 sc
->sc_bbp_id
= bbp_id
;
880 sc
->sc_bbp_rev
= __SHIFTOUT(info
, BWI_INFO_BBPREV_MASK
);
881 sc
->sc_bbp_pkg
= __SHIFTOUT(info
, BWI_INFO_BBPPKG_MASK
);
882 device_printf(sc
->sc_dev
, "BBP: id 0x%04x, rev 0x%x, pkg %d\n",
883 sc
->sc_bbp_id
, sc
->sc_bbp_rev
, sc
->sc_bbp_pkg
);
885 DPRINTF(sc
, BWI_DBG_ATTACH
, "nregwin %d, cap 0x%08x\n",
886 nregwin
, sc
->sc_cap
);
889 * Create rest of the regwins
892 /* Don't re-create common regwin, if it is already created */
893 i
= BWI_REGWIN_EXIST(&sc
->sc_com_regwin
) ? 1 : 0;
895 for (; i
< nregwin
; ++i
) {
897 * Get regwin information
899 error
= bwi_regwin_select(sc
, i
);
901 device_printf(sc
->sc_dev
,
902 "can't select regwin %d\n", i
);
905 bwi_regwin_info(sc
, &rw_type
, &rw_rev
);
909 * 1) Bus (PCI/PCIE) regwin
911 * Ignore rest types of regwin
913 if (rw_type
== BWI_REGWIN_T_BUSPCI
||
914 rw_type
== BWI_REGWIN_T_BUSPCIE
) {
915 if (BWI_REGWIN_EXIST(&sc
->sc_bus_regwin
)) {
916 device_printf(sc
->sc_dev
,
917 "bus regwin already exists\n");
919 BWI_CREATE_REGWIN(&sc
->sc_bus_regwin
, i
,
922 } else if (rw_type
== BWI_REGWIN_T_MAC
) {
923 /* XXX ignore return value */
924 bwi_mac_attach(sc
, i
, rw_rev
);
928 /* At least one MAC shold exist */
929 if (!BWI_REGWIN_EXIST(&sc
->sc_mac
[0].mac_regwin
)) {
930 device_printf(sc
->sc_dev
, "no MAC was found\n");
933 KKASSERT(sc
->sc_nmac
> 0);
935 /* Bus regwin must exist */
936 if (!BWI_REGWIN_EXIST(&sc
->sc_bus_regwin
)) {
937 device_printf(sc
->sc_dev
, "no bus regwin was found\n");
941 /* Start with first MAC */
942 error
= bwi_regwin_switch(sc
, &sc
->sc_mac
[0].mac_regwin
, NULL
);
951 bwi_bus_init(struct bwi_softc
*sc
, struct bwi_mac
*mac
)
953 struct bwi_regwin
*old
, *bus
;
957 bus
= &sc
->sc_bus_regwin
;
958 KKASSERT(sc
->sc_cur_regwin
== &mac
->mac_regwin
);
961 * Tell bus to generate requested interrupts
963 if (bus
->rw_rev
< 6 && bus
->rw_type
== BWI_REGWIN_T_BUSPCI
) {
965 * NOTE: Read BWI_FLAGS from MAC regwin
967 val
= CSR_READ_4(sc
, BWI_FLAGS
);
969 error
= bwi_regwin_switch(sc
, bus
, &old
);
973 CSR_SETBITS_4(sc
, BWI_INTRVEC
, (val
& BWI_FLAGS_INTR_MASK
));
977 mac_mask
= 1 << mac
->mac_id
;
979 error
= bwi_regwin_switch(sc
, bus
, &old
);
983 val
= pci_read_config(sc
->sc_dev
, BWI_PCIR_INTCTL
, 4);
984 val
|= mac_mask
<< 8;
985 pci_write_config(sc
->sc_dev
, BWI_PCIR_INTCTL
, val
, 4);
988 if (sc
->sc_flags
& BWI_F_BUS_INITED
)
991 if (bus
->rw_type
== BWI_REGWIN_T_BUSPCI
) {
993 * Enable prefetch and burst
995 CSR_SETBITS_4(sc
, BWI_BUS_CONFIG
,
996 BWI_BUS_CONFIG_PREFETCH
| BWI_BUS_CONFIG_BURST
);
998 if (bus
->rw_rev
< 5) {
999 struct bwi_regwin
*com
= &sc
->sc_com_regwin
;
1002 * Configure timeouts for bus operation
1006 * Set service timeout and request timeout
1008 CSR_SETBITS_4(sc
, BWI_CONF_LO
,
1009 __SHIFTIN(BWI_CONF_LO_SERVTO
, BWI_CONF_LO_SERVTO_MASK
) |
1010 __SHIFTIN(BWI_CONF_LO_REQTO
, BWI_CONF_LO_REQTO_MASK
));
1013 * If there is common regwin, we switch to that regwin
1014 * and switch back to bus regwin once we have done.
1016 if (BWI_REGWIN_EXIST(com
)) {
1017 error
= bwi_regwin_switch(sc
, com
, NULL
);
1022 /* Let bus know what we have changed */
1023 CSR_WRITE_4(sc
, BWI_BUS_ADDR
, BWI_BUS_ADDR_MAGIC
);
1024 CSR_READ_4(sc
, BWI_BUS_ADDR
); /* Flush */
1025 CSR_WRITE_4(sc
, BWI_BUS_DATA
, 0);
1026 CSR_READ_4(sc
, BWI_BUS_DATA
); /* Flush */
1028 if (BWI_REGWIN_EXIST(com
)) {
1029 error
= bwi_regwin_switch(sc
, bus
, NULL
);
1033 } else if (bus
->rw_rev
>= 11) {
1035 * Enable memory read multiple
1037 CSR_SETBITS_4(sc
, BWI_BUS_CONFIG
, BWI_BUS_CONFIG_MRM
);
1043 sc
->sc_flags
|= BWI_F_BUS_INITED
;
1045 return bwi_regwin_switch(sc
, old
, NULL
);
1049 bwi_get_card_flags(struct bwi_softc
*sc
)
1051 sc
->sc_card_flags
= bwi_read_sprom(sc
, BWI_SPROM_CARD_FLAGS
);
1052 if (sc
->sc_card_flags
== 0xffff)
1053 sc
->sc_card_flags
= 0;
1055 if (sc
->sc_pci_subvid
== PCI_VENDOR_APPLE
&&
1056 sc
->sc_pci_subdid
== 0x4e && /* XXX */
1057 sc
->sc_pci_revid
> 0x40)
1058 sc
->sc_card_flags
|= BWI_CARD_F_PA_GPIO9
;
1060 DPRINTF(sc
, BWI_DBG_ATTACH
, "card flags 0x%04x\n", sc
->sc_card_flags
);
1064 bwi_get_eaddr(struct bwi_softc
*sc
, uint16_t eaddr_ofs
, uint8_t *eaddr
)
1068 for (i
= 0; i
< 3; ++i
) {
1069 *((uint16_t *)eaddr
+ i
) =
1070 htobe16(bwi_read_sprom(sc
, eaddr_ofs
+ 2 * i
));
1075 bwi_get_clock_freq(struct bwi_softc
*sc
, struct bwi_clock_freq
*freq
)
1077 struct bwi_regwin
*com
;
1082 bzero(freq
, sizeof(*freq
));
1083 com
= &sc
->sc_com_regwin
;
1085 KKASSERT(BWI_REGWIN_EXIST(com
));
1086 KKASSERT(sc
->sc_cur_regwin
== com
);
1087 KKASSERT(sc
->sc_cap
& BWI_CAP_CLKMODE
);
1090 * Calculate clock frequency
1094 if (com
->rw_rev
< 6) {
1095 val
= pci_read_config(sc
->sc_dev
, BWI_PCIR_GPIO_OUT
, 4);
1096 if (val
& BWI_PCIM_GPIO_OUT_CLKSRC
) {
1097 src
= BWI_CLKSRC_PCI
;
1100 src
= BWI_CLKSRC_CS_OSC
;
1103 } else if (com
->rw_rev
< 10) {
1104 val
= CSR_READ_4(sc
, BWI_CLOCK_CTRL
);
1106 src
= __SHIFTOUT(val
, BWI_CLOCK_CTRL_CLKSRC
);
1107 if (src
== BWI_CLKSRC_LP_OSC
) {
1110 div
= (__SHIFTOUT(val
, BWI_CLOCK_CTRL_FDIV
) + 1) << 2;
1112 /* Unknown source */
1113 if (src
>= BWI_CLKSRC_MAX
)
1114 src
= BWI_CLKSRC_CS_OSC
;
1117 val
= CSR_READ_4(sc
, BWI_CLOCK_INFO
);
1119 src
= BWI_CLKSRC_CS_OSC
;
1120 div
= (__SHIFTOUT(val
, BWI_CLOCK_INFO_FDIV
) + 1) << 2;
1123 KKASSERT(src
>= 0 && src
< BWI_CLKSRC_MAX
);
1126 DPRINTF(sc
, BWI_DBG_ATTACH
, "clksrc %s\n",
1127 src
== BWI_CLKSRC_PCI
? "PCI" :
1128 (src
== BWI_CLKSRC_LP_OSC
? "LP_OSC" : "CS_OSC"));
1130 freq
->clkfreq_min
= bwi_clkfreq
[src
].freq_min
/ div
;
1131 freq
->clkfreq_max
= bwi_clkfreq
[src
].freq_max
/ div
;
1133 DPRINTF(sc
, BWI_DBG_ATTACH
, "clkfreq min %u, max %u\n",
1134 freq
->clkfreq_min
, freq
->clkfreq_max
);
1138 bwi_set_clock_mode(struct bwi_softc
*sc
, enum bwi_clock_mode clk_mode
)
1140 struct bwi_regwin
*old
, *com
;
1141 uint32_t clk_ctrl
, clk_src
;
1142 int error
, pwr_off
= 0;
1144 com
= &sc
->sc_com_regwin
;
1145 if (!BWI_REGWIN_EXIST(com
))
1148 if (com
->rw_rev
>= 10 || com
->rw_rev
< 6)
1152 * For common regwin whose rev is [6, 10), the chip
1153 * must be capable to change clock mode.
1155 if ((sc
->sc_cap
& BWI_CAP_CLKMODE
) == 0)
1158 error
= bwi_regwin_switch(sc
, com
, &old
);
1162 if (clk_mode
== BWI_CLOCK_MODE_FAST
)
1163 bwi_power_on(sc
, 0); /* Don't turn on PLL */
1165 clk_ctrl
= CSR_READ_4(sc
, BWI_CLOCK_CTRL
);
1166 clk_src
= __SHIFTOUT(clk_ctrl
, BWI_CLOCK_CTRL_CLKSRC
);
1169 case BWI_CLOCK_MODE_FAST
:
1170 clk_ctrl
&= ~BWI_CLOCK_CTRL_SLOW
;
1171 clk_ctrl
|= BWI_CLOCK_CTRL_IGNPLL
;
1173 case BWI_CLOCK_MODE_SLOW
:
1174 clk_ctrl
|= BWI_CLOCK_CTRL_SLOW
;
1176 case BWI_CLOCK_MODE_DYN
:
1177 clk_ctrl
&= ~(BWI_CLOCK_CTRL_SLOW
|
1178 BWI_CLOCK_CTRL_IGNPLL
|
1179 BWI_CLOCK_CTRL_NODYN
);
1180 if (clk_src
!= BWI_CLKSRC_CS_OSC
) {
1181 clk_ctrl
|= BWI_CLOCK_CTRL_NODYN
;
1186 CSR_WRITE_4(sc
, BWI_CLOCK_CTRL
, clk_ctrl
);
1189 bwi_power_off(sc
, 0); /* Leave PLL as it is */
1191 return bwi_regwin_switch(sc
, old
, NULL
);
1195 bwi_set_clock_delay(struct bwi_softc
*sc
)
1197 struct bwi_regwin
*old
, *com
;
1200 com
= &sc
->sc_com_regwin
;
1201 if (!BWI_REGWIN_EXIST(com
))
1204 error
= bwi_regwin_switch(sc
, com
, &old
);
1208 if (sc
->sc_bbp_id
== BWI_BBPID_BCM4321
) {
1209 if (sc
->sc_bbp_rev
== 0)
1210 CSR_WRITE_4(sc
, BWI_CONTROL
, BWI_CONTROL_MAGIC0
);
1211 else if (sc
->sc_bbp_rev
== 1)
1212 CSR_WRITE_4(sc
, BWI_CONTROL
, BWI_CONTROL_MAGIC1
);
1215 if (sc
->sc_cap
& BWI_CAP_CLKMODE
) {
1216 if (com
->rw_rev
>= 10) {
1217 CSR_FILT_SETBITS_4(sc
, BWI_CLOCK_INFO
, 0xffff, 0x40000);
1219 struct bwi_clock_freq freq
;
1221 bwi_get_clock_freq(sc
, &freq
);
1222 CSR_WRITE_4(sc
, BWI_PLL_ON_DELAY
,
1223 howmany(freq
.clkfreq_max
* 150, 1000000));
1224 CSR_WRITE_4(sc
, BWI_FREQ_SEL_DELAY
,
1225 howmany(freq
.clkfreq_max
* 15, 1000000));
1229 return bwi_regwin_switch(sc
, old
, NULL
);
1235 struct bwi_softc
*sc
= xsc
;
1236 struct ieee80211com
*ic
= &sc
->sc_ic
;
1237 struct ifnet
*ifp
= &ic
->ic_if
;
1238 struct bwi_mac
*mac
;
1241 ASSERT_SERIALIZED(ifp
->if_serializer
);
1243 error
= bwi_stop(sc
);
1245 if_printf(ifp
, "can't stop\n");
1249 bwi_bbp_power_on(sc
, BWI_CLOCK_MODE_FAST
);
1253 mac
= &sc
->sc_mac
[0];
1254 error
= bwi_regwin_switch(sc
, &mac
->mac_regwin
, NULL
);
1258 error
= bwi_mac_init(mac
);
1262 bwi_bbp_power_on(sc
, BWI_CLOCK_MODE_DYN
);
1264 bcopy(IF_LLADDR(ifp
), ic
->ic_myaddr
, sizeof(ic
->ic_myaddr
));
1266 bwi_set_bssid(sc
, bwi_zero_addr
); /* Clear BSSID */
1267 bwi_set_addr_filter(sc
, BWI_ADDR_FILTER_MYADDR
, ic
->ic_myaddr
);
1269 bwi_mac_reset_hwkeys(mac
);
1271 if ((mac
->mac_flags
& BWI_MAC_F_HAS_TXSTATS
) == 0) {
1276 * Drain any possible pending TX status
1278 for (i
= 0; i
< NRETRY
; ++i
) {
1279 if ((CSR_READ_4(sc
, BWI_TXSTATUS0
) &
1280 BWI_TXSTATUS0_VALID
) == 0)
1282 CSR_READ_4(sc
, BWI_TXSTATUS1
);
1285 if_printf(ifp
, "can't drain TX status\n");
1289 if (mac
->mac_phy
.phy_mode
== IEEE80211_MODE_11G
)
1290 bwi_mac_updateslot(mac
, 1);
1293 error
= bwi_mac_start(mac
);
1298 bwi_enable_intrs(sc
, BWI_INIT_INTRS
);
1300 ifp
->if_flags
|= IFF_RUNNING
;
1301 ifp
->if_flags
&= ~IFF_OACTIVE
;
1303 if (ic
->ic_opmode
!= IEEE80211_M_MONITOR
) {
1304 if (ic
->ic_roaming
!= IEEE80211_ROAMING_MANUAL
)
1305 ieee80211_new_state(ic
, IEEE80211_S_SCAN
, -1);
1307 ieee80211_new_state(ic
, IEEE80211_S_RUN
, -1);
1315 bwi_ioctl(struct ifnet
*ifp
, u_long cmd
, caddr_t req
, struct ucred
*cr
)
1317 struct bwi_softc
*sc
= ifp
->if_softc
;
1320 ASSERT_SERIALIZED(ifp
->if_serializer
);
1324 if ((ifp
->if_flags
& (IFF_UP
| IFF_RUNNING
)) ==
1325 (IFF_UP
| IFF_RUNNING
)) {
1326 struct bwi_mac
*mac
;
1329 KKASSERT(sc
->sc_cur_regwin
->rw_type
==
1331 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
1333 if ((ifp
->if_flags
& IFF_PROMISC
) &&
1334 (sc
->sc_flags
& BWI_F_PROMISC
) == 0) {
1336 sc
->sc_flags
|= BWI_F_PROMISC
;
1337 } else if ((ifp
->if_flags
& IFF_PROMISC
) == 0 &&
1338 (sc
->sc_flags
& BWI_F_PROMISC
)) {
1340 sc
->sc_flags
&= ~BWI_F_PROMISC
;
1344 bwi_mac_set_promisc(mac
, promisc
);
1347 if (ifp
->if_flags
& IFF_UP
) {
1348 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
1351 if (ifp
->if_flags
& IFF_RUNNING
)
1356 error
= ieee80211_ioctl(&sc
->sc_ic
, cmd
, req
, cr
);
1360 if (error
== ENETRESET
) {
1361 if ((ifp
->if_flags
& (IFF_UP
| IFF_RUNNING
)) ==
1362 (IFF_UP
| IFF_RUNNING
))
1370 bwi_start(struct ifnet
*ifp
)
1372 struct bwi_softc
*sc
= ifp
->if_softc
;
1373 struct ieee80211com
*ic
= &sc
->sc_ic
;
1374 struct bwi_txbuf_data
*tbd
= &sc
->sc_tx_bdata
[BWI_TX_DATA_RING
];
1377 ASSERT_SERIALIZED(ifp
->if_serializer
);
1379 if ((ifp
->if_flags
& IFF_OACTIVE
) ||
1380 (ifp
->if_flags
& IFF_RUNNING
) == 0)
1386 while (tbd
->tbd_buf
[idx
].tb_mbuf
== NULL
) {
1387 struct ieee80211_frame
*wh
;
1388 struct ieee80211_node
*ni
;
1392 if (!IF_QEMPTY(&ic
->ic_mgtq
)) {
1393 IF_DEQUEUE(&ic
->ic_mgtq
, m
);
1395 ni
= (struct ieee80211_node
*)m
->m_pkthdr
.rcvif
;
1396 m
->m_pkthdr
.rcvif
= NULL
;
1399 } else if (!ifq_is_empty(&ifp
->if_snd
)) {
1400 struct ether_header
*eh
;
1402 if (ic
->ic_state
!= IEEE80211_S_RUN
)
1405 m
= ifq_dequeue(&ifp
->if_snd
, NULL
);
1409 if (m
->m_len
< sizeof(*eh
)) {
1410 m
= m_pullup(m
, sizeof(*eh
));
1416 eh
= mtod(m
, struct ether_header
*);
1418 ni
= ieee80211_find_txnode(ic
, eh
->ether_dhost
);
1429 m
= ieee80211_encap(ic
, m
, ni
);
1431 ieee80211_free_node(ni
);
1439 if (ic
->ic_rawbpf
!= NULL
)
1440 bpf_mtap(ic
->ic_rawbpf
, m
);
1442 wh
= mtod(m
, struct ieee80211_frame
*);
1443 if (wh
->i_fc
[1] & IEEE80211_FC1_WEP
) {
1444 if (ieee80211_crypto_encap(ic
, ni
, m
) == NULL
) {
1445 ieee80211_free_node(ni
);
1451 wh
= NULL
; /* Catch any invalid use */
1453 if (bwi_encap(sc
, idx
, m
, &ni
, mgt_pkt
) != 0) {
1454 /* 'm' is freed in bwi_encap() if we reach here */
1456 ieee80211_free_node(ni
);
1463 idx
= (idx
+ 1) % BWI_TX_NDESC
;
1465 if (tbd
->tbd_used
+ BWI_TX_NSPRDESC
>= BWI_TX_NDESC
) {
1466 ifp
->if_flags
|= IFF_OACTIVE
;
1473 sc
->sc_tx_timer
= 5;
1478 bwi_watchdog(struct ifnet
*ifp
)
1480 struct bwi_softc
*sc
= ifp
->if_softc
;
1482 ASSERT_SERIALIZED(ifp
->if_serializer
);
1486 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
1489 if (sc
->sc_tx_timer
) {
1490 if (--sc
->sc_tx_timer
== 0) {
1491 if_printf(ifp
, "watchdog timeout\n");
1498 ieee80211_watchdog(&sc
->sc_ic
);
1502 bwi_stop(struct bwi_softc
*sc
)
1504 struct ieee80211com
*ic
= &sc
->sc_ic
;
1505 struct ifnet
*ifp
= &ic
->ic_if
;
1506 struct bwi_mac
*mac
;
1507 int i
, error
, pwr_off
= 0;
1509 ASSERT_SERIALIZED(ifp
->if_serializer
);
1511 ieee80211_new_state(ic
, IEEE80211_S_INIT
, -1);
1513 if (ifp
->if_flags
& IFF_RUNNING
) {
1514 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
1515 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
1517 bwi_disable_intrs(sc
, BWI_ALL_INTRS
);
1518 CSR_READ_4(sc
, BWI_MAC_INTR_MASK
);
1522 for (i
= 0; i
< sc
->sc_nmac
; ++i
) {
1523 struct bwi_regwin
*old_rw
;
1525 mac
= &sc
->sc_mac
[i
];
1526 if ((mac
->mac_flags
& BWI_MAC_F_INITED
) == 0)
1529 error
= bwi_regwin_switch(sc
, &mac
->mac_regwin
, &old_rw
);
1533 bwi_mac_shutdown(mac
);
1536 bwi_regwin_switch(sc
, old_rw
, NULL
);
1540 bwi_bbp_power_off(sc
);
1542 sc
->sc_tx_timer
= 0;
1544 ifp
->if_flags
&= ~(IFF_RUNNING
| IFF_OACTIVE
);
1551 struct bwi_softc
*sc
= xsc
;
1552 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
1553 uint32_t intr_status
;
1554 uint32_t txrx_intr_status
[BWI_TXRX_NRING
];
1557 ASSERT_SERIALIZED(ifp
->if_serializer
);
1559 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
1563 * Get interrupt status
1565 intr_status
= CSR_READ_4(sc
, BWI_MAC_INTR_STATUS
);
1566 if (intr_status
== 0xffffffff) /* Not for us */
1569 DPRINTF(sc
, BWI_DBG_INTR
, "intr status 0x%08x\n", intr_status
);
1571 intr_status
&= CSR_READ_4(sc
, BWI_MAC_INTR_MASK
);
1572 if (intr_status
== 0) /* Nothing is interesting */
1576 DPRINTF(sc
, BWI_DBG_INTR
, "%s\n", "TX/RX intr");
1577 for (i
= 0; i
< BWI_TXRX_NRING
; ++i
) {
1580 if (BWI_TXRX_IS_RX(i
))
1581 mask
= BWI_TXRX_RX_INTRS
;
1583 mask
= BWI_TXRX_TX_INTRS
;
1585 txrx_intr_status
[i
] =
1586 CSR_READ_4(sc
, BWI_TXRX_INTR_STATUS(i
)) & mask
;
1588 _DPRINTF(sc
, BWI_DBG_INTR
, ", %d 0x%08x",
1589 i
, txrx_intr_status
[i
]);
1591 if (txrx_intr_status
[i
] & BWI_TXRX_INTR_ERROR
) {
1592 if_printf(ifp
, "intr fatal TX/RX (%d) error 0x%08x\n",
1593 i
, txrx_intr_status
[i
]);
1597 _DPRINTF(sc
, BWI_DBG_INTR
, "%s\n", "");
1600 * Acknowledge interrupt
1602 CSR_WRITE_4(sc
, BWI_MAC_INTR_STATUS
, intr_status
);
1604 for (i
= 0; i
< BWI_TXRX_NRING
; ++i
)
1605 CSR_WRITE_4(sc
, BWI_TXRX_INTR_STATUS(i
), txrx_intr_status
[i
]);
1607 /* Disable all interrupts */
1608 bwi_disable_intrs(sc
, BWI_ALL_INTRS
);
1610 if (intr_status
& BWI_INTR_PHY_TXERR
)
1611 if_printf(ifp
, "intr PHY TX error\n");
1614 /* TODO: reset device */
1617 if (intr_status
& BWI_INTR_TBTT
) {
1618 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
1619 bwi_mac_config_ps((struct bwi_mac
*)sc
->sc_cur_regwin
);
1622 if (intr_status
& BWI_INTR_EO_ATIM
)
1623 if_printf(ifp
, "EO_ATIM\n");
1625 if (intr_status
& BWI_INTR_PMQ
) {
1627 if ((CSR_READ_4(sc
, BWI_MAC_PS_STATUS
) & 0x8) == 0)
1630 CSR_WRITE_2(sc
, BWI_MAC_PS_STATUS
, 0x2);
1633 if (intr_status
& BWI_INTR_NOISE
)
1634 if_printf(ifp
, "intr noise\n");
1636 if (txrx_intr_status
[0] & BWI_TXRX_INTR_RX
)
1639 if (txrx_intr_status
[3] & BWI_TXRX_INTR_RX
)
1640 sc
->sc_txeof_status(sc
);
1642 if (intr_status
& BWI_INTR_TX_DONE
)
1647 /* Re-enable interrupts */
1648 bwi_enable_intrs(sc
, BWI_INIT_INTRS
);
1652 bwi_newstate(struct ieee80211com
*ic
, enum ieee80211_state nstate
, int arg
)
1654 struct bwi_softc
*sc
= ic
->ic_if
.if_softc
;
1655 struct ifnet
*ifp
= &ic
->ic_if
;
1658 ASSERT_SERIALIZED(ifp
->if_serializer
);
1660 callout_stop(&sc
->sc_scan_ch
);
1661 callout_stop(&sc
->sc_calib_ch
);
1663 if (nstate
== IEEE80211_S_INIT
)
1666 error
= bwi_set_chan(sc
, ic
->ic_curchan
);
1668 if_printf(ifp
, "can't set channel to %u\n",
1669 ieee80211_chan2ieee(ic
, ic
->ic_curchan
));
1673 if (ic
->ic_opmode
== IEEE80211_M_MONITOR
) {
1675 } else if (nstate
== IEEE80211_S_RUN
) {
1676 struct bwi_mac
*mac
;
1678 bwi_set_bssid(sc
, ic
->ic_bss
->ni_bssid
);
1680 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
1681 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
1683 /* Initial TX power calibration */
1684 bwi_mac_calibrate_txpower(mac
);
1686 bwi_set_bssid(sc
, bwi_zero_addr
);
1690 error
= sc
->sc_newstate(ic
, nstate
, arg
);
1692 if (nstate
== IEEE80211_S_SCAN
) {
1693 callout_reset(&sc
->sc_scan_ch
,
1694 (sc
->sc_dwell_time
* hz
) / 1000,
1696 } else if (nstate
== IEEE80211_S_RUN
) {
1697 /* XXX 15 seconds */
1698 callout_reset(&sc
->sc_calib_ch
, hz
* 15, bwi_calibrate
, sc
);
1704 bwi_media_change(struct ifnet
*ifp
)
1708 ASSERT_SERIALIZED(ifp
->if_serializer
);
1710 error
= ieee80211_media_change(ifp
);
1711 if (error
!= ENETRESET
)
1714 if ((ifp
->if_flags
& (IFF_UP
| IFF_RUNNING
)) == (IFF_UP
| IFF_RUNNING
))
1715 bwi_init(ifp
->if_softc
);
1720 bwi_dma_alloc(struct bwi_softc
*sc
)
1722 int error
, i
, has_txstats
;
1723 bus_addr_t lowaddr
= 0;
1724 bus_size_t tx_ring_sz
, rx_ring_sz
, desc_sz
= 0;
1725 uint32_t txrx_ctrl_step
= 0;
1728 for (i
= 0; i
< sc
->sc_nmac
; ++i
) {
1729 if (sc
->sc_mac
[i
].mac_flags
& BWI_MAC_F_HAS_TXSTATS
) {
1735 switch (sc
->sc_bus_space
) {
1736 case BWI_BUS_SPACE_30BIT
:
1737 case BWI_BUS_SPACE_32BIT
:
1738 if (sc
->sc_bus_space
== BWI_BUS_SPACE_30BIT
)
1739 lowaddr
= BWI_BUS_SPACE_MAXADDR
;
1741 lowaddr
= BUS_SPACE_MAXADDR_32BIT
;
1742 desc_sz
= sizeof(struct bwi_desc32
);
1743 txrx_ctrl_step
= 0x20;
1745 sc
->sc_init_tx_ring
= bwi_init_tx_ring32
;
1746 sc
->sc_free_tx_ring
= bwi_free_tx_ring32
;
1747 sc
->sc_init_rx_ring
= bwi_init_rx_ring32
;
1748 sc
->sc_free_rx_ring
= bwi_free_rx_ring32
;
1749 sc
->sc_setup_rxdesc
= bwi_setup_rx_desc32
;
1750 sc
->sc_setup_txdesc
= bwi_setup_tx_desc32
;
1751 sc
->sc_rxeof
= bwi_rxeof32
;
1752 sc
->sc_start_tx
= bwi_start_tx32
;
1754 sc
->sc_init_txstats
= bwi_init_txstats32
;
1755 sc
->sc_free_txstats
= bwi_free_txstats32
;
1756 sc
->sc_txeof_status
= bwi_txeof_status32
;
1760 case BWI_BUS_SPACE_64BIT
:
1761 lowaddr
= BUS_SPACE_MAXADDR
; /* XXX */
1762 desc_sz
= sizeof(struct bwi_desc64
);
1763 txrx_ctrl_step
= 0x40;
1765 sc
->sc_init_tx_ring
= bwi_init_tx_ring64
;
1766 sc
->sc_free_tx_ring
= bwi_free_tx_ring64
;
1767 sc
->sc_init_rx_ring
= bwi_init_rx_ring64
;
1768 sc
->sc_free_rx_ring
= bwi_free_rx_ring64
;
1769 sc
->sc_setup_rxdesc
= bwi_setup_rx_desc64
;
1770 sc
->sc_setup_txdesc
= bwi_setup_tx_desc64
;
1771 sc
->sc_rxeof
= bwi_rxeof64
;
1772 sc
->sc_start_tx
= bwi_start_tx64
;
1774 sc
->sc_init_txstats
= bwi_init_txstats64
;
1775 sc
->sc_free_txstats
= bwi_free_txstats64
;
1776 sc
->sc_txeof_status
= bwi_txeof_status64
;
1781 KKASSERT(lowaddr
!= 0);
1782 KKASSERT(desc_sz
!= 0);
1783 KKASSERT(txrx_ctrl_step
!= 0);
1785 tx_ring_sz
= roundup(desc_sz
* BWI_TX_NDESC
, BWI_RING_ALIGN
);
1786 rx_ring_sz
= roundup(desc_sz
* BWI_RX_NDESC
, BWI_RING_ALIGN
);
1789 * Create top level DMA tag
1791 error
= bus_dma_tag_create(NULL
, BWI_ALIGN
, 0,
1792 lowaddr
, BUS_SPACE_MAXADDR
,
1795 BUS_SPACE_UNRESTRICTED
,
1796 BUS_SPACE_MAXSIZE_32BIT
,
1797 0, &sc
->sc_parent_dtag
);
1799 device_printf(sc
->sc_dev
, "can't create parent DMA tag\n");
1803 #define TXRX_CTRL(idx) (BWI_TXRX_CTRL_BASE + (idx) * txrx_ctrl_step)
1806 * Create TX ring DMA stuffs
1808 error
= bus_dma_tag_create(sc
->sc_parent_dtag
, BWI_RING_ALIGN
, 0,
1809 BUS_SPACE_MAXADDR
, BUS_SPACE_MAXADDR
,
1811 tx_ring_sz
, 1, BUS_SPACE_MAXSIZE_32BIT
,
1812 0, &sc
->sc_txring_dtag
);
1814 device_printf(sc
->sc_dev
, "can't create TX ring DMA tag\n");
1818 for (i
= 0; i
< BWI_TX_NRING
; ++i
) {
1819 error
= bwi_dma_ring_alloc(sc
, sc
->sc_txring_dtag
,
1820 &sc
->sc_tx_rdata
[i
], tx_ring_sz
,
1823 device_printf(sc
->sc_dev
, "%dth TX ring "
1824 "DMA alloc failed\n", i
);
1830 * Create RX ring DMA stuffs
1832 error
= bus_dma_tag_create(sc
->sc_parent_dtag
, BWI_RING_ALIGN
, 0,
1833 BUS_SPACE_MAXADDR
, BUS_SPACE_MAXADDR
,
1835 rx_ring_sz
, 1, BUS_SPACE_MAXSIZE_32BIT
,
1836 0, &sc
->sc_rxring_dtag
);
1838 device_printf(sc
->sc_dev
, "can't create RX ring DMA tag\n");
1842 error
= bwi_dma_ring_alloc(sc
, sc
->sc_rxring_dtag
, &sc
->sc_rx_rdata
,
1843 rx_ring_sz
, TXRX_CTRL(0));
1845 device_printf(sc
->sc_dev
, "RX ring DMA alloc failed\n");
1850 error
= bwi_dma_txstats_alloc(sc
, TXRX_CTRL(3), desc_sz
);
1852 device_printf(sc
->sc_dev
,
1853 "TX stats DMA alloc failed\n");
1860 return bwi_dma_mbuf_create(sc
);
1864 bwi_dma_free(struct bwi_softc
*sc
)
1866 if (sc
->sc_txring_dtag
!= NULL
) {
1869 for (i
= 0; i
< BWI_TX_NRING
; ++i
) {
1870 struct bwi_ring_data
*rd
= &sc
->sc_tx_rdata
[i
];
1872 if (rd
->rdata_desc
!= NULL
) {
1873 bus_dmamap_unload(sc
->sc_txring_dtag
,
1875 bus_dmamem_free(sc
->sc_txring_dtag
,
1880 bus_dma_tag_destroy(sc
->sc_txring_dtag
);
1883 if (sc
->sc_rxring_dtag
!= NULL
) {
1884 struct bwi_ring_data
*rd
= &sc
->sc_rx_rdata
;
1886 if (rd
->rdata_desc
!= NULL
) {
1887 bus_dmamap_unload(sc
->sc_rxring_dtag
, rd
->rdata_dmap
);
1888 bus_dmamem_free(sc
->sc_rxring_dtag
, rd
->rdata_desc
,
1891 bus_dma_tag_destroy(sc
->sc_rxring_dtag
);
1894 bwi_dma_txstats_free(sc
);
1895 bwi_dma_mbuf_destroy(sc
, BWI_TX_NRING
, 1);
1897 if (sc
->sc_parent_dtag
!= NULL
)
1898 bus_dma_tag_destroy(sc
->sc_parent_dtag
);
1902 bwi_dma_ring_alloc(struct bwi_softc
*sc
, bus_dma_tag_t dtag
,
1903 struct bwi_ring_data
*rd
, bus_size_t size
,
1908 error
= bus_dmamem_alloc(dtag
, &rd
->rdata_desc
,
1909 BUS_DMA_WAITOK
| BUS_DMA_ZERO
,
1912 device_printf(sc
->sc_dev
, "can't allocate DMA mem\n");
1916 error
= bus_dmamap_load(dtag
, rd
->rdata_dmap
, rd
->rdata_desc
, size
,
1917 bwi_dma_ring_addr
, &rd
->rdata_paddr
,
1920 device_printf(sc
->sc_dev
, "can't load DMA mem\n");
1921 bus_dmamem_free(dtag
, rd
->rdata_desc
, rd
->rdata_dmap
);
1922 rd
->rdata_desc
= NULL
;
1926 rd
->rdata_txrx_ctrl
= txrx_ctrl
;
1931 bwi_dma_txstats_alloc(struct bwi_softc
*sc
, uint32_t ctrl_base
,
1934 struct bwi_txstats_data
*st
;
1935 bus_size_t dma_size
;
1938 st
= kmalloc(sizeof(*st
), M_DEVBUF
, M_WAITOK
| M_ZERO
);
1939 sc
->sc_txstats
= st
;
1942 * Create TX stats descriptor DMA stuffs
1944 dma_size
= roundup(desc_sz
* BWI_TXSTATS_NDESC
, BWI_RING_ALIGN
);
1946 error
= bus_dma_tag_create(sc
->sc_parent_dtag
, BWI_RING_ALIGN
, 0,
1947 BUS_SPACE_MAXADDR
, BUS_SPACE_MAXADDR
,
1949 dma_size
, 1, BUS_SPACE_MAXSIZE_32BIT
,
1950 0, &st
->stats_ring_dtag
);
1952 device_printf(sc
->sc_dev
, "can't create txstats ring "
1957 error
= bus_dmamem_alloc(st
->stats_ring_dtag
, &st
->stats_ring
,
1958 BUS_DMA_WAITOK
| BUS_DMA_ZERO
,
1959 &st
->stats_ring_dmap
);
1961 device_printf(sc
->sc_dev
, "can't allocate txstats ring "
1963 bus_dma_tag_destroy(st
->stats_ring_dtag
);
1964 st
->stats_ring_dtag
= NULL
;
1968 error
= bus_dmamap_load(st
->stats_ring_dtag
, st
->stats_ring_dmap
,
1969 st
->stats_ring
, dma_size
,
1970 bwi_dma_ring_addr
, &st
->stats_ring_paddr
,
1973 device_printf(sc
->sc_dev
, "can't load txstats ring DMA mem\n");
1974 bus_dmamem_free(st
->stats_ring_dtag
, st
->stats_ring
,
1975 st
->stats_ring_dmap
);
1976 bus_dma_tag_destroy(st
->stats_ring_dtag
);
1977 st
->stats_ring_dtag
= NULL
;
1982 * Create TX stats DMA stuffs
1984 dma_size
= roundup(sizeof(struct bwi_txstats
) * BWI_TXSTATS_NDESC
,
1987 error
= bus_dma_tag_create(sc
->sc_parent_dtag
, BWI_ALIGN
, 0,
1988 BUS_SPACE_MAXADDR
, BUS_SPACE_MAXADDR
,
1990 dma_size
, 1, BUS_SPACE_MAXSIZE_32BIT
,
1991 0, &st
->stats_dtag
);
1993 device_printf(sc
->sc_dev
, "can't create txstats DMA tag\n");
1997 error
= bus_dmamem_alloc(st
->stats_dtag
, (void **)&st
->stats
,
1998 BUS_DMA_WAITOK
| BUS_DMA_ZERO
,
2001 device_printf(sc
->sc_dev
, "can't allocate txstats DMA mem\n");
2002 bus_dma_tag_destroy(st
->stats_dtag
);
2003 st
->stats_dtag
= NULL
;
2007 error
= bus_dmamap_load(st
->stats_dtag
, st
->stats_dmap
, st
->stats
,
2008 dma_size
, bwi_dma_ring_addr
, &st
->stats_paddr
,
2011 device_printf(sc
->sc_dev
, "can't load txstats DMA mem\n");
2012 bus_dmamem_free(st
->stats_dtag
, st
->stats
, st
->stats_dmap
);
2013 bus_dma_tag_destroy(st
->stats_dtag
);
2014 st
->stats_dtag
= NULL
;
2018 st
->stats_ctrl_base
= ctrl_base
;
2023 bwi_dma_txstats_free(struct bwi_softc
*sc
)
2025 struct bwi_txstats_data
*st
;
2027 if (sc
->sc_txstats
== NULL
)
2029 st
= sc
->sc_txstats
;
2031 if (st
->stats_ring_dtag
!= NULL
) {
2032 bus_dmamap_unload(st
->stats_ring_dtag
, st
->stats_ring_dmap
);
2033 bus_dmamem_free(st
->stats_ring_dtag
, st
->stats_ring
,
2034 st
->stats_ring_dmap
);
2035 bus_dma_tag_destroy(st
->stats_ring_dtag
);
2038 if (st
->stats_dtag
!= NULL
) {
2039 bus_dmamap_unload(st
->stats_dtag
, st
->stats_dmap
);
2040 bus_dmamem_free(st
->stats_dtag
, st
->stats
, st
->stats_dmap
);
2041 bus_dma_tag_destroy(st
->stats_dtag
);
2044 kfree(st
, M_DEVBUF
);
2048 bwi_dma_ring_addr(void *arg
, bus_dma_segment_t
*seg
, int nseg
, int error
)
2050 KASSERT(nseg
== 1, ("too many segments\n"));
2051 *((bus_addr_t
*)arg
) = seg
->ds_addr
;
2055 bwi_dma_mbuf_create(struct bwi_softc
*sc
)
2057 struct bwi_rxbuf_data
*rbd
= &sc
->sc_rx_bdata
;
2058 int i
, j
, k
, ntx
, error
;
2061 * Create TX/RX mbuf DMA tag
2063 error
= bus_dma_tag_create(sc
->sc_parent_dtag
, 1, 0,
2064 BUS_SPACE_MAXADDR
, BUS_SPACE_MAXADDR
,
2065 NULL
, NULL
, MCLBYTES
, 1,
2066 BUS_SPACE_MAXSIZE_32BIT
,
2067 0, &sc
->sc_buf_dtag
);
2069 device_printf(sc
->sc_dev
, "can't create mbuf DMA tag\n");
2076 * Create TX mbuf DMA map
2078 for (i
= 0; i
< BWI_TX_NRING
; ++i
) {
2079 struct bwi_txbuf_data
*tbd
= &sc
->sc_tx_bdata
[i
];
2081 for (j
= 0; j
< BWI_TX_NDESC
; ++j
) {
2082 error
= bus_dmamap_create(sc
->sc_buf_dtag
, 0,
2083 &tbd
->tbd_buf
[j
].tb_dmap
);
2085 device_printf(sc
->sc_dev
, "can't create "
2086 "%dth tbd, %dth DMA map\n", i
, j
);
2089 for (k
= 0; k
< j
; ++k
) {
2090 bus_dmamap_destroy(sc
->sc_buf_dtag
,
2091 tbd
->tbd_buf
[k
].tb_dmap
);
2100 * Create RX mbuf DMA map and a spare DMA map
2102 error
= bus_dmamap_create(sc
->sc_buf_dtag
, 0,
2103 &rbd
->rbd_tmp_dmap
);
2105 device_printf(sc
->sc_dev
,
2106 "can't create spare RX buf DMA map\n");
2110 for (j
= 0; j
< BWI_RX_NDESC
; ++j
) {
2111 error
= bus_dmamap_create(sc
->sc_buf_dtag
, 0,
2112 &rbd
->rbd_buf
[j
].rb_dmap
);
2114 device_printf(sc
->sc_dev
, "can't create %dth "
2115 "RX buf DMA map\n", j
);
2117 for (k
= 0; k
< j
; ++k
) {
2118 bus_dmamap_destroy(sc
->sc_buf_dtag
,
2119 rbd
->rbd_buf
[j
].rb_dmap
);
2121 bus_dmamap_destroy(sc
->sc_buf_dtag
,
2129 bwi_dma_mbuf_destroy(sc
, ntx
, 0);
2134 bwi_dma_mbuf_destroy(struct bwi_softc
*sc
, int ntx
, int nrx
)
2138 if (sc
->sc_buf_dtag
== NULL
)
2141 for (i
= 0; i
< ntx
; ++i
) {
2142 struct bwi_txbuf_data
*tbd
= &sc
->sc_tx_bdata
[i
];
2144 for (j
= 0; j
< BWI_TX_NDESC
; ++j
) {
2145 struct bwi_txbuf
*tb
= &tbd
->tbd_buf
[j
];
2147 if (tb
->tb_mbuf
!= NULL
) {
2148 bus_dmamap_unload(sc
->sc_buf_dtag
,
2150 m_freem(tb
->tb_mbuf
);
2152 if (tb
->tb_ni
!= NULL
)
2153 ieee80211_free_node(tb
->tb_ni
);
2154 bus_dmamap_destroy(sc
->sc_buf_dtag
, tb
->tb_dmap
);
2159 struct bwi_rxbuf_data
*rbd
= &sc
->sc_rx_bdata
;
2161 bus_dmamap_destroy(sc
->sc_buf_dtag
, rbd
->rbd_tmp_dmap
);
2162 for (j
= 0; j
< BWI_RX_NDESC
; ++j
) {
2163 struct bwi_rxbuf
*rb
= &rbd
->rbd_buf
[j
];
2165 if (rb
->rb_mbuf
!= NULL
) {
2166 bus_dmamap_unload(sc
->sc_buf_dtag
,
2168 m_freem(rb
->rb_mbuf
);
2170 bus_dmamap_destroy(sc
->sc_buf_dtag
, rb
->rb_dmap
);
2174 bus_dma_tag_destroy(sc
->sc_buf_dtag
);
2175 sc
->sc_buf_dtag
= NULL
;
2179 bwi_enable_intrs(struct bwi_softc
*sc
, uint32_t enable_intrs
)
2181 CSR_SETBITS_4(sc
, BWI_MAC_INTR_MASK
, enable_intrs
);
2185 bwi_disable_intrs(struct bwi_softc
*sc
, uint32_t disable_intrs
)
2187 CSR_CLRBITS_4(sc
, BWI_MAC_INTR_MASK
, disable_intrs
);
2191 bwi_init_tx_ring32(struct bwi_softc
*sc
, int ring_idx
)
2193 struct bwi_ring_data
*rd
;
2194 struct bwi_txbuf_data
*tbd
;
2195 uint32_t val
, addr_hi
, addr_lo
;
2197 KKASSERT(ring_idx
< BWI_TX_NRING
);
2198 rd
= &sc
->sc_tx_rdata
[ring_idx
];
2199 tbd
= &sc
->sc_tx_bdata
[ring_idx
];
2204 bzero(rd
->rdata_desc
, sizeof(struct bwi_desc32
) * BWI_TX_NDESC
);
2205 bus_dmamap_sync(sc
->sc_txring_dtag
, rd
->rdata_dmap
,
2206 BUS_DMASYNC_PREWRITE
);
2208 addr_lo
= __SHIFTOUT(rd
->rdata_paddr
, BWI_TXRX32_RINGINFO_ADDR_MASK
);
2209 addr_hi
= __SHIFTOUT(rd
->rdata_paddr
, BWI_TXRX32_RINGINFO_FUNC_MASK
);
2211 val
= __SHIFTIN(addr_lo
, BWI_TXRX32_RINGINFO_ADDR_MASK
) |
2212 __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX
,
2213 BWI_TXRX32_RINGINFO_FUNC_MASK
);
2214 CSR_WRITE_4(sc
, rd
->rdata_txrx_ctrl
+ BWI_TX32_RINGINFO
, val
);
2216 val
= __SHIFTIN(addr_hi
, BWI_TXRX32_CTRL_ADDRHI_MASK
) |
2217 BWI_TXRX32_CTRL_ENABLE
;
2218 CSR_WRITE_4(sc
, rd
->rdata_txrx_ctrl
+ BWI_TX32_CTRL
, val
);
2224 bwi_init_rxdesc_ring32(struct bwi_softc
*sc
, uint32_t ctrl_base
,
2225 bus_addr_t paddr
, int hdr_size
, int ndesc
)
2227 uint32_t val
, addr_hi
, addr_lo
;
2229 addr_lo
= __SHIFTOUT(paddr
, BWI_TXRX32_RINGINFO_ADDR_MASK
);
2230 addr_hi
= __SHIFTOUT(paddr
, BWI_TXRX32_RINGINFO_FUNC_MASK
);
2232 val
= __SHIFTIN(addr_lo
, BWI_TXRX32_RINGINFO_ADDR_MASK
) |
2233 __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX
,
2234 BWI_TXRX32_RINGINFO_FUNC_MASK
);
2235 CSR_WRITE_4(sc
, ctrl_base
+ BWI_RX32_RINGINFO
, val
);
2237 val
= __SHIFTIN(hdr_size
, BWI_RX32_CTRL_HDRSZ_MASK
) |
2238 __SHIFTIN(addr_hi
, BWI_TXRX32_CTRL_ADDRHI_MASK
) |
2239 BWI_TXRX32_CTRL_ENABLE
;
2240 CSR_WRITE_4(sc
, ctrl_base
+ BWI_RX32_CTRL
, val
);
2242 CSR_WRITE_4(sc
, ctrl_base
+ BWI_RX32_INDEX
,
2243 (ndesc
- 1) * sizeof(struct bwi_desc32
));
2247 bwi_init_rx_ring32(struct bwi_softc
*sc
)
2249 struct bwi_ring_data
*rd
= &sc
->sc_rx_rdata
;
2252 sc
->sc_rx_bdata
.rbd_idx
= 0;
2254 for (i
= 0; i
< BWI_RX_NDESC
; ++i
) {
2255 error
= bwi_newbuf(sc
, i
, 1);
2257 if_printf(&sc
->sc_ic
.ic_if
,
2258 "can't allocate %dth RX buffer\n", i
);
2262 bus_dmamap_sync(sc
->sc_rxring_dtag
, rd
->rdata_dmap
,
2263 BUS_DMASYNC_PREWRITE
);
2265 bwi_init_rxdesc_ring32(sc
, rd
->rdata_txrx_ctrl
, rd
->rdata_paddr
,
2266 sizeof(struct bwi_rxbuf_hdr
), BWI_RX_NDESC
);
2271 bwi_init_txstats32(struct bwi_softc
*sc
)
2273 struct bwi_txstats_data
*st
= sc
->sc_txstats
;
2274 bus_addr_t stats_paddr
;
2277 bzero(st
->stats
, BWI_TXSTATS_NDESC
* sizeof(struct bwi_txstats
));
2278 bus_dmamap_sync(st
->stats_dtag
, st
->stats_dmap
, BUS_DMASYNC_PREWRITE
);
2282 stats_paddr
= st
->stats_paddr
;
2283 for (i
= 0; i
< BWI_TXSTATS_NDESC
; ++i
) {
2284 bwi_setup_desc32(sc
, st
->stats_ring
, BWI_TXSTATS_NDESC
, i
,
2285 stats_paddr
, sizeof(struct bwi_txstats
), 0);
2286 stats_paddr
+= sizeof(struct bwi_txstats
);
2288 bus_dmamap_sync(st
->stats_ring_dtag
, st
->stats_ring_dmap
,
2289 BUS_DMASYNC_PREWRITE
);
2291 bwi_init_rxdesc_ring32(sc
, st
->stats_ctrl_base
,
2292 st
->stats_ring_paddr
, 0, BWI_TXSTATS_NDESC
);
2297 bwi_setup_rx_desc32(struct bwi_softc
*sc
, int buf_idx
, bus_addr_t paddr
,
2300 struct bwi_ring_data
*rd
= &sc
->sc_rx_rdata
;
2302 KKASSERT(buf_idx
< BWI_RX_NDESC
);
2303 bwi_setup_desc32(sc
, rd
->rdata_desc
, BWI_RX_NDESC
, buf_idx
,
2308 bwi_setup_tx_desc32(struct bwi_softc
*sc
, struct bwi_ring_data
*rd
,
2309 int buf_idx
, bus_addr_t paddr
, int buf_len
)
2311 KKASSERT(buf_idx
< BWI_TX_NDESC
);
2312 bwi_setup_desc32(sc
, rd
->rdata_desc
, BWI_TX_NDESC
, buf_idx
,
2317 bwi_init_tx_ring64(struct bwi_softc
*sc
, int ring_idx
)
2324 bwi_init_rx_ring64(struct bwi_softc
*sc
)
2331 bwi_init_txstats64(struct bwi_softc
*sc
)
2338 bwi_setup_rx_desc64(struct bwi_softc
*sc
, int buf_idx
, bus_addr_t paddr
,
2345 bwi_setup_tx_desc64(struct bwi_softc
*sc
, struct bwi_ring_data
*rd
,
2346 int buf_idx
, bus_addr_t paddr
, int buf_len
)
2352 bwi_dma_buf_addr(void *arg
, bus_dma_segment_t
*seg
, int nseg
,
2353 bus_size_t mapsz __unused
, int error
)
2356 KASSERT(nseg
== 1, ("too many segments(%d)\n", nseg
));
2357 *((bus_addr_t
*)arg
) = seg
->ds_addr
;
2362 bwi_newbuf(struct bwi_softc
*sc
, int buf_idx
, int init
)
2364 struct bwi_rxbuf_data
*rbd
= &sc
->sc_rx_bdata
;
2365 struct bwi_rxbuf
*rxbuf
= &rbd
->rbd_buf
[buf_idx
];
2366 struct bwi_rxbuf_hdr
*hdr
;
2372 KKASSERT(buf_idx
< BWI_RX_NDESC
);
2374 m
= m_getcl(init
? MB_WAIT
: MB_DONTWAIT
, MT_DATA
, M_PKTHDR
);
2379 * If the NIC is up and running, we need to:
2380 * - Clear RX buffer's header.
2381 * - Restore RX descriptor settings.
2388 m
->m_len
= m
->m_pkthdr
.len
= MCLBYTES
;
2391 * Try to load RX buf into temporary DMA map
2393 error
= bus_dmamap_load_mbuf(sc
->sc_buf_dtag
, rbd
->rbd_tmp_dmap
, m
,
2394 bwi_dma_buf_addr
, &paddr
,
2395 init
? BUS_DMA_WAITOK
: BUS_DMA_NOWAIT
);
2400 * See the comment above
2409 bus_dmamap_unload(sc
->sc_buf_dtag
, rxbuf
->rb_dmap
);
2411 rxbuf
->rb_paddr
= paddr
;
2414 * Swap RX buf's DMA map with the loaded temporary one
2416 map
= rxbuf
->rb_dmap
;
2417 rxbuf
->rb_dmap
= rbd
->rbd_tmp_dmap
;
2418 rbd
->rbd_tmp_dmap
= map
;
2422 * Clear RX buf header
2424 hdr
= mtod(rxbuf
->rb_mbuf
, struct bwi_rxbuf_hdr
*);
2425 bzero(hdr
, sizeof(*hdr
));
2426 bus_dmamap_sync(sc
->sc_buf_dtag
, rxbuf
->rb_dmap
, BUS_DMASYNC_PREWRITE
);
2429 * Setup RX buf descriptor
2431 sc
->sc_setup_rxdesc(sc
, buf_idx
, rxbuf
->rb_paddr
,
2432 rxbuf
->rb_mbuf
->m_len
- sizeof(*hdr
));
2437 bwi_set_addr_filter(struct bwi_softc
*sc
, uint16_t addr_ofs
,
2438 const uint8_t *addr
)
2442 CSR_WRITE_2(sc
, BWI_ADDR_FILTER_CTRL
,
2443 BWI_ADDR_FILTER_CTRL_SET
| addr_ofs
);
2445 for (i
= 0; i
< (IEEE80211_ADDR_LEN
/ 2); ++i
) {
2448 addr_val
= (uint16_t)addr
[i
* 2] |
2449 (((uint16_t)addr
[(i
* 2) + 1]) << 8);
2450 CSR_WRITE_2(sc
, BWI_ADDR_FILTER_DATA
, addr_val
);
2455 bwi_set_chan(struct bwi_softc
*sc
, struct ieee80211_channel
*c
)
2457 struct ieee80211com
*ic
= &sc
->sc_ic
;
2458 struct ifnet
*ifp
= &ic
->ic_if
;
2459 struct bwi_mac
*mac
;
2463 ASSERT_SERIALIZED(ifp
->if_serializer
);
2465 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
2466 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
2468 chan
= ieee80211_chan2ieee(ic
, c
);
2470 bwi_rf_set_chan(mac
, chan
, 0);
2473 * Setup radio tap channel freq and flags
2475 if (IEEE80211_IS_CHAN_G(c
))
2476 flags
= IEEE80211_CHAN_G
;
2478 flags
= IEEE80211_CHAN_B
;
2480 sc
->sc_tx_th
.wt_chan_freq
= sc
->sc_rx_th
.wr_chan_freq
=
2481 htole16(c
->ic_freq
);
2482 sc
->sc_tx_th
.wt_chan_flags
= sc
->sc_rx_th
.wr_chan_flags
=
2489 bwi_next_scan(void *xsc
)
2491 struct bwi_softc
*sc
= xsc
;
2492 struct ieee80211com
*ic
= &sc
->sc_ic
;
2493 struct ifnet
*ifp
= &ic
->ic_if
;
2495 lwkt_serialize_enter(ifp
->if_serializer
);
2497 if (ic
->ic_state
== IEEE80211_S_SCAN
)
2498 ieee80211_next_scan(ic
);
2500 lwkt_serialize_exit(ifp
->if_serializer
);
2504 bwi_rxeof(struct bwi_softc
*sc
, int end_idx
)
2506 struct bwi_ring_data
*rd
= &sc
->sc_rx_rdata
;
2507 struct bwi_rxbuf_data
*rbd
= &sc
->sc_rx_bdata
;
2508 struct ieee80211com
*ic
= &sc
->sc_ic
;
2509 struct ifnet
*ifp
= &ic
->ic_if
;
2513 while (idx
!= end_idx
) {
2514 struct bwi_rxbuf
*rb
= &rbd
->rbd_buf
[idx
];
2515 struct bwi_rxbuf_hdr
*hdr
;
2516 struct ieee80211_frame_min
*wh
;
2517 struct ieee80211_node
*ni
;
2519 const uint8_t *plcp
;
2521 int buflen
, wh_ofs
, hdr_extra
, rssi
;
2524 bus_dmamap_sync(sc
->sc_buf_dtag
, rb
->rb_dmap
,
2525 BUS_DMASYNC_POSTREAD
);
2527 if (bwi_newbuf(sc
, idx
, 0)) {
2532 hdr
= mtod(m
, struct bwi_rxbuf_hdr
*);
2533 flags2
= le16toh(hdr
->rxh_flags2
);
2536 if (flags2
& BWI_RXH_F2_TYPE2FRAME
)
2538 wh_ofs
= hdr_extra
+ 6; /* XXX magic number */
2540 buflen
= le16toh(hdr
->rxh_buflen
);
2541 if (buflen
< BWI_FRAME_MIN_LEN(wh_ofs
)) {
2542 if_printf(ifp
, "short frame %d, hdr_extra %d\n",
2549 plcp
= ((const uint8_t *)(hdr
+ 1) + hdr_extra
);
2550 rssi
= bwi_calc_rssi(sc
, hdr
);
2552 m
->m_pkthdr
.rcvif
= ifp
;
2553 m
->m_len
= m
->m_pkthdr
.len
= buflen
+ sizeof(*hdr
);
2554 m_adj(m
, sizeof(*hdr
) + wh_ofs
);
2557 if (sc
->sc_drvbpf
!= NULL
)
2558 bwi_rx_radiotap(sc
, m
, hdr
, plcp
, rssi
);
2560 m_adj(m
, -IEEE80211_CRC_LEN
);
2562 wh
= mtod(m
, struct ieee80211_frame_min
*);
2563 ni
= ieee80211_find_rxnode(ic
, wh
);
2565 ieee80211_input(ic
, m
, ni
, rssi
- BWI_NOISE_FLOOR
,
2566 le16toh(hdr
->rxh_tsf
));
2567 ieee80211_free_node(ni
);
2569 idx
= (idx
+ 1) % BWI_RX_NDESC
;
2573 bus_dmamap_sync(sc
->sc_rxring_dtag
, rd
->rdata_dmap
,
2574 BUS_DMASYNC_PREWRITE
);
2578 bwi_rxeof32(struct bwi_softc
*sc
)
2580 uint32_t val
, rx_ctrl
;
2583 rx_ctrl
= sc
->sc_rx_rdata
.rdata_txrx_ctrl
;
2585 val
= CSR_READ_4(sc
, rx_ctrl
+ BWI_RX32_STATUS
);
2586 end_idx
= __SHIFTOUT(val
, BWI_RX32_STATUS_INDEX_MASK
) /
2587 sizeof(struct bwi_desc32
);
2589 bwi_rxeof(sc
, end_idx
);
2591 CSR_WRITE_4(sc
, rx_ctrl
+ BWI_RX32_INDEX
,
2592 end_idx
* sizeof(struct bwi_desc32
));
2596 bwi_rxeof64(struct bwi_softc
*sc
)
2602 bwi_reset_rx_ring32(struct bwi_softc
*sc
, uint32_t rx_ctrl
)
2606 CSR_WRITE_4(sc
, rx_ctrl
+ BWI_RX32_CTRL
, 0);
2610 for (i
= 0; i
< NRETRY
; ++i
) {
2613 status
= CSR_READ_4(sc
, rx_ctrl
+ BWI_RX32_STATUS
);
2614 if (__SHIFTOUT(status
, BWI_RX32_STATUS_STATE_MASK
) ==
2615 BWI_RX32_STATUS_STATE_DISABLED
)
2621 if_printf(&sc
->sc_ic
.ic_if
, "reset rx ring timedout\n");
2625 CSR_WRITE_4(sc
, rx_ctrl
+ BWI_RX32_RINGINFO
, 0);
2629 bwi_free_txstats32(struct bwi_softc
*sc
)
2631 bwi_reset_rx_ring32(sc
, sc
->sc_txstats
->stats_ctrl_base
);
2635 bwi_free_rx_ring32(struct bwi_softc
*sc
)
2637 struct bwi_ring_data
*rd
= &sc
->sc_rx_rdata
;
2638 struct bwi_rxbuf_data
*rbd
= &sc
->sc_rx_bdata
;
2641 bwi_reset_rx_ring32(sc
, rd
->rdata_txrx_ctrl
);
2643 for (i
= 0; i
< BWI_RX_NDESC
; ++i
) {
2644 struct bwi_rxbuf
*rb
= &rbd
->rbd_buf
[i
];
2646 if (rb
->rb_mbuf
!= NULL
) {
2647 bus_dmamap_unload(sc
->sc_buf_dtag
, rb
->rb_dmap
);
2648 m_freem(rb
->rb_mbuf
);
2655 bwi_free_tx_ring32(struct bwi_softc
*sc
, int ring_idx
)
2657 struct bwi_ring_data
*rd
;
2658 struct bwi_txbuf_data
*tbd
;
2659 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
2660 uint32_t state
, val
;
2663 KKASSERT(ring_idx
< BWI_TX_NRING
);
2664 rd
= &sc
->sc_tx_rdata
[ring_idx
];
2665 tbd
= &sc
->sc_tx_bdata
[ring_idx
];
2669 for (i
= 0; i
< NRETRY
; ++i
) {
2670 val
= CSR_READ_4(sc
, rd
->rdata_txrx_ctrl
+ BWI_TX32_STATUS
);
2671 state
= __SHIFTOUT(val
, BWI_TX32_STATUS_STATE_MASK
);
2672 if (state
== BWI_TX32_STATUS_STATE_DISABLED
||
2673 state
== BWI_TX32_STATUS_STATE_IDLE
||
2674 state
== BWI_TX32_STATUS_STATE_STOPPED
)
2680 if_printf(ifp
, "wait for TX ring(%d) stable timed out\n",
2684 CSR_WRITE_4(sc
, rd
->rdata_txrx_ctrl
+ BWI_TX32_CTRL
, 0);
2685 for (i
= 0; i
< NRETRY
; ++i
) {
2686 val
= CSR_READ_4(sc
, rd
->rdata_txrx_ctrl
+ BWI_TX32_STATUS
);
2687 state
= __SHIFTOUT(val
, BWI_TX32_STATUS_STATE_MASK
);
2688 if (state
== BWI_TX32_STATUS_STATE_DISABLED
)
2694 if_printf(ifp
, "reset TX ring (%d) timed out\n", ring_idx
);
2700 CSR_WRITE_4(sc
, rd
->rdata_txrx_ctrl
+ BWI_TX32_RINGINFO
, 0);
2702 for (i
= 0; i
< BWI_TX_NDESC
; ++i
) {
2703 struct bwi_txbuf
*tb
= &tbd
->tbd_buf
[i
];
2705 if (tb
->tb_mbuf
!= NULL
) {
2706 bus_dmamap_unload(sc
->sc_buf_dtag
, tb
->tb_dmap
);
2707 m_freem(tb
->tb_mbuf
);
2710 if (tb
->tb_ni
!= NULL
) {
2711 ieee80211_free_node(tb
->tb_ni
);
2718 bwi_free_txstats64(struct bwi_softc
*sc
)
2724 bwi_free_rx_ring64(struct bwi_softc
*sc
)
2730 bwi_free_tx_ring64(struct bwi_softc
*sc
, int ring_idx
)
2735 /* XXX does not belong here */
2737 bwi_rate2plcp(uint8_t rate
)
2739 rate
&= IEEE80211_RATE_VAL
;
2743 case 4: return 0x14;
2744 case 11: return 0x37;
2745 case 22: return 0x6e;
2746 case 44: return 0xdc;
2748 case 12: return 0xb;
2749 case 18: return 0xf;
2750 case 24: return 0xa;
2751 case 36: return 0xe;
2752 case 48: return 0x9;
2753 case 72: return 0xd;
2754 case 96: return 0x8;
2755 case 108: return 0xc;
2758 panic("unsupported rate %u\n", rate
);
2762 /* XXX does not belong here */
2763 #define IEEE80211_OFDM_PLCP_RATE_MASK __BITS(3, 0)
2764 #define IEEE80211_OFDM_PLCP_LEN_MASK __BITS(16, 5)
2766 static __inline
void
2767 bwi_ofdm_plcp_header(uint32_t *plcp0
, int pkt_len
, uint8_t rate
)
2771 plcp
= __SHIFTIN(bwi_rate2plcp(rate
), IEEE80211_OFDM_PLCP_RATE_MASK
) |
2772 __SHIFTIN(pkt_len
, IEEE80211_OFDM_PLCP_LEN_MASK
);
2773 *plcp0
= htole32(plcp
);
2776 /* XXX does not belong here */
2777 struct ieee80211_ds_plcp_hdr
{
2784 #define IEEE80211_DS_PLCP_SERVICE_LOCKED 0x04
2785 #define IEEE80211_DS_PLCL_SERVICE_PBCC 0x08
2786 #define IEEE80211_DS_PLCP_SERVICE_LENEXT5 0x20
2787 #define IEEE80211_DS_PLCP_SERVICE_LENEXT6 0x40
2788 #define IEEE80211_DS_PLCP_SERVICE_LENEXT7 0x80
2790 static __inline
void
2791 bwi_ds_plcp_header(struct ieee80211_ds_plcp_hdr
*plcp
, int pkt_len
,
2794 int len
, service
, pkt_bitlen
;
2796 pkt_bitlen
= pkt_len
* NBBY
;
2797 len
= howmany(pkt_bitlen
* 2, rate
);
2799 service
= IEEE80211_DS_PLCP_SERVICE_LOCKED
;
2800 if (rate
== (11 * 2)) {
2804 * PLCP service field needs to be adjusted,
2805 * if TX rate is 11Mbytes/s
2807 pkt_bitlen1
= len
* 11;
2808 if (pkt_bitlen1
- pkt_bitlen
>= NBBY
)
2809 service
|= IEEE80211_DS_PLCP_SERVICE_LENEXT7
;
2812 plcp
->i_signal
= bwi_rate2plcp(rate
);
2813 plcp
->i_service
= service
;
2814 plcp
->i_length
= htole16(len
);
2815 /* NOTE: do NOT touch i_crc */
2818 static __inline
void
2819 bwi_plcp_header(void *plcp
, int pkt_len
, uint8_t rate
)
2821 enum ieee80211_modtype modtype
;
2824 * Assume caller has zeroed 'plcp'
2827 modtype
= ieee80211_rate2modtype(rate
);
2828 if (modtype
== IEEE80211_MODTYPE_OFDM
)
2829 bwi_ofdm_plcp_header(plcp
, pkt_len
, rate
);
2830 else if (modtype
== IEEE80211_MODTYPE_DS
)
2831 bwi_ds_plcp_header(plcp
, pkt_len
, rate
);
2833 panic("unsupport modulation type %u\n", modtype
);
2837 bwi_encap(struct bwi_softc
*sc
, int idx
, struct mbuf
*m
,
2838 struct ieee80211_node
**ni0
, int mgt_pkt
)
2840 struct ieee80211com
*ic
= &sc
->sc_ic
;
2841 struct ieee80211_node
*ni
= *ni0
;
2842 struct bwi_ring_data
*rd
= &sc
->sc_tx_rdata
[BWI_TX_DATA_RING
];
2843 struct bwi_txbuf_data
*tbd
= &sc
->sc_tx_bdata
[BWI_TX_DATA_RING
];
2844 struct bwi_txbuf
*tb
= &tbd
->tbd_buf
[idx
];
2845 struct bwi_mac
*mac
;
2846 struct bwi_txbuf_hdr
*hdr
;
2847 struct ieee80211_frame
*wh
;
2848 uint8_t rate
, rate_fb
;
2852 int pkt_len
, error
, mcast_pkt
= 0;
2858 KKASSERT(ni
!= NULL
);
2859 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
2860 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
2862 wh
= mtod(m
, struct ieee80211_frame
*);
2864 /* Get 802.11 frame len before prepending TX header */
2865 pkt_len
= m
->m_pkthdr
.len
+ IEEE80211_CRC_LEN
;
2870 bzero(tb
->tb_rate_idx
, sizeof(tb
->tb_rate_idx
));
2872 if (ic
->ic_fixed_rate
!= IEEE80211_FIXED_RATE_NONE
) {
2875 rate
= IEEE80211_RS_RATE(&ni
->ni_rates
,
2878 if (ic
->ic_fixed_rate
>= 1)
2879 idx
= ic
->ic_fixed_rate
- 1;
2882 rate_fb
= IEEE80211_RS_RATE(&ni
->ni_rates
, idx
);
2884 /* TODO: TX rate control */
2885 rate
= rate_fb
= (1 * 2);
2888 /* Fixed at 1Mbits/s for mgt frames */
2889 rate
= rate_fb
= (1 * 2);
2892 if (IEEE80211_IS_MULTICAST(wh
->i_addr1
)) {
2893 rate
= rate_fb
= ic
->ic_mcast_rate
;
2897 if (rate
== 0 || rate_fb
== 0) {
2898 /* XXX this should not happen */
2899 if_printf(&ic
->ic_if
, "invalid rate %u or fallback rate %u",
2901 rate
= rate_fb
= (1 * 2); /* Force 1Mbits/s */
2907 if (sc
->sc_drvbpf
!= NULL
) {
2908 sc
->sc_tx_th
.wt_flags
= 0;
2909 if (wh
->i_fc
[1] & IEEE80211_FC1_WEP
)
2910 sc
->sc_tx_th
.wt_flags
|= IEEE80211_RADIOTAP_F_WEP
;
2911 if (ieee80211_rate2modtype(rate
) == IEEE80211_MODTYPE_DS
&&
2912 (ic
->ic_flags
& IEEE80211_F_SHPREAMBLE
) &&
2914 sc
->sc_tx_th
.wt_flags
|= IEEE80211_RADIOTAP_F_SHORTPRE
;
2916 sc
->sc_tx_th
.wt_rate
= rate
;
2918 bpf_ptap(sc
->sc_drvbpf
, m
, &sc
->sc_tx_th
, sc
->sc_tx_th_len
);
2922 * Setup the embedded TX header
2924 M_PREPEND(m
, sizeof(*hdr
), MB_DONTWAIT
);
2926 if_printf(&ic
->ic_if
, "prepend TX header failed\n");
2929 hdr
= mtod(m
, struct bwi_txbuf_hdr
*);
2931 bzero(hdr
, sizeof(*hdr
));
2933 bcopy(wh
->i_fc
, hdr
->txh_fc
, sizeof(hdr
->txh_fc
));
2934 bcopy(wh
->i_addr1
, hdr
->txh_addr1
, sizeof(hdr
->txh_addr1
));
2940 ack_rate
= ieee80211_ack_rate(ni
, rate_fb
);
2941 dur
= ieee80211_txtime(ni
,
2942 sizeof(struct ieee80211_frame_ack
) + IEEE80211_CRC_LEN
,
2943 ack_rate
, ic
->ic_flags
& ~IEEE80211_F_SHPREAMBLE
);
2945 hdr
->txh_fb_duration
= htole16(dur
);
2948 hdr
->txh_id
= __SHIFTIN(BWI_TX_DATA_RING
, BWI_TXH_ID_RING_MASK
) |
2949 __SHIFTIN(idx
, BWI_TXH_ID_IDX_MASK
);
2951 bwi_plcp_header(hdr
->txh_plcp
, pkt_len
, rate
);
2952 bwi_plcp_header(hdr
->txh_fb_plcp
, pkt_len
, rate_fb
);
2954 phy_ctrl
= __SHIFTIN(mac
->mac_rf
.rf_ant_mode
,
2955 BWI_TXH_PHY_C_ANTMODE_MASK
);
2956 if (ieee80211_rate2modtype(rate
) == IEEE80211_MODTYPE_OFDM
)
2957 phy_ctrl
|= BWI_TXH_PHY_C_OFDM
;
2958 else if ((ic
->ic_flags
& IEEE80211_F_SHPREAMBLE
) && rate
!= (2 * 1))
2959 phy_ctrl
|= BWI_TXH_PHY_C_SHPREAMBLE
;
2961 mac_ctrl
= BWI_TXH_MAC_C_HWSEQ
| BWI_TXH_MAC_C_FIRST_FRAG
;
2962 if (!IEEE80211_IS_MULTICAST(wh
->i_addr1
))
2963 mac_ctrl
|= BWI_TXH_MAC_C_ACK
;
2964 if (ieee80211_rate2modtype(rate_fb
) == IEEE80211_MODTYPE_OFDM
)
2965 mac_ctrl
|= BWI_TXH_MAC_C_FB_OFDM
;
2967 hdr
->txh_mac_ctrl
= htole32(mac_ctrl
);
2968 hdr
->txh_phy_ctrl
= htole16(phy_ctrl
);
2970 /* Catch any further usage */
2975 error
= bus_dmamap_load_mbuf(sc
->sc_buf_dtag
, tb
->tb_dmap
, m
,
2976 bwi_dma_buf_addr
, &paddr
, BUS_DMA_NOWAIT
);
2977 if (error
&& error
!= EFBIG
) {
2978 if_printf(&ic
->ic_if
, "can't load TX buffer (1) %d\n", error
);
2982 if (error
) { /* error == EFBIG */
2985 m_new
= m_defrag(m
, MB_DONTWAIT
);
2986 if (m_new
== NULL
) {
2987 if_printf(&ic
->ic_if
, "can't defrag TX buffer\n");
2994 error
= bus_dmamap_load_mbuf(sc
->sc_buf_dtag
, tb
->tb_dmap
, m
,
2995 bwi_dma_buf_addr
, &paddr
,
2998 if_printf(&ic
->ic_if
, "can't load TX buffer (2) %d\n",
3005 bus_dmamap_sync(sc
->sc_buf_dtag
, tb
->tb_dmap
, BUS_DMASYNC_PREWRITE
);
3007 if (mgt_pkt
|| mcast_pkt
) {
3008 /* Don't involve mcast/mgt packets into TX rate control */
3009 ieee80211_free_node(ni
);
3016 p
= mtod(m
, const uint8_t *);
3017 for (i
= 0; i
< m
->m_pkthdr
.len
; ++i
) {
3018 if (i
!= 0 && i
% 8 == 0)
3020 kprintf("%02x ", p
[i
]);
3025 DPRINTF(sc
, BWI_DBG_TX
, "idx %d, pkt_len %d, buflen %d\n",
3026 idx
, pkt_len
, m
->m_pkthdr
.len
);
3028 /* Setup TX descriptor */
3029 sc
->sc_setup_txdesc(sc
, rd
, idx
, paddr
, m
->m_pkthdr
.len
);
3030 bus_dmamap_sync(sc
->sc_txring_dtag
, rd
->rdata_dmap
,
3031 BUS_DMASYNC_PREWRITE
);
3034 sc
->sc_start_tx(sc
, rd
->rdata_txrx_ctrl
, idx
);
3043 bwi_start_tx32(struct bwi_softc
*sc
, uint32_t tx_ctrl
, int idx
)
3045 idx
= (idx
+ 1) % BWI_TX_NDESC
;
3046 CSR_WRITE_4(sc
, tx_ctrl
+ BWI_TX32_INDEX
,
3047 idx
* sizeof(struct bwi_desc32
));
3051 bwi_start_tx64(struct bwi_softc
*sc
, uint32_t tx_ctrl
, int idx
)
3057 bwi_txeof_status32(struct bwi_softc
*sc
)
3059 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
3060 uint32_t val
, ctrl_base
;
3063 ctrl_base
= sc
->sc_txstats
->stats_ctrl_base
;
3065 val
= CSR_READ_4(sc
, ctrl_base
+ BWI_RX32_STATUS
);
3066 end_idx
= __SHIFTOUT(val
, BWI_RX32_STATUS_INDEX_MASK
) /
3067 sizeof(struct bwi_desc32
);
3069 bwi_txeof_status(sc
, end_idx
);
3071 CSR_WRITE_4(sc
, ctrl_base
+ BWI_RX32_INDEX
,
3072 end_idx
* sizeof(struct bwi_desc32
));
3074 if ((ifp
->if_flags
& IFF_OACTIVE
) == 0)
3079 bwi_txeof_status64(struct bwi_softc
*sc
)
3085 _bwi_txeof(struct bwi_softc
*sc
, uint16_t tx_id
, int acked
, int data_txcnt
)
3087 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
3088 struct bwi_txbuf_data
*tbd
;
3089 struct bwi_txbuf
*tb
;
3090 int ring_idx
, buf_idx
;
3093 if_printf(ifp
, "zero tx id\n");
3097 ring_idx
= __SHIFTOUT(tx_id
, BWI_TXH_ID_RING_MASK
);
3098 buf_idx
= __SHIFTOUT(tx_id
, BWI_TXH_ID_IDX_MASK
);
3100 KKASSERT(ring_idx
== BWI_TX_DATA_RING
);
3101 KKASSERT(buf_idx
< BWI_TX_NDESC
);
3103 tbd
= &sc
->sc_tx_bdata
[ring_idx
];
3104 KKASSERT(tbd
->tbd_used
> 0);
3107 tb
= &tbd
->tbd_buf
[buf_idx
];
3109 DPRINTF(sc
, BWI_DBG_TXEOF
, "txeof idx %d, "
3110 "acked %d, data_txcnt %d, ni %p\n",
3111 buf_idx
, acked
, data_txcnt
, tb
->tb_ni
);
3113 bus_dmamap_unload(sc
->sc_buf_dtag
, tb
->tb_dmap
);
3114 m_freem(tb
->tb_mbuf
);
3117 if (tb
->tb_ni
!= NULL
) {
3118 /* Feed back 'acked and data_txcnt' */
3119 ieee80211_free_node(tb
->tb_ni
);
3123 if (tbd
->tbd_used
== 0)
3124 sc
->sc_tx_timer
= 0;
3126 ifp
->if_flags
&= ~IFF_OACTIVE
;
3130 bwi_txeof_status(struct bwi_softc
*sc
, int end_idx
)
3132 struct bwi_txstats_data
*st
= sc
->sc_txstats
;
3135 bus_dmamap_sync(st
->stats_dtag
, st
->stats_dmap
, BUS_DMASYNC_POSTREAD
);
3137 idx
= st
->stats_idx
;
3138 while (idx
!= end_idx
) {
3139 const struct bwi_txstats
*stats
= &st
->stats
[idx
];
3141 if ((stats
->txs_flags
& BWI_TXS_F_PENDING
) == 0) {
3144 data_txcnt
= __SHIFTOUT(stats
->txs_txcnt
,
3145 BWI_TXS_TXCNT_DATA
);
3146 _bwi_txeof(sc
, le16toh(stats
->txs_id
),
3147 stats
->txs_flags
& BWI_TXS_F_ACKED
,
3150 idx
= (idx
+ 1) % BWI_TXSTATS_NDESC
;
3152 st
->stats_idx
= idx
;
3156 bwi_txeof(struct bwi_softc
*sc
)
3158 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
3161 uint32_t tx_status0
, tx_status1
;
3165 tx_status0
= CSR_READ_4(sc
, BWI_TXSTATUS0
);
3166 if ((tx_status0
& BWI_TXSTATUS0_VALID
) == 0)
3168 tx_status1
= CSR_READ_4(sc
, BWI_TXSTATUS1
);
3170 tx_id
= __SHIFTOUT(tx_status0
, BWI_TXSTATUS0_TXID_MASK
);
3171 data_txcnt
= __SHIFTOUT(tx_status0
,
3172 BWI_TXSTATUS0_DATA_TXCNT_MASK
);
3174 if (tx_status0
& (BWI_TXSTATUS0_AMPDU
| BWI_TXSTATUS0_PENDING
))
3177 _bwi_txeof(sc
, tx_id
, tx_status0
& BWI_TXSTATUS0_ACKED
,
3181 if ((ifp
->if_flags
& IFF_OACTIVE
) == 0)
3186 bwi_bbp_power_on(struct bwi_softc
*sc
, enum bwi_clock_mode clk_mode
)
3188 bwi_power_on(sc
, 1);
3189 return bwi_set_clock_mode(sc
, clk_mode
);
3193 bwi_bbp_power_off(struct bwi_softc
*sc
)
3195 bwi_set_clock_mode(sc
, BWI_CLOCK_MODE_SLOW
);
3196 bwi_power_off(sc
, 1);
3200 bwi_get_pwron_delay(struct bwi_softc
*sc
)
3202 struct bwi_regwin
*com
, *old
;
3203 struct bwi_clock_freq freq
;
3207 com
= &sc
->sc_com_regwin
;
3208 KKASSERT(BWI_REGWIN_EXIST(com
));
3210 if ((sc
->sc_cap
& BWI_CAP_CLKMODE
) == 0)
3213 error
= bwi_regwin_switch(sc
, com
, &old
);
3217 bwi_get_clock_freq(sc
, &freq
);
3219 val
= CSR_READ_4(sc
, BWI_PLL_ON_DELAY
);
3220 sc
->sc_pwron_delay
= howmany((val
+ 2) * 1000000, freq
.clkfreq_min
);
3221 DPRINTF(sc
, BWI_DBG_ATTACH
, "power on delay %u\n", sc
->sc_pwron_delay
);
3223 return bwi_regwin_switch(sc
, old
, NULL
);
3227 bwi_bus_attach(struct bwi_softc
*sc
)
3229 struct bwi_regwin
*bus
, *old
;
3232 bus
= &sc
->sc_bus_regwin
;
3234 error
= bwi_regwin_switch(sc
, bus
, &old
);
3238 if (!bwi_regwin_is_enabled(sc
, bus
))
3239 bwi_regwin_enable(sc
, bus
, 0);
3241 /* Disable interripts */
3242 CSR_WRITE_4(sc
, BWI_INTRVEC
, 0);
3244 return bwi_regwin_switch(sc
, old
, NULL
);
3248 bwi_regwin_name(const struct bwi_regwin
*rw
)
3250 switch (rw
->rw_type
) {
3251 case BWI_REGWIN_T_COM
:
3253 case BWI_REGWIN_T_BUSPCI
:
3255 case BWI_REGWIN_T_MAC
:
3257 case BWI_REGWIN_T_BUSPCIE
:
3260 panic("unknown regwin type 0x%04x\n", rw
->rw_type
);
3265 bwi_regwin_disable_bits(struct bwi_softc
*sc
)
3269 /* XXX cache this */
3270 busrev
= __SHIFTOUT(CSR_READ_4(sc
, BWI_ID_LO
), BWI_ID_LO_BUSREV_MASK
);
3271 DPRINTF(sc
, BWI_DBG_ATTACH
| BWI_DBG_INIT
| BWI_DBG_MISC
,
3272 "bus rev %u\n", busrev
);
3274 if (busrev
== BWI_BUSREV_0
)
3275 return BWI_STATE_LO_DISABLE1
;
3276 else if (busrev
== BWI_BUSREV_1
)
3277 return BWI_STATE_LO_DISABLE2
;
3279 return (BWI_STATE_LO_DISABLE1
| BWI_STATE_LO_DISABLE2
);
3283 bwi_regwin_is_enabled(struct bwi_softc
*sc
, struct bwi_regwin
*rw
)
3285 uint32_t val
, disable_bits
;
3287 disable_bits
= bwi_regwin_disable_bits(sc
);
3288 val
= CSR_READ_4(sc
, BWI_STATE_LO
);
3290 if ((val
& (BWI_STATE_LO_CLOCK
|
3291 BWI_STATE_LO_RESET
|
3292 disable_bits
)) == BWI_STATE_LO_CLOCK
) {
3293 DPRINTF(sc
, BWI_DBG_ATTACH
| BWI_DBG_INIT
, "%s is enabled\n",
3294 bwi_regwin_name(rw
));
3297 DPRINTF(sc
, BWI_DBG_ATTACH
| BWI_DBG_INIT
, "%s is disabled\n",
3298 bwi_regwin_name(rw
));
3304 bwi_regwin_disable(struct bwi_softc
*sc
, struct bwi_regwin
*rw
, uint32_t flags
)
3306 uint32_t state_lo
, disable_bits
;
3309 state_lo
= CSR_READ_4(sc
, BWI_STATE_LO
);
3312 * If current regwin is in 'reset' state, it was already disabled.
3314 if (state_lo
& BWI_STATE_LO_RESET
) {
3315 DPRINTF(sc
, BWI_DBG_ATTACH
| BWI_DBG_INIT
,
3316 "%s was already disabled\n", bwi_regwin_name(rw
));
3320 disable_bits
= bwi_regwin_disable_bits(sc
);
3323 * Disable normal clock
3325 state_lo
= BWI_STATE_LO_CLOCK
| disable_bits
;
3326 CSR_WRITE_4(sc
, BWI_STATE_LO
, state_lo
);
3329 * Wait until normal clock is disabled
3332 for (i
= 0; i
< NRETRY
; ++i
) {
3333 state_lo
= CSR_READ_4(sc
, BWI_STATE_LO
);
3334 if (state_lo
& disable_bits
)
3339 device_printf(sc
->sc_dev
, "%s disable clock timeout\n",
3340 bwi_regwin_name(rw
));
3343 for (i
= 0; i
< NRETRY
; ++i
) {
3346 state_hi
= CSR_READ_4(sc
, BWI_STATE_HI
);
3347 if ((state_hi
& BWI_STATE_HI_BUSY
) == 0)
3352 device_printf(sc
->sc_dev
, "%s wait BUSY unset timeout\n",
3353 bwi_regwin_name(rw
));
3358 * Reset and disable regwin with gated clock
3360 state_lo
= BWI_STATE_LO_RESET
| disable_bits
|
3361 BWI_STATE_LO_CLOCK
| BWI_STATE_LO_GATED_CLOCK
|
3362 __SHIFTIN(flags
, BWI_STATE_LO_FLAGS_MASK
);
3363 CSR_WRITE_4(sc
, BWI_STATE_LO
, state_lo
);
3365 /* Flush pending bus write */
3366 CSR_READ_4(sc
, BWI_STATE_LO
);
3369 /* Reset and disable regwin */
3370 state_lo
= BWI_STATE_LO_RESET
| disable_bits
|
3371 __SHIFTIN(flags
, BWI_STATE_LO_FLAGS_MASK
);
3372 CSR_WRITE_4(sc
, BWI_STATE_LO
, state_lo
);
3374 /* Flush pending bus write */
3375 CSR_READ_4(sc
, BWI_STATE_LO
);
3380 bwi_regwin_enable(struct bwi_softc
*sc
, struct bwi_regwin
*rw
, uint32_t flags
)
3382 uint32_t state_lo
, state_hi
, imstate
;
3384 bwi_regwin_disable(sc
, rw
, flags
);
3386 /* Reset regwin with gated clock */
3387 state_lo
= BWI_STATE_LO_RESET
|
3388 BWI_STATE_LO_CLOCK
|
3389 BWI_STATE_LO_GATED_CLOCK
|
3390 __SHIFTIN(flags
, BWI_STATE_LO_FLAGS_MASK
);
3391 CSR_WRITE_4(sc
, BWI_STATE_LO
, state_lo
);
3393 /* Flush pending bus write */
3394 CSR_READ_4(sc
, BWI_STATE_LO
);
3397 state_hi
= CSR_READ_4(sc
, BWI_STATE_HI
);
3398 if (state_hi
& BWI_STATE_HI_SERROR
)
3399 CSR_WRITE_4(sc
, BWI_STATE_HI
, 0);
3401 imstate
= CSR_READ_4(sc
, BWI_IMSTATE
);
3402 if (imstate
& (BWI_IMSTATE_INBAND_ERR
| BWI_IMSTATE_TIMEOUT
)) {
3403 imstate
&= ~(BWI_IMSTATE_INBAND_ERR
| BWI_IMSTATE_TIMEOUT
);
3404 CSR_WRITE_4(sc
, BWI_IMSTATE
, imstate
);
3407 /* Enable regwin with gated clock */
3408 state_lo
= BWI_STATE_LO_CLOCK
|
3409 BWI_STATE_LO_GATED_CLOCK
|
3410 __SHIFTIN(flags
, BWI_STATE_LO_FLAGS_MASK
);
3411 CSR_WRITE_4(sc
, BWI_STATE_LO
, state_lo
);
3413 /* Flush pending bus write */
3414 CSR_READ_4(sc
, BWI_STATE_LO
);
3417 /* Enable regwin with normal clock */
3418 state_lo
= BWI_STATE_LO_CLOCK
|
3419 __SHIFTIN(flags
, BWI_STATE_LO_FLAGS_MASK
);
3420 CSR_WRITE_4(sc
, BWI_STATE_LO
, state_lo
);
3422 /* Flush pending bus write */
3423 CSR_READ_4(sc
, BWI_STATE_LO
);
3428 bwi_set_bssid(struct bwi_softc
*sc
, const uint8_t *bssid
)
3430 struct ieee80211com
*ic
= &sc
->sc_ic
;
3431 struct bwi_mac
*mac
;
3432 struct bwi_myaddr_bssid buf
;
3437 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
3438 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
3440 bwi_set_addr_filter(sc
, BWI_ADDR_FILTER_BSSID
, bssid
);
3442 bcopy(ic
->ic_myaddr
, buf
.myaddr
, sizeof(buf
.myaddr
));
3443 bcopy(bssid
, buf
.bssid
, sizeof(buf
.bssid
));
3445 n
= sizeof(buf
) / sizeof(val
);
3446 p
= (const uint8_t *)&buf
;
3447 for (i
= 0; i
< n
; ++i
) {
3451 for (j
= 0; j
< sizeof(val
); ++j
)
3452 val
|= ((uint32_t)(*p
++)) << (j
* 8);
3454 TMPLT_WRITE_4(mac
, 0x20 + (i
* sizeof(val
)), val
);
3459 bwi_updateslot(struct ifnet
*ifp
)
3461 struct bwi_softc
*sc
= ifp
->if_softc
;
3462 struct ieee80211com
*ic
= &sc
->sc_ic
;
3463 struct bwi_mac
*mac
;
3465 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
3468 ASSERT_SERIALIZED(ifp
->if_serializer
);
3470 DPRINTF(sc
, BWI_DBG_80211
, "%s\n", __func__
);
3472 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
3473 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
3475 bwi_mac_updateslot(mac
, (ic
->ic_flags
& IEEE80211_F_SHSLOT
));
3479 bwi_calibrate(void *xsc
)
3481 struct bwi_softc
*sc
= xsc
;
3482 struct ieee80211com
*ic
= &sc
->sc_ic
;
3483 struct ifnet
*ifp
= &ic
->ic_if
;
3485 lwkt_serialize_enter(ifp
->if_serializer
);
3487 if (ic
->ic_state
== IEEE80211_S_RUN
) {
3488 struct bwi_mac
*mac
;
3490 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
3491 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
3493 if (ic
->ic_opmode
!= IEEE80211_M_MONITOR
)
3494 bwi_mac_calibrate_txpower(mac
);
3496 /* XXX 15 seconds */
3497 callout_reset(&sc
->sc_calib_ch
, hz
* 15, bwi_calibrate
, sc
);
3500 lwkt_serialize_exit(ifp
->if_serializer
);
3504 bwi_calc_rssi(struct bwi_softc
*sc
, const struct bwi_rxbuf_hdr
*hdr
)
3506 struct bwi_mac
*mac
;
3508 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
3509 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
3511 return bwi_rf_calc_rssi(mac
, hdr
);
3514 static __inline
uint8_t
3515 bwi_ofdm_plcp2rate(const uint32_t *plcp0
)
3520 plcp
= le32toh(*plcp0
);
3521 plcp_rate
= __SHIFTOUT(plcp
, IEEE80211_OFDM_PLCP_RATE_MASK
);
3522 return ieee80211_plcp2rate(plcp_rate
, 1);
3525 static __inline
uint8_t
3526 bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr
*hdr
)
3528 return ieee80211_plcp2rate(hdr
->i_signal
, 0);
3532 bwi_rx_radiotap(struct bwi_softc
*sc
, struct mbuf
*m
,
3533 struct bwi_rxbuf_hdr
*hdr
, const void *plcp
, int rssi
)
3535 const struct ieee80211_frame_min
*wh
;
3539 KKASSERT(sc
->sc_drvbpf
!= NULL
);
3541 flags1
= htole16(hdr
->rxh_flags1
);
3542 if (flags1
& BWI_RXH_F1_OFDM
)
3543 rate
= bwi_ofdm_plcp2rate(plcp
);
3545 rate
= bwi_ds_plcp2rate(plcp
);
3547 sc
->sc_rx_th
.wr_flags
= IEEE80211_RADIOTAP_F_FCS
;
3548 if (flags1
& BWI_RXH_F1_SHPREAMBLE
)
3549 sc
->sc_rx_th
.wr_flags
|= IEEE80211_RADIOTAP_F_SHORTPRE
;
3551 wh
= mtod(m
, const struct ieee80211_frame_min
*);
3552 if (wh
->i_fc
[1] & IEEE80211_FC1_WEP
)
3553 sc
->sc_rx_th
.wr_flags
|= IEEE80211_RADIOTAP_F_WEP
;
3555 sc
->sc_rx_th
.wr_tsf
= hdr
->rxh_tsf
; /* No endian convertion */
3556 sc
->sc_rx_th
.wr_rate
= rate
;
3557 sc
->sc_rx_th
.wr_antsignal
= rssi
;
3558 sc
->sc_rx_th
.wr_antnoise
= BWI_NOISE_FLOOR
;
3560 bpf_ptap(sc
->sc_drvbpf
, m
, &sc
->sc_rx_th
, sc
->sc_rx_th_len
);