diff options
author | Felix Fietkau <nbd@openwrt.org> | 2010-05-13 14:37:25 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-05-25 11:12:54 -0400 |
commit | a65e4cb402b5f3e120570ba1faca4354d47e8f2f (patch) | |
tree | c72b125a4fa9095ff05ffd1cdcb66e5af183ec80 /drivers | |
parent | 774610e4f26cb3d9da14a8b5974324c9e51017bd (diff) |
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: Felix Fietkau <nbd@openwrt.org>
Acked-by: Benoit Papillault <benoit.papillault@free.fr>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/beacon.c | 63 |
1 files changed, 10 insertions, 53 deletions
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 77face76e05f..f43d85a302c4 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -76,22 +76,13 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, | |||
76 | ds = bf->bf_desc; | 76 | ds = bf->bf_desc; |
77 | flags = ATH9K_TXDESC_NOACK; | 77 | flags = ATH9K_TXDESC_NOACK; |
78 | 78 | ||
79 | if (((sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || | 79 | ds->ds_link = 0; |
80 | (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) && | 80 | /* |
81 | (ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) { | 81 | * Switch antenna every beacon. |
82 | ds->ds_link = bf->bf_daddr; /* self-linked */ | 82 | * Should only switch every beacon period, not for every SWBA |
83 | flags |= ATH9K_TXDESC_VEOL; | 83 | * XXX assumes two antennae |
84 | /* Let hardware handle antenna switching. */ | 84 | */ |
85 | antenna = 0; | 85 | antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1); |
86 | } else { | ||
87 | ds->ds_link = 0; | ||
88 | /* | ||
89 | * Switch antenna every beacon. | ||
90 | * Should only switch every beacon period, not for every SWBA | ||
91 | * XXX assumes two antennae | ||
92 | */ | ||
93 | antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1); | ||
94 | } | ||
95 | 86 | ||
96 | sband = &sc->sbands[common->hw->conf.channel->band]; | 87 | sband = &sc->sbands[common->hw->conf.channel->band]; |
97 | rate = sband->bitrates[rateidx].hw_value; | 88 | rate = sband->bitrates[rateidx].hw_value; |
@@ -215,36 +206,6 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, | |||
215 | return bf; | 206 | return bf; |
216 | } | 207 | } |
217 | 208 | ||
218 | /* | ||
219 | * Startup beacon transmission for adhoc mode when they are sent entirely | ||
220 | * by the hardware using the self-linked descriptor + veol trick. | ||
221 | */ | ||
222 | static void ath_beacon_start_adhoc(struct ath_softc *sc, | ||
223 | struct ieee80211_vif *vif) | ||
224 | { | ||
225 | struct ath_hw *ah = sc->sc_ah; | ||
226 | struct ath_common *common = ath9k_hw_common(ah); | ||
227 | struct ath_buf *bf; | ||
228 | struct ath_vif *avp; | ||
229 | struct sk_buff *skb; | ||
230 | |||
231 | avp = (void *)vif->drv_priv; | ||
232 | |||
233 | if (avp->av_bcbuf == NULL) | ||
234 | return; | ||
235 | |||
236 | bf = avp->av_bcbuf; | ||
237 | skb = bf->bf_mpdu; | ||
238 | |||
239 | ath_beacon_setup(sc, avp, bf, 0); | ||
240 | |||
241 | /* NB: caller is known to have already stopped tx dma */ | ||
242 | ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr); | ||
243 | ath9k_hw_txstart(ah, sc->beacon.beaconq); | ||
244 | ath_print(common, ATH_DBG_BEACON, "TXDP%u = %llx (%p)\n", | ||
245 | sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc); | ||
246 | } | ||
247 | |||
248 | int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) | 209 | int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) |
249 | { | 210 | { |
250 | struct ath_softc *sc = aphy->sc; | 211 | struct ath_softc *sc = aphy->sc; |
@@ -265,7 +226,8 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) | |||
265 | list_del(&avp->av_bcbuf->list); | 226 | list_del(&avp->av_bcbuf->list); |
266 | 227 | ||
267 | if (sc->sc_ah->opmode == NL80211_IFTYPE_AP || | 228 | if (sc->sc_ah->opmode == NL80211_IFTYPE_AP || |
268 | !(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) { | 229 | sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC || |
230 | sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) { | ||
269 | int slot; | 231 | int slot; |
270 | /* | 232 | /* |
271 | * Assign the vif to a beacon xmit slot. As | 233 | * Assign the vif to a beacon xmit slot. As |
@@ -715,8 +677,7 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, | |||
715 | * self-linked tx descriptor and let the hardware deal with things. | 677 | * self-linked tx descriptor and let the hardware deal with things. |
716 | */ | 678 | */ |
717 | intval |= ATH9K_BEACON_ENA; | 679 | intval |= ATH9K_BEACON_ENA; |
718 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) | 680 | ah->imask |= ATH9K_INT_SWBA; |
719 | ah->imask |= ATH9K_INT_SWBA; | ||
720 | 681 | ||
721 | ath_beaconq_config(sc); | 682 | ath_beaconq_config(sc); |
722 | 683 | ||
@@ -726,10 +687,6 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, | |||
726 | ath9k_beacon_init(sc, nexttbtt, intval); | 687 | ath9k_beacon_init(sc, nexttbtt, intval); |
727 | sc->beacon.bmisscnt = 0; | 688 | sc->beacon.bmisscnt = 0; |
728 | ath9k_hw_set_interrupts(ah, ah->imask); | 689 | ath9k_hw_set_interrupts(ah, ah->imask); |
729 | |||
730 | /* FIXME: Handle properly when vif is NULL */ | ||
731 | if (vif && ah->caps.hw_caps & ATH9K_HW_CAP_VEOL) | ||
732 | ath_beacon_start_adhoc(sc, vif); | ||
733 | } | 690 | } |
734 | 691 | ||
735 | void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) | 692 | void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) |