xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852bs/core/rtw_sreset.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2019 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 #include <drv_types.h>
17 #include <rtw_sreset.h>
18 
sreset_init_value(_adapter * padapter)19 void sreset_init_value(_adapter *padapter)
20 {
21 #if defined(DBG_CONFIG_ERROR_DETECT)
22 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
23 	HAL_DATA_TYPE	*pHalData = GET_PHL_COM(dvobj);
24 	struct sreset_priv *psrtpriv = &pHalData->srestpriv;
25 
26 	_rtw_mutex_init(&psrtpriv->silentreset_mutex);
27 	psrtpriv->silent_reset_inprogress = _FALSE;
28 	psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
29 	psrtpriv->last_tx_time = 0;
30 	psrtpriv->last_tx_complete_time = 0;
31 #endif
32 }
sreset_reset_value(_adapter * padapter)33 void sreset_reset_value(_adapter *padapter)
34 {
35 #if defined(DBG_CONFIG_ERROR_DETECT)
36 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
37 	HAL_DATA_TYPE	*pHalData = GET_PHL_COM(dvobj);
38 	struct sreset_priv *psrtpriv = &pHalData->srestpriv;
39 
40 	psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
41 	psrtpriv->last_tx_time = 0;
42 	psrtpriv->last_tx_complete_time = 0;
43 #endif
44 }
45 
sreset_get_wifi_status(_adapter * padapter)46 u8 sreset_get_wifi_status(_adapter *padapter)
47 {
48 #if defined(DBG_CONFIG_ERROR_DETECT)
49 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
50 	HAL_DATA_TYPE	*pHalData = GET_PHL_COM(dvobj);
51 	struct sreset_priv *psrtpriv = &pHalData->srestpriv;
52 	u8 status = WIFI_STATUS_SUCCESS;
53 	u32 val32 = 0;
54 
55 	if (psrtpriv->silent_reset_inprogress == _TRUE)
56 		return status;
57 	#if 0 /*GEORGIA_TODO_REDEFINE_IO*/
58 	val32 = rtw_read32(padapter, REG_TXDMA_STATUS);
59 	#else
60 	val32 = rtw_hal_get_dma_statu(padapter);
61 	#endif
62 	if (val32 == 0xeaeaeaea)
63 		psrtpriv->Wifi_Error_Status = WIFI_IF_NOT_EXIST;
64 	else if (val32 != 0) {
65 		RTW_INFO("txdmastatu(%x)\n", val32);
66 		psrtpriv->Wifi_Error_Status = WIFI_MAC_TXDMA_ERROR;
67 	}
68 
69 	if (WIFI_STATUS_SUCCESS != psrtpriv->Wifi_Error_Status) {
70 		RTW_INFO("==>%s error_status(0x%x)\n", __FUNCTION__, psrtpriv->Wifi_Error_Status);
71 		status = (psrtpriv->Wifi_Error_Status & (~(USB_READ_PORT_FAIL | USB_WRITE_PORT_FAIL)));
72 	}
73 	RTW_INFO("==> %s wifi_status(0x%x)\n", __FUNCTION__, status);
74 
75 	/* status restore */
76 	psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
77 
78 	return status;
79 #else
80 	return WIFI_STATUS_SUCCESS;
81 #endif
82 }
83 
sreset_set_wifi_error_status(_adapter * padapter,u32 status)84 void sreset_set_wifi_error_status(_adapter *padapter, u32 status)
85 {
86 #if defined(DBG_CONFIG_ERROR_DETECT)
87 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
88 	HAL_DATA_TYPE	*pHalData = GET_PHL_COM(dvobj);
89 	pHalData->srestpriv.Wifi_Error_Status = status;
90 #endif
91 }
92 
sreset_set_trigger_point(_adapter * padapter,s32 tgp)93 void sreset_set_trigger_point(_adapter *padapter, s32 tgp)
94 {
95 #if defined(DBG_CONFIG_ERROR_DETECT)
96 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
97 	HAL_DATA_TYPE	*pHalData = GET_PHL_COM(dvobj);
98 	pHalData->srestpriv.dbg_trigger_point = tgp;
99 #endif
100 }
101 
sreset_inprogress(_adapter * padapter)102 bool sreset_inprogress(_adapter *padapter)
103 {
104 #if defined(DBG_CONFIG_ERROR_RESET)
105 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
106 	HAL_DATA_TYPE	*pHalData = GET_PHL_COM(dvobj);
107 	return pHalData->srestpriv.silent_reset_inprogress;
108 #else
109 	return _FALSE;
110 #endif
111 }
112 
sreset_restore_security_station(_adapter * padapter)113 void sreset_restore_security_station(_adapter *padapter)
114 {
115 	struct mlme_priv *mlmepriv = &padapter->mlmepriv;
116 	struct sta_priv *pstapriv = &padapter->stapriv;
117 	struct sta_info *psta;
118 	struct mlme_ext_info	*pmlmeinfo = &padapter->mlmeextpriv.mlmext_info;
119 
120 	rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, NULL);
121 
122 	if ((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) ||
123 	    (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) {
124 		psta = rtw_get_stainfo(pstapriv, get_bssid(mlmepriv));
125 		if (psta == NULL) {
126 			/* DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail\n")); */
127 		} else {
128 			/* pairwise key */
129 			rtw_setstakey_cmd(padapter, psta, UNICAST_KEY, _FALSE);
130 			/* group key */
131 			rtw_set_key(padapter, &padapter->securitypriv, padapter->securitypriv.dot118021XGrpKeyid, 0, _FALSE);
132 		}
133 	}
134 }
135 
sreset_restore_network_station(_adapter * padapter)136 void sreset_restore_network_station(_adapter *padapter)
137 {
138 	struct mlme_priv *mlmepriv = &padapter->mlmepriv;
139 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
140 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
141 	u8 do_rfk = _FALSE;
142 
143 	rtw_setopmode_cmd(padapter, Ndis802_11Infrastructure, RTW_CMDF_DIRECTLY);
144 
145 	{
146 		u8 threshold;
147 #ifdef CONFIG_USB_HCI
148 		/* TH=1 => means that invalidate usb rx aggregation */
149 		/* TH=0 => means that validate usb rx aggregation, use init value. */
150 #ifdef CONFIG_80211N_HT
151 		if (mlmepriv->htpriv.ht_option) {
152 			if (padapter->registrypriv.wifi_spec == 1)
153 				threshold = 1;
154 			else
155 				threshold = 0;
156 			rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
157 		} else {
158 			threshold = 1;
159 			rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
160 		}
161 #endif /* CONFIG_80211N_HT */
162 #endif
163 	}
164 
165 	do_rfk = _TRUE;
166 	set_channel_bwmode(padapter,
167 			pmlmeext->chandef.chan,
168 			pmlmeext->chandef.offset,
169 			pmlmeext->chandef.bw,
170 			do_rfk);
171 
172 	rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
173 
174 	{
175 		u8	join_type = 0;
176 
177 		rtw_hal_rcr_set_chk_bssid(padapter, MLME_STA_CONNECTING);
178 		rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
179 	}
180 
181 	rtw_set_hw_after_join(padapter, 1);
182 	/* restore Sequence No. */
183 	rtw_hal_set_hwreg(padapter, HW_VAR_RESTORE_HW_SEQ, 0);
184 
185 	sreset_restore_security_station(padapter);
186 }
187 
188 
sreset_restore_network_status(_adapter * padapter)189 void sreset_restore_network_status(_adapter *padapter)
190 {
191 	struct mlme_priv *mlmepriv = &padapter->mlmepriv;
192 
193 	if (MLME_IS_STA(padapter)) {
194 		RTW_INFO(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_STATION_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv));
195 		sreset_restore_network_station(padapter);
196 	} else if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter)) {
197 		RTW_INFO(FUNC_ADPT_FMT" %s\n", FUNC_ADPT_ARG(padapter), MLME_IS_AP(padapter) ? "AP" : "MESH");
198 		rtw_ap_restore_network(padapter);
199 	} else if (MLME_IS_ADHOC(padapter))
200 		RTW_INFO(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_ADHOC_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv));
201 	else
202 		RTW_INFO(FUNC_ADPT_FMT" fwstate:0x%08x - ???\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv));
203 }
204 
sreset_stop_adapter(_adapter * padapter)205 void sreset_stop_adapter(_adapter *padapter)
206 {
207 	struct mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
208 	struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;
209 
210 	if (padapter == NULL)
211 		return;
212 
213 	RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
214 
215 	rtw_netif_stop_queue(padapter->pnetdev);
216 
217 	rtw_cancel_all_timer(padapter);
218 
219 	/* TODO: OS and HCI independent */
220 #if defined(CONFIG_USB_HCI)
221 	rtw_tasklet_kill(&pxmitpriv->xmit_tasklet);
222 #endif
223 
224 	if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY))
225 		rtw_scan_abort(padapter, 0);
226 
227 	if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING)) {
228 		rtw_set_to_roam(padapter, 0);
229 		rtw_join_timeout_handler(padapter);
230 	}
231 
232 }
233 
sreset_start_adapter(_adapter * padapter)234 void sreset_start_adapter(_adapter *padapter)
235 {
236 	struct mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
237 	struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;
238 
239 	if (padapter == NULL)
240 		return;
241 
242 	RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
243 
244 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
245 		sreset_restore_network_status(padapter);
246 
247 	/* TODO: OS and HCI independent */
248 #if defined(CONFIG_USB_HCI)
249 	rtw_tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
250 #endif
251 	#if 0 /*#ifdef CONFIG_CORE_DM_CHK_TIMER*/
252 	if (is_primary_adapter(padapter))
253 		_set_timer(&adapter_to_dvobj(padapter)->dynamic_chk_timer, 2000);
254 	#endif
255 	rtw_netif_wake_queue(padapter->pnetdev);
256 }
257 
sreset_reset(_adapter * padapter)258 void sreset_reset(_adapter *padapter)
259 {
260 #ifdef DBG_CONFIG_ERROR_RESET
261 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
262 	struct mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
263 	struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;
264 	systime start = rtw_get_current_time();
265 	struct dvobj_priv *psdpriv = padapter->dvobj;
266 	HAL_DATA_TYPE	*pHalData = GET_PHL_COM(psdpriv);
267 	struct sreset_priv *psrtpriv = &pHalData->srestpriv;
268 
269 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
270 
271 	RTW_INFO("%s\n", __FUNCTION__);
272 
273 	psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
274 
275 
276 #ifdef CONFIG_LPS
277 	rtw_set_ps_mode(padapter, PM_PS_MODE_ACTIVE, 0, 0, "SRESET");
278 #endif/* #ifdef CONFIG_LPS */
279 
280 	_enter_pwrlock(&pwrpriv->lock);
281 
282 	psrtpriv->silent_reset_inprogress = _TRUE;
283 	pwrpriv->change_rfpwrstate = rf_off;
284 
285 	rtw_mi_sreset_adapter_hdl(padapter, _FALSE);/*sreset_stop_adapter*/
286 #ifdef CONFIG_IPS
287 	_ips_enter(padapter);
288 	_ips_leave(padapter);
289 #endif
290 #ifdef CONFIG_CONCURRENT_MODE
291 	rtw_mi_ap_info_restore(padapter);
292 #endif
293 	rtw_mi_sreset_adapter_hdl(padapter, _TRUE);/*sreset_start_adapter*/
294 
295 	psrtpriv->silent_reset_inprogress = _FALSE;
296 
297 	_exit_pwrlock(&pwrpriv->lock);
298 
299 	RTW_INFO("%s done in %d ms\n", __FUNCTION__, rtw_get_passing_time_ms(start));
300 	pdbgpriv->dbg_sreset_cnt++;
301 
302 	psrtpriv->self_dect_fw = _FALSE;
303 	psrtpriv->rx_cnt = 0;
304 #endif
305 }
306