main.c 31.3 KB
Newer Older
1 2 3 4 5 6
/**
  * This file contains the major functions in WLAN
  * driver. It includes init, exit, open, close and main
  * thread etc..
  */

7
#include <linux/moduleparam.h>
8 9 10 11
#include <linux/delay.h>
#include <linux/etherdevice.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
12
#include <linux/kthread.h>
13
#include <linux/kfifo.h>
14
#include <linux/stddef.h>
J
Johannes Berg 已提交
15
#include <linux/ieee80211.h>
16
#include <net/iw_handler.h>
17
#include <net/cfg80211.h>
18 19 20 21 22

#include "host.h"
#include "decl.h"
#include "dev.h"
#include "wext.h"
23
#include "cfg.h"
24
#include "debugfs.h"
25
#include "scan.h"
26
#include "assoc.h"
27
#include "cmd.h"
28

29
#define DRIVER_RELEASE_VERSION "323.p0"
30
const char lbs_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION
31 32 33 34 35
#ifdef  DEBUG
    "-dbg"
#endif
    "";

36 37

/* Module parameters */
38 39 40
unsigned int lbs_debug;
EXPORT_SYMBOL_GPL(lbs_debug);
module_param_named(libertas_debug, lbs_debug, int, 0644);
41 42


43 44 45 46 47
/* This global structure is used to send the confirm_sleep command as
 * fast as possible down to the firmware. */
struct cmd_confirm_sleep confirm_sleep;


48
/**
49
 * the table to keep region code
50
 */
51
u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE] =
52
    { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 };
53 54

/**
55 56 57
 * FW rate table.  FW refers to rates by their index in this table, not by the
 * rate value itself.  Values of 0x00 are
 * reserved positions.
58
 */
59 60 61 62
static u8 fw_data_rates[MAX_RATES] =
    { 0x02, 0x04, 0x0B, 0x16, 0x00, 0x0C, 0x12,
      0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x00
};
63 64

/**
65 66 67 68
 *  @brief use index to get the data rate
 *
 *  @param idx                The index of data rate
 *  @return 	   		data rate or 0
69
 */
70
u32 lbs_fw_index_to_data_rate(u8 idx)
71 72 73 74 75 76 77 78 79 80 81 82
{
	if (idx >= sizeof(fw_data_rates))
		idx = 0;
	return fw_data_rates[idx];
}

/**
 *  @brief use rate to get the index
 *
 *  @param rate                 data rate
 *  @return 	   		index or 0
 */
83
u8 lbs_data_rate_to_fw_index(u32 rate)
84 85 86 87 88 89 90 91 92 93 94 95
{
	u8 i;

	if (!rate)
		return 0;

	for (i = 0; i < sizeof(fw_data_rates); i++) {
		if (rate == fw_data_rates[i])
			return i;
	}
	return 0;
}
96

97

98 99
static int lbs_add_rtap(struct lbs_private *priv);
static void lbs_remove_rtap(struct lbs_private *priv);
100

101 102 103 104

/**
 * Get function for sysfs attribute rtap
 */
105
static ssize_t lbs_rtap_get(struct device *dev,
106 107
		struct device_attribute *attr, char * buf)
{
108
	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
109
	return snprintf(buf, 5, "0x%X\n", priv->monitormode);
110 111 112 113 114
}

/**
 *  Set function for sysfs attribute rtap
 */
115
static ssize_t lbs_rtap_set(struct device *dev,
116 117 118
		struct device_attribute *attr, const char * buf, size_t count)
{
	int monitor_mode;
119
	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
120 121

	sscanf(buf, "%x", &monitor_mode);
122 123
	if (monitor_mode) {
		if (priv->monitormode == monitor_mode)
124
			return strlen(buf);
125
		if (!priv->monitormode) {
126
			if (priv->infra_open || lbs_mesh_open(priv))
127
				return -EBUSY;
128
			if (priv->mode == IW_MODE_INFRA)
129 130 131
				lbs_cmd_80211_deauthenticate(priv,
							     priv->curbssparams.bssid,
							     WLAN_REASON_DEAUTH_LEAVING);
132
			else if (priv->mode == IW_MODE_ADHOC)
133
				lbs_adhoc_stop(priv);
134
			lbs_add_rtap(priv);
135
		}
136
		priv->monitormode = monitor_mode;
137
	} else {
138
		if (!priv->monitormode)
139
			return strlen(buf);
140
		priv->monitormode = 0;
141
		lbs_remove_rtap(priv);
D
David Woodhouse 已提交
142

143 144 145
		if (priv->currenttxskb) {
			dev_kfree_skb_any(priv->currenttxskb);
			priv->currenttxskb = NULL;
D
David Woodhouse 已提交
146 147 148 149
		}

		/* Wake queues, command thread, etc. */
		lbs_host_to_card_done(priv);
150 151
	}

152
	lbs_prepare_and_send_command(priv,
153
			CMD_802_11_MONITOR_MODE, CMD_ACT_SET,
154
			CMD_OPTION_WAITFORRSP, 0, &priv->monitormode);
155 156 157 158
	return strlen(buf);
}

/**
159 160
 * lbs_rtap attribute to be exported per ethX interface
 * through sysfs (/sys/class/net/ethX/lbs_rtap)
161
 */
162 163 164
static DEVICE_ATTR(lbs_rtap, 0644, lbs_rtap_get, lbs_rtap_set );

/**
165
 *  @brief This function opens the ethX interface
166 167
 *
 *  @param dev     A pointer to net_device structure
168
 *  @return 	   0 or -EBUSY if monitor mode active
169
 */
170
static int lbs_dev_open(struct net_device *dev)
171
{
172
	struct lbs_private *priv = dev->ml_priv;
173
	int ret = 0;
174

175 176
	lbs_deb_enter(LBS_DEB_NET);

177
	spin_lock_irq(&priv->driver_lock);
178

179
	if (priv->monitormode) {
180 181 182
		ret = -EBUSY;
		goto out;
	}
183

184
	priv->infra_open = 1;
185

186 187 188 189
	if (priv->connect_status == LBS_CONNECTED)
		netif_carrier_on(dev);
	else
		netif_carrier_off(dev);
190

191 192 193
	if (!priv->tx_pending_len)
		netif_wake_queue(dev);
 out:
194

195
	spin_unlock_irq(&priv->driver_lock);
196
	lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
197
	return ret;
198 199 200 201 202 203 204 205
}

