mac80211: Populate radiotap header with MCS info for TX frames
authorHelmut Schaa <helmut.schaa@googlemail.com>
Tue, 11 Oct 2011 16:08:55 +0000 (18:08 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 14 Oct 2011 18:48:14 +0000 (14:48 -0400)
mac80211 already filled in the MCS rate info for rx'ed frames but tx'ed
frames that are sent to a monitor interface during the status callback
lack this information.

Add the radiotap fields for MCS info to ieee80211_tx_status_rtap_hdr
and populate them when sending tx'ed frames to the monitors.

The needed headroom is only extended by one byte since we don't include
legacy rate information in the rtap header for HT frames.

Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
include/net/mac80211.h
net/mac80211/status.c

index 021317367d5513ed93cc8df0b50ecfe04234ec77..dc1123aa8181d08a9b91bf2fe3281577088e56d1 100644 (file)
@@ -2522,7 +2522,7 @@ static inline int ieee80211_sta_ps_transition_ni(struct ieee80211_sta *sta,
  * The TX headroom reserved by mac80211 for its own tx_status functions.
  * This is enough for the radiotap header.
  */
-#define IEEE80211_TX_STATUS_HEADROOM   13
+#define IEEE80211_TX_STATUS_HEADROOM   14
 
 /**
  * ieee80211_sta_set_buffered - inform mac80211 about driver-buffered frames
index f97fa0a54cf62a2e93dce1a5e641e33a261d1a00..df643cedf9b9e17514281a811189e902f1411b6a 100644 (file)
@@ -243,6 +243,11 @@ static int ieee80211_tx_radiotap_len(struct ieee80211_tx_info *info)
        /* IEEE80211_RADIOTAP_DATA_RETRIES */
        len += 1;
 
+       /* IEEE80211_TX_RC_MCS */
+       if (info->status.rates[0].idx >= 0 &&
+           info->status.rates[0].flags & IEEE80211_TX_RC_MCS)
+               len += 3;
+
        return len;
 }
 
@@ -299,6 +304,24 @@ static void ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band
        /* for now report the total retry_count */
        *pos = retry_count;
        pos++;
+
+       /* IEEE80211_TX_RC_MCS */
+       if (info->status.rates[0].idx >= 0 &&
+           info->status.rates[0].flags & IEEE80211_TX_RC_MCS) {
+               rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_MCS);
+               pos[0] = IEEE80211_RADIOTAP_MCS_HAVE_MCS |
+                        IEEE80211_RADIOTAP_MCS_HAVE_GI |
+                        IEEE80211_RADIOTAP_MCS_HAVE_BW;
+               if (info->status.rates[0].flags & IEEE80211_TX_RC_SHORT_GI)
+                       pos[1] |= IEEE80211_RADIOTAP_MCS_SGI;
+               if (info->status.rates[0].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+                       pos[1] |= IEEE80211_RADIOTAP_MCS_BW_40;
+               if (info->status.rates[0].flags & IEEE80211_TX_RC_GREEN_FIELD)
+                       pos[1] |= IEEE80211_RADIOTAP_MCS_FMT_GF;
+               pos[2] = info->status.rates[0].idx;
+               pos += 3;
+       }
+
 }
 
 /*