main.c 38.0 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 14

#include <net/iw_handler.h>
15
#include <net/ieee80211.h>
16 17 18 19 20 21 22

#include "host.h"
#include "decl.h"
#include "dev.h"
#include "wext.h"
#include "debugfs.h"
#include "assoc.h"
23
#include "join.h"
24
#include "cmd.h"
25

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

33 34

/* Module parameters */
35 36 37
unsigned int lbs_debug;
EXPORT_SYMBOL_GPL(lbs_debug);
module_param_named(libertas_debug, lbs_debug, int, 0644);
38 39


40 41 42 43 44
#define LBS_TX_PWR_DEFAULT		20	/*100mW */
#define LBS_TX_PWR_US_DEFAULT		20	/*100mW */
#define LBS_TX_PWR_JP_DEFAULT		16	/*50mW */
#define LBS_TX_PWR_FR_DEFAULT		20	/*100mW */
#define LBS_TX_PWR_EMEA_DEFAULT	20	/*100mW */
45 46 47 48

/* Format { channel, frequency (MHz), maxtxpower } */
/* band: 'B/G', region: USA FCC/Canada IC */
static struct chan_freq_power channel_freq_power_US_BG[] = {
49 50 51 52 53 54 55 56 57 58 59
	{1, 2412, LBS_TX_PWR_US_DEFAULT},
	{2, 2417, LBS_TX_PWR_US_DEFAULT},
	{3, 2422, LBS_TX_PWR_US_DEFAULT},
	{4, 2427, LBS_TX_PWR_US_DEFAULT},
	{5, 2432, LBS_TX_PWR_US_DEFAULT},
	{6, 2437, LBS_TX_PWR_US_DEFAULT},
	{7, 2442, LBS_TX_PWR_US_DEFAULT},
	{8, 2447, LBS_TX_PWR_US_DEFAULT},
	{9, 2452, LBS_TX_PWR_US_DEFAULT},
	{10, 2457, LBS_TX_PWR_US_DEFAULT},
	{11, 2462, LBS_TX_PWR_US_DEFAULT}
60 61 62 63
};

/* band: 'B/G', region: Europe ETSI */
static struct chan_freq_power channel_freq_power_EU_BG[] = {
64 65 66 67 68 69 70 71 72 73 74 75 76
	{1, 2412, LBS_TX_PWR_EMEA_DEFAULT},
	{2, 2417, LBS_TX_PWR_EMEA_DEFAULT},
	{3, 2422, LBS_TX_PWR_EMEA_DEFAULT},
	{4, 2427, LBS_TX_PWR_EMEA_DEFAULT},
	{5, 2432, LBS_TX_PWR_EMEA_DEFAULT},
	{6, 2437, LBS_TX_PWR_EMEA_DEFAULT},
	{7, 2442, LBS_TX_PWR_EMEA_DEFAULT},
	{8, 2447, LBS_TX_PWR_EMEA_DEFAULT},
	{9, 2452, LBS_TX_PWR_EMEA_DEFAULT},
	{10, 2457, LBS_TX_PWR_EMEA_DEFAULT},
	{11, 2462, LBS_TX_PWR_EMEA_DEFAULT},
	{12, 2467, LBS_TX_PWR_EMEA_DEFAULT},
	{13, 2472, LBS_TX_PWR_EMEA_DEFAULT}
77 78 79 80
};

/* band: 'B/G', region: Spain */
static struct chan_freq_power channel_freq_power_SPN_BG[] = {
81 82
	{10, 2457, LBS_TX_PWR_DEFAULT},
	{11, 2462, LBS_TX_PWR_DEFAULT}
83 84 85 86
};

/* band: 'B/G', region: France */
static struct chan_freq_power channel_freq_power_FR_BG[] = {
87 88 89 90
	{10, 2457, LBS_TX_PWR_FR_DEFAULT},
	{11, 2462, LBS_TX_PWR_FR_DEFAULT},
	{12, 2467, LBS_TX_PWR_FR_DEFAULT},
	{13, 2472, LBS_TX_PWR_FR_DEFAULT}
91 92 93 94
};

/* band: 'B/G', region: Japan */
static struct chan_freq_power channel_freq_power_JPN_BG[] = {
95 96 97 98 99 100 101 102 103 104 105 106 107 108
	{1, 2412, LBS_TX_PWR_JP_DEFAULT},
	{2, 2417, LBS_TX_PWR_JP_DEFAULT},
	{3, 2422, LBS_TX_PWR_JP_DEFAULT},
	{4, 2427, LBS_TX_PWR_JP_DEFAULT},
	{5, 2432, LBS_TX_PWR_JP_DEFAULT},
	{6, 2437, LBS_TX_PWR_JP_DEFAULT},
	{7, 2442, LBS_TX_PWR_JP_DEFAULT},
	{8, 2447, LBS_TX_PWR_JP_DEFAULT},
	{9, 2452, LBS_TX_PWR_JP_DEFAULT},
	{10, 2457, LBS_TX_PWR_JP_DEFAULT},
	{11, 2462, LBS_TX_PWR_JP_DEFAULT},
	{12, 2467, LBS_TX_PWR_JP_DEFAULT},
	{13, 2472, LBS_TX_PWR_JP_DEFAULT},
	{14, 2484, LBS_TX_PWR_JP_DEFAULT}
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
};

/**
 * the structure for channel, frequency and power
 */
struct region_cfp_table {
	u8 region;
	struct chan_freq_power *cfp_BG;
	int cfp_no_BG;
};

/**
 * the structure for the mapping between region and CFP
 */
static struct region_cfp_table region_cfp_table[] = {
	{0x10,			/*US FCC */
	 channel_freq_power_US_BG,
126
	 ARRAY_SIZE(channel_freq_power_US_BG),
127 128 129 130
	 }
	,
	{0x20,			/*CANADA IC */
	 channel_freq_power_US_BG,
131
	 ARRAY_SIZE(channel_freq_power_US_BG),
132 133 134
	 }
	,
	{0x30, /*EU*/ channel_freq_power_EU_BG,
135
	 ARRAY_SIZE(channel_freq_power_EU_BG),
136 137 138
	 }
	,
	{0x31, /*SPAIN*/ channel_freq_power_SPN_BG,
139
	 ARRAY_SIZE(channel_freq_power_SPN_BG),
140 141 142
	 }
	,
	{0x32, /*FRANCE*/ channel_freq_power_FR_BG,
143
	 ARRAY_SIZE(channel_freq_power_FR_BG),
144 145 146
	 }
	,
	{0x40, /*JAPAN*/ channel_freq_power_JPN_BG,
147
	 ARRAY_SIZE(channel_freq_power_JPN_BG),
148 149 150 151 152 153
	 }
	,
/*Add new region here */
};

