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