/**
 *  @brief This function closes the ethX interface
 *
 *  @param dev     A pointer to net_device structure
 *  @return 	   0
 */
206
static int lbs_eth_stop(struct net_device *dev)
207
{
208
	struct lbs_private *priv = dev->ml_priv;
209

210
	lbs_deb_enter(LBS_DEB_NET);
211

212
	spin_lock_irq(&priv->driver_lock);
213
	priv->infra_open = 0;
214 215
	netif_stop_queue(dev);
	spin_unlock_irq(&priv->driver_lock);
216

217 218
	schedule_work(&priv->mcast_work);

219
	lbs_deb_leave(LBS_DEB_NET);
220
	return 0;
221 222
}

223
static void lbs_tx_timeout(struct net_device *dev)
224
{
225
	struct lbs_private *priv = dev->ml_priv;
226

227
	lbs_deb_enter(LBS_DEB_TX);
228

229
	lbs_pr_err("tx watch dog timeout\n");
230 231 232

	dev->trans_start = jiffies;

233 234 235
	if (priv->currenttxskb)
		lbs_send_tx_feedback(priv, 0);

236 237 238
	/* XX: Shouldn't we also call into the hw-specific driver
	   to kick it somehow? */
	lbs_host_to_card_done(priv);
239

240 241 242 243 244 245 246
	/* More often than not, this actually happens because the
	   firmware has crapped itself -- rather than just a very
	   busy medium. So send a harmless command, and if/when
	   _that_ times out, we'll kick it in the head. */
	lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
				     0, 0, NULL);

247
	lbs_deb_leave(LBS_DEB_TX);
248 249
}

250 251
void lbs_host_to_card_done(struct lbs_private *priv)
{
252 253
	unsigned long flags;

254 255
	lbs_deb_enter(LBS_DEB_THREAD);

256
	spin_lock_irqsave(&priv->driver_lock, flags);
257 258 259 260

	priv->dnld_sent = DNLD_RES_RECEIVED;

	/* Wake main thread if commands are pending */
261 262 263 264
	if (!priv->cur_cmd || priv->tx_pending_len > 0) {
		if (!priv->wakeup_dev_required)
			wake_up_interruptible(&priv->waitq);
	}
265

266
	spin_unlock_irqrestore(&priv->driver_lock, flags);
267
	lbs_deb_leave(LBS_DEB_THREAD);
268 269 270
}
EXPORT_SYMBOL_GPL(lbs_host_to_card_done);

271
int lbs_set_mac_address(struct net_device *dev, void *addr)
272 273
{
	int ret = 0;
274
	struct lbs_private *priv = dev->ml_priv;
275
	struct sockaddr *phwaddr = addr;
276
	struct cmd_ds_802_11_mac_address cmd;
277

278
	lbs_deb_enter(LBS_DEB_NET);
279

280
	/* In case it was called from the mesh device */
281
	dev = priv->dev;
282

283 284 285
	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
	cmd.action = cpu_to_le16(CMD_ACT_SET);
	memcpy(cmd.macadd, phwaddr->sa_data, ETH_ALEN);
286

287
	ret = lbs_cmd_with_response(priv, CMD_802_11_MAC_ADDRESS, &cmd);
288
	if (ret) {
289
		lbs_deb_net("set MAC address failed\n");
290 291 292
		goto done;
	}

293 294
	memcpy(priv->current_addr, phwaddr->sa_data, ETH_ALEN);
	memcpy(dev->dev_addr, phwaddr->sa_data, ETH_ALEN);
295
	if (priv->mesh_dev)
296
		memcpy(priv->mesh_dev->dev_addr, phwaddr->sa_data, ETH_ALEN);
297 298

done:
299
	lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
300 301 302
	return ret;
}

303 304 305

static inline int mac_in_list(unsigned char *list, int list_len,
			      unsigned char *mac)
306
{
307 308 309 310 311 312 313 314 315
	while (list_len) {
		if (!memcmp(list, mac, ETH_ALEN))
			return 1;
		list += ETH_ALEN;
		list_len--;
	}
	return 0;
}

316

317 318 319 320 321
static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd,
			       struct net_device *dev, int nr_addrs)
{
	int i = nr_addrs;
	struct dev_mc_list *mc_list;
322
	int cnt;
323 324 325 326

	if ((dev->flags & (IFF_UP|IFF_MULTICAST)) != (IFF_UP|IFF_MULTICAST))
		return nr_addrs;

327
	netif_addr_lock_bh(dev);
328 329
	cnt = netdev_mc_count(dev);
	netdev_for_each_mc_addr(mc_list, dev) {
330
		if (mac_in_list(cmd->maclist, nr_addrs, mc_list->dmi_addr)) {
J
Johannes Berg 已提交
331 332
			lbs_deb_net("mcast address %s:%pM skipped\n", dev->name,
				    mc_list->dmi_addr);
333
			cnt--;
334 335
			continue;
		}
336

337 338 339
		if (i == MRVDRV_MAX_MULTICAST_LIST_SIZE)
			break;
		memcpy(&cmd->maclist[6*i], mc_list->dmi_addr, ETH_ALEN);
J
Johannes Berg 已提交
340 341
		lbs_deb_net("mcast address %s:%pM added to filter\n", dev->name,
			    mc_list->dmi_addr);
342
		i++;
343
		cnt--;
344
	}
345
	netif_addr_unlock_bh(dev);
346
	if (cnt)
347 348
		return -EOVERFLOW;

349 350 351
	return i;
}

