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 const u32 db_invert_table[12][8] = {
34 {10, 13, 16, 20, 25, 32, 40, 50}, /* @U(32,3) */
35 {64, 80, 101, 128, 160, 201, 256, 318}, /* @U(32,3) */
36 {401, 505, 635, 800, 1007, 1268, 1596, 2010}, /* @U(32,3) */
37 {316, 398, 501, 631, 794, 1000, 1259, 1585}, /* @U(32,0) */
38 {1995, 2512, 3162, 3981, 5012, 6310, 7943, 10000}, /* @U(32,0) */
39 {12589, 15849, 19953, 25119, 31623, 39811, 50119, 63098}, /* @U(32,0) */
40 {79433, 100000, 125893, 158489, 199526, 251189, 316228,
41 398107}, /* @U(32,0) */
42 {501187, 630957, 794328, 1000000, 1258925, 1584893, 1995262,
43 2511886}, /* @U(32,0) */
44 {3162278, 3981072, 5011872, 6309573, 7943282, 1000000, 12589254,
45 15848932}, /* @U(32,0) */
46 {19952623, 25118864, 31622777, 39810717, 50118723, 63095734,
47 79432823, 100000000}, /* @U(32,0) */
48 {125892541, 158489319, 199526232, 251188643, 316227766, 398107171,
49 501187234, 630957345}, /* @U(32,0) */
50 {794328235, 1000000000, 1258925412, 1584893192, 1995262315,
51 2511886432U, 3162277660U, 3981071706U} }; /* @U(32,0) */
52
53 /*Y = 10*log(X)*/
odm_pwdb_conversion(s32 X,u32 total_bit,u32 decimal_bit)54 s32 odm_pwdb_conversion(s32 X, u32 total_bit, u32 decimal_bit)
55 {
56 s32 Y, integer = 0, decimal = 0;
57 u32 i;
58
59 if (X == 0)
60 X = 1; /* @log2(x), x can't be 0 */
61
62 for (i = (total_bit - 1); i > 0; i--) {
63 if (X & BIT(i)) {
64 integer = i;
65 if (i > 0) {
66 /*decimal is 0.5dB*3=1.5dB~=2dB */
67 decimal = (X & BIT(i - 1)) ? 2 : 0;
68 }
69 break;
70 }
71 }
72
73 Y = 3 * (integer - decimal_bit) + decimal; /* @10*log(x)=3*log2(x), */
74
75 return Y;
76 }
77
odm_sign_conversion(s32 value,u32 total_bit)78 s32 odm_sign_conversion(s32 value, u32 total_bit)
79 {
80 if (value & BIT(total_bit - 1))
81 value -= BIT(total_bit);
82
83 return value;
84 }
85
86 /*threshold must form low to high*/
phydm_find_intrvl(void * dm_void,u16 val,u16 * threshold,u16 th_len)87 u16 phydm_find_intrvl(void *dm_void, u16 val, u16 *threshold, u16 th_len)
88 {
89 struct dm_struct *dm = (struct dm_struct *)dm_void;
90 u16 i = 0;
91 u16 ret_val = 0;
92 u16 max_th = threshold[th_len - 1];
93
94 for (i = 0; i < th_len; i++) {
95 if (val < threshold[i]) {
96 ret_val = i;
97 break;
98 } else if (val >= max_th) {
99 ret_val = th_len;
100 break;
101 }
102 }
103
104 return ret_val;
105 }
106
phydm_seq_sorting(void * dm_void,u32 * value,u32 * rank_idx,u32 * idx_out,u8 seq_length)107 void phydm_seq_sorting(void *dm_void, u32 *value, u32 *rank_idx, u32 *idx_out,
108 u8 seq_length)
109 {
110 u8 i = 0, j = 0;
111 u32 tmp_a, tmp_b;
112 u32 tmp_idx_a, tmp_idx_b;
113
114 for (i = 0; i < seq_length; i++)
115 rank_idx[i] = i;
116
117 for (i = 0; i < (seq_length - 1); i++) {
118 for (j = 0; j < (seq_length - 1 - i); j++) {
119 tmp_a = value[j];
120 tmp_b = value[j + 1];
121
122 tmp_idx_a = rank_idx[j];
123 tmp_idx_b = rank_idx[j + 1];
124
125 if (tmp_a < tmp_b) {
126 value[j] = tmp_b;
127 value[j + 1] = tmp_a;
128
129 rank_idx[j] = tmp_idx_b;
130 rank_idx[j + 1] = tmp_idx_a;
131 }
132 }
133 }
134
135 for (i = 0; i < seq_length; i++)
136 idx_out[rank_idx[i]] = i + 1;
137 }
138
odm_convert_to_db(u64 value)139 u32 odm_convert_to_db(u64 value)
140 {
141 u8 i;
142 u8 j;
143 u32 dB;
144
145 if (value >= db_invert_table[11][7])
146 return 96; /* @maximum 96 dB */
147
148 for (i = 0; i < 12; i++) {
149 if (i <= 2 && (value << FRAC_BITS) <= db_invert_table[i][7])
150 break;
151 else if (i > 2 && value <= db_invert_table[i][7])
152 break;
153 }
154
155 for (j = 0; j < 8; j++) {
156 if (i <= 2 && (value << FRAC_BITS) <= db_invert_table[i][j])
157 break;
158 else if (i > 2 && i < 12 && value <= db_invert_table[i][j])
159 break;
160 }
161
162 /*special cases*/
163 if (j == 0 && i == 0)
164 goto end;
165
166 if (i == 3 && j == 0) {
167 if (db_invert_table[3][0] - value >
168 value - (db_invert_table[2][7] >> FRAC_BITS)) {
169 i = 2;
170 j = 7;
171 }
172 goto end;
173 }
174
175 if (i < 3)
176 value = value << FRAC_BITS; /*@elements of row 0~2 shift left*/
177
178 /*compare difference to get precise dB*/
179 if (j == 0) {
180 if (db_invert_table[i][j] - value >
181 value - db_invert_table[i - 1][7]) {
182 i = i - 1;
183 j = 7;
184 }
185 } else {
186 if (db_invert_table[i][j] - value >
187 value - db_invert_table[i][j - 1]) {
188 j = j - 1;
189 }
190 }
191 end:
192 dB = (i << 3) + j + 1;
193
194 return dB;
195 }
196
phydm_db_2_linear(u32 value)197 u64 phydm_db_2_linear(u32 value)
198 {
199 u8 i = 0;
200 u8 j = 0;
201 u64 linear = 0;
202
203 value = value & 0xFF;
204
205 /* @1dB~96dB */
206 if (value > 96) {
207 value = 96;
208 } else if (value < 1) {
209 linear = 1;
210 return linear;
211 }
212
213 i = (u8)((value - 1) >> 3);
214 j = (u8)(value - 1) - (i << 3);
215
216 linear = db_invert_table[i][j];
217
218 if (i > 2)
219 linear = linear << FRAC_BITS;
220
221 return linear;
222 }
223
phydm_show_fraction_num(u32 frac_val,u8 bit_num)224 u16 phydm_show_fraction_num(u32 frac_val, u8 bit_num)
225 {
226 u8 i = 0;
227 u16 val = 0;
228 u16 base = 5000;
229
230 for (i = bit_num; i > 0; i--) {
231 if (frac_val & BIT(i - 1))
232 val += (base >> (bit_num - i));
233 }
234 return val;
235 }
236
phydm_ones_num_in_bitmap(u64 val,u8 size)237 u16 phydm_ones_num_in_bitmap(u64 val, u8 size)
238 {
239 u8 i = 0;
240 u8 ones_num = 0;
241
242 for (i = 0; i < size; i++) {
243 if (val & BIT(0))
244 ones_num++;
245
246 val = val >> 1;
247 }
248
249 return ones_num;
250 }
251
phydm_gen_bitmask(u8 mask_num)252 u64 phydm_gen_bitmask(u8 mask_num)
253 {
254 u8 i = 0;
255 u64 bitmask = 0;
256
257 if (mask_num > 64)
258 return 1;
259
260 for (i = 0; i < mask_num; i++)
261 bitmask = (bitmask << 1) | BIT(0);
262
263 return bitmask;
264 }
265
phydm_cnvrt_2_sign(u32 val,u8 bit_num)266 s32 phydm_cnvrt_2_sign(u32 val, u8 bit_num)
267 {
268 if (bit_num >= 32)
269 return (s32)val;
270
271 if (val & BIT(bit_num - 1)) /*Sign BIT*/
272 val -= (1 << bit_num); /*@2's*/
273
274 return val;
275 }
276
phydm_cnvrt_2_sign_64(u64 val,u8 bit_num)277 s64 phydm_cnvrt_2_sign_64(u64 val, u8 bit_num)
278 {
279 u64 one = 1;
280 s64 val_sign = (s64)val;
281
282 if (bit_num >= 64)
283 return (s64)val;
284
285 if (val & (one << (bit_num - 1))) /*Sign BIT*/
286 val_sign = val - (one << bit_num); /*@2's*/
287
288 return val_sign;
289 }
290
291