main.c 40.1 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 100 101

/**
 * Attributes exported through sysfs
 */

/**
102
 * @brief Get function for sysfs attribute anycast_mask
103
 */
104
static ssize_t lbs_anycast_get(struct device *dev,
D
Dan Williams 已提交
105 106
		struct device_attribute *attr, char * buf)
{
107
	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
108
	struct cmd_ds_mesh_access mesh_access;
109
	int ret;
110 111

	memset(&mesh_access, 0, sizeof(mesh_access));
112 113 114 115

	ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_ANYCAST, &mesh_access);
	if (ret)
		return ret;
116

117
	return snprintf(buf, 12, "0x%X\n", le32_to_cpu(mesh_access.data[0]));
118 119 120
}

/**
121
 * @brief Set function for sysfs attribute anycast_mask
122
 */
123
static ssize_t lbs_anycast_set(struct device *dev,
D
Dan Williams 已提交
124 125
		struct device_attribute *attr, const char * buf, size_t count)
{
126
	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
127
	struct cmd_ds_mesh_access mesh_access;
128
	uint32_t datum;
129
	int ret;
130 131

	memset(&mesh_access, 0, sizeof(mesh_access));
132
	sscanf(buf, "%x", &datum);
133 134
	mesh_access.data[0] = cpu_to_le32(datum);

135 136 137 138
	ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_ANYCAST, &mesh_access);
	if (ret)
		return ret;

139 140 141
	return strlen(buf);
}

142 143 144 145 146 147
/**
 * @brief Get function for sysfs attribute prb_rsp_limit
 */
static ssize_t lbs_prb_rsp_limit_get(struct device *dev,
		struct device_attribute *attr, char *buf)
{
148
	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
	struct cmd_ds_mesh_access mesh_access;
	int ret;
	u32 retry_limit;

	memset(&mesh_access, 0, sizeof(mesh_access));
	mesh_access.data[0] = cpu_to_le32(CMD_ACT_GET);

	ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
			&mesh_access);
	if (ret)
		return ret;

	retry_limit = le32_to_cpu(mesh_access.data[1]);
	return snprintf(buf, 10, "%d\n", retry_limit);
}

/**
 * @brief Set function for sysfs attribute prb_rsp_limit
 */
static ssize_t lbs_prb_rsp_limit_set(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
171
	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
	struct cmd_ds_mesh_access mesh_access;
	int ret;
	unsigned long retry_limit;

	memset(&mesh_access, 0, sizeof(mesh_access));
	mesh_access.data[0] = cpu_to_le32(CMD_ACT_SET);

	if (!strict_strtoul(buf, 10, &retry_limit))
		return -ENOTSUPP;
	if (retry_limit > 15)
		return -ENOTSUPP;

	mesh_access.data[1] = cpu_to_le32(retry_limit);

	ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
			&mesh_access);
	if (ret)
		return ret;

	return strlen(buf);
}

194 195
static int lbs_add_rtap(struct lbs_private *priv);
static void lbs_remove_rtap(struct lbs_private *priv);
196 197
static int lbs_add_mesh(struct lbs_private *priv);
static void lbs_remove_mesh(struct lbs_private *priv);
198

199 200 201 202

/**
 * Get function for sysfs attribute rtap
 */
203
static ssize_t lbs_rtap_get(struct device *dev,
204 205
		struct device_attribute *attr, char * buf)
{
206
	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
207
	return snprintf(buf, 5, "0x%X\n", priv->monitormode);
208 209 210 211 212
}

/**
 *  Set function for sysfs attribute rtap
 */
213
static ssize_t lbs_rtap_set(struct device *dev,
214 215 216
		struct device_attribute *attr, const char * buf, size_t count)
{
	int monitor_mode;
217
	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
218 219

	sscanf(buf, "%x", &monitor_mode);
220 221
	if (monitor_mode) {
		if (priv->monitormode == monitor_mode)
222
			return strlen(buf);
223
		if (!priv->monitormode) {
224 225
			if (priv->infra_open || priv->mesh_open)
				return -EBUSY;
226
			if (priv->mode == IW_MODE_INFRA)
227 228 229
				lbs_cmd_80211_deauthenticate(priv,
							     priv->curbssparams.bssid,
							     WLAN_REASON_DEAUTH_LEAVING);
230
			else if (priv->mode == IW_MODE_ADHOC)
231
				lbs_adhoc_stop(priv);
232
			lbs_add_rtap(priv);
233
		}
234
		priv->monitormode = monitor_mode;
235
	} else {
236
		if (!priv->monitormode)
237
			return strlen(buf);
238
		priv->monitormode = 0;
239
		lbs_remove_rtap(priv);
D
David Woodhouse 已提交
240

241 242 243
		if (priv->currenttxskb) {
			dev_kfree_skb_any(priv->currenttxskb);
			priv->currenttxskb = NULL;
D
David Woodhouse 已提交
244 245 246 247
		}

		/* Wake queues, command thread, etc. */
		lbs_host_to_card_done(priv);
248 249
	}

250
	lbs_prepare_and_send_command(priv,
251
			CMD_802_11_MONITOR_MODE, CMD_ACT_SET,
252
			CMD_OPTION_WAITFORRSP, 0, &priv->monitormode);
253 254 255 256
	return strlen(buf);
}

/**
257 258
 * lbs_rtap attribute to be exported per ethX interface
 * through sysfs (/sys/class/net/ethX/lbs_rtap)
259
 */
260 261 262 263 264 265 266 267
static DEVICE_ATTR(lbs_rtap, 0644, lbs_rtap_get, lbs_rtap_set );

/**
 * Get function for sysfs attribute mesh
 */
static ssize_t lbs_mesh_get(struct device *dev,
		struct device_attribute *attr, char * buf)
{
268
	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
269 270 271 272 273 274 275 276 277
	return snprintf(buf, 5, "0x%X\n", !!priv->mesh_dev);
}

/**
 *  Set function for sysfs attribute mesh
 */
static ssize_t lbs_mesh_set(struct device *dev,
		struct device_attribute *attr, const char * buf, size_t count)
{
278
	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
279
	int enable;
280
	int ret, action = CMD_ACT_MESH_CONFIG_STOP;
281 282 283 284 285