/**
154
 * the table to keep region code
155
 */
156
u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE] =
157
    { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 };
158 159

/**
160
 * 802.11b/g supported bitrates (in 500Kb/s units)
161
 */
162
u8 lbs_bg_rates[MAX_RATES] =
163 164
    { 0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c,
0x00, 0x00 };
165 166

/**
167 168 169
 * 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.
170
 */
171 172 173 174
static u8 fw_data_rates[MAX_RATES] =
    { 0x02, 0x04, 0x0B, 0x16, 0x00, 0x0C, 0x12,
      0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x00
};
175 176

/**
177 178 179 180
 *  @brief use index to get the data rate
 *
 *  @param idx                The index of data rate
 *  @return 	   		data rate or 0
181
 */
182
u32 lbs_fw_index_to_data_rate(u8 idx)
183 184 185 186 187 188 189 190 191 192 193 194
{
	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
 */
195
u8 lbs_data_rate_to_fw_index(u32 rate)
196 197 198 199 200 201 202 203 204 205 206 207
{
	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;
}
208 209 210 211 212 213

/**
 * Attributes exported through sysfs
 */

/**
214
 * @brief Get function for sysfs attribute anycast_mask
215
 */
216
static ssize_t lbs_anycast_get(struct device *dev,
D
Dan Williams 已提交
217 218
		struct device_attribute *attr, char * buf)
{
219
	struct lbs_private *priv = to_net_dev(dev)->priv;
220
	struct cmd_ds_mesh_access mesh_access;
221
	int ret;
222 223

	memset(&mesh_access, 0, sizeof(mesh_access));
224 225 226 227

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

229
	return snprintf(buf, 12, "0x%X\n", le32_to_cpu(mesh_access.data[0]));
230 231 232
}

/**
233
 * @brief Set function for sysfs attribute anycast_mask
234
 */
235
static ssize_t lbs_anycast_set(struct device *dev,
D
Dan Williams 已提交
236 237
		struct device_attribute *attr, const char * buf, size_t count)
{
238
	struct lbs_private *priv = to_net_dev(dev)->priv;
239
	struct cmd_ds_mesh_access mesh_access;
240
	uint32_t datum;
241
	int ret;
242 243

	memset(&mesh_access, 0, sizeof(mesh_access));
244
	sscanf(buf, "%x", &datum);
245 246
	mesh_access.data[0] = cpu_to_le32(datum);

247 248 249 250
	ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_ANYCAST, &mesh_access);
	if (ret)
		return ret;

251 252 253
	return strlen(buf);
}

254 255
static int lbs_add_rtap(struct lbs_private *priv);
static void lbs_remove_rtap(struct lbs_private *priv);
256 257
static int lbs_add_mesh(struct lbs_private *priv);
static void lbs_remove_mesh(struct lbs_private *priv);
258

259 260 261 262

/**
 * Get function for sysfs attribute rtap
 */
263
static ssize_t lbs_rtap_get(struct device *dev,
264 265
		struct device_attribute *attr, char * buf)
{
266
	struct lbs_private *priv = to_net_dev(dev)->priv;
267
	return snprintf(buf, 5, "0x%X\n", priv->monitormode);
268 269 270 271 272
}

/**
 *  Set function for sysfs attribute rtap
 */
273
static ssize_t lbs_rtap_set(struct device *dev,
274 275 276
		struct device_attribute *attr, const char * buf, size_t count)
{
	int monitor_mode;
277
	struct lbs_private *priv = to_net_dev(dev)->priv;
278 279

	sscanf(buf, "%x", &monitor_mode);
280
	if (monitor_mode != LBS_MONITOR_OFF) {
281
		if(priv->monitormode == monitor_mode)
282
			return strlen(buf);
283
		if (priv->monitormode == LBS_MONITOR_OFF) {
284 285
			if (priv->infra_open || priv->mesh_open)
				return -EBUSY;
286
			if (priv->mode == IW_MODE_INFRA)
287
				lbs_send_deauthentication(priv);
288
			else if (priv->mode == IW_MODE_ADHOC)
289 290
				lbs_stop_adhoc_network(priv);
			lbs_add_rtap(priv);
291
		}
292
		priv->monitormode = monitor_mode;
293 294 295
	}

	else {
296
		if (priv->monitormode == LBS_MONITOR_OFF)
297
			return strlen(buf);
298
		priv->monitormode = LBS_MONITOR_OFF;
299
		lbs_remove_rtap(priv);
D
David Woodhouse 已提交
300

301 302 303
		if (priv->currenttxskb) {
			dev_kfree_skb_any(priv->currenttxskb);
			priv->currenttxskb = NULL;
D
David Woodhouse 已提交
304 305 306 307
		}

		/* Wake queues, command thread, etc. */
		lbs_host_to_card_done(priv);
308 309
	}

310
	lbs_prepare_and_send_command(priv,
311
			CMD_802_11_MONITOR_MODE, CMD_ACT_SET,
312
			CMD_OPTION_WAITFORRSP, 0, &priv->monitormode);
313 314 315 316
	return strlen(buf);
}

/**
317 318
 * lbs_rtap attribute to be exported per ethX interface
 * through sysfs (/sys/class/net/ethX/lbs_rtap)
319
 */
320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346
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)
{
	struct lbs_private *priv = to_net_dev(dev)->priv;
	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)
{
	struct lbs_private *priv = to_net_dev(dev)->priv;
	int enable;
	int ret;

	sscanf(buf, "%x", &enable);
	enable = !!enable;
	if (enable == !!priv->mesh_dev)
		return count;

347
	ret = lbs_mesh_config(priv, enable, priv->curbssparams.channel);
348 349
	if (ret)
		return ret;
350

351 352 353 354 355 356 357 358 359 360 361 362 363
	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);
364

365
/**
366 367
 * anycast_mask attribute to be exported per mshX interface
 * through sysfs (/sys/class/net/mshX/anycast_mask)
368
 */
369
static DEVICE_ATTR(anycast_mask, 0644, lbs_anycast_get, lbs_anycast_set);
370

371
static struct attribute *lbs_mesh_sysfs_entries[] = {
372 373 374 375
	&dev_attr_anycast_mask.attr,
	NULL,
};

376 377
static struct attribute_group lbs_mesh_attr_group = {
	.attrs = lbs_mesh_sysfs_entries,
378 379
};

380
/**
381
 *  @brief This function opens the ethX or mshX interface
382 383
 *
 *  @param dev     A pointer to net_device structure
384
 *  @return 	   0 or -EBUSY if monitor mode active
385
 */
