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 if (igi >= 0x20 && dm->rssi_min >= 27) {
543 //printf(">>>>>TUYA CCK FA CNT = %d, RSSI = %d, IGI =%d \n", cckpd_t->cck_fa_ma, dm->rssi_min, igi);
544 is_update = false;
545 odm_set_bb_reg(dm, R_0xa08, BIT(21) | BIT(20), 0x2);
546 //odm_set_bb_reg(dm, R_0xac8, 0xff, 0x18);
547 }
548 else {
549 //printf("CCK FA CNT = %d, RSSI = %d, IGI =%d \n", cckpd_t->cck_fa_ma, dm->rssi_min, igi);
550 odm_set_bb_reg(dm, R_0xa08, BIT(21) | BIT(20), cckpd_t->cck_din_shift_opt);
551 //odm_set_bb_reg(dm, R_0xac8, 0xff, cckpd_t->cck_pd_20m_1r);
552 }
553 } else {
554 if (cckpd_t->cck_fa_ma > 1000)
555 lv = CCK_PD_LV_1;
556 else if (cckpd_t->cck_fa_ma < 500)
557 lv = CCK_PD_LV_0;
558 else
559 is_update = false;
560 }
561
562 if (is_update)
563 phydm_set_cckpd_lv_type3(dm, lv);
564
565 if (cckpd_t->cck_n_rx == 2) {
566 if (cckpd_t->cck_bw == CHANNEL_WIDTH_20) {
567 pd_th = cckpd_t->cur_cck_pd_20m_2r;
568 cs_ratio = cckpd_t->cur_cck_cs_ratio_20m_2r;
569 } else {
570 pd_th = cckpd_t->cur_cck_pd_40m_2r;
571 cs_ratio = cckpd_t->cur_cck_cs_ratio_40m_2r;
572 }
573 } else {
574 if (cckpd_t->cck_bw == CHANNEL_WIDTH_20) {
575 pd_th = cckpd_t->cur_cck_pd_20m_1r;
576 cs_ratio = cckpd_t->cur_cck_cs_ratio_20m_1r;
577 } else {
578 pd_th = cckpd_t->cur_cck_pd_40m_1r;
579 cs_ratio = cckpd_t->cur_cck_cs_ratio_40m_1r;
580 }
581 }
582 PHYDM_DBG(dm, DBG_CCKPD,
583 "[%dR][%dM] is_linked=%d, lv=%d, cs_ratio=0x%x, pd_th=0x%x\n\n",
584 cckpd_t->cck_n_rx, 20 << cckpd_t->cck_bw, dm->is_linked,
585 cckpd_t->cck_pd_lv, cs_ratio, pd_th);
586 }
587
phydm_cck_pd_init_type3(void * dm_void)588 void phydm_cck_pd_init_type3(void *dm_void)
589 {
590 struct dm_struct *dm = (struct dm_struct *)dm_void;
591 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
592 u32 reg_tmp = 0;
593
594 /*Get Default value*/
595 cckpd_t->cck_pd_20m_1r = (u8)odm_get_bb_reg(dm, R_0xac8, 0xff);
596 cckpd_t->cck_pd_20m_2r = (u8)odm_get_bb_reg(dm, R_0xac8, 0xff00);
597 cckpd_t->cck_pd_40m_1r = (u8)odm_get_bb_reg(dm, R_0xacc, 0xff);
598 cckpd_t->cck_pd_40m_2r = (u8)odm_get_bb_reg(dm, R_0xacc, 0xff00);
599 cckpd_t->cck_din_shift_opt = (u8)odm_get_bb_reg(dm, R_0xa08, BIT(21) | BIT(20));
600
601 reg_tmp = odm_get_bb_reg(dm, R_0xad0, MASKDWORD);
602 cckpd_t->cck_cs_ratio_20m_1r = (u8)(reg_tmp & 0x1f);
603 cckpd_t->cck_cs_ratio_20m_2r = (u8)((reg_tmp & 0x3e0) >> 5);
604 cckpd_t->cck_cs_ratio_40m_1r = (u8)((reg_tmp & 0x1f00000) >> 20);
605 cckpd_t->cck_cs_ratio_40m_2r = (u8)((reg_tmp & 0x3e000000) >> 25);
606 }
607 #endif /*#ifdef PHYDM_COMPILE_CCKPD_TYPE3*/
608
609 #ifdef PHYDM_COMPILE_CCKPD_TYPE4
phydm_write_cck_pd_type4(void * dm_void,enum cckpd_lv lv,enum cckpd_mode mode)610 void phydm_write_cck_pd_type4(void *dm_void, enum cckpd_lv lv,
611 enum cckpd_mode mode)
612 {
613 struct dm_struct *dm = (struct dm_struct *)dm_void;
614 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
615 u32 val = 0;
616
617 PHYDM_DBG(dm, DBG_CCKPD, "write CCK CCA parameters(CS_ratio & PD)\n");
618 switch (mode) {
619 case CCK_BW20_1R: /*RFBW20_1R*/
620 {
621 val = cckpd_t->cckpd_jgr3[0][0][0][lv];
622 odm_set_bb_reg(dm, R_0x1ac8, 0xff, val);
623 val = cckpd_t->cckpd_jgr3[0][0][1][lv];
624 odm_set_bb_reg(dm, R_0x1ad0, 0x1f, val);
625 } break;
626 case CCK_BW40_1R: /*RFBW40_1R*/
627 {
628 val = cckpd_t->cckpd_jgr3[1][0][0][lv];
629 odm_set_bb_reg(dm, R_0x1acc, 0xff, val);
630 val = cckpd_t->cckpd_jgr3[1][0][1][lv];
631 odm_set_bb_reg(dm, R_0x1ad0, 0x01F00000, val);
632 } break;
633 #if (defined(PHYDM_COMPILE_ABOVE_2SS))
634 case CCK_BW20_2R: /*RFBW20_2R*/
635 {
636 val = cckpd_t->cckpd_jgr3[0][1][0][lv];
637 odm_set_bb_reg(dm, R_0x1ac8, 0xff00, val);
638 val = cckpd_t->cckpd_jgr3[0][1][1][lv];
639 odm_set_bb_reg(dm, R_0x1ad0, 0x3e0, val);
640 } break;
641 case CCK_BW40_2R: /*RFBW40_2R*/
642 {
643 val = cckpd_t->cckpd_jgr3[1][1][0][lv];
644 odm_set_bb_reg(dm, R_0x1acc, 0xff00, val);
645 val = cckpd_t->cckpd_jgr3[1][1][1][lv];
646 odm_set_bb_reg(dm, R_0x1ad0, 0x3E000000, val);
647 } break;
648 #endif
649 #if (defined(PHYDM_COMPILE_ABOVE_3SS))
650 case CCK_BW20_3R: /*RFBW20_3R*/
651 {
652 val = cckpd_t->cckpd_jgr3[0][2][0][lv];
653 odm_set_bb_reg(dm, R_0x1ac8, 0xff0000, val);
654 val = cckpd_t->cckpd_jgr3[0][2][1][lv];
655 odm_set_bb_reg(dm, R_0x1ad0, 0x7c00, val);
656 } break;
657 case CCK_BW40_3R: /*RFBW40_3R*/
658 {
659 val = cckpd_t->cckpd_jgr3[1][2][0][lv];
660 odm_set_bb_reg(dm, R_0x1acc, 0xff0000, val);
661 val = cckpd_t->cckpd_jgr3[1][2][1][lv] & 0x3;
662 odm_set_bb_reg(dm, R_0x1ad0, 0xC0000000, val);
663 val = (cckpd_t->cckpd_jgr3[1][2][1][lv] & 0x1c) >> 2;
664 odm_set_bb_reg(dm, R_0x1ad4, 0x7, val);
665 } break;
666 #endif
667 #if (defined(PHYDM_COMPILE_ABOVE_4SS))
668 case CCK_BW20_4R: /*RFBW20_4R*/
669 {
670 val = cckpd_t->cckpd_jgr3[0][3][0][lv];
671 odm_set_bb_reg(dm, R_0x1ac8, 0xff000000, val);
672 val = cckpd_t->cckpd_jgr3[0][3][1][lv];
673 odm_set_bb_reg(dm, R_0x1ad0, 0xF8000, val);
674 } break;
675 case CCK_BW40_4R: /*RFBW40_4R*/
676 {
677 val = cckpd_t->cckpd_jgr3[1][3][0][lv];
678 odm_set_bb_reg(dm, R_0x1acc, 0xff000000, val);
679 val = cckpd_t->cckpd_jgr3[1][3][1][lv];
680 odm_set_bb_reg(dm, R_0x1ad4, 0xf8, val);
681 } break;
682 #endif
683 default:
684 /*@pr_debug("[%s] warning!\n", __func__);*/
685 break;
686 }
687 }
688
phydm_set_cck_pd_lv_type4(void * dm_void,enum cckpd_lv lv)689 void phydm_set_cck_pd_lv_type4(void *dm_void, enum cckpd_lv lv)
690 {
691 struct dm_struct *dm = (struct dm_struct *)dm_void;
692 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
693 enum cckpd_mode cck_mode = CCK_BW20_2R;
694 enum channel_width cck_bw = CHANNEL_WIDTH_20;
695 u8 cck_n_rx = 0;
696 u32 val = 0;
697 /*u32 val_dbg = 0;*/
698
699 PHYDM_DBG(dm, DBG_CCKPD, "%s ======>\n", __func__);
700 PHYDM_DBG(dm, DBG_CCKPD, "lv: (%d) -> (%d)\n", cckpd_t->cck_pd_lv, lv);
701
702 /*[Check Nrx]*/
703 cck_n_rx = (u8)odm_get_bb_reg(dm, R_0x1a2c, 0x60000) + 1;
704
705 /*[Check BW]*/
706 val = odm_get_bb_reg(dm, R_0x9b0, 0xc);
707 if (val == 0)
708 cck_bw = CHANNEL_WIDTH_20;
709 else if (val == 1)
710 cck_bw = CHANNEL_WIDTH_40;
711 else
712 cck_bw = CHANNEL_WIDTH_80;
713
714 /*[Check LV]*/
715 if (cckpd_t->cck_pd_lv == lv &&
716 cckpd_t->cck_n_rx == cck_n_rx &&
717 cckpd_t->cck_bw == cck_bw) {
718 PHYDM_DBG(dm, DBG_CCKPD, "stay in lv=%d\n", lv);
719 return;
720 }
721
722 cckpd_t->cck_bw = cck_bw;
723 cckpd_t->cck_n_rx = cck_n_rx;
724 cckpd_t->cck_pd_lv = lv;
725 cckpd_t->cck_fa_ma = CCK_FA_MA_RESET;
726
727 switch (cck_n_rx) {
728 case 1: /*1R*/
729 {
730 if (cck_bw == CHANNEL_WIDTH_20)
731 cck_mode = CCK_BW20_1R;
732 else if (cck_bw == CHANNEL_WIDTH_40)
733 cck_mode = CCK_BW40_1R;
734 } break;
735 #if (defined(PHYDM_COMPILE_ABOVE_2SS))
736 case 2: /*2R*/
737 {
738 if (cck_bw == CHANNEL_WIDTH_20)
739 cck_mode = CCK_BW20_2R;
740 else if (cck_bw == CHANNEL_WIDTH_40)
741 cck_mode = CCK_BW40_2R;
742 } break;
743 #endif
744 #if (defined(PHYDM_COMPILE_ABOVE_3SS))
745 case 3: /*3R*/
746 {
747 if (cck_bw == CHANNEL_WIDTH_20)
748 cck_mode = CCK_BW20_3R;
749 else if (cck_bw == CHANNEL_WIDTH_40)
750 cck_mode = CCK_BW40_3R;
751 } break;
752 #endif
753 #if (defined(PHYDM_COMPILE_ABOVE_4SS))
754 case 4: /*4R*/
755 {
756 if (cck_bw == CHANNEL_WIDTH_20)
757 cck_mode = CCK_BW20_4R;
758 else if (cck_bw == CHANNEL_WIDTH_40)
759 cck_mode = CCK_BW40_4R;
760 } break;
761 #endif
762 default:
763 /*@pr_debug("[%s] warning!\n", __func__);*/
764 break;
765 }
766 phydm_write_cck_pd_type4(dm, lv, cck_mode);
767 }
768
phydm_read_cckpd_para_type4(void * dm_void)769 void phydm_read_cckpd_para_type4(void *dm_void)
770 {
771 struct dm_struct *dm = (struct dm_struct *)dm_void;
772 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
773 u8 bw = 0; /*r_RX_RF_BW*/
774 u8 n_rx = 0;
775 u8 curr_cck_pd_t[2][4][2];
776 u32 reg0 = 0;
777 u32 reg1 = 0;
778 u32 reg2 = 0;
779 u32 reg3 = 0;
780
781 if (!(dm->debug_components & DBG_CCKPD))
782 return;
783
784 bw = (u8)odm_get_bb_reg(dm, R_0x9b0, 0xc);
785 n_rx = (u8)odm_get_bb_reg(dm, R_0x1a2c, 0x60000) + 1;
786
787 reg0 = odm_get_bb_reg(dm, R_0x1ac8, MASKDWORD);
788 reg1 = odm_get_bb_reg(dm, R_0x1acc, MASKDWORD);
789 reg2 = odm_get_bb_reg(dm, R_0x1ad0, MASKDWORD);
790 reg3 = odm_get_bb_reg(dm, R_0x1ad4, MASKDWORD);
791 curr_cck_pd_t[0][0][0] = (u8)(reg0 & 0x000000ff);
792 curr_cck_pd_t[1][0][0] = (u8)(reg1 & 0x000000ff);
793 curr_cck_pd_t[0][0][1] = (u8)(reg2 & 0x0000001f);
794 curr_cck_pd_t[1][0][1] = (u8)((reg2 & 0x01f00000) >> 20);
795 #if (defined(PHYDM_COMPILE_ABOVE_2SS))
796 if (dm->support_ic_type & PHYDM_IC_ABOVE_2SS) {
797 curr_cck_pd_t[0][1][0] = (u8)((reg0 & 0x0000ff00) >> 8);
798 curr_cck_pd_t[1][1][0] = (u8)((reg1 & 0x0000ff00) >> 8);
799 curr_cck_pd_t[0][1][1] = (u8)((reg2 & 0x000003E0) >> 5);
800 curr_cck_pd_t[1][1][1] = (u8)((reg2 & 0x3E000000) >> 25);
801 }
802 #endif
803 #if (defined(PHYDM_COMPILE_ABOVE_3SS))
804 if (dm->support_ic_type & PHYDM_IC_ABOVE_3SS) {
805 curr_cck_pd_t[0][2][0] = (u8)((reg0 & 0x00ff0000) >> 16);
806 curr_cck_pd_t[1][2][0] = (u8)((reg1 & 0x00ff0000) >> 16);
807 curr_cck_pd_t[0][2][1] = (u8)((reg2 & 0x00007C00) >> 10);
808 curr_cck_pd_t[1][2][1] = (u8)((reg2 & 0xC0000000) >> 30) |
809 (u8)((reg3 & 0x00000007) << 2);
810 }
811 #endif
812 #if (defined(PHYDM_COMPILE_ABOVE_4SS))
813 if (dm->support_ic_type & PHYDM_IC_ABOVE_4SS) {
814 curr_cck_pd_t[0][3][0] = (u8)((reg0 & 0xff000000) >> 24);
815 curr_cck_pd_t[1][3][0] = (u8)((reg1 & 0xff000000) >> 24);
816 curr_cck_pd_t[0][3][1] = (u8)((reg2 & 0x000F8000) >> 15);
817 curr_cck_pd_t[1][3][1] = (u8)((reg3 & 0x000000F8) >> 3);
818 }
819 #endif
820
821 PHYDM_DBG(dm, DBG_CCKPD, "bw=%dM, Nrx=%d\n", 20 << bw, n_rx);
822 PHYDM_DBG(dm, DBG_CCKPD, "lv=%d, readback CS_th=0x%x, PD th=0x%x\n",
823 cckpd_t->cck_pd_lv,
824 curr_cck_pd_t[bw][n_rx - 1][1],
825 curr_cck_pd_t[bw][n_rx - 1][0]);
826 }
827
phydm_cckpd_type4(void * dm_void)828 void phydm_cckpd_type4(void *dm_void)
829 {
830 struct dm_struct *dm = (struct dm_struct *)dm_void;
831 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
832 u8 igi = dm->dm_dig_table.cur_ig_value;
833 enum cckpd_lv lv = 0;
834 boolean is_update = true;
835
836 PHYDM_DBG(dm, DBG_CCKPD, "%s ======>\n", __func__);
837
838 if (dm->is_linked) {
839 PHYDM_DBG(dm, DBG_CCKPD, "Linked!!!\n");
840 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
841 if (dm->rssi_min > 40) {
842 lv = CCK_PD_LV_4;
843 PHYDM_DBG(dm, DBG_CCKPD, "Order 1\n");
844 } else if (dm->rssi_min > 32) {
845 lv = CCK_PD_LV_3;
846 PHYDM_DBG(dm, DBG_CCKPD, "Order 2\n");
847 } else if (dm->rssi_min > 24) {
848 lv = CCK_PD_LV_2;
849 PHYDM_DBG(dm, DBG_CCKPD, "Order 3\n");
850 } else {
851 if (cckpd_t->cck_fa_ma > 1000) {
852 lv = CCK_PD_LV_1;
853 PHYDM_DBG(dm, DBG_CCKPD, "Order 4-1\n");
854 } else if (cckpd_t->cck_fa_ma < 500) {
855 lv = CCK_PD_LV_0;
856 PHYDM_DBG(dm, DBG_CCKPD, "Order 4-2\n");
857 } else {
858 is_update = false;
859 PHYDM_DBG(dm, DBG_CCKPD, "Order 4-3\n");
860 }
861 }
862 #else /*ODM_AP*/
863 if (igi > 0x38 && dm->rssi_min > 32) {
864 lv = CCK_PD_LV_4;
865 PHYDM_DBG(dm, DBG_CCKPD, "Order 1\n");
866 } else if (igi > 0x2a && dm->rssi_min > 32) {
867 lv = CCK_PD_LV_3;
868 PHYDM_DBG(dm, DBG_CCKPD, "Order 2\n");
869 } else if (igi > 0x24 || dm->rssi_min > 24) {
870 lv = CCK_PD_LV_2;
871 PHYDM_DBG(dm, DBG_CCKPD, "Order 3\n");
872 } else {
873 if (cckpd_t->cck_fa_ma > 1000) {
874 lv = CCK_PD_LV_1;
875 PHYDM_DBG(dm, DBG_CCKPD, "Order 4-1\n");
876 } else if (cckpd_t->cck_fa_ma < 500) {
877 lv = CCK_PD_LV_0;
878 PHYDM_DBG(dm, DBG_CCKPD, "Order 4-2\n");
879 } else {
880 is_update = false;
881 PHYDM_DBG(dm, DBG_CCKPD, "Order 4-3\n");
882 }
883 }
884 #endif
885 } else {
886 PHYDM_DBG(dm, DBG_CCKPD, "UnLinked!!!\n");
887 if (cckpd_t->cck_fa_ma > 1000) {
888 lv = CCK_PD_LV_1;
889 PHYDM_DBG(dm, DBG_CCKPD, "Order 1\n");
890 } else if (cckpd_t->cck_fa_ma < 500) {
891 lv = CCK_PD_LV_0;
892 PHYDM_DBG(dm, DBG_CCKPD, "Order 2\n");
893 } else {
894 is_update = false;
895 PHYDM_DBG(dm, DBG_CCKPD, "Order 3\n");
896 }
897 }
898
899 if (is_update) {
900 phydm_set_cck_pd_lv_type4(dm, lv);
901
902 PHYDM_DBG(dm, DBG_CCKPD, "setting CS_th = 0x%x, PD th = 0x%x\n",
903 cckpd_t->cckpd_jgr3[cckpd_t->cck_bw]
904 [cckpd_t->cck_n_rx - 1][1][lv],
905 cckpd_t->cckpd_jgr3[cckpd_t->cck_bw]
906 [cckpd_t->cck_n_rx - 1][0][lv]);
907 }
908 phydm_read_cckpd_para_type4(dm);
909 }
910
phydm_cck_pd_init_type4(void * dm_void)911 void phydm_cck_pd_init_type4(void *dm_void)
912 {
913 struct dm_struct *dm = (struct dm_struct *)dm_void;
914 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
915 u32 reg0 = 0;
916 u32 reg1 = 0;
917 u32 reg2 = 0;
918 u32 reg3 = 0;
919 u8 pw_step = 0;
920 u8 cs_step = 0;
921 u8 cck_bw = 0; /*r_RX_RF_BW*/
922 u8 cck_n_rx = 0;
923 u8 val = 0;
924 u8 i = 0;
925
926 PHYDM_DBG(dm, DBG_CCKPD, "[%s]======>\n", __func__);
927
928 #if 0
929 /*@
930 *cckpd_t[0][0][0][0] = 1ac8[7:0] r_PD_lim_RFBW20_1R
931 *cckpd_t[0][1][0][0] = 1ac8[15:8] r_PD_lim_RFBW20_2R
932 *cckpd_t[0][2][0][0] = 1ac8[23:16] r_PD_lim_RFBW20_3R
933 *cckpd_t[0][3][0][0] = 1ac8[31:24] r_PD_lim_RFBW20_4R
934 *cckpd_t[1][0][0][0] = 1acc[7:0] r_PD_lim_RFBW40_1R
935 *cckpd_t[1][1][0][0] = 1acc[15:8] r_PD_lim_RFBW40_2R
936 *cckpd_t[1][2][0][0] = 1acc[23:16] r_PD_lim_RFBW40_3R
937 *cckpd_t[1][3][0][0] = 1acc[31:24] r_PD_lim_RFBW40_4R
938 *
939 *
940 *cckpd_t[0][0][1][0] = 1ad0[4:0] r_CS_ratio_RFBW20_1R[4:0]
941 *cckpd_t[0][1][1][0] = 1ad0[9:5] r_CS_ratio_RFBW20_2R[4:0]
942 *cckpd_t[0][2][1][0] = 1ad0[14:10] r_CS_ratio_RFBW20_3R[4:0]
943 *cckpd_t[0][3][1][0] = 1ad0[19:15] r_CS_ratio_RFBW20_4R[4:0]
944 *cckpd_t[1][0][1][0] = 1ad0[24:20] r_CS_ratio_RFBW40_1R[4:0]
945 *cckpd_t[1][1][1][0] = 1ad0[29:25] r_CS_ratio_RFBW40_2R[4:0]
946 *cckpd_t[1][2][1][0] = 1ad0[31:30] r_CS_ratio_RFBW40_3R[1:0]
947 * 1ad4[2:0] r_CS_ratio_RFBW40_3R[4:2]
948 *cckpd_t[1][3][1][0] = 1ad4[7:3] r_CS_ratio_RFBW40_4R[4:0]
949 */
950 #endif
951 /*[Check Nrx]*/
952 cck_n_rx = (u8)odm_get_bb_reg(dm, R_0x1a2c, 0x60000) + 1;
953
954 /*[Check BW]*/
955 val = (u8)odm_get_bb_reg(dm, R_0x9b0, 0xc);
956 if (val == 0)
957 cck_bw = CHANNEL_WIDTH_20;
958 else if (val == 1)
959 cck_bw = CHANNEL_WIDTH_40;
960 else
961 cck_bw = CHANNEL_WIDTH_80;
962
963 cckpd_t->cck_bw = cck_bw;
964 cckpd_t->cck_n_rx = cck_n_rx;
965 reg0 = odm_get_bb_reg(dm, R_0x1ac8, MASKDWORD);
966 reg1 = odm_get_bb_reg(dm, R_0x1acc, MASKDWORD);
967 reg2 = odm_get_bb_reg(dm, R_0x1ad0, MASKDWORD);
968 reg3 = odm_get_bb_reg(dm, R_0x1ad4, MASKDWORD);
969
970 for (i = 0 ; i < CCK_PD_LV_MAX ; i++) {
971 pw_step = i * 2;
972 cs_step = i * 2;
973
974 #if (RTL8197G_SUPPORT)
975 if (dm->support_ic_type & ODM_RTL8197G) {
976 pw_step = i;
977 cs_step = i;
978 if (i > CCK_PD_LV_3) {
979 pw_step = 3;
980 cs_step = 3;
981 }
982 }
983 #endif
984
985 #if (RTL8822C_SUPPORT)
986 if (dm->support_ic_type & ODM_RTL8822C) {
987 if (i == CCK_PD_LV_1) {
988 pw_step = 9; /*IGI-19.2:0x11=d'17*/
989 cs_step = 0;
990 } else if (i == CCK_PD_LV_2) {
991 pw_step = 12; /*IGI-15.5:0x14=d'20*/
992 cs_step = 1;
993 } else if (i == CCK_PD_LV_3) {
994 pw_step = 14; /*IGI-14:0x16=d'22*/
995 cs_step = 1;
996 } else if (i == CCK_PD_LV_4) {
997 pw_step = 17; /*IGI-12:0x19=d'25*/
998 cs_step = 1;
999 }
1000 }
1001 #endif
1002
1003 val = (u8)(reg0 & 0x000000ff) + pw_step;
1004 PHYDM_DBG(dm, DBG_CCKPD, "lvl %d val = %x\n\n", i, val);
1005 cckpd_t->cckpd_jgr3[0][0][0][i] = val;
1006
1007 val = (u8)(reg1 & 0x000000ff) + pw_step;
1008 cckpd_t->cckpd_jgr3[1][0][0][i] = val;
1009
1010 val = (u8)(reg2 & 0x0000001f) + cs_step;
1011 cckpd_t->cckpd_jgr3[0][0][1][i] = val;
1012
1013 val = (u8)((reg2 & 0x01f00000) >> 20) + cs_step;
1014 cckpd_t->cckpd_jgr3[1][0][1][i] = val;
1015
1016 #ifdef PHYDM_COMPILE_ABOVE_2SS
1017 if (dm->support_ic_type & PHYDM_IC_ABOVE_2SS) {
1018 val = (u8)((reg0 & 0x0000ff00) >> 8) + pw_step;
1019 cckpd_t->cckpd_jgr3[0][1][0][i] = val;
1020
1021 val = (u8)((reg1 & 0x0000ff00) >> 8) + pw_step;
1022 cckpd_t->cckpd_jgr3[1][1][0][i] = val;
1023
1024 val = (u8)((reg2 & 0x000003e0) >> 5) + cs_step;
1025 cckpd_t->cckpd_jgr3[0][1][1][i] = val;
1026
1027 val = (u8)((reg2 & 0x3e000000) >> 25) + cs_step;
1028 cckpd_t->cckpd_jgr3[1][1][1][i] = val;
1029 }
1030 #endif
1031
1032 #ifdef PHYDM_COMPILE_ABOVE_3SS
1033 if (dm->support_ic_type & PHYDM_IC_ABOVE_3SS) {
1034 val = (u8)((reg0 & 0x00ff0000) >> 16) + pw_step;
1035 cckpd_t->cckpd_jgr3[0][2][0][i] = val;
1036
1037 val = (u8)((reg1 & 0x00ff0000) >> 16) + pw_step;
1038 cckpd_t->cckpd_jgr3[1][2][0][i] = val;
1039 val = (u8)((reg2 & 0x00007c00) >> 10) + cs_step;
1040 cckpd_t->cckpd_jgr3[0][2][1][i] = val;
1041 val = (u8)(((reg2 & 0xc0000000) >> 30) |
1042 ((reg3 & 0x7) << 3)) + cs_step;
1043 cckpd_t->cckpd_jgr3[1][2][1][i] = val;
1044 }
1045 #endif
1046
1047 #ifdef PHYDM_COMPILE_ABOVE_4SS
1048 if (dm->support_ic_type & PHYDM_IC_ABOVE_4SS) {
1049 val = (u8)((reg0 & 0xff000000) >> 24) + pw_step;
1050 cckpd_t->cckpd_jgr3[0][3][0][i] = val;
1051
1052 val = (u8)((reg1 & 0xff000000) >> 24) + pw_step;
1053 cckpd_t->cckpd_jgr3[1][3][0][i] = val;
1054
1055 val = (u8)((reg2 & 0x000f8000) >> 15) + cs_step;
1056 cckpd_t->cckpd_jgr3[0][3][1][i] = val;
1057
1058 val = (u8)((reg3 & 0x000000f8) >> 3) + cs_step;
1059 cckpd_t->cckpd_jgr3[1][3][1][i] = val;
1060 }
1061 #endif
1062 }
1063 }
1064
phydm_invalid_cckpd_type4(void * dm_void)1065 void phydm_invalid_cckpd_type4(void *dm_void)
1066 {
1067 struct dm_struct *dm = (struct dm_struct *)dm_void;
1068 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
1069 u8 val = 0;
1070 u8 i = 0;
1071 u8 j = 0;
1072 u8 k = 0;
1073
1074 PHYDM_DBG(dm, DBG_CCKPD, "[%s]======>\n", __func__);
1075
1076 for (i = 0; i < CCK_PD_LV_MAX; i++) {
1077 for (j = 0; j < 2; j++) {
1078 for (k = 0; k < dm->num_rf_path; k++) {
1079 val = cckpd_t->cckpd_jgr3[j][k][1][i];
1080 if (val == INVALID_CS_RATIO_0)
1081 cckpd_t->cckpd_jgr3[j][k][1][i] = 0x1c;
1082 else if (val == INVALID_CS_RATIO_1)
1083 cckpd_t->cckpd_jgr3[j][k][1][i] = 0x1e;
1084 else if (val > MAXVALID_CS_RATIO)
1085 cckpd_t->cckpd_jgr3[j][k][1][i] =
1086 MAXVALID_CS_RATIO;
1087 }
1088 }
1089
1090 #if (RTL8198F_SUPPORT)
1091 if (dm->support_ic_type & ODM_RTL8198F) {
1092 val = cckpd_t->cckpd_jgr3[0][3][1][i];
1093 if (i == CCK_PD_LV_1 && val > 0x10)
1094 cckpd_t->cckpd_jgr3[0][3][1][i] = 0x10;
1095 else if (i == CCK_PD_LV_2 && val > 0x10)
1096 cckpd_t->cckpd_jgr3[0][3][1][i] = 0x10;
1097 else if (i == CCK_PD_LV_3 && val > 0x10)
1098 cckpd_t->cckpd_jgr3[0][3][1][i] = 0x10;
1099 else if (i == CCK_PD_LV_4 && val > 0x10)
1100 cckpd_t->cckpd_jgr3[0][3][1][i] = 0x10;
1101 val = cckpd_t->cckpd_jgr3[1][3][1][i];
1102 if (i == CCK_PD_LV_1 && val > 0xF)
1103 cckpd_t->cckpd_jgr3[1][3][1][i] = 0xF;
1104 else if (i == CCK_PD_LV_2 && val > 0xF)
1105 cckpd_t->cckpd_jgr3[1][3][1][i] = 0xF;
1106 else if (i == CCK_PD_LV_3 && val > 0xF)
1107 cckpd_t->cckpd_jgr3[1][3][1][i] = 0xF;
1108 else if (i == CCK_PD_LV_4 && val > 0xF)
1109 cckpd_t->cckpd_jgr3[1][3][1][i] = 0xF;
1110 }
1111 #endif
1112 }
1113 }
1114
1115 #endif /*#ifdef PHYDM_COMPILE_CCKPD_TYPE4*/
1116
1117
1118 #ifdef PHYDM_COMPILE_CCKPD_TYPE5
phydm_write_cck_pd_type5(void * dm_void,enum cckpd_lv lv,enum cckpd_mode mode)1119 void phydm_write_cck_pd_type5(void *dm_void, enum cckpd_lv lv,
1120 enum cckpd_mode mode)
1121 {
1122 struct dm_struct *dm = (struct dm_struct *)dm_void;
1123 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
1124 u32 val = 0;
1125
1126 PHYDM_DBG(dm, DBG_CCKPD, "write CCK CCA parameters(CS_ratio & PD)\n");
1127 switch (mode) {
1128 case CCK_BW20_1R: /*RFBW20_1R*/
1129 {
1130 val = cckpd_t->cck_pd_table_jgr3[0][0][0][lv];
1131 odm_set_bb_reg(dm, R_0x1a30, 0x1f, val);
1132 val = cckpd_t->cck_pd_table_jgr3[0][0][1][lv];
1133 odm_set_bb_reg(dm, R_0x1a20, 0x1f, val);
1134 } break;
1135 case CCK_BW40_1R: /*RFBW40_1R*/
1136 {
1137 val = cckpd_t->cck_pd_table_jgr3[1][0][0][lv];
1138 odm_set_bb_reg(dm, R_0x1a34, 0x1f, val);
1139 val = cckpd_t->cck_pd_table_jgr3[1][0][1][lv];
1140 odm_set_bb_reg(dm, R_0x1a24, 0x1f, val);
1141 } break;
1142 #if (defined(PHYDM_COMPILE_ABOVE_2SS))
1143 case CCK_BW20_2R: /*RFBW20_2R*/
1144 {
1145 val = cckpd_t->cck_pd_table_jgr3[0][1][0][lv];
1146 odm_set_bb_reg(dm, R_0x1a30, 0x3e0, val);
1147 val = cckpd_t->cck_pd_table_jgr3[0][1][1][lv];
1148 odm_set_bb_reg(dm, R_0x1a20, 0x3e0, val);
1149 } break;
1150 case CCK_BW40_2R: /*RFBW40_2R*/
1151 {
1152 val = cckpd_t->cck_pd_table_jgr3[1][1][0][lv];
1153 odm_set_bb_reg(dm, R_0x1a34, 0x3e0, val);
1154 val = cckpd_t->cck_pd_table_jgr3[1][1][1][lv];
1155 odm_set_bb_reg(dm, R_0x1a24, 0x3e0, val);
1156 } break;
1157 #endif
1158 #if (defined(PHYDM_COMPILE_ABOVE_3SS))
1159 case CCK_BW20_3R: /*RFBW20_3R*/
1160 {
1161 val = cckpd_t->cck_pd_table_jgr3[0][2][0][lv];
1162 odm_set_bb_reg(dm, R_0x1a30, 0x7c00, val);
1163 val = cckpd_t->cck_pd_table_jgr3[0][2][1][lv];
1164 odm_set_bb_reg(dm, R_0x1a20, 0x7c00, val);
1165 } break;
1166 case CCK_BW40_3R: /*RFBW40_3R*/
1167 {
1168 val = cckpd_t->cck_pd_table_jgr3[1][2][0][lv];
1169 odm_set_bb_reg(dm, R_0x1a34, 0x7c00, val);
1170 val = cckpd_t->cck_pd_table_jgr3[1][2][1][lv];
1171 odm_set_bb_reg(dm, R_0x1a24, 0x7c00, val);
1172 } break;
1173 #endif
1174 #if (defined(PHYDM_COMPILE_ABOVE_4SS))
1175 case CCK_BW20_4R: /*RFBW20_4R*/
1176 {
1177 val = cckpd_t->cck_pd_table_jgr3[0][3][0][lv];
1178 odm_set_bb_reg(dm, R_0x1a30, 0xF8000, val);
1179 val = cckpd_t->cck_pd_table_jgr3[0][3][1][lv];
1180 odm_set_bb_reg(dm, R_0x1a20, 0xF8000, val);
1181 } break;
1182 case CCK_BW40_4R: /*RFBW40_4R*/
1183 {
1184 val = cckpd_t->cck_pd_table_jgr3[1][3][0][lv];
1185 odm_set_bb_reg(dm, R_0x1a34, 0xF8000, val);
1186 val = cckpd_t->cck_pd_table_jgr3[1][3][1][lv];
1187 odm_set_bb_reg(dm, R_0x1a24, 0xF8000, val);
1188 } break;
1189 #endif
1190 default:
1191 /*@pr_debug("[%s] warning!\n", __func__);*/
1192 break;
1193 }
1194 }
1195
1196
phydm_set_cck_pd_lv_type5(void * dm_void,enum cckpd_lv lv)1197 void phydm_set_cck_pd_lv_type5(void *dm_void, enum cckpd_lv lv)
1198 {
1199 struct dm_struct *dm = (struct dm_struct *)dm_void;
1200 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
1201 enum cckpd_mode cck_mode = CCK_BW20_1R;
1202 enum channel_width cck_bw = CHANNEL_WIDTH_20;
1203 u8 cck_n_rx = 0;
1204 u32 val = 0;
1205 /*u32 val_dbg = 0;*/
1206
1207 PHYDM_DBG(dm, DBG_CCKPD, "%s ======>\n", __func__);
1208 PHYDM_DBG(dm, DBG_CCKPD, "lv: (%d) -> (%d)\n", cckpd_t->cck_pd_lv, lv);
1209
1210 /*[Check Nrx] for 8723F*/
1211 cck_n_rx = 1;
1212
1213 /*[Check BW]*/
1214 val = odm_get_bb_reg(dm, R_0x9b0, 0xc);
1215 if (val == 0)
1216 cck_bw = CHANNEL_WIDTH_20;
1217 else if (val == 1)
1218 cck_bw = CHANNEL_WIDTH_40;
1219 else
1220 cck_bw = CHANNEL_WIDTH_80;
1221
1222 /*[Check LV]*/
1223 if (cckpd_t->cck_pd_lv == lv &&
1224 cckpd_t->cck_n_rx == cck_n_rx &&
1225 cckpd_t->cck_bw == cck_bw) {
1226 PHYDM_DBG(dm, DBG_CCKPD, "stay in lv=%d\n", lv);
1227 return;
1228 }
1229 cckpd_t->cck_bw = cck_bw;
1230 cckpd_t->cck_n_rx = cck_n_rx;
1231 cckpd_t->cck_pd_lv = lv;
1232 cckpd_t->cck_fa_ma = CCK_FA_MA_RESET;
1233
1234 switch (cck_n_rx) {
1235 case 1: /*1R*/
1236 {
1237 if (cck_bw == CHANNEL_WIDTH_20)
1238 cck_mode = CCK_BW20_1R;
1239 else if (cck_bw == CHANNEL_WIDTH_40)
1240 cck_mode = CCK_BW40_1R;
1241 } break;
1242 #if (defined(PHYDM_COMPILE_ABOVE_2SS))
1243 case 2: /*2R*/
1244 {
1245 if (cck_bw == CHANNEL_WIDTH_20)
1246 cck_mode = CCK_BW20_2R;
1247 else if (cck_bw == CHANNEL_WIDTH_40)
1248 cck_mode = CCK_BW40_2R;
1249 } break;
1250 #endif
1251 #if (defined(PHYDM_COMPILE_ABOVE_3SS))
1252 case 3: /*3R*/
1253 {
1254 if (cck_bw == CHANNEL_WIDTH_20)
1255 cck_mode = CCK_BW20_3R;
1256 else if (cck_bw == CHANNEL_WIDTH_40)
1257 cck_mode = CCK_BW40_3R;
1258 } break;
1259 #endif
1260 #if (defined(PHYDM_COMPILE_ABOVE_4SS))
1261 case 4: /*4R*/
1262 {
1263 if (cck_bw == CHANNEL_WIDTH_20)
1264 cck_mode = CCK_BW20_4R;
1265 else if (cck_bw == CHANNEL_WIDTH_40)
1266 cck_mode = CCK_BW40_4R;
1267 } break;
1268 #endif
1269 default:
1270 /*@pr_debug("[%s] warning!\n", __func__);*/
1271 break;
1272 }
1273
1274
1275
1276 phydm_write_cck_pd_type5(dm, lv, cck_mode);
1277 }
1278
phydm_read_cckpd_para_type5(void * dm_void)1279 void phydm_read_cckpd_para_type5(void *dm_void)
1280 {
1281 struct dm_struct *dm = (struct dm_struct *)dm_void;
1282 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
1283 u8 bw = 0; /*r_RX_RF_BW*/
1284 u8 n_rx = 0;
1285 u8 curr_cck_pd_t[2][4][2];
1286 u32 reg0 = 0;
1287 u32 reg1 = 0;
1288 u32 reg2 = 0;
1289 u32 reg3 = 0;
1290
1291 bw = (u8)odm_get_bb_reg(dm, R_0x9b0, 0xc);
1292
1293 reg0 = odm_get_bb_reg(dm, R_0x1a30, MASKDWORD);
1294 reg1 = odm_get_bb_reg(dm, R_0x1a34, MASKDWORD);
1295 reg2 = odm_get_bb_reg(dm, R_0x1a20, MASKDWORD);
1296 reg3 = odm_get_bb_reg(dm, R_0x1a24, MASKDWORD);
1297 curr_cck_pd_t[0][0][0] = (u8)(reg0 & 0x0000001f);
1298 curr_cck_pd_t[1][0][0] = (u8)(reg1 & 0x0000001f);
1299 curr_cck_pd_t[0][0][1] = (u8)(reg2 & 0x0000001f);
1300 curr_cck_pd_t[1][0][1] = (u8)(reg3 & 0x0000001f);
1301 n_rx = 1;
1302 #if (defined(PHYDM_COMPILE_ABOVE_2SS))
1303 if (dm->support_ic_type & PHYDM_IC_ABOVE_2SS) {
1304 curr_cck_pd_t[0][1][0] = (u8)((reg0 & 0x000003E0) >> 5);
1305 curr_cck_pd_t[1][1][0] = (u8)((reg1 & 0x000003E0) >> 5);
1306 curr_cck_pd_t[0][1][1] = (u8)((reg2 & 0x000003E0) >> 5);
1307 curr_cck_pd_t[1][1][1] = (u8)((reg3 & 0x000003E0) >> 5);
1308 n_rx = 2;
1309 }
1310 #endif
1311 #if (defined(PHYDM_COMPILE_ABOVE_3SS))
1312 if (dm->support_ic_type & PHYDM_IC_ABOVE_3SS) {
1313 curr_cck_pd_t[0][2][0] = (u8)((reg0 & 0x00007C00) >> 10);
1314 curr_cck_pd_t[1][2][0] = (u8)((reg1 & 0x00007C00) >> 10);
1315 curr_cck_pd_t[0][2][1] = (u8)((reg2 & 0x00007C00) >> 10);
1316 curr_cck_pd_t[1][2][1] = (u8)((reg3 & 0x00007C00) >> 10);
1317 n_rx = 3;
1318 }
1319 #endif
1320 #if (defined(PHYDM_COMPILE_ABOVE_4SS))
1321 if (dm->support_ic_type & PHYDM_IC_ABOVE_4SS) {
1322 curr_cck_pd_t[0][3][0] = (u8)((reg0 & 0x000F8000) >> 15);
1323 curr_cck_pd_t[1][3][0] = (u8)((reg1 & 0x000F8000) >> 15);
1324 curr_cck_pd_t[0][3][1] = (u8)((reg2 & 0x000F8000) >> 15);
1325 curr_cck_pd_t[1][3][1] = (u8)((reg3 & 0x000F8000) >> 15);
1326 n_rx = 4;
1327 }
1328 #endif
1329
1330 PHYDM_DBG(dm, DBG_CCKPD, "bw=%dM, Nrx=%d\n", 20 << bw, n_rx);
1331 PHYDM_DBG(dm, DBG_CCKPD, "lv=%d, readback CS_th=0x%x, PD th=0x%x\n",
1332 cckpd_t->cck_pd_lv,
1333 curr_cck_pd_t[bw][n_rx - 1][1],
1334 curr_cck_pd_t[bw][n_rx - 1][0]);
1335 }
1336
phydm_cckpd_type5(void * dm_void)1337 void phydm_cckpd_type5(void *dm_void)
1338 {
1339 struct dm_struct *dm = (struct dm_struct *)dm_void;
1340 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
1341 u8 igi = dm->dm_dig_table.cur_ig_value;
1342 enum cckpd_lv lv = 0;
1343 boolean is_update = true;
1344
1345 PHYDM_DBG(dm, DBG_CCKPD, "%s ======>\n", __func__);
1346
1347 if (dm->is_linked) {
1348 PHYDM_DBG(dm, DBG_CCKPD, "Linked!!!\n");
1349 if (dm->rssi_min > 40) {
1350 lv = CCK_PD_LV_4;
1351 PHYDM_DBG(dm, DBG_CCKPD, "Order 1\n");
1352 } else if (dm->rssi_min > 32) {
1353 lv = CCK_PD_LV_3;
1354 PHYDM_DBG(dm, DBG_CCKPD, "Order 2\n");
1355 } else if (dm->rssi_min > 24) {
1356 lv = CCK_PD_LV_2;
1357 PHYDM_DBG(dm, DBG_CCKPD, "Order 3\n");
1358 } else {
1359 if (cckpd_t->cck_fa_ma > 1000) {
1360 lv = CCK_PD_LV_1;
1361 PHYDM_DBG(dm, DBG_CCKPD, "Order 4-1\n");
1362 } else if (cckpd_t->cck_fa_ma < 500) {
1363 lv = CCK_PD_LV_0;
1364 PHYDM_DBG(dm, DBG_CCKPD, "Order 4-2\n");
1365 } else {
1366 is_update = false;
1367 PHYDM_DBG(dm, DBG_CCKPD, "Order 4-3\n");
1368 }
1369 }
1370 } else {
1371 PHYDM_DBG(dm, DBG_CCKPD, "UnLinked!!!\n");
1372 if (cckpd_t->cck_fa_ma > 1000) {
1373 lv = CCK_PD_LV_1;
1374 PHYDM_DBG(dm, DBG_CCKPD, "Order 1\n");
1375 } else if (cckpd_t->cck_fa_ma < 500) {
1376 lv = CCK_PD_LV_0;
1377 PHYDM_DBG(dm, DBG_CCKPD, "Order 2\n");
1378 } else {
1379 is_update = false;
1380 PHYDM_DBG(dm, DBG_CCKPD, "Order 3\n");
1381 }
1382 }
1383
1384 if (is_update) {
1385 phydm_set_cck_pd_lv_type5(dm, lv);
1386
1387 PHYDM_DBG(dm, DBG_CCKPD, "setting CS_th = 0x%x, PD th = 0x%x\n",
1388 cckpd_t->cck_pd_table_jgr3[cckpd_t->cck_bw]
1389 [cckpd_t->cck_n_rx - 1][1][lv],
1390 cckpd_t->cck_pd_table_jgr3[cckpd_t->cck_bw]
1391 [cckpd_t->cck_n_rx - 1][0][lv]);
1392 }
1393
1394 phydm_read_cckpd_para_type5(dm);
1395 }
1396
phydm_cck_pd_init_type5(void * dm_void)1397 void phydm_cck_pd_init_type5(void *dm_void)
1398 {
1399 struct dm_struct *dm = (struct dm_struct *)dm_void;
1400 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
1401 u32 reg0 = 0;
1402 u32 reg1 = 0;
1403 u32 reg2 = 0;
1404 u32 reg3 = 0;
1405 u8 pw_step = 0;
1406 u8 cs_step = 0;
1407 u8 cck_bw = 0; /*r_RX_RF_BW*/
1408 u8 cck_n_rx = 0;
1409 u8 val = 0;
1410 u8 i = 0;
1411
1412 PHYDM_DBG(dm, DBG_CCKPD, "[%s]======>\n", __func__);
1413 #if 0
1414 /*@
1415 *cckpd_t[0][0][0][0] = 1a30[4:0] r_PD_lim_RFBW20_1R
1416 *cckpd_t[0][1][0][0] = 1a30[9:5] r_PD_lim_RFBW20_2R
1417 *cckpd_t[0][2][0][0] = 1a30[14:10] r_PD_lim_RFBW20_3R
1418 *cckpd_t[0][3][0][0] = 1a30[19:15] r_PD_lim_RFBW20_4R
1419 *cckpd_t[1][0][0][0] = 1a34[4:0] r_PD_lim_RFBW40_1R
1420 *cckpd_t[1][1][0][0] = 1a34[9:5] r_PD_lim_RFBW40_2R
1421 *cckpd_t[1][2][0][0] = 1a34[14:10] r_PD_lim_RFBW40_3R
1422 *cckpd_t[1][3][0][0] = 1a34[19:15] r_PD_lim_RFBW40_4R
1423 *
1424 *
1425 *cckpd_t[0][0][1][0] = 1a20[4:0] r_CS_ratio_RFBW20_1R
1426 *cckpd_t[0][1][1][0] = 1a20[9:5] r_CS_ratio_RFBW20_2R
1427 *cckpd_t[0][2][1][0] = 1a20[14:10] r_CS_ratio_RFBW20_3R
1428 *cckpd_t[0][3][1][0] = 1a20[19:15] r_CS_ratio_RFBW20_4R
1429 *cckpd_t[1][0][1][0] = 1a24[4:0] r_CS_ratio_RFBW40_1R
1430 *cckpd_t[1][1][1][0] = 1a24[9:5] r_CS_ratio_RFBW40_2R
1431 *cckpd_t[1][2][1][0] = 1a24[14:10] r_CS_ratio_RFBW40_3R
1432 *cckpd_t[1][3][1][0] = 1a24[19:15] r_CS_ratio_RFBW40_4R
1433 */
1434 #endif
1435 /*[Check Nrx]*/
1436 cck_n_rx = 1;
1437
1438 /*[Check BW]*/
1439 val = (u8)odm_get_bb_reg(dm, R_0x9b0, 0xc);
1440 if (val == 0)
1441 cck_bw = CHANNEL_WIDTH_20;
1442 else if (val == 1)
1443 cck_bw = CHANNEL_WIDTH_40;
1444 else
1445 cck_bw = CHANNEL_WIDTH_80;
1446
1447 cckpd_t->cck_bw = cck_bw;
1448 reg0 = odm_get_bb_reg(dm, R_0x1a30, MASKDWORD);
1449 reg1 = odm_get_bb_reg(dm, R_0x1a34, MASKDWORD);
1450 reg2 = odm_get_bb_reg(dm, R_0x1a20, MASKDWORD);
1451 reg3 = odm_get_bb_reg(dm, R_0x1a24, MASKDWORD);
1452
1453 for (i = 0 ; i < CCK_PD_LV_MAX ; i++) {
1454 pw_step = i * 2;
1455 cs_step = i * 2;
1456
1457 #if (RTL8723F_SUPPORT)
1458 if (dm->support_ic_type & ODM_RTL8723F) {
1459 if (i == CCK_PD_LV_1) {
1460 pw_step = 9; /*IGI-19.2:0x11=d'17*/
1461 cs_step = 0;
1462 } else if (i == CCK_PD_LV_2) {
1463 pw_step = 12; /*IGI-15.5:0x14=d'20*/
1464 cs_step = 1;
1465 } else if (i == CCK_PD_LV_3) {
1466 pw_step = 14; /*IGI-14:0x16=d'22*/
1467 cs_step = 1;
1468 } else if (i == CCK_PD_LV_4) {
1469 pw_step = 17; /*IGI-12:0x19=d'25*/
1470 cs_step = 1;
1471 }
1472 }
1473 #endif
1474 val = (u8)(reg0 & 0x0000001F) + pw_step;
1475 PHYDM_DBG(dm, DBG_CCKPD, "lvl %d val = %x\n\n", i, val);
1476 cckpd_t->cck_pd_table_jgr3[0][0][0][i] = val;
1477
1478 val = (u8)(reg1 & 0x0000001F) + pw_step;
1479 cckpd_t->cck_pd_table_jgr3[1][0][0][i] = val;
1480
1481 val = (u8)(reg2 & 0x0000001F) + cs_step;
1482 cckpd_t->cck_pd_table_jgr3[0][0][1][i] = val;
1483
1484 val = (u8)(reg3 & 0x0000001F) + cs_step;
1485 cckpd_t->cck_pd_table_jgr3[1][0][1][i] = val;
1486
1487 #ifdef PHYDM_COMPILE_ABOVE_2SS
1488 if (dm->support_ic_type & PHYDM_IC_ABOVE_2SS) {
1489 val = (u8)((reg0 & 0x000003E0) >> 5) + pw_step;
1490 cckpd_t->cck_pd_table_jgr3[0][1][0][i] = val;
1491
1492 val = (u8)((reg1 & 0x000003E0) >> 5) + pw_step;
1493 cckpd_t->cck_pd_table_jgr3[1][1][0][i] = val;
1494
1495 val = (u8)((reg2 & 0x000003E0) >> 5) + cs_step;
1496 cckpd_t->cck_pd_table_jgr3[0][1][1][i] = val;
1497
1498 val = (u8)((reg3 & 0x000003E0) >> 5) + cs_step;
1499 cckpd_t->cck_pd_table_jgr3[1][1][1][i] = val;
1500
1501 cck_n_rx = 2;
1502 }
1503 #endif
1504 #ifdef PHYDM_COMPILE_ABOVE_3SS
1505 if (dm->support_ic_type & PHYDM_IC_ABOVE_3SS) {
1506 val = (u8)((reg0 & 0x00007C00) >> 10) + pw_step;
1507 cckpd_t->cck_pd_table_jgr3[0][2][0][i] = val;
1508
1509 val = (u8)((reg1 & 0x00007C00) >> 10) + pw_step;
1510 cckpd_t->cck_pd_table_jgr3[1][2][0][i] = val;
1511
1512 val = (u8)((reg2 & 0x00007C00) >> 10) + cs_step;
1513 cckpd_t->cck_pd_table_jgr3[0][2][1][i] = val;
1514
1515 val = (u8)((reg3 & 0x00007C00) >> 10) + cs_step;
1516 cckpd_t->cck_pd_table_jgr3[1][2][1][i] = val;
1517
1518 cck_n_rx = 3;
1519 }
1520 #endif
1521
1522 #ifdef PHYDM_COMPILE_ABOVE_4SS
1523 if (dm->support_ic_type & PHYDM_IC_ABOVE_4SS) {
1524 val = (u8)((reg0 & 0x000F8000) >> 15) + pw_step;
1525 cckpd_t->cck_pd_table_jgr3[0][3][0][i] = val;
1526
1527 val = (u8)((reg1 & 0x000F8000) >> 15) + pw_step;
1528 cckpd_t->cck_pd_table_jgr3[1][3][0][i] = val;
1529
1530 val = (u8)((reg2 & 0x000F8000) >> 15) + cs_step;
1531 cckpd_t->cck_pd_table_jgr3[0][3][1][i] = val;
1532
1533 val = (u8)((reg3 & 0x000F8000) >> 15) + cs_step;
1534 cckpd_t->cck_pd_table_jgr3[1][3][1][i] = val;
1535
1536 cck_n_rx = 4;
1537 }
1538 #endif
1539 }
1540 cckpd_t->cck_n_rx = cck_n_rx;
1541 }
1542
1543
1544
1545
1546 #endif /*#ifdef PHYDM_COMPILE_CCKPD_TYPE5*/
1547
1548
1549
1550
phydm_set_cckpd_val(void * dm_void,u32 * val_buf,u8 val_len)1551 void phydm_set_cckpd_val(void *dm_void, u32 *val_buf, u8 val_len)
1552 {
1553 struct dm_struct *dm = (struct dm_struct *)dm_void;
1554 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
1555 enum cckpd_lv lv;
1556
1557 if (val_len != 1) {
1558 PHYDM_DBG(dm, ODM_COMP_API, "[Error][CCKPD]Need val_len=1\n");
1559 return;
1560 }
1561
1562 lv = (enum cckpd_lv)val_buf[0];
1563
1564 if (lv > CCK_PD_LV_4) {
1565 pr_debug("[%s] warning! lv=%d\n", __func__, lv);
1566 return;
1567 }
1568
1569 switch (cckpd_t->cckpd_hw_type) {
1570 #ifdef PHYDM_COMPILE_CCKPD_TYPE1
1571 case 1:
1572 phydm_set_cckpd_lv_type1(dm, lv);
1573 break;
1574 #endif
1575 #ifdef PHYDM_COMPILE_CCKPD_TYPE2
1576 case 2:
1577 phydm_set_cckpd_lv_type2(dm, lv);
1578 break;
1579 #endif
1580 #ifdef PHYDM_COMPILE_CCKPD_TYPE3
1581 case 3:
1582 phydm_set_cckpd_lv_type3(dm, lv);
1583 break;
1584 #endif
1585 #ifdef PHYDM_COMPILE_CCKPD_TYPE4
1586 case 4:
1587 phydm_set_cck_pd_lv_type4(dm, lv);
1588 break;
1589 #endif
1590 #ifdef PHYDM_COMPILE_CCKPD_TYPE5
1591 case 5:
1592 phydm_set_cck_pd_lv_type5(dm, lv);
1593 break;
1594 #endif
1595 default:
1596 pr_debug("[%s]warning\n", __func__);
1597 break;
1598 }
1599 }
1600
1601 boolean
phydm_stop_cck_pd_th(void * dm_void)1602 phydm_stop_cck_pd_th(void *dm_void)
1603 {
1604 struct dm_struct *dm = (struct dm_struct *)dm_void;
1605
1606 if (!(dm->support_ability & ODM_BB_FA_CNT)) {
1607 PHYDM_DBG(dm, DBG_CCKPD, "Not Support:ODM_BB_FA_CNT disable\n");
1608 return true;
1609 }
1610
1611 if (!(dm->support_ability & ODM_BB_CCK_PD)) {
1612 PHYDM_DBG(dm, DBG_CCKPD, "Not Support:ODM_BB_CCK_PD disable\n");
1613 return true;
1614 }
1615
1616 if (dm->pause_ability & ODM_BB_CCK_PD) {
1617 PHYDM_DBG(dm, DBG_CCKPD, "Return: Pause CCKPD in LV=%d\n",
1618 dm->pause_lv_table.lv_cckpd);
1619 return true;
1620 }
1621
1622 if (dm->is_linked && (*dm->channel > 36)) {
1623 PHYDM_DBG(dm, DBG_CCKPD, "Return: 5G CH=%d\n", *dm->channel);
1624 return true;
1625 }
1626 return false;
1627 }
1628
phydm_cck_pd_th(void * dm_void)1629 void phydm_cck_pd_th(void *dm_void)
1630 {
1631 struct dm_struct *dm = (struct dm_struct *)dm_void;
1632 struct phydm_fa_struct *fa_t = &dm->false_alm_cnt;
1633 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
1634 u32 cck_fa = fa_t->cnt_cck_fail;
1635 #ifdef PHYDM_TDMA_DIG_SUPPORT
1636 struct phydm_fa_acc_struct *fa_acc_t = &dm->false_alm_cnt_acc;
1637 #endif
1638
1639 PHYDM_DBG(dm, DBG_CCKPD, "[%s] ======>\n", __func__);
1640
1641 if (phydm_stop_cck_pd_th(dm))
1642 return;
1643
1644 #ifdef PHYDM_TDMA_DIG_SUPPORT
1645 if (dm->original_dig_restore)
1646 cck_fa = fa_t->cnt_cck_fail;
1647 else
1648 cck_fa = fa_acc_t->cnt_cck_fail_1sec;
1649 #endif
1650
1651 if (cckpd_t->cck_fa_ma == CCK_FA_MA_RESET)
1652 cckpd_t->cck_fa_ma = cck_fa;
1653 else
1654 cckpd_t->cck_fa_ma = (cckpd_t->cck_fa_ma * 3 + cck_fa) >> 2;
1655
1656 PHYDM_DBG(dm, DBG_CCKPD,
1657 "IGI=0x%x, rssi_min=%d, cck_fa=%d, cck_fa_ma=%d\n",
1658 dm->dm_dig_table.cur_ig_value, dm->rssi_min,
1659 cck_fa, cckpd_t->cck_fa_ma);
1660
1661 switch (cckpd_t->cckpd_hw_type) {
1662 #ifdef PHYDM_COMPILE_CCKPD_TYPE1
1663 case 1:
1664 phydm_cckpd_type1(dm);
1665 break;
1666 #endif
1667 #ifdef PHYDM_COMPILE_CCKPD_TYPE2
1668 case 2:
1669 phydm_cckpd_type2(dm);
1670 break;
1671 #endif
1672 #ifdef PHYDM_COMPILE_CCKPD_TYPE3
1673 case 3:
1674 phydm_cckpd_type3(dm);
1675 break;
1676 #endif
1677 #ifdef PHYDM_COMPILE_CCKPD_TYPE4
1678 case 4:
1679 #ifdef PHYDM_DCC_ENHANCE
1680 if (dm->dm_dcc_info.dcc_en)
1681 phydm_cckpd_type4_dcc(dm);
1682 else
1683 #endif
1684 phydm_cckpd_type4(dm);
1685 break;
1686 #endif
1687 #ifdef PHYDM_COMPILE_CCKPD_TYPE5
1688 case 5:
1689 phydm_cckpd_type5(dm);
1690 break;
1691 #endif
1692 default:
1693 pr_debug("[%s]warning\n", __func__);
1694 break;
1695 }
1696 }
1697
phydm_cck_pd_init(void * dm_void)1698 void phydm_cck_pd_init(void *dm_void)
1699 {
1700 struct dm_struct *dm = (struct dm_struct *)dm_void;
1701 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
1702
1703 if (*dm->mp_mode)
1704 return;
1705
1706 if (dm->support_ic_type & CCK_PD_IC_TYPE1)
1707 cckpd_t->cckpd_hw_type = 1;
1708 else if (dm->support_ic_type & CCK_PD_IC_TYPE2)
1709 cckpd_t->cckpd_hw_type = 2;
1710 else if (dm->support_ic_type & CCK_PD_IC_TYPE3)
1711 cckpd_t->cckpd_hw_type = 3;
1712 else if (dm->support_ic_type & CCK_PD_IC_TYPE4)
1713 cckpd_t->cckpd_hw_type = 4;
1714
1715 if (dm->support_ic_type & CCK_PD_IC_TYPE5)
1716 cckpd_t->cckpd_hw_type = 5;
1717
1718 PHYDM_DBG(dm, DBG_CCKPD, "[%s] cckpd_hw_type=%d\n",
1719 __func__, cckpd_t->cckpd_hw_type);
1720
1721 cckpd_t->cck_pd_lv = CCK_PD_LV_INIT;
1722 cckpd_t->cck_n_rx = 0xff;
1723 cckpd_t->cck_bw = CHANNEL_WIDTH_MAX;
1724 cckpd_t->cck_fa_th[1] = 400;
1725 cckpd_t->cck_fa_th[0] = 200;
1726
1727 switch (cckpd_t->cckpd_hw_type) {
1728 #ifdef PHYDM_COMPILE_CCKPD_TYPE1
1729 case 1:
1730 phydm_set_cckpd_lv_type1(dm, CCK_PD_LV_1);
1731 break;
1732 #endif
1733 #ifdef PHYDM_COMPILE_CCKPD_TYPE2
1734 case 2:
1735 cckpd_t->aaa_default = odm_read_1byte(dm, 0xaaa) & 0x1f;
1736 phydm_set_cckpd_lv_type2(dm, CCK_PD_LV_1);
1737 break;
1738 #endif
1739 #ifdef PHYDM_COMPILE_CCKPD_TYPE3
1740 case 3:
1741 phydm_cck_pd_init_type3(dm);
1742 phydm_set_cckpd_lv_type3(dm, CCK_PD_LV_1);
1743 break;
1744 #endif
1745 #ifdef PHYDM_COMPILE_CCKPD_TYPE4
1746 case 4:
1747 phydm_cck_pd_init_type4(dm);
1748 phydm_invalid_cckpd_type4(dm);
1749 phydm_set_cck_pd_lv_type4(dm, CCK_PD_LV_1);
1750 break;
1751 #endif
1752 #ifdef PHYDM_COMPILE_CCKPD_TYPE5
1753 case 5:
1754 phydm_cck_pd_init_type5(dm);
1755 break;
1756 #endif
1757 default:
1758 pr_debug("[%s]warning\n", __func__);
1759 break;
1760 }
1761 }
1762
1763 #ifdef PHYDM_DCC_ENHANCE
1764
phydm_cckpd_type4_dcc(void * dm_void)1765 void phydm_cckpd_type4_dcc(void *dm_void)
1766 {
1767 struct dm_struct *dm = (struct dm_struct *)dm_void;
1768 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
1769 enum cckpd_lv lv_curr = cckpd_t->cck_pd_lv;
1770 enum phydm_cck_pd_trend trend = CCKPD_STABLE;
1771 u8 th_ofst = 0;
1772 u16 lv_up_th, lv_down_th;
1773
1774 PHYDM_DBG(dm, DBG_CCKPD, "%s ======>\n", __func__);
1775
1776 if (!dm->is_linked)
1777 th_ofst = 1;
1778
1779 lv_up_th = (cckpd_t->cck_fa_th[1]) << th_ofst;
1780 lv_down_th = (cckpd_t->cck_fa_th[0]) << th_ofst;
1781
1782 PHYDM_DBG(dm, DBG_CCKPD, "th{Up, Down}: {%d, %d}\n",
1783 lv_up_th, lv_down_th);
1784
1785 if (cckpd_t->cck_fa_ma > lv_up_th) {
1786 if (lv_curr <= CCK_PD_LV_3) {
1787 lv_curr++;
1788 trend = CCKPD_INCREASING;
1789 } else {
1790 lv_curr = CCK_PD_LV_4;
1791 }
1792 } else if (cckpd_t->cck_fa_ma < lv_down_th) {
1793 if (lv_curr >= CCK_PD_LV_1) {
1794 lv_curr--;
1795 trend = CCKPD_DECREASING;
1796 } else {
1797 lv_curr = CCK_PD_LV_0;
1798 }
1799 }
1800
1801 PHYDM_DBG(dm, DBG_CCKPD, "lv: %d->%d\n", cckpd_t->cck_pd_lv, lv_curr);
1802 #if 1
1803 if (trend != CCKPD_STABLE) {
1804 phydm_set_cck_pd_lv_type4(dm, lv_curr);
1805
1806 PHYDM_DBG(dm, DBG_CCKPD, "setting CS_th = 0x%x, PD th = 0x%x\n",
1807 cckpd_t->cckpd_jgr3[cckpd_t->cck_bw]
1808 [cckpd_t->cck_n_rx - 1][1][lv_curr],
1809 cckpd_t->cckpd_jgr3[cckpd_t->cck_bw]
1810 [cckpd_t->cck_n_rx - 1][0][lv_curr]);
1811 }
1812 phydm_read_cckpd_para_type4(dm);
1813 #endif
1814 }
1815
phydm_do_cckpd(void * dm_void)1816 boolean phydm_do_cckpd(void *dm_void)
1817 {
1818 struct dm_struct *dm = (struct dm_struct *)dm_void;
1819 struct phydm_dig_struct *dig_t = &dm->dm_dig_table;
1820
1821 if (dig_t->igi_trend == DIG_INCREASING)
1822 return false;
1823
1824 return true;
1825 }
1826
phydm_dig_cckpd_coex(void * dm_void)1827 void phydm_dig_cckpd_coex(void *dm_void)
1828 {
1829 struct dm_struct *dm = (struct dm_struct *)dm_void;
1830 struct phydm_dcc_struct *dcc = &dm->dm_dcc_info;
1831
1832 if (*dm->channel > 36) {
1833 phydm_dig(dm);
1834 return;
1835 } else if (!dcc->dcc_en) {
1836 phydm_dig(dm);
1837 phydm_cck_pd_th(dm);
1838 return;
1839 }
1840
1841 dcc->dig_execute_cnt++;
1842 PHYDM_DBG(dm, DBG_CCKPD, "DCC_cnt: %d\n", dcc->dig_execute_cnt);
1843
1844 if (dcc->dig_execute_cnt % dcc->dcc_ratio) {
1845 PHYDM_DBG(dm, DBG_CCKPD, "DCC: DIG\n");
1846 phydm_dig(dm);
1847 } else {
1848 if (phydm_do_cckpd(dm)) {
1849 PHYDM_DBG(dm, DBG_CCKPD, "DCC: CCKPD\n");
1850 dcc->dcc_mode = DCC_CCK_PD;
1851 phydm_cck_pd_th(dm);
1852 } else {
1853 PHYDM_DBG(dm, DBG_CCKPD, "DCC: Boost_DIG\n");
1854 dcc->dcc_mode = DCC_DIG;
1855 phydm_dig(dm);
1856 }
1857 }
1858 }
1859
phydm_dig_cckpd_coex_init(void * dm_void)1860 void phydm_dig_cckpd_coex_init(void *dm_void)
1861 {
1862 struct dm_struct *dm = (struct dm_struct *)dm_void;
1863 struct phydm_dig_struct *dig_t = &dm->dm_dig_table;
1864 struct phydm_dcc_struct *dcc = &dm->dm_dcc_info;
1865
1866 dcc->dcc_mode = DCC_DIG;
1867 dcc->dcc_en = false;
1868 dcc->dig_execute_cnt = 0;
1869 dcc->dcc_ratio = 2;
1870 }
1871
phydm_dig_cckpd_coex_dbg(void * dm_void,char input[][16],u32 * _used,char * output,u32 * _out_len)1872 void phydm_dig_cckpd_coex_dbg(void *dm_void, char input[][16], u32 *_used,
1873 char *output, u32 *_out_len)
1874 {
1875 struct dm_struct *dm = (struct dm_struct *)dm_void;
1876 struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table;
1877 struct phydm_dcc_struct *dcc = &dm->dm_dcc_info;
1878 char help[] = "-h";
1879 u32 var[10] = {0};
1880 u32 used = *_used;
1881 u32 out_len = *_out_len;
1882 u8 i = 0;
1883
1884 for (i = 0; i < 3; i++) {
1885 if (input[i + 1])
1886 PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var[i]);
1887 }
1888
1889 if ((strcmp(input[1], help) == 0)) {
1890 PDM_SNPF(out_len, used, output + used, out_len - used,
1891 "Enable: en {0/1}\n");
1892 PDM_SNPF(out_len, used, output + used, out_len - used,
1893 "DCC_ratio: ratio {x}\n");
1894 PDM_SNPF(out_len, used, output + used, out_len - used,
1895 "threshold: th {Down_th} {Up_th}\n");
1896 } else if ((strcmp(input[1], "en") == 0)) {
1897 dcc->dcc_en = (var[1]) ? true : false;
1898 PDM_SNPF(out_len, used, output + used, out_len - used,
1899 "en=%d\n", dcc->dcc_en);
1900 } else if ((strcmp(input[1], "ratio") == 0)) {
1901 dcc->dcc_ratio = (u8)var[1];
1902 PDM_SNPF(out_len, used, output + used, out_len - used,
1903 "Ratio=%d\n", dcc->dcc_ratio);
1904 } else if ((strcmp(input[1], "th") == 0)) {
1905 cckpd_t->cck_fa_th[1] = (u16)var[2];
1906 cckpd_t->cck_fa_th[0] = (u16)var[1];
1907 PDM_SNPF(out_len, used, output + used, out_len - used,
1908 "th{Down, Up}: {%d, %d}\n",
1909 cckpd_t->cck_fa_th[0], cckpd_t->cck_fa_th[1]);
1910 }
1911
1912 *_used = used;
1913 *_out_len = out_len;
1914 }
1915
1916 #endif
1917 #endif /*#ifdef PHYDM_SUPPORT_CCKPD*/
1918
1919