aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhu, Yi <yi.zhu@intel.com>2008-10-29 17:05:45 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-11-10 15:17:36 -0500
commit60294de3af99586bb4a205274d02a7c8b910c0c3 (patch)
tree5f28e0bbb7286ed379c34544e7dfa78f9d212743
parenteb4779c40549f8e0dd45c9a30f279134c9a86131 (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.c15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c18
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 */
729static void iwl4965_connection_init_rx_config(struct iwl_priv *priv) 729static 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
804static int iwl4965_set_mode(struct iwl_priv *priv, int mode) 804static 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
2394static void iwl_bg_run_time_calib_work(struct work_struct *work) 2392static 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 */
2178static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv) 2178static 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