dhd_linux.c 24.4 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 246 247 248 249
	if (!ifp)
		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
	brcmf_fws_bus_blocked(drvr, state);

274
	for (i = 0; i < BRCMF_MAX_IFS; i++)
275 276
		brcmf_txflowblock_if(drvr->iflist[i],
				     BRCMF_NETIF_STOP_REASON_BLOCK_BUS, state);
277 278
}

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

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

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

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

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

306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
		/* 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)
325
			ifp->stats.multicast++;
326 327 328 329 330 331 332

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

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

333 334
		/* Process special event packets */
		brcmf_fweh_process_skb(drvr, skb);
335

336 337 338 339 340 341 342
		if (!(ifp->ndev->flags & IFF_UP)) {
			brcmu_pkt_buf_free_skb(skb);
			continue;
		}

		ifp->stats.rx_bytes += skb->len;
		ifp->stats.rx_packets++;
343 344 345 346 347 348 349 350 351 352 353 354 355 356

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

357 358
void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp,
		      bool success)
359
{
360
	struct brcmf_if *ifp;
361
	struct ethhdr *eh;
362
	u8 ifidx;
363
	u16 type;
364
	int res;
365

366
	res = brcmf_proto_hdrpull(drvr, false, &ifidx, txp);
367

368 369
	ifp = drvr->iflist[ifidx];
	if (!ifp)
370
		goto done;
371

372 373 374
	if (res == 0) {
		eh = (struct ethhdr *)(txp->data);
		type = ntohs(eh->h_proto);
375

376 377 378 379 380
		if (type == ETH_P_PAE) {
			atomic_dec(&ifp->pend_8021x_cnt);
			if (waitqueue_active(&ifp->pend_8021x_wait))
				wake_up(&ifp->pend_8021x_wait);
		}
381
	}
382 383
	if (!success)
		ifp->stats.tx_errors++;
384 385
done:
	brcmu_pkt_buf_free_skb(txp);
386
}
387

388 389 390 391 392
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;

393 394 395 396 397 398 399
	/* 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);
	}
400 401 402 403
}

static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
{
404
	struct brcmf_if *ifp = netdev_priv(ndev);
405

406
	brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
407 408 409 410

	return &ifp->stats;
}

411 412 413 414 415
/*
 * 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)
416
{
417
	s32 err;
418

419 420
	err = brcmf_fil_iovar_int_set(ifp, "toe_ol", toe_ol);
	if (err < 0) {
421
		brcmf_err("Setting toe_ol failed, %d\n", err);
422
		return err;
423 424
	}

425 426
	err = brcmf_fil_iovar_int_set(ifp, "toe", (toe_ol != 0));
	if (err < 0)
427
		brcmf_err("Setting toe failed, %d\n", err);
428

429
	return err;
430 431 432 433 434 435

}

static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
				    struct ethtool_drvinfo *info)
{
436
	struct brcmf_if *ifp = netdev_priv(ndev);
437
	struct brcmf_pub *drvr = ifp->drvr;
438

439 440 441 442 443
	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));
444 445
}

446 447
static const struct ethtool_ops brcmf_ethtool_ops = {
	.get_drvinfo = brcmf_ethtool_get_drvinfo,
448 449
};

450
static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr)
451
{
452
	struct brcmf_pub *drvr = ifp->drvr;
453 454 455 456 457 458 459
	struct ethtool_drvinfo info;
	char drvname[sizeof(info.driver)];
	u32 cmd;
	struct ethtool_value edata;
	u32 toe_cmpnt, csum_dir;
	int ret;

460
	brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482

	/* 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);
		}
483
		/* report dongle driver type */
484
		else
485
			sprintf(info.driver, "wl");
486

487
		sprintf(info.version, "%lu", drvr->drv_version);
488 489
		if (copy_to_user(uaddr, &info, sizeof(info)))
			return -EFAULT;
490
		brcmf_dbg(TRACE, "given %*s, returning %s\n",
491 492 493 494 495 496
			  (int)sizeof(drvname), drvname, info.driver);
		break;

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

530
		ret = brcmf_toe_set(ifp, toe_cmpnt);
531 532 533 534 535 536
		if (ret < 0)
			return ret;

		/* If setting TX checksum mode, tell Linux the new mode */
		if (cmd == ETHTOOL_STXCSUM) {
			if (edata.data)
537
				ifp->ndev->features |= NETIF_F_IP_CSUM;
538
			else
539
				ifp->ndev->features &= ~NETIF_F_IP_CSUM;
540 541 542 543 544 545 546 547 548 549 550 551 552 553
		}

		break;

	default:
		return -EOPNOTSUPP;
	}

	return 0;
}

