dhd_linux.c 23.2 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * Copyright (c) 2010 Broadcom Corporation
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <linux/kernel.h>
#include <linux/etherdevice.h>
19
#include <linux/module.h>
20
21
22
23
24
25
26
27
28
#include <net/cfg80211.h>
#include <net/rtnetlink.h>
#include <brcmu_utils.h>
#include <brcmu_wifi.h>

#include "dhd.h"
#include "dhd_bus.h"
#include "dhd_proto.h"
#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");
Hante Meuleman's avatar
Hante Meuleman committed
35
MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
36
37
MODULE_LICENSE("Dual BSD/GPL");

38
#define MAX_WAIT_FOR_8021X_TX		50	/* msecs */
39
40

/* Error bits */
41
int brcmf_msg_level;
42
43
module_param_named(debug, brcmf_msg_level, int, S_IRUSR | S_IWUSR);
MODULE_PARM_DESC(debug, "level of debug output");
44

45
46
47
48
49
50
/* P2P0 enable */
static int brcmf_p2p_enable;
#ifdef CONFIG_BRCMDBG
module_param_named(p2pon, brcmf_p2p_enable, int, 0);
MODULE_PARM_DESC(p2pon, "enable p2p management functionality");
#endif
51
52
53
54

char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx)
{
	if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
55
		brcmf_err("ifidx %d out of range\n", ifidx);
56
57
58
		return "<if_bad>";
	}

59
	if (drvr->iflist[ifidx] == NULL) {
60
		brcmf_err("null i/f %d\n", ifidx);
61
62
63
		return "<if_null>";
	}

64
65
	if (drvr->iflist[ifidx]->ndev)
		return drvr->iflist[ifidx]->ndev->name;
66
67
68
69
70
71

	return "<if_none>";
}

static void _brcmf_set_multicast_list(struct work_struct *work)
{
72
	struct brcmf_if *ifp;
73
74
	struct net_device *ndev;
	struct netdev_hw_addr *ha;
75
	u32 cmd_value, cnt;
76
77
	__le32 cnt_le;
	char *buf, *bufp;
78
79
	u32 buflen;
	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
92
93
94
	cnt = netdev_mc_count(ndev);
	buflen = sizeof(cnt) + (cnt * ETH_ALEN);
	buf = kmalloc(buflen, GFP_ATOMIC);
	if (!buf)
95
		return;
96
	bufp = buf;
97
98

	cnt_le = cpu_to_le32(cnt);
99
	memcpy(bufp, &cnt_le, sizeof(cnt_le));
100
101
102
103
104
105
106
107
108
109
	bufp += sizeof(cnt_le);

	netdev_for_each_mc_addr(ha, ndev) {
		if (!cnt)
			break;
		memcpy(bufp, ha->addr, ETH_ALEN);
		bufp += ETH_ALEN;
		cnt--;
	}

110
111
	err = brcmf_fil_iovar_data_set(ifp, "mcast_list", buf, buflen);
	if (err < 0) {
112
		brcmf_err("Setting mcast_list failed, %d\n", err);
113
		cmd_value = cnt ? true : cmd_value;
114
115
116
117
	}

	kfree(buf);

118
119
	/*
	 * Now send the allmulti setting.  This is based on the setting in the
120
121
122
	 * net_device flags, but might be modified above to be turned on if we
	 * were trying to set some addresses and dongle rejected it...
	 */
123
124
	err = brcmf_fil_iovar_int_set(ifp, "allmulti", cmd_value);
	if (err < 0)
125
		brcmf_err("Setting allmulti failed, %d\n", err);
126
127
128
129
130

	/*Finally, pick up the PROMISC flag */
	cmd_value = (ndev->flags & IFF_PROMISC) ? true : false;
	err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PROMISC, cmd_value);
	if (err < 0)
131
		brcmf_err("Setting BRCMF_C_SET_PROMISC failed, %d\n",
132
			  err);
133
134
135
136
137
}

