1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2016  Realtek Corporation.
5  *
6  * Contact Information:
7  * wlanfae <wlanfae@realtek.com>
8  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
9  * Hsinchu 300, Taiwan.
10  *
11  * Larry Finger <Larry.Finger@lwfinger.net>
12  *
13  *****************************************************************************/
14 
15 /* ************************************************************
16  * include files
17  * *************************************************************/
18 
19 #include "mp_precomp.h"
20 #include "phydm_precomp.h"
21 
22 #define READ_AND_CONFIG_MP(ic, txt) (odm_read_and_config_mp_##ic##txt(dm))
23 #define READ_AND_CONFIG_TC(ic, txt) (odm_read_and_config_tc_##ic##txt(dm))
24 
25 #define READ_AND_CONFIG READ_AND_CONFIG_MP
26 
27 #define READ_FIRMWARE_MP(ic, txt)                                              \
28 	(odm_read_firmware_mp_##ic##txt(dm, p_firmware, size))
29 #define READ_FIRMWARE_TC(ic, txt)                                              \
30 	(odm_read_firmware_tc_##ic##txt(dm, p_firmware, size))
31 
32 #define READ_FIRMWARE READ_FIRMWARE_MP
33 
34 #define GET_VERSION_MP(ic, txt) (odm_get_version_mp_##ic##txt())
35 #define GET_VERSION_TC(ic, txt) (odm_get_version_tc_##ic##txt())
36 
37 #define GET_VERSION(ic, txt) GET_VERSION_MP(ic, txt)
38 
phydm_process_rssi_pwdb(struct phy_dm_struct * dm,struct rtl_sta_info * entry,struct dm_per_pkt_info * pktinfo,u32 undecorated_smoothed_ofdm,u32 undecorated_smoothed_cck)39 static u32 phydm_process_rssi_pwdb(struct phy_dm_struct *dm,
40 				   struct rtl_sta_info *entry,
41 				   struct dm_per_pkt_info *pktinfo,
42 				   u32 undecorated_smoothed_ofdm,
43 				   u32 undecorated_smoothed_cck)
44 {
45 	u32 weighting = 0, undecorated_smoothed_pwdb;
46 	/* 2011.07.28 LukeLee: modified to prevent unstable CCK RSSI */
47 
48 	if (entry->rssi_stat.ofdm_pkt ==
49 	    64) { /* speed up when all packets are OFDM*/
50 		undecorated_smoothed_pwdb = undecorated_smoothed_ofdm;
51 		ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
52 			     "PWDB_0[%d] = (( %d ))\n", pktinfo->station_id,
53 			     undecorated_smoothed_cck);
54 	} else {
55 		if (entry->rssi_stat.valid_bit < 64)
56 			entry->rssi_stat.valid_bit++;
57 
58 		if (entry->rssi_stat.valid_bit == 64) {
59 			weighting = ((entry->rssi_stat.ofdm_pkt) > 4) ?
60 					    64 :
61 					    (entry->rssi_stat.ofdm_pkt << 4);
62 			undecorated_smoothed_pwdb =
63 				(weighting * undecorated_smoothed_ofdm +
64 				 (64 - weighting) * undecorated_smoothed_cck) >>
65 				6;
66 			ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
67 				     "PWDB_1[%d] = (( %d )), W = (( %d ))\n",
68 				     pktinfo->station_id,
69 				     undecorated_smoothed_cck, weighting);
70 		} else {
71 			if (entry->rssi_stat.valid_bit != 0)
72 				undecorated_smoothed_pwdb =
73 					(entry->rssi_stat.ofdm_pkt *
74 						 undecorated_smoothed_ofdm +
75 					 (entry->rssi_stat.valid_bit -
76 					  entry->rssi_stat.ofdm_pkt) *
77 						 undecorated_smoothed_cck) /
78 					entry->rssi_stat.valid_bit;
79 			else
80 				undecorated_smoothed_pwdb = 0;
81 
82 			ODM_RT_TRACE(
83 				dm, ODM_COMP_RSSI_MONITOR,
84 				"PWDB_2[%d] = (( %d )), ofdm_pkt = (( %d )), Valid_Bit = (( %d ))\n",
85 				pktinfo->station_id, undecorated_smoothed_cck,
86 				entry->rssi_stat.ofdm_pkt,
87 				entry->rssi_stat.valid_bit);
88 		}
89 	}
90 
91 	return undecorated_smoothed_pwdb;
92 }
93 
phydm_process_rssi_cck(struct phy_dm_struct * dm,struct dm_phy_status_info * phy_info,struct rtl_sta_info * entry,u32 undecorated_smoothed_cck)94 static u32 phydm_process_rssi_cck(struct phy_dm_struct *dm,
95 				  struct dm_phy_status_info *phy_info,
96 				  struct rtl_sta_info *entry,
97 				  u32 undecorated_smoothed_cck)
98 {
99 	u32 rssi_ave;
100 	u8 i;
101 
102 	rssi_ave = phy_info->rx_pwdb_all;
103 	dm->rssi_a = (u8)phy_info->rx_pwdb_all;
104 	dm->rssi_b = 0xFF;
105 	dm->rssi_c = 0xFF;
106 	dm->rssi_d = 0xFF;
107 
108 	if (entry->rssi_stat.cck_pkt <= 63)
109 		entry->rssi_stat.cck_pkt++;
110 
111 	/* 1 Process CCK RSSI */
112 	if (undecorated_smoothed_cck <= 0) { /* initialize */
113 		undecorated_smoothed_cck = phy_info->rx_pwdb_all;
114 		entry->rssi_stat.cck_sum_power =
115 			(u16)phy_info->rx_pwdb_all; /*reset*/
116 		entry->rssi_stat.cck_pkt = 1; /*reset*/
117 		ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, "CCK_INIT: (( %d ))\n",
118 			     undecorated_smoothed_cck);
119 	} else if (entry->rssi_stat.cck_pkt <= CCK_RSSI_INIT_COUNT) {
120 		entry->rssi_stat.cck_sum_power =
121 			entry->rssi_stat.cck_sum_power +
122 			(u16)phy_info->rx_pwdb_all;
123 		undecorated_smoothed_cck = entry->rssi_stat.cck_sum_power /
124 					   entry->rssi_stat.cck_pkt;
125 
126 		ODM_RT_TRACE(
127 			dm, ODM_COMP_RSSI_MONITOR,
128 			"CCK_0: (( %d )), SumPow = (( %d )), cck_pkt = (( %d ))\n",
129 			undecorated_smoothed_cck,
130 			entry->rssi_stat.cck_sum_power,
131 			entry->rssi_stat.cck_pkt);
132 	} else {
133 		if (phy_info->rx_pwdb_all > (u32)undecorated_smoothed_cck) {
134 			undecorated_smoothed_cck =
135 				(((undecorated_smoothed_cck) *
136 				  (RX_SMOOTH_FACTOR - 1)) +
137 				 (phy_info->rx_pwdb_all)) /
138 				(RX_SMOOTH_FACTOR);
139 			undecorated_smoothed_cck = undecorated_smoothed_cck + 1;
140 			ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
141 				     "CCK_1: (( %d ))\n",
142 				     undecorated_smoothed_cck);
143 		} else {
144 			undecorated_smoothed_cck =
145 				(((undecorated_smoothed_cck) *
146 				  (RX_SMOOTH_FACTOR - 1)) +
147 				 (phy_info->rx_pwdb_all)) /
148 				(RX_SMOOTH_FACTOR);
149 			ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
150 				     "CCK_2: (( %d ))\n",
151 				     undecorated_smoothed_cck);
152 		}
153 	}
154 
155 	i = 63;
156 	entry->rssi_stat.ofdm_pkt -=
157 		(u8)((entry->rssi_stat.packet_map >> i) & BIT(0));
158 	entry->rssi_stat.packet_map = entry->rssi_stat.packet_map << 1;
159 	return undecorated_smoothed_cck;
160 }
161 
phydm_process_rssi_ofdm(struct phy_dm_struct * dm,struct dm_phy_status_info * phy_info,struct rtl_sta_info * entry,u32 undecorated_smoothed_ofdm)162 static u32 phydm_process_rssi_ofdm(struct phy_dm_struct *dm,
163 				   struct dm_phy_status_info *phy_info,
164 				   struct rtl_sta_info *entry,
165 				   u32 undecorated_smoothed_ofdm)
166 {
167 	u32 rssi_ave;
168 	u8 rssi_max, rssi_min, i;
169 
170 	if (dm->support_ic_type & (ODM_RTL8814A | ODM_RTL8822B)) {
171 		u8 rx_count = 0;
172 		u32 rssi_linear = 0;
173 
174 		if (dm->rx_ant_status & ODM_RF_A) {
175 			dm->rssi_a = phy_info->rx_mimo_signal_strength
176 					     [ODM_RF_PATH_A];
177 			rx_count++;
178 			rssi_linear += odm_convert_to_linear(
179 				phy_info->rx_mimo_signal_strength
180 					[ODM_RF_PATH_A]);
181 		} else {
182 			dm->rssi_a = 0;
183 		}
184 
185 		if (dm->rx_ant_status & ODM_RF_B) {
186 			dm->rssi_b = phy_info->rx_mimo_signal_strength
187 					     [ODM_RF_PATH_B];
188 			rx_count++;
189 			rssi_linear += odm_convert_to_linear(
190 				phy_info->rx_mimo_signal_strength
191 					[ODM_RF_PATH_B]);
192 		} else {
193 			dm->rssi_b = 0;
194 		}
195 
196 		if (dm->rx_ant_status & ODM_RF_C) {
197 			dm->rssi_c = phy_info->rx_mimo_signal_strength
198 					     [ODM_RF_PATH_C];
199 			rx_count++;
200 			rssi_linear += odm_convert_to_linear(
201 				phy_info->rx_mimo_signal_strength
202 					[ODM_RF_PATH_C]);
203 		} else {
204 			dm->rssi_c = 0;
205 		}
206 
207 		if (dm->rx_ant_status & ODM_RF_D) {
208 			dm->rssi_d = phy_info->rx_mimo_signal_strength
209 					     [ODM_RF_PATH_D];
210 			rx_count++;
211 			rssi_linear += odm_convert_to_linear(
212 				phy_info->rx_mimo_signal_strength
213 					[ODM_RF_PATH_D]);
214 		} else {
215 			dm->rssi_d = 0;
216 		}
217 
218 		/* Calculate average RSSI */
219 		switch (rx_count) {
220 		case 2:
221 			rssi_linear = (rssi_linear >> 1);
222 			break;
223 		case 3:
224 			/* rssi_linear/3 ~ rssi_linear*11/32 */
225 			rssi_linear = ((rssi_linear) + (rssi_linear << 1) +
226 				       (rssi_linear << 3)) >>
227 				      5;
228 			break;
229 		case 4:
230 			rssi_linear = (rssi_linear >> 2);
231 			break;
232 		}
233 
234 		rssi_ave = odm_convert_to_db(rssi_linear);
235 	} else {
236 		if (phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B] == 0) {
237 			rssi_ave = phy_info->rx_mimo_signal_strength
238 					   [ODM_RF_PATH_A];
239 			dm->rssi_a = phy_info->rx_mimo_signal_strength
240 					     [ODM_RF_PATH_A];
241 			dm->rssi_b = 0;
242 		} else {
243 			dm->rssi_a = phy_info->rx_mimo_signal_strength
244 					     [ODM_RF_PATH_A];
245 			dm->rssi_b = phy_info->rx_mimo_signal_strength
246 					     [ODM_RF_PATH_B];
247 
248 			if (phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A] >
249 			    phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]) {
250 				rssi_max = phy_info->rx_mimo_signal_strength
251 						   [ODM_RF_PATH_A];
252 				rssi_min = phy_info->rx_mimo_signal_strength
253 						   [ODM_RF_PATH_B];
254 			} else {
255 				rssi_max = phy_info->rx_mimo_signal_strength
256 						   [ODM_RF_PATH_B];
257 				rssi_min = phy_info->rx_mimo_signal_strength
258 						   [ODM_RF_PATH_A];
259 			}
260 			if ((rssi_max - rssi_min) < 3)
261 				rssi_ave = rssi_max;
262 			else if ((rssi_max - rssi_min) < 6)
263 				rssi_ave = rssi_max - 1;
264 			else if ((rssi_max - rssi_min) < 10)
265 				rssi_ave = rssi_max - 2;
266 			else
267 				rssi_ave = rssi_max - 3;
268 		}
269 	}
270 
271 	/* 1 Process OFDM RSSI */
272 	if (undecorated_smoothed_ofdm <= 0) { /* initialize */
273 		undecorated_smoothed_ofdm = phy_info->rx_pwdb_all;
274 		ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, "OFDM_INIT: (( %d ))\n",
275 			     undecorated_smoothed_ofdm);
276 	} else {
277 		if (phy_info->rx_pwdb_all > (u32)undecorated_smoothed_ofdm) {
278 			undecorated_smoothed_ofdm =
279 				(((undecorated_smoothed_ofdm) *
280 				  (RX_SMOOTH_FACTOR - 1)) +
281 				 (rssi_ave)) /
282 				(RX_SMOOTH_FACTOR);
283 			undecorated_smoothed_ofdm =
284 				undecorated_smoothed_ofdm + 1;
285 			ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
286 				     "OFDM_1: (( %d ))\n",
287 				     undecorated_smoothed_ofdm);
288 		} else {
289 			undecorated_smoothed_ofdm =
290 				(((undecorated_smoothed_ofdm) *
291 				  (RX_SMOOTH_FACTOR - 1)) +
292 				 (rssi_ave)) /
293 				(RX_SMOOTH_FACTOR);
294 			ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
295 				     "OFDM_2: (( %d ))\n",
296 				     undecorated_smoothed_ofdm);
297 		}
298 	}
299 
300 	if (entry->rssi_stat.ofdm_pkt != 64) {
301 		i = 63;
302 		entry->rssi_stat.ofdm_pkt -=
303 			(u8)(((entry->rssi_stat.packet_map >> i) & BIT(0)) - 1);
304 	}
305 
306 	entry->rssi_stat.packet_map =
307 		(entry->rssi_stat.packet_map << 1) | BIT(0);
308 	return undecorated_smoothed_ofdm;
309 }
310 
311 static u8 odm_evm_db_to_percentage(s8);
312 static u8 odm_evm_dbm_jaguar_series(s8);
313 
phydm_get_rssi_average(struct phy_dm_struct * dm,struct dm_phy_status_info * phy_info)314 static inline u32 phydm_get_rssi_average(struct phy_dm_struct *dm,
315 					 struct dm_phy_status_info *phy_info)
316 {
317 	u8 rssi_max = 0, rssi_min = 0;
318 
319 	dm->rssi_a = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A];
320 	dm->rssi_b = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B];
321 
322 	if (phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A] >
323 	    phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]) {
324 		rssi_max = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A];
325 		rssi_min = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B];
326 	} else {
327 		rssi_max = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B];
328 		rssi_min = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A];
329 	}
330 	if ((rssi_max - rssi_min) < 3)
331 		return rssi_max;
332 	else if ((rssi_max - rssi_min) < 6)
333 		return rssi_max - 1;
334 	else if ((rssi_max - rssi_min) < 10)
335 		return rssi_max - 2;
336 	else
337 		return rssi_max - 3;
338 }
339 
phydm_get_evm_dbm(u8 i,u8 EVM,struct phy_status_rpt_8812 * phy_sta_rpt,struct dm_phy_status_info * phy_info)340 static inline u8 phydm_get_evm_dbm(u8 i, u8 EVM,
341 				   struct phy_status_rpt_8812 *phy_sta_rpt,
342 				   struct dm_phy_status_info *phy_info)
343 {
344 	if (i < ODM_RF_PATH_C)
345 		return odm_evm_dbm_jaguar_series(phy_sta_rpt->rxevm[i]);
346 	else
347 		return odm_evm_dbm_jaguar_series(phy_sta_rpt->rxevm_cd[i - 2]);
348 	/*RT_DISP(FRX, RX_PHY_SQ, ("RXRATE=%x RXEVM=%x EVM=%s%d\n",*/
349 	/*pktinfo->data_rate, phy_sta_rpt->rxevm[i], "%", EVM));*/
350 }
351 
phydm_get_odm_evm(u8 i,struct dm_per_pkt_info * pktinfo,struct phy_status_rpt_8812 * phy_sta_rpt)352 static inline u8 phydm_get_odm_evm(u8 i, struct dm_per_pkt_info *pktinfo,
353 				   struct phy_status_rpt_8812 *phy_sta_rpt)
354 {
355 	u8 evm = 0;
356 
357 	if (pktinfo->data_rate >= ODM_RATE6M &&
358 	    pktinfo->data_rate <= ODM_RATE54M) {
359 		if (i == ODM_RF_PATH_A) {
360 			evm = odm_evm_db_to_percentage(
361 				(phy_sta_rpt->sigevm)); /*dbm*/
362 			evm += 20;
363 			if (evm > 100)
364 				evm = 100;
365 		}
366 	} else {
367 		if (i < ODM_RF_PATH_C) {
368 			if (phy_sta_rpt->rxevm[i] == -128)
369 				phy_sta_rpt->rxevm[i] = -25;
370 			evm = odm_evm_db_to_percentage(
371 				(phy_sta_rpt->rxevm[i])); /*dbm*/
372 		} else {
373 			if (phy_sta_rpt->rxevm_cd[i - 2] == -128)
374 				phy_sta_rpt->rxevm_cd[i - 2] = -25;
375 			evm = odm_evm_db_to_percentage(
376 				(phy_sta_rpt->rxevm_cd[i - 2])); /*dbm*/
377 		}
378 	}
379 
380 	return evm;
381 }
382 
phydm_get_rx_pwr(u8 LNA_idx,u8 VGA_idx,u8 cck_highpwr)383 static inline s8 phydm_get_rx_pwr(u8 LNA_idx, u8 VGA_idx, u8 cck_highpwr)
384 {
385 	switch (LNA_idx) {
386 	case 7:
387 		if (VGA_idx <= 27)
388 			return -100 + 2 * (27 - VGA_idx); /*VGA_idx = 27~2*/
389 		else
390 			return -100;
391 		break;
392 	case 6:
393 		return -48 + 2 * (2 - VGA_idx); /*VGA_idx = 2~0*/
394 	case 5:
395 		return -42 + 2 * (7 - VGA_idx); /*VGA_idx = 7~5*/
396 	case 4:
397 		return -36 + 2 * (7 - VGA_idx); /*VGA_idx = 7~4*/
398 	case 3:
399 		return -24 + 2 * (7 - VGA_idx); /*VGA_idx = 7~0*/
400 	case 2:
401 		if (cck_highpwr)
402 			return -12 + 2 * (5 - VGA_idx); /*VGA_idx = 5~0*/
403 		else
404 			return -6 + 2 * (5 - VGA_idx);
405 		break;
406 	case 1:
407 		return 8 - 2 * VGA_idx;
408 	case 0:
409 		return 14 - 2 * VGA_idx;
410 	default:
411 		break;
412 	}
413 	return 0;
414 }
415 
phydm_adjust_pwdb(u8 cck_highpwr,u8 pwdb_all)416 static inline u8 phydm_adjust_pwdb(u8 cck_highpwr, u8 pwdb_all)
417 {
418 	if (!cck_highpwr) {
419 		if (pwdb_all >= 80)
420 			return ((pwdb_all - 80) << 1) + ((pwdb_all - 80) >> 1) +
421 			       80;
422 		else if ((pwdb_all <= 78) && (pwdb_all >= 20))
423 			return pwdb_all + 3;
424 		if (pwdb_all > 100)
425 			return 100;
426 	}
427 	return pwdb_all;
428 }
429 
430 static inline u8
phydm_get_signal_quality_8812(struct dm_phy_status_info * phy_info,struct phy_dm_struct * dm,struct phy_status_rpt_8812 * phy_sta_rpt)431 phydm_get_signal_quality_8812(struct dm_phy_status_info *phy_info,
432 			      struct phy_dm_struct *dm,
433 			      struct phy_status_rpt_8812 *phy_sta_rpt)
434 {
435 	u8 sq_rpt;
436 
437 	if (phy_info->rx_pwdb_all > 40 && !dm->is_in_hct_test)
438 		return 100;
439 
440 	sq_rpt = phy_sta_rpt->pwdb_all;
441 
442 	if (sq_rpt > 64)
443 		return 0;
444 	else if (sq_rpt < 20)
445 		return 100;
446 	else
447 		return ((64 - sq_rpt) * 100) / 44;
448 }
449 
450 static inline u8
phydm_get_signal_quality_8192(struct dm_phy_status_info * phy_info,struct phy_dm_struct * dm,struct phy_status_rpt_8192cd * phy_sta_rpt)451 phydm_get_signal_quality_8192(struct dm_phy_status_info *phy_info,
452 			      struct phy_dm_struct *dm,
453 			      struct phy_status_rpt_8192cd *phy_sta_rpt)
454 {
455 	u8 sq_rpt;
456 
457 	if (phy_info->rx_pwdb_all > 40 && !dm->is_in_hct_test)
458 		return 100;
459 
460 	sq_rpt = phy_sta_rpt->cck_sig_qual_ofdm_pwdb_all;
461 
462 	if (sq_rpt > 64)
463 		return 0;
464 	else if (sq_rpt < 20)
465 		return 100;
466 	else
467 		return ((64 - sq_rpt) * 100) / 44;
468 }
469 
odm_query_rx_pwr_percentage(s8 ant_power)470 static u8 odm_query_rx_pwr_percentage(s8 ant_power)
471 {
472 	if ((ant_power <= -100) || (ant_power >= 20))
473 		return 0;
474 	else if (ant_power >= 0)
475 		return 100;
476 	else
477 		return 100 + ant_power;
478 }
479 
480 /*
481  * 2012/01/12 MH MOve some signal strength smooth method to MP HAL layer.
482  * IF other SW team do not support the feature, remove this section.??
483  */
484 
odm_signal_scale_mapping(struct phy_dm_struct * dm,s32 curr_sig)485 s32 odm_signal_scale_mapping(struct phy_dm_struct *dm, s32 curr_sig)
486 {
487 	{
488 		return curr_sig;
489 	}
490 }
491 
odm_sq_process_patch_rt_cid_819x_lenovo(struct phy_dm_struct * dm,u8 is_cck_rate,u8 pwdb_all,u8 path,u8 RSSI)492 static u8 odm_sq_process_patch_rt_cid_819x_lenovo(struct phy_dm_struct *dm,
493 						  u8 is_cck_rate, u8 pwdb_all,
494 						  u8 path, u8 RSSI)
495 {
496 	u8 sq = 0;
497 	return sq;
498 }
499 
odm_evm_db_to_percentage(s8 value)500 static u8 odm_evm_db_to_percentage(s8 value)
501 {
502 	/* -33dB~0dB to 0%~99% */
503 	s8 ret_val;
504 
505 	ret_val = value;
506 	ret_val /= 2;
507 
508 	if (ret_val >= 0)
509 		ret_val = 0;
510 
511 	if (ret_val <= -33)
512 		ret_val = -33;
513 
514 	ret_val = 0 - ret_val;
515 	ret_val *= 3;
516 
517 	if (ret_val == 99)
518 		ret_val = 100;
519 
520 	return (u8)ret_val;
521 }
522 
odm_evm_dbm_jaguar_series(s8 value)523 static u8 odm_evm_dbm_jaguar_series(s8 value)
524 {
525 	s8 ret_val = value;
526 
527 	/* -33dB~0dB to 33dB ~ 0dB */
528 	if (ret_val == -128)
529 		ret_val = 127;
530 	else if (ret_val < 0)
531 		ret_val = 0 - ret_val;
532 
533 	ret_val = ret_val >> 1;
534 	return (u8)ret_val;
535 }
536 
odm_cfo(s8 value)537 static s16 odm_cfo(s8 value)
538 {
539 	s16 ret_val;
540 
541 	if (value < 0) {
542 		ret_val = 0 - value;
543 		ret_val = (ret_val << 1) + (ret_val >> 1); /* *2.5~=312.5/2^7 */
544 		ret_val =
545 			ret_val | BIT(12); /* set bit12 as 1 for negative cfo */
546 	} else {
547 		ret_val = value;
548 		ret_val = (ret_val << 1) + (ret_val >> 1); /* *2.5~=312.5/2^7 */
549 	}
550 	return ret_val;
551 }
552 
phydm_rate_to_num_ss(struct phy_dm_struct * dm,u8 data_rate)553 static u8 phydm_rate_to_num_ss(struct phy_dm_struct *dm, u8 data_rate)
554 {
555 	u8 num_ss = 1;
556 
557 	if (data_rate <= ODM_RATE54M)
558 		num_ss = 1;
559 	else if (data_rate <= ODM_RATEMCS31)
560 		num_ss = ((data_rate - ODM_RATEMCS0) >> 3) + 1;
561 	else if (data_rate <= ODM_RATEVHTSS1MCS9)
562 		num_ss = 1;
563 	else if (data_rate <= ODM_RATEVHTSS2MCS9)
564 		num_ss = 2;
565 	else if (data_rate <= ODM_RATEVHTSS3MCS9)
566 		num_ss = 3;
567 	else if (data_rate <= ODM_RATEVHTSS4MCS9)
568 		num_ss = 4;
569 
570 	return num_ss;
571 }
572 
odm_rx_phy_status92c_series_parsing(struct phy_dm_struct * dm,struct dm_phy_status_info * phy_info,u8 * phy_status,struct dm_per_pkt_info * pktinfo)573 static void odm_rx_phy_status92c_series_parsing(
574 	struct phy_dm_struct *dm, struct dm_phy_status_info *phy_info,
575 	u8 *phy_status, struct dm_per_pkt_info *pktinfo)
576 {
577 	u8 i, max_spatial_stream;
578 	s8 rx_pwr[4], rx_pwr_all = 0;
579 	u8 EVM, pwdb_all = 0, pwdb_all_bt;
580 	u8 RSSI, total_rssi = 0;
581 	bool is_cck_rate = false;
582 	u8 rf_rx_num = 0;
583 	u8 LNA_idx = 0;
584 	u8 VGA_idx = 0;
585 	u8 cck_agc_rpt;
586 	u8 num_ss;
587 	struct phy_status_rpt_8192cd *phy_sta_rpt =
588 		(struct phy_status_rpt_8192cd *)phy_status;
589 
590 	is_cck_rate = (pktinfo->data_rate <= ODM_RATE11M) ? true : false;
591 
592 	if (pktinfo->is_to_self)
593 		dm->curr_station_id = pktinfo->station_id;
594 
595 	phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = -1;
596 	phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1;
597 
598 	if (is_cck_rate) {
599 		dm->phy_dbg_info.num_qry_phy_status_cck++;
600 		cck_agc_rpt = phy_sta_rpt->cck_agc_rpt_ofdm_cfosho_a;
601 
602 		if (dm->support_ic_type & (ODM_RTL8703B)) {
603 		} else { /*3 bit LNA*/
604 
605 			LNA_idx = ((cck_agc_rpt & 0xE0) >> 5);
606 			VGA_idx = (cck_agc_rpt & 0x1F);
607 		}
608 
609 		ODM_RT_TRACE(
610 			dm, ODM_COMP_RSSI_MONITOR,
611 			"ext_lna_gain (( %d )), LNA_idx: (( 0x%x )), VGA_idx: (( 0x%x )), rx_pwr_all: (( %d ))\n",
612 			dm->ext_lna_gain, LNA_idx, VGA_idx, rx_pwr_all);
613 
614 		if (dm->board_type & ODM_BOARD_EXT_LNA)
615 			rx_pwr_all -= dm->ext_lna_gain;
616 
617 		pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
618 
619 		if (pktinfo->is_to_self) {
620 			dm->cck_lna_idx = LNA_idx;
621 			dm->cck_vga_idx = VGA_idx;
622 		}
623 		phy_info->rx_pwdb_all = pwdb_all;
624 
625 		phy_info->bt_rx_rssi_percentage = pwdb_all;
626 		phy_info->recv_signal_power = rx_pwr_all;
627 		/* (3) Get Signal Quality (EVM) */
628 		{
629 			u8 sq;
630 
631 			sq = phydm_get_signal_quality_8192(phy_info, dm,
632 							   phy_sta_rpt);
633 			phy_info->signal_quality = sq;
634 			phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = sq;
635 			phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1;
636 		}
637 
638 		for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX; i++) {
639 			if (i == 0)
640 				phy_info->rx_mimo_signal_strength[0] = pwdb_all;
641 			else
642 				phy_info->rx_mimo_signal_strength[1] = 0;
643 		}
644 	} else { /* 2 is OFDM rate */
645 		dm->phy_dbg_info.num_qry_phy_status_ofdm++;
646 
647 		/*  */
648 		/* (1)Get RSSI for HT rate */
649 		/*  */
650 
651 		for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX; i++) {
652 			/* 2008/01/30 MH we will judge RF RX path now. */
653 			if (dm->rf_path_rx_enable & BIT(i))
654 				rf_rx_num++;
655 			/* else */
656 			/* continue; */
657 
658 			rx_pwr[i] =
659 				((phy_sta_rpt->path_agc[i].gain & 0x3F) * 2) -
660 				110;
661 
662 			if (pktinfo->is_to_self) {
663 				dm->ofdm_agc_idx[i] =
664 					(phy_sta_rpt->path_agc[i].gain & 0x3F);
665 				/**/
666 			}
667 
668 			phy_info->rx_pwr[i] = rx_pwr[i];
669 
670 			/* Translate DBM to percentage. */
671 			RSSI = odm_query_rx_pwr_percentage(rx_pwr[i]);
672 			total_rssi += RSSI;
673 
674 			phy_info->rx_mimo_signal_strength[i] = (u8)RSSI;
675 
676 			/* Get Rx snr value in DB */
677 			dm->phy_dbg_info.rx_snr_db[i] =
678 				(s32)(phy_sta_rpt->path_rxsnr[i] / 2);
679 			phy_info->rx_snr[i] = dm->phy_dbg_info.rx_snr_db[i];
680 
681 			/* Record Signal Strength for next packet */
682 			/* if(pktinfo->is_packet_match_bssid) */
683 			{
684 			}
685 		}
686 
687 		/*  */
688 		/* (2)PWDB, Average PWDB calcuated by hardware (for RA) */
689 		/*  */
690 		rx_pwr_all = (((phy_sta_rpt->cck_sig_qual_ofdm_pwdb_all) >> 1) &
691 			      0x7f) -
692 			     110;
693 
694 		pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
695 		pwdb_all_bt = pwdb_all;
696 
697 		phy_info->rx_pwdb_all = pwdb_all;
698 		phy_info->bt_rx_rssi_percentage = pwdb_all_bt;
699 		phy_info->rx_power = rx_pwr_all;
700 		phy_info->recv_signal_power = rx_pwr_all;
701 
702 		if ((dm->support_platform == ODM_WIN) && (dm->patch_id == 19)) {
703 			/* do nothing */
704 		} else if ((dm->support_platform == ODM_WIN) &&
705 			   (dm->patch_id == 25)) {
706 			/* do nothing */
707 		} else { /* mgnt_info->customer_id != RT_CID_819X_LENOVO */
708 			/*  */
709 			/* (3)EVM of HT rate */
710 			/*  */
711 			if (pktinfo->data_rate >= ODM_RATEMCS8 &&
712 			    pktinfo->data_rate <= ODM_RATEMCS15) {
713 				/* both spatial stream make sense */
714 				max_spatial_stream = 2;
715 			} else {
716 				/* only spatial stream 1 makes sense */
717 				max_spatial_stream = 1;
718 			}
719 
720 			for (i = 0; i < max_spatial_stream; i++) {
721 				/*Don't use shift operation like "rx_evmX >>= 1"
722 				 *because the compilor of free build environment
723 				 *fill most significant bit to "zero" when doing
724 				 *shifting operation which may change a negative
725 				 *value to positive one, then the dbm value
726 				 *(which is supposed to be negative)  is not
727 				 *correct anymore.
728 				 */
729 				EVM = odm_evm_db_to_percentage(
730 					(phy_sta_rpt
731 						 ->stream_rxevm[i])); /* dbm */
732 
733 				/* Fill value in RFD, Get the first spatial
734 				 * stream only
735 				 */
736 				if (i == ODM_RF_PATH_A)
737 					phy_info->signal_quality =
738 						(u8)(EVM & 0xff);
739 				phy_info->rx_mimo_signal_quality[i] =
740 					(u8)(EVM & 0xff);
741 			}
742 		}
743 
744 		num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate);
745 		odm_parsing_cfo(dm, pktinfo, phy_sta_rpt->path_cfotail, num_ss);
746 	}
747 	/* UI BSS List signal strength(in percentage), make it good looking,
748 	 * from 0~100.
749 	 */
750 	/* It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp(). */
751 	if (is_cck_rate) {
752 		phy_info->signal_strength = (u8)(
753 			odm_signal_scale_mapping(dm, pwdb_all)); /*pwdb_all;*/
754 	} else {
755 		if (rf_rx_num != 0) {
756 			phy_info->signal_strength =
757 				(u8)(odm_signal_scale_mapping(dm, total_rssi /=
758 								  rf_rx_num));
759 		}
760 	}
761 
762 	/* For 92C/92D HW (Hybrid) Antenna Diversity */
763 }
764 
765 static void
odm_rx_phy_bw_jaguar_series_parsing(struct dm_phy_status_info * phy_info,struct dm_per_pkt_info * pktinfo,struct phy_status_rpt_8812 * phy_sta_rpt)766 odm_rx_phy_bw_jaguar_series_parsing(struct dm_phy_status_info *phy_info,
767 				    struct dm_per_pkt_info *pktinfo,
768 				    struct phy_status_rpt_8812 *phy_sta_rpt)
769 {
770 	if (pktinfo->data_rate <= ODM_RATE54M) {
771 		switch (phy_sta_rpt->r_RFMOD) {
772 		case 1:
773 			if (phy_sta_rpt->sub_chnl == 0)
774 				phy_info->band_width = 1;
775 			else
776 				phy_info->band_width = 0;
777 			break;
778 
779 		case 2:
780 			if (phy_sta_rpt->sub_chnl == 0)
781 				phy_info->band_width = 2;
782 			else if (phy_sta_rpt->sub_chnl == 9 ||
783 				 phy_sta_rpt->sub_chnl == 10)
784 				phy_info->band_width = 1;
785 			else
786 				phy_info->band_width = 0;
787 			break;
788 
789 		default:
790 		case 0:
791 			phy_info->band_width = 0;
792 			break;
793 		}
794 	}
795 }
796 
odm_rx_phy_status_jaguar_series_parsing(struct phy_dm_struct * dm,struct dm_phy_status_info * phy_info,u8 * phy_status,struct dm_per_pkt_info * pktinfo)797 static void odm_rx_phy_status_jaguar_series_parsing(
798 	struct phy_dm_struct *dm, struct dm_phy_status_info *phy_info,
799 	u8 *phy_status, struct dm_per_pkt_info *pktinfo)
800 {
801 	u8 i, max_spatial_stream;
802 	s8 rx_pwr[4], rx_pwr_all = 0;
803 	u8 EVM = 0, evm_dbm, pwdb_all = 0, pwdb_all_bt;
804 	u8 RSSI, avg_rssi = 0, best_rssi = 0, second_rssi = 0;
805 	u8 is_cck_rate = 0;
806 	u8 rf_rx_num = 0;
807 	u8 cck_highpwr = 0;
808 	u8 LNA_idx, VGA_idx;
809 	struct phy_status_rpt_8812 *phy_sta_rpt =
810 		(struct phy_status_rpt_8812 *)phy_status;
811 	struct fast_antenna_training *fat_tab = &dm->dm_fat_table;
812 	u8 num_ss;
813 
814 	odm_rx_phy_bw_jaguar_series_parsing(phy_info, pktinfo, phy_sta_rpt);
815 
816 	if (pktinfo->data_rate <= ODM_RATE11M)
817 		is_cck_rate = true;
818 	else
819 		is_cck_rate = false;
820 
821 	if (pktinfo->is_to_self)
822 		dm->curr_station_id = pktinfo->station_id;
823 	else
824 		dm->curr_station_id = 0xff;
825 
826 	phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = -1;
827 	phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1;
828 	phy_info->rx_mimo_signal_quality[ODM_RF_PATH_C] = -1;
829 	phy_info->rx_mimo_signal_quality[ODM_RF_PATH_D] = -1;
830 
831 	if (is_cck_rate) {
832 		u8 cck_agc_rpt;
833 
834 		dm->phy_dbg_info.num_qry_phy_status_cck++;
835 
836 		/*(1)Hardware does not provide RSSI for CCK*/
837 		/*(2)PWDB, Average PWDB calculated by hardware (for RA)*/
838 
839 		cck_highpwr = dm->is_cck_high_power;
840 
841 		cck_agc_rpt = phy_sta_rpt->cfosho[0];
842 		LNA_idx = ((cck_agc_rpt & 0xE0) >> 5);
843 		VGA_idx = (cck_agc_rpt & 0x1F);
844 
845 		if (dm->support_ic_type == ODM_RTL8812) {
846 			rx_pwr_all =
847 				phydm_get_rx_pwr(LNA_idx, VGA_idx, cck_highpwr);
848 			rx_pwr_all += 6;
849 			pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
850 			pwdb_all = phydm_adjust_pwdb(cck_highpwr, pwdb_all);
851 
852 		} else if (dm->support_ic_type & (ODM_RTL8821 | ODM_RTL8881A)) {
853 			s8 pout = -6;
854 
855 			switch (LNA_idx) {
856 			case 5:
857 				rx_pwr_all = pout - 32 - (2 * VGA_idx);
858 				break;
859 			case 4:
860 				rx_pwr_all = pout - 24 - (2 * VGA_idx);
861 				break;
862 			case 2:
863 				rx_pwr_all = pout - 11 - (2 * VGA_idx);
864 				break;
865 			case 1:
866 				rx_pwr_all = pout + 5 - (2 * VGA_idx);
867 				break;
868 			case 0:
869 				rx_pwr_all = pout + 21 - (2 * VGA_idx);
870 				break;
871 			}
872 			pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
873 		} else if (dm->support_ic_type == ODM_RTL8814A ||
874 			   dm->support_ic_type == ODM_RTL8822B) {
875 			s8 pout = -6;
876 
877 			switch (LNA_idx) {
878 			/*CCK only use LNA: 2, 3, 5, 7*/
879 			case 7:
880 				rx_pwr_all = pout - 32 - (2 * VGA_idx);
881 				break;
882 			case 5:
883 				rx_pwr_all = pout - 22 - (2 * VGA_idx);
884 				break;
885 			case 3:
886 				rx_pwr_all = pout - 2 - (2 * VGA_idx);
887 				break;
888 			case 2:
889 				rx_pwr_all = pout + 5 - (2 * VGA_idx);
890 				break;
891 			default:
892 				break;
893 			}
894 			pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
895 		}
896 
897 		dm->cck_lna_idx = LNA_idx;
898 		dm->cck_vga_idx = VGA_idx;
899 		phy_info->rx_pwdb_all = pwdb_all;
900 		phy_info->bt_rx_rssi_percentage = pwdb_all;
901 		phy_info->recv_signal_power = rx_pwr_all;
902 		/*(3) Get Signal Quality (EVM)*/
903 		{
904 			u8 sq;
905 
906 			if ((dm->support_platform == ODM_WIN) &&
907 			    (dm->patch_id == RT_CID_819X_LENOVO))
908 				sq = odm_sq_process_patch_rt_cid_819x_lenovo(
909 					dm, is_cck_rate, pwdb_all, 0, 0);
910 			else
911 				sq = phydm_get_signal_quality_8812(phy_info, dm,
912 								   phy_sta_rpt);
913 
914 			phy_info->signal_quality = sq;
915 			phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = sq;
916 		}
917 
918 		for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
919 			if (i == 0)
920 				phy_info->rx_mimo_signal_strength[0] = pwdb_all;
921 			else
922 				phy_info->rx_mimo_signal_strength[i] = 0;
923 		}
924 	} else {
925 		/*is OFDM rate*/
926 		fat_tab->hw_antsw_occur = phy_sta_rpt->hw_antsw_occur;
927 
928 		dm->phy_dbg_info.num_qry_phy_status_ofdm++;
929 
930 		/*(1)Get RSSI for OFDM rate*/
931 
932 		for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
933 			/*2008/01/30 MH we will judge RF RX path now.*/
934 			if (dm->rf_path_rx_enable & BIT(i))
935 				rf_rx_num++;
936 			/*2012.05.25 LukeLee: Testchip AGC report is wrong,
937 			 *it should be restored back to old formula in MP chip
938 			 */
939 			if (i < ODM_RF_PATH_C)
940 				rx_pwr[i] = (phy_sta_rpt->gain_trsw[i] & 0x7F) -
941 					    110;
942 			else
943 				rx_pwr[i] = (phy_sta_rpt->gain_trsw_cd[i - 2] &
944 					     0x7F) -
945 					    110;
946 
947 			phy_info->rx_pwr[i] = rx_pwr[i];
948 
949 			/* Translate DBM to percentage. */
950 			RSSI = odm_query_rx_pwr_percentage(rx_pwr[i]);
951 
952 			/*total_rssi += RSSI;*/
953 			/*Get the best two RSSI*/
954 			if (RSSI > best_rssi && RSSI > second_rssi) {
955 				second_rssi = best_rssi;
956 				best_rssi = RSSI;
957 			} else if (RSSI > second_rssi && RSSI <= best_rssi) {
958 				second_rssi = RSSI;
959 			}
960 
961 			phy_info->rx_mimo_signal_strength[i] = (u8)RSSI;
962 
963 			/*Get Rx snr value in DB*/
964 			if (i < ODM_RF_PATH_C)
965 				phy_info->rx_snr[i] =
966 					dm->phy_dbg_info.rx_snr_db[i] =
967 						phy_sta_rpt->rxsnr[i] / 2;
968 			else if (dm->support_ic_type &
969 				 (ODM_RTL8814A | ODM_RTL8822B))
970 				phy_info->rx_snr[i] = dm->phy_dbg_info
971 							      .rx_snr_db[i] =
972 					phy_sta_rpt->csi_current[i - 2] / 2;
973 
974 			/*(2) CFO_short  & CFO_tail*/
975 			if (i < ODM_RF_PATH_C) {
976 				phy_info->cfo_short[i] =
977 					odm_cfo((phy_sta_rpt->cfosho[i]));
978 				phy_info->cfo_tail[i] =
979 					odm_cfo((phy_sta_rpt->cfotail[i]));
980 			}
981 		}
982 
983 		/*(3)PWDB, Average PWDB calculated by hardware (for RA)*/
984 
985 		/*2012.05.25 LukeLee: Testchip AGC report is wrong, it should be
986 		 *restored back to old formula in MP chip
987 		 */
988 		if ((dm->support_ic_type &
989 		     (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8881A)) &&
990 		    (!dm->is_mp_chip))
991 			rx_pwr_all = (phy_sta_rpt->pwdb_all & 0x7f) - 110;
992 		else
993 			rx_pwr_all = (((phy_sta_rpt->pwdb_all) >> 1) & 0x7f) -
994 				     110; /*OLD FORMULA*/
995 
996 		pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
997 		pwdb_all_bt = pwdb_all;
998 
999 		phy_info->rx_pwdb_all = pwdb_all;
1000 		phy_info->bt_rx_rssi_percentage = pwdb_all_bt;
1001 		phy_info->rx_power = rx_pwr_all;
1002 		phy_info->recv_signal_power = rx_pwr_all;
1003 
1004 		if ((dm->support_platform == ODM_WIN) && (dm->patch_id == 19)) {
1005 			/*do nothing*/
1006 		} else {
1007 			/*mgnt_info->customer_id != RT_CID_819X_LENOVO*/
1008 
1009 			/*(4)EVM of OFDM rate*/
1010 
1011 			if ((pktinfo->data_rate >= ODM_RATEMCS8) &&
1012 			    (pktinfo->data_rate <= ODM_RATEMCS15))
1013 				max_spatial_stream = 2;
1014 			else if ((pktinfo->data_rate >= ODM_RATEVHTSS2MCS0) &&
1015 				 (pktinfo->data_rate <= ODM_RATEVHTSS2MCS9))
1016 				max_spatial_stream = 2;
1017 			else if ((pktinfo->data_rate >= ODM_RATEMCS16) &&
1018 				 (pktinfo->data_rate <= ODM_RATEMCS23))
1019 				max_spatial_stream = 3;
1020 			else if ((pktinfo->data_rate >= ODM_RATEVHTSS3MCS0) &&
1021 				 (pktinfo->data_rate <= ODM_RATEVHTSS3MCS9))
1022 				max_spatial_stream = 3;
1023 			else
1024 				max_spatial_stream = 1;
1025 
1026 			for (i = 0; i < max_spatial_stream; i++) {
1027 				/*Don't use shift operation like "rx_evmX >>= 1"
1028 				 *because the compilor of free build environment
1029 				 *fill most significant bit to "zero" when doing
1030 				 *shifting operation which may change a negative
1031 				 *value to positive one, then the dbm value
1032 				 *(which is supposed to be negative) is not
1033 				 *correct anymore.
1034 				 */
1035 
1036 				EVM = phydm_get_odm_evm(i, pktinfo,
1037 							phy_sta_rpt);
1038 				evm_dbm = phydm_get_evm_dbm(i, EVM, phy_sta_rpt,
1039 							    phy_info);
1040 				phy_info->rx_mimo_signal_quality[i] = EVM;
1041 				phy_info->rx_mimo_evm_dbm[i] = evm_dbm;
1042 			}
1043 		}
1044 
1045 		num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate);
1046 		odm_parsing_cfo(dm, pktinfo, phy_sta_rpt->cfotail, num_ss);
1047 	}
1048 
1049 	/*UI BSS List signal strength(in percentage), make it good looking,
1050 	 *from 0~100.
1051 	 */
1052 	/*It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().*/
1053 	if (is_cck_rate) {
1054 		phy_info->signal_strength = (u8)(
1055 			odm_signal_scale_mapping(dm, pwdb_all)); /*pwdb_all;*/
1056 	} else {
1057 		if (rf_rx_num != 0) {
1058 			/* 2015/01 Sean, use the best two RSSI only,
1059 			 * suggested by Ynlin and ChenYu.
1060 			 */
1061 			if (rf_rx_num == 1)
1062 				avg_rssi = best_rssi;
1063 			else
1064 				avg_rssi = (best_rssi + second_rssi) / 2;
1065 			phy_info->signal_strength =
1066 				(u8)(odm_signal_scale_mapping(dm, avg_rssi));
1067 		}
1068 	}
1069 	dm->rx_pwdb_ave = dm->rx_pwdb_ave + phy_info->rx_pwdb_all;
1070 
1071 	dm->dm_fat_table.antsel_rx_keep_0 = phy_sta_rpt->antidx_anta;
1072 	dm->dm_fat_table.antsel_rx_keep_1 = phy_sta_rpt->antidx_antb;
1073 	dm->dm_fat_table.antsel_rx_keep_2 = phy_sta_rpt->antidx_antc;
1074 	dm->dm_fat_table.antsel_rx_keep_3 = phy_sta_rpt->antidx_antd;
1075 }
1076 
phydm_reset_rssi_for_dm(struct phy_dm_struct * dm,u8 station_id)1077 void phydm_reset_rssi_for_dm(struct phy_dm_struct *dm, u8 station_id)
1078 {
1079 	struct rtl_sta_info *entry;
1080 
1081 	entry = dm->odm_sta_info[station_id];
1082 
1083 	if (!IS_STA_VALID(entry))
1084 		return;
1085 
1086 	ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
1087 		     "Reset RSSI for macid = (( %d ))\n", station_id);
1088 
1089 	entry->rssi_stat.undecorated_smoothed_cck = -1;
1090 	entry->rssi_stat.undecorated_smoothed_ofdm = -1;
1091 	entry->rssi_stat.undecorated_smoothed_pwdb = -1;
1092 	entry->rssi_stat.ofdm_pkt = 0;
1093 	entry->rssi_stat.cck_pkt = 0;
1094 	entry->rssi_stat.cck_sum_power = 0;
1095 	entry->rssi_stat.is_send_rssi = RA_RSSI_STATE_INIT;
1096 	entry->rssi_stat.packet_map = 0;
1097 	entry->rssi_stat.valid_bit = 0;
1098 }
1099 
odm_init_rssi_for_dm(struct phy_dm_struct * dm)1100 void odm_init_rssi_for_dm(struct phy_dm_struct *dm) {}
1101 
odm_process_rssi_for_dm(struct phy_dm_struct * dm,struct dm_phy_status_info * phy_info,struct dm_per_pkt_info * pktinfo)1102 static void odm_process_rssi_for_dm(struct phy_dm_struct *dm,
1103 				    struct dm_phy_status_info *phy_info,
1104 				    struct dm_per_pkt_info *pktinfo)
1105 {
1106 	s32 undecorated_smoothed_pwdb, undecorated_smoothed_cck,
1107 		undecorated_smoothed_ofdm;
1108 	u8 is_cck_rate = 0;
1109 	u8 send_rssi_2_fw = 0;
1110 	struct rtl_sta_info *entry;
1111 
1112 	if (pktinfo->station_id >= ODM_ASSOCIATE_ENTRY_NUM)
1113 		return;
1114 
1115 	/* 2012/05/30 MH/Luke.Lee Add some description */
1116 	/* In windows driver: AP/IBSS mode STA */
1117 	entry = dm->odm_sta_info[pktinfo->station_id];
1118 
1119 	if (!IS_STA_VALID(entry))
1120 		return;
1121 
1122 	{
1123 		if ((!pktinfo->is_packet_match_bssid)) /*data frame only*/
1124 			return;
1125 	}
1126 
1127 	if (pktinfo->is_packet_beacon)
1128 		dm->phy_dbg_info.num_qry_beacon_pkt++;
1129 
1130 	is_cck_rate = (pktinfo->data_rate <= ODM_RATE11M) ? true : false;
1131 	dm->rx_rate = pktinfo->data_rate;
1132 
1133 	/* --------------Statistic for antenna/path diversity---------------- */
1134 
1135 	/* -----------------Smart Antenna Debug Message------------------ */
1136 
1137 	undecorated_smoothed_cck = entry->rssi_stat.undecorated_smoothed_cck;
1138 	undecorated_smoothed_ofdm = entry->rssi_stat.undecorated_smoothed_ofdm;
1139 	undecorated_smoothed_pwdb = entry->rssi_stat.undecorated_smoothed_pwdb;
1140 
1141 	if (pktinfo->is_packet_to_self || pktinfo->is_packet_beacon) {
1142 		if (!is_cck_rate) /* ofdm rate */
1143 			undecorated_smoothed_ofdm = phydm_process_rssi_ofdm(
1144 				dm, phy_info, entry, undecorated_smoothed_ofdm);
1145 		else
1146 			undecorated_smoothed_cck = phydm_process_rssi_cck(
1147 				dm, phy_info, entry, undecorated_smoothed_cck);
1148 
1149 		undecorated_smoothed_pwdb = phydm_process_rssi_pwdb(
1150 			dm, entry, pktinfo, undecorated_smoothed_ofdm,
1151 			undecorated_smoothed_cck);
1152 
1153 		if ((entry->rssi_stat.ofdm_pkt >= 1 ||
1154 		     entry->rssi_stat.cck_pkt >= 5) &&
1155 		    (entry->rssi_stat.is_send_rssi == RA_RSSI_STATE_INIT)) {
1156 			send_rssi_2_fw = 1;
1157 			entry->rssi_stat.is_send_rssi = RA_RSSI_STATE_SEND;
1158 		}
1159 
1160 		entry->rssi_stat.undecorated_smoothed_cck =
1161 			undecorated_smoothed_cck;
1162 		entry->rssi_stat.undecorated_smoothed_ofdm =
1163 			undecorated_smoothed_ofdm;
1164 		entry->rssi_stat.undecorated_smoothed_pwdb =
1165 			undecorated_smoothed_pwdb;
1166 
1167 		if (send_rssi_2_fw) { /* Trigger init rate by RSSI */
1168 
1169 			if (entry->rssi_stat.ofdm_pkt != 0)
1170 				entry->rssi_stat.undecorated_smoothed_pwdb =
1171 					undecorated_smoothed_ofdm;
1172 
1173 			ODM_RT_TRACE(
1174 				dm, ODM_COMP_RSSI_MONITOR,
1175 				"[Send to FW] PWDB = (( %d )), ofdm_pkt = (( %d )), cck_pkt = (( %d ))\n",
1176 				undecorated_smoothed_pwdb,
1177 				entry->rssi_stat.ofdm_pkt,
1178 				entry->rssi_stat.cck_pkt);
1179 		}
1180 	}
1181 }
1182 
1183 /*
1184  * Endianness before calling this API
1185  */
odm_phy_status_query_92c_series(struct phy_dm_struct * dm,struct dm_phy_status_info * phy_info,u8 * phy_status,struct dm_per_pkt_info * pktinfo)1186 static void odm_phy_status_query_92c_series(struct phy_dm_struct *dm,
1187 					    struct dm_phy_status_info *phy_info,
1188 					    u8 *phy_status,
1189 					    struct dm_per_pkt_info *pktinfo)
1190 {
1191 	odm_rx_phy_status92c_series_parsing(dm, phy_info, phy_status, pktinfo);
1192 	odm_process_rssi_for_dm(dm, phy_info, pktinfo);
1193 }
1194 
1195 /*
1196  * Endianness before calling this API
1197  */
1198 
odm_phy_status_query_jaguar_series(struct phy_dm_struct * dm,struct dm_phy_status_info * phy_info,u8 * phy_status,struct dm_per_pkt_info * pktinfo)1199 static void odm_phy_status_query_jaguar_series(
1200 	struct phy_dm_struct *dm, struct dm_phy_status_info *phy_info,
1201 	u8 *phy_status, struct dm_per_pkt_info *pktinfo)
1202 {
1203 	odm_rx_phy_status_jaguar_series_parsing(dm, phy_info, phy_status,
1204 						pktinfo);
1205 	odm_process_rssi_for_dm(dm, phy_info, pktinfo);
1206 }
1207 
odm_phy_status_query(struct phy_dm_struct * dm,struct dm_phy_status_info * phy_info,u8 * phy_status,struct dm_per_pkt_info * pktinfo)1208 void odm_phy_status_query(struct phy_dm_struct *dm,
1209 			  struct dm_phy_status_info *phy_info, u8 *phy_status,
1210 			  struct dm_per_pkt_info *pktinfo)
1211 {
1212 	if (dm->support_ic_type & ODM_IC_PHY_STATUE_NEW_TYPE) {
1213 		phydm_rx_phy_status_new_type(dm, phy_status, pktinfo, phy_info);
1214 		return;
1215 	}
1216 
1217 	if (dm->support_ic_type & ODM_IC_11AC_SERIES)
1218 		odm_phy_status_query_jaguar_series(dm, phy_info, phy_status,
1219 						   pktinfo);
1220 
1221 	if (dm->support_ic_type & ODM_IC_11N_SERIES)
1222 		odm_phy_status_query_92c_series(dm, phy_info, phy_status,
1223 						pktinfo);
1224 }
1225 
1226 /* For future use. */
odm_mac_status_query(struct phy_dm_struct * dm,u8 * mac_status,u8 mac_id,bool is_packet_match_bssid,bool is_packet_to_self,bool is_packet_beacon)1227 void odm_mac_status_query(struct phy_dm_struct *dm, u8 *mac_status, u8 mac_id,
1228 			  bool is_packet_match_bssid, bool is_packet_to_self,
1229 			  bool is_packet_beacon)
1230 {
1231 	/* 2011/10/19 Driver team will handle in the future. */
1232 }
1233 
1234 /*
1235  * If you want to add a new IC, Please follow below template and generate
1236  * a new one.
1237  */
1238 
1239 enum hal_status
odm_config_rf_with_header_file(struct phy_dm_struct * dm,enum odm_rf_config_type config_type,enum odm_rf_radio_path e_rf_path)1240 odm_config_rf_with_header_file(struct phy_dm_struct *dm,
1241 			       enum odm_rf_config_type config_type,
1242 			       enum odm_rf_radio_path e_rf_path)
1243 {
1244 	ODM_RT_TRACE(dm, ODM_COMP_INIT,
1245 		     "===>%s (%s)\n", __func__,
1246 		     (dm->is_mp_chip) ? "MPChip" : "TestChip");
1247 	ODM_RT_TRACE(
1248 		dm, ODM_COMP_INIT,
1249 		"dm->support_platform: 0x%X, dm->support_interface: 0x%X, dm->board_type: 0x%X\n",
1250 		dm->support_platform, dm->support_interface, dm->board_type);
1251 
1252 	/* 1 AP doesn't use PHYDM power tracking table in these ICs */
1253 	/* JJ ADD 20161014 */
1254 
1255 	/* 1 All platforms support */
1256 	if (dm->support_ic_type == ODM_RTL8822B) {
1257 		if (config_type == CONFIG_RF_RADIO) {
1258 			if (e_rf_path == ODM_RF_PATH_A)
1259 				READ_AND_CONFIG_MP(8822b, _radioa);
1260 			else if (e_rf_path == ODM_RF_PATH_B)
1261 				READ_AND_CONFIG_MP(8822b, _radiob);
1262 		} else if (config_type == CONFIG_RF_TXPWR_LMT) {
1263 			if (dm->rfe_type == 5)
1264 				READ_AND_CONFIG_MP(8822b, _txpwr_lmt_type5);
1265 			else
1266 				READ_AND_CONFIG_MP(8822b, _txpwr_lmt);
1267 		}
1268 	}
1269 
1270 	return HAL_STATUS_SUCCESS;
1271 }
1272 
1273 enum hal_status
odm_config_rf_with_tx_pwr_track_header_file(struct phy_dm_struct * dm)1274 odm_config_rf_with_tx_pwr_track_header_file(struct phy_dm_struct *dm)
1275 {
1276 	ODM_RT_TRACE(dm, ODM_COMP_INIT,
1277 		     "===>%s (%s)\n", __func__,
1278 		     (dm->is_mp_chip) ? "MPChip" : "TestChip");
1279 	ODM_RT_TRACE(
1280 		dm, ODM_COMP_INIT,
1281 		"dm->support_platform: 0x%X, dm->support_interface: 0x%X, dm->board_type: 0x%X\n",
1282 		dm->support_platform, dm->support_interface, dm->board_type);
1283 
1284 	/* 1 AP doesn't use PHYDM power tracking table in these ICs */
1285 	/* JJ ADD 20161014 */
1286 
1287 	/* 1 All platforms support */
1288 
1289 	if (dm->support_ic_type == ODM_RTL8822B) {
1290 		if (dm->rfe_type == 0)
1291 			READ_AND_CONFIG_MP(8822b, _txpowertrack_type0);
1292 		else if (dm->rfe_type == 1)
1293 			READ_AND_CONFIG_MP(8822b, _txpowertrack_type1);
1294 		else if (dm->rfe_type == 2)
1295 			READ_AND_CONFIG_MP(8822b, _txpowertrack_type2);
1296 		else if ((dm->rfe_type == 3) || (dm->rfe_type == 5))
1297 			READ_AND_CONFIG_MP(8822b, _txpowertrack_type3_type5);
1298 		else if (dm->rfe_type == 4)
1299 			READ_AND_CONFIG_MP(8822b, _txpowertrack_type4);
1300 		else if (dm->rfe_type == 6)
1301 			READ_AND_CONFIG_MP(8822b, _txpowertrack_type6);
1302 		else if (dm->rfe_type == 7)
1303 			READ_AND_CONFIG_MP(8822b, _txpowertrack_type7);
1304 		else if (dm->rfe_type == 8)
1305 			READ_AND_CONFIG_MP(8822b, _txpowertrack_type8);
1306 		else if (dm->rfe_type == 9)
1307 			READ_AND_CONFIG_MP(8822b, _txpowertrack_type9);
1308 		else
1309 			READ_AND_CONFIG_MP(8822b, _txpowertrack);
1310 	}
1311 
1312 	return HAL_STATUS_SUCCESS;
1313 }
1314 
1315 enum hal_status
odm_config_bb_with_header_file(struct phy_dm_struct * dm,enum odm_bb_config_type config_type)1316 odm_config_bb_with_header_file(struct phy_dm_struct *dm,
1317 			       enum odm_bb_config_type config_type)
1318 {
1319 	/* 1 AP doesn't use PHYDM initialization in these ICs */
1320 	/* JJ ADD 20161014 */
1321 
1322 	/* 1 All platforms support */
1323 	if (dm->support_ic_type == ODM_RTL8822B) {
1324 		if (config_type == CONFIG_BB_PHY_REG)
1325 			READ_AND_CONFIG_MP(8822b, _phy_reg);
1326 		else if (config_type == CONFIG_BB_AGC_TAB)
1327 			READ_AND_CONFIG_MP(8822b, _agc_tab);
1328 		else if (config_type == CONFIG_BB_PHY_REG_PG)
1329 			READ_AND_CONFIG_MP(8822b, _phy_reg_pg);
1330 		/*else if (config_type == CONFIG_BB_PHY_REG_MP)*/
1331 		/*READ_AND_CONFIG_MP(8822b, _phy_reg_mp);*/
1332 	}
1333 
1334 	return HAL_STATUS_SUCCESS;
1335 }
1336 
odm_config_mac_with_header_file(struct phy_dm_struct * dm)1337 enum hal_status odm_config_mac_with_header_file(struct phy_dm_struct *dm)
1338 {
1339 	ODM_RT_TRACE(dm, ODM_COMP_INIT,
1340 		     "===>%s (%s)\n", __func__,
1341 		     (dm->is_mp_chip) ? "MPChip" : "TestChip");
1342 	ODM_RT_TRACE(
1343 		dm, ODM_COMP_INIT,
1344 		"dm->support_platform: 0x%X, dm->support_interface: 0x%X, dm->board_type: 0x%X\n",
1345 		dm->support_platform, dm->support_interface, dm->board_type);
1346 
1347 	/* 1 AP doesn't use PHYDM initialization in these ICs */
1348 	/* JJ ADD 20161014 */
1349 
1350 	/* 1 All platforms support */
1351 	if (dm->support_ic_type == ODM_RTL8822B)
1352 		READ_AND_CONFIG_MP(8822b, _mac_reg);
1353 
1354 	return HAL_STATUS_SUCCESS;
1355 }
1356 
1357 enum hal_status
odm_config_fw_with_header_file(struct phy_dm_struct * dm,enum odm_fw_config_type config_type,u8 * p_firmware,u32 * size)1358 odm_config_fw_with_header_file(struct phy_dm_struct *dm,
1359 			       enum odm_fw_config_type config_type,
1360 			       u8 *p_firmware, u32 *size)
1361 {
1362 	return HAL_STATUS_SUCCESS;
1363 }
1364 
odm_get_hw_img_version(struct phy_dm_struct * dm)1365 u32 odm_get_hw_img_version(struct phy_dm_struct *dm)
1366 {
1367 	u32 version = 0;
1368 
1369 	/* 1 AP doesn't use PHYDM initialization in these ICs */
1370 	/* JJ ADD 20161014 */
1371 
1372 	/*1 All platforms support*/
1373 	if (dm->support_ic_type == ODM_RTL8822B)
1374 		version = GET_VERSION_MP(8822b, _mac_reg);
1375 
1376 	return version;
1377 }
1378 
1379 /* For 8822B only!! need to move to FW finally */
1380 /*==============================================*/
1381 
phydm_query_is_mu_api(struct phy_dm_struct * phydm,u8 ppdu_idx,u8 * p_data_rate,u8 * p_gid)1382 bool phydm_query_is_mu_api(struct phy_dm_struct *phydm, u8 ppdu_idx,
1383 			   u8 *p_data_rate, u8 *p_gid)
1384 {
1385 	u8 data_rate = 0, gid = 0;
1386 	bool is_mu = false;
1387 
1388 	data_rate = phydm->phy_dbg_info.num_of_ppdu[ppdu_idx];
1389 	gid = phydm->phy_dbg_info.gid_num[ppdu_idx];
1390 
1391 	if (data_rate & BIT(7)) {
1392 		is_mu = true;
1393 		data_rate = data_rate & ~(BIT(7));
1394 	} else {
1395 		is_mu = false;
1396 	}
1397 
1398 	*p_data_rate = data_rate;
1399 	*p_gid = gid;
1400 
1401 	return is_mu;
1402 }
1403 
phydm_rx_statistic_cal(struct phy_dm_struct * phydm,u8 * phy_status,struct dm_per_pkt_info * pktinfo)1404 static void phydm_rx_statistic_cal(struct phy_dm_struct *phydm, u8 *phy_status,
1405 				   struct dm_per_pkt_info *pktinfo)
1406 {
1407 	struct phy_status_rpt_jaguar2_type1 *phy_sta_rpt =
1408 		(struct phy_status_rpt_jaguar2_type1 *)phy_status;
1409 	u8 date_rate = pktinfo->data_rate & ~(BIT(7));
1410 
1411 	if ((phy_sta_rpt->gid != 0) && (phy_sta_rpt->gid != 63)) {
1412 		if (date_rate >= ODM_RATEVHTSS1MCS0) {
1413 			phydm->phy_dbg_info
1414 				.num_qry_mu_vht_pkt[date_rate - 0x2C]++;
1415 			phydm->phy_dbg_info.num_of_ppdu[pktinfo->ppdu_cnt] =
1416 				date_rate | BIT(7);
1417 			phydm->phy_dbg_info.gid_num[pktinfo->ppdu_cnt] =
1418 				phy_sta_rpt->gid;
1419 		}
1420 
1421 	} else {
1422 		if (date_rate >= ODM_RATEVHTSS1MCS0) {
1423 			phydm->phy_dbg_info.num_qry_vht_pkt[date_rate - 0x2C]++;
1424 			phydm->phy_dbg_info.num_of_ppdu[pktinfo->ppdu_cnt] =
1425 				date_rate;
1426 			phydm->phy_dbg_info.gid_num[pktinfo->ppdu_cnt] =
1427 				phy_sta_rpt->gid;
1428 		}
1429 	}
1430 }
1431 
phydm_reset_phy_info(struct phy_dm_struct * phydm,struct dm_phy_status_info * phy_info)1432 static void phydm_reset_phy_info(struct phy_dm_struct *phydm,
1433 				 struct dm_phy_status_info *phy_info)
1434 {
1435 	phy_info->rx_pwdb_all = 0;
1436 	phy_info->signal_quality = 0;
1437 	phy_info->band_width = 0;
1438 	phy_info->rx_count = 0;
1439 	odm_memory_set(phydm, phy_info->rx_mimo_signal_quality, 0, 4);
1440 	odm_memory_set(phydm, phy_info->rx_mimo_signal_strength, 0, 4);
1441 	odm_memory_set(phydm, phy_info->rx_snr, 0, 4);
1442 
1443 	phy_info->rx_power = -110;
1444 	phy_info->recv_signal_power = -110;
1445 	phy_info->bt_rx_rssi_percentage = 0;
1446 	phy_info->signal_strength = 0;
1447 	phy_info->bt_coex_pwr_adjust = 0;
1448 	phy_info->channel = 0;
1449 	phy_info->is_mu_packet = 0;
1450 	phy_info->is_beamformed = 0;
1451 	phy_info->rxsc = 0;
1452 	odm_memory_set(phydm, phy_info->rx_pwr, -110, 4);
1453 	odm_memory_set(phydm, phy_info->rx_mimo_evm_dbm, 0, 4);
1454 	odm_memory_set(phydm, phy_info->cfo_short, 0, 8);
1455 	odm_memory_set(phydm, phy_info->cfo_tail, 0, 8);
1456 }
1457 
phydm_set_per_path_phy_info(u8 rx_path,s8 rx_pwr,s8 rx_evm,s8 cfo_tail,s8 rx_snr,struct dm_phy_status_info * phy_info)1458 static void phydm_set_per_path_phy_info(u8 rx_path, s8 rx_pwr, s8 rx_evm,
1459 					s8 cfo_tail, s8 rx_snr,
1460 					struct dm_phy_status_info *phy_info)
1461 {
1462 	u8 evm_dbm = 0;
1463 	u8 evm_percentage = 0;
1464 
1465 	/* SNR is S(8,1), EVM is S(8,1), CFO is S(8,7) */
1466 
1467 	if (rx_evm < 0) {
1468 		/* Calculate EVM in dBm */
1469 		evm_dbm = ((u8)(0 - rx_evm) >> 1);
1470 
1471 		/* Calculate EVM in percentage */
1472 		if (evm_dbm >= 33)
1473 			evm_percentage = 100;
1474 		else
1475 			evm_percentage = (evm_dbm << 1) + (evm_dbm);
1476 	}
1477 
1478 	phy_info->rx_pwr[rx_path] = rx_pwr;
1479 	phy_info->rx_mimo_evm_dbm[rx_path] = evm_dbm;
1480 
1481 	/* CFO = CFO_tail * 312.5 / 2^7 ~= CFO tail * 39/512 (kHz)*/
1482 	phy_info->cfo_tail[rx_path] = cfo_tail;
1483 	phy_info->cfo_tail[rx_path] = ((phy_info->cfo_tail[rx_path] << 5) +
1484 				       (phy_info->cfo_tail[rx_path] << 2) +
1485 				       (phy_info->cfo_tail[rx_path] << 1) +
1486 				       (phy_info->cfo_tail[rx_path])) >>
1487 				      9;
1488 
1489 	phy_info->rx_mimo_signal_strength[rx_path] =
1490 		odm_query_rx_pwr_percentage(rx_pwr);
1491 	phy_info->rx_mimo_signal_quality[rx_path] = evm_percentage;
1492 	phy_info->rx_snr[rx_path] = rx_snr >> 1;
1493 }
1494 
phydm_set_common_phy_info(s8 rx_power,u8 channel,bool is_beamformed,bool is_mu_packet,u8 bandwidth,u8 signal_quality,u8 rxsc,struct dm_phy_status_info * phy_info)1495 static void phydm_set_common_phy_info(s8 rx_power, u8 channel,
1496 				      bool is_beamformed, bool is_mu_packet,
1497 				      u8 bandwidth, u8 signal_quality, u8 rxsc,
1498 				      struct dm_phy_status_info *phy_info)
1499 {
1500 	phy_info->rx_power = rx_power; /* RSSI in dB */
1501 	phy_info->recv_signal_power = rx_power; /* RSSI in dB */
1502 	phy_info->channel = channel; /* channel number */
1503 	phy_info->is_beamformed = is_beamformed; /* apply BF */
1504 	phy_info->is_mu_packet = is_mu_packet; /* MU packet */
1505 	phy_info->rxsc = rxsc;
1506 	phy_info->rx_pwdb_all =
1507 		odm_query_rx_pwr_percentage(rx_power); /* RSSI in percentage */
1508 	phy_info->signal_quality = signal_quality; /* signal quality */
1509 	phy_info->band_width = bandwidth; /* bandwidth */
1510 }
1511 
phydm_get_rx_phy_status_type0(struct phy_dm_struct * dm,u8 * phy_status,struct dm_per_pkt_info * pktinfo,struct dm_phy_status_info * phy_info)1512 static void phydm_get_rx_phy_status_type0(struct phy_dm_struct *dm,
1513 					  u8 *phy_status,
1514 					  struct dm_per_pkt_info *pktinfo,
1515 					  struct dm_phy_status_info *phy_info)
1516 {
1517 	/* type 0 is used for cck packet */
1518 
1519 	struct phy_status_rpt_jaguar2_type0 *phy_sta_rpt =
1520 		(struct phy_status_rpt_jaguar2_type0 *)phy_status;
1521 	u8 sq = 0;
1522 	s8 rx_power = phy_sta_rpt->pwdb - 110;
1523 
1524 	/* JJ ADD 20161014 */
1525 
1526 	/* Calculate Signal Quality*/
1527 	if (pktinfo->is_packet_match_bssid) {
1528 		if (phy_sta_rpt->signal_quality >= 64) {
1529 			sq = 0;
1530 		} else if (phy_sta_rpt->signal_quality <= 20) {
1531 			sq = 100;
1532 		} else {
1533 			/* mapping to 2~99% */
1534 			sq = 64 - phy_sta_rpt->signal_quality;
1535 			sq = ((sq << 3) + sq) >> 2;
1536 		}
1537 	}
1538 
1539 	/* Modify CCK PWDB if old AGC */
1540 	if (!dm->cck_new_agc) {
1541 		u8 lna_idx, vga_idx;
1542 
1543 		lna_idx = ((phy_sta_rpt->lna_h << 3) | phy_sta_rpt->lna_l);
1544 		vga_idx = phy_sta_rpt->vga;
1545 
1546 		/* JJ ADD 20161014 */
1547 
1548 		/* Need to do !! */
1549 		/*if (dm->support_ic_type & ODM_RTL8822B) */
1550 		/*rx_power = odm_CCKRSSI_8822B(LNA_idx, VGA_idx);*/
1551 	}
1552 
1553 	/* Update CCK packet counter */
1554 	dm->phy_dbg_info.num_qry_phy_status_cck++;
1555 
1556 	/*CCK no STBC and LDPC*/
1557 	dm->phy_dbg_info.is_ldpc_pkt = false;
1558 	dm->phy_dbg_info.is_stbc_pkt = false;
1559 
1560 	/* Update Common information */
1561 	phydm_set_common_phy_info(rx_power, phy_sta_rpt->channel, false, false,
1562 				  ODM_BW20M, sq, phy_sta_rpt->rxsc, phy_info);
1563 
1564 	/* Update CCK pwdb */
1565 	/* Update per-path information */
1566 	phydm_set_per_path_phy_info(ODM_RF_PATH_A, rx_power, 0, 0, 0, phy_info);
1567 
1568 	dm->dm_fat_table.antsel_rx_keep_0 = phy_sta_rpt->antidx_a;
1569 	dm->dm_fat_table.antsel_rx_keep_1 = phy_sta_rpt->antidx_b;
1570 	dm->dm_fat_table.antsel_rx_keep_2 = phy_sta_rpt->antidx_c;
1571 	dm->dm_fat_table.antsel_rx_keep_3 = phy_sta_rpt->antidx_d;
1572 }
1573 
phydm_get_rx_phy_status_type1(struct phy_dm_struct * dm,u8 * phy_status,struct dm_per_pkt_info * pktinfo,struct dm_phy_status_info * phy_info)1574 static void phydm_get_rx_phy_status_type1(struct phy_dm_struct *dm,
1575 					  u8 *phy_status,
1576 					  struct dm_per_pkt_info *pktinfo,
1577 					  struct dm_phy_status_info *phy_info)
1578 {
1579 	/* type 1 is used for ofdm packet */
1580 
1581 	struct phy_status_rpt_jaguar2_type1 *phy_sta_rpt =
1582 		(struct phy_status_rpt_jaguar2_type1 *)phy_status;
1583 	s8 rx_pwr_db = -120;
1584 	u8 i, rxsc, bw = ODM_BW20M, rx_count = 0;
1585 	bool is_mu;
1586 	u8 num_ss;
1587 
1588 	/* Update OFDM packet counter */
1589 	dm->phy_dbg_info.num_qry_phy_status_ofdm++;
1590 
1591 	/* Update per-path information */
1592 	for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
1593 		if (dm->rx_ant_status & BIT(i)) {
1594 			s8 rx_path_pwr_db;
1595 
1596 			/* RX path counter */
1597 			rx_count++;
1598 
1599 			/* Update per-path information
1600 			 * (RSSI_dB RSSI_percentage EVM SNR CFO sq)
1601 			 */
1602 			/* EVM report is reported by stream, not path */
1603 			rx_path_pwr_db = phy_sta_rpt->pwdb[i] -
1604 					 110; /* per-path pwdb in dB domain */
1605 			phydm_set_per_path_phy_info(
1606 				i, rx_path_pwr_db,
1607 				phy_sta_rpt->rxevm[rx_count - 1],
1608 				phy_sta_rpt->cfo_tail[i], phy_sta_rpt->rxsnr[i],
1609 				phy_info);
1610 
1611 			/* search maximum pwdb */
1612 			if (rx_path_pwr_db > rx_pwr_db)
1613 				rx_pwr_db = rx_path_pwr_db;
1614 		}
1615 	}
1616 
1617 	/* mapping RX counter from 1~4 to 0~3 */
1618 	if (rx_count > 0)
1619 		phy_info->rx_count = rx_count - 1;
1620 
1621 	/* Check if MU packet or not */
1622 	if ((phy_sta_rpt->gid != 0) && (phy_sta_rpt->gid != 63)) {
1623 		is_mu = true;
1624 		dm->phy_dbg_info.num_qry_mu_pkt++;
1625 	} else {
1626 		is_mu = false;
1627 	}
1628 
1629 	/* count BF packet */
1630 	dm->phy_dbg_info.num_qry_bf_pkt =
1631 		dm->phy_dbg_info.num_qry_bf_pkt + phy_sta_rpt->beamformed;
1632 
1633 	/*STBC or LDPC pkt*/
1634 	dm->phy_dbg_info.is_ldpc_pkt = phy_sta_rpt->ldpc;
1635 	dm->phy_dbg_info.is_stbc_pkt = phy_sta_rpt->stbc;
1636 
1637 	/* Check sub-channel */
1638 	if ((pktinfo->data_rate > ODM_RATE11M) &&
1639 	    (pktinfo->data_rate < ODM_RATEMCS0))
1640 		rxsc = phy_sta_rpt->l_rxsc;
1641 	else
1642 		rxsc = phy_sta_rpt->ht_rxsc;
1643 
1644 	/* Check RX bandwidth */
1645 	if (dm->support_ic_type & ODM_RTL8822B) {
1646 		if ((rxsc >= 1) && (rxsc <= 8))
1647 			bw = ODM_BW20M;
1648 		else if ((rxsc >= 9) && (rxsc <= 12))
1649 			bw = ODM_BW40M;
1650 		else if (rxsc >= 13)
1651 			bw = ODM_BW80M;
1652 		else
1653 			bw = phy_sta_rpt->rf_mode;
1654 	} else if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8723D |
1655 					  ODM_RTL8710B)) { /* JJ ADD 20161014 */
1656 		if (phy_sta_rpt->rf_mode == 0)
1657 			bw = ODM_BW20M;
1658 		else if ((rxsc == 1) || (rxsc == 2))
1659 			bw = ODM_BW20M;
1660 		else
1661 			bw = ODM_BW40M;
1662 	}
1663 
1664 	/* Update packet information */
1665 	phydm_set_common_phy_info(
1666 		rx_pwr_db, phy_sta_rpt->channel, (bool)phy_sta_rpt->beamformed,
1667 		is_mu, bw, odm_evm_db_to_percentage(phy_sta_rpt->rxevm[0]),
1668 		rxsc, phy_info);
1669 
1670 	num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate);
1671 
1672 	odm_parsing_cfo(dm, pktinfo, phy_sta_rpt->cfo_tail, num_ss);
1673 	dm->dm_fat_table.antsel_rx_keep_0 = phy_sta_rpt->antidx_a;
1674 	dm->dm_fat_table.antsel_rx_keep_1 = phy_sta_rpt->antidx_b;
1675 	dm->dm_fat_table.antsel_rx_keep_2 = phy_sta_rpt->antidx_c;
1676 	dm->dm_fat_table.antsel_rx_keep_3 = phy_sta_rpt->antidx_d;
1677 
1678 	if (pktinfo->is_packet_match_bssid) {
1679 		/* */
1680 		phydm_rx_statistic_cal(dm, phy_status, pktinfo);
1681 	}
1682 }
1683 
phydm_get_rx_phy_status_type2(struct phy_dm_struct * dm,u8 * phy_status,struct dm_per_pkt_info * pktinfo,struct dm_phy_status_info * phy_info)1684 static void phydm_get_rx_phy_status_type2(struct phy_dm_struct *dm,
1685 					  u8 *phy_status,
1686 					  struct dm_per_pkt_info *pktinfo,
1687 					  struct dm_phy_status_info *phy_info)
1688 {
1689 	struct phy_status_rpt_jaguar2_type2 *phy_sta_rpt =
1690 		(struct phy_status_rpt_jaguar2_type2 *)phy_status;
1691 	s8 rx_pwr_db = -120;
1692 	u8 i, rxsc, bw = ODM_BW20M, rx_count = 0;
1693 
1694 	/* Update OFDM packet counter */
1695 	dm->phy_dbg_info.num_qry_phy_status_ofdm++;
1696 
1697 	/* Update per-path information */
1698 	for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
1699 		if (dm->rx_ant_status & BIT(i)) {
1700 			s8 rx_path_pwr_db;
1701 
1702 			/* RX path counter */
1703 			rx_count++;
1704 
1705 			/* Update per-path information
1706 			 * (RSSI_dB RSSI_percentage EVM SNR CFO sq)
1707 			 */
1708 			rx_path_pwr_db = phy_sta_rpt->pwdb[i] -
1709 					 110; /* per-path pwdb in dB domain */
1710 
1711 			phydm_set_per_path_phy_info(i, rx_path_pwr_db, 0, 0, 0,
1712 						    phy_info);
1713 
1714 			/* search maximum pwdb */
1715 			if (rx_path_pwr_db > rx_pwr_db)
1716 				rx_pwr_db = rx_path_pwr_db;
1717 		}
1718 	}
1719 
1720 	/* mapping RX counter from 1~4 to 0~3 */
1721 	if (rx_count > 0)
1722 		phy_info->rx_count = rx_count - 1;
1723 
1724 	/* Check RX sub-channel */
1725 	if ((pktinfo->data_rate > ODM_RATE11M) &&
1726 	    (pktinfo->data_rate < ODM_RATEMCS0))
1727 		rxsc = phy_sta_rpt->l_rxsc;
1728 	else
1729 		rxsc = phy_sta_rpt->ht_rxsc;
1730 
1731 	/*STBC or LDPC pkt*/
1732 	dm->phy_dbg_info.is_ldpc_pkt = phy_sta_rpt->ldpc;
1733 	dm->phy_dbg_info.is_stbc_pkt = phy_sta_rpt->stbc;
1734 
1735 	/* Check RX bandwidth */
1736 	/* the BW information of sc=0 is useless, because there is
1737 	 * no information of RF mode
1738 	 */
1739 
1740 	if (dm->support_ic_type & ODM_RTL8822B) {
1741 		if ((rxsc >= 1) && (rxsc <= 8))
1742 			bw = ODM_BW20M;
1743 		else if ((rxsc >= 9) && (rxsc <= 12))
1744 			bw = ODM_BW40M;
1745 		else if (rxsc >= 13)
1746 			bw = ODM_BW80M;
1747 		else
1748 			bw = ODM_BW20M;
1749 	} else if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8723D |
1750 					  ODM_RTL8710B)) { /* JJ ADD 20161014 */
1751 		if (rxsc == 3)
1752 			bw = ODM_BW40M;
1753 		else if ((rxsc == 1) || (rxsc == 2))
1754 			bw = ODM_BW20M;
1755 		else
1756 			bw = ODM_BW20M;
1757 	}
1758 
1759 	/* Update packet information */
1760 	phydm_set_common_phy_info(rx_pwr_db, phy_sta_rpt->channel,
1761 				  (bool)phy_sta_rpt->beamformed, false, bw, 0,
1762 				  rxsc, phy_info);
1763 }
1764 
1765 static void
phydm_process_rssi_for_dm_new_type(struct phy_dm_struct * dm,struct dm_phy_status_info * phy_info,struct dm_per_pkt_info * pktinfo)1766 phydm_process_rssi_for_dm_new_type(struct phy_dm_struct *dm,
1767 				   struct dm_phy_status_info *phy_info,
1768 				   struct dm_per_pkt_info *pktinfo)
1769 {
1770 	s32 undecorated_smoothed_pwdb, accumulate_pwdb;
1771 	u32 rssi_ave;
1772 	u8 i;
1773 	struct rtl_sta_info *entry;
1774 	u8 scaling_factor = 4;
1775 
1776 	if (pktinfo->station_id >= ODM_ASSOCIATE_ENTRY_NUM)
1777 		return;
1778 
1779 	entry = dm->odm_sta_info[pktinfo->station_id];
1780 
1781 	if (!IS_STA_VALID(entry))
1782 		return;
1783 
1784 	if ((!pktinfo->is_packet_match_bssid)) /*data frame only*/
1785 		return;
1786 
1787 	if (pktinfo->is_packet_beacon)
1788 		dm->phy_dbg_info.num_qry_beacon_pkt++;
1789 
1790 	if (pktinfo->is_packet_to_self || pktinfo->is_packet_beacon) {
1791 		u32 rssi_linear = 0;
1792 
1793 		dm->rx_rate = pktinfo->data_rate;
1794 		undecorated_smoothed_pwdb =
1795 			entry->rssi_stat.undecorated_smoothed_pwdb;
1796 		accumulate_pwdb = dm->accumulate_pwdb[pktinfo->station_id];
1797 		dm->rssi_a = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A];
1798 		dm->rssi_b = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B];
1799 		dm->rssi_c = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_C];
1800 		dm->rssi_d = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_D];
1801 
1802 		for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
1803 			if (phy_info->rx_mimo_signal_strength[i] != 0)
1804 				rssi_linear += odm_convert_to_linear(
1805 					phy_info->rx_mimo_signal_strength[i]);
1806 		}
1807 
1808 		switch (phy_info->rx_count + 1) {
1809 		case 2:
1810 			rssi_linear = (rssi_linear >> 1);
1811 			break;
1812 		case 3:
1813 			/* rssi_linear/3 ~ rssi_linear*11/32 */
1814 			rssi_linear = ((rssi_linear) + (rssi_linear << 1) +
1815 				       (rssi_linear << 3)) >>
1816 				      5;
1817 			break;
1818 		case 4:
1819 			rssi_linear = (rssi_linear >> 2);
1820 			break;
1821 		}
1822 		rssi_ave = odm_convert_to_db(rssi_linear);
1823 
1824 		if (undecorated_smoothed_pwdb <= 0) {
1825 			accumulate_pwdb =
1826 				(phy_info->rx_pwdb_all << scaling_factor);
1827 			undecorated_smoothed_pwdb = phy_info->rx_pwdb_all;
1828 		} else {
1829 			accumulate_pwdb = accumulate_pwdb -
1830 					  (accumulate_pwdb >> scaling_factor) +
1831 					  rssi_ave;
1832 			undecorated_smoothed_pwdb =
1833 				(accumulate_pwdb +
1834 				 (1 << (scaling_factor - 1))) >>
1835 				scaling_factor;
1836 		}
1837 
1838 		entry->rssi_stat.undecorated_smoothed_pwdb =
1839 			undecorated_smoothed_pwdb;
1840 		dm->accumulate_pwdb[pktinfo->station_id] = accumulate_pwdb;
1841 	}
1842 }
1843 
phydm_rx_phy_status_new_type(struct phy_dm_struct * phydm,u8 * phy_status,struct dm_per_pkt_info * pktinfo,struct dm_phy_status_info * phy_info)1844 void phydm_rx_phy_status_new_type(struct phy_dm_struct *phydm, u8 *phy_status,
1845 				  struct dm_per_pkt_info *pktinfo,
1846 				  struct dm_phy_status_info *phy_info)
1847 {
1848 	u8 phy_status_type = (*phy_status & 0xf);
1849 
1850 	/* Memory reset */
1851 	phydm_reset_phy_info(phydm, phy_info);
1852 
1853 	/* Phy status parsing */
1854 	switch (phy_status_type) {
1855 	case 0: {
1856 		phydm_get_rx_phy_status_type0(phydm, phy_status, pktinfo,
1857 					      phy_info);
1858 		break;
1859 	}
1860 	case 1: {
1861 		phydm_get_rx_phy_status_type1(phydm, phy_status, pktinfo,
1862 					      phy_info);
1863 		break;
1864 	}
1865 	case 2: {
1866 		phydm_get_rx_phy_status_type2(phydm, phy_status, pktinfo,
1867 					      phy_info);
1868 		break;
1869 	}
1870 	default:
1871 		return;
1872 	}
1873 
1874 	/* Update signal strength to UI, and phy_info->rx_pwdb_all is the
1875 	 * maximum RSSI of all path
1876 	 */
1877 	phy_info->signal_strength =
1878 		(u8)(odm_signal_scale_mapping(phydm, phy_info->rx_pwdb_all));
1879 
1880 	/* Calculate average RSSI and smoothed RSSI */
1881 	phydm_process_rssi_for_dm_new_type(phydm, phy_info, pktinfo);
1882 }
1883 
query_phydm_trx_capability(struct phy_dm_struct * dm)1884 u32 query_phydm_trx_capability(struct phy_dm_struct *dm)
1885 {
1886 	u32 value32 = 0xFFFFFFFF;
1887 
1888 	return value32;
1889 }
1890 
query_phydm_stbc_capability(struct phy_dm_struct * dm)1891 u32 query_phydm_stbc_capability(struct phy_dm_struct *dm)
1892 {
1893 	u32 value32 = 0xFFFFFFFF;
1894 
1895 	return value32;
1896 }
1897 
query_phydm_ldpc_capability(struct phy_dm_struct * dm)1898 u32 query_phydm_ldpc_capability(struct phy_dm_struct *dm)
1899 {
1900 	u32 value32 = 0xFFFFFFFF;
1901 
1902 	return value32;
1903 }
1904 
query_phydm_txbf_parameters(struct phy_dm_struct * dm)1905 u32 query_phydm_txbf_parameters(struct phy_dm_struct *dm)
1906 {
1907 	u32 value32 = 0xFFFFFFFF;
1908 
1909 	return value32;
1910 }
1911 
query_phydm_txbf_capability(struct phy_dm_struct * dm)1912 u32 query_phydm_txbf_capability(struct phy_dm_struct *dm)
1913 {
1914 	u32 value32 = 0xFFFFFFFF;
1915 
1916 	return value32;
1917 }
1918