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

Commit da966bca authored by Jiri Slaby's avatar Jiri Slaby Committed by John W. Linville
Browse files

Ath5k: add AP mode



Add support for AP mode. This involves:
- enablement in ath5k_beacon_config -- initialize beacon timer
- add AP to the supported modes in ath5k_add_interface
- handle beacon change even for AP in ath5k_config_interface
- remove useless test for IBSS in ath5k_beacon_update

Note that it doesn't enable the AP mode for the driver. It must
be enabled by NL80211_IFTYPE_AP bit added to interface_modes.

v2:
Fixed opmode constant (IEEE80211_ to NL80211_)

Signed-off-by: default avatarJiri Slaby <jirislaby@gmail.com>
Cc: Nick Kossifidis <mickflemm@gmail.com>
Cc: Luis R. Rodriguez <mcgrof@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 7eb27af7
Loading
Loading
Loading
Loading
+17 −25
Original line number Diff line number Diff line
@@ -237,8 +237,7 @@ static int ath5k_get_tx_stats(struct ieee80211_hw *hw,
		struct ieee80211_tx_queue_stats *stats);
static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
static void ath5k_reset_tsf(struct ieee80211_hw *hw);
static int ath5k_beacon_update(struct ieee80211_hw *hw,
		struct sk_buff *skb);
static int ath5k_beacon_update(struct ath5k_softc *sc, struct sk_buff *skb);

static struct ieee80211_ops ath5k_hw_ops = {
	.tx 		= ath5k_tx,
@@ -2137,8 +2136,6 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
 *
 * In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA
 * interrupts to detect TSF updates only.
 *
 * AP mode is missing.
 */
static void
ath5k_beacon_config(struct ath5k_softc *sc)
@@ -2151,7 +2148,8 @@ ath5k_beacon_config(struct ath5k_softc *sc)

	if (sc->opmode == NL80211_IFTYPE_STATION) {
		sc->imask |= AR5K_INT_BMISS;
	} else if (sc->opmode == NL80211_IFTYPE_ADHOC) {
	} else if (sc->opmode == NL80211_IFTYPE_ADHOC ||
			sc->opmode == NL80211_IFTYPE_AP) {
		/*
		 * In IBSS mode we use a self-linked tx descriptor and let the
		 * hardware send the beacons automatically. We have to load it
@@ -2163,13 +2161,15 @@ ath5k_beacon_config(struct ath5k_softc *sc)

		sc->imask |= AR5K_INT_SWBA;

		if (sc->opmode == NL80211_IFTYPE_ADHOC) {
			if (ath5k_hw_hasveol(ah)) {
				spin_lock(&sc->block);
				ath5k_beacon_send(sc);
				spin_unlock(&sc->block);
			}
		} else
			ath5k_beacon_update_timers(sc, -1);
	}
	/* TODO else AP */

	ath5k_hw_set_imr(ah, sc->imask);
}
@@ -2740,6 +2740,7 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
	sc->vif = conf->vif;

	switch (conf->type) {
	case NL80211_IFTYPE_AP:
	case NL80211_IFTYPE_STATION:
	case NL80211_IFTYPE_ADHOC:
	case NL80211_IFTYPE_MONITOR:
@@ -2803,7 +2804,7 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
		ret = -EIO;
		goto unlock;
	}
	if (conf->bssid) {
	if (conf->changed & IEEE80211_IFCC_BSSID && conf->bssid) {
		/* Cache for later use during resets */
		memcpy(ah->ah_bssid, conf->bssid, ETH_ALEN);
		/* XXX: assoc id is set to 0 for now, mac80211 doesn't have
@@ -2811,18 +2812,16 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
		ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
		mmiowb();
	}

	if (conf->changed & IEEE80211_IFCC_BEACON &&
	    vif->type == NL80211_IFTYPE_ADHOC) {
			(vif->type == NL80211_IFTYPE_ADHOC ||
			 vif->type == NL80211_IFTYPE_AP)) {
		struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
		if (!beacon) {
			ret = -ENOMEM;
			goto unlock;
		}
		/* call old handler for now */
		ath5k_beacon_update(hw, beacon);
		ath5k_beacon_update(sc, beacon);
	}

	mutex_unlock(&sc->lock);

	return ath5k_reset_wake(sc);
@@ -3052,19 +3051,13 @@ ath5k_reset_tsf(struct ieee80211_hw *hw)
}

static int
ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
ath5k_beacon_update(struct ath5k_softc *sc, struct sk_buff *skb)
{
	struct ath5k_softc *sc = hw->priv;
	unsigned long flags;
	int ret;

	ath5k_debug_dump_skb(sc, skb, "BC  ", 1);

	if (sc->opmode != NL80211_IFTYPE_ADHOC) {
		ret = -EIO;
		goto end;
	}

	spin_lock_irqsave(&sc->block, flags);
	ath5k_txbuf_free(sc, sc->bbuf);
	sc->bbuf->skb = skb;
@@ -3077,7 +3070,6 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
		mmiowb();
	}

end:
	return ret;
}