Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 19cc1087 authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville
Browse files

iwlwifi: do proper hw restart



When the microcode fails for any reason, ask mac80211 to
recover instead of trying ourselves and failing at it.

Signed-off-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarReinette Chatre <reinette.chatre@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 44033f80
Loading
Loading
Loading
Loading
+13 −30
Original line number Original line Diff line number Diff line
@@ -190,7 +190,6 @@ int iwl_commit_rxon(struct iwl_priv *priv)


	priv->cfg->ops->smgmt->clear_station_table(priv);
	priv->cfg->ops->smgmt->clear_station_table(priv);


	if (!priv->error_recovering)
	priv->start_calib = 0;
	priv->start_calib = 0;


	/* Add the broadcast address so we can send broadcast frames */
	/* Add the broadcast address so we can send broadcast frames */
@@ -967,23 +966,6 @@ static inline void iwl_synchronize_irq(struct iwl_priv *priv)
	tasklet_kill(&priv->irq_tasklet);
	tasklet_kill(&priv->irq_tasklet);
}
}


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

	memcpy(&priv->staging_rxon, &priv->recovery_rxon,
	       sizeof(priv->staging_rxon));
	priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
	iwlcore_commit_rxon(priv);

	iwl_rxon_add_station(priv, priv->bssid, 1);

	spin_lock_irqsave(&priv->lock, flags);
	priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id);
	priv->error_recovering = 0;
	spin_unlock_irqrestore(&priv->lock, flags);
}

static void iwl_irq_tasklet(struct iwl_priv *priv)
static void iwl_irq_tasklet(struct iwl_priv *priv)
{
{
	u32 inta, handled = 0;
	u32 inta, handled = 0;
@@ -1514,9 +1496,6 @@ static void iwl_alive_start(struct iwl_priv *priv)
	set_bit(STATUS_READY, &priv->status);
	set_bit(STATUS_READY, &priv->status);
	wake_up_interruptible(&priv->wait_command_queue);
	wake_up_interruptible(&priv->wait_command_queue);


	if (priv->error_recovering)
		iwl_error_recovery(priv);

	iwl_power_update_mode(priv, 1);
	iwl_power_update_mode(priv, 1);


	/* reassociate for ADHOC mode */
	/* reassociate for ADHOC mode */
@@ -1715,9 +1694,6 @@ static int __iwl_up(struct iwl_priv *priv)
			continue;
			continue;
		}
		}


		/* Clear out the uCode error bit if it is set */
		clear_bit(STATUS_FW_ERROR, &priv->status);

		/* start card; "initialize" will load runtime ucode */
		/* start card; "initialize" will load runtime ucode */
		iwl_nic_start(priv);
		iwl_nic_start(priv);


@@ -1812,9 +1788,18 @@ static void iwl_bg_restart(struct work_struct *data)
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
		return;
		return;


	if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
		mutex_lock(&priv->mutex);
		priv->vif = NULL;
		priv->is_open = 0;
		mutex_unlock(&priv->mutex);
		iwl_down(priv);
		ieee80211_restart_hw(priv->hw);
	} else {
		iwl_down(priv);
		iwl_down(priv);
		queue_work(priv->workqueue, &priv->up);
		queue_work(priv->workqueue, &priv->up);
	}
	}
}


static void iwl_bg_rx_replenish(struct work_struct *data)
static void iwl_bg_rx_replenish(struct work_struct *data)
{
{
@@ -2007,10 +1992,8 @@ static void iwl_mac_stop(struct ieee80211_hw *hw)


	IWL_DEBUG_MAC80211(priv, "enter\n");
	IWL_DEBUG_MAC80211(priv, "enter\n");


	if (!priv->is_open) {
	if (!priv->is_open)
		IWL_DEBUG_MAC80211(priv, "leave - skip\n");
		return;
		return;
	}


	priv->is_open = 0;
	priv->is_open = 0;


+0 −5
Original line number Original line Diff line number Diff line
@@ -1229,11 +1229,6 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
		IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
		IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
			  "Restarting adapter due to uCode error.\n");
			  "Restarting adapter due to uCode error.\n");


		if (iwl_is_associated(priv)) {
			memcpy(&priv->recovery_rxon, &priv->active_rxon,
			       sizeof(priv->recovery_rxon));
			priv->error_recovering = 1;
		}
		if (priv->cfg->mod_params->restart_fw)
		if (priv->cfg->mod_params->restart_fw)
			queue_work(priv->workqueue, &priv->restart);
			queue_work(priv->workqueue, &priv->restart);
	}
	}
