Begin tidying up the reassociation and node sleep/wakeup paths.
* Move the node sleep/wake state under the TX lock rather than the node lock. Let's leave the node lock protecting rate control only for now. * When reassociating, various state needs to be cleared. For example, the aggregate session needs to be torn down, including any pending aggregation negotiation and BAR TX waiting. * .. and we need to do a "cleanup" pass since frames in the hardware TX queue need to be transmitted. Modify ath_tx_tid_cleanup() to be called with the TX lock held and push frames into a completion list. This allows for the cleanup to be done atomically for all TIDs in a node rather than grabbing and releasing the TX lock each time.
This commit is contained in:
parent
99aa6ad820
commit
4bd9be4c73
@ -3845,8 +3845,11 @@ ath_tx_default_comp(struct ath_softc *sc, struct ath_buf *bf, int fail)
|
||||
* XXX TODO: during drain, ensure that the callback is
|
||||
* being called so we get a chance to update the TIM.
|
||||
*/
|
||||
if (bf->bf_node)
|
||||
if (bf->bf_node) {
|
||||
ATH_TX_LOCK(sc);
|
||||
ath_tx_update_tim(sc, bf->bf_node, 0);
|
||||
ATH_TX_UNLOCK(sc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do any tx complete callback. Note this must
|
||||
@ -5380,6 +5383,31 @@ ath_newassoc(struct ieee80211_node *ni, int isnew)
|
||||
(vap->iv_flags & IEEE80211_F_PRIVACY) == 0 && sc->sc_hasclrkey &&
|
||||
ni->ni_ucastkey.wk_keyix == IEEE80211_KEYIX_NONE)
|
||||
ath_setup_stationkey(ni);
|
||||
|
||||
/*
|
||||
* If we're reassociating, make sure that any paused queues
|
||||
* get unpaused.
|
||||
*
|
||||
* Now, we may hvae frames in the hardware queue for this node.
|
||||
* So if we are reassociating and there are frames in the queue,
|
||||
* we need to go through the cleanup path to ensure that they're
|
||||
* marked as non-aggregate.
|
||||
*/
|
||||
if (! isnew) {
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: %6D: reassoc; is_powersave=%d\n",
|
||||
__func__,
|
||||
ni->ni_macaddr,
|
||||
":",
|
||||
an->an_is_powersave);
|
||||
|
||||
/* XXX for now, we can't hold the lock across assoc */
|
||||
ath_tx_node_reassoc(sc, an);
|
||||
|
||||
/* XXX for now, we can't hold the lock across wakeup */
|
||||
if (an->an_is_powersave)
|
||||
ath_tx_node_wakeup(sc, an);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
@ -5959,12 +5987,7 @@ ath_node_set_tim(struct ieee80211_node *ni, int enable)
|
||||
struct ath_vap *avp = ATH_VAP(ni->ni_vap);
|
||||
int changed = 0;
|
||||
|
||||
ATH_NODE_UNLOCK_ASSERT(an);
|
||||
|
||||
/*
|
||||
* For now, just track and then update the TIM.
|
||||
*/
|
||||
ATH_NODE_LOCK(an);
|
||||
ATH_TX_LOCK(sc);
|
||||
an->an_stack_psq = enable;
|
||||
|
||||
/*
|
||||
@ -5975,7 +5998,7 @@ ath_node_set_tim(struct ieee80211_node *ni, int enable)
|
||||
* and AP/IBSS node power save.
|
||||
*/
|
||||
if (avp->av_set_tim == NULL) {
|
||||
ATH_NODE_UNLOCK(an);
|
||||
ATH_TX_UNLOCK(sc);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -5997,13 +6020,13 @@ ath_node_set_tim(struct ieee80211_node *ni, int enable)
|
||||
DPRINTF(sc, ATH_DEBUG_NODE_PWRSAVE,
|
||||
"%s: an=%p, enable=%d, tim_set=1, ignoring\n",
|
||||
__func__, an, enable);
|
||||
ATH_NODE_UNLOCK(an);
|
||||
ATH_TX_UNLOCK(sc);
|
||||
} else if (enable) {
|
||||
DPRINTF(sc, ATH_DEBUG_NODE_PWRSAVE,
|
||||
"%s: an=%p, enable=%d, enabling TIM\n",
|
||||
__func__, an, enable);
|
||||
an->an_tim_set = 1;
|
||||
ATH_NODE_UNLOCK(an);
|
||||
ATH_TX_UNLOCK(sc);
|
||||
changed = avp->av_set_tim(ni, enable);
|
||||
} else if (atomic_load_acq_int(&an->an_swq_depth) == 0) {
|
||||
/* disable */
|
||||
@ -6011,7 +6034,7 @@ ath_node_set_tim(struct ieee80211_node *ni, int enable)
|
||||
"%s: an=%p, enable=%d, an_swq_depth == 0, disabling\n",
|
||||
__func__, an, enable);
|
||||
an->an_tim_set = 0;
|
||||
ATH_NODE_UNLOCK(an);
|
||||
ATH_TX_UNLOCK(sc);
|
||||
changed = avp->av_set_tim(ni, enable);
|
||||
} else if (! an->an_is_powersave) {
|
||||
/*
|
||||
@ -6021,7 +6044,7 @@ ath_node_set_tim(struct ieee80211_node *ni, int enable)
|
||||
"%s: an=%p, enable=%d, an_pwrsave=0, disabling\n",
|
||||
__func__, an, enable);
|
||||
an->an_tim_set = 0;
|
||||
ATH_NODE_UNLOCK(an);
|
||||
ATH_TX_UNLOCK(sc);
|
||||
changed = avp->av_set_tim(ni, enable);
|
||||
} else {
|
||||
/*
|
||||
@ -6029,7 +6052,7 @@ ath_node_set_tim(struct ieee80211_node *ni, int enable)
|
||||
* software queue isn't empty, so don't clear the TIM bit
|
||||
* for now.
|
||||
*/
|
||||
ATH_NODE_UNLOCK(an);
|
||||
ATH_TX_UNLOCK(sc);
|
||||
DPRINTF(sc, ATH_DEBUG_NODE_PWRSAVE,
|
||||
"%s: enable=%d, an_swq_depth > 0, ignoring\n",
|
||||
__func__, enable);
|
||||
@ -6094,7 +6117,7 @@ ath_tx_update_tim(struct ath_softc *sc, struct ieee80211_node *ni,
|
||||
if (avp->av_set_tim == NULL)
|
||||
return;
|
||||
|
||||
ATH_NODE_UNLOCK_ASSERT(an);
|
||||
ATH_TX_LOCK_ASSERT(sc);
|
||||
|
||||
if (enable) {
|
||||
/*
|
||||
@ -6104,7 +6127,6 @@ ath_tx_update_tim(struct ath_softc *sc, struct ieee80211_node *ni,
|
||||
if (atomic_load_acq_int(&an->an_swq_depth) == 0)
|
||||
return;
|
||||
|
||||
ATH_NODE_LOCK(an);
|
||||
if (an->an_is_powersave &&
|
||||
an->an_tim_set == 0 &&
|
||||
atomic_load_acq_int(&an->an_swq_depth) != 0) {
|
||||
@ -6112,10 +6134,7 @@ ath_tx_update_tim(struct ath_softc *sc, struct ieee80211_node *ni,
|
||||
"%s: an=%p, swq_depth>0, tim_set=0, set!\n",
|
||||
__func__, an);
|
||||
an->an_tim_set = 1;
|
||||
ATH_NODE_UNLOCK(an);
|
||||
(void) avp->av_set_tim(ni, 1);
|
||||
} else {
|
||||
ATH_NODE_UNLOCK(an);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
@ -6124,7 +6143,6 @@ ath_tx_update_tim(struct ath_softc *sc, struct ieee80211_node *ni,
|
||||
if (atomic_load_acq_int(&an->an_swq_depth) != 0)
|
||||
return;
|
||||
|
||||
ATH_NODE_LOCK(an);
|
||||
if (an->an_is_powersave &&
|
||||
an->an_stack_psq == 0 &&
|
||||
an->an_tim_set == 1 &&
|
||||
@ -6134,10 +6152,7 @@ ath_tx_update_tim(struct ath_softc *sc, struct ieee80211_node *ni,
|
||||
" clear!\n",
|
||||
__func__, an);
|
||||
an->an_tim_set = 0;
|
||||
ATH_NODE_UNLOCK(an);
|
||||
(void) avp->av_set_tim(ni, 0);
|
||||
} else {
|
||||
ATH_NODE_UNLOCK(an);
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
Loading…
x
Reference in New Issue
Block a user