352
static void lbs_set_mcast_worker(struct work_struct *work)
353
{
354 355 356 357 358
	struct lbs_private *priv = container_of(work, struct lbs_private, mcast_work);
	struct cmd_ds_mac_multicast_adr mcast_cmd;
	int dev_flags;
	int nr_addrs;
	int old_mac_control = priv->mac_control;
359

360
	lbs_deb_enter(LBS_DEB_NET);
361

362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
	dev_flags = priv->dev->flags;
	if (priv->mesh_dev)
		dev_flags |= priv->mesh_dev->flags;

	if (dev_flags & IFF_PROMISC) {
		priv->mac_control |= CMD_ACT_MAC_PROMISCUOUS_ENABLE;
		priv->mac_control &= ~(CMD_ACT_MAC_ALL_MULTICAST_ENABLE |
				       CMD_ACT_MAC_MULTICAST_ENABLE);
		goto out_set_mac_control;
	} else if (dev_flags & IFF_ALLMULTI) {
	do_allmulti:
		priv->mac_control |= CMD_ACT_MAC_ALL_MULTICAST_ENABLE;
		priv->mac_control &= ~(CMD_ACT_MAC_PROMISCUOUS_ENABLE |
				       CMD_ACT_MAC_MULTICAST_ENABLE);
		goto out_set_mac_control;
377 378
	}

379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402
	/* Once for priv->dev, again for priv->mesh_dev if it exists */
	nr_addrs = lbs_add_mcast_addrs(&mcast_cmd, priv->dev, 0);
	if (nr_addrs >= 0 && priv->mesh_dev)
		nr_addrs = lbs_add_mcast_addrs(&mcast_cmd, priv->mesh_dev, nr_addrs);
	if (nr_addrs < 0)
		goto do_allmulti;

	if (nr_addrs) {
		int size = offsetof(struct cmd_ds_mac_multicast_adr,
				    maclist[6*nr_addrs]);

		mcast_cmd.action = cpu_to_le16(CMD_ACT_SET);
		mcast_cmd.hdr.size = cpu_to_le16(size);
		mcast_cmd.nr_of_adrs = cpu_to_le16(nr_addrs);

		lbs_cmd_async(priv, CMD_MAC_MULTICAST_ADR, &mcast_cmd.hdr, size);

		priv->mac_control |= CMD_ACT_MAC_MULTICAST_ENABLE;
	} else
		priv->mac_control &= ~CMD_ACT_MAC_MULTICAST_ENABLE;

	priv->mac_control &= ~(CMD_ACT_MAC_PROMISCUOUS_ENABLE |
			       CMD_ACT_MAC_ALL_MULTICAST_ENABLE);
 out_set_mac_control:
403 404
	if (priv->mac_control != old_mac_control)
		lbs_set_mac_control(priv);
405

406
	lbs_deb_leave(LBS_DEB_NET);
407 408
}

409
void lbs_set_multicast_list(struct net_device *dev)
410
{
411
	struct lbs_private *priv = dev->ml_priv;
412 413 414 415

	schedule_work(&priv->mcast_work);
}

416
/**
417
 *  @brief This function handles the major jobs in the LBS driver.
418 419
 *  It handles all events generated by firmware, RX data received
 *  from firmware and TX data sent from kernel.
420
 *
421
 *  @param data    A pointer to lbs_thread structure
422 423
 *  @return 	   0
 */
