dhd_linux.c 23.3 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
36
MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
MODULE_SUPPORTED_DEVICE("Broadcom 802.11 WLAN fullmac cards");
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, &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

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

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

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

371
	if (type == ETH_P_PAE) {
372
373
374
		atomic_dec(&ifp->pend_8021x_cnt);
		if (waitqueue_active(&ifp->pend_8021x_wait))
			wake_up(&ifp->pend_8021x_wait);
375
	}
376
377
	if (!success)
		ifp->stats.tx_errors++;
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
619
620
621
622
623

	ndev->hard_header_len = ETH_HLEN + drvr->hdrlen;
	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
641
642
643
644
645
646
647
		goto fail;
	}

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

	return 0;

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

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
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:
	return -EBADE;
}

711
712
struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
			      char *name, u8 *mac_addr)
713
714
{
	struct brcmf_if *ifp;
715
	struct net_device *ndev;
716

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

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

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

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


753
754
	init_waitqueue_head(&ifp->pend_8021x_wait);

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

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

761
	return ifp;
762
763
}

764
void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
765
766
767
{
	struct brcmf_if *ifp;

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

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

790
		unregister_netdev(ifp->ndev);
791
792
		drvr->iflist[bssidx] = NULL;
		if (bssidx == 0)
793
			brcmf_cfg80211_detach(drvr->config);
794
		free_netdev(ifp->ndev);
795
796
797
	}
}

798
int brcmf_attach(uint bus_hdrlen, struct device *dev)
799
{
800
	struct brcmf_pub *drvr = NULL;
801
	int ret = 0;
802
803
804
805

	brcmf_dbg(TRACE, "Enter\n");

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

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

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

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

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

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

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

832
	return ret;
833
834

fail:
835
	brcmf_detach(dev);
836

837
	return ret;
838
839
}

840
int brcmf_bus_start(struct device *dev)
841
842
{
	int ret = -1;
843
844
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_pub *drvr = bus_if->drvr;
845
	struct brcmf_if *ifp;
846
	struct brcmf_if *p2p_ifp;
847
848
849
850

	brcmf_dbg(TRACE, "\n");

	/* Bring up the bus */
851
	ret = brcmf_bus_init(bus_if);
852
	if (ret != 0) {
853
		brcmf_err("brcmf_sdbrcm_bus_init failed %d\n", ret);
854
855
856
		return ret;
	}

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

862
863
864
865
866
867
868
	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;

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

	/* Bus is ready, do any initialization */
	ret = brcmf_c_preinit_dcmds(ifp);
874
	if (ret < 0)
875
		goto fail;
876

877
	drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev);
878
879
880
881
	if (drvr->config == NULL) {
		ret = -ENOMEM;
		goto fail;
	}
882

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

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

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

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

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

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

920
921
922
923
924
925
926
927
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;

928
929
	if (drvr->iflist[0])
		brcmf_fil_cmd_int_set(drvr->iflist[0], BRCMF_C_TERMINATED, 1);
930
931
}

932
void brcmf_detach(struct device *dev)
933
{
934
	s32 i;
935
936
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_pub *drvr = bus_if->drvr;
937
938
939

	brcmf_dbg(TRACE, "Enter\n");

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

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

946
947
948
949
	/* make sure primary interface removed last */
	for (i = BRCMF_MAX_IFS-1; i > -1; i--)
		if (drvr->iflist[i])
			brcmf_del_if(drvr, i);
950

951
	brcmf_bus_detach(drvr);
952

953
	if (drvr->prot)
954
		brcmf_proto_detach(drvr);
955

956
	brcmf_debugfs_detach(drvr);
957
958
	bus_if->drvr = NULL;
	kfree(drvr);
959
960
}

961
static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp)
962
{
963
	return atomic_read(&ifp->pend_8021x_cnt);
964
965
966
967
}

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

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

	WARN_ON(!err);

	return !err;
978
979
}

980
981
982
983
984
985
986
987
988
989
/*
 * 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;
}

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

994
#ifdef CONFIG_BRCMFMAC_SDIO
995
	brcmf_sdio_init();
996
#endif
997
#ifdef CONFIG_BRCMFMAC_USB
998
	brcmf_usb_init();
999
#endif
1000
}
For faster browsing, not all history is shown. View entire blame