386
static int lbs_dev_open(struct net_device *dev)
387
{
388 389
	struct lbs_private *priv = (struct lbs_private *) dev->priv ;
	int ret = 0;
390

391
	spin_lock_irq(&priv->driver_lock);
392

393 394 395 396
	if (priv->monitormode != LBS_MONITOR_OFF) {
		ret = -EBUSY;
		goto out;
	}
397

398 399 400 401 402 403
	if (dev == priv->mesh_dev) {
		priv->mesh_open = 1;
		priv->mesh_connect_status = LBS_CONNECTED;
		netif_carrier_on(dev);
	} else {
		priv->infra_open = 1;
404

405 406
		if (priv->connect_status == LBS_CONNECTED)
			netif_carrier_on(dev);
407
		else
408
			netif_carrier_off(dev);
409
	}
410

411 412 413
	if (!priv->tx_pending_len)
		netif_wake_queue(dev);
 out:
414

415 416
	spin_unlock_irq(&priv->driver_lock);
	return ret;
417 418 419 420 421 422 423 424
}

/**
 *  @brief This function closes the mshX interface
 *
 *  @param dev     A pointer to net_device structure
 *  @return 	   0
 */
425
static int lbs_mesh_stop(struct net_device *dev)
426
{
427
	struct lbs_private *priv = (struct lbs_private *) (dev->priv);
428

429 430
	spin_lock_irq(&priv->driver_lock);

431
	priv->mesh_open = 0;
432 433 434 435
	priv->mesh_connect_status = LBS_DISCONNECTED;

	netif_stop_queue(dev);
	netif_carrier_off(dev);
436

437 438
	spin_unlock_irq(&priv->driver_lock);
	return 0;
439 440 441 442 443 444 445 446
}

/**
 *  @brief This function closes the ethX interface
 *
 *  @param dev     A pointer to net_device structure
 *  @return 	   0
 */
447
static int lbs_eth_stop(struct net_device *dev)
448
{
449
	struct lbs_private *priv = (struct lbs_private *) dev->priv;
450

451 452
	spin_lock_irq(&priv->driver_lock);

453
	priv->infra_open = 0;
454 455

	netif_stop_queue(dev);
456

457 458
	spin_unlock_irq(&priv->driver_lock);
	return 0;
459 460
}

461
static void lbs_tx_timeout(struct net_device *dev)
462
{
463
	struct lbs_private *priv = (struct lbs_private *) dev->priv;
464

465
	lbs_deb_enter(LBS_DEB_TX);
466

467
	lbs_pr_err("tx watch dog timeout\n");
468 469 470

	dev->trans_start = jiffies;

471
	if (priv->currenttxskb) {
472 473
		priv->eventcause = 0x01000000;
		lbs_send_tx_feedback(priv);
474
	}
475 476 477
	/* XX: Shouldn't we also call into the hw-specific driver
	   to kick it somehow? */
	lbs_host_to_card_done(priv);
478

479 480 481 482 483 484 485
	/* 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);

486
	lbs_deb_leave(LBS_DEB_TX);
487 488
}

489 490
void lbs_host_to_card_done(struct lbs_private *priv)
{
491 492 493
	unsigned long flags;

	spin_lock_irqsave(&priv->driver_lock, flags);
494 495 496 497

	priv->dnld_sent = DNLD_RES_RECEIVED;

	/* Wake main thread if commands are pending */
498
	if (!priv->cur_cmd || priv->tx_pending_len > 0)
499 500
		wake_up_interruptible(&priv->waitq);

501
	spin_unlock_irqrestore(&priv->driver_lock, flags);
502 503 504
}
EXPORT_SYMBOL_GPL(lbs_host_to_card_done);

505 506 507
/**
 *  @brief This function returns the network statistics
 *
508
 *  @param dev     A pointer to struct lbs_private structure
509 510
 *  @return 	   A pointer to net_device_stats structure
 */
511
static struct net_device_stats *lbs_get_stats(struct net_device *dev)
512
{
513
	struct lbs_private *priv = (struct lbs_private *) dev->priv;
514 515 516 517

	return &priv->stats;
}

518
static int lbs_set_mac_address(struct net_device *dev, void *addr)
519 520
{
	int ret = 0;
521
	struct lbs_private *priv = (struct lbs_private *) dev->priv;
522 523
	struct sockaddr *phwaddr = addr;

524
	lbs_deb_enter(LBS_DEB_NET);
525

526 527 528
	/* In case it was called from the mesh device */
	dev = priv->dev ;

529
	memset(priv->current_addr, 0, ETH_ALEN);
530 531

	/* dev->dev_addr is 8 bytes */
532
	lbs_deb_hex(LBS_DEB_NET, "dev->dev_addr", dev->dev_addr, ETH_ALEN);
533

534
	lbs_deb_hex(LBS_DEB_NET, "addr", phwaddr->sa_data, ETH_ALEN);
535
	memcpy(priv->current_addr, phwaddr->sa_data, ETH_ALEN);
536

537
	ret = lbs_prepare_and_send_command(priv, CMD_802_11_MAC_ADDRESS,
538 539
				    CMD_ACT_SET,
				    CMD_OPTION_WAITFORRSP, 0, NULL);
540 541

	if (ret) {
542
		lbs_deb_net("set MAC address failed\n");
543 544 545 546
		ret = -1;
		goto done;
	}

547 548
	lbs_deb_hex(LBS_DEB_NET, "priv->macaddr", priv->current_addr, ETH_ALEN);
	memcpy(dev->dev_addr, priv->current_addr, ETH_ALEN);
549
	if (priv->mesh_dev)
550
		memcpy(priv->mesh_dev->dev_addr, priv->current_addr, ETH_ALEN);
551 552

done:
553
	lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
554 555 556
	return ret;
}

557
static int lbs_copy_multicast_address(struct lbs_private *priv,
558 559 560 561 562 563
				     struct net_device *dev)
{
	int i = 0;
	struct dev_mc_list *mcptr = dev->mc_list;

	for (i = 0; i < dev->mc_count; i++) {
564
		memcpy(&priv->multicastlist[i], mcptr->dmi_addr, ETH_ALEN);
565 566 567 568 569 570 571
		mcptr = mcptr->next;
	}

	return i;

}

