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/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>
27 #include "dhd_proto.h"
29 #include "fwil_types.h"
31 #include "wl_cfg80211.h"
35 MODULE_AUTHOR("Broadcom Corporation");
36 MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
37 MODULE_LICENSE("Dual BSD/GPL");
39 #define MAX_WAIT_FOR_8021X_TX 50 /* msecs */
43 module_param_named(debug
, brcmf_msg_level
, int, S_IRUSR
| S_IWUSR
);
44 MODULE_PARM_DESC(debug
, "level of debug output");
47 static int brcmf_p2p_enable
;
49 module_param_named(p2pon
, brcmf_p2p_enable
, int, 0);
50 MODULE_PARM_DESC(p2pon
, "enable p2p management functionality");
53 char *brcmf_ifname(struct brcmf_pub
*drvr
, int ifidx
)
55 if (ifidx
< 0 || ifidx
>= BRCMF_MAX_IFS
) {
56 brcmf_err("ifidx %d out of range\n", ifidx
);
60 if (drvr
->iflist
[ifidx
] == NULL
) {
61 brcmf_err("null i/f %d\n", ifidx
);
65 if (drvr
->iflist
[ifidx
]->ndev
)
66 return drvr
->iflist
[ifidx
]->ndev
->name
;
71 static void _brcmf_set_multicast_list(struct work_struct
*work
)
74 struct net_device
*ndev
;
75 struct netdev_hw_addr
*ha
;
82 ifp
= container_of(work
, struct brcmf_if
, multicast_work
);
84 brcmf_dbg(TRACE
, "Enter, idx=%d\n", ifp
->bssidx
);
88 /* Determine initial value of allmulti flag */
89 cmd_value
= (ndev
->flags
& IFF_ALLMULTI
) ? true : false;
91 /* Send down the multicast list first. */
92 cnt
= netdev_mc_count(ndev
);
93 buflen
= sizeof(cnt
) + (cnt
* ETH_ALEN
);
94 buf
= kmalloc(buflen
, GFP_ATOMIC
);
99 cnt_le
= cpu_to_le32(cnt
);
100 memcpy(bufp
, &cnt_le
, sizeof(cnt_le
));
101 bufp
+= sizeof(cnt_le
);
103 netdev_for_each_mc_addr(ha
, ndev
) {
106 memcpy(bufp
, ha
->addr
, ETH_ALEN
);
111 err
= brcmf_fil_iovar_data_set(ifp
, "mcast_list", buf
, buflen
);
113 brcmf_err("Setting mcast_list failed, %d\n", err
);
114 cmd_value
= cnt
? true : cmd_value
;
120 * Now send the allmulti setting. This is based on the setting in the
121 * net_device flags, but might be modified above to be turned on if we
122 * were trying to set some addresses and dongle rejected it...
124 err
= brcmf_fil_iovar_int_set(ifp
, "allmulti", cmd_value
);
126 brcmf_err("Setting allmulti failed, %d\n", err
);
128 /*Finally, pick up the PROMISC flag */
129 cmd_value
= (ndev
->flags
& IFF_PROMISC
) ? true : false;
130 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PROMISC
, cmd_value
);
132 brcmf_err("Setting BRCMF_C_SET_PROMISC failed, %d\n",
137 _brcmf_set_mac_address(struct work_struct
*work
)
139 struct brcmf_if
*ifp
;
142 ifp
= container_of(work
, struct brcmf_if
, setmacaddr_work
);
144 brcmf_dbg(TRACE
, "Enter, idx=%d\n", ifp
->bssidx
);
146 err
= brcmf_fil_iovar_data_set(ifp
, "cur_etheraddr", ifp
->mac_addr
,
149 brcmf_err("Setting cur_etheraddr failed, %d\n", err
);
151 brcmf_dbg(TRACE
, "MAC address updated to %pM\n",
153 memcpy(ifp
->ndev
->dev_addr
, ifp
->mac_addr
, ETH_ALEN
);
157 static int brcmf_netdev_set_mac_address(struct net_device
*ndev
, void *addr
)
159 struct brcmf_if
*ifp
= netdev_priv(ndev
);
160 struct sockaddr
*sa
= (struct sockaddr
*)addr
;
162 memcpy(&ifp
->mac_addr
, sa
->sa_data
, ETH_ALEN
);
163 schedule_work(&ifp
->setmacaddr_work
);
167 static void brcmf_netdev_set_multicast_list(struct net_device
*ndev
)
169 struct brcmf_if
*ifp
= netdev_priv(ndev
);
171 schedule_work(&ifp
->multicast_work
);
174 static netdev_tx_t
brcmf_netdev_start_xmit(struct sk_buff
*skb
,
175 struct net_device
*ndev
)
178 struct brcmf_if
*ifp
= netdev_priv(ndev
);
179 struct brcmf_pub
*drvr
= ifp
->drvr
;
182 brcmf_dbg(DATA
, "Enter, idx=%d\n", ifp
->bssidx
);
184 /* Can the device send data? */
185 if (drvr
->bus_if
->state
!= BRCMF_BUS_DATA
) {
186 brcmf_err("xmit rejected state=%d\n", drvr
->bus_if
->state
);
187 netif_stop_queue(ndev
);
193 if (!drvr
->iflist
[ifp
->bssidx
]) {
194 brcmf_err("bad ifidx %d\n", ifp
->bssidx
);
195 netif_stop_queue(ndev
);
201 /* Make sure there's enough room for any header */
202 if (skb_headroom(skb
) < drvr
->hdrlen
) {
203 struct sk_buff
*skb2
;
205 brcmf_dbg(INFO
, "%s: insufficient headroom\n",
206 brcmf_ifname(drvr
, ifp
->bssidx
));
207 drvr
->bus_if
->tx_realloc
++;
208 skb2
= skb_realloc_headroom(skb
, drvr
->hdrlen
);
212 brcmf_err("%s: skb_realloc_headroom failed\n",
213 brcmf_ifname(drvr
, ifp
->bssidx
));
219 /* validate length for ether packet */
220 if (skb
->len
< sizeof(*eh
)) {
226 ret
= brcmf_fws_process_skb(ifp
, skb
);
230 ifp
->stats
.tx_dropped
++;
232 ifp
->stats
.tx_packets
++;
233 ifp
->stats
.tx_bytes
+= skb
->len
;
236 /* Return ok: we always eat the packet */
240 void brcmf_txflowblock_if(struct brcmf_if
*ifp
,
241 enum brcmf_netif_stop_reason reason
, bool state
)
248 brcmf_dbg(TRACE
, "enter: idx=%d stop=0x%X reason=%d state=%d\n",
249 ifp
->bssidx
, ifp
->netif_stop
, reason
, state
);
251 spin_lock_irqsave(&ifp
->netif_stop_lock
, flags
);
253 if (!ifp
->netif_stop
)
254 netif_stop_queue(ifp
->ndev
);
255 ifp
->netif_stop
|= reason
;
257 ifp
->netif_stop
&= ~reason
;
258 if (!ifp
->netif_stop
)
259 netif_wake_queue(ifp
->ndev
);
261 spin_unlock_irqrestore(&ifp
->netif_stop_lock
, flags
);
264 void brcmf_txflowblock(struct device
*dev
, bool state
)
266 struct brcmf_bus
*bus_if
= dev_get_drvdata(dev
);
267 struct brcmf_pub
*drvr
= bus_if
->drvr
;
270 brcmf_dbg(TRACE
, "Enter\n");
272 if (brcmf_fws_fc_active(drvr
->fws
)) {
273 brcmf_fws_bus_blocked(drvr
, state
);
275 for (i
= 0; i
< BRCMF_MAX_IFS
; i
++)
276 brcmf_txflowblock_if(drvr
->iflist
[i
],
277 BRCMF_NETIF_STOP_REASON_BLOCK_BUS
,
282 void brcmf_rx_frames(struct device
*dev
, struct sk_buff_head
*skb_list
)
284 struct sk_buff
*skb
, *pnext
;
285 struct brcmf_if
*ifp
;
286 struct brcmf_bus
*bus_if
= dev_get_drvdata(dev
);
287 struct brcmf_pub
*drvr
= bus_if
->drvr
;
291 brcmf_dbg(DATA
, "Enter\n");
293 skb_queue_walk_safe(skb_list
, skb
, pnext
) {
294 skb_unlink(skb
, skb_list
);
296 /* process and remove protocol-specific header */
297 ret
= brcmf_proto_hdrpull(drvr
, drvr
->fw_signals
, &ifidx
, skb
);
298 ifp
= drvr
->iflist
[ifidx
];
300 if (ret
|| !ifp
|| !ifp
->ndev
) {
301 if ((ret
!= -ENODATA
) && ifp
)
302 ifp
->stats
.rx_errors
++;
303 brcmu_pkt_buf_free_skb(skb
);
307 skb
->dev
= ifp
->ndev
;
308 skb
->protocol
= eth_type_trans(skb
, skb
->dev
);
310 if (skb
->pkt_type
== PACKET_MULTICAST
)
311 ifp
->stats
.multicast
++;
313 /* Process special event packets */
314 brcmf_fweh_process_skb(drvr
, skb
);
316 if (!(ifp
->ndev
->flags
& IFF_UP
)) {
317 brcmu_pkt_buf_free_skb(skb
);
321 ifp
->stats
.rx_bytes
+= skb
->len
;
322 ifp
->stats
.rx_packets
++;
327 /* If the receive is not processed inside an ISR,
328 * the softirqd must be woken explicitly to service the
329 * NET_RX_SOFTIRQ. This is handled by netif_rx_ni().
335 void brcmf_txfinalize(struct brcmf_pub
*drvr
, struct sk_buff
*txp
,
338 struct brcmf_if
*ifp
;
344 res
= brcmf_proto_hdrpull(drvr
, false, &ifidx
, txp
);
346 ifp
= drvr
->iflist
[ifidx
];
351 eh
= (struct ethhdr
*)(txp
->data
);
352 type
= ntohs(eh
->h_proto
);
354 if (type
== ETH_P_PAE
) {
355 atomic_dec(&ifp
->pend_8021x_cnt
);
356 if (waitqueue_active(&ifp
->pend_8021x_wait
))
357 wake_up(&ifp
->pend_8021x_wait
);
361 ifp
->stats
.tx_errors
++;
363 brcmu_pkt_buf_free_skb(txp
);
366 void brcmf_txcomplete(struct device
*dev
, struct sk_buff
*txp
, bool success
)
368 struct brcmf_bus
*bus_if
= dev_get_drvdata(dev
);
369 struct brcmf_pub
*drvr
= bus_if
->drvr
;
371 /* await txstatus signal for firmware if active */
372 if (brcmf_fws_fc_active(drvr
->fws
)) {
374 brcmf_fws_bustxfail(drvr
->fws
, txp
);
376 brcmf_txfinalize(drvr
, txp
, success
);
380 static struct net_device_stats
*brcmf_netdev_get_stats(struct net_device
*ndev
)
382 struct brcmf_if
*ifp
= netdev_priv(ndev
);
384 brcmf_dbg(TRACE
, "Enter, idx=%d\n", ifp
->bssidx
);
390 * Set current toe component enables in toe_ol iovar,
391 * and set toe global enable iovar
393 static int brcmf_toe_set(struct brcmf_if
*ifp
, u32 toe_ol
)
397 err
= brcmf_fil_iovar_int_set(ifp
, "toe_ol", toe_ol
);
399 brcmf_err("Setting toe_ol failed, %d\n", err
);
403 err
= brcmf_fil_iovar_int_set(ifp
, "toe", (toe_ol
!= 0));
405 brcmf_err("Setting toe failed, %d\n", err
);
411 static void brcmf_ethtool_get_drvinfo(struct net_device
*ndev
,
412 struct ethtool_drvinfo
*info
)
414 struct brcmf_if
*ifp
= netdev_priv(ndev
);
415 struct brcmf_pub
*drvr
= ifp
->drvr
;
417 strlcpy(info
->driver
, KBUILD_MODNAME
, sizeof(info
->driver
));
418 snprintf(info
->version
, sizeof(info
->version
), "%lu",
420 strlcpy(info
->bus_info
, dev_name(drvr
->bus_if
->dev
),
421 sizeof(info
->bus_info
));
424 static const struct ethtool_ops brcmf_ethtool_ops
= {
425 .get_drvinfo
= brcmf_ethtool_get_drvinfo
,
428 static int brcmf_ethtool(struct brcmf_if
*ifp
, void __user
*uaddr
)
430 struct brcmf_pub
*drvr
= ifp
->drvr
;
431 struct ethtool_drvinfo info
;
432 char drvname
[sizeof(info
.driver
)];
434 struct ethtool_value edata
;
435 u32 toe_cmpnt
, csum_dir
;
438 brcmf_dbg(TRACE
, "Enter, idx=%d\n", ifp
->bssidx
);
440 /* all ethtool calls start with a cmd word */
441 if (copy_from_user(&cmd
, uaddr
, sizeof(u32
)))
445 case ETHTOOL_GDRVINFO
:
446 /* Copy out any request driver name */
447 if (copy_from_user(&info
, uaddr
, sizeof(info
)))
449 strncpy(drvname
, info
.driver
, sizeof(info
.driver
));
450 drvname
[sizeof(info
.driver
) - 1] = '\0';
452 /* clear struct for return */
453 memset(&info
, 0, sizeof(info
));
456 /* if requested, identify ourselves */
457 if (strcmp(drvname
, "?dhd") == 0) {
458 sprintf(info
.driver
, "dhd");
459 strcpy(info
.version
, BRCMF_VERSION_STR
);
461 /* report dongle driver type */
463 sprintf(info
.driver
, "wl");
465 sprintf(info
.version
, "%lu", drvr
->drv_version
);
466 if (copy_to_user(uaddr
, &info
, sizeof(info
)))
468 brcmf_dbg(TRACE
, "given %*s, returning %s\n",
469 (int)sizeof(drvname
), drvname
, info
.driver
);
472 /* Get toe offload components from dongle */
473 case ETHTOOL_GRXCSUM
:
474 case ETHTOOL_GTXCSUM
:
475 ret
= brcmf_fil_iovar_int_get(ifp
, "toe_ol", &toe_cmpnt
);
480 (cmd
== ETHTOOL_GTXCSUM
) ? TOE_TX_CSUM_OL
: TOE_RX_CSUM_OL
;
483 edata
.data
= (toe_cmpnt
& csum_dir
) ? 1 : 0;
485 if (copy_to_user(uaddr
, &edata
, sizeof(edata
)))
489 /* Set toe offload components in dongle */
490 case ETHTOOL_SRXCSUM
:
491 case ETHTOOL_STXCSUM
:
492 if (copy_from_user(&edata
, uaddr
, sizeof(edata
)))
495 /* Read the current settings, update and write back */
496 ret
= brcmf_fil_iovar_int_get(ifp
, "toe_ol", &toe_cmpnt
);
501 (cmd
== ETHTOOL_STXCSUM
) ? TOE_TX_CSUM_OL
: TOE_RX_CSUM_OL
;
504 toe_cmpnt
|= csum_dir
;
506 toe_cmpnt
&= ~csum_dir
;
508 ret
= brcmf_toe_set(ifp
, toe_cmpnt
);
512 /* If setting TX checksum mode, tell Linux the new mode */
513 if (cmd
== ETHTOOL_STXCSUM
) {
515 ifp
->ndev
->features
|= NETIF_F_IP_CSUM
;
517 ifp
->ndev
->features
&= ~NETIF_F_IP_CSUM
;
529 static int brcmf_netdev_ioctl_entry(struct net_device
*ndev
, struct ifreq
*ifr
,
532 struct brcmf_if
*ifp
= netdev_priv(ndev
);
533 struct brcmf_pub
*drvr
= ifp
->drvr
;
535 brcmf_dbg(TRACE
, "Enter, idx=%d, cmd=0x%04x\n", ifp
->bssidx
, cmd
);
537 if (!drvr
->iflist
[ifp
->bssidx
])
540 if (cmd
== SIOCETHTOOL
)
541 return brcmf_ethtool(ifp
, ifr
->ifr_data
);
546 static int brcmf_netdev_stop(struct net_device
*ndev
)
548 struct brcmf_if
*ifp
= netdev_priv(ndev
);
550 brcmf_dbg(TRACE
, "Enter, idx=%d\n", ifp
->bssidx
);
552 brcmf_cfg80211_down(ndev
);
554 /* Set state and stop OS transmissions */
555 netif_stop_queue(ndev
);
560 static int brcmf_netdev_open(struct net_device
*ndev
)
562 struct brcmf_if
*ifp
= netdev_priv(ndev
);
563 struct brcmf_pub
*drvr
= ifp
->drvr
;
564 struct brcmf_bus
*bus_if
= drvr
->bus_if
;
568 brcmf_dbg(TRACE
, "Enter, idx=%d\n", ifp
->bssidx
);
570 /* If bus is not ready, can't continue */
571 if (bus_if
->state
!= BRCMF_BUS_DATA
) {
572 brcmf_err("failed bus is not ready\n");
576 atomic_set(&ifp
->pend_8021x_cnt
, 0);
578 /* Get current TOE mode from dongle */
579 if (brcmf_fil_iovar_int_get(ifp
, "toe_ol", &toe_ol
) >= 0
580 && (toe_ol
& TOE_TX_CSUM_OL
) != 0)
581 ndev
->features
|= NETIF_F_IP_CSUM
;
583 ndev
->features
&= ~NETIF_F_IP_CSUM
;
585 /* Allow transmit calls */
586 netif_start_queue(ndev
);
587 if (brcmf_cfg80211_up(ndev
)) {
588 brcmf_err("failed to bring up cfg80211\n");
595 static const struct net_device_ops brcmf_netdev_ops_pri
= {
596 .ndo_open
= brcmf_netdev_open
,
597 .ndo_stop
= brcmf_netdev_stop
,
598 .ndo_get_stats
= brcmf_netdev_get_stats
,
599 .ndo_do_ioctl
= brcmf_netdev_ioctl_entry
,
600 .ndo_start_xmit
= brcmf_netdev_start_xmit
,
601 .ndo_set_mac_address
= brcmf_netdev_set_mac_address
,
602 .ndo_set_rx_mode
= brcmf_netdev_set_multicast_list
605 int brcmf_net_attach(struct brcmf_if
*ifp
, bool rtnl_locked
)
607 struct brcmf_pub
*drvr
= ifp
->drvr
;
608 struct net_device
*ndev
;
611 brcmf_dbg(TRACE
, "Enter, idx=%d mac=%pM\n", ifp
->bssidx
,
615 /* set appropriate operations */
616 ndev
->netdev_ops
= &brcmf_netdev_ops_pri
;
618 ndev
->hard_header_len
+= drvr
->hdrlen
;
619 ndev
->ethtool_ops
= &brcmf_ethtool_ops
;
621 drvr
->rxsz
= ndev
->mtu
+ ndev
->hard_header_len
+
624 /* set the mac address */
625 memcpy(ndev
->dev_addr
, ifp
->mac_addr
, ETH_ALEN
);
627 INIT_WORK(&ifp
->setmacaddr_work
, _brcmf_set_mac_address
);
628 INIT_WORK(&ifp
->multicast_work
, _brcmf_set_multicast_list
);
631 err
= register_netdevice(ndev
);
633 err
= register_netdev(ndev
);
635 brcmf_err("couldn't register the net device\n");
639 brcmf_dbg(INFO
, "%s: Broadcom Dongle Host Driver\n", ndev
->name
);
641 ndev
->destructor
= free_netdev
;
645 drvr
->iflist
[ifp
->bssidx
] = NULL
;
646 ndev
->netdev_ops
= NULL
;
651 static int brcmf_net_p2p_open(struct net_device
*ndev
)
653 brcmf_dbg(TRACE
, "Enter\n");
655 return brcmf_cfg80211_up(ndev
);
658 static int brcmf_net_p2p_stop(struct net_device
*ndev
)
660 brcmf_dbg(TRACE
, "Enter\n");
662 return brcmf_cfg80211_down(ndev
);
665 static int brcmf_net_p2p_do_ioctl(struct net_device
*ndev
,
666 struct ifreq
*ifr
, int cmd
)
668 brcmf_dbg(TRACE
, "Enter\n");
672 static netdev_tx_t
brcmf_net_p2p_start_xmit(struct sk_buff
*skb
,
673 struct net_device
*ndev
)
676 dev_kfree_skb_any(skb
);
681 static const struct net_device_ops brcmf_netdev_ops_p2p
= {
682 .ndo_open
= brcmf_net_p2p_open
,
683 .ndo_stop
= brcmf_net_p2p_stop
,
684 .ndo_do_ioctl
= brcmf_net_p2p_do_ioctl
,
685 .ndo_start_xmit
= brcmf_net_p2p_start_xmit
688 static int brcmf_net_p2p_attach(struct brcmf_if
*ifp
)
690 struct net_device
*ndev
;
692 brcmf_dbg(TRACE
, "Enter, idx=%d mac=%pM\n", ifp
->bssidx
,
696 ndev
->netdev_ops
= &brcmf_netdev_ops_p2p
;
698 /* set the mac address */
699 memcpy(ndev
->dev_addr
, ifp
->mac_addr
, ETH_ALEN
);
701 if (register_netdev(ndev
) != 0) {
702 brcmf_err("couldn't register the p2p net device\n");
706 brcmf_dbg(INFO
, "%s: Broadcom Dongle Host Driver\n", ndev
->name
);
711 ifp
->drvr
->iflist
[ifp
->bssidx
] = NULL
;
712 ndev
->netdev_ops
= NULL
;
717 struct brcmf_if
*brcmf_add_if(struct brcmf_pub
*drvr
, s32 bssidx
, s32 ifidx
,
718 char *name
, u8
*mac_addr
)
720 struct brcmf_if
*ifp
;
721 struct net_device
*ndev
;
723 brcmf_dbg(TRACE
, "Enter, idx=%d, ifidx=%d\n", bssidx
, ifidx
);
725 ifp
= drvr
->iflist
[bssidx
];
727 * Delete the existing interface before overwriting it
728 * in case we missed the BRCMF_E_IF_DEL event.
731 brcmf_err("ERROR: netdev:%s already exists\n",
734 netif_stop_queue(ifp
->ndev
);
735 unregister_netdev(ifp
->ndev
);
736 free_netdev(ifp
->ndev
);
737 drvr
->iflist
[bssidx
] = NULL
;
739 brcmf_err("ignore IF event\n");
740 return ERR_PTR(-EINVAL
);
744 if (!brcmf_p2p_enable
&& bssidx
== 1) {
745 /* this is P2P_DEVICE interface */
746 brcmf_dbg(INFO
, "allocate non-netdev interface\n");
747 ifp
= kzalloc(sizeof(*ifp
), GFP_KERNEL
);
749 return ERR_PTR(-ENOMEM
);
751 brcmf_dbg(INFO
, "allocate netdev interface\n");
752 /* Allocate netdev, including space for private structure */
753 ndev
= alloc_netdev(sizeof(*ifp
), name
, ether_setup
);
755 return ERR_PTR(-ENOMEM
);
757 ifp
= netdev_priv(ndev
);
762 drvr
->iflist
[bssidx
] = ifp
;
764 ifp
->bssidx
= bssidx
;
766 init_waitqueue_head(&ifp
->pend_8021x_wait
);
767 spin_lock_init(&ifp
->netif_stop_lock
);
769 if (mac_addr
!= NULL
)
770 memcpy(ifp
->mac_addr
, mac_addr
, ETH_ALEN
);
772 brcmf_dbg(TRACE
, " ==== pid:%x, if:%s (%pM) created ===\n",
773 current
->pid
, name
, ifp
->mac_addr
);
778 void brcmf_del_if(struct brcmf_pub
*drvr
, s32 bssidx
)
780 struct brcmf_if
*ifp
;
782 ifp
= drvr
->iflist
[bssidx
];
783 drvr
->iflist
[bssidx
] = NULL
;
785 brcmf_err("Null interface, idx=%d\n", bssidx
);
788 brcmf_dbg(TRACE
, "Enter, idx=%d, ifidx=%d\n", bssidx
, ifp
->ifidx
);
791 if (ifp
->ndev
->netdev_ops
== &brcmf_netdev_ops_pri
) {
793 brcmf_netdev_stop(ifp
->ndev
);
797 netif_stop_queue(ifp
->ndev
);
800 if (ifp
->ndev
->netdev_ops
== &brcmf_netdev_ops_pri
) {
801 cancel_work_sync(&ifp
->setmacaddr_work
);
802 cancel_work_sync(&ifp
->multicast_work
);
804 /* unregister will take care of freeing it */
805 unregister_netdev(ifp
->ndev
);
807 brcmf_cfg80211_detach(drvr
->config
);
813 int brcmf_attach(uint bus_hdrlen
, struct device
*dev
)
815 struct brcmf_pub
*drvr
= NULL
;
818 brcmf_dbg(TRACE
, "Enter\n");
820 /* Allocate primary brcmf_info */
821 drvr
= kzalloc(sizeof(struct brcmf_pub
), GFP_ATOMIC
);
825 mutex_init(&drvr
->proto_block
);
827 /* Link to bus module */
828 drvr
->hdrlen
= bus_hdrlen
;
829 drvr
->bus_if
= dev_get_drvdata(dev
);
830 drvr
->bus_if
->drvr
= drvr
;
832 /* create device debugfs folder */
833 brcmf_debugfs_attach(drvr
);
835 /* Attach and link in the protocol */
836 ret
= brcmf_proto_attach(drvr
);
838 brcmf_err("brcmf_prot_attach failed\n");
842 /* attach firmware event handler */
843 brcmf_fweh_attach(drvr
);
845 INIT_LIST_HEAD(&drvr
->bus_if
->dcmd_list
);
855 int brcmf_bus_start(struct device
*dev
)
858 struct brcmf_bus
*bus_if
= dev_get_drvdata(dev
);
859 struct brcmf_pub
*drvr
= bus_if
->drvr
;
860 struct brcmf_if
*ifp
;
861 struct brcmf_if
*p2p_ifp
;
863 brcmf_dbg(TRACE
, "\n");
865 /* Bring up the bus */
866 ret
= brcmf_bus_init(bus_if
);
868 brcmf_err("brcmf_sdbrcm_bus_init failed %d\n", ret
);
872 /* add primary networking interface */
873 ifp
= brcmf_add_if(drvr
, 0, 0, "wlan%d", NULL
);
877 if (brcmf_p2p_enable
)
878 p2p_ifp
= brcmf_add_if(drvr
, 1, 0, "p2p%d", NULL
);
884 /* signal bus ready */
885 bus_if
->state
= BRCMF_BUS_DATA
;
887 /* Bus is ready, do any initialization */
888 ret
= brcmf_c_preinit_dcmds(ifp
);
892 drvr
->fw_signals
= true;
893 ret
= brcmf_fws_init(drvr
);
897 brcmf_fws_add_interface(ifp
);
899 drvr
->config
= brcmf_cfg80211_attach(drvr
, bus_if
->dev
);
900 if (drvr
->config
== NULL
) {
905 ret
= brcmf_fweh_activate_events(ifp
);
909 ret
= brcmf_net_attach(ifp
, false);
912 brcmf_err("failed: %d\n", ret
);
914 brcmf_cfg80211_detach(drvr
->config
);
916 brcmf_fws_del_interface(ifp
);
917 brcmf_fws_deinit(drvr
);
919 if (drvr
->iflist
[0]) {
920 free_netdev(ifp
->ndev
);
921 drvr
->iflist
[0] = NULL
;
924 free_netdev(p2p_ifp
->ndev
);
925 drvr
->iflist
[1] = NULL
;
929 if ((brcmf_p2p_enable
) && (p2p_ifp
))
930 if (brcmf_net_p2p_attach(p2p_ifp
) < 0)
931 brcmf_p2p_enable
= 0;
936 static void brcmf_bus_detach(struct brcmf_pub
*drvr
)
938 brcmf_dbg(TRACE
, "Enter\n");
941 /* Stop the protocol module */
942 brcmf_proto_stop(drvr
);
944 /* Stop the bus module */
945 brcmf_bus_stop(drvr
->bus_if
);
949 void brcmf_dev_reset(struct device
*dev
)
951 struct brcmf_bus
*bus_if
= dev_get_drvdata(dev
);
952 struct brcmf_pub
*drvr
= bus_if
->drvr
;
958 brcmf_fil_cmd_int_set(drvr
->iflist
[0], BRCMF_C_TERMINATED
, 1);
961 void brcmf_detach(struct device
*dev
)
964 struct brcmf_bus
*bus_if
= dev_get_drvdata(dev
);
965 struct brcmf_pub
*drvr
= bus_if
->drvr
;
967 brcmf_dbg(TRACE
, "Enter\n");
972 /* stop firmware event handling */
973 brcmf_fweh_detach(drvr
);
975 /* make sure primary interface removed last */
976 for (i
= BRCMF_MAX_IFS
-1; i
> -1; i
--)
977 if (drvr
->iflist
[i
]) {
978 brcmf_fws_del_interface(drvr
->iflist
[i
]);
979 brcmf_del_if(drvr
, i
);
982 brcmf_bus_detach(drvr
);
985 brcmf_proto_detach(drvr
);
987 brcmf_fws_deinit(drvr
);
989 brcmf_debugfs_detach(drvr
);
994 static int brcmf_get_pend_8021x_cnt(struct brcmf_if
*ifp
)
996 return atomic_read(&ifp
->pend_8021x_cnt
);
999 int brcmf_netdev_wait_pend8021x(struct net_device
*ndev
)
1001 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1004 err
= wait_event_timeout(ifp
->pend_8021x_wait
,
1005 !brcmf_get_pend_8021x_cnt(ifp
),
1006 msecs_to_jiffies(MAX_WAIT_FOR_8021X_TX
));
1014 * return chip id and rev of the device encoded in u32.
1016 u32
brcmf_get_chip_info(struct brcmf_if
*ifp
)
1018 struct brcmf_bus
*bus
= ifp
->drvr
->bus_if
;
1020 return bus
->chip
<< 4 | bus
->chiprev
;
1023 static void brcmf_driver_init(struct work_struct
*work
)
1025 brcmf_debugfs_init();
1027 #ifdef CONFIG_BRCMFMAC_SDIO
1030 #ifdef CONFIG_BRCMFMAC_USB
1034 static DECLARE_WORK(brcmf_driver_work
, brcmf_driver_init
);
1036 static int __init
brcmfmac_module_init(void)
1038 if (!schedule_work(&brcmf_driver_work
))
1044 static void __exit
brcmfmac_module_exit(void)
1046 cancel_work_sync(&brcmf_driver_work
);
1048 #ifdef CONFIG_BRCMFMAC_SDIO
1051 #ifdef CONFIG_BRCMFMAC_USB
1054 brcmf_debugfs_exit();
1057 module_init(brcmfmac_module_init
);
1058 module_exit(brcmfmac_module_exit
);