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

Commit 60294de3 authored by Zhu, Yi's avatar Zhu, Yi Committed by John W. Linville
Browse files

iwlwifi: fix priv->iw_mode setting when multiple vif are configured



mac80211 supports multiple virtual interfaces for a single device. For
example, a managed interface (wlan0) and a monitor interface (mon0) can
exist at the same time. Thus priv->iw_mode is not sufficient to track
the wireless mode any more. The patch redefines priv->iw_mode as the
first interface mode (the same as priv->vif->type if priv->vif != NULL).
If another monitor type interface is created later, we don't change
priv->iw_mode into monitor. This way, the original interface still
works. The patch also requests mac80211 to do reassociation after we
change the Rx filter flags.

Signed-off-by: default avatarZhu Yi <yi.zhu@intel.com>
Signed-off-by: default avatarReinette Chatre <reinette.chatre@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent eb4779c4
Loading
Loading
Loading
Loading
+7 −8
Original line number Diff line number Diff line
@@ -726,13 +726,13 @@ static void iwl_set_flags_for_band(struct iwl_priv *priv,
/*
 * initialize rxon structure with default values from eeprom
 */
static void iwl4965_connection_init_rx_config(struct iwl_priv *priv)
static void iwl4965_connection_init_rx_config(struct iwl_priv *priv, int mode)
{
	const struct iwl_channel_info *ch_info;

	memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));

	switch (priv->iw_mode) {
	switch (mode) {
	case NL80211_IFTYPE_AP:
		priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP;
		break;
@@ -755,7 +755,7 @@ static void iwl4965_connection_init_rx_config(struct iwl_priv *priv)
		    RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
		break;
	default:
		IWL_ERROR("Unsupported interface type %d\n", priv->iw_mode);
		IWL_ERROR("Unsupported interface type %d\n", mode);
		break;
	}

@@ -803,9 +803,7 @@ static void iwl4965_connection_init_rx_config(struct iwl_priv *priv)

static int iwl4965_set_mode(struct iwl_priv *priv, int mode)
{
	priv->iw_mode = mode;

	iwl4965_connection_init_rx_config(priv);
	iwl4965_connection_init_rx_config(priv, mode);
	memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);

	iwl_clear_stations_table(priv);
@@ -2056,7 +2054,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
		active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
	} else {
		/* Initialize our rx_config data */
		iwl4965_connection_init_rx_config(priv);
		iwl4965_connection_init_rx_config(priv, priv->iw_mode);
		memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
	}

@@ -2380,7 +2378,6 @@ static void iwl4965_bg_set_monitor(struct work_struct *work)
	mutex_lock(&priv->mutex);

	ret = iwl4965_set_mode(priv, NL80211_IFTYPE_MONITOR);

	if (ret) {
		if (ret == -EAGAIN)
			IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n");
@@ -2389,6 +2386,7 @@ static void iwl4965_bg_set_monitor(struct work_struct *work)
	}

	mutex_unlock(&priv->mutex);
	ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC);
}

static void iwl_bg_run_time_calib_work(struct work_struct *work)
@@ -2720,6 +2718,7 @@ static int iwl4965_mac_add_interface(struct ieee80211_hw *hw,

	spin_lock_irqsave(&priv->lock, flags);
	priv->vif = conf->vif;
	priv->iw_mode = conf->type;

	spin_unlock_irqrestore(&priv->lock, flags);

+9 −9
Original line number Diff line number Diff line
@@ -2175,13 +2175,14 @@ static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv,
/*
 * initialize rxon structure with default values from eeprom
 */
static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv)
static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv,
					      int mode)
{
	const struct iwl3945_channel_info *ch_info;

	memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));

	switch (priv->iw_mode) {
	switch (mode) {
	case NL80211_IFTYPE_AP:
		priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP;
		break;
@@ -2204,7 +2205,7 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv)
		    RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
		break;
	default:
		IWL_ERROR("Unsupported interface type %d\n", priv->iw_mode);
		IWL_ERROR("Unsupported interface type %d\n", mode);
		break;
	}

@@ -2227,8 +2228,7 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv)
	 * in some case A channels are all non IBSS
	 * in this case force B/G channel
	 */
	if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
	    !(is_channel_ibss(ch_info)))
	if ((mode == NL80211_IFTYPE_ADHOC) && !(is_channel_ibss(ch_info)))
		ch_info = &priv->channel_info[0];

	priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
@@ -2261,9 +2261,7 @@ static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode)
		}
	}

	priv->iw_mode = mode;

	iwl3945_connection_init_rx_config(priv);
	iwl3945_connection_init_rx_config(priv, mode);
	memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);

	iwl3945_clear_stations_table(priv);
@@ -5685,7 +5683,7 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
		active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
	} else {
		/* Initialize our rx_config data */
		iwl3945_connection_init_rx_config(priv);
		iwl3945_connection_init_rx_config(priv, priv->iw_mode);
		memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
	}

@@ -6001,6 +5999,7 @@ static void iwl3945_bg_set_monitor(struct work_struct *work)
			IWL_ERROR("iwl3945_set_mode() failed\n");

	mutex_unlock(&priv->mutex);
	ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC);
}

#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
@@ -6544,6 +6543,7 @@ static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,

	spin_lock_irqsave(&priv->lock, flags);
	priv->vif = conf->vif;
	priv->iw_mode = conf->type;

	spin_unlock_irqrestore(&priv->lock, flags);