dhd_linux.c 23.5 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(TRACE, "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
227
228
229
230
	/* 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)
231
		atomic_inc(&ifp->pend_8021x_cnt);
232

233
	/* If the protocol uses a data header, apply it */
234
	brcmf_proto_hdrpush(drvr, ifp->ifidx, skb);
235
236

	/* Use bus module to send data frame */
237
	ret =  brcmf_bus_txdata(drvr->bus_if, skb);
238
239

done:
240
241
242
243
244
245
	if (ret) {
		ifp->stats.tx_dropped++;
	} else {
		ifp->stats.tx_packets++;
		ifp->stats.tx_bytes += skb->len;
	}
246
247

	/* Return ok: we always eat the packet */
248
	return NETDEV_TX_OK;
249
250
}

251
void brcmf_txflowblock(struct device *dev, bool state)
252
253
{
	struct net_device *ndev;
254
255
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_pub *drvr = bus_if->drvr;
256
	int i;
257
258
259

	brcmf_dbg(TRACE, "Enter\n");

260
261
262
263
264
265
266
267
	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);
		}
268
269
}

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

	brcmf_dbg(TRACE, "Enter\n");

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

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

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

297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
		/* 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)
316
			ifp->stats.multicast++;
317
318
319
320
321
322
323
324

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

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

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

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

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

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

		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);
	}
}

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

363
	res = brcmf_proto_hdrpull(drvr, false, &ifidx, txp);
364

365
366
	ifp = drvr->iflist[ifidx];
	if (!ifp)
367
		goto done;
368

369
370
371
	if (res == 0) {
		eh = (struct ethhdr *)(txp->data);
		type = ntohs(eh->h_proto);
372

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

done:
	brcmu_pkt_buf_free_skb(txp);
384
385
386
387
}

static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
{
388
	struct brcmf_if *ifp = netdev_priv(ndev);
389

390
	brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
391
392
393
394

	return &ifp->stats;
}

395
396
397
398
399
/*
 * 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)
400
{
401
	s32 err;
402

403
404
	err = brcmf_fil_iovar_int_set(ifp, "toe_ol", toe_ol);
	if (err < 0) {
405
		brcmf_err("Setting toe_ol failed, %d\n", err);
406
		return err;
407
408
	}

409
410
	err = brcmf_fil_iovar_int_set(ifp, "toe", (toe_ol != 0));
	if (err < 0)
411
		brcmf_err("Setting toe failed, %d\n", err);
412

413
	return err;
414
415
416
417
418
419

}

static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
				    struct ethtool_drvinfo *info)
{
420
	struct brcmf_if *ifp = netdev_priv(ndev);
421
	struct brcmf_pub *drvr = ifp->drvr;
422

423
424
425
426
427
	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));
428
429
}

430
431
static const struct ethtool_ops brcmf_ethtool_ops = {
	.get_drvinfo = brcmf_ethtool_get_drvinfo,
432
433
};

434
static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr)
435
{
436
	struct brcmf_pub *drvr = ifp->drvr;
437
438
439
440
441
442
443
	struct ethtool_drvinfo info;
	char drvname[sizeof(info.driver)];
	u32 cmd;
	struct ethtool_value edata;
	u32 toe_cmpnt, csum_dir;
	int ret;

444
	brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466

	/* 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);
		}
467
		/* report dongle driver type */
468
		else
469
			sprintf(info.driver, "wl");
470

471
		sprintf(info.version, "%lu", drvr->drv_version);
472
473
		if (copy_to_user(uaddr, &info, sizeof(info)))
			return -EFAULT;
474
		brcmf_dbg(TRACE, "given %*s, returning %s\n",
475
476
477
478
479
480
			  (int)sizeof(drvname), drvname, info.driver);
		break;

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

514
		ret = brcmf_toe_set(ifp, toe_cmpnt);
515
516
517
518
519
520
		if (ret < 0)
			return ret;

		/* If setting TX checksum mode, tell Linux the new mode */
		if (cmd == ETHTOOL_STXCSUM) {
			if (edata.data)
521
				ifp->ndev->features |= NETIF_F_IP_CSUM;
522
			else
523
				ifp->ndev->features &= ~NETIF_F_IP_CSUM;
524
525
526
527
528
529
530
531
532
533
534
535
536
537
		}

		break;

	default:
		return -EOPNOTSUPP;
	}

	return 0;
}

static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr,
				    int cmd)
{
538
	struct brcmf_if *ifp = netdev_priv(ndev);
539
	struct brcmf_pub *drvr = ifp->drvr;
540

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

543
	if (!drvr->iflist[ifp->bssidx])
544
545
546
		return -1;

	if (cmd == SIOCETHTOOL)
547
		return brcmf_ethtool(ifp, ifr->ifr_data);
548
549
550
551
552
553

	return -EOPNOTSUPP;
}