424
static int lbs_thread(void *data)
425
{
426
	struct net_device *dev = data;
427
	struct lbs_private *priv = dev->ml_priv;
428 429
	wait_queue_t wait;

430
	lbs_deb_enter(LBS_DEB_THREAD);
431 432 433 434

	init_waitqueue_entry(&wait, current);

	for (;;) {
435
		int shouldsleep;
436
		u8 resp_idx;
437

438 439
		lbs_deb_thread("1: currenttxskb %p, dnld_sent %d\n",
				priv->currenttxskb, priv->dnld_sent);
440

441
		add_wait_queue(&priv->waitq, &wait);
442
		set_current_state(TASK_INTERRUPTIBLE);
443
		spin_lock_irq(&priv->driver_lock);
444

445
		if (kthread_should_stop())
446
			shouldsleep = 0;	/* Bye */
447 448
		else if (priv->surpriseremoved)
			shouldsleep = 1;	/* We need to wait until we're _told_ to die */
449 450
		else if (priv->psstate == PS_STATE_SLEEP)
			shouldsleep = 1;	/* Sleep mode. Nothing we can do till it wakes */
451 452
		else if (priv->cmd_timed_out)
			shouldsleep = 0;	/* Command timed out. Recover */
453 454
		else if (!priv->fw_ready)
			shouldsleep = 1;	/* Firmware not ready. We're waiting for it */
455 456
		else if (priv->dnld_sent)
			shouldsleep = 1;	/* Something is en route to the device already */
457 458
		else if (priv->tx_pending_len > 0)
			shouldsleep = 0;	/* We've a packet to send */
459 460
		else if (priv->resp_len[priv->resp_idx])
			shouldsleep = 0;	/* We have a command response */
461 462
		else if (priv->cur_cmd)
			shouldsleep = 1;	/* Can't send a command; one already running */
463 464
		else if (!list_empty(&priv->cmdpendingq) &&
					!(priv->wakeup_dev_required))
465
			shouldsleep = 0;	/* We have a command to send */
S
Stefani Seibold 已提交
466
		else if (kfifo_len(&priv->event_fifo))
467
			shouldsleep = 0;	/* We have an event to process */
468 469 470 471
		else
			shouldsleep = 1;	/* No command */

		if (shouldsleep) {
472
			lbs_deb_thread("sleeping, connect_status %d, "
473
				"psmode %d, psstate %d\n",
474 475
				priv->connect_status,
				priv->psmode, priv->psstate);
476
			spin_unlock_irq(&priv->driver_lock);
477 478
			schedule();
		} else
479
			spin_unlock_irq(&priv->driver_lock);
480

481 482
		lbs_deb_thread("2: currenttxskb %p, dnld_send %d\n",
			       priv->currenttxskb, priv->dnld_sent);
483 484

		set_current_state(TASK_RUNNING);
485
		remove_wait_queue(&priv->waitq, &wait);
486

487 488
		lbs_deb_thread("3: currenttxskb %p, dnld_sent %d\n",
			       priv->currenttxskb, priv->dnld_sent);
489

490
		if (kthread_should_stop()) {
491
			lbs_deb_thread("break from main thread\n");
492 493 494
			break;
		}

495 496 497 498
		if (priv->surpriseremoved) {
			lbs_deb_thread("adapter removed; waiting to die...\n");
			continue;
		}
499

500 501
		lbs_deb_thread("4: currenttxskb %p, dnld_sent %d\n",
		       priv->currenttxskb, priv->dnld_sent);
502

503
		/* Process any pending command response */
504
		spin_lock_irq(&priv->driver_lock);
505 506
		resp_idx = priv->resp_idx;
		if (priv->resp_len[resp_idx]) {
507
			spin_unlock_irq(&priv->driver_lock);
508 509 510
			lbs_process_command_response(priv,
				priv->resp_buf[resp_idx],
				priv->resp_len[resp_idx]);
511
			spin_lock_irq(&priv->driver_lock);
512
			priv->resp_len[resp_idx] = 0;
513
		}
514
		spin_unlock_irq(&priv->driver_lock);
515

516 517
		/* Process hardware events, e.g. card removed, link lost */
		spin_lock_irq(&priv->driver_lock);
S
Stefani Seibold 已提交
518
		while (kfifo_len(&priv->event_fifo)) {
519
			u32 event;
520

S
Stefani Seibold 已提交
521 522 523 524
			if (kfifo_out(&priv->event_fifo,
				(unsigned char *) &event, sizeof(event)) !=
				sizeof(event))
					break;
525 526 527 528 529 530 531 532 533 534 535 536 537 538
			spin_unlock_irq(&priv->driver_lock);
			lbs_process_event(priv, event);
			spin_lock_irq(&priv->driver_lock);
		}
		spin_unlock_irq(&priv->driver_lock);

		if (priv->wakeup_dev_required) {
			lbs_deb_thread("Waking up device...\n");
			/* Wake up device */
			if (priv->exit_deep_sleep(priv))
				lbs_deb_thread("Wakeup device failed\n");
			continue;
		}

539
		/* command timeout stuff */
540 541 542
		if (priv->cmd_timed_out && priv->cur_cmd) {
			struct cmd_ctrl_node *cmdnode = priv->cur_cmd;

H
Holger Schurig 已提交
543 544 545 546 547
			lbs_pr_info("Timeout submitting command 0x%04x\n",
				le16_to_cpu(cmdnode->cmdbuf->command));
			lbs_complete_command(priv, cmdnode, -ETIMEDOUT);
			if (priv->reset_card)
				priv->reset_card(priv);
548 549 550
		}
		priv->cmd_timed_out = 0;

551 552 553
		if (!priv->fw_ready)
			continue;

554
		/* Check if we need to confirm Sleep Request received previously */
555 556 557
		if (priv->psstate == PS_STATE_PRE_SLEEP &&
		    !priv->dnld_sent && !priv->cur_cmd) {
			if (priv->connect_status == LBS_CONNECTED) {
558 559 560 561
				lbs_deb_thread("pre-sleep, currenttxskb %p, "
					"dnld_sent %d, cur_cmd %p\n",
					priv->currenttxskb, priv->dnld_sent,
					priv->cur_cmd);
562

563
				lbs_ps_confirm_sleep(priv);
564 565 566 567 568 569
			} else {
				/* workaround for firmware sending
				 * deauth/linkloss event immediately
				 * after sleep request; remove this
				 * after firmware fixes it
				 */
570
				priv->psstate = PS_STATE_AWAKE;
571 572
				lbs_pr_alert("ignore PS_SleepConfirm in "
					"non-connected state\n");
573 574 575 576 577 578
			}
		}

		/* The PS state is changed during processing of Sleep Request
		 * event above
		 */
579 580
		if ((priv->psstate == PS_STATE_SLEEP) ||
		    (priv->psstate == PS_STATE_PRE_SLEEP))
581 582
			continue;

583 584 585
		if (priv->is_deep_sleep)
			continue;

586
		/* Execute the next command */
587
		if (!priv->dnld_sent && !priv->cur_cmd)
588
			lbs_execute_next_command(priv);
589 590

		/* Wake-up command waiters which can't sleep in
591
		 * lbs_prepare_and_send_command
592
		 */
593 594
		if (!list_empty(&priv->cmdpendingq))
			wake_up_all(&priv->cmd_pending);
595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611

		spin_lock_irq(&priv->driver_lock);
		if (!priv->dnld_sent && priv->tx_pending_len > 0) {
			int ret = priv->hw_host_to_card(priv, MVMS_DAT,
							priv->tx_pending_buf,
							priv->tx_pending_len);
			if (ret) {
				lbs_deb_tx("host_to_card failed %d\n", ret);
				priv->dnld_sent = DNLD_RES_RECEIVED;
			}
			priv->tx_pending_len = 0;
			if (!priv->currenttxskb) {
				/* We can wake the queues immediately if we aren't
				   waiting for TX feedback */
				if (priv->connect_status == LBS_CONNECTED)
					netif_wake_queue(priv->dev);
				if (priv->mesh_dev &&
612
				    lbs_mesh_connected(priv))
613 614 615 616
					netif_wake_queue(priv->mesh_dev);
			}
		}
		spin_unlock_irq(&priv->driver_lock);
617 618
	}

619
	del_timer(&priv->command_timer);
620
	del_timer(&priv->auto_deepsleep_timer);
621
	wake_up_all(&priv->cmd_pending);
622

623
	lbs_deb_leave(LBS_DEB_THREAD);
624 625 626
	return 0;
}

627 628 629
static int lbs_suspend_callback(struct lbs_private *priv, unsigned long dummy,
				struct cmd_header *cmd)
{
630
	lbs_deb_enter(LBS_DEB_FW);
631 632 633 634 635 636

	netif_device_detach(priv->dev);
	if (priv->mesh_dev)
		netif_device_detach(priv->mesh_dev);

	priv->fw_ready = 0;
637
	lbs_deb_leave(LBS_DEB_FW);
638 639 640 641 642 643 644 645
	return 0;
}

int lbs_suspend(struct lbs_private *priv)
{
	struct cmd_header cmd;
	int ret;

646 647
	lbs_deb_enter(LBS_DEB_FW);

648 649 650 651 652
	if (priv->wol_criteria == 0xffffffff) {
		lbs_pr_info("Suspend attempt without configuring wake params!\n");
		return -EINVAL;
	}

653
	memset(&cmd, 0, sizeof(cmd));
654

655 656 657 658 659
	ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_ACTIVATE, &cmd,
			sizeof(cmd), lbs_suspend_callback, 0);
	if (ret)
		lbs_pr_info("HOST_SLEEP_ACTIVATE failed: %d\n", ret);

660
	lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
