aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJames Ketrenos <jketreno@linux.intel.com>2005-08-24 22:43:11 -0400
committerJames Ketrenos <jketreno@linux.intel.com>2005-11-07 18:49:53 -0500
commita613bffd3aac89bb0a8c9b7afa72af9b0ae30f0a (patch)
tree982d4f3de285993749138b0e6e2f2d778b120407 /drivers
parentea2b26e0a0264650e13acac8e66d315bb818897c (diff)
Catch ipw2200 up to equivelancy with v1.0.2
Removed unneeded parenthesis around numeric constant defines Added support for iwspy Put in fix for Ad-Hoc mode not passing through all packets (thanks to KKH) Put in fix for fragmentation not working for fragment sizes between 441-464 bytes (thanks to Mohamed Abbas) Fixed #592 problem of CONFIG_IEEE80211_WPA_MODULE not including WPA support into the driver -- fixed as a result of no longer limiting WPAs inclusion Fixed #594 problem with user rates mask causing lack of association if AP mandatory rate is masked out. We now add back in as a supported rate any mandatory rate. Fixed #597 kernel oops due to calling dev_kfree_skb on an skb multiple times. Added code to control LEDs that can be controlled through the wireless NIC (vs. non-wireless HW interfaces) -- this is currently disabled by default due to reports by some users of it hanging their laptop. Added some more debug messages around fragmentation logic Added locking around STATUS_HCMD_ACTIVE to prevent re-entry race conditions Moved ipw_adapter_restart to only execute on the priv->workqueue to keep keyboard errors from occuring during adapter restart Added CFG_BACKGROUND_SCAN to easily allow people to play with background scanning implementations Modified WPA logic to send WPA IE if one is set (vs. being based on wpa_enabled) Modified scan result logic to report WPA and RSN IEs if set (vs. being based on wpa_enabled) Fixed issues with endianess compatability between the host and wireless adapter (thanks to York Liu and Yi Zhu) Fixed problem with Ad-Hoc network creation causing a firmware error if a scan was actively running (thanks to Mohamed Abbas) Signed-off-by: James Ketrenos <jketreno@linux.intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ipw2200.c962
-rw-r--r--drivers/net/wireless/ipw2200.h73
2 files changed, 773 insertions, 262 deletions
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index ddbee3edcd8c..ea7a3dcf1daa 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -32,7 +32,7 @@
32 32
33#include "ipw2200.h" 33#include "ipw2200.h"
34 34
35#define IPW2200_VERSION "1.0.1" 35#define IPW2200_VERSION "1.0.2"
36#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver" 36#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver"
37#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation" 37#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation"
38#define DRV_VERSION IPW2200_VERSION 38#define DRV_VERSION IPW2200_VERSION
@@ -49,6 +49,7 @@ static int mode = 0;
49static u32 ipw_debug_level; 49static u32 ipw_debug_level;
50static int associate = 1; 50static int associate = 1;
51static int auto_create = 1; 51static int auto_create = 1;
52static int led = 0;
52static int disable = 0; 53static int disable = 0;
53static const char ipw_modes[] = { 54static const char ipw_modes[] = {
54 'a', 'b', 'g', '?' 55 'a', 'b', 'g', '?'
@@ -637,6 +638,313 @@ static void ipw_init_ordinals(struct ipw_priv *priv)
637 638
638} 639}
639 640
641u32 ipw_register_toggle(u32 reg)
642{
643 reg &= ~CX2_START_STANDBY;
644 if (reg & CX2_GATE_ODMA)
645 reg &= ~CX2_GATE_ODMA;
646 if (reg & CX2_GATE_IDMA)
647 reg &= ~CX2_GATE_IDMA;
648 if (reg & CX2_GATE_ADMA)
649 reg &= ~CX2_GATE_ADMA;
650 return reg;
651}
652
653/*
654 * LED behavior:
655 * - On radio ON, turn on any LEDs that require to be on during start
656 * - On initialization, start unassociated blink
657 * - On association, disable unassociated blink
658 * - On disassociation, start unassociated blink
659 * - On radio OFF, turn off any LEDs started during radio on
660 *
661 */
662#define LD_TIME_LINK_ON 300
663#define LD_TIME_LINK_OFF 2700
664#define LD_TIME_ACT_ON 250
665
666void ipw_led_link_on(struct ipw_priv *priv)
667{
668 unsigned long flags;
669 u32 led;
670
671 /* If configured to not use LEDs, or nic_type is 1,
672 * then we don't toggle a LINK led */
673 if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)
674 return;
675
676 spin_lock_irqsave(&priv->lock, flags);
677
678 if (!(priv->status & STATUS_RF_KILL_MASK) &&
679 !(priv->status & STATUS_LED_LINK_ON)) {
680 IPW_DEBUG_LED("Link LED On\n");
681 led = ipw_read_reg32(priv, CX2_EVENT_REG);
682 led |= priv->led_association_on;
683
684 led = ipw_register_toggle(led);
685
686 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
687 ipw_write_reg32(priv, CX2_EVENT_REG, led);
688
689 priv->status |= STATUS_LED_LINK_ON;
690
691 /* If we aren't associated, schedule turning the LED off */
692 if (!(priv->status & STATUS_ASSOCIATED))
693 queue_delayed_work(priv->workqueue,
694 &priv->led_link_off,
695 LD_TIME_LINK_ON);
696 }
697
698 spin_unlock_irqrestore(&priv->lock, flags);
699}
700
701void ipw_led_link_off(struct ipw_priv *priv)
702{
703 unsigned long flags;
704 u32 led;
705
706 /* If configured not to use LEDs, or nic type is 1,
707 * then we don't goggle the LINK led. */
708 if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)
709 return;
710
711 spin_lock_irqsave(&priv->lock, flags);
712
713 if (priv->status & STATUS_LED_LINK_ON) {
714 led = ipw_read_reg32(priv, CX2_EVENT_REG);
715 led &= priv->led_association_off;
716 led = ipw_register_toggle(led);
717
718 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
719 ipw_write_reg32(priv, CX2_EVENT_REG, led);
720
721 IPW_DEBUG_LED("Link LED Off\n");
722
723 priv->status &= ~STATUS_LED_LINK_ON;
724
725 /* If we aren't associated and the radio is on, schedule
726 * turning the LED on (blink while unassociated) */
727 if (!(priv->status & STATUS_RF_KILL_MASK) &&
728 !(priv->status & STATUS_ASSOCIATED))
729 queue_delayed_work(priv->workqueue, &priv->led_link_on,
730 LD_TIME_LINK_OFF);
731
732 }
733
734 spin_unlock_irqrestore(&priv->lock, flags);
735}
736
737void ipw_led_activity_on(struct ipw_priv *priv)
738{
739 unsigned long flags;
740 u32 led;
741
742 if (priv->config & CFG_NO_LED)
743 return;
744
745 spin_lock_irqsave(&priv->lock, flags);
746
747 if (priv->status & STATUS_RF_KILL_MASK) {
748 spin_unlock_irqrestore(&priv->lock, flags);
749 return;
750 }
751
752 if (!(priv->status & STATUS_LED_ACT_ON)) {
753 led = ipw_read_reg32(priv, CX2_EVENT_REG);
754 led |= priv->led_activity_on;
755
756 led = ipw_register_toggle(led);
757
758 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
759 ipw_write_reg32(priv, CX2_EVENT_REG, led);
760
761 IPW_DEBUG_LED("Activity LED On\n");
762
763 priv->status |= STATUS_LED_ACT_ON;
764
765 queue_delayed_work(priv->workqueue, &priv->led_act_off,
766 LD_TIME_ACT_ON);
767 } else {
768 /* Reschedule LED off for full time period */
769 cancel_delayed_work(&priv->led_act_off);
770 queue_delayed_work(priv->workqueue, &priv->led_act_off,
771 LD_TIME_ACT_ON);
772 }
773
774 spin_unlock_irqrestore(&priv->lock, flags);
775}
776
777void ipw_led_activity_off(struct ipw_priv *priv)
778{
779 unsigned long flags;
780 u32 led;
781
782 if (priv->config & CFG_NO_LED)
783 return;
784
785 spin_lock_irqsave(&priv->lock, flags);
786
787 if (priv->status & STATUS_LED_ACT_ON) {
788 led = ipw_read_reg32(priv, CX2_EVENT_REG);
789 led &= priv->led_activity_off;
790
791 led = ipw_register_toggle(led);
792
793 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
794 ipw_write_reg32(priv, CX2_EVENT_REG, led);
795
796 IPW_DEBUG_LED("Activity LED Off\n");
797
798 priv->status &= ~STATUS_LED_ACT_ON;
799 }
800
801 spin_unlock_irqrestore(&priv->lock, flags);
802}
803
804void ipw_led_band_on(struct ipw_priv *priv)
805{
806 unsigned long flags;
807 u32 led;
808
809 /* Only nic type 1 supports mode LEDs */
810 if (priv->config & CFG_NO_LED || priv->nic_type != EEPROM_NIC_TYPE_1)
811 return;
812
813 spin_lock_irqsave(&priv->lock, flags);
814
815 led = ipw_read_reg32(priv, CX2_EVENT_REG);
816 if (priv->assoc_network->mode == IEEE_A) {
817 led |= priv->led_ofdm_on;
818 led &= priv->led_association_off;
819 IPW_DEBUG_LED("Mode LED On: 802.11a\n");
820 } else if (priv->assoc_network->mode == IEEE_G) {
821 led |= priv->led_ofdm_on;
822 led |= priv->led_association_on;
823 IPW_DEBUG_LED("Mode LED On: 802.11g\n");
824 } else {
825 led &= priv->led_ofdm_off;
826 led |= priv->led_association_on;
827 IPW_DEBUG_LED("Mode LED On: 802.11b\n");
828 }
829
830 led = ipw_register_toggle(led);
831
832 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
833 ipw_write_reg32(priv, CX2_EVENT_REG, led);
834
835 spin_unlock_irqrestore(&priv->lock, flags);
836}
837
838void ipw_led_band_off(struct ipw_priv *priv)
839{
840 unsigned long flags;
841 u32 led;
842
843 /* Only nic type 1 supports mode LEDs */
844 if (priv->config & CFG_NO_LED || priv->nic_type != EEPROM_NIC_TYPE_1)
845 return;
846
847 spin_lock_irqsave(&priv->lock, flags);
848
849 led = ipw_read_reg32(priv, CX2_EVENT_REG);
850 led &= priv->led_ofdm_off;
851 led &= priv->led_association_off;
852
853 led = ipw_register_toggle(led);
854
855 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
856 ipw_write_reg32(priv, CX2_EVENT_REG, led);
857
858 spin_unlock_irqrestore(&priv->lock, flags);
859}
860
861void ipw_led_radio_on(struct ipw_priv *priv)
862{
863 ipw_led_link_on(priv);
864}
865
866void ipw_led_radio_off(struct ipw_priv *priv)
867{
868 ipw_led_activity_off(priv);
869 ipw_led_link_off(priv);
870}
871
872void ipw_led_link_up(struct ipw_priv *priv)
873{
874 /* Set the Link Led on for all nic types */
875 ipw_led_link_on(priv);
876}
877
878void ipw_led_link_down(struct ipw_priv *priv)
879{
880 ipw_led_activity_off(priv);
881 ipw_led_link_off(priv);
882
883 if (priv->status & STATUS_RF_KILL_MASK)
884 ipw_led_radio_off(priv);
885}
886
887void ipw_led_init(struct ipw_priv *priv)
888{
889 priv->nic_type = priv->eeprom[EEPROM_NIC_TYPE];
890
891 /* Set the default PINs for the link and activity leds */
892 priv->led_activity_on = CX2_ACTIVITY_LED;
893 priv->led_activity_off = ~(CX2_ACTIVITY_LED);
894
895 priv->led_association_on = CX2_ASSOCIATED_LED;
896 priv->led_association_off = ~(CX2_ASSOCIATED_LED);
897
898 /* Set the default PINs for the OFDM leds */
899 priv->led_ofdm_on = CX2_OFDM_LED;
900 priv->led_ofdm_off = ~(CX2_OFDM_LED);
901
902 switch (priv->nic_type) {
903 case EEPROM_NIC_TYPE_1:
904 /* In this NIC type, the LEDs are reversed.... */
905 priv->led_activity_on = CX2_ASSOCIATED_LED;
906 priv->led_activity_off = ~(CX2_ASSOCIATED_LED);
907 priv->led_association_on = CX2_ACTIVITY_LED;
908 priv->led_association_off = ~(CX2_ACTIVITY_LED);
909
910 if (!(priv->config & CFG_NO_LED))
911 ipw_led_band_on(priv);
912
913 /* And we don't blink link LEDs for this nic, so
914 * just return here */
915 return;
916
917 case EEPROM_NIC_TYPE_3:
918 case EEPROM_NIC_TYPE_2:
919 case EEPROM_NIC_TYPE_4:
920 case EEPROM_NIC_TYPE_0:
921 break;
922
923 default:
924 IPW_DEBUG_INFO("Unknown NIC type from EEPROM: %d\n",
925 priv->nic_type);
926 priv->nic_type = EEPROM_NIC_TYPE_0;
927 break;
928 }
929
930 if (!(priv->config & CFG_NO_LED)) {
931 if (priv->status & STATUS_ASSOCIATED)
932 ipw_led_link_on(priv);
933 else
934 ipw_led_link_off(priv);
935 }
936}
937
938void ipw_led_shutdown(struct ipw_priv *priv)
939{
940 cancel_delayed_work(&priv->led_link_on);
941 cancel_delayed_work(&priv->led_link_off);
942 cancel_delayed_work(&priv->led_act_off);
943 ipw_led_activity_off(priv);
944 ipw_led_link_off(priv);
945 ipw_led_band_off(priv);
946}
947
640/* 948/*
641 * The following adds a new attribute to the sysfs representation 949 * The following adds a new attribute to the sysfs representation
642 * of this device driver (i.e. a new file in /sys/bus/pci/drivers/ipw/) 950 * of this device driver (i.e. a new file in /sys/bus/pci/drivers/ipw/)
@@ -648,8 +956,9 @@ static ssize_t show_debug_level(struct device_driver *d, char *buf)
648{ 956{
649 return sprintf(buf, "0x%08X\n", ipw_debug_level); 957 return sprintf(buf, "0x%08X\n", ipw_debug_level);
650} 958}
651static ssize_t store_debug_level(struct device_driver *d, 959
652 const char *buf, size_t count) 960static ssize_t store_debug_level(struct device_driver *d, const char *buf,
961 size_t count)
653{ 962{
654 char *p = (char *)buf; 963 char *p = (char *)buf;
655 u32 val; 964 u32 val;
@@ -673,6 +982,82 @@ static ssize_t store_debug_level(struct device_driver *d,
673static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, 982static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
674 show_debug_level, store_debug_level); 983 show_debug_level, store_debug_level);
675 984
985static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
986 char *buf)
987{
988 struct ipw_priv *priv = dev_get_drvdata(d);
989 return sprintf(buf, "%d\n", priv->ieee->scan_age);
990}
991
992static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
993 const char *buf, size_t count)
994{
995 struct ipw_priv *priv = dev_get_drvdata(d);
996 struct net_device *dev = priv->net_dev;
997 char buffer[] = "00000000";
998 unsigned long len =
999 (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1;
1000 unsigned long val;
1001 char *p = buffer;
1002
1003 IPW_DEBUG_INFO("enter\n");
1004
1005 strncpy(buffer, buf, len);
1006 buffer[len] = 0;
1007
1008 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
1009 p++;
1010 if (p[0] == 'x' || p[0] == 'X')
1011 p++;
1012 val = simple_strtoul(p, &p, 16);
1013 } else
1014 val = simple_strtoul(p, &p, 10);
1015 if (p == buffer) {
1016 IPW_DEBUG_INFO("%s: user supplied invalid value.\n", dev->name);
1017 } else {
1018 priv->ieee->scan_age = val;
1019 IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age);
1020 }
1021
1022 IPW_DEBUG_INFO("exit\n");
1023 return len;
1024}
1025
1026static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
1027
1028static ssize_t show_led(struct device *d, struct device_attribute *attr,
1029 char *buf)
1030{
1031 struct ipw_priv *priv = dev_get_drvdata(d);
1032 return sprintf(buf, "%d\n", (priv->config & CFG_NO_LED) ? 0 : 1);
1033}
1034
1035static ssize_t store_led(struct device *d, struct device_attribute *attr,
1036 const char *buf, size_t count)
1037{
1038 struct ipw_priv *priv = dev_get_drvdata(d);
1039
1040 IPW_DEBUG_INFO("enter\n");
1041
1042 if (count == 0)
1043 return 0;
1044
1045 if (*buf == 0) {
1046 IPW_DEBUG_LED("Disabling LED control.\n");
1047 priv->config |= CFG_NO_LED;
1048 ipw_led_shutdown(priv);
1049 } else {
1050 IPW_DEBUG_LED("Enabling LED control.\n");
1051 priv->config &= ~CFG_NO_LED;
1052 ipw_led_init(priv);
1053 }
1054
1055 IPW_DEBUG_INFO("exit\n");
1056 return count;
1057}
1058
1059static DEVICE_ATTR(led, S_IWUSR | S_IRUGO, show_led, store_led);
1060
676static ssize_t show_status(struct device *d, 1061static ssize_t show_status(struct device *d,
677 struct device_attribute *attr, char *buf) 1062 struct device_attribute *attr, char *buf)
678{ 1063{
@@ -694,23 +1079,8 @@ static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
694static ssize_t show_nic_type(struct device *d, 1079static ssize_t show_nic_type(struct device *d,
695 struct device_attribute *attr, char *buf) 1080 struct device_attribute *attr, char *buf)
696{ 1081{
697 struct ipw_priv *p = d->driver_data; 1082 struct ipw_priv *priv = d->driver_data;
698 u8 type = p->eeprom[EEPROM_NIC_TYPE]; 1083 return sprintf(buf, "TYPE: %d\n", priv->nic_type);
699
700 switch (type) {
701 case EEPROM_NIC_TYPE_STANDARD:
702 return sprintf(buf, "STANDARD\n");
703 case EEPROM_NIC_TYPE_DELL:
704 return sprintf(buf, "DELL\n");
705 case EEPROM_NIC_TYPE_FUJITSU:
706 return sprintf(buf, "FUJITSU\n");
707 case EEPROM_NIC_TYPE_IBM:
708 return sprintf(buf, "IBM\n");
709 case EEPROM_NIC_TYPE_HP:
710 return sprintf(buf, "HP\n");
711 }
712
713 return sprintf(buf, "UNKNOWN\n");
714} 1084}
715 1085
716static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL); 1086static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL);
@@ -955,9 +1325,8 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
955 if (disable_radio) { 1325 if (disable_radio) {
956 priv->status |= STATUS_RF_KILL_SW; 1326 priv->status |= STATUS_RF_KILL_SW;
957 1327
958 if (priv->workqueue) { 1328 if (priv->workqueue)
959 cancel_delayed_work(&priv->request_scan); 1329 cancel_delayed_work(&priv->request_scan);
960 }
961 wake_up_interruptible(&priv->wait_command_queue); 1330 wake_up_interruptible(&priv->wait_command_queue);
962 queue_work(priv->workqueue, &priv->down); 1331 queue_work(priv->workqueue, &priv->down);
963 } else { 1332 } else {
@@ -1081,11 +1450,9 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
1081 IPW_DEBUG_RF_KILL("RF_KILL_DONE\n"); 1450 IPW_DEBUG_RF_KILL("RF_KILL_DONE\n");
1082 priv->status |= STATUS_RF_KILL_HW; 1451 priv->status |= STATUS_RF_KILL_HW;
1083 wake_up_interruptible(&priv->wait_command_queue); 1452 wake_up_interruptible(&priv->wait_command_queue);
1084 netif_carrier_off(priv->net_dev);
1085 netif_stop_queue(priv->net_dev);
1086 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING); 1453 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
1087 notify_wx_assoc_event(priv);
1088 cancel_delayed_work(&priv->request_scan); 1454 cancel_delayed_work(&priv->request_scan);
1455 schedule_work(&priv->link_down);
1089 queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ); 1456 queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
1090 handled |= CX2_INTA_BIT_RF_KILL_DONE; 1457 handled |= CX2_INTA_BIT_RF_KILL_DONE;
1091 } 1458 }
@@ -1182,9 +1549,12 @@ static char *get_cmd_string(u8 cmd)
1182static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) 1549static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
1183{ 1550{
1184 int rc = 0; 1551 int rc = 0;
1552 unsigned long flags;
1185 1553
1554 spin_lock_irqsave(&priv->lock, flags);
1186 if (priv->status & STATUS_HCMD_ACTIVE) { 1555 if (priv->status & STATUS_HCMD_ACTIVE) {
1187 IPW_ERROR("Already sending a command\n"); 1556 IPW_ERROR("Already sending a command\n");
1557 spin_unlock_irqrestore(&priv->lock, flags);
1188 return -1; 1558 return -1;
1189 } 1559 }
1190 1560
@@ -1195,19 +1565,30 @@ static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
1195 printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len); 1565 printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len);
1196 1566
1197 rc = ipw_queue_tx_hcmd(priv, cmd->cmd, &cmd->param, cmd->len, 0); 1567 rc = ipw_queue_tx_hcmd(priv, cmd->cmd, &cmd->param, cmd->len, 0);
1198 if (rc) 1568 if (rc) {
1569 priv->status &= ~STATUS_HCMD_ACTIVE;
1570 spin_unlock_irqrestore(&priv->lock, flags);
1199 return rc; 1571 return rc;
1572 }
1573 spin_unlock_irqrestore(&priv->lock, flags);
1200 1574
1201 rc = wait_event_interruptible_timeout(priv->wait_command_queue, 1575 rc = wait_event_interruptible_timeout(priv->wait_command_queue,
1202 !(priv-> 1576 !(priv->
1203 status & STATUS_HCMD_ACTIVE), 1577 status & STATUS_HCMD_ACTIVE),
1204 HOST_COMPLETE_TIMEOUT); 1578 HOST_COMPLETE_TIMEOUT);
1205 if (rc == 0) { 1579 if (rc == 0) {
1206 IPW_DEBUG_INFO("Command completion failed out after %dms.\n", 1580 spin_lock_irqsave(&priv->lock, flags);
1207 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); 1581 if (priv->status & STATUS_HCMD_ACTIVE) {
1208 priv->status &= ~STATUS_HCMD_ACTIVE; 1582 IPW_DEBUG_INFO("Command completion failed out after "
1209 return -EIO; 1583 "%dms.\n",
1584 1000 * (HOST_COMPLETE_TIMEOUT / HZ));
1585 priv->status &= ~STATUS_HCMD_ACTIVE;
1586 spin_unlock_irqrestore(&priv->lock, flags);
1587 return -EIO;
1588 }
1589 spin_unlock_irqrestore(&priv->lock, flags);
1210 } 1590 }
1591
1211 if (priv->status & STATUS_RF_KILL_MASK) { 1592 if (priv->status & STATUS_RF_KILL_MASK) {
1212 IPW_DEBUG_INFO("Command aborted due to RF Kill Switch\n"); 1593 IPW_DEBUG_INFO("Command aborted due to RF Kill Switch\n");
1213 return -EIO; 1594 return -EIO;
@@ -1304,6 +1685,11 @@ static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
1304 return 0; 1685 return 0;
1305} 1686}
1306 1687
1688/*
1689 * NOTE: This must be executed from our workqueue as it results in udelay
1690 * being called which may corrupt the keyboard if executed on default
1691 * workqueue
1692 */
1307static void ipw_adapter_restart(void *adapter) 1693static void ipw_adapter_restart(void *adapter)
1308{ 1694{
1309 struct ipw_priv *priv = adapter; 1695 struct ipw_priv *priv = adapter;
@@ -1327,7 +1713,7 @@ static void ipw_scan_check(void *data)
1327 IPW_DEBUG_SCAN("Scan completion watchdog resetting " 1713 IPW_DEBUG_SCAN("Scan completion watchdog resetting "
1328 "adapter (%dms).\n", 1714 "adapter (%dms).\n",
1329 IPW_SCAN_CHECK_WATCHDOG / 100); 1715 IPW_SCAN_CHECK_WATCHDOG / 100);
1330 ipw_adapter_restart(priv); 1716 queue_work(priv->workqueue, &priv->adapter_restart);
1331 } 1717 }
1332} 1718}
1333 1719
@@ -1400,12 +1786,25 @@ static int ipw_send_associate(struct ipw_priv *priv,
1400 .len = sizeof(*associate) 1786 .len = sizeof(*associate)
1401 }; 1787 };
1402 1788
1789 struct ipw_associate tmp_associate;
1790 memcpy(&tmp_associate, associate, sizeof(*associate));
1791 tmp_associate.policy_support =
1792 cpu_to_le16(tmp_associate.policy_support);
1793 tmp_associate.assoc_tsf_msw = cpu_to_le32(tmp_associate.assoc_tsf_msw);
1794 tmp_associate.assoc_tsf_lsw = cpu_to_le32(tmp_associate.assoc_tsf_lsw);
1795 tmp_associate.capability = cpu_to_le16(tmp_associate.capability);
1796 tmp_associate.listen_interval =
1797 cpu_to_le16(tmp_associate.listen_interval);
1798 tmp_associate.beacon_interval =
1799 cpu_to_le16(tmp_associate.beacon_interval);
1800 tmp_associate.atim_window = cpu_to_le16(tmp_associate.atim_window);
1801
1403 if (!priv || !associate) { 1802 if (!priv || !associate) {
1404 IPW_ERROR("Invalid args\n"); 1803 IPW_ERROR("Invalid args\n");
1405 return -1; 1804 return -1;
1406 } 1805 }
1407 1806
1408 memcpy(&cmd.param, associate, sizeof(*associate)); 1807 memcpy(&cmd.param, &tmp_associate, sizeof(*associate));
1409 if (ipw_send_cmd(priv, &cmd)) { 1808 if (ipw_send_cmd(priv, &cmd)) {
1410 IPW_ERROR("failed to send ASSOCIATE command\n"); 1809 IPW_ERROR("failed to send ASSOCIATE command\n");
1411 return -1; 1810 return -1;
@@ -1706,7 +2105,7 @@ static void ipw_eeprom_init_sram(struct ipw_priv *priv)
1706 2105
1707 /* read entire contents of eeprom into private buffer */ 2106 /* read entire contents of eeprom into private buffer */
1708 for (i = 0; i < 128; i++) 2107 for (i = 0; i < 128; i++)
1709 eeprom[i] = eeprom_read_u16(priv, (u8) i); 2108 eeprom[i] = le16_to_cpu(eeprom_read_u16(priv, (u8) i));
1710 2109
1711 /* 2110 /*
1712 If the data looks correct, then copy it to our private 2111 If the data looks correct, then copy it to our private
@@ -2001,6 +2400,9 @@ static void ipw_remove_current_network(struct ipw_priv *priv)
2001{ 2400{
2002 struct list_head *element, *safe; 2401 struct list_head *element, *safe;
2003 struct ieee80211_network *network = NULL; 2402 struct ieee80211_network *network = NULL;
2403 unsigned long flags;
2404
2405 spin_lock_irqsave(&priv->ieee->lock, flags);
2004 list_for_each_safe(element, safe, &priv->ieee->network_list) { 2406 list_for_each_safe(element, safe, &priv->ieee->network_list) {
2005 network = list_entry(element, struct ieee80211_network, list); 2407 network = list_entry(element, struct ieee80211_network, list);
2006 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) { 2408 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
@@ -2009,6 +2411,7 @@ static void ipw_remove_current_network(struct ipw_priv *priv)
2009 &priv->ieee->network_free_list); 2411 &priv->ieee->network_free_list);
2010 } 2412 }
2011 } 2413 }
2414 spin_unlock_irqrestore(&priv->ieee->lock, flags);
2012} 2415}
2013 2416
2014/** 2417/**
@@ -2158,7 +2561,8 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
2158 */ 2561 */
2159 /* load new ipw uCode */ 2562 /* load new ipw uCode */
2160 for (i = 0; i < len / 2; i++) 2563 for (i = 0; i < len / 2; i++)
2161 ipw_write_reg16(priv, CX2_BASEBAND_CONTROL_STORE, image[i]); 2564 ipw_write_reg16(priv, CX2_BASEBAND_CONTROL_STORE,
2565 cpu_to_le16(image[i]));
2162 2566
2163 /* enable DINO */ 2567 /* enable DINO */
2164 ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, 0); 2568 ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, 0);
@@ -2181,7 +2585,8 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
2181 2585
2182 for (i = 0; i < ARRAY_SIZE(response_buffer); i++) 2586 for (i = 0; i < ARRAY_SIZE(response_buffer); i++)
2183 response_buffer[i] = 2587 response_buffer[i] =
2184 ipw_read_reg32(priv, CX2_BASEBAND_RX_FIFO_READ); 2588 le32_to_cpu(ipw_read_reg32(priv,
2589 CX2_BASEBAND_RX_FIFO_READ));
2185 memcpy(&priv->dino_alive, response_buffer, 2590 memcpy(&priv->dino_alive, response_buffer,
2186 sizeof(priv->dino_alive)); 2591 sizeof(priv->dino_alive));
2187 if (priv->dino_alive.alive_command == 1 2592 if (priv->dino_alive.alive_command == 1
@@ -2250,13 +2655,14 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
2250 * offeset*/ 2655 * offeset*/
2251 /* Dma loading */ 2656 /* Dma loading */
2252 rc = ipw_fw_dma_add_buffer(priv, shared_phys + offset, 2657 rc = ipw_fw_dma_add_buffer(priv, shared_phys + offset,
2253 chunk->address, chunk->length); 2658 le32_to_cpu(chunk->address),
2659 le32_to_cpu(chunk->length));
2254 if (rc) { 2660 if (rc) {
2255 IPW_DEBUG_INFO("dmaAddBuffer Failed\n"); 2661 IPW_DEBUG_INFO("dmaAddBuffer Failed\n");
2256 goto out; 2662 goto out;
2257 } 2663 }
2258 2664
2259 offset += chunk->length; 2665 offset += le32_to_cpu(chunk->length);
2260 } while (offset < len); 2666 } while (offset < len);
2261 2667
2262 /* Run the DMA and wait for the answer */ 2668 /* Run the DMA and wait for the answer */
@@ -2351,14 +2757,17 @@ static int ipw_init_nic(struct ipw_priv *priv)
2351static int ipw_reset_nic(struct ipw_priv *priv) 2757static int ipw_reset_nic(struct ipw_priv *priv)
2352{ 2758{
2353 int rc = 0; 2759 int rc = 0;
2760 unsigned long flags;
2354 2761
2355 IPW_DEBUG_TRACE(">>\n"); 2762 IPW_DEBUG_TRACE(">>\n");
2356 2763
2357 rc = ipw_init_nic(priv); 2764 rc = ipw_init_nic(priv);
2358 2765
2766 spin_lock_irqsave(&priv->lock, flags);
2359 /* Clear the 'host command active' bit... */ 2767 /* Clear the 'host command active' bit... */
2360 priv->status &= ~STATUS_HCMD_ACTIVE; 2768 priv->status &= ~STATUS_HCMD_ACTIVE;
2361 wake_up_interruptible(&priv->wait_command_queue); 2769 wake_up_interruptible(&priv->wait_command_queue);
2770 spin_unlock_irqrestore(&priv->lock, flags);
2362 2771
2363 IPW_DEBUG_TRACE("<<\n"); 2772 IPW_DEBUG_TRACE("<<\n");
2364 return rc; 2773 return rc;
@@ -2378,17 +2787,18 @@ static int ipw_get_fw(struct ipw_priv *priv,
2378 } 2787 }
2379 2788
2380 header = (struct fw_header *)(*fw)->data; 2789 header = (struct fw_header *)(*fw)->data;
2381 if (IPW_FW_MAJOR(header->version) != IPW_FW_MAJOR_VERSION) { 2790 if (IPW_FW_MAJOR(le32_to_cpu(header->version)) != IPW_FW_MAJOR_VERSION) {
2382 IPW_ERROR("'%s' firmware version not compatible (%d != %d)\n", 2791 IPW_ERROR("'%s' firmware version not compatible (%d != %d)\n",
2383 name, 2792 name,
2384 IPW_FW_MAJOR(header->version), IPW_FW_MAJOR_VERSION); 2793 IPW_FW_MAJOR(le32_to_cpu(header->version)),
2794 IPW_FW_MAJOR_VERSION);
2385 return -EINVAL; 2795 return -EINVAL;
2386 } 2796 }
2387 2797
2388 IPW_DEBUG_INFO("Loading firmware '%s' file v%d.%d (%zd bytes)\n", 2798 IPW_DEBUG_INFO("Loading firmware '%s' file v%d.%d (%zd bytes)\n",
2389 name, 2799 name,
2390 IPW_FW_MAJOR(header->version), 2800 IPW_FW_MAJOR(le32_to_cpu(header->version)),
2391 IPW_FW_MINOR(header->version), 2801 IPW_FW_MINOR(le32_to_cpu(header->version)),
2392 (*fw)->size - sizeof(struct fw_header)); 2802 (*fw)->size - sizeof(struct fw_header));
2393 return 0; 2803 return 0;
2394} 2804}
@@ -2414,6 +2824,7 @@ static inline void ipw_rx_queue_reset(struct ipw_priv *priv,
2414 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr, 2824 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
2415 CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); 2825 CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
2416 dev_kfree_skb(rxq->pool[i].skb); 2826 dev_kfree_skb(rxq->pool[i].skb);
2827 rxq->pool[i].skb = NULL;
2417 } 2828 }
2418 list_add_tail(&rxq->pool[i].list, &rxq->rx_used); 2829 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
2419 } 2830 }
@@ -2769,16 +3180,18 @@ static void ipw_queue_tx_free_tfd(struct ipw_priv *priv,
2769 return; 3180 return;
2770 3181
2771 /* sanity check */ 3182 /* sanity check */
2772 if (bd->u.data.num_chunks > NUM_TFD_CHUNKS) { 3183 if (le32_to_cpu(bd->u.data.num_chunks) > NUM_TFD_CHUNKS) {
2773 IPW_ERROR("Too many chunks: %i\n", bd->u.data.num_chunks); 3184 IPW_ERROR("Too many chunks: %i\n",
3185 le32_to_cpu(bd->u.data.num_chunks));
2774 /** @todo issue fatal error, it is quite serious situation */ 3186 /** @todo issue fatal error, it is quite serious situation */
2775 return; 3187 return;
2776 } 3188 }
2777 3189
2778 /* unmap chunks if any */ 3190 /* unmap chunks if any */
2779 for (i = 0; i < bd->u.data.num_chunks; i++) { 3191 for (i = 0; i < le32_to_cpu(bd->u.data.num_chunks); i++) {
2780 pci_unmap_single(dev, bd->u.data.chunk_ptr[i], 3192 pci_unmap_single(dev, le32_to_cpu(bd->u.data.chunk_ptr[i]),
2781 bd->u.data.chunk_len[i], PCI_DMA_TODEVICE); 3193 le16_to_cpu(bd->u.data.chunk_len[i]),
3194 PCI_DMA_TODEVICE);
2782 if (txq->txb[txq->q.last_used]) { 3195 if (txq->txb[txq->q.last_used]) {
2783 ieee80211_txb_free(txq->txb[txq->q.last_used]); 3196 ieee80211_txb_free(txq->txb[txq->q.last_used]);
2784 txq->txb[txq->q.last_used] = NULL; 3197 txq->txb[txq->q.last_used] = NULL;
@@ -2841,9 +3254,8 @@ static void inline __maybe_wake_tx(struct ipw_priv *priv)
2841 switch (priv->port_type) { 3254 switch (priv->port_type) {
2842 case DCR_TYPE_MU_BSS: 3255 case DCR_TYPE_MU_BSS:
2843 case DCR_TYPE_MU_IBSS: 3256 case DCR_TYPE_MU_IBSS:
2844 if (!(priv->status & STATUS_ASSOCIATED)) { 3257 if (!(priv->status & STATUS_ASSOCIATED))
2845 return; 3258 return;
2846 }
2847 } 3259 }
2848 netif_wake_queue(priv->net_dev); 3260 netif_wake_queue(priv->net_dev);
2849 } 3261 }
@@ -3307,8 +3719,13 @@ static inline void ipw_handle_missed_beacon(struct ipw_priv *priv,
3307 IPW_DL_STATE, 3719 IPW_DL_STATE,
3308 "Missed beacon: %d - disassociate\n", missed_count); 3720 "Missed beacon: %d - disassociate\n", missed_count);
3309 priv->status &= ~STATUS_ROAMING; 3721 priv->status &= ~STATUS_ROAMING;
3310 if (priv->status & STATUS_SCANNING) 3722 if (priv->status & STATUS_SCANNING) {
3723 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
3724 IPW_DL_STATE,
3725 "Aborting scan with missed beacon.\n");
3311 queue_work(priv->workqueue, &priv->abort_scan); 3726 queue_work(priv->workqueue, &priv->abort_scan);
3727 }
3728
3312 queue_work(priv->workqueue, &priv->disassociate); 3729 queue_work(priv->workqueue, &priv->disassociate);
3313 return; 3730 return;
3314 } 3731 }
@@ -3342,6 +3759,8 @@ static inline void ipw_handle_missed_beacon(struct ipw_priv *priv,
3342 * stuck (only if we aren't roaming -- 3759 * stuck (only if we aren't roaming --
3343 * otherwise we'll never scan more than 2 or 3 3760 * otherwise we'll never scan more than 2 or 3
3344 * channels..) */ 3761 * channels..) */
3762 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
3763 IPW_DL_STATE, "Aborting scan with missed beacon.\n");
3345 queue_work(priv->workqueue, &priv->abort_scan); 3764 queue_work(priv->workqueue, &priv->abort_scan);
3346 } 3765 }
3347 3766
@@ -3356,6 +3775,8 @@ static inline void ipw_handle_missed_beacon(struct ipw_priv *priv,
3356static inline void ipw_rx_notification(struct ipw_priv *priv, 3775static inline void ipw_rx_notification(struct ipw_priv *priv,
3357 struct ipw_rx_notification *notif) 3776 struct ipw_rx_notification *notif)
3358{ 3777{
3778 notif->size = le16_to_cpu(notif->size);
3779
3359 IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, notif->size); 3780 IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, notif->size);
3360 3781
3361 switch (notif->subtype) { 3782 switch (notif->subtype) {
@@ -3400,29 +3821,8 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3400 priv->status &= ~STATUS_ASSOCIATING; 3821 priv->status &= ~STATUS_ASSOCIATING;
3401 priv->status |= STATUS_ASSOCIATED; 3822 priv->status |= STATUS_ASSOCIATED;
3402 3823
3403 netif_carrier_on(priv->net_dev); 3824 schedule_work(&priv->link_up);
3404 if (netif_queue_stopped(priv->net_dev)) {
3405 IPW_DEBUG_NOTIF
3406 ("waking queue\n");
3407 netif_wake_queue(priv->net_dev);
3408 } else {
3409 IPW_DEBUG_NOTIF
3410 ("starting queue\n");
3411 netif_start_queue(priv->
3412 net_dev);
3413 }
3414 3825
3415 ipw_reset_stats(priv);
3416 /* Ensure the rate is updated immediately */
3417 priv->last_rate =
3418 ipw_get_current_rate(priv);
3419 schedule_work(&priv->gather_stats);
3420 notify_wx_assoc_event(priv);
3421
3422/* queue_delayed_work(priv->workqueue,
3423 &priv->request_scan,
3424 SCAN_ASSOCIATED_INTERVAL);
3425*/
3426 break; 3826 break;
3427 } 3827 }
3428 3828
@@ -3455,12 +3855,7 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3455 STATUS_AUTH | 3855 STATUS_AUTH |
3456 STATUS_ASSOCIATED); 3856 STATUS_ASSOCIATED);
3457 3857
3458 netif_carrier_off(priv-> 3858 schedule_work(&priv->link_down);
3459 net_dev);
3460 netif_stop_queue(priv->net_dev);
3461 queue_work(priv->workqueue,
3462 &priv->request_scan);
3463 notify_wx_assoc_event(priv);
3464 break; 3859 break;
3465 } 3860 }
3466 3861
@@ -3506,31 +3901,8 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3506 STATUS_ASSOCIATING | 3901 STATUS_ASSOCIATING |
3507 STATUS_ASSOCIATED | STATUS_AUTH); 3902 STATUS_ASSOCIATED | STATUS_AUTH);
3508 3903
3509 netif_stop_queue(priv->net_dev); 3904 schedule_work(&priv->link_down);
3510 if (!(priv->status & STATUS_ROAMING)) {
3511 netif_carrier_off(priv->
3512 net_dev);
3513 notify_wx_assoc_event(priv);
3514
3515 /* Cancel any queued work ... */
3516 cancel_delayed_work(&priv->
3517 request_scan);
3518 cancel_delayed_work(&priv->
3519 adhoc_check);
3520
3521 /* Queue up another scan... */
3522 queue_work(priv->workqueue,
3523 &priv->request_scan);
3524
3525 cancel_delayed_work(&priv->
3526 gather_stats);
3527 } else {
3528 priv->status |= STATUS_ROAMING;
3529 queue_work(priv->workqueue,
3530 &priv->request_scan);
3531 }
3532 3905
3533 ipw_reset_stats(priv);
3534 break; 3906 break;
3535 } 3907 }
3536 3908
@@ -3576,11 +3948,7 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3576 STATUS_AUTH | 3948 STATUS_AUTH |
3577 STATUS_ASSOCIATED); 3949 STATUS_ASSOCIATED);
3578 3950
3579 netif_carrier_off(priv->net_dev); 3951 schedule_work(&priv->link_down);
3580 netif_stop_queue(priv->net_dev);
3581 queue_work(priv->workqueue,
3582 &priv->request_scan);
3583 notify_wx_assoc_event(priv);
3584 break; 3952 break;
3585 3953
3586 case CMAS_TX_AUTH_SEQ_1: 3954 case CMAS_TX_AUTH_SEQ_1:
@@ -3682,6 +4050,10 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3682 } else if (priv->status & STATUS_SCAN_PENDING) 4050 } else if (priv->status & STATUS_SCAN_PENDING)
3683 queue_work(priv->workqueue, 4051 queue_work(priv->workqueue,
3684 &priv->request_scan); 4052 &priv->request_scan);
4053 else if (priv->config & CFG_BACKGROUND_SCAN
4054 && priv->status & STATUS_ASSOCIATED)
4055 queue_delayed_work(priv->workqueue,
4056 &priv->request_scan, HZ);
3685 4057
3686 priv->ieee->scans++; 4058 priv->ieee->scans++;
3687 break; 4059 break;
@@ -3690,13 +4062,13 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3690 case HOST_NOTIFICATION_STATUS_FRAG_LENGTH:{ 4062 case HOST_NOTIFICATION_STATUS_FRAG_LENGTH:{
3691 struct notif_frag_length *x = &notif->u.frag_len; 4063 struct notif_frag_length *x = &notif->u.frag_len;
3692 4064
3693 if (notif->size == sizeof(*x)) { 4065 if (notif->size == sizeof(*x))
3694 IPW_ERROR("Frag length: %d\n", x->frag_length); 4066 IPW_ERROR("Frag length: %d\n",
3695 } else { 4067 le16_to_cpu(x->frag_length));
4068 else
3696 IPW_ERROR("Frag length of wrong size %d " 4069 IPW_ERROR("Frag length of wrong size %d "
3697 "(should be %zd)\n", 4070 "(should be %zd)\n",
3698 notif->size, sizeof(*x)); 4071 notif->size, sizeof(*x));
3699 }
3700 break; 4072 break;
3701 } 4073 }
3702 4074
@@ -3722,11 +4094,9 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3722 case HOST_NOTIFICATION_DINO_CONFIG_RESPONSE:{ 4094 case HOST_NOTIFICATION_DINO_CONFIG_RESPONSE:{
3723 IPW_ERROR("Dino config\n"); 4095 IPW_ERROR("Dino config\n");
3724 if (priv->hcmd 4096 if (priv->hcmd
3725 && priv->hcmd->cmd == HOST_CMD_DINO_CONFIG) { 4097 && priv->hcmd->cmd != HOST_CMD_DINO_CONFIG)
3726 /* TODO: Do anything special? */
3727 } else {
3728 IPW_ERROR("Unexpected DINO_CONFIG_RESPONSE\n"); 4098 IPW_ERROR("Unexpected DINO_CONFIG_RESPONSE\n");
3729 } 4099
3730 break; 4100 break;
3731 } 4101 }
3732 4102
@@ -3739,8 +4109,11 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3739 break; 4109 break;
3740 } 4110 }
3741 4111
3742 if (x->state == HOST_NOTIFICATION_STATUS_BEACON_MISSING) 4112 if (le32_to_cpu(x->state) ==
3743 ipw_handle_missed_beacon(priv, x->number); 4113 HOST_NOTIFICATION_STATUS_BEACON_MISSING)
4114 ipw_handle_missed_beacon(priv,
4115 le32_to_cpu(x->
4116 number));
3744 4117
3745 break; 4118 break;
3746 } 4119 }
@@ -3779,7 +4152,8 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3779 case HOST_NOTIFICATION_NOISE_STATS:{ 4152 case HOST_NOTIFICATION_NOISE_STATS:{
3780 if (notif->size == sizeof(u32)) { 4153 if (notif->size == sizeof(u32)) {
3781 priv->last_noise = 4154 priv->last_noise =
3782 (u8) (notif->u.noise.value & 0xff); 4155 (u8) (le32_to_cpu(notif->u.noise.value) &
4156 0xff);
3783 average_add(&priv->average_noise, 4157 average_add(&priv->average_noise,
3784 priv->last_noise); 4158 priv->last_noise);
3785 break; 4159 break;
@@ -3896,9 +4270,8 @@ static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
3896 priv->tx_packets++; 4270 priv->tx_packets++;
3897 } 4271 }
3898 done: 4272 done:
3899 if (ipw_queue_space(q) > q->low_mark && qindex >= 0) { 4273 if (ipw_queue_space(q) > q->low_mark && qindex >= 0)
3900 __maybe_wake_tx(priv); 4274 __maybe_wake_tx(priv);
3901 }
3902 used = q->first_empty - q->last_used; 4275 used = q->first_empty - q->last_used;
3903 if (used < 0) 4276 if (used < 0)
3904 used += q->n_bd; 4277 used += q->n_bd;
@@ -4217,13 +4590,16 @@ static int ipw_compatible_rates(struct ipw_priv *priv,
4217 num_rates = min(network->rates_len, (u8) IPW_MAX_RATES); 4590 num_rates = min(network->rates_len, (u8) IPW_MAX_RATES);
4218 rates->num_rates = 0; 4591 rates->num_rates = 0;
4219 for (i = 0; i < num_rates; i++) { 4592 for (i = 0; i < num_rates; i++) {
4220 if (!ipw_is_rate_in_mask 4593 if (!ipw_is_rate_in_mask(priv, network->mode,
4221 (priv, network->mode, network->rates[i])) { 4594 network->rates[i])) {
4595
4222 if (network->rates[i] & IEEE80211_BASIC_RATE_MASK) { 4596 if (network->rates[i] & IEEE80211_BASIC_RATE_MASK) {
4223 IPW_DEBUG_SCAN 4597 IPW_DEBUG_SCAN("Adding masked mandatory "
4224 ("Basic rate %02X masked: 0x%08X\n", 4598 "rate %02X\n",
4225 network->rates[i], priv->rates_mask); 4599 network->rates[i]);
4226 return 0; 4600 rates->supported_rates[rates->num_rates++] =
4601 network->rates[i];
4602 continue;
4227 } 4603 }
4228 4604
4229 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n", 4605 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
@@ -4234,16 +4610,18 @@ static int ipw_compatible_rates(struct ipw_priv *priv,
4234 rates->supported_rates[rates->num_rates++] = network->rates[i]; 4610 rates->supported_rates[rates->num_rates++] = network->rates[i];
4235 } 4611 }
4236 4612
4237 num_rates = 4613 num_rates = min(network->rates_ex_len,
4238 min(network->rates_ex_len, (u8) (IPW_MAX_RATES - num_rates)); 4614 (u8) (IPW_MAX_RATES - num_rates));
4239 for (i = 0; i < num_rates; i++) { 4615 for (i = 0; i < num_rates; i++) {
4240 if (!ipw_is_rate_in_mask 4616 if (!ipw_is_rate_in_mask(priv, network->mode,
4241 (priv, network->mode, network->rates_ex[i])) { 4617 network->rates_ex[i])) {
4242 if (network->rates_ex[i] & IEEE80211_BASIC_RATE_MASK) { 4618 if (network->rates_ex[i] & IEEE80211_BASIC_RATE_MASK) {
4243 IPW_DEBUG_SCAN 4619 IPW_DEBUG_SCAN("Adding masked mandatory "
4244 ("Basic rate %02X masked: 0x%08X\n", 4620 "rate %02X\n",
4245 network->rates_ex[i], priv->rates_mask); 4621 network->rates_ex[i]);
4246 return 0; 4622 rates->supported_rates[rates->num_rates++] =
4623 network->rates[i];
4624 continue;
4247 } 4625 }
4248 4626
4249 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n", 4627 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
@@ -4531,9 +4909,7 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
4531 * FW fatal error. 4909 * FW fatal error.
4532 */ 4910 */
4533 network->mode = is_valid_channel(priv->ieee->mode, priv->channel); 4911 network->mode = is_valid_channel(priv->ieee->mode, priv->channel);
4534 if (network->mode) { 4912 if (!network->mode) {
4535 network->channel = priv->channel;
4536 } else {
4537 IPW_WARNING("Overriding invalid channel\n"); 4913 IPW_WARNING("Overriding invalid channel\n");
4538 if (priv->ieee->mode & IEEE_A) { 4914 if (priv->ieee->mode & IEEE_A) {
4539 network->mode = IEEE_A; 4915 network->mode = IEEE_A;
@@ -4572,10 +4948,8 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
4572 network->beacon_interval = 100; /* Default */ 4948 network->beacon_interval = 100; /* Default */
4573 network->listen_interval = 10; /* Default */ 4949 network->listen_interval = 10; /* Default */
4574 network->atim_window = 0; /* Default */ 4950 network->atim_window = 0; /* Default */
4575#ifdef CONFIG_IEEE80211_WPA
4576 network->wpa_ie_len = 0; 4951 network->wpa_ie_len = 0;
4577 network->rsn_ie_len = 0; 4952 network->rsn_ie_len = 0;
4578#endif /* CONFIG_IEEE80211_WPA */
4579} 4953}
4580 4954
4581static void ipw_send_wep_keys(struct ipw_priv *priv) 4955static void ipw_send_wep_keys(struct ipw_priv *priv)
@@ -4593,9 +4967,9 @@ static void ipw_send_wep_keys(struct ipw_priv *priv)
4593 4967
4594 for (i = 0; i < 4; i++) { 4968 for (i = 0; i < 4; i++) {
4595 key->key_index = i; 4969 key->key_index = i;
4596 if (!(priv->sec.flags & (1 << i))) { 4970 if (!(priv->sec.flags & (1 << i)))
4597 key->key_size = 0; 4971 key->key_size = 0;
4598 } else { 4972 else {
4599 key->key_size = priv->sec.key_sizes[i]; 4973 key->key_size = priv->sec.key_sizes[i];
4600 memcpy(key->key, priv->sec.keys[i], key->key_size); 4974 memcpy(key->key, priv->sec.keys[i], key->key_size);
4601 } 4975 }
@@ -4752,9 +5126,10 @@ static int ipw_request_scan(struct ipw_priv *priv)
4752 } 5126 }
4753 5127
4754 if (priv->status & STATUS_SCANNING) { 5128 if (priv->status & STATUS_SCANNING) {
4755 IPW_DEBUG_HC("Concurrent scan requested. Aborting first.\n"); 5129 IPW_DEBUG_HC("Concurrent scan requested. Ignoring.\n");
5130// IPW_DEBUG_HC("Concurrent scan requested. Aborting first.\n");
4756 priv->status |= STATUS_SCAN_PENDING; 5131 priv->status |= STATUS_SCAN_PENDING;
4757 ipw_abort_scan(priv); 5132// ipw_abort_scan(priv);
4758 return 0; 5133 return 0;
4759 } 5134 }
4760 5135
@@ -4772,11 +5147,12 @@ static int ipw_request_scan(struct ipw_priv *priv)
4772 5147
4773 memset(&scan, 0, sizeof(scan)); 5148 memset(&scan, 0, sizeof(scan));
4774 5149
4775 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = 20; 5150 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = cpu_to_le16(20);
4776 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] = 20; 5151 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
4777 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = 20; 5152 cpu_to_le16(20);
5153 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(20);
4778 5154
4779 scan.full_scan_index = ieee80211_get_scans(priv->ieee); 5155 scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
4780 5156
4781#ifdef CONFIG_IPW_MONITOR 5157#ifdef CONFIG_IPW_MONITOR
4782 if (priv->ieee->iw_mode == IW_MODE_MONITOR) { 5158 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
@@ -4798,7 +5174,8 @@ static int ipw_request_scan(struct ipw_priv *priv)
4798 ipw_set_scan_type(&scan, channel_index, 5174 ipw_set_scan_type(&scan, channel_index,
4799 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN); 5175 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN);
4800 5176
4801 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = 2000; 5177 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
5178 cpu_to_le16(2000);
4802 } else { 5179 } else {
4803#endif /* CONFIG_IPW_MONITOR */ 5180#endif /* CONFIG_IPW_MONITOR */
4804 /* If we are roaming, then make this a directed scan for the current 5181 /* If we are roaming, then make this a directed scan for the current
@@ -4807,7 +5184,7 @@ static int ipw_request_scan(struct ipw_priv *priv)
4807 if ((priv->status & STATUS_ROAMING) 5184 if ((priv->status & STATUS_ROAMING)
4808 || (!(priv->status & STATUS_ASSOCIATED) 5185 || (!(priv->status & STATUS_ASSOCIATED)
4809 && (priv->config & CFG_STATIC_ESSID) 5186 && (priv->config & CFG_STATIC_ESSID)
4810 && (scan.full_scan_index % 2))) { 5187 && (le32_to_cpu(scan.full_scan_index) % 2))) {
4811 err = ipw_send_ssid(priv, priv->essid, priv->essid_len); 5188 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
4812 if (err) { 5189 if (err) {
4813 IPW_DEBUG_HC 5190 IPW_DEBUG_HC
@@ -4882,7 +5259,6 @@ static int ipw_request_scan(struct ipw_priv *priv)
4882 5259
4883/* Support for wpa_supplicant. Will be replaced with WEXT once 5260/* Support for wpa_supplicant. Will be replaced with WEXT once
4884 * they get WPA support. */ 5261 * they get WPA support. */
4885#ifdef CONFIG_IEEE80211_WPA
4886 5262
4887/* following definitions must match definitions in driver_ipw.c */ 5263/* following definitions must match definitions in driver_ipw.c */
4888 5264
@@ -4959,6 +5335,7 @@ static int ipw_wpa_enable(struct ipw_priv *priv, int value)
4959 } else { 5335 } else {
4960 sec.level = SEC_LEVEL_0; 5336 sec.level = SEC_LEVEL_0;
4961 sec.enabled = 0; 5337 sec.enabled = 0;
5338 ieee->wpa_ie_len = 0;
4962 } 5339 }
4963 5340
4964 if (ieee->set_security) 5341 if (ieee->set_security)
@@ -4999,6 +5376,8 @@ static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value)
4999static int ipw_wpa_set_param(struct net_device *dev, u8 name, u32 value) 5376static int ipw_wpa_set_param(struct net_device *dev, u8 name, u32 value)
5000{ 5377{
5001 struct ipw_priv *priv = ieee80211_priv(dev); 5378 struct ipw_priv *priv = ieee80211_priv(dev);
5379 struct ieee80211_crypt_data *crypt;
5380 unsigned long flags;
5002 int ret = 0; 5381 int ret = 0;
5003 5382
5004 switch (name) { 5383 switch (name) {
@@ -5007,7 +5386,22 @@ static int ipw_wpa_set_param(struct net_device *dev, u8 name, u32 value)
5007 break; 5386 break;
5008 5387
5009 case IPW_PARAM_TKIP_COUNTERMEASURES: 5388 case IPW_PARAM_TKIP_COUNTERMEASURES:
5010 priv->ieee->tkip_countermeasures = value; 5389 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
5390 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) {
5391 IPW_WARNING("Can't set TKIP countermeasures: "
5392 "crypt not set!\n");
5393 break;
5394 }
5395
5396 flags = crypt->ops->get_flags(crypt->priv);
5397
5398 if (value)
5399 flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
5400 else
5401 flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
5402
5403 crypt->ops->set_flags(flags, crypt->priv);
5404
5011 break; 5405 break;
5012 5406
5013 case IPW_PARAM_DROP_UNENCRYPTED: 5407 case IPW_PARAM_DROP_UNENCRYPTED:
@@ -5313,7 +5707,6 @@ static int ipw_wpa_supplicant(struct net_device *dev, struct iw_point *p)
5313 kfree(param); 5707 kfree(param);
5314 return ret; 5708 return ret;
5315} 5709}
5316#endif /* CONFIG_IEEE80211_WPA */
5317 5710
5318static int ipw_associate_network(struct ipw_priv *priv, 5711static int ipw_associate_network(struct ipw_priv *priv,
5319 struct ieee80211_network *network, 5712 struct ieee80211_network *network,
@@ -5346,13 +5739,11 @@ static int ipw_associate_network(struct ipw_priv *priv,
5346 if (priv->capability & CAP_PRIVACY_ON) 5739 if (priv->capability & CAP_PRIVACY_ON)
5347 ipw_send_wep_keys(priv); 5740 ipw_send_wep_keys(priv);
5348 5741
5349#ifdef CONFIG_IEEE80211_WPA 5742 if (priv->ieee->wpa_ie_len) {
5350 if (priv->ieee->wpa_enabled) {
5351 priv->assoc_request.policy_support = 0x02; /* RSN active */ 5743 priv->assoc_request.policy_support = 0x02; /* RSN active */
5352 ipw_set_rsn_capa(priv, priv->ieee->wpa_ie, 5744 ipw_set_rsn_capa(priv, priv->ieee->wpa_ie,
5353 priv->ieee->wpa_ie_len); 5745 priv->ieee->wpa_ie_len);
5354 } 5746 }
5355#endif
5356 5747
5357 /* 5748 /*
5358 * It is valid for our ieee device to support multiple modes, but 5749 * It is valid for our ieee device to support multiple modes, but
@@ -5511,12 +5902,15 @@ static void ipw_roam(void *data)
5511 if (priv->status & STATUS_ASSOCIATED) { 5902 if (priv->status & STATUS_ASSOCIATED) {
5512 /* First pass through ROAM process -- look for a better 5903 /* First pass through ROAM process -- look for a better
5513 * network */ 5904 * network */
5905 unsigned long flags;
5514 u8 rssi = priv->assoc_network->stats.rssi; 5906 u8 rssi = priv->assoc_network->stats.rssi;
5515 priv->assoc_network->stats.rssi = -128; 5907 priv->assoc_network->stats.rssi = -128;
5908 spin_lock_irqsave(&priv->ieee->lock, flags);
5516 list_for_each_entry(network, &priv->ieee->network_list, list) { 5909 list_for_each_entry(network, &priv->ieee->network_list, list) {
5517 if (network != priv->assoc_network) 5910 if (network != priv->assoc_network)
5518 ipw_best_network(priv, &match, network, 1); 5911 ipw_best_network(priv, &match, network, 1);
5519 } 5912 }
5913 spin_unlock_irqrestore(&priv->ieee->lock, flags);
5520 priv->assoc_network->stats.rssi = rssi; 5914 priv->assoc_network->stats.rssi = rssi;
5521 5915
5522 if (match.network == priv->assoc_network) { 5916 if (match.network == priv->assoc_network) {
@@ -5549,6 +5943,7 @@ static void ipw_associate(void *data)
5549 }; 5943 };
5550 struct ipw_supported_rates *rates; 5944 struct ipw_supported_rates *rates;
5551 struct list_head *element; 5945 struct list_head *element;
5946 unsigned long flags;
5552 5947
5553 if (!(priv->config & CFG_ASSOCIATE) && 5948 if (!(priv->config & CFG_ASSOCIATE) &&
5554 !(priv->config & (CFG_STATIC_ESSID | 5949 !(priv->config & (CFG_STATIC_ESSID |
@@ -5557,6 +5952,8 @@ static void ipw_associate(void *data)
5557 return; 5952 return;
5558 } 5953 }
5559 5954
5955 /* Protect our use of the network_list */
5956 spin_lock_irqsave(&priv->ieee->lock, flags);
5560 list_for_each_entry(network, &priv->ieee->network_list, list) 5957 list_for_each_entry(network, &priv->ieee->network_list, list)
5561 ipw_best_network(priv, &match, network, 0); 5958 ipw_best_network(priv, &match, network, 0);
5562 5959
@@ -5567,6 +5964,7 @@ static void ipw_associate(void *data)
5567 priv->ieee->iw_mode == IW_MODE_ADHOC && 5964 priv->ieee->iw_mode == IW_MODE_ADHOC &&
5568 priv->config & CFG_ADHOC_CREATE && 5965 priv->config & CFG_ADHOC_CREATE &&
5569 priv->config & CFG_STATIC_ESSID && 5966 priv->config & CFG_STATIC_ESSID &&
5967 priv->config & CFG_STATIC_CHANNEL &&
5570 !list_empty(&priv->ieee->network_free_list)) { 5968 !list_empty(&priv->ieee->network_free_list)) {
5571 element = priv->ieee->network_free_list.next; 5969 element = priv->ieee->network_free_list.next;
5572 network = list_entry(element, struct ieee80211_network, list); 5970 network = list_entry(element, struct ieee80211_network, list);
@@ -5575,14 +5973,16 @@ static void ipw_associate(void *data)
5575 list_del(element); 5973 list_del(element);
5576 list_add_tail(&network->list, &priv->ieee->network_list); 5974 list_add_tail(&network->list, &priv->ieee->network_list);
5577 } 5975 }
5976 spin_unlock_irqrestore(&priv->ieee->lock, flags);
5578 5977
5579 /* If we reached the end of the list, then we don't have any valid 5978 /* If we reached the end of the list, then we don't have any valid
5580 * matching APs */ 5979 * matching APs */
5581 if (!network) { 5980 if (!network) {
5582 ipw_debug_config(priv); 5981 ipw_debug_config(priv);
5583 5982
5584 queue_delayed_work(priv->workqueue, &priv->request_scan, 5983 if (!(priv->status & STATUS_SCANNING))
5585 SCAN_INTERVAL); 5984 queue_delayed_work(priv->workqueue, &priv->request_scan,
5985 SCAN_INTERVAL);
5586 5986
5587 return; 5987 return;
5588 } 5988 }
@@ -5601,7 +6001,7 @@ static inline void ipw_handle_data_packet(struct ipw_priv *priv,
5601 6001
5602 /* We only process data packets if the 6002 /* We only process data packets if the
5603 * interface is open */ 6003 * interface is open */
5604 if (unlikely((pkt->u.frame.length + IPW_RX_FRAME_SIZE) > 6004 if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
5605 skb_tailroom(rxb->skb))) { 6005 skb_tailroom(rxb->skb))) {
5606 priv->ieee->stats.rx_errors++; 6006 priv->ieee->stats.rx_errors++;
5607 priv->wstats.discard.misc++; 6007 priv->wstats.discard.misc++;
@@ -5618,14 +6018,16 @@ static inline void ipw_handle_data_packet(struct ipw_priv *priv,
5618 skb_reserve(rxb->skb, offsetof(struct ipw_rx_packet, u.frame.data)); 6018 skb_reserve(rxb->skb, offsetof(struct ipw_rx_packet, u.frame.data));
5619 6019
5620 /* Set the size of the skb to the size of the frame */ 6020 /* Set the size of the skb to the size of the frame */
5621 skb_put(rxb->skb, pkt->u.frame.length); 6021 skb_put(rxb->skb, le16_to_cpu(pkt->u.frame.length));
5622 6022
5623 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len); 6023 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
5624 6024
5625 if (!ieee80211_rx(priv->ieee, rxb->skb, stats)) 6025 if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
5626 priv->ieee->stats.rx_errors++; 6026 priv->ieee->stats.rx_errors++;
5627 else /* ieee80211_rx succeeded, so it now owns the SKB */ 6027 else { /* ieee80211_rx succeeded, so it now owns the SKB */
5628 rxb->skb = NULL; 6028 rxb->skb = NULL;
6029 ipw_led_activity_on(priv);
6030 }
5629} 6031}
5630 6032
5631static inline int is_network_packet(struct ipw_priv *priv, 6033static inline int is_network_packet(struct ipw_priv *priv,
@@ -5634,23 +6036,29 @@ static inline int is_network_packet(struct ipw_priv *priv,
5634 /* Filter incoming packets to determine if they are targetted toward 6036 /* Filter incoming packets to determine if they are targetted toward
5635 * this network, discarding packets coming from ourselves */ 6037 * this network, discarding packets coming from ourselves */
5636 switch (priv->ieee->iw_mode) { 6038 switch (priv->ieee->iw_mode) {
5637 case IW_MODE_ADHOC: 6039 case IW_MODE_ADHOC: /* Header: Dest. | Source | BSSID */
6040 /* {broad,multi}cast packets to our IBSS go through */
5638 if (is_broadcast_ether_addr(header->addr1) || 6041 if (is_broadcast_ether_addr(header->addr1) ||
5639 is_multicast_ether_addr(header->addr1)) 6042 is_multicast_ether_addr(header->addr1))
5640 return !memcmp(header->addr3, priv->bssid, ETH_ALEN); 6043 return !memcmp(header->addr3, priv->bssid, ETH_ALEN);
5641 else 6044
5642 return memcmp(header->addr1, priv->net_dev->dev_addr, 6045 /* packets to our adapter go through */
5643 ETH_ALEN); 6046 return !memcmp(header->addr1, priv->net_dev->dev_addr,
6047 ETH_ALEN);
5644 break; 6048 break;
5645 case IW_MODE_INFRA: 6049
5646 if (is_broadcast_ether_addr(header->addr3) || 6050 case IW_MODE_INFRA: /* Header: Dest. | AP{BSSID} | Source */
5647 is_multicast_ether_addr(header->addr3)) 6051 /* {broad,multi}cast packets to our IBSS go through */
5648 return !memcmp(header->addr1, priv->bssid, ETH_ALEN); 6052 if (is_broadcast_ether_addr(header->addr1) ||
5649 else 6053 is_multicast_ether_addr(header->addr1))
5650 return memcmp(header->addr3, priv->net_dev->dev_addr, 6054 return !memcmp(header->addr2, priv->bssid, ETH_ALEN);
5651 ETH_ALEN); 6055
6056 /* packets to our adapter go through */
6057 return !memcmp(header->addr1, priv->net_dev->dev_addr,
6058 ETH_ALEN);
5652 break; 6059 break;
5653 } 6060 }
6061
5654 return 1; 6062 return 1;
5655} 6063}
5656 6064
@@ -5695,7 +6103,7 @@ static void ipw_rx(struct ipw_priv *priv)
5695 struct ieee80211_rx_stats stats = { 6103 struct ieee80211_rx_stats stats = {
5696 .rssi = pkt->u.frame.rssi_dbm - 6104 .rssi = pkt->u.frame.rssi_dbm -
5697 IPW_RSSI_TO_DBM, 6105 IPW_RSSI_TO_DBM,
5698 .signal = pkt->u.frame.signal, 6106 /* .signal = le16_to_cpu(pkt->u.frame.signal), */
5699 .rate = pkt->u.frame.rate, 6107 .rate = pkt->u.frame.rate,
5700 .mac_time = jiffies, 6108 .mac_time = jiffies,
5701 .received_channel = 6109 .received_channel =
@@ -5705,7 +6113,7 @@ static void ipw_rx(struct ipw_priv *priv)
5705 control & (1 << 0)) ? 6113 control & (1 << 0)) ?
5706 IEEE80211_24GHZ_BAND : 6114 IEEE80211_24GHZ_BAND :
5707 IEEE80211_52GHZ_BAND, 6115 IEEE80211_52GHZ_BAND,
5708 .len = pkt->u.frame.length, 6116 .len = le16_to_cpu(pkt->u.frame.length),
5709 }; 6117 };
5710 6118
5711 if (stats.rssi != 0) 6119 if (stats.rssi != 0)
@@ -5746,9 +6154,10 @@ static void ipw_rx(struct ipw_priv *priv)
5746 } 6154 }
5747 6155
5748 IPW_DEBUG_RX("Frame: len=%u\n", 6156 IPW_DEBUG_RX("Frame: len=%u\n",
5749 pkt->u.frame.length); 6157 le16_to_cpu(pkt->u.frame.length));
5750 6158
5751 if (pkt->u.frame.length < frame_hdr_len(header)) { 6159 if (le16_to_cpu(pkt->u.frame.length) <
6160 frame_hdr_len(header)) {
5752 IPW_DEBUG_DROP 6161 IPW_DEBUG_DROP
5753 ("Received packet is too small. " 6162 ("Received packet is too small. "
5754 "Dropping.\n"); 6163 "Dropping.\n");
@@ -5757,19 +6166,20 @@ static void ipw_rx(struct ipw_priv *priv)
5757 break; 6166 break;
5758 } 6167 }
5759 6168
5760 switch (WLAN_FC_GET_TYPE(header->frame_ctl)) { 6169 switch (WLAN_FC_GET_TYPE
6170 (le16_to_cpu(header->frame_ctl))) {
5761 case IEEE80211_FTYPE_MGMT: 6171 case IEEE80211_FTYPE_MGMT:
5762 ieee80211_rx_mgt(priv->ieee, header, 6172 ieee80211_rx_mgt(priv->ieee, header,
5763 &stats); 6173 &stats);
5764 if (priv->ieee->iw_mode == IW_MODE_ADHOC 6174 if (priv->ieee->iw_mode == IW_MODE_ADHOC
5765 && 6175 &&
5766 ((WLAN_FC_GET_STYPE 6176 ((WLAN_FC_GET_STYPE
5767 (header->frame_ctl) == 6177 (le16_to_cpu(header->frame_ctl))
5768 IEEE80211_STYPE_PROBE_RESP) 6178 == IEEE80211_STYPE_PROBE_RESP)
5769 || 6179 ||
5770 (WLAN_FC_GET_STYPE 6180 (WLAN_FC_GET_STYPE
5771 (header->frame_ctl) == 6181 (le16_to_cpu(header->frame_ctl))
5772 IEEE80211_STYPE_BEACON)) 6182 == IEEE80211_STYPE_BEACON))
5773 && !memcmp(header->addr3, 6183 && !memcmp(header->addr3,
5774 priv->bssid, ETH_ALEN)) 6184 priv->bssid, ETH_ALEN))
5775 ipw_add_station(priv, 6185 ipw_add_station(priv,
@@ -5852,7 +6262,9 @@ static int ipw_wx_get_name(struct net_device *dev,
5852 union iwreq_data *wrqu, char *extra) 6262 union iwreq_data *wrqu, char *extra)
5853{ 6263{
5854 struct ipw_priv *priv = ieee80211_priv(dev); 6264 struct ipw_priv *priv = ieee80211_priv(dev);
5855 if (!(priv->status & STATUS_ASSOCIATED)) 6265 if (priv->status & STATUS_RF_KILL_MASK) {
6266 strcpy(wrqu->name, "radio off");
6267 } else if (!(priv->status & STATUS_ASSOCIATED))
5856 strcpy(wrqu->name, "unassociated"); 6268 strcpy(wrqu->name, "unassociated");
5857 else 6269 else
5858 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c", 6270 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c",
@@ -5892,9 +6304,8 @@ static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
5892 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 6304 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
5893 IPW_DEBUG_ASSOC("Disassociating due to channel change.\n"); 6305 IPW_DEBUG_ASSOC("Disassociating due to channel change.\n");
5894 ipw_disassociate(priv); 6306 ipw_disassociate(priv);
5895 } else { 6307 } else if (!(priv->status & (STATUS_SCANNING)))
5896 ipw_associate(priv); 6308 ipw_associate(priv);
5897 }
5898 6309
5899 return 0; 6310 return 0;
5900} 6311}
@@ -5986,9 +6397,8 @@ static int ipw_wx_set_mode(struct net_device *dev,
5986#ifdef CONFIG_PM 6397#ifdef CONFIG_PM
5987 /* Free the existing firmware and reset the fw_loaded 6398 /* Free the existing firmware and reset the fw_loaded
5988 * flag so ipw_load() will bring in the new firmawre */ 6399 * flag so ipw_load() will bring in the new firmawre */
5989 if (fw_loaded) { 6400 if (fw_loaded)
5990 fw_loaded = 0; 6401 fw_loaded = 0;
5991 }
5992 6402
5993 release_firmware(bootfw); 6403 release_firmware(bootfw);
5994 release_firmware(ucode); 6404 release_firmware(ucode);
@@ -5997,7 +6407,7 @@ static int ipw_wx_set_mode(struct net_device *dev,
5997#endif 6407#endif
5998 6408
5999 priv->ieee->iw_mode = wrqu->mode; 6409 priv->ieee->iw_mode = wrqu->mode;
6000 ipw_adapter_restart(priv); 6410 queue_work(priv->workqueue, &priv->adapter_restart);
6001 6411
6002 return err; 6412 return err;
6003} 6413}
@@ -6149,9 +6559,8 @@ static int ipw_wx_set_wap(struct net_device *dev,
6149 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 6559 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
6150 IPW_DEBUG_ASSOC("Disassociating due to BSSID change.\n"); 6560 IPW_DEBUG_ASSOC("Disassociating due to BSSID change.\n");
6151 ipw_disassociate(priv); 6561 ipw_disassociate(priv);
6152 } else { 6562 } else if (!(priv->status & (STATUS_SCANNING)))
6153 ipw_associate(priv); 6563 ipw_associate(priv);
6154 }
6155 6564
6156 return 0; 6565 return 0;
6157} 6566}
@@ -6220,9 +6629,8 @@ static int ipw_wx_set_essid(struct net_device *dev,
6220 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 6629 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
6221 IPW_DEBUG_ASSOC("Disassociating due to ESSID change.\n"); 6630 IPW_DEBUG_ASSOC("Disassociating due to ESSID change.\n");
6222 ipw_disassociate(priv); 6631 ipw_disassociate(priv);
6223 } else { 6632 } else if (!(priv->status & (STATUS_SCANNING)))
6224 ipw_associate(priv); 6633 ipw_associate(priv);
6225 }
6226 6634
6227 return 0; 6635 return 0;
6228} 6636}
@@ -6383,10 +6791,10 @@ static int ipw_wx_set_rate(struct net_device *dev,
6383 if ((priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) { 6791 if ((priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) {
6384 IPW_DEBUG_ASSOC("Disassociating due to RATE change.\n"); 6792 IPW_DEBUG_ASSOC("Disassociating due to RATE change.\n");
6385 ipw_disassociate(priv); 6793 ipw_disassociate(priv);
6794 } else if (!(priv->status & (STATUS_SCANNING))) {
6795 /* We are not yet associated, so kick one off... */
6796 ipw_associate(priv);
6386 } 6797 }
6387 } else {
6388 /* We are not yet associated, so kick one off... */
6389 ipw_associate(priv);
6390 } 6798 }
6391 6799
6392 return 0; 6800 return 0;
@@ -6635,11 +7043,10 @@ static int ipw_wx_get_power(struct net_device *dev,
6635{ 7043{
6636 struct ipw_priv *priv = ieee80211_priv(dev); 7044 struct ipw_priv *priv = ieee80211_priv(dev);
6637 7045
6638 if (!(priv->power_mode & IPW_POWER_ENABLED)) { 7046 if (!(priv->power_mode & IPW_POWER_ENABLED))
6639 wrqu->power.disabled = 1; 7047 wrqu->power.disabled = 1;
6640 } else { 7048 else
6641 wrqu->power.disabled = 0; 7049 wrqu->power.disabled = 0;
6642 }
6643 7050
6644 IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode); 7051 IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode);
6645 7052
@@ -6764,6 +7171,9 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
6764 } else 7171 } else
6765 ipw_send_supported_rates(priv, &priv->rates); 7172 ipw_send_supported_rates(priv, &priv->rates);
6766 7173
7174 /* Update the band LEDs */
7175 ipw_led_band_on(priv);
7176
6767 IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n", 7177 IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n",
6768 mode & IEEE_A ? 'a' : '.', 7178 mode & IEEE_A ? 'a' : '.',
6769 mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.'); 7179 mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.');
@@ -6870,7 +7280,7 @@ static int ipw_wx_set_monitor(struct net_device *dev,
6870 if (enable) { 7280 if (enable) {
6871 if (priv->ieee->iw_mode != IW_MODE_MONITOR) { 7281 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
6872 priv->net_dev->type = ARPHRD_IEEE80211; 7282 priv->net_dev->type = ARPHRD_IEEE80211;
6873 ipw_adapter_restart(priv); 7283 queue_work(priv->workqueue, &priv->adapter_restart);
6874 } 7284 }
6875 7285
6876 ipw_set_channel(priv, parms[1]); 7286 ipw_set_channel(priv, parms[1]);
@@ -6878,7 +7288,7 @@ static int ipw_wx_set_monitor(struct net_device *dev,
6878 if (priv->ieee->iw_mode != IW_MODE_MONITOR) 7288 if (priv->ieee->iw_mode != IW_MODE_MONITOR)
6879 return 0; 7289 return 0;
6880 priv->net_dev->type = ARPHRD_ETHER; 7290 priv->net_dev->type = ARPHRD_ETHER;
6881 ipw_adapter_restart(priv); 7291 queue_work(priv->workqueue, &priv->adapter_restart);
6882 } 7292 }
6883 return 0; 7293 return 0;
6884} 7294}
@@ -6889,7 +7299,7 @@ static int ipw_wx_reset(struct net_device *dev,
6889{ 7299{
6890 struct ipw_priv *priv = ieee80211_priv(dev); 7300 struct ipw_priv *priv = ieee80211_priv(dev);
6891 IPW_DEBUG_WX("RESET\n"); 7301 IPW_DEBUG_WX("RESET\n");
6892 ipw_adapter_restart(priv); 7302 queue_work(priv->workqueue, &priv->adapter_restart);
6893 return 0; 7303 return 0;
6894} 7304}
6895#endif // CONFIG_IPW_MONITOR 7305#endif // CONFIG_IPW_MONITOR
@@ -6925,6 +7335,10 @@ static iw_handler ipw_wx_handlers[] = {
6925 IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode, 7335 IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode,
6926 IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power, 7336 IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power,
6927 IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power, 7337 IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power,
7338 IW_IOCTL(SIOCSIWSPY) = iw_handler_set_spy,
7339 IW_IOCTL(SIOCGIWSPY) = iw_handler_get_spy,
7340 IW_IOCTL(SIOCSIWTHRSPY) = iw_handler_set_thrspy,
7341 IW_IOCTL(SIOCGIWTHRSPY) = iw_handler_get_thrspy,
6928}; 7342};
6929 7343
6930#define IPW_PRIV_SET_POWER SIOCIWFIRSTPRIV 7344#define IPW_PRIV_SET_POWER SIOCIWFIRSTPRIV
@@ -6993,6 +7407,8 @@ static struct iw_handler_def ipw_wx_handler_def = {
6993 .private_args = ipw_priv_args, 7407 .private_args = ipw_priv_args,
6994}; 7408};
6995 7409
7410static struct iw_public_data ipw_wx_data;
7411
6996/* 7412/*
6997 * Get wireless statistics. 7413 * Get wireless statistics.
6998 * Called by /proc/net/wireless 7414 * Called by /proc/net/wireless
@@ -7057,7 +7473,7 @@ static inline void init_sys_config(struct ipw_sys_config *sys_config)
7057 sys_config->dot11g_auto_detection = 0; 7473 sys_config->dot11g_auto_detection = 0;
7058 sys_config->enable_cts_to_self = 0; 7474 sys_config->enable_cts_to_self = 0;
7059 sys_config->bt_coexist_collision_thr = 0; 7475 sys_config->bt_coexist_collision_thr = 0;
7060 sys_config->pass_noise_stats_to_host = 1; 7476 sys_config->pass_noise_stats_to_host = 0; //1 -- fix for 256
7061} 7477}
7062 7478
7063static int ipw_net_open(struct net_device *dev) 7479static int ipw_net_open(struct net_device *dev)
@@ -7131,7 +7547,7 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
7131 tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK; 7547 tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK;
7132 7548
7133 tfd->u.data.cmd_id = DINO_CMD_TX; 7549 tfd->u.data.cmd_id = DINO_CMD_TX;
7134 tfd->u.data.len = txb->payload_size; 7550 tfd->u.data.len = cpu_to_le16(txb->payload_size);
7135 remaining_bytes = txb->payload_size; 7551 remaining_bytes = txb->payload_size;
7136 if (unlikely(!unicast)) 7552 if (unlikely(!unicast))
7137 tfd->u.data.tx_flags = DCT_FLAG_NO_WEP; 7553 tfd->u.data.tx_flags = DCT_FLAG_NO_WEP;
@@ -7149,8 +7565,14 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
7149 memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len); 7565 memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len);
7150 7566
7151 /* payload */ 7567 /* payload */
7152 tfd->u.data.num_chunks = min((u8) (NUM_TFD_CHUNKS - 2), txb->nr_frags); 7568 tfd->u.data.num_chunks = cpu_to_le32(min((u8) (NUM_TFD_CHUNKS - 2),
7153 for (i = 0; i < tfd->u.data.num_chunks; i++) { 7569 txb->nr_frags));
7570 IPW_DEBUG_FRAG("%i fragments being sent as %i chunks.\n",
7571 txb->nr_frags, le32_to_cpu(tfd->u.data.num_chunks));
7572 for (i = 0; i < le32_to_cpu(tfd->u.data.num_chunks); i++) {
7573 IPW_DEBUG_FRAG("Adding fragment %i of %i (%d bytes).\n",
7574 i, le32_to_cpu(tfd->u.data.num_chunks),
7575 txb->fragments[i]->len - hdr_len);
7154 IPW_DEBUG_TX("Dumping TX packet frag %i of %i (%d bytes):\n", 7576 IPW_DEBUG_TX("Dumping TX packet frag %i of %i (%d bytes):\n",
7155 i, tfd->u.data.num_chunks, 7577 i, tfd->u.data.num_chunks,
7156 txb->fragments[i]->len - hdr_len); 7578 txb->fragments[i]->len - hdr_len);
@@ -7158,11 +7580,13 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
7158 txb->fragments[i]->len - hdr_len); 7580 txb->fragments[i]->len - hdr_len);
7159 7581
7160 tfd->u.data.chunk_ptr[i] = 7582 tfd->u.data.chunk_ptr[i] =
7161 pci_map_single(priv->pci_dev, 7583 cpu_to_le32(pci_map_single
7162 txb->fragments[i]->data + hdr_len, 7584 (priv->pci_dev,
7163 txb->fragments[i]->len - hdr_len, 7585 txb->fragments[i]->data + hdr_len,
7164 PCI_DMA_TODEVICE); 7586 txb->fragments[i]->len - hdr_len,
7165 tfd->u.data.chunk_len[i] = txb->fragments[i]->len - hdr_len; 7587 PCI_DMA_TODEVICE));
7588 tfd->u.data.chunk_len[i] =
7589 cpu_to_le16(txb->fragments[i]->len - hdr_len);
7166 } 7590 }
7167 7591
7168 if (i != txb->nr_frags) { 7592 if (i != txb->nr_frags) {
@@ -7177,7 +7601,7 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
7177 remaining_bytes); 7601 remaining_bytes);
7178 skb = alloc_skb(remaining_bytes, GFP_ATOMIC); 7602 skb = alloc_skb(remaining_bytes, GFP_ATOMIC);
7179 if (skb != NULL) { 7603 if (skb != NULL) {
7180 tfd->u.data.chunk_len[i] = remaining_bytes; 7604 tfd->u.data.chunk_len[i] = cpu_to_le16(remaining_bytes);
7181 for (j = i; j < txb->nr_frags; j++) { 7605 for (j = i; j < txb->nr_frags; j++) {
7182 int size = txb->fragments[j]->len - hdr_len; 7606 int size = txb->fragments[j]->len - hdr_len;
7183 printk(KERN_INFO "Adding frag %d %d...\n", 7607 printk(KERN_INFO "Adding frag %d %d...\n",
@@ -7188,10 +7612,14 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
7188 dev_kfree_skb_any(txb->fragments[i]); 7612 dev_kfree_skb_any(txb->fragments[i]);
7189 txb->fragments[i] = skb; 7613 txb->fragments[i] = skb;
7190 tfd->u.data.chunk_ptr[i] = 7614 tfd->u.data.chunk_ptr[i] =
7191 pci_map_single(priv->pci_dev, skb->data, 7615 cpu_to_le32(pci_map_single
7192 tfd->u.data.chunk_len[i], 7616 (priv->pci_dev, skb->data,
7193 PCI_DMA_TODEVICE); 7617 tfd->u.data.chunk_len[i],
7194 tfd->u.data.num_chunks++; 7618 PCI_DMA_TODEVICE));
7619
7620 tfd->u.data.num_chunks =
7621 cpu_to_le32(le32_to_cpu(tfd->u.data.num_chunks) +
7622 1);
7195 } 7623 }
7196 } 7624 }
7197 7625
@@ -7227,6 +7655,7 @@ static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
7227 } 7655 }
7228 7656
7229 ipw_tx_skb(priv, txb); 7657 ipw_tx_skb(priv, txb);
7658 ipw_led_activity_on(priv);
7230 7659
7231 spin_unlock_irqrestore(&priv->lock, flags); 7660 spin_unlock_irqrestore(&priv->lock, flags);
7232 return 0; 7661 return 0;
@@ -7260,7 +7689,7 @@ static int ipw_net_set_mac_address(struct net_device *dev, void *p)
7260 memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN); 7689 memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
7261 printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n", 7690 printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n",
7262 priv->net_dev->name, MAC_ARG(priv->mac_addr)); 7691 priv->net_dev->name, MAC_ARG(priv->mac_addr));
7263 ipw_adapter_restart(priv); 7692 queue_work(priv->workqueue, &priv->adapter_restart);
7264 return 0; 7693 return 0;
7265} 7694}
7266 7695
@@ -7414,6 +7843,46 @@ static void ipw_rf_kill(void *adapter)
7414 spin_unlock_irqrestore(&priv->lock, flags); 7843 spin_unlock_irqrestore(&priv->lock, flags);
7415} 7844}
7416 7845
7846void ipw_link_up(struct ipw_priv *priv)
7847{
7848 netif_carrier_on(priv->net_dev);
7849 if (netif_queue_stopped(priv->net_dev)) {
7850 IPW_DEBUG_NOTIF("waking queue\n");
7851 netif_wake_queue(priv->net_dev);
7852 } else {
7853 IPW_DEBUG_NOTIF("starting queue\n");
7854 netif_start_queue(priv->net_dev);
7855 }
7856
7857 ipw_reset_stats(priv);
7858 /* Ensure the rate is updated immediately */
7859 priv->last_rate = ipw_get_current_rate(priv);
7860 ipw_gather_stats(priv);
7861 ipw_led_link_up(priv);
7862 notify_wx_assoc_event(priv);
7863
7864 if (priv->config & CFG_BACKGROUND_SCAN)
7865 queue_delayed_work(priv->workqueue, &priv->request_scan, HZ);
7866}
7867
7868void ipw_link_down(struct ipw_priv *priv)
7869{
7870 ipw_led_link_down(priv);
7871 netif_carrier_off(priv->net_dev);
7872 netif_stop_queue(priv->net_dev);
7873 notify_wx_assoc_event(priv);
7874
7875 /* Cancel any queued work ... */
7876 cancel_delayed_work(&priv->request_scan);
7877 cancel_delayed_work(&priv->adhoc_check);
7878 cancel_delayed_work(&priv->gather_stats);
7879
7880 ipw_reset_stats(priv);
7881
7882 /* Queue up another scan... */
7883 queue_work(priv->workqueue, &priv->request_scan);
7884}
7885
7417static int ipw_setup_deferred_work(struct ipw_priv *priv) 7886static int ipw_setup_deferred_work(struct ipw_priv *priv)
7418{ 7887{
7419 int ret = 0; 7888 int ret = 0;
@@ -7436,6 +7905,13 @@ static int ipw_setup_deferred_work(struct ipw_priv *priv)
7436 INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_abort_scan, priv); 7905 INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_abort_scan, priv);
7437 INIT_WORK(&priv->roam, ipw_roam, priv); 7906 INIT_WORK(&priv->roam, ipw_roam, priv);
7438 INIT_WORK(&priv->scan_check, ipw_scan_check, priv); 7907 INIT_WORK(&priv->scan_check, ipw_scan_check, priv);
7908 INIT_WORK(&priv->link_up, (void (*)(void *))ipw_link_up, priv);
7909 INIT_WORK(&priv->link_down, (void (*)(void *))ipw_link_down, priv);
7910 INIT_WORK(&priv->led_link_on, (void (*)(void *))ipw_led_link_on, priv);
7911 INIT_WORK(&priv->led_link_off, (void (*)(void *))ipw_led_link_off,
7912 priv);
7913 INIT_WORK(&priv->led_act_off, (void (*)(void *))ipw_led_activity_off,
7914 priv);
7439 7915
7440 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) 7916 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
7441 ipw_irq_tasklet, (unsigned long)priv); 7917 ipw_irq_tasklet, (unsigned long)priv);
@@ -7636,8 +8112,9 @@ static int ipw_up(struct ipw_priv *priv)
7636 rc = ipw_config(priv); 8112 rc = ipw_config(priv);
7637 if (!rc) { 8113 if (!rc) {
7638 IPW_DEBUG_INFO("Configured device on count %i\n", i); 8114 IPW_DEBUG_INFO("Configured device on count %i\n", i);
8115 ipw_led_init(priv);
8116 ipw_led_radio_on(priv);
7639 priv->notif_missed_beacons = 0; 8117 priv->notif_missed_beacons = 0;
7640 netif_start_queue(priv->net_dev);
7641 return 0; 8118 return 0;
7642 } else { 8119 } else {
7643 IPW_DEBUG_INFO("Device configuration failed: 0x%08X\n", 8120 IPW_DEBUG_INFO("Device configuration failed: 0x%08X\n",
@@ -7675,11 +8152,12 @@ static void ipw_down(struct ipw_priv *priv)
7675 netif_stop_queue(priv->net_dev); 8152 netif_stop_queue(priv->net_dev);
7676 8153
7677 ipw_stop_nic(priv); 8154 ipw_stop_nic(priv);
8155
8156 ipw_led_radio_off(priv);
7678} 8157}
7679 8158
7680static int ipw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 8159static int ipw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
7681{ 8160{
7682#ifdef CONFIG_IEEE80211_WPA
7683 struct iwreq *wrq = (struct iwreq *)rq; 8161 struct iwreq *wrq = (struct iwreq *)rq;
7684 int ret = -1; 8162 int ret = -1;
7685 switch (cmd) { 8163 switch (cmd) {
@@ -7691,8 +8169,6 @@ static int ipw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
7691 return -EOPNOTSUPP; 8169 return -EOPNOTSUPP;
7692 } 8170 }
7693 8171
7694#endif /* CONFIG_IEEE80211_WPA */
7695
7696 return -EOPNOTSUPP; 8172 return -EOPNOTSUPP;
7697} 8173}
7698 8174
@@ -7739,7 +8215,7 @@ static struct pci_device_id card_ids[] = {
7739 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2762, 0, 0, 0}, 8215 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2762, 0, 0, 0},
7740 {PCI_VENDOR_ID_INTEL, 0x104f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 8216 {PCI_VENDOR_ID_INTEL, 0x104f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
7741 {PCI_VENDOR_ID_INTEL, 0x4220, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */ 8217 {PCI_VENDOR_ID_INTEL, 0x4220, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */
7742 {PCI_VENDOR_ID_INTEL, 0x4221, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 2225BG */ 8218 {PCI_VENDOR_ID_INTEL, 0x4221, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */
7743 {PCI_VENDOR_ID_INTEL, 0x4223, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */ 8219 {PCI_VENDOR_ID_INTEL, 0x4223, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */
7744 {PCI_VENDOR_ID_INTEL, 0x4224, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */ 8220 {PCI_VENDOR_ID_INTEL, 0x4224, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */
7745 8221
@@ -7764,6 +8240,8 @@ static struct attribute *ipw_sysfs_entries[] = {
7764 &dev_attr_eeprom_delay.attr, 8240 &dev_attr_eeprom_delay.attr,
7765 &dev_attr_ucode_version.attr, 8241 &dev_attr_ucode_version.attr,
7766 &dev_attr_rtc.attr, 8242 &dev_attr_rtc.attr,
8243 &dev_attr_scan_age.attr,
8244 &dev_attr_led.attr,
7767 NULL 8245 NULL
7768}; 8246};
7769 8247
@@ -7789,6 +8267,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7789 8267
7790 priv = ieee80211_priv(net_dev); 8268 priv = ieee80211_priv(net_dev);
7791 priv->ieee = netdev_priv(net_dev); 8269 priv->ieee = netdev_priv(net_dev);
8270
7792 priv->net_dev = net_dev; 8271 priv->net_dev = net_dev;
7793 priv->pci_dev = pdev; 8272 priv->pci_dev = pdev;
7794#ifdef CONFIG_IPW_DEBUG 8273#ifdef CONFIG_IPW_DEBUG
@@ -7843,6 +8322,12 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7843 } 8322 }
7844 8323
7845 /* Initialize module parameter values here */ 8324 /* Initialize module parameter values here */
8325
8326 /* We default to disabling the LED code as right now it causes
8327 * too many systems to lock up... */
8328 if (!led)
8329 priv->config |= CFG_NO_LED;
8330
7846 if (associate) 8331 if (associate)
7847 priv->config |= CFG_ASSOCIATE; 8332 priv->config |= CFG_ASSOCIATE;
7848 else 8333 else
@@ -7893,14 +8378,9 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7893 priv->adapter = IPW_2915ABG; 8378 priv->adapter = IPW_2915ABG;
7894 priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B; 8379 priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B;
7895 } else { 8380 } else {
7896 if (priv->pci_dev->device == 0x4221) 8381 printk(KERN_INFO DRV_NAME
7897 printk(KERN_INFO DRV_NAME 8382 ": Detected Intel PRO/Wireless 2200BG Network "
7898 ": Detected Intel PRO/Wireless 2225BG Network " 8383 "Connection\n");
7899 "Connection\n");
7900 else
7901 printk(KERN_INFO DRV_NAME
7902 ": Detected Intel PRO/Wireless 2200BG Network "
7903 "Connection\n");
7904 8384
7905 priv->ieee->abg_true = 0; 8385 priv->ieee->abg_true = 0;
7906 band = IEEE80211_24GHZ_BAND; 8386 band = IEEE80211_24GHZ_BAND;
@@ -7933,6 +8413,9 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7933 SET_MODULE_OWNER(net_dev); 8413 SET_MODULE_OWNER(net_dev);
7934 SET_NETDEV_DEV(net_dev, &pdev->dev); 8414 SET_NETDEV_DEV(net_dev, &pdev->dev);
7935 8415
8416 ipw_wx_data.spy_data = &priv->ieee->spy_data;
8417 ipw_wx_data.ieee80211 = priv->ieee;
8418
7936 priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit; 8419 priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit;
7937 priv->ieee->set_security = shim__set_security; 8420 priv->ieee->set_security = shim__set_security;
7938 8421
@@ -7944,6 +8427,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7944 net_dev->set_multicast_list = ipw_net_set_multicast_list; 8427 net_dev->set_multicast_list = ipw_net_set_multicast_list;
7945 net_dev->set_mac_address = ipw_net_set_mac_address; 8428 net_dev->set_mac_address = ipw_net_set_mac_address;
7946 net_dev->get_wireless_stats = ipw_get_wireless_stats; 8429 net_dev->get_wireless_stats = ipw_get_wireless_stats;
8430 net_dev->wireless_data = &ipw_wx_data;
7947 net_dev->wireless_handlers = &ipw_wx_handler_def; 8431 net_dev->wireless_handlers = &ipw_wx_handler_def;
7948 net_dev->ethtool_ops = &ipw_ethtool_ops; 8432 net_dev->ethtool_ops = &ipw_ethtool_ops;
7949 net_dev->irq = pdev->irq; 8433 net_dev->irq = pdev->irq;
@@ -7960,12 +8444,12 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7960 err = register_netdev(net_dev); 8444 err = register_netdev(net_dev);
7961 if (err) { 8445 if (err) {
7962 IPW_ERROR("failed to register network device\n"); 8446 IPW_ERROR("failed to register network device\n");
7963 goto out_remove_group; 8447 goto out_remove_sysfs;
7964 } 8448 }
7965 8449
7966 return 0; 8450 return 0;
7967 8451
7968 out_remove_group: 8452 out_remove_sysfs:
7969 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group); 8453 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
7970 out_release_irq: 8454 out_release_irq:
7971 free_irq(pdev->irq, priv); 8455 free_irq(pdev->irq, priv);
@@ -8005,17 +8489,17 @@ static void ipw_pci_remove(struct pci_dev *pdev)
8005 } 8489 }
8006 ipw_tx_queue_free(priv); 8490 ipw_tx_queue_free(priv);
8007 8491
8492 ipw_led_shutdown(priv);
8493
8008 /* ipw_down will ensure that there is no more pending work 8494 /* ipw_down will ensure that there is no more pending work
8009 * in the workqueue's, so we can safely remove them now. */ 8495 * in the workqueue's, so we can safely remove them now. */
8010 if (priv->workqueue) { 8496 cancel_delayed_work(&priv->adhoc_check);
8011 cancel_delayed_work(&priv->adhoc_check); 8497 cancel_delayed_work(&priv->gather_stats);
8012 cancel_delayed_work(&priv->gather_stats); 8498 cancel_delayed_work(&priv->request_scan);
8013 cancel_delayed_work(&priv->request_scan); 8499 cancel_delayed_work(&priv->rf_kill);
8014 cancel_delayed_work(&priv->rf_kill); 8500 cancel_delayed_work(&priv->scan_check);
8015 cancel_delayed_work(&priv->scan_check); 8501 destroy_workqueue(priv->workqueue);
8016 destroy_workqueue(priv->workqueue); 8502 priv->workqueue = NULL;
8017 priv->workqueue = NULL;
8018 }
8019 8503
8020 free_irq(pdev->irq, priv); 8504 free_irq(pdev->irq, priv);
8021 iounmap(priv->hw_base); 8505 iounmap(priv->hw_base);
@@ -8138,6 +8622,10 @@ MODULE_PARM_DESC(associate, "auto associate when scanning (default on)");
8138module_param(auto_create, int, 0444); 8622module_param(auto_create, int, 0444);
8139MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)"); 8623MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
8140 8624
8625module_param(led, int, 0444);
8626MODULE_PARM_DESC(auto_create,
8627 "enable led control on some systems (default 0 off)\n");
8628
8141module_param(debug, int, 0444); 8629module_param(debug, int, 0444);
8142MODULE_PARM_DESC(debug, "debug output mask"); 8630MODULE_PARM_DESC(debug, "debug output mask");
8143 8631
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 068027963181..1b339cb7a522 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -403,9 +403,9 @@ struct clx2_tx_queue {
403#define RX_FREE_BUFFERS 32 403#define RX_FREE_BUFFERS 32
404#define RX_LOW_WATERMARK 8 404#define RX_LOW_WATERMARK 8
405 405
406#define SUP_RATE_11A_MAX_NUM_CHANNELS (8) 406#define SUP_RATE_11A_MAX_NUM_CHANNELS 8
407#define SUP_RATE_11B_MAX_NUM_CHANNELS (4) 407#define SUP_RATE_11B_MAX_NUM_CHANNELS 4
408#define SUP_RATE_11G_MAX_NUM_CHANNELS (12) 408#define SUP_RATE_11G_MAX_NUM_CHANNELS 12
409 409
410// Used for passing to driver number of successes and failures per rate 410// Used for passing to driver number of successes and failures per rate
411struct rate_histogram { 411struct rate_histogram {
@@ -890,6 +890,9 @@ struct ipw_cmd {
890#define STATUS_SCANNING (1<<21) 890#define STATUS_SCANNING (1<<21)
891#define STATUS_SCAN_ABORTING (1<<22) 891#define STATUS_SCAN_ABORTING (1<<22)
892 892
893#define STATUS_LED_LINK_ON (1<<24)
894#define STATUS_LED_ACT_ON (1<<25)
895
893#define STATUS_INDIRECT_BYTE (1<<28) /* sysfs entry configured for access */ 896#define STATUS_INDIRECT_BYTE (1<<28) /* sysfs entry configured for access */
894#define STATUS_INDIRECT_DWORD (1<<29) /* sysfs entry configured for access */ 897#define STATUS_INDIRECT_DWORD (1<<29) /* sysfs entry configured for access */
895#define STATUS_DIRECT_DWORD (1<<30) /* sysfs entry configured for access */ 898#define STATUS_DIRECT_DWORD (1<<30) /* sysfs entry configured for access */
@@ -905,6 +908,8 @@ struct ipw_cmd {
905#define CFG_ASSOCIATE (1<<6) 908#define CFG_ASSOCIATE (1<<6)
906#define CFG_FIXED_RATE (1<<7) 909#define CFG_FIXED_RATE (1<<7)
907#define CFG_ADHOC_CREATE (1<<8) 910#define CFG_ADHOC_CREATE (1<<8)
911#define CFG_NO_LED (1<<9)
912#define CFG_BACKGROUND_SCAN (1<<10)
908 913
909#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */ 914#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */
910#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */ 915#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */
@@ -1046,9 +1051,24 @@ struct ipw_priv {
1046 struct work_struct abort_scan; 1051 struct work_struct abort_scan;
1047 struct work_struct roam; 1052 struct work_struct roam;
1048 struct work_struct scan_check; 1053 struct work_struct scan_check;
1054 struct work_struct link_up;
1055 struct work_struct link_down;
1049 1056
1050 struct tasklet_struct irq_tasklet; 1057 struct tasklet_struct irq_tasklet;
1051 1058
1059 /* LED related variables and work_struct */
1060 u8 nic_type;
1061 u32 led_activity_on;
1062 u32 led_activity_off;
1063 u32 led_association_on;
1064 u32 led_association_off;
1065 u32 led_ofdm_on;
1066 u32 led_ofdm_off;
1067
1068 struct work_struct led_link_on;
1069 struct work_struct led_link_off;
1070 struct work_struct led_act_off;
1071
1052#define IPW_2200BG 1 1072#define IPW_2200BG 1
1053#define IPW_2915ABG 2 1073#define IPW_2915ABG 2
1054 u8 adapter; 1074 u8 adapter;
@@ -1126,6 +1146,8 @@ do { if (ipw_debug_level & (level)) \
1126#define IPW_DL_RF_KILL (1<<17) 1146#define IPW_DL_RF_KILL (1<<17)
1127#define IPW_DL_FW_ERRORS (1<<18) 1147#define IPW_DL_FW_ERRORS (1<<18)
1128 1148
1149#define IPW_DL_LED (1<<19)
1150
1129#define IPW_DL_ORD (1<<20) 1151#define IPW_DL_ORD (1<<20)
1130 1152
1131#define IPW_DL_FRAG (1<<21) 1153#define IPW_DL_FRAG (1<<21)
@@ -1151,6 +1173,7 @@ do { if (ipw_debug_level & (level)) \
1151#define IPW_DEBUG_TX(f, a...) IPW_DEBUG(IPW_DL_TX, f, ## a) 1173#define IPW_DEBUG_TX(f, a...) IPW_DEBUG(IPW_DL_TX, f, ## a)
1152#define IPW_DEBUG_ISR(f, a...) IPW_DEBUG(IPW_DL_ISR, f, ## a) 1174#define IPW_DEBUG_ISR(f, a...) IPW_DEBUG(IPW_DL_ISR, f, ## a)
1153#define IPW_DEBUG_MANAGEMENT(f, a...) IPW_DEBUG(IPW_DL_MANAGE, f, ## a) 1175#define IPW_DEBUG_MANAGEMENT(f, a...) IPW_DEBUG(IPW_DL_MANAGE, f, ## a)
1176#define IPW_DEBUG_LED(f, a...) IPW_DEBUG(IPW_DL_LED, f, ## a)
1154#define IPW_DEBUG_WEP(f, a...) IPW_DEBUG(IPW_DL_WEP, f, ## a) 1177#define IPW_DEBUG_WEP(f, a...) IPW_DEBUG(IPW_DL_WEP, f, ## a)
1155#define IPW_DEBUG_HC(f, a...) IPW_DEBUG(IPW_DL_HOST_COMMAND, f, ## a) 1178#define IPW_DEBUG_HC(f, a...) IPW_DEBUG(IPW_DL_HOST_COMMAND, f, ## a)
1156#define IPW_DEBUG_FRAG(f, a...) IPW_DEBUG(IPW_DL_FRAG, f, ## a) 1179#define IPW_DEBUG_FRAG(f, a...) IPW_DEBUG(IPW_DL_FRAG, f, ## a)
@@ -1268,25 +1291,25 @@ do { if (ipw_debug_level & (level)) \
1268#define CX2_DMA_I_DMA_CONTROL 0x003000A4 1291#define CX2_DMA_I_DMA_CONTROL 0x003000A4
1269#define CX2_DMA_I_CB_BASE 0x003000A0 1292#define CX2_DMA_I_CB_BASE 0x003000A0
1270 1293
1271#define CX2_TX_CMD_QUEUE_BD_BASE (0x00000200) 1294#define CX2_TX_CMD_QUEUE_BD_BASE 0x00000200
1272#define CX2_TX_CMD_QUEUE_BD_SIZE (0x00000204) 1295#define CX2_TX_CMD_QUEUE_BD_SIZE 0x00000204
1273#define CX2_TX_QUEUE_0_BD_BASE (0x00000208) 1296#define CX2_TX_QUEUE_0_BD_BASE 0x00000208
1274#define CX2_TX_QUEUE_0_BD_SIZE (0x0000020C) 1297#define CX2_TX_QUEUE_0_BD_SIZE (0x0000020C)
1275#define CX2_TX_QUEUE_1_BD_BASE (0x00000210) 1298#define CX2_TX_QUEUE_1_BD_BASE 0x00000210
1276#define CX2_TX_QUEUE_1_BD_SIZE (0x00000214) 1299#define CX2_TX_QUEUE_1_BD_SIZE 0x00000214
1277#define CX2_TX_QUEUE_2_BD_BASE (0x00000218) 1300#define CX2_TX_QUEUE_2_BD_BASE 0x00000218
1278#define CX2_TX_QUEUE_2_BD_SIZE (0x0000021C) 1301#define CX2_TX_QUEUE_2_BD_SIZE (0x0000021C)
1279#define CX2_TX_QUEUE_3_BD_BASE (0x00000220) 1302#define CX2_TX_QUEUE_3_BD_BASE 0x00000220
1280#define CX2_TX_QUEUE_3_BD_SIZE (0x00000224) 1303#define CX2_TX_QUEUE_3_BD_SIZE 0x00000224
1281#define CX2_RX_BD_BASE (0x00000240) 1304#define CX2_RX_BD_BASE 0x00000240
1282#define CX2_RX_BD_SIZE (0x00000244) 1305#define CX2_RX_BD_SIZE 0x00000244
1283#define CX2_RFDS_TABLE_LOWER (0x00000500) 1306#define CX2_RFDS_TABLE_LOWER 0x00000500
1284 1307
1285#define CX2_TX_CMD_QUEUE_READ_INDEX (0x00000280) 1308#define CX2_TX_CMD_QUEUE_READ_INDEX 0x00000280
1286#define CX2_TX_QUEUE_0_READ_INDEX (0x00000284) 1309#define CX2_TX_QUEUE_0_READ_INDEX 0x00000284
1287#define CX2_TX_QUEUE_1_READ_INDEX (0x00000288) 1310#define CX2_TX_QUEUE_1_READ_INDEX 0x00000288
1288#define CX2_TX_QUEUE_2_READ_INDEX (0x0000028C) 1311#define CX2_TX_QUEUE_2_READ_INDEX (0x0000028C)
1289#define CX2_TX_QUEUE_3_READ_INDEX (0x00000290) 1312#define CX2_TX_QUEUE_3_READ_INDEX 0x00000290
1290#define CX2_RX_READ_INDEX (0x000002A0) 1313#define CX2_RX_READ_INDEX (0x000002A0)
1291 1314
1292#define CX2_TX_CMD_QUEUE_WRITE_INDEX (0x00000F80) 1315#define CX2_TX_CMD_QUEUE_WRITE_INDEX (0x00000F80)
@@ -1333,15 +1356,15 @@ do { if (ipw_debug_level & (level)) \
1333#define EEPROM_HW_VERSION (GET_EEPROM_ADDR(0x72,LSB)) /* 2 bytes */ 1356#define EEPROM_HW_VERSION (GET_EEPROM_ADDR(0x72,LSB)) /* 2 bytes */
1334 1357
1335/* NIC type as found in the one byte EEPROM_NIC_TYPE offset*/ 1358/* NIC type as found in the one byte EEPROM_NIC_TYPE offset*/
1336#define EEPROM_NIC_TYPE_STANDARD 0 1359#define EEPROM_NIC_TYPE_0 0
1337#define EEPROM_NIC_TYPE_DELL 1 1360#define EEPROM_NIC_TYPE_1 1
1338#define EEPROM_NIC_TYPE_FUJITSU 2 1361#define EEPROM_NIC_TYPE_2 2
1339#define EEPROM_NIC_TYPE_IBM 3 1362#define EEPROM_NIC_TYPE_3 3
1340#define EEPROM_NIC_TYPE_HP 4 1363#define EEPROM_NIC_TYPE_4 4
1341 1364
1342#define FW_MEM_REG_LOWER_BOUND 0x00300000 1365#define FW_MEM_REG_LOWER_BOUND 0x00300000
1343#define FW_MEM_REG_EEPROM_ACCESS (FW_MEM_REG_LOWER_BOUND + 0x40) 1366#define FW_MEM_REG_EEPROM_ACCESS (FW_MEM_REG_LOWER_BOUND + 0x40)
1344 1367#define CX2_EVENT_REG (FW_MEM_REG_LOWER_BOUND + 0x04)
1345#define EEPROM_BIT_SK (1<<0) 1368#define EEPROM_BIT_SK (1<<0)
1346#define EEPROM_BIT_CS (1<<1) 1369#define EEPROM_BIT_CS (1<<1)
1347#define EEPROM_BIT_DI (1<<2) 1370#define EEPROM_BIT_DI (1<<2)