diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 0c3983b74b3e..331429898ea1 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -338,11 +338,15 @@ enum ieee80211_bss_change { * @RSSI_EVENT: AP's rssi crossed the a threshold set by the driver. * @MLME_EVENT: event related to MLME * @BAR_RX_EVENT: a BAR was received + * @BA_FRAME_TIMEOUT: Frames were released from the reordering buffer because + * they timed out. This won't be called for each frame released, but only + * once each time the timeout triggers. */ enum ieee80211_event_type { RSSI_EVENT, MLME_EVENT, BAR_RX_EVENT, + BA_FRAME_TIMEOUT, }; /** @@ -405,7 +409,7 @@ struct ieee80211_mlme_event { * struct ieee80211_ba_event - data attached for BlockAck related events * @sta: pointer to the &ieee80211_sta to which this event relates * @tid: the tid - * @ssn: the starting sequence number + * @ssn: the starting sequence number (for %BAR_RX_EVENT) */ struct ieee80211_ba_event { struct ieee80211_sta *sta; @@ -418,7 +422,7 @@ struct ieee80211_ba_event { * @type: The event itself. See &enum ieee80211_event_type. * @rssi: relevant if &type is %RSSI_EVENT * @mlme: relevant if &type is %AUTH_EVENT - * @ba: relevant if &type is %BAR_RX_EVENT + * @ba: relevant if &type is %BAR_RX_EVENT or %BA_FRAME_TIMEOUT * @u:union holding the fields above */ struct ieee80211_event { diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index ac6bfa999416..e08253547f42 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -3229,6 +3229,15 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) ieee80211_sta_reorder_release(sta->sdata, tid_agg_rx, &frames); spin_unlock(&tid_agg_rx->reorder_lock); + if (!skb_queue_empty(&frames)) { + struct ieee80211_event event = { + .type = BA_FRAME_TIMEOUT, + .u.ba.tid = tid, + .u.ba.sta = &sta->sta, + }; + drv_event_callback(rx.local, rx.sdata, &event); + } + ieee80211_rx_handlers(&rx, &frames); }