diff options
| author | Mohamed Abbas <mabbas@linux.intel.com> | 2008-03-28 19:21:06 -0400 |
|---|---|---|
| committer | John W. Linville <linville@tuxdriver.com> | 2008-04-01 17:13:18 -0400 |
| commit | ad97edd2f524940d524c26ae273a4eb23067a7c0 (patch) | |
| tree | 7d7af2310ec45dd70dfe17b1723fc66b9228d5cc | |
| parent | c8381fdcab98b74f670d879097bab35d97d88400 (diff) | |
iwlwifi: hook iwlwifi with Linux rfkill
This patch hook IWL with Linux rfkill.
Signed-off-by: Mohamed Abbas <mabbas@linux.intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
| -rw-r--r-- | drivers/net/wireless/iwlwifi/Kconfig | 6 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/Makefile | 4 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 1 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.h | 5 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 4 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 1 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-rfkill.c | 174 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-rfkill.h | 56 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/iwl4965-base.c | 54 |
9 files changed, 271 insertions, 34 deletions
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index c26ca749fc1e..4a5c8c0d007d 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
| @@ -9,6 +9,12 @@ config IWLWIFI_LEDS | |||
| 9 | This option enables LEDS for the iwlwifi drivers | 9 | This option enables LEDS for the iwlwifi drivers |
| 10 | 10 | ||
| 11 | 11 | ||
| 12 | config IWLCORE_RFKILL | ||
| 13 | boolean "IWLWIFI RF kill support" | ||
| 14 | depends on IWLCORE | ||
| 15 | select RFKILL | ||
| 16 | select RFKILL_INPUT | ||
| 17 | |||
| 12 | config IWL4965 | 18 | config IWL4965 |
| 13 | tristate "Intel Wireless WiFi 4965AGN" | 19 | tristate "Intel Wireless WiFi 4965AGN" |
| 14 | depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL | 20 | depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL |
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 64fca4d9ac76..2751e8aa97d7 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile | |||
| @@ -9,6 +9,10 @@ ifeq ($(CONFIG_IWLWIFI_LEDS),y) | |||
| 9 | iwlcore-objs += iwl-led.o | 9 | iwlcore-objs += iwl-led.o |
| 10 | endif | 10 | endif |
| 11 | 11 | ||
| 12 | ifeq ($(CONFIG_IWLCORE_RFKILL),y) | ||
| 13 | iwlcore-objs += iwl-rfkill.o | ||
| 14 | endif | ||
| 15 | |||
| 12 | obj-$(CONFIG_IWL3945) += iwl3945.o | 16 | obj-$(CONFIG_IWL3945) += iwl3945.o |
| 13 | iwl3945-objs = iwl3945-base.o iwl-3945.o iwl-3945-rs.o | 17 | iwl3945-objs = iwl3945-base.o iwl-3945.o iwl-3945-rs.o |
| 14 | 18 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index e5f64d7fbfde..3ab5d8292502 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
| @@ -4961,6 +4961,7 @@ static struct iwl_lib_ops iwl4965_lib = { | |||
| 4961 | .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, | 4961 | .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, |
| 4962 | .release_semaphore = iwlcore_eeprom_release_semaphore, | 4962 | .release_semaphore = iwlcore_eeprom_release_semaphore, |
| 4963 | }, | 4963 | }, |
| 4964 | .radio_kill_sw = iwl4965_radio_kill_sw, | ||
| 4964 | }; | 4965 | }; |
| 4965 | 4966 | ||
| 4966 | static struct iwl_ops iwl4965_ops = { | 4967 | static struct iwl_ops iwl4965_ops = { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h index 069e591981b2..ca864fa65ca4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965.h | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | extern struct pci_device_id iwl4965_hw_card_ids[]; | 40 | extern struct pci_device_id iwl4965_hw_card_ids[]; |
| 41 | 41 | ||
| 42 | #define DRV_NAME "iwl4965" | 42 | #define DRV_NAME "iwl4965" |
| 43 | #include "iwl-rfkill.h" | ||
| 43 | #include "iwl-eeprom.h" | 44 | #include "iwl-eeprom.h" |
| 44 | #include "iwl-4965-hw.h" | 45 | #include "iwl-4965-hw.h" |
| 45 | #include "iwl-csr.h" | 46 | #include "iwl-csr.h" |
| @@ -739,6 +740,7 @@ extern int iwl4965_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index | |||
| 739 | extern int iwl4965_queue_space(const struct iwl4965_queue *q); | 740 | extern int iwl4965_queue_space(const struct iwl4965_queue *q); |
| 740 | struct iwl_priv; | 741 | struct iwl_priv; |
| 741 | 742 | ||
| 743 | extern void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio); | ||
| 742 | /* | 744 | /* |
| 743 | * Forward declare iwl-4965.c functions for iwl-base.c | 745 | * Forward declare iwl-4965.c functions for iwl-base.c |
| 744 | */ | 746 | */ |
| @@ -1050,6 +1052,9 @@ struct iwl_priv { | |||
| 1050 | * 4965's initialize alive response contains some calibration data. */ | 1052 | * 4965's initialize alive response contains some calibration data. */ |
| 1051 | struct iwl4965_init_alive_resp card_alive_init; | 1053 | struct iwl4965_init_alive_resp card_alive_init; |
| 1052 | struct iwl4965_alive_resp card_alive; | 1054 | struct iwl4965_alive_resp card_alive; |
| 1055 | #ifdef CONFIG_IWLCORE_RFKILL | ||
| 1056 | struct iwl_rfkill_mngr rfkill_mngr; | ||
| 1057 | #endif | ||
| 1053 | 1058 | ||
| 1054 | #ifdef CONFIG_IWL4965_LEDS | 1059 | #ifdef CONFIG_IWL4965_LEDS |
| 1055 | struct iwl4965_led led[IWL_LED_TRG_MAX]; | 1060 | struct iwl4965_led led[IWL_LED_TRG_MAX]; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 342a269b8abb..49fb52f07354 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
| @@ -35,6 +35,7 @@ struct iwl_priv; /* FIXME: remove */ | |||
| 35 | #include "iwl-debug.h" | 35 | #include "iwl-debug.h" |
| 36 | #include "iwl-eeprom.h" | 36 | #include "iwl-eeprom.h" |
| 37 | #include "iwl-core.h" | 37 | #include "iwl-core.h" |
| 38 | #include "iwl-rfkill.h" | ||
| 38 | 39 | ||
| 39 | #include "iwl-4965.h" /* FIXME: remove */ | 40 | #include "iwl-4965.h" /* FIXME: remove */ |
| 40 | 41 | ||
| @@ -257,12 +258,15 @@ int iwlcore_low_level_notify(struct iwl_priv *priv, | |||
| 257 | { | 258 | { |
| 258 | switch (notify) { | 259 | switch (notify) { |
| 259 | case IWLCORE_INIT_EVT: | 260 | case IWLCORE_INIT_EVT: |
| 261 | iwl_rfkill_init(priv); | ||
| 260 | break; | 262 | break; |
| 261 | case IWLCORE_START_EVT: | 263 | case IWLCORE_START_EVT: |
| 262 | break; | 264 | break; |
| 263 | case IWLCORE_STOP_EVT: | 265 | case IWLCORE_STOP_EVT: |
| 264 | break; | 266 | break; |
| 265 | case IWLCORE_REMOVE_EVT: | 267 | case IWLCORE_REMOVE_EVT: |
| 268 | iwl_rfkill_unregister(priv); | ||
| 269 | iwl_rfkill_free(priv); | ||
| 266 | break; | 270 | break; |
| 267 | } | 271 | } |
| 268 | 272 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 4dfa05948d73..5efafe1a1d86 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
| @@ -91,6 +91,7 @@ struct iwl_lib_ops { | |||
| 91 | int (*init_drv)(struct iwl_priv *priv); | 91 | int (*init_drv)(struct iwl_priv *priv); |
| 92 | /* eeprom operations (as defined in iwl-eeprom.h) */ | 92 | /* eeprom operations (as defined in iwl-eeprom.h) */ |
| 93 | struct iwl_eeprom_ops eeprom_ops; | 93 | struct iwl_eeprom_ops eeprom_ops; |
| 94 | void (*radio_kill_sw)(struct iwl_priv *priv, int disable_radio); | ||
| 94 | }; | 95 | }; |
| 95 | 96 | ||
| 96 | struct iwl_ops { | 97 | struct iwl_ops { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c new file mode 100644 index 000000000000..66abf52e8987 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.c | |||
| @@ -0,0 +1,174 @@ | |||
| 1 | /****************************************************************************** | ||
| 2 | * | ||
| 3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | ||
| 4 | * | ||
| 5 | * Portions of this file are derived from the ipw3945 project, as well | ||
| 6 | * as portions of the ieee80211 subsystem header files. | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of version 2 of the GNU General Public License as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
| 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 15 | * more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License along with | ||
| 18 | * this program; if not, write to the Free Software Foundation, Inc., | ||
| 19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
| 20 | * | ||
| 21 | * The full GNU General Public License is included in this distribution in the | ||
| 22 | * file called LICENSE. | ||
| 23 | * | ||
| 24 | * Contact Information: | ||
| 25 | * James P. Ketrenos <ipw2100-admin@linux.intel.com> | ||
| 26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
| 27 | *****************************************************************************/ | ||
| 28 | #include <linux/kernel.h> | ||
| 29 | #include <linux/module.h> | ||
| 30 | #include <linux/version.h> | ||
| 31 | #include <linux/init.h> | ||
| 32 | |||
| 33 | #include <net/mac80211.h> | ||
| 34 | |||
| 35 | #include "iwl-eeprom.h" | ||
| 36 | #include "iwl-core.h" | ||
| 37 | #include "iwl-4965.h" | ||
| 38 | #include "iwl-helpers.h" | ||
| 39 | |||
| 40 | |||
| 41 | static inline int iwl_is_rfkill(struct iwl_priv *priv) | ||
| 42 | { | ||
| 43 | return test_bit(STATUS_RF_KILL_HW, &priv->status) || | ||
| 44 | test_bit(STATUS_RF_KILL_SW, &priv->status); | ||
| 45 | } | ||
| 46 | |||
| 47 | |||
| 48 | /* software rf-kill from user */ | ||
| 49 | static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state) | ||
| 50 | { | ||
| 51 | struct iwl_priv *priv = data; | ||
| 52 | int err = 0; | ||
| 53 | |||
| 54 | if (!priv->rfkill_mngr.rfkill) | ||
| 55 | return 0; | ||
| 56 | |||
| 57 | IWL_DEBUG_RF_KILL("we recieved soft RFKILL set to state %d\n", state); | ||
| 58 | mutex_lock(&priv->mutex); | ||
| 59 | |||
| 60 | switch (state) { | ||
| 61 | case RFKILL_STATE_ON: | ||
| 62 | priv->cfg->ops->lib->radio_kill_sw(priv, 0); | ||
| 63 | /* if HW rf-kill is set dont allow ON state */ | ||
| 64 | if (iwl_is_rfkill(priv)) | ||
| 65 | err = -EBUSY; | ||
| 66 | break; | ||
| 67 | case RFKILL_STATE_OFF: | ||
| 68 | priv->cfg->ops->lib->radio_kill_sw(priv, 1); | ||
| 69 | if (!iwl_is_rfkill(priv)) | ||
| 70 | err = -EBUSY; | ||
| 71 | break; | ||
| 72 | } | ||
| 73 | mutex_unlock(&priv->mutex); | ||
| 74 | |||
| 75 | return err; | ||
| 76 | } | ||
| 77 | |||
| 78 | int iwl_rfkill_init(struct iwl_priv *priv) | ||
| 79 | { | ||
| 80 | struct device *device = wiphy_dev(priv->hw->wiphy); | ||
| 81 | int ret = 0; | ||
| 82 | |||
| 83 | BUG_ON(device == NULL); | ||
| 84 | |||
| 85 | priv->rfkill_mngr.rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN); | ||
| 86 | if (!priv->rfkill_mngr.rfkill) { | ||
| 87 | ret = -ENOMEM; | ||
| 88 | goto error; | ||
| 89 | } | ||
| 90 | |||
| 91 | priv->rfkill_mngr.rfkill->name = priv->cfg->name; | ||
| 92 | priv->rfkill_mngr.rfkill->data = priv; | ||
| 93 | priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON; | ||
| 94 | priv->rfkill_mngr.rfkill->toggle_radio = iwl_rfkill_soft_rf_kill; | ||
| 95 | priv->rfkill_mngr.rfkill->user_claim_unsupported = 1; | ||
| 96 | |||
| 97 | priv->rfkill_mngr.rfkill->dev.class->suspend = NULL; | ||
| 98 | priv->rfkill_mngr.rfkill->dev.class->resume = NULL; | ||
| 99 | |||
| 100 | priv->rfkill_mngr.input_dev = input_allocate_device(); | ||
| 101 | if (!priv->rfkill_mngr.input_dev) { | ||
| 102 | ret = -ENOMEM; | ||
| 103 | goto freed_rfkill; | ||
| 104 | } | ||
| 105 | |||
| 106 | priv->rfkill_mngr.input_dev->name = priv->cfg->name; | ||
| 107 | priv->rfkill_mngr.input_dev->phys = wiphy_name(priv->hw->wiphy); | ||
| 108 | priv->rfkill_mngr.input_dev->id.bustype = BUS_HOST; | ||
| 109 | priv->rfkill_mngr.input_dev->id.vendor = priv->pci_dev->vendor; | ||
| 110 | priv->rfkill_mngr.input_dev->dev.parent = device; | ||
| 111 | priv->rfkill_mngr.input_dev->evbit[0] = BIT(EV_KEY); | ||
| 112 | set_bit(KEY_WLAN, priv->rfkill_mngr.input_dev->keybit); | ||
| 113 | |||
| 114 | ret = rfkill_register(priv->rfkill_mngr.rfkill); | ||
| 115 | if (ret) | ||
| 116 | goto free_input_dev; | ||
| 117 | |||
| 118 | ret = input_register_device(priv->rfkill_mngr.input_dev); | ||
| 119 | if (ret) | ||
| 120 | goto unregister_rfkill; | ||
| 121 | |||
| 122 | return ret; | ||
| 123 | |||
| 124 | unregister_rfkill: | ||
| 125 | rfkill_unregister(priv->rfkill_mngr.rfkill); | ||
| 126 | |||
| 127 | free_input_dev: | ||
| 128 | input_free_device(priv->rfkill_mngr.input_dev); | ||
| 129 | priv->rfkill_mngr.input_dev = NULL; | ||
| 130 | |||
| 131 | freed_rfkill: | ||
| 132 | rfkill_free(priv->rfkill_mngr.rfkill); | ||
| 133 | priv->rfkill_mngr.rfkill = NULL; | ||
| 134 | |||
| 135 | error: | ||
| 136 | return ret; | ||
| 137 | } | ||
| 138 | EXPORT_SYMBOL(iwl_rfkill_init); | ||
| 139 | |||
| 140 | void iwl_rfkill_unregister(struct iwl_priv *priv) | ||
| 141 | { | ||
| 142 | |||
| 143 | if (priv->rfkill_mngr.input_dev) | ||
| 144 | input_unregister_device(priv->rfkill_mngr.input_dev); | ||
| 145 | |||
| 146 | if (priv->rfkill_mngr.rfkill) | ||
| 147 | rfkill_unregister(priv->rfkill_mngr.rfkill); | ||
| 148 | } | ||
| 149 | EXPORT_SYMBOL(iwl_rfkill_unregister); | ||
| 150 | |||
| 151 | |||
| 152 | void iwl_rfkill_free(struct iwl_priv *priv) | ||
| 153 | { | ||
| 154 | if (priv->rfkill_mngr.input_dev) | ||
| 155 | input_free_device(priv->rfkill_mngr.input_dev); | ||
| 156 | |||
| 157 | if (priv->rfkill_mngr.rfkill) | ||
| 158 | rfkill_free(priv->rfkill_mngr.rfkill); | ||
| 159 | } | ||
| 160 | EXPORT_SYMBOL(iwl_rfkill_free); | ||
| 161 | |||
| 162 | /* set rf-kill to the right state. */ | ||
| 163 | void iwl_rfkill_set_hw_state(struct iwl_priv *priv) | ||
| 164 | { | ||
| 165 | |||
| 166 | if (!priv->rfkill_mngr.rfkill) | ||
| 167 | return; | ||
| 168 | |||
| 169 | if (!iwl_is_rfkill(priv)) | ||
| 170 | priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON; | ||
| 171 | else | ||
| 172 | priv->rfkill_mngr.rfkill->state = RFKILL_STATE_OFF; | ||
| 173 | } | ||
| 174 | EXPORT_SYMBOL(iwl_rfkill_set_hw_state); | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.h b/drivers/net/wireless/iwlwifi/iwl-rfkill.h new file mode 100644 index 000000000000..a5cbc5ab45d9 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.h | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | /****************************************************************************** | ||
| 2 | * | ||
| 3 | * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved. | ||
| 4 | * | ||
| 5 | * Portions of this file are derived from the ipw3945 project, as well | ||
| 6 | * as portions of the ieee80211 subsystem header files. | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of version 2 of the GNU General Public License as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
| 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 15 | * more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License along with | ||
| 18 | * this program; if not, write to the Free Software Foundation, Inc., | ||
| 19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
| 20 | * | ||
| 21 | * The full GNU General Public License is included in this distribution in the | ||
| 22 | * file called LICENSE. | ||
| 23 | * | ||
| 24 | * Contact Information: | ||
| 25 | * James P. Ketrenos <ipw2100-admin@linux.intel.com> | ||
| 26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
| 27 | *****************************************************************************/ | ||
| 28 | #ifndef __iwl_rf_kill_h__ | ||
| 29 | #define __iwl_rf_kill_h__ | ||
| 30 | |||
| 31 | struct iwl_priv; | ||
| 32 | |||
| 33 | #include <linux/rfkill.h> | ||
| 34 | #include <linux/input.h> | ||
| 35 | |||
| 36 | |||
| 37 | #ifdef CONFIG_IWLCORE_RFKILL | ||
| 38 | struct iwl_rfkill_mngr { | ||
| 39 | struct rfkill *rfkill; | ||
| 40 | struct input_dev *input_dev; | ||
| 41 | }; | ||
| 42 | |||
| 43 | void iwl_rfkill_set_hw_state(struct iwl_priv *priv); | ||
| 44 | void iwl_rfkill_free(struct iwl_priv *priv); | ||
| 45 | void iwl_rfkill_unregister(struct iwl_priv *priv); | ||
| 46 | int iwl_rfkill_init(struct iwl_priv *priv); | ||
| 47 | #else | ||
| 48 | static inline void iwl_rfkill_set_hw_state(struct iwl_priv *priv) {} | ||
| 49 | static inline void iwl_rfkill_free(struct iwl_priv *priv) {} | ||
| 50 | static inline void iwl_rfkill_unregister(struct iwl_priv *priv) {} | ||
| 51 | static inline int iwl_rfkill_init(struct iwl_priv *priv) { return 0; } | ||
| 52 | #endif | ||
| 53 | |||
| 54 | |||
| 55 | |||
| 56 | #endif /* __iwl_rf_kill_h__ */ | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 5261b6179a86..7f56565b4002 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
| @@ -2607,7 +2607,7 @@ static void iwl4965_set_rate(struct iwl_priv *priv) | |||
| 2607 | (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; | 2607 | (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; |
| 2608 | } | 2608 | } |
| 2609 | 2609 | ||
| 2610 | static void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio) | 2610 | void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio) |
| 2611 | { | 2611 | { |
| 2612 | unsigned long flags; | 2612 | unsigned long flags; |
| 2613 | 2613 | ||
| @@ -2625,8 +2625,16 @@ static void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio) | |||
| 2625 | iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, | 2625 | iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, |
| 2626 | CSR_UCODE_SW_BIT_RFKILL); | 2626 | CSR_UCODE_SW_BIT_RFKILL); |
| 2627 | spin_unlock_irqrestore(&priv->lock, flags); | 2627 | spin_unlock_irqrestore(&priv->lock, flags); |
| 2628 | iwl4965_send_card_state(priv, CARD_STATE_CMD_DISABLE, 0); | 2628 | /* call the host command only if no hw rf-kill set */ |
| 2629 | if (!test_bit(STATUS_RF_KILL_HW, &priv->status)) | ||
| 2630 | iwl4965_send_card_state(priv, | ||
| 2631 | CARD_STATE_CMD_DISABLE, | ||
| 2632 | 0); | ||
| 2629 | set_bit(STATUS_RF_KILL_SW, &priv->status); | 2633 | set_bit(STATUS_RF_KILL_SW, &priv->status); |
| 2634 | |||
| 2635 | /* make sure mac80211 stop sending Tx frame */ | ||
| 2636 | if (priv->mac80211_registered) | ||
| 2637 | ieee80211_stop_queues(priv->hw); | ||
| 2630 | } | 2638 | } |
| 2631 | return; | 2639 | return; |
| 2632 | } | 2640 | } |
| @@ -5852,6 +5860,7 @@ static int __iwl4965_up(struct iwl_priv *priv) | |||
| 5852 | if (test_bit(STATUS_RF_KILL_SW, &priv->status)) { | 5860 | if (test_bit(STATUS_RF_KILL_SW, &priv->status)) { |
| 5853 | IWL_WARNING("Radio disabled by SW RF kill (module " | 5861 | IWL_WARNING("Radio disabled by SW RF kill (module " |
| 5854 | "parameter)\n"); | 5862 | "parameter)\n"); |
| 5863 | iwl_rfkill_set_hw_state(priv); | ||
| 5855 | return -ENODEV; | 5864 | return -ENODEV; |
| 5856 | } | 5865 | } |
| 5857 | 5866 | ||
| @@ -5867,11 +5876,13 @@ static int __iwl4965_up(struct iwl_priv *priv) | |||
| 5867 | else { | 5876 | else { |
| 5868 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 5877 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
| 5869 | if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) { | 5878 | if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) { |
| 5879 | iwl_rfkill_set_hw_state(priv); | ||
| 5870 | IWL_WARNING("Radio disabled by HW RF Kill switch\n"); | 5880 | IWL_WARNING("Radio disabled by HW RF Kill switch\n"); |
| 5871 | return -ENODEV; | 5881 | return -ENODEV; |
| 5872 | } | 5882 | } |
| 5873 | } | 5883 | } |
| 5874 | 5884 | ||
| 5885 | iwl_rfkill_set_hw_state(priv); | ||
| 5875 | iwl_write32(priv, CSR_INT, 0xFFFFFFFF); | 5886 | iwl_write32(priv, CSR_INT, 0xFFFFFFFF); |
| 5876 | 5887 | ||
| 5877 | rc = iwl4965_hw_nic_init(priv); | 5888 | rc = iwl4965_hw_nic_init(priv); |
| @@ -5985,6 +5996,9 @@ static void iwl4965_bg_rf_kill(struct work_struct *work) | |||
| 5985 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) | 5996 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) |
| 5986 | queue_work(priv->workqueue, &priv->restart); | 5997 | queue_work(priv->workqueue, &priv->restart); |
| 5987 | } else { | 5998 | } else { |
| 5999 | /* make sure mac80211 stop sending Tx frame */ | ||
| 6000 | if (priv->mac80211_registered) | ||
| 6001 | ieee80211_stop_queues(priv->hw); | ||
| 5988 | 6002 | ||
| 5989 | if (!test_bit(STATUS_RF_KILL_HW, &priv->status)) | 6003 | if (!test_bit(STATUS_RF_KILL_HW, &priv->status)) |
| 5990 | IWL_DEBUG_RF_KILL("Can not turn radio back on - " | 6004 | IWL_DEBUG_RF_KILL("Can not turn radio back on - " |
| @@ -5994,6 +6008,8 @@ static void iwl4965_bg_rf_kill(struct work_struct *work) | |||
| 5994 | "Kill switch must be turned off for " | 6008 | "Kill switch must be turned off for " |
| 5995 | "wireless networking to work.\n"); | 6009 | "wireless networking to work.\n"); |
| 5996 | } | 6010 | } |
| 6011 | iwl_rfkill_set_hw_state(priv); | ||
| 6012 | |||
| 5997 | mutex_unlock(&priv->mutex); | 6013 | mutex_unlock(&priv->mutex); |
| 5998 | } | 6014 | } |
| 5999 | 6015 | ||
| @@ -6674,7 +6690,8 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
| 6674 | } | 6690 | } |
| 6675 | #endif | 6691 | #endif |
| 6676 | 6692 | ||
| 6677 | iwl4965_radio_kill_sw(priv, !conf->radio_enabled); | 6693 | if (priv->cfg->ops->lib->radio_kill_sw) |
| 6694 | priv->cfg->ops->lib->radio_kill_sw(priv, !conf->radio_enabled); | ||
| 6678 | 6695 | ||
| 6679 | if (!conf->radio_enabled) { | 6696 | if (!conf->radio_enabled) { |
| 6680 | IWL_DEBUG_MAC80211("leave - radio disabled\n"); | 6697 | IWL_DEBUG_MAC80211("leave - radio disabled\n"); |
| @@ -7449,36 +7466,6 @@ static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, | |||
| 7449 | 7466 | ||
| 7450 | #endif /* CONFIG_IWLWIFI_DEBUG */ | 7467 | #endif /* CONFIG_IWLWIFI_DEBUG */ |
| 7451 | 7468 | ||
| 7452 | static ssize_t show_rf_kill(struct device *d, | ||
| 7453 | struct device_attribute *attr, char *buf) | ||
| 7454 | { | ||
| 7455 | /* | ||
| 7456 | * 0 - RF kill not enabled | ||
| 7457 | * 1 - SW based RF kill active (sysfs) | ||
| 7458 | * 2 - HW based RF kill active | ||
| 7459 | * 3 - Both HW and SW based RF kill active | ||
| 7460 | */ | ||
| 7461 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; | ||
| 7462 | int val = (test_bit(STATUS_RF_KILL_SW, &priv->status) ? 0x1 : 0x0) | | ||
| 7463 | (test_bit(STATUS_RF_KILL_HW, &priv->status) ? 0x2 : 0x0); | ||
| 7464 | |||
| 7465 | return sprintf(buf, "%i\n", val); | ||
| 7466 | } | ||
| 7467 | |||
| 7468 | static ssize_t store_rf_kill(struct device *d, | ||
| 7469 | struct device_attribute *attr, | ||
| 7470 | const char *buf, size_t count) | ||
| 7471 | { | ||
| 7472 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; | ||
| 7473 | |||
| 7474 | mutex_lock(&priv->mutex); | ||
| 7475 | iwl4965_radio_kill_sw(priv, buf[0] == '1'); | ||
| 7476 | mutex_unlock(&priv->mutex); | ||
| 7477 | |||
| 7478 | return count; | ||
| 7479 | } | ||
| 7480 | |||
| 7481 | static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill); | ||
| 7482 | 7469 | ||
| 7483 | static ssize_t show_temperature(struct device *d, | 7470 | static ssize_t show_temperature(struct device *d, |
| 7484 | struct device_attribute *attr, char *buf) | 7471 | struct device_attribute *attr, char *buf) |
| @@ -7964,7 +7951,6 @@ static struct attribute *iwl4965_sysfs_entries[] = { | |||
| 7964 | #endif | 7951 | #endif |
| 7965 | &dev_attr_power_level.attr, | 7952 | &dev_attr_power_level.attr, |
| 7966 | &dev_attr_retry_rate.attr, | 7953 | &dev_attr_retry_rate.attr, |
| 7967 | &dev_attr_rf_kill.attr, | ||
| 7968 | &dev_attr_rs_window.attr, | 7954 | &dev_attr_rs_window.attr, |
| 7969 | &dev_attr_statistics.attr, | 7955 | &dev_attr_statistics.attr, |
| 7970 | &dev_attr_status.attr, | 7956 | &dev_attr_status.attr, |
