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