dhd_linux.c 24.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
#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
	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
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
void brcmf_txflowblock_if(struct brcmf_if *ifp,
			  enum brcmf_netif_stop_reason reason, bool state)
{
	if (!ifp)
		return;

	brcmf_dbg(TRACE, "enter: idx=%d stop=0x%X reason=%d state=%d\n",
		  ifp->bssidx, ifp->netif_stop, reason, state);
	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);
	}
}

259
void brcmf_txflowblock(struct device *dev, bool state)
260
{
261
262
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_pub *drvr = bus_if->drvr;
263
	int i;
264
265
266

	brcmf_dbg(TRACE, "Enter\n");

267
	for (i = 0; i < BRCMF_MAX_IFS; i++)
268
269
		brcmf_txflowblock_if(drvr->iflist[i],
				     BRCMF_NETIF_STOP_REASON_BLOCK_BUS, state);
270
271
}

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

	brcmf_dbg(TRACE, "Enter\n");

285
286
	skb_queue_walk_safe(skb_list, skb, pnext) {
		skb_unlink(skb, skb_list);
287

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

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

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

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

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

326
327
		/* Process special event packets */
		brcmf_fweh_process_skb(drvr, skb);
328

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

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

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

350
351
void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp,
		      bool success)
352
{
353
	struct brcmf_if *ifp;
354
	struct ethhdr *eh;
355
	u8 ifidx;
356
	u16 type;
357
	int res;
358

359
	res = brcmf_proto_hdrpull(drvr, false, &ifidx, txp);
360

361
362
	ifp = drvr->iflist[ifidx];
	if (!ifp)
363
		goto done;
364

365
366
367
	if (res == 0) {
		eh = (struct ethhdr *)(txp->data);
		type = ntohs(eh->h_proto);
368

369
370
371
372
373
		if (type == ETH_P_PAE) {
			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
done:
	brcmu_pkt_buf_free_skb(txp);
379
}
380

381
382
383
384
385
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;

386
387
388
389
390
391
392
	/* 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);
	}
393
394
395
396
}

static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
{
397
	struct brcmf_if *ifp = netdev_priv(ndev);
398

399
	brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
400
401
402
403

	return &ifp->stats;
}

404
405
406
407
408
/*
 * 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)
409
{
410
	s32 err;
411

412
413
	err = brcmf_fil_iovar_int_set(ifp, "toe_ol", toe_ol);
	if (err < 0) {
414
		brcmf_err("Setting toe_ol failed, %d\n", err);
415
		return err;
416
417
	}

418
419
	err = brcmf_fil_iovar_int_set(ifp, "toe", (toe_ol != 0));
	if (err < 0)
420
		brcmf_err("Setting toe failed, %d\n", err);
421

422
	return err;
423
424
425
426
427
428

}

static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
				    struct ethtool_drvinfo *info)
{
429
	struct brcmf_if *ifp = netdev_priv(ndev);
430
	struct brcmf_pub *drvr = ifp->drvr;
431

432
433
434
435
436
	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));
437
438
}

439
440
static const struct ethtool_ops brcmf_ethtool_ops = {
	.get_drvinfo = brcmf_ethtool_get_drvinfo,
441
442
};

443
static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr)
444
{
445
	struct brcmf_pub *drvr = ifp->drvr;
446
447
448
449
450
451
452
	struct ethtool_drvinfo info;
	char drvname[sizeof(info.driver)];
	u32 cmd;
	struct ethtool_value edata;
	u32 toe_cmpnt, csum_dir;
	int ret;

453
	brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475

	/* 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);
		}
476
		/* report dongle driver type */
477
		else
478
			sprintf(info.driver, "wl");
479

480
		sprintf(info.version, "%lu", drvr->drv_version);
481
482
		if (copy_to_user(uaddr, &info, sizeof(info)))
			return -EFAULT;
483
		brcmf_dbg(TRACE, "given %*s, returning %s\n",
484
485
486
487
488
489
			  (int)sizeof(drvname), drvname, info.driver);
		break;

		/* Get toe offload components from dongle */
	case ETHTOOL_GRXCSUM:
	case ETHTOOL_GTXCSUM:
490
		ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt);
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
		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 */
511
		ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt);
