Commit 0fb8ca45 authored by Jouni Malinen's avatar Jouni Malinen Committed by John W. Linville

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: default avatarJouni Malinen <jouni.malinen@atheros.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 9d8eed12
...@@ -436,6 +436,9 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) ...@@ -436,6 +436,9 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
* is valid. This is useful in monitor mode and necessary for beacon frames * is valid. This is useful in monitor mode and necessary for beacon frames
* to enable IBSS merging. * to enable IBSS merging.
* @RX_FLAG_SHORTPRE: Short preamble was used for this frame * @RX_FLAG_SHORTPRE: Short preamble was used for this frame
* @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index
* @RX_FLAG_40MHZ: HT40 (40 MHz) was used
* @RX_FLAG_SHORT_GI: Short guard interval was used
*/ */
enum mac80211_rx_flags { enum mac80211_rx_flags {
RX_FLAG_MMIC_ERROR = 1<<0, RX_FLAG_MMIC_ERROR = 1<<0,
...@@ -446,7 +449,10 @@ enum mac80211_rx_flags { ...@@ -446,7 +449,10 @@ enum mac80211_rx_flags {
RX_FLAG_FAILED_FCS_CRC = 1<<5, RX_FLAG_FAILED_FCS_CRC = 1<<5,
RX_FLAG_FAILED_PLCP_CRC = 1<<6, RX_FLAG_FAILED_PLCP_CRC = 1<<6,
RX_FLAG_TSFT = 1<<7, RX_FLAG_TSFT = 1<<7,
RX_FLAG_SHORTPRE = 1<<8 RX_FLAG_SHORTPRE = 1<<8,
RX_FLAG_HT = 1<<9,
RX_FLAG_40MHZ = 1<<10,
RX_FLAG_SHORT_GI = 1<<11,
}; };
/** /**
...@@ -466,7 +472,8 @@ enum mac80211_rx_flags { ...@@ -466,7 +472,8 @@ enum mac80211_rx_flags {
* @noise: noise when receiving this frame, in dBm. * @noise: noise when receiving this frame, in dBm.
* @qual: overall signal quality indication, in percent (0-100). * @qual: overall signal quality indication, in percent (0-100).
* @antenna: antenna used * @antenna: antenna used
* @rate_idx: index of data rate into band's supported rates * @rate_idx: index of data rate into band's supported rates or MCS index if
* HT rates are use (RX_FLAG_HT)
* @flag: %RX_FLAG_* * @flag: %RX_FLAG_*
*/ */
struct ieee80211_rx_status { struct ieee80211_rx_status {
......
...@@ -1613,8 +1613,13 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, ...@@ -1613,8 +1613,13 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
* e.g: at 1 MBit that means mactime is 192 usec earlier * e.g: at 1 MBit that means mactime is 192 usec earlier
* (=24 bytes * 8 usecs/byte) than the beacon timestamp. * (=24 bytes * 8 usecs/byte) than the beacon timestamp.
*/ */
int rate = local->hw.wiphy->bands[band]-> int rate;
if (rx_status->flag & RX_FLAG_HT) {
rate = 65; /* TODO: HT rates */
} else {
rate = local->hw.wiphy->bands[band]->
bitrates[rx_status->rate_idx].bitrate; bitrates[rx_status->rate_idx].bitrate;
}
rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate); rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate);
} else if (local && local->ops && local->ops->get_tsf) } else if (local && local->ops && local->ops->get_tsf)
/* second best option: get current TSF */ /* second best option: get current TSF */
......
...@@ -149,6 +149,16 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, ...@@ -149,6 +149,16 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
pos++; pos++;
/* IEEE80211_RADIOTAP_RATE */ /* IEEE80211_RADIOTAP_RATE */
if (status->flag & RX_FLAG_HT) {
/*
* TODO: add following information into radiotap header once
* suitable fields are defined for it:
* - MCS index (status->rate_idx)
* - HT40 (status->flag & RX_FLAG_40MHZ)
* - short-GI (status->flag & RX_FLAG_SHORT_GI)
*/
*pos = 0;
} else
*pos = rate->bitrate / 5; *pos = rate->bitrate / 5;
pos++; pos++;
...@@ -1849,9 +1859,15 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, ...@@ -1849,9 +1859,15 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
if (!(sdata->dev->flags & IFF_PROMISC)) if (!(sdata->dev->flags & IFF_PROMISC))
return 0; return 0;
rx->flags &= ~IEEE80211_RX_RA_MATCH; rx->flags &= ~IEEE80211_RX_RA_MATCH;
} else if (!rx->sta) } else if (!rx->sta) {
int rate_idx;
if (rx->status->flag & RX_FLAG_HT)
rate_idx = 0; /* TODO: HT rates */
else
rate_idx = rx->status->rate_idx;
rx->sta = ieee80211_ibss_add_sta(sdata, bssid, hdr->addr2, rx->sta = ieee80211_ibss_add_sta(sdata, bssid, hdr->addr2,
BIT(rx->status->rate_idx)); BIT(rate_idx));
}
break; break;
case NL80211_IFTYPE_MESH_POINT: case NL80211_IFTYPE_MESH_POINT:
if (!multicast && if (!multicast &&
...@@ -2057,7 +2073,13 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, ...@@ -2057,7 +2073,13 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
tid_agg_rx->reorder_buf[index]->cb, tid_agg_rx->reorder_buf[index]->cb,
sizeof(status)); sizeof(status));
sband = local->hw.wiphy->bands[status.band]; sband = local->hw.wiphy->bands[status.band];
rate = &sband->bitrates[status.rate_idx]; if (status.flag & RX_FLAG_HT) {
/* TODO: HT rates */
rate = sband->bitrates;
} else {
rate = &sband->bitrates
[status.rate_idx];
}
__ieee80211_rx_handle_packet(hw, __ieee80211_rx_handle_packet(hw,
tid_agg_rx->reorder_buf[index], tid_agg_rx->reorder_buf[index],
&status, rate); &status, rate);
...@@ -2101,6 +2123,9 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, ...@@ -2101,6 +2123,9 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
memcpy(&status, tid_agg_rx->reorder_buf[index]->cb, memcpy(&status, tid_agg_rx->reorder_buf[index]->cb,
sizeof(status)); sizeof(status));
sband = local->hw.wiphy->bands[status.band]; sband = local->hw.wiphy->bands[status.band];
if (status.flag & RX_FLAG_HT)
rate = sband->bitrates; /* TODO: HT rates */
else
rate = &sband->bitrates[status.rate_idx]; rate = &sband->bitrates[status.rate_idx];
__ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index], __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index],
&status, rate); &status, rate);
...@@ -2189,15 +2214,26 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, ...@@ -2189,15 +2214,26 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
} }
sband = local->hw.wiphy->bands[status->band]; sband = local->hw.wiphy->bands[status->band];
if (!sband) {
if (!sband ||
status->rate_idx < 0 ||
status->rate_idx >= sband->n_bitrates) {
WARN_ON(1); WARN_ON(1);
return; return;
} }
if (status->flag & RX_FLAG_HT) {
/* rate_idx is MCS index */
if (WARN_ON(status->rate_idx < 0 ||
status->rate_idx >= 76))
return;
/* HT rates are not in the table - use the highest legacy rate
* for now since other parts of mac80211 may not yet be fully
* MCS aware. */
rate = &sband->bitrates[sband->n_bitrates - 1];
} else {
if (WARN_ON(status->rate_idx < 0 ||
status->rate_idx >= sband->n_bitrates))
return;
rate = &sband->bitrates[status->rate_idx]; rate = &sband->bitrates[status->rate_idx];
}
/* /*
* key references and virtual interfaces are protected using RCU * key references and virtual interfaces are protected using RCU
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment