dhd_linux.c 23.8 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
#include "fwsignal.h"
34
35

MODULE_AUTHOR("Broadcom Corporation");
Hante Meuleman's avatar
Hante Meuleman committed
36
MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
37
38
MODULE_LICENSE("Dual BSD/GPL");

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

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

46
47
48
49
50
51
/* 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
52
53
54
55

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

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

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

	return "<if_none>";
}

static void _brcmf_set_multicast_list(struct work_struct *work)
{
73
	struct brcmf_if *ifp;
74
75
	struct net_device *ndev;
	struct netdev_hw_addr *ha;
76
	u32 cmd_value, cnt;
77
78
	__le32 cnt_le;
	char *buf, *bufp;
79
80
	u32 buflen;
	s32 err;
81

82
	ifp = container_of(work, struct brcmf_if, multicast_work);
83

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

86
	ndev = ifp->ndev;
87
88

	/* Determine initial value of allmulti flag */
89
	cmd_value = (ndev->flags & IFF_ALLMULTI) ? true : false;
90
91

	/* Send down the multicast list first. */
92
93
94
95
	cnt = netdev_mc_count(ndev);
	buflen = sizeof(cnt) + (cnt * ETH_ALEN);
	buf = kmalloc(buflen, GFP_ATOMIC);
	if (!buf)
96
		return;
97
	bufp = buf;
98
99

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

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

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

	kfree(buf);

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

	/*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)
132
		brcmf_err("Setting BRCMF_C_SET_PROMISC failed, %d\n",
133
			  err);
134
135
136
137
138
}

static void
_brcmf_set_mac_address(struct work_struct *work)
{
139
140
	struct brcmf_if *ifp;
	s32 err;
141

142
	ifp = container_of(work, struct brcmf_if, setmacaddr_work);
143

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

146
	err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", ifp->mac_addr,
147
148
				       ETH_ALEN);
	if (err < 0) {
149
		brcmf_err("Setting cur_etheraddr failed, %d\n", err);
150
151
	} else {
		brcmf_dbg(TRACE, "MAC address updated to %pM\n",
152
153
			  ifp->mac_addr);
		memcpy(ifp->ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
154
	}
155
156
157
158
}

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

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

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

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

174
175
static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
					   struct net_device *ndev)
176
177
{
	int ret;
178
	struct brcmf_if *ifp = netdev_priv(ndev);
179
	struct brcmf_pub *drvr = ifp->drvr;
180
	struct ethhdr *eh;
181

182
	brcmf_dbg(DATA, "Enter, idx=%d\n", ifp->bssidx);
183

184
185
186
	/* Can the device send data? */
	if (drvr->bus_if->state != BRCMF_BUS_DATA) {
		brcmf_err("xmit rejected state=%d\n", drvr->bus_if->state);
187
		netif_stop_queue(ndev);
188
189
190
		dev_kfree_skb(skb);
		ret = -ENODEV;
		goto done;
191
192
	}

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

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

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

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

226
	ret = brcmf_fws_process_skb(ifp, skb);
227
228

done:
229
230
231
232
233
234
	if (ret) {
		ifp->stats.tx_dropped++;
	} else {
		ifp->stats.tx_packets++;
		ifp->stats.tx_bytes += skb->len;
	}
235
236

	/* Return ok: we always eat the packet */
237
	return NETDEV_TX_OK;
238
239
}

240
241
242
void brcmf_txflowblock_if(struct brcmf_if *ifp,
			  enum brcmf_netif_stop_reason reason, bool state)
{
243
244
	unsigned long flags;

245
	if (!ifp || !ifp->ndev)
246
247
248
249
		return;

	brcmf_dbg(TRACE, "enter: idx=%d stop=0x%X reason=%d state=%d\n",
		  ifp->bssidx, ifp->netif_stop, reason, state);
250
251

	spin_lock_irqsave(&ifp->netif_stop_lock, flags);
252
253
254
255
256
257
258
259
260
	if (state) {
		if (!ifp->netif_stop)
			netif_stop_queue(ifp->ndev);
		ifp->netif_stop |= reason;
	} else {
		ifp->netif_stop &= ~reason;
		if (!ifp->netif_stop)
			netif_wake_queue(ifp->ndev);
	}
261
	spin_unlock_irqrestore(&ifp->netif_stop_lock, flags);
262
263
}

