diff options
author | Eyal Shapira <eyal@wizery.com> | 2015-01-28 07:44:06 -0500 |
---|---|---|
committer | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2015-02-01 08:39:29 -0500 |
commit | 1e9c62fa9158f35dfd73ef6231154710154e6e09 (patch) | |
tree | f3c1fae598e0642106c70c7cd75c8e3a05082b55 | |
parent | 3d44eebf773950dd2e24ad7ac786b589d6522d67 (diff) |
iwlwifi: mvm: rs: enable forcing single stream Tx decision
In certain testing scenarios we'd like to force a decision
between STBC/BFER/SISO. In the normal scenario this decision
is done by the FW. Enable this option vis debugfs.
Signed-off-by: Eyal Shapira <eyalx.shapira@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h | 8 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/rs.c | 84 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/rs.h | 10 |
3 files changed, 102 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h index 4c33f2775dc9..0f1ea80a55ef 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h | |||
@@ -330,6 +330,14 @@ enum { | |||
330 | #define LQ_SS_BFER_ALLOWED_POS 2 | 330 | #define LQ_SS_BFER_ALLOWED_POS 2 |
331 | #define LQ_SS_BFER_ALLOWED (1 << LQ_SS_BFER_ALLOWED_POS) | 331 | #define LQ_SS_BFER_ALLOWED (1 << LQ_SS_BFER_ALLOWED_POS) |
332 | 332 | ||
333 | /* Bit 3: Force BFER or STBC for testing | ||
334 | * If this is set: | ||
335 | * If BFER is allowed then force the ucode to choose BFER else | ||
336 | * If STBC is allowed then force the ucode to choose STBC over SISO | ||
337 | */ | ||
338 | #define LQ_SS_FORCE_POS 3 | ||
339 | #define LQ_SS_FORCE (1 << LQ_SS_FORCE_POS) | ||
340 | |||
333 | /* Bit 31: ss_params field is valid. Used for FW backward compatibility | 341 | /* Bit 31: ss_params field is valid. Used for FW backward compatibility |
334 | * with other drivers which don't support the ss_params API yet | 342 | * with other drivers which don't support the ss_params API yet |
335 | */ | 343 | */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index 95b718b4f8ab..194bd1f939ca 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include "sta.h" | 39 | #include "sta.h" |
40 | #include "iwl-op-mode.h" | 40 | #include "iwl-op-mode.h" |
41 | #include "mvm.h" | 41 | #include "mvm.h" |
42 | #include "debugfs.h" | ||
42 | 43 | ||
43 | #define RS_NAME "iwl-mvm-rs" | 44 | #define RS_NAME "iwl-mvm-rs" |
44 | 45 | ||
@@ -3057,6 +3058,20 @@ static void rs_set_lq_ss_params(struct iwl_mvm *mvm, | |||
3057 | if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) | 3058 | if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) |
3058 | goto out; | 3059 | goto out; |
3059 | 3060 | ||
3061 | /* Check if forcing the decision is configured. | ||
3062 | * Note that SISO is forced by not allowing STBC or BFER | ||
3063 | */ | ||
3064 | if (lq_sta->ss_force == RS_SS_FORCE_STBC) | ||
3065 | ss_params |= (LQ_SS_STBC_1SS_ALLOWED | LQ_SS_FORCE); | ||
3066 | else if (lq_sta->ss_force == RS_SS_FORCE_BFER) | ||
3067 | ss_params |= (LQ_SS_BFER_ALLOWED | LQ_SS_FORCE); | ||
3068 | |||
3069 | if (lq_sta->ss_force != RS_SS_FORCE_NONE) { | ||
3070 | IWL_DEBUG_RATE(mvm, "Forcing single stream Tx decision %d\n", | ||
3071 | lq_sta->ss_force); | ||
3072 | goto out; | ||
3073 | } | ||
3074 | |||
3060 | if (lq_sta->stbc_capable) | 3075 | if (lq_sta->stbc_capable) |
3061 | ss_params |= LQ_SS_STBC_1SS_ALLOWED; | 3076 | ss_params |= LQ_SS_STBC_1SS_ALLOWED; |
3062 | 3077 | ||
@@ -3502,9 +3517,73 @@ static const struct file_operations rs_sta_dbgfs_drv_tx_stats_ops = { | |||
3502 | .llseek = default_llseek, | 3517 | .llseek = default_llseek, |
3503 | }; | 3518 | }; |
3504 | 3519 | ||
3520 | static ssize_t iwl_dbgfs_ss_force_read(struct file *file, | ||
3521 | char __user *user_buf, | ||
3522 | size_t count, loff_t *ppos) | ||
3523 | { | ||
3524 | struct iwl_lq_sta *lq_sta = file->private_data; | ||
3525 | char buf[12]; | ||
3526 | int bufsz = sizeof(buf); | ||
3527 | int pos = 0; | ||
3528 | static const char * const ss_force_name[] = { | ||
3529 | [RS_SS_FORCE_NONE] = "none", | ||
3530 | [RS_SS_FORCE_STBC] = "stbc", | ||
3531 | [RS_SS_FORCE_BFER] = "bfer", | ||
3532 | [RS_SS_FORCE_SISO] = "siso", | ||
3533 | }; | ||
3534 | |||
3535 | pos += scnprintf(buf+pos, bufsz-pos, "%s\n", | ||
3536 | ss_force_name[lq_sta->ss_force]); | ||
3537 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
3538 | } | ||
3539 | |||
3540 | static ssize_t iwl_dbgfs_ss_force_write(struct iwl_lq_sta *lq_sta, char *buf, | ||
3541 | size_t count, loff_t *ppos) | ||
3542 | { | ||
3543 | struct iwl_mvm *mvm = lq_sta->pers.drv; | ||
3544 | int ret = 0; | ||
3545 | |||
3546 | if (!strncmp("none", buf, 4)) { | ||
3547 | lq_sta->ss_force = RS_SS_FORCE_NONE; | ||
3548 | } else if (!strncmp("siso", buf, 4)) { | ||
3549 | lq_sta->ss_force = RS_SS_FORCE_SISO; | ||
3550 | } else if (!strncmp("stbc", buf, 4)) { | ||
3551 | if (lq_sta->stbc_capable) { | ||
3552 | lq_sta->ss_force = RS_SS_FORCE_STBC; | ||
3553 | } else { | ||
3554 | IWL_ERR(mvm, | ||
3555 | "can't force STBC. peer doesn't support\n"); | ||
3556 | ret = -EINVAL; | ||
3557 | } | ||
3558 | } else if (!strncmp("bfer", buf, 4)) { | ||
3559 | if (lq_sta->bfer_capable) { | ||
3560 | lq_sta->ss_force = RS_SS_FORCE_BFER; | ||
3561 | } else { | ||
3562 | IWL_ERR(mvm, | ||
3563 | "can't force BFER. peer doesn't support\n"); | ||
3564 | ret = -EINVAL; | ||
3565 | } | ||
3566 | } else { | ||
3567 | IWL_ERR(mvm, "valid values none|siso|stbc|bfer\n"); | ||
3568 | ret = -EINVAL; | ||
3569 | } | ||
3570 | return ret ?: count; | ||
3571 | } | ||
3572 | |||
3573 | #define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \ | ||
3574 | _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_lq_sta) | ||
3575 | #define MVM_DEBUGFS_ADD_FILE_RS(name, parent, mode) do { \ | ||
3576 | if (!debugfs_create_file(#name, mode, parent, lq_sta, \ | ||
3577 | &iwl_dbgfs_##name##_ops)) \ | ||
3578 | goto err; \ | ||
3579 | } while (0) | ||
3580 | |||
3581 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(ss_force, 32); | ||
3582 | |||
3505 | static void rs_add_debugfs(void *mvm, void *mvm_sta, struct dentry *dir) | 3583 | static void rs_add_debugfs(void *mvm, void *mvm_sta, struct dentry *dir) |
3506 | { | 3584 | { |
3507 | struct iwl_lq_sta *lq_sta = mvm_sta; | 3585 | struct iwl_lq_sta *lq_sta = mvm_sta; |
3586 | |||
3508 | debugfs_create_file("rate_scale_table", S_IRUSR | S_IWUSR, dir, | 3587 | debugfs_create_file("rate_scale_table", S_IRUSR | S_IWUSR, dir, |
3509 | lq_sta, &rs_sta_dbgfs_scale_table_ops); | 3588 | lq_sta, &rs_sta_dbgfs_scale_table_ops); |
3510 | debugfs_create_file("rate_stats_table", S_IRUSR, dir, | 3589 | debugfs_create_file("rate_stats_table", S_IRUSR, dir, |
@@ -3515,6 +3594,11 @@ static void rs_add_debugfs(void *mvm, void *mvm_sta, struct dentry *dir) | |||
3515 | &lq_sta->tx_agg_tid_en); | 3594 | &lq_sta->tx_agg_tid_en); |
3516 | debugfs_create_u8("reduced_tpc", S_IRUSR | S_IWUSR, dir, | 3595 | debugfs_create_u8("reduced_tpc", S_IRUSR | S_IWUSR, dir, |
3517 | &lq_sta->pers.dbg_fixed_txp_reduction); | 3596 | &lq_sta->pers.dbg_fixed_txp_reduction); |
3597 | |||
3598 | MVM_DEBUGFS_ADD_FILE_RS(ss_force, dir, S_IRUSR | S_IWUSR); | ||
3599 | return; | ||
3600 | err: | ||
3601 | IWL_ERR((struct iwl_mvm *)mvm, "Can't create debugfs entity\n"); | ||
3518 | } | 3602 | } |
3519 | 3603 | ||
3520 | static void rs_remove_debugfs(void *mvm, void *mvm_sta) | 3604 | static void rs_remove_debugfs(void *mvm, void *mvm_sta) |
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h index ba57f5ae2375..dc4ef3dfafe1 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.h +++ b/drivers/net/wireless/iwlwifi/mvm/rs.h | |||
@@ -240,6 +240,13 @@ enum rs_column { | |||
240 | RS_COLUMN_INVALID, | 240 | RS_COLUMN_INVALID, |
241 | }; | 241 | }; |
242 | 242 | ||
243 | enum rs_ss_force_opt { | ||
244 | RS_SS_FORCE_NONE = 0, | ||
245 | RS_SS_FORCE_STBC, | ||
246 | RS_SS_FORCE_BFER, | ||
247 | RS_SS_FORCE_SISO, | ||
248 | }; | ||
249 | |||
243 | /* Packet stats per rate */ | 250 | /* Packet stats per rate */ |
244 | struct rs_rate_stats { | 251 | struct rs_rate_stats { |
245 | u64 success; | 252 | u64 success; |
@@ -324,6 +331,9 @@ struct iwl_lq_sta { | |||
324 | /* tx power reduce for this sta */ | 331 | /* tx power reduce for this sta */ |
325 | int tpc_reduce; | 332 | int tpc_reduce; |
326 | 333 | ||
334 | /* force STBC/BFER/SISO for testing */ | ||
335 | enum rs_ss_force_opt ss_force; | ||
336 | |||
327 | /* persistent fields - initialized only once - keep last! */ | 337 | /* persistent fields - initialized only once - keep last! */ |
328 | struct lq_sta_pers { | 338 | struct lq_sta_pers { |
329 | #ifdef CONFIG_MAC80211_DEBUGFS | 339 | #ifdef CONFIG_MAC80211_DEBUGFS |