static void
_brcmf_set_mac_address(struct work_struct *work)
{
138
139
	struct brcmf_if *ifp;
	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
147
				       ETH_ALEN);
	if (err < 0) {
148
		brcmf_err("Setting cur_etheraddr failed, %d\n", err);
149
150
	} else {
		brcmf_dbg(TRACE, "MAC address updated to %pM\n",
151
152
			  ifp->mac_addr);
		memcpy(ifp->ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
153
	}
154
155
156
157
}

static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr)
{
158
	struct brcmf_if *ifp = netdev_priv(ndev);
159
160
	struct sockaddr *sa = (struct sockaddr *)addr;

161
162
	memcpy(&ifp->mac_addr, sa->sa_data, ETH_ALEN);
	schedule_work(&ifp->setmacaddr_work);
163
164
165
166
167
	return 0;
}

static void brcmf_netdev_set_multicast_list(struct net_device *ndev)
{
168
	struct brcmf_if *ifp = netdev_priv(ndev);
169

170
	schedule_work(&ifp->multicast_work);
171
172
}

173
174
static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
					   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
184
185
	/* Can the device send data? */
	if (drvr->bus_if->state != BRCMF_BUS_DATA) {
		brcmf_err("xmit rejected state=%d\n", drvr->bus_if->state);
186
		netif_stop_queue(ndev);
187
188
189
		dev_kfree_skb(skb);
		ret = -ENODEV;
		goto done;
190
191
	}

192
193
	if (!drvr->iflist[ifp->bssidx]) {
		brcmf_err("bad ifidx %d\n", ifp->bssidx);
194
		netif_stop_queue(ndev);
195
196
197
		dev_kfree_skb(skb);
		ret = -ENODEV;
		goto done;
198
199
200
	}

	/* Make sure there's enough room for any header */
201
	if (skb_headroom(skb) < drvr->hdrlen) {
202
203
204
		struct sk_buff *skb2;

		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
209
210
		dev_kfree_skb(skb);
		skb = skb2;
		if (skb == NULL) {
211
			brcmf_err("%s: skb_realloc_headroom failed\n",
212
				  brcmf_ifname(drvr, ifp->bssidx));
213
214
215
216
217
			ret = -ENOMEM;
			goto done;
		}
	}

218
219
220
221
222
	/* validate length for ether packet */
	if (skb->len < sizeof(*eh)) {
		ret = -EINVAL;
		dev_kfree_skb(skb);
		goto done;
223
224
	}

225
226
227
228
229
	/* handle ethernet header */
	eh = (struct ethhdr *)(skb->data);
	if (is_multicast_ether_addr(eh->h_dest))
		drvr->tx_multicast++;
	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
240
241
242
243
244
	if (ret) {
		ifp->stats.tx_dropped++;
	} else {
		ifp->stats.tx_packets++;
		ifp->stats.tx_bytes += skb->len;
	}
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
254
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_pub *drvr = bus_if->drvr;
255
	int i;
256
257
258

	brcmf_dbg(TRACE, "Enter\n");

259
260
261
262
263
264
265
266
	for (i = 0; i < BRCMF_MAX_IFS; i++)
		if (drvr->iflist[i]) {
			ndev = drvr->iflist[i]->ndev;
			if (state)
				netif_stop_queue(ndev);
			else
				netif_wake_queue(ndev);
		}
267
268
}

