[rt2x00-users] [PATCH] rt2x00: Implement get_antenna and set_antenna callback functions
Gertjan van Wingerde
gwingerde at gmail.com
Sun Apr 17 22:47:06 EST 2011
On 16 apr. 2011, at 21:59, Ivo van Doorn <ivdoorn at gmail.com> wrote:
> Implement the get_antenna and set_antenna callback functions, which will
> allow clients to control the antenna for all non-11n hardware (Antenna handling
> in rt2800 is still a bit magical, so we can't use the set_antenna for those drivers
> yet).
>
> To best support the set_antenna callback some modifications are needed in the
> diversity handling. We should never look at the default antenna settings to determine
> if software diversity is enabled. Instead we should set the diversity flag when
> possible, which will allow the link_tuner to automatically pick up the tuning.
>
> Signed-off-by: Ivo van Doorn <IvDoorn at gmail.com>
Acked-by: Gertjan van Wingerde <gwingerde at gmail.com>
> ---
> diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
> index bbe76f7..937f9e8 100644
> --- a/drivers/net/wireless/rt2x00/rt2400pci.c
> +++ b/drivers/net/wireless/rt2x00/rt2400pci.c
> @@ -1720,6 +1720,8 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = {
> .tx_last_beacon = rt2400pci_tx_last_beacon,
> .rfkill_poll = rt2x00mac_rfkill_poll,
> .flush = rt2x00mac_flush,
> + .set_antenna = rt2x00mac_set_antenna,
> + .get_antenna = rt2x00mac_get_antenna,
> .get_ringparam = rt2x00mac_get_ringparam,
> };
>
> diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
> index 6f48996..d27d7b8 100644
> --- a/drivers/net/wireless/rt2x00/rt2500pci.c
> +++ b/drivers/net/wireless/rt2x00/rt2500pci.c
> @@ -2013,6 +2013,8 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = {
> .tx_last_beacon = rt2500pci_tx_last_beacon,
> .rfkill_poll = rt2x00mac_rfkill_poll,
> .flush = rt2x00mac_flush,
> + .set_antenna = rt2x00mac_set_antenna,
> + .get_antenna = rt2x00mac_get_antenna,
> .get_ringparam = rt2x00mac_get_ringparam,
> };
>
> diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
> index 9298446..8f379bd 100644
> --- a/drivers/net/wireless/rt2x00/rt2500usb.c
> +++ b/drivers/net/wireless/rt2x00/rt2500usb.c
> @@ -1823,6 +1823,8 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = {
> .conf_tx = rt2x00mac_conf_tx,
> .rfkill_poll = rt2x00mac_rfkill_poll,
> .flush = rt2x00mac_flush,
> + .set_antenna = rt2x00mac_set_antenna,
> + .get_antenna = rt2x00mac_get_antenna,
> .get_ringparam = rt2x00mac_get_ringparam,
> };
>
> diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
> index f1d8f55..acf561f 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00.h
> +++ b/drivers/net/wireless/rt2x00/rt2x00.h
> @@ -1254,6 +1254,8 @@ int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
> const struct ieee80211_tx_queue_params *params);
> void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw);
> void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop);
> +int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant);
> +int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
> void rt2x00mac_get_ringparam(struct ieee80211_hw *hw,
> u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max);
>
> diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
> index f70a2b4..2a313b6 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00config.c
> +++ b/drivers/net/wireless/rt2x00/rt2x00config.c
> @@ -109,15 +109,6 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
> rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp, changed);
> }
>
> -static inline
> -enum antenna rt2x00lib_config_antenna_check(enum antenna current_ant,
> - enum antenna default_ant)
> -{
> - if (current_ant != ANTENNA_SW_DIVERSITY)
> - return current_ant;
> - return (default_ant != ANTENNA_SW_DIVERSITY) ? default_ant : ANTENNA_B;
> -}
> -
> void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
> struct antenna_setup config)
> {
> @@ -126,19 +117,35 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
> struct antenna_setup *active = &rt2x00dev->link.ant.active;
>
> /*
> - * Failsafe: Make sure we are not sending the
> - * ANTENNA_SW_DIVERSITY state to the driver.
> - * If that happens, fallback to hardware defaults,
> - * or our own default.
> + * When the caller tries to send the SW diversity,
> + * we must update the ANTENNA_RX_DIVERSITY flag to
> + * enable the antenna diversity in the link tuner.
> + *
> + * Secondly, we must guarentee we never send the
> + * software antenna diversity command to the driver.
> */
> - if (!(ant->flags & ANTENNA_RX_DIVERSITY))
> - config.rx = rt2x00lib_config_antenna_check(config.rx, def->rx);
> - else if (config.rx == ANTENNA_SW_DIVERSITY)
> + if (!(ant->flags & ANTENNA_RX_DIVERSITY)) {
> + if (config.rx == ANTENNA_SW_DIVERSITY) {
> + ant->flags |= ANTENNA_RX_DIVERSITY;
> +
> + if (def->rx == ANTENNA_SW_DIVERSITY)
> + config.rx = ANTENNA_B;
> + else
> + config.rx = def->rx;
> + }
> + } else if (config.rx == ANTENNA_SW_DIVERSITY)
> config.rx = active->rx;
>
> - if (!(ant->flags & ANTENNA_TX_DIVERSITY))
> - config.tx = rt2x00lib_config_antenna_check(config.tx, def->tx);
> - else if (config.tx == ANTENNA_SW_DIVERSITY)
> + if (!(ant->flags & ANTENNA_TX_DIVERSITY)) {
> + if (config.tx == ANTENNA_SW_DIVERSITY) {
> + ant->flags |= ANTENNA_TX_DIVERSITY;
> +
> + if (def->tx == ANTENNA_SW_DIVERSITY)
> + config.tx = ANTENNA_B;
> + else
> + config.tx = def->tx;
> + }
> + } else if (config.tx == ANTENNA_SW_DIVERSITY)
> config.tx = active->tx;
>
> /*
> diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
> index ba0bb76..fa55399 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00link.c
> +++ b/drivers/net/wireless/rt2x00/rt2x00link.c
> @@ -192,17 +192,7 @@ static bool rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev)
> /*
> * Determine if software diversity is enabled for
> * either the TX or RX antenna (or both).
> - * Always perform this check since within the link
> - * tuner interval the configuration might have changed.
> */
> - ant->flags &= ~ANTENNA_RX_DIVERSITY;
> - ant->flags &= ~ANTENNA_TX_DIVERSITY;
> -
> - if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
> - ant->flags |= ANTENNA_RX_DIVERSITY;
> - if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
> - ant->flags |= ANTENNA_TX_DIVERSITY;
> -
> if (!(ant->flags & ANTENNA_RX_DIVERSITY) &&
> !(ant->flags & ANTENNA_TX_DIVERSITY)) {
> ant->flags = 0;
> diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
> index 6d1d383..93bec14 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00mac.c
> +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
> @@ -738,6 +738,71 @@ void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop)
> }
> EXPORT_SYMBOL_GPL(rt2x00mac_flush);
>
> +int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
> +{
> + struct rt2x00_dev *rt2x00dev = hw->priv;
> + struct link_ant *ant = &rt2x00dev->link.ant;
> + struct antenna_setup *def = &rt2x00dev->default_ant;
> + struct antenna_setup setup;
> +
> + // The antenna value is not supposed to be 0,
> + // or exceed the maximum number of antenna's.
> + if (!tx_ant || (tx_ant & ~3) || !rx_ant || (rx_ant & ~3))
> + return -EINVAL;
> +
> + // When the client tried to configure the antenna to or from
> + // diversity mode, we must reset the default antenna as well
> + // as that controls the diversity switch.
> + if (ant->flags & ANTENNA_TX_DIVERSITY && tx_ant != 3)
> + ant->flags &= ~ANTENNA_TX_DIVERSITY;
> + if (ant->flags & ANTENNA_RX_DIVERSITY && rx_ant != 3)
> + ant->flags &= ~ANTENNA_RX_DIVERSITY;
> +
> + // If diversity is being enabled, check if we need hardware
> + // or software diversity. In the latter case, reset the value,
> + // and make sure we update the antenna flags to have the
> + // link tuner pick up the diversity tuning.
> + if (tx_ant == 3 && def->tx == ANTENNA_SW_DIVERSITY) {
> + tx_ant = ANTENNA_SW_DIVERSITY;
> + ant->flags |= ANTENNA_TX_DIVERSITY;
> + }
> +
> + if (rx_ant == 3 && def->rx == ANTENNA_SW_DIVERSITY) {
> + rx_ant = ANTENNA_SW_DIVERSITY;
> + ant->flags |= ANTENNA_RX_DIVERSITY;
> + }
> +
> + setup.tx = tx_ant;
> + setup.rx = rx_ant;
> +
> + rt2x00lib_config_antenna(rt2x00dev, setup);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(rt2x00mac_set_antenna);
> +
> +int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
> +{
> + struct rt2x00_dev *rt2x00dev = hw->priv;
> + struct link_ant *ant = &rt2x00dev->link.ant;
> + struct antenna_setup *active = &rt2x00dev->link.ant.active;
> +
> + // When software diversity is active, we must report this to the
> + // client and not the current active antenna state.
> + if (ant->flags & ANTENNA_TX_DIVERSITY)
> + *tx_ant = ANTENNA_HW_DIVERSITY;
> + else
> + *tx_ant = active->tx;
> +
> + if (ant->flags & ANTENNA_RX_DIVERSITY)
> + *rx_ant = ANTENNA_HW_DIVERSITY;
> + else
> + *rx_ant = active->rx;
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(rt2x00mac_get_antenna);
> +
> void rt2x00mac_get_ringparam(struct ieee80211_hw *hw,
> u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
> {
> diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
> index eb54031..9d35ec1 100644
> --- a/drivers/net/wireless/rt2x00/rt61pci.c
> +++ b/drivers/net/wireless/rt2x00/rt61pci.c
> @@ -2979,6 +2979,8 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
> .get_tsf = rt61pci_get_tsf,
> .rfkill_poll = rt2x00mac_rfkill_poll,
> .flush = rt2x00mac_flush,
> + .set_antenna = rt2x00mac_set_antenna,
> + .get_antenna = rt2x00mac_get_antenna,
> .get_ringparam = rt2x00mac_get_ringparam,
> };
>
> diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
> index 3aa7785..f69e871 100644
> --- a/drivers/net/wireless/rt2x00/rt73usb.c
> +++ b/drivers/net/wireless/rt2x00/rt73usb.c
> @@ -2310,6 +2310,8 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
> .get_tsf = rt73usb_get_tsf,
> .rfkill_poll = rt2x00mac_rfkill_poll,
> .flush = rt2x00mac_flush,
> + .set_antenna = rt2x00mac_set_antenna,
> + .get_antenna = rt2x00mac_get_antenna,
> .get_ringparam = rt2x00mac_get_ringparam,
> };
>
>
> _______________________________________________
> users mailing list
> users at rt2x00.serialmonkey.com
> http://rt2x00.serialmonkey.com/mailman/listinfo/users_rt2x00.serialmonkey.com
More information about the users
mailing list