if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
+ if (!ctx->is_active)
+ return;
+
ctx->qos_data.def_qos_parm.qos_flags = 0;
if (ctx->qos_data.qos_active)
static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val)
{
- u16 new_val = 0;
- u16 beacon_factor = 0;
+ u16 new_val;
+ u16 beacon_factor;
+
+ /*
+ * If mac80211 hasn't given us a beacon interval, program
+ * the default into the device (not checking this here
+ * would cause the adjustment below to return the maximum
+ * value, which may break PAN.)
+ */
+ if (!beacon_val)
+ return DEFAULT_BEACON_INTERVAL;
+
+ /*
+ * If the beacon interval we obtained from the peer
+ * is too large, we'll have to wake up more often
+ * (and in IBSS case, we'll beacon too much)
+ *
+ * For example, if max_beacon_val is 4096, and the
+ * requested beacon interval is 7000, we'll have to
+ * use 3500 to be able to wake up on the beacons.
+ *
+ * This could badly influence beacon detection stats.
+ */
beacon_factor = (beacon_val + max_beacon_val) / max_beacon_val;
new_val = beacon_val / beacon_factor;
ctx->timing.atim_window = 0;
if (ctx->ctxid == IWL_RXON_CTX_PAN &&
- (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION)) {
+ (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION) &&
+ iwl_is_associated(priv, IWL_RXON_CTX_BSS) &&
+ priv->contexts[IWL_RXON_CTX_BSS].vif &&
+ priv->contexts[IWL_RXON_CTX_BSS].vif->bss_conf.beacon_int) {
ctx->timing.beacon_interval =
priv->contexts[IWL_RXON_CTX_BSS].timing.beacon_interval;
beacon_int = le16_to_cpu(ctx->timing.beacon_interval);
+ } else if (ctx->ctxid == IWL_RXON_CTX_BSS &&
+ iwl_is_associated(priv, IWL_RXON_CTX_PAN) &&
+ priv->contexts[IWL_RXON_CTX_PAN].vif &&
+ priv->contexts[IWL_RXON_CTX_PAN].vif->bss_conf.beacon_int &&
+ (!iwl_is_associated_ctx(ctx) || !ctx->vif ||
+ !ctx->vif->bss_conf.beacon_int)) {
+ ctx->timing.beacon_interval =
+ priv->contexts[IWL_RXON_CTX_PAN].timing.beacon_interval;
+ beacon_int = le16_to_cpu(ctx->timing.beacon_interval);
} else {
beacon_int = iwl_adjust_beacon_interval(beacon_int,
priv->hw_params.max_beacon_itrvl * TIME_UNIT);
*/
priv->iw_mode = vif->type;
+ ctx->is_active = true;
+
err = iwl_set_mode(priv, vif);
- if (err)
+ if (err) {
+ if (!ctx->always_active)
+ ctx->is_active = false;
goto out_err;
+ }
if (priv->cfg->advanced_bt_coexist &&
vif->type == NL80211_IFTYPE_ADHOC) {
{
struct iwl_priv *priv = hw->priv;
struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
- bool scan_completed = false;
IWL_DEBUG_MAC80211(priv, "enter\n");
WARN_ON(ctx->vif != vif);
ctx->vif = NULL;
- iwl_scan_cancel_timeout(priv, 100);
- iwl_set_mode(priv, vif);
-
if (priv->scan_vif == vif) {
- scan_completed = true;
- priv->scan_vif = NULL;
- priv->scan_request = NULL;
+ iwl_scan_cancel_timeout(priv, 200);
+ iwl_force_scan_end(priv);
}
+ iwl_set_mode(priv, vif);
+
+ if (!ctx->always_active)
+ ctx->is_active = false;
/*
* When removing the IBSS interface, overwrite the
memset(priv->bssid, 0, ETH_ALEN);
mutex_unlock(&priv->mutex);
- if (scan_completed)
- ieee80211_scan_completed(priv->hw, true);
-
IWL_DEBUG_MAC80211(priv, "leave\n");
}
spin_unlock_irqrestore(&priv->lock, flags);
+ iwl_scan_cancel_timeout(priv, 100);
if (!iwl_is_ready_rf(priv)) {
IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
mutex_unlock(&priv->mutex);
/* we are restarting association process
* clear RXON_FILTER_ASSOC_MSK bit
*/
- iwl_scan_cancel_timeout(priv, 100);
ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwlcore_commit_rxon(priv, ctx);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return -EINVAL;
+ if (test_bit(STATUS_SCANNING, &priv->status)) {
+ IWL_DEBUG_INFO(priv, "scan in progress.\n");
+ return -EINVAL;
+ }
+
if (mode >= IWL_MAX_FORCE_RESET) {
IWL_DEBUG_INFO(priv, "invalid reset request.\n");
return -EINVAL;