269
void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
270
271
272
{
	unsigned char *eth;
	uint len;
273
	struct sk_buff *skb, *pnext;
274
	struct brcmf_if *ifp;
275
276
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_pub *drvr = bus_if->drvr;
277
278
	u8 ifidx;
	int ret;
279
280
281

	brcmf_dbg(TRACE, "Enter\n");

282
283
	skb_queue_walk_safe(skb_list, skb, pnext) {
		skb_unlink(skb, skb_list);
284

285
		/* process and remove protocol-specific header */
286
		ret = brcmf_proto_hdrpull(drvr, &ifidx, skb);
287
288
289
290
291
		ifp = drvr->iflist[ifidx];

		if (ret || !ifp || !ifp->ndev) {
			if ((ret != -ENODATA) && ifp)
				ifp->stats.rx_errors++;
292
293
294
295
			brcmu_pkt_buf_free_skb(skb);
			continue;
		}

296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
		/* Get the protocol, maintain skb around eth_type_trans()
		 * The main reason for this hack is for the limitation of
		 * Linux 2.4 where 'eth_type_trans' uses the
		 * 'net->hard_header_len'
		 * to perform skb_pull inside vs ETH_HLEN. Since to avoid
		 * coping of the packet coming from the network stack to add
		 * BDC, Hardware header etc, during network interface
		 * registration
		 * we set the 'net->hard_header_len' to ETH_HLEN + extra space
		 * required
		 * for BDC, Hardware header etc. and not just the ETH_HLEN
		 */
		eth = skb->data;
		len = skb->len;

		skb->dev = ifp->ndev;
		skb->protocol = eth_type_trans(skb, skb->dev);

		if (skb->pkt_type == PACKET_MULTICAST)
315
			ifp->stats.multicast++;
316
317
318
319
320
321
322
323

		skb->data = eth;
		skb->len = len;

		/* Strip header, count, deliver upward */
		skb_pull(skb, ETH_HLEN);

		/* Process special event packets and then discard them */
324
		brcmf_fweh_process_skb(drvr, skb, &ifidx);
325

326
327
		if (drvr->iflist[ifidx]) {
			ifp = drvr->iflist[ifidx];
328
			ifp->ndev->last_rx = jiffies;
329
		}
330

331
332
333
334
335
336
337
		if (!(ifp->ndev->flags & IFF_UP)) {
			brcmu_pkt_buf_free_skb(skb);
			continue;
		}

		ifp->stats.rx_bytes += skb->len;
		ifp->stats.rx_packets++;
338
339
340
341
342
343
344
345
346
347
348
349
350
351

		if (in_interrupt())
			netif_rx(skb);
		else
			/* If the receive is not processed inside an ISR,
			 * the softirqd must be woken explicitly to service
			 * the NET_RX_SOFTIRQ.  In 2.6 kernels, this is handled
			 * by netif_rx_ni(), but in earlier kernels, we need
			 * to do it manually.
			 */
			netif_rx_ni(skb);
	}
}

352
void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
353
{
354
	u8 ifidx;
355
356
	struct ethhdr *eh;
	u16 type;
357
358
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_pub *drvr = bus_if->drvr;
359
	struct brcmf_if *ifp;
360

361
	brcmf_proto_hdrpull(drvr, &ifidx, txp);
362

363
364
365
366
	ifp = drvr->iflist[ifidx];
	if (!ifp)
		return;

367
368
369
	eh = (struct ethhdr *)(txp->data);
	type = ntohs(eh->h_proto);

370
	if (type == ETH_P_PAE) {
371
372
373
		atomic_dec(&ifp->pend_8021x_cnt);
		if (waitqueue_active(&ifp->pend_8021x_wait))
			wake_up(&ifp->pend_8021x_wait);
374
	}
375
376
	if (!success)
		ifp->stats.tx_errors++;
377
378
379
380
}

static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
{
381
	struct brcmf_if *ifp = netdev_priv(ndev);
382

383
	brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
384
385
386
387

	return &ifp->stats;
}

388
389
390
391
392
/*
 * Set current toe component enables in toe_ol iovar,
 * and set toe global enable iovar
 */
static int brcmf_toe_set(struct brcmf_if *ifp, u32 toe_ol)
393
{
394
	s32 err;
395

396
397
	err = brcmf_fil_iovar_int_set(ifp, "toe_ol", toe_ol);
	if (err < 0) {
398
		brcmf_err("Setting toe_ol failed, %d\n", err);
399
		return err;
400
401
	}

402
403
	err = brcmf_fil_iovar_int_set(ifp, "toe", (toe_ol != 0));
	if (err < 0)
404
		brcmf_err("Setting toe failed, %d\n", err);
405

406
	return err;
407
408
409
410
411
412

}

