Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 265963
b: refs/heads/master
c: f0425be
h: refs/heads/master
i:
  265961: 7e6f125
  265959: 3e36aea
v: v3
  • Loading branch information
Felix Fietkau authored and John W. Linville committed Sep 13, 2011
1 parent 86c3785 commit 77fec12
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 765b07e46725287ceb1be648b6cb5988fbb585f2
refs/heads/master: f0425beda4d404a6e751439b562100b902ba9c98
5 changes: 5 additions & 0 deletions trunk/net/mac80211/sta_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ enum ieee80211_sta_info_flags {
* @stop_initiator: initiator of a session stop
* @tx_stop: TX DelBA frame when stopping
* @buf_size: reorder buffer size at receiver
* @failed_bar_ssn: ssn of the last failed BAR tx attempt
* @bar_pending: BAR needs to be re-sent
*
* This structure's lifetime is managed by RCU, assignments to
* the array holding it must hold the aggregation mutex.
Expand All @@ -106,6 +108,9 @@ struct tid_ampdu_tx {
u8 stop_initiator;
bool tx_stop;
u8 buf_size;

u16 failed_bar_ssn;
bool bar_pending;
};

/**
Expand Down
37 changes: 36 additions & 1 deletion trunk/net/mac80211/status.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,32 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
dev_kfree_skb(skb);
}

static void ieee80211_check_pending_bar(struct sta_info *sta, u8 *addr, u8 tid)
{
struct tid_ampdu_tx *tid_tx;

tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]);
if (!tid_tx || !tid_tx->bar_pending)
return;

tid_tx->bar_pending = false;
ieee80211_send_bar(sta->sdata, addr, tid, tid_tx->failed_bar_ssn);
}

static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb)
{
struct ieee80211_mgmt *mgmt = (void *) skb->data;
struct ieee80211_local *local = sta->local;
struct ieee80211_sub_if_data *sdata = sta->sdata;

if (ieee80211_is_data_qos(mgmt->frame_control)) {
struct ieee80211_hdr *hdr = (void *) skb->data;
u8 *qc = ieee80211_get_qos_ctl(hdr);
u16 tid = qc[0] & 0xf;

ieee80211_check_pending_bar(sta, hdr->addr1, tid);
}

if (ieee80211_is_action(mgmt->frame_control) &&
sdata->vif.type == NL80211_IFTYPE_STATION &&
mgmt->u.action.category == WLAN_CATEGORY_HT &&
Expand Down Expand Up @@ -161,6 +181,18 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb)
}
}

static void ieee80211_set_bar_pending(struct sta_info *sta, u8 tid, u16 ssn)
{
struct tid_ampdu_tx *tid_tx;

tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]);
if (!tid_tx)
return;

tid_tx->failed_bar_ssn = ssn;
tid_tx->bar_pending = true;
}

/*
* Use a static threshold for now, best value to be determined
* by testing ...
Expand Down Expand Up @@ -254,10 +286,13 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
*/
bar = (struct ieee80211_bar *) skb->data;
if (!(bar->control & IEEE80211_BAR_CTRL_MULTI_TID)) {
u16 ssn = le16_to_cpu(bar->start_seq_num);

tid = (bar->control &
IEEE80211_BAR_CTRL_TID_INFO_MASK) >>
IEEE80211_BAR_CTRL_TID_INFO_SHIFT;
ieee80211_stop_tx_ba_session(&sta->sta, tid);

ieee80211_set_bar_pending(sta, tid, ssn);
}
}

Expand Down

0 comments on commit 77fec12

Please sign in to comment.