staging: brcm80211: move sdio related variables to dhd_sdio.c
[pandora-kernel.git] / drivers / staging / brcm80211 / brcmfmac / dhd_linux.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/init.h>
18 #include <linux/kernel.h>
19 #include <linux/kthread.h>
20 #include <linux/slab.h>
21 #include <linux/skbuff.h>
22 #include <linux/netdevice.h>
23 #include <linux/etherdevice.h>
24 #include <linux/mmc/sdio_func.h>
25 #include <linux/random.h>
26 #include <linux/spinlock.h>
27 #include <linux/ethtool.h>
28 #include <linux/fcntl.h>
29 #include <linux/fs.h>
30 #include <linux/uaccess.h>
31 #include <linux/hardirq.h>
32 #include <linux/mutex.h>
33 #include <net/cfg80211.h>
34 #include <defs.h>
35 #include <brcmu_utils.h>
36 #include <brcmu_wifi.h>
37
38 #include "dhd.h"
39 #include "dhd_bus.h"
40 #include "dhd_proto.h"
41 #include "dhd_dbg.h"
42 #include "wl_cfg80211.h"
43 #include "bcmchip.h"
44
45 #if defined(CONFIG_PM_SLEEP)
46 #include <linux/suspend.h>
47 atomic_t brcmf_mmc_suspend;
48 #endif  /*  defined(CONFIG_PM_SLEEP) */
49
50 MODULE_AUTHOR("Broadcom Corporation");
51 MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac driver.");
52 MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards");
53 MODULE_LICENSE("Dual BSD/GPL");
54
55
56 /* Interface control information */
57 struct brcmf_if {
58         struct brcmf_info *info;        /* back pointer to brcmf_info */
59         /* OS/stack specifics */
60         struct net_device *net;
61         struct net_device_stats stats;
62         int idx;                /* iface idx in dongle */
63         int state;              /* interface state */
64         uint subunit;           /* subunit */
65         u8 mac_addr[ETH_ALEN];  /* assigned MAC address */
66         bool attached;          /* Delayed attachment when unset */
67         bool txflowcontrol;     /* Per interface flow control indicator */
68         char name[IFNAMSIZ];    /* linux interface name */
69 };
70
71 /* Local private structure (extension of pub) */
72 struct brcmf_info {
73         struct brcmf_pub pub;
74
75         /* OS/stack specifics */
76         struct brcmf_if *iflist[BRCMF_MAX_IFS];
77
78         struct mutex proto_block;
79         wait_queue_head_t ioctl_resp_wait;
80
81         /* Thread to issue ioctl for multicast */
82         struct task_struct *sysioc_tsk;
83         struct semaphore sysioc_sem;
84         bool set_multicast;
85         bool set_macaddress;
86         u8 macvalue[ETH_ALEN];
87         atomic_t pend_8021x_cnt;
88 };
89
90 /* Error bits */
91 module_param(brcmf_msg_level, int, 0);
92
93 /* Spawn a thread for system ioctls (set mac, set mcast) */
94 uint brcmf_sysioc = true;
95 module_param(brcmf_sysioc, uint, 0);
96
97 /* ARP offload agent mode : Enable ARP Host Auto-Reply
98 and ARP Peer Auto-Reply */
99 uint brcmf_arp_mode = 0xb;
100 module_param(brcmf_arp_mode, uint, 0);
101
102 /* ARP offload enable */
103 uint brcmf_arp_enable = true;
104 module_param(brcmf_arp_enable, uint, 0);
105
106 /* Global Pkt filter enable control */
107 uint brcmf_pkt_filter_enable = true;
108 module_param(brcmf_pkt_filter_enable, uint, 0);
109
110 /*  Pkt filter init setup */
111 uint brcmf_pkt_filter_init;
112 module_param(brcmf_pkt_filter_init, uint, 0);
113
114 /* Pkt filter mode control */
115 uint brcmf_master_mode = true;
116 module_param(brcmf_master_mode, uint, 0);
117
118 /* Contorl fw roaming */
119 uint brcmf_roam = 1;
120
121 /* Control radio state */
122 uint brcmf_radio_up = 1;
123
124 /* Network inteface name */
125 char iface_name[IFNAMSIZ] = "wlan";
126 module_param_string(iface_name, iface_name, IFNAMSIZ, 0);
127
128 /* The following are specific to the SDIO dongle */
129
130 /* IOCTL response timeout */
131 int brcmf_ioctl_timeout_msec = IOCTL_RESP_TIMEOUT;
132
133 #ifdef SDTEST
134 /* Echo packet generator (pkts/s) */
135 uint brcmf_pktgen;
136 module_param(brcmf_pktgen, uint, 0);
137
138 /* Echo packet len (0 => sawtooth, max 2040) */
139 uint brcmf_pktgen_len;
140 module_param(brcmf_pktgen_len, uint, 0);
141 #endif
142
143 static int brcmf_toe_get(struct brcmf_info *drvr_priv, int idx, u32 *toe_ol);
144 static int brcmf_toe_set(struct brcmf_info *drvr_priv, int idx, u32 toe_ol);
145 static int brcmf_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata,
146                             struct brcmf_event_msg *event_ptr,
147                             void **data_ptr);
148
149 /*
150  * Generalized timeout mechanism.  Uses spin sleep with exponential
151  * back-off until
152  * the sleep time reaches one jiffy, then switches over to task delay.  Usage:
153  *
154  *      brcmf_timeout_start(&tmo, usec);
155  *      while (!brcmf_timeout_expired(&tmo))
156  *              if (poll_something())
157  *                      break;
158  *      if (brcmf_timeout_expired(&tmo))
159  *              fatal();
160  */
161
162 void brcmf_timeout_start(struct brcmf_timeout *tmo, uint usec)
163 {
164         tmo->limit = usec;
165         tmo->increment = 0;
166         tmo->elapsed = 0;
167         tmo->tick = 1000000 / HZ;
168 }
169
170 int brcmf_timeout_expired(struct brcmf_timeout *tmo)
171 {
172         /* Does nothing the first call */
173         if (tmo->increment == 0) {
174                 tmo->increment = 1;
175                 return 0;
176         }
177
178         if (tmo->elapsed >= tmo->limit)
179                 return 1;
180
181         /* Add the delay that's about to take place */
182         tmo->elapsed += tmo->increment;
183
184         if (tmo->increment < tmo->tick) {
185                 udelay(tmo->increment);
186                 tmo->increment *= 2;
187                 if (tmo->increment > tmo->tick)
188                         tmo->increment = tmo->tick;
189         } else {
190                 wait_queue_head_t delay_wait;
191                 DECLARE_WAITQUEUE(wait, current);
192                 int pending;
193                 init_waitqueue_head(&delay_wait);
194                 add_wait_queue(&delay_wait, &wait);
195                 set_current_state(TASK_INTERRUPTIBLE);
196                 schedule_timeout(1);
197                 pending = signal_pending(current);
198                 remove_wait_queue(&delay_wait, &wait);
199                 set_current_state(TASK_RUNNING);
200                 if (pending)
201                         return 1;       /* Interrupted */
202         }
203
204         return 0;
205 }
206
207 static int brcmf_net2idx(struct brcmf_info *drvr_priv, struct net_device *net)
208 {
209         int i = 0;
210
211         while (i < BRCMF_MAX_IFS) {
212                 if (drvr_priv->iflist[i] && (drvr_priv->iflist[i]->net == net))
213                         return i;
214                 i++;
215         }
216
217         return BRCMF_BAD_IF;
218 }
219
220 int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name)
221 {
222         int i = BRCMF_MAX_IFS;
223
224         if (name == NULL || *name == '\0')
225                 return 0;
226
227         while (--i > 0)
228                 if (drvr_priv->iflist[i]
229                     && !strncmp(drvr_priv->iflist[i]->name, name, IFNAMSIZ))
230                         break;
231
232         BRCMF_TRACE(("%s: return idx %d for \"%s\"\n", __func__, i, name));
233
234         return i;               /* default - the primary interface */
235 }
236
237 char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx)
238 {
239         struct brcmf_info *drvr_priv = drvr->info;
240
241         if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
242                 BRCMF_ERROR(("%s: ifidx %d out of range\n", __func__, ifidx));
243                 return "<if_bad>";
244         }
245
246         if (drvr_priv->iflist[ifidx] == NULL) {
247                 BRCMF_ERROR(("%s: null i/f %d\n", __func__, ifidx));
248                 return "<if_null>";
249         }
250
251         if (drvr_priv->iflist[ifidx]->net)
252                 return drvr_priv->iflist[ifidx]->net->name;
253
254         return "<if_none>";
255 }
256
257 static void _brcmf_set_multicast_list(struct brcmf_info *drvr_priv, int ifidx)
258 {
259         struct net_device *dev;
260         struct netdev_hw_addr *ha;
261         u32 allmulti, cnt;
262
263         struct brcmf_ioctl ioc;
264         char *buf, *bufp;
265         uint buflen;
266         int ret;
267
268         dev = drvr_priv->iflist[ifidx]->net;
269         cnt = netdev_mc_count(dev);
270
271         /* Determine initial value of allmulti flag */
272         allmulti = (dev->flags & IFF_ALLMULTI) ? true : false;
273
274         /* Send down the multicast list first. */
275
276         buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETH_ALEN);
277         bufp = buf = kmalloc(buflen, GFP_ATOMIC);
278         if (!bufp) {
279                 BRCMF_ERROR(("%s: out of memory for mcast_list, cnt %d\n",
280                              brcmf_ifname(&drvr_priv->pub, ifidx), cnt));
281                 return;
282         }
283
284         strcpy(bufp, "mcast_list");
285         bufp += strlen("mcast_list") + 1;
286
287         cnt = cpu_to_le32(cnt);
288         memcpy(bufp, &cnt, sizeof(cnt));
289         bufp += sizeof(cnt);
290
291         netdev_for_each_mc_addr(ha, dev) {
292                 if (!cnt)
293                         break;
294                 memcpy(bufp, ha->addr, ETH_ALEN);
295                 bufp += ETH_ALEN;
296                 cnt--;
297         }
298
299         memset(&ioc, 0, sizeof(ioc));
300         ioc.cmd = BRCMF_C_SET_VAR;
301         ioc.buf = buf;
302         ioc.len = buflen;
303         ioc.set = true;
304
305         ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len);
306         if (ret < 0) {
307                 BRCMF_ERROR(("%s: set mcast_list failed, cnt %d\n",
308                              brcmf_ifname(&drvr_priv->pub, ifidx), cnt));
309                 allmulti = cnt ? true : allmulti;
310         }
311
312         kfree(buf);
313
314         /* Now send the allmulti setting.  This is based on the setting in the
315          * net_device flags, but might be modified above to be turned on if we
316          * were trying to set some addresses and dongle rejected it...
317          */
318
319         buflen = sizeof("allmulti") + sizeof(allmulti);
320         buf = kmalloc(buflen, GFP_ATOMIC);
321         if (!buf) {
322                 BRCMF_ERROR(("%s: out of memory for allmulti\n",
323                              brcmf_ifname(&drvr_priv->pub, ifidx)));
324                 return;
325         }
326         allmulti = cpu_to_le32(allmulti);
327
328         if (!brcmu_mkiovar
329             ("allmulti", (void *)&allmulti, sizeof(allmulti), buf, buflen)) {
330                 BRCMF_ERROR(("%s: mkiovar failed for allmulti, datalen %d "
331                              "buflen %u\n",
332                              brcmf_ifname(&drvr_priv->pub, ifidx),
333                              (int)sizeof(allmulti), buflen));
334                 kfree(buf);
335                 return;
336         }
337
338         memset(&ioc, 0, sizeof(ioc));
339         ioc.cmd = BRCMF_C_SET_VAR;
340         ioc.buf = buf;
341         ioc.len = buflen;
342         ioc.set = true;
343
344         ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len);
345         if (ret < 0) {
346                 BRCMF_ERROR(("%s: set allmulti %d failed\n",
347                              brcmf_ifname(&drvr_priv->pub, ifidx),
348                              le32_to_cpu(allmulti)));
349         }
350
351         kfree(buf);
352
353         /* Finally, pick up the PROMISC flag as well, like the NIC
354                  driver does */
355
356         allmulti = (dev->flags & IFF_PROMISC) ? true : false;
357         allmulti = cpu_to_le32(allmulti);
358
359         memset(&ioc, 0, sizeof(ioc));
360         ioc.cmd = BRCMF_C_SET_PROMISC;
361         ioc.buf = &allmulti;
362         ioc.len = sizeof(allmulti);
363         ioc.set = true;
364
365         ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len);
366         if (ret < 0) {
367                 BRCMF_ERROR(("%s: set promisc %d failed\n",
368                              brcmf_ifname(&drvr_priv->pub, ifidx),
369                              le32_to_cpu(allmulti)));
370         }
371 }
372
373 static int _brcmf_set_mac_address(struct brcmf_info *drvr_priv, int ifidx, u8 *addr)
374 {
375         char buf[32];
376         struct brcmf_ioctl ioc;
377         int ret;
378
379         BRCMF_TRACE(("%s enter\n", __func__));
380         if (!brcmu_mkiovar
381             ("cur_etheraddr", (char *)addr, ETH_ALEN, buf, 32)) {
382                 BRCMF_ERROR(("%s: mkiovar failed for cur_etheraddr\n",
383                              brcmf_ifname(&drvr_priv->pub, ifidx)));
384                 return -1;
385         }
386         memset(&ioc, 0, sizeof(ioc));
387         ioc.cmd = BRCMF_C_SET_VAR;
388         ioc.buf = buf;
389         ioc.len = 32;
390         ioc.set = true;
391
392         ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len);
393         if (ret < 0)
394                 BRCMF_ERROR(("%s: set cur_etheraddr failed\n",
395                              brcmf_ifname(&drvr_priv->pub, ifidx)));
396         else
397                 memcpy(drvr_priv->iflist[ifidx]->net->dev_addr, addr, ETH_ALEN);
398
399         return ret;
400 }
401
402 #ifdef SOFTAP
403 static struct net_device *ap_net_dev;
404 #endif
405
406 /* Virtual interfaces only ((ifp && ifp->info && ifp->idx == true) */
407 static void brcmf_op_if(struct brcmf_if *ifp)
408 {
409         struct brcmf_info *drvr_priv;
410         int ret = 0, err = 0;
411
412         drvr_priv = ifp->info;
413
414         BRCMF_TRACE(("%s: idx %d, state %d\n", __func__, ifp->idx, ifp->state));
415
416         switch (ifp->state) {
417         case BRCMF_E_IF_ADD:
418                 /*
419                  * Delete the existing interface before overwriting it
420                  * in case we missed the BRCMF_E_IF_DEL event.
421                  */
422                 if (ifp->net != NULL) {
423                         BRCMF_ERROR(("%s: ERROR: netdev:%s already exists, "
424                                      "try free & unregister\n",
425                                      __func__, ifp->net->name));
426                         netif_stop_queue(ifp->net);
427                         unregister_netdev(ifp->net);
428                         free_netdev(ifp->net);
429                 }
430                 /* Allocate etherdev, including space for private structure */
431                 ifp->net = alloc_etherdev(sizeof(drvr_priv));
432                 if (!ifp->net) {
433                         BRCMF_ERROR(("%s: OOM - alloc_etherdev\n", __func__));
434                         ret = -ENOMEM;
435                 }
436                 if (ret == 0) {
437                         strcpy(ifp->net->name, ifp->name);
438                         memcpy(netdev_priv(ifp->net), &drvr_priv, sizeof(drvr_priv));
439                         err = brcmf_net_attach(&drvr_priv->pub, ifp->idx);
440                         if (err != 0) {
441                                 BRCMF_ERROR(("%s: brcmf_net_attach failed, "
442                                              "err %d\n",
443                                              __func__, err));
444                                 ret = -EOPNOTSUPP;
445                         } else {
446 #ifdef SOFTAP
447                                 /* semaphore that the soft AP CODE
448                                          waits on */
449                                 struct semaphore ap_eth_sema;
450
451                                 /* save ptr to wl0.1 netdev for use
452                                          in wl_iw.c  */
453                                 ap_net_dev = ifp->net;
454                                 /* signal to the SOFTAP 'sleeper' thread,
455                                          wl0.1 is ready */
456                                 up(&ap_eth_sema);
457 #endif
458                                 BRCMF_TRACE(("\n ==== pid:%x, net_device for "
459                                              "if:%s created ===\n\n",
460                                              current->pid, ifp->net->name));
461                                 ifp->state = 0;
462                         }
463                 }
464                 break;
465         case BRCMF_E_IF_DEL:
466                 if (ifp->net != NULL) {
467                         BRCMF_TRACE(("\n%s: got 'WLC_E_IF_DEL' state\n",
468                                      __func__));
469                         netif_stop_queue(ifp->net);
470                         unregister_netdev(ifp->net);
471                         ret = BRCMF_DEL_IF;     /* Make sure the free_netdev()
472                                                          is called */
473                 }
474                 break;
475         default:
476                 BRCMF_ERROR(("%s: bad op %d\n", __func__, ifp->state));
477                 break;
478         }
479
480         if (ret < 0) {
481                 if (ifp->net)
482                         free_netdev(ifp->net);
483
484                 drvr_priv->iflist[ifp->idx] = NULL;
485                 kfree(ifp);
486 #ifdef SOFTAP
487                 if (ifp->net == ap_net_dev)
488                         ap_net_dev = NULL;      /*  NULL  SOFTAP global
489                                                          wl0.1 as well */
490 #endif                          /*  SOFTAP */
491         }
492 }
493
494 static int _brcmf_sysioc_thread(void *data)
495 {
496         struct brcmf_info *drvr_priv = (struct brcmf_info *) data;
497         int i;
498 #ifdef SOFTAP
499         bool in_ap = false;
500 #endif
501
502         allow_signal(SIGTERM);
503
504         while (down_interruptible(&drvr_priv->sysioc_sem) == 0) {
505                 if (kthread_should_stop())
506                         break;
507                 for (i = 0; i < BRCMF_MAX_IFS; i++) {
508                         struct brcmf_if *ifentry = drvr_priv->iflist[i];
509                         if (ifentry) {
510 #ifdef SOFTAP
511                                 in_ap = (ap_net_dev != NULL);
512 #endif                          /* SOFTAP */
513                                 if (ifentry->state)
514                                         brcmf_op_if(ifentry);
515 #ifdef SOFTAP
516                                 if (drvr_priv->iflist[i] == NULL) {
517                                         BRCMF_TRACE(("\n\n %s: interface %d "
518                                                      "removed!\n", __func__,
519                                                      i));
520                                         continue;
521                                 }
522
523                                 if (in_ap && drvr_priv->set_macaddress) {
524                                         BRCMF_TRACE(("attempt to set MAC for"
525                                                      " %s in AP Mode,"
526                                                      " blocked.\n",
527                                                      ifentry->net->name));
528                                         drvr_priv->set_macaddress = false;
529                                         continue;
530                                 }
531
532                                 if (in_ap && drvr_priv->set_multicast) {
533                                         BRCMF_TRACE(("attempt to set MULTICAST "
534                                                      "list for %s in AP Mode, "
535                                                      "blocked.\n",
536                                                      ifentry->net->name));
537                                         drvr_priv->set_multicast = false;
538                                         continue;
539                                 }
540 #endif                          /* SOFTAP */
541                                 if (drvr_priv->set_multicast) {
542                                         drvr_priv->set_multicast = false;
543                                         _brcmf_set_multicast_list(drvr_priv, i);
544                                 }
545                                 if (drvr_priv->set_macaddress) {
546                                         drvr_priv->set_macaddress = false;
547                                         _brcmf_set_mac_address(drvr_priv, i,
548                                                 drvr_priv->macvalue);
549                                 }
550                         }
551                 }
552         }
553         return 0;
554 }
555
556 static int brcmf_netdev_set_mac_address(struct net_device *dev, void *addr)
557 {
558         int ret = 0;
559
560         struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(dev);
561         struct sockaddr *sa = (struct sockaddr *)addr;
562         int ifidx;
563
564         ifidx = brcmf_net2idx(drvr_priv, dev);
565         if (ifidx == BRCMF_BAD_IF)
566                 return -1;
567
568         memcpy(&drvr_priv->macvalue, sa->sa_data, ETH_ALEN);
569         drvr_priv->set_macaddress = true;
570         up(&drvr_priv->sysioc_sem);
571
572         return ret;
573 }
574
575 static void brcmf_netdev_set_multicast_list(struct net_device *dev)
576 {
577         struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(dev);
578         int ifidx;
579
580         ifidx = brcmf_net2idx(drvr_priv, dev);
581         if (ifidx == BRCMF_BAD_IF)
582                 return;
583
584         drvr_priv->set_multicast = true;
585         up(&drvr_priv->sysioc_sem);
586 }
587
588 int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx, struct sk_buff *pktbuf)
589 {
590         struct brcmf_info *drvr_priv = drvr->info;
591
592         /* Reject if down */
593         if (!drvr->up || (drvr->busstate == BRCMF_BUS_DOWN))
594                 return -ENODEV;
595
596         /* Update multicast statistic */
597         if (pktbuf->len >= ETH_ALEN) {
598                 u8 *pktdata = (u8 *) (pktbuf->data);
599                 struct ethhdr *eh = (struct ethhdr *)pktdata;
600
601                 if (is_multicast_ether_addr(eh->h_dest))
602                         drvr->tx_multicast++;
603                 if (ntohs(eh->h_proto) == ETH_P_PAE)
604                         atomic_inc(&drvr_priv->pend_8021x_cnt);
605         }
606
607         /* If the protocol uses a data header, apply it */
608         brcmf_proto_hdrpush(drvr, ifidx, pktbuf);
609
610         /* Use bus module to send data frame */
611         return brcmf_sdbrcm_bus_txdata(drvr->bus, pktbuf);
612 }
613
614 static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *net)
615 {
616         int ret;
617         struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net);
618         int ifidx;
619
620         BRCMF_TRACE(("%s: Enter\n", __func__));
621
622         /* Reject if down */
623         if (!drvr_priv->pub.up || (drvr_priv->pub.busstate == BRCMF_BUS_DOWN)) {
624                 BRCMF_ERROR(("%s: xmit rejected pub.up=%d busstate=%d\n",
625                              __func__, drvr_priv->pub.up,
626                              drvr_priv->pub.busstate));
627                 netif_stop_queue(net);
628                 return -ENODEV;
629         }
630
631         ifidx = brcmf_net2idx(drvr_priv, net);
632         if (ifidx == BRCMF_BAD_IF) {
633                 BRCMF_ERROR(("%s: bad ifidx %d\n", __func__, ifidx));
634                 netif_stop_queue(net);
635                 return -ENODEV;
636         }
637
638         /* Make sure there's enough room for any header */
639         if (skb_headroom(skb) < drvr_priv->pub.hdrlen) {
640                 struct sk_buff *skb2;
641
642                 BRCMF_INFO(("%s: insufficient headroom\n",
643                             brcmf_ifname(&drvr_priv->pub, ifidx)));
644                 drvr_priv->pub.tx_realloc++;
645                 skb2 = skb_realloc_headroom(skb, drvr_priv->pub.hdrlen);
646                 dev_kfree_skb(skb);
647                 skb = skb2;
648                 if (skb == NULL) {
649                         BRCMF_ERROR(("%s: skb_realloc_headroom failed\n",
650                                      brcmf_ifname(&drvr_priv->pub, ifidx)));
651                         ret = -ENOMEM;
652                         goto done;
653                 }
654         }
655
656         ret = brcmf_sendpkt(&drvr_priv->pub, ifidx, skb);
657
658 done:
659         if (ret)
660                 drvr_priv->pub.dstats.tx_dropped++;
661         else
662                 drvr_priv->pub.tx_packets++;
663
664         /* Return ok: we always eat the packet */
665         return 0;
666 }
667
668 void brcmf_txflowcontrol(struct brcmf_pub *drvr, int ifidx, bool state)
669 {
670         struct net_device *net;
671         struct brcmf_info *drvr_priv = drvr->info;
672
673         BRCMF_TRACE(("%s: Enter\n", __func__));
674
675         drvr->txoff = state;
676         net = drvr_priv->iflist[ifidx]->net;
677         if (state == ON)
678                 netif_stop_queue(net);
679         else
680                 netif_wake_queue(net);
681 }
682
683 void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx, struct sk_buff *skb,
684                   int numpkt)
685 {
686         struct brcmf_info *drvr_priv = drvr->info;
687         unsigned char *eth;
688         uint len;
689         void *data;
690         struct sk_buff *pnext, *save_pktbuf;
691         int i;
692         struct brcmf_if *ifp;
693         struct brcmf_event_msg event;
694
695         BRCMF_TRACE(("%s: Enter\n", __func__));
696
697         save_pktbuf = skb;
698
699         for (i = 0; skb && i < numpkt; i++, skb = pnext) {
700
701                 pnext = skb->next;
702                 skb->next = NULL;
703
704                 /* Get the protocol, maintain skb around eth_type_trans()
705                  * The main reason for this hack is for the limitation of
706                  * Linux 2.4 where 'eth_type_trans' uses the
707                  * 'net->hard_header_len'
708                  * to perform skb_pull inside vs ETH_HLEN. Since to avoid
709                  * coping of the packet coming from the network stack to add
710                  * BDC, Hardware header etc, during network interface
711                  * registration
712                  * we set the 'net->hard_header_len' to ETH_HLEN + extra space
713                  * required
714                  * for BDC, Hardware header etc. and not just the ETH_HLEN
715                  */
716                 eth = skb->data;
717                 len = skb->len;
718
719                 ifp = drvr_priv->iflist[ifidx];
720                 if (ifp == NULL)
721                         ifp = drvr_priv->iflist[0];
722
723                 skb->dev = ifp->net;
724                 skb->protocol = eth_type_trans(skb, skb->dev);
725
726                 if (skb->pkt_type == PACKET_MULTICAST)
727                         drvr_priv->pub.rx_multicast++;
728
729                 skb->data = eth;
730                 skb->len = len;
731
732                 /* Strip header, count, deliver upward */
733                 skb_pull(skb, ETH_HLEN);
734
735                 /* Process special event packets and then discard them */
736                 if (ntohs(skb->protocol) == ETH_P_LINK_CTL)
737                         brcmf_host_event(drvr_priv, &ifidx,
738                                           skb_mac_header(skb),
739                                           &event, &data);
740
741                 if (drvr_priv->iflist[ifidx] &&
742                     !drvr_priv->iflist[ifidx]->state)
743                         ifp = drvr_priv->iflist[ifidx];
744
745                 if (ifp->net)
746                         ifp->net->last_rx = jiffies;
747
748                 drvr->dstats.rx_bytes += skb->len;
749                 drvr->rx_packets++;     /* Local count */
750
751                 if (in_interrupt())
752                         netif_rx(skb);
753                 else
754                         /* If the receive is not processed inside an ISR,
755                          * the softirqd must be woken explicitly to service
756                          * the NET_RX_SOFTIRQ.  In 2.6 kernels, this is handled
757                          * by netif_rx_ni(), but in earlier kernels, we need
758                          * to do it manually.
759                          */
760                         netif_rx_ni(skb);
761         }
762 }
763
764 void brcmf_txcomplete(struct brcmf_pub *drvr, struct sk_buff *txp, bool success)
765 {
766         uint ifidx;
767         struct brcmf_info *drvr_priv = drvr->info;
768         struct ethhdr *eh;
769         u16 type;
770
771         brcmf_proto_hdrpull(drvr, &ifidx, txp);
772
773         eh = (struct ethhdr *)(txp->data);
774         type = ntohs(eh->h_proto);
775
776         if (type == ETH_P_PAE)
777                 atomic_dec(&drvr_priv->pend_8021x_cnt);
778
779 }
780
781 static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *net)
782 {
783         struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net);
784         struct brcmf_if *ifp;
785         int ifidx;
786
787         BRCMF_TRACE(("%s: Enter\n", __func__));
788
789         ifidx = brcmf_net2idx(drvr_priv, net);
790         if (ifidx == BRCMF_BAD_IF)
791                 return NULL;
792
793         ifp = drvr_priv->iflist[ifidx];
794
795         if (drvr_priv->pub.up)
796                 /* Use the protocol to get dongle stats */
797                 brcmf_proto_dstats(&drvr_priv->pub);
798
799         /* Copy dongle stats to net device stats */
800         ifp->stats.rx_packets = drvr_priv->pub.dstats.rx_packets;
801         ifp->stats.tx_packets = drvr_priv->pub.dstats.tx_packets;
802         ifp->stats.rx_bytes = drvr_priv->pub.dstats.rx_bytes;
803         ifp->stats.tx_bytes = drvr_priv->pub.dstats.tx_bytes;
804         ifp->stats.rx_errors = drvr_priv->pub.dstats.rx_errors;
805         ifp->stats.tx_errors = drvr_priv->pub.dstats.tx_errors;
806         ifp->stats.rx_dropped = drvr_priv->pub.dstats.rx_dropped;
807         ifp->stats.tx_dropped = drvr_priv->pub.dstats.tx_dropped;
808         ifp->stats.multicast = drvr_priv->pub.dstats.multicast;
809
810         return &ifp->stats;
811 }
812
813 /* Retrieve current toe component enables, which are kept
814          as a bitmap in toe_ol iovar */
815 static int brcmf_toe_get(struct brcmf_info *drvr_priv, int ifidx, u32 *toe_ol)
816 {
817         struct brcmf_ioctl ioc;
818         char buf[32];
819         int ret;
820
821         memset(&ioc, 0, sizeof(ioc));
822
823         ioc.cmd = BRCMF_C_GET_VAR;
824         ioc.buf = buf;
825         ioc.len = (uint) sizeof(buf);
826         ioc.set = false;
827
828         strcpy(buf, "toe_ol");
829         ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len);
830         if (ret < 0) {
831                 /* Check for older dongle image that doesn't support toe_ol */
832                 if (ret == -EIO) {
833                         BRCMF_ERROR(("%s: toe not supported by device\n",
834                                      brcmf_ifname(&drvr_priv->pub, ifidx)));
835                         return -EOPNOTSUPP;
836                 }
837
838                 BRCMF_INFO(("%s: could not get toe_ol: ret=%d\n",
839                             brcmf_ifname(&drvr_priv->pub, ifidx), ret));
840                 return ret;
841         }
842
843         memcpy(toe_ol, buf, sizeof(u32));
844         return 0;
845 }
846
847 /* Set current toe component enables in toe_ol iovar,
848          and set toe global enable iovar */
849 static int brcmf_toe_set(struct brcmf_info *drvr_priv, int ifidx, u32 toe_ol)
850 {
851         struct brcmf_ioctl ioc;
852         char buf[32];
853         int toe, ret;
854
855         memset(&ioc, 0, sizeof(ioc));
856
857         ioc.cmd = BRCMF_C_SET_VAR;
858         ioc.buf = buf;
859         ioc.len = (uint) sizeof(buf);
860         ioc.set = true;
861
862         /* Set toe_ol as requested */
863
864         strcpy(buf, "toe_ol");
865         memcpy(&buf[sizeof("toe_ol")], &toe_ol, sizeof(u32));
866
867         ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len);
868         if (ret < 0) {
869                 BRCMF_ERROR(("%s: could not set toe_ol: ret=%d\n",
870                              brcmf_ifname(&drvr_priv->pub, ifidx), ret));
871                 return ret;
872         }
873
874         /* Enable toe globally only if any components are enabled. */
875
876         toe = (toe_ol != 0);
877
878         strcpy(buf, "toe");
879         memcpy(&buf[sizeof("toe")], &toe, sizeof(u32));
880
881         ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len);
882         if (ret < 0) {
883                 BRCMF_ERROR(("%s: could not set toe: ret=%d\n",
884                              brcmf_ifname(&drvr_priv->pub, ifidx), ret));
885                 return ret;
886         }
887
888         return 0;
889 }
890
891 static void brcmf_ethtool_get_drvinfo(struct net_device *net,
892                                     struct ethtool_drvinfo *info)
893 {
894         struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net);
895
896         sprintf(info->driver, KBUILD_MODNAME);
897         sprintf(info->version, "%lu", drvr_priv->pub.drv_version);
898         sprintf(info->fw_version, "%s", BCM4329_FW_NAME);
899         sprintf(info->bus_info, "%s",
900                 dev_name(&brcmf_cfg80211_get_sdio_func()->dev));
901 }
902
903 struct ethtool_ops brcmf_ethtool_ops = {
904         .get_drvinfo = brcmf_ethtool_get_drvinfo
905 };
906
907 static int brcmf_ethtool(struct brcmf_info *drvr_priv, void *uaddr)
908 {
909         struct ethtool_drvinfo info;
910         char drvname[sizeof(info.driver)];
911         u32 cmd;
912         struct ethtool_value edata;
913         u32 toe_cmpnt, csum_dir;
914         int ret;
915
916         BRCMF_TRACE(("%s: Enter\n", __func__));
917
918         /* all ethtool calls start with a cmd word */
919         if (copy_from_user(&cmd, uaddr, sizeof(u32)))
920                 return -EFAULT;
921
922         switch (cmd) {
923         case ETHTOOL_GDRVINFO:
924                 /* Copy out any request driver name */
925                 if (copy_from_user(&info, uaddr, sizeof(info)))
926                         return -EFAULT;
927                 strncpy(drvname, info.driver, sizeof(info.driver));
928                 drvname[sizeof(info.driver) - 1] = '\0';
929
930                 /* clear struct for return */
931                 memset(&info, 0, sizeof(info));
932                 info.cmd = cmd;
933
934                 /* if requested, identify ourselves */
935                 if (strcmp(drvname, "?dhd") == 0) {
936                         sprintf(info.driver, "dhd");
937                         strcpy(info.version, BRCMF_VERSION_STR);
938                 }
939
940                 /* otherwise, require dongle to be up */
941                 else if (!drvr_priv->pub.up) {
942                         BRCMF_ERROR(("%s: dongle is not up\n", __func__));
943                         return -ENODEV;
944                 }
945
946                 /* finally, report dongle driver type */
947                 else if (drvr_priv->pub.iswl)
948                         sprintf(info.driver, "wl");
949                 else
950                         sprintf(info.driver, "xx");
951
952                 sprintf(info.version, "%lu", drvr_priv->pub.drv_version);
953                 if (copy_to_user(uaddr, &info, sizeof(info)))
954                         return -EFAULT;
955                 BRCMF_CTL(("%s: given %*s, returning %s\n", __func__,
956                            (int)sizeof(drvname), drvname, info.driver));
957                 break;
958
959                 /* Get toe offload components from dongle */
960         case ETHTOOL_GRXCSUM:
961         case ETHTOOL_GTXCSUM:
962                 ret = brcmf_toe_get(drvr_priv, 0, &toe_cmpnt);
963                 if (ret < 0)
964                         return ret;
965
966                 csum_dir =
967                     (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
968
969                 edata.cmd = cmd;
970                 edata.data = (toe_cmpnt & csum_dir) ? 1 : 0;
971
972                 if (copy_to_user(uaddr, &edata, sizeof(edata)))
973                         return -EFAULT;
974                 break;
975
976                 /* Set toe offload components in dongle */
977         case ETHTOOL_SRXCSUM:
978         case ETHTOOL_STXCSUM:
979                 if (copy_from_user(&edata, uaddr, sizeof(edata)))
980                         return -EFAULT;
981
982                 /* Read the current settings, update and write back */
983                 ret = brcmf_toe_get(drvr_priv, 0, &toe_cmpnt);
984                 if (ret < 0)
985                         return ret;
986
987                 csum_dir =
988                     (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
989
990                 if (edata.data != 0)
991                         toe_cmpnt |= csum_dir;
992                 else
993                         toe_cmpnt &= ~csum_dir;
994
995                 ret = brcmf_toe_set(drvr_priv, 0, toe_cmpnt);
996                 if (ret < 0)
997                         return ret;
998
999                 /* If setting TX checksum mode, tell Linux the new mode */
1000                 if (cmd == ETHTOOL_STXCSUM) {
1001                         if (edata.data)
1002                                 drvr_priv->iflist[0]->net->features |=
1003                                     NETIF_F_IP_CSUM;
1004                         else
1005                                 drvr_priv->iflist[0]->net->features &=
1006                                     ~NETIF_F_IP_CSUM;
1007                 }
1008
1009                 break;
1010
1011         default:
1012                 return -EOPNOTSUPP;
1013         }
1014
1015         return 0;
1016 }
1017
1018 static int brcmf_netdev_ioctl_entry(struct net_device *net, struct ifreq *ifr,
1019                                     int cmd)
1020 {
1021         struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net);
1022         struct brcmf_c_ioctl ioc;
1023         int bcmerror = 0;
1024         int buflen = 0;
1025         void *buf = NULL;
1026         uint driver = 0;
1027         int ifidx;
1028         bool is_set_key_cmd;
1029
1030         ifidx = brcmf_net2idx(drvr_priv, net);
1031         BRCMF_TRACE(("%s: ifidx %d, cmd 0x%04x\n", __func__, ifidx, cmd));
1032
1033         if (ifidx == BRCMF_BAD_IF)
1034                 return -1;
1035
1036         if (cmd == SIOCETHTOOL)
1037                 return brcmf_ethtool(drvr_priv, (void *)ifr->ifr_data);
1038
1039         if (cmd != SIOCDEVPRIVATE)
1040                 return -EOPNOTSUPP;
1041
1042         memset(&ioc, 0, sizeof(ioc));
1043
1044         /* Copy the ioc control structure part of ioctl request */
1045         if (copy_from_user(&ioc, ifr->ifr_data, sizeof(struct brcmf_ioctl))) {
1046                 bcmerror = -EINVAL;
1047                 goto done;
1048         }
1049
1050         /* Copy out any buffer passed */
1051         if (ioc.buf) {
1052                 buflen = min_t(int, ioc.len, BRCMF_IOCTL_MAXLEN);
1053                 /* optimization for direct ioctl calls from kernel */
1054                 /*
1055                    if (segment_eq(get_fs(), KERNEL_DS)) {
1056                    buf = ioc.buf;
1057                    } else {
1058                  */
1059                 {
1060                         buf = kmalloc(buflen, GFP_ATOMIC);
1061                         if (!buf) {
1062                                 bcmerror = -ENOMEM;
1063                                 goto done;
1064                         }
1065                         if (copy_from_user(buf, ioc.buf, buflen)) {
1066                                 bcmerror = -EINVAL;
1067                                 goto done;
1068                         }
1069                 }
1070         }
1071
1072         /* To differentiate read 4 more byes */
1073         if ((copy_from_user(&driver, (char *)ifr->ifr_data +
1074                             sizeof(struct brcmf_ioctl), sizeof(uint)) != 0)) {
1075                 bcmerror = -EINVAL;
1076                 goto done;
1077         }
1078
1079         if (!capable(CAP_NET_ADMIN)) {
1080                 bcmerror = -EPERM;
1081                 goto done;
1082         }
1083
1084         /* check for local brcmf ioctl and handle it */
1085         if (driver == BRCMF_IOCTL_MAGIC) {
1086                 bcmerror = brcmf_c_ioctl((void *)&drvr_priv->pub, &ioc, buf, buflen);
1087                 if (bcmerror)
1088                         drvr_priv->pub.bcmerror = bcmerror;
1089                 goto done;
1090         }
1091
1092         /* send to dongle (must be up, and wl) */
1093         if ((drvr_priv->pub.busstate != BRCMF_BUS_DATA)) {
1094                 BRCMF_ERROR(("%s DONGLE_DOWN,__func__\n", __func__));
1095                 bcmerror = -EIO;
1096                 goto done;
1097         }
1098
1099         if (!drvr_priv->pub.iswl) {
1100                 bcmerror = -EIO;
1101                 goto done;
1102         }
1103
1104         /*
1105          * Intercept BRCMF_C_SET_KEY IOCTL - serialize M4 send and
1106          * set key IOCTL to prevent M4 encryption.
1107          */
1108         is_set_key_cmd = ((ioc.cmd == BRCMF_C_SET_KEY) ||
1109                           ((ioc.cmd == BRCMF_C_SET_VAR) &&
1110                            !(strncmp("wsec_key", ioc.buf, 9))) ||
1111                           ((ioc.cmd == BRCMF_C_SET_VAR) &&
1112                            !(strncmp("bsscfg:wsec_key", ioc.buf, 15))));
1113         if (is_set_key_cmd)
1114                 brcmf_netdev_wait_pend8021x(net);
1115
1116         bcmerror =
1117             brcmf_proto_ioctl(&drvr_priv->pub, ifidx, (struct brcmf_ioctl *)&ioc,
1118                               buf, buflen);
1119
1120 done:
1121         if (!bcmerror && buf && ioc.buf) {
1122                 if (copy_to_user(ioc.buf, buf, buflen))
1123                         bcmerror = -EFAULT;
1124         }
1125
1126         kfree(buf);
1127
1128         if (bcmerror > 0)
1129                 bcmerror = 0;
1130
1131         return bcmerror;
1132 }
1133
1134 static int brcmf_netdev_stop(struct net_device *net)
1135 {
1136 #if !defined(IGNORE_ETH0_DOWN)
1137         struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net);
1138
1139         BRCMF_TRACE(("%s: Enter\n", __func__));
1140         brcmf_cfg80211_down();
1141         if (drvr_priv->pub.up == 0)
1142                 return 0;
1143
1144         /* Set state and stop OS transmissions */
1145         drvr_priv->pub.up = 0;
1146         netif_stop_queue(net);
1147 #else
1148         BRCMF_ERROR(("BYPASS %s:due to BRCM compilation: under investigation\n",
1149                      __func__));
1150 #endif                          /* !defined(IGNORE_ETH0_DOWN) */
1151
1152         return 0;
1153 }
1154
1155 static int brcmf_netdev_open(struct net_device *net)
1156 {
1157         struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net);
1158         u32 toe_ol;
1159         int ifidx = brcmf_net2idx(drvr_priv, net);
1160         s32 ret = 0;
1161
1162         BRCMF_TRACE(("%s: ifidx %d\n", __func__, ifidx));
1163
1164         if (ifidx == 0) {       /* do it only for primary eth0 */
1165
1166                 /* try to bring up bus */
1167                 ret = brcmf_bus_start(&drvr_priv->pub);
1168                 if (ret != 0) {
1169                         BRCMF_ERROR(("%s: failed with code %d\n",
1170                                      __func__, ret));
1171                         return -1;
1172                 }
1173                 atomic_set(&drvr_priv->pend_8021x_cnt, 0);
1174
1175                 memcpy(net->dev_addr, drvr_priv->pub.mac, ETH_ALEN);
1176
1177                 /* Get current TOE mode from dongle */
1178                 if (brcmf_toe_get(drvr_priv, ifidx, &toe_ol) >= 0
1179                     && (toe_ol & TOE_TX_CSUM_OL) != 0)
1180                         drvr_priv->iflist[ifidx]->net->features |=
1181                                 NETIF_F_IP_CSUM;
1182                 else
1183                         drvr_priv->iflist[ifidx]->net->features &=
1184                                 ~NETIF_F_IP_CSUM;
1185         }
1186         /* Allow transmit calls */
1187         netif_start_queue(net);
1188         drvr_priv->pub.up = 1;
1189         if (unlikely(brcmf_cfg80211_up())) {
1190                 BRCMF_ERROR(("%s: failed to bring up cfg80211\n",
1191                              __func__));
1192                 return -1;
1193         }
1194
1195         return ret;
1196 }
1197
1198 int
1199 brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, void *handle, char *name,
1200            u8 *mac_addr, u32 flags, u8 bssidx)
1201 {
1202         struct brcmf_if *ifp;
1203
1204         BRCMF_TRACE(("%s: idx %d, handle->%p\n", __func__, ifidx, handle));
1205
1206         ifp = drvr_priv->iflist[ifidx];
1207         if (!ifp) {
1208                 ifp = kmalloc(sizeof(struct brcmf_if), GFP_ATOMIC);
1209                 if (!ifp) {
1210                         BRCMF_ERROR(("%s: OOM - struct brcmf_if\n", __func__));
1211                         return -ENOMEM;
1212                 }
1213         }
1214
1215         memset(ifp, 0, sizeof(struct brcmf_if));
1216         ifp->info = drvr_priv;
1217         drvr_priv->iflist[ifidx] = ifp;
1218         strlcpy(ifp->name, name, IFNAMSIZ);
1219         if (mac_addr != NULL)
1220                 memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN);
1221
1222         if (handle == NULL) {
1223                 ifp->state = BRCMF_E_IF_ADD;
1224                 ifp->idx = ifidx;
1225                 up(&drvr_priv->sysioc_sem);
1226         } else
1227                 ifp->net = (struct net_device *)handle;
1228
1229         return 0;
1230 }
1231
1232 void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx)
1233 {
1234         struct brcmf_if *ifp;
1235
1236         BRCMF_TRACE(("%s: idx %d\n", __func__, ifidx));
1237
1238         ifp = drvr_priv->iflist[ifidx];
1239         if (!ifp) {
1240                 BRCMF_ERROR(("%s: Null interface\n", __func__));
1241                 return;
1242         }
1243
1244         ifp->state = BRCMF_E_IF_DEL;
1245         ifp->idx = ifidx;
1246         up(&drvr_priv->sysioc_sem);
1247 }
1248
1249 struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, uint bus_hdrlen)
1250 {
1251         struct brcmf_info *drvr_priv = NULL;
1252         struct net_device *net;
1253
1254         BRCMF_TRACE(("%s: Enter\n", __func__));
1255
1256         /* Allocate etherdev, including space for private structure */
1257         net = alloc_etherdev(sizeof(drvr_priv));
1258         if (!net) {
1259                 BRCMF_ERROR(("%s: OOM - alloc_etherdev\n", __func__));
1260                 goto fail;
1261         }
1262
1263         /* Allocate primary brcmf_info */
1264         drvr_priv = kzalloc(sizeof(struct brcmf_info), GFP_ATOMIC);
1265         if (!drvr_priv) {
1266                 BRCMF_ERROR(("%s: OOM - alloc brcmf_info\n", __func__));
1267                 goto fail;
1268         }
1269
1270         /*
1271          * Save the brcmf_info into the priv
1272          */
1273         memcpy(netdev_priv(net), &drvr_priv, sizeof(drvr_priv));
1274
1275         /* Set network interface name if it was provided as module parameter */
1276         if (iface_name[0]) {
1277                 int len;
1278                 char ch;
1279                 strncpy(net->name, iface_name, IFNAMSIZ);
1280                 net->name[IFNAMSIZ - 1] = 0;
1281                 len = strlen(net->name);
1282                 ch = net->name[len - 1];
1283                 if ((ch > '9' || ch < '0') && (len < IFNAMSIZ - 2))
1284                         strcat(net->name, "%d");
1285         }
1286
1287         if (brcmf_add_if(drvr_priv, 0, (void *)net, net->name, NULL, 0, 0) ==
1288             BRCMF_BAD_IF)
1289                 goto fail;
1290
1291         net->netdev_ops = NULL;
1292         mutex_init(&drvr_priv->proto_block);
1293         /* Initialize other structure content */
1294         init_waitqueue_head(&drvr_priv->ioctl_resp_wait);
1295
1296         /* Link to info module */
1297         drvr_priv->pub.info = drvr_priv;
1298
1299         /* Link to bus module */
1300         drvr_priv->pub.bus = bus;
1301         drvr_priv->pub.hdrlen = bus_hdrlen;
1302
1303         /* Attach and link in the protocol */
1304         if (brcmf_proto_attach(&drvr_priv->pub) != 0) {
1305                 BRCMF_ERROR(("brcmf_prot_attach failed\n"));
1306                 goto fail;
1307         }
1308
1309         /* Attach and link in the cfg80211 */
1310         if (unlikely(brcmf_cfg80211_attach(net, &drvr_priv->pub))) {
1311                 BRCMF_ERROR(("wl_cfg80211_attach failed\n"));
1312                 goto fail;
1313         }
1314
1315         if (brcmf_sysioc) {
1316                 sema_init(&drvr_priv->sysioc_sem, 0);
1317                 drvr_priv->sysioc_tsk = kthread_run(_brcmf_sysioc_thread, drvr_priv,
1318                                                 "_brcmf_sysioc");
1319                 if (IS_ERR(drvr_priv->sysioc_tsk)) {
1320                         printk(KERN_WARNING
1321                                 "_brcmf_sysioc thread failed to start\n");
1322                         drvr_priv->sysioc_tsk = NULL;
1323                 }
1324         } else
1325                 drvr_priv->sysioc_tsk = NULL;
1326
1327         /*
1328          * Save the brcmf_info into the priv
1329          */
1330         memcpy(netdev_priv(net), &drvr_priv, sizeof(drvr_priv));
1331
1332 #if defined(CONFIG_PM_SLEEP)
1333         atomic_set(&brcmf_mmc_suspend, false);
1334 #endif  /* defined(CONFIG_PM_SLEEP) */
1335         return &drvr_priv->pub;
1336
1337 fail:
1338         if (net)
1339                 free_netdev(net);
1340         if (drvr_priv)
1341                 brcmf_detach(&drvr_priv->pub);
1342
1343         return NULL;
1344 }
1345
1346 int brcmf_bus_start(struct brcmf_pub *drvr)
1347 {
1348         int ret = -1;
1349         struct brcmf_info *drvr_priv = drvr->info;
1350         /* Room for "event_msgs" + '\0' + bitvec */
1351         char iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
1352
1353         BRCMF_TRACE(("%s:\n", __func__));
1354
1355         /* Bring up the bus */
1356         ret = brcmf_sdbrcm_bus_init(&drvr_priv->pub, true);
1357         if (ret != 0) {
1358                 BRCMF_ERROR(("%s, brcmf_sdbrcm_bus_init failed %d\n", __func__,
1359                              ret));
1360                 return ret;
1361         }
1362
1363         /* If bus is not ready, can't come up */
1364         if (drvr_priv->pub.busstate != BRCMF_BUS_DATA) {
1365                 BRCMF_ERROR(("%s failed bus is not ready\n", __func__));
1366                 return -ENODEV;
1367         }
1368
1369         brcmu_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN,
1370                       iovbuf, sizeof(iovbuf));
1371         brcmf_proto_cdc_query_ioctl(drvr, 0, BRCMF_C_GET_VAR, iovbuf,
1372                                     sizeof(iovbuf));
1373         memcpy(drvr->eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
1374
1375         setbit(drvr->eventmask, BRCMF_E_SET_SSID);
1376         setbit(drvr->eventmask, BRCMF_E_PRUNE);
1377         setbit(drvr->eventmask, BRCMF_E_AUTH);
1378         setbit(drvr->eventmask, BRCMF_E_REASSOC);
1379         setbit(drvr->eventmask, BRCMF_E_REASSOC_IND);
1380         setbit(drvr->eventmask, BRCMF_E_DEAUTH_IND);
1381         setbit(drvr->eventmask, BRCMF_E_DISASSOC_IND);
1382         setbit(drvr->eventmask, BRCMF_E_DISASSOC);
1383         setbit(drvr->eventmask, BRCMF_E_JOIN);
1384         setbit(drvr->eventmask, BRCMF_E_ASSOC_IND);
1385         setbit(drvr->eventmask, BRCMF_E_PSK_SUP);
1386         setbit(drvr->eventmask, BRCMF_E_LINK);
1387         setbit(drvr->eventmask, BRCMF_E_NDIS_LINK);
1388         setbit(drvr->eventmask, BRCMF_E_MIC_ERROR);
1389         setbit(drvr->eventmask, BRCMF_E_PMKID_CACHE);
1390         setbit(drvr->eventmask, BRCMF_E_TXFAIL);
1391         setbit(drvr->eventmask, BRCMF_E_JOIN_START);
1392         setbit(drvr->eventmask, BRCMF_E_SCAN_COMPLETE);
1393
1394 /* enable dongle roaming event */
1395
1396         drvr->pktfilter_count = 1;
1397         /* Setup filter to allow only unicast */
1398         drvr->pktfilter[0] = "100 0 0 0 0x01 0x00";
1399
1400         /* Bus is ready, do any protocol initialization */
1401         ret = brcmf_proto_init(&drvr_priv->pub);
1402         if (ret < 0)
1403                 return ret;
1404
1405         return 0;
1406 }
1407
1408 static struct net_device_ops brcmf_netdev_ops_pri = {
1409         .ndo_open = brcmf_netdev_open,
1410         .ndo_stop = brcmf_netdev_stop,
1411         .ndo_get_stats = brcmf_netdev_get_stats,
1412         .ndo_do_ioctl = brcmf_netdev_ioctl_entry,
1413         .ndo_start_xmit = brcmf_netdev_start_xmit,
1414         .ndo_set_mac_address = brcmf_netdev_set_mac_address,
1415         .ndo_set_multicast_list = brcmf_netdev_set_multicast_list
1416 };
1417
1418 int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx)
1419 {
1420         struct brcmf_info *drvr_priv = drvr->info;
1421         struct net_device *net;
1422         u8 temp_addr[ETH_ALEN] = {
1423                 0x00, 0x90, 0x4c, 0x11, 0x22, 0x33};
1424
1425         BRCMF_TRACE(("%s: ifidx %d\n", __func__, ifidx));
1426
1427         net = drvr_priv->iflist[ifidx]->net;
1428         net->netdev_ops = &brcmf_netdev_ops_pri;
1429
1430         /*
1431          * We have to use the primary MAC for virtual interfaces
1432          */
1433         if (ifidx != 0) {
1434                 /* for virtual interfaces use the primary MAC  */
1435                 memcpy(temp_addr, drvr_priv->pub.mac, ETH_ALEN);
1436
1437         }
1438
1439         if (ifidx == 1) {
1440                 BRCMF_TRACE(("%s ACCESS POINT MAC:\n", __func__));
1441                 /*  ACCESSPOINT INTERFACE CASE */
1442                 temp_addr[0] |= 0X02;   /* set bit 2 ,
1443                          - Locally Administered address  */
1444
1445         }
1446         net->hard_header_len = ETH_HLEN + drvr_priv->pub.hdrlen;
1447         net->ethtool_ops = &brcmf_ethtool_ops;
1448
1449         drvr_priv->pub.rxsz = net->mtu + net->hard_header_len +
1450                                 drvr_priv->pub.hdrlen;
1451
1452         memcpy(net->dev_addr, temp_addr, ETH_ALEN);
1453
1454         if (register_netdev(net) != 0) {
1455                 BRCMF_ERROR(("%s: couldn't register the net device\n",
1456                              __func__));
1457                 goto fail;
1458         }
1459
1460         BRCMF_INFO(("%s: Broadcom Dongle Host Driver\n", net->name));
1461
1462         return 0;
1463
1464 fail:
1465         net->netdev_ops = NULL;
1466         return -EBADE;
1467 }
1468
1469 static void brcmf_bus_detach(struct brcmf_pub *drvr)
1470 {
1471         struct brcmf_info *drvr_priv;
1472
1473         BRCMF_TRACE(("%s: Enter\n", __func__));
1474
1475         if (drvr) {
1476                 drvr_priv = drvr->info;
1477                 if (drvr_priv) {
1478                         /* Stop the protocol module */
1479                         brcmf_proto_stop(&drvr_priv->pub);
1480
1481                         /* Stop the bus module */
1482                         brcmf_sdbrcm_bus_stop(drvr_priv->pub.bus, true);
1483                 }
1484         }
1485 }
1486
1487 void brcmf_detach(struct brcmf_pub *drvr)
1488 {
1489         struct brcmf_info *drvr_priv;
1490
1491         BRCMF_TRACE(("%s: Enter\n", __func__));
1492
1493         if (drvr) {
1494                 drvr_priv = drvr->info;
1495                 if (drvr_priv) {
1496                         struct brcmf_if *ifp;
1497                         int i;
1498
1499                         for (i = 1; i < BRCMF_MAX_IFS; i++)
1500                                 if (drvr_priv->iflist[i])
1501                                         brcmf_del_if(drvr_priv, i);
1502
1503                         ifp = drvr_priv->iflist[0];
1504                         if (ifp->net->netdev_ops == &brcmf_netdev_ops_pri) {
1505                                 brcmf_netdev_stop(ifp->net);
1506                                 unregister_netdev(ifp->net);
1507                         }
1508
1509                         if (drvr_priv->sysioc_tsk) {
1510                                 send_sig(SIGTERM, drvr_priv->sysioc_tsk, 1);
1511                                 kthread_stop(drvr_priv->sysioc_tsk);
1512                                 drvr_priv->sysioc_tsk = NULL;
1513                         }
1514
1515                         brcmf_bus_detach(drvr);
1516
1517                         if (drvr->prot)
1518                                 brcmf_proto_detach(drvr);
1519
1520                         brcmf_cfg80211_detach();
1521
1522                         free_netdev(ifp->net);
1523                         kfree(ifp);
1524                         kfree(drvr_priv);
1525                 }
1526         }
1527 }
1528
1529 static void __exit brcmf_module_cleanup(void)
1530 {
1531         BRCMF_TRACE(("%s: Enter\n", __func__));
1532
1533         brcmf_bus_unregister();
1534 }
1535
1536 static int __init brcmf_module_init(void)
1537 {
1538         int error;
1539
1540         BRCMF_TRACE(("%s: Enter\n", __func__));
1541
1542         error = brcmf_bus_register();
1543
1544         if (error) {
1545                 BRCMF_ERROR(("%s: brcmf_bus_register failed\n", __func__));
1546                 goto failed;
1547         }
1548         return 0;
1549
1550 failed:
1551         return -EINVAL;
1552 }
1553
1554 module_init(brcmf_module_init);
1555 module_exit(brcmf_module_cleanup);
1556
1557 int brcmf_os_proto_block(struct brcmf_pub *drvr)
1558 {
1559         struct brcmf_info *drvr_priv = drvr->info;
1560
1561         if (drvr_priv) {
1562                 mutex_lock(&drvr_priv->proto_block);
1563                 return 1;
1564         }
1565         return 0;
1566 }
1567
1568 int brcmf_os_proto_unblock(struct brcmf_pub *drvr)
1569 {
1570         struct brcmf_info *drvr_priv = drvr->info;
1571
1572         if (drvr_priv) {
1573                 mutex_unlock(&drvr_priv->proto_block);
1574                 return 1;
1575         }
1576
1577         return 0;
1578 }
1579
1580 unsigned int brcmf_os_get_ioctl_resp_timeout(void)
1581 {
1582         return (unsigned int)brcmf_ioctl_timeout_msec;
1583 }
1584
1585 void brcmf_os_set_ioctl_resp_timeout(unsigned int timeout_msec)
1586 {
1587         brcmf_ioctl_timeout_msec = (int)timeout_msec;
1588 }
1589
1590 int brcmf_os_ioctl_resp_wait(struct brcmf_pub *drvr, uint *condition,
1591                              bool *pending)
1592 {
1593         struct brcmf_info *drvr_priv = drvr->info;
1594         DECLARE_WAITQUEUE(wait, current);
1595         int timeout = brcmf_ioctl_timeout_msec;
1596
1597         /* Convert timeout in millsecond to jiffies */
1598         timeout = timeout * HZ / 1000;
1599
1600         /* Wait until control frame is available */
1601         add_wait_queue(&drvr_priv->ioctl_resp_wait, &wait);
1602         set_current_state(TASK_INTERRUPTIBLE);
1603
1604         while (!(*condition) && (!signal_pending(current) && timeout))
1605                 timeout = schedule_timeout(timeout);
1606
1607         if (signal_pending(current))
1608                 *pending = true;
1609
1610         set_current_state(TASK_RUNNING);
1611         remove_wait_queue(&drvr_priv->ioctl_resp_wait, &wait);
1612
1613         return timeout;
1614 }
1615
1616 int brcmf_os_ioctl_resp_wake(struct brcmf_pub *drvr)
1617 {
1618         struct brcmf_info *drvr_priv = drvr->info;
1619
1620         if (waitqueue_active(&drvr_priv->ioctl_resp_wait))
1621                 wake_up_interruptible(&drvr_priv->ioctl_resp_wait);
1622
1623         return 0;
1624 }
1625
1626 static int brcmf_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata,
1627                             struct brcmf_event_msg *event, void **data)
1628 {
1629         int bcmerror = 0;
1630
1631         bcmerror = brcmf_c_host_event(drvr_priv, ifidx, pktdata, event, data);
1632         if (bcmerror != 0)
1633                 return bcmerror;
1634
1635         if (drvr_priv->iflist[*ifidx]->net)
1636                 brcmf_cfg80211_event(drvr_priv->iflist[*ifidx]->net,
1637                                      event, *data);
1638
1639         return bcmerror;
1640 }
1641
1642 int brcmf_netdev_reset(struct net_device *dev, u8 flag)
1643 {
1644         struct brcmf_info *drvr_priv = *(struct brcmf_info **)netdev_priv(dev);
1645
1646         brcmf_bus_devreset(&drvr_priv->pub, flag);
1647
1648         return 1;
1649 }
1650
1651 static int brcmf_get_pend_8021x_cnt(struct brcmf_info *drvr_priv)
1652 {
1653         return atomic_read(&drvr_priv->pend_8021x_cnt);
1654 }
1655
1656 #define MAX_WAIT_FOR_8021X_TX   10
1657
1658 int brcmf_netdev_wait_pend8021x(struct net_device *dev)
1659 {
1660         struct brcmf_info *drvr_priv = *(struct brcmf_info **)netdev_priv(dev);
1661         int timeout = 10 * HZ / 1000;
1662         int ntimes = MAX_WAIT_FOR_8021X_TX;
1663         int pend = brcmf_get_pend_8021x_cnt(drvr_priv);
1664
1665         while (ntimes && pend) {
1666                 if (pend) {
1667                         set_current_state(TASK_INTERRUPTIBLE);
1668                         schedule_timeout(timeout);
1669                         set_current_state(TASK_RUNNING);
1670                         ntimes--;
1671                 }
1672                 pend = brcmf_get_pend_8021x_cnt(drvr_priv);
1673         }
1674         return pend;
1675 }
1676
1677 #ifdef BCMDBG
1678 int brcmf_write_to_file(struct brcmf_pub *drvr, u8 *buf, int size)
1679 {
1680         int ret = 0;
1681         struct file *fp;
1682         mm_segment_t old_fs;
1683         loff_t pos = 0;
1684
1685         /* change to KERNEL_DS address limit */
1686         old_fs = get_fs();
1687         set_fs(KERNEL_DS);
1688
1689         /* open file to write */
1690         fp = filp_open("/tmp/mem_dump", O_WRONLY | O_CREAT, 0640);
1691         if (!fp) {
1692                 BRCMF_ERROR(("%s: open file error\n", __func__));
1693                 ret = -1;
1694                 goto exit;
1695         }
1696
1697         /* Write buf to file */
1698         fp->f_op->write(fp, buf, size, &pos);
1699
1700 exit:
1701         /* free buf before return */
1702         kfree(buf);
1703         /* close file before return */
1704         if (fp)
1705                 filp_close(fp, current->files);
1706         /* restore previous address limit */
1707         set_fs(old_fs);
1708
1709         return ret;
1710 }
1711 #endif                          /* BCMDBG */