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 *****************************************************************************/
15
16 /* ************************************************************
17 * include files
18 * ************************************************************ */
19 #include "mp_precomp.h"
20 #include "phydm_precomp.h"
21
22 #if (defined(CONFIG_PATH_DIVERSITY))
23 #if RTL8814A_SUPPORT
24
25 void
phydm_dtp_fix_tx_path(void * p_dm_void,u8 path)26 phydm_dtp_fix_tx_path(
27 void *p_dm_void,
28 u8 path
29 )
30 {
31 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
32 struct _ODM_PATH_DIVERSITY_ *p_dm_path_div = &p_dm->dm_path_div;
33 u8 i, num_enable_path = 0;
34
35 if (path == p_dm_path_div->pre_tx_path)
36 return;
37 else
38 p_dm_path_div->pre_tx_path = path;
39
40 odm_set_bb_reg(p_dm, 0x93c, BIT(18) | BIT(19), 3);
41
42 for (i = 0; i < 4; i++) {
43 if (path & BIT(i))
44 num_enable_path++;
45 }
46 PHYDM_DBG(p_dm, DBG_PATH_DIV, (" number of turn-on path : (( %d ))\n", num_enable_path));
47
48 if (num_enable_path == 1) {
49 odm_set_bb_reg(p_dm, 0x93c, 0xf00000, path);
50
51 if (path == BB_PATH_A) { /* 1-1 */
52 PHYDM_DBG(p_dm, DBG_PATH_DIV, (" Turn on path (( A ))\n"));
53 odm_set_bb_reg(p_dm, 0x93c, BIT(25) | BIT(24), 0);
54 } else if (path == BB_PATH_B) { /* 1-2 */
55 PHYDM_DBG(p_dm, DBG_PATH_DIV, (" Turn on path (( B ))\n"));
56 odm_set_bb_reg(p_dm, 0x93c, BIT(27) | BIT(26), 0);
57 } else if (path == BB_PATH_C) { /* 1-3 */
58 PHYDM_DBG(p_dm, DBG_PATH_DIV, (" Turn on path (( C ))\n"));
59 odm_set_bb_reg(p_dm, 0x93c, BIT(29) | BIT(28), 0);
60
61 } else if (path == BB_PATH_D) { /* 1-4 */
62 PHYDM_DBG(p_dm, DBG_PATH_DIV, (" Turn on path (( D ))\n"));
63 odm_set_bb_reg(p_dm, 0x93c, BIT(31) | BIT(30), 0);
64 }
65
66 } else if (num_enable_path == 2) {
67 odm_set_bb_reg(p_dm, 0x93c, 0xf00000, path);
68 odm_set_bb_reg(p_dm, 0x940, 0xf0, path);
69
70 if (path == (BB_PATH_AB)) { /* 2-1 */
71 PHYDM_DBG(p_dm, DBG_PATH_DIV, (" Turn on path (( A B ))\n"));
72 /* set for 1ss */
73 odm_set_bb_reg(p_dm, 0x93c, BIT(25) | BIT(24), 0);
74 odm_set_bb_reg(p_dm, 0x93c, BIT(27) | BIT(26), 1);
75 /* set for 2ss */
76 odm_set_bb_reg(p_dm, 0x940, BIT(9) | BIT(8), 0);
77 odm_set_bb_reg(p_dm, 0x940, BIT(11) | BIT(10), 1);
78 } else if (path == BB_PATH_AC) { /* 2-2 */
79 PHYDM_DBG(p_dm, DBG_PATH_DIV, (" Turn on path (( A C ))\n"));
80 /* set for 1ss */
81 odm_set_bb_reg(p_dm, 0x93c, BIT(25) | BIT(24), 0);
82 odm_set_bb_reg(p_dm, 0x93c, BIT(29) | BIT(28), 1);
83 /* set for 2ss */
84 odm_set_bb_reg(p_dm, 0x940, BIT(9) | BIT(8), 0);
85 odm_set_bb_reg(p_dm, 0x940, BIT(13) | BIT(12), 1);
86 } else if (path == BB_PATH_AD) { /* 2-3 */
87 PHYDM_DBG(p_dm, DBG_PATH_DIV, (" Turn on path (( A D ))\n"));
88 /* set for 1ss */
89 odm_set_bb_reg(p_dm, 0x93c, BIT(25) | BIT(24), 0);
90 odm_set_bb_reg(p_dm, 0x93c, BIT(31) | BIT(30), 1);
91 /* set for 2ss */
92 odm_set_bb_reg(p_dm, 0x940, BIT(9) | BIT(8), 0);
93 odm_set_bb_reg(p_dm, 0x940, BIT(15) | BIT(14), 1);
94 } else if (path == BB_PATH_BC) { /* 2-4 */
95 PHYDM_DBG(p_dm, DBG_PATH_DIV, (" Turn on path (( B C ))\n"));
96 /* set for 1ss */
97 odm_set_bb_reg(p_dm, 0x93c, BIT(27) | BIT(26), 0);
98 odm_set_bb_reg(p_dm, 0x93c, BIT(29) | BIT(28), 1);
99 /* set for 2ss */
100 odm_set_bb_reg(p_dm, 0x940, BIT(11) | BIT(10), 0);
101 odm_set_bb_reg(p_dm, 0x940, BIT(13) | BIT(12), 1);
102 } else if (path == BB_PATH_BD) { /* 2-5 */
103 PHYDM_DBG(p_dm, DBG_PATH_DIV, (" Turn on path (( B D ))\n"));
104 /* set for 1ss */
105 odm_set_bb_reg(p_dm, 0x93c, BIT(27) | BIT(26), 0);
106 odm_set_bb_reg(p_dm, 0x93c, BIT(31) | BIT(30), 1);
107 /* set for 2ss */
108 odm_set_bb_reg(p_dm, 0x940, BIT(11) | BIT(10), 0);
109 odm_set_bb_reg(p_dm, 0x940, BIT(15) | BIT(14), 1);
110 } else if (path == BB_PATH_CD) { /* 2-6 */
111 PHYDM_DBG(p_dm, DBG_PATH_DIV, (" Turn on path (( C D ))\n"));
112 /* set for 1ss */
113 odm_set_bb_reg(p_dm, 0x93c, BIT(29) | BIT(28), 0);
114 odm_set_bb_reg(p_dm, 0x93c, BIT(31) | BIT(30), 1);
115 /* set for 2ss */
116 odm_set_bb_reg(p_dm, 0x940, BIT(13) | BIT(12), 0);
117 odm_set_bb_reg(p_dm, 0x940, BIT(15) | BIT(14), 1);
118 }
119
120 } else if (num_enable_path == 3) {
121 odm_set_bb_reg(p_dm, 0x93c, 0xf00000, path);
122 odm_set_bb_reg(p_dm, 0x940, 0xf0, path);
123 odm_set_bb_reg(p_dm, 0x940, 0xf0000, path);
124
125 if (path == BB_PATH_ABC) { /* 3-1 */
126 PHYDM_DBG(p_dm, DBG_PATH_DIV, (" Turn on path (( A B C))\n"));
127 /* set for 1ss */
128 odm_set_bb_reg(p_dm, 0x93c, BIT(25) | BIT(24), 0);
129 odm_set_bb_reg(p_dm, 0x93c, BIT(27) | BIT(26), 1);
130 odm_set_bb_reg(p_dm, 0x93c, BIT(29) | BIT(28), 2);
131 /* set for 2ss */
132 odm_set_bb_reg(p_dm, 0x940, BIT(9) | BIT(8), 0);
133 odm_set_bb_reg(p_dm, 0x940, BIT(11) | BIT(10), 1);
134 odm_set_bb_reg(p_dm, 0x940, BIT(13) | BIT(12), 2);
135 /* set for 3ss */
136 odm_set_bb_reg(p_dm, 0x940, BIT(21) | BIT(20), 0);
137 odm_set_bb_reg(p_dm, 0x940, BIT(23) | BIT(22), 1);
138 odm_set_bb_reg(p_dm, 0x940, BIT(25) | BIT(24), 2);
139 } else if (path == BB_PATH_ABD) { /* 3-2 */
140 PHYDM_DBG(p_dm, DBG_PATH_DIV, (" Turn on path (( A B D ))\n"));
141 /* set for 1ss */
142 odm_set_bb_reg(p_dm, 0x93c, BIT(25) | BIT(24), 0);
143 odm_set_bb_reg(p_dm, 0x93c, BIT(27) | BIT(26), 1);
144 odm_set_bb_reg(p_dm, 0x93c, BIT(31) | BIT(30), 2);
145 /* set for 2ss */
146 odm_set_bb_reg(p_dm, 0x940, BIT(9) | BIT(8), 0);
147 odm_set_bb_reg(p_dm, 0x940, BIT(11) | BIT(10), 1);
148 odm_set_bb_reg(p_dm, 0x940, BIT(15) | BIT(14), 2);
149 /* set for 3ss */
150 odm_set_bb_reg(p_dm, 0x940, BIT(21) | BIT(20), 0);
151 odm_set_bb_reg(p_dm, 0x940, BIT(23) | BIT(22), 1);
152 odm_set_bb_reg(p_dm, 0x940, BIT(27) | BIT(26), 2);
153
154 } else if (path == BB_PATH_ACD) { /* 3-3 */
155 PHYDM_DBG(p_dm, DBG_PATH_DIV, (" Turn on path (( A C D ))\n"));
156 /* set for 1ss */
157 odm_set_bb_reg(p_dm, 0x93c, BIT(25) | BIT(24), 0);
158 odm_set_bb_reg(p_dm, 0x93c, BIT(29) | BIT(28), 1);
159 odm_set_bb_reg(p_dm, 0x93c, BIT(31) | BIT(30), 2);
160 /* set for 2ss */
161 odm_set_bb_reg(p_dm, 0x940, BIT(9) | BIT(8), 0);
162 odm_set_bb_reg(p_dm, 0x940, BIT(13) | BIT(12), 1);
163 odm_set_bb_reg(p_dm, 0x940, BIT(15) | BIT(14), 2);
164 /* set for 3ss */
165 odm_set_bb_reg(p_dm, 0x940, BIT(21) | BIT(20), 0);
166 odm_set_bb_reg(p_dm, 0x940, BIT(25) | BIT(24), 1);
167 odm_set_bb_reg(p_dm, 0x940, BIT(27) | BIT(26), 2);
168 } else if (path == BB_PATH_BCD) { /* 3-4 */
169 PHYDM_DBG(p_dm, DBG_PATH_DIV, (" Turn on path (( B C D))\n"));
170 /* set for 1ss */
171 odm_set_bb_reg(p_dm, 0x93c, BIT(27) | BIT(26), 0);
172 odm_set_bb_reg(p_dm, 0x93c, BIT(29) | BIT(28), 1);
173 odm_set_bb_reg(p_dm, 0x93c, BIT(31) | BIT(30), 2);
174 /* set for 2ss */
175 odm_set_bb_reg(p_dm, 0x940, BIT(11) | BIT(10), 0);
176 odm_set_bb_reg(p_dm, 0x940, BIT(13) | BIT(12), 1);
177 odm_set_bb_reg(p_dm, 0x940, BIT(15) | BIT(14), 2);
178 /* set for 3ss */
179 odm_set_bb_reg(p_dm, 0x940, BIT(23) | BIT(22), 0);
180 odm_set_bb_reg(p_dm, 0x940, BIT(25) | BIT(24), 1);
181 odm_set_bb_reg(p_dm, 0x940, BIT(27) | BIT(26), 2);
182 }
183 } else if (num_enable_path == 4)
184 PHYDM_DBG(p_dm, DBG_PATH_DIV, (" Turn on path ((A B C D))\n"));
185
186 }
187
188 void
phydm_find_default_path(void * p_dm_void)189 phydm_find_default_path(
190 void *p_dm_void
191 )
192 {
193 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
194 struct _ODM_PATH_DIVERSITY_ *p_dm_path_div = &p_dm->dm_path_div;
195 u32 rssi_avg_a = 0, rssi_avg_b = 0, rssi_avg_c = 0, rssi_avg_d = 0, rssi_avg_bcd = 0;
196 u32 rssi_total_a = 0, rssi_total_b = 0, rssi_total_c = 0, rssi_total_d = 0;
197
198 /* 2 Default path Selection By RSSI */
199
200 rssi_avg_a = (p_dm_path_div->path_a_cnt_all > 0) ? (p_dm_path_div->path_a_sum_all / p_dm_path_div->path_a_cnt_all) : 0 ;
201 rssi_avg_b = (p_dm_path_div->path_b_cnt_all > 0) ? (p_dm_path_div->path_b_sum_all / p_dm_path_div->path_b_cnt_all) : 0 ;
202 rssi_avg_c = (p_dm_path_div->path_c_cnt_all > 0) ? (p_dm_path_div->path_c_sum_all / p_dm_path_div->path_c_cnt_all) : 0 ;
203 rssi_avg_d = (p_dm_path_div->path_d_cnt_all > 0) ? (p_dm_path_div->path_d_sum_all / p_dm_path_div->path_d_cnt_all) : 0 ;
204
205
206 p_dm_path_div->path_a_sum_all = 0;
207 p_dm_path_div->path_a_cnt_all = 0;
208 p_dm_path_div->path_b_sum_all = 0;
209 p_dm_path_div->path_b_cnt_all = 0;
210 p_dm_path_div->path_c_sum_all = 0;
211 p_dm_path_div->path_c_cnt_all = 0;
212 p_dm_path_div->path_d_sum_all = 0;
213 p_dm_path_div->path_d_cnt_all = 0;
214
215 if (p_dm_path_div->use_path_a_as_default_ant == 1) {
216 rssi_avg_bcd = (rssi_avg_b + rssi_avg_c + rssi_avg_d) / 3;
217
218 if ((rssi_avg_a + ANT_DECT_RSSI_TH) > rssi_avg_bcd) {
219 p_dm_path_div->is_path_a_exist = true;
220 p_dm_path_div->default_path = PATH_A;
221 } else
222 p_dm_path_div->is_path_a_exist = false;
223 } else {
224 if ((rssi_avg_a >= rssi_avg_b) && (rssi_avg_a >= rssi_avg_c) && (rssi_avg_a >= rssi_avg_d))
225 p_dm_path_div->default_path = PATH_A;
226 else if ((rssi_avg_b >= rssi_avg_c) && (rssi_avg_b >= rssi_avg_d))
227 p_dm_path_div->default_path = PATH_B;
228 else if (rssi_avg_c >= rssi_avg_d)
229 p_dm_path_div->default_path = PATH_C;
230 else
231 p_dm_path_div->default_path = PATH_D;
232 }
233
234
235 }
236
237
238 void
phydm_candidate_dtp_update(void * p_dm_void)239 phydm_candidate_dtp_update(
240 void *p_dm_void
241 )
242 {
243 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
244 struct _ODM_PATH_DIVERSITY_ *p_dm_path_div = &p_dm->dm_path_div;
245
246 p_dm_path_div->num_candidate = 3;
247
248 if (p_dm_path_div->use_path_a_as_default_ant == 1) {
249 if (p_dm_path_div->num_tx_path == 3) {
250 if (p_dm_path_div->is_path_a_exist) {
251 p_dm_path_div->ant_candidate_1 = BB_PATH_ABC;
252 p_dm_path_div->ant_candidate_2 = BB_PATH_ABD;
253 p_dm_path_div->ant_candidate_3 = BB_PATH_ACD;
254 } else { /* use path BCD */
255 p_dm_path_div->num_candidate = 1;
256 phydm_dtp_fix_tx_path(p_dm, BB_PATH_BCD);
257 return;
258 }
259 } else if (p_dm_path_div->num_tx_path == 2) {
260 if (p_dm_path_div->is_path_a_exist) {
261 p_dm_path_div->ant_candidate_1 = BB_PATH_AB;
262 p_dm_path_div->ant_candidate_2 = BB_PATH_AC;
263 p_dm_path_div->ant_candidate_3 = BB_PATH_AD;
264 } else {
265 p_dm_path_div->ant_candidate_1 = BB_PATH_BC;
266 p_dm_path_div->ant_candidate_2 = BB_PATH_BD;
267 p_dm_path_div->ant_candidate_3 = BB_PATH_CD;
268 }
269 }
270 } else {
271 /* 2 3 TX mode */
272 if (p_dm_path_div->num_tx_path == 3) { /* choose 3 ant form 4 */
273 if (p_dm_path_div->default_path == PATH_A) { /* choose 2 ant form 3 */
274 p_dm_path_div->ant_candidate_1 = BB_PATH_ABC;
275 p_dm_path_div->ant_candidate_2 = BB_PATH_ABD;
276 p_dm_path_div->ant_candidate_3 = BB_PATH_ACD;
277 } else if (p_dm_path_div->default_path == PATH_B) {
278 p_dm_path_div->ant_candidate_1 = BB_PATH_ABC;
279 p_dm_path_div->ant_candidate_2 = BB_PATH_ABD;
280 p_dm_path_div->ant_candidate_3 = BB_PATH_BCD;
281 } else if (p_dm_path_div->default_path == PATH_C) {
282 p_dm_path_div->ant_candidate_1 = BB_PATH_ABC;
283 p_dm_path_div->ant_candidate_2 = BB_PATH_ACD;
284 p_dm_path_div->ant_candidate_3 = BB_PATH_BCD;
285 } else if (p_dm_path_div->default_path == PATH_D) {
286 p_dm_path_div->ant_candidate_1 = BB_PATH_ABD;
287 p_dm_path_div->ant_candidate_2 = BB_PATH_ACD;
288 p_dm_path_div->ant_candidate_3 = BB_PATH_BCD;
289 }
290 }
291
292 /* 2 2 TX mode */
293 else if (p_dm_path_div->num_tx_path == 2) { /* choose 2 ant form 4 */
294 if (p_dm_path_div->default_path == PATH_A) { /* choose 2 ant form 3 */
295 p_dm_path_div->ant_candidate_1 = BB_PATH_AB;
296 p_dm_path_div->ant_candidate_2 = BB_PATH_AC;
297 p_dm_path_div->ant_candidate_3 = BB_PATH_AD;
298 } else if (p_dm_path_div->default_path == PATH_B) {
299 p_dm_path_div->ant_candidate_1 = BB_PATH_AB;
300 p_dm_path_div->ant_candidate_2 = BB_PATH_BC;
301 p_dm_path_div->ant_candidate_3 = BB_PATH_BD;
302 } else if (p_dm_path_div->default_path == PATH_C) {
303 p_dm_path_div->ant_candidate_1 = BB_PATH_AC;
304 p_dm_path_div->ant_candidate_2 = BB_PATH_BC;
305 p_dm_path_div->ant_candidate_3 = BB_PATH_CD;
306 } else if (p_dm_path_div->default_path == PATH_D) {
307 p_dm_path_div->ant_candidate_1 = BB_PATH_AD;
308 p_dm_path_div->ant_candidate_2 = BB_PATH_BD;
309 p_dm_path_div->ant_candidate_3 = BB_PATH_CD;
310 }
311 }
312 }
313 }
314
315
316 void
phydm_dynamic_tx_path(void * p_dm_void)317 phydm_dynamic_tx_path(
318 void *p_dm_void
319 )
320 {
321 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
322 struct _ODM_PATH_DIVERSITY_ *p_dm_path_div = &p_dm->dm_path_div;
323
324 struct sta_info *p_entry;
325 u32 i;
326 u8 num_client = 0;
327 u8 h2c_parameter[6] = {0};
328
329
330 if (!p_dm->is_linked) { /* is_linked==False */
331 PHYDM_DBG(p_dm, DBG_PATH_DIV, ("DTP_8814 [No Link!!!]\n"));
332
333 if (p_dm_path_div->is_become_linked == true) {
334 PHYDM_DBG(p_dm, DBG_PATH_DIV, (" [Be disconnected]----->\n"));
335 p_dm_path_div->is_become_linked = p_dm->is_linked;
336 }
337 return;
338 } else {
339 if (p_dm_path_div->is_become_linked == false) {
340 PHYDM_DBG(p_dm, DBG_PATH_DIV, (" [Be Linked !!!]----->\n"));
341 p_dm_path_div->is_become_linked = p_dm->is_linked;
342 }
343 }
344
345 /* 2 [period CTRL] */
346 if (p_dm_path_div->dtp_period >= 2)
347 p_dm_path_div->dtp_period = 0;
348 else {
349 /* PHYDM_DBG(p_dm,DBG_PATH_DIV, ("Phydm_Dynamic_Tx_Path_8814A() Stay = (( %d ))\n",p_dm_path_div->dtp_period)); */
350 p_dm_path_div->dtp_period++;
351 return;
352 }
353
354
355 /* 2 [Fix path] */
356 if (p_dm->path_select != PHYDM_AUTO_PATH)
357 return;
358
359 /* 2 [Check Bfer] */
360 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
361 #if (BEAMFORMING_SUPPORT == 1)
362 {
363 enum beamforming_cap beamform_cap = (p_dm->beamforming_info.beamform_cap);
364
365 if (beamform_cap & BEAMFORMER_CAP) { /* BFmer On && Div On->Div Off */
366 if (p_dm_path_div->fix_path_bfer == 0) {
367 PHYDM_DBG(p_dm, DBG_PATH_DIV, ("[ PathDiv : OFF ] BFmer ==1\n"));
368 p_dm_path_div->fix_path_bfer = 1 ;
369 }
370 return;
371 } else { /* BFmer Off && Div Off->Div On */
372 if (p_dm_path_div->fix_path_bfer == 1) {
373 PHYDM_DBG(p_dm, DBG_PATH_DIV, ("[ PathDiv : ON ] BFmer ==0\n"));
374 p_dm_path_div->fix_path_bfer = 0;
375 }
376 }
377 }
378 #endif
379 #endif
380
381 if (p_dm_path_div->use_path_a_as_default_ant == 1) {
382 phydm_find_default_path(p_dm);
383 phydm_candidate_dtp_update(p_dm);
384 } else {
385 if (p_dm_path_div->phydm_dtp_state == PHYDM_DTP_INIT) {
386 phydm_find_default_path(p_dm);
387 phydm_candidate_dtp_update(p_dm);
388 p_dm_path_div->phydm_dtp_state = PHYDM_DTP_RUNNING_1;
389 }
390
391 else if (p_dm_path_div->phydm_dtp_state == PHYDM_DTP_RUNNING_1) {
392 p_dm_path_div->dtp_check_patha_counter++;
393
394 if (p_dm_path_div->dtp_check_patha_counter >= NUM_RESET_DTP_PERIOD) {
395 p_dm_path_div->dtp_check_patha_counter = 0;
396 p_dm_path_div->phydm_dtp_state = PHYDM_DTP_INIT;
397 }
398 /* 2 Search space update */
399 else {
400 /* 1. find the worst candidate */
401
402
403 /* 2. repalce the worst candidate */
404 }
405 }
406 }
407
408 /* 2 Dynamic path Selection H2C */
409
410 if (p_dm_path_div->num_candidate == 1)
411 return;
412 else {
413 h2c_parameter[0] = p_dm_path_div->num_candidate;
414 h2c_parameter[1] = p_dm_path_div->num_tx_path;
415 h2c_parameter[2] = p_dm_path_div->ant_candidate_1;
416 h2c_parameter[3] = p_dm_path_div->ant_candidate_2;
417 h2c_parameter[4] = p_dm_path_div->ant_candidate_3;
418
419 odm_fill_h2c_cmd(p_dm, PHYDM_H2C_DYNAMIC_TX_PATH, 6, h2c_parameter);
420 }
421
422 }
423
424
425
426 void
phydm_dynamic_tx_path_init(void * p_dm_void)427 phydm_dynamic_tx_path_init(
428 void *p_dm_void
429 )
430 {
431 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
432 struct _ODM_PATH_DIVERSITY_ *p_dm_path_div = &(p_dm->dm_path_div);
433 struct _ADAPTER *p_adapter = p_dm->adapter;
434 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 };
435 u8 search_space_3[NUM_CHOOSE3_FROM4] = {BB_PATH_BCD, BB_PATH_ACD, BB_PATH_ABD, BB_PATH_ABC};
436
437 #if ((DM_ODM_SUPPORT_TYPE == ODM_WIN) && USB_SWITCH_SUPPORT)
438 p_dm_path_div->is_u3_mode = (*p_dm->hub_usb_mode == 2) ? 1 : 0;
439 PHYDM_DBG(p_dm, DBG_PATH_DIV, ("[WIN USB] is_u3_mode = (( %d ))\n", p_dm_path_div->is_u3_mode));
440 #else
441 p_dm_path_div->is_u3_mode = 1;
442 #endif
443 PHYDM_DBG(p_dm, DBG_PATH_DIV, ("Dynamic TX path Init 8814\n"));
444
445 memcpy(&(p_dm_path_div->search_space_2[0]), &(search_space_2[0]), NUM_CHOOSE2_FROM4);
446 memcpy(&(p_dm_path_div->search_space_3[0]), &(search_space_3[0]), NUM_CHOOSE3_FROM4);
447
448 p_dm_path_div->use_path_a_as_default_ant = 1;
449 p_dm_path_div->phydm_dtp_state = PHYDM_DTP_INIT;
450 p_dm->path_select = PHYDM_AUTO_PATH;
451 p_dm_path_div->phydm_path_div_type = PHYDM_4R_PATH_DIV;
452
453
454 if (p_dm_path_div->is_u3_mode) {
455 p_dm_path_div->num_tx_path = 3;
456 phydm_dtp_fix_tx_path(p_dm, BB_PATH_BCD);/* 3TX Set Init TX path*/
457
458 } else {
459 p_dm_path_div->num_tx_path = 2;
460 phydm_dtp_fix_tx_path(p_dm, BB_PATH_BC);/* 2TX // Set Init TX path*/
461 }
462
463 }
464
465
466 void
phydm_process_rssi_for_path_div(void * p_dm_void,void * p_phy_info_void,void * p_pkt_info_void)467 phydm_process_rssi_for_path_div(
468 void *p_dm_void,
469 void *p_phy_info_void,
470 void *p_pkt_info_void
471 )
472 {
473 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
474 struct phydm_phyinfo_struct *p_phy_info = (struct phydm_phyinfo_struct *)p_phy_info_void;
475 struct phydm_perpkt_info_struct *p_pktinfo = (struct phydm_perpkt_info_struct *)p_pkt_info_void;
476 struct _ODM_PATH_DIVERSITY_ *p_dm_path_div = &(p_dm->dm_path_div);
477
478 if (p_pktinfo->is_packet_to_self || p_pktinfo->is_packet_match_bssid) {
479 if (p_pktinfo->data_rate > ODM_RATE11M) {
480 if (p_dm_path_div->phydm_path_div_type == PHYDM_4R_PATH_DIV) {
481 #if RTL8814A_SUPPORT
482 if (p_dm->support_ic_type & ODM_RTL8814A) {
483 p_dm_path_div->path_a_sum_all += p_phy_info->rx_mimo_signal_strength[0];
484 p_dm_path_div->path_a_cnt_all++;
485
486 p_dm_path_div->path_b_sum_all += p_phy_info->rx_mimo_signal_strength[1];
487 p_dm_path_div->path_b_cnt_all++;
488
489 p_dm_path_div->path_c_sum_all += p_phy_info->rx_mimo_signal_strength[2];
490 p_dm_path_div->path_c_cnt_all++;
491
492 p_dm_path_div->path_d_sum_all += p_phy_info->rx_mimo_signal_strength[3];
493 p_dm_path_div->path_d_cnt_all++;
494 }
495 #endif
496 } else {
497 p_dm_path_div->path_a_sum[p_pktinfo->station_id] += p_phy_info->rx_mimo_signal_strength[0];
498 p_dm_path_div->path_a_cnt[p_pktinfo->station_id]++;
499
500 p_dm_path_div->path_b_sum[p_pktinfo->station_id] += p_phy_info->rx_mimo_signal_strength[1];
501 p_dm_path_div->path_b_cnt[p_pktinfo->station_id]++;
502 }
503 }
504 }
505
506
507 }
508
509 #endif /* #if RTL8814A_SUPPORT */
510
511 void
odm_pathdiv_debug(void * p_dm_void,u32 * const dm_value,u32 * _used,char * output,u32 * _out_len)512 odm_pathdiv_debug(
513 void *p_dm_void,
514 u32 *const dm_value,
515 u32 *_used,
516 char *output,
517 u32 *_out_len
518 )
519 {
520 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
521 struct _ODM_PATH_DIVERSITY_ *p_dm_path_div = &(p_dm->dm_path_div);
522 u32 used = *_used;
523 u32 out_len = *_out_len;
524
525 p_dm->path_select = (dm_value[0] & 0xf);
526 PHYDM_SNPRINTF((output + used, out_len - used, "Path_select = (( 0x%x ))\n", p_dm->path_select));
527
528 /* 2 [Fix path] */
529 if (p_dm->path_select != PHYDM_AUTO_PATH) {
530 PHYDM_SNPRINTF((output + used, out_len - used, "Trun on path [%s%s%s%s]\n",
531 ((p_dm->path_select) & 0x1) ? "A" : "",
532 ((p_dm->path_select) & 0x2) ? "B" : "",
533 ((p_dm->path_select) & 0x4) ? "C" : "",
534 ((p_dm->path_select) & 0x8) ? "D" : ""));
535
536 phydm_dtp_fix_tx_path(p_dm, p_dm->path_select);
537 } else
538 PHYDM_SNPRINTF((output + used, out_len - used, "%s\n", "Auto path"));
539
540 *_used = used;
541 *_out_len = out_len;
542 }
543
544 #endif /* #if(defined(CONFIG_PATH_DIVERSITY)) */
545
546 void
phydm_c2h_dtp_handler(void * p_dm_void,u8 * cmd_buf,u8 cmd_len)547 phydm_c2h_dtp_handler(
548 void *p_dm_void,
549 u8 *cmd_buf,
550 u8 cmd_len
551 )
552 {
553 #if (defined(CONFIG_PATH_DIVERSITY))
554 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
555 struct _ODM_PATH_DIVERSITY_ *p_dm_path_div = &(p_dm->dm_path_div);
556
557 u8 macid = cmd_buf[0];
558 u8 target = cmd_buf[1];
559 u8 nsc_1 = cmd_buf[2];
560 u8 nsc_2 = cmd_buf[3];
561 u8 nsc_3 = cmd_buf[4];
562
563 PHYDM_DBG(p_dm, DBG_PATH_DIV, ("Target_candidate = (( %d ))\n", target));
564 /*
565 if( (nsc_1 >= nsc_2) && (nsc_1 >= nsc_3))
566 {
567 phydm_dtp_fix_tx_path(p_dm, p_dm_path_div->ant_candidate_1);
568 }
569 else if( nsc_2 >= nsc_3)
570 {
571 phydm_dtp_fix_tx_path(p_dm, p_dm_path_div->ant_candidate_2);
572 }
573 else
574 {
575 phydm_dtp_fix_tx_path(p_dm, p_dm_path_div->ant_candidate_3);
576 }
577 */
578 #endif
579 }
580
581 void
odm_path_diversity(void * p_dm_void)582 odm_path_diversity(
583 void *p_dm_void
584 )
585 {
586 #if (defined(CONFIG_PATH_DIVERSITY))
587 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
588
589 if (!(p_dm->support_ability & ODM_BB_PATH_DIV)) {
590 PHYDM_DBG(p_dm, DBG_PATH_DIV, ("Return: Not Support PathDiv\n"));
591 return;
592 }
593
594 #if RTL8812A_SUPPORT
595
596 if (p_dm->support_ic_type & ODM_RTL8812)
597 odm_path_diversity_8812a(p_dm);
598 else
599 #endif
600
601 #if RTL8814A_SUPPORT
602 if (p_dm->support_ic_type & ODM_RTL8814A)
603 phydm_dynamic_tx_path(p_dm);
604 else
605 #endif
606 {}
607 #endif
608 }
609
610 void
phydm_path_diversity_init(void * p_dm_void)611 phydm_path_diversity_init(
612 void *p_dm_void
613 )
614 {
615 #if (defined(CONFIG_PATH_DIVERSITY))
616 struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
617
618 /*p_dm->support_ability |= ODM_BB_PATH_DIV;*/
619
620 if (*(p_dm->p_mp_mode) == true)
621 return;
622
623 if (!(p_dm->support_ability & ODM_BB_PATH_DIV)) {
624 PHYDM_DBG(p_dm, DBG_PATH_DIV, ("Return: Not Support PathDiv\n"));
625 return;
626 }
627
628 #if RTL8812A_SUPPORT
629 if (p_dm->support_ic_type & ODM_RTL8812)
630 odm_path_diversity_init_8812a(p_dm);
631 else
632 #endif
633
634 #if RTL8814A_SUPPORT
635 if (p_dm->support_ic_type & ODM_RTL8814A)
636 phydm_dynamic_tx_path_init(p_dm);
637 else
638 #endif
639 {}
640 #endif
641 }
642
643
644
645 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
646 /*
647 * 2011/12/02 MH Copy from MP oursrc for temporarily test.
648 * */
649
650 void
odm_path_div_chk_ant_switch_callback(struct timer_list * p_timer)651 odm_path_div_chk_ant_switch_callback(
652 struct timer_list *p_timer
653 )
654 {
655 }
656
657 void
odm_path_div_chk_ant_switch_workitem_callback(void * p_context)658 odm_path_div_chk_ant_switch_workitem_callback(
659 void *p_context
660 )
661 {
662 }
663
664 void
odm_cck_tx_path_diversity_callback(struct timer_list * p_timer)665 odm_cck_tx_path_diversity_callback(
666 struct timer_list *p_timer
667 )
668 {
669 }
670
671 void
odm_cck_tx_path_diversity_work_item_callback(void * p_context)672 odm_cck_tx_path_diversity_work_item_callback(
673 void *p_context
674 )
675 {
676 }
677 u8
odm_sw_ant_div_select_scan_chnl(struct _ADAPTER * adapter)678 odm_sw_ant_div_select_scan_chnl(
679 struct _ADAPTER *adapter
680 )
681 {
682 return 0;
683 }
684 void
odm_sw_ant_div_construct_scan_chnl(struct _ADAPTER * adapter,u8 scan_chnl)685 odm_sw_ant_div_construct_scan_chnl(
686 struct _ADAPTER *adapter,
687 u8 scan_chnl
688 )
689 {
690 }
691
692 #endif /* #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) */
693