diff options
author | David S. Miller <davem@davemloft.net> | 2008-07-06 00:41:53 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-07-06 00:41:53 -0400 |
commit | f3032be921cd126615ce3bfd7084e3d319f3f892 (patch) | |
tree | c2ce874f2ab7f107dddf7b854772e0f3b64d35a1 /drivers/net/wireless/iwlwifi/iwl3945-base.c | |
parent | 70c03b49b80ba3634958acc31853771019c0ebd3 (diff) | |
parent | 18d7260527ce7c0d0a177afdf92d8f868f50b067 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl3945-base.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 245 |
1 files changed, 176 insertions, 69 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 92d1b2e312d4..3bc2644039f0 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -970,7 +970,7 @@ static int iwl3945_full_rxon_required(struct iwl3945_priv *priv) | |||
970 | { | 970 | { |
971 | 971 | ||
972 | /* These items are only settable from the full RXON command */ | 972 | /* These items are only settable from the full RXON command */ |
973 | if (!(priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) || | 973 | if (!(iwl3945_is_associated(priv)) || |
974 | compare_ether_addr(priv->staging_rxon.bssid_addr, | 974 | compare_ether_addr(priv->staging_rxon.bssid_addr, |
975 | priv->active_rxon.bssid_addr) || | 975 | priv->active_rxon.bssid_addr) || |
976 | compare_ether_addr(priv->staging_rxon.node_addr, | 976 | compare_ether_addr(priv->staging_rxon.node_addr, |
@@ -2312,7 +2312,7 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv) | |||
2312 | #endif | 2312 | #endif |
2313 | 2313 | ||
2314 | ch_info = iwl3945_get_channel_info(priv, priv->band, | 2314 | ch_info = iwl3945_get_channel_info(priv, priv->band, |
2315 | le16_to_cpu(priv->staging_rxon.channel)); | 2315 | le16_to_cpu(priv->active_rxon.channel)); |
2316 | 2316 | ||
2317 | if (!ch_info) | 2317 | if (!ch_info) |
2318 | ch_info = &priv->channel_info[0]; | 2318 | ch_info = &priv->channel_info[0]; |
@@ -2539,6 +2539,11 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h | |||
2539 | iwl3945_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); | 2539 | iwl3945_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); |
2540 | return priv->hw_setting.bcast_sta_id; | 2540 | return priv->hw_setting.bcast_sta_id; |
2541 | } | 2541 | } |
2542 | /* If we are in monitor mode, use BCAST. This is required for | ||
2543 | * packet injection. */ | ||
2544 | case IEEE80211_IF_TYPE_MNTR: | ||
2545 | return priv->hw_setting.bcast_sta_id; | ||
2546 | |||
2542 | default: | 2547 | default: |
2543 | IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode); | 2548 | IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode); |
2544 | return priv->hw_setting.bcast_sta_id; | 2549 | return priv->hw_setting.bcast_sta_id; |
@@ -2578,11 +2583,6 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) | |||
2578 | goto drop_unlock; | 2583 | goto drop_unlock; |
2579 | } | 2584 | } |
2580 | 2585 | ||
2581 | if (!priv->vif) { | ||
2582 | IWL_DEBUG_DROP("Dropping - !priv->vif\n"); | ||
2583 | goto drop_unlock; | ||
2584 | } | ||
2585 | |||
2586 | if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == IWL_INVALID_RATE) { | 2586 | if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == IWL_INVALID_RATE) { |
2587 | IWL_ERROR("ERROR: No TX rate available.\n"); | 2587 | IWL_ERROR("ERROR: No TX rate available.\n"); |
2588 | goto drop_unlock; | 2588 | goto drop_unlock; |
@@ -2603,9 +2603,10 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) | |||
2603 | #endif | 2603 | #endif |
2604 | 2604 | ||
2605 | /* drop all data frame if we are not associated */ | 2605 | /* drop all data frame if we are not associated */ |
2606 | if ((!iwl3945_is_associated(priv) || | 2606 | if (ieee80211_is_data(fc) && |
2607 | ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id)) && | 2607 | (priv->iw_mode != IEEE80211_IF_TYPE_MNTR) && /* packet injection */ |
2608 | ieee80211_is_data(fc)) { | 2608 | (!iwl3945_is_associated(priv) || |
2609 | ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id))) { | ||
2609 | IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n"); | 2610 | IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n"); |
2610 | goto drop_unlock; | 2611 | goto drop_unlock; |
2611 | } | 2612 | } |
@@ -5921,7 +5922,9 @@ static void __iwl3945_down(struct iwl3945_priv *priv) | |||
5921 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | 5922 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
5922 | STATUS_GEO_CONFIGURED | | 5923 | STATUS_GEO_CONFIGURED | |
5923 | test_bit(STATUS_IN_SUSPEND, &priv->status) << | 5924 | test_bit(STATUS_IN_SUSPEND, &priv->status) << |
5924 | STATUS_IN_SUSPEND; | 5925 | STATUS_IN_SUSPEND | |
5926 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | ||
5927 | STATUS_EXIT_PENDING; | ||
5925 | goto exit; | 5928 | goto exit; |
5926 | } | 5929 | } |
5927 | 5930 | ||
@@ -5936,7 +5939,9 @@ static void __iwl3945_down(struct iwl3945_priv *priv) | |||
5936 | test_bit(STATUS_IN_SUSPEND, &priv->status) << | 5939 | test_bit(STATUS_IN_SUSPEND, &priv->status) << |
5937 | STATUS_IN_SUSPEND | | 5940 | STATUS_IN_SUSPEND | |
5938 | test_bit(STATUS_FW_ERROR, &priv->status) << | 5941 | test_bit(STATUS_FW_ERROR, &priv->status) << |
5939 | STATUS_FW_ERROR; | 5942 | STATUS_FW_ERROR | |
5943 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | ||
5944 | STATUS_EXIT_PENDING; | ||
5940 | 5945 | ||
5941 | spin_lock_irqsave(&priv->lock, flags); | 5946 | spin_lock_irqsave(&priv->lock, flags); |
5942 | iwl3945_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 5947 | iwl3945_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
@@ -6008,11 +6013,12 @@ static int __iwl3945_up(struct iwl3945_priv *priv) | |||
6008 | else { | 6013 | else { |
6009 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 6014 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
6010 | if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) { | 6015 | if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) { |
6016 | iwl3945_rfkill_set_hw_state(priv); | ||
6011 | IWL_WARNING("Radio disabled by HW RF Kill switch\n"); | 6017 | IWL_WARNING("Radio disabled by HW RF Kill switch\n"); |
6012 | return -ENODEV; | 6018 | return -ENODEV; |
6013 | } | 6019 | } |
6014 | } | 6020 | } |
6015 | 6021 | iwl3945_rfkill_set_hw_state(priv); | |
6016 | iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF); | 6022 | iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF); |
6017 | 6023 | ||
6018 | rc = iwl3945_hw_nic_init(priv); | 6024 | rc = iwl3945_hw_nic_init(priv); |
@@ -6068,6 +6074,7 @@ static int __iwl3945_up(struct iwl3945_priv *priv) | |||
6068 | 6074 | ||
6069 | set_bit(STATUS_EXIT_PENDING, &priv->status); | 6075 | set_bit(STATUS_EXIT_PENDING, &priv->status); |
6070 | __iwl3945_down(priv); | 6076 | __iwl3945_down(priv); |
6077 | clear_bit(STATUS_EXIT_PENDING, &priv->status); | ||
6071 | 6078 | ||
6072 | /* tried to restart and config the device for as long as our | 6079 | /* tried to restart and config the device for as long as our |
6073 | * patience could withstand */ | 6080 | * patience could withstand */ |
@@ -6135,6 +6142,8 @@ static void iwl3945_bg_rf_kill(struct work_struct *work) | |||
6135 | "Kill switch must be turned off for " | 6142 | "Kill switch must be turned off for " |
6136 | "wireless networking to work.\n"); | 6143 | "wireless networking to work.\n"); |
6137 | } | 6144 | } |
6145 | |||
6146 | iwl3945_rfkill_set_hw_state(priv); | ||
6138 | mutex_unlock(&priv->mutex); | 6147 | mutex_unlock(&priv->mutex); |
6139 | } | 6148 | } |
6140 | 6149 | ||
@@ -6685,11 +6694,6 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
6685 | 6694 | ||
6686 | IWL_DEBUG_MAC80211("enter\n"); | 6695 | IWL_DEBUG_MAC80211("enter\n"); |
6687 | 6696 | ||
6688 | if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) { | ||
6689 | IWL_DEBUG_MAC80211("leave - monitor\n"); | ||
6690 | return -1; | ||
6691 | } | ||
6692 | |||
6693 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, | 6697 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, |
6694 | ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); | 6698 | ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); |
6695 | 6699 | ||
@@ -6836,7 +6840,7 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv) | |||
6836 | return; | 6840 | return; |
6837 | 6841 | ||
6838 | /* The following should be done only at AP bring up */ | 6842 | /* The following should be done only at AP bring up */ |
6839 | if ((priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) == 0) { | 6843 | if (!(iwl3945_is_associated(priv))) { |
6840 | 6844 | ||
6841 | /* RXON - unassoc (to set timing command) */ | 6845 | /* RXON - unassoc (to set timing command) */ |
6842 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 6846 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
@@ -6998,26 +7002,18 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw, | |||
6998 | unsigned int *total_flags, | 7002 | unsigned int *total_flags, |
6999 | int mc_count, struct dev_addr_list *mc_list) | 7003 | int mc_count, struct dev_addr_list *mc_list) |
7000 | { | 7004 | { |
7001 | /* | ||
7002 | * XXX: dummy | ||
7003 | * see also iwl3945_connection_init_rx_config | ||
7004 | */ | ||
7005 | struct iwl3945_priv *priv = hw->priv; | 7005 | struct iwl3945_priv *priv = hw->priv; |
7006 | int new_flags = 0; | 7006 | |
7007 | if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { | 7007 | if (changed_flags & (*total_flags) & FIF_OTHER_BSS) { |
7008 | if (*total_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { | 7008 | IWL_DEBUG_MAC80211("Enter: type %d (0x%x, 0x%x)\n", |
7009 | IWL_DEBUG_MAC80211("Enter: type %d (0x%x, 0x%x)\n", | 7009 | IEEE80211_IF_TYPE_MNTR, |
7010 | IEEE80211_IF_TYPE_MNTR, | 7010 | changed_flags, *total_flags); |
7011 | changed_flags, *total_flags); | 7011 | /* queue work 'cuz mac80211 is holding a lock which |
7012 | /* queue work 'cuz mac80211 is holding a lock which | 7012 | * prevents us from issuing (synchronous) f/w cmds */ |
7013 | * prevents us from issuing (synchronous) f/w cmds */ | 7013 | queue_work(priv->workqueue, &priv->set_monitor); |
7014 | queue_work(priv->workqueue, &priv->set_monitor); | ||
7015 | new_flags &= FIF_PROMISC_IN_BSS | | ||
7016 | FIF_OTHER_BSS | | ||
7017 | FIF_ALLMULTI; | ||
7018 | } | ||
7019 | } | 7014 | } |
7020 | *total_flags = new_flags; | 7015 | *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | |
7016 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; | ||
7021 | } | 7017 | } |
7022 | 7018 | ||
7023 | static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw, | 7019 | static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw, |
@@ -7412,37 +7408,6 @@ static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, | |||
7412 | 7408 | ||
7413 | #endif /* CONFIG_IWL3945_DEBUG */ | 7409 | #endif /* CONFIG_IWL3945_DEBUG */ |
7414 | 7410 | ||
7415 | static ssize_t show_rf_kill(struct device *d, | ||
7416 | struct device_attribute *attr, char *buf) | ||
7417 | { | ||
7418 | /* | ||
7419 | * 0 - RF kill not enabled | ||
7420 | * 1 - SW based RF kill active (sysfs) | ||
7421 | * 2 - HW based RF kill active | ||
7422 | * 3 - Both HW and SW based RF kill active | ||
7423 | */ | ||
7424 | struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; | ||
7425 | int val = (test_bit(STATUS_RF_KILL_SW, &priv->status) ? 0x1 : 0x0) | | ||
7426 | (test_bit(STATUS_RF_KILL_HW, &priv->status) ? 0x2 : 0x0); | ||
7427 | |||
7428 | return sprintf(buf, "%i\n", val); | ||
7429 | } | ||
7430 | |||
7431 | static ssize_t store_rf_kill(struct device *d, | ||
7432 | struct device_attribute *attr, | ||
7433 | const char *buf, size_t count) | ||
7434 | { | ||
7435 | struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; | ||
7436 | |||
7437 | mutex_lock(&priv->mutex); | ||
7438 | iwl3945_radio_kill_sw(priv, buf[0] == '1'); | ||
7439 | mutex_unlock(&priv->mutex); | ||
7440 | |||
7441 | return count; | ||
7442 | } | ||
7443 | |||
7444 | static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill); | ||
7445 | |||
7446 | static ssize_t show_temperature(struct device *d, | 7411 | static ssize_t show_temperature(struct device *d, |
7447 | struct device_attribute *attr, char *buf) | 7412 | struct device_attribute *attr, char *buf) |
7448 | { | 7413 | { |
@@ -7928,7 +7893,6 @@ static struct attribute *iwl3945_sysfs_entries[] = { | |||
7928 | #endif | 7893 | #endif |
7929 | &dev_attr_power_level.attr, | 7894 | &dev_attr_power_level.attr, |
7930 | &dev_attr_retry_rate.attr, | 7895 | &dev_attr_retry_rate.attr, |
7931 | &dev_attr_rf_kill.attr, | ||
7932 | &dev_attr_rs_window.attr, | 7896 | &dev_attr_rs_window.attr, |
7933 | &dev_attr_statistics.attr, | 7897 | &dev_attr_statistics.attr, |
7934 | &dev_attr_status.attr, | 7898 | &dev_attr_status.attr, |
@@ -8169,6 +8133,11 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8169 | pci_save_state(pdev); | 8133 | pci_save_state(pdev); |
8170 | pci_disable_device(pdev); | 8134 | pci_disable_device(pdev); |
8171 | 8135 | ||
8136 | err = iwl3945_rfkill_init(priv); | ||
8137 | if (err) | ||
8138 | IWL_ERROR("Unable to initialize RFKILL system. " | ||
8139 | "Ignoring error: %d\n", err); | ||
8140 | |||
8172 | return 0; | 8141 | return 0; |
8173 | 8142 | ||
8174 | out_free_geos: | 8143 | out_free_geos: |
@@ -8231,6 +8200,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
8231 | 8200 | ||
8232 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); | 8201 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); |
8233 | 8202 | ||
8203 | iwl3945_rfkill_unregister(priv); | ||
8234 | iwl3945_dealloc_ucode_pci(priv); | 8204 | iwl3945_dealloc_ucode_pci(priv); |
8235 | 8205 | ||
8236 | if (priv->rxq.bd) | 8206 | if (priv->rxq.bd) |
@@ -8299,6 +8269,143 @@ static int iwl3945_pci_resume(struct pci_dev *pdev) | |||
8299 | 8269 | ||
8300 | #endif /* CONFIG_PM */ | 8270 | #endif /* CONFIG_PM */ |
8301 | 8271 | ||
8272 | /*************** RFKILL FUNCTIONS **********/ | ||
8273 | #ifdef CONFIG_IWLWIFI_RFKILL | ||
8274 | /* software rf-kill from user */ | ||
8275 | static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state) | ||
8276 | { | ||
8277 | struct iwl3945_priv *priv = data; | ||
8278 | int err = 0; | ||
8279 | |||
8280 | if (!priv->rfkill_mngr.rfkill) | ||
8281 | return 0; | ||
8282 | |||
8283 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
8284 | return 0; | ||
8285 | |||
8286 | IWL_DEBUG_RF_KILL("we recieved soft RFKILL set to state %d\n", state); | ||
8287 | mutex_lock(&priv->mutex); | ||
8288 | |||
8289 | switch (state) { | ||
8290 | case RFKILL_STATE_UNBLOCKED: | ||
8291 | iwl3945_radio_kill_sw(priv, 0); | ||
8292 | /* if HW rf-kill is set dont allow ON state */ | ||
8293 | if (iwl3945_is_rfkill(priv)) | ||
8294 | err = -EBUSY; | ||
8295 | break; | ||
8296 | case RFKILL_STATE_SOFT_BLOCKED: | ||
8297 | iwl3945_radio_kill_sw(priv, 1); | ||
8298 | if (!iwl3945_is_rfkill(priv)) | ||
8299 | err = -EBUSY; | ||
8300 | break; | ||
8301 | default: | ||
8302 | IWL_WARNING("we recieved unexpected RFKILL state %d\n", state); | ||
8303 | break; | ||
8304 | } | ||
8305 | mutex_unlock(&priv->mutex); | ||
8306 | |||
8307 | return err; | ||
8308 | } | ||
8309 | |||
8310 | int iwl3945_rfkill_init(struct iwl3945_priv *priv) | ||
8311 | { | ||
8312 | struct device *device = wiphy_dev(priv->hw->wiphy); | ||
8313 | int ret = 0; | ||
8314 | |||
8315 | BUG_ON(device == NULL); | ||
8316 | |||
8317 | IWL_DEBUG_RF_KILL("Initializing RFKILL.\n"); | ||
8318 | priv->rfkill_mngr.rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN); | ||
8319 | if (!priv->rfkill_mngr.rfkill) { | ||
8320 | IWL_ERROR("Unable to allocate rfkill device.\n"); | ||
8321 | ret = -ENOMEM; | ||
8322 | goto error; | ||
8323 | } | ||
8324 | |||
8325 | priv->rfkill_mngr.rfkill->name = priv->cfg->name; | ||
8326 | priv->rfkill_mngr.rfkill->data = priv; | ||
8327 | priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON; | ||
8328 | priv->rfkill_mngr.rfkill->toggle_radio = iwl3945_rfkill_soft_rf_kill; | ||
8329 | priv->rfkill_mngr.rfkill->user_claim_unsupported = 1; | ||
8330 | |||
8331 | priv->rfkill_mngr.rfkill->dev.class->suspend = NULL; | ||
8332 | priv->rfkill_mngr.rfkill->dev.class->resume = NULL; | ||
8333 | |||
8334 | priv->rfkill_mngr.input_dev = input_allocate_device(); | ||
8335 | if (!priv->rfkill_mngr.input_dev) { | ||
8336 | IWL_ERROR("Unable to allocate rfkill input device.\n"); | ||
8337 | ret = -ENOMEM; | ||
8338 | goto freed_rfkill; | ||
8339 | } | ||
8340 | |||
8341 | priv->rfkill_mngr.input_dev->name = priv->cfg->name; | ||
8342 | priv->rfkill_mngr.input_dev->phys = wiphy_name(priv->hw->wiphy); | ||
8343 | priv->rfkill_mngr.input_dev->id.bustype = BUS_HOST; | ||
8344 | priv->rfkill_mngr.input_dev->id.vendor = priv->pci_dev->vendor; | ||
8345 | priv->rfkill_mngr.input_dev->dev.parent = device; | ||
8346 | priv->rfkill_mngr.input_dev->evbit[0] = BIT(EV_KEY); | ||
8347 | set_bit(KEY_WLAN, priv->rfkill_mngr.input_dev->keybit); | ||
8348 | |||
8349 | ret = rfkill_register(priv->rfkill_mngr.rfkill); | ||
8350 | if (ret) { | ||
8351 | IWL_ERROR("Unable to register rfkill: %d\n", ret); | ||
8352 | goto free_input_dev; | ||
8353 | } | ||
8354 | |||
8355 | ret = input_register_device(priv->rfkill_mngr.input_dev); | ||
8356 | if (ret) { | ||
8357 | IWL_ERROR("Unable to register rfkill input device: %d\n", ret); | ||
8358 | goto unregister_rfkill; | ||
8359 | } | ||
8360 | |||
8361 | IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n"); | ||
8362 | return ret; | ||
8363 | |||
8364 | unregister_rfkill: | ||
8365 | rfkill_unregister(priv->rfkill_mngr.rfkill); | ||
8366 | priv->rfkill_mngr.rfkill = NULL; | ||
8367 | |||
8368 | free_input_dev: | ||
8369 | input_free_device(priv->rfkill_mngr.input_dev); | ||
8370 | priv->rfkill_mngr.input_dev = NULL; | ||
8371 | |||
8372 | freed_rfkill: | ||
8373 | if (priv->rfkill_mngr.rfkill != NULL) | ||
8374 | rfkill_free(priv->rfkill_mngr.rfkill); | ||
8375 | priv->rfkill_mngr.rfkill = NULL; | ||
8376 | |||
8377 | error: | ||
8378 | IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n"); | ||
8379 | return ret; | ||
8380 | } | ||
8381 | |||
8382 | void iwl3945_rfkill_unregister(struct iwl3945_priv *priv) | ||
8383 | { | ||
8384 | |||
8385 | if (priv->rfkill_mngr.input_dev) | ||
8386 | input_unregister_device(priv->rfkill_mngr.input_dev); | ||
8387 | |||
8388 | if (priv->rfkill_mngr.rfkill) | ||
8389 | rfkill_unregister(priv->rfkill_mngr.rfkill); | ||
8390 | |||
8391 | priv->rfkill_mngr.input_dev = NULL; | ||
8392 | priv->rfkill_mngr.rfkill = NULL; | ||
8393 | } | ||
8394 | |||
8395 | /* set rf-kill to the right state. */ | ||
8396 | void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv) | ||
8397 | { | ||
8398 | |||
8399 | if (!priv->rfkill_mngr.rfkill) | ||
8400 | return; | ||
8401 | |||
8402 | if (!iwl3945_is_rfkill(priv)) | ||
8403 | priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON; | ||
8404 | else | ||
8405 | priv->rfkill_mngr.rfkill->state = RFKILL_STATE_OFF; | ||
8406 | } | ||
8407 | #endif | ||
8408 | |||
8302 | /***************************************************************************** | 8409 | /***************************************************************************** |
8303 | * | 8410 | * |
8304 | * driver and module entry point | 8411 | * driver and module entry point |