OSDN Git Service

Add rtl8821ce driver version 5.5.2
[android-x86/external-kernel-drivers.git] / rtl8821ce / hal / phydm / phydm_pow_train.c
diff --git a/rtl8821ce/hal/phydm/phydm_pow_train.c b/rtl8821ce/hal/phydm/phydm_pow_train.c
new file mode 100644 (file)
index 0000000..5339515
--- /dev/null
@@ -0,0 +1,183 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2017  Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+/*************************************************************
+ * include files
+ ************************************************************/
+
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+#ifdef PHYDM_POWER_TRAINING_SUPPORT
+void phydm_reset_pt_para(void *dm_void)
+{
+       struct dm_struct *dm = (struct dm_struct *)dm_void;
+       struct phydm_pow_train_stuc *pt_t = &dm->pow_train_table;
+
+       pt_t->pow_train_score = 0;
+}
+
+void phydm_update_power_training_state(void *dm_void)
+{
+       struct dm_struct *dm = (struct dm_struct *)dm_void;
+       struct phydm_pow_train_stuc *pt_t = &dm->pow_train_table;
+       struct phydm_fa_struct *fa_cnt = &dm->false_alm_cnt;
+       struct ccx_info *ccx = &dm->dm_ccx_info;
+       u32 pt_score_tmp = ENABLE_PT_SCORE;
+       u32 crc_ok_cnt = 0;
+       u32 cca_cnt = 0;
+
+       /*@is_disable_power_training is the key to H2C to disable/enable PT*/
+       /*@if is_disable_power_training == 1, it will use largest power*/
+       if (!(dm->support_ability & ODM_BB_PWR_TRAIN) || !dm->is_linked) {
+               dm->is_disable_power_training = true;
+               phydm_reset_pt_para(dm);
+               return;
+       }
+
+       PHYDM_DBG(dm, DBG_PWR_TRAIN, "%s ======>\n", __func__);
+
+       if (pt_t->pt_state == DISABLE_POW_TRAIN) {
+               dm->is_disable_power_training = true;
+               phydm_reset_pt_para(dm);
+               PHYDM_DBG(dm, DBG_PWR_TRAIN, "Disable PT\n");
+               return;
+
+       } else if (pt_t->pt_state == ENABLE_POW_TRAIN) {
+               dm->is_disable_power_training = false;
+               phydm_reset_pt_para(dm);
+               PHYDM_DBG(dm, DBG_PWR_TRAIN, "Enable PT\n");
+               return;
+
+       } else if (pt_t->pt_state == DYNAMIC_POW_TRAIN) {
+               PHYDM_DBG(dm, DBG_PWR_TRAIN, "Dynamic PT\n");
+
+               /* @Compute score */
+               crc_ok_cnt = dm->phy_dbg_info.num_qry_phy_status_ofdm +
+                            dm->phy_dbg_info.num_qry_phy_status_cck;
+               cca_cnt = fa_cnt->cnt_cca_all;
+#if 0
+               if (crc_ok_cnt > cca_cnt) { /*invalid situation*/
+                       pt_score_tmp = KEEP_PRE_PT_SCORE;
+                       return;
+               } else if ((crc_ok_cnt + (crc_ok_cnt >> 1)) <= cca_cnt) {
+               /* @???crc_ok <= (2/3)*cca */
+                       pt_score_tmp = DISABLE_PT_SCORE;
+                       dm->is_disable_power_training = true;
+               } else if ((crc_ok_cnt + (crc_ok_cnt >> 2)) <= cca_cnt) {
+               /* @???crc_ok <= (4/5)*cca */
+                       pt_score_tmp = KEEP_PRE_PT_SCORE;
+               } else {
+               /* @???crc_ok > (4/5)*cca */
+                       pt_score_tmp = ENABLE_PT_SCORE;
+                       dm->is_disable_power_training = false;
+               }
+#endif
+               if (ccx->nhm_ratio > 10) {
+                       pt_score_tmp = DISABLE_PT_SCORE;
+                       dm->is_disable_power_training = true;
+               } else if (ccx->nhm_ratio < 5) {
+                       pt_score_tmp = ENABLE_PT_SCORE;
+                       dm->is_disable_power_training = false;
+               } else {
+                       pt_score_tmp = KEEP_PRE_PT_SCORE;
+               }
+
+               PHYDM_DBG(dm, DBG_PWR_TRAIN,
+                         "pkt_cnt{ofdm,cck,all} = {%d, %d, %d}, cnt_cca_all=%d\n",
+                         dm->phy_dbg_info.num_qry_phy_status_ofdm,
+                         dm->phy_dbg_info.num_qry_phy_status_cck,
+                         crc_ok_cnt, cca_cnt);
+
+               PHYDM_DBG(dm, DBG_PWR_TRAIN, "pt_score_tmp=%d\n", pt_score_tmp);
+
+               /* smoothing */
+               pt_t->pow_train_score = (pt_score_tmp << 4) +
+                                       (pt_t->pow_train_score >> 1) +
+                                       (pt_t->pow_train_score >> 2);
+
+               pt_score_tmp = (pt_t->pow_train_score + 32) >> 6;
+
+               PHYDM_DBG(dm, DBG_PWR_TRAIN,
+                         "pow_train_score = %d, score after smoothing = %d, is_disable_PT = %d\n",
+                         pt_t->pow_train_score, pt_score_tmp,
+                         dm->is_disable_power_training);
+       } else {
+               PHYDM_DBG(dm, DBG_PWR_TRAIN, "[%s]warning\n", __func__);
+       }
+}
+
+void phydm_pow_train_debug(
+       void *dm_void,
+       char input[][16],
+       u32 *_used,
+       char *output,
+       u32 *_out_len)
+{
+       struct dm_struct *dm = (struct dm_struct *)dm_void;
+       struct phydm_pow_train_stuc *pt_t = &dm->pow_train_table;
+       char help[] = "-h";
+       u32 var1[10] = {0};
+       u32 used = *_used;
+       u32 out_len = *_out_len;
+       u32 i;
+
+       if ((strcmp(input[1], help) == 0)) {
+               PDM_SNPF(out_len, used, output + used, out_len - used,
+                        "0: Dynamic state\n");
+               PDM_SNPF(out_len, used, output + used, out_len - used,
+                        "1: Enable PT\n");
+               PDM_SNPF(out_len, used, output + used, out_len - used,
+                        "2: Disable PT\n");
+
+       } else {
+               for (i = 0; i < 10; i++) {
+                       if (input[i + 1])
+                               PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]);
+               }
+
+               if (var1[0] == 0) {
+                       pt_t->pt_state = DYNAMIC_POW_TRAIN;
+                       PDM_SNPF(out_len, used, output + used, out_len - used,
+                                "Dynamic state\n");
+               } else if (var1[0] == 1) {
+                       pt_t->pt_state = ENABLE_POW_TRAIN;
+                       PDM_SNPF(out_len, used, output + used, out_len - used,
+                                "Enable PT\n");
+               } else if (var1[0] == 2) {
+                       pt_t->pt_state = DISABLE_POW_TRAIN;
+                       PDM_SNPF(out_len, used, output + used, out_len - used,
+                                "Disable PT\n");
+               } else {
+                       PDM_SNPF(out_len, used, output + used, out_len - used,
+                                "Set Error\n");
+               }
+       }
+
+       *_used = used;
+       *_out_len = out_len;
+}
+
+#endif