2 * This file contains the major functions in WLAN
3 * driver. It includes init, exit, open, close and main
7 #include <linux/delay.h>
8 #include <linux/freezer.h>
9 #include <linux/etherdevice.h>
10 #include <linux/netdevice.h>
11 #include <linux/if_arp.h>
13 #include <net/iw_handler.h>
25 static struct pm_dev
*wlan_pm_dev
= NULL
;
28 #define WLAN_TX_PWR_DEFAULT 20 /*100mW */
29 #define WLAN_TX_PWR_US_DEFAULT 20 /*100mW */
30 #define WLAN_TX_PWR_JP_DEFAULT 16 /*50mW */
31 #define WLAN_TX_PWR_FR_DEFAULT 20 /*100mW */
32 #define WLAN_TX_PWR_EMEA_DEFAULT 20 /*100mW */
34 /* Format { channel, frequency (MHz), maxtxpower } */
35 /* band: 'B/G', region: USA FCC/Canada IC */
36 static struct chan_freq_power channel_freq_power_US_BG
[] = {
37 {1, 2412, WLAN_TX_PWR_US_DEFAULT
},
38 {2, 2417, WLAN_TX_PWR_US_DEFAULT
},
39 {3, 2422, WLAN_TX_PWR_US_DEFAULT
},
40 {4, 2427, WLAN_TX_PWR_US_DEFAULT
},
41 {5, 2432, WLAN_TX_PWR_US_DEFAULT
},
42 {6, 2437, WLAN_TX_PWR_US_DEFAULT
},
43 {7, 2442, WLAN_TX_PWR_US_DEFAULT
},
44 {8, 2447, WLAN_TX_PWR_US_DEFAULT
},
45 {9, 2452, WLAN_TX_PWR_US_DEFAULT
},
46 {10, 2457, WLAN_TX_PWR_US_DEFAULT
},
47 {11, 2462, WLAN_TX_PWR_US_DEFAULT
}
50 /* band: 'B/G', region: Europe ETSI */
51 static struct chan_freq_power channel_freq_power_EU_BG
[] = {
52 {1, 2412, WLAN_TX_PWR_EMEA_DEFAULT
},
53 {2, 2417, WLAN_TX_PWR_EMEA_DEFAULT
},
54 {3, 2422, WLAN_TX_PWR_EMEA_DEFAULT
},
55 {4, 2427, WLAN_TX_PWR_EMEA_DEFAULT
},
56 {5, 2432, WLAN_TX_PWR_EMEA_DEFAULT
},
57 {6, 2437, WLAN_TX_PWR_EMEA_DEFAULT
},
58 {7, 2442, WLAN_TX_PWR_EMEA_DEFAULT
},
59 {8, 2447, WLAN_TX_PWR_EMEA_DEFAULT
},
60 {9, 2452, WLAN_TX_PWR_EMEA_DEFAULT
},
61 {10, 2457, WLAN_TX_PWR_EMEA_DEFAULT
},
62 {11, 2462, WLAN_TX_PWR_EMEA_DEFAULT
},
63 {12, 2467, WLAN_TX_PWR_EMEA_DEFAULT
},
64 {13, 2472, WLAN_TX_PWR_EMEA_DEFAULT
}
67 /* band: 'B/G', region: Spain */
68 static struct chan_freq_power channel_freq_power_SPN_BG
[] = {
69 {10, 2457, WLAN_TX_PWR_DEFAULT
},
70 {11, 2462, WLAN_TX_PWR_DEFAULT
}
73 /* band: 'B/G', region: France */
74 static struct chan_freq_power channel_freq_power_FR_BG
[] = {
75 {10, 2457, WLAN_TX_PWR_FR_DEFAULT
},
76 {11, 2462, WLAN_TX_PWR_FR_DEFAULT
},
77 {12, 2467, WLAN_TX_PWR_FR_DEFAULT
},
78 {13, 2472, WLAN_TX_PWR_FR_DEFAULT
}
81 /* band: 'B/G', region: Japan */
82 static struct chan_freq_power channel_freq_power_JPN_BG
[] = {
83 {1, 2412, WLAN_TX_PWR_JP_DEFAULT
},
84 {2, 2417, WLAN_TX_PWR_JP_DEFAULT
},
85 {3, 2422, WLAN_TX_PWR_JP_DEFAULT
},
86 {4, 2427, WLAN_TX_PWR_JP_DEFAULT
},
87 {5, 2432, WLAN_TX_PWR_JP_DEFAULT
},
88 {6, 2437, WLAN_TX_PWR_JP_DEFAULT
},
89 {7, 2442, WLAN_TX_PWR_JP_DEFAULT
},
90 {8, 2447, WLAN_TX_PWR_JP_DEFAULT
},
91 {9, 2452, WLAN_TX_PWR_JP_DEFAULT
},
92 {10, 2457, WLAN_TX_PWR_JP_DEFAULT
},
93 {11, 2462, WLAN_TX_PWR_JP_DEFAULT
},
94 {12, 2467, WLAN_TX_PWR_JP_DEFAULT
},
95 {13, 2472, WLAN_TX_PWR_JP_DEFAULT
},
96 {14, 2484, WLAN_TX_PWR_JP_DEFAULT
}
100 * the structure for channel, frequency and power
102 struct region_cfp_table
{
104 struct chan_freq_power
*cfp_BG
;
109 * the structure for the mapping between region and CFP
111 static struct region_cfp_table region_cfp_table
[] = {
113 channel_freq_power_US_BG
,
114 sizeof(channel_freq_power_US_BG
) / sizeof(struct chan_freq_power
),
117 {0x20, /*CANADA IC */
118 channel_freq_power_US_BG
,
119 sizeof(channel_freq_power_US_BG
) / sizeof(struct chan_freq_power
),
122 {0x30, /*EU*/ channel_freq_power_EU_BG
,
123 sizeof(channel_freq_power_EU_BG
) / sizeof(struct chan_freq_power
),
126 {0x31, /*SPAIN*/ channel_freq_power_SPN_BG
,
127 sizeof(channel_freq_power_SPN_BG
) / sizeof(struct chan_freq_power
),
130 {0x32, /*FRANCE*/ channel_freq_power_FR_BG
,
131 sizeof(channel_freq_power_FR_BG
) / sizeof(struct chan_freq_power
),
134 {0x40, /*JAPAN*/ channel_freq_power_JPN_BG
,
135 sizeof(channel_freq_power_JPN_BG
) / sizeof(struct chan_freq_power
),
138 /*Add new region here */
142 * the rates supported by the card
144 u8 libertas_wlan_data_rates
[WLAN_SUPPORTED_RATES
] =
145 { 0x02, 0x04, 0x0B, 0x16, 0x00, 0x0C, 0x12,
146 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x00
150 * the rates supported
152 u8 libertas_supported_rates
[G_SUPPORTED_RATES
] =
153 { 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c,
157 * the rates supported for ad-hoc G mode
159 u8 libertas_adhoc_rates_g
[G_SUPPORTED_RATES
] =
160 { 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c,
164 * the rates supported for ad-hoc B mode
166 u8 libertas_adhoc_rates_b
[4] = { 0x82, 0x84, 0x8b, 0x96 };
169 * the global variable of a pointer to wlan_private
172 static wlan_private
*wlanpriv
= NULL
;
175 static struct net_device
*libertas_devs
[MAX_DEVS
];
176 static int libertas_found
= 0;
179 * the table to keep region code
181 u16 libertas_region_code_to_index
[MRVDRV_MAX_REGION_CODE
] =
182 { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 };
184 static u8
*default_fw_name
= "usb8388.bin";
187 * Attributes exported through sysfs
189 #define to_net_dev(class) container_of(class, struct net_device, class_dev)
192 * @brief Get function for sysfs attribute libertas_mpp
194 static ssize_t
libertas_mpp_get(struct class_device
* dev
, char * buf
) {
195 struct cmd_ds_mesh_access mesh_access
;
197 memset(&mesh_access
, 0, sizeof(mesh_access
));
198 libertas_prepare_and_send_command(to_net_dev(dev
)->priv
,
200 cmd_act_mesh_get_mpp
,
201 cmd_option_waitforrsp
, 0, (void *)&mesh_access
);
203 return snprintf(buf
, 3, "%d\n", mesh_access
.data
[0]);
207 * @brief Set function for sysfs attribute libertas_mpp
209 static ssize_t
libertas_mpp_set(struct class_device
* dev
, const char * buf
,
211 struct cmd_ds_mesh_access mesh_access
;
214 memset(&mesh_access
, 0, sizeof(mesh_access
));
215 sscanf(buf
, "%d", &(mesh_access
.data
[0]));
216 libertas_prepare_and_send_command((to_net_dev(dev
))->priv
,
218 cmd_act_mesh_set_mpp
,
219 cmd_option_waitforrsp
, 0, (void *)&mesh_access
);
224 * libertas_mpp attribute to be exported per mshX interface
225 * through sysfs (/sys/class/net/mshX/libertas-mpp)
227 static CLASS_DEVICE_ATTR(libertas_mpp
, 0644, libertas_mpp_get
,
231 * @brief Check if the device can be open and wait if necessary.
233 * @param dev A pointer to net_device structure
236 * For USB adapter, on some systems the device open handler will be
237 * called before FW ready. Use the following flag check and wait
238 * function to work around the issue.
241 static int pre_open_check(struct net_device
*dev
) {
242 wlan_private
*priv
= (wlan_private
*) dev
->priv
;
243 wlan_adapter
*adapter
= priv
->adapter
;
246 while (!adapter
->fw_ready
&& i
< 20) {
248 msleep_interruptible(100);
250 if (!adapter
->fw_ready
) {
251 lbs_pr_info("FW not ready, pre_open_check() return failure\n");
260 * @brief This function opens the device
262 * @param dev A pointer to net_device structure
265 static int wlan_dev_open(struct net_device
*dev
)
267 wlan_private
*priv
= (wlan_private
*) dev
->priv
;
268 wlan_adapter
*adapter
= priv
->adapter
;
275 if (adapter
->connect_status
== libertas_connected
) {
276 netif_carrier_on(priv
->wlan_dev
.netdev
);
278 netif_carrier_off(priv
->wlan_dev
.netdev
);
284 * @brief This function opens the mshX interface
286 * @param dev A pointer to net_device structure
289 static int mesh_open(struct net_device
*dev
)
291 wlan_private
*priv
= (wlan_private
*) dev
->priv
;
293 if(pre_open_check(dev
) == -1)
295 priv
->mesh_open
= 1 ;
296 netif_start_queue(priv
->mesh_dev
);
297 if (priv
->infra_open
== 0)
298 return wlan_dev_open(priv
->wlan_dev
.netdev
) ;
303 * @brief This function opens the ethX interface
305 * @param dev A pointer to net_device structure
308 static int wlan_open(struct net_device
*dev
)
310 wlan_private
*priv
= (wlan_private
*) dev
->priv
;
312 if(pre_open_check(dev
) == -1)
314 priv
->infra_open
= 1 ;
315 netif_wake_queue(priv
->wlan_dev
.netdev
);
317 return wlan_dev_open(priv
->wlan_dev
.netdev
) ;
321 static int wlan_dev_close(struct net_device
*dev
)
323 wlan_private
*priv
= dev
->priv
;
327 netif_carrier_off(priv
->wlan_dev
.netdev
);
335 * @brief This function closes the mshX interface
337 * @param dev A pointer to net_device structure
340 static int mesh_close(struct net_device
*dev
)
342 wlan_private
*priv
= (wlan_private
*) (dev
->priv
);
345 netif_stop_queue(priv
->mesh_dev
);
346 if (priv
->infra_open
== 0)
347 return wlan_dev_close( ((wlan_private
*) dev
->priv
)->wlan_dev
.netdev
) ;
353 * @brief This function closes the ethX interface
355 * @param dev A pointer to net_device structure
358 static int wlan_close(struct net_device
*dev
) {
359 wlan_private
*priv
= (wlan_private
*) dev
->priv
;
361 netif_stop_queue(priv
->wlan_dev
.netdev
);
362 priv
->infra_open
= 0;
363 if (priv
->mesh_open
== 0)
364 return wlan_dev_close( ((wlan_private
*) dev
->priv
)->wlan_dev
.netdev
) ;
373 * @brief This function is a callback function. it is called by
374 * kernel to enter or exit power saving mode.
376 * @param pmdev A pointer to pm_dev
377 * @param pmreq pm_request_t
378 * @param pmdata A pointer to pmdata
381 static int wlan_pm_callback(struct pm_dev
*pmdev
, pm_request_t pmreq
,
384 wlan_private
*priv
= wlanpriv
;
385 wlan_adapter
*adapter
= priv
->adapter
;
386 struct net_device
*dev
= priv
->wlan_dev
.netdev
;
388 lbs_pr_debug(1, "WPRM_PM_CALLBACK: pmreq = %d.\n", pmreq
);
392 lbs_pr_debug(1, "WPRM_PM_CALLBACK: enter PM_SUSPEND.\n");
394 /* in associated mode */
395 if (adapter
->connect_status
== libertas_connected
) {
396 if ((adapter
->psstate
!= PS_STATE_SLEEP
)
399 "wlan_pm_callback: can't enter sleep mode\n");
404 * Detach the network interface
405 * if the network is running
407 if (netif_running(dev
)) {
408 netif_device_detach(dev
);
410 "netif_device_detach().\n");
412 libertas_sbi_suspend(priv
);
417 /* in non associated mode */
420 * Detach the network interface
421 * if the network is running
423 if (netif_running(dev
))
424 netif_device_detach(dev
);
427 * Storing and restoring of the regs be taken care
428 * at the driver rest will be done at wlan driver
429 * this makes driver independent of the card
432 libertas_sbi_suspend(priv
);
437 /* in associated mode */
438 if (adapter
->connect_status
== libertas_connected
) {
441 * Bring the inteface up first
442 * This case should not happen still ...
444 libertas_sbi_resume(priv
);
447 * Attach the network interface
448 * if the network is running
450 if (netif_running(dev
)) {
451 netif_device_attach(dev
);
453 "after netif_device_attach().\n");
456 "After netif attach, in associated mode.\n");
461 /* in non associated mode */
464 * Bring the inteface up first
465 * This case should not happen still ...
468 libertas_sbi_resume(priv
);
470 if (netif_running(dev
))
471 netif_device_attach(dev
);
473 lbs_pr_debug(1, "after netif attach, in NON associated mode.\n");
479 #endif /* ENABLE_PM */
481 static int wlan_hard_start_xmit(struct sk_buff
*skb
, struct net_device
*dev
)
484 wlan_private
*priv
= dev
->priv
;
488 if (priv
->wlan_dev
.dnld_sent
|| priv
->adapter
->TxLockFlag
) {
489 priv
->stats
.tx_dropped
++;
493 netif_stop_queue(priv
->wlan_dev
.netdev
);
495 if (libertas_process_tx(priv
, skb
) == 0)
496 dev
->trans_start
= jiffies
;
503 * @brief Mark mesh packets and handover them to wlan_hard_start_xmit
506 static int mesh_pre_start_xmit(struct sk_buff
*skb
, struct net_device
*dev
)
508 wlan_private
*priv
= dev
->priv
;
513 return wlan_hard_start_xmit(skb
, priv
->wlan_dev
.netdev
);
517 * @brief Mark non-mesh packets and handover them to wlan_hard_start_xmit
520 static int wlan_pre_start_xmit(struct sk_buff
*skb
, struct net_device
*dev
) {
522 UNSET_MESH_FRAME(skb
);
524 return wlan_hard_start_xmit(skb
, dev
);
527 static void wlan_tx_timeout(struct net_device
*dev
)
529 wlan_private
*priv
= (wlan_private
*) dev
->priv
;
533 lbs_pr_err("tx watch dog timeout!\n");
535 priv
->wlan_dev
.dnld_sent
= DNLD_RES_RECEIVED
;
536 dev
->trans_start
= jiffies
;
538 if (priv
->adapter
->currenttxskb
) {
539 if (priv
->adapter
->radiomode
== WLAN_RADIOMODE_RADIOTAP
) {
540 /* If we are here, we have not received feedback from
541 the previous packet. Assume TX_FAIL and move on. */
542 priv
->adapter
->eventcause
= 0x01000000;
543 libertas_send_tx_feedback(priv
);
545 wake_up_interruptible(&priv
->mainthread
.waitq
);
546 } else if (priv
->adapter
->connect_status
== libertas_connected
)
547 netif_wake_queue(priv
->wlan_dev
.netdev
);
553 * @brief This function returns the network statistics
555 * @param dev A pointer to wlan_private structure
556 * @return A pointer to net_device_stats structure
558 static struct net_device_stats
*wlan_get_stats(struct net_device
*dev
)
560 wlan_private
*priv
= (wlan_private
*) dev
->priv
;
565 static int wlan_set_mac_address(struct net_device
*dev
, void *addr
)
568 wlan_private
*priv
= (wlan_private
*) dev
->priv
;
569 wlan_adapter
*adapter
= priv
->adapter
;
570 struct sockaddr
*phwaddr
= addr
;
574 memset(adapter
->current_addr
, 0, ETH_ALEN
);
576 /* dev->dev_addr is 8 bytes */
577 lbs_dbg_hex("dev->dev_addr:", dev
->dev_addr
, ETH_ALEN
);
579 lbs_dbg_hex("addr:", phwaddr
->sa_data
, ETH_ALEN
);
580 memcpy(adapter
->current_addr
, phwaddr
->sa_data
, ETH_ALEN
);
582 ret
= libertas_prepare_and_send_command(priv
, cmd_802_11_mac_address
,
584 cmd_option_waitforrsp
, 0, NULL
);
587 lbs_pr_debug(1, "set mac address failed.\n");
592 lbs_dbg_hex("adapter->macaddr:", adapter
->current_addr
, ETH_ALEN
);
593 memcpy(dev
->dev_addr
, adapter
->current_addr
, ETH_ALEN
);
594 memcpy(((wlan_private
*) dev
->priv
)->mesh_dev
->dev_addr
, adapter
->current_addr
, ETH_ALEN
);
601 static int wlan_copy_multicast_address(wlan_adapter
* adapter
,
602 struct net_device
*dev
)
605 struct dev_mc_list
*mcptr
= dev
->mc_list
;
607 for (i
= 0; i
< dev
->mc_count
; i
++) {
608 memcpy(&adapter
->multicastlist
[i
], mcptr
->dmi_addr
, ETH_ALEN
);
616 static void wlan_set_multicast_list(struct net_device
*dev
)
618 wlan_private
*priv
= dev
->priv
;
619 wlan_adapter
*adapter
= priv
->adapter
;
624 oldpacketfilter
= adapter
->currentpacketfilter
;
626 if (dev
->flags
& IFF_PROMISC
) {
627 lbs_pr_debug(1, "enable Promiscuous mode\n");
628 adapter
->currentpacketfilter
|=
629 cmd_act_mac_promiscuous_enable
;
630 adapter
->currentpacketfilter
&=
631 ~(cmd_act_mac_all_multicast_enable
|
632 cmd_act_mac_multicast_enable
);
635 adapter
->currentpacketfilter
&=
636 ~cmd_act_mac_promiscuous_enable
;
638 if (dev
->flags
& IFF_ALLMULTI
|| dev
->mc_count
>
639 MRVDRV_MAX_MULTICAST_LIST_SIZE
) {
640 lbs_pr_debug(1, "Enabling All Multicast!\n");
641 adapter
->currentpacketfilter
|=
642 cmd_act_mac_all_multicast_enable
;
643 adapter
->currentpacketfilter
&=
644 ~cmd_act_mac_multicast_enable
;
646 adapter
->currentpacketfilter
&=
647 ~cmd_act_mac_all_multicast_enable
;
649 if (!dev
->mc_count
) {
650 lbs_pr_debug(1, "No multicast addresses - "
651 "disabling multicast!\n");
652 adapter
->currentpacketfilter
&=
653 ~cmd_act_mac_multicast_enable
;
657 adapter
->currentpacketfilter
|=
658 cmd_act_mac_multicast_enable
;
660 adapter
->nr_of_multicastmacaddr
=
661 wlan_copy_multicast_address(adapter
, dev
);
663 lbs_pr_debug(1, "Multicast addresses: %d\n",
666 for (i
= 0; i
< dev
->mc_count
; i
++) {
667 lbs_pr_debug(1, "Multicast address %d:"
668 "%x %x %x %x %x %x\n", i
,
669 adapter
->multicastlist
[i
][0],
670 adapter
->multicastlist
[i
][1],
671 adapter
->multicastlist
[i
][2],
672 adapter
->multicastlist
[i
][3],
673 adapter
->multicastlist
[i
][4],
674 adapter
->multicastlist
[i
][5]);
676 /* set multicast addresses to firmware */
677 libertas_prepare_and_send_command(priv
,
678 cmd_mac_multicast_adr
,
685 if (adapter
->currentpacketfilter
!= oldpacketfilter
) {
686 libertas_set_mac_packet_filter(priv
);
693 * @brief This function hanldes the major job in WLAN driver.
694 * it handles the event generated by firmware, rx data received
695 * from firmware and tx data sent from kernel.
697 * @param data A pointer to wlan_thread structure
700 static int wlan_service_main_thread(void *data
)
702 struct wlan_thread
*thread
= data
;
703 wlan_private
*priv
= thread
->priv
;
704 wlan_adapter
*adapter
= priv
->adapter
;
710 wlan_activate_thread(thread
);
712 init_waitqueue_entry(&wait
, current
);
715 lbs_pr_debug(1, "main-thread 111: intcounter=%d "
716 "currenttxskb=%p dnld_sent=%d\n",
718 adapter
->currenttxskb
, priv
->wlan_dev
.dnld_sent
);
720 add_wait_queue(&thread
->waitq
, &wait
);
721 set_current_state(TASK_INTERRUPTIBLE
);
722 spin_lock_irq(&adapter
->driver_lock
);
723 if ((adapter
->psstate
== PS_STATE_SLEEP
) ||
724 (!adapter
->intcounter
725 && (priv
->wlan_dev
.dnld_sent
|| adapter
->cur_cmd
||
726 list_empty(&adapter
->cmdpendingq
)))) {
728 "main-thread sleeping... Conn=%d IntC=%d PS_mode=%d PS_State=%d\n",
729 adapter
->connect_status
, adapter
->intcounter
,
730 adapter
->psmode
, adapter
->psstate
);
731 spin_unlock_irq(&adapter
->driver_lock
);
734 spin_unlock_irq(&adapter
->driver_lock
);
738 "main-thread 222 (waking up): intcounter=%d currenttxskb=%p "
739 "dnld_sent=%d\n", adapter
->intcounter
,
740 adapter
->currenttxskb
, priv
->wlan_dev
.dnld_sent
);
742 set_current_state(TASK_RUNNING
);
743 remove_wait_queue(&thread
->waitq
, &wait
);
746 lbs_pr_debug(1, "main-thread 333: intcounter=%d currenttxskb=%p "
749 adapter
->currenttxskb
, priv
->wlan_dev
.dnld_sent
);
751 if (kthread_should_stop()
752 || adapter
->surpriseremoved
) {
754 "main-thread: break from main thread: surpriseremoved=0x%x\n",
755 adapter
->surpriseremoved
);
760 spin_lock_irq(&adapter
->driver_lock
);
761 if (adapter
->intcounter
) {
763 adapter
->intcounter
= 0;
764 int_status
= libertas_sbi_get_int_status(priv
, &ireg
);
768 "main-thread: reading HOST_INT_STATUS_REG failed\n");
769 spin_unlock_irq(&adapter
->driver_lock
);
772 adapter
->hisregcpy
|= ireg
;
775 lbs_pr_debug(1, "main-thread 444: intcounter=%d currenttxskb=%p "
778 adapter
->currenttxskb
, priv
->wlan_dev
.dnld_sent
);
780 /* command response? */
781 if (adapter
->hisregcpy
& his_cmdupldrdy
) {
782 lbs_pr_debug(1, "main-thread: cmd response ready.\n");
784 adapter
->hisregcpy
&= ~his_cmdupldrdy
;
785 spin_unlock_irq(&adapter
->driver_lock
);
786 libertas_process_rx_command(priv
);
787 spin_lock_irq(&adapter
->driver_lock
);
791 if (adapter
->hisregcpy
& his_cardevent
) {
792 lbs_pr_debug(1, "main-thread: Card Event Activity.\n");
794 adapter
->hisregcpy
&= ~his_cardevent
;
796 if (libertas_sbi_read_event_cause(priv
)) {
798 "main-thread: libertas_sbi_read_event_cause failed.\n");
799 spin_unlock_irq(&adapter
->driver_lock
);
802 spin_unlock_irq(&adapter
->driver_lock
);
803 libertas_process_event(priv
);
805 spin_unlock_irq(&adapter
->driver_lock
);
807 /* Check if we need to confirm Sleep Request received previously */
808 if (adapter
->psstate
== PS_STATE_PRE_SLEEP
) {
809 if (!priv
->wlan_dev
.dnld_sent
&& !adapter
->cur_cmd
) {
810 if (adapter
->connect_status
==
811 libertas_connected
) {
813 "main_thread: PRE_SLEEP--intcounter=%d currenttxskb=%p "
814 "dnld_sent=%d cur_cmd=%p, confirm now\n",
816 adapter
->currenttxskb
,
817 priv
->wlan_dev
.dnld_sent
,
820 libertas_ps_confirm_sleep(priv
,
821 (u16
) adapter
->psmode
);
823 /* workaround for firmware sending
824 * deauth/linkloss event immediately
825 * after sleep request, remove this
826 * after firmware fixes it
828 adapter
->psstate
= PS_STATE_AWAKE
;
830 "main-thread: ignore PS_SleepConfirm in non-connected state\n");
835 /* The PS state is changed during processing of Sleep Request
838 if ((priv
->adapter
->psstate
== PS_STATE_SLEEP
) ||
839 (priv
->adapter
->psstate
== PS_STATE_PRE_SLEEP
))
842 /* Execute the next command */
843 if (!priv
->wlan_dev
.dnld_sent
&& !priv
->adapter
->cur_cmd
)
844 libertas_execute_next_command(priv
);
846 /* Wake-up command waiters which can't sleep in
847 * libertas_prepare_and_send_command
849 if (!adapter
->nr_cmd_pending
)
850 wake_up_all(&adapter
->cmd_pending
);
852 libertas_tx_runqueue(priv
);
855 del_timer(&adapter
->command_timer
);
856 adapter
->nr_cmd_pending
= 0;
857 wake_up_all(&adapter
->cmd_pending
);
858 wlan_deactivate_thread(thread
);
865 * @brief This function adds the card. it will probe the
866 * card, allocate the wlan_priv and initialize the device.
868 * @param card A pointer to card
869 * @return A pointer to wlan_private structure
871 wlan_private
*wlan_add_card(void *card
)
873 struct net_device
*dev
= NULL
;
874 struct net_device
*mesh_dev
= NULL
;
875 wlan_private
*priv
= NULL
;
879 /* Allocate an Ethernet device and register it */
880 if (!(dev
= alloc_etherdev(sizeof(wlan_private
)))) {
881 lbs_pr_alert( "Init ethernet device failed!\n");
887 /* allocate buffer for wlan_adapter */
888 if (!(priv
->adapter
= kmalloc(sizeof(wlan_adapter
), GFP_KERNEL
))) {
889 lbs_pr_alert( "Allocate buffer for wlan_adapter failed!\n");
893 /* Allocate a virtual mesh device */
894 if (!(mesh_dev
= alloc_netdev(0, "msh%d", ether_setup
))) {
895 lbs_pr_debug(1, "Init ethernet device failed!\n");
899 /* Both intervaces share the priv structure */
900 mesh_dev
->priv
= priv
;
902 /* init wlan_adapter */
903 memset(priv
->adapter
, 0, sizeof(wlan_adapter
));
905 priv
->wlan_dev
.netdev
= dev
;
906 priv
->wlan_dev
.card
= card
;
908 priv
->infra_open
= 0;
909 priv
->mesh_dev
= mesh_dev
;
912 SET_MODULE_OWNER(dev
);
913 SET_MODULE_OWNER(mesh_dev
);
915 /* Setup the OS Interface to our functions */
916 dev
->open
= wlan_open
;
917 dev
->hard_start_xmit
= wlan_pre_start_xmit
;
918 dev
->stop
= wlan_close
;
919 dev
->do_ioctl
= libertas_do_ioctl
;
920 dev
->set_mac_address
= wlan_set_mac_address
;
921 mesh_dev
->open
= mesh_open
;
922 mesh_dev
->hard_start_xmit
= mesh_pre_start_xmit
;
923 mesh_dev
->stop
= mesh_close
;
924 mesh_dev
->do_ioctl
= libertas_do_ioctl
;
925 memcpy(mesh_dev
->dev_addr
, wlanpriv
->wlan_dev
.netdev
->dev_addr
,
926 sizeof(wlanpriv
->wlan_dev
.netdev
->dev_addr
));
928 #define WLAN_WATCHDOG_TIMEOUT (5 * HZ)
930 dev
->tx_timeout
= wlan_tx_timeout
;
931 dev
->get_stats
= wlan_get_stats
;
932 dev
->watchdog_timeo
= WLAN_WATCHDOG_TIMEOUT
;
933 dev
->ethtool_ops
= &libertas_ethtool_ops
;
934 mesh_dev
->get_stats
= wlan_get_stats
;
935 mesh_dev
->ethtool_ops
= &libertas_ethtool_ops
;
938 dev
->wireless_handlers
= (struct iw_handler_def
*)&libertas_handler_def
;
939 mesh_dev
->wireless_handlers
= (struct iw_handler_def
*)&libertas_handler_def
;
941 #define NETIF_F_DYNALLOC 16
942 dev
->features
|= NETIF_F_DYNALLOC
;
943 dev
->flags
|= IFF_BROADCAST
| IFF_MULTICAST
;
944 dev
->set_multicast_list
= wlan_set_multicast_list
;
946 INIT_LIST_HEAD(&priv
->adapter
->cmdfreeq
);
947 INIT_LIST_HEAD(&priv
->adapter
->cmdpendingq
);
949 spin_lock_init(&priv
->adapter
->driver_lock
);
950 init_waitqueue_head(&priv
->adapter
->cmd_pending
);
951 priv
->adapter
->nr_cmd_pending
= 0;
953 lbs_pr_debug(1, "Starting kthread...\n");
954 priv
->mainthread
.priv
= priv
;
955 wlan_create_thread(wlan_service_main_thread
,
956 &priv
->mainthread
, "wlan_main_service");
959 create_singlethread_workqueue("libertas_assoc");
960 INIT_DELAYED_WORK(&priv
->assoc_work
, wlan_association_worker
);
963 * Register the device. Fillup the private data structure with
964 * relevant information from the card and request for the required
967 if (libertas_sbi_register_dev(priv
) < 0) {
968 lbs_pr_info("failed to register wlan device!\n");
969 goto err_registerdev
;
973 if (libertas_init_fw(priv
)) {
974 lbs_pr_debug(1, "Firmware Init failed\n");
975 goto err_registerdev
;
978 if (register_netdev(dev
)) {
979 lbs_pr_err("Cannot register network device!\n");
983 /* Register virtual mesh interface */
984 if (register_netdev(mesh_dev
)) {
985 lbs_pr_info("Cannot register mesh virtual interface!\n");
989 lbs_pr_info("%s: Marvell Wlan 802.11 adapter ", dev
->name
);
991 libertas_debugfs_init_one(priv
, dev
);
993 if (libertas_found
== MAX_DEVS
)
995 libertas_devs
[libertas_found
] = dev
;
998 if (!(wlan_pm_dev
= pm_register(PM_UNKNOWN_DEV
, 0, wlan_pm_callback
)))
999 lbs_pr_alert( "failed to register PM callback\n");
1001 if (class_device_create_file(&(mesh_dev
->class_dev
), &class_device_attr_libertas_mpp
))
1002 goto err_create_file
;
1008 class_device_remove_file(&(mesh_dev
->class_dev
), &class_device_attr_libertas_mpp
);
1010 libertas_sbi_unregister_dev(priv
);
1012 destroy_workqueue(priv
->assoc_thread
);
1013 /* Stop the thread servicing the interrupts */
1014 wake_up_interruptible(&priv
->mainthread
.waitq
);
1015 wlan_terminate_thread(&priv
->mainthread
);
1016 kfree(priv
->adapter
);
1019 free_netdev(mesh_dev
);
1026 static void wake_pending_cmdnodes(wlan_private
*priv
)
1028 struct cmd_ctrl_node
*cmdnode
;
1029 unsigned long flags
;
1031 spin_lock_irqsave(&priv
->adapter
->driver_lock
, flags
);
1032 list_for_each_entry(cmdnode
, &priv
->adapter
->cmdpendingq
, list
) {
1033 cmdnode
->cmdwaitqwoken
= 1;
1034 wake_up_interruptible(&cmdnode
->cmdwait_q
);
1036 spin_unlock_irqrestore(&priv
->adapter
->driver_lock
, flags
);
1040 int wlan_remove_card(void *card
)
1042 wlan_private
*priv
= libertas_sbi_get_priv(card
);
1043 wlan_adapter
*adapter
;
1044 struct net_device
*dev
;
1045 struct net_device
*mesh_dev
;
1046 union iwreq_data wrqu
;
1056 adapter
= priv
->adapter
;
1063 dev
= priv
->wlan_dev
.netdev
;
1064 mesh_dev
= priv
->mesh_dev
;
1066 netif_stop_queue(mesh_dev
);
1067 netif_stop_queue(priv
->wlan_dev
.netdev
);
1068 netif_carrier_off(priv
->wlan_dev
.netdev
);
1070 wake_pending_cmdnodes(priv
);
1072 class_device_remove_file(&(mesh_dev
->class_dev
), &class_device_attr_libertas_mpp
);
1073 unregister_netdev(mesh_dev
);
1074 unregister_netdev(dev
);
1076 cancel_delayed_work(&priv
->assoc_work
);
1077 destroy_workqueue(priv
->assoc_thread
);
1079 if (adapter
->psmode
== wlan802_11powermodemax_psp
) {
1080 adapter
->psmode
= wlan802_11powermodecam
;
1081 libertas_ps_wakeup(priv
, cmd_option_waitforrsp
);
1084 memset(wrqu
.ap_addr
.sa_data
, 0xaa, ETH_ALEN
);
1085 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
1086 wireless_send_event(priv
->wlan_dev
.netdev
, SIOCGIWAP
, &wrqu
, NULL
);
1089 pm_unregister(wlan_pm_dev
);
1092 adapter
->surpriseremoved
= 1;
1094 /* Stop the thread servicing the interrupts */
1095 wlan_terminate_thread(&priv
->mainthread
);
1097 libertas_debugfs_remove_one(priv
);
1099 lbs_pr_debug(1, "Free adapter\n");
1100 libertas_free_adapter(priv
);
1102 for (i
= 0; i
<libertas_found
; i
++) {
1103 if (libertas_devs
[i
]==priv
->wlan_dev
.netdev
) {
1104 libertas_devs
[i
] = libertas_devs
[--libertas_found
];
1105 libertas_devs
[libertas_found
] = NULL
;
1110 lbs_pr_debug(1, "Unregister finish\n");
1112 priv
->wlan_dev
.netdev
= NULL
;
1113 priv
->mesh_dev
= NULL
;
1114 free_netdev(mesh_dev
);
1123 * @brief This function finds the CFP in
1124 * region_cfp_table based on region and band parameter.
1126 * @param region The region code
1127 * @param band The band
1128 * @param cfp_no A pointer to CFP number
1129 * @return A pointer to CFP
1131 struct chan_freq_power
*libertas_get_region_cfp_table(u8 region
, u8 band
, int *cfp_no
)
1137 end
= sizeof(region_cfp_table
)/sizeof(struct region_cfp_table
);
1139 for (i
= 0; i
< end
; i
++) {
1140 lbs_pr_debug(1, "region_cfp_table[i].region=%d\n",
1141 region_cfp_table
[i
].region
);
1142 if (region_cfp_table
[i
].region
== region
) {
1143 *cfp_no
= region_cfp_table
[i
].cfp_no_BG
;
1145 return region_cfp_table
[i
].cfp_BG
;
1153 int libertas_set_regiontable(wlan_private
* priv
, u8 region
, u8 band
)
1155 wlan_adapter
*adapter
= priv
->adapter
;
1158 struct chan_freq_power
*cfp
;
1163 memset(adapter
->region_channel
, 0, sizeof(adapter
->region_channel
));
1166 cfp
= libertas_get_region_cfp_table(region
, band
, &cfp_no
);
1168 adapter
->region_channel
[i
].nrcfp
= cfp_no
;
1169 adapter
->region_channel
[i
].CFP
= cfp
;
1171 lbs_pr_debug(1, "wrong region code %#x in band B-G\n",
1175 adapter
->region_channel
[i
].valid
= 1;
1176 adapter
->region_channel
[i
].region
= region
;
1177 adapter
->region_channel
[i
].band
= band
;
1185 * @brief This function handles the interrupt. it will change PS
1186 * state if applicable. it will wake up main_thread to handle
1187 * the interrupt event as well.
1189 * @param dev A pointer to net_device structure
1192 void libertas_interrupt(struct net_device
*dev
)
1194 wlan_private
*priv
= dev
->priv
;
1198 lbs_pr_debug(1, "libertas_interrupt: intcounter=%d\n",
1199 priv
->adapter
->intcounter
);
1201 priv
->adapter
->intcounter
++;
1203 if (priv
->adapter
->psstate
== PS_STATE_SLEEP
) {
1204 priv
->adapter
->psstate
= PS_STATE_AWAKE
;
1205 netif_wake_queue(dev
);
1208 wake_up_interruptible(&priv
->mainthread
.waitq
);
1213 static int wlan_init_module(void)
1219 if (libertas_fw_name
== NULL
) {
1220 libertas_fw_name
= default_fw_name
;
1223 libertas_debugfs_init();
1225 if (libertas_sbi_register()) {
1227 libertas_debugfs_remove();
1236 static void wlan_cleanup_module(void)
1242 for (i
= 0; i
<libertas_found
; i
++) {
1243 wlan_private
*priv
= libertas_devs
[i
]->priv
;
1247 libertas_sbi_unregister();
1248 libertas_debugfs_remove();
1253 module_init(wlan_init_module
);
1254 module_exit(wlan_cleanup_module
);
1256 MODULE_DESCRIPTION("M-WLAN Driver");
1257 MODULE_AUTHOR("Marvell International Ltd.");
1258 MODULE_LICENSE("GPL");