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