static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
				    struct ethtool_drvinfo *info)
{
413
	struct brcmf_if *ifp = netdev_priv(ndev);
414
	struct brcmf_pub *drvr = ifp->drvr;
415

416
417
418
419
420
	strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
	snprintf(info->version, sizeof(info->version), "%lu",
		 drvr->drv_version);
	strlcpy(info->bus_info, dev_name(drvr->bus_if->dev),
		sizeof(info->bus_info));
421
422
}

423
424
static const struct ethtool_ops brcmf_ethtool_ops = {
	.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
431
432
433
434
435
436
	struct ethtool_drvinfo info;
	char drvname[sizeof(info.driver)];
	u32 cmd;
	struct ethtool_value edata;
	u32 toe_cmpnt, csum_dir;
	int ret;

437
	brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459

	/* all ethtool calls start with a cmd word */
	if (copy_from_user(&cmd, uaddr, sizeof(u32)))
		return -EFAULT;

	switch (cmd) {
	case ETHTOOL_GDRVINFO:
		/* Copy out any request driver name */
		if (copy_from_user(&info, uaddr, sizeof(info)))
			return -EFAULT;
		strncpy(drvname, info.driver, sizeof(info.driver));
		drvname[sizeof(info.driver) - 1] = '\0';

		/* clear struct for return */
		memset(&info, 0, sizeof(info));
		info.cmd = cmd;

		/* if requested, identify ourselves */
		if (strcmp(drvname, "?dhd") == 0) {
			sprintf(info.driver, "dhd");
			strcpy(info.version, BRCMF_VERSION_STR);
		}
460
		/* report dongle driver type */
461
		else
462
			sprintf(info.driver, "wl");
463

464
		sprintf(info.version, "%lu", drvr->drv_version);
465
466
		if (copy_to_user(uaddr, &info, sizeof(info)))
			return -EFAULT;
467
		brcmf_dbg(TRACE, "given %*s, returning %s\n",
468
469
470
471
472
473
			  (int)sizeof(drvname), drvname, info.driver);
		break;

		/* Get toe offload components from dongle */
	case ETHTOOL_GRXCSUM:
	case ETHTOOL_GTXCSUM:
474
		ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt);
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
		if (ret < 0)
			return ret;

		csum_dir =
		    (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;

		edata.cmd = cmd;
		edata.data = (toe_cmpnt & csum_dir) ? 1 : 0;

		if (copy_to_user(uaddr, &edata, sizeof(edata)))
			return -EFAULT;
		break;

		/* Set toe offload components in dongle */
	case ETHTOOL_SRXCSUM:
	case ETHTOOL_STXCSUM:
		if (copy_from_user(&edata, uaddr, sizeof(edata)))
			return -EFAULT;

		/* Read the current settings, update and write back */
495
		ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt);
496
497
498
499
500
501
502
503
504
505
506
		if (ret < 0)
			return ret;

		csum_dir =
		    (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;

		if (edata.data != 0)
			toe_cmpnt |= csum_dir;
		else
			toe_cmpnt &= ~csum_dir;

507
		ret = brcmf_toe_set(ifp, toe_cmpnt);
508
509
510
511
512
513
		if (ret < 0)
			return ret;

		/* If setting TX checksum mode, tell Linux the new mode */
		if (cmd == ETHTOOL_STXCSUM) {
			if (edata.data)
514
				ifp->ndev->features |= NETIF_F_IP_CSUM;
515
			else
516
				ifp->ndev->features &= ~NETIF_F_IP_CSUM;
517
518
519
520
521
522
523
524
525
526
527
528
529
530
		}

		break;

	default:
		return -EOPNOTSUPP;
	}

	return 0;
}

static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr,
				    int cmd)
{
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
538
539
		return -1;

	if (cmd == SIOCETHTOOL)
540
		return brcmf_ethtool(ifp, ifr->ifr_data);
541
542
543
544
545
546

	return -EOPNOTSUPP;
}

