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: Jiri Slaby <[EMAIL PROTECTED]>
Cc: Nick Kossifidis <[EMAIL PROTECTED]>
Cc: Luis R. Rodriguez <[EMAIL PROTECTED]>
---
 drivers/net/wireless/ath5k/base.c |   42 +++++++++++++++----------------------
 1 files changed, 17 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/ath5k/base.c 
b/drivers/net/wireless/ath5k/base.c
index 9b95c40..72b5e47 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -238,8 +238,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,
@@ -2157,8 +2156,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)
@@ -2171,7 +2168,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
@@ -2183,13 +2181,15 @@ ath5k_beacon_config(struct ath5k_softc *sc)
 
                sc->imask |= AR5K_INT_SWBA;
 
-               if (ath5k_hw_hasveol(ah)) {
-                       spin_lock(&sc->block);
-                       ath5k_beacon_send(sc);
-                       spin_unlock(&sc->block);
-               }
+               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);
 }
@@ -2741,6 +2741,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:
@@ -2804,7 +2805,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
@@ -2812,18 +2813,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);
@@ -3055,19 +3054,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;
@@ -3080,7 +3073,6 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct 
sk_buff *skb)
                mmiowb();
        }
 
-end:
        return ret;
 }
 
-- 
1.6.0.2

_______________________________________________
ath5k-devel mailing list
ath5k-devel@lists.ath5k.org
https://lists.ath5k.org/mailman/listinfo/ath5k-devel

Reply via email to