Populates the radiotap header with dbm_antsignal using the rssi value extracted from the firmware's hardware RX header, fixing missing signal data in monitor mode captures. Signed-off-by: Shivesh --- .../broadcom/brcm80211/brcmfmac/core.c | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index ec170647800d..673f0000389c 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -431,45 +431,51 @@ void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb) netif_rx(skb); } +struct brcmf_radiotap_info { + struct ieee80211_radiotap_header hdr; + s8 dbm_antsignal; +} __packed; + void brcmf_netif_mon_rx(struct brcmf_if *ifp, struct sk_buff *skb) { if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FMT_RADIOTAP)) { - /* Do nothing */ + /* Firmware already provided a full radiotap header; do nothing */ } else if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FMT_HW_RX_HDR)) { struct wlc_d11rxhdr *wlc_rxhdr = (struct wlc_d11rxhdr *)skb->data; - struct ieee80211_radiotap_header *radiotap; + struct brcmf_radiotap_info *rtap; unsigned int offset; u16 RxStatus1; + s8 rssi; RxStatus1 = le16_to_cpu(wlc_rxhdr->rxhdr.RxStatus1); + rssi = wlc_rxhdr->rssi; offset = sizeof(struct wlc_d11rxhdr); - /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU - * subframes - */ + /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */ if (RxStatus1 & RXS_PBPRES) offset += 2; offset += D11_PHY_HDR_LEN; skb_pull(skb, offset); - /* TODO: use RX header to fill some radiotap data */ - radiotap = skb_push(skb, sizeof(*radiotap)); - memset(radiotap, 0, sizeof(*radiotap)); - radiotap->it_len = cpu_to_le16(sizeof(*radiotap)); + /* Insert our radiotap header with RSSI data */ + rtap = skb_push(skb, sizeof(*rtap)); + memset(rtap, 0, sizeof(*rtap)); + rtap->hdr.it_len = cpu_to_le16(sizeof(*rtap)); + rtap->hdr.it_present = cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL); + rtap->dbm_antsignal = rssi; - /* TODO: 4 bytes with receive status? */ - skb->len -= 4; + /* Strip the 4-byte receive status / FCS tail */ + skb_trim(skb, skb->len - 4); } else { struct ieee80211_radiotap_header *radiotap; - /* TODO: use RX status to fill some radiotap data */ radiotap = skb_push(skb, sizeof(*radiotap)); memset(radiotap, 0, sizeof(*radiotap)); radiotap->it_len = cpu_to_le16(sizeof(*radiotap)); - /* TODO: 4 bytes with receive status? */ - skb->len -= 4; + /* Strip the 4-byte receive status / FCS tail */ + skb_trim(skb, skb->len - 4); } skb->dev = ifp->ndev; -- 2.53.0