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