1 /******************************************************************************
2 *
3 * Copyright(c) 2007 - 2017 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26 /*@************************************************************
27 * include files
28 ************************************************************/
29
30 #include "mp_precomp.h"
31 #include "phydm_precomp.h"
32
33 #ifdef PHYDM_SUPPORT_CCKPD
34 #ifdef PHYDM_COMPILE_CCKPD_TYPE1
phydm_write_cck_pd_type1(void * dm_void,u8 cca_th)35 void phydm_write_cck_pd_type1(void *dm_void, u8 cca_th)
36 {
37 struct dm_struct *dm = (struct dm_struct *)dm_void;
38 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
39
40 PHYDM_DBG(dm, DBG_CCKPD, "[%s] cck_cca_th=((0x%x))\n",
41 __func__, cca_th);
42
43 odm_write_1byte(dm, R_0xa0a, cca_th);
44 cckpd_t->cur_cck_cca_thres = cca_th;
45 }
46
phydm_set_cckpd_lv_type1(void * dm_void,enum cckpd_lv lv)47 void phydm_set_cckpd_lv_type1(void *dm_void, enum cckpd_lv lv)
48 {
49 struct dm_struct *dm = (struct dm_struct *)dm_void;
50 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
51 u8 pd_th = 0;
52
53 PHYDM_DBG(dm, DBG_CCKPD, "%s ======>\n", __func__);
54 PHYDM_DBG(dm, DBG_CCKPD, "lv: (%d) -> (%d)\n", cckpd_t->cck_pd_lv, lv);
55
56 if (cckpd_t->cck_pd_lv == lv) {
57 PHYDM_DBG(dm, DBG_CCKPD, "stay in lv=%d\n", lv);
58 return;
59 }
60
61 cckpd_t->cck_pd_lv = lv;
62 cckpd_t->cck_fa_ma = CCK_FA_MA_RESET;
63
64 if (lv == CCK_PD_LV_4)
65 pd_th = 0xed;
66 else if (lv == CCK_PD_LV_3)
67 pd_th = 0xdd;
68 else if (lv == CCK_PD_LV_2)
69 pd_th = 0xcd;
70 else if (lv == CCK_PD_LV_1)
71 pd_th = 0x83;
72 else if (lv == CCK_PD_LV_0)
73 pd_th = 0x40;
74
75 phydm_write_cck_pd_type1(dm, pd_th);
76 }
77
phydm_cckpd_type1(void * dm_void)78 void phydm_cckpd_type1(void *dm_void)
79 {
80 struct dm_struct *dm = (struct dm_struct *)dm_void;
81 struct phydm_dig_struct *dig_t = &dm->dm_dig_table;
82 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
83 enum cckpd_lv lv = CCK_PD_LV_INIT;
84 boolean is_update = true;
85
86 if (dm->is_linked) {
87 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
88 if (dm->support_ic_type & ODM_RTL8822B) {
89 if (dm->rssi_min > 35) {
90 lv = CCK_PD_LV_2;
91 } else if (dm->rssi_min > 20) {
92 if (cckpd_t->cck_fa_ma > 500)
93 lv = CCK_PD_LV_2;
94 else if (cckpd_t->cck_fa_ma < 250)
95 lv = CCK_PD_LV_1;
96 else
97 is_update = false;
98 } else { /*RSSI < 20*/
99 lv = CCK_PD_LV_1;
100 }
101 } else {
102 if (dm->rssi_min > 60) {
103 lv = CCK_PD_LV_3;
104 } else if (dm->rssi_min > 35) {
105 lv = CCK_PD_LV_2;
106 } else if (dm->rssi_min > 20) {
107 if (cckpd_t->cck_fa_ma > 500)
108 lv = CCK_PD_LV_2;
109 else if (cckpd_t->cck_fa_ma < 250)
110 lv = CCK_PD_LV_1;
111 else
112 is_update = false;
113 } else { /*RSSI < 20*/
114 lv = CCK_PD_LV_1;
115 }
116 }
117 #else /*ODM_AP*/
118 if (dig_t->cur_ig_value > 0x32)
119 lv = CCK_PD_LV_4;
120 else if (dig_t->cur_ig_value > 0x2a)
121 lv = CCK_PD_LV_3;
122 else if (dig_t->cur_ig_value > 0x24)
123 lv = CCK_PD_LV_2;
124 else
125 lv = CCK_PD_LV_1;
126 #endif
127 } else {
128 if (cckpd_t->cck_fa_ma > 1000)
129 lv = CCK_PD_LV_1;
130 else if (cckpd_t->cck_fa_ma < 500)
131 lv = CCK_PD_LV_0;
132 else
133 is_update = false;
134 }
135
136 /*[Abnormal case] =================================================*/
137 #if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
138 /*@HP 22B LPS power consumption issue & [PCIE-1596]*/
139 if (dm->hp_hw_id && dm->traffic_load == TRAFFIC_ULTRA_LOW) {
140 lv = CCK_PD_LV_0;
141 PHYDM_DBG(dm, DBG_CCKPD, "CCKPD Abnormal case1\n");
142 } else if ((dm->p_advance_ota & PHYDM_ASUS_OTA_SETTING) &&
143 cckpd_t->cck_fa_ma > 200 && dm->rssi_min <= 20) {
144 lv = CCK_PD_LV_1;
145 cckpd_t->cck_pd_lv = lv;
146 phydm_write_cck_pd_type1(dm, 0xc3); /*@for ASUS OTA test*/
147 is_update = false;
148 PHYDM_DBG(dm, DBG_CCKPD, "CCKPD Abnormal case2\n");
149 }
150 #elif (DM_ODM_SUPPORT_TYPE & (ODM_AP))
151 #ifdef MCR_WIRELESS_EXTEND
152 lv = CCK_PD_LV_2;
153 cckpd_t->cck_pd_lv = lv;
154 phydm_write_cck_pd_type1(dm, 0x43);
155 is_update = false;
156 PHYDM_DBG(dm, DBG_CCKPD, "CCKPD Abnormal case3\n");
157 #endif
158 #endif
159 /*=================================================================*/
160
161 if (is_update)
162 phydm_set_cckpd_lv_type1(dm, lv);
163
164 PHYDM_DBG(dm, DBG_CCKPD, "is_linked=%d, lv=%d, pd_th=0x%x\n\n",
165 dm->is_linked, cckpd_t->cck_pd_lv,
166 cckpd_t->cur_cck_cca_thres);
167 }
168 #endif /*#ifdef PHYDM_COMPILE_CCKPD_TYPE1*/
169
170 #ifdef PHYDM_COMPILE_CCKPD_TYPE2
phydm_write_cck_pd_type2(void * dm_void,u8 cca_th,u8 cca_th_aaa)171 void phydm_write_cck_pd_type2(void *dm_void, u8 cca_th, u8 cca_th_aaa)
172 {
173 struct dm_struct *dm = (struct dm_struct *)dm_void;
174 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
175
176 PHYDM_DBG(dm, DBG_CCKPD, "[%s] pd_th=0x%x, cs_ratio=0x%x\n",
177 __func__, cca_th, cca_th_aaa);
178
179 odm_set_bb_reg(dm, R_0xa08, 0x3f0000, cca_th);
180 odm_set_bb_reg(dm, R_0xaa8, 0x1f0000, cca_th_aaa);
181 cckpd_t->cur_cck_cca_thres = cca_th;
182 cckpd_t->cck_cca_th_aaa = cca_th_aaa;
183 }
184
phydm_set_cckpd_lv_type2(void * dm_void,enum cckpd_lv lv)185 void phydm_set_cckpd_lv_type2(void *dm_void, enum cckpd_lv lv)
186 {
187 struct dm_struct *dm = (struct dm_struct *)dm_void;
188 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
189 u8 pd_th = 0, cs_ratio = 0, cs_2r_offset = 0;
190 u8 cck_n_rx = 1;
191
192 PHYDM_DBG(dm, DBG_CCKPD, "%s ======>\n", __func__);
193 PHYDM_DBG(dm, DBG_CCKPD, "lv: (%d) -> (%d)\n", cckpd_t->cck_pd_lv, lv);
194
195 /*@r_mrx & r_cca_mrc*/
196 cck_n_rx = (odm_get_bb_reg(dm, R_0xa2c, BIT(18)) &&
197 odm_get_bb_reg(dm, R_0xa2c, BIT(22))) ? 2 : 1;
198
199 if (cckpd_t->cck_pd_lv == lv && cckpd_t->cck_n_rx == cck_n_rx) {
200 PHYDM_DBG(dm, DBG_CCKPD, "stay in lv=%d\n", lv);
201 return;
202 }
203
204 cckpd_t->cck_n_rx = cck_n_rx;
205 cckpd_t->cck_pd_lv = lv;
206 cckpd_t->cck_fa_ma = CCK_FA_MA_RESET;
207
208 if (lv == CCK_PD_LV_4) {
209 cs_ratio = cckpd_t->aaa_default + 8;
210 cs_2r_offset = 5;
211 pd_th = 0xd;
212 } else if (lv == CCK_PD_LV_3) {
213 cs_ratio = cckpd_t->aaa_default + 6;
214 cs_2r_offset = 4;
215 pd_th = 0xd;
216 } else if (lv == CCK_PD_LV_2) {
217 cs_ratio = cckpd_t->aaa_default + 4;
218 cs_2r_offset = 3;
219 pd_th = 0xd;
220 } else if (lv == CCK_PD_LV_1) {
221 cs_ratio = cckpd_t->aaa_default + 2;
222 cs_2r_offset = 1;
223 pd_th = 0x7;
224 } else if (lv == CCK_PD_LV_0) {
225 cs_ratio = cckpd_t->aaa_default;
226 cs_2r_offset = 0;
227 pd_th = 0x3;
228 }
229
230 if (cckpd_t->cck_n_rx == 2) {
231 if (cs_ratio >= cs_2r_offset)
232 cs_ratio = cs_ratio - cs_2r_offset;
233 else
234 cs_ratio = 0;
235 }
236 phydm_write_cck_pd_type2(dm, pd_th, cs_ratio);
237 }
238
239 #if 0
240 void phydm_set_cckpd_lv_type2_bcn(void *dm_void, enum cckpd_lv lv)
241 {
242 struct dm_struct *dm = (struct dm_struct *)dm_void;
243 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
244 u8 pd_th = 0, cs_ratio = 0, cs_2r_offset = 0;
245 u8 cck_n_rx = 1;
246 u8 cs_ratio_pre = 0;
247 u8 bcn_cnt = dm->phy_dbg_info.beacon_cnt_in_period; //BCN CNT
248 u8 ofst = 0;
249 u8 ofst_direc = 0; //0:+, 1:-
250
251 PHYDM_DBG(dm, DBG_CCKPD, "%s ======>\n", __func__);
252 PHYDM_DBG(dm, DBG_CCKPD, "lv: (%d) -> (%d)\n", cckpd_t->cck_pd_lv, lv);
253
254 /*@r_mrx & r_cca_mrc*/
255 cck_n_rx = (odm_get_bb_reg(dm, R_0xa2c, BIT(18)) &&
256 odm_get_bb_reg(dm, R_0xa2c, BIT(22))) ? 2 : 1;
257 cs_ratio_pre = (u8)((odm_get_bb_reg(dm, R_0xaa8, 0x1f0000)));
258 PHYDM_DBG(dm, DBG_CCKPD, "BCN: %d, pre CS ratio: 0x%x\n", bcn_cnt,
259 cs_ratio_pre);
260
261 if (cckpd_t->cck_pd_lv == lv && cckpd_t->cck_n_rx == cck_n_rx &&
262 (bcn_cnt >= 10 && bcn_cnt < 14)) {
263 PHYDM_DBG(dm, DBG_CCKPD, "BCN ok, stay lv=%d, cs ratio=0x%x\n",
264 lv, cs_ratio_pre);
265 return;
266 }
267
268 cckpd_t->cck_n_rx = cck_n_rx;
269 cckpd_t->cck_pd_lv = lv;
270 cckpd_t->cck_fa_ma = CCK_FA_MA_RESET;
271
272 if (lv == CCK_PD_LV_4) {
273 cs_ratio = cckpd_t->aaa_default + 8;
274 cs_2r_offset = 5;
275 pd_th = 0xd;
276 } else if (lv == CCK_PD_LV_3) {
277 cs_ratio = cckpd_t->aaa_default + 6;
278 cs_2r_offset = 4;
279 pd_th = 0xd;
280 } else if (lv == CCK_PD_LV_2) {
281 cs_ratio = cckpd_t->aaa_default + 4;
282 cs_2r_offset = 3;
283 pd_th = 0xd;
284 } else if (lv == CCK_PD_LV_1) {
285 cs_ratio = cckpd_t->aaa_default + 2;
286 cs_2r_offset = 1;
287 pd_th = 0x7;
288 } else if (lv == CCK_PD_LV_0) {
289 cs_ratio = cckpd_t->aaa_default;
290 cs_2r_offset = 0;
291 pd_th = 0x3;
292 }
293
294 if (cckpd_t->cck_n_rx == 2) {
295 if (cs_ratio >= cs_2r_offset)
296 cs_ratio = cs_ratio - cs_2r_offset;
297 else
298 cs_ratio = 0;
299 }
300
301 if (bcn_cnt >= 18) {
302 ofst_direc = 0;
303 ofst = 0x2;
304 } else if (bcn_cnt >= 14) {
305 ofst_direc = 0;
306 ofst = 0x1;
307 } else if (bcn_cnt >= 10) {
308 ofst_direc = 0;
309 ofst = 0x0;
310 } else if (bcn_cnt >= 5) {
311 ofst_direc = 1;
312 ofst = 0x3;
313 } else {
314 ofst_direc = 1;
315 ofst = 0x4;
316 }
317 PHYDM_DBG(dm, DBG_CCKPD, "bcn:(%d), ofst:(%s%d)\n", bcn_cnt,
318 ((ofst_direc) ? "-" : "+"), ofst);
319
320 if (ofst_direc == 0)
321 cs_ratio = cs_ratio + ofst;
322 else
323 cs_ratio = cs_ratio - ofst;
324
325 if (cs_ratio == cs_ratio_pre) {
326 PHYDM_DBG(dm, DBG_CCKPD, "Same cs ratio, lv=%d cs_ratio=0x%x\n",
327 lv, cs_ratio);
328 return;
329 }
330 phydm_write_cck_pd_type2(dm, pd_th, cs_ratio);
331 }
332 #endif
333
phydm_cckpd_type2(void * dm_void)334 void phydm_cckpd_type2(void *dm_void)
335 {
336 struct dm_struct *dm = (struct dm_struct *)dm_void;
337 struct phydm_dig_struct *dig_t = &dm->dm_dig_table;
338 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
339 enum cckpd_lv lv = CCK_PD_LV_INIT;
340 u8 igi = dig_t->cur_ig_value;
341 u8 rssi_min = dm->rssi_min;
342 boolean is_update = true;
343
344 PHYDM_DBG(dm, DBG_CCKPD, "%s ======>\n", __func__);
345
346 if (dm->is_linked) {
347 if (igi > 0x38 && rssi_min > 32) {
348 lv = CCK_PD_LV_4;
349 } else if (igi > 0x2a && rssi_min > 32) {
350 lv = CCK_PD_LV_3;
351 } else if (igi > 0x24 || (rssi_min > 24 && rssi_min <= 30)) {
352 lv = CCK_PD_LV_2;
353 } else if (igi <= 0x24 || rssi_min < 22) {
354 if (cckpd_t->cck_fa_ma > 1000) {
355 lv = CCK_PD_LV_1;
356 } else if (cckpd_t->cck_fa_ma < 500) {
357 lv = CCK_PD_LV_0;
358 } else {
359 is_update = false;
360 }
361 } else {
362 is_update = false;
363 }
364 } else {
365 if (cckpd_t->cck_fa_ma > 1000) {
366 lv = CCK_PD_LV_1;
367 } else if (cckpd_t->cck_fa_ma < 500) {
368 lv = CCK_PD_LV_0;
369 } else {
370 is_update = false;
371 }
372 }
373
374 /*[Abnormal case] =================================================*/
375 #if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
376 /*@21C Miracast lag issue & [PCIE-3298]*/
377 if (dm->support_ic_type & ODM_RTL8821C && rssi_min > 60) {
378 lv = CCK_PD_LV_4;
379 cckpd_t->cck_pd_lv = lv;
380 phydm_write_cck_pd_type2(dm, 0x1d, (cckpd_t->aaa_default + 8));
381 is_update = false;
382 PHYDM_DBG(dm, DBG_CCKPD, "CCKPD Abnormal case1\n");
383 }
384 #endif
385 /*=================================================================*/
386
387 if (is_update) {
388 phydm_set_cckpd_lv_type2(dm, lv);
389 }
390
391 PHYDM_DBG(dm, DBG_CCKPD,
392 "is_linked=%d, lv=%d, n_rx=%d, cs_ratio=0x%x, pd_th=0x%x\n\n",
393 dm->is_linked, cckpd_t->cck_pd_lv, cckpd_t->cck_n_rx,
394 cckpd_t->cck_cca_th_aaa, cckpd_t->cur_cck_cca_thres);
395 }
396 #endif /*#ifdef PHYDM_COMPILE_CCKPD_TYPE2*/
397
398 #ifdef PHYDM_COMPILE_CCKPD_TYPE3
phydm_write_cck_pd_type3(void * dm_void,u8 pd_th,u8 cs_ratio,enum cckpd_mode mode)399 void phydm_write_cck_pd_type3(void *dm_void, u8 pd_th, u8 cs_ratio,
400 enum cckpd_mode mode)
401 {
402 struct dm_struct *dm = (struct dm_struct *)dm_void;
403 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
404
405 PHYDM_DBG(dm, DBG_CCKPD,
406 "[%s] mode=%d, pd_th=0x%x, cs_ratio=0x%x\n", __func__,
407 mode, pd_th, cs_ratio);
408
409 switch (mode) {
410 case CCK_BW20_1R: /*RFBW20_1R*/
411 {
412 cckpd_t->cur_cck_pd_20m_1r = pd_th;
413 cckpd_t->cur_cck_cs_ratio_20m_1r = cs_ratio;
414 odm_set_bb_reg(dm, R_0xac8, 0xff, pd_th);
415 odm_set_bb_reg(dm, R_0xad0, 0x1f, cs_ratio);
416 } break;
417 case CCK_BW20_2R: /*RFBW20_2R*/
418 {
419 cckpd_t->cur_cck_pd_20m_2r = pd_th;
420 cckpd_t->cur_cck_cs_ratio_20m_2r = cs_ratio;
421 odm_set_bb_reg(dm, R_0xac8, 0xff00, pd_th);
422 odm_set_bb_reg(dm, R_0xad0, 0x3e0, cs_ratio);
423 } break;
424 case CCK_BW40_1R: /*RFBW40_1R*/
425 {
426 cckpd_t->cur_cck_pd_40m_1r = pd_th;
427 cckpd_t->cur_cck_cs_ratio_40m_1r = cs_ratio;
428 odm_set_bb_reg(dm, R_0xacc, 0xff, pd_th);
429 odm_set_bb_reg(dm, R_0xad0, 0x1f00000, cs_ratio);
430 } break;
431 case CCK_BW40_2R: /*RFBW40_2R*/
432 {
433 cckpd_t->cur_cck_pd_40m_2r = pd_th;
434 cckpd_t->cur_cck_cs_ratio_40m_2r = cs_ratio;
435 odm_set_bb_reg(dm, R_0xacc, 0xff00, pd_th);
436 odm_set_bb_reg(dm, R_0xad0, 0x3e000000, cs_ratio);
437 } break;
438
439 default:
440 /*@pr_debug("[%s] warning!\n", __func__);*/
441 break;
442 }
443 }
444
phydm_set_cckpd_lv_type3(void * dm_void,enum cckpd_lv lv)445 void phydm_set_cckpd_lv_type3(void *dm_void, enum cckpd_lv lv)
446 {
447 struct dm_struct *dm = (struct dm_struct *)dm_void;
448 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
449 enum cckpd_mode cck_mode = CCK_BW20_2R;
450 enum channel_width cck_bw = CHANNEL_WIDTH_20;
451 u8 cck_n_rx = 1;
452 u8 pd_th;
453 u8 cs_ratio;
454
455 PHYDM_DBG(dm, DBG_CCKPD, "%s ======>\n", __func__);
456 PHYDM_DBG(dm, DBG_CCKPD, "lv: (%d) -> (%d)\n", cckpd_t->cck_pd_lv, lv);
457
458 /*[Check Nrx]*/
459 cck_n_rx = (odm_get_bb_reg(dm, R_0xa2c, BIT(17))) ? 2 : 1;
460
461 /*[Check BW]*/
462 if (odm_get_bb_reg(dm, R_0x800, BIT(0)))
463 cck_bw = CHANNEL_WIDTH_40;
464 else
465 cck_bw = CHANNEL_WIDTH_20;
466
467 /*[Check LV]*/
468 if (cckpd_t->cck_pd_lv == lv &&
469 cckpd_t->cck_n_rx == cck_n_rx &&
470 cckpd_t->cck_bw == cck_bw) {
471 PHYDM_DBG(dm, DBG_CCKPD, "stay in lv=%d\n", lv);
472 return;
473 }
474
475 cckpd_t->cck_bw = cck_bw;
476 cckpd_t->cck_n_rx = cck_n_rx;
477 cckpd_t->cck_pd_lv = lv;
478 cckpd_t->cck_fa_ma = CCK_FA_MA_RESET;
479
480 if (cck_n_rx == 2) {
481 if (cck_bw == CHANNEL_WIDTH_20) {
482 pd_th = cckpd_t->cck_pd_20m_2r;
483 cs_ratio = cckpd_t->cck_cs_ratio_20m_2r;
484 cck_mode = CCK_BW20_2R;
485 } else {
486 pd_th = cckpd_t->cck_pd_40m_2r;
487 cs_ratio = cckpd_t->cck_cs_ratio_40m_2r;
488 cck_mode = CCK_BW40_2R;
489 }
490 } else {
491 if (cck_bw == CHANNEL_WIDTH_20) {
492 pd_th = cckpd_t->cck_pd_20m_1r;
493 cs_ratio = cckpd_t->cck_cs_ratio_20m_1r;
494 cck_mode = CCK_BW20_1R;
495 } else {
496 pd_th = cckpd_t->cck_pd_40m_1r;
497 cs_ratio = cckpd_t->cck_cs_ratio_40m_1r;
498 cck_mode = CCK_BW40_1R;
499 }
500 }
501
502 if (lv == CCK_PD_LV_4) {
503 if (cck_n_rx == 2) {
504 pd_th += 4;
505 cs_ratio += 2;
506 } else {
507 pd_th += 4;
508 cs_ratio += 3;
509 }
510 } else if (lv == CCK_PD_LV_3) {
511 if (cck_n_rx == 2) {
512 pd_th += 3;
513 cs_ratio += 1;
514 } else {
515 pd_th += 3;
516 cs_ratio += 2;
517 }
518 } else if (lv == CCK_PD_LV_2) {
519 pd_th += 2;
520 cs_ratio += 1;
521 } else if (lv == CCK_PD_LV_1) {
522 pd_th += 1;
523 cs_ratio += 1;
524 }
525
526 phydm_write_cck_pd_type3(dm, pd_th, cs_ratio, cck_mode);
527 }
528
phydm_cckpd_type3(void * dm_void)529 void phydm_cckpd_type3(void *dm_void)
530 {
531 struct dm_struct *dm = (struct dm_struct *)dm_void;
532 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
533 enum cckpd_lv lv = CCK_PD_LV_INIT;
534 u8 igi = dm->dm_dig_table.cur_ig_value;
535 boolean is_update = true;
536 u8 pd_th = 0;
537 u8 cs_ratio = 0;
538
539 PHYDM_DBG(dm, DBG_CCKPD, "%s ======>\n", __func__);
540
541 if (dm->is_linked) {
542 if (igi > 0x38 && dm->rssi_min > 32) {
543 lv = CCK_PD_LV_4;
544 } else if ((igi > 0x2a) && (dm->rssi_min > 32)) {
545 lv = CCK_PD_LV_3;
546 } else if ((igi > 0x24) ||
547 (dm->rssi_min > 24 && dm->rssi_min <= 30)) {
548 lv = CCK_PD_LV_2;
549 } else if ((igi <= 0x24) || (dm->rssi_min < 22)) {
550 if (cckpd_t->cck_fa_ma > 1000)
551 lv = CCK_PD_LV_1;
552 else if (cckpd_t->cck_fa_ma < 500)
553 lv = CCK_PD_LV_0;
554 else
555 is_update = false;
556 }
557 } else {
558 if (cckpd_t->cck_fa_ma > 1000)
559 lv = CCK_PD_LV_1;
560 else if (cckpd_t->cck_fa_ma < 500)
561 lv = CCK_PD_LV_0;
562 else
563 is_update = false;
564 }
565
566 if (is_update)
567 phydm_set_cckpd_lv_type3(dm, lv);
568
569 if (cckpd_t->cck_n_rx == 2) {
570 if (cckpd_t->cck_bw == CHANNEL_WIDTH_20) {
571 pd_th = cckpd_t->cur_cck_pd_20m_2r;
572 cs_ratio = cckpd_t->cur_cck_cs_ratio_20m_2r;
573 } else {
574 pd_th = cckpd_t->cur_cck_pd_40m_2r;
575 cs_ratio = cckpd_t->cur_cck_cs_ratio_40m_2r;
576 }
577 } else {
578 if (cckpd_t->cck_bw == CHANNEL_WIDTH_20) {
579 pd_th = cckpd_t->cur_cck_pd_20m_1r;
580 cs_ratio = cckpd_t->cur_cck_cs_ratio_20m_1r;
581 } else {
582 pd_th = cckpd_t->cur_cck_pd_40m_1r;
583 cs_ratio = cckpd_t->cur_cck_cs_ratio_40m_1r;
584 }
585 }
586 PHYDM_DBG(dm, DBG_CCKPD,
587 "[%dR][%dM] is_linked=%d, lv=%d, cs_ratio=0x%x, pd_th=0x%x\n\n",
588 cckpd_t->cck_n_rx, 20 << cckpd_t->cck_bw, dm->is_linked,
589 cckpd_t->cck_pd_lv, cs_ratio, pd_th);
590 }
591
phydm_cck_pd_init_type3(void * dm_void)592 void phydm_cck_pd_init_type3(void *dm_void)
593 {
594 struct dm_struct *dm = (struct dm_struct *)dm_void;
595 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
596 u32 reg_tmp = 0;
597
598 /*Get Default value*/
599 cckpd_t->cck_pd_20m_1r = (u8)odm_get_bb_reg(dm, R_0xac8, 0xff);
600 cckpd_t->cck_pd_20m_2r = (u8)odm_get_bb_reg(dm, R_0xac8, 0xff00);
601 cckpd_t->cck_pd_40m_1r = (u8)odm_get_bb_reg(dm, R_0xacc, 0xff);
602 cckpd_t->cck_pd_40m_2r = (u8)odm_get_bb_reg(dm, R_0xacc, 0xff00);
603
604 reg_tmp = odm_get_bb_reg(dm, R_0xad0, MASKDWORD);
605 cckpd_t->cck_cs_ratio_20m_1r = (u8)(reg_tmp & 0x1f);
606 cckpd_t->cck_cs_ratio_20m_2r = (u8)((reg_tmp & 0x3e0) >> 5);
607 cckpd_t->cck_cs_ratio_40m_1r = (u8)((reg_tmp & 0x1f00000) >> 20);
608 cckpd_t->cck_cs_ratio_40m_2r = (u8)((reg_tmp & 0x3e000000) >> 25);
609 }
610 #endif /*#ifdef PHYDM_COMPILE_CCKPD_TYPE3*/
611
612 #ifdef PHYDM_COMPILE_CCKPD_TYPE4
phydm_write_cck_pd_type4(void * dm_void,enum cckpd_lv lv,enum cckpd_mode mode)613 void phydm_write_cck_pd_type4(void *dm_void, enum cckpd_lv lv,
614 enum cckpd_mode mode)
615 {
616 struct dm_struct *dm = (struct dm_struct *)dm_void;
617 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
618 u32 val = 0;
619
620 PHYDM_DBG(dm, DBG_CCKPD, "write CCK CCA parameters(CS_ratio & PD)\n");
621 switch (mode) {
622 case CCK_BW20_1R: /*RFBW20_1R*/
623 {
624 val = cckpd_t->cckpd_jgr3[0][0][0][lv];
625 odm_set_bb_reg(dm, R_0x1ac8, 0xff, val);
626 val = cckpd_t->cckpd_jgr3[0][0][1][lv];
627 odm_set_bb_reg(dm, R_0x1ad0, 0x1f, val);
628 } break;
629 case CCK_BW40_1R: /*RFBW40_1R*/
630 {
631 val = cckpd_t->cckpd_jgr3[1][0][0][lv];
632 odm_set_bb_reg(dm, R_0x1acc, 0xff, val);
633 val = cckpd_t->cckpd_jgr3[1][0][1][lv];
634 odm_set_bb_reg(dm, R_0x1ad0, 0x01F00000, val);
635 } break;
636 #if (defined(PHYDM_COMPILE_ABOVE_2SS))
637 case CCK_BW20_2R: /*RFBW20_2R*/
638 {
639 val = cckpd_t->cckpd_jgr3[0][1][0][lv];
640 odm_set_bb_reg(dm, R_0x1ac8, 0xff00, val);
641 val = cckpd_t->cckpd_jgr3[0][1][1][lv];
642 odm_set_bb_reg(dm, R_0x1ad0, 0x3e0, val);
643 } break;
644 case CCK_BW40_2R: /*RFBW40_2R*/
645 {
646 val = cckpd_t->cckpd_jgr3[1][1][0][lv];
647 odm_set_bb_reg(dm, R_0x1acc, 0xff00, val);
648 val = cckpd_t->cckpd_jgr3[1][1][1][lv];
649 odm_set_bb_reg(dm, R_0x1ad0, 0x3E000000, val);
650 } break;
651 #endif
652 #if (defined(PHYDM_COMPILE_ABOVE_3SS))
653 case CCK_BW20_3R: /*RFBW20_3R*/
654 {
655 val = cckpd_t->cckpd_jgr3[0][2][0][lv];
656 odm_set_bb_reg(dm, R_0x1ac8, 0xff0000, val);
657 val = cckpd_t->cckpd_jgr3[0][2][1][lv];
658 odm_set_bb_reg(dm, R_0x1ad0, 0x7c00, val);
659 } break;
660 case CCK_BW40_3R: /*RFBW40_3R*/
661 {
662 val = cckpd_t->cckpd_jgr3[1][2][0][lv];
663 odm_set_bb_reg(dm, R_0x1acc, 0xff0000, val);
664 val = cckpd_t->cckpd_jgr3[1][2][1][lv] & 0x3;
665 odm_set_bb_reg(dm, R_0x1ad0, 0xC0000000, val);
666 val = (cckpd_t->cckpd_jgr3[1][2][1][lv] & 0x1c) >> 2;
667 odm_set_bb_reg(dm, R_0x1ad4, 0x7, val);
668 } break;
669 #endif
670 #if (defined(PHYDM_COMPILE_ABOVE_4SS))
671 case CCK_BW20_4R: /*RFBW20_4R*/
672 {
673 val = cckpd_t->cckpd_jgr3[0][3][0][lv];
674 odm_set_bb_reg(dm, R_0x1ac8, 0xff000000, val);
675 val = cckpd_t->cckpd_jgr3[0][3][1][lv];
676 odm_set_bb_reg(dm, R_0x1ad0, 0xF8000, val);
677 } break;
678 case CCK_BW40_4R: /*RFBW40_4R*/
679 {
680 val = cckpd_t->cckpd_jgr3[1][3][0][lv];
681 odm_set_bb_reg(dm, R_0x1acc, 0xff000000, val);
682 val = cckpd_t->cckpd_jgr3[1][3][1][lv];
683 odm_set_bb_reg(dm, R_0x1ad4, 0xf8, val);
684 } break;
685 #endif
686 default:
687 /*@pr_debug("[%s] warning!\n", __func__);*/
688 break;
689 }
690 }
691
phydm_set_cck_pd_lv_type4(void * dm_void,enum cckpd_lv lv)692 void phydm_set_cck_pd_lv_type4(void *dm_void, enum cckpd_lv lv)
693 {
694 struct dm_struct *dm = (struct dm_struct *)dm_void;
695 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
696 enum cckpd_mode cck_mode = CCK_BW20_2R;
697 enum channel_width cck_bw = CHANNEL_WIDTH_20;
698 u8 cck_n_rx = 0;
699 u32 val = 0;
700 /*u32 val_dbg = 0;*/
701
702 PHYDM_DBG(dm, DBG_CCKPD, "%s ======>\n", __func__);
703 PHYDM_DBG(dm, DBG_CCKPD, "lv: (%d) -> (%d)\n", cckpd_t->cck_pd_lv, lv);
704
705 /*[Check Nrx]*/
706 cck_n_rx = (u8)odm_get_bb_reg(dm, R_0x1a2c, 0x60000) + 1;
707
708 /*[Check BW]*/
709 val = odm_get_bb_reg(dm, R_0x9b0, 0xc);
710 if (val == 0)
711 cck_bw = CHANNEL_WIDTH_20;
712 else if (val == 1)
713 cck_bw = CHANNEL_WIDTH_40;
714 else
715 cck_bw = CHANNEL_WIDTH_80;
716
717 /*[Check LV]*/
718 if (cckpd_t->cck_pd_lv == lv &&
719 cckpd_t->cck_n_rx == cck_n_rx &&
720 cckpd_t->cck_bw == cck_bw) {
721 PHYDM_DBG(dm, DBG_CCKPD, "stay in lv=%d\n", lv);
722 return;
723 }
724
725 cckpd_t->cck_bw = cck_bw;
726 cckpd_t->cck_n_rx = cck_n_rx;
727 cckpd_t->cck_pd_lv = lv;
728 cckpd_t->cck_fa_ma = CCK_FA_MA_RESET;
729
730 switch (cck_n_rx) {
731 case 1: /*1R*/
732 {
733 if (cck_bw == CHANNEL_WIDTH_20)
734 cck_mode = CCK_BW20_1R;
735 else if (cck_bw == CHANNEL_WIDTH_40)
736 cck_mode = CCK_BW40_1R;
737 } break;
738 #if (defined(PHYDM_COMPILE_ABOVE_2SS))
739 case 2: /*2R*/
740 {
741 if (cck_bw == CHANNEL_WIDTH_20)
742 cck_mode = CCK_BW20_2R;
743 else if (cck_bw == CHANNEL_WIDTH_40)
744 cck_mode = CCK_BW40_2R;
745 } break;
746 #endif
747 #if (defined(PHYDM_COMPILE_ABOVE_3SS))
748 case 3: /*3R*/
749 {
750 if (cck_bw == CHANNEL_WIDTH_20)
751 cck_mode = CCK_BW20_3R;
752 else if (cck_bw == CHANNEL_WIDTH_40)
753 cck_mode = CCK_BW40_3R;
754 } break;
755 #endif
756 #if (defined(PHYDM_COMPILE_ABOVE_4SS))
757 case 4: /*4R*/
758 {
759 if (cck_bw == CHANNEL_WIDTH_20)
760 cck_mode = CCK_BW20_4R;
761 else if (cck_bw == CHANNEL_WIDTH_40)
762 cck_mode = CCK_BW40_4R;
763 } break;
764 #endif
765 default:
766 /*@pr_debug("[%s] warning!\n", __func__);*/
767 break;
768 }
769 phydm_write_cck_pd_type4(dm, lv, cck_mode);
770 }
771
phydm_read_cckpd_para_type4(void * dm_void)772 void phydm_read_cckpd_para_type4(void *dm_void)
773 {
774 struct dm_struct *dm = (struct dm_struct *)dm_void;
775 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
776 u8 bw = 0; /*r_RX_RF_BW*/
777 u8 n_rx = 0;
778 u8 curr_cck_pd_t[2][4][2];
779 u32 reg0 = 0;
780 u32 reg1 = 0;
781 u32 reg2 = 0;
782 u32 reg3 = 0;
783
784 if (!(dm->debug_components & DBG_CCKPD))
785 return;
786
787 bw = (u8)odm_get_bb_reg(dm, R_0x9b0, 0xc);
788 n_rx = (u8)odm_get_bb_reg(dm, R_0x1a2c, 0x60000) + 1;
789
790 reg0 = odm_get_bb_reg(dm, R_0x1ac8, MASKDWORD);
791 reg1 = odm_get_bb_reg(dm, R_0x1acc, MASKDWORD);
792 reg2 = odm_get_bb_reg(dm, R_0x1ad0, MASKDWORD);
793 reg3 = odm_get_bb_reg(dm, R_0x1ad4, MASKDWORD);
794 curr_cck_pd_t[0][0][0] = (u8)(reg0 & 0x000000ff);
795 curr_cck_pd_t[1][0][0] = (u8)(reg1 & 0x000000ff);
796 curr_cck_pd_t[0][0][1] = (u8)(reg2 & 0x0000001f);
797 curr_cck_pd_t[1][0][1] = (u8)((reg2 & 0x01f00000) >> 20);
798 #if (defined(PHYDM_COMPILE_ABOVE_2SS))
799 if (dm->support_ic_type & PHYDM_IC_ABOVE_2SS) {
800 curr_cck_pd_t[0][1][0] = (u8)((reg0 & 0x0000ff00) >> 8);
801 curr_cck_pd_t[1][1][0] = (u8)((reg1 & 0x0000ff00) >> 8);
802 curr_cck_pd_t[0][1][1] = (u8)((reg2 & 0x000003E0) >> 5);
803 curr_cck_pd_t[1][1][1] = (u8)((reg2 & 0x3E000000) >> 25);
804 }
805 #endif
806 #if (defined(PHYDM_COMPILE_ABOVE_3SS))
807 if (dm->support_ic_type & PHYDM_IC_ABOVE_3SS) {
808 curr_cck_pd_t[0][2][0] = (u8)((reg0 & 0x00ff0000) >> 16);
809 curr_cck_pd_t[1][2][0] = (u8)((reg1 & 0x00ff0000) >> 16);
810 curr_cck_pd_t[0][2][1] = (u8)((reg2 & 0x00007C00) >> 10);
811 curr_cck_pd_t[1][2][1] = (u8)((reg2 & 0xC0000000) >> 30) |
812 (u8)((reg3 & 0x00000007) << 2);
813 }
814 #endif
815 #if (defined(PHYDM_COMPILE_ABOVE_4SS))
816 if (dm->support_ic_type & PHYDM_IC_ABOVE_4SS) {
817 curr_cck_pd_t[0][3][0] = (u8)((reg0 & 0xff000000) >> 24);
818 curr_cck_pd_t[1][3][0] = (u8)((reg1 & 0xff000000) >> 24);
819 curr_cck_pd_t[0][3][1] = (u8)((reg2 & 0x000F8000) >> 15);
820 curr_cck_pd_t[1][3][1] = (u8)((reg3 & 0x000000F8) >> 3);
821 }
822 #endif
823
824 PHYDM_DBG(dm, DBG_CCKPD, "bw=%dM, Nrx=%d\n", 20 << bw, n_rx);
825 PHYDM_DBG(dm, DBG_CCKPD, "lv=%d, readback CS_th=0x%x, PD th=0x%x\n",
826 cckpd_t->cck_pd_lv,
827 curr_cck_pd_t[bw][n_rx - 1][1],
828 curr_cck_pd_t[bw][n_rx - 1][0]);
829 }
830
phydm_cckpd_type4(void * dm_void)831 void phydm_cckpd_type4(void *dm_void)
832 {
833 struct dm_struct *dm = (struct dm_struct *)dm_void;
834 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
835 u8 igi = dm->dm_dig_table.cur_ig_value;
836 enum cckpd_lv lv = 0;
837 boolean is_update = true;
838
839 PHYDM_DBG(dm, DBG_CCKPD, "%s ======>\n", __func__);
840
841 if (dm->is_linked) {
842 PHYDM_DBG(dm, DBG_CCKPD, "Linked!!!\n");
843 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
844 if (dm->rssi_min > 40) {
845 lv = CCK_PD_LV_4;
846 PHYDM_DBG(dm, DBG_CCKPD, "Order 1\n");
847 } else if (dm->rssi_min > 32) {
848 lv = CCK_PD_LV_3;
849 PHYDM_DBG(dm, DBG_CCKPD, "Order 2\n");
850 } else if (dm->rssi_min > 24) {
851 lv = CCK_PD_LV_2;
852 PHYDM_DBG(dm, DBG_CCKPD, "Order 3\n");
853 } else {
854 if (cckpd_t->cck_fa_ma > 1000) {
855 lv = CCK_PD_LV_1;
856 PHYDM_DBG(dm, DBG_CCKPD, "Order 4-1\n");
857 } else if (cckpd_t->cck_fa_ma < 500) {
858 lv = CCK_PD_LV_0;
859 PHYDM_DBG(dm, DBG_CCKPD, "Order 4-2\n");
860 } else {
861 is_update = false;
862 PHYDM_DBG(dm, DBG_CCKPD, "Order 4-3\n");
863 }
864 }
865 #else /*ODM_AP*/
866 if (igi > 0x38 && dm->rssi_min > 32) {
867 lv = CCK_PD_LV_4;
868 PHYDM_DBG(dm, DBG_CCKPD, "Order 1\n");
869 } else if (igi > 0x2a && dm->rssi_min > 32) {
870 lv = CCK_PD_LV_3;
871 PHYDM_DBG(dm, DBG_CCKPD, "Order 2\n");
872 } else if (igi > 0x24 || dm->rssi_min > 24) {
873 lv = CCK_PD_LV_2;
874 PHYDM_DBG(dm, DBG_CCKPD, "Order 3\n");
875 } else {
876 if (cckpd_t->cck_fa_ma > 1000) {
877 lv = CCK_PD_LV_1;
878 PHYDM_DBG(dm, DBG_CCKPD, "Order 4-1\n");
879 } else if (cckpd_t->cck_fa_ma < 500) {
880 lv = CCK_PD_LV_0;
881 PHYDM_DBG(dm, DBG_CCKPD, "Order 4-2\n");
882 } else {
883 is_update = false;
884 PHYDM_DBG(dm, DBG_CCKPD, "Order 4-3\n");
885 }
886 }
887 #endif
888 } else {
889 PHYDM_DBG(dm, DBG_CCKPD, "UnLinked!!!\n");
890 if (cckpd_t->cck_fa_ma > 1000) {
891 lv = CCK_PD_LV_1;
892 PHYDM_DBG(dm, DBG_CCKPD, "Order 1\n");
893 } else if (cckpd_t->cck_fa_ma < 500) {
894 lv = CCK_PD_LV_0;
895 PHYDM_DBG(dm, DBG_CCKPD, "Order 2\n");
896 } else {
897 is_update = false;
898 PHYDM_DBG(dm, DBG_CCKPD, "Order 3\n");
899 }
900 }
901
902 if (is_update) {
903 phydm_set_cck_pd_lv_type4(dm, lv);
904
905 PHYDM_DBG(dm, DBG_CCKPD, "setting CS_th = 0x%x, PD th = 0x%x\n",
906 cckpd_t->cckpd_jgr3[cckpd_t->cck_bw]
907 [cckpd_t->cck_n_rx - 1][1][lv],
908 cckpd_t->cckpd_jgr3[cckpd_t->cck_bw]
909 [cckpd_t->cck_n_rx - 1][0][lv]);
910 }
911 phydm_read_cckpd_para_type4(dm);
912 }
913
phydm_cck_pd_init_type4(void * dm_void)914 void phydm_cck_pd_init_type4(void *dm_void)
915 {
916 struct dm_struct *dm = (struct dm_struct *)dm_void;
917 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
918 u32 reg0 = 0;
919 u32 reg1 = 0;
920 u32 reg2 = 0;
921 u32 reg3 = 0;
922 u8 pw_step = 0;
923 u8 cs_step = 0;
924 u8 cck_bw = 0; /*r_RX_RF_BW*/
925 u8 cck_n_rx = 0;
926 u8 val = 0;
927 u8 i = 0;
928
929 PHYDM_DBG(dm, DBG_CCKPD, "[%s]======>\n", __func__);
930
931 #if 0
932 /*@
933 *cckpd_t[0][0][0][0] = 1ac8[7:0] r_PD_lim_RFBW20_1R
934 *cckpd_t[0][1][0][0] = 1ac8[15:8] r_PD_lim_RFBW20_2R
935 *cckpd_t[0][2][0][0] = 1ac8[23:16] r_PD_lim_RFBW20_3R
936 *cckpd_t[0][3][0][0] = 1ac8[31:24] r_PD_lim_RFBW20_4R
937 *cckpd_t[1][0][0][0] = 1acc[7:0] r_PD_lim_RFBW40_1R
938 *cckpd_t[1][1][0][0] = 1acc[15:8] r_PD_lim_RFBW40_2R
939 *cckpd_t[1][2][0][0] = 1acc[23:16] r_PD_lim_RFBW40_3R
940 *cckpd_t[1][3][0][0] = 1acc[31:24] r_PD_lim_RFBW40_4R
941 *
942 *
943 *cckpd_t[0][0][1][0] = 1ad0[4:0] r_CS_ratio_RFBW20_1R[4:0]
944 *cckpd_t[0][1][1][0] = 1ad0[9:5] r_CS_ratio_RFBW20_2R[4:0]
945 *cckpd_t[0][2][1][0] = 1ad0[14:10] r_CS_ratio_RFBW20_3R[4:0]
946 *cckpd_t[0][3][1][0] = 1ad0[19:15] r_CS_ratio_RFBW20_4R[4:0]
947 *cckpd_t[1][0][1][0] = 1ad0[24:20] r_CS_ratio_RFBW40_1R[4:0]
948 *cckpd_t[1][1][1][0] = 1ad0[29:25] r_CS_ratio_RFBW40_2R[4:0]
949 *cckpd_t[1][2][1][0] = 1ad0[31:30] r_CS_ratio_RFBW40_3R[1:0]
950 * 1ad4[2:0] r_CS_ratio_RFBW40_3R[4:2]
951 *cckpd_t[1][3][1][0] = 1ad4[7:3] r_CS_ratio_RFBW40_4R[4:0]
952 */
953 #endif
954 /*[Check Nrx]*/
955 cck_n_rx = (u8)odm_get_bb_reg(dm, R_0x1a2c, 0x60000) + 1;
956
957 /*[Check BW]*/
958 val = (u8)odm_get_bb_reg(dm, R_0x9b0, 0xc);
959 if (val == 0)
960 cck_bw = CHANNEL_WIDTH_20;
961 else if (val == 1)
962 cck_bw = CHANNEL_WIDTH_40;
963 else
964 cck_bw = CHANNEL_WIDTH_80;
965
966 cckpd_t->cck_bw = cck_bw;
967 cckpd_t->cck_n_rx = cck_n_rx;
968 reg0 = odm_get_bb_reg(dm, R_0x1ac8, MASKDWORD);
969 reg1 = odm_get_bb_reg(dm, R_0x1acc, MASKDWORD);
970 reg2 = odm_get_bb_reg(dm, R_0x1ad0, MASKDWORD);
971 reg3 = odm_get_bb_reg(dm, R_0x1ad4, MASKDWORD);
972
973 for (i = 0 ; i < CCK_PD_LV_MAX ; i++) {
974 pw_step = i * 2;
975 cs_step = i * 2;
976
977 #if (RTL8197G_SUPPORT)
978 if (dm->support_ic_type & ODM_RTL8197G) {
979 pw_step = i;
980 cs_step = i;
981 if (i > CCK_PD_LV_3) {
982 pw_step = 3;
983 cs_step = 3;
984 }
985 }
986 #endif
987
988 #if (RTL8822C_SUPPORT)
989 if (dm->support_ic_type & ODM_RTL8822C) {
990 if (i == CCK_PD_LV_1) {
991 pw_step = 9; /*IGI-19.2:0x11=d'17*/
992 cs_step = 0;
993 } else if (i == CCK_PD_LV_2) {
994 pw_step = 12; /*IGI-15.5:0x14=d'20*/
995 cs_step = 1;
996 } else if (i == CCK_PD_LV_3) {
997 pw_step = 14; /*IGI-14:0x16=d'22*/
998 cs_step = 1;
999 } else if (i == CCK_PD_LV_4) {
1000 pw_step = 17; /*IGI-12:0x19=d'25*/
1001 cs_step = 1;
1002 }
1003 }
1004 #endif
1005
1006 val = (u8)(reg0 & 0x000000ff) + pw_step;
1007 PHYDM_DBG(dm, DBG_CCKPD, "lvl %d val = %x\n\n", i, val);
1008 cckpd_t->cckpd_jgr3[0][0][0][i] = val;
1009
1010 val = (u8)(reg1 & 0x000000ff) + pw_step;
1011 cckpd_t->cckpd_jgr3[1][0][0][i] = val;
1012
1013 val = (u8)(reg2 & 0x0000001f) + cs_step;
1014 cckpd_t->cckpd_jgr3[0][0][1][i] = val;
1015
1016 val = (u8)((reg2 & 0x01f00000) >> 20) + cs_step;
1017 cckpd_t->cckpd_jgr3[1][0][1][i] = val;
1018
1019 #ifdef PHYDM_COMPILE_ABOVE_2SS
1020 if (dm->support_ic_type & PHYDM_IC_ABOVE_2SS) {
1021 val = (u8)((reg0 & 0x0000ff00) >> 8) + pw_step;
1022 cckpd_t->cckpd_jgr3[0][1][0][i] = val;
1023
1024 val = (u8)((reg1 & 0x0000ff00) >> 8) + pw_step;
1025 cckpd_t->cckpd_jgr3[1][1][0][i] = val;
1026
1027 val = (u8)((reg2 & 0x000003e0) >> 5) + cs_step;
1028 cckpd_t->cckpd_jgr3[0][1][1][i] = val;
1029
1030 val = (u8)((reg2 & 0x3e000000) >> 25) + cs_step;
1031 cckpd_t->cckpd_jgr3[1][1][1][i] = val;
1032 }
1033 #endif
1034
1035 #ifdef PHYDM_COMPILE_ABOVE_3SS
1036 if (dm->support_ic_type & PHYDM_IC_ABOVE_3SS) {
1037 val = (u8)((reg0 & 0x00ff0000) >> 16) + pw_step;
1038 cckpd_t->cckpd_jgr3[0][2][0][i] = val;
1039
1040 val = (u8)((reg1 & 0x00ff0000) >> 16) + pw_step;
1041 cckpd_t->cckpd_jgr3[1][2][0][i] = val;
1042 val = (u8)((reg2 & 0x00007c00) >> 10) + cs_step;
1043 cckpd_t->cckpd_jgr3[0][2][1][i] = val;
1044 val = (u8)(((reg2 & 0xc0000000) >> 30) |
1045 ((reg3 & 0x7) << 3)) + cs_step;
1046 cckpd_t->cckpd_jgr3[1][2][1][i] = val;
1047 }
1048 #endif
1049
1050 #ifdef PHYDM_COMPILE_ABOVE_4SS
1051 if (dm->support_ic_type & PHYDM_IC_ABOVE_4SS) {
1052 val = (u8)((reg0 & 0xff000000) >> 24) + pw_step;
1053 cckpd_t->cckpd_jgr3[0][3][0][i] = val;
1054
1055 val = (u8)((reg1 & 0xff000000) >> 24) + pw_step;
1056 cckpd_t->cckpd_jgr3[1][3][0][i] = val;
1057
1058 val = (u8)((reg2 & 0x000f8000) >> 15) + cs_step;
1059 cckpd_t->cckpd_jgr3[0][3][1][i] = val;
1060
1061 val = (u8)((reg3 & 0x000000f8) >> 3) + cs_step;
1062 cckpd_t->cckpd_jgr3[1][3][1][i] = val;
1063 }
1064 #endif
1065 }
1066 }
1067
phydm_invalid_cckpd_type4(void * dm_void)1068 void phydm_invalid_cckpd_type4(void *dm_void)
1069 {
1070 struct dm_struct *dm = (struct dm_struct *)dm_void;
1071 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
1072 u8 val = 0;
1073 u8 i = 0;
1074 u8 j = 0;
1075 u8 k = 0;
1076
1077 PHYDM_DBG(dm, DBG_CCKPD, "[%s]======>\n", __func__);
1078
1079 for (i = 0; i < CCK_PD_LV_MAX; i++) {
1080 for (j = 0; j < 2; j++) {
1081 for (k = 0; k < dm->num_rf_path; k++) {
1082 val = cckpd_t->cckpd_jgr3[j][k][1][i];
1083 if (val == INVALID_CS_RATIO_0)
1084 cckpd_t->cckpd_jgr3[j][k][1][i] = 0x1c;
1085 else if (val == INVALID_CS_RATIO_1)
1086 cckpd_t->cckpd_jgr3[j][k][1][i] = 0x1e;
1087 else if (val > MAXVALID_CS_RATIO)
1088 cckpd_t->cckpd_jgr3[j][k][1][i] =
1089 MAXVALID_CS_RATIO;
1090 }
1091 }
1092
1093 #if (RTL8198F_SUPPORT)
1094 if (dm->support_ic_type & ODM_RTL8198F) {
1095 val = cckpd_t->cckpd_jgr3[0][3][1][i];
1096 if (i == CCK_PD_LV_1 && val > 0x10)
1097 cckpd_t->cckpd_jgr3[0][3][1][i] = 0x10;
1098 else if (i == CCK_PD_LV_2 && val > 0x10)
1099 cckpd_t->cckpd_jgr3[0][3][1][i] = 0x10;
1100 else if (i == CCK_PD_LV_3 && val > 0x10)
1101 cckpd_t->cckpd_jgr3[0][3][1][i] = 0x10;
1102 else if (i == CCK_PD_LV_4 && val > 0x10)
1103 cckpd_t->cckpd_jgr3[0][3][1][i] = 0x10;
1104 val = cckpd_t->cckpd_jgr3[1][3][1][i];
1105 if (i == CCK_PD_LV_1 && val > 0xF)
1106 cckpd_t->cckpd_jgr3[1][3][1][i] = 0xF;
1107 else if (i == CCK_PD_LV_2 && val > 0xF)
1108 cckpd_t->cckpd_jgr3[1][3][1][i] = 0xF;
1109 else if (i == CCK_PD_LV_3 && val > 0xF)
1110 cckpd_t->cckpd_jgr3[1][3][1][i] = 0xF;
1111 else if (i == CCK_PD_LV_4 && val > 0xF)
1112 cckpd_t->cckpd_jgr3[1][3][1][i] = 0xF;
1113 }
1114 #endif
1115 }
1116 }
1117
1118 #endif /*#ifdef PHYDM_COMPILE_CCKPD_TYPE4*/
1119
phydm_set_cckpd_val(void * dm_void,u32 * val_buf,u8 val_len)1120 void phydm_set_cckpd_val(void *dm_void, u32 *val_buf, u8 val_len)
1121 {
1122 struct dm_struct *dm = (struct dm_struct *)dm_void;
1123 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
1124 enum cckpd_lv lv;
1125
1126 if (val_len != 1) {
1127 PHYDM_DBG(dm, ODM_COMP_API, "[Error][CCKPD]Need val_len=1\n");
1128 return;
1129 }
1130
1131 lv = (enum cckpd_lv)val_buf[0];
1132
1133 if (lv > CCK_PD_LV_4) {
1134 pr_debug("[%s] warning! lv=%d\n", __func__, lv);
1135 return;
1136 }
1137
1138 switch (cckpd_t->cckpd_hw_type) {
1139 #ifdef PHYDM_COMPILE_CCKPD_TYPE1
1140 case 1:
1141 phydm_set_cckpd_lv_type1(dm, lv);
1142 break;
1143 #endif
1144 #ifdef PHYDM_COMPILE_CCKPD_TYPE2
1145 case 2:
1146 phydm_set_cckpd_lv_type2(dm, lv);
1147 break;
1148 #endif
1149 #ifdef PHYDM_COMPILE_CCKPD_TYPE3
1150 case 3:
1151 phydm_set_cckpd_lv_type3(dm, lv);
1152 break;
1153 #endif
1154 #ifdef PHYDM_COMPILE_CCKPD_TYPE4
1155 case 4:
1156 phydm_set_cck_pd_lv_type4(dm, lv);
1157 break;
1158 #endif
1159 default:
1160 pr_debug("[%s]warning\n", __func__);
1161 break;
1162 }
1163 }
1164
1165 boolean
phydm_stop_cck_pd_th(void * dm_void)1166 phydm_stop_cck_pd_th(void *dm_void)
1167 {
1168 struct dm_struct *dm = (struct dm_struct *)dm_void;
1169
1170 if (!(dm->support_ability & ODM_BB_FA_CNT)) {
1171 PHYDM_DBG(dm, DBG_CCKPD, "Not Support:ODM_BB_FA_CNT disable\n");
1172 return true;
1173 }
1174
1175 if (!(dm->support_ability & ODM_BB_CCK_PD)) {
1176 PHYDM_DBG(dm, DBG_CCKPD, "Not Support:ODM_BB_CCK_PD disable\n");
1177 return true;
1178 }
1179
1180 if (dm->pause_ability & ODM_BB_CCK_PD) {
1181 PHYDM_DBG(dm, DBG_CCKPD, "Return: Pause CCKPD in LV=%d\n",
1182 dm->pause_lv_table.lv_cckpd);
1183 return true;
1184 }
1185
1186 if (dm->is_linked && (*dm->channel > 36)) {
1187 PHYDM_DBG(dm, DBG_CCKPD, "Return: 5G CH=%d\n", *dm->channel);
1188 return true;
1189 }
1190 return false;
1191 }
1192
phydm_cck_pd_th(void * dm_void)1193 void phydm_cck_pd_th(void *dm_void)
1194 {
1195 struct dm_struct *dm = (struct dm_struct *)dm_void;
1196 struct phydm_fa_struct *fa_t = &dm->false_alm_cnt;
1197 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
1198 u32 cck_fa = fa_t->cnt_cck_fail;
1199 #ifdef PHYDM_TDMA_DIG_SUPPORT
1200 struct phydm_fa_acc_struct *fa_acc_t = &dm->false_alm_cnt_acc;
1201 #endif
1202
1203 PHYDM_DBG(dm, DBG_CCKPD, "[%s] ======>\n", __func__);
1204
1205 if (phydm_stop_cck_pd_th(dm))
1206 return;
1207
1208 #ifdef PHYDM_TDMA_DIG_SUPPORT
1209 if (dm->original_dig_restore)
1210 cck_fa = fa_t->cnt_cck_fail;
1211 else
1212 cck_fa = fa_acc_t->cnt_cck_fail_1sec;
1213 #endif
1214
1215 if (cckpd_t->cck_fa_ma == CCK_FA_MA_RESET)
1216 cckpd_t->cck_fa_ma = cck_fa;
1217 else
1218 cckpd_t->cck_fa_ma = (cckpd_t->cck_fa_ma * 3 + cck_fa) >> 2;
1219
1220 PHYDM_DBG(dm, DBG_CCKPD,
1221 "IGI=0x%x, rssi_min=%d, cck_fa=%d, cck_fa_ma=%d\n",
1222 dm->dm_dig_table.cur_ig_value, dm->rssi_min,
1223 cck_fa, cckpd_t->cck_fa_ma);
1224
1225 switch (cckpd_t->cckpd_hw_type) {
1226 #ifdef PHYDM_COMPILE_CCKPD_TYPE1
1227 case 1:
1228 phydm_cckpd_type1(dm);
1229 break;
1230 #endif
1231 #ifdef PHYDM_COMPILE_CCKPD_TYPE2
1232 case 2:
1233 phydm_cckpd_type2(dm);
1234 break;
1235 #endif
1236 #ifdef PHYDM_COMPILE_CCKPD_TYPE3
1237 case 3:
1238 phydm_cckpd_type3(dm);
1239 break;
1240 #endif
1241 #ifdef PHYDM_COMPILE_CCKPD_TYPE4
1242 case 4:
1243 #ifdef PHYDM_DCC_ENHANCE
1244 if (dm->dm_dcc_info.dcc_en)
1245 phydm_cckpd_type4_dcc(dm);
1246 else
1247 #endif
1248 phydm_cckpd_type4(dm);
1249 break;
1250 #endif
1251 default:
1252 pr_debug("[%s]warning\n", __func__);
1253 break;
1254 }
1255 }
1256
phydm_cck_pd_init(void * dm_void)1257 void phydm_cck_pd_init(void *dm_void)
1258 {
1259 struct dm_struct *dm = (struct dm_struct *)dm_void;
1260 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
1261
1262 if (*dm->mp_mode)
1263 return;
1264
1265 if (dm->support_ic_type & CCK_PD_IC_TYPE1)
1266 cckpd_t->cckpd_hw_type = 1;
1267 else if (dm->support_ic_type & CCK_PD_IC_TYPE2)
1268 cckpd_t->cckpd_hw_type = 2;
1269 else if (dm->support_ic_type & CCK_PD_IC_TYPE3)
1270 cckpd_t->cckpd_hw_type = 3;
1271 else if (dm->support_ic_type & CCK_PD_IC_TYPE4)
1272 cckpd_t->cckpd_hw_type = 4;
1273
1274 PHYDM_DBG(dm, DBG_CCKPD, "[%s] cckpd_hw_type=%d\n",
1275 __func__, cckpd_t->cckpd_hw_type);
1276
1277 cckpd_t->cck_pd_lv = CCK_PD_LV_INIT;
1278 cckpd_t->cck_n_rx = 0xff;
1279 cckpd_t->cck_bw = CHANNEL_WIDTH_MAX;
1280 cckpd_t->cck_fa_th[1] = 400;
1281 cckpd_t->cck_fa_th[0] = 200;
1282
1283 switch (cckpd_t->cckpd_hw_type) {
1284 #ifdef PHYDM_COMPILE_CCKPD_TYPE1
1285 case 1:
1286 phydm_set_cckpd_lv_type1(dm, CCK_PD_LV_1);
1287 break;
1288 #endif
1289 #ifdef PHYDM_COMPILE_CCKPD_TYPE2
1290 case 2:
1291 cckpd_t->aaa_default = odm_read_1byte(dm, 0xaaa) & 0x1f;
1292 phydm_set_cckpd_lv_type2(dm, CCK_PD_LV_1);
1293 break;
1294 #endif
1295 #ifdef PHYDM_COMPILE_CCKPD_TYPE3
1296 case 3:
1297 phydm_cck_pd_init_type3(dm);
1298 phydm_set_cckpd_lv_type3(dm, CCK_PD_LV_1);
1299 break;
1300 #endif
1301 #ifdef PHYDM_COMPILE_CCKPD_TYPE4
1302 case 4:
1303 phydm_cck_pd_init_type4(dm);
1304 phydm_invalid_cckpd_type4(dm);
1305 phydm_set_cck_pd_lv_type4(dm, CCK_PD_LV_1);
1306 break;
1307 #endif
1308 default:
1309 pr_debug("[%s]warning\n", __func__);
1310 break;
1311 }
1312 }
1313
1314 #ifdef PHYDM_DCC_ENHANCE
1315
phydm_cckpd_type4_dcc(void * dm_void)1316 void phydm_cckpd_type4_dcc(void *dm_void)
1317 {
1318 struct dm_struct *dm = (struct dm_struct *)dm_void;
1319 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
1320 enum cckpd_lv lv_curr = cckpd_t->cck_pd_lv;
1321 enum phydm_cck_pd_trend trend = CCKPD_STABLE;
1322 u8 th_ofst = 0;
1323 u16 lv_up_th, lv_down_th;
1324
1325 PHYDM_DBG(dm, DBG_CCKPD, "%s ======>\n", __func__);
1326
1327 if (!dm->is_linked)
1328 th_ofst = 1;
1329
1330 lv_up_th = (cckpd_t->cck_fa_th[1]) << th_ofst;
1331 lv_down_th = (cckpd_t->cck_fa_th[0]) << th_ofst;
1332
1333 PHYDM_DBG(dm, DBG_CCKPD, "th{Up, Down}: {%d, %d}\n",
1334 lv_up_th, lv_down_th);
1335
1336 if (cckpd_t->cck_fa_ma > lv_up_th) {
1337 if (lv_curr <= CCK_PD_LV_3) {
1338 lv_curr++;
1339 trend = CCKPD_INCREASING;
1340 } else {
1341 lv_curr = CCK_PD_LV_4;
1342 }
1343 } else if (cckpd_t->cck_fa_ma < lv_down_th) {
1344 if (lv_curr >= CCK_PD_LV_1) {
1345 lv_curr--;
1346 trend = CCKPD_DECREASING;
1347 } else {
1348 lv_curr = CCK_PD_LV_0;
1349 }
1350 }
1351
1352 PHYDM_DBG(dm, DBG_CCKPD, "lv: %d->%d\n", cckpd_t->cck_pd_lv, lv_curr);
1353 #if 1
1354 if (trend != CCKPD_STABLE) {
1355 phydm_set_cck_pd_lv_type4(dm, lv_curr);
1356
1357 PHYDM_DBG(dm, DBG_CCKPD, "setting CS_th = 0x%x, PD th = 0x%x\n",
1358 cckpd_t->cckpd_jgr3[cckpd_t->cck_bw]
1359 [cckpd_t->cck_n_rx - 1][1][lv_curr],
1360 cckpd_t->cckpd_jgr3[cckpd_t->cck_bw]
1361 [cckpd_t->cck_n_rx - 1][0][lv_curr]);
1362 }
1363 phydm_read_cckpd_para_type4(dm);
1364 #endif
1365 }
1366
phydm_do_cckpd(void * dm_void)1367 boolean phydm_do_cckpd(void *dm_void)
1368 {
1369 struct dm_struct *dm = (struct dm_struct *)dm_void;
1370 struct phydm_dig_struct *dig_t = &dm->dm_dig_table;
1371
1372 if (dig_t->igi_trend == DIG_INCREASING)
1373 return false;
1374
1375 return true;
1376 }
1377
phydm_dig_cckpd_coex(void * dm_void)1378 void phydm_dig_cckpd_coex(void *dm_void)
1379 {
1380 struct dm_struct *dm = (struct dm_struct *)dm_void;
1381 struct phydm_dcc_struct *dcc = &dm->dm_dcc_info;
1382
1383 if (*dm->channel > 36) {
1384 phydm_dig(dm);
1385 return;
1386 } else if (!dcc->dcc_en) {
1387 phydm_dig(dm);
1388 phydm_cck_pd_th(dm);
1389 return;
1390 }
1391
1392 dcc->dig_execute_cnt++;
1393 PHYDM_DBG(dm, DBG_CCKPD, "DCC_cnt: %d\n", dcc->dig_execute_cnt);
1394
1395 if (dcc->dig_execute_cnt % dcc->dcc_ratio) {
1396 PHYDM_DBG(dm, DBG_CCKPD, "DCC: DIG\n");
1397 phydm_dig(dm);
1398 } else {
1399 if (phydm_do_cckpd(dm)) {
1400 PHYDM_DBG(dm, DBG_CCKPD, "DCC: CCKPD\n");
1401 dcc->dcc_mode = DCC_CCK_PD;
1402 phydm_cck_pd_th(dm);
1403 } else {
1404 PHYDM_DBG(dm, DBG_CCKPD, "DCC: Boost_DIG\n");
1405 dcc->dcc_mode = DCC_DIG;
1406 phydm_dig(dm);
1407 }
1408 }
1409 }
1410
phydm_dig_cckpd_coex_init(void * dm_void)1411 void phydm_dig_cckpd_coex_init(void *dm_void)
1412 {
1413 struct dm_struct *dm = (struct dm_struct *)dm_void;
1414 struct phydm_dig_struct *dig_t = &dm->dm_dig_table;
1415 struct phydm_dcc_struct *dcc = &dm->dm_dcc_info;
1416
1417 dcc->dcc_mode = DCC_DIG;
1418 dcc->dcc_en = false;
1419 dcc->dig_execute_cnt = 0;
1420 dcc->dcc_ratio = 2;
1421 }
1422
phydm_dig_cckpd_coex_dbg(void * dm_void,char input[][16],u32 * _used,char * output,u32 * _out_len)1423 void phydm_dig_cckpd_coex_dbg(void *dm_void, char input[][16], u32 *_used,
1424 char *output, u32 *_out_len)
1425 {
1426 struct dm_struct *dm = (struct dm_struct *)dm_void;
1427 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
1428 struct phydm_dcc_struct *dcc = &dm->dm_dcc_info;
1429 char help[] = "-h";
1430 u32 var[10] = {0};
1431 u32 used = *_used;
1432 u32 out_len = *_out_len;
1433 u8 i = 0;
1434
1435 for (i = 0; i < 3; i++) {
1436 if (input[i + 1])
1437 PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var[i]);
1438 }
1439
1440 if ((strcmp(input[1], help) == 0)) {
1441 PDM_SNPF(out_len, used, output + used, out_len - used,
1442 "Enable: en {0/1}\n");
1443 PDM_SNPF(out_len, used, output + used, out_len - used,
1444 "DCC_ratio: ratio {x}\n");
1445 PDM_SNPF(out_len, used, output + used, out_len - used,
1446 "threshold: th {Down_th} {Up_th}\n");
1447 } else if ((strcmp(input[1], "en") == 0)) {
1448 dcc->dcc_en = (var[1]) ? true : false;
1449 PDM_SNPF(out_len, used, output + used, out_len - used,
1450 "en=%d\n", dcc->dcc_en);
1451 } else if ((strcmp(input[1], "ratio") == 0)) {
1452 dcc->dcc_ratio = (u8)var[1];
1453 PDM_SNPF(out_len, used, output + used, out_len - used,
1454 "Ratio=%d\n", dcc->dcc_ratio);
1455 } else if ((strcmp(input[1], "th") == 0)) {
1456 cckpd_t->cck_fa_th[1] = (u16)var[2];
1457 cckpd_t->cck_fa_th[0] = (u16)var[1];
1458 PDM_SNPF(out_len, used, output + used, out_len - used,
1459 "th{Down, Up}: {%d, %d}\n",
1460 cckpd_t->cck_fa_th[0], cckpd_t->cck_fa_th[1]);
1461 }
1462
1463 *_used = used;
1464 *_out_len = out_len;
1465 }
1466
1467 #endif
1468 #endif /*#ifdef PHYDM_SUPPORT_CCKPD*/
1469
1470