	sscanf(buf, "%x", &enable);
	enable = !!enable;
	if (enable == !!priv->mesh_dev)
		return count;
286 287
	if (enable)
		action = CMD_ACT_MESH_CONFIG_START;
288
	ret = lbs_mesh_config(priv, action, priv->channel);
289 290
	if (ret)
		return ret;
291

292 293 294 295 296 297 298 299 300 301 302 303 304
	if (enable)
		lbs_add_mesh(priv);
	else
		lbs_remove_mesh(priv);

	return count;
}

/**
 * lbs_mesh attribute to be exported per ethX interface
 * through sysfs (/sys/class/net/ethX/lbs_mesh)
 */
static DEVICE_ATTR(lbs_mesh, 0644, lbs_mesh_get, lbs_mesh_set);
305

306
/**
307 308
 * anycast_mask attribute to be exported per mshX interface
 * through sysfs (/sys/class/net/mshX/anycast_mask)
309
 */
310
static DEVICE_ATTR(anycast_mask, 0644, lbs_anycast_get, lbs_anycast_set);
311

312 313 314 315 316 317 318
/**
 * prb_rsp_limit attribute to be exported per mshX interface
 * through sysfs (/sys/class/net/mshX/prb_rsp_limit)
 */
static DEVICE_ATTR(prb_rsp_limit, 0644, lbs_prb_rsp_limit_get,
		lbs_prb_rsp_limit_set);

319
static struct attribute *lbs_mesh_sysfs_entries[] = {
320
	&dev_attr_anycast_mask.attr,
321
	&dev_attr_prb_rsp_limit.attr,
322 323 324
	NULL,
};

325 326
static struct attribute_group lbs_mesh_attr_group = {
	.attrs = lbs_mesh_sysfs_entries,
327 328
};

329
/**
330
 *  @brief This function opens the ethX or mshX interface
331 332
 *
 *  @param dev     A pointer to net_device structure
333
 *  @return 	   0 or -EBUSY if monitor mode active
334
 */
335
static int lbs_dev_open(struct net_device *dev)
336
{
337
	struct lbs_private *priv = dev->ml_priv;
338
	int ret = 0;
339

340 341
	lbs_deb_enter(LBS_DEB_NET);

342
	spin_lock_irq(&priv->driver_lock);
343

344
	if (priv->monitormode) {
345 346 347
		ret = -EBUSY;
		goto out;
	}
348

349 350 351 352 353 354
	if (dev == priv->mesh_dev) {
		priv->mesh_open = 1;
		priv->mesh_connect_status = LBS_CONNECTED;
		netif_carrier_on(dev);
	} else {
		priv->infra_open = 1;
355

356 357
		if (priv->connect_status == LBS_CONNECTED)
			netif_carrier_on(dev);
358
		else
359
			netif_carrier_off(dev);
360
	}
361

362 363 364
	if (!priv->tx_pending_len)
		netif_wake_queue(dev);
 out:
365

366
	spin_unlock_irq(&priv->driver_lock);
367
	lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
368
	return ret;
369 370 371 372 373 374 375 376
}

/**
 *  @brief This function closes the mshX interface
 *
 *  @param dev     A pointer to net_device structure
 *  @return 	   0
 */
377
static int lbs_mesh_stop(struct net_device *dev)
378
{
379
	struct lbs_private *priv = dev->ml_priv;
380

381
	lbs_deb_enter(LBS_DEB_MESH);
382 383
	spin_lock_irq(&priv->driver_lock);

384
	priv->mesh_open = 0;
385 386 387 388
	priv->mesh_connect_status = LBS_DISCONNECTED;

	netif_stop_queue(dev);
	netif_carrier_off(dev);
389

390
	spin_unlock_irq(&priv->driver_lock);
391

392 393
	schedule_work(&priv->mcast_work);

394
	lbs_deb_leave(LBS_DEB_MESH);
395
	return 0;
396 397 398 399 400 401 402 403
}

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

408
	lbs_deb_enter(LBS_DEB_NET);
409

410
	spin_lock_irq(&priv->driver_lock);
411
	priv->infra_open = 0;
412 413
	netif_stop_queue(dev);
	spin_unlock_irq(&priv->driver_lock);
414

415 416
	schedule_work(&priv->mcast_work);

417
	lbs_deb_leave(LBS_DEB_NET);
418
	return 0;
419 420
}

421
static void lbs_tx_timeout(struct net_device *dev)
422
{
423
	struct lbs_private *priv = dev->ml_priv;
424

425
	lbs_deb_enter(LBS_DEB_TX);
426

427
	lbs_pr_err("tx watch dog timeout\n");
428 429 430

	dev->trans_start = jiffies;

431 432 433
	if (priv->currenttxskb)
		lbs_send_tx_feedback(priv, 0);

434 435 436
	/* XX: Shouldn't we also call into the hw-specific driver
	   to kick it somehow? */
	lbs_host_to_card_done(priv);
437

438 439 440 441 442 443 444
	/* 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);

445
	lbs_deb_leave(LBS_DEB_TX);
446 447
}

448 449
void lbs_host_to_card_done(struct lbs_private *priv)
{
450 451
	unsigned long flags;

452 453
	lbs_deb_enter(LBS_DEB_THREAD);

454
	spin_lock_irqsave(&priv->driver_lock, flags);
455 456 457 458

	priv->dnld_sent = DNLD_RES_RECEIVED;

	/* Wake main thread if commands are pending */
459 460 461 462
	if (!priv->cur_cmd || priv->tx_pending_len > 0) {
		if (!priv->wakeup_dev_required)
			wake_up_interruptible(&priv->waitq);
	}
463

464
	spin_unlock_irqrestore(&priv->driver_lock, flags);
465
	lbs_deb_leave(LBS_DEB_THREAD);
466 467 468
}
EXPORT_SYMBOL_GPL(lbs_host_to_card_done);

