Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 213985
b: refs/heads/master
c: aa0c863
h: refs/heads/master
i:
  213983: 3e67985
v: v3
  • Loading branch information
Christian Lamparter authored and John W. Linville committed Aug 16, 2010
1 parent 8d5abe5 commit 32ad070
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 87 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: 6044474ed86484b899d46e040ade3872e83fc9f7
refs/heads/master: aa0c86364f925c6f12195072562b18c5609ff082
214 changes: 128 additions & 86 deletions trunk/net/mac80211/rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,57 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw,
*/
#define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10)

static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
struct tid_ampdu_rx *tid_agg_rx,
struct sk_buff_head *frames)
{
int index;

/* release the buffer until next missing frame */
index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
tid_agg_rx->buf_size;
if (!tid_agg_rx->reorder_buf[index] &&
tid_agg_rx->stored_mpdu_num > 1) {
/*
* No buffers ready to be released, but check whether any
* frames in the reorder buffer have timed out.
*/
int j;
int skipped = 1;
for (j = (index + 1) % tid_agg_rx->buf_size; j != index;
j = (j + 1) % tid_agg_rx->buf_size) {
if (!tid_agg_rx->reorder_buf[j]) {
skipped++;
continue;
}
if (!time_after(jiffies, tid_agg_rx->reorder_time[j] +
HT_RX_REORDER_BUF_TIMEOUT))
break;

#ifdef CONFIG_MAC80211_HT_DEBUG
if (net_ratelimit())
printk(KERN_DEBUG "%s: release an RX reorder "
"frame due to timeout on earlier "
"frames\n",
wiphy_name(hw->wiphy));
#endif
ieee80211_release_reorder_frame(hw, tid_agg_rx,
j, frames);

/*
* Increment the head seq# also for the skipped slots.
*/
tid_agg_rx->head_seq_num =
(tid_agg_rx->head_seq_num + skipped) & SEQ_MASK;
skipped = 0;
}
} else while (tid_agg_rx->reorder_buf[index]) {
ieee80211_release_reorder_frame(hw, tid_agg_rx, index, frames);
index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
tid_agg_rx->buf_size;
}
}

/*
* As this function belongs to the RX path it must be under
* rcu_read_lock protection. It returns false if the frame
Expand Down Expand Up @@ -643,49 +694,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
tid_agg_rx->reorder_buf[index] = skb;
tid_agg_rx->reorder_time[index] = jiffies;
tid_agg_rx->stored_mpdu_num++;
/* release the buffer until next missing frame */
index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
tid_agg_rx->buf_size;
if (!tid_agg_rx->reorder_buf[index] &&
tid_agg_rx->stored_mpdu_num > 1) {
/*
* No buffers ready to be released, but check whether any
* frames in the reorder buffer have timed out.
*/
int j;
int skipped = 1;
for (j = (index + 1) % tid_agg_rx->buf_size; j != index;
j = (j + 1) % tid_agg_rx->buf_size) {
if (!tid_agg_rx->reorder_buf[j]) {
skipped++;
continue;
}
if (!time_after(jiffies, tid_agg_rx->reorder_time[j] +
HT_RX_REORDER_BUF_TIMEOUT))
break;

#ifdef CONFIG_MAC80211_HT_DEBUG
if (net_ratelimit())
printk(KERN_DEBUG "%s: release an RX reorder "
"frame due to timeout on earlier "
"frames\n",
wiphy_name(hw->wiphy));
#endif
ieee80211_release_reorder_frame(hw, tid_agg_rx,
j, frames);

/*
* Increment the head seq# also for the skipped slots.
*/
tid_agg_rx->head_seq_num =
(tid_agg_rx->head_seq_num + skipped) & SEQ_MASK;
skipped = 0;
}
} else while (tid_agg_rx->reorder_buf[index]) {
ieee80211_release_reorder_frame(hw, tid_agg_rx, index, frames);
index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
tid_agg_rx->buf_size;
}
ieee80211_sta_reorder_release(hw, tid_agg_rx, frames);

return true;
}
Expand Down Expand Up @@ -2267,19 +2276,46 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
dev_kfree_skb(skb);
}


