main.c 35.5 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 12
#include <linux/delay.h>
#include <linux/freezer.h>
#include <linux/etherdevice.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
13
#include <linux/kthread.h>
14 15

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

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

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

34 35

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


41 42 43 44 45
#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 */
46 47 48 49

/* Format { channel, frequency (MHz), maxtxpower } */
/* band: 'B/G', region: USA FCC/Canada IC */
static struct chan_freq_power channel_freq_power_US_BG[] = {
50 51 52 53 54 55 56 57 58 59 60
	{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}
61 62 63 64
};

/* band: 'B/G', region: Europe ETSI */
static struct chan_freq_power channel_freq_power_EU_BG[] = {
65 66 67 68 69 70 71 72 73 74 75 76 77
	{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}
78 79 80 81
};

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

/* band: 'B/G', region: France */
static struct chan_freq_power channel_freq_power_FR_BG[] = {
88 89 90 91
	{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}
92 93 94 95
};

/* band: 'B/G', region: Japan */
static struct chan_freq_power channel_freq_power_JPN_BG[] = {
96 97 98 99 100 101 102 103 104 105 106 107 108 109
	{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}
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
};

/**
 * 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,
127
	 ARRAY_SIZE(channel_freq_power_US_BG),
128 129 130 131
	 }
	,
	{0x20,			/*CANADA IC */
	 channel_freq_power_US_BG,
132
	 ARRAY_SIZE(channel_freq_power_US_BG),
133 134 135
	 }
	,
	{0x30, /*EU*/ channel_freq_power_EU_BG,
136
	 ARRAY_SIZE(channel_freq_power_EU_BG),
137 138 139
	 }
	,
	{0x31, /*SPAIN*/ channel_freq_power_SPN_BG,
140
	 ARRAY_SIZE(channel_freq_power_SPN_BG),
141 142 143
	 }
	,
	{0x32, /*FRANCE*/ channel_freq_power_FR_BG,
144
	 ARRAY_SIZE(channel_freq_power_FR_BG),
145 146 147
	 }
	,
	{0x40, /*JAPAN*/ channel_freq_power_JPN_BG,
148
	 ARRAY_SIZE(channel_freq_power_JPN_BG),
149 150 151 152 153 154
	 }
	,
/*Add new region here */
};

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

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

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

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

/**
 * Attributes exported through sysfs
 */

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

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

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

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

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

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

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

252 253 254
	return strlen(buf);
}

255 256
static int lbs_add_rtap(struct lbs_private *priv);
static void lbs_remove_rtap(struct lbs_private *priv);
257 258 259
static int lbs_add_mesh(struct lbs_private *priv);
static void lbs_remove_mesh(struct lbs_private *priv);
  
260 261 262 263

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

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

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

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

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

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

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

/**
318 319
 * lbs_rtap attribute to be exported per ethX interface
 * through sysfs (/sys/class/net/ethX/lbs_rtap)
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 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364
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;

	ret = lbs_mesh_config(priv, enable);
	if (ret)
		return ret;
		
	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);
365

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

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

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

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

392
	spin_lock_irq(&priv->driver_lock);
393

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

399 400 401 402 403 404 405 406 407
	if (dev == priv->mesh_dev) {
		priv->mesh_open = 1;
		priv->mesh_connect_status = LBS_CONNECTED;
		netif_carrier_on(dev);
	} else {
		priv->infra_open = 1;
		
		if (priv->connect_status == LBS_CONNECTED)
			netif_carrier_on(dev);
408
		else
409
			netif_carrier_off(dev);
410
	}
411

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

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

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

430 431
	spin_lock_irq(&priv->driver_lock);

432
	priv->mesh_open = 0;
433 434 435 436 437 438 439
	priv->mesh_connect_status = LBS_DISCONNECTED;

	netif_stop_queue(dev);
	netif_carrier_off(dev);
	
	spin_unlock_irq(&priv->driver_lock);
	return 0;
440 441 442 443 444 445 446 447
}

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

452 453
	spin_lock_irq(&priv->driver_lock);

454
	priv->infra_open = 0;
455 456 457 458 459

	netif_stop_queue(dev);
	
	spin_unlock_irq(&priv->driver_lock);
	return 0;
460 461
}

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

466
	lbs_deb_enter(LBS_DEB_TX);
467

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

	dev->trans_start = jiffies;

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

480
	lbs_deb_leave(LBS_DEB_TX);
481 482
}

483 484
void lbs_host_to_card_done(struct lbs_private *priv)
{
485 486 487
	unsigned long flags;

	spin_lock_irqsave(&priv->driver_lock, flags);
488 489 490 491

	priv->dnld_sent = DNLD_RES_RECEIVED;

	/* Wake main thread if commands are pending */
