summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/intel/iwlwifi/dvm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/dvm')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/eeprom.c8
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c11
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/main.c78
3 files changed, 63 insertions, 34 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/eeprom.c b/drivers/net/wireless/intel/iwlwifi/dvm/eeprom.c
index 931aa3f5798d..cdc05f7e75a6 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/eeprom.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/eeprom.c
@@ -676,12 +676,12 @@ static int iwl_eeprom_acquire_semaphore(struct iwl_trans *trans)
for (count = 0; count < IWL_EEPROM_SEM_RETRY_LIMIT; count++) {
/* Request semaphore */
iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
+ CSR_HW_IF_CONFIG_REG_EEPROM_OWN_SEM);
/* See if we got it */
ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
- CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
+ CSR_HW_IF_CONFIG_REG_EEPROM_OWN_SEM,
+ CSR_HW_IF_CONFIG_REG_EEPROM_OWN_SEM,
IWL_EEPROM_SEM_TIMEOUT);
if (ret >= 0) {
IWL_DEBUG_EEPROM(trans->dev,
@@ -697,7 +697,7 @@ static int iwl_eeprom_acquire_semaphore(struct iwl_trans *trans)
static void iwl_eeprom_release_semaphore(struct iwl_trans *trans)
{
iwl_clear_bit(trans, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
+ CSR_HW_IF_CONFIG_REG_EEPROM_OWN_SEM);
}
static int iwl_eeprom_verify_signature(struct iwl_trans *trans, bool nvm_is_otp)
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
index 74d163e56511..56d19a034c24 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
@@ -1565,6 +1565,16 @@ static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw,
IWL_DEBUG_MAC80211(priv, "leave\n");
}
+static void
+iwlagn_mac_reconfig_complete(struct ieee80211_hw *hw,
+ enum ieee80211_reconfig_type reconfig_type)
+{
+ struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
+
+ if (reconfig_type == IEEE80211_RECONFIG_TYPE_RESTART)
+ iwl_trans_finish_sw_reset(priv->trans);
+}
+
const struct ieee80211_ops iwlagn_hw_ops = {
.add_chanctx = ieee80211_emulate_add_chanctx,
.remove_chanctx = ieee80211_emulate_remove_chanctx,
@@ -1598,6 +1608,7 @@ const struct ieee80211_ops iwlagn_hw_ops = {
.tx_last_beacon = iwlagn_mac_tx_last_beacon,
.event_callback = iwlagn_mac_event_callback,
.set_tim = iwlagn_mac_set_tim,
+ .reconfig_complete = iwlagn_mac_reconfig_complete,
};
/* This function both allocates and initializes hw and priv. */
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
index 769b75c3fa5b..30789ba06d9d 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
@@ -1241,7 +1241,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
STATISTICS_NOTIFICATION,
REPLY_TX,
};
- int i;
+ int i, err;
/************************
* 1. Allocating HW data
@@ -1249,6 +1249,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
hw = iwl_alloc_all();
if (!hw) {
pr_err("%s: Cannot allocate network device\n", trans->name);
+ err = -ENOMEM;
goto out;
}
@@ -1299,8 +1300,10 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
break;
}
- if (WARN_ON(!priv->lib))
+ if (WARN_ON(!priv->lib)) {
+ err = -ENODEV;
goto out_free_hw;
+ }
/*
* Populate the state variables that the transport layer needs
@@ -1377,12 +1380,14 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
IWL_INFO(priv, "Detected %s, REV=0x%X\n",
priv->trans->name, priv->trans->hw_rev);
- if (iwl_trans_start_hw(priv->trans))
+ err = iwl_trans_start_hw(priv->trans);
+ if (err)
goto out_free_hw;
/* Read the EEPROM */
- if (iwl_read_eeprom(priv->trans, &priv->eeprom_blob,
- &priv->eeprom_blob_size)) {
+ err = iwl_read_eeprom(priv->trans, &priv->eeprom_blob,
+ &priv->eeprom_blob_size);
+ if (err) {
IWL_ERR(priv, "Unable to init EEPROM\n");
goto out_free_hw;
}
@@ -1393,13 +1398,17 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
priv->nvm_data = iwl_parse_eeprom_data(priv->trans, priv->cfg,
priv->eeprom_blob,
priv->eeprom_blob_size);
- if (!priv->nvm_data)
+ if (!priv->nvm_data) {
+ err = -ENOMEM;
goto out_free_eeprom_blob;
+ }
- if (iwl_nvm_check_version(priv->nvm_data, priv->trans))
+ err = iwl_nvm_check_version(priv->nvm_data, priv->trans);
+ if (err)
goto out_free_eeprom;
- if (iwl_eeprom_init_hw_params(priv))
+ err = iwl_eeprom_init_hw_params(priv);
+ if (err)
goto out_free_eeprom;
/* extract MAC Address */
@@ -1446,7 +1455,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
atomic_set(&priv->queue_stop_count[i], 0);
}
- if (iwl_init_drv(priv))
+ err = iwl_init_drv(priv);
+ if (err)
goto out_free_eeprom;
/* At this point both hw and priv are initialized. */
@@ -1480,7 +1490,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
*
* 7. Setup and register with mac80211 and debugfs
**************************************************/
- if (iwlagn_mac_setup_register(priv, &fw->ucode_capa))
+ err = iwlagn_mac_setup_register(priv, &fw->ucode_capa);
+ if (err)
goto out_destroy_workqueue;
iwl_dbgfs_register(priv, dbgfs_dir);
@@ -1500,8 +1511,7 @@ out_free_eeprom:
out_free_hw:
ieee80211_free_hw(priv->hw);
out:
- op_mode = NULL;
- return op_mode;
+ return ERR_PTR(err);
}
static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode)
@@ -1895,17 +1905,9 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
unsigned int reload_msec;
unsigned long reload_jiffies;
- if (iwl_have_debug_level(IWL_DL_FW))
- iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS);
-
/* uCode is no longer loaded. */
priv->ucode_loaded = false;
- /* Set the FW error flag -- cleared on iwl_down */
- set_bit(STATUS_FW_ERROR, &priv->status);
-
- iwl_abort_notification_waits(&priv->notif_wait);
-
/* Keep the restart process from trying to send host
* commands by clearing the ready bit */
clear_bit(STATUS_READY, &priv->status);
@@ -1942,27 +1944,43 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
}
}
-static void iwl_nic_error(struct iwl_op_mode *op_mode, bool sync)
+static void iwl_nic_error(struct iwl_op_mode *op_mode,
+ enum iwl_fw_error_type type)
{
struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
+ /* Set the FW error flag -- cleared on iwl_down */
+ set_bit(STATUS_FW_ERROR, &priv->status);
+
+ iwl_abort_notification_waits(&priv->notif_wait);
+
+ if (type == IWL_ERR_TYPE_CMD_QUEUE_FULL && iwl_check_for_ct_kill(priv))
+ return;
+
IWL_ERR(priv, "Loaded firmware version: %s\n",
priv->fw->fw_version);
- iwl_dump_nic_error_log(priv);
- iwl_dump_nic_event_log(priv, false, NULL);
+ if (type == IWL_ERR_TYPE_CMD_QUEUE_FULL) {
+ IWL_ERR(priv, "Command queue full!\n");
+ } else {
+ iwl_dump_nic_error_log(priv);
+ iwl_dump_nic_event_log(priv, false, NULL);
+ }
- iwlagn_fw_error(priv, false);
+ if (iwl_have_debug_level(IWL_DL_FW))
+ iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS);
}
-static void iwl_cmd_queue_full(struct iwl_op_mode *op_mode)
+static bool iwlagn_sw_reset(struct iwl_op_mode *op_mode,
+ enum iwl_fw_error_type type)
{
struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
- if (!iwl_check_for_ct_kill(priv)) {
- IWL_ERR(priv, "Restarting adapter queue is full\n");
- iwlagn_fw_error(priv, false);
- }
+ if (type == IWL_ERR_TYPE_CMD_QUEUE_FULL && iwl_check_for_ct_kill(priv))
+ return false;
+
+ iwlagn_fw_error(priv, false);
+ return true;
}
#define EEPROM_RF_CONFIG_TYPE_MAX 0x3
@@ -2117,7 +2135,7 @@ static const struct iwl_op_mode_ops iwl_dvm_ops = {
.hw_rf_kill = iwl_set_hw_rfkill_state,
.free_skb = iwl_free_skb,
.nic_error = iwl_nic_error,
- .cmd_queue_full = iwl_cmd_queue_full,
+ .sw_reset = iwlagn_sw_reset,
.nic_config = iwl_nic_config,
.wimax_active = iwl_wimax_active,
};