aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-core.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-08-23 04:46:58 -0400
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2010-08-27 12:49:38 -0400
commitd0fe478c9f42dbc4916aa8d1d7a05d7f669d2209 (patch)
treebb710248e2298dffa76fd336a74b647947140d1f /drivers/net/wireless/iwlwifi/iwl-core.c
parentbde4530e9d2fa013b5674e4c9b066ed6d87ab45c (diff)
iwlwifi: allow using multiple contexts
We're now ready to start using multiple contexts. We do this by keeping track of the valid interface types per context (exclusive [ibss] and normal) and checking which context is "free" when a new interface is added. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-core.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c80
1 files changed, 48 insertions, 32 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index a2b39fd4081e..87a2e40972ba 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1028,38 +1028,34 @@ EXPORT_SYMBOL(iwl_set_flags_for_band);
1028 * initialize rxon structure with default values from eeprom 1028 * initialize rxon structure with default values from eeprom
1029 */ 1029 */
1030void iwl_connection_init_rx_config(struct iwl_priv *priv, 1030void iwl_connection_init_rx_config(struct iwl_priv *priv,
1031 struct ieee80211_vif *vif) 1031 struct iwl_rxon_context *ctx)
1032{ 1032{
1033 const struct iwl_channel_info *ch_info; 1033 const struct iwl_channel_info *ch_info;
1034 enum nl80211_iftype type = NL80211_IFTYPE_STATION;
1035 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
1036
1037 if (vif) {
1038 type = vif->type;
1039 ctx = iwl_rxon_ctx_from_vif(vif);
1040 }
1041 1034
1042 memset(&ctx->staging, 0, sizeof(ctx->staging)); 1035 memset(&ctx->staging, 0, sizeof(ctx->staging));
1043 1036
1044 switch (type) { 1037 if (!ctx->vif) {
1038 ctx->staging.dev_type = ctx->unused_devtype;
1039 } else switch (ctx->vif->type) {
1045 case NL80211_IFTYPE_AP: 1040 case NL80211_IFTYPE_AP:
1046 ctx->staging.dev_type = RXON_DEV_TYPE_AP; 1041 ctx->staging.dev_type = ctx->ap_devtype;
1047 break; 1042 break;
1048 1043
1049 case NL80211_IFTYPE_STATION: 1044 case NL80211_IFTYPE_STATION:
1050 ctx->staging.dev_type = RXON_DEV_TYPE_ESS; 1045 ctx->staging.dev_type = ctx->station_devtype;
1051 ctx->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; 1046 ctx->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
1052 break; 1047 break;
1053 1048
1054 case NL80211_IFTYPE_ADHOC: 1049 case NL80211_IFTYPE_ADHOC:
1055 ctx->staging.dev_type = RXON_DEV_TYPE_IBSS; 1050 ctx->staging.dev_type = ctx->ibss_devtype;
1056 ctx->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK; 1051 ctx->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
1057 ctx->staging.filter_flags = RXON_FILTER_BCON_AWARE_MSK | 1052 ctx->staging.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
1058 RXON_FILTER_ACCEPT_GRP_MSK; 1053 RXON_FILTER_ACCEPT_GRP_MSK;
1059 break; 1054 break;
1060 1055
1061 default: 1056 default:
1062 IWL_ERR(priv, "Unsupported interface type %d\n", type); 1057 IWL_ERR(priv, "Unsupported interface type %d\n",
1058 ctx->vif->type);
1063 break; 1059 break;
1064 } 1060 }
1065 1061
@@ -1081,7 +1077,7 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv,
1081 ctx->staging.channel = cpu_to_le16(ch_info->channel); 1077 ctx->staging.channel = cpu_to_le16(ch_info->channel);
1082 priv->band = ch_info->band; 1078 priv->band = ch_info->band;
1083 1079
1084 iwl_set_flags_for_band(priv, ctx, priv->band, vif); 1080 iwl_set_flags_for_band(priv, ctx, priv->band, ctx->vif);
1085 1081
1086 ctx->staging.ofdm_basic_rates = 1082 ctx->staging.ofdm_basic_rates =
1087 (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; 1083 (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
@@ -1091,8 +1087,8 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv,
1091 /* clear both MIX and PURE40 mode flag */ 1087 /* clear both MIX and PURE40 mode flag */
1092 ctx->staging.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED | 1088 ctx->staging.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED |
1093 RXON_FLG_CHANNEL_MODE_PURE_40); 1089 RXON_FLG_CHANNEL_MODE_PURE_40);
1094 if (vif) 1090 if (ctx->vif)
1095 memcpy(ctx->staging.node_addr, vif->addr, ETH_ALEN); 1091 memcpy(ctx->staging.node_addr, ctx->vif->addr, ETH_ALEN);
1096 1092
1097 ctx->staging.ofdm_ht_single_stream_basic_rates = 0xff; 1093 ctx->staging.ofdm_ht_single_stream_basic_rates = 0xff;
1098 ctx->staging.ofdm_ht_dual_stream_basic_rates = 0xff; 1094 ctx->staging.ofdm_ht_dual_stream_basic_rates = 0xff;
@@ -1952,7 +1948,7 @@ static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif)
1952{ 1948{
1953 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); 1949 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
1954 1950
1955 iwl_connection_init_rx_config(priv, vif); 1951 iwl_connection_init_rx_config(priv, ctx);
1956 1952
1957 if (priv->cfg->ops->hcmd->set_rxon_chain) 1953 if (priv->cfg->ops->hcmd->set_rxon_chain)
1958 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); 1954 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
@@ -1964,7 +1960,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1964{ 1960{
1965 struct iwl_priv *priv = hw->priv; 1961 struct iwl_priv *priv = hw->priv;
1966 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; 1962 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
1967 struct iwl_rxon_context *ctx; 1963 struct iwl_rxon_context *tmp, *ctx = NULL;
1968 int err = 0; 1964 int err = 0;
1969 1965
1970 IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", 1966 IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n",
@@ -1972,23 +1968,45 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1972 1968
1973 mutex_lock(&priv->mutex); 1969 mutex_lock(&priv->mutex);
1974 1970
1975 /* For now always use this context. */
1976 ctx = &priv->contexts[IWL_RXON_CTX_BSS];
1977
1978 vif_priv->ctx = ctx;
1979
1980 if (WARN_ON(!iwl_is_ready_rf(priv))) { 1971 if (WARN_ON(!iwl_is_ready_rf(priv))) {
1981 err = -EINVAL; 1972 err = -EINVAL;
1982 goto out; 1973 goto out;
1983 } 1974 }
1984 1975
1985 if (ctx->vif) { 1976 for_each_context(priv, tmp) {
1986 IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n"); 1977 u32 possible_modes =
1978 tmp->interface_modes | tmp->exclusive_interface_modes;
1979
1980 if (tmp->vif) {
1981 /* check if this busy context is exclusive */
1982 if (tmp->exclusive_interface_modes &
1983 BIT(tmp->vif->type)) {
1984 err = -EINVAL;
1985 goto out;
1986 }
1987 continue;
1988 }
1989
1990 if (!(possible_modes & BIT(vif->type)))
1991 continue;
1992
1993 /* have maybe usable context w/o interface */
1994 ctx = tmp;
1995 break;
1996 }
1997
1998 if (!ctx) {
1987 err = -EOPNOTSUPP; 1999 err = -EOPNOTSUPP;
1988 goto out; 2000 goto out;
1989 } 2001 }
1990 2002
2003 vif_priv->ctx = ctx;
1991 ctx->vif = vif; 2004 ctx->vif = vif;
2005 /*
2006 * This variable will be correct only when there's just
2007 * a single context, but all code using it is for hardware
2008 * that supports only one context.
2009 */
1992 priv->iw_mode = vif->type; 2010 priv->iw_mode = vif->type;
1993 2011
1994 err = iwl_set_mode(priv, vif); 2012 err = iwl_set_mode(priv, vif);
@@ -2029,11 +2047,11 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
2029 2047
2030 mutex_lock(&priv->mutex); 2048 mutex_lock(&priv->mutex);
2031 2049
2032 if (iwl_is_ready_rf(priv)) { 2050 WARN_ON(ctx->vif != vif);
2033 iwl_scan_cancel_timeout(priv, 100); 2051 ctx->vif = NULL;
2034 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2052
2035 iwlcore_commit_rxon(priv, ctx); 2053 iwl_scan_cancel_timeout(priv, 100);
2036 } 2054 iwl_set_mode(priv, vif);
2037 2055
2038 if (priv->scan_vif == vif) { 2056 if (priv->scan_vif == vif) {
2039 scan_completed = true; 2057 scan_completed = true;
@@ -2051,8 +2069,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
2051 if (vif->type == NL80211_IFTYPE_ADHOC) 2069 if (vif->type == NL80211_IFTYPE_ADHOC)
2052 priv->bt_traffic_load = priv->notif_bt_traffic_load; 2070 priv->bt_traffic_load = priv->notif_bt_traffic_load;
2053 2071
2054 WARN_ON(ctx->vif != vif);
2055 ctx->vif = NULL;
2056 memset(priv->bssid, 0, ETH_ALEN); 2072 memset(priv->bssid, 0, ETH_ALEN);
2057 mutex_unlock(&priv->mutex); 2073 mutex_unlock(&priv->mutex);
2058 2074