From f2e8911747ab13bf46b2edac8aece75410d37139 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Thu, 10 Mar 2011 11:35:08 +0100 Subject: [PATCH] --- yaml --- r: 236395 b: refs/heads/master c: 61f4420597b750e932ad0e8567715f1a3439bb03 h: refs/heads/master i: 236393: f381307f26f3c3a7ebf8e4e14cb24fb6104b2a2b 236391: 8c764956e7c13ee654dda986a76e817401837bce v: v3 --- [refs] | 2 +- .../staging/brcm80211/brcmsmac/wl_mac80211.c | 3 ++ .../staging/brcm80211/brcmsmac/wlc_ampdu.c | 43 +++++++++++++++++++ .../staging/brcm80211/brcmsmac/wlc_pub.h | 4 ++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 8279a97659c6..80fcfc631acc 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 8ada0be34014565dc4e57d1194d18594a5bcd161 +refs/heads/master: 61f4420597b750e932ad0e8567715f1a3439bb03 diff --git a/trunk/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/trunk/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 3550551da316..a523b231cffe 100644 --- a/trunk/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/trunk/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -648,6 +648,9 @@ wl_ops_ampdu_action(struct ieee80211_hw *hw, break; case IEEE80211_AMPDU_TX_STOP: + WL_LOCK(wl); + wlc_ampdu_flush(wl->wlc, sta, tid); + WL_UNLOCK(wl); ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; case IEEE80211_AMPDU_TX_OPERATIONAL: diff --git a/trunk/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/trunk/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index 26dd9b6a8757..3d00180efacc 100644 --- a/trunk/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/trunk/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -1363,3 +1363,46 @@ void wlc_ampdu_shm_upd(struct ampdu_info *ampdu) wlc_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_DEF); } } + +struct cb_del_ampdu_pars { + struct ieee80211_sta *sta; + u16 tid; +}; + +/* + * callback function that helps flushing ampdu packets from a priority queue + */ +static bool cb_del_ampdu_pkt(void *p, int arg_a) +{ + struct sk_buff *mpdu = (struct sk_buff *)p; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(mpdu); + struct cb_del_ampdu_pars *ampdu_pars = + (struct cb_del_ampdu_pars *)arg_a; + bool rc; + + rc = tx_info->flags & IEEE80211_TX_CTL_AMPDU ? true : false; + rc = rc && (tx_info->control.sta == NULL || ampdu_pars->sta == NULL || + tx_info->control.sta == ampdu_pars->sta); + rc = rc && ((u8)(mpdu->priority) == ampdu_pars->tid); + return rc; +} + +/* + * When a remote party is no longer available for ampdu communication, any + * pending tx ampdu packets in the driver have to be flushed. + */ +void wlc_ampdu_flush(struct wlc_info *wlc, + struct ieee80211_sta *sta, u16 tid) +{ + struct wlc_txq_info *qi = wlc->active_queue; + struct pktq *pq = &qi->q; + int prec; + struct cb_del_ampdu_pars ampdu_pars; + + ampdu_pars.sta = sta; + ampdu_pars.tid = tid; + for (prec = 0; prec < pq->num_prec; prec++) { + pktq_pflush(pq, prec, true, cb_del_ampdu_pkt, + (int)&du_pars); + } +} diff --git a/trunk/drivers/staging/brcm80211/brcmsmac/wlc_pub.h b/trunk/drivers/staging/brcm80211/brcmsmac/wlc_pub.h index 5536f5111f48..b956c23fa467 100644 --- a/trunk/drivers/staging/brcm80211/brcmsmac/wlc_pub.h +++ b/trunk/drivers/staging/brcm80211/brcmsmac/wlc_pub.h @@ -536,6 +536,10 @@ extern u32 wlc_delta_txfunfl(struct wlc_info *wlc, int fifo); extern void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset); extern void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs); +struct ieee80211_sta; +extern void wlc_ampdu_flush(struct wlc_info *wlc, struct ieee80211_sta *sta, + u16 tid); + /* wlc_phy.c helper functions */ extern void wlc_set_ps_ctrl(struct wlc_info *wlc); extern void wlc_mctrl(struct wlc_info *wlc, u32 mask, u32 val);