492
	if (!priv->cur_cmd)
493 494
		wake_up_interruptible(&priv->waitq);

D
David Woodhouse 已提交
495
	/* Don't wake netif queues if we're in monitor mode and
496 497 498 499 500
	   a TX packet is already pending, or if there are commands
	   queued to be sent. */
	if (!priv->currenttxskb && list_empty(&priv->cmdpendingq)) {
		if (priv->dev && priv->connect_status == LBS_CONNECTED)
			netif_wake_queue(priv->dev);
501

502 503 504 505
		if (priv->mesh_dev && priv->mesh_connect_status == LBS_CONNECTED)
			netif_wake_queue(priv->mesh_dev);
	}
	spin_unlock_irqrestore(&priv->driver_lock, flags);
506 507 508
}
EXPORT_SYMBOL_GPL(lbs_host_to_card_done);

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

	return &priv->stats;
}

522
static int lbs_set_mac_address(struct net_device *dev, void *addr)
523 524
{
	int ret = 0;
525
	struct lbs_private *priv = (struct lbs_private *) dev->priv;
526 527
	struct sockaddr *phwaddr = addr;

528
	lbs_deb_enter(LBS_DEB_NET);
529

530 531 532
	/* In case it was called from the mesh device */
	dev = priv->dev ;

533
	memset(priv->current_addr, 0, ETH_ALEN);
534 535

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

538
	lbs_deb_hex(LBS_DEB_NET, "addr", phwaddr->sa_data, ETH_ALEN);
539
	memcpy(priv->current_addr, phwaddr->sa_data, ETH_ALEN);
540

541
	ret = lbs_prepare_and_send_command(priv, CMD_802_11_MAC_ADDRESS,
542 543
				    CMD_ACT_SET,
				    CMD_OPTION_WAITFORRSP, 0, NULL);
544 545

	if (ret) {
546
		lbs_deb_net("set MAC address failed\n");
547 548 549 550
		ret = -1;
		goto done;
	}

551 552
	lbs_deb_hex(LBS_DEB_NET, "priv->macaddr", priv->current_addr, ETH_ALEN);
	memcpy(dev->dev_addr, priv->current_addr, ETH_ALEN);
553
	if (priv->mesh_dev)
554
		memcpy(priv->mesh_dev->dev_addr, priv->current_addr, ETH_ALEN);
555 556

done:
557
	lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
558 559 560
	return ret;
}

561
static int lbs_copy_multicast_address(struct lbs_private *priv,
562 563 564 565 566 567
				     struct net_device *dev)
{
	int i = 0;
	struct dev_mc_list *mcptr = dev->mc_list;

	for (i = 0; i < dev->mc_count; i++) {
568
		memcpy(&priv->multicastlist[i], mcptr->dmi_addr, ETH_ALEN);
569 570 571 572 573 574 575
		mcptr = mcptr->next;
	}

	return i;

}

576
static void lbs_set_multicast_list(struct net_device *dev)
577
{
578
	struct lbs_private *priv = dev->priv;
579
	int oldpacketfilter;
580
	DECLARE_MAC_BUF(mac);
581

582
	lbs_deb_enter(LBS_DEB_NET);
583

584
	oldpacketfilter = priv->currentpacketfilter;
585 586

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

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

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

617
				priv->currentpacketfilter |=
618
				    CMD_ACT_MAC_MULTICAST_ENABLE;
619

620 621
				priv->nr_of_multicastmacaddr =
				    lbs_copy_multicast_address(priv, dev);
622

623
				lbs_deb_net("multicast addresses: %d\n",
624 625 626
				       dev->mc_count);

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

640
	if (priv->currentpacketfilter != oldpacketfilter) {
641
		lbs_set_mac_packet_filter(priv);
642 643
	}

644
	lbs_deb_leave(LBS_DEB_NET);
645 646 647
}

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

