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 #include "mp_precomp.h"
30 #include "phydm_precomp.h"
31
32 #ifdef CONFIG_PATH_DIVERSITY
33 #if RTL8814A_SUPPORT
phydm_dtp_fix_tx_path(void * dm_void,u8 path)34 void phydm_dtp_fix_tx_path(
35 void *dm_void,
36 u8 path)
37 {
38 struct dm_struct *dm = (struct dm_struct *)dm_void;
39 struct _ODM_PATH_DIVERSITY_ *p_div = &dm->dm_path_div;
40 u8 i, num_enable_path = 0;
41
42 if (path == p_div->pre_tx_path)
43 return;
44 else
45 p_div->pre_tx_path = path;
46
47 odm_set_bb_reg(dm, R_0x93c, BIT(18) | BIT(19), 3);
48
49 for (i = 0; i < 4; i++) {
50 if (path & BIT(i))
51 num_enable_path++;
52 }
53 PHYDM_DBG(dm, DBG_PATH_DIV, " number of turn-on path : (( %d ))\n",
54 num_enable_path);
55
56 if (num_enable_path == 1) {
57 odm_set_bb_reg(dm, R_0x93c, 0xf00000, path);
58
59 if (path == BB_PATH_A) { /* @1-1 */
60 PHYDM_DBG(dm, DBG_PATH_DIV, " Turn on path (( A ))\n");
61 odm_set_bb_reg(dm, R_0x93c, BIT(25) | BIT(24), 0);
62 } else if (path == BB_PATH_B) { /* @1-2 */
63 PHYDM_DBG(dm, DBG_PATH_DIV, " Turn on path (( B ))\n");
64 odm_set_bb_reg(dm, R_0x93c, BIT(27) | BIT(26), 0);
65 } else if (path == BB_PATH_C) { /* @1-3 */
66 PHYDM_DBG(dm, DBG_PATH_DIV, " Turn on path (( C ))\n");
67 odm_set_bb_reg(dm, R_0x93c, BIT(29) | BIT(28), 0);
68
69 } else if (path == BB_PATH_D) { /* @1-4 */
70 PHYDM_DBG(dm, DBG_PATH_DIV, " Turn on path (( D ))\n");
71 odm_set_bb_reg(dm, R_0x93c, BIT(31) | BIT(30), 0);
72 }
73
74 } else if (num_enable_path == 2) {
75 odm_set_bb_reg(dm, R_0x93c, 0xf00000, path);
76 odm_set_bb_reg(dm, R_0x940, 0xf0, path);
77
78 if (path == (BB_PATH_AB)) { /* @2-1 */
79 PHYDM_DBG(dm, DBG_PATH_DIV,
80 " Turn on path (( A B ))\n");
81 /* set for 1ss */
82 odm_set_bb_reg(dm, R_0x93c, BIT(25) | BIT(24), 0);
83 odm_set_bb_reg(dm, R_0x93c, BIT(27) | BIT(26), 1);
84 /* set for 2ss */
85 odm_set_bb_reg(dm, R_0x940, BIT(9) | BIT(8), 0);
86 odm_set_bb_reg(dm, R_0x940, BIT(11) | BIT(10), 1);
87 } else if (path == BB_PATH_AC) { /* @2-2 */
88 PHYDM_DBG(dm, DBG_PATH_DIV,
89 " Turn on path (( A C ))\n");
90 /* set for 1ss */
91 odm_set_bb_reg(dm, R_0x93c, BIT(25) | BIT(24), 0);
92 odm_set_bb_reg(dm, R_0x93c, BIT(29) | BIT(28), 1);
93 /* set for 2ss */
94 odm_set_bb_reg(dm, R_0x940, BIT(9) | BIT(8), 0);
95 odm_set_bb_reg(dm, R_0x940, BIT(13) | BIT(12), 1);
96 } else if (path == BB_PATH_AD) { /* @2-3 */
97 PHYDM_DBG(dm, DBG_PATH_DIV,
98 " Turn on path (( A D ))\n");
99 /* set for 1ss */
100 odm_set_bb_reg(dm, R_0x93c, BIT(25) | BIT(24), 0);
101 odm_set_bb_reg(dm, R_0x93c, BIT(31) | BIT(30), 1);
102 /* set for 2ss */
103 odm_set_bb_reg(dm, R_0x940, BIT(9) | BIT(8), 0);
104 odm_set_bb_reg(dm, R_0x940, BIT(15) | BIT(14), 1);
105 } else if (path == BB_PATH_BC) { /* @2-4 */
106 PHYDM_DBG(dm, DBG_PATH_DIV,
107 " Turn on path (( B C ))\n");
108 /* set for 1ss */
109 odm_set_bb_reg(dm, R_0x93c, BIT(27) | BIT(26), 0);
110 odm_set_bb_reg(dm, R_0x93c, BIT(29) | BIT(28), 1);
111 /* set for 2ss */
112 odm_set_bb_reg(dm, R_0x940, BIT(11) | BIT(10), 0);
113 odm_set_bb_reg(dm, R_0x940, BIT(13) | BIT(12), 1);
114 } else if (path == BB_PATH_BD) { /* @2-5 */
115 PHYDM_DBG(dm, DBG_PATH_DIV,
116 " Turn on path (( B D ))\n");
117 /* set for 1ss */
118 odm_set_bb_reg(dm, R_0x93c, BIT(27) | BIT(26), 0);
119 odm_set_bb_reg(dm, R_0x93c, BIT(31) | BIT(30), 1);
120 /* set for 2ss */
121 odm_set_bb_reg(dm, R_0x940, BIT(11) | BIT(10), 0);
122 odm_set_bb_reg(dm, R_0x940, BIT(15) | BIT(14), 1);
123 } else if (path == BB_PATH_CD) { /* @2-6 */
124 PHYDM_DBG(dm, DBG_PATH_DIV,
125 " Turn on path (( C D ))\n");
126 /* set for 1ss */
127 odm_set_bb_reg(dm, R_0x93c, BIT(29) | BIT(28), 0);
128 odm_set_bb_reg(dm, R_0x93c, BIT(31) | BIT(30), 1);
129 /* set for 2ss */
130 odm_set_bb_reg(dm, R_0x940, BIT(13) | BIT(12), 0);
131 odm_set_bb_reg(dm, R_0x940, BIT(15) | BIT(14), 1);
132 }
133
134 } else if (num_enable_path == 3) {
135 odm_set_bb_reg(dm, R_0x93c, 0xf00000, path);
136 odm_set_bb_reg(dm, R_0x940, 0xf0, path);
137 odm_set_bb_reg(dm, R_0x940, 0xf0000, path);
138
139 if (path == BB_PATH_ABC) { /* @3-1 */
140 PHYDM_DBG(dm, DBG_PATH_DIV,
141 " Turn on path (( A B C))\n");
142 /* set for 1ss */
143 odm_set_bb_reg(dm, R_0x93c, BIT(25) | BIT(24), 0);
144 odm_set_bb_reg(dm, R_0x93c, BIT(27) | BIT(26), 1);
145 odm_set_bb_reg(dm, R_0x93c, BIT(29) | BIT(28), 2);
146 /* set for 2ss */
147 odm_set_bb_reg(dm, R_0x940, BIT(9) | BIT(8), 0);
148 odm_set_bb_reg(dm, R_0x940, BIT(11) | BIT(10), 1);
149 odm_set_bb_reg(dm, R_0x940, BIT(13) | BIT(12), 2);
150 /* set for 3ss */
151 odm_set_bb_reg(dm, R_0x940, BIT(21) | BIT(20), 0);
152 odm_set_bb_reg(dm, R_0x940, BIT(23) | BIT(22), 1);
153 odm_set_bb_reg(dm, R_0x940, BIT(25) | BIT(24), 2);
154 } else if (path == BB_PATH_ABD) { /* @3-2 */
155 PHYDM_DBG(dm, DBG_PATH_DIV,
156 " Turn on path (( A B D ))\n");
157 /* set for 1ss */
158 odm_set_bb_reg(dm, R_0x93c, BIT(25) | BIT(24), 0);
159 odm_set_bb_reg(dm, R_0x93c, BIT(27) | BIT(26), 1);
160 odm_set_bb_reg(dm, R_0x93c, BIT(31) | BIT(30), 2);
161 /* set for 2ss */
162 odm_set_bb_reg(dm, R_0x940, BIT(9) | BIT(8), 0);
163 odm_set_bb_reg(dm, R_0x940, BIT(11) | BIT(10), 1);
164 odm_set_bb_reg(dm, R_0x940, BIT(15) | BIT(14), 2);
165 /* set for 3ss */
166 odm_set_bb_reg(dm, R_0x940, BIT(21) | BIT(20), 0);
167 odm_set_bb_reg(dm, R_0x940, BIT(23) | BIT(22), 1);
168 odm_set_bb_reg(dm, R_0x940, BIT(27) | BIT(26), 2);
169
170 } else if (path == BB_PATH_ACD) { /* @3-3 */
171 PHYDM_DBG(dm, DBG_PATH_DIV,
172 " Turn on path (( A C D ))\n");
173 /* set for 1ss */
174 odm_set_bb_reg(dm, R_0x93c, BIT(25) | BIT(24), 0);
175 odm_set_bb_reg(dm, R_0x93c, BIT(29) | BIT(28), 1);
176 odm_set_bb_reg(dm, R_0x93c, BIT(31) | BIT(30), 2);
177 /* set for 2ss */
178 odm_set_bb_reg(dm, R_0x940, BIT(9) | BIT(8), 0);
179 odm_set_bb_reg(dm, R_0x940, BIT(13) | BIT(12), 1);
180 odm_set_bb_reg(dm, R_0x940, BIT(15) | BIT(14), 2);
181 /* set for 3ss */
182 odm_set_bb_reg(dm, R_0x940, BIT(21) | BIT(20), 0);
183 odm_set_bb_reg(dm, R_0x940, BIT(25) | BIT(24), 1);
184 odm_set_bb_reg(dm, R_0x940, BIT(27) | BIT(26), 2);
185 } else if (path == BB_PATH_BCD) { /* @3-4 */
186 PHYDM_DBG(dm, DBG_PATH_DIV,
187 " Turn on path (( B C D))\n");
188 /* set for 1ss */
189 odm_set_bb_reg(dm, R_0x93c, BIT(27) | BIT(26), 0);
190 odm_set_bb_reg(dm, R_0x93c, BIT(29) | BIT(28), 1);
191 odm_set_bb_reg(dm, R_0x93c, BIT(31) | BIT(30), 2);
192 /* set for 2ss */
193 odm_set_bb_reg(dm, R_0x940, BIT(11) | BIT(10), 0);
194 odm_set_bb_reg(dm, R_0x940, BIT(13) | BIT(12), 1);
195 odm_set_bb_reg(dm, R_0x940, BIT(15) | BIT(14), 2);
196 /* set for 3ss */
197 odm_set_bb_reg(dm, R_0x940, BIT(23) | BIT(22), 0);
198 odm_set_bb_reg(dm, R_0x940, BIT(25) | BIT(24), 1);
199 odm_set_bb_reg(dm, R_0x940, BIT(27) | BIT(26), 2);
200 }
201 } else if (num_enable_path == 4)
202 PHYDM_DBG(dm, DBG_PATH_DIV, " Turn on path ((A B C D))\n");
203 }
204
phydm_find_default_path(void * dm_void)205 void phydm_find_default_path(
206 void *dm_void)
207 {
208 struct dm_struct *dm = (struct dm_struct *)dm_void;
209 struct _ODM_PATH_DIVERSITY_ *p_div = &dm->dm_path_div;
210 u32 rssi_a = 0, rssi_b = 0, rssi_c = 0, rssi_d = 0, rssi_bcd = 0;
211 u32 rssi_total_a = 0, rssi_total_b = 0;
212 u32 rssi_total_c = 0, rssi_total_d = 0;
213
214 /* @2 Default path Selection By RSSI */
215
216 rssi_a = (p_div->path_a_cnt_all > 0) ?
217 (p_div->path_a_sum_all / p_div->path_a_cnt_all) : 0;
218 rssi_b = (p_div->path_b_cnt_all > 0) ?
219 (p_div->path_b_sum_all / p_div->path_b_cnt_all) : 0;
220 rssi_c = (p_div->path_c_cnt_all > 0) ?
221 (p_div->path_c_sum_all / p_div->path_c_cnt_all) : 0;
222 rssi_d = (p_div->path_d_cnt_all > 0) ?
223 (p_div->path_d_sum_all / p_div->path_d_cnt_all) : 0;
224
225 p_div->path_a_sum_all = 0;
226 p_div->path_a_cnt_all = 0;
227 p_div->path_b_sum_all = 0;
228 p_div->path_b_cnt_all = 0;
229 p_div->path_c_sum_all = 0;
230 p_div->path_c_cnt_all = 0;
231 p_div->path_d_sum_all = 0;
232 p_div->path_d_cnt_all = 0;
233
234 if (p_div->use_path_a_as_default_ant == 1) {
235 rssi_bcd = (rssi_b + rssi_c + rssi_d) / 3;
236
237 if ((rssi_a + ANT_DECT_RSSI_TH) > rssi_bcd) {
238 p_div->is_path_a_exist = true;
239 p_div->default_path = PATH_A;
240 } else {
241 p_div->is_path_a_exist = false;
242 }
243 } else {
244 if (rssi_a >= rssi_b &&
245 rssi_a >= rssi_c &&
246 rssi_a >= rssi_d)
247 p_div->default_path = PATH_A;
248 else if ((rssi_b >= rssi_c) && (rssi_b >= rssi_d))
249 p_div->default_path = PATH_B;
250 else if (rssi_c >= rssi_d)
251 p_div->default_path = PATH_C;
252 else
253 p_div->default_path = PATH_D;
254 }
255 }
256
phydm_candidate_dtp_update(void * dm_void)257 void phydm_candidate_dtp_update(
258 void *dm_void)
259 {
260 struct dm_struct *dm = (struct dm_struct *)dm_void;
261 struct _ODM_PATH_DIVERSITY_ *p_div = &dm->dm_path_div;
262
263 p_div->num_candidate = 3;
264
265 if (p_div->use_path_a_as_default_ant == 1) {
266 if (p_div->num_tx_path == 3) {
267 if (p_div->is_path_a_exist) {
268 p_div->ant_candidate_1 = BB_PATH_ABC;
269 p_div->ant_candidate_2 = BB_PATH_ABD;
270 p_div->ant_candidate_3 = BB_PATH_ACD;
271 } else { /* use path BCD */
272 p_div->num_candidate = 1;
273 phydm_dtp_fix_tx_path(dm, BB_PATH_BCD);
274 return;
275 }
276 } else if (p_div->num_tx_path == 2) {
277 if (p_div->is_path_a_exist) {
278 p_div->ant_candidate_1 = BB_PATH_AB;
279 p_div->ant_candidate_2 = BB_PATH_AC;
280 p_div->ant_candidate_3 = BB_PATH_AD;
281 } else {
282 p_div->ant_candidate_1 = BB_PATH_BC;
283 p_div->ant_candidate_2 = BB_PATH_BD;
284 p_div->ant_candidate_3 = BB_PATH_CD;
285 }
286 }
287 } else {
288 /* @2 3 TX mode */
289 if (p_div->num_tx_path == 3) { /* @choose 3 ant form 4 */
290 if (p_div->default_path == PATH_A) {
291 /* @choose 2 ant form 3 */
292 p_div->ant_candidate_1 = BB_PATH_ABC;
293 p_div->ant_candidate_2 = BB_PATH_ABD;
294 p_div->ant_candidate_3 = BB_PATH_ACD;
295 } else if (p_div->default_path == PATH_B) {
296 p_div->ant_candidate_1 = BB_PATH_ABC;
297 p_div->ant_candidate_2 = BB_PATH_ABD;
298 p_div->ant_candidate_3 = BB_PATH_BCD;
299 } else if (p_div->default_path == PATH_C) {
300 p_div->ant_candidate_1 = BB_PATH_ABC;
301 p_div->ant_candidate_2 = BB_PATH_ACD;
302 p_div->ant_candidate_3 = BB_PATH_BCD;
303 } else if (p_div->default_path == PATH_D) {
304 p_div->ant_candidate_1 = BB_PATH_ABD;
305 p_div->ant_candidate_2 = BB_PATH_ACD;
306 p_div->ant_candidate_3 = BB_PATH_BCD;
307 }
308 }
309
310 /* @2 2 TX mode */
311 else if (p_div->num_tx_path == 2) { /* @choose 2 ant form 4 */
312 if (p_div->default_path == PATH_A) {
313 /* @choose 2 ant form 3 */
314 p_div->ant_candidate_1 = BB_PATH_AB;
315 p_div->ant_candidate_2 = BB_PATH_AC;
316 p_div->ant_candidate_3 = BB_PATH_AD;
317 } else if (p_div->default_path == PATH_B) {
318 p_div->ant_candidate_1 = BB_PATH_AB;
319 p_div->ant_candidate_2 = BB_PATH_BC;
320 p_div->ant_candidate_3 = BB_PATH_BD;
321 } else if (p_div->default_path == PATH_C) {
322 p_div->ant_candidate_1 = BB_PATH_AC;
323 p_div->ant_candidate_2 = BB_PATH_BC;
324 p_div->ant_candidate_3 = BB_PATH_CD;
325 } else if (p_div->default_path == PATH_D) {
326 p_div->ant_candidate_1 = BB_PATH_AD;
327 p_div->ant_candidate_2 = BB_PATH_BD;
328 p_div->ant_candidate_3 = BB_PATH_CD;
329 }
330 }
331 }
332 }
333
phydm_dynamic_tx_path(void * dm_void)334 void phydm_dynamic_tx_path(
335 void *dm_void)
336 {
337 struct dm_struct *dm = (struct dm_struct *)dm_void;
338 struct _ODM_PATH_DIVERSITY_ *p_div = &dm->dm_path_div;
339
340 struct sta_info *entry;
341 u32 i;
342 u8 num_client = 0;
343 u8 h2c_parameter[6] = {0};
344
345 if (!dm->is_linked) { /* @is_linked==False */
346 PHYDM_DBG(dm, DBG_PATH_DIV, "DTP_8814 [No Link!!!]\n");
347
348 if (p_div->is_become_linked) {
349 PHYDM_DBG(dm, DBG_PATH_DIV, "[Be disconnected]---->\n");
350 p_div->is_become_linked = dm->is_linked;
351 }
352 return;
353 } else {
354 if (!p_div->is_become_linked) {
355 PHYDM_DBG(dm, DBG_PATH_DIV, " [Be Linked !!!]----->\n");
356 p_div->is_become_linked = dm->is_linked;
357 }
358 }
359
360 /* @2 [period CTRL] */
361 if (p_div->dtp_period >= 2) {
362 p_div->dtp_period = 0;
363 } else {
364 p_div->dtp_period++;
365 return;
366 }
367
368 /* @2 [Fix path] */
369 if (dm->path_select != PHYDM_AUTO_PATH)
370 return;
371
372 /* @2 [Check Bfer] */
373 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
374 #ifdef PHYDM_BEAMFORMING_SUPPORT
375 {
376 enum beamforming_cap beamform_cap = (dm->beamforming_info.beamform_cap);
377
378 if (beamform_cap & BEAMFORMER_CAP) { /* @BFmer On && Div On->Div Off */
379 if (p_div->fix_path_bfer == 0) {
380 PHYDM_DBG(dm, DBG_PATH_DIV,
381 "[ PathDiv : OFF ] BFmer ==1\n");
382 p_div->fix_path_bfer = 1;
383 }
384 return;
385 } else { /* @BFmer Off && Div Off->Div On */
386 if (p_div->fix_path_bfer == 1) {
387 PHYDM_DBG(dm, DBG_PATH_DIV,
388 "[ PathDiv : ON ] BFmer ==0\n");
389 p_div->fix_path_bfer = 0;
390 }
391 }
392 }
393 #endif
394 #endif
395
396 if (p_div->use_path_a_as_default_ant == 1) {
397 phydm_find_default_path(dm);
398 phydm_candidate_dtp_update(dm);
399 } else {
400 if (p_div->phydm_dtp_state == PHYDM_DTP_INIT) {
401 phydm_find_default_path(dm);
402 phydm_candidate_dtp_update(dm);
403 p_div->phydm_dtp_state = PHYDM_DTP_RUNNING_1;
404 }
405
406 else if (p_div->phydm_dtp_state == PHYDM_DTP_RUNNING_1) {
407 p_div->dtp_check_patha_counter++;
408
409 if (p_div->dtp_check_patha_counter >=
410 NUM_RESET_DTP_PERIOD) {
411 p_div->dtp_check_patha_counter = 0;
412 p_div->phydm_dtp_state = PHYDM_DTP_INIT;
413 }
414 #if 0
415 /* @2 Search space update */
416 else {
417 /* @1. find the worst candidate */
418
419
420 /* @2. repalce the worst candidate */
421 }
422 #endif
423 }
424 }
425
426 /* @2 Dynamic path Selection H2C */
427
428 if (p_div->num_candidate == 1) {
429 return;
430 } else {
431 h2c_parameter[0] = p_div->num_candidate;
432 h2c_parameter[1] = p_div->num_tx_path;
433 h2c_parameter[2] = p_div->ant_candidate_1;
434 h2c_parameter[3] = p_div->ant_candidate_2;
435 h2c_parameter[4] = p_div->ant_candidate_3;
436
437 odm_fill_h2c_cmd(dm, PHYDM_H2C_DYNAMIC_TX_PATH, 6, h2c_parameter);
438 }
439 }
440
phydm_dynamic_tx_path_init(void * dm_void)441 void phydm_dynamic_tx_path_init(
442 void *dm_void)
443 {
444 struct dm_struct *dm = (struct dm_struct *)dm_void;
445 struct _ODM_PATH_DIVERSITY_ *p_div = &dm->dm_path_div;
446 void *adapter = dm->adapter;
447 u8 search_space_2[NUM_CHOOSE2_FROM4] = {BB_PATH_AB, BB_PATH_AC, BB_PATH_AD, BB_PATH_BC, BB_PATH_BD, BB_PATH_CD};
448 u8 search_space_3[NUM_CHOOSE3_FROM4] = {BB_PATH_BCD, BB_PATH_ACD, BB_PATH_ABD, BB_PATH_ABC};
449
450 #if ((DM_ODM_SUPPORT_TYPE == ODM_WIN) && USB_SWITCH_SUPPORT)
451 p_div->is_u3_mode = (*dm->hub_usb_mode == 2) ? 1 : 0;
452 PHYDM_DBG(dm, DBG_PATH_DIV, "[WIN USB] is_u3_mode = (( %d ))\n",
453 p_div->is_u3_mode);
454 #else
455 p_div->is_u3_mode = 1;
456 #endif
457 PHYDM_DBG(dm, DBG_PATH_DIV, "Dynamic TX path Init 8814\n");
458
459 memcpy(&p_div->search_space_2[0], &search_space_2[0],
460 NUM_CHOOSE2_FROM4);
461 memcpy(&p_div->search_space_3[0], &search_space_3[0],
462 NUM_CHOOSE3_FROM4);
463
464 p_div->use_path_a_as_default_ant = 1;
465 p_div->phydm_dtp_state = PHYDM_DTP_INIT;
466 dm->path_select = PHYDM_AUTO_PATH;
467 p_div->phydm_path_div_type = PHYDM_4R_PATH_DIV;
468
469 if (p_div->is_u3_mode) {
470 p_div->num_tx_path = 3;
471 phydm_dtp_fix_tx_path(dm, BB_PATH_BCD); /* @3TX Set Init TX path*/
472
473 } else {
474 p_div->num_tx_path = 2;
475 phydm_dtp_fix_tx_path(dm, BB_PATH_BC); /* @2TX // Set Init TX path*/
476 }
477 }
478
phydm_process_rssi_for_path_div_8814a(void * dm_void,void * phy_info_void,void * pkt_info_void)479 void phydm_process_rssi_for_path_div_8814a(void *dm_void, void *phy_info_void,
480 void *pkt_info_void)
481 {
482 struct dm_struct *dm = (struct dm_struct *)dm_void;
483 struct phydm_phyinfo_struct *phy_info = NULL;
484 struct phydm_perpkt_info_struct *pktinfo = NULL;
485 struct _ODM_PATH_DIVERSITY_ *p_div = &dm->dm_path_div;
486
487 phy_info = (struct phydm_phyinfo_struct *)phy_info_void;
488 pktinfo = (struct phydm_perpkt_info_struct *)pkt_info_void;
489
490 if (!(pktinfo->is_packet_to_self || pktinfo->is_packet_match_bssid))
491 return;
492
493 if (pktinfo->data_rate <= ODM_RATE11M)
494 return;
495
496 if (p_div->phydm_path_div_type == PHYDM_4R_PATH_DIV) {
497 p_div->path_a_sum_all += phy_info->rx_mimo_signal_strength[0];
498 p_div->path_a_cnt_all++;
499
500 p_div->path_b_sum_all += phy_info->rx_mimo_signal_strength[1];
501 p_div->path_b_cnt_all++;
502
503 p_div->path_c_sum_all += phy_info->rx_mimo_signal_strength[2];
504 p_div->path_c_cnt_all++;
505
506 p_div->path_d_sum_all += phy_info->rx_mimo_signal_strength[3];
507 p_div->path_d_cnt_all++;
508 }
509 }
510
phydm_pathdiv_debug_8814a(void * dm_void,char input[][16],u32 * _used,char * output,u32 * _out_len)511 void phydm_pathdiv_debug_8814a(void *dm_void, char input[][16], u32 *_used,
512 char *output, u32 *_out_len)
513 {
514 struct dm_struct *dm = (struct dm_struct *)dm_void;
515 struct _ODM_PATH_DIVERSITY_ *p_div = &dm->dm_path_div;
516 u32 used = *_used;
517 u32 out_len = *_out_len;
518 u32 dm_value[10] = {0};
519 u8 i, input_idx = 0;
520
521 for (i = 0; i < 5; i++) {
522 if (input[i + 1]) {
523 PHYDM_SSCANF(input[i + 1], DCMD_HEX, &dm_value[i]);
524 input_idx++;
525 }
526 }
527
528 if (input_idx == 0)
529 return;
530
531 dm->path_select = (u8)(dm_value[0] & 0xf);
532 PDM_SNPF(out_len, used, output + used, out_len - used,
533 "Path_select = (( 0x%x ))\n", dm->path_select);
534
535 /* @2 [Fix path] */
536 if (dm->path_select != PHYDM_AUTO_PATH) {
537 PDM_SNPF(out_len, used, output + used, out_len - used,
538 "Turn on path [%s%s%s%s]\n",
539 ((dm->path_select) & 0x1) ? "A" : "",
540 ((dm->path_select) & 0x2) ? "B" : "",
541 ((dm->path_select) & 0x4) ? "C" : "",
542 ((dm->path_select) & 0x8) ? "D" : "");
543
544 phydm_dtp_fix_tx_path(dm, dm->path_select);
545 } else {
546 PDM_SNPF(out_len, used, output + used, out_len - used, "%s\n",
547 "Auto path");
548 }
549
550 *_used = used;
551 *_out_len = out_len;
552 }
553
554 #endif /* @#if RTL8814A_SUPPORT */
555
556 #if RTL8812A_SUPPORT
phydm_update_tx_path_8812a(void * dm_void,enum bb_path path)557 void phydm_update_tx_path_8812a(void *dm_void, enum bb_path path)
558 {
559 struct dm_struct *dm = (struct dm_struct *)dm_void;
560 struct _ODM_PATH_DIVERSITY_ *p_div = &dm->dm_path_div;
561
562 if (p_div->default_tx_path != path) {
563 PHYDM_DBG(dm, DBG_PATH_DIV, "Need to Update Tx path\n");
564
565 if (path == BB_PATH_A) {
566 /*Tx by Reg*/
567 odm_set_bb_reg(dm, R_0x80c, 0xFFF0, 0x111);
568 /*Resp Tx by Txinfo*/
569 odm_set_bb_reg(dm, R_0x6d8, 0xc0, 1);
570 } else {
571 /*Tx by Reg*/
572 odm_set_bb_reg(dm, R_0x80c, 0xFFF0, 0x222);
573 /*Resp Tx by Txinfo*/
574 odm_set_bb_reg(dm, R_0x6d8, 0xc0, 2);
575 }
576 }
577 p_div->default_tx_path = path;
578
579 PHYDM_DBG(dm, DBG_PATH_DIV, "path=%s\n",
580 (path == BB_PATH_A) ? "A" : "B");
581 }
582
phydm_path_diversity_init_8812a(void * dm_void)583 void phydm_path_diversity_init_8812a(void *dm_void)
584 {
585 struct dm_struct *dm = (struct dm_struct *)dm_void;
586 struct _ODM_PATH_DIVERSITY_ *p_div = &dm->dm_path_div;
587 u32 i;
588
589 odm_set_bb_reg(dm, R_0x80c, BIT(29), 1); /* Tx path from Reg */
590 odm_set_bb_reg(dm, R_0x80c, 0xFFF0, 0x111); /* Tx by Reg */
591 odm_set_bb_reg(dm, R_0x6d8, BIT(7) | BIT6, 1); /* Resp Tx by Txinfo */
592 phydm_set_tx_path_by_bb_reg(dm, RF_PATH_A);
593
594 for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++)
595 p_div->path_sel[i] = 1; /* TxInfo default at path-A */
596 }
597 #endif
598
599 #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT
phydm_set_resp_tx_path_by_fw_jgr3(void * dm_void,u8 macid,enum bb_path path,boolean enable)600 void phydm_set_resp_tx_path_by_fw_jgr3(void *dm_void, u8 macid,
601 enum bb_path path, boolean enable)
602 {
603 struct dm_struct *dm = (struct dm_struct *)dm_void;
604 struct _ODM_PATH_DIVERSITY_ *p_div = &dm->dm_path_div;
605 u8 h2c_para[7] = {0};
606 u8 path_map[4] = {0}; /* tx logic map*/
607 u8 num_enable_path = 0;
608 u8 n_tx_path_ctrl_map = 0;
609 u8 i = 0, n_sts = 0;
610
611 /*Response TX is controlled in FW ctrl info*/
612
613 PHYDM_DBG(dm, DBG_PATH_DIV, "[%s] =====>\n", __func__);
614
615 if (enable) {
616 n_tx_path_ctrl_map = path;
617
618 for (i = 0; i < 4; i++) {
619 path_map[i] = 0;
620 if (path & BIT(i))
621 num_enable_path++;
622 }
623
624 for (i = 0; i < 4; i++) {
625 if (path & BIT(i)) {
626 path_map[i] = n_sts;
627 n_sts++;
628
629 if (n_sts == num_enable_path)
630 break;
631 }
632 }
633 }
634
635 PHYDM_DBG(dm, DBG_PATH_DIV, "ctrl_map=0x%x Map[D:A]={%d, %d, %d, %d}\n",
636 n_tx_path_ctrl_map,
637 path_map[3], path_map[2], path_map[1], path_map[0]);
638
639 h2c_para[0] = macid;
640 h2c_para[1] = n_tx_path_ctrl_map;
641 h2c_para[2] = (path_map[3] << 6) | (path_map[2] << 4) |
642 (path_map[1] << 2) | path_map[0];
643
644 odm_fill_h2c_cmd(dm, PHYDM_H2C_DYNAMIC_TX_PATH, 7, h2c_para);
645 }
646
phydm_get_tx_path_txdesc_jgr3(void * dm_void,u8 macid,struct path_txdesc_ctrl * desc)647 void phydm_get_tx_path_txdesc_jgr3(void *dm_void, u8 macid,
648 struct path_txdesc_ctrl *desc)
649 {
650 struct dm_struct *dm = (struct dm_struct *)dm_void;
651 struct _ODM_PATH_DIVERSITY_ *p_div = &dm->dm_path_div;
652 u8 ant_map_a = 0, ant_map_b = 0;
653 u8 ntx_map = 0;
654
655 if (p_div->path_sel[macid] == BB_PATH_A) {
656 desc->ant_map_a = 0; /*offest24[23:22]*/
657 desc->ant_map_b = 0; /*offest24[25:24]*/
658 desc->ntx_map = BB_PATH_A; /*offest28[23:20]*/
659 } else if (p_div->path_sel[macid] == BB_PATH_B) {
660 desc->ant_map_a = 0; /*offest24[23:22]*/
661 desc->ant_map_b = 0; /*offest24[25:24]*/
662 desc->ntx_map = BB_PATH_B; /*offest28[23:20]*/
663 } else {
664 desc->ant_map_a = 0; /*offest24[23:22]*/
665 desc->ant_map_b = 1; /*offest24[25:24]*/
666 desc->ntx_map = BB_PATH_AB; /*offest28[23:20]*/
667 }
668 }
669 #endif
670
phydm_tx_path_by_mac_or_reg(void * dm_void,enum phydm_path_ctrl ctrl)671 void phydm_tx_path_by_mac_or_reg(void *dm_void, enum phydm_path_ctrl ctrl)
672 {
673 struct dm_struct *dm = (struct dm_struct *)dm_void;
674 struct _ODM_PATH_DIVERSITY_ *p_div = &dm->dm_path_div;
675
676 PHYDM_DBG(dm, DBG_PATH_DIV, "[%s] ctrl=%s\n",
677 __func__, (ctrl == TX_PATH_BY_REG) ? "REG" : "DESC");
678
679 if (ctrl == p_div->tx_path_ctrl)
680 return;
681
682 p_div->tx_path_ctrl = ctrl;
683
684 switch (dm->support_ic_type) {
685 #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT
686 case ODM_RTL8822B:
687 case ODM_RTL8822C:
688 case ODM_RTL8812F:
689 case ODM_RTL8197G:
690 if (ctrl == TX_PATH_BY_REG) {
691 odm_set_bb_reg(dm, R_0x1e24, BIT(16), 0); /*OFDM*/
692 odm_set_bb_reg(dm, R_0x1a84, 0xe0, 0); /*CCK*/
693 } else {
694 odm_set_bb_reg(dm, R_0x1e24, BIT(16), 1); /*OFDM*/
695 odm_set_bb_reg(dm, R_0x1a84, 0xe0, 7); /*CCK*/
696 }
697
698 break;
699 #endif
700 #if 0 /*(RTL8822B_SUPPORT)*/ /*@ HW Bug*/
701 case ODM_RTL8822B:
702 if (ctrl == TX_PATH_BY_REG) {
703 odm_set_bb_reg(dm, R_0x93c, BIT(18), 0);
704 odm_set_bb_reg(dm, R_0xa84, 0xe0, 0); /*CCK*/
705 } else {
706 odm_set_bb_reg(dm, R_0x93c, BIT(18), 1);
707 odm_set_bb_reg(dm, R_0xa84, 0xe0, 7); /*CCK*/
708 }
709
710 break;
711 #endif
712 default:
713 break;
714 }
715 }
716
phydm_fix_1ss_tx_path_by_bb_reg(void * dm_void,enum bb_path tx_path_sel_1ss,enum bb_path tx_path_sel_cck)717 void phydm_fix_1ss_tx_path_by_bb_reg(void *dm_void,
718 enum bb_path tx_path_sel_1ss,
719 enum bb_path tx_path_sel_cck)
720 {
721 struct dm_struct *dm = (struct dm_struct *)dm_void;
722 struct _ODM_PATH_DIVERSITY_ *p_div = &dm->dm_path_div;
723
724 if (tx_path_sel_1ss != BB_PATH_AUTO) {
725 p_div->ofdm_fix_path_en = true;
726 p_div->ofdm_fix_path_sel = tx_path_sel_1ss;
727 } else {
728 p_div->ofdm_fix_path_en = false;
729 p_div->ofdm_fix_path_sel = dm->tx_1ss_status;
730 }
731
732 if (tx_path_sel_cck != BB_PATH_AUTO) {
733 p_div->cck_fix_path_en = true;
734 p_div->cck_fix_path_sel = tx_path_sel_cck;
735 } else {
736 p_div->cck_fix_path_en = false;
737 p_div->cck_fix_path_sel = dm->tx_1ss_status;
738 }
739
740 p_div->force_update = true;
741
742 PHYDM_DBG(dm, DBG_PATH_DIV,
743 "{OFDM_fix_en=%d, path=%d} {CCK_fix_en=%d, path=%d}\n",
744 p_div->ofdm_fix_path_en, p_div->ofdm_fix_path_sel,
745 p_div->cck_fix_path_en, p_div->cck_fix_path_sel);
746 }
747
phydm_set_tx_path_by_bb_reg(void * dm_void,enum bb_path tx_path_sel_1ss)748 void phydm_set_tx_path_by_bb_reg(void *dm_void, enum bb_path tx_path_sel_1ss)
749 {
750 struct dm_struct *dm = (struct dm_struct *)dm_void;
751 struct _ODM_PATH_DIVERSITY_ *p_div = &dm->dm_path_div;
752 enum bb_path tx_path_sel_cck = tx_path_sel_1ss;
753
754 if (!p_div->force_update) {
755 if (tx_path_sel_1ss == p_div->default_tx_path) {
756 PHYDM_DBG(dm, DBG_PATH_DIV, "Stay in TX path=%s\n",
757 (tx_path_sel_1ss == BB_PATH_A) ? "A" : "B");
758 return;
759 }
760 }
761 p_div->force_update = false;
762
763 p_div->default_tx_path = tx_path_sel_1ss;
764
765 PHYDM_DBG(dm, DBG_PATH_DIV, "Switch TX path=%s\n",
766 (tx_path_sel_1ss == BB_PATH_A) ? "A" : "B");
767
768 /*Adv-ctrl mode*/
769 if (p_div->cck_fix_path_en) {
770 PHYDM_DBG(dm, DBG_PATH_DIV, "Fix CCK TX path=%d\n",
771 p_div->cck_fix_path_sel);
772 tx_path_sel_cck = p_div->cck_fix_path_sel;
773 }
774
775 if (p_div->ofdm_fix_path_en) {
776 PHYDM_DBG(dm, DBG_PATH_DIV, "Fix OFDM TX path=%d\n",
777 p_div->ofdm_fix_path_sel);
778 tx_path_sel_1ss = p_div->ofdm_fix_path_sel;
779 }
780
781 switch (dm->support_ic_type) {
782 #if RTL8822C_SUPPORT
783 case ODM_RTL8822C:
784 phydm_config_tx_path_8822c(dm, dm->tx_2ss_status,
785 tx_path_sel_1ss, tx_path_sel_cck);
786 break;
787 #endif
788
789 #if RTL8822B_SUPPORT
790 case ODM_RTL8822B:
791 if (dm->tx_ant_status != BB_PATH_AB)
792 return;
793
794 phydm_config_tx_path_8822b(dm, BB_PATH_AB,
795 tx_path_sel_1ss, tx_path_sel_cck);
796 break;
797 #endif
798
799 #if RTL8192F_SUPPORT
800 case ODM_RTL8192F:
801 if (dm->tx_ant_status != BB_PATH_AB)
802 return;
803
804 phydm_config_tx_path_8192f(dm, BB_PATH_AB,
805 tx_path_sel_1ss, tx_path_sel_cck);
806 break;
807 #endif
808
809 #if RTL8812A_SUPPORT
810 case ODM_RTL8812:
811 phydm_update_tx_path_8812a(dm, tx_path_sel_1ss);
812 break;
813 #endif
814 default:
815 break;
816 }
817 }
818
phydm_tx_path_diversity_2ss(void * dm_void)819 void phydm_tx_path_diversity_2ss(void *dm_void)
820 {
821 struct dm_struct *dm = (struct dm_struct *)dm_void;
822 struct _ODM_PATH_DIVERSITY_ *p_div = &dm->dm_path_div;
823 struct cmn_sta_info *sta;
824 enum bb_path default_tx_path = BB_PATH_A, path = BB_PATH_A;
825 u32 rssi_a = 0, rssi_b = 0;
826 u32 local_max_rssi, glb_min_rssi = 0xff;
827 u8 i = 0;
828
829 PHYDM_DBG(dm, DBG_PATH_DIV, "[%s] =======>\n", __func__);
830
831 if (!dm->is_linked) {
832 if (dm->first_disconnect)
833 phydm_tx_path_by_mac_or_reg(dm, TX_PATH_BY_REG);
834
835 PHYDM_DBG(dm, DBG_PATH_DIV, "No Link\n");
836 return;
837 }
838
839 #if 0/*def PHYDM_IC_JGR3_SERIES_SUPPORT*/
840 if (dm->support_ic_type & ODM_IC_JGR3_SERIES) {
841 if (dm->is_one_entry_only || p_div->cck_fix_path_en ||
842 p_div->ofdm_fix_path_en)
843 phydm_tx_path_by_mac_or_reg(dm, TX_PATH_BY_REG);
844 else
845 phydm_tx_path_by_mac_or_reg(dm, TX_PATH_BY_DESC);
846 }
847 #endif
848
849 for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
850 sta = dm->phydm_sta_info[i];
851 if (!is_sta_active(sta))
852 continue;
853
854 /* 2 Caculate RSSI per path */
855 rssi_a = PHYDM_DIV(p_div->path_a_sum[i], p_div->path_a_cnt[i]);
856 rssi_b = PHYDM_DIV(p_div->path_b_sum[i], p_div->path_b_cnt[i]);
857
858 if (rssi_a == rssi_b)
859 path = p_div->default_tx_path;
860 else
861 path = (rssi_a > rssi_b) ? BB_PATH_A : BB_PATH_B;
862
863 local_max_rssi = (rssi_a > rssi_b) ? rssi_a : rssi_b;
864
865 PHYDM_DBG(dm, DBG_PATH_DIV,
866 "[%d]PathA sum=%d, cnt=%d, avg_rssi=%d\n",
867 i, p_div->path_a_sum[i],
868 p_div->path_a_cnt[i], rssi_a);
869 PHYDM_DBG(dm, DBG_PATH_DIV,
870 "[%d]PathB sum=%d, cnt=%d, avg_rssi=%d\n",
871 i, p_div->path_b_sum[i],
872 p_div->path_b_cnt[i], rssi_b);
873
874 /*Select default Tx path */
875 if (local_max_rssi < glb_min_rssi) {
876 glb_min_rssi = local_max_rssi;
877 default_tx_path = path;
878 }
879
880 if (p_div->path_sel[i] != path) {
881 p_div->path_sel[i] = path;
882 #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT
883 if (dm->support_ic_type & ODM_IC_JGR3_SERIES)
884 phydm_set_resp_tx_path_by_fw_jgr3(dm, i,
885 path, true);
886 #endif
887 }
888
889 p_div->path_a_cnt[i] = 0;
890 p_div->path_a_sum[i] = 0;
891 p_div->path_b_cnt[i] = 0;
892 p_div->path_b_sum[i] = 0;
893 }
894
895 /* 2 Update default Tx path */
896 phydm_set_tx_path_by_bb_reg(dm, default_tx_path);
897 PHYDM_DBG(dm, DBG_PATH_DIV, "[%s] end\n\n", __func__);
898 }
899
phydm_tx_path_diversity(void * dm_void)900 void phydm_tx_path_diversity(void *dm_void)
901 {
902 struct dm_struct *dm = (struct dm_struct *)dm_void;
903 struct _ODM_PATH_DIVERSITY_ *p_div = &dm->dm_path_div;
904
905 p_div->path_div_in_progress = false;
906
907 if (!(dm->support_ability & ODM_BB_PATH_DIV))
908 return;
909
910 if (p_div->stop_path_div) {
911 PHYDM_DBG(dm, DBG_PATH_DIV,
912 "stop_path_div=1, tx_1ss_status=%d\n",
913 dm->tx_1ss_status);
914 return;
915 }
916
917 switch (dm->support_ic_type) {
918 #ifdef PHYDM_CONFIG_PATH_DIV_V2
919 case ODM_RTL8822B:
920 case ODM_RTL8822C:
921 case ODM_RTL8192F:
922 case ODM_RTL8812F:
923 case ODM_RTL8197G:
924 if (dm->rx_ant_status != BB_PATH_AB) {
925 PHYDM_DBG(dm, DBG_PATH_DIV,
926 "[Return] tx_Path_en=%d, rx_Path_en=%d\n",
927 dm->tx_ant_status, dm->rx_ant_status);
928 return;
929 }
930
931 p_div->path_div_in_progress = true;
932 phydm_tx_path_diversity_2ss(dm);
933 break;
934 #endif
935
936 #if (RTL8812A_SUPPORT)
937 case ODM_RTL8812:
938 phydm_tx_path_diversity_2ss(dm);
939 break;
940 #endif
941
942 #if RTL8814A_SUPPORT
943 case ODM_RTL8814A:
944 phydm_dynamic_tx_path(dm);
945 break;
946 #endif
947 }
948 }
949
phydm_tx_path_diversity_init_v2(void * dm_void)950 void phydm_tx_path_diversity_init_v2(void *dm_void)
951 {
952 struct dm_struct *dm = (struct dm_struct *)dm_void;
953 struct _ODM_PATH_DIVERSITY_ *p_div = &dm->dm_path_div;
954 u32 i = 0;
955
956 PHYDM_DBG(dm, DBG_PATH_DIV, "[%s] ====>\n", __func__);
957
958 /*BB_PATH_AB is a invalid value used for init state*/
959 p_div->default_tx_path = BB_PATH_A;
960 p_div->tx_path_ctrl = TX_PATH_CTRL_INIT;
961 p_div->path_div_in_progress = false;
962
963 p_div->cck_fix_path_en = false;
964 p_div->ofdm_fix_path_en = false;
965 p_div->force_update = false;
966
967 for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++)
968 p_div->path_sel[i] = BB_PATH_A; /* TxInfo default at path-A */
969
970 phydm_tx_path_by_mac_or_reg(dm, TX_PATH_BY_REG);
971 }
972
phydm_tx_path_diversity_init(void * dm_void)973 void phydm_tx_path_diversity_init(void *dm_void)
974 {
975 struct dm_struct *dm = (struct dm_struct *)dm_void;
976
977 if (!(dm->support_ability & ODM_BB_PATH_DIV))
978 return;
979
980 switch (dm->support_ic_type) {
981 #ifdef PHYDM_CONFIG_PATH_DIV_V2
982 case ODM_RTL8822C:
983 case ODM_RTL8822B:
984 case ODM_RTL8192F:
985 case ODM_RTL8812F:
986 case ODM_RTL8197G:
987 phydm_tx_path_diversity_init_v2(dm); /*@ After 8822B*/
988 break;
989 #endif
990
991 #if RTL8812A_SUPPORT
992 case ODM_RTL8812:
993 phydm_path_diversity_init_8812a(dm);
994 break;
995 #endif
996
997 #if RTL8814A_SUPPORT
998 case ODM_RTL8814A:
999 phydm_dynamic_tx_path_init(dm);
1000 break;
1001 #endif
1002 }
1003 }
1004
phydm_process_rssi_for_path_div(void * dm_void,void * phy_info_void,void * pkt_info_void)1005 void phydm_process_rssi_for_path_div(void *dm_void, void *phy_info_void,
1006 void *pkt_info_void)
1007 {
1008 struct dm_struct *dm = (struct dm_struct *)dm_void;
1009 struct phydm_phyinfo_struct *phy_info = NULL;
1010 struct phydm_perpkt_info_struct *pktinfo = NULL;
1011 struct _ODM_PATH_DIVERSITY_ *p_div = &dm->dm_path_div;
1012 u8 id = 0;
1013
1014 phy_info = (struct phydm_phyinfo_struct *)phy_info_void;
1015 pktinfo = (struct phydm_perpkt_info_struct *)pkt_info_void;
1016
1017 if (!(pktinfo->is_packet_to_self || pktinfo->is_packet_match_bssid))
1018 return;
1019
1020 if (pktinfo->is_cck_rate)
1021 return;
1022
1023 id = pktinfo->station_id;
1024 p_div->path_a_sum[id] += phy_info->rx_mimo_signal_strength[0];
1025 p_div->path_a_cnt[id]++;
1026
1027 p_div->path_b_sum[id] += phy_info->rx_mimo_signal_strength[1];
1028 p_div->path_b_cnt[id]++;
1029 }
1030
phydm_pathdiv_debug(void * dm_void,char input[][16],u32 * _used,char * output,u32 * _out_len)1031 void phydm_pathdiv_debug(void *dm_void, char input[][16], u32 *_used,
1032 char *output, u32 *_out_len)
1033 {
1034 struct dm_struct *dm = (struct dm_struct *)dm_void;
1035 struct _ODM_PATH_DIVERSITY_ *p_div = &dm->dm_path_div;
1036 char help[] = "-h";
1037 u32 used = *_used;
1038 u32 out_len = *_out_len;
1039 u32 val[10] = {0};
1040 u8 i, input_idx = 0;
1041
1042 for (i = 0; i < 5; i++) {
1043 PHYDM_SSCANF(input[i + 1], DCMD_HEX, &val[i]);
1044 input_idx++;
1045 }
1046
1047 if (input_idx == 0)
1048 return;
1049
1050 PHYDM_SSCANF(input[1], DCMD_HEX, &val[0]);
1051 PHYDM_SSCANF(input[2], DCMD_HEX, &val[1]);
1052
1053 if ((strcmp(input[1], help) == 0)) {
1054 PDM_SNPF(out_len, used, output + used, out_len - used,
1055 "{1:TX Ctrl Sig} {0:BB, 1:MAC}\n");
1056 PDM_SNPF(out_len, used, output + used, out_len - used,
1057 "{2:BB Default TX REG} {path}\n");
1058 PDM_SNPF(out_len, used, output + used, out_len - used,
1059 "{3:MAC DESC TX} {path} {macid}\n");
1060 #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT
1061 PDM_SNPF(out_len, used, output + used, out_len - used,
1062 "{4:MAC Resp TX} {path} {macid}\n");
1063 #endif
1064 PDM_SNPF(out_len, used, output + used, out_len - used,
1065 "{5:Fix 1ss path} {ofdm path} {cck path}\n");
1066 } else if (val[0] == 1) {
1067 phydm_tx_path_by_mac_or_reg(dm, (enum phydm_path_ctrl)val[1]);
1068 } else if (val[0] == 2) {
1069 phydm_set_tx_path_by_bb_reg(dm, (enum bb_path)val[1]);
1070 } else if (val[0] == 3) {
1071 p_div->path_sel[val[2]] = (enum bb_path)val[1];
1072 #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT
1073 } else if (val[0] == 4) {
1074 phydm_set_resp_tx_path_by_fw_jgr3(dm, (u8)val[2],
1075 (enum bb_path)val[1], true);
1076 #endif
1077 } else if (val[0] == 5) {
1078 phydm_fix_1ss_tx_path_by_bb_reg(dm, (enum bb_path)val[1],
1079 (enum bb_path)val[2]);
1080 }
1081 *_used = used;
1082 *_out_len = out_len;
1083 }
1084
phydm_c2h_dtp_handler(void * dm_void,u8 * cmd_buf,u8 cmd_len)1085 void phydm_c2h_dtp_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len)
1086 {
1087 struct dm_struct *dm = (struct dm_struct *)dm_void;
1088 struct _ODM_PATH_DIVERSITY_ *p_div = &dm->dm_path_div;
1089
1090 u8 macid = cmd_buf[0];
1091 u8 target = cmd_buf[1];
1092 u8 nsc_1 = cmd_buf[2];
1093 u8 nsc_2 = cmd_buf[3];
1094 u8 nsc_3 = cmd_buf[4];
1095
1096 PHYDM_DBG(dm, DBG_PATH_DIV, "Target_candidate = (( %d ))\n", target);
1097 /*@
1098 if( (nsc_1 >= nsc_2) && (nsc_1 >= nsc_3))
1099 {
1100 phydm_dtp_fix_tx_path(dm, p_div->ant_candidate_1);
1101 }
1102 else if( nsc_2 >= nsc_3)
1103 {
1104 phydm_dtp_fix_tx_path(dm, p_div->ant_candidate_2);
1105 }
1106 else
1107 {
1108 phydm_dtp_fix_tx_path(dm, p_div->ant_candidate_3);
1109 }
1110 */
1111 }
1112
1113 #endif /* @#ifdef CONFIG_PATH_DIVERSITY */
1114