+0 −1
Original line number Original line Diff line number Diff line
@@ -933,7 +933,6 @@ struct iwl_priv {
	const struct iwl_rxon_cmd active_rxon;
	const struct iwl_rxon_cmd active_rxon;
	struct iwl_rxon_cmd staging_rxon;
	struct iwl_rxon_cmd staging_rxon;


	int error_recovering;
	struct iwl_rxon_cmd recovery_rxon;
	struct iwl_rxon_cmd recovery_rxon;


	/* 1st responses from initialize and runtime uCode images.
	/* 1st responses from initialize and runtime uCode images.
+11 −25
Original line number Original line Diff line number Diff line
@@ -1837,23 +1837,6 @@ static void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
	iwl_release_nic_access(priv);
	iwl_release_nic_access(priv);
}
}


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

	memcpy(&priv->staging_rxon, &priv->recovery_rxon,
	       sizeof(priv->staging_rxon));
	priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
	iwlcore_commit_rxon(priv);

	priv->cfg->ops->smgmt->add_station(priv, priv->bssid, 1, 0, NULL);

	spin_lock_irqsave(&priv->lock, flags);
	priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id);
	priv->error_recovering = 0;
	spin_unlock_irqrestore(&priv->lock, flags);
}

static void iwl3945_irq_tasklet(struct iwl_priv *priv)
static void iwl3945_irq_tasklet(struct iwl_priv *priv)
{
{
	u32 inta, handled = 0;
	u32 inta, handled = 0;
@@ -2683,9 +2666,6 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
	/* After the ALIVE response, we can send commands to 3945 uCode */
	/* After the ALIVE response, we can send commands to 3945 uCode */
	set_bit(STATUS_ALIVE, &priv->status);
	set_bit(STATUS_ALIVE, &priv->status);


	/* Clear out the uCode error bit if it is set */
	clear_bit(STATUS_FW_ERROR, &priv->status);

	if (iwl_is_rfkill(priv))
	if (iwl_is_rfkill(priv))
		return;
		return;


@@ -2722,9 +2702,6 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
	set_bit(STATUS_READY, &priv->status);
	set_bit(STATUS_READY, &priv->status);
	wake_up_interruptible(&priv->wait_command_queue);
	wake_up_interruptible(&priv->wait_command_queue);


	if (priv->error_recovering)
		iwl3945_error_recovery(priv);

	/* reassociate for ADHOC mode */
	/* reassociate for ADHOC mode */
	if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {
	if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {
		struct sk_buff *beacon = ieee80211_beacon_get(priv->hw,
		struct sk_buff *beacon = ieee80211_beacon_get(priv->hw,
@@ -3231,9 +3208,18 @@ static void iwl3945_bg_restart(struct work_struct *data)
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
		return;
		return;


	if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
		mutex_lock(&priv->mutex);
		priv->vif = NULL;
		priv->is_open = 0;
		mutex_unlock(&priv->mutex);
		iwl3945_down(priv);
		ieee80211_restart_hw(priv->hw);
	} else {
		iwl3945_down(priv);
		iwl3945_down(priv);
		queue_work(priv->workqueue, &priv->up);
		queue_work(priv->workqueue, &priv->up);
	}
	}
}


static void iwl3945_bg_rx_replenish(struct work_struct *data)
static void iwl3945_bg_rx_replenish(struct work_struct *data)
{
{