572
static void lbs_set_multicast_list(struct net_device *dev)
573
{
574
	struct lbs_private *priv = dev->priv;
575
	int oldpacketfilter;
576
	DECLARE_MAC_BUF(mac);
577

578
	lbs_deb_enter(LBS_DEB_NET);
579

580
	oldpacketfilter = priv->currentpacketfilter;
581 582

	if (dev->flags & IFF_PROMISC) {
583
		lbs_deb_net("enable promiscuous mode\n");
584
		priv->currentpacketfilter |=
585
		    CMD_ACT_MAC_PROMISCUOUS_ENABLE;
586
		priv->currentpacketfilter &=
587 588
		    ~(CMD_ACT_MAC_ALL_MULTICAST_ENABLE |
		      CMD_ACT_MAC_MULTICAST_ENABLE);
589 590
	} else {
		/* Multicast */
591
		priv->currentpacketfilter &=
592
		    ~CMD_ACT_MAC_PROMISCUOUS_ENABLE;
593 594 595

		if (dev->flags & IFF_ALLMULTI || dev->mc_count >
		    MRVDRV_MAX_MULTICAST_LIST_SIZE) {
596
			lbs_deb_net( "enabling all multicast\n");
597
			priv->currentpacketfilter |=
598
			    CMD_ACT_MAC_ALL_MULTICAST_ENABLE;
599
			priv->currentpacketfilter &=
600
			    ~CMD_ACT_MAC_MULTICAST_ENABLE;
601
		} else {
602
			priv->currentpacketfilter &=
603
			    ~CMD_ACT_MAC_ALL_MULTICAST_ENABLE;
604 605

			if (!dev->mc_count) {
606 607
				lbs_deb_net("no multicast addresses, "
				       "disabling multicast\n");
608
				priv->currentpacketfilter &=
609
				    ~CMD_ACT_MAC_MULTICAST_ENABLE;
610 611 612
			} else {
				int i;

613
				priv->currentpacketfilter |=
614
				    CMD_ACT_MAC_MULTICAST_ENABLE;
615

616 617
				priv->nr_of_multicastmacaddr =
				    lbs_copy_multicast_address(priv, dev);
618

619
				lbs_deb_net("multicast addresses: %d\n",
620 621 622
				       dev->mc_count);

				for (i = 0; i < dev->mc_count; i++) {
623 624
					lbs_deb_net("Multicast address %d:%s\n",
					       i, print_mac(mac,
625
					       priv->multicastlist[i]));
626
				}
627
				/* send multicast addresses to firmware */
628
				lbs_prepare_and_send_command(priv,
629 630
						      CMD_MAC_MULTICAST_ADR,
						      CMD_ACT_SET, 0, 0,
631 632 633 634 635
						      NULL);
			}
		}
	}

636
	if (priv->currentpacketfilter != oldpacketfilter) {
637
		lbs_set_mac_packet_filter(priv);
638 639
	}

640
	lbs_deb_leave(LBS_DEB_NET);
641 642 643
}

/**
644
 *  @brief This function handles the major jobs in the LBS driver.
645 646
 *  It handles all events generated by firmware, RX data received
 *  from firmware and TX data sent from kernel.
647
 *
648
 *  @param data    A pointer to lbs_thread structure
649 650
 *  @return 	   0
 */
