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.20 2008/02/15 11:48:15 sephe Exp $
37 #include <sys/param.h>
38 #include <sys/bitops.h>
39 #include <sys/endian.h>
40 #include <sys/kernel.h>
42 #include <sys/malloc.h>
45 #include <sys/serialize.h>
46 #include <sys/socket.h>
47 #include <sys/sockio.h>
48 #include <sys/sysctl.h>
50 #include <net/ethernet.h>
53 #include <net/if_arp.h>
54 #include <net/if_dl.h>
55 #include <net/if_media.h>
56 #include <net/ifq_var.h>
58 #include <netproto/802_11/ieee80211_radiotap.h>
59 #include <netproto/802_11/ieee80211_var.h>
60 #include <netproto/802_11/wlan_ratectl/onoe/ieee80211_onoe_param.h>
62 #include <bus/pci/pcireg.h>
63 #include <bus/pci/pcivar.h>
64 #include <bus/pci/pcidevs.h>
66 #include <dev/netif/bwi/if_bwireg.h>
67 #include <dev/netif/bwi/if_bwivar.h>
68 #include <dev/netif/bwi/bwimac.h>
69 #include <dev/netif/bwi/bwirf.h>
71 struct bwi_clock_freq
{
76 struct bwi_myaddr_bssid
{
77 uint8_t myaddr
[IEEE80211_ADDR_LEN
];
78 uint8_t bssid
[IEEE80211_ADDR_LEN
];
81 static int bwi_probe(device_t
);
82 static int bwi_attach(device_t
);
83 static int bwi_detach(device_t
);
84 static int bwi_shutdown(device_t
);
86 static void bwi_init(void *);
87 static int bwi_ioctl(struct ifnet
*, u_long
, caddr_t
, struct ucred
*);
88 static void bwi_start(struct ifnet
*);
89 static void bwi_watchdog(struct ifnet
*);
90 static int bwi_newstate(struct ieee80211com
*, enum ieee80211_state
, int);
91 static void bwi_updateslot(struct ifnet
*);
92 static int bwi_media_change(struct ifnet
*);
93 static void *bwi_ratectl_attach(struct ieee80211com
*, u_int
);
95 static void bwi_next_scan(void *);
96 static void bwi_calibrate(void *);
98 static void bwi_newstate_begin(struct bwi_softc
*, enum ieee80211_state
);
99 static void bwi_init_statechg(struct bwi_softc
*, int);
100 static int bwi_stop(struct bwi_softc
*, int);
101 static int bwi_newbuf(struct bwi_softc
*, int, int);
102 static int bwi_encap(struct bwi_softc
*, int, struct mbuf
*,
103 struct ieee80211_node
**, int);
105 static void bwi_init_rxdesc_ring32(struct bwi_softc
*, uint32_t,
106 bus_addr_t
, int, int);
107 static void bwi_reset_rx_ring32(struct bwi_softc
*, uint32_t);
109 static int bwi_init_tx_ring32(struct bwi_softc
*, int);
110 static int bwi_init_rx_ring32(struct bwi_softc
*);
111 static int bwi_init_txstats32(struct bwi_softc
*);
112 static void bwi_free_tx_ring32(struct bwi_softc
*, int);
113 static void bwi_free_rx_ring32(struct bwi_softc
*);
114 static void bwi_free_txstats32(struct bwi_softc
*);
115 static void bwi_setup_rx_desc32(struct bwi_softc
*, int, bus_addr_t
, int);
116 static void bwi_setup_tx_desc32(struct bwi_softc
*, struct bwi_ring_data
*,
117 int, bus_addr_t
, int);
118 static int bwi_rxeof32(struct bwi_softc
*);
119 static void bwi_start_tx32(struct bwi_softc
*, uint32_t, int);
120 static void bwi_txeof_status32(struct bwi_softc
*);
122 static int bwi_init_tx_ring64(struct bwi_softc
*, int);
123 static int bwi_init_rx_ring64(struct bwi_softc
*);
124 static int bwi_init_txstats64(struct bwi_softc
*);
125 static void bwi_free_tx_ring64(struct bwi_softc
*, int);
126 static void bwi_free_rx_ring64(struct bwi_softc
*);
127 static void bwi_free_txstats64(struct bwi_softc
*);
128 static void bwi_setup_rx_desc64(struct bwi_softc
*, int, bus_addr_t
, int);
129 static void bwi_setup_tx_desc64(struct bwi_softc
*, struct bwi_ring_data
*,
130 int, bus_addr_t
, int);
131 static int bwi_rxeof64(struct bwi_softc
*);
132 static void bwi_start_tx64(struct bwi_softc
*, uint32_t, int);
133 static void bwi_txeof_status64(struct bwi_softc
*);
135 static void bwi_intr(void *);
136 static int bwi_rxeof(struct bwi_softc
*, int);
137 static void _bwi_txeof(struct bwi_softc
*, uint16_t, int, int);
138 static void bwi_txeof(struct bwi_softc
*);
139 static void bwi_txeof_status(struct bwi_softc
*, int);
140 static void bwi_enable_intrs(struct bwi_softc
*, uint32_t);
141 static void bwi_disable_intrs(struct bwi_softc
*, uint32_t);
142 static int bwi_calc_rssi(struct bwi_softc
*, const struct bwi_rxbuf_hdr
*);
143 static void bwi_rx_radiotap(struct bwi_softc
*, struct mbuf
*,
144 struct bwi_rxbuf_hdr
*, const void *, int, int);
146 static int bwi_dma_alloc(struct bwi_softc
*);
147 static void bwi_dma_free(struct bwi_softc
*);
148 static int bwi_dma_ring_alloc(struct bwi_softc
*, bus_dma_tag_t
,
149 struct bwi_ring_data
*, bus_size_t
,
151 static int bwi_dma_mbuf_create(struct bwi_softc
*);
152 static void bwi_dma_mbuf_destroy(struct bwi_softc
*, int, int);
153 static int bwi_dma_txstats_alloc(struct bwi_softc
*, uint32_t, bus_size_t
);
154 static void bwi_dma_txstats_free(struct bwi_softc
*);
155 static void bwi_dma_ring_addr(void *, bus_dma_segment_t
*, int, int);
156 static void bwi_dma_buf_addr(void *, bus_dma_segment_t
*, int,
159 static void bwi_power_on(struct bwi_softc
*, int);
160 static int bwi_power_off(struct bwi_softc
*, int);
161 static int bwi_set_clock_mode(struct bwi_softc
*, enum bwi_clock_mode
);
162 static int bwi_set_clock_delay(struct bwi_softc
*);
163 static void bwi_get_clock_freq(struct bwi_softc
*, struct bwi_clock_freq
*);
164 static int bwi_get_pwron_delay(struct bwi_softc
*sc
);
165 static void bwi_set_addr_filter(struct bwi_softc
*, uint16_t,
167 static void bwi_set_bssid(struct bwi_softc
*, const uint8_t *);
168 static int bwi_set_chan(struct bwi_softc
*, struct ieee80211_channel
*);
170 static void bwi_get_card_flags(struct bwi_softc
*);
171 static void bwi_get_eaddr(struct bwi_softc
*, uint16_t, uint8_t *);
173 static int bwi_bus_attach(struct bwi_softc
*);
174 static int bwi_bbp_attach(struct bwi_softc
*);
175 static int bwi_bbp_power_on(struct bwi_softc
*, enum bwi_clock_mode
);
176 static void bwi_bbp_power_off(struct bwi_softc
*);
178 static const char *bwi_regwin_name(const struct bwi_regwin
*);
179 static uint32_t bwi_regwin_disable_bits(struct bwi_softc
*);
180 static void bwi_regwin_info(struct bwi_softc
*, uint16_t *, uint8_t *);
181 static int bwi_regwin_select(struct bwi_softc
*, int);
183 static void bwi_led_attach(struct bwi_softc
*);
184 static void bwi_led_newstate(struct bwi_softc
*, enum ieee80211_state
);
185 static void bwi_led_event(struct bwi_softc
*, int);
186 static void bwi_led_blink_start(struct bwi_softc
*, int, int);
187 static void bwi_led_blink_next(void *);
188 static void bwi_led_blink_end(void *);
190 static const struct bwi_dev
{
195 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM4301
,
196 "Broadcom BCM4301 802.11 Wireless Lan" },
198 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM4307
,
199 "Broadcom BCM4307 802.11 Wireless Lan" },
201 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM4311
,
202 "Broadcom BCM4311 802.11 Wireless Lan" },
204 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM4312
,
205 "Broadcom BCM4312 802.11 Wireless Lan" },
207 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM4306_1
,
208 "Broadcom BCM4306 802.11 Wireless Lan" },
210 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM4306_2
,
211 "Broadcom BCM4306 802.11 Wireless Lan" },
213 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM4306_3
,
214 "Broadcom BCM4306 802.11 Wireless Lan" },
216 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM4309
,
217 "Broadcom BCM4309 802.11 Wireless Lan" },
219 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM4318
,
220 "Broadcom BCM4318 802.11 Wireless Lan" },
222 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM4319
,
223 "Broadcom BCM4319 802.11 Wireless Lan" }
226 static device_method_t bwi_methods
[] = {
227 DEVMETHOD(device_probe
, bwi_probe
),
228 DEVMETHOD(device_attach
, bwi_attach
),
229 DEVMETHOD(device_detach
, bwi_detach
),
230 DEVMETHOD(device_shutdown
, bwi_shutdown
),
232 DEVMETHOD(device_suspend
, bwi_suspend
),
233 DEVMETHOD(device_resume
, bwi_resume
),
238 static driver_t bwi_driver
= {
241 sizeof(struct bwi_softc
)
244 static devclass_t bwi_devclass
;
246 DRIVER_MODULE(bwi
, pci
, bwi_driver
, bwi_devclass
, 0, 0);
247 DRIVER_MODULE(bwi
, cardbus
, bwi_driver
, bwi_devclass
, 0, 0);
249 MODULE_DEPEND(bwi
, wlan
, 1, 1, 1);
250 MODULE_DEPEND(bwi
, wlan_ratectl_onoe
, 1, 1, 1);
252 MODULE_DEPEND(bwi
, wlan_ratectl_amrr
, 1, 1, 1);
254 MODULE_DEPEND(bwi
, pci
, 1, 1, 1);
255 MODULE_DEPEND(bwi
, cardbus
, 1, 1, 1);
257 static const struct {
261 } bwi_bbpid_map
[] = {
262 { 0x4301, 0x4301, 0x4301 },
263 { 0x4305, 0x4307, 0x4307 },
264 { 0x4403, 0x4403, 0x4402 },
265 { 0x4610, 0x4615, 0x4610 },
266 { 0x4710, 0x4715, 0x4710 },
267 { 0x4720, 0x4725, 0x4309 }
270 static const struct {
273 } bwi_regwin_count
[] = {
286 #define CLKSRC(src) \
287 [BWI_CLKSRC_ ## src] = { \
288 .freq_min = BWI_CLKSRC_ ##src## _FMIN, \
289 .freq_max = BWI_CLKSRC_ ##src## _FMAX \
292 static const struct {
295 } bwi_clkfreq
[BWI_CLKSRC_MAX
] = {
303 #define VENDOR_LED_ACT(vendor) \
305 .vid = PCI_VENDOR_##vendor, \
306 .led_act = { BWI_VENDOR_LED_ACT_##vendor } \
309 static const struct {
311 uint8_t led_act
[BWI_LED_MAX
];
312 } bwi_vendor_led_act
[] = {
313 VENDOR_LED_ACT(COMPAQ
),
314 VENDOR_LED_ACT(LINKSYS
)
317 static const uint8_t bwi_default_led_act
[BWI_LED_MAX
] =
318 { BWI_VENDOR_LED_ACT_DEFAULT
};
320 #undef VENDOR_LED_ACT
322 static const struct {
325 } bwi_led_duration
[109] = {
342 #ifdef BWI_DEBUG_VERBOSE
343 static uint32_t bwi_debug
= BWI_DBG_ATTACH
| BWI_DBG_INIT
| BWI_DBG_TXPOWER
;
345 static uint32_t bwi_debug
;
347 TUNABLE_INT("hw.bwi.debug", (int *)&bwi_debug
);
348 #endif /* BWI_DEBUG */
350 static const uint8_t bwi_zero_addr
[IEEE80211_ADDR_LEN
];
352 static const struct ieee80211_rateset bwi_rateset_11b
=
353 { 4, { 2, 4, 11, 22 } };
354 static const struct ieee80211_rateset bwi_rateset_11g
=
355 { 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
358 bwi_read_sprom(struct bwi_softc
*sc
, uint16_t ofs
)
360 return CSR_READ_2(sc
, ofs
+ BWI_SPROM_START
);
364 bwi_setup_desc32(struct bwi_softc
*sc
, struct bwi_desc32
*desc_array
,
365 int ndesc
, int desc_idx
, bus_addr_t paddr
, int buf_len
,
368 struct bwi_desc32
*desc
= &desc_array
[desc_idx
];
369 uint32_t ctrl
, addr
, addr_hi
, addr_lo
;
371 addr_lo
= __SHIFTOUT(paddr
, BWI_DESC32_A_ADDR_MASK
);
372 addr_hi
= __SHIFTOUT(paddr
, BWI_DESC32_A_FUNC_MASK
);
374 addr
= __SHIFTIN(addr_lo
, BWI_DESC32_A_ADDR_MASK
) |
375 __SHIFTIN(BWI_DESC32_A_FUNC_TXRX
, BWI_DESC32_A_FUNC_MASK
);
377 ctrl
= __SHIFTIN(buf_len
, BWI_DESC32_C_BUFLEN_MASK
) |
378 __SHIFTIN(addr_hi
, BWI_DESC32_C_ADDRHI_MASK
);
379 if (desc_idx
== ndesc
- 1)
380 ctrl
|= BWI_DESC32_C_EOR
;
383 ctrl
|= BWI_DESC32_C_FRAME_START
|
384 BWI_DESC32_C_FRAME_END
|
388 desc
->addr
= htole32(addr
);
389 desc
->ctrl
= htole32(ctrl
);
392 /* XXX does not belong here */
394 bwi_rate2plcp(uint8_t rate
)
396 rate
&= IEEE80211_RATE_VAL
;
401 case 11: return 0x37;
402 case 22: return 0x6e;
403 case 44: return 0xdc;
412 case 108: return 0xc;
415 panic("unsupported rate %u\n", rate
);
419 /* XXX does not belong here */
420 #define IEEE80211_OFDM_PLCP_RATE_MASK __BITS(3, 0)
421 #define IEEE80211_OFDM_PLCP_LEN_MASK __BITS(16, 5)
424 bwi_ofdm_plcp_header(uint32_t *plcp0
, int pkt_len
, uint8_t rate
)
428 plcp
= __SHIFTIN(bwi_rate2plcp(rate
), IEEE80211_OFDM_PLCP_RATE_MASK
) |
429 __SHIFTIN(pkt_len
, IEEE80211_OFDM_PLCP_LEN_MASK
);
430 *plcp0
= htole32(plcp
);
433 /* XXX does not belong here */
434 struct ieee80211_ds_plcp_hdr
{
441 #define IEEE80211_DS_PLCP_SERVICE_LOCKED 0x04
442 #define IEEE80211_DS_PLCL_SERVICE_PBCC 0x08
443 #define IEEE80211_DS_PLCP_SERVICE_LENEXT5 0x20
444 #define IEEE80211_DS_PLCP_SERVICE_LENEXT6 0x40
445 #define IEEE80211_DS_PLCP_SERVICE_LENEXT7 0x80
448 bwi_ds_plcp_header(struct ieee80211_ds_plcp_hdr
*plcp
, int pkt_len
,
451 int len
, service
, pkt_bitlen
;
453 pkt_bitlen
= pkt_len
* NBBY
;
454 len
= howmany(pkt_bitlen
* 2, rate
);
456 service
= IEEE80211_DS_PLCP_SERVICE_LOCKED
;
457 if (rate
== (11 * 2)) {
461 * PLCP service field needs to be adjusted,
462 * if TX rate is 11Mbytes/s
464 pkt_bitlen1
= len
* 11;
465 if (pkt_bitlen1
- pkt_bitlen
>= NBBY
)
466 service
|= IEEE80211_DS_PLCP_SERVICE_LENEXT7
;
469 plcp
->i_signal
= bwi_rate2plcp(rate
);
470 plcp
->i_service
= service
;
471 plcp
->i_length
= htole16(len
);
472 /* NOTE: do NOT touch i_crc */
476 bwi_plcp_header(void *plcp
, int pkt_len
, uint8_t rate
)
478 enum ieee80211_modtype modtype
;
481 * Assume caller has zeroed 'plcp'
484 modtype
= ieee80211_rate2modtype(rate
);
485 if (modtype
== IEEE80211_MODTYPE_OFDM
)
486 bwi_ofdm_plcp_header(plcp
, pkt_len
, rate
);
487 else if (modtype
== IEEE80211_MODTYPE_DS
)
488 bwi_ds_plcp_header(plcp
, pkt_len
, rate
);
490 panic("unsupport modulation type %u\n", modtype
);
493 static __inline
uint8_t
494 bwi_ofdm_plcp2rate(const uint32_t *plcp0
)
499 plcp
= le32toh(*plcp0
);
500 plcp_rate
= __SHIFTOUT(plcp
, IEEE80211_OFDM_PLCP_RATE_MASK
);
501 return ieee80211_plcp2rate(plcp_rate
, 1);
504 static __inline
uint8_t
505 bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr
*hdr
)
507 return ieee80211_plcp2rate(hdr
->i_signal
, 0);
511 bwi_probe(device_t dev
)
513 const struct bwi_dev
*b
;
516 did
= pci_get_device(dev
);
517 vid
= pci_get_vendor(dev
);
519 for (b
= bwi_devices
; b
->desc
!= NULL
; ++b
) {
520 if (b
->did
== did
&& b
->vid
== vid
) {
521 device_set_desc(dev
, b
->desc
);
529 bwi_attach(device_t dev
)
531 struct bwi_softc
*sc
= device_get_softc(dev
);
532 struct ieee80211com
*ic
= &sc
->sc_ic
;
533 struct ifnet
*ifp
= &ic
->ic_if
;
538 if_initname(ifp
, device_get_name(dev
), device_get_unit(dev
));
542 * Initialize sysctl variables
544 sc
->sc_fw_version
= BWI_FW_VERSION3
;
545 sc
->sc_dwell_time
= 200;
546 sc
->sc_led_idle
= (2350 * hz
) / 1000;
547 sc
->sc_led_blink
= 1;
548 sc
->sc_txpwr_calib
= 1;
550 sc
->sc_debug
= bwi_debug
;
553 callout_init(&sc
->sc_scan_ch
);
554 callout_init(&sc
->sc_calib_ch
);
557 if (pci_get_powerstate(dev
) != PCI_POWERSTATE_D0
) {
560 /* XXX Save more PCIR */
561 irq
= pci_read_config(dev
, PCIR_INTLINE
, 4);
562 mem
= pci_read_config(dev
, BWI_PCIR_BAR
, 4);
564 device_printf(dev
, "chip is in D%d power mode "
565 "-- setting to D0\n", pci_get_powerstate(dev
));
567 pci_set_powerstate(dev
, PCI_POWERSTATE_D0
);
569 pci_write_config(dev
, PCIR_INTLINE
, irq
, 4);
570 pci_write_config(dev
, BWI_PCIR_BAR
, mem
, 4);
572 #endif /* !BURN_BRIDGE */
574 pci_enable_busmaster(dev
);
576 /* Get more PCI information */
577 sc
->sc_pci_revid
= pci_get_revid(dev
);
578 sc
->sc_pci_subvid
= pci_get_subvendor(dev
);
579 sc
->sc_pci_subdid
= pci_get_subdevice(dev
);
584 sc
->sc_mem_rid
= BWI_PCIR_BAR
;
585 sc
->sc_mem_res
= bus_alloc_resource_any(dev
, SYS_RES_MEMORY
,
586 &sc
->sc_mem_rid
, RF_ACTIVE
);
587 if (sc
->sc_mem_res
== NULL
) {
588 device_printf(dev
, "can't allocate IO memory\n");
591 sc
->sc_mem_bt
= rman_get_bustag(sc
->sc_mem_res
);
592 sc
->sc_mem_bh
= rman_get_bushandle(sc
->sc_mem_res
);
598 sc
->sc_irq_res
= bus_alloc_resource_any(dev
, SYS_RES_IRQ
,
600 RF_SHAREABLE
| RF_ACTIVE
);
601 if (sc
->sc_irq_res
== NULL
) {
602 device_printf(dev
, "can't allocate irq\n");
610 sysctl_ctx_init(&sc
->sc_sysctl_ctx
);
611 sc
->sc_sysctl_tree
= SYSCTL_ADD_NODE(&sc
->sc_sysctl_ctx
,
612 SYSCTL_STATIC_CHILDREN(_hw
),
614 device_get_nameunit(dev
),
616 if (sc
->sc_sysctl_tree
== NULL
) {
617 device_printf(dev
, "can't add sysctl node\n");
622 SYSCTL_ADD_UINT(&sc
->sc_sysctl_ctx
,
623 SYSCTL_CHILDREN(sc
->sc_sysctl_tree
), OID_AUTO
,
624 "dwell_time", CTLFLAG_RW
, &sc
->sc_dwell_time
, 0,
625 "Channel dwell time during scan (msec)");
626 SYSCTL_ADD_UINT(&sc
->sc_sysctl_ctx
,
627 SYSCTL_CHILDREN(sc
->sc_sysctl_tree
), OID_AUTO
,
628 "fw_version", CTLFLAG_RD
, &sc
->sc_fw_version
, 0,
630 SYSCTL_ADD_UINT(&sc
->sc_sysctl_ctx
,
631 SYSCTL_CHILDREN(sc
->sc_sysctl_tree
), OID_AUTO
,
632 "led_idle", CTLFLAG_RW
, &sc
->sc_led_idle
, 0,
633 "# ticks before LED enters idle state");
634 SYSCTL_ADD_INT(&sc
->sc_sysctl_ctx
,
635 SYSCTL_CHILDREN(sc
->sc_sysctl_tree
), OID_AUTO
,
636 "led_blink", CTLFLAG_RW
, &sc
->sc_led_blink
, 0,
637 "Allow LED to blink");
638 SYSCTL_ADD_INT(&sc
->sc_sysctl_ctx
,
639 SYSCTL_CHILDREN(sc
->sc_sysctl_tree
), OID_AUTO
,
640 "txpwr_calib", CTLFLAG_RW
, &sc
->sc_txpwr_calib
, 0,
641 "Enable software TX power calibration");
643 SYSCTL_ADD_UINT(&sc
->sc_sysctl_ctx
,
644 SYSCTL_CHILDREN(sc
->sc_sysctl_tree
), OID_AUTO
,
645 "debug", CTLFLAG_RW
, &sc
->sc_debug
, 0, "Debug flags");
650 error
= bwi_bbp_attach(sc
);
654 error
= bwi_bbp_power_on(sc
, BWI_CLOCK_MODE_FAST
);
658 if (BWI_REGWIN_EXIST(&sc
->sc_com_regwin
)) {
659 error
= bwi_set_clock_delay(sc
);
663 error
= bwi_set_clock_mode(sc
, BWI_CLOCK_MODE_FAST
);
667 error
= bwi_get_pwron_delay(sc
);
672 error
= bwi_bus_attach(sc
);
676 bwi_get_card_flags(sc
);
680 for (i
= 0; i
< sc
->sc_nmac
; ++i
) {
681 struct bwi_regwin
*old
;
683 mac
= &sc
->sc_mac
[i
];
684 error
= bwi_regwin_switch(sc
, &mac
->mac_regwin
, &old
);
688 error
= bwi_mac_lateattach(mac
);
692 error
= bwi_regwin_switch(sc
, old
, NULL
);
698 * XXX First MAC is known to exist
701 mac
= &sc
->sc_mac
[0];
704 bwi_bbp_power_off(sc
);
706 error
= bwi_dma_alloc(sc
);
711 ifp
->if_flags
= IFF_BROADCAST
| IFF_SIMPLEX
| IFF_MULTICAST
;
712 ifp
->if_init
= bwi_init
;
713 ifp
->if_ioctl
= bwi_ioctl
;
714 ifp
->if_start
= bwi_start
;
715 ifp
->if_watchdog
= bwi_watchdog
;
716 ifq_set_maxlen(&ifp
->if_snd
, IFQ_MAXLEN
);
717 ifq_set_ready(&ifp
->if_snd
);
720 sc
->sc_locale
= __SHIFTOUT(bwi_read_sprom(sc
, BWI_SPROM_CARD_INFO
),
721 BWI_SPROM_CARD_INFO_LOCALE
);
722 DPRINTF(sc
, BWI_DBG_ATTACH
, "locale: %d\n", sc
->sc_locale
);
725 * Setup ratesets, phytype, channels and get MAC address
727 if (phy
->phy_mode
== IEEE80211_MODE_11B
||
728 phy
->phy_mode
== IEEE80211_MODE_11G
) {
731 ic
->ic_sup_rates
[IEEE80211_MODE_11B
] = bwi_rateset_11b
;
733 if (phy
->phy_mode
== IEEE80211_MODE_11B
) {
734 chan_flags
= IEEE80211_CHAN_B
;
735 ic
->ic_phytype
= IEEE80211_T_DS
;
737 chan_flags
= IEEE80211_CHAN_CCK
|
738 IEEE80211_CHAN_OFDM
|
741 ic
->ic_phytype
= IEEE80211_T_OFDM
;
742 ic
->ic_sup_rates
[IEEE80211_MODE_11G
] =
746 /* XXX depend on locale */
747 for (i
= 1; i
<= 14; ++i
) {
748 ic
->ic_channels
[i
].ic_freq
=
749 ieee80211_ieee2mhz(i
, IEEE80211_CHAN_2GHZ
);
750 ic
->ic_channels
[i
].ic_flags
= chan_flags
;
753 bwi_get_eaddr(sc
, BWI_SPROM_11BG_EADDR
, ic
->ic_myaddr
);
754 if (IEEE80211_IS_MULTICAST(ic
->ic_myaddr
)) {
755 bwi_get_eaddr(sc
, BWI_SPROM_11A_EADDR
, ic
->ic_myaddr
);
756 if (IEEE80211_IS_MULTICAST(ic
->ic_myaddr
)) {
757 device_printf(dev
, "invalid MAC address: "
758 "%6D\n", ic
->ic_myaddr
, ":");
761 } else if (phy
->phy_mode
== IEEE80211_MODE_11A
) {
766 panic("unknown phymode %d\n", phy
->phy_mode
);
769 ic
->ic_caps
= IEEE80211_C_SHSLOT
|
770 IEEE80211_C_SHPREAMBLE
|
773 ic
->ic_state
= IEEE80211_S_INIT
;
774 ic
->ic_opmode
= IEEE80211_M_STA
;
776 IEEE80211_ONOE_PARAM_SETUP(&sc
->sc_onoe_param
);
777 ic
->ic_ratectl
.rc_st_ratectl_cap
= IEEE80211_RATECTL_CAP_ONOE
;
778 ic
->ic_ratectl
.rc_st_ratectl
= IEEE80211_RATECTL_ONOE
;
779 ic
->ic_ratectl
.rc_st_attach
= bwi_ratectl_attach
;
781 ic
->ic_updateslot
= bwi_updateslot
;
783 ieee80211_ifattach(ic
);
785 ic
->ic_headroom
= sizeof(struct bwi_txbuf_hdr
);
786 ic
->ic_flags_ext
|= IEEE80211_FEXT_SWBMISS
;
788 sc
->sc_newstate
= ic
->ic_newstate
;
789 ic
->ic_newstate
= bwi_newstate
;
791 ieee80211_media_init(ic
, bwi_media_change
, ieee80211_media_status
);
796 bpfattach_dlt(ifp
, DLT_IEEE802_11_RADIO
,
797 sizeof(struct ieee80211_frame
) + sizeof(sc
->sc_tx_th
),
800 sc
->sc_tx_th_len
= roundup(sizeof(sc
->sc_tx_th
), sizeof(uint32_t));
801 sc
->sc_tx_th
.wt_ihdr
.it_len
= htole16(sc
->sc_tx_th_len
);
802 sc
->sc_tx_th
.wt_ihdr
.it_present
= htole32(BWI_TX_RADIOTAP_PRESENT
);
804 sc
->sc_rx_th_len
= roundup(sizeof(sc
->sc_rx_th
), sizeof(uint32_t));
805 sc
->sc_rx_th
.wr_ihdr
.it_len
= htole16(sc
->sc_rx_th_len
);
806 sc
->sc_rx_th
.wr_ihdr
.it_present
= htole32(BWI_RX_RADIOTAP_PRESENT
);
808 error
= bus_setup_intr(dev
, sc
->sc_irq_res
, INTR_MPSAFE
, bwi_intr
, sc
,
809 &sc
->sc_irq_handle
, ifp
->if_serializer
);
811 device_printf(dev
, "can't setup intr\n");
813 ieee80211_ifdetach(ic
);
818 ieee80211_announce(ic
);
827 bwi_detach(device_t dev
)
829 struct bwi_softc
*sc
= device_get_softc(dev
);
831 if (device_is_attached(dev
)) {
832 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
835 lwkt_serialize_enter(ifp
->if_serializer
);
837 bus_teardown_intr(dev
, sc
->sc_irq_res
, sc
->sc_irq_handle
);
838 lwkt_serialize_exit(ifp
->if_serializer
);
841 ieee80211_ifdetach(&sc
->sc_ic
);
843 for (i
= 0; i
< sc
->sc_nmac
; ++i
)
844 bwi_mac_detach(&sc
->sc_mac
[i
]);
847 if (sc
->sc_sysctl_tree
!= NULL
)
848 sysctl_ctx_free(&sc
->sc_sysctl_ctx
);
850 if (sc
->sc_irq_res
!= NULL
) {
851 bus_release_resource(dev
, SYS_RES_IRQ
, sc
->sc_irq_rid
,
855 if (sc
->sc_mem_res
!= NULL
) {
856 bus_release_resource(dev
, SYS_RES_MEMORY
, sc
->sc_mem_rid
,
866 bwi_shutdown(device_t dev
)
868 struct bwi_softc
*sc
= device_get_softc(dev
);
869 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
871 lwkt_serialize_enter(ifp
->if_serializer
);
873 lwkt_serialize_exit(ifp
->if_serializer
);
878 bwi_power_on(struct bwi_softc
*sc
, int with_pll
)
880 uint32_t gpio_in
, gpio_out
, gpio_en
;
883 gpio_in
= pci_read_config(sc
->sc_dev
, BWI_PCIR_GPIO_IN
, 4);
884 if (gpio_in
& BWI_PCIM_GPIO_PWR_ON
)
887 gpio_out
= pci_read_config(sc
->sc_dev
, BWI_PCIR_GPIO_OUT
, 4);
888 gpio_en
= pci_read_config(sc
->sc_dev
, BWI_PCIR_GPIO_ENABLE
, 4);
890 gpio_out
|= BWI_PCIM_GPIO_PWR_ON
;
891 gpio_en
|= BWI_PCIM_GPIO_PWR_ON
;
893 /* Turn off PLL first */
894 gpio_out
|= BWI_PCIM_GPIO_PLL_PWR_OFF
;
895 gpio_en
|= BWI_PCIM_GPIO_PLL_PWR_OFF
;
898 pci_write_config(sc
->sc_dev
, BWI_PCIR_GPIO_OUT
, gpio_out
, 4);
899 pci_write_config(sc
->sc_dev
, BWI_PCIR_GPIO_ENABLE
, gpio_en
, 4);
904 gpio_out
&= ~BWI_PCIM_GPIO_PLL_PWR_OFF
;
905 pci_write_config(sc
->sc_dev
, BWI_PCIR_GPIO_OUT
, gpio_out
, 4);
910 /* Clear "Signaled Target Abort" */
911 status
= pci_read_config(sc
->sc_dev
, PCIR_STATUS
, 2);
912 status
&= ~PCIM_STATUS_STABORT
;
913 pci_write_config(sc
->sc_dev
, PCIR_STATUS
, status
, 2);
917 bwi_power_off(struct bwi_softc
*sc
, int with_pll
)
919 uint32_t gpio_out
, gpio_en
;
921 pci_read_config(sc
->sc_dev
, BWI_PCIR_GPIO_IN
, 4); /* dummy read */
922 gpio_out
= pci_read_config(sc
->sc_dev
, BWI_PCIR_GPIO_OUT
, 4);
923 gpio_en
= pci_read_config(sc
->sc_dev
, BWI_PCIR_GPIO_ENABLE
, 4);
925 gpio_out
&= ~BWI_PCIM_GPIO_PWR_ON
;
926 gpio_en
|= BWI_PCIM_GPIO_PWR_ON
;
928 gpio_out
|= BWI_PCIM_GPIO_PLL_PWR_OFF
;
929 gpio_en
|= BWI_PCIM_GPIO_PLL_PWR_OFF
;
932 pci_write_config(sc
->sc_dev
, BWI_PCIR_GPIO_OUT
, gpio_out
, 4);
933 pci_write_config(sc
->sc_dev
, BWI_PCIR_GPIO_ENABLE
, gpio_en
, 4);
938 bwi_regwin_switch(struct bwi_softc
*sc
, struct bwi_regwin
*rw
,
939 struct bwi_regwin
**old_rw
)
946 if (!BWI_REGWIN_EXIST(rw
))
949 if (sc
->sc_cur_regwin
!= rw
) {
950 error
= bwi_regwin_select(sc
, rw
->rw_id
);
952 if_printf(&sc
->sc_ic
.ic_if
, "can't select regwin %d\n",
959 *old_rw
= sc
->sc_cur_regwin
;
960 sc
->sc_cur_regwin
= rw
;
965 bwi_regwin_select(struct bwi_softc
*sc
, int id
)
967 uint32_t win
= BWI_PCIM_REGWIN(id
);
971 for (i
= 0; i
< RETRY_MAX
; ++i
) {
972 pci_write_config(sc
->sc_dev
, BWI_PCIR_SEL_REGWIN
, win
, 4);
973 if (pci_read_config(sc
->sc_dev
, BWI_PCIR_SEL_REGWIN
, 4) == win
)
983 bwi_regwin_info(struct bwi_softc
*sc
, uint16_t *type
, uint8_t *rev
)
987 val
= CSR_READ_4(sc
, BWI_ID_HI
);
988 *type
= BWI_ID_HI_REGWIN_TYPE(val
);
989 *rev
= BWI_ID_HI_REGWIN_REV(val
);
991 DPRINTF(sc
, BWI_DBG_ATTACH
, "regwin: type 0x%03x, rev %d, "
992 "vendor 0x%04x\n", *type
, *rev
,
993 __SHIFTOUT(val
, BWI_ID_HI_REGWIN_VENDOR_MASK
));
997 bwi_bbp_attach(struct bwi_softc
*sc
)
999 #define N(arr) (int)(sizeof(arr) / sizeof(arr[0]))
1000 uint16_t bbp_id
, rw_type
;
1003 int error
, nregwin
, i
;
1006 * Get 0th regwin information
1007 * NOTE: 0th regwin should exist
1009 error
= bwi_regwin_select(sc
, 0);
1011 device_printf(sc
->sc_dev
, "can't select regwin 0\n");
1014 bwi_regwin_info(sc
, &rw_type
, &rw_rev
);
1021 if (rw_type
== BWI_REGWIN_T_COM
) {
1022 info
= CSR_READ_4(sc
, BWI_INFO
);
1023 bbp_id
= __SHIFTOUT(info
, BWI_INFO_BBPID_MASK
);
1025 BWI_CREATE_REGWIN(&sc
->sc_com_regwin
, 0, rw_type
, rw_rev
);
1027 sc
->sc_cap
= CSR_READ_4(sc
, BWI_CAPABILITY
);
1029 uint16_t did
= pci_get_device(sc
->sc_dev
);
1030 uint8_t revid
= pci_get_revid(sc
->sc_dev
);
1032 for (i
= 0; i
< N(bwi_bbpid_map
); ++i
) {
1033 if (did
>= bwi_bbpid_map
[i
].did_min
&&
1034 did
<= bwi_bbpid_map
[i
].did_max
) {
1035 bbp_id
= bwi_bbpid_map
[i
].bbp_id
;
1040 device_printf(sc
->sc_dev
, "no BBP id for device id "
1045 info
= __SHIFTIN(revid
, BWI_INFO_BBPREV_MASK
) |
1046 __SHIFTIN(0, BWI_INFO_BBPPKG_MASK
);
1050 * Find out number of regwins
1053 if (rw_type
== BWI_REGWIN_T_COM
&& rw_rev
>= 4) {
1054 nregwin
= __SHIFTOUT(info
, BWI_INFO_NREGWIN_MASK
);
1056 for (i
= 0; i
< N(bwi_regwin_count
); ++i
) {
1057 if (bwi_regwin_count
[i
].bbp_id
== bbp_id
) {
1058 nregwin
= bwi_regwin_count
[i
].nregwin
;
1063 device_printf(sc
->sc_dev
, "no number of win for "
1064 "BBP id 0x%04x\n", bbp_id
);
1069 /* Record BBP id/rev for later using */
1070 sc
->sc_bbp_id
= bbp_id
;
1071 sc
->sc_bbp_rev
= __SHIFTOUT(info
, BWI_INFO_BBPREV_MASK
);
1072 sc
->sc_bbp_pkg
= __SHIFTOUT(info
, BWI_INFO_BBPPKG_MASK
);
1073 device_printf(sc
->sc_dev
, "BBP: id 0x%04x, rev 0x%x, pkg %d\n",
1074 sc
->sc_bbp_id
, sc
->sc_bbp_rev
, sc
->sc_bbp_pkg
);
1076 DPRINTF(sc
, BWI_DBG_ATTACH
, "nregwin %d, cap 0x%08x\n",
1077 nregwin
, sc
->sc_cap
);
1080 * Create rest of the regwins
1083 /* Don't re-create common regwin, if it is already created */
1084 i
= BWI_REGWIN_EXIST(&sc
->sc_com_regwin
) ? 1 : 0;
1086 for (; i
< nregwin
; ++i
) {
1088 * Get regwin information
1090 error
= bwi_regwin_select(sc
, i
);
1092 device_printf(sc
->sc_dev
,
1093 "can't select regwin %d\n", i
);
1096 bwi_regwin_info(sc
, &rw_type
, &rw_rev
);
1100 * 1) Bus (PCI/PCIE) regwin
1102 * Ignore rest types of regwin
1104 if (rw_type
== BWI_REGWIN_T_BUSPCI
||
1105 rw_type
== BWI_REGWIN_T_BUSPCIE
) {
1106 if (BWI_REGWIN_EXIST(&sc
->sc_bus_regwin
)) {
1107 device_printf(sc
->sc_dev
,
1108 "bus regwin already exists\n");
1110 BWI_CREATE_REGWIN(&sc
->sc_bus_regwin
, i
,
1113 } else if (rw_type
== BWI_REGWIN_T_MAC
) {
1114 /* XXX ignore return value */
1115 bwi_mac_attach(sc
, i
, rw_rev
);
1119 /* At least one MAC shold exist */
1120 if (!BWI_REGWIN_EXIST(&sc
->sc_mac
[0].mac_regwin
)) {
1121 device_printf(sc
->sc_dev
, "no MAC was found\n");
1124 KKASSERT(sc
->sc_nmac
> 0);
1126 /* Bus regwin must exist */
1127 if (!BWI_REGWIN_EXIST(&sc
->sc_bus_regwin
)) {
1128 device_printf(sc
->sc_dev
, "no bus regwin was found\n");
1132 /* Start with first MAC */
1133 error
= bwi_regwin_switch(sc
, &sc
->sc_mac
[0].mac_regwin
, NULL
);
1142 bwi_bus_init(struct bwi_softc
*sc
, struct bwi_mac
*mac
)
1144 struct bwi_regwin
*old
, *bus
;
1148 bus
= &sc
->sc_bus_regwin
;
1149 KKASSERT(sc
->sc_cur_regwin
== &mac
->mac_regwin
);
1152 * Tell bus to generate requested interrupts
1154 if (bus
->rw_rev
< 6 && bus
->rw_type
== BWI_REGWIN_T_BUSPCI
) {
1156 * NOTE: Read BWI_FLAGS from MAC regwin
1158 val
= CSR_READ_4(sc
, BWI_FLAGS
);
1160 error
= bwi_regwin_switch(sc
, bus
, &old
);
1164 CSR_SETBITS_4(sc
, BWI_INTRVEC
, (val
& BWI_FLAGS_INTR_MASK
));
1168 mac_mask
= 1 << mac
->mac_id
;
1170 error
= bwi_regwin_switch(sc
, bus
, &old
);
1174 val
= pci_read_config(sc
->sc_dev
, BWI_PCIR_INTCTL
, 4);
1175 val
|= mac_mask
<< 8;
1176 pci_write_config(sc
->sc_dev
, BWI_PCIR_INTCTL
, val
, 4);
1179 if (sc
->sc_flags
& BWI_F_BUS_INITED
)
1182 if (bus
->rw_type
== BWI_REGWIN_T_BUSPCI
) {
1184 * Enable prefetch and burst
1186 CSR_SETBITS_4(sc
, BWI_BUS_CONFIG
,
1187 BWI_BUS_CONFIG_PREFETCH
| BWI_BUS_CONFIG_BURST
);
1189 if (bus
->rw_rev
< 5) {
1190 struct bwi_regwin
*com
= &sc
->sc_com_regwin
;
1193 * Configure timeouts for bus operation
1197 * Set service timeout and request timeout
1199 CSR_SETBITS_4(sc
, BWI_CONF_LO
,
1200 __SHIFTIN(BWI_CONF_LO_SERVTO
, BWI_CONF_LO_SERVTO_MASK
) |
1201 __SHIFTIN(BWI_CONF_LO_REQTO
, BWI_CONF_LO_REQTO_MASK
));
1204 * If there is common regwin, we switch to that regwin
1205 * and switch back to bus regwin once we have done.
1207 if (BWI_REGWIN_EXIST(com
)) {
1208 error
= bwi_regwin_switch(sc
, com
, NULL
);
1213 /* Let bus know what we have changed */
1214 CSR_WRITE_4(sc
, BWI_BUS_ADDR
, BWI_BUS_ADDR_MAGIC
);
1215 CSR_READ_4(sc
, BWI_BUS_ADDR
); /* Flush */
1216 CSR_WRITE_4(sc
, BWI_BUS_DATA
, 0);
1217 CSR_READ_4(sc
, BWI_BUS_DATA
); /* Flush */
1219 if (BWI_REGWIN_EXIST(com
)) {
1220 error
= bwi_regwin_switch(sc
, bus
, NULL
);
1224 } else if (bus
->rw_rev
>= 11) {
1226 * Enable memory read multiple
1228 CSR_SETBITS_4(sc
, BWI_BUS_CONFIG
, BWI_BUS_CONFIG_MRM
);
1234 sc
->sc_flags
|= BWI_F_BUS_INITED
;
1236 return bwi_regwin_switch(sc
, old
, NULL
);
1240 bwi_get_card_flags(struct bwi_softc
*sc
)
1242 sc
->sc_card_flags
= bwi_read_sprom(sc
, BWI_SPROM_CARD_FLAGS
);
1243 if (sc
->sc_card_flags
== 0xffff)
1244 sc
->sc_card_flags
= 0;
1246 if (sc
->sc_pci_subvid
== PCI_VENDOR_APPLE
&&
1247 sc
->sc_pci_subdid
== 0x4e && /* XXX */
1248 sc
->sc_pci_revid
> 0x40)
1249 sc
->sc_card_flags
|= BWI_CARD_F_PA_GPIO9
;
1251 DPRINTF(sc
, BWI_DBG_ATTACH
, "card flags 0x%04x\n", sc
->sc_card_flags
);
1255 bwi_get_eaddr(struct bwi_softc
*sc
, uint16_t eaddr_ofs
, uint8_t *eaddr
)
1259 for (i
= 0; i
< 3; ++i
) {
1260 *((uint16_t *)eaddr
+ i
) =
1261 htobe16(bwi_read_sprom(sc
, eaddr_ofs
+ 2 * i
));
1266 bwi_get_clock_freq(struct bwi_softc
*sc
, struct bwi_clock_freq
*freq
)
1268 struct bwi_regwin
*com
;
1273 bzero(freq
, sizeof(*freq
));
1274 com
= &sc
->sc_com_regwin
;
1276 KKASSERT(BWI_REGWIN_EXIST(com
));
1277 KKASSERT(sc
->sc_cur_regwin
== com
);
1278 KKASSERT(sc
->sc_cap
& BWI_CAP_CLKMODE
);
1281 * Calculate clock frequency
1285 if (com
->rw_rev
< 6) {
1286 val
= pci_read_config(sc
->sc_dev
, BWI_PCIR_GPIO_OUT
, 4);
1287 if (val
& BWI_PCIM_GPIO_OUT_CLKSRC
) {
1288 src
= BWI_CLKSRC_PCI
;
1291 src
= BWI_CLKSRC_CS_OSC
;
1294 } else if (com
->rw_rev
< 10) {
1295 val
= CSR_READ_4(sc
, BWI_CLOCK_CTRL
);
1297 src
= __SHIFTOUT(val
, BWI_CLOCK_CTRL_CLKSRC
);
1298 if (src
== BWI_CLKSRC_LP_OSC
) {
1301 div
= (__SHIFTOUT(val
, BWI_CLOCK_CTRL_FDIV
) + 1) << 2;
1303 /* Unknown source */
1304 if (src
>= BWI_CLKSRC_MAX
)
1305 src
= BWI_CLKSRC_CS_OSC
;
1308 val
= CSR_READ_4(sc
, BWI_CLOCK_INFO
);
1310 src
= BWI_CLKSRC_CS_OSC
;
1311 div
= (__SHIFTOUT(val
, BWI_CLOCK_INFO_FDIV
) + 1) << 2;
1314 KKASSERT(src
>= 0 && src
< BWI_CLKSRC_MAX
);
1317 DPRINTF(sc
, BWI_DBG_ATTACH
, "clksrc %s\n",
1318 src
== BWI_CLKSRC_PCI
? "PCI" :
1319 (src
== BWI_CLKSRC_LP_OSC
? "LP_OSC" : "CS_OSC"));
1321 freq
->clkfreq_min
= bwi_clkfreq
[src
].freq_min
/ div
;
1322 freq
->clkfreq_max
= bwi_clkfreq
[src
].freq_max
/ div
;
1324 DPRINTF(sc
, BWI_DBG_ATTACH
, "clkfreq min %u, max %u\n",
1325 freq
->clkfreq_min
, freq
->clkfreq_max
);
1329 bwi_set_clock_mode(struct bwi_softc
*sc
, enum bwi_clock_mode clk_mode
)
1331 struct bwi_regwin
*old
, *com
;
1332 uint32_t clk_ctrl
, clk_src
;
1333 int error
, pwr_off
= 0;
1335 com
= &sc
->sc_com_regwin
;
1336 if (!BWI_REGWIN_EXIST(com
))
1339 if (com
->rw_rev
>= 10 || com
->rw_rev
< 6)
1343 * For common regwin whose rev is [6, 10), the chip
1344 * must be capable to change clock mode.
1346 if ((sc
->sc_cap
& BWI_CAP_CLKMODE
) == 0)
1349 error
= bwi_regwin_switch(sc
, com
, &old
);
1353 if (clk_mode
== BWI_CLOCK_MODE_FAST
)
1354 bwi_power_on(sc
, 0); /* Don't turn on PLL */
1356 clk_ctrl
= CSR_READ_4(sc
, BWI_CLOCK_CTRL
);
1357 clk_src
= __SHIFTOUT(clk_ctrl
, BWI_CLOCK_CTRL_CLKSRC
);
1360 case BWI_CLOCK_MODE_FAST
:
1361 clk_ctrl
&= ~BWI_CLOCK_CTRL_SLOW
;
1362 clk_ctrl
|= BWI_CLOCK_CTRL_IGNPLL
;
1364 case BWI_CLOCK_MODE_SLOW
:
1365 clk_ctrl
|= BWI_CLOCK_CTRL_SLOW
;
1367 case BWI_CLOCK_MODE_DYN
:
1368 clk_ctrl
&= ~(BWI_CLOCK_CTRL_SLOW
|
1369 BWI_CLOCK_CTRL_IGNPLL
|
1370 BWI_CLOCK_CTRL_NODYN
);
1371 if (clk_src
!= BWI_CLKSRC_CS_OSC
) {
1372 clk_ctrl
|= BWI_CLOCK_CTRL_NODYN
;
1377 CSR_WRITE_4(sc
, BWI_CLOCK_CTRL
, clk_ctrl
);
1380 bwi_power_off(sc
, 0); /* Leave PLL as it is */
1382 return bwi_regwin_switch(sc
, old
, NULL
);
1386 bwi_set_clock_delay(struct bwi_softc
*sc
)
1388 struct bwi_regwin
*old
, *com
;
1391 com
= &sc
->sc_com_regwin
;
1392 if (!BWI_REGWIN_EXIST(com
))
1395 error
= bwi_regwin_switch(sc
, com
, &old
);
1399 if (sc
->sc_bbp_id
== BWI_BBPID_BCM4321
) {
1400 if (sc
->sc_bbp_rev
== 0)
1401 CSR_WRITE_4(sc
, BWI_CONTROL
, BWI_CONTROL_MAGIC0
);
1402 else if (sc
->sc_bbp_rev
== 1)
1403 CSR_WRITE_4(sc
, BWI_CONTROL
, BWI_CONTROL_MAGIC1
);
1406 if (sc
->sc_cap
& BWI_CAP_CLKMODE
) {
1407 if (com
->rw_rev
>= 10) {
1408 CSR_FILT_SETBITS_4(sc
, BWI_CLOCK_INFO
, 0xffff, 0x40000);
1410 struct bwi_clock_freq freq
;
1412 bwi_get_clock_freq(sc
, &freq
);
1413 CSR_WRITE_4(sc
, BWI_PLL_ON_DELAY
,
1414 howmany(freq
.clkfreq_max
* 150, 1000000));
1415 CSR_WRITE_4(sc
, BWI_FREQ_SEL_DELAY
,
1416 howmany(freq
.clkfreq_max
* 15, 1000000));
1420 return bwi_regwin_switch(sc
, old
, NULL
);
1426 bwi_init_statechg(xsc
, 1);
1430 bwi_init_statechg(struct bwi_softc
*sc
, int statechg
)
1432 struct ieee80211com
*ic
= &sc
->sc_ic
;
1433 struct ifnet
*ifp
= &ic
->ic_if
;
1434 struct bwi_mac
*mac
;
1437 ASSERT_SERIALIZED(ifp
->if_serializer
);
1439 error
= bwi_stop(sc
, statechg
);
1441 if_printf(ifp
, "can't stop\n");
1445 bwi_bbp_power_on(sc
, BWI_CLOCK_MODE_FAST
);
1449 mac
= &sc
->sc_mac
[0];
1450 error
= bwi_regwin_switch(sc
, &mac
->mac_regwin
, NULL
);
1454 error
= bwi_mac_init(mac
);
1458 bwi_bbp_power_on(sc
, BWI_CLOCK_MODE_DYN
);
1460 bcopy(IF_LLADDR(ifp
), ic
->ic_myaddr
, sizeof(ic
->ic_myaddr
));
1462 bwi_set_bssid(sc
, bwi_zero_addr
); /* Clear BSSID */
1463 bwi_set_addr_filter(sc
, BWI_ADDR_FILTER_MYADDR
, ic
->ic_myaddr
);
1465 bwi_mac_reset_hwkeys(mac
);
1467 if ((mac
->mac_flags
& BWI_MAC_F_HAS_TXSTATS
) == 0) {
1472 * Drain any possible pending TX status
1474 for (i
= 0; i
< NRETRY
; ++i
) {
1475 if ((CSR_READ_4(sc
, BWI_TXSTATUS0
) &
1476 BWI_TXSTATUS0_VALID
) == 0)
1478 CSR_READ_4(sc
, BWI_TXSTATUS1
);
1481 if_printf(ifp
, "can't drain TX status\n");
1485 if (mac
->mac_phy
.phy_mode
== IEEE80211_MODE_11G
)
1486 bwi_mac_updateslot(mac
, 1);
1489 error
= bwi_mac_start(mac
);
1494 bwi_enable_intrs(sc
, BWI_INIT_INTRS
);
1496 ifp
->if_flags
|= IFF_RUNNING
;
1497 ifp
->if_flags
&= ~IFF_OACTIVE
;
1500 if (ic
->ic_opmode
!= IEEE80211_M_MONITOR
) {
1501 if (ic
->ic_roaming
!= IEEE80211_ROAMING_MANUAL
)
1502 ieee80211_new_state(ic
, IEEE80211_S_SCAN
, -1);
1504 ieee80211_new_state(ic
, IEEE80211_S_RUN
, -1);
1507 ieee80211_new_state(ic
, ic
->ic_state
, -1);
1517 bwi_ioctl(struct ifnet
*ifp
, u_long cmd
, caddr_t req
, struct ucred
*cr
)
1519 struct bwi_softc
*sc
= ifp
->if_softc
;
1522 ASSERT_SERIALIZED(ifp
->if_serializer
);
1526 if ((ifp
->if_flags
& (IFF_UP
| IFF_RUNNING
)) ==
1527 (IFF_UP
| IFF_RUNNING
)) {
1528 struct bwi_mac
*mac
;
1531 KKASSERT(sc
->sc_cur_regwin
->rw_type
==
1533 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
1535 if ((ifp
->if_flags
& IFF_PROMISC
) &&
1536 (sc
->sc_flags
& BWI_F_PROMISC
) == 0) {
1538 sc
->sc_flags
|= BWI_F_PROMISC
;
1539 } else if ((ifp
->if_flags
& IFF_PROMISC
) == 0 &&
1540 (sc
->sc_flags
& BWI_F_PROMISC
)) {
1542 sc
->sc_flags
&= ~BWI_F_PROMISC
;
1546 bwi_mac_set_promisc(mac
, promisc
);
1549 if (ifp
->if_flags
& IFF_UP
) {
1550 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
1553 if (ifp
->if_flags
& IFF_RUNNING
)
1558 error
= ieee80211_ioctl(&sc
->sc_ic
, cmd
, req
, cr
);
1562 if (error
== ENETRESET
) {
1563 if ((ifp
->if_flags
& (IFF_UP
| IFF_RUNNING
)) ==
1564 (IFF_UP
| IFF_RUNNING
))
1572 bwi_start(struct ifnet
*ifp
)
1574 struct bwi_softc
*sc
= ifp
->if_softc
;
1575 struct ieee80211com
*ic
= &sc
->sc_ic
;
1576 struct bwi_txbuf_data
*tbd
= &sc
->sc_tx_bdata
[BWI_TX_DATA_RING
];
1579 ASSERT_SERIALIZED(ifp
->if_serializer
);
1581 if ((ifp
->if_flags
& IFF_OACTIVE
) ||
1582 (ifp
->if_flags
& IFF_RUNNING
) == 0)
1588 while (tbd
->tbd_buf
[idx
].tb_mbuf
== NULL
) {
1589 struct ieee80211_frame
*wh
;
1590 struct ieee80211_node
*ni
;
1594 if (!IF_QEMPTY(&ic
->ic_mgtq
)) {
1595 IF_DEQUEUE(&ic
->ic_mgtq
, m
);
1597 ni
= (struct ieee80211_node
*)m
->m_pkthdr
.rcvif
;
1598 m
->m_pkthdr
.rcvif
= NULL
;
1601 } else if (!ifq_is_empty(&ifp
->if_snd
)) {
1602 struct ether_header
*eh
;
1604 if (ic
->ic_state
!= IEEE80211_S_RUN
)
1607 m
= ifq_dequeue(&ifp
->if_snd
, NULL
);
1611 if (m
->m_len
< sizeof(*eh
)) {
1612 m
= m_pullup(m
, sizeof(*eh
));
1618 eh
= mtod(m
, struct ether_header
*);
1620 ni
= ieee80211_find_txnode(ic
, eh
->ether_dhost
);
1631 m
= ieee80211_encap(ic
, m
, ni
);
1633 ieee80211_free_node(ni
);
1641 if (ic
->ic_rawbpf
!= NULL
)
1642 bpf_mtap(ic
->ic_rawbpf
, m
);
1644 wh
= mtod(m
, struct ieee80211_frame
*);
1645 if (wh
->i_fc
[1] & IEEE80211_FC1_WEP
) {
1646 if (ieee80211_crypto_encap(ic
, ni
, m
) == NULL
) {
1647 ieee80211_free_node(ni
);
1653 wh
= NULL
; /* Catch any invalid use */
1655 if (bwi_encap(sc
, idx
, m
, &ni
, mgt_pkt
) != 0) {
1656 /* 'm' is freed in bwi_encap() if we reach here */
1658 ieee80211_free_node(ni
);
1665 idx
= (idx
+ 1) % BWI_TX_NDESC
;
1667 if (tbd
->tbd_used
+ BWI_TX_NSPRDESC
>= BWI_TX_NDESC
) {
1668 ifp
->if_flags
|= IFF_OACTIVE
;
1675 sc
->sc_tx_timer
= 5;
1680 bwi_watchdog(struct ifnet
*ifp
)
1682 struct bwi_softc
*sc
= ifp
->if_softc
;
1684 ASSERT_SERIALIZED(ifp
->if_serializer
);
1688 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
1691 if (sc
->sc_tx_timer
) {
1692 if (--sc
->sc_tx_timer
== 0) {
1693 if_printf(ifp
, "watchdog timeout\n");
1700 ieee80211_watchdog(&sc
->sc_ic
);
1704 bwi_stop(struct bwi_softc
*sc
, int state_chg
)
1706 struct ieee80211com
*ic
= &sc
->sc_ic
;
1707 struct ifnet
*ifp
= &ic
->ic_if
;
1708 struct bwi_mac
*mac
;
1709 int i
, error
, pwr_off
= 0;
1711 ASSERT_SERIALIZED(ifp
->if_serializer
);
1714 ieee80211_new_state(ic
, IEEE80211_S_INIT
, -1);
1716 bwi_newstate_begin(sc
, IEEE80211_S_INIT
);
1718 if (ifp
->if_flags
& IFF_RUNNING
) {
1719 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
1720 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
1722 bwi_disable_intrs(sc
, BWI_ALL_INTRS
);
1723 CSR_READ_4(sc
, BWI_MAC_INTR_MASK
);
1727 for (i
= 0; i
< sc
->sc_nmac
; ++i
) {
1728 struct bwi_regwin
*old_rw
;
1730 mac
= &sc
->sc_mac
[i
];
1731 if ((mac
->mac_flags
& BWI_MAC_F_INITED
) == 0)
1734 error
= bwi_regwin_switch(sc
, &mac
->mac_regwin
, &old_rw
);
1738 bwi_mac_shutdown(mac
);
1741 bwi_regwin_switch(sc
, old_rw
, NULL
);
1745 bwi_bbp_power_off(sc
);
1747 sc
->sc_tx_timer
= 0;
1749 ifp
->if_flags
&= ~(IFF_RUNNING
| IFF_OACTIVE
);
1756 struct bwi_softc
*sc
= xsc
;
1757 struct bwi_mac
*mac
;
1758 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
1759 uint32_t intr_status
;
1760 uint32_t txrx_intr_status
[BWI_TXRX_NRING
];
1761 int i
, txrx_error
, tx
= 0, rx_data
= -1;
1763 ASSERT_SERIALIZED(ifp
->if_serializer
);
1765 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
1769 * Get interrupt status
1771 intr_status
= CSR_READ_4(sc
, BWI_MAC_INTR_STATUS
);
1772 if (intr_status
== 0xffffffff) /* Not for us */
1775 DPRINTF(sc
, BWI_DBG_INTR
, "intr status 0x%08x\n", intr_status
);
1777 intr_status
&= CSR_READ_4(sc
, BWI_MAC_INTR_MASK
);
1778 if (intr_status
== 0) /* Nothing is interesting */
1781 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
1782 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
1785 DPRINTF(sc
, BWI_DBG_INTR
, "%s\n", "TX/RX intr");
1786 for (i
= 0; i
< BWI_TXRX_NRING
; ++i
) {
1789 if (BWI_TXRX_IS_RX(i
))
1790 mask
= BWI_TXRX_RX_INTRS
;
1792 mask
= BWI_TXRX_TX_INTRS
;
1794 txrx_intr_status
[i
] =
1795 CSR_READ_4(sc
, BWI_TXRX_INTR_STATUS(i
)) & mask
;
1797 _DPRINTF(sc
, BWI_DBG_INTR
, ", %d 0x%08x",
1798 i
, txrx_intr_status
[i
]);
1800 if (txrx_intr_status
[i
] & BWI_TXRX_INTR_ERROR
) {
1801 if_printf(ifp
, "intr fatal TX/RX (%d) error 0x%08x\n",
1802 i
, txrx_intr_status
[i
]);
1806 _DPRINTF(sc
, BWI_DBG_INTR
, "%s\n", "");
1809 * Acknowledge interrupt
1811 CSR_WRITE_4(sc
, BWI_MAC_INTR_STATUS
, intr_status
);
1813 for (i
= 0; i
< BWI_TXRX_NRING
; ++i
)
1814 CSR_WRITE_4(sc
, BWI_TXRX_INTR_STATUS(i
), txrx_intr_status
[i
]);
1816 /* Disable all interrupts */
1817 bwi_disable_intrs(sc
, BWI_ALL_INTRS
);
1819 if (intr_status
& BWI_INTR_PHY_TXERR
) {
1820 if (mac
->mac_flags
& BWI_MAC_F_PHYE_RESET
) {
1821 if_printf(ifp
, "intr PHY TX error\n");
1822 /* XXX to netisr0? */
1823 bwi_init_statechg(sc
, 0);
1829 /* TODO: reset device */
1832 if (intr_status
& BWI_INTR_TBTT
)
1833 bwi_mac_config_ps(mac
);
1835 if (intr_status
& BWI_INTR_EO_ATIM
)
1836 if_printf(ifp
, "EO_ATIM\n");
1838 if (intr_status
& BWI_INTR_PMQ
) {
1840 if ((CSR_READ_4(sc
, BWI_MAC_PS_STATUS
) & 0x8) == 0)
1843 CSR_WRITE_2(sc
, BWI_MAC_PS_STATUS
, 0x2);
1846 if (intr_status
& BWI_INTR_NOISE
)
1847 if_printf(ifp
, "intr noise\n");
1849 if (txrx_intr_status
[0] & BWI_TXRX_INTR_RX
)
1850 rx_data
= sc
->sc_rxeof(sc
);
1852 if (txrx_intr_status
[3] & BWI_TXRX_INTR_RX
) {
1853 sc
->sc_txeof_status(sc
);
1857 if (intr_status
& BWI_INTR_TX_DONE
) {
1862 /* Re-enable interrupts */
1863 bwi_enable_intrs(sc
, BWI_INIT_INTRS
);
1865 if (sc
->sc_blink_led
!= NULL
&& sc
->sc_led_blink
) {
1866 int evt
= BWI_LED_EVENT_NONE
;
1868 if (tx
&& rx_data
> 0) {
1869 if (sc
->sc_rx_rate
> sc
->sc_tx_rate
)
1870 evt
= BWI_LED_EVENT_RX
;
1872 evt
= BWI_LED_EVENT_TX
;
1874 evt
= BWI_LED_EVENT_TX
;
1875 } else if (rx_data
> 0) {
1876 evt
= BWI_LED_EVENT_RX
;
1877 } else if (rx_data
== 0) {
1878 evt
= BWI_LED_EVENT_POLL
;
1881 if (evt
!= BWI_LED_EVENT_NONE
)
1882 bwi_led_event(sc
, evt
);
1887 bwi_newstate_begin(struct bwi_softc
*sc
, enum ieee80211_state nstate
)
1889 callout_stop(&sc
->sc_scan_ch
);
1890 callout_stop(&sc
->sc_calib_ch
);
1892 ieee80211_ratectl_newstate(&sc
->sc_ic
, nstate
);
1893 bwi_led_newstate(sc
, nstate
);
1895 if (nstate
== IEEE80211_S_INIT
)
1896 sc
->sc_txpwrcb_type
= BWI_TXPWR_INIT
;
1900 bwi_newstate(struct ieee80211com
*ic
, enum ieee80211_state nstate
, int arg
)
1902 struct bwi_softc
*sc
= ic
->ic_if
.if_softc
;
1903 struct ifnet
*ifp
= &ic
->ic_if
;
1906 ASSERT_SERIALIZED(ifp
->if_serializer
);
1908 bwi_newstate_begin(sc
, nstate
);
1910 if (nstate
== IEEE80211_S_INIT
)
1913 error
= bwi_set_chan(sc
, ic
->ic_curchan
);
1915 if_printf(ifp
, "can't set channel to %u\n",
1916 ieee80211_chan2ieee(ic
, ic
->ic_curchan
));
1920 if (ic
->ic_opmode
== IEEE80211_M_MONITOR
) {
1922 } else if (nstate
== IEEE80211_S_RUN
) {
1923 struct bwi_mac
*mac
;
1925 bwi_set_bssid(sc
, ic
->ic_bss
->ni_bssid
);
1927 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
1928 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
1930 /* Initial TX power calibration */
1931 bwi_mac_calibrate_txpower(mac
, BWI_TXPWR_INIT
);
1933 sc
->sc_txpwrcb_type
= BWI_TXPWR_FORCE
;
1935 sc
->sc_txpwrcb_type
= BWI_TXPWR_CALIB
;
1938 bwi_set_bssid(sc
, bwi_zero_addr
);
1942 error
= sc
->sc_newstate(ic
, nstate
, arg
);
1944 if (nstate
== IEEE80211_S_SCAN
) {
1945 callout_reset(&sc
->sc_scan_ch
,
1946 (sc
->sc_dwell_time
* hz
) / 1000,
1948 } else if (nstate
== IEEE80211_S_RUN
) {
1949 callout_reset(&sc
->sc_calib_ch
, hz
, bwi_calibrate
, sc
);
1955 bwi_media_change(struct ifnet
*ifp
)
1959 ASSERT_SERIALIZED(ifp
->if_serializer
);
1961 error
= ieee80211_media_change(ifp
);
1962 if (error
!= ENETRESET
)
1965 if ((ifp
->if_flags
& (IFF_UP
| IFF_RUNNING
)) == (IFF_UP
| IFF_RUNNING
))
1966 bwi_init(ifp
->if_softc
);
1971 bwi_dma_alloc(struct bwi_softc
*sc
)
1973 int error
, i
, has_txstats
;
1974 bus_addr_t lowaddr
= 0;
1975 bus_size_t tx_ring_sz
, rx_ring_sz
, desc_sz
= 0;
1976 uint32_t txrx_ctrl_step
= 0;
1979 for (i
= 0; i
< sc
->sc_nmac
; ++i
) {
1980 if (sc
->sc_mac
[i
].mac_flags
& BWI_MAC_F_HAS_TXSTATS
) {
1986 switch (sc
->sc_bus_space
) {
1987 case BWI_BUS_SPACE_30BIT
:
1988 case BWI_BUS_SPACE_32BIT
:
1989 if (sc
->sc_bus_space
== BWI_BUS_SPACE_30BIT
)
1990 lowaddr
= BWI_BUS_SPACE_MAXADDR
;
1992 lowaddr
= BUS_SPACE_MAXADDR_32BIT
;
1993 desc_sz
= sizeof(struct bwi_desc32
);
1994 txrx_ctrl_step
= 0x20;
1996 sc
->sc_init_tx_ring
= bwi_init_tx_ring32
;
1997 sc
->sc_free_tx_ring
= bwi_free_tx_ring32
;
1998 sc
->sc_init_rx_ring
= bwi_init_rx_ring32
;
1999 sc
->sc_free_rx_ring
= bwi_free_rx_ring32
;
2000 sc
->sc_setup_rxdesc
= bwi_setup_rx_desc32
;
2001 sc
->sc_setup_txdesc
= bwi_setup_tx_desc32
;
2002 sc
->sc_rxeof
= bwi_rxeof32
;
2003 sc
->sc_start_tx
= bwi_start_tx32
;
2005 sc
->sc_init_txstats
= bwi_init_txstats32
;
2006 sc
->sc_free_txstats
= bwi_free_txstats32
;
2007 sc
->sc_txeof_status
= bwi_txeof_status32
;
2011 case BWI_BUS_SPACE_64BIT
:
2012 lowaddr
= BUS_SPACE_MAXADDR
; /* XXX */
2013 desc_sz
= sizeof(struct bwi_desc64
);
2014 txrx_ctrl_step
= 0x40;
2016 sc
->sc_init_tx_ring
= bwi_init_tx_ring64
;
2017 sc
->sc_free_tx_ring
= bwi_free_tx_ring64
;
2018 sc
->sc_init_rx_ring
= bwi_init_rx_ring64
;
2019 sc
->sc_free_rx_ring
= bwi_free_rx_ring64
;
2020 sc
->sc_setup_rxdesc
= bwi_setup_rx_desc64
;
2021 sc
->sc_setup_txdesc
= bwi_setup_tx_desc64
;
2022 sc
->sc_rxeof
= bwi_rxeof64
;
2023 sc
->sc_start_tx
= bwi_start_tx64
;
2025 sc
->sc_init_txstats
= bwi_init_txstats64
;
2026 sc
->sc_free_txstats
= bwi_free_txstats64
;
2027 sc
->sc_txeof_status
= bwi_txeof_status64
;
2032 KKASSERT(lowaddr
!= 0);
2033 KKASSERT(desc_sz
!= 0);
2034 KKASSERT(txrx_ctrl_step
!= 0);
2036 tx_ring_sz
= roundup(desc_sz
* BWI_TX_NDESC
, BWI_RING_ALIGN
);
2037 rx_ring_sz
= roundup(desc_sz
* BWI_RX_NDESC
, BWI_RING_ALIGN
);
2040 * Create top level DMA tag
2042 error
= bus_dma_tag_create(NULL
, BWI_ALIGN
, 0,
2043 lowaddr
, BUS_SPACE_MAXADDR
,
2046 BUS_SPACE_UNRESTRICTED
,
2047 BUS_SPACE_MAXSIZE_32BIT
,
2048 0, &sc
->sc_parent_dtag
);
2050 device_printf(sc
->sc_dev
, "can't create parent DMA tag\n");
2054 #define TXRX_CTRL(idx) (BWI_TXRX_CTRL_BASE + (idx) * txrx_ctrl_step)
2057 * Create TX ring DMA stuffs
2059 error
= bus_dma_tag_create(sc
->sc_parent_dtag
, BWI_RING_ALIGN
, 0,
2060 BUS_SPACE_MAXADDR
, BUS_SPACE_MAXADDR
,
2062 tx_ring_sz
, 1, BUS_SPACE_MAXSIZE_32BIT
,
2063 0, &sc
->sc_txring_dtag
);
2065 device_printf(sc
->sc_dev
, "can't create TX ring DMA tag\n");
2069 for (i
= 0; i
< BWI_TX_NRING
; ++i
) {
2070 error
= bwi_dma_ring_alloc(sc
, sc
->sc_txring_dtag
,
2071 &sc
->sc_tx_rdata
[i
], tx_ring_sz
,
2074 device_printf(sc
->sc_dev
, "%dth TX ring "
2075 "DMA alloc failed\n", i
);
2081 * Create RX ring DMA stuffs
2083 error
= bus_dma_tag_create(sc
->sc_parent_dtag
, BWI_RING_ALIGN
, 0,
2084 BUS_SPACE_MAXADDR
, BUS_SPACE_MAXADDR
,
2086 rx_ring_sz
, 1, BUS_SPACE_MAXSIZE_32BIT
,
2087 0, &sc
->sc_rxring_dtag
);
2089 device_printf(sc
->sc_dev
, "can't create RX ring DMA tag\n");
2093 error
= bwi_dma_ring_alloc(sc
, sc
->sc_rxring_dtag
, &sc
->sc_rx_rdata
,
2094 rx_ring_sz
, TXRX_CTRL(0));
2096 device_printf(sc
->sc_dev
, "RX ring DMA alloc failed\n");
2101 error
= bwi_dma_txstats_alloc(sc
, TXRX_CTRL(3), desc_sz
);
2103 device_printf(sc
->sc_dev
,
2104 "TX stats DMA alloc failed\n");
2111 return bwi_dma_mbuf_create(sc
);
2115 bwi_dma_free(struct bwi_softc
*sc
)
2117 if (sc
->sc_txring_dtag
!= NULL
) {
2120 for (i
= 0; i
< BWI_TX_NRING
; ++i
) {
2121 struct bwi_ring_data
*rd
= &sc
->sc_tx_rdata
[i
];
2123 if (rd
->rdata_desc
!= NULL
) {
2124 bus_dmamap_unload(sc
->sc_txring_dtag
,
2126 bus_dmamem_free(sc
->sc_txring_dtag
,
2131 bus_dma_tag_destroy(sc
->sc_txring_dtag
);
2134 if (sc
->sc_rxring_dtag
!= NULL
) {
2135 struct bwi_ring_data
*rd
= &sc
->sc_rx_rdata
;
2137 if (rd
->rdata_desc
!= NULL
) {
2138 bus_dmamap_unload(sc
->sc_rxring_dtag
, rd
->rdata_dmap
);
2139 bus_dmamem_free(sc
->sc_rxring_dtag
, rd
->rdata_desc
,
2142 bus_dma_tag_destroy(sc
->sc_rxring_dtag
);
2145 bwi_dma_txstats_free(sc
);
2146 bwi_dma_mbuf_destroy(sc
, BWI_TX_NRING
, 1);
2148 if (sc
->sc_parent_dtag
!= NULL
)
2149 bus_dma_tag_destroy(sc
->sc_parent_dtag
);
2153 bwi_dma_ring_alloc(struct bwi_softc
*sc
, bus_dma_tag_t dtag
,
2154 struct bwi_ring_data
*rd
, bus_size_t size
,
2159 error
= bus_dmamem_alloc(dtag
, &rd
->rdata_desc
,
2160 BUS_DMA_WAITOK
| BUS_DMA_ZERO
,
2163 device_printf(sc
->sc_dev
, "can't allocate DMA mem\n");
2167 error
= bus_dmamap_load(dtag
, rd
->rdata_dmap
, rd
->rdata_desc
, size
,
2168 bwi_dma_ring_addr
, &rd
->rdata_paddr
,
2171 device_printf(sc
->sc_dev
, "can't load DMA mem\n");
2172 bus_dmamem_free(dtag
, rd
->rdata_desc
, rd
->rdata_dmap
);
2173 rd
->rdata_desc
= NULL
;
2177 rd
->rdata_txrx_ctrl
= txrx_ctrl
;
2182 bwi_dma_txstats_alloc(struct bwi_softc
*sc
, uint32_t ctrl_base
,
2185 struct bwi_txstats_data
*st
;
2186 bus_size_t dma_size
;
2189 st
= kmalloc(sizeof(*st
), M_DEVBUF
, M_WAITOK
| M_ZERO
);
2190 sc
->sc_txstats
= st
;
2193 * Create TX stats descriptor DMA stuffs
2195 dma_size
= roundup(desc_sz
* BWI_TXSTATS_NDESC
, BWI_RING_ALIGN
);
2197 error
= bus_dma_tag_create(sc
->sc_parent_dtag
, BWI_RING_ALIGN
, 0,
2198 BUS_SPACE_MAXADDR
, BUS_SPACE_MAXADDR
,
2200 dma_size
, 1, BUS_SPACE_MAXSIZE_32BIT
,
2201 0, &st
->stats_ring_dtag
);
2203 device_printf(sc
->sc_dev
, "can't create txstats ring "
2208 error
= bus_dmamem_alloc(st
->stats_ring_dtag
, &st
->stats_ring
,
2209 BUS_DMA_WAITOK
| BUS_DMA_ZERO
,
2210 &st
->stats_ring_dmap
);
2212 device_printf(sc
->sc_dev
, "can't allocate txstats ring "
2214 bus_dma_tag_destroy(st
->stats_ring_dtag
);
2215 st
->stats_ring_dtag
= NULL
;
2219 error
= bus_dmamap_load(st
->stats_ring_dtag
, st
->stats_ring_dmap
,
2220 st
->stats_ring
, dma_size
,
2221 bwi_dma_ring_addr
, &st
->stats_ring_paddr
,
2224 device_printf(sc
->sc_dev
, "can't load txstats ring DMA mem\n");
2225 bus_dmamem_free(st
->stats_ring_dtag
, st
->stats_ring
,
2226 st
->stats_ring_dmap
);
2227 bus_dma_tag_destroy(st
->stats_ring_dtag
);
2228 st
->stats_ring_dtag
= NULL
;
2233 * Create TX stats DMA stuffs
2235 dma_size
= roundup(sizeof(struct bwi_txstats
) * BWI_TXSTATS_NDESC
,
2238 error
= bus_dma_tag_create(sc
->sc_parent_dtag
, BWI_ALIGN
, 0,
2239 BUS_SPACE_MAXADDR
, BUS_SPACE_MAXADDR
,
2241 dma_size
, 1, BUS_SPACE_MAXSIZE_32BIT
,
2242 0, &st
->stats_dtag
);
2244 device_printf(sc
->sc_dev
, "can't create txstats DMA tag\n");
2248 error
= bus_dmamem_alloc(st
->stats_dtag
, (void **)&st
->stats
,
2249 BUS_DMA_WAITOK
| BUS_DMA_ZERO
,
2252 device_printf(sc
->sc_dev
, "can't allocate txstats DMA mem\n");
2253 bus_dma_tag_destroy(st
->stats_dtag
);
2254 st
->stats_dtag
= NULL
;
2258 error
= bus_dmamap_load(st
->stats_dtag
, st
->stats_dmap
, st
->stats
,
2259 dma_size
, bwi_dma_ring_addr
, &st
->stats_paddr
,
2262 device_printf(sc
->sc_dev
, "can't load txstats DMA mem\n");
2263 bus_dmamem_free(st
->stats_dtag
, st
->stats
, st
->stats_dmap
);
2264 bus_dma_tag_destroy(st
->stats_dtag
);
2265 st
->stats_dtag
= NULL
;
2269 st
->stats_ctrl_base
= ctrl_base
;
2274 bwi_dma_txstats_free(struct bwi_softc
*sc
)
2276 struct bwi_txstats_data
*st
;
2278 if (sc
->sc_txstats
== NULL
)
2280 st
= sc
->sc_txstats
;
2282 if (st
->stats_ring_dtag
!= NULL
) {
2283 bus_dmamap_unload(st
->stats_ring_dtag
, st
->stats_ring_dmap
);
2284 bus_dmamem_free(st
->stats_ring_dtag
, st
->stats_ring
,
2285 st
->stats_ring_dmap
);
2286 bus_dma_tag_destroy(st
->stats_ring_dtag
);
2289 if (st
->stats_dtag
!= NULL
) {
2290 bus_dmamap_unload(st
->stats_dtag
, st
->stats_dmap
);
2291 bus_dmamem_free(st
->stats_dtag
, st
->stats
, st
->stats_dmap
);
2292 bus_dma_tag_destroy(st
->stats_dtag
);
2295 kfree(st
, M_DEVBUF
);
2299 bwi_dma_ring_addr(void *arg
, bus_dma_segment_t
*seg
, int nseg
, int error
)
2301 KASSERT(nseg
== 1, ("too many segments\n"));
2302 *((bus_addr_t
*)arg
) = seg
->ds_addr
;
2306 bwi_dma_mbuf_create(struct bwi_softc
*sc
)
2308 struct bwi_rxbuf_data
*rbd
= &sc
->sc_rx_bdata
;
2309 int i
, j
, k
, ntx
, error
;
2312 * Create TX/RX mbuf DMA tag
2314 error
= bus_dma_tag_create(sc
->sc_parent_dtag
, 1, 0,
2315 BUS_SPACE_MAXADDR
, BUS_SPACE_MAXADDR
,
2316 NULL
, NULL
, MCLBYTES
, 1,
2317 BUS_SPACE_MAXSIZE_32BIT
,
2318 0, &sc
->sc_buf_dtag
);
2320 device_printf(sc
->sc_dev
, "can't create mbuf DMA tag\n");
2327 * Create TX mbuf DMA map
2329 for (i
= 0; i
< BWI_TX_NRING
; ++i
) {
2330 struct bwi_txbuf_data
*tbd
= &sc
->sc_tx_bdata
[i
];
2332 for (j
= 0; j
< BWI_TX_NDESC
; ++j
) {
2333 error
= bus_dmamap_create(sc
->sc_buf_dtag
, 0,
2334 &tbd
->tbd_buf
[j
].tb_dmap
);
2336 device_printf(sc
->sc_dev
, "can't create "
2337 "%dth tbd, %dth DMA map\n", i
, j
);
2340 for (k
= 0; k
< j
; ++k
) {
2341 bus_dmamap_destroy(sc
->sc_buf_dtag
,
2342 tbd
->tbd_buf
[k
].tb_dmap
);
2351 * Create RX mbuf DMA map and a spare DMA map
2353 error
= bus_dmamap_create(sc
->sc_buf_dtag
, 0,
2354 &rbd
->rbd_tmp_dmap
);
2356 device_printf(sc
->sc_dev
,
2357 "can't create spare RX buf DMA map\n");
2361 for (j
= 0; j
< BWI_RX_NDESC
; ++j
) {
2362 error
= bus_dmamap_create(sc
->sc_buf_dtag
, 0,
2363 &rbd
->rbd_buf
[j
].rb_dmap
);
2365 device_printf(sc
->sc_dev
, "can't create %dth "
2366 "RX buf DMA map\n", j
);
2368 for (k
= 0; k
< j
; ++k
) {
2369 bus_dmamap_destroy(sc
->sc_buf_dtag
,
2370 rbd
->rbd_buf
[j
].rb_dmap
);
2372 bus_dmamap_destroy(sc
->sc_buf_dtag
,
2380 bwi_dma_mbuf_destroy(sc
, ntx
, 0);
2385 bwi_dma_mbuf_destroy(struct bwi_softc
*sc
, int ntx
, int nrx
)
2389 if (sc
->sc_buf_dtag
== NULL
)
2392 for (i
= 0; i
< ntx
; ++i
) {
2393 struct bwi_txbuf_data
*tbd
= &sc
->sc_tx_bdata
[i
];
2395 for (j
= 0; j
< BWI_TX_NDESC
; ++j
) {
2396 struct bwi_txbuf
*tb
= &tbd
->tbd_buf
[j
];
2398 if (tb
->tb_mbuf
!= NULL
) {
2399 bus_dmamap_unload(sc
->sc_buf_dtag
,
2401 m_freem(tb
->tb_mbuf
);
2403 if (tb
->tb_ni
!= NULL
)
2404 ieee80211_free_node(tb
->tb_ni
);
2405 bus_dmamap_destroy(sc
->sc_buf_dtag
, tb
->tb_dmap
);
2410 struct bwi_rxbuf_data
*rbd
= &sc
->sc_rx_bdata
;
2412 bus_dmamap_destroy(sc
->sc_buf_dtag
, rbd
->rbd_tmp_dmap
);
2413 for (j
= 0; j
< BWI_RX_NDESC
; ++j
) {
2414 struct bwi_rxbuf
*rb
= &rbd
->rbd_buf
[j
];
2416 if (rb
->rb_mbuf
!= NULL
) {
2417 bus_dmamap_unload(sc
->sc_buf_dtag
,
2419 m_freem(rb
->rb_mbuf
);
2421 bus_dmamap_destroy(sc
->sc_buf_dtag
, rb
->rb_dmap
);
2425 bus_dma_tag_destroy(sc
->sc_buf_dtag
);
2426 sc
->sc_buf_dtag
= NULL
;
2430 bwi_enable_intrs(struct bwi_softc
*sc
, uint32_t enable_intrs
)
2432 CSR_SETBITS_4(sc
, BWI_MAC_INTR_MASK
, enable_intrs
);
2436 bwi_disable_intrs(struct bwi_softc
*sc
, uint32_t disable_intrs
)
2438 CSR_CLRBITS_4(sc
, BWI_MAC_INTR_MASK
, disable_intrs
);
2442 bwi_init_tx_ring32(struct bwi_softc
*sc
, int ring_idx
)
2444 struct bwi_ring_data
*rd
;
2445 struct bwi_txbuf_data
*tbd
;
2446 uint32_t val
, addr_hi
, addr_lo
;
2448 KKASSERT(ring_idx
< BWI_TX_NRING
);
2449 rd
= &sc
->sc_tx_rdata
[ring_idx
];
2450 tbd
= &sc
->sc_tx_bdata
[ring_idx
];
2455 bzero(rd
->rdata_desc
, sizeof(struct bwi_desc32
) * BWI_TX_NDESC
);
2456 bus_dmamap_sync(sc
->sc_txring_dtag
, rd
->rdata_dmap
,
2457 BUS_DMASYNC_PREWRITE
);
2459 addr_lo
= __SHIFTOUT(rd
->rdata_paddr
, BWI_TXRX32_RINGINFO_ADDR_MASK
);
2460 addr_hi
= __SHIFTOUT(rd
->rdata_paddr
, BWI_TXRX32_RINGINFO_FUNC_MASK
);
2462 val
= __SHIFTIN(addr_lo
, BWI_TXRX32_RINGINFO_ADDR_MASK
) |
2463 __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX
,
2464 BWI_TXRX32_RINGINFO_FUNC_MASK
);
2465 CSR_WRITE_4(sc
, rd
->rdata_txrx_ctrl
+ BWI_TX32_RINGINFO
, val
);
2467 val
= __SHIFTIN(addr_hi
, BWI_TXRX32_CTRL_ADDRHI_MASK
) |
2468 BWI_TXRX32_CTRL_ENABLE
;
2469 CSR_WRITE_4(sc
, rd
->rdata_txrx_ctrl
+ BWI_TX32_CTRL
, val
);
2475 bwi_init_rxdesc_ring32(struct bwi_softc
*sc
, uint32_t ctrl_base
,
2476 bus_addr_t paddr
, int hdr_size
, int ndesc
)
2478 uint32_t val
, addr_hi
, addr_lo
;
2480 addr_lo
= __SHIFTOUT(paddr
, BWI_TXRX32_RINGINFO_ADDR_MASK
);
2481 addr_hi
= __SHIFTOUT(paddr
, BWI_TXRX32_RINGINFO_FUNC_MASK
);
2483 val
= __SHIFTIN(addr_lo
, BWI_TXRX32_RINGINFO_ADDR_MASK
) |
2484 __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX
,
2485 BWI_TXRX32_RINGINFO_FUNC_MASK
);
2486 CSR_WRITE_4(sc
, ctrl_base
+ BWI_RX32_RINGINFO
, val
);
2488 val
= __SHIFTIN(hdr_size
, BWI_RX32_CTRL_HDRSZ_MASK
) |
2489 __SHIFTIN(addr_hi
, BWI_TXRX32_CTRL_ADDRHI_MASK
) |
2490 BWI_TXRX32_CTRL_ENABLE
;
2491 CSR_WRITE_4(sc
, ctrl_base
+ BWI_RX32_CTRL
, val
);
2493 CSR_WRITE_4(sc
, ctrl_base
+ BWI_RX32_INDEX
,
2494 (ndesc
- 1) * sizeof(struct bwi_desc32
));
2498 bwi_init_rx_ring32(struct bwi_softc
*sc
)
2500 struct bwi_ring_data
*rd
= &sc
->sc_rx_rdata
;
2503 sc
->sc_rx_bdata
.rbd_idx
= 0;
2505 for (i
= 0; i
< BWI_RX_NDESC
; ++i
) {
2506 error
= bwi_newbuf(sc
, i
, 1);
2508 if_printf(&sc
->sc_ic
.ic_if
,
2509 "can't allocate %dth RX buffer\n", i
);
2513 bus_dmamap_sync(sc
->sc_rxring_dtag
, rd
->rdata_dmap
,
2514 BUS_DMASYNC_PREWRITE
);
2516 bwi_init_rxdesc_ring32(sc
, rd
->rdata_txrx_ctrl
, rd
->rdata_paddr
,
2517 sizeof(struct bwi_rxbuf_hdr
), BWI_RX_NDESC
);
2522 bwi_init_txstats32(struct bwi_softc
*sc
)
2524 struct bwi_txstats_data
*st
= sc
->sc_txstats
;
2525 bus_addr_t stats_paddr
;
2528 bzero(st
->stats
, BWI_TXSTATS_NDESC
* sizeof(struct bwi_txstats
));
2529 bus_dmamap_sync(st
->stats_dtag
, st
->stats_dmap
, BUS_DMASYNC_PREWRITE
);
2533 stats_paddr
= st
->stats_paddr
;
2534 for (i
= 0; i
< BWI_TXSTATS_NDESC
; ++i
) {
2535 bwi_setup_desc32(sc
, st
->stats_ring
, BWI_TXSTATS_NDESC
, i
,
2536 stats_paddr
, sizeof(struct bwi_txstats
), 0);
2537 stats_paddr
+= sizeof(struct bwi_txstats
);
2539 bus_dmamap_sync(st
->stats_ring_dtag
, st
->stats_ring_dmap
,
2540 BUS_DMASYNC_PREWRITE
);
2542 bwi_init_rxdesc_ring32(sc
, st
->stats_ctrl_base
,
2543 st
->stats_ring_paddr
, 0, BWI_TXSTATS_NDESC
);
2548 bwi_setup_rx_desc32(struct bwi_softc
*sc
, int buf_idx
, bus_addr_t paddr
,
2551 struct bwi_ring_data
*rd
= &sc
->sc_rx_rdata
;
2553 KKASSERT(buf_idx
< BWI_RX_NDESC
);
2554 bwi_setup_desc32(sc
, rd
->rdata_desc
, BWI_RX_NDESC
, buf_idx
,
2559 bwi_setup_tx_desc32(struct bwi_softc
*sc
, struct bwi_ring_data
*rd
,
2560 int buf_idx
, bus_addr_t paddr
, int buf_len
)
2562 KKASSERT(buf_idx
< BWI_TX_NDESC
);
2563 bwi_setup_desc32(sc
, rd
->rdata_desc
, BWI_TX_NDESC
, buf_idx
,
2568 bwi_init_tx_ring64(struct bwi_softc
*sc
, int ring_idx
)
2575 bwi_init_rx_ring64(struct bwi_softc
*sc
)
2582 bwi_init_txstats64(struct bwi_softc
*sc
)
2589 bwi_setup_rx_desc64(struct bwi_softc
*sc
, int buf_idx
, bus_addr_t paddr
,
2596 bwi_setup_tx_desc64(struct bwi_softc
*sc
, struct bwi_ring_data
*rd
,
2597 int buf_idx
, bus_addr_t paddr
, int buf_len
)
2603 bwi_dma_buf_addr(void *arg
, bus_dma_segment_t
*seg
, int nseg
,
2604 bus_size_t mapsz __unused
, int error
)
2607 KASSERT(nseg
== 1, ("too many segments(%d)\n", nseg
));
2608 *((bus_addr_t
*)arg
) = seg
->ds_addr
;
2613 bwi_newbuf(struct bwi_softc
*sc
, int buf_idx
, int init
)
2615 struct bwi_rxbuf_data
*rbd
= &sc
->sc_rx_bdata
;
2616 struct bwi_rxbuf
*rxbuf
= &rbd
->rbd_buf
[buf_idx
];
2617 struct bwi_rxbuf_hdr
*hdr
;
2623 KKASSERT(buf_idx
< BWI_RX_NDESC
);
2625 m
= m_getcl(init
? MB_WAIT
: MB_DONTWAIT
, MT_DATA
, M_PKTHDR
);
2630 * If the NIC is up and running, we need to:
2631 * - Clear RX buffer's header.
2632 * - Restore RX descriptor settings.
2639 m
->m_len
= m
->m_pkthdr
.len
= MCLBYTES
;
2642 * Try to load RX buf into temporary DMA map
2644 error
= bus_dmamap_load_mbuf(sc
->sc_buf_dtag
, rbd
->rbd_tmp_dmap
, m
,
2645 bwi_dma_buf_addr
, &paddr
,
2646 init
? BUS_DMA_WAITOK
: BUS_DMA_NOWAIT
);
2651 * See the comment above
2660 bus_dmamap_unload(sc
->sc_buf_dtag
, rxbuf
->rb_dmap
);
2662 rxbuf
->rb_paddr
= paddr
;
2665 * Swap RX buf's DMA map with the loaded temporary one
2667 map
= rxbuf
->rb_dmap
;
2668 rxbuf
->rb_dmap
= rbd
->rbd_tmp_dmap
;
2669 rbd
->rbd_tmp_dmap
= map
;
2673 * Clear RX buf header
2675 hdr
= mtod(rxbuf
->rb_mbuf
, struct bwi_rxbuf_hdr
*);
2676 bzero(hdr
, sizeof(*hdr
));
2677 bus_dmamap_sync(sc
->sc_buf_dtag
, rxbuf
->rb_dmap
, BUS_DMASYNC_PREWRITE
);
2680 * Setup RX buf descriptor
2682 sc
->sc_setup_rxdesc(sc
, buf_idx
, rxbuf
->rb_paddr
,
2683 rxbuf
->rb_mbuf
->m_len
- sizeof(*hdr
));
2688 bwi_set_addr_filter(struct bwi_softc
*sc
, uint16_t addr_ofs
,
2689 const uint8_t *addr
)
2693 CSR_WRITE_2(sc
, BWI_ADDR_FILTER_CTRL
,
2694 BWI_ADDR_FILTER_CTRL_SET
| addr_ofs
);
2696 for (i
= 0; i
< (IEEE80211_ADDR_LEN
/ 2); ++i
) {
2699 addr_val
= (uint16_t)addr
[i
* 2] |
2700 (((uint16_t)addr
[(i
* 2) + 1]) << 8);
2701 CSR_WRITE_2(sc
, BWI_ADDR_FILTER_DATA
, addr_val
);
2706 bwi_set_chan(struct bwi_softc
*sc
, struct ieee80211_channel
*c
)
2708 struct ieee80211com
*ic
= &sc
->sc_ic
;
2709 struct ifnet
*ifp
= &ic
->ic_if
;
2710 struct bwi_mac
*mac
;
2714 ASSERT_SERIALIZED(ifp
->if_serializer
);
2716 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
2717 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
2719 chan
= ieee80211_chan2ieee(ic
, c
);
2721 bwi_rf_set_chan(mac
, chan
, 0);
2724 * Setup radio tap channel freq and flags
2726 if (IEEE80211_IS_CHAN_G(c
))
2727 flags
= IEEE80211_CHAN_G
;
2729 flags
= IEEE80211_CHAN_B
;
2731 sc
->sc_tx_th
.wt_chan_freq
= sc
->sc_rx_th
.wr_chan_freq
=
2732 htole16(c
->ic_freq
);
2733 sc
->sc_tx_th
.wt_chan_flags
= sc
->sc_rx_th
.wr_chan_flags
=
2740 bwi_next_scan(void *xsc
)
2742 struct bwi_softc
*sc
= xsc
;
2743 struct ieee80211com
*ic
= &sc
->sc_ic
;
2744 struct ifnet
*ifp
= &ic
->ic_if
;
2746 lwkt_serialize_enter(ifp
->if_serializer
);
2748 if (ic
->ic_state
== IEEE80211_S_SCAN
)
2749 ieee80211_next_scan(ic
);
2751 lwkt_serialize_exit(ifp
->if_serializer
);
2755 bwi_rxeof(struct bwi_softc
*sc
, int end_idx
)
2757 struct bwi_ring_data
*rd
= &sc
->sc_rx_rdata
;
2758 struct bwi_rxbuf_data
*rbd
= &sc
->sc_rx_bdata
;
2759 struct ieee80211com
*ic
= &sc
->sc_ic
;
2760 struct ifnet
*ifp
= &ic
->ic_if
;
2761 int idx
, rx_data
= 0;
2764 while (idx
!= end_idx
) {
2765 struct bwi_rxbuf
*rb
= &rbd
->rbd_buf
[idx
];
2766 struct bwi_rxbuf_hdr
*hdr
;
2767 struct ieee80211_frame_min
*wh
;
2768 struct ieee80211_node
*ni
;
2772 int buflen
, wh_ofs
, hdr_extra
, rssi
, type
, rate
;
2775 bus_dmamap_sync(sc
->sc_buf_dtag
, rb
->rb_dmap
,
2776 BUS_DMASYNC_POSTREAD
);
2778 if (bwi_newbuf(sc
, idx
, 0)) {
2783 hdr
= mtod(m
, struct bwi_rxbuf_hdr
*);
2784 flags2
= le16toh(hdr
->rxh_flags2
);
2787 if (flags2
& BWI_RXH_F2_TYPE2FRAME
)
2789 wh_ofs
= hdr_extra
+ 6; /* XXX magic number */
2791 buflen
= le16toh(hdr
->rxh_buflen
);
2792 if (buflen
< BWI_FRAME_MIN_LEN(wh_ofs
)) {
2793 if_printf(ifp
, "short frame %d, hdr_extra %d\n",
2800 plcp
= ((const uint8_t *)(hdr
+ 1) + hdr_extra
);
2801 rssi
= bwi_calc_rssi(sc
, hdr
);
2803 m
->m_pkthdr
.rcvif
= ifp
;
2804 m
->m_len
= m
->m_pkthdr
.len
= buflen
+ sizeof(*hdr
);
2805 m_adj(m
, sizeof(*hdr
) + wh_ofs
);
2807 if (htole16(hdr
->rxh_flags1
) & BWI_RXH_F1_OFDM
)
2808 rate
= bwi_ofdm_plcp2rate(plcp
);
2810 rate
= bwi_ds_plcp2rate(plcp
);
2813 if (sc
->sc_drvbpf
!= NULL
)
2814 bwi_rx_radiotap(sc
, m
, hdr
, plcp
, rate
, rssi
);
2816 m_adj(m
, -IEEE80211_CRC_LEN
);
2818 wh
= mtod(m
, struct ieee80211_frame_min
*);
2819 ni
= ieee80211_find_rxnode(ic
, wh
);
2821 type
= ieee80211_input(ic
, m
, ni
, rssi
- BWI_NOISE_FLOOR
,
2822 le16toh(hdr
->rxh_tsf
));
2823 ieee80211_free_node(ni
);
2825 if (type
== IEEE80211_FC0_TYPE_DATA
) {
2827 sc
->sc_rx_rate
= rate
;
2830 idx
= (idx
+ 1) % BWI_RX_NDESC
;
2834 bus_dmamap_sync(sc
->sc_rxring_dtag
, rd
->rdata_dmap
,
2835 BUS_DMASYNC_PREWRITE
);
2840 bwi_rxeof32(struct bwi_softc
*sc
)
2842 uint32_t val
, rx_ctrl
;
2843 int end_idx
, rx_data
;
2845 rx_ctrl
= sc
->sc_rx_rdata
.rdata_txrx_ctrl
;
2847 val
= CSR_READ_4(sc
, rx_ctrl
+ BWI_RX32_STATUS
);
2848 end_idx
= __SHIFTOUT(val
, BWI_RX32_STATUS_INDEX_MASK
) /
2849 sizeof(struct bwi_desc32
);
2851 rx_data
= bwi_rxeof(sc
, end_idx
);
2853 CSR_WRITE_4(sc
, rx_ctrl
+ BWI_RX32_INDEX
,
2854 end_idx
* sizeof(struct bwi_desc32
));
2860 bwi_rxeof64(struct bwi_softc
*sc
)
2867 bwi_reset_rx_ring32(struct bwi_softc
*sc
, uint32_t rx_ctrl
)
2871 CSR_WRITE_4(sc
, rx_ctrl
+ BWI_RX32_CTRL
, 0);
2875 for (i
= 0; i
< NRETRY
; ++i
) {
2878 status
= CSR_READ_4(sc
, rx_ctrl
+ BWI_RX32_STATUS
);
2879 if (__SHIFTOUT(status
, BWI_RX32_STATUS_STATE_MASK
) ==
2880 BWI_RX32_STATUS_STATE_DISABLED
)
2886 if_printf(&sc
->sc_ic
.ic_if
, "reset rx ring timedout\n");
2890 CSR_WRITE_4(sc
, rx_ctrl
+ BWI_RX32_RINGINFO
, 0);
2894 bwi_free_txstats32(struct bwi_softc
*sc
)
2896 bwi_reset_rx_ring32(sc
, sc
->sc_txstats
->stats_ctrl_base
);
2900 bwi_free_rx_ring32(struct bwi_softc
*sc
)
2902 struct bwi_ring_data
*rd
= &sc
->sc_rx_rdata
;
2903 struct bwi_rxbuf_data
*rbd
= &sc
->sc_rx_bdata
;
2906 bwi_reset_rx_ring32(sc
, rd
->rdata_txrx_ctrl
);
2908 for (i
= 0; i
< BWI_RX_NDESC
; ++i
) {
2909 struct bwi_rxbuf
*rb
= &rbd
->rbd_buf
[i
];
2911 if (rb
->rb_mbuf
!= NULL
) {
2912 bus_dmamap_unload(sc
->sc_buf_dtag
, rb
->rb_dmap
);
2913 m_freem(rb
->rb_mbuf
);
2920 bwi_free_tx_ring32(struct bwi_softc
*sc
, int ring_idx
)
2922 struct bwi_ring_data
*rd
;
2923 struct bwi_txbuf_data
*tbd
;
2924 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
2925 uint32_t state
, val
;
2928 KKASSERT(ring_idx
< BWI_TX_NRING
);
2929 rd
= &sc
->sc_tx_rdata
[ring_idx
];
2930 tbd
= &sc
->sc_tx_bdata
[ring_idx
];
2934 for (i
= 0; i
< NRETRY
; ++i
) {
2935 val
= CSR_READ_4(sc
, rd
->rdata_txrx_ctrl
+ BWI_TX32_STATUS
);
2936 state
= __SHIFTOUT(val
, BWI_TX32_STATUS_STATE_MASK
);
2937 if (state
== BWI_TX32_STATUS_STATE_DISABLED
||
2938 state
== BWI_TX32_STATUS_STATE_IDLE
||
2939 state
== BWI_TX32_STATUS_STATE_STOPPED
)
2945 if_printf(ifp
, "wait for TX ring(%d) stable timed out\n",
2949 CSR_WRITE_4(sc
, rd
->rdata_txrx_ctrl
+ BWI_TX32_CTRL
, 0);
2950 for (i
= 0; i
< NRETRY
; ++i
) {
2951 val
= CSR_READ_4(sc
, rd
->rdata_txrx_ctrl
+ BWI_TX32_STATUS
);
2952 state
= __SHIFTOUT(val
, BWI_TX32_STATUS_STATE_MASK
);
2953 if (state
== BWI_TX32_STATUS_STATE_DISABLED
)
2959 if_printf(ifp
, "reset TX ring (%d) timed out\n", ring_idx
);
2965 CSR_WRITE_4(sc
, rd
->rdata_txrx_ctrl
+ BWI_TX32_RINGINFO
, 0);
2967 for (i
= 0; i
< BWI_TX_NDESC
; ++i
) {
2968 struct bwi_txbuf
*tb
= &tbd
->tbd_buf
[i
];
2970 if (tb
->tb_mbuf
!= NULL
) {
2971 bus_dmamap_unload(sc
->sc_buf_dtag
, tb
->tb_dmap
);
2972 m_freem(tb
->tb_mbuf
);
2975 if (tb
->tb_ni
!= NULL
) {
2976 ieee80211_free_node(tb
->tb_ni
);
2983 bwi_free_txstats64(struct bwi_softc
*sc
)
2989 bwi_free_rx_ring64(struct bwi_softc
*sc
)
2995 bwi_free_tx_ring64(struct bwi_softc
*sc
, int ring_idx
)
3001 bwi_encap(struct bwi_softc
*sc
, int idx
, struct mbuf
*m
,
3002 struct ieee80211_node
**ni0
, int mgt_pkt
)
3004 struct ieee80211com
*ic
= &sc
->sc_ic
;
3005 struct ieee80211_node
*ni
= *ni0
;
3006 struct bwi_ring_data
*rd
= &sc
->sc_tx_rdata
[BWI_TX_DATA_RING
];
3007 struct bwi_txbuf_data
*tbd
= &sc
->sc_tx_bdata
[BWI_TX_DATA_RING
];
3008 struct bwi_txbuf
*tb
= &tbd
->tbd_buf
[idx
];
3009 struct bwi_mac
*mac
;
3010 struct bwi_txbuf_hdr
*hdr
;
3011 struct ieee80211_frame
*wh
;
3012 uint8_t rate
, rate_fb
;
3016 int pkt_len
, error
, mcast_pkt
= 0;
3022 KKASSERT(ni
!= NULL
);
3023 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
3024 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
3026 wh
= mtod(m
, struct ieee80211_frame
*);
3028 /* Get 802.11 frame len before prepending TX header */
3029 pkt_len
= m
->m_pkthdr
.len
+ IEEE80211_CRC_LEN
;
3034 bzero(tb
->tb_rateidx
, sizeof(tb
->tb_rateidx
));
3036 if (ic
->ic_fixed_rate
!= IEEE80211_FIXED_RATE_NONE
) {
3039 rate
= IEEE80211_RS_RATE(&ni
->ni_rates
,
3042 if (ic
->ic_fixed_rate
>= 1)
3043 idx
= ic
->ic_fixed_rate
- 1;
3046 rate_fb
= IEEE80211_RS_RATE(&ni
->ni_rates
, idx
);
3048 tb
->tb_rateidx_cnt
= ieee80211_ratectl_findrate(ni
,
3049 m
->m_pkthdr
.len
, tb
->tb_rateidx
, BWI_NTXRATE
);
3051 rate
= IEEE80211_RS_RATE(&ni
->ni_rates
,
3053 if (tb
->tb_rateidx_cnt
== BWI_NTXRATE
) {
3054 rate_fb
= IEEE80211_RS_RATE(&ni
->ni_rates
,
3059 tb
->tb_buflen
= m
->m_pkthdr
.len
;
3062 /* Fixed at 1Mbits/s for mgt frames */
3063 rate
= rate_fb
= (1 * 2);
3066 if (IEEE80211_IS_MULTICAST(wh
->i_addr1
)) {
3067 rate
= rate_fb
= ic
->ic_mcast_rate
;
3071 if (rate
== 0 || rate_fb
== 0) {
3072 /* XXX this should not happen */
3073 if_printf(&ic
->ic_if
, "invalid rate %u or fallback rate %u",
3075 rate
= rate_fb
= (1 * 2); /* Force 1Mbits/s */
3077 sc
->sc_tx_rate
= rate
;
3082 if (sc
->sc_drvbpf
!= NULL
) {
3083 sc
->sc_tx_th
.wt_flags
= 0;
3084 if (wh
->i_fc
[1] & IEEE80211_FC1_WEP
)
3085 sc
->sc_tx_th
.wt_flags
|= IEEE80211_RADIOTAP_F_WEP
;
3086 if (ieee80211_rate2modtype(rate
) == IEEE80211_MODTYPE_DS
&&
3087 (ic
->ic_flags
& IEEE80211_F_SHPREAMBLE
) &&
3089 sc
->sc_tx_th
.wt_flags
|= IEEE80211_RADIOTAP_F_SHORTPRE
;
3091 sc
->sc_tx_th
.wt_rate
= rate
;
3093 bpf_ptap(sc
->sc_drvbpf
, m
, &sc
->sc_tx_th
, sc
->sc_tx_th_len
);
3097 * Setup the embedded TX header
3099 M_PREPEND(m
, sizeof(*hdr
), MB_DONTWAIT
);
3101 if_printf(&ic
->ic_if
, "prepend TX header failed\n");
3104 hdr
= mtod(m
, struct bwi_txbuf_hdr
*);
3106 bzero(hdr
, sizeof(*hdr
));
3108 bcopy(wh
->i_fc
, hdr
->txh_fc
, sizeof(hdr
->txh_fc
));
3109 bcopy(wh
->i_addr1
, hdr
->txh_addr1
, sizeof(hdr
->txh_addr1
));
3115 ack_rate
= ieee80211_ack_rate(ni
, rate_fb
);
3116 dur
= ieee80211_txtime(ni
,
3117 sizeof(struct ieee80211_frame_ack
) + IEEE80211_CRC_LEN
,
3118 ack_rate
, ic
->ic_flags
& IEEE80211_F_SHPREAMBLE
);
3120 hdr
->txh_fb_duration
= htole16(dur
);
3123 hdr
->txh_id
= __SHIFTIN(BWI_TX_DATA_RING
, BWI_TXH_ID_RING_MASK
) |
3124 __SHIFTIN(idx
, BWI_TXH_ID_IDX_MASK
);
3126 bwi_plcp_header(hdr
->txh_plcp
, pkt_len
, rate
);
3127 bwi_plcp_header(hdr
->txh_fb_plcp
, pkt_len
, rate_fb
);
3129 phy_ctrl
= __SHIFTIN(mac
->mac_rf
.rf_ant_mode
,
3130 BWI_TXH_PHY_C_ANTMODE_MASK
);
3131 if (ieee80211_rate2modtype(rate
) == IEEE80211_MODTYPE_OFDM
)
3132 phy_ctrl
|= BWI_TXH_PHY_C_OFDM
;
3133 else if ((ic
->ic_flags
& IEEE80211_F_SHPREAMBLE
) && rate
!= (2 * 1))
3134 phy_ctrl
|= BWI_TXH_PHY_C_SHPREAMBLE
;
3136 mac_ctrl
= BWI_TXH_MAC_C_HWSEQ
| BWI_TXH_MAC_C_FIRST_FRAG
;
3137 if (!IEEE80211_IS_MULTICAST(wh
->i_addr1
))
3138 mac_ctrl
|= BWI_TXH_MAC_C_ACK
;
3139 if (ieee80211_rate2modtype(rate_fb
) == IEEE80211_MODTYPE_OFDM
)
3140 mac_ctrl
|= BWI_TXH_MAC_C_FB_OFDM
;
3142 hdr
->txh_mac_ctrl
= htole32(mac_ctrl
);
3143 hdr
->txh_phy_ctrl
= htole16(phy_ctrl
);
3145 /* Catch any further usage */
3150 error
= bus_dmamap_load_mbuf(sc
->sc_buf_dtag
, tb
->tb_dmap
, m
,
3151 bwi_dma_buf_addr
, &paddr
, BUS_DMA_NOWAIT
);
3152 if (error
&& error
!= EFBIG
) {
3153 if_printf(&ic
->ic_if
, "can't load TX buffer (1) %d\n", error
);
3157 if (error
) { /* error == EFBIG */
3160 m_new
= m_defrag(m
, MB_DONTWAIT
);
3161 if (m_new
== NULL
) {
3162 if_printf(&ic
->ic_if
, "can't defrag TX buffer\n");
3169 error
= bus_dmamap_load_mbuf(sc
->sc_buf_dtag
, tb
->tb_dmap
, m
,
3170 bwi_dma_buf_addr
, &paddr
,
3173 if_printf(&ic
->ic_if
, "can't load TX buffer (2) %d\n",
3180 bus_dmamap_sync(sc
->sc_buf_dtag
, tb
->tb_dmap
, BUS_DMASYNC_PREWRITE
);
3182 if (mgt_pkt
|| mcast_pkt
) {
3183 /* Don't involve mcast/mgt packets into TX rate control */
3184 ieee80211_free_node(ni
);
3191 p
= mtod(m
, const uint8_t *);
3192 for (i
= 0; i
< m
->m_pkthdr
.len
; ++i
) {
3193 if (i
!= 0 && i
% 8 == 0)
3195 kprintf("%02x ", p
[i
]);
3200 DPRINTF(sc
, BWI_DBG_TX
, "idx %d, pkt_len %d, buflen %d\n",
3201 idx
, pkt_len
, m
->m_pkthdr
.len
);
3203 /* Setup TX descriptor */
3204 sc
->sc_setup_txdesc(sc
, rd
, idx
, paddr
, m
->m_pkthdr
.len
);
3205 bus_dmamap_sync(sc
->sc_txring_dtag
, rd
->rdata_dmap
,
3206 BUS_DMASYNC_PREWRITE
);
3209 sc
->sc_start_tx(sc
, rd
->rdata_txrx_ctrl
, idx
);
3218 bwi_start_tx32(struct bwi_softc
*sc
, uint32_t tx_ctrl
, int idx
)
3220 idx
= (idx
+ 1) % BWI_TX_NDESC
;
3221 CSR_WRITE_4(sc
, tx_ctrl
+ BWI_TX32_INDEX
,
3222 idx
* sizeof(struct bwi_desc32
));
3226 bwi_start_tx64(struct bwi_softc
*sc
, uint32_t tx_ctrl
, int idx
)
3232 bwi_txeof_status32(struct bwi_softc
*sc
)
3234 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
3235 uint32_t val
, ctrl_base
;
3238 ctrl_base
= sc
->sc_txstats
->stats_ctrl_base
;
3240 val
= CSR_READ_4(sc
, ctrl_base
+ BWI_RX32_STATUS
);
3241 end_idx
= __SHIFTOUT(val
, BWI_RX32_STATUS_INDEX_MASK
) /
3242 sizeof(struct bwi_desc32
);
3244 bwi_txeof_status(sc
, end_idx
);
3246 CSR_WRITE_4(sc
, ctrl_base
+ BWI_RX32_INDEX
,
3247 end_idx
* sizeof(struct bwi_desc32
));
3249 if ((ifp
->if_flags
& IFF_OACTIVE
) == 0)
3254 bwi_txeof_status64(struct bwi_softc
*sc
)
3260 _bwi_txeof(struct bwi_softc
*sc
, uint16_t tx_id
, int acked
, int data_txcnt
)
3262 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
3263 struct bwi_txbuf_data
*tbd
;
3264 struct bwi_txbuf
*tb
;
3265 int ring_idx
, buf_idx
;
3268 if_printf(ifp
, "zero tx id\n");
3272 ring_idx
= __SHIFTOUT(tx_id
, BWI_TXH_ID_RING_MASK
);
3273 buf_idx
= __SHIFTOUT(tx_id
, BWI_TXH_ID_IDX_MASK
);
3275 KKASSERT(ring_idx
== BWI_TX_DATA_RING
);
3276 KKASSERT(buf_idx
< BWI_TX_NDESC
);
3278 tbd
= &sc
->sc_tx_bdata
[ring_idx
];
3279 KKASSERT(tbd
->tbd_used
> 0);
3282 tb
= &tbd
->tbd_buf
[buf_idx
];
3284 DPRINTF(sc
, BWI_DBG_TXEOF
, "txeof idx %d, "
3285 "acked %d, data_txcnt %d, ni %p\n",
3286 buf_idx
, acked
, data_txcnt
, tb
->tb_ni
);
3288 bus_dmamap_unload(sc
->sc_buf_dtag
, tb
->tb_dmap
);
3289 m_freem(tb
->tb_mbuf
);
3292 if (tb
->tb_ni
!= NULL
) {
3293 struct ieee80211_ratectl_res res
[BWI_NTXRATE
];
3296 if (data_txcnt
<= BWI_SHRETRY_FB
|| tb
->tb_rateidx_cnt
== 1) {
3298 res
[0].rc_res_rateidx
= tb
->tb_rateidx
[0];
3299 res
[0].rc_res_tries
= data_txcnt
;
3301 res_len
= BWI_NTXRATE
;
3302 res
[0].rc_res_rateidx
= tb
->tb_rateidx
[0];
3303 res
[0].rc_res_tries
= BWI_SHRETRY_FB
;
3304 res
[1].rc_res_rateidx
= tb
->tb_rateidx
[1];
3305 res
[1].rc_res_tries
= data_txcnt
- BWI_SHRETRY_FB
;
3309 retry
= data_txcnt
> 0 ? data_txcnt
- 1 : 0;
3313 ieee80211_ratectl_tx_complete(tb
->tb_ni
, tb
->tb_buflen
,
3314 res
, res_len
, retry
, 0, !acked
);
3316 ieee80211_free_node(tb
->tb_ni
);
3320 if (tbd
->tbd_used
== 0)
3321 sc
->sc_tx_timer
= 0;
3323 ifp
->if_flags
&= ~IFF_OACTIVE
;
3327 bwi_txeof_status(struct bwi_softc
*sc
, int end_idx
)
3329 struct bwi_txstats_data
*st
= sc
->sc_txstats
;
3332 bus_dmamap_sync(st
->stats_dtag
, st
->stats_dmap
, BUS_DMASYNC_POSTREAD
);
3334 idx
= st
->stats_idx
;
3335 while (idx
!= end_idx
) {
3336 const struct bwi_txstats
*stats
= &st
->stats
[idx
];
3338 if ((stats
->txs_flags
& BWI_TXS_F_PENDING
) == 0) {
3341 data_txcnt
= __SHIFTOUT(stats
->txs_txcnt
,
3342 BWI_TXS_TXCNT_DATA
);
3343 _bwi_txeof(sc
, le16toh(stats
->txs_id
),
3344 stats
->txs_flags
& BWI_TXS_F_ACKED
,
3347 idx
= (idx
+ 1) % BWI_TXSTATS_NDESC
;
3349 st
->stats_idx
= idx
;
3353 bwi_txeof(struct bwi_softc
*sc
)
3355 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
3358 uint32_t tx_status0
, tx_status1
;
3362 tx_status0
= CSR_READ_4(sc
, BWI_TXSTATUS0
);
3363 if ((tx_status0
& BWI_TXSTATUS0_VALID
) == 0)
3365 tx_status1
= CSR_READ_4(sc
, BWI_TXSTATUS1
);
3367 tx_id
= __SHIFTOUT(tx_status0
, BWI_TXSTATUS0_TXID_MASK
);
3368 data_txcnt
= __SHIFTOUT(tx_status0
,
3369 BWI_TXSTATUS0_DATA_TXCNT_MASK
);
3371 if (tx_status0
& (BWI_TXSTATUS0_AMPDU
| BWI_TXSTATUS0_PENDING
))
3374 _bwi_txeof(sc
, tx_id
, tx_status0
& BWI_TXSTATUS0_ACKED
,
3378 if ((ifp
->if_flags
& IFF_OACTIVE
) == 0)
3383 bwi_bbp_power_on(struct bwi_softc
*sc
, enum bwi_clock_mode clk_mode
)
3385 bwi_power_on(sc
, 1);
3386 return bwi_set_clock_mode(sc
, clk_mode
);
3390 bwi_bbp_power_off(struct bwi_softc
*sc
)
3392 bwi_set_clock_mode(sc
, BWI_CLOCK_MODE_SLOW
);
3393 bwi_power_off(sc
, 1);
3397 bwi_get_pwron_delay(struct bwi_softc
*sc
)
3399 struct bwi_regwin
*com
, *old
;
3400 struct bwi_clock_freq freq
;
3404 com
= &sc
->sc_com_regwin
;
3405 KKASSERT(BWI_REGWIN_EXIST(com
));
3407 if ((sc
->sc_cap
& BWI_CAP_CLKMODE
) == 0)
3410 error
= bwi_regwin_switch(sc
, com
, &old
);
3414 bwi_get_clock_freq(sc
, &freq
);
3416 val
= CSR_READ_4(sc
, BWI_PLL_ON_DELAY
);
3417 sc
->sc_pwron_delay
= howmany((val
+ 2) * 1000000, freq
.clkfreq_min
);
3418 DPRINTF(sc
, BWI_DBG_ATTACH
, "power on delay %u\n", sc
->sc_pwron_delay
);
3420 return bwi_regwin_switch(sc
, old
, NULL
);
3424 bwi_bus_attach(struct bwi_softc
*sc
)
3426 struct bwi_regwin
*bus
, *old
;
3429 bus
= &sc
->sc_bus_regwin
;
3431 error
= bwi_regwin_switch(sc
, bus
, &old
);
3435 if (!bwi_regwin_is_enabled(sc
, bus
))
3436 bwi_regwin_enable(sc
, bus
, 0);
3438 /* Disable interripts */
3439 CSR_WRITE_4(sc
, BWI_INTRVEC
, 0);
3441 return bwi_regwin_switch(sc
, old
, NULL
);
3445 bwi_regwin_name(const struct bwi_regwin
*rw
)
3447 switch (rw
->rw_type
) {
3448 case BWI_REGWIN_T_COM
:
3450 case BWI_REGWIN_T_BUSPCI
:
3452 case BWI_REGWIN_T_MAC
:
3454 case BWI_REGWIN_T_BUSPCIE
:
3457 panic("unknown regwin type 0x%04x\n", rw
->rw_type
);
3462 bwi_regwin_disable_bits(struct bwi_softc
*sc
)
3466 /* XXX cache this */
3467 busrev
= __SHIFTOUT(CSR_READ_4(sc
, BWI_ID_LO
), BWI_ID_LO_BUSREV_MASK
);
3468 DPRINTF(sc
, BWI_DBG_ATTACH
| BWI_DBG_INIT
| BWI_DBG_MISC
,
3469 "bus rev %u\n", busrev
);
3471 if (busrev
== BWI_BUSREV_0
)
3472 return BWI_STATE_LO_DISABLE1
;
3473 else if (busrev
== BWI_BUSREV_1
)
3474 return BWI_STATE_LO_DISABLE2
;
3476 return (BWI_STATE_LO_DISABLE1
| BWI_STATE_LO_DISABLE2
);
3480 bwi_regwin_is_enabled(struct bwi_softc
*sc
, struct bwi_regwin
*rw
)
3482 uint32_t val
, disable_bits
;
3484 disable_bits
= bwi_regwin_disable_bits(sc
);
3485 val
= CSR_READ_4(sc
, BWI_STATE_LO
);
3487 if ((val
& (BWI_STATE_LO_CLOCK
|
3488 BWI_STATE_LO_RESET
|
3489 disable_bits
)) == BWI_STATE_LO_CLOCK
) {
3490 DPRINTF(sc
, BWI_DBG_ATTACH
| BWI_DBG_INIT
, "%s is enabled\n",
3491 bwi_regwin_name(rw
));
3494 DPRINTF(sc
, BWI_DBG_ATTACH
| BWI_DBG_INIT
, "%s is disabled\n",
3495 bwi_regwin_name(rw
));
3501 bwi_regwin_disable(struct bwi_softc
*sc
, struct bwi_regwin
*rw
, uint32_t flags
)
3503 uint32_t state_lo
, disable_bits
;
3506 state_lo
= CSR_READ_4(sc
, BWI_STATE_LO
);
3509 * If current regwin is in 'reset' state, it was already disabled.
3511 if (state_lo
& BWI_STATE_LO_RESET
) {
3512 DPRINTF(sc
, BWI_DBG_ATTACH
| BWI_DBG_INIT
,
3513 "%s was already disabled\n", bwi_regwin_name(rw
));
3517 disable_bits
= bwi_regwin_disable_bits(sc
);
3520 * Disable normal clock
3522 state_lo
= BWI_STATE_LO_CLOCK
| disable_bits
;
3523 CSR_WRITE_4(sc
, BWI_STATE_LO
, state_lo
);
3526 * Wait until normal clock is disabled
3529 for (i
= 0; i
< NRETRY
; ++i
) {
3530 state_lo
= CSR_READ_4(sc
, BWI_STATE_LO
);
3531 if (state_lo
& disable_bits
)
3536 device_printf(sc
->sc_dev
, "%s disable clock timeout\n",
3537 bwi_regwin_name(rw
));
3540 for (i
= 0; i
< NRETRY
; ++i
) {
3543 state_hi
= CSR_READ_4(sc
, BWI_STATE_HI
);
3544 if ((state_hi
& BWI_STATE_HI_BUSY
) == 0)
3549 device_printf(sc
->sc_dev
, "%s wait BUSY unset timeout\n",
3550 bwi_regwin_name(rw
));
3555 * Reset and disable regwin with gated clock
3557 state_lo
= BWI_STATE_LO_RESET
| disable_bits
|
3558 BWI_STATE_LO_CLOCK
| BWI_STATE_LO_GATED_CLOCK
|
3559 __SHIFTIN(flags
, BWI_STATE_LO_FLAGS_MASK
);
3560 CSR_WRITE_4(sc
, BWI_STATE_LO
, state_lo
);
3562 /* Flush pending bus write */
3563 CSR_READ_4(sc
, BWI_STATE_LO
);
3566 /* Reset and disable regwin */
3567 state_lo
= BWI_STATE_LO_RESET
| disable_bits
|
3568 __SHIFTIN(flags
, BWI_STATE_LO_FLAGS_MASK
);
3569 CSR_WRITE_4(sc
, BWI_STATE_LO
, state_lo
);
3571 /* Flush pending bus write */
3572 CSR_READ_4(sc
, BWI_STATE_LO
);
3577 bwi_regwin_enable(struct bwi_softc
*sc
, struct bwi_regwin
*rw
, uint32_t flags
)
3579 uint32_t state_lo
, state_hi
, imstate
;
3581 bwi_regwin_disable(sc
, rw
, flags
);
3583 /* Reset regwin with gated clock */
3584 state_lo
= BWI_STATE_LO_RESET
|
3585 BWI_STATE_LO_CLOCK
|
3586 BWI_STATE_LO_GATED_CLOCK
|
3587 __SHIFTIN(flags
, BWI_STATE_LO_FLAGS_MASK
);
3588 CSR_WRITE_4(sc
, BWI_STATE_LO
, state_lo
);
3590 /* Flush pending bus write */
3591 CSR_READ_4(sc
, BWI_STATE_LO
);
3594 state_hi
= CSR_READ_4(sc
, BWI_STATE_HI
);
3595 if (state_hi
& BWI_STATE_HI_SERROR
)
3596 CSR_WRITE_4(sc
, BWI_STATE_HI
, 0);
3598 imstate
= CSR_READ_4(sc
, BWI_IMSTATE
);
3599 if (imstate
& (BWI_IMSTATE_INBAND_ERR
| BWI_IMSTATE_TIMEOUT
)) {
3600 imstate
&= ~(BWI_IMSTATE_INBAND_ERR
| BWI_IMSTATE_TIMEOUT
);
3601 CSR_WRITE_4(sc
, BWI_IMSTATE
, imstate
);
3604 /* Enable regwin with gated clock */
3605 state_lo
= BWI_STATE_LO_CLOCK
|
3606 BWI_STATE_LO_GATED_CLOCK
|
3607 __SHIFTIN(flags
, BWI_STATE_LO_FLAGS_MASK
);
3608 CSR_WRITE_4(sc
, BWI_STATE_LO
, state_lo
);
3610 /* Flush pending bus write */
3611 CSR_READ_4(sc
, BWI_STATE_LO
);
3614 /* Enable regwin with normal clock */
3615 state_lo
= BWI_STATE_LO_CLOCK
|
3616 __SHIFTIN(flags
, BWI_STATE_LO_FLAGS_MASK
);
3617 CSR_WRITE_4(sc
, BWI_STATE_LO
, state_lo
);
3619 /* Flush pending bus write */
3620 CSR_READ_4(sc
, BWI_STATE_LO
);
3625 bwi_set_bssid(struct bwi_softc
*sc
, const uint8_t *bssid
)
3627 struct ieee80211com
*ic
= &sc
->sc_ic
;
3628 struct bwi_mac
*mac
;
3629 struct bwi_myaddr_bssid buf
;
3634 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
3635 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
3637 bwi_set_addr_filter(sc
, BWI_ADDR_FILTER_BSSID
, bssid
);
3639 bcopy(ic
->ic_myaddr
, buf
.myaddr
, sizeof(buf
.myaddr
));
3640 bcopy(bssid
, buf
.bssid
, sizeof(buf
.bssid
));
3642 n
= sizeof(buf
) / sizeof(val
);
3643 p
= (const uint8_t *)&buf
;
3644 for (i
= 0; i
< n
; ++i
) {
3648 for (j
= 0; j
< sizeof(val
); ++j
)
3649 val
|= ((uint32_t)(*p
++)) << (j
* 8);
3651 TMPLT_WRITE_4(mac
, 0x20 + (i
* sizeof(val
)), val
);
3656 bwi_updateslot(struct ifnet
*ifp
)
3658 struct bwi_softc
*sc
= ifp
->if_softc
;
3659 struct ieee80211com
*ic
= &sc
->sc_ic
;
3660 struct bwi_mac
*mac
;
3662 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
3665 ASSERT_SERIALIZED(ifp
->if_serializer
);
3667 DPRINTF(sc
, BWI_DBG_80211
, "%s\n", __func__
);
3669 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
3670 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
3672 bwi_mac_updateslot(mac
, (ic
->ic_flags
& IEEE80211_F_SHSLOT
));
3676 bwi_calibrate(void *xsc
)
3678 struct bwi_softc
*sc
= xsc
;
3679 struct ieee80211com
*ic
= &sc
->sc_ic
;
3680 struct ifnet
*ifp
= &ic
->ic_if
;
3682 lwkt_serialize_enter(ifp
->if_serializer
);
3684 if (ic
->ic_state
== IEEE80211_S_RUN
) {
3685 struct bwi_mac
*mac
;
3687 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
3688 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
3690 if (ic
->ic_opmode
!= IEEE80211_M_MONITOR
) {
3691 bwi_mac_calibrate_txpower(mac
, sc
->sc_txpwrcb_type
);
3692 sc
->sc_txpwrcb_type
= BWI_TXPWR_CALIB
;
3695 /* XXX 15 seconds */
3696 callout_reset(&sc
->sc_calib_ch
, hz
* 15, bwi_calibrate
, sc
);
3699 lwkt_serialize_exit(ifp
->if_serializer
);
3703 bwi_calc_rssi(struct bwi_softc
*sc
, const struct bwi_rxbuf_hdr
*hdr
)
3705 struct bwi_mac
*mac
;
3707 KKASSERT(sc
->sc_cur_regwin
->rw_type
== BWI_REGWIN_T_MAC
);
3708 mac
= (struct bwi_mac
*)sc
->sc_cur_regwin
;
3710 return bwi_rf_calc_rssi(mac
, hdr
);
3714 bwi_rx_radiotap(struct bwi_softc
*sc
, struct mbuf
*m
,
3715 struct bwi_rxbuf_hdr
*hdr
, const void *plcp
,
3718 const struct ieee80211_frame_min
*wh
;
3720 KKASSERT(sc
->sc_drvbpf
!= NULL
);
3722 sc
->sc_rx_th
.wr_flags
= IEEE80211_RADIOTAP_F_FCS
;
3723 if (htole16(hdr
->rxh_flags1
) & BWI_RXH_F1_SHPREAMBLE
)
3724 sc
->sc_rx_th
.wr_flags
|= IEEE80211_RADIOTAP_F_SHORTPRE
;
3726 wh
= mtod(m
, const struct ieee80211_frame_min
*);
3727 if (wh
->i_fc
[1] & IEEE80211_FC1_WEP
)
3728 sc
->sc_rx_th
.wr_flags
|= IEEE80211_RADIOTAP_F_WEP
;
3730 sc
->sc_rx_th
.wr_tsf
= hdr
->rxh_tsf
; /* No endian convertion */
3731 sc
->sc_rx_th
.wr_rate
= rate
;
3732 sc
->sc_rx_th
.wr_antsignal
= rssi
;
3733 sc
->sc_rx_th
.wr_antnoise
= BWI_NOISE_FLOOR
;
3735 bpf_ptap(sc
->sc_drvbpf
, m
, &sc
->sc_rx_th
, sc
->sc_rx_th_len
);
3739 bwi_led_attach(struct bwi_softc
*sc
)
3741 const uint8_t *led_act
= NULL
;
3742 uint16_t gpio
, val
[BWI_LED_MAX
];
3745 #define N(arr) (int)(sizeof(arr) / sizeof(arr[0]))
3747 for (i
= 0; i
< N(bwi_vendor_led_act
); ++i
) {
3748 if (sc
->sc_pci_subvid
== bwi_vendor_led_act
[i
].vid
) {
3749 led_act
= bwi_vendor_led_act
[i
].led_act
;
3753 if (led_act
== NULL
)
3754 led_act
= bwi_default_led_act
;
3758 gpio
= bwi_read_sprom(sc
, BWI_SPROM_GPIO01
);
3759 val
[0] = __SHIFTOUT(gpio
, BWI_SPROM_GPIO_0
);
3760 val
[1] = __SHIFTOUT(gpio
, BWI_SPROM_GPIO_1
);
3762 gpio
= bwi_read_sprom(sc
, BWI_SPROM_GPIO23
);
3763 val
[2] = __SHIFTOUT(gpio
, BWI_SPROM_GPIO_2
);
3764 val
[3] = __SHIFTOUT(gpio
, BWI_SPROM_GPIO_3
);
3766 for (i
= 0; i
< BWI_LED_MAX
; ++i
) {
3767 struct bwi_led
*led
= &sc
->sc_leds
[i
];
3769 if (val
[i
] == 0xff) {
3770 led
->l_act
= led_act
[i
];
3772 if (val
[i
] & BWI_LED_ACT_LOW
)
3773 led
->l_flags
|= BWI_LED_F_ACTLOW
;
3774 led
->l_act
= __SHIFTOUT(val
[i
], BWI_LED_ACT_MASK
);
3776 led
->l_mask
= (1 << i
);
3778 if (led
->l_act
== BWI_LED_ACT_BLINK_SLOW
||
3779 led
->l_act
== BWI_LED_ACT_BLINK_POLL
||
3780 led
->l_act
== BWI_LED_ACT_BLINK
) {
3781 led
->l_flags
|= BWI_LED_F_BLINK
;
3782 if (led
->l_act
== BWI_LED_ACT_BLINK_POLL
)
3783 led
->l_flags
|= BWI_LED_F_POLLABLE
;
3784 else if (led
->l_act
== BWI_LED_ACT_BLINK_SLOW
)
3785 led
->l_flags
|= BWI_LED_F_SLOW
;
3787 if (sc
->sc_blink_led
== NULL
) {
3788 sc
->sc_blink_led
= led
;
3789 if (led
->l_flags
& BWI_LED_F_SLOW
)
3790 BWI_LED_SLOWDOWN(sc
->sc_led_idle
);
3794 DPRINTF(sc
, BWI_DBG_LED
| BWI_DBG_ATTACH
,
3795 "%dth led, act %d, lowact %d\n", i
,
3796 led
->l_act
, led
->l_flags
& BWI_LED_F_ACTLOW
);
3798 callout_init(&sc
->sc_led_blink_ch
);
3801 static __inline
uint16_t
3802 bwi_led_onoff(const struct bwi_led
*led
, uint16_t val
, int on
)
3804 if (led
->l_flags
& BWI_LED_F_ACTLOW
)
3809 val
&= ~led
->l_mask
;
3814 bwi_led_newstate(struct bwi_softc
*sc
, enum ieee80211_state nstate
)
3816 struct ieee80211com
*ic
= &sc
->sc_ic
;
3820 if (nstate
== IEEE80211_S_INIT
) {
3821 callout_stop(&sc
->sc_led_blink_ch
);
3822 sc
->sc_led_blinking
= 0;
3825 if ((ic
->ic_if
.if_flags
& IFF_RUNNING
) == 0)
3828 val
= CSR_READ_2(sc
, BWI_MAC_GPIO_CTRL
);
3829 for (i
= 0; i
< BWI_LED_MAX
; ++i
) {
3830 struct bwi_led
*led
= &sc
->sc_leds
[i
];
3833 if (led
->l_act
== BWI_LED_ACT_UNKN
||
3834 led
->l_act
== BWI_LED_ACT_NULL
)
3837 if ((led
->l_flags
& BWI_LED_F_BLINK
) &&
3838 nstate
!= IEEE80211_S_INIT
)
3841 switch (led
->l_act
) {
3842 case BWI_LED_ACT_ON
: /* Always on */
3845 case BWI_LED_ACT_OFF
: /* Always off */
3846 case BWI_LED_ACT_5GHZ
: /* TODO: 11A */
3852 case IEEE80211_S_INIT
:
3855 case IEEE80211_S_RUN
:
3856 if (led
->l_act
== BWI_LED_ACT_11G
&&
3857 ic
->ic_curmode
!= IEEE80211_MODE_11G
)
3861 if (led
->l_act
== BWI_LED_ACT_ASSOC
)
3868 val
= bwi_led_onoff(led
, val
, on
);
3870 CSR_WRITE_2(sc
, BWI_MAC_GPIO_CTRL
, val
);
3874 bwi_led_event(struct bwi_softc
*sc
, int event
)
3876 struct bwi_led
*led
= sc
->sc_blink_led
;
3879 if (event
== BWI_LED_EVENT_POLL
) {
3880 if ((led
->l_flags
& BWI_LED_F_POLLABLE
) == 0)
3882 if (ticks
- sc
->sc_led_ticks
< sc
->sc_led_idle
)
3886 sc
->sc_led_ticks
= ticks
;
3887 if (sc
->sc_led_blinking
)
3891 case BWI_LED_EVENT_RX
:
3892 rate
= sc
->sc_rx_rate
;
3894 case BWI_LED_EVENT_TX
:
3895 rate
= sc
->sc_tx_rate
;
3897 case BWI_LED_EVENT_POLL
:
3901 panic("unknown LED event %d\n", event
);
3904 bwi_led_blink_start(sc
, bwi_led_duration
[rate
].on_dur
,
3905 bwi_led_duration
[rate
].off_dur
);
3909 bwi_led_blink_start(struct bwi_softc
*sc
, int on_dur
, int off_dur
)
3911 struct bwi_led
*led
= sc
->sc_blink_led
;
3914 val
= CSR_READ_2(sc
, BWI_MAC_GPIO_CTRL
);
3915 val
= bwi_led_onoff(led
, val
, 1);
3916 CSR_WRITE_2(sc
, BWI_MAC_GPIO_CTRL
, val
);
3918 if (led
->l_flags
& BWI_LED_F_SLOW
) {
3919 BWI_LED_SLOWDOWN(on_dur
);
3920 BWI_LED_SLOWDOWN(off_dur
);
3923 sc
->sc_led_blinking
= 1;
3924 sc
->sc_led_blink_offdur
= off_dur
;
3926 callout_reset(&sc
->sc_led_blink_ch
, on_dur
, bwi_led_blink_next
, sc
);
3930 bwi_led_blink_next(void *xsc
)
3932 struct bwi_softc
*sc
= xsc
;
3935 val
= CSR_READ_2(sc
, BWI_MAC_GPIO_CTRL
);
3936 val
= bwi_led_onoff(sc
->sc_blink_led
, val
, 0);
3937 CSR_WRITE_2(sc
, BWI_MAC_GPIO_CTRL
, val
);
3939 callout_reset(&sc
->sc_led_blink_ch
, sc
->sc_led_blink_offdur
,
3940 bwi_led_blink_end
, sc
);
3944 bwi_led_blink_end(void *xsc
)
3946 struct bwi_softc
*sc
= xsc
;
3948 sc
->sc_led_blinking
= 0;
3952 bwi_ratectl_attach(struct ieee80211com
*ic
, u_int rc
)
3954 struct bwi_softc
*sc
= ic
->ic_if
.if_softc
;
3957 case IEEE80211_RATECTL_ONOE
:
3958 return &sc
->sc_onoe_param
;
3959 case IEEE80211_RATECTL_NONE
:
3960 /* This could only happen during detaching */
3963 panic("unknown rate control algo %u\n", rc
);