diff options
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 82 |
1 files changed, 47 insertions, 35 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 3aae8e9e4e0a..c9ff98a93211 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -82,10 +82,10 @@ static inline int should_drop_frame(struct ieee80211_rx_status *status, | |||
82 | */ | 82 | */ |
83 | static struct sk_buff * | 83 | static struct sk_buff * |
84 | ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | 84 | ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, |
85 | struct ieee80211_rx_status *status) | 85 | struct ieee80211_rx_status *status, |
86 | struct ieee80211_rate *rate) | ||
86 | { | 87 | { |
87 | struct ieee80211_sub_if_data *sdata; | 88 | struct ieee80211_sub_if_data *sdata; |
88 | struct ieee80211_rate *rate; | ||
89 | int needed_headroom = 0; | 89 | int needed_headroom = 0; |
90 | struct ieee80211_radiotap_header *rthdr; | 90 | struct ieee80211_radiotap_header *rthdr; |
91 | __le64 *rttsft = NULL; | 91 | __le64 *rttsft = NULL; |
@@ -194,14 +194,11 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
194 | rtfixed->rx_flags |= | 194 | rtfixed->rx_flags |= |
195 | cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADFCS); | 195 | cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADFCS); |
196 | 196 | ||
197 | rate = ieee80211_get_rate(local, status->phymode, | 197 | rtfixed->rate = rate->bitrate / 5; |
198 | status->rate); | ||
199 | if (rate) | ||
200 | rtfixed->rate = rate->rate / 5; | ||
201 | 198 | ||
202 | rtfixed->chan_freq = cpu_to_le16(status->freq); | 199 | rtfixed->chan_freq = cpu_to_le16(status->freq); |
203 | 200 | ||
204 | if (status->phymode == MODE_IEEE80211A) | 201 | if (status->band == IEEE80211_BAND_5GHZ) |
205 | rtfixed->chan_flags = | 202 | rtfixed->chan_flags = |
206 | cpu_to_le16(IEEE80211_CHAN_OFDM | | 203 | cpu_to_le16(IEEE80211_CHAN_OFDM | |
207 | IEEE80211_CHAN_5GHZ); | 204 | IEEE80211_CHAN_5GHZ); |
@@ -320,34 +317,21 @@ static void ieee80211_verify_ip_alignment(struct ieee80211_txrx_data *rx) | |||
320 | 317 | ||
321 | 318 | ||
322 | static u32 ieee80211_rx_load_stats(struct ieee80211_local *local, | 319 | static u32 ieee80211_rx_load_stats(struct ieee80211_local *local, |
323 | struct sk_buff *skb, | 320 | struct sk_buff *skb, |
324 | struct ieee80211_rx_status *status) | 321 | struct ieee80211_rx_status *status, |
322 | struct ieee80211_rate *rate) | ||
325 | { | 323 | { |
326 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 324 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
327 | u32 load = 0, hdrtime; | 325 | u32 load = 0, hdrtime; |
328 | struct ieee80211_rate *rate; | ||
329 | struct ieee80211_hw_mode *mode = local->hw.conf.mode; | ||
330 | int i; | ||
331 | 326 | ||
332 | /* Estimate total channel use caused by this frame */ | 327 | /* Estimate total channel use caused by this frame */ |
333 | 328 | ||
334 | if (unlikely(mode->num_rates < 0)) | ||
335 | return TXRX_CONTINUE; | ||
336 | |||
337 | rate = &mode->rates[0]; | ||
338 | for (i = 0; i < mode->num_rates; i++) { | ||
339 | if (mode->rates[i].val == status->rate) { | ||
340 | rate = &mode->rates[i]; | ||
341 | break; | ||
342 | } | ||
343 | } | ||
344 | |||
345 | /* 1 bit at 1 Mbit/s takes 1 usec; in channel_use values, | 329 | /* 1 bit at 1 Mbit/s takes 1 usec; in channel_use values, |
346 | * 1 usec = 1/8 * (1080 / 10) = 13.5 */ | 330 | * 1 usec = 1/8 * (1080 / 10) = 13.5 */ |
347 | 331 | ||
348 | if (mode->mode == MODE_IEEE80211A || | 332 | if (status->band == IEEE80211_BAND_5GHZ || |
349 | (mode->mode == MODE_IEEE80211G && | 333 | (status->band == IEEE80211_BAND_5GHZ && |
350 | rate->flags & IEEE80211_RATE_ERP)) | 334 | rate->flags & IEEE80211_RATE_ERP_G)) |
351 | hdrtime = CHAN_UTIL_HDR_SHORT; | 335 | hdrtime = CHAN_UTIL_HDR_SHORT; |
352 | else | 336 | else |
353 | hdrtime = CHAN_UTIL_HDR_LONG; | 337 | hdrtime = CHAN_UTIL_HDR_LONG; |
@@ -356,7 +340,8 @@ static u32 ieee80211_rx_load_stats(struct ieee80211_local *local, | |||
356 | if (!is_multicast_ether_addr(hdr->addr1)) | 340 | if (!is_multicast_ether_addr(hdr->addr1)) |
357 | load += hdrtime; | 341 | load += hdrtime; |
358 | 342 | ||
359 | load += skb->len * rate->rate_inv; | 343 | /* TODO: optimise again */ |
344 | load += skb->len * CHAN_UTIL_RATE_LCM / rate->bitrate; | ||
360 | 345 | ||
361 | /* Divide channel_use by 8 to avoid wrapping around the counter */ | 346 | /* Divide channel_use by 8 to avoid wrapping around the counter */ |
362 | load >>= CHAN_UTIL_SHIFT; | 347 | load >>= CHAN_UTIL_SHIFT; |
@@ -1685,7 +1670,8 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
1685 | static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | 1670 | static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, |
1686 | struct sk_buff *skb, | 1671 | struct sk_buff *skb, |
1687 | struct ieee80211_rx_status *status, | 1672 | struct ieee80211_rx_status *status, |
1688 | u32 load) | 1673 | u32 load, |
1674 | struct ieee80211_rate *rate) | ||
1689 | { | 1675 | { |
1690 | struct ieee80211_local *local = hw_to_local(hw); | 1676 | struct ieee80211_local *local = hw_to_local(hw); |
1691 | struct ieee80211_sub_if_data *sdata; | 1677 | struct ieee80211_sub_if_data *sdata; |
@@ -1705,6 +1691,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
1705 | 1691 | ||
1706 | rx.u.rx.status = status; | 1692 | rx.u.rx.status = status; |
1707 | rx.u.rx.load = load; | 1693 | rx.u.rx.load = load; |
1694 | rx.u.rx.rate = rate; | ||
1708 | rx.fc = le16_to_cpu(hdr->frame_control); | 1695 | rx.fc = le16_to_cpu(hdr->frame_control); |
1709 | type = rx.fc & IEEE80211_FCTL_FTYPE; | 1696 | type = rx.fc & IEEE80211_FCTL_FTYPE; |
1710 | 1697 | ||
@@ -1837,6 +1824,8 @@ u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
1837 | u16 head_seq_num, buf_size; | 1824 | u16 head_seq_num, buf_size; |
1838 | int index; | 1825 | int index; |
1839 | u32 pkt_load; | 1826 | u32 pkt_load; |
1827 | struct ieee80211_supported_band *sband; | ||
1828 | struct ieee80211_rate *rate; | ||
1840 | 1829 | ||
1841 | buf_size = tid_agg_rx->buf_size; | 1830 | buf_size = tid_agg_rx->buf_size; |
1842 | head_seq_num = tid_agg_rx->head_seq_num; | 1831 | head_seq_num = tid_agg_rx->head_seq_num; |
@@ -1867,12 +1856,14 @@ u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
1867 | memcpy(&status, | 1856 | memcpy(&status, |
1868 | tid_agg_rx->reorder_buf[index]->cb, | 1857 | tid_agg_rx->reorder_buf[index]->cb, |
1869 | sizeof(status)); | 1858 | sizeof(status)); |
1859 | sband = local->hw.wiphy->bands[status.band]; | ||
1860 | rate = &sband->bitrates[status.rate_idx]; | ||
1870 | pkt_load = ieee80211_rx_load_stats(local, | 1861 | pkt_load = ieee80211_rx_load_stats(local, |
1871 | tid_agg_rx->reorder_buf[index], | 1862 | tid_agg_rx->reorder_buf[index], |
1872 | &status); | 1863 | &status, rate); |
1873 | __ieee80211_rx_handle_packet(hw, | 1864 | __ieee80211_rx_handle_packet(hw, |
1874 | tid_agg_rx->reorder_buf[index], | 1865 | tid_agg_rx->reorder_buf[index], |
1875 | &status, pkt_load); | 1866 | &status, pkt_load, rate); |
1876 | tid_agg_rx->stored_mpdu_num--; | 1867 | tid_agg_rx->stored_mpdu_num--; |
1877 | tid_agg_rx->reorder_buf[index] = NULL; | 1868 | tid_agg_rx->reorder_buf[index] = NULL; |
1878 | } | 1869 | } |
@@ -1912,11 +1903,13 @@ u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
1912 | /* release the reordered frame back to stack */ | 1903 | /* release the reordered frame back to stack */ |
1913 | memcpy(&status, tid_agg_rx->reorder_buf[index]->cb, | 1904 | memcpy(&status, tid_agg_rx->reorder_buf[index]->cb, |
1914 | sizeof(status)); | 1905 | sizeof(status)); |
1906 | sband = local->hw.wiphy->bands[status.band]; | ||
1907 | rate = &sband->bitrates[status.rate_idx]; | ||
1915 | pkt_load = ieee80211_rx_load_stats(local, | 1908 | pkt_load = ieee80211_rx_load_stats(local, |
1916 | tid_agg_rx->reorder_buf[index], | 1909 | tid_agg_rx->reorder_buf[index], |
1917 | &status); | 1910 | &status, rate); |
1918 | __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index], | 1911 | __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index], |
1919 | &status, pkt_load); | 1912 | &status, pkt_load, rate); |
1920 | tid_agg_rx->stored_mpdu_num--; | 1913 | tid_agg_rx->stored_mpdu_num--; |
1921 | tid_agg_rx->reorder_buf[index] = NULL; | 1914 | tid_agg_rx->reorder_buf[index] = NULL; |
1922 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); | 1915 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); |
@@ -1997,6 +1990,25 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1997 | { | 1990 | { |
1998 | struct ieee80211_local *local = hw_to_local(hw); | 1991 | struct ieee80211_local *local = hw_to_local(hw); |
1999 | u32 pkt_load; | 1992 | u32 pkt_load; |
1993 | struct ieee80211_rate *rate = NULL; | ||
1994 | struct ieee80211_supported_band *sband; | ||
1995 | |||
1996 | if (status->band < 0 || | ||
1997 | status->band > IEEE80211_NUM_BANDS) { | ||
1998 | WARN_ON(1); | ||
1999 | return; | ||
2000 | } | ||
2001 | |||
2002 | sband = local->hw.wiphy->bands[status->band]; | ||
2003 | |||
2004 | if (!sband || | ||
2005 | status->rate_idx < 0 || | ||
2006 | status->rate_idx >= sband->n_bitrates) { | ||
2007 | WARN_ON(1); | ||
2008 | return; | ||
2009 | } | ||
2010 | |||
2011 | rate = &sband->bitrates[status->rate_idx]; | ||
2000 | 2012 | ||
2001 | /* | 2013 | /* |
2002 | * key references and virtual interfaces are protected using RCU | 2014 | * key references and virtual interfaces are protected using RCU |
@@ -2011,17 +2023,17 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2011 | * if it was previously present. | 2023 | * if it was previously present. |
2012 | * Also, frames with less than 16 bytes are dropped. | 2024 | * Also, frames with less than 16 bytes are dropped. |
2013 | */ | 2025 | */ |
2014 | skb = ieee80211_rx_monitor(local, skb, status); | 2026 | skb = ieee80211_rx_monitor(local, skb, status, rate); |
2015 | if (!skb) { | 2027 | if (!skb) { |
2016 | rcu_read_unlock(); | 2028 | rcu_read_unlock(); |
2017 | return; | 2029 | return; |
2018 | } | 2030 | } |
2019 | 2031 | ||
2020 | pkt_load = ieee80211_rx_load_stats(local, skb, status); | 2032 | pkt_load = ieee80211_rx_load_stats(local, skb, status, rate); |
2021 | local->channel_use_raw += pkt_load; | 2033 | local->channel_use_raw += pkt_load; |
2022 | 2034 | ||
2023 | if (!ieee80211_rx_reorder_ampdu(local, skb)) | 2035 | if (!ieee80211_rx_reorder_ampdu(local, skb)) |
2024 | __ieee80211_rx_handle_packet(hw, skb, status, pkt_load); | 2036 | __ieee80211_rx_handle_packet(hw, skb, status, pkt_load, rate); |
2025 | 2037 | ||
2026 | rcu_read_unlock(); | 2038 | rcu_read_unlock(); |
2027 | } | 2039 | } |