651
static int lbs_thread(void *data)
652
{
653
	struct net_device *dev = data;
654
	struct lbs_private *priv = dev->priv;
655 656 657
	wait_queue_t wait;
	u8 ireg = 0;

658
	lbs_deb_enter(LBS_DEB_THREAD);
659 660 661 662

	init_waitqueue_entry(&wait, current);

	for (;;) {
663 664
		int shouldsleep;

665
		lbs_deb_thread( "main-thread 111: intcounter=%d currenttxskb=%p dnld_sent=%d\n",
666
				priv->intcounter, priv->currenttxskb, priv->dnld_sent);
667

668
		add_wait_queue(&priv->waitq, &wait);
669
		set_current_state(TASK_INTERRUPTIBLE);
670
		spin_lock_irq(&priv->driver_lock);
671

672
		if (kthread_should_stop())
673
			shouldsleep = 0;	/* Bye */
674 675
		else if (priv->surpriseremoved)
			shouldsleep = 1;	/* We need to wait until we're _told_ to die */
676 677 678 679
		else if (priv->psstate == PS_STATE_SLEEP)
			shouldsleep = 1;	/* Sleep mode. Nothing we can do till it wakes */
		else if (priv->intcounter)
			shouldsleep = 0;	/* Interrupt pending. Deal with it now */
680 681
		else if (priv->cmd_timed_out)
			shouldsleep = 0;	/* Command timed out. Recover */
682 683
		else if (!priv->fw_ready)
			shouldsleep = 1;	/* Firmware not ready. We're waiting for it */
684 685
		else if (priv->dnld_sent)
			shouldsleep = 1;	/* Something is en route to the device already */
686 687
		else if (priv->tx_pending_len > 0)
			shouldsleep = 0;	/* We've a packet to send */
688 689 690 691 692 693 694 695
		else if (priv->cur_cmd)
			shouldsleep = 1;	/* Can't send a command; one already running */
		else if (!list_empty(&priv->cmdpendingq))
			shouldsleep = 0;	/* We have a command to send */
		else
			shouldsleep = 1;	/* No command */

		if (shouldsleep) {
696
			lbs_deb_thread("main-thread sleeping... Conn=%d IntC=%d PS_mode=%d PS_State=%d\n",
697 698 699
				       priv->connect_status, priv->intcounter,
				       priv->psmode, priv->psstate);
			spin_unlock_irq(&priv->driver_lock);
700 701
			schedule();
		} else
702
			spin_unlock_irq(&priv->driver_lock);
703

704
		lbs_deb_thread("main-thread 222 (waking up): intcounter=%d currenttxskb=%p dnld_sent=%d\n",
705
			       priv->intcounter, priv->currenttxskb, priv->dnld_sent);
706 707

		set_current_state(TASK_RUNNING);
708
		remove_wait_queue(&priv->waitq, &wait);
709

710
		lbs_deb_thread("main-thread 333: intcounter=%d currenttxskb=%p dnld_sent=%d\n",
711
			       priv->intcounter, priv->currenttxskb, priv->dnld_sent);
712

713 714
		if (kthread_should_stop()) {
			lbs_deb_thread("main-thread: break from main thread\n");
715 716 717
			break;
		}

718 719 720 721
		if (priv->surpriseremoved) {
			lbs_deb_thread("adapter removed; waiting to die...\n");
			continue;
		}
722

723
		spin_lock_irq(&priv->driver_lock);
724

725
		if (priv->intcounter) {
726
			u8 int_status;
727

728
			priv->intcounter = 0;
729
			int_status = priv->hw_get_int_status(priv, &ireg);
730 731

			if (int_status) {
732
				lbs_deb_thread("main-thread: reading HOST_INT_STATUS_REG failed\n");
733
				spin_unlock_irq(&priv->driver_lock);
734 735
				continue;
			}
736
			priv->hisregcpy |= ireg;
737 738
		}

739
		lbs_deb_thread("main-thread 444: intcounter=%d currenttxskb=%p dnld_sent=%d\n",
740
			       priv->intcounter, priv->currenttxskb, priv->dnld_sent);
741 742

		/* command response? */
743
		if (priv->hisregcpy & MRVDRV_CMD_UPLD_RDY) {
744
			lbs_deb_thread("main-thread: cmd response ready\n");
745

746 747
			priv->hisregcpy &= ~MRVDRV_CMD_UPLD_RDY;
			spin_unlock_irq(&priv->driver_lock);
748
			lbs_process_rx_command(priv);
749
			spin_lock_irq(&priv->driver_lock);
750 751
		}

752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771
		if (priv->cmd_timed_out && priv->cur_cmd) {
			struct cmd_ctrl_node *cmdnode = priv->cur_cmd;

			if (++priv->nr_retries > 10) {
				lbs_pr_info("Excessive timeouts submitting command %x\n",
					    le16_to_cpu(cmdnode->cmdbuf->command));
				lbs_complete_command(priv, cmdnode, -ETIMEDOUT);
				priv->nr_retries = 0;
			} else {
				priv->cur_cmd = NULL;
				lbs_pr_info("requeueing command %x due to timeout (#%d)\n",
					    le16_to_cpu(cmdnode->cmdbuf->command), priv->nr_retries);

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

772
		/* Any Card Event */
773
		if (priv->hisregcpy & MRVDRV_CARDEVENT) {
774
			lbs_deb_thread("main-thread: Card Event Activity\n");
775

776
			priv->hisregcpy &= ~MRVDRV_CARDEVENT;
777

778
			if (priv->hw_read_event_cause(priv)) {
779
				lbs_pr_alert("main-thread: hw_read_event_cause failed\n");
780
				spin_unlock_irq(&priv->driver_lock);
781 782
				continue;
			}
783
			spin_unlock_irq(&priv->driver_lock);
784
			lbs_process_event(priv);
785
		} else
786
			spin_unlock_irq(&priv->driver_lock);
787

788 789 790
		if (!priv->fw_ready)
			continue;

791
		/* Check if we need to confirm Sleep Request received previously */
792 793 794
		if (priv->psstate == PS_STATE_PRE_SLEEP &&
		    !priv->dnld_sent && !priv->cur_cmd) {
			if (priv->connect_status == LBS_CONNECTED) {
795
				lbs_deb_thread("main_thread: PRE_SLEEP--intcounter=%d currenttxskb=%p dnld_sent=%d cur_cmd=%p, confirm now\n",
796
					       priv->intcounter, priv->currenttxskb, priv->dnld_sent, priv->cur_cmd);
797

798
				lbs_ps_confirm_sleep(priv, (u16) priv->psmode);
799 800 801 802 803 804
			} else {
				/* workaround for firmware sending
				 * deauth/linkloss event immediately
				 * after sleep request; remove this
				 * after firmware fixes it
				 */
805
				priv->psstate = PS_STATE_AWAKE;
806
				lbs_pr_alert("main-thread: ignore PS_SleepConfirm in non-connected state\n");
807 808 809 810 811 812
			}
		}

		/* The PS state is changed during processing of Sleep Request
		 * event above
		 */
813 814
		if ((priv->psstate == PS_STATE_SLEEP) ||
		    (priv->psstate == PS_STATE_PRE_SLEEP))
815 816 817
			continue;

		/* Execute the next command */
818
		if (!priv->dnld_sent && !priv->cur_cmd)
819
			lbs_execute_next_command(priv);
820 821

		/* Wake-up command waiters which can't sleep in
822
		 * lbs_prepare_and_send_command
823
		 */
824 825
		if (!list_empty(&priv->cmdpendingq))
			wake_up_all(&priv->cmd_pending);
826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847

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

850 851
	del_timer(&priv->command_timer);
	wake_up_all(&priv->cmd_pending);
852

853
	lbs_deb_leave(LBS_DEB_THREAD);
854 855 856
	return 0;
}

857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875
static int lbs_suspend_callback(struct lbs_private *priv, unsigned long dummy,
				struct cmd_header *cmd)
{
	lbs_deb_fw("HOST_SLEEP_ACTIVATE succeeded\n");

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

	priv->fw_ready = 0;
	return 0;
}


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

876 877 878 879 880
	if (priv->wol_criteria == 0xffffffff) {
		lbs_pr_info("Suspend attempt without configuring wake params!\n");
		return -EINVAL;
	}

881
	memset(&cmd, 0, sizeof(cmd));
882

883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908
	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);

	return ret;
}
EXPORT_SYMBOL_GPL(lbs_suspend);

int lbs_resume(struct lbs_private *priv)
{
	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);

	return 0;
}
EXPORT_SYMBOL_GPL(lbs_resume);

H
Holger Schurig 已提交
909 910 911 912 913
/**
 *  @brief This function downloads firmware image, gets
 *  HW spec from firmware and set basic parameters to
 *  firmware.
 *
914
 *  @param priv    A pointer to struct lbs_private structure
H
Holger Schurig 已提交
915 916
 *  @return 	   0 or -1
 */
917
static int lbs_setup_firmware(struct lbs_private *priv)
H
Holger Schurig 已提交
918 919 920 921 922 923 924 925
{
	int ret = -1;

	lbs_deb_enter(LBS_DEB_FW);

	/*
	 * Read MAC address from HW
	 */
926
	memset(priv->current_addr, 0xff, ETH_ALEN);
927
	ret = lbs_update_hw_spec(priv);
H
Holger Schurig 已提交
928 929 930 931 932
	if (ret) {
		ret = -1;
		goto done;
	}

933
	lbs_set_mac_packet_filter(priv);
H
Holger Schurig 已提交
934

935 936
	ret = lbs_get_data_rate(priv);
	if (ret < 0) {
H
Holger Schurig 已提交
937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952
		ret = -1;
		goto done;
	}

	ret = 0;
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)
{
953
	struct lbs_private *priv = (struct lbs_private *)data;
H
Holger Schurig 已提交
954 955
	unsigned long flags;

956
	spin_lock_irqsave(&priv->driver_lock, flags);
H
Holger Schurig 已提交
957

958 959 960
	if (!priv->cur_cmd) {
		lbs_pr_info("Command timer expired; no pending command\n");
		goto out;
H
Holger Schurig 已提交
961 962
	}

963
	lbs_pr_info("Command %x timed out\n", le16_to_cpu(priv->cur_cmd->cmdbuf->command));
H
Holger Schurig 已提交
964

965
	priv->cmd_timed_out = 1;
H
Holger Schurig 已提交
966
	wake_up_interruptible(&priv->waitq);
967 968
 out:
	spin_unlock_irqrestore(&priv->driver_lock, flags);
H
Holger Schurig 已提交
969 970
}