469
static int lbs_set_mac_address(struct net_device *dev, void *addr)
470 471
{
	int ret = 0;
472
	struct lbs_private *priv = dev->ml_priv;
473
	struct sockaddr *phwaddr = addr;
474
	struct cmd_ds_802_11_mac_address cmd;
475

476
	lbs_deb_enter(LBS_DEB_NET);
477

478
	/* In case it was called from the mesh device */
479
	dev = priv->dev;
480

481 482 483
	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
	cmd.action = cpu_to_le16(CMD_ACT_SET);
	memcpy(cmd.macadd, phwaddr->sa_data, ETH_ALEN);
484

485
	ret = lbs_cmd_with_response(priv, CMD_802_11_MAC_ADDRESS, &cmd);
486
	if (ret) {
487
		lbs_deb_net("set MAC address failed\n");
488 489 490
		goto done;
	}

491 492
	memcpy(priv->current_addr, phwaddr->sa_data, ETH_ALEN);
	memcpy(dev->dev_addr, phwaddr->sa_data, ETH_ALEN);
493
	if (priv->mesh_dev)
494
		memcpy(priv->mesh_dev->dev_addr, phwaddr->sa_data, ETH_ALEN);
495 496

done:
497
	lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
498 499 500
	return ret;
}

501 502 503

static inline int mac_in_list(unsigned char *list, int list_len,
			      unsigned char *mac)
504
{
505 506 507 508 509 510 511 512 513
	while (list_len) {
		if (!memcmp(list, mac, ETH_ALEN))
			return 1;
		list += ETH_ALEN;
		list_len--;
	}
	return 0;
}

514

515 516 517 518 519 520 521 522 523
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;

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

524
	netif_addr_lock_bh(dev);
525 526
	for (mc_list = dev->mc_list; mc_list; mc_list = mc_list->next) {
		if (mac_in_list(cmd->maclist, nr_addrs, mc_list->dmi_addr)) {
J
Johannes Berg 已提交
527 528
			lbs_deb_net("mcast address %s:%pM skipped\n", dev->name,
				    mc_list->dmi_addr);
529 530
			continue;
		}
531

532 533 534
		if (i == MRVDRV_MAX_MULTICAST_LIST_SIZE)
			break;
		memcpy(&cmd->maclist[6*i], mc_list->dmi_addr, ETH_ALEN);
J
Johannes Berg 已提交
535 536
		lbs_deb_net("mcast address %s:%pM added to filter\n", dev->name,
			    mc_list->dmi_addr);
537
		i++;
538
	}
539
	netif_addr_unlock_bh(dev);
540 541 542
	if (mc_list)
		return -EOVERFLOW;

543 544 545
	return i;
}

546
static void lbs_set_mcast_worker(struct work_struct *work)
547
{
548 549 550 551 552
	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;
553

554
	lbs_deb_enter(LBS_DEB_NET);
555

556 557 558 559 560 561 562 563 564 565 566 567 568 569 570
	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;
571 572
	}

573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596
	/* 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:
597 598
	if (priv->mac_control != old_mac_control)
		lbs_set_mac_control(priv);
599

600
	lbs_deb_leave(LBS_DEB_NET);
601 602
}

603 604
static void lbs_set_multicast_list(struct net_device *dev)
{
605
	struct lbs_private *priv = dev->ml_priv;
606 607 608 609

	schedule_work(&priv->mcast_work);
}

610
/**
611
 *  @brief This function handles the major jobs in the LBS driver.
612 613
 *  It handles all events generated by firmware, RX data received
 *  from firmware and TX data sent from kernel.
614
 *
615
 *  @param data    A pointer to lbs_thread structure
616 617
 *  @return 	   0
 */
