2 * Copyright (c) 2010 Broadcom Corporation
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.
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.
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>
30 #include <linux/uaccess.h>
31 #include <linux/hardirq.h>
32 #include <linux/mutex.h>
33 #include <linux/wait.h>
34 #include <net/cfg80211.h>
36 #include <brcmu_utils.h>
37 #include <brcmu_wifi.h>
41 #include "dhd_proto.h"
43 #include "wl_cfg80211.h"
46 MODULE_AUTHOR("Broadcom Corporation");
47 MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac driver.");
48 MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards");
49 MODULE_LICENSE("Dual BSD/GPL");
52 /* Interface control information */
54 struct brcmf_info *info; /* back pointer to brcmf_info */
55 /* OS/stack specifics */
56 struct net_device *net;
57 struct net_device_stats stats;
58 int idx; /* iface idx in dongle */
59 int state; /* interface state */
60 uint subunit; /* subunit */
61 u8 mac_addr[ETH_ALEN]; /* assigned MAC address */
62 bool attached; /* Delayed attachment when unset */
63 bool txflowcontrol; /* Per interface flow control indicator */
64 char name[IFNAMSIZ]; /* linux interface name */
67 /* Local private structure (extension of pub) */
71 /* OS/stack specifics */
72 struct brcmf_if *iflist[BRCMF_MAX_IFS];
74 struct mutex proto_block;
76 /* Thread to issue ioctl for multicast */
77 struct task_struct *sysioc_tsk;
78 wait_queue_head_t sysioc_waitq;
81 u8 macvalue[ETH_ALEN];
82 atomic_t pend_8021x_cnt;
86 module_param(brcmf_msg_level, int, 0);
88 /* Spawn a thread for system ioctls (set mac, set mcast) */
89 uint brcmf_sysioc = true;
90 module_param(brcmf_sysioc, uint, 0);
92 /* ARP offload agent mode : Enable ARP Host Auto-Reply
93 and ARP Peer Auto-Reply */
94 uint brcmf_arp_mode = 0xb;
95 module_param(brcmf_arp_mode, uint, 0);
97 /* ARP offload enable */
98 uint brcmf_arp_enable = true;
99 module_param(brcmf_arp_enable, uint, 0);
101 /* Global Pkt filter enable control */
102 uint brcmf_pkt_filter_enable = true;
103 module_param(brcmf_pkt_filter_enable, uint, 0);
105 /* Pkt filter init setup */
106 uint brcmf_pkt_filter_init;
107 module_param(brcmf_pkt_filter_init, uint, 0);
109 /* Pkt filter mode control */
110 uint brcmf_master_mode = true;
111 module_param(brcmf_master_mode, uint, 0);
113 /* Contorl fw roaming */
116 /* Control radio state */
117 uint brcmf_radio_up = 1;
119 /* Network inteface name */
120 char iface_name[IFNAMSIZ] = "wlan";
121 module_param_string(iface_name, iface_name, IFNAMSIZ, 0);
123 static int brcmf_toe_get(struct brcmf_info *drvr_priv, int idx, u32 *toe_ol);
124 static int brcmf_toe_set(struct brcmf_info *drvr_priv, int idx, u32 toe_ol);
125 static int brcmf_host_event(struct brcmf_info *drvr_priv, int *ifidx,
126 void *pktdata, struct brcmf_event_msg *event_ptr,
129 static int brcmf_net2idx(struct brcmf_info *drvr_priv, struct net_device *net)
133 while (i < BRCMF_MAX_IFS) {
134 if (drvr_priv->iflist[i] && (drvr_priv->iflist[i]->net == net))
142 int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name)
144 int i = BRCMF_MAX_IFS;
146 if (name == NULL || *name == '\0')
150 if (drvr_priv->iflist[i]
151 && !strncmp(drvr_priv->iflist[i]->name, name, IFNAMSIZ))
154 brcmf_dbg(TRACE, "return idx %d for \"%s\"\n", i, name);
156 return i; /* default - the primary interface */
159 char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx)
161 struct brcmf_info *drvr_priv = drvr->info;
163 if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
164 brcmf_dbg(ERROR, "ifidx %d out of range\n", ifidx);
168 if (drvr_priv->iflist[ifidx] == NULL) {
169 brcmf_dbg(ERROR, "null i/f %d\n", ifidx);
173 if (drvr_priv->iflist[ifidx]->net)
174 return drvr_priv->iflist[ifidx]->net->name;
179 static void _brcmf_set_multicast_list(struct brcmf_info *drvr_priv, int ifidx)
181 struct net_device *dev;
182 struct netdev_hw_addr *ha;
185 struct brcmf_ioctl ioc;
190 dev = drvr_priv->iflist[ifidx]->net;
191 cnt = netdev_mc_count(dev);
193 /* Determine initial value of allmulti flag */
194 allmulti = (dev->flags & IFF_ALLMULTI) ? true : false;
196 /* Send down the multicast list first. */
198 buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETH_ALEN);
199 bufp = buf = kmalloc(buflen, GFP_ATOMIC);
201 brcmf_dbg(ERROR, "%s: out of memory for mcast_list, cnt %d\n",
202 brcmf_ifname(&drvr_priv->pub, ifidx), cnt);
206 strcpy(bufp, "mcast_list");
207 bufp += strlen("mcast_list") + 1;
209 cnt = cpu_to_le32(cnt);
210 memcpy(bufp, &cnt, sizeof(cnt));
213 netdev_for_each_mc_addr(ha, dev) {
216 memcpy(bufp, ha->addr, ETH_ALEN);
221 memset(&ioc, 0, sizeof(ioc));
222 ioc.cmd = BRCMF_C_SET_VAR;
227 ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len);
229 brcmf_dbg(ERROR, "%s: set mcast_list failed, cnt %d\n",
230 brcmf_ifname(&drvr_priv->pub, ifidx), cnt);
231 allmulti = cnt ? true : allmulti;
236 /* Now send the allmulti setting. This is based on the setting in the
237 * net_device flags, but might be modified above to be turned on if we
238 * were trying to set some addresses and dongle rejected it...
241 buflen = sizeof("allmulti") + sizeof(allmulti);
242 buf = kmalloc(buflen, GFP_ATOMIC);
244 brcmf_dbg(ERROR, "%s: out of memory for allmulti\n",
245 brcmf_ifname(&drvr_priv->pub, ifidx));
248 allmulti = cpu_to_le32(allmulti);
251 ("allmulti", (void *)&allmulti, sizeof(allmulti), buf, buflen)) {
252 brcmf_dbg(ERROR, "%s: mkiovar failed for allmulti, datalen %d buflen %u\n",
253 brcmf_ifname(&drvr_priv->pub, ifidx),
254 (int)sizeof(allmulti), buflen);
259 memset(&ioc, 0, sizeof(ioc));
260 ioc.cmd = BRCMF_C_SET_VAR;
265 ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len);
267 brcmf_dbg(ERROR, "%s: set allmulti %d failed\n",
268 brcmf_ifname(&drvr_priv->pub, ifidx),
269 le32_to_cpu(allmulti));
274 /* Finally, pick up the PROMISC flag as well, like the NIC
277 allmulti = (dev->flags & IFF_PROMISC) ? true : false;
278 allmulti = cpu_to_le32(allmulti);
280 memset(&ioc, 0, sizeof(ioc));
281 ioc.cmd = BRCMF_C_SET_PROMISC;
283 ioc.len = sizeof(allmulti);
286 ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len);
288 brcmf_dbg(ERROR, "%s: set promisc %d failed\n",
289 brcmf_ifname(&drvr_priv->pub, ifidx),
290 le32_to_cpu(allmulti));
295 _brcmf_set_mac_address(struct brcmf_info *drvr_priv, int ifidx, u8 *addr)
298 struct brcmf_ioctl ioc;
301 brcmf_dbg(TRACE, "enter\n");
302 if (!brcmu_mkiovar("cur_etheraddr", (char *)addr, ETH_ALEN, buf, 32)) {
303 brcmf_dbg(ERROR, "%s: mkiovar failed for cur_etheraddr\n",
304 brcmf_ifname(&drvr_priv->pub, ifidx));
307 memset(&ioc, 0, sizeof(ioc));
308 ioc.cmd = BRCMF_C_SET_VAR;
313 ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len);
315 brcmf_dbg(ERROR, "%s: set cur_etheraddr failed\n",
316 brcmf_ifname(&drvr_priv->pub, ifidx));
318 memcpy(drvr_priv->iflist[ifidx]->net->dev_addr, addr, ETH_ALEN);
324 static struct net_device *ap_net_dev;
327 /* Virtual interfaces only ((ifp && ifp->info && ifp->idx == true) */
328 static void brcmf_op_if(struct brcmf_if *ifp)
330 struct brcmf_info *drvr_priv;
331 int ret = 0, err = 0;
333 drvr_priv = ifp->info;
335 brcmf_dbg(TRACE, "idx %d, state %d\n", ifp->idx, ifp->state);
337 switch (ifp->state) {
340 * Delete the existing interface before overwriting it
341 * in case we missed the BRCMF_E_IF_DEL event.
343 if (ifp->net != NULL) {
344 brcmf_dbg(ERROR, "ERROR: netdev:%s already exists, try free & unregister\n",
346 netif_stop_queue(ifp->net);
347 unregister_netdev(ifp->net);
348 free_netdev(ifp->net);
350 /* Allocate etherdev, including space for private structure */
351 ifp->net = alloc_etherdev(sizeof(drvr_priv));
353 brcmf_dbg(ERROR, "OOM - alloc_etherdev\n");
357 strcpy(ifp->net->name, ifp->name);
358 memcpy(netdev_priv(ifp->net), &drvr_priv,
360 err = brcmf_net_attach(&drvr_priv->pub, ifp->idx);
362 brcmf_dbg(ERROR, "brcmf_net_attach failed, err %d\n",
367 /* semaphore that the soft AP CODE
369 struct semaphore ap_eth_sema;
371 /* save ptr to wl0.1 netdev for use
373 ap_net_dev = ifp->net;
374 /* signal to the SOFTAP 'sleeper' thread,
378 brcmf_dbg(TRACE, " ==== pid:%x, net_device for if:%s created ===\n",
379 current->pid, ifp->net->name);
385 if (ifp->net != NULL) {
386 brcmf_dbg(TRACE, "got 'WLC_E_IF_DEL' state\n");
387 netif_stop_queue(ifp->net);
388 unregister_netdev(ifp->net);
389 ret = BRCMF_DEL_IF; /* Make sure the free_netdev()
394 brcmf_dbg(ERROR, "bad op %d\n", ifp->state);
400 free_netdev(ifp->net);
402 drvr_priv->iflist[ifp->idx] = NULL;
405 if (ifp->net == ap_net_dev)
406 ap_net_dev = NULL; /* NULL SOFTAP global
412 static int _brcmf_sysioc_thread(void *data)
414 struct brcmf_info *drvr_priv = (struct brcmf_info *) data;
419 DECLARE_WAITQUEUE(wait, current);
420 allow_signal(SIGTERM);
422 add_wait_queue(&drvr_priv->sysioc_waitq, &wait);
424 prepare_to_wait(&drvr_priv->sysioc_waitq, &wait,
430 if (kthread_should_stop())
433 for (i = 0; i < BRCMF_MAX_IFS; i++) {
434 struct brcmf_if *ifentry = drvr_priv->iflist[i];
437 in_ap = (ap_net_dev != NULL);
440 brcmf_op_if(ifentry);
442 if (drvr_priv->iflist[i] == NULL) {
443 brcmf_dbg(TRACE, "interface %d removed!\n",
448 if (in_ap && drvr_priv->set_macaddress) {
449 brcmf_dbg(TRACE, "attempt to set MAC for %s in AP Mode, blocked.\n",
451 drvr_priv->set_macaddress = false;
455 if (in_ap && drvr_priv->set_multicast) {
456 brcmf_dbg(TRACE, "attempt to set MULTICAST list for %s in AP Mode, blocked.\n",
458 drvr_priv->set_multicast = false;
462 if (drvr_priv->set_multicast) {
463 drvr_priv->set_multicast = false;
464 _brcmf_set_multicast_list(drvr_priv, i);
466 if (drvr_priv->set_macaddress) {
467 drvr_priv->set_macaddress = false;
468 _brcmf_set_mac_address(drvr_priv, i,
469 drvr_priv->macvalue);
474 finish_wait(&drvr_priv->sysioc_waitq, &wait);
478 static int brcmf_netdev_set_mac_address(struct net_device *dev, void *addr)
482 struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(dev);
483 struct sockaddr *sa = (struct sockaddr *)addr;
486 ifidx = brcmf_net2idx(drvr_priv, dev);
487 if (ifidx == BRCMF_BAD_IF)
490 memcpy(&drvr_priv->macvalue, sa->sa_data, ETH_ALEN);
491 drvr_priv->set_macaddress = true;
492 wake_up(&drvr_priv->sysioc_waitq);
496 static void brcmf_netdev_set_multicast_list(struct net_device *dev)
498 struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(dev);
501 ifidx = brcmf_net2idx(drvr_priv, dev);
502 if (ifidx == BRCMF_BAD_IF)
505 drvr_priv->set_multicast = true;
506 wake_up(&drvr_priv->sysioc_waitq);
509 int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx, struct sk_buff *pktbuf)
511 struct brcmf_info *drvr_priv = drvr->info;
514 if (!drvr->up || (drvr->busstate == BRCMF_BUS_DOWN))
517 /* Update multicast statistic */
518 if (pktbuf->len >= ETH_ALEN) {
519 u8 *pktdata = (u8 *) (pktbuf->data);
520 struct ethhdr *eh = (struct ethhdr *)pktdata;
522 if (is_multicast_ether_addr(eh->h_dest))
523 drvr->tx_multicast++;
524 if (ntohs(eh->h_proto) == ETH_P_PAE)
525 atomic_inc(&drvr_priv->pend_8021x_cnt);
528 /* If the protocol uses a data header, apply it */
529 brcmf_proto_hdrpush(drvr, ifidx, pktbuf);
531 /* Use bus module to send data frame */
532 return brcmf_sdbrcm_bus_txdata(drvr->bus, pktbuf);
535 static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *net)
538 struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net);
541 brcmf_dbg(TRACE, "Enter\n");
544 if (!drvr_priv->pub.up || (drvr_priv->pub.busstate == BRCMF_BUS_DOWN)) {
545 brcmf_dbg(ERROR, "xmit rejected pub.up=%d busstate=%d\n",
546 drvr_priv->pub.up, drvr_priv->pub.busstate);
547 netif_stop_queue(net);
551 ifidx = brcmf_net2idx(drvr_priv, net);
552 if (ifidx == BRCMF_BAD_IF) {
553 brcmf_dbg(ERROR, "bad ifidx %d\n", ifidx);
554 netif_stop_queue(net);
558 /* Make sure there's enough room for any header */
559 if (skb_headroom(skb) < drvr_priv->pub.hdrlen) {
560 struct sk_buff *skb2;
562 brcmf_dbg(INFO, "%s: insufficient headroom\n",
563 brcmf_ifname(&drvr_priv->pub, ifidx));
564 drvr_priv->pub.tx_realloc++;
565 skb2 = skb_realloc_headroom(skb, drvr_priv->pub.hdrlen);
569 brcmf_dbg(ERROR, "%s: skb_realloc_headroom failed\n",
570 brcmf_ifname(&drvr_priv->pub, ifidx));
576 ret = brcmf_sendpkt(&drvr_priv->pub, ifidx, skb);
580 drvr_priv->pub.dstats.tx_dropped++;
582 drvr_priv->pub.tx_packets++;
584 /* Return ok: we always eat the packet */
588 void brcmf_txflowcontrol(struct brcmf_pub *drvr, int ifidx, bool state)
590 struct net_device *net;
591 struct brcmf_info *drvr_priv = drvr->info;
593 brcmf_dbg(TRACE, "Enter\n");
596 net = drvr_priv->iflist[ifidx]->net;
598 netif_stop_queue(net);
600 netif_wake_queue(net);
603 void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx, struct sk_buff *skb,
606 struct brcmf_info *drvr_priv = drvr->info;
610 struct sk_buff *pnext, *save_pktbuf;
612 struct brcmf_if *ifp;
613 struct brcmf_event_msg event;
615 brcmf_dbg(TRACE, "Enter\n");
619 for (i = 0; skb && i < numpkt; i++, skb = pnext) {
624 /* Get the protocol, maintain skb around eth_type_trans()
625 * The main reason for this hack is for the limitation of
626 * Linux 2.4 where 'eth_type_trans' uses the
627 * 'net->hard_header_len'
628 * to perform skb_pull inside vs ETH_HLEN. Since to avoid
629 * coping of the packet coming from the network stack to add
630 * BDC, Hardware header etc, during network interface
632 * we set the 'net->hard_header_len' to ETH_HLEN + extra space
634 * for BDC, Hardware header etc. and not just the ETH_HLEN
639 ifp = drvr_priv->iflist[ifidx];
641 ifp = drvr_priv->iflist[0];
644 skb->protocol = eth_type_trans(skb, skb->dev);
646 if (skb->pkt_type == PACKET_MULTICAST)
647 drvr_priv->pub.rx_multicast++;
652 /* Strip header, count, deliver upward */
653 skb_pull(skb, ETH_HLEN);
655 /* Process special event packets and then discard them */
656 if (ntohs(skb->protocol) == ETH_P_LINK_CTL)
657 brcmf_host_event(drvr_priv, &ifidx,
661 if (drvr_priv->iflist[ifidx] &&
662 !drvr_priv->iflist[ifidx]->state)
663 ifp = drvr_priv->iflist[ifidx];
666 ifp->net->last_rx = jiffies;
668 drvr->dstats.rx_bytes += skb->len;
669 drvr->rx_packets++; /* Local count */
674 /* If the receive is not processed inside an ISR,
675 * the softirqd must be woken explicitly to service
676 * the NET_RX_SOFTIRQ. In 2.6 kernels, this is handled
677 * by netif_rx_ni(), but in earlier kernels, we need
684 void brcmf_txcomplete(struct brcmf_pub *drvr, struct sk_buff *txp, bool success)
687 struct brcmf_info *drvr_priv = drvr->info;
691 brcmf_proto_hdrpull(drvr, &ifidx, txp);
693 eh = (struct ethhdr *)(txp->data);
694 type = ntohs(eh->h_proto);
696 if (type == ETH_P_PAE)
697 atomic_dec(&drvr_priv->pend_8021x_cnt);
701 static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *net)
703 struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net);
704 struct brcmf_if *ifp;
707 brcmf_dbg(TRACE, "Enter\n");
709 ifidx = brcmf_net2idx(drvr_priv, net);
710 if (ifidx == BRCMF_BAD_IF)
713 ifp = drvr_priv->iflist[ifidx];
715 if (drvr_priv->pub.up)
716 /* Use the protocol to get dongle stats */
717 brcmf_proto_dstats(&drvr_priv->pub);
719 /* Copy dongle stats to net device stats */
720 ifp->stats.rx_packets = drvr_priv->pub.dstats.rx_packets;
721 ifp->stats.tx_packets = drvr_priv->pub.dstats.tx_packets;
722 ifp->stats.rx_bytes = drvr_priv->pub.dstats.rx_bytes;
723 ifp->stats.tx_bytes = drvr_priv->pub.dstats.tx_bytes;
724 ifp->stats.rx_errors = drvr_priv->pub.dstats.rx_errors;
725 ifp->stats.tx_errors = drvr_priv->pub.dstats.tx_errors;
726 ifp->stats.rx_dropped = drvr_priv->pub.dstats.rx_dropped;
727 ifp->stats.tx_dropped = drvr_priv->pub.dstats.tx_dropped;
728 ifp->stats.multicast = drvr_priv->pub.dstats.multicast;
733 /* Retrieve current toe component enables, which are kept
734 as a bitmap in toe_ol iovar */
735 static int brcmf_toe_get(struct brcmf_info *drvr_priv, int ifidx, u32 *toe_ol)
737 struct brcmf_ioctl ioc;
741 memset(&ioc, 0, sizeof(ioc));
743 ioc.cmd = BRCMF_C_GET_VAR;
745 ioc.len = (uint) sizeof(buf);
748 strcpy(buf, "toe_ol");
749 ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len);
751 /* Check for older dongle image that doesn't support toe_ol */
753 brcmf_dbg(ERROR, "%s: toe not supported by device\n",
754 brcmf_ifname(&drvr_priv->pub, ifidx));
758 brcmf_dbg(INFO, "%s: could not get toe_ol: ret=%d\n",
759 brcmf_ifname(&drvr_priv->pub, ifidx), ret);
763 memcpy(toe_ol, buf, sizeof(u32));
767 /* Set current toe component enables in toe_ol iovar,
768 and set toe global enable iovar */
769 static int brcmf_toe_set(struct brcmf_info *drvr_priv, int ifidx, u32 toe_ol)
771 struct brcmf_ioctl ioc;
775 memset(&ioc, 0, sizeof(ioc));
777 ioc.cmd = BRCMF_C_SET_VAR;
779 ioc.len = (uint) sizeof(buf);
782 /* Set toe_ol as requested */
784 strcpy(buf, "toe_ol");
785 memcpy(&buf[sizeof("toe_ol")], &toe_ol, sizeof(u32));
787 ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len);
789 brcmf_dbg(ERROR, "%s: could not set toe_ol: ret=%d\n",
790 brcmf_ifname(&drvr_priv->pub, ifidx), ret);
794 /* Enable toe globally only if any components are enabled. */
799 memcpy(&buf[sizeof("toe")], &toe, sizeof(u32));
801 ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len);
803 brcmf_dbg(ERROR, "%s: could not set toe: ret=%d\n",
804 brcmf_ifname(&drvr_priv->pub, ifidx), ret);
811 static void brcmf_ethtool_get_drvinfo(struct net_device *net,
812 struct ethtool_drvinfo *info)
814 struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net);
816 sprintf(info->driver, KBUILD_MODNAME);
817 sprintf(info->version, "%lu", drvr_priv->pub.drv_version);
818 sprintf(info->fw_version, "%s", BCM4329_FW_NAME);
819 sprintf(info->bus_info, "%s",
820 dev_name(&brcmf_cfg80211_get_sdio_func()->dev));
823 struct ethtool_ops brcmf_ethtool_ops = {
824 .get_drvinfo = brcmf_ethtool_get_drvinfo
827 static int brcmf_ethtool(struct brcmf_info *drvr_priv, void *uaddr)
829 struct ethtool_drvinfo info;
830 char drvname[sizeof(info.driver)];
832 struct ethtool_value edata;
833 u32 toe_cmpnt, csum_dir;
836 brcmf_dbg(TRACE, "Enter\n");
838 /* all ethtool calls start with a cmd word */
839 if (copy_from_user(&cmd, uaddr, sizeof(u32)))
843 case ETHTOOL_GDRVINFO:
844 /* Copy out any request driver name */
845 if (copy_from_user(&info, uaddr, sizeof(info)))
847 strncpy(drvname, info.driver, sizeof(info.driver));
848 drvname[sizeof(info.driver) - 1] = '\0';
850 /* clear struct for return */
851 memset(&info, 0, sizeof(info));
854 /* if requested, identify ourselves */
855 if (strcmp(drvname, "?dhd") == 0) {
856 sprintf(info.driver, "dhd");
857 strcpy(info.version, BRCMF_VERSION_STR);
860 /* otherwise, require dongle to be up */
861 else if (!drvr_priv->pub.up) {
862 brcmf_dbg(ERROR, "dongle is not up\n");
866 /* finally, report dongle driver type */
867 else if (drvr_priv->pub.iswl)
868 sprintf(info.driver, "wl");
870 sprintf(info.driver, "xx");
872 sprintf(info.version, "%lu", drvr_priv->pub.drv_version);
873 if (copy_to_user(uaddr, &info, sizeof(info)))
875 brcmf_dbg(CTL, "given %*s, returning %s\n",
876 (int)sizeof(drvname), drvname, info.driver);
879 /* Get toe offload components from dongle */
880 case ETHTOOL_GRXCSUM:
881 case ETHTOOL_GTXCSUM:
882 ret = brcmf_toe_get(drvr_priv, 0, &toe_cmpnt);
887 (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
890 edata.data = (toe_cmpnt & csum_dir) ? 1 : 0;
892 if (copy_to_user(uaddr, &edata, sizeof(edata)))
896 /* Set toe offload components in dongle */
897 case ETHTOOL_SRXCSUM:
898 case ETHTOOL_STXCSUM:
899 if (copy_from_user(&edata, uaddr, sizeof(edata)))
902 /* Read the current settings, update and write back */
903 ret = brcmf_toe_get(drvr_priv, 0, &toe_cmpnt);
908 (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
911 toe_cmpnt |= csum_dir;
913 toe_cmpnt &= ~csum_dir;
915 ret = brcmf_toe_set(drvr_priv, 0, toe_cmpnt);
919 /* If setting TX checksum mode, tell Linux the new mode */
920 if (cmd == ETHTOOL_STXCSUM) {
922 drvr_priv->iflist[0]->net->features |=
925 drvr_priv->iflist[0]->net->features &=
938 static int brcmf_netdev_ioctl_entry(struct net_device *net, struct ifreq *ifr,
941 struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net);
942 struct brcmf_c_ioctl ioc;
950 ifidx = brcmf_net2idx(drvr_priv, net);
951 brcmf_dbg(TRACE, "ifidx %d, cmd 0x%04x\n", ifidx, cmd);
953 if (ifidx == BRCMF_BAD_IF)
956 if (cmd == SIOCETHTOOL)
957 return brcmf_ethtool(drvr_priv, ifr->ifr_data);
959 if (cmd != SIOCDEVPRIVATE)
962 memset(&ioc, 0, sizeof(ioc));
964 /* Copy the ioc control structure part of ioctl request */
965 if (copy_from_user(&ioc, ifr->ifr_data, sizeof(struct brcmf_ioctl))) {
970 /* Copy out any buffer passed */
972 buflen = min_t(int, ioc.len, BRCMF_IOCTL_MAXLEN);
973 /* optimization for direct ioctl calls from kernel */
975 if (segment_eq(get_fs(), KERNEL_DS)) {
980 buf = kmalloc(buflen, GFP_ATOMIC);
985 if (copy_from_user(buf, ioc.buf, buflen)) {
992 /* To differentiate read 4 more byes */
993 if ((copy_from_user(&driver, (char *)ifr->ifr_data +
994 sizeof(struct brcmf_ioctl), sizeof(uint)) != 0)) {
999 if (!capable(CAP_NET_ADMIN)) {
1004 /* check for local brcmf ioctl and handle it */
1005 if (driver == BRCMF_IOCTL_MAGIC) {
1006 bcmerror = brcmf_c_ioctl((void *)&drvr_priv->pub, &ioc,
1009 drvr_priv->pub.bcmerror = bcmerror;
1013 /* send to dongle (must be up, and wl) */
1014 if ((drvr_priv->pub.busstate != BRCMF_BUS_DATA)) {
1015 brcmf_dbg(ERROR, "DONGLE_DOWN\n");
1020 if (!drvr_priv->pub.iswl) {
1026 * Intercept BRCMF_C_SET_KEY IOCTL - serialize M4 send and
1027 * set key IOCTL to prevent M4 encryption.
1029 is_set_key_cmd = ((ioc.cmd == BRCMF_C_SET_KEY) ||
1030 ((ioc.cmd == BRCMF_C_SET_VAR) &&
1031 !(strncmp("wsec_key", ioc.buf, 9))) ||
1032 ((ioc.cmd == BRCMF_C_SET_VAR) &&
1033 !(strncmp("bsscfg:wsec_key", ioc.buf, 15))));
1035 brcmf_netdev_wait_pend8021x(net);
1037 bcmerror = brcmf_proto_ioctl(&drvr_priv->pub, ifidx,
1038 (struct brcmf_ioctl *)&ioc, buf, buflen);
1041 if (!bcmerror && buf && ioc.buf) {
1042 if (copy_to_user(ioc.buf, buf, buflen))
1054 static int brcmf_netdev_stop(struct net_device *net)
1056 struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net);
1058 brcmf_dbg(TRACE, "Enter\n");
1059 brcmf_cfg80211_down();
1060 if (drvr_priv->pub.up == 0)
1063 /* Set state and stop OS transmissions */
1064 drvr_priv->pub.up = 0;
1065 netif_stop_queue(net);
1070 static int brcmf_netdev_open(struct net_device *net)
1072 struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net);
1074 int ifidx = brcmf_net2idx(drvr_priv, net);
1077 brcmf_dbg(TRACE, "ifidx %d\n", ifidx);
1079 if (ifidx == 0) { /* do it only for primary eth0 */
1081 /* try to bring up bus */
1082 ret = brcmf_bus_start(&drvr_priv->pub);
1084 brcmf_dbg(ERROR, "failed with code %d\n", ret);
1087 atomic_set(&drvr_priv->pend_8021x_cnt, 0);
1089 memcpy(net->dev_addr, drvr_priv->pub.mac, ETH_ALEN);
1091 /* Get current TOE mode from dongle */
1092 if (brcmf_toe_get(drvr_priv, ifidx, &toe_ol) >= 0
1093 && (toe_ol & TOE_TX_CSUM_OL) != 0)
1094 drvr_priv->iflist[ifidx]->net->features |=
1097 drvr_priv->iflist[ifidx]->net->features &=
1100 /* Allow transmit calls */
1101 netif_start_queue(net);
1102 drvr_priv->pub.up = 1;
1103 if (unlikely(brcmf_cfg80211_up())) {
1104 brcmf_dbg(ERROR, "failed to bring up cfg80211\n");
1112 brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, struct net_device *net,
1113 char *name, u8 *mac_addr, u32 flags, u8 bssidx)
1115 struct brcmf_if *ifp;
1117 brcmf_dbg(TRACE, "idx %d, handle->%p\n", ifidx, net);
1119 ifp = drvr_priv->iflist[ifidx];
1121 ifp = kmalloc(sizeof(struct brcmf_if), GFP_ATOMIC);
1123 brcmf_dbg(ERROR, "OOM - struct brcmf_if\n");
1128 memset(ifp, 0, sizeof(struct brcmf_if));
1129 ifp->info = drvr_priv;
1130 drvr_priv->iflist[ifidx] = ifp;
1131 strlcpy(ifp->name, name, IFNAMSIZ);
1132 if (mac_addr != NULL)
1133 memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN);
1136 ifp->state = BRCMF_E_IF_ADD;
1138 wake_up(&drvr_priv->sysioc_waitq);
1145 void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx)
1147 struct brcmf_if *ifp;
1149 brcmf_dbg(TRACE, "idx %d\n", ifidx);
1151 ifp = drvr_priv->iflist[ifidx];
1153 brcmf_dbg(ERROR, "Null interface\n");
1157 ifp->state = BRCMF_E_IF_DEL;
1159 wake_up(&drvr_priv->sysioc_waitq);
1162 struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, uint bus_hdrlen)
1164 struct brcmf_info *drvr_priv = NULL;
1165 struct net_device *net;
1167 brcmf_dbg(TRACE, "Enter\n");
1169 /* Allocate etherdev, including space for private structure */
1170 net = alloc_etherdev(sizeof(drvr_priv));
1172 brcmf_dbg(ERROR, "OOM - alloc_etherdev\n");
1176 /* Allocate primary brcmf_info */
1177 drvr_priv = kzalloc(sizeof(struct brcmf_info), GFP_ATOMIC);
1179 brcmf_dbg(ERROR, "OOM - alloc brcmf_info\n");
1184 * Save the brcmf_info into the priv
1186 memcpy(netdev_priv(net), &drvr_priv, sizeof(drvr_priv));
1188 /* Set network interface name if it was provided as module parameter */
1189 if (iface_name[0]) {
1192 strncpy(net->name, iface_name, IFNAMSIZ);
1193 net->name[IFNAMSIZ - 1] = 0;
1194 len = strlen(net->name);
1195 ch = net->name[len - 1];
1196 if ((ch > '9' || ch < '0') && (len < IFNAMSIZ - 2))
1197 strcat(net->name, "%d");
1200 if (brcmf_add_if(drvr_priv, 0, net, net->name, NULL, 0, 0) ==
1204 net->netdev_ops = NULL;
1205 mutex_init(&drvr_priv->proto_block);
1207 /* Link to info module */
1208 drvr_priv->pub.info = drvr_priv;
1210 /* Link to bus module */
1211 drvr_priv->pub.bus = bus;
1212 drvr_priv->pub.hdrlen = bus_hdrlen;
1214 /* Attach and link in the protocol */
1215 if (brcmf_proto_attach(&drvr_priv->pub) != 0) {
1216 brcmf_dbg(ERROR, "brcmf_prot_attach failed\n");
1220 /* Attach and link in the cfg80211 */
1221 if (unlikely(brcmf_cfg80211_attach(net, &drvr_priv->pub))) {
1222 brcmf_dbg(ERROR, "wl_cfg80211_attach failed\n");
1227 init_waitqueue_head(&drvr_priv->sysioc_waitq);
1228 drvr_priv->sysioc_tsk = kthread_run(_brcmf_sysioc_thread,
1229 drvr_priv, "_brcmf_sysioc");
1230 if (IS_ERR(drvr_priv->sysioc_tsk)) {
1232 "_brcmf_sysioc thread failed to start\n");
1233 drvr_priv->sysioc_tsk = NULL;
1236 drvr_priv->sysioc_tsk = NULL;
1239 * Save the brcmf_info into the priv
1241 memcpy(netdev_priv(net), &drvr_priv, sizeof(drvr_priv));
1243 return &drvr_priv->pub;
1249 brcmf_detach(&drvr_priv->pub);
1254 int brcmf_bus_start(struct brcmf_pub *drvr)
1257 struct brcmf_info *drvr_priv = drvr->info;
1258 /* Room for "event_msgs" + '\0' + bitvec */
1259 char iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
1261 brcmf_dbg(TRACE, "\n");
1263 /* Bring up the bus */
1264 ret = brcmf_sdbrcm_bus_init(&drvr_priv->pub, true);
1266 brcmf_dbg(ERROR, "brcmf_sdbrcm_bus_init failed %d\n", ret);
1270 /* If bus is not ready, can't come up */
1271 if (drvr_priv->pub.busstate != BRCMF_BUS_DATA) {
1272 brcmf_dbg(ERROR, "failed bus is not ready\n");
1276 brcmu_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN,
1277 iovbuf, sizeof(iovbuf));
1278 brcmf_proto_cdc_query_ioctl(drvr, 0, BRCMF_C_GET_VAR, iovbuf,
1280 memcpy(drvr->eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
1282 setbit(drvr->eventmask, BRCMF_E_SET_SSID);
1283 setbit(drvr->eventmask, BRCMF_E_PRUNE);
1284 setbit(drvr->eventmask, BRCMF_E_AUTH);
1285 setbit(drvr->eventmask, BRCMF_E_REASSOC);
1286 setbit(drvr->eventmask, BRCMF_E_REASSOC_IND);
1287 setbit(drvr->eventmask, BRCMF_E_DEAUTH_IND);
1288 setbit(drvr->eventmask, BRCMF_E_DISASSOC_IND);
1289 setbit(drvr->eventmask, BRCMF_E_DISASSOC);
1290 setbit(drvr->eventmask, BRCMF_E_JOIN);
1291 setbit(drvr->eventmask, BRCMF_E_ASSOC_IND);
1292 setbit(drvr->eventmask, BRCMF_E_PSK_SUP);
1293 setbit(drvr->eventmask, BRCMF_E_LINK);
1294 setbit(drvr->eventmask, BRCMF_E_NDIS_LINK);
1295 setbit(drvr->eventmask, BRCMF_E_MIC_ERROR);
1296 setbit(drvr->eventmask, BRCMF_E_PMKID_CACHE);
1297 setbit(drvr->eventmask, BRCMF_E_TXFAIL);
1298 setbit(drvr->eventmask, BRCMF_E_JOIN_START);
1299 setbit(drvr->eventmask, BRCMF_E_SCAN_COMPLETE);
1301 /* enable dongle roaming event */
1303 drvr->pktfilter_count = 1;
1304 /* Setup filter to allow only unicast */
1305 drvr->pktfilter[0] = "100 0 0 0 0x01 0x00";
1307 /* Bus is ready, do any protocol initialization */
1308 ret = brcmf_proto_init(&drvr_priv->pub);
1315 static struct net_device_ops brcmf_netdev_ops_pri = {
1316 .ndo_open = brcmf_netdev_open,
1317 .ndo_stop = brcmf_netdev_stop,
1318 .ndo_get_stats = brcmf_netdev_get_stats,
1319 .ndo_do_ioctl = brcmf_netdev_ioctl_entry,
1320 .ndo_start_xmit = brcmf_netdev_start_xmit,
1321 .ndo_set_mac_address = brcmf_netdev_set_mac_address,
1322 .ndo_set_multicast_list = brcmf_netdev_set_multicast_list
1325 int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx)
1327 struct brcmf_info *drvr_priv = drvr->info;
1328 struct net_device *net;
1329 u8 temp_addr[ETH_ALEN] = {
1330 0x00, 0x90, 0x4c, 0x11, 0x22, 0x33};
1332 brcmf_dbg(TRACE, "ifidx %d\n", ifidx);
1334 net = drvr_priv->iflist[ifidx]->net;
1335 net->netdev_ops = &brcmf_netdev_ops_pri;
1338 * We have to use the primary MAC for virtual interfaces
1341 /* for virtual interfaces use the primary MAC */
1342 memcpy(temp_addr, drvr_priv->pub.mac, ETH_ALEN);
1347 brcmf_dbg(TRACE, "ACCESS POINT MAC:\n");
1348 /* ACCESSPOINT INTERFACE CASE */
1349 temp_addr[0] |= 0X02; /* set bit 2 ,
1350 - Locally Administered address */
1353 net->hard_header_len = ETH_HLEN + drvr_priv->pub.hdrlen;
1354 net->ethtool_ops = &brcmf_ethtool_ops;
1356 drvr_priv->pub.rxsz = net->mtu + net->hard_header_len +
1357 drvr_priv->pub.hdrlen;
1359 memcpy(net->dev_addr, temp_addr, ETH_ALEN);
1361 if (register_netdev(net) != 0) {
1362 brcmf_dbg(ERROR, "couldn't register the net device\n");
1366 brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", net->name);
1371 net->netdev_ops = NULL;
1375 static void brcmf_bus_detach(struct brcmf_pub *drvr)
1377 struct brcmf_info *drvr_priv;
1379 brcmf_dbg(TRACE, "Enter\n");
1382 drvr_priv = drvr->info;
1384 /* Stop the protocol module */
1385 brcmf_proto_stop(&drvr_priv->pub);
1387 /* Stop the bus module */
1388 brcmf_sdbrcm_bus_stop(drvr_priv->pub.bus, true);
1393 void brcmf_detach(struct brcmf_pub *drvr)
1395 struct brcmf_info *drvr_priv;
1397 brcmf_dbg(TRACE, "Enter\n");
1400 drvr_priv = drvr->info;
1402 struct brcmf_if *ifp;
1405 for (i = 1; i < BRCMF_MAX_IFS; i++)
1406 if (drvr_priv->iflist[i])
1407 brcmf_del_if(drvr_priv, i);
1409 ifp = drvr_priv->iflist[0];
1410 if (ifp->net->netdev_ops == &brcmf_netdev_ops_pri) {
1411 brcmf_netdev_stop(ifp->net);
1412 unregister_netdev(ifp->net);
1415 if (drvr_priv->sysioc_tsk) {
1416 send_sig(SIGTERM, drvr_priv->sysioc_tsk, 1);
1417 kthread_stop(drvr_priv->sysioc_tsk);
1418 drvr_priv->sysioc_tsk = NULL;
1421 brcmf_bus_detach(drvr);
1424 brcmf_proto_detach(drvr);
1426 brcmf_cfg80211_detach();
1428 free_netdev(ifp->net);
1435 static void __exit brcmf_module_cleanup(void)
1437 brcmf_dbg(TRACE, "Enter\n");
1439 brcmf_bus_unregister();
1442 static int __init brcmf_module_init(void)
1446 brcmf_dbg(TRACE, "Enter\n");
1448 error = brcmf_bus_register();
1451 brcmf_dbg(ERROR, "brcmf_bus_register failed\n");
1460 module_init(brcmf_module_init);
1461 module_exit(brcmf_module_cleanup);
1463 int brcmf_os_proto_block(struct brcmf_pub *drvr)
1465 struct brcmf_info *drvr_priv = drvr->info;
1468 mutex_lock(&drvr_priv->proto_block);
1474 int brcmf_os_proto_unblock(struct brcmf_pub *drvr)
1476 struct brcmf_info *drvr_priv = drvr->info;
1479 mutex_unlock(&drvr_priv->proto_block);
1486 static int brcmf_host_event(struct brcmf_info *drvr_priv, int *ifidx,
1487 void *pktdata, struct brcmf_event_msg *event,
1492 bcmerror = brcmf_c_host_event(drvr_priv, ifidx, pktdata, event, data);
1496 if (drvr_priv->iflist[*ifidx]->net)
1497 brcmf_cfg80211_event(drvr_priv->iflist[*ifidx]->net,
1503 int brcmf_netdev_reset(struct net_device *dev, u8 flag)
1505 struct brcmf_info *drvr_priv = *(struct brcmf_info **)netdev_priv(dev);
1507 brcmf_bus_devreset(&drvr_priv->pub, flag);
1512 static int brcmf_get_pend_8021x_cnt(struct brcmf_info *drvr_priv)
1514 return atomic_read(&drvr_priv->pend_8021x_cnt);
1517 #define MAX_WAIT_FOR_8021X_TX 10
1519 int brcmf_netdev_wait_pend8021x(struct net_device *dev)
1521 struct brcmf_info *drvr_priv = *(struct brcmf_info **)netdev_priv(dev);
1522 int timeout = 10 * HZ / 1000;
1523 int ntimes = MAX_WAIT_FOR_8021X_TX;
1524 int pend = brcmf_get_pend_8021x_cnt(drvr_priv);
1526 while (ntimes && pend) {
1528 set_current_state(TASK_INTERRUPTIBLE);
1529 schedule_timeout(timeout);
1530 set_current_state(TASK_RUNNING);
1533 pend = brcmf_get_pend_8021x_cnt(drvr_priv);
1539 int brcmf_write_to_file(struct brcmf_pub *drvr, u8 *buf, int size)
1543 mm_segment_t old_fs;
1546 /* change to KERNEL_DS address limit */
1550 /* open file to write */
1551 fp = filp_open("/tmp/mem_dump", O_WRONLY | O_CREAT, 0640);
1553 brcmf_dbg(ERROR, "open file error\n");
1558 /* Write buf to file */
1559 fp->f_op->write(fp, buf, size, &pos);
1562 /* free buf before return */
1564 /* close file before return */
1566 filp_close(fp, current->files);
1567 /* restore previous address limit */