264
void brcmf_txflowblock(struct device *dev, bool state)
265
{
266
267
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_pub *drvr = bus_if->drvr;
268
	int i;
269
270
271

	brcmf_dbg(TRACE, "Enter\n");

272
273
274
275
276
277
278
279
	if (brcmf_fws_fc_active(drvr->fws)) {
		brcmf_fws_bus_blocked(drvr, state);
	} else {
		for (i = 0; i < BRCMF_MAX_IFS; i++)
			brcmf_txflowblock_if(drvr->iflist[i],
					     BRCMF_NETIF_STOP_REASON_BLOCK_BUS,
					     state);
	}
280
281
}

282
void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
283
{
284
	struct sk_buff *skb, *pnext;
285
	struct brcmf_if *ifp;
286
287
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_pub *drvr = bus_if->drvr;
288
289
	u8 ifidx;
	int ret;
290

291
	brcmf_dbg(DATA, "Enter\n");
292

293
294
	skb_queue_walk_safe(skb_list, skb, pnext) {
		skb_unlink(skb, skb_list);
295

296
		/* process and remove protocol-specific header */
297
		ret = brcmf_proto_hdrpull(drvr, drvr->fw_signals, &ifidx, skb);
298
299
300
301
302
		ifp = drvr->iflist[ifidx];

		if (ret || !ifp || !ifp->ndev) {
			if ((ret != -ENODATA) && ifp)
				ifp->stats.rx_errors++;
303
304
305
306
			brcmu_pkt_buf_free_skb(skb);
			continue;
		}

307
308
309
310
		skb->dev = ifp->ndev;
		skb->protocol = eth_type_trans(skb, skb->dev);

		if (skb->pkt_type == PACKET_MULTICAST)
311
			ifp->stats.multicast++;
312

313
314
		/* Process special event packets */
		brcmf_fweh_process_skb(drvr, skb);
315

316
317
318
319
320
321
322
		if (!(ifp->ndev->flags & IFF_UP)) {
			brcmu_pkt_buf_free_skb(skb);
			continue;
		}

		ifp->stats.rx_bytes += skb->len;
		ifp->stats.rx_packets++;
323
324
325
326
327

		if (in_interrupt())
			netif_rx(skb);
		else
			/* If the receive is not processed inside an ISR,
328
329
			 * the softirqd must be woken explicitly to service the
			 * NET_RX_SOFTIRQ. This is handled by netif_rx_ni().
330
331
332
333
334
			 */
			netif_rx_ni(skb);
	}
}

335
336
void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp,
		      bool success)
337
{
338
	struct brcmf_if *ifp;
339
	struct ethhdr *eh;
340
	u8 ifidx;
341
	u16 type;
342
	int res;
343

344
	res = brcmf_proto_hdrpull(drvr, false, &ifidx, txp);
345

346
347
	ifp = drvr->iflist[ifidx];
	if (!ifp)
348
		goto done;
349

350
351
352
	if (res == 0) {
		eh = (struct ethhdr *)(txp->data);
		type = ntohs(eh->h_proto);
353

354
355
356
357
358
		if (type == ETH_P_PAE) {
			atomic_dec(&ifp->pend_8021x_cnt);
			if (waitqueue_active(&ifp->pend_8021x_wait))
				wake_up(&ifp->pend_8021x_wait);
		}
359
	}
360
361
	if (!success)
		ifp->stats.tx_errors++;
362
363
done:
	brcmu_pkt_buf_free_skb(txp);
364
}
365

366
367
368
369
370
void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
{
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_pub *drvr = bus_if->drvr;

371
372
373
374
375
376
377
	/* await txstatus signal for firmware if active */
	if (brcmf_fws_fc_active(drvr->fws)) {
		if (!success)
			brcmf_fws_bustxfail(drvr->fws, txp);
	} else {
		brcmf_txfinalize(drvr, txp, success);
	}
378
379
380
381
}

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

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

	return &ifp->stats;
}

