]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[karo-tx-linux.git] / drivers / net / wireless / 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/kernel.h>
18 #include <linux/etherdevice.h>
19 #include <linux/module.h>
20 #include <net/cfg80211.h>
21 #include <net/rtnetlink.h>
22 #include <brcmu_utils.h>
23 #include <brcmu_wifi.h>
24
25 #include "dhd.h"
26 #include "dhd_bus.h"
27 #include "dhd_proto.h"
28 #include "dhd_dbg.h"
29 #include "fwil_types.h"
30 #include "p2p.h"
31 #include "wl_cfg80211.h"
32 #include "fwil.h"
33
34 MODULE_AUTHOR("Broadcom Corporation");
35 MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
36 MODULE_SUPPORTED_DEVICE("Broadcom 802.11 WLAN fullmac cards");
37 MODULE_LICENSE("Dual BSD/GPL");
38
39 #define MAX_WAIT_FOR_8021X_TX           50      /* msecs */
40
41 /* Error bits */
42 int brcmf_msg_level;
43 module_param(brcmf_msg_level, int, 0);
44
45 /* P2P0 enable */
46 static int brcmf_p2p_enable;
47 #ifdef CONFIG_BRCMDBG
48 module_param_named(p2pon, brcmf_p2p_enable, int, 0);
49 MODULE_PARM_DESC(p2pon, "enable p2p management functionality");
50 #endif
51
52 char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx)
53 {
54         if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
55                 brcmf_err("ifidx %d out of range\n", ifidx);
56                 return "<if_bad>";
57         }
58
59         if (drvr->iflist[ifidx] == NULL) {
60                 brcmf_err("null i/f %d\n", ifidx);
61                 return "<if_null>";
62         }
63
64         if (drvr->iflist[ifidx]->ndev)
65                 return drvr->iflist[ifidx]->ndev->name;
66
67         return "<if_none>";
68 }
69
70 static void _brcmf_set_multicast_list(struct work_struct *work)
71 {
72         struct brcmf_if *ifp;
73         struct net_device *ndev;
74         struct netdev_hw_addr *ha;
75         u32 cmd_value, cnt;
76         __le32 cnt_le;
77         char *buf, *bufp;
78         u32 buflen;
79         s32 err;
80
81         ifp = container_of(work, struct brcmf_if, multicast_work);
82
83         brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
84
85         ndev = ifp->ndev;
86
87         /* Determine initial value of allmulti flag */
88         cmd_value = (ndev->flags & IFF_ALLMULTI) ? true : false;
89
90         /* Send down the multicast list first. */
91         cnt = netdev_mc_count(ndev);
92         buflen = sizeof(cnt) + (cnt * ETH_ALEN);
93         buf = kmalloc(buflen, GFP_ATOMIC);
94         if (!buf)
95                 return;
96         bufp = buf;
97
98         cnt_le = cpu_to_le32(cnt);
99         memcpy(bufp, &cnt_le, sizeof(cnt_le));
100         bufp += sizeof(cnt_le);
101
102         netdev_for_each_mc_addr(ha, ndev) {
103                 if (!cnt)
104                         break;
105                 memcpy(bufp, ha->addr, ETH_ALEN);
106                 bufp += ETH_ALEN;
107                 cnt--;
108         }
109
110         err = brcmf_fil_iovar_data_set(ifp, "mcast_list", buf, buflen);
111         if (err < 0) {
112                 brcmf_err("Setting mcast_list failed, %d\n", err);
113                 cmd_value = cnt ? true : cmd_value;
114         }
115
116         kfree(buf);
117
118         /*
119          * Now send the allmulti setting.  This is based on the setting in the
120          * net_device flags, but might be modified above to be turned on if we
121          * were trying to set some addresses and dongle rejected it...
122          */
123         err = brcmf_fil_iovar_int_set(ifp, "allmulti", cmd_value);
124         if (err < 0)
125                 brcmf_err("Setting allmulti failed, %d\n", err);
126
127         /*Finally, pick up the PROMISC flag */
128         cmd_value = (ndev->flags & IFF_PROMISC) ? true : false;
129         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PROMISC, cmd_value);
130         if (err < 0)
131                 brcmf_err("Setting BRCMF_C_SET_PROMISC failed, %d\n",
132                           err);
133 }
134
135 static void
136 _brcmf_set_mac_address(struct work_struct *work)
137 {
138         struct brcmf_if *ifp;
139         s32 err;
140
141         ifp = container_of(work, struct brcmf_if, setmacaddr_work);
142
143         brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
144
145         err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", ifp->mac_addr,
146                                        ETH_ALEN);
147         if (err < 0) {
148                 brcmf_err("Setting cur_etheraddr failed, %d\n", err);
149         } else {
150                 brcmf_dbg(TRACE, "MAC address updated to %pM\n",
151                           ifp->mac_addr);
152                 memcpy(ifp->ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
153         }
154 }
155
156 static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr)
157 {
158         struct brcmf_if *ifp = netdev_priv(ndev);
159         struct sockaddr *sa = (struct sockaddr *)addr;
160
161         memcpy(&ifp->mac_addr, sa->sa_data, ETH_ALEN);
162         schedule_work(&ifp->setmacaddr_work);
163         return 0;
164 }
165
166 static void brcmf_netdev_set_multicast_list(struct net_device *ndev)
167 {
168         struct brcmf_if *ifp = netdev_priv(ndev);
169
170         schedule_work(&ifp->multicast_work);
171 }
172
173 static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
174                                            struct net_device *ndev)
175 {
176         int ret;
177         struct brcmf_if *ifp = netdev_priv(ndev);
178         struct brcmf_pub *drvr = ifp->drvr;
179         struct ethhdr *eh;
180
181         brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
182
183         /* Can the device send data? */
184         if (drvr->bus_if->state != BRCMF_BUS_DATA) {
185                 brcmf_err("xmit rejected state=%d\n", drvr->bus_if->state);
186                 netif_stop_queue(ndev);
187                 dev_kfree_skb(skb);
188                 ret = -ENODEV;
189                 goto done;
190         }
191
192         if (!drvr->iflist[ifp->bssidx]) {
193                 brcmf_err("bad ifidx %d\n", ifp->bssidx);
194                 netif_stop_queue(ndev);
195                 dev_kfree_skb(skb);
196                 ret = -ENODEV;
197                 goto done;
198         }
199
200         /* Make sure there's enough room for any header */
201         if (skb_headroom(skb) < drvr->hdrlen) {
202                 struct sk_buff *skb2;
203
204                 brcmf_dbg(INFO, "%s: insufficient headroom\n",
205                           brcmf_ifname(drvr, ifp->bssidx));
206                 drvr->bus_if->tx_realloc++;
207                 skb2 = skb_realloc_headroom(skb, drvr->hdrlen);
208                 dev_kfree_skb(skb);
209                 skb = skb2;
210                 if (skb == NULL) {
211                         brcmf_err("%s: skb_realloc_headroom failed\n",
212                                   brcmf_ifname(drvr, ifp->bssidx));
213                         ret = -ENOMEM;
214                         goto done;
215                 }
216         }
217
218         /* validate length for ether packet */
219         if (skb->len < sizeof(*eh)) {
220                 ret = -EINVAL;
221                 dev_kfree_skb(skb);
222                 goto done;
223         }
224
225         /* handle ethernet header */
226         eh = (struct ethhdr *)(skb->data);
227         if (is_multicast_ether_addr(eh->h_dest))
228                 drvr->tx_multicast++;
229         if (ntohs(eh->h_proto) == ETH_P_PAE)
230                 atomic_inc(&ifp->pend_8021x_cnt);
231
232         /* If the protocol uses a data header, apply it */
233         brcmf_proto_hdrpush(drvr, ifp->ifidx, skb);
234
235         /* Use bus module to send data frame */
236         ret =  brcmf_bus_txdata(drvr->bus_if, skb);
237
238 done:
239         if (ret) {
240                 ifp->stats.tx_dropped++;
241         } else {
242                 ifp->stats.tx_packets++;
243                 ifp->stats.tx_bytes += skb->len;
244         }
245
246         /* Return ok: we always eat the packet */
247         return NETDEV_TX_OK;
248 }
249
250 void brcmf_txflowblock(struct device *dev, bool state)
251 {
252         struct net_device *ndev;
253         struct brcmf_bus *bus_if = dev_get_drvdata(dev);
254         struct brcmf_pub *drvr = bus_if->drvr;
255         int i;
256
257         brcmf_dbg(TRACE, "Enter\n");
258
259         for (i = 0; i < BRCMF_MAX_IFS; i++)
260                 if (drvr->iflist[i]) {
261                         ndev = drvr->iflist[i]->ndev;
262                         if (state)
263                                 netif_stop_queue(ndev);
264                         else
265                                 netif_wake_queue(ndev);
266                 }
267 }
268
269 void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
270 {
271         unsigned char *eth;
272         uint len;
273         struct sk_buff *skb, *pnext;
274         struct brcmf_if *ifp;
275         struct brcmf_bus *bus_if = dev_get_drvdata(dev);
276         struct brcmf_pub *drvr = bus_if->drvr;
277         u8 ifidx;
278         int ret;
279
280         brcmf_dbg(TRACE, "Enter\n");
281
282         skb_queue_walk_safe(skb_list, skb, pnext) {
283                 skb_unlink(skb, skb_list);
284
285                 /* process and remove protocol-specific header */
286                 ret = brcmf_proto_hdrpull(drvr, &ifidx, skb);
287                 ifp = drvr->iflist[ifidx];
288
289                 if (ret || !ifp || !ifp->ndev) {
290                         if ((ret != -ENODATA) && ifp)
291                                 ifp->stats.rx_errors++;
292                         brcmu_pkt_buf_free_skb(skb);
293                         continue;
294                 }
295
296                 /* Get the protocol, maintain skb around eth_type_trans()
297                  * The main reason for this hack is for the limitation of
298                  * Linux 2.4 where 'eth_type_trans' uses the
299                  * 'net->hard_header_len'
300                  * to perform skb_pull inside vs ETH_HLEN. Since to avoid
301                  * coping of the packet coming from the network stack to add
302                  * BDC, Hardware header etc, during network interface
303                  * registration
304                  * we set the 'net->hard_header_len' to ETH_HLEN + extra space
305                  * required
306                  * for BDC, Hardware header etc. and not just the ETH_HLEN
307                  */
308                 eth = skb->data;
309                 len = skb->len;
310
311                 skb->dev = ifp->ndev;
312                 skb->protocol = eth_type_trans(skb, skb->dev);
313
314                 if (skb->pkt_type == PACKET_MULTICAST)
315                         ifp->stats.multicast++;
316
317                 skb->data = eth;
318                 skb->len = len;
319
320                 /* Strip header, count, deliver upward */
321                 skb_pull(skb, ETH_HLEN);
322
323                 /* Process special event packets and then discard them */
324                 brcmf_fweh_process_skb(drvr, skb, &ifidx);
325
326                 if (drvr->iflist[ifidx]) {
327                         ifp = drvr->iflist[ifidx];
328                         ifp->ndev->last_rx = jiffies;
329                 }
330
331                 if (!(ifp->ndev->flags & IFF_UP)) {
332                         brcmu_pkt_buf_free_skb(skb);
333                         continue;
334                 }
335
336                 ifp->stats.rx_bytes += skb->len;
337                 ifp->stats.rx_packets++;
338
339                 if (in_interrupt())
340                         netif_rx(skb);
341                 else
342                         /* If the receive is not processed inside an ISR,
343                          * the softirqd must be woken explicitly to service
344                          * the NET_RX_SOFTIRQ.  In 2.6 kernels, this is handled
345                          * by netif_rx_ni(), but in earlier kernels, we need
346                          * to do it manually.
347                          */
348                         netif_rx_ni(skb);
349         }
350 }
351
352 void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
353 {
354         u8 ifidx;
355         struct ethhdr *eh;
356         u16 type;
357         struct brcmf_bus *bus_if = dev_get_drvdata(dev);
358         struct brcmf_pub *drvr = bus_if->drvr;
359         struct brcmf_if *ifp;
360
361         brcmf_proto_hdrpull(drvr, &ifidx, txp);
362
363         ifp = drvr->iflist[ifidx];
364         if (!ifp)
365                 return;
366
367         eh = (struct ethhdr *)(txp->data);
368         type = ntohs(eh->h_proto);
369
370         if (type == ETH_P_PAE) {
371                 atomic_dec(&ifp->pend_8021x_cnt);
372                 if (waitqueue_active(&ifp->pend_8021x_wait))
373                         wake_up(&ifp->pend_8021x_wait);
374         }
375         if (!success)
376                 ifp->stats.tx_errors++;
377 }
378
379 static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
380 {
381         struct brcmf_if *ifp = netdev_priv(ndev);
382
383         brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
384
385         return &ifp->stats;
386 }
387
388 /*
389  * Set current toe component enables in toe_ol iovar,
390  * and set toe global enable iovar
391  */
392 static int brcmf_toe_set(struct brcmf_if *ifp, u32 toe_ol)
393 {
394         s32 err;
395
396         err = brcmf_fil_iovar_int_set(ifp, "toe_ol", toe_ol);
397         if (err < 0) {
398                 brcmf_err("Setting toe_ol failed, %d\n", err);
399                 return err;
400         }
401
402         err = brcmf_fil_iovar_int_set(ifp, "toe", (toe_ol != 0));
403         if (err < 0)
404                 brcmf_err("Setting toe failed, %d\n", err);
405
406         return err;
407
408 }
409
410 static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
411                                     struct ethtool_drvinfo *info)
412 {
413         struct brcmf_if *ifp = netdev_priv(ndev);
414         struct brcmf_pub *drvr = ifp->drvr;
415
416         strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
417         snprintf(info->version, sizeof(info->version), "%lu",
418                  drvr->drv_version);
419         strlcpy(info->bus_info, dev_name(drvr->bus_if->dev),
420                 sizeof(info->bus_info));
421 }
422
423 static const struct ethtool_ops brcmf_ethtool_ops = {
424         .get_drvinfo = brcmf_ethtool_get_drvinfo,
425 };
426
427 static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr)
428 {
429         struct brcmf_pub *drvr = ifp->drvr;
430         struct ethtool_drvinfo info;
431         char drvname[sizeof(info.driver)];
432         u32 cmd;
433         struct ethtool_value edata;
434         u32 toe_cmpnt, csum_dir;
435         int ret;
436
437         brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
438
439         /* all ethtool calls start with a cmd word */
440         if (copy_from_user(&cmd, uaddr, sizeof(u32)))
441                 return -EFAULT;
442
443         switch (cmd) {
444         case ETHTOOL_GDRVINFO:
445                 /* Copy out any request driver name */
446                 if (copy_from_user(&info, uaddr, sizeof(info)))
447                         return -EFAULT;
448                 strncpy(drvname, info.driver, sizeof(info.driver));
449                 drvname[sizeof(info.driver) - 1] = '\0';
450
451                 /* clear struct for return */
452                 memset(&info, 0, sizeof(info));
453                 info.cmd = cmd;
454
455                 /* if requested, identify ourselves */
456                 if (strcmp(drvname, "?dhd") == 0) {
457                         sprintf(info.driver, "dhd");
458                         strcpy(info.version, BRCMF_VERSION_STR);
459                 }
460                 /* report dongle driver type */
461                 else
462                         sprintf(info.driver, "wl");
463
464                 sprintf(info.version, "%lu", drvr->drv_version);
465                 if (copy_to_user(uaddr, &info, sizeof(info)))
466                         return -EFAULT;
467                 brcmf_dbg(TRACE, "given %*s, returning %s\n",
468                           (int)sizeof(drvname), drvname, info.driver);
469                 break;
470
471                 /* Get toe offload components from dongle */
472         case ETHTOOL_GRXCSUM:
473         case ETHTOOL_GTXCSUM:
474                 ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt);
475                 if (ret < 0)
476                         return ret;
477
478                 csum_dir =
479                     (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
480
481                 edata.cmd = cmd;
482                 edata.data = (toe_cmpnt & csum_dir) ? 1 : 0;
483
484                 if (copy_to_user(uaddr, &edata, sizeof(edata)))
485                         return -EFAULT;
486                 break;
487
488                 /* Set toe offload components in dongle */
489         case ETHTOOL_SRXCSUM:
490         case ETHTOOL_STXCSUM:
491                 if (copy_from_user(&edata, uaddr, sizeof(edata)))
492                         return -EFAULT;
493
494                 /* Read the current settings, update and write back */
495                 ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt);
496                 if (ret < 0)
497                         return ret;
498
499                 csum_dir =
500                     (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
501
502                 if (edata.data != 0)
503                         toe_cmpnt |= csum_dir;
504                 else
505                         toe_cmpnt &= ~csum_dir;
506
507                 ret = brcmf_toe_set(ifp, toe_cmpnt);
508                 if (ret < 0)
509                         return ret;
510
511                 /* If setting TX checksum mode, tell Linux the new mode */
512                 if (cmd == ETHTOOL_STXCSUM) {
513                         if (edata.data)
514                                 ifp->ndev->features |= NETIF_F_IP_CSUM;
515                         else
516                                 ifp->ndev->features &= ~NETIF_F_IP_CSUM;
517                 }
518
519                 break;
520
521         default:
522                 return -EOPNOTSUPP;
523         }
524
525         return 0;
526 }
527
528 static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr,
529                                     int cmd)
530 {
531         struct brcmf_if *ifp = netdev_priv(ndev);
532         struct brcmf_pub *drvr = ifp->drvr;
533
534         brcmf_dbg(TRACE, "Enter, idx=%d, cmd=0x%04x\n", ifp->bssidx, cmd);
535
536         if (!drvr->iflist[ifp->bssidx])
537                 return -1;
538
539         if (cmd == SIOCETHTOOL)
540                 return brcmf_ethtool(ifp, ifr->ifr_data);
541
542         return -EOPNOTSUPP;
543 }
544
545 static int brcmf_netdev_stop(struct net_device *ndev)
546 {
547         struct brcmf_if *ifp = netdev_priv(ndev);
548
549         brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
550
551         brcmf_cfg80211_down(ndev);
552
553         /* Set state and stop OS transmissions */
554         netif_stop_queue(ndev);
555
556         return 0;
557 }
558
559 static int brcmf_netdev_open(struct net_device *ndev)
560 {
561         struct brcmf_if *ifp = netdev_priv(ndev);
562         struct brcmf_pub *drvr = ifp->drvr;
563         struct brcmf_bus *bus_if = drvr->bus_if;
564         u32 toe_ol;
565         s32 ret = 0;
566
567         brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
568
569         /* If bus is not ready, can't continue */
570         if (bus_if->state != BRCMF_BUS_DATA) {
571                 brcmf_err("failed bus is not ready\n");
572                 return -EAGAIN;
573         }
574
575         atomic_set(&ifp->pend_8021x_cnt, 0);
576
577         /* Get current TOE mode from dongle */
578         if (brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_ol) >= 0
579             && (toe_ol & TOE_TX_CSUM_OL) != 0)
580                 ndev->features |= NETIF_F_IP_CSUM;
581         else
582                 ndev->features &= ~NETIF_F_IP_CSUM;
583
584         /* Allow transmit calls */
585         netif_start_queue(ndev);
586         if (brcmf_cfg80211_up(ndev)) {
587                 brcmf_err("failed to bring up cfg80211\n");
588                 return -1;
589         }
590
591         return ret;
592 }
593
594 static const struct net_device_ops brcmf_netdev_ops_pri = {
595         .ndo_open = brcmf_netdev_open,
596         .ndo_stop = brcmf_netdev_stop,
597         .ndo_get_stats = brcmf_netdev_get_stats,
598         .ndo_do_ioctl = brcmf_netdev_ioctl_entry,
599         .ndo_start_xmit = brcmf_netdev_start_xmit,
600         .ndo_set_mac_address = brcmf_netdev_set_mac_address,
601         .ndo_set_rx_mode = brcmf_netdev_set_multicast_list
602 };
603
604 int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked)
605 {
606         struct brcmf_pub *drvr = ifp->drvr;
607         struct net_device *ndev;
608         s32 err;
609
610         brcmf_dbg(TRACE, "Enter, idx=%d mac=%pM\n", ifp->bssidx,
611                   ifp->mac_addr);
612         ndev = ifp->ndev;
613
614         /* set appropriate operations */
615         ndev->netdev_ops = &brcmf_netdev_ops_pri;
616
617         ndev->hard_header_len = ETH_HLEN + drvr->hdrlen;
618         ndev->ethtool_ops = &brcmf_ethtool_ops;
619
620         drvr->rxsz = ndev->mtu + ndev->hard_header_len +
621                               drvr->hdrlen;
622
623         /* set the mac address */
624         memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
625
626         INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address);
627         INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list);
628
629         if (rtnl_locked)
630                 err = register_netdevice(ndev);
631         else
632                 err = register_netdev(ndev);
633         if (err != 0) {
634                 brcmf_err("couldn't register the net device\n");
635                 goto fail;
636         }
637
638         brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
639
640         return 0;
641
642 fail:
643         ndev->netdev_ops = NULL;
644         return -EBADE;
645 }
646
647 static int brcmf_net_p2p_open(struct net_device *ndev)
648 {
649         brcmf_dbg(TRACE, "Enter\n");
650
651         return brcmf_cfg80211_up(ndev);
652 }
653
654 static int brcmf_net_p2p_stop(struct net_device *ndev)
655 {
656         brcmf_dbg(TRACE, "Enter\n");
657
658         return brcmf_cfg80211_down(ndev);
659 }
660
661 static int brcmf_net_p2p_do_ioctl(struct net_device *ndev,
662                                   struct ifreq *ifr, int cmd)
663 {
664         brcmf_dbg(TRACE, "Enter\n");
665         return 0;
666 }
667
668 static netdev_tx_t brcmf_net_p2p_start_xmit(struct sk_buff *skb,
669                                             struct net_device *ndev)
670 {
671         if (skb)
672                 dev_kfree_skb_any(skb);
673
674         return NETDEV_TX_OK;
675 }
676
677 static const struct net_device_ops brcmf_netdev_ops_p2p = {
678         .ndo_open = brcmf_net_p2p_open,
679         .ndo_stop = brcmf_net_p2p_stop,
680         .ndo_do_ioctl = brcmf_net_p2p_do_ioctl,
681         .ndo_start_xmit = brcmf_net_p2p_start_xmit
682 };
683
684 static int brcmf_net_p2p_attach(struct brcmf_if *ifp)
685 {
686         struct net_device *ndev;
687
688         brcmf_dbg(TRACE, "Enter, idx=%d mac=%pM\n", ifp->bssidx,
689                   ifp->mac_addr);
690         ndev = ifp->ndev;
691
692         ndev->netdev_ops = &brcmf_netdev_ops_p2p;
693
694         /* set the mac address */
695         memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
696
697         if (register_netdev(ndev) != 0) {
698                 brcmf_err("couldn't register the p2p net device\n");
699                 goto fail;
700         }
701
702         brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
703
704         return 0;
705
706 fail:
707         return -EBADE;
708 }
709
710 struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
711                               char *name, u8 *mac_addr)
712 {
713         struct brcmf_if *ifp;
714         struct net_device *ndev;
715
716         brcmf_dbg(TRACE, "Enter, idx=%d, ifidx=%d\n", bssidx, ifidx);
717
718         ifp = drvr->iflist[bssidx];
719         /*
720          * Delete the existing interface before overwriting it
721          * in case we missed the BRCMF_E_IF_DEL event.
722          */
723         if (ifp) {
724                 brcmf_err("ERROR: netdev:%s already exists\n",
725                           ifp->ndev->name);
726                 if (ifidx) {
727                         netif_stop_queue(ifp->ndev);
728                         unregister_netdev(ifp->ndev);
729                         free_netdev(ifp->ndev);
730                         drvr->iflist[bssidx] = NULL;
731                 } else {
732                         brcmf_err("ignore IF event\n");
733                         return ERR_PTR(-EINVAL);
734                 }
735         }
736
737         /* Allocate netdev, including space for private structure */
738         ndev = alloc_netdev(sizeof(struct brcmf_if), name, ether_setup);
739         if (!ndev) {
740                 brcmf_err("OOM - alloc_netdev\n");
741                 return ERR_PTR(-ENOMEM);
742         }
743
744         ifp = netdev_priv(ndev);
745         ifp->ndev = ndev;
746         ifp->drvr = drvr;
747         drvr->iflist[bssidx] = ifp;
748         ifp->ifidx = ifidx;
749         ifp->bssidx = bssidx;
750
751
752         init_waitqueue_head(&ifp->pend_8021x_wait);
753
754         if (mac_addr != NULL)
755                 memcpy(ifp->mac_addr, mac_addr, ETH_ALEN);
756
757         brcmf_dbg(TRACE, " ==== pid:%x, if:%s (%pM) created ===\n",
758                   current->pid, ifp->ndev->name, ifp->mac_addr);
759
760         return ifp;
761 }
762
763 void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
764 {
765         struct brcmf_if *ifp;
766
767         ifp = drvr->iflist[bssidx];
768         if (!ifp) {
769                 brcmf_err("Null interface, idx=%d\n", bssidx);
770                 return;
771         }
772         brcmf_dbg(TRACE, "Enter, idx=%d, ifidx=%d\n", bssidx, ifp->ifidx);
773         if (ifp->ndev) {
774                 if (bssidx == 0) {
775                         if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
776                                 rtnl_lock();
777                                 brcmf_netdev_stop(ifp->ndev);
778                                 rtnl_unlock();
779                         }
780                 } else {
781                         netif_stop_queue(ifp->ndev);
782                 }
783
784                 if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
785                         cancel_work_sync(&ifp->setmacaddr_work);
786                         cancel_work_sync(&ifp->multicast_work);
787                 }
788
789                 unregister_netdev(ifp->ndev);
790                 drvr->iflist[bssidx] = NULL;
791                 if (bssidx == 0)
792                         brcmf_cfg80211_detach(drvr->config);
793                 free_netdev(ifp->ndev);
794         }
795 }
796
797 int brcmf_attach(uint bus_hdrlen, struct device *dev)
798 {
799         struct brcmf_pub *drvr = NULL;
800         int ret = 0;
801
802         brcmf_dbg(TRACE, "Enter\n");
803
804         /* Allocate primary brcmf_info */
805         drvr = kzalloc(sizeof(struct brcmf_pub), GFP_ATOMIC);
806         if (!drvr)
807                 return -ENOMEM;
808
809         mutex_init(&drvr->proto_block);
810
811         /* Link to bus module */
812         drvr->hdrlen = bus_hdrlen;
813         drvr->bus_if = dev_get_drvdata(dev);
814         drvr->bus_if->drvr = drvr;
815
816         /* create device debugfs folder */
817         brcmf_debugfs_attach(drvr);
818
819         /* Attach and link in the protocol */
820         ret = brcmf_proto_attach(drvr);
821         if (ret != 0) {
822                 brcmf_err("brcmf_prot_attach failed\n");
823                 goto fail;
824         }
825
826         /* attach firmware event handler */
827         brcmf_fweh_attach(drvr);
828
829         INIT_LIST_HEAD(&drvr->bus_if->dcmd_list);
830
831         return ret;
832
833 fail:
834         brcmf_detach(dev);
835
836         return ret;
837 }
838
839 int brcmf_bus_start(struct device *dev)
840 {
841         int ret = -1;
842         struct brcmf_bus *bus_if = dev_get_drvdata(dev);
843         struct brcmf_pub *drvr = bus_if->drvr;
844         struct brcmf_if *ifp;
845         struct brcmf_if *p2p_ifp;
846
847         brcmf_dbg(TRACE, "\n");
848
849         /* Bring up the bus */
850         ret = brcmf_bus_init(bus_if);
851         if (ret != 0) {
852                 brcmf_err("brcmf_sdbrcm_bus_init failed %d\n", ret);
853                 return ret;
854         }
855
856         /* add primary networking interface */
857         ifp = brcmf_add_if(drvr, 0, 0, "wlan%d", NULL);
858         if (IS_ERR(ifp))
859                 return PTR_ERR(ifp);
860
861         if (brcmf_p2p_enable)
862                 p2p_ifp = brcmf_add_if(drvr, 1, 0, "p2p%d", NULL);
863         else
864                 p2p_ifp = NULL;
865         if (IS_ERR(p2p_ifp))
866                 p2p_ifp = NULL;
867
868         /* signal bus ready */
869         bus_if->state = BRCMF_BUS_DATA;
870
871         /* Bus is ready, do any initialization */
872         ret = brcmf_c_preinit_dcmds(ifp);
873         if (ret < 0)
874                 goto fail;
875
876         drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev);
877         if (drvr->config == NULL) {
878                 ret = -ENOMEM;
879                 goto fail;
880         }
881
882         ret = brcmf_fweh_activate_events(ifp);
883         if (ret < 0)
884                 goto fail;
885
886         ret = brcmf_net_attach(ifp, false);
887 fail:
888         if (ret < 0) {
889                 brcmf_err("failed: %d\n", ret);
890                 if (drvr->config)
891                         brcmf_cfg80211_detach(drvr->config);
892                 free_netdev(ifp->ndev);
893                 drvr->iflist[0] = NULL;
894                 if (p2p_ifp) {
895                         free_netdev(p2p_ifp->ndev);
896                         drvr->iflist[1] = NULL;
897                 }
898                 return ret;
899         }
900         if ((brcmf_p2p_enable) && (p2p_ifp))
901                 brcmf_net_p2p_attach(p2p_ifp);
902
903         return 0;
904 }
905
906 static void brcmf_bus_detach(struct brcmf_pub *drvr)
907 {
908         brcmf_dbg(TRACE, "Enter\n");
909
910         if (drvr) {
911                 /* Stop the protocol module */
912                 brcmf_proto_stop(drvr);
913
914                 /* Stop the bus module */
915                 brcmf_bus_stop(drvr->bus_if);
916         }
917 }
918
919 void brcmf_dev_reset(struct device *dev)
920 {
921         struct brcmf_bus *bus_if = dev_get_drvdata(dev);
922         struct brcmf_pub *drvr = bus_if->drvr;
923
924         if (drvr == NULL)
925                 return;
926
927         if (drvr->iflist[0])
928                 brcmf_fil_cmd_int_set(drvr->iflist[0], BRCMF_C_TERMINATED, 1);
929 }
930
931 void brcmf_detach(struct device *dev)
932 {
933         s32 i;
934         struct brcmf_bus *bus_if = dev_get_drvdata(dev);
935         struct brcmf_pub *drvr = bus_if->drvr;
936
937         brcmf_dbg(TRACE, "Enter\n");
938
939         if (drvr == NULL)
940                 return;
941
942         /* stop firmware event handling */
943         brcmf_fweh_detach(drvr);
944
945         /* make sure primary interface removed last */
946         for (i = BRCMF_MAX_IFS-1; i > -1; i--)
947                 if (drvr->iflist[i])
948                         brcmf_del_if(drvr, i);
949
950         brcmf_bus_detach(drvr);
951
952         if (drvr->prot)
953                 brcmf_proto_detach(drvr);
954
955         brcmf_debugfs_detach(drvr);
956         bus_if->drvr = NULL;
957         kfree(drvr);
958 }
959
960 static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp)
961 {
962         return atomic_read(&ifp->pend_8021x_cnt);
963 }
964
965 int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
966 {
967         struct brcmf_if *ifp = netdev_priv(ndev);
968         int err;
969
970         err = wait_event_timeout(ifp->pend_8021x_wait,
971                                  !brcmf_get_pend_8021x_cnt(ifp),
972                                  msecs_to_jiffies(MAX_WAIT_FOR_8021X_TX));
973
974         WARN_ON(!err);
975
976         return !err;
977 }
978
979 /*
980  * return chip id and rev of the device encoded in u32.
981  */
982 u32 brcmf_get_chip_info(struct brcmf_if *ifp)
983 {
984         struct brcmf_bus *bus = ifp->drvr->bus_if;
985
986         return bus->chip << 4 | bus->chiprev;
987 }
988
989 static void brcmf_driver_init(struct work_struct *work)
990 {
991         brcmf_debugfs_init();
992
993 #ifdef CONFIG_BRCMFMAC_SDIO
994         brcmf_sdio_init();
995 #endif
996 #ifdef CONFIG_BRCMFMAC_USB
997         brcmf_usb_init();
998 #endif
999 }
1000 static DECLARE_WORK(brcmf_driver_work, brcmf_driver_init);
1001
1002 static int __init brcmfmac_module_init(void)
1003 {
1004         if (!schedule_work(&brcmf_driver_work))
1005                 return -EBUSY;
1006
1007         return 0;
1008 }
1009
1010 static void __exit brcmfmac_module_exit(void)
1011 {
1012         cancel_work_sync(&brcmf_driver_work);
1013
1014 #ifdef CONFIG_BRCMFMAC_SDIO
1015         brcmf_sdio_exit();
1016 #endif
1017 #ifdef CONFIG_BRCMFMAC_USB
1018         brcmf_usb_exit();
1019 #endif
1020         brcmf_debugfs_exit();
1021 }
1022
1023 module_init(brcmfmac_module_init);
1024 module_exit(brcmfmac_module_exit);