3.16.66-rc1 review patch.  If anyone has any objections, please let me know.

------------------

From: Arend van Spriel <ar...@broadcom.com>

commit 75effb03ee8e4c9d4bbc909118ce5444b047dfde upstream.

In rx path the firmware provide an interface index which is used to
map to a struct brcmf_if instance. However, this involves some trick
that is done in two places. This is changed by having driver core
providing brcmf_get_ifp() function.

Reviewed-by: Hante Meuleman <meule...@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <fran...@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <piete...@broadcom.com>
Signed-off-by: Arend van Spriel <ar...@broadcom.com>
Signed-off-by: Kalle Valo <kv...@codeaurora.org>
[bwh: Backported to 3.16:
 - Drop changes to PCIe bus support
 - Adjust filenames]
Signed-off-by: Ben Hutchings <b...@decadent.org.uk>
---
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
@@ -276,6 +276,7 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
                         struct sk_buff *pktbuf)
 {
        struct brcmf_proto_bcdc_header *h;
+       struct brcmf_if *ifp;
 
        brcmf_dbg(BCDC, "Enter\n");
 
@@ -289,30 +290,21 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
        trace_brcmf_bcdchdr(pktbuf->data);
        h = (struct brcmf_proto_bcdc_header *)(pktbuf->data);
 
-       *ifidx = BCDC_GET_IF_IDX(h);
-       if (*ifidx >= BRCMF_MAX_IFS) {
-               brcmf_err("rx data ifnum out of range (%d)\n", *ifidx);
+       ifp = brcmf_get_ifp(drvr, BCDC_GET_IF_IDX(h));
+       if (IS_ERR_OR_NULL(ifp)) {
+               brcmf_dbg(INFO, "no matching ifp found\n");
                return -EBADE;
        }
-       /* The ifidx is the idx to map to matching netdev/ifp. When receiving
-        * events this is easy because it contains the bssidx which maps
-        * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd.
-        * bssidx 1 is used for p2p0 and no data can be received or
-        * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0
-        */
-       if (*ifidx)
-               (*ifidx)++;
-
        if (((h->flags & BCDC_FLAG_VER_MASK) >> BCDC_FLAG_VER_SHIFT) !=
            BCDC_PROTO_VER) {
                brcmf_err("%s: non-BCDC packet received, flags 0x%x\n",
-                         brcmf_ifname(drvr, *ifidx), h->flags);
+                         brcmf_ifname(drvr, ifp->ifidx), h->flags);
                return -EBADE;
        }
 
        if (h->flags & BCDC_FLAG_SUM_GOOD) {
                brcmf_dbg(BCDC, "%s: BDC rcv, good checksum, flags 0x%x\n",
-                         brcmf_ifname(drvr, *ifidx), h->flags);
+                         brcmf_ifname(drvr, ifp->ifidx), h->flags);
                pktbuf->ip_summed = CHECKSUM_UNNECESSARY;
        }
 
@@ -320,12 +312,15 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
 
        skb_pull(pktbuf, BCDC_HEADER_LEN);
        if (do_fws)
-               brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf);
+               brcmf_fws_hdrpull(drvr, ifp->ifidx, h->data_offset << 2,
+                                 pktbuf);
        else
                skb_pull(pktbuf, h->data_offset << 2);
 
        if (pktbuf->len == 0)
                return -ENODATA;
+
+       *ifidx = ifp->ifidx;
        return 0;
 }
 
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -81,6 +81,25 @@ char *brcmf_ifname(struct brcmf_pub *drv
        return "<if_none>";
 }
 
+struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx)
+{
+       if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
+               brcmf_err("ifidx %d out of range\n", ifidx);
+               return ERR_PTR(-ERANGE);
+       }
+
+       /* The ifidx is the idx to map to matching netdev/ifp. When receiving
+        * events this is easy because it contains the bssidx which maps
+        * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd.
+        * bssidx 1 is used for p2p0 and no data can be received or
+        * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0
+        */
+       if (ifidx)
+               ifidx++;
+
+       return drvr->iflist[ifidx];
+}
+
 static void _brcmf_set_multicast_list(struct work_struct *work)
 {
        struct brcmf_if *ifp;
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -178,7 +178,7 @@ int brcmf_netdev_wait_pend8021x(struct n
 
 /* Return pointer to interface name */
 char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
-
+struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx);
 int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
 struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
                              char *name, u8 *mac_addr);

Reply via email to