389
390
391
392
393
/*
 * 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)
394
{
395
	s32 err;
396

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

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

407
	return err;
408
409
410
411
412
413

}

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

417
418
419
420
421
	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));
422
423
}

424
425
static const struct ethtool_ops brcmf_ethtool_ops = {
	.get_drvinfo = brcmf_ethtool_get_drvinfo,
426
427
};

428
static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr)
429
{
430
	struct brcmf_pub *drvr = ifp->drvr;
431
432
433
434
435
436
437
	struct ethtool_drvinfo info;
	char drvname[sizeof(info.driver)];
	u32 cmd;
	struct ethtool_value edata;
	u32 toe_cmpnt, csum_dir;
	int ret;

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

	/* 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);
		}
461
		/* report dongle driver type */
462
		else
463
			sprintf(info.driver, "wl");
464

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

		/* Get toe offload components from dongle */
	case ETHTOOL_GRXCSUM:
	case ETHTOOL_GTXCSUM:
475
		ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt);
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
		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 */
496
		ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt);
497
498
499
500
501
502
503
504
505
506
507
		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;

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

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

		break;

	default:
		return -EOPNOTSUPP;
	}

	return 0;
}

static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr,
				    int cmd)
{
532
	struct brcmf_if *ifp = netdev_priv(ndev);
533
	struct brcmf_pub *drvr = ifp->drvr;
534

535
	brcmf_dbg(TRACE, "Enter, idx=%d, cmd=0x%04x\n", ifp->bssidx, cmd);
536

537
	if (!drvr->iflist[ifp->bssidx])
538
539
540
		return -1;

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

	return -EOPNOTSUPP;
}

static int brcmf_netdev_stop(struct net_device *ndev)
{
548
	struct brcmf_if *ifp = netdev_priv(ndev);
549

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

552
	brcmf_cfg80211_down(ndev);
553

554
555
556
557
558
559
560
561
	/* Set state and stop OS transmissions */
	netif_stop_queue(ndev);

	return 0;
}

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;
565
566
567
	u32 toe_ol;
	s32 ret = 0;

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

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

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

578
579
580
	/* 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)
581
		ndev->features |= NETIF_F_IP_CSUM;
582
	else
583
		ndev->features &= ~NETIF_F_IP_CSUM;
584

585
586
	/* Allow transmit calls */
	netif_start_queue(ndev);
587
	if (brcmf_cfg80211_up(ndev)) {
588
		brcmf_err("failed to bring up cfg80211\n");
589
590
591
592
593
594
		return -1;
	}

	return ret;
}

595
596
597
598
599
600
601
602
603
604
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
};

605
int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked)
606
{
607
	struct brcmf_pub *drvr = ifp->drvr;
608
	struct net_device *ndev;
609
	s32 err;
610

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

615
	/* set appropriate operations */
616
	ndev->netdev_ops = &brcmf_netdev_ops_pri;
617

618
	ndev->hard_header_len += drvr->hdrlen;
619
620
621
622
623
	ndev->ethtool_ops = &brcmf_ethtool_ops;

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

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

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

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

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

641
	ndev->destructor = free_netdev;
642
643
644
	return 0;

fail:
645
	drvr->iflist[ifp->bssidx] = NULL;
646
	ndev->netdev_ops = NULL;
647
	free_netdev(ndev);
648
649
650
	return -EBADE;
}

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
710
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:
711
712
713
	ifp->drvr->iflist[ifp->bssidx] = NULL;
	ndev->netdev_ops = NULL;
	free_netdev(ndev);
714
715
716
	return -EBADE;
}

717
718
struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
			      char *name, u8 *mac_addr)