661 662 663 664
	return ret;
}
EXPORT_SYMBOL_GPL(lbs_suspend);

665
void lbs_resume(struct lbs_private *priv)
666
{
667 668
	lbs_deb_enter(LBS_DEB_FW);

669 670 671 672 673 674 675 676 677 678 679
	priv->fw_ready = 1;

	/* Firmware doesn't seem to give us RX packets any more
	   until we send it some command. Might as well update */
	lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
				     0, 0, NULL);

	netif_device_attach(priv->dev);
	if (priv->mesh_dev)
		netif_device_attach(priv->mesh_dev);

680
	lbs_deb_leave(LBS_DEB_FW);
681 682 683
}
EXPORT_SYMBOL_GPL(lbs_resume);

H
Holger Schurig 已提交
684
/**
685 686
 * @brief This function gets the HW spec from the firmware and sets
 *        some basic parameters.
H
Holger Schurig 已提交
687
 *
688
 *  @param priv    A pointer to struct lbs_private structure
H
Holger Schurig 已提交
689 690
 *  @return 	   0 or -1
 */
691
static int lbs_setup_firmware(struct lbs_private *priv)
H
Holger Schurig 已提交
692 693
{
	int ret = -1;
694
	s16 curlevel = 0, minlevel = 0, maxlevel = 0;
H
Holger Schurig 已提交
695 696 697

	lbs_deb_enter(LBS_DEB_FW);

698
	/* Read MAC address from firmware */
699
	memset(priv->current_addr, 0xff, ETH_ALEN);
700
	ret = lbs_update_hw_spec(priv);
701
	if (ret)
H
Holger Schurig 已提交
702 703
		goto done;

704 705 706 707 708 709 710 711
	/* Read power levels if available */
	ret = lbs_get_tx_power(priv, &curlevel, &minlevel, &maxlevel);
	if (ret == 0) {
		priv->txpower_cur = curlevel;
		priv->txpower_min = minlevel;
		priv->txpower_max = maxlevel;
	}

712
	lbs_set_mac_control(priv);
H
Holger Schurig 已提交
713 714 715 716 717 718 719 720 721
done:
	lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
	return ret;
}

/**
 *  This function handles the timeout of command sending.
 *  It will re-send the same command again.
 */
H
Holger Schurig 已提交
722
static void lbs_cmd_timeout_handler(unsigned long data)
H
Holger Schurig 已提交
723
{
724
	struct lbs_private *priv = (struct lbs_private *)data;
H
Holger Schurig 已提交
725 726
	unsigned long flags;

727
	lbs_deb_enter(LBS_DEB_CMD);
728
	spin_lock_irqsave(&priv->driver_lock, flags);
H
Holger Schurig 已提交
729

730
	if (!priv->cur_cmd)
731
		goto out;
H
Holger Schurig 已提交
732

733 734
	lbs_pr_info("command 0x%04x timed out\n",
		le16_to_cpu(priv->cur_cmd->cmdbuf->command));
H
Holger Schurig 已提交
735

736
	priv->cmd_timed_out = 1;
H
Holger Schurig 已提交
737
	wake_up_interruptible(&priv->waitq);
738
out:
739
	spin_unlock_irqrestore(&priv->driver_lock, flags);
740
	lbs_deb_leave(LBS_DEB_CMD);
H
Holger Schurig 已提交
741 742
}

743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763
/**
 *  This function put the device back to deep sleep mode when timer expires
 *  and no activity (command, event, data etc.) is detected.
 */
static void auto_deepsleep_timer_fn(unsigned long data)
{
	struct lbs_private *priv = (struct lbs_private *)data;
	int ret;

	lbs_deb_enter(LBS_DEB_CMD);

	if (priv->is_activity_detected) {
		priv->is_activity_detected = 0;
	} else {
		if (priv->is_auto_deep_sleep_enabled &&
				(!priv->wakeup_dev_required) &&
				(priv->connect_status != LBS_CONNECTED)) {
			lbs_deb_main("Entering auto deep sleep mode...\n");
			ret = lbs_prepare_and_send_command(priv,
					CMD_802_11_DEEP_SLEEP, 0,
					0, 0, NULL);
764 765
			if (ret)
				lbs_pr_err("Enter Deep Sleep command failed\n");
766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798
		}
	}
	mod_timer(&priv->auto_deepsleep_timer , jiffies +
				(priv->auto_deep_sleep_timeout * HZ)/1000);
	lbs_deb_leave(LBS_DEB_CMD);
}

int lbs_enter_auto_deep_sleep(struct lbs_private *priv)
{
	lbs_deb_enter(LBS_DEB_SDIO);

	priv->is_auto_deep_sleep_enabled = 1;
	if (priv->is_deep_sleep)
		priv->wakeup_dev_required = 1;
	mod_timer(&priv->auto_deepsleep_timer ,
			jiffies + (priv->auto_deep_sleep_timeout * HZ)/1000);

	lbs_deb_leave(LBS_DEB_SDIO);
	return 0;
}

int lbs_exit_auto_deep_sleep(struct lbs_private *priv)
{
	lbs_deb_enter(LBS_DEB_SDIO);

	priv->is_auto_deep_sleep_enabled = 0;
	priv->auto_deep_sleep_timeout = 0;
	del_timer(&priv->auto_deepsleep_timer);

	lbs_deb_leave(LBS_DEB_SDIO);
	return 0;
}

