staging: brcm80211: removed log after kzalloc()/kmalloc() failure
[pandora-kernel.git] / drivers / staging / brcm80211 / brcmfmac / dhd_cdc.c
1 /*
2  * Copyright (c) 2010 Broadcom Corporation
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 #include <linux/types.h>
18 #include <linux/netdevice.h>
19 #include <linux/sched.h>
20 #include <defs.h>
21
22 #include <brcmu_utils.h>
23 #include <brcmu_wifi.h>
24
25 #include "dhd.h"
26 #include "dhd_proto.h"
27 #include "dhd_bus.h"
28 #include "dhd_dbg.h"
29
30 struct brcmf_proto_cdc_ioctl {
31         __le32 cmd;     /* ioctl command value */
32         __le32 len;     /* lower 16: output buflen;
33                          * upper 16: input buflen (excludes header) */
34         __le32 flags;   /* flag defns given below */
35         __le32 status;  /* status code returned from the device */
36 };
37
38 /* Max valid buffer size that can be sent to the dongle */
39 #define CDC_MAX_MSG_SIZE        (ETH_FRAME_LEN+ETH_FCS_LEN)
40
41 /* CDC flag definitions */
42 #define CDCF_IOC_ERROR          0x01            /* 1=ioctl cmd failed */
43 #define CDCF_IOC_SET            0x02            /* 0=get, 1=set cmd */
44 #define CDCF_IOC_IF_MASK        0xF000          /* I/F index */
45 #define CDCF_IOC_IF_SHIFT       12
46 #define CDCF_IOC_ID_MASK        0xFFFF0000      /* id an ioctl pairing */
47 #define CDCF_IOC_ID_SHIFT       16              /* ID Mask shift bits */
48 #define CDC_IOC_ID(flags)       \
49         (((flags) & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT)
50
51 /*
52  * BDC header - Broadcom specific extension of CDC.
53  * Used on data packets to convey priority across USB.
54  */
55 #define BDC_HEADER_LEN          4
56 #define BDC_PROTO_VER           1       /* Protocol version */
57 #define BDC_FLAG_VER_MASK       0xf0    /* Protocol version mask */
58 #define BDC_FLAG_VER_SHIFT      4       /* Protocol version shift */
59 #define BDC_FLAG_SUM_GOOD       0x04    /* Good RX checksums */
60 #define BDC_FLAG_SUM_NEEDED     0x08    /* Dongle needs to do TX checksums */
61 #define BDC_PRIORITY_MASK       0x7
62 #define BDC_FLAG2_IF_MASK       0x0f    /* packet rx interface in APSTA */
63 #define BDC_FLAG2_IF_SHIFT      0
64
65 #define BDC_GET_IF_IDX(hdr) \
66         ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT))
67 #define BDC_SET_IF_IDX(hdr, idx) \
68         ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \
69         ((idx) << BDC_FLAG2_IF_SHIFT)))
70
71 struct brcmf_proto_bdc_header {
72         u8 flags;
73         u8 priority;    /* 802.1d Priority, 4:7 flow control info for usb */
74         u8 flags2;
75         u8 rssi;
76 };
77
78
79 #define RETRIES 2       /* # of retries to retrieve matching ioctl response */
80 #define BUS_HEADER_LEN  (16+BRCMF_SDALIGN) /* Must be atleast SDPCM_RESERVE
81                                          * (amount of header tha might be added)
82                                          * plus any space that might be needed
83                                          * for alignment padding.
84                                          */
85 #define ROUND_UP_MARGIN 2048    /* Biggest SDIO block size possible for
86                                  * round off at the end of buffer
87                                  */
88
89 struct brcmf_proto {
90         u16 reqid;
91         u8 pending;
92         u32 lastcmd;
93         u8 bus_header[BUS_HEADER_LEN];
94         struct brcmf_proto_cdc_ioctl msg;
95         unsigned char buf[BRCMF_C_IOCTL_MAXLEN + ROUND_UP_MARGIN];
96 };
97
98 static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr)
99 {
100         struct brcmf_proto *prot = drvr->prot;
101         int len = le32_to_cpu(prot->msg.len) +
102                         sizeof(struct brcmf_proto_cdc_ioctl);
103
104         brcmf_dbg(TRACE, "Enter\n");
105
106         /* NOTE : cdc->msg.len holds the desired length of the buffer to be
107          *        returned. Only up to CDC_MAX_MSG_SIZE of this buffer area
108          *        is actually sent to the dongle
109          */
110         if (len > CDC_MAX_MSG_SIZE)
111                 len = CDC_MAX_MSG_SIZE;
112
113         /* Send request */
114         return brcmf_sdbrcm_bus_txctl(drvr->bus, (unsigned char *)&prot->msg,
115                                       len);
116 }
117
118 static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)
119 {
120         int ret;
121         struct brcmf_proto *prot = drvr->prot;
122
123         brcmf_dbg(TRACE, "Enter\n");
124
125         do {
126                 ret = brcmf_sdbrcm_bus_rxctl(drvr->bus,
127                                 (unsigned char *)&prot->msg,
128                                 len + sizeof(struct brcmf_proto_cdc_ioctl));
129                 if (ret < 0)
130                         break;
131         } while (CDC_IOC_ID(le32_to_cpu(prot->msg.flags)) != id);
132
133         return ret;
134 }
135
136 int
137 brcmf_proto_cdc_query_ioctl(struct brcmf_pub *drvr, int ifidx, uint cmd,
138                             void *buf, uint len)
139 {
140         struct brcmf_proto *prot = drvr->prot;
141         struct brcmf_proto_cdc_ioctl *msg = &prot->msg;
142         void *info;
143         int ret = 0, retries = 0;
144         u32 id, flags;
145
146         brcmf_dbg(TRACE, "Enter\n");
147         brcmf_dbg(CTL, "cmd %d len %d\n", cmd, len);
148
149         /* Respond "bcmerror" and "bcmerrorstr" with local cache */
150         if (cmd == BRCMF_C_GET_VAR && buf) {
151                 if (!strcmp((char *)buf, "bcmerrorstr")) {
152                         strncpy((char *)buf, "bcm_error",
153                                 BCME_STRLEN);
154                         goto done;
155                 } else if (!strcmp((char *)buf, "bcmerror")) {
156                         *(int *)buf = drvr->dongle_error;
157                         goto done;
158                 }
159         }
160
161         memset(msg, 0, sizeof(struct brcmf_proto_cdc_ioctl));
162
163         msg->cmd = cpu_to_le32(cmd);
164         msg->len = cpu_to_le32(len);
165         flags = (++prot->reqid << CDCF_IOC_ID_SHIFT);
166         flags = (flags & ~CDCF_IOC_IF_MASK) | (ifidx << CDCF_IOC_IF_SHIFT);
167         msg->flags = cpu_to_le32(flags);
168
169         if (buf)
170                 memcpy(prot->buf, buf, len);
171
172         ret = brcmf_proto_cdc_msg(drvr);
173         if (ret < 0) {
174                 brcmf_dbg(ERROR, "brcmf_proto_cdc_msg failed w/status %d\n",
175                           ret);
176                 goto done;
177         }
178
179 retry:
180         /* wait for interrupt and get first fragment */
181         ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
182         if (ret < 0)
183                 goto done;
184
185         flags = le32_to_cpu(msg->flags);
186         id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT;
187
188         if ((id < prot->reqid) && (++retries < RETRIES))
189                 goto retry;
190         if (id != prot->reqid) {
191                 brcmf_dbg(ERROR, "%s: unexpected request id %d (expected %d)\n",
192                           brcmf_ifname(drvr, ifidx), id, prot->reqid);
193                 ret = -EINVAL;
194                 goto done;
195         }
196
197         /* Check info buffer */
198         info = (void *)&msg[1];
199
200         /* Copy info buffer */
201         if (buf) {
202                 if (ret < (int)len)
203                         len = ret;
204                 memcpy(buf, info, len);
205         }
206
207         /* Check the ERROR flag */
208         if (flags & CDCF_IOC_ERROR) {
209                 ret = le32_to_cpu(msg->status);
210                 /* Cache error from dongle */
211                 drvr->dongle_error = ret;
212         }
213
214 done:
215         return ret;
216 }
217
218 int brcmf_proto_cdc_set_ioctl(struct brcmf_pub *drvr, int ifidx, uint cmd,
219                               void *buf, uint len)
220 {
221         struct brcmf_proto *prot = drvr->prot;
222         struct brcmf_proto_cdc_ioctl *msg = &prot->msg;
223         int ret = 0;
224         u32 flags, id;
225
226         brcmf_dbg(TRACE, "Enter\n");
227         brcmf_dbg(CTL, "cmd %d len %d\n", cmd, len);
228
229         memset(msg, 0, sizeof(struct brcmf_proto_cdc_ioctl));
230
231         msg->cmd = cpu_to_le32(cmd);
232         msg->len = cpu_to_le32(len);
233         flags = (++prot->reqid << CDCF_IOC_ID_SHIFT) | CDCF_IOC_SET;
234         flags = (flags & ~CDCF_IOC_IF_MASK) | (ifidx << CDCF_IOC_IF_SHIFT);
235         msg->flags = cpu_to_le32(flags);
236
237         if (buf)
238                 memcpy(prot->buf, buf, len);
239
240         ret = brcmf_proto_cdc_msg(drvr);
241         if (ret < 0)
242                 goto done;
243
244         ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
245         if (ret < 0)
246                 goto done;
247
248         flags = le32_to_cpu(msg->flags);
249         id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT;
250
251         if (id != prot->reqid) {
252                 brcmf_dbg(ERROR, "%s: unexpected request id %d (expected %d)\n",
253                           brcmf_ifname(drvr, ifidx), id, prot->reqid);
254                 ret = -EINVAL;
255                 goto done;
256         }
257
258         /* Check the ERROR flag */
259         if (flags & CDCF_IOC_ERROR) {
260                 ret = le32_to_cpu(msg->status);
261                 /* Cache error from dongle */
262                 drvr->dongle_error = ret;
263         }
264
265 done:
266         return ret;
267 }
268
269 int
270 brcmf_proto_ioctl(struct brcmf_pub *drvr, int ifidx, struct brcmf_ioctl *ioc,
271                   int len)
272 {
273         struct brcmf_proto *prot = drvr->prot;
274         int ret = -1;
275
276         if (drvr->busstate == BRCMF_BUS_DOWN) {
277                 brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n");
278                 return ret;
279         }
280         brcmf_os_proto_block(drvr);
281
282         brcmf_dbg(TRACE, "Enter\n");
283
284         if (len > BRCMF_C_IOCTL_MAXLEN)
285                 goto done;
286
287         if (prot->pending == true) {
288                 brcmf_dbg(TRACE, "CDC packet is pending!!!! cmd=0x%x (%lu) lastcmd=0x%x (%lu)\n",
289                           ioc->cmd, (unsigned long)ioc->cmd, prot->lastcmd,
290                           (unsigned long)prot->lastcmd);
291                 if ((ioc->cmd == BRCMF_C_SET_VAR) ||
292                     (ioc->cmd == BRCMF_C_GET_VAR))
293                         brcmf_dbg(TRACE, "iovar cmd=%s\n", (char *)ioc->buf);
294
295                 goto done;
296         }
297
298         prot->pending = true;
299         prot->lastcmd = ioc->cmd;
300         if (ioc->set)
301                 ret = brcmf_proto_cdc_set_ioctl(drvr, ifidx, ioc->cmd,
302                                                 ioc->buf, len);
303         else {
304                 ret = brcmf_proto_cdc_query_ioctl(drvr, ifidx, ioc->cmd,
305                                                   ioc->buf, len);
306                 if (ret > 0)
307                         ioc->used = ret - sizeof(struct brcmf_proto_cdc_ioctl);
308         }
309
310         /* Too many programs assume ioctl() returns 0 on success */
311         if (ret >= 0)
312                 ret = 0;
313         else {
314                 struct brcmf_proto_cdc_ioctl *msg = &prot->msg;
315                 /* len == needed when set/query fails from dongle */
316                 ioc->needed = le32_to_cpu(msg->len);
317         }
318
319         /* Intercept the wme_dp ioctl here */
320         if (!ret && ioc->cmd == BRCMF_C_SET_VAR &&
321             !strcmp(ioc->buf, "wme_dp")) {
322                 int slen;
323                 __le32 val = 0;
324
325                 slen = strlen("wme_dp") + 1;
326                 if (len >= (int)(slen + sizeof(int)))
327                         memcpy(&val, (char *)ioc->buf + slen, sizeof(int));
328                 drvr->wme_dp = (u8) le32_to_cpu(val);
329         }
330
331         prot->pending = false;
332
333 done:
334         brcmf_os_proto_unblock(drvr);
335
336         return ret;
337 }
338
339 static bool pkt_sum_needed(struct sk_buff *skb)
340 {
341         return skb->ip_summed == CHECKSUM_PARTIAL;
342 }
343
344 static void pkt_set_sum_good(struct sk_buff *skb, bool x)
345 {
346         skb->ip_summed = (x ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE);
347 }
348
349 void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,
350                          struct sk_buff *pktbuf)
351 {
352         struct brcmf_proto_bdc_header *h;
353
354         brcmf_dbg(TRACE, "Enter\n");
355
356         /* Push BDC header used to convey priority for buses that don't */
357
358         skb_push(pktbuf, BDC_HEADER_LEN);
359
360         h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
361
362         h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
363         if (pkt_sum_needed(pktbuf))
364                 h->flags |= BDC_FLAG_SUM_NEEDED;
365
366         h->priority = (pktbuf->priority & BDC_PRIORITY_MASK);
367         h->flags2 = 0;
368         h->rssi = 0;
369         BDC_SET_IF_IDX(h, ifidx);
370 }
371
372 int brcmf_proto_hdrpull(struct brcmf_pub *drvr, int *ifidx,
373                         struct sk_buff *pktbuf)
374 {
375         struct brcmf_proto_bdc_header *h;
376
377         brcmf_dbg(TRACE, "Enter\n");
378
379         /* Pop BDC header used to convey priority for buses that don't */
380
381         if (pktbuf->len < BDC_HEADER_LEN) {
382                 brcmf_dbg(ERROR, "rx data too short (%d < %d)\n",
383                           pktbuf->len, BDC_HEADER_LEN);
384                 return -EBADE;
385         }
386
387         h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
388
389         *ifidx = BDC_GET_IF_IDX(h);
390         if (*ifidx >= BRCMF_MAX_IFS) {
391                 brcmf_dbg(ERROR, "rx data ifnum out of range (%d)\n", *ifidx);
392                 return -EBADE;
393         }
394
395         if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) !=
396             BDC_PROTO_VER) {
397                 brcmf_dbg(ERROR, "%s: non-BDC packet received, flags 0x%x\n",
398                           brcmf_ifname(drvr, *ifidx), h->flags);
399                 return -EBADE;
400         }
401
402         if (h->flags & BDC_FLAG_SUM_GOOD) {
403                 brcmf_dbg(INFO, "%s: BDC packet received with good rx-csum, flags 0x%x\n",
404                           brcmf_ifname(drvr, *ifidx), h->flags);
405                 pkt_set_sum_good(pktbuf, true);
406         }
407
408         pktbuf->priority = h->priority & BDC_PRIORITY_MASK;
409
410         skb_pull(pktbuf, BDC_HEADER_LEN);
411
412         return 0;
413 }
414
415 int brcmf_proto_attach(struct brcmf_pub *drvr)
416 {
417         struct brcmf_proto *cdc;
418
419         cdc = kzalloc(sizeof(struct brcmf_proto), GFP_ATOMIC);
420         if (!cdc)
421                 goto fail;
422
423         /* ensure that the msg buf directly follows the cdc msg struct */
424         if ((unsigned long)(&cdc->msg + 1) != (unsigned long)cdc->buf) {
425                 brcmf_dbg(ERROR, "struct brcmf_proto is not correctly defined\n");
426                 goto fail;
427         }
428
429         drvr->prot = cdc;
430         drvr->hdrlen += BDC_HEADER_LEN;
431         drvr->maxctl = BRCMF_C_IOCTL_MAXLEN +
432                         sizeof(struct brcmf_proto_cdc_ioctl) + ROUND_UP_MARGIN;
433         return 0;
434
435 fail:
436         kfree(cdc);
437         return -ENOMEM;
438 }
439
440 /* ~NOTE~ What if another thread is waiting on the semaphore?  Holding it? */
441 void brcmf_proto_detach(struct brcmf_pub *drvr)
442 {
443         kfree(drvr->prot);
444         drvr->prot = NULL;
445 }
446
447 void brcmf_proto_dstats(struct brcmf_pub *drvr)
448 {
449         /* No stats from dongle added yet, copy bus stats */
450         drvr->dstats.tx_packets = drvr->tx_packets;
451         drvr->dstats.tx_errors = drvr->tx_errors;
452         drvr->dstats.rx_packets = drvr->rx_packets;
453         drvr->dstats.rx_errors = drvr->rx_errors;
454         drvr->dstats.rx_dropped = drvr->rx_dropped;
455         drvr->dstats.multicast = drvr->rx_multicast;
456         return;
457 }
458
459 int brcmf_proto_init(struct brcmf_pub *drvr)
460 {
461         int ret = 0;
462         char buf[128];
463
464         brcmf_dbg(TRACE, "Enter\n");
465
466         brcmf_os_proto_block(drvr);
467
468         /* Get the device MAC address */
469         strcpy(buf, "cur_etheraddr");
470         ret = brcmf_proto_cdc_query_ioctl(drvr, 0, BRCMF_C_GET_VAR,
471                                           buf, sizeof(buf));
472         if (ret < 0) {
473                 brcmf_os_proto_unblock(drvr);
474                 return ret;
475         }
476         memcpy(drvr->mac, buf, ETH_ALEN);
477
478         brcmf_os_proto_unblock(drvr);
479
480         ret = brcmf_c_preinit_ioctls(drvr);
481
482         /* Always assumes wl for now */
483         drvr->iswl = true;
484
485         return ret;
486 }
487
488 void brcmf_proto_stop(struct brcmf_pub *drvr)
489 {
490         /* Nothing to do for CDC */
491 }