3.16.66-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Arend van Spriel arend.vanspriel@broadcom.com
commit a4176ec356c73a46c07c181c6d04039fafa34a9f upstream.
For USB there is no separate channel being used to pass events from firmware to the host driver and as such are passed over the data path. In order to detect mock event messages an additional check is needed on event subtype. This check is added conditionally using unlikely() keyword.
Reviewed-by: Hante Meuleman hante.meuleman@broadcom.com Reviewed-by: Pieter-Paul Giesberts pieter-paul.giesberts@broadcom.com Reviewed-by: Franky Lin franky.lin@broadcom.com Signed-off-by: Arend van Spriel arend.vanspriel@broadcom.com Signed-off-by: Kalle Valo kvalo@codeaurora.org [bwh: Backported to 3.16: - Drop changes to PCIe bus support - Adjust filenames] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -553,7 +553,8 @@ void brcmf_rx_frame(struct device *dev, } else { /* Process special event packets */ if (handle_event) - brcmf_fweh_process_skb(ifp->drvr, skb); + brcmf_fweh_process_skb(ifp->drvr, skb, + BCMILCP_SUBTYPE_VENDOR_LONG);
brcmf_netif_rx(ifp, skb); } @@ -580,7 +581,7 @@ void brcmf_rx_event(struct device *dev,
skb->protocol = eth_type_trans(skb, ifp->ndev);
- brcmf_fweh_process_skb(ifp->drvr, skb); + brcmf_fweh_process_skb(ifp->drvr, skb, 0); brcmu_pkt_buf_free_skb(skb); }
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h @@ -174,7 +174,7 @@ enum brcmf_fweh_event_code { */ #define BRCM_OUI "\x00\x10\x18" #define BCMILCP_BCM_SUBTYPE_EVENT 1 - +#define BCMILCP_SUBTYPE_VENDOR_LONG 32769
/** * struct brcm_ethhdr - broadcom specific ether header. @@ -292,10 +292,10 @@ void brcmf_fweh_process_event(struct brc u32 packet_len);
static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr, - struct sk_buff *skb) + struct sk_buff *skb, u16 stype) { struct brcmf_event *event_packet; - u16 usr_stype; + u16 subtype, usr_stype;
/* only process events when protocol matches */ if (skb->protocol != cpu_to_be16(ETH_P_LINK_CTL)) @@ -304,8 +304,16 @@ static inline void brcmf_fweh_process_sk if ((skb->len + ETH_HLEN) < sizeof(*event_packet)) return;
- /* check for BRCM oui match */ event_packet = (struct brcmf_event *)skb_mac_header(skb); + + /* check subtype if needed */ + if (unlikely(stype)) { + subtype = get_unaligned_be16(&event_packet->hdr.subtype); + if (subtype != stype) + return; + } + + /* check for BRCM oui match */ if (memcmp(BRCM_OUI, &event_packet->hdr.oui[0], sizeof(event_packet->hdr.oui))) return;