diff options
author | Zhu, Yi <yi.zhu@intel.com> | 2008-10-29 17:05:45 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-11-10 15:17:36 -0500 |
commit | 60294de3af99586bb4a205274d02a7c8b910c0c3 (patch) | |
tree | 5f28e0bbb7286ed379c34544e7dfa78f9d212743 | |
parent | eb4779c40549f8e0dd45c9a30f279134c9a86131 (diff) |
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: Zhu Yi <yi.zhu@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 15 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 18 |
2 files changed, 16 insertions, 17 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index ad186e134dec..ae30d495876b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -726,13 +726,13 @@ static void iwl_set_flags_for_band(struct iwl_priv *priv, | |||
726 | /* | 726 | /* |
727 | * initialize rxon structure with default values from eeprom | 727 | * initialize rxon structure with default values from eeprom |
728 | */ | 728 | */ |
729 | static void iwl4965_connection_init_rx_config(struct iwl_priv *priv) | 729 | static void iwl4965_connection_init_rx_config(struct iwl_priv *priv, int mode) |
730 | { | 730 | { |
731 | const struct iwl_channel_info *ch_info; | 731 | const struct iwl_channel_info *ch_info; |
732 | 732 | ||
733 | memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon)); | 733 | memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon)); |
734 | 734 | ||
735 | switch (priv->iw_mode) { | 735 | switch (mode) { |
736 | case NL80211_IFTYPE_AP: | 736 | case NL80211_IFTYPE_AP: |
737 | priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP; | 737 | priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP; |
738 | break; | 738 | break; |
@@ -755,7 +755,7 @@ static void iwl4965_connection_init_rx_config(struct iwl_priv *priv) | |||
755 | RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK; | 755 | RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK; |
756 | break; | 756 | break; |
757 | default: | 757 | default: |
758 | IWL_ERROR("Unsupported interface type %d\n", priv->iw_mode); | 758 | IWL_ERROR("Unsupported interface type %d\n", mode); |
759 | break; | 759 | break; |
760 | } | 760 | } |
761 | 761 | ||
@@ -803,9 +803,7 @@ static void iwl4965_connection_init_rx_config(struct iwl_priv *priv) | |||
803 | 803 | ||
804 | static int iwl4965_set_mode(struct iwl_priv *priv, int mode) | 804 | static int iwl4965_set_mode(struct iwl_priv *priv, int mode) |
805 | { | 805 | { |
806 | priv->iw_mode = mode; | 806 | iwl4965_connection_init_rx_config(priv, mode); |
807 | |||
808 | iwl4965_connection_init_rx_config(priv); | ||
809 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); | 807 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); |
810 | 808 | ||
811 | iwl_clear_stations_table(priv); | 809 | iwl_clear_stations_table(priv); |
@@ -2056,7 +2054,7 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
2056 | active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 2054 | active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
2057 | } else { | 2055 | } else { |
2058 | /* Initialize our rx_config data */ | 2056 | /* Initialize our rx_config data */ |
2059 | iwl4965_connection_init_rx_config(priv); | 2057 | iwl4965_connection_init_rx_config(priv, priv->iw_mode); |
2060 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); | 2058 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); |
2061 | } | 2059 | } |
2062 | 2060 | ||
@@ -2380,7 +2378,6 @@ static void iwl4965_bg_set_monitor(struct work_struct *work) | |||
2380 | mutex_lock(&priv->mutex); | 2378 | mutex_lock(&priv->mutex); |
2381 | 2379 | ||
2382 | ret = iwl4965_set_mode(priv, NL80211_IFTYPE_MONITOR); | 2380 | ret = iwl4965_set_mode(priv, NL80211_IFTYPE_MONITOR); |
2383 | |||
2384 | if (ret) { | 2381 | if (ret) { |
2385 | if (ret == -EAGAIN) | 2382 | if (ret == -EAGAIN) |
2386 | IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n"); | 2383 | IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n"); |
@@ -2389,6 +2386,7 @@ static void iwl4965_bg_set_monitor(struct work_struct *work) | |||
2389 | } | 2386 | } |
2390 | 2387 | ||
2391 | mutex_unlock(&priv->mutex); | 2388 | mutex_unlock(&priv->mutex); |
2389 | ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC); | ||
2392 | } | 2390 | } |
2393 | 2391 | ||
2394 | static void iwl_bg_run_time_calib_work(struct work_struct *work) | 2392 | 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, | |||
2720 | 2718 | ||
2721 | spin_lock_irqsave(&priv->lock, flags); | 2719 | spin_lock_irqsave(&priv->lock, flags); |
2722 | priv->vif = conf->vif; | 2720 | priv->vif = conf->vif; |
2721 | priv->iw_mode = conf->type; | ||
2723 | 2722 | ||
2724 | spin_unlock_irqrestore(&priv->lock, flags); | 2723 | spin_unlock_irqrestore(&priv->lock, flags); |
2725 | 2724 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 9a4ffab29610..119185fb1e26 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -2175,13 +2175,14 @@ static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv, | |||
2175 | /* | 2175 | /* |
2176 | * initialize rxon structure with default values from eeprom | 2176 | * initialize rxon structure with default values from eeprom |
2177 | */ | 2177 | */ |
2178 | static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv) | 2178 | static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv, |
2179 | int mode) | ||
2179 | { | 2180 | { |
2180 | const struct iwl3945_channel_info *ch_info; | 2181 | const struct iwl3945_channel_info *ch_info; |
2181 | 2182 | ||
2182 | memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon)); | 2183 | memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon)); |
2183 | 2184 | ||
2184 | switch (priv->iw_mode) { | 2185 | switch (mode) { |
2185 | case NL80211_IFTYPE_AP: | 2186 | case NL80211_IFTYPE_AP: |
2186 | priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP; | 2187 | priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP; |
2187 | break; | 2188 | break; |
@@ -2204,7 +2205,7 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv) | |||
2204 | RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK; | 2205 | RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK; |
2205 | break; | 2206 | break; |
2206 | default: | 2207 | default: |
2207 | IWL_ERROR("Unsupported interface type %d\n", priv->iw_mode); | 2208 | IWL_ERROR("Unsupported interface type %d\n", mode); |
2208 | break; | 2209 | break; |
2209 | } | 2210 | } |
2210 | 2211 | ||
@@ -2227,8 +2228,7 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv) | |||
2227 | * in some case A channels are all non IBSS | 2228 | * in some case A channels are all non IBSS |
2228 | * in this case force B/G channel | 2229 | * in this case force B/G channel |
2229 | */ | 2230 | */ |
2230 | if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) && | 2231 | if ((mode == NL80211_IFTYPE_ADHOC) && !(is_channel_ibss(ch_info))) |
2231 | !(is_channel_ibss(ch_info))) | ||
2232 | ch_info = &priv->channel_info[0]; | 2232 | ch_info = &priv->channel_info[0]; |
2233 | 2233 | ||
2234 | priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); | 2234 | 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) | |||
2261 | } | 2261 | } |
2262 | } | 2262 | } |
2263 | 2263 | ||
2264 | priv->iw_mode = mode; | 2264 | iwl3945_connection_init_rx_config(priv, mode); |
2265 | |||
2266 | iwl3945_connection_init_rx_config(priv); | ||
2267 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); | 2265 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); |
2268 | 2266 | ||
2269 | iwl3945_clear_stations_table(priv); | 2267 | iwl3945_clear_stations_table(priv); |
@@ -5685,7 +5683,7 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv) | |||
5685 | active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 5683 | active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
5686 | } else { | 5684 | } else { |
5687 | /* Initialize our rx_config data */ | 5685 | /* Initialize our rx_config data */ |
5688 | iwl3945_connection_init_rx_config(priv); | 5686 | iwl3945_connection_init_rx_config(priv, priv->iw_mode); |
5689 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); | 5687 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); |
5690 | } | 5688 | } |
5691 | 5689 | ||
@@ -6001,6 +5999,7 @@ static void iwl3945_bg_set_monitor(struct work_struct *work) | |||
6001 | IWL_ERROR("iwl3945_set_mode() failed\n"); | 5999 | IWL_ERROR("iwl3945_set_mode() failed\n"); |
6002 | 6000 | ||
6003 | mutex_unlock(&priv->mutex); | 6001 | mutex_unlock(&priv->mutex); |
6002 | ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC); | ||
6004 | } | 6003 | } |
6005 | 6004 | ||
6006 | #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) | 6005 | #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) |
@@ -6544,6 +6543,7 @@ static int iwl3945_mac_add_interface(struct ieee80211_hw *hw, | |||
6544 | 6543 | ||
6545 | spin_lock_irqsave(&priv->lock, flags); | 6544 | spin_lock_irqsave(&priv->lock, flags); |
6546 | priv->vif = conf->vif; | 6545 | priv->vif = conf->vif; |
6546 | priv->iw_mode = conf->type; | ||
6547 | 6547 | ||
6548 | spin_unlock_irqrestore(&priv->lock, flags); | 6548 | spin_unlock_irqrestore(&priv->lock, flags); |
6549 | 6549 | ||