static int brcmf_netdev_stop(struct net_device *ndev)
{
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
554
555
556
557
558
559
560
	/* Set state and stop OS transmissions */
	netif_stop_queue(ndev);

	return 0;
}

static int brcmf_netdev_open(struct net_device *ndev)
{
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
565
566
	u32 toe_ol;
	s32 ret = 0;

567
	brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
568

569
570
	/* If bus is not ready, can't continue */
	if (bus_if->state != BRCMF_BUS_DATA) {
571
		brcmf_err("failed bus is not ready\n");
572
573
		return -EAGAIN;
	}
574

575
	atomic_set(&ifp->pend_8021x_cnt, 0);
576

577
578
579
	/* Get current TOE mode from dongle */
	if (brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_ol) >= 0
	    && (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
585
	/* Allow transmit calls */
	netif_start_queue(ndev);
586
	if (brcmf_cfg80211_up(ndev)) {
587
		brcmf_err("failed to bring up cfg80211\n");
588
589
590
591
592
593
		return -1;
	}

	return ret;
}

594
595
596
597
598
599
600
601
602
603
static const struct net_device_ops brcmf_netdev_ops_pri = {
	.ndo_open = brcmf_netdev_open,
	.ndo_stop = brcmf_netdev_stop,
	.ndo_get_stats = brcmf_netdev_get_stats,
	.ndo_do_ioctl = brcmf_netdev_ioctl_entry,
	.ndo_start_xmit = brcmf_netdev_start_xmit,
	.ndo_set_mac_address = brcmf_netdev_set_mac_address,
	.ndo_set_rx_mode = brcmf_netdev_set_multicast_list
};

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
618
619
620
621
622

	ndev->hard_header_len = ETH_HLEN + drvr->hdrlen;
	ndev->ethtool_ops = &brcmf_ethtool_ops;

	drvr->rxsz = ndev->mtu + ndev->hard_header_len +
			      drvr->hdrlen;

623
624
	/* set the mac address */
	memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
625

626
627
628
	INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address);
	INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list);

629
630
631
632
633
	if (rtnl_locked)
		err = register_netdevice(ndev);
	else
		err = register_netdev(ndev);
	if (err != 0) {
634
		brcmf_err("couldn't register the net device\n");
635
636
637
638
639
640
641
642
643
644
645
646
		goto fail;
	}

	brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);

	return 0;

fail:
	ndev->netdev_ops = NULL;
	return -EBADE;
}

647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
static int brcmf_net_p2p_open(struct net_device *ndev)
{
	brcmf_dbg(TRACE, "Enter\n");

	return brcmf_cfg80211_up(ndev);
}

static int brcmf_net_p2p_stop(struct net_device *ndev)
{
	brcmf_dbg(TRACE, "Enter\n");

	return brcmf_cfg80211_down(ndev);
}

static int brcmf_net_p2p_do_ioctl(struct net_device *ndev,
				  struct ifreq *ifr, int cmd)
{
	brcmf_dbg(TRACE, "Enter\n");
	return 0;
}

static netdev_tx_t brcmf_net_p2p_start_xmit(struct sk_buff *skb,
					    struct net_device *ndev)
{
	if (skb)
		dev_kfree_skb_any(skb);

	return NETDEV_TX_OK;
}

static const struct net_device_ops brcmf_netdev_ops_p2p = {
	.ndo_open = brcmf_net_p2p_open,
	.ndo_stop = brcmf_net_p2p_stop,
	.ndo_do_ioctl = brcmf_net_p2p_do_ioctl,
	.ndo_start_xmit = brcmf_net_p2p_start_xmit
};

