ath5k: Implement antenna control

* Add code to support the various antenna scenarios supported by hw

 * For now hardcode the default scenario (single or dual omnis with
 tx/rx diversity working and tx antenna handled by session -hw keeps
 track on which antenna it got ack from each ap/station and maps each
 ap/station to one of the antennas-).

 Signed-off-by: Nick Kossifidis <mickflemm@gmail.com>
 Signed-off-by: Bob Copeland <me@bobcopeland.com>

Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Nick Kossifidis
2009-04-30 15:55:49 -04:00
committed by John W. Linville
parent 6f5f39c95a
commit 2bed03ebf6
8 changed files with 271 additions and 51 deletions

View File

@@ -1279,7 +1279,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
(sc->power_level * 2),
hw_rate,
info->control.rates[0].count, keyidx, 0, flags,
info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags,
cts_rate, duration);
if (ret)
goto err_unmap;
@@ -2009,7 +2009,8 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ath5k_hw *ah = sc->ah;
struct ath5k_desc *ds;
int ret, antenna = 0;
int ret = 0;
u8 antenna;
u32 flags;
bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
@@ -2023,23 +2024,35 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
}
ds = bf->desc;
antenna = ah->ah_tx_ant;
flags = AR5K_TXDESC_NOACK;
if (sc->opmode == NL80211_IFTYPE_ADHOC && ath5k_hw_hasveol(ah)) {
ds->ds_link = bf->daddr; /* self-linked */
flags |= AR5K_TXDESC_VEOL;
/*
* Let hardware handle antenna switching if txantenna is not set
*/
} else {
} else
ds->ds_link = 0;
/*
* Switch antenna every 4 beacons if txantenna is not set
* XXX assumes two antennas
*/
if (antenna == 0)
antenna = sc->bsent & 4 ? 2 : 1;
}
/*
* If we use multiple antennas on AP and use
* the Sectored AP scenario, switch antenna every
* 4 beacons to make sure everybody hears our AP.
* When a client tries to associate, hw will keep
* track of the tx antenna to be used for this client
* automaticaly, based on ACKed packets.
*
* Note: AP still listens and transmits RTS on the
* default antenna which is supposed to be an omni.
*
* Note2: On sectored scenarios it's possible to have
* multiple antennas (1omni -the default- and 14 sectors)
* so if we choose to actually support this mode we need
* to allow user to set how many antennas we have and tweak
* the code below to send beacons on all of them.
*/
if (ah->ah_ant_mode == AR5K_ANTMODE_SECTOR_AP)
antenna = sc->bsent & 4 ? 2 : 1;
/* FIXME: If we are in g mode and rate is a CCK rate
* subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta
@@ -2752,12 +2765,16 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
struct ath5k_softc *sc = hw->priv;
struct ath5k_hw *ah = sc->ah;
struct ieee80211_conf *conf = &hw->conf;
int ret;
int ret = 0;
mutex_lock(&sc->lock);
sc->bintval = conf->beacon_int;
ret = ath5k_chan_set(sc, conf->channel);
if (ret < 0)
return ret;
if ((changed & IEEE80211_CONF_CHANGE_POWER) &&
(sc->power_level != conf->power_level)) {
sc->power_level = conf->power_level;
@@ -2766,10 +2783,27 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2));
}
ret = ath5k_chan_set(sc, conf->channel);
/* TODO:
* 1) Move this on config_interface and handle each case
* separately eg. when we have only one STA vif, use
* AR5K_ANTMODE_SINGLE_AP
*
* 2) Allow the user to change antenna mode eg. when only
* one antenna is present
*
* 3) Allow the user to set default/tx antenna when possible
*
* 4) Default mode should handle 90% of the cases, together
* with fixed a/b and single AP modes we should be able to
* handle 99%. Sectored modes are extreme cases and i still
* haven't found a usage for them. If we decide to support them,
* then we must allow the user to set how many tx antennas we
* have available
*/
ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT);
mutex_unlock(&sc->lock);
return ret;
return 0;
}
#define SUPPORTED_FIF_FLAGS \