719
720
{
	struct brcmf_if *ifp;
721
	struct net_device *ndev;
722

723
	brcmf_dbg(TRACE, "Enter, idx=%d, ifidx=%d\n", bssidx, ifidx);
724

725
	ifp = drvr->iflist[bssidx];
726
727
728
729
730
	/*
	 * Delete the existing interface before overwriting it
	 * in case we missed the BRCMF_E_IF_DEL event.
	 */
	if (ifp) {
731
		brcmf_err("ERROR: netdev:%s already exists\n",
732
			  ifp->ndev->name);
733
734
735
736
		if (ifidx) {
			netif_stop_queue(ifp->ndev);
			unregister_netdev(ifp->ndev);
			free_netdev(ifp->ndev);
737
			drvr->iflist[bssidx] = NULL;
738
		} else {
739
			brcmf_err("ignore IF event\n");
740
741
			return ERR_PTR(-EINVAL);
		}
742
	}
743

744
745
746
747
	if (!brcmf_p2p_enable && bssidx == 1) {
		/* this is P2P_DEVICE interface */
		brcmf_dbg(INFO, "allocate non-netdev interface\n");
		ifp = kzalloc(sizeof(*ifp), GFP_KERNEL);
748
749
		if (!ifp)
			return ERR_PTR(-ENOMEM);
750
751
752
753
	} else {
		brcmf_dbg(INFO, "allocate netdev interface\n");
		/* Allocate netdev, including space for private structure */
		ndev = alloc_netdev(sizeof(*ifp), name, ether_setup);
754
		if (!ndev)
755
756
757
758
			return ERR_PTR(-ENOMEM);

		ifp = netdev_priv(ndev);
		ifp->ndev = ndev;
759
	}
760

761
	ifp->drvr = drvr;
762
763
	drvr->iflist[bssidx] = ifp;
	ifp->ifidx = ifidx;
764
	ifp->bssidx = bssidx;
765

766
	init_waitqueue_head(&ifp->pend_8021x_wait);
767
	spin_lock_init(&ifp->netif_stop_lock);
768

769
770
	if (mac_addr != NULL)
		memcpy(ifp->mac_addr, mac_addr, ETH_ALEN);
771

772
	brcmf_dbg(TRACE, " ==== pid:%x, if:%s (%pM) created ===\n",
773
		  current->pid, name, ifp->mac_addr);
774

775
	return ifp;
776
777
}

778
void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
779
780
781
{
	struct brcmf_if *ifp;

782
	ifp = drvr->iflist[bssidx];
783
	drvr->iflist[bssidx] = NULL;
784
	if (!ifp) {
785
		brcmf_err("Null interface, idx=%d\n", bssidx);
786
787
		return;
	}
788
	brcmf_dbg(TRACE, "Enter, idx=%d, ifidx=%d\n", bssidx, ifp->ifidx);
789
	if (ifp->ndev) {
790
		if (bssidx == 0) {
791
792
793
794
795
796
797
798
799
			if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
				rtnl_lock();
				brcmf_netdev_stop(ifp->ndev);
				rtnl_unlock();
			}
		} else {
			netif_stop_queue(ifp->ndev);
		}

800
801
802
803
		if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
			cancel_work_sync(&ifp->setmacaddr_work);
			cancel_work_sync(&ifp->multicast_work);
		}
804
		/* unregister will take care of freeing it */
805
		unregister_netdev(ifp->ndev);
806
		if (bssidx == 0)
807
			brcmf_cfg80211_detach(drvr->config);
808
809
	} else {
		kfree(ifp);
810
811
812
	}
}

813
int brcmf_attach(uint bus_hdrlen, struct device *dev)
814
{
815
	struct brcmf_pub *drvr = NULL;
816
	int ret = 0;
817
818
819
820

	brcmf_dbg(TRACE, "Enter\n");

	/* Allocate primary brcmf_info */
821
822
	drvr = kzalloc(sizeof(struct brcmf_pub), GFP_ATOMIC);
	if (!drvr)
823
		return -ENOMEM;
824

825
	mutex_init(&drvr->proto_block);
826
827

	/* Link to bus module */
828
829
	drvr->hdrlen = bus_hdrlen;
	drvr->bus_if = dev_get_drvdata(dev);
830
	drvr->bus_if->drvr = drvr;
831

832
833
834
	/* create device debugfs folder */
	brcmf_debugfs_attach(drvr);

835
	/* Attach and link in the protocol */
836
837
	ret = brcmf_proto_attach(drvr);
	if (ret != 0) {
838
		brcmf_err("brcmf_prot_attach failed\n");
839
840
841
		goto fail;
	}

842
843
844
	/* attach firmware event handler */
	brcmf_fweh_attach(drvr);

845
846
	INIT_LIST_HEAD(&drvr->bus_if->dcmd_list);

847
	return ret;
848
849

fail:
850
	brcmf_detach(dev);
851

852
	return ret;
853
854
}