512
513
514
515
516
517
518
519
520
521
522
		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;

523
		ret = brcmf_toe_set(ifp, toe_cmpnt);
524
525
526
527
528
529
		if (ret < 0)
			return ret;

		/* If setting TX checksum mode, tell Linux the new mode */
		if (cmd == ETHTOOL_STXCSUM) {
			if (edata.data)
530
				ifp->ndev->features |= NETIF_F_IP_CSUM;
531
			else
532
				ifp->ndev->features &= ~NETIF_F_IP_CSUM;
533
534
535
536
537
538
539
540
541
542
543
544
545
546
		}

		break;

	default:
		return -EOPNOTSUPP;
	}

	return 0;
}

static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr,
				    int cmd)
{
547
	struct brcmf_if *ifp = netdev_priv(ndev);
548
	struct brcmf_pub *drvr = ifp->drvr;
549

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

552
	if (!drvr->iflist[ifp->bssidx])
553
554
555
		return -1;

	if (cmd == SIOCETHTOOL)
556
		return brcmf_ethtool(ifp, ifr->ifr_data);
557
558
559
560
561
562

	return -EOPNOTSUPP;
}

static int brcmf_netdev_stop(struct net_device *ndev)
{
563
	struct brcmf_if *ifp = netdev_priv(ndev);
564

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

567
	brcmf_cfg80211_down(ndev);
568

569
570
571
572
573
574
575
576
	/* Set state and stop OS transmissions */
	netif_stop_queue(ndev);

	return 0;
}

static int brcmf_netdev_open(struct net_device *ndev)
{
577
	struct brcmf_if *ifp = netdev_priv(ndev);
578
	struct brcmf_pub *drvr = ifp->drvr;
579
	struct brcmf_bus *bus_if = drvr->bus_if;
580
581
582
	u32 toe_ol;
	s32 ret = 0;

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

585
586
	/* If bus is not ready, can't continue */
	if (bus_if->state != BRCMF_BUS_DATA) {
587
		brcmf_err("failed bus is not ready\n");
588
589
		return -EAGAIN;
	}
590

591
	atomic_set(&ifp->pend_8021x_cnt, 0);
592

593
594
595
	/* 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)
596
		ndev->features |= NETIF_F_IP_CSUM;
597
	else
598
		ndev->features &= ~NETIF_F_IP_CSUM;
599

600
601
	/* Allow transmit calls */
	netif_start_queue(ndev);
602
	if (brcmf_cfg80211_up(ndev)) {
603
		brcmf_err("failed to bring up cfg80211\n");
604
605
606
607
608
609
		return -1;
	}

	return ret;
}

610
611
612
613
614
615
616
617
618
619
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
};

620
int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked)
621
{
622
	struct brcmf_pub *drvr = ifp->drvr;
623
	struct net_device *ndev;
624
	s32 err;
625

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

630
	/* set appropriate operations */
631
	ndev->netdev_ops = &brcmf_netdev_ops_pri;
632
633
634
635
636
637
638

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

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

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

642
643
644
	INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address);
	INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list);

645
646
647
648
649
	if (rtnl_locked)
		err = register_netdevice(ndev);
	else
		err = register_netdev(ndev);
	if (err != 0) {
650
		brcmf_err("couldn't register the net device\n");
651
652
653
654
655
656
657
658
		goto fail;
	}

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

	return 0;

fail:
659
	drvr->iflist[ifp->bssidx] = NULL;
660
	ndev->netdev_ops = NULL;
661
	free_netdev(ndev);
662
663
664
	return -EBADE;
}

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
717
718
719
720
721
722
723
724
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:
725
726
727
	ifp->drvr->iflist[ifp->bssidx] = NULL;
	ndev->netdev_ops = NULL;
	free_netdev(ndev);
728
729
730
	return -EBADE;
}

731
732
struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
			      char *name, u8 *mac_addr)