799
static int lbs_init_adapter(struct lbs_private *priv)
800
{
H
Holger Schurig 已提交
801
	size_t bufsize;
802
	int i, ret = 0;
H
Holger Schurig 已提交
803

804 805
	lbs_deb_enter(LBS_DEB_MAIN);

H
Holger Schurig 已提交
806 807
	/* Allocate buffer to store the BSSID list */
	bufsize = MAX_NETWORK_COUNT * sizeof(struct bss_descriptor);
808 809
	priv->networks = kzalloc(bufsize, GFP_KERNEL);
	if (!priv->networks) {
H
Holger Schurig 已提交
810
		lbs_pr_err("Out of memory allocating beacons\n");
811 812
		ret = -1;
		goto out;
H
Holger Schurig 已提交
813 814
	}

815
	/* Initialize scan result lists */
816 817
	INIT_LIST_HEAD(&priv->network_free_list);
	INIT_LIST_HEAD(&priv->network_list);
818
	for (i = 0; i < MAX_NETWORK_COUNT; i++) {
819 820
		list_add_tail(&priv->networks[i].list,
			      &priv->network_free_list);
821
	}
H
Holger Schurig 已提交
822

823
	memset(priv->current_addr, 0xff, ETH_ALEN);
H
Holger Schurig 已提交
824

825 826 827
	priv->connect_status = LBS_DISCONNECTED;
	priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
	priv->mode = IW_MODE_INFRA;
828
	priv->channel = DEFAULT_AD_HOC_CHANNEL;
829
	priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON;
830
	priv->radio_on = 1;
831
	priv->enablehwauto = 1;
832 833
	priv->psmode = LBS802_11POWERMODECAM;
	priv->psstate = PS_STATE_FULL_POWER;
834 835 836 837
	priv->is_deep_sleep = 0;
	priv->is_auto_deep_sleep_enabled = 0;
	priv->wakeup_dev_required = 0;
	init_waitqueue_head(&priv->ds_awake_q);
838
	priv->authtype_auto = 1;
H
Holger Schurig 已提交
839

840
	mutex_init(&priv->lock);
H
Holger Schurig 已提交
841

H
Holger Schurig 已提交
842
	setup_timer(&priv->command_timer, lbs_cmd_timeout_handler,
843
		(unsigned long)priv);
844 845
	setup_timer(&priv->auto_deepsleep_timer, auto_deepsleep_timer_fn,
			(unsigned long)priv);
H
Holger Schurig 已提交
846

847 848
	INIT_LIST_HEAD(&priv->cmdfreeq);
	INIT_LIST_HEAD(&priv->cmdpendingq);
H
Holger Schurig 已提交
849

850 851
	spin_lock_init(&priv->driver_lock);
	init_waitqueue_head(&priv->cmd_pending);
H
Holger Schurig 已提交
852

853
	/* Allocate the command buffers */
854
	if (lbs_allocate_cmd_buffer(priv)) {
855
		lbs_pr_err("Out of memory allocating command buffers\n");
856 857 858 859 860 861 862
		ret = -ENOMEM;
		goto out;
	}
	priv->resp_idx = 0;
	priv->resp_len[0] = priv->resp_len[1] = 0;

	/* Create the event FIFO */
S
Stefani Seibold 已提交
863
	ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL);
864
	if (ret) {
865 866
		lbs_pr_err("Out of memory allocating event FIFO buffer\n");
		goto out;
867
	}
H
Holger Schurig 已提交
868

869
out:
870 871
	lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);

872 873
	return ret;
}
H
Holger Schurig 已提交
874

875
static void lbs_free_adapter(struct lbs_private *priv)
876
{
877
	lbs_deb_enter(LBS_DEB_MAIN);
H
Holger Schurig 已提交
878

879
	lbs_free_cmd_buffer(priv);
880
	kfifo_free(&priv->event_fifo);
881
	del_timer(&priv->command_timer);
882
	del_timer(&priv->auto_deepsleep_timer);
883 884
	kfree(priv->networks);
	priv->networks = NULL;
885 886

	lbs_deb_leave(LBS_DEB_MAIN);
H
Holger Schurig 已提交
887 888
}

889 890 891 892 893 894 895 896 897 898 899
static const struct net_device_ops lbs_netdev_ops = {
	.ndo_open 		= lbs_dev_open,
	.ndo_stop		= lbs_eth_stop,
	.ndo_start_xmit		= lbs_hard_start_xmit,
	.ndo_set_mac_address	= lbs_set_mac_address,
	.ndo_tx_timeout 	= lbs_tx_timeout,
	.ndo_set_multicast_list = lbs_set_multicast_list,
	.ndo_change_mtu		= eth_change_mtu,
	.ndo_validate_addr	= eth_validate_addr,
};

900 901
/**
 * @brief This function adds the card. it will probe the
902
 * card, allocate the lbs_priv and initialize the device.
903 904
 *
 *  @param card    A pointer to card
905
 *  @return 	   A pointer to struct lbs_private structure
906
 */
907
struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
908
{
909 910
	struct net_device *dev;
	struct wireless_dev *wdev;
911
	struct lbs_private *priv = NULL;
912

913
	lbs_deb_enter(LBS_DEB_MAIN);
914 915

	/* Allocate an Ethernet device and register it */
916 917 918
	wdev = lbs_cfg_alloc(dmdev);
	if (IS_ERR(wdev)) {
		lbs_pr_err("cfg80211 init failed\n");
919
		goto done;
920
	}
921 922 923 924
	/* TODO? */
	wdev->iftype = NL80211_IFTYPE_STATION;
	priv = wdev_priv(wdev);
	priv->wdev = wdev;
925

926
	if (lbs_init_adapter(priv)) {
927
		lbs_pr_err("failed to initialize adapter structure.\n");
928 929 930 931 932 933 934 935
		goto err_wdev;
	}

	//TODO? dev = alloc_netdev_mq(0, "wlan%d", ether_setup, IWM_TX_QUEUES);
	dev = alloc_netdev(0, "wlan%d", ether_setup);
	if (!dev) {
		dev_err(dmdev, "no memory for network device instance\n");
		goto err_adapter;
936 937
	}

938 939 940 941
	dev->ieee80211_ptr = wdev;
	dev->ml_priv = priv;
	SET_NETDEV_DEV(dev, dmdev);
	wdev->netdev = dev;
942
	priv->dev = dev;
943

944
 	dev->netdev_ops = &lbs_netdev_ops;
945
	dev->watchdog_timeo = 5 * HZ;
946
	dev->ethtool_ops = &lbs_ethtool_ops;
947
#ifdef	WIRELESS_EXT
948
	dev->wireless_handlers = &lbs_handler_def;
949 950 951
#endif
	dev->flags |= IFF_BROADCAST | IFF_MULTICAST;

952 953 954 955 956 957 958

	// TODO: kzalloc + iwm_init_default_profile(iwm, iwm->umac_profile); ??


	priv->card = card;
	priv->infra_open = 0;

959

960
	priv->rtap_net_dev = NULL;
961
	strcpy(dev->name, "wlan%d");
962 963 964

	lbs_deb_thread("Starting main thread...\n");
	init_waitqueue_head(&priv->waitq);
965
	priv->main_thread = kthread_run(lbs_thread, dev, "lbs_main");
966 967
	if (IS_ERR(priv->main_thread)) {
		lbs_deb_thread("Error creating main thread.\n");
968
		goto err_ndev;
969 970
	}

971 972 973
	priv->work_thread = create_singlethread_workqueue("lbs_worker");
	INIT_DELAYED_WORK(&priv->assoc_work, lbs_association_worker);
	INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker);
