• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500-V1.0.1.40_1.0.68/src/linux/linux-2.6/drivers/net/wireless/libertas/
1/**
2  * This file contains the major functions in WLAN
3  * driver. It includes init, exit, open, close and main
4  * thread etc..
5  */
6
7#include <linux/moduleparam.h>
8#include <linux/delay.h>
9#include <linux/freezer.h>
10#include <linux/etherdevice.h>
11#include <linux/netdevice.h>
12#include <linux/if_arp.h>
13
14#include <net/iw_handler.h>
15#include <net/ieee80211.h>
16
17#include "host.h"
18#include "decl.h"
19#include "dev.h"
20#include "wext.h"
21#include "debugfs.h"
22#include "assoc.h"
23
24#define DRIVER_RELEASE_VERSION "322.p0"
25const char libertas_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION
26#ifdef  DEBUG
27    "-dbg"
28#endif
29    "";
30
31
32/* Module parameters */
33unsigned int libertas_debug = 0;
34module_param(libertas_debug, int, 0644);
35EXPORT_SYMBOL_GPL(libertas_debug);
36
37
38#define WLAN_TX_PWR_DEFAULT		20	/*100mW */
39#define WLAN_TX_PWR_US_DEFAULT		20	/*100mW */
40#define WLAN_TX_PWR_JP_DEFAULT		16	/*50mW */
41#define WLAN_TX_PWR_FR_DEFAULT		20	/*100mW */
42#define WLAN_TX_PWR_EMEA_DEFAULT	20	/*100mW */
43
44/* Format { channel, frequency (MHz), maxtxpower } */
45/* band: 'B/G', region: USA FCC/Canada IC */
46static struct chan_freq_power channel_freq_power_US_BG[] = {
47	{1, 2412, WLAN_TX_PWR_US_DEFAULT},
48	{2, 2417, WLAN_TX_PWR_US_DEFAULT},
49	{3, 2422, WLAN_TX_PWR_US_DEFAULT},
50	{4, 2427, WLAN_TX_PWR_US_DEFAULT},
51	{5, 2432, WLAN_TX_PWR_US_DEFAULT},
52	{6, 2437, WLAN_TX_PWR_US_DEFAULT},
53	{7, 2442, WLAN_TX_PWR_US_DEFAULT},
54	{8, 2447, WLAN_TX_PWR_US_DEFAULT},
55	{9, 2452, WLAN_TX_PWR_US_DEFAULT},
56	{10, 2457, WLAN_TX_PWR_US_DEFAULT},
57	{11, 2462, WLAN_TX_PWR_US_DEFAULT}
58};
59
60/* band: 'B/G', region: Europe ETSI */
61static struct chan_freq_power channel_freq_power_EU_BG[] = {
62	{1, 2412, WLAN_TX_PWR_EMEA_DEFAULT},
63	{2, 2417, WLAN_TX_PWR_EMEA_DEFAULT},
64	{3, 2422, WLAN_TX_PWR_EMEA_DEFAULT},
65	{4, 2427, WLAN_TX_PWR_EMEA_DEFAULT},
66	{5, 2432, WLAN_TX_PWR_EMEA_DEFAULT},
67	{6, 2437, WLAN_TX_PWR_EMEA_DEFAULT},
68	{7, 2442, WLAN_TX_PWR_EMEA_DEFAULT},
69	{8, 2447, WLAN_TX_PWR_EMEA_DEFAULT},
70	{9, 2452, WLAN_TX_PWR_EMEA_DEFAULT},
71	{10, 2457, WLAN_TX_PWR_EMEA_DEFAULT},
72	{11, 2462, WLAN_TX_PWR_EMEA_DEFAULT},
73	{12, 2467, WLAN_TX_PWR_EMEA_DEFAULT},
74	{13, 2472, WLAN_TX_PWR_EMEA_DEFAULT}
75};
76
77/* band: 'B/G', region: Spain */
78static struct chan_freq_power channel_freq_power_SPN_BG[] = {
79	{10, 2457, WLAN_TX_PWR_DEFAULT},
80	{11, 2462, WLAN_TX_PWR_DEFAULT}
81};
82
83/* band: 'B/G', region: France */
84static struct chan_freq_power channel_freq_power_FR_BG[] = {
85	{10, 2457, WLAN_TX_PWR_FR_DEFAULT},
86	{11, 2462, WLAN_TX_PWR_FR_DEFAULT},
87	{12, 2467, WLAN_TX_PWR_FR_DEFAULT},
88	{13, 2472, WLAN_TX_PWR_FR_DEFAULT}
89};
90
91/* band: 'B/G', region: Japan */
92static struct chan_freq_power channel_freq_power_JPN_BG[] = {
93	{1, 2412, WLAN_TX_PWR_JP_DEFAULT},
94	{2, 2417, WLAN_TX_PWR_JP_DEFAULT},
95	{3, 2422, WLAN_TX_PWR_JP_DEFAULT},
96	{4, 2427, WLAN_TX_PWR_JP_DEFAULT},
97	{5, 2432, WLAN_TX_PWR_JP_DEFAULT},
98	{6, 2437, WLAN_TX_PWR_JP_DEFAULT},
99	{7, 2442, WLAN_TX_PWR_JP_DEFAULT},
100	{8, 2447, WLAN_TX_PWR_JP_DEFAULT},
101	{9, 2452, WLAN_TX_PWR_JP_DEFAULT},
102	{10, 2457, WLAN_TX_PWR_JP_DEFAULT},
103	{11, 2462, WLAN_TX_PWR_JP_DEFAULT},
104	{12, 2467, WLAN_TX_PWR_JP_DEFAULT},
105	{13, 2472, WLAN_TX_PWR_JP_DEFAULT},
106	{14, 2484, WLAN_TX_PWR_JP_DEFAULT}
107};
108
109/**
110 * the structure for channel, frequency and power
111 */
112struct region_cfp_table {
113	u8 region;
114	struct chan_freq_power *cfp_BG;
115	int cfp_no_BG;
116};
117
118/**
119 * the structure for the mapping between region and CFP
120 */
121static struct region_cfp_table region_cfp_table[] = {
122	{0x10,			/*US FCC */
123	 channel_freq_power_US_BG,
124	 sizeof(channel_freq_power_US_BG) / sizeof(struct chan_freq_power),
125	 }
126	,
127	{0x20,			/*CANADA IC */
128	 channel_freq_power_US_BG,
129	 sizeof(channel_freq_power_US_BG) / sizeof(struct chan_freq_power),
130	 }
131	,
132	{0x30, /*EU*/ channel_freq_power_EU_BG,
133	 sizeof(channel_freq_power_EU_BG) / sizeof(struct chan_freq_power),
134	 }
135	,
136	{0x31, /*SPAIN*/ channel_freq_power_SPN_BG,
137	 sizeof(channel_freq_power_SPN_BG) / sizeof(struct chan_freq_power),
138	 }
139	,
140	{0x32, /*FRANCE*/ channel_freq_power_FR_BG,
141	 sizeof(channel_freq_power_FR_BG) / sizeof(struct chan_freq_power),
142	 }
143	,
144	{0x40, /*JAPAN*/ channel_freq_power_JPN_BG,
145	 sizeof(channel_freq_power_JPN_BG) / sizeof(struct chan_freq_power),
146	 }
147	,
148/*Add new region here */
149};
150
151/**
152 * the rates supported
153 */
154u8 libertas_supported_rates[G_SUPPORTED_RATES] =
155    { 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c,
1560 };
157
158/**
159 * the rates supported for ad-hoc G mode
160 */
161u8 libertas_adhoc_rates_g[G_SUPPORTED_RATES] =
162    { 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c,
1630 };
164
165/**
166 * the rates supported for ad-hoc B mode
167 */
168u8 libertas_adhoc_rates_b[4] = { 0x82, 0x84, 0x8b, 0x96 };
169
170/**
171 * the table to keep region code
172 */
173u16 libertas_region_code_to_index[MRVDRV_MAX_REGION_CODE] =
174    { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 };
175
176/**
177 * Attributes exported through sysfs
178 */
179
180/**
181 * @brief Get function for sysfs attribute anycast_mask
182 */
183static ssize_t libertas_anycast_get(struct device * dev,
184		struct device_attribute *attr, char * buf)
185{
186	struct cmd_ds_mesh_access mesh_access;
187
188	memset(&mesh_access, 0, sizeof(mesh_access));
189	libertas_prepare_and_send_command(to_net_dev(dev)->priv,
190			cmd_mesh_access,
191			cmd_act_mesh_get_anycast,
192			cmd_option_waitforrsp, 0, (void *)&mesh_access);
193
194	return snprintf(buf, 12, "0x%X\n", le32_to_cpu(mesh_access.data[0]));
195}
196
197/**
198 * @brief Set function for sysfs attribute anycast_mask
199 */
200static ssize_t libertas_anycast_set(struct device * dev,
201		struct device_attribute *attr, const char * buf, size_t count)
202{
203	struct cmd_ds_mesh_access mesh_access;
204	uint32_t datum;
205
206	memset(&mesh_access, 0, sizeof(mesh_access));
207	sscanf(buf, "%x", &datum);
208	mesh_access.data[0] = cpu_to_le32(datum);
209
210	libertas_prepare_and_send_command((to_net_dev(dev))->priv,
211			cmd_mesh_access,
212			cmd_act_mesh_set_anycast,
213			cmd_option_waitforrsp, 0, (void *)&mesh_access);
214	return strlen(buf);
215}
216
217/**
218 * anycast_mask attribute to be exported per mshX interface
219 * through sysfs (/sys/class/net/mshX/anycast_mask)
220 */
221static DEVICE_ATTR(anycast_mask, 0644, libertas_anycast_get, libertas_anycast_set);
222
223static int pre_open_check(struct net_device *dev)
224{
225	wlan_private *priv = (wlan_private *) dev->priv;
226	wlan_adapter *adapter = priv->adapter;
227	int i = 0;
228
229	while (!adapter->fw_ready && i < 20) {
230		i++;
231		msleep_interruptible(100);
232	}
233	if (!adapter->fw_ready) {
234		lbs_pr_err("firmware not ready\n");
235		return -1;
236	}
237
238	return 0;
239}
240
241/**
242 *  @brief This function opens the device
243 *
244 *  @param dev     A pointer to net_device structure
245 *  @return 	   0
246 */
247static int wlan_dev_open(struct net_device *dev)
248{
249	wlan_private *priv = (wlan_private *) dev->priv;
250	wlan_adapter *adapter = priv->adapter;
251
252	lbs_deb_enter(LBS_DEB_NET);
253
254	priv->open = 1;
255
256	if (adapter->connect_status == libertas_connected) {
257		netif_carrier_on(priv->dev);
258		netif_carrier_on(priv->mesh_dev);
259	} else {
260		netif_carrier_off(priv->dev);
261		netif_carrier_off(priv->mesh_dev);
262	}
263
264	lbs_deb_leave(LBS_DEB_NET);
265	return 0;
266}
267/**
268 *  @brief This function opens the mshX interface
269 *
270 *  @param dev     A pointer to net_device structure
271 *  @return 	   0
272 */
273static int mesh_open(struct net_device *dev)
274{
275	wlan_private *priv = (wlan_private *) dev->priv ;
276
277	if (pre_open_check(dev) == -1)
278		return -1;
279	priv->mesh_open = 1 ;
280	netif_wake_queue(priv->mesh_dev);
281	if (priv->infra_open == 0)
282		return wlan_dev_open(priv->dev) ;
283	return 0;
284}
285
286/**
287 *  @brief This function opens the ethX interface
288 *
289 *  @param dev     A pointer to net_device structure
290 *  @return 	   0
291 */
292static int wlan_open(struct net_device *dev)
293{
294	wlan_private *priv = (wlan_private *) dev->priv ;
295
296	if(pre_open_check(dev) == -1)
297		return -1;
298	priv->infra_open = 1 ;
299	netif_wake_queue(priv->dev);
300	if (priv->open == 0)
301		return wlan_dev_open(priv->dev) ;
302	return 0;
303}
304
305static int wlan_dev_close(struct net_device *dev)
306{
307	wlan_private *priv = dev->priv;
308
309	lbs_deb_enter(LBS_DEB_NET);
310
311	netif_carrier_off(priv->dev);
312	priv->open = 0;
313
314	lbs_deb_leave(LBS_DEB_NET);
315	return 0;
316}
317
318/**
319 *  @brief This function closes the mshX interface
320 *
321 *  @param dev     A pointer to net_device structure
322 *  @return 	   0
323 */
324static int mesh_close(struct net_device *dev)
325{
326	wlan_private *priv = (wlan_private *) (dev->priv);
327
328	priv->mesh_open = 0;
329	netif_stop_queue(priv->mesh_dev);
330	if (priv->infra_open == 0)
331		return wlan_dev_close(dev);
332	else
333		return 0;
334}
335
336/**
337 *  @brief This function closes the ethX interface
338 *
339 *  @param dev     A pointer to net_device structure
340 *  @return 	   0
341 */
342static int wlan_close(struct net_device *dev)
343{
344	wlan_private *priv = (wlan_private *) dev->priv;
345
346	netif_stop_queue(dev);
347	priv->infra_open = 0;
348	if (priv->mesh_open == 0)
349		return wlan_dev_close(dev);
350	else
351		return 0;
352}
353
354
355static int wlan_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
356{
357	int ret = 0;
358	wlan_private *priv = dev->priv;
359
360	lbs_deb_enter(LBS_DEB_NET);
361
362	if (priv->dnld_sent || priv->adapter->TxLockFlag) {
363		priv->stats.tx_dropped++;
364		goto done;
365	}
366
367	netif_stop_queue(priv->dev);
368	netif_stop_queue(priv->mesh_dev);
369
370	if (libertas_process_tx(priv, skb) == 0)
371		dev->trans_start = jiffies;
372done:
373	lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
374	return ret;
375}
376
377/**
378 * @brief Mark mesh packets and handover them to wlan_hard_start_xmit
379 *
380 */
381static int mesh_pre_start_xmit(struct sk_buff *skb, struct net_device *dev)
382{
383	wlan_private *priv = dev->priv;
384	int ret;
385
386	lbs_deb_enter(LBS_DEB_MESH);
387
388	SET_MESH_FRAME(skb);
389
390	ret = wlan_hard_start_xmit(skb, priv->dev);
391	lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
392	return ret;
393}
394
395/**
396 * @brief Mark non-mesh packets and handover them to wlan_hard_start_xmit
397 *
398 */
399static int wlan_pre_start_xmit(struct sk_buff *skb, struct net_device *dev)
400{
401	int ret;
402
403	lbs_deb_enter(LBS_DEB_NET);
404
405	UNSET_MESH_FRAME(skb);
406
407	ret = wlan_hard_start_xmit(skb, dev);
408	lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
409	return ret;
410}
411
412static void wlan_tx_timeout(struct net_device *dev)
413{
414	wlan_private *priv = (wlan_private *) dev->priv;
415
416	lbs_deb_enter(LBS_DEB_TX);
417
418	lbs_pr_err("tx watch dog timeout\n");
419
420	priv->dnld_sent = DNLD_RES_RECEIVED;
421	dev->trans_start = jiffies;
422
423	if (priv->adapter->currenttxskb) {
424		if (priv->adapter->radiomode == WLAN_RADIOMODE_RADIOTAP) {
425			/* If we are here, we have not received feedback from
426			   the previous packet.  Assume TX_FAIL and move on. */
427			priv->adapter->eventcause = 0x01000000;
428			libertas_send_tx_feedback(priv);
429		} else
430			wake_up_interruptible(&priv->mainthread.waitq);
431	} else if (priv->adapter->connect_status == libertas_connected) {
432		netif_wake_queue(priv->dev);
433		netif_wake_queue(priv->mesh_dev);
434	}
435
436	lbs_deb_leave(LBS_DEB_TX);
437}
438
439/**
440 *  @brief This function returns the network statistics
441 *
442 *  @param dev     A pointer to wlan_private structure
443 *  @return 	   A pointer to net_device_stats structure
444 */
445static struct net_device_stats *wlan_get_stats(struct net_device *dev)
446{
447	wlan_private *priv = (wlan_private *) dev->priv;
448
449	return &priv->stats;
450}
451
452static int wlan_set_mac_address(struct net_device *dev, void *addr)
453{
454	int ret = 0;
455	wlan_private *priv = (wlan_private *) dev->priv;
456	wlan_adapter *adapter = priv->adapter;
457	struct sockaddr *phwaddr = addr;
458
459	lbs_deb_enter(LBS_DEB_NET);
460
461	/* In case it was called from the mesh device */
462	dev = priv->dev ;
463
464	memset(adapter->current_addr, 0, ETH_ALEN);
465
466	/* dev->dev_addr is 8 bytes */
467	lbs_dbg_hex("dev->dev_addr:", dev->dev_addr, ETH_ALEN);
468
469	lbs_dbg_hex("addr:", phwaddr->sa_data, ETH_ALEN);
470	memcpy(adapter->current_addr, phwaddr->sa_data, ETH_ALEN);
471
472	ret = libertas_prepare_and_send_command(priv, cmd_802_11_mac_address,
473				    cmd_act_set,
474				    cmd_option_waitforrsp, 0, NULL);
475
476	if (ret) {
477		lbs_deb_net("set MAC address failed\n");
478		ret = -1;
479		goto done;
480	}
481
482	lbs_dbg_hex("adapter->macaddr:", adapter->current_addr, ETH_ALEN);
483	memcpy(dev->dev_addr, adapter->current_addr, ETH_ALEN);
484	if (priv->mesh_dev)
485		memcpy(priv->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN);
486
487done:
488	lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
489	return ret;
490}
491
492static int wlan_copy_multicast_address(wlan_adapter * adapter,
493				     struct net_device *dev)
494{
495	int i = 0;
496	struct dev_mc_list *mcptr = dev->mc_list;
497
498	for (i = 0; i < dev->mc_count; i++) {
499		memcpy(&adapter->multicastlist[i], mcptr->dmi_addr, ETH_ALEN);
500		mcptr = mcptr->next;
501	}
502
503	return i;
504
505}
506
507static void wlan_set_multicast_list(struct net_device *dev)
508{
509	wlan_private *priv = dev->priv;
510	wlan_adapter *adapter = priv->adapter;
511	int oldpacketfilter;
512
513	lbs_deb_enter(LBS_DEB_NET);
514
515	oldpacketfilter = adapter->currentpacketfilter;
516
517	if (dev->flags & IFF_PROMISC) {
518		lbs_deb_net("enable promiscuous mode\n");
519		adapter->currentpacketfilter |=
520		    cmd_act_mac_promiscuous_enable;
521		adapter->currentpacketfilter &=
522		    ~(cmd_act_mac_all_multicast_enable |
523		      cmd_act_mac_multicast_enable);
524	} else {
525		/* Multicast */
526		adapter->currentpacketfilter &=
527		    ~cmd_act_mac_promiscuous_enable;
528
529		if (dev->flags & IFF_ALLMULTI || dev->mc_count >
530		    MRVDRV_MAX_MULTICAST_LIST_SIZE) {
531			lbs_deb_net( "enabling all multicast\n");
532			adapter->currentpacketfilter |=
533			    cmd_act_mac_all_multicast_enable;
534			adapter->currentpacketfilter &=
535			    ~cmd_act_mac_multicast_enable;
536		} else {
537			adapter->currentpacketfilter &=
538			    ~cmd_act_mac_all_multicast_enable;
539
540			if (!dev->mc_count) {
541				lbs_deb_net("no multicast addresses, "
542				       "disabling multicast\n");
543				adapter->currentpacketfilter &=
544				    ~cmd_act_mac_multicast_enable;
545			} else {
546				int i;
547
548				adapter->currentpacketfilter |=
549				    cmd_act_mac_multicast_enable;
550
551				adapter->nr_of_multicastmacaddr =
552				    wlan_copy_multicast_address(adapter, dev);
553
554				lbs_deb_net("multicast addresses: %d\n",
555				       dev->mc_count);
556
557				for (i = 0; i < dev->mc_count; i++) {
558					lbs_deb_net("Multicast address %d:"
559					       MAC_FMT "\n", i,
560					       adapter->multicastlist[i][0],
561					       adapter->multicastlist[i][1],
562					       adapter->multicastlist[i][2],
563					       adapter->multicastlist[i][3],
564					       adapter->multicastlist[i][4],
565					       adapter->multicastlist[i][5]);
566				}
567				/* send multicast addresses to firmware */
568				libertas_prepare_and_send_command(priv,
569						      cmd_mac_multicast_adr,
570						      cmd_act_set, 0, 0,
571						      NULL);
572			}
573		}
574	}
575
576	if (adapter->currentpacketfilter != oldpacketfilter) {
577		libertas_set_mac_packet_filter(priv);
578	}
579
580	lbs_deb_leave(LBS_DEB_NET);
581}
582
583/**
584 *  @brief This function handles the major jobs in the WLAN driver.
585 *  It handles all events generated by firmware, RX data received
586 *  from firmware and TX data sent from kernel.
587 *
588 *  @param data    A pointer to wlan_thread structure
589 *  @return 	   0
590 */
591static int wlan_service_main_thread(void *data)
592{
593	struct wlan_thread *thread = data;
594	wlan_private *priv = thread->priv;
595	wlan_adapter *adapter = priv->adapter;
596	wait_queue_t wait;
597	u8 ireg = 0;
598
599	lbs_deb_enter(LBS_DEB_THREAD);
600
601	wlan_activate_thread(thread);
602
603	init_waitqueue_entry(&wait, current);
604
605	for (;;) {
606		lbs_deb_thread( "main-thread 111: intcounter=%d "
607		       "currenttxskb=%p dnld_sent=%d\n",
608		       adapter->intcounter,
609		       adapter->currenttxskb, priv->dnld_sent);
610
611		add_wait_queue(&thread->waitq, &wait);
612		set_current_state(TASK_INTERRUPTIBLE);
613		spin_lock_irq(&adapter->driver_lock);
614		if ((adapter->psstate == PS_STATE_SLEEP) ||
615		    (!adapter->intcounter
616		     && (priv->dnld_sent || adapter->cur_cmd ||
617			 list_empty(&adapter->cmdpendingq)))) {
618			lbs_deb_thread(
619			       "main-thread sleeping... Conn=%d IntC=%d PS_mode=%d PS_State=%d\n",
620			       adapter->connect_status, adapter->intcounter,
621			       adapter->psmode, adapter->psstate);
622			spin_unlock_irq(&adapter->driver_lock);
623			schedule();
624		} else
625			spin_unlock_irq(&adapter->driver_lock);
626
627
628		lbs_deb_thread(
629		       "main-thread 222 (waking up): intcounter=%d currenttxskb=%p "
630		       "dnld_sent=%d\n", adapter->intcounter,
631		       adapter->currenttxskb, priv->dnld_sent);
632
633		set_current_state(TASK_RUNNING);
634		remove_wait_queue(&thread->waitq, &wait);
635		try_to_freeze();
636
637		lbs_deb_thread("main-thread 333: intcounter=%d currenttxskb=%p "
638		       "dnld_sent=%d\n",
639		       adapter->intcounter,
640		       adapter->currenttxskb, priv->dnld_sent);
641
642		if (kthread_should_stop()
643		    || adapter->surpriseremoved) {
644			lbs_deb_thread(
645			       "main-thread: break from main thread: surpriseremoved=0x%x\n",
646			       adapter->surpriseremoved);
647			break;
648		}
649
650
651		spin_lock_irq(&adapter->driver_lock);
652		if (adapter->intcounter) {
653			u8 int_status;
654			adapter->intcounter = 0;
655			int_status = priv->hw_get_int_status(priv, &ireg);
656
657			if (int_status) {
658				lbs_deb_thread(
659				       "main-thread: reading HOST_INT_STATUS_REG failed\n");
660				spin_unlock_irq(&adapter->driver_lock);
661				continue;
662			}
663			adapter->hisregcpy |= ireg;
664		}
665
666		lbs_deb_thread("main-thread 444: intcounter=%d currenttxskb=%p "
667		       "dnld_sent=%d\n",
668		       adapter->intcounter,
669		       adapter->currenttxskb, priv->dnld_sent);
670
671		/* command response? */
672		if (adapter->hisregcpy & his_cmdupldrdy) {
673			lbs_deb_thread("main-thread: cmd response ready\n");
674
675			adapter->hisregcpy &= ~his_cmdupldrdy;
676			spin_unlock_irq(&adapter->driver_lock);
677			libertas_process_rx_command(priv);
678			spin_lock_irq(&adapter->driver_lock);
679		}
680
681		/* Any Card Event */
682		if (adapter->hisregcpy & his_cardevent) {
683			lbs_deb_thread("main-thread: Card Event Activity\n");
684
685			adapter->hisregcpy &= ~his_cardevent;
686
687			if (priv->hw_read_event_cause(priv)) {
688				lbs_pr_alert(
689				       "main-thread: hw_read_event_cause failed\n");
690				spin_unlock_irq(&adapter->driver_lock);
691				continue;
692			}
693			spin_unlock_irq(&adapter->driver_lock);
694			libertas_process_event(priv);
695		} else
696			spin_unlock_irq(&adapter->driver_lock);
697
698		/* Check if we need to confirm Sleep Request received previously */
699		if (adapter->psstate == PS_STATE_PRE_SLEEP) {
700			if (!priv->dnld_sent && !adapter->cur_cmd) {
701				if (adapter->connect_status ==
702				    libertas_connected) {
703					lbs_deb_thread(
704					       "main_thread: PRE_SLEEP--intcounter=%d currenttxskb=%p "
705					       "dnld_sent=%d cur_cmd=%p, confirm now\n",
706					       adapter->intcounter,
707					       adapter->currenttxskb,
708					       priv->dnld_sent,
709					       adapter->cur_cmd);
710
711					libertas_ps_confirm_sleep(priv,
712						       (u16) adapter->psmode);
713				} else {
714					adapter->psstate = PS_STATE_AWAKE;
715					lbs_pr_alert(
716					       "main-thread: ignore PS_SleepConfirm in non-connected state\n");
717				}
718			}
719		}
720
721		/* The PS state is changed during processing of Sleep Request
722		 * event above
723		 */
724		if ((priv->adapter->psstate == PS_STATE_SLEEP) ||
725		    (priv->adapter->psstate == PS_STATE_PRE_SLEEP))
726			continue;
727
728		/* Execute the next command */
729		if (!priv->dnld_sent && !priv->adapter->cur_cmd)
730			libertas_execute_next_command(priv);
731
732		/* Wake-up command waiters which can't sleep in
733		 * libertas_prepare_and_send_command
734		 */
735		if (!adapter->nr_cmd_pending)
736			wake_up_all(&adapter->cmd_pending);
737
738		libertas_tx_runqueue(priv);
739	}
740
741	del_timer(&adapter->command_timer);
742	adapter->nr_cmd_pending = 0;
743	wake_up_all(&adapter->cmd_pending);
744	wlan_deactivate_thread(thread);
745
746	lbs_deb_leave(LBS_DEB_THREAD);
747	return 0;
748}
749
750/**
751 * @brief This function adds the card. it will probe the
752 * card, allocate the wlan_priv and initialize the device.
753 *
754 *  @param card    A pointer to card
755 *  @return 	   A pointer to wlan_private structure
756 */
757wlan_private *libertas_add_card(void *card, struct device *dmdev)
758{
759	struct net_device *dev = NULL;
760	wlan_private *priv = NULL;
761
762	lbs_deb_enter(LBS_DEB_NET);
763
764	/* Allocate an Ethernet device and register it */
765	if (!(dev = alloc_etherdev(sizeof(wlan_private)))) {
766		lbs_pr_err("init ethX device failed\n");
767		return NULL;
768	}
769	priv = dev->priv;
770
771	/* allocate buffer for wlan_adapter */
772	if (!(priv->adapter = kzalloc(sizeof(wlan_adapter), GFP_KERNEL))) {
773		lbs_pr_err("allocate buffer for wlan_adapter failed\n");
774		goto err_kzalloc;
775	}
776
777	priv->dev = dev;
778	priv->card = card;
779	priv->mesh_open = 0;
780	priv->infra_open = 0;
781
782	SET_MODULE_OWNER(dev);
783
784	/* Setup the OS Interface to our functions */
785	dev->open = wlan_open;
786	dev->hard_start_xmit = wlan_pre_start_xmit;
787	dev->stop = wlan_close;
788	dev->set_mac_address = wlan_set_mac_address;
789	dev->tx_timeout = wlan_tx_timeout;
790	dev->get_stats = wlan_get_stats;
791	dev->watchdog_timeo = 5 * HZ;
792	dev->ethtool_ops = &libertas_ethtool_ops;
793#ifdef	WIRELESS_EXT
794	dev->wireless_handlers = (struct iw_handler_def *)&libertas_handler_def;
795#endif
796#define NETIF_F_DYNALLOC 16
797	dev->features |= NETIF_F_DYNALLOC;
798	dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
799	dev->set_multicast_list = wlan_set_multicast_list;
800
801	SET_NETDEV_DEV(dev, dmdev);
802
803	INIT_LIST_HEAD(&priv->adapter->cmdfreeq);
804	INIT_LIST_HEAD(&priv->adapter->cmdpendingq);
805
806	spin_lock_init(&priv->adapter->driver_lock);
807	init_waitqueue_head(&priv->adapter->cmd_pending);
808	priv->adapter->nr_cmd_pending = 0;
809	goto done;
810
811err_kzalloc:
812	free_netdev(dev);
813	priv = NULL;
814done:
815	lbs_deb_leave_args(LBS_DEB_NET, "priv %p", priv);
816	return priv;
817}
818EXPORT_SYMBOL_GPL(libertas_add_card);
819
820int libertas_activate_card(wlan_private *priv, char *fw_name)
821{
822	struct net_device *dev = priv->dev;
823	int ret = -1;
824
825	lbs_deb_enter(LBS_DEB_MAIN);
826
827	lbs_deb_thread("Starting kthread...\n");
828	priv->mainthread.priv = priv;
829	wlan_create_thread(wlan_service_main_thread,
830			   &priv->mainthread, "wlan_main_service");
831
832	priv->assoc_thread =
833		create_singlethread_workqueue("libertas_assoc");
834	INIT_DELAYED_WORK(&priv->assoc_work, libertas_association_worker);
835	INIT_WORK(&priv->sync_channel, libertas_sync_channel);
836
837	/*
838	 * Register the device. Fillup the private data structure with
839	 * relevant information from the card and request for the required
840	 * IRQ.
841	 */
842	if (priv->hw_register_dev(priv) < 0) {
843		lbs_pr_err("failed to register WLAN device\n");
844		goto err_registerdev;
845	}
846
847	/* init FW and HW */
848	if (fw_name && libertas_init_fw(priv, fw_name)) {
849		lbs_pr_err("firmware init failed\n");
850		goto err_registerdev;
851	}
852
853	if (register_netdev(dev)) {
854		lbs_pr_err("cannot register ethX device\n");
855		goto err_init_fw;
856	}
857
858	lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name);
859
860	libertas_debugfs_init_one(priv, dev);
861
862	ret = 0;
863	goto done;
864
865err_init_fw:
866	priv->hw_unregister_dev(priv);
867err_registerdev:
868	destroy_workqueue(priv->assoc_thread);
869	/* Stop the thread servicing the interrupts */
870	wake_up_interruptible(&priv->mainthread.waitq);
871	wlan_terminate_thread(&priv->mainthread);
872done:
873	lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
874	return ret;
875}
876EXPORT_SYMBOL_GPL(libertas_activate_card);
877
878
879/**
880 * @brief This function adds mshX interface
881 *
882 *  @param priv    A pointer to the wlan_private structure
883 *  @return 	   0 if successful, -X otherwise
884 */
885int libertas_add_mesh(wlan_private *priv, struct device *dev)
886{
887	struct net_device *mesh_dev = NULL;
888	int ret = 0;
889
890	lbs_deb_enter(LBS_DEB_MESH);
891
892	/* Allocate a virtual mesh device */
893	if (!(mesh_dev = alloc_netdev(0, "msh%d", ether_setup))) {
894		lbs_deb_mesh("init mshX device failed\n");
895		ret = -ENOMEM;
896		goto done;
897	}
898	mesh_dev->priv = priv;
899	priv->mesh_dev = mesh_dev;
900
901	SET_MODULE_OWNER(mesh_dev);
902
903	mesh_dev->open = mesh_open;
904	mesh_dev->hard_start_xmit = mesh_pre_start_xmit;
905	mesh_dev->stop = mesh_close;
906	mesh_dev->get_stats = wlan_get_stats;
907	mesh_dev->set_mac_address = wlan_set_mac_address;
908	mesh_dev->ethtool_ops = &libertas_ethtool_ops;
909	memcpy(mesh_dev->dev_addr, priv->dev->dev_addr,
910			sizeof(priv->dev->dev_addr));
911
912	SET_NETDEV_DEV(priv->mesh_dev, dev);
913
914#ifdef	WIRELESS_EXT
915	mesh_dev->wireless_handlers = (struct iw_handler_def *)&mesh_handler_def;
916#endif
917#define NETIF_F_DYNALLOC 16
918
919	/* Register virtual mesh interface */
920	ret = register_netdev(mesh_dev);
921	if (ret) {
922		lbs_pr_err("cannot register mshX virtual interface\n");
923		goto err_free;
924	}
925
926	ret = device_create_file(&(mesh_dev->dev), &dev_attr_anycast_mask);
927	if (ret)
928		goto err_unregister;
929
930	/* Everything successful */
931	ret = 0;
932	goto done;
933
934
935err_unregister:
936	unregister_netdev(mesh_dev);
937
938err_free:
939	free_netdev(mesh_dev);
940
941done:
942	lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
943	return ret;
944}
945EXPORT_SYMBOL_GPL(libertas_add_mesh);
946
947static void wake_pending_cmdnodes(wlan_private *priv)
948{
949	struct cmd_ctrl_node *cmdnode;
950	unsigned long flags;
951
952	lbs_deb_enter(LBS_DEB_CMD);
953
954	spin_lock_irqsave(&priv->adapter->driver_lock, flags);
955	list_for_each_entry(cmdnode, &priv->adapter->cmdpendingq, list) {
956		cmdnode->cmdwaitqwoken = 1;
957		wake_up_interruptible(&cmdnode->cmdwait_q);
958	}
959	spin_unlock_irqrestore(&priv->adapter->driver_lock, flags);
960}
961
962
963int libertas_remove_card(wlan_private *priv)
964{
965	wlan_adapter *adapter;
966	struct net_device *dev;
967	union iwreq_data wrqu;
968
969	lbs_deb_enter(LBS_DEB_NET);
970
971	if (!priv)
972		goto out;
973
974	adapter = priv->adapter;
975
976	if (!adapter)
977		goto out;
978
979	dev = priv->dev;
980
981	netif_stop_queue(priv->dev);
982	netif_carrier_off(priv->dev);
983
984	wake_pending_cmdnodes(priv);
985
986	unregister_netdev(dev);
987
988	cancel_delayed_work(&priv->assoc_work);
989	destroy_workqueue(priv->assoc_thread);
990
991	if (adapter->psmode == wlan802_11powermodemax_psp) {
992		adapter->psmode = wlan802_11powermodecam;
993		libertas_ps_wakeup(priv, cmd_option_waitforrsp);
994	}
995
996	memset(wrqu.ap_addr.sa_data, 0xaa, ETH_ALEN);
997	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
998	wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
999
1000	adapter->surpriseremoved = 1;
1001
1002	/* Stop the thread servicing the interrupts */
1003	wlan_terminate_thread(&priv->mainthread);
1004
1005	libertas_debugfs_remove_one(priv);
1006
1007	lbs_deb_net("free adapter\n");
1008	libertas_free_adapter(priv);
1009
1010	lbs_deb_net("unregister finish\n");
1011
1012	priv->dev = NULL;
1013	free_netdev(dev);
1014
1015out:
1016	lbs_deb_leave(LBS_DEB_NET);
1017	return 0;
1018}
1019EXPORT_SYMBOL_GPL(libertas_remove_card);
1020
1021
1022void libertas_remove_mesh(wlan_private *priv)
1023{
1024	struct net_device *mesh_dev;
1025
1026	lbs_deb_enter(LBS_DEB_NET);
1027
1028	if (!priv)
1029		goto out;
1030
1031	mesh_dev = priv->mesh_dev;
1032
1033	netif_stop_queue(mesh_dev);
1034	netif_carrier_off(priv->mesh_dev);
1035
1036	device_remove_file(&(mesh_dev->dev), &dev_attr_anycast_mask);
1037	unregister_netdev(mesh_dev);
1038
1039	priv->mesh_dev = NULL ;
1040	free_netdev(mesh_dev);
1041
1042out:
1043	lbs_deb_leave(LBS_DEB_NET);
1044}
1045EXPORT_SYMBOL_GPL(libertas_remove_mesh);
1046
1047/**
1048 *  @brief This function finds the CFP in
1049 *  region_cfp_table based on region and band parameter.
1050 *
1051 *  @param region  The region code
1052 *  @param band	   The band
1053 *  @param cfp_no  A pointer to CFP number
1054 *  @return 	   A pointer to CFP
1055 */
1056struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band, int *cfp_no)
1057{
1058	int i, end;
1059
1060	lbs_deb_enter(LBS_DEB_MAIN);
1061
1062	end = sizeof(region_cfp_table)/sizeof(struct region_cfp_table);
1063
1064	for (i = 0; i < end ; i++) {
1065		lbs_deb_main("region_cfp_table[i].region=%d\n",
1066			region_cfp_table[i].region);
1067		if (region_cfp_table[i].region == region) {
1068			*cfp_no = region_cfp_table[i].cfp_no_BG;
1069			lbs_deb_leave(LBS_DEB_MAIN);
1070			return region_cfp_table[i].cfp_BG;
1071		}
1072	}
1073
1074	lbs_deb_leave_args(LBS_DEB_MAIN, "ret NULL");
1075	return NULL;
1076}
1077
1078int libertas_set_regiontable(wlan_private * priv, u8 region, u8 band)
1079{
1080	wlan_adapter *adapter = priv->adapter;
1081	int ret = 0;
1082	int i = 0;
1083
1084	struct chan_freq_power *cfp;
1085	int cfp_no;
1086
1087	lbs_deb_enter(LBS_DEB_MAIN);
1088
1089	memset(adapter->region_channel, 0, sizeof(adapter->region_channel));
1090
1091	{
1092		cfp = libertas_get_region_cfp_table(region, band, &cfp_no);
1093		if (cfp != NULL) {
1094			adapter->region_channel[i].nrcfp = cfp_no;
1095			adapter->region_channel[i].CFP = cfp;
1096		} else {
1097			lbs_deb_main("wrong region code %#x in band B/G\n",
1098			       region);
1099			ret = -1;
1100			goto out;
1101		}
1102		adapter->region_channel[i].valid = 1;
1103		adapter->region_channel[i].region = region;
1104		adapter->region_channel[i].band = band;
1105		i++;
1106	}
1107out:
1108	lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
1109	return ret;
1110}
1111
1112/**
1113 *  @brief This function handles the interrupt. it will change PS
1114 *  state if applicable. it will wake up main_thread to handle
1115 *  the interrupt event as well.
1116 *
1117 *  @param dev     A pointer to net_device structure
1118 *  @return 	   n/a
1119 */
1120void libertas_interrupt(struct net_device *dev)
1121{
1122	wlan_private *priv = dev->priv;
1123
1124	lbs_deb_enter(LBS_DEB_THREAD);
1125
1126	lbs_deb_thread("libertas_interrupt: intcounter=%d\n",
1127	       priv->adapter->intcounter);
1128
1129	priv->adapter->intcounter++;
1130
1131	if (priv->adapter->psstate == PS_STATE_SLEEP) {
1132		priv->adapter->psstate = PS_STATE_AWAKE;
1133		netif_wake_queue(dev);
1134		netif_wake_queue(priv->mesh_dev);
1135	}
1136
1137	wake_up_interruptible(&priv->mainthread.waitq);
1138
1139	lbs_deb_leave(LBS_DEB_THREAD);
1140}
1141EXPORT_SYMBOL_GPL(libertas_interrupt);
1142
1143static int libertas_init_module(void)
1144{
1145	lbs_deb_enter(LBS_DEB_MAIN);
1146	libertas_debugfs_init();
1147	lbs_deb_leave(LBS_DEB_MAIN);
1148	return 0;
1149}
1150
1151static void libertas_exit_module(void)
1152{
1153	lbs_deb_enter(LBS_DEB_MAIN);
1154
1155	libertas_debugfs_remove();
1156
1157	lbs_deb_leave(LBS_DEB_MAIN);
1158}
1159
1160module_init(libertas_init_module);
1161module_exit(libertas_exit_module);
1162
1163MODULE_DESCRIPTION("Libertas WLAN Driver Library");
1164MODULE_AUTHOR("Marvell International Ltd.");
1165MODULE_LICENSE("GPL");
1166