mac80211: add pending brcmfmac patches fixing multiple interfaces
[openwrt.git] / package / kernel / mac80211 / patches / 320-brcmfmac-make-brcmf_proto_hdrpull-return-struct-brcm.patch
1 From: Arend van Spriel <arend@broadcom.com>
2 Date: Wed, 26 Aug 2015 22:14:54 +0200
3 Subject: [PATCH] brcmfmac: make brcmf_proto_hdrpull() return struct
4  brcmf_if instance
5
6 Avoid spreading the ifidx in the driver, but have it return the
7 struct brcmf_if instance.
8
9 Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
10 Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
11 Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
12 Signed-off-by: Arend van Spriel <arend@broadcom.com>
13 ---
14
15 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
16 +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
17 @@ -272,11 +272,11 @@ brcmf_proto_bcdc_hdrpush(struct brcmf_pu
18  }
19  
20  static int
21 -brcmf_proto_bcdc_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
22 -                        struct sk_buff *pktbuf)
23 +brcmf_proto_bcdc_hdrpull(struct brcmf_pub *drvr, bool do_fws,
24 +                        struct sk_buff *pktbuf, struct brcmf_if **ifp)
25  {
26         struct brcmf_proto_bcdc_header *h;
27 -       struct brcmf_if *ifp;
28 +       struct brcmf_if *tmp_if;
29  
30         brcmf_dbg(BCDC, "Enter\n");
31  
32 @@ -290,21 +290,21 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
33         trace_brcmf_bcdchdr(pktbuf->data);
34         h = (struct brcmf_proto_bcdc_header *)(pktbuf->data);
35  
36 -       ifp = brcmf_get_ifp(drvr, BCDC_GET_IF_IDX(h));
37 -       if (IS_ERR_OR_NULL(ifp)) {
38 +       tmp_if = brcmf_get_ifp(drvr, BCDC_GET_IF_IDX(h));
39 +       if (!tmp_if) {
40                 brcmf_dbg(INFO, "no matching ifp found\n");
41                 return -EBADE;
42         }
43         if (((h->flags & BCDC_FLAG_VER_MASK) >> BCDC_FLAG_VER_SHIFT) !=
44             BCDC_PROTO_VER) {
45                 brcmf_err("%s: non-BCDC packet received, flags 0x%x\n",
46 -                         brcmf_ifname(drvr, ifp->ifidx), h->flags);
47 +                         brcmf_ifname(drvr, tmp_if->ifidx), h->flags);
48                 return -EBADE;
49         }
50  
51         if (h->flags & BCDC_FLAG_SUM_GOOD) {
52                 brcmf_dbg(BCDC, "%s: BDC rcv, good checksum, flags 0x%x\n",
53 -                         brcmf_ifname(drvr, ifp->ifidx), h->flags);
54 +                         brcmf_ifname(drvr, tmp_if->ifidx), h->flags);
55                 pktbuf->ip_summed = CHECKSUM_UNNECESSARY;
56         }
57  
58 @@ -312,7 +312,7 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
59  
60         skb_pull(pktbuf, BCDC_HEADER_LEN);
61         if (do_fws)
62 -               brcmf_fws_hdrpull(drvr, ifp->ifidx, h->data_offset << 2,
63 +               brcmf_fws_hdrpull(drvr, tmp_if->ifidx, h->data_offset << 2,
64                                   pktbuf);
65         else
66                 skb_pull(pktbuf, h->data_offset << 2);
67 @@ -320,7 +320,7 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
68         if (pktbuf->len == 0)
69                 return -ENODATA;
70  
71 -       *ifidx = ifp->ifidx;
72 +       *ifp = tmp_if;
73         return 0;
74  }
75  
76 --- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
77 +++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
78 @@ -87,7 +87,7 @@ struct brcmf_if *brcmf_get_ifp(struct br
79  {
80         if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
81                 brcmf_err("ifidx %d out of range\n", ifidx);
82 -               return ERR_PTR(-ERANGE);
83 +               return NULL;
84         }
85  
86         /* The ifidx is the idx to map to matching netdev/ifp. When receiving
87 @@ -539,17 +539,15 @@ void brcmf_rx_frame(struct device *dev,
88         struct brcmf_bus *bus_if = dev_get_drvdata(dev);
89         struct brcmf_pub *drvr = bus_if->drvr;
90         struct brcmf_skb_reorder_data *rd;
91 -       u8 ifidx;
92         int ret;
93  
94         brcmf_dbg(DATA, "Enter: %s: rxp=%p\n", dev_name(dev), skb);
95  
96         /* process and remove protocol-specific header */
97 -       ret = brcmf_proto_hdrpull(drvr, true, &ifidx, skb);
98 -       ifp = drvr->iflist[ifidx];
99 +       ret = brcmf_proto_hdrpull(drvr, true, skb, &ifp);
100  
101         if (ret || !ifp || !ifp->ndev) {
102 -               if ((ret != -ENODATA) && ifp)
103 +               if (ret != -ENODATA && ifp)
104                         ifp->stats.rx_errors++;
105                 brcmu_pkt_buf_free_skb(skb);
106                 return;
107 @@ -592,17 +590,17 @@ void brcmf_txcomplete(struct device *dev
108  {
109         struct brcmf_bus *bus_if = dev_get_drvdata(dev);
110         struct brcmf_pub *drvr = bus_if->drvr;
111 -       u8 ifidx;
112 +       struct brcmf_if *ifp;
113  
114         /* await txstatus signal for firmware if active */
115         if (brcmf_fws_fc_active(drvr->fws)) {
116                 if (!success)
117                         brcmf_fws_bustxfail(drvr->fws, txp);
118         } else {
119 -               if (brcmf_proto_hdrpull(drvr, false, &ifidx, txp))
120 +               if (brcmf_proto_hdrpull(drvr, false, txp, &ifp))
121                         brcmu_pkt_buf_free_skb(txp);
122                 else
123 -                       brcmf_txfinalize(drvr, txp, ifidx, success);
124 +                       brcmf_txfinalize(drvr, txp, ifp->ifidx, success);
125         }
126  }
127  
128 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
129 +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
130 @@ -1448,7 +1448,7 @@ brcmf_fws_txs_process(struct brcmf_fws_i
131         struct sk_buff *skb;
132         struct brcmf_skbuff_cb *skcb;
133         struct brcmf_fws_mac_descriptor *entry = NULL;
134 -       u8 ifidx;
135 +       struct brcmf_if *ifp;
136  
137         brcmf_dbg(DATA, "flags %d\n", flags);
138  
139 @@ -1497,15 +1497,16 @@ brcmf_fws_txs_process(struct brcmf_fws_i
140         }
141         brcmf_fws_macdesc_return_req_credit(skb);
142  
143 -       if (brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb)) {
144 +       ret = brcmf_proto_hdrpull(fws->drvr, false, skb, &ifp);
145 +       if (ret) {
146                 brcmu_pkt_buf_free_skb(skb);
147                 return -EINVAL;
148         }
149         if (!remove_from_hanger)
150 -               ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifidx,
151 +               ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifp->ifidx,
152                                                     genbit, seq);
153         if (remove_from_hanger || ret)
154 -               brcmf_txfinalize(fws->drvr, skb, ifidx, true);
155 +               brcmf_txfinalize(fws->drvr, skb, ifp->ifidx, true);
156  
157         return 0;
158  }
159 @@ -1848,7 +1849,7 @@ static int brcmf_fws_commit_skb(struct b
160                 entry->transit_count--;
161                 if (entry->suppressed)
162                         entry->suppr_transit_count--;
163 -               brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
164 +               (void)brcmf_proto_hdrpull(fws->drvr, false, skb, NULL);
165                 goto rollback;
166         }
167  
168 --- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
169 +++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
170 @@ -522,7 +522,7 @@ static int brcmf_msgbuf_set_dcmd(struct
171  
172  
173  static int brcmf_msgbuf_hdrpull(struct brcmf_pub *drvr, bool do_fws,
174 -                               u8 *ifidx, struct sk_buff *skb)
175 +                               struct sk_buff *skb, struct brcmf_if **ifp)
176  {
177         return -ENODEV;
178  }
179 @@ -1082,7 +1082,7 @@ brcmf_msgbuf_rx_skb(struct brcmf_msgbuf
180         struct brcmf_if *ifp;
181  
182         ifp = brcmf_get_ifp(msgbuf->drvr, ifidx);
183 -       if (IS_ERR_OR_NULL(ifp) || !ifp->ndev) {
184 +       if (!ifp || !ifp->ndev) {
185                 brcmf_err("Received pkt for invalid ifidx %d\n", ifidx);
186                 brcmu_pkt_buf_free_skb(skb);
187                 return;
188 --- a/drivers/net/wireless/brcm80211/brcmfmac/proto.h
189 +++ b/drivers/net/wireless/brcm80211/brcmfmac/proto.h
190 @@ -24,8 +24,8 @@ enum proto_addr_mode {
191  
192  
193  struct brcmf_proto {
194 -       int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
195 -                      struct sk_buff *skb);
196 +       int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws,
197 +                      struct sk_buff *skb, struct brcmf_if **ifp);
198         int (*query_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd,
199                           void *buf, uint len);
200         int (*set_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf,
201 @@ -46,9 +46,19 @@ int brcmf_proto_attach(struct brcmf_pub
202  void brcmf_proto_detach(struct brcmf_pub *drvr);
203  
204  static inline int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws,
205 -                                     u8 *ifidx, struct sk_buff *skb)
206 +                                     struct sk_buff *skb,
207 +                                     struct brcmf_if **ifp)
208  {
209 -       return drvr->proto->hdrpull(drvr, do_fws, ifidx, skb);
210 +       struct brcmf_if *tmp = NULL;
211 +
212 +       /* assure protocol is always called with
213 +        * non-null initialized pointer.
214 +        */
215 +       if (ifp)
216 +               *ifp = NULL;
217 +       else
218 +               ifp = &tmp;
219 +       return drvr->proto->hdrpull(drvr, do_fws, skb, ifp);
220  }
221  static inline int brcmf_proto_query_dcmd(struct brcmf_pub *drvr, int ifidx,
222                                          uint cmd, void *buf, uint len)