Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a65e4cb4 authored by Felix Fietkau's avatar Felix Fietkau Committed by John W. Linville
Browse files

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: default avatarFelix Fietkau <nbd@openwrt.org>
Acked-by: default avatarBenoit Papillault <benoit.papillault@free.fr>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 774610e4
Loading
Loading
Loading
Loading
+10 −53
Original line number Diff line number Diff line
@@ -76,14 +76,6 @@ 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.
@@ -91,7 +83,6 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
	 * 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,7 +677,6 @@ 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;

	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)