618
static int lbs_thread(void *data)
619
{
620
	struct net_device *dev = data;
621
	struct lbs_private *priv = dev->ml_priv;
622 623
	wait_queue_t wait;

624
	lbs_deb_enter(LBS_DEB_THREAD);
625 626 627 628

	init_waitqueue_entry(&wait, current);

	for (;;) {
629
		int shouldsleep;
630
		u8 resp_idx;
631

632 633
		lbs_deb_thread("1: currenttxskb %p, dnld_sent %d\n",
				priv->currenttxskb, priv->dnld_sent);
634

635
		add_wait_queue(&priv->waitq, &wait);
636
		set_current_state(TASK_INTERRUPTIBLE);
637
		spin_lock_irq(&priv->driver_lock);
638

639
		if (kthread_should_stop())
640
			shouldsleep = 0;	/* Bye */
641 642
		else if (priv->surpriseremoved)
			shouldsleep = 1;	/* We need to wait until we're _told_ to die */
643 644
		else if (priv->psstate == PS_STATE_SLEEP)
			shouldsleep = 1;	/* Sleep mode. Nothing we can do till it wakes */
645 646
		else if (priv->cmd_timed_out)
			shouldsleep = 0;	/* Command timed out. Recover */
647 648
		else if (!priv->fw_ready)
			shouldsleep = 1;	/* Firmware not ready. We're waiting for it */
649 650
		else if (priv->dnld_sent)
			shouldsleep = 1;	/* Something is en route to the device already */
651 652
		else if (priv->tx_pending_len > 0)
			shouldsleep = 0;	/* We've a packet to send */
653 654
		else if (priv->resp_len[priv->resp_idx])
			shouldsleep = 0;	/* We have a command response */
655 656
		else if (priv->cur_cmd)
			shouldsleep = 1;	/* Can't send a command; one already running */
657 658
		else if (!list_empty(&priv->cmdpendingq) &&
					!(priv->wakeup_dev_required))
659
			shouldsleep = 0;	/* We have a command to send */
660 661
		else if (__kfifo_len(priv->event_fifo))
			shouldsleep = 0;	/* We have an event to process */
662 663 664 665
		else
			shouldsleep = 1;	/* No command */

		if (shouldsleep) {
666
			lbs_deb_thread("sleeping, connect_status %d, "
667
				"psmode %d, psstate %d\n",
668 669
				priv->connect_status,
				priv->psmode, priv->psstate);
670
			spin_unlock_irq(&priv->driver_lock);
671 672
			schedule();
		} else
673
			spin_unlock_irq(&priv->driver_lock);
674

675 676
		lbs_deb_thread("2: currenttxskb %p, dnld_send %d\n",
			       priv->currenttxskb, priv->dnld_sent);
677 678

		set_current_state(TASK_RUNNING);
679
		remove_wait_queue(&priv->waitq, &wait);
680

681 682
		lbs_deb_thread("3: currenttxskb %p, dnld_sent %d\n",
			       priv->currenttxskb, priv->dnld_sent);
683

684
		if (kthread_should_stop()) {
685
			lbs_deb_thread("break from main thread\n");
686 687 688
			break;
		}

689 690 691 692
		if (priv->surpriseremoved) {
			lbs_deb_thread("adapter removed; waiting to die...\n");
			continue;
		}
693

694 695
		lbs_deb_thread("4: currenttxskb %p, dnld_sent %d\n",
		       priv->currenttxskb, priv->dnld_sent);
696

697
		/* Process any pending command response */
698
		spin_lock_irq(&priv->driver_lock);
699 700
		resp_idx = priv->resp_idx;
		if (priv->resp_len[resp_idx]) {
701
			spin_unlock_irq(&priv->driver_lock);
702 703 704
			lbs_process_command_response(priv,
				priv->resp_buf[resp_idx],
				priv->resp_len[resp_idx]);
705
			spin_lock_irq(&priv->driver_lock);
706
			priv->resp_len[resp_idx] = 0;
707
		}
708
		spin_unlock_irq(&priv->driver_lock);
709

710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729
		/* Process hardware events, e.g. card removed, link lost */
		spin_lock_irq(&priv->driver_lock);
		while (__kfifo_len(priv->event_fifo)) {
			u32 event;
			__kfifo_get(priv->event_fifo, (unsigned char *) &event,
				sizeof(event));
			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;
		}

730
		/* command timeout stuff */
731 732 733
		if (priv->cmd_timed_out && priv->cur_cmd) {
			struct cmd_ctrl_node *cmdnode = priv->cur_cmd;

734 735 736 737
			if (++priv->nr_retries > 3) {
				lbs_pr_info("Excessive timeouts submitting "
					"command 0x%04x\n",
					le16_to_cpu(cmdnode->cmdbuf->command));
738 739
				lbs_complete_command(priv, cmdnode, -ETIMEDOUT);
				priv->nr_retries = 0;
740
				if (priv->reset_card)
741
					priv->reset_card(priv);
742 743
			} else {
				priv->cur_cmd = NULL;
744
				priv->dnld_sent = DNLD_RES_RECEIVED;
745 746 747 748
				lbs_pr_info("requeueing command 0x%04x due "
					"to timeout (#%d)\n",
					le16_to_cpu(cmdnode->cmdbuf->command),
					priv->nr_retries);
749 750 751 752 753 754 755 756

				/* Stick it back at the _top_ of the pending queue
				   for immediate resubmission */
				list_add(&cmdnode->list, &priv->cmdpendingq);
			}
		}
		priv->cmd_timed_out = 0;

757 758


759 760 761
		if (!priv->fw_ready)
			continue;

762
		/* Check if we need to confirm Sleep Request received previously */
763 764 765
		if (priv->psstate == PS_STATE_PRE_SLEEP &&
		    !priv->dnld_sent && !priv->cur_cmd) {
			if (priv->connect_status == LBS_CONNECTED) {
766 767 768 769
				lbs_deb_thread("pre-sleep, currenttxskb %p, "
					"dnld_sent %d, cur_cmd %p\n",
					priv->currenttxskb, priv->dnld_sent,
					priv->cur_cmd);
770

771
				lbs_ps_confirm_sleep(priv);
772 773 774 775 776 777
			} else {
				/* workaround for firmware sending
				 * deauth/linkloss event immediately
				 * after sleep request; remove this
				 * after firmware fixes it
				 */
778
				priv->psstate = PS_STATE_AWAKE;
779 780
				lbs_pr_alert("ignore PS_SleepConfirm in "
					"non-connected state\n");
781 782 783 784 785 786
			}
		}

		/* The PS state is changed during processing of Sleep Request
		 * event above
		 */
787 788
		if ((priv->psstate == PS_STATE_SLEEP) ||
		    (priv->psstate == PS_STATE_PRE_SLEEP))
789 790
			continue;

791 792 793
		if (priv->is_deep_sleep)
			continue;

794
		/* Execute the next command */
795
		if (!priv->dnld_sent && !priv->cur_cmd)
796
			lbs_execute_next_command(priv);
797 798

		/* Wake-up command waiters which can't sleep in
799
		 * lbs_prepare_and_send_command
800
		 */
801 802
		if (!list_empty(&priv->cmdpendingq))
			wake_up_all(&priv->cmd_pending);
803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824

		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 &&
				    priv->mesh_connect_status == LBS_CONNECTED)
					netif_wake_queue(priv->mesh_dev);
			}
		}
		spin_unlock_irq(&priv->driver_lock);
825 826
	}

827
	del_timer(&priv->command_timer);
828
	del_timer(&priv->auto_deepsleep_timer);
829
	wake_up_all(&priv->cmd_pending);
830

831
	lbs_deb_leave(LBS_DEB_THREAD);
832 833 834
	return 0;
}

835 836 837
static int lbs_suspend_callback(struct lbs_private *priv, unsigned long dummy,
				struct cmd_header *cmd)
{
838
	lbs_deb_enter(LBS_DEB_FW);
839 840 841 842 843 844

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

	priv->fw_ready = 0;
845
	lbs_deb_leave(LBS_DEB_FW);
846 847 848 849 850 851 852 853
	return 0;
}

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

854 855
	lbs_deb_enter(LBS_DEB_FW);

856 857 858 859 860
	if (priv->wol_criteria == 0xffffffff) {
		lbs_pr_info("Suspend attempt without configuring wake params!\n");
		return -EINVAL;
	}

861
	memset(&cmd, 0, sizeof(cmd));
862

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

868
	lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
869 870 871 872
	return ret;
}
EXPORT_SYMBOL_GPL(lbs_suspend);

