xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_halmac.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /******************************************************************************
3  *
4  * Copyright(c) 2015 - 2019 Realtek Corporation.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of version 2 of the GNU General Public License as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13  * more details.
14  *
15  *****************************************************************************/
16 #define _HAL_HALMAC_C_
17 
18 #include <drv_types.h>		/* PADAPTER, struct dvobj_priv, SDIO_ERR_VAL8 and etc. */
19 #include <hal_data.h>		/* efuse, PHAL_DATA_TYPE and etc. */
20 #include "hal_halmac.h"		/* dvobj_to_halmac() and ect. */
21 
22 /*
23  * HALMAC take return value 0 for fail and 1 for success to replace
24  * _FALSE/_TRUE after V1_04_09
25  */
26 #define RTW_HALMAC_FAIL			0
27 #define RTW_HALMAC_SUCCESS		1
28 
29 #define DEFAULT_INDICATOR_TIMELMT	1000	/* ms */
30 #define MSG_PREFIX			"[HALMAC]"
31 
32 #define RTW_HALMAC_DLFW_MEM_NO_STOP_TX
33 #define RTW_HALMAC_FILTER_DRV_C2H	/* Block C2H owner=driver */
34 
35 /*
36  * Driver API for HALMAC operations
37  */
38 
39 #ifdef CONFIG_SDIO_HCI
40 #include <rtw_sdio.h>
41 
_halmac_mac_reg_page0_chk(const char * func,struct dvobj_priv * dvobj,u32 offset)42 static u8 _halmac_mac_reg_page0_chk(const char *func, struct dvobj_priv *dvobj, u32 offset)
43 {
44 #if defined(CONFIG_IO_CHECK_IN_ANA_LOW_CLK) && defined(CONFIG_LPS_LCLK)
45 	struct pwrctrl_priv *pwrpriv = &dvobj->pwrctl_priv;
46 	u32 mac_reg_offset = 0;
47 
48 	if (pwrpriv->pwr_mode == PS_MODE_ACTIVE)
49 		return _TRUE;
50 
51 	if (pwrpriv->lps_level == LPS_NORMAL)
52 		return _TRUE;
53 
54 	if (pwrpriv->rpwm >= PS_STATE_S2)
55 		return _TRUE;
56 
57 	if (offset & (WLAN_IOREG_DEVICE_ID << 13))  { /*WLAN_IOREG_OFFSET*/
58 		mac_reg_offset = offset & HALMAC_WLAN_MAC_REG_MSK;
59 		if (mac_reg_offset < 0x100) {
60 			RTW_ERR(FUNC_ADPT_FMT
61 				"access MAC REG -0x%04x in PS-mode:0x%02x (rpwm:0x%02x, lps_level:0x%02x)\n",
62 				FUNC_ADPT_ARG(dvobj_get_primary_adapter(dvobj)), mac_reg_offset,
63 				pwrpriv->pwr_mode, pwrpriv->rpwm, pwrpriv->lps_level);
64 			rtw_warn_on(1);
65 			return _FALSE;
66 		}
67 	}
68 #endif
69 	return _TRUE;
70 }
71 
_halmac_sdio_cmd52_read(void * p,u32 offset)72 static u8 _halmac_sdio_cmd52_read(void *p, u32 offset)
73 {
74 	struct dvobj_priv *d;
75 	u8 val;
76 	u8 ret;
77 
78 
79 	d = (struct dvobj_priv *)p;
80 	_halmac_mac_reg_page0_chk(__func__, d, offset);
81 	ret = rtw_sdio_read_cmd52(d, offset, &val, 1);
82 	if (_FAIL == ret) {
83 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
84 		return SDIO_ERR_VAL8;
85 	}
86 
87 	return val;
88 }
89 
_halmac_sdio_cmd52_write(void * p,u32 offset,u8 val)90 static void _halmac_sdio_cmd52_write(void *p, u32 offset, u8 val)
91 {
92 	struct dvobj_priv *d;
93 	u8 ret;
94 
95 
96 	d = (struct dvobj_priv *)p;
97 	_halmac_mac_reg_page0_chk(__func__, d, offset);
98 	ret = rtw_sdio_write_cmd52(d, offset, &val, 1);
99 	if (_FAIL == ret)
100 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
101 }
102 
_halmac_sdio_reg_read_8(void * p,u32 offset)103 static u8 _halmac_sdio_reg_read_8(void *p, u32 offset)
104 {
105 	struct dvobj_priv *d;
106 	u8 *pbuf;
107 	u8 val;
108 	u8 ret;
109 
110 
111 	d = (struct dvobj_priv *)p;
112 	val = SDIO_ERR_VAL8;
113 	_halmac_mac_reg_page0_chk(__func__, d, offset);
114 	pbuf = rtw_zmalloc(1);
115 	if (!pbuf)
116 		return val;
117 
118 	ret = rtw_sdio_read_cmd53(d, offset, pbuf, 1);
119 	if (ret == _FAIL) {
120 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
121 		goto exit;
122 	}
123 
124 	val = *pbuf;
125 
126 exit:
127 	rtw_mfree(pbuf, 1);
128 
129 	return val;
130 }
131 
_halmac_sdio_reg_read_16(void * p,u32 offset)132 static u16 _halmac_sdio_reg_read_16(void *p, u32 offset)
133 {
134 	struct dvobj_priv *d;
135 	u8 *pbuf;
136 	u16 val;
137 	u8 ret;
138 
139 
140 	d = (struct dvobj_priv *)p;
141 	val = SDIO_ERR_VAL16;
142 	_halmac_mac_reg_page0_chk(__func__, d, offset);
143 	pbuf = rtw_zmalloc(2);
144 	if (!pbuf)
145 		return val;
146 
147 	ret = rtw_sdio_read_cmd53(d, offset, pbuf, 2);
148 	if (ret == _FAIL) {
149 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
150 		goto exit;
151 	}
152 
153 	val = le16_to_cpu(*(u16 *)pbuf);
154 
155 exit:
156 	rtw_mfree(pbuf, 2);
157 
158 	return val;
159 }
160 
_halmac_sdio_reg_read_32(void * p,u32 offset)161 static u32 _halmac_sdio_reg_read_32(void *p, u32 offset)
162 {
163 	struct dvobj_priv *d;
164 	u8 *pbuf;
165 	u32 val;
166 	u8 ret;
167 
168 
169 	d = (struct dvobj_priv *)p;
170 	val = SDIO_ERR_VAL32;
171 	_halmac_mac_reg_page0_chk(__func__, d, offset);
172 	pbuf = rtw_zmalloc(4);
173 	if (!pbuf)
174 		return val;
175 
176 	ret = rtw_sdio_read_cmd53(d, offset, pbuf, 4);
177 	if (ret == _FAIL) {
178 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
179 		goto exit;
180 	}
181 
182 	val = le32_to_cpu(*(u32 *)pbuf);
183 
184 exit:
185 	rtw_mfree(pbuf, 4);
186 
187 	return val;
188 }
189 
_halmac_sdio_reg_read_n(void * p,u32 offset,u32 size,u8 * data)190 static u8 _halmac_sdio_reg_read_n(void *p, u32 offset, u32 size, u8 *data)
191 {
192 	struct dvobj_priv *d = (struct dvobj_priv *)p;
193 	u8 *pbuf;
194 	u8 ret;
195 	u8 rst = RTW_HALMAC_FAIL;
196 	u32 sdio_read_size;
197 
198 
199 	if (!data)
200 		return rst;
201 
202 	sdio_read_size = RND4(size);
203 	sdio_read_size = rtw_sdio_cmd53_align_size(d, sdio_read_size);
204 
205 	pbuf = rtw_zmalloc(sdio_read_size);
206 	if (!pbuf)
207 		return rst;
208 
209 	ret = rtw_sdio_read_cmd53(d, offset, pbuf, sdio_read_size);
210 	if (ret == _FAIL) {
211 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
212 		goto exit;
213 	}
214 
215 	_rtw_memcpy(data, pbuf, size);
216 	rst = RTW_HALMAC_SUCCESS;
217 exit:
218 	rtw_mfree(pbuf, sdio_read_size);
219 
220 	return rst;
221 }
222 
_halmac_sdio_reg_write_8(void * p,u32 offset,u8 val)223 static void _halmac_sdio_reg_write_8(void *p, u32 offset, u8 val)
224 {
225 	struct dvobj_priv *d;
226 	u8 *pbuf;
227 	u8 ret;
228 
229 
230 	d = (struct dvobj_priv *)p;
231 	_halmac_mac_reg_page0_chk(__func__, d, offset);
232 	pbuf = rtw_zmalloc(1);
233 	if (!pbuf)
234 		return;
235 	_rtw_memcpy(pbuf, &val, 1);
236 
237 	ret = rtw_sdio_write_cmd53(d, offset, pbuf, 1);
238 	if (ret == _FAIL)
239 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
240 
241 	rtw_mfree(pbuf, 1);
242 }
243 
_halmac_sdio_reg_write_16(void * p,u32 offset,u16 val)244 static void _halmac_sdio_reg_write_16(void *p, u32 offset, u16 val)
245 {
246 	struct dvobj_priv *d;
247 	u8 *pbuf;
248 	u8 ret;
249 
250 
251 	d = (struct dvobj_priv *)p;
252 	_halmac_mac_reg_page0_chk(__func__, d, offset);
253 	val = cpu_to_le16(val);
254 	pbuf = rtw_zmalloc(2);
255 	if (!pbuf)
256 		return;
257 	_rtw_memcpy(pbuf, &val, 2);
258 
259 	ret = rtw_sdio_write_cmd53(d, offset, pbuf, 2);
260 	if (ret == _FAIL)
261 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
262 
263 	rtw_mfree(pbuf, 2);
264 }
265 
_halmac_sdio_reg_write_32(void * p,u32 offset,u32 val)266 static void _halmac_sdio_reg_write_32(void *p, u32 offset, u32 val)
267 {
268 	struct dvobj_priv *d;
269 	u8 *pbuf;
270 	u8 ret;
271 
272 
273 	d = (struct dvobj_priv *)p;
274 	_halmac_mac_reg_page0_chk(__func__, d, offset);
275 	val = cpu_to_le32(val);
276 	pbuf = rtw_zmalloc(4);
277 	if (!pbuf)
278 		return;
279 	_rtw_memcpy(pbuf, &val, 4);
280 
281 	ret = rtw_sdio_write_cmd53(d, offset, pbuf, 4);
282 	if (ret == _FAIL)
283 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
284 
285 	rtw_mfree(pbuf, 4);
286 }
287 
_halmac_sdio_read_cia(void * p,u32 offset)288 static u8 _halmac_sdio_read_cia(void *p, u32 offset)
289 {
290 	struct dvobj_priv *d;
291 	u8 data = 0;
292 	u8 ret;
293 
294 
295 	d = (struct dvobj_priv *)p;
296 
297 	ret = rtw_sdio_f0_read(d, offset, &data, 1);
298 	if (ret == _FAIL)
299 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
300 
301 	return data;
302 }
303 
304 #else /* !CONFIG_SDIO_HCI */
305 
_halmac_reg_read_8(void * p,u32 offset)306 static u8 _halmac_reg_read_8(void *p, u32 offset)
307 {
308 	struct dvobj_priv *d;
309 	PADAPTER adapter;
310 
311 
312 	d = (struct dvobj_priv *)p;
313 	adapter = dvobj_get_primary_adapter(d);
314 
315 	return _rtw_read8(adapter, offset);
316 }
317 
_halmac_reg_read_16(void * p,u32 offset)318 static u16 _halmac_reg_read_16(void *p, u32 offset)
319 {
320 	struct dvobj_priv *d;
321 	PADAPTER adapter;
322 
323 
324 	d = (struct dvobj_priv *)p;
325 	adapter = dvobj_get_primary_adapter(d);
326 
327 	return _rtw_read16(adapter, offset);
328 }
329 
_halmac_reg_read_32(void * p,u32 offset)330 static u32 _halmac_reg_read_32(void *p, u32 offset)
331 {
332 	struct dvobj_priv *d;
333 	PADAPTER adapter;
334 
335 
336 	d = (struct dvobj_priv *)p;
337 	adapter = dvobj_get_primary_adapter(d);
338 
339 	return _rtw_read32(adapter, offset);
340 }
341 
_halmac_reg_write_8(void * p,u32 offset,u8 val)342 static void _halmac_reg_write_8(void *p, u32 offset, u8 val)
343 {
344 	struct dvobj_priv *d;
345 	PADAPTER adapter;
346 	int err;
347 
348 
349 	d = (struct dvobj_priv *)p;
350 	adapter = dvobj_get_primary_adapter(d);
351 
352 	err = _rtw_write8(adapter, offset, val);
353 	if (err == _FAIL)
354 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
355 }
356 
_halmac_reg_write_16(void * p,u32 offset,u16 val)357 static void _halmac_reg_write_16(void *p, u32 offset, u16 val)
358 {
359 	struct dvobj_priv *d;
360 	PADAPTER adapter;
361 	int err;
362 
363 
364 	d = (struct dvobj_priv *)p;
365 	adapter = dvobj_get_primary_adapter(d);
366 
367 	err = _rtw_write16(adapter, offset, val);
368 	if (err == _FAIL)
369 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
370 }
371 
_halmac_reg_write_32(void * p,u32 offset,u32 val)372 static void _halmac_reg_write_32(void *p, u32 offset, u32 val)
373 {
374 	struct dvobj_priv *d;
375 	PADAPTER adapter;
376 	int err;
377 
378 
379 	d = (struct dvobj_priv *)p;
380 	adapter = dvobj_get_primary_adapter(d);
381 
382 	err = _rtw_write32(adapter, offset, val);
383 	if (err == _FAIL)
384 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
385 }
386 #endif /* !CONFIG_SDIO_HCI */
387 
388 #ifdef DBG_IO
_halmac_reg_read_monitor(void * p,u32 addr,u32 len,u32 val,const char * caller,const u32 line)389 static void _halmac_reg_read_monitor(void *p, u32 addr, u32 len, u32 val
390 	, const char *caller, const u32 line)
391 {
392 	struct dvobj_priv *d = (struct dvobj_priv *)p;
393 	_adapter *adapter = dvobj_get_primary_adapter(d);
394 
395 	dbg_rtw_reg_read_monitor(adapter, addr, len, val, caller, line);
396 }
397 
_halmac_reg_write_monitor(void * p,u32 addr,u32 len,u32 val,const char * caller,const u32 line)398 static void _halmac_reg_write_monitor(void *p, u32 addr, u32 len, u32 val
399 	, const char *caller, const u32 line)
400 {
401 	struct dvobj_priv *d = (struct dvobj_priv *)p;
402 	_adapter *adapter = dvobj_get_primary_adapter(d);
403 
404 	dbg_rtw_reg_write_monitor(adapter, addr, len, val, caller, line);
405 }
406 #endif
407 
_halmac_mfree(void * p,void * buffer,u32 size)408 static u8 _halmac_mfree(void *p, void *buffer, u32 size)
409 {
410 	rtw_mfree(buffer, size);
411 	return RTW_HALMAC_SUCCESS;
412 }
413 
_halmac_malloc(void * p,u32 size)414 static void *_halmac_malloc(void *p, u32 size)
415 {
416 	return rtw_zmalloc(size);
417 }
418 
_halmac_memcpy(void * p,void * dest,void * src,u32 size)419 static u8 _halmac_memcpy(void *p, void *dest, void *src, u32 size)
420 {
421 	_rtw_memcpy(dest, src, size);
422 	return RTW_HALMAC_SUCCESS;
423 }
424 
_halmac_memset(void * p,void * addr,u8 value,u32 size)425 static u8 _halmac_memset(void *p, void *addr, u8 value, u32 size)
426 {
427 	_rtw_memset(addr, value, size);
428 	return RTW_HALMAC_SUCCESS;
429 }
430 
_halmac_udelay(void * p,u32 us)431 static void _halmac_udelay(void *p, u32 us)
432 {
433 	/* Most hardware polling wait time < 50us) */
434 	if (us <= 50)
435 		rtw_udelay_os(us);
436 	else if (us <= 1000)
437 		rtw_usleep_os(us);
438 	else
439 		rtw_msleep_os(RTW_DIV_ROUND_UP(us, 1000));
440 }
441 
_halmac_mutex_init(void * p,HALMAC_MUTEX * pMutex)442 static u8 _halmac_mutex_init(void *p, HALMAC_MUTEX *pMutex)
443 {
444 	_rtw_mutex_init(pMutex);
445 	return RTW_HALMAC_SUCCESS;
446 }
447 
_halmac_mutex_deinit(void * p,HALMAC_MUTEX * pMutex)448 static u8 _halmac_mutex_deinit(void *p, HALMAC_MUTEX *pMutex)
449 {
450 	_rtw_mutex_free(pMutex);
451 	return RTW_HALMAC_SUCCESS;
452 }
453 
_halmac_mutex_lock(void * p,HALMAC_MUTEX * pMutex)454 static u8 _halmac_mutex_lock(void *p, HALMAC_MUTEX *pMutex)
455 {
456 	int err;
457 
458 	err = _enter_critical_mutex(pMutex, NULL);
459 	if (err)
460 		return RTW_HALMAC_FAIL;
461 
462 	return RTW_HALMAC_SUCCESS;
463 }
464 
_halmac_mutex_unlock(void * p,HALMAC_MUTEX * pMutex)465 static u8 _halmac_mutex_unlock(void *p, HALMAC_MUTEX *pMutex)
466 {
467 	_exit_critical_mutex(pMutex, NULL);
468 	return RTW_HALMAC_SUCCESS;
469 }
470 
471 #ifndef CONFIG_SDIO_HCI
472 #define DBG_MSG_FILTER
473 #endif
474 
475 #ifdef DBG_MSG_FILTER
is_msg_allowed(uint drv_lv,u8 msg_lv)476 static u8 is_msg_allowed(uint drv_lv, u8 msg_lv)
477 {
478 	switch (drv_lv) {
479 	case _DRV_NONE_:
480 		return _FALSE;
481 
482 	case _DRV_ALWAYS_:
483 		if (msg_lv > HALMAC_DBG_ALWAYS)
484 			return _FALSE;
485 		break;
486 	case _DRV_ERR_:
487 		if (msg_lv > HALMAC_DBG_ERR)
488 			return _FALSE;
489 		break;
490 	case _DRV_WARNING_:
491 		if (msg_lv > HALMAC_DBG_WARN)
492 			return _FALSE;
493 		break;
494 	case _DRV_INFO_:
495 		if (msg_lv >= HALMAC_DBG_TRACE)
496 			return _FALSE;
497 		break;
498 	}
499 
500 	return _TRUE;
501 }
502 #endif /* DBG_MSG_FILTER */
503 
_halmac_msg_print(void * p,u32 msg_type,u8 msg_level,s8 * fmt,...)504 static u8 _halmac_msg_print(void *p, u32 msg_type, u8 msg_level, s8 *fmt, ...)
505 {
506 #define MSG_LEN		100
507 	va_list args;
508 	u8 str[MSG_LEN] = {0};
509 #ifdef DBG_MSG_FILTER
510 	uint drv_level = _DRV_NONE_;
511 #endif
512 	int err;
513 	u8 ret = RTW_HALMAC_SUCCESS;
514 
515 
516 #ifdef DBG_MSG_FILTER
517 #ifdef CONFIG_RTW_DEBUG
518 	drv_level = rtw_drv_log_level;
519 #endif
520 	if (is_msg_allowed(drv_level, msg_level) == _FALSE)
521 		return ret;
522 #endif
523 
524 	str[0] = '\n';
525 	va_start(args, fmt);
526 	err = vsnprintf(str, MSG_LEN, fmt, args);
527 	va_end(args);
528 
529 	/* An output error is encountered */
530 	if (err < 0)
531 		return RTW_HALMAC_FAIL;
532 	/* Output may be truncated due to size limit */
533 	if ((err == (MSG_LEN - 1)) && (str[MSG_LEN - 2] != '\n'))
534 		ret = RTW_HALMAC_FAIL;
535 
536 	if (msg_level == HALMAC_DBG_ALWAYS)
537 		RTW_PRINT(MSG_PREFIX "%s", str);
538 	else if (msg_level <= HALMAC_DBG_ERR)
539 		RTW_ERR(MSG_PREFIX "%s", str);
540 	else if (msg_level <= HALMAC_DBG_WARN)
541 		RTW_WARN(MSG_PREFIX "%s", str);
542 	else
543 		RTW_DBG(MSG_PREFIX "%s", str);
544 
545 	return ret;
546 }
547 
_halmac_buff_print(void * p,u32 msg_type,u8 msg_level,s8 * buf,u32 size)548 static u8 _halmac_buff_print(void *p, u32 msg_type, u8 msg_level, s8 *buf, u32 size)
549 {
550 	if (msg_level <= HALMAC_DBG_WARN)
551 		RTW_INFO_DUMP(MSG_PREFIX, buf, size);
552 	else
553 		RTW_DBG_DUMP(MSG_PREFIX, buf, size);
554 
555 	return RTW_HALMAC_SUCCESS;
556 }
557 
558 
559 const char *const RTW_HALMAC_FEATURE_NAME[] = {
560 	"HALMAC_FEATURE_CFG_PARA",
561 	"HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE",
562 	"HALMAC_FEATURE_DUMP_LOGICAL_EFUSE",
563 	"HALMAC_FEATURE_DUMP_LOGICAL_EFUSE_MASK",
564 	"HALMAC_FEATURE_UPDATE_PACKET",
565 	"HALMAC_FEATURE_SEND_SCAN_PACKET",
566 	"HALMAC_FEATURE_DROP_SCAN_PACKET",
567 	"HALMAC_FEATURE_UPDATE_DATAPACK",
568 	"HALMAC_FEATURE_RUN_DATAPACK",
569 	"HALMAC_FEATURE_CHANNEL_SWITCH",
570 	"HALMAC_FEATURE_IQK",
571 	"HALMAC_FEATURE_POWER_TRACKING",
572 	"HALMAC_FEATURE_PSD",
573 	"HALMAC_FEATURE_FW_SNDING",
574 	"HALMAC_FEATURE_DPK",
575 	"HALMAC_FEATURE_ALL"
576 };
577 
is_valid_id_status(enum halmac_feature_id id,enum halmac_cmd_process_status status)578 static inline u8 is_valid_id_status(enum halmac_feature_id id, enum halmac_cmd_process_status status)
579 {
580 	switch (id) {
581 	case HALMAC_FEATURE_CFG_PARA:
582 		RTW_DBG("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
583 		break;
584 	case HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE:
585 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
586 		if (HALMAC_CMD_PROCESS_DONE != status)
587 			RTW_INFO("%s: id(%d) unspecified status(%d)!\n",
588 				 __FUNCTION__, id, status);
589 		break;
590 	case HALMAC_FEATURE_DUMP_LOGICAL_EFUSE:
591 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
592 		if (HALMAC_CMD_PROCESS_DONE != status)
593 			RTW_INFO("%s: id(%d) unspecified status(%d)!\n",
594 				 __FUNCTION__, id, status);
595 		break;
596 	case HALMAC_FEATURE_UPDATE_PACKET:
597 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
598 		if (status != HALMAC_CMD_PROCESS_DONE)
599 			RTW_INFO("%s: id(%d) unspecified status(%d)!\n",
600 				 __FUNCTION__, id, status);
601 		break;
602 	case HALMAC_FEATURE_UPDATE_DATAPACK:
603 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
604 		break;
605 	case HALMAC_FEATURE_RUN_DATAPACK:
606 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
607 		break;
608 	case HALMAC_FEATURE_CHANNEL_SWITCH:
609 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
610 		if ((status != HALMAC_CMD_PROCESS_DONE) && (status != HALMAC_CMD_PROCESS_RCVD))
611 			RTW_INFO("%s: id(%d) unspecified status(%d)!\n",
612 				 __FUNCTION__, id, status);
613 		if (status == HALMAC_CMD_PROCESS_DONE)
614 			return _FALSE;
615 		break;
616 	case HALMAC_FEATURE_IQK:
617 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
618 		break;
619 	case HALMAC_FEATURE_POWER_TRACKING:
620 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
621 		break;
622 	case HALMAC_FEATURE_PSD:
623 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
624 		break;
625 	case HALMAC_FEATURE_FW_SNDING:
626 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
627 		break;
628 	case HALMAC_FEATURE_DPK:
629 		if (status == HALMAC_CMD_PROCESS_RCVD)
630 			return _FALSE;
631 		if ((status != HALMAC_CMD_PROCESS_DONE)
632 		    || (status != HALMAC_CMD_PROCESS_ERROR))
633 			RTW_WARN("%s: %s unexpected status(0x%x)!\n",
634 				 __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id],
635 				 status);
636 		break;
637 	case HALMAC_FEATURE_ALL:
638 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
639 		break;
640 	default:
641 		RTW_ERR("%s: unknown feature id(%d)\n", __FUNCTION__, id);
642 		return _FALSE;
643 	}
644 
645 	return _TRUE;
646 }
647 
init_halmac_event_with_waittime(struct dvobj_priv * d,enum halmac_feature_id id,u8 * buf,u32 size,u32 time)648 static int init_halmac_event_with_waittime(struct dvobj_priv *d, enum halmac_feature_id id, u8 *buf, u32 size, u32 time)
649 {
650 	struct submit_ctx *sctx;
651 
652 
653 	if (!d->hmpriv.indicator[id].sctx) {
654 		sctx = (struct submit_ctx *)rtw_zmalloc(sizeof(*sctx));
655 		if (!sctx)
656 			return -1;
657 	} else {
658 		RTW_WARN("%s: id(%d) sctx is not NULL!!\n", __FUNCTION__, id);
659 		sctx = d->hmpriv.indicator[id].sctx;
660 		d->hmpriv.indicator[id].sctx = NULL;
661 	}
662 
663 	rtw_sctx_init(sctx, time);
664 	d->hmpriv.indicator[id].buffer = buf;
665 	d->hmpriv.indicator[id].buf_size = size;
666 	d->hmpriv.indicator[id].ret_size = 0;
667 	d->hmpriv.indicator[id].status = 0;
668 	/* fill sctx at least to sure other variables are all ready! */
669 	d->hmpriv.indicator[id].sctx = sctx;
670 
671 	return 0;
672 }
673 
init_halmac_event(struct dvobj_priv * d,enum halmac_feature_id id,u8 * buf,u32 size)674 static inline int init_halmac_event(struct dvobj_priv *d, enum halmac_feature_id id, u8 *buf, u32 size)
675 {
676 	return init_halmac_event_with_waittime(d, id, buf, size, DEFAULT_INDICATOR_TIMELMT);
677 }
678 
free_halmac_event(struct dvobj_priv * d,enum halmac_feature_id id)679 static void free_halmac_event(struct dvobj_priv *d, enum halmac_feature_id id)
680 {
681 	struct submit_ctx *sctx;
682 
683 
684 	if (!d->hmpriv.indicator[id].sctx)
685 		return;
686 
687 	sctx = d->hmpriv.indicator[id].sctx;
688 	d->hmpriv.indicator[id].sctx = NULL;
689 	rtw_mfree((u8 *)sctx, sizeof(*sctx));
690 }
691 
wait_halmac_event(struct dvobj_priv * d,enum halmac_feature_id id)692 static int wait_halmac_event(struct dvobj_priv *d, enum halmac_feature_id id)
693 {
694 	struct halmac_adapter *mac;
695 	struct halmac_api *api;
696 	struct submit_ctx *sctx;
697 	int status;
698 	int ret;
699 
700 
701 	sctx = d->hmpriv.indicator[id].sctx;
702 	if (!sctx)
703 		return -1;
704 
705 	ret = rtw_sctx_wait(sctx, RTW_HALMAC_FEATURE_NAME[id]);
706 	status = sctx->status;
707 	free_halmac_event(d, id);
708 	if (_SUCCESS == ret)
709 		return 0;
710 
711 	/* If no one change sctx->status, it is timeout case */
712 	if (status == 0)
713 		status = RTW_SCTX_DONE_TIMEOUT;
714 	RTW_ERR("%s: id(%d, %s) status=0x%x ! Reset HALMAC state!\n",
715 		__FUNCTION__, id, RTW_HALMAC_FEATURE_NAME[id], status);
716 	mac = dvobj_to_halmac(d);
717 	api = HALMAC_GET_API(mac);
718 	api->halmac_reset_feature(mac, id);
719 
720 	return -1;
721 }
722 
723 /*
724  * Return:
725  *	Always return RTW_HALMAC_SUCCESS, HALMAC don't care the return value.
726  */
_halmac_event_indication(void * p,enum halmac_feature_id feature_id,enum halmac_cmd_process_status process_status,u8 * buf,u32 size)727 static u8 _halmac_event_indication(void *p, enum halmac_feature_id feature_id,
728 				enum halmac_cmd_process_status process_status,
729 				u8 *buf, u32 size)
730 {
731 	struct dvobj_priv *d;
732 	PADAPTER adapter;
733 	PHAL_DATA_TYPE hal;
734 	struct halmac_indicator *tbl, *indicator;
735 	struct submit_ctx *sctx;
736 	u32 cpsz;
737 	u8 ret;
738 
739 
740 	d = (struct dvobj_priv *)p;
741 	adapter = dvobj_get_primary_adapter(d);
742 	hal = GET_HAL_DATA(adapter);
743 	tbl = d->hmpriv.indicator;
744 
745 	/* Filter(Skip) middle status indication */
746 	ret = is_valid_id_status(feature_id, process_status);
747 	if (_FALSE == ret)
748 		goto exit;
749 
750 	indicator = &tbl[feature_id];
751 	indicator->status = process_status;
752 	indicator->ret_size = size;
753 	if (!indicator->sctx) {
754 		RTW_WARN("%s: id(%d, %s) is not waiting!!\n", __FUNCTION__,
755 			 feature_id, RTW_HALMAC_FEATURE_NAME[feature_id]);
756 		goto exit;
757 	}
758 	sctx = indicator->sctx;
759 
760 	if (HALMAC_CMD_PROCESS_ERROR == process_status) {
761 		RTW_ERR("%s: id(%d, %s) Something wrong!!\n", __FUNCTION__,
762 			feature_id, RTW_HALMAC_FEATURE_NAME[feature_id]);
763 		if ((size == 1) && buf)
764 			RTW_ERR("%s: error code=0x%x\n", __FUNCTION__, *buf);
765 		rtw_sctx_done_err(&sctx, RTW_SCTX_DONE_UNKNOWN);
766 		goto exit;
767 	}
768 
769 	if (size > indicator->buf_size) {
770 		RTW_WARN("%s: id(%d, %s) buffer is not enough(%d<%d), "
771 			 "and data will be truncated!\n",
772 			 __FUNCTION__,
773 			 feature_id, RTW_HALMAC_FEATURE_NAME[feature_id],
774 			 indicator->buf_size, size);
775 		cpsz = indicator->buf_size;
776 	} else {
777 		cpsz = size;
778 	}
779 	if (cpsz && indicator->buffer)
780 		_rtw_memcpy(indicator->buffer, buf, cpsz);
781 
782 	rtw_sctx_done(&sctx);
783 
784 exit:
785 	return RTW_HALMAC_SUCCESS;
786 }
787 
788 struct halmac_platform_api rtw_halmac_platform_api = {
789 	/* R/W register */
790 #ifdef CONFIG_SDIO_HCI
791 	.SDIO_CMD52_READ = _halmac_sdio_cmd52_read,
792 	.SDIO_CMD53_READ_8 = _halmac_sdio_reg_read_8,
793 	.SDIO_CMD53_READ_16 = _halmac_sdio_reg_read_16,
794 	.SDIO_CMD53_READ_32 = _halmac_sdio_reg_read_32,
795 	.SDIO_CMD53_READ_N = _halmac_sdio_reg_read_n,
796 	.SDIO_CMD52_WRITE = _halmac_sdio_cmd52_write,
797 	.SDIO_CMD53_WRITE_8 = _halmac_sdio_reg_write_8,
798 	.SDIO_CMD53_WRITE_16 = _halmac_sdio_reg_write_16,
799 	.SDIO_CMD53_WRITE_32 = _halmac_sdio_reg_write_32,
800 	.SDIO_CMD52_CIA_READ = _halmac_sdio_read_cia,
801 #endif /* CONFIG_SDIO_HCI */
802 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
803 	.REG_READ_8 = _halmac_reg_read_8,
804 	.REG_READ_16 = _halmac_reg_read_16,
805 	.REG_READ_32 = _halmac_reg_read_32,
806 	.REG_WRITE_8 = _halmac_reg_write_8,
807 	.REG_WRITE_16 = _halmac_reg_write_16,
808 	.REG_WRITE_32 = _halmac_reg_write_32,
809 #endif /* CONFIG_USB_HCI || CONFIG_PCI_HCI */
810 
811 #ifdef DBG_IO
812 	.READ_MONITOR = _halmac_reg_read_monitor,
813 	.WRITE_MONITOR = _halmac_reg_write_monitor,
814 #endif
815 
816 	/* Write data */
817 #if 0
818 	/* impletement in HAL-IC level */
819 	.SEND_RSVD_PAGE = sdio_write_data_rsvd_page,
820 	.SEND_H2C_PKT = sdio_write_data_h2c,
821 #endif
822 	/* Memory allocate */
823 	.RTL_FREE = _halmac_mfree,
824 	.RTL_MALLOC = _halmac_malloc,
825 	.RTL_MEMCPY = _halmac_memcpy,
826 	.RTL_MEMSET = _halmac_memset,
827 
828 	/* Sleep */
829 	.RTL_DELAY_US = _halmac_udelay,
830 
831 	/* Process Synchronization */
832 	.MUTEX_INIT = _halmac_mutex_init,
833 	.MUTEX_DEINIT = _halmac_mutex_deinit,
834 	.MUTEX_LOCK = _halmac_mutex_lock,
835 	.MUTEX_UNLOCK = _halmac_mutex_unlock,
836 
837 	.MSG_PRINT = _halmac_msg_print,
838 	.BUFF_PRINT = _halmac_buff_print,
839 	.EVENT_INDICATION = _halmac_event_indication,
840 };
841 
rtw_halmac_read8(struct intf_hdl * pintfhdl,u32 addr)842 u8 rtw_halmac_read8(struct intf_hdl *pintfhdl, u32 addr)
843 {
844 	struct halmac_adapter *mac;
845 	struct halmac_api *api;
846 
847 
848 	/* WARNING: pintf_dev should not be null! */
849 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
850 	api = HALMAC_GET_API(mac);
851 
852 	return api->halmac_reg_read_8(mac, addr);
853 }
854 
rtw_halmac_read16(struct intf_hdl * pintfhdl,u32 addr)855 u16 rtw_halmac_read16(struct intf_hdl *pintfhdl, u32 addr)
856 {
857 	struct halmac_adapter *mac;
858 	struct halmac_api *api;
859 
860 
861 	/* WARNING: pintf_dev should not be null! */
862 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
863 	api = HALMAC_GET_API(mac);
864 
865 	return api->halmac_reg_read_16(mac, addr);
866 }
867 
rtw_halmac_read32(struct intf_hdl * pintfhdl,u32 addr)868 u32 rtw_halmac_read32(struct intf_hdl *pintfhdl, u32 addr)
869 {
870 	struct halmac_adapter *mac;
871 	struct halmac_api *api;
872 
873 
874 	/* WARNING: pintf_dev should not be null! */
875 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
876 	api = HALMAC_GET_API(mac);
877 
878 	return api->halmac_reg_read_32(mac, addr);
879 }
880 
_read_register(struct dvobj_priv * d,u32 addr,u32 cnt,u8 * buf)881 static void _read_register(struct dvobj_priv *d, u32 addr, u32 cnt, u8 *buf)
882 {
883 #if 1
884 	struct _ADAPTER *a;
885 	u32 i, n;
886 	u16 val16;
887 	u32 val32;
888 
889 
890 	a = dvobj_get_primary_adapter(d);
891 
892 	i = addr & 0x3;
893 	/* Handle address not start from 4 bytes alignment case */
894 	if (i) {
895 		val32 = cpu_to_le32(rtw_read32(a, addr & ~0x3));
896 		n = 4 - i;
897 		_rtw_memcpy(buf, ((u8 *)&val32) + i, n);
898 		i = n;
899 		cnt -= n;
900 	}
901 
902 	while (cnt) {
903 		if (cnt >= 4)
904 			n = 4;
905 		else if (cnt >= 2)
906 			n = 2;
907 		else
908 			n = 1;
909 		cnt -= n;
910 
911 		switch (n) {
912 		case 1:
913 			buf[i] = rtw_read8(a, addr+i);
914 			i++;
915 			break;
916 		case 2:
917 			val16 = cpu_to_le16(rtw_read16(a, addr+i));
918 			_rtw_memcpy(&buf[i], &val16, 2);
919 			i += 2;
920 			break;
921 		case 4:
922 			val32 = cpu_to_le32(rtw_read32(a, addr+i));
923 			_rtw_memcpy(&buf[i], &val32, 4);
924 			i += 4;
925 			break;
926 		}
927 	}
928 #else
929 	struct _ADAPTER *a;
930 	u32 i;
931 
932 
933 	a = dvobj_get_primary_adapter(d);
934 	for (i = 0; i < cnt; i++)
935 		buf[i] = rtw_read8(a, addr + i);
936 #endif
937 }
938 
939 #ifdef CONFIG_SDIO_HCI
_sdio_read_local(struct dvobj_priv * d,u32 addr,u32 cnt,u8 * buf)940 static int _sdio_read_local(struct dvobj_priv *d, u32 addr, u32 cnt, u8 *buf)
941 {
942 	struct halmac_adapter *mac;
943 	struct halmac_api *api;
944 	enum halmac_ret_status status;
945 
946 
947 	if (buf == NULL)
948 		return -1;
949 
950 	mac = dvobj_to_halmac(d);
951 	api = HALMAC_GET_API(mac);
952 
953 	status = api->halmac_reg_sdio_cmd53_read_n(mac, addr, cnt, buf);
954 	if (status != HALMAC_RET_SUCCESS) {
955 		RTW_ERR("%s: addr=0x%08x cnt=%d err=%d\n",
956 			__FUNCTION__, addr, cnt, status);
957 		return -1;
958 	}
959 
960 	return 0;
961 }
962 #endif /* CONFIG_SDIO_HCI */
963 
rtw_halmac_read_mem(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * pmem)964 void rtw_halmac_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem)
965 {
966 	struct dvobj_priv *d;
967 
968 
969 	if (pmem == NULL) {
970 		RTW_ERR("pmem is NULL\n");
971 		return;
972 	}
973 
974 	d = pintfhdl->pintf_dev;
975 
976 #ifdef CONFIG_SDIO_HCI
977 	if (addr & 0xFFFF0000) {
978 		int err = 0;
979 
980 		err = _sdio_read_local(d, addr, cnt, pmem);
981 		if (!err)
982 			return;
983 	}
984 #endif /* CONFIG_SDIO_HCI */
985 
986 	_read_register(d, addr, cnt, pmem);
987 }
988 
989 #ifdef CONFIG_SDIO_INDIRECT_ACCESS
rtw_halmac_iread8(struct intf_hdl * pintfhdl,u32 addr)990 u8 rtw_halmac_iread8(struct intf_hdl *pintfhdl, u32 addr)
991 {
992 	struct halmac_adapter *mac;
993 	struct halmac_api *api;
994 
995 	/* WARNING: pintf_dev should not be null! */
996 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
997 	api = HALMAC_GET_API(mac);
998 
999 	/*return api->halmac_reg_read_indirect_8(mac, addr);*/
1000 	return api->halmac_reg_read_8(mac, addr);
1001 }
1002 
rtw_halmac_iread16(struct intf_hdl * pintfhdl,u32 addr)1003 u16 rtw_halmac_iread16(struct intf_hdl *pintfhdl, u32 addr)
1004 {
1005 	struct halmac_adapter *mac;
1006 	struct halmac_api *api;
1007 	u16 val16 = 0;
1008 
1009 	/* WARNING: pintf_dev should not be null! */
1010 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
1011 	api = HALMAC_GET_API(mac);
1012 
1013 	/*return api->halmac_reg_read_indirect_16(mac, addr);*/
1014 	return api->halmac_reg_read_16(mac, addr);
1015 }
1016 
rtw_halmac_iread32(struct intf_hdl * pintfhdl,u32 addr)1017 u32 rtw_halmac_iread32(struct intf_hdl *pintfhdl, u32 addr)
1018 {
1019 	struct halmac_adapter *mac;
1020 	struct halmac_api *api;
1021 
1022 
1023 	/* WARNING: pintf_dev should not be null! */
1024 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
1025 	api = HALMAC_GET_API(mac);
1026 
1027 	return api->halmac_reg_read_indirect_32(mac, addr);
1028 }
1029 #endif /* CONFIG_SDIO_INDIRECT_ACCESS */
1030 
rtw_halmac_write8(struct intf_hdl * pintfhdl,u32 addr,u8 value)1031 int rtw_halmac_write8(struct intf_hdl *pintfhdl, u32 addr, u8 value)
1032 {
1033 	struct halmac_adapter *mac;
1034 	struct halmac_api *api;
1035 	enum halmac_ret_status status;
1036 
1037 
1038 	/* WARNING: pintf_dev should not be null! */
1039 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
1040 	api = HALMAC_GET_API(mac);
1041 
1042 	status = api->halmac_reg_write_8(mac, addr, value);
1043 
1044 	if (status == HALMAC_RET_SUCCESS)
1045 		return 0;
1046 
1047 	return -1;
1048 }
1049 
rtw_halmac_write16(struct intf_hdl * pintfhdl,u32 addr,u16 value)1050 int rtw_halmac_write16(struct intf_hdl *pintfhdl, u32 addr, u16 value)
1051 {
1052 	struct halmac_adapter *mac;
1053 	struct halmac_api *api;
1054 	enum halmac_ret_status status;
1055 
1056 
1057 	/* WARNING: pintf_dev should not be null! */
1058 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
1059 	api = HALMAC_GET_API(mac);
1060 
1061 	status = api->halmac_reg_write_16(mac, addr, value);
1062 
1063 	if (status == HALMAC_RET_SUCCESS)
1064 		return 0;
1065 
1066 	return -1;
1067 }
1068 
rtw_halmac_write32(struct intf_hdl * pintfhdl,u32 addr,u32 value)1069 int rtw_halmac_write32(struct intf_hdl *pintfhdl, u32 addr, u32 value)
1070 {
1071 	struct halmac_adapter *mac;
1072 	struct halmac_api *api;
1073 	enum halmac_ret_status status;
1074 
1075 
1076 	/* WARNING: pintf_dev should not be null! */
1077 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
1078 	api = HALMAC_GET_API(mac);
1079 
1080 	status = api->halmac_reg_write_32(mac, addr, value);
1081 
1082 	if (status == HALMAC_RET_SUCCESS)
1083 		return 0;
1084 
1085 	return -1;
1086 }
1087 
init_write_rsvd_page_size(struct dvobj_priv * d)1088 static int init_write_rsvd_page_size(struct dvobj_priv *d)
1089 {
1090 	struct halmac_adapter *mac;
1091 	struct halmac_api *api;
1092 	u32 size = 0;
1093 	struct halmac_ofld_func_info ofld_info;
1094 	enum halmac_ret_status status;
1095 	int err = 0;
1096 
1097 
1098 #ifdef CONFIG_USB_HCI
1099 	/* for USB do not exceed MAX_CMDBUF_SZ */
1100 	size = 0x1000;
1101 #elif defined(CONFIG_PCI_HCI)
1102 	size = MAX_CMDBUF_SZ - TXDESC_OFFSET;
1103 #elif defined(CONFIG_SDIO_HCI)
1104 	size = 0x7000; /* 28KB */
1105 #else
1106 	/* Use HALMAC default setting and don't call any function */
1107 	return 0;
1108 #endif
1109 #if 0	/* Fail to pass coverity DEADCODE check */
1110 	/* If size==0, use HALMAC default setting and don't call any function */
1111 	if (!size)
1112 		return 0;
1113 #endif
1114 	err = rtw_halmac_set_max_dl_fw_size(d, size);
1115 	if (err) {
1116 		RTW_ERR("%s: Fail to set max download fw size!\n", __FUNCTION__);
1117 		return -1;
1118 	}
1119 
1120 	mac = dvobj_to_halmac(d);
1121 	api = HALMAC_GET_API(mac);
1122 
1123 	_rtw_memset(&ofld_info, 0, sizeof(ofld_info));
1124 	ofld_info.halmac_malloc_max_sz = 0xFFFFFFFF;
1125 	ofld_info.rsvd_pg_drv_buf_max_sz = size;
1126 	status = api->halmac_ofld_func_cfg(mac, &ofld_info);
1127 	if (status != HALMAC_RET_SUCCESS) {
1128 		RTW_ERR("%s: Fail to config offload parameters!\n", __FUNCTION__);
1129 		return -1;
1130 	}
1131 
1132 	return 0;
1133 }
1134 
init_priv(struct halmacpriv * priv)1135 static int init_priv(struct halmacpriv *priv)
1136 {
1137 	struct halmac_indicator *indicator;
1138 	u32 count, size;
1139 
1140 
1141 	if (priv->indicator)
1142 		RTW_WARN("%s: HALMAC private data is not CLEAR!\n", __FUNCTION__);
1143 	count = HALMAC_FEATURE_ALL + 1;
1144 	size = sizeof(*indicator) * count;
1145 	indicator = (struct halmac_indicator *)rtw_zmalloc(size);
1146 	if (!indicator)
1147 		return -1;
1148 	priv->indicator = indicator;
1149 
1150 	return 0;
1151 }
1152 
deinit_priv(struct halmacpriv * priv)1153 static void deinit_priv(struct halmacpriv *priv)
1154 {
1155 	struct halmac_indicator *indicator;
1156 
1157 
1158 	indicator = priv->indicator;
1159 	priv->indicator = NULL;
1160 	if (indicator) {
1161 		u32 count, size;
1162 
1163 		count = HALMAC_FEATURE_ALL + 1;
1164 #ifdef CONFIG_RTW_DEBUG
1165 		{
1166 			struct submit_ctx *sctx;
1167 			u32 i;
1168 
1169 			for (i = 0; i < count; i++) {
1170 				if (!indicator[i].sctx)
1171 					continue;
1172 
1173 				RTW_WARN("%s: %s id(%d) sctx still exist!!\n",
1174 					__FUNCTION__, RTW_HALMAC_FEATURE_NAME[i], i);
1175 				sctx = indicator[i].sctx;
1176 				indicator[i].sctx = NULL;
1177 				rtw_mfree((u8 *)sctx, sizeof(*sctx));
1178 			}
1179 		}
1180 #endif /* !CONFIG_RTW_DEBUG */
1181 		size = sizeof(*indicator) * count;
1182 		rtw_mfree((u8 *)indicator, size);
1183 	}
1184 }
1185 
1186 #ifdef CONFIG_SDIO_HCI
_sdio_ver_drv2halmac(struct dvobj_priv * d)1187 static enum halmac_sdio_spec_ver _sdio_ver_drv2halmac(struct dvobj_priv *d)
1188 {
1189 	bool v3;
1190 	enum halmac_sdio_spec_ver ver;
1191 
1192 
1193 	v3 = rtw_is_sdio30(dvobj_get_primary_adapter(d));
1194 	if (v3)
1195 		ver = HALMAC_SDIO_SPEC_VER_3_00;
1196 	else
1197 		ver = HALMAC_SDIO_SPEC_VER_2_00;
1198 
1199 	return ver;
1200 }
1201 #endif /* CONFIG_SDIO_HCI */
1202 
rtw_halmac_get_version(char * str,u32 len)1203 void rtw_halmac_get_version(char *str, u32 len)
1204 {
1205 	enum halmac_ret_status status;
1206 	struct halmac_ver ver;
1207 
1208 
1209 	status = halmac_get_version(&ver);
1210 	if (status != HALMAC_RET_SUCCESS)
1211 		return;
1212 
1213 	rtw_sprintf(str, len, "V%d_%02d_%02d",
1214 		    ver.major_ver, ver.prototype_ver, ver.minor_ver);
1215 }
1216 
rtw_halmac_init_adapter(struct dvobj_priv * d,struct halmac_platform_api * pf_api)1217 int rtw_halmac_init_adapter(struct dvobj_priv *d, struct halmac_platform_api *pf_api)
1218 {
1219 	struct halmac_adapter *halmac;
1220 	struct halmac_api *api;
1221 	enum halmac_interface intf;
1222 	enum halmac_intf_phy_platform pltfm = HALMAC_INTF_PHY_PLATFORM_ALL;
1223 	enum halmac_ret_status status;
1224 	int err = 0;
1225 #ifdef CONFIG_SDIO_HCI
1226 	struct halmac_sdio_hw_info info;
1227 #endif /* CONFIG_SDIO_HCI */
1228 
1229 
1230 	halmac = dvobj_to_halmac(d);
1231 	if (halmac) {
1232 		RTW_WARN("%s: initialize already completed!\n", __FUNCTION__);
1233 		goto error;
1234 	}
1235 
1236 	err = init_priv(&d->hmpriv);
1237 	if (err)
1238 		goto error;
1239 
1240 #ifdef CONFIG_SDIO_HCI
1241 	intf = HALMAC_INTERFACE_SDIO;
1242 #elif defined(CONFIG_USB_HCI)
1243 	intf = HALMAC_INTERFACE_USB;
1244 #elif defined(CONFIG_PCI_HCI)
1245 	intf = HALMAC_INTERFACE_PCIE;
1246 #else
1247 #warning "INTERFACE(CONFIG_XXX_HCI) not be defined!!"
1248 	intf = HALMAC_INTERFACE_UNDEFINE;
1249 #endif
1250 	status = halmac_init_adapter(d, pf_api, intf, &halmac, &api);
1251 	if (HALMAC_RET_SUCCESS != status) {
1252 		RTW_ERR("%s: halmac_init_adapter fail!(status=%d)\n", __FUNCTION__, status);
1253 		err = -1;
1254 		if (halmac)
1255 			goto deinit;
1256 		goto free;
1257 	}
1258 
1259 	dvobj_set_halmac(d, halmac);
1260 
1261 	status = api->halmac_interface_integration_tuning(halmac);
1262 	if (status != HALMAC_RET_SUCCESS) {
1263 		RTW_ERR("%s: halmac_interface_integration_tuning fail!(status=%d)\n", __FUNCTION__, status);
1264 		err = -1;
1265 		goto deinit;
1266 	}
1267 
1268 #ifdef CONFIG_PLATFORM_RTK1319
1269 	pltfm = HALMAC_INTF_PHY_PLATFORM_DHC;
1270 #endif /* CONFIG_PLATFORM_RTK1319 */
1271 	status = api->halmac_phy_cfg(halmac, pltfm);
1272 	if (status != HALMAC_RET_SUCCESS) {
1273 		RTW_ERR("%s: halmac_phy_cfg fail! (platform=%d, status=%d)\n",
1274 			__FUNCTION__, pltfm, status);
1275 		err = -1;
1276 		goto deinit;
1277 	}
1278 
1279 	init_write_rsvd_page_size(d);
1280 
1281 #ifdef CONFIG_SDIO_HCI
1282 	_rtw_memset(&info, 0, sizeof(info));
1283 	info.spec_ver = _sdio_ver_drv2halmac(d);
1284 	/* Convert clock speed unit to MHz from Hz */
1285 	info.clock_speed = RTW_DIV_ROUND_UP(rtw_sdio_get_clock(d), 1000000);
1286 	info.block_size = rtw_sdio_get_block_size(d);
1287 	if (d->hmpriv.sdio_io_indir == 2)
1288 		info.io_indir_flag = 0;
1289 	else
1290 		info.io_indir_flag = 1; /* Default enable indirect I/O */
1291 	RTW_DBG("%s: SDIO ver=%u clock=%uMHz blk_size=%u bytes, io_indir=%u\n",
1292 		__FUNCTION__, info.spec_ver+2, info.clock_speed,
1293 		info.block_size, info.io_indir_flag);
1294 	status = api->halmac_sdio_hw_info(halmac, &info);
1295 	if (status != HALMAC_RET_SUCCESS) {
1296 		RTW_ERR("%s: halmac_sdio_hw_info fail!(status=%d)\n",
1297 			__FUNCTION__, status);
1298 		err = -1;
1299 		goto deinit;
1300 	}
1301 #endif /* CONFIG_SDIO_HCI */
1302 
1303 	return 0;
1304 
1305 deinit:
1306 	status = halmac_deinit_adapter(halmac);
1307 	dvobj_set_halmac(d, NULL);
1308 	if (status != HALMAC_RET_SUCCESS)
1309 		RTW_ERR("%s: halmac_deinit_adapter fail!(status=%d)\n",
1310 			__FUNCTION__, status);
1311 
1312 free:
1313 	deinit_priv(&d->hmpriv);
1314 
1315 error:
1316 	return err;
1317 }
1318 
rtw_halmac_deinit_adapter(struct dvobj_priv * d)1319 int rtw_halmac_deinit_adapter(struct dvobj_priv *d)
1320 {
1321 	struct halmac_adapter *halmac;
1322 	enum halmac_ret_status status;
1323 	int err = 0;
1324 
1325 
1326 	halmac = dvobj_to_halmac(d);
1327 	if (halmac) {
1328 		status = halmac_deinit_adapter(halmac);
1329 		dvobj_set_halmac(d, NULL);
1330 		if (status != HALMAC_RET_SUCCESS)
1331 			err = -1;
1332 	}
1333 
1334 	deinit_priv(&d->hmpriv);
1335 
1336 	return err;
1337 }
1338 
_hw_port_drv2halmac(enum _hw_port hwport)1339 static inline enum halmac_portid _hw_port_drv2halmac(enum _hw_port hwport)
1340 {
1341 	enum halmac_portid port = HALMAC_PORTID_NUM;
1342 
1343 
1344 	switch (hwport) {
1345 	case HW_PORT0:
1346 		port = HALMAC_PORTID0;
1347 		break;
1348 	case HW_PORT1:
1349 		port = HALMAC_PORTID1;
1350 		break;
1351 	case HW_PORT2:
1352 		port = HALMAC_PORTID2;
1353 		break;
1354 	case HW_PORT3:
1355 		port = HALMAC_PORTID3;
1356 		break;
1357 	case HW_PORT4:
1358 		port = HALMAC_PORTID4;
1359 		break;
1360 	default:
1361 		break;
1362 	}
1363 
1364 	return port;
1365 }
1366 
_network_type_drv2halmac(u8 type)1367 static enum halmac_network_type_select _network_type_drv2halmac(u8 type)
1368 {
1369 	enum halmac_network_type_select network = HALMAC_NETWORK_UNDEFINE;
1370 
1371 
1372 	switch (type) {
1373 	case _HW_STATE_NOLINK_:
1374 	case _HW_STATE_MONITOR_:
1375 		network = HALMAC_NETWORK_NO_LINK;
1376 		break;
1377 
1378 	case _HW_STATE_ADHOC_:
1379 		network = HALMAC_NETWORK_ADHOC;
1380 		break;
1381 
1382 	case _HW_STATE_STATION_:
1383 		network = HALMAC_NETWORK_INFRASTRUCTURE;
1384 		break;
1385 
1386 	case _HW_STATE_AP_:
1387 		network = HALMAC_NETWORK_AP;
1388 		break;
1389 	}
1390 
1391 	return network;
1392 }
1393 
_network_type_halmac2drv(enum halmac_network_type_select network)1394 static u8 _network_type_halmac2drv(enum halmac_network_type_select network)
1395 {
1396 	u8 type = _HW_STATE_NOLINK_;
1397 
1398 
1399 	switch (network) {
1400 	case HALMAC_NETWORK_NO_LINK:
1401 	case HALMAC_NETWORK_UNDEFINE:
1402 		type = _HW_STATE_NOLINK_;
1403 		break;
1404 
1405 	case HALMAC_NETWORK_ADHOC:
1406 		type = _HW_STATE_ADHOC_;
1407 		break;
1408 
1409 	case HALMAC_NETWORK_INFRASTRUCTURE:
1410 		type = _HW_STATE_STATION_;
1411 		break;
1412 
1413 	case HALMAC_NETWORK_AP:
1414 		type = _HW_STATE_AP_;
1415 		break;
1416 	}
1417 
1418 	return type;
1419 }
1420 
_beacon_ctrl_halmac2drv(struct halmac_bcn_ctrl * ctrl,struct rtw_halmac_bcn_ctrl * drv_ctrl)1421 static void _beacon_ctrl_halmac2drv(struct halmac_bcn_ctrl *ctrl,
1422 				struct rtw_halmac_bcn_ctrl *drv_ctrl)
1423 {
1424 	drv_ctrl->rx_bssid_fit = ctrl->dis_rx_bssid_fit ? 0 : 1;
1425 	drv_ctrl->txbcn_rpt = ctrl->en_txbcn_rpt ? 1 : 0;
1426 	drv_ctrl->tsf_update = ctrl->dis_tsf_udt ? 0 : 1;
1427 	drv_ctrl->enable_bcn = ctrl->en_bcn ? 1 : 0;
1428 	drv_ctrl->rxbcn_rpt = ctrl->en_rxbcn_rpt ? 1 : 0;
1429 	drv_ctrl->p2p_ctwin = ctrl->en_p2p_ctwin ? 1 : 0;
1430 	drv_ctrl->p2p_bcn_area = ctrl->en_p2p_bcn_area ? 1 : 0;
1431 }
1432 
_beacon_ctrl_drv2halmac(struct rtw_halmac_bcn_ctrl * drv_ctrl,struct halmac_bcn_ctrl * ctrl)1433 static void _beacon_ctrl_drv2halmac(struct rtw_halmac_bcn_ctrl *drv_ctrl,
1434 				struct halmac_bcn_ctrl *ctrl)
1435 {
1436 	ctrl->dis_rx_bssid_fit = drv_ctrl->rx_bssid_fit ? 0 : 1;
1437 	ctrl->en_txbcn_rpt = drv_ctrl->txbcn_rpt ? 1 : 0;
1438 	ctrl->dis_tsf_udt = drv_ctrl->tsf_update ? 0 : 1;
1439 	ctrl->en_bcn = drv_ctrl->enable_bcn ? 1 : 0;
1440 	ctrl->en_rxbcn_rpt = drv_ctrl->rxbcn_rpt ? 1 : 0;
1441 	ctrl->en_p2p_ctwin = drv_ctrl->p2p_ctwin ? 1 : 0;
1442 	ctrl->en_p2p_bcn_area = drv_ctrl->p2p_bcn_area ? 1 : 0;
1443 }
1444 
rtw_halmac_get_hw_value(struct dvobj_priv * d,enum halmac_hw_id hw_id,void * pvalue)1445 int rtw_halmac_get_hw_value(struct dvobj_priv *d, enum halmac_hw_id hw_id, void *pvalue)
1446 {
1447 	struct halmac_adapter *mac;
1448 	struct halmac_api *api;
1449 	enum halmac_ret_status status;
1450 
1451 
1452 	mac = dvobj_to_halmac(d);
1453 	api = HALMAC_GET_API(mac);
1454 
1455 	status = api->halmac_get_hw_value(mac, hw_id, pvalue);
1456 	if (HALMAC_RET_SUCCESS != status)
1457 		return -1;
1458 
1459 	return 0;
1460 }
1461 
1462 /**
1463  * rtw_halmac_get_tx_fifo_size() - TX FIFO size
1464  * @d:		struct dvobj_priv*
1465  * @size:	TX FIFO size, unit is byte.
1466  *
1467  * Get TX FIFO size(byte) from HALMAC.
1468  *
1469  * Return 0 for OK, otherwise fail.
1470  */
rtw_halmac_get_tx_fifo_size(struct dvobj_priv * d,u32 * size)1471 int rtw_halmac_get_tx_fifo_size(struct dvobj_priv *d, u32 *size)
1472 {
1473 	struct halmac_adapter *halmac;
1474 	struct halmac_api *api;
1475 	enum halmac_ret_status status;
1476 	u32 val = 0;
1477 
1478 
1479 	halmac = dvobj_to_halmac(d);
1480 	api = HALMAC_GET_API(halmac);
1481 
1482 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_TXFIFO_SIZE, &val);
1483 	if (status != HALMAC_RET_SUCCESS)
1484 		return -1;
1485 
1486 	*size = val;
1487 
1488 	return 0;
1489 }
1490 
1491 /**
1492  * rtw_halmac_get_rx_fifo_size() - RX FIFO size
1493  * @d:		struct dvobj_priv*
1494  * @size:	RX FIFO size, unit is byte
1495  *
1496  * Get RX FIFO size(byte) from HALMAC.
1497  *
1498  * Return 0 for OK, otherwise fail.
1499  */
rtw_halmac_get_rx_fifo_size(struct dvobj_priv * d,u32 * size)1500 int rtw_halmac_get_rx_fifo_size(struct dvobj_priv *d, u32 *size)
1501 {
1502 	struct halmac_adapter *halmac;
1503 	struct halmac_api *api;
1504 	enum halmac_ret_status status;
1505 	u32 val = 0;
1506 
1507 
1508 	halmac = dvobj_to_halmac(d);
1509 	api = HALMAC_GET_API(halmac);
1510 
1511 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RXFIFO_SIZE, &val);
1512 	if (status != HALMAC_RET_SUCCESS)
1513 		return -1;
1514 
1515 	*size = val;
1516 
1517 	return 0;
1518 }
1519 
1520 /**
1521  * rtw_halmac_get_rsvd_drv_pg_bndy() - Reserve page boundary of driver
1522  * @d:		struct dvobj_priv*
1523  * @size:	Page size, unit is byte
1524  *
1525  * Get reserve page boundary of driver from HALMAC.
1526  *
1527  * Return 0 for OK, otherwise fail.
1528  */
rtw_halmac_get_rsvd_drv_pg_bndy(struct dvobj_priv * d,u16 * bndy)1529 int rtw_halmac_get_rsvd_drv_pg_bndy(struct dvobj_priv *d, u16 *bndy)
1530 {
1531 	struct halmac_adapter *halmac;
1532 	struct halmac_api *api;
1533 	enum halmac_ret_status status;
1534 	u16 val = 0;
1535 
1536 
1537 	halmac = dvobj_to_halmac(d);
1538 	api = HALMAC_GET_API(halmac);
1539 
1540 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RSVD_PG_BNDY, &val);
1541 	if (status != HALMAC_RET_SUCCESS)
1542 		return -1;
1543 
1544 	*bndy = val;
1545 
1546 	return 0;
1547 }
1548 
1549 /**
1550  * rtw_halmac_get_page_size() - Page size
1551  * @d:		struct dvobj_priv*
1552  * @size:	Page size, unit is byte
1553  *
1554  * Get TX/RX page size(byte) from HALMAC.
1555  *
1556  * Return 0 for OK, otherwise fail.
1557  */
rtw_halmac_get_page_size(struct dvobj_priv * d,u32 * size)1558 int rtw_halmac_get_page_size(struct dvobj_priv *d, u32 *size)
1559 {
1560 	struct halmac_adapter *halmac;
1561 	struct halmac_api *api;
1562 	enum halmac_ret_status status;
1563 	u32 val = 0;
1564 
1565 
1566 	halmac = dvobj_to_halmac(d);
1567 	api = HALMAC_GET_API(halmac);
1568 
1569 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_PAGE_SIZE, &val);
1570 	if (status != HALMAC_RET_SUCCESS)
1571 		return -1;
1572 
1573 	*size = val;
1574 
1575 	return 0;
1576 }
1577 
1578 /**
1579  * rtw_halmac_get_tx_agg_align_size() - TX aggregation align size
1580  * @d:		struct dvobj_priv*
1581  * @size:	TX aggregation align size, unit is byte
1582  *
1583  * Get TX aggregation align size(byte) from HALMAC.
1584  *
1585  * Return 0 for OK, otherwise fail.
1586  */
rtw_halmac_get_tx_agg_align_size(struct dvobj_priv * d,u16 * size)1587 int rtw_halmac_get_tx_agg_align_size(struct dvobj_priv *d, u16 *size)
1588 {
1589 	struct halmac_adapter *halmac;
1590 	struct halmac_api *api;
1591 	enum halmac_ret_status status;
1592 	u16 val = 0;
1593 
1594 
1595 	halmac = dvobj_to_halmac(d);
1596 	api = HALMAC_GET_API(halmac);
1597 
1598 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_TX_AGG_ALIGN_SIZE, &val);
1599 	if (status != HALMAC_RET_SUCCESS)
1600 		return -1;
1601 
1602 	*size = val;
1603 
1604 	return 0;
1605 }
1606 
1607 /**
1608  * rtw_halmac_get_rx_agg_align_size() - RX aggregation align size
1609  * @d:		struct dvobj_priv*
1610  * @size:	RX aggregation align size, unit is byte
1611  *
1612  * Get RX aggregation align size(byte) from HALMAC.
1613  *
1614  * Return 0 for OK, otherwise fail.
1615  */
rtw_halmac_get_rx_agg_align_size(struct dvobj_priv * d,u8 * size)1616 int rtw_halmac_get_rx_agg_align_size(struct dvobj_priv *d, u8 *size)
1617 {
1618 	struct halmac_adapter *halmac;
1619 	struct halmac_api *api;
1620 	enum halmac_ret_status status;
1621 	u8 val = 0;
1622 
1623 
1624 	halmac = dvobj_to_halmac(d);
1625 	api = HALMAC_GET_API(halmac);
1626 
1627 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RX_AGG_ALIGN_SIZE, &val);
1628 	if (status != HALMAC_RET_SUCCESS)
1629 		return -1;
1630 
1631 	*size = val;
1632 
1633 	return 0;
1634 }
1635 
1636 /*
1637  * Description:
1638  *	Get RX driver info size. RX driver info is a small memory space between
1639  *	scriptor and RX payload.
1640  *
1641  *	+-------------------------+
1642  *	| RX descriptor           |
1643  *	| usually 24 bytes        |
1644  *	+-------------------------+
1645  *	| RX driver info          |
1646  *	| depends on driver cfg   |
1647  *	+-------------------------+
1648  *	| RX paylad               |
1649  *	|                         |
1650  *	+-------------------------+
1651  *
1652  * Parameter:
1653  *	d	pointer to struct dvobj_priv of driver
1654  *	sz	rx driver info size in bytes.
1655  *
1656  * Return:
1657  *	0	Success
1658  *	other	Fail
1659  */
rtw_halmac_get_rx_drv_info_sz(struct dvobj_priv * d,u8 * sz)1660 int rtw_halmac_get_rx_drv_info_sz(struct dvobj_priv *d, u8 *sz)
1661 {
1662 	enum halmac_ret_status status;
1663 	struct halmac_adapter *halmac = dvobj_to_halmac(d);
1664 	struct halmac_api *api = HALMAC_GET_API(halmac);
1665 	u8 dw = 0;
1666 
1667 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_DRV_INFO_SIZE, &dw);
1668 	if (status != HALMAC_RET_SUCCESS)
1669 		return -1;
1670 
1671 	*sz = dw * 8;
1672 	return 0;
1673 }
1674 
1675 /**
1676  * rtw_halmac_get_tx_desc_size() - TX descriptor size
1677  * @d:		struct dvobj_priv*
1678  * @size:	TX descriptor size, unit is byte.
1679  *
1680  * Get TX descriptor size(byte) from HALMAC.
1681  *
1682  * Return 0 for OK, otherwise fail.
1683  */
rtw_halmac_get_tx_desc_size(struct dvobj_priv * d,u32 * size)1684 int rtw_halmac_get_tx_desc_size(struct dvobj_priv *d, u32 *size)
1685 {
1686 	struct halmac_adapter *halmac;
1687 	struct halmac_api *api;
1688 	enum halmac_ret_status status;
1689 	u32 val = 0;
1690 
1691 
1692 	halmac = dvobj_to_halmac(d);
1693 	api = HALMAC_GET_API(halmac);
1694 
1695 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_TX_DESC_SIZE, &val);
1696 	if (status != HALMAC_RET_SUCCESS)
1697 		return -1;
1698 
1699 	*size = val;
1700 
1701 	return 0;
1702 }
1703 
1704 /**
1705  * rtw_halmac_get_rx_desc_size() - RX descriptor size
1706  * @d:		struct dvobj_priv*
1707  * @size:	RX descriptor size, unit is byte.
1708  *
1709  * Get RX descriptor size(byte) from HALMAC.
1710  *
1711  * Return 0 for OK, otherwise fail.
1712  */
rtw_halmac_get_rx_desc_size(struct dvobj_priv * d,u32 * size)1713 int rtw_halmac_get_rx_desc_size(struct dvobj_priv *d, u32 *size)
1714 {
1715 	struct halmac_adapter *halmac;
1716 	struct halmac_api *api;
1717 	enum halmac_ret_status status;
1718 	u32 val = 0;
1719 
1720 
1721 	halmac = dvobj_to_halmac(d);
1722 	api = HALMAC_GET_API(halmac);
1723 
1724 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RX_DESC_SIZE, &val);
1725 	if (status != HALMAC_RET_SUCCESS)
1726 		return -1;
1727 
1728 	*size = val;
1729 
1730 	return 0;
1731 }
1732 
1733 /**
1734  * rtw_halmac_get_tx_dma_ch_map() - Get TX DMA channel Map for tx desc
1735  * @d:		struct dvobj_priv*
1736  * @dma_ch_map:	return map of QSEL to DMA channel
1737  * @map_size:	size of dma_ch_map
1738  *		Suggest size to be last valid QSEL(QSLT_CMD)+1 or full QSLT
1739  *		size(0x20)
1740  *
1741  * 8814B would need this to get mapping of QSEL to DMA channel for TX desc.
1742  *
1743  * Return 0 for OK, otherwise fail.
1744  */
rtw_halmac_get_tx_dma_ch_map(struct dvobj_priv * d,u8 * dma_ch_map,u8 map_size)1745 int rtw_halmac_get_tx_dma_ch_map(struct dvobj_priv *d, u8 *dma_ch_map, u8 map_size)
1746 {
1747 	struct halmac_adapter *halmac;
1748 	struct halmac_api *api;
1749 	enum halmac_ret_status status;
1750 	struct halmac_rqpn_ch_map map;
1751 	enum halmac_dma_ch channel = HALMAC_DMA_CH_UNDEFINE;
1752 	u8 qsel;
1753 
1754 
1755 	halmac = dvobj_to_halmac(d);
1756 	api = HALMAC_GET_API(halmac);
1757 
1758 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RQPN_CH_MAPPING, &map);
1759 	if (status != HALMAC_RET_SUCCESS)
1760 		return -1;
1761 
1762 	for (qsel = 0; qsel < map_size; qsel++) {
1763 		switch (qsel) {
1764 		/*case QSLT_VO:*/
1765 		case 0x06:
1766 		case 0x07:
1767 			channel = map.dma_map_vo;
1768 			break;
1769 		/*case QSLT_VI:*/
1770 		case 0x04:
1771 		case 0x05:
1772 			channel = map.dma_map_vi;
1773 			break;
1774 		/*case QSLT_BE:*/
1775 		case 0x00:
1776 		case 0x03:
1777 			channel = map.dma_map_be;
1778 			break;
1779 		/*case QSLT_BK:*/
1780 		case 0x01:
1781 		case 0x02:
1782 			channel = map.dma_map_bk;
1783 			break;
1784 		/*case QSLT_BEACON:*/
1785 		case 0x10:
1786 			channel = HALMAC_DMA_CH_BCN;
1787 			break;
1788 		/*case QSLT_HIGH:*/
1789 		case 0x11:
1790 			channel = map.dma_map_hi;
1791 			break;
1792 		/*case QSLT_MGNT:*/
1793 		case 0x12:
1794 			channel = map.dma_map_mg;
1795 			break;
1796 		/*case QSLT_CMD:*/
1797 		case 0x13:
1798 			channel = HALMAC_DMA_CH_H2C;
1799 			break;
1800 		default:
1801 			/*RTW_ERR("%s: invalid qsel=0x%x\n", __FUNCTION__, qsel);*/
1802 			channel = HALMAC_DMA_CH_UNDEFINE;
1803 			break;
1804 		}
1805 		dma_ch_map[qsel] = (u8)channel;
1806 	}
1807 
1808 	return 0;
1809 }
1810 
1811 /**
1812  * rtw_halmac_get_fw_max_size() - Firmware MAX size
1813  * @d:		struct dvobj_priv*
1814  * @size:	MAX Firmware size, unit is byte.
1815  *
1816  * Get Firmware MAX size(byte) from HALMAC.
1817  *
1818  * Return 0 for OK, otherwise fail.
1819  */
rtw_halmac_get_fw_max_size(struct dvobj_priv * d,u32 * size)1820 static int rtw_halmac_get_fw_max_size(struct dvobj_priv *d, u32 *size)
1821 {
1822 	struct halmac_adapter *halmac;
1823 	struct halmac_api *api;
1824 	enum halmac_ret_status status;
1825 	u32 val = 0;
1826 
1827 
1828 	halmac = dvobj_to_halmac(d);
1829 	api = HALMAC_GET_API(halmac);
1830 
1831 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_FW_MAX_SIZE, &val);
1832 	if (status != HALMAC_RET_SUCCESS)
1833 		return -1;
1834 
1835 	*size = val;
1836 
1837 	return 0;
1838 }
1839 
1840 /**
1841  * rtw_halmac_get_ori_h2c_size() - Original H2C MAX size
1842  * @d:		struct dvobj_priv*
1843  * @size:	H2C MAX size, unit is byte.
1844  *
1845  * Get original H2C MAX size(byte) from HALMAC.
1846  *
1847  * Return 0 for OK, otherwise fail.
1848  */
rtw_halmac_get_ori_h2c_size(struct dvobj_priv * d,u32 * size)1849 int rtw_halmac_get_ori_h2c_size(struct dvobj_priv *d, u32 *size)
1850 {
1851 	struct halmac_adapter *halmac;
1852 	struct halmac_api *api;
1853 	enum halmac_ret_status status;
1854 	u32 val = 0;
1855 
1856 
1857 	halmac = dvobj_to_halmac(d);
1858 	api = HALMAC_GET_API(halmac);
1859 
1860 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_ORI_H2C_SIZE, &val);
1861 	if (status != HALMAC_RET_SUCCESS)
1862 		return -1;
1863 
1864 	*size = val;
1865 
1866 	return 0;
1867 }
1868 
rtw_halmac_get_oqt_size(struct dvobj_priv * d,u8 * size)1869 int rtw_halmac_get_oqt_size(struct dvobj_priv *d, u8 *size)
1870 {
1871 	enum halmac_ret_status status;
1872 	struct halmac_adapter *halmac;
1873 	struct halmac_api *api;
1874 	u8 val;
1875 
1876 
1877 	if (!size)
1878 		return -1;
1879 
1880 	halmac = dvobj_to_halmac(d);
1881 	api = HALMAC_GET_API(halmac);
1882 
1883 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_AC_OQT_SIZE, &val);
1884 	if (status != HALMAC_RET_SUCCESS)
1885 		return -1;
1886 
1887 	*size = val;
1888 	return 0;
1889 }
1890 
rtw_halmac_get_ac_queue_number(struct dvobj_priv * d,u8 * num)1891 int rtw_halmac_get_ac_queue_number(struct dvobj_priv *d, u8 *num)
1892 {
1893 	enum halmac_ret_status status;
1894 	struct halmac_adapter *halmac;
1895 	struct halmac_api *api;
1896 	u8 val;
1897 
1898 
1899 	if (!num)
1900 		return -1;
1901 
1902 	halmac = dvobj_to_halmac(d);
1903 	api = HALMAC_GET_API(halmac);
1904 
1905 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_AC_QUEUE_NUM, &val);
1906 	if (status != HALMAC_RET_SUCCESS)
1907 		return -1;
1908 
1909 	*num = val;
1910 	return 0;
1911 }
1912 
1913 /**
1914  * rtw_halmac_get_mac_address() - Get MAC address of specific port
1915  * @d:		struct dvobj_priv*
1916  * @hwport:	port
1917  * @addr:	buffer for storing MAC address
1918  *
1919  * Get MAC address of specific port from HALMAC.
1920  *
1921  * Return 0 for OK, otherwise fail.
1922  */
rtw_halmac_get_mac_address(struct dvobj_priv * d,enum _hw_port hwport,u8 * addr)1923 int rtw_halmac_get_mac_address(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
1924 {
1925 	struct halmac_adapter *halmac;
1926 	struct halmac_api *api;
1927 	enum halmac_portid port;
1928 	union halmac_wlan_addr hwa;
1929 	enum halmac_ret_status status;
1930 	int err = -1;
1931 
1932 
1933 	if (!addr)
1934 		goto out;
1935 
1936 	halmac = dvobj_to_halmac(d);
1937 	api = HALMAC_GET_API(halmac);
1938 	port = _hw_port_drv2halmac(hwport);
1939 	_rtw_memset(&hwa, 0, sizeof(hwa));
1940 
1941 	status = api->halmac_get_mac_addr(halmac, port, &hwa);
1942 	if (status != HALMAC_RET_SUCCESS)
1943 		goto out;
1944 
1945 	_rtw_memcpy(addr, hwa.addr, 6);
1946 
1947 	err = 0;
1948 out:
1949 	return err;
1950 }
1951 
1952 /**
1953  * rtw_halmac_get_network_type() - Get network type of specific port
1954  * @d:		struct dvobj_priv*
1955  * @hwport:	port
1956  * @type:	buffer to put network type (_HW_STATE_*)
1957  *
1958  * Get network type of specific port from HALMAC.
1959  *
1960  * Return 0 for OK, otherwise fail.
1961  */
rtw_halmac_get_network_type(struct dvobj_priv * d,enum _hw_port hwport,u8 * type)1962 int rtw_halmac_get_network_type(struct dvobj_priv *d, enum _hw_port hwport, u8 *type)
1963 {
1964 #if 0
1965 	struct halmac_adapter *halmac;
1966 	struct halmac_api *api;
1967 	enum halmac_portid port;
1968 	enum halmac_network_type_select network;
1969 	enum halmac_ret_status status;
1970 	int err = -1;
1971 
1972 
1973 	halmac = dvobj_to_halmac(d);
1974 	api = HALMAC_GET_API(halmac);
1975 	port = _hw_port_drv2halmac(hwport);
1976 	network = HALMAC_NETWORK_UNDEFINE;
1977 
1978 	status = api->halmac_get_net_type(halmac, port, &network);
1979 	if (status != HALMAC_RET_SUCCESS)
1980 		goto out;
1981 
1982 	*type = _network_type_halmac2drv(network);
1983 
1984 	err = 0;
1985 out:
1986 	return err;
1987 #else
1988 	struct _ADAPTER *a;
1989 	enum halmac_portid port;
1990 	enum halmac_network_type_select network;
1991 	u32 val;
1992 	int err = -1;
1993 
1994 
1995 	a = dvobj_get_primary_adapter(d);
1996 	port = _hw_port_drv2halmac(hwport);
1997 	network = HALMAC_NETWORK_UNDEFINE;
1998 
1999 	switch (port) {
2000 	case HALMAC_PORTID0:
2001 		val = rtw_read32(a, REG_CR);
2002 		network = BIT_GET_NETYPE0(val);
2003 		break;
2004 
2005 	case HALMAC_PORTID1:
2006 		val = rtw_read32(a, REG_CR);
2007 		network = BIT_GET_NETYPE1(val);
2008 		break;
2009 
2010 	case HALMAC_PORTID2:
2011 		val = rtw_read32(a, REG_CR_EXT);
2012 		network = BIT_GET_NETYPE2(val);
2013 		break;
2014 
2015 	case HALMAC_PORTID3:
2016 		val = rtw_read32(a, REG_CR_EXT);
2017 		network = BIT_GET_NETYPE3(val);
2018 		break;
2019 
2020 	case HALMAC_PORTID4:
2021 		val = rtw_read32(a, REG_CR_EXT);
2022 		network = BIT_GET_NETYPE4(val);
2023 		break;
2024 
2025 	default:
2026 		goto out;
2027 	}
2028 
2029 	*type = _network_type_halmac2drv(network);
2030 
2031 	err = 0;
2032 out:
2033 	return err;
2034 #endif
2035 }
2036 
2037 /**
2038  * rtw_halmac_get_bcn_ctrl() - Get beacon control setting of specific port
2039  * @d:		struct dvobj_priv*
2040  * @hwport:	port
2041  * @bcn_ctrl:	setting of beacon control
2042  *
2043  * Get beacon control setting of specific port from HALMAC.
2044  *
2045  * Return 0 for OK, otherwise fail.
2046  */
rtw_halmac_get_bcn_ctrl(struct dvobj_priv * d,enum _hw_port hwport,struct rtw_halmac_bcn_ctrl * bcn_ctrl)2047 int rtw_halmac_get_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,
2048 			struct rtw_halmac_bcn_ctrl *bcn_ctrl)
2049 {
2050 	struct halmac_adapter *halmac;
2051 	struct halmac_api *api;
2052 	enum halmac_portid port;
2053 	struct halmac_bcn_ctrl ctrl;
2054 	enum halmac_ret_status status;
2055 	int err = -1;
2056 
2057 
2058 	halmac = dvobj_to_halmac(d);
2059 	api = HALMAC_GET_API(halmac);
2060 	port = _hw_port_drv2halmac(hwport);
2061 	_rtw_memset(&ctrl, 0, sizeof(ctrl));
2062 
2063 	status = api->halmac_rw_bcn_ctrl(halmac, port, 0, &ctrl);
2064 	if (status != HALMAC_RET_SUCCESS)
2065 		goto out;
2066 	_beacon_ctrl_halmac2drv(&ctrl, bcn_ctrl);
2067 
2068 	err = 0;
2069 out:
2070 	return err;
2071 }
2072 
2073 /*
2074  * Note:
2075  *	When this function return, the register REG_RCR may be changed.
2076  */
rtw_halmac_config_rx_info(struct dvobj_priv * d,enum halmac_drv_info info)2077 int rtw_halmac_config_rx_info(struct dvobj_priv *d, enum halmac_drv_info info)
2078 {
2079 	struct halmac_adapter *halmac;
2080 	struct halmac_api *api;
2081 	enum halmac_ret_status status;
2082 	int err = -1;
2083 
2084 
2085 	halmac = dvobj_to_halmac(d);
2086 	api = HALMAC_GET_API(halmac);
2087 
2088 	status = api->halmac_cfg_drv_info(halmac, info);
2089 	if (status != HALMAC_RET_SUCCESS)
2090 		goto out;
2091 
2092 	err = 0;
2093 out:
2094 	/* Sync driver RCR cache with register setting */
2095 	rtw_hal_get_hwreg(dvobj_get_primary_adapter(d), HW_VAR_RCR, NULL);
2096 
2097 	return err;
2098 }
2099 
2100 /**
2101  * rtw_halmac_set_max_dl_fw_size() - Set the MAX download firmware size
2102  * @d:		struct dvobj_priv*
2103  * @size:	the max download firmware size in one I/O
2104  *
2105  * Set the max download firmware size in one I/O.
2106  * Please also consider the max size of the callback function "SEND_RSVD_PAGE"
2107  * could accept, because download firmware would call "SEND_RSVD_PAGE" to send
2108  * firmware to IC.
2109  *
2110  * If the value of "size" is not even, it would be rounded down to nearest
2111  * even, and 0 and 1 are both invalid value.
2112  *
2113  * Return 0 for setting OK, otherwise fail.
2114  */
rtw_halmac_set_max_dl_fw_size(struct dvobj_priv * d,u32 size)2115 int rtw_halmac_set_max_dl_fw_size(struct dvobj_priv *d, u32 size)
2116 {
2117 	struct halmac_adapter *mac;
2118 	struct halmac_api *api;
2119 	enum halmac_ret_status status;
2120 
2121 
2122 	if (!size || (size == 1))
2123 		return -1;
2124 
2125 	mac = dvobj_to_halmac(d);
2126 	if (!mac) {
2127 		RTW_ERR("%s: HALMAC is not ready!!\n", __FUNCTION__);
2128 		return -1;
2129 	}
2130 	api = HALMAC_GET_API(mac);
2131 
2132 	size &= ~1; /* round down to even */
2133 	status = api->halmac_cfg_max_dl_size(mac, size);
2134 	if (status != HALMAC_RET_SUCCESS) {
2135 		RTW_WARN("%s: Fail to cfg_max_dl_size(%d), err=%d!!\n",
2136 			 __FUNCTION__, size, status);
2137 		return -1;
2138 	}
2139 
2140 	return 0;
2141 }
2142 
2143 /**
2144  * rtw_halmac_set_mac_address() - Set mac address of specific port
2145  * @d:		struct dvobj_priv*
2146  * @hwport:	port
2147  * @addr:	mac address
2148  *
2149  * Set self mac address of specific port to HALMAC.
2150  *
2151  * Return 0 for OK, otherwise fail.
2152  */
rtw_halmac_set_mac_address(struct dvobj_priv * d,enum _hw_port hwport,u8 * addr)2153 int rtw_halmac_set_mac_address(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
2154 {
2155 	struct halmac_adapter *halmac;
2156 	struct halmac_api *api;
2157 	enum halmac_portid port;
2158 	union halmac_wlan_addr hwa;
2159 	enum halmac_ret_status status;
2160 	int err = -1;
2161 
2162 
2163 	halmac = dvobj_to_halmac(d);
2164 	api = HALMAC_GET_API(halmac);
2165 
2166 	port = _hw_port_drv2halmac(hwport);
2167 	_rtw_memset(&hwa, 0, sizeof(hwa));
2168 	_rtw_memcpy(hwa.addr, addr, 6);
2169 
2170 	status = api->halmac_cfg_mac_addr(halmac, port, &hwa);
2171 	if (status != HALMAC_RET_SUCCESS)
2172 		goto out;
2173 
2174 	err = 0;
2175 out:
2176 	return err;
2177 }
2178 
2179 /**
2180  * rtw_halmac_set_bssid() - Set BSSID of specific port
2181  * @d:		struct dvobj_priv*
2182  * @hwport:	port
2183  * @addr:	BSSID, mac address of AP
2184  *
2185  * Set BSSID of specific port to HALMAC.
2186  *
2187  * Return 0 for OK, otherwise fail.
2188  */
rtw_halmac_set_bssid(struct dvobj_priv * d,enum _hw_port hwport,u8 * addr)2189 int rtw_halmac_set_bssid(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
2190 {
2191 	struct halmac_adapter *halmac;
2192 	struct halmac_api *api;
2193 	enum halmac_portid port;
2194 	union halmac_wlan_addr hwa;
2195 	enum halmac_ret_status status;
2196 	int err = -1;
2197 
2198 
2199 	halmac = dvobj_to_halmac(d);
2200 	api = HALMAC_GET_API(halmac);
2201 	port = _hw_port_drv2halmac(hwport);
2202 
2203 	_rtw_memset(&hwa, 0, sizeof(hwa));
2204 	_rtw_memcpy(hwa.addr, addr, 6);
2205 	status = api->halmac_cfg_bssid(halmac, port, &hwa);
2206 	if (status != HALMAC_RET_SUCCESS)
2207 		goto out;
2208 
2209 	err = 0;
2210 out:
2211 	return err;
2212 }
2213 
2214 /**
2215  * rtw_halmac_set_tx_address() - Set transmitter address of specific port
2216  * @d:		struct dvobj_priv*
2217  * @hwport:	port
2218  * @addr:	transmitter address
2219  *
2220  * Set transmitter address of specific port to HALMAC.
2221  *
2222  * Return 0 for OK, otherwise fail.
2223  */
rtw_halmac_set_tx_address(struct dvobj_priv * d,enum _hw_port hwport,u8 * addr)2224 int rtw_halmac_set_tx_address(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
2225 {
2226 	struct halmac_adapter *halmac;
2227 	struct halmac_api *api;
2228 	enum halmac_portid port;
2229 	union halmac_wlan_addr hwa;
2230 	enum halmac_ret_status status;
2231 	int err = -1;
2232 
2233 
2234 	halmac = dvobj_to_halmac(d);
2235 	api = HALMAC_GET_API(halmac);
2236 	port = _hw_port_drv2halmac(hwport);
2237 	_rtw_memset(&hwa, 0, sizeof(hwa));
2238 	_rtw_memcpy(hwa.addr, addr, 6);
2239 
2240 	status = api->halmac_cfg_transmitter_addr(halmac, port, &hwa);
2241 	if (status != HALMAC_RET_SUCCESS)
2242 		goto out;
2243 
2244 	err = 0;
2245 out:
2246 	return err;
2247 }
2248 
2249 /**
2250  * rtw_halmac_set_network_type() - Set network type of specific port
2251  * @d:		struct dvobj_priv*
2252  * @hwport:	port
2253  * @type:	network type (_HW_STATE_*)
2254  *
2255  * Set network type of specific port to HALMAC.
2256  *
2257  * Return 0 for OK, otherwise fail.
2258  */
rtw_halmac_set_network_type(struct dvobj_priv * d,enum _hw_port hwport,u8 type)2259 int rtw_halmac_set_network_type(struct dvobj_priv *d, enum _hw_port hwport, u8 type)
2260 {
2261 	struct halmac_adapter *halmac;
2262 	struct halmac_api *api;
2263 	enum halmac_portid port;
2264 	enum halmac_network_type_select network;
2265 	enum halmac_ret_status status;
2266 	int err = -1;
2267 
2268 
2269 	halmac = dvobj_to_halmac(d);
2270 	api = HALMAC_GET_API(halmac);
2271 	port = _hw_port_drv2halmac(hwport);
2272 	network = _network_type_drv2halmac(type);
2273 
2274 	status = api->halmac_cfg_net_type(halmac, port, network);
2275 	if (status != HALMAC_RET_SUCCESS)
2276 		goto out;
2277 
2278 	err = 0;
2279 out:
2280 	return err;
2281 }
2282 
2283 /**
2284  * rtw_halmac_reset_tsf() - Reset TSF timer of specific port
2285  * @d:		struct dvobj_priv*
2286  * @hwport:	port
2287  *
2288  * Notice HALMAC to reset timing synchronization function(TSF) timer of
2289  * specific port.
2290  *
2291  * Return 0 for OK, otherwise fail.
2292  */
rtw_halmac_reset_tsf(struct dvobj_priv * d,enum _hw_port hwport)2293 int rtw_halmac_reset_tsf(struct dvobj_priv *d, enum _hw_port hwport)
2294 {
2295 	struct halmac_adapter *halmac;
2296 	struct halmac_api *api;
2297 	enum halmac_portid port;
2298 	enum halmac_ret_status status;
2299 	int err = -1;
2300 
2301 
2302 	halmac = dvobj_to_halmac(d);
2303 	api = HALMAC_GET_API(halmac);
2304 	port = _hw_port_drv2halmac(hwport);
2305 
2306 	status = api->halmac_cfg_tsf_rst(halmac, port);
2307 	if (status != HALMAC_RET_SUCCESS)
2308 		goto out;
2309 
2310 	err = 0;
2311 out:
2312 	return err;
2313 }
2314 
2315 /**
2316  * rtw_halmac_set_bcn_interval() - Set beacon interval of each port
2317  * @d:		struct dvobj_priv*
2318  * @hwport:	port
2319  * @space:	beacon interval, unit is ms
2320  *
2321  * Set beacon interval of specific port to HALMAC.
2322  *
2323  * Return 0 for OK, otherwise fail.
2324  */
rtw_halmac_set_bcn_interval(struct dvobj_priv * d,enum _hw_port hwport,u32 interval)2325 int rtw_halmac_set_bcn_interval(struct dvobj_priv *d, enum _hw_port hwport,
2326 				u32 interval)
2327 {
2328 	struct halmac_adapter *halmac;
2329 	struct halmac_api *api;
2330 	enum halmac_portid port;
2331 	enum halmac_ret_status status;
2332 	int err = -1;
2333 
2334 
2335 	halmac = dvobj_to_halmac(d);
2336 	api = HALMAC_GET_API(halmac);
2337 	port = _hw_port_drv2halmac(hwport);
2338 
2339 	status = api->halmac_cfg_bcn_space(halmac, port, interval);
2340 	if (status != HALMAC_RET_SUCCESS)
2341 		goto out;
2342 
2343 	err = 0;
2344 out:
2345 	return err;
2346 }
2347 
2348 /**
2349  * rtw_halmac_set_bcn_ctrl() - Set beacon control setting of each port
2350  * @d:		struct dvobj_priv*
2351  * @hwport:	port
2352  * @bcn_ctrl:	setting of beacon control
2353  *
2354  * Set beacon control setting of specific port to HALMAC.
2355  *
2356  * Return 0 for OK, otherwise fail.
2357  */
rtw_halmac_set_bcn_ctrl(struct dvobj_priv * d,enum _hw_port hwport,struct rtw_halmac_bcn_ctrl * bcn_ctrl)2358 int rtw_halmac_set_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,
2359 			struct rtw_halmac_bcn_ctrl *bcn_ctrl)
2360 {
2361 	struct halmac_adapter *halmac;
2362 	struct halmac_api *api;
2363 	enum halmac_portid port;
2364 	struct halmac_bcn_ctrl ctrl;
2365 	enum halmac_ret_status status;
2366 	int err = -1;
2367 
2368 
2369 	halmac = dvobj_to_halmac(d);
2370 	api = HALMAC_GET_API(halmac);
2371 	port = _hw_port_drv2halmac(hwport);
2372 	_rtw_memset(&ctrl, 0, sizeof(ctrl));
2373 	_beacon_ctrl_drv2halmac(bcn_ctrl, &ctrl);
2374 
2375 	status = api->halmac_rw_bcn_ctrl(halmac, port, 1, &ctrl);
2376 	if (status != HALMAC_RET_SUCCESS)
2377 		goto out;
2378 
2379 	err = 0;
2380 out:
2381 	return err;
2382 }
2383 
2384 /**
2385  * rtw_halmac_set_aid() - Set association identifier(AID) of specific port
2386  * @d:		struct dvobj_priv*
2387  * @hwport:	port
2388  * @aid:	Association identifier
2389  *
2390  * Set association identifier(AID) of specific port to HALMAC.
2391  *
2392  * Return 0 for OK, otherwise fail.
2393  */
rtw_halmac_set_aid(struct dvobj_priv * d,enum _hw_port hwport,u16 aid)2394 int rtw_halmac_set_aid(struct dvobj_priv *d, enum _hw_port hwport, u16 aid)
2395 {
2396 	struct halmac_adapter *halmac;
2397 	struct halmac_api *api;
2398 	enum halmac_portid port;
2399 	enum halmac_ret_status status;
2400 	int err = -1;
2401 
2402 
2403 	halmac = dvobj_to_halmac(d);
2404 	api = HALMAC_GET_API(halmac);
2405 	port = _hw_port_drv2halmac(hwport);
2406 
2407 #if 0
2408 	status = api->halmac_cfg_aid(halmac, port, aid);
2409 	if (status != HALMAC_RET_SUCCESS)
2410 		goto out;
2411 #else
2412 {
2413 	struct _ADAPTER *a;
2414 	u32 addr;
2415 	u16 val;
2416 
2417 	a = dvobj_get_primary_adapter(d);
2418 
2419 	switch (port) {
2420 	case 0:
2421 		addr = REG_BCN_PSR_RPT;
2422 		val = rtw_read16(a, addr);
2423 		val = BIT_SET_PS_AID_0(val, aid);
2424 		rtw_write16(a, addr, val);
2425 		break;
2426 
2427 	case 1:
2428 		addr = REG_BCN_PSR_RPT1;
2429 		val = rtw_read16(a, addr);
2430 		val = BIT_SET_PS_AID_1(val, aid);
2431 		rtw_write16(a, addr, val);
2432 		break;
2433 
2434 	case 2:
2435 		addr = REG_BCN_PSR_RPT2;
2436 		val = rtw_read16(a, addr);
2437 		val = BIT_SET_PS_AID_2(val, aid);
2438 		rtw_write16(a, addr, val);
2439 		break;
2440 
2441 	case 3:
2442 		addr = REG_BCN_PSR_RPT3;
2443 		val = rtw_read16(a, addr);
2444 		val = BIT_SET_PS_AID_3(val, aid);
2445 		rtw_write16(a, addr, val);
2446 		break;
2447 
2448 	case 4:
2449 		addr = REG_BCN_PSR_RPT4;
2450 		val = rtw_read16(a, addr);
2451 		val = BIT_SET_PS_AID_4(val, aid);
2452 		rtw_write16(a, addr, val);
2453 		break;
2454 
2455 	default:
2456 		goto out;
2457 	}
2458 }
2459 #endif
2460 
2461 	err = 0;
2462 out:
2463 	return err;
2464 }
2465 
rtw_halmac_set_bandwidth(struct dvobj_priv * d,u8 channel,u8 pri_ch_idx,u8 bw)2466 int rtw_halmac_set_bandwidth(struct dvobj_priv *d, u8 channel, u8 pri_ch_idx, u8 bw)
2467 {
2468 	struct halmac_adapter *mac;
2469 	struct halmac_api *api;
2470 	enum halmac_ret_status status;
2471 
2472 
2473 	mac = dvobj_to_halmac(d);
2474 	api = HALMAC_GET_API(mac);
2475 
2476 	status = api->halmac_cfg_ch_bw(mac, channel, pri_ch_idx, bw);
2477 	if (HALMAC_RET_SUCCESS != status)
2478 		return -1;
2479 
2480 	return 0;
2481 }
2482 
2483 /**
2484  * rtw_halmac_set_edca() - config edca parameter
2485  * @d:		struct dvobj_priv*
2486  * @queue:	XMIT_[VO/VI/BE/BK]_QUEUE
2487  * @aifs:	Arbitration inter-frame space(AIFS)
2488  * @cw:		Contention window(CW)
2489  * @txop:	MAX Transmit Opportunity(TXOP)
2490  *
2491  * Return: 0 if process OK, otherwise -1.
2492  */
rtw_halmac_set_edca(struct dvobj_priv * d,u8 queue,u8 aifs,u8 cw,u16 txop)2493 int rtw_halmac_set_edca(struct dvobj_priv *d, u8 queue, u8 aifs, u8 cw, u16 txop)
2494 {
2495 	struct halmac_adapter *mac;
2496 	struct halmac_api *api;
2497 	enum halmac_acq_id ac;
2498 	struct halmac_edca_para edca;
2499 	enum halmac_ret_status status;
2500 
2501 
2502 	mac = dvobj_to_halmac(d);
2503 	api = HALMAC_GET_API(mac);
2504 
2505 	switch (queue) {
2506 	case XMIT_VO_QUEUE:
2507 		ac = HALMAC_ACQ_ID_VO;
2508 		break;
2509 	case XMIT_VI_QUEUE:
2510 		ac = HALMAC_ACQ_ID_VI;
2511 		break;
2512 	case XMIT_BE_QUEUE:
2513 		ac = HALMAC_ACQ_ID_BE;
2514 		break;
2515 	case XMIT_BK_QUEUE:
2516 		ac = HALMAC_ACQ_ID_BK;
2517 		break;
2518 	default:
2519 		return -1;
2520 	}
2521 
2522 	edca.aifs = aifs;
2523 	edca.cw = cw;
2524 	edca.txop_limit = txop;
2525 
2526 	status = api->halmac_cfg_edca_para(mac, ac, &edca);
2527 	if (status != HALMAC_RET_SUCCESS)
2528 		return -1;
2529 
2530 	return 0;
2531 }
2532 
2533 /**
2534  * rtw_halmac_set_rts_full_bw() - Send RTS to all covered channels
2535  * @d:		struct dvobj_priv*
2536  * @enable:	_TRUE(enable), _FALSE(disable)
2537  *
2538  * Hradware will duplicate RTS packet to all channels which are covered in used
2539  * bandwidth.
2540  *
2541  * Return 0 if process OK, otherwise -1.
2542  */
rtw_halmac_set_rts_full_bw(struct dvobj_priv * d,u8 enable)2543 int rtw_halmac_set_rts_full_bw(struct dvobj_priv *d, u8 enable)
2544 {
2545 	struct halmac_adapter *mac;
2546 	struct halmac_api *api;
2547 	enum halmac_ret_status status;
2548 	u8 full;
2549 
2550 
2551 	mac = dvobj_to_halmac(d);
2552 	api = HALMAC_GET_API(mac);
2553 	full = (enable == _TRUE) ? 1 : 0;
2554 
2555 	status = api->halmac_set_hw_value(mac, HALMAC_HW_RTS_FULL_BW, &full);
2556 	if (HALMAC_RET_SUCCESS != status)
2557 		return -1;
2558 
2559 	return 0;
2560 }
2561 
2562 #ifdef RTW_HALMAC_DBG_POWER_SWITCH
_dump_mac_reg(struct dvobj_priv * d,u32 start,u32 end)2563 static void _dump_mac_reg(struct dvobj_priv *d, u32 start, u32 end)
2564 {
2565 	struct _ADAPTER *adapter;
2566 	int i, j = 1;
2567 
2568 
2569 	adapter = dvobj_get_primary_adapter(d);
2570 	for (i = start; i < end; i += 4) {
2571 		if (j % 4 == 1)
2572 			RTW_PRINT("0x%04x", i);
2573 		_RTW_PRINT(" 0x%08x ", rtw_read32(adapter, i));
2574 		if ((j++) % 4 == 0)
2575 			_RTW_PRINT("\n");
2576 	}
2577 }
2578 
dump_dbg_val(struct _ADAPTER * a,u32 reg)2579 void dump_dbg_val(struct _ADAPTER *a, u32 reg)
2580 {
2581 	u32 v32;
2582 
2583 
2584 	rtw_write8(a, 0x3A, reg);
2585 	v32 = rtw_read32(a, 0xC0);
2586 	RTW_PRINT("0x3A = %02x, 0xC0 = 0x%08x\n",reg, v32);
2587 }
2588 
2589 #ifdef CONFIG_PCI_HCI
_dump_pcie_cfg_space(struct dvobj_priv * d)2590 static void _dump_pcie_cfg_space(struct dvobj_priv *d)
2591 {
2592 	struct _ADAPTER *padapter = dvobj_get_primary_adapter(d);
2593 	struct dvobj_priv       *pdvobjpriv = adapter_to_dvobj(padapter);
2594 	struct pci_dev  *pdev = pdvobjpriv->ppcidev;
2595 	struct pci_dev  *bridge_pdev = pdev->bus->self;
2596 
2597         u32 tmp[4] = { 0 };
2598         u32 i, j;
2599 
2600 	RTW_PRINT("\n*****  PCI Device Configuration Space *****\n\n");
2601 
2602         for(i = 0; i < 0x100; i += 0x10)
2603         {
2604                 for (j = 0 ; j < 4 ; j++)
2605                         pci_read_config_dword(pdev, i + j * 4, tmp+j);
2606 
2607         	RTW_PRINT("%03x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
2608                         i, tmp[0] & 0xFF, (tmp[0] >> 8) & 0xFF, (tmp[0] >> 16) & 0xFF, (tmp[0] >> 24) & 0xFF,
2609                         tmp[1] & 0xFF, (tmp[1] >> 8) & 0xFF, (tmp[1] >> 16) & 0xFF, (tmp[1] >> 24) & 0xFF,
2610                         tmp[2] & 0xFF, (tmp[2] >> 8) & 0xFF, (tmp[2] >> 16) & 0xFF, (tmp[2] >> 24) & 0xFF,
2611                         tmp[3] & 0xFF, (tmp[3] >> 8) & 0xFF, (tmp[3] >> 16) & 0xFF, (tmp[3] >> 24) & 0xFF);
2612         }
2613 
2614 	RTW_PRINT("\n*****  PCI Host Device Configuration Space*****\n\n");
2615 
2616         for(i = 0; i < 0x100; i += 0x10)
2617         {
2618                 for (j = 0 ; j < 4 ; j++)
2619                         pci_read_config_dword(bridge_pdev, i + j * 4, tmp+j);
2620 
2621         	RTW_PRINT("%03x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
2622                         i, tmp[0] & 0xFF, (tmp[0] >> 8) & 0xFF, (tmp[0] >> 16) & 0xFF, (tmp[0] >> 24) & 0xFF,
2623                         tmp[1] & 0xFF, (tmp[1] >> 8) & 0xFF, (tmp[1] >> 16) & 0xFF, (tmp[1] >> 24) & 0xFF,
2624                         tmp[2] & 0xFF, (tmp[2] >> 8) & 0xFF, (tmp[2] >> 16) & 0xFF, (tmp[2] >> 24) & 0xFF,
2625                         tmp[3] & 0xFF, (tmp[3] >> 8) & 0xFF, (tmp[3] >> 16) & 0xFF, (tmp[3] >> 24) & 0xFF);
2626         }
2627 }
2628 #endif
2629 
_dump_mac_reg_for_power_switch(struct dvobj_priv * d,const char * caller,char * desc)2630 static void _dump_mac_reg_for_power_switch(struct dvobj_priv *d,
2631 					   const char* caller, char* desc)
2632 {
2633 	struct _ADAPTER *a;
2634 	u8 v8;
2635 
2636 
2637 	RTW_PRINT("%s: %s\n", caller, desc);
2638 	RTW_PRINT("======= MAC REG =======\n");
2639 	/* page 0/1 */
2640 	_dump_mac_reg(d, 0x0, 0x200);
2641 	_dump_mac_reg(d, 0x300, 0x400); /* also dump page 3 */
2642 
2643 	/* dump debug register */
2644 	a = dvobj_get_primary_adapter(d);
2645 
2646 #ifdef CONFIG_PCI_HCI
2647 	_dump_pcie_cfg_space(d);
2648 
2649 	v8 = rtw_read8(a, 0xF6) | 0x01;
2650 	rtw_write8(a, 0xF6, v8);
2651 	RTW_PRINT("0xF6 = %02x\n", v8);
2652 
2653 	dump_dbg_val(a, 0x63);
2654 	dump_dbg_val(a, 0x64);
2655 	dump_dbg_val(a, 0x68);
2656 	dump_dbg_val(a, 0x69);
2657 	dump_dbg_val(a, 0x6a);
2658 	dump_dbg_val(a, 0x6b);
2659 	dump_dbg_val(a, 0x71);
2660 	dump_dbg_val(a, 0x72);
2661 #endif
2662 }
2663 
_power_switch(struct halmac_adapter * halmac,struct halmac_api * api,enum halmac_mac_power pwr)2664 static enum halmac_ret_status _power_switch(struct halmac_adapter *halmac,
2665 					    struct halmac_api *api,
2666 					    enum halmac_mac_power pwr)
2667 {
2668 	enum halmac_ret_status status;
2669 	char desc[80] = {0};
2670 
2671 
2672 	rtw_sprintf(desc, 80, "before calling power %s",
2673 				(pwr==HALMAC_MAC_POWER_ON)?"on":"off");
2674 	_dump_mac_reg_for_power_switch((struct dvobj_priv *)halmac->drv_adapter,
2675 			__FUNCTION__, desc);
2676 
2677 	status = api->halmac_mac_power_switch(halmac, pwr);
2678 	RTW_PRINT("%s: status=%d\n", __FUNCTION__, status);
2679 
2680 	rtw_sprintf(desc, 80, "after calling power %s",
2681 				(pwr==HALMAC_MAC_POWER_ON)?"on":"off");
2682 	_dump_mac_reg_for_power_switch((struct dvobj_priv *)halmac->drv_adapter,
2683 			__FUNCTION__, desc);
2684 
2685 	return status;
2686 }
2687 #else /* !RTW_HALMAC_DBG_POWER_SWITCH */
2688 #define _power_switch(mac, api, pwr)	(api)->halmac_mac_power_switch(mac, pwr)
2689 #endif /* !RTW_HALMAC_DBG_POWER_SWITCH */
2690 
2691 /*
2692  * Description:
2693  *	Power on device hardware.
2694  *	[Notice!] If device's power state is on before,
2695  *	it would be power off first and turn on power again.
2696  *
2697  * Return:
2698  *	0	power on success
2699  *	-1	power on fail
2700  *	-2	power state unchange
2701  */
rtw_halmac_poweron(struct dvobj_priv * d)2702 int rtw_halmac_poweron(struct dvobj_priv *d)
2703 {
2704 	struct halmac_adapter *halmac;
2705 	struct halmac_api *api;
2706 	enum halmac_ret_status status;
2707 	int err = -1;
2708 #if defined(CONFIG_PCI_HCI) && defined(CONFIG_RTL8822B)
2709 	struct _ADAPTER *a;
2710 	u8 v8;
2711 	u32 addr;
2712 
2713 	a = dvobj_get_primary_adapter(d);
2714 #endif
2715 
2716 	halmac = dvobj_to_halmac(d);
2717 	if (!halmac)
2718 		goto out;
2719 
2720 	api = HALMAC_GET_API(halmac);
2721 
2722 	status = api->halmac_pre_init_system_cfg(halmac);
2723 	if (status != HALMAC_RET_SUCCESS)
2724 		goto out;
2725 
2726 #ifdef CONFIG_SDIO_HCI
2727 	status = api->halmac_sdio_cmd53_4byte(halmac, HALMAC_SDIO_CMD53_4BYTE_MODE_RW);
2728 	if (status != HALMAC_RET_SUCCESS)
2729 		goto out;
2730 #endif /* CONFIG_SDIO_HCI */
2731 
2732 #if defined(CONFIG_PCI_HCI) && defined(CONFIG_RTL8822B)
2733 	addr = 0x3F3;
2734 	v8 = rtw_read8(a, addr);
2735 	RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v8);
2736 	/* are we in pcie debug mode? */
2737 	if (!(v8 & BIT(2))) {
2738 		RTW_PRINT("%s: Enable pcie debug mode\n", __FUNCTION__);
2739 		v8 |= BIT(2);
2740 		v8 = rtw_write8(a, addr, v8);
2741 	}
2742 #endif
2743 
2744 	status = _power_switch(halmac, api, HALMAC_MAC_POWER_ON);
2745 	if (HALMAC_RET_PWR_UNCHANGE == status) {
2746 
2747 #if defined(CONFIG_PCI_HCI) && defined(CONFIG_RTL8822B)
2748 		addr = 0x3F3;
2749 		v8 = rtw_read8(a, addr);
2750 		RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v8);
2751 
2752 		/* are we in pcie debug mode? */
2753 		if (!(v8 & BIT(2))) {
2754 			RTW_PRINT("%s: Enable pcie debug mode\n", __FUNCTION__);
2755 			v8 |= BIT(2);
2756 			v8 = rtw_write8(a, addr, v8);
2757 		} else if (v8 & BIT(0)) {
2758 			/* DMA stuck */
2759 			addr = 0x1350;
2760 			v8 = rtw_read8(a, addr);
2761 			RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v8);
2762 			RTW_PRINT("%s: recover DMA stuck\n", __FUNCTION__);
2763 			v8 |= BIT(6);
2764 			v8 = rtw_write8(a, addr, v8);
2765 			RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v8);
2766 		}
2767 #endif
2768 		/*
2769 		 * Work around for warm reboot but device not power off,
2770 		 * but it would also fall into this case when auto power on is enabled.
2771 		 */
2772 		_power_switch(halmac, api, HALMAC_MAC_POWER_OFF);
2773 		status = _power_switch(halmac, api, HALMAC_MAC_POWER_ON);
2774 		RTW_WARN("%s: Power state abnormal, try to recover...%s\n",
2775 			 __FUNCTION__, (HALMAC_RET_SUCCESS == status)?"OK":"FAIL!");
2776 	}
2777 	if (HALMAC_RET_SUCCESS != status) {
2778 		if (HALMAC_RET_PWR_UNCHANGE == status)
2779 			err = -2;
2780 		goto out;
2781 	}
2782 
2783 	status = api->halmac_init_system_cfg(halmac);
2784 	if (status != HALMAC_RET_SUCCESS)
2785 		goto out;
2786 
2787 	err = 0;
2788 out:
2789 	return err;
2790 }
2791 
2792 /*
2793  * Description:
2794  *	Power off device hardware.
2795  *
2796  * Return:
2797  *	0	Power off success
2798  *	-1	Power off fail
2799  */
rtw_halmac_poweroff(struct dvobj_priv * d)2800 int rtw_halmac_poweroff(struct dvobj_priv *d)
2801 {
2802 	struct halmac_adapter *halmac;
2803 	struct halmac_api *api;
2804 	enum halmac_ret_status status;
2805 	int err = -1;
2806 
2807 
2808 	halmac = dvobj_to_halmac(d);
2809 	if (!halmac)
2810 		goto out;
2811 
2812 	api = HALMAC_GET_API(halmac);
2813 
2814 	status = _power_switch(halmac, api, HALMAC_MAC_POWER_OFF);
2815 	if ((HALMAC_RET_SUCCESS != status)
2816 	    && (HALMAC_RET_PWR_UNCHANGE != status))
2817 		goto out;
2818 
2819 	err = 0;
2820 out:
2821 	return err;
2822 }
2823 
2824 #ifdef CONFIG_SUPPORT_TRX_SHARED
_trx_share_mode_drv2halmac(u8 trx_share_mode)2825 static inline enum halmac_rx_fifo_expanding_mode _trx_share_mode_drv2halmac(u8 trx_share_mode)
2826 {
2827 	if (0 == trx_share_mode)
2828 		return HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE;
2829 	else if (1 == trx_share_mode)
2830 		return HALMAC_RX_FIFO_EXPANDING_MODE_1_BLOCK;
2831 	else if (2 == trx_share_mode)
2832 		return HALMAC_RX_FIFO_EXPANDING_MODE_2_BLOCK;
2833 	else if (3 == trx_share_mode)
2834 		return HALMAC_RX_FIFO_EXPANDING_MODE_3_BLOCK;
2835 	else
2836 		return HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE;
2837 }
2838 
_rtw_get_trx_share_mode(struct _ADAPTER * adapter)2839 static enum halmac_rx_fifo_expanding_mode _rtw_get_trx_share_mode(struct _ADAPTER *adapter)
2840 {
2841 	struct registry_priv *registry_par = &adapter->registrypriv;
2842 
2843 	return _trx_share_mode_drv2halmac(registry_par->trx_share_mode);
2844 }
2845 
dump_trx_share_mode(void * sel,struct _ADAPTER * adapter)2846 void dump_trx_share_mode(void *sel, struct _ADAPTER *adapter)
2847 {
2848 	struct registry_priv  *registry_par = &adapter->registrypriv;
2849 	u8 mode = _trx_share_mode_drv2halmac(registry_par->trx_share_mode);
2850 
2851 	if (HALMAC_RX_FIFO_EXPANDING_MODE_1_BLOCK == mode)
2852 		RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "RX_FIFO_EXPANDING_MODE_1");
2853 	else if (HALMAC_RX_FIFO_EXPANDING_MODE_2_BLOCK == mode)
2854 		RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "RX_FIFO_EXPANDING_MODE_2");
2855 	else if (HALMAC_RX_FIFO_EXPANDING_MODE_3_BLOCK == mode)
2856 		RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "RX_FIFO_EXPANDING_MODE_3");
2857 	else
2858 		RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "DISABLE");
2859 }
2860 #endif
2861 
_rsvd_page_num_drv2halmac(u16 num)2862 static enum halmac_drv_rsvd_pg_num _rsvd_page_num_drv2halmac(u16 num)
2863 {
2864 	if (num <= 8)
2865 		return HALMAC_RSVD_PG_NUM8;
2866 	if (num <= 16)
2867 		return HALMAC_RSVD_PG_NUM16;
2868 	if (num <= 24)
2869 		return HALMAC_RSVD_PG_NUM24;
2870 	if (num <= 32)
2871 		return HALMAC_RSVD_PG_NUM32;
2872 	if (num <= 64)
2873 		return HALMAC_RSVD_PG_NUM64;
2874 	if (num <= 128)
2875 		return HALMAC_RSVD_PG_NUM128;
2876 
2877 	if (num > 256)
2878 		RTW_WARN("%s: Fail to allocate RSVD page(%d)!!"
2879 			 " The MAX RSVD page number is 256...\n",
2880 			 __FUNCTION__, num);
2881 
2882 	return HALMAC_RSVD_PG_NUM256;
2883 }
2884 
_rsvd_page_num_halmac2drv(enum halmac_drv_rsvd_pg_num rsvd_page_number)2885 static u16 _rsvd_page_num_halmac2drv(enum halmac_drv_rsvd_pg_num rsvd_page_number)
2886 {
2887 	u16 num = 0;
2888 
2889 
2890 	switch (rsvd_page_number) {
2891 	case HALMAC_RSVD_PG_NUM8:
2892 		num = 8;
2893 		break;
2894 
2895 	case HALMAC_RSVD_PG_NUM16:
2896 		num = 16;
2897 		break;
2898 
2899 	case HALMAC_RSVD_PG_NUM24:
2900 		num = 24;
2901 		break;
2902 
2903 	case HALMAC_RSVD_PG_NUM32:
2904 		num = 32;
2905 		break;
2906 
2907 	case HALMAC_RSVD_PG_NUM64:
2908 		num = 64;
2909 		break;
2910 
2911 	case HALMAC_RSVD_PG_NUM128:
2912 		num = 128;
2913 		break;
2914 
2915 	case HALMAC_RSVD_PG_NUM256:
2916 		num = 256;
2917 		break;
2918 	}
2919 
2920 	return num;
2921 }
2922 
_choose_trx_mode(struct dvobj_priv * d)2923 static enum halmac_trx_mode _choose_trx_mode(struct dvobj_priv *d)
2924 {
2925 	PADAPTER p;
2926 
2927 
2928 	p = dvobj_get_primary_adapter(d);
2929 
2930 	if (p->registrypriv.wifi_spec)
2931 		return HALMAC_TRX_MODE_WMM;
2932 
2933 #ifdef CONFIG_SUPPORT_TRX_SHARED
2934 	if (_rtw_get_trx_share_mode(p))
2935 		return HALMAC_TRX_MODE_TRXSHARE;
2936 #endif
2937 
2938 	return HALMAC_TRX_MODE_NORMAL;
2939 }
2940 
_rf_type_drv2halmac(enum rf_type rf_drv)2941 static inline enum halmac_rf_type _rf_type_drv2halmac(enum rf_type rf_drv)
2942 {
2943 	enum halmac_rf_type rf_mac;
2944 
2945 
2946 	switch (rf_drv) {
2947 	case RF_1T1R:
2948 		rf_mac = HALMAC_RF_1T1R;
2949 		break;
2950 	case RF_1T2R:
2951 		rf_mac = HALMAC_RF_1T2R;
2952 		break;
2953 	case RF_2T2R:
2954 		rf_mac = HALMAC_RF_2T2R;
2955 		break;
2956 	case RF_2T3R:
2957 		rf_mac = HALMAC_RF_2T3R;
2958 		break;
2959 	case RF_2T4R:
2960 		rf_mac = HALMAC_RF_2T4R;
2961 		break;
2962 	case RF_3T3R:
2963 		rf_mac = HALMAC_RF_3T3R;
2964 		break;
2965 	case RF_3T4R:
2966 		rf_mac = HALMAC_RF_3T4R;
2967 		break;
2968 	case RF_4T4R:
2969 		rf_mac = HALMAC_RF_4T4R;
2970 		break;
2971 	default:
2972 		rf_mac = HALMAC_RF_MAX_TYPE;
2973 		RTW_ERR("%s: Invalid RF type(0x%x)!\n", __FUNCTION__, rf_drv);
2974 		break;
2975 	}
2976 
2977 	return rf_mac;
2978 }
2979 
_rf_type_halmac2drv(enum halmac_rf_type rf_mac)2980 static inline enum rf_type _rf_type_halmac2drv(enum halmac_rf_type rf_mac)
2981 {
2982 	enum rf_type rf_drv;
2983 
2984 
2985 	switch (rf_mac) {
2986 	case HALMAC_RF_1T2R:
2987 		rf_drv = RF_1T2R;
2988 		break;
2989 	case HALMAC_RF_2T4R:
2990 		rf_drv = RF_2T4R;
2991 		break;
2992 	case HALMAC_RF_2T2R:
2993 	case HALMAC_RF_2T2R_GREEN:
2994 		rf_drv = RF_2T2R;
2995 		break;
2996 	case HALMAC_RF_2T3R:
2997 		rf_drv = RF_2T3R;
2998 		break;
2999 	case HALMAC_RF_1T1R:
3000 		rf_drv = RF_1T1R;
3001 		break;
3002 	case HALMAC_RF_3T3R:
3003 		rf_drv = RF_3T3R;
3004 		break;
3005 	case HALMAC_RF_3T4R:
3006 		rf_drv = RF_3T4R;
3007 		break;
3008 	case HALMAC_RF_4T4R:
3009 		rf_drv = RF_4T4R;
3010 		break;
3011 	default:
3012 		rf_drv = RF_TYPE_MAX;
3013 		RTW_ERR("%s: Invalid RF type(0x%x)!\n", __FUNCTION__, rf_mac);
3014 		break;
3015 	}
3016 
3017 	return rf_drv;
3018 }
3019 
_cut_version_drv2phydm(enum tag_HAL_Cut_Version_Definition cut_drv)3020 static enum odm_cut_version _cut_version_drv2phydm(
3021 				enum tag_HAL_Cut_Version_Definition cut_drv)
3022 {
3023 	enum odm_cut_version cut_phydm = ODM_CUT_A;
3024 	u32 diff;
3025 
3026 
3027 	if (cut_drv > K_CUT_VERSION)
3028 		RTW_WARN("%s: unknown cut_ver=%d !!\n", __FUNCTION__, cut_drv);
3029 
3030 	diff = cut_drv - A_CUT_VERSION;
3031 	cut_phydm += diff;
3032 
3033 	return cut_phydm;
3034 }
3035 
_send_general_info_by_reg(struct dvobj_priv * d,struct halmac_general_info * info)3036 static int _send_general_info_by_reg(struct dvobj_priv *d,
3037 				     struct halmac_general_info *info)
3038 {
3039 	struct _ADAPTER *a;
3040 	struct hal_com_data *hal;
3041 	enum tag_HAL_Cut_Version_Definition cut_drv;
3042 	enum rf_type rftype;
3043 	enum odm_cut_version cut_phydm;
3044 	u8 h2c[RTW_HALMAC_H2C_MAX_SIZE] = {0};
3045 
3046 
3047 	a = dvobj_get_primary_adapter(d);
3048 	hal = GET_HAL_DATA(a);
3049 	rftype = _rf_type_halmac2drv(info->rf_type);
3050 	cut_drv = GET_CVID_CUT_VERSION(hal->version_id);
3051 	cut_phydm = _cut_version_drv2phydm(cut_drv);
3052 
3053 #define CLASS_GENERAL_INFO_REG				0x02
3054 #define CMD_ID_GENERAL_INFO_REG				0x0C
3055 #define GENERAL_INFO_REG_SET_CMD_ID(buf, v)		SET_BITS_TO_LE_4BYTE(buf, 0, 5, v)
3056 #define GENERAL_INFO_REG_SET_CLASS(buf, v)		SET_BITS_TO_LE_4BYTE(buf, 5, 3, v)
3057 #define GENERAL_INFO_REG_SET_RFE_TYPE(buf, v)		SET_BITS_TO_LE_4BYTE(buf, 8, 8, v)
3058 #define GENERAL_INFO_REG_SET_RF_TYPE(buf, v)		SET_BITS_TO_LE_4BYTE(buf, 16, 8, v)
3059 #define GENERAL_INFO_REG_SET_CUT_VERSION(buf, v)	SET_BITS_TO_LE_4BYTE(buf, 24, 8, v)
3060 #define GENERAL_INFO_REG_SET_RX_ANT_STATUS(buf, v)	SET_BITS_TO_LE_1BYTE(buf+4, 0, 4, v)
3061 #define GENERAL_INFO_REG_SET_TX_ANT_STATUS(buf, v)	SET_BITS_TO_LE_1BYTE(buf+4, 4, 4, v)
3062 
3063 	GENERAL_INFO_REG_SET_CMD_ID(h2c, CMD_ID_GENERAL_INFO_REG);
3064 	GENERAL_INFO_REG_SET_CLASS(h2c, CLASS_GENERAL_INFO_REG);
3065 	GENERAL_INFO_REG_SET_RFE_TYPE(h2c, info->rfe_type);
3066 	GENERAL_INFO_REG_SET_RF_TYPE(h2c, rftype);
3067 	GENERAL_INFO_REG_SET_CUT_VERSION(h2c, cut_phydm);
3068 	GENERAL_INFO_REG_SET_RX_ANT_STATUS(h2c, info->rx_ant_status);
3069 	GENERAL_INFO_REG_SET_TX_ANT_STATUS(h2c, info->tx_ant_status);
3070 
3071 	return rtw_halmac_send_h2c(d, h2c);
3072 }
3073 
_send_general_info(struct dvobj_priv * d)3074 static int _send_general_info(struct dvobj_priv *d)
3075 {
3076 	struct _ADAPTER *adapter;
3077 	struct hal_com_data *hal;
3078 	struct halmac_adapter *halmac;
3079 	struct halmac_api *api;
3080 	struct halmac_general_info info;
3081 	enum halmac_ret_status status;
3082 	enum rf_type rf = RF_1T1R;
3083 	enum bb_path txpath = BB_PATH_A;
3084 	enum bb_path rxpath = BB_PATH_A;
3085 	int err;
3086 
3087 
3088 	adapter = dvobj_get_primary_adapter(d);
3089 	hal = GET_HAL_DATA(adapter);
3090 	halmac = dvobj_to_halmac(d);
3091 	if (!halmac)
3092 		return -1;
3093 	api = HALMAC_GET_API(halmac);
3094 
3095 	_rtw_memset(&info, 0, sizeof(info));
3096 	info.rfe_type = (u8)hal->rfe_type;
3097 	rtw_hal_get_trx_path(d, &rf, &txpath, &rxpath);
3098 	info.rf_type = _rf_type_drv2halmac(rf);
3099 	info.tx_ant_status = (u8)txpath;
3100 	info.rx_ant_status = (u8)rxpath;
3101 	info.ext_pa = 0;	/* 2.4G or 5G? format not known */
3102 	info.package_type = hal->PackageType;
3103 	info.mp_mode = adapter->registrypriv.mp_mode;
3104 
3105 	status = api->halmac_send_general_info(halmac, &info);
3106 	switch (status) {
3107 	case HALMAC_RET_SUCCESS:
3108 		break;
3109 	case HALMAC_RET_NO_DLFW:
3110 		RTW_WARN("%s: halmac_send_general_info() fail because fw not dl!\n",
3111 			 __FUNCTION__);
3112 		/* fall through */
3113 	default:
3114 		return -1;
3115 	}
3116 
3117 	err = _send_general_info_by_reg(d, &info);
3118 	if (err) {
3119 		RTW_ERR("%s: Fail to send general info by register!\n",
3120 			 __FUNCTION__);
3121 		return -1;
3122 	}
3123 
3124 	return 0;
3125 }
3126 
_cfg_drv_rsvd_pg_num(struct dvobj_priv * d)3127 static int _cfg_drv_rsvd_pg_num(struct dvobj_priv *d)
3128 {
3129 	struct _ADAPTER *a;
3130 	struct hal_com_data *hal;
3131 	struct halmac_adapter *halmac;
3132 	struct halmac_api *api;
3133 	enum halmac_drv_rsvd_pg_num rsvd_page_number;
3134 	enum halmac_ret_status status;
3135 	u16 drv_rsvd_num;
3136 	int ret = 0;
3137 
3138 
3139 	a = dvobj_get_primary_adapter(d);
3140 	hal = GET_HAL_DATA(a);
3141 	halmac = dvobj_to_halmac(d);
3142 	api = HALMAC_GET_API(halmac);
3143 
3144 	drv_rsvd_num = rtw_hal_get_rsvd_page_num(a);
3145 	rsvd_page_number = _rsvd_page_num_drv2halmac(drv_rsvd_num);
3146 	status = api->halmac_cfg_drv_rsvd_pg_num(halmac, rsvd_page_number);
3147 	if (status != HALMAC_RET_SUCCESS) {
3148 		ret = -1;
3149 		goto exit;
3150 	}
3151 	hal->drv_rsvd_page_number = _rsvd_page_num_halmac2drv(rsvd_page_number);
3152 
3153 exit:
3154 #ifndef DBG_RSVD_PAGE_CFG
3155 	if (drv_rsvd_num != _rsvd_page_num_halmac2drv(rsvd_page_number))
3156 #endif
3157 		RTW_INFO("%s: request %d pages => halmac %d pages %s\n"
3158 			, __FUNCTION__, drv_rsvd_num, _rsvd_page_num_halmac2drv(rsvd_page_number)
3159 			, ret ? "fail" : "success");
3160 
3161 	return ret;
3162 }
3163 
_debug_dlfw_fail(struct dvobj_priv * d)3164 static void _debug_dlfw_fail(struct dvobj_priv *d)
3165 {
3166 	struct _ADAPTER *a;
3167 	u32 addr;
3168 	u32 v32, i, n;
3169 
3170 
3171 	a = dvobj_get_primary_adapter(d);
3172 
3173 	/* read 0x80[15:0], 0x10F8[31:0] once */
3174 	addr = 0x80;
3175 	v32 = rtw_read16(a, addr);
3176 	RTW_PRINT("%s: 0x%X = 0x%04x\n", __FUNCTION__, addr, v32);
3177 
3178 	addr = 0x10F8;
3179 	v32 = rtw_read32(a, addr);
3180 	RTW_PRINT("%s: 0x%X = 0x%08x\n", __FUNCTION__, addr, v32);
3181 
3182 	/* read 0x10FC[31:0], 5 times */
3183 	addr = 0x10FC;
3184 	n = 5;
3185 	for (i = 0; i < n; i++) {
3186 		v32 = rtw_read32(a, addr);
3187 		RTW_PRINT("%s: 0x%X = 0x%08x (%u/%u)\n",
3188 			  __FUNCTION__, addr, v32, i, n);
3189 	}
3190 
3191 	/*
3192 	 * write 0x3A[7:0]=0x28 and 0xF6[7:0]=0x01
3193 	 * and then read 0xC0[31:0] 5 times
3194 	 */
3195 	addr = 0x3A;
3196 	v32 = 0x28;
3197 	rtw_write8(a, addr, (u8)v32);
3198 	v32 = rtw_read8(a, addr);
3199 	RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v32);
3200 
3201 	addr = 0xF6;
3202 	v32 = 0x1;
3203 	rtw_write8(a, addr, (u8)v32);
3204 	v32 = rtw_read8(a, addr);
3205 	RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v32);
3206 
3207 	addr = 0xC0;
3208 	n = 5;
3209 	for (i = 0; i < n; i++) {
3210 		v32 = rtw_read32(a, addr);
3211 		RTW_PRINT("%s: 0x%X = 0x%08x (%u/%u)\n",
3212 			  __FUNCTION__, addr, v32, i, n);
3213 	}
3214 
3215 	mac_reg_dump(NULL, a);
3216 #ifdef CONFIG_SDIO_HCI
3217 	RTW_PRINT("======= SDIO Local REG =======\n");
3218 	sdio_local_reg_dump(NULL, a);
3219 	RTW_PRINT("======= SDIO CCCR REG =======\n");
3220 	sd_f0_reg_dump(NULL, a);
3221 #endif /* CONFIG_SDIO_HCI */
3222 
3223 	/* read 0x80 after 10 secs */
3224 	rtw_msleep_os(10000);
3225 	addr = 0x80;
3226 	v32 = rtw_read16(a, addr);
3227 	RTW_PRINT("%s: 0x%X = 0x%04x (after 10 secs)\n",
3228 		  __FUNCTION__, addr, v32);
3229 }
3230 
_enter_cpu_sleep_mode(struct dvobj_priv * d)3231 static enum halmac_ret_status _enter_cpu_sleep_mode(struct dvobj_priv *d)
3232 {
3233 	struct hal_com_data *hal;
3234 	struct halmac_adapter *mac;
3235 	struct halmac_api *api;
3236 
3237 
3238 	hal = GET_HAL_DATA(dvobj_get_primary_adapter(d));
3239 	mac = dvobj_to_halmac(d);
3240 	api = HALMAC_GET_API(mac);
3241 
3242 #ifdef CONFIG_RTL8822B
3243 	/* Support after firmware version 21 */
3244 	if (hal->firmware_version < 21)
3245 		return HALMAC_RET_NOT_SUPPORT;
3246 #elif defined(CONFIG_RTL8821C)
3247 	/* Support after firmware version 13.6 or 16 */
3248 	if (hal->firmware_version == 13) {
3249 		if (hal->firmware_sub_version < 6)
3250 			return HALMAC_RET_NOT_SUPPORT;
3251 	} else if (hal->firmware_version < 16) {
3252 		return HALMAC_RET_NOT_SUPPORT;
3253 	}
3254 #endif
3255 
3256 	return api->halmac_enter_cpu_sleep_mode(mac);
3257 }
3258 
3259 /*
3260  * _cpu_sleep() - Let IC CPU enter sleep mode
3261  * @d:		struct dvobj_priv*
3262  * @timeout:	time limit of wait, unit is ms
3263  *		0 for no limit
3264  *
3265  * Return 0 for CPU in sleep mode, otherwise fail to enter sleep mode.
3266  * Error codes definition are as follow:
3267  * 	-1	HALMAC enter sleep return fail
3268  *	-2	HALMAC get CPU mode return fail
3269  *	-110	timeout
3270  */
_cpu_sleep(struct dvobj_priv * d,u32 timeout)3271 static int _cpu_sleep(struct dvobj_priv *d, u32 timeout)
3272 {
3273 	struct halmac_adapter *mac;
3274 	struct halmac_api *api;
3275 	enum halmac_ret_status status;
3276 	enum halmac_wlcpu_mode mode = HALMAC_WLCPU_UNDEFINE;
3277 	systime start_t;
3278 	s32 period = 0;
3279 	u32 cnt = 0;
3280 	int err = 0;
3281 
3282 
3283 	mac = dvobj_to_halmac(d);
3284 	api = HALMAC_GET_API(mac);
3285 
3286 	start_t = rtw_get_current_time();
3287 
3288 	status = _enter_cpu_sleep_mode(d);
3289 	if (status != HALMAC_RET_SUCCESS) {
3290 		if (status != HALMAC_RET_NOT_SUPPORT)
3291 			err = -1;
3292 		goto exit;
3293 	}
3294 
3295 	do {
3296 		cnt++;
3297 
3298 		mode = HALMAC_WLCPU_UNDEFINE;
3299 		status = api->halmac_get_cpu_mode(mac, &mode);
3300 
3301 		period = rtw_get_passing_time_ms(start_t);
3302 
3303 		if (status != HALMAC_RET_SUCCESS) {
3304 			err = -2;
3305 			break;
3306 		}
3307 		if (mode == HALMAC_WLCPU_SLEEP)
3308 			break;
3309 		if (period > timeout) {
3310 			err = -110;
3311 			break;
3312 		}
3313 
3314 		rtw_msleep_os(1);
3315 	} while (1);
3316 
3317 exit:
3318 	if (err)
3319 		RTW_ERR("%s: Fail to enter sleep mode! (%d, %d)\n",
3320 			__FUNCTION__, status, mode);
3321 
3322 	RTW_INFO("%s: Cost %dms to polling %u times. (err=%d)\n",
3323 		__FUNCTION__, period, cnt, err);
3324 
3325 	return err;
3326 }
3327 
_init_trx_cfg_drv(struct dvobj_priv * d)3328 static void _init_trx_cfg_drv(struct dvobj_priv *d)
3329 {
3330 #ifdef CONFIG_PCI_HCI
3331 	rtw_hal_irp_reset(dvobj_get_primary_adapter(d));
3332 #endif
3333 }
3334 
3335 /*
3336  * Description:
3337  *	Downlaod Firmware Flow
3338  *
3339  * Parameters:
3340  *	d	pointer of struct dvobj_priv
3341  *	fw	firmware array
3342  *	fwsize	firmware size
3343  *	re_dl	re-download firmware or not
3344  *		0: run in init hal flow, not re-download
3345  *		1: it is a stand alone operation, not in init hal flow
3346  *
3347  * Return:
3348  *	0	Success
3349  *	others	Fail
3350  */
download_fw(struct dvobj_priv * d,u8 * fw,u32 fwsize,u8 re_dl)3351 static int download_fw(struct dvobj_priv *d, u8 *fw, u32 fwsize, u8 re_dl)
3352 {
3353 	PHAL_DATA_TYPE hal;
3354 	struct halmac_adapter *mac;
3355 	struct halmac_api *api;
3356 	struct halmac_fw_version fw_vesion;
3357 	enum halmac_ret_status status;
3358 	int err = 0;
3359 
3360 
3361 	hal = GET_HAL_DATA(dvobj_get_primary_adapter(d));
3362 	mac = dvobj_to_halmac(d);
3363 	api = HALMAC_GET_API(mac);
3364 
3365 	if ((!fw) || (!fwsize))
3366 		return -1;
3367 
3368 	/* 1. Driver Stop Tx */
3369 	/* ToDo */
3370 
3371 	/* 2. Driver Check Tx FIFO is empty */
3372 	err = rtw_halmac_txfifo_wait_empty(d, 2000); /* wait 2s */
3373 	if (err) {
3374 		err = -1;
3375 		goto resume_tx;
3376 	}
3377 
3378 	/* 3. Config MAX download size */
3379 	/*
3380 	 * Already done in rtw_halmac_init_adapter() or
3381 	 * somewhere calling rtw_halmac_set_max_dl_fw_size().
3382 	 */
3383 
3384 	if (re_dl) {
3385 		/* 4. Enter IC CPU sleep mode */
3386 		err = _cpu_sleep(d, 2000);
3387 		if (err) {
3388 			RTW_ERR("%s: IC CPU fail to enter sleep mode!(%d)\n",
3389 				__FUNCTION__, err);
3390 			/* skip this error */
3391 			err = 0;
3392 		}
3393 	}
3394 
3395 	/* 5. Download Firmware */
3396 	status = api->halmac_download_firmware(mac, fw, fwsize);
3397 	if (status != HALMAC_RET_SUCCESS) {
3398 		RTW_ERR("%s: download firmware FAIL! status=0x%02x\n",
3399 			__FUNCTION__, status);
3400 		_debug_dlfw_fail(d);
3401 		err = -1;
3402 		goto resume_tx;
3403 	}
3404 
3405 	/* 5.1. (Driver) Reset driver variables if needed */
3406 	hal->LastHMEBoxNum = 0;
3407 
3408 	/* 5.2. (Driver) Get FW version */
3409 	status = api->halmac_get_fw_version(mac, &fw_vesion);
3410 	if (status == HALMAC_RET_SUCCESS) {
3411 		hal->firmware_version = fw_vesion.version;
3412 		hal->firmware_sub_version = fw_vesion.sub_version;
3413 		hal->firmware_size = fwsize;
3414 	}
3415 
3416 resume_tx:
3417 	/* 6. Driver resume TX if needed */
3418 	/* ToDo */
3419 
3420 	if (err)
3421 		goto exit;
3422 
3423 	if (re_dl) {
3424 		enum halmac_trx_mode mode;
3425 
3426 		/* 7. Change reserved page size */
3427 		err = _cfg_drv_rsvd_pg_num(d);
3428 		if (err)
3429 			return -1;
3430 
3431 		/* 8. Init TRX Configuration */
3432 		mode = _choose_trx_mode(d);
3433 		status = api->halmac_init_trx_cfg(mac, mode);
3434 		if (HALMAC_RET_SUCCESS != status)
3435 			return -1;
3436 		_init_trx_cfg_drv(d);
3437 
3438 		/* 9. Config RX Aggregation */
3439 		err = rtw_halmac_rx_agg_switch(d, _TRUE);
3440 		if (err)
3441 			return -1;
3442 
3443 		/* 10. Send General Info */
3444 		err = _send_general_info(d);
3445 		if (err)
3446 			return -1;
3447 	}
3448 
3449 exit:
3450 	return err;
3451 }
3452 
init_mac_flow(struct dvobj_priv * d)3453 static int init_mac_flow(struct dvobj_priv *d)
3454 {
3455 	PADAPTER p;
3456 	struct hal_com_data *hal;
3457 	struct halmac_adapter *halmac;
3458 	struct halmac_api *api;
3459 	enum halmac_drv_rsvd_pg_num rsvd_page_number;
3460 	union halmac_wlan_addr hwa;
3461 	enum halmac_trx_mode trx_mode;
3462 	enum halmac_ret_status status;
3463 	u8 drv_rsvd_num;
3464 	u8 nettype;
3465 	int err, err_ret = -1;
3466 
3467 
3468 	p = dvobj_get_primary_adapter(d);
3469 	hal = GET_HAL_DATA(p);
3470 	halmac = dvobj_to_halmac(d);
3471 	api = HALMAC_GET_API(halmac);
3472 
3473 #ifdef CONFIG_SUPPORT_TRX_SHARED
3474 	status = api->halmac_cfg_rxff_expand_mode(halmac,
3475 						  _rtw_get_trx_share_mode(p));
3476 	if (status != HALMAC_RET_SUCCESS)
3477 		goto out;
3478 #endif
3479 
3480 #ifdef DBG_LA_MODE
3481 	if (dvobj_to_regsty(d)->la_mode_en) {
3482 		status = api->halmac_cfg_la_mode(halmac, HALMAC_LA_MODE_PARTIAL);
3483 		if (status != HALMAC_RET_SUCCESS) {
3484 			RTW_ERR("%s: Fail to enable LA mode!\n", __FUNCTION__);
3485 			goto out;
3486 		}
3487 		RTW_PRINT("%s: Enable LA mode OK.\n", __FUNCTION__);
3488 	}
3489 #endif
3490 
3491 	err = _cfg_drv_rsvd_pg_num(d);
3492 	if (err)
3493 		goto out;
3494 
3495 #ifdef CONFIG_USB_HCI
3496 	status = api->halmac_set_bulkout_num(halmac, d->RtNumOutPipes);
3497 	if (status != HALMAC_RET_SUCCESS)
3498 		goto out;
3499 #endif /* CONFIG_USB_HCI */
3500 
3501 	trx_mode = _choose_trx_mode(d);
3502 	status = api->halmac_init_mac_cfg(halmac, trx_mode);
3503 	if (status != HALMAC_RET_SUCCESS)
3504 		goto out;
3505 
3506 	/* Driver insert flow: Sync driver setting with register */
3507 	/* Sync driver RCR cache with register setting */
3508 	rtw_hal_get_hwreg(dvobj_get_primary_adapter(d), HW_VAR_RCR, NULL);
3509 
3510 #ifdef CONFIG_RTS_FULL_BW
3511 	err = rtw_halmac_set_rts_full_bw(d, _TRUE);
3512 	if (err)
3513 		RTW_WARN("%s: Fail to set RTS FULL BW mode\n", __FUNCTION__);
3514 #else
3515 	err = rtw_halmac_set_rts_full_bw(d, _FALSE);
3516 	if (err)
3517 		RTW_WARN("%s: Fail to disable RTS FULL BW mode\n", __FUNCTION__);
3518 #endif /* CONFIG_RTS_FULL_BW */
3519 
3520 	_init_trx_cfg_drv(d);
3521 	/* Driver inser flow end */
3522 
3523 	err = rtw_halmac_rx_agg_switch(d, _TRUE);
3524 	if (err)
3525 		goto out;
3526 
3527 	nettype = dvobj_to_regsty(d)->wireless_mode;
3528 	if (is_supported_vht(nettype) == _TRUE)
3529 		status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_AC);
3530 	else if (is_supported_ht(nettype) == _TRUE)
3531 		status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_N);
3532 	else if (IsSupportedTxOFDM(nettype) == _TRUE)
3533 		status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_G);
3534 	else
3535 		status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_B);
3536 	if (status != HALMAC_RET_SUCCESS)
3537 		goto out;
3538 
3539 	err_ret = 0;
3540 out:
3541 	return err_ret;
3542 }
3543 
_drv_enable_trx(struct dvobj_priv * d)3544 static int _drv_enable_trx(struct dvobj_priv *d)
3545 {
3546 	struct _ADAPTER *adapter;
3547 	u32 status;
3548 
3549 
3550 	adapter = dvobj_get_primary_adapter(d);
3551 	if (adapter->bup == _FALSE) {
3552 #ifdef CONFIG_NEW_NETDEV_HDL
3553 		status = rtw_mi_start_drv_threads(adapter);
3554 #else
3555 		status = rtw_start_drv_threads(adapter);
3556 #endif
3557 		if (status == _FAIL) {
3558 			RTW_ERR("%s: Start threads Failed!\n", __FUNCTION__);
3559 			return -1;
3560 		}
3561 	}
3562 
3563 	rtw_intf_start(adapter);
3564 
3565 	return 0;
3566 }
3567 
3568 /*
3569  * Notices:
3570  *	Make sure following information
3571  *	1. GET_HAL_RFPATH
3572  *	2. GET_HAL_DATA(dvobj_get_primary_adapter(d))->rfe_type
3573  *	3. GET_HAL_DATA(dvobj_get_primary_adapter(d))->PackageType
3574  *	4. dvobj_get_primary_adapter(d)->registrypriv.mp_mode
3575  *	are all ready before calling this function.
3576  */
_halmac_init_hal(struct dvobj_priv * d,u8 * fw,u32 fwsize)3577 static int _halmac_init_hal(struct dvobj_priv *d, u8 *fw, u32 fwsize)
3578 {
3579 	PADAPTER adapter;
3580 	struct halmac_adapter *halmac;
3581 	struct halmac_api *api;
3582 	enum halmac_ret_status status;
3583 	u32 ok;
3584 	u8 fw_ok = _FALSE;
3585 	int err, err_ret = -1;
3586 
3587 
3588 	adapter = dvobj_get_primary_adapter(d);
3589 	halmac = dvobj_to_halmac(d);
3590 	if (!halmac)
3591 		goto out;
3592 	api = HALMAC_GET_API(halmac);
3593 
3594 	/* StatePowerOff */
3595 
3596 	/* SKIP: halmac_init_adapter (Already done before) */
3597 
3598 	/* halmac_pre_Init_system_cfg */
3599 	/* halmac_mac_power_switch(on) */
3600 	/* halmac_Init_system_cfg */
3601 	ok = rtw_hal_power_on(adapter);
3602 	if (_FAIL == ok)
3603 		goto out;
3604 
3605 	/* StatePowerOn */
3606 
3607 	/* DownloadFW */
3608 	if (fw && fwsize) {
3609 		err = download_fw(d, fw, fwsize, 0);
3610 		if (err)
3611 			goto out;
3612 		fw_ok = _TRUE;
3613 	}
3614 
3615 	/* InitMACFlow */
3616 	err = init_mac_flow(d);
3617 	if (err)
3618 		goto out;
3619 
3620 	/* Driver insert flow: Enable TR/RX */
3621 	err = _drv_enable_trx(d);
3622 	if (err)
3623 		goto out;
3624 
3625 	/* halmac_send_general_info */
3626 	if (_TRUE == fw_ok) {
3627 		err = _send_general_info(d);
3628 		if (err)
3629 			goto out;
3630 	}
3631 
3632 	/* Init Phy parameter-MAC */
3633 	ok = rtw_hal_init_mac_register(adapter);
3634 	if (_FALSE == ok)
3635 		goto out;
3636 
3637 	/* StateMacInitialized */
3638 
3639 	/* halmac_cfg_drv_info */
3640 	err = rtw_halmac_config_rx_info(d, HALMAC_DRV_INFO_PHY_STATUS);
3641 	if (err)
3642 		goto out;
3643 
3644 	/* halmac_set_hw_value(HALMAC_HW_EN_BB_RF) */
3645 	/* Init BB, RF */
3646 	ok = rtw_hal_init_phy(adapter);
3647 	if (_FALSE == ok)
3648 		goto out;
3649 
3650 	status = api->halmac_init_interface_cfg(halmac);
3651 	if (status != HALMAC_RET_SUCCESS)
3652 		goto out;
3653 
3654 	/* SKIP: halmac_verify_platform_api */
3655 	/* SKIP: halmac_h2c_lb */
3656 
3657 	/* StateRxIdle */
3658 
3659 	err_ret = 0;
3660 out:
3661 	return err_ret;
3662 }
3663 
rtw_halmac_init_hal(struct dvobj_priv * d)3664 int rtw_halmac_init_hal(struct dvobj_priv *d)
3665 {
3666 	return _halmac_init_hal(d, NULL, 0);
3667 }
3668 
3669 /*
3670  * Notices:
3671  *	Make sure following information
3672  *	1. GET_HAL_RFPATH
3673  *	2. GET_HAL_DATA(dvobj_get_primary_adapter(d))->rfe_type
3674  *	3. GET_HAL_DATA(dvobj_get_primary_adapter(d))->PackageType
3675  *	4. dvobj_get_primary_adapter(d)->registrypriv.mp_mode
3676  *	are all ready before calling this function.
3677  */
rtw_halmac_init_hal_fw(struct dvobj_priv * d,u8 * fw,u32 fwsize)3678 int rtw_halmac_init_hal_fw(struct dvobj_priv *d, u8 *fw, u32 fwsize)
3679 {
3680 	return _halmac_init_hal(d, fw, fwsize);
3681 }
3682 
3683 /*
3684  * Notices:
3685  *	Make sure following information
3686  *	1. GET_HAL_RFPATH
3687  *	2. GET_HAL_DATA(dvobj_get_primary_adapter(d))->rfe_type
3688  *	3. GET_HAL_DATA(dvobj_get_primary_adapter(d))->PackageType
3689  *	4. dvobj_get_primary_adapter(d)->registrypriv.mp_mode
3690  *	are all ready before calling this function.
3691  */
rtw_halmac_init_hal_fw_file(struct dvobj_priv * d,u8 * fwpath)3692 int rtw_halmac_init_hal_fw_file(struct dvobj_priv *d, u8 *fwpath)
3693 {
3694 	u8 *fw = NULL;
3695 	u32 fwmaxsize = 0, size = 0;
3696 	int err = 0;
3697 
3698 
3699 	err = rtw_halmac_get_fw_max_size(d, &fwmaxsize);
3700 	if (err) {
3701 		RTW_ERR("%s: Fail to get Firmware MAX size(err=%d)\n", __FUNCTION__, err);
3702 		return -1;
3703 	}
3704 
3705 	fw = rtw_zmalloc(fwmaxsize);
3706 	if (!fw)
3707 		return -1;
3708 
3709 	size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
3710 	if (!size) {
3711 		err = -1;
3712 		goto exit;
3713 	}
3714 
3715 	err = _halmac_init_hal(d, fw, size);
3716 
3717 exit:
3718 	rtw_mfree(fw, fwmaxsize);
3719 	/*fw = NULL;*/
3720 
3721 	return err;
3722 }
3723 
rtw_halmac_deinit_hal(struct dvobj_priv * d)3724 int rtw_halmac_deinit_hal(struct dvobj_priv *d)
3725 {
3726 	PADAPTER adapter;
3727 	struct halmac_adapter *halmac;
3728 	struct halmac_api *api;
3729 	enum halmac_ret_status status;
3730 	int err = -1;
3731 
3732 
3733 	adapter = dvobj_get_primary_adapter(d);
3734 	halmac = dvobj_to_halmac(d);
3735 	if (!halmac)
3736 		goto out;
3737 	api = HALMAC_GET_API(halmac);
3738 
3739 	status = api->halmac_deinit_interface_cfg(halmac);
3740 	if (status != HALMAC_RET_SUCCESS)
3741 		goto out;
3742 
3743 	rtw_hal_power_off(adapter);
3744 
3745 	err = 0;
3746 out:
3747 	return err;
3748 }
3749 
rtw_halmac_self_verify(struct dvobj_priv * d)3750 int rtw_halmac_self_verify(struct dvobj_priv *d)
3751 {
3752 	struct halmac_adapter *mac;
3753 	struct halmac_api *api;
3754 	enum halmac_ret_status status;
3755 	int err = -1;
3756 
3757 
3758 	mac = dvobj_to_halmac(d);
3759 	api = HALMAC_GET_API(mac);
3760 
3761 	status = api->halmac_verify_platform_api(mac);
3762 	if (status != HALMAC_RET_SUCCESS)
3763 		goto out;
3764 
3765 	status = api->halmac_h2c_lb(mac);
3766 	if (status != HALMAC_RET_SUCCESS)
3767 		goto out;
3768 
3769 	err = 0;
3770 out:
3771 	return err;
3772 }
3773 
rtw_halmac_txfifo_is_empty(struct dvobj_priv * d)3774 static u8 rtw_halmac_txfifo_is_empty(struct dvobj_priv *d)
3775 {
3776 	struct halmac_adapter *mac;
3777 	struct halmac_api *api;
3778 	enum halmac_ret_status status;
3779 	u32 chk_num = 10;
3780 	u8 rst = _FALSE;
3781 
3782 
3783 	mac = dvobj_to_halmac(d);
3784 	api = HALMAC_GET_API(mac);
3785 
3786 	status = api->halmac_txfifo_is_empty(mac, chk_num);
3787 	if (status == HALMAC_RET_SUCCESS)
3788 		rst = _TRUE;
3789 
3790 	return rst;
3791 }
3792 
3793 /**
3794  * rtw_halmac_txfifo_wait_empty() - Wait TX FIFO to be emtpy
3795  * @d:		struct dvobj_priv*
3796  * @timeout:	time limit of wait, unit is ms
3797  *		0 for no limit
3798  *
3799  * Wait TX FIFO to be emtpy.
3800  *
3801  * Return 0 for TX FIFO is empty, otherwise not empty.
3802  */
rtw_halmac_txfifo_wait_empty(struct dvobj_priv * d,u32 timeout)3803 int rtw_halmac_txfifo_wait_empty(struct dvobj_priv *d, u32 timeout)
3804 {
3805 	struct _ADAPTER *a;
3806 	u8 empty = _FALSE;
3807 	u32 cnt = 0;
3808 	systime start_time = 0;
3809 	u32 pass_time; /* ms */
3810 
3811 
3812 	a = dvobj_get_primary_adapter(d);
3813 	start_time = rtw_get_current_time();
3814 
3815 	do {
3816 		cnt++;
3817 		empty = rtw_halmac_txfifo_is_empty(d);
3818 		if (empty == _TRUE)
3819 			break;
3820 
3821 		if (timeout) {
3822 			pass_time = rtw_get_passing_time_ms(start_time);
3823 			if (pass_time > timeout)
3824 				break;
3825 		}
3826 		if (RTW_CANNOT_IO(a)) {
3827 			RTW_WARN("%s: Interrupted by I/O forbiden!\n", __FUNCTION__);
3828 			break;
3829 		}
3830 
3831 		rtw_msleep_os(2);
3832 	} while (1);
3833 
3834 	if (empty == _FALSE) {
3835 #ifdef CONFIG_RTW_DEBUG
3836 		u16 dbg_reg[] = {0x210, 0x230, 0x234, 0x238, 0x23C, 0x240,
3837 				 0x418, 0x10FC, 0x10F8, 0x11F4, 0x11F8};
3838 		u8 i;
3839 		u32 val;
3840 
3841 		if (!RTW_CANNOT_IO(a)) {
3842 			for (i = 0; i < ARRAY_SIZE(dbg_reg); i++) {
3843 				val = rtw_read32(a, dbg_reg[i]);
3844 				RTW_ERR("REG_%X:0x%08x\n", dbg_reg[i], val);
3845 			}
3846 		}
3847 #endif /* CONFIG_RTW_DEBUG */
3848 
3849 		RTW_ERR("%s: Fail to wait txfifo empty!(cnt=%d)\n",
3850 			__FUNCTION__, cnt);
3851 		return -1;
3852 	}
3853 
3854 	return 0;
3855 }
3856 
_fw_mem_drv2halmac(enum fw_mem mem,u8 tx_stop)3857 static enum halmac_dlfw_mem _fw_mem_drv2halmac(enum fw_mem mem, u8 tx_stop)
3858 {
3859 	enum halmac_dlfw_mem mem_halmac = HALMAC_DLFW_MEM_UNDEFINE;
3860 
3861 
3862 	switch (mem) {
3863 	case FW_EMEM:
3864 		if (tx_stop == _FALSE)
3865 			mem_halmac = HALMAC_DLFW_MEM_EMEM_RSVD_PG;
3866 		else
3867 			mem_halmac = HALMAC_DLFW_MEM_EMEM;
3868 		break;
3869 
3870 	case FW_IMEM:
3871 	case FW_DMEM:
3872 		mem_halmac = HALMAC_DLFW_MEM_UNDEFINE;
3873 		break;
3874 	}
3875 
3876 	return mem_halmac;
3877 }
3878 
rtw_halmac_dlfw_mem(struct dvobj_priv * d,u8 * fw,u32 fwsize,enum fw_mem mem)3879 int rtw_halmac_dlfw_mem(struct dvobj_priv *d, u8 *fw, u32 fwsize, enum fw_mem mem)
3880 {
3881 	struct halmac_adapter *mac;
3882 	struct halmac_api *api;
3883 	enum halmac_ret_status status;
3884 	enum halmac_dlfw_mem dlfw_mem;
3885 	u8 tx_stop = _FALSE;
3886 	u32 chk_timeout = 2000; /* unit: ms */
3887 	int err = 0;
3888 
3889 
3890 	mac = dvobj_to_halmac(d);
3891 	api = HALMAC_GET_API(mac);
3892 
3893 	if ((!fw) || (!fwsize))
3894 		return -1;
3895 
3896 #ifndef RTW_HALMAC_DLFW_MEM_NO_STOP_TX
3897 	/* 1. Driver Stop Tx */
3898 	/* ToDo */
3899 
3900 	/* 2. Driver Check Tx FIFO is empty */
3901 	err = rtw_halmac_txfifo_wait_empty(d, chk_timeout);
3902 	if (err)
3903 		tx_stop = _FALSE;
3904 	else
3905 		tx_stop = _TRUE;
3906 #endif /* !RTW_HALMAC_DLFW_MEM_NO_STOP_TX */
3907 
3908 	/* 3. Download Firmware MEM */
3909 	dlfw_mem = _fw_mem_drv2halmac(mem, tx_stop);
3910 	if (dlfw_mem == HALMAC_DLFW_MEM_UNDEFINE) {
3911 		err = -1;
3912 		goto resume_tx;
3913 	}
3914 	status = api->halmac_free_download_firmware(mac, dlfw_mem, fw, fwsize);
3915 	if (status != HALMAC_RET_SUCCESS) {
3916 		RTW_ERR("%s: halmac_free_download_firmware fail(err=0x%x)\n",
3917 			__FUNCTION__, status);
3918 		err = -1;
3919 		goto resume_tx;
3920 	}
3921 
3922 resume_tx:
3923 #ifndef RTW_HALMAC_DLFW_MEM_NO_STOP_TX
3924 	/* 4. Driver resume TX if needed */
3925 	/* ToDo */
3926 #endif /* !RTW_HALMAC_DLFW_MEM_NO_STOP_TX */
3927 
3928 	return err;
3929 }
3930 
rtw_halmac_dlfw_mem_from_file(struct dvobj_priv * d,u8 * fwpath,enum fw_mem mem)3931 int rtw_halmac_dlfw_mem_from_file(struct dvobj_priv *d, u8 *fwpath, enum fw_mem mem)
3932 {
3933 	u8 *fw = NULL;
3934 	u32 fwmaxsize = 0, size = 0;
3935 	int err = 0;
3936 
3937 
3938 	err = rtw_halmac_get_fw_max_size(d, &fwmaxsize);
3939 	if (err) {
3940 		RTW_ERR("%s: Fail to get Firmware MAX size(err=%d)\n", __FUNCTION__, err);
3941 		return -1;
3942 	}
3943 
3944 	fw = rtw_zmalloc(fwmaxsize);
3945 	if (!fw)
3946 		return -1;
3947 
3948 	size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
3949 	if (size)
3950 		err = rtw_halmac_dlfw_mem(d, fw, size, mem);
3951 	else
3952 		err = -1;
3953 
3954 	rtw_mfree(fw, fwmaxsize);
3955 	/*fw = NULL;*/
3956 
3957 	return err;
3958 }
3959 
3960 /*
3961  * Return:
3962  *	0	Success
3963  *	-22	Invalid arguemnt
3964  */
rtw_halmac_dlfw(struct dvobj_priv * d,u8 * fw,u32 fwsize)3965 int rtw_halmac_dlfw(struct dvobj_priv *d, u8 *fw, u32 fwsize)
3966 {
3967 	PADAPTER adapter;
3968 	enum halmac_ret_status status;
3969 	u32 ok;
3970 	int err, err_ret = -1;
3971 
3972 
3973 	if (!fw || !fwsize)
3974 		return -22;
3975 
3976 	adapter = dvobj_get_primary_adapter(d);
3977 
3978 	/* re-download firmware */
3979 	if (rtw_is_hw_init_completed(adapter))
3980 		return download_fw(d, fw, fwsize, 1);
3981 
3982 	/* Download firmware before hal init */
3983 	/* Power on, download firmware and init mac */
3984 	ok = rtw_hal_power_on(adapter);
3985 	if (_FAIL == ok)
3986 		goto out;
3987 
3988 	err = download_fw(d, fw, fwsize, 0);
3989 	if (err) {
3990 		err_ret = err;
3991 		goto out;
3992 	}
3993 
3994 	err = init_mac_flow(d);
3995 	if (err)
3996 		goto out;
3997 
3998 	err = _send_general_info(d);
3999 	if (err)
4000 		goto out;
4001 
4002 	err_ret = 0;
4003 
4004 out:
4005 	return err_ret;
4006 }
4007 
rtw_halmac_dlfw_from_file(struct dvobj_priv * d,u8 * fwpath)4008 int rtw_halmac_dlfw_from_file(struct dvobj_priv *d, u8 *fwpath)
4009 {
4010 	u8 *fw = NULL;
4011 	u32 fwmaxsize = 0, size = 0;
4012 	int err = 0;
4013 
4014 
4015 	err = rtw_halmac_get_fw_max_size(d, &fwmaxsize);
4016 	if (err) {
4017 		RTW_ERR("%s: Fail to get Firmware MAX size(err=%d)\n", __FUNCTION__, err);
4018 		return -1;
4019 	}
4020 
4021 	fw = rtw_zmalloc(fwmaxsize);
4022 	if (!fw)
4023 		return -1;
4024 
4025 	size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
4026 	if (size)
4027 		err = rtw_halmac_dlfw(d, fw, size);
4028 	else
4029 		err = -1;
4030 
4031 	rtw_mfree(fw, fwmaxsize);
4032 	/*fw = NULL;*/
4033 
4034 	return err;
4035 }
4036 
4037 /*
4038  * Description:
4039  *	Power on/off BB/RF domain.
4040  *
4041  * Parameters:
4042  *	enable	_TRUE/_FALSE for power on/off
4043  *
4044  * Return:
4045  *	0	Success
4046  *	others	Fail
4047  */
rtw_halmac_phy_power_switch(struct dvobj_priv * d,u8 enable)4048 int rtw_halmac_phy_power_switch(struct dvobj_priv *d, u8 enable)
4049 {
4050 	PADAPTER adapter;
4051 	struct halmac_adapter *halmac;
4052 	struct halmac_api *api;
4053 	enum halmac_ret_status status;
4054 	u8 on;
4055 
4056 
4057 	adapter = dvobj_get_primary_adapter(d);
4058 	halmac = dvobj_to_halmac(d);
4059 	if (!halmac)
4060 		return -1;
4061 	api = HALMAC_GET_API(halmac);
4062 	on = (enable == _TRUE) ? 1 : 0;
4063 
4064 	status = api->halmac_set_hw_value(halmac, HALMAC_HW_EN_BB_RF, &on);
4065 	if (status != HALMAC_RET_SUCCESS)
4066 		return -1;
4067 
4068 	return 0;
4069 }
4070 
_is_fw_read_cmd_down(PADAPTER adapter,u8 msgbox_num)4071 static u8 _is_fw_read_cmd_down(PADAPTER adapter, u8 msgbox_num)
4072 {
4073 	u8 read_down = _FALSE;
4074 	int retry_cnts = 100;
4075 	u8 valid;
4076 
4077 	do {
4078 		valid = rtw_read8(adapter, REG_HMETFR) & BIT(msgbox_num);
4079 		if (0 == valid)
4080 			read_down = _TRUE;
4081 		else
4082 			rtw_msleep_os(1);
4083 	} while ((!read_down) && (retry_cnts--));
4084 
4085 	if (_FALSE == read_down)
4086 		RTW_WARN("%s, reg_1cc(%x), msg_box(%d)...\n", __func__, rtw_read8(adapter, REG_HMETFR), msgbox_num);
4087 
4088 	return read_down;
4089 }
4090 
4091 /**
4092  * rtw_halmac_send_h2c() - Send H2C to firmware
4093  * @d:		struct dvobj_priv*
4094  * @h2c:	H2C data buffer, suppose to be 8 bytes
4095  *
4096  * Send H2C to firmware by message box register(0x1D0~0x1D3 & 0x1F0~0x1F3).
4097  *
4098  * Assume firmware be ready to accept H2C here, please check
4099  * (hal->bFWReady == _TRUE) before call this function or make sure firmware is
4100  * ready.
4101  *
4102  * Return: 0 if process OK, otherwise fail to send this H2C.
4103  */
rtw_halmac_send_h2c(struct dvobj_priv * d,u8 * h2c)4104 int rtw_halmac_send_h2c(struct dvobj_priv *d, u8 *h2c)
4105 {
4106 	PADAPTER adapter = dvobj_get_primary_adapter(d);
4107 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
4108 	u8 h2c_box_num = 0;
4109 	u32 msgbox_addr = 0;
4110 	u32 msgbox_ex_addr = 0;
4111 	u32 h2c_cmd = 0;
4112 	u32 h2c_cmd_ex = 0;
4113 	int err = -1;
4114 
4115 
4116 	if (!h2c) {
4117 		RTW_WARN("%s: pbuf is NULL\n", __FUNCTION__);
4118 		return err;
4119 	}
4120 
4121 	if (rtw_is_surprise_removed(adapter)) {
4122 		RTW_WARN("%s: surprise removed\n", __FUNCTION__);
4123 		return err;
4124 	}
4125 
4126 	_enter_critical_mutex(&d->h2c_fwcmd_mutex, NULL);
4127 
4128 	/* pay attention to if race condition happened in H2C cmd setting */
4129 	h2c_box_num = hal->LastHMEBoxNum;
4130 
4131 	if (!_is_fw_read_cmd_down(adapter, h2c_box_num)) {
4132 		RTW_WARN(" fw read cmd failed...\n");
4133 #ifdef DBG_CONFIG_ERROR_DETECT
4134 		hal->srestpriv.self_dect_fw = _TRUE;
4135 		hal->srestpriv.self_dect_fw_cnt++;
4136 #endif /* DBG_CONFIG_ERROR_DETECT */
4137 		goto exit;
4138 	}
4139 
4140 	/* Write Ext command (byte 4~7) */
4141 	msgbox_ex_addr = REG_HMEBOX_E0 + (h2c_box_num * EX_MESSAGE_BOX_SIZE);
4142 	_rtw_memcpy((u8 *)(&h2c_cmd_ex), h2c + 4, EX_MESSAGE_BOX_SIZE);
4143 	h2c_cmd_ex = le32_to_cpu(h2c_cmd_ex);
4144 	rtw_write32(adapter, msgbox_ex_addr, h2c_cmd_ex);
4145 
4146 	/* Write command (byte 0~3) */
4147 	msgbox_addr = REG_HMEBOX0 + (h2c_box_num * MESSAGE_BOX_SIZE);
4148 	_rtw_memcpy((u8 *)(&h2c_cmd), h2c, 4);
4149 	h2c_cmd = le32_to_cpu(h2c_cmd);
4150 	rtw_write32(adapter, msgbox_addr, h2c_cmd);
4151 
4152 	/* update last msg box number */
4153 	hal->LastHMEBoxNum = (h2c_box_num + 1) % MAX_H2C_BOX_NUMS;
4154 	err = 0;
4155 
4156 #ifdef DBG_H2C_CONTENT
4157 	RTW_INFO_DUMP("[H2C] - ", h2c, RTW_HALMAC_H2C_MAX_SIZE);
4158 #endif
4159 exit:
4160 	_exit_critical_mutex(&d->h2c_fwcmd_mutex, NULL);
4161 	return err;
4162 }
4163 
4164 /**
4165  * rtw_halmac_c2h_handle() - Handle C2H for HALMAC
4166  * @d:		struct dvobj_priv*
4167  * @c2h:	Full C2H packet, including RX description and payload
4168  * @size:	Size(byte) of c2h
4169  *
4170  * Send C2H packet to HALMAC to process C2H packets, and the expected C2H ID is
4171  * 0xFF. This function won't have any I/O, so caller doesn't have to call it in
4172  * I/O safe place(ex. command thread).
4173  *
4174  * Please sure doesn't call this function in the same thread as someone is
4175  * waiting HALMAC C2H ack, otherwise there is a deadlock happen.
4176  *
4177  * Return: 0 if process OK, otherwise no action for this C2H.
4178  */
rtw_halmac_c2h_handle(struct dvobj_priv * d,u8 * c2h,u32 size)4179 int rtw_halmac_c2h_handle(struct dvobj_priv *d, u8 *c2h, u32 size)
4180 {
4181 	struct halmac_adapter *mac;
4182 	struct halmac_api *api;
4183 	enum halmac_ret_status status;
4184 #ifdef RTW_HALMAC_FILTER_DRV_C2H
4185 	u32 desc_size = 0;
4186 	u8 *c2h_data;
4187 	u8 sub;
4188 #endif /* RTW_HALMAC_FILTER_DRV_C2H */
4189 
4190 
4191 	mac = dvobj_to_halmac(d);
4192 	api = HALMAC_GET_API(mac);
4193 
4194 #ifdef RTW_HALMAC_FILTER_DRV_C2H
4195 	status = api->halmac_get_hw_value(mac, HALMAC_HW_RX_DESC_SIZE,
4196 					  &desc_size);
4197 	if (status != HALMAC_RET_SUCCESS) {
4198 		RTW_ERR("%s: fail to get rx desc size!\n", __FUNCTION__);
4199 		goto skip_filter;
4200 	}
4201 
4202 	c2h_data = c2h + desc_size;
4203 	sub = C2H_HDR_GET_C2H_SUB_CMD_ID(c2h_data);
4204 	switch (sub) {
4205 	case C2H_SUB_CMD_ID_C2H_PKT_FTM_DBG:
4206 	case C2H_SUB_CMD_ID_C2H_PKT_FTM_2_DBG:
4207 	case C2H_SUB_CMD_ID_C2H_PKT_FTM_3_DBG:
4208 	case C2H_SUB_CMD_ID_C2H_PKT_FTM_4_DBG:
4209 	case C2H_SUB_CMD_ID_FTMACKRPT_HDL_DBG:
4210 	case C2H_SUB_CMD_ID_FTMC2H_RPT:
4211 	case C2H_SUB_CMD_ID_DRVFTMC2H_RPT:
4212 	case C2H_SUB_CMD_ID_C2H_PKT_FTM_5_DBG:
4213 	case C2H_SUB_CMD_ID_CCX_RPT:
4214 	case C2H_SUB_CMD_ID_C2H_PKT_NAN_RPT:
4215 	case C2H_SUB_CMD_ID_C2H_PKT_ATM_RPT:
4216 	case C2H_SUB_CMD_ID_C2H_PKT_SCC_CSA_RPT:
4217 	case C2H_SUB_CMD_ID_C2H_PKT_FW_STATUS_NOTIFY:
4218 	case C2H_SUB_CMD_ID_C2H_PKT_FTMSESSION_END:
4219 	case C2H_SUB_CMD_ID_C2H_PKT_DETECT_THERMAL:
4220 	case C2H_SUB_CMD_ID_FW_FWCTRL_RPT:
4221 	case C2H_SUB_CMD_ID_SCAN_CH_NOTIFY:
4222 	case C2H_SUB_CMD_ID_FW_TBTT_RPT:
4223 	case C2H_SUB_CMD_ID_BCN_OFFLOAD:
4224 	case C2H_SUB_CMD_ID_FW_DBG_MSG:
4225 		RTW_PRINT("%s: unhandled C2H, id=0xFF subid=0x%x len=%u\n",
4226 			  __FUNCTION__, sub, C2H_HDR_GET_LEN(c2h_data));
4227 		RTW_PRINT_DUMP("C2H: ", c2h_data, size - desc_size);
4228 		return 0;
4229 	}
4230 
4231 skip_filter:
4232 #endif /* RTW_HALMAC_FILTER_DRV_C2H */
4233 
4234 	status = api->halmac_get_c2h_info(mac, c2h, size);
4235 	if (HALMAC_RET_SUCCESS != status)
4236 		return -1;
4237 
4238 	return 0;
4239 }
4240 
rtw_halmac_get_available_efuse_size(struct dvobj_priv * d,u32 * size)4241 int rtw_halmac_get_available_efuse_size(struct dvobj_priv *d, u32 *size)
4242 {
4243 	struct halmac_adapter *mac;
4244 	struct halmac_api *api;
4245 	enum halmac_ret_status status;
4246 	u32 val;
4247 
4248 
4249 	mac = dvobj_to_halmac(d);
4250 	api = HALMAC_GET_API(mac);
4251 
4252 	status = api->halmac_get_efuse_available_size(mac, &val);
4253 	if (HALMAC_RET_SUCCESS != status)
4254 		return -1;
4255 
4256 	*size = val;
4257 	return 0;
4258 }
4259 
rtw_halmac_get_physical_efuse_size(struct dvobj_priv * d,u32 * size)4260 int rtw_halmac_get_physical_efuse_size(struct dvobj_priv *d, u32 *size)
4261 {
4262 	struct halmac_adapter *mac;
4263 	struct halmac_api *api;
4264 	enum halmac_ret_status status;
4265 	u32 val;
4266 
4267 
4268 	mac = dvobj_to_halmac(d);
4269 	api = HALMAC_GET_API(mac);
4270 
4271 	status = api->halmac_get_efuse_size(mac, &val);
4272 	if (HALMAC_RET_SUCCESS != status)
4273 		return -1;
4274 
4275 	*size = val;
4276 	return 0;
4277 }
4278 
rtw_halmac_read_physical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size)4279 int rtw_halmac_read_physical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size)
4280 {
4281 	struct halmac_adapter *mac;
4282 	struct halmac_api *api;
4283 	enum halmac_ret_status status;
4284 	enum halmac_feature_id id;
4285 	int ret;
4286 
4287 
4288 	mac = dvobj_to_halmac(d);
4289 	api = HALMAC_GET_API(mac);
4290 	id = HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE;
4291 
4292 	ret = init_halmac_event(d, id, map, size);
4293 	if (ret)
4294 		return -1;
4295 
4296 	status = api->halmac_dump_efuse_map(mac, HALMAC_EFUSE_R_DRV);
4297 	if (HALMAC_RET_SUCCESS != status) {
4298 		free_halmac_event(d, id);
4299 		return -1;
4300 	}
4301 
4302 	ret = wait_halmac_event(d, id);
4303 	if (ret)
4304 		return -1;
4305 
4306 	return 0;
4307 }
4308 
rtw_halmac_read_physical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)4309 int rtw_halmac_read_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4310 {
4311 	struct halmac_adapter *mac;
4312 	struct halmac_api *api;
4313 	enum halmac_ret_status status;
4314 	u8 v;
4315 	u32 i;
4316 	u8 *efuse = NULL;
4317 	u32 size = 0;
4318 	int err = 0;
4319 
4320 
4321 	mac = dvobj_to_halmac(d);
4322 	api = HALMAC_GET_API(mac);
4323 
4324 	if (api->halmac_read_efuse) {
4325 		for (i = 0; i < cnt; i++) {
4326 			status = api->halmac_read_efuse(mac, offset + i, &v);
4327 			if (HALMAC_RET_SUCCESS != status)
4328 				return -1;
4329 			data[i] = v;
4330 		}
4331 	} else {
4332 		err = rtw_halmac_get_physical_efuse_size(d, &size);
4333 		if (err)
4334 			return -1;
4335 
4336 		efuse = rtw_zmalloc(size);
4337 		if (!efuse)
4338 			return -1;
4339 
4340 		err = rtw_halmac_read_physical_efuse_map(d, efuse, size);
4341 		if (err)
4342 			err = -1;
4343 		else
4344 			_rtw_memcpy(data, efuse + offset, cnt);
4345 
4346 		rtw_mfree(efuse, size);
4347 	}
4348 
4349 	return err;
4350 }
4351 
rtw_halmac_write_physical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)4352 int rtw_halmac_write_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4353 {
4354 	struct halmac_adapter *mac;
4355 	struct halmac_api *api;
4356 	enum halmac_ret_status status;
4357 	u32 i;
4358 
4359 
4360 	mac = dvobj_to_halmac(d);
4361 	api = HALMAC_GET_API(mac);
4362 
4363 	if (api->halmac_write_efuse == NULL)
4364 		return -1;
4365 
4366 	for (i = 0; i < cnt; i++) {
4367 		status = api->halmac_write_efuse(mac, offset + i, data[i]);
4368 		if (HALMAC_RET_SUCCESS != status)
4369 			return -1;
4370 	}
4371 
4372 	return 0;
4373 }
4374 
rtw_halmac_get_logical_efuse_size(struct dvobj_priv * d,u32 * size)4375 int rtw_halmac_get_logical_efuse_size(struct dvobj_priv *d, u32 *size)
4376 {
4377 	struct halmac_adapter *mac;
4378 	struct halmac_api *api;
4379 	enum halmac_ret_status status;
4380 	u32 val;
4381 
4382 
4383 	mac = dvobj_to_halmac(d);
4384 	api = HALMAC_GET_API(mac);
4385 
4386 	status = api->halmac_get_logical_efuse_size(mac, &val);
4387 	if (HALMAC_RET_SUCCESS != status)
4388 		return -1;
4389 
4390 	*size = val;
4391 	return 0;
4392 }
4393 
rtw_halmac_read_logical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size,u8 * maskmap,u32 masksize)4394 int rtw_halmac_read_logical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size, u8 *maskmap, u32 masksize)
4395 {
4396 	struct halmac_adapter *mac;
4397 	struct halmac_api *api;
4398 	enum halmac_ret_status status;
4399 	enum halmac_feature_id id;
4400 	int ret;
4401 
4402 
4403 	mac = dvobj_to_halmac(d);
4404 	api = HALMAC_GET_API(mac);
4405 	id = HALMAC_FEATURE_DUMP_LOGICAL_EFUSE;
4406 
4407 	ret = init_halmac_event(d, id, map, size);
4408 	if (ret)
4409 		return -1;
4410 
4411 	status = api->halmac_dump_logical_efuse_map(mac, HALMAC_EFUSE_R_DRV);
4412 	if (HALMAC_RET_SUCCESS != status) {
4413 		free_halmac_event(d, id);
4414 		return -1;
4415 	}
4416 
4417 	ret = wait_halmac_event(d, id);
4418 	if (ret)
4419 		return -1;
4420 
4421 	if (maskmap && masksize) {
4422 		struct halmac_pg_efuse_info pginfo;
4423 
4424 		pginfo.efuse_map = map;
4425 		pginfo.efuse_map_size = size;
4426 		pginfo.efuse_mask = maskmap;
4427 		pginfo.efuse_mask_size = masksize;
4428 
4429 		status = api->halmac_mask_logical_efuse(mac, &pginfo);
4430 		if (status != HALMAC_RET_SUCCESS)
4431 			RTW_WARN("%s: mask logical efuse FAIL!\n", __FUNCTION__);
4432 	}
4433 
4434 	return 0;
4435 }
4436 
rtw_halmac_write_logical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size,u8 * maskmap,u32 masksize)4437 int rtw_halmac_write_logical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size, u8 *maskmap, u32 masksize)
4438 {
4439 	struct halmac_adapter *mac;
4440 	struct halmac_api *api;
4441 	struct halmac_pg_efuse_info pginfo;
4442 	enum halmac_ret_status status;
4443 
4444 
4445 	mac = dvobj_to_halmac(d);
4446 	api = HALMAC_GET_API(mac);
4447 
4448 	pginfo.efuse_map = map;
4449 	pginfo.efuse_map_size = size;
4450 	pginfo.efuse_mask = maskmap;
4451 	pginfo.efuse_mask_size = masksize;
4452 
4453 	status = api->halmac_pg_efuse_by_map(mac, &pginfo, HALMAC_EFUSE_R_AUTO);
4454 	if (HALMAC_RET_SUCCESS != status)
4455 		return -1;
4456 
4457 	return 0;
4458 }
4459 
rtw_halmac_read_logical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)4460 int rtw_halmac_read_logical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4461 {
4462 	struct halmac_adapter *mac;
4463 	struct halmac_api *api;
4464 	enum halmac_ret_status status;
4465 	u8 v;
4466 	u32 i;
4467 
4468 
4469 	mac = dvobj_to_halmac(d);
4470 	api = HALMAC_GET_API(mac);
4471 
4472 	for (i = 0; i < cnt; i++) {
4473 		status = api->halmac_read_logical_efuse(mac, offset + i, &v);
4474 		if (HALMAC_RET_SUCCESS != status)
4475 			return -1;
4476 		data[i] = v;
4477 	}
4478 
4479 	return 0;
4480 }
4481 
rtw_halmac_write_logical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)4482 int rtw_halmac_write_logical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4483 {
4484 	struct halmac_adapter *mac;
4485 	struct halmac_api *api;
4486 	enum halmac_ret_status status;
4487 	u32 i;
4488 
4489 
4490 	mac = dvobj_to_halmac(d);
4491 	api = HALMAC_GET_API(mac);
4492 
4493 	for (i = 0; i < cnt; i++) {
4494 		status = api->halmac_write_logical_efuse(mac, offset + i, data[i]);
4495 		if (HALMAC_RET_SUCCESS != status)
4496 			return -1;
4497 	}
4498 
4499 	return 0;
4500 }
4501 
rtw_halmac_write_bt_physical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)4502 int rtw_halmac_write_bt_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4503 {
4504 	struct halmac_adapter *mac;
4505 	struct halmac_api *api;
4506 	enum halmac_ret_status status;
4507 	u32 i;
4508 	u8 bank = 1;
4509 
4510 
4511 	mac = dvobj_to_halmac(d);
4512 	api = HALMAC_GET_API(mac);
4513 
4514 	for (i = 0; i < cnt; i++) {
4515 		status = api->halmac_write_efuse_bt(mac, offset + i, data[i], bank);
4516 		if (HALMAC_RET_SUCCESS != status) {
4517 			printk("%s: halmac_write_efuse_bt status = %d\n", __FUNCTION__, status);
4518 			return -1;
4519 		}
4520 	}
4521 	printk("%s: halmac_write_efuse_bt status = HALMAC_RET_SUCCESS %d\n", __FUNCTION__, status);
4522 	return 0;
4523 }
4524 
4525 
rtw_halmac_read_bt_physical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size)4526 int rtw_halmac_read_bt_physical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size)
4527 {
4528 	struct halmac_adapter *mac;
4529 	struct halmac_api *api;
4530 	enum halmac_ret_status status;
4531 	int bank = 1;
4532 
4533 
4534 	mac = dvobj_to_halmac(d);
4535 	api = HALMAC_GET_API(mac);
4536 
4537 	status = api->halmac_dump_efuse_map_bt(mac, bank, size, map);
4538 	if (HALMAC_RET_SUCCESS != status) {
4539 		printk("%s: halmac_dump_efuse_map_bt fail!\n", __FUNCTION__);
4540 		return -1;
4541 	}
4542 
4543 	printk("%s: OK!\n", __FUNCTION__);
4544 
4545 	return 0;
4546 }
4547 
_fifo_sel_drv2halmac(u8 fifo_sel)4548 static enum hal_fifo_sel _fifo_sel_drv2halmac(u8 fifo_sel)
4549 {
4550 	switch (fifo_sel) {
4551 	case 0:
4552 		return HAL_FIFO_SEL_TX;
4553 	case 1:
4554 		return HAL_FIFO_SEL_RX;
4555 	case 2:
4556 		return HAL_FIFO_SEL_RSVD_PAGE;
4557 	case 3:
4558 		return HAL_FIFO_SEL_REPORT;
4559 	case 4:
4560 		return HAL_FIFO_SEL_LLT;
4561 	case 5:
4562 		return HAL_FIFO_SEL_RXBUF_FW;
4563 	}
4564 
4565 	return HAL_FIFO_SEL_RSVD_PAGE;
4566 }
4567 
4568 /*#define CONFIG_HALMAC_FIFO_DUMP*/
rtw_halmac_dump_fifo(struct dvobj_priv * d,u8 fifo_sel,u32 addr,u32 size,u8 * buffer)4569 int rtw_halmac_dump_fifo(struct dvobj_priv *d, u8 fifo_sel, u32 addr, u32 size, u8 *buffer)
4570 {
4571 	struct halmac_adapter *mac;
4572 	struct halmac_api *api;
4573 	enum hal_fifo_sel halmac_fifo_sel;
4574 	enum halmac_ret_status status;
4575 	u8 *pfifo_map = NULL;
4576 	u32 fifo_size = 0;
4577 	s8 ret = 0;/* 0:success, -1:error */
4578 	u8 mem_created = _FALSE;
4579 
4580 
4581 	mac = dvobj_to_halmac(d);
4582 	api = HALMAC_GET_API(mac);
4583 
4584 	if ((size != 0) && (buffer == NULL))
4585 		return -1;
4586 
4587 	halmac_fifo_sel = _fifo_sel_drv2halmac(fifo_sel);
4588 
4589 	if ((size) && (buffer)) {
4590 		pfifo_map = buffer;
4591 		fifo_size = size;
4592 	} else {
4593 		fifo_size = api->halmac_get_fifo_size(mac, halmac_fifo_sel);
4594 
4595 		if (fifo_size)
4596 			pfifo_map = rtw_zvmalloc(fifo_size);
4597 		if (pfifo_map == NULL)
4598 			return -1;
4599 		mem_created = _TRUE;
4600 	}
4601 
4602 	status = api->halmac_dump_fifo(mac, halmac_fifo_sel, addr, fifo_size, pfifo_map);
4603 	if (HALMAC_RET_SUCCESS != status) {
4604 		ret = -1;
4605 		goto _exit;
4606 	}
4607 
4608 #ifdef CONFIG_HALMAC_FIFO_DUMP
4609 	{
4610 		static const char * const fifo_sel_str[] = {
4611 			"TX", "RX", "RSVD_PAGE", "REPORT", "LLT", "RXBUF_FW"
4612 		};
4613 
4614 		RTW_INFO("%s FIFO DUMP [start_addr:0x%04x , size:%d]\n", fifo_sel_str[halmac_fifo_sel], addr, fifo_size);
4615 		RTW_INFO_DUMP("\n", pfifo_map, fifo_size);
4616 		RTW_INFO(" ==================================================\n");
4617 	}
4618 #endif /* CONFIG_HALMAC_FIFO_DUMP */
4619 
4620 _exit:
4621 	if ((mem_created == _TRUE) && pfifo_map)
4622 		rtw_vmfree(pfifo_map, fifo_size);
4623 
4624 	return ret;
4625 }
4626 
4627 /*
4628  * rtw_halmac_rx_agg_switch() - Switch RX aggregation function and setting
4629  * @d		struct dvobj_priv *
4630  * @enable	_FALSE/_TRUE for disable/enable RX aggregation function
4631  *
4632  * This function could help to on/off bus RX aggregation function, and is only
4633  * useful for SDIO and USB interface. Although only "enable" flag is brough in,
4634  * some setting would be taken from other places, and they are from:
4635  * [DMA aggregation]
4636  *	struct hal_com_data.rxagg_dma_size
4637  *	struct hal_com_data.rxagg_dma_timeout
4638  * [USB aggregation] (only use for USB interface)
4639  *	struct hal_com_data.rxagg_usb_size
4640  *	struct hal_com_data.rxagg_usb_timeout
4641  * If above values of size and timeout are both 0 means driver would not
4642  * control the threshold setting and leave it to HALMAC handle.
4643  *
4644  * From HALMAC V1_04_04, driver force the size threshold be hard limit, and the
4645  * rx size can not exceed the setting.
4646  *
4647  * Return 0 for success, otherwise fail.
4648  */
rtw_halmac_rx_agg_switch(struct dvobj_priv * d,u8 enable)4649 int rtw_halmac_rx_agg_switch(struct dvobj_priv *d, u8 enable)
4650 {
4651 	struct _ADAPTER *adapter;
4652 	struct hal_com_data *hal;
4653 	struct halmac_adapter *halmac;
4654 	struct halmac_api *api;
4655 	struct halmac_rxagg_cfg rxaggcfg;
4656 	enum halmac_ret_status status;
4657 
4658 
4659 	adapter = dvobj_get_primary_adapter(d);
4660 	hal = GET_HAL_DATA(adapter);
4661 	halmac = dvobj_to_halmac(d);
4662 	api = HALMAC_GET_API(halmac);
4663 	_rtw_memset((void *)&rxaggcfg, 0, sizeof(rxaggcfg));
4664 	rxaggcfg.mode = HALMAC_RX_AGG_MODE_NONE;
4665 	/*
4666 	 * Always enable size limit to avoid rx size exceed
4667 	 * driver defined size.
4668 	 */
4669 	rxaggcfg.threshold.size_limit_en = 1;
4670 
4671 #ifdef RTW_RX_AGGREGATION
4672 	if (_TRUE == enable) {
4673 #ifdef CONFIG_SDIO_HCI
4674 		rxaggcfg.mode = HALMAC_RX_AGG_MODE_DMA;
4675 		rxaggcfg.threshold.drv_define = 0;
4676 		if (hal->rxagg_dma_size || hal->rxagg_dma_timeout) {
4677 			rxaggcfg.threshold.drv_define = 1;
4678 			rxaggcfg.threshold.timeout = hal->rxagg_dma_timeout;
4679 			rxaggcfg.threshold.size = hal->rxagg_dma_size;
4680 			RTW_INFO("%s: RX aggregation threshold: "
4681 				 "timeout=%u size=%u\n",
4682 				 __FUNCTION__,
4683 				 hal->rxagg_dma_timeout,
4684 				 hal->rxagg_dma_size);
4685 		}
4686 #elif defined(CONFIG_USB_HCI)
4687 		switch (hal->rxagg_mode) {
4688 		case RX_AGG_DISABLE:
4689 			rxaggcfg.mode = HALMAC_RX_AGG_MODE_NONE;
4690 			break;
4691 
4692 		case RX_AGG_DMA:
4693 			rxaggcfg.mode = HALMAC_RX_AGG_MODE_DMA;
4694 			if (hal->rxagg_dma_size || hal->rxagg_dma_timeout) {
4695 				rxaggcfg.threshold.drv_define = 1;
4696 				rxaggcfg.threshold.timeout = hal->rxagg_dma_timeout;
4697 				rxaggcfg.threshold.size = hal->rxagg_dma_size;
4698 			}
4699 			break;
4700 
4701 		case RX_AGG_USB:
4702 		case RX_AGG_MIX:
4703 			rxaggcfg.mode = HALMAC_RX_AGG_MODE_USB;
4704 			if (hal->rxagg_usb_size || hal->rxagg_usb_timeout) {
4705 				rxaggcfg.threshold.drv_define = 1;
4706 				rxaggcfg.threshold.timeout = hal->rxagg_usb_timeout;
4707 				rxaggcfg.threshold.size = hal->rxagg_usb_size;
4708 			}
4709 			break;
4710 		}
4711 #endif /* CONFIG_USB_HCI */
4712 	}
4713 #endif /* RTW_RX_AGGREGATION */
4714 
4715 	status = api->halmac_cfg_rx_aggregation(halmac, &rxaggcfg);
4716 	if (status != HALMAC_RET_SUCCESS)
4717 		return -1;
4718 
4719 	return 0;
4720 }
4721 
rtw_halmac_download_rsvd_page(struct dvobj_priv * dvobj,u8 pg_offset,u8 * pbuf,u32 size)4722 int rtw_halmac_download_rsvd_page(struct dvobj_priv *dvobj, u8 pg_offset, u8 *pbuf, u32 size)
4723 {
4724 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4725 	struct halmac_adapter *halmac = dvobj_to_halmac(dvobj);
4726 	struct halmac_api *api = HALMAC_GET_API(halmac);
4727 
4728 	status = api->halmac_dl_drv_rsvd_page(halmac, pg_offset, pbuf, size);
4729 	if (status != HALMAC_RET_SUCCESS)
4730 		return -1;
4731 
4732 	return 0;
4733 }
4734 
4735 /*
4736  * Description
4737  *	Fill following spec info from HALMAC API:
4738  *	sec_cam_ent_num
4739  *
4740  * Return
4741  *	0	Success
4742  *	others	Fail
4743  */
rtw_halmac_fill_hal_spec(struct dvobj_priv * dvobj,struct hal_spec_t * spec)4744 int rtw_halmac_fill_hal_spec(struct dvobj_priv *dvobj, struct hal_spec_t *spec)
4745 {
4746 	enum halmac_ret_status status;
4747 	struct halmac_adapter *halmac;
4748 	struct halmac_api *api;
4749 	u8 cam = 0;	/* Security Cam Entry Number */
4750 
4751 
4752 	halmac = dvobj_to_halmac(dvobj);
4753 	api = HALMAC_GET_API(halmac);
4754 
4755 	/* Prepare data from HALMAC */
4756 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_CAM_ENTRY_NUM, &cam);
4757 	if (status != HALMAC_RET_SUCCESS)
4758 		return -1;
4759 
4760 	/* Fill data to hal_spec_t */
4761 	spec->sec_cam_ent_num = cam;
4762 
4763 	return 0;
4764 }
4765 
rtw_halmac_p2pps(struct dvobj_priv * dvobj,struct hal_p2p_ps_para * pp2p_ps_para)4766 int rtw_halmac_p2pps(struct dvobj_priv *dvobj, struct hal_p2p_ps_para *pp2p_ps_para)
4767 {
4768 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4769 	struct halmac_adapter *halmac = dvobj_to_halmac(dvobj);
4770 	struct halmac_api *api = HALMAC_GET_API(halmac);
4771 	struct halmac_p2pps halmac_p2p_ps;
4772 
4773 	(&halmac_p2p_ps)->offload_en = pp2p_ps_para->offload_en;
4774 	(&halmac_p2p_ps)->role = pp2p_ps_para->role;
4775 	(&halmac_p2p_ps)->ctwindow_en = pp2p_ps_para->ctwindow_en;
4776 	(&halmac_p2p_ps)->noa_en = pp2p_ps_para->noa_en;
4777 	(&halmac_p2p_ps)->noa_sel = pp2p_ps_para->noa_sel;
4778 	(&halmac_p2p_ps)->all_sta_sleep = pp2p_ps_para->all_sta_sleep;
4779 	(&halmac_p2p_ps)->discovery = pp2p_ps_para->discovery;
4780 	(&halmac_p2p_ps)->disable_close_rf = pp2p_ps_para->disable_close_rf;
4781 	(&halmac_p2p_ps)->p2p_port_id = _hw_port_drv2halmac(pp2p_ps_para->p2p_port_id);
4782 	(&halmac_p2p_ps)->p2p_group = pp2p_ps_para->p2p_group;
4783 	(&halmac_p2p_ps)->p2p_macid = pp2p_ps_para->p2p_macid;
4784 	(&halmac_p2p_ps)->ctwindow_length = pp2p_ps_para->ctwindow_length;
4785 	(&halmac_p2p_ps)->noa_duration_para = pp2p_ps_para->noa_duration_para;
4786 	(&halmac_p2p_ps)->noa_interval_para = pp2p_ps_para->noa_interval_para;
4787 	(&halmac_p2p_ps)->noa_start_time_para = pp2p_ps_para->noa_start_time_para;
4788 	(&halmac_p2p_ps)->noa_count_para = pp2p_ps_para->noa_count_para;
4789 
4790 	status = api->halmac_p2pps(halmac, (&halmac_p2p_ps));
4791 	if (status != HALMAC_RET_SUCCESS)
4792 		return -1;
4793 
4794 	return 0;
4795 
4796 }
4797 
4798 /**
4799  * rtw_halmac_iqk() - Run IQ Calibration
4800  * @d:		struct dvobj_priv*
4801  * @clear:	IQK parameters
4802  * @segment:	IQK parameters
4803  *
4804  * Process IQ Calibration(IQK).
4805  *
4806  * Return 0 for OK, otherwise fail.
4807  */
rtw_halmac_iqk(struct dvobj_priv * d,u8 clear,u8 segment)4808 int rtw_halmac_iqk(struct dvobj_priv *d, u8 clear, u8 segment)
4809 {
4810 	struct halmac_adapter *mac;
4811 	struct halmac_api *api;
4812 	enum halmac_ret_status status;
4813 	enum halmac_feature_id id;
4814 	struct halmac_iqk_para para;
4815 	int ret;
4816 	u8 retry = 3;
4817 	u8 delay = 1; /* ms */
4818 
4819 
4820 	mac = dvobj_to_halmac(d);
4821 	api = HALMAC_GET_API(mac);
4822 	id = HALMAC_FEATURE_IQK;
4823 
4824 	ret = init_halmac_event(d, id, NULL, 0);
4825 	if (ret)
4826 		return -1;
4827 
4828 	para.clear = clear;
4829 	para.segment_iqk = segment;
4830 
4831 	do {
4832 		status = api->halmac_start_iqk(mac, &para);
4833 		if (status != HALMAC_RET_BUSY_STATE)
4834 			break;
4835 		RTW_WARN("%s: Fail to start IQK, status is BUSY! retry=%d\n", __FUNCTION__, retry);
4836 		if (!retry)
4837 			break;
4838 		retry--;
4839 		rtw_msleep_os(delay);
4840 	} while (1);
4841 	if (status != HALMAC_RET_SUCCESS) {
4842 		free_halmac_event(d, id);
4843 		return -1;
4844 	}
4845 
4846 	ret = wait_halmac_event(d, id);
4847 	if (ret)
4848 		return -1;
4849 
4850 	return 0;
4851 }
4852 
4853 /**
4854  * rtw_halmac_dpk() - Run DP Calibration
4855  * @d:		struct dvobj_priv*
4856  * @buf:	buffer for store return value
4857  * @bufsz:	size of buffer
4858  *
4859  * Process DP Calibration(DPK).
4860  *
4861  * Return 0 for OK, otherwise fail.
4862  */
rtw_halmac_dpk(struct dvobj_priv * d,u8 * buf,u32 bufsz)4863 int rtw_halmac_dpk(struct dvobj_priv *d, u8 *buf, u32 bufsz)
4864 {
4865 	struct halmac_adapter *mac;
4866 	struct halmac_api *api;
4867 	enum halmac_ret_status status;
4868 	enum halmac_feature_id id;
4869 	int ret;
4870 
4871 
4872 	mac = dvobj_to_halmac(d);
4873 	api = HALMAC_GET_API(mac);
4874 	id = HALMAC_FEATURE_DPK;
4875 
4876 	ret = init_halmac_event(d, id, buf, bufsz);
4877 	if (ret)
4878 		return -1;
4879 
4880 	status = api->halmac_start_dpk(mac);
4881 	if (status != HALMAC_RET_SUCCESS) {
4882 		free_halmac_event(d, id);
4883 		RTW_ERR("%s: Fail to start DPK (0x%x)!\n",
4884 			__FUNCTION__, status);
4885 		return -1;
4886 	}
4887 
4888 	ret = wait_halmac_event(d, id);
4889 	if (ret)
4890 		return -1;
4891 
4892 	return 0;
4893 }
4894 
_phy_parameter_val_drv2halmac(u32 val,u8 msk_en,u32 msk)4895 static inline u32 _phy_parameter_val_drv2halmac(u32 val, u8 msk_en, u32 msk)
4896 {
4897 	if (!msk_en)
4898 		return val;
4899 
4900 	return (val << bitshift(msk));
4901 }
4902 
_phy_parameter_drv2halmac(struct rtw_phy_parameter * para,struct halmac_phy_parameter_info * info)4903 static int _phy_parameter_drv2halmac(struct rtw_phy_parameter *para, struct halmac_phy_parameter_info *info)
4904 {
4905 	if (!para || !info)
4906 		return -1;
4907 
4908 	_rtw_memset(info, 0, sizeof(*info));
4909 
4910 	switch (para->cmd) {
4911 	case 0:
4912 		/* MAC register */
4913 		switch (para->data.mac.size) {
4914 		case 1:
4915 			info->cmd_id = HALMAC_PARAMETER_CMD_MAC_W8;
4916 			break;
4917 		case 2:
4918 			info->cmd_id = HALMAC_PARAMETER_CMD_MAC_W16;
4919 			break;
4920 		default:
4921 			info->cmd_id = HALMAC_PARAMETER_CMD_MAC_W32;
4922 			break;
4923 		}
4924 		info->content.MAC_REG_W.value = _phy_parameter_val_drv2halmac(
4925 							para->data.mac.value,
4926 							para->data.mac.msk_en,
4927 							para->data.mac.msk);
4928 		info->content.MAC_REG_W.msk = para->data.mac.msk;
4929 		info->content.MAC_REG_W.offset = para->data.mac.offset;
4930 		info->content.MAC_REG_W.msk_en = para->data.mac.msk_en;
4931 		break;
4932 
4933 	case 1:
4934 		/* BB register */
4935 		switch (para->data.bb.size) {
4936 		case 1:
4937 			info->cmd_id = HALMAC_PARAMETER_CMD_BB_W8;
4938 			break;
4939 		case 2:
4940 			info->cmd_id = HALMAC_PARAMETER_CMD_BB_W16;
4941 			break;
4942 		default:
4943 			info->cmd_id = HALMAC_PARAMETER_CMD_BB_W32;
4944 			break;
4945 		}
4946 		info->content.BB_REG_W.value = _phy_parameter_val_drv2halmac(
4947 							para->data.bb.value,
4948 							para->data.bb.msk_en,
4949 							para->data.bb.msk);
4950 		info->content.BB_REG_W.msk = para->data.bb.msk;
4951 		info->content.BB_REG_W.offset = para->data.bb.offset;
4952 		info->content.BB_REG_W.msk_en = para->data.bb.msk_en;
4953 		break;
4954 
4955 	case 2:
4956 		/* RF register */
4957 		info->cmd_id = HALMAC_PARAMETER_CMD_RF_W;
4958 		info->content.RF_REG_W.value = _phy_parameter_val_drv2halmac(
4959 							para->data.rf.value,
4960 							para->data.rf.msk_en,
4961 							para->data.rf.msk);
4962 		info->content.RF_REG_W.msk = para->data.rf.msk;
4963 		info->content.RF_REG_W.offset = para->data.rf.offset;
4964 		info->content.RF_REG_W.msk_en = para->data.rf.msk_en;
4965 		info->content.RF_REG_W.rf_path = para->data.rf.path;
4966 		break;
4967 
4968 	case 3:
4969 		/* Delay register */
4970 		if (para->data.delay.unit == 0)
4971 			info->cmd_id = HALMAC_PARAMETER_CMD_DELAY_US;
4972 		else
4973 			info->cmd_id = HALMAC_PARAMETER_CMD_DELAY_MS;
4974 		info->content.DELAY_TIME.delay_time = para->data.delay.value;
4975 		break;
4976 
4977 	case 0xFF:
4978 		/* Latest(End) command */
4979 		info->cmd_id = HALMAC_PARAMETER_CMD_END;
4980 		break;
4981 
4982 	default:
4983 		return -1;
4984 	}
4985 
4986 	return 0;
4987 }
4988 
4989 /**
4990  * rtw_halmac_cfg_phy_para() - Register(Phy parameter) configuration
4991  * @d:		struct dvobj_priv*
4992  * @para:	phy parameter
4993  *
4994  * Configure registers by firmware using H2C/C2H mechanism.
4995  * The latest command should be para->cmd==0xFF(End command) to finish all
4996  * processes.
4997  *
4998  * Return: 0 for OK, otherwise fail.
4999  */
rtw_halmac_cfg_phy_para(struct dvobj_priv * d,struct rtw_phy_parameter * para)5000 int rtw_halmac_cfg_phy_para(struct dvobj_priv *d, struct rtw_phy_parameter *para)
5001 {
5002 	struct halmac_adapter *mac;
5003 	struct halmac_api *api;
5004 	enum halmac_ret_status status;
5005 	enum halmac_feature_id id;
5006 	struct halmac_phy_parameter_info info;
5007 	u8 full_fifo;
5008 	int err, ret;
5009 
5010 
5011 	mac = dvobj_to_halmac(d);
5012 	api = HALMAC_GET_API(mac);
5013 	id = HALMAC_FEATURE_CFG_PARA;
5014 	full_fifo = 1; /* ToDo: How to deciede? */
5015 	ret = 0;
5016 
5017 	err = _phy_parameter_drv2halmac(para, &info);
5018 	if (err)
5019 		return -1;
5020 
5021 	err = init_halmac_event(d, id, NULL, 0);
5022 	if (err)
5023 		return -1;
5024 
5025 	status = api->halmac_cfg_parameter(mac, &info, full_fifo);
5026 	if (info.cmd_id == HALMAC_PARAMETER_CMD_END) {
5027 		if (status == HALMAC_RET_SUCCESS) {
5028 			err = wait_halmac_event(d, id);
5029 			if (err)
5030 				ret = -1;
5031 		} else {
5032 			free_halmac_event(d, id);
5033 			ret = -1;
5034 			RTW_ERR("%s: Fail to send END of cfg parameter, status is 0x%x!\n", __FUNCTION__, status);
5035 		}
5036 	} else {
5037 		if (status == HALMAC_RET_PARA_SENDING) {
5038 			err = wait_halmac_event(d, id);
5039 			if (err)
5040 				ret = -1;
5041 		} else {
5042 			free_halmac_event(d, id);
5043 			if (status != HALMAC_RET_SUCCESS) {
5044 				ret = -1;
5045 				RTW_ERR("%s: Fail to cfg parameter, status is 0x%x!\n", __FUNCTION__, status);
5046 			}
5047 		}
5048 	}
5049 
5050 	return ret;
5051 }
5052 
_led_mode_drv2halmac(u8 drv_mode)5053 static enum halmac_wlled_mode _led_mode_drv2halmac(u8 drv_mode)
5054 {
5055 	enum halmac_wlled_mode halmac_mode;
5056 
5057 
5058 	switch (drv_mode) {
5059 	case 1:
5060 		halmac_mode = HALMAC_WLLED_MODE_TX;
5061 		break;
5062 	case 2:
5063 		halmac_mode = HALMAC_WLLED_MODE_RX;
5064 		break;
5065 	case 3:
5066 		halmac_mode = HALMAC_WLLED_MODE_SW_CTRL;
5067 		break;
5068 	case 0:
5069 	default:
5070 		halmac_mode = HALMAC_WLLED_MODE_TRX;
5071 		break;
5072 	}
5073 
5074 	return halmac_mode;
5075 }
5076 
5077 /**
5078  * rtw_halmac_led_cfg() - Configure Hardware LED Mode
5079  * @d:		struct dvobj_priv*
5080  * @enable:	enable or disable LED function
5081  *		0: disable
5082  *		1: enable
5083  * @mode:	WLan LED mode (valid when enable==1)
5084  *		0: Blink when TX(transmit packet) and RX(receive packet)
5085  *		1: Blink when TX only
5086  *		2: Blink when RX only
5087  *		3: Software control
5088  *
5089  * Configure hardware WLan LED mode.
5090  * If want to change LED mode after enabled, need to disable LED first and
5091  * enable again to set new mode.
5092  *
5093  * Return 0 for OK, otherwise fail.
5094  */
rtw_halmac_led_cfg(struct dvobj_priv * d,u8 enable,u8 mode)5095 int rtw_halmac_led_cfg(struct dvobj_priv *d, u8 enable, u8 mode)
5096 {
5097 	struct halmac_adapter *halmac;
5098 	struct halmac_api *api;
5099 	enum halmac_wlled_mode led_mode;
5100 	enum halmac_ret_status status;
5101 
5102 
5103 	halmac = dvobj_to_halmac(d);
5104 	api = HALMAC_GET_API(halmac);
5105 
5106 	if (enable) {
5107 		status = api->halmac_pinmux_set_func(halmac,
5108 						     HALMAC_GPIO_FUNC_WL_LED);
5109 		if (status != HALMAC_RET_SUCCESS) {
5110 			RTW_ERR("%s: pinmux set fail!(0x%x)\n",
5111 				__FUNCTION__, status);
5112 			return -1;
5113 		}
5114 
5115 		led_mode = _led_mode_drv2halmac(mode);
5116 		status = api->halmac_pinmux_wl_led_mode(halmac, led_mode);
5117 		if (status != HALMAC_RET_SUCCESS) {
5118 			RTW_ERR("%s: mode set fail!(0x%x)\n",
5119 				__FUNCTION__, status);
5120 			return -1;
5121 		}
5122 	} else {
5123 		/* Change LED to software control and turn off */
5124 		api->halmac_pinmux_wl_led_mode(halmac,
5125 					       HALMAC_WLLED_MODE_SW_CTRL);
5126 		api->halmac_pinmux_wl_led_sw_ctrl(halmac, 0);
5127 
5128 		status = api->halmac_pinmux_free_func(halmac,
5129 						      HALMAC_GPIO_FUNC_WL_LED);
5130 		if (status != HALMAC_RET_SUCCESS) {
5131 			RTW_ERR("%s: pinmux free fail!(0x%x)\n",
5132 				__FUNCTION__, status);
5133 			return -1;
5134 		}
5135 	}
5136 
5137 	return 0;
5138 }
5139 
5140 /**
5141  * rtw_halmac_led_switch() - Turn Hardware LED on/off
5142  * @d:		struct dvobj_priv*
5143  * @on:		LED light or not
5144  *		0: Off
5145  *		1: On(Light)
5146  *
5147  * Turn Hardware WLan LED On/Off.
5148  * Before use this function, user should call rtw_halmac_led_ctrl() to switch
5149  * mode to "software control(3)" first, otherwise control would fail.
5150  * The interval between on and off must be longer than 1 ms, or the LED would
5151  * keep light or dark only.
5152  * Ex. Turn off LED at first, turn on after 0.5ms and turn off again after
5153  * 0.5ms. The LED during this flow will only keep dark, and miss the turn on
5154  * operation between two turn off operations.
5155  */
rtw_halmac_led_switch(struct dvobj_priv * d,u8 on)5156 void rtw_halmac_led_switch(struct dvobj_priv *d, u8 on)
5157 {
5158 	struct halmac_adapter *halmac;
5159 	struct halmac_api *api;
5160 
5161 
5162 	halmac = dvobj_to_halmac(d);
5163 	api = HALMAC_GET_API(halmac);
5164 
5165 	api->halmac_pinmux_wl_led_sw_ctrl(halmac, on);
5166 }
5167 
_gpio_cfg(struct dvobj_priv * d,enum halmac_gpio_func gpio,u8 enable)5168 static int _gpio_cfg(struct dvobj_priv *d, enum halmac_gpio_func gpio, u8 enable)
5169 {
5170 	struct halmac_adapter *halmac;
5171 	struct halmac_api *api;
5172 	enum halmac_ret_status status;
5173 
5174 
5175 	halmac = dvobj_to_halmac(d);
5176 	api = HALMAC_GET_API(halmac);
5177 
5178 	if (enable) {
5179 		status = api->halmac_pinmux_set_func(halmac, gpio);
5180 		if (status != HALMAC_RET_SUCCESS) {
5181 			RTW_ERR("%s: pinmux set GPIO(%d) fail!(0x%x)\n",
5182 				__FUNCTION__, gpio, status);
5183 			return -1;
5184 		}
5185 	} else {
5186  		status = api->halmac_pinmux_free_func(halmac, gpio);
5187 		if (status != HALMAC_RET_SUCCESS) {
5188 			RTW_ERR("%s: pinmux free GPIO(%d) fail!(0x%x)\n",
5189 				__FUNCTION__, gpio, status);
5190 			return -1;
5191 		}
5192 	}
5193 
5194 	return 0;
5195 }
5196 
5197 /**
5198  * rtw_halmac_bt_wake_cfg() - Configure BT wake host function
5199  * @d:		struct dvobj_priv*
5200  * @enable:	enable or disable BT wake host function
5201  *		0: disable
5202  *		1: enable
5203  *
5204  * Configure pinmux to allow BT to control BT wake host pin.
5205  *
5206  * Return 0 for OK, otherwise fail.
5207  */
rtw_halmac_bt_wake_cfg(struct dvobj_priv * d,u8 enable)5208 int rtw_halmac_bt_wake_cfg(struct dvobj_priv *d, u8 enable)
5209 {
5210 	return _gpio_cfg(d, HALMAC_GPIO_FUNC_BT_HOST_WAKE1, enable);
5211 }
5212 
_gpio_to_func_for_rfe_ctrl(u8 gpio)5213 static enum halmac_gpio_func _gpio_to_func_for_rfe_ctrl(u8 gpio)
5214 {
5215 	enum halmac_gpio_func f = HALMAC_GPIO_FUNC_UNDEFINE;
5216 
5217 
5218 #ifdef CONFIG_RTL8822C
5219 	switch (gpio) {
5220 	case 1:
5221 		f = HALMAC_GPIO_FUNC_ANTSWB;
5222 		break;
5223 	case 2:
5224 		f = HALMAC_GPIO_FUNC_S1_TRSW;
5225 		break;
5226 	case 3:
5227 		f = HALMAC_GPIO_FUNC_S0_TRSW;
5228 		break;
5229 	case 6:
5230 		f = HALMAC_GPIO_FUNC_S0_PAPE;
5231 		break;
5232 	case 7:
5233 		f = HALMAC_GPIO_FUNC_S0_TRSWB;
5234 		break;
5235 	case 13:
5236 		f = HALMAC_GPIO_FUNC_ANTSW;
5237 		break;
5238 	}
5239 #endif /* CONFIG_RTL8822C */
5240 
5241 	return f;
5242 }
5243 
5244 /**
5245  * rtw_halmac_rfe_ctrl_cfg() - Configure RFE control GPIO
5246  * @d:		struct dvobj_priv*
5247  * @gpio:	gpio number
5248  *
5249  * Configure pinmux to enable RFE control GPIO.
5250  *
5251  * Return 0 for OK, otherwise fail.
5252  */
rtw_halmac_rfe_ctrl_cfg(struct dvobj_priv * d,u8 gpio)5253 int rtw_halmac_rfe_ctrl_cfg(struct dvobj_priv *d, u8 gpio)
5254 {
5255 	enum halmac_gpio_func f;
5256 
5257 
5258 	f = _gpio_to_func_for_rfe_ctrl(gpio);
5259 	if (f == HALMAC_GPIO_FUNC_UNDEFINE)
5260 		return -1;
5261 	return _gpio_cfg(d, f, 1);
5262 }
5263 
5264 #ifdef CONFIG_PNO_SUPPORT
5265 /**
5266  * _halmac_scanoffload() - Switch channel by firmware during scanning
5267  * @d:		struct dvobj_priv*
5268  * @enable:	1: enable, 0: disable
5269  * @nlo:	1: nlo mode (no c2h event), 0: normal mode
5270  * @ssid:	ssid of probe request
5271  * @ssid_len:	ssid length
5272  *
5273  * Switch Channel and Send Porbe Request Offloaded by FW
5274  *
5275  * Return 0 for OK, otherwise fail.
5276  */
_halmac_scanoffload(struct dvobj_priv * d,u32 enable,u8 nlo,u8 * ssid,u8 ssid_len)5277 static int _halmac_scanoffload(struct dvobj_priv *d, u32 enable, u8 nlo,
5278 			       u8 *ssid, u8 ssid_len)
5279 {
5280 	struct _ADAPTER *adapter;
5281 	struct halmac_adapter *mac;
5282 	struct halmac_api *api;
5283 	enum halmac_ret_status status;
5284 	struct halmac_ch_info ch_info;
5285 	struct halmac_ch_switch_option cs_option;
5286 	struct mlme_ext_priv *pmlmeext;
5287 	enum halmac_feature_id id_update, id_ch_sw;
5288 	struct halmac_indicator *indicator, *tbl;
5289 
5290 	int err = 0;
5291 	u8 probereq[64];
5292 	u32 len = 0;
5293 	int i = 0;
5294 	struct pno_ssid pnossid;
5295 	struct rf_ctl_t *rfctl = NULL;
5296 	struct _RT_CHANNEL_INFO *ch_set;
5297 
5298 
5299 	tbl = d->hmpriv.indicator;
5300 	adapter = dvobj_get_primary_adapter(d);
5301 	mac = dvobj_to_halmac(d);
5302 	if (!mac)
5303 		return -1;
5304 	api = HALMAC_GET_API(mac);
5305 	id_update = HALMAC_FEATURE_UPDATE_PACKET;
5306 	id_ch_sw = HALMAC_FEATURE_CHANNEL_SWITCH;
5307 	pmlmeext = &(adapter->mlmeextpriv);
5308 	rfctl = adapter_to_rfctl(adapter);
5309 	ch_set = rfctl->channel_set;
5310 
5311 	RTW_INFO("%s: %s scanoffload, mode: %s\n",
5312 		 __FUNCTION__, enable?"Enable":"Disable",
5313 		 nlo?"PNO/NLO":"Normal");
5314 
5315 	if (enable) {
5316 		_rtw_memset(probereq, 0, sizeof(probereq));
5317 
5318 		_rtw_memset(&pnossid, 0, sizeof(pnossid));
5319 		if (ssid) {
5320 			if (ssid_len > sizeof(pnossid.SSID)) {
5321 				RTW_ERR("%s: SSID length(%d) is too long(>%d)!!\n",
5322 					__FUNCTION__, ssid_len, sizeof(pnossid.SSID));
5323 				return -1;
5324 			}
5325 
5326 			pnossid.SSID_len = ssid_len;
5327 			_rtw_memcpy(pnossid.SSID, ssid, ssid_len);
5328 		}
5329 
5330 		rtw_hal_construct_ProbeReq(adapter, probereq, &len, &pnossid);
5331 
5332 		if (!nlo) {
5333 			err = init_halmac_event(d, id_update, NULL, 0);
5334 			if (err)
5335 				return -1;
5336 		}
5337 
5338 		status = api->halmac_update_packet(mac, HALMAC_PACKET_PROBE_REQ,
5339 						   probereq, len);
5340 		if (status != HALMAC_RET_SUCCESS) {
5341 			if (!nlo)
5342 				free_halmac_event(d, id_update);
5343 			RTW_ERR("%s: halmac_update_packet FAIL(%d)!!\n",
5344 				__FUNCTION__, status);
5345 			return -1;
5346 		}
5347 
5348 		if (!nlo) {
5349 			err = wait_halmac_event(d, id_update);
5350 			if (err)
5351 				RTW_ERR("%s: wait update packet FAIL(%d)!!\n",
5352 					__FUNCTION__, err);
5353 		}
5354 
5355 		api->halmac_clear_ch_info(mac);
5356 
5357 		for (i = 0; i < rfctl->max_chan_nums && ch_set[i].ChannelNum != 0; i++) {
5358 			_rtw_memset(&ch_info, 0, sizeof(ch_info));
5359 			ch_info.extra_info = 0;
5360 			ch_info.channel = ch_set[i].ChannelNum;
5361 			ch_info.bw = HALMAC_BW_20;
5362 			ch_info.pri_ch_idx = HALMAC_CH_IDX_1;
5363 			ch_info.action_id = HALMAC_CS_ACTIVE_SCAN;
5364 			ch_info.timeout = 1;
5365 			status = api->halmac_add_ch_info(mac, &ch_info);
5366 			if (status != HALMAC_RET_SUCCESS) {
5367 				RTW_ERR("%s: add_ch_info FAIL(%d)!!\n",
5368 					__FUNCTION__, status);
5369 				return -1;
5370 			}
5371 		}
5372 
5373 		/* set channel switch option */
5374 		_rtw_memset(&cs_option, 0, sizeof(cs_option));
5375 		cs_option.dest_bw = HALMAC_BW_20;
5376 		cs_option.periodic_option = HALMAC_CS_PERIODIC_2_PHASE;
5377 		cs_option.dest_pri_ch_idx = HALMAC_CH_IDX_UNDEFINE;
5378 		cs_option.tsf_low = 0;
5379 		cs_option.switch_en = 1;
5380 		cs_option.dest_ch_en = 1;
5381 		cs_option.absolute_time_en = 0;
5382 		cs_option.dest_ch = 1;
5383 
5384 		cs_option.normal_period = 5;
5385 		cs_option.normal_period_sel = 0;
5386 		cs_option.normal_cycle = 10;
5387 
5388 		cs_option.phase_2_period = 1;
5389 		cs_option.phase_2_period_sel = 1;
5390 
5391 		/* nlo is for wow fw,  1: no c2h response */
5392 		cs_option.nlo_en = nlo;
5393 
5394 		if (!nlo) {
5395 			err = init_halmac_event(d, id_ch_sw, NULL, 0);
5396 			if (err)
5397 				return -1;
5398 		}
5399 
5400 		status = api->halmac_ctrl_ch_switch(mac, &cs_option);
5401 		if (status != HALMAC_RET_SUCCESS) {
5402 			if (!nlo)
5403 				free_halmac_event(d, id_ch_sw);
5404 			RTW_ERR("%s: halmac_ctrl_ch_switch FAIL(%d)!!\n",
5405 				__FUNCTION__, status);
5406 			return -1;
5407 		}
5408 
5409 		if (!nlo) {
5410 			err = wait_halmac_event(d, id_ch_sw);
5411 			if (err)
5412 				RTW_ERR("%s: wait ctrl_ch_switch FAIL(%d)!!\n",
5413 					__FUNCTION__, err);
5414 		}
5415 	} else {
5416 		api->halmac_clear_ch_info(mac);
5417 
5418 		_rtw_memset(&cs_option, 0, sizeof(cs_option));
5419 		cs_option.switch_en = 0;
5420 
5421 		if (!nlo) {
5422 			err = init_halmac_event(d, id_ch_sw, NULL, 0);
5423 			if (err)
5424 				return -1;
5425 		}
5426 
5427 		status = api->halmac_ctrl_ch_switch(mac, &cs_option);
5428 		if (status != HALMAC_RET_SUCCESS) {
5429 			if (!nlo)
5430 				free_halmac_event(d, id_ch_sw);
5431 			RTW_ERR("%s: halmac_ctrl_ch_switch FAIL(%d)!!\n",
5432 				__FUNCTION__, status);
5433 			return -1;
5434 		}
5435 
5436 		if (!nlo) {
5437 			err = wait_halmac_event(d, id_ch_sw);
5438 			if (err)
5439 				RTW_ERR("%s: wait ctrl_ch_switch FAIL(%d)!!\n",
5440 					__FUNCTION__, err);
5441 		}
5442 	}
5443 
5444 	return 0;
5445 }
5446 
5447 /**
5448  * rtw_halmac_pno_scanoffload() - Control firmware scan AP function for PNO
5449  * @d:		struct dvobj_priv*
5450  * @enable:	1: enable, 0: disable
5451  *
5452  * Switch firmware scan AP function for PNO(prefer network offload) or
5453  * NLO(network list offload).
5454  *
5455  * Return 0 for OK, otherwise fail.
5456  */
rtw_halmac_pno_scanoffload(struct dvobj_priv * d,u32 enable)5457 int rtw_halmac_pno_scanoffload(struct dvobj_priv *d, u32 enable)
5458 {
5459 	return _halmac_scanoffload(d, enable, 1, NULL, 0);
5460 }
5461 #endif /* CONFIG_PNO_SUPPORT */
5462 
5463 #ifdef CONFIG_SDIO_HCI
5464 
5465 /**
5466  * rtw_halmac_preinit_sdio_io_indirect() - Enable indirect I/O or not
5467  * @d:		struct dvobj_priv*
5468  * @enable:	true: enable, false: disable
5469  *
5470  * Enable register access using direct I/O or indirect. This function should be
5471  * called before rtw_halmac_init_adapter(), and the life cycle is the same as
5472  * driver until removing driver.
5473  *
5474  * Return 0 for OK, otherwise fail.
5475  */
rtw_halmac_preinit_sdio_io_indirect(struct dvobj_priv * d,bool enable)5476 int rtw_halmac_preinit_sdio_io_indirect(struct dvobj_priv *d, bool enable)
5477 {
5478 	struct halmac_adapter *halmac;
5479 	struct halmacpriv *priv;
5480 
5481 
5482 	halmac = dvobj_to_halmac(d);
5483 	if (halmac) {
5484 		RTW_WARN("%s: illegal operation! "
5485 			 "preinit function only could be called before init!\n",
5486 			 __FUNCTION__);
5487 		return -1;
5488 	}
5489 
5490 	priv = &d->hmpriv;
5491 	priv->sdio_io_indir = (enable ? 1 : 2);
5492 
5493 	return 0;
5494 }
5495 
5496 /*
5497  * Description:
5498  *	Update queue allocated page number to driver
5499  *
5500  * Parameter:
5501  *	d	pointer to struct dvobj_priv of driver
5502  *
5503  * Return:
5504  *	0	Success, "page" is valid.
5505  *	others	Fail, "page" is invalid.
5506  */
rtw_halmac_query_tx_page_num(struct dvobj_priv * d)5507 int rtw_halmac_query_tx_page_num(struct dvobj_priv *d)
5508 {
5509 	PADAPTER adapter;
5510 	struct halmacpriv *hmpriv;
5511 	struct halmac_adapter *halmac;
5512 	struct halmac_api *api;
5513 	struct halmac_rqpn_map rqpn;
5514 	enum halmac_dma_mapping dmaqueue;
5515 	struct halmac_txff_allocation fifosize;
5516 	enum halmac_ret_status status;
5517 	u8 i;
5518 
5519 
5520 	adapter = dvobj_get_primary_adapter(d);
5521 	hmpriv = &d->hmpriv;
5522 	halmac = dvobj_to_halmac(d);
5523 	api = HALMAC_GET_API(halmac);
5524 	_rtw_memset((void *)&rqpn, 0, sizeof(rqpn));
5525 	_rtw_memset((void *)&fifosize, 0, sizeof(fifosize));
5526 
5527 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RQPN_MAPPING, &rqpn);
5528 	if (status != HALMAC_RET_SUCCESS)
5529 		return -1;
5530 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_TXFF_ALLOCATION, &fifosize);
5531 	if (status != HALMAC_RET_SUCCESS)
5532 		return -1;
5533 
5534 	for (i = 0; i < HW_QUEUE_ENTRY; i++) {
5535 		hmpriv->txpage[i] = 0;
5536 
5537 		/* Driver index mapping to HALMAC DMA queue */
5538 		dmaqueue = HALMAC_DMA_MAPPING_UNDEFINE;
5539 		switch (i) {
5540 		case VO_QUEUE_INX:
5541 			dmaqueue = rqpn.dma_map_vo;
5542 			break;
5543 		case VI_QUEUE_INX:
5544 			dmaqueue = rqpn.dma_map_vi;
5545 			break;
5546 		case BE_QUEUE_INX:
5547 			dmaqueue = rqpn.dma_map_be;
5548 			break;
5549 		case BK_QUEUE_INX:
5550 			dmaqueue = rqpn.dma_map_bk;
5551 			break;
5552 		case MGT_QUEUE_INX:
5553 			dmaqueue = rqpn.dma_map_mg;
5554 			break;
5555 		case HIGH_QUEUE_INX:
5556 			dmaqueue = rqpn.dma_map_hi;
5557 			break;
5558 		case BCN_QUEUE_INX:
5559 		case TXCMD_QUEUE_INX:
5560 			/* Unlimited */
5561 			hmpriv->txpage[i] = 0xFFFF;
5562 			continue;
5563 		}
5564 
5565 		switch (dmaqueue) {
5566 		case HALMAC_DMA_MAPPING_EXTRA:
5567 			hmpriv->txpage[i] = fifosize.extra_queue_pg_num;
5568 			break;
5569 		case HALMAC_DMA_MAPPING_LOW:
5570 			hmpriv->txpage[i] = fifosize.low_queue_pg_num;
5571 			break;
5572 		case HALMAC_DMA_MAPPING_NORMAL:
5573 			hmpriv->txpage[i] = fifosize.normal_queue_pg_num;
5574 			break;
5575 		case HALMAC_DMA_MAPPING_HIGH:
5576 			hmpriv->txpage[i] = fifosize.high_queue_pg_num;
5577 			break;
5578 		case HALMAC_DMA_MAPPING_UNDEFINE:
5579 			break;
5580 		}
5581 		hmpriv->txpage[i] += fifosize.pub_queue_pg_num;
5582 	}
5583 
5584 	return 0;
5585 }
5586 
5587 /*
5588  * Description:
5589  *	Get specific queue allocated page number
5590  *
5591  * Parameter:
5592  *	d	pointer to struct dvobj_priv of driver
5593  *	queue	target queue to query, VO/VI/BE/BK/.../TXCMD_QUEUE_INX
5594  *	page	return allocated page number
5595  *
5596  * Return:
5597  *	0	Success, "page" is valid.
5598  *	others	Fail, "page" is invalid.
5599  */
rtw_halmac_get_tx_queue_page_num(struct dvobj_priv * d,u8 queue,u32 * page)5600 int rtw_halmac_get_tx_queue_page_num(struct dvobj_priv *d, u8 queue, u32 *page)
5601 {
5602 	*page = 0;
5603 	if (queue < HW_QUEUE_ENTRY)
5604 		*page = d->hmpriv.txpage[queue];
5605 
5606 	return 0;
5607 }
5608 
5609 /*
5610  * Return:
5611  *	address for SDIO command
5612  */
rtw_halmac_sdio_get_tx_addr(struct dvobj_priv * d,u8 * desc,u32 size)5613 u32 rtw_halmac_sdio_get_tx_addr(struct dvobj_priv *d, u8 *desc, u32 size)
5614 {
5615 	struct halmac_adapter *mac;
5616 	struct halmac_api *api;
5617 	enum halmac_ret_status status;
5618 	u32 addr;
5619 
5620 
5621 	mac = dvobj_to_halmac(d);
5622 	api = HALMAC_GET_API(mac);
5623 
5624 	status = api->halmac_get_sdio_tx_addr(mac, desc, size, &addr);
5625 	if (HALMAC_RET_SUCCESS != status)
5626 		return 0;
5627 
5628 	return addr;
5629 }
5630 
rtw_halmac_sdio_tx_allowed(struct dvobj_priv * d,u8 * buf,u32 size)5631 int rtw_halmac_sdio_tx_allowed(struct dvobj_priv *d, u8 *buf, u32 size)
5632 {
5633 	struct halmac_adapter *mac;
5634 	struct halmac_api *api;
5635 	enum halmac_ret_status status;
5636 
5637 
5638 	mac = dvobj_to_halmac(d);
5639 	api = HALMAC_GET_API(mac);
5640 
5641 	status = api->halmac_tx_allowed_sdio(mac, buf, size);
5642 	if (HALMAC_RET_SUCCESS != status)
5643 		return -1;
5644 
5645 	return 0;
5646 }
5647 
rtw_halmac_sdio_get_rx_addr(struct dvobj_priv * d,u8 * seq)5648 u32 rtw_halmac_sdio_get_rx_addr(struct dvobj_priv *d, u8 *seq)
5649 {
5650 	u8 id;
5651 
5652 #define RTW_SDIO_ADDR_RX_RX0FF_PRFIX	0x0E000
5653 #define RTW_SDIO_ADDR_RX_RX0FF_GEN(a)	(RTW_SDIO_ADDR_RX_RX0FF_PRFIX|(a&0x3))
5654 
5655 	id = *seq;
5656 	(*seq)++;
5657 	return RTW_SDIO_ADDR_RX_RX0FF_GEN(id);
5658 }
5659 
rtw_halmac_sdio_set_tx_format(struct dvobj_priv * d,enum halmac_sdio_tx_format format)5660 int rtw_halmac_sdio_set_tx_format(struct dvobj_priv *d, enum halmac_sdio_tx_format format)
5661 {
5662 	struct halmac_adapter *mac;
5663 	struct halmac_api *api;
5664 	enum halmac_ret_status status;
5665 
5666 	mac = dvobj_to_halmac(d);
5667 	api = HALMAC_GET_API(mac);
5668 
5669 	status = api->halmac_set_hw_value(mac, HALMAC_HW_SDIO_TX_FORMAT, &format);
5670 	if (HALMAC_RET_SUCCESS != status)
5671 		return -1;
5672 
5673 	return 0;
5674 }
5675 #endif /* CONFIG_SDIO_HCI */
5676 
5677 #ifdef CONFIG_USB_HCI
rtw_halmac_usb_get_bulkout_id(struct dvobj_priv * d,u8 * buf,u32 size)5678 u8 rtw_halmac_usb_get_bulkout_id(struct dvobj_priv *d, u8 *buf, u32 size)
5679 {
5680 	struct halmac_adapter *mac;
5681 	struct halmac_api *api;
5682 	enum halmac_ret_status status;
5683 	u8 bulkout_id;
5684 
5685 
5686 	mac = dvobj_to_halmac(d);
5687 	api = HALMAC_GET_API(mac);
5688 
5689 	status = api->halmac_get_usb_bulkout_id(mac, buf, size, &bulkout_id);
5690 	if (HALMAC_RET_SUCCESS != status)
5691 		return 0;
5692 
5693 	return bulkout_id;
5694 }
5695 
5696 /**
5697  * rtw_halmac_usb_get_txagg_desc_num() - MAX descriptor number in one bulk for TX
5698  * @d:		struct dvobj_priv*
5699  * @size:	TX FIFO size, unit is byte.
5700  *
5701  * Get MAX descriptor number in one bulk out from HALMAC.
5702  *
5703  * Return 0 for OK, otherwise fail.
5704  */
rtw_halmac_usb_get_txagg_desc_num(struct dvobj_priv * d,u8 * num)5705 int rtw_halmac_usb_get_txagg_desc_num(struct dvobj_priv *d, u8 *num)
5706 {
5707 	struct halmac_adapter *halmac;
5708 	struct halmac_api *api;
5709 	enum halmac_ret_status status;
5710 	u8 val = 0;
5711 
5712 
5713 	halmac = dvobj_to_halmac(d);
5714 	api = HALMAC_GET_API(halmac);
5715 
5716 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_USB_TXAGG_DESC_NUM, &val);
5717 	if (status != HALMAC_RET_SUCCESS)
5718 		return -1;
5719 
5720 	*num = val;
5721 
5722 	return 0;
5723 }
5724 
_usb_mode_drv2halmac(enum RTW_USB_SPEED usb_mode)5725 static inline enum halmac_usb_mode _usb_mode_drv2halmac(enum RTW_USB_SPEED usb_mode)
5726 {
5727 	enum halmac_usb_mode halmac_usb_mode = HALMAC_USB_MODE_U2;
5728 
5729 	switch (usb_mode) {
5730 	case RTW_USB_SPEED_2:
5731 		halmac_usb_mode = HALMAC_USB_MODE_U2;
5732 		break;
5733 	case RTW_USB_SPEED_3:
5734 		halmac_usb_mode = HALMAC_USB_MODE_U3;
5735 		break;
5736 	default:
5737 		halmac_usb_mode = HALMAC_USB_MODE_U2;
5738 		break;
5739 	}
5740 
5741 	return halmac_usb_mode;
5742 }
5743 
rtw_halmac_switch_usb_mode(struct dvobj_priv * d,enum RTW_USB_SPEED usb_mode)5744 u8 rtw_halmac_switch_usb_mode(struct dvobj_priv *d, enum RTW_USB_SPEED usb_mode)
5745 {
5746 	PADAPTER adapter;
5747 	struct halmac_adapter *mac;
5748 	struct halmac_api *api;
5749 	enum halmac_ret_status status;
5750 	enum halmac_usb_mode halmac_usb_mode;
5751 
5752 	adapter = dvobj_get_primary_adapter(d);
5753 	mac = dvobj_to_halmac(d);
5754 	api = HALMAC_GET_API(mac);
5755 	halmac_usb_mode = _usb_mode_drv2halmac(usb_mode);
5756 	status = api->halmac_set_hw_value(mac, HALMAC_HW_USB_MODE, (void *)&halmac_usb_mode);
5757 
5758 	if (HALMAC_RET_SUCCESS != status)
5759 		return _FAIL;
5760 
5761 	return _SUCCESS;
5762 }
5763 #endif /* CONFIG_USB_HCI */
5764 
5765 #ifdef CONFIG_BEAMFORMING
5766 #ifdef RTW_BEAMFORMING_VERSION_2
rtw_halmac_bf_add_mu_bfer(struct dvobj_priv * d,u16 paid,u16 csi_para,u16 my_aid,enum halmac_csi_seg_len sel,u8 * addr)5767 int rtw_halmac_bf_add_mu_bfer(struct dvobj_priv *d, u16 paid, u16 csi_para,
5768 		u16 my_aid, enum halmac_csi_seg_len sel, u8 *addr)
5769 {
5770 	struct halmac_adapter *mac;
5771 	struct halmac_api *api;
5772 	enum halmac_ret_status status;
5773 	struct halmac_mu_bfer_init_para param;
5774 
5775 
5776 	mac = dvobj_to_halmac(d);
5777 	api = HALMAC_GET_API(mac);
5778 
5779 	_rtw_memset(&param, 0, sizeof(param));
5780 	param.paid = paid;
5781 	param.csi_para = csi_para;
5782 	param.my_aid = my_aid;
5783 	param.csi_length_sel = sel;
5784 	_rtw_memcpy(param.bfer_address.addr, addr, 6);
5785 
5786 	status = api->halmac_mu_bfer_entry_init(mac, &param);
5787 	if (status != HALMAC_RET_SUCCESS)
5788 		return -1;
5789 
5790 	return 0;
5791 }
5792 
rtw_halmac_bf_del_mu_bfer(struct dvobj_priv * d)5793 int rtw_halmac_bf_del_mu_bfer(struct dvobj_priv *d)
5794 {
5795 	struct halmac_adapter *mac;
5796 	struct halmac_api *api;
5797 	enum halmac_ret_status status;
5798 
5799 
5800 	mac = dvobj_to_halmac(d);
5801 	api = HALMAC_GET_API(mac);
5802 
5803 	status = api->halmac_mu_bfer_entry_del(mac);
5804 	if (status != HALMAC_RET_SUCCESS)
5805 		return -1;
5806 
5807 	return 0;
5808 }
5809 
5810 
rtw_halmac_bf_cfg_sounding(struct dvobj_priv * d,enum halmac_snd_role role,enum halmac_data_rate rate)5811 int rtw_halmac_bf_cfg_sounding(struct dvobj_priv *d,
5812 		enum halmac_snd_role role, enum halmac_data_rate rate)
5813 {
5814 	struct halmac_adapter *mac;
5815 	struct halmac_api *api;
5816 	enum halmac_ret_status status;
5817 
5818 
5819 	mac = dvobj_to_halmac(d);
5820 	api = HALMAC_GET_API(mac);
5821 
5822 	status = api->halmac_cfg_sounding(mac, role, rate);
5823 	if (status != HALMAC_RET_SUCCESS)
5824 		return -1;
5825 
5826 	return 0;
5827 }
5828 
rtw_halmac_bf_del_sounding(struct dvobj_priv * d,enum halmac_snd_role role)5829 int rtw_halmac_bf_del_sounding(struct dvobj_priv *d,
5830 		enum halmac_snd_role role)
5831 {
5832 	struct halmac_adapter *mac;
5833 	struct halmac_api *api;
5834 	enum halmac_ret_status status;
5835 
5836 
5837 	mac = dvobj_to_halmac(d);
5838 	api = HALMAC_GET_API(mac);
5839 
5840 	status = api->halmac_del_sounding(mac, role);
5841 	if (status != HALMAC_RET_SUCCESS)
5842 		return -1;
5843 
5844 	return 0;
5845 }
5846 
5847 /**
5848  * rtw_halmac_bf_cfg_csi_rate() - Config data rate for CSI report frame by RSSI
5849  * @d:		struct dvobj_priv*
5850  * @rssi:	RSSI vlaue, unit is percentage (0~100).
5851  * @current_rate:	Current CSI frame rate
5852  *			Valid value example
5853  *			0	CCK 1M
5854  *			3	CCK 11M
5855  *			4	OFDM 6M
5856  *			and so on
5857  * @fixrate_en:	Enable to fix CSI frame in VHT rate, otherwise legacy OFDM rate.
5858  *		The value "0" for disable, otheriwse enable.
5859  * @new_rate:	Return new data rate, and value range is the same as
5860  *		current_rate
5861  * @bmp_ofdm54: Return to suggest enabling OFDM 54M for CSI report frame or not,
5862  *		The valid values and meanings are:
5863  *		0x00	disable
5864  *		0x01	enable
5865  *		0xFF	Keep current setting
5866  *
5867  * According RSSI to config data rate for CSI report frame of Beamforming.
5868  *
5869  * Return 0 for OK, otherwise fail.
5870  */
rtw_halmac_bf_cfg_csi_rate(struct dvobj_priv * d,u8 rssi,u8 current_rate,u8 fixrate_en,u8 * new_rate,u8 * bmp_ofdm54)5871 int rtw_halmac_bf_cfg_csi_rate(struct dvobj_priv *d, u8 rssi,
5872 			       u8 current_rate, u8 fixrate_en, u8 *new_rate,
5873 			       u8 *bmp_ofdm54)
5874 {
5875 	struct halmac_adapter *mac;
5876 	struct halmac_api *api;
5877 	enum halmac_ret_status status;
5878 
5879 
5880 	mac = dvobj_to_halmac(d);
5881 	api = HALMAC_GET_API(mac);
5882 
5883 	status = api->halmac_cfg_csi_rate(mac,
5884 			rssi, current_rate, fixrate_en, new_rate,
5885 			bmp_ofdm54);
5886 	if (status != HALMAC_RET_SUCCESS)
5887 		return -1;
5888 
5889 	return 0;
5890 }
5891 
rtw_halmac_bf_cfg_mu_mimo(struct dvobj_priv * d,enum halmac_snd_role role,u8 * sounding_sts,u16 grouping_bitmap,u8 mu_tx_en,u32 * given_gid_tab,u32 * given_user_pos)5892 int rtw_halmac_bf_cfg_mu_mimo(struct dvobj_priv *d, enum halmac_snd_role role,
5893 		u8 *sounding_sts, u16 grouping_bitmap, u8 mu_tx_en,
5894 		u32 *given_gid_tab, u32 *given_user_pos)
5895 {
5896 	struct halmac_adapter *mac;
5897 	struct halmac_api *api;
5898 	enum halmac_ret_status status;
5899 	struct halmac_cfg_mumimo_para param;
5900 
5901 
5902 	mac = dvobj_to_halmac(d);
5903 	api = HALMAC_GET_API(mac);
5904 
5905 	_rtw_memset(&param, 0, sizeof(param));
5906 
5907 	param.role = role;
5908 	param.grouping_bitmap = grouping_bitmap;
5909 	param.mu_tx_en = mu_tx_en;
5910 
5911 	if (sounding_sts)
5912 		_rtw_memcpy(param.sounding_sts, sounding_sts, 6);
5913 
5914 	if (given_gid_tab)
5915 		_rtw_memcpy(param.given_gid_tab, given_gid_tab, 8);
5916 
5917 	if (given_user_pos)
5918 		_rtw_memcpy(param.given_user_pos, given_user_pos, 16);
5919 
5920 	status = api->halmac_cfg_mumimo(mac, &param);
5921 	if (status != HALMAC_RET_SUCCESS)
5922 		return -1;
5923 
5924 	return 0;
5925 }
5926 
5927 #endif /* RTW_BEAMFORMING_VERSION_2 */
5928 #endif /* CONFIG_BEAMFORMING */
5929