mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-11 07:04:04 +08:00
staging: brcm80211: added IEEE80211_AMPDU_TX_STOP handling
Driver now flushes AMPDU packets for a specified station on Mac80211 calling wl_ops_ampdu_action(IEEE80211_AMPDU_TX_STOP). Not all AMPDU packets are flushed yet: there can still be AMPDU packets pending in hardware (DMA). That is the subject of the next patch in this series. Signed-off-by: Roland Vossen <rvossen@broadcom.com> Reviewed-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
8ada0be340
commit
61f4420597
@ -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:
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user