static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr,
				    int cmd)
{
554
	struct brcmf_if *ifp = netdev_priv(ndev);
555
	struct brcmf_pub *drvr = ifp->drvr;
556

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

559
	if (!drvr->iflist[ifp->bssidx])
560 561 562
		return -1;

	if (cmd == SIOCETHTOOL)
563
		return brcmf_ethtool(ifp, ifr->ifr_data);
564 565 566 567 568 569

	return -EOPNOTSUPP;
}

static int brcmf_netdev_stop(struct net_device *ndev)
{
570
	struct brcmf_if *ifp = netdev_priv(ndev);
571

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

574
	brcmf_cfg80211_down(ndev);
575

576 577 578 579 580 581 582 583
	/* Set state and stop OS transmissions */
	netif_stop_queue(ndev);

	return 0;
}

static int brcmf_netdev_open(struct net_device *ndev)
{
584
	struct brcmf_if *ifp = netdev_priv(ndev);
585
	struct brcmf_pub *drvr = ifp->drvr;
586
	struct brcmf_bus *bus_if = drvr->bus_if;
587 588 589
	u32 toe_ol;
	s32 ret = 0;

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

592 593
	/* If bus is not ready, can't continue */
	if (bus_if->state != BRCMF_BUS_DATA) {
594
		brcmf_err("failed bus is not ready\n");
595 596
		return -EAGAIN;
	}
597

598
	atomic_set(&ifp->pend_8021x_cnt, 0);
599

600 601 602
	/* 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)
603
		ndev->features |= NETIF_F_IP_CSUM;
604
	else
605
		ndev->features &= ~NETIF_F_IP_CSUM;
606

607 608
	/* Allow transmit calls */
	netif_start_queue(ndev);
609
	if (brcmf_cfg80211_up(ndev)) {
610
		brcmf_err("failed to bring up cfg80211\n");
611 612 613 614 615 616
		return -1;
	}

	return ret;
}

617 618 619 620 621 622 623 624 625 626
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
};

627
int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked)
628
{
629
	struct brcmf_pub *drvr = ifp->drvr;
630
	struct net_device *ndev;
631
	s32 err;
632

633
	brcmf_dbg(TRACE, "Enter, idx=%d mac=%pM\n", ifp->bssidx,
634
		  ifp->mac_addr);
635
	ndev = ifp->ndev;
636

637
	/* set appropriate operations */
638
	ndev->netdev_ops = &brcmf_netdev_ops_pri;
639 640 641 642 643 644 645

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

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

646 647
	/* set the mac address */
	memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
648

649 650 651
	INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address);
	INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list);

652 653 654 655 656
	if (rtnl_locked)
		err = register_netdevice(ndev);
	else
		err = register_netdev(ndev);
	if (err != 0) {
657
		brcmf_err("couldn't register the net device\n");
658 659 660 661 662
		goto fail;
	}

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

663
	ndev->destructor = free_netdev;
664 665 666
	return 0;

fail:
667
	drvr->iflist[ifp->bssidx] = NULL;
668
	ndev->netdev_ops = NULL;
669
	free_netdev(ndev);
670 671 672
	return -EBADE;
}

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 725 726 727 728 729 730 731 732
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:
733 734 735
	ifp->drvr->iflist[ifp->bssidx] = NULL;
	ndev->netdev_ops = NULL;
	free_netdev(ndev);
736 737 738
	return -EBADE;
}

739 740
struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
			      char *name, u8 *mac_addr)
741 742
{
	struct brcmf_if *ifp;
743
	struct net_device *ndev;
744

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

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

766 767 768 769
	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);
770 771
		if (!ifp)
			return ERR_PTR(-ENOMEM);
772 773 774 775
	} else {
		brcmf_dbg(INFO, "allocate netdev interface\n");
		/* Allocate netdev, including space for private structure */
		ndev = alloc_netdev(sizeof(*ifp), name, ether_setup);
776
		if (!ndev)
777 778 779 780
			return ERR_PTR(-ENOMEM);

		ifp = netdev_priv(ndev);
		ifp->ndev = ndev;
781
	}
782

783
	ifp->drvr = drvr;
