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.3 2007/09/16 04:24:30 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_radiotap.h>
58 #include <netproto/802_11/ieee80211_var.h>
60 #include <bus/pci/pcireg.h>
61 #include <bus/pci/pcivar.h>
62 #include <bus/pci/pcidevs.h>
65 #include "if_bwireg.h"
66 #include "if_bwivar.h"
71 struct bwi_retry_lim
{
78 static int bwi_mac_test(struct bwi_mac
*);
79 static int bwi_mac_get_property(struct bwi_mac
*);
81 static void bwi_mac_set_retry_lim(struct bwi_mac
*,
82 const struct bwi_retry_lim
*);
83 static void bwi_mac_set_ackrates(struct bwi_mac
*,
84 const struct ieee80211_rateset
*);
86 static int bwi_mac_gpio_init(struct bwi_mac
*);
87 static int bwi_mac_gpio_fini(struct bwi_mac
*);
88 static void bwi_mac_opmode_init(struct bwi_mac
*);
89 static void bwi_mac_hostflags_init(struct bwi_mac
*);
90 static void bwi_mac_bss_param_init(struct bwi_mac
*);
92 static int bwi_mac_fw_alloc(struct bwi_mac
*);
93 static void bwi_mac_fw_free(struct bwi_mac
*);
94 static int bwi_mac_fw_load(struct bwi_mac
*);
95 static int bwi_mac_fw_init(struct bwi_mac
*);
96 static int bwi_mac_fw_load_iv(struct bwi_mac
*, const struct fw_image
*);
98 static void bwi_mac_setup_tpctl(struct bwi_mac
*);
99 static void bwi_mac_adjust_tpctl(struct bwi_mac
*, int, int);
101 static void bwi_mac_lock(struct bwi_mac
*);
102 static void bwi_mac_unlock(struct bwi_mac
*);
104 static const uint8_t bwi_sup_macrev
[] = { 2, 4, 5, 6, 7, 9, 10 };
107 bwi_tmplt_write_4(struct bwi_mac
*mac
, uint32_t ofs
, uint32_t val
)
109 struct bwi_softc
*sc
= mac
->mac_sc
;
111 if (mac
->mac_flags
& BWI_MAC_F_BSWAP
)
114 CSR_WRITE_4(sc
, BWI_MAC_TMPLT_CTRL
, ofs
);
115 CSR_WRITE_4(sc
, BWI_MAC_TMPLT_DATA
, val
);
119 bwi_hostflags_write(struct bwi_mac
*mac
, uint64_t flags
)
123 val
= flags
& 0xffff;
124 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_HFLAGS_LO
, val
);
126 val
= (flags
>> 16) & 0xffff;
127 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_HFLAGS_MI
, val
);
129 /* HI has unclear meaning, so leave it as it is */
133 bwi_hostflags_read(struct bwi_mac
*mac
)
137 /* HI has unclear meaning, so don't touch it */
140 val
= MOBJ_READ_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_HFLAGS_MI
);
143 val
= MOBJ_READ_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_HFLAGS_LO
);
150 bwi_memobj_read_2(struct bwi_mac
*mac
, uint16_t obj_id
, uint16_t ofs0
)
152 struct bwi_softc
*sc
= mac
->mac_sc
;
156 data_reg
= BWI_MOBJ_DATA
;
160 data_reg
= BWI_MOBJ_DATA_UNALIGN
;
162 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
, BWI_MOBJ_CTRL_VAL(obj_id
, ofs
));
163 return CSR_READ_2(sc
, data_reg
);
167 bwi_memobj_read_4(struct bwi_mac
*mac
, uint16_t obj_id
, uint16_t ofs0
)
169 struct bwi_softc
*sc
= mac
->mac_sc
;
176 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
, BWI_MOBJ_CTRL_VAL(obj_id
, ofs
));
177 ret
= CSR_READ_2(sc
, BWI_MOBJ_DATA_UNALIGN
);
180 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
,
181 BWI_MOBJ_CTRL_VAL(obj_id
, ofs
+ 1));
182 ret
|= CSR_READ_2(sc
, BWI_MOBJ_DATA
);
186 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
, BWI_MOBJ_CTRL_VAL(obj_id
, ofs
));
187 return CSR_READ_4(sc
, BWI_MOBJ_DATA
);
192 bwi_memobj_write_2(struct bwi_mac
*mac
, uint16_t obj_id
, uint16_t ofs0
,
195 struct bwi_softc
*sc
= mac
->mac_sc
;
199 data_reg
= BWI_MOBJ_DATA
;
203 data_reg
= BWI_MOBJ_DATA_UNALIGN
;
205 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
, BWI_MOBJ_CTRL_VAL(obj_id
, ofs
));
206 CSR_WRITE_2(sc
, data_reg
, v
);
210 bwi_memobj_write_4(struct bwi_mac
*mac
, uint16_t obj_id
, uint16_t ofs0
,
213 struct bwi_softc
*sc
= mac
->mac_sc
;
218 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
, BWI_MOBJ_CTRL_VAL(obj_id
, ofs
));
219 CSR_WRITE_2(sc
, BWI_MOBJ_DATA_UNALIGN
, v
>> 16);
221 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
,
222 BWI_MOBJ_CTRL_VAL(obj_id
, ofs
+ 1));
223 CSR_WRITE_2(sc
, BWI_MOBJ_DATA
, v
& 0xffff);
225 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
, BWI_MOBJ_CTRL_VAL(obj_id
, ofs
));
226 CSR_WRITE_4(sc
, BWI_MOBJ_DATA
, v
);
231 bwi_mac_lateattach(struct bwi_mac
*mac
)
235 if (mac
->mac_rev
>= 5)
236 CSR_READ_4(mac
->mac_sc
, BWI_STATE_HI
); /* dummy read */
238 bwi_mac_reset(mac
, 1);
240 error
= bwi_phy_attach(mac
);
244 error
= bwi_rf_attach(mac
);
248 /* Link 11B/G PHY, unlink 11A PHY */
249 if (mac
->mac_phy
.phy_mode
== IEEE80211_MODE_11A
)
250 bwi_mac_reset(mac
, 0);
252 bwi_mac_reset(mac
, 1);
254 error
= bwi_mac_test(mac
);
258 error
= bwi_mac_get_property(mac
);
262 error
= bwi_rf_map_txpower(mac
);
267 CSR_WRITE_2(mac
->mac_sc
, BWI_BBP_ATTEN
, BWI_BBP_ATTEN_MAGIC
);
268 bwi_regwin_disable(mac
->mac_sc
, &mac
->mac_regwin
, 0);
274 bwi_mac_init(struct bwi_mac
*mac
)
276 struct bwi_softc
*sc
= mac
->mac_sc
;
279 /* Clear MAC/PHY/RF states */
280 bwi_mac_setup_tpctl(mac
);
281 bwi_rf_clear_state(&mac
->mac_rf
);
282 bwi_phy_clear_state(&mac
->mac_phy
);
284 /* Enable MAC and linked it to PHY */
285 if (!bwi_regwin_is_enabled(sc
, &mac
->mac_regwin
))
286 bwi_mac_reset(mac
, 1);
288 /* Initialize backplane */
289 error
= bwi_bus_init(sc
, mac
);
293 /* XXX work around for hardware bugs? */
294 if (sc
->sc_bus_regwin
.rw_rev
<= 5 &&
295 sc
->sc_bus_regwin
.rw_type
!= BWI_REGWIN_T_BUSPCIE
) {
296 CSR_SETBITS_4(sc
, BWI_CONF_LO
,
297 __SHIFTIN(BWI_CONF_LO_SERVTO
, BWI_CONF_LO_SERVTO_MASK
) |
298 __SHIFTIN(BWI_CONF_LO_REQTO
, BWI_CONF_LO_REQTO_MASK
));
302 error
= bwi_phy_calibrate(mac
);
304 if_printf(&sc
->sc_ic
.ic_if
, "PHY calibrate failed\n");
308 /* Prepare to initialize firmware */
309 CSR_WRITE_4(sc
, BWI_MAC_STATUS
,
310 BWI_MAC_STATUS_UCODE_JUMP0
|
311 BWI_MAC_STATUS_IHREN
);
314 * Load and initialize firmwares
316 error
= bwi_mac_fw_alloc(mac
);
320 error
= bwi_mac_fw_load(mac
);
324 error
= bwi_mac_gpio_init(mac
);
328 error
= bwi_mac_fw_init(mac
);
337 /* TODO: LED, hardware rf enabled is only related to LED setting */
342 CSR_WRITE_4(sc
, BWI_BBP_ATTEN
, 0);
345 /* TODO: interference mitigation */
350 bwi_rf_set_ant_mode(mac
, mac
->mac_rf
.rf_ant_mode
);
353 * Initialize operation mode (RX configuration)
355 bwi_mac_opmode_init(mac
);
357 /* XXX what's these */
358 if (mac
->mac_rev
< 3) {
359 CSR_WRITE_2(sc
, 0x60e, 0);
360 CSR_WRITE_2(sc
, 0x610, 0x8000);
361 CSR_WRITE_2(sc
, 0x604, 0);
362 CSR_WRITE_2(sc
, 0x606, 0x200);
364 CSR_WRITE_4(sc
, 0x188, 0x80000000);
365 CSR_WRITE_4(sc
, 0x18c, 0x2000000);
369 * Initialize TX/RX interrupts' mask
371 CSR_WRITE_4(sc
, BWI_MAC_INTR_STATUS
, BWI_INTR_TIMER1
);
372 for (i
= 0; i
< BWI_TXRX_NRING
; ++i
) {
375 if (BWI_TXRX_IS_RX(i
))
376 intrs
= BWI_TXRX_RX_INTRS
;
378 intrs
= BWI_TXRX_TX_INTRS
;
379 CSR_WRITE_4(sc
, BWI_TXRX_INTR_MASK(i
), intrs
);
382 /* XXX what's this */
383 CSR_SETBITS_4(sc
, BWI_STATE_LO
, 0x100000);
385 /* Setup MAC power up delay */
386 CSR_WRITE_2(sc
, BWI_MAC_POWERUP_DELAY
, sc
->sc_pwron_delay
);
388 /* Set MAC regwin revision */
389 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_MACREV
, mac
->mac_rev
);
392 * Initialize host flags
394 bwi_mac_hostflags_init(mac
);
397 * Initialize BSS parameters
399 bwi_mac_bss_param_init(mac
);
402 * Initialize TX rings
404 for (i
= 0; i
< BWI_TX_NRING
; ++i
) {
405 error
= sc
->sc_init_tx_ring(sc
, i
);
407 if_printf(&sc
->sc_ic
.ic_if
,
408 "can't initialize %dth TX ring\n", i
);
416 error
= sc
->sc_init_rx_ring(sc
);
418 if_printf(&sc
->sc_ic
.ic_if
, "can't initialize RX ring\n");
423 * Initialize TX stats if the current MAC uses that
425 if (mac
->mac_flags
& BWI_MAC_F_HAS_TXSTATS
) {
426 error
= sc
->sc_init_txstats(sc
);
428 if_printf(&sc
->sc_ic
.ic_if
,
429 "can't initialize TX stats ring\n");
434 /* XXX what's these */
435 CSR_WRITE_2(sc
, 0x612, 0x50); /* Force Pre-TBTT to 80? */
436 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, 0x416, 0x50);
437 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, 0x414, 0x1f4);
439 mac
->mac_flags
|= BWI_MAC_F_INITED
;
444 bwi_mac_reset(struct bwi_mac
*mac
, int link_phy
)
446 struct bwi_softc
*sc
= mac
->mac_sc
;
447 uint32_t flags
, state_lo
, status
;
449 flags
= BWI_STATE_LO_FLAG_PHYRST
| BWI_STATE_LO_FLAG_PHYCLKEN
;
451 flags
|= BWI_STATE_LO_FLAG_PHYLNK
;
452 bwi_regwin_enable(sc
, &mac
->mac_regwin
, flags
);
455 state_lo
= CSR_READ_4(sc
, BWI_STATE_LO
);
456 state_lo
|= BWI_STATE_LO_GATED_CLOCK
;
457 state_lo
&= ~__SHIFTIN(BWI_STATE_LO_FLAG_PHYRST
,
458 BWI_STATE_LO_FLAGS_MASK
);
459 CSR_WRITE_4(sc
, BWI_STATE_LO
, state_lo
);
460 /* Flush pending bus write */
461 CSR_READ_4(sc
, BWI_STATE_LO
);
464 state_lo
&= ~BWI_STATE_LO_GATED_CLOCK
;
465 CSR_WRITE_4(sc
, BWI_STATE_LO
, state_lo
);
466 /* Flush pending bus write */
467 CSR_READ_4(sc
, BWI_STATE_LO
);
470 CSR_WRITE_2(sc
, BWI_BBP_ATTEN
, 0);
472 status
= CSR_READ_4(sc
, BWI_MAC_STATUS
);
473 status
|= BWI_MAC_STATUS_IHREN
;
475 status
|= BWI_MAC_STATUS_PHYLNK
;
477 status
&= ~BWI_MAC_STATUS_PHYLNK
;
478 CSR_WRITE_4(sc
, BWI_MAC_STATUS
, status
);
481 DPRINTF(sc
, "%s\n", "PHY is linked");
482 mac
->mac_phy
.phy_flags
|= BWI_PHY_F_LINKED
;
484 DPRINTF(sc
, "%s\n", "PHY is unlinked");
485 mac
->mac_phy
.phy_flags
&= ~BWI_PHY_F_LINKED
;
490 bwi_mac_set_tpctl_11bg(struct bwi_mac
*mac
, const struct bwi_tpctl
*new_tpctl
)
492 struct bwi_rf
*rf
= &mac
->mac_rf
;
493 struct bwi_tpctl
*tpctl
= &mac
->mac_tpctl
;
495 if (new_tpctl
!= NULL
) {
496 KKASSERT(new_tpctl
->bbp_atten
<= BWI_BBP_ATTEN_MAX
);
497 KKASSERT(new_tpctl
->rf_atten
<=
498 (rf
->rf_rev
< 6 ? BWI_RF_ATTEN_MAX0
499 : BWI_RF_ATTEN_MAX1
));
500 KKASSERT(new_tpctl
->tp_ctrl1
<= BWI_TPCTL1_MAX
);
502 tpctl
->bbp_atten
= new_tpctl
->bbp_atten
;
503 tpctl
->rf_atten
= new_tpctl
->rf_atten
;
504 tpctl
->tp_ctrl1
= new_tpctl
->tp_ctrl1
;
507 /* Set BBP attenuation */
508 bwi_phy_set_bbp_atten(mac
, tpctl
->bbp_atten
);
510 /* Set RF attenuation */
511 RF_WRITE(mac
, BWI_RFR_ATTEN
, tpctl
->rf_atten
);
512 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_RF_ATTEN
,
516 if (rf
->rf_type
== BWI_RF_T_BCM2050
) {
517 RF_FILT_SETBITS(mac
, BWI_RFR_TXPWR
, ~BWI_RFR_TXPWR1_MASK
,
518 __SHIFTIN(tpctl
->tp_ctrl1
, BWI_RFR_TXPWR1_MASK
));
521 /* Adjust RF Local Oscillator */
522 if (mac
->mac_phy
.phy_mode
== IEEE80211_MODE_11G
)
523 bwi_rf_lo_adjust(mac
, tpctl
);
527 bwi_mac_test(struct bwi_mac
*mac
)
529 struct bwi_softc
*sc
= mac
->mac_sc
;
530 uint32_t orig_val
, val
;
532 #define TEST_VAL1 0xaa5555aa
533 #define TEST_VAL2 0x55aaaa55
535 /* Save it for later restoring */
536 orig_val
= MOBJ_READ_4(mac
, BWI_COMM_MOBJ
, 0);
539 MOBJ_WRITE_4(mac
, BWI_COMM_MOBJ
, 0, TEST_VAL1
);
540 val
= MOBJ_READ_4(mac
, BWI_COMM_MOBJ
, 0);
541 if (val
!= TEST_VAL1
) {
542 device_printf(sc
->sc_dev
, "TEST1 failed\n");
547 MOBJ_WRITE_4(mac
, BWI_COMM_MOBJ
, 0, TEST_VAL2
);
548 val
= MOBJ_READ_4(mac
, BWI_COMM_MOBJ
, 0);
549 if (val
!= TEST_VAL2
) {
550 device_printf(sc
->sc_dev
, "TEST2 failed\n");
554 /* Restore to the original value */
555 MOBJ_WRITE_4(mac
, BWI_COMM_MOBJ
, 0, orig_val
);
557 val
= CSR_READ_4(sc
, BWI_MAC_STATUS
);
558 if ((val
& ~BWI_MAC_STATUS_PHYLNK
) != BWI_MAC_STATUS_IHREN
) {
559 device_printf(sc
->sc_dev
, "%s failed, MAC status 0x%08x\n",
564 val
= CSR_READ_4(sc
, BWI_MAC_INTR_STATUS
);
566 device_printf(sc
->sc_dev
, "%s failed, intr status %08x\n",
578 bwi_mac_setup_tpctl(struct bwi_mac
*mac
)
580 struct bwi_softc
*sc
= mac
->mac_sc
;
581 struct bwi_rf
*rf
= &mac
->mac_rf
;
582 struct bwi_phy
*phy
= &mac
->mac_phy
;
583 struct bwi_tpctl
*tpctl
= &mac
->mac_tpctl
;
585 /* Calc BBP attenuation */
586 if (rf
->rf_type
== BWI_RF_T_BCM2050
&& rf
->rf_rev
< 6)
587 tpctl
->bbp_atten
= 0;
589 tpctl
->bbp_atten
= 2;
591 /* Calc TX power CTRL1?? */
593 if (rf
->rf_type
== BWI_RF_T_BCM2050
) {
596 else if (rf
->rf_rev
< 6)
598 else if (rf
->rf_rev
== 8)
602 /* Empty TX power CTRL2?? */
603 tpctl
->tp_ctrl2
= 0xffff;
606 * Calc RF attenuation
608 if (phy
->phy_mode
== IEEE80211_MODE_11A
) {
609 tpctl
->rf_atten
= 0x60;
613 if (BWI_IS_BRCM_BCM4309G(sc
) && sc
->sc_pci_revid
< 0x51) {
614 tpctl
->rf_atten
= sc
->sc_pci_revid
< 0x43 ? 2 : 3;
620 if (rf
->rf_type
!= BWI_RF_T_BCM2050
) {
621 if (rf
->rf_type
== BWI_RF_T_BCM2053
&& rf
->rf_rev
== 1)
627 * NB: If we reaches here and the card is BRCM_BCM4309G,
628 * then the card's PCI revision must >= 0x51
632 switch (rf
->rf_rev
) {
634 if (phy
->phy_mode
== IEEE80211_MODE_11G
) {
635 if (BWI_IS_BRCM_BCM4309G(sc
) || BWI_IS_BRCM_BU4306(sc
))
640 if (BWI_IS_BRCM_BCM4309G(sc
))
647 if (phy
->phy_mode
== IEEE80211_MODE_11G
) {
649 * NOTE: Order of following conditions is critical
651 if (BWI_IS_BRCM_BCM4309G(sc
))
653 else if (BWI_IS_BRCM_BU4306(sc
))
655 else if (sc
->sc_bbp_id
== BWI_BBPID_BCM4320
)
668 tpctl
->rf_atten
= 0x1a;
672 DPRINTF(sc
, "bbp atten: %u, rf atten: %u, ctrl1: %u, ctrl2: %u\n",
673 tpctl
->bbp_atten
, tpctl
->rf_atten
,
674 tpctl
->tp_ctrl1
, tpctl
->tp_ctrl2
);
678 bwi_mac_dummy_xmit(struct bwi_mac
*mac
)
681 static const uint32_t packet_11a
[PACKET_LEN
] =
682 { 0x000201cc, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 };
683 static const uint32_t packet_11bg
[PACKET_LEN
] =
684 { 0x000b846e, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 };
686 struct bwi_softc
*sc
= mac
->mac_sc
;
687 struct bwi_rf
*rf
= &mac
->mac_rf
;
688 const uint32_t *packet
;
692 if (mac
->mac_phy
.phy_mode
== IEEE80211_MODE_11A
) {
698 packet
= packet_11bg
;
702 for (i
= 0; i
< PACKET_LEN
; ++i
)
703 TMPLT_WRITE_4(mac
, i
* 4, packet
[i
]);
705 CSR_READ_4(sc
, BWI_MAC_STATUS
); /* dummy read */
707 CSR_WRITE_2(sc
, 0x568, 0);
708 CSR_WRITE_2(sc
, 0x7c0, 0);
709 CSR_WRITE_2(sc
, 0x50c, val_50c
);
710 CSR_WRITE_2(sc
, 0x508, 0);
711 CSR_WRITE_2(sc
, 0x50a, 0);
712 CSR_WRITE_2(sc
, 0x54c, 0);
713 CSR_WRITE_2(sc
, 0x56a, 0x14);
714 CSR_WRITE_2(sc
, 0x568, 0x826);
715 CSR_WRITE_2(sc
, 0x500, 0);
716 CSR_WRITE_2(sc
, 0x502, 0x30);
718 if (rf
->rf_type
== BWI_RF_T_BCM2050
&& rf
->rf_rev
<= 5)
719 RF_WRITE(mac
, 0x51, 0x17);
721 for (i
= 0; i
< wait_max
; ++i
) {
722 if (CSR_READ_2(sc
, 0x50e) & 0x80)
726 for (i
= 0; i
< 10; ++i
) {
727 if (CSR_READ_2(sc
, 0x50e) & 0x400)
731 for (i
= 0; i
< 10; ++i
) {
732 if ((CSR_READ_2(sc
, 0x690) & 0x100) == 0)
737 if (rf
->rf_type
== BWI_RF_T_BCM2050
&& rf
->rf_rev
<= 5)
738 RF_WRITE(mac
, 0x51, 0x37);
743 bwi_mac_init_tpctl_11bg(struct bwi_mac
*mac
)
745 struct bwi_softc
*sc
= mac
->mac_sc
;
746 struct bwi_phy
*phy
= &mac
->mac_phy
;
747 struct bwi_rf
*rf
= &mac
->mac_rf
;
748 struct bwi_tpctl tpctl_orig
;
749 int restore_tpctl
= 0;
751 KKASSERT(phy
->phy_mode
!= IEEE80211_MODE_11A
);
753 if (BWI_IS_BRCM_BU4306(sc
))
756 PHY_WRITE(mac
, 0x28, 0x8018);
757 CSR_CLRBITS_2(sc
, BWI_BBP_ATTEN
, 0x20);
759 if (phy
->phy_mode
== IEEE80211_MODE_11G
) {
760 if ((phy
->phy_flags
& BWI_PHY_F_LINKED
) == 0)
762 PHY_WRITE(mac
, 0x47a, 0xc111);
764 if (mac
->mac_flags
& BWI_MAC_F_TPCTL_INITED
)
767 if (phy
->phy_mode
== IEEE80211_MODE_11B
&& phy
->phy_rev
>= 2 &&
768 rf
->rf_type
== BWI_RF_T_BCM2050
) {
769 RF_SETBITS(mac
, 0x76, 0x84);
771 struct bwi_tpctl tpctl
;
773 /* Backup original TX power control variables */
774 bcopy(&mac
->mac_tpctl
, &tpctl_orig
, sizeof(tpctl_orig
));
777 bcopy(&mac
->mac_tpctl
, &tpctl
, sizeof(tpctl
));
778 tpctl
.bbp_atten
= 11;
781 if (rf
->rf_rev
>= 6 && rf
->rf_rev
<= 8)
787 bwi_mac_set_tpctl_11bg(mac
, &tpctl
);
790 bwi_mac_dummy_xmit(mac
);
792 mac
->mac_flags
|= BWI_MAC_F_TPCTL_INITED
;
793 rf
->rf_base_tssi
= PHY_READ(mac
, 0x29);
794 DPRINTF(sc
, "base tssi %d\n", rf
->rf_base_tssi
);
796 if (abs(rf
->rf_base_tssi
- rf
->rf_idle_tssi
) >= 20) {
797 if_printf(&sc
->sc_ic
.ic_if
, "base tssi measure failed\n");
798 mac
->mac_flags
|= BWI_MAC_F_TPCTL_ERROR
;
802 bwi_mac_set_tpctl_11bg(mac
, &tpctl_orig
);
804 RF_CLRBITS(mac
, 0x76, 0x84);
806 bwi_rf_clear_tssi(mac
);
810 bwi_mac_detach(struct bwi_mac
*mac
)
812 bwi_mac_fw_free(mac
);
816 bwi_fwimage_is_valid(struct bwi_softc
*sc
, const struct fw_image
*fw
,
819 const struct bwi_fwhdr
*hdr
;
820 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
822 if (fw
->fw_imglen
< sizeof(*hdr
)) {
823 if_printf(ifp
, "invalid firmware (%s): invalid size %u\n",
824 fw
->fw_name
, fw
->fw_imglen
);
828 hdr
= (const struct bwi_fwhdr
*)fw
->fw_image
;
830 if (fw_type
!= BWI_FW_T_IV
) {
832 * Don't verify IV's size, it has different meaning
834 if (be32toh(hdr
->fw_size
) != fw
->fw_imglen
- sizeof(*hdr
)) {
835 if_printf(ifp
, "invalid firmware (%s): size mismatch, "
836 "fw %u, real %u\n", fw
->fw_name
,
837 be32toh(hdr
->fw_size
),
838 fw
->fw_imglen
- sizeof(*hdr
));
843 if (hdr
->fw_type
!= fw_type
) {
844 if_printf(ifp
, "invalid firmware (%s): type mismatch, "
845 "fw \'%c\', target \'%c\'\n", fw
->fw_name
,
846 hdr
->fw_type
, fw_type
);
850 if (hdr
->fw_gen
!= BWI_FW_GEN_1
) {
851 if_printf(ifp
, "invalid firmware (%s): wrong generation, "
852 "fw %d, target %d\n", fw
->fw_name
,
853 hdr
->fw_gen
, BWI_FW_GEN_1
);
863 bwi_mac_fw_alloc(struct bwi_mac
*mac
)
865 struct bwi_softc
*sc
= mac
->mac_sc
;
866 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
870 if (mac
->mac_ucode
== NULL
) {
871 ksnprintf(fwname
, sizeof(fwname
), BWI_FW_UCODE_PATH
,
873 mac
->mac_rev
>= 5 ? 5 : mac
->mac_rev
);
875 mac
->mac_ucode
= firmware_image_load(fwname
);
876 if (mac
->mac_ucode
== NULL
) {
877 if_printf(ifp
, "request firmware %s failed\n", fwname
);
881 if (!bwi_fwimage_is_valid(sc
, mac
->mac_ucode
, BWI_FW_T_UCODE
))
885 if (mac
->mac_pcm
== NULL
) {
886 ksnprintf(fwname
, sizeof(fwname
), BWI_FW_PCM_PATH
,
888 mac
->mac_rev
< 5 ? 4 : 5);
890 mac
->mac_pcm
= firmware_image_load(fwname
);
891 if (mac
->mac_pcm
== NULL
) {
892 if_printf(ifp
, "request firmware %s failed\n", fwname
);
896 if (!bwi_fwimage_is_valid(sc
, mac
->mac_pcm
, BWI_FW_T_PCM
))
900 if (mac
->mac_iv
== NULL
) {
902 if (mac
->mac_rev
== 2 || mac
->mac_rev
== 4) {
904 } else if (mac
->mac_rev
>= 5 && mac
->mac_rev
<= 10) {
907 if_printf(ifp
, "no suitable IV for MAC rev %d\n",
912 ksnprintf(fwname
, sizeof(fwname
), BWI_FW_IV_PATH
,
913 sc
->sc_fw_version
, idx
);
915 mac
->mac_iv
= firmware_image_load(fwname
);
916 if (mac
->mac_iv
== NULL
) {
917 if_printf(ifp
, "request firmware %s failed\n", fwname
);
920 if (!bwi_fwimage_is_valid(sc
, mac
->mac_iv
, BWI_FW_T_IV
))
924 if (mac
->mac_iv_ext
== NULL
) {
926 if (mac
->mac_rev
== 2 || mac
->mac_rev
== 4 ||
927 mac
->mac_rev
>= 11) {
930 } else if (mac
->mac_rev
>= 5 && mac
->mac_rev
<= 10) {
933 if_printf(ifp
, "no suitible ExtIV for MAC rev %d\n",
938 ksnprintf(fwname
, sizeof(fwname
), BWI_FW_IV_EXT_PATH
,
939 sc
->sc_fw_version
, idx
);
941 mac
->mac_iv_ext
= firmware_image_load(fwname
);
942 if (mac
->mac_iv_ext
== NULL
) {
943 if_printf(ifp
, "request firmware %s failed\n", fwname
);
946 if (!bwi_fwimage_is_valid(sc
, mac
->mac_iv_ext
, BWI_FW_T_IV
))
954 bwi_mac_fw_free(struct bwi_mac
*mac
)
956 if (mac
->mac_ucode
!= NULL
) {
957 firmware_image_unload(mac
->mac_ucode
);
958 mac
->mac_ucode
= NULL
;
961 if (mac
->mac_pcm
!= NULL
) {
962 firmware_image_unload(mac
->mac_pcm
);
966 if (mac
->mac_iv
!= NULL
) {
967 firmware_image_unload(mac
->mac_iv
);
971 if (mac
->mac_iv_ext
!= NULL
) {
972 firmware_image_unload(mac
->mac_iv_ext
);
973 mac
->mac_iv_ext
= NULL
;
978 bwi_mac_fw_load(struct bwi_mac
*mac
)
980 struct bwi_softc
*sc
= mac
->mac_sc
;
981 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
989 fw
= (const uint32_t *)
990 ((const uint8_t *)mac
->mac_ucode
->fw_image
+ BWI_FWHDR_SZ
);
991 fw_len
= (mac
->mac_ucode
->fw_imglen
- BWI_FWHDR_SZ
) / sizeof(uint32_t);
993 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
,
995 BWI_FW_UCODE_MOBJ
| BWI_WR_MOBJ_AUTOINC
, 0));
996 for (i
= 0; i
< fw_len
; ++i
) {
997 CSR_WRITE_4(sc
, BWI_MOBJ_DATA
, be32toh(fw
[i
]));
1004 fw
= (const uint32_t *)
1005 ((const uint8_t *)mac
->mac_pcm
->fw_image
+ BWI_FWHDR_SZ
);
1006 fw_len
= (mac
->mac_pcm
->fw_imglen
- BWI_FWHDR_SZ
) / sizeof(uint32_t);
1008 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
,
1009 BWI_MOBJ_CTRL_VAL(BWI_FW_PCM_MOBJ
, 0x01ea));
1010 CSR_WRITE_4(sc
, BWI_MOBJ_DATA
, 0x4000);
1012 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
,
1013 BWI_MOBJ_CTRL_VAL(BWI_FW_PCM_MOBJ
, 0x01eb));
1014 for (i
= 0; i
< fw_len
; ++i
) {
1015 CSR_WRITE_4(sc
, BWI_MOBJ_DATA
, be32toh(fw
[i
]));
1019 CSR_WRITE_4(sc
, BWI_MAC_INTR_STATUS
, BWI_ALL_INTRS
);
1020 CSR_WRITE_4(sc
, BWI_MAC_STATUS
,
1021 BWI_MAC_STATUS_UCODE_START
|
1022 BWI_MAC_STATUS_IHREN
|
1023 BWI_MAC_STATUS_INFRA
);
1027 for (i
= 0; i
< NRETRY
; ++i
) {
1028 uint32_t intr_status
;
1030 intr_status
= CSR_READ_4(sc
, BWI_MAC_INTR_STATUS
);
1031 if (intr_status
== BWI_INTR_READY
)
1036 if_printf(ifp
, "firmware (ucode&pcm) loading timed out\n");
1042 CSR_READ_4(sc
, BWI_MAC_INTR_STATUS
); /* dummy read */
1044 fw_rev
= MOBJ_READ_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_FWREV
);
1045 if (fw_rev
> BWI_FW_VERSION3_REVMAX
) {
1046 if_printf(ifp
, "firmware version 4 is not supported yet\n");
1050 if_printf(ifp
, "firmware rev 0x%04x, patch level 0x%04x\n", fw_rev
,
1051 MOBJ_READ_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_FWPATCHLV
));
1056 bwi_mac_gpio_init(struct bwi_mac
*mac
)
1058 struct bwi_softc
*sc
= mac
->mac_sc
;
1059 struct bwi_regwin
*old
, *gpio_rw
;
1060 uint32_t filt
, bits
;
1063 CSR_CLRBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_GPOSEL_MASK
);
1066 CSR_SETBITS_2(sc
, BWI_MAC_GPIO_MASK
, 0xf);
1070 if (sc
->sc_bbp_id
== BWI_BBPID_BCM4301
) {
1074 if (sc
->sc_card_flags
& BWI_CARD_F_PA_GPIO9
) {
1075 CSR_SETBITS_2(sc
, BWI_MAC_GPIO_MASK
, 0x200);
1080 gpio_rw
= BWI_GPIO_REGWIN(sc
);
1081 error
= bwi_regwin_switch(sc
, gpio_rw
, &old
);
1085 CSR_FILT_SETBITS_4(sc
, BWI_GPIO_CTRL
, filt
, bits
);
1087 return bwi_regwin_switch(sc
, old
, NULL
);
1091 bwi_mac_gpio_fini(struct bwi_mac
*mac
)
1093 struct bwi_softc
*sc
= mac
->mac_sc
;
1094 struct bwi_regwin
*old
, *gpio_rw
;
1097 gpio_rw
= BWI_GPIO_REGWIN(sc
);
1098 error
= bwi_regwin_switch(sc
, gpio_rw
, &old
);
1102 CSR_WRITE_4(sc
, BWI_GPIO_CTRL
, 0);
1104 return bwi_regwin_switch(sc
, old
, NULL
);
1108 bwi_mac_fw_load_iv(struct bwi_mac
*mac
, const struct fw_image
*fw
)
1110 struct bwi_softc
*sc
= mac
->mac_sc
;
1111 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
1112 const struct bwi_fwhdr
*hdr
;
1113 const struct bwi_fw_iv
*iv
;
1114 int n
, i
, iv_img_size
;
1116 /* Get the number of IVs in the IV image */
1117 hdr
= (const struct bwi_fwhdr
*)fw
->fw_image
;
1118 n
= be32toh(hdr
->fw_iv_cnt
);
1119 DPRINTF(sc
, "IV count %d\n", n
);
1121 /* Calculate the IV image size, for later sanity check */
1122 iv_img_size
= fw
->fw_imglen
- sizeof(*hdr
);
1124 /* Locate the first IV */
1125 iv
= (const struct bwi_fw_iv
*)
1126 ((const uint8_t *)fw
->fw_image
+ sizeof(*hdr
));
1128 for (i
= 0; i
< n
; ++i
) {
1129 uint16_t iv_ofs
, ofs
;
1132 if (iv_img_size
< sizeof(iv
->iv_ofs
)) {
1133 if_printf(ifp
, "invalid IV image, ofs\n");
1136 iv_img_size
-= sizeof(iv
->iv_ofs
);
1137 sz
+= sizeof(iv
->iv_ofs
);
1139 iv_ofs
= be16toh(iv
->iv_ofs
);
1141 ofs
= __SHIFTOUT(iv_ofs
, BWI_FW_IV_OFS_MASK
);
1142 if (ofs
>= 0x1000) {
1143 if_printf(ifp
, "invalid ofs (0x%04x) "
1144 "for %dth iv\n", ofs
, i
);
1148 if (iv_ofs
& BWI_FW_IV_IS_32BIT
) {
1151 if (iv_img_size
< sizeof(iv
->iv_val
.val32
)) {
1152 if_printf(ifp
, "invalid IV image, val32\n");
1155 iv_img_size
-= sizeof(iv
->iv_val
.val32
);
1156 sz
+= sizeof(iv
->iv_val
.val32
);
1158 val32
= be32toh(iv
->iv_val
.val32
);
1159 CSR_WRITE_4(sc
, ofs
, val32
);
1163 if (iv_img_size
< sizeof(iv
->iv_val
.val16
)) {
1164 if_printf(ifp
, "invalid IV image, val16\n");
1167 iv_img_size
-= sizeof(iv
->iv_val
.val16
);
1168 sz
+= sizeof(iv
->iv_val
.val16
);
1170 val16
= be16toh(iv
->iv_val
.val16
);
1171 CSR_WRITE_2(sc
, ofs
, val16
);
1174 iv
= (const struct bwi_fw_iv
*)((const uint8_t *)iv
+ sz
);
1177 if (iv_img_size
!= 0) {
1178 if_printf(ifp
, "invalid IV image, size left %d\n", iv_img_size
);
1185 bwi_mac_fw_init(struct bwi_mac
*mac
)
1187 struct ifnet
*ifp
= &mac
->mac_sc
->sc_ic
.ic_if
;
1190 error
= bwi_mac_fw_load_iv(mac
, mac
->mac_iv
);
1192 if_printf(ifp
, "load IV failed\n");
1196 if (mac
->mac_iv_ext
!= NULL
) {
1197 error
= bwi_mac_fw_load_iv(mac
, mac
->mac_iv_ext
);
1199 if_printf(ifp
, "load ExtIV failed\n");
1205 bwi_mac_opmode_init(struct bwi_mac
*mac
)
1207 struct bwi_softc
*sc
= mac
->mac_sc
;
1208 struct ieee80211com
*ic
= &sc
->sc_ic
;
1209 uint32_t mac_status
;
1212 CSR_CLRBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_INFRA
);
1213 CSR_SETBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_INFRA
);
1214 CSR_SETBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_PASS_BCN
);
1216 /* Set probe resp timeout to infinite */
1217 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_PROBE_RESP_TO
, 0);
1220 * TODO: factor out following part
1223 mac_status
= CSR_READ_4(sc
, BWI_MAC_STATUS
);
1224 mac_status
&= ~(BWI_MAC_STATUS_OPMODE_HOSTAP
|
1225 BWI_MAC_STATUS_PASS_CTL
|
1226 BWI_MAC_STATUS_PASS_BADPLCP
|
1227 BWI_MAC_STATUS_PASS_BADFCS
|
1228 BWI_MAC_STATUS_PROMISC
);
1229 mac_status
|= BWI_MAC_STATUS_INFRA
;
1231 /* Always turn on PROMISC on old hardware */
1232 if (mac
->mac_rev
< 5)
1233 mac_status
|= BWI_MAC_STATUS_PROMISC
;
1235 switch (ic
->ic_opmode
) {
1236 case IEEE80211_M_IBSS
:
1237 mac_status
&= ~BWI_MAC_STATUS_INFRA
;
1239 case IEEE80211_M_HOSTAP
:
1240 mac_status
|= BWI_MAC_STATUS_OPMODE_HOSTAP
;
1242 case IEEE80211_M_MONITOR
:
1244 /* Do you want data from your microwave oven? */
1245 mac_status
|= BWI_MAC_STATUS_PASS_CTL
|
1246 BWI_MAC_STATUS_PASS_BADPLCP
|
1247 BWI_MAC_STATUS_PASS_BADFCS
;
1249 mac_status
|= BWI_MAC_STATUS_PASS_CTL
;
1257 if (ic
->ic_if
.if_flags
& IFF_PROMISC
)
1258 mac_status
|= BWI_MAC_STATUS_PROMISC
;
1260 CSR_WRITE_4(sc
, BWI_MAC_STATUS
, mac_status
);
1262 if (ic
->ic_opmode
!= IEEE80211_M_IBSS
&&
1263 ic
->ic_opmode
!= IEEE80211_M_HOSTAP
) {
1264 if (sc
->sc_bbp_id
== BWI_BBPID_BCM4306
&& sc
->sc_bbp_rev
== 3)
1271 CSR_WRITE_2(sc
, BWI_MAC_PRE_TBTT
, pre_tbtt
);
1275 bwi_mac_hostflags_init(struct bwi_mac
*mac
)
1277 struct bwi_softc
*sc
= mac
->mac_sc
;
1278 struct bwi_phy
*phy
= &mac
->mac_phy
;
1279 struct bwi_rf
*rf
= &mac
->mac_rf
;
1280 uint64_t host_flags
;
1282 if (phy
->phy_mode
== IEEE80211_MODE_11A
)
1285 host_flags
= HFLAGS_READ(mac
);
1286 host_flags
|= BWI_HFLAG_SYM_WA
;
1288 if (phy
->phy_mode
== IEEE80211_MODE_11G
) {
1289 if (phy
->phy_rev
== 1)
1290 host_flags
|= BWI_HFLAG_GDC_WA
;
1291 if (sc
->sc_card_flags
& BWI_CARD_F_PA_GPIO9
)
1292 host_flags
|= BWI_HFLAG_OFDM_PA
;
1293 } else if (phy
->phy_mode
== IEEE80211_MODE_11B
) {
1294 if (phy
->phy_rev
>= 2 && rf
->rf_type
== BWI_RF_T_BCM2050
)
1295 host_flags
&= ~BWI_HFLAG_GDC_WA
;
1297 panic("unknown PHY mode %u\n", phy
->phy_mode
);
1300 HFLAGS_WRITE(mac
, host_flags
);
1304 bwi_mac_bss_param_init(struct bwi_mac
*mac
)
1306 struct bwi_softc
*sc
= mac
->mac_sc
;
1307 struct bwi_phy
*phy
= &mac
->mac_phy
;
1308 struct bwi_retry_lim lim
;
1312 * Set short/long retry limits
1314 bzero(&lim
, sizeof(lim
));
1315 lim
.shretry
= BWI_SHRETRY
;
1316 lim
.shretry_fb
= BWI_SHRETRY_FB
;
1317 lim
.lgretry
= BWI_LGRETRY
;
1318 lim
.lgretry_fb
= BWI_LGRETRY_FB
;
1319 bwi_mac_set_retry_lim(mac
, &lim
);
1322 * Implicitly prevent firmware from sending probe response
1323 * by setting its "probe response timeout" to 1us.
1325 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_PROBE_RESP_TO
, 1);
1328 * XXX MAC level acknowledge and CW min/max should depend
1329 * on the char rateset of the IBSS/BSS to join.
1333 * Set MAC level acknowledge rates
1335 bwi_mac_set_ackrates(mac
, &sc
->sc_ic
.ic_sup_rates
[phy
->phy_mode
]);
1340 if (phy
->phy_mode
== IEEE80211_MODE_11B
)
1341 cw_min
= IEEE80211_CW_MIN_0
;
1343 cw_min
= IEEE80211_CW_MIN_1
;
1344 MOBJ_WRITE_2(mac
, BWI_80211_MOBJ
, BWI_80211_MOBJ_CWMIN
, cw_min
);
1349 MOBJ_WRITE_2(mac
, BWI_80211_MOBJ
, BWI_80211_MOBJ_CWMAX
,
1354 bwi_mac_set_retry_lim(struct bwi_mac
*mac
, const struct bwi_retry_lim
*lim
)
1356 /* Short/Long retry limit */
1357 MOBJ_WRITE_2(mac
, BWI_80211_MOBJ
, BWI_80211_MOBJ_SHRETRY
,
1359 MOBJ_WRITE_2(mac
, BWI_80211_MOBJ
, BWI_80211_MOBJ_LGRETRY
,
1362 /* Short/Long retry fallback limit */
1363 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_SHRETRY_FB
,
1365 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_LGRETEY_FB
,
1370 bwi_mac_set_ackrates(struct bwi_mac
*mac
, const struct ieee80211_rateset
*rs
)
1374 /* XXX not standard conforming */
1375 for (i
= 0; i
< rs
->rs_nrates
; ++i
) {
1376 enum ieee80211_modtype modtype
;
1379 modtype
= ieee80211_rate2modtype(rs
->rs_rates
[i
]);
1381 case IEEE80211_MODTYPE_DS
:
1384 case IEEE80211_MODTYPE_OFDM
:
1388 panic("unsupported modtype %u\n", modtype
);
1390 ofs
+= (bwi_rate2plcp(rs
->rs_rates
[i
]) & 0xf) * 2;
1392 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, ofs
+ 0x20,
1393 MOBJ_READ_2(mac
, BWI_COMM_MOBJ
, ofs
));
1398 bwi_mac_start(struct bwi_mac
*mac
)
1400 struct bwi_softc
*sc
= mac
->mac_sc
;
1402 CSR_SETBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_ENABLE
);
1403 CSR_WRITE_4(sc
, BWI_MAC_INTR_STATUS
, BWI_INTR_READY
);
1405 /* Flush pending bus writes */
1406 CSR_READ_4(sc
, BWI_MAC_STATUS
);
1407 CSR_READ_4(sc
, BWI_MAC_INTR_STATUS
);
1409 return bwi_mac_config_ps(mac
);
1413 bwi_mac_stop(struct bwi_mac
*mac
)
1415 struct bwi_softc
*sc
= mac
->mac_sc
;
1418 error
= bwi_mac_config_ps(mac
);
1422 CSR_CLRBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_ENABLE
);
1424 /* Flush pending bus write */
1425 CSR_READ_4(sc
, BWI_MAC_STATUS
);
1427 #define NRETRY 10000
1428 for (i
= 0; i
< NRETRY
; ++i
) {
1429 if (CSR_READ_4(sc
, BWI_MAC_INTR_STATUS
) & BWI_INTR_READY
)
1434 if_printf(&sc
->sc_ic
.ic_if
, "can't stop MAC\n");
1443 bwi_mac_config_ps(struct bwi_mac
*mac
)
1445 struct bwi_softc
*sc
= mac
->mac_sc
;
1448 status
= CSR_READ_4(sc
, BWI_MAC_STATUS
);
1450 status
&= ~BWI_MAC_STATUS_HW_PS
;
1451 status
|= BWI_MAC_STATUS_WAKEUP
;
1452 CSR_WRITE_4(sc
, BWI_MAC_STATUS
, status
);
1454 /* Flush pending bus write */
1455 CSR_READ_4(sc
, BWI_MAC_STATUS
);
1457 if (mac
->mac_rev
>= 5) {
1461 for (i
= 0; i
< NRETRY
; ++i
) {
1462 if (MOBJ_READ_2(mac
, BWI_COMM_MOBJ
,
1463 BWI_COMM_MOBJ_UCODE_STATE
) != BWI_UCODE_STATE_PS
)
1468 if_printf(&sc
->sc_ic
.ic_if
, "config PS failed\n");
1477 bwi_mac_reset_hwkeys(struct bwi_mac
*mac
)
1479 /* TODO: firmware crypto */
1480 MOBJ_READ_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_KEYTABLE_OFS
);
1484 bwi_mac_shutdown(struct bwi_mac
*mac
)
1486 struct bwi_softc
*sc
= mac
->mac_sc
;
1489 if (mac
->mac_flags
& BWI_MAC_F_HAS_TXSTATS
)
1490 sc
->sc_free_txstats(sc
);
1492 sc
->sc_free_rx_ring(sc
);
1494 for (i
= 0; i
< BWI_TX_NRING
; ++i
)
1495 sc
->sc_free_tx_ring(sc
, i
);
1501 bwi_mac_gpio_fini(mac
);
1503 bwi_rf_off(mac
); /* XXX again */
1504 CSR_WRITE_2(sc
, BWI_BBP_ATTEN
, BWI_BBP_ATTEN_MAGIC
);
1505 bwi_regwin_disable(sc
, &mac
->mac_regwin
, 0);
1507 mac
->mac_flags
&= ~BWI_MAC_F_INITED
;
1511 bwi_mac_get_property(struct bwi_mac
*mac
)
1513 struct bwi_softc
*sc
= mac
->mac_sc
;
1514 enum bwi_bus_space old_bus_space
;
1520 val
= CSR_READ_4(sc
, BWI_MAC_STATUS
);
1521 if (val
& BWI_MAC_STATUS_BSWAP
) {
1522 DPRINTF(sc
, "%s\n", "need byte swap");
1523 mac
->mac_flags
|= BWI_MAC_F_BSWAP
;
1529 old_bus_space
= sc
->sc_bus_space
;
1531 val
= CSR_READ_4(sc
, BWI_STATE_HI
);
1532 if (__SHIFTOUT(val
, BWI_STATE_HI_FLAGS_MASK
) &
1533 BWI_STATE_HI_FLAG_64BIT
) {
1535 sc
->sc_bus_space
= BWI_BUS_SPACE_64BIT
;
1536 DPRINTF(sc
, "%s\n", "64bit bus space");
1538 uint32_t txrx_reg
= BWI_TXRX_CTRL_BASE
+ BWI_TX32_CTRL
;
1540 CSR_WRITE_4(sc
, txrx_reg
, BWI_TXRX32_CTRL_ADDRHI_MASK
);
1541 if (CSR_READ_4(sc
, txrx_reg
) & BWI_TXRX32_CTRL_ADDRHI_MASK
) {
1543 sc
->sc_bus_space
= BWI_BUS_SPACE_32BIT
;
1544 DPRINTF(sc
, "%s\n", "32bit bus space");
1547 sc
->sc_bus_space
= BWI_BUS_SPACE_30BIT
;
1548 DPRINTF(sc
, "%s\n", "30bit bus space");
1552 if (old_bus_space
!= 0 && old_bus_space
!= sc
->sc_bus_space
) {
1553 device_printf(sc
->sc_dev
, "MACs bus space mismatch!\n");
1560 bwi_mac_updateslot(struct bwi_mac
*mac
, int shslot
)
1564 if (mac
->mac_phy
.phy_mode
== IEEE80211_MODE_11B
)
1568 slot_time
= IEEE80211_DUR_SHSLOT
;
1570 slot_time
= IEEE80211_DUR_SLOT
;
1572 CSR_WRITE_2(mac
->mac_sc
, BWI_MAC_SLOTTIME
,
1573 slot_time
+ BWI_MAC_SLOTTIME_ADJUST
);
1574 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_SLOTTIME
, slot_time
);
1578 bwi_mac_attach(struct bwi_softc
*sc
, int id
, uint8_t rev
)
1580 struct bwi_mac
*mac
;
1583 KKASSERT(sc
->sc_nmac
<= BWI_MAC_MAX
&& sc
->sc_nmac
>= 0);
1585 if (sc
->sc_nmac
== BWI_MAC_MAX
) {
1586 device_printf(sc
->sc_dev
, "too many MACs\n");
1591 * More than one MAC is only supported by BCM4309
1593 if (sc
->sc_nmac
!= 0 &&
1594 pci_get_device(sc
->sc_dev
) != PCI_PRODUCT_BROADCOM_BCM4309
) {
1595 DPRINTF(sc
, "%s\n", "ignore second MAC");
1599 mac
= &sc
->sc_mac
[sc
->sc_nmac
];
1601 /* XXX will this happen? */
1602 if (BWI_REGWIN_EXIST(&mac
->mac_regwin
)) {
1603 device_printf(sc
->sc_dev
, "%dth MAC already attached\n",
1609 * Test whether the revision of this MAC is supported
1611 #define N(arr) (int)(sizeof(arr) / sizeof(arr[0]))
1612 for (i
= 0; i
< N(bwi_sup_macrev
); ++i
) {
1613 if (bwi_sup_macrev
[i
] == rev
)
1616 if (i
== N(bwi_sup_macrev
)) {
1617 device_printf(sc
->sc_dev
, "MAC rev %u is "
1618 "not supported\n", rev
);
1623 BWI_CREATE_MAC(mac
, sc
, id
, rev
);
1626 if (mac
->mac_rev
< 5) {
1627 mac
->mac_flags
|= BWI_MAC_F_HAS_TXSTATS
;
1628 DPRINTF(sc
, "%s\n", "has TX stats");
1634 static __inline
void
1635 bwi_mac_balance_atten(int *bbp_atten0
, int *rf_atten0
)
1637 int bbp_atten
, rf_atten
, rf_atten_lim
= -1;
1639 bbp_atten
= *bbp_atten0
;
1640 rf_atten
= *rf_atten0
;
1643 * RF attenuation affects TX power BWI_RF_ATTEN_FACTOR times
1644 * as much as BBP attenuation, so we try our best to keep RF
1645 * attenuation within range. BBP attenuation will be clamped
1646 * later if it is out of range during balancing.
1648 * BWI_RF_ATTEN_MAX0 is used as RF attenuation upper limit.
1652 * Use BBP attenuation to balance RF attenuation
1656 else if (rf_atten
> BWI_RF_ATTEN_MAX0
)
1657 rf_atten_lim
= BWI_RF_ATTEN_MAX0
;
1659 if (rf_atten_lim
>= 0) {
1660 bbp_atten
+= (BWI_RF_ATTEN_FACTOR
* (rf_atten
- rf_atten_lim
));
1661 rf_atten
= rf_atten_lim
;
1665 * If possible, use RF attenuation to balance BBP attenuation
1666 * NOTE: RF attenuation is still kept within range.
1668 while (rf_atten
< BWI_RF_ATTEN_MAX0
&& bbp_atten
> BWI_BBP_ATTEN_MAX
) {
1669 bbp_atten
-= BWI_RF_ATTEN_FACTOR
;
1672 while (rf_atten
> 0 && bbp_atten
< 0) {
1673 bbp_atten
+= BWI_RF_ATTEN_FACTOR
;
1677 /* RF attenuation MUST be within range */
1678 KKASSERT(rf_atten
>= 0 && rf_atten
<= BWI_RF_ATTEN_MAX0
);
1681 * Clamp BBP attenuation
1685 else if (bbp_atten
> BWI_BBP_ATTEN_MAX
)
1686 bbp_atten
= BWI_BBP_ATTEN_MAX
;
1688 *rf_atten0
= rf_atten
;
1689 *bbp_atten0
= bbp_atten
;
1693 bwi_mac_adjust_tpctl(struct bwi_mac
*mac
, int rf_atten_adj
, int bbp_atten_adj
)
1695 struct bwi_softc
*sc
= mac
->mac_sc
;
1696 struct bwi_rf
*rf
= &mac
->mac_rf
;
1697 struct bwi_tpctl tpctl
;
1698 int bbp_atten
, rf_atten
, tp_ctrl1
;
1700 bcopy(&mac
->mac_tpctl
, &tpctl
, sizeof(tpctl
));
1702 /* NOTE: Use signed value to do calulation */
1703 bbp_atten
= tpctl
.bbp_atten
;
1704 rf_atten
= tpctl
.rf_atten
;
1705 tp_ctrl1
= tpctl
.tp_ctrl1
;
1707 bbp_atten
+= bbp_atten_adj
;
1708 rf_atten
+= rf_atten_adj
;
1710 bwi_mac_balance_atten(&bbp_atten
, &rf_atten
);
1712 if (rf
->rf_type
== BWI_RF_T_BCM2050
&& rf
->rf_rev
== 2) {
1713 if (rf_atten
<= 1) {
1714 if (tp_ctrl1
== 0) {
1718 } else if (sc
->sc_card_flags
& BWI_CARD_F_PA_GPIO9
) {
1720 (BWI_RF_ATTEN_FACTOR
* (rf_atten
- 2));
1723 } else if (rf_atten
> 4 && tp_ctrl1
!= 0) {
1725 if (bbp_atten
< 3) {
1733 bwi_mac_balance_atten(&bbp_atten
, &rf_atten
);
1736 tpctl
.bbp_atten
= bbp_atten
;
1737 tpctl
.rf_atten
= rf_atten
;
1738 tpctl
.tp_ctrl1
= tp_ctrl1
;
1741 bwi_mac_set_tpctl_11bg(mac
, &tpctl
);
1742 bwi_mac_unlock(mac
);
1746 * http://bcm-specs.sipsolutions.net/RecalculateTransmissionPower
1749 bwi_mac_calibrate_txpower(struct bwi_mac
*mac
)
1751 struct bwi_softc
*sc
= mac
->mac_sc
;
1752 struct bwi_rf
*rf
= &mac
->mac_rf
;
1753 int8_t tssi
[4], tssi_avg
, cur_txpwr
;
1754 int error
, i
, ofdm_tssi
;
1755 int txpwr_diff
, rf_atten_adj
, bbp_atten_adj
;
1757 if (mac
->mac_flags
& BWI_MAC_F_TPCTL_ERROR
) {
1758 DPRINTF(sc
, "%s\n", "tpctl error happened, can't set txpower");
1762 if (BWI_IS_BRCM_BU4306(sc
)) {
1763 DPRINTF(sc
, "%s\n", "BU4306, can't set txpower");
1768 * Save latest TSSI and reset the related memory objects
1771 error
= bwi_rf_get_latest_tssi(mac
, tssi
, BWI_COMM_MOBJ_TSSI_DS
);
1773 DPRINTF(sc
, "%s\n", "no DS tssi");
1775 if (mac
->mac_phy
.phy_mode
== IEEE80211_MODE_11B
)
1778 error
= bwi_rf_get_latest_tssi(mac
, tssi
,
1779 BWI_COMM_MOBJ_TSSI_OFDM
);
1781 DPRINTF(sc
, "%s\n", "no OFDM tssi");
1785 for (i
= 0; i
< 4; ++i
) {
1791 bwi_rf_clear_tssi(mac
);
1793 DPRINTF(sc
, "tssi0 %d, tssi1 %d, tssi2 %d, tssi3 %d\n",
1794 tssi
[0], tssi
[1], tssi
[2], tssi
[3]);
1797 * Calculate RF/BBP attenuation adjustment based on
1798 * the difference between desired TX power and sampled
1801 /* +8 == "each incremented by 1/2" */
1802 tssi_avg
= (tssi
[0] + tssi
[1] + tssi
[2] + tssi
[3] + 8) / 4;
1803 if (ofdm_tssi
&& (HFLAGS_READ(mac
) & BWI_HFLAG_PWR_BOOST_DS
))
1806 DPRINTF(sc
, "tssi avg %d\n", tssi_avg
);
1808 error
= bwi_rf_tssi2dbm(mac
, tssi_avg
, &cur_txpwr
);
1811 DPRINTF(sc
, "current txpower %d\n", cur_txpwr
);
1813 txpwr_diff
= rf
->rf_txpower_max
- cur_txpwr
; /* XXX ni_txpower */
1815 rf_atten_adj
= -howmany(txpwr_diff
, 8);
1816 bbp_atten_adj
= -(txpwr_diff
/ 2) -
1817 (BWI_RF_ATTEN_FACTOR
* rf_atten_adj
);
1819 if (rf_atten_adj
== 0 && bbp_atten_adj
== 0) {
1820 DPRINTF(sc
, "%s\n", "no need to adjust RF/BBP attenuation");
1825 DPRINTF(sc
, "rf atten adjust %d, bbp atten adjust %d\n",
1826 rf_atten_adj
, bbp_atten_adj
);
1827 bwi_mac_adjust_tpctl(mac
, rf_atten_adj
, bbp_atten_adj
);
1832 bwi_mac_lock(struct bwi_mac
*mac
)
1834 struct bwi_softc
*sc
= mac
->mac_sc
;
1835 struct ieee80211com
*ic
= &sc
->sc_ic
;
1837 KKASSERT((mac
->mac_flags
& BWI_MAC_F_LOCKED
) == 0);
1839 if (mac
->mac_rev
< 3)
1841 else if (ic
->ic_opmode
!= IEEE80211_M_HOSTAP
)
1842 bwi_mac_config_ps(mac
);
1844 CSR_SETBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_RFLOCK
);
1846 /* Flush pending bus write */
1847 CSR_READ_4(sc
, BWI_MAC_STATUS
);
1850 mac
->mac_flags
|= BWI_MAC_F_LOCKED
;
1854 bwi_mac_unlock(struct bwi_mac
*mac
)
1856 struct bwi_softc
*sc
= mac
->mac_sc
;
1857 struct ieee80211com
*ic
= &sc
->sc_ic
;
1859 KKASSERT(mac
->mac_flags
& BWI_MAC_F_LOCKED
);
1861 CSR_READ_2(sc
, BWI_PHYINFO
); /* dummy read */
1863 CSR_CLRBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_RFLOCK
);
1865 if (mac
->mac_rev
< 3)
1867 else if (ic
->ic_opmode
!= IEEE80211_M_HOSTAP
)
1868 bwi_mac_config_ps(mac
);
1870 mac
->mac_flags
&= ~BWI_MAC_F_LOCKED
;
1874 bwi_mac_set_promisc(struct bwi_mac
*mac
, int promisc
)
1876 struct bwi_softc
*sc
= mac
->mac_sc
;
1878 if (mac
->mac_rev
< 5) /* Promisc is always on */
1882 CSR_SETBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_PROMISC
);
1884 CSR_CLRBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_PROMISC
);