aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/libertas/main.c')
-rw-r--r--drivers/net/wireless/libertas/main.c289
1 files changed, 169 insertions, 120 deletions
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 4d4e2f3b66ac..406f54d40956 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -10,6 +10,7 @@
10#include <linux/netdevice.h> 10#include <linux/netdevice.h>
11#include <linux/if_arp.h> 11#include <linux/if_arp.h>
12#include <linux/kthread.h> 12#include <linux/kthread.h>
13#include <linux/kfifo.h>
13 14
14#include <net/iw_handler.h> 15#include <net/iw_handler.h>
15#include <net/ieee80211.h> 16#include <net/ieee80211.h>
@@ -19,8 +20,8 @@
19#include "dev.h" 20#include "dev.h"
20#include "wext.h" 21#include "wext.h"
21#include "debugfs.h" 22#include "debugfs.h"
23#include "scan.h"
22#include "assoc.h" 24#include "assoc.h"
23#include "join.h"
24#include "cmd.h" 25#include "cmd.h"
25 26
26#define DRIVER_RELEASE_VERSION "323.p0" 27#define DRIVER_RELEASE_VERSION "323.p0"
@@ -37,6 +38,11 @@ EXPORT_SYMBOL_GPL(lbs_debug);
37module_param_named(libertas_debug, lbs_debug, int, 0644); 38module_param_named(libertas_debug, lbs_debug, int, 0644);
38 39
39 40
41/* This global structure is used to send the confirm_sleep command as
42 * fast as possible down to the firmware. */
43struct cmd_confirm_sleep confirm_sleep;
44
45
40#define LBS_TX_PWR_DEFAULT 20 /*100mW */ 46#define LBS_TX_PWR_DEFAULT 20 /*100mW */
41#define LBS_TX_PWR_US_DEFAULT 20 /*100mW */ 47#define LBS_TX_PWR_US_DEFAULT 20 /*100mW */
42#define LBS_TX_PWR_JP_DEFAULT 16 /*50mW */ 48#define LBS_TX_PWR_JP_DEFAULT 16 /*50mW */
@@ -277,10 +283,10 @@ static ssize_t lbs_rtap_set(struct device *dev,
277 struct lbs_private *priv = to_net_dev(dev)->priv; 283 struct lbs_private *priv = to_net_dev(dev)->priv;
278 284
279 sscanf(buf, "%x", &monitor_mode); 285 sscanf(buf, "%x", &monitor_mode);
280 if (monitor_mode != LBS_MONITOR_OFF) { 286 if (monitor_mode) {
281 if(priv->monitormode == monitor_mode) 287 if (priv->monitormode == monitor_mode)
282 return strlen(buf); 288 return strlen(buf);
283 if (priv->monitormode == LBS_MONITOR_OFF) { 289 if (!priv->monitormode) {
284 if (priv->infra_open || priv->mesh_open) 290 if (priv->infra_open || priv->mesh_open)
285 return -EBUSY; 291 return -EBUSY;
286 if (priv->mode == IW_MODE_INFRA) 292 if (priv->mode == IW_MODE_INFRA)
@@ -293,9 +299,9 @@ static ssize_t lbs_rtap_set(struct device *dev,
293 } 299 }
294 300
295 else { 301 else {
296 if (priv->monitormode == LBS_MONITOR_OFF) 302 if (!priv->monitormode)
297 return strlen(buf); 303 return strlen(buf);
298 priv->monitormode = LBS_MONITOR_OFF; 304 priv->monitormode = 0;
299 lbs_remove_rtap(priv); 305 lbs_remove_rtap(priv);
300 306
301 if (priv->currenttxskb) { 307 if (priv->currenttxskb) {
@@ -392,7 +398,7 @@ static int lbs_dev_open(struct net_device *dev)
392 398
393 spin_lock_irq(&priv->driver_lock); 399 spin_lock_irq(&priv->driver_lock);
394 400
395 if (priv->monitormode != LBS_MONITOR_OFF) { 401 if (priv->monitormode) {
396 ret = -EBUSY; 402 ret = -EBUSY;
397 goto out; 403 goto out;
398 } 404 }
@@ -475,10 +481,9 @@ static void lbs_tx_timeout(struct net_device *dev)
475 481
476 dev->trans_start = jiffies; 482 dev->trans_start = jiffies;
477 483
478 if (priv->currenttxskb) { 484 if (priv->currenttxskb)
479 priv->eventcause = 0x01000000; 485 lbs_send_tx_feedback(priv, 0);
480 lbs_send_tx_feedback(priv); 486
481 }
482 /* XX: Shouldn't we also call into the hw-specific driver 487 /* XX: Shouldn't we also call into the hw-specific driver
483 to kick it somehow? */ 488 to kick it somehow? */
484 lbs_host_to_card_done(priv); 489 lbs_host_to_card_done(priv);
@@ -531,34 +536,27 @@ static int lbs_set_mac_address(struct net_device *dev, void *addr)
531 int ret = 0; 536 int ret = 0;
532 struct lbs_private *priv = (struct lbs_private *) dev->priv; 537 struct lbs_private *priv = (struct lbs_private *) dev->priv;
533 struct sockaddr *phwaddr = addr; 538 struct sockaddr *phwaddr = addr;
539 struct cmd_ds_802_11_mac_address cmd;
534 540
535 lbs_deb_enter(LBS_DEB_NET); 541 lbs_deb_enter(LBS_DEB_NET);
536 542
537 /* In case it was called from the mesh device */ 543 /* In case it was called from the mesh device */
538 dev = priv->dev ; 544 dev = priv->dev;
539
540 memset(priv->current_addr, 0, ETH_ALEN);
541
542 /* dev->dev_addr is 8 bytes */
543 lbs_deb_hex(LBS_DEB_NET, "dev->dev_addr", dev->dev_addr, ETH_ALEN);
544
545 lbs_deb_hex(LBS_DEB_NET, "addr", phwaddr->sa_data, ETH_ALEN);
546 memcpy(priv->current_addr, phwaddr->sa_data, ETH_ALEN);
547 545
548 ret = lbs_prepare_and_send_command(priv, CMD_802_11_MAC_ADDRESS, 546 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
549 CMD_ACT_SET, 547 cmd.action = cpu_to_le16(CMD_ACT_SET);
550 CMD_OPTION_WAITFORRSP, 0, NULL); 548 memcpy(cmd.macadd, phwaddr->sa_data, ETH_ALEN);
551 549
550 ret = lbs_cmd_with_response(priv, CMD_802_11_MAC_ADDRESS, &cmd);
552 if (ret) { 551 if (ret) {
553 lbs_deb_net("set MAC address failed\n"); 552 lbs_deb_net("set MAC address failed\n");
554 ret = -1;
555 goto done; 553 goto done;
556 } 554 }
557 555
558 lbs_deb_hex(LBS_DEB_NET, "priv->macaddr", priv->current_addr, ETH_ALEN); 556 memcpy(priv->current_addr, phwaddr->sa_data, ETH_ALEN);
559 memcpy(dev->dev_addr, priv->current_addr, ETH_ALEN); 557 memcpy(dev->dev_addr, phwaddr->sa_data, ETH_ALEN);
560 if (priv->mesh_dev) 558 if (priv->mesh_dev)
561 memcpy(priv->mesh_dev->dev_addr, priv->current_addr, ETH_ALEN); 559 memcpy(priv->mesh_dev->dev_addr, phwaddr->sa_data, ETH_ALEN);
562 560
563done: 561done:
564 lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret); 562 lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
@@ -581,45 +579,45 @@ static int lbs_copy_multicast_address(struct lbs_private *priv,
581static void lbs_set_multicast_list(struct net_device *dev) 579static void lbs_set_multicast_list(struct net_device *dev)
582{ 580{
583 struct lbs_private *priv = dev->priv; 581 struct lbs_private *priv = dev->priv;
584 int oldpacketfilter; 582 int old_mac_control;
585 DECLARE_MAC_BUF(mac); 583 DECLARE_MAC_BUF(mac);
586 584
587 lbs_deb_enter(LBS_DEB_NET); 585 lbs_deb_enter(LBS_DEB_NET);
588 586
589 oldpacketfilter = priv->currentpacketfilter; 587 old_mac_control = priv->mac_control;
590 588
591 if (dev->flags & IFF_PROMISC) { 589 if (dev->flags & IFF_PROMISC) {
592 lbs_deb_net("enable promiscuous mode\n"); 590 lbs_deb_net("enable promiscuous mode\n");
593 priv->currentpacketfilter |= 591 priv->mac_control |=
594 CMD_ACT_MAC_PROMISCUOUS_ENABLE; 592 CMD_ACT_MAC_PROMISCUOUS_ENABLE;
595 priv->currentpacketfilter &= 593 priv->mac_control &=
596 ~(CMD_ACT_MAC_ALL_MULTICAST_ENABLE | 594 ~(CMD_ACT_MAC_ALL_MULTICAST_ENABLE |
597 CMD_ACT_MAC_MULTICAST_ENABLE); 595 CMD_ACT_MAC_MULTICAST_ENABLE);
598 } else { 596 } else {
599 /* Multicast */ 597 /* Multicast */
600 priv->currentpacketfilter &= 598 priv->mac_control &=
601 ~CMD_ACT_MAC_PROMISCUOUS_ENABLE; 599 ~CMD_ACT_MAC_PROMISCUOUS_ENABLE;
602 600
603 if (dev->flags & IFF_ALLMULTI || dev->mc_count > 601 if (dev->flags & IFF_ALLMULTI || dev->mc_count >
604 MRVDRV_MAX_MULTICAST_LIST_SIZE) { 602 MRVDRV_MAX_MULTICAST_LIST_SIZE) {
605 lbs_deb_net( "enabling all multicast\n"); 603 lbs_deb_net( "enabling all multicast\n");
606 priv->currentpacketfilter |= 604 priv->mac_control |=
607 CMD_ACT_MAC_ALL_MULTICAST_ENABLE; 605 CMD_ACT_MAC_ALL_MULTICAST_ENABLE;
608 priv->currentpacketfilter &= 606 priv->mac_control &=
609 ~CMD_ACT_MAC_MULTICAST_ENABLE; 607 ~CMD_ACT_MAC_MULTICAST_ENABLE;
610 } else { 608 } else {
611 priv->currentpacketfilter &= 609 priv->mac_control &=
612 ~CMD_ACT_MAC_ALL_MULTICAST_ENABLE; 610 ~CMD_ACT_MAC_ALL_MULTICAST_ENABLE;
613 611
614 if (!dev->mc_count) { 612 if (!dev->mc_count) {
615 lbs_deb_net("no multicast addresses, " 613 lbs_deb_net("no multicast addresses, "
616 "disabling multicast\n"); 614 "disabling multicast\n");
617 priv->currentpacketfilter &= 615 priv->mac_control &=
618 ~CMD_ACT_MAC_MULTICAST_ENABLE; 616 ~CMD_ACT_MAC_MULTICAST_ENABLE;
619 } else { 617 } else {
620 int i; 618 int i;
621 619
622 priv->currentpacketfilter |= 620 priv->mac_control |=
623 CMD_ACT_MAC_MULTICAST_ENABLE; 621 CMD_ACT_MAC_MULTICAST_ENABLE;
624 622
625 priv->nr_of_multicastmacaddr = 623 priv->nr_of_multicastmacaddr =
@@ -642,9 +640,8 @@ static void lbs_set_multicast_list(struct net_device *dev)
642 } 640 }
643 } 641 }
644 642
645 if (priv->currentpacketfilter != oldpacketfilter) { 643 if (priv->mac_control != old_mac_control)
646 lbs_set_mac_packet_filter(priv); 644 lbs_set_mac_control(priv);
647 }
648 645
649 lbs_deb_leave(LBS_DEB_NET); 646 lbs_deb_leave(LBS_DEB_NET);
650} 647}
@@ -662,7 +659,6 @@ static int lbs_thread(void *data)
662 struct net_device *dev = data; 659 struct net_device *dev = data;
663 struct lbs_private *priv = dev->priv; 660 struct lbs_private *priv = dev->priv;
664 wait_queue_t wait; 661 wait_queue_t wait;
665 u8 ireg = 0;
666 662
667 lbs_deb_enter(LBS_DEB_THREAD); 663 lbs_deb_enter(LBS_DEB_THREAD);
668 664
@@ -670,9 +666,10 @@ static int lbs_thread(void *data)
670 666
671 for (;;) { 667 for (;;) {
672 int shouldsleep; 668 int shouldsleep;
669 u8 resp_idx;
673 670
674 lbs_deb_thread( "main-thread 111: intcounter=%d currenttxskb=%p dnld_sent=%d\n", 671 lbs_deb_thread("1: currenttxskb %p, dnld_sent %d\n",
675 priv->intcounter, priv->currenttxskb, priv->dnld_sent); 672 priv->currenttxskb, priv->dnld_sent);
676 673
677 add_wait_queue(&priv->waitq, &wait); 674 add_wait_queue(&priv->waitq, &wait);
678 set_current_state(TASK_INTERRUPTIBLE); 675 set_current_state(TASK_INTERRUPTIBLE);
@@ -684,8 +681,6 @@ static int lbs_thread(void *data)
684 shouldsleep = 1; /* We need to wait until we're _told_ to die */ 681 shouldsleep = 1; /* We need to wait until we're _told_ to die */
685 else if (priv->psstate == PS_STATE_SLEEP) 682 else if (priv->psstate == PS_STATE_SLEEP)
686 shouldsleep = 1; /* Sleep mode. Nothing we can do till it wakes */ 683 shouldsleep = 1; /* Sleep mode. Nothing we can do till it wakes */
687 else if (priv->intcounter)
688 shouldsleep = 0; /* Interrupt pending. Deal with it now */
689 else if (priv->cmd_timed_out) 684 else if (priv->cmd_timed_out)
690 shouldsleep = 0; /* Command timed out. Recover */ 685 shouldsleep = 0; /* Command timed out. Recover */
691 else if (!priv->fw_ready) 686 else if (!priv->fw_ready)
@@ -698,29 +693,34 @@ static int lbs_thread(void *data)
698 shouldsleep = 1; /* Can't send a command; one already running */ 693 shouldsleep = 1; /* Can't send a command; one already running */
699 else if (!list_empty(&priv->cmdpendingq)) 694 else if (!list_empty(&priv->cmdpendingq))
700 shouldsleep = 0; /* We have a command to send */ 695 shouldsleep = 0; /* We have a command to send */
696 else if (__kfifo_len(priv->event_fifo))
697 shouldsleep = 0; /* We have an event to process */
698 else if (priv->resp_len[priv->resp_idx])
699 shouldsleep = 0; /* We have a command response */
701 else 700 else
702 shouldsleep = 1; /* No command */ 701 shouldsleep = 1; /* No command */
703 702
704 if (shouldsleep) { 703 if (shouldsleep) {
705 lbs_deb_thread("main-thread sleeping... Conn=%d IntC=%d PS_mode=%d PS_State=%d\n", 704 lbs_deb_thread("sleeping, connect_status %d, "
706 priv->connect_status, priv->intcounter, 705 "ps_mode %d, ps_state %d\n",
707 priv->psmode, priv->psstate); 706 priv->connect_status,
707 priv->psmode, priv->psstate);
708 spin_unlock_irq(&priv->driver_lock); 708 spin_unlock_irq(&priv->driver_lock);
709 schedule(); 709 schedule();
710 } else 710 } else
711 spin_unlock_irq(&priv->driver_lock); 711 spin_unlock_irq(&priv->driver_lock);
712 712
713 lbs_deb_thread("main-thread 222 (waking up): intcounter=%d currenttxskb=%p dnld_sent=%d\n", 713 lbs_deb_thread("2: currenttxskb %p, dnld_send %d\n",
714 priv->intcounter, priv->currenttxskb, priv->dnld_sent); 714 priv->currenttxskb, priv->dnld_sent);
715 715
716 set_current_state(TASK_RUNNING); 716 set_current_state(TASK_RUNNING);
717 remove_wait_queue(&priv->waitq, &wait); 717 remove_wait_queue(&priv->waitq, &wait);
718 718
719 lbs_deb_thread("main-thread 333: intcounter=%d currenttxskb=%p dnld_sent=%d\n", 719 lbs_deb_thread("3: currenttxskb %p, dnld_sent %d\n",
720 priv->intcounter, priv->currenttxskb, priv->dnld_sent); 720 priv->currenttxskb, priv->dnld_sent);
721 721
722 if (kthread_should_stop()) { 722 if (kthread_should_stop()) {
723 lbs_deb_thread("main-thread: break from main thread\n"); 723 lbs_deb_thread("break from main thread\n");
724 break; 724 break;
725 } 725 }
726 726
@@ -729,35 +729,23 @@ static int lbs_thread(void *data)
729 continue; 729 continue;
730 } 730 }
731 731
732 spin_lock_irq(&priv->driver_lock); 732 lbs_deb_thread("4: currenttxskb %p, dnld_sent %d\n",
733 733 priv->currenttxskb, priv->dnld_sent);
734 if (priv->intcounter) {
735 u8 int_status;
736
737 priv->intcounter = 0;
738 int_status = priv->hw_get_int_status(priv, &ireg);
739
740 if (int_status) {
741 lbs_deb_thread("main-thread: reading HOST_INT_STATUS_REG failed\n");
742 spin_unlock_irq(&priv->driver_lock);
743 continue;
744 }
745 priv->hisregcpy |= ireg;
746 }
747
748 lbs_deb_thread("main-thread 444: intcounter=%d currenttxskb=%p dnld_sent=%d\n",
749 priv->intcounter, priv->currenttxskb, priv->dnld_sent);
750 734
751 /* command response? */ 735 spin_lock_irq(&priv->driver_lock);
752 if (priv->hisregcpy & MRVDRV_CMD_UPLD_RDY) { 736 /* Process any pending command response */
753 lbs_deb_thread("main-thread: cmd response ready\n"); 737 resp_idx = priv->resp_idx;
754 738 if (priv->resp_len[resp_idx]) {
755 priv->hisregcpy &= ~MRVDRV_CMD_UPLD_RDY;
756 spin_unlock_irq(&priv->driver_lock); 739 spin_unlock_irq(&priv->driver_lock);
757 lbs_process_rx_command(priv); 740 lbs_process_command_response(priv,
741 priv->resp_buf[resp_idx],
742 priv->resp_len[resp_idx]);
758 spin_lock_irq(&priv->driver_lock); 743 spin_lock_irq(&priv->driver_lock);
744 priv->resp_len[resp_idx] = 0;
759 } 745 }
746 spin_unlock_irq(&priv->driver_lock);
760 747
748 /* command timeout stuff */
761 if (priv->cmd_timed_out && priv->cur_cmd) { 749 if (priv->cmd_timed_out && priv->cur_cmd) {
762 struct cmd_ctrl_node *cmdnode = priv->cur_cmd; 750 struct cmd_ctrl_node *cmdnode = priv->cur_cmd;
763 751
@@ -778,21 +766,18 @@ static int lbs_thread(void *data)
778 } 766 }
779 priv->cmd_timed_out = 0; 767 priv->cmd_timed_out = 0;
780 768
781 /* Any Card Event */ 769 /* Process hardware events, e.g. card removed, link lost */
782 if (priv->hisregcpy & MRVDRV_CARDEVENT) { 770 spin_lock_irq(&priv->driver_lock);
783 lbs_deb_thread("main-thread: Card Event Activity\n"); 771 while (__kfifo_len(priv->event_fifo)) {
784 772 u32 event;
785 priv->hisregcpy &= ~MRVDRV_CARDEVENT;
786 773
787 if (priv->hw_read_event_cause(priv)) { 774 __kfifo_get(priv->event_fifo, (unsigned char *) &event,
788 lbs_pr_alert("main-thread: hw_read_event_cause failed\n"); 775 sizeof(event));
789 spin_unlock_irq(&priv->driver_lock);
790 continue;
791 }
792 spin_unlock_irq(&priv->driver_lock);
793 lbs_process_event(priv);
794 } else
795 spin_unlock_irq(&priv->driver_lock); 776 spin_unlock_irq(&priv->driver_lock);
777 lbs_process_event(priv, event);
778 spin_lock_irq(&priv->driver_lock);
779 }
780 spin_unlock_irq(&priv->driver_lock);
796 781
797 if (!priv->fw_ready) 782 if (!priv->fw_ready)
798 continue; 783 continue;
@@ -801,10 +786,12 @@ static int lbs_thread(void *data)
801 if (priv->psstate == PS_STATE_PRE_SLEEP && 786 if (priv->psstate == PS_STATE_PRE_SLEEP &&
802 !priv->dnld_sent && !priv->cur_cmd) { 787 !priv->dnld_sent && !priv->cur_cmd) {
803 if (priv->connect_status == LBS_CONNECTED) { 788 if (priv->connect_status == LBS_CONNECTED) {
804 lbs_deb_thread("main_thread: PRE_SLEEP--intcounter=%d currenttxskb=%p dnld_sent=%d cur_cmd=%p, confirm now\n", 789 lbs_deb_thread("pre-sleep, currenttxskb %p, "
805 priv->intcounter, priv->currenttxskb, priv->dnld_sent, priv->cur_cmd); 790 "dnld_sent %d, cur_cmd %p\n",
791 priv->currenttxskb, priv->dnld_sent,
792 priv->cur_cmd);
806 793
807 lbs_ps_confirm_sleep(priv, (u16) priv->psmode); 794 lbs_ps_confirm_sleep(priv);
808 } else { 795 } else {
809 /* workaround for firmware sending 796 /* workaround for firmware sending
810 * deauth/linkloss event immediately 797 * deauth/linkloss event immediately
@@ -812,7 +799,8 @@ static int lbs_thread(void *data)
812 * after firmware fixes it 799 * after firmware fixes it
813 */ 800 */
814 priv->psstate = PS_STATE_AWAKE; 801 priv->psstate = PS_STATE_AWAKE;
815 lbs_pr_alert("main-thread: ignore PS_SleepConfirm in non-connected state\n"); 802 lbs_pr_alert("ignore PS_SleepConfirm in "
803 "non-connected state\n");
816 } 804 }
817 } 805 }
818 806
@@ -945,7 +933,7 @@ static int lbs_setup_firmware(struct lbs_private *priv)
945 goto done; 933 goto done;
946 } 934 }
947 935
948 lbs_set_mac_packet_filter(priv); 936 lbs_set_mac_control(priv);
949 937
950 ret = lbs_get_data_rate(priv); 938 ret = lbs_get_data_rate(priv);
951 if (ret < 0) { 939 if (ret < 0) {
@@ -985,6 +973,18 @@ out:
985 lbs_deb_leave(LBS_DEB_CMD); 973 lbs_deb_leave(LBS_DEB_CMD);
986} 974}
987 975
976static void lbs_sync_channel_worker(struct work_struct *work)
977{
978 struct lbs_private *priv = container_of(work, struct lbs_private,
979 sync_channel);
980
981 lbs_deb_enter(LBS_DEB_MAIN);
982 if (lbs_update_channel(priv))
983 lbs_pr_info("Channel synchronization failed.");
984 lbs_deb_leave(LBS_DEB_MAIN);
985}
986
987
988static int lbs_init_adapter(struct lbs_private *priv) 988static int lbs_init_adapter(struct lbs_private *priv)
989{ 989{
990 size_t bufsize; 990 size_t bufsize;
@@ -1009,14 +1009,6 @@ static int lbs_init_adapter(struct lbs_private *priv)
1009 &priv->network_free_list); 1009 &priv->network_free_list);
1010 } 1010 }
1011 1011
1012 priv->lbs_ps_confirm_sleep.seqnum = cpu_to_le16(++priv->seqnum);
1013 priv->lbs_ps_confirm_sleep.command =
1014 cpu_to_le16(CMD_802_11_PS_MODE);
1015 priv->lbs_ps_confirm_sleep.size =
1016 cpu_to_le16(sizeof(struct PS_CMD_ConfirmSleep));
1017 priv->lbs_ps_confirm_sleep.action =
1018 cpu_to_le16(CMD_SUBCMD_SLEEP_CONFIRMED);
1019
1020 memset(priv->current_addr, 0xff, ETH_ALEN); 1012 memset(priv->current_addr, 0xff, ETH_ALEN);
1021 1013
1022 priv->connect_status = LBS_DISCONNECTED; 1014 priv->connect_status = LBS_DISCONNECTED;
@@ -1024,7 +1016,7 @@ static int lbs_init_adapter(struct lbs_private *priv)
1024 priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; 1016 priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
1025 priv->mode = IW_MODE_INFRA; 1017 priv->mode = IW_MODE_INFRA;
1026 priv->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL; 1018 priv->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL;
1027 priv->currentpacketfilter = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON; 1019 priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON;
1028 priv->radioon = RADIO_ON; 1020 priv->radioon = RADIO_ON;
1029 priv->auto_rate = 1; 1021 priv->auto_rate = 1;
1030 priv->capability = WLAN_CAPABILITY_SHORT_PREAMBLE; 1022 priv->capability = WLAN_CAPABILITY_SHORT_PREAMBLE;
@@ -1045,7 +1037,18 @@ static int lbs_init_adapter(struct lbs_private *priv)
1045 /* Allocate the command buffers */ 1037 /* Allocate the command buffers */
1046 if (lbs_allocate_cmd_buffer(priv)) { 1038 if (lbs_allocate_cmd_buffer(priv)) {
1047 lbs_pr_err("Out of memory allocating command buffers\n"); 1039 lbs_pr_err("Out of memory allocating command buffers\n");
1048 ret = -1; 1040 ret = -ENOMEM;
1041 goto out;
1042 }
1043 priv->resp_idx = 0;
1044 priv->resp_len[0] = priv->resp_len[1] = 0;
1045
1046 /* Create the event FIFO */
1047 priv->event_fifo = kfifo_alloc(sizeof(u32) * 16, GFP_KERNEL, NULL);
1048 if (IS_ERR(priv->event_fifo)) {
1049 lbs_pr_err("Out of memory allocating event FIFO buffer\n");
1050 ret = -ENOMEM;
1051 goto out;
1049 } 1052 }
1050 1053
1051out: 1054out:
@@ -1059,6 +1062,8 @@ static void lbs_free_adapter(struct lbs_private *priv)
1059 lbs_deb_enter(LBS_DEB_MAIN); 1062 lbs_deb_enter(LBS_DEB_MAIN);
1060 1063
1061 lbs_free_cmd_buffer(priv); 1064 lbs_free_cmd_buffer(priv);
1065 if (priv->event_fifo)
1066 kfifo_free(priv->event_fifo);
1062 del_timer(&priv->command_timer); 1067 del_timer(&priv->command_timer);
1063 kfree(priv->networks); 1068 kfree(priv->networks);
1064 priv->networks = NULL; 1069 priv->networks = NULL;
@@ -1128,7 +1133,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
1128 priv->work_thread = create_singlethread_workqueue("lbs_worker"); 1133 priv->work_thread = create_singlethread_workqueue("lbs_worker");
1129 INIT_DELAYED_WORK(&priv->assoc_work, lbs_association_worker); 1134 INIT_DELAYED_WORK(&priv->assoc_work, lbs_association_worker);
1130 INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker); 1135 INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker);
1131 INIT_WORK(&priv->sync_channel, lbs_sync_channel); 1136 INIT_WORK(&priv->sync_channel, lbs_sync_channel_worker);
1132 1137
1133 sprintf(priv->mesh_ssid, "mesh"); 1138 sprintf(priv->mesh_ssid, "mesh");
1134 priv->mesh_ssid_len = 4; 1139 priv->mesh_ssid_len = 4;
@@ -1380,7 +1385,7 @@ static void lbs_remove_mesh(struct lbs_private *priv)
1380 * @param cfp_no A pointer to CFP number 1385 * @param cfp_no A pointer to CFP number
1381 * @return A pointer to CFP 1386 * @return A pointer to CFP
1382 */ 1387 */
1383struct chan_freq_power *lbs_get_region_cfp_table(u8 region, u8 band, int *cfp_no) 1388struct chan_freq_power *lbs_get_region_cfp_table(u8 region, int *cfp_no)
1384{ 1389{
1385 int i, end; 1390 int i, end;
1386 1391
@@ -1414,7 +1419,7 @@ int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band)
1414 1419
1415 memset(priv->region_channel, 0, sizeof(priv->region_channel)); 1420 memset(priv->region_channel, 0, sizeof(priv->region_channel));
1416 1421
1417 cfp = lbs_get_region_cfp_table(region, band, &cfp_no); 1422 cfp = lbs_get_region_cfp_table(region, &cfp_no);
1418 if (cfp != NULL) { 1423 if (cfp != NULL) {
1419 priv->region_channel[i].nrcfp = cfp_no; 1424 priv->region_channel[i].nrcfp = cfp_no;
1420 priv->region_channel[i].CFP = cfp; 1425 priv->region_channel[i].CFP = cfp;
@@ -1433,31 +1438,49 @@ out:
1433 return ret; 1438 return ret;
1434} 1439}
1435 1440
1436/** 1441void lbs_queue_event(struct lbs_private *priv, u32 event)
1437 * @brief This function handles the interrupt. it will change PS 1442{
1438 * state if applicable. it will wake up main_thread to handle 1443 unsigned long flags;
1439 * the interrupt event as well. 1444
1440 * 1445 lbs_deb_enter(LBS_DEB_THREAD);
1441 * @param dev A pointer to net_device structure 1446 spin_lock_irqsave(&priv->driver_lock, flags);
1442 * @return n/a 1447
1443 */ 1448 if (priv->psstate == PS_STATE_SLEEP)
1444void lbs_interrupt(struct lbs_private *priv) 1449 priv->psstate = PS_STATE_AWAKE;
1450
1451 __kfifo_put(priv->event_fifo, (unsigned char *) &event, sizeof(u32));
1452
1453 wake_up_interruptible(&priv->waitq);
1454
1455 spin_unlock_irqrestore(&priv->driver_lock, flags);
1456 lbs_deb_leave(LBS_DEB_THREAD);
1457}
1458EXPORT_SYMBOL_GPL(lbs_queue_event);
1459
1460void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx)
1445{ 1461{
1446 lbs_deb_enter(LBS_DEB_THREAD); 1462 lbs_deb_enter(LBS_DEB_THREAD);
1447 1463
1448 lbs_deb_thread("lbs_interrupt: intcounter=%d\n", priv->intcounter);
1449 priv->intcounter++;
1450 if (priv->psstate == PS_STATE_SLEEP) 1464 if (priv->psstate == PS_STATE_SLEEP)
1451 priv->psstate = PS_STATE_AWAKE; 1465 priv->psstate = PS_STATE_AWAKE;
1466
1467 /* Swap buffers by flipping the response index */
1468 BUG_ON(resp_idx > 1);
1469 priv->resp_idx = resp_idx;
1470
1452 wake_up_interruptible(&priv->waitq); 1471 wake_up_interruptible(&priv->waitq);
1453 1472
1454 lbs_deb_leave(LBS_DEB_THREAD); 1473 lbs_deb_leave(LBS_DEB_THREAD);
1455} 1474}
1456EXPORT_SYMBOL_GPL(lbs_interrupt); 1475EXPORT_SYMBOL_GPL(lbs_notify_command_response);
1457 1476
1458static int __init lbs_init_module(void) 1477static int __init lbs_init_module(void)
1459{ 1478{
1460 lbs_deb_enter(LBS_DEB_MAIN); 1479 lbs_deb_enter(LBS_DEB_MAIN);
1480 memset(&confirm_sleep, 0, sizeof(confirm_sleep));
1481 confirm_sleep.hdr.command = cpu_to_le16(CMD_802_11_PS_MODE);
1482 confirm_sleep.hdr.size = cpu_to_le16(sizeof(confirm_sleep));
1483 confirm_sleep.action = cpu_to_le16(CMD_SUBCMD_SLEEP_CONFIRMED);
1461 lbs_debugfs_init(); 1484 lbs_debugfs_init();
1462 lbs_deb_leave(LBS_DEB_MAIN); 1485 lbs_deb_leave(LBS_DEB_MAIN);
1463 return 0; 1486 return 0;
@@ -1554,6 +1577,32 @@ out:
1554 return ret; 1577 return ret;
1555} 1578}
1556 1579
1580#ifndef CONFIG_IEEE80211
1581const char *escape_essid(const char *essid, u8 essid_len)
1582{
1583 static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
1584 const char *s = essid;
1585 char *d = escaped;
1586
1587 if (ieee80211_is_empty_essid(essid, essid_len)) {
1588 memcpy(escaped, "<hidden>", sizeof("<hidden>"));
1589 return escaped;
1590 }
1591
1592 essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE);
1593 while (essid_len--) {
1594 if (*s == '\0') {
1595 *d++ = '\\';
1596 *d++ = '0';
1597 s++;
1598 } else {
1599 *d++ = *s++;
1600 }
1601 }
1602 *d = '\0';
1603 return escaped;
1604}
1605#endif
1557 1606
1558module_init(lbs_init_module); 1607module_init(lbs_init_module);
1559module_exit(lbs_exit_module); 1608module_exit(lbs_exit_module);