aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/319-brcmfmac-consolidate-ifp-lookup-in-driver-core.patch
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2015-08-26 22:10:14 +0000
committerRafał Miłecki <zajec5@gmail.com>2015-08-26 22:10:14 +0000
commit2cd72294b629f0075bb38f4401ab3b91c539470c (patch)
tree8d1e00bb1175ddb03c5d920ff29bbec125ab548a /package/kernel/mac80211/patches/319-brcmfmac-consolidate-ifp-lookup-in-driver-core.patch
parentf87990840db36a8a9e5fac8044c4f3a3a213b849 (diff)
downloadupstream-2cd72294b629f0075bb38f4401ab3b91c539470c.tar.gz
upstream-2cd72294b629f0075bb38f4401ab3b91c539470c.tar.bz2
upstream-2cd72294b629f0075bb38f4401ab3b91c539470c.zip
mac80211: add pending brcmfmac patches fixing multiple interfaces
So far support for multiple interface was somehow broken in brcmfmac. Driver couldn't correctly match firmware and system interfaces resulting in not working APs and WARNINGs. This pending patches fixes that :) Signed-off-by: Rafał Miłecki <zajec5@gmail.com> SVN-Revision: 46734
Diffstat (limited to 'package/kernel/mac80211/patches/319-brcmfmac-consolidate-ifp-lookup-in-driver-core.patch')
-rw-r--r--package/kernel/mac80211/patches/319-brcmfmac-consolidate-ifp-lookup-in-driver-core.patch138
1 files changed, 138 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/319-brcmfmac-consolidate-ifp-lookup-in-driver-core.patch b/package/kernel/mac80211/patches/319-brcmfmac-consolidate-ifp-lookup-in-driver-core.patch
new file mode 100644
index 0000000000..97444b3c0d
--- /dev/null
+++ b/package/kernel/mac80211/patches/319-brcmfmac-consolidate-ifp-lookup-in-driver-core.patch
@@ -0,0 +1,138 @@
+From: Arend van Spriel <arend@broadcom.com>
+Date: Wed, 26 Aug 2015 22:14:53 +0200
+Subject: [PATCH] brcmfmac: consolidate ifp lookup in driver core
+
+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 <meuleman@broadcom.com>
+Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
+Signed-off-by: Arend van Spriel <arend@broadcom.com>
+---
+
+--- 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/core.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
+@@ -83,6 +83,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/core.h
++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h
+@@ -202,7 +202,7 @@ int brcmf_netdev_wait_pend8021x(struct b
+
+ /* 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);
+--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
+@@ -1081,16 +1081,8 @@ brcmf_msgbuf_rx_skb(struct brcmf_msgbuf
+ {
+ struct brcmf_if *ifp;
+
+- /* 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)++;
+- ifp = msgbuf->drvr->iflist[ifidx];
+- if (!ifp || !ifp->ndev) {
++ ifp = brcmf_get_ifp(msgbuf->drvr, ifidx);
++ if (IS_ERR_OR_NULL(ifp) || !ifp->ndev) {
+ brcmf_err("Received pkt for invalid ifidx %d\n", ifidx);
+ brcmu_pkt_buf_free_skb(skb);
+ return;