662
	lbs_deb_enter(LBS_DEB_THREAD);
663 664 665

	init_waitqueue_entry(&wait, current);

666
	set_freezable();
667

668
	for (;;) {
669 670
		int shouldsleep;

671
		lbs_deb_thread( "main-thread 111: intcounter=%d currenttxskb=%p dnld_sent=%d\n",
672
				priv->intcounter, priv->currenttxskb, priv->dnld_sent);
673

674
		add_wait_queue(&priv->waitq, &wait);
675
		set_current_state(TASK_INTERRUPTIBLE);
676
		spin_lock_irq(&priv->driver_lock);
677

678 679 680 681 682 683
		if (priv->surpriseremoved)
			shouldsleep = 0;	/* Bye */
		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 */
684 685
		else if (!priv->fw_ready)
			shouldsleep = 1;	/* Firmware not ready. We're waiting for it */
686 687
		else if (priv->dnld_sent)
			shouldsleep = 1;	/* Something is en route to the device already */
688 689
		else if (priv->tx_pending_len > 0)
			shouldsleep = 0;	/* We've a packet to send */
690 691 692 693 694 695 696 697
		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) {
698
			lbs_deb_thread("main-thread sleeping... Conn=%d IntC=%d PS_mode=%d PS_State=%d\n",
699 700 701
				       priv->connect_status, priv->intcounter,
				       priv->psmode, priv->psstate);
			spin_unlock_irq(&priv->driver_lock);
702 703
			schedule();
		} else
704
			spin_unlock_irq(&priv->driver_lock);
705

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

		set_current_state(TASK_RUNNING);
710
		remove_wait_queue(&priv->waitq, &wait);
711 712
		try_to_freeze();

713
		lbs_deb_thread("main-thread 333: intcounter=%d currenttxskb=%p dnld_sent=%d\n",
714
			       priv->intcounter, priv->currenttxskb, priv->dnld_sent);
715

716
		if (kthread_should_stop() || priv->surpriseremoved) {
717
			lbs_deb_thread("main-thread: break from main thread: surpriseremoved=0x%x\n",
718
				       priv->surpriseremoved);
719 720 721 722
			break;
		}


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
		}

		/* Any Card Event */
753
		if (priv->hisregcpy & MRVDRV_CARDEVENT) {
754
			lbs_deb_thread("main-thread: Card Event Activity\n");
755

756
			priv->hisregcpy &= ~MRVDRV_CARDEVENT;
757

758
			if (priv->hw_read_event_cause(priv)) {
759
				lbs_pr_alert("main-thread: hw_read_event_cause failed\n");
760
				spin_unlock_irq(&priv->driver_lock);
761 762
				continue;
			}
763
			spin_unlock_irq(&priv->driver_lock);
764
			lbs_process_event(priv);
765
		} else
766
			spin_unlock_irq(&priv->driver_lock);
767

768 769 770
		if (!priv->fw_ready)
			continue;

771
		/* Check if we need to confirm Sleep Request received previously */
772 773 774
		if (priv->psstate == PS_STATE_PRE_SLEEP &&
		    !priv->dnld_sent && !priv->cur_cmd) {
			if (priv->connect_status == LBS_CONNECTED) {
775
				lbs_deb_thread("main_thread: PRE_SLEEP--intcounter=%d currenttxskb=%p dnld_sent=%d cur_cmd=%p, confirm now\n",
776
					       priv->intcounter, priv->currenttxskb, priv->dnld_sent, priv->cur_cmd);
777

778
				lbs_ps_confirm_sleep(priv, (u16) priv->psmode);
779 780 781 782 783 784
			} else {
				/* workaround for firmware sending
				 * deauth/linkloss event immediately
				 * after sleep request; remove this
				 * after firmware fixes it
				 */
785
				priv->psstate = PS_STATE_AWAKE;
786
				lbs_pr_alert("main-thread: ignore PS_SleepConfirm in non-connected state\n");
787 788 789 790 791 792
			}
		}

		/* The PS state is changed during processing of Sleep Request
		 * event above
		 */