974
	INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker);
975

976 977 978
	priv->wol_criteria = 0xffffffff;
	priv->wol_gpio = 0xff;

979 980
	goto done;

981
 err_ndev:
982
	free_netdev(dev);
983 984 985 986 987 988 989

 err_adapter:
	lbs_free_adapter(priv);

 err_wdev:
	lbs_cfg_free(priv);

990
	priv = NULL;
991

992
done:
993
	lbs_deb_leave_args(LBS_DEB_MAIN, "priv %p", priv);
994 995
	return priv;
}
996
EXPORT_SYMBOL_GPL(lbs_add_card);
997

998

999
void lbs_remove_card(struct lbs_private *priv)
1000
{
1001
	struct net_device *dev = priv->dev;
1002 1003

	lbs_deb_enter(LBS_DEB_MAIN);
1004

1005
	lbs_remove_mesh(priv);
1006
	lbs_remove_rtap(priv);
1007

1008
	dev = priv->dev;
1009

1010 1011
	cancel_delayed_work_sync(&priv->scan_work);
	cancel_delayed_work_sync(&priv->assoc_work);
1012
	cancel_work_sync(&priv->mcast_work);
1013 1014 1015 1016 1017

	/* worker thread destruction blocks on the in-flight command which
	 * should have been cleared already in lbs_stop_card().
	 */
	lbs_deb_main("destroying worker thread\n");
1018
	destroy_workqueue(priv->work_thread);
1019
	lbs_deb_main("done destroying worker thread\n");
1020

1021 1022
	if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
		priv->psmode = LBS802_11POWERMODECAM;
1023
		lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
1024 1025
	}

1026
	lbs_send_disconnect_notification(priv);
1027

1028 1029 1030 1031 1032
	if (priv->is_deep_sleep) {
		priv->is_deep_sleep = 0;
		wake_up_interruptible(&priv->ds_awake_q);
	}

1033
	/* Stop the thread servicing the interrupts */
1034
	priv->surpriseremoved = 1;
1035 1036
	kthread_stop(priv->main_thread);

1037
	lbs_free_adapter(priv);
1038
	lbs_cfg_free(priv);
1039 1040 1041 1042 1043 1044

	priv->dev = NULL;
	free_netdev(dev);

	lbs_deb_leave(LBS_DEB_MAIN);
}
1045
EXPORT_SYMBOL_GPL(lbs_remove_card);
1046 1047


H
Holger Schurig 已提交
1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058
static int lbs_rtap_supported(struct lbs_private *priv)
{
	if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5)
		return 1;

	/* newer firmware use a capability mask */
	return ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) &&
		(priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK));
}


1059
int lbs_start_card(struct lbs_private *priv)
1060 1061 1062 1063 1064 1065 1066
{
	struct net_device *dev = priv->dev;
	int ret = -1;

	lbs_deb_enter(LBS_DEB_MAIN);

	/* poke the firmware */
1067
	ret = lbs_setup_firmware(priv);
1068 1069 1070
	if (ret)
		goto done;

1071 1072
	if (lbs_cfg_register(priv)) {
		lbs_pr_err("cannot register device\n");
1073
		goto done;
1074
	}
1075 1076 1077

	lbs_update_channel(priv);

H
Holger Schurig 已提交
1078 1079
	lbs_init_mesh(priv);

1080 1081 1082 1083
	/*
	 * While rtap isn't related to mesh, only mesh-enabled
	 * firmware implements the rtap functionality via
	 * CMD_802_11_MONITOR_MODE.
1084
	 */
H
Holger Schurig 已提交
1085
	if (lbs_rtap_supported(priv)) {
1086 1087
		if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
			lbs_pr_err("cannot register lbs_rtap attribute\n");
1088
	}
1089

1090
	lbs_debugfs_init_one(priv, dev);
1091

1092 1093
	lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name);

1094
	ret = 0;
1095

1096
done:
1097 1098 1099
	lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
	return ret;
}
1100
EXPORT_SYMBOL_GPL(lbs_start_card);
1101 1102


1103
void lbs_stop_card(struct lbs_private *priv)
1104
{
1105
	struct net_device *dev;
1106 1107 1108 1109 1110
	struct cmd_ctrl_node *cmdnode;
	unsigned long flags;

	lbs_deb_enter(LBS_DEB_MAIN);

1111 1112
	if (!priv)
		goto out;
1113
	dev = priv->dev;
1114

1115 1116
	netif_stop_queue(dev);
	netif_carrier_off(dev);
1117

1118
	lbs_debugfs_remove_one(priv);
H
Holger Schurig 已提交
1119 1120 1121
	lbs_deinit_mesh(priv);

	if (lbs_rtap_supported(priv))
1122
		device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
1123

1124
	/* Delete the timeout of the currently processing command */
1125
	del_timer_sync(&priv->command_timer);
1126
	del_timer_sync(&priv->auto_deepsleep_timer);
1127 1128

	/* Flush pending command nodes */
1129
	spin_lock_irqsave(&priv->driver_lock, flags);
1130
	lbs_deb_main("clearing pending commands\n");
1131
	list_for_each_entry(cmdnode, &priv->cmdpendingq, list) {
1132
		cmdnode->result = -ENOENT;
1133 1134 1135
		cmdnode->cmdwaitqwoken = 1;
		wake_up_interruptible(&cmdnode->cmdwait_q);
	}
1136 1137 1138 1139 1140 1141 1142 1143 1144

	/* Flush the command the card is currently processing */
	if (priv->cur_cmd) {
		lbs_deb_main("clearing current command\n");
		priv->cur_cmd->result = -ENOENT;
		priv->cur_cmd->cmdwaitqwoken = 1;
		wake_up_interruptible(&priv->cur_cmd->cmdwait_q);
	}
	lbs_deb_main("done clearing commands\n");
1145
	spin_unlock_irqrestore(&priv->driver_lock, flags);
1146 1147 1148

	unregister_netdev(dev);

1149
out:
1150
	lbs_deb_leave(LBS_DEB_MAIN);
1151
}
1152
EXPORT_SYMBOL_GPL(lbs_stop_card);
1153