733
734
{
	struct brcmf_if *ifp;
735
	struct net_device *ndev;
736

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

739
	ifp = drvr->iflist[bssidx];
740
741
742
743
744
	/*
	 * Delete the existing interface before overwriting it
	 * in case we missed the BRCMF_E_IF_DEL event.
	 */
	if (ifp) {
745
		brcmf_err("ERROR: netdev:%s already exists\n",
746
			  ifp->ndev->name);
747
748
749
750
		if (ifidx) {
			netif_stop_queue(ifp->ndev);
			unregister_netdev(ifp->ndev);
			free_netdev(ifp->ndev);
751
			drvr->iflist[bssidx] = NULL;
752
		} else {
753
			brcmf_err("ignore IF event\n");
754
755
			return ERR_PTR(-EINVAL);
		}
756
	}
757

758
759
760
761
	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);
762
763
		if (!ifp)
			return ERR_PTR(-ENOMEM);
764
765
766
767
	} else {
		brcmf_dbg(INFO, "allocate netdev interface\n");
		/* Allocate netdev, including space for private structure */
		ndev = alloc_netdev(sizeof(*ifp), name, ether_setup);
768
		if (!ndev)
769
770
771
772
			return ERR_PTR(-ENOMEM);

		ifp = netdev_priv(ndev);
		ifp->ndev = ndev;
773
	}
774

775
	ifp->drvr = drvr;
776
777
	drvr->iflist[bssidx] = ifp;
	ifp->ifidx = ifidx;
778
	ifp->bssidx = bssidx;
779

780
781
	init_waitqueue_head(&ifp->pend_8021x_wait);

782
783
	if (mac_addr != NULL)
		memcpy(ifp->mac_addr, mac_addr, ETH_ALEN);
784

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

788
	return ifp;
789
790
}

791
void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
792
793
794
{
	struct brcmf_if *ifp;

795
	ifp = drvr->iflist[bssidx];
796
	if (!ifp) {
797
		brcmf_err("Null interface, idx=%d\n", bssidx);
798
799
		return;
	}
800
	brcmf_dbg(TRACE, "Enter, idx=%d, ifidx=%d\n", bssidx, ifp->ifidx);
801
	if (ifp->ndev) {
802
		if (bssidx == 0) {
803
804
805
806
807
808
809
810
811
			if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
				rtnl_lock();
				brcmf_netdev_stop(ifp->ndev);
				rtnl_unlock();
			}
		} else {
			netif_stop_queue(ifp->ndev);
		}

812
813
814
815
		if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
			cancel_work_sync(&ifp->setmacaddr_work);
			cancel_work_sync(&ifp->multicast_work);
		}
816

817
		unregister_netdev(ifp->ndev);
818
		if (bssidx == 0)
819
			brcmf_cfg80211_detach(drvr->config);
820
		free_netdev(ifp->ndev);
821
822
	} else {
		kfree(ifp);
823
	}
824
	drvr->iflist[bssidx] = NULL;
825
826
}

827
int brcmf_attach(uint bus_hdrlen, struct device *dev)
828
{
829
	struct brcmf_pub *drvr = NULL;
830
	int ret = 0;
831
832
833
834

	brcmf_dbg(TRACE, "Enter\n");

	/* Allocate primary brcmf_info */
835
836
	drvr = kzalloc(sizeof(struct brcmf_pub), GFP_ATOMIC);
	if (!drvr)
837
		return -ENOMEM;
838

839
	mutex_init(&drvr->proto_block);
840
841

	/* Link to bus module */
842
843
	drvr->hdrlen = bus_hdrlen;
	drvr->bus_if = dev_get_drvdata(dev);
844
	drvr->bus_if->drvr = drvr;
845

846
847
848
	/* create device debugfs folder */
	brcmf_debugfs_attach(drvr);

849
	/* Attach and link in the protocol */
850
851
	ret = brcmf_proto_attach(drvr);
	if (ret != 0) {
852
		brcmf_err("brcmf_prot_attach failed\n");
853
854
855
		goto fail;
	}

856
857
858
	/* attach firmware event handler */
	brcmf_fweh_attach(drvr);

859
860
	INIT_LIST_HEAD(&drvr->bus_if->dcmd_list);

861
	return ret;
862
863

fail:
864
	brcmf_detach(dev);
865

866
	return ret;
867
868
}

