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

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
...@@ -237,8 +237,7 @@ static int ath5k_get_tx_stats(struct ieee80211_hw *hw, ...@@ -237,8 +237,7 @@ static int ath5k_get_tx_stats(struct ieee80211_hw *hw,
struct ieee80211_tx_queue_stats *stats); struct ieee80211_tx_queue_stats *stats);
static u64 ath5k_get_tsf(struct ieee80211_hw *hw); static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
static void ath5k_reset_tsf(struct ieee80211_hw *hw); static void ath5k_reset_tsf(struct ieee80211_hw *hw);
static int ath5k_beacon_update(struct ieee80211_hw *hw, static int ath5k_beacon_update(struct ath5k_softc *sc, struct sk_buff *skb);
struct sk_buff *skb);
static struct ieee80211_ops ath5k_hw_ops = { static struct ieee80211_ops ath5k_hw_ops = {
.tx = ath5k_tx, .tx = ath5k_tx,
...@@ -2137,8 +2136,6 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) ...@@ -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 * In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA
* interrupts to detect TSF updates only. * interrupts to detect TSF updates only.
*
* AP mode is missing.
*/ */
static void static void
ath5k_beacon_config(struct ath5k_softc *sc) ath5k_beacon_config(struct ath5k_softc *sc)
...@@ -2151,7 +2148,8 @@ ath5k_beacon_config(struct ath5k_softc *sc) ...@@ -2151,7 +2148,8 @@ ath5k_beacon_config(struct ath5k_softc *sc)
if (sc->opmode == NL80211_IFTYPE_STATION) { if (sc->opmode == NL80211_IFTYPE_STATION) {
sc->imask |= AR5K_INT_BMISS; 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 * In IBSS mode we use a self-linked tx descriptor and let the
* hardware send the beacons automatically. We have to load it * hardware send the beacons automatically. We have to load it
...@@ -2163,13 +2161,15 @@ ath5k_beacon_config(struct ath5k_softc *sc) ...@@ -2163,13 +2161,15 @@ ath5k_beacon_config(struct ath5k_softc *sc)
sc->imask |= AR5K_INT_SWBA; sc->imask |= AR5K_INT_SWBA;
if (ath5k_hw_hasveol(ah)) { if (sc->opmode == NL80211_IFTYPE_ADHOC) {
spin_lock(&sc->block); if (ath5k_hw_hasveol(ah)) {
ath5k_beacon_send(sc); spin_lock(&sc->block);
spin_unlock(&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); ath5k_hw_set_imr(ah, sc->imask);
} }
...@@ -2740,6 +2740,7 @@ static int ath5k_add_interface(struct ieee80211_hw *hw, ...@@ -2740,6 +2740,7 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
sc->vif = conf->vif; sc->vif = conf->vif;
switch (conf->type) { switch (conf->type) {
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_MONITOR:
...@@ -2803,7 +2804,7 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ...@@ -2803,7 +2804,7 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
ret = -EIO; ret = -EIO;
goto unlock; goto unlock;
} }
if (conf->bssid) { if (conf->changed & IEEE80211_IFCC_BSSID && conf->bssid) {
/* Cache for later use during resets */ /* Cache for later use during resets */
memcpy(ah->ah_bssid, conf->bssid, ETH_ALEN); memcpy(ah->ah_bssid, conf->bssid, ETH_ALEN);
/* XXX: assoc id is set to 0 for now, mac80211 doesn't have /* 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, ...@@ -2811,18 +2812,16 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
ath5k_hw_set_associd(ah, ah->ah_bssid, 0); ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
mmiowb(); mmiowb();
} }
if (conf->changed & IEEE80211_IFCC_BEACON && 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); struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
if (!beacon) { if (!beacon) {
ret = -ENOMEM; ret = -ENOMEM;
goto unlock; goto unlock;
} }
/* call old handler for now */ ath5k_beacon_update(sc, beacon);
ath5k_beacon_update(hw, beacon);
} }
mutex_unlock(&sc->lock); mutex_unlock(&sc->lock);
return ath5k_reset_wake(sc); return ath5k_reset_wake(sc);
...@@ -3052,19 +3051,13 @@ ath5k_reset_tsf(struct ieee80211_hw *hw) ...@@ -3052,19 +3051,13 @@ ath5k_reset_tsf(struct ieee80211_hw *hw)
} }
static int 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; unsigned long flags;
int ret; int ret;
ath5k_debug_dump_skb(sc, skb, "BC ", 1); ath5k_debug_dump_skb(sc, skb, "BC ", 1);
if (sc->opmode != NL80211_IFTYPE_ADHOC) {
ret = -EIO;
goto end;
}
spin_lock_irqsave(&sc->block, flags); spin_lock_irqsave(&sc->block, flags);
ath5k_txbuf_free(sc, sc->bbuf); ath5k_txbuf_free(sc, sc->bbuf);
sc->bbuf->skb = skb; sc->bbuf->skb = skb;
...@@ -3077,7 +3070,6 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -3077,7 +3070,6 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
mmiowb(); mmiowb();
} }
end:
return ret; return ret;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment