Commit a8fff50e authored by Jouni Malinen's avatar Jouni Malinen Committed by John W. Linville

ath9k: Updated Beacon generation to use mac80211-style

This change moves ath9k to use mac80211-generated Beacon frames instead
of trying to allocate a single Beacon frame and then update it. In
addition, the remaining ath_skb_{map,unmap}_single() wrapper calls are
replaced with direct pci_{map,unmap}_single() calls in beacon.c. Power
save buffering for multicast/broadcast frames is not yet converted to
use mac80211-style (frames to be buffered inside mac80211, not in
driver).
Signed-off-by: default avatarJouni Malinen <jouni.malinen@atheros.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 2ad67de3
...@@ -172,6 +172,7 @@ static void empty_mcastq_into_cabq(struct ath_hal *ah, ...@@ -172,6 +172,7 @@ static void empty_mcastq_into_cabq(struct ath_hal *ah,
mcastq->axq_link = NULL; mcastq->axq_link = NULL;
} }
/* TODO: use ieee80211_get_buffered_bc() to fetch power saved mcast frames */
/* This is only run at DTIM. We move everything from the vap's mcast queue /* This is only run at DTIM. We move everything from the vap's mcast queue
* to the hardware cab queue. Caller must hold the mcastq lock. */ * to the hardware cab queue. Caller must hold the mcastq lock. */
static void trigger_mcastq(struct ath_hal *ah, static void trigger_mcastq(struct ath_hal *ah,
...@@ -206,7 +207,6 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) ...@@ -206,7 +207,6 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
int cabq_depth; int cabq_depth;
int mcastq_depth; int mcastq_depth;
int is_beacon_dtim = 0; int is_beacon_dtim = 0;
unsigned int curlen;
struct ath_txq *cabq; struct ath_txq *cabq;
struct ath_txq *mcastq; struct ath_txq *mcastq;
avp = sc->sc_vaps[if_id]; avp = sc->sc_vaps[if_id];
...@@ -223,33 +223,27 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) ...@@ -223,33 +223,27 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
} }
bf = avp->av_bcbuf; bf = avp->av_bcbuf;
skb = (struct sk_buff *) bf->bf_mpdu; skb = (struct sk_buff *) bf->bf_mpdu;
if (skb) {
pci_unmap_single(sc->pdev, bf->bf_dmacontext,
skb_end_pointer(skb) - skb->head,
PCI_DMA_TODEVICE);
}
/* skb = ieee80211_beacon_get(sc->hw, avp->av_if_data);
* Update dynamic beacon contents. If this returns bf->bf_mpdu = skb;
* non-zero then we need to remap the memory because if (skb == NULL)
* the beacon frame changed size (probably because return NULL;
* of the TIM bitmap). bf->bf_buf_addr = bf->bf_dmacontext =
*/ pci_map_single(sc->pdev, skb->data,
curlen = skb->len; skb_end_pointer(skb) - skb->head,
PCI_DMA_TODEVICE);
/* TODO: convert to use ieee80211_get_buffered_bc() */
/* XXX: spin_lock_bh should not be used here, but sparse bitches /* XXX: spin_lock_bh should not be used here, but sparse bitches
* otherwise. We should fix sparse :) */ * otherwise. We should fix sparse :) */
spin_lock_bh(&mcastq->axq_lock); spin_lock_bh(&mcastq->axq_lock);
mcastq_depth = avp->av_mcastq.axq_depth; mcastq_depth = avp->av_mcastq.axq_depth;
if (ath_update_beacon(sc, if_id, &avp->av_boff, skb, mcastq_depth) ==
1) {
ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE,
get_dma_mem_context(bf, bf_dmacontext));
bf->bf_buf_addr = ath_skb_map_single(sc, skb, PCI_DMA_TODEVICE,
get_dma_mem_context(bf, bf_dmacontext));
} else {
pci_dma_sync_single_for_cpu(sc->pdev,
bf->bf_buf_addr,
skb_tailroom(skb),
PCI_DMA_TODEVICE);
}
/* /*
* if the CABQ traffic from previous DTIM is pending and the current * if the CABQ traffic from previous DTIM is pending and the current
* beacon is also a DTIM. * beacon is also a DTIM.
...@@ -262,6 +256,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) ...@@ -262,6 +256,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
cabq_depth = cabq->axq_depth; cabq_depth = cabq->axq_depth;
spin_unlock_bh(&cabq->axq_lock); spin_unlock_bh(&cabq->axq_lock);
if (avp->av_boff.bo_tim)
is_beacon_dtim = avp->av_boff.bo_tim[4] & 1; is_beacon_dtim = avp->av_boff.bo_tim[4] & 1;
if (mcastq_depth && is_beacon_dtim && cabq_depth) { if (mcastq_depth && is_beacon_dtim && cabq_depth) {
...@@ -408,8 +403,9 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) ...@@ -408,8 +403,9 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
bf = avp->av_bcbuf; bf = avp->av_bcbuf;
if (bf->bf_mpdu != NULL) { if (bf->bf_mpdu != NULL) {
skb = (struct sk_buff *)bf->bf_mpdu; skb = (struct sk_buff *)bf->bf_mpdu;
ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE, pci_unmap_single(sc->pdev, bf->bf_dmacontext,
get_dma_mem_context(bf, bf_dmacontext)); skb_end_pointer(skb) - skb->head,
PCI_DMA_TODEVICE);
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL; bf->bf_mpdu = NULL;
} }
...@@ -439,9 +435,8 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) ...@@ -439,9 +435,8 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
__le64 val; __le64 val;
int intval; int intval;
/* FIXME: Use default value for now: Sujith */ intval = sc->hw->conf.beacon_int ?
sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
intval = ATH_DEFAULT_BINTVAL;
/* /*
* The beacon interval is in TU's; the TSF in usecs. * The beacon interval is in TU's; the TSF in usecs.
...@@ -466,8 +461,10 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) ...@@ -466,8 +461,10 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
memcpy(&wh[1], &val, sizeof(val)); memcpy(&wh[1], &val, sizeof(val));
} }
bf->bf_buf_addr = ath_skb_map_single(sc, skb, PCI_DMA_TODEVICE, bf->bf_buf_addr = bf->bf_dmacontext =
get_dma_mem_context(bf, bf_dmacontext)); pci_map_single(sc->pdev, skb->data,
skb_end_pointer(skb) - skb->head,
PCI_DMA_TODEVICE);
bf->bf_mpdu = skb; bf->bf_mpdu = skb;
return 0; return 0;
...@@ -493,8 +490,9 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp) ...@@ -493,8 +490,9 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
bf = avp->av_bcbuf; bf = avp->av_bcbuf;
if (bf->bf_mpdu != NULL) { if (bf->bf_mpdu != NULL) {
struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu; struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE, pci_unmap_single(sc->pdev, bf->bf_dmacontext,
get_dma_mem_context(bf, bf_dmacontext)); skb_end_pointer(skb) - skb->head,
PCI_DMA_TODEVICE);
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL; bf->bf_mpdu = NULL;
} }
...@@ -520,8 +518,9 @@ void ath_beacon_free(struct ath_softc *sc) ...@@ -520,8 +518,9 @@ void ath_beacon_free(struct ath_softc *sc)
list_for_each_entry(bf, &sc->sc_bbuf, list) { list_for_each_entry(bf, &sc->sc_bbuf, list) {
if (bf->bf_mpdu != NULL) { if (bf->bf_mpdu != NULL) {
struct sk_buff *skb = (struct sk_buff *) bf->bf_mpdu; struct sk_buff *skb = (struct sk_buff *) bf->bf_mpdu;
ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE, pci_unmap_single(sc->pdev, bf->bf_dmacontext,
get_dma_mem_context(bf, bf_dmacontext)); skb_end_pointer(skb) - skb->head,
PCI_DMA_TODEVICE);
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL; bf->bf_mpdu = NULL;
} }
...@@ -643,8 +642,8 @@ void ath9k_beacon_tasklet(unsigned long data) ...@@ -643,8 +642,8 @@ void ath9k_beacon_tasklet(unsigned long data)
* on the tsf to safeguard against missing an swba. * on the tsf to safeguard against missing an swba.
*/ */
/* FIXME: Use default value for now - Sujith */ intval = sc->hw->conf.beacon_int ?
intval = ATH_DEFAULT_BINTVAL; sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
tsf = ath9k_hw_gettsf64(ah); tsf = ath9k_hw_gettsf64(ah);
tsftu = TSF_TO_TU(tsf>>32, tsf); tsftu = TSF_TO_TU(tsf>>32, tsf);
...@@ -760,7 +759,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) ...@@ -760,7 +759,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
* Protocol stack doesn't support dynamic beacon configuration, * Protocol stack doesn't support dynamic beacon configuration,
* use default configurations. * use default configurations.
*/ */
conf.beacon_interval = ATH_DEFAULT_BINTVAL; conf.beacon_interval = sc->hw->conf.beacon_int ?
sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
conf.listen_interval = 1; conf.listen_interval = 1;
conf.dtim_period = conf.beacon_interval; conf.dtim_period = conf.beacon_interval;
conf.dtim_count = 1; conf.dtim_count = 1;
......
...@@ -729,11 +729,6 @@ void ath_beacon_sync(struct ath_softc *sc, int if_id); ...@@ -729,11 +729,6 @@ void ath_beacon_sync(struct ath_softc *sc, int if_id);
void ath_get_beaconconfig(struct ath_softc *sc, void ath_get_beaconconfig(struct ath_softc *sc,
int if_id, int if_id,
struct ath_beacon_config *conf); struct ath_beacon_config *conf);
int ath_update_beacon(struct ath_softc *sc,
int if_id,
struct ath_beacon_offset *bo,
struct sk_buff *skb,
int mcast);
/********/ /********/
/* VAPs */ /* VAPs */
/********/ /********/
......
...@@ -624,6 +624,18 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, ...@@ -624,6 +624,18 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
ath_beacon_sync(sc, 0); ath_beacon_sync(sc, 0);
} }
if ((conf->changed & IEEE80211_IFCC_BEACON) &&
(vif->type == IEEE80211_IF_TYPE_AP)) {
ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq);
error = ath_beacon_alloc(sc, 0);
if (error != 0)
return error;
ath_beacon_config(sc, 0);
sc->sc_flags |= SC_OP_BEACONS;
}
/* Check for WLAN_CAPABILITY_PRIVACY ? */ /* Check for WLAN_CAPABILITY_PRIVACY ? */
if ((avp->av_opmode != IEEE80211_IF_TYPE_STA)) { if ((avp->av_opmode != IEEE80211_IF_TYPE_STA)) {
for (i = 0; i < IEEE80211_WEP_NKID; i++) for (i = 0; i < IEEE80211_WEP_NKID; i++)
...@@ -1052,15 +1064,6 @@ void ath_get_beaconconfig(struct ath_softc *sc, ...@@ -1052,15 +1064,6 @@ void ath_get_beaconconfig(struct ath_softc *sc,
conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval; conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval;
} }
int ath_update_beacon(struct ath_softc *sc,
int if_id,
struct ath_beacon_offset *bo,
struct sk_buff *skb,
int mcast)
{
return 0;
}
void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
struct ath_xmit_status *tx_status, struct ath_node *an) struct ath_xmit_status *tx_status, struct ath_node *an)
{ {
......
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