793 794
		if ((priv->psstate == PS_STATE_SLEEP) ||
		    (priv->psstate == PS_STATE_PRE_SLEEP))
795 796 797
			continue;

		/* Execute the next command */
798
		if (!priv->dnld_sent && !priv->cur_cmd)
799
			lbs_execute_next_command(priv);
800 801

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

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

830 831
	del_timer(&priv->command_timer);
	wake_up_all(&priv->cmd_pending);
832

833
	lbs_deb_leave(LBS_DEB_THREAD);
834 835 836
	return 0;
}

H
Holger Schurig 已提交
837 838 839 840 841
/**
 *  @brief This function downloads firmware image, gets
 *  HW spec from firmware and set basic parameters to
 *  firmware.
 *
842
 *  @param priv    A pointer to struct lbs_private structure
H
Holger Schurig 已提交
843 844
 *  @return 	   0 or -1
 */
845
static int lbs_setup_firmware(struct lbs_private *priv)
H
Holger Schurig 已提交
846 847 848 849 850 851 852 853
{
	int ret = -1;

	lbs_deb_enter(LBS_DEB_FW);

	/*
	 * Read MAC address from HW
	 */
854
	memset(priv->current_addr, 0xff, ETH_ALEN);
855
	ret = lbs_update_hw_spec(priv);
H
Holger Schurig 已提交
856 857 858 859 860
	if (ret) {
		ret = -1;
		goto done;
	}

861
	lbs_set_mac_packet_filter(priv);
H
Holger Schurig 已提交
862

863 864
	ret = lbs_get_data_rate(priv);
	if (ret < 0) {
H
Holger Schurig 已提交
865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880
		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)
{
881
	struct lbs_private *priv = (struct lbs_private *)data;
882
	struct cmd_ctrl_node *node;
H
Holger Schurig 已提交
883 884
	unsigned long flags;

885 886
	node = priv->cur_cmd;
	if (node == NULL) {
H
Holger Schurig 已提交
887 888 889 890
		lbs_deb_fw("ptempnode empty\n");
		return;
	}

891
	if (!node->cmdbuf) {
H
Holger Schurig 已提交
892 893 894 895
		lbs_deb_fw("cmd is NULL\n");
		return;
	}

896
	lbs_pr_info("command %x timed out\n", le16_to_cpu(node->cmdbuf->command));
H
Holger Schurig 已提交
897

898
	if (!priv->fw_ready)
H
Holger Schurig 已提交
899 900
		return;

901 902 903
	spin_lock_irqsave(&priv->driver_lock, flags);
	priv->cur_cmd = NULL;
	spin_unlock_irqrestore(&priv->driver_lock, flags);
H
Holger Schurig 已提交
904 905

	lbs_deb_fw("re-sending same command because of timeout\n");
906
	lbs_queue_cmd(priv, node, 0);
H
Holger Schurig 已提交
907 908 909 910 911 912

	wake_up_interruptible(&priv->waitq);

	return;
}

913
static int lbs_init_adapter(struct lbs_private *priv)
914
{
H
Holger Schurig 已提交
915
	size_t bufsize;
916
	int i, ret = 0;
H
Holger Schurig 已提交
917 918 919

	/* Allocate buffer to store the BSSID list */
	bufsize = MAX_NETWORK_COUNT * sizeof(struct bss_descriptor);
920 921
	priv->networks = kzalloc(bufsize, GFP_KERNEL);
	if (!priv->networks) {
H
Holger Schurig 已提交
922
		lbs_pr_err("Out of memory allocating beacons\n");
923 924
		ret = -1;
		goto out;
H
Holger Schurig 已提交
925 926
	}

927
	/* Initialize scan result lists */
928 929
	INIT_LIST_HEAD(&priv->network_free_list);
	INIT_LIST_HEAD(&priv->network_list);
930
	for (i = 0; i < MAX_NETWORK_COUNT; i++) {
931 932
		list_add_tail(&priv->networks[i].list,
			      &priv->network_free_list);
933
	}
H
Holger Schurig 已提交
934

935 936
	priv->lbs_ps_confirm_sleep.seqnum = cpu_to_le16(++priv->seqnum);
	priv->lbs_ps_confirm_sleep.command =
H
Holger Schurig 已提交
937
	    cpu_to_le16(CMD_802_11_PS_MODE);
938
	priv->lbs_ps_confirm_sleep.size =
H
Holger Schurig 已提交
939
	    cpu_to_le16(sizeof(struct PS_CMD_ConfirmSleep));
940
	priv->lbs_ps_confirm_sleep.action =
H
Holger Schurig 已提交
941 942
	    cpu_to_le16(CMD_SUBCMD_SLEEP_CONFIRMED);

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

945 946 947 948 949 950 951 952 953 954 955
	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 已提交
956

957
	mutex_init(&priv->lock);
H
Holger Schurig 已提交
958

959
	setup_timer(&priv->command_timer, command_timer_fn,
960
	            (unsigned long)priv);
H
Holger Schurig 已提交
961

962 963
	INIT_LIST_HEAD(&priv->cmdfreeq);
	INIT_LIST_HEAD(&priv->cmdpendingq);
H
Holger Schurig 已提交
964

965 966
	spin_lock_init(&priv->driver_lock);
	init_waitqueue_head(&priv->cmd_pending);
H
Holger Schurig 已提交
967

968
	/* Allocate the command buffers */
969
	if (lbs_allocate_cmd_buffer(priv)) {
970 971 972
		lbs_pr_err("Out of memory allocating command buffers\n");
		ret = -1;
	}
H
Holger Schurig 已提交
973

974 975 976
out:
	return ret;
}
H
Holger Schurig 已提交
977

978
static void lbs_free_adapter(struct lbs_private *priv)
979 980
{
	lbs_deb_fw("free command buffer\n");
981
	lbs_free_cmd_buffer(priv);
H
Holger Schurig 已提交
982

983
	lbs_deb_fw("free command_timer\n");
984
	del_timer(&priv->command_timer);
985 986

	lbs_deb_fw("free scan results table\n");
987 988
	kfree(priv->networks);
	priv->networks = NULL;
H
Holger Schurig 已提交
989 990
}

991 992
/**
 * @brief This function adds the card. it will probe the
993
 * card, allocate the lbs_priv and initialize the device.
994 995
 *
 *  @param card    A pointer to card
996
 *  @return 	   A pointer to struct lbs_private structure
997
 */
998
struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
999 1000
{
	struct net_device *dev = NULL;
1001
	struct lbs_private *priv = NULL;
1002

1003
	lbs_deb_enter(LBS_DEB_NET);
1004 1005

	/* Allocate an Ethernet device and register it */
1006 1007
	dev = alloc_etherdev(sizeof(struct lbs_private));
	if (!dev) {
1008
		lbs_pr_err("init ethX device failed\n");
1009
		goto done;
1010
	}
1011
	priv = dev->priv;
1012

1013
	if (lbs_init_adapter(priv)) {
1014 1015 1016 1017
		lbs_pr_err("failed to initialize adapter structure.\n");
		goto err_init_adapter;
	}

1018 1019
	priv->dev = dev;
	priv->card = card;
1020 1021 1022 1023
	priv->mesh_open = 0;
	priv->infra_open = 0;

	/* Setup the OS Interface to our functions */
1024
	dev->open = lbs_dev_open;
1025
	dev->hard_start_xmit = lbs_hard_start_xmit;
1026
	dev->stop = lbs_eth_stop;
1027 1028 1029
	dev->set_mac_address = lbs_set_mac_address;
	dev->tx_timeout = lbs_tx_timeout;
	dev->get_stats = lbs_get_stats;
1030
	dev->watchdog_timeo = 5 * HZ;
1031
	dev->ethtool_ops = &lbs_ethtool_ops;
1032
#ifdef	WIRELESS_EXT
1033
	dev->wireless_handlers = (struct iw_handler_def *)&lbs_handler_def;
1034 1035
#endif
	dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
1036
	dev->set_multicast_list = lbs_set_multicast_list;
1037

1038 1039
	SET_NETDEV_DEV(dev, dmdev);

1040
	priv->rtap_net_dev = NULL;
1041 1042 1043

	lbs_deb_thread("Starting main thread...\n");
	init_waitqueue_head(&priv->waitq);
1044
	priv->main_thread = kthread_run(lbs_thread, dev, "lbs_main");
1045 1046
	if (IS_ERR(priv->main_thread)) {
		lbs_deb_thread("Error creating main thread.\n");
1047
		goto err_init_adapter;
1048 1049
	}

1050 1051 1052 1053
	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);
1054

1055 1056 1057
	sprintf(priv->mesh_ssid, "mesh");
	priv->mesh_ssid_len = 4;

1058 1059
	goto done;

1060
err_init_adapter:
1061
	lbs_free_adapter(priv);
1062
	free_netdev(dev);
1063
	priv = NULL;
1064

1065 1066 1067 1068
done:
	lbs_deb_leave_args(LBS_DEB_NET, "priv %p", priv);
	return priv;
}
1069
EXPORT_SYMBOL_GPL(lbs_add_card);
1070