static int brcmf_net_p2p_attach(struct brcmf_if *ifp)
{
	struct net_device *ndev;

	brcmf_dbg(TRACE, "Enter, idx=%d mac=%pM\n", ifp->bssidx,
		  ifp->mac_addr);
	ndev = ifp->ndev;

	ndev->netdev_ops = &brcmf_netdev_ops_p2p;

	/* set the mac address */
	memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN);

	if (register_netdev(ndev) != 0) {
		brcmf_err("couldn't register the p2p net device\n");
		goto fail;
	}

	brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);

	return 0;

fail:
	return -EBADE;
}

710
711
struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
			      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
721
722
723
	/*
	 * Delete the existing interface before overwriting it
	 * in case we missed the BRCMF_E_IF_DEL event.
	 */
	if (ifp) {
724
		brcmf_err("ERROR: netdev:%s already exists\n",
725
			  ifp->ndev->name);
726
727
728
729
		if (ifidx) {
			netif_stop_queue(ifp->ndev);
			unregister_netdev(ifp->ndev);
			free_netdev(ifp->ndev);
730
			drvr->iflist[bssidx] = NULL;
731
		} else {
732
			brcmf_err("ignore IF event\n");
733
734
			return ERR_PTR(-EINVAL);
		}
735
	}
736

737
	/* Allocate netdev, including space for private structure */
738
739
	ndev = alloc_netdev(sizeof(struct brcmf_if), name, ether_setup);
	if (!ndev) {
740
		brcmf_err("OOM - alloc_netdev\n");
741
		return ERR_PTR(-ENOMEM);
742
	}
743

744
745
	ifp = netdev_priv(ndev);
	ifp->ndev = ndev;
746
	ifp->drvr = drvr;
747
748
	drvr->iflist[bssidx] = ifp;
	ifp->ifidx = ifidx;
749
	ifp->bssidx = bssidx;
750
751


752
753
	init_waitqueue_head(&ifp->pend_8021x_wait);

754
755
	if (mac_addr != NULL)
		memcpy(ifp->mac_addr, mac_addr, ETH_ALEN);
756

757
758
	brcmf_dbg(TRACE, " ==== pid:%x, if:%s (%pM) created ===\n",
		  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
766
{
	struct brcmf_if *ifp;

767
	ifp = drvr->iflist[bssidx];
768
	if (!ifp) {
769
		brcmf_err("Null interface, idx=%d\n", bssidx);
770
771
		return;
	}
772
	brcmf_dbg(TRACE, "Enter, idx=%d, ifidx=%d\n", bssidx, ifp->ifidx);
773
	if (ifp->ndev) {
774
		if (bssidx == 0) {
775
776
777
778
779
780
781
782
783
			if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
				rtnl_lock();
				brcmf_netdev_stop(ifp->ndev);
				rtnl_unlock();
			}
		} else {
			netif_stop_queue(ifp->ndev);
		}

784
785
786
787
		if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
			cancel_work_sync(&ifp->setmacaddr_work);
			cancel_work_sync(&ifp->multicast_work);
		}
788

789
		unregister_netdev(ifp->ndev);
790
791
		drvr->iflist[bssidx] = NULL;
		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
803
804

	brcmf_dbg(TRACE, "Enter\n");

	/* Allocate primary brcmf_info */
805
806
	drvr = kzalloc(sizeof(struct brcmf_pub), GFP_ATOMIC);
	if (!drvr)
807
		return -ENOMEM;
808

809
	mutex_init(&drvr->proto_block);
810
811

	/* Link to bus module */
812
813
	drvr->hdrlen = bus_hdrlen;
	drvr->bus_if = dev_get_drvdata(dev);
814
	drvr->bus_if->drvr = drvr;
815

816
817
818
	/* create device debugfs folder */
	brcmf_debugfs_attach(drvr);

819
	/* Attach and link in the protocol */
820
821
	ret = brcmf_proto_attach(drvr);
	if (ret != 0) {
822
		brcmf_err("brcmf_prot_attach failed\n");
823
824
825
		goto fail;
	}

826
827
828
	/* attach firmware event handler */
	brcmf_fweh_attach(drvr);

829
830
	INIT_LIST_HEAD(&drvr->bus_if->dcmd_list);

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
843
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_pub *drvr = bus_if->drvr;
844
	struct brcmf_if *ifp;
845
	struct brcmf_if *p2p_ifp;
846
847
848
849

	brcmf_dbg(TRACE, "\n");

	/* 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
854
855
		return ret;
	}

856
	/* add primary networking interface */
857
	ifp = brcmf_add_if(drvr, 0, 0, "wlan%d", NULL);
858
859
860
	if (IS_ERR(ifp))
		return PTR_ERR(ifp);

861
862
863
864
865
866
867
	if (brcmf_p2p_enable)
		p2p_ifp = brcmf_add_if(drvr, 1, 0, "p2p%d", NULL);
	else
		p2p_ifp = NULL;
	if (IS_ERR(p2p_ifp))
		p2p_ifp = NULL;

868
869
870
871
872
	/* signal bus ready */
	bus_if->state = BRCMF_BUS_DATA;

	/* Bus is ready, do any initialization */
	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
878
879
880
	if (drvr->config == NULL) {
		ret = -ENOMEM;
		goto fail;
	}
881

882
883
884
885
	ret = brcmf_fweh_activate_events(ifp);
	if (ret < 0)
		goto fail;

886
	ret = brcmf_net_attach(ifp, false);
887
fail:
888
	if (ret < 0) {
889
		brcmf_err("failed: %d\n", ret);
890
891
		if (drvr->config)
			brcmf_cfg80211_detach(drvr->config);
892
		free_netdev(ifp->ndev);
893
		drvr->iflist[0] = NULL;
894
895
896
897
		if (p2p_ifp) {
			free_netdev(p2p_ifp->ndev);
			drvr->iflist[1] = NULL;
		}
898
		return ret;
899
	}
900
901
	if ((brcmf_p2p_enable) && (p2p_ifp))
		brcmf_net_p2p_attach(p2p_ifp);
902

903
904
905
906
907
908
909
910
	return 0;
}