873
void lbs_resume(struct lbs_private *priv)
874
{
875 876
	lbs_deb_enter(LBS_DEB_FW);

877 878 879 880 881 882 883 884 885 886 887
	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);

888
	lbs_deb_leave(LBS_DEB_FW);
889 890 891
}
EXPORT_SYMBOL_GPL(lbs_resume);

H
Holger Schurig 已提交
892
/**
893 894
 * @brief This function gets the HW spec from the firmware and sets
 *        some basic parameters.
H
Holger Schurig 已提交
895
 *
896
 *  @param priv    A pointer to struct lbs_private structure
H
Holger Schurig 已提交
897 898
 *  @return 	   0 or -1
 */
899
static int lbs_setup_firmware(struct lbs_private *priv)
H
Holger Schurig 已提交
900 901
{
	int ret = -1;
902
	s16 curlevel = 0, minlevel = 0, maxlevel = 0;
H
Holger Schurig 已提交
903 904 905

	lbs_deb_enter(LBS_DEB_FW);

906
	/* Read MAC address from firmware */
907
	memset(priv->current_addr, 0xff, ETH_ALEN);
908
	ret = lbs_update_hw_spec(priv);
909
	if (ret)
H
Holger Schurig 已提交
910 911
		goto done;

912 913 914 915 916 917 918 919
	/* 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;
	}

920
	lbs_set_mac_control(priv);
H
Holger Schurig 已提交
921 922 923 924 925 926 927 928 929 930 931
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.
 */
static void command_timer_fn(unsigned long data)
{
932
	struct lbs_private *priv = (struct lbs_private *)data;
H
Holger Schurig 已提交
933 934
	unsigned long flags;

935
	lbs_deb_enter(LBS_DEB_CMD);
936
	spin_lock_irqsave(&priv->driver_lock, flags);
H
Holger Schurig 已提交
937

938
	if (!priv->cur_cmd)
939
		goto out;
H
Holger Schurig 已提交
940

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

944
	priv->cmd_timed_out = 1;
H
Holger Schurig 已提交
945
	wake_up_interruptible(&priv->waitq);
946
out:
947
	spin_unlock_irqrestore(&priv->driver_lock, flags);
948
	lbs_deb_leave(LBS_DEB_CMD);
H
Holger Schurig 已提交
949 950
}

951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971
/**
 *  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);
972 973
			if (ret)
				lbs_pr_err("Enter Deep Sleep command failed\n");
974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006
		}
	}
	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;
}

1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018
static void lbs_sync_channel_worker(struct work_struct *work)
{
	struct lbs_private *priv = container_of(work, struct lbs_private,
		sync_channel);

	lbs_deb_enter(LBS_DEB_MAIN);
	if (lbs_update_channel(priv))
		lbs_pr_info("Channel synchronization failed.");
	lbs_deb_leave(LBS_DEB_MAIN);
}


1019
static int lbs_init_adapter(struct lbs_private *priv)
1020
{
H
Holger Schurig 已提交
1021
	size_t bufsize;
1022
	int i, ret = 0;
H
Holger Schurig 已提交
1023

1024 1025
	lbs_deb_enter(LBS_DEB_MAIN);

H
Holger Schurig 已提交
1026 1027
	/* Allocate buffer to store the BSSID list */
	bufsize = MAX_NETWORK_COUNT * sizeof(struct bss_descriptor);
1028 1029
	priv->networks = kzalloc(bufsize, GFP_KERNEL);
	if (!priv->networks) {
H
Holger Schurig 已提交
1030
		lbs_pr_err("Out of memory allocating beacons\n");
1031 1032
		ret = -1;
		goto out;
H
Holger Schurig 已提交
1033 1034
	}

1035
	/* Initialize scan result lists */
1036 1037
	INIT_LIST_HEAD(&priv->network_free_list);
	INIT_LIST_HEAD(&priv->network_list);
1038
	for (i = 0; i < MAX_NETWORK_COUNT; i++) {
1039 1040
		list_add_tail(&priv->networks[i].list,
			      &priv->network_free_list);
1041
	}
H
Holger Schurig 已提交
1042

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

1045 1046 1047 1048
	priv->connect_status = LBS_DISCONNECTED;
	priv->mesh_connect_status = LBS_DISCONNECTED;
	priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
	priv->mode = IW_MODE_INFRA;
1049
	priv->channel = DEFAULT_AD_HOC_CHANNEL;
1050
	priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON;
1051
	priv->radio_on = 1;
1052
	priv->enablehwauto = 1;
1053 1054 1055
	priv->capability = WLAN_CAPABILITY_SHORT_PREAMBLE;
	priv->psmode = LBS802_11POWERMODECAM;
	priv->psstate = PS_STATE_FULL_POWER;
1056 1057 1058 1059
	priv->is_deep_sleep = 0;
	priv->is_auto_deep_sleep_enabled = 0;
	priv->wakeup_dev_required = 0;
	init_waitqueue_head(&priv->ds_awake_q);
H
Holger Schurig 已提交
1060

1061
	mutex_init(&priv->lock);
H
Holger Schurig 已提交
1062

1063
	setup_timer(&priv->command_timer, command_timer_fn,
1064
		(unsigned long)priv);
1065 1066
	setup_timer(&priv->auto_deepsleep_timer, auto_deepsleep_timer_fn,
			(unsigned long)priv);
H
Holger Schurig 已提交
1067

1068 1069
	INIT_LIST_HEAD(&priv->cmdfreeq);
	INIT_LIST_HEAD(&priv->cmdpendingq);
H
Holger Schurig 已提交
1070

1071 1072
	spin_lock_init(&priv->driver_lock);
	init_waitqueue_head(&priv->cmd_pending);
H
Holger Schurig 已提交
1073

1074
	/* Allocate the command buffers */
1075
	if (lbs_allocate_cmd_buffer(priv)) {
1076
		lbs_pr_err("Out of memory allocating command buffers\n");
1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088
		ret = -ENOMEM;
		goto out;
	}
	priv->resp_idx = 0;
	priv->resp_len[0] = priv->resp_len[1] = 0;

	/* Create the event FIFO */
	priv->event_fifo = kfifo_alloc(sizeof(u32) * 16, GFP_KERNEL, NULL);
	if (IS_ERR(priv->event_fifo)) {
		lbs_pr_err("Out of memory allocating event FIFO buffer\n");
		ret = -ENOMEM;
		goto out;
1089
	}
H
Holger Schurig 已提交
1090

1091
out:
1092 1093
	lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);

