aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath5k
diff options
context:
space:
mode:
authorJiri Slaby <jirislaby@gmail.com>2008-10-12 16:54:10 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-10-31 19:00:17 -0400
commitda966bcae70e4012b7d999820b728dd6502047e0 (patch)
treeb746632bc1d67d9cd68e81efd30874669888889d /drivers/net/wireless/ath5k
parent7eb27af766e4a1db3dbc02a5b3d175885bf2ce93 (diff)
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: Jiri Slaby <jirislaby@gmail.com> Cc: Nick Kossifidis <mickflemm@gmail.com> Cc: Luis R. Rodriguez <mcgrof@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath5k')
-rw-r--r--drivers/net/wireless/ath5k/base.c42
1 files changed, 17 insertions, 25 deletions
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index fcd688765d04..c98380845fa7 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -237,8 +237,7 @@ static int ath5k_get_tx_stats(struct ieee80211_hw *hw,
237 struct ieee80211_tx_queue_stats *stats); 237 struct ieee80211_tx_queue_stats *stats);
238static u64 ath5k_get_tsf(struct ieee80211_hw *hw); 238static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
239static void ath5k_reset_tsf(struct ieee80211_hw *hw); 239static void ath5k_reset_tsf(struct ieee80211_hw *hw);
240static int ath5k_beacon_update(struct ieee80211_hw *hw, 240static int ath5k_beacon_update(struct ath5k_softc *sc, struct sk_buff *skb);
241 struct sk_buff *skb);
242 241
243static struct ieee80211_ops ath5k_hw_ops = { 242static struct ieee80211_ops ath5k_hw_ops = {
244 .tx = ath5k_tx, 243 .tx = ath5k_tx,
@@ -2137,8 +2136,6 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
2137 * 2136 *
2138 * In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA 2137 * In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA
2139 * interrupts to detect TSF updates only. 2138 * interrupts to detect TSF updates only.
2140 *
2141 * AP mode is missing.
2142 */ 2139 */
2143static void 2140static void
2144ath5k_beacon_config(struct ath5k_softc *sc) 2141ath5k_beacon_config(struct ath5k_softc *sc)
@@ -2151,7 +2148,8 @@ ath5k_beacon_config(struct ath5k_softc *sc)
2151 2148
2152 if (sc->opmode == NL80211_IFTYPE_STATION) { 2149 if (sc->opmode == NL80211_IFTYPE_STATION) {
2153 sc->imask |= AR5K_INT_BMISS; 2150 sc->imask |= AR5K_INT_BMISS;
2154 } else if (sc->opmode == NL80211_IFTYPE_ADHOC) { 2151 } else if (sc->opmode == NL80211_IFTYPE_ADHOC ||
2152 sc->opmode == NL80211_IFTYPE_AP) {
2155 /* 2153 /*
2156 * In IBSS mode we use a self-linked tx descriptor and let the 2154 * In IBSS mode we use a self-linked tx descriptor and let the
2157 * hardware send the beacons automatically. We have to load it 2155 * hardware send the beacons automatically. We have to load it
@@ -2163,13 +2161,15 @@ ath5k_beacon_config(struct ath5k_softc *sc)
2163 2161
2164 sc->imask |= AR5K_INT_SWBA; 2162 sc->imask |= AR5K_INT_SWBA;
2165 2163
2166 if (ath5k_hw_hasveol(ah)) { 2164 if (sc->opmode == NL80211_IFTYPE_ADHOC) {
2167 spin_lock(&sc->block); 2165 if (ath5k_hw_hasveol(ah)) {
2168 ath5k_beacon_send(sc); 2166 spin_lock(&sc->block);
2169 spin_unlock(&sc->block); 2167 ath5k_beacon_send(sc);
2170 } 2168 spin_unlock(&sc->block);
2169 }
2170 } else
2171 ath5k_beacon_update_timers(sc, -1);
2171 } 2172 }
2172 /* TODO else AP */
2173 2173
2174 ath5k_hw_set_imr(ah, sc->imask); 2174 ath5k_hw_set_imr(ah, sc->imask);
2175} 2175}
@@ -2740,6 +2740,7 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
2740 sc->vif = conf->vif; 2740 sc->vif = conf->vif;
2741 2741
2742 switch (conf->type) { 2742 switch (conf->type) {
2743 case NL80211_IFTYPE_AP:
2743 case NL80211_IFTYPE_STATION: 2744 case NL80211_IFTYPE_STATION:
2744 case NL80211_IFTYPE_ADHOC: 2745 case NL80211_IFTYPE_ADHOC:
2745 case NL80211_IFTYPE_MONITOR: 2746 case NL80211_IFTYPE_MONITOR:
@@ -2803,7 +2804,7 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2803 ret = -EIO; 2804 ret = -EIO;
2804 goto unlock; 2805 goto unlock;
2805 } 2806 }
2806 if (conf->bssid) { 2807 if (conf->changed & IEEE80211_IFCC_BSSID && conf->bssid) {
2807 /* Cache for later use during resets */ 2808 /* Cache for later use during resets */
2808 memcpy(ah->ah_bssid, conf->bssid, ETH_ALEN); 2809 memcpy(ah->ah_bssid, conf->bssid, ETH_ALEN);
2809 /* XXX: assoc id is set to 0 for now, mac80211 doesn't have 2810 /* 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 ath5k_hw_set_associd(ah, ah->ah_bssid, 0); 2812 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
2812 mmiowb(); 2813 mmiowb();
2813 } 2814 }
2814
2815 if (conf->changed & IEEE80211_IFCC_BEACON && 2815 if (conf->changed & IEEE80211_IFCC_BEACON &&
2816 vif->type == NL80211_IFTYPE_ADHOC) { 2816 (vif->type == NL80211_IFTYPE_ADHOC ||
2817 vif->type == NL80211_IFTYPE_AP)) {
2817 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); 2818 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
2818 if (!beacon) { 2819 if (!beacon) {
2819 ret = -ENOMEM; 2820 ret = -ENOMEM;
2820 goto unlock; 2821 goto unlock;
2821 } 2822 }
2822 /* call old handler for now */ 2823 ath5k_beacon_update(sc, beacon);
2823 ath5k_beacon_update(hw, beacon);
2824 } 2824 }
2825
2826 mutex_unlock(&sc->lock); 2825 mutex_unlock(&sc->lock);
2827 2826
2828 return ath5k_reset_wake(sc); 2827 return ath5k_reset_wake(sc);
@@ -3052,19 +3051,13 @@ ath5k_reset_tsf(struct ieee80211_hw *hw)
3052} 3051}
3053 3052
3054static int 3053static int
3055ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) 3054ath5k_beacon_update(struct ath5k_softc *sc, struct sk_buff *skb)
3056{ 3055{
3057 struct ath5k_softc *sc = hw->priv;
3058 unsigned long flags; 3056 unsigned long flags;
3059 int ret; 3057 int ret;
3060 3058
3061 ath5k_debug_dump_skb(sc, skb, "BC ", 1); 3059 ath5k_debug_dump_skb(sc, skb, "BC ", 1);
3062 3060
3063 if (sc->opmode != NL80211_IFTYPE_ADHOC) {
3064 ret = -EIO;
3065 goto end;
3066 }
3067
3068 spin_lock_irqsave(&sc->block, flags); 3061 spin_lock_irqsave(&sc->block, flags);
3069 ath5k_txbuf_free(sc, sc->bbuf); 3062 ath5k_txbuf_free(sc, sc->bbuf);
3070 sc->bbuf->skb = skb; 3063 sc->bbuf->skb = skb;
@@ -3077,7 +3070,6 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
3077 mmiowb(); 3070 mmiowb();
3078 } 3071 }
3079 3072
3080end:
3081 return ret; 3073 return ret;
3082} 3074}
3083 3075