1154

1155 1156 1157 1158 1159 1160 1161 1162 1163 1164
void lbs_queue_event(struct lbs_private *priv, u32 event)
{
	unsigned long flags;

	lbs_deb_enter(LBS_DEB_THREAD);
	spin_lock_irqsave(&priv->driver_lock, flags);

	if (priv->psstate == PS_STATE_SLEEP)
		priv->psstate = PS_STATE_AWAKE;

1165
	kfifo_in(&priv->event_fifo, (unsigned char *) &event, sizeof(u32));
1166 1167 1168 1169 1170 1171 1172 1173 1174

	wake_up_interruptible(&priv->waitq);

	spin_unlock_irqrestore(&priv->driver_lock, flags);
	lbs_deb_leave(LBS_DEB_THREAD);
}
EXPORT_SYMBOL_GPL(lbs_queue_event);

void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx)
1175
{
1176
	lbs_deb_enter(LBS_DEB_THREAD);
1177

1178
	if (priv->psstate == PS_STATE_SLEEP)
1179
		priv->psstate = PS_STATE_AWAKE;
1180 1181 1182 1183 1184

	/* Swap buffers by flipping the response index */
	BUG_ON(resp_idx > 1);
	priv->resp_idx = resp_idx;

1185
	wake_up_interruptible(&priv->waitq);
1186

1187
	lbs_deb_leave(LBS_DEB_THREAD);
1188
}
1189
EXPORT_SYMBOL_GPL(lbs_notify_command_response);
1190

1191
static int __init lbs_init_module(void)
1192
{
1193
	lbs_deb_enter(LBS_DEB_MAIN);
1194 1195 1196 1197
	memset(&confirm_sleep, 0, sizeof(confirm_sleep));
	confirm_sleep.hdr.command = cpu_to_le16(CMD_802_11_PS_MODE);
	confirm_sleep.hdr.size = cpu_to_le16(sizeof(confirm_sleep));
	confirm_sleep.action = cpu_to_le16(CMD_SUBCMD_SLEEP_CONFIRMED);
1198
	lbs_debugfs_init();
1199 1200
	lbs_deb_leave(LBS_DEB_MAIN);
	return 0;
1201 1202
}

1203
static void __exit lbs_exit_module(void)
1204
{
1205
	lbs_deb_enter(LBS_DEB_MAIN);
1206
	lbs_debugfs_remove();
1207
	lbs_deb_leave(LBS_DEB_MAIN);
1208 1209
}

1210 1211 1212 1213
/*
 * rtap interface support fuctions
 */

1214
static int lbs_rtap_open(struct net_device *dev)
1215
{
1216
	/* Yes, _stop_ the queue. Because we don't support injection */
1217 1218 1219 1220 1221
	lbs_deb_enter(LBS_DEB_MAIN);
	netif_carrier_off(dev);
	netif_stop_queue(dev);
	lbs_deb_leave(LBS_DEB_LEAVE);
	return 0;
1222 1223
}

1224
static int lbs_rtap_stop(struct net_device *dev)
1225
{
1226 1227 1228
	lbs_deb_enter(LBS_DEB_MAIN);
	lbs_deb_leave(LBS_DEB_MAIN);
	return 0;
1229 1230
}

1231 1232
static netdev_tx_t lbs_rtap_hard_start_xmit(struct sk_buff *skb,
					    struct net_device *dev)
1233
{
1234 1235
	netif_stop_queue(dev);
	return NETDEV_TX_BUSY;
1236 1237
}

1238
static void lbs_remove_rtap(struct lbs_private *priv)
1239
{
1240
	lbs_deb_enter(LBS_DEB_MAIN);
1241
	if (priv->rtap_net_dev == NULL)
1242
		goto out;
1243
	unregister_netdev(priv->rtap_net_dev);
1244
	free_netdev(priv->rtap_net_dev);
1245
	priv->rtap_net_dev = NULL;
1246
out:
1247
	lbs_deb_leave(LBS_DEB_MAIN);
1248 1249
}

1250 1251 1252 1253 1254 1255
static const struct net_device_ops rtap_netdev_ops = {
	.ndo_open = lbs_rtap_open,
	.ndo_stop = lbs_rtap_stop,
	.ndo_start_xmit = lbs_rtap_hard_start_xmit,
};

1256
static int lbs_add_rtap(struct lbs_private *priv)
1257
{
1258
	int ret = 0;
1259
	struct net_device *rtap_dev;
1260

1261 1262 1263 1264 1265
	lbs_deb_enter(LBS_DEB_MAIN);
	if (priv->rtap_net_dev) {
		ret = -EPERM;
		goto out;
	}
1266

1267
	rtap_dev = alloc_netdev(0, "rtap%d", ether_setup);
1268 1269 1270 1271
	if (rtap_dev == NULL) {
		ret = -ENOMEM;
		goto out;
	}
1272

1273
	memcpy(rtap_dev->dev_addr, priv->current_addr, ETH_ALEN);
1274
	rtap_dev->type = ARPHRD_IEEE80211_RADIOTAP;
1275
	rtap_dev->netdev_ops = &rtap_netdev_ops;
1276
	rtap_dev->ml_priv = priv;
1277
	SET_NETDEV_DEV(rtap_dev, priv->dev->dev.parent);
1278

1279 1280
	ret = register_netdev(rtap_dev);
	if (ret) {
1281
		free_netdev(rtap_dev);
1282
		goto out;
1283
	}
1284
	priv->rtap_net_dev = rtap_dev;
1285

1286 1287 1288
out:
	lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
	return ret;
1289 1290
}

1291 1292
module_init(lbs_init_module);
module_exit(lbs_exit_module);
1293

1294
MODULE_DESCRIPTION("Libertas WLAN Driver Library");
1295 1296
MODULE_AUTHOR("Marvell International Ltd.");
MODULE_LICENSE("GPL");