971
static int lbs_init_adapter(struct lbs_private *priv)
972
{
H
Holger Schurig 已提交
973
	size_t bufsize;
974
	int i, ret = 0;
H
Holger Schurig 已提交
975 976 977

	/* Allocate buffer to store the BSSID list */
	bufsize = MAX_NETWORK_COUNT * sizeof(struct bss_descriptor);
978 979
	priv->networks = kzalloc(bufsize, GFP_KERNEL);
	if (!priv->networks) {
H
Holger Schurig 已提交
980
		lbs_pr_err("Out of memory allocating beacons\n");
981 982
		ret = -1;
		goto out;
H
Holger Schurig 已提交
983 984
	}

985
	/* Initialize scan result lists */
986 987
	INIT_LIST_HEAD(&priv->network_free_list);
	INIT_LIST_HEAD(&priv->network_list);
988
	for (i = 0; i < MAX_NETWORK_COUNT; i++) {
989 990
		list_add_tail(&priv->networks[i].list,
			      &priv->network_free_list);
991
	}
H
Holger Schurig 已提交
992

993 994
	priv->lbs_ps_confirm_sleep.seqnum = cpu_to_le16(++priv->seqnum);
	priv->lbs_ps_confirm_sleep.command =
H
Holger Schurig 已提交
995
	    cpu_to_le16(CMD_802_11_PS_MODE);
996
	priv->lbs_ps_confirm_sleep.size =
H
Holger Schurig 已提交
997
	    cpu_to_le16(sizeof(struct PS_CMD_ConfirmSleep));
998
	priv->lbs_ps_confirm_sleep.action =
H
Holger Schurig 已提交
999 1000
	    cpu_to_le16(CMD_SUBCMD_SLEEP_CONFIRMED);

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

1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013
	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;
	priv->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL;
	priv->currentpacketfilter = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON;
	priv->radioon = RADIO_ON;
	priv->auto_rate = 1;
	priv->capability = WLAN_CAPABILITY_SHORT_PREAMBLE;
	priv->psmode = LBS802_11POWERMODECAM;
	priv->psstate = PS_STATE_FULL_POWER;
H
Holger Schurig 已提交
1014

1015
	mutex_init(&priv->lock);
H
Holger Schurig 已提交
1016

1017
	setup_timer(&priv->command_timer, command_timer_fn,
1018
	            (unsigned long)priv);
H
Holger Schurig 已提交
1019

1020 1021
	INIT_LIST_HEAD(&priv->cmdfreeq);
	INIT_LIST_HEAD(&priv->cmdpendingq);
H
Holger Schurig 已提交
1022

1023 1024
	spin_lock_init(&priv->driver_lock);
	init_waitqueue_head(&priv->cmd_pending);
H
Holger Schurig 已提交
1025

1026
	/* Allocate the command buffers */
1027
	if (lbs_allocate_cmd_buffer(priv)) {
1028 1029 1030
		lbs_pr_err("Out of memory allocating command buffers\n");
		ret = -1;
	}
H
Holger Schurig 已提交
1031

1032 1033 1034
out:
	return ret;
}
H
Holger Schurig 已提交
1035

1036
static void lbs_free_adapter(struct lbs_private *priv)
1037 1038
{
	lbs_deb_fw("free command buffer\n");
1039
	lbs_free_cmd_buffer(priv);
H
Holger Schurig 已提交
1040

1041
	lbs_deb_fw("free command_timer\n");
1042
	del_timer(&priv->command_timer);
1043 1044

	lbs_deb_fw("free scan results table\n");
1045 1046
	kfree(priv->networks);
	priv->networks = NULL;
H
Holger Schurig 已提交
1047 1048
}

1049 1050
/**
 * @brief This function adds the card. it will probe the
1051
 * card, allocate the lbs_priv and initialize the device.
1052 1053
 *
 *  @param card    A pointer to card
1054
 *  @return 	   A pointer to struct lbs_private structure
1055
 */
1056
struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
1057 1058
{
	struct net_device *dev = NULL;
1059
	struct lbs_private *priv = NULL;
1060

1061
	lbs_deb_enter(LBS_DEB_NET);
1062 1063

	/* Allocate an Ethernet device and register it */
1064 1065
	dev = alloc_etherdev(sizeof(struct lbs_private));
	if (!dev) {
1066
		lbs_pr_err("init ethX device failed\n");
1067
		goto done;
1068
	}
1069
	priv = dev->priv;
1070

1071
	if (lbs_init_adapter(priv)) {
1072 1073 1074 1075
		lbs_pr_err("failed to initialize adapter structure.\n");
		goto err_init_adapter;
	}

1076 1077
	priv->dev = dev;
	priv->card = card;
1078 1079 1080 1081
	priv->mesh_open = 0;
	priv->infra_open = 0;

	/* Setup the OS Interface to our functions */
1082
	dev->open = lbs_dev_open;
1083
	dev->hard_start_xmit = lbs_hard_start_xmit;
1084
	dev->stop = lbs_eth_stop;
1085 1086 1087
	dev->set_mac_address = lbs_set_mac_address;
	dev->tx_timeout = lbs_tx_timeout;
	dev->get_stats = lbs_get_stats;
1088
	dev->watchdog_timeo = 5 * HZ;
1089
	dev->ethtool_ops = &lbs_ethtool_ops;
1090
#ifdef	WIRELESS_EXT
1091
	dev->wireless_handlers = (struct iw_handler_def *)&lbs_handler_def;
1092 1093
#endif
	dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
1094
	dev->set_multicast_list = lbs_set_multicast_list;
1095

1096 1097
	SET_NETDEV_DEV(dev, dmdev);

1098
	priv->rtap_net_dev = NULL;
1099 1100 1101

	lbs_deb_thread("Starting main thread...\n");
	init_waitqueue_head(&priv->waitq);
1102
	priv->main_thread = kthread_run(lbs_thread, dev, "lbs_main");
1103 1104
	if (IS_ERR(priv->main_thread)) {
		lbs_deb_thread("Error creating main thread.\n");
1105
		goto err_init_adapter;
1106 1107
	}

1108 1109 1110 1111
	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);
	INIT_WORK(&priv->sync_channel, lbs_sync_channel);
1112

1113 1114 1115
	sprintf(priv->mesh_ssid, "mesh");
	priv->mesh_ssid_len = 4;

1116 1117 1118
	priv->wol_criteria = 0xffffffff;
	priv->wol_gpio = 0xff;

1119 1120
	goto done;

1121
err_init_adapter:
1122
	lbs_free_adapter(priv);
1123
	free_netdev(dev);
1124
	priv = NULL;
1125

1126 1127 1128 1129
done:
	lbs_deb_leave_args(LBS_DEB_NET, "priv %p", priv);
	return priv;
}
1130
EXPORT_SYMBOL_GPL(lbs_add_card);
1131

1132