1094 1095
	return ret;
}
H
Holger Schurig 已提交
1096

1097
static void lbs_free_adapter(struct lbs_private *priv)
1098
{
1099
	lbs_deb_enter(LBS_DEB_MAIN);
H
Holger Schurig 已提交
1100

1101
	lbs_free_cmd_buffer(priv);
1102 1103
	if (priv->event_fifo)
		kfifo_free(priv->event_fifo);
1104
	del_timer(&priv->command_timer);
1105
	del_timer(&priv->auto_deepsleep_timer);
1106 1107
	kfree(priv->networks);
	priv->networks = NULL;
1108 1109

	lbs_deb_leave(LBS_DEB_MAIN);
H
Holger Schurig 已提交
1110 1111
}

1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122
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,
};

1123 1124
/**
 * @brief This function adds the card. it will probe the
1125
 * card, allocate the lbs_priv and initialize the device.
1126 1127
 *
 *  @param card    A pointer to card
1128
 *  @return 	   A pointer to struct lbs_private structure
1129
 */
1130
struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
1131
{
1132 1133
	struct net_device *dev;
	struct wireless_dev *wdev;
1134
	struct lbs_private *priv = NULL;
1135

1136
	lbs_deb_enter(LBS_DEB_MAIN);
1137 1138

	/* Allocate an Ethernet device and register it */
1139 1140 1141
	wdev = lbs_cfg_alloc(dmdev);
	if (IS_ERR(wdev)) {
		lbs_pr_err("cfg80211 init failed\n");
1142
		goto done;
1143
	}
1144 1145 1146 1147
	/* TODO? */
	wdev->iftype = NL80211_IFTYPE_STATION;
	priv = wdev_priv(wdev);
	priv->wdev = wdev;
1148

1149
	if (lbs_init_adapter(priv)) {
1150
		lbs_pr_err("failed to initialize adapter structure.\n");
1151 1152 1153 1154 1155 1156 1157 1158
		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;
1159 1160
	}

1161 1162 1163 1164
	dev->ieee80211_ptr = wdev;
	dev->ml_priv = priv;
	SET_NETDEV_DEV(dev, dmdev);
	wdev->netdev = dev;
1165
	priv->dev = dev;
1166

1167
 	dev->netdev_ops = &lbs_netdev_ops;
1168
	dev->watchdog_timeo = 5 * HZ;
1169
	dev->ethtool_ops = &lbs_ethtool_ops;
1170
#ifdef	WIRELESS_EXT
1171
	dev->wireless_handlers = &lbs_handler_def;
1172 1173 1174
#endif
	dev->flags |= IFF_BROADCAST | IFF_MULTICAST;

1175 1176 1177 1178 1179 1180 1181 1182

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


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

1183

1184
	priv->rtap_net_dev = NULL;
1185
	strcpy(dev->name, "wlan%d");
1186 1187 1188

	lbs_deb_thread("Starting main thread...\n");
	init_waitqueue_head(&priv->waitq);
1189
	priv->main_thread = kthread_run(lbs_thread, dev, "lbs_main");
1190 1191
	if (IS_ERR(priv->main_thread)) {
		lbs_deb_thread("Error creating main thread.\n");
1192
		goto err_ndev;
1193 1194
	}

1195 1196 1197
	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);
1198
	INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker);
1199
	INIT_WORK(&priv->sync_channel, lbs_sync_channel_worker);
1200

1201 1202 1203
	sprintf(priv->mesh_ssid, "mesh");
	priv->mesh_ssid_len = 4;

1204 1205 1206
	priv->wol_criteria = 0xffffffff;
	priv->wol_gpio = 0xff;

1207 1208
	goto done;

1209
 err_ndev:
1210
	free_netdev(dev);
1211 1212 1213 1214 1215 1216 1217

 err_adapter:
	lbs_free_adapter(priv);

 err_wdev:
	lbs_cfg_free(priv);

1218
	priv = NULL;
1219

1220
done:
1221
	lbs_deb_leave_args(LBS_DEB_MAIN, "priv %p", priv);
1222 1223
	return priv;
}
1224
EXPORT_SYMBOL_GPL(lbs_add_card);
1225

1226

1227
void lbs_remove_card(struct lbs_private *priv)
1228
{
1229
	struct net_device *dev = priv->dev;
1230 1231

	lbs_deb_enter(LBS_DEB_MAIN);
1232

1233
	lbs_remove_mesh(priv);
1234
	lbs_remove_rtap(priv);
1235

1236
	dev = priv->dev;
1237

1238 1239
	cancel_delayed_work_sync(&priv->scan_work);
	cancel_delayed_work_sync(&priv->assoc_work);
1240
	cancel_work_sync(&priv->mcast_work);
1241 1242 1243 1244 1245

	/* 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");
1246
	destroy_workqueue(priv->work_thread);
1247
	lbs_deb_main("done destroying worker thread\n");
1248

1249 1250
	if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
		priv->psmode = LBS802_11POWERMODECAM;
1251
		lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
1252 1253
	}

1254
	lbs_send_disconnect_notification(priv);
1255

1256 1257 1258 1259 1260
	if (priv->is_deep_sleep) {
		priv->is_deep_sleep = 0;
		wake_up_interruptible(&priv->ds_awake_q);
	}

1261
	/* Stop the thread servicing the interrupts */
1262
	priv->surpriseremoved = 1;
1263 1264
	kthread_stop(priv->main_thread);

1265
	lbs_free_adapter(priv);
1266
	lbs_cfg_free(priv);
1267 1268 1269 1270 1271 1272

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

	lbs_deb_leave(LBS_DEB_MAIN);
}
1273
EXPORT_SYMBOL_GPL(lbs_remove_card);
1274 1275


