Skip to content

Commit

Permalink
iwlwifi: port to cfg80211 rfkill
Browse files Browse the repository at this point in the history
This ports the iwlwifi rfkill code to the new API offered by
cfg80211 and thus removes a lot of useless stuff. The soft-
rfkill is completely removed since that is now handled by
setting the interfaces down.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Tested-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Johannes Berg authored and John W. Linville committed Jun 10, 2009
1 parent 1506e30 commit a60e77e
Show file tree
Hide file tree
Showing 11 changed files with 19 additions and 414 deletions.
4 changes: 0 additions & 4 deletions drivers/net/wireless/iwlwifi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ config IWLWIFI_LEDS
bool "Enable LED support in iwlagn and iwl3945 drivers"
depends on IWLWIFI

config IWLWIFI_RFKILL
def_bool y
depends on IWLWIFI && RFKILL

config IWLWIFI_SPECTRUM_MEASUREMENT
bool "Enable Spectrum Measurement in iwlagn driver"
depends on IWLWIFI
Expand Down
1 change: 0 additions & 1 deletion drivers/net/wireless/iwlwifi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o
iwlcore-objs += iwl-scan.o
iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o
iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o
iwlcore-$(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) += iwl-spectrum.o

obj-$(CONFIG_IWLAGN) += iwlagn.o
Expand Down
5 changes: 0 additions & 5 deletions drivers/net/wireless/iwlwifi/iwl-3945.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@
#include <linux/kernel.h>
#include <net/ieee80211_radiotap.h>

/*used for rfkill*/
#include <linux/rfkill.h>
#include <linux/input.h>

/* Hardware specific file defines the PCI IDs table for that hardware module */
extern struct pci_device_id iwl3945_hw_card_ids[];

Expand Down Expand Up @@ -155,7 +151,6 @@ struct iwl3945_frame {
#define STATUS_HCMD_SYNC_ACTIVE 1 /* sync host command in progress */
#define STATUS_INT_ENABLED 2
#define STATUS_RF_KILL_HW 3
#define STATUS_RF_KILL_SW 4
#define STATUS_INIT 5
#define STATUS_ALIVE 6
#define STATUS_READY 7
Expand Down
42 changes: 12 additions & 30 deletions drivers/net/wireless/iwlwifi/iwl-agn.c
Original file line number Diff line number Diff line change
Expand Up @@ -737,19 +737,13 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
clear_bit(STATUS_RF_KILL_HW, &priv->status);


if (flags & SW_CARD_DISABLED)
set_bit(STATUS_RF_KILL_SW, &priv->status);
else
clear_bit(STATUS_RF_KILL_SW, &priv->status);

if (!(flags & RXON_CARD_DISABLED))
iwl_scan_cancel(priv);

if ((test_bit(STATUS_RF_KILL_HW, &status) !=
test_bit(STATUS_RF_KILL_HW, &priv->status)) ||
(test_bit(STATUS_RF_KILL_SW, &status) !=
test_bit(STATUS_RF_KILL_SW, &priv->status)))
queue_work(priv->workqueue, &priv->rf_kill);
test_bit(STATUS_RF_KILL_HW, &priv->status)))
wiphy_rfkill_set_hw_state(priv->hw->wiphy,
test_bit(STATUS_RF_KILL_HW, &priv->status));
else
wake_up_interruptible(&priv->wait_command_queue);
}
Expand Down Expand Up @@ -1045,7 +1039,7 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
set_bit(STATUS_RF_KILL_HW, &priv->status);
else
clear_bit(STATUS_RF_KILL_HW, &priv->status);
queue_work(priv->workqueue, &priv->rf_kill);
wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill);
}

handled |= CSR_INT_BIT_RF_KILL;
Expand Down Expand Up @@ -1218,7 +1212,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
set_bit(STATUS_RF_KILL_HW, &priv->status);
else
clear_bit(STATUS_RF_KILL_HW, &priv->status);
queue_work(priv->workqueue, &priv->rf_kill);
wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill);
}

handled |= CSR_INT_BIT_RF_KILL;
Expand Down Expand Up @@ -1726,12 +1720,10 @@ static void __iwl_down(struct iwl_priv *priv)
ieee80211_stop_queues(priv->hw);

/* If we have not previously called iwl_init() then
* clear all bits but the RF Kill bits and return */
* clear all bits but the RF Kill bit and return */
if (!iwl_is_init(priv)) {
priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) <<
STATUS_RF_KILL_HW |
test_bit(STATUS_RF_KILL_SW, &priv->status) <<
STATUS_RF_KILL_SW |
test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
STATUS_GEO_CONFIGURED |
test_bit(STATUS_EXIT_PENDING, &priv->status) <<
Expand All @@ -1740,11 +1732,9 @@ static void __iwl_down(struct iwl_priv *priv)
}