784 785
	drvr->iflist[bssidx] = ifp;
	ifp->ifidx = ifidx;
786
	ifp->bssidx = bssidx;
787

788
	init_waitqueue_head(&ifp->pend_8021x_wait);
789
	spin_lock_init(&ifp->netif_stop_lock);
790

791 792
	if (mac_addr != NULL)
		memcpy(ifp->mac_addr, mac_addr, ETH_ALEN);
793

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

797
	return ifp;
798 799
}

800
void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
801 802 803
{
	struct brcmf_if *ifp;

804
	ifp = drvr->iflist[bssidx];
805
	drvr->iflist[bssidx] = NULL;
806
	if (!ifp) {
807
		brcmf_err("Null interface, idx=%d\n", bssidx);
808 809
		return;
	}
810
	brcmf_dbg(TRACE, "Enter, idx=%d, ifidx=%d\n", bssidx, ifp->ifidx);
811
	if (ifp->ndev) {
812
		if (bssidx == 0) {
813 814 815 816 817 818 819 820 821
			if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
				rtnl_lock();
				brcmf_netdev_stop(ifp->ndev);
				rtnl_unlock();
			}
		} else {
			netif_stop_queue(ifp->ndev);
		}

822 823 824 825
		if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
			cancel_work_sync(&ifp->setmacaddr_work);
			cancel_work_sync(&ifp->multicast_work);
		}
826
		/* unregister will take care of freeing it */
827
		unregister_netdev(ifp->ndev);
828
		if (bssidx == 0)
829
			brcmf_cfg80211_detach(drvr->config);
830 831
	} else {
		kfree(ifp);
832 833 834
	}
}

835
int brcmf_attach(uint bus_hdrlen, struct device *dev)
836
{
837
	struct brcmf_pub *drvr = NULL;
838
	int ret = 0;
839 840 841 842

	brcmf_dbg(TRACE, "Enter\n");

	/* Allocate primary brcmf_info */
843 844
	drvr = kzalloc(sizeof(struct brcmf_pub), GFP_ATOMIC);
	if (!drvr)
845
		return -ENOMEM;
846

847
	mutex_init(&drvr->proto_block);
848 849

	/* Link to bus module */
850 851
	drvr->hdrlen = bus_hdrlen;
	drvr->bus_if = dev_get_drvdata(dev);
852
	drvr->bus_if->drvr = drvr;
853

854 855 856
	/* create device debugfs folder */
	brcmf_debugfs_attach(drvr);

857
	/* Attach and link in the protocol */
858 859
	ret = brcmf_proto_attach(drvr);
	if (ret != 0) {
860
		brcmf_err("brcmf_prot_attach failed\n");
861 862 863
		goto fail;
	}

864 865 866
	/* attach firmware event handler */
	brcmf_fweh_attach(drvr);

867 868
	INIT_LIST_HEAD(&drvr->bus_if->dcmd_list);

869
	return ret;
870 871

fail:
872
	brcmf_detach(dev);
873

874
	return ret;
875 876
}

877
int brcmf_bus_start(struct device *dev)
878 879
{
	int ret = -1;
880 881
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_pub *drvr = bus_if->drvr;
882
	struct brcmf_if *ifp;
883
	struct brcmf_if *p2p_ifp;
884 885 886 887

	brcmf_dbg(TRACE, "\n");

	/* Bring up the bus */
A
Arend van Spriel 已提交
888
	ret = brcmf_bus_init(bus_if);
889
	if (ret != 0) {
890
		brcmf_err("brcmf_sdbrcm_bus_init failed %d\n", ret);
891 892 893
		return ret;
	}

894
	/* add primary networking interface */
895
	ifp = brcmf_add_if(drvr, 0, 0, "wlan%d", NULL);
896 897 898
	if (IS_ERR(ifp))
		return PTR_ERR(ifp);

899 900 901 902 903 904 905
	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;

906 907 908 909 910
	/* signal bus ready */
	bus_if->state = BRCMF_BUS_DATA;

	/* Bus is ready, do any initialization */
	ret = brcmf_c_preinit_dcmds(ifp);
911
	if (ret < 0)
912
		goto fail;
913

914
	drvr->fw_signals = true;
915 916 917 918
	ret = brcmf_fws_init(drvr);
	if (ret < 0)
		goto fail;

919
	brcmf_fws_add_interface(ifp);
920

A
Arend van Spriel 已提交
921
	drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev);