1071

1072
int lbs_remove_card(struct lbs_private *priv)
1073
{
1074
	struct net_device *dev = priv->dev;
1075
	union iwreq_data wrqu;
1076 1077

	lbs_deb_enter(LBS_DEB_MAIN);
1078

1079
	lbs_remove_mesh(priv);
1080
	lbs_remove_rtap(priv);
1081

1082
	dev = priv->dev;
1083

1084 1085 1086
	cancel_delayed_work(&priv->scan_work);
	cancel_delayed_work(&priv->assoc_work);
	destroy_workqueue(priv->work_thread);
1087

1088 1089
	if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
		priv->psmode = LBS802_11POWERMODECAM;
1090
		lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
1091 1092
	}

1093 1094 1095 1096 1097
	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 */
1098
	priv->surpriseremoved = 1;
1099 1100
	kthread_stop(priv->main_thread);

1101
	lbs_free_adapter(priv);
1102 1103 1104 1105 1106 1107 1108

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

	lbs_deb_leave(LBS_DEB_MAIN);
	return 0;
}
1109
EXPORT_SYMBOL_GPL(lbs_remove_card);
1110 1111


1112
int lbs_start_card(struct lbs_private *priv)
1113 1114 1115 1116 1117 1118 1119
{
	struct net_device *dev = priv->dev;
	int ret = -1;

	lbs_deb_enter(LBS_DEB_MAIN);

	/* poke the firmware */
1120
	ret = lbs_setup_firmware(priv);
1121 1122 1123 1124
	if (ret)
		goto done;

	/* init 802.11d */
1125
	lbs_init_11d(priv);
1126 1127

	if (register_netdev(dev)) {
1128
		lbs_pr_err("cannot register ethX device\n");
1129
		goto done;
1130
	}
1131 1132
	if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
		lbs_pr_err("cannot register lbs_rtap attribute\n");
1133 1134
	if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
		lbs_pr_err("cannot register lbs_mesh attribute\n");
1135

1136
	lbs_debugfs_init_one(priv, dev);
1137

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

1140
	ret = 0;
1141

1142
done:
1143 1144 1145
	lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
	return ret;
}
1146
EXPORT_SYMBOL_GPL(lbs_start_card);
1147 1148


