ath9k: remove VEOL support for ad-hoc

With VEOL, Beacon transmission in ad-hoc does not currently work.
I believe for larger ad-hoc networks, VEOL is too unreliable, as
it can get beacon transmissions stuck during synchronization.
Use SWBA based beacon trasmission similar to AP mode instead.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Acked-by: Benoit Papillault <benoit.papillault@free.fr>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Felix Fietkau 2010-05-13 20:37:25 +02:00 committed by John W. Linville
parent 774610e4f2
commit a65e4cb402

View File

@ -76,22 +76,13 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
ds = bf->bf_desc; ds = bf->bf_desc;
flags = ATH9K_TXDESC_NOACK; flags = ATH9K_TXDESC_NOACK;
if (((sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || ds->ds_link = 0;
(sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) && /*
(ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) { * Switch antenna every beacon.
ds->ds_link = bf->bf_daddr; /* self-linked */ * Should only switch every beacon period, not for every SWBA
flags |= ATH9K_TXDESC_VEOL; * XXX assumes two antennae
/* Let hardware handle antenna switching. */ */
antenna = 0; antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
} else {
ds->ds_link = 0;
/*
* Switch antenna every beacon.
* Should only switch every beacon period, not for every SWBA
* XXX assumes two antennae
*/
antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
}
sband = &sc->sbands[common->hw->conf.channel->band]; sband = &sc->sbands[common->hw->conf.channel->band];
rate = sband->bitrates[rateidx].hw_value; rate = sband->bitrates[rateidx].hw_value;
@ -215,36 +206,6 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
return bf; return bf;
} }
/*
* Startup beacon transmission for adhoc mode when they are sent entirely
* by the hardware using the self-linked descriptor + veol trick.
*/
static void ath_beacon_start_adhoc(struct ath_softc *sc,
struct ieee80211_vif *vif)
{
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ath_buf *bf;
struct ath_vif *avp;
struct sk_buff *skb;
avp = (void *)vif->drv_priv;
if (avp->av_bcbuf == NULL)
return;
bf = avp->av_bcbuf;
skb = bf->bf_mpdu;
ath_beacon_setup(sc, avp, bf, 0);
/* NB: caller is known to have already stopped tx dma */
ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr);
ath9k_hw_txstart(ah, sc->beacon.beaconq);
ath_print(common, ATH_DBG_BEACON, "TXDP%u = %llx (%p)\n",
sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc);
}
int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
{ {
struct ath_softc *sc = aphy->sc; struct ath_softc *sc = aphy->sc;
@ -265,7 +226,8 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
list_del(&avp->av_bcbuf->list); list_del(&avp->av_bcbuf->list);
if (sc->sc_ah->opmode == NL80211_IFTYPE_AP || if (sc->sc_ah->opmode == NL80211_IFTYPE_AP ||
!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) { sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC ||
sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) {
int slot; int slot;
/* /*
* Assign the vif to a beacon xmit slot. As * Assign the vif to a beacon xmit slot. As
@ -715,8 +677,7 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
* self-linked tx descriptor and let the hardware deal with things. * self-linked tx descriptor and let the hardware deal with things.
*/ */
intval |= ATH9K_BEACON_ENA; intval |= ATH9K_BEACON_ENA;
if (!(ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) ah->imask |= ATH9K_INT_SWBA;
ah->imask |= ATH9K_INT_SWBA;
ath_beaconq_config(sc); ath_beaconq_config(sc);
@ -726,10 +687,6 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
ath9k_beacon_init(sc, nexttbtt, intval); ath9k_beacon_init(sc, nexttbtt, intval);
sc->beacon.bmisscnt = 0; sc->beacon.bmisscnt = 0;
ath9k_hw_set_interrupts(ah, ah->imask); ath9k_hw_set_interrupts(ah, ah->imask);
/* FIXME: Handle properly when vif is NULL */
if (vif && ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)
ath_beacon_start_adhoc(sc, vif);
} }
void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)