922 923 924 925
	if (drvr->config == NULL) {
		ret = -ENOMEM;
		goto fail;
	}
926

927 928 929 930
	ret = brcmf_fweh_activate_events(ifp);
	if (ret < 0)
		goto fail;

931
	ret = brcmf_net_attach(ifp, false);
932
fail:
933
	if (ret < 0) {
934
		brcmf_err("failed: %d\n", ret);
935 936
		if (drvr->config)
			brcmf_cfg80211_detach(drvr->config);
937 938
		if (drvr->fws) {
			brcmf_fws_del_interface(ifp);
939
			brcmf_fws_deinit(drvr);
940
		}
941 942 943 944
		if (p2p_ifp) {
			free_netdev(p2p_ifp->ndev);
			drvr->iflist[1] = NULL;
		}
945
		return ret;
946
	}
947
	if ((brcmf_p2p_enable) && (p2p_ifp))
948 949
		if (brcmf_net_p2p_attach(p2p_ifp) < 0)
			brcmf_p2p_enable = 0;
950

951 952 953 954 955 956 957 958
	return 0;
}

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

	if (drvr) {
959 960
		/* Stop the protocol module */
		brcmf_proto_stop(drvr);
961

962
		/* Stop the bus module */
A
Arend van Spriel 已提交
963
		brcmf_bus_stop(drvr->bus_if);
964 965 966
	}
}

967 968 969 970 971 972 973 974
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;

975 976
	if (drvr->iflist[0])
		brcmf_fil_cmd_int_set(drvr->iflist[0], BRCMF_C_TERMINATED, 1);
977 978
}

979
void brcmf_detach(struct device *dev)
980
{
981
	s32 i;
982 983
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_pub *drvr = bus_if->drvr;
984 985 986

	brcmf_dbg(TRACE, "Enter\n");

987 988
	if (drvr == NULL)
		return;
989

990 991 992
	/* stop firmware event handling */
	brcmf_fweh_detach(drvr);

993 994
	/* make sure primary interface removed last */
	for (i = BRCMF_MAX_IFS-1; i > -1; i--)
995 996
		if (drvr->iflist[i]) {
			brcmf_fws_del_interface(drvr->iflist[i]);
997
			brcmf_del_if(drvr, i);
998
		}
999

1000
	brcmf_bus_detach(drvr);
1001

1002
	if (drvr->prot)
1003
		brcmf_proto_detach(drvr);
1004

1005
	brcmf_fws_deinit(drvr);
1006

1007
	brcmf_debugfs_detach(drvr);
1008 1009
	bus_if->drvr = NULL;
	kfree(drvr);
1010 1011
}

1012
static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp)
1013
{
1014
	return atomic_read(&ifp->pend_8021x_cnt);
1015 1016 1017 1018
}

int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
{
1019
	struct brcmf_if *ifp = netdev_priv(ndev);
1020 1021
	int err;

1022 1023
	err = wait_event_timeout(ifp->pend_8021x_wait,
				 !brcmf_get_pend_8021x_cnt(ifp),
1024 1025 1026 1027 1028
				 msecs_to_jiffies(MAX_WAIT_FOR_8021X_TX));

	WARN_ON(!err);

	return !err;
1029 1030
}

1031 1032 1033 1034 1035 1036 1037 1038 1039 1040
/*
 * 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;
}

1041
static void brcmf_driver_init(struct work_struct *work)
1042
{
1043 1044
	brcmf_debugfs_init();

1045
#ifdef CONFIG_BRCMFMAC_SDIO
1046
	brcmf_sdio_init();
1047
#endif
1048
#ifdef CONFIG_BRCMFMAC_USB
1049
	brcmf_usb_init();
1050
#endif
1051 1052 1053 1054 1055 1056 1057 1058
}
static DECLARE_WORK(brcmf_driver_work, brcmf_driver_init);

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

1059
	return 0;
1060 1061
}

1062
static void __exit brcmfmac_module_exit(void)
1063
{
1064 1065
	cancel_work_sync(&brcmf_driver_work);

1066 1067 1068
#ifdef CONFIG_BRCMFMAC_SDIO
	brcmf_sdio_exit();
#endif
1069 1070 1071
#ifdef CONFIG_BRCMFMAC_USB
	brcmf_usb_exit();
#endif
1072
	brcmf_debugfs_exit();
1073 1074
}

1075 1076
module_init(brcmfmac_module_init);
module_exit(brcmfmac_module_exit);