/* ...otherwise clear out all the status bits but the RF Kill
* bits and continue taking the NIC down. */
* bit and continue taking the NIC down. */
priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) <<
STATUS_RF_KILL_HW |
test_bit(STATUS_RF_KILL_SW, &priv->status) <<
STATUS_RF_KILL_SW |
test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
STATUS_GEO_CONFIGURED |
test_bit(STATUS_FW_ERROR, &priv->status) <<
Expand Down Expand Up @@ -1866,9 +1856,10 @@ static int __iwl_up(struct iwl_priv *priv)
set_bit(STATUS_RF_KILL_HW, &priv->status);

if (iwl_is_rfkill(priv)) {
wiphy_rfkill_set_hw_state(priv->hw->wiphy, true);

iwl_enable_interrupts(priv);
IWL_WARN(priv, "Radio disabled by %s RF Kill switch\n",
test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW");
IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n");
return 0;
}

Expand Down Expand Up @@ -2001,7 +1992,6 @@ static void iwl_bg_up(struct work_struct *data)
mutex_lock(&priv->mutex);
__iwl_up(priv);
mutex_unlock(&priv->mutex);
iwl_rfkill_set_hw_state(priv);
}

static void iwl_bg_restart(struct work_struct *data)
Expand Down Expand Up @@ -2179,8 +2169,6 @@ static int iwl_mac_start(struct ieee80211_hw *hw)

mutex_unlock(&priv->mutex);

iwl_rfkill_set_hw_state(priv);

if (ret)
return ret;

Expand Down Expand Up @@ -2775,7 +2763,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
INIT_WORK(&priv->up, iwl_bg_up);
INIT_WORK(&priv->restart, iwl_bg_restart);
INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill);
INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work);
INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
Expand Down Expand Up @@ -3046,12 +3033,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
else
set_bit(STATUS_RF_KILL_HW, &priv->status);

err = iwl_rfkill_init(priv);
if (err)
IWL_ERR(priv, "Unable to initialize RFKILL system. "
"Ignoring error: %d\n", err);
else
iwl_rfkill_set_hw_state(priv);
wiphy_rfkill_set_hw_state(priv->hw->wiphy,
test_bit(STATUS_RF_KILL_HW, &priv->status));

iwl_power_initialize(priv);
return 0;
Expand Down Expand Up @@ -3115,7 +3098,6 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)

iwl_synchronize_irq(priv);

iwl_rfkill_unregister(priv);
iwl_dealloc_ucode_pci(priv);

if (priv->rxq.bd)
Expand Down
138 changes: 0 additions & 138 deletions drivers/net/wireless/iwlwifi/iwl-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
#include "iwl-debug.h"
#include "iwl-core.h"
#include "iwl-io.h"
#include "iwl-rfkill.h"
#include "iwl-power.h"
#include "iwl-sta.h"
#include "iwl-helpers.h"
Expand Down Expand Up @@ -2211,126 +2210,6 @@ int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
}
EXPORT_SYMBOL(iwl_send_card_state);

void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv)
{
unsigned long flags;

if (test_bit(STATUS_RF_KILL_SW, &priv->status))
return;

IWL_DEBUG_RF_KILL(priv, "Manual SW RF KILL set to: RADIO OFF\n");

iwl_scan_cancel(priv);
/* FIXME: This is a workaround for AP */
if (priv->iw_mode != NL80211_IFTYPE_AP) {
spin_lock_irqsave(&priv->lock, flags);
iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
CSR_UCODE_SW_BIT_RFKILL);
spin_unlock_irqrestore(&priv->lock, flags);
/* call the host command only if no hw rf-kill set */
if (!test_bit(STATUS_RF_KILL_HW, &priv->status) &&
iwl_is_ready(priv))
iwl_send_card_state(priv,
CARD_STATE_CMD_DISABLE, 0);
set_bit(STATUS_RF_KILL_SW, &priv->status);
/* make sure mac80211 stop sending Tx frame */
if (priv->mac80211_registered)
ieee80211_stop_queues(priv->hw);
}
}
EXPORT_SYMBOL(iwl_radio_kill_sw_disable_radio);

int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv)
{
unsigned long flags;

if (!test_bit(STATUS_RF_KILL_SW, &priv->status))
return 0;

IWL_DEBUG_RF_KILL(priv, "Manual SW RF KILL set to: RADIO ON\n");

spin_lock_irqsave(&priv->lock, flags);
iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);

/* If the driver is up it will receive CARD_STATE_NOTIFICATION
* notification where it will clear SW rfkill status.
* Setting it here would break the handler. Only if the
* interface is down we can set here since we don't
* receive any further notification.
*/
if (!priv->is_open)
clear_bit(STATUS_RF_KILL_SW, &priv->status);
spin_unlock_irqrestore(&priv->lock, flags);

/* wake up ucode */
msleep(10);

iwl_read32(priv, CSR_UCODE_DRV_GP1);
spin_lock_irqsave(&priv->reg_lock, flags);
if (!iwl_grab_nic_access(priv))
iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->reg_lock, flags);

