123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- From e665988be29ccea3584528967b432a5cfd801ca4 Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
- Date: Fri, 8 Feb 2019 07:42:30 +0100
- Subject: [PATCH] brcmfmac: support monitor frames with the hardware/ucode
- header
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- So far there were two monitor frame formats:
- 1) 802.11 frames (with frame (sub)type & all addresses)
- 2) 802.11 frames with the radiotap header
- Testing the latest FullMAC firmwares for 4366b1/4366c0 resulted in
- discovering a new format being used. It seems (almost?) identical to the
- one known from ucode used in SoftMAC devices which is most likely the
- same codebase anyway.
- While new firmwares will /announce/ radiotap header support using the
- "rtap" fw capability string it seems no string was added for the new
- ucode header format.
- All above means that:
- 1) We need new format support when dealing with a received frame
- 2) A new feature bit & mapping quirks have to be added manually
- As for now only an empty radiotap is being created. Adding support for
- extracting some info (band, channel, signal, etc.) is planned for the
- future.
- Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
- Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
- Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
- ---
- .../broadcom/brcm80211/brcmfmac/core.c | 55 +++++++++++++++++++
- .../broadcom/brcm80211/brcmfmac/feature.c | 4 ++
- .../broadcom/brcm80211/brcmfmac/feature.h | 4 +-
- 3 files changed, 62 insertions(+), 1 deletion(-)
- --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
- +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
- @@ -42,6 +42,36 @@
-
- #define BRCMF_BSSIDX_INVALID -1
-
- +#define RXS_PBPRES BIT(2)
- +
- +#define D11_PHY_HDR_LEN 6
- +
- +struct d11rxhdr_le {
- + __le16 RxFrameSize;
- + u16 PAD;
- + __le16 PhyRxStatus_0;
- + __le16 PhyRxStatus_1;
- + __le16 PhyRxStatus_2;
- + __le16 PhyRxStatus_3;
- + __le16 PhyRxStatus_4;
- + __le16 PhyRxStatus_5;
- + __le16 RxStatus1;
- + __le16 RxStatus2;
- + __le16 RxTSFTime;
- + __le16 RxChan;
- + u8 unknown[12];
- +} __packed;
- +
- +struct wlc_d11rxhdr {
- + struct d11rxhdr_le rxhdr;
- + __le32 tsf_l;
- + s8 rssi;
- + s8 rxpwr0;
- + s8 rxpwr1;
- + s8 do_rssi_ma;
- + s8 rxpwr[4];
- +} __packed;
- +
- char *brcmf_ifname(struct brcmf_if *ifp)
- {
- if (!ifp)
- @@ -361,6 +391,35 @@ void brcmf_netif_mon_rx(struct brcmf_if
- {
- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FMT_RADIOTAP)) {
- /* 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;
- + unsigned int offset;
- + u16 RxStatus1;
- +
- + RxStatus1 = le16_to_cpu(wlc_rxhdr->rxhdr.RxStatus1);
- +
- + offset = sizeof(struct wlc_d11rxhdr);
- + /* 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 */
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
- + radiotap = skb_push(skb, sizeof(*radiotap));
- +#else
- + radiotap = (struct ieee80211_radiotap_header *)skb_push(skb, sizeof(*radiotap));
- +#endif
- + memset(radiotap, 0, sizeof(*radiotap));
- + radiotap->it_len = cpu_to_le16(sizeof(*radiotap));
- +
- + /* TODO: 4 bytes with receive status? */
- + skb->len -= 4;
- } else {
- struct ieee80211_radiotap_header *radiotap;
-
- --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
- +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
- @@ -102,6 +102,10 @@ static const struct brcmf_feat_fwfeat br
- { "01-6cb8e269", BIT(BRCMF_FEAT_MONITOR) },
- /* brcmfmac4366b-pcie.bin from linux-firmware.git commit 52442afee990 */
- { "01-c47a91a4", BIT(BRCMF_FEAT_MONITOR) },
- + /* brcmfmac4366b-pcie.bin from linux-firmware.git commit 211de1679a68 */
- + { "01-801fb449", BIT(BRCMF_FEAT_MONITOR_FMT_HW_RX_HDR) },
- + /* brcmfmac4366c-pcie.bin from linux-firmware.git commit 211de1679a68 */
- + { "01-d2cbb8fd", BIT(BRCMF_FEAT_MONITOR_FMT_HW_RX_HDR) },
- };
-
- static void brcmf_feat_firmware_overrides(struct brcmf_pub *drv)
- --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
- +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
- @@ -33,6 +33,7 @@
- * MFP: 802.11w Management Frame Protection.
- * MONITOR: firmware can pass monitor packets to host.
- * MONITOR_FMT_RADIOTAP: firmware provides monitor packets with radiotap header
- + * MONITOR_FMT_HW_RX_HDR: firmware provides monitor packets with hw/ucode header
- */
- #define BRCMF_FEAT_LIST \
- BRCMF_FEAT_DEF(MBSS) \
- @@ -48,7 +49,8 @@
- BRCMF_FEAT_DEF(WOWL_ARP_ND) \
- BRCMF_FEAT_DEF(MFP) \
- BRCMF_FEAT_DEF(MONITOR) \
- - BRCMF_FEAT_DEF(MONITOR_FMT_RADIOTAP)
- + BRCMF_FEAT_DEF(MONITOR_FMT_RADIOTAP) \
- + BRCMF_FEAT_DEF(MONITOR_FMT_HW_RX_HDR)
-
- /*
- * Quirks:
|