aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c25
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c80
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c11
5 files changed, 82 insertions, 40 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 1d58b1c7facd..ad0e67f5c0d4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2828,8 +2828,10 @@ static void iwl_alive_start(struct iwl_priv *priv)
2828 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; 2828 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
2829 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2829 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2830 } else { 2830 } else {
2831 struct iwl_rxon_context *tmp;
2831 /* Initialize our rx_config data */ 2832 /* Initialize our rx_config data */
2832 iwl_connection_init_rx_config(priv, NULL); 2833 for_each_context(priv, tmp)
2834 iwl_connection_init_rx_config(priv, tmp);
2833 2835
2834 if (priv->cfg->ops->hcmd->set_rxon_chain) 2836 if (priv->cfg->ops->hcmd->set_rxon_chain)
2835 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); 2837 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
@@ -3370,6 +3372,8 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
3370{ 3372{
3371 int ret; 3373 int ret;
3372 struct ieee80211_hw *hw = priv->hw; 3374 struct ieee80211_hw *hw = priv->hw;
3375 struct iwl_rxon_context *ctx;
3376
3373 hw->rate_control_algorithm = "iwl-agn-rs"; 3377 hw->rate_control_algorithm = "iwl-agn-rs";
3374 3378
3375 /* Tell mac80211 our characteristics */ 3379 /* Tell mac80211 our characteristics */
@@ -3389,9 +3393,10 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
3389 hw->sta_data_size = sizeof(struct iwl_station_priv); 3393 hw->sta_data_size = sizeof(struct iwl_station_priv);
3390 hw->vif_data_size = sizeof(struct iwl_vif_priv); 3394 hw->vif_data_size = sizeof(struct iwl_vif_priv);
3391 3395
3392 hw->wiphy->interface_modes = 3396 for_each_context(priv, ctx) {
3393 BIT(NL80211_IFTYPE_STATION) | 3397 hw->wiphy->interface_modes |= ctx->interface_modes;
3394 BIT(NL80211_IFTYPE_ADHOC); 3398 hw->wiphy->interface_modes |= ctx->exclusive_interface_modes;
3399 }
3395 3400
3396 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | 3401 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
3397 WIPHY_FLAG_DISABLE_BEACON_HINTS; 3402 WIPHY_FLAG_DISABLE_BEACON_HINTS;
@@ -4289,6 +4294,13 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
4289 priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; 4294 priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
4290 priv->contexts[IWL_RXON_CTX_BSS].ac_to_fifo = iwlagn_bss_ac_to_fifo; 4295 priv->contexts[IWL_RXON_CTX_BSS].ac_to_fifo = iwlagn_bss_ac_to_fifo;
4291 priv->contexts[IWL_RXON_CTX_BSS].ac_to_queue = iwlagn_bss_ac_to_queue; 4296 priv->contexts[IWL_RXON_CTX_BSS].ac_to_queue = iwlagn_bss_ac_to_queue;
4297 priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes =
4298 BIT(NL80211_IFTYPE_ADHOC);
4299 priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
4300 BIT(NL80211_IFTYPE_STATION);
4301 priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS;
4302 priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS;
4303 priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS;
4292 4304
4293 priv->contexts[IWL_RXON_CTX_PAN].rxon_cmd = REPLY_WIPAN_RXON; 4305 priv->contexts[IWL_RXON_CTX_PAN].rxon_cmd = REPLY_WIPAN_RXON;
4294 priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd = REPLY_WIPAN_RXON_TIMING; 4306 priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd = REPLY_WIPAN_RXON_TIMING;
@@ -4301,6 +4313,11 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
4301 priv->contexts[IWL_RXON_CTX_PAN].ac_to_fifo = iwlagn_pan_ac_to_fifo; 4313 priv->contexts[IWL_RXON_CTX_PAN].ac_to_fifo = iwlagn_pan_ac_to_fifo;
4302 priv->contexts[IWL_RXON_CTX_PAN].ac_to_queue = iwlagn_pan_ac_to_queue; 4314 priv->contexts[IWL_RXON_CTX_PAN].ac_to_queue = iwlagn_pan_ac_to_queue;
4303 priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE; 4315 priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE;
4316 priv->contexts[IWL_RXON_CTX_PAN].interface_modes =
4317 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP);
4318 priv->contexts[IWL_RXON_CTX_PAN].ap_devtype = RXON_DEV_TYPE_CP;
4319 priv->contexts[IWL_RXON_CTX_PAN].station_devtype = RXON_DEV_TYPE_2STA;
4320 priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P;
4304 4321
4305 BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); 4322 BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
4306 4323
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
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 4d7910001b75..f7b57ed84f66 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -394,7 +394,7 @@ bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
394 struct iwl_rxon_context *ctx, 394 struct iwl_rxon_context *ctx,
395 struct ieee80211_sta_ht_cap *ht_cap); 395 struct ieee80211_sta_ht_cap *ht_cap);
396void iwl_connection_init_rx_config(struct iwl_priv *priv, 396void iwl_connection_init_rx_config(struct iwl_priv *priv,
397 struct ieee80211_vif *vif); 397 struct iwl_rxon_context *ctx);
398void iwl_set_rate(struct iwl_priv *priv); 398void iwl_set_rate(struct iwl_priv *priv);
399int iwl_set_decrypted_flag(struct iwl_priv *priv, 399int iwl_set_decrypted_flag(struct iwl_priv *priv,
400 struct ieee80211_hdr *hdr, 400 struct ieee80211_hdr *hdr,
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 422c71e122f7..4dd38b7b8b74 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1117,6 +1117,10 @@ struct iwl_rxon_context {
1117 u8 mcast_queue; 1117 u8 mcast_queue;
1118 1118
1119 enum iwl_rxon_context_id ctxid; 1119 enum iwl_rxon_context_id ctxid;
1120
1121 u32 interface_modes, exclusive_interface_modes;
1122 u8 unused_devtype, ap_devtype, ibss_devtype, station_devtype;
1123
1120 /* 1124 /*
1121 * We declare this const so it can only be 1125 * We declare this const so it can only be
1122 * changed via explicit cast within the 1126 * changed via explicit cast within the
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 76a45b239664..68e624afb987 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -2540,7 +2540,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2540 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2540 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2541 } else { 2541 } else {
2542 /* Initialize our rx_config data */ 2542 /* Initialize our rx_config data */
2543 iwl_connection_init_rx_config(priv, NULL); 2543 iwl_connection_init_rx_config(priv, ctx);
2544 } 2544 }
2545 2545
2546 /* Configure Bluetooth device coexistence support */ 2546 /* Configure Bluetooth device coexistence support */
@@ -3955,8 +3955,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
3955 IEEE80211_HW_SUPPORTS_DYNAMIC_PS; 3955 IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
3956 3956
3957 hw->wiphy->interface_modes = 3957 hw->wiphy->interface_modes =
3958 BIT(NL80211_IFTYPE_STATION) | 3958 priv->contexts[IWL_RXON_CTX_BSS].interface_modes;
3959 BIT(NL80211_IFTYPE_ADHOC);
3960 3959
3961 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | 3960 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
3962 WIPHY_FLAG_DISABLE_BEACON_HINTS; 3961 WIPHY_FLAG_DISABLE_BEACON_HINTS;
@@ -4024,6 +4023,12 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
4024 priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; 4023 priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM;
4025 priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; 4024 priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID;
4026 priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; 4025 priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
4026 priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
4027 BIT(NL80211_IFTYPE_STATION) |
4028 BIT(NL80211_IFTYPE_ADHOC);
4029 priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS;
4030 priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS;
4031 priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS;
4027 4032
4028 /* 4033 /*
4029 * Disabling hardware scan means that mac80211 will perform scans 4034 * Disabling hardware scan means that mac80211 will perform scans