static int brcmf_netdev_stop(struct net_device *ndev)
{
554
	struct brcmf_if *ifp = netdev_priv(ndev);
555

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

558
	brcmf_cfg80211_down(ndev);
559

560
561
562
563
564
565
566
567
	/* Set state and stop OS transmissions */
	netif_stop_queue(ndev);

	return 0;
}

static int brcmf_netdev_open(struct net_device *ndev)
{
568
	struct brcmf_if *ifp = netdev_priv(ndev);
569
	struct brcmf_pub *drvr = ifp->drvr;
570
	struct brcmf_bus *bus_if = drvr->bus_if;
571
572
573
	u32 toe_ol;
	s32 ret = 0;

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

576
577
	/* If bus is not ready, can't continue */
	if (bus_if->state != BRCMF_BUS_DATA) {
578
		brcmf_err("failed bus is not ready\n");
579
580
		return -EAGAIN;
	}
581

582
	atomic_set(&ifp->pend_8021x_cnt, 0);
583

584
585
586
	/* 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)
587
		ndev->features |= NETIF_F_IP_CSUM;
588
	else
589
		ndev->features &= ~NETIF_F_IP_CSUM;
590

591
592
	/* Allow transmit calls */
	netif_start_queue(ndev);
593
	if (brcmf_cfg80211_up(ndev)) {
594
		brcmf_err("failed to bring up cfg80211\n");
595
596
597
598
599
600
		return -1;
	}

	return ret;
}

601
602
603
604
605
606
607
608
609
610
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
};

611
int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked)
612
{
613
	struct brcmf_pub *drvr = ifp->drvr;
614
	struct net_device *ndev;
615
	s32 err;
616

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

621
	/* set appropriate operations */
622
	ndev->netdev_ops = &brcmf_netdev_ops_pri;
623
624
625
626
627
628
629

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

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

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

633
634
635
	INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address);
	INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list);

636
637
638
639
640
	if (rtnl_locked)
		err = register_netdevice(ndev);
	else
		err = register_netdev(ndev);
	if (err != 0) {
641
		brcmf_err("couldn't register the net device\n");
642
643
644
645
646
647
648
649
650
651
652
653
		goto fail;
	}

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

	return 0;

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

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
711
712
713
714
715
716
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;
}

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
	/* Allocate netdev, including space for private structure */
745
746
	ndev = alloc_netdev(sizeof(struct brcmf_if), name, ether_setup);
	if (!ndev) {
747
		brcmf_err("OOM - alloc_netdev\n");
748
		return ERR_PTR(-ENOMEM);
749
	}
750

751
752
	ifp = netdev_priv(ndev);
	ifp->ndev = ndev;
753
	ifp->drvr = drvr;
754
755
	drvr->iflist[bssidx] = ifp;
	ifp->ifidx = ifidx;
756
	ifp->bssidx = bssidx;
757
758


759
760
	init_waitqueue_head(&ifp->pend_8021x_wait);

761
762
	if (mac_addr != NULL)
		memcpy(ifp->mac_addr, mac_addr, ETH_ALEN);
763

764
765
	brcmf_dbg(TRACE, " ==== pid:%x, if:%s (%pM) created ===\n",
		  current->pid, ifp->ndev->name, ifp->mac_addr);
766

767
	return ifp;
768
769
}

770
void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
771
772
773
{
	struct brcmf_if *ifp;

774
	ifp = drvr->iflist[bssidx];
775
	if (!ifp) {
776
		brcmf_err("Null interface, idx=%d\n", bssidx);
777
778
		return;
	}
779
	brcmf_dbg(TRACE, "Enter, idx=%d, ifidx=%d\n", bssidx, ifp->ifidx);
780
	if (ifp->ndev) {
781
		if (bssidx == 0) {
782
783
784
785
786
787
788
789
790
			if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
				rtnl_lock();
				brcmf_netdev_stop(ifp->ndev);
				rtnl_unlock();
			}
		} else {
			netif_stop_queue(ifp->ndev);
		}

791
792
793
794
		if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
			cancel_work_sync(&ifp->setmacaddr_work);
			cancel_work_sync(&ifp->multicast_work);
		}
795

796
		unregister_netdev(ifp->ndev);
797
798
		drvr->iflist[bssidx] = NULL;
		if (bssidx == 0)
799
			brcmf_cfg80211_detach(drvr->config);
800
		free_netdev(ifp->ndev);
801
802
803
	}
}

804
int brcmf_attach(uint bus_hdrlen, struct device *dev)
805
{
806
	struct brcmf_pub *drvr = NULL;
807
	int ret = 0;
808
809
810
811

	brcmf_dbg(TRACE, "Enter\n");

	/* Allocate primary brcmf_info */
812
813
	drvr = kzalloc(sizeof(struct brcmf_pub), GFP_ATOMIC);
	if (!drvr)
814
		return -ENOMEM;
815

816
	mutex_init(&drvr->proto_block);
817
818

	/* Link to bus module */
819
820
	drvr->hdrlen = bus_hdrlen;
	drvr->bus_if = dev_get_drvdata(dev);
821
	drvr->bus_if->drvr = drvr;
822

823
824
825
	/* create device debugfs folder */
	brcmf_debugfs_attach(drvr);

826
	/* Attach and link in the protocol */
827
828
	ret = brcmf_proto_attach(drvr);
	if (ret != 0) {
829
		brcmf_err("brcmf_prot_attach failed\n");
830
831
832
		goto fail;
	}

833
834
835
	/* attach firmware event handler */
	brcmf_fweh_attach(drvr);

836
837
	INIT_LIST_HEAD(&drvr->bus_if->dcmd_list);

838
	return ret;
839
840

fail:
841
	brcmf_detach(dev);
842

843
	return ret;
844
845
}

