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