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 CONFIG_ADAPTIVE_SOML
34
phydm_dynamicsoftmletting(void * dm_void)35 void phydm_dynamicsoftmletting(void *dm_void)
36 {
37 struct dm_struct *dm = (struct dm_struct *)dm_void;
38 u32 ret_val;
39
40 #if (RTL8822B_SUPPORT == 1)
41 if (!*dm->mp_mode) {
42 if (dm->support_ic_type & ODM_RTL8822B) {
43 if (!dm->is_linked | dm->iot_table.is_linked_cmw500)
44 return;
45
46 if (dm->bsomlenabled) {
47 PHYDM_DBG(dm, ODM_COMP_API,
48 "PHYDM_DynamicSoftMLSetting(): SoML has been enable, skip dynamic SoML switch\n");
49 return;
50 }
51
52 ret_val = odm_get_bb_reg(dm, R_0xf8c, MASKBYTE0);
53 PHYDM_DBG(dm, ODM_COMP_API,
54 "PHYDM_DynamicSoftMLSetting(): Read 0xF8C = 0x%08X\n",
55 ret_val);
56
57 if (ret_val < 0x16) {
58 PHYDM_DBG(dm, ODM_COMP_API,
59 "PHYDM_DynamicSoftMLSetting(): 0xF8C(== 0x%08X) < 0x16, enable SoML\n",
60 ret_val);
61 phydm_somlrxhp_setting(dm, true);
62 #if 0
63 /*odm_set_bb_reg(dm, R_0x19a8, MASKDWORD, 0xc10a0000);*/
64 #endif
65 dm->bsomlenabled = true;
66 }
67 }
68 }
69 #endif
70 }
71
phydm_soml_on_off(void * dm_void,u8 swch)72 void phydm_soml_on_off(void *dm_void, u8 swch)
73 {
74 struct dm_struct *dm = (struct dm_struct *)dm_void;
75 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
76
77 if (swch == SOML_ON) {
78 PHYDM_DBG(dm, DBG_ADPTV_SOML, "(( Turn on )) SOML\n");
79
80 if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8192F))
81 odm_set_bb_reg(dm, R_0x998, BIT(6), swch);
82 #if (RTL8822B_SUPPORT == 1)
83 else if (dm->support_ic_type == ODM_RTL8822B)
84 phydm_somlrxhp_setting(dm, true);
85 #endif
86
87 } else if (swch == SOML_OFF) {
88 PHYDM_DBG(dm, DBG_ADPTV_SOML, "(( Turn off )) SOML\n");
89
90 if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8192F))
91 odm_set_bb_reg(dm, R_0x998, BIT(6), swch);
92 #if (RTL8822B_SUPPORT == 1)
93 else if (dm->support_ic_type == ODM_RTL8822B)
94 phydm_somlrxhp_setting(dm, false);
95 #endif
96 }
97 soml_tab->soml_on_off = swch;
98 }
99
100 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
phydm_adaptive_soml_callback(struct phydm_timer_list * timer)101 void phydm_adaptive_soml_callback(struct phydm_timer_list *timer)
102 {
103 void *adapter = (void *)timer->Adapter;
104 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter));
105 struct dm_struct *dm = &hal_data->DM_OutSrc;
106 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
107
108 #if DEV_BUS_TYPE == RT_PCI_INTERFACE
109 #if USE_WORKITEM
110 odm_schedule_work_item(&soml_tab->phydm_adaptive_soml_workitem);
111 #else
112 {
113 #if 0
114 /*@dbg_print("%s\n",__func__);*/
115 #endif
116 phydm_adsl(dm);
117 }
118 #endif
119 #else
120 odm_schedule_work_item(&soml_tab->phydm_adaptive_soml_workitem);
121 #endif
122 }
123
phydm_adaptive_soml_workitem_callback(void * context)124 void phydm_adaptive_soml_workitem_callback(void *context)
125 {
126 #ifdef CONFIG_ADAPTIVE_SOML
127 void *adapter = (void *)context;
128 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter));
129 struct dm_struct *dm = &hal_data->DM_OutSrc;
130
131 #if 0
132 /*@dbg_print("%s\n",__func__);*/
133 #endif
134 phydm_adsl(dm);
135 #endif
136 }
137
138 #elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
phydm_adaptive_soml_callback(void * dm_void)139 void phydm_adaptive_soml_callback(void *dm_void)
140 {
141 struct dm_struct *dm = (struct dm_struct *)dm_void;
142 void *padapter = dm->adapter;
143
144 if (*dm->is_net_closed == true)
145 return;
146 if (dm->support_interface == ODM_ITRF_PCIE)
147 phydm_adsl(dm);
148 else {
149 /* @Can't do I/O in timer callback*/
150 phydm_run_in_thread_cmd(dm,
151 phydm_adaptive_soml_workitem_callback,
152 dm);
153 }
154 }
155
phydm_adaptive_soml_workitem_callback(void * context)156 void phydm_adaptive_soml_workitem_callback(void *context)
157 {
158 struct dm_struct *dm = (void *)context;
159
160 #if 0
161 /*@dbg_print("%s\n",__func__);*/
162 #endif
163 phydm_adsl(dm);
164 }
165
166 #else
phydm_adaptive_soml_callback(void * dm_void)167 void phydm_adaptive_soml_callback(void *dm_void)
168 {
169 struct dm_struct *dm = (struct dm_struct *)dm_void;
170
171 PHYDM_DBG(dm, DBG_ADPTV_SOML, "******SOML_Callback******\n");
172 phydm_adsl(dm);
173 }
174 #endif
175
phydm_rx_rate_for_soml(void * dm_void,void * pkt_info_void)176 void phydm_rx_rate_for_soml(void *dm_void, void *pkt_info_void)
177 {
178 struct dm_struct *dm = (struct dm_struct *)dm_void;
179 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
180 struct phydm_perpkt_info_struct *pktinfo = NULL;
181 u8 data_rate;
182
183 pktinfo = (struct phydm_perpkt_info_struct *)pkt_info_void;
184 data_rate = (pktinfo->data_rate & 0x7f);
185
186 if (pktinfo->data_rate >= ODM_RATEMCS0 &&
187 pktinfo->data_rate <= ODM_RATEMCS31)
188 soml_tab->ht_cnt[data_rate - ODM_RATEMCS0]++;
189 else if ((pktinfo->data_rate >= ODM_RATEVHTSS1MCS0) &&
190 (pktinfo->data_rate <= ODM_RATEVHTSS4MCS9))
191 soml_tab->vht_cnt[data_rate - ODM_RATEVHTSS1MCS0]++;
192 }
193
phydm_rx_qam_for_soml(void * dm_void,void * pkt_info_void)194 void phydm_rx_qam_for_soml(void *dm_void, void *pkt_info_void)
195 {
196 struct dm_struct *dm = (struct dm_struct *)dm_void;
197 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
198 struct phydm_perpkt_info_struct *pktinfo = NULL;
199 u8 date_rate;
200
201 pktinfo = (struct phydm_perpkt_info_struct *)pkt_info_void;
202 date_rate = (pktinfo->data_rate & 0x7f);
203 if (soml_tab->soml_state_cnt < (soml_tab->soml_train_num << 1)) {
204 if (soml_tab->soml_on_off == SOML_ON) {
205 return;
206 } else if (soml_tab->soml_on_off == SOML_OFF) {
207 if (date_rate >= ODM_RATEMCS8 &&
208 date_rate <= ODM_RATEMCS10)
209 soml_tab->num_ht_qam[BPSK_QPSK]++;
210
211 else if ((date_rate >= ODM_RATEMCS11) &&
212 (date_rate <= ODM_RATEMCS12))
213 soml_tab->num_ht_qam[QAM16]++;
214
215 else if ((date_rate >= ODM_RATEMCS13) &&
216 (date_rate <= ODM_RATEMCS15))
217 soml_tab->num_ht_qam[QAM64]++;
218
219 else if ((date_rate >= ODM_RATEVHTSS2MCS0) &&
220 (date_rate <= ODM_RATEVHTSS2MCS2))
221 soml_tab->num_vht_qam[BPSK_QPSK]++;
222
223 else if ((date_rate >= ODM_RATEVHTSS2MCS3) &&
224 (date_rate <= ODM_RATEVHTSS2MCS4))
225 soml_tab->num_vht_qam[QAM16]++;
226
227 else if ((date_rate >= ODM_RATEVHTSS2MCS5) &&
228 (date_rate <= ODM_RATEVHTSS2MCS5))
229 soml_tab->num_vht_qam[QAM64]++;
230
231 else if ((date_rate >= ODM_RATEVHTSS2MCS8) &&
232 (date_rate <= ODM_RATEVHTSS2MCS9))
233 soml_tab->num_vht_qam[QAM256]++;
234 }
235 }
236 }
237
phydm_soml_reset_rx_rate(void * dm_void)238 void phydm_soml_reset_rx_rate(void *dm_void)
239 {
240 struct dm_struct *dm = (struct dm_struct *)dm_void;
241 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
242 u8 order;
243
244 for (order = 0; order < HT_RATE_IDX; order++) {
245 soml_tab->ht_cnt[order] = 0;
246 soml_tab->pre_ht_cnt[order] = 0;
247 soml_tab->ht_cnt_on[order] = 0;
248 soml_tab->ht_cnt_off[order] = 0;
249 soml_tab->ht_crc_ok_cnt_on[order] = 0;
250 soml_tab->ht_crc_fail_cnt_on[order] = 0;
251 soml_tab->ht_crc_ok_cnt_off[order] = 0;
252 soml_tab->ht_crc_fail_cnt_off[order] = 0;
253 }
254
255 for (order = 0; order < VHT_RATE_IDX; order++) {
256 soml_tab->vht_cnt[order] = 0;
257 soml_tab->pre_vht_cnt[order] = 0;
258 soml_tab->vht_cnt_on[order] = 0;
259 soml_tab->vht_cnt_off[order] = 0;
260 soml_tab->vht_crc_ok_cnt_on[order] = 0;
261 soml_tab->vht_crc_fail_cnt_on[order] = 0;
262 soml_tab->vht_crc_ok_cnt_off[order] = 0;
263 soml_tab->vht_crc_fail_cnt_off[order] = 0;
264 }
265 }
266
phydm_soml_reset_qam(void * dm_void)267 void phydm_soml_reset_qam(void *dm_void)
268 {
269 struct dm_struct *dm = (struct dm_struct *)dm_void;
270 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
271 u8 order;
272
273 for (order = 0; order < HT_ORDER_TYPE; order++)
274 soml_tab->num_ht_qam[order] = 0;
275
276 for (order = 0; order < VHT_ORDER_TYPE; order++)
277 soml_tab->num_vht_qam[order] = 0;
278 }
279
phydm_soml_cfo_process(void * dm_void,s32 * diff_a,s32 * diff_b)280 void phydm_soml_cfo_process(void *dm_void, s32 *diff_a, s32 *diff_b)
281 {
282 struct dm_struct *dm = (struct dm_struct *)dm_void;
283 u32 value32, value32_1, value32_2, value32_3;
284 s32 cfo_acq_a, cfo_acq_b, cfo_end_a, cfo_end_b;
285
286 value32 = odm_get_bb_reg(dm, R_0xd10, MASKDWORD);
287 value32_1 = odm_get_bb_reg(dm, R_0xd14, MASKDWORD);
288 value32_2 = odm_get_bb_reg(dm, R_0xd50, MASKDWORD);
289 value32_3 = odm_get_bb_reg(dm, R_0xd54, MASKDWORD);
290
291 cfo_acq_a = (s32)((value32 & 0x1fff0000) >> 16);
292 cfo_end_a = (s32)((value32_1 & 0x1fff0000) >> 16);
293 cfo_acq_b = (s32)((value32_2 & 0x1fff0000) >> 16);
294 cfo_end_b = (s32)((value32_3 & 0x1fff0000) >> 16);
295
296 *diff_a = ((cfo_acq_a >= cfo_end_a) ? (cfo_acq_a - cfo_end_a) :
297 (cfo_end_a - cfo_acq_a));
298 *diff_b = ((cfo_acq_b >= cfo_end_b) ? (cfo_acq_b - cfo_end_b) :
299 (cfo_end_b - cfo_acq_b));
300
301 *diff_a = ((*diff_a * 312) + (*diff_a >> 1)) >> 12; /* @312.5/2^12 */
302 *diff_b = ((*diff_b * 312) + (*diff_b >> 1)) >> 12; /* @312.5/2^12 */
303 }
304
phydm_soml_debug(void * dm_void,char input[][16],u32 * _used,char * output,u32 * _out_len)305 void phydm_soml_debug(void *dm_void, char input[][16], u32 *_used,
306 char *output, u32 *_out_len)
307 {
308 struct dm_struct *dm = (struct dm_struct *)dm_void;
309 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
310 u32 used = *_used;
311 u32 out_len = *_out_len;
312 u32 dm_value[10] = {0};
313 u8 i = 0, input_idx = 0;
314
315 if (!(dm->support_ability & ODM_BB_ADAPTIVE_SOML))
316 return;
317
318 for (i = 0; i < 5; i++) {
319 if (input[i + 1]) {
320 PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &dm_value[i]);
321 input_idx++;
322 }
323 }
324
325 if (input_idx == 0)
326 return;
327
328 if (dm_value[0] == 1) { /*Turn on/off SOML*/
329 soml_tab->soml_select = (u8)dm_value[1];
330
331 } else if (dm_value[0] == 2) { /*training number for SOML*/
332
333 soml_tab->soml_train_num = (u8)dm_value[1];
334 PDM_SNPF(out_len, used, output + used, out_len - used,
335 "soml_train_num = ((%d))\n",
336 soml_tab->soml_train_num);
337 } else if (dm_value[0] == 3) { /*training interval for SOML*/
338
339 soml_tab->soml_intvl = (u8)dm_value[1];
340 PDM_SNPF(out_len, used, output + used, out_len - used,
341 "soml_intvl = ((%d))\n", soml_tab->soml_intvl);
342 } else if (dm_value[0] == 4) { /*@function period for SOML*/
343
344 soml_tab->soml_period = (u8)dm_value[1];
345 PDM_SNPF(out_len, used, output + used, out_len - used,
346 "soml_period = ((%d))\n", soml_tab->soml_period);
347 } else if (dm_value[0] == 5) { /*@delay_time for SOML*/
348
349 soml_tab->soml_delay_time = (u8)dm_value[1];
350 PDM_SNPF(out_len, used, output + used, out_len - used,
351 "soml_delay_time = ((%d))\n",
352 soml_tab->soml_delay_time);
353 } else if (dm_value[0] == 6) { /* @for SOML Rx QAM distribution th*/
354 if (dm_value[1] == 256) {
355 soml_tab->qam256_dist_th = (u8)dm_value[2];
356 PDM_SNPF(out_len, used, output + used, out_len - used,
357 "qam256_dist_th = ((%d))\n",
358 soml_tab->qam256_dist_th);
359 } else if (dm_value[1] == 64) {
360 soml_tab->qam64_dist_th = (u8)dm_value[2];
361 PDM_SNPF(out_len, used, output + used, out_len - used,
362 "qam64_dist_th = ((%d))\n",
363 soml_tab->qam64_dist_th);
364 } else if (dm_value[1] == 16) {
365 soml_tab->qam16_dist_th = (u8)dm_value[2];
366 PDM_SNPF(out_len, used, output + used, out_len - used,
367 "qam16_dist_th = ((%d))\n",
368 soml_tab->qam16_dist_th);
369 } else if (dm_value[1] == 4) {
370 soml_tab->bpsk_qpsk_dist_th = (u8)dm_value[2];
371 PDM_SNPF(out_len, used, output + used, out_len - used,
372 "bpsk_qpsk_dist_th = ((%d))\n",
373 soml_tab->bpsk_qpsk_dist_th);
374 }
375 } else if (dm_value[0] == 7) { /* @for SOML cfo th*/
376 if (dm_value[1] == 256) {
377 soml_tab->cfo_qam256_th = (u8)dm_value[2];
378 PDM_SNPF(out_len, used, output + used, out_len - used,
379 "cfo_qam256_th = ((%d KHz))\n",
380 soml_tab->cfo_qam256_th);
381 } else if (dm_value[1] == 64) {
382 soml_tab->cfo_qam64_th = (u8)dm_value[2];
383 PDM_SNPF(out_len, used, output + used, out_len - used,
384 "cfo_qam64_th = ((%d KHz))\n",
385 soml_tab->cfo_qam64_th);
386 } else if (dm_value[1] == 16) {
387 soml_tab->cfo_qam16_th = (u8)dm_value[2];
388 PDM_SNPF(out_len, used, output + used, out_len - used,
389 "cfo_qam16_th = ((%d KHz))\n",
390 soml_tab->cfo_qam16_th);
391 } else if (dm_value[1] == 4) {
392 soml_tab->cfo_qpsk_th = (u8)dm_value[2];
393 PDM_SNPF(out_len, used, output + used, out_len - used,
394 "cfo_qpsk_th = ((%d KHz))\n",
395 soml_tab->cfo_qpsk_th);
396 }
397 } else if (dm_value[0] == 100) {
398 /*show parameters*/
399 PDM_SNPF(out_len, used, output + used, out_len - used,
400 "soml_select = ((%d))\n", soml_tab->soml_select);
401 PDM_SNPF(out_len, used, output + used, out_len - used,
402 "soml_train_num = ((%d))\n",
403 soml_tab->soml_train_num);
404 PDM_SNPF(out_len, used, output + used, out_len - used,
405 "soml_intvl = ((%d))\n", soml_tab->soml_intvl);
406 PDM_SNPF(out_len, used, output + used, out_len - used,
407 "soml_period = ((%d))\n", soml_tab->soml_period);
408 PDM_SNPF(out_len, used, output + used, out_len - used,
409 "soml_delay_time = ((%d))\n\n",
410 soml_tab->soml_delay_time);
411 PDM_SNPF(out_len, used, output + used, out_len - used,
412 "qam256_dist_th = ((%d)), qam64_dist_th = ((%d)), ",
413 soml_tab->qam256_dist_th,
414 soml_tab->qam64_dist_th);
415 PDM_SNPF(out_len, used, output + used, out_len - used,
416 "qam16_dist_th = ((%d)), bpsk_qpsk_dist_th = ((%d))\n",
417 soml_tab->qam16_dist_th,
418 soml_tab->bpsk_qpsk_dist_th);
419 PDM_SNPF(out_len, used, output + used, out_len - used,
420 "cfo_qam256_th = ((%d KHz)), cfo_qam64_th = ((%d KHz)), ",
421 soml_tab->cfo_qam256_th,
422 soml_tab->cfo_qam64_th);
423 PDM_SNPF(out_len, used, output + used, out_len - used,
424 "cfo_qam16_th = ((%d KHz)), cfo_qpsk_th = ((%d KHz))\n",
425 soml_tab->cfo_qam16_th,
426 soml_tab->cfo_qpsk_th);
427 }
428 *_used = used;
429 *_out_len = out_len;
430 }
431
phydm_soml_stats_ht_on(void * dm_void)432 void phydm_soml_stats_ht_on(void *dm_void)
433 {
434 struct dm_struct *dm = (struct dm_struct *)dm_void;
435 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
436 u8 i, mcs0;
437 u16 num_bytes_diff, num_rate_diff;
438
439 mcs0 = ODM_RATEMCS0;
440 for (i = mcs0; i <= ODM_RATEMCS15; i++) {
441 num_rate_diff = soml_tab->ht_cnt[i - mcs0] -
442 soml_tab->pre_ht_cnt[i - mcs0];
443 soml_tab->ht_cnt_on[i - mcs0] += num_rate_diff;
444 soml_tab->pre_ht_cnt[i - mcs0] = soml_tab->ht_cnt[i - mcs0];
445 num_bytes_diff = soml_tab->ht_byte[i - mcs0] -
446 soml_tab->pre_ht_byte[i - mcs0];
447 soml_tab->ht_byte_on[i - mcs0] += num_bytes_diff;
448 soml_tab->pre_ht_byte[i - mcs0] = soml_tab->ht_byte[i - mcs0];
449 }
450 }
451
phydm_soml_stats_ht_off(void * dm_void)452 void phydm_soml_stats_ht_off(void *dm_void)
453 {
454 struct dm_struct *dm = (struct dm_struct *)dm_void;
455 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
456 u8 i, mcs0;
457 u16 num_bytes_diff, num_rate_diff;
458
459 mcs0 = ODM_RATEMCS0;
460 for (i = mcs0; i <= ODM_RATEMCS15; i++) {
461 num_rate_diff = soml_tab->ht_cnt[i - mcs0] -
462 soml_tab->pre_ht_cnt[i - mcs0];
463 soml_tab->ht_cnt_off[i - mcs0] += num_rate_diff;
464 soml_tab->pre_ht_cnt[i - mcs0] = soml_tab->ht_cnt[i - mcs0];
465 num_bytes_diff = soml_tab->ht_byte[i - mcs0] -
466 soml_tab->pre_ht_byte[i - mcs0];
467 soml_tab->ht_byte_off[i - mcs0] += num_bytes_diff;
468 soml_tab->pre_ht_byte[i - mcs0] = soml_tab->ht_byte[i - mcs0];
469 }
470 }
471
phydm_soml_stats_vht_on(void * dm_void)472 void phydm_soml_stats_vht_on(void *dm_void)
473 {
474 struct dm_struct *dm = (struct dm_struct *)dm_void;
475 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
476 u8 j, vht0;
477 u16 num_bytes_diff, num_rate_diff;
478
479 vht0 = ODM_RATEVHTSS1MCS0;
480 for (j = vht0; j <= ODM_RATEVHTSS2MCS9; j++) {
481 num_rate_diff = soml_tab->vht_cnt[j - vht0] -
482 soml_tab->pre_vht_cnt[j - vht0];
483 soml_tab->vht_cnt_on[j - vht0] += num_rate_diff;
484 soml_tab->pre_vht_cnt[j - vht0] = soml_tab->vht_cnt[j - vht0];
485 num_bytes_diff = soml_tab->vht_byte[j - vht0] -
486 soml_tab->pre_vht_byte[j - vht0];
487 soml_tab->vht_byte_on[j - vht0] += num_bytes_diff;
488 soml_tab->pre_vht_byte[j - vht0] = soml_tab->vht_byte[j - vht0];
489 }
490 }
491
phydm_soml_stats_vht_off(void * dm_void)492 void phydm_soml_stats_vht_off(void *dm_void)
493 {
494 struct dm_struct *dm = (struct dm_struct *)dm_void;
495 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
496 u8 j, vht0;
497 u16 num_bytes_diff, num_rate_diff;
498
499 vht0 = ODM_RATEVHTSS1MCS0;
500 for (j = vht0; j <= ODM_RATEVHTSS2MCS9; j++) {
501 num_rate_diff = soml_tab->vht_cnt[j - vht0] -
502 soml_tab->pre_vht_cnt[j - vht0];
503 soml_tab->vht_cnt_off[j - vht0] += num_rate_diff;
504 soml_tab->pre_vht_cnt[j - vht0] = soml_tab->vht_cnt[j - vht0];
505 num_bytes_diff = soml_tab->vht_byte[j - vht0] -
506 soml_tab->pre_vht_byte[j - vht0];
507 soml_tab->vht_byte_off[j - vht0] += num_bytes_diff;
508 soml_tab->pre_vht_byte[j - vht0] = soml_tab->vht_byte[j - vht0];
509 }
510 }
511
phydm_soml_statistics(void * dm_void,u8 on_off_state)512 void phydm_soml_statistics(void *dm_void, u8 on_off_state)
513 {
514 struct dm_struct *dm = (struct dm_struct *)dm_void;
515 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
516
517 if (on_off_state == SOML_ON) {
518 if (*dm->channel <= 14)
519 phydm_soml_stats_ht_on(dm);
520 if (dm->support_ic_type == ODM_RTL8822B)
521 phydm_soml_stats_vht_on(dm);
522 } else if (on_off_state == SOML_OFF) {
523 if (*dm->channel <= 14)
524 phydm_soml_stats_ht_off(dm);
525 if (dm->support_ic_type == ODM_RTL8822B)
526 phydm_soml_stats_vht_off(dm);
527 }
528 }
529
phydm_adsl_init_state(void * dm_void)530 void phydm_adsl_init_state(void *dm_void)
531 {
532 struct dm_struct *dm = (struct dm_struct *)dm_void;
533 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
534
535 u8 next_on_off;
536 u16 ht_reset[HT_RATE_IDX] = {0}, vht_reset[VHT_RATE_IDX] = {0};
537 u8 size = sizeof(ht_reset[0]);
538
539 phydm_soml_reset_rx_rate(dm);
540 odm_move_memory(dm, soml_tab->ht_byte, ht_reset,
541 HT_RATE_IDX * size);
542 odm_move_memory(dm, soml_tab->ht_byte_on, ht_reset,
543 HT_RATE_IDX * size);
544 odm_move_memory(dm, soml_tab->ht_byte_off, ht_reset,
545 HT_RATE_IDX * size);
546 odm_move_memory(dm, soml_tab->vht_byte, vht_reset,
547 VHT_RATE_IDX * size);
548 odm_move_memory(dm, soml_tab->vht_byte_on, vht_reset,
549 VHT_RATE_IDX * size);
550 odm_move_memory(dm, soml_tab->vht_byte_off, vht_reset,
551 VHT_RATE_IDX * size);
552 if (dm->support_ic_type == ODM_RTL8822B) {
553 soml_tab->cfo_cnt++;
554 phydm_soml_cfo_process(dm,
555 &soml_tab->cfo_diff_a,
556 &soml_tab->cfo_diff_b);
557 PHYDM_DBG(dm, DBG_ADPTV_SOML,
558 "[ (%d) cfo_diff_a = %d KHz; cfo_diff_b = %d KHz ]\n",
559 soml_tab->cfo_cnt, soml_tab->cfo_diff_a,
560 soml_tab->cfo_diff_b);
561 soml_tab->cfo_diff_sum_a += soml_tab->cfo_diff_a;
562 soml_tab->cfo_diff_sum_b += soml_tab->cfo_diff_b;
563 }
564
565 soml_tab->is_soml_method_enable = 1;
566 soml_tab->get_stats = false;
567 soml_tab->soml_state_cnt++;
568 next_on_off = (soml_tab->soml_on_off == SOML_ON) ? SOML_ON : SOML_OFF;
569 phydm_soml_on_off(dm, next_on_off);
570 odm_set_timer(dm, &soml_tab->phydm_adaptive_soml_timer,
571 soml_tab->soml_delay_time); /*@ms*/
572 }
573
phydm_adsl_odd_state(void * dm_void)574 void phydm_adsl_odd_state(void *dm_void)
575 {
576 struct dm_struct *dm = (struct dm_struct *)dm_void;
577 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
578 u16 ht_reset[HT_RATE_IDX] = {0}, vht_reset[VHT_RATE_IDX] = {0};
579 u8 size = sizeof(ht_reset[0]);
580
581 soml_tab->get_stats = true;
582 soml_tab->soml_state_cnt++;
583 odm_move_memory(dm, soml_tab->pre_ht_cnt, soml_tab->ht_cnt,
584 HT_RATE_IDX * size);
585 odm_move_memory(dm, soml_tab->pre_vht_cnt, soml_tab->vht_cnt,
586 VHT_RATE_IDX * size);
587 odm_move_memory(dm, soml_tab->pre_ht_byte, soml_tab->ht_byte,
588 HT_RATE_IDX * size);
589 odm_move_memory(dm, soml_tab->pre_vht_byte, soml_tab->vht_byte,
590 VHT_RATE_IDX * size);
591
592 if (dm->support_ic_type == ODM_RTL8822B) {
593 soml_tab->cfo_cnt++;
594 phydm_soml_cfo_process(dm,
595 &soml_tab->cfo_diff_a,
596 &soml_tab->cfo_diff_b);
597 PHYDM_DBG(dm, DBG_ADPTV_SOML,
598 "[ (%d) cfo_diff_a = %d KHz; cfo_diff_b = %d KHz ]\n",
599 soml_tab->cfo_cnt, soml_tab->cfo_diff_a,
600 soml_tab->cfo_diff_b);
601 soml_tab->cfo_diff_sum_a += soml_tab->cfo_diff_a;
602 soml_tab->cfo_diff_sum_b += soml_tab->cfo_diff_b;
603 }
604 odm_set_timer(dm, &soml_tab->phydm_adaptive_soml_timer,
605 soml_tab->soml_intvl); /*@ms*/
606 }
607
phydm_adsl_even_state(void * dm_void)608 void phydm_adsl_even_state(void *dm_void)
609 {
610 struct dm_struct *dm = (struct dm_struct *)dm_void;
611 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
612 u8 next_on_off;
613
614 soml_tab->get_stats = false;
615 if (dm->support_ic_type == ODM_RTL8822B) {
616 soml_tab->cfo_cnt++;
617 phydm_soml_cfo_process(dm,
618 &soml_tab->cfo_diff_a,
619 &soml_tab->cfo_diff_b);
620 PHYDM_DBG(dm, DBG_ADPTV_SOML,
621 "[ (%d) cfo_diff_a = %d KHz; cfo_diff_b = %d KHz ]\n",
622 soml_tab->cfo_cnt, soml_tab->cfo_diff_a,
623 soml_tab->cfo_diff_b);
624 soml_tab->cfo_diff_sum_a += soml_tab->cfo_diff_a;
625 soml_tab->cfo_diff_sum_b += soml_tab->cfo_diff_b;
626 }
627 soml_tab->soml_state_cnt++;
628 phydm_soml_statistics(dm, soml_tab->soml_on_off);
629 next_on_off = (soml_tab->soml_on_off == SOML_ON) ? SOML_OFF : SOML_ON;
630 phydm_soml_on_off(dm, next_on_off);
631 odm_set_timer(dm, &soml_tab->phydm_adaptive_soml_timer,
632 soml_tab->soml_delay_time); /*@ms*/
633 }
634
phydm_adsl_decision_state(void * dm_void)635 void phydm_adsl_decision_state(void *dm_void)
636 {
637 struct dm_struct *dm = (struct dm_struct *)dm_void;
638 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
639 boolean on_above = false, off_above = false;
640 u8 i, max_idx_on = 0, max_idx_off = 0;
641 u8 next_on_off = soml_tab->soml_last_state;
642 u8 mcs0 = ODM_RATEMCS0, vht0 = ODM_RATEVHTSS1MCS0;
643 u8 crc_taget = soml_tab->soml_last_state;
644 u8 rate_num = 1, ss_shift = 0;
645 u16 ht_ok_max_on = 0, ht_fail_max_on = 0, utility_on = 0;
646 u16 ht_ok_max_off = 0, ht_fail_max_off = 0, utility_off = 0;
647 u16 vht_ok_max_on = 0, vht_fail_max_on = 0;
648 u16 vht_ok_max_off = 0, vht_fail_max_off = 0;
649 u16 num_total_qam = 0;
650 u16 cnt_max_on = 0, cnt_max_off = 0;
651 u32 ht_total_cnt_on = 0, ht_total_cnt_off = 0;
652 u32 total_ht_rate_on = 0, total_ht_rate_off = 0;
653 u32 vht_total_cnt_on = 0, vht_total_cnt_off = 0;
654 u32 total_vht_rate_on = 0, total_vht_rate_off = 0;
655 u32 rate_per_pkt_on = 0, rate_per_pkt_off = 0;
656 s32 cfo_diff_avg_a, cfo_diff_avg_b;
657 u16 vht_phy_rate_table[] = {
658 /*@20M*/
659 6, 13, 19, 26, 39, 52, 58, 65, 78, 90, /*@1SS MCS0~9*/
660 13, 26, 39, 52, 78, 104, 117, 130, 156, 180 /*@2SSMCS0~9*/
661 };
662
663 if (dm->support_ic_type & ODM_IC_1SS)
664 rate_num = 1;
665 #ifdef PHYDM_COMPILE_ABOVE_2SS
666 else if (dm->support_ic_type & ODM_IC_2SS)
667 rate_num = 2;
668 #endif
669 #ifdef PHYDM_COMPILE_ABOVE_3SS
670 else if (dm->support_ic_type & ODM_IC_3SS)
671 rate_num = 3;
672 #endif
673 #ifdef PHYDM_COMPILE_ABOVE_4SS
674 else if (dm->support_ic_type & ODM_IC_4SS)
675 rate_num = 4;
676 #endif
677 else
678 pr_debug("%s: mismatch IC type %x\n", __func__,
679 dm->support_ic_type);
680 soml_tab->get_stats = false;
681 PHYDM_DBG(dm, DBG_ADPTV_SOML, "[Decisoin state ]\n");
682 phydm_soml_statistics(dm, soml_tab->soml_on_off);
683 if (*dm->channel <= 14) {
684 /* @[Search 1st and 2nd rate by counter] */
685 for (i = 0; i < rate_num; i++) {
686 ss_shift = (i << 3);
687 PHYDM_DBG(dm, DBG_ADPTV_SOML,
688 "*ht_cnt_on HT MCS[%d :%d ] = {%d, %d, %d, %d, %d, %d, %d, %d}\n",
689 (ss_shift), (ss_shift + 7),
690 soml_tab->ht_cnt_on[ss_shift + 0],
691 soml_tab->ht_cnt_on[ss_shift + 1],
692 soml_tab->ht_cnt_on[ss_shift + 2],
693 soml_tab->ht_cnt_on[ss_shift + 3],
694 soml_tab->ht_cnt_on[ss_shift + 4],
695 soml_tab->ht_cnt_on[ss_shift + 5],
696 soml_tab->ht_cnt_on[ss_shift + 6],
697 soml_tab->ht_cnt_on[ss_shift + 7]);
698 }
699
700 for (i = 0; i < rate_num; i++) {
701 ss_shift = (i << 3);
702 PHYDM_DBG(dm, DBG_ADPTV_SOML,
703 "*ht_cnt_off HT MCS[%d :%d ] = {%d, %d, %d, %d, %d, %d, %d, %d}\n",
704 (ss_shift), (ss_shift + 7),
705 soml_tab->ht_cnt_off[ss_shift + 0],
706 soml_tab->ht_cnt_off[ss_shift + 1],
707 soml_tab->ht_cnt_off[ss_shift + 2],
708 soml_tab->ht_cnt_off[ss_shift + 3],
709 soml_tab->ht_cnt_off[ss_shift + 4],
710 soml_tab->ht_cnt_off[ss_shift + 5],
711 soml_tab->ht_cnt_off[ss_shift + 6],
712 soml_tab->ht_cnt_off[ss_shift + 7]);
713 }
714
715 for (i = 0; i < rate_num; i++) {
716 ss_shift = (i << 3);
717 PHYDM_DBG(dm, DBG_ADPTV_SOML,
718 "*ht_crc_ok_cnt_on HT MCS[%d :%d ] = {%d, %d, %d, %d, %d, %d, %d, %d}\n",
719 (ss_shift), (ss_shift + 7),
720 soml_tab->ht_crc_ok_cnt_on[ss_shift + 0],
721 soml_tab->ht_crc_ok_cnt_on[ss_shift + 1],
722 soml_tab->ht_crc_ok_cnt_on[ss_shift + 2],
723 soml_tab->ht_crc_ok_cnt_on[ss_shift + 3],
724 soml_tab->ht_crc_ok_cnt_on[ss_shift + 4],
725 soml_tab->ht_crc_ok_cnt_on[ss_shift + 5],
726 soml_tab->ht_crc_ok_cnt_on[ss_shift + 6],
727 soml_tab->ht_crc_ok_cnt_on[ss_shift + 7]);
728 }
729
730 for (i = 0; i < rate_num; i++) {
731 ss_shift = (i << 3);
732 PHYDM_DBG(dm, DBG_ADPTV_SOML,
733 "*ht_crc_fail_cnt_on HT MCS[%d :%d ] = {%d, %d, %d, %d, %d, %d, %d, %d}\n",
734 (ss_shift), (ss_shift + 7),
735 soml_tab->ht_crc_fail_cnt_on[ss_shift + 0],
736 soml_tab->ht_crc_fail_cnt_on[ss_shift + 1],
737 soml_tab->ht_crc_fail_cnt_on[ss_shift + 2],
738 soml_tab->ht_crc_fail_cnt_on[ss_shift + 3],
739 soml_tab->ht_crc_fail_cnt_on[ss_shift + 4],
740 soml_tab->ht_crc_fail_cnt_on[ss_shift + 5],
741 soml_tab->ht_crc_fail_cnt_on[ss_shift + 6],
742 soml_tab->ht_crc_fail_cnt_on[ss_shift + 7]);
743 }
744
745 for (i = 0; i < rate_num; i++) {
746 ss_shift = (i << 3);
747 PHYDM_DBG(dm, DBG_ADPTV_SOML,
748 "*ht_crc_ok_cnt_off HT MCS[%d :%d ] = {%d, %d, %d, %d, %d, %d, %d, %d}\n",
749 (ss_shift), (ss_shift + 7),
750 soml_tab->ht_crc_ok_cnt_off[ss_shift + 0],
751 soml_tab->ht_crc_ok_cnt_off[ss_shift + 1],
752 soml_tab->ht_crc_ok_cnt_off[ss_shift + 2],
753 soml_tab->ht_crc_ok_cnt_off[ss_shift + 3],
754 soml_tab->ht_crc_ok_cnt_off[ss_shift + 4],
755 soml_tab->ht_crc_ok_cnt_off[ss_shift + 5],
756 soml_tab->ht_crc_ok_cnt_off[ss_shift + 6],
757 soml_tab->ht_crc_ok_cnt_off[ss_shift + 7]);
758 }
759
760 for (i = 0; i < rate_num; i++) {
761 ss_shift = (i << 3);
762 PHYDM_DBG(dm, DBG_ADPTV_SOML,
763 "*ht_crc_fail_cnt_off HT MCS[%d :%d ] = {%d, %d, %d, %d, %d, %d, %d, %d}\n",
764 (ss_shift), (ss_shift + 7),
765 soml_tab->ht_crc_fail_cnt_off[ss_shift + 0],
766 soml_tab->ht_crc_fail_cnt_off[ss_shift + 1],
767 soml_tab->ht_crc_fail_cnt_off[ss_shift + 2],
768 soml_tab->ht_crc_fail_cnt_off[ss_shift + 3],
769 soml_tab->ht_crc_fail_cnt_off[ss_shift + 4],
770 soml_tab->ht_crc_fail_cnt_off[ss_shift + 5],
771 soml_tab->ht_crc_fail_cnt_off[ss_shift + 6],
772 soml_tab->ht_crc_fail_cnt_off[ss_shift + 7]);
773 }
774 for (i = ODM_RATEMCS0; i <= ODM_RATEMCS15; i++) {
775 ht_total_cnt_on += soml_tab->ht_cnt_on[i - mcs0];
776 ht_total_cnt_off += soml_tab->ht_cnt_off[i - mcs0];
777 total_ht_rate_on += (soml_tab->ht_cnt_on[i - mcs0] *
778 phy_rate_table[i]);
779 total_ht_rate_off += (soml_tab->ht_cnt_off[i - mcs0] *
780 phy_rate_table[i]);
781 if (soml_tab->ht_cnt_on[i - mcs0] > cnt_max_on) {
782 cnt_max_on = soml_tab->ht_cnt_on[i - mcs0];
783 max_idx_on = i - mcs0;
784 }
785
786 if (soml_tab->ht_cnt_off[i - mcs0] > cnt_max_off) {
787 cnt_max_off = soml_tab->ht_cnt_off[i - mcs0];
788 max_idx_off = i - mcs0;
789 }
790 }
791 total_ht_rate_on = total_ht_rate_on << 3;
792 total_ht_rate_off = total_ht_rate_off << 3;
793 rate_per_pkt_on = (ht_total_cnt_on != 0) ?
794 (total_ht_rate_on / ht_total_cnt_on) : 0;
795 rate_per_pkt_off = (ht_total_cnt_off != 0) ?
796 (total_ht_rate_off / ht_total_cnt_off) : 0;
797 #if (DM_ODM_SUPPORT_TYPE == ODM_AP)
798 ht_ok_max_on = soml_tab->ht_crc_ok_cnt_on[max_idx_on];
799 ht_fail_max_on = soml_tab->ht_crc_fail_cnt_on[max_idx_on];
800 ht_ok_max_off = soml_tab->ht_crc_ok_cnt_off[max_idx_off];
801 ht_fail_max_off = soml_tab->ht_crc_fail_cnt_off[max_idx_off];
802
803 if (ht_fail_max_on == 0)
804 ht_fail_max_on = 1;
805
806 if (ht_fail_max_off == 0)
807 ht_fail_max_off = 1;
808
809 if (ht_ok_max_on > ht_fail_max_on)
810 on_above = true;
811
812 if (ht_ok_max_off > ht_fail_max_off)
813 off_above = true;
814
815 if (on_above && !off_above) {
816 crc_taget = SOML_ON;
817 } else if (!on_above && off_above) {
818 crc_taget = SOML_OFF;
819 } else if (on_above && off_above) {
820 utility_on = (ht_ok_max_on << 7) / ht_fail_max_on;
821 utility_off = (ht_ok_max_off << 7) / ht_fail_max_off;
822 crc_taget = (utility_on == utility_off) ?
823 (soml_tab->soml_last_state) :
824 ((utility_on > utility_off) ? SOML_ON :
825 SOML_OFF);
826
827 } else if (!on_above && !off_above) {
828 if (ht_ok_max_on == 0)
829 ht_ok_max_on = 1;
830 if (ht_ok_max_off == 0)
831 ht_ok_max_off = 1;
832 utility_on = (ht_fail_max_on << 7) / ht_ok_max_on;
833 utility_off = (ht_fail_max_off << 7) / ht_ok_max_off;
834 crc_taget = (utility_on == utility_off) ?
835 (soml_tab->soml_last_state) :
836 ((utility_on < utility_off) ? SOML_ON :
837 SOML_OFF);
838 }
839 #endif
840 } else if (dm->support_ic_type == ODM_RTL8822B) {
841 cfo_diff_avg_a = soml_tab->cfo_diff_sum_a / soml_tab->cfo_cnt;
842 cfo_diff_avg_b = soml_tab->cfo_diff_sum_b / soml_tab->cfo_cnt;
843 soml_tab->cfo_diff_avg_a = (soml_tab->cfo_cnt != 0) ?
844 cfo_diff_avg_a : 0;
845 soml_tab->cfo_diff_avg_b = (soml_tab->cfo_cnt != 0) ?
846 cfo_diff_avg_b : 0;
847 PHYDM_DBG(dm, DBG_ADPTV_SOML,
848 "[ cfo_diff_avg_a = %d KHz; cfo_diff_avg_b = %d KHz]\n",
849 soml_tab->cfo_diff_avg_a,
850 soml_tab->cfo_diff_avg_b);
851 for (i = 0; i < VHT_ORDER_TYPE; i++)
852 num_total_qam += soml_tab->num_vht_qam[i];
853
854 PHYDM_DBG(dm, DBG_ADPTV_SOML,
855 "[ ((2SS)) BPSK_QPSK_count = %d ; 16QAM_count = %d ; 64QAM_count = %d ; 256QAM_count = %d ; num_total_qam = %d]\n",
856 soml_tab->num_vht_qam[BPSK_QPSK],
857 soml_tab->num_vht_qam[QAM16],
858 soml_tab->num_vht_qam[QAM64],
859 soml_tab->num_vht_qam[QAM256],
860 num_total_qam);
861 if (((soml_tab->num_vht_qam[QAM256] * 100) >
862 (num_total_qam * soml_tab->qam256_dist_th)) &&
863 cfo_diff_avg_a > soml_tab->cfo_qam256_th &&
864 cfo_diff_avg_b > soml_tab->cfo_qam256_th) {
865 PHYDM_DBG(dm, DBG_ADPTV_SOML,
866 "[ QAM256_ratio > %d ; cfo_diff_avg_a > %d KHz ==> SOML_OFF]\n",
867 soml_tab->qam256_dist_th,
868 soml_tab->cfo_qam256_th);
869 PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ Final decisoin ] : ");
870 phydm_soml_on_off(dm, SOML_OFF);
871 return;
872 } else if (((soml_tab->num_vht_qam[QAM64] * 100) >
873 (num_total_qam * soml_tab->qam64_dist_th)) &&
874 (cfo_diff_avg_a > soml_tab->cfo_qam64_th) &&
875 (cfo_diff_avg_b > soml_tab->cfo_qam64_th)) {
876 PHYDM_DBG(dm, DBG_ADPTV_SOML,
877 "[ QAM64_ratio > %d ; cfo_diff_avg_a > %d KHz ==> SOML_OFF]\n",
878 soml_tab->qam64_dist_th,
879 soml_tab->cfo_qam64_th);
880 PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ Final decisoin ] : ");
881 phydm_soml_on_off(dm, SOML_OFF);
882 return;
883 } else if (((soml_tab->num_vht_qam[QAM16] * 100) >
884 (num_total_qam * soml_tab->qam16_dist_th)) &&
885 (cfo_diff_avg_a > soml_tab->cfo_qam16_th) &&
886 (cfo_diff_avg_b > soml_tab->cfo_qam16_th)) {
887 PHYDM_DBG(dm, DBG_ADPTV_SOML,
888 "[ QAM16_ratio > %d ; cfo_diff_avg_a > %d KHz ==> SOML_OFF]\n",
889 soml_tab->qam16_dist_th,
890 soml_tab->cfo_qam16_th);
891 PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ Final decisoin ] : ");
892 phydm_soml_on_off(dm, SOML_OFF);
893 return;
894 } else if (((soml_tab->num_vht_qam[BPSK_QPSK] * 100) >
895 (num_total_qam * soml_tab->bpsk_qpsk_dist_th)) &&
896 (cfo_diff_avg_a > soml_tab->cfo_qpsk_th) &&
897 (cfo_diff_avg_b > soml_tab->cfo_qpsk_th)) {
898 PHYDM_DBG(dm, DBG_ADPTV_SOML,
899 "[ BPSK_QPSK_ratio > %d ; cfo_diff_avg_a > %d KHz ==> SOML_OFF]\n",
900 soml_tab->bpsk_qpsk_dist_th,
901 soml_tab->cfo_qpsk_th);
902 PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ Final decisoin ] : ");
903 phydm_soml_on_off(dm, SOML_OFF);
904 return;
905 }
906
907 for (i = 0; i < rate_num; i++) {
908 ss_shift = 10 * i;
909 PHYDM_DBG(dm, DBG_ADPTV_SOML,
910 "[ vht_cnt_on VHT-%d ss MCS[0:9] = {%d, %d, %d, %d, %d, %d, %d, %d, %d, %d} ]\n",
911 (i + 1),
912 soml_tab->vht_cnt_on[ss_shift + 0],
913 soml_tab->vht_cnt_on[ss_shift + 1],
914 soml_tab->vht_cnt_on[ss_shift + 2],
915 soml_tab->vht_cnt_on[ss_shift + 3],
916 soml_tab->vht_cnt_on[ss_shift + 4],
917 soml_tab->vht_cnt_on[ss_shift + 5],
918 soml_tab->vht_cnt_on[ss_shift + 6],
919 soml_tab->vht_cnt_on[ss_shift + 7],
920 soml_tab->vht_cnt_on[ss_shift + 8],
921 soml_tab->vht_cnt_on[ss_shift + 9]);
922 }
923
924 for (i = 0; i < rate_num; i++) {
925 ss_shift = 10 * i;
926 PHYDM_DBG(dm, DBG_ADPTV_SOML,
927 "[ vht_cnt_off VHT-%d ss MCS[0:9] = {%d, %d, %d, %d, %d, %d, %d, %d, %d, %d} ]\n",
928 (i + 1),
929 soml_tab->vht_cnt_off[ss_shift + 0],
930 soml_tab->vht_cnt_off[ss_shift + 1],
931 soml_tab->vht_cnt_off[ss_shift + 2],
932 soml_tab->vht_cnt_off[ss_shift + 3],
933 soml_tab->vht_cnt_off[ss_shift + 4],
934 soml_tab->vht_cnt_off[ss_shift + 5],
935 soml_tab->vht_cnt_off[ss_shift + 6],
936 soml_tab->vht_cnt_off[ss_shift + 7],
937 soml_tab->vht_cnt_off[ss_shift + 8],
938 soml_tab->vht_cnt_off[ss_shift + 9]);
939 }
940
941 for (i = 0; i < rate_num; i++) {
942 ss_shift = 10 * i;
943 PHYDM_DBG(dm, DBG_ADPTV_SOML,
944 "*vht_crc_ok_cnt_on VHT-%d ss MCS[0:9] = {%d, %d, %d, %d, %d, %d, %d, %d, %d, %d}\n",
945 (i + 1),
946 soml_tab->vht_crc_ok_cnt_on[ss_shift + 0],
947 soml_tab->vht_crc_ok_cnt_on[ss_shift + 1],
948 soml_tab->vht_crc_ok_cnt_on[ss_shift + 2],
949 soml_tab->vht_crc_ok_cnt_on[ss_shift + 3],
950 soml_tab->vht_crc_ok_cnt_on[ss_shift + 4],
951 soml_tab->vht_crc_ok_cnt_on[ss_shift + 5],
952 soml_tab->vht_crc_ok_cnt_on[ss_shift + 6],
953 soml_tab->vht_crc_ok_cnt_on[ss_shift + 7],
954 soml_tab->vht_crc_ok_cnt_on[ss_shift + 8],
955 soml_tab->vht_crc_ok_cnt_on[ss_shift + 9]);
956 }
957 for (i = 0; i < rate_num; i++) {
958 ss_shift = 10 * i;
959 PHYDM_DBG(dm, DBG_ADPTV_SOML,
960 "*vht_crc_fail_cnt_on VHT-%d ss MCS[0:9] = {%d, %d, %d, %d, %d, %d, %d, %d, %d, %d}\n",
961 (i + 1),
962 soml_tab->vht_crc_fail_cnt_on[ss_shift + 0],
963 soml_tab->vht_crc_fail_cnt_on[ss_shift + 1],
964 soml_tab->vht_crc_fail_cnt_on[ss_shift + 2],
965 soml_tab->vht_crc_fail_cnt_on[ss_shift + 3],
966 soml_tab->vht_crc_fail_cnt_on[ss_shift + 4],
967 soml_tab->vht_crc_fail_cnt_on[ss_shift + 5],
968 soml_tab->vht_crc_fail_cnt_on[ss_shift + 6],
969 soml_tab->vht_crc_fail_cnt_on[ss_shift + 7],
970 soml_tab->vht_crc_fail_cnt_on[ss_shift + 8],
971 soml_tab->vht_crc_fail_cnt_on[ss_shift + 9]);
972 }
973 for (i = 0; i < rate_num; i++) {
974 ss_shift = 10 * i;
975 PHYDM_DBG(dm, DBG_ADPTV_SOML,
976 "*vht_crc_ok_cnt_off VHT-%d ss MCS[0:9] = {%d, %d, %d, %d, %d, %d, %d, %d, %d, %d}\n",
977 (i + 1),
978 soml_tab->vht_crc_ok_cnt_off[ss_shift + 0],
979 soml_tab->vht_crc_ok_cnt_off[ss_shift + 1],
980 soml_tab->vht_crc_ok_cnt_off[ss_shift + 2],
981 soml_tab->vht_crc_ok_cnt_off[ss_shift + 3],
982 soml_tab->vht_crc_ok_cnt_off[ss_shift + 4],
983 soml_tab->vht_crc_ok_cnt_off[ss_shift + 5],
984 soml_tab->vht_crc_ok_cnt_off[ss_shift + 6],
985 soml_tab->vht_crc_ok_cnt_off[ss_shift + 7],
986 soml_tab->vht_crc_ok_cnt_off[ss_shift + 8],
987 soml_tab->vht_crc_ok_cnt_off[ss_shift + 9]);
988 }
989 for (i = 0; i < rate_num; i++) {
990 ss_shift = 10 * i;
991 PHYDM_DBG(dm, DBG_ADPTV_SOML,
992 "*vht_crc_fail_cnt_off VHT-%d ss MCS[0:9] = {%d, %d, %d, %d, %d, %d, %d, %d, %d, %d}\n",
993 (i + 1),
994 soml_tab->vht_crc_fail_cnt_off[ss_shift + 0],
995 soml_tab->vht_crc_fail_cnt_off[ss_shift + 1],
996 soml_tab->vht_crc_fail_cnt_off[ss_shift + 2],
997 soml_tab->vht_crc_fail_cnt_off[ss_shift + 3],
998 soml_tab->vht_crc_fail_cnt_off[ss_shift + 4],
999 soml_tab->vht_crc_fail_cnt_off[ss_shift + 5],
1000 soml_tab->vht_crc_fail_cnt_off[ss_shift + 6],
1001 soml_tab->vht_crc_fail_cnt_off[ss_shift + 7],
1002 soml_tab->vht_crc_fail_cnt_off[ss_shift + 8],
1003 soml_tab->vht_crc_fail_cnt_off[ss_shift + 9]);
1004 }
1005
1006 for (i = ODM_RATEVHTSS2MCS0; i <= ODM_RATEVHTSS2MCS9; i++) {
1007 vht_total_cnt_on += soml_tab->vht_cnt_on[i - vht0];
1008 vht_total_cnt_off += soml_tab->vht_cnt_off[i - vht0];
1009 total_vht_rate_on += (soml_tab->vht_cnt_on[i - vht0] *
1010 vht_phy_rate_table[i - vht0]);
1011 total_vht_rate_off += (soml_tab->vht_cnt_off[i - vht0] *
1012 vht_phy_rate_table[i - vht0]);
1013
1014 if (soml_tab->vht_cnt_on[i - vht0] > cnt_max_on) {
1015 cnt_max_on = soml_tab->vht_cnt_on[i - vht0];
1016 max_idx_on = i - vht0;
1017 }
1018
1019 if (soml_tab->vht_cnt_off[i - vht0] > cnt_max_off) {
1020 cnt_max_off = soml_tab->vht_cnt_off[i - vht0];
1021 max_idx_off = i - vht0;
1022 }
1023 }
1024 total_vht_rate_on = total_vht_rate_on << 3;
1025 total_vht_rate_off = total_vht_rate_off << 3;
1026 rate_per_pkt_on = (vht_total_cnt_on != 0) ?
1027 (total_vht_rate_on / vht_total_cnt_on) : 0;
1028 rate_per_pkt_off = (vht_total_cnt_off != 0) ?
1029 (total_vht_rate_off / vht_total_cnt_off) : 0;
1030 #if (DM_ODM_SUPPORT_TYPE == ODM_AP)
1031 vht_ok_max_on = soml_tab->vht_crc_ok_cnt_on[max_idx_on];
1032 vht_fail_max_on = soml_tab->vht_crc_fail_cnt_on[max_idx_on];
1033 vht_ok_max_off = soml_tab->vht_crc_ok_cnt_off[max_idx_off];
1034 vht_fail_max_off = soml_tab->vht_crc_fail_cnt_off[max_idx_off];
1035
1036 if (vht_fail_max_on == 0)
1037 vht_fail_max_on = 1;
1038
1039 if (vht_fail_max_off == 0)
1040 vht_fail_max_off = 1;
1041
1042 if (vht_ok_max_on > vht_fail_max_on)
1043 on_above = true;
1044
1045 if (vht_ok_max_off > vht_fail_max_off)
1046 off_above = true;
1047
1048 if (on_above && !off_above) {
1049 crc_taget = SOML_ON;
1050 } else if (!on_above && off_above) {
1051 crc_taget = SOML_OFF;
1052 } else if (on_above && off_above) {
1053 utility_on = (vht_ok_max_on << 7) / vht_fail_max_on;
1054 utility_off = (vht_ok_max_off << 7) / vht_fail_max_off;
1055 crc_taget = (utility_on == utility_off) ?
1056 (soml_tab->soml_last_state) :
1057 ((utility_on > utility_off) ? SOML_ON :
1058 SOML_OFF);
1059
1060 } else if (!on_above && !off_above) {
1061 if (vht_ok_max_on == 0)
1062 vht_ok_max_on = 1;
1063 if (vht_ok_max_off == 0)
1064 vht_ok_max_off = 1;
1065 utility_on = (vht_fail_max_on << 7) / vht_ok_max_on;
1066 utility_off = (vht_fail_max_off << 7) / vht_ok_max_off;
1067 crc_taget = (utility_on == utility_off) ?
1068 (soml_tab->soml_last_state) :
1069 ((utility_on < utility_off) ? SOML_ON :
1070 SOML_OFF);
1071 }
1072 #endif
1073
1074 }
1075
1076 /* @[Decision] */
1077 PHYDM_DBG(dm, DBG_ADPTV_SOML,
1078 "[ rate_per_pkt_on = %d ; rate_per_pkt_off = %d ]\n",
1079 rate_per_pkt_on, rate_per_pkt_off);
1080 #if (DM_ODM_SUPPORT_TYPE == ODM_AP)
1081 if (max_idx_on == max_idx_off && max_idx_on != 0) {
1082 PHYDM_DBG(dm, DBG_ADPTV_SOML,
1083 "[ max_idx_on == max_idx_off ]\n");
1084 PHYDM_DBG(dm, DBG_ADPTV_SOML,
1085 "[ max_idx = %d, crc_utility_on = %d, crc_utility_off = %d, crc_target = %d]\n",
1086 max_idx_on, utility_on, utility_off,
1087 crc_taget);
1088 next_on_off = crc_taget;
1089 } else
1090 #endif
1091 if (rate_per_pkt_on > rate_per_pkt_off) {
1092 next_on_off = SOML_ON;
1093 PHYDM_DBG(dm, DBG_ADPTV_SOML,
1094 "[ rate_per_pkt_on > rate_per_pkt_off ==> SOML_ON ]\n");
1095 } else if (rate_per_pkt_on < rate_per_pkt_off) {
1096 next_on_off = SOML_OFF;
1097 PHYDM_DBG(dm, DBG_ADPTV_SOML,
1098 "[ rate_per_pkt_on < rate_per_pkt_off ==> SOML_OFF ]\n");
1099 } else {
1100 PHYDM_DBG(dm, DBG_ADPTV_SOML,
1101 "[ stay at soml_last_state ]\n");
1102 next_on_off = soml_tab->soml_last_state;
1103 }
1104
1105 PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ Final decisoin ] : ");
1106 phydm_soml_on_off(dm, next_on_off);
1107 soml_tab->soml_last_state = next_on_off;
1108 }
1109
phydm_adsl(void * dm_void)1110 void phydm_adsl(void *dm_void)
1111 {
1112 struct dm_struct *dm = (struct dm_struct *)dm_void;
1113 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
1114
1115 if (dm->support_ic_type & PHYDM_ADAPTIVE_SOML_IC) {
1116 PHYDM_DBG(dm, DBG_ADPTV_SOML, "soml_state_cnt =((%d))\n",
1117 soml_tab->soml_state_cnt);
1118 /*Traning state: 0(alt) 1(ori) 2(alt) 3(ori)===============*/
1119 if (soml_tab->soml_state_cnt <
1120 (soml_tab->soml_train_num << 1)) {
1121 if (soml_tab->soml_state_cnt == 0)
1122 phydm_adsl_init_state(dm);
1123 else if ((soml_tab->soml_state_cnt % 2) != 0)
1124 phydm_adsl_odd_state(dm);
1125 else if ((soml_tab->soml_state_cnt % 2) == 0)
1126 phydm_adsl_even_state(dm);
1127 } else {
1128 phydm_adsl_decision_state(dm);
1129 }
1130 }
1131 }
1132
phydm_adaptive_soml_reset(void * dm_void)1133 void phydm_adaptive_soml_reset(void *dm_void)
1134 {
1135 struct dm_struct *dm = (struct dm_struct *)dm_void;
1136 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
1137
1138 soml_tab->soml_state_cnt = 0;
1139 soml_tab->is_soml_method_enable = 0;
1140 soml_tab->soml_counter = 0;
1141 }
1142
phydm_set_adsl_val(void * dm_void,u32 * val_buf,u8 val_len)1143 void phydm_set_adsl_val(void *dm_void, u32 *val_buf, u8 val_len)
1144 {
1145 struct dm_struct *dm = (struct dm_struct *)dm_void;
1146
1147 if (!(dm->support_ability & ODM_BB_ADAPTIVE_SOML))
1148 return;
1149
1150 if (val_len != 1) {
1151 PHYDM_DBG(dm, ODM_COMP_API, "[Error][ADSL]Need val_len=1\n");
1152 return;
1153 }
1154
1155 phydm_soml_on_off(dm, (u8)val_buf[1]);
1156 }
1157
phydm_soml_crc_acq(void * dm_void,u8 rate_id,boolean crc32,u32 length)1158 void phydm_soml_crc_acq(void *dm_void, u8 rate_id, boolean crc32, u32 length)
1159 {
1160 struct dm_struct *dm = (struct dm_struct *)dm_void;
1161 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
1162 u8 offset = 0;
1163
1164 if (!(dm->support_ability & ODM_BB_ADAPTIVE_SOML))
1165 return;
1166
1167 if (!soml_tab->get_stats)
1168 return;
1169 if (length < 1400)
1170 return;
1171
1172 if (soml_tab->soml_on_off == SOML_ON) {
1173 if (rate_id >= ODM_RATEMCS0 && rate_id <= ODM_RATEMCS15) {
1174 offset = rate_id - ODM_RATEMCS0;
1175 if (crc32 == CRC_OK)
1176 soml_tab->ht_crc_ok_cnt_on[offset]++;
1177 else if (crc32 == CRC_FAIL)
1178 soml_tab->ht_crc_fail_cnt_on[offset]++;
1179 } else if (rate_id >= ODM_RATEVHTSS1MCS0 &&
1180 rate_id <= ODM_RATEVHTSS2MCS9) {
1181 offset = rate_id - ODM_RATEVHTSS1MCS0;
1182 if (crc32 == CRC_OK)
1183 soml_tab->vht_crc_ok_cnt_on[offset]++;
1184 else if (crc32 == CRC_FAIL)
1185 soml_tab->vht_crc_fail_cnt_on[offset]++;
1186 }
1187 } else if (soml_tab->soml_on_off == SOML_OFF) {
1188 if (rate_id >= ODM_RATEMCS0 && rate_id <= ODM_RATEMCS15) {
1189 offset = rate_id - ODM_RATEMCS0;
1190 if (crc32 == CRC_OK)
1191 soml_tab->ht_crc_ok_cnt_off[offset]++;
1192 else if (crc32 == CRC_FAIL)
1193 soml_tab->ht_crc_fail_cnt_off[offset]++;
1194 } else if (rate_id >= ODM_RATEVHTSS1MCS0 &&
1195 rate_id <= ODM_RATEVHTSS2MCS9) {
1196 offset = rate_id - ODM_RATEVHTSS1MCS0;
1197 if (crc32 == CRC_OK)
1198 soml_tab->vht_crc_ok_cnt_off[offset]++;
1199 else if (crc32 == CRC_FAIL)
1200 soml_tab->vht_crc_fail_cnt_off[offset]++;
1201 }
1202 }
1203 }
1204
phydm_soml_bytes_acq(void * dm_void,u8 rate_id,u32 length)1205 void phydm_soml_bytes_acq(void *dm_void, u8 rate_id, u32 length)
1206 {
1207 struct dm_struct *dm = (struct dm_struct *)dm_void;
1208 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
1209 u8 offset = 0;
1210
1211 if (!(dm->support_ability & ODM_BB_ADAPTIVE_SOML))
1212 return;
1213
1214 if (rate_id >= ODM_RATEMCS0 && rate_id <= ODM_RATEMCS31) {
1215 offset = rate_id - ODM_RATEMCS0;
1216 if (offset > (HT_RATE_IDX - 1))
1217 offset = HT_RATE_IDX - 1;
1218
1219 soml_tab->ht_byte[offset] += (u16)length;
1220 } else if (rate_id >= ODM_RATEVHTSS1MCS0 &&
1221 rate_id <= ODM_RATEVHTSS4MCS9) {
1222 offset = rate_id - ODM_RATEVHTSS1MCS0;
1223 if (offset > (VHT_RATE_IDX - 1))
1224 offset = VHT_RATE_IDX - 1;
1225
1226 soml_tab->vht_byte[offset] += (u16)length;
1227 }
1228 }
1229
1230 #if defined(CONFIG_RTL_TRIBAND_SUPPORT) && defined(CONFIG_USB_HCI)
pre_phydm_adaptive_soml_callback(unsigned long task_dm)1231 static void pre_phydm_adaptive_soml_callback(unsigned long task_dm)
1232 {
1233 struct dm_struct *dm = (struct dm_struct *)task_dm;
1234 struct rtl8192cd_priv *priv = dm->priv;
1235 struct priv_shared_info *pshare = priv->pshare;
1236
1237 if (!(priv->drv_state & DRV_STATE_OPEN))
1238 return;
1239 if (pshare->bDriverStopped || pshare->bSurpriseRemoved) {
1240 printk("[%s] bDriverStopped(%d) OR bSurpriseRemoved(%d)\n",
1241 __FUNCTION__, pshare->bDriverStopped,
1242 pshare->bSurpriseRemoved);
1243 return;
1244 }
1245
1246 rtw_enqueue_timer_event(priv, &pshare->adaptive_soml_event,
1247 ENQUEUE_TO_TAIL);
1248 }
1249
phydm_adaptive_soml_timers_usb(void * dm_void,u8 state)1250 void phydm_adaptive_soml_timers_usb(void *dm_void, u8 state)
1251 {
1252 struct dm_struct *dm = (struct dm_struct *)dm_void;
1253 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
1254 struct rtl8192cd_priv *priv = dm->priv;
1255
1256 if (state == INIT_SOML_TIMMER) {
1257 init_timer(&soml_tab->phydm_adaptive_soml_timer);
1258 soml_tab->phydm_adaptive_soml_timer.data = (unsigned long)dm;
1259 soml_tab->phydm_adaptive_soml_timer.function = pre_phydm_adaptive_soml_callback;
1260 INIT_TIMER_EVENT_ENTRY(&priv->pshare->adaptive_soml_event,
1261 phydm_adaptive_soml_callback,
1262 (unsigned long)dm);
1263 } else if (state == CANCEL_SOML_TIMMER) {
1264 odm_cancel_timer(dm, &soml_tab->phydm_adaptive_soml_timer);
1265 } else if (state == RELEASE_SOML_TIMMER) {
1266 odm_release_timer(dm, &soml_tab->phydm_adaptive_soml_timer);
1267 }
1268 }
1269 #endif /* defined(CONFIG_RTL_TRIBAND_SUPPORT) && defined(CONFIG_USB_HCI) */
1270
phydm_adaptive_soml_timers(void * dm_void,u8 state)1271 void phydm_adaptive_soml_timers(void *dm_void, u8 state)
1272 {
1273 struct dm_struct *dm = (struct dm_struct *)dm_void;
1274 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
1275
1276 if (!(dm->support_ic_type & PHYDM_ADAPTIVE_SOML_IC))
1277 return;
1278
1279 #if defined(CONFIG_RTL_TRIBAND_SUPPORT) && defined(CONFIG_USB_HCI)
1280 struct rtl8192cd_priv *priv = dm->priv;
1281
1282 if (priv->hci_type == RTL_HCI_USB) {
1283 phydm_adaptive_soml_timers_usb(dm_void, state);
1284 } else
1285 #endif /* defined(CONFIG_RTL_TRIBAND_SUPPORT) && defined(CONFIG_USB_HCI) */
1286 {
1287 if (state == INIT_SOML_TIMMER) {
1288 odm_initialize_timer(dm, &soml_tab->phydm_adaptive_soml_timer,
1289 (void *)phydm_adaptive_soml_callback, NULL,
1290 "phydm_adaptive_soml_timer");
1291 } else if (state == CANCEL_SOML_TIMMER) {
1292 odm_cancel_timer(dm, &soml_tab->phydm_adaptive_soml_timer);
1293 } else if (state == RELEASE_SOML_TIMMER) {
1294 odm_release_timer(dm, &soml_tab->phydm_adaptive_soml_timer);
1295 }
1296 }
1297 }
1298
phydm_adaptive_soml_init(void * dm_void)1299 void phydm_adaptive_soml_init(void *dm_void)
1300 {
1301 struct dm_struct *dm = (struct dm_struct *)dm_void;
1302 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
1303 #if 0
1304 if (!(dm->support_ability & ODM_BB_ADAPTIVE_SOML)) {
1305 PHYDM_DBG(dm, DBG_ADPTV_SOML,
1306 "[Return] Not Support Adaptive SOML\n");
1307 return;
1308 }
1309 #endif
1310
1311 if (!(dm->support_ic_type & PHYDM_ADAPTIVE_SOML_IC))
1312 return;
1313
1314 PHYDM_DBG(dm, DBG_ADPTV_SOML, "%s\n", __func__);
1315
1316 soml_tab->soml_state_cnt = 0;
1317 soml_tab->soml_delay_time = 40;
1318 soml_tab->soml_intvl = 150;
1319 soml_tab->soml_train_num = 4;
1320 soml_tab->is_soml_method_enable = 0;
1321 soml_tab->soml_counter = 0;
1322 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
1323 soml_tab->soml_period = 1;
1324 #else
1325 soml_tab->soml_period = 4;
1326 #endif
1327 soml_tab->soml_select = 0;
1328 soml_tab->cfo_cnt = 0;
1329 soml_tab->cfo_diff_sum_a = 0;
1330 soml_tab->cfo_diff_sum_b = 0;
1331
1332 soml_tab->cfo_qpsk_th = 94;
1333 soml_tab->cfo_qam16_th = 38;
1334 soml_tab->cfo_qam64_th = 17;
1335 soml_tab->cfo_qam256_th = 7;
1336
1337 soml_tab->bpsk_qpsk_dist_th = 20;
1338 soml_tab->qam16_dist_th = 20;
1339 soml_tab->qam64_dist_th = 20;
1340 soml_tab->qam256_dist_th = 20;
1341
1342 if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8192F))
1343 odm_set_bb_reg(dm, 0x988, BIT(25), 1);
1344 }
1345
phydm_adaptive_soml(void * dm_void)1346 void phydm_adaptive_soml(void *dm_void)
1347 {
1348 struct dm_struct *dm = (struct dm_struct *)dm_void;
1349 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
1350
1351 if (!(dm->support_ability & ODM_BB_ADAPTIVE_SOML)) {
1352 PHYDM_DBG(dm, DBG_ADPTV_SOML,
1353 "[Return!!!] Not Support Adaptive SOML Function\n");
1354 return;
1355 }
1356
1357 if (dm->pause_ability & ODM_BB_ADAPTIVE_SOML) {
1358 PHYDM_DBG(dm, DBG_ADPTV_SOML, "Return: Pause ADSL in LV=%d\n",
1359 dm->pause_lv_table.lv_adsl);
1360 return;
1361 }
1362
1363 if (soml_tab->soml_counter < soml_tab->soml_period) {
1364 soml_tab->soml_counter++;
1365 return;
1366 }
1367 soml_tab->soml_counter = 0;
1368 soml_tab->soml_state_cnt = 0;
1369 soml_tab->cfo_cnt = 0;
1370 soml_tab->cfo_diff_sum_a = 0;
1371 soml_tab->cfo_diff_sum_b = 0;
1372
1373 phydm_soml_reset_qam(dm);
1374
1375 if (soml_tab->soml_select == 0) {
1376 PHYDM_DBG(dm, DBG_ADPTV_SOML,
1377 "[ Adaptive SOML Training !!!]\n");
1378 } else if (soml_tab->soml_select == 1) {
1379 PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ Stop Adaptive SOML !!!]\n");
1380 phydm_soml_on_off(dm, SOML_ON);
1381 return;
1382 } else if (soml_tab->soml_select == 2) {
1383 PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ Stop Adaptive SOML !!!]\n");
1384 phydm_soml_on_off(dm, SOML_OFF);
1385 return;
1386 }
1387
1388 if (dm->support_ic_type & PHYDM_ADAPTIVE_SOML_IC)
1389 phydm_adsl(dm);
1390 }
1391
phydm_enable_adaptive_soml(void * dm_void)1392 void phydm_enable_adaptive_soml(void *dm_void)
1393 {
1394 struct dm_struct *dm = (struct dm_struct *)dm_void;
1395
1396 PHYDM_DBG(dm, DBG_ADPTV_SOML, "[%s]\n", __func__);
1397 dm->support_ability |= ODM_BB_ADAPTIVE_SOML;
1398 phydm_soml_on_off(dm, SOML_ON);
1399 }
1400
phydm_stop_adaptive_soml(void * dm_void)1401 void phydm_stop_adaptive_soml(void *dm_void)
1402 {
1403 struct dm_struct *dm = (struct dm_struct *)dm_void;
1404
1405 PHYDM_DBG(dm, DBG_ADPTV_SOML, "[%s]\n", __func__);
1406 dm->support_ability &= ~ODM_BB_ADAPTIVE_SOML;
1407 phydm_soml_on_off(dm, SOML_ON);
1408 }
1409
phydm_adaptive_soml_para_set(void * dm_void,u8 train_num,u8 intvl,u8 period,u8 delay_time)1410 void phydm_adaptive_soml_para_set(void *dm_void, u8 train_num, u8 intvl,
1411 u8 period, u8 delay_time)
1412 {
1413 struct dm_struct *dm = (struct dm_struct *)dm_void;
1414 struct adaptive_soml *soml_tab = &dm->dm_soml_table;
1415
1416 soml_tab->soml_train_num = train_num;
1417 soml_tab->soml_intvl = intvl;
1418 soml_tab->soml_period = period;
1419 soml_tab->soml_delay_time = delay_time;
1420 }
1421 #endif /* @end of CONFIG_ADAPTIVE_SOML*/
1422
phydm_init_soft_ml_setting(void * dm_void)1423 void phydm_init_soft_ml_setting(void *dm_void)
1424 {
1425 struct dm_struct *dm = (struct dm_struct *)dm_void;
1426 u32 soml_mask = BIT(31) | BIT(30) | BIT(29) | BIT(28);
1427
1428 #if (RTL8822B_SUPPORT == 1)
1429 if (!*dm->mp_mode) {
1430 if (dm->support_ic_type & ODM_RTL8822B) {
1431 #if 0
1432 /*odm_set_bb_reg(dm, R_0x19a8, MASKDWORD, 0xd10a0000);*/
1433 #endif
1434 phydm_somlrxhp_setting(dm, true);
1435 dm->bsomlenabled = true;
1436 }
1437 }
1438 #endif
1439 #if (RTL8821C_SUPPORT == 1)
1440 if (!*dm->mp_mode) {
1441 if (dm->support_ic_type & ODM_RTL8821C)
1442 odm_set_bb_reg(dm, R_0x19a8, soml_mask, 0xd);
1443 }
1444 #endif
1445 #if (RTL8195B_SUPPORT == 1)
1446 if (!*dm->mp_mode) {
1447 if (dm->support_ic_type & ODM_RTL8195B)
1448 odm_set_bb_reg(dm, R_0x19a8, soml_mask, 0xd);
1449 }
1450 #endif
1451 }
1452