1133
int lbs_remove_card(struct lbs_private *priv)
1134
{
1135
	struct net_device *dev = priv->dev;
1136
	union iwreq_data wrqu;
1137 1138

	lbs_deb_enter(LBS_DEB_MAIN);
1139

1140
	lbs_remove_mesh(priv);
1141
	lbs_remove_rtap(priv);
1142

1143
	dev = priv->dev;
1144

1145 1146 1147
	cancel_delayed_work(&priv->scan_work);
	cancel_delayed_work(&priv->assoc_work);
	destroy_workqueue(priv->work_thread);
1148

1149 1150
	if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
		priv->psmode = LBS802_11POWERMODECAM;
1151
		lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
1152 1153
	}

1154 1155 1156 1157 1158
	memset(wrqu.ap_addr.sa_data, 0xaa, ETH_ALEN);
	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
	wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);

	/* Stop the thread servicing the interrupts */
1159
	priv->surpriseremoved = 1;
1160 1161
	kthread_stop(priv->main_thread);

1162
	lbs_free_adapter(priv);
1163 1164 1165 1166 1167 1168 1169

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

	lbs_deb_leave(LBS_DEB_MAIN);
	return 0;
}
1170
EXPORT_SYMBOL_GPL(lbs_remove_card);
1171 1172


1173
int lbs_start_card(struct lbs_private *priv)
1174 1175 1176 1177 1178 1179 1180
{
	struct net_device *dev = priv->dev;
	int ret = -1;

	lbs_deb_enter(LBS_DEB_MAIN);

	/* poke the firmware */
1181
	ret = lbs_setup_firmware(priv);
1182 1183 1184 1185
	if (ret)
		goto done;

	/* init 802.11d */
1186
	lbs_init_11d(priv);
1187 1188

	if (register_netdev(dev)) {
1189
		lbs_pr_err("cannot register ethX device\n");
1190
		goto done;
1191
	}
1192 1193
	if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
		lbs_pr_err("cannot register lbs_rtap attribute\n");
1194 1195 1196 1197

	/* 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
1198
	   but we check them in that order because 20.pXX doesn't
1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209
	   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 */

	lbs_update_channel(priv);
	priv->mesh_tlv = 0x100 + 291;
1210
	if (lbs_mesh_config(priv, 1, priv->curbssparams.channel)) {
1211
		priv->mesh_tlv = 0x100 + 37;
1212
		if (lbs_mesh_config(priv, 1, priv->curbssparams.channel))
1213 1214 1215 1216 1217 1218 1219 1220
			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");
	}
1221

1222
	lbs_debugfs_init_one(priv, dev);
1223

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

1226
	ret = 0;
1227

1228
done:
1229 1230 1231
	lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
	return ret;
}
1232
EXPORT_SYMBOL_GPL(lbs_start_card);
1233 1234


1235
int lbs_stop_card(struct lbs_private *priv)
1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246
{
	struct net_device *dev = priv->dev;
	int ret = -1;
	struct cmd_ctrl_node *cmdnode;
	unsigned long flags;

	lbs_deb_enter(LBS_DEB_MAIN);

	netif_stop_queue(priv->dev);
	netif_carrier_off(priv->dev);

1247
	lbs_debugfs_remove_one(priv);
1248
	device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
1249 1250
	if (priv->mesh_tlv)
		device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
1251 1252

	/* Flush pending command nodes */
1253 1254
	spin_lock_irqsave(&priv->driver_lock, flags);
	list_for_each_entry(cmdnode, &priv->cmdpendingq, list) {
1255
		cmdnode->result = -ENOENT;
1256 1257 1258
		cmdnode->cmdwaitqwoken = 1;
		wake_up_interruptible(&cmdnode->cmdwait_q);
	}
1259
	spin_unlock_irqrestore(&priv->driver_lock, flags);
1260 1261 1262 1263

	unregister_netdev(dev);

	lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
1264
	return ret;
1265
}
1266
EXPORT_SYMBOL_GPL(lbs_stop_card);
1267

1268

1269 1270 1271
/**
 * @brief This function adds mshX interface
 *
1272
 *  @param priv    A pointer to the struct lbs_private structure
1273 1274
 *  @return 	   0 if successful, -X otherwise
 */
1275
static int lbs_add_mesh(struct lbs_private *priv)
1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290
{
	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;
	}
	mesh_dev->priv = priv;
	priv->mesh_dev = mesh_dev;

1291
	mesh_dev->open = lbs_dev_open;
1292
	mesh_dev->hard_start_xmit = lbs_hard_start_xmit;
1293
	mesh_dev->stop = lbs_mesh_stop;
1294 1295 1296
	mesh_dev->get_stats = lbs_get_stats;
	mesh_dev->set_mac_address = lbs_set_mac_address;
	mesh_dev->ethtool_ops = &lbs_ethtool_ops;
1297 1298
	memcpy(mesh_dev->dev_addr, priv->dev->dev_addr,
			sizeof(priv->dev->dev_addr));
1299

1300
	SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent);
1301

1302
#ifdef	WIRELESS_EXT
1303
	mesh_dev->wireless_handlers = (struct iw_handler_def *)&mesh_handler_def;
1304 1305 1306 1307 1308 1309 1310 1311
#endif
	/* Register virtual mesh interface */
	ret = register_netdev(mesh_dev);
	if (ret) {
		lbs_pr_err("cannot register mshX virtual interface\n");
		goto err_free;
	}

1312
	ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329
	if (ret)
		goto err_unregister;

	/* 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;
}
1330
EXPORT_SYMBOL_GPL(lbs_add_mesh);
1331

1332

1333
static void lbs_remove_mesh(struct lbs_private *priv)
1334 1335 1336
{
	struct net_device *mesh_dev;

1337
	lbs_deb_enter(LBS_DEB_MAIN);
1338 1339 1340 1341 1342

	if (!priv)
		goto out;

	mesh_dev = priv->mesh_dev;
1343 1344
	if (!mesh_dev)
		goto out;
1345 1346

	netif_stop_queue(mesh_dev);
1347
	netif_carrier_off(priv->mesh_dev);
1348

1349
	sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
1350 1351
	unregister_netdev(mesh_dev);

1352
	priv->mesh_dev = NULL;
1353 1354 1355
	free_netdev(mesh_dev);

out:
1356
	lbs_deb_leave(LBS_DEB_MAIN);
1357
}
1358
EXPORT_SYMBOL_GPL(lbs_remove_mesh);
1359

1360 1361 1362 1363 1364 1365 1366 1367 1368
/**
 *  @brief This function finds the CFP in
 *  region_cfp_table based on region and band parameter.
 *
 *  @param region  The region code
 *  @param band	   The band
 *  @param cfp_no  A pointer to CFP number
 *  @return 	   A pointer to CFP
 */