1276
int lbs_start_card(struct lbs_private *priv)
1277 1278 1279 1280 1281 1282 1283
{
	struct net_device *dev = priv->dev;
	int ret = -1;

	lbs_deb_enter(LBS_DEB_MAIN);

	/* poke the firmware */
1284
	ret = lbs_setup_firmware(priv);
1285 1286 1287
	if (ret)
		goto done;

1288 1289
	if (lbs_cfg_register(priv)) {
		lbs_pr_err("cannot register device\n");
1290
		goto done;
1291
	}
1292 1293 1294

	lbs_update_channel(priv);

1295 1296 1297 1298
	/* Check mesh FW version and appropriately send the mesh start
	 * command
	 */
	if (priv->mesh_fw_ver == MESH_FW_OLD) {
1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311
		/* Enable mesh, if supported, and work out which TLV it uses.
		   0x100 + 291 is an unofficial value used in 5.110.20.pXX
		   0x100 + 37 is the official value used in 5.110.21.pXX
		   but we check them in that order because 20.pXX doesn't
		   give an error -- it just silently fails. */

		/* 5.110.20.pXX firmware will fail the command if the channel
		   doesn't match the existing channel. But only if the TLV
		   is correct. If the channel is wrong, _BOTH_ versions will
		   give an error to 0x100+291, and allow 0x100+37 to succeed.
		   It's just that 5.110.20.pXX will not have done anything
		   useful */

1312
		priv->mesh_tlv = TLV_TYPE_OLD_MESH_ID;
1313
		if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
1314
				    priv->channel)) {
1315
			priv->mesh_tlv = TLV_TYPE_MESH_ID;
1316
			if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
1317
					    priv->channel))
1318 1319
				priv->mesh_tlv = 0;
		}
1320 1321 1322 1323 1324 1325
	} else if (priv->mesh_fw_ver == MESH_FW_NEW) {
		/* 10.0.0.pXX new firmwares should succeed with TLV
		 * 0x100+37; Do not invoke command with old TLV.
		 */
		priv->mesh_tlv = TLV_TYPE_MESH_ID;
		if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
1326
				    priv->channel))
1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340
			priv->mesh_tlv = 0;
	}
	if (priv->mesh_tlv) {
		lbs_add_mesh(priv);

		if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
			lbs_pr_err("cannot register lbs_mesh attribute\n");

		/* While rtap isn't related to mesh, only mesh-enabled
		 * firmware implements the rtap functionality via
		 * CMD_802_11_MONITOR_MODE.
		 */
		if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
			lbs_pr_err("cannot register lbs_rtap attribute\n");
1341
	}
1342

1343
	lbs_debugfs_init_one(priv, dev);
1344

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

1347
	ret = 0;
1348

1349
done:
1350 1351 1352
	lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
	return ret;
}
1353
EXPORT_SYMBOL_GPL(lbs_start_card);
1354 1355


1356
void lbs_stop_card(struct lbs_private *priv)
1357
{
1358
	struct net_device *dev;
1359 1360 1361 1362 1363
	struct cmd_ctrl_node *cmdnode;
	unsigned long flags;

	lbs_deb_enter(LBS_DEB_MAIN);

1364 1365
	if (!priv)
		goto out;
1366
	dev = priv->dev;
1367

1368 1369
	netif_stop_queue(dev);
	netif_carrier_off(dev);
1370

1371
	lbs_debugfs_remove_one(priv);
1372
	if (priv->mesh_tlv) {
1373
		device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
1374
		device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
1375
	}
1376

1377
	/* Delete the timeout of the currently processing command */
1378
	del_timer_sync(&priv->command_timer);
1379
	del_timer_sync(&priv->auto_deepsleep_timer);
1380 1381

	/* Flush pending command nodes */
1382
	spin_lock_irqsave(&priv->driver_lock, flags);
1383
	lbs_deb_main("clearing pending commands\n");
1384
	list_for_each_entry(cmdnode, &priv->cmdpendingq, list) {
1385
		cmdnode->result = -ENOENT;
1386 1387 1388
		cmdnode->cmdwaitqwoken = 1;
		wake_up_interruptible(&cmdnode->cmdwait_q);
	}
1389 1390 1391 1392 1393 1394 1395 1396 1397

	/* 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");
1398
	spin_unlock_irqrestore(&priv->driver_lock, flags);
1399 1400 1401

	unregister_netdev(dev);

1402
out:
1403
	lbs_deb_leave(LBS_DEB_MAIN);
1404
}
1405
EXPORT_SYMBOL_GPL(lbs_stop_card);
1406

1407

1408 1409 1410 1411 1412 1413 1414 1415
static const struct net_device_ops mesh_netdev_ops = {
	.ndo_open		= lbs_dev_open,
	.ndo_stop 		= lbs_mesh_stop,
	.ndo_start_xmit		= lbs_hard_start_xmit,
	.ndo_set_mac_address	= lbs_set_mac_address,
	.ndo_set_multicast_list = lbs_set_multicast_list,
};

1416 1417 1418
/**
 * @brief This function adds mshX interface
 *
1419
 *  @param priv    A pointer to the struct lbs_private structure
1420 1421
 *  @return 	   0 if successful, -X otherwise
 */
1422
static int lbs_add_mesh(struct lbs_private *priv)
1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434
{
	struct net_device *mesh_dev = NULL;
	int ret = 0;

	lbs_deb_enter(LBS_DEB_MESH);

	/* Allocate a virtual mesh device */
	if (!(mesh_dev = alloc_netdev(0, "msh%d", ether_setup))) {
		lbs_deb_mesh("init mshX device failed\n");
		ret = -ENOMEM;
		goto done;
	}
1435
	mesh_dev->ml_priv = priv;
1436 1437
	priv->mesh_dev = mesh_dev;

1438
	mesh_dev->netdev_ops = &mesh_netdev_ops;
1439
	mesh_dev->ethtool_ops = &lbs_ethtool_ops;
1440 1441
	memcpy(mesh_dev->dev_addr, priv->dev->dev_addr,
			sizeof(priv->dev->dev_addr));
1442

1443
	SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent);
1444

1445
#ifdef	WIRELESS_EXT
1446
	mesh_dev->wireless_handlers = (struct iw_handler_def *)&mesh_handler_def;
1447
#endif
1448
	mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
1449 1450 1451 1452 1453 1454 1455
	/* Register virtual mesh interface */
	ret = register_netdev(mesh_dev);
	if (ret) {
		lbs_pr_err("cannot register mshX virtual interface\n");
		goto err_free;
	}

1456
	ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
1457 1458 1459
	if (ret)
		goto err_unregister;

1460 1461
	lbs_persist_config_init(mesh_dev);

1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475
	/* Everything successful */
	ret = 0;
	goto done;

err_unregister:
	unregister_netdev(mesh_dev);

err_free:
	free_netdev(mesh_dev);

done:
	lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
	return ret;
}
1476

