Message ID | 20180619154809.25698-3-zajec5@gmail.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Kalle Valo |
Headers | show |
On 6/19/2018 5:48 PM, Rafał Miłecki wrote: > From: Rafał Miłecki <rafal@milecki.pl> > > 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). Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> > Signed-off-by: Rafał Miłecki <rafal@milecki.pl> > --- > V2: Use cpu_to_le16 when setting it_len > V3: Update TODO comments > Rename flag (after adding MONITOR) > Update commit message > --- > .../wireless/broadcom/brcm80211/brcmfmac/core.c | 25 ++++++++++++++++++++++ > .../wireless/broadcom/brcm80211/brcmfmac/core.h | 2 ++ > .../wireless/broadcom/brcm80211/brcmfmac/feature.h | 4 +++- > .../wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 17 +++++++++++++++ > 4 files changed, 47 insertions(+), 1 deletion(-)
Hi Rafał, I love your patch! Perhaps something to improve: [auto build test WARNING on wireless-drivers-next/master] [also build test WARNING on v4.18-rc1 next-20180619] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Rafa-Mi-ecki/brcmfmac-detect-firmware-support-for-monitor-interface/20180620-012610 base: https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git master smatch warnings: drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1166 brcmf_msgbuf_process_rx_complete() error: we previously assumed 'ifp' could be null (see line 1161) # https://github.com/0day-ci/linux/commit/71f840a490aca9a2d4e9609641a929c6936c20e2 git remote add linux-review https://github.com/0day-ci/linux git remote update linux-review git checkout 71f840a490aca9a2d4e9609641a929c6936c20e2 vim +/ifp +1166 drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1124 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1125 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1126 static void 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1127 brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf) 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1128 { 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1129 struct msgbuf_rx_complete *rx_complete; 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1130 struct sk_buff *skb; 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1131 u16 data_offset; 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1132 u16 buflen; 71f840a49 drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Rafał Miłecki 2018-06-19 1133 u16 flags; 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1134 u32 idx; c56caa9db drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Franky Lin 2016-04-11 1135 struct brcmf_if *ifp; 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1136 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1137 brcmf_msgbuf_update_rxbufpost_count(msgbuf, 1); 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1138 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1139 rx_complete = (struct msgbuf_rx_complete *)buf; 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1140 data_offset = le16_to_cpu(rx_complete->data_offset); 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1141 buflen = le16_to_cpu(rx_complete->data_len); 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1142 idx = le32_to_cpu(rx_complete->msg.request_id); 71f840a49 drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Rafał Miłecki 2018-06-19 1143 flags = le16_to_cpu(rx_complete->flags); 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1144 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1145 skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev, 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1146 msgbuf->rx_pktids, idx); 7d072b404 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Arend van Spriel 2015-05-26 1147 if (!skb) 7d072b404 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Arend van Spriel 2015-05-26 1148 return; 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1149 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1150 if (data_offset) 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1151 skb_pull(skb, data_offset); 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1152 else if (msgbuf->rx_dataoffset) 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1153 skb_pull(skb, msgbuf->rx_dataoffset); 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1154 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1155 skb_trim(skb, buflen); 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1156 71f840a49 drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Rafał Miłecki 2018-06-19 1157 if ((flags & BRCMF_MSGBUF_PKT_FLAGS_FRAME_MASK) == 71f840a49 drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Rafał Miłecki 2018-06-19 1158 BRCMF_MSGBUF_PKT_FLAGS_FRAME_802_11) { 71f840a49 drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Rafał Miłecki 2018-06-19 1159 ifp = msgbuf->drvr->mon_if; 71f840a49 drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Rafał Miłecki 2018-06-19 1160 71f840a49 drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Rafał Miłecki 2018-06-19 @1161 if (!ifp) { 71f840a49 drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Rafał Miłecki 2018-06-19 1162 brcmf_err("Received unexpected monitor pkt\n"); 71f840a49 drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Rafał Miłecki 2018-06-19 1163 brcmu_pkt_buf_free_skb(skb); 71f840a49 drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Rafał Miłecki 2018-06-19 1164 } 71f840a49 drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Rafał Miłecki 2018-06-19 1165 71f840a49 drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Rafał Miłecki 2018-06-19 @1166 brcmf_netif_mon_rx(ifp, skb); 71f840a49 drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Rafał Miłecki 2018-06-19 1167 return; 71f840a49 drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Rafał Miłecki 2018-06-19 1168 } 71f840a49 drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Rafał Miłecki 2018-06-19 1169 c56caa9db drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Franky Lin 2016-04-11 1170 ifp = brcmf_get_ifp(msgbuf->drvr, rx_complete->msg.ifidx); c56caa9db drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Franky Lin 2016-04-11 1171 if (!ifp || !ifp->ndev) { c56caa9db drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Franky Lin 2016-04-11 1172 brcmf_err("Received pkt for invalid ifidx %d\n", c56caa9db drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Franky Lin 2016-04-11 1173 rx_complete->msg.ifidx); c56caa9db drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Franky Lin 2016-04-11 1174 brcmu_pkt_buf_free_skb(skb); c56caa9db drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Franky Lin 2016-04-11 1175 return; c56caa9db drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Franky Lin 2016-04-11 1176 } 31143e293 drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Franky Lin 2016-06-02 1177 31143e293 drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Franky Lin 2016-06-02 1178 skb->protocol = eth_type_trans(skb, ifp->ndev); 9c349892c drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c Arend van Spriel 2016-04-11 1179 brcmf_netif_rx(ifp, skb); 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1180 } 9a1bb6025 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c Hante Meuleman 2014-07-30 1181 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index 72954fd6df3b..b1f702faff4f 100644 --- 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, struct sk_buff *skb) 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) { diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h index 401f50458686..dcf6e27cc16f 100644 --- 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_if *ifp, 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); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h index 6eddb19ca48d..0782f2aa3767 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h @@ -34,6 +34,7 @@ * GSCAN: enhanced scan offload feature. * FWSUP: Firmware supplicant. * MONITOR: monitor interface + * MONITOR_FMT_RADIOTAP: monitor packets include radiotap header */ #define BRCMF_FEAT_LIST \ BRCMF_FEAT_DEF(MBSS) \ @@ -50,7 +51,8 @@ BRCMF_FEAT_DEF(MFP) \ BRCMF_FEAT_DEF(GSCAN) \ BRCMF_FEAT_DEF(FWSUP) \ - BRCMF_FEAT_DEF(MONITOR) + BRCMF_FEAT_DEF(MONITOR) \ + BRCMF_FEAT_DEF(MONITOR_FMT_RADIOTAP) /* * Quirks: diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c index c40ba8855cd5..6abf9795930e 100644 --- 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 brcmf_msgbuf *msgbuf, void *buf) 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 brcmf_msgbuf *msgbuf, void *buf) 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,19 @@ brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf) 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); + } + + 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",