static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
struct ieee80211_rx_data *rx,
struct sk_buff *skb,
struct ieee80211_rate *rate)
static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
ieee80211_rx_result res)
{
struct sk_buff_head reorder_release;
ieee80211_rx_result res = RX_DROP_MONITOR;
switch (res) {
case RX_DROP_MONITOR:
I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop);
if (rx->sta)
rx->sta->rx_dropped++;
/* fall through */
case RX_CONTINUE: {
struct ieee80211_rate *rate = NULL;
struct ieee80211_supported_band *sband;
struct ieee80211_rx_status *status;

status = IEEE80211_SKB_RXCB((rx->skb));

sband = rx->local->hw.wiphy->bands[status->band];
if (!(status->flag & RX_FLAG_HT))
rate = &sband->bitrates[status->rate_idx];

__skb_queue_head_init(&reorder_release);
ieee80211_rx_cooked_monitor(rx, rate);
break;
}
case RX_DROP_UNUSABLE:
I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop);
if (rx->sta)
rx->sta->rx_dropped++;
dev_kfree_skb(rx->skb);
break;
case RX_QUEUED:
I802_DEBUG_INC(rx->sdata->local->rx_handlers_queued);
break;
}
}

rx->skb = skb;
rx->sdata = sdata;
static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
struct sk_buff_head *frames)
{
ieee80211_rx_result res = RX_DROP_MONITOR;
struct sk_buff *skb;

#define CALL_RXH(rxh) \
do { \
Expand All @@ -2288,17 +2324,7 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
goto rxh_next; \
} while (0);

/*
* NB: the rxh_next label works even if we jump
* to it from here because then the list will
* be empty, which is a trivial check
*/
CALL_RXH(ieee80211_rx_h_passive_scan)
CALL_RXH(ieee80211_rx_h_check)

ieee80211_rx_reorder_ampdu(rx, &reorder_release);

while ((skb = __skb_dequeue(&reorder_release))) {
while ((skb = __skb_dequeue(frames))) {
/*
* all the other fields are valid across frames
* that belong to an aMPDU since they are on the
Expand All @@ -2316,42 +2342,58 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
CALL_RXH(ieee80211_rx_h_remove_qos_control)
CALL_RXH(ieee80211_rx_h_amsdu)
#ifdef CONFIG_MAC80211_MESH
if (ieee80211_vif_is_mesh(&sdata->vif))
if (ieee80211_vif_is_mesh(&rx->sdata->vif))
CALL_RXH(ieee80211_rx_h_mesh_fwding);
#endif
CALL_RXH(ieee80211_rx_h_data)

/* special treatment -- needs the queue */
res = ieee80211_rx_h_ctrl(rx, &reorder_release);
res = ieee80211_rx_h_ctrl(rx, frames);
if (res != RX_CONTINUE)
goto rxh_next;

CALL_RXH(ieee80211_rx_h_action)
CALL_RXH(ieee80211_rx_h_mgmt)

rxh_next:
ieee80211_rx_handlers_result(rx, res);

#undef CALL_RXH
}
}

static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
struct ieee80211_rx_data *rx,
struct sk_buff *skb,
struct ieee80211_rate *rate)
{
struct sk_buff_head reorder_release;
ieee80211_rx_result res = RX_DROP_MONITOR;

__skb_queue_head_init(&reorder_release);

rx->skb = skb;
rx->sdata = sdata;

#define CALL_RXH(rxh) \
do { \
res = rxh(rx); \
if (res != RX_CONTINUE) \
goto rxh_next; \
} while (0);

CALL_RXH(ieee80211_rx_h_passive_scan)
CALL_RXH(ieee80211_rx_h_check)

ieee80211_rx_reorder_ampdu(rx, &reorder_release);

ieee80211_rx_handlers(rx, &reorder_release);
return;

rxh_next:
switch (res) {
case RX_DROP_MONITOR:
I802_DEBUG_INC(sdata->local->rx_handlers_drop);
if (rx->sta)
rx->sta->rx_dropped++;
/* fall through */
case RX_CONTINUE:
ieee80211_rx_cooked_monitor(rx, rate);
break;
case RX_DROP_UNUSABLE:
I802_DEBUG_INC(sdata->local->rx_handlers_drop);
if (rx->sta)
rx->sta->rx_dropped++;
dev_kfree_skb(rx->skb);
break;
case RX_QUEUED:
I802_DEBUG_INC(sdata->local->rx_handlers_queued);
break;
}
}
ieee80211_rx_handlers_result(rx, res);

#undef CALL_RXH
}

/* main receive path */
Expand Down

0 comments on commit 32ad070

Please sign in to comment.