1477
static void lbs_remove_mesh(struct lbs_private *priv)
1478 1479 1480 1481 1482
{
	struct net_device *mesh_dev;


	mesh_dev = priv->mesh_dev;
1483
	if (!mesh_dev)
1484
		return;
1485

1486
	lbs_deb_enter(LBS_DEB_MESH);
1487
	netif_stop_queue(mesh_dev);
1488
	netif_carrier_off(mesh_dev);
1489
	sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
1490
	lbs_persist_config_remove(mesh_dev);
1491
	unregister_netdev(mesh_dev);
1492
	priv->mesh_dev = NULL;
1493
	free_netdev(mesh_dev);
1494
	lbs_deb_leave(LBS_DEB_MESH);
1495 1496
}

1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516
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;

	__kfifo_put(priv->event_fifo, (unsigned char *) &event, sizeof(u32));

	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)
1517
{
1518
	lbs_deb_enter(LBS_DEB_THREAD);
1519

1520
	if (priv->psstate == PS_STATE_SLEEP)
1521
		priv->psstate = PS_STATE_AWAKE;
1522 1523 1524 1525 1526

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

1527
	wake_up_interruptible(&priv->waitq);
1528

1529
	lbs_deb_leave(LBS_DEB_THREAD);
1530
}
1531
EXPORT_SYMBOL_GPL(lbs_notify_command_response);
1532

1533
static int __init lbs_init_module(void)
1534
{
1535
	lbs_deb_enter(LBS_DEB_MAIN);
1536 1537 1538 1539
	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);
1540
	lbs_debugfs_init();
1541 1542
	lbs_deb_leave(LBS_DEB_MAIN);
	return 0;
1543 1544
}

1545
static void __exit lbs_exit_module(void)
1546
{
1547
	lbs_deb_enter(LBS_DEB_MAIN);
1548
	lbs_debugfs_remove();
1549
	lbs_deb_leave(LBS_DEB_MAIN);
1550 1551
}

1552 1553 1554 1555
/*
 * rtap interface support fuctions
 */

1556
static int lbs_rtap_open(struct net_device *dev)
1557
{
1558
	/* Yes, _stop_ the queue. Because we don't support injection */
1559 1560 1561 1562 1563
	lbs_deb_enter(LBS_DEB_MAIN);
	netif_carrier_off(dev);
	netif_stop_queue(dev);
	lbs_deb_leave(LBS_DEB_LEAVE);
	return 0;
1564 1565
}

1566
static int lbs_rtap_stop(struct net_device *dev)
1567
{
1568 1569 1570
	lbs_deb_enter(LBS_DEB_MAIN);
	lbs_deb_leave(LBS_DEB_MAIN);
	return 0;
1571 1572
}

1573 1574
static netdev_tx_t lbs_rtap_hard_start_xmit(struct sk_buff *skb,
					    struct net_device *dev)
1575
{
1576 1577
	netif_stop_queue(dev);
	return NETDEV_TX_BUSY;
1578 1579
}

1580
static void lbs_remove_rtap(struct lbs_private *priv)
1581
{
1582
	lbs_deb_enter(LBS_DEB_MAIN);
1583
	if (priv->rtap_net_dev == NULL)
1584
		goto out;
1585
	unregister_netdev(priv->rtap_net_dev);
1586
	free_netdev(priv->rtap_net_dev);
1587
	priv->rtap_net_dev = NULL;
1588
out:
1589
	lbs_deb_leave(LBS_DEB_MAIN);
1590 1591
}

1592 1593 1594 1595 1596 1597
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,
};

1598
static int lbs_add_rtap(struct lbs_private *priv)
1599
{
1600
	int ret = 0;
1601
	struct net_device *rtap_dev;
1602

1603 1604 1605 1606 1607
	lbs_deb_enter(LBS_DEB_MAIN);
	if (priv->rtap_net_dev) {
		ret = -EPERM;
		goto out;
	}
1608

1609
	rtap_dev = alloc_netdev(0, "rtap%d", ether_setup);
1610 1611 1612 1613
	if (rtap_dev == NULL) {
		ret = -ENOMEM;
		goto out;
	}
1614

1615
	memcpy(rtap_dev->dev_addr, priv->current_addr, ETH_ALEN);
1616
	rtap_dev->type = ARPHRD_IEEE80211_RADIOTAP;
1617
	rtap_dev->netdev_ops = &rtap_netdev_ops;
1618
	rtap_dev->ml_priv = priv;
1619
	SET_NETDEV_DEV(rtap_dev, priv->dev->dev.parent);
1620

1621 1622
	ret = register_netdev(rtap_dev);
	if (ret) {
1623
		free_netdev(rtap_dev);
1624
		goto out;
1625
	}
1626
	priv->rtap_net_dev = rtap_dev;
1627

1628 1629 1630
out:
	lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
	return ret;
1631 1632
}

1633 1634
module_init(lbs_init_module);
module_exit(lbs_exit_module);
1635

1636
MODULE_DESCRIPTION("Libertas WLAN Driver Library");
1637 1638
MODULE_AUTHOR("Marvell International Ltd.");
MODULE_LICENSE("GPL");