1149
int lbs_stop_card(struct lbs_private *priv)
1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160
{
	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);

1161
	lbs_debugfs_remove_one(priv);
1162
	device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
1163
	device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
1164 1165

	/* Flush pending command nodes */
1166 1167
	spin_lock_irqsave(&priv->driver_lock, flags);
	list_for_each_entry(cmdnode, &priv->cmdpendingq, list) {
1168 1169 1170
		cmdnode->cmdwaitqwoken = 1;
		wake_up_interruptible(&cmdnode->cmdwait_q);
	}
1171
	spin_unlock_irqrestore(&priv->driver_lock, flags);
1172 1173 1174 1175

	unregister_netdev(dev);

	lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
1176
	return ret;
1177
}
1178
EXPORT_SYMBOL_GPL(lbs_stop_card);
1179

1180

1181 1182 1183
/**
 * @brief This function adds mshX interface
 *
1184
 *  @param priv    A pointer to the struct lbs_private structure
1185 1186
 *  @return 	   0 if successful, -X otherwise
 */
1187
static int lbs_add_mesh(struct lbs_private *priv)
1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202
{
	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;

1203
	mesh_dev->open = lbs_dev_open;
1204
	mesh_dev->hard_start_xmit = lbs_hard_start_xmit;
1205
	mesh_dev->stop = lbs_mesh_stop;
1206 1207 1208
	mesh_dev->get_stats = lbs_get_stats;
	mesh_dev->set_mac_address = lbs_set_mac_address;
	mesh_dev->ethtool_ops = &lbs_ethtool_ops;
1209 1210
	memcpy(mesh_dev->dev_addr, priv->dev->dev_addr,
			sizeof(priv->dev->dev_addr));
1211

1212
	SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent);
