Le 13/05/2010 20:37, Felix Fietkau a écrit :
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@xxxxxxxxxxx>
This is very good step toward IBSS. Thanks Felix! Acked-by: Benoit Papillault <benoit.papillault@xxxxxxx>
--- drivers/net/wireless/ath/ath9k/beacon.c | 63 +++++-------------------------- 1 files changed, 10 insertions(+), 53 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 77face7..f43d85a 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -76,22 +76,13 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, ds = bf->bf_desc; flags = ATH9K_TXDESC_NOACK; - if (((sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || - (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT))&& - (ah->caps.hw_caps& ATH9K_HW_CAP_VEOL)) { - ds->ds_link = bf->bf_daddr; /* self-linked */ - flags |= ATH9K_TXDESC_VEOL; - /* Let hardware handle antenna switching. */ - antenna = 0; - } 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); - } + 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]; rate = sband->bitrates[rateidx].hw_value; @@ -215,36 +206,6 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, 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) { 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); 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; /* * 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. */ 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); @@ -726,10 +687,6 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, ath9k_beacon_init(sc, nexttbtt, intval); sc->beacon.bmisscnt = 0; 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)
-- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html