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.12 2008/02/14 12:53:51 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/firmware.h>
43 #include <sys/malloc.h>
46 #include <sys/serialize.h>
47 #include <sys/socket.h>
48 #include <sys/sockio.h>
49 #include <sys/sysctl.h>
51 #include <net/ethernet.h>
54 #include <net/if_arp.h>
55 #include <net/if_dl.h>
56 #include <net/if_media.h>
57 #include <net/ifq_var.h>
59 #include <netproto/802_11/ieee80211_radiotap.h>
60 #include <netproto/802_11/ieee80211_var.h>
61 #include <netproto/802_11/wlan_ratectl/onoe/ieee80211_onoe_param.h>
63 #include <bus/pci/pcireg.h>
64 #include <bus/pci/pcivar.h>
65 #include <bus/pci/pcidevs.h>
67 #include <dev/netif/bwi/if_bwireg.h>
68 #include <dev/netif/bwi/if_bwivar.h>
69 #include <dev/netif/bwi/bwiphy.h>
70 #include <dev/netif/bwi/bwirf.h>
71 #include <dev/netif/bwi/bwimac.h>
73 struct bwi_retry_lim
{
80 static int bwi_mac_test(struct bwi_mac
*);
81 static int bwi_mac_get_property(struct bwi_mac
*);
83 static void bwi_mac_set_retry_lim(struct bwi_mac
*,
84 const struct bwi_retry_lim
*);
85 static void bwi_mac_set_ackrates(struct bwi_mac
*,
86 const struct ieee80211_rateset
*);
88 static int bwi_mac_gpio_init(struct bwi_mac
*);
89 static int bwi_mac_gpio_fini(struct bwi_mac
*);
90 static void bwi_mac_opmode_init(struct bwi_mac
*);
91 static void bwi_mac_hostflags_init(struct bwi_mac
*);
92 static void bwi_mac_bss_param_init(struct bwi_mac
*);
94 static int bwi_mac_fw_alloc(struct bwi_mac
*);
95 static void bwi_mac_fw_free(struct bwi_mac
*);
96 static int bwi_mac_fw_load(struct bwi_mac
*);
97 static int bwi_mac_fw_init(struct bwi_mac
*);
98 static int bwi_mac_fw_load_iv(struct bwi_mac
*, const struct fw_image
*);
100 static void bwi_mac_setup_tpctl(struct bwi_mac
*);
101 static void bwi_mac_adjust_tpctl(struct bwi_mac
*, int, int);
103 static void bwi_mac_lock(struct bwi_mac
*);
104 static void bwi_mac_unlock(struct bwi_mac
*);
106 static const uint8_t bwi_sup_macrev
[] = { 2, 4, 5, 6, 7, 9, 10 };
109 bwi_tmplt_write_4(struct bwi_mac
*mac
, uint32_t ofs
, uint32_t val
)
111 struct bwi_softc
*sc
= mac
->mac_sc
;
113 if (mac
->mac_flags
& BWI_MAC_F_BSWAP
)
116 CSR_WRITE_4(sc
, BWI_MAC_TMPLT_CTRL
, ofs
);
117 CSR_WRITE_4(sc
, BWI_MAC_TMPLT_DATA
, val
);
121 bwi_hostflags_write(struct bwi_mac
*mac
, uint64_t flags
)
125 val
= flags
& 0xffff;
126 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_HFLAGS_LO
, val
);
128 val
= (flags
>> 16) & 0xffff;
129 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_HFLAGS_MI
, val
);
131 /* HI has unclear meaning, so leave it as it is */
135 bwi_hostflags_read(struct bwi_mac
*mac
)
139 /* HI has unclear meaning, so don't touch it */
142 val
= MOBJ_READ_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_HFLAGS_MI
);
145 val
= MOBJ_READ_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_HFLAGS_LO
);
152 bwi_memobj_read_2(struct bwi_mac
*mac
, uint16_t obj_id
, uint16_t ofs0
)
154 struct bwi_softc
*sc
= mac
->mac_sc
;
158 data_reg
= BWI_MOBJ_DATA
;
162 data_reg
= BWI_MOBJ_DATA_UNALIGN
;
164 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
, BWI_MOBJ_CTRL_VAL(obj_id
, ofs
));
165 return CSR_READ_2(sc
, data_reg
);
169 bwi_memobj_read_4(struct bwi_mac
*mac
, uint16_t obj_id
, uint16_t ofs0
)
171 struct bwi_softc
*sc
= mac
->mac_sc
;
178 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
, BWI_MOBJ_CTRL_VAL(obj_id
, ofs
));
179 ret
= CSR_READ_2(sc
, BWI_MOBJ_DATA_UNALIGN
);
182 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
,
183 BWI_MOBJ_CTRL_VAL(obj_id
, ofs
+ 1));
184 ret
|= CSR_READ_2(sc
, BWI_MOBJ_DATA
);
188 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
, BWI_MOBJ_CTRL_VAL(obj_id
, ofs
));
189 return CSR_READ_4(sc
, BWI_MOBJ_DATA
);
194 bwi_memobj_write_2(struct bwi_mac
*mac
, uint16_t obj_id
, uint16_t ofs0
,
197 struct bwi_softc
*sc
= mac
->mac_sc
;
201 data_reg
= BWI_MOBJ_DATA
;
205 data_reg
= BWI_MOBJ_DATA_UNALIGN
;
207 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
, BWI_MOBJ_CTRL_VAL(obj_id
, ofs
));
208 CSR_WRITE_2(sc
, data_reg
, v
);
212 bwi_memobj_write_4(struct bwi_mac
*mac
, uint16_t obj_id
, uint16_t ofs0
,
215 struct bwi_softc
*sc
= mac
->mac_sc
;
220 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
, BWI_MOBJ_CTRL_VAL(obj_id
, ofs
));
221 CSR_WRITE_2(sc
, BWI_MOBJ_DATA_UNALIGN
, v
>> 16);
223 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
,
224 BWI_MOBJ_CTRL_VAL(obj_id
, ofs
+ 1));
225 CSR_WRITE_2(sc
, BWI_MOBJ_DATA
, v
& 0xffff);
227 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
, BWI_MOBJ_CTRL_VAL(obj_id
, ofs
));
228 CSR_WRITE_4(sc
, BWI_MOBJ_DATA
, v
);
233 bwi_mac_lateattach(struct bwi_mac
*mac
)
237 if (mac
->mac_rev
>= 5)
238 CSR_READ_4(mac
->mac_sc
, BWI_STATE_HI
); /* dummy read */
240 bwi_mac_reset(mac
, 1);
242 error
= bwi_phy_attach(mac
);
246 error
= bwi_rf_attach(mac
);
250 /* Link 11B/G PHY, unlink 11A PHY */
251 if (mac
->mac_phy
.phy_mode
== IEEE80211_MODE_11A
)
252 bwi_mac_reset(mac
, 0);
254 bwi_mac_reset(mac
, 1);
256 error
= bwi_mac_test(mac
);
260 error
= bwi_mac_get_property(mac
);
264 error
= bwi_rf_map_txpower(mac
);
269 CSR_WRITE_2(mac
->mac_sc
, BWI_BBP_ATTEN
, BWI_BBP_ATTEN_MAGIC
);
270 bwi_regwin_disable(mac
->mac_sc
, &mac
->mac_regwin
, 0);
276 bwi_mac_init(struct bwi_mac
*mac
)
278 struct bwi_softc
*sc
= mac
->mac_sc
;
281 /* Clear MAC/PHY/RF states */
282 bwi_mac_setup_tpctl(mac
);
283 bwi_rf_clear_state(&mac
->mac_rf
);
284 bwi_phy_clear_state(&mac
->mac_phy
);
286 /* Enable MAC and linked it to PHY */
287 if (!bwi_regwin_is_enabled(sc
, &mac
->mac_regwin
))
288 bwi_mac_reset(mac
, 1);
290 /* Initialize backplane */
291 error
= bwi_bus_init(sc
, mac
);
295 /* XXX work around for hardware bugs? */
296 if (sc
->sc_bus_regwin
.rw_rev
<= 5 &&
297 sc
->sc_bus_regwin
.rw_type
!= BWI_REGWIN_T_BUSPCIE
) {
298 CSR_SETBITS_4(sc
, BWI_CONF_LO
,
299 __SHIFTIN(BWI_CONF_LO_SERVTO
, BWI_CONF_LO_SERVTO_MASK
) |
300 __SHIFTIN(BWI_CONF_LO_REQTO
, BWI_CONF_LO_REQTO_MASK
));
304 error
= bwi_phy_calibrate(mac
);
306 if_printf(&sc
->sc_ic
.ic_if
, "PHY calibrate failed\n");
310 /* Prepare to initialize firmware */
311 CSR_WRITE_4(sc
, BWI_MAC_STATUS
,
312 BWI_MAC_STATUS_UCODE_JUMP0
|
313 BWI_MAC_STATUS_IHREN
);
316 * Load and initialize firmwares
318 error
= bwi_mac_fw_alloc(mac
);
322 error
= bwi_mac_fw_load(mac
);
326 error
= bwi_mac_gpio_init(mac
);
330 error
= bwi_mac_fw_init(mac
);
339 /* TODO: LED, hardware rf enabled is only related to LED setting */
344 CSR_WRITE_2(sc
, BWI_BBP_ATTEN
, 0);
347 /* TODO: interference mitigation */
352 bwi_rf_set_ant_mode(mac
, mac
->mac_rf
.rf_ant_mode
);
355 * Initialize operation mode (RX configuration)
357 bwi_mac_opmode_init(mac
);
359 /* XXX what's these */
360 if (mac
->mac_rev
< 3) {
361 CSR_WRITE_2(sc
, 0x60e, 0);
362 CSR_WRITE_2(sc
, 0x610, 0x8000);
363 CSR_WRITE_2(sc
, 0x604, 0);
364 CSR_WRITE_2(sc
, 0x606, 0x200);
366 CSR_WRITE_4(sc
, 0x188, 0x80000000);
367 CSR_WRITE_4(sc
, 0x18c, 0x2000000);
371 * Initialize TX/RX interrupts' mask
373 CSR_WRITE_4(sc
, BWI_MAC_INTR_STATUS
, BWI_INTR_TIMER1
);
374 for (i
= 0; i
< BWI_TXRX_NRING
; ++i
) {
377 if (BWI_TXRX_IS_RX(i
))
378 intrs
= BWI_TXRX_RX_INTRS
;
380 intrs
= BWI_TXRX_TX_INTRS
;
381 CSR_WRITE_4(sc
, BWI_TXRX_INTR_MASK(i
), intrs
);
384 /* XXX what's this */
385 CSR_SETBITS_4(sc
, BWI_STATE_LO
, 0x100000);
387 /* Setup MAC power up delay */
388 CSR_WRITE_2(sc
, BWI_MAC_POWERUP_DELAY
, sc
->sc_pwron_delay
);
390 /* Set MAC regwin revision */
391 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_MACREV
, mac
->mac_rev
);
394 * Initialize host flags
396 bwi_mac_hostflags_init(mac
);
399 * Initialize BSS parameters
401 bwi_mac_bss_param_init(mac
);
404 * Initialize TX rings
406 for (i
= 0; i
< BWI_TX_NRING
; ++i
) {
407 error
= sc
->sc_init_tx_ring(sc
, i
);
409 if_printf(&sc
->sc_ic
.ic_if
,
410 "can't initialize %dth TX ring\n", i
);
418 error
= sc
->sc_init_rx_ring(sc
);
420 if_printf(&sc
->sc_ic
.ic_if
, "can't initialize RX ring\n");
425 * Initialize TX stats if the current MAC uses that
427 if (mac
->mac_flags
& BWI_MAC_F_HAS_TXSTATS
) {
428 error
= sc
->sc_init_txstats(sc
);
430 if_printf(&sc
->sc_ic
.ic_if
,
431 "can't initialize TX stats ring\n");
436 /* XXX what's these */
437 CSR_WRITE_2(sc
, 0x612, 0x50); /* Force Pre-TBTT to 80? */
438 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, 0x416, 0x50);
439 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, 0x414, 0x1f4);
441 mac
->mac_flags
|= BWI_MAC_F_INITED
;
446 bwi_mac_reset(struct bwi_mac
*mac
, int link_phy
)
448 struct bwi_softc
*sc
= mac
->mac_sc
;
449 uint32_t flags
, state_lo
, status
;
451 flags
= BWI_STATE_LO_FLAG_PHYRST
| BWI_STATE_LO_FLAG_PHYCLKEN
;
453 flags
|= BWI_STATE_LO_FLAG_PHYLNK
;
454 bwi_regwin_enable(sc
, &mac
->mac_regwin
, flags
);
457 state_lo
= CSR_READ_4(sc
, BWI_STATE_LO
);
458 state_lo
|= BWI_STATE_LO_GATED_CLOCK
;
459 state_lo
&= ~__SHIFTIN(BWI_STATE_LO_FLAG_PHYRST
,
460 BWI_STATE_LO_FLAGS_MASK
);
461 CSR_WRITE_4(sc
, BWI_STATE_LO
, state_lo
);
462 /* Flush pending bus write */
463 CSR_READ_4(sc
, BWI_STATE_LO
);
466 state_lo
&= ~BWI_STATE_LO_GATED_CLOCK
;
467 CSR_WRITE_4(sc
, BWI_STATE_LO
, state_lo
);
468 /* Flush pending bus write */
469 CSR_READ_4(sc
, BWI_STATE_LO
);
472 CSR_WRITE_2(sc
, BWI_BBP_ATTEN
, 0);
474 status
= CSR_READ_4(sc
, BWI_MAC_STATUS
);
475 status
|= BWI_MAC_STATUS_IHREN
;
477 status
|= BWI_MAC_STATUS_PHYLNK
;
479 status
&= ~BWI_MAC_STATUS_PHYLNK
;
480 CSR_WRITE_4(sc
, BWI_MAC_STATUS
, status
);
483 DPRINTF(sc
, BWI_DBG_MAC
| BWI_DBG_ATTACH
| BWI_DBG_INIT
,
484 "%s\n", "PHY is linked");
485 mac
->mac_phy
.phy_flags
|= BWI_PHY_F_LINKED
;
487 DPRINTF(sc
, BWI_DBG_MAC
| BWI_DBG_ATTACH
| BWI_DBG_INIT
,
488 "%s\n", "PHY is unlinked");
489 mac
->mac_phy
.phy_flags
&= ~BWI_PHY_F_LINKED
;
494 bwi_mac_set_tpctl_11bg(struct bwi_mac
*mac
, const struct bwi_tpctl
*new_tpctl
)
496 struct bwi_rf
*rf
= &mac
->mac_rf
;
497 struct bwi_tpctl
*tpctl
= &mac
->mac_tpctl
;
499 if (new_tpctl
!= NULL
) {
500 KKASSERT(new_tpctl
->bbp_atten
<= BWI_BBP_ATTEN_MAX
);
501 KKASSERT(new_tpctl
->rf_atten
<=
502 (rf
->rf_rev
< 6 ? BWI_RF_ATTEN_MAX0
503 : BWI_RF_ATTEN_MAX1
));
504 KKASSERT(new_tpctl
->tp_ctrl1
<= BWI_TPCTL1_MAX
);
506 tpctl
->bbp_atten
= new_tpctl
->bbp_atten
;
507 tpctl
->rf_atten
= new_tpctl
->rf_atten
;
508 tpctl
->tp_ctrl1
= new_tpctl
->tp_ctrl1
;
511 /* Set BBP attenuation */
512 bwi_phy_set_bbp_atten(mac
, tpctl
->bbp_atten
);
514 /* Set RF attenuation */
515 RF_WRITE(mac
, BWI_RFR_ATTEN
, tpctl
->rf_atten
);
516 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_RF_ATTEN
,
520 if (rf
->rf_type
== BWI_RF_T_BCM2050
) {
521 RF_FILT_SETBITS(mac
, BWI_RFR_TXPWR
, ~BWI_RFR_TXPWR1_MASK
,
522 __SHIFTIN(tpctl
->tp_ctrl1
, BWI_RFR_TXPWR1_MASK
));
525 /* Adjust RF Local Oscillator */
526 if (mac
->mac_phy
.phy_mode
== IEEE80211_MODE_11G
)
527 bwi_rf_lo_adjust(mac
, tpctl
);
531 bwi_mac_test(struct bwi_mac
*mac
)
533 struct bwi_softc
*sc
= mac
->mac_sc
;
534 uint32_t orig_val
, val
;
536 #define TEST_VAL1 0xaa5555aa
537 #define TEST_VAL2 0x55aaaa55
539 /* Save it for later restoring */
540 orig_val
= MOBJ_READ_4(mac
, BWI_COMM_MOBJ
, 0);
543 MOBJ_WRITE_4(mac
, BWI_COMM_MOBJ
, 0, TEST_VAL1
);
544 val
= MOBJ_READ_4(mac
, BWI_COMM_MOBJ
, 0);
545 if (val
!= TEST_VAL1
) {
546 device_printf(sc
->sc_dev
, "TEST1 failed\n");
551 MOBJ_WRITE_4(mac
, BWI_COMM_MOBJ
, 0, TEST_VAL2
);
552 val
= MOBJ_READ_4(mac
, BWI_COMM_MOBJ
, 0);
553 if (val
!= TEST_VAL2
) {
554 device_printf(sc
->sc_dev
, "TEST2 failed\n");
558 /* Restore to the original value */
559 MOBJ_WRITE_4(mac
, BWI_COMM_MOBJ
, 0, orig_val
);
561 val
= CSR_READ_4(sc
, BWI_MAC_STATUS
);
562 if ((val
& ~BWI_MAC_STATUS_PHYLNK
) != BWI_MAC_STATUS_IHREN
) {
563 device_printf(sc
->sc_dev
, "%s failed, MAC status 0x%08x\n",
568 val
= CSR_READ_4(sc
, BWI_MAC_INTR_STATUS
);
570 device_printf(sc
->sc_dev
, "%s failed, intr status %08x\n",
582 bwi_mac_setup_tpctl(struct bwi_mac
*mac
)
584 struct bwi_softc
*sc
= mac
->mac_sc
;
585 struct bwi_rf
*rf
= &mac
->mac_rf
;
586 struct bwi_phy
*phy
= &mac
->mac_phy
;
587 struct bwi_tpctl
*tpctl
= &mac
->mac_tpctl
;
589 /* Calc BBP attenuation */
590 if (rf
->rf_type
== BWI_RF_T_BCM2050
&& rf
->rf_rev
< 6)
591 tpctl
->bbp_atten
= 0;
593 tpctl
->bbp_atten
= 2;
595 /* Calc TX power CTRL1?? */
597 if (rf
->rf_type
== BWI_RF_T_BCM2050
) {
600 else if (rf
->rf_rev
< 6)
602 else if (rf
->rf_rev
== 8)
606 /* Empty TX power CTRL2?? */
607 tpctl
->tp_ctrl2
= 0xffff;
610 * Calc RF attenuation
612 if (phy
->phy_mode
== IEEE80211_MODE_11A
) {
613 tpctl
->rf_atten
= 0x60;
617 if (BWI_IS_BRCM_BCM4309G(sc
) && sc
->sc_pci_revid
< 0x51) {
618 tpctl
->rf_atten
= sc
->sc_pci_revid
< 0x43 ? 2 : 3;
624 if (rf
->rf_type
!= BWI_RF_T_BCM2050
) {
625 if (rf
->rf_type
== BWI_RF_T_BCM2053
&& rf
->rf_rev
== 1)
631 * NB: If we reaches here and the card is BRCM_BCM4309G,
632 * then the card's PCI revision must >= 0x51
636 switch (rf
->rf_rev
) {
638 if (phy
->phy_mode
== IEEE80211_MODE_11G
) {
639 if (BWI_IS_BRCM_BCM4309G(sc
) || BWI_IS_BRCM_BU4306(sc
))
644 if (BWI_IS_BRCM_BCM4309G(sc
))
651 if (phy
->phy_mode
== IEEE80211_MODE_11G
) {
653 * NOTE: Order of following conditions is critical
655 if (BWI_IS_BRCM_BCM4309G(sc
))
657 else if (BWI_IS_BRCM_BU4306(sc
))
659 else if (sc
->sc_bbp_id
== BWI_BBPID_BCM4320
)
672 tpctl
->rf_atten
= 0x1a;
676 DPRINTF(sc
, BWI_DBG_MAC
| BWI_DBG_INIT
| BWI_DBG_TXPOWER
,
677 "bbp atten: %u, rf atten: %u, ctrl1: %u, ctrl2: %u\n",
678 tpctl
->bbp_atten
, tpctl
->rf_atten
,
679 tpctl
->tp_ctrl1
, tpctl
->tp_ctrl2
);
683 bwi_mac_dummy_xmit(struct bwi_mac
*mac
)
686 static const uint32_t packet_11a
[PACKET_LEN
] =
687 { 0x000201cc, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 };
688 static const uint32_t packet_11bg
[PACKET_LEN
] =
689 { 0x000b846e, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 };
691 struct bwi_softc
*sc
= mac
->mac_sc
;
692 struct bwi_rf
*rf
= &mac
->mac_rf
;
693 const uint32_t *packet
;
697 if (mac
->mac_phy
.phy_mode
== IEEE80211_MODE_11A
) {
703 packet
= packet_11bg
;
707 for (i
= 0; i
< PACKET_LEN
; ++i
)
708 TMPLT_WRITE_4(mac
, i
* 4, packet
[i
]);
710 CSR_READ_4(sc
, BWI_MAC_STATUS
); /* dummy read */
712 CSR_WRITE_2(sc
, 0x568, 0);
713 CSR_WRITE_2(sc
, 0x7c0, 0);
714 CSR_WRITE_2(sc
, 0x50c, val_50c
);
715 CSR_WRITE_2(sc
, 0x508, 0);
716 CSR_WRITE_2(sc
, 0x50a, 0);
717 CSR_WRITE_2(sc
, 0x54c, 0);
718 CSR_WRITE_2(sc
, 0x56a, 0x14);
719 CSR_WRITE_2(sc
, 0x568, 0x826);
720 CSR_WRITE_2(sc
, 0x500, 0);
721 CSR_WRITE_2(sc
, 0x502, 0x30);
723 if (rf
->rf_type
== BWI_RF_T_BCM2050
&& rf
->rf_rev
<= 5)
724 RF_WRITE(mac
, 0x51, 0x17);
726 for (i
= 0; i
< wait_max
; ++i
) {
727 if (CSR_READ_2(sc
, 0x50e) & 0x80)
731 for (i
= 0; i
< 10; ++i
) {
732 if (CSR_READ_2(sc
, 0x50e) & 0x400)
736 for (i
= 0; i
< 10; ++i
) {
737 if ((CSR_READ_2(sc
, 0x690) & 0x100) == 0)
742 if (rf
->rf_type
== BWI_RF_T_BCM2050
&& rf
->rf_rev
<= 5)
743 RF_WRITE(mac
, 0x51, 0x37);
748 bwi_mac_init_tpctl_11bg(struct bwi_mac
*mac
)
750 struct bwi_softc
*sc
= mac
->mac_sc
;
751 struct bwi_phy
*phy
= &mac
->mac_phy
;
752 struct bwi_rf
*rf
= &mac
->mac_rf
;
753 struct bwi_tpctl tpctl_orig
;
754 int restore_tpctl
= 0;
756 KKASSERT(phy
->phy_mode
!= IEEE80211_MODE_11A
);
758 if (BWI_IS_BRCM_BU4306(sc
))
761 PHY_WRITE(mac
, 0x28, 0x8018);
762 CSR_CLRBITS_2(sc
, BWI_BBP_ATTEN
, 0x20);
764 if (phy
->phy_mode
== IEEE80211_MODE_11G
) {
765 if ((phy
->phy_flags
& BWI_PHY_F_LINKED
) == 0)
767 PHY_WRITE(mac
, 0x47a, 0xc111);
769 if (mac
->mac_flags
& BWI_MAC_F_TPCTL_INITED
)
772 if (phy
->phy_mode
== IEEE80211_MODE_11B
&& phy
->phy_rev
>= 2 &&
773 rf
->rf_type
== BWI_RF_T_BCM2050
) {
774 RF_SETBITS(mac
, 0x76, 0x84);
776 struct bwi_tpctl tpctl
;
778 /* Backup original TX power control variables */
779 bcopy(&mac
->mac_tpctl
, &tpctl_orig
, sizeof(tpctl_orig
));
782 bcopy(&mac
->mac_tpctl
, &tpctl
, sizeof(tpctl
));
783 tpctl
.bbp_atten
= 11;
786 if (rf
->rf_rev
>= 6 && rf
->rf_rev
<= 8)
792 bwi_mac_set_tpctl_11bg(mac
, &tpctl
);
795 bwi_mac_dummy_xmit(mac
);
797 mac
->mac_flags
|= BWI_MAC_F_TPCTL_INITED
;
798 rf
->rf_base_tssi
= PHY_READ(mac
, 0x29);
799 DPRINTF(sc
, BWI_DBG_MAC
| BWI_DBG_INIT
| BWI_DBG_TXPOWER
,
800 "base tssi %d\n", rf
->rf_base_tssi
);
802 if (abs(rf
->rf_base_tssi
- rf
->rf_idle_tssi
) >= 20) {
803 if_printf(&sc
->sc_ic
.ic_if
, "base tssi measure failed\n");
804 mac
->mac_flags
|= BWI_MAC_F_TPCTL_ERROR
;
808 bwi_mac_set_tpctl_11bg(mac
, &tpctl_orig
);
810 RF_CLRBITS(mac
, 0x76, 0x84);
812 bwi_rf_clear_tssi(mac
);
816 bwi_mac_detach(struct bwi_mac
*mac
)
818 bwi_mac_fw_free(mac
);
822 bwi_fwimage_is_valid(struct bwi_softc
*sc
, const struct fw_image
*fw
,
825 const struct bwi_fwhdr
*hdr
;
826 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
828 if (fw
->fw_imglen
< sizeof(*hdr
)) {
829 if_printf(ifp
, "invalid firmware (%s): invalid size %u\n",
830 fw
->fw_name
, fw
->fw_imglen
);
834 hdr
= (const struct bwi_fwhdr
*)fw
->fw_image
;
836 if (fw_type
!= BWI_FW_T_IV
) {
838 * Don't verify IV's size, it has different meaning
840 if (be32toh(hdr
->fw_size
) != fw
->fw_imglen
- sizeof(*hdr
)) {
841 if_printf(ifp
, "invalid firmware (%s): size mismatch, "
842 "fw %u, real %u\n", fw
->fw_name
,
843 be32toh(hdr
->fw_size
),
844 fw
->fw_imglen
- sizeof(*hdr
));
849 if (hdr
->fw_type
!= fw_type
) {
850 if_printf(ifp
, "invalid firmware (%s): type mismatch, "
851 "fw \'%c\', target \'%c\'\n", fw
->fw_name
,
852 hdr
->fw_type
, fw_type
);
856 if (hdr
->fw_gen
!= BWI_FW_GEN_1
) {
857 if_printf(ifp
, "invalid firmware (%s): wrong generation, "
858 "fw %d, target %d\n", fw
->fw_name
,
859 hdr
->fw_gen
, BWI_FW_GEN_1
);
869 bwi_mac_fw_alloc(struct bwi_mac
*mac
)
871 struct bwi_softc
*sc
= mac
->mac_sc
;
872 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
873 struct fw_image
*img
;
878 * NB: serializer need to be released before loading firmware
879 * image to avoid possible dead lock
881 ASSERT_SERIALIZED(ifp
->if_serializer
);
883 if (mac
->mac_ucode
== NULL
) {
884 ksnprintf(fwname
, sizeof(fwname
), BWI_FW_UCODE_PATH
,
886 mac
->mac_rev
>= 5 ? 5 : mac
->mac_rev
);
888 lwkt_serialize_exit(ifp
->if_serializer
);
889 img
= firmware_image_load(fwname
, NULL
);
890 lwkt_serialize_enter(ifp
->if_serializer
);
892 mac
->mac_ucode
= img
;
893 if (mac
->mac_ucode
== NULL
) {
894 if_printf(ifp
, "request firmware %s failed\n", fwname
);
898 if (!bwi_fwimage_is_valid(sc
, mac
->mac_ucode
, BWI_FW_T_UCODE
))
902 if (mac
->mac_pcm
== NULL
) {
903 ksnprintf(fwname
, sizeof(fwname
), BWI_FW_PCM_PATH
,
905 mac
->mac_rev
< 5 ? 4 : 5);
907 lwkt_serialize_exit(ifp
->if_serializer
);
908 img
= firmware_image_load(fwname
, NULL
);
909 lwkt_serialize_enter(ifp
->if_serializer
);
912 if (mac
->mac_pcm
== NULL
) {
913 if_printf(ifp
, "request firmware %s failed\n", fwname
);
917 if (!bwi_fwimage_is_valid(sc
, mac
->mac_pcm
, BWI_FW_T_PCM
))
921 if (mac
->mac_iv
== NULL
) {
923 if (mac
->mac_rev
== 2 || mac
->mac_rev
== 4) {
925 } else if (mac
->mac_rev
>= 5 && mac
->mac_rev
<= 10) {
928 if_printf(ifp
, "no suitable IV for MAC rev %d\n",
933 ksnprintf(fwname
, sizeof(fwname
), BWI_FW_IV_PATH
,
934 sc
->sc_fw_version
, idx
);
936 lwkt_serialize_exit(ifp
->if_serializer
);
937 img
= firmware_image_load(fwname
, NULL
);
938 lwkt_serialize_enter(ifp
->if_serializer
);
941 if (mac
->mac_iv
== NULL
) {
942 if_printf(ifp
, "request firmware %s failed\n", fwname
);
945 if (!bwi_fwimage_is_valid(sc
, mac
->mac_iv
, BWI_FW_T_IV
))
949 if (mac
->mac_iv_ext
== NULL
) {
951 if (mac
->mac_rev
== 2 || mac
->mac_rev
== 4 ||
952 mac
->mac_rev
>= 11) {
955 } else if (mac
->mac_rev
>= 5 && mac
->mac_rev
<= 10) {
958 if_printf(ifp
, "no suitible ExtIV for MAC rev %d\n",
963 ksnprintf(fwname
, sizeof(fwname
), BWI_FW_IV_EXT_PATH
,
964 sc
->sc_fw_version
, idx
);
966 lwkt_serialize_exit(ifp
->if_serializer
);
967 img
= firmware_image_load(fwname
, NULL
);
968 lwkt_serialize_enter(ifp
->if_serializer
);
970 mac
->mac_iv_ext
= img
;
971 if (mac
->mac_iv_ext
== NULL
) {
972 if_printf(ifp
, "request firmware %s failed\n", fwname
);
975 if (!bwi_fwimage_is_valid(sc
, mac
->mac_iv_ext
, BWI_FW_T_IV
))
983 bwi_mac_fw_free(struct bwi_mac
*mac
)
985 if (mac
->mac_ucode
!= NULL
) {
986 firmware_image_unload(mac
->mac_ucode
);
987 mac
->mac_ucode
= NULL
;
990 if (mac
->mac_pcm
!= NULL
) {
991 firmware_image_unload(mac
->mac_pcm
);
995 if (mac
->mac_iv
!= NULL
) {
996 firmware_image_unload(mac
->mac_iv
);
1000 if (mac
->mac_iv_ext
!= NULL
) {
1001 firmware_image_unload(mac
->mac_iv_ext
);
1002 mac
->mac_iv_ext
= NULL
;
1007 bwi_mac_fw_load(struct bwi_mac
*mac
)
1009 struct bwi_softc
*sc
= mac
->mac_sc
;
1010 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
1018 fw
= (const uint32_t *)
1019 ((const uint8_t *)mac
->mac_ucode
->fw_image
+ BWI_FWHDR_SZ
);
1020 fw_len
= (mac
->mac_ucode
->fw_imglen
- BWI_FWHDR_SZ
) / sizeof(uint32_t);
1022 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
,
1024 BWI_FW_UCODE_MOBJ
| BWI_WR_MOBJ_AUTOINC
, 0));
1025 for (i
= 0; i
< fw_len
; ++i
) {
1026 CSR_WRITE_4(sc
, BWI_MOBJ_DATA
, be32toh(fw
[i
]));
1033 fw
= (const uint32_t *)
1034 ((const uint8_t *)mac
->mac_pcm
->fw_image
+ BWI_FWHDR_SZ
);
1035 fw_len
= (mac
->mac_pcm
->fw_imglen
- BWI_FWHDR_SZ
) / sizeof(uint32_t);
1037 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
,
1038 BWI_MOBJ_CTRL_VAL(BWI_FW_PCM_MOBJ
, 0x01ea));
1039 CSR_WRITE_4(sc
, BWI_MOBJ_DATA
, 0x4000);
1041 CSR_WRITE_4(sc
, BWI_MOBJ_CTRL
,
1042 BWI_MOBJ_CTRL_VAL(BWI_FW_PCM_MOBJ
, 0x01eb));
1043 for (i
= 0; i
< fw_len
; ++i
) {
1044 CSR_WRITE_4(sc
, BWI_MOBJ_DATA
, be32toh(fw
[i
]));
1048 CSR_WRITE_4(sc
, BWI_MAC_INTR_STATUS
, BWI_ALL_INTRS
);
1049 CSR_WRITE_4(sc
, BWI_MAC_STATUS
,
1050 BWI_MAC_STATUS_UCODE_START
|
1051 BWI_MAC_STATUS_IHREN
|
1052 BWI_MAC_STATUS_INFRA
);
1056 for (i
= 0; i
< NRETRY
; ++i
) {
1057 uint32_t intr_status
;
1059 intr_status
= CSR_READ_4(sc
, BWI_MAC_INTR_STATUS
);
1060 if (intr_status
== BWI_INTR_READY
)
1065 if_printf(ifp
, "firmware (ucode&pcm) loading timed out\n");
1071 CSR_READ_4(sc
, BWI_MAC_INTR_STATUS
); /* dummy read */
1073 fw_rev
= MOBJ_READ_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_FWREV
);
1074 if (fw_rev
> BWI_FW_VERSION3_REVMAX
) {
1075 if_printf(ifp
, "firmware version 4 is not supported yet\n");
1079 if_printf(ifp
, "firmware rev 0x%04x, patch level 0x%04x\n", fw_rev
,
1080 MOBJ_READ_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_FWPATCHLV
));
1085 bwi_mac_gpio_init(struct bwi_mac
*mac
)
1087 struct bwi_softc
*sc
= mac
->mac_sc
;
1088 struct bwi_regwin
*old
, *gpio_rw
;
1089 uint32_t filt
, bits
;
1092 CSR_CLRBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_GPOSEL_MASK
);
1095 CSR_SETBITS_2(sc
, BWI_MAC_GPIO_MASK
, 0xf);
1099 if (sc
->sc_bbp_id
== BWI_BBPID_BCM4301
) {
1103 if (sc
->sc_card_flags
& BWI_CARD_F_PA_GPIO9
) {
1104 CSR_SETBITS_2(sc
, BWI_MAC_GPIO_MASK
, 0x200);
1109 gpio_rw
= BWI_GPIO_REGWIN(sc
);
1110 error
= bwi_regwin_switch(sc
, gpio_rw
, &old
);
1114 CSR_FILT_SETBITS_4(sc
, BWI_GPIO_CTRL
, filt
, bits
);
1116 return bwi_regwin_switch(sc
, old
, NULL
);
1120 bwi_mac_gpio_fini(struct bwi_mac
*mac
)
1122 struct bwi_softc
*sc
= mac
->mac_sc
;
1123 struct bwi_regwin
*old
, *gpio_rw
;
1126 gpio_rw
= BWI_GPIO_REGWIN(sc
);
1127 error
= bwi_regwin_switch(sc
, gpio_rw
, &old
);
1131 CSR_WRITE_4(sc
, BWI_GPIO_CTRL
, 0);
1133 return bwi_regwin_switch(sc
, old
, NULL
);
1137 bwi_mac_fw_load_iv(struct bwi_mac
*mac
, const struct fw_image
*fw
)
1139 struct bwi_softc
*sc
= mac
->mac_sc
;
1140 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
1141 const struct bwi_fwhdr
*hdr
;
1142 const struct bwi_fw_iv
*iv
;
1143 int n
, i
, iv_img_size
;
1145 /* Get the number of IVs in the IV image */
1146 hdr
= (const struct bwi_fwhdr
*)fw
->fw_image
;
1147 n
= be32toh(hdr
->fw_iv_cnt
);
1148 DPRINTF(sc
, BWI_DBG_MAC
| BWI_DBG_INIT
| BWI_DBG_FIRMWARE
,
1149 "IV count %d\n", n
);
1151 /* Calculate the IV image size, for later sanity check */
1152 iv_img_size
= fw
->fw_imglen
- sizeof(*hdr
);
1154 /* Locate the first IV */
1155 iv
= (const struct bwi_fw_iv
*)
1156 ((const uint8_t *)fw
->fw_image
+ sizeof(*hdr
));
1158 for (i
= 0; i
< n
; ++i
) {
1159 uint16_t iv_ofs
, ofs
;
1162 if (iv_img_size
< sizeof(iv
->iv_ofs
)) {
1163 if_printf(ifp
, "invalid IV image, ofs\n");
1166 iv_img_size
-= sizeof(iv
->iv_ofs
);
1167 sz
+= sizeof(iv
->iv_ofs
);
1169 iv_ofs
= be16toh(iv
->iv_ofs
);
1171 ofs
= __SHIFTOUT(iv_ofs
, BWI_FW_IV_OFS_MASK
);
1172 if (ofs
>= 0x1000) {
1173 if_printf(ifp
, "invalid ofs (0x%04x) "
1174 "for %dth iv\n", ofs
, i
);
1178 if (iv_ofs
& BWI_FW_IV_IS_32BIT
) {
1181 if (iv_img_size
< sizeof(iv
->iv_val
.val32
)) {
1182 if_printf(ifp
, "invalid IV image, val32\n");
1185 iv_img_size
-= sizeof(iv
->iv_val
.val32
);
1186 sz
+= sizeof(iv
->iv_val
.val32
);
1188 val32
= be32toh(iv
->iv_val
.val32
);
1189 CSR_WRITE_4(sc
, ofs
, val32
);
1193 if (iv_img_size
< sizeof(iv
->iv_val
.val16
)) {
1194 if_printf(ifp
, "invalid IV image, val16\n");
1197 iv_img_size
-= sizeof(iv
->iv_val
.val16
);
1198 sz
+= sizeof(iv
->iv_val
.val16
);
1200 val16
= be16toh(iv
->iv_val
.val16
);
1201 CSR_WRITE_2(sc
, ofs
, val16
);
1204 iv
= (const struct bwi_fw_iv
*)((const uint8_t *)iv
+ sz
);
1207 if (iv_img_size
!= 0) {
1208 if_printf(ifp
, "invalid IV image, size left %d\n", iv_img_size
);
1215 bwi_mac_fw_init(struct bwi_mac
*mac
)
1217 struct ifnet
*ifp
= &mac
->mac_sc
->sc_ic
.ic_if
;
1220 error
= bwi_mac_fw_load_iv(mac
, mac
->mac_iv
);
1222 if_printf(ifp
, "load IV failed\n");
1226 if (mac
->mac_iv_ext
!= NULL
) {
1227 error
= bwi_mac_fw_load_iv(mac
, mac
->mac_iv_ext
);
1229 if_printf(ifp
, "load ExtIV failed\n");
1235 bwi_mac_opmode_init(struct bwi_mac
*mac
)
1237 struct bwi_softc
*sc
= mac
->mac_sc
;
1238 struct ieee80211com
*ic
= &sc
->sc_ic
;
1239 uint32_t mac_status
;
1242 CSR_CLRBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_INFRA
);
1243 CSR_SETBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_INFRA
);
1244 CSR_SETBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_PASS_BCN
);
1246 /* Set probe resp timeout to infinite */
1247 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_PROBE_RESP_TO
, 0);
1250 * TODO: factor out following part
1253 mac_status
= CSR_READ_4(sc
, BWI_MAC_STATUS
);
1254 mac_status
&= ~(BWI_MAC_STATUS_OPMODE_HOSTAP
|
1255 BWI_MAC_STATUS_PASS_CTL
|
1256 BWI_MAC_STATUS_PASS_BADPLCP
|
1257 BWI_MAC_STATUS_PASS_BADFCS
|
1258 BWI_MAC_STATUS_PROMISC
);
1259 mac_status
|= BWI_MAC_STATUS_INFRA
;
1261 /* Always turn on PROMISC on old hardware */
1262 if (mac
->mac_rev
< 5)
1263 mac_status
|= BWI_MAC_STATUS_PROMISC
;
1265 switch (ic
->ic_opmode
) {
1266 case IEEE80211_M_IBSS
:
1267 mac_status
&= ~BWI_MAC_STATUS_INFRA
;
1269 case IEEE80211_M_HOSTAP
:
1270 mac_status
|= BWI_MAC_STATUS_OPMODE_HOSTAP
;
1272 case IEEE80211_M_MONITOR
:
1274 /* Do you want data from your microwave oven? */
1275 mac_status
|= BWI_MAC_STATUS_PASS_CTL
|
1276 BWI_MAC_STATUS_PASS_BADPLCP
|
1277 BWI_MAC_STATUS_PASS_BADFCS
;
1279 mac_status
|= BWI_MAC_STATUS_PASS_CTL
;
1287 if (ic
->ic_if
.if_flags
& IFF_PROMISC
)
1288 mac_status
|= BWI_MAC_STATUS_PROMISC
;
1290 CSR_WRITE_4(sc
, BWI_MAC_STATUS
, mac_status
);
1292 if (ic
->ic_opmode
!= IEEE80211_M_IBSS
&&
1293 ic
->ic_opmode
!= IEEE80211_M_HOSTAP
) {
1294 if (sc
->sc_bbp_id
== BWI_BBPID_BCM4306
&& sc
->sc_bbp_rev
== 3)
1301 CSR_WRITE_2(sc
, BWI_MAC_PRE_TBTT
, pre_tbtt
);
1305 bwi_mac_hostflags_init(struct bwi_mac
*mac
)
1307 struct bwi_softc
*sc
= mac
->mac_sc
;
1308 struct bwi_phy
*phy
= &mac
->mac_phy
;
1309 struct bwi_rf
*rf
= &mac
->mac_rf
;
1310 uint64_t host_flags
;
1312 if (phy
->phy_mode
== IEEE80211_MODE_11A
)
1315 host_flags
= HFLAGS_READ(mac
);
1316 host_flags
|= BWI_HFLAG_SYM_WA
;
1318 if (phy
->phy_mode
== IEEE80211_MODE_11G
) {
1319 if (phy
->phy_rev
== 1)
1320 host_flags
|= BWI_HFLAG_GDC_WA
;
1321 if (sc
->sc_card_flags
& BWI_CARD_F_PA_GPIO9
)
1322 host_flags
|= BWI_HFLAG_OFDM_PA
;
1323 } else if (phy
->phy_mode
== IEEE80211_MODE_11B
) {
1324 if (phy
->phy_rev
>= 2 && rf
->rf_type
== BWI_RF_T_BCM2050
)
1325 host_flags
&= ~BWI_HFLAG_GDC_WA
;
1327 panic("unknown PHY mode %u\n", phy
->phy_mode
);
1330 HFLAGS_WRITE(mac
, host_flags
);
1334 bwi_mac_bss_param_init(struct bwi_mac
*mac
)
1336 struct bwi_softc
*sc
= mac
->mac_sc
;
1337 struct bwi_phy
*phy
= &mac
->mac_phy
;
1338 struct bwi_retry_lim lim
;
1342 * Set short/long retry limits
1344 bzero(&lim
, sizeof(lim
));
1345 lim
.shretry
= BWI_SHRETRY
;
1346 lim
.shretry_fb
= BWI_SHRETRY_FB
;
1347 lim
.lgretry
= BWI_LGRETRY
;
1348 lim
.lgretry_fb
= BWI_LGRETRY_FB
;
1349 bwi_mac_set_retry_lim(mac
, &lim
);
1352 * Implicitly prevent firmware from sending probe response
1353 * by setting its "probe response timeout" to 1us.
1355 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_PROBE_RESP_TO
, 1);
1358 * XXX MAC level acknowledge and CW min/max should depend
1359 * on the char rateset of the IBSS/BSS to join.
1363 * Set MAC level acknowledge rates
1365 bwi_mac_set_ackrates(mac
, &sc
->sc_ic
.ic_sup_rates
[phy
->phy_mode
]);
1370 if (phy
->phy_mode
== IEEE80211_MODE_11B
)
1371 cw_min
= IEEE80211_CW_MIN_0
;
1373 cw_min
= IEEE80211_CW_MIN_1
;
1374 MOBJ_WRITE_2(mac
, BWI_80211_MOBJ
, BWI_80211_MOBJ_CWMIN
, cw_min
);
1379 MOBJ_WRITE_2(mac
, BWI_80211_MOBJ
, BWI_80211_MOBJ_CWMAX
,
1384 bwi_mac_set_retry_lim(struct bwi_mac
*mac
, const struct bwi_retry_lim
*lim
)
1386 /* Short/Long retry limit */
1387 MOBJ_WRITE_2(mac
, BWI_80211_MOBJ
, BWI_80211_MOBJ_SHRETRY
,
1389 MOBJ_WRITE_2(mac
, BWI_80211_MOBJ
, BWI_80211_MOBJ_LGRETRY
,
1392 /* Short/Long retry fallback limit */
1393 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_SHRETRY_FB
,
1395 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_LGRETEY_FB
,
1400 bwi_mac_set_ackrates(struct bwi_mac
*mac
, const struct ieee80211_rateset
*rs
)
1404 /* XXX not standard conforming */
1405 for (i
= 0; i
< rs
->rs_nrates
; ++i
) {
1406 enum ieee80211_modtype modtype
;
1409 modtype
= ieee80211_rate2modtype(rs
->rs_rates
[i
]);
1411 case IEEE80211_MODTYPE_DS
:
1414 case IEEE80211_MODTYPE_OFDM
:
1418 panic("unsupported modtype %u\n", modtype
);
1420 ofs
+= (bwi_rate2plcp(rs
->rs_rates
[i
]) & 0xf) * 2;
1422 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, ofs
+ 0x20,
1423 MOBJ_READ_2(mac
, BWI_COMM_MOBJ
, ofs
));
1428 bwi_mac_start(struct bwi_mac
*mac
)
1430 struct bwi_softc
*sc
= mac
->mac_sc
;
1432 CSR_SETBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_ENABLE
);
1433 CSR_WRITE_4(sc
, BWI_MAC_INTR_STATUS
, BWI_INTR_READY
);
1435 /* Flush pending bus writes */
1436 CSR_READ_4(sc
, BWI_MAC_STATUS
);
1437 CSR_READ_4(sc
, BWI_MAC_INTR_STATUS
);
1439 return bwi_mac_config_ps(mac
);
1443 bwi_mac_stop(struct bwi_mac
*mac
)
1445 struct bwi_softc
*sc
= mac
->mac_sc
;
1448 error
= bwi_mac_config_ps(mac
);
1452 CSR_CLRBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_ENABLE
);
1454 /* Flush pending bus write */
1455 CSR_READ_4(sc
, BWI_MAC_STATUS
);
1457 #define NRETRY 10000
1458 for (i
= 0; i
< NRETRY
; ++i
) {
1459 if (CSR_READ_4(sc
, BWI_MAC_INTR_STATUS
) & BWI_INTR_READY
)
1464 if_printf(&sc
->sc_ic
.ic_if
, "can't stop MAC\n");
1473 bwi_mac_config_ps(struct bwi_mac
*mac
)
1475 struct bwi_softc
*sc
= mac
->mac_sc
;
1478 status
= CSR_READ_4(sc
, BWI_MAC_STATUS
);
1480 status
&= ~BWI_MAC_STATUS_HW_PS
;
1481 status
|= BWI_MAC_STATUS_WAKEUP
;
1482 CSR_WRITE_4(sc
, BWI_MAC_STATUS
, status
);
1484 /* Flush pending bus write */
1485 CSR_READ_4(sc
, BWI_MAC_STATUS
);
1487 if (mac
->mac_rev
>= 5) {
1491 for (i
= 0; i
< NRETRY
; ++i
) {
1492 if (MOBJ_READ_2(mac
, BWI_COMM_MOBJ
,
1493 BWI_COMM_MOBJ_UCODE_STATE
) != BWI_UCODE_STATE_PS
)
1498 if_printf(&sc
->sc_ic
.ic_if
, "config PS failed\n");
1507 bwi_mac_reset_hwkeys(struct bwi_mac
*mac
)
1509 /* TODO: firmware crypto */
1510 MOBJ_READ_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_KEYTABLE_OFS
);
1514 bwi_mac_shutdown(struct bwi_mac
*mac
)
1516 struct bwi_softc
*sc
= mac
->mac_sc
;
1519 if (mac
->mac_flags
& BWI_MAC_F_HAS_TXSTATS
)
1520 sc
->sc_free_txstats(sc
);
1522 sc
->sc_free_rx_ring(sc
);
1524 for (i
= 0; i
< BWI_TX_NRING
; ++i
)
1525 sc
->sc_free_tx_ring(sc
, i
);
1531 bwi_mac_gpio_fini(mac
);
1533 bwi_rf_off(mac
); /* XXX again */
1534 CSR_WRITE_2(sc
, BWI_BBP_ATTEN
, BWI_BBP_ATTEN_MAGIC
);
1535 bwi_regwin_disable(sc
, &mac
->mac_regwin
, 0);
1537 mac
->mac_flags
&= ~BWI_MAC_F_INITED
;
1541 bwi_mac_get_property(struct bwi_mac
*mac
)
1543 struct bwi_softc
*sc
= mac
->mac_sc
;
1544 enum bwi_bus_space old_bus_space
;
1550 val
= CSR_READ_4(sc
, BWI_MAC_STATUS
);
1551 if (val
& BWI_MAC_STATUS_BSWAP
) {
1552 DPRINTF(sc
, BWI_DBG_MAC
| BWI_DBG_ATTACH
, "%s\n",
1554 mac
->mac_flags
|= BWI_MAC_F_BSWAP
;
1560 old_bus_space
= sc
->sc_bus_space
;
1562 val
= CSR_READ_4(sc
, BWI_STATE_HI
);
1563 if (__SHIFTOUT(val
, BWI_STATE_HI_FLAGS_MASK
) &
1564 BWI_STATE_HI_FLAG_64BIT
) {
1566 sc
->sc_bus_space
= BWI_BUS_SPACE_64BIT
;
1567 DPRINTF(sc
, BWI_DBG_MAC
| BWI_DBG_ATTACH
, "%s\n",
1570 uint32_t txrx_reg
= BWI_TXRX_CTRL_BASE
+ BWI_TX32_CTRL
;
1572 CSR_WRITE_4(sc
, txrx_reg
, BWI_TXRX32_CTRL_ADDRHI_MASK
);
1573 if (CSR_READ_4(sc
, txrx_reg
) & BWI_TXRX32_CTRL_ADDRHI_MASK
) {
1575 sc
->sc_bus_space
= BWI_BUS_SPACE_32BIT
;
1576 DPRINTF(sc
, BWI_DBG_MAC
| BWI_DBG_ATTACH
, "%s\n",
1580 sc
->sc_bus_space
= BWI_BUS_SPACE_30BIT
;
1581 DPRINTF(sc
, BWI_DBG_MAC
| BWI_DBG_ATTACH
, "%s\n",
1586 if (old_bus_space
!= 0 && old_bus_space
!= sc
->sc_bus_space
) {
1587 device_printf(sc
->sc_dev
, "MACs bus space mismatch!\n");
1594 bwi_mac_updateslot(struct bwi_mac
*mac
, int shslot
)
1598 if (mac
->mac_phy
.phy_mode
== IEEE80211_MODE_11B
)
1602 slot_time
= IEEE80211_DUR_SHSLOT
;
1604 slot_time
= IEEE80211_DUR_SLOT
;
1606 CSR_WRITE_2(mac
->mac_sc
, BWI_MAC_SLOTTIME
,
1607 slot_time
+ BWI_MAC_SLOTTIME_ADJUST
);
1608 MOBJ_WRITE_2(mac
, BWI_COMM_MOBJ
, BWI_COMM_MOBJ_SLOTTIME
, slot_time
);
1612 bwi_mac_attach(struct bwi_softc
*sc
, int id
, uint8_t rev
)
1614 struct bwi_mac
*mac
;
1617 KKASSERT(sc
->sc_nmac
<= BWI_MAC_MAX
&& sc
->sc_nmac
>= 0);
1619 if (sc
->sc_nmac
== BWI_MAC_MAX
) {
1620 device_printf(sc
->sc_dev
, "too many MACs\n");
1625 * More than one MAC is only supported by BCM4309
1627 if (sc
->sc_nmac
!= 0 &&
1628 pci_get_device(sc
->sc_dev
) != PCI_PRODUCT_BROADCOM_BCM4309
) {
1629 DPRINTF(sc
, BWI_DBG_MAC
| BWI_DBG_ATTACH
, "%s\n",
1630 "ignore second MAC");
1634 mac
= &sc
->sc_mac
[sc
->sc_nmac
];
1636 /* XXX will this happen? */
1637 if (BWI_REGWIN_EXIST(&mac
->mac_regwin
)) {
1638 device_printf(sc
->sc_dev
, "%dth MAC already attached\n",
1644 * Test whether the revision of this MAC is supported
1646 #define N(arr) (int)(sizeof(arr) / sizeof(arr[0]))
1647 for (i
= 0; i
< N(bwi_sup_macrev
); ++i
) {
1648 if (bwi_sup_macrev
[i
] == rev
)
1651 if (i
== N(bwi_sup_macrev
)) {
1652 device_printf(sc
->sc_dev
, "MAC rev %u is "
1653 "not supported\n", rev
);
1658 BWI_CREATE_MAC(mac
, sc
, id
, rev
);
1661 if (mac
->mac_rev
< 5) {
1662 mac
->mac_flags
|= BWI_MAC_F_HAS_TXSTATS
;
1663 DPRINTF(sc
, BWI_DBG_MAC
| BWI_DBG_ATTACH
, "%s\n",
1667 device_printf(sc
->sc_dev
, "MAC: rev %u\n", rev
);
1671 static __inline
void
1672 bwi_mac_balance_atten(int *bbp_atten0
, int *rf_atten0
)
1674 int bbp_atten
, rf_atten
, rf_atten_lim
= -1;
1676 bbp_atten
= *bbp_atten0
;
1677 rf_atten
= *rf_atten0
;
1680 * RF attenuation affects TX power BWI_RF_ATTEN_FACTOR times
1681 * as much as BBP attenuation, so we try our best to keep RF
1682 * attenuation within range. BBP attenuation will be clamped
1683 * later if it is out of range during balancing.
1685 * BWI_RF_ATTEN_MAX0 is used as RF attenuation upper limit.
1689 * Use BBP attenuation to balance RF attenuation
1693 else if (rf_atten
> BWI_RF_ATTEN_MAX0
)
1694 rf_atten_lim
= BWI_RF_ATTEN_MAX0
;
1696 if (rf_atten_lim
>= 0) {
1697 bbp_atten
+= (BWI_RF_ATTEN_FACTOR
* (rf_atten
- rf_atten_lim
));
1698 rf_atten
= rf_atten_lim
;
1702 * If possible, use RF attenuation to balance BBP attenuation
1703 * NOTE: RF attenuation is still kept within range.
1705 while (rf_atten
< BWI_RF_ATTEN_MAX0
&& bbp_atten
> BWI_BBP_ATTEN_MAX
) {
1706 bbp_atten
-= BWI_RF_ATTEN_FACTOR
;
1709 while (rf_atten
> 0 && bbp_atten
< 0) {
1710 bbp_atten
+= BWI_RF_ATTEN_FACTOR
;
1714 /* RF attenuation MUST be within range */
1715 KKASSERT(rf_atten
>= 0 && rf_atten
<= BWI_RF_ATTEN_MAX0
);
1718 * Clamp BBP attenuation
1722 else if (bbp_atten
> BWI_BBP_ATTEN_MAX
)
1723 bbp_atten
= BWI_BBP_ATTEN_MAX
;
1725 *rf_atten0
= rf_atten
;
1726 *bbp_atten0
= bbp_atten
;
1730 bwi_mac_adjust_tpctl(struct bwi_mac
*mac
, int rf_atten_adj
, int bbp_atten_adj
)
1732 struct bwi_softc
*sc
= mac
->mac_sc
;
1733 struct bwi_rf
*rf
= &mac
->mac_rf
;
1734 struct bwi_tpctl tpctl
;
1735 int bbp_atten
, rf_atten
, tp_ctrl1
;
1737 bcopy(&mac
->mac_tpctl
, &tpctl
, sizeof(tpctl
));
1739 /* NOTE: Use signed value to do calulation */
1740 bbp_atten
= tpctl
.bbp_atten
;
1741 rf_atten
= tpctl
.rf_atten
;
1742 tp_ctrl1
= tpctl
.tp_ctrl1
;
1744 bbp_atten
+= bbp_atten_adj
;
1745 rf_atten
+= rf_atten_adj
;
1747 bwi_mac_balance_atten(&bbp_atten
, &rf_atten
);
1749 if (rf
->rf_type
== BWI_RF_T_BCM2050
&& rf
->rf_rev
== 2) {
1750 if (rf_atten
<= 1) {
1751 if (tp_ctrl1
== 0) {
1755 } else if (sc
->sc_card_flags
& BWI_CARD_F_PA_GPIO9
) {
1757 (BWI_RF_ATTEN_FACTOR
* (rf_atten
- 2));
1760 } else if (rf_atten
> 4 && tp_ctrl1
!= 0) {
1762 if (bbp_atten
< 3) {
1770 bwi_mac_balance_atten(&bbp_atten
, &rf_atten
);
1773 tpctl
.bbp_atten
= bbp_atten
;
1774 tpctl
.rf_atten
= rf_atten
;
1775 tpctl
.tp_ctrl1
= tp_ctrl1
;
1778 bwi_mac_set_tpctl_11bg(mac
, &tpctl
);
1779 bwi_mac_unlock(mac
);
1783 * http://bcm-specs.sipsolutions.net/RecalculateTransmissionPower
1786 bwi_mac_calibrate_txpower(struct bwi_mac
*mac
)
1788 struct bwi_softc
*sc
= mac
->mac_sc
;
1789 struct bwi_rf
*rf
= &mac
->mac_rf
;
1790 int8_t tssi
[4], tssi_avg
, cur_txpwr
;
1791 int error
, i
, ofdm_tssi
;
1792 int txpwr_diff
, rf_atten_adj
, bbp_atten_adj
;
1794 if (!sc
->sc_txpwr_calib
)
1797 if (mac
->mac_flags
& BWI_MAC_F_TPCTL_ERROR
) {
1798 DPRINTF(sc
, BWI_DBG_MAC
| BWI_DBG_TXPOWER
, "%s\n",
1799 "tpctl error happened, can't set txpower");
1803 if (BWI_IS_BRCM_BU4306(sc
)) {
1804 DPRINTF(sc
, BWI_DBG_MAC
| BWI_DBG_TXPOWER
, "%s\n",
1805 "BU4306, can't set txpower");
1810 * Save latest TSSI and reset the related memory objects
1813 error
= bwi_rf_get_latest_tssi(mac
, tssi
, BWI_COMM_MOBJ_TSSI_DS
);
1815 DPRINTF(sc
, BWI_DBG_MAC
| BWI_DBG_TXPOWER
, "%s\n",
1818 if (mac
->mac_phy
.phy_mode
== IEEE80211_MODE_11B
)
1821 error
= bwi_rf_get_latest_tssi(mac
, tssi
,
1822 BWI_COMM_MOBJ_TSSI_OFDM
);
1824 DPRINTF(sc
, BWI_DBG_MAC
| BWI_DBG_TXPOWER
, "%s\n",
1829 for (i
= 0; i
< 4; ++i
) {
1835 bwi_rf_clear_tssi(mac
);
1837 DPRINTF(sc
, BWI_DBG_MAC
| BWI_DBG_TXPOWER
,
1838 "tssi0 %d, tssi1 %d, tssi2 %d, tssi3 %d\n",
1839 tssi
[0], tssi
[1], tssi
[2], tssi
[3]);
1842 * Calculate RF/BBP attenuation adjustment based on
1843 * the difference between desired TX power and sampled
1846 /* +8 == "each incremented by 1/2" */
1847 tssi_avg
= (tssi
[0] + tssi
[1] + tssi
[2] + tssi
[3] + 8) / 4;
1848 if (ofdm_tssi
&& (HFLAGS_READ(mac
) & BWI_HFLAG_PWR_BOOST_DS
))
1851 DPRINTF(sc
, BWI_DBG_MAC
| BWI_DBG_TXPOWER
, "tssi avg %d\n", tssi_avg
);
1853 error
= bwi_rf_tssi2dbm(mac
, tssi_avg
, &cur_txpwr
);
1856 DPRINTF(sc
, BWI_DBG_MAC
| BWI_DBG_TXPOWER
, "current txpower %d\n",
1859 txpwr_diff
= rf
->rf_txpower_max
- cur_txpwr
; /* XXX ni_txpower */
1861 rf_atten_adj
= -howmany(txpwr_diff
, 8);
1862 bbp_atten_adj
= -(txpwr_diff
/ 2) -
1863 (BWI_RF_ATTEN_FACTOR
* rf_atten_adj
);
1865 if (rf_atten_adj
== 0 && bbp_atten_adj
== 0) {
1866 DPRINTF(sc
, BWI_DBG_MAC
| BWI_DBG_TXPOWER
, "%s\n",
1867 "no need to adjust RF/BBP attenuation");
1872 DPRINTF(sc
, BWI_DBG_MAC
| BWI_DBG_TXPOWER
,
1873 "rf atten adjust %d, bbp atten adjust %d\n",
1874 rf_atten_adj
, bbp_atten_adj
);
1875 bwi_mac_adjust_tpctl(mac
, rf_atten_adj
, bbp_atten_adj
);
1880 bwi_mac_lock(struct bwi_mac
*mac
)
1882 struct bwi_softc
*sc
= mac
->mac_sc
;
1883 struct ieee80211com
*ic
= &sc
->sc_ic
;
1885 KKASSERT((mac
->mac_flags
& BWI_MAC_F_LOCKED
) == 0);
1887 if (mac
->mac_rev
< 3)
1889 else if (ic
->ic_opmode
!= IEEE80211_M_HOSTAP
)
1890 bwi_mac_config_ps(mac
);
1892 CSR_SETBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_RFLOCK
);
1894 /* Flush pending bus write */
1895 CSR_READ_4(sc
, BWI_MAC_STATUS
);
1898 mac
->mac_flags
|= BWI_MAC_F_LOCKED
;
1902 bwi_mac_unlock(struct bwi_mac
*mac
)
1904 struct bwi_softc
*sc
= mac
->mac_sc
;
1905 struct ieee80211com
*ic
= &sc
->sc_ic
;
1907 KKASSERT(mac
->mac_flags
& BWI_MAC_F_LOCKED
);
1909 CSR_READ_2(sc
, BWI_PHYINFO
); /* dummy read */
1911 CSR_CLRBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_RFLOCK
);
1913 if (mac
->mac_rev
< 3)
1915 else if (ic
->ic_opmode
!= IEEE80211_M_HOSTAP
)
1916 bwi_mac_config_ps(mac
);
1918 mac
->mac_flags
&= ~BWI_MAC_F_LOCKED
;
1922 bwi_mac_set_promisc(struct bwi_mac
*mac
, int promisc
)
1924 struct bwi_softc
*sc
= mac
->mac_sc
;
1926 if (mac
->mac_rev
< 5) /* Promisc is always on */
1930 CSR_SETBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_PROMISC
);
1932 CSR_CLRBITS_4(sc
, BWI_MAC_STATUS
, BWI_MAC_STATUS_PROMISC
);