aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/dvm/scan.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-06-22 09:57:55 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-06-25 08:53:43 -0400
commitb3a6d2e0e727c3b126093c9b5fcdf41dd12bc4fd (patch)
tree62b040233659b78e0408b2d3c5bfd538728fcad1 /drivers/net/wireless/iwlwifi/dvm/scan.c
parent94bfa4a255b3436e9a258585be6687d1f5c02a71 (diff)
iwlwifi: limit dwell time more strictly
The dwell time for scanning is currently limited so that it fits into the timings inside the ucode when that is tracking DTIM/beacon periods for the AP(s) it's connected to. However, when it's connected to two APs, those may be in lockstep, for example if they both have a DTIM interval of 100 TU, then one could be 50 TU after the other, leaving only 50 TU free to be used by scanning. Since we can't know how far apart they are the only option is to restrict to 1/2 of the minium of the two APs. In theory, it would be possible to not use 1/2 of the minimum but take into account that if they have different intervals then there will be a bit more time since they can't be in lockstep, but as they will have 100 TU intervals in practice that complex calculation will probably just result in hard-to-find bugs. Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/dvm/scan.c')
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/scan.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/drivers/net/wireless/iwlwifi/dvm/scan.c b/drivers/net/wireless/iwlwifi/dvm/scan.c
index 6633074258c7..e3467fa86899 100644
--- a/drivers/net/wireless/iwlwifi/dvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/dvm/scan.c
@@ -396,15 +396,21 @@ static u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
396static u16 iwl_limit_dwell(struct iwl_priv *priv, u16 dwell_time) 396static u16 iwl_limit_dwell(struct iwl_priv *priv, u16 dwell_time)
397{ 397{
398 struct iwl_rxon_context *ctx; 398 struct iwl_rxon_context *ctx;
399 int limits[NUM_IWL_RXON_CTX] = {};
400 int n_active = 0;
401 u16 limit;
402
403 BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
399 404
400 /* 405 /*
401 * If we're associated, we clamp the dwell time 98% 406 * If we're associated, we clamp the dwell time 98%
402 * of the smallest beacon interval (minus 2 * channel 407 * of the beacon interval (minus 2 * channel tune time)
403 * tune time) 408 * If both contexts are active, we have to restrict to
409 * 1/2 of the minimum of them, because they might be in
410 * lock-step with the time inbetween only half of what
411 * time we'd have in each of them.
404 */ 412 */
405 for_each_context(priv, ctx) { 413 for_each_context(priv, ctx) {
406 u16 value;
407
408 switch (ctx->staging.dev_type) { 414 switch (ctx->staging.dev_type) {
409 case RXON_DEV_TYPE_P2P: 415 case RXON_DEV_TYPE_P2P:
410 /* no timing constraints */ 416 /* no timing constraints */
@@ -424,14 +430,25 @@ static u16 iwl_limit_dwell(struct iwl_priv *priv, u16 dwell_time)
424 break; 430 break;
425 } 431 }
426 432
427 value = ctx->beacon_int; 433 limits[n_active++] = ctx->beacon_int ?: IWL_PASSIVE_DWELL_BASE;
428 if (!value)
429 value = IWL_PASSIVE_DWELL_BASE;
430 value = (value * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
431 dwell_time = min(value, dwell_time);
432 } 434 }
433 435
434 return dwell_time; 436 switch (n_active) {
437 case 0:
438 return dwell_time;
439 case 2:
440 limit = (limits[1] * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
441 limit /= 2;
442 dwell_time = min(limit, dwell_time);
443 /* fall through to limit further */
444 case 1:
445 limit = (limits[0] * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
446 limit /= n_active;
447 return min(limit, dwell_time);
448 default:
449 WARN_ON_ONCE(1);
450 return dwell_time;
451 }
435} 452}
436 453
437static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, 454static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,