xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8822cs/hal/phydm/phydm_cck_rx_pathdiv.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2017  Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * The full GNU General Public License is included in this distribution in the
15  * file called LICENSE.
16  *
17  * Contact Information:
18  * wlanfae <wlanfae@realtek.com>
19  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20  * Hsinchu 300, Taiwan.
21  *
22  * Larry Finger <Larry.Finger@lwfinger.net>
23  *
24  *****************************************************************************/
25 
26 /*@************************************************************
27  * include files
28  ************************************************************/
29 
30 #include "mp_precomp.h"
31 #include "phydm_precomp.h"
32 
33 #ifdef PHYDM_CCK_RX_PATHDIV_SUPPORT /* @PHYDM-342*/
phydm_cck_rx_pathdiv_manaul(void * dm_void,boolean en_cck_rx_pathdiv)34 void phydm_cck_rx_pathdiv_manaul(void *dm_void, boolean en_cck_rx_pathdiv)
35 {
36 	struct dm_struct *dm = (struct dm_struct *)dm_void;
37 
38 	/* @Can not apply for 98F/14B/97G from DD YC*/
39 	if (en_cck_rx_pathdiv) {
40 		odm_set_bb_reg(dm, R_0x1a14, BIT(7), 0x0);
41 		odm_set_bb_reg(dm, R_0x1a74, BIT(8), 0x1);
42 	} else {
43 		odm_set_bb_reg(dm, R_0x1a14, BIT(7), 0x1);
44 		odm_set_bb_reg(dm, R_0x1a74, BIT(8), 0x0);
45 	}
46 }
47 
phydm_cck_rx_pathdiv_watchdog(void * dm_void)48 void phydm_cck_rx_pathdiv_watchdog(void *dm_void)
49 {
50 	struct dm_struct *dm = (struct dm_struct *)dm_void;
51 	struct phydm_cck_rx_pathdiv *cckrx_t = &dm->dm_cck_rx_pathdiv_table;
52 	struct phydm_fa_struct *fa_t = &dm->false_alm_cnt;
53 	u8 rssi_th = 0;
54 	u32 rssi_a = 0, rssi_b = 0, rssi_avg = 0;
55 
56 	if (!cckrx_t->en_cck_rx_pathdiv)
57 		return;
58 
59 	rssi_a = PHYDM_DIV(cckrx_t->path_a_sum, cckrx_t->path_a_cnt);
60 	rssi_b = PHYDM_DIV(cckrx_t->path_b_sum, cckrx_t->path_b_cnt);
61 	rssi_avg = (rssi_a + rssi_b) >> 1;
62 
63 	pr_debug("Rx-A:%d, Rx-B:%d, avg:%d\n", rssi_a, rssi_b, rssi_avg);
64 
65 	cckrx_t->path_a_cnt = 0;
66 	cckrx_t->path_a_sum = 0;
67 	cckrx_t->path_b_cnt = 0;
68 	cckrx_t->path_b_sum = 0;
69 
70 	if (fa_t->cnt_all >= 100)
71 		rssi_th = cckrx_t->rssi_fa_th;
72 	else
73 		rssi_th = cckrx_t->rssi_th;
74 
75 	if (dm->phy_dbg_info.num_qry_beacon_pkt > 14 && rssi_avg <= rssi_th)
76 		phydm_cck_rx_pathdiv_manaul(dm, true);
77 	else
78 		phydm_cck_rx_pathdiv_manaul(dm, false);
79 }
80 
phydm_cck_rx_pathdiv_init(void * dm_void)81 void phydm_cck_rx_pathdiv_init(void *dm_void)
82 {
83 	struct dm_struct *dm = (struct dm_struct *)dm_void;
84 	struct phydm_cck_rx_pathdiv *cckrx_t = &dm->dm_cck_rx_pathdiv_table;
85 
86 	cckrx_t->en_cck_rx_pathdiv = false;
87 	cckrx_t->path_a_cnt = 0;
88 	cckrx_t->path_a_sum = 0;
89 	cckrx_t->path_b_cnt = 0;
90 	cckrx_t->path_b_sum = 0;
91 	cckrx_t->rssi_fa_th = 45;
92 	cckrx_t->rssi_th = 25;
93 }
94 
phydm_process_rssi_for_cck_rx_pathdiv(void * dm_void,void * phy_info_void,void * pkt_info_void)95 void phydm_process_rssi_for_cck_rx_pathdiv(void *dm_void, void *phy_info_void,
96 					   void *pkt_info_void)
97 {
98 	struct dm_struct *dm = (struct dm_struct *)dm_void;
99 	struct phydm_phyinfo_struct *phy_info = NULL;
100 	struct phydm_perpkt_info_struct *pktinfo = NULL;
101 	struct phydm_cck_rx_pathdiv *cckrx_t = &dm->dm_cck_rx_pathdiv_table;
102 
103 	phy_info = (struct phydm_phyinfo_struct *)phy_info_void;
104 	pktinfo = (struct phydm_perpkt_info_struct *)pkt_info_void;
105 
106 	if (!(pktinfo->is_packet_to_self || pktinfo->is_packet_match_bssid))
107 		return;
108 
109 	if (pktinfo->is_cck_rate)
110 		return;
111 
112 	cckrx_t->path_a_sum += phy_info->rx_mimo_signal_strength[0];
113 	cckrx_t->path_a_cnt++;
114 
115 	cckrx_t->path_b_sum += phy_info->rx_mimo_signal_strength[1];
116 	cckrx_t->path_b_cnt++;
117 }
118 
phydm_cck_rx_pathdiv_dbg(void * dm_void,char input[][16],u32 * _used,char * output,u32 * _out_len)119 void phydm_cck_rx_pathdiv_dbg(void *dm_void, char input[][16], u32 *_used,
120 			      char *output, u32 *_out_len)
121 {
122 	struct dm_struct *dm = (struct dm_struct *)dm_void;
123 	struct phydm_cck_rx_pathdiv *cckrx_t = &dm->dm_cck_rx_pathdiv_table;
124 	char help[] = "-h";
125 	u32 var1[10] = {0};
126 	u32 used = *_used;
127 	u32 out_len = *_out_len;
128 	u8 i = 0;
129 
130 	if (!(dm->support_ic_type & ODM_RTL8822C))
131 		return;
132 
133 	for (i = 0; i < 3; i++) {
134 		PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]);
135 	}
136 
137 	if ((strcmp(input[1], help) == 0)) {
138 		PDM_SNPF(out_len, used, output + used, out_len - used,
139 			 "CCK rx pathdiv manual on: {1} {En}\n");
140 		PDM_SNPF(out_len, used, output + used, out_len - used,
141 			 "CCK rx pathdiv watchdog on: {2} {En}\n");
142 		PDM_SNPF(out_len, used, output + used, out_len - used,
143 			 "CCK rx pathdiv rssi_th : {3} {th} {fa_th}\n");
144 	} else if (var1[0] == 1) {
145 		if (var1[1] == 1)
146 			phydm_cck_rx_pathdiv_manaul(dm, true);
147 		else
148 			phydm_cck_rx_pathdiv_manaul(dm, false);
149 	} else if (var1[0] == 2) {
150 		if (var1[1] == 1) {
151 			cckrx_t->en_cck_rx_pathdiv = true;
152 		} else {
153 			cckrx_t->en_cck_rx_pathdiv = false;
154 			phydm_cck_rx_pathdiv_manaul(dm, false);
155 		}
156 	} else if (var1[0] == 3) {
157 		cckrx_t->rssi_th = (u8)var1[1];
158 		cckrx_t->rssi_fa_th = (u8)var1[2];
159 	}
160 	*_used = used;
161 	*_out_len = out_len;
162 }
163 #endif
164