--- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1535,7 +1535,7 @@ static void b43_write_beacon_template(st len, ram_offset, shm_size_offset, rate); /* Write the PHY TX control parameters. */ - antenna = B43_ANTENNA_DEFAULT; + antenna = dev->tx_antenna; antenna = b43_antenna_to_phyctl(antenna); ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL); /* We can't send beacons with short preamble. Would get PHY errors. */ @@ -3052,8 +3052,8 @@ static int b43_chip_init(struct b43_wlde /* Select the antennae */ if (phy->ops->set_rx_antenna) - phy->ops->set_rx_antenna(dev, B43_ANTENNA_DEFAULT); - b43_mgmtframe_txantenna(dev, B43_ANTENNA_DEFAULT); + phy->ops->set_rx_antenna(dev, dev->rx_antenna); + b43_mgmtframe_txantenna(dev, dev->tx_antenna); if (phy->type == B43_PHYTYPE_B) { value16 = b43_read16(dev, 0x005E); @@ -3782,7 +3782,6 @@ static int b43_op_config(struct ieee8021 struct b43_wldev *dev; struct b43_phy *phy; struct ieee80211_conf *conf = &hw->conf; - int antenna; int err = 0; bool reload_bss = false; @@ -3836,11 +3835,9 @@ static int b43_op_config(struct ieee8021 } /* Antennas for RX and management frame TX. */ - antenna = B43_ANTENNA_DEFAULT; - b43_mgmtframe_txantenna(dev, antenna); - antenna = B43_ANTENNA_DEFAULT; + b43_mgmtframe_txantenna(dev, dev->tx_antenna); if (phy->ops->set_rx_antenna) - phy->ops->set_rx_antenna(dev, antenna); + phy->ops->set_rx_antenna(dev, dev->rx_antenna); if (wl->radio_enabled != phy->radio_on) { if (wl->radio_enabled) { @@ -4910,6 +4907,47 @@ static int b43_op_get_survey(struct ieee return 0; } +static int b43_op_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) +{ + struct b43_wl *wl = hw_to_b43_wl(hw); + struct b43_wldev *dev = wl->current_dev; + + if (tx_ant == 1 && rx_ant == 1) { + dev->tx_antenna = B43_ANTENNA0; + dev->rx_antenna = B43_ANTENNA0; + } + else if (tx_ant == 2 && rx_ant == 2) { + dev->tx_antenna = B43_ANTENNA1; + dev->rx_antenna = B43_ANTENNA1; + } + else if ((tx_ant & 3) == 3 && (rx_ant & 3) == 3) { + dev->tx_antenna = B43_ANTENNA_DEFAULT; + dev->rx_antenna = B43_ANTENNA_DEFAULT; + } + else { + return -EINVAL; + } + + return 0; +} + + +static int b43_op_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) +{ + struct b43_wl *wl = hw_to_b43_wl(hw); + struct b43_wldev *dev = wl->current_dev; + + switch (dev->tx_antenna) { + case B43_ANTENNA0: + *tx_ant = 1; *rx_ant = 1; break; + case B43_ANTENNA1: + *tx_ant = 2; *rx_ant = 2; break; + case B43_ANTENNA_DEFAULT: + *tx_ant = 3; *rx_ant = 3; break; + } + return 0; +} + static const struct ieee80211_ops b43_hw_ops = { .tx = b43_op_tx, .conf_tx = b43_op_conf_tx, @@ -4931,6 +4969,8 @@ static const struct ieee80211_ops b43_hw .sw_scan_complete = b43_op_sw_scan_complete_notifier, .get_survey = b43_op_get_survey, .rfkill_poll = b43_rfkill_poll, + .set_antenna = b43_op_set_antenna, + .get_antenna = b43_op_get_antenna, }; /* Hard-reset the chip. Do not call this directly. @@ -5177,6 +5217,8 @@ static int b43_one_core_attach(struct b4 if (!wldev) goto out; + wldev->rx_antenna = B43_ANTENNA_DEFAULT; + wldev->tx_antenna = B43_ANTENNA_DEFAULT; wldev->use_pio = b43_modparam_pio; wldev->dev = dev; wldev->wl = wl; @@ -5264,6 +5306,9 @@ static struct b43_wl *b43_wireless_init( BIT(NL80211_IFTYPE_WDS) | BIT(NL80211_IFTYPE_ADHOC); + hw->wiphy->available_antennas_rx = 0x3; + hw->wiphy->available_antennas_tx = 0x3; + hw->queues = modparam_qos ? 4 : 1; wl->mac80211_initially_registered_queues = hw->queues; hw->max_rates = 2; --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -792,6 +792,8 @@ struct b43_wldev { bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */ bool use_pio; /* TRUE if next init should use PIO */ int gpiomask; /* GPIO LED mask as a module parameter */ + int rx_antenna; /* Used RX antenna (B43_ANTENNAxxx) */ + int tx_antenna; /* Used TX antenna (B43_ANTENNAxxx) */ /* PHY/Radio device. */ struct b43_phy phy;