aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c138
1 files changed, 92 insertions, 46 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index a5afb79dab6e..d052f4004829 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -19,6 +19,7 @@
19#include <net/ieee80211_radiotap.h> 19#include <net/ieee80211_radiotap.h>
20 20
21#include "ieee80211_i.h" 21#include "ieee80211_i.h"
22#include "driver-ops.h"
22#include "led.h" 23#include "led.h"
23#include "mesh.h" 24#include "mesh.h"
24#include "wep.h" 25#include "wep.h"
@@ -773,9 +774,7 @@ static void ap_sta_ps_start(struct sta_info *sta)
773 774
774 atomic_inc(&sdata->bss->num_sta_ps); 775 atomic_inc(&sdata->bss->num_sta_ps);
775 set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL); 776 set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL);
776 if (local->ops->sta_notify) 777 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_SLEEP, &sta->sta);
777 local->ops->sta_notify(local_to_hw(local), &sdata->vif,
778 STA_NOTIFY_SLEEP, &sta->sta);
779#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 778#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
780 printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n", 779 printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n",
781 sdata->dev->name, sta->sta.addr, sta->sta.aid); 780 sdata->dev->name, sta->sta.addr, sta->sta.aid);
@@ -792,9 +791,7 @@ static int ap_sta_ps_end(struct sta_info *sta)
792 atomic_dec(&sdata->bss->num_sta_ps); 791 atomic_dec(&sdata->bss->num_sta_ps);
793 792
794 clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL); 793 clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL);
795 if (local->ops->sta_notify) 794 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_AWAKE, &sta->sta);
796 local->ops->sta_notify(local_to_hw(local), &sdata->vif,
797 STA_NOTIFY_AWAKE, &sta->sta);
798 795
799 if (!skb_queue_empty(&sta->ps_tx_buf)) 796 if (!skb_queue_empty(&sta->ps_tx_buf))
800 sta_info_clear_tim_bit(sta); 797 sta_info_clear_tim_bit(sta);
@@ -2287,6 +2284,43 @@ static inline u16 seq_sub(u16 sq1, u16 sq2)
2287} 2284}
2288 2285
2289 2286
2287static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
2288 struct tid_ampdu_rx *tid_agg_rx,
2289 int index)
2290{
2291 struct ieee80211_supported_band *sband;
2292 struct ieee80211_rate *rate;
2293 struct ieee80211_rx_status status;
2294
2295 if (!tid_agg_rx->reorder_buf[index])
2296 goto no_frame;
2297
2298 /* release the reordered frames to stack */
2299 memcpy(&status, tid_agg_rx->reorder_buf[index]->cb, sizeof(status));
2300 sband = hw->wiphy->bands[status.band];
2301 if (status.flag & RX_FLAG_HT)
2302 rate = sband->bitrates; /* TODO: HT rates */
2303 else
2304 rate = &sband->bitrates[status.rate_idx];
2305 __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index],
2306 &status, rate);
2307 tid_agg_rx->stored_mpdu_num--;
2308 tid_agg_rx->reorder_buf[index] = NULL;
2309
2310no_frame:
2311 tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num);
2312}
2313
2314
2315/*
2316 * Timeout (in jiffies) for skb's that are waiting in the RX reorder buffer. If
2317 * the skb was added to the buffer longer than this time ago, the earlier
2318 * frames that have not yet been received are assumed to be lost and the skb
2319 * can be released for processing. This may also release other skb's from the
2320 * reorder buffer if there are no additional gaps between the frames.
2321 */
2322#define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10)
2323
2290/* 2324/*
2291 * As it function blongs to Rx path it must be called with 2325 * As it function blongs to Rx path it must be called with
2292 * the proper rcu_read_lock protection for its flow. 2326 * the proper rcu_read_lock protection for its flow.
@@ -2298,12 +2332,8 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
2298 u16 mpdu_seq_num, 2332 u16 mpdu_seq_num,
2299 int bar_req) 2333 int bar_req)
2300{ 2334{
2301 struct ieee80211_local *local = hw_to_local(hw);
2302 struct ieee80211_rx_status status;
2303 u16 head_seq_num, buf_size; 2335 u16 head_seq_num, buf_size;
2304 int index; 2336 int index;
2305 struct ieee80211_supported_band *sband;
2306 struct ieee80211_rate *rate;
2307 2337
2308 buf_size = tid_agg_rx->buf_size; 2338 buf_size = tid_agg_rx->buf_size;
2309 head_seq_num = tid_agg_rx->head_seq_num; 2339 head_seq_num = tid_agg_rx->head_seq_num;
@@ -2328,28 +2358,8 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
2328 index = seq_sub(tid_agg_rx->head_seq_num, 2358 index = seq_sub(tid_agg_rx->head_seq_num,
2329 tid_agg_rx->ssn) 2359 tid_agg_rx->ssn)
2330 % tid_agg_rx->buf_size; 2360 % tid_agg_rx->buf_size;
2331 2361 ieee80211_release_reorder_frame(hw, tid_agg_rx,
2332 if (tid_agg_rx->reorder_buf[index]) { 2362 index);
2333 /* release the reordered frames to stack */
2334 memcpy(&status,
2335 tid_agg_rx->reorder_buf[index]->cb,
2336 sizeof(status));
2337 sband = local->hw.wiphy->bands[status.band];
2338 if (status.flag & RX_FLAG_HT) {
2339 /* TODO: HT rates */
2340 rate = sband->bitrates;
2341 } else {
2342 rate = &sband->bitrates
2343 [status.rate_idx];
2344 }
2345 __ieee80211_rx_handle_packet(hw,
2346 tid_agg_rx->reorder_buf[index],
2347 &status, rate);
2348 tid_agg_rx->stored_mpdu_num--;
2349 tid_agg_rx->reorder_buf[index] = NULL;
2350 }
2351 tid_agg_rx->head_seq_num =
2352 seq_inc(tid_agg_rx->head_seq_num);
2353 } 2363 }
2354 if (bar_req) 2364 if (bar_req)
2355 return 1; 2365 return 1;
@@ -2376,26 +2386,50 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
2376 2386
2377 /* put the frame in the reordering buffer */ 2387 /* put the frame in the reordering buffer */
2378 tid_agg_rx->reorder_buf[index] = skb; 2388 tid_agg_rx->reorder_buf[index] = skb;
2389 tid_agg_rx->reorder_time[index] = jiffies;
2379 memcpy(tid_agg_rx->reorder_buf[index]->cb, rxstatus, 2390 memcpy(tid_agg_rx->reorder_buf[index]->cb, rxstatus,
2380 sizeof(*rxstatus)); 2391 sizeof(*rxstatus));
2381 tid_agg_rx->stored_mpdu_num++; 2392 tid_agg_rx->stored_mpdu_num++;
2382 /* release the buffer until next missing frame */ 2393 /* release the buffer until next missing frame */
2383 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) 2394 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn)
2384 % tid_agg_rx->buf_size; 2395 % tid_agg_rx->buf_size;
2385 while (tid_agg_rx->reorder_buf[index]) { 2396 if (!tid_agg_rx->reorder_buf[index] &&
2386 /* release the reordered frame back to stack */ 2397 tid_agg_rx->stored_mpdu_num > 1) {
2387 memcpy(&status, tid_agg_rx->reorder_buf[index]->cb, 2398 /*
2388 sizeof(status)); 2399 * No buffers ready to be released, but check whether any
2389 sband = local->hw.wiphy->bands[status.band]; 2400 * frames in the reorder buffer have timed out.
2390 if (status.flag & RX_FLAG_HT) 2401 */
2391 rate = sband->bitrates; /* TODO: HT rates */ 2402 int j;
2392 else 2403 int skipped = 1;
2393 rate = &sband->bitrates[status.rate_idx]; 2404 for (j = (index + 1) % tid_agg_rx->buf_size; j != index;
2394 __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index], 2405 j = (j + 1) % tid_agg_rx->buf_size) {
2395 &status, rate); 2406 if (tid_agg_rx->reorder_buf[j] == NULL) {
2396 tid_agg_rx->stored_mpdu_num--; 2407 skipped++;
2397 tid_agg_rx->reorder_buf[index] = NULL; 2408 continue;
2398 tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); 2409 }
2410 if (!time_after(jiffies, tid_agg_rx->reorder_time[j] +
2411 HZ / 10))
2412 break;
2413
2414#ifdef CONFIG_MAC80211_HT_DEBUG
2415 if (net_ratelimit())
2416 printk(KERN_DEBUG "%s: release an RX reorder "
2417 "frame due to timeout on earlier "
2418 "frames\n",
2419 wiphy_name(hw->wiphy));
2420#endif
2421 ieee80211_release_reorder_frame(hw, tid_agg_rx, j);
2422
2423 /*
2424 * Increment the head seq# also for the skipped slots.
2425 */
2426 tid_agg_rx->head_seq_num =
2427 (tid_agg_rx->head_seq_num + skipped) &
2428 SEQ_MASK;
2429 skipped = 0;
2430 }
2431 } else while (tid_agg_rx->reorder_buf[index]) {
2432 ieee80211_release_reorder_frame(hw, tid_agg_rx, index);
2399 index = seq_sub(tid_agg_rx->head_seq_num, 2433 index = seq_sub(tid_agg_rx->head_seq_num,
2400 tid_agg_rx->ssn) % tid_agg_rx->buf_size; 2434 tid_agg_rx->ssn) % tid_agg_rx->buf_size;
2401 } 2435 }
@@ -2517,6 +2551,18 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
2517 return; 2551 return;
2518 } 2552 }
2519 2553
2554 /*
2555 * In theory, the block ack reordering should happen after duplicate
2556 * removal (ieee80211_rx_h_check(), which is an RX handler). As such,
2557 * the call to ieee80211_rx_reorder_ampdu() should really be moved to
2558 * happen as a new RX handler between ieee80211_rx_h_check and
2559 * ieee80211_rx_h_decrypt. This cleanup may eventually happen, but for
2560 * the time being, the call can be here since RX reorder buf processing
2561 * will implicitly skip duplicates. We could, in theory at least,
2562 * process frames that ieee80211_rx_h_passive_scan would drop (e.g.,
2563 * frames from other than operational channel), but that should not
2564 * happen in normal networks.
2565 */
2520 if (!ieee80211_rx_reorder_ampdu(local, skb, status)) 2566 if (!ieee80211_rx_reorder_ampdu(local, skb, status))
2521 __ieee80211_rx_handle_packet(hw, skb, status, rate); 2567 __ieee80211_rx_handle_packet(hw, skb, status, rate);
2522 2568