1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
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 /*  Description: */
17 /*  */
18 /*  This file is for 92CE/92CU dynamic mechanism only */
19 /*  */
20 /*  */
21 /*  */
22 #define _RTL8723A_DM_C_
23 
24 /*  */
25 /*  include files */
26 /*  */
27 #include <osdep_service.h>
28 #include <drv_types.h>
29 
30 #include <rtl8723a_hal.h>
31 #include <usb_ops_linux.h>
32 
33 /*  */
34 /*  Global var */
35 /*  */
36 
dm_CheckPbcGPIO(struct rtw_adapter * padapter)37 static void dm_CheckPbcGPIO(struct rtw_adapter *padapter)
38 {
39 	u8	tmp1byte;
40 	u8	bPbcPressed = false;
41 
42 	if (!padapter->registrypriv.hw_wps_pbc)
43 		return;
44 
45 	tmp1byte = rtl8723au_read8(padapter, GPIO_IO_SEL);
46 	tmp1byte |= (HAL_8192C_HW_GPIO_WPS_BIT);
47 	/* enable GPIO[2] as output mode */
48 	rtl8723au_write8(padapter, GPIO_IO_SEL, tmp1byte);
49 
50 	tmp1byte &= ~(HAL_8192C_HW_GPIO_WPS_BIT);
51 	/* reset the floating voltage level */
52 	rtl8723au_write8(padapter,  GPIO_IN, tmp1byte);
53 
54 	tmp1byte = rtl8723au_read8(padapter, GPIO_IO_SEL);
55 	tmp1byte &= ~(HAL_8192C_HW_GPIO_WPS_BIT);
56 	/* enable GPIO[2] as input mode */
57 	rtl8723au_write8(padapter, GPIO_IO_SEL, tmp1byte);
58 
59 	tmp1byte = rtl8723au_read8(padapter, GPIO_IN);
60 
61 	if (tmp1byte == 0xff)
62 		return;
63 
64 	if (tmp1byte&HAL_8192C_HW_GPIO_WPS_BIT)
65 		bPbcPressed = true;
66 
67 	if (bPbcPressed) {
68 		/*  Here we only set bPbcPressed to true */
69 		/*  After trigger PBC, the variable will be set to false */
70 		DBG_8723A("CheckPbcGPIO - PBC is pressed\n");
71 
72 		if (padapter->pid[0] == 0) {
73 			/* 0 is the default value and it means the application
74 			 * monitors the HW PBC doesn't privde its pid to driver.
75 			 */
76 			return;
77 		}
78 
79 		kill_pid(find_vpid(padapter->pid[0]), SIGUSR1, 1);
80 	}
81 }
82 
83 /*  Initialize GPIO setting registers */
84 /*  functions */
85 
rtl8723a_init_dm_priv(struct rtw_adapter * Adapter)86 void rtl8723a_init_dm_priv(struct rtw_adapter *Adapter)
87 {
88 	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
89 	struct dm_priv	*pdmpriv = &pHalData->dmpriv;
90 	struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
91 	u8 cut_ver, fab_ver;
92 
93 	memset(pdmpriv, 0, sizeof(struct dm_priv));
94 	memset(pDM_Odm, 0, sizeof(*pDM_Odm));
95 
96 	pDM_Odm->Adapter = Adapter;
97 
98 	ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_IC_TYPE, ODM_RTL8723A);
99 
100 	if (IS_8723A_A_CUT(pHalData->VersionID)) {
101 		fab_ver = ODM_UMC;
102 		cut_ver = ODM_CUT_A;
103 	} else if (IS_8723A_B_CUT(pHalData->VersionID)) {
104 		fab_ver = ODM_UMC;
105 		cut_ver = ODM_CUT_B;
106 	} else {
107 		fab_ver = ODM_TSMC;
108 		cut_ver = ODM_CUT_A;
109 	}
110 	ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_FAB_VER, fab_ver);
111 	ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_CUT_VER, cut_ver);
112 	ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_MP_TEST_CHIP, IS_NORMAL_CHIP(pHalData->VersionID));
113 
114 	ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_BOARD_TYPE, pHalData->BoardType);
115 
116 	if (pHalData->BoardType == BOARD_USB_High_PA) {
117 		ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_EXT_LNA, true);
118 		ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_EXT_PA, true);
119 	}
120 	ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_BWIFI_TEST, Adapter->registrypriv.wifi_spec);
121 }
122 
Update_ODM_ComInfo_8723a(struct rtw_adapter * Adapter)123 static void Update_ODM_ComInfo_8723a(struct rtw_adapter *Adapter)
124 {
125 	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
126 	struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
127 	struct dm_priv	*pdmpriv = &pHalData->dmpriv;
128 	int i;
129 	pdmpriv->InitODMFlag = 0;
130 	/*  Pointer reference */
131 	rtl8723a_odm_support_ability_set(Adapter, DYNAMIC_ALL_FUNC_ENABLE);
132 
133 	for (i = 0; i < NUM_STA; i++)
134 		ODM_CmnInfoPtrArrayHook23a(pDM_Odm, ODM_CMNINFO_STA_STATUS, i, NULL);
135 }
136 
rtl8723a_InitHalDm(struct rtw_adapter * Adapter)137 void rtl8723a_InitHalDm(struct rtw_adapter *Adapter)
138 {
139 	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
140 	struct dm_priv	*pdmpriv = &pHalData->dmpriv;
141 	struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
142 	u8	i;
143 
144 	Update_ODM_ComInfo_8723a(Adapter);
145 	ODM23a_DMInit(pDM_Odm);
146 	/*  Save REG_INIDATA_RATE_SEL value for TXDESC. */
147 	for (i = 0; i < 32; i++)
148 		pdmpriv->INIDATA_RATE[i] = rtl8723au_read8(Adapter, REG_INIDATA_RATE_SEL+i) & 0x3f;
149 }
150 
151 void
rtl8723a_HalDmWatchDog(struct rtw_adapter * Adapter)152 rtl8723a_HalDmWatchDog(
153 	struct rtw_adapter *Adapter
154 	)
155 {
156 	bool		bFwCurrentInPSMode = false;
157 	bool		bFwPSAwake = true;
158 	u8 bLinked = false;
159 	u8 hw_init_completed = false;
160 	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
161 	struct dm_priv	*pdmpriv = &pHalData->dmpriv;
162 
163 	hw_init_completed = Adapter->hw_init_completed;
164 
165 	if (hw_init_completed == false)
166 		goto skip_dm;
167 
168 	bFwCurrentInPSMode = Adapter->pwrctrlpriv.bFwCurrentInPSMode;
169 	bFwPSAwake = rtl8723a_get_fwlps_rf_on(Adapter);
170 
171 	if (!bFwCurrentInPSMode && bFwPSAwake) {
172 		/*  Read REG_INIDATA_RATE_SEL value for TXDESC. */
173 		if (check_fwstate(&Adapter->mlmepriv, WIFI_STATION_STATE)) {
174 			pdmpriv->INIDATA_RATE[0] = rtl8723au_read8(Adapter, REG_INIDATA_RATE_SEL) & 0x3f;
175 		} else {
176 			u8	i;
177 			for (i = 1 ; i < (Adapter->stapriv.asoc_sta_count + 1); i++)
178 				pdmpriv->INIDATA_RATE[i] = rtl8723au_read8(Adapter, (REG_INIDATA_RATE_SEL+i)) & 0x3f;
179 		}
180 	}
181 
182 	/* ODM */
183 	if (rtw_linked_check(Adapter))
184 		bLinked = true;
185 
186 	ODM_CmnInfoUpdate23a(&pHalData->odmpriv, ODM_CMNINFO_LINK, bLinked);
187 	ODM_DMWatchdog23a(Adapter);
188 
189 skip_dm:
190 
191 	/*  Check GPIO to determine current RF on/off and Pbc status. */
192 	/*  Check Hardware Radio ON/OFF or not */
193 	dm_CheckPbcGPIO(Adapter);
194 }
195