1213

1214
#ifdef	WIRELESS_EXT
1215
	mesh_dev->wireless_handlers = (struct iw_handler_def *)&mesh_handler_def;
1216 1217 1218 1219 1220 1221 1222 1223
#endif
	/* Register virtual mesh interface */
	ret = register_netdev(mesh_dev);
	if (ret) {
		lbs_pr_err("cannot register mshX virtual interface\n");
		goto err_free;
	}

1224
	ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241
	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;
}
1242
EXPORT_SYMBOL_GPL(lbs_add_mesh);
1243

1244

1245
static void lbs_remove_mesh(struct lbs_private *priv)
1246 1247 1248
{
	struct net_device *mesh_dev;

1249
	lbs_deb_enter(LBS_DEB_MAIN);
1250 1251 1252 1253 1254

	if (!priv)
		goto out;

	mesh_dev = priv->mesh_dev;
1255 1256
	if (!mesh_dev)
		goto out;
1257 1258

	netif_stop_queue(mesh_dev);
1259
	netif_carrier_off(priv->mesh_dev);
1260

1261
	sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
1262 1263
	unregister_netdev(mesh_dev);

1264
	priv->mesh_dev = NULL;
1265 1266 1267
	free_netdev(mesh_dev);

out:
1268
	lbs_deb_leave(LBS_DEB_MAIN);
1269
}
1270
EXPORT_SYMBOL_GPL(lbs_remove_mesh);
1271

1272 1273 1274 1275 1276 1277 1278 1279 1280
/**
 *  @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
 */
1281
struct chan_freq_power *lbs_get_region_cfp_table(u8 region, u8 band, int *cfp_no)
1282 1283 1284
{
	int i, end;

1285
	lbs_deb_enter(LBS_DEB_MAIN);
1286

1287
	end = ARRAY_SIZE(region_cfp_table);
1288 1289

	for (i = 0; i < end ; i++) {
1290
		lbs_deb_main("region_cfp_table[i].region=%d\n",
1291 1292 1293
			region_cfp_table[i].region);
		if (region_cfp_table[i].region == region) {
			*cfp_no = region_cfp_table[i].cfp_no_BG;
1294
			lbs_deb_leave(LBS_DEB_MAIN);
1295 1296 1297 1298
			return region_cfp_table[i].cfp_BG;
		}
	}

1299
	lbs_deb_leave_args(LBS_DEB_MAIN, "ret NULL");
1300 1301 1302
	return NULL;
}

1303
int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band)
1304
{
1305
	int ret = 0;
1306 1307 1308 1309 1310
	int i = 0;

	struct chan_freq_power *cfp;
	int cfp_no;

1311
	lbs_deb_enter(LBS_DEB_MAIN);
1312

1313
	memset(priv->region_channel, 0, sizeof(priv->region_channel));
1314 1315

	{
1316
		cfp = lbs_get_region_cfp_table(region, band, &cfp_no);
1317
		if (cfp != NULL) {
1318 1319
			priv->region_channel[i].nrcfp = cfp_no;
			priv->region_channel[i].CFP = cfp;
1320
		} else {
1321
			lbs_deb_main("wrong region code %#x in band B/G\n",
1322
			       region);
1323 1324
			ret = -1;
			goto out;
1325
		}
1326 1327 1328
		priv->region_channel[i].valid = 1;
		priv->region_channel[i].region = region;
		priv->region_channel[i].band = band;
1329 1330
		i++;
	}
1331 1332 1333
out:
	lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
	return ret;
1334 1335 1336 1337 1338 1339 1340 1341 1342 1343
}

/**
 *  @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
 */
