aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2008-12-12 07:38:33 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-12-19 15:23:04 -0500
commit0fb8ca45eb164c405eef8978f26829f9348b4d4d (patch)
tree1fc5728b225e7d5a0d06bb0700c83d64bde44f82
parent9d8eed12dbc04f8ed70090da14211c808b5a8d81 (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.h11
-rw-r--r--net/mac80211/mlme.c7
-rw-r--r--net/mac80211/rx.c56
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 */
440enum mac80211_rx_flags { 443enum 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 */
472struct ieee80211_rx_status { 479struct 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