1369
struct chan_freq_power *lbs_get_region_cfp_table(u8 region, u8 band, int *cfp_no)
1370 1371 1372
{
	int i, end;

1373
	lbs_deb_enter(LBS_DEB_MAIN);
1374

1375
	end = ARRAY_SIZE(region_cfp_table);
1376 1377

	for (i = 0; i < end ; i++) {
1378
		lbs_deb_main("region_cfp_table[i].region=%d\n",
1379 1380 1381
			region_cfp_table[i].region);
		if (region_cfp_table[i].region == region) {
			*cfp_no = region_cfp_table[i].cfp_no_BG;
1382
			lbs_deb_leave(LBS_DEB_MAIN);
1383 1384 1385 1386
			return region_cfp_table[i].cfp_BG;
		}
	}

1387
	lbs_deb_leave_args(LBS_DEB_MAIN, "ret NULL");
1388 1389 1390
	return NULL;
}

1391
int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band)
1392
{
1393
	int ret = 0;
1394 1395 1396 1397 1398
	int i = 0;

	struct chan_freq_power *cfp;
	int cfp_no;

1399
	lbs_deb_enter(LBS_DEB_MAIN);
1400

1401
	memset(priv->region_channel, 0, sizeof(priv->region_channel));
1402 1403

	{
1404
		cfp = lbs_get_region_cfp_table(region, band, &cfp_no);
1405
		if (cfp != NULL) {
1406 1407
			priv->region_channel[i].nrcfp = cfp_no;
			priv->region_channel[i].CFP = cfp;
1408
		} else {
1409
			lbs_deb_main("wrong region code %#x in band B/G\n",
1410
			       region);
1411 1412
			ret = -1;
			goto out;
1413
		}
1414 1415 1416
		priv->region_channel[i].valid = 1;
		priv->region_channel[i].region = region;
		priv->region_channel[i].band = band;
1417 1418
		i++;
	}
1419 1420 1421
out:
	lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
	return ret;
1422 1423 1424 1425 1426 1427 1428 1429 1430 1431
}

/**
 *  @brief This function handles the interrupt. it will change PS
 *  state if applicable. it will wake up main_thread to handle
 *  the interrupt event as well.
 *
 *  @param dev     A pointer to net_device structure
 *  @return 	   n/a
 */
1432
void lbs_interrupt(struct lbs_private *priv)
1433
{
1434
	lbs_deb_enter(LBS_DEB_THREAD);
1435

1436 1437
	lbs_deb_thread("lbs_interrupt: intcounter=%d\n", priv->intcounter);

1438
	priv->intcounter++;
1439

1440
	if (priv->psstate == PS_STATE_SLEEP)
1441
		priv->psstate = PS_STATE_AWAKE;
1442

1443
	wake_up_interruptible(&priv->waitq);
1444

1445
	lbs_deb_leave(LBS_DEB_THREAD);
1446
}
1447
EXPORT_SYMBOL_GPL(lbs_interrupt);
1448

1449
int lbs_reset_device(struct lbs_private *priv)
1450 1451 1452 1453
{
	int ret;

	lbs_deb_enter(LBS_DEB_MAIN);
1454
	ret = lbs_prepare_and_send_command(priv, CMD_802_11_RESET,
1455 1456 1457 1458 1459 1460
				    CMD_ACT_HALT, 0, 0, NULL);
	msleep_interruptible(10);

	lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
	return ret;
}
1461
EXPORT_SYMBOL_GPL(lbs_reset_device);
1462

1463
static int __init lbs_init_module(void)
1464
{
1465
	lbs_deb_enter(LBS_DEB_MAIN);
1466
	lbs_debugfs_init();
1467 1468
	lbs_deb_leave(LBS_DEB_MAIN);
	return 0;
1469 1470
}

1471
static void __exit lbs_exit_module(void)
1472
{
1473
	lbs_deb_enter(LBS_DEB_MAIN);
1474

1475
	lbs_debugfs_remove();
1476

1477
	lbs_deb_leave(LBS_DEB_MAIN);
1478 1479
}

1480 1481 1482 1483
/*
 * rtap interface support fuctions
 */

1484
static int lbs_rtap_open(struct net_device *dev)
1485
{
1486
	/* Yes, _stop_ the queue. Because we don't support injection */
1487 1488 1489 1490 1491
        netif_carrier_off(dev);
        netif_stop_queue(dev);
        return 0;
}

1492
static int lbs_rtap_stop(struct net_device *dev)
1493 1494 1495 1496
{
        return 0;
}

1497
static int lbs_rtap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
1498 1499
{
        netif_stop_queue(dev);
1500
        return NETDEV_TX_BUSY;
1501 1502
}

1503
static struct net_device_stats *lbs_rtap_get_stats(struct net_device *dev)
1504
{
1505
	struct lbs_private *priv = dev->priv;
1506
	return &priv->stats;
1507 1508 1509
}


1510
static void lbs_remove_rtap(struct lbs_private *priv)
1511 1512 1513 1514
{
	if (priv->rtap_net_dev == NULL)
		return;
	unregister_netdev(priv->rtap_net_dev);
1515
	free_netdev(priv->rtap_net_dev);
1516 1517 1518
	priv->rtap_net_dev = NULL;
}

1519
static int lbs_add_rtap(struct lbs_private *priv)
1520 1521
{
	int rc = 0;
1522
	struct net_device *rtap_dev;
1523 1524 1525 1526

	if (priv->rtap_net_dev)
		return -EPERM;

1527 1528
	rtap_dev = alloc_netdev(0, "rtap%d", ether_setup);
	if (rtap_dev == NULL)
1529 1530
		return -ENOMEM;

1531
	memcpy(rtap_dev->dev_addr, priv->current_addr, ETH_ALEN);
1532 1533 1534 1535 1536 1537 1538
	rtap_dev->type = ARPHRD_IEEE80211_RADIOTAP;
	rtap_dev->open = lbs_rtap_open;
	rtap_dev->stop = lbs_rtap_stop;
	rtap_dev->get_stats = lbs_rtap_get_stats;
	rtap_dev->hard_start_xmit = lbs_rtap_hard_start_xmit;
	rtap_dev->set_multicast_list = lbs_set_multicast_list;
	rtap_dev->priv = priv;
1539

1540
	rc = register_netdev(rtap_dev);
1541
	if (rc) {
1542
		free_netdev(rtap_dev);
1543 1544
		return rc;
	}
1545
	priv->rtap_net_dev = rtap_dev;
1546 1547 1548 1549 1550

	return 0;
}


1551 1552
module_init(lbs_init_module);
module_exit(lbs_exit_module);
1553

1554
MODULE_DESCRIPTION("Libertas WLAN Driver Library");
1555 1556
MODULE_AUTHOR("Marvell International Ltd.");
MODULE_LICENSE("GPL");