aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAdel Gadllah <adel.gadllah@gmail.com>2008-07-01 11:49:50 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-07-08 10:21:35 -0400
commit80fcc9e28cf3a209fbfb39a7bbddc313c59c7424 (patch)
treefe77fdd591652db82a87bff12d4b1528a1ecdfe4 /drivers
parentebd74487d4b7a48ab8513ecfe3d321346d7c602e (diff)
iwlwifi: remove input device and fix rfkill state
This patch fixes the iwlwifi rfkill. It removes the input device from iwl3945, adds support for RFKILL_STATE_HARD_BLOCKED and calls rfkill_force_state() to update the state rather than accessing it directly. The calls to iwl|iwl3945_rfkill_set_hw_state() had to be moved because rfkill_force_state() cannot be called from an atomic context. Tested on iwl3945 and seems to work fine. Cc: Randy Dunlap <randy.dunlap@oracle.com> Cc: Ivo van Doorn <ivdoorn@gmail.com> Cc: Fabien Crespel <fcrespel@gmail.com> Cc: Zhu Yi <yi.zhu@intel.com> Cc: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Signed-off-by: Adel Gadllah <adel.gadllah@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rfkill.c57
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rfkill.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c117
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c8
8 files changed, 105 insertions, 111 deletions
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index b628a44057f7..82b66a3d3a5d 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -104,6 +104,7 @@ config IWL3945
104 select IWLWIFI 104 select IWLWIFI
105 select MAC80211_LEDS if IWL3945_LEDS 105 select MAC80211_LEDS if IWL3945_LEDS
106 select LEDS_CLASS if IWL3945_LEDS 106 select LEDS_CLASS if IWL3945_LEDS
107 select RFKILL if IWL3945_RFKILL
107 ---help--- 108 ---help---
108 Select to build the driver supporting the: 109 Select to build the driver supporting the:
109 110
@@ -126,6 +127,10 @@ config IWL3945
126 say M here and read <file:Documentation/kbuild/modules.txt>. The 127 say M here and read <file:Documentation/kbuild/modules.txt>. The
127 module will be called iwl3945.ko. 128 module will be called iwl3945.ko.
128 129
130config IWL3945_RFKILL
131 bool "Enable RF kill support in iwl3945 drivers"
132 depends on IWL3945
133
129config IWL3945_SPECTRUM_MEASUREMENT 134config IWL3945_SPECTRUM_MEASUREMENT
130 bool "Enable Spectrum Measurement in iwl3945 drivers" 135 bool "Enable Spectrum Measurement in iwl3945 drivers"
131 depends on IWL3945 136 depends on IWL3945
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index a77497809d97..9c0a09eaca6f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -690,14 +690,9 @@ enum {
690 690
691#endif 691#endif
692 692
693#ifdef CONFIG_IWLWIFI_RFKILL 693#ifdef CONFIG_IWL3945_RFKILL
694struct iwl3945_priv; 694struct iwl3945_priv;
695 695
696struct iwl3945_rfkill_mngr {
697 struct rfkill *rfkill;
698 struct input_dev *input_dev;
699};
700
701void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv); 696void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv);
702void iwl3945_rfkill_unregister(struct iwl3945_priv *priv); 697void iwl3945_rfkill_unregister(struct iwl3945_priv *priv);
703int iwl3945_rfkill_init(struct iwl3945_priv *priv); 698int iwl3945_rfkill_init(struct iwl3945_priv *priv);
@@ -800,8 +795,8 @@ struct iwl3945_priv {
800 struct iwl3945_init_alive_resp card_alive_init; 795 struct iwl3945_init_alive_resp card_alive_init;
801 struct iwl3945_alive_resp card_alive; 796 struct iwl3945_alive_resp card_alive;
802 797
803#ifdef CONFIG_IWLWIFI_RFKILL 798#ifdef CONFIG_IWL3945_RFKILL
804 struct iwl3945_rfkill_mngr rfkill_mngr; 799 struct rfkill *rfkill;
805#endif 800#endif
806 801
807#ifdef CONFIG_IWL3945_LEDS 802#ifdef CONFIG_IWL3945_LEDS
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index eb4abe1ebbdb..dafd62c7dfd6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -356,10 +356,19 @@ static inline int iwl_is_init(struct iwl_priv *priv)
356 return test_bit(STATUS_INIT, &priv->status); 356 return test_bit(STATUS_INIT, &priv->status);
357} 357}
358 358
359static inline int iwl_is_rfkill_sw(struct iwl_priv *priv)
360{
361 return test_bit(STATUS_RF_KILL_SW, &priv->status);
362}
363
364static inline int iwl_is_rfkill_hw(struct iwl_priv *priv)
365{
366 return test_bit(STATUS_RF_KILL_HW, &priv->status);
367}
368
359static inline int iwl_is_rfkill(struct iwl_priv *priv) 369static inline int iwl_is_rfkill(struct iwl_priv *priv)
360{ 370{
361 return test_bit(STATUS_RF_KILL_HW, &priv->status) || 371 return iwl_is_rfkill_hw(priv) || iwl_is_rfkill_sw(priv);
362 test_bit(STATUS_RF_KILL_SW, &priv->status);
363} 372}
364 373
365static inline int iwl_is_ready_rf(struct iwl_priv *priv) 374static inline int iwl_is_ready_rf(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index d1289cfc213c..70e10ea35a51 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -929,7 +929,7 @@ struct iwl_priv {
929 struct iwl_init_alive_resp card_alive_init; 929 struct iwl_init_alive_resp card_alive_init;
930 struct iwl_alive_resp card_alive; 930 struct iwl_alive_resp card_alive;
931#ifdef CONFIG_IWLWIFI_RFKILL 931#ifdef CONFIG_IWLWIFI_RFKILL
932 struct iwl_rfkill_mngr rfkill_mngr; 932 struct rfkill *rfkill;
933#endif 933#endif
934 934
935#ifdef CONFIG_IWLWIFI_LEDS 935#ifdef CONFIG_IWLWIFI_LEDS
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c
index eebaf43f66b2..e5e5846e9f25 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.c
@@ -44,7 +44,7 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
44 struct iwl_priv *priv = data; 44 struct iwl_priv *priv = data;
45 int err = 0; 45 int err = 0;
46 46
47 if (!priv->rfkill_mngr.rfkill) 47 if (!priv->rfkill)
48 return 0; 48 return 0;
49 49
50 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 50 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -55,20 +55,20 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
55 55
56 switch (state) { 56 switch (state) {
57 case RFKILL_STATE_UNBLOCKED: 57 case RFKILL_STATE_UNBLOCKED:
58 iwl_radio_kill_sw_enable_radio(priv); 58 if (iwl_is_rfkill_hw(priv)) {
59 /* if HW rf-kill is set dont allow ON state */
60 if (iwl_is_rfkill(priv))
61 err = -EBUSY; 59 err = -EBUSY;
60 goto out_unlock;
61 }
62 iwl_radio_kill_sw_enable_radio(priv);
62 break; 63 break;
63 case RFKILL_STATE_SOFT_BLOCKED: 64 case RFKILL_STATE_SOFT_BLOCKED:
64 iwl_radio_kill_sw_disable_radio(priv); 65 iwl_radio_kill_sw_disable_radio(priv);
65 if (!iwl_is_rfkill(priv))
66 err = -EBUSY;
67 break; 66 break;
68 default: 67 default:
69 IWL_WARNING("we recieved unexpected RFKILL state %d\n", state); 68 IWL_WARNING("we recieved unexpected RFKILL state %d\n", state);
70 break; 69 break;
71 } 70 }
71out_unlock:
72 mutex_unlock(&priv->mutex); 72 mutex_unlock(&priv->mutex);
73 73
74 return err; 74 return err;
@@ -82,23 +82,23 @@ int iwl_rfkill_init(struct iwl_priv *priv)
82 BUG_ON(device == NULL); 82 BUG_ON(device == NULL);
83 83
84 IWL_DEBUG_RF_KILL("Initializing RFKILL.\n"); 84 IWL_DEBUG_RF_KILL("Initializing RFKILL.\n");
85 priv->rfkill_mngr.rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN); 85 priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
86 if (!priv->rfkill_mngr.rfkill) { 86 if (!priv->rfkill) {
87 IWL_ERROR("Unable to allocate rfkill device.\n"); 87 IWL_ERROR("Unable to allocate rfkill device.\n");
88 ret = -ENOMEM; 88 ret = -ENOMEM;
89 goto error; 89 goto error;
90 } 90 }
91 91
92 priv->rfkill_mngr.rfkill->name = priv->cfg->name; 92 priv->rfkill->name = priv->cfg->name;
93 priv->rfkill_mngr.rfkill->data = priv; 93 priv->rfkill->data = priv;
94 priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON; 94 priv->rfkill->state = RFKILL_STATE_UNBLOCKED;
95 priv->rfkill_mngr.rfkill->toggle_radio = iwl_rfkill_soft_rf_kill; 95 priv->rfkill->toggle_radio = iwl_rfkill_soft_rf_kill;
96 priv->rfkill_mngr.rfkill->user_claim_unsupported = 1; 96 priv->rfkill->user_claim_unsupported = 1;
97 97
98 priv->rfkill_mngr.rfkill->dev.class->suspend = NULL; 98 priv->rfkill->dev.class->suspend = NULL;
99 priv->rfkill_mngr.rfkill->dev.class->resume = NULL; 99 priv->rfkill->dev.class->resume = NULL;
100 100
101 ret = rfkill_register(priv->rfkill_mngr.rfkill); 101 ret = rfkill_register(priv->rfkill);
102 if (ret) { 102 if (ret) {
103 IWL_ERROR("Unable to register rfkill: %d\n", ret); 103 IWL_ERROR("Unable to register rfkill: %d\n", ret);
104 goto free_rfkill; 104 goto free_rfkill;
@@ -108,9 +108,9 @@ int iwl_rfkill_init(struct iwl_priv *priv)
108 return ret; 108 return ret;
109 109
110free_rfkill: 110free_rfkill:
111 if (priv->rfkill_mngr.rfkill != NULL) 111 if (priv->rfkill != NULL)
112 rfkill_free(priv->rfkill_mngr.rfkill); 112 rfkill_free(priv->rfkill);
113 priv->rfkill_mngr.rfkill = NULL; 113 priv->rfkill = NULL;
114 114
115error: 115error:
116 IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n"); 116 IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
@@ -121,22 +121,27 @@ EXPORT_SYMBOL(iwl_rfkill_init);
121void iwl_rfkill_unregister(struct iwl_priv *priv) 121void iwl_rfkill_unregister(struct iwl_priv *priv)
122{ 122{
123 123
124 if (priv->rfkill_mngr.rfkill) 124 if (priv->rfkill)
125 rfkill_unregister(priv->rfkill_mngr.rfkill); 125 rfkill_unregister(priv->rfkill);
126 126
127 priv->rfkill_mngr.rfkill = NULL; 127 priv->rfkill = NULL;
128} 128}
129EXPORT_SYMBOL(iwl_rfkill_unregister); 129EXPORT_SYMBOL(iwl_rfkill_unregister);
130 130
131/* set rf-kill to the right state. */ 131/* set rf-kill to the right state. */
132void iwl_rfkill_set_hw_state(struct iwl_priv *priv) 132void iwl_rfkill_set_hw_state(struct iwl_priv *priv)
133{ 133{
134 if (!priv->rfkill_mngr.rfkill) 134 if (!priv->rfkill)
135 return; 135 return;
136 136
137 if (!iwl_is_rfkill(priv)) 137 if (iwl_is_rfkill_hw(priv)) {
138 priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON; 138 rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED);
139 return;
140 }
141
142 if (!iwl_is_rfkill_sw(priv))
143 rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED);
139 else 144 else
140 priv->rfkill_mngr.rfkill->state = RFKILL_STATE_OFF; 145 rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED);
141} 146}
142EXPORT_SYMBOL(iwl_rfkill_set_hw_state); 147EXPORT_SYMBOL(iwl_rfkill_set_hw_state);
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.h b/drivers/net/wireless/iwlwifi/iwl-rfkill.h
index 00692d2e9bd8..402fd4c781da 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rfkill.h
+++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.h
@@ -33,9 +33,6 @@ struct iwl_priv;
33#include <linux/rfkill.h> 33#include <linux/rfkill.h>
34 34
35#ifdef CONFIG_IWLWIFI_RFKILL 35#ifdef CONFIG_IWLWIFI_RFKILL
36struct iwl_rfkill_mngr {
37 struct rfkill *rfkill;
38};
39 36
40void iwl_rfkill_set_hw_state(struct iwl_priv *priv); 37void iwl_rfkill_set_hw_state(struct iwl_priv *priv);
41void iwl_rfkill_unregister(struct iwl_priv *priv); 38void iwl_rfkill_unregister(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index baa1abd5a14d..1a7d18fea89d 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -537,10 +537,20 @@ static inline int iwl3945_is_init(struct iwl3945_priv *priv)
537 return test_bit(STATUS_INIT, &priv->status); 537 return test_bit(STATUS_INIT, &priv->status);
538} 538}
539 539
540static inline int iwl3945_is_rfkill_sw(struct iwl3945_priv *priv)
541{
542 return test_bit(STATUS_RF_KILL_SW, &priv->status);
543}
544
545static inline int iwl3945_is_rfkill_hw(struct iwl3945_priv *priv)
546{
547 return test_bit(STATUS_RF_KILL_HW, &priv->status);
548}
549
540static inline int iwl3945_is_rfkill(struct iwl3945_priv *priv) 550static inline int iwl3945_is_rfkill(struct iwl3945_priv *priv)
541{ 551{
542 return test_bit(STATUS_RF_KILL_HW, &priv->status) || 552 return iwl3945_is_rfkill_hw(priv) ||
543 test_bit(STATUS_RF_KILL_SW, &priv->status); 553 iwl3945_is_rfkill_sw(priv);
544} 554}
545 555
546static inline int iwl3945_is_ready_rf(struct iwl3945_priv *priv) 556static inline int iwl3945_is_ready_rf(struct iwl3945_priv *priv)
@@ -6013,12 +6023,11 @@ static int __iwl3945_up(struct iwl3945_priv *priv)
6013 else { 6023 else {
6014 set_bit(STATUS_RF_KILL_HW, &priv->status); 6024 set_bit(STATUS_RF_KILL_HW, &priv->status);
6015 if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) { 6025 if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) {
6016 iwl3945_rfkill_set_hw_state(priv);
6017 IWL_WARNING("Radio disabled by HW RF Kill switch\n"); 6026 IWL_WARNING("Radio disabled by HW RF Kill switch\n");
6018 return -ENODEV; 6027 return -ENODEV;
6019 } 6028 }
6020 } 6029 }
6021 iwl3945_rfkill_set_hw_state(priv); 6030
6022 iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF); 6031 iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF);
6023 6032
6024 rc = iwl3945_hw_nic_init(priv); 6033 rc = iwl3945_hw_nic_init(priv);
@@ -6143,8 +6152,8 @@ static void iwl3945_bg_rf_kill(struct work_struct *work)
6143 "wireless networking to work.\n"); 6152 "wireless networking to work.\n");
6144 } 6153 }
6145 6154
6146 iwl3945_rfkill_set_hw_state(priv);
6147 mutex_unlock(&priv->mutex); 6155 mutex_unlock(&priv->mutex);
6156 iwl3945_rfkill_set_hw_state(priv);
6148} 6157}
6149 6158
6150static void iwl3945_bg_set_monitor(struct work_struct *work) 6159static void iwl3945_bg_set_monitor(struct work_struct *work)
@@ -6398,6 +6407,7 @@ static void iwl3945_bg_up(struct work_struct *data)
6398 mutex_lock(&priv->mutex); 6407 mutex_lock(&priv->mutex);
6399 __iwl3945_up(priv); 6408 __iwl3945_up(priv);
6400 mutex_unlock(&priv->mutex); 6409 mutex_unlock(&priv->mutex);
6410 iwl3945_rfkill_set_hw_state(priv);
6401} 6411}
6402 6412
6403static void iwl3945_bg_restart(struct work_struct *data) 6413static void iwl3945_bg_restart(struct work_struct *data)
@@ -6618,6 +6628,8 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw)
6618 6628
6619 mutex_unlock(&priv->mutex); 6629 mutex_unlock(&priv->mutex);
6620 6630
6631 iwl3945_rfkill_set_hw_state(priv);
6632
6621 if (ret) 6633 if (ret)
6622 goto out_release_irq; 6634 goto out_release_irq;
6623 6635
@@ -8276,14 +8288,14 @@ static int iwl3945_pci_resume(struct pci_dev *pdev)
8276#endif /* CONFIG_PM */ 8288#endif /* CONFIG_PM */
8277 8289
8278/*************** RFKILL FUNCTIONS **********/ 8290/*************** RFKILL FUNCTIONS **********/
8279#ifdef CONFIG_IWLWIFI_RFKILL 8291#ifdef CONFIG_IWL3945_RFKILL
8280/* software rf-kill from user */ 8292/* software rf-kill from user */
8281static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state) 8293static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
8282{ 8294{
8283 struct iwl3945_priv *priv = data; 8295 struct iwl3945_priv *priv = data;
8284 int err = 0; 8296 int err = 0;
8285 8297
8286 if (!priv->rfkill_mngr.rfkill) 8298 if (!priv->rfkill)
8287 return 0; 8299 return 0;
8288 8300
8289 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 8301 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -8294,20 +8306,20 @@ static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
8294 8306
8295 switch (state) { 8307 switch (state) {
8296 case RFKILL_STATE_UNBLOCKED: 8308 case RFKILL_STATE_UNBLOCKED:
8297 iwl3945_radio_kill_sw(priv, 0); 8309 if (iwl3945_is_rfkill_hw(priv)) {
8298 /* if HW rf-kill is set dont allow ON state */
8299 if (iwl3945_is_rfkill(priv))
8300 err = -EBUSY; 8310 err = -EBUSY;
8311 goto out_unlock;
8312 }
8313 iwl3945_radio_kill_sw(priv, 0);
8301 break; 8314 break;
8302 case RFKILL_STATE_SOFT_BLOCKED: 8315 case RFKILL_STATE_SOFT_BLOCKED:
8303 iwl3945_radio_kill_sw(priv, 1); 8316 iwl3945_radio_kill_sw(priv, 1);
8304 if (!iwl3945_is_rfkill(priv))
8305 err = -EBUSY;
8306 break; 8317 break;
8307 default: 8318 default:
8308 IWL_WARNING("we recieved unexpected RFKILL state %d\n", state); 8319 IWL_WARNING("we recieved unexpected RFKILL state %d\n", state);
8309 break; 8320 break;
8310 } 8321 }
8322out_unlock:
8311 mutex_unlock(&priv->mutex); 8323 mutex_unlock(&priv->mutex);
8312 8324
8313 return err; 8325 return err;
@@ -8321,64 +8333,35 @@ int iwl3945_rfkill_init(struct iwl3945_priv *priv)
8321 BUG_ON(device == NULL); 8333 BUG_ON(device == NULL);
8322 8334
8323 IWL_DEBUG_RF_KILL("Initializing RFKILL.\n"); 8335 IWL_DEBUG_RF_KILL("Initializing RFKILL.\n");
8324 priv->rfkill_mngr.rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN); 8336 priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
8325 if (!priv->rfkill_mngr.rfkill) { 8337 if (!priv->rfkill) {
8326 IWL_ERROR("Unable to allocate rfkill device.\n"); 8338 IWL_ERROR("Unable to allocate rfkill device.\n");
8327 ret = -ENOMEM; 8339 ret = -ENOMEM;
8328 goto error; 8340 goto error;
8329 } 8341 }
8330 8342
8331 priv->rfkill_mngr.rfkill->name = priv->cfg->name; 8343 priv->rfkill->name = priv->cfg->name;
8332 priv->rfkill_mngr.rfkill->data = priv; 8344 priv->rfkill->data = priv;
8333 priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON; 8345 priv->rfkill->state = RFKILL_STATE_UNBLOCKED;
8334 priv->rfkill_mngr.rfkill->toggle_radio = iwl3945_rfkill_soft_rf_kill; 8346 priv->rfkill->toggle_radio = iwl3945_rfkill_soft_rf_kill;
8335 priv->rfkill_mngr.rfkill->user_claim_unsupported = 1; 8347 priv->rfkill->user_claim_unsupported = 1;
8336
8337 priv->rfkill_mngr.rfkill->dev.class->suspend = NULL;
8338 priv->rfkill_mngr.rfkill->dev.class->resume = NULL;
8339 8348
8340 priv->rfkill_mngr.input_dev = input_allocate_device(); 8349 priv->rfkill->dev.class->suspend = NULL;
8341 if (!priv->rfkill_mngr.input_dev) { 8350 priv->rfkill->dev.class->resume = NULL;
8342 IWL_ERROR("Unable to allocate rfkill input device.\n");
8343 ret = -ENOMEM;
8344 goto freed_rfkill;
8345 }
8346 8351
8347 priv->rfkill_mngr.input_dev->name = priv->cfg->name; 8352 ret = rfkill_register(priv->rfkill);
8348 priv->rfkill_mngr.input_dev->phys = wiphy_name(priv->hw->wiphy);
8349 priv->rfkill_mngr.input_dev->id.bustype = BUS_HOST;
8350 priv->rfkill_mngr.input_dev->id.vendor = priv->pci_dev->vendor;
8351 priv->rfkill_mngr.input_dev->dev.parent = device;
8352 priv->rfkill_mngr.input_dev->evbit[0] = BIT(EV_KEY);
8353 set_bit(KEY_WLAN, priv->rfkill_mngr.input_dev->keybit);
8354
8355 ret = rfkill_register(priv->rfkill_mngr.rfkill);
8356 if (ret) { 8353 if (ret) {
8357 IWL_ERROR("Unable to register rfkill: %d\n", ret); 8354 IWL_ERROR("Unable to register rfkill: %d\n", ret);
8358 goto free_input_dev; 8355 goto freed_rfkill;
8359 }
8360
8361 ret = input_register_device(priv->rfkill_mngr.input_dev);
8362 if (ret) {
8363 IWL_ERROR("Unable to register rfkill input device: %d\n", ret);
8364 goto unregister_rfkill;
8365 } 8356 }
8366 8357
8367 IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n"); 8358 IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
8368 return ret; 8359 return ret;
8369 8360
8370unregister_rfkill:
8371 rfkill_unregister(priv->rfkill_mngr.rfkill);
8372 priv->rfkill_mngr.rfkill = NULL;
8373
8374free_input_dev:
8375 input_free_device(priv->rfkill_mngr.input_dev);
8376 priv->rfkill_mngr.input_dev = NULL;
8377
8378freed_rfkill: 8361freed_rfkill:
8379 if (priv->rfkill_mngr.rfkill != NULL) 8362 if (priv->rfkill != NULL)
8380 rfkill_free(priv->rfkill_mngr.rfkill); 8363 rfkill_free(priv->rfkill);
8381 priv->rfkill_mngr.rfkill = NULL; 8364 priv->rfkill = NULL;
8382 8365
8383error: 8366error:
8384 IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n"); 8367 IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
@@ -8387,28 +8370,28 @@ error:
8387 8370
8388void iwl3945_rfkill_unregister(struct iwl3945_priv *priv) 8371void iwl3945_rfkill_unregister(struct iwl3945_priv *priv)
8389{ 8372{
8373 if (priv->rfkill)
8374 rfkill_unregister(priv->rfkill);
8390 8375
8391 if (priv->rfkill_mngr.input_dev) 8376 priv->rfkill = NULL;
8392 input_unregister_device(priv->rfkill_mngr.input_dev);
8393
8394 if (priv->rfkill_mngr.rfkill)
8395 rfkill_unregister(priv->rfkill_mngr.rfkill);
8396
8397 priv->rfkill_mngr.input_dev = NULL;
8398 priv->rfkill_mngr.rfkill = NULL;
8399} 8377}
8400 8378
8401/* set rf-kill to the right state. */ 8379/* set rf-kill to the right state. */
8402void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv) 8380void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv)
8403{ 8381{
8404 8382
8405 if (!priv->rfkill_mngr.rfkill) 8383 if (!priv->rfkill)
8384 return;
8385
8386 if (iwl3945_is_rfkill_hw(priv)) {
8387 rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED);
8406 return; 8388 return;
8389 }
8407 8390
8408 if (!iwl3945_is_rfkill(priv)) 8391 if (!iwl3945_is_rfkill_sw(priv))
8409 priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON; 8392 rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED);
8410 else 8393 else
8411 priv->rfkill_mngr.rfkill->state = RFKILL_STATE_OFF; 8394 rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED);
8412} 8395}
8413#endif 8396#endif
8414 8397
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 60b7a6498fe8..7f65d9123b2a 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -2187,13 +2187,11 @@ static int __iwl4965_up(struct iwl_priv *priv)
2187 2187
2188 if (!test_bit(STATUS_IN_SUSPEND, &priv->status) && 2188 if (!test_bit(STATUS_IN_SUSPEND, &priv->status) &&
2189 iwl_is_rfkill(priv)) { 2189 iwl_is_rfkill(priv)) {
2190 iwl_rfkill_set_hw_state(priv);
2191 IWL_WARNING("Radio disabled by %s RF Kill switch\n", 2190 IWL_WARNING("Radio disabled by %s RF Kill switch\n",
2192 test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW"); 2191 test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW");
2193 return -ENODEV; 2192 return -ENODEV;
2194 } 2193 }
2195 2194
2196 iwl_rfkill_set_hw_state(priv);
2197 iwl_write32(priv, CSR_INT, 0xFFFFFFFF); 2195 iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
2198 2196
2199 ret = priv->cfg->ops->lib->alloc_shared_mem(priv); 2197 ret = priv->cfg->ops->lib->alloc_shared_mem(priv);
@@ -2330,9 +2328,8 @@ static void iwl4965_bg_rf_kill(struct work_struct *work)
2330 "Kill switch must be turned off for " 2328 "Kill switch must be turned off for "
2331 "wireless networking to work.\n"); 2329 "wireless networking to work.\n");
2332 } 2330 }
2333 iwl_rfkill_set_hw_state(priv);
2334
2335 mutex_unlock(&priv->mutex); 2331 mutex_unlock(&priv->mutex);
2332 iwl_rfkill_set_hw_state(priv);
2336} 2333}
2337 2334
2338static void iwl4965_bg_set_monitor(struct work_struct *work) 2335static void iwl4965_bg_set_monitor(struct work_struct *work)
@@ -2390,6 +2387,7 @@ static void iwl4965_bg_up(struct work_struct *data)
2390 mutex_lock(&priv->mutex); 2387 mutex_lock(&priv->mutex);
2391 __iwl4965_up(priv); 2388 __iwl4965_up(priv);
2392 mutex_unlock(&priv->mutex); 2389 mutex_unlock(&priv->mutex);
2390 iwl_rfkill_set_hw_state(priv);
2393} 2391}
2394 2392
2395static void iwl4965_bg_restart(struct work_struct *data) 2393static void iwl4965_bg_restart(struct work_struct *data)
@@ -2604,6 +2602,8 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
2604 2602
2605 mutex_unlock(&priv->mutex); 2603 mutex_unlock(&priv->mutex);
2606 2604
2605 iwl_rfkill_set_hw_state(priv);
2606
2607 if (ret) 2607 if (ret)
2608 goto out_release_irq; 2608 goto out_release_irq;
2609 2609