if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
IWL_DEBUG_RF_KILL(priv, "Can not turn radio back on - "
"disabled by HW switch\n");
return 0;
}

/* when driver is up while rfkill is on, it wont receive
* any CARD_STATE_NOTIFICATION notifications so we have to
* restart it in here
*/
if (priv->is_open && !test_bit(STATUS_ALIVE, &priv->status)) {
clear_bit(STATUS_RF_KILL_SW, &priv->status);
if (!iwl_is_rfkill(priv))
queue_work(priv->workqueue, &priv->up);
}

/* If the driver is already loaded, it will receive
* CARD_STATE_NOTIFICATION notifications and the handler will
* call restart to reload the driver.
*/
return 1;
}
EXPORT_SYMBOL(iwl_radio_kill_sw_enable_radio);

void iwl_bg_rf_kill(struct work_struct *work)
{
struct iwl_priv *priv = container_of(work, struct iwl_priv, rf_kill);

wake_up_interruptible(&priv->wait_command_queue);

if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;

mutex_lock(&priv->mutex);

if (!iwl_is_rfkill(priv)) {
IWL_DEBUG_RF_KILL(priv,
"HW and/or SW RF Kill no longer active, restarting "
"device\n");
if (!test_bit(STATUS_EXIT_PENDING, &priv->status) &&
priv->is_open)
queue_work(priv->workqueue, &priv->restart);
} else {
/* make sure mac80211 stop sending Tx frame */
if (priv->mac80211_registered)
ieee80211_stop_queues(priv->hw);

if (!test_bit(STATUS_RF_KILL_HW, &priv->status))
IWL_DEBUG_RF_KILL(priv, "Can not turn radio back on - "
"disabled by SW switch\n");
else
IWL_WARN(priv, "Radio Frequency Kill Switch is On:\n"
"Kill switch must be turned off for "
"wireless networking to work.\n");
}
mutex_unlock(&priv->mutex);
iwl_rfkill_set_hw_state(priv);
}
EXPORT_SYMBOL(iwl_bg_rf_kill);

void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
Expand Down Expand Up @@ -2849,23 +2728,6 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
if (priv->cfg->ops->hcmd->set_rxon_chain)
priv->cfg->ops->hcmd->set_rxon_chain(priv);

if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
if (conf->radio_enabled &&
iwl_radio_kill_sw_enable_radio(priv)) {
IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - "
"waiting for uCode\n");
goto out;
}

if (!conf->radio_enabled)
iwl_radio_kill_sw_disable_radio(priv);
}

if (!conf->radio_enabled) {
IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n");
goto out;
}

if (!iwl_is_ready(priv)) {
IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
goto out;
Expand Down
16 changes: 1 addition & 15 deletions drivers/net/wireless/iwlwifi/iwl-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -348,14 +348,6 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id);
****************************************************/
int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);

/*****************************************************
* RF -Kill - here and not in iwl-rfkill.h to be available when
* RF-kill subsystem is not compiled.
****************************************************/
void iwl_bg_rf_kill(struct work_struct *work);
void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv);
int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv);

/*******************************************************************************
* Rate
******************************************************************************/
Expand Down Expand Up @@ -498,7 +490,6 @@ void iwlcore_free_geos(struct iwl_priv *priv);
#define STATUS_HCMD_SYNC_ACTIVE 1 /* sync host command in progress */
#define STATUS_INT_ENABLED 2
#define STATUS_RF_KILL_HW 3
#define STATUS_RF_KILL_SW 4
#define STATUS_INIT 5
#define STATUS_ALIVE 6
#define STATUS_READY 7
Expand Down Expand Up @@ -533,19 +524,14 @@ static inline int iwl_is_init(struct iwl_priv *priv)
return test_bit(STATUS_INIT, &priv->status);
}

static inline int iwl_is_rfkill_sw(struct iwl_priv *priv)
{
return test_bit(STATUS_RF_KILL_SW, &priv->status);
}

static inline int iwl_is_rfkill_hw(struct iwl_priv *priv)
{
return test_bit(STATUS_RF_KILL_HW, &priv->status);
}

static inline int iwl_is_rfkill(struct iwl_priv *priv)
{
return iwl_is_rfkill_hw(priv) || iwl_is_rfkill_sw(priv);
return iwl_is_rfkill_hw(priv);
}

static inline int iwl_is_ready_rf(struct iwl_priv *priv)
Expand Down
2 changes: 0 additions & 2 deletions drivers/net/wireless/iwlwifi/iwl-debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -449,8 +449,6 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
test_bit(STATUS_INT_ENABLED, &priv->status));
pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n",
test_bit(STATUS_RF_KILL_HW, &priv->status));
pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_SW:\t %d\n",
test_bit(STATUS_RF_KILL_SW, &priv->status));
pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n",
test_bit(STATUS_INIT, &priv->status));
pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n",
Expand Down
Loading

0 comments on commit a60e77e

Please sign in to comment.