xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8822cs/hal/phydm/phydm_antdect.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /******************************************************************************
2*4882a593Smuzhiyun  *
3*4882a593Smuzhiyun  * Copyright(c) 2007 - 2017  Realtek Corporation.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * This program is free software; you can redistribute it and/or modify it
6*4882a593Smuzhiyun  * under the terms of version 2 of the GNU General Public License as
7*4882a593Smuzhiyun  * published by the Free Software Foundation.
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  * This program is distributed in the hope that it will be useful, but WITHOUT
10*4882a593Smuzhiyun  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11*4882a593Smuzhiyun  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12*4882a593Smuzhiyun  * more details.
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  * The full GNU General Public License is included in this distribution in the
15*4882a593Smuzhiyun  * file called LICENSE.
16*4882a593Smuzhiyun  *
17*4882a593Smuzhiyun  * Contact Information:
18*4882a593Smuzhiyun  * wlanfae <wlanfae@realtek.com>
19*4882a593Smuzhiyun  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20*4882a593Smuzhiyun  * Hsinchu 300, Taiwan.
21*4882a593Smuzhiyun  *
22*4882a593Smuzhiyun  * Larry Finger <Larry.Finger@lwfinger.net>
23*4882a593Smuzhiyun  *
24*4882a593Smuzhiyun  *****************************************************************************/
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun /* ************************************************************
27*4882a593Smuzhiyun  * include files
28*4882a593Smuzhiyun  * ************************************************************ */
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #include "mp_precomp.h"
31*4882a593Smuzhiyun #include "phydm_precomp.h"
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun #ifdef CONFIG_ANT_DETECTION
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun /* @IS_ANT_DETECT_SUPPORT_SINGLE_TONE(adapter)
36*4882a593Smuzhiyun  * IS_ANT_DETECT_SUPPORT_RSSI(adapter)
37*4882a593Smuzhiyun  * IS_ANT_DETECT_SUPPORT_PSD(adapter) */
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun /* @1 [1. Single Tone method] =================================================== */
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun /*@
42*4882a593Smuzhiyun  * Description:
43*4882a593Smuzhiyun  *	Set Single/Dual Antenna default setting for products that do not do detection in advance.
44*4882a593Smuzhiyun  *
45*4882a593Smuzhiyun  * Added by Joseph, 2012.03.22
46*4882a593Smuzhiyun  *   */
odm_sw_ant_div_construct_scan_chnl(void * adapter,u8 scan_chnl)47*4882a593Smuzhiyun void odm_sw_ant_div_construct_scan_chnl(
48*4882a593Smuzhiyun 	void *adapter,
49*4882a593Smuzhiyun 	u8 scan_chnl)
50*4882a593Smuzhiyun {
51*4882a593Smuzhiyun }
52*4882a593Smuzhiyun 
odm_sw_ant_div_select_scan_chnl(void * adapter)53*4882a593Smuzhiyun u8 odm_sw_ant_div_select_scan_chnl(
54*4882a593Smuzhiyun 	void *adapter)
55*4882a593Smuzhiyun {
56*4882a593Smuzhiyun 	return 0;
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun 
odm_single_dual_antenna_default_setting(void * dm_void)59*4882a593Smuzhiyun void odm_single_dual_antenna_default_setting(
60*4882a593Smuzhiyun 	void *dm_void)
61*4882a593Smuzhiyun {
62*4882a593Smuzhiyun 	struct dm_struct *dm = (struct dm_struct *)dm_void;
63*4882a593Smuzhiyun 	struct sw_antenna_switch *dm_swat_table = &dm->dm_swat_table;
64*4882a593Smuzhiyun 	void *adapter = dm->adapter;
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 	u8 bt_ant_num = BT_GetPgAntNum(adapter);
67*4882a593Smuzhiyun 	/* Set default antenna A and B status */
68*4882a593Smuzhiyun 	if (bt_ant_num == 2) {
69*4882a593Smuzhiyun 		dm_swat_table->ANTA_ON = true;
70*4882a593Smuzhiyun 		dm_swat_table->ANTB_ON = true;
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun 	} else if (bt_ant_num == 1) {
73*4882a593Smuzhiyun 		/* Set antenna A as default */
74*4882a593Smuzhiyun 		dm_swat_table->ANTA_ON = true;
75*4882a593Smuzhiyun 		dm_swat_table->ANTB_ON = false;
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun 	} else
78*4882a593Smuzhiyun 		RT_ASSERT(false, ("Incorrect antenna number!!\n"));
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun /* @2 8723A ANT DETECT
82*4882a593Smuzhiyun  *
83*4882a593Smuzhiyun  * Description:
84*4882a593Smuzhiyun  *	Implement IQK single tone for RF DPK loopback and BB PSD scanning.
85*4882a593Smuzhiyun  *	This function is cooperated with BB team Neil.
86*4882a593Smuzhiyun  *
87*4882a593Smuzhiyun  * Added by Roger, 2011.12.15
88*4882a593Smuzhiyun  *   */
89*4882a593Smuzhiyun boolean
odm_single_dual_antenna_detection(void * dm_void,u8 mode)90*4882a593Smuzhiyun odm_single_dual_antenna_detection(
91*4882a593Smuzhiyun 	void *dm_void,
92*4882a593Smuzhiyun 	u8 mode)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun 	struct dm_struct *dm = (struct dm_struct *)dm_void;
95*4882a593Smuzhiyun 	void *adapter = dm->adapter;
96*4882a593Smuzhiyun 	struct sw_antenna_switch *dm_swat_table = &dm->dm_swat_table;
97*4882a593Smuzhiyun 	u32 current_channel, rf_loop_reg;
98*4882a593Smuzhiyun 	u8 n;
99*4882a593Smuzhiyun 	u32 reg88c, regc08, reg874, regc50, reg948, regb2c, reg92c, reg930, reg064, afe_rrx_wait_cca;
100*4882a593Smuzhiyun 	u8 initial_gain = 0x5a;
101*4882a593Smuzhiyun 	u32 PSD_report_tmp;
102*4882a593Smuzhiyun 	u32 ant_a_report = 0x0, ant_b_report = 0x0, ant_0_report = 0x0;
103*4882a593Smuzhiyun 	boolean is_result = true;
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun 	PHYDM_DBG(dm, DBG_ANT_DIV, "%s============>\n", __func__);
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 	if (!(dm->support_ic_type & ODM_RTL8723B))
108*4882a593Smuzhiyun 		return is_result;
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun 	/* Retrieve antenna detection registry info, added by Roger, 2012.11.27. */
111*4882a593Smuzhiyun 	if (!IS_ANT_DETECT_SUPPORT_SINGLE_TONE(((PADAPTER)adapter)))
112*4882a593Smuzhiyun 		return is_result;
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun 	/* @1 Backup Current RF/BB Settings */
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	current_channel = odm_get_rf_reg(dm, RF_PATH_A, ODM_CHANNEL, RFREGOFFSETMASK);
117*4882a593Smuzhiyun 	rf_loop_reg = odm_get_rf_reg(dm, RF_PATH_A, RF_0x00, RFREGOFFSETMASK);
118*4882a593Smuzhiyun 	if (dm->support_ic_type & ODM_RTL8723B) {
119*4882a593Smuzhiyun 		reg92c = odm_get_bb_reg(dm, REG_DPDT_CONTROL, MASKDWORD);
120*4882a593Smuzhiyun 		reg930 = odm_get_bb_reg(dm, rfe_ctrl_anta_src, MASKDWORD);
121*4882a593Smuzhiyun 		reg948 = odm_get_bb_reg(dm, REG_S0_S1_PATH_SWITCH, MASKDWORD);
122*4882a593Smuzhiyun 		regb2c = odm_get_bb_reg(dm, REG_AGC_TABLE_SELECT, MASKDWORD);
123*4882a593Smuzhiyun 		reg064 = odm_get_mac_reg(dm, REG_SYM_WLBT_PAPE_SEL, BIT(29));
124*4882a593Smuzhiyun 		odm_set_bb_reg(dm, REG_DPDT_CONTROL, 0x3, 0x1);
125*4882a593Smuzhiyun 		odm_set_bb_reg(dm, rfe_ctrl_anta_src, 0xff, 0x77);
126*4882a593Smuzhiyun 		odm_set_mac_reg(dm, REG_SYM_WLBT_PAPE_SEL, BIT(29), 0x1); /* @dbg 7 */
127*4882a593Smuzhiyun 		odm_set_bb_reg(dm, REG_S0_S1_PATH_SWITCH, 0x3c0, 0x0); /* @dbg 8 */
128*4882a593Smuzhiyun 		odm_set_bb_reg(dm, REG_AGC_TABLE_SELECT, BIT(31), 0x0);
129*4882a593Smuzhiyun 	}
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 	ODM_delay_us(10);
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 	/* Store A path Register 88c, c08, 874, c50 */
134*4882a593Smuzhiyun 	reg88c = odm_get_bb_reg(dm, REG_FPGA0_ANALOG_PARAMETER4, MASKDWORD);
135*4882a593Smuzhiyun 	regc08 = odm_get_bb_reg(dm, REG_OFDM_0_TR_MUX_PAR, MASKDWORD);
136*4882a593Smuzhiyun 	reg874 = odm_get_bb_reg(dm, REG_FPGA0_XCD_RF_INTERFACE_SW, MASKDWORD);
137*4882a593Smuzhiyun 	regc50 = odm_get_bb_reg(dm, REG_OFDM_0_XA_AGC_CORE1, MASKDWORD);
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 	/* Store AFE Registers */
140*4882a593Smuzhiyun 	if (dm->support_ic_type & ODM_RTL8723B)
141*4882a593Smuzhiyun 		afe_rrx_wait_cca = odm_get_bb_reg(dm, REG_RX_WAIT_CCA, MASKDWORD);
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 	/* Set PSD 128 pts */
144*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_FPGA0_PSD_FUNCTION, BIT(14) | BIT15, 0x0); /* @128 pts */
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun 	/* To SET CH1 to do */
147*4882a593Smuzhiyun 	odm_set_rf_reg(dm, RF_PATH_A, ODM_CHANNEL, RFREGOFFSETMASK, 0x7401); /* @channel 1 */
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	/* @AFE all on step */
150*4882a593Smuzhiyun 	if (dm->support_ic_type & ODM_RTL8723B)
151*4882a593Smuzhiyun 		odm_set_bb_reg(dm, REG_RX_WAIT_CCA, MASKDWORD, 0x01c00016);
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	/* @3 wire Disable */
154*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_FPGA0_ANALOG_PARAMETER4, MASKDWORD, 0xCCF000C0);
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun 	/* @BB IQK setting */
157*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_OFDM_0_TR_MUX_PAR, MASKDWORD, 0x000800E4);
158*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_FPGA0_XCD_RF_INTERFACE_SW, MASKDWORD, 0x22208000);
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun 	/* @IQK setting tone@ 4.34Mhz */
161*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_TX_IQK_TONE_A, MASKDWORD, 0x10008C1C);
162*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_TX_IQK, MASKDWORD, 0x01007c00);
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun 	/* Page B init */
165*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_CONFIG_ANT_A, MASKDWORD, 0x00080000);
166*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_CONFIG_ANT_A, MASKDWORD, 0x0f600000);
167*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_RX_IQK, MASKDWORD, 0x01004800);
168*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_RX_IQK_TONE_A, MASKDWORD, 0x10008c1f);
169*4882a593Smuzhiyun 	if (dm->support_ic_type & ODM_RTL8723B) {
170*4882a593Smuzhiyun 		odm_set_bb_reg(dm, REG_TX_IQK_PI_A, MASKDWORD, 0x82150016);
171*4882a593Smuzhiyun 		odm_set_bb_reg(dm, REG_RX_IQK_PI_A, MASKDWORD, 0x28150016);
172*4882a593Smuzhiyun 	}
173*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_IQK_AGC_RSP, MASKDWORD, 0x001028d0);
174*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_OFDM_0_XA_AGC_CORE1, 0x7f, initial_gain);
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 	/* @IQK Single tone start */
177*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_FPGA0_IQK, 0xffffff00, 0x808000);
178*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_IQK_AGC_PTS, MASKDWORD, 0xf9000000);
179*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_IQK_AGC_PTS, MASKDWORD, 0xf8000000);
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 	ODM_delay_us(10000);
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun 	/* PSD report of antenna A */
184*4882a593Smuzhiyun 	PSD_report_tmp = 0x0;
185*4882a593Smuzhiyun 	for (n = 0; n < 2; n++) {
186*4882a593Smuzhiyun 		PSD_report_tmp = phydm_get_psd_data(dm, 14, initial_gain);
187*4882a593Smuzhiyun 		if (PSD_report_tmp > ant_a_report)
188*4882a593Smuzhiyun 			ant_a_report = PSD_report_tmp;
189*4882a593Smuzhiyun 	}
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun 	/* @change to Antenna B */
192*4882a593Smuzhiyun 	if (dm->support_ic_type & ODM_RTL8723B) {
193*4882a593Smuzhiyun 		odm_set_bb_reg(dm, REG_S0_S1_PATH_SWITCH, 0xfff, 0x280);
194*4882a593Smuzhiyun 		odm_set_bb_reg(dm, REG_AGC_TABLE_SELECT, BIT(31), 0x1);
195*4882a593Smuzhiyun 	}
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	ODM_delay_us(10);
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 	/* PSD report of antenna B */
200*4882a593Smuzhiyun 	PSD_report_tmp = 0x0;
201*4882a593Smuzhiyun 	for (n = 0; n < 2; n++) {
202*4882a593Smuzhiyun 		PSD_report_tmp = phydm_get_psd_data(dm, 14, initial_gain);
203*4882a593Smuzhiyun 		if (PSD_report_tmp > ant_b_report)
204*4882a593Smuzhiyun 			ant_b_report = PSD_report_tmp;
205*4882a593Smuzhiyun 	}
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun 	/* @Close IQK Single Tone function */
208*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_FPGA0_IQK, 0xffffff00, 0x000000);
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun 	/* @1 Return to antanna A */
211*4882a593Smuzhiyun 	if (dm->support_ic_type & ODM_RTL8723B) {
212*4882a593Smuzhiyun 		/* @external DPDT */
213*4882a593Smuzhiyun 		odm_set_bb_reg(dm, REG_DPDT_CONTROL, MASKDWORD, reg92c);
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 		/* @internal S0/S1 */
216*4882a593Smuzhiyun 		odm_set_bb_reg(dm, REG_S0_S1_PATH_SWITCH, MASKDWORD, reg948);
217*4882a593Smuzhiyun 		odm_set_bb_reg(dm, REG_AGC_TABLE_SELECT, MASKDWORD, regb2c);
218*4882a593Smuzhiyun 		odm_set_bb_reg(dm, rfe_ctrl_anta_src, MASKDWORD, reg930);
219*4882a593Smuzhiyun 		odm_set_mac_reg(dm, REG_SYM_WLBT_PAPE_SEL, BIT(29), reg064);
220*4882a593Smuzhiyun 	}
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_FPGA0_ANALOG_PARAMETER4, MASKDWORD, reg88c);
223*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_OFDM_0_TR_MUX_PAR, MASKDWORD, regc08);
224*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_FPGA0_XCD_RF_INTERFACE_SW, MASKDWORD, reg874);
225*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_OFDM_0_XA_AGC_CORE1, 0x7F, 0x40);
226*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_OFDM_0_XA_AGC_CORE1, MASKDWORD, regc50);
227*4882a593Smuzhiyun 	odm_set_rf_reg(dm, RF_PATH_A, RF_CHNLBW, RFREGOFFSETMASK, current_channel);
228*4882a593Smuzhiyun 	odm_set_rf_reg(dm, RF_PATH_A, RF_0x00, RFREGOFFSETMASK, rf_loop_reg);
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 	/* Reload AFE Registers */
231*4882a593Smuzhiyun 	if (dm->support_ic_type & ODM_RTL8723B)
232*4882a593Smuzhiyun 		odm_set_bb_reg(dm, REG_RX_WAIT_CCA, MASKDWORD, afe_rrx_wait_cca);
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 	if (dm->support_ic_type & ODM_RTL8723B) {
235*4882a593Smuzhiyun 		PHYDM_DBG(dm, DBG_ANT_DIV, "psd_report_A[%d]= %d\n", 2416,
236*4882a593Smuzhiyun 			  ant_a_report);
237*4882a593Smuzhiyun 		PHYDM_DBG(dm, DBG_ANT_DIV, "psd_report_B[%d]= %d\n", 2416,
238*4882a593Smuzhiyun 			  ant_b_report);
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 		/* @2 Test ant B based on ant A is ON */
241*4882a593Smuzhiyun 		if (ant_a_report >= 100 && ant_b_report >= 100 && ant_a_report <= 135 && ant_b_report <= 135) {
242*4882a593Smuzhiyun 			u8 TH1 = 2, TH2 = 6;
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun 			if ((ant_a_report - ant_b_report < TH1) || (ant_b_report - ant_a_report < TH1)) {
245*4882a593Smuzhiyun 				dm_swat_table->ANTA_ON = true;
246*4882a593Smuzhiyun 				dm_swat_table->ANTB_ON = true;
247*4882a593Smuzhiyun 				PHYDM_DBG(dm, DBG_ANT_DIV, "%s: Dual Antenna\n",
248*4882a593Smuzhiyun 					  __func__);
249*4882a593Smuzhiyun 			} else if (((ant_a_report - ant_b_report >= TH1) && (ant_a_report - ant_b_report <= TH2)) ||
250*4882a593Smuzhiyun 				   ((ant_b_report - ant_a_report >= TH1) && (ant_b_report - ant_a_report <= TH2))) {
251*4882a593Smuzhiyun 				dm_swat_table->ANTA_ON = false;
252*4882a593Smuzhiyun 				dm_swat_table->ANTB_ON = false;
253*4882a593Smuzhiyun 				is_result = false;
254*4882a593Smuzhiyun 				PHYDM_DBG(dm, DBG_ANT_DIV,
255*4882a593Smuzhiyun 					  "%s: Need to check again\n",
256*4882a593Smuzhiyun 					  __func__);
257*4882a593Smuzhiyun 			} else {
258*4882a593Smuzhiyun 				dm_swat_table->ANTA_ON = true;
259*4882a593Smuzhiyun 				dm_swat_table->ANTB_ON = false;
260*4882a593Smuzhiyun 				PHYDM_DBG(dm, DBG_ANT_DIV,
261*4882a593Smuzhiyun 					  "%s: Single Antenna\n", __func__);
262*4882a593Smuzhiyun 			}
263*4882a593Smuzhiyun 			dm->ant_detected_info.is_ant_detected = true;
264*4882a593Smuzhiyun 			dm->ant_detected_info.db_for_ant_a = ant_a_report;
265*4882a593Smuzhiyun 			dm->ant_detected_info.db_for_ant_b = ant_b_report;
266*4882a593Smuzhiyun 			dm->ant_detected_info.db_for_ant_o = ant_0_report;
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 		} else {
269*4882a593Smuzhiyun 			PHYDM_DBG(dm, DBG_ANT_DIV, "return false!!\n");
270*4882a593Smuzhiyun 			is_result = false;
271*4882a593Smuzhiyun 		}
272*4882a593Smuzhiyun 	}
273*4882a593Smuzhiyun 	return is_result;
274*4882a593Smuzhiyun }
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun /* @1 [2. Scan AP RSSI method] ================================================== */
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun boolean
odm_sw_ant_div_check_before_link(void * dm_void)279*4882a593Smuzhiyun odm_sw_ant_div_check_before_link(
280*4882a593Smuzhiyun 	void *dm_void)
281*4882a593Smuzhiyun {
282*4882a593Smuzhiyun #if (RT_MEM_SIZE_LEVEL != RT_MEM_SIZE_MINIMUM)
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun 	struct dm_struct *dm = (struct dm_struct *)dm_void;
285*4882a593Smuzhiyun 	void *adapter = dm->adapter;
286*4882a593Smuzhiyun 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter));
287*4882a593Smuzhiyun 	//PMGNT_INFO		mgnt_info = &adapter->MgntInfo;
288*4882a593Smuzhiyun 	PMGNT_INFO mgnt_info = &(((PADAPTER)(adapter))->MgntInfo);
289*4882a593Smuzhiyun 	struct sw_antenna_switch *dm_swat_table = &dm->dm_swat_table;
290*4882a593Smuzhiyun 	struct phydm_fat_struct *fat_tab = &dm->dm_fat_table;
291*4882a593Smuzhiyun 	s8 score = 0;
292*4882a593Smuzhiyun 	PRT_WLAN_BSS p_tmp_bss_desc, p_test_bss_desc;
293*4882a593Smuzhiyun 	u8 power_target_L = 9, power_target_H = 16;
294*4882a593Smuzhiyun 	u8 tmp_power_diff = 0, power_diff = 0, avg_power_diff = 0, max_power_diff = 0, min_power_diff = 0xff;
295*4882a593Smuzhiyun 	u16 index, counter = 0;
296*4882a593Smuzhiyun 	static u8 scan_channel;
297*4882a593Smuzhiyun 	u32 tmp_swas_no_link_bk_reg948;
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 	PHYDM_DBG(dm, DBG_ANT_DIV, "ANTA_ON = (( %d )) , ANTB_ON = (( %d ))\n",
300*4882a593Smuzhiyun 		  dm->dm_swat_table.ANTA_ON, dm->dm_swat_table.ANTB_ON);
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 	/* @if(HP id) */
303*4882a593Smuzhiyun 	{
304*4882a593Smuzhiyun 		if (dm->dm_swat_table.rssi_ant_dect_result == true && dm->support_ic_type == ODM_RTL8723B) {
305*4882a593Smuzhiyun 			PHYDM_DBG(dm, DBG_ANT_DIV,
306*4882a593Smuzhiyun 				  "8723B RSSI-based Antenna Detection is done\n");
307*4882a593Smuzhiyun 			return false;
308*4882a593Smuzhiyun 		}
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun 		if (dm->support_ic_type == ODM_RTL8723B) {
311*4882a593Smuzhiyun 			if (dm_swat_table->swas_no_link_bk_reg948 == 0xff)
312*4882a593Smuzhiyun 				dm_swat_table->swas_no_link_bk_reg948 = odm_read_4byte(dm, REG_S0_S1_PATH_SWITCH);
313*4882a593Smuzhiyun 		}
314*4882a593Smuzhiyun 	}
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun 	if (dm->adapter == NULL) { /* @For BSOD when plug/unplug fast.  //By YJ,120413 */
317*4882a593Smuzhiyun 		/* The ODM structure is not initialized. */
318*4882a593Smuzhiyun 		return false;
319*4882a593Smuzhiyun 	}
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun 	/* Retrieve antenna detection registry info, added by Roger, 2012.11.27. */
322*4882a593Smuzhiyun 	if (!IS_ANT_DETECT_SUPPORT_RSSI(((PADAPTER)adapter)))
323*4882a593Smuzhiyun 		return false;
324*4882a593Smuzhiyun 	else
325*4882a593Smuzhiyun 		PHYDM_DBG(dm, DBG_ANT_DIV, "Antenna Detection: RSSI method\n");
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun 	/* Since driver is going to set BB register, it shall check if there is another thread controlling BB/RF. */
328*4882a593Smuzhiyun 	odm_acquire_spin_lock(dm, RT_RF_STATE_SPINLOCK);
329*4882a593Smuzhiyun 	if (hal_data->eRFPowerState != eRfOn || mgnt_info->RFChangeInProgress || mgnt_info->bMediaConnect) {
330*4882a593Smuzhiyun 		odm_release_spin_lock(dm, RT_RF_STATE_SPINLOCK);
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun 		PHYDM_DBG(dm, DBG_ANT_DIV,
333*4882a593Smuzhiyun 			  "%s: rf_change_in_progress(%x), e_rf_power_state(%x)\n",
334*4882a593Smuzhiyun 			  __func__, mgnt_info->RFChangeInProgress,
335*4882a593Smuzhiyun 			  hal_data->eRFPowerState);
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun 		dm_swat_table->swas_no_link_state = 0;
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 		return false;
340*4882a593Smuzhiyun 	} else
341*4882a593Smuzhiyun 		odm_release_spin_lock(dm, RT_RF_STATE_SPINLOCK);
342*4882a593Smuzhiyun 	PHYDM_DBG(dm, DBG_ANT_DIV, "dm_swat_table->swas_no_link_state = %d\n",
343*4882a593Smuzhiyun 		  dm_swat_table->swas_no_link_state);
344*4882a593Smuzhiyun 	/* @1 Run AntDiv mechanism "Before Link" part. */
345*4882a593Smuzhiyun 	if (dm_swat_table->swas_no_link_state == 0) {
346*4882a593Smuzhiyun 		/* @1 Prepare to do Scan again to check current antenna state. */
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun 		/* Set check state to next step. */
349*4882a593Smuzhiyun 		dm_swat_table->swas_no_link_state = 1;
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun 		/* @Copy Current Scan list. */
352*4882a593Smuzhiyun 		mgnt_info->tmpNumBssDesc = mgnt_info->NumBssDesc;
353*4882a593Smuzhiyun 		PlatformMoveMemory((void *)mgnt_info->tmpbssDesc, (void *)mgnt_info->bssDesc, sizeof(RT_WLAN_BSS) * MAX_BSS_DESC);
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun 		/* @Go back to scan function again. */
356*4882a593Smuzhiyun 		PHYDM_DBG(dm, DBG_ANT_DIV, "%s: Scan one more time\n",
357*4882a593Smuzhiyun 			  __func__);
358*4882a593Smuzhiyun 		mgnt_info->ScanStep = 0;
359*4882a593Smuzhiyun 		mgnt_info->bScanAntDetect = true;
360*4882a593Smuzhiyun 		scan_channel = odm_sw_ant_div_select_scan_chnl(adapter);
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun 		if (dm->support_ic_type & (ODM_RTL8188E | ODM_RTL8821)) {
363*4882a593Smuzhiyun 			if (fat_tab->rx_idle_ant == MAIN_ANT)
364*4882a593Smuzhiyun 				odm_update_rx_idle_ant(dm, AUX_ANT);
365*4882a593Smuzhiyun 			else
366*4882a593Smuzhiyun 				odm_update_rx_idle_ant(dm, MAIN_ANT);
367*4882a593Smuzhiyun 			if (scan_channel == 0) {
368*4882a593Smuzhiyun 				PHYDM_DBG(dm, DBG_ANT_DIV,
369*4882a593Smuzhiyun 					  "%s: No AP List Avaiable, Using ant(%s)\n",
370*4882a593Smuzhiyun 					  __func__,
371*4882a593Smuzhiyun 					  (fat_tab->rx_idle_ant == MAIN_ANT) ?
372*4882a593Smuzhiyun 					  "AUX_ANT" : "MAIN_ANT");
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun 				if (IS_5G_WIRELESS_MODE(mgnt_info->dot11CurrentWirelessMode)) {
375*4882a593Smuzhiyun 					dm_swat_table->ant_5g = fat_tab->rx_idle_ant;
376*4882a593Smuzhiyun 					PHYDM_DBG(dm, DBG_ANT_DIV, "dm_swat_table->ant_5g=%s\n", (fat_tab->rx_idle_ant == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT");
377*4882a593Smuzhiyun 				} else {
378*4882a593Smuzhiyun 					dm_swat_table->ant_2g = fat_tab->rx_idle_ant;
379*4882a593Smuzhiyun 					PHYDM_DBG(dm, DBG_ANT_DIV, "dm_swat_table->ant_2g=%s\n", (fat_tab->rx_idle_ant == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT");
380*4882a593Smuzhiyun 				}
381*4882a593Smuzhiyun 				return false;
382*4882a593Smuzhiyun 			}
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun 			PHYDM_DBG(dm, DBG_ANT_DIV,
385*4882a593Smuzhiyun 				  "%s: Change to %s for testing.\n", __func__,
386*4882a593Smuzhiyun 				  ((fat_tab->rx_idle_ant == MAIN_ANT) ?
387*4882a593Smuzhiyun 				  "MAIN_ANT" : "AUX_ANT"));
388*4882a593Smuzhiyun 		} else if (dm->support_ic_type & (ODM_RTL8723B)) {
389*4882a593Smuzhiyun 			/*Switch Antenna to another one.*/
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 			tmp_swas_no_link_bk_reg948 = odm_read_4byte(dm, REG_S0_S1_PATH_SWITCH);
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun 			if (dm_swat_table->cur_antenna == MAIN_ANT && tmp_swas_no_link_bk_reg948 == 0x200) {
394*4882a593Smuzhiyun 				odm_set_bb_reg(dm, REG_S0_S1_PATH_SWITCH, 0xfff, 0x280);
395*4882a593Smuzhiyun 				odm_set_bb_reg(dm, REG_AGC_TABLE_SELECT, BIT(31), 0x1);
396*4882a593Smuzhiyun 				dm_swat_table->cur_antenna = AUX_ANT;
397*4882a593Smuzhiyun 			} else {
398*4882a593Smuzhiyun 				PHYDM_DBG(dm, DBG_ANT_DIV,
399*4882a593Smuzhiyun 					  "Reg[948]= (( %x )) was in wrong state\n",
400*4882a593Smuzhiyun 					  tmp_swas_no_link_bk_reg948);
401*4882a593Smuzhiyun 				return false;
402*4882a593Smuzhiyun 			}
403*4882a593Smuzhiyun 			ODM_delay_us(10);
404*4882a593Smuzhiyun 
405*4882a593Smuzhiyun 			PHYDM_DBG(dm, DBG_ANT_DIV,
406*4882a593Smuzhiyun 				  "%s: Change to (( %s-ant))  for testing.\n",
407*4882a593Smuzhiyun 				  __func__,
408*4882a593Smuzhiyun 				  (dm_swat_table->cur_antenna == MAIN_ANT) ?
409*4882a593Smuzhiyun 				  "MAIN" : "AUX");
410*4882a593Smuzhiyun 		}
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun 		odm_sw_ant_div_construct_scan_chnl(adapter, scan_channel);
413*4882a593Smuzhiyun 		PlatformSetTimer(adapter, &mgnt_info->ScanTimer, 5);
414*4882a593Smuzhiyun 
415*4882a593Smuzhiyun 		return true;
416*4882a593Smuzhiyun 	} else { /* @dm_swat_table->swas_no_link_state == 1 */
417*4882a593Smuzhiyun 		/* @1 ScanComple() is called after antenna swiched. */
418*4882a593Smuzhiyun 		/* @1 Check scan result and determine which antenna is going */
419*4882a593Smuzhiyun 		/* @1 to be used. */
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 		PHYDM_DBG(dm, DBG_ANT_DIV, " tmp_num_bss_desc= (( %d ))\n",
422*4882a593Smuzhiyun 			  mgnt_info->tmpNumBssDesc); /* @debug for Dino */
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun 		for (index = 0; index < mgnt_info->tmpNumBssDesc; index++) {
425*4882a593Smuzhiyun 			p_tmp_bss_desc = &mgnt_info->tmpbssDesc[index]; /* @Antenna 1 */
426*4882a593Smuzhiyun 			p_test_bss_desc = &mgnt_info->bssDesc[index]; /* @Antenna 2 */
427*4882a593Smuzhiyun 
428*4882a593Smuzhiyun 			if (PlatformCompareMemory(p_test_bss_desc->bdBssIdBuf, p_tmp_bss_desc->bdBssIdBuf, 6) != 0) {
429*4882a593Smuzhiyun 				PHYDM_DBG(dm, DBG_ANT_DIV,
430*4882a593Smuzhiyun 					  "%s: ERROR!! This shall not happen.\n",
431*4882a593Smuzhiyun 					  __func__);
432*4882a593Smuzhiyun 				continue;
433*4882a593Smuzhiyun 			}
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun 			if (dm->support_ic_type != ODM_RTL8723B) {
436*4882a593Smuzhiyun 				if (p_tmp_bss_desc->ChannelNumber == scan_channel) {
437*4882a593Smuzhiyun 					if (p_tmp_bss_desc->RecvSignalPower > p_test_bss_desc->RecvSignalPower) {
438*4882a593Smuzhiyun 						PHYDM_DBG(dm, DBG_ANT_DIV, "%s: Compare scan entry: score++\n", __func__);
439*4882a593Smuzhiyun 						RT_PRINT_STR(COMP_SCAN, DBG_WARNING, "GetScanInfo(): new Bss SSID:", p_tmp_bss_desc->bdSsIdBuf, p_tmp_bss_desc->bdSsIdLen);
440*4882a593Smuzhiyun 						PHYDM_DBG(dm, DBG_ANT_DIV, "at ch %d, Original: %d, Test: %d\n\n", p_tmp_bss_desc->ChannelNumber, p_tmp_bss_desc->RecvSignalPower, p_test_bss_desc->RecvSignalPower);
441*4882a593Smuzhiyun 
442*4882a593Smuzhiyun 						score++;
443*4882a593Smuzhiyun 						PlatformMoveMemory(p_test_bss_desc, p_tmp_bss_desc, sizeof(RT_WLAN_BSS));
444*4882a593Smuzhiyun 					} else if (p_tmp_bss_desc->RecvSignalPower < p_test_bss_desc->RecvSignalPower) {
445*4882a593Smuzhiyun 						PHYDM_DBG(dm, DBG_ANT_DIV, "%s: Compare scan entry: score--\n", __func__);
446*4882a593Smuzhiyun 						RT_PRINT_STR(COMP_SCAN, DBG_WARNING, "GetScanInfo(): new Bss SSID:", p_tmp_bss_desc->bdSsIdBuf, p_tmp_bss_desc->bdSsIdLen);
447*4882a593Smuzhiyun 						PHYDM_DBG(dm, DBG_ANT_DIV, "at ch %d, Original: %d, Test: %d\n\n", p_tmp_bss_desc->ChannelNumber, p_tmp_bss_desc->RecvSignalPower, p_test_bss_desc->RecvSignalPower);
448*4882a593Smuzhiyun 						score--;
449*4882a593Smuzhiyun 					} else {
450*4882a593Smuzhiyun 						if (p_test_bss_desc->bdTstamp - p_tmp_bss_desc->bdTstamp < 5000) {
451*4882a593Smuzhiyun 							RT_PRINT_STR(COMP_SCAN, DBG_WARNING, "GetScanInfo(): new Bss SSID:", p_tmp_bss_desc->bdSsIdBuf, p_tmp_bss_desc->bdSsIdLen);
452*4882a593Smuzhiyun 							PHYDM_DBG(dm, DBG_ANT_DIV, "at ch %d, Original: %d, Test: %d\n", p_tmp_bss_desc->ChannelNumber, p_tmp_bss_desc->RecvSignalPower, p_test_bss_desc->RecvSignalPower);
453*4882a593Smuzhiyun 							PHYDM_DBG(dm, DBG_ANT_DIV, "The 2nd Antenna didn't get this AP\n\n");
454*4882a593Smuzhiyun 						}
455*4882a593Smuzhiyun 					}
456*4882a593Smuzhiyun 				}
457*4882a593Smuzhiyun 			} else { /* @8723B */
458*4882a593Smuzhiyun 				if (p_tmp_bss_desc->ChannelNumber == scan_channel) {
459*4882a593Smuzhiyun 					PHYDM_DBG(dm, DBG_ANT_DIV, "channel_number == scan_channel->(( %d ))\n", p_tmp_bss_desc->ChannelNumber);
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun 					if (p_tmp_bss_desc->RecvSignalPower > p_test_bss_desc->RecvSignalPower) { /* Pow(Ant1) > Pow(Ant2) */
462*4882a593Smuzhiyun 						counter++;
463*4882a593Smuzhiyun 						tmp_power_diff = (u8)(p_tmp_bss_desc->RecvSignalPower - p_test_bss_desc->RecvSignalPower);
464*4882a593Smuzhiyun 						power_diff = power_diff + tmp_power_diff;
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun 						PHYDM_DBG(dm, DBG_ANT_DIV, "Original: %d, Test: %d\n", p_tmp_bss_desc->RecvSignalPower, p_test_bss_desc->RecvSignalPower);
467*4882a593Smuzhiyun 						PHYDM_PRINT_ADDR(dm, DBG_ANT_DIV, "SSID:", p_tmp_bss_desc->bdSsIdBuf);
468*4882a593Smuzhiyun 						PHYDM_PRINT_ADDR(dm, DBG_ANT_DIV, "BSSID:", p_tmp_bss_desc->bdSsIdBuf);
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun #if 0
471*4882a593Smuzhiyun 						/* PHYDM_DBG(dm,DBG_ANT_DIV, "tmp_power_diff: (( %d)),max_power_diff: (( %d)),min_power_diff: (( %d))\n", tmp_power_diff,max_power_diff,min_power_diff); */
472*4882a593Smuzhiyun #endif
473*4882a593Smuzhiyun 						if (tmp_power_diff > max_power_diff)
474*4882a593Smuzhiyun 							max_power_diff = tmp_power_diff;
475*4882a593Smuzhiyun 						if (tmp_power_diff < min_power_diff)
476*4882a593Smuzhiyun 							min_power_diff = tmp_power_diff;
477*4882a593Smuzhiyun #if 0
478*4882a593Smuzhiyun 						/* PHYDM_DBG(dm,DBG_ANT_DIV, "max_power_diff: (( %d)),min_power_diff: (( %d))\n",max_power_diff,min_power_diff); */
479*4882a593Smuzhiyun #endif
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun 						PlatformMoveMemory(p_test_bss_desc, p_tmp_bss_desc, sizeof(RT_WLAN_BSS));
482*4882a593Smuzhiyun 					} else if (p_test_bss_desc->RecvSignalPower > p_tmp_bss_desc->RecvSignalPower) { /* Pow(Ant1) < Pow(Ant2) */
483*4882a593Smuzhiyun 						counter++;
484*4882a593Smuzhiyun 						tmp_power_diff = (u8)(p_test_bss_desc->RecvSignalPower - p_tmp_bss_desc->RecvSignalPower);
485*4882a593Smuzhiyun 						power_diff = power_diff + tmp_power_diff;
486*4882a593Smuzhiyun 						PHYDM_DBG(dm, DBG_ANT_DIV, "Original: %d, Test: %d\n", p_tmp_bss_desc->RecvSignalPower, p_test_bss_desc->RecvSignalPower);
487*4882a593Smuzhiyun 						PHYDM_PRINT_ADDR(dm, DBG_ANT_DIV, "SSID:", p_tmp_bss_desc->bdSsIdBuf);
488*4882a593Smuzhiyun 						PHYDM_PRINT_ADDR(dm, DBG_ANT_DIV, "BSSID:", p_tmp_bss_desc->bdSsIdBuf);
489*4882a593Smuzhiyun 						if (tmp_power_diff > max_power_diff)
490*4882a593Smuzhiyun 							max_power_diff = tmp_power_diff;
491*4882a593Smuzhiyun 						if (tmp_power_diff < min_power_diff)
492*4882a593Smuzhiyun 							min_power_diff = tmp_power_diff;
493*4882a593Smuzhiyun 					} else { /* Pow(Ant1) = Pow(Ant2) */
494*4882a593Smuzhiyun 						if (p_test_bss_desc->bdTstamp > p_tmp_bss_desc->bdTstamp) { /* Stamp(Ant1) < Stamp(Ant2) */
495*4882a593Smuzhiyun 							PHYDM_DBG(dm, DBG_ANT_DIV, "time_diff: %lld\n", (p_test_bss_desc->bdTstamp - p_tmp_bss_desc->bdTstamp) / 1000);
496*4882a593Smuzhiyun 							if (p_test_bss_desc->bdTstamp - p_tmp_bss_desc->bdTstamp > 5000) {
497*4882a593Smuzhiyun 								counter++;
498*4882a593Smuzhiyun 								PHYDM_DBG(dm, DBG_ANT_DIV, "Original: %d, Test: %d\n", p_tmp_bss_desc->RecvSignalPower, p_test_bss_desc->RecvSignalPower);
499*4882a593Smuzhiyun 								PHYDM_PRINT_ADDR(dm, DBG_ANT_DIV, "SSID:", p_tmp_bss_desc->bdSsIdBuf);
500*4882a593Smuzhiyun 								PHYDM_PRINT_ADDR(dm, DBG_ANT_DIV, "BSSID:", p_tmp_bss_desc->bdSsIdBuf);
501*4882a593Smuzhiyun 								min_power_diff = 0;
502*4882a593Smuzhiyun 							}
503*4882a593Smuzhiyun 						} else
504*4882a593Smuzhiyun 							PHYDM_DBG(dm, DBG_ANT_DIV, "[Error !!!]: Time_diff: %lld\n", (p_test_bss_desc->bdTstamp - p_tmp_bss_desc->bdTstamp) / 1000);
505*4882a593Smuzhiyun 					}
506*4882a593Smuzhiyun 				}
507*4882a593Smuzhiyun 			}
508*4882a593Smuzhiyun 		}
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun 		if (dm->support_ic_type & (ODM_RTL8188E | ODM_RTL8821)) {
511*4882a593Smuzhiyun 			if (mgnt_info->NumBssDesc != 0 && score < 0) {
512*4882a593Smuzhiyun 				PHYDM_DBG(dm, DBG_ANT_DIV,
513*4882a593Smuzhiyun 					  "%s: Using ant(%s)\n", __func__,
514*4882a593Smuzhiyun 					  (fat_tab->rx_idle_ant == MAIN_ANT) ?
515*4882a593Smuzhiyun 					  "MAIN_ANT" : "AUX_ANT");
516*4882a593Smuzhiyun 			} else {
517*4882a593Smuzhiyun 				PHYDM_DBG(dm, DBG_ANT_DIV,
518*4882a593Smuzhiyun 					  "%s: Remain ant(%s)\n", __func__,
519*4882a593Smuzhiyun 					  (fat_tab->rx_idle_ant == MAIN_ANT) ?
520*4882a593Smuzhiyun 					  "AUX_ANT" : "MAIN_ANT");
521*4882a593Smuzhiyun 
522*4882a593Smuzhiyun 				if (fat_tab->rx_idle_ant == MAIN_ANT)
523*4882a593Smuzhiyun 					odm_update_rx_idle_ant(dm, AUX_ANT);
524*4882a593Smuzhiyun 				else
525*4882a593Smuzhiyun 					odm_update_rx_idle_ant(dm, MAIN_ANT);
526*4882a593Smuzhiyun 			}
527*4882a593Smuzhiyun 
528*4882a593Smuzhiyun 			if (IS_5G_WIRELESS_MODE(mgnt_info->dot11CurrentWirelessMode)) {
529*4882a593Smuzhiyun 				dm_swat_table->ant_5g = fat_tab->rx_idle_ant;
530*4882a593Smuzhiyun 				PHYDM_DBG(dm, DBG_ANT_DIV,
531*4882a593Smuzhiyun 					  "dm_swat_table->ant_5g=%s\n",
532*4882a593Smuzhiyun 					  (fat_tab->rx_idle_ant == MAIN_ANT) ?
533*4882a593Smuzhiyun 					  "MAIN_ANT" : "AUX_ANT");
534*4882a593Smuzhiyun 			} else {
535*4882a593Smuzhiyun 				dm_swat_table->ant_2g = fat_tab->rx_idle_ant;
536*4882a593Smuzhiyun 				PHYDM_DBG(dm, DBG_ANT_DIV,
537*4882a593Smuzhiyun 					  "dm_swat_table->ant_2g=%s\n",
538*4882a593Smuzhiyun 					  (fat_tab->rx_idle_ant == MAIN_ANT) ?
539*4882a593Smuzhiyun 					  "MAIN_ANT" : "AUX_ANT");
540*4882a593Smuzhiyun 			}
541*4882a593Smuzhiyun 		} else if (dm->support_ic_type == ODM_RTL8723B) {
542*4882a593Smuzhiyun 			if (counter == 0) {
543*4882a593Smuzhiyun 				if (dm->dm_swat_table.pre_aux_fail_detec == false) {
544*4882a593Smuzhiyun 					dm->dm_swat_table.pre_aux_fail_detec = true;
545*4882a593Smuzhiyun 					dm->dm_swat_table.rssi_ant_dect_result = false;
546*4882a593Smuzhiyun 					PHYDM_DBG(dm, DBG_ANT_DIV, "counter=(( 0 )) , [[ Cannot find any AP with Aux-ant ]] ->  Scan Target-channel again\n");
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun 					/* @3 [ Scan again ] */
549*4882a593Smuzhiyun 					odm_sw_ant_div_construct_scan_chnl(adapter, scan_channel);
550*4882a593Smuzhiyun 					PlatformSetTimer(adapter, &mgnt_info->ScanTimer, 5);
551*4882a593Smuzhiyun 					return true;
552*4882a593Smuzhiyun 				} else { /* pre_aux_fail_detec == true */
553*4882a593Smuzhiyun 					/* @2 [ Single Antenna ] */
554*4882a593Smuzhiyun 					dm->dm_swat_table.pre_aux_fail_detec = false;
555*4882a593Smuzhiyun 					dm->dm_swat_table.rssi_ant_dect_result = true;
556*4882a593Smuzhiyun 					PHYDM_DBG(dm, DBG_ANT_DIV, "counter=(( 0 )) , [[  Still cannot find any AP ]]\n");
557*4882a593Smuzhiyun 					PHYDM_DBG(dm, DBG_ANT_DIV, "%s: Single antenna\n", __func__);
558*4882a593Smuzhiyun 				}
559*4882a593Smuzhiyun 				dm->dm_swat_table.aux_fail_detec_counter++;
560*4882a593Smuzhiyun 			} else {
561*4882a593Smuzhiyun 				dm->dm_swat_table.pre_aux_fail_detec = false;
562*4882a593Smuzhiyun 
563*4882a593Smuzhiyun 				if (counter == 3) {
564*4882a593Smuzhiyun 					avg_power_diff = ((power_diff - max_power_diff - min_power_diff) >> 1) + ((max_power_diff + min_power_diff) >> 2);
565*4882a593Smuzhiyun 					PHYDM_DBG(dm, DBG_ANT_DIV, "counter: (( %d )) ,  power_diff: (( %d ))\n", counter, power_diff);
566*4882a593Smuzhiyun 					PHYDM_DBG(dm, DBG_ANT_DIV, "[ counter==3 ] Modified avg_power_diff: (( %d )) , max_power_diff: (( %d )) ,  min_power_diff: (( %d ))\n", avg_power_diff, max_power_diff, min_power_diff);
567*4882a593Smuzhiyun 				} else if (counter >= 4) {
568*4882a593Smuzhiyun 					avg_power_diff = (power_diff - max_power_diff - min_power_diff) / (counter - 2);
569*4882a593Smuzhiyun 					PHYDM_DBG(dm, DBG_ANT_DIV, "counter: (( %d )) ,  power_diff: (( %d ))\n", counter, power_diff);
570*4882a593Smuzhiyun 					PHYDM_DBG(dm, DBG_ANT_DIV, "[ counter>=4 ] Modified avg_power_diff: (( %d )) , max_power_diff: (( %d )) ,  min_power_diff: (( %d ))\n", avg_power_diff, max_power_diff, min_power_diff);
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun 				} else { /* @counter==1,2 */
573*4882a593Smuzhiyun 					avg_power_diff = power_diff / counter;
574*4882a593Smuzhiyun 					PHYDM_DBG(dm, DBG_ANT_DIV, "avg_power_diff: (( %d )) , counter: (( %d )) ,  power_diff: (( %d ))\n", avg_power_diff, counter, power_diff);
575*4882a593Smuzhiyun 				}
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun 				/* @2 [ Retry ] */
578*4882a593Smuzhiyun 				if (avg_power_diff >= power_target_L && avg_power_diff <= power_target_H) {
579*4882a593Smuzhiyun 					dm->dm_swat_table.retry_counter++;
580*4882a593Smuzhiyun 
581*4882a593Smuzhiyun 					if (dm->dm_swat_table.retry_counter <= 3) {
582*4882a593Smuzhiyun 						dm->dm_swat_table.rssi_ant_dect_result = false;
583*4882a593Smuzhiyun 						PHYDM_DBG(dm, DBG_ANT_DIV, "[[ Low confidence result ]] avg_power_diff= (( %d ))  ->  Scan Target-channel again ]]\n", avg_power_diff);
584*4882a593Smuzhiyun 
585*4882a593Smuzhiyun 						/* @3 [ Scan again ] */
586*4882a593Smuzhiyun 						odm_sw_ant_div_construct_scan_chnl(adapter, scan_channel);
587*4882a593Smuzhiyun 						PlatformSetTimer(adapter, &mgnt_info->ScanTimer, 5);
588*4882a593Smuzhiyun 						return true;
589*4882a593Smuzhiyun 					} else {
590*4882a593Smuzhiyun 						dm->dm_swat_table.rssi_ant_dect_result = true;
591*4882a593Smuzhiyun 						PHYDM_DBG(dm, DBG_ANT_DIV, "[[ Still Low confidence result ]]  (( retry_counter > 3 ))\n");
592*4882a593Smuzhiyun 						PHYDM_DBG(dm, DBG_ANT_DIV, "%s: Single antenna\n", __func__);
593*4882a593Smuzhiyun 					}
594*4882a593Smuzhiyun 				}
595*4882a593Smuzhiyun 				/* @2 [ Dual Antenna ] */
596*4882a593Smuzhiyun 				else if ((mgnt_info->NumBssDesc != 0) && (avg_power_diff < power_target_L)) {
597*4882a593Smuzhiyun 					dm->dm_swat_table.rssi_ant_dect_result = true;
598*4882a593Smuzhiyun 					if (dm->dm_swat_table.ANTB_ON == false) {
599*4882a593Smuzhiyun 						dm->dm_swat_table.ANTA_ON = true;
600*4882a593Smuzhiyun 						dm->dm_swat_table.ANTB_ON = true;
601*4882a593Smuzhiyun 					}
602*4882a593Smuzhiyun 					PHYDM_DBG(dm, DBG_ANT_DIV, "%s: Dual antenna\n", __func__);
603*4882a593Smuzhiyun 					dm->dm_swat_table.dual_ant_counter++;
604*4882a593Smuzhiyun 
605*4882a593Smuzhiyun 					/* set bt coexDM from 1ant coexDM to 2ant coexDM */
606*4882a593Smuzhiyun 					BT_SetBtCoexAntNum(adapter, BT_COEX_ANT_TYPE_DETECTED, 2);
607*4882a593Smuzhiyun 
608*4882a593Smuzhiyun 					/* @3 [ Init antenna diversity ] */
609*4882a593Smuzhiyun 					dm->support_ability |= ODM_BB_ANT_DIV;
610*4882a593Smuzhiyun 					odm_ant_div_init(dm);
611*4882a593Smuzhiyun 				}
612*4882a593Smuzhiyun 				/* @2 [ Single Antenna ] */
613*4882a593Smuzhiyun 				else if (avg_power_diff > power_target_H) {
614*4882a593Smuzhiyun 					dm->dm_swat_table.rssi_ant_dect_result = true;
615*4882a593Smuzhiyun 					if (dm->dm_swat_table.ANTB_ON == true) {
616*4882a593Smuzhiyun 						dm->dm_swat_table.ANTA_ON = true;
617*4882a593Smuzhiyun 						dm->dm_swat_table.ANTB_ON = false;
618*4882a593Smuzhiyun #if 0
619*4882a593Smuzhiyun 						/* @bt_set_bt_coex_ant_num(adapter, BT_COEX_ANT_TYPE_DETECTED, 1); */
620*4882a593Smuzhiyun #endif
621*4882a593Smuzhiyun 					}
622*4882a593Smuzhiyun 					PHYDM_DBG(dm, DBG_ANT_DIV, "%s: Single antenna\n", __func__);
623*4882a593Smuzhiyun 					dm->dm_swat_table.single_ant_counter++;
624*4882a593Smuzhiyun 				}
625*4882a593Smuzhiyun 			}
626*4882a593Smuzhiyun #if 0
627*4882a593Smuzhiyun 			/* PHYDM_DBG(dm,DBG_ANT_DIV, "is_result=(( %d ))\n",dm->dm_swat_table.rssi_ant_dect_result); */
628*4882a593Smuzhiyun #endif
629*4882a593Smuzhiyun 			PHYDM_DBG(dm, DBG_ANT_DIV,
630*4882a593Smuzhiyun 				  "dual_ant_counter = (( %d )), single_ant_counter = (( %d )) , retry_counter = (( %d )) , aux_fail_detec_counter = (( %d ))\n\n\n",
631*4882a593Smuzhiyun 				  dm->dm_swat_table.dual_ant_counter,
632*4882a593Smuzhiyun 				  dm->dm_swat_table.single_ant_counter,
633*4882a593Smuzhiyun 				  dm->dm_swat_table.retry_counter,
634*4882a593Smuzhiyun 				  dm->dm_swat_table.aux_fail_detec_counter);
635*4882a593Smuzhiyun 
636*4882a593Smuzhiyun 			/* @2 recover the antenna setting */
637*4882a593Smuzhiyun 
638*4882a593Smuzhiyun 			if (dm->dm_swat_table.ANTB_ON == false)
639*4882a593Smuzhiyun 				odm_set_bb_reg(dm, REG_S0_S1_PATH_SWITCH, 0xfff, (dm_swat_table->swas_no_link_bk_reg948));
640*4882a593Smuzhiyun 
641*4882a593Smuzhiyun 			PHYDM_DBG(dm, DBG_ANT_DIV,
642*4882a593Smuzhiyun 				  "is_result=(( %d )), Recover  Reg[948]= (( %x ))\n\n",
643*4882a593Smuzhiyun 				  dm->dm_swat_table.rssi_ant_dect_result,
644*4882a593Smuzhiyun 				  dm_swat_table->swas_no_link_bk_reg948);
645*4882a593Smuzhiyun 		}
646*4882a593Smuzhiyun 
647*4882a593Smuzhiyun 		/* @Check state reset to default and wait for next time. */
648*4882a593Smuzhiyun 		dm_swat_table->swas_no_link_state = 0;
649*4882a593Smuzhiyun 		mgnt_info->bScanAntDetect = false;
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun 		return false;
652*4882a593Smuzhiyun 	}
653*4882a593Smuzhiyun 
654*4882a593Smuzhiyun #else
655*4882a593Smuzhiyun 	return false;
656*4882a593Smuzhiyun #endif
657*4882a593Smuzhiyun 
658*4882a593Smuzhiyun 	return false;
659*4882a593Smuzhiyun }
660*4882a593Smuzhiyun 
661*4882a593Smuzhiyun /* @1 [3. PSD method] ========================================================== */
odm_single_dual_antenna_detection_psd(void * dm_void)662*4882a593Smuzhiyun void odm_single_dual_antenna_detection_psd(
663*4882a593Smuzhiyun 	void *dm_void)
664*4882a593Smuzhiyun {
665*4882a593Smuzhiyun 	struct dm_struct *dm = (struct dm_struct *)dm_void;
666*4882a593Smuzhiyun 	u32 channel_ori;
667*4882a593Smuzhiyun 	u8 initial_gain = 0x36;
668*4882a593Smuzhiyun 	u8 tone_idx;
669*4882a593Smuzhiyun 	u8 tone_lenth_1 = 7, tone_lenth_2 = 4;
670*4882a593Smuzhiyun 	u16 tone_idx_1[7] = {88, 104, 120, 8, 24, 40, 56};
671*4882a593Smuzhiyun 	u16 tone_idx_2[4] = {8, 24, 40, 56};
672*4882a593Smuzhiyun 	u32 psd_report_main[11] = {0}, psd_report_aux[11] = {0};
673*4882a593Smuzhiyun 	/* u8	tone_lenth_1=4, tone_lenth_2=2; */
674*4882a593Smuzhiyun 	/* u16	tone_idx_1[4]={88, 120, 24, 56}; */
675*4882a593Smuzhiyun 	/* u16	tone_idx_2[2]={ 24,  56}; */
676*4882a593Smuzhiyun 	/* u32	psd_report_main[6]={0}, psd_report_aux[6]={0}; */
677*4882a593Smuzhiyun 
678*4882a593Smuzhiyun 	u32 PSD_report_temp, max_psd_report_main = 0, max_psd_report_aux = 0;
679*4882a593Smuzhiyun 	u32 PSD_power_threshold;
680*4882a593Smuzhiyun 	u32 main_psd_result = 0, aux_psd_result = 0;
681*4882a593Smuzhiyun 	u32 regc50, reg948, regb2c, regc14, reg908;
682*4882a593Smuzhiyun 	u32 i = 0, test_num = 8;
683*4882a593Smuzhiyun 
684*4882a593Smuzhiyun 	if (dm->support_ic_type != ODM_RTL8723B)
685*4882a593Smuzhiyun 		return;
686*4882a593Smuzhiyun 
687*4882a593Smuzhiyun 	PHYDM_DBG(dm, DBG_ANT_DIV, "%s============>\n", __func__);
688*4882a593Smuzhiyun 
689*4882a593Smuzhiyun 	/* @2 [ Backup Current RF/BB Settings ] */
690*4882a593Smuzhiyun 
691*4882a593Smuzhiyun 	channel_ori = odm_get_rf_reg(dm, RF_PATH_A, ODM_CHANNEL, RFREGOFFSETMASK);
692*4882a593Smuzhiyun 	reg948 = odm_get_bb_reg(dm, REG_S0_S1_PATH_SWITCH, MASKDWORD);
693*4882a593Smuzhiyun 	regb2c = odm_get_bb_reg(dm, REG_AGC_TABLE_SELECT, MASKDWORD);
694*4882a593Smuzhiyun 	regc50 = odm_get_bb_reg(dm, REG_OFDM_0_XA_AGC_CORE1, MASKDWORD);
695*4882a593Smuzhiyun 	regc14 = odm_get_bb_reg(dm, R_0xc14, MASKDWORD);
696*4882a593Smuzhiyun 	reg908 = odm_get_bb_reg(dm, R_0x908, MASKDWORD);
697*4882a593Smuzhiyun 
698*4882a593Smuzhiyun 	/* @2 [ setting for doing PSD function (CH4)] */
699*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_FPGA0_RFMOD, BIT(24), 0); /* @disable whole CCK block */
700*4882a593Smuzhiyun 	odm_write_1byte(dm, REG_TXPAUSE, 0xFF); /* Turn off TX  ->  Pause TX Queue */
701*4882a593Smuzhiyun 	odm_set_bb_reg(dm, R_0xc14, MASKDWORD, 0x0); /* @[ Set IQK Matrix = 0 ] equivalent to [ Turn off CCA] */
702*4882a593Smuzhiyun 
703*4882a593Smuzhiyun 	/* PHYTXON while loop */
704*4882a593Smuzhiyun 	odm_set_bb_reg(dm, R_0x908, MASKDWORD, 0x803);
705*4882a593Smuzhiyun 	while (odm_get_bb_reg(dm, R_0xdf4, BIT(6))) {
706*4882a593Smuzhiyun 		i++;
707*4882a593Smuzhiyun 		if (i > 1000000) {
708*4882a593Smuzhiyun 			PHYDM_DBG(dm, DBG_ANT_DIV,
709*4882a593Smuzhiyun 				  "Wait in %s() more than %d times!\n",
710*4882a593Smuzhiyun 				  __FUNCTION__, i);
711*4882a593Smuzhiyun 			break;
712*4882a593Smuzhiyun 		}
713*4882a593Smuzhiyun 	}
714*4882a593Smuzhiyun 
715*4882a593Smuzhiyun 	odm_set_bb_reg(dm, R_0xc50, 0x7f, initial_gain);
716*4882a593Smuzhiyun 	odm_set_rf_reg(dm, RF_PATH_A, ODM_CHANNEL, 0x7ff, 0x04); /* Set RF to CH4 & 40M */
717*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_FPGA0_ANALOG_PARAMETER4, 0xf00000, 0xf); /* @3 wire Disable    88c[23:20]=0xf */
718*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_FPGA0_PSD_FUNCTION, BIT(14) | BIT15, 0x0); /* 128 pt	 */ /* Set PSD 128 ptss */
719*4882a593Smuzhiyun 	ODM_delay_us(3000);
720*4882a593Smuzhiyun 
721*4882a593Smuzhiyun 	/* @2 [ Doing PSD Function in (CH4)] */
722*4882a593Smuzhiyun 
723*4882a593Smuzhiyun 	/* @Antenna A */
724*4882a593Smuzhiyun 	PHYDM_DBG(dm, DBG_ANT_DIV, "Switch to Main-ant   (CH4)\n");
725*4882a593Smuzhiyun 	odm_set_bb_reg(dm, R_0x948, 0xfff, 0x200);
726*4882a593Smuzhiyun 	ODM_delay_us(10);
727*4882a593Smuzhiyun 	PHYDM_DBG(dm, DBG_ANT_DIV, "dbg\n");
728*4882a593Smuzhiyun 	for (i = 0; i < test_num; i++) {
729*4882a593Smuzhiyun 		for (tone_idx = 0; tone_idx < tone_lenth_1; tone_idx++) {
730*4882a593Smuzhiyun 			PSD_report_temp = phydm_get_psd_data(dm, tone_idx_1[tone_idx], initial_gain);
731*4882a593Smuzhiyun 			/* @if(  PSD_report_temp>psd_report_main[tone_idx]  ) */
732*4882a593Smuzhiyun 			psd_report_main[tone_idx] += PSD_report_temp;
733*4882a593Smuzhiyun 		}
734*4882a593Smuzhiyun 	}
735*4882a593Smuzhiyun 	/* @Antenna B */
736*4882a593Smuzhiyun 	PHYDM_DBG(dm, DBG_ANT_DIV, "Switch to Aux-ant   (CH4)\n");
737*4882a593Smuzhiyun 	odm_set_bb_reg(dm, R_0x948, 0xfff, 0x280);
738*4882a593Smuzhiyun 	ODM_delay_us(10);
739*4882a593Smuzhiyun 	for (i = 0; i < test_num; i++) {
740*4882a593Smuzhiyun 		for (tone_idx = 0; tone_idx < tone_lenth_1; tone_idx++) {
741*4882a593Smuzhiyun 			PSD_report_temp = phydm_get_psd_data(dm, tone_idx_1[tone_idx], initial_gain);
742*4882a593Smuzhiyun 			/* @if(  PSD_report_temp>psd_report_aux[tone_idx]  ) */
743*4882a593Smuzhiyun 			psd_report_aux[tone_idx] += PSD_report_temp;
744*4882a593Smuzhiyun 		}
745*4882a593Smuzhiyun 	}
746*4882a593Smuzhiyun 	/* @2 [ Doing PSD Function in (CH8)] */
747*4882a593Smuzhiyun 
748*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_FPGA0_ANALOG_PARAMETER4, 0xf00000, 0x0); /* @3 wire enable    88c[23:20]=0x0 */
749*4882a593Smuzhiyun 	ODM_delay_us(3000);
750*4882a593Smuzhiyun 
751*4882a593Smuzhiyun 	odm_set_bb_reg(dm, R_0xc50, 0x7f, initial_gain);
752*4882a593Smuzhiyun 	odm_set_rf_reg(dm, RF_PATH_A, ODM_CHANNEL, 0x7ff, 0x04); /* Set RF to CH8 & 40M */
753*4882a593Smuzhiyun 
754*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_FPGA0_ANALOG_PARAMETER4, 0xf00000, 0xf); /* @3 wire Disable    88c[23:20]=0xf */
755*4882a593Smuzhiyun 	ODM_delay_us(3000);
756*4882a593Smuzhiyun 
757*4882a593Smuzhiyun 	/* @Antenna A */
758*4882a593Smuzhiyun 	PHYDM_DBG(dm, DBG_ANT_DIV, "Switch to Main-ant   (CH8)\n");
759*4882a593Smuzhiyun 	odm_set_bb_reg(dm, R_0x948, 0xfff, 0x200);
760*4882a593Smuzhiyun 	ODM_delay_us(10);
761*4882a593Smuzhiyun 
762*4882a593Smuzhiyun 	for (i = 0; i < test_num; i++) {
763*4882a593Smuzhiyun 		for (tone_idx = 0; tone_idx < tone_lenth_2; tone_idx++) {
764*4882a593Smuzhiyun 			PSD_report_temp = phydm_get_psd_data(dm, tone_idx_2[tone_idx], initial_gain);
765*4882a593Smuzhiyun 			/* @if(  PSD_report_temp>psd_report_main[tone_idx]  ) */
766*4882a593Smuzhiyun 			psd_report_main[tone_lenth_1 + tone_idx] += PSD_report_temp;
767*4882a593Smuzhiyun 		}
768*4882a593Smuzhiyun 	}
769*4882a593Smuzhiyun 
770*4882a593Smuzhiyun 	/* @Antenna B */
771*4882a593Smuzhiyun 	PHYDM_DBG(dm, DBG_ANT_DIV, "Switch to Aux-ant   (CH8)\n");
772*4882a593Smuzhiyun 	odm_set_bb_reg(dm, R_0x948, 0xfff, 0x280);
773*4882a593Smuzhiyun 	ODM_delay_us(10);
774*4882a593Smuzhiyun 
775*4882a593Smuzhiyun 	for (i = 0; i < test_num; i++) {
776*4882a593Smuzhiyun 		for (tone_idx = 0; tone_idx < tone_lenth_2; tone_idx++) {
777*4882a593Smuzhiyun 			PSD_report_temp = phydm_get_psd_data(dm, tone_idx_2[tone_idx], initial_gain);
778*4882a593Smuzhiyun 			/* @if(  PSD_report_temp>psd_report_aux[tone_idx]  ) */
779*4882a593Smuzhiyun 			psd_report_aux[tone_lenth_1 + tone_idx] += PSD_report_temp;
780*4882a593Smuzhiyun 		}
781*4882a593Smuzhiyun 	}
782*4882a593Smuzhiyun 
783*4882a593Smuzhiyun 	/* @2 [ Calculate Result ] */
784*4882a593Smuzhiyun 
785*4882a593Smuzhiyun 	PHYDM_DBG(dm, DBG_ANT_DIV, "\nMain PSD Result: (ALL)\n");
786*4882a593Smuzhiyun 	for (tone_idx = 0; tone_idx < (tone_lenth_1 + tone_lenth_2); tone_idx++) {
787*4882a593Smuzhiyun 		PHYDM_DBG(dm, DBG_ANT_DIV, "[Tone-%d]: %d,\n", (tone_idx + 1),
788*4882a593Smuzhiyun 			  psd_report_main[tone_idx]);
789*4882a593Smuzhiyun 		main_psd_result += psd_report_main[tone_idx];
790*4882a593Smuzhiyun 		if (psd_report_main[tone_idx] > max_psd_report_main)
791*4882a593Smuzhiyun 			max_psd_report_main = psd_report_main[tone_idx];
792*4882a593Smuzhiyun 	}
793*4882a593Smuzhiyun 	PHYDM_DBG(dm, DBG_ANT_DIV,
794*4882a593Smuzhiyun 		  "--------------------------- \nTotal_Main= (( %d ))\n",
795*4882a593Smuzhiyun 		  main_psd_result);
796*4882a593Smuzhiyun 	PHYDM_DBG(dm, DBG_ANT_DIV, "MAX_Main = (( %d ))\n",
797*4882a593Smuzhiyun 		  max_psd_report_main);
798*4882a593Smuzhiyun 
799*4882a593Smuzhiyun 	PHYDM_DBG(dm, DBG_ANT_DIV, "\nAux PSD Result: (ALL)\n");
800*4882a593Smuzhiyun 	for (tone_idx = 0; tone_idx < (tone_lenth_1 + tone_lenth_2); tone_idx++) {
801*4882a593Smuzhiyun 		PHYDM_DBG(dm, DBG_ANT_DIV, "[Tone-%d]: %d,\n", (tone_idx + 1),
802*4882a593Smuzhiyun 			  psd_report_aux[tone_idx]);
803*4882a593Smuzhiyun 		aux_psd_result += psd_report_aux[tone_idx];
804*4882a593Smuzhiyun 		if (psd_report_aux[tone_idx] > max_psd_report_aux)
805*4882a593Smuzhiyun 			max_psd_report_aux = psd_report_aux[tone_idx];
806*4882a593Smuzhiyun 	}
807*4882a593Smuzhiyun 	PHYDM_DBG(dm, DBG_ANT_DIV,
808*4882a593Smuzhiyun 		  "--------------------------- \nTotal_Aux= (( %d ))\n",
809*4882a593Smuzhiyun 		  aux_psd_result);
810*4882a593Smuzhiyun 	PHYDM_DBG(dm, DBG_ANT_DIV, "MAX_Aux = (( %d ))\n\n",
811*4882a593Smuzhiyun 		  max_psd_report_aux);
812*4882a593Smuzhiyun 
813*4882a593Smuzhiyun 	/* @main_psd_result=main_psd_result-max_psd_report_main; */
814*4882a593Smuzhiyun 	/* @aux_psd_result=aux_psd_result-max_psd_report_aux; */
815*4882a593Smuzhiyun 	PSD_power_threshold = (main_psd_result * 7) >> 3;
816*4882a593Smuzhiyun 
817*4882a593Smuzhiyun 	PHYDM_DBG(dm, DBG_ANT_DIV,
818*4882a593Smuzhiyun 		  "[ Main_result, Aux_result ] = [ %d , %d ], PSD_power_threshold=(( %d ))\n",
819*4882a593Smuzhiyun 		  main_psd_result, aux_psd_result, PSD_power_threshold);
820*4882a593Smuzhiyun 
821*4882a593Smuzhiyun 	/* @3 [ Dual Antenna ] */
822*4882a593Smuzhiyun 	if (aux_psd_result >= PSD_power_threshold) {
823*4882a593Smuzhiyun 		if (dm->dm_swat_table.ANTB_ON == false) {
824*4882a593Smuzhiyun 			dm->dm_swat_table.ANTA_ON = true;
825*4882a593Smuzhiyun 			dm->dm_swat_table.ANTB_ON = true;
826*4882a593Smuzhiyun 		}
827*4882a593Smuzhiyun 		PHYDM_DBG(dm, DBG_ANT_DIV,
828*4882a593Smuzhiyun 			  "odm_sw_ant_div_check_before_link(): Dual antenna\n");
829*4882a593Smuzhiyun 
830*4882a593Smuzhiyun #if 0
831*4882a593Smuzhiyun 		/* set bt coexDM from 1ant coexDM to 2ant coexDM */
832*4882a593Smuzhiyun 		/* @bt_set_bt_coex_ant_num(adapter, BT_COEX_ANT_TYPE_DETECTED, 2); */
833*4882a593Smuzhiyun #endif
834*4882a593Smuzhiyun 
835*4882a593Smuzhiyun 		/* @Init antenna diversity */
836*4882a593Smuzhiyun 		dm->support_ability |= ODM_BB_ANT_DIV;
837*4882a593Smuzhiyun 		odm_ant_div_init(dm);
838*4882a593Smuzhiyun 	}
839*4882a593Smuzhiyun 	/* @3 [ Single Antenna ] */
840*4882a593Smuzhiyun 	else {
841*4882a593Smuzhiyun 		if (dm->dm_swat_table.ANTB_ON == true) {
842*4882a593Smuzhiyun 			dm->dm_swat_table.ANTA_ON = true;
843*4882a593Smuzhiyun 			dm->dm_swat_table.ANTB_ON = false;
844*4882a593Smuzhiyun 		}
845*4882a593Smuzhiyun 		PHYDM_DBG(dm, DBG_ANT_DIV,
846*4882a593Smuzhiyun 			  "odm_sw_ant_div_check_before_link(): Single antenna\n");
847*4882a593Smuzhiyun 	}
848*4882a593Smuzhiyun 
849*4882a593Smuzhiyun 	/* @2 [ Recover all parameters ] */
850*4882a593Smuzhiyun 
851*4882a593Smuzhiyun 	odm_set_rf_reg(dm, RF_PATH_A, RF_CHNLBW, RFREGOFFSETMASK, channel_ori);
852*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_FPGA0_ANALOG_PARAMETER4, 0xf00000, 0x0); /* @3 wire enable    88c[23:20]=0x0 */
853*4882a593Smuzhiyun 	odm_set_bb_reg(dm, R_0xc50, 0x7f, regc50);
854*4882a593Smuzhiyun 
855*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_S0_S1_PATH_SWITCH, MASKDWORD, reg948);
856*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_AGC_TABLE_SELECT, MASKDWORD, regb2c);
857*4882a593Smuzhiyun 
858*4882a593Smuzhiyun 	odm_set_bb_reg(dm, REG_FPGA0_RFMOD, BIT(24), 1); /* @enable whole CCK block */
859*4882a593Smuzhiyun 	odm_write_1byte(dm, REG_TXPAUSE, 0x0); /* Turn on TX	 */ /* Resume TX Queue */
860*4882a593Smuzhiyun 	odm_set_bb_reg(dm, R_0xc14, MASKDWORD, regc14); /* @[ Set IQK Matrix = 0 ] equivalent to [ Turn on CCA] */
861*4882a593Smuzhiyun 	odm_set_bb_reg(dm, R_0x908, MASKDWORD, reg908);
862*4882a593Smuzhiyun 
863*4882a593Smuzhiyun 	return;
864*4882a593Smuzhiyun }
865*4882a593Smuzhiyun 
odm_sw_ant_detect_init(void * dm_void)866*4882a593Smuzhiyun void odm_sw_ant_detect_init(void *dm_void)
867*4882a593Smuzhiyun {
868*4882a593Smuzhiyun #if (RTL8723B_SUPPORT == 1)
869*4882a593Smuzhiyun 
870*4882a593Smuzhiyun 	struct dm_struct *dm = (struct dm_struct *)dm_void;
871*4882a593Smuzhiyun 	struct sw_antenna_switch *dm_swat_table = &dm->dm_swat_table;
872*4882a593Smuzhiyun 
873*4882a593Smuzhiyun 	if (dm->support_ic_type != ODM_RTL8723B)
874*4882a593Smuzhiyun 		return;
875*4882a593Smuzhiyun 
876*4882a593Smuzhiyun 	/* @dm_swat_table->pre_antenna = MAIN_ANT; */
877*4882a593Smuzhiyun 	/* @dm_swat_table->cur_antenna = MAIN_ANT; */
878*4882a593Smuzhiyun 	dm_swat_table->swas_no_link_state = 0;
879*4882a593Smuzhiyun 	dm_swat_table->pre_aux_fail_detec = false;
880*4882a593Smuzhiyun 	dm_swat_table->swas_no_link_bk_reg948 = 0xff;
881*4882a593Smuzhiyun 
882*4882a593Smuzhiyun #ifdef CONFIG_PSD_TOOL
883*4882a593Smuzhiyun 	phydm_psd_init(dm);
884*4882a593Smuzhiyun #endif
885*4882a593Smuzhiyun #endif
886*4882a593Smuzhiyun }
887*4882a593Smuzhiyun #endif
888*4882a593Smuzhiyun 
889