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");
H
Hante Meuleman 已提交
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 */
A
Arend van Spriel 已提交
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

A
Arend van Spriel 已提交
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 */
A
Arend van Spriel 已提交
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)
{
1001
	struct brcmf_if *ifp = netdev_priv(ndev);
1002 1003
	int err;

1004 1005
	err = wait_event_timeout(ifp->pend_8021x_wait,
				 !brcmf_get_pend_8021x_cnt(ifp),
1006 1007 1008 1009 1010
				 msecs_to_jiffies(MAX_WAIT_FOR_8021X_TX));

	WARN_ON(!err);

	return !err;
1011 1012
}

1013 1014 1015 1016 1017 1018 1019 1020 1021 1022
/*
 * 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;
}

1023
static void brcmf_driver_init(struct work_struct *work)
1024
{
1025 1026
	brcmf_debugfs_init();

1027
#ifdef CONFIG_BRCMFMAC_SDIO
1028
	brcmf_sdio_init();
1029
#endif
1030
#ifdef CONFIG_BRCMFMAC_USB
1031
	brcmf_usb_init();
1032
#endif
1033 1034 1035 1036 1037 1038 1039 1040
}
static DECLARE_WORK(brcmf_driver_work, brcmf_driver_init);

static int __init brcmfmac_module_init(void)
{
	if (!schedule_work(&brcmf_driver_work))
		return -EBUSY;

1041
	return 0;
1042 1043
}

1044
static void __exit brcmfmac_module_exit(void)
1045
{
1046 1047
	cancel_work_sync(&brcmf_driver_work);

1048 1049 1050
#ifdef CONFIG_BRCMFMAC_SDIO
	brcmf_sdio_exit();
#endif
1051 1052 1053
#ifdef CONFIG_BRCMFMAC_USB
	brcmf_usb_exit();
#endif
1054
	brcmf_debugfs_exit();
1055 1056
}

1057 1058
module_init(brcmfmac_module_init);
module_exit(brcmfmac_module_exit);