xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/rtl8723bs/hal/phydm/phydm_pathdiv.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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