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/bwimac.c,v 1.1 2007/09/08 06:15:54 sephe Exp $
37 #include <sys/param.h>
38 #include <sys/endian.h>
39 #include <sys/kernel.h>
41 #include <sys/firmware.h>
42 #include <sys/malloc.h>
45 #include <sys/serialize.h>
46 #include <sys/socket.h>
47 #include <sys/sockio.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_var.h>
59 #include <bus/pci/pcireg.h>
60 #include <bus/pci/pcivar.h>
61 #include <bus/pci/pcidevs.h>
64 #include "if_bwireg.h"
65 #include "if_bwivar.h"
70 struct bwi_retry_lim
{
77 static int bwi_mac_test(struct bwi_mac
*);
78 static int bwi_mac_get_property(struct bwi_mac
*);
80 static void bwi_mac_set_retry_lim(struct bwi_mac
*,
81 const struct bwi_retry_lim
*);
82 static void bwi_mac_set_ackrates(struct bwi_mac
*,
83 const struct ieee80211_rateset
*);
85 static int bwi_mac_gpio_init(struct bwi_mac
*);
86 static int bwi_mac_gpio_fini(struct bwi_mac
*);
87 static void bwi_mac_opmode_init(struct bwi_mac
*);
88 static void bwi_mac_hostflags_init(struct bwi_mac
*);
89 static void bwi_mac_bss_param_init(struct bwi_mac
*);
91 static int bwi_mac_fw_alloc(struct bwi_mac
*);
92 static void bwi_mac_fw_free(struct bwi_mac
*);
93 static int bwi_mac_fw_load(struct bwi_mac
*);
94 static int bwi_mac_fw_init(struct bwi_mac
*);
95 static int bwi_mac_fw_load_iv(struct bwi_mac
*, const struct fw_image
*);
97 static void bwi_mac_setup_tpctl(struct bwi_mac
*);
98 static void bwi_mac_adjust_tpctl(struct bwi_mac
*, int, int);
100 static void bwi_mac_lock(struct bwi_mac
*);
101 static void bwi_mac_unlock(struct bwi_mac
*);
103 static const uint8_t bwi_sup_macrev
[] = { 2, 4, 5, 6, 7, 9, 10 };
106 bwi_tmplt_write_4(struct bwi_mac
*mac
, uint32_t ofs
, uint32_t val
)
108 struct bwi_softc
*sc
= mac
->mac_sc
;
110 if (mac
->mac_flags
& BWI_MAC_F_BSWAP
)
113 CSR_WRITE_4(sc
, BWI_MAC_TMPLT_CTRL
, ofs
);
114 CSR_WRITE_4(sc
, BWI_MAC_TMPLT_DATA
, val
);
118 bwi_hostflags_write(struct bwi_mac
*mac
, uint64_t flags
)
122 val
= flags
& 0xffff;
123 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_HFLAGS_LO
, val
);
125 val
= (flags
>> 16) & 0xffff;
126 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_HFLAGS_MI
, val
);
128 /* HI has unclear meaning, so leave it as it is */
132 bwi_hostflags_read(struct bwi_mac
*mac
)
136 /* HI has unclear meaning, so don't touch it */
139 val
= MOBJ_READ_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_HFLAGS_MI
);
142 val
= MOBJ_READ_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_HFLAGS_LO
);
149 bwi_memobj_read_2(struct bwi_mac
*mac
, uint16_t obj_id
, uint16_t ofs0
)
151 struct bwi_softc
*sc
= mac
->mac_sc
;
155 data_reg
= BWI_MOBJ_DATA
;
159 data_reg
= BWI_MOBJ_DATA_UNALIGN
;
161 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
, BWI_MOBJ_CTRL_VAL(obj_id
, ofs
));
162 return CSR_READ_2(sc
, data_reg
);
166 bwi_memobj_read_4(struct bwi_mac
*mac
, uint16_t obj_id
, uint16_t ofs0
)
168 struct bwi_softc
*sc
= mac
->mac_sc
;
175 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
, BWI_MOBJ_CTRL_VAL(obj_id
, ofs
));
176 ret
= CSR_READ_2(sc
, BWI_MOBJ_DATA_UNALIGN
);
179 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
,
180 BWI_MOBJ_CTRL_VAL(obj_id
, ofs
+ 1));
181 ret
|= CSR_READ_2(sc
, BWI_MOBJ_DATA
);
185 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
, BWI_MOBJ_CTRL_VAL(obj_id
, ofs
));
186 return CSR_READ_4(sc
, BWI_MOBJ_DATA
);
191 bwi_memobj_write_2(struct bwi_mac
*mac
, uint16_t obj_id
, uint16_t ofs0
,
194 struct bwi_softc
*sc
= mac
->mac_sc
;
198 data_reg
= BWI_MOBJ_DATA
;
202 data_reg
= BWI_MOBJ_DATA_UNALIGN
;
204 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
, BWI_MOBJ_CTRL_VAL(obj_id
, ofs
));
205 CSR_WRITE_2(sc
, data_reg
, v
);
209 bwi_memobj_write_4(struct bwi_mac
*mac
, uint16_t obj_id
, uint16_t ofs0
,
212 struct bwi_softc
*sc
= mac
->mac_sc
;
217 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
, BWI_MOBJ_CTRL_VAL(obj_id
, ofs
));
218 CSR_WRITE_2(sc
, BWI_MOBJ_DATA_UNALIGN
, v
>> 16);
220 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
,
221 BWI_MOBJ_CTRL_VAL(obj_id
, ofs
+ 1));
222 CSR_WRITE_2(sc
, BWI_MOBJ_DATA
, v
& 0xffff);
224 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
, BWI_MOBJ_CTRL_VAL(obj_id
, ofs
));
225 CSR_WRITE_4(sc
, BWI_MOBJ_DATA
, v
);
230 bwi_mac_lateattach(struct bwi_mac
*mac
)
234 if (mac
->mac_rev
>= 5)
235 CSR_READ_4(mac
->mac_sc
, BWI_STATE_HI
); /* dummy read */
237 bwi_mac_reset(mac
, 1);
239 error
= bwi_phy_attach(mac
);
243 error
= bwi_rf_attach(mac
);
247 /* Link 11B/G PHY, unlink 11A PHY */
248 if (mac
->mac_phy
.phy_mode
== IEEE80211_MODE_11A
)
249 bwi_mac_reset(mac
, 0);
251 bwi_mac_reset(mac
, 1);
253 error
= bwi_mac_test(mac
);
257 error
= bwi_mac_get_property(mac
);
261 error
= bwi_rf_map_txpower(mac
);
266 CSR_WRITE_2(mac
->mac_sc
, BWI_BBP_ATTEN
, BWI_BBP_ATTEN_MAGIC
);
267 bwi_regwin_disable(mac
->mac_sc
, &mac
->mac_regwin
, 0);
273 bwi_mac_init(struct bwi_mac
*mac
)
275 struct bwi_softc
*sc
= mac
->mac_sc
;
278 /* Clear MAC/PHY/RF states */
279 bwi_mac_setup_tpctl(mac
);
280 bwi_rf_clear_state(&mac
->mac_rf
);
281 bwi_phy_clear_state(&mac
->mac_phy
);
283 /* Enable MAC and linked it to PHY */
284 if (!bwi_regwin_is_enabled(sc
, &mac
->mac_regwin
))
285 bwi_mac_reset(mac
, 1);
287 /* Initialize backplane */
288 error
= bwi_bus_init(sc
, mac
);
292 /* XXX work around for hardware bugs? */
293 if (sc
->sc_bus_regwin
.rw_rev
<= 5 &&
294 sc
->sc_bus_regwin
.rw_type
!= BWI_REGWIN_T_BUSPCIE
) {
295 CSR_SETBITS_4(sc
, BWI_CONF_LO
,
296 __SHIFTIN(BWI_CONF_LO_SERVTO
, BWI_CONF_LO_SERVTO_MASK
) |
297 __SHIFTIN(BWI_CONF_LO_REQTO
, BWI_CONF_LO_REQTO_MASK
));
301 error
= bwi_phy_calibrate(mac
);
303 if_printf(&sc
->sc_ic
.ic_if
, "PHY calibrate failed\n");
307 /* Prepare to initialize firmware */
308 CSR_WRITE_4(sc
, BWI_MAC_STATUS
,
309 BWI_MAC_STATUS_UCODE_JUMP0
|
310 BWI_MAC_STATUS_IHREN
);
313 * Load and initialize firmwares
315 error
= bwi_mac_fw_alloc(mac
);
319 error
= bwi_mac_fw_load(mac
);
323 error
= bwi_mac_gpio_init(mac
);
327 error
= bwi_mac_fw_init(mac
);
336 /* TODO: LED, hardware rf enabled is only related to LED setting */
341 CSR_WRITE_4(sc
, BWI_BBP_ATTEN
, 0);
344 /* TODO: interference mitigation */
349 bwi_rf_set_ant_mode(mac
, mac
->mac_rf
.rf_ant_mode
);
352 * Initialize operation mode (RX configuration)
354 bwi_mac_opmode_init(mac
);
356 /* XXX what's these */
357 if (mac
->mac_rev
< 3) {
358 CSR_WRITE_2(sc
, 0x60e, 0);
359 CSR_WRITE_2(sc
, 0x610, 0x8000);
360 CSR_WRITE_2(sc
, 0x604, 0);
361 CSR_WRITE_2(sc
, 0x606, 0x200);
363 CSR_WRITE_4(sc
, 0x188, 0x80000000);
364 CSR_WRITE_4(sc
, 0x18c, 0x2000000);
368 * Initialize TX/RX interrupts' mask
370 CSR_WRITE_4(sc
, BWI_MAC_INTR_STATUS
, BWI_INTR_TIMER1
);
371 for (i
= 0; i
< BWI_TXRX_NRING
; ++i
) {
374 if (BWI_TXRX_IS_RX(i
))
375 intrs
= BWI_TXRX_RX_INTRS
;
377 intrs
= BWI_TXRX_TX_INTRS
;
378 CSR_WRITE_4(sc
, BWI_TXRX_INTR_MASK(i
), intrs
);
381 /* XXX what's this */
382 CSR_SETBITS_4(sc
, BWI_STATE_LO
, 0x100000);
384 /* Setup MAC power up delay */
385 CSR_WRITE_2(sc
, BWI_MAC_POWERUP_DELAY
, sc
->sc_pwron_delay
);
387 /* Set MAC regwin revision */
388 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_MACREV
, mac
->mac_rev
);
391 * Initialize host flags
393 bwi_mac_hostflags_init(mac
);
396 * Initialize BSS parameters
398 bwi_mac_bss_param_init(mac
);
401 * Initialize TX rings
403 for (i
= 0; i
< BWI_TX_NRING
; ++i
) {
404 error
= sc
->sc_init_tx_ring(sc
, i
);
406 if_printf(&sc
->sc_ic
.ic_if
,
407 "can't initialize %dth TX ring\n", i
);
415 error
= sc
->sc_init_rx_ring(sc
);
417 if_printf(&sc
->sc_ic
.ic_if
, "can't initialize RX ring\n");
422 * Initialize TX stats if the current MAC uses that
424 if (mac
->mac_flags
& BWI_MAC_F_HAS_TXSTATS
) {
425 error
= sc
->sc_init_txstats(sc
);
427 if_printf(&sc
->sc_ic
.ic_if
,
428 "can't initialize TX stats ring\n");
433 /* XXX what's these */
434 CSR_WRITE_2(sc
, 0x612, 0x50); /* Force Pre-TBTT to 80? */
435 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, 0x416, 0x50);
436 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, 0x414, 0x1f4);
438 mac
->mac_flags
|= BWI_MAC_F_INITED
;
443 bwi_mac_reset(struct bwi_mac
*mac
, int link_phy
)
445 struct bwi_softc
*sc
= mac
->mac_sc
;
446 uint32_t flags
, state_lo
, status
;
448 flags
= BWI_STATE_LO_FLAG_PHYRST
| BWI_STATE_LO_FLAG_PHYCLKEN
;
450 flags
|= BWI_STATE_LO_FLAG_PHYLNK
;
451 bwi_regwin_enable(sc
, &mac
->mac_regwin
, flags
);
454 state_lo
= CSR_READ_4(sc
, BWI_STATE_LO
);
455 state_lo
|= BWI_STATE_LO_GATED_CLOCK
;
456 state_lo
&= ~__SHIFTIN(BWI_STATE_LO_FLAG_PHYRST
,
457 BWI_STATE_LO_FLAGS_MASK
);
458 CSR_WRITE_4(sc
, BWI_STATE_LO
, state_lo
);
459 /* Flush pending bus write */
460 CSR_READ_4(sc
, BWI_STATE_LO
);
463 state_lo
&= ~BWI_STATE_LO_GATED_CLOCK
;
464 CSR_WRITE_4(sc
, BWI_STATE_LO
, state_lo
);
465 /* Flush pending bus write */
466 CSR_READ_4(sc
, BWI_STATE_LO
);
469 CSR_WRITE_2(sc
, BWI_BBP_ATTEN
, 0);
471 status
= CSR_READ_4(sc
, BWI_MAC_STATUS
);
472 status
|= BWI_MAC_STATUS_IHREN
;
474 status
|= BWI_MAC_STATUS_PHYLNK
;
476 status
&= ~BWI_MAC_STATUS_PHYLNK
;
477 CSR_WRITE_4(sc
, BWI_MAC_STATUS
, status
);
480 DPRINTF(sc
, "%s\n", "PHY is linked");
481 mac
->mac_phy
.phy_flags
|= BWI_PHY_F_LINKED
;
483 DPRINTF(sc
, "%s\n", "PHY is unlinked");
484 mac
->mac_phy
.phy_flags
&= ~BWI_PHY_F_LINKED
;
489 bwi_mac_set_tpctl_11bg(struct bwi_mac
*mac
, const struct bwi_tpctl
*new_tpctl
)
491 struct bwi_rf
*rf
= &mac
->mac_rf
;
492 struct bwi_tpctl
*tpctl
= &mac
->mac_tpctl
;
494 if (new_tpctl
!= NULL
) {
495 KKASSERT(new_tpctl
->bbp_atten
<= BWI_BBP_ATTEN_MAX
);
496 KKASSERT(new_tpctl
->rf_atten
<=
497 (rf
->rf_rev
< 6 ? BWI_RF_ATTEN_MAX0
498 : BWI_RF_ATTEN_MAX1
));
499 KKASSERT(new_tpctl
->tp_ctrl1
<= BWI_TPCTL1_MAX
);
501 tpctl
->bbp_atten
= new_tpctl
->bbp_atten
;
502 tpctl
->rf_atten
= new_tpctl
->rf_atten
;
503 tpctl
->tp_ctrl1
= new_tpctl
->tp_ctrl1
;
506 /* Set BBP attenuation */
507 bwi_phy_set_bbp_atten(mac
, tpctl
->bbp_atten
);
509 /* Set RF attenuation */
510 RF_WRITE(mac
, BWI_RFR_ATTEN
, tpctl
->rf_atten
);
511 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_RF_ATTEN
,
515 if (rf
->rf_type
== BWI_RF_T_BCM2050
) {
516 RF_FILT_SETBITS(mac
, BWI_RFR_TXPWR
, ~BWI_RFR_TXPWR1_MASK
,
517 __SHIFTIN(tpctl
->tp_ctrl1
, BWI_RFR_TXPWR1_MASK
));
520 /* Adjust RF Local Oscillator */
521 if (mac
->mac_phy
.phy_mode
== IEEE80211_MODE_11G
)
522 bwi_rf_lo_adjust(mac
, tpctl
);
526 bwi_mac_test(struct bwi_mac
*mac
)
528 struct bwi_softc
*sc
= mac
->mac_sc
;
529 uint32_t orig_val
, val
;
531 #define TEST_VAL1 0xaa5555aa
532 #define TEST_VAL2 0x55aaaa55
534 /* Save it for later restoring */
535 orig_val
= MOBJ_READ_4(mac
, BWI_COMM_MOBJ
, 0);
538 MOBJ_WRITE_4(mac
, BWI_COMM_MOBJ
, 0, TEST_VAL1
);
539 val
= MOBJ_READ_4(mac
, BWI_COMM_MOBJ
, 0);
540 if (val
!= TEST_VAL1
) {
541 device_printf(sc
->sc_dev
, "TEST1 failed\n");
546 MOBJ_WRITE_4(mac
, BWI_COMM_MOBJ
, 0, TEST_VAL2
);
547 val
= MOBJ_READ_4(mac
, BWI_COMM_MOBJ
, 0);
548 if (val
!= TEST_VAL2
) {
549 device_printf(sc
->sc_dev
, "TEST2 failed\n");
553 /* Restore to the original value */
554 MOBJ_WRITE_4(mac
, BWI_COMM_MOBJ
, 0, orig_val
);
556 val
= CSR_READ_4(sc
, BWI_MAC_STATUS
);
557 if ((val
& ~BWI_MAC_STATUS_PHYLNK
) != BWI_MAC_STATUS_IHREN
) {
558 device_printf(sc
->sc_dev
, "%s failed, MAC status 0x%08x\n",
563 val
= CSR_READ_4(sc
, BWI_MAC_INTR_STATUS
);
565 device_printf(sc
->sc_dev
, "%s failed, intr status %08x\n",
577 bwi_mac_setup_tpctl(struct bwi_mac
*mac
)
579 struct bwi_softc
*sc
= mac
->mac_sc
;
580 struct bwi_rf
*rf
= &mac
->mac_rf
;
581 struct bwi_phy
*phy
= &mac
->mac_phy
;
582 struct bwi_tpctl
*tpctl
= &mac
->mac_tpctl
;
584 /* Calc BBP attenuation */
585 if (rf
->rf_type
== BWI_RF_T_BCM2050
&& rf
->rf_rev
< 6)
586 tpctl
->bbp_atten
= 0;
588 tpctl
->bbp_atten
= 2;
590 /* Calc TX power CTRL1?? */
592 if (rf
->rf_type
== BWI_RF_T_BCM2050
) {
595 else if (rf
->rf_rev
< 6)
597 else if (rf
->rf_rev
== 8)
601 /* Empty TX power CTRL2?? */
602 tpctl
->tp_ctrl2
= 0xffff;
605 * Calc RF attenuation
607 if (phy
->phy_mode
== IEEE80211_MODE_11A
) {
608 tpctl
->rf_atten
= 0x60;
612 if (BWI_IS_BRCM_BCM4309G(sc
) && sc
->sc_pci_revid
< 0x51) {
613 tpctl
->rf_atten
= sc
->sc_pci_revid
< 0x43 ? 2 : 3;
619 if (rf
->rf_type
!= BWI_RF_T_BCM2050
) {
620 if (rf
->rf_type
== BWI_RF_T_BCM2053
&& rf
->rf_rev
== 1)
626 * NB: If we reaches here and the card is BRCM_BCM4309G,
627 * then the card's PCI revision must >= 0x51
631 switch (rf
->rf_rev
) {
633 if (phy
->phy_mode
== IEEE80211_MODE_11G
) {
634 if (BWI_IS_BRCM_BCM4309G(sc
) || BWI_IS_BRCM_BU4306(sc
))
639 if (BWI_IS_BRCM_BCM4309G(sc
))
646 if (phy
->phy_mode
== IEEE80211_MODE_11G
) {
648 * NOTE: Order of following conditions is critical
650 if (BWI_IS_BRCM_BCM4309G(sc
))
652 else if (BWI_IS_BRCM_BU4306(sc
))
654 else if (sc
->sc_bbp_id
== BWI_BBPID_BCM4320
)
667 tpctl
->rf_atten
= 0x1a;
671 DPRINTF(sc
, "bbp atten: %u, rf atten: %u, ctrl1: %u, ctrl2: %u\n",
672 tpctl
->bbp_atten
, tpctl
->rf_atten
,
673 tpctl
->tp_ctrl1
, tpctl
->tp_ctrl2
);
677 bwi_mac_dummy_xmit(struct bwi_mac
*mac
)
680 static const uint32_t packet_11a
[PACKET_LEN
] =
681 { 0x000201cc, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 };
682 static const uint32_t packet_11bg
[PACKET_LEN
] =
683 { 0x000b846e, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 };
685 struct bwi_softc
*sc
= mac
->mac_sc
;
686 struct bwi_rf
*rf
= &mac
->mac_rf
;
687 const uint32_t *packet
;
691 if (mac
->mac_phy
.phy_mode
== IEEE80211_MODE_11A
) {
697 packet
= packet_11bg
;
701 for (i
= 0; i
< PACKET_LEN
; ++i
)
702 TMPLT_WRITE_4(mac
, i
* 4, packet
[i
]);
704 CSR_READ_4(sc
, BWI_MAC_STATUS
); /* dummy read */
706 CSR_WRITE_2(sc
, 0x568, 0);
707 CSR_WRITE_2(sc
, 0x7c0, 0);
708 CSR_WRITE_2(sc
, 0x50c, val_50c
);
709 CSR_WRITE_2(sc
, 0x508, 0);
710 CSR_WRITE_2(sc
, 0x50a, 0);
711 CSR_WRITE_2(sc
, 0x54c, 0);
712 CSR_WRITE_2(sc
, 0x56a, 0x14);
713 CSR_WRITE_2(sc
, 0x568, 0x826);
714 CSR_WRITE_2(sc
, 0x500, 0);
715 CSR_WRITE_2(sc
, 0x502, 0x30);
717 if (rf
->rf_type
== BWI_RF_T_BCM2050
&& rf
->rf_rev
<= 5)
718 RF_WRITE(mac
, 0x51, 0x17);
720 for (i
= 0; i
< wait_max
; ++i
) {
721 if (CSR_READ_2(sc
, 0x50e) & 0x80)
725 for (i
= 0; i
< 10; ++i
) {
726 if (CSR_READ_2(sc
, 0x50e) & 0x400)
730 for (i
= 0; i
< 10; ++i
) {
731 if ((CSR_READ_2(sc
, 0x690) & 0x100) == 0)
736 if (rf
->rf_type
== BWI_RF_T_BCM2050
&& rf
->rf_rev
<= 5)
737 RF_WRITE(mac
, 0x51, 0x37);
742 bwi_mac_init_tpctl_11bg(struct bwi_mac
*mac
)
744 struct bwi_softc
*sc
= mac
->mac_sc
;
745 struct bwi_phy
*phy
= &mac
->mac_phy
;
746 struct bwi_rf
*rf
= &mac
->mac_rf
;
747 struct bwi_tpctl tpctl_orig
;
748 int restore_tpctl
= 0;
750 KKASSERT(phy
->phy_mode
!= IEEE80211_MODE_11A
);
752 if (BWI_IS_BRCM_BU4306(sc
))
755 PHY_WRITE(mac
, 0x28, 0x8018);
756 CSR_CLRBITS_2(sc
, BWI_BBP_ATTEN
, 0x20);
758 if (phy
->phy_mode
== IEEE80211_MODE_11G
) {
759 if ((phy
->phy_flags
& BWI_PHY_F_LINKED
) == 0)
761 PHY_WRITE(mac
, 0x47a, 0xc111);
763 if (mac
->mac_flags
& BWI_MAC_F_TPCTL_INITED
)
766 if (phy
->phy_mode
== IEEE80211_MODE_11B
&& phy
->phy_rev
>= 2 &&
767 rf
->rf_type
== BWI_RF_T_BCM2050
) {
768 RF_SETBITS(mac
, 0x76, 0x84);
770 struct bwi_tpctl tpctl
;
772 /* Backup original TX power control variables */
773 bcopy(&mac
->mac_tpctl
, &tpctl_orig
, sizeof(tpctl_orig
));
776 bcopy(&mac
->mac_tpctl
, &tpctl
, sizeof(tpctl
));
777 tpctl
.bbp_atten
= 11;
780 if (rf
->rf_rev
>= 6 && rf
->rf_rev
<= 8)
786 bwi_mac_set_tpctl_11bg(mac
, &tpctl
);
789 bwi_mac_dummy_xmit(mac
);
791 mac
->mac_flags
|= BWI_MAC_F_TPCTL_INITED
;
792 rf
->rf_base_tssi
= PHY_READ(mac
, 0x29);
793 DPRINTF(sc
, "base tssi %d\n", rf
->rf_base_tssi
);
795 if (abs(rf
->rf_base_tssi
- rf
->rf_idle_tssi
) >= 20) {
796 if_printf(&sc
->sc_ic
.ic_if
, "base tssi measure failed\n");
797 mac
->mac_flags
|= BWI_MAC_F_TPCTL_ERROR
;
801 bwi_mac_set_tpctl_11bg(mac
, &tpctl_orig
);
803 RF_CLRBITS(mac
, 0x76, 0x84);
805 bwi_rf_clear_tssi(mac
);
809 bwi_mac_detach(struct bwi_mac
*mac
)
811 bwi_mac_fw_free(mac
);
815 bwi_fwimage_is_valid(struct bwi_softc
*sc
, const struct fw_image
*fw
,
818 const struct bwi_fwhdr
*hdr
;
819 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
821 if (fw
->fw_imglen
< sizeof(*hdr
)) {
822 if_printf(ifp
, "invalid firmware (%s): invalid size %u\n",
823 fw
->fw_name
, fw
->fw_imglen
);
827 hdr
= (const struct bwi_fwhdr
*)fw
->fw_image
;
829 if (fw_type
!= BWI_FW_T_IV
) {
831 * Don't verify IV's size, it has different meaning
833 if (be32toh(hdr
->fw_size
) != fw
->fw_imglen
- sizeof(*hdr
)) {
834 if_printf(ifp
, "invalid firmware (%s): size mismatch, "
835 "fw %u, real %u\n", fw
->fw_name
,
836 be32toh(hdr
->fw_size
),
837 fw
->fw_imglen
- sizeof(*hdr
));
842 if (hdr
->fw_type
!= fw_type
) {
843 if_printf(ifp
, "invalid firmware (%s): type mismatch, "
844 "fw \'%c\', target \'%c\'\n", fw
->fw_name
,
845 hdr
->fw_type
, fw_type
);
849 if (hdr
->fw_gen
!= BWI_FW_GEN_1
) {
850 if_printf(ifp
, "invalid firmware (%s): wrong generation, "
851 "fw %d, target %d\n", fw
->fw_name
,
852 hdr
->fw_gen
, BWI_FW_GEN_1
);
862 bwi_mac_fw_alloc(struct bwi_mac
*mac
)
864 struct bwi_softc
*sc
= mac
->mac_sc
;
865 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
869 if (mac
->mac_ucode
== NULL
) {
870 ksnprintf(fwname
, sizeof(fwname
), BWI_FW_UCODE_PATH
,
872 mac
->mac_rev
>= 5 ? 5 : mac
->mac_rev
);
874 mac
->mac_ucode
= firmware_image_load(fwname
);
875 if (mac
->mac_ucode
== NULL
) {
876 if_printf(ifp
, "request firmware %s failed\n", fwname
);
880 if (!bwi_fwimage_is_valid(sc
, mac
->mac_ucode
, BWI_FW_T_UCODE
))
884 if (mac
->mac_pcm
== NULL
) {
885 ksnprintf(fwname
, sizeof(fwname
), BWI_FW_PCM_PATH
,
887 mac
->mac_rev
< 5 ? 4 : 5);
889 mac
->mac_pcm
= firmware_image_load(fwname
);
890 if (mac
->mac_pcm
== NULL
) {
891 if_printf(ifp
, "request firmware %s failed\n", fwname
);
895 if (!bwi_fwimage_is_valid(sc
, mac
->mac_pcm
, BWI_FW_T_PCM
))
899 if (mac
->mac_iv
== NULL
) {
901 if (mac
->mac_rev
== 2 || mac
->mac_rev
== 4) {
903 } else if (mac
->mac_rev
>= 5 && mac
->mac_rev
<= 10) {
906 if_printf(ifp
, "no suitible IV for MAC rev %d\n",
911 ksnprintf(fwname
, sizeof(fwname
), BWI_FW_IV_PATH
,
912 sc
->sc_fw_version
, idx
);
914 mac
->mac_iv
= firmware_image_load(fwname
);
915 if (mac
->mac_iv
== NULL
) {
916 if_printf(ifp
, "request firmware %s failed\n", fwname
);
919 if (!bwi_fwimage_is_valid(sc
, mac
->mac_iv
, BWI_FW_T_IV
))
923 if (mac
->mac_iv_ext
== NULL
) {
925 if (mac
->mac_rev
== 2 || mac
->mac_rev
== 4 ||
926 mac
->mac_rev
>= 11) {
929 } else if (mac
->mac_rev
>= 5 && mac
->mac_rev
<= 10) {
932 if_printf(ifp
, "no suitible ExtIV for MAC rev %d\n",
937 ksnprintf(fwname
, sizeof(fwname
), BWI_FW_IV_EXT_PATH
,
938 sc
->sc_fw_version
, idx
);
940 mac
->mac_iv_ext
= firmware_image_load(fwname
);
941 if (mac
->mac_iv_ext
== NULL
) {
942 if_printf(ifp
, "request firmware %s failed\n", fwname
);
945 if (!bwi_fwimage_is_valid(sc
, mac
->mac_iv_ext
, BWI_FW_T_IV
))
953 bwi_mac_fw_free(struct bwi_mac
*mac
)
955 if (mac
->mac_ucode
!= NULL
) {
956 firmware_image_unload(mac
->mac_ucode
);
957 mac
->mac_ucode
= NULL
;
960 if (mac
->mac_pcm
!= NULL
) {
961 firmware_image_unload(mac
->mac_pcm
);
965 if (mac
->mac_iv
!= NULL
) {
966 firmware_image_unload(mac
->mac_iv
);
970 if (mac
->mac_iv_ext
!= NULL
) {
971 firmware_image_unload(mac
->mac_iv_ext
);
972 mac
->mac_iv_ext
= NULL
;
977 bwi_mac_fw_load(struct bwi_mac
*mac
)
979 struct bwi_softc
*sc
= mac
->mac_sc
;
980 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
988 fw
= (const uint32_t *)
989 ((const uint8_t *)mac
->mac_ucode
->fw_image
+ BWI_FWHDR_SZ
);
990 fw_len
= (mac
->mac_ucode
->fw_imglen
- BWI_FWHDR_SZ
) / sizeof(uint32_t);
992 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
,
994 BWI_FW_UCODE_MOBJ
| BWI_WR_MOBJ_AUTOINC
, 0));
995 for (i
= 0; i
< fw_len
; ++i
) {
996 CSR_WRITE_4(sc
, BWI_MOBJ_DATA
, be32toh(fw
[i
]));
1003 fw
= (const uint32_t *)
1004 ((const uint8_t *)mac
->mac_pcm
->fw_image
+ BWI_FWHDR_SZ
);
1005 fw_len
= (mac
->mac_pcm
->fw_imglen
- BWI_FWHDR_SZ
) / sizeof(uint32_t);
1007 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
,
1008 BWI_MOBJ_CTRL_VAL(BWI_FW_PCM_MOBJ
, 0x01ea));
1009 CSR_WRITE_4(sc
, BWI_MOBJ_DATA
, 0x4000);
1011 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
,
1012 BWI_MOBJ_CTRL_VAL(BWI_FW_PCM_MOBJ
, 0x01eb));
1013 for (i
= 0; i
< fw_len
; ++i
) {
1014 CSR_WRITE_4(sc
, BWI_MOBJ_DATA
, be32toh(fw
[i
]));
1018 CSR_WRITE_4(sc
, BWI_MAC_INTR_STATUS
, BWI_ALL_INTRS
);
1019 CSR_WRITE_4(sc
, BWI_MAC_STATUS
,
1020 BWI_MAC_STATUS_UCODE_START
|
1021 BWI_MAC_STATUS_IHREN
|
1022 BWI_MAC_STATUS_INFRA
);
1026 for (i
= 0; i
< NRETRY
; ++i
) {
1027 uint32_t intr_status
;
1029 intr_status
= CSR_READ_4(sc
, BWI_MAC_INTR_STATUS
);
1030 if (intr_status
== BWI_INTR_READY
)
1035 if_printf(ifp
, "firmware (ucode&pcm) loading timed out\n");
1041 CSR_READ_4(sc
, BWI_MAC_INTR_STATUS
); /* dummy read */
1043 fw_rev
= MOBJ_READ_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_FWREV
);
1044 if (fw_rev
> BWI_FW_VERSION3_REVMAX
) {
1045 if_printf(ifp
, "firmware version 4 is not supported yet\n");
1049 if_printf(ifp
, "firmware rev 0x%04x, patch level 0x%04x\n", fw_rev
,
1050 MOBJ_READ_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_FWPATCHLV
));
1055 bwi_mac_gpio_init(struct bwi_mac
*mac
)
1057 struct bwi_softc
*sc
= mac
->mac_sc
;
1058 struct bwi_regwin
*old
, *gpio_rw
;
1059 uint32_t filt
, bits
;
1062 CSR_CLRBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_GPOSEL_MASK
);
1065 CSR_SETBITS_2(sc
, BWI_MAC_GPIO_MASK
, 0xf);
1069 if (sc
->sc_bbp_id
== BWI_BBPID_BCM4301
) {
1073 if (sc
->sc_card_flags
& BWI_CARD_F_PA_GPIO9
) {
1074 CSR_SETBITS_2(sc
, BWI_MAC_GPIO_MASK
, 0x200);
1079 gpio_rw
= BWI_GPIO_REGWIN(sc
);
1080 error
= bwi_regwin_switch(sc
, gpio_rw
, &old
);
1084 CSR_FILT_SETBITS_4(sc
, BWI_GPIO_CTRL
, filt
, bits
);
1086 return bwi_regwin_switch(sc
, old
, NULL
);
1090 bwi_mac_gpio_fini(struct bwi_mac
*mac
)
1092 struct bwi_softc
*sc
= mac
->mac_sc
;
1093 struct bwi_regwin
*old
, *gpio_rw
;
1096 gpio_rw
= BWI_GPIO_REGWIN(sc
);
1097 error
= bwi_regwin_switch(sc
, gpio_rw
, &old
);
1101 CSR_WRITE_4(sc
, BWI_GPIO_CTRL
, 0);
1103 return bwi_regwin_switch(sc
, old
, NULL
);
1107 bwi_mac_fw_load_iv(struct bwi_mac
*mac
, const struct fw_image
*fw
)
1109 struct bwi_softc
*sc
= mac
->mac_sc
;
1110 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
1111 const struct bwi_fwhdr
*hdr
;
1112 const struct bwi_fw_iv
*iv
;
1113 int n
, i
, iv_img_size
;
1115 /* Get the number of IVs in the IV image */
1116 hdr
= (const struct bwi_fwhdr
*)fw
->fw_image
;
1117 n
= be32toh(hdr
->fw_iv_cnt
);
1118 DPRINTF(sc
, "IV count %d\n", n
);
1120 /* Calculate the IV image size, for later sanity check */
1121 iv_img_size
= fw
->fw_imglen
- sizeof(*hdr
);
1123 /* Locate the first IV */
1124 iv
= (const struct bwi_fw_iv
*)
1125 ((const uint8_t *)fw
->fw_image
+ sizeof(*hdr
));
1127 for (i
= 0; i
< n
; ++i
) {
1128 uint16_t iv_ofs
, ofs
;
1131 if (iv_img_size
< sizeof(iv
->iv_ofs
)) {
1132 if_printf(ifp
, "invalid IV image, ofs\n");
1135 iv_img_size
-= sizeof(iv
->iv_ofs
);
1136 sz
+= sizeof(iv
->iv_ofs
);
1138 iv_ofs
= be16toh(iv
->iv_ofs
);
1140 ofs
= __SHIFTOUT(iv_ofs
, BWI_FW_IV_OFS_MASK
);
1141 if (ofs
>= 0x1000) {
1142 if_printf(ifp
, "invalid ofs (0x%04x) "
1143 "for %dth iv\n", ofs
, i
);
1147 if (iv_ofs
& BWI_FW_IV_IS_32BIT
) {
1150 if (iv_img_size
< sizeof(iv
->iv_val
.val32
)) {
1151 if_printf(ifp
, "invalid IV image, val32\n");
1154 iv_img_size
-= sizeof(iv
->iv_val
.val32
);
1155 sz
+= sizeof(iv
->iv_val
.val32
);
1157 val32
= be32toh(iv
->iv_val
.val32
);
1158 CSR_WRITE_4(sc
, ofs
, val32
);
1162 if (iv_img_size
< sizeof(iv
->iv_val
.val16
)) {
1163 if_printf(ifp
, "invalid IV image, val16\n");
1166 iv_img_size
-= sizeof(iv
->iv_val
.val16
);
1167 sz
+= sizeof(iv
->iv_val
.val16
);
1169 val16
= be16toh(iv
->iv_val
.val16
);
1170 CSR_WRITE_2(sc
, ofs
, val16
);
1173 iv
= (const struct bwi_fw_iv
*)((const uint8_t *)iv
+ sz
);
1176 if (iv_img_size
!= 0) {
1177 if_printf(ifp
, "invalid IV image, size left %d\n", iv_img_size
);
1184 bwi_mac_fw_init(struct bwi_mac
*mac
)
1186 struct ifnet
*ifp
= &mac
->mac_sc
->sc_ic
.ic_if
;
1189 error
= bwi_mac_fw_load_iv(mac
, mac
->mac_iv
);
1191 if_printf(ifp
, "load IV failed\n");
1195 if (mac
->mac_iv_ext
!= NULL
) {
1196 error
= bwi_mac_fw_load_iv(mac
, mac
->mac_iv_ext
);
1198 if_printf(ifp
, "load ExtIV failed\n");
1204 bwi_mac_opmode_init(struct bwi_mac
*mac
)
1206 struct bwi_softc
*sc
= mac
->mac_sc
;
1207 struct ieee80211com
*ic
= &sc
->sc_ic
;
1208 uint32_t mac_status
;
1211 CSR_CLRBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_INFRA
);
1212 CSR_SETBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_INFRA
);
1213 CSR_SETBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_PASS_BCN
);
1215 /* Set probe resp timeout to infinite */
1216 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_PROBE_RESP_TO
, 0);
1219 * TODO: factor out following part
1222 mac_status
= CSR_READ_4(sc
, BWI_MAC_STATUS
);
1223 mac_status
&= ~(BWI_MAC_STATUS_OPMODE_HOSTAP
|
1224 BWI_MAC_STATUS_PASS_CTL
|
1225 BWI_MAC_STATUS_PASS_BADPLCP
|
1226 BWI_MAC_STATUS_PASS_BADFCS
|
1227 BWI_MAC_STATUS_PROMISC
);
1228 mac_status
|= BWI_MAC_STATUS_INFRA
;
1230 /* Always turn on PROMISC on old hardware */
1231 if (mac
->mac_rev
< 5)
1232 mac_status
|= BWI_MAC_STATUS_PROMISC
;
1234 switch (ic
->ic_opmode
) {
1235 case IEEE80211_M_IBSS
:
1236 mac_status
&= ~BWI_MAC_STATUS_INFRA
;
1238 case IEEE80211_M_HOSTAP
:
1239 mac_status
|= BWI_MAC_STATUS_OPMODE_HOSTAP
;
1241 case IEEE80211_M_MONITOR
:
1243 /* Do you want data from your microwave oven? */
1244 mac_status
|= BWI_MAC_STATUS_PASS_CTL
|
1245 BWI_MAC_STATUS_PASS_BADPLCP
|
1246 BWI_MAC_STATUS_PASS_BADFCS
;
1248 mac_status
|= BWI_MAC_STATUS_PASS_CTL
;
1256 if (ic
->ic_if
.if_flags
& IFF_PROMISC
)
1257 mac_status
|= BWI_MAC_STATUS_PROMISC
;
1259 CSR_WRITE_4(sc
, BWI_MAC_STATUS
, mac_status
);
1261 if (ic
->ic_opmode
!= IEEE80211_M_IBSS
&&
1262 ic
->ic_opmode
!= IEEE80211_M_HOSTAP
) {
1263 if (sc
->sc_bbp_id
== BWI_BBPID_BCM4306
&& sc
->sc_bbp_rev
== 3)
1270 CSR_WRITE_2(sc
, BWI_MAC_PRE_TBTT
, pre_tbtt
);
1274 bwi_mac_hostflags_init(struct bwi_mac
*mac
)
1276 struct bwi_softc
*sc
= mac
->mac_sc
;
1277 struct bwi_phy
*phy
= &mac
->mac_phy
;
1278 struct bwi_rf
*rf
= &mac
->mac_rf
;
1279 uint64_t host_flags
;
1281 if (phy
->phy_mode
== IEEE80211_MODE_11A
)
1284 host_flags
= HFLAGS_READ(mac
);
1285 host_flags
|= BWI_HFLAG_SYM_WA
;
1287 if (phy
->phy_mode
== IEEE80211_MODE_11G
) {
1288 if (phy
->phy_rev
== 1)
1289 host_flags
|= BWI_HFLAG_GDC_WA
;
1290 if (sc
->sc_card_flags
& BWI_CARD_F_PA_GPIO9
)
1291 host_flags
|= BWI_HFLAG_OFDM_PA
;
1292 } else if (phy
->phy_mode
== IEEE80211_MODE_11B
) {
1293 if (phy
->phy_rev
>= 2 && rf
->rf_type
== BWI_RF_T_BCM2050
)
1294 host_flags
&= ~BWI_HFLAG_GDC_WA
;
1296 panic("unknown PHY mode %u\n", phy
->phy_mode
);
1299 HFLAGS_WRITE(mac
, host_flags
);
1303 bwi_mac_bss_param_init(struct bwi_mac
*mac
)
1305 struct bwi_softc
*sc
= mac
->mac_sc
;
1306 struct bwi_phy
*phy
= &mac
->mac_phy
;
1307 struct bwi_retry_lim lim
;
1311 * Set short/long retry limits
1313 bzero(&lim
, sizeof(lim
));
1314 lim
.shretry
= BWI_SHRETRY
;
1315 lim
.shretry_fb
= BWI_SHRETRY_FB
;
1316 lim
.lgretry
= BWI_LGRETRY
;
1317 lim
.lgretry_fb
= BWI_LGRETRY_FB
;
1318 bwi_mac_set_retry_lim(mac
, &lim
);
1321 * Implicitly prevent firmware from sending probe response
1322 * by setting its "probe response timeout" to 1us.
1324 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_PROBE_RESP_TO
, 1);
1327 * XXX MAC level acknowledge and CW min/max should depend
1328 * on the char rateset of the IBSS/BSS to join.
1332 * Set MAC level acknowledge rates
1334 bwi_mac_set_ackrates(mac
, &sc
->sc_ic
.ic_sup_rates
[phy
->phy_mode
]);
1339 if (phy
->phy_mode
== IEEE80211_MODE_11B
)
1340 cw_min
= IEEE80211_CW_MIN_0
;
1342 cw_min
= IEEE80211_CW_MIN_1
;
1343 MOBJ_WRITE_2(mac
, BWI_80211_MOBJ
, BWI_80211_MOBJ_CWMIN
, cw_min
);
1348 MOBJ_WRITE_2(mac
, BWI_80211_MOBJ
, BWI_80211_MOBJ_CWMAX
,
1353 bwi_mac_set_retry_lim(struct bwi_mac
*mac
, const struct bwi_retry_lim
*lim
)
1355 /* Short/Long retry limit */
1356 MOBJ_WRITE_2(mac
, BWI_80211_MOBJ
, BWI_80211_MOBJ_SHRETRY
,
1358 MOBJ_WRITE_2(mac
, BWI_80211_MOBJ
, BWI_80211_MOBJ_LGRETRY
,
1361 /* Short/Long retry fallback limit */
1362 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_SHRETRY_FB
,
1364 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_LGRETEY_FB
,
1369 bwi_mac_set_ackrates(struct bwi_mac
*mac
, const struct ieee80211_rateset
*rs
)
1373 /* XXX not standard conforming */
1374 for (i
= 0; i
< rs
->rs_nrates
; ++i
) {
1375 enum ieee80211_modtype modtype
;
1378 modtype
= ieee80211_rate2modtype(rs
->rs_rates
[i
]);
1380 case IEEE80211_MODTYPE_DS
:
1383 case IEEE80211_MODTYPE_OFDM
:
1387 panic("unsupported modtype %u\n", modtype
);
1389 ofs
+= (bwi_rate2plcp(rs
->rs_rates
[i
]) & 0xf) * 2;
1391 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, ofs
+ 0x20,
1392 MOBJ_READ_2(mac
, BWI_COMM_MOBJ
, ofs
));
1397 bwi_mac_start(struct bwi_mac
*mac
)
1399 struct bwi_softc
*sc
= mac
->mac_sc
;
1401 CSR_SETBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_ENABLE
);
1402 CSR_WRITE_4(sc
, BWI_MAC_INTR_STATUS
, BWI_INTR_READY
);
1404 /* Flush pending bus writes */
1405 CSR_READ_4(sc
, BWI_MAC_STATUS
);
1406 CSR_READ_4(sc
, BWI_MAC_INTR_STATUS
);
1408 return bwi_mac_config_ps(mac
);
1412 bwi_mac_stop(struct bwi_mac
*mac
)
1414 struct bwi_softc
*sc
= mac
->mac_sc
;
1417 error
= bwi_mac_config_ps(mac
);
1421 CSR_CLRBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_ENABLE
);
1423 /* Flush pending bus write */
1424 CSR_READ_4(sc
, BWI_MAC_STATUS
);
1426 #define NRETRY 10000
1427 for (i
= 0; i
< NRETRY
; ++i
) {
1428 if (CSR_READ_4(sc
, BWI_MAC_INTR_STATUS
) & BWI_INTR_READY
)
1433 if_printf(&sc
->sc_ic
.ic_if
, "can't stop MAC\n");
1442 bwi_mac_config_ps(struct bwi_mac
*mac
)
1444 struct bwi_softc
*sc
= mac
->mac_sc
;
1447 status
= CSR_READ_4(sc
, BWI_MAC_STATUS
);
1449 status
&= ~BWI_MAC_STATUS_HW_PS
;
1450 status
|= BWI_MAC_STATUS_WAKEUP
;
1451 CSR_WRITE_4(sc
, BWI_MAC_STATUS
, status
);
1453 /* Flush pending bus write */
1454 CSR_READ_4(sc
, BWI_MAC_STATUS
);
1456 if (mac
->mac_rev
>= 5) {
1460 for (i
= 0; i
< NRETRY
; ++i
) {
1461 if (MOBJ_READ_2(mac
, BWI_COMM_MOBJ
,
1462 BWI_COMM_MOBJ_UCODE_STATE
) != BWI_UCODE_STATE_PS
)
1467 if_printf(&sc
->sc_ic
.ic_if
, "config PS failed\n");
1476 bwi_mac_reset_hwkeys(struct bwi_mac
*mac
)
1478 /* TODO: firmware crypto */
1479 MOBJ_READ_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_KEYTABLE_OFS
);
1483 bwi_mac_shutdown(struct bwi_mac
*mac
)
1485 struct bwi_softc
*sc
= mac
->mac_sc
;
1488 if (mac
->mac_flags
& BWI_MAC_F_HAS_TXSTATS
)
1489 sc
->sc_free_txstats(sc
);
1491 sc
->sc_free_rx_ring(sc
);
1493 for (i
= 0; i
< BWI_TX_NRING
; ++i
)
1494 sc
->sc_free_tx_ring(sc
, i
);
1500 bwi_mac_gpio_fini(mac
);
1502 bwi_rf_off(mac
); /* XXX again */
1503 CSR_WRITE_2(sc
, BWI_BBP_ATTEN
, BWI_BBP_ATTEN_MAGIC
);
1504 bwi_regwin_disable(sc
, &mac
->mac_regwin
, 0);
1506 mac
->mac_flags
&= ~BWI_MAC_F_INITED
;
1510 bwi_mac_get_property(struct bwi_mac
*mac
)
1512 struct bwi_softc
*sc
= mac
->mac_sc
;
1513 enum bwi_bus_space old_bus_space
;
1519 val
= CSR_READ_4(sc
, BWI_MAC_STATUS
);
1520 if (val
& BWI_MAC_STATUS_BSWAP
) {
1521 DPRINTF(sc
, "%s\n", "need byte swap");
1522 mac
->mac_flags
|= BWI_MAC_F_BSWAP
;
1528 old_bus_space
= sc
->sc_bus_space
;
1530 val
= CSR_READ_4(sc
, BWI_STATE_HI
);
1531 if (__SHIFTOUT(val
, BWI_STATE_HI_FLAGS_MASK
) &
1532 BWI_STATE_HI_FLAG_64BIT
) {
1534 sc
->sc_bus_space
= BWI_BUS_SPACE_64BIT
;
1535 DPRINTF(sc
, "%s\n", "64bit bus space");
1537 uint32_t txrx_reg
= BWI_TXRX_CTRL_BASE
+ BWI_TX32_CTRL
;
1539 CSR_WRITE_4(sc
, txrx_reg
, BWI_TXRX32_CTRL_ADDRHI_MASK
);
1540 if (CSR_READ_4(sc
, txrx_reg
) & BWI_TXRX32_CTRL_ADDRHI_MASK
) {
1542 sc
->sc_bus_space
= BWI_BUS_SPACE_32BIT
;
1543 DPRINTF(sc
, "%s\n", "32bit bus space");
1546 sc
->sc_bus_space
= BWI_BUS_SPACE_30BIT
;
1547 DPRINTF(sc
, "%s\n", "30bit bus space");
1551 if (old_bus_space
!= 0 && old_bus_space
!= sc
->sc_bus_space
) {
1552 device_printf(sc
->sc_dev
, "MACs bus space mismatch!\n");
1559 bwi_mac_updateslot(struct bwi_mac
*mac
, int shslot
)
1563 if (mac
->mac_phy
.phy_mode
== IEEE80211_MODE_11B
)
1567 slot_time
= IEEE80211_DUR_SHSLOT
;
1569 slot_time
= IEEE80211_DUR_SLOT
;
1571 CSR_WRITE_2(mac
->mac_sc
, BWI_MAC_SLOTTIME
,
1572 slot_time
+ BWI_MAC_SLOTTIME_ADJUST
);
1573 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_SLOTTIME
, slot_time
);
1577 bwi_mac_attach(struct bwi_softc
*sc
, int id
, uint8_t rev
)
1579 struct bwi_mac
*mac
;
1582 KKASSERT(sc
->sc_nmac
<= BWI_MAC_MAX
&& sc
->sc_nmac
>= 0);
1584 if (sc
->sc_nmac
== BWI_MAC_MAX
) {
1585 device_printf(sc
->sc_dev
, "too many MACs\n");
1590 * More than one MAC is only supported by BCM4309
1592 if (sc
->sc_nmac
!= 0 &&
1593 pci_get_device(sc
->sc_dev
) != PCI_PRODUCT_BROADCOM_BCM4309
) {
1594 DPRINTF(sc
, "%s\n", "ignore second MAC");
1598 mac
= &sc
->sc_mac
[sc
->sc_nmac
];
1600 /* XXX will this happen? */
1601 if (BWI_REGWIN_EXIST(&mac
->mac_regwin
)) {
1602 device_printf(sc
->sc_dev
, "%dth MAC already attached\n",
1608 * Test whether the revision of this MAC is supported
1610 #define N(arr) (int)(sizeof(arr) / sizeof(arr[0]))
1611 for (i
= 0; i
< N(bwi_sup_macrev
); ++i
) {
1612 if (bwi_sup_macrev
[i
] == rev
)
1615 if (i
== N(bwi_sup_macrev
)) {
1616 device_printf(sc
->sc_dev
, "MAC rev %u is "
1617 "not supported\n", rev
);
1622 BWI_CREATE_MAC(mac
, sc
, id
, rev
);
1625 if (mac
->mac_rev
< 5) {
1626 mac
->mac_flags
|= BWI_MAC_F_HAS_TXSTATS
;
1627 DPRINTF(sc
, "%s\n", "has TX stats");
1633 static __inline
void
1634 bwi_mac_balance_atten(int *bbp_atten0
, int *rf_atten0
)
1636 int bbp_atten
, rf_atten
, rf_atten_lim
= -1;
1638 bbp_atten
= *bbp_atten0
;
1639 rf_atten
= *rf_atten0
;
1642 * RF attenuation affects TX power BWI_RF_ATTEN_FACTOR times
1643 * as much as BBP attenuation, so we try our best to keep RF
1644 * attenuation within range. BBP attenuation will be clamped
1645 * later if it is out of range during balancing.
1647 * BWI_RF_ATTEN_MAX0 is used as RF attenuation upper limit.
1651 * Use BBP attenuation to balance RF attenuation
1655 else if (rf_atten
> BWI_RF_ATTEN_MAX0
)
1656 rf_atten_lim
= BWI_RF_ATTEN_MAX0
;
1658 if (rf_atten_lim
>= 0) {
1659 bbp_atten
+= (BWI_RF_ATTEN_FACTOR
* (rf_atten
- rf_atten_lim
));
1660 rf_atten
= rf_atten_lim
;
1664 * If possible, use RF attenuation to balance BBP attenuation
1665 * NOTE: RF attenuation is still kept within range.
1667 while (rf_atten
< BWI_RF_ATTEN_MAX0
&& bbp_atten
> BWI_BBP_ATTEN_MAX
) {
1668 bbp_atten
-= BWI_RF_ATTEN_FACTOR
;
1671 while (rf_atten
> 0 && bbp_atten
< 0) {
1672 bbp_atten
+= BWI_RF_ATTEN_FACTOR
;
1676 /* RF attenuation MUST be within range */
1677 KKASSERT(rf_atten
>= 0 && rf_atten
<= BWI_RF_ATTEN_MAX0
);
1680 * Clamp BBP attenuation
1684 else if (bbp_atten
> BWI_BBP_ATTEN_MAX
)
1685 bbp_atten
= BWI_BBP_ATTEN_MAX
;
1687 *rf_atten0
= rf_atten
;
1688 *bbp_atten0
= bbp_atten
;
1692 bwi_mac_adjust_tpctl(struct bwi_mac
*mac
, int rf_atten_adj
, int bbp_atten_adj
)
1694 struct bwi_softc
*sc
= mac
->mac_sc
;
1695 struct bwi_rf
*rf
= &mac
->mac_rf
;
1696 struct bwi_tpctl tpctl
;
1697 int bbp_atten
, rf_atten
, tp_ctrl1
;
1699 bcopy(&mac
->mac_tpctl
, &tpctl
, sizeof(tpctl
));
1701 /* NOTE: Use signed value to do calulation */
1702 bbp_atten
= tpctl
.bbp_atten
;
1703 rf_atten
= tpctl
.rf_atten
;
1704 tp_ctrl1
= tpctl
.tp_ctrl1
;
1706 bbp_atten
+= bbp_atten_adj
;
1707 rf_atten
+= rf_atten_adj
;
1709 bwi_mac_balance_atten(&bbp_atten
, &rf_atten
);
1711 if (rf
->rf_type
== BWI_RF_T_BCM2050
&& rf
->rf_rev
== 2) {
1712 if (rf_atten
<= 1) {
1713 if (tp_ctrl1
== 0) {
1717 } else if (sc
->sc_card_flags
& BWI_CARD_F_PA_GPIO9
) {
1719 (BWI_RF_ATTEN_FACTOR
* (rf_atten
- 2));
1722 } else if (rf_atten
> 4 && tp_ctrl1
!= 0) {
1724 if (bbp_atten
< 3) {
1732 bwi_mac_balance_atten(&bbp_atten
, &rf_atten
);
1735 tpctl
.bbp_atten
= bbp_atten
;
1736 tpctl
.rf_atten
= rf_atten
;
1737 tpctl
.tp_ctrl1
= tp_ctrl1
;
1740 bwi_mac_set_tpctl_11bg(mac
, &tpctl
);
1741 bwi_mac_unlock(mac
);
1745 * http://bcm-specs.sipsolutions.net/RecalculateTransmissionPower
1748 bwi_mac_calibrate_txpower(struct bwi_mac
*mac
)
1750 struct bwi_softc
*sc
= mac
->mac_sc
;
1751 struct bwi_rf
*rf
= &mac
->mac_rf
;
1752 int8_t tssi
[4], tssi_avg
, cur_txpwr
;
1753 int error
, i
, ofdm_tssi
;
1754 int txpwr_diff
, rf_atten_adj
, bbp_atten_adj
;
1756 if (mac
->mac_flags
& BWI_MAC_F_TPCTL_ERROR
) {
1757 DPRINTF(sc
, "%s\n", "tpctl error happened, can't set txpower");
1761 if (BWI_IS_BRCM_BU4306(sc
)) {
1762 DPRINTF(sc
, "%s\n", "BU4306, can't set txpower");
1767 * Save latest TSSI and reset the related memory objects
1770 error
= bwi_rf_get_latest_tssi(mac
, tssi
, BWI_COMM_MOBJ_TSSI_DS
);
1772 DPRINTF(sc
, "%s\n", "no DS tssi");
1774 if (mac
->mac_phy
.phy_mode
== IEEE80211_MODE_11B
)
1777 error
= bwi_rf_get_latest_tssi(mac
, tssi
,
1778 BWI_COMM_MOBJ_TSSI_OFDM
);
1780 DPRINTF(sc
, "%s\n", "no OFDM tssi");
1784 for (i
= 0; i
< 4; ++i
) {
1790 bwi_rf_clear_tssi(mac
);
1792 DPRINTF(sc
, "tssi0 %d, tssi1 %d, tssi2 %d, tssi3 %d\n",
1793 tssi
[0], tssi
[1], tssi
[2], tssi
[3]);
1796 * Calculate RF/BBP attenuation adjustment based on
1797 * the difference between desired TX power and sampled
1800 /* +8 == "each incremented by 1/2" */
1801 tssi_avg
= (tssi
[0] + tssi
[1] + tssi
[2] + tssi
[3] + 8) / 4;
1802 if (ofdm_tssi
&& (HFLAGS_READ(mac
) & BWI_HFLAG_PWR_BOOST_DS
))
1805 DPRINTF(sc
, "tssi avg %d\n", tssi_avg
);
1807 error
= bwi_rf_tssi2dbm(mac
, tssi_avg
, &cur_txpwr
);
1810 DPRINTF(sc
, "current txpower %d\n", cur_txpwr
);
1812 txpwr_diff
= rf
->rf_txpower_max
- cur_txpwr
; /* XXX ni_txpower */
1814 rf_atten_adj
= -howmany(txpwr_diff
, 8);
1815 bbp_atten_adj
= -(txpwr_diff
/ 2) -
1816 (BWI_RF_ATTEN_FACTOR
* rf_atten_adj
);
1818 if (rf_atten_adj
== 0 && bbp_atten_adj
== 0) {
1819 DPRINTF(sc
, "%s\n", "no need to adjust RF/BBP attenuation");
1824 DPRINTF(sc
, "rf atten adjust %d, bbp atten adjust %d\n",
1825 rf_atten_adj
, bbp_atten_adj
);
1826 bwi_mac_adjust_tpctl(mac
, rf_atten_adj
, bbp_atten_adj
);
1831 bwi_mac_lock(struct bwi_mac
*mac
)
1833 struct bwi_softc
*sc
= mac
->mac_sc
;
1834 struct ieee80211com
*ic
= &sc
->sc_ic
;
1836 KKASSERT((mac
->mac_flags
& BWI_MAC_F_LOCKED
) == 0);
1838 if (mac
->mac_rev
< 3)
1840 else if (ic
->ic_opmode
!= IEEE80211_M_HOSTAP
)
1841 bwi_mac_config_ps(mac
);
1843 CSR_SETBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_RFLOCK
);
1845 /* Flush pending bus write */
1846 CSR_READ_4(sc
, BWI_MAC_STATUS
);
1849 mac
->mac_flags
|= BWI_MAC_F_LOCKED
;
1853 bwi_mac_unlock(struct bwi_mac
*mac
)
1855 struct bwi_softc
*sc
= mac
->mac_sc
;
1856 struct ieee80211com
*ic
= &sc
->sc_ic
;
1858 KKASSERT(mac
->mac_flags
& BWI_MAC_F_LOCKED
);
1860 CSR_READ_2(sc
, BWI_PHYINFO
); /* dummy read */
1862 CSR_CLRBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_RFLOCK
);
1864 if (mac
->mac_rev
< 3)
1866 else if (ic
->ic_opmode
!= IEEE80211_M_HOSTAP
)
1867 bwi_mac_config_ps(mac
);
1869 mac
->mac_flags
&= ~BWI_MAC_F_LOCKED
;
1873 bwi_mac_set_promisc(struct bwi_mac
*mac
, int promisc
)
1875 struct bwi_softc
*sc
= mac
->mac_sc
;
1877 if (mac
->mac_rev
< 5) /* Promisc is always on */
1881 CSR_SETBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_PROMISC
);
1883 CSR_CLRBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_PROMISC
);