diff options
author | Jouni Malinen <jouni.malinen@atheros.com> | 2008-12-12 07:38:33 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-12-19 15:23:04 -0500 |
commit | 0fb8ca45eb164c405eef8978f26829f9348b4d4d (patch) | |
tree | 1fc5728b225e7d5a0d06bb0700c83d64bde44f82 | |
parent | 9d8eed12dbc04f8ed70090da14211c808b5a8d81 (diff) |
mac80211: Add HT rates into RX status reporting
This patch adds option for HT-enabled drivers to report HT rates
(HT20/HT40, short GI, MCS index) to mac80211. These rates are
currently not in the rate table, so the rate_idx is used to indicate
MCS index.
Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | include/net/mac80211.h | 11 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 7 | ||||
-rw-r--r-- | net/mac80211/rx.c | 56 |
3 files changed, 61 insertions, 13 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 22ae72c58d76..9428d3e2f113 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -436,6 +436,9 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) | |||
436 | * is valid. This is useful in monitor mode and necessary for beacon frames | 436 | * is valid. This is useful in monitor mode and necessary for beacon frames |
437 | * to enable IBSS merging. | 437 | * to enable IBSS merging. |
438 | * @RX_FLAG_SHORTPRE: Short preamble was used for this frame | 438 | * @RX_FLAG_SHORTPRE: Short preamble was used for this frame |
439 | * @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index | ||
440 | * @RX_FLAG_40MHZ: HT40 (40 MHz) was used | ||
441 | * @RX_FLAG_SHORT_GI: Short guard interval was used | ||
439 | */ | 442 | */ |
440 | enum mac80211_rx_flags { | 443 | enum mac80211_rx_flags { |
441 | RX_FLAG_MMIC_ERROR = 1<<0, | 444 | RX_FLAG_MMIC_ERROR = 1<<0, |
@@ -446,7 +449,10 @@ enum mac80211_rx_flags { | |||
446 | RX_FLAG_FAILED_FCS_CRC = 1<<5, | 449 | RX_FLAG_FAILED_FCS_CRC = 1<<5, |
447 | RX_FLAG_FAILED_PLCP_CRC = 1<<6, | 450 | RX_FLAG_FAILED_PLCP_CRC = 1<<6, |
448 | RX_FLAG_TSFT = 1<<7, | 451 | RX_FLAG_TSFT = 1<<7, |
449 | RX_FLAG_SHORTPRE = 1<<8 | 452 | RX_FLAG_SHORTPRE = 1<<8, |
453 | RX_FLAG_HT = 1<<9, | ||
454 | RX_FLAG_40MHZ = 1<<10, | ||
455 | RX_FLAG_SHORT_GI = 1<<11, | ||
450 | }; | 456 | }; |
451 | 457 | ||
452 | /** | 458 | /** |
@@ -466,7 +472,8 @@ enum mac80211_rx_flags { | |||
466 | * @noise: noise when receiving this frame, in dBm. | 472 | * @noise: noise when receiving this frame, in dBm. |
467 | * @qual: overall signal quality indication, in percent (0-100). | 473 | * @qual: overall signal quality indication, in percent (0-100). |
468 | * @antenna: antenna used | 474 | * @antenna: antenna used |
469 | * @rate_idx: index of data rate into band's supported rates | 475 | * @rate_idx: index of data rate into band's supported rates or MCS index if |
476 | * HT rates are use (RX_FLAG_HT) | ||
470 | * @flag: %RX_FLAG_* | 477 | * @flag: %RX_FLAG_* |
471 | */ | 478 | */ |
472 | struct ieee80211_rx_status { | 479 | struct ieee80211_rx_status { |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index e4d1fca5c72d..a444b38f4901 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1613,8 +1613,13 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
1613 | * e.g: at 1 MBit that means mactime is 192 usec earlier | 1613 | * e.g: at 1 MBit that means mactime is 192 usec earlier |
1614 | * (=24 bytes * 8 usecs/byte) than the beacon timestamp. | 1614 | * (=24 bytes * 8 usecs/byte) than the beacon timestamp. |
1615 | */ | 1615 | */ |
1616 | int rate = local->hw.wiphy->bands[band]-> | 1616 | int rate; |
1617 | if (rx_status->flag & RX_FLAG_HT) { | ||
1618 | rate = 65; /* TODO: HT rates */ | ||
1619 | } else { | ||
1620 | rate = local->hw.wiphy->bands[band]-> | ||
1617 | bitrates[rx_status->rate_idx].bitrate; | 1621 | bitrates[rx_status->rate_idx].bitrate; |
1622 | } | ||
1618 | rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate); | 1623 | rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate); |
1619 | } else if (local && local->ops && local->ops->get_tsf) | 1624 | } else if (local && local->ops && local->ops->get_tsf) |
1620 | /* second best option: get current TSF */ | 1625 | /* second best option: get current TSF */ |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 73cf126cef49..b729c005a2b3 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -149,7 +149,17 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | |||
149 | pos++; | 149 | pos++; |
150 | 150 | ||
151 | /* IEEE80211_RADIOTAP_RATE */ | 151 | /* IEEE80211_RADIOTAP_RATE */ |
152 | *pos = rate->bitrate / 5; | 152 | if (status->flag & RX_FLAG_HT) { |
153 | /* | ||
154 | * TODO: add following information into radiotap header once | ||
155 | * suitable fields are defined for it: | ||
156 | * - MCS index (status->rate_idx) | ||
157 | * - HT40 (status->flag & RX_FLAG_40MHZ) | ||
158 | * - short-GI (status->flag & RX_FLAG_SHORT_GI) | ||
159 | */ | ||
160 | *pos = 0; | ||
161 | } else | ||
162 | *pos = rate->bitrate / 5; | ||
153 | pos++; | 163 | pos++; |
154 | 164 | ||
155 | /* IEEE80211_RADIOTAP_CHANNEL */ | 165 | /* IEEE80211_RADIOTAP_CHANNEL */ |
@@ -1849,9 +1859,15 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
1849 | if (!(sdata->dev->flags & IFF_PROMISC)) | 1859 | if (!(sdata->dev->flags & IFF_PROMISC)) |
1850 | return 0; | 1860 | return 0; |
1851 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 1861 | rx->flags &= ~IEEE80211_RX_RA_MATCH; |
1852 | } else if (!rx->sta) | 1862 | } else if (!rx->sta) { |
1863 | int rate_idx; | ||
1864 | if (rx->status->flag & RX_FLAG_HT) | ||
1865 | rate_idx = 0; /* TODO: HT rates */ | ||
1866 | else | ||
1867 | rate_idx = rx->status->rate_idx; | ||
1853 | rx->sta = ieee80211_ibss_add_sta(sdata, bssid, hdr->addr2, | 1868 | rx->sta = ieee80211_ibss_add_sta(sdata, bssid, hdr->addr2, |
1854 | BIT(rx->status->rate_idx)); | 1869 | BIT(rate_idx)); |
1870 | } | ||
1855 | break; | 1871 | break; |
1856 | case NL80211_IFTYPE_MESH_POINT: | 1872 | case NL80211_IFTYPE_MESH_POINT: |
1857 | if (!multicast && | 1873 | if (!multicast && |
@@ -2057,7 +2073,13 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
2057 | tid_agg_rx->reorder_buf[index]->cb, | 2073 | tid_agg_rx->reorder_buf[index]->cb, |
2058 | sizeof(status)); | 2074 | sizeof(status)); |
2059 | sband = local->hw.wiphy->bands[status.band]; | 2075 | sband = local->hw.wiphy->bands[status.band]; |
2060 | rate = &sband->bitrates[status.rate_idx]; | 2076 | if (status.flag & RX_FLAG_HT) { |
2077 | /* TODO: HT rates */ | ||
2078 | rate = sband->bitrates; | ||
2079 | } else { | ||
2080 | rate = &sband->bitrates | ||
2081 | [status.rate_idx]; | ||
2082 | } | ||
2061 | __ieee80211_rx_handle_packet(hw, | 2083 | __ieee80211_rx_handle_packet(hw, |
2062 | tid_agg_rx->reorder_buf[index], | 2084 | tid_agg_rx->reorder_buf[index], |
2063 | &status, rate); | 2085 | &status, rate); |
@@ -2101,7 +2123,10 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
2101 | memcpy(&status, tid_agg_rx->reorder_buf[index]->cb, | 2123 | memcpy(&status, tid_agg_rx->reorder_buf[index]->cb, |
2102 | sizeof(status)); | 2124 | sizeof(status)); |
2103 | sband = local->hw.wiphy->bands[status.band]; | 2125 | sband = local->hw.wiphy->bands[status.band]; |
2104 | rate = &sband->bitrates[status.rate_idx]; | 2126 | if (status.flag & RX_FLAG_HT) |
2127 | rate = sband->bitrates; /* TODO: HT rates */ | ||
2128 | else | ||
2129 | rate = &sband->bitrates[status.rate_idx]; | ||
2105 | __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index], | 2130 | __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index], |
2106 | &status, rate); | 2131 | &status, rate); |
2107 | tid_agg_rx->stored_mpdu_num--; | 2132 | tid_agg_rx->stored_mpdu_num--; |
@@ -2189,15 +2214,26 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2189 | } | 2214 | } |
2190 | 2215 | ||
2191 | sband = local->hw.wiphy->bands[status->band]; | 2216 | sband = local->hw.wiphy->bands[status->band]; |
2192 | 2217 | if (!sband) { | |
2193 | if (!sband || | ||
2194 | status->rate_idx < 0 || | ||
2195 | status->rate_idx >= sband->n_bitrates) { | ||
2196 | WARN_ON(1); | 2218 | WARN_ON(1); |
2197 | return; | 2219 | return; |
2198 | } | 2220 | } |
2199 | 2221 | ||
2200 | rate = &sband->bitrates[status->rate_idx]; | 2222 | if (status->flag & RX_FLAG_HT) { |
2223 | /* rate_idx is MCS index */ | ||
2224 | if (WARN_ON(status->rate_idx < 0 || | ||
2225 | status->rate_idx >= 76)) | ||
2226 | return; | ||
2227 | /* HT rates are not in the table - use the highest legacy rate | ||
2228 | * for now since other parts of mac80211 may not yet be fully | ||
2229 | * MCS aware. */ | ||
2230 | rate = &sband->bitrates[sband->n_bitrates - 1]; | ||
2231 | } else { | ||
2232 | if (WARN_ON(status->rate_idx < 0 || | ||
2233 | status->rate_idx >= sband->n_bitrates)) | ||
2234 | return; | ||
2235 | rate = &sband->bitrates[status->rate_idx]; | ||
2236 | } | ||
2201 | 2237 | ||
2202 | /* | 2238 | /* |
2203 | * key references and virtual interfaces are protected using RCU | 2239 | * key references and virtual interfaces are protected using RCU |