xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/rtl8822bs/hal/rtl8822b/sdio/rtl8822bs_ops.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2015 - 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 #define _RTL8822BS_OPS_C_
16 
17 #include <drv_types.h>		/* PADAPTER, basic_types.h and etc. */
18 #include <hal_data.h>		/* HAL_DATA_TYPE, GET_HAL_DATA() and etc. */
19 #include <hal_intf.h>		/* struct hal_ops */
20 #include "../rtl8822b.h"	/* rtl8822b_sethwreg() and etc. */
21 #include "rtl8822bs.h"		/* rtl8822bs_hal_init() */
22 
intf_chip_configure(PADAPTER adapter)23 static void intf_chip_configure(PADAPTER adapter)
24 {
25 }
26 
27 /*
28  * Description:
29  *	Collect all hardware information, fill "HAL_DATA_TYPE".
30  *	Sometimes this would be used to read MAC address.
31  *	This function will do
32  *	1. Read Efuse/EEPROM to initialize
33  *	2. Read registers to initialize
34  *	3. Other vaiables initialization
35  */
read_adapter_info(PADAPTER adapter)36 static u8 read_adapter_info(PADAPTER adapter)
37 {
38 	u8 ret = _FAIL;
39 
40 	/*
41 	 * 1. Read Efuse/EEPROM to initialize
42 	 */
43 	if (rtl8822b_read_efuse(adapter) != _SUCCESS)
44 		goto exit;
45 
46 	/*
47 	 * 2. Read registers to initialize
48 	 */
49 
50 	/*
51 	 * 3. Other Initialization
52 	 */
53 
54 	ret = _SUCCESS;
55 
56 exit:
57 	return ret;
58 }
59 
rtl8822bs_get_interrupt(PADAPTER adapter,u32 * hisr,u16 * rx_len)60 void rtl8822bs_get_interrupt(PADAPTER adapter, u32 *hisr, u16 *rx_len)
61 {
62 	u8 data[8] = {0};
63 
64 
65 	rtw_read_mem(adapter, REG_SDIO_HISR_8822B, 8, data);
66 
67 	if (hisr)
68 		*hisr = le32_to_cpu(*(u32 *)data);
69 	if (rx_len)
70 		*rx_len = le16_to_cpu(*(u16 *)&data[4]);
71 }
72 
rtl8822bs_clear_interrupt(PADAPTER adapter,u32 hisr)73 void rtl8822bs_clear_interrupt(PADAPTER adapter, u32 hisr)
74 {
75 	/* Perform write one clear operation */
76 	if (hisr)
77 		rtw_write32(adapter, REG_SDIO_HISR_8822B, hisr);
78 }
79 
update_himr(PADAPTER adapter,u32 himr)80 static void update_himr(PADAPTER adapter, u32 himr)
81 {
82 	rtw_write32(adapter, REG_SDIO_HIMR_8822B, himr);
83 }
84 
85 /*
86  * Description:
87  *	Initialize SDIO Host Interrupt Mask configuration variables for future use.
88  *
89  */
init_interrupt(PADAPTER adapter)90 static void init_interrupt(PADAPTER adapter)
91 {
92 	struct hal_com_data *hal;
93 
94 
95 	hal = GET_HAL_DATA(adapter);
96 	hal->sdio_himr = (u32)(
97 				 BIT_RX_REQUEST_MSK_8822B	|
98 #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT
99 				 BIT_SDIO_AVAL_MSK_8822B		|
100 #endif /* CONFIG_SDIO_TX_ENABLE_AVAL_INT */
101 #if 0
102 				 BIT_SDIO_TXERR_MSK_8822B	|
103 				 BIT_SDIO_RXERR_MSK_8822B	|
104 				 BIT_SDIO_TXFOVW_MSK_8822B	|
105 				 BIT_SDIO_RXFOVW_MSK_8822B	|
106 				 BIT_SDIO_TXBCNOK_MSK_8822B	|
107 				 BIT_SDIO_TXBCNERR_MSK_8822B	|
108 				 BIT_SDIO_BCNERLY_INT_MSK_8822B	|
109 				 BIT_SDIO_C2HCMD_INT_MSK_8822B	|
110 #endif
111 #if defined(CONFIG_LPS_LCLK) && !defined(CONFIG_DETECT_CPWM_BY_POLLING)
112 				 BIT_SDIO_CPWM1_MSK_8822B	|
113 #if 0
114 				 BIT_SDIO_CPWM2_MSK_8822B	|
115 #endif
116 #endif /* CONFIG_LPS_LCLK && !CONFIG_DETECT_CPWM_BY_POLLING */
117 #if 0
118 				 BIT_SDIO_HSISR_IND_MSK_8822B	|
119 				 BIT_SDIO_GTINT3_MSK_8822B	|
120 				 BIT_SDIO_GTINT4_MSK_8822B	|
121 				 BIT_SDIO_PSTIMEOUT_MSK_8822B	|
122 				 BIT_SDIO_OCPINT_MSK_8822B	|
123 				 BIT_SDIIO_ATIMend_MSK_8822B	|
124 				 BIT_SDIO_ATIMend_E_MSK_8822B	|
125 				 BIT_SDIO_CTWend_MSK_8822B	|
126 				 BIT_SDIO_CRCERR_MSK_8822B	|
127 #endif
128 				 0);
129 }
130 
131 /*
132  * Description:
133  *	Clear corresponding SDIO Host ISR interrupt service.
134  *
135  * Assumption:
136  *	Using SDIO Local register ONLY for configuration.
137  */
138 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
clear_interrupt_all(PADAPTER adapter)139 static void clear_interrupt_all(PADAPTER adapter)
140 {
141 	PHAL_DATA_TYPE hal;
142 
143 
144 	if (rtw_is_surprise_removed(adapter))
145 		return;
146 
147 	hal = GET_HAL_DATA(adapter);
148 	rtl8822bs_clear_interrupt(adapter, 0xFFFFFFFF);
149 }
150 #endif /*#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)*/
151 /*
152  * Description:
153  *	Enalbe SDIO Host Interrupt Mask configuration on SDIO local domain.
154  *
155  * Assumption:
156  *	1. Using SDIO Local register ONLY for configuration.
157  *	2. PASSIVE LEVEL
158  */
enable_interrupt(PADAPTER adapter)159 static void enable_interrupt(PADAPTER adapter)
160 {
161 	PHAL_DATA_TYPE hal;
162 
163 
164 	hal = GET_HAL_DATA(adapter);
165 
166 	update_himr(adapter, hal->sdio_himr);
167 	RTW_INFO(FUNC_ADPT_FMT ": update SDIO HIMR=0x%08X\n",
168 		 FUNC_ADPT_ARG(adapter), hal->sdio_himr);
169 }
170 
171 /*
172  * Description:
173  *	Disable SDIO Host IMR configuration to mask unnecessary interrupt service.
174  *
175  * Assumption:
176  *	Using SDIO Local register ONLY for configuration.
177  */
disable_interrupt(PADAPTER adapter)178 static void disable_interrupt(PADAPTER adapter)
179 {
180 	PHAL_DATA_TYPE hal;
181 
182 
183 	hal = GET_HAL_DATA(adapter);
184 
185 	update_himr(adapter, 0);
186 	RTW_INFO("%s: update SDIO HIMR=0\n", __FUNCTION__);
187 }
188 
_run_thread(PADAPTER adapter)189 static void _run_thread(PADAPTER adapter)
190 {
191 #ifndef CONFIG_SDIO_TX_TASKLET
192 	struct xmit_priv *xmitpriv = &adapter->xmitpriv;
193 
194 	if (xmitpriv->SdioXmitThread == NULL) {
195 		RTW_INFO(FUNC_ADPT_FMT " start RTWHALXT\n", FUNC_ADPT_ARG(adapter));
196 		xmitpriv->SdioXmitThread = kthread_run(rtl8822bs_xmit_thread, adapter, "RTWHALXT");
197 		if (IS_ERR(xmitpriv->SdioXmitThread)) {
198 			RTW_ERR("%s: start rtl8822bs_xmit_thread FAIL!!\n", __FUNCTION__);
199 			xmitpriv->SdioXmitThread = NULL;
200 		}
201 	}
202 #endif /* !CONFIG_SDIO_TX_TASKLET */
203 }
204 
run_thread(PADAPTER adapter)205 static void run_thread(PADAPTER adapter)
206 {
207 	_run_thread(adapter);
208 	rtl8822b_run_thread(adapter);
209 }
210 
_cancel_thread(PADAPTER adapter)211 static void _cancel_thread(PADAPTER adapter)
212 {
213 #ifndef CONFIG_SDIO_TX_TASKLET
214 	struct xmit_priv *xmitpriv = &adapter->xmitpriv;
215 
216 	/* stop xmit_buf_thread */
217 	if (xmitpriv->SdioXmitThread) {
218 		_rtw_up_sema(&xmitpriv->SdioXmitSema);
219 		rtw_thread_stop(xmitpriv->SdioXmitThread);
220 		xmitpriv->SdioXmitThread = NULL;
221 	}
222 #endif /* !CONFIG_SDIO_TX_TASKLET */
223 }
224 
cancel_thread(PADAPTER adapter)225 static void cancel_thread(PADAPTER adapter)
226 {
227 	rtl8822b_cancel_thread(adapter);
228 	_cancel_thread(adapter);
229 }
230 
231 /*
232  * If variable not handled here,
233  * some variables will be processed in rtl8822b_sethwreg()
234  */
sethwreg(PADAPTER adapter,u8 variable,u8 * val)235 static u8 sethwreg(PADAPTER adapter, u8 variable, u8 *val)
236 {
237 	PHAL_DATA_TYPE hal;
238 	u8 ret = _SUCCESS;
239 	u8 val8;
240 
241 
242 	hal = GET_HAL_DATA(adapter);
243 
244 	switch (variable) {
245 	case HW_VAR_SET_RPWM:
246 		/*
247 		 * RPWM use follwoing bits:
248 		 * BIT0 - 1: 32K, 0: Normal Clock
249 		 * BIT6 - Ack Bit
250 		 * BIT7 - Toggling Bit
251 		 */
252 		val8 = PS_STATE(*val);
253 		/*
254 		 * PS_STATE == 0 is special case for initializing,
255 		 * and keep the value to be 0
256 		 */
257 		if (val8 && (val8 < PS_STATE_S2))
258 			val8 = BIT_REQ_PS_8822B;
259 		else
260 			val8 = 0;
261 
262 		if (*val & PS_ACK)
263 			val8 |= BIT_ACK_8822B;
264 		if (*val & PS_TOGGLE)
265 			val8 |= BIT_TOGGLE_8822B;
266 
267 		rtw_write8(adapter, REG_SDIO_HRPWM1_8822B, val8);
268 		break;
269 
270 	default:
271 		ret = rtl8822b_sethwreg(adapter, variable, val);
272 		break;
273 	}
274 
275 	return ret;
276 }
277 
278 /*
279  * If variable not handled here,
280  * some variables will be processed in GetHwReg8723B()
281  */
gethwreg(PADAPTER adapter,u8 variable,u8 * val)282 static void gethwreg(PADAPTER adapter, u8 variable, u8 *val)
283 {
284 	PHAL_DATA_TYPE hal;
285 	u8 val8;
286 
287 
288 	hal = GET_HAL_DATA(adapter);
289 
290 	switch (variable) {
291 	case HW_VAR_CPWM:
292 		val8 = rtw_read8(adapter, REG_SDIO_HCPWM1_V2_8822B);
293 
294 		if (val8 & BIT_CUR_PS_8822B)
295 			*val = PS_STATE_S0;
296 		else
297 			*val = PS_STATE_S4;
298 
299 		if (val8 & BIT_TOGGLE_8822B)
300 			*val |= PS_TOGGLE;
301 		break;
302 
303 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) || defined(CONFIG_FWLPS_IN_IPS)
304 	case HW_VAR_RPWM_TOG:
305 		*val = rtw_read8(adapter, REG_SDIO_HRPWM1_8822B);
306 		*val &= BIT_TOGGLE_8822B;
307 		break;
308 #endif
309 
310 	default:
311 		rtl8822b_gethwreg(adapter, variable, val);
312 		break;
313 	}
314 }
315 
316 /*
317  * Description:
318  *	Query setting of specified variable.
319  */
gethaldefvar(PADAPTER adapter,HAL_DEF_VARIABLE eVariable,void * pval)320 static u8 gethaldefvar(PADAPTER adapter, HAL_DEF_VARIABLE eVariable, void *pval)
321 {
322 	PHAL_DATA_TYPE hal;
323 	u8 bResult = _SUCCESS;
324 
325 
326 	hal = GET_HAL_DATA(adapter);
327 
328 	switch (eVariable) {
329 	case HW_VAR_MAX_RX_AMPDU_FACTOR:
330 		if (check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
331 			/* Set AMPDU Factor 32K for AP mode */
332 			*(HT_CAP_AMPDU_FACTOR *)pval = MAX_AMPDU_FACTOR_32K;
333 		else
334 			/* Default use MAX size */
335 			*(HT_CAP_AMPDU_FACTOR *)pval = MAX_AMPDU_FACTOR_64K;
336 		break;
337 
338 	default:
339 		bResult = rtl8822b_gethaldefvar(adapter, eVariable, pval);
340 		break;
341 	}
342 
343 	return bResult;
344 }
345 
346 /*
347  * Description:
348  *	Change default setting of specified variable.
349  */
sethaldefvar(PADAPTER adapter,HAL_DEF_VARIABLE eVariable,void * pval)350 static u8 sethaldefvar(PADAPTER adapter, HAL_DEF_VARIABLE eVariable, void *pval)
351 {
352 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
353 	u8 bResult = _SUCCESS;
354 
355 	switch (eVariable) {
356 	default:
357 		bResult = rtl8822b_sethaldefvar(adapter, eVariable, pval);
358 		break;
359 	}
360 
361 	return bResult;
362 }
363 
rtl8822bs_set_hal_ops(PADAPTER adapter)364 void rtl8822bs_set_hal_ops(PADAPTER adapter)
365 {
366 	struct hal_ops *ops;
367 	int err;
368 
369 
370 	err = rtl8822bs_halmac_init_adapter(adapter);
371 	if (err) {
372 		RTW_INFO("%s: [ERROR]HALMAC initialize FAIL!\n", __FUNCTION__);
373 		return;
374 	}
375 
376 	rtl8822b_set_hal_ops(adapter);
377 	init_interrupt(adapter);
378 
379 	ops = &adapter->hal_func;
380 
381 	ops->init_default_value = rtl8822bs_init_default_value;
382 	ops->intf_chip_configure = intf_chip_configure;
383 	ops->read_adapter_info = read_adapter_info;
384 
385 	ops->hal_init = rtl8822bs_init;
386 	ops->hal_deinit = rtl8822bs_deinit;
387 
388 	ops->init_xmit_priv = rtl8822bs_init_xmit_priv;
389 	ops->free_xmit_priv = rtl8822bs_free_xmit_priv;
390 	ops->hal_xmit = rtl8822bs_hal_xmit;
391 	ops->mgnt_xmit = rtl8822bs_mgnt_xmit;
392 	ops->hal_xmitframe_enqueue = rtl8822bs_hal_xmit_enqueue;
393 #ifdef CONFIG_XMIT_THREAD_MODE
394 	ops->xmit_thread_handler = rtl8822bs_xmit_buf_handler;
395 #endif
396 	ops->run_thread = run_thread;
397 	ops->cancel_thread = cancel_thread;
398 
399 	ops->init_recv_priv = rtl8822bs_init_recv_priv;
400 	ops->free_recv_priv = rtl8822bs_free_recv_priv;
401 #ifdef CONFIG_RECV_THREAD_MODE
402 	ops->recv_hdl = rtl8822bs_recv_hdl;
403 #endif
404 
405 	ops->enable_interrupt = enable_interrupt;
406 	ops->disable_interrupt = disable_interrupt;
407 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
408 	ops->clear_interrupt = clear_interrupt_all;
409 #endif
410 
411 #ifdef CONFIG_RTW_SW_LED
412 	ops->InitSwLeds = rtl8822bs_initswleds;
413 	ops->DeInitSwLeds = rtl8822bs_deinitswleds;
414 #endif
415 	ops->set_hw_reg_handler = sethwreg;
416 	ops->GetHwRegHandler = gethwreg;
417 	ops->get_hal_def_var_handler = gethaldefvar;
418 	ops->SetHalDefVarHandler = sethaldefvar;
419 }
420 
421 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
rtl8822bs_disable_interrupt_but_cpwm2(PADAPTER adapter)422 void rtl8822bs_disable_interrupt_but_cpwm2(PADAPTER adapter)
423 {
424 	u32 himr, tmp;
425 
426 	tmp = rtw_read32(adapter, REG_SDIO_HIMR);
427 	RTW_INFO("%s: Read SDIO_REG_HIMR: 0x%08x\n", __FUNCTION__, tmp);
428 
429 	himr = BIT_SDIO_CPWM2_MSK;
430 	update_himr(adapter, himr);
431 
432 	tmp = rtw_read32(adapter, REG_SDIO_HIMR);
433 	RTW_INFO("%s: Read again SDIO_REG_HIMR: 0x%08x\n", __FUNCTION__, tmp);
434 }
435 #endif /* CONFIG_WOWLAN */
436