1344
void lbs_interrupt(struct lbs_private *priv)
1345
{
1346
	lbs_deb_enter(LBS_DEB_THREAD);
1347

1348 1349 1350 1351 1352 1353 1354
	lbs_deb_thread("lbs_interrupt: intcounter=%d\n", priv->intcounter);

	if (spin_trylock(&priv->driver_lock)) {
		spin_unlock(&priv->driver_lock);
		printk(KERN_CRIT "%s called without driver_lock held\n", __func__);
		WARN_ON(1);
	}
1355

1356
	priv->intcounter++;
1357

1358
	if (priv->psstate == PS_STATE_SLEEP)
1359
		priv->psstate = PS_STATE_AWAKE;
1360

1361
	wake_up_interruptible(&priv->waitq);
1362

1363
	lbs_deb_leave(LBS_DEB_THREAD);
1364
}
1365
EXPORT_SYMBOL_GPL(lbs_interrupt);
1366

1367
int lbs_reset_device(struct lbs_private *priv)
1368 1369 1370 1371
{
	int ret;

	lbs_deb_enter(LBS_DEB_MAIN);
1372
	ret = lbs_prepare_and_send_command(priv, CMD_802_11_RESET,
1373 1374 1375 1376 1377 1378
				    CMD_ACT_HALT, 0, 0, NULL);
	msleep_interruptible(10);

	lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
	return ret;
}
1379
EXPORT_SYMBOL_GPL(lbs_reset_device);
1380

1381
static int __init lbs_init_module(void)
1382
{
1383
	lbs_deb_enter(LBS_DEB_MAIN);
1384
	lbs_debugfs_init();
1385 1386
	lbs_deb_leave(LBS_DEB_MAIN);
	return 0;
1387 1388
}

1389
static void __exit lbs_exit_module(void)
1390
{
1391
	lbs_deb_enter(LBS_DEB_MAIN);
1392

1393
	lbs_debugfs_remove();
1394

1395
	lbs_deb_leave(LBS_DEB_MAIN);
1396 1397
}

1398 1399 1400 1401
/*
 * rtap interface support fuctions
 */

1402
static int lbs_rtap_open(struct net_device *dev)
1403
{
1404
	/* Yes, _stop_ the queue. Because we don't support injection */
1405 1406 1407 1408 1409
        netif_carrier_off(dev);
        netif_stop_queue(dev);
        return 0;
}

1410
static int lbs_rtap_stop(struct net_device *dev)
1411 1412 1413 1414
{
        return 0;
}

1415
static int lbs_rtap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
1416 1417
{
        netif_stop_queue(dev);
1418
        return NETDEV_TX_BUSY;
1419 1420
}

1421
static struct net_device_stats *lbs_rtap_get_stats(struct net_device *dev)
1422
{
1423
	struct lbs_private *priv = dev->priv;
1424
	return &priv->stats;
1425 1426 1427
}


1428
static void lbs_remove_rtap(struct lbs_private *priv)
1429 1430 1431 1432
{
	if (priv->rtap_net_dev == NULL)
		return;
	unregister_netdev(priv->rtap_net_dev);
1433
	free_netdev(priv->rtap_net_dev);
1434 1435 1436
	priv->rtap_net_dev = NULL;
}

1437
static int lbs_add_rtap(struct lbs_private *priv)
1438 1439
{
	int rc = 0;
1440
	struct net_device *rtap_dev;
1441 1442 1443 1444

	if (priv->rtap_net_dev)
		return -EPERM;

1445 1446
	rtap_dev = alloc_netdev(0, "rtap%d", ether_setup);
	if (rtap_dev == NULL)
1447 1448
		return -ENOMEM;

1449
	memcpy(rtap_dev->dev_addr, priv->current_addr, ETH_ALEN);
1450 1451 1452 1453 1454 1455 1456
	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;
1457

1458
	rc = register_netdev(rtap_dev);
1459
	if (rc) {
1460
		free_netdev(rtap_dev);
1461 1462
		return rc;
	}
1463
	priv->rtap_net_dev = rtap_dev;
1464 1465 1466 1467 1468

	return 0;
}


1469 1470
module_init(lbs_init_module);
module_exit(lbs_exit_module);
1471

1472
MODULE_DESCRIPTION("Libertas WLAN Driver Library");
1473 1474
MODULE_AUTHOR("Marvell International Ltd.");
MODULE_LICENSE("GPL");