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:
committed by
John W. Linville
parent
6f5f39c95a
commit
2bed03ebf6
@@ -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 \
|
||||
|
Reference in New Issue
Block a user