855
int brcmf_bus_start(struct device *dev)
856
857
{
	int ret = -1;
858
859
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_pub *drvr = bus_if->drvr;
860
	struct brcmf_if *ifp;
861
	struct brcmf_if *p2p_ifp;
862
863
864
865

	brcmf_dbg(TRACE, "\n");

	/* Bring up the bus */
866
	ret = brcmf_bus_init(bus_if);
867
	if (ret != 0) {
868
		brcmf_err("brcmf_sdbrcm_bus_init failed %d\n", ret);
869
870
871
		return ret;
	}

872
	/* add primary networking interface */
873
	ifp = brcmf_add_if(drvr, 0, 0, "wlan%d", NULL);
874
875
876
	if (IS_ERR(ifp))
		return PTR_ERR(ifp);

877
878
879
880
881
882
883
	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;

884
885
886
887
888
	/* signal bus ready */
	bus_if->state = BRCMF_BUS_DATA;

	/* Bus is ready, do any initialization */
	ret = brcmf_c_preinit_dcmds(ifp);
889
	if (ret < 0)
890
		goto fail;
891

892
	drvr->fw_signals = true;
893
894
895
896
	ret = brcmf_fws_init(drvr);
	if (ret < 0)
		goto fail;

897
	brcmf_fws_add_interface(ifp);
898

899
	drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev);
900
901
902
903
	if (drvr->config == NULL) {
		ret = -ENOMEM;
		goto fail;
	}
904

905
906
907
908
	ret = brcmf_fweh_activate_events(ifp);
	if (ret < 0)
		goto fail;

909
	ret = brcmf_net_attach(ifp, false);
910
fail:
911
	if (ret < 0) {
912
		brcmf_err("failed: %d\n", ret);
913
914
		if (drvr->config)
			brcmf_cfg80211_detach(drvr->config);
915
916
		if (drvr->fws) {
			brcmf_fws_del_interface(ifp);
917
			brcmf_fws_deinit(drvr);
918
		}
919
920
921
922
		if (drvr->iflist[0]) {
			free_netdev(ifp->ndev);
			drvr->iflist[0] = NULL;
		}
923
924
925
926
		if (p2p_ifp) {
			free_netdev(p2p_ifp->ndev);
			drvr->iflist[1] = NULL;
		}
927
		return ret;
928
	}
929
	if ((brcmf_p2p_enable) && (p2p_ifp))
930
931
		if (brcmf_net_p2p_attach(p2p_ifp) < 0)
			brcmf_p2p_enable = 0;
932

933
934
935
936
937
938
939
940
	return 0;
}

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

	if (drvr) {
941
942
		/* Stop the protocol module */
		brcmf_proto_stop(drvr);
943

944
		/* Stop the bus module */
945
		brcmf_bus_stop(drvr->bus_if);
946
947
948
	}
}

949
950
951
952
953
954
955
956
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;

957
958
	if (drvr->iflist[0])
		brcmf_fil_cmd_int_set(drvr->iflist[0], BRCMF_C_TERMINATED, 1);
959
960
}

961
void brcmf_detach(struct device *dev)
962
{
963
	s32 i;
964
965
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_pub *drvr = bus_if->drvr;
966
967
968

	brcmf_dbg(TRACE, "Enter\n");

969
970
	if (drvr == NULL)
		return;
971

972
973
974
	/* stop firmware event handling */
	brcmf_fweh_detach(drvr);

975
976
	/* make sure primary interface removed last */
	for (i = BRCMF_MAX_IFS-1; i > -1; i--)
977
978
		if (drvr->iflist[i]) {
			brcmf_fws_del_interface(drvr->iflist[i]);
979
			brcmf_del_if(drvr, i);
980
		}
981

982
	brcmf_bus_detach(drvr);
983

984
	if (drvr->prot)
985
		brcmf_proto_detach(drvr);
986

987
	brcmf_fws_deinit(drvr);
988

989
	brcmf_debugfs_detach(drvr);
990
991
	bus_if->drvr = NULL;
	kfree(drvr);
992
993
}

994
static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp)
995
{
996
	return atomic_read(&ifp->pend_8021x_cnt);
997
998
999
1000
}

int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
{