diff options
Diffstat (limited to 'package/kernel/mac80211/patches/338-v4.19-0003-brcmfmac-handle-msgbuf-packets-marked-with-monitor-m.patch')
-rw-r--r-- | package/kernel/mac80211/patches/338-v4.19-0003-brcmfmac-handle-msgbuf-packets-marked-with-monitor-m.patch | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/338-v4.19-0003-brcmfmac-handle-msgbuf-packets-marked-with-monitor-m.patch b/package/kernel/mac80211/patches/338-v4.19-0003-brcmfmac-handle-msgbuf-packets-marked-with-monitor-m.patch new file mode 100644 index 0000000000..d640bcfecc --- /dev/null +++ b/package/kernel/mac80211/patches/338-v4.19-0003-brcmfmac-handle-msgbuf-packets-marked-with-monitor-m.patch @@ -0,0 +1,137 @@ +From a8d7631858aff156b72f807ee7cc062048e63836 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> +Date: Sun, 24 Jun 2018 21:44:37 +0200 +Subject: [PATCH] brcmfmac: handle msgbuf packets marked with monitor mode flag +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +New Broadcom firmwares mark monitor mode packets using a newly defined +bit in the flags field. Use it to filter them out and pass to the +monitor interface. These defines were found in bcmmsgbuf.h from SDK. + +As not every firmware generates radiotap header this commit introduces +BRCMF_FEAT_MONITOR_FMT_RADIOTAP flag. It has to be has based on firmware +capabilities. If not present brcmf_netif_mon_rx() will assume packet is +a raw 802.11 frame and will prepend it with an empty radiotap header. + +This new code is limited to the msgbuf protocol at this point. Adding +support for SDIO/USB devices will require some extra work (possibly a +new firmware release). + +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> +--- + .../wireless/broadcom/brcm80211/brcmfmac/core.c | 25 ++++++++++++++++++++++ + .../wireless/broadcom/brcm80211/brcmfmac/core.h | 2 ++ + .../wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 18 ++++++++++++++++ + 3 files changed, 45 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -21,6 +21,7 @@ + #include <net/cfg80211.h> + #include <net/rtnetlink.h> + #include <net/addrconf.h> ++#include <net/ieee80211_radiotap.h> + #include <net/ipv6.h> + #include <brcmu_utils.h> + #include <brcmu_wifi.h> +@@ -404,6 +405,30 @@ void brcmf_netif_rx(struct brcmf_if *ifp + netif_rx_ni(skb); + } + ++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 */ ++ } 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; ++ } ++ ++ skb->dev = ifp->ndev; ++ skb_reset_mac_header(skb); ++ skb->pkt_type = PACKET_OTHERHOST; ++ skb->protocol = htons(ETH_P_802_2); ++ ++ brcmf_netif_rx(ifp, skb); ++} ++ + static int brcmf_rx_hdrpull(struct brcmf_pub *drvr, struct sk_buff *skb, + struct brcmf_if **ifp) + { +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +@@ -121,6 +121,7 @@ struct brcmf_pub { + + struct brcmf_if *iflist[BRCMF_MAX_IFS]; + s32 if2bss[BRCMF_MAX_IFS]; ++ struct brcmf_if *mon_if; + + struct mutex proto_block; + unsigned char proto_buf[BRCMF_DCMD_MAXLEN]; +@@ -216,6 +217,7 @@ void brcmf_txflowblock_if(struct brcmf_i + enum brcmf_netif_stop_reason reason, bool state); + void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success); + void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb); ++void brcmf_netif_mon_rx(struct brcmf_if *ifp, struct sk_buff *skb); + void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on); + int __init brcmf_core_init(void); + void __exit brcmf_core_exit(void); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +@@ -69,6 +69,8 @@ + #define BRCMF_MSGBUF_MAX_EVENTBUF_POST 8 + + #define BRCMF_MSGBUF_PKT_FLAGS_FRAME_802_3 0x01 ++#define BRCMF_MSGBUF_PKT_FLAGS_FRAME_802_11 0x02 ++#define BRCMF_MSGBUF_PKT_FLAGS_FRAME_MASK 0x07 + #define BRCMF_MSGBUF_PKT_FLAGS_PRIO_SHIFT 5 + + #define BRCMF_MSGBUF_TX_FLUSH_CNT1 32 +@@ -1128,6 +1130,7 @@ brcmf_msgbuf_process_rx_complete(struct + struct sk_buff *skb; + u16 data_offset; + u16 buflen; ++ u16 flags; + u32 idx; + struct brcmf_if *ifp; + +@@ -1137,6 +1140,7 @@ brcmf_msgbuf_process_rx_complete(struct + data_offset = le16_to_cpu(rx_complete->data_offset); + buflen = le16_to_cpu(rx_complete->data_len); + idx = le32_to_cpu(rx_complete->msg.request_id); ++ flags = le16_to_cpu(rx_complete->flags); + + skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev, + msgbuf->rx_pktids, idx); +@@ -1150,6 +1154,20 @@ brcmf_msgbuf_process_rx_complete(struct + + skb_trim(skb, buflen); + ++ if ((flags & BRCMF_MSGBUF_PKT_FLAGS_FRAME_MASK) == ++ BRCMF_MSGBUF_PKT_FLAGS_FRAME_802_11) { ++ ifp = msgbuf->drvr->mon_if; ++ ++ if (!ifp) { ++ brcmf_err("Received unexpected monitor pkt\n"); ++ brcmu_pkt_buf_free_skb(skb); ++ return; ++ } ++ ++ brcmf_netif_mon_rx(ifp, skb); ++ return; ++ } ++ + ifp = brcmf_get_ifp(msgbuf->drvr, rx_complete->msg.ifidx); + if (!ifp || !ifp->ndev) { + brcmf_err("Received pkt for invalid ifidx %d\n", |