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.c71
1 files changed, 31 insertions, 40 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index de5bba7f910a..0563b6969a21 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -30,7 +30,6 @@
30static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, 30static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
31 struct tid_ampdu_rx *tid_agg_rx, 31 struct tid_ampdu_rx *tid_agg_rx,
32 struct sk_buff *skb, 32 struct sk_buff *skb,
33 struct ieee80211_rx_status *status,
34 u16 mpdu_seq_num, 33 u16 mpdu_seq_num,
35 int bar_req); 34 int bar_req);
36/* 35/*
@@ -59,11 +58,11 @@ static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
59 return skb; 58 return skb;
60} 59}
61 60
62static inline int should_drop_frame(struct ieee80211_rx_status *status, 61static inline int should_drop_frame(struct sk_buff *skb,
63 struct sk_buff *skb,
64 int present_fcs_len, 62 int present_fcs_len,
65 int radiotap_len) 63 int radiotap_len)
66{ 64{
65 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
67 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 66 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
68 67
69 if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) 68 if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC))
@@ -111,10 +110,10 @@ ieee80211_rx_radiotap_len(struct ieee80211_local *local,
111static void 110static void
112ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, 111ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
113 struct sk_buff *skb, 112 struct sk_buff *skb,
114 struct ieee80211_rx_status *status,
115 struct ieee80211_rate *rate, 113 struct ieee80211_rate *rate,
116 int rtap_len) 114 int rtap_len)
117{ 115{
116 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
118 struct ieee80211_radiotap_header *rthdr; 117 struct ieee80211_radiotap_header *rthdr;
119 unsigned char *pos; 118 unsigned char *pos;
120 119
@@ -220,9 +219,9 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
220 */ 219 */
221static struct sk_buff * 220static struct sk_buff *
222ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, 221ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
223 struct ieee80211_rx_status *status,
224 struct ieee80211_rate *rate) 222 struct ieee80211_rate *rate)
225{ 223{
224 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb);
226 struct ieee80211_sub_if_data *sdata; 225 struct ieee80211_sub_if_data *sdata;
227 int needed_headroom = 0; 226 int needed_headroom = 0;
228 struct sk_buff *skb, *skb2; 227 struct sk_buff *skb, *skb2;
@@ -248,8 +247,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
248 present_fcs_len = FCS_LEN; 247 present_fcs_len = FCS_LEN;
249 248
250 if (!local->monitors) { 249 if (!local->monitors) {
251 if (should_drop_frame(status, origskb, present_fcs_len, 250 if (should_drop_frame(origskb, present_fcs_len, rtap_len)) {
252 rtap_len)) {
253 dev_kfree_skb(origskb); 251 dev_kfree_skb(origskb);
254 return NULL; 252 return NULL;
255 } 253 }
@@ -257,7 +255,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
257 return remove_monitor_info(local, origskb, rtap_len); 255 return remove_monitor_info(local, origskb, rtap_len);
258 } 256 }
259 257
260 if (should_drop_frame(status, origskb, present_fcs_len, rtap_len)) { 258 if (should_drop_frame(origskb, present_fcs_len, rtap_len)) {
261 /* only need to expand headroom if necessary */ 259 /* only need to expand headroom if necessary */
262 skb = origskb; 260 skb = origskb;
263 origskb = NULL; 261 origskb = NULL;
@@ -289,7 +287,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
289 287
290 /* if necessary, prepend radiotap information */ 288 /* if necessary, prepend radiotap information */
291 if (!(status->flag & RX_FLAG_RADIOTAP)) 289 if (!(status->flag & RX_FLAG_RADIOTAP))
292 ieee80211_add_rx_radiotap_header(local, skb, status, rate, 290 ieee80211_add_rx_radiotap_header(local, skb, rate,
293 needed_headroom); 291 needed_headroom);
294 292
295 skb_reset_mac_header(skb); 293 skb_reset_mac_header(skb);
@@ -421,12 +419,11 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
421 struct sk_buff *skb = rx->skb; 419 struct sk_buff *skb = rx->skb;
422 420
423 if (unlikely(local->hw_scanning)) 421 if (unlikely(local->hw_scanning))
424 return ieee80211_scan_rx(rx->sdata, skb, rx->status); 422 return ieee80211_scan_rx(rx->sdata, skb);
425 423
426 if (unlikely(local->sw_scanning)) { 424 if (unlikely(local->sw_scanning)) {
427 /* drop all the other packets during a software scan anyway */ 425 /* drop all the other packets during a software scan anyway */
428 if (ieee80211_scan_rx(rx->sdata, skb, rx->status) 426 if (ieee80211_scan_rx(rx->sdata, skb) != RX_QUEUED)
429 != RX_QUEUED)
430 dev_kfree_skb(skb); 427 dev_kfree_skb(skb);
431 return RX_QUEUED; 428 return RX_QUEUED;
432 } 429 }
@@ -1620,7 +1617,7 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx)
1620 /* manage reordering buffer according to requested */ 1617 /* manage reordering buffer according to requested */
1621 /* sequence number */ 1618 /* sequence number */
1622 rcu_read_lock(); 1619 rcu_read_lock();
1623 ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, NULL, NULL, 1620 ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, NULL,
1624 start_seq_num, 1); 1621 start_seq_num, 1);
1625 rcu_read_unlock(); 1622 rcu_read_unlock();
1626 return RX_DROP_UNUSABLE; 1623 return RX_DROP_UNUSABLE;
@@ -1817,13 +1814,13 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
1817 return RX_DROP_MONITOR; 1814 return RX_DROP_MONITOR;
1818 1815
1819 if (ieee80211_vif_is_mesh(&sdata->vif)) 1816 if (ieee80211_vif_is_mesh(&sdata->vif))
1820 return ieee80211_mesh_rx_mgmt(sdata, rx->skb, rx->status); 1817 return ieee80211_mesh_rx_mgmt(sdata, rx->skb);
1821 1818
1822 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 1819 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
1823 return ieee80211_ibss_rx_mgmt(sdata, rx->skb, rx->status); 1820 return ieee80211_ibss_rx_mgmt(sdata, rx->skb);
1824 1821
1825 if (sdata->vif.type == NL80211_IFTYPE_STATION) 1822 if (sdata->vif.type == NL80211_IFTYPE_STATION)
1826 return ieee80211_sta_rx_mgmt(sdata, rx->skb, rx->status); 1823 return ieee80211_sta_rx_mgmt(sdata, rx->skb);
1827 1824
1828 return RX_DROP_MONITOR; 1825 return RX_DROP_MONITOR;
1829} 1826}
@@ -2114,9 +2111,9 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
2114 */ 2111 */
2115static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, 2112static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2116 struct sk_buff *skb, 2113 struct sk_buff *skb,
2117 struct ieee80211_rx_status *status,
2118 struct ieee80211_rate *rate) 2114 struct ieee80211_rate *rate)
2119{ 2115{
2116 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
2120 struct ieee80211_local *local = hw_to_local(hw); 2117 struct ieee80211_local *local = hw_to_local(hw);
2121 struct ieee80211_sub_if_data *sdata; 2118 struct ieee80211_sub_if_data *sdata;
2122 struct ieee80211_hdr *hdr; 2119 struct ieee80211_hdr *hdr;
@@ -2227,20 +2224,21 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
2227{ 2224{
2228 struct ieee80211_supported_band *sband; 2225 struct ieee80211_supported_band *sband;
2229 struct ieee80211_rate *rate; 2226 struct ieee80211_rate *rate;
2230 struct ieee80211_rx_status status; 2227 struct sk_buff *skb = tid_agg_rx->reorder_buf[index];
2228 struct ieee80211_rx_status *status;
2231 2229
2232 if (!tid_agg_rx->reorder_buf[index]) 2230 if (!skb)
2233 goto no_frame; 2231 goto no_frame;
2234 2232
2233 status = IEEE80211_SKB_RXCB(skb);
2234
2235 /* release the reordered frames to stack */ 2235 /* release the reordered frames to stack */
2236 memcpy(&status, tid_agg_rx->reorder_buf[index]->cb, sizeof(status)); 2236 sband = hw->wiphy->bands[status->band];
2237 sband = hw->wiphy->bands[status.band]; 2237 if (status->flag & RX_FLAG_HT)
2238 if (status.flag & RX_FLAG_HT)
2239 rate = sband->bitrates; /* TODO: HT rates */ 2238 rate = sband->bitrates; /* TODO: HT rates */
2240 else 2239 else
2241 rate = &sband->bitrates[status.rate_idx]; 2240 rate = &sband->bitrates[status->rate_idx];
2242 __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index], 2241 __ieee80211_rx_handle_packet(hw, skb, rate);
2243 &status, rate);
2244 tid_agg_rx->stored_mpdu_num--; 2242 tid_agg_rx->stored_mpdu_num--;
2245 tid_agg_rx->reorder_buf[index] = NULL; 2243 tid_agg_rx->reorder_buf[index] = NULL;
2246 2244
@@ -2265,7 +2263,6 @@ no_frame:
2265static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, 2263static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
2266 struct tid_ampdu_rx *tid_agg_rx, 2264 struct tid_ampdu_rx *tid_agg_rx,
2267 struct sk_buff *skb, 2265 struct sk_buff *skb,
2268 struct ieee80211_rx_status *rxstatus,
2269 u16 mpdu_seq_num, 2266 u16 mpdu_seq_num,
2270 int bar_req) 2267 int bar_req)
2271{ 2268{
@@ -2324,8 +2321,6 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
2324 /* put the frame in the reordering buffer */ 2321 /* put the frame in the reordering buffer */
2325 tid_agg_rx->reorder_buf[index] = skb; 2322 tid_agg_rx->reorder_buf[index] = skb;
2326 tid_agg_rx->reorder_time[index] = jiffies; 2323 tid_agg_rx->reorder_time[index] = jiffies;
2327 memcpy(tid_agg_rx->reorder_buf[index]->cb, rxstatus,
2328 sizeof(*rxstatus));
2329 tid_agg_rx->stored_mpdu_num++; 2324 tid_agg_rx->stored_mpdu_num++;
2330 /* release the buffer until next missing frame */ 2325 /* release the buffer until next missing frame */
2331 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) 2326 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn)
@@ -2374,8 +2369,7 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
2374} 2369}
2375 2370
2376static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local, 2371static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
2377 struct sk_buff *skb, 2372 struct sk_buff *skb)
2378 struct ieee80211_rx_status *status)
2379{ 2373{
2380 struct ieee80211_hw *hw = &local->hw; 2374 struct ieee80211_hw *hw = &local->hw;
2381 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 2375 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
@@ -2424,7 +2418,7 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
2424 2418
2425 /* according to mpdu sequence number deal with reordering buffer */ 2419 /* according to mpdu sequence number deal with reordering buffer */
2426 mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4; 2420 mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4;
2427 ret = ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb, status, 2421 ret = ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb,
2428 mpdu_seq_num, 0); 2422 mpdu_seq_num, 0);
2429 end_reorder: 2423 end_reorder:
2430 return ret; 2424 return ret;
@@ -2434,12 +2428,12 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
2434 * This is the receive path handler. It is called by a low level driver when an 2428 * This is the receive path handler. It is called by a low level driver when an
2435 * 802.11 MPDU is received from the hardware. 2429 * 802.11 MPDU is received from the hardware.
2436 */ 2430 */
2437void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, 2431void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
2438 struct ieee80211_rx_status *status)
2439{ 2432{
2440 struct ieee80211_local *local = hw_to_local(hw); 2433 struct ieee80211_local *local = hw_to_local(hw);
2441 struct ieee80211_rate *rate = NULL; 2434 struct ieee80211_rate *rate = NULL;
2442 struct ieee80211_supported_band *sband; 2435 struct ieee80211_supported_band *sband;
2436 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
2443 2437
2444 if (status->band < 0 || 2438 if (status->band < 0 ||
2445 status->band >= IEEE80211_NUM_BANDS) { 2439 status->band >= IEEE80211_NUM_BANDS) {
@@ -2482,7 +2476,7 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
2482 * if it was previously present. 2476 * if it was previously present.
2483 * Also, frames with less than 16 bytes are dropped. 2477 * Also, frames with less than 16 bytes are dropped.
2484 */ 2478 */
2485 skb = ieee80211_rx_monitor(local, skb, status, rate); 2479 skb = ieee80211_rx_monitor(local, skb, rate);
2486 if (!skb) { 2480 if (!skb) {
2487 rcu_read_unlock(); 2481 rcu_read_unlock();
2488 return; 2482 return;
@@ -2500,8 +2494,8 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
2500 * frames from other than operational channel), but that should not 2494 * frames from other than operational channel), but that should not
2501 * happen in normal networks. 2495 * happen in normal networks.
2502 */ 2496 */
2503 if (!ieee80211_rx_reorder_ampdu(local, skb, status)) 2497 if (!ieee80211_rx_reorder_ampdu(local, skb))
2504 __ieee80211_rx_handle_packet(hw, skb, status, rate); 2498 __ieee80211_rx_handle_packet(hw, skb, rate);
2505 2499
2506 rcu_read_unlock(); 2500 rcu_read_unlock();
2507} 2501}
@@ -2509,16 +2503,13 @@ EXPORT_SYMBOL(__ieee80211_rx);
2509 2503
2510/* This is a version of the rx handler that can be called from hard irq 2504/* This is a version of the rx handler that can be called from hard irq
2511 * context. Post the skb on the queue and schedule the tasklet */ 2505 * context. Post the skb on the queue and schedule the tasklet */
2512void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb, 2506void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb)
2513 struct ieee80211_rx_status *status)
2514{ 2507{
2515 struct ieee80211_local *local = hw_to_local(hw); 2508 struct ieee80211_local *local = hw_to_local(hw);
2516 2509
2517 BUILD_BUG_ON(sizeof(struct ieee80211_rx_status) > sizeof(skb->cb)); 2510 BUILD_BUG_ON(sizeof(struct ieee80211_rx_status) > sizeof(skb->cb));
2518 2511
2519 skb->dev = local->mdev; 2512 skb->dev = local->mdev;
2520 /* copy status into skb->cb for use by tasklet */
2521 memcpy(skb->cb, status, sizeof(*status));
2522 skb->pkt_type = IEEE80211_RX_MSG; 2513 skb->pkt_type = IEEE80211_RX_MSG;
2523 skb_queue_tail(&local->skb_queue, skb); 2514 skb_queue_tail(&local->skb_queue, skb);
2524 tasklet_schedule(&local->tasklet); 2515 tasklet_schedule(&local->tasklet);