869
int brcmf_bus_start(struct device *dev)
870
871
{
	int ret = -1;
872
873
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_pub *drvr = bus_if->drvr;
874
	struct brcmf_if *ifp;
875
	struct brcmf_if *p2p_ifp;
876
877
878
879

	brcmf_dbg(TRACE, "\n");

	/* Bring up the bus */
880
	ret = brcmf_bus_init(bus_if);
881
	if (ret != 0) {
882
		brcmf_err("brcmf_sdbrcm_bus_init failed %d\n", ret);
883
884
885
		return ret;
	}

886
	/* add primary networking interface */
887
	ifp = brcmf_add_if(drvr, 0, 0, "wlan%d", NULL);
888
889
890
	if (IS_ERR(ifp))
		return PTR_ERR(ifp);

891
892
893
894
895
896
897
	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;

898
899
900
901
902
	/* signal bus ready */
	bus_if->state = BRCMF_BUS_DATA;

	/* Bus is ready, do any initialization */
	ret = brcmf_c_preinit_dcmds(ifp);
903
	if (ret < 0)
904
		goto fail;
905

906
	drvr->fw_signals = true;
907
908
909
910
	ret = brcmf_fws_init(drvr);
	if (ret < 0)
		goto fail;

911
	brcmf_fws_add_interface(ifp);
912

913
	drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev);
914
915
916
917
	if (drvr->config == NULL) {
		ret = -ENOMEM;
		goto fail;
	}
918

919
920
921
922
	ret = brcmf_fweh_activate_events(ifp);
	if (ret < 0)
		goto fail;

923
	ret = brcmf_net_attach(ifp, false);
924
fail:
925
	if (ret < 0) {
926
		brcmf_err("failed: %d\n", ret);
927
928
		if (drvr->config)
			brcmf_cfg80211_detach(drvr->config);
929
930
		if (drvr->fws) {
			brcmf_fws_del_interface(ifp);
931
			brcmf_fws_deinit(drvr);
932
		}
933
934
935
936
		if (p2p_ifp) {
			free_netdev(p2p_ifp->ndev);
			drvr->iflist[1] = NULL;
		}
937
		return ret;
938
	}
939
	if ((brcmf_p2p_enable) && (p2p_ifp))
940
941
		if (brcmf_net_p2p_attach(p2p_ifp) < 0)
			brcmf_p2p_enable = 0;
942

943
944
945
946
947
948
949
950
	return 0;
}

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

	if (drvr) {
951
952
		/* Stop the protocol module */
		brcmf_proto_stop(drvr);
953

954
		/* Stop the bus module */
955
		brcmf_bus_stop(drvr->bus_if);
956
957
958
	}
}

959
960
961
962
963
964
965
966
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;

967
968
	if (drvr->iflist[0])
		brcmf_fil_cmd_int_set(drvr->iflist[0], BRCMF_C_TERMINATED, 1);
969
970
}

971
void brcmf_detach(struct device *dev)
972
{
973
	s32 i;
974
975
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_pub *drvr = bus_if->drvr;
976
977
978

	brcmf_dbg(TRACE, "Enter\n");

979
980
	if (drvr == NULL)
		return;
981

982
983
984
	/* stop firmware event handling */
	brcmf_fweh_detach(drvr);

985
986
	/* make sure primary interface removed last */
	for (i = BRCMF_MAX_IFS-1; i > -1; i--)
987
988
		if (drvr->iflist[i]) {
			brcmf_fws_del_interface(drvr->iflist[i]);
989
			brcmf_del_if(drvr, i);
990
		}
991

992
	brcmf_bus_detach(drvr);
993

994
	if (drvr->prot)
995
		brcmf_proto_detach(drvr);
996

997
	brcmf_fws_deinit(drvr);
998

999
	brcmf_debugfs_detach(drvr);
1000
	bus_if->drvr = NULL;