xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/rtl8723ds/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_ret_status status;
1223 	int err = 0;
1224 #ifdef CONFIG_SDIO_HCI
1225 	struct halmac_sdio_hw_info info;
1226 #endif /* CONFIG_SDIO_HCI */
1227 
1228 
1229 	halmac = dvobj_to_halmac(d);
1230 	if (halmac) {
1231 		RTW_WARN("%s: initialize already completed!\n", __FUNCTION__);
1232 		goto error;
1233 	}
1234 
1235 	err = init_priv(&d->hmpriv);
1236 	if (err)
1237 		goto error;
1238 
1239 #ifdef CONFIG_SDIO_HCI
1240 	intf = HALMAC_INTERFACE_SDIO;
1241 #elif defined(CONFIG_USB_HCI)
1242 	intf = HALMAC_INTERFACE_USB;
1243 #elif defined(CONFIG_PCI_HCI)
1244 	intf = HALMAC_INTERFACE_PCIE;
1245 #else
1246 #warning "INTERFACE(CONFIG_XXX_HCI) not be defined!!"
1247 	intf = HALMAC_INTERFACE_UNDEFINE;
1248 #endif
1249 	status = halmac_init_adapter(d, pf_api, intf, &halmac, &api);
1250 	if (HALMAC_RET_SUCCESS != status) {
1251 		RTW_ERR("%s: halmac_init_adapter fail!(status=%d)\n", __FUNCTION__, status);
1252 		err = -1;
1253 		if (halmac)
1254 			goto deinit;
1255 		goto free;
1256 	}
1257 
1258 	dvobj_set_halmac(d, halmac);
1259 
1260 	status = api->halmac_interface_integration_tuning(halmac);
1261 	if (status != HALMAC_RET_SUCCESS) {
1262 		RTW_ERR("%s: halmac_interface_integration_tuning fail!(status=%d)\n", __FUNCTION__, status);
1263 		err = -1;
1264 		goto deinit;
1265 	}
1266 
1267 	status = api->halmac_phy_cfg(halmac, HALMAC_INTF_PHY_PLATFORM_ALL);
1268 	if (status != HALMAC_RET_SUCCESS) {
1269 		RTW_ERR("%s: halmac_phy_cfg fail!(status=%d)\n", __FUNCTION__, status);
1270 		err = -1;
1271 		goto deinit;
1272 	}
1273 
1274 	init_write_rsvd_page_size(d);
1275 
1276 #ifdef CONFIG_SDIO_HCI
1277 	_rtw_memset(&info, 0, sizeof(info));
1278 	info.spec_ver = _sdio_ver_drv2halmac(d);
1279 	/* Convert clock speed unit to MHz from Hz */
1280 	info.clock_speed = RTW_DIV_ROUND_UP(rtw_sdio_get_clock(d), 1000000);
1281 	info.block_size = rtw_sdio_get_block_size(d);
1282 	if (d->hmpriv.sdio_io_indir == 2)
1283 		info.io_indir_flag = 0;
1284 	else
1285 		info.io_indir_flag = 1; /* Default enable indirect I/O */
1286 	RTW_DBG("%s: SDIO ver=%u clock=%uMHz blk_size=%u bytes, io_indir=%u\n",
1287 		__FUNCTION__, info.spec_ver+2, info.clock_speed,
1288 		info.block_size, info.io_indir_flag);
1289 	status = api->halmac_sdio_hw_info(halmac, &info);
1290 	if (status != HALMAC_RET_SUCCESS) {
1291 		RTW_ERR("%s: halmac_sdio_hw_info fail!(status=%d)\n",
1292 			__FUNCTION__, status);
1293 		err = -1;
1294 		goto deinit;
1295 	}
1296 #endif /* CONFIG_SDIO_HCI */
1297 
1298 	return 0;
1299 
1300 deinit:
1301 	status = halmac_deinit_adapter(halmac);
1302 	dvobj_set_halmac(d, NULL);
1303 	if (status != HALMAC_RET_SUCCESS)
1304 		RTW_ERR("%s: halmac_deinit_adapter fail!(status=%d)\n",
1305 			__FUNCTION__, status);
1306 
1307 free:
1308 	deinit_priv(&d->hmpriv);
1309 
1310 error:
1311 	return err;
1312 }
1313 
rtw_halmac_deinit_adapter(struct dvobj_priv * d)1314 int rtw_halmac_deinit_adapter(struct dvobj_priv *d)
1315 {
1316 	struct halmac_adapter *halmac;
1317 	enum halmac_ret_status status;
1318 	int err = 0;
1319 
1320 
1321 	halmac = dvobj_to_halmac(d);
1322 	if (halmac) {
1323 		status = halmac_deinit_adapter(halmac);
1324 		dvobj_set_halmac(d, NULL);
1325 		if (status != HALMAC_RET_SUCCESS)
1326 			err = -1;
1327 	}
1328 
1329 	deinit_priv(&d->hmpriv);
1330 
1331 	return err;
1332 }
1333 
_hw_port_drv2halmac(enum _hw_port hwport)1334 static inline enum halmac_portid _hw_port_drv2halmac(enum _hw_port hwport)
1335 {
1336 	enum halmac_portid port = HALMAC_PORTID_NUM;
1337 
1338 
1339 	switch (hwport) {
1340 	case HW_PORT0:
1341 		port = HALMAC_PORTID0;
1342 		break;
1343 	case HW_PORT1:
1344 		port = HALMAC_PORTID1;
1345 		break;
1346 	case HW_PORT2:
1347 		port = HALMAC_PORTID2;
1348 		break;
1349 	case HW_PORT3:
1350 		port = HALMAC_PORTID3;
1351 		break;
1352 	case HW_PORT4:
1353 		port = HALMAC_PORTID4;
1354 		break;
1355 	default:
1356 		break;
1357 	}
1358 
1359 	return port;
1360 }
1361 
_network_type_drv2halmac(u8 type)1362 static enum halmac_network_type_select _network_type_drv2halmac(u8 type)
1363 {
1364 	enum halmac_network_type_select network = HALMAC_NETWORK_UNDEFINE;
1365 
1366 
1367 	switch (type) {
1368 	case _HW_STATE_NOLINK_:
1369 	case _HW_STATE_MONITOR_:
1370 		network = HALMAC_NETWORK_NO_LINK;
1371 		break;
1372 
1373 	case _HW_STATE_ADHOC_:
1374 		network = HALMAC_NETWORK_ADHOC;
1375 		break;
1376 
1377 	case _HW_STATE_STATION_:
1378 		network = HALMAC_NETWORK_INFRASTRUCTURE;
1379 		break;
1380 
1381 	case _HW_STATE_AP_:
1382 		network = HALMAC_NETWORK_AP;
1383 		break;
1384 	}
1385 
1386 	return network;
1387 }
1388 
_network_type_halmac2drv(enum halmac_network_type_select network)1389 static u8 _network_type_halmac2drv(enum halmac_network_type_select network)
1390 {
1391 	u8 type = _HW_STATE_NOLINK_;
1392 
1393 
1394 	switch (network) {
1395 	case HALMAC_NETWORK_NO_LINK:
1396 	case HALMAC_NETWORK_UNDEFINE:
1397 		type = _HW_STATE_NOLINK_;
1398 		break;
1399 
1400 	case HALMAC_NETWORK_ADHOC:
1401 		type = _HW_STATE_ADHOC_;
1402 		break;
1403 
1404 	case HALMAC_NETWORK_INFRASTRUCTURE:
1405 		type = _HW_STATE_STATION_;
1406 		break;
1407 
1408 	case HALMAC_NETWORK_AP:
1409 		type = _HW_STATE_AP_;
1410 		break;
1411 	}
1412 
1413 	return type;
1414 }
1415 
_beacon_ctrl_halmac2drv(struct halmac_bcn_ctrl * ctrl,struct rtw_halmac_bcn_ctrl * drv_ctrl)1416 static void _beacon_ctrl_halmac2drv(struct halmac_bcn_ctrl *ctrl,
1417 				struct rtw_halmac_bcn_ctrl *drv_ctrl)
1418 {
1419 	drv_ctrl->rx_bssid_fit = ctrl->dis_rx_bssid_fit ? 0 : 1;
1420 	drv_ctrl->txbcn_rpt = ctrl->en_txbcn_rpt ? 1 : 0;
1421 	drv_ctrl->tsf_update = ctrl->dis_tsf_udt ? 0 : 1;
1422 	drv_ctrl->enable_bcn = ctrl->en_bcn ? 1 : 0;
1423 	drv_ctrl->rxbcn_rpt = ctrl->en_rxbcn_rpt ? 1 : 0;
1424 	drv_ctrl->p2p_ctwin = ctrl->en_p2p_ctwin ? 1 : 0;
1425 	drv_ctrl->p2p_bcn_area = ctrl->en_p2p_bcn_area ? 1 : 0;
1426 }
1427 
_beacon_ctrl_drv2halmac(struct rtw_halmac_bcn_ctrl * drv_ctrl,struct halmac_bcn_ctrl * ctrl)1428 static void _beacon_ctrl_drv2halmac(struct rtw_halmac_bcn_ctrl *drv_ctrl,
1429 				struct halmac_bcn_ctrl *ctrl)
1430 {
1431 	ctrl->dis_rx_bssid_fit = drv_ctrl->rx_bssid_fit ? 0 : 1;
1432 	ctrl->en_txbcn_rpt = drv_ctrl->txbcn_rpt ? 1 : 0;
1433 	ctrl->dis_tsf_udt = drv_ctrl->tsf_update ? 0 : 1;
1434 	ctrl->en_bcn = drv_ctrl->enable_bcn ? 1 : 0;
1435 	ctrl->en_rxbcn_rpt = drv_ctrl->rxbcn_rpt ? 1 : 0;
1436 	ctrl->en_p2p_ctwin = drv_ctrl->p2p_ctwin ? 1 : 0;
1437 	ctrl->en_p2p_bcn_area = drv_ctrl->p2p_bcn_area ? 1 : 0;
1438 }
1439 
rtw_halmac_get_hw_value(struct dvobj_priv * d,enum halmac_hw_id hw_id,void * pvalue)1440 int rtw_halmac_get_hw_value(struct dvobj_priv *d, enum halmac_hw_id hw_id, void *pvalue)
1441 {
1442 	struct halmac_adapter *mac;
1443 	struct halmac_api *api;
1444 	enum halmac_ret_status status;
1445 
1446 
1447 	mac = dvobj_to_halmac(d);
1448 	api = HALMAC_GET_API(mac);
1449 
1450 	status = api->halmac_get_hw_value(mac, hw_id, pvalue);
1451 	if (HALMAC_RET_SUCCESS != status)
1452 		return -1;
1453 
1454 	return 0;
1455 }
1456 
1457 /**
1458  * rtw_halmac_get_tx_fifo_size() - TX FIFO size
1459  * @d:		struct dvobj_priv*
1460  * @size:	TX FIFO size, unit is byte.
1461  *
1462  * Get TX FIFO size(byte) from HALMAC.
1463  *
1464  * Return 0 for OK, otherwise fail.
1465  */
rtw_halmac_get_tx_fifo_size(struct dvobj_priv * d,u32 * size)1466 int rtw_halmac_get_tx_fifo_size(struct dvobj_priv *d, u32 *size)
1467 {
1468 	struct halmac_adapter *halmac;
1469 	struct halmac_api *api;
1470 	enum halmac_ret_status status;
1471 	u32 val = 0;
1472 
1473 
1474 	halmac = dvobj_to_halmac(d);
1475 	api = HALMAC_GET_API(halmac);
1476 
1477 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_TXFIFO_SIZE, &val);
1478 	if (status != HALMAC_RET_SUCCESS)
1479 		return -1;
1480 
1481 	*size = val;
1482 
1483 	return 0;
1484 }
1485 
1486 /**
1487  * rtw_halmac_get_rx_fifo_size() - RX FIFO size
1488  * @d:		struct dvobj_priv*
1489  * @size:	RX FIFO size, unit is byte
1490  *
1491  * Get RX FIFO size(byte) from HALMAC.
1492  *
1493  * Return 0 for OK, otherwise fail.
1494  */
rtw_halmac_get_rx_fifo_size(struct dvobj_priv * d,u32 * size)1495 int rtw_halmac_get_rx_fifo_size(struct dvobj_priv *d, u32 *size)
1496 {
1497 	struct halmac_adapter *halmac;
1498 	struct halmac_api *api;
1499 	enum halmac_ret_status status;
1500 	u32 val = 0;
1501 
1502 
1503 	halmac = dvobj_to_halmac(d);
1504 	api = HALMAC_GET_API(halmac);
1505 
1506 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RXFIFO_SIZE, &val);
1507 	if (status != HALMAC_RET_SUCCESS)
1508 		return -1;
1509 
1510 	*size = val;
1511 
1512 	return 0;
1513 }
1514 
1515 /**
1516  * rtw_halmac_get_rsvd_drv_pg_bndy() - Reserve page boundary of driver
1517  * @d:		struct dvobj_priv*
1518  * @size:	Page size, unit is byte
1519  *
1520  * Get reserve page boundary of driver from HALMAC.
1521  *
1522  * Return 0 for OK, otherwise fail.
1523  */
rtw_halmac_get_rsvd_drv_pg_bndy(struct dvobj_priv * d,u16 * bndy)1524 int rtw_halmac_get_rsvd_drv_pg_bndy(struct dvobj_priv *d, u16 *bndy)
1525 {
1526 	struct halmac_adapter *halmac;
1527 	struct halmac_api *api;
1528 	enum halmac_ret_status status;
1529 	u16 val = 0;
1530 
1531 
1532 	halmac = dvobj_to_halmac(d);
1533 	api = HALMAC_GET_API(halmac);
1534 
1535 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RSVD_PG_BNDY, &val);
1536 	if (status != HALMAC_RET_SUCCESS)
1537 		return -1;
1538 
1539 	*bndy = val;
1540 
1541 	return 0;
1542 }
1543 
1544 /**
1545  * rtw_halmac_get_page_size() - Page size
1546  * @d:		struct dvobj_priv*
1547  * @size:	Page size, unit is byte
1548  *
1549  * Get TX/RX page size(byte) from HALMAC.
1550  *
1551  * Return 0 for OK, otherwise fail.
1552  */
rtw_halmac_get_page_size(struct dvobj_priv * d,u32 * size)1553 int rtw_halmac_get_page_size(struct dvobj_priv *d, u32 *size)
1554 {
1555 	struct halmac_adapter *halmac;
1556 	struct halmac_api *api;
1557 	enum halmac_ret_status status;
1558 	u32 val = 0;
1559 
1560 
1561 	halmac = dvobj_to_halmac(d);
1562 	api = HALMAC_GET_API(halmac);
1563 
1564 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_PAGE_SIZE, &val);
1565 	if (status != HALMAC_RET_SUCCESS)
1566 		return -1;
1567 
1568 	*size = val;
1569 
1570 	return 0;
1571 }
1572 
1573 /**
1574  * rtw_halmac_get_tx_agg_align_size() - TX aggregation align size
1575  * @d:		struct dvobj_priv*
1576  * @size:	TX aggregation align size, unit is byte
1577  *
1578  * Get TX aggregation align size(byte) from HALMAC.
1579  *
1580  * Return 0 for OK, otherwise fail.
1581  */
rtw_halmac_get_tx_agg_align_size(struct dvobj_priv * d,u16 * size)1582 int rtw_halmac_get_tx_agg_align_size(struct dvobj_priv *d, u16 *size)
1583 {
1584 	struct halmac_adapter *halmac;
1585 	struct halmac_api *api;
1586 	enum halmac_ret_status status;
1587 	u16 val = 0;
1588 
1589 
1590 	halmac = dvobj_to_halmac(d);
1591 	api = HALMAC_GET_API(halmac);
1592 
1593 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_TX_AGG_ALIGN_SIZE, &val);
1594 	if (status != HALMAC_RET_SUCCESS)
1595 		return -1;
1596 
1597 	*size = val;
1598 
1599 	return 0;
1600 }
1601 
1602 /**
1603  * rtw_halmac_get_rx_agg_align_size() - RX aggregation align size
1604  * @d:		struct dvobj_priv*
1605  * @size:	RX aggregation align size, unit is byte
1606  *
1607  * Get RX aggregation align size(byte) from HALMAC.
1608  *
1609  * Return 0 for OK, otherwise fail.
1610  */
rtw_halmac_get_rx_agg_align_size(struct dvobj_priv * d,u8 * size)1611 int rtw_halmac_get_rx_agg_align_size(struct dvobj_priv *d, u8 *size)
1612 {
1613 	struct halmac_adapter *halmac;
1614 	struct halmac_api *api;
1615 	enum halmac_ret_status status;
1616 	u8 val = 0;
1617 
1618 
1619 	halmac = dvobj_to_halmac(d);
1620 	api = HALMAC_GET_API(halmac);
1621 
1622 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RX_AGG_ALIGN_SIZE, &val);
1623 	if (status != HALMAC_RET_SUCCESS)
1624 		return -1;
1625 
1626 	*size = val;
1627 
1628 	return 0;
1629 }
1630 
1631 /*
1632  * Description:
1633  *	Get RX driver info size. RX driver info is a small memory space between
1634  *	scriptor and RX payload.
1635  *
1636  *	+-------------------------+
1637  *	| RX descriptor           |
1638  *	| usually 24 bytes        |
1639  *	+-------------------------+
1640  *	| RX driver info          |
1641  *	| depends on driver cfg   |
1642  *	+-------------------------+
1643  *	| RX paylad               |
1644  *	|                         |
1645  *	+-------------------------+
1646  *
1647  * Parameter:
1648  *	d	pointer to struct dvobj_priv of driver
1649  *	sz	rx driver info size in bytes.
1650  *
1651  * Return:
1652  *	0	Success
1653  *	other	Fail
1654  */
rtw_halmac_get_rx_drv_info_sz(struct dvobj_priv * d,u8 * sz)1655 int rtw_halmac_get_rx_drv_info_sz(struct dvobj_priv *d, u8 *sz)
1656 {
1657 	enum halmac_ret_status status;
1658 	struct halmac_adapter *halmac = dvobj_to_halmac(d);
1659 	struct halmac_api *api = HALMAC_GET_API(halmac);
1660 	u8 dw = 0;
1661 
1662 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_DRV_INFO_SIZE, &dw);
1663 	if (status != HALMAC_RET_SUCCESS)
1664 		return -1;
1665 
1666 	*sz = dw * 8;
1667 	return 0;
1668 }
1669 
1670 /**
1671  * rtw_halmac_get_tx_desc_size() - TX descriptor size
1672  * @d:		struct dvobj_priv*
1673  * @size:	TX descriptor size, unit is byte.
1674  *
1675  * Get TX descriptor size(byte) from HALMAC.
1676  *
1677  * Return 0 for OK, otherwise fail.
1678  */
rtw_halmac_get_tx_desc_size(struct dvobj_priv * d,u32 * size)1679 int rtw_halmac_get_tx_desc_size(struct dvobj_priv *d, u32 *size)
1680 {
1681 	struct halmac_adapter *halmac;
1682 	struct halmac_api *api;
1683 	enum halmac_ret_status status;
1684 	u32 val = 0;
1685 
1686 
1687 	halmac = dvobj_to_halmac(d);
1688 	api = HALMAC_GET_API(halmac);
1689 
1690 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_TX_DESC_SIZE, &val);
1691 	if (status != HALMAC_RET_SUCCESS)
1692 		return -1;
1693 
1694 	*size = val;
1695 
1696 	return 0;
1697 }
1698 
1699 /**
1700  * rtw_halmac_get_rx_desc_size() - RX descriptor size
1701  * @d:		struct dvobj_priv*
1702  * @size:	RX descriptor size, unit is byte.
1703  *
1704  * Get RX descriptor size(byte) from HALMAC.
1705  *
1706  * Return 0 for OK, otherwise fail.
1707  */
rtw_halmac_get_rx_desc_size(struct dvobj_priv * d,u32 * size)1708 int rtw_halmac_get_rx_desc_size(struct dvobj_priv *d, u32 *size)
1709 {
1710 	struct halmac_adapter *halmac;
1711 	struct halmac_api *api;
1712 	enum halmac_ret_status status;
1713 	u32 val = 0;
1714 
1715 
1716 	halmac = dvobj_to_halmac(d);
1717 	api = HALMAC_GET_API(halmac);
1718 
1719 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RX_DESC_SIZE, &val);
1720 	if (status != HALMAC_RET_SUCCESS)
1721 		return -1;
1722 
1723 	*size = val;
1724 
1725 	return 0;
1726 }
1727 
1728 /**
1729  * rtw_halmac_get_tx_dma_ch_map() - Get TX DMA channel Map for tx desc
1730  * @d:		struct dvobj_priv*
1731  * @dma_ch_map:	return map of QSEL to DMA channel
1732  * @map_size:	size of dma_ch_map
1733  *		Suggest size to be last valid QSEL(QSLT_CMD)+1 or full QSLT
1734  *		size(0x20)
1735  *
1736  * 8814B would need this to get mapping of QSEL to DMA channel for TX desc.
1737  *
1738  * Return 0 for OK, otherwise fail.
1739  */
rtw_halmac_get_tx_dma_ch_map(struct dvobj_priv * d,u8 * dma_ch_map,u8 map_size)1740 int rtw_halmac_get_tx_dma_ch_map(struct dvobj_priv *d, u8 *dma_ch_map, u8 map_size)
1741 {
1742 	struct halmac_adapter *halmac;
1743 	struct halmac_api *api;
1744 	enum halmac_ret_status status;
1745 	struct halmac_rqpn_ch_map map;
1746 	enum halmac_dma_ch channel = HALMAC_DMA_CH_UNDEFINE;
1747 	u8 qsel;
1748 
1749 
1750 	halmac = dvobj_to_halmac(d);
1751 	api = HALMAC_GET_API(halmac);
1752 
1753 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RQPN_CH_MAPPING, &map);
1754 	if (status != HALMAC_RET_SUCCESS)
1755 		return -1;
1756 
1757 	for (qsel = 0; qsel < map_size; qsel++) {
1758 		switch (qsel) {
1759 		/*case QSLT_VO:*/
1760 		case 0x06:
1761 		case 0x07:
1762 			channel = map.dma_map_vo;
1763 			break;
1764 		/*case QSLT_VI:*/
1765 		case 0x04:
1766 		case 0x05:
1767 			channel = map.dma_map_vi;
1768 			break;
1769 		/*case QSLT_BE:*/
1770 		case 0x00:
1771 		case 0x03:
1772 			channel = map.dma_map_be;
1773 			break;
1774 		/*case QSLT_BK:*/
1775 		case 0x01:
1776 		case 0x02:
1777 			channel = map.dma_map_bk;
1778 			break;
1779 		/*case QSLT_BEACON:*/
1780 		case 0x10:
1781 			channel = HALMAC_DMA_CH_BCN;
1782 			break;
1783 		/*case QSLT_HIGH:*/
1784 		case 0x11:
1785 			channel = map.dma_map_hi;
1786 			break;
1787 		/*case QSLT_MGNT:*/
1788 		case 0x12:
1789 			channel = map.dma_map_mg;
1790 			break;
1791 		/*case QSLT_CMD:*/
1792 		case 0x13:
1793 			channel = HALMAC_DMA_CH_H2C;
1794 			break;
1795 		default:
1796 			/*RTW_ERR("%s: invalid qsel=0x%x\n", __FUNCTION__, qsel);*/
1797 			channel = HALMAC_DMA_CH_UNDEFINE;
1798 			break;
1799 		}
1800 		dma_ch_map[qsel] = (u8)channel;
1801 	}
1802 
1803 	return 0;
1804 }
1805 
1806 /**
1807  * rtw_halmac_get_fw_max_size() - Firmware MAX size
1808  * @d:		struct dvobj_priv*
1809  * @size:	MAX Firmware size, unit is byte.
1810  *
1811  * Get Firmware MAX size(byte) from HALMAC.
1812  *
1813  * Return 0 for OK, otherwise fail.
1814  */
rtw_halmac_get_fw_max_size(struct dvobj_priv * d,u32 * size)1815 static int rtw_halmac_get_fw_max_size(struct dvobj_priv *d, u32 *size)
1816 {
1817 	struct halmac_adapter *halmac;
1818 	struct halmac_api *api;
1819 	enum halmac_ret_status status;
1820 	u32 val = 0;
1821 
1822 
1823 	halmac = dvobj_to_halmac(d);
1824 	api = HALMAC_GET_API(halmac);
1825 
1826 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_FW_MAX_SIZE, &val);
1827 	if (status != HALMAC_RET_SUCCESS)
1828 		return -1;
1829 
1830 	*size = val;
1831 
1832 	return 0;
1833 }
1834 
1835 /**
1836  * rtw_halmac_get_ori_h2c_size() - Original H2C MAX size
1837  * @d:		struct dvobj_priv*
1838  * @size:	H2C MAX size, unit is byte.
1839  *
1840  * Get original H2C MAX size(byte) from HALMAC.
1841  *
1842  * Return 0 for OK, otherwise fail.
1843  */
rtw_halmac_get_ori_h2c_size(struct dvobj_priv * d,u32 * size)1844 int rtw_halmac_get_ori_h2c_size(struct dvobj_priv *d, u32 *size)
1845 {
1846 	struct halmac_adapter *halmac;
1847 	struct halmac_api *api;
1848 	enum halmac_ret_status status;
1849 	u32 val = 0;
1850 
1851 
1852 	halmac = dvobj_to_halmac(d);
1853 	api = HALMAC_GET_API(halmac);
1854 
1855 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_ORI_H2C_SIZE, &val);
1856 	if (status != HALMAC_RET_SUCCESS)
1857 		return -1;
1858 
1859 	*size = val;
1860 
1861 	return 0;
1862 }
1863 
rtw_halmac_get_oqt_size(struct dvobj_priv * d,u8 * size)1864 int rtw_halmac_get_oqt_size(struct dvobj_priv *d, u8 *size)
1865 {
1866 	enum halmac_ret_status status;
1867 	struct halmac_adapter *halmac;
1868 	struct halmac_api *api;
1869 	u8 val;
1870 
1871 
1872 	if (!size)
1873 		return -1;
1874 
1875 	halmac = dvobj_to_halmac(d);
1876 	api = HALMAC_GET_API(halmac);
1877 
1878 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_AC_OQT_SIZE, &val);
1879 	if (status != HALMAC_RET_SUCCESS)
1880 		return -1;
1881 
1882 	*size = val;
1883 	return 0;
1884 }
1885 
rtw_halmac_get_ac_queue_number(struct dvobj_priv * d,u8 * num)1886 int rtw_halmac_get_ac_queue_number(struct dvobj_priv *d, u8 *num)
1887 {
1888 	enum halmac_ret_status status;
1889 	struct halmac_adapter *halmac;
1890 	struct halmac_api *api;
1891 	u8 val;
1892 
1893 
1894 	if (!num)
1895 		return -1;
1896 
1897 	halmac = dvobj_to_halmac(d);
1898 	api = HALMAC_GET_API(halmac);
1899 
1900 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_AC_QUEUE_NUM, &val);
1901 	if (status != HALMAC_RET_SUCCESS)
1902 		return -1;
1903 
1904 	*num = val;
1905 	return 0;
1906 }
1907 
1908 /**
1909  * rtw_halmac_get_mac_address() - Get MAC address of specific port
1910  * @d:		struct dvobj_priv*
1911  * @hwport:	port
1912  * @addr:	buffer for storing MAC address
1913  *
1914  * Get MAC address of specific port from HALMAC.
1915  *
1916  * Return 0 for OK, otherwise fail.
1917  */
rtw_halmac_get_mac_address(struct dvobj_priv * d,enum _hw_port hwport,u8 * addr)1918 int rtw_halmac_get_mac_address(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
1919 {
1920 	struct halmac_adapter *halmac;
1921 	struct halmac_api *api;
1922 	enum halmac_portid port;
1923 	union halmac_wlan_addr hwa;
1924 	enum halmac_ret_status status;
1925 	int err = -1;
1926 
1927 
1928 	if (!addr)
1929 		goto out;
1930 
1931 	halmac = dvobj_to_halmac(d);
1932 	api = HALMAC_GET_API(halmac);
1933 	port = _hw_port_drv2halmac(hwport);
1934 	_rtw_memset(&hwa, 0, sizeof(hwa));
1935 
1936 	status = api->halmac_get_mac_addr(halmac, port, &hwa);
1937 	if (status != HALMAC_RET_SUCCESS)
1938 		goto out;
1939 
1940 	_rtw_memcpy(addr, hwa.addr, 6);
1941 
1942 	err = 0;
1943 out:
1944 	return err;
1945 }
1946 
1947 /**
1948  * rtw_halmac_get_network_type() - Get network type of specific port
1949  * @d:		struct dvobj_priv*
1950  * @hwport:	port
1951  * @type:	buffer to put network type (_HW_STATE_*)
1952  *
1953  * Get network type of specific port from HALMAC.
1954  *
1955  * Return 0 for OK, otherwise fail.
1956  */
rtw_halmac_get_network_type(struct dvobj_priv * d,enum _hw_port hwport,u8 * type)1957 int rtw_halmac_get_network_type(struct dvobj_priv *d, enum _hw_port hwport, u8 *type)
1958 {
1959 #if 0
1960 	struct halmac_adapter *halmac;
1961 	struct halmac_api *api;
1962 	enum halmac_portid port;
1963 	enum halmac_network_type_select network;
1964 	enum halmac_ret_status status;
1965 	int err = -1;
1966 
1967 
1968 	halmac = dvobj_to_halmac(d);
1969 	api = HALMAC_GET_API(halmac);
1970 	port = _hw_port_drv2halmac(hwport);
1971 	network = HALMAC_NETWORK_UNDEFINE;
1972 
1973 	status = api->halmac_get_net_type(halmac, port, &network);
1974 	if (status != HALMAC_RET_SUCCESS)
1975 		goto out;
1976 
1977 	*type = _network_type_halmac2drv(network);
1978 
1979 	err = 0;
1980 out:
1981 	return err;
1982 #else
1983 	struct _ADAPTER *a;
1984 	enum halmac_portid port;
1985 	enum halmac_network_type_select network;
1986 	u32 val;
1987 	int err = -1;
1988 
1989 
1990 	a = dvobj_get_primary_adapter(d);
1991 	port = _hw_port_drv2halmac(hwport);
1992 	network = HALMAC_NETWORK_UNDEFINE;
1993 
1994 	switch (port) {
1995 	case HALMAC_PORTID0:
1996 		val = rtw_read32(a, REG_CR);
1997 		network = BIT_GET_NETYPE0(val);
1998 		break;
1999 
2000 	case HALMAC_PORTID1:
2001 		val = rtw_read32(a, REG_CR);
2002 		network = BIT_GET_NETYPE1(val);
2003 		break;
2004 
2005 	case HALMAC_PORTID2:
2006 		val = rtw_read32(a, REG_CR_EXT);
2007 		network = BIT_GET_NETYPE2(val);
2008 		break;
2009 
2010 	case HALMAC_PORTID3:
2011 		val = rtw_read32(a, REG_CR_EXT);
2012 		network = BIT_GET_NETYPE3(val);
2013 		break;
2014 
2015 	case HALMAC_PORTID4:
2016 		val = rtw_read32(a, REG_CR_EXT);
2017 		network = BIT_GET_NETYPE4(val);
2018 		break;
2019 
2020 	default:
2021 		goto out;
2022 	}
2023 
2024 	*type = _network_type_halmac2drv(network);
2025 
2026 	err = 0;
2027 out:
2028 	return err;
2029 #endif
2030 }
2031 
2032 /**
2033  * rtw_halmac_get_bcn_ctrl() - Get beacon control setting of specific port
2034  * @d:		struct dvobj_priv*
2035  * @hwport:	port
2036  * @bcn_ctrl:	setting of beacon control
2037  *
2038  * Get beacon control setting of specific port from HALMAC.
2039  *
2040  * Return 0 for OK, otherwise fail.
2041  */
rtw_halmac_get_bcn_ctrl(struct dvobj_priv * d,enum _hw_port hwport,struct rtw_halmac_bcn_ctrl * bcn_ctrl)2042 int rtw_halmac_get_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,
2043 			struct rtw_halmac_bcn_ctrl *bcn_ctrl)
2044 {
2045 	struct halmac_adapter *halmac;
2046 	struct halmac_api *api;
2047 	enum halmac_portid port;
2048 	struct halmac_bcn_ctrl ctrl;
2049 	enum halmac_ret_status status;
2050 	int err = -1;
2051 
2052 
2053 	halmac = dvobj_to_halmac(d);
2054 	api = HALMAC_GET_API(halmac);
2055 	port = _hw_port_drv2halmac(hwport);
2056 	_rtw_memset(&ctrl, 0, sizeof(ctrl));
2057 
2058 	status = api->halmac_rw_bcn_ctrl(halmac, port, 0, &ctrl);
2059 	if (status != HALMAC_RET_SUCCESS)
2060 		goto out;
2061 	_beacon_ctrl_halmac2drv(&ctrl, bcn_ctrl);
2062 
2063 	err = 0;
2064 out:
2065 	return err;
2066 }
2067 
2068 /*
2069  * Note:
2070  *	When this function return, the register REG_RCR may be changed.
2071  */
rtw_halmac_config_rx_info(struct dvobj_priv * d,enum halmac_drv_info info)2072 int rtw_halmac_config_rx_info(struct dvobj_priv *d, enum halmac_drv_info info)
2073 {
2074 	struct halmac_adapter *halmac;
2075 	struct halmac_api *api;
2076 	enum halmac_ret_status status;
2077 	int err = -1;
2078 
2079 
2080 	halmac = dvobj_to_halmac(d);
2081 	api = HALMAC_GET_API(halmac);
2082 
2083 	status = api->halmac_cfg_drv_info(halmac, info);
2084 	if (status != HALMAC_RET_SUCCESS)
2085 		goto out;
2086 
2087 	err = 0;
2088 out:
2089 	/* Sync driver RCR cache with register setting */
2090 	rtw_hal_get_hwreg(dvobj_get_primary_adapter(d), HW_VAR_RCR, NULL);
2091 
2092 	return err;
2093 }
2094 
2095 /**
2096  * rtw_halmac_set_max_dl_fw_size() - Set the MAX download firmware size
2097  * @d:		struct dvobj_priv*
2098  * @size:	the max download firmware size in one I/O
2099  *
2100  * Set the max download firmware size in one I/O.
2101  * Please also consider the max size of the callback function "SEND_RSVD_PAGE"
2102  * could accept, because download firmware would call "SEND_RSVD_PAGE" to send
2103  * firmware to IC.
2104  *
2105  * If the value of "size" is not even, it would be rounded down to nearest
2106  * even, and 0 and 1 are both invalid value.
2107  *
2108  * Return 0 for setting OK, otherwise fail.
2109  */
rtw_halmac_set_max_dl_fw_size(struct dvobj_priv * d,u32 size)2110 int rtw_halmac_set_max_dl_fw_size(struct dvobj_priv *d, u32 size)
2111 {
2112 	struct halmac_adapter *mac;
2113 	struct halmac_api *api;
2114 	enum halmac_ret_status status;
2115 
2116 
2117 	if (!size || (size == 1))
2118 		return -1;
2119 
2120 	mac = dvobj_to_halmac(d);
2121 	if (!mac) {
2122 		RTW_ERR("%s: HALMAC is not ready!!\n", __FUNCTION__);
2123 		return -1;
2124 	}
2125 	api = HALMAC_GET_API(mac);
2126 
2127 	size &= ~1; /* round down to even */
2128 	status = api->halmac_cfg_max_dl_size(mac, size);
2129 	if (status != HALMAC_RET_SUCCESS) {
2130 		RTW_WARN("%s: Fail to cfg_max_dl_size(%d), err=%d!!\n",
2131 			 __FUNCTION__, size, status);
2132 		return -1;
2133 	}
2134 
2135 	return 0;
2136 }
2137 
2138 /**
2139  * rtw_halmac_set_mac_address() - Set mac address of specific port
2140  * @d:		struct dvobj_priv*
2141  * @hwport:	port
2142  * @addr:	mac address
2143  *
2144  * Set self mac address of specific port to HALMAC.
2145  *
2146  * Return 0 for OK, otherwise fail.
2147  */
rtw_halmac_set_mac_address(struct dvobj_priv * d,enum _hw_port hwport,u8 * addr)2148 int rtw_halmac_set_mac_address(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
2149 {
2150 	struct halmac_adapter *halmac;
2151 	struct halmac_api *api;
2152 	enum halmac_portid port;
2153 	union halmac_wlan_addr hwa;
2154 	enum halmac_ret_status status;
2155 	int err = -1;
2156 
2157 
2158 	halmac = dvobj_to_halmac(d);
2159 	api = HALMAC_GET_API(halmac);
2160 
2161 	port = _hw_port_drv2halmac(hwport);
2162 	_rtw_memset(&hwa, 0, sizeof(hwa));
2163 	_rtw_memcpy(hwa.addr, addr, 6);
2164 
2165 	status = api->halmac_cfg_mac_addr(halmac, port, &hwa);
2166 	if (status != HALMAC_RET_SUCCESS)
2167 		goto out;
2168 
2169 	err = 0;
2170 out:
2171 	return err;
2172 }
2173 
2174 /**
2175  * rtw_halmac_set_bssid() - Set BSSID of specific port
2176  * @d:		struct dvobj_priv*
2177  * @hwport:	port
2178  * @addr:	BSSID, mac address of AP
2179  *
2180  * Set BSSID of specific port to HALMAC.
2181  *
2182  * Return 0 for OK, otherwise fail.
2183  */
rtw_halmac_set_bssid(struct dvobj_priv * d,enum _hw_port hwport,u8 * addr)2184 int rtw_halmac_set_bssid(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
2185 {
2186 	struct halmac_adapter *halmac;
2187 	struct halmac_api *api;
2188 	enum halmac_portid port;
2189 	union halmac_wlan_addr hwa;
2190 	enum halmac_ret_status status;
2191 	int err = -1;
2192 
2193 
2194 	halmac = dvobj_to_halmac(d);
2195 	api = HALMAC_GET_API(halmac);
2196 	port = _hw_port_drv2halmac(hwport);
2197 
2198 	_rtw_memset(&hwa, 0, sizeof(hwa));
2199 	_rtw_memcpy(hwa.addr, addr, 6);
2200 	status = api->halmac_cfg_bssid(halmac, port, &hwa);
2201 	if (status != HALMAC_RET_SUCCESS)
2202 		goto out;
2203 
2204 	err = 0;
2205 out:
2206 	return err;
2207 }
2208 
2209 /**
2210  * rtw_halmac_set_tx_address() - Set transmitter address of specific port
2211  * @d:		struct dvobj_priv*
2212  * @hwport:	port
2213  * @addr:	transmitter address
2214  *
2215  * Set transmitter address of specific port to HALMAC.
2216  *
2217  * Return 0 for OK, otherwise fail.
2218  */
rtw_halmac_set_tx_address(struct dvobj_priv * d,enum _hw_port hwport,u8 * addr)2219 int rtw_halmac_set_tx_address(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
2220 {
2221 	struct halmac_adapter *halmac;
2222 	struct halmac_api *api;
2223 	enum halmac_portid port;
2224 	union halmac_wlan_addr hwa;
2225 	enum halmac_ret_status status;
2226 	int err = -1;
2227 
2228 
2229 	halmac = dvobj_to_halmac(d);
2230 	api = HALMAC_GET_API(halmac);
2231 	port = _hw_port_drv2halmac(hwport);
2232 	_rtw_memset(&hwa, 0, sizeof(hwa));
2233 	_rtw_memcpy(hwa.addr, addr, 6);
2234 
2235 	status = api->halmac_cfg_transmitter_addr(halmac, port, &hwa);
2236 	if (status != HALMAC_RET_SUCCESS)
2237 		goto out;
2238 
2239 	err = 0;
2240 out:
2241 	return err;
2242 }
2243 
2244 /**
2245  * rtw_halmac_set_network_type() - Set network type of specific port
2246  * @d:		struct dvobj_priv*
2247  * @hwport:	port
2248  * @type:	network type (_HW_STATE_*)
2249  *
2250  * Set network type of specific port to HALMAC.
2251  *
2252  * Return 0 for OK, otherwise fail.
2253  */
rtw_halmac_set_network_type(struct dvobj_priv * d,enum _hw_port hwport,u8 type)2254 int rtw_halmac_set_network_type(struct dvobj_priv *d, enum _hw_port hwport, u8 type)
2255 {
2256 	struct halmac_adapter *halmac;
2257 	struct halmac_api *api;
2258 	enum halmac_portid port;
2259 	enum halmac_network_type_select network;
2260 	enum halmac_ret_status status;
2261 	int err = -1;
2262 
2263 
2264 	halmac = dvobj_to_halmac(d);
2265 	api = HALMAC_GET_API(halmac);
2266 	port = _hw_port_drv2halmac(hwport);
2267 	network = _network_type_drv2halmac(type);
2268 
2269 	status = api->halmac_cfg_net_type(halmac, port, network);
2270 	if (status != HALMAC_RET_SUCCESS)
2271 		goto out;
2272 
2273 	err = 0;
2274 out:
2275 	return err;
2276 }
2277 
2278 /**
2279  * rtw_halmac_reset_tsf() - Reset TSF timer of specific port
2280  * @d:		struct dvobj_priv*
2281  * @hwport:	port
2282  *
2283  * Notice HALMAC to reset timing synchronization function(TSF) timer of
2284  * specific port.
2285  *
2286  * Return 0 for OK, otherwise fail.
2287  */
rtw_halmac_reset_tsf(struct dvobj_priv * d,enum _hw_port hwport)2288 int rtw_halmac_reset_tsf(struct dvobj_priv *d, enum _hw_port hwport)
2289 {
2290 	struct halmac_adapter *halmac;
2291 	struct halmac_api *api;
2292 	enum halmac_portid port;
2293 	enum halmac_ret_status status;
2294 	int err = -1;
2295 
2296 
2297 	halmac = dvobj_to_halmac(d);
2298 	api = HALMAC_GET_API(halmac);
2299 	port = _hw_port_drv2halmac(hwport);
2300 
2301 	status = api->halmac_cfg_tsf_rst(halmac, port);
2302 	if (status != HALMAC_RET_SUCCESS)
2303 		goto out;
2304 
2305 	err = 0;
2306 out:
2307 	return err;
2308 }
2309 
2310 /**
2311  * rtw_halmac_set_bcn_interval() - Set beacon interval of each port
2312  * @d:		struct dvobj_priv*
2313  * @hwport:	port
2314  * @space:	beacon interval, unit is ms
2315  *
2316  * Set beacon interval of specific port to HALMAC.
2317  *
2318  * Return 0 for OK, otherwise fail.
2319  */
rtw_halmac_set_bcn_interval(struct dvobj_priv * d,enum _hw_port hwport,u32 interval)2320 int rtw_halmac_set_bcn_interval(struct dvobj_priv *d, enum _hw_port hwport,
2321 				u32 interval)
2322 {
2323 	struct halmac_adapter *halmac;
2324 	struct halmac_api *api;
2325 	enum halmac_portid port;
2326 	enum halmac_ret_status status;
2327 	int err = -1;
2328 
2329 
2330 	halmac = dvobj_to_halmac(d);
2331 	api = HALMAC_GET_API(halmac);
2332 	port = _hw_port_drv2halmac(hwport);
2333 
2334 	status = api->halmac_cfg_bcn_space(halmac, port, interval);
2335 	if (status != HALMAC_RET_SUCCESS)
2336 		goto out;
2337 
2338 	err = 0;
2339 out:
2340 	return err;
2341 }
2342 
2343 /**
2344  * rtw_halmac_set_bcn_ctrl() - Set beacon control setting of each port
2345  * @d:		struct dvobj_priv*
2346  * @hwport:	port
2347  * @bcn_ctrl:	setting of beacon control
2348  *
2349  * Set beacon control setting of specific port to HALMAC.
2350  *
2351  * Return 0 for OK, otherwise fail.
2352  */
rtw_halmac_set_bcn_ctrl(struct dvobj_priv * d,enum _hw_port hwport,struct rtw_halmac_bcn_ctrl * bcn_ctrl)2353 int rtw_halmac_set_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,
2354 			struct rtw_halmac_bcn_ctrl *bcn_ctrl)
2355 {
2356 	struct halmac_adapter *halmac;
2357 	struct halmac_api *api;
2358 	enum halmac_portid port;
2359 	struct halmac_bcn_ctrl ctrl;
2360 	enum halmac_ret_status status;
2361 	int err = -1;
2362 
2363 
2364 	halmac = dvobj_to_halmac(d);
2365 	api = HALMAC_GET_API(halmac);
2366 	port = _hw_port_drv2halmac(hwport);
2367 	_rtw_memset(&ctrl, 0, sizeof(ctrl));
2368 	_beacon_ctrl_drv2halmac(bcn_ctrl, &ctrl);
2369 
2370 	status = api->halmac_rw_bcn_ctrl(halmac, port, 1, &ctrl);
2371 	if (status != HALMAC_RET_SUCCESS)
2372 		goto out;
2373 
2374 	err = 0;
2375 out:
2376 	return err;
2377 }
2378 
2379 /**
2380  * rtw_halmac_set_aid() - Set association identifier(AID) of specific port
2381  * @d:		struct dvobj_priv*
2382  * @hwport:	port
2383  * @aid:	Association identifier
2384  *
2385  * Set association identifier(AID) of specific port to HALMAC.
2386  *
2387  * Return 0 for OK, otherwise fail.
2388  */
rtw_halmac_set_aid(struct dvobj_priv * d,enum _hw_port hwport,u16 aid)2389 int rtw_halmac_set_aid(struct dvobj_priv *d, enum _hw_port hwport, u16 aid)
2390 {
2391 	struct halmac_adapter *halmac;
2392 	struct halmac_api *api;
2393 	enum halmac_portid port;
2394 	enum halmac_ret_status status;
2395 	int err = -1;
2396 
2397 
2398 	halmac = dvobj_to_halmac(d);
2399 	api = HALMAC_GET_API(halmac);
2400 	port = _hw_port_drv2halmac(hwport);
2401 
2402 #if 0
2403 	status = api->halmac_cfg_aid(halmac, port, aid);
2404 	if (status != HALMAC_RET_SUCCESS)
2405 		goto out;
2406 #else
2407 {
2408 	struct _ADAPTER *a;
2409 	u32 addr;
2410 	u16 val;
2411 
2412 	a = dvobj_get_primary_adapter(d);
2413 
2414 	switch (port) {
2415 	case 0:
2416 		addr = REG_BCN_PSR_RPT;
2417 		val = rtw_read16(a, addr);
2418 		val = BIT_SET_PS_AID_0(val, aid);
2419 		rtw_write16(a, addr, val);
2420 		break;
2421 
2422 	case 1:
2423 		addr = REG_BCN_PSR_RPT1;
2424 		val = rtw_read16(a, addr);
2425 		val = BIT_SET_PS_AID_1(val, aid);
2426 		rtw_write16(a, addr, val);
2427 		break;
2428 
2429 	case 2:
2430 		addr = REG_BCN_PSR_RPT2;
2431 		val = rtw_read16(a, addr);
2432 		val = BIT_SET_PS_AID_2(val, aid);
2433 		rtw_write16(a, addr, val);
2434 		break;
2435 
2436 	case 3:
2437 		addr = REG_BCN_PSR_RPT3;
2438 		val = rtw_read16(a, addr);
2439 		val = BIT_SET_PS_AID_3(val, aid);
2440 		rtw_write16(a, addr, val);
2441 		break;
2442 
2443 	case 4:
2444 		addr = REG_BCN_PSR_RPT4;
2445 		val = rtw_read16(a, addr);
2446 		val = BIT_SET_PS_AID_4(val, aid);
2447 		rtw_write16(a, addr, val);
2448 		break;
2449 
2450 	default:
2451 		goto out;
2452 	}
2453 }
2454 #endif
2455 
2456 	err = 0;
2457 out:
2458 	return err;
2459 }
2460 
rtw_halmac_set_bandwidth(struct dvobj_priv * d,u8 channel,u8 pri_ch_idx,u8 bw)2461 int rtw_halmac_set_bandwidth(struct dvobj_priv *d, u8 channel, u8 pri_ch_idx, u8 bw)
2462 {
2463 	struct halmac_adapter *mac;
2464 	struct halmac_api *api;
2465 	enum halmac_ret_status status;
2466 
2467 
2468 	mac = dvobj_to_halmac(d);
2469 	api = HALMAC_GET_API(mac);
2470 
2471 	status = api->halmac_cfg_ch_bw(mac, channel, pri_ch_idx, bw);
2472 	if (HALMAC_RET_SUCCESS != status)
2473 		return -1;
2474 
2475 	return 0;
2476 }
2477 
2478 /**
2479  * rtw_halmac_set_edca() - config edca parameter
2480  * @d:		struct dvobj_priv*
2481  * @queue:	XMIT_[VO/VI/BE/BK]_QUEUE
2482  * @aifs:	Arbitration inter-frame space(AIFS)
2483  * @cw:		Contention window(CW)
2484  * @txop:	MAX Transmit Opportunity(TXOP)
2485  *
2486  * Return: 0 if process OK, otherwise -1.
2487  */
rtw_halmac_set_edca(struct dvobj_priv * d,u8 queue,u8 aifs,u8 cw,u16 txop)2488 int rtw_halmac_set_edca(struct dvobj_priv *d, u8 queue, u8 aifs, u8 cw, u16 txop)
2489 {
2490 	struct halmac_adapter *mac;
2491 	struct halmac_api *api;
2492 	enum halmac_acq_id ac;
2493 	struct halmac_edca_para edca;
2494 	enum halmac_ret_status status;
2495 
2496 
2497 	mac = dvobj_to_halmac(d);
2498 	api = HALMAC_GET_API(mac);
2499 
2500 	switch (queue) {
2501 	case XMIT_VO_QUEUE:
2502 		ac = HALMAC_ACQ_ID_VO;
2503 		break;
2504 	case XMIT_VI_QUEUE:
2505 		ac = HALMAC_ACQ_ID_VI;
2506 		break;
2507 	case XMIT_BE_QUEUE:
2508 		ac = HALMAC_ACQ_ID_BE;
2509 		break;
2510 	case XMIT_BK_QUEUE:
2511 		ac = HALMAC_ACQ_ID_BK;
2512 		break;
2513 	default:
2514 		return -1;
2515 	}
2516 
2517 	edca.aifs = aifs;
2518 	edca.cw = cw;
2519 	edca.txop_limit = txop;
2520 
2521 	status = api->halmac_cfg_edca_para(mac, ac, &edca);
2522 	if (status != HALMAC_RET_SUCCESS)
2523 		return -1;
2524 
2525 	return 0;
2526 }
2527 
2528 /**
2529  * rtw_halmac_set_rts_full_bw() - Send RTS to all covered channels
2530  * @d:		struct dvobj_priv*
2531  * @enable:	_TRUE(enable), _FALSE(disable)
2532  *
2533  * Hradware will duplicate RTS packet to all channels which are covered in used
2534  * bandwidth.
2535  *
2536  * Return 0 if process OK, otherwise -1.
2537  */
rtw_halmac_set_rts_full_bw(struct dvobj_priv * d,u8 enable)2538 int rtw_halmac_set_rts_full_bw(struct dvobj_priv *d, u8 enable)
2539 {
2540 	struct halmac_adapter *mac;
2541 	struct halmac_api *api;
2542 	enum halmac_ret_status status;
2543 	u8 full;
2544 
2545 
2546 	mac = dvobj_to_halmac(d);
2547 	api = HALMAC_GET_API(mac);
2548 	full = (enable == _TRUE) ? 1 : 0;
2549 
2550 	status = api->halmac_set_hw_value(mac, HALMAC_HW_RTS_FULL_BW, &full);
2551 	if (HALMAC_RET_SUCCESS != status)
2552 		return -1;
2553 
2554 	return 0;
2555 }
2556 
2557 #ifdef RTW_HALMAC_DBG_POWER_SWITCH
_dump_mac_reg(struct dvobj_priv * d,u32 start,u32 end)2558 static void _dump_mac_reg(struct dvobj_priv *d, u32 start, u32 end)
2559 {
2560 	struct _ADAPTER *adapter;
2561 	int i, j = 1;
2562 
2563 
2564 	adapter = dvobj_get_primary_adapter(d);
2565 	for (i = start; i < end; i += 4) {
2566 		if (j % 4 == 1)
2567 			RTW_PRINT("0x%04x", i);
2568 		_RTW_PRINT(" 0x%08x ", rtw_read32(adapter, i));
2569 		if ((j++) % 4 == 0)
2570 			_RTW_PRINT("\n");
2571 	}
2572 }
2573 
dump_dbg_val(struct _ADAPTER * a,u32 reg)2574 void dump_dbg_val(struct _ADAPTER *a, u32 reg)
2575 {
2576 	u32 v32;
2577 
2578 
2579 	rtw_write8(a, 0x3A, reg);
2580 	v32 = rtw_read32(a, 0xC0);
2581 	RTW_PRINT("0x3A = %02x, 0xC0 = 0x%08x\n",reg, v32);
2582 }
2583 
2584 #ifdef CONFIG_PCI_HCI
_dump_pcie_cfg_space(struct dvobj_priv * d)2585 static void _dump_pcie_cfg_space(struct dvobj_priv *d)
2586 {
2587 	struct _ADAPTER *padapter = dvobj_get_primary_adapter(d);
2588 	struct dvobj_priv       *pdvobjpriv = adapter_to_dvobj(padapter);
2589 	struct pci_dev  *pdev = pdvobjpriv->ppcidev;
2590 	struct pci_dev  *bridge_pdev = pdev->bus->self;
2591 
2592         u32 tmp[4] = { 0 };
2593         u32 i, j;
2594 
2595 	RTW_PRINT("\n*****  PCI Device Configuration Space *****\n\n");
2596 
2597         for(i = 0; i < 0x100; i += 0x10)
2598         {
2599                 for (j = 0 ; j < 4 ; j++)
2600                         pci_read_config_dword(pdev, i + j * 4, tmp+j);
2601 
2602         	RTW_PRINT("%03x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
2603                         i, tmp[0] & 0xFF, (tmp[0] >> 8) & 0xFF, (tmp[0] >> 16) & 0xFF, (tmp[0] >> 24) & 0xFF,
2604                         tmp[1] & 0xFF, (tmp[1] >> 8) & 0xFF, (tmp[1] >> 16) & 0xFF, (tmp[1] >> 24) & 0xFF,
2605                         tmp[2] & 0xFF, (tmp[2] >> 8) & 0xFF, (tmp[2] >> 16) & 0xFF, (tmp[2] >> 24) & 0xFF,
2606                         tmp[3] & 0xFF, (tmp[3] >> 8) & 0xFF, (tmp[3] >> 16) & 0xFF, (tmp[3] >> 24) & 0xFF);
2607         }
2608 
2609 	RTW_PRINT("\n*****  PCI Host Device Configuration Space*****\n\n");
2610 
2611         for(i = 0; i < 0x100; i += 0x10)
2612         {
2613                 for (j = 0 ; j < 4 ; j++)
2614                         pci_read_config_dword(bridge_pdev, i + j * 4, tmp+j);
2615 
2616         	RTW_PRINT("%03x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
2617                         i, tmp[0] & 0xFF, (tmp[0] >> 8) & 0xFF, (tmp[0] >> 16) & 0xFF, (tmp[0] >> 24) & 0xFF,
2618                         tmp[1] & 0xFF, (tmp[1] >> 8) & 0xFF, (tmp[1] >> 16) & 0xFF, (tmp[1] >> 24) & 0xFF,
2619                         tmp[2] & 0xFF, (tmp[2] >> 8) & 0xFF, (tmp[2] >> 16) & 0xFF, (tmp[2] >> 24) & 0xFF,
2620                         tmp[3] & 0xFF, (tmp[3] >> 8) & 0xFF, (tmp[3] >> 16) & 0xFF, (tmp[3] >> 24) & 0xFF);
2621         }
2622 }
2623 #endif
2624 
_dump_mac_reg_for_power_switch(struct dvobj_priv * d,const char * caller,char * desc)2625 static void _dump_mac_reg_for_power_switch(struct dvobj_priv *d,
2626 					   const char* caller, char* desc)
2627 {
2628 	struct _ADAPTER *a;
2629 	u8 v8;
2630 
2631 
2632 	RTW_PRINT("%s: %s\n", caller, desc);
2633 	RTW_PRINT("======= MAC REG =======\n");
2634 	/* page 0/1 */
2635 	_dump_mac_reg(d, 0x0, 0x200);
2636 	_dump_mac_reg(d, 0x300, 0x400); /* also dump page 3 */
2637 
2638 	/* dump debug register */
2639 	a = dvobj_get_primary_adapter(d);
2640 
2641 #ifdef CONFIG_PCI_HCI
2642 	_dump_pcie_cfg_space(d);
2643 
2644 	v8 = rtw_read8(a, 0xF6) | 0x01;
2645 	rtw_write8(a, 0xF6, v8);
2646 	RTW_PRINT("0xF6 = %02x\n", v8);
2647 
2648 	dump_dbg_val(a, 0x63);
2649 	dump_dbg_val(a, 0x64);
2650 	dump_dbg_val(a, 0x68);
2651 	dump_dbg_val(a, 0x69);
2652 	dump_dbg_val(a, 0x6a);
2653 	dump_dbg_val(a, 0x6b);
2654 	dump_dbg_val(a, 0x71);
2655 	dump_dbg_val(a, 0x72);
2656 #endif
2657 }
2658 
_power_switch(struct halmac_adapter * halmac,struct halmac_api * api,enum halmac_mac_power pwr)2659 static enum halmac_ret_status _power_switch(struct halmac_adapter *halmac,
2660 					    struct halmac_api *api,
2661 					    enum halmac_mac_power pwr)
2662 {
2663 	enum halmac_ret_status status;
2664 	char desc[80] = {0};
2665 
2666 
2667 	rtw_sprintf(desc, 80, "before calling power %s",
2668 				(pwr==HALMAC_MAC_POWER_ON)?"on":"off");
2669 	_dump_mac_reg_for_power_switch((struct dvobj_priv *)halmac->drv_adapter,
2670 			__FUNCTION__, desc);
2671 
2672 	status = api->halmac_mac_power_switch(halmac, pwr);
2673 	RTW_PRINT("%s: status=%d\n", __FUNCTION__, status);
2674 
2675 	rtw_sprintf(desc, 80, "after calling power %s",
2676 				(pwr==HALMAC_MAC_POWER_ON)?"on":"off");
2677 	_dump_mac_reg_for_power_switch((struct dvobj_priv *)halmac->drv_adapter,
2678 			__FUNCTION__, desc);
2679 
2680 	return status;
2681 }
2682 #else /* !RTW_HALMAC_DBG_POWER_SWITCH */
2683 #define _power_switch(mac, api, pwr)	(api)->halmac_mac_power_switch(mac, pwr)
2684 #endif /* !RTW_HALMAC_DBG_POWER_SWITCH */
2685 
2686 /*
2687  * Description:
2688  *	Power on device hardware.
2689  *	[Notice!] If device's power state is on before,
2690  *	it would be power off first and turn on power again.
2691  *
2692  * Return:
2693  *	0	power on success
2694  *	-1	power on fail
2695  *	-2	power state unchange
2696  */
rtw_halmac_poweron(struct dvobj_priv * d)2697 int rtw_halmac_poweron(struct dvobj_priv *d)
2698 {
2699 	struct halmac_adapter *halmac;
2700 	struct halmac_api *api;
2701 	enum halmac_ret_status status;
2702 	int err = -1;
2703 #if defined(CONFIG_PCI_HCI) && defined(CONFIG_RTL8822B)
2704 	struct _ADAPTER *a;
2705 	u8 v8;
2706 	u32 addr;
2707 
2708 	a = dvobj_get_primary_adapter(d);
2709 #endif
2710 
2711 	halmac = dvobj_to_halmac(d);
2712 	if (!halmac)
2713 		goto out;
2714 
2715 	api = HALMAC_GET_API(halmac);
2716 
2717 	status = api->halmac_pre_init_system_cfg(halmac);
2718 	if (status != HALMAC_RET_SUCCESS)
2719 		goto out;
2720 
2721 #ifdef CONFIG_SDIO_HCI
2722 	status = api->halmac_sdio_cmd53_4byte(halmac, HALMAC_SDIO_CMD53_4BYTE_MODE_RW);
2723 	if (status != HALMAC_RET_SUCCESS)
2724 		goto out;
2725 #endif /* CONFIG_SDIO_HCI */
2726 
2727 #if defined(CONFIG_PCI_HCI) && defined(CONFIG_RTL8822B)
2728 	addr = 0x3F3;
2729 	v8 = rtw_read8(a, addr);
2730 	RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v8);
2731 	/* are we in pcie debug mode? */
2732 	if (!(v8 & BIT(2))) {
2733 		RTW_PRINT("%s: Enable pcie debug mode\n", __FUNCTION__);
2734 		v8 |= BIT(2);
2735 		v8 = rtw_write8(a, addr, v8);
2736 	}
2737 #endif
2738 
2739 	status = _power_switch(halmac, api, HALMAC_MAC_POWER_ON);
2740 	if (HALMAC_RET_PWR_UNCHANGE == status) {
2741 
2742 #if defined(CONFIG_PCI_HCI) && defined(CONFIG_RTL8822B)
2743 		addr = 0x3F3;
2744 		v8 = rtw_read8(a, addr);
2745 		RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v8);
2746 
2747 		/* are we in pcie debug mode? */
2748 		if (!(v8 & BIT(2))) {
2749 			RTW_PRINT("%s: Enable pcie debug mode\n", __FUNCTION__);
2750 			v8 |= BIT(2);
2751 			v8 = rtw_write8(a, addr, v8);
2752 		} else if (v8 & BIT(0)) {
2753 			/* DMA stuck */
2754 			addr = 0x1350;
2755 			v8 = rtw_read8(a, addr);
2756 			RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v8);
2757 			RTW_PRINT("%s: recover DMA stuck\n", __FUNCTION__);
2758 			v8 |= BIT(6);
2759 			v8 = rtw_write8(a, addr, v8);
2760 			RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v8);
2761 		}
2762 #endif
2763 		/*
2764 		 * Work around for warm reboot but device not power off,
2765 		 * but it would also fall into this case when auto power on is enabled.
2766 		 */
2767 		_power_switch(halmac, api, HALMAC_MAC_POWER_OFF);
2768 		status = _power_switch(halmac, api, HALMAC_MAC_POWER_ON);
2769 		RTW_WARN("%s: Power state abnormal, try to recover...%s\n",
2770 			 __FUNCTION__, (HALMAC_RET_SUCCESS == status)?"OK":"FAIL!");
2771 	}
2772 	if (HALMAC_RET_SUCCESS != status) {
2773 		if (HALMAC_RET_PWR_UNCHANGE == status)
2774 			err = -2;
2775 		goto out;
2776 	}
2777 
2778 	status = api->halmac_init_system_cfg(halmac);
2779 	if (status != HALMAC_RET_SUCCESS)
2780 		goto out;
2781 
2782 	err = 0;
2783 out:
2784 	return err;
2785 }
2786 
2787 /*
2788  * Description:
2789  *	Power off device hardware.
2790  *
2791  * Return:
2792  *	0	Power off success
2793  *	-1	Power off fail
2794  */
rtw_halmac_poweroff(struct dvobj_priv * d)2795 int rtw_halmac_poweroff(struct dvobj_priv *d)
2796 {
2797 	struct halmac_adapter *halmac;
2798 	struct halmac_api *api;
2799 	enum halmac_ret_status status;
2800 	int err = -1;
2801 
2802 
2803 	halmac = dvobj_to_halmac(d);
2804 	if (!halmac)
2805 		goto out;
2806 
2807 	api = HALMAC_GET_API(halmac);
2808 
2809 	status = _power_switch(halmac, api, HALMAC_MAC_POWER_OFF);
2810 	if ((HALMAC_RET_SUCCESS != status)
2811 	    && (HALMAC_RET_PWR_UNCHANGE != status))
2812 		goto out;
2813 
2814 	err = 0;
2815 out:
2816 	return err;
2817 }
2818 
2819 #ifdef CONFIG_SUPPORT_TRX_SHARED
_trx_share_mode_drv2halmac(u8 trx_share_mode)2820 static inline enum halmac_rx_fifo_expanding_mode _trx_share_mode_drv2halmac(u8 trx_share_mode)
2821 {
2822 	if (0 == trx_share_mode)
2823 		return HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE;
2824 	else if (1 == trx_share_mode)
2825 		return HALMAC_RX_FIFO_EXPANDING_MODE_1_BLOCK;
2826 	else if (2 == trx_share_mode)
2827 		return HALMAC_RX_FIFO_EXPANDING_MODE_2_BLOCK;
2828 	else if (3 == trx_share_mode)
2829 		return HALMAC_RX_FIFO_EXPANDING_MODE_3_BLOCK;
2830 	else
2831 		return HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE;
2832 }
2833 
_rtw_get_trx_share_mode(struct _ADAPTER * adapter)2834 static enum halmac_rx_fifo_expanding_mode _rtw_get_trx_share_mode(struct _ADAPTER *adapter)
2835 {
2836 	struct registry_priv *registry_par = &adapter->registrypriv;
2837 
2838 	return _trx_share_mode_drv2halmac(registry_par->trx_share_mode);
2839 }
2840 
dump_trx_share_mode(void * sel,struct _ADAPTER * adapter)2841 void dump_trx_share_mode(void *sel, struct _ADAPTER *adapter)
2842 {
2843 	struct registry_priv  *registry_par = &adapter->registrypriv;
2844 	u8 mode = _trx_share_mode_drv2halmac(registry_par->trx_share_mode);
2845 
2846 	if (HALMAC_RX_FIFO_EXPANDING_MODE_1_BLOCK == mode)
2847 		RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "RX_FIFO_EXPANDING_MODE_1");
2848 	else if (HALMAC_RX_FIFO_EXPANDING_MODE_2_BLOCK == mode)
2849 		RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "RX_FIFO_EXPANDING_MODE_2");
2850 	else if (HALMAC_RX_FIFO_EXPANDING_MODE_3_BLOCK == mode)
2851 		RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "RX_FIFO_EXPANDING_MODE_3");
2852 	else
2853 		RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "DISABLE");
2854 }
2855 #endif
2856 
_rsvd_page_num_drv2halmac(u16 num)2857 static enum halmac_drv_rsvd_pg_num _rsvd_page_num_drv2halmac(u16 num)
2858 {
2859 	if (num <= 8)
2860 		return HALMAC_RSVD_PG_NUM8;
2861 	if (num <= 16)
2862 		return HALMAC_RSVD_PG_NUM16;
2863 	if (num <= 24)
2864 		return HALMAC_RSVD_PG_NUM24;
2865 	if (num <= 32)
2866 		return HALMAC_RSVD_PG_NUM32;
2867 	if (num <= 64)
2868 		return HALMAC_RSVD_PG_NUM64;
2869 	if (num <= 128)
2870 		return HALMAC_RSVD_PG_NUM128;
2871 
2872 	if (num > 256)
2873 		RTW_WARN("%s: Fail to allocate RSVD page(%d)!!"
2874 			 " The MAX RSVD page number is 256...\n",
2875 			 __FUNCTION__, num);
2876 
2877 	return HALMAC_RSVD_PG_NUM256;
2878 }
2879 
_rsvd_page_num_halmac2drv(enum halmac_drv_rsvd_pg_num rsvd_page_number)2880 static u16 _rsvd_page_num_halmac2drv(enum halmac_drv_rsvd_pg_num rsvd_page_number)
2881 {
2882 	u16 num = 0;
2883 
2884 
2885 	switch (rsvd_page_number) {
2886 	case HALMAC_RSVD_PG_NUM8:
2887 		num = 8;
2888 		break;
2889 
2890 	case HALMAC_RSVD_PG_NUM16:
2891 		num = 16;
2892 		break;
2893 
2894 	case HALMAC_RSVD_PG_NUM24:
2895 		num = 24;
2896 		break;
2897 
2898 	case HALMAC_RSVD_PG_NUM32:
2899 		num = 32;
2900 		break;
2901 
2902 	case HALMAC_RSVD_PG_NUM64:
2903 		num = 64;
2904 		break;
2905 
2906 	case HALMAC_RSVD_PG_NUM128:
2907 		num = 128;
2908 		break;
2909 
2910 	case HALMAC_RSVD_PG_NUM256:
2911 		num = 256;
2912 		break;
2913 	}
2914 
2915 	return num;
2916 }
2917 
_choose_trx_mode(struct dvobj_priv * d)2918 static enum halmac_trx_mode _choose_trx_mode(struct dvobj_priv *d)
2919 {
2920 	PADAPTER p;
2921 
2922 
2923 	p = dvobj_get_primary_adapter(d);
2924 
2925 	if (p->registrypriv.wifi_spec)
2926 		return HALMAC_TRX_MODE_WMM;
2927 
2928 #ifdef CONFIG_SUPPORT_TRX_SHARED
2929 	if (_rtw_get_trx_share_mode(p))
2930 		return HALMAC_TRX_MODE_TRXSHARE;
2931 #endif
2932 
2933 	return HALMAC_TRX_MODE_NORMAL;
2934 }
2935 
_rf_type_drv2halmac(enum rf_type rf_drv)2936 static inline enum halmac_rf_type _rf_type_drv2halmac(enum rf_type rf_drv)
2937 {
2938 	enum halmac_rf_type rf_mac;
2939 
2940 
2941 	switch (rf_drv) {
2942 	case RF_1T1R:
2943 		rf_mac = HALMAC_RF_1T1R;
2944 		break;
2945 	case RF_1T2R:
2946 		rf_mac = HALMAC_RF_1T2R;
2947 		break;
2948 	case RF_2T2R:
2949 		rf_mac = HALMAC_RF_2T2R;
2950 		break;
2951 	case RF_2T3R:
2952 		rf_mac = HALMAC_RF_2T3R;
2953 		break;
2954 	case RF_2T4R:
2955 		rf_mac = HALMAC_RF_2T4R;
2956 		break;
2957 	case RF_3T3R:
2958 		rf_mac = HALMAC_RF_3T3R;
2959 		break;
2960 	case RF_3T4R:
2961 		rf_mac = HALMAC_RF_3T4R;
2962 		break;
2963 	case RF_4T4R:
2964 		rf_mac = HALMAC_RF_4T4R;
2965 		break;
2966 	default:
2967 		rf_mac = HALMAC_RF_MAX_TYPE;
2968 		RTW_ERR("%s: Invalid RF type(0x%x)!\n", __FUNCTION__, rf_drv);
2969 		break;
2970 	}
2971 
2972 	return rf_mac;
2973 }
2974 
_rf_type_halmac2drv(enum halmac_rf_type rf_mac)2975 static inline enum rf_type _rf_type_halmac2drv(enum halmac_rf_type rf_mac)
2976 {
2977 	enum rf_type rf_drv;
2978 
2979 
2980 	switch (rf_mac) {
2981 	case HALMAC_RF_1T2R:
2982 		rf_drv = RF_1T2R;
2983 		break;
2984 	case HALMAC_RF_2T4R:
2985 		rf_drv = RF_2T4R;
2986 		break;
2987 	case HALMAC_RF_2T2R:
2988 	case HALMAC_RF_2T2R_GREEN:
2989 		rf_drv = RF_2T2R;
2990 		break;
2991 	case HALMAC_RF_2T3R:
2992 		rf_drv = RF_2T3R;
2993 		break;
2994 	case HALMAC_RF_1T1R:
2995 		rf_drv = RF_1T1R;
2996 		break;
2997 	case HALMAC_RF_3T3R:
2998 		rf_drv = RF_3T3R;
2999 		break;
3000 	case HALMAC_RF_3T4R:
3001 		rf_drv = RF_3T4R;
3002 		break;
3003 	case HALMAC_RF_4T4R:
3004 		rf_drv = RF_4T4R;
3005 		break;
3006 	default:
3007 		rf_drv = RF_TYPE_MAX;
3008 		RTW_ERR("%s: Invalid RF type(0x%x)!\n", __FUNCTION__, rf_mac);
3009 		break;
3010 	}
3011 
3012 	return rf_drv;
3013 }
3014 
_cut_version_drv2phydm(enum tag_HAL_Cut_Version_Definition cut_drv)3015 static enum odm_cut_version _cut_version_drv2phydm(
3016 				enum tag_HAL_Cut_Version_Definition cut_drv)
3017 {
3018 	enum odm_cut_version cut_phydm = ODM_CUT_A;
3019 	u32 diff;
3020 
3021 
3022 	if (cut_drv > K_CUT_VERSION)
3023 		RTW_WARN("%s: unknown cut_ver=%d !!\n", __FUNCTION__, cut_drv);
3024 
3025 	diff = cut_drv - A_CUT_VERSION;
3026 	cut_phydm += diff;
3027 
3028 	return cut_phydm;
3029 }
3030 
_send_general_info_by_reg(struct dvobj_priv * d,struct halmac_general_info * info)3031 static int _send_general_info_by_reg(struct dvobj_priv *d,
3032 				     struct halmac_general_info *info)
3033 {
3034 	struct _ADAPTER *a;
3035 	struct hal_com_data *hal;
3036 	enum tag_HAL_Cut_Version_Definition cut_drv;
3037 	enum rf_type rftype;
3038 	enum odm_cut_version cut_phydm;
3039 	u8 h2c[RTW_HALMAC_H2C_MAX_SIZE] = {0};
3040 
3041 
3042 	a = dvobj_get_primary_adapter(d);
3043 	hal = GET_HAL_DATA(a);
3044 	rftype = _rf_type_halmac2drv(info->rf_type);
3045 	cut_drv = GET_CVID_CUT_VERSION(hal->version_id);
3046 	cut_phydm = _cut_version_drv2phydm(cut_drv);
3047 
3048 #define CLASS_GENERAL_INFO_REG				0x02
3049 #define CMD_ID_GENERAL_INFO_REG				0x0C
3050 #define GENERAL_INFO_REG_SET_CMD_ID(buf, v)		SET_BITS_TO_LE_4BYTE(buf, 0, 5, v)
3051 #define GENERAL_INFO_REG_SET_CLASS(buf, v)		SET_BITS_TO_LE_4BYTE(buf, 5, 3, v)
3052 #define GENERAL_INFO_REG_SET_RFE_TYPE(buf, v)		SET_BITS_TO_LE_4BYTE(buf, 8, 8, v)
3053 #define GENERAL_INFO_REG_SET_RF_TYPE(buf, v)		SET_BITS_TO_LE_4BYTE(buf, 16, 8, v)
3054 #define GENERAL_INFO_REG_SET_CUT_VERSION(buf, v)	SET_BITS_TO_LE_4BYTE(buf, 24, 8, v)
3055 #define GENERAL_INFO_REG_SET_RX_ANT_STATUS(buf, v)	SET_BITS_TO_LE_1BYTE(buf+4, 0, 4, v)
3056 #define GENERAL_INFO_REG_SET_TX_ANT_STATUS(buf, v)	SET_BITS_TO_LE_1BYTE(buf+4, 4, 4, v)
3057 
3058 	GENERAL_INFO_REG_SET_CMD_ID(h2c, CMD_ID_GENERAL_INFO_REG);
3059 	GENERAL_INFO_REG_SET_CLASS(h2c, CLASS_GENERAL_INFO_REG);
3060 	GENERAL_INFO_REG_SET_RFE_TYPE(h2c, info->rfe_type);
3061 	GENERAL_INFO_REG_SET_RF_TYPE(h2c, rftype);
3062 	GENERAL_INFO_REG_SET_CUT_VERSION(h2c, cut_phydm);
3063 	GENERAL_INFO_REG_SET_RX_ANT_STATUS(h2c, info->rx_ant_status);
3064 	GENERAL_INFO_REG_SET_TX_ANT_STATUS(h2c, info->tx_ant_status);
3065 
3066 	return rtw_halmac_send_h2c(d, h2c);
3067 }
3068 
_send_general_info(struct dvobj_priv * d)3069 static int _send_general_info(struct dvobj_priv *d)
3070 {
3071 	struct _ADAPTER *adapter;
3072 	struct hal_com_data *hal;
3073 	struct halmac_adapter *halmac;
3074 	struct halmac_api *api;
3075 	struct halmac_general_info info;
3076 	enum halmac_ret_status status;
3077 	enum rf_type rf = RF_1T1R;
3078 	enum bb_path txpath = BB_PATH_A;
3079 	enum bb_path rxpath = BB_PATH_A;
3080 	int err;
3081 
3082 
3083 	adapter = dvobj_get_primary_adapter(d);
3084 	hal = GET_HAL_DATA(adapter);
3085 	halmac = dvobj_to_halmac(d);
3086 	if (!halmac)
3087 		return -1;
3088 	api = HALMAC_GET_API(halmac);
3089 
3090 	_rtw_memset(&info, 0, sizeof(info));
3091 	info.rfe_type = (u8)hal->rfe_type;
3092 	rtw_hal_get_trx_path(d, &rf, &txpath, &rxpath);
3093 	info.rf_type = _rf_type_drv2halmac(rf);
3094 	info.tx_ant_status = (u8)txpath;
3095 	info.rx_ant_status = (u8)rxpath;
3096 	info.ext_pa = 0;	/* 2.4G or 5G? format not known */
3097 	info.package_type = hal->PackageType;
3098 	info.mp_mode = adapter->registrypriv.mp_mode;
3099 
3100 	status = api->halmac_send_general_info(halmac, &info);
3101 	switch (status) {
3102 	case HALMAC_RET_SUCCESS:
3103 		break;
3104 	case HALMAC_RET_NO_DLFW:
3105 		RTW_WARN("%s: halmac_send_general_info() fail because fw not dl!\n",
3106 			 __FUNCTION__);
3107 		/* go through */
3108 	default:
3109 		return -1;
3110 	}
3111 
3112 	err = _send_general_info_by_reg(d, &info);
3113 	if (err) {
3114 		RTW_ERR("%s: Fail to send general info by register!\n",
3115 			 __FUNCTION__);
3116 		return -1;
3117 	}
3118 
3119 	return 0;
3120 }
3121 
_cfg_drv_rsvd_pg_num(struct dvobj_priv * d)3122 static int _cfg_drv_rsvd_pg_num(struct dvobj_priv *d)
3123 {
3124 	struct _ADAPTER *a;
3125 	struct hal_com_data *hal;
3126 	struct halmac_adapter *halmac;
3127 	struct halmac_api *api;
3128 	enum halmac_drv_rsvd_pg_num rsvd_page_number;
3129 	enum halmac_ret_status status;
3130 	u16 drv_rsvd_num;
3131 	int ret = 0;
3132 
3133 
3134 	a = dvobj_get_primary_adapter(d);
3135 	hal = GET_HAL_DATA(a);
3136 	halmac = dvobj_to_halmac(d);
3137 	api = HALMAC_GET_API(halmac);
3138 
3139 	drv_rsvd_num = rtw_hal_get_rsvd_page_num(a);
3140 	rsvd_page_number = _rsvd_page_num_drv2halmac(drv_rsvd_num);
3141 	status = api->halmac_cfg_drv_rsvd_pg_num(halmac, rsvd_page_number);
3142 	if (status != HALMAC_RET_SUCCESS) {
3143 		ret = -1;
3144 		goto exit;
3145 	}
3146 	hal->drv_rsvd_page_number = _rsvd_page_num_halmac2drv(rsvd_page_number);
3147 
3148 exit:
3149 #ifndef DBG_RSVD_PAGE_CFG
3150 	if (drv_rsvd_num != _rsvd_page_num_halmac2drv(rsvd_page_number))
3151 #endif
3152 		RTW_INFO("%s: request %d pages => halmac %d pages %s\n"
3153 			, __FUNCTION__, drv_rsvd_num, _rsvd_page_num_halmac2drv(rsvd_page_number)
3154 			, ret ? "fail" : "success");
3155 
3156 	return ret;
3157 }
3158 
_debug_dlfw_fail(struct dvobj_priv * d)3159 static void _debug_dlfw_fail(struct dvobj_priv *d)
3160 {
3161 	struct _ADAPTER *a;
3162 	u32 addr;
3163 	u32 v32, i, n;
3164 
3165 
3166 	a = dvobj_get_primary_adapter(d);
3167 
3168 	/* read 0x80[15:0], 0x10F8[31:0] once */
3169 	addr = 0x80;
3170 	v32 = rtw_read16(a, addr);
3171 	RTW_PRINT("%s: 0x%X = 0x%04x\n", __FUNCTION__, addr, v32);
3172 
3173 	addr = 0x10F8;
3174 	v32 = rtw_read32(a, addr);
3175 	RTW_PRINT("%s: 0x%X = 0x%08x\n", __FUNCTION__, addr, v32);
3176 
3177 	/* read 0x10FC[31:0], 5 times */
3178 	addr = 0x10FC;
3179 	n = 5;
3180 	for (i = 0; i < n; i++) {
3181 		v32 = rtw_read32(a, addr);
3182 		RTW_PRINT("%s: 0x%X = 0x%08x (%u/%u)\n",
3183 			  __FUNCTION__, addr, v32, i, n);
3184 	}
3185 
3186 	/*
3187 	 * write 0x3A[7:0]=0x28 and 0xF6[7:0]=0x01
3188 	 * and then read 0xC0[31:0] 5 times
3189 	 */
3190 	addr = 0x3A;
3191 	v32 = 0x28;
3192 	rtw_write8(a, addr, (u8)v32);
3193 	v32 = rtw_read8(a, addr);
3194 	RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v32);
3195 
3196 	addr = 0xF6;
3197 	v32 = 0x1;
3198 	rtw_write8(a, addr, (u8)v32);
3199 	v32 = rtw_read8(a, addr);
3200 	RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v32);
3201 
3202 	addr = 0xC0;
3203 	n = 5;
3204 	for (i = 0; i < n; i++) {
3205 		v32 = rtw_read32(a, addr);
3206 		RTW_PRINT("%s: 0x%X = 0x%08x (%u/%u)\n",
3207 			  __FUNCTION__, addr, v32, i, n);
3208 	}
3209 
3210 	mac_reg_dump(NULL, a);
3211 #ifdef CONFIG_SDIO_HCI
3212 	RTW_PRINT("======= SDIO Local REG =======\n");
3213 	sdio_local_reg_dump(NULL, a);
3214 	RTW_PRINT("======= SDIO CCCR REG =======\n");
3215 	sd_f0_reg_dump(NULL, a);
3216 #endif /* CONFIG_SDIO_HCI */
3217 
3218 	/* read 0x80 after 10 secs */
3219 	rtw_msleep_os(10000);
3220 	addr = 0x80;
3221 	v32 = rtw_read16(a, addr);
3222 	RTW_PRINT("%s: 0x%X = 0x%04x (after 10 secs)\n",
3223 		  __FUNCTION__, addr, v32);
3224 }
3225 
_enter_cpu_sleep_mode(struct dvobj_priv * d)3226 static enum halmac_ret_status _enter_cpu_sleep_mode(struct dvobj_priv *d)
3227 {
3228 	struct hal_com_data *hal;
3229 	struct halmac_adapter *mac;
3230 	struct halmac_api *api;
3231 
3232 
3233 	hal = GET_HAL_DATA(dvobj_get_primary_adapter(d));
3234 	mac = dvobj_to_halmac(d);
3235 	api = HALMAC_GET_API(mac);
3236 
3237 #ifdef CONFIG_RTL8822B
3238 	/* Support after firmware version 21 */
3239 	if (hal->firmware_version < 21)
3240 		return HALMAC_RET_NOT_SUPPORT;
3241 #elif defined(CONFIG_RTL8821C)
3242 	/* Support after firmware version 13.6 or 16 */
3243 	if (hal->firmware_version == 13) {
3244 		if (hal->firmware_sub_version < 6)
3245 			return HALMAC_RET_NOT_SUPPORT;
3246 	} else if (hal->firmware_version < 16) {
3247 		return HALMAC_RET_NOT_SUPPORT;
3248 	}
3249 #endif
3250 
3251 	return api->halmac_enter_cpu_sleep_mode(mac);
3252 }
3253 
3254 /*
3255  * _cpu_sleep() - Let IC CPU enter sleep mode
3256  * @d:		struct dvobj_priv*
3257  * @timeout:	time limit of wait, unit is ms
3258  *		0 for no limit
3259  *
3260  * Return 0 for CPU in sleep mode, otherwise fail to enter sleep mode.
3261  * Error codes definition are as follow:
3262  * 	-1	HALMAC enter sleep return fail
3263  *	-2	HALMAC get CPU mode return fail
3264  *	-110	timeout
3265  */
_cpu_sleep(struct dvobj_priv * d,u32 timeout)3266 static int _cpu_sleep(struct dvobj_priv *d, u32 timeout)
3267 {
3268 	struct halmac_adapter *mac;
3269 	struct halmac_api *api;
3270 	enum halmac_ret_status status;
3271 	enum halmac_wlcpu_mode mode = HALMAC_WLCPU_UNDEFINE;
3272 	systime start_t;
3273 	s32 period = 0;
3274 	u32 cnt = 0;
3275 	int err = 0;
3276 
3277 
3278 	mac = dvobj_to_halmac(d);
3279 	api = HALMAC_GET_API(mac);
3280 
3281 	start_t = rtw_get_current_time();
3282 
3283 	status = _enter_cpu_sleep_mode(d);
3284 	if (status != HALMAC_RET_SUCCESS) {
3285 		if (status != HALMAC_RET_NOT_SUPPORT)
3286 			err = -1;
3287 		goto exit;
3288 	}
3289 
3290 	do {
3291 		cnt++;
3292 
3293 		mode = HALMAC_WLCPU_UNDEFINE;
3294 		status = api->halmac_get_cpu_mode(mac, &mode);
3295 
3296 		period = rtw_get_passing_time_ms(start_t);
3297 
3298 		if (status != HALMAC_RET_SUCCESS) {
3299 			err = -2;
3300 			break;
3301 		}
3302 		if (mode == HALMAC_WLCPU_SLEEP)
3303 			break;
3304 		if (period > timeout) {
3305 			err = -110;
3306 			break;
3307 		}
3308 
3309 		rtw_msleep_os(1);
3310 	} while (1);
3311 
3312 exit:
3313 	if (err)
3314 		RTW_ERR("%s: Fail to enter sleep mode! (%d, %d)\n",
3315 			__FUNCTION__, status, mode);
3316 
3317 	RTW_INFO("%s: Cost %dms to polling %u times. (err=%d)\n",
3318 		__FUNCTION__, period, cnt, err);
3319 
3320 	return err;
3321 }
3322 
_init_trx_cfg_drv(struct dvobj_priv * d)3323 static void _init_trx_cfg_drv(struct dvobj_priv *d)
3324 {
3325 #ifdef CONFIG_PCI_HCI
3326 	rtw_hal_irp_reset(dvobj_get_primary_adapter(d));
3327 #endif
3328 }
3329 
3330 /*
3331  * Description:
3332  *	Downlaod Firmware Flow
3333  *
3334  * Parameters:
3335  *	d	pointer of struct dvobj_priv
3336  *	fw	firmware array
3337  *	fwsize	firmware size
3338  *	re_dl	re-download firmware or not
3339  *		0: run in init hal flow, not re-download
3340  *		1: it is a stand alone operation, not in init hal flow
3341  *
3342  * Return:
3343  *	0	Success
3344  *	others	Fail
3345  */
download_fw(struct dvobj_priv * d,u8 * fw,u32 fwsize,u8 re_dl)3346 static int download_fw(struct dvobj_priv *d, u8 *fw, u32 fwsize, u8 re_dl)
3347 {
3348 	PHAL_DATA_TYPE hal;
3349 	struct halmac_adapter *mac;
3350 	struct halmac_api *api;
3351 	struct halmac_fw_version fw_vesion;
3352 	enum halmac_ret_status status;
3353 	int err = 0;
3354 
3355 
3356 	hal = GET_HAL_DATA(dvobj_get_primary_adapter(d));
3357 	mac = dvobj_to_halmac(d);
3358 	api = HALMAC_GET_API(mac);
3359 
3360 	if ((!fw) || (!fwsize))
3361 		return -1;
3362 
3363 	/* 1. Driver Stop Tx */
3364 	/* ToDo */
3365 
3366 	/* 2. Driver Check Tx FIFO is empty */
3367 	err = rtw_halmac_txfifo_wait_empty(d, 2000); /* wait 2s */
3368 	if (err) {
3369 		err = -1;
3370 		goto resume_tx;
3371 	}
3372 
3373 	/* 3. Config MAX download size */
3374 	/*
3375 	 * Already done in rtw_halmac_init_adapter() or
3376 	 * somewhere calling rtw_halmac_set_max_dl_fw_size().
3377 	 */
3378 
3379 	if (re_dl) {
3380 		/* 4. Enter IC CPU sleep mode */
3381 		err = _cpu_sleep(d, 2000);
3382 		if (err) {
3383 			RTW_ERR("%s: IC CPU fail to enter sleep mode!(%d)\n",
3384 				__FUNCTION__, err);
3385 			/* skip this error */
3386 			err = 0;
3387 		}
3388 	}
3389 
3390 	/* 5. Download Firmware */
3391 	status = api->halmac_download_firmware(mac, fw, fwsize);
3392 	if (status != HALMAC_RET_SUCCESS) {
3393 		RTW_ERR("%s: download firmware FAIL! status=0x%02x\n",
3394 			__FUNCTION__, status);
3395 		_debug_dlfw_fail(d);
3396 		err = -1;
3397 		goto resume_tx;
3398 	}
3399 
3400 	/* 5.1. (Driver) Reset driver variables if needed */
3401 	hal->LastHMEBoxNum = 0;
3402 
3403 	/* 5.2. (Driver) Get FW version */
3404 	status = api->halmac_get_fw_version(mac, &fw_vesion);
3405 	if (status == HALMAC_RET_SUCCESS) {
3406 		hal->firmware_version = fw_vesion.version;
3407 		hal->firmware_sub_version = fw_vesion.sub_version;
3408 		hal->firmware_size = fwsize;
3409 	}
3410 
3411 resume_tx:
3412 	/* 6. Driver resume TX if needed */
3413 	/* ToDo */
3414 
3415 	if (err)
3416 		goto exit;
3417 
3418 	if (re_dl) {
3419 		enum halmac_trx_mode mode;
3420 
3421 		/* 7. Change reserved page size */
3422 		err = _cfg_drv_rsvd_pg_num(d);
3423 		if (err)
3424 			return -1;
3425 
3426 		/* 8. Init TRX Configuration */
3427 		mode = _choose_trx_mode(d);
3428 		status = api->halmac_init_trx_cfg(mac, mode);
3429 		if (HALMAC_RET_SUCCESS != status)
3430 			return -1;
3431 		_init_trx_cfg_drv(d);
3432 
3433 		/* 9. Config RX Aggregation */
3434 		err = rtw_halmac_rx_agg_switch(d, _TRUE);
3435 		if (err)
3436 			return -1;
3437 
3438 		/* 10. Send General Info */
3439 		err = _send_general_info(d);
3440 		if (err)
3441 			return -1;
3442 	}
3443 
3444 exit:
3445 	return err;
3446 }
3447 
init_mac_flow(struct dvobj_priv * d)3448 static int init_mac_flow(struct dvobj_priv *d)
3449 {
3450 	PADAPTER p;
3451 	struct hal_com_data *hal;
3452 	struct halmac_adapter *halmac;
3453 	struct halmac_api *api;
3454 	enum halmac_drv_rsvd_pg_num rsvd_page_number;
3455 	union halmac_wlan_addr hwa;
3456 	enum halmac_trx_mode trx_mode;
3457 	enum halmac_ret_status status;
3458 	u8 drv_rsvd_num;
3459 	u8 nettype;
3460 	int err, err_ret = -1;
3461 
3462 
3463 	p = dvobj_get_primary_adapter(d);
3464 	hal = GET_HAL_DATA(p);
3465 	halmac = dvobj_to_halmac(d);
3466 	api = HALMAC_GET_API(halmac);
3467 
3468 #ifdef CONFIG_SUPPORT_TRX_SHARED
3469 	status = api->halmac_cfg_rxff_expand_mode(halmac,
3470 						  _rtw_get_trx_share_mode(p));
3471 	if (status != HALMAC_RET_SUCCESS)
3472 		goto out;
3473 #endif
3474 
3475 #ifdef DBG_LA_MODE
3476 	if (dvobj_to_regsty(d)->la_mode_en) {
3477 		status = api->halmac_cfg_la_mode(halmac, HALMAC_LA_MODE_PARTIAL);
3478 		if (status != HALMAC_RET_SUCCESS) {
3479 			RTW_ERR("%s: Fail to enable LA mode!\n", __FUNCTION__);
3480 			goto out;
3481 		}
3482 		RTW_PRINT("%s: Enable LA mode OK.\n", __FUNCTION__);
3483 	}
3484 #endif
3485 
3486 	err = _cfg_drv_rsvd_pg_num(d);
3487 	if (err)
3488 		goto out;
3489 
3490 #ifdef CONFIG_USB_HCI
3491 	status = api->halmac_set_bulkout_num(halmac, d->RtNumOutPipes);
3492 	if (status != HALMAC_RET_SUCCESS)
3493 		goto out;
3494 #endif /* CONFIG_USB_HCI */
3495 
3496 	trx_mode = _choose_trx_mode(d);
3497 	status = api->halmac_init_mac_cfg(halmac, trx_mode);
3498 	if (status != HALMAC_RET_SUCCESS)
3499 		goto out;
3500 
3501 	/* Driver insert flow: Sync driver setting with register */
3502 	/* Sync driver RCR cache with register setting */
3503 	rtw_hal_get_hwreg(dvobj_get_primary_adapter(d), HW_VAR_RCR, NULL);
3504 
3505 #ifdef CONFIG_RTS_FULL_BW
3506 	err = rtw_halmac_set_rts_full_bw(d, _TRUE);
3507 	if (err)
3508 		RTW_WARN("%s: Fail to set RTS FULL BW mode\n", __FUNCTION__);
3509 #else
3510 	err = rtw_halmac_set_rts_full_bw(d, _FALSE);
3511 	if (err)
3512 		RTW_WARN("%s: Fail to disable RTS FULL BW mode\n", __FUNCTION__);
3513 #endif /* CONFIG_RTS_FULL_BW */
3514 
3515 	_init_trx_cfg_drv(d);
3516 	/* Driver inser flow end */
3517 
3518 	err = rtw_halmac_rx_agg_switch(d, _TRUE);
3519 	if (err)
3520 		goto out;
3521 
3522 	nettype = dvobj_to_regsty(d)->wireless_mode;
3523 	if (is_supported_vht(nettype) == _TRUE)
3524 		status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_AC);
3525 	else if (is_supported_ht(nettype) == _TRUE)
3526 		status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_N);
3527 	else if (IsSupportedTxOFDM(nettype) == _TRUE)
3528 		status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_G);
3529 	else
3530 		status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_B);
3531 	if (status != HALMAC_RET_SUCCESS)
3532 		goto out;
3533 
3534 	err_ret = 0;
3535 out:
3536 	return err_ret;
3537 }
3538 
_drv_enable_trx(struct dvobj_priv * d)3539 static int _drv_enable_trx(struct dvobj_priv *d)
3540 {
3541 	struct _ADAPTER *adapter;
3542 	u32 status;
3543 
3544 
3545 	adapter = dvobj_get_primary_adapter(d);
3546 	if (adapter->bup == _FALSE) {
3547 #ifdef CONFIG_NEW_NETDEV_HDL
3548 		status = rtw_mi_start_drv_threads(adapter);
3549 #else
3550 		status = rtw_start_drv_threads(adapter);
3551 #endif
3552 		if (status == _FAIL) {
3553 			RTW_ERR("%s: Start threads Failed!\n", __FUNCTION__);
3554 			return -1;
3555 		}
3556 	}
3557 
3558 	rtw_intf_start(adapter);
3559 
3560 	return 0;
3561 }
3562 
3563 /*
3564  * Notices:
3565  *	Make sure following information
3566  *	1. GET_HAL_RFPATH
3567  *	2. GET_HAL_DATA(dvobj_get_primary_adapter(d))->rfe_type
3568  *	3. GET_HAL_DATA(dvobj_get_primary_adapter(d))->PackageType
3569  *	4. dvobj_get_primary_adapter(d)->registrypriv.mp_mode
3570  *	are all ready before calling this function.
3571  */
_halmac_init_hal(struct dvobj_priv * d,u8 * fw,u32 fwsize)3572 static int _halmac_init_hal(struct dvobj_priv *d, u8 *fw, u32 fwsize)
3573 {
3574 	PADAPTER adapter;
3575 	struct halmac_adapter *halmac;
3576 	struct halmac_api *api;
3577 	enum halmac_ret_status status;
3578 	u32 ok;
3579 	u8 fw_ok = _FALSE;
3580 	int err, err_ret = -1;
3581 
3582 
3583 	adapter = dvobj_get_primary_adapter(d);
3584 	halmac = dvobj_to_halmac(d);
3585 	if (!halmac)
3586 		goto out;
3587 	api = HALMAC_GET_API(halmac);
3588 
3589 	/* StatePowerOff */
3590 
3591 	/* SKIP: halmac_init_adapter (Already done before) */
3592 
3593 	/* halmac_pre_Init_system_cfg */
3594 	/* halmac_mac_power_switch(on) */
3595 	/* halmac_Init_system_cfg */
3596 	ok = rtw_hal_power_on(adapter);
3597 	if (_FAIL == ok)
3598 		goto out;
3599 
3600 	/* StatePowerOn */
3601 
3602 	/* DownloadFW */
3603 	if (fw && fwsize) {
3604 		err = download_fw(d, fw, fwsize, 0);
3605 		if (err)
3606 			goto out;
3607 		fw_ok = _TRUE;
3608 	}
3609 
3610 	/* InitMACFlow */
3611 	err = init_mac_flow(d);
3612 	if (err)
3613 		goto out;
3614 
3615 	/* Driver insert flow: Enable TR/RX */
3616 	err = _drv_enable_trx(d);
3617 	if (err)
3618 		goto out;
3619 
3620 	/* halmac_send_general_info */
3621 	if (_TRUE == fw_ok) {
3622 		err = _send_general_info(d);
3623 		if (err)
3624 			goto out;
3625 	}
3626 
3627 	/* Init Phy parameter-MAC */
3628 	ok = rtw_hal_init_mac_register(adapter);
3629 	if (_FALSE == ok)
3630 		goto out;
3631 
3632 	/* StateMacInitialized */
3633 
3634 	/* halmac_cfg_drv_info */
3635 	err = rtw_halmac_config_rx_info(d, HALMAC_DRV_INFO_PHY_STATUS);
3636 	if (err)
3637 		goto out;
3638 
3639 	/* halmac_set_hw_value(HALMAC_HW_EN_BB_RF) */
3640 	/* Init BB, RF */
3641 	ok = rtw_hal_init_phy(adapter);
3642 	if (_FALSE == ok)
3643 		goto out;
3644 
3645 	status = api->halmac_init_interface_cfg(halmac);
3646 	if (status != HALMAC_RET_SUCCESS)
3647 		goto out;
3648 
3649 	/* SKIP: halmac_verify_platform_api */
3650 	/* SKIP: halmac_h2c_lb */
3651 
3652 	/* StateRxIdle */
3653 
3654 	err_ret = 0;
3655 out:
3656 	return err_ret;
3657 }
3658 
rtw_halmac_init_hal(struct dvobj_priv * d)3659 int rtw_halmac_init_hal(struct dvobj_priv *d)
3660 {
3661 	return _halmac_init_hal(d, NULL, 0);
3662 }
3663 
3664 /*
3665  * Notices:
3666  *	Make sure following information
3667  *	1. GET_HAL_RFPATH
3668  *	2. GET_HAL_DATA(dvobj_get_primary_adapter(d))->rfe_type
3669  *	3. GET_HAL_DATA(dvobj_get_primary_adapter(d))->PackageType
3670  *	4. dvobj_get_primary_adapter(d)->registrypriv.mp_mode
3671  *	are all ready before calling this function.
3672  */
rtw_halmac_init_hal_fw(struct dvobj_priv * d,u8 * fw,u32 fwsize)3673 int rtw_halmac_init_hal_fw(struct dvobj_priv *d, u8 *fw, u32 fwsize)
3674 {
3675 	return _halmac_init_hal(d, fw, fwsize);
3676 }
3677 
3678 /*
3679  * Notices:
3680  *	Make sure following information
3681  *	1. GET_HAL_RFPATH
3682  *	2. GET_HAL_DATA(dvobj_get_primary_adapter(d))->rfe_type
3683  *	3. GET_HAL_DATA(dvobj_get_primary_adapter(d))->PackageType
3684  *	4. dvobj_get_primary_adapter(d)->registrypriv.mp_mode
3685  *	are all ready before calling this function.
3686  */
rtw_halmac_init_hal_fw_file(struct dvobj_priv * d,u8 * fwpath)3687 int rtw_halmac_init_hal_fw_file(struct dvobj_priv *d, u8 *fwpath)
3688 {
3689 	u8 *fw = NULL;
3690 	u32 fwmaxsize = 0, size = 0;
3691 	int err = 0;
3692 
3693 
3694 	err = rtw_halmac_get_fw_max_size(d, &fwmaxsize);
3695 	if (err) {
3696 		RTW_ERR("%s: Fail to get Firmware MAX size(err=%d)\n", __FUNCTION__, err);
3697 		return -1;
3698 	}
3699 
3700 	fw = rtw_zmalloc(fwmaxsize);
3701 	if (!fw)
3702 		return -1;
3703 
3704 	size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
3705 	if (!size) {
3706 		err = -1;
3707 		goto exit;
3708 	}
3709 
3710 	err = _halmac_init_hal(d, fw, size);
3711 
3712 exit:
3713 	rtw_mfree(fw, fwmaxsize);
3714 	/*fw = NULL;*/
3715 
3716 	return err;
3717 }
3718 
rtw_halmac_deinit_hal(struct dvobj_priv * d)3719 int rtw_halmac_deinit_hal(struct dvobj_priv *d)
3720 {
3721 	PADAPTER adapter;
3722 	struct halmac_adapter *halmac;
3723 	struct halmac_api *api;
3724 	enum halmac_ret_status status;
3725 	int err = -1;
3726 
3727 
3728 	adapter = dvobj_get_primary_adapter(d);
3729 	halmac = dvobj_to_halmac(d);
3730 	if (!halmac)
3731 		goto out;
3732 	api = HALMAC_GET_API(halmac);
3733 
3734 	status = api->halmac_deinit_interface_cfg(halmac);
3735 	if (status != HALMAC_RET_SUCCESS)
3736 		goto out;
3737 
3738 	rtw_hal_power_off(adapter);
3739 
3740 	err = 0;
3741 out:
3742 	return err;
3743 }
3744 
rtw_halmac_self_verify(struct dvobj_priv * d)3745 int rtw_halmac_self_verify(struct dvobj_priv *d)
3746 {
3747 	struct halmac_adapter *mac;
3748 	struct halmac_api *api;
3749 	enum halmac_ret_status status;
3750 	int err = -1;
3751 
3752 
3753 	mac = dvobj_to_halmac(d);
3754 	api = HALMAC_GET_API(mac);
3755 
3756 	status = api->halmac_verify_platform_api(mac);
3757 	if (status != HALMAC_RET_SUCCESS)
3758 		goto out;
3759 
3760 	status = api->halmac_h2c_lb(mac);
3761 	if (status != HALMAC_RET_SUCCESS)
3762 		goto out;
3763 
3764 	err = 0;
3765 out:
3766 	return err;
3767 }
3768 
rtw_halmac_txfifo_is_empty(struct dvobj_priv * d)3769 static u8 rtw_halmac_txfifo_is_empty(struct dvobj_priv *d)
3770 {
3771 	struct halmac_adapter *mac;
3772 	struct halmac_api *api;
3773 	enum halmac_ret_status status;
3774 	u32 chk_num = 10;
3775 	u8 rst = _FALSE;
3776 
3777 
3778 	mac = dvobj_to_halmac(d);
3779 	api = HALMAC_GET_API(mac);
3780 
3781 	status = api->halmac_txfifo_is_empty(mac, chk_num);
3782 	if (status == HALMAC_RET_SUCCESS)
3783 		rst = _TRUE;
3784 
3785 	return rst;
3786 }
3787 
3788 /**
3789  * rtw_halmac_txfifo_wait_empty() - Wait TX FIFO to be emtpy
3790  * @d:		struct dvobj_priv*
3791  * @timeout:	time limit of wait, unit is ms
3792  *		0 for no limit
3793  *
3794  * Wait TX FIFO to be emtpy.
3795  *
3796  * Return 0 for TX FIFO is empty, otherwise not empty.
3797  */
rtw_halmac_txfifo_wait_empty(struct dvobj_priv * d,u32 timeout)3798 int rtw_halmac_txfifo_wait_empty(struct dvobj_priv *d, u32 timeout)
3799 {
3800 	struct _ADAPTER *a;
3801 	u8 empty = _FALSE;
3802 	u32 cnt = 0;
3803 	systime start_time = 0;
3804 	u32 pass_time; /* ms */
3805 
3806 
3807 	a = dvobj_get_primary_adapter(d);
3808 	start_time = rtw_get_current_time();
3809 
3810 	do {
3811 		cnt++;
3812 		empty = rtw_halmac_txfifo_is_empty(d);
3813 		if (empty == _TRUE)
3814 			break;
3815 
3816 		if (timeout) {
3817 			pass_time = rtw_get_passing_time_ms(start_time);
3818 			if (pass_time > timeout)
3819 				break;
3820 		}
3821 		if (RTW_CANNOT_IO(a)) {
3822 			RTW_WARN("%s: Interrupted by I/O forbiden!\n", __FUNCTION__);
3823 			break;
3824 		}
3825 
3826 		rtw_msleep_os(2);
3827 	} while (1);
3828 
3829 	if (empty == _FALSE) {
3830 #ifdef CONFIG_RTW_DEBUG
3831 		u16 dbg_reg[] = {0x210, 0x230, 0x234, 0x238, 0x23C, 0x240,
3832 				 0x418, 0x10FC, 0x10F8, 0x11F4, 0x11F8};
3833 		u8 i;
3834 		u32 val;
3835 
3836 		if (!RTW_CANNOT_IO(a)) {
3837 			for (i = 0; i < ARRAY_SIZE(dbg_reg); i++) {
3838 				val = rtw_read32(a, dbg_reg[i]);
3839 				RTW_ERR("REG_%X:0x%08x\n", dbg_reg[i], val);
3840 			}
3841 		}
3842 #endif /* CONFIG_RTW_DEBUG */
3843 
3844 		RTW_ERR("%s: Fail to wait txfifo empty!(cnt=%d)\n",
3845 			__FUNCTION__, cnt);
3846 		return -1;
3847 	}
3848 
3849 	return 0;
3850 }
3851 
_fw_mem_drv2halmac(enum fw_mem mem,u8 tx_stop)3852 static enum halmac_dlfw_mem _fw_mem_drv2halmac(enum fw_mem mem, u8 tx_stop)
3853 {
3854 	enum halmac_dlfw_mem mem_halmac = HALMAC_DLFW_MEM_UNDEFINE;
3855 
3856 
3857 	switch (mem) {
3858 	case FW_EMEM:
3859 		if (tx_stop == _FALSE)
3860 			mem_halmac = HALMAC_DLFW_MEM_EMEM_RSVD_PG;
3861 		else
3862 			mem_halmac = HALMAC_DLFW_MEM_EMEM;
3863 		break;
3864 
3865 	case FW_IMEM:
3866 	case FW_DMEM:
3867 		mem_halmac = HALMAC_DLFW_MEM_UNDEFINE;
3868 		break;
3869 	}
3870 
3871 	return mem_halmac;
3872 }
3873 
rtw_halmac_dlfw_mem(struct dvobj_priv * d,u8 * fw,u32 fwsize,enum fw_mem mem)3874 int rtw_halmac_dlfw_mem(struct dvobj_priv *d, u8 *fw, u32 fwsize, enum fw_mem mem)
3875 {
3876 	struct halmac_adapter *mac;
3877 	struct halmac_api *api;
3878 	enum halmac_ret_status status;
3879 	enum halmac_dlfw_mem dlfw_mem;
3880 	u8 tx_stop = _FALSE;
3881 	u32 chk_timeout = 2000; /* unit: ms */
3882 	int err = 0;
3883 
3884 
3885 	mac = dvobj_to_halmac(d);
3886 	api = HALMAC_GET_API(mac);
3887 
3888 	if ((!fw) || (!fwsize))
3889 		return -1;
3890 
3891 #ifndef RTW_HALMAC_DLFW_MEM_NO_STOP_TX
3892 	/* 1. Driver Stop Tx */
3893 	/* ToDo */
3894 
3895 	/* 2. Driver Check Tx FIFO is empty */
3896 	err = rtw_halmac_txfifo_wait_empty(d, chk_timeout);
3897 	if (err)
3898 		tx_stop = _FALSE;
3899 	else
3900 		tx_stop = _TRUE;
3901 #endif /* !RTW_HALMAC_DLFW_MEM_NO_STOP_TX */
3902 
3903 	/* 3. Download Firmware MEM */
3904 	dlfw_mem = _fw_mem_drv2halmac(mem, tx_stop);
3905 	if (dlfw_mem == HALMAC_DLFW_MEM_UNDEFINE) {
3906 		err = -1;
3907 		goto resume_tx;
3908 	}
3909 	status = api->halmac_free_download_firmware(mac, dlfw_mem, fw, fwsize);
3910 	if (status != HALMAC_RET_SUCCESS) {
3911 		RTW_ERR("%s: halmac_free_download_firmware fail(err=0x%x)\n",
3912 			__FUNCTION__, status);
3913 		err = -1;
3914 		goto resume_tx;
3915 	}
3916 
3917 resume_tx:
3918 #ifndef RTW_HALMAC_DLFW_MEM_NO_STOP_TX
3919 	/* 4. Driver resume TX if needed */
3920 	/* ToDo */
3921 #endif /* !RTW_HALMAC_DLFW_MEM_NO_STOP_TX */
3922 
3923 	return err;
3924 }
3925 
rtw_halmac_dlfw_mem_from_file(struct dvobj_priv * d,u8 * fwpath,enum fw_mem mem)3926 int rtw_halmac_dlfw_mem_from_file(struct dvobj_priv *d, u8 *fwpath, enum fw_mem mem)
3927 {
3928 	u8 *fw = NULL;
3929 	u32 fwmaxsize = 0, size = 0;
3930 	int err = 0;
3931 
3932 
3933 	err = rtw_halmac_get_fw_max_size(d, &fwmaxsize);
3934 	if (err) {
3935 		RTW_ERR("%s: Fail to get Firmware MAX size(err=%d)\n", __FUNCTION__, err);
3936 		return -1;
3937 	}
3938 
3939 	fw = rtw_zmalloc(fwmaxsize);
3940 	if (!fw)
3941 		return -1;
3942 
3943 	size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
3944 	if (size)
3945 		err = rtw_halmac_dlfw_mem(d, fw, size, mem);
3946 	else
3947 		err = -1;
3948 
3949 	rtw_mfree(fw, fwmaxsize);
3950 	/*fw = NULL;*/
3951 
3952 	return err;
3953 }
3954 
3955 /*
3956  * Return:
3957  *	0	Success
3958  *	-22	Invalid arguemnt
3959  */
rtw_halmac_dlfw(struct dvobj_priv * d,u8 * fw,u32 fwsize)3960 int rtw_halmac_dlfw(struct dvobj_priv *d, u8 *fw, u32 fwsize)
3961 {
3962 	PADAPTER adapter;
3963 	enum halmac_ret_status status;
3964 	u32 ok;
3965 	int err, err_ret = -1;
3966 
3967 
3968 	if (!fw || !fwsize)
3969 		return -22;
3970 
3971 	adapter = dvobj_get_primary_adapter(d);
3972 
3973 	/* re-download firmware */
3974 	if (rtw_is_hw_init_completed(adapter))
3975 		return download_fw(d, fw, fwsize, 1);
3976 
3977 	/* Download firmware before hal init */
3978 	/* Power on, download firmware and init mac */
3979 	ok = rtw_hal_power_on(adapter);
3980 	if (_FAIL == ok)
3981 		goto out;
3982 
3983 	err = download_fw(d, fw, fwsize, 0);
3984 	if (err) {
3985 		err_ret = err;
3986 		goto out;
3987 	}
3988 
3989 	err = init_mac_flow(d);
3990 	if (err)
3991 		goto out;
3992 
3993 	err = _send_general_info(d);
3994 	if (err)
3995 		goto out;
3996 
3997 	err_ret = 0;
3998 
3999 out:
4000 	return err_ret;
4001 }
4002 
rtw_halmac_dlfw_from_file(struct dvobj_priv * d,u8 * fwpath)4003 int rtw_halmac_dlfw_from_file(struct dvobj_priv *d, u8 *fwpath)
4004 {
4005 	u8 *fw = NULL;
4006 	u32 fwmaxsize = 0, size = 0;
4007 	int err = 0;
4008 
4009 
4010 	err = rtw_halmac_get_fw_max_size(d, &fwmaxsize);
4011 	if (err) {
4012 		RTW_ERR("%s: Fail to get Firmware MAX size(err=%d)\n", __FUNCTION__, err);
4013 		return -1;
4014 	}
4015 
4016 	fw = rtw_zmalloc(fwmaxsize);
4017 	if (!fw)
4018 		return -1;
4019 
4020 	size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
4021 	if (size)
4022 		err = rtw_halmac_dlfw(d, fw, size);
4023 	else
4024 		err = -1;
4025 
4026 	rtw_mfree(fw, fwmaxsize);
4027 	/*fw = NULL;*/
4028 
4029 	return err;
4030 }
4031 
4032 /*
4033  * Description:
4034  *	Power on/off BB/RF domain.
4035  *
4036  * Parameters:
4037  *	enable	_TRUE/_FALSE for power on/off
4038  *
4039  * Return:
4040  *	0	Success
4041  *	others	Fail
4042  */
rtw_halmac_phy_power_switch(struct dvobj_priv * d,u8 enable)4043 int rtw_halmac_phy_power_switch(struct dvobj_priv *d, u8 enable)
4044 {
4045 	PADAPTER adapter;
4046 	struct halmac_adapter *halmac;
4047 	struct halmac_api *api;
4048 	enum halmac_ret_status status;
4049 	u8 on;
4050 
4051 
4052 	adapter = dvobj_get_primary_adapter(d);
4053 	halmac = dvobj_to_halmac(d);
4054 	if (!halmac)
4055 		return -1;
4056 	api = HALMAC_GET_API(halmac);
4057 	on = (enable == _TRUE) ? 1 : 0;
4058 
4059 	status = api->halmac_set_hw_value(halmac, HALMAC_HW_EN_BB_RF, &on);
4060 	if (status != HALMAC_RET_SUCCESS)
4061 		return -1;
4062 
4063 	return 0;
4064 }
4065 
_is_fw_read_cmd_down(PADAPTER adapter,u8 msgbox_num)4066 static u8 _is_fw_read_cmd_down(PADAPTER adapter, u8 msgbox_num)
4067 {
4068 	u8 read_down = _FALSE;
4069 	int retry_cnts = 100;
4070 	u8 valid;
4071 
4072 	do {
4073 		valid = rtw_read8(adapter, REG_HMETFR) & BIT(msgbox_num);
4074 		if (0 == valid)
4075 			read_down = _TRUE;
4076 		else
4077 			rtw_msleep_os(1);
4078 	} while ((!read_down) && (retry_cnts--));
4079 
4080 	if (_FALSE == read_down)
4081 		RTW_WARN("%s, reg_1cc(%x), msg_box(%d)...\n", __func__, rtw_read8(adapter, REG_HMETFR), msgbox_num);
4082 
4083 	return read_down;
4084 }
4085 
4086 /**
4087  * rtw_halmac_send_h2c() - Send H2C to firmware
4088  * @d:		struct dvobj_priv*
4089  * @h2c:	H2C data buffer, suppose to be 8 bytes
4090  *
4091  * Send H2C to firmware by message box register(0x1D0~0x1D3 & 0x1F0~0x1F3).
4092  *
4093  * Assume firmware be ready to accept H2C here, please check
4094  * (hal->bFWReady == _TRUE) before call this function or make sure firmware is
4095  * ready.
4096  *
4097  * Return: 0 if process OK, otherwise fail to send this H2C.
4098  */
rtw_halmac_send_h2c(struct dvobj_priv * d,u8 * h2c)4099 int rtw_halmac_send_h2c(struct dvobj_priv *d, u8 *h2c)
4100 {
4101 	PADAPTER adapter = dvobj_get_primary_adapter(d);
4102 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
4103 	u8 h2c_box_num = 0;
4104 	u32 msgbox_addr = 0;
4105 	u32 msgbox_ex_addr = 0;
4106 	u32 h2c_cmd = 0;
4107 	u32 h2c_cmd_ex = 0;
4108 	int err = -1;
4109 
4110 
4111 	if (!h2c) {
4112 		RTW_WARN("%s: pbuf is NULL\n", __FUNCTION__);
4113 		return err;
4114 	}
4115 
4116 	if (rtw_is_surprise_removed(adapter)) {
4117 		RTW_WARN("%s: surprise removed\n", __FUNCTION__);
4118 		return err;
4119 	}
4120 
4121 	_enter_critical_mutex(&d->h2c_fwcmd_mutex, NULL);
4122 
4123 	/* pay attention to if race condition happened in H2C cmd setting */
4124 	h2c_box_num = hal->LastHMEBoxNum;
4125 
4126 	if (!_is_fw_read_cmd_down(adapter, h2c_box_num)) {
4127 		RTW_WARN(" fw read cmd failed...\n");
4128 #ifdef DBG_CONFIG_ERROR_DETECT
4129 		hal->srestpriv.self_dect_fw = _TRUE;
4130 		hal->srestpriv.self_dect_fw_cnt++;
4131 #endif /* DBG_CONFIG_ERROR_DETECT */
4132 		goto exit;
4133 	}
4134 
4135 	/* Write Ext command (byte 4~7) */
4136 	msgbox_ex_addr = REG_HMEBOX_E0 + (h2c_box_num * EX_MESSAGE_BOX_SIZE);
4137 	_rtw_memcpy((u8 *)(&h2c_cmd_ex), h2c + 4, EX_MESSAGE_BOX_SIZE);
4138 	h2c_cmd_ex = le32_to_cpu(h2c_cmd_ex);
4139 	rtw_write32(adapter, msgbox_ex_addr, h2c_cmd_ex);
4140 
4141 	/* Write command (byte 0~3) */
4142 	msgbox_addr = REG_HMEBOX0 + (h2c_box_num * MESSAGE_BOX_SIZE);
4143 	_rtw_memcpy((u8 *)(&h2c_cmd), h2c, 4);
4144 	h2c_cmd = le32_to_cpu(h2c_cmd);
4145 	rtw_write32(adapter, msgbox_addr, h2c_cmd);
4146 
4147 	/* update last msg box number */
4148 	hal->LastHMEBoxNum = (h2c_box_num + 1) % MAX_H2C_BOX_NUMS;
4149 	err = 0;
4150 
4151 #ifdef DBG_H2C_CONTENT
4152 	RTW_INFO_DUMP("[H2C] - ", h2c, RTW_HALMAC_H2C_MAX_SIZE);
4153 #endif
4154 exit:
4155 	_exit_critical_mutex(&d->h2c_fwcmd_mutex, NULL);
4156 	return err;
4157 }
4158 
4159 /**
4160  * rtw_halmac_c2h_handle() - Handle C2H for HALMAC
4161  * @d:		struct dvobj_priv*
4162  * @c2h:	Full C2H packet, including RX description and payload
4163  * @size:	Size(byte) of c2h
4164  *
4165  * Send C2H packet to HALMAC to process C2H packets, and the expected C2H ID is
4166  * 0xFF. This function won't have any I/O, so caller doesn't have to call it in
4167  * I/O safe place(ex. command thread).
4168  *
4169  * Please sure doesn't call this function in the same thread as someone is
4170  * waiting HALMAC C2H ack, otherwise there is a deadlock happen.
4171  *
4172  * Return: 0 if process OK, otherwise no action for this C2H.
4173  */
rtw_halmac_c2h_handle(struct dvobj_priv * d,u8 * c2h,u32 size)4174 int rtw_halmac_c2h_handle(struct dvobj_priv *d, u8 *c2h, u32 size)
4175 {
4176 	struct halmac_adapter *mac;
4177 	struct halmac_api *api;
4178 	enum halmac_ret_status status;
4179 #ifdef RTW_HALMAC_FILTER_DRV_C2H
4180 	u32 desc_size = 0;
4181 	u8 *c2h_data;
4182 	u8 sub;
4183 #endif /* RTW_HALMAC_FILTER_DRV_C2H */
4184 
4185 
4186 	mac = dvobj_to_halmac(d);
4187 	api = HALMAC_GET_API(mac);
4188 
4189 #ifdef RTW_HALMAC_FILTER_DRV_C2H
4190 	status = api->halmac_get_hw_value(mac, HALMAC_HW_RX_DESC_SIZE,
4191 					  &desc_size);
4192 	if (status != HALMAC_RET_SUCCESS) {
4193 		RTW_ERR("%s: fail to get rx desc size!\n", __FUNCTION__);
4194 		goto skip_filter;
4195 	}
4196 
4197 	c2h_data = c2h + desc_size;
4198 	sub = C2H_HDR_GET_C2H_SUB_CMD_ID(c2h_data);
4199 	switch (sub) {
4200 	case C2H_SUB_CMD_ID_C2H_PKT_FTM_DBG:
4201 	case C2H_SUB_CMD_ID_C2H_PKT_FTM_2_DBG:
4202 	case C2H_SUB_CMD_ID_C2H_PKT_FTM_3_DBG:
4203 	case C2H_SUB_CMD_ID_C2H_PKT_FTM_4_DBG:
4204 	case C2H_SUB_CMD_ID_FTMACKRPT_HDL_DBG:
4205 	case C2H_SUB_CMD_ID_FTMC2H_RPT:
4206 	case C2H_SUB_CMD_ID_DRVFTMC2H_RPT:
4207 	case C2H_SUB_CMD_ID_C2H_PKT_FTM_5_DBG:
4208 	case C2H_SUB_CMD_ID_CCX_RPT:
4209 	case C2H_SUB_CMD_ID_C2H_PKT_NAN_RPT:
4210 	case C2H_SUB_CMD_ID_C2H_PKT_ATM_RPT:
4211 	case C2H_SUB_CMD_ID_C2H_PKT_SCC_CSA_RPT:
4212 	case C2H_SUB_CMD_ID_C2H_PKT_FW_STATUS_NOTIFY:
4213 	case C2H_SUB_CMD_ID_C2H_PKT_FTMSESSION_END:
4214 	case C2H_SUB_CMD_ID_C2H_PKT_DETECT_THERMAL:
4215 	case C2H_SUB_CMD_ID_FW_FWCTRL_RPT:
4216 	case C2H_SUB_CMD_ID_SCAN_CH_NOTIFY:
4217 	case C2H_SUB_CMD_ID_FW_TBTT_RPT:
4218 	case C2H_SUB_CMD_ID_BCN_OFFLOAD:
4219 	case C2H_SUB_CMD_ID_FW_DBG_MSG:
4220 		RTW_PRINT("%s: unhandled C2H, id=0xFF subid=0x%x len=%u\n",
4221 			  __FUNCTION__, sub, C2H_HDR_GET_LEN(c2h_data));
4222 		RTW_PRINT_DUMP("C2H: ", c2h_data, size - desc_size);
4223 		return 0;
4224 	}
4225 
4226 skip_filter:
4227 #endif /* RTW_HALMAC_FILTER_DRV_C2H */
4228 
4229 	status = api->halmac_get_c2h_info(mac, c2h, size);
4230 	if (HALMAC_RET_SUCCESS != status)
4231 		return -1;
4232 
4233 	return 0;
4234 }
4235 
rtw_halmac_get_available_efuse_size(struct dvobj_priv * d,u32 * size)4236 int rtw_halmac_get_available_efuse_size(struct dvobj_priv *d, u32 *size)
4237 {
4238 	struct halmac_adapter *mac;
4239 	struct halmac_api *api;
4240 	enum halmac_ret_status status;
4241 	u32 val;
4242 
4243 
4244 	mac = dvobj_to_halmac(d);
4245 	api = HALMAC_GET_API(mac);
4246 
4247 	status = api->halmac_get_efuse_available_size(mac, &val);
4248 	if (HALMAC_RET_SUCCESS != status)
4249 		return -1;
4250 
4251 	*size = val;
4252 	return 0;
4253 }
4254 
rtw_halmac_get_physical_efuse_size(struct dvobj_priv * d,u32 * size)4255 int rtw_halmac_get_physical_efuse_size(struct dvobj_priv *d, u32 *size)
4256 {
4257 	struct halmac_adapter *mac;
4258 	struct halmac_api *api;
4259 	enum halmac_ret_status status;
4260 	u32 val;
4261 
4262 
4263 	mac = dvobj_to_halmac(d);
4264 	api = HALMAC_GET_API(mac);
4265 
4266 	status = api->halmac_get_efuse_size(mac, &val);
4267 	if (HALMAC_RET_SUCCESS != status)
4268 		return -1;
4269 
4270 	*size = val;
4271 	return 0;
4272 }
4273 
rtw_halmac_read_physical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size)4274 int rtw_halmac_read_physical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size)
4275 {
4276 	struct halmac_adapter *mac;
4277 	struct halmac_api *api;
4278 	enum halmac_ret_status status;
4279 	enum halmac_feature_id id;
4280 	int ret;
4281 
4282 
4283 	mac = dvobj_to_halmac(d);
4284 	api = HALMAC_GET_API(mac);
4285 	id = HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE;
4286 
4287 	ret = init_halmac_event(d, id, map, size);
4288 	if (ret)
4289 		return -1;
4290 
4291 	status = api->halmac_dump_efuse_map(mac, HALMAC_EFUSE_R_DRV);
4292 	if (HALMAC_RET_SUCCESS != status) {
4293 		free_halmac_event(d, id);
4294 		return -1;
4295 	}
4296 
4297 	ret = wait_halmac_event(d, id);
4298 	if (ret)
4299 		return -1;
4300 
4301 	return 0;
4302 }
4303 
rtw_halmac_read_physical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)4304 int rtw_halmac_read_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4305 {
4306 	struct halmac_adapter *mac;
4307 	struct halmac_api *api;
4308 	enum halmac_ret_status status;
4309 	u8 v;
4310 	u32 i;
4311 	u8 *efuse = NULL;
4312 	u32 size = 0;
4313 	int err = 0;
4314 
4315 
4316 	mac = dvobj_to_halmac(d);
4317 	api = HALMAC_GET_API(mac);
4318 
4319 	if (api->halmac_read_efuse) {
4320 		for (i = 0; i < cnt; i++) {
4321 			status = api->halmac_read_efuse(mac, offset + i, &v);
4322 			if (HALMAC_RET_SUCCESS != status)
4323 				return -1;
4324 			data[i] = v;
4325 		}
4326 	} else {
4327 		err = rtw_halmac_get_physical_efuse_size(d, &size);
4328 		if (err)
4329 			return -1;
4330 
4331 		efuse = rtw_zmalloc(size);
4332 		if (!efuse)
4333 			return -1;
4334 
4335 		err = rtw_halmac_read_physical_efuse_map(d, efuse, size);
4336 		if (err)
4337 			err = -1;
4338 		else
4339 			_rtw_memcpy(data, efuse + offset, cnt);
4340 
4341 		rtw_mfree(efuse, size);
4342 	}
4343 
4344 	return err;
4345 }
4346 
rtw_halmac_write_physical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)4347 int rtw_halmac_write_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4348 {
4349 	struct halmac_adapter *mac;
4350 	struct halmac_api *api;
4351 	enum halmac_ret_status status;
4352 	u32 i;
4353 
4354 
4355 	mac = dvobj_to_halmac(d);
4356 	api = HALMAC_GET_API(mac);
4357 
4358 	if (api->halmac_write_efuse == NULL)
4359 		return -1;
4360 
4361 	for (i = 0; i < cnt; i++) {
4362 		status = api->halmac_write_efuse(mac, offset + i, data[i]);
4363 		if (HALMAC_RET_SUCCESS != status)
4364 			return -1;
4365 	}
4366 
4367 	return 0;
4368 }
4369 
rtw_halmac_get_logical_efuse_size(struct dvobj_priv * d,u32 * size)4370 int rtw_halmac_get_logical_efuse_size(struct dvobj_priv *d, u32 *size)
4371 {
4372 	struct halmac_adapter *mac;
4373 	struct halmac_api *api;
4374 	enum halmac_ret_status status;
4375 	u32 val;
4376 
4377 
4378 	mac = dvobj_to_halmac(d);
4379 	api = HALMAC_GET_API(mac);
4380 
4381 	status = api->halmac_get_logical_efuse_size(mac, &val);
4382 	if (HALMAC_RET_SUCCESS != status)
4383 		return -1;
4384 
4385 	*size = val;
4386 	return 0;
4387 }
4388 
rtw_halmac_read_logical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size,u8 * maskmap,u32 masksize)4389 int rtw_halmac_read_logical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size, u8 *maskmap, u32 masksize)
4390 {
4391 	struct halmac_adapter *mac;
4392 	struct halmac_api *api;
4393 	enum halmac_ret_status status;
4394 	enum halmac_feature_id id;
4395 	int ret;
4396 
4397 
4398 	mac = dvobj_to_halmac(d);
4399 	api = HALMAC_GET_API(mac);
4400 	id = HALMAC_FEATURE_DUMP_LOGICAL_EFUSE;
4401 
4402 	ret = init_halmac_event(d, id, map, size);
4403 	if (ret)
4404 		return -1;
4405 
4406 	status = api->halmac_dump_logical_efuse_map(mac, HALMAC_EFUSE_R_DRV);
4407 	if (HALMAC_RET_SUCCESS != status) {
4408 		free_halmac_event(d, id);
4409 		return -1;
4410 	}
4411 
4412 	ret = wait_halmac_event(d, id);
4413 	if (ret)
4414 		return -1;
4415 
4416 	if (maskmap && masksize) {
4417 		struct halmac_pg_efuse_info pginfo;
4418 
4419 		pginfo.efuse_map = map;
4420 		pginfo.efuse_map_size = size;
4421 		pginfo.efuse_mask = maskmap;
4422 		pginfo.efuse_mask_size = masksize;
4423 
4424 		status = api->halmac_mask_logical_efuse(mac, &pginfo);
4425 		if (status != HALMAC_RET_SUCCESS)
4426 			RTW_WARN("%s: mask logical efuse FAIL!\n", __FUNCTION__);
4427 	}
4428 
4429 	return 0;
4430 }
4431 
rtw_halmac_write_logical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size,u8 * maskmap,u32 masksize)4432 int rtw_halmac_write_logical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size, u8 *maskmap, u32 masksize)
4433 {
4434 	struct halmac_adapter *mac;
4435 	struct halmac_api *api;
4436 	struct halmac_pg_efuse_info pginfo;
4437 	enum halmac_ret_status status;
4438 
4439 
4440 	mac = dvobj_to_halmac(d);
4441 	api = HALMAC_GET_API(mac);
4442 
4443 	pginfo.efuse_map = map;
4444 	pginfo.efuse_map_size = size;
4445 	pginfo.efuse_mask = maskmap;
4446 	pginfo.efuse_mask_size = masksize;
4447 
4448 	status = api->halmac_pg_efuse_by_map(mac, &pginfo, HALMAC_EFUSE_R_AUTO);
4449 	if (HALMAC_RET_SUCCESS != status)
4450 		return -1;
4451 
4452 	return 0;
4453 }
4454 
rtw_halmac_read_logical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)4455 int rtw_halmac_read_logical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4456 {
4457 	struct halmac_adapter *mac;
4458 	struct halmac_api *api;
4459 	enum halmac_ret_status status;
4460 	u8 v;
4461 	u32 i;
4462 
4463 
4464 	mac = dvobj_to_halmac(d);
4465 	api = HALMAC_GET_API(mac);
4466 
4467 	for (i = 0; i < cnt; i++) {
4468 		status = api->halmac_read_logical_efuse(mac, offset + i, &v);
4469 		if (HALMAC_RET_SUCCESS != status)
4470 			return -1;
4471 		data[i] = v;
4472 	}
4473 
4474 	return 0;
4475 }
4476 
rtw_halmac_write_logical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)4477 int rtw_halmac_write_logical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4478 {
4479 	struct halmac_adapter *mac;
4480 	struct halmac_api *api;
4481 	enum halmac_ret_status status;
4482 	u32 i;
4483 
4484 
4485 	mac = dvobj_to_halmac(d);
4486 	api = HALMAC_GET_API(mac);
4487 
4488 	for (i = 0; i < cnt; i++) {
4489 		status = api->halmac_write_logical_efuse(mac, offset + i, data[i]);
4490 		if (HALMAC_RET_SUCCESS != status)
4491 			return -1;
4492 	}
4493 
4494 	return 0;
4495 }
4496 
rtw_halmac_write_bt_physical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)4497 int rtw_halmac_write_bt_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4498 {
4499 	struct halmac_adapter *mac;
4500 	struct halmac_api *api;
4501 	enum halmac_ret_status status;
4502 	u32 i;
4503 	u8 bank = 1;
4504 
4505 
4506 	mac = dvobj_to_halmac(d);
4507 	api = HALMAC_GET_API(mac);
4508 
4509 	for (i = 0; i < cnt; i++) {
4510 		status = api->halmac_write_efuse_bt(mac, offset + i, data[i], bank);
4511 		if (HALMAC_RET_SUCCESS != status) {
4512 			printk("%s: halmac_write_efuse_bt status = %d\n", __FUNCTION__, status);
4513 			return -1;
4514 		}
4515 	}
4516 	printk("%s: halmac_write_efuse_bt status = HALMAC_RET_SUCCESS %d\n", __FUNCTION__, status);
4517 	return 0;
4518 }
4519 
4520 
rtw_halmac_read_bt_physical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size)4521 int rtw_halmac_read_bt_physical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size)
4522 {
4523 	struct halmac_adapter *mac;
4524 	struct halmac_api *api;
4525 	enum halmac_ret_status status;
4526 	int bank = 1;
4527 
4528 
4529 	mac = dvobj_to_halmac(d);
4530 	api = HALMAC_GET_API(mac);
4531 
4532 	status = api->halmac_dump_efuse_map_bt(mac, bank, size, map);
4533 	if (HALMAC_RET_SUCCESS != status) {
4534 		printk("%s: halmac_dump_efuse_map_bt fail!\n", __FUNCTION__);
4535 		return -1;
4536 	}
4537 
4538 	printk("%s: OK!\n", __FUNCTION__);
4539 
4540 	return 0;
4541 }
4542 
_fifo_sel_drv2halmac(u8 fifo_sel)4543 static enum hal_fifo_sel _fifo_sel_drv2halmac(u8 fifo_sel)
4544 {
4545 	switch (fifo_sel) {
4546 	case 0:
4547 		return HAL_FIFO_SEL_TX;
4548 	case 1:
4549 		return HAL_FIFO_SEL_RX;
4550 	case 2:
4551 		return HAL_FIFO_SEL_RSVD_PAGE;
4552 	case 3:
4553 		return HAL_FIFO_SEL_REPORT;
4554 	case 4:
4555 		return HAL_FIFO_SEL_LLT;
4556 	case 5:
4557 		return HAL_FIFO_SEL_RXBUF_FW;
4558 	}
4559 
4560 	return HAL_FIFO_SEL_RSVD_PAGE;
4561 }
4562 
4563 /*#define CONFIG_HALMAC_FIFO_DUMP*/
rtw_halmac_dump_fifo(struct dvobj_priv * d,u8 fifo_sel,u32 addr,u32 size,u8 * buffer)4564 int rtw_halmac_dump_fifo(struct dvobj_priv *d, u8 fifo_sel, u32 addr, u32 size, u8 *buffer)
4565 {
4566 	struct halmac_adapter *mac;
4567 	struct halmac_api *api;
4568 	enum hal_fifo_sel halmac_fifo_sel;
4569 	enum halmac_ret_status status;
4570 	u8 *pfifo_map = NULL;
4571 	u32 fifo_size = 0;
4572 	s8 ret = 0;/* 0:success, -1:error */
4573 	u8 mem_created = _FALSE;
4574 
4575 
4576 	mac = dvobj_to_halmac(d);
4577 	api = HALMAC_GET_API(mac);
4578 
4579 	if ((size != 0) && (buffer == NULL))
4580 		return -1;
4581 
4582 	halmac_fifo_sel = _fifo_sel_drv2halmac(fifo_sel);
4583 
4584 	if ((size) && (buffer)) {
4585 		pfifo_map = buffer;
4586 		fifo_size = size;
4587 	} else {
4588 		fifo_size = api->halmac_get_fifo_size(mac, halmac_fifo_sel);
4589 
4590 		if (fifo_size)
4591 			pfifo_map = rtw_zvmalloc(fifo_size);
4592 		if (pfifo_map == NULL)
4593 			return -1;
4594 		mem_created = _TRUE;
4595 	}
4596 
4597 	status = api->halmac_dump_fifo(mac, halmac_fifo_sel, addr, fifo_size, pfifo_map);
4598 	if (HALMAC_RET_SUCCESS != status) {
4599 		ret = -1;
4600 		goto _exit;
4601 	}
4602 
4603 #ifdef CONFIG_HALMAC_FIFO_DUMP
4604 	{
4605 		static const char * const fifo_sel_str[] = {
4606 			"TX", "RX", "RSVD_PAGE", "REPORT", "LLT", "RXBUF_FW"
4607 		};
4608 
4609 		RTW_INFO("%s FIFO DUMP [start_addr:0x%04x , size:%d]\n", fifo_sel_str[halmac_fifo_sel], addr, fifo_size);
4610 		RTW_INFO_DUMP("\n", pfifo_map, fifo_size);
4611 		RTW_INFO(" ==================================================\n");
4612 	}
4613 #endif /* CONFIG_HALMAC_FIFO_DUMP */
4614 
4615 _exit:
4616 	if ((mem_created == _TRUE) && pfifo_map)
4617 		rtw_vmfree(pfifo_map, fifo_size);
4618 
4619 	return ret;
4620 }
4621 
4622 /*
4623  * rtw_halmac_rx_agg_switch() - Switch RX aggregation function and setting
4624  * @d		struct dvobj_priv *
4625  * @enable	_FALSE/_TRUE for disable/enable RX aggregation function
4626  *
4627  * This function could help to on/off bus RX aggregation function, and is only
4628  * useful for SDIO and USB interface. Although only "enable" flag is brough in,
4629  * some setting would be taken from other places, and they are from:
4630  * [DMA aggregation]
4631  *	struct hal_com_data.rxagg_dma_size
4632  *	struct hal_com_data.rxagg_dma_timeout
4633  * [USB aggregation] (only use for USB interface)
4634  *	struct hal_com_data.rxagg_usb_size
4635  *	struct hal_com_data.rxagg_usb_timeout
4636  * If above values of size and timeout are both 0 means driver would not
4637  * control the threshold setting and leave it to HALMAC handle.
4638  *
4639  * From HALMAC V1_04_04, driver force the size threshold be hard limit, and the
4640  * rx size can not exceed the setting.
4641  *
4642  * Return 0 for success, otherwise fail.
4643  */
rtw_halmac_rx_agg_switch(struct dvobj_priv * d,u8 enable)4644 int rtw_halmac_rx_agg_switch(struct dvobj_priv *d, u8 enable)
4645 {
4646 	struct _ADAPTER *adapter;
4647 	struct hal_com_data *hal;
4648 	struct halmac_adapter *halmac;
4649 	struct halmac_api *api;
4650 	struct halmac_rxagg_cfg rxaggcfg;
4651 	enum halmac_ret_status status;
4652 
4653 
4654 	adapter = dvobj_get_primary_adapter(d);
4655 	hal = GET_HAL_DATA(adapter);
4656 	halmac = dvobj_to_halmac(d);
4657 	api = HALMAC_GET_API(halmac);
4658 	_rtw_memset((void *)&rxaggcfg, 0, sizeof(rxaggcfg));
4659 	rxaggcfg.mode = HALMAC_RX_AGG_MODE_NONE;
4660 	/*
4661 	 * Always enable size limit to avoid rx size exceed
4662 	 * driver defined size.
4663 	 */
4664 	rxaggcfg.threshold.size_limit_en = 1;
4665 
4666 #ifdef RTW_RX_AGGREGATION
4667 	if (_TRUE == enable) {
4668 #ifdef CONFIG_SDIO_HCI
4669 		rxaggcfg.mode = HALMAC_RX_AGG_MODE_DMA;
4670 		rxaggcfg.threshold.drv_define = 0;
4671 		if (hal->rxagg_dma_size || hal->rxagg_dma_timeout) {
4672 			rxaggcfg.threshold.drv_define = 1;
4673 			rxaggcfg.threshold.timeout = hal->rxagg_dma_timeout;
4674 			rxaggcfg.threshold.size = hal->rxagg_dma_size;
4675 			RTW_INFO("%s: RX aggregation threshold: "
4676 				 "timeout=%u size=%u\n",
4677 				 __FUNCTION__,
4678 				 hal->rxagg_dma_timeout,
4679 				 hal->rxagg_dma_size);
4680 		}
4681 #elif defined(CONFIG_USB_HCI)
4682 		switch (hal->rxagg_mode) {
4683 		case RX_AGG_DISABLE:
4684 			rxaggcfg.mode = HALMAC_RX_AGG_MODE_NONE;
4685 			break;
4686 
4687 		case RX_AGG_DMA:
4688 			rxaggcfg.mode = HALMAC_RX_AGG_MODE_DMA;
4689 			if (hal->rxagg_dma_size || hal->rxagg_dma_timeout) {
4690 				rxaggcfg.threshold.drv_define = 1;
4691 				rxaggcfg.threshold.timeout = hal->rxagg_dma_timeout;
4692 				rxaggcfg.threshold.size = hal->rxagg_dma_size;
4693 			}
4694 			break;
4695 
4696 		case RX_AGG_USB:
4697 		case RX_AGG_MIX:
4698 			rxaggcfg.mode = HALMAC_RX_AGG_MODE_USB;
4699 			if (hal->rxagg_usb_size || hal->rxagg_usb_timeout) {
4700 				rxaggcfg.threshold.drv_define = 1;
4701 				rxaggcfg.threshold.timeout = hal->rxagg_usb_timeout;
4702 				rxaggcfg.threshold.size = hal->rxagg_usb_size;
4703 			}
4704 			break;
4705 		}
4706 #endif /* CONFIG_USB_HCI */
4707 	}
4708 #endif /* RTW_RX_AGGREGATION */
4709 
4710 	status = api->halmac_cfg_rx_aggregation(halmac, &rxaggcfg);
4711 	if (status != HALMAC_RET_SUCCESS)
4712 		return -1;
4713 
4714 	return 0;
4715 }
4716 
rtw_halmac_download_rsvd_page(struct dvobj_priv * dvobj,u8 pg_offset,u8 * pbuf,u32 size)4717 int rtw_halmac_download_rsvd_page(struct dvobj_priv *dvobj, u8 pg_offset, u8 *pbuf, u32 size)
4718 {
4719 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4720 	struct halmac_adapter *halmac = dvobj_to_halmac(dvobj);
4721 	struct halmac_api *api = HALMAC_GET_API(halmac);
4722 
4723 	status = api->halmac_dl_drv_rsvd_page(halmac, pg_offset, pbuf, size);
4724 	if (status != HALMAC_RET_SUCCESS)
4725 		return -1;
4726 
4727 	return 0;
4728 }
4729 
4730 /*
4731  * Description
4732  *	Fill following spec info from HALMAC API:
4733  *	sec_cam_ent_num
4734  *
4735  * Return
4736  *	0	Success
4737  *	others	Fail
4738  */
rtw_halmac_fill_hal_spec(struct dvobj_priv * dvobj,struct hal_spec_t * spec)4739 int rtw_halmac_fill_hal_spec(struct dvobj_priv *dvobj, struct hal_spec_t *spec)
4740 {
4741 	enum halmac_ret_status status;
4742 	struct halmac_adapter *halmac;
4743 	struct halmac_api *api;
4744 	u8 cam = 0;	/* Security Cam Entry Number */
4745 
4746 
4747 	halmac = dvobj_to_halmac(dvobj);
4748 	api = HALMAC_GET_API(halmac);
4749 
4750 	/* Prepare data from HALMAC */
4751 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_CAM_ENTRY_NUM, &cam);
4752 	if (status != HALMAC_RET_SUCCESS)
4753 		return -1;
4754 
4755 	/* Fill data to hal_spec_t */
4756 	spec->sec_cam_ent_num = cam;
4757 
4758 	return 0;
4759 }
4760 
rtw_halmac_p2pps(struct dvobj_priv * dvobj,struct hal_p2p_ps_para * pp2p_ps_para)4761 int rtw_halmac_p2pps(struct dvobj_priv *dvobj, struct hal_p2p_ps_para *pp2p_ps_para)
4762 {
4763 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4764 	struct halmac_adapter *halmac = dvobj_to_halmac(dvobj);
4765 	struct halmac_api *api = HALMAC_GET_API(halmac);
4766 	struct halmac_p2pps halmac_p2p_ps;
4767 
4768 	(&halmac_p2p_ps)->offload_en = pp2p_ps_para->offload_en;
4769 	(&halmac_p2p_ps)->role = pp2p_ps_para->role;
4770 	(&halmac_p2p_ps)->ctwindow_en = pp2p_ps_para->ctwindow_en;
4771 	(&halmac_p2p_ps)->noa_en = pp2p_ps_para->noa_en;
4772 	(&halmac_p2p_ps)->noa_sel = pp2p_ps_para->noa_sel;
4773 	(&halmac_p2p_ps)->all_sta_sleep = pp2p_ps_para->all_sta_sleep;
4774 	(&halmac_p2p_ps)->discovery = pp2p_ps_para->discovery;
4775 	(&halmac_p2p_ps)->disable_close_rf = pp2p_ps_para->disable_close_rf;
4776 	(&halmac_p2p_ps)->p2p_port_id = _hw_port_drv2halmac(pp2p_ps_para->p2p_port_id);
4777 	(&halmac_p2p_ps)->p2p_group = pp2p_ps_para->p2p_group;
4778 	(&halmac_p2p_ps)->p2p_macid = pp2p_ps_para->p2p_macid;
4779 	(&halmac_p2p_ps)->ctwindow_length = pp2p_ps_para->ctwindow_length;
4780 	(&halmac_p2p_ps)->noa_duration_para = pp2p_ps_para->noa_duration_para;
4781 	(&halmac_p2p_ps)->noa_interval_para = pp2p_ps_para->noa_interval_para;
4782 	(&halmac_p2p_ps)->noa_start_time_para = pp2p_ps_para->noa_start_time_para;
4783 	(&halmac_p2p_ps)->noa_count_para = pp2p_ps_para->noa_count_para;
4784 
4785 	status = api->halmac_p2pps(halmac, (&halmac_p2p_ps));
4786 	if (status != HALMAC_RET_SUCCESS)
4787 		return -1;
4788 
4789 	return 0;
4790 
4791 }
4792 
4793 /**
4794  * rtw_halmac_iqk() - Run IQ Calibration
4795  * @d:		struct dvobj_priv*
4796  * @clear:	IQK parameters
4797  * @segment:	IQK parameters
4798  *
4799  * Process IQ Calibration(IQK).
4800  *
4801  * Return 0 for OK, otherwise fail.
4802  */
rtw_halmac_iqk(struct dvobj_priv * d,u8 clear,u8 segment)4803 int rtw_halmac_iqk(struct dvobj_priv *d, u8 clear, u8 segment)
4804 {
4805 	struct halmac_adapter *mac;
4806 	struct halmac_api *api;
4807 	enum halmac_ret_status status;
4808 	enum halmac_feature_id id;
4809 	struct halmac_iqk_para para;
4810 	int ret;
4811 	u8 retry = 3;
4812 	u8 delay = 1; /* ms */
4813 
4814 
4815 	mac = dvobj_to_halmac(d);
4816 	api = HALMAC_GET_API(mac);
4817 	id = HALMAC_FEATURE_IQK;
4818 
4819 	ret = init_halmac_event(d, id, NULL, 0);
4820 	if (ret)
4821 		return -1;
4822 
4823 	para.clear = clear;
4824 	para.segment_iqk = segment;
4825 
4826 	do {
4827 		status = api->halmac_start_iqk(mac, &para);
4828 		if (status != HALMAC_RET_BUSY_STATE)
4829 			break;
4830 		RTW_WARN("%s: Fail to start IQK, status is BUSY! retry=%d\n", __FUNCTION__, retry);
4831 		if (!retry)
4832 			break;
4833 		retry--;
4834 		rtw_msleep_os(delay);
4835 	} while (1);
4836 	if (status != HALMAC_RET_SUCCESS) {
4837 		free_halmac_event(d, id);
4838 		return -1;
4839 	}
4840 
4841 	ret = wait_halmac_event(d, id);
4842 	if (ret)
4843 		return -1;
4844 
4845 	return 0;
4846 }
4847 
4848 /**
4849  * rtw_halmac_dpk() - Run DP Calibration
4850  * @d:		struct dvobj_priv*
4851  * @buf:	buffer for store return value
4852  * @bufsz:	size of buffer
4853  *
4854  * Process DP Calibration(DPK).
4855  *
4856  * Return 0 for OK, otherwise fail.
4857  */
rtw_halmac_dpk(struct dvobj_priv * d,u8 * buf,u32 bufsz)4858 int rtw_halmac_dpk(struct dvobj_priv *d, u8 *buf, u32 bufsz)
4859 {
4860 	struct halmac_adapter *mac;
4861 	struct halmac_api *api;
4862 	enum halmac_ret_status status;
4863 	enum halmac_feature_id id;
4864 	int ret;
4865 
4866 
4867 	mac = dvobj_to_halmac(d);
4868 	api = HALMAC_GET_API(mac);
4869 	id = HALMAC_FEATURE_DPK;
4870 
4871 	ret = init_halmac_event(d, id, buf, bufsz);
4872 	if (ret)
4873 		return -1;
4874 
4875 	status = api->halmac_start_dpk(mac);
4876 	if (status != HALMAC_RET_SUCCESS) {
4877 		free_halmac_event(d, id);
4878 		RTW_ERR("%s: Fail to start DPK (0x%x)!\n",
4879 			__FUNCTION__, status);
4880 		return -1;
4881 	}
4882 
4883 	ret = wait_halmac_event(d, id);
4884 	if (ret)
4885 		return -1;
4886 
4887 	return 0;
4888 }
4889 
_phy_parameter_val_drv2halmac(u32 val,u8 msk_en,u32 msk)4890 static inline u32 _phy_parameter_val_drv2halmac(u32 val, u8 msk_en, u32 msk)
4891 {
4892 	if (!msk_en)
4893 		return val;
4894 
4895 	return (val << bitshift(msk));
4896 }
4897 
_phy_parameter_drv2halmac(struct rtw_phy_parameter * para,struct halmac_phy_parameter_info * info)4898 static int _phy_parameter_drv2halmac(struct rtw_phy_parameter *para, struct halmac_phy_parameter_info *info)
4899 {
4900 	if (!para || !info)
4901 		return -1;
4902 
4903 	_rtw_memset(info, 0, sizeof(*info));
4904 
4905 	switch (para->cmd) {
4906 	case 0:
4907 		/* MAC register */
4908 		switch (para->data.mac.size) {
4909 		case 1:
4910 			info->cmd_id = HALMAC_PARAMETER_CMD_MAC_W8;
4911 			break;
4912 		case 2:
4913 			info->cmd_id = HALMAC_PARAMETER_CMD_MAC_W16;
4914 			break;
4915 		default:
4916 			info->cmd_id = HALMAC_PARAMETER_CMD_MAC_W32;
4917 			break;
4918 		}
4919 		info->content.MAC_REG_W.value = _phy_parameter_val_drv2halmac(
4920 							para->data.mac.value,
4921 							para->data.mac.msk_en,
4922 							para->data.mac.msk);
4923 		info->content.MAC_REG_W.msk = para->data.mac.msk;
4924 		info->content.MAC_REG_W.offset = para->data.mac.offset;
4925 		info->content.MAC_REG_W.msk_en = para->data.mac.msk_en;
4926 		break;
4927 
4928 	case 1:
4929 		/* BB register */
4930 		switch (para->data.bb.size) {
4931 		case 1:
4932 			info->cmd_id = HALMAC_PARAMETER_CMD_BB_W8;
4933 			break;
4934 		case 2:
4935 			info->cmd_id = HALMAC_PARAMETER_CMD_BB_W16;
4936 			break;
4937 		default:
4938 			info->cmd_id = HALMAC_PARAMETER_CMD_BB_W32;
4939 			break;
4940 		}
4941 		info->content.BB_REG_W.value = _phy_parameter_val_drv2halmac(
4942 							para->data.bb.value,
4943 							para->data.bb.msk_en,
4944 							para->data.bb.msk);
4945 		info->content.BB_REG_W.msk = para->data.bb.msk;
4946 		info->content.BB_REG_W.offset = para->data.bb.offset;
4947 		info->content.BB_REG_W.msk_en = para->data.bb.msk_en;
4948 		break;
4949 
4950 	case 2:
4951 		/* RF register */
4952 		info->cmd_id = HALMAC_PARAMETER_CMD_RF_W;
4953 		info->content.RF_REG_W.value = _phy_parameter_val_drv2halmac(
4954 							para->data.rf.value,
4955 							para->data.rf.msk_en,
4956 							para->data.rf.msk);
4957 		info->content.RF_REG_W.msk = para->data.rf.msk;
4958 		info->content.RF_REG_W.offset = para->data.rf.offset;
4959 		info->content.RF_REG_W.msk_en = para->data.rf.msk_en;
4960 		info->content.RF_REG_W.rf_path = para->data.rf.path;
4961 		break;
4962 
4963 	case 3:
4964 		/* Delay register */
4965 		if (para->data.delay.unit == 0)
4966 			info->cmd_id = HALMAC_PARAMETER_CMD_DELAY_US;
4967 		else
4968 			info->cmd_id = HALMAC_PARAMETER_CMD_DELAY_MS;
4969 		info->content.DELAY_TIME.delay_time = para->data.delay.value;
4970 		break;
4971 
4972 	case 0xFF:
4973 		/* Latest(End) command */
4974 		info->cmd_id = HALMAC_PARAMETER_CMD_END;
4975 		break;
4976 
4977 	default:
4978 		return -1;
4979 	}
4980 
4981 	return 0;
4982 }
4983 
4984 /**
4985  * rtw_halmac_cfg_phy_para() - Register(Phy parameter) configuration
4986  * @d:		struct dvobj_priv*
4987  * @para:	phy parameter
4988  *
4989  * Configure registers by firmware using H2C/C2H mechanism.
4990  * The latest command should be para->cmd==0xFF(End command) to finish all
4991  * processes.
4992  *
4993  * Return: 0 for OK, otherwise fail.
4994  */
rtw_halmac_cfg_phy_para(struct dvobj_priv * d,struct rtw_phy_parameter * para)4995 int rtw_halmac_cfg_phy_para(struct dvobj_priv *d, struct rtw_phy_parameter *para)
4996 {
4997 	struct halmac_adapter *mac;
4998 	struct halmac_api *api;
4999 	enum halmac_ret_status status;
5000 	enum halmac_feature_id id;
5001 	struct halmac_phy_parameter_info info;
5002 	u8 full_fifo;
5003 	int err, ret;
5004 
5005 
5006 	mac = dvobj_to_halmac(d);
5007 	api = HALMAC_GET_API(mac);
5008 	id = HALMAC_FEATURE_CFG_PARA;
5009 	full_fifo = 1; /* ToDo: How to deciede? */
5010 	ret = 0;
5011 
5012 	err = _phy_parameter_drv2halmac(para, &info);
5013 	if (err)
5014 		return -1;
5015 
5016 	err = init_halmac_event(d, id, NULL, 0);
5017 	if (err)
5018 		return -1;
5019 
5020 	status = api->halmac_cfg_parameter(mac, &info, full_fifo);
5021 	if (info.cmd_id == HALMAC_PARAMETER_CMD_END) {
5022 		if (status == HALMAC_RET_SUCCESS) {
5023 			err = wait_halmac_event(d, id);
5024 			if (err)
5025 				ret = -1;
5026 		} else {
5027 			free_halmac_event(d, id);
5028 			ret = -1;
5029 			RTW_ERR("%s: Fail to send END of cfg parameter, status is 0x%x!\n", __FUNCTION__, status);
5030 		}
5031 	} else {
5032 		if (status == HALMAC_RET_PARA_SENDING) {
5033 			err = wait_halmac_event(d, id);
5034 			if (err)
5035 				ret = -1;
5036 		} else {
5037 			free_halmac_event(d, id);
5038 			if (status != HALMAC_RET_SUCCESS) {
5039 				ret = -1;
5040 				RTW_ERR("%s: Fail to cfg parameter, status is 0x%x!\n", __FUNCTION__, status);
5041 			}
5042 		}
5043 	}
5044 
5045 	return ret;
5046 }
5047 
_led_mode_drv2halmac(u8 drv_mode)5048 static enum halmac_wlled_mode _led_mode_drv2halmac(u8 drv_mode)
5049 {
5050 	enum halmac_wlled_mode halmac_mode;
5051 
5052 
5053 	switch (drv_mode) {
5054 	case 1:
5055 		halmac_mode = HALMAC_WLLED_MODE_TX;
5056 		break;
5057 	case 2:
5058 		halmac_mode = HALMAC_WLLED_MODE_RX;
5059 		break;
5060 	case 3:
5061 		halmac_mode = HALMAC_WLLED_MODE_SW_CTRL;
5062 		break;
5063 	case 0:
5064 	default:
5065 		halmac_mode = HALMAC_WLLED_MODE_TRX;
5066 		break;
5067 	}
5068 
5069 	return halmac_mode;
5070 }
5071 
5072 /**
5073  * rtw_halmac_led_cfg() - Configure Hardware LED Mode
5074  * @d:		struct dvobj_priv*
5075  * @enable:	enable or disable LED function
5076  *		0: disable
5077  *		1: enable
5078  * @mode:	WLan LED mode (valid when enable==1)
5079  *		0: Blink when TX(transmit packet) and RX(receive packet)
5080  *		1: Blink when TX only
5081  *		2: Blink when RX only
5082  *		3: Software control
5083  *
5084  * Configure hardware WLan LED mode.
5085  * If want to change LED mode after enabled, need to disable LED first and
5086  * enable again to set new mode.
5087  *
5088  * Return 0 for OK, otherwise fail.
5089  */
rtw_halmac_led_cfg(struct dvobj_priv * d,u8 enable,u8 mode)5090 int rtw_halmac_led_cfg(struct dvobj_priv *d, u8 enable, u8 mode)
5091 {
5092 	struct halmac_adapter *halmac;
5093 	struct halmac_api *api;
5094 	enum halmac_wlled_mode led_mode;
5095 	enum halmac_ret_status status;
5096 
5097 
5098 	halmac = dvobj_to_halmac(d);
5099 	api = HALMAC_GET_API(halmac);
5100 
5101 	if (enable) {
5102 		status = api->halmac_pinmux_set_func(halmac,
5103 						     HALMAC_GPIO_FUNC_WL_LED);
5104 		if (status != HALMAC_RET_SUCCESS) {
5105 			RTW_ERR("%s: pinmux set fail!(0x%x)\n",
5106 				__FUNCTION__, status);
5107 			return -1;
5108 		}
5109 
5110 		led_mode = _led_mode_drv2halmac(mode);
5111 		status = api->halmac_pinmux_wl_led_mode(halmac, led_mode);
5112 		if (status != HALMAC_RET_SUCCESS) {
5113 			RTW_ERR("%s: mode set fail!(0x%x)\n",
5114 				__FUNCTION__, status);
5115 			return -1;
5116 		}
5117 	} else {
5118 		/* Change LED to software control and turn off */
5119 		api->halmac_pinmux_wl_led_mode(halmac,
5120 					       HALMAC_WLLED_MODE_SW_CTRL);
5121 		api->halmac_pinmux_wl_led_sw_ctrl(halmac, 0);
5122 
5123 		status = api->halmac_pinmux_free_func(halmac,
5124 						      HALMAC_GPIO_FUNC_WL_LED);
5125 		if (status != HALMAC_RET_SUCCESS) {
5126 			RTW_ERR("%s: pinmux free fail!(0x%x)\n",
5127 				__FUNCTION__, status);
5128 			return -1;
5129 		}
5130 	}
5131 
5132 	return 0;
5133 }
5134 
5135 /**
5136  * rtw_halmac_led_switch() - Turn Hardware LED on/off
5137  * @d:		struct dvobj_priv*
5138  * @on:		LED light or not
5139  *		0: Off
5140  *		1: On(Light)
5141  *
5142  * Turn Hardware WLan LED On/Off.
5143  * Before use this function, user should call rtw_halmac_led_ctrl() to switch
5144  * mode to "software control(3)" first, otherwise control would fail.
5145  * The interval between on and off must be longer than 1 ms, or the LED would
5146  * keep light or dark only.
5147  * Ex. Turn off LED at first, turn on after 0.5ms and turn off again after
5148  * 0.5ms. The LED during this flow will only keep dark, and miss the turn on
5149  * operation between two turn off operations.
5150  */
rtw_halmac_led_switch(struct dvobj_priv * d,u8 on)5151 void rtw_halmac_led_switch(struct dvobj_priv *d, u8 on)
5152 {
5153 	struct halmac_adapter *halmac;
5154 	struct halmac_api *api;
5155 
5156 
5157 	halmac = dvobj_to_halmac(d);
5158 	api = HALMAC_GET_API(halmac);
5159 
5160 	api->halmac_pinmux_wl_led_sw_ctrl(halmac, on);
5161 }
5162 
5163 /**
5164  * rtw_halmac_bt_wake_cfg() - Configure BT wake host function
5165  * @d:		struct dvobj_priv*
5166  * @enable:	enable or disable BT wake host function
5167  *		0: disable
5168  *		1: enable
5169  *
5170  * Configure pinmux to allow BT to control BT wake host pin.
5171  *
5172  * Return 0 for OK, otherwise fail.
5173  */
rtw_halmac_bt_wake_cfg(struct dvobj_priv * d,u8 enable)5174 int rtw_halmac_bt_wake_cfg(struct dvobj_priv *d, u8 enable)
5175 {
5176 	struct halmac_adapter *halmac;
5177 	struct halmac_api *api;
5178 	enum halmac_ret_status status;
5179 
5180 
5181 	halmac = dvobj_to_halmac(d);
5182 	api = HALMAC_GET_API(halmac);
5183 
5184 	if (enable) {
5185 		status = api->halmac_pinmux_set_func(halmac,
5186 						HALMAC_GPIO_FUNC_BT_HOST_WAKE1);
5187 		if (status != HALMAC_RET_SUCCESS) {
5188 			RTW_ERR("%s: pinmux set BT_HOST_WAKE1 fail!(0x%x)\n",
5189 				__FUNCTION__, status);
5190 			return -1;
5191 		}
5192 	} else {
5193 		status = api->halmac_pinmux_free_func(halmac,
5194 						HALMAC_GPIO_FUNC_BT_HOST_WAKE1);
5195 		if (status != HALMAC_RET_SUCCESS) {
5196 			RTW_ERR("%s: pinmux free BT_HOST_WAKE1 fail!(0x%x)\n",
5197 				__FUNCTION__, status);
5198 			return -1;
5199 		}
5200 	}
5201 
5202 	return 0;
5203 }
5204 
5205 #ifdef CONFIG_PNO_SUPPORT
5206 /**
5207  * _halmac_scanoffload() - Switch channel by firmware during scanning
5208  * @d:		struct dvobj_priv*
5209  * @enable:	1: enable, 0: disable
5210  * @nlo:	1: nlo mode (no c2h event), 0: normal mode
5211  * @ssid:	ssid of probe request
5212  * @ssid_len:	ssid length
5213  *
5214  * Switch Channel and Send Porbe Request Offloaded by FW
5215  *
5216  * Return 0 for OK, otherwise fail.
5217  */
_halmac_scanoffload(struct dvobj_priv * d,u32 enable,u8 nlo,u8 * ssid,u8 ssid_len)5218 static int _halmac_scanoffload(struct dvobj_priv *d, u32 enable, u8 nlo,
5219 			       u8 *ssid, u8 ssid_len)
5220 {
5221 	struct _ADAPTER *adapter;
5222 	struct halmac_adapter *mac;
5223 	struct halmac_api *api;
5224 	enum halmac_ret_status status;
5225 	struct halmac_ch_info ch_info;
5226 	struct halmac_ch_switch_option cs_option;
5227 	struct mlme_ext_priv *pmlmeext;
5228 	enum halmac_feature_id id_update, id_ch_sw;
5229 	struct halmac_indicator *indicator, *tbl;
5230 
5231 	int err = 0;
5232 	u8 probereq[64];
5233 	u32 len = 0;
5234 	int i = 0;
5235 	struct pno_ssid pnossid;
5236 	struct rf_ctl_t *rfctl = NULL;
5237 	struct _RT_CHANNEL_INFO *ch_set;
5238 
5239 
5240 	tbl = d->hmpriv.indicator;
5241 	adapter = dvobj_get_primary_adapter(d);
5242 	mac = dvobj_to_halmac(d);
5243 	if (!mac)
5244 		return -1;
5245 	api = HALMAC_GET_API(mac);
5246 	id_update = HALMAC_FEATURE_UPDATE_PACKET;
5247 	id_ch_sw = HALMAC_FEATURE_CHANNEL_SWITCH;
5248 	pmlmeext = &(adapter->mlmeextpriv);
5249 	rfctl = adapter_to_rfctl(adapter);
5250 	ch_set = rfctl->channel_set;
5251 
5252 	RTW_INFO("%s: %s scanoffload, mode: %s\n",
5253 		 __FUNCTION__, enable?"Enable":"Disable",
5254 		 nlo?"PNO/NLO":"Normal");
5255 
5256 	if (enable) {
5257 		_rtw_memset(probereq, 0, sizeof(probereq));
5258 
5259 		_rtw_memset(&pnossid, 0, sizeof(pnossid));
5260 		if (ssid) {
5261 			if (ssid_len > sizeof(pnossid.SSID)) {
5262 				RTW_ERR("%s: SSID length(%d) is too long(>%d)!!\n",
5263 					__FUNCTION__, ssid_len, sizeof(pnossid.SSID));
5264 				return -1;
5265 			}
5266 
5267 			pnossid.SSID_len = ssid_len;
5268 			_rtw_memcpy(pnossid.SSID, ssid, ssid_len);
5269 		}
5270 
5271 		rtw_hal_construct_ProbeReq(adapter, probereq, &len, &pnossid);
5272 
5273 		if (!nlo) {
5274 			err = init_halmac_event(d, id_update, NULL, 0);
5275 			if (err)
5276 				return -1;
5277 		}
5278 
5279 		status = api->halmac_update_packet(mac, HALMAC_PACKET_PROBE_REQ,
5280 						   probereq, len);
5281 		if (status != HALMAC_RET_SUCCESS) {
5282 			if (!nlo)
5283 				free_halmac_event(d, id_update);
5284 			RTW_ERR("%s: halmac_update_packet FAIL(%d)!!\n",
5285 				__FUNCTION__, status);
5286 			return -1;
5287 		}
5288 
5289 		if (!nlo) {
5290 			err = wait_halmac_event(d, id_update);
5291 			if (err)
5292 				RTW_ERR("%s: wait update packet FAIL(%d)!!\n",
5293 					__FUNCTION__, err);
5294 		}
5295 
5296 		api->halmac_clear_ch_info(mac);
5297 
5298 		for (i = 0; i < rfctl->max_chan_nums && ch_set[i].ChannelNum != 0; i++) {
5299 			_rtw_memset(&ch_info, 0, sizeof(ch_info));
5300 			ch_info.extra_info = 0;
5301 			ch_info.channel = ch_set[i].ChannelNum;
5302 			ch_info.bw = HALMAC_BW_20;
5303 			ch_info.pri_ch_idx = HALMAC_CH_IDX_1;
5304 			ch_info.action_id = HALMAC_CS_ACTIVE_SCAN;
5305 			ch_info.timeout = 1;
5306 			status = api->halmac_add_ch_info(mac, &ch_info);
5307 			if (status != HALMAC_RET_SUCCESS) {
5308 				RTW_ERR("%s: add_ch_info FAIL(%d)!!\n",
5309 					__FUNCTION__, status);
5310 				return -1;
5311 			}
5312 		}
5313 
5314 		/* set channel switch option */
5315 		_rtw_memset(&cs_option, 0, sizeof(cs_option));
5316 		cs_option.dest_bw = HALMAC_BW_20;
5317 		cs_option.periodic_option = HALMAC_CS_PERIODIC_2_PHASE;
5318 		cs_option.dest_pri_ch_idx = HALMAC_CH_IDX_UNDEFINE;
5319 		cs_option.tsf_low = 0;
5320 		cs_option.switch_en = 1;
5321 		cs_option.dest_ch_en = 1;
5322 		cs_option.absolute_time_en = 0;
5323 		cs_option.dest_ch = 1;
5324 
5325 		cs_option.normal_period = 5;
5326 		cs_option.normal_period_sel = 0;
5327 		cs_option.normal_cycle = 10;
5328 
5329 		cs_option.phase_2_period = 1;
5330 		cs_option.phase_2_period_sel = 1;
5331 
5332 		/* nlo is for wow fw,  1: no c2h response */
5333 		cs_option.nlo_en = nlo;
5334 
5335 		if (!nlo) {
5336 			err = init_halmac_event(d, id_ch_sw, NULL, 0);
5337 			if (err)
5338 				return -1;
5339 		}
5340 
5341 		status = api->halmac_ctrl_ch_switch(mac, &cs_option);
5342 		if (status != HALMAC_RET_SUCCESS) {
5343 			if (!nlo)
5344 				free_halmac_event(d, id_ch_sw);
5345 			RTW_ERR("%s: halmac_ctrl_ch_switch FAIL(%d)!!\n",
5346 				__FUNCTION__, status);
5347 			return -1;
5348 		}
5349 
5350 		if (!nlo) {
5351 			err = wait_halmac_event(d, id_ch_sw);
5352 			if (err)
5353 				RTW_ERR("%s: wait ctrl_ch_switch FAIL(%d)!!\n",
5354 					__FUNCTION__, err);
5355 		}
5356 	} else {
5357 		api->halmac_clear_ch_info(mac);
5358 
5359 		_rtw_memset(&cs_option, 0, sizeof(cs_option));
5360 		cs_option.switch_en = 0;
5361 
5362 		if (!nlo) {
5363 			err = init_halmac_event(d, id_ch_sw, NULL, 0);
5364 			if (err)
5365 				return -1;
5366 		}
5367 
5368 		status = api->halmac_ctrl_ch_switch(mac, &cs_option);
5369 		if (status != HALMAC_RET_SUCCESS) {
5370 			if (!nlo)
5371 				free_halmac_event(d, id_ch_sw);
5372 			RTW_ERR("%s: halmac_ctrl_ch_switch FAIL(%d)!!\n",
5373 				__FUNCTION__, status);
5374 			return -1;
5375 		}
5376 
5377 		if (!nlo) {
5378 			err = wait_halmac_event(d, id_ch_sw);
5379 			if (err)
5380 				RTW_ERR("%s: wait ctrl_ch_switch FAIL(%d)!!\n",
5381 					__FUNCTION__, err);
5382 		}
5383 	}
5384 
5385 	return 0;
5386 }
5387 
5388 /**
5389  * rtw_halmac_pno_scanoffload() - Control firmware scan AP function for PNO
5390  * @d:		struct dvobj_priv*
5391  * @enable:	1: enable, 0: disable
5392  *
5393  * Switch firmware scan AP function for PNO(prefer network offload) or
5394  * NLO(network list offload).
5395  *
5396  * Return 0 for OK, otherwise fail.
5397  */
rtw_halmac_pno_scanoffload(struct dvobj_priv * d,u32 enable)5398 int rtw_halmac_pno_scanoffload(struct dvobj_priv *d, u32 enable)
5399 {
5400 	return _halmac_scanoffload(d, enable, 1, NULL, 0);
5401 }
5402 #endif /* CONFIG_PNO_SUPPORT */
5403 
5404 #ifdef CONFIG_SDIO_HCI
5405 
5406 /**
5407  * rtw_halmac_preinit_sdio_io_indirect() - Enable indirect I/O or not
5408  * @d:		struct dvobj_priv*
5409  * @enable:	true: enable, false: disable
5410  *
5411  * Enable register access using direct I/O or indirect. This function should be
5412  * called before rtw_halmac_init_adapter(), and the life cycle is the same as
5413  * driver until removing driver.
5414  *
5415  * Return 0 for OK, otherwise fail.
5416  */
rtw_halmac_preinit_sdio_io_indirect(struct dvobj_priv * d,bool enable)5417 int rtw_halmac_preinit_sdio_io_indirect(struct dvobj_priv *d, bool enable)
5418 {
5419 	struct halmac_adapter *halmac;
5420 	struct halmacpriv *priv;
5421 
5422 
5423 	halmac = dvobj_to_halmac(d);
5424 	if (halmac) {
5425 		RTW_WARN("%s: illegal operation! "
5426 			 "preinit function only could be called before init!\n",
5427 			 __FUNCTION__);
5428 		return -1;
5429 	}
5430 
5431 	priv = &d->hmpriv;
5432 	priv->sdio_io_indir = (enable ? 1 : 2);
5433 
5434 	return 0;
5435 }
5436 
5437 /*
5438  * Description:
5439  *	Update queue allocated page number to driver
5440  *
5441  * Parameter:
5442  *	d	pointer to struct dvobj_priv of driver
5443  *
5444  * Return:
5445  *	0	Success, "page" is valid.
5446  *	others	Fail, "page" is invalid.
5447  */
rtw_halmac_query_tx_page_num(struct dvobj_priv * d)5448 int rtw_halmac_query_tx_page_num(struct dvobj_priv *d)
5449 {
5450 	PADAPTER adapter;
5451 	struct halmacpriv *hmpriv;
5452 	struct halmac_adapter *halmac;
5453 	struct halmac_api *api;
5454 	struct halmac_rqpn_map rqpn;
5455 	enum halmac_dma_mapping dmaqueue;
5456 	struct halmac_txff_allocation fifosize;
5457 	enum halmac_ret_status status;
5458 	u8 i;
5459 
5460 
5461 	adapter = dvobj_get_primary_adapter(d);
5462 	hmpriv = &d->hmpriv;
5463 	halmac = dvobj_to_halmac(d);
5464 	api = HALMAC_GET_API(halmac);
5465 	_rtw_memset((void *)&rqpn, 0, sizeof(rqpn));
5466 	_rtw_memset((void *)&fifosize, 0, sizeof(fifosize));
5467 
5468 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RQPN_MAPPING, &rqpn);
5469 	if (status != HALMAC_RET_SUCCESS)
5470 		return -1;
5471 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_TXFF_ALLOCATION, &fifosize);
5472 	if (status != HALMAC_RET_SUCCESS)
5473 		return -1;
5474 
5475 	for (i = 0; i < HW_QUEUE_ENTRY; i++) {
5476 		hmpriv->txpage[i] = 0;
5477 
5478 		/* Driver index mapping to HALMAC DMA queue */
5479 		dmaqueue = HALMAC_DMA_MAPPING_UNDEFINE;
5480 		switch (i) {
5481 		case VO_QUEUE_INX:
5482 			dmaqueue = rqpn.dma_map_vo;
5483 			break;
5484 		case VI_QUEUE_INX:
5485 			dmaqueue = rqpn.dma_map_vi;
5486 			break;
5487 		case BE_QUEUE_INX:
5488 			dmaqueue = rqpn.dma_map_be;
5489 			break;
5490 		case BK_QUEUE_INX:
5491 			dmaqueue = rqpn.dma_map_bk;
5492 			break;
5493 		case MGT_QUEUE_INX:
5494 			dmaqueue = rqpn.dma_map_mg;
5495 			break;
5496 		case HIGH_QUEUE_INX:
5497 			dmaqueue = rqpn.dma_map_hi;
5498 			break;
5499 		case BCN_QUEUE_INX:
5500 		case TXCMD_QUEUE_INX:
5501 			/* Unlimited */
5502 			hmpriv->txpage[i] = 0xFFFF;
5503 			continue;
5504 		}
5505 
5506 		switch (dmaqueue) {
5507 		case HALMAC_DMA_MAPPING_EXTRA:
5508 			hmpriv->txpage[i] = fifosize.extra_queue_pg_num;
5509 			break;
5510 		case HALMAC_DMA_MAPPING_LOW:
5511 			hmpriv->txpage[i] = fifosize.low_queue_pg_num;
5512 			break;
5513 		case HALMAC_DMA_MAPPING_NORMAL:
5514 			hmpriv->txpage[i] = fifosize.normal_queue_pg_num;
5515 			break;
5516 		case HALMAC_DMA_MAPPING_HIGH:
5517 			hmpriv->txpage[i] = fifosize.high_queue_pg_num;
5518 			break;
5519 		case HALMAC_DMA_MAPPING_UNDEFINE:
5520 			break;
5521 		}
5522 		hmpriv->txpage[i] += fifosize.pub_queue_pg_num;
5523 	}
5524 
5525 	return 0;
5526 }
5527 
5528 /*
5529  * Description:
5530  *	Get specific queue allocated page number
5531  *
5532  * Parameter:
5533  *	d	pointer to struct dvobj_priv of driver
5534  *	queue	target queue to query, VO/VI/BE/BK/.../TXCMD_QUEUE_INX
5535  *	page	return allocated page number
5536  *
5537  * Return:
5538  *	0	Success, "page" is valid.
5539  *	others	Fail, "page" is invalid.
5540  */
rtw_halmac_get_tx_queue_page_num(struct dvobj_priv * d,u8 queue,u32 * page)5541 int rtw_halmac_get_tx_queue_page_num(struct dvobj_priv *d, u8 queue, u32 *page)
5542 {
5543 	*page = 0;
5544 	if (queue < HW_QUEUE_ENTRY)
5545 		*page = d->hmpriv.txpage[queue];
5546 
5547 	return 0;
5548 }
5549 
5550 /*
5551  * Return:
5552  *	address for SDIO command
5553  */
rtw_halmac_sdio_get_tx_addr(struct dvobj_priv * d,u8 * desc,u32 size)5554 u32 rtw_halmac_sdio_get_tx_addr(struct dvobj_priv *d, u8 *desc, u32 size)
5555 {
5556 	struct halmac_adapter *mac;
5557 	struct halmac_api *api;
5558 	enum halmac_ret_status status;
5559 	u32 addr;
5560 
5561 
5562 	mac = dvobj_to_halmac(d);
5563 	api = HALMAC_GET_API(mac);
5564 
5565 	status = api->halmac_get_sdio_tx_addr(mac, desc, size, &addr);
5566 	if (HALMAC_RET_SUCCESS != status)
5567 		return 0;
5568 
5569 	return addr;
5570 }
5571 
rtw_halmac_sdio_tx_allowed(struct dvobj_priv * d,u8 * buf,u32 size)5572 int rtw_halmac_sdio_tx_allowed(struct dvobj_priv *d, u8 *buf, u32 size)
5573 {
5574 	struct halmac_adapter *mac;
5575 	struct halmac_api *api;
5576 	enum halmac_ret_status status;
5577 
5578 
5579 	mac = dvobj_to_halmac(d);
5580 	api = HALMAC_GET_API(mac);
5581 
5582 	status = api->halmac_tx_allowed_sdio(mac, buf, size);
5583 	if (HALMAC_RET_SUCCESS != status)
5584 		return -1;
5585 
5586 	return 0;
5587 }
5588 
rtw_halmac_sdio_get_rx_addr(struct dvobj_priv * d,u8 * seq)5589 u32 rtw_halmac_sdio_get_rx_addr(struct dvobj_priv *d, u8 *seq)
5590 {
5591 	u8 id;
5592 
5593 #define RTW_SDIO_ADDR_RX_RX0FF_PRFIX	0x0E000
5594 #define RTW_SDIO_ADDR_RX_RX0FF_GEN(a)	(RTW_SDIO_ADDR_RX_RX0FF_PRFIX|(a&0x3))
5595 
5596 	id = *seq;
5597 	(*seq)++;
5598 	return RTW_SDIO_ADDR_RX_RX0FF_GEN(id);
5599 }
5600 
rtw_halmac_sdio_set_tx_format(struct dvobj_priv * d,enum halmac_sdio_tx_format format)5601 int rtw_halmac_sdio_set_tx_format(struct dvobj_priv *d, enum halmac_sdio_tx_format format)
5602 {
5603 	struct halmac_adapter *mac;
5604 	struct halmac_api *api;
5605 	enum halmac_ret_status status;
5606 
5607 	mac = dvobj_to_halmac(d);
5608 	api = HALMAC_GET_API(mac);
5609 
5610 	status = api->halmac_set_hw_value(mac, HALMAC_HW_SDIO_TX_FORMAT, &format);
5611 	if (HALMAC_RET_SUCCESS != status)
5612 		return -1;
5613 
5614 	return 0;
5615 }
5616 #endif /* CONFIG_SDIO_HCI */
5617 
5618 #ifdef CONFIG_USB_HCI
rtw_halmac_usb_get_bulkout_id(struct dvobj_priv * d,u8 * buf,u32 size)5619 u8 rtw_halmac_usb_get_bulkout_id(struct dvobj_priv *d, u8 *buf, u32 size)
5620 {
5621 	struct halmac_adapter *mac;
5622 	struct halmac_api *api;
5623 	enum halmac_ret_status status;
5624 	u8 bulkout_id;
5625 
5626 
5627 	mac = dvobj_to_halmac(d);
5628 	api = HALMAC_GET_API(mac);
5629 
5630 	status = api->halmac_get_usb_bulkout_id(mac, buf, size, &bulkout_id);
5631 	if (HALMAC_RET_SUCCESS != status)
5632 		return 0;
5633 
5634 	return bulkout_id;
5635 }
5636 
5637 /**
5638  * rtw_halmac_usb_get_txagg_desc_num() - MAX descriptor number in one bulk for TX
5639  * @d:		struct dvobj_priv*
5640  * @size:	TX FIFO size, unit is byte.
5641  *
5642  * Get MAX descriptor number in one bulk out from HALMAC.
5643  *
5644  * Return 0 for OK, otherwise fail.
5645  */
rtw_halmac_usb_get_txagg_desc_num(struct dvobj_priv * d,u8 * num)5646 int rtw_halmac_usb_get_txagg_desc_num(struct dvobj_priv *d, u8 *num)
5647 {
5648 	struct halmac_adapter *halmac;
5649 	struct halmac_api *api;
5650 	enum halmac_ret_status status;
5651 	u8 val = 0;
5652 
5653 
5654 	halmac = dvobj_to_halmac(d);
5655 	api = HALMAC_GET_API(halmac);
5656 
5657 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_USB_TXAGG_DESC_NUM, &val);
5658 	if (status != HALMAC_RET_SUCCESS)
5659 		return -1;
5660 
5661 	*num = val;
5662 
5663 	return 0;
5664 }
5665 
_usb_mode_drv2halmac(enum RTW_USB_SPEED usb_mode)5666 static inline enum halmac_usb_mode _usb_mode_drv2halmac(enum RTW_USB_SPEED usb_mode)
5667 {
5668 	enum halmac_usb_mode halmac_usb_mode = HALMAC_USB_MODE_U2;
5669 
5670 	switch (usb_mode) {
5671 	case RTW_USB_SPEED_2:
5672 		halmac_usb_mode = HALMAC_USB_MODE_U2;
5673 		break;
5674 	case RTW_USB_SPEED_3:
5675 		halmac_usb_mode = HALMAC_USB_MODE_U3;
5676 		break;
5677 	default:
5678 		halmac_usb_mode = HALMAC_USB_MODE_U2;
5679 		break;
5680 	}
5681 
5682 	return halmac_usb_mode;
5683 }
5684 
rtw_halmac_switch_usb_mode(struct dvobj_priv * d,enum RTW_USB_SPEED usb_mode)5685 u8 rtw_halmac_switch_usb_mode(struct dvobj_priv *d, enum RTW_USB_SPEED usb_mode)
5686 {
5687 	PADAPTER adapter;
5688 	struct halmac_adapter *mac;
5689 	struct halmac_api *api;
5690 	enum halmac_ret_status status;
5691 	enum halmac_usb_mode halmac_usb_mode;
5692 
5693 	adapter = dvobj_get_primary_adapter(d);
5694 	mac = dvobj_to_halmac(d);
5695 	api = HALMAC_GET_API(mac);
5696 	halmac_usb_mode = _usb_mode_drv2halmac(usb_mode);
5697 	status = api->halmac_set_hw_value(mac, HALMAC_HW_USB_MODE, (void *)&halmac_usb_mode);
5698 
5699 	if (HALMAC_RET_SUCCESS != status)
5700 		return _FAIL;
5701 
5702 	return _SUCCESS;
5703 }
5704 #endif /* CONFIG_USB_HCI */
5705 
5706 #ifdef CONFIG_BEAMFORMING
5707 #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)5708 int rtw_halmac_bf_add_mu_bfer(struct dvobj_priv *d, u16 paid, u16 csi_para,
5709 		u16 my_aid, enum halmac_csi_seg_len sel, u8 *addr)
5710 {
5711 	struct halmac_adapter *mac;
5712 	struct halmac_api *api;
5713 	enum halmac_ret_status status;
5714 	struct halmac_mu_bfer_init_para param;
5715 
5716 
5717 	mac = dvobj_to_halmac(d);
5718 	api = HALMAC_GET_API(mac);
5719 
5720 	_rtw_memset(&param, 0, sizeof(param));
5721 	param.paid = paid;
5722 	param.csi_para = csi_para;
5723 	param.my_aid = my_aid;
5724 	param.csi_length_sel = sel;
5725 	_rtw_memcpy(param.bfer_address.addr, addr, 6);
5726 
5727 	status = api->halmac_mu_bfer_entry_init(mac, &param);
5728 	if (status != HALMAC_RET_SUCCESS)
5729 		return -1;
5730 
5731 	return 0;
5732 }
5733 
rtw_halmac_bf_del_mu_bfer(struct dvobj_priv * d)5734 int rtw_halmac_bf_del_mu_bfer(struct dvobj_priv *d)
5735 {
5736 	struct halmac_adapter *mac;
5737 	struct halmac_api *api;
5738 	enum halmac_ret_status status;
5739 
5740 
5741 	mac = dvobj_to_halmac(d);
5742 	api = HALMAC_GET_API(mac);
5743 
5744 	status = api->halmac_mu_bfer_entry_del(mac);
5745 	if (status != HALMAC_RET_SUCCESS)
5746 		return -1;
5747 
5748 	return 0;
5749 }
5750 
5751 
rtw_halmac_bf_cfg_sounding(struct dvobj_priv * d,enum halmac_snd_role role,enum halmac_data_rate rate)5752 int rtw_halmac_bf_cfg_sounding(struct dvobj_priv *d,
5753 		enum halmac_snd_role role, enum halmac_data_rate rate)
5754 {
5755 	struct halmac_adapter *mac;
5756 	struct halmac_api *api;
5757 	enum halmac_ret_status status;
5758 
5759 
5760 	mac = dvobj_to_halmac(d);
5761 	api = HALMAC_GET_API(mac);
5762 
5763 	status = api->halmac_cfg_sounding(mac, role, rate);
5764 	if (status != HALMAC_RET_SUCCESS)
5765 		return -1;
5766 
5767 	return 0;
5768 }
5769 
rtw_halmac_bf_del_sounding(struct dvobj_priv * d,enum halmac_snd_role role)5770 int rtw_halmac_bf_del_sounding(struct dvobj_priv *d,
5771 		enum halmac_snd_role role)
5772 {
5773 	struct halmac_adapter *mac;
5774 	struct halmac_api *api;
5775 	enum halmac_ret_status status;
5776 
5777 
5778 	mac = dvobj_to_halmac(d);
5779 	api = HALMAC_GET_API(mac);
5780 
5781 	status = api->halmac_del_sounding(mac, role);
5782 	if (status != HALMAC_RET_SUCCESS)
5783 		return -1;
5784 
5785 	return 0;
5786 }
5787 
5788 /**
5789  * rtw_halmac_bf_cfg_csi_rate() - Config data rate for CSI report frame by RSSI
5790  * @d:		struct dvobj_priv*
5791  * @rssi:	RSSI vlaue, unit is percentage (0~100).
5792  * @current_rate:	Current CSI frame rate
5793  *			Valid value example
5794  *			0	CCK 1M
5795  *			3	CCK 11M
5796  *			4	OFDM 6M
5797  *			and so on
5798  * @fixrate_en:	Enable to fix CSI frame in VHT rate, otherwise legacy OFDM rate.
5799  *		The value "0" for disable, otheriwse enable.
5800  * @new_rate:	Return new data rate, and value range is the same as
5801  *		current_rate
5802  * @bmp_ofdm54: Return to suggest enabling OFDM 54M for CSI report frame or not,
5803  *		The valid values and meanings are:
5804  *		0x00	disable
5805  *		0x01	enable
5806  *		0xFF	Keep current setting
5807  *
5808  * According RSSI to config data rate for CSI report frame of Beamforming.
5809  *
5810  * Return 0 for OK, otherwise fail.
5811  */
rtw_halmac_bf_cfg_csi_rate(struct dvobj_priv * d,u8 rssi,u8 current_rate,u8 fixrate_en,u8 * new_rate,u8 * bmp_ofdm54)5812 int rtw_halmac_bf_cfg_csi_rate(struct dvobj_priv *d, u8 rssi,
5813 			       u8 current_rate, u8 fixrate_en, u8 *new_rate,
5814 			       u8 *bmp_ofdm54)
5815 {
5816 	struct halmac_adapter *mac;
5817 	struct halmac_api *api;
5818 	enum halmac_ret_status status;
5819 
5820 
5821 	mac = dvobj_to_halmac(d);
5822 	api = HALMAC_GET_API(mac);
5823 
5824 	status = api->halmac_cfg_csi_rate(mac,
5825 			rssi, current_rate, fixrate_en, new_rate,
5826 			bmp_ofdm54);
5827 	if (status != HALMAC_RET_SUCCESS)
5828 		return -1;
5829 
5830 	return 0;
5831 }
5832 
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)5833 int rtw_halmac_bf_cfg_mu_mimo(struct dvobj_priv *d, enum halmac_snd_role role,
5834 		u8 *sounding_sts, u16 grouping_bitmap, u8 mu_tx_en,
5835 		u32 *given_gid_tab, u32 *given_user_pos)
5836 {
5837 	struct halmac_adapter *mac;
5838 	struct halmac_api *api;
5839 	enum halmac_ret_status status;
5840 	struct halmac_cfg_mumimo_para param;
5841 
5842 
5843 	mac = dvobj_to_halmac(d);
5844 	api = HALMAC_GET_API(mac);
5845 
5846 	_rtw_memset(&param, 0, sizeof(param));
5847 
5848 	param.role = role;
5849 	param.grouping_bitmap = grouping_bitmap;
5850 	param.mu_tx_en = mu_tx_en;
5851 
5852 	if (sounding_sts)
5853 		_rtw_memcpy(param.sounding_sts, sounding_sts, 6);
5854 
5855 	if (given_gid_tab)
5856 		_rtw_memcpy(param.given_gid_tab, given_gid_tab, 8);
5857 
5858 	if (given_user_pos)
5859 		_rtw_memcpy(param.given_user_pos, given_user_pos, 16);
5860 
5861 	status = api->halmac_cfg_mumimo(mac, &param);
5862 	if (status != HALMAC_RET_SUCCESS)
5863 		return -1;
5864 
5865 	return 0;
5866 }
5867 
5868 #endif /* RTW_BEAMFORMING_VERSION_2 */
5869 #endif /* CONFIG_BEAMFORMING */
5870