|
@@ -189,6 +189,12 @@ ieee80211_rx_radiotap_hdrlen(struct ieee80211_local *local,
|
|
|
BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_he_mu) != 12);
|
|
|
}
|
|
|
|
|
|
+ if (status->flag & RX_FLAG_RADIOTAP_LSIG) {
|
|
|
+ len = ALIGN(len, 2);
|
|
|
+ len += 4;
|
|
|
+ BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_lsig) != 4);
|
|
|
+ }
|
|
|
+
|
|
|
if (status->chains) {
|
|
|
/* antenna and antenna signal fields */
|
|
|
len += 2 * hweight8(status->chains);
|
|
@@ -279,6 +285,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
|
|
|
struct ieee80211_vendor_radiotap rtap = {};
|
|
|
struct ieee80211_radiotap_he he = {};
|
|
|
struct ieee80211_radiotap_he_mu he_mu = {};
|
|
|
+ struct ieee80211_radiotap_lsig lsig = {};
|
|
|
|
|
|
if (status->flag & RX_FLAG_RADIOTAP_HE) {
|
|
|
he = *(struct ieee80211_radiotap_he *)skb->data;
|
|
@@ -291,6 +298,11 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
|
|
|
skb_pull(skb, sizeof(he_mu));
|
|
|
}
|
|
|
|
|
|
+ if (status->flag & RX_FLAG_RADIOTAP_LSIG) {
|
|
|
+ lsig = *(struct ieee80211_radiotap_lsig *)skb->data;
|
|
|
+ skb_pull(skb, sizeof(lsig));
|
|
|
+ }
|
|
|
+
|
|
|
if (status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA) {
|
|
|
rtap = *(struct ieee80211_vendor_radiotap *)skb->data;
|
|
|
/* rtap.len and rtap.pad are undone immediately */
|
|
@@ -630,6 +642,15 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
|
|
|
pos += sizeof(he_mu);
|
|
|
}
|
|
|
|
|
|
+ if (status->flag & RX_FLAG_RADIOTAP_LSIG) {
|
|
|
+ /* ensure 2 byte alignment */
|
|
|
+ while ((pos - (u8 *)rthdr) & 1)
|
|
|
+ pos++;
|
|
|
+ rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_LSIG);
|
|
|
+ memcpy(pos, &lsig, sizeof(lsig));
|
|
|
+ pos += sizeof(lsig);
|
|
|
+ }
|
|
|
+
|
|
|
for_each_set_bit(chain, &chains, IEEE80211_MAX_CHAINS) {
|
|
|
*pos++ = status->chain_signal[chain];
|
|
|
*pos++ = chain;
|