aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-11-16 07:58:21 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-11-18 17:09:17 -0500
commit5f0b7de59fae1e57b2481c9756cd4a0f6308530f (patch)
tree7b937d9d04d03ed3cb90b62c9c791d77d80e7228 /net/mac80211/rx.c
parenteb9fb5b8883535c27d2cc5d4e4dbab3532f97b18 (diff)
mac80211: improve rate handling
Some code currently assumes that there's a valid rate pointer even in the HT case, but there can't be. To reduce reliance on that, remove the rate pointer from the RX data struct and pass it where it's needed. Also, for now, in radiotap announce HT frames as having a DYN channel type, and remove their rate from cooked monitor radiotap completely (it isn't present in the regular monitor radiotap either.) Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c35
1 files changed, 18 insertions, 17 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 904aaea081c..e0cb3357f79 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -163,6 +163,9 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
163 if (status->band == IEEE80211_BAND_5GHZ) 163 if (status->band == IEEE80211_BAND_5GHZ)
164 put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ, 164 put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ,
165 pos); 165 pos);
166 else if (status->flag & RX_FLAG_HT)
167 put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ,
168 pos);
166 else if (rate->flags & IEEE80211_RATE_ERP_G) 169 else if (rate->flags & IEEE80211_RATE_ERP_G)
167 put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ, 170 put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ,
168 pos); 171 pos);
@@ -1845,14 +1848,15 @@ static void ieee80211_rx_michael_mic_report(struct ieee80211_hdr *hdr,
1845} 1848}
1846 1849
1847/* TODO: use IEEE80211_RX_FRAGMENTED */ 1850/* TODO: use IEEE80211_RX_FRAGMENTED */
1848static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx) 1851static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
1852 struct ieee80211_rate *rate)
1849{ 1853{
1850 struct ieee80211_sub_if_data *sdata; 1854 struct ieee80211_sub_if_data *sdata;
1851 struct ieee80211_local *local = rx->local; 1855 struct ieee80211_local *local = rx->local;
1852 struct ieee80211_rtap_hdr { 1856 struct ieee80211_rtap_hdr {
1853 struct ieee80211_radiotap_header hdr; 1857 struct ieee80211_radiotap_header hdr;
1854 u8 flags; 1858 u8 flags;
1855 u8 rate; 1859 u8 rate_or_pad;
1856 __le16 chan_freq; 1860 __le16 chan_freq;
1857 __le16 chan_flags; 1861 __le16 chan_flags;
1858 } __attribute__ ((packed)) *rthdr; 1862 } __attribute__ ((packed)) *rthdr;
@@ -1872,10 +1876,13 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx)
1872 rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); 1876 rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr));
1873 rthdr->hdr.it_present = 1877 rthdr->hdr.it_present =
1874 cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | 1878 cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
1875 (1 << IEEE80211_RADIOTAP_RATE) |
1876 (1 << IEEE80211_RADIOTAP_CHANNEL)); 1879 (1 << IEEE80211_RADIOTAP_CHANNEL));
1877 1880
1878 rthdr->rate = rx->rate->bitrate / 5; 1881 if (rate) {
1882 rthdr->rate_or_pad = rate->bitrate / 5;
1883 rthdr->hdr.it_present |=
1884 cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE);
1885 }
1879 rthdr->chan_freq = cpu_to_le16(status->freq); 1886 rthdr->chan_freq = cpu_to_le16(status->freq);
1880 1887
1881 if (status->band == IEEE80211_BAND_5GHZ) 1888 if (status->band == IEEE80211_BAND_5GHZ)
@@ -1928,7 +1935,8 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx)
1928 1935
1929static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, 1936static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
1930 struct ieee80211_rx_data *rx, 1937 struct ieee80211_rx_data *rx,
1931 struct sk_buff *skb) 1938 struct sk_buff *skb,
1939 struct ieee80211_rate *rate)
1932{ 1940{
1933 ieee80211_rx_result res = RX_DROP_MONITOR; 1941 ieee80211_rx_result res = RX_DROP_MONITOR;
1934 1942
@@ -1972,7 +1980,7 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
1972 rx->sta->rx_dropped++; 1980 rx->sta->rx_dropped++;
1973 /* fall through */ 1981 /* fall through */
1974 case RX_CONTINUE: 1982 case RX_CONTINUE:
1975 ieee80211_rx_cooked_monitor(rx); 1983 ieee80211_rx_cooked_monitor(rx, rate);
1976 break; 1984 break;
1977 case RX_DROP_UNUSABLE: 1985 case RX_DROP_UNUSABLE:
1978 I802_DEBUG_INC(sdata->local->rx_handlers_drop); 1986 I802_DEBUG_INC(sdata->local->rx_handlers_drop);
@@ -2095,7 +2103,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2095 memset(&rx, 0, sizeof(rx)); 2103 memset(&rx, 0, sizeof(rx));
2096 rx.skb = skb; 2104 rx.skb = skb;
2097 rx.local = local; 2105 rx.local = local;
2098 rx.rate = rate;
2099 2106
2100 if (ieee80211_is_data(hdr->frame_control) || ieee80211_is_mgmt(hdr->frame_control)) 2107 if (ieee80211_is_data(hdr->frame_control) || ieee80211_is_mgmt(hdr->frame_control))
2101 local->dot11ReceivedFragmentCount++; 2108 local->dot11ReceivedFragmentCount++;
@@ -2167,11 +2174,11 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2167 prev->dev->name); 2174 prev->dev->name);
2168 continue; 2175 continue;
2169 } 2176 }
2170 ieee80211_invoke_rx_handlers(prev, &rx, skb_new); 2177 ieee80211_invoke_rx_handlers(prev, &rx, skb_new, rate);
2171 prev = sdata; 2178 prev = sdata;
2172 } 2179 }
2173 if (prev) 2180 if (prev)
2174 ieee80211_invoke_rx_handlers(prev, &rx, skb); 2181 ieee80211_invoke_rx_handlers(prev, &rx, skb, rate);
2175 else 2182 else
2176 dev_kfree_skb(skb); 2183 dev_kfree_skb(skb);
2177} 2184}
@@ -2200,7 +2207,7 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
2200 int index) 2207 int index)
2201{ 2208{
2202 struct ieee80211_supported_band *sband; 2209 struct ieee80211_supported_band *sband;
2203 struct ieee80211_rate *rate; 2210 struct ieee80211_rate *rate = NULL;
2204 struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; 2211 struct sk_buff *skb = tid_agg_rx->reorder_buf[index];
2205 struct ieee80211_rx_status *status; 2212 struct ieee80211_rx_status *status;
2206 2213
@@ -2211,9 +2218,7 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
2211 2218
2212 /* release the reordered frames to stack */ 2219 /* release the reordered frames to stack */
2213 sband = hw->wiphy->bands[status->band]; 2220 sband = hw->wiphy->bands[status->band];
2214 if (status->flag & RX_FLAG_HT) 2221 if (!(status->flag & RX_FLAG_HT))
2215 rate = sband->bitrates; /* TODO: HT rates */
2216 else
2217 rate = &sband->bitrates[status->rate_idx]; 2222 rate = &sband->bitrates[status->rate_idx];
2218 __ieee80211_rx_handle_packet(hw, skb, rate); 2223 __ieee80211_rx_handle_packet(hw, skb, rate);
2219 tid_agg_rx->stored_mpdu_num--; 2224 tid_agg_rx->stored_mpdu_num--;
@@ -2460,10 +2465,6 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
2460 status->rate_idx, 2465 status->rate_idx,
2461 status->rate_idx)) 2466 status->rate_idx))
2462 goto drop; 2467 goto drop;
2463 /* HT rates are not in the table - use the highest legacy rate
2464 * for now since other parts of mac80211 may not yet be fully
2465 * MCS aware. */
2466 rate = &sband->bitrates[sband->n_bitrates - 1];
2467 } else { 2468 } else {
2468 if (WARN_ON(status->rate_idx < 0 || 2469 if (WARN_ON(status->rate_idx < 0 ||
2469 status->rate_idx >= sband->n_bitrates)) 2470 status->rate_idx >= sband->n_bitrates))