846
int brcmf_bus_start(struct device *dev)
847
848
{
	int ret = -1;
849
850
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_pub *drvr = bus_if->drvr;
851
	struct brcmf_if *ifp;
852
	struct brcmf_if *p2p_ifp;
853
854
855
856

	brcmf_dbg(TRACE, "\n");

	/* Bring up the bus */
857
	ret = brcmf_bus_init(bus_if);
858
	if (ret != 0) {
859
		brcmf_err("brcmf_sdbrcm_bus_init failed %d\n", ret);
860
861
862
		return ret;
	}

863
	/* add primary networking interface */
864
	ifp = brcmf_add_if(drvr, 0, 0, "wlan%d", NULL);
865
866
867
	if (IS_ERR(ifp))
		return PTR_ERR(ifp);

868
869
870
871
872
873
874
	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;

875
876
877
878
879
	/* signal bus ready */
	bus_if->state = BRCMF_BUS_DATA;

	/* Bus is ready, do any initialization */
	ret = brcmf_c_preinit_dcmds(ifp);
880
	if (ret < 0)
881
		goto fail;
882

883
884
885
	drvr->fw_signals = true;
	(void)brcmf_fws_init(drvr);

886
	drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev);
887
888
889
890
	if (drvr->config == NULL) {
		ret = -ENOMEM;
		goto fail;
	}
891

892
893
894
895
	ret = brcmf_fweh_activate_events(ifp);
	if (ret < 0)
		goto fail;

896
	ret = brcmf_net_attach(ifp, false);
897
fail:
898
	if (ret < 0) {
899
		brcmf_err("failed: %d\n", ret);
900
901
		if (drvr->config)
			brcmf_cfg80211_detach(drvr->config);
902
903
		if (drvr->fws)
			brcmf_fws_deinit(drvr);
904
		free_netdev(ifp->ndev);
905
		drvr->iflist[0] = NULL;
906
907
908
909
		if (p2p_ifp) {
			free_netdev(p2p_ifp->ndev);
			drvr->iflist[1] = NULL;
		}
910
		return ret;
911
	}
912
913
	if ((brcmf_p2p_enable) && (p2p_ifp))
		brcmf_net_p2p_attach(p2p_ifp);
914

915
916
917
918
919
920
921
922
	return 0;
}

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

	if (drvr) {
923
924
		/* Stop the protocol module */
		brcmf_proto_stop(drvr);
925

926
		/* Stop the bus module */
927
		brcmf_bus_stop(drvr->bus_if);
928
929
930
	}
}

931
932
933
934
935
936
937
938
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;

939
940
	if (drvr->iflist[0])
		brcmf_fil_cmd_int_set(drvr->iflist[0], BRCMF_C_TERMINATED, 1);
941
942
}

943
void brcmf_detach(struct device *dev)
944
{
945
	s32 i;
946
947
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_pub *drvr = bus_if->drvr;
948
949
950

	brcmf_dbg(TRACE, "Enter\n");

951
952
	if (drvr == NULL)
		return;
953

954
955
956
	/* stop firmware event handling */
	brcmf_fweh_detach(drvr);

957
958
959
960
	/* make sure primary interface removed last */
	for (i = BRCMF_MAX_IFS-1; i > -1; i--)
		if (drvr->iflist[i])
			brcmf_del_if(drvr, i);
961

962
	brcmf_bus_detach(drvr);
963

964
	if (drvr->prot)
965
		brcmf_proto_detach(drvr);
966

967
968
969
	if (drvr->fws)
		brcmf_fws_deinit(drvr);

970
	brcmf_debugfs_detach(drvr);
971
972
	bus_if->drvr = NULL;
	kfree(drvr);
973
974
}

975
static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp)
976
{
977
	return atomic_read(&ifp->pend_8021x_cnt);
978
979
980
981
}

int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
{
982
	struct brcmf_if *ifp = netdev_priv(ndev);
983
984
	int err;

985
986
	err = wait_event_timeout(ifp->pend_8021x_wait,
				 !brcmf_get_pend_8021x_cnt(ifp),
987
988
989
990
991
				 msecs_to_jiffies(MAX_WAIT_FOR_8021X_TX));

	WARN_ON(!err);

	return !err;
992
993
}

994
995
996
997
998
999
1000
/*
 * 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;

For faster browsing, not all history is shown. View entire blame