mac80211: brcmfmac: fix memleak and add size optimization
[openwrt/staging/rmilecki.git] / package / kernel / mac80211 / patches / 855-0003-brcmfmac-initialize-fws-ignal-for-BCDC-protocol-only.patch
1 From 8931da16a3cb2e0646b1430a9fd94c0a6a5bfd41 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
3 Date: Sat, 24 Sep 2016 22:06:31 +0200
4 Subject: [PATCH 1/2] brcmfmac: initialize fws(ignal) for BCDC protocol only
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 There are two protocols used by Broadcom FullMAC devices: BCDC and
10 msgbuf. They use different ways for (some part of) communication with
11 the firmware. Firmware Signaling is required for the first one only
12 (BCDC).
13
14 So far we were always initializing fws and always calling it's skb
15 processing function. It was fws that was passing skb processing to the
16 protocol specific function. It was redundant for the msgbuf case.
17
18 Simply taking few lines of code out of fws allows us to totally avoid
19 using it. This simplifies code flow, saves some memory & will allow
20 further optimizations like not compiling fwsignal.c.
21
22 Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
23 ---
24 .../wireless/broadcom/brcm80211/brcmfmac/core.c | 24 ++++++++++++++++------
25 .../broadcom/brcm80211/brcmfmac/fwsignal.c | 17 ++++++---------
26 .../broadcom/brcm80211/brcmfmac/fwsignal.h | 1 +
27 3 files changed, 25 insertions(+), 17 deletions(-)
28
29 diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
30 index 27cd50a..bc3d8ab 100644
31 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
32 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
33 @@ -250,7 +250,17 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
34 if (eh->h_proto == htons(ETH_P_PAE))
35 atomic_inc(&ifp->pend_8021x_cnt);
36
37 - ret = brcmf_fws_process_skb(ifp, skb);
38 + /* determine the priority */
39 + if (skb->priority == 0 || skb->priority > 7)
40 + skb->priority = cfg80211_classify8021d(skb, NULL);
41 +
42 + if (drvr->fws && brcmf_fws_skbs_queueing(drvr->fws)) {
43 + ret = brcmf_fws_process_skb(ifp, skb);
44 + } else {
45 + ret = brcmf_proto_txdata(drvr, ifp->ifidx, 0, skb);
46 + if (ret < 0)
47 + brcmf_txfinalize(ifp, skb, false);
48 + }
49
50 done:
51 if (ret) {
52 @@ -405,7 +415,7 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
53 struct brcmf_if *ifp;
54
55 /* await txstatus signal for firmware if active */
56 - if (brcmf_fws_fc_active(drvr->fws)) {
57 + if (drvr->fws && brcmf_fws_fc_active(drvr->fws)) {
58 if (!success)
59 brcmf_fws_bustxfail(drvr->fws, txp);
60 } else {
61 @@ -1006,11 +1016,13 @@ int brcmf_bus_start(struct device *dev)
62 }
63 brcmf_feat_attach(drvr);
64
65 - ret = brcmf_fws_init(drvr);
66 - if (ret < 0)
67 - goto fail;
68 + if (bus_if->proto_type == BRCMF_PROTO_BCDC) {
69 + ret = brcmf_fws_init(drvr);
70 + if (ret < 0)
71 + goto fail;
72
73 - brcmf_fws_add_interface(ifp);
74 + brcmf_fws_add_interface(ifp);
75 + }
76
77 drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev,
78 drvr->settings->p2p_enable);
79 diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
80 index a190f53..495eaf8 100644
81 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
82 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
83 @@ -2100,16 +2100,6 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
84 int rc = 0;
85
86 brcmf_dbg(DATA, "tx proto=0x%X\n", ntohs(eh->h_proto));
87 - /* determine the priority */
88 - if ((skb->priority == 0) || (skb->priority > 7))
89 - skb->priority = cfg80211_classify8021d(skb, NULL);
90 -
91 - if (fws->avoid_queueing) {
92 - rc = brcmf_proto_txdata(drvr, ifp->ifidx, 0, skb);
93 - if (rc < 0)
94 - brcmf_txfinalize(ifp, skb, false);
95 - return rc;
96 - }
97
98 /* set control buffer information */
99 skcb->if_flags = 0;
100 @@ -2155,7 +2145,7 @@ void brcmf_fws_add_interface(struct brcmf_if *ifp)
101 struct brcmf_fws_info *fws = ifp->drvr->fws;
102 struct brcmf_fws_mac_descriptor *entry;
103
104 - if (!ifp->ndev)
105 + if (!fws || !ifp->ndev)
106 return;
107
108 entry = &fws->desc.iface[ifp->ifidx];
109 @@ -2442,6 +2432,11 @@ void brcmf_fws_deinit(struct brcmf_pub *drvr)
110 kfree(fws);
111 }
112
113 +bool brcmf_fws_skbs_queueing(struct brcmf_fws_info *fws)
114 +{
115 + return !fws->avoid_queueing;
116 +}
117 +
118 bool brcmf_fws_fc_active(struct brcmf_fws_info *fws)
119 {
120 if (!fws->creditmap_received)
121 diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h
122 index ef0ad85..8f7c1d7 100644
123 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h
124 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h
125 @@ -20,6 +20,7 @@
126
127 int brcmf_fws_init(struct brcmf_pub *drvr);
128 void brcmf_fws_deinit(struct brcmf_pub *drvr);
129 +bool brcmf_fws_skbs_queueing(struct brcmf_fws_info *fws);
130 bool brcmf_fws_fc_active(struct brcmf_fws_info *fws);
131 void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb);
132 int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb);
133 --
134 2.9.3
135