static u16 iwl_limit_dwell(struct iwl_priv *priv, u16 dwell_time)
 {
        struct iwl_rxon_context *ctx;
+       int limits[NUM_IWL_RXON_CTX] = {};
+       int n_active = 0;
+       u16 limit;
+
+       BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
 
        /*
         * If we're associated, we clamp the dwell time 98%
-        * of the smallest beacon interval (minus 2 * channel
-        * tune time)
+        * of the beacon interval (minus 2 * channel tune time)
+        * If both contexts are active, we have to restrict to
+        * 1/2 of the minimum of them, because they might be in
+        * lock-step with the time inbetween only half of what
+        * time we'd have in each of them.
         */
        for_each_context(priv, ctx) {
-               u16 value;
-
                switch (ctx->staging.dev_type) {
                case RXON_DEV_TYPE_P2P:
                        /* no timing constraints */
                        break;
                }
 
-               value = ctx->beacon_int;
-               if (!value)
-                       value = IWL_PASSIVE_DWELL_BASE;
-               value = (value * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
-               dwell_time = min(value, dwell_time);
+               limits[n_active++] = ctx->beacon_int ?: IWL_PASSIVE_DWELL_BASE;
        }
 
-       return dwell_time;
+       switch (n_active) {
+       case 0:
+               return dwell_time;
+       case 2:
+               limit = (limits[1] * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
+               limit /= 2;
+               dwell_time = min(limit, dwell_time);
+               /* fall through to limit further */
+       case 1:
+               limit = (limits[0] * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
+               limit /= n_active;
+               return min(limit, dwell_time);
+       default:
+               WARN_ON_ONCE(1);
+               return dwell_time;
+       }
 }
 
 static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,