static void brcmf_bus_detach(struct brcmf_pub *drvr)
{
	brcmf_dbg(TRACE, "Enter\n");

	if (drvr) {
911
912
		/* Stop the protocol module */
		brcmf_proto_stop(drvr);
913

914
		/* Stop the bus module */
915
		brcmf_bus_stop(drvr->bus_if);
916
917
918
	}
}

919
920
921
922
923
924
925
926
void brcmf_dev_reset(struct device *dev)
{
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_pub *drvr = bus_if->drvr;

	if (drvr == NULL)
		return;

927
928
	if (drvr->iflist[0])
		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
935
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_pub *drvr = bus_if->drvr;
936
937
938

	brcmf_dbg(TRACE, "Enter\n");

939
940
	if (drvr == NULL)
		return;
941

942
943
944
	/* stop firmware event handling */
	brcmf_fweh_detach(drvr);

945
946
947
948
	/* make sure primary interface removed last */
	for (i = BRCMF_MAX_IFS-1; i > -1; i--)
		if (drvr->iflist[i])
			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
957
	bus_if->drvr = NULL;
	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
966
}

int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
{
967
	struct brcmf_if *ifp = netdev_priv(ndev);
968
969
	int err;

970
971
	err = wait_event_timeout(ifp->pend_8021x_wait,
				 !brcmf_get_pend_8021x_cnt(ifp),
972
973
974
975
976
				 msecs_to_jiffies(MAX_WAIT_FOR_8021X_TX));

	WARN_ON(!err);

	return !err;
977
978
}

979
980
981
982
983
984
985
986
987
988
/*
 * return chip id and rev of the device encoded in u32.
 */
u32 brcmf_get_chip_info(struct brcmf_if *ifp)
{
	struct brcmf_bus *bus = ifp->drvr->bus_if;

	return bus->chip << 4 | bus->chiprev;
}

989
static void brcmf_driver_init(struct work_struct *work)
990
{
991
992
	brcmf_debugfs_init();

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);
For faster browsing, not all history is shown. View entire blame