xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/rtl8723cs/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",
1213 		    ver.major_ver, ver.prototype_ver, ver.minor_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 		_power_switch(halmac, api, HALMAC_MAC_POWER_OFF);
2772 		status = _power_switch(halmac, api, HALMAC_MAC_POWER_ON);
2773 		RTW_WARN("%s: Power state abnormal, try to recover...%s\n",
2774 			 __FUNCTION__, (HALMAC_RET_SUCCESS == status)?"OK":"FAIL!");
2775 	}
2776 	if (HALMAC_RET_SUCCESS != status) {
2777 		if (HALMAC_RET_PWR_UNCHANGE == status)
2778 			err = -2;
2779 		goto out;
2780 	}
2781 
2782 	status = api->halmac_init_system_cfg(halmac);
2783 	if (status != HALMAC_RET_SUCCESS)
2784 		goto out;
2785 
2786 	err = 0;
2787 out:
2788 	return err;
2789 }
2790 
2791 /*
2792  * Description:
2793  *	Power off device hardware.
2794  *
2795  * Return:
2796  *	0	Power off success
2797  *	-1	Power off fail
2798  */
rtw_halmac_poweroff(struct dvobj_priv * d)2799 int rtw_halmac_poweroff(struct dvobj_priv *d)
2800 {
2801 	struct halmac_adapter *halmac;
2802 	struct halmac_api *api;
2803 	enum halmac_ret_status status;
2804 	int err = -1;
2805 
2806 
2807 	halmac = dvobj_to_halmac(d);
2808 	if (!halmac)
2809 		goto out;
2810 
2811 	api = HALMAC_GET_API(halmac);
2812 
2813 	status = _power_switch(halmac, api, HALMAC_MAC_POWER_OFF);
2814 	if ((HALMAC_RET_SUCCESS != status)
2815 	    && (HALMAC_RET_PWR_UNCHANGE != status))
2816 		goto out;
2817 
2818 	err = 0;
2819 out:
2820 	return err;
2821 }
2822 
2823 #ifdef CONFIG_SUPPORT_TRX_SHARED
_trx_share_mode_drv2halmac(u8 trx_share_mode)2824 static inline enum halmac_rx_fifo_expanding_mode _trx_share_mode_drv2halmac(u8 trx_share_mode)
2825 {
2826 	if (0 == trx_share_mode)
2827 		return HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE;
2828 	else if (1 == trx_share_mode)
2829 		return HALMAC_RX_FIFO_EXPANDING_MODE_1_BLOCK;
2830 	else if (2 == trx_share_mode)
2831 		return HALMAC_RX_FIFO_EXPANDING_MODE_2_BLOCK;
2832 	else if (3 == trx_share_mode)
2833 		return HALMAC_RX_FIFO_EXPANDING_MODE_3_BLOCK;
2834 	else
2835 		return HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE;
2836 }
2837 
_rtw_get_trx_share_mode(struct _ADAPTER * adapter)2838 static enum halmac_rx_fifo_expanding_mode _rtw_get_trx_share_mode(struct _ADAPTER *adapter)
2839 {
2840 	struct registry_priv *registry_par = &adapter->registrypriv;
2841 
2842 	return _trx_share_mode_drv2halmac(registry_par->trx_share_mode);
2843 }
2844 
dump_trx_share_mode(void * sel,struct _ADAPTER * adapter)2845 void dump_trx_share_mode(void *sel, struct _ADAPTER *adapter)
2846 {
2847 	struct registry_priv  *registry_par = &adapter->registrypriv;
2848 	u8 mode = _trx_share_mode_drv2halmac(registry_par->trx_share_mode);
2849 
2850 	if (HALMAC_RX_FIFO_EXPANDING_MODE_1_BLOCK == mode)
2851 		RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "RX_FIFO_EXPANDING_MODE_1");
2852 	else if (HALMAC_RX_FIFO_EXPANDING_MODE_2_BLOCK == mode)
2853 		RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "RX_FIFO_EXPANDING_MODE_2");
2854 	else if (HALMAC_RX_FIFO_EXPANDING_MODE_3_BLOCK == mode)
2855 		RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "RX_FIFO_EXPANDING_MODE_3");
2856 	else
2857 		RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "DISABLE");
2858 }
2859 #endif
2860 
_rsvd_page_num_drv2halmac(u16 num)2861 static enum halmac_drv_rsvd_pg_num _rsvd_page_num_drv2halmac(u16 num)
2862 {
2863 	if (num <= 8)
2864 		return HALMAC_RSVD_PG_NUM8;
2865 	if (num <= 16)
2866 		return HALMAC_RSVD_PG_NUM16;
2867 	if (num <= 24)
2868 		return HALMAC_RSVD_PG_NUM24;
2869 	if (num <= 32)
2870 		return HALMAC_RSVD_PG_NUM32;
2871 	if (num <= 64)
2872 		return HALMAC_RSVD_PG_NUM64;
2873 	if (num <= 128)
2874 		return HALMAC_RSVD_PG_NUM128;
2875 
2876 	if (num > 256)
2877 		RTW_WARN("%s: Fail to allocate RSVD page(%d)!!"
2878 			 " The MAX RSVD page number is 256...\n",
2879 			 __FUNCTION__, num);
2880 
2881 	return HALMAC_RSVD_PG_NUM256;
2882 }
2883 
_rsvd_page_num_halmac2drv(enum halmac_drv_rsvd_pg_num rsvd_page_number)2884 static u16 _rsvd_page_num_halmac2drv(enum halmac_drv_rsvd_pg_num rsvd_page_number)
2885 {
2886 	u16 num = 0;
2887 
2888 
2889 	switch (rsvd_page_number) {
2890 	case HALMAC_RSVD_PG_NUM8:
2891 		num = 8;
2892 		break;
2893 
2894 	case HALMAC_RSVD_PG_NUM16:
2895 		num = 16;
2896 		break;
2897 
2898 	case HALMAC_RSVD_PG_NUM24:
2899 		num = 24;
2900 		break;
2901 
2902 	case HALMAC_RSVD_PG_NUM32:
2903 		num = 32;
2904 		break;
2905 
2906 	case HALMAC_RSVD_PG_NUM64:
2907 		num = 64;
2908 		break;
2909 
2910 	case HALMAC_RSVD_PG_NUM128:
2911 		num = 128;
2912 		break;
2913 
2914 	case HALMAC_RSVD_PG_NUM256:
2915 		num = 256;
2916 		break;
2917 	}
2918 
2919 	return num;
2920 }
2921 
_choose_trx_mode(struct dvobj_priv * d)2922 static enum halmac_trx_mode _choose_trx_mode(struct dvobj_priv *d)
2923 {
2924 	PADAPTER p;
2925 
2926 
2927 	p = dvobj_get_primary_adapter(d);
2928 
2929 	if (p->registrypriv.wifi_spec)
2930 		return HALMAC_TRX_MODE_WMM;
2931 
2932 #ifdef CONFIG_SUPPORT_TRX_SHARED
2933 	if (_rtw_get_trx_share_mode(p))
2934 		return HALMAC_TRX_MODE_TRXSHARE;
2935 #endif
2936 
2937 	return HALMAC_TRX_MODE_NORMAL;
2938 }
2939 
_rf_type_drv2halmac(enum rf_type rf_drv)2940 static inline enum halmac_rf_type _rf_type_drv2halmac(enum rf_type rf_drv)
2941 {
2942 	enum halmac_rf_type rf_mac;
2943 
2944 
2945 	switch (rf_drv) {
2946 	case RF_1T1R:
2947 		rf_mac = HALMAC_RF_1T1R;
2948 		break;
2949 	case RF_1T2R:
2950 		rf_mac = HALMAC_RF_1T2R;
2951 		break;
2952 	case RF_2T2R:
2953 		rf_mac = HALMAC_RF_2T2R;
2954 		break;
2955 	case RF_2T3R:
2956 		rf_mac = HALMAC_RF_2T3R;
2957 		break;
2958 	case RF_2T4R:
2959 		rf_mac = HALMAC_RF_2T4R;
2960 		break;
2961 	case RF_3T3R:
2962 		rf_mac = HALMAC_RF_3T3R;
2963 		break;
2964 	case RF_3T4R:
2965 		rf_mac = HALMAC_RF_3T4R;
2966 		break;
2967 	case RF_4T4R:
2968 		rf_mac = HALMAC_RF_4T4R;
2969 		break;
2970 	default:
2971 		rf_mac = HALMAC_RF_MAX_TYPE;
2972 		RTW_ERR("%s: Invalid RF type(0x%x)!\n", __FUNCTION__, rf_drv);
2973 		break;
2974 	}
2975 
2976 	return rf_mac;
2977 }
2978 
_rf_type_halmac2drv(enum halmac_rf_type rf_mac)2979 static inline enum rf_type _rf_type_halmac2drv(enum halmac_rf_type rf_mac)
2980 {
2981 	enum rf_type rf_drv;
2982 
2983 
2984 	switch (rf_mac) {
2985 	case HALMAC_RF_1T2R:
2986 		rf_drv = RF_1T2R;
2987 		break;
2988 	case HALMAC_RF_2T4R:
2989 		rf_drv = RF_2T4R;
2990 		break;
2991 	case HALMAC_RF_2T2R:
2992 	case HALMAC_RF_2T2R_GREEN:
2993 		rf_drv = RF_2T2R;
2994 		break;
2995 	case HALMAC_RF_2T3R:
2996 		rf_drv = RF_2T3R;
2997 		break;
2998 	case HALMAC_RF_1T1R:
2999 		rf_drv = RF_1T1R;
3000 		break;
3001 	case HALMAC_RF_3T3R:
3002 		rf_drv = RF_3T3R;
3003 		break;
3004 	case HALMAC_RF_3T4R:
3005 		rf_drv = RF_3T4R;
3006 		break;
3007 	case HALMAC_RF_4T4R:
3008 		rf_drv = RF_4T4R;
3009 		break;
3010 	default:
3011 		rf_drv = RF_TYPE_MAX;
3012 		RTW_ERR("%s: Invalid RF type(0x%x)!\n", __FUNCTION__, rf_mac);
3013 		break;
3014 	}
3015 
3016 	return rf_drv;
3017 }
3018 
_cut_version_drv2phydm(enum tag_HAL_Cut_Version_Definition cut_drv)3019 static enum odm_cut_version _cut_version_drv2phydm(
3020 				enum tag_HAL_Cut_Version_Definition cut_drv)
3021 {
3022 	enum odm_cut_version cut_phydm = ODM_CUT_A;
3023 	u32 diff;
3024 
3025 
3026 	if (cut_drv > K_CUT_VERSION)
3027 		RTW_WARN("%s: unknown cut_ver=%d !!\n", __FUNCTION__, cut_drv);
3028 
3029 	diff = cut_drv - A_CUT_VERSION;
3030 	cut_phydm += diff;
3031 
3032 	return cut_phydm;
3033 }
3034 
_send_general_info_by_reg(struct dvobj_priv * d,struct halmac_general_info * info)3035 static int _send_general_info_by_reg(struct dvobj_priv *d,
3036 				     struct halmac_general_info *info)
3037 {
3038 	struct _ADAPTER *a;
3039 	struct hal_com_data *hal;
3040 	enum tag_HAL_Cut_Version_Definition cut_drv;
3041 	enum rf_type rftype;
3042 	enum odm_cut_version cut_phydm;
3043 	u8 h2c[RTW_HALMAC_H2C_MAX_SIZE] = {0};
3044 
3045 
3046 	a = dvobj_get_primary_adapter(d);
3047 	hal = GET_HAL_DATA(a);
3048 	rftype = _rf_type_halmac2drv(info->rf_type);
3049 	cut_drv = GET_CVID_CUT_VERSION(hal->version_id);
3050 	cut_phydm = _cut_version_drv2phydm(cut_drv);
3051 
3052 #define CLASS_GENERAL_INFO_REG				0x02
3053 #define CMD_ID_GENERAL_INFO_REG				0x0C
3054 #define GENERAL_INFO_REG_SET_CMD_ID(buf, v)		SET_BITS_TO_LE_4BYTE(buf, 0, 5, v)
3055 #define GENERAL_INFO_REG_SET_CLASS(buf, v)		SET_BITS_TO_LE_4BYTE(buf, 5, 3, v)
3056 #define GENERAL_INFO_REG_SET_RFE_TYPE(buf, v)		SET_BITS_TO_LE_4BYTE(buf, 8, 8, v)
3057 #define GENERAL_INFO_REG_SET_RF_TYPE(buf, v)		SET_BITS_TO_LE_4BYTE(buf, 16, 8, v)
3058 #define GENERAL_INFO_REG_SET_CUT_VERSION(buf, v)	SET_BITS_TO_LE_4BYTE(buf, 24, 8, v)
3059 #define GENERAL_INFO_REG_SET_RX_ANT_STATUS(buf, v)	SET_BITS_TO_LE_1BYTE(buf+4, 0, 4, v)
3060 #define GENERAL_INFO_REG_SET_TX_ANT_STATUS(buf, v)	SET_BITS_TO_LE_1BYTE(buf+4, 4, 4, v)
3061 
3062 	GENERAL_INFO_REG_SET_CMD_ID(h2c, CMD_ID_GENERAL_INFO_REG);
3063 	GENERAL_INFO_REG_SET_CLASS(h2c, CLASS_GENERAL_INFO_REG);
3064 	GENERAL_INFO_REG_SET_RFE_TYPE(h2c, info->rfe_type);
3065 	GENERAL_INFO_REG_SET_RF_TYPE(h2c, rftype);
3066 	GENERAL_INFO_REG_SET_CUT_VERSION(h2c, cut_phydm);
3067 	GENERAL_INFO_REG_SET_RX_ANT_STATUS(h2c, info->rx_ant_status);
3068 	GENERAL_INFO_REG_SET_TX_ANT_STATUS(h2c, info->tx_ant_status);
3069 
3070 	return rtw_halmac_send_h2c(d, h2c);
3071 }
3072 
_send_general_info(struct dvobj_priv * d)3073 static int _send_general_info(struct dvobj_priv *d)
3074 {
3075 	struct _ADAPTER *adapter;
3076 	struct hal_com_data *hal;
3077 	struct halmac_adapter *halmac;
3078 	struct halmac_api *api;
3079 	struct halmac_general_info info;
3080 	enum halmac_ret_status status;
3081 	enum rf_type rf = RF_1T1R;
3082 	enum bb_path txpath = BB_PATH_A;
3083 	enum bb_path rxpath = BB_PATH_A;
3084 	int err;
3085 
3086 
3087 	adapter = dvobj_get_primary_adapter(d);
3088 	hal = GET_HAL_DATA(adapter);
3089 	halmac = dvobj_to_halmac(d);
3090 	if (!halmac)
3091 		return -1;
3092 	api = HALMAC_GET_API(halmac);
3093 
3094 	_rtw_memset(&info, 0, sizeof(info));
3095 	info.rfe_type = (u8)hal->rfe_type;
3096 	rtw_hal_get_trx_path(d, &rf, &txpath, &rxpath);
3097 	info.rf_type = _rf_type_drv2halmac(rf);
3098 	info.tx_ant_status = (u8)txpath;
3099 	info.rx_ant_status = (u8)rxpath;
3100 	info.ext_pa = 0;	/* 2.4G or 5G? format not known */
3101 	info.package_type = hal->PackageType;
3102 	info.mp_mode = adapter->registrypriv.mp_mode;
3103 
3104 	status = api->halmac_send_general_info(halmac, &info);
3105 	switch (status) {
3106 	case HALMAC_RET_SUCCESS:
3107 		break;
3108 	case HALMAC_RET_NO_DLFW:
3109 		RTW_WARN("%s: halmac_send_general_info() fail because fw not dl!\n",
3110 			 __FUNCTION__);
3111 		/* fall through */
3112 	default:
3113 		return -1;
3114 	}
3115 
3116 	err = _send_general_info_by_reg(d, &info);
3117 	if (err) {
3118 		RTW_ERR("%s: Fail to send general info by register!\n",
3119 			 __FUNCTION__);
3120 		return -1;
3121 	}
3122 
3123 	return 0;
3124 }
3125 
_cfg_drv_rsvd_pg_num(struct dvobj_priv * d)3126 static int _cfg_drv_rsvd_pg_num(struct dvobj_priv *d)
3127 {
3128 	struct _ADAPTER *a;
3129 	struct hal_com_data *hal;
3130 	struct halmac_adapter *halmac;
3131 	struct halmac_api *api;
3132 	enum halmac_drv_rsvd_pg_num rsvd_page_number;
3133 	enum halmac_ret_status status;
3134 	u16 drv_rsvd_num;
3135 	int ret = 0;
3136 
3137 
3138 	a = dvobj_get_primary_adapter(d);
3139 	hal = GET_HAL_DATA(a);
3140 	halmac = dvobj_to_halmac(d);
3141 	api = HALMAC_GET_API(halmac);
3142 
3143 	drv_rsvd_num = rtw_hal_get_rsvd_page_num(a);
3144 	rsvd_page_number = _rsvd_page_num_drv2halmac(drv_rsvd_num);
3145 	status = api->halmac_cfg_drv_rsvd_pg_num(halmac, rsvd_page_number);
3146 	if (status != HALMAC_RET_SUCCESS) {
3147 		ret = -1;
3148 		goto exit;
3149 	}
3150 	hal->drv_rsvd_page_number = _rsvd_page_num_halmac2drv(rsvd_page_number);
3151 
3152 exit:
3153 #ifndef DBG_RSVD_PAGE_CFG
3154 	if (drv_rsvd_num != _rsvd_page_num_halmac2drv(rsvd_page_number))
3155 #endif
3156 		RTW_INFO("%s: request %d pages => halmac %d pages %s\n"
3157 			, __FUNCTION__, drv_rsvd_num, _rsvd_page_num_halmac2drv(rsvd_page_number)
3158 			, ret ? "fail" : "success");
3159 
3160 	return ret;
3161 }
3162 
_debug_dlfw_fail(struct dvobj_priv * d)3163 static void _debug_dlfw_fail(struct dvobj_priv *d)
3164 {
3165 	struct _ADAPTER *a;
3166 	u32 addr;
3167 	u32 v32, i, n;
3168 
3169 
3170 	a = dvobj_get_primary_adapter(d);
3171 
3172 	/* read 0x80[15:0], 0x10F8[31:0] once */
3173 	addr = 0x80;
3174 	v32 = rtw_read16(a, addr);
3175 	RTW_PRINT("%s: 0x%X = 0x%04x\n", __FUNCTION__, addr, v32);
3176 
3177 	addr = 0x10F8;
3178 	v32 = rtw_read32(a, addr);
3179 	RTW_PRINT("%s: 0x%X = 0x%08x\n", __FUNCTION__, addr, v32);
3180 
3181 	/* read 0x10FC[31:0], 5 times */
3182 	addr = 0x10FC;
3183 	n = 5;
3184 	for (i = 0; i < n; i++) {
3185 		v32 = rtw_read32(a, addr);
3186 		RTW_PRINT("%s: 0x%X = 0x%08x (%u/%u)\n",
3187 			  __FUNCTION__, addr, v32, i, n);
3188 	}
3189 
3190 	/*
3191 	 * write 0x3A[7:0]=0x28 and 0xF6[7:0]=0x01
3192 	 * and then read 0xC0[31:0] 5 times
3193 	 */
3194 	addr = 0x3A;
3195 	v32 = 0x28;
3196 	rtw_write8(a, addr, (u8)v32);
3197 	v32 = rtw_read8(a, addr);
3198 	RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v32);
3199 
3200 	addr = 0xF6;
3201 	v32 = 0x1;
3202 	rtw_write8(a, addr, (u8)v32);
3203 	v32 = rtw_read8(a, addr);
3204 	RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v32);
3205 
3206 	addr = 0xC0;
3207 	n = 5;
3208 	for (i = 0; i < n; i++) {
3209 		v32 = rtw_read32(a, addr);
3210 		RTW_PRINT("%s: 0x%X = 0x%08x (%u/%u)\n",
3211 			  __FUNCTION__, addr, v32, i, n);
3212 	}
3213 
3214 	mac_reg_dump(NULL, a);
3215 #ifdef CONFIG_SDIO_HCI
3216 	RTW_PRINT("======= SDIO Local REG =======\n");
3217 	sdio_local_reg_dump(NULL, a);
3218 	RTW_PRINT("======= SDIO CCCR REG =======\n");
3219 	sd_f0_reg_dump(NULL, a);
3220 #endif /* CONFIG_SDIO_HCI */
3221 
3222 	/* read 0x80 after 10 secs */
3223 	rtw_msleep_os(10000);
3224 	addr = 0x80;
3225 	v32 = rtw_read16(a, addr);
3226 	RTW_PRINT("%s: 0x%X = 0x%04x (after 10 secs)\n",
3227 		  __FUNCTION__, addr, v32);
3228 }
3229 
_enter_cpu_sleep_mode(struct dvobj_priv * d)3230 static enum halmac_ret_status _enter_cpu_sleep_mode(struct dvobj_priv *d)
3231 {
3232 	struct hal_com_data *hal;
3233 	struct halmac_adapter *mac;
3234 	struct halmac_api *api;
3235 
3236 
3237 	hal = GET_HAL_DATA(dvobj_get_primary_adapter(d));
3238 	mac = dvobj_to_halmac(d);
3239 	api = HALMAC_GET_API(mac);
3240 
3241 #ifdef CONFIG_RTL8822B
3242 	/* Support after firmware version 21 */
3243 	if (hal->firmware_version < 21)
3244 		return HALMAC_RET_NOT_SUPPORT;
3245 #elif defined(CONFIG_RTL8821C)
3246 	/* Support after firmware version 13.6 or 16 */
3247 	if (hal->firmware_version == 13) {
3248 		if (hal->firmware_sub_version < 6)
3249 			return HALMAC_RET_NOT_SUPPORT;
3250 	} else if (hal->firmware_version < 16) {
3251 		return HALMAC_RET_NOT_SUPPORT;
3252 	}
3253 #endif
3254 
3255 	return api->halmac_enter_cpu_sleep_mode(mac);
3256 }
3257 
3258 /*
3259  * _cpu_sleep() - Let IC CPU enter sleep mode
3260  * @d:		struct dvobj_priv*
3261  * @timeout:	time limit of wait, unit is ms
3262  *		0 for no limit
3263  *
3264  * Return 0 for CPU in sleep mode, otherwise fail to enter sleep mode.
3265  * Error codes definition are as follow:
3266  * 	-1	HALMAC enter sleep return fail
3267  *	-2	HALMAC get CPU mode return fail
3268  *	-110	timeout
3269  */
_cpu_sleep(struct dvobj_priv * d,u32 timeout)3270 static int _cpu_sleep(struct dvobj_priv *d, u32 timeout)
3271 {
3272 	struct halmac_adapter *mac;
3273 	struct halmac_api *api;
3274 	enum halmac_ret_status status;
3275 	enum halmac_wlcpu_mode mode = HALMAC_WLCPU_UNDEFINE;
3276 	systime start_t;
3277 	s32 period = 0;
3278 	u32 cnt = 0;
3279 	int err = 0;
3280 
3281 
3282 	mac = dvobj_to_halmac(d);
3283 	api = HALMAC_GET_API(mac);
3284 
3285 	start_t = rtw_get_current_time();
3286 
3287 	status = _enter_cpu_sleep_mode(d);
3288 	if (status != HALMAC_RET_SUCCESS) {
3289 		if (status != HALMAC_RET_NOT_SUPPORT)
3290 			err = -1;
3291 		goto exit;
3292 	}
3293 
3294 	do {
3295 		cnt++;
3296 
3297 		mode = HALMAC_WLCPU_UNDEFINE;
3298 		status = api->halmac_get_cpu_mode(mac, &mode);
3299 
3300 		period = rtw_get_passing_time_ms(start_t);
3301 
3302 		if (status != HALMAC_RET_SUCCESS) {
3303 			err = -2;
3304 			break;
3305 		}
3306 		if (mode == HALMAC_WLCPU_SLEEP)
3307 			break;
3308 		if (period > timeout) {
3309 			err = -110;
3310 			break;
3311 		}
3312 
3313 		rtw_msleep_os(1);
3314 	} while (1);
3315 
3316 exit:
3317 	if (err)
3318 		RTW_ERR("%s: Fail to enter sleep mode! (%d, %d)\n",
3319 			__FUNCTION__, status, mode);
3320 
3321 	RTW_INFO("%s: Cost %dms to polling %u times. (err=%d)\n",
3322 		__FUNCTION__, period, cnt, err);
3323 
3324 	return err;
3325 }
3326 
_init_trx_cfg_drv(struct dvobj_priv * d)3327 static void _init_trx_cfg_drv(struct dvobj_priv *d)
3328 {
3329 #ifdef CONFIG_PCI_HCI
3330 	rtw_hal_irp_reset(dvobj_get_primary_adapter(d));
3331 #endif
3332 }
3333 
3334 /*
3335  * Description:
3336  *	Downlaod Firmware Flow
3337  *
3338  * Parameters:
3339  *	d	pointer of struct dvobj_priv
3340  *	fw	firmware array
3341  *	fwsize	firmware size
3342  *	re_dl	re-download firmware or not
3343  *		0: run in init hal flow, not re-download
3344  *		1: it is a stand alone operation, not in init hal flow
3345  *
3346  * Return:
3347  *	0	Success
3348  *	others	Fail
3349  */
download_fw(struct dvobj_priv * d,u8 * fw,u32 fwsize,u8 re_dl)3350 static int download_fw(struct dvobj_priv *d, u8 *fw, u32 fwsize, u8 re_dl)
3351 {
3352 	PHAL_DATA_TYPE hal;
3353 	struct halmac_adapter *mac;
3354 	struct halmac_api *api;
3355 	struct halmac_fw_version fw_vesion;
3356 	enum halmac_ret_status status;
3357 	int err = 0;
3358 
3359 
3360 	hal = GET_HAL_DATA(dvobj_get_primary_adapter(d));
3361 	mac = dvobj_to_halmac(d);
3362 	api = HALMAC_GET_API(mac);
3363 
3364 	if ((!fw) || (!fwsize))
3365 		return -1;
3366 
3367 	/* 1. Driver Stop Tx */
3368 	/* ToDo */
3369 
3370 	/* 2. Driver Check Tx FIFO is empty */
3371 	err = rtw_halmac_txfifo_wait_empty(d, 2000); /* wait 2s */
3372 	if (err) {
3373 		err = -1;
3374 		goto resume_tx;
3375 	}
3376 
3377 	/* 3. Config MAX download size */
3378 	/*
3379 	 * Already done in rtw_halmac_init_adapter() or
3380 	 * somewhere calling rtw_halmac_set_max_dl_fw_size().
3381 	 */
3382 
3383 	if (re_dl) {
3384 		/* 4. Enter IC CPU sleep mode */
3385 		err = _cpu_sleep(d, 2000);
3386 		if (err) {
3387 			RTW_ERR("%s: IC CPU fail to enter sleep mode!(%d)\n",
3388 				__FUNCTION__, err);
3389 			/* skip this error */
3390 			err = 0;
3391 		}
3392 	}
3393 
3394 	/* 5. Download Firmware */
3395 	status = api->halmac_download_firmware(mac, fw, fwsize);
3396 	if (status != HALMAC_RET_SUCCESS) {
3397 		RTW_ERR("%s: download firmware FAIL! status=0x%02x\n",
3398 			__FUNCTION__, status);
3399 		_debug_dlfw_fail(d);
3400 		err = -1;
3401 		goto resume_tx;
3402 	}
3403 
3404 	/* 5.1. (Driver) Reset driver variables if needed */
3405 	hal->LastHMEBoxNum = 0;
3406 
3407 	/* 5.2. (Driver) Get FW version */
3408 	status = api->halmac_get_fw_version(mac, &fw_vesion);
3409 	if (status == HALMAC_RET_SUCCESS) {
3410 		hal->firmware_version = fw_vesion.version;
3411 		hal->firmware_sub_version = fw_vesion.sub_version;
3412 		hal->firmware_size = fwsize;
3413 	}
3414 
3415 resume_tx:
3416 	/* 6. Driver resume TX if needed */
3417 	/* ToDo */
3418 
3419 	if (err)
3420 		goto exit;
3421 
3422 	if (re_dl) {
3423 		enum halmac_trx_mode mode;
3424 
3425 		/* 7. Change reserved page size */
3426 		err = _cfg_drv_rsvd_pg_num(d);
3427 		if (err)
3428 			return -1;
3429 
3430 		/* 8. Init TRX Configuration */
3431 		mode = _choose_trx_mode(d);
3432 		status = api->halmac_init_trx_cfg(mac, mode);
3433 		if (HALMAC_RET_SUCCESS != status)
3434 			return -1;
3435 		_init_trx_cfg_drv(d);
3436 
3437 		/* 9. Config RX Aggregation */
3438 		err = rtw_halmac_rx_agg_switch(d, _TRUE);
3439 		if (err)
3440 			return -1;
3441 
3442 		/* 10. Send General Info */
3443 		err = _send_general_info(d);
3444 		if (err)
3445 			return -1;
3446 	}
3447 
3448 exit:
3449 	return err;
3450 }
3451 
init_mac_flow(struct dvobj_priv * d)3452 static int init_mac_flow(struct dvobj_priv *d)
3453 {
3454 	PADAPTER p;
3455 	struct hal_com_data *hal;
3456 	struct halmac_adapter *halmac;
3457 	struct halmac_api *api;
3458 	enum halmac_drv_rsvd_pg_num rsvd_page_number;
3459 	union halmac_wlan_addr hwa;
3460 	enum halmac_trx_mode trx_mode;
3461 	enum halmac_ret_status status;
3462 	u8 drv_rsvd_num;
3463 	u8 nettype;
3464 	int err, err_ret = -1;
3465 
3466 
3467 	p = dvobj_get_primary_adapter(d);
3468 	hal = GET_HAL_DATA(p);
3469 	halmac = dvobj_to_halmac(d);
3470 	api = HALMAC_GET_API(halmac);
3471 
3472 #ifdef CONFIG_SUPPORT_TRX_SHARED
3473 	status = api->halmac_cfg_rxff_expand_mode(halmac,
3474 						  _rtw_get_trx_share_mode(p));
3475 	if (status != HALMAC_RET_SUCCESS)
3476 		goto out;
3477 #endif
3478 
3479 #ifdef DBG_LA_MODE
3480 	if (dvobj_to_regsty(d)->la_mode_en) {
3481 		status = api->halmac_cfg_la_mode(halmac, HALMAC_LA_MODE_PARTIAL);
3482 		if (status != HALMAC_RET_SUCCESS) {
3483 			RTW_ERR("%s: Fail to enable LA mode!\n", __FUNCTION__);
3484 			goto out;
3485 		}
3486 		RTW_PRINT("%s: Enable LA mode OK.\n", __FUNCTION__);
3487 	}
3488 #endif
3489 
3490 	err = _cfg_drv_rsvd_pg_num(d);
3491 	if (err)
3492 		goto out;
3493 
3494 #ifdef CONFIG_USB_HCI
3495 	status = api->halmac_set_bulkout_num(halmac, d->RtNumOutPipes);
3496 	if (status != HALMAC_RET_SUCCESS)
3497 		goto out;
3498 #endif /* CONFIG_USB_HCI */
3499 
3500 	trx_mode = _choose_trx_mode(d);
3501 	status = api->halmac_init_mac_cfg(halmac, trx_mode);
3502 	if (status != HALMAC_RET_SUCCESS)
3503 		goto out;
3504 
3505 	/* Driver insert flow: Sync driver setting with register */
3506 	/* Sync driver RCR cache with register setting */
3507 	rtw_hal_get_hwreg(dvobj_get_primary_adapter(d), HW_VAR_RCR, NULL);
3508 
3509 #ifdef CONFIG_RTS_FULL_BW
3510 	err = rtw_halmac_set_rts_full_bw(d, _TRUE);
3511 	if (err)
3512 		RTW_WARN("%s: Fail to set RTS FULL BW mode\n", __FUNCTION__);
3513 #else
3514 	err = rtw_halmac_set_rts_full_bw(d, _FALSE);
3515 	if (err)
3516 		RTW_WARN("%s: Fail to disable RTS FULL BW mode\n", __FUNCTION__);
3517 #endif /* CONFIG_RTS_FULL_BW */
3518 
3519 	_init_trx_cfg_drv(d);
3520 	/* Driver inser flow end */
3521 
3522 	err = rtw_halmac_rx_agg_switch(d, _TRUE);
3523 	if (err)
3524 		goto out;
3525 
3526 	nettype = dvobj_to_regsty(d)->wireless_mode;
3527 	if (is_supported_vht(nettype) == _TRUE)
3528 		status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_AC);
3529 	else if (is_supported_ht(nettype) == _TRUE)
3530 		status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_N);
3531 	else if (IsSupportedTxOFDM(nettype) == _TRUE)
3532 		status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_G);
3533 	else
3534 		status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_B);
3535 	if (status != HALMAC_RET_SUCCESS)
3536 		goto out;
3537 
3538 	err_ret = 0;
3539 out:
3540 	return err_ret;
3541 }
3542 
_drv_enable_trx(struct dvobj_priv * d)3543 static int _drv_enable_trx(struct dvobj_priv *d)
3544 {
3545 	struct _ADAPTER *adapter;
3546 	u32 status;
3547 
3548 
3549 	adapter = dvobj_get_primary_adapter(d);
3550 	if (adapter->bup == _FALSE) {
3551 #ifdef CONFIG_NEW_NETDEV_HDL
3552 		status = rtw_mi_start_drv_threads(adapter);
3553 #else
3554 		status = rtw_start_drv_threads(adapter);
3555 #endif
3556 		if (status == _FAIL) {
3557 			RTW_ERR("%s: Start threads Failed!\n", __FUNCTION__);
3558 			return -1;
3559 		}
3560 	}
3561 
3562 	rtw_intf_start(adapter);
3563 
3564 	return 0;
3565 }
3566 
3567 /*
3568  * Notices:
3569  *	Make sure following information
3570  *	1. GET_HAL_RFPATH
3571  *	2. GET_HAL_DATA(dvobj_get_primary_adapter(d))->rfe_type
3572  *	3. GET_HAL_DATA(dvobj_get_primary_adapter(d))->PackageType
3573  *	4. dvobj_get_primary_adapter(d)->registrypriv.mp_mode
3574  *	are all ready before calling this function.
3575  */
_halmac_init_hal(struct dvobj_priv * d,u8 * fw,u32 fwsize)3576 static int _halmac_init_hal(struct dvobj_priv *d, u8 *fw, u32 fwsize)
3577 {
3578 	PADAPTER adapter;
3579 	struct halmac_adapter *halmac;
3580 	struct halmac_api *api;
3581 	enum halmac_ret_status status;
3582 	u32 ok;
3583 	u8 fw_ok = _FALSE;
3584 	int err, err_ret = -1;
3585 
3586 
3587 	adapter = dvobj_get_primary_adapter(d);
3588 	halmac = dvobj_to_halmac(d);
3589 	if (!halmac)
3590 		goto out;
3591 	api = HALMAC_GET_API(halmac);
3592 
3593 	/* StatePowerOff */
3594 
3595 	/* SKIP: halmac_init_adapter (Already done before) */
3596 
3597 	/* halmac_pre_Init_system_cfg */
3598 	/* halmac_mac_power_switch(on) */
3599 	/* halmac_Init_system_cfg */
3600 	ok = rtw_hal_power_on(adapter);
3601 	if (_FAIL == ok)
3602 		goto out;
3603 
3604 	/* StatePowerOn */
3605 
3606 	/* DownloadFW */
3607 	if (fw && fwsize) {
3608 		err = download_fw(d, fw, fwsize, 0);
3609 		if (err)
3610 			goto out;
3611 		fw_ok = _TRUE;
3612 	}
3613 
3614 	/* InitMACFlow */
3615 	err = init_mac_flow(d);
3616 	if (err)
3617 		goto out;
3618 
3619 	/* Driver insert flow: Enable TR/RX */
3620 	err = _drv_enable_trx(d);
3621 	if (err)
3622 		goto out;
3623 
3624 	/* halmac_send_general_info */
3625 	if (_TRUE == fw_ok) {
3626 		err = _send_general_info(d);
3627 		if (err)
3628 			goto out;
3629 	}
3630 
3631 	/* Init Phy parameter-MAC */
3632 	ok = rtw_hal_init_mac_register(adapter);
3633 	if (_FALSE == ok)
3634 		goto out;
3635 
3636 	/* StateMacInitialized */
3637 
3638 	/* halmac_cfg_drv_info */
3639 	err = rtw_halmac_config_rx_info(d, HALMAC_DRV_INFO_PHY_STATUS);
3640 	if (err)
3641 		goto out;
3642 
3643 	/* halmac_set_hw_value(HALMAC_HW_EN_BB_RF) */
3644 	/* Init BB, RF */
3645 	ok = rtw_hal_init_phy(adapter);
3646 	if (_FALSE == ok)
3647 		goto out;
3648 
3649 	status = api->halmac_init_interface_cfg(halmac);
3650 	if (status != HALMAC_RET_SUCCESS)
3651 		goto out;
3652 
3653 	/* SKIP: halmac_verify_platform_api */
3654 	/* SKIP: halmac_h2c_lb */
3655 
3656 	/* StateRxIdle */
3657 
3658 	err_ret = 0;
3659 out:
3660 	return err_ret;
3661 }
3662 
rtw_halmac_init_hal(struct dvobj_priv * d)3663 int rtw_halmac_init_hal(struct dvobj_priv *d)
3664 {
3665 	return _halmac_init_hal(d, NULL, 0);
3666 }
3667 
3668 /*
3669  * Notices:
3670  *	Make sure following information
3671  *	1. GET_HAL_RFPATH
3672  *	2. GET_HAL_DATA(dvobj_get_primary_adapter(d))->rfe_type
3673  *	3. GET_HAL_DATA(dvobj_get_primary_adapter(d))->PackageType
3674  *	4. dvobj_get_primary_adapter(d)->registrypriv.mp_mode
3675  *	are all ready before calling this function.
3676  */
rtw_halmac_init_hal_fw(struct dvobj_priv * d,u8 * fw,u32 fwsize)3677 int rtw_halmac_init_hal_fw(struct dvobj_priv *d, u8 *fw, u32 fwsize)
3678 {
3679 	return _halmac_init_hal(d, fw, fwsize);
3680 }
3681 
3682 /*
3683  * Notices:
3684  *	Make sure following information
3685  *	1. GET_HAL_RFPATH
3686  *	2. GET_HAL_DATA(dvobj_get_primary_adapter(d))->rfe_type
3687  *	3. GET_HAL_DATA(dvobj_get_primary_adapter(d))->PackageType
3688  *	4. dvobj_get_primary_adapter(d)->registrypriv.mp_mode
3689  *	are all ready before calling this function.
3690  */
rtw_halmac_init_hal_fw_file(struct dvobj_priv * d,u8 * fwpath)3691 int rtw_halmac_init_hal_fw_file(struct dvobj_priv *d, u8 *fwpath)
3692 {
3693 	u8 *fw = NULL;
3694 	u32 fwmaxsize = 0, size = 0;
3695 	int err = 0;
3696 
3697 
3698 	err = rtw_halmac_get_fw_max_size(d, &fwmaxsize);
3699 	if (err) {
3700 		RTW_ERR("%s: Fail to get Firmware MAX size(err=%d)\n", __FUNCTION__, err);
3701 		return -1;
3702 	}
3703 
3704 	fw = rtw_zmalloc(fwmaxsize);
3705 	if (!fw)
3706 		return -1;
3707 
3708 	size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
3709 	if (!size) {
3710 		err = -1;
3711 		goto exit;
3712 	}
3713 
3714 	err = _halmac_init_hal(d, fw, size);
3715 
3716 exit:
3717 	rtw_mfree(fw, fwmaxsize);
3718 	/*fw = NULL;*/
3719 
3720 	return err;
3721 }
3722 
rtw_halmac_deinit_hal(struct dvobj_priv * d)3723 int rtw_halmac_deinit_hal(struct dvobj_priv *d)
3724 {
3725 	PADAPTER adapter;
3726 	struct halmac_adapter *halmac;
3727 	struct halmac_api *api;
3728 	enum halmac_ret_status status;
3729 	int err = -1;
3730 
3731 
3732 	adapter = dvobj_get_primary_adapter(d);
3733 	halmac = dvobj_to_halmac(d);
3734 	if (!halmac)
3735 		goto out;
3736 	api = HALMAC_GET_API(halmac);
3737 
3738 	status = api->halmac_deinit_interface_cfg(halmac);
3739 	if (status != HALMAC_RET_SUCCESS)
3740 		goto out;
3741 
3742 	rtw_hal_power_off(adapter);
3743 
3744 	err = 0;
3745 out:
3746 	return err;
3747 }
3748 
rtw_halmac_self_verify(struct dvobj_priv * d)3749 int rtw_halmac_self_verify(struct dvobj_priv *d)
3750 {
3751 	struct halmac_adapter *mac;
3752 	struct halmac_api *api;
3753 	enum halmac_ret_status status;
3754 	int err = -1;
3755 
3756 
3757 	mac = dvobj_to_halmac(d);
3758 	api = HALMAC_GET_API(mac);
3759 
3760 	status = api->halmac_verify_platform_api(mac);
3761 	if (status != HALMAC_RET_SUCCESS)
3762 		goto out;
3763 
3764 	status = api->halmac_h2c_lb(mac);
3765 	if (status != HALMAC_RET_SUCCESS)
3766 		goto out;
3767 
3768 	err = 0;
3769 out:
3770 	return err;
3771 }
3772 
rtw_halmac_txfifo_is_empty(struct dvobj_priv * d)3773 static u8 rtw_halmac_txfifo_is_empty(struct dvobj_priv *d)
3774 {
3775 	struct halmac_adapter *mac;
3776 	struct halmac_api *api;
3777 	enum halmac_ret_status status;
3778 	u32 chk_num = 10;
3779 	u8 rst = _FALSE;
3780 
3781 
3782 	mac = dvobj_to_halmac(d);
3783 	api = HALMAC_GET_API(mac);
3784 
3785 	status = api->halmac_txfifo_is_empty(mac, chk_num);
3786 	if (status == HALMAC_RET_SUCCESS)
3787 		rst = _TRUE;
3788 
3789 	return rst;
3790 }
3791 
3792 /**
3793  * rtw_halmac_txfifo_wait_empty() - Wait TX FIFO to be emtpy
3794  * @d:		struct dvobj_priv*
3795  * @timeout:	time limit of wait, unit is ms
3796  *		0 for no limit
3797  *
3798  * Wait TX FIFO to be emtpy.
3799  *
3800  * Return 0 for TX FIFO is empty, otherwise not empty.
3801  */
rtw_halmac_txfifo_wait_empty(struct dvobj_priv * d,u32 timeout)3802 int rtw_halmac_txfifo_wait_empty(struct dvobj_priv *d, u32 timeout)
3803 {
3804 	struct _ADAPTER *a;
3805 	u8 empty = _FALSE;
3806 	u32 cnt = 0;
3807 	systime start_time = 0;
3808 	u32 pass_time; /* ms */
3809 
3810 
3811 	a = dvobj_get_primary_adapter(d);
3812 	start_time = rtw_get_current_time();
3813 
3814 	do {
3815 		cnt++;
3816 		empty = rtw_halmac_txfifo_is_empty(d);
3817 		if (empty == _TRUE)
3818 			break;
3819 
3820 		if (timeout) {
3821 			pass_time = rtw_get_passing_time_ms(start_time);
3822 			if (pass_time > timeout)
3823 				break;
3824 		}
3825 		if (RTW_CANNOT_IO(a)) {
3826 			RTW_WARN("%s: Interrupted by I/O forbiden!\n", __FUNCTION__);
3827 			break;
3828 		}
3829 
3830 		rtw_msleep_os(2);
3831 	} while (1);
3832 
3833 	if (empty == _FALSE) {
3834 #ifdef CONFIG_RTW_DEBUG
3835 		u16 dbg_reg[] = {0x210, 0x230, 0x234, 0x238, 0x23C, 0x240,
3836 				 0x418, 0x10FC, 0x10F8, 0x11F4, 0x11F8};
3837 		u8 i;
3838 		u32 val;
3839 
3840 		if (!RTW_CANNOT_IO(a)) {
3841 			for (i = 0; i < ARRAY_SIZE(dbg_reg); i++) {
3842 				val = rtw_read32(a, dbg_reg[i]);
3843 				RTW_ERR("REG_%X:0x%08x\n", dbg_reg[i], val);
3844 			}
3845 		}
3846 #endif /* CONFIG_RTW_DEBUG */
3847 
3848 		RTW_ERR("%s: Fail to wait txfifo empty!(cnt=%d)\n",
3849 			__FUNCTION__, cnt);
3850 		return -1;
3851 	}
3852 
3853 	return 0;
3854 }
3855 
_fw_mem_drv2halmac(enum fw_mem mem,u8 tx_stop)3856 static enum halmac_dlfw_mem _fw_mem_drv2halmac(enum fw_mem mem, u8 tx_stop)
3857 {
3858 	enum halmac_dlfw_mem mem_halmac = HALMAC_DLFW_MEM_UNDEFINE;
3859 
3860 
3861 	switch (mem) {
3862 	case FW_EMEM:
3863 		if (tx_stop == _FALSE)
3864 			mem_halmac = HALMAC_DLFW_MEM_EMEM_RSVD_PG;
3865 		else
3866 			mem_halmac = HALMAC_DLFW_MEM_EMEM;
3867 		break;
3868 
3869 	case FW_IMEM:
3870 	case FW_DMEM:
3871 		mem_halmac = HALMAC_DLFW_MEM_UNDEFINE;
3872 		break;
3873 	}
3874 
3875 	return mem_halmac;
3876 }
3877 
rtw_halmac_dlfw_mem(struct dvobj_priv * d,u8 * fw,u32 fwsize,enum fw_mem mem)3878 int rtw_halmac_dlfw_mem(struct dvobj_priv *d, u8 *fw, u32 fwsize, enum fw_mem mem)
3879 {
3880 	struct halmac_adapter *mac;
3881 	struct halmac_api *api;
3882 	enum halmac_ret_status status;
3883 	enum halmac_dlfw_mem dlfw_mem;
3884 	u8 tx_stop = _FALSE;
3885 	u32 chk_timeout = 2000; /* unit: ms */
3886 	int err = 0;
3887 
3888 
3889 	mac = dvobj_to_halmac(d);
3890 	api = HALMAC_GET_API(mac);
3891 
3892 	if ((!fw) || (!fwsize))
3893 		return -1;
3894 
3895 #ifndef RTW_HALMAC_DLFW_MEM_NO_STOP_TX
3896 	/* 1. Driver Stop Tx */
3897 	/* ToDo */
3898 
3899 	/* 2. Driver Check Tx FIFO is empty */
3900 	err = rtw_halmac_txfifo_wait_empty(d, chk_timeout);
3901 	if (err)
3902 		tx_stop = _FALSE;
3903 	else
3904 		tx_stop = _TRUE;
3905 #endif /* !RTW_HALMAC_DLFW_MEM_NO_STOP_TX */
3906 
3907 	/* 3. Download Firmware MEM */
3908 	dlfw_mem = _fw_mem_drv2halmac(mem, tx_stop);
3909 	if (dlfw_mem == HALMAC_DLFW_MEM_UNDEFINE) {
3910 		err = -1;
3911 		goto resume_tx;
3912 	}
3913 	status = api->halmac_free_download_firmware(mac, dlfw_mem, fw, fwsize);
3914 	if (status != HALMAC_RET_SUCCESS) {
3915 		RTW_ERR("%s: halmac_free_download_firmware fail(err=0x%x)\n",
3916 			__FUNCTION__, status);
3917 		err = -1;
3918 		goto resume_tx;
3919 	}
3920 
3921 resume_tx:
3922 #ifndef RTW_HALMAC_DLFW_MEM_NO_STOP_TX
3923 	/* 4. Driver resume TX if needed */
3924 	/* ToDo */
3925 #endif /* !RTW_HALMAC_DLFW_MEM_NO_STOP_TX */
3926 
3927 	return err;
3928 }
3929 
rtw_halmac_dlfw_mem_from_file(struct dvobj_priv * d,u8 * fwpath,enum fw_mem mem)3930 int rtw_halmac_dlfw_mem_from_file(struct dvobj_priv *d, u8 *fwpath, enum fw_mem mem)
3931 {
3932 	u8 *fw = NULL;
3933 	u32 fwmaxsize = 0, size = 0;
3934 	int err = 0;
3935 
3936 
3937 	err = rtw_halmac_get_fw_max_size(d, &fwmaxsize);
3938 	if (err) {
3939 		RTW_ERR("%s: Fail to get Firmware MAX size(err=%d)\n", __FUNCTION__, err);
3940 		return -1;
3941 	}
3942 
3943 	fw = rtw_zmalloc(fwmaxsize);
3944 	if (!fw)
3945 		return -1;
3946 
3947 	size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
3948 	if (size)
3949 		err = rtw_halmac_dlfw_mem(d, fw, size, mem);
3950 	else
3951 		err = -1;
3952 
3953 	rtw_mfree(fw, fwmaxsize);
3954 	/*fw = NULL;*/
3955 
3956 	return err;
3957 }
3958 
3959 /*
3960  * Return:
3961  *	0	Success
3962  *	-22	Invalid arguemnt
3963  */
rtw_halmac_dlfw(struct dvobj_priv * d,u8 * fw,u32 fwsize)3964 int rtw_halmac_dlfw(struct dvobj_priv *d, u8 *fw, u32 fwsize)
3965 {
3966 	PADAPTER adapter;
3967 	enum halmac_ret_status status;
3968 	u32 ok;
3969 	int err, err_ret = -1;
3970 
3971 
3972 	if (!fw || !fwsize)
3973 		return -22;
3974 
3975 	adapter = dvobj_get_primary_adapter(d);
3976 
3977 	/* re-download firmware */
3978 	if (rtw_is_hw_init_completed(adapter))
3979 		return download_fw(d, fw, fwsize, 1);
3980 
3981 	/* Download firmware before hal init */
3982 	/* Power on, download firmware and init mac */
3983 	ok = rtw_hal_power_on(adapter);
3984 	if (_FAIL == ok)
3985 		goto out;
3986 
3987 	err = download_fw(d, fw, fwsize, 0);
3988 	if (err) {
3989 		err_ret = err;
3990 		goto out;
3991 	}
3992 
3993 	err = init_mac_flow(d);
3994 	if (err)
3995 		goto out;
3996 
3997 	err = _send_general_info(d);
3998 	if (err)
3999 		goto out;
4000 
4001 	err_ret = 0;
4002 
4003 out:
4004 	return err_ret;
4005 }
4006 
rtw_halmac_dlfw_from_file(struct dvobj_priv * d,u8 * fwpath)4007 int rtw_halmac_dlfw_from_file(struct dvobj_priv *d, u8 *fwpath)
4008 {
4009 	u8 *fw = NULL;
4010 	u32 fwmaxsize = 0, size = 0;
4011 	int err = 0;
4012 
4013 
4014 	err = rtw_halmac_get_fw_max_size(d, &fwmaxsize);
4015 	if (err) {
4016 		RTW_ERR("%s: Fail to get Firmware MAX size(err=%d)\n", __FUNCTION__, err);
4017 		return -1;
4018 	}
4019 
4020 	fw = rtw_zmalloc(fwmaxsize);
4021 	if (!fw)
4022 		return -1;
4023 
4024 	size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
4025 	if (size)
4026 		err = rtw_halmac_dlfw(d, fw, size);
4027 	else
4028 		err = -1;
4029 
4030 	rtw_mfree(fw, fwmaxsize);
4031 	/*fw = NULL;*/
4032 
4033 	return err;
4034 }
4035 
4036 /*
4037  * Description:
4038  *	Power on/off BB/RF domain.
4039  *
4040  * Parameters:
4041  *	enable	_TRUE/_FALSE for power on/off
4042  *
4043  * Return:
4044  *	0	Success
4045  *	others	Fail
4046  */
rtw_halmac_phy_power_switch(struct dvobj_priv * d,u8 enable)4047 int rtw_halmac_phy_power_switch(struct dvobj_priv *d, u8 enable)
4048 {
4049 	PADAPTER adapter;
4050 	struct halmac_adapter *halmac;
4051 	struct halmac_api *api;
4052 	enum halmac_ret_status status;
4053 	u8 on;
4054 
4055 
4056 	adapter = dvobj_get_primary_adapter(d);
4057 	halmac = dvobj_to_halmac(d);
4058 	if (!halmac)
4059 		return -1;
4060 	api = HALMAC_GET_API(halmac);
4061 	on = (enable == _TRUE) ? 1 : 0;
4062 
4063 	status = api->halmac_set_hw_value(halmac, HALMAC_HW_EN_BB_RF, &on);
4064 	if (status != HALMAC_RET_SUCCESS)
4065 		return -1;
4066 
4067 	return 0;
4068 }
4069 
_is_fw_read_cmd_down(PADAPTER adapter,u8 msgbox_num)4070 static u8 _is_fw_read_cmd_down(PADAPTER adapter, u8 msgbox_num)
4071 {
4072 	u8 read_down = _FALSE;
4073 	int retry_cnts = 100;
4074 	u8 valid;
4075 
4076 	do {
4077 		valid = rtw_read8(adapter, REG_HMETFR) & BIT(msgbox_num);
4078 		if (0 == valid)
4079 			read_down = _TRUE;
4080 		else
4081 			rtw_msleep_os(1);
4082 	} while ((!read_down) && (retry_cnts--));
4083 
4084 	if (_FALSE == read_down)
4085 		RTW_WARN("%s, reg_1cc(%x), msg_box(%d)...\n", __func__, rtw_read8(adapter, REG_HMETFR), msgbox_num);
4086 
4087 	return read_down;
4088 }
4089 
4090 /**
4091  * rtw_halmac_send_h2c() - Send H2C to firmware
4092  * @d:		struct dvobj_priv*
4093  * @h2c:	H2C data buffer, suppose to be 8 bytes
4094  *
4095  * Send H2C to firmware by message box register(0x1D0~0x1D3 & 0x1F0~0x1F3).
4096  *
4097  * Assume firmware be ready to accept H2C here, please check
4098  * (hal->bFWReady == _TRUE) before call this function or make sure firmware is
4099  * ready.
4100  *
4101  * Return: 0 if process OK, otherwise fail to send this H2C.
4102  */
rtw_halmac_send_h2c(struct dvobj_priv * d,u8 * h2c)4103 int rtw_halmac_send_h2c(struct dvobj_priv *d, u8 *h2c)
4104 {
4105 	PADAPTER adapter = dvobj_get_primary_adapter(d);
4106 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
4107 	u8 h2c_box_num = 0;
4108 	u32 msgbox_addr = 0;
4109 	u32 msgbox_ex_addr = 0;
4110 	u32 h2c_cmd = 0;
4111 	u32 h2c_cmd_ex = 0;
4112 	int err = -1;
4113 
4114 
4115 	if (!h2c) {
4116 		RTW_WARN("%s: pbuf is NULL\n", __FUNCTION__);
4117 		return err;
4118 	}
4119 
4120 	if (rtw_is_surprise_removed(adapter)) {
4121 		RTW_WARN("%s: surprise removed\n", __FUNCTION__);
4122 		return err;
4123 	}
4124 
4125 	_enter_critical_mutex(&d->h2c_fwcmd_mutex, NULL);
4126 
4127 	/* pay attention to if race condition happened in H2C cmd setting */
4128 	h2c_box_num = hal->LastHMEBoxNum;
4129 
4130 	if (!_is_fw_read_cmd_down(adapter, h2c_box_num)) {
4131 		RTW_WARN(" fw read cmd failed...\n");
4132 #ifdef DBG_CONFIG_ERROR_DETECT
4133 		hal->srestpriv.self_dect_fw = _TRUE;
4134 		hal->srestpriv.self_dect_fw_cnt++;
4135 #endif /* DBG_CONFIG_ERROR_DETECT */
4136 		goto exit;
4137 	}
4138 
4139 	/* Write Ext command (byte 4~7) */
4140 	msgbox_ex_addr = REG_HMEBOX_E0 + (h2c_box_num * EX_MESSAGE_BOX_SIZE);
4141 	_rtw_memcpy((u8 *)(&h2c_cmd_ex), h2c + 4, EX_MESSAGE_BOX_SIZE);
4142 	h2c_cmd_ex = le32_to_cpu(h2c_cmd_ex);
4143 	rtw_write32(adapter, msgbox_ex_addr, h2c_cmd_ex);
4144 
4145 	/* Write command (byte 0~3) */
4146 	msgbox_addr = REG_HMEBOX0 + (h2c_box_num * MESSAGE_BOX_SIZE);
4147 	_rtw_memcpy((u8 *)(&h2c_cmd), h2c, 4);
4148 	h2c_cmd = le32_to_cpu(h2c_cmd);
4149 	rtw_write32(adapter, msgbox_addr, h2c_cmd);
4150 
4151 	/* update last msg box number */
4152 	hal->LastHMEBoxNum = (h2c_box_num + 1) % MAX_H2C_BOX_NUMS;
4153 	err = 0;
4154 
4155 #ifdef DBG_H2C_CONTENT
4156 	RTW_INFO_DUMP("[H2C] - ", h2c, RTW_HALMAC_H2C_MAX_SIZE);
4157 #endif
4158 exit:
4159 	_exit_critical_mutex(&d->h2c_fwcmd_mutex, NULL);
4160 	return err;
4161 }
4162 
4163 /**
4164  * rtw_halmac_c2h_handle() - Handle C2H for HALMAC
4165  * @d:		struct dvobj_priv*
4166  * @c2h:	Full C2H packet, including RX description and payload
4167  * @size:	Size(byte) of c2h
4168  *
4169  * Send C2H packet to HALMAC to process C2H packets, and the expected C2H ID is
4170  * 0xFF. This function won't have any I/O, so caller doesn't have to call it in
4171  * I/O safe place(ex. command thread).
4172  *
4173  * Please sure doesn't call this function in the same thread as someone is
4174  * waiting HALMAC C2H ack, otherwise there is a deadlock happen.
4175  *
4176  * Return: 0 if process OK, otherwise no action for this C2H.
4177  */
rtw_halmac_c2h_handle(struct dvobj_priv * d,u8 * c2h,u32 size)4178 int rtw_halmac_c2h_handle(struct dvobj_priv *d, u8 *c2h, u32 size)
4179 {
4180 	struct halmac_adapter *mac;
4181 	struct halmac_api *api;
4182 	enum halmac_ret_status status;
4183 #ifdef RTW_HALMAC_FILTER_DRV_C2H
4184 	u32 desc_size = 0;
4185 	u8 *c2h_data;
4186 	u8 sub;
4187 #endif /* RTW_HALMAC_FILTER_DRV_C2H */
4188 
4189 
4190 	mac = dvobj_to_halmac(d);
4191 	api = HALMAC_GET_API(mac);
4192 
4193 #ifdef RTW_HALMAC_FILTER_DRV_C2H
4194 	status = api->halmac_get_hw_value(mac, HALMAC_HW_RX_DESC_SIZE,
4195 					  &desc_size);
4196 	if (status != HALMAC_RET_SUCCESS) {
4197 		RTW_ERR("%s: fail to get rx desc size!\n", __FUNCTION__);
4198 		goto skip_filter;
4199 	}
4200 
4201 	c2h_data = c2h + desc_size;
4202 	sub = C2H_HDR_GET_C2H_SUB_CMD_ID(c2h_data);
4203 	switch (sub) {
4204 	case C2H_SUB_CMD_ID_C2H_PKT_FTM_DBG:
4205 	case C2H_SUB_CMD_ID_C2H_PKT_FTM_2_DBG:
4206 	case C2H_SUB_CMD_ID_C2H_PKT_FTM_3_DBG:
4207 	case C2H_SUB_CMD_ID_C2H_PKT_FTM_4_DBG:
4208 	case C2H_SUB_CMD_ID_FTMACKRPT_HDL_DBG:
4209 	case C2H_SUB_CMD_ID_FTMC2H_RPT:
4210 	case C2H_SUB_CMD_ID_DRVFTMC2H_RPT:
4211 	case C2H_SUB_CMD_ID_C2H_PKT_FTM_5_DBG:
4212 	case C2H_SUB_CMD_ID_CCX_RPT:
4213 	case C2H_SUB_CMD_ID_C2H_PKT_NAN_RPT:
4214 	case C2H_SUB_CMD_ID_C2H_PKT_ATM_RPT:
4215 	case C2H_SUB_CMD_ID_C2H_PKT_SCC_CSA_RPT:
4216 	case C2H_SUB_CMD_ID_C2H_PKT_FW_STATUS_NOTIFY:
4217 	case C2H_SUB_CMD_ID_C2H_PKT_FTMSESSION_END:
4218 	case C2H_SUB_CMD_ID_C2H_PKT_DETECT_THERMAL:
4219 	case C2H_SUB_CMD_ID_FW_FWCTRL_RPT:
4220 	case C2H_SUB_CMD_ID_SCAN_CH_NOTIFY:
4221 	case C2H_SUB_CMD_ID_FW_TBTT_RPT:
4222 	case C2H_SUB_CMD_ID_BCN_OFFLOAD:
4223 	case C2H_SUB_CMD_ID_FW_DBG_MSG:
4224 		RTW_PRINT("%s: unhandled C2H, id=0xFF subid=0x%x len=%u\n",
4225 			  __FUNCTION__, sub, C2H_HDR_GET_LEN(c2h_data));
4226 		RTW_PRINT_DUMP("C2H: ", c2h_data, size - desc_size);
4227 		return 0;
4228 	}
4229 
4230 skip_filter:
4231 #endif /* RTW_HALMAC_FILTER_DRV_C2H */
4232 
4233 	status = api->halmac_get_c2h_info(mac, c2h, size);
4234 	if (HALMAC_RET_SUCCESS != status)
4235 		return -1;
4236 
4237 	return 0;
4238 }
4239 
rtw_halmac_get_available_efuse_size(struct dvobj_priv * d,u32 * size)4240 int rtw_halmac_get_available_efuse_size(struct dvobj_priv *d, u32 *size)
4241 {
4242 	struct halmac_adapter *mac;
4243 	struct halmac_api *api;
4244 	enum halmac_ret_status status;
4245 	u32 val;
4246 
4247 
4248 	mac = dvobj_to_halmac(d);
4249 	api = HALMAC_GET_API(mac);
4250 
4251 	status = api->halmac_get_efuse_available_size(mac, &val);
4252 	if (HALMAC_RET_SUCCESS != status)
4253 		return -1;
4254 
4255 	*size = val;
4256 	return 0;
4257 }
4258 
rtw_halmac_get_physical_efuse_size(struct dvobj_priv * d,u32 * size)4259 int rtw_halmac_get_physical_efuse_size(struct dvobj_priv *d, u32 *size)
4260 {
4261 	struct halmac_adapter *mac;
4262 	struct halmac_api *api;
4263 	enum halmac_ret_status status;
4264 	u32 val;
4265 
4266 
4267 	mac = dvobj_to_halmac(d);
4268 	api = HALMAC_GET_API(mac);
4269 
4270 	status = api->halmac_get_efuse_size(mac, &val);
4271 	if (HALMAC_RET_SUCCESS != status)
4272 		return -1;
4273 
4274 	*size = val;
4275 	return 0;
4276 }
4277 
rtw_halmac_read_physical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size)4278 int rtw_halmac_read_physical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size)
4279 {
4280 	struct halmac_adapter *mac;
4281 	struct halmac_api *api;
4282 	enum halmac_ret_status status;
4283 	enum halmac_feature_id id;
4284 	int ret;
4285 
4286 
4287 	mac = dvobj_to_halmac(d);
4288 	api = HALMAC_GET_API(mac);
4289 	id = HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE;
4290 
4291 	ret = init_halmac_event(d, id, map, size);
4292 	if (ret)
4293 		return -1;
4294 
4295 	status = api->halmac_dump_efuse_map(mac, HALMAC_EFUSE_R_DRV);
4296 	if (HALMAC_RET_SUCCESS != status) {
4297 		free_halmac_event(d, id);
4298 		return -1;
4299 	}
4300 
4301 	ret = wait_halmac_event(d, id);
4302 	if (ret)
4303 		return -1;
4304 
4305 	return 0;
4306 }
4307 
rtw_halmac_read_physical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)4308 int rtw_halmac_read_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4309 {
4310 	struct halmac_adapter *mac;
4311 	struct halmac_api *api;
4312 	enum halmac_ret_status status;
4313 	u8 v;
4314 	u32 i;
4315 	u8 *efuse = NULL;
4316 	u32 size = 0;
4317 	int err = 0;
4318 
4319 
4320 	mac = dvobj_to_halmac(d);
4321 	api = HALMAC_GET_API(mac);
4322 
4323 	if (api->halmac_read_efuse) {
4324 		for (i = 0; i < cnt; i++) {
4325 			status = api->halmac_read_efuse(mac, offset + i, &v);
4326 			if (HALMAC_RET_SUCCESS != status)
4327 				return -1;
4328 			data[i] = v;
4329 		}
4330 	} else {
4331 		err = rtw_halmac_get_physical_efuse_size(d, &size);
4332 		if (err)
4333 			return -1;
4334 
4335 		efuse = rtw_zmalloc(size);
4336 		if (!efuse)
4337 			return -1;
4338 
4339 		err = rtw_halmac_read_physical_efuse_map(d, efuse, size);
4340 		if (err)
4341 			err = -1;
4342 		else
4343 			_rtw_memcpy(data, efuse + offset, cnt);
4344 
4345 		rtw_mfree(efuse, size);
4346 	}
4347 
4348 	return err;
4349 }
4350 
rtw_halmac_write_physical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)4351 int rtw_halmac_write_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4352 {
4353 	struct halmac_adapter *mac;
4354 	struct halmac_api *api;
4355 	enum halmac_ret_status status;
4356 	u32 i;
4357 
4358 
4359 	mac = dvobj_to_halmac(d);
4360 	api = HALMAC_GET_API(mac);
4361 
4362 	if (api->halmac_write_efuse == NULL)
4363 		return -1;
4364 
4365 	for (i = 0; i < cnt; i++) {
4366 		status = api->halmac_write_efuse(mac, offset + i, data[i]);
4367 		if (HALMAC_RET_SUCCESS != status)
4368 			return -1;
4369 	}
4370 
4371 	return 0;
4372 }
4373 
rtw_halmac_get_logical_efuse_size(struct dvobj_priv * d,u32 * size)4374 int rtw_halmac_get_logical_efuse_size(struct dvobj_priv *d, u32 *size)
4375 {
4376 	struct halmac_adapter *mac;
4377 	struct halmac_api *api;
4378 	enum halmac_ret_status status;
4379 	u32 val;
4380 
4381 
4382 	mac = dvobj_to_halmac(d);
4383 	api = HALMAC_GET_API(mac);
4384 
4385 	status = api->halmac_get_logical_efuse_size(mac, &val);
4386 	if (HALMAC_RET_SUCCESS != status)
4387 		return -1;
4388 
4389 	*size = val;
4390 	return 0;
4391 }
4392 
rtw_halmac_read_logical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size,u8 * maskmap,u32 masksize)4393 int rtw_halmac_read_logical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size, u8 *maskmap, u32 masksize)
4394 {
4395 	struct halmac_adapter *mac;
4396 	struct halmac_api *api;
4397 	enum halmac_ret_status status;
4398 	enum halmac_feature_id id;
4399 	int ret;
4400 
4401 
4402 	mac = dvobj_to_halmac(d);
4403 	api = HALMAC_GET_API(mac);
4404 	id = HALMAC_FEATURE_DUMP_LOGICAL_EFUSE;
4405 
4406 	ret = init_halmac_event(d, id, map, size);
4407 	if (ret)
4408 		return -1;
4409 
4410 	status = api->halmac_dump_logical_efuse_map(mac, HALMAC_EFUSE_R_DRV);
4411 	if (HALMAC_RET_SUCCESS != status) {
4412 		free_halmac_event(d, id);
4413 		return -1;
4414 	}
4415 
4416 	ret = wait_halmac_event(d, id);
4417 	if (ret)
4418 		return -1;
4419 
4420 	if (maskmap && masksize) {
4421 		struct halmac_pg_efuse_info pginfo;
4422 
4423 		pginfo.efuse_map = map;
4424 		pginfo.efuse_map_size = size;
4425 		pginfo.efuse_mask = maskmap;
4426 		pginfo.efuse_mask_size = masksize;
4427 
4428 		status = api->halmac_mask_logical_efuse(mac, &pginfo);
4429 		if (status != HALMAC_RET_SUCCESS)
4430 			RTW_WARN("%s: mask logical efuse FAIL!\n", __FUNCTION__);
4431 	}
4432 
4433 	return 0;
4434 }
4435 
rtw_halmac_write_logical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size,u8 * maskmap,u32 masksize)4436 int rtw_halmac_write_logical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size, u8 *maskmap, u32 masksize)
4437 {
4438 	struct halmac_adapter *mac;
4439 	struct halmac_api *api;
4440 	struct halmac_pg_efuse_info pginfo;
4441 	enum halmac_ret_status status;
4442 
4443 
4444 	mac = dvobj_to_halmac(d);
4445 	api = HALMAC_GET_API(mac);
4446 
4447 	pginfo.efuse_map = map;
4448 	pginfo.efuse_map_size = size;
4449 	pginfo.efuse_mask = maskmap;
4450 	pginfo.efuse_mask_size = masksize;
4451 
4452 	status = api->halmac_pg_efuse_by_map(mac, &pginfo, HALMAC_EFUSE_R_AUTO);
4453 	if (HALMAC_RET_SUCCESS != status)
4454 		return -1;
4455 
4456 	return 0;
4457 }
4458 
rtw_halmac_read_logical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)4459 int rtw_halmac_read_logical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4460 {
4461 	struct halmac_adapter *mac;
4462 	struct halmac_api *api;
4463 	enum halmac_ret_status status;
4464 	u8 v;
4465 	u32 i;
4466 
4467 
4468 	mac = dvobj_to_halmac(d);
4469 	api = HALMAC_GET_API(mac);
4470 
4471 	for (i = 0; i < cnt; i++) {
4472 		status = api->halmac_read_logical_efuse(mac, offset + i, &v);
4473 		if (HALMAC_RET_SUCCESS != status)
4474 			return -1;
4475 		data[i] = v;
4476 	}
4477 
4478 	return 0;
4479 }
4480 
rtw_halmac_write_logical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)4481 int rtw_halmac_write_logical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4482 {
4483 	struct halmac_adapter *mac;
4484 	struct halmac_api *api;
4485 	enum halmac_ret_status status;
4486 	u32 i;
4487 
4488 
4489 	mac = dvobj_to_halmac(d);
4490 	api = HALMAC_GET_API(mac);
4491 
4492 	for (i = 0; i < cnt; i++) {
4493 		status = api->halmac_write_logical_efuse(mac, offset + i, data[i]);
4494 		if (HALMAC_RET_SUCCESS != status)
4495 			return -1;
4496 	}
4497 
4498 	return 0;
4499 }
4500 
rtw_halmac_write_bt_physical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)4501 int rtw_halmac_write_bt_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4502 {
4503 	struct halmac_adapter *mac;
4504 	struct halmac_api *api;
4505 	enum halmac_ret_status status;
4506 	u32 i;
4507 	u8 bank = 1;
4508 
4509 
4510 	mac = dvobj_to_halmac(d);
4511 	api = HALMAC_GET_API(mac);
4512 
4513 	for (i = 0; i < cnt; i++) {
4514 		status = api->halmac_write_efuse_bt(mac, offset + i, data[i], bank);
4515 		if (HALMAC_RET_SUCCESS != status) {
4516 			printk("%s: halmac_write_efuse_bt status = %d\n", __FUNCTION__, status);
4517 			return -1;
4518 		}
4519 	}
4520 	printk("%s: halmac_write_efuse_bt status = HALMAC_RET_SUCCESS %d\n", __FUNCTION__, status);
4521 	return 0;
4522 }
4523 
4524 
rtw_halmac_read_bt_physical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size)4525 int rtw_halmac_read_bt_physical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size)
4526 {
4527 	struct halmac_adapter *mac;
4528 	struct halmac_api *api;
4529 	enum halmac_ret_status status;
4530 	int bank = 1;
4531 
4532 
4533 	mac = dvobj_to_halmac(d);
4534 	api = HALMAC_GET_API(mac);
4535 
4536 	status = api->halmac_dump_efuse_map_bt(mac, bank, size, map);
4537 	if (HALMAC_RET_SUCCESS != status) {
4538 		printk("%s: halmac_dump_efuse_map_bt fail!\n", __FUNCTION__);
4539 		return -1;
4540 	}
4541 
4542 	printk("%s: OK!\n", __FUNCTION__);
4543 
4544 	return 0;
4545 }
4546 
_fifo_sel_drv2halmac(u8 fifo_sel)4547 static enum hal_fifo_sel _fifo_sel_drv2halmac(u8 fifo_sel)
4548 {
4549 	switch (fifo_sel) {
4550 	case 0:
4551 		return HAL_FIFO_SEL_TX;
4552 	case 1:
4553 		return HAL_FIFO_SEL_RX;
4554 	case 2:
4555 		return HAL_FIFO_SEL_RSVD_PAGE;
4556 	case 3:
4557 		return HAL_FIFO_SEL_REPORT;
4558 	case 4:
4559 		return HAL_FIFO_SEL_LLT;
4560 	case 5:
4561 		return HAL_FIFO_SEL_RXBUF_FW;
4562 	}
4563 
4564 	return HAL_FIFO_SEL_RSVD_PAGE;
4565 }
4566 
4567 /*#define CONFIG_HALMAC_FIFO_DUMP*/
rtw_halmac_dump_fifo(struct dvobj_priv * d,u8 fifo_sel,u32 addr,u32 size,u8 * buffer)4568 int rtw_halmac_dump_fifo(struct dvobj_priv *d, u8 fifo_sel, u32 addr, u32 size, u8 *buffer)
4569 {
4570 	struct halmac_adapter *mac;
4571 	struct halmac_api *api;
4572 	enum hal_fifo_sel halmac_fifo_sel;
4573 	enum halmac_ret_status status;
4574 	u8 *pfifo_map = NULL;
4575 	u32 fifo_size = 0;
4576 	s8 ret = 0;/* 0:success, -1:error */
4577 	u8 mem_created = _FALSE;
4578 
4579 
4580 	mac = dvobj_to_halmac(d);
4581 	api = HALMAC_GET_API(mac);
4582 
4583 	if ((size != 0) && (buffer == NULL))
4584 		return -1;
4585 
4586 	halmac_fifo_sel = _fifo_sel_drv2halmac(fifo_sel);
4587 
4588 	if ((size) && (buffer)) {
4589 		pfifo_map = buffer;
4590 		fifo_size = size;
4591 	} else {
4592 		fifo_size = api->halmac_get_fifo_size(mac, halmac_fifo_sel);
4593 
4594 		if (fifo_size)
4595 			pfifo_map = rtw_zvmalloc(fifo_size);
4596 		if (pfifo_map == NULL)
4597 			return -1;
4598 		mem_created = _TRUE;
4599 	}
4600 
4601 	status = api->halmac_dump_fifo(mac, halmac_fifo_sel, addr, fifo_size, pfifo_map);
4602 	if (HALMAC_RET_SUCCESS != status) {
4603 		ret = -1;
4604 		goto _exit;
4605 	}
4606 
4607 #ifdef CONFIG_HALMAC_FIFO_DUMP
4608 	{
4609 		static const char * const fifo_sel_str[] = {
4610 			"TX", "RX", "RSVD_PAGE", "REPORT", "LLT", "RXBUF_FW"
4611 		};
4612 
4613 		RTW_INFO("%s FIFO DUMP [start_addr:0x%04x , size:%d]\n", fifo_sel_str[halmac_fifo_sel], addr, fifo_size);
4614 		RTW_INFO_DUMP("\n", pfifo_map, fifo_size);
4615 		RTW_INFO(" ==================================================\n");
4616 	}
4617 #endif /* CONFIG_HALMAC_FIFO_DUMP */
4618 
4619 _exit:
4620 	if ((mem_created == _TRUE) && pfifo_map)
4621 		rtw_vmfree(pfifo_map, fifo_size);
4622 
4623 	return ret;
4624 }
4625 
4626 /*
4627  * rtw_halmac_rx_agg_switch() - Switch RX aggregation function and setting
4628  * @d		struct dvobj_priv *
4629  * @enable	_FALSE/_TRUE for disable/enable RX aggregation function
4630  *
4631  * This function could help to on/off bus RX aggregation function, and is only
4632  * useful for SDIO and USB interface. Although only "enable" flag is brough in,
4633  * some setting would be taken from other places, and they are from:
4634  * [DMA aggregation]
4635  *	struct hal_com_data.rxagg_dma_size
4636  *	struct hal_com_data.rxagg_dma_timeout
4637  * [USB aggregation] (only use for USB interface)
4638  *	struct hal_com_data.rxagg_usb_size
4639  *	struct hal_com_data.rxagg_usb_timeout
4640  * If above values of size and timeout are both 0 means driver would not
4641  * control the threshold setting and leave it to HALMAC handle.
4642  *
4643  * From HALMAC V1_04_04, driver force the size threshold be hard limit, and the
4644  * rx size can not exceed the setting.
4645  *
4646  * Return 0 for success, otherwise fail.
4647  */
rtw_halmac_rx_agg_switch(struct dvobj_priv * d,u8 enable)4648 int rtw_halmac_rx_agg_switch(struct dvobj_priv *d, u8 enable)
4649 {
4650 	struct _ADAPTER *adapter;
4651 	struct hal_com_data *hal;
4652 	struct halmac_adapter *halmac;
4653 	struct halmac_api *api;
4654 	struct halmac_rxagg_cfg rxaggcfg;
4655 	enum halmac_ret_status status;
4656 
4657 
4658 	adapter = dvobj_get_primary_adapter(d);
4659 	hal = GET_HAL_DATA(adapter);
4660 	halmac = dvobj_to_halmac(d);
4661 	api = HALMAC_GET_API(halmac);
4662 	_rtw_memset((void *)&rxaggcfg, 0, sizeof(rxaggcfg));
4663 	rxaggcfg.mode = HALMAC_RX_AGG_MODE_NONE;
4664 	/*
4665 	 * Always enable size limit to avoid rx size exceed
4666 	 * driver defined size.
4667 	 */
4668 	rxaggcfg.threshold.size_limit_en = 1;
4669 
4670 #ifdef RTW_RX_AGGREGATION
4671 	if (_TRUE == enable) {
4672 #ifdef CONFIG_SDIO_HCI
4673 		rxaggcfg.mode = HALMAC_RX_AGG_MODE_DMA;
4674 		rxaggcfg.threshold.drv_define = 0;
4675 		if (hal->rxagg_dma_size || hal->rxagg_dma_timeout) {
4676 			rxaggcfg.threshold.drv_define = 1;
4677 			rxaggcfg.threshold.timeout = hal->rxagg_dma_timeout;
4678 			rxaggcfg.threshold.size = hal->rxagg_dma_size;
4679 			RTW_INFO("%s: RX aggregation threshold: "
4680 				 "timeout=%u size=%u\n",
4681 				 __FUNCTION__,
4682 				 hal->rxagg_dma_timeout,
4683 				 hal->rxagg_dma_size);
4684 		}
4685 #elif defined(CONFIG_USB_HCI)
4686 		switch (hal->rxagg_mode) {
4687 		case RX_AGG_DISABLE:
4688 			rxaggcfg.mode = HALMAC_RX_AGG_MODE_NONE;
4689 			break;
4690 
4691 		case RX_AGG_DMA:
4692 			rxaggcfg.mode = HALMAC_RX_AGG_MODE_DMA;
4693 			if (hal->rxagg_dma_size || hal->rxagg_dma_timeout) {
4694 				rxaggcfg.threshold.drv_define = 1;
4695 				rxaggcfg.threshold.timeout = hal->rxagg_dma_timeout;
4696 				rxaggcfg.threshold.size = hal->rxagg_dma_size;
4697 			}
4698 			break;
4699 
4700 		case RX_AGG_USB:
4701 		case RX_AGG_MIX:
4702 			rxaggcfg.mode = HALMAC_RX_AGG_MODE_USB;
4703 			if (hal->rxagg_usb_size || hal->rxagg_usb_timeout) {
4704 				rxaggcfg.threshold.drv_define = 1;
4705 				rxaggcfg.threshold.timeout = hal->rxagg_usb_timeout;
4706 				rxaggcfg.threshold.size = hal->rxagg_usb_size;
4707 			}
4708 			break;
4709 		}
4710 #endif /* CONFIG_USB_HCI */
4711 	}
4712 #endif /* RTW_RX_AGGREGATION */
4713 
4714 	status = api->halmac_cfg_rx_aggregation(halmac, &rxaggcfg);
4715 	if (status != HALMAC_RET_SUCCESS)
4716 		return -1;
4717 
4718 	return 0;
4719 }
4720 
rtw_halmac_download_rsvd_page(struct dvobj_priv * dvobj,u8 pg_offset,u8 * pbuf,u32 size)4721 int rtw_halmac_download_rsvd_page(struct dvobj_priv *dvobj, u8 pg_offset, u8 *pbuf, u32 size)
4722 {
4723 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4724 	struct halmac_adapter *halmac = dvobj_to_halmac(dvobj);
4725 	struct halmac_api *api = HALMAC_GET_API(halmac);
4726 
4727 	status = api->halmac_dl_drv_rsvd_page(halmac, pg_offset, pbuf, size);
4728 	if (status != HALMAC_RET_SUCCESS)
4729 		return -1;
4730 
4731 	return 0;
4732 }
4733 
4734 /*
4735  * Description
4736  *	Fill following spec info from HALMAC API:
4737  *	sec_cam_ent_num
4738  *
4739  * Return
4740  *	0	Success
4741  *	others	Fail
4742  */
rtw_halmac_fill_hal_spec(struct dvobj_priv * dvobj,struct hal_spec_t * spec)4743 int rtw_halmac_fill_hal_spec(struct dvobj_priv *dvobj, struct hal_spec_t *spec)
4744 {
4745 	enum halmac_ret_status status;
4746 	struct halmac_adapter *halmac;
4747 	struct halmac_api *api;
4748 	u8 cam = 0;	/* Security Cam Entry Number */
4749 
4750 
4751 	halmac = dvobj_to_halmac(dvobj);
4752 	api = HALMAC_GET_API(halmac);
4753 
4754 	/* Prepare data from HALMAC */
4755 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_CAM_ENTRY_NUM, &cam);
4756 	if (status != HALMAC_RET_SUCCESS)
4757 		return -1;
4758 
4759 	/* Fill data to hal_spec_t */
4760 	spec->sec_cam_ent_num = cam;
4761 
4762 	return 0;
4763 }
4764 
rtw_halmac_p2pps(struct dvobj_priv * dvobj,struct hal_p2p_ps_para * pp2p_ps_para)4765 int rtw_halmac_p2pps(struct dvobj_priv *dvobj, struct hal_p2p_ps_para *pp2p_ps_para)
4766 {
4767 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4768 	struct halmac_adapter *halmac = dvobj_to_halmac(dvobj);
4769 	struct halmac_api *api = HALMAC_GET_API(halmac);
4770 	struct halmac_p2pps halmac_p2p_ps;
4771 
4772 	(&halmac_p2p_ps)->offload_en = pp2p_ps_para->offload_en;
4773 	(&halmac_p2p_ps)->role = pp2p_ps_para->role;
4774 	(&halmac_p2p_ps)->ctwindow_en = pp2p_ps_para->ctwindow_en;
4775 	(&halmac_p2p_ps)->noa_en = pp2p_ps_para->noa_en;
4776 	(&halmac_p2p_ps)->noa_sel = pp2p_ps_para->noa_sel;
4777 	(&halmac_p2p_ps)->all_sta_sleep = pp2p_ps_para->all_sta_sleep;
4778 	(&halmac_p2p_ps)->discovery = pp2p_ps_para->discovery;
4779 	(&halmac_p2p_ps)->disable_close_rf = pp2p_ps_para->disable_close_rf;
4780 	(&halmac_p2p_ps)->p2p_port_id = _hw_port_drv2halmac(pp2p_ps_para->p2p_port_id);
4781 	(&halmac_p2p_ps)->p2p_group = pp2p_ps_para->p2p_group;
4782 	(&halmac_p2p_ps)->p2p_macid = pp2p_ps_para->p2p_macid;
4783 	(&halmac_p2p_ps)->ctwindow_length = pp2p_ps_para->ctwindow_length;
4784 	(&halmac_p2p_ps)->noa_duration_para = pp2p_ps_para->noa_duration_para;
4785 	(&halmac_p2p_ps)->noa_interval_para = pp2p_ps_para->noa_interval_para;
4786 	(&halmac_p2p_ps)->noa_start_time_para = pp2p_ps_para->noa_start_time_para;
4787 	(&halmac_p2p_ps)->noa_count_para = pp2p_ps_para->noa_count_para;
4788 
4789 	status = api->halmac_p2pps(halmac, (&halmac_p2p_ps));
4790 	if (status != HALMAC_RET_SUCCESS)
4791 		return -1;
4792 
4793 	return 0;
4794 
4795 }
4796 
4797 /**
4798  * rtw_halmac_iqk() - Run IQ Calibration
4799  * @d:		struct dvobj_priv*
4800  * @clear:	IQK parameters
4801  * @segment:	IQK parameters
4802  *
4803  * Process IQ Calibration(IQK).
4804  *
4805  * Return 0 for OK, otherwise fail.
4806  */
rtw_halmac_iqk(struct dvobj_priv * d,u8 clear,u8 segment)4807 int rtw_halmac_iqk(struct dvobj_priv *d, u8 clear, u8 segment)
4808 {
4809 	struct halmac_adapter *mac;
4810 	struct halmac_api *api;
4811 	enum halmac_ret_status status;
4812 	enum halmac_feature_id id;
4813 	struct halmac_iqk_para para;
4814 	int ret;
4815 	u8 retry = 3;
4816 	u8 delay = 1; /* ms */
4817 
4818 
4819 	mac = dvobj_to_halmac(d);
4820 	api = HALMAC_GET_API(mac);
4821 	id = HALMAC_FEATURE_IQK;
4822 
4823 	ret = init_halmac_event(d, id, NULL, 0);
4824 	if (ret)
4825 		return -1;
4826 
4827 	para.clear = clear;
4828 	para.segment_iqk = segment;
4829 
4830 	do {
4831 		status = api->halmac_start_iqk(mac, &para);
4832 		if (status != HALMAC_RET_BUSY_STATE)
4833 			break;
4834 		RTW_WARN("%s: Fail to start IQK, status is BUSY! retry=%d\n", __FUNCTION__, retry);
4835 		if (!retry)
4836 			break;
4837 		retry--;
4838 		rtw_msleep_os(delay);
4839 	} while (1);
4840 	if (status != HALMAC_RET_SUCCESS) {
4841 		free_halmac_event(d, id);
4842 		return -1;
4843 	}
4844 
4845 	ret = wait_halmac_event(d, id);
4846 	if (ret)
4847 		return -1;
4848 
4849 	return 0;
4850 }
4851 
4852 /**
4853  * rtw_halmac_dpk() - Run DP Calibration
4854  * @d:		struct dvobj_priv*
4855  * @buf:	buffer for store return value
4856  * @bufsz:	size of buffer
4857  *
4858  * Process DP Calibration(DPK).
4859  *
4860  * Return 0 for OK, otherwise fail.
4861  */
rtw_halmac_dpk(struct dvobj_priv * d,u8 * buf,u32 bufsz)4862 int rtw_halmac_dpk(struct dvobj_priv *d, u8 *buf, u32 bufsz)
4863 {
4864 	struct halmac_adapter *mac;
4865 	struct halmac_api *api;
4866 	enum halmac_ret_status status;
4867 	enum halmac_feature_id id;
4868 	int ret;
4869 
4870 
4871 	mac = dvobj_to_halmac(d);
4872 	api = HALMAC_GET_API(mac);
4873 	id = HALMAC_FEATURE_DPK;
4874 
4875 	ret = init_halmac_event(d, id, buf, bufsz);
4876 	if (ret)
4877 		return -1;
4878 
4879 	status = api->halmac_start_dpk(mac);
4880 	if (status != HALMAC_RET_SUCCESS) {
4881 		free_halmac_event(d, id);
4882 		RTW_ERR("%s: Fail to start DPK (0x%x)!\n",
4883 			__FUNCTION__, status);
4884 		return -1;
4885 	}
4886 
4887 	ret = wait_halmac_event(d, id);
4888 	if (ret)
4889 		return -1;
4890 
4891 	return 0;
4892 }
4893 
_phy_parameter_val_drv2halmac(u32 val,u8 msk_en,u32 msk)4894 static inline u32 _phy_parameter_val_drv2halmac(u32 val, u8 msk_en, u32 msk)
4895 {
4896 	if (!msk_en)
4897 		return val;
4898 
4899 	return (val << bitshift(msk));
4900 }
4901 
_phy_parameter_drv2halmac(struct rtw_phy_parameter * para,struct halmac_phy_parameter_info * info)4902 static int _phy_parameter_drv2halmac(struct rtw_phy_parameter *para, struct halmac_phy_parameter_info *info)
4903 {
4904 	if (!para || !info)
4905 		return -1;
4906 
4907 	_rtw_memset(info, 0, sizeof(*info));
4908 
4909 	switch (para->cmd) {
4910 	case 0:
4911 		/* MAC register */
4912 		switch (para->data.mac.size) {
4913 		case 1:
4914 			info->cmd_id = HALMAC_PARAMETER_CMD_MAC_W8;
4915 			break;
4916 		case 2:
4917 			info->cmd_id = HALMAC_PARAMETER_CMD_MAC_W16;
4918 			break;
4919 		default:
4920 			info->cmd_id = HALMAC_PARAMETER_CMD_MAC_W32;
4921 			break;
4922 		}
4923 		info->content.MAC_REG_W.value = _phy_parameter_val_drv2halmac(
4924 							para->data.mac.value,
4925 							para->data.mac.msk_en,
4926 							para->data.mac.msk);
4927 		info->content.MAC_REG_W.msk = para->data.mac.msk;
4928 		info->content.MAC_REG_W.offset = para->data.mac.offset;
4929 		info->content.MAC_REG_W.msk_en = para->data.mac.msk_en;
4930 		break;
4931 
4932 	case 1:
4933 		/* BB register */
4934 		switch (para->data.bb.size) {
4935 		case 1:
4936 			info->cmd_id = HALMAC_PARAMETER_CMD_BB_W8;
4937 			break;
4938 		case 2:
4939 			info->cmd_id = HALMAC_PARAMETER_CMD_BB_W16;
4940 			break;
4941 		default:
4942 			info->cmd_id = HALMAC_PARAMETER_CMD_BB_W32;
4943 			break;
4944 		}
4945 		info->content.BB_REG_W.value = _phy_parameter_val_drv2halmac(
4946 							para->data.bb.value,
4947 							para->data.bb.msk_en,
4948 							para->data.bb.msk);
4949 		info->content.BB_REG_W.msk = para->data.bb.msk;
4950 		info->content.BB_REG_W.offset = para->data.bb.offset;
4951 		info->content.BB_REG_W.msk_en = para->data.bb.msk_en;
4952 		break;
4953 
4954 	case 2:
4955 		/* RF register */
4956 		info->cmd_id = HALMAC_PARAMETER_CMD_RF_W;
4957 		info->content.RF_REG_W.value = _phy_parameter_val_drv2halmac(
4958 							para->data.rf.value,
4959 							para->data.rf.msk_en,
4960 							para->data.rf.msk);
4961 		info->content.RF_REG_W.msk = para->data.rf.msk;
4962 		info->content.RF_REG_W.offset = para->data.rf.offset;
4963 		info->content.RF_REG_W.msk_en = para->data.rf.msk_en;
4964 		info->content.RF_REG_W.rf_path = para->data.rf.path;
4965 		break;
4966 
4967 	case 3:
4968 		/* Delay register */
4969 		if (para->data.delay.unit == 0)
4970 			info->cmd_id = HALMAC_PARAMETER_CMD_DELAY_US;
4971 		else
4972 			info->cmd_id = HALMAC_PARAMETER_CMD_DELAY_MS;
4973 		info->content.DELAY_TIME.delay_time = para->data.delay.value;
4974 		break;
4975 
4976 	case 0xFF:
4977 		/* Latest(End) command */
4978 		info->cmd_id = HALMAC_PARAMETER_CMD_END;
4979 		break;
4980 
4981 	default:
4982 		return -1;
4983 	}
4984 
4985 	return 0;
4986 }
4987 
4988 /**
4989  * rtw_halmac_cfg_phy_para() - Register(Phy parameter) configuration
4990  * @d:		struct dvobj_priv*
4991  * @para:	phy parameter
4992  *
4993  * Configure registers by firmware using H2C/C2H mechanism.
4994  * The latest command should be para->cmd==0xFF(End command) to finish all
4995  * processes.
4996  *
4997  * Return: 0 for OK, otherwise fail.
4998  */
rtw_halmac_cfg_phy_para(struct dvobj_priv * d,struct rtw_phy_parameter * para)4999 int rtw_halmac_cfg_phy_para(struct dvobj_priv *d, struct rtw_phy_parameter *para)
5000 {
5001 	struct halmac_adapter *mac;
5002 	struct halmac_api *api;
5003 	enum halmac_ret_status status;
5004 	enum halmac_feature_id id;
5005 	struct halmac_phy_parameter_info info;
5006 	u8 full_fifo;
5007 	int err, ret;
5008 
5009 
5010 	mac = dvobj_to_halmac(d);
5011 	api = HALMAC_GET_API(mac);
5012 	id = HALMAC_FEATURE_CFG_PARA;
5013 	full_fifo = 1; /* ToDo: How to deciede? */
5014 	ret = 0;
5015 
5016 	err = _phy_parameter_drv2halmac(para, &info);
5017 	if (err)
5018 		return -1;
5019 
5020 	err = init_halmac_event(d, id, NULL, 0);
5021 	if (err)
5022 		return -1;
5023 
5024 	status = api->halmac_cfg_parameter(mac, &info, full_fifo);
5025 	if (info.cmd_id == HALMAC_PARAMETER_CMD_END) {
5026 		if (status == HALMAC_RET_SUCCESS) {
5027 			err = wait_halmac_event(d, id);
5028 			if (err)
5029 				ret = -1;
5030 		} else {
5031 			free_halmac_event(d, id);
5032 			ret = -1;
5033 			RTW_ERR("%s: Fail to send END of cfg parameter, status is 0x%x!\n", __FUNCTION__, status);
5034 		}
5035 	} else {
5036 		if (status == HALMAC_RET_PARA_SENDING) {
5037 			err = wait_halmac_event(d, id);
5038 			if (err)
5039 				ret = -1;
5040 		} else {
5041 			free_halmac_event(d, id);
5042 			if (status != HALMAC_RET_SUCCESS) {
5043 				ret = -1;
5044 				RTW_ERR("%s: Fail to cfg parameter, status is 0x%x!\n", __FUNCTION__, status);
5045 			}
5046 		}
5047 	}
5048 
5049 	return ret;
5050 }
5051 
_led_mode_drv2halmac(u8 drv_mode)5052 static enum halmac_wlled_mode _led_mode_drv2halmac(u8 drv_mode)
5053 {
5054 	enum halmac_wlled_mode halmac_mode;
5055 
5056 
5057 	switch (drv_mode) {
5058 	case 1:
5059 		halmac_mode = HALMAC_WLLED_MODE_TX;
5060 		break;
5061 	case 2:
5062 		halmac_mode = HALMAC_WLLED_MODE_RX;
5063 		break;
5064 	case 3:
5065 		halmac_mode = HALMAC_WLLED_MODE_SW_CTRL;
5066 		break;
5067 	case 0:
5068 	default:
5069 		halmac_mode = HALMAC_WLLED_MODE_TRX;
5070 		break;
5071 	}
5072 
5073 	return halmac_mode;
5074 }
5075 
5076 /**
5077  * rtw_halmac_led_cfg() - Configure Hardware LED Mode
5078  * @d:		struct dvobj_priv*
5079  * @enable:	enable or disable LED function
5080  *		0: disable
5081  *		1: enable
5082  * @mode:	WLan LED mode (valid when enable==1)
5083  *		0: Blink when TX(transmit packet) and RX(receive packet)
5084  *		1: Blink when TX only
5085  *		2: Blink when RX only
5086  *		3: Software control
5087  *
5088  * Configure hardware WLan LED mode.
5089  * If want to change LED mode after enabled, need to disable LED first and
5090  * enable again to set new mode.
5091  *
5092  * Return 0 for OK, otherwise fail.
5093  */
rtw_halmac_led_cfg(struct dvobj_priv * d,u8 enable,u8 mode)5094 int rtw_halmac_led_cfg(struct dvobj_priv *d, u8 enable, u8 mode)
5095 {
5096 	struct halmac_adapter *halmac;
5097 	struct halmac_api *api;
5098 	enum halmac_wlled_mode led_mode;
5099 	enum halmac_ret_status status;
5100 
5101 
5102 	halmac = dvobj_to_halmac(d);
5103 	api = HALMAC_GET_API(halmac);
5104 
5105 	if (enable) {
5106 		status = api->halmac_pinmux_set_func(halmac,
5107 						     HALMAC_GPIO_FUNC_WL_LED);
5108 		if (status != HALMAC_RET_SUCCESS) {
5109 			RTW_ERR("%s: pinmux set fail!(0x%x)\n",
5110 				__FUNCTION__, status);
5111 			return -1;
5112 		}
5113 
5114 		led_mode = _led_mode_drv2halmac(mode);
5115 		status = api->halmac_pinmux_wl_led_mode(halmac, led_mode);
5116 		if (status != HALMAC_RET_SUCCESS) {
5117 			RTW_ERR("%s: mode set fail!(0x%x)\n",
5118 				__FUNCTION__, status);
5119 			return -1;
5120 		}
5121 	} else {
5122 		/* Change LED to software control and turn off */
5123 		api->halmac_pinmux_wl_led_mode(halmac,
5124 					       HALMAC_WLLED_MODE_SW_CTRL);
5125 		api->halmac_pinmux_wl_led_sw_ctrl(halmac, 0);
5126 
5127 		status = api->halmac_pinmux_free_func(halmac,
5128 						      HALMAC_GPIO_FUNC_WL_LED);
5129 		if (status != HALMAC_RET_SUCCESS) {
5130 			RTW_ERR("%s: pinmux free fail!(0x%x)\n",
5131 				__FUNCTION__, status);
5132 			return -1;
5133 		}
5134 	}
5135 
5136 	return 0;
5137 }
5138 
5139 /**
5140  * rtw_halmac_led_switch() - Turn Hardware LED on/off
5141  * @d:		struct dvobj_priv*
5142  * @on:		LED light or not
5143  *		0: Off
5144  *		1: On(Light)
5145  *
5146  * Turn Hardware WLan LED On/Off.
5147  * Before use this function, user should call rtw_halmac_led_ctrl() to switch
5148  * mode to "software control(3)" first, otherwise control would fail.
5149  * The interval between on and off must be longer than 1 ms, or the LED would
5150  * keep light or dark only.
5151  * Ex. Turn off LED at first, turn on after 0.5ms and turn off again after
5152  * 0.5ms. The LED during this flow will only keep dark, and miss the turn on
5153  * operation between two turn off operations.
5154  */
rtw_halmac_led_switch(struct dvobj_priv * d,u8 on)5155 void rtw_halmac_led_switch(struct dvobj_priv *d, u8 on)
5156 {
5157 	struct halmac_adapter *halmac;
5158 	struct halmac_api *api;
5159 
5160 
5161 	halmac = dvobj_to_halmac(d);
5162 	api = HALMAC_GET_API(halmac);
5163 
5164 	api->halmac_pinmux_wl_led_sw_ctrl(halmac, on);
5165 }
5166 
_gpio_cfg(struct dvobj_priv * d,enum halmac_gpio_func gpio,u8 enable)5167 static int _gpio_cfg(struct dvobj_priv *d, enum halmac_gpio_func gpio, u8 enable)
5168 {
5169 	struct halmac_adapter *halmac;
5170 	struct halmac_api *api;
5171 	enum halmac_ret_status status;
5172 
5173 
5174 	halmac = dvobj_to_halmac(d);
5175 	api = HALMAC_GET_API(halmac);
5176 
5177 	if (enable) {
5178 		status = api->halmac_pinmux_set_func(halmac, gpio);
5179 		if (status != HALMAC_RET_SUCCESS) {
5180 			RTW_ERR("%s: pinmux set GPIO(%d) fail!(0x%x)\n",
5181 				__FUNCTION__, gpio, status);
5182 			return -1;
5183 		}
5184 	} else {
5185  		status = api->halmac_pinmux_free_func(halmac, gpio);
5186 		if (status != HALMAC_RET_SUCCESS) {
5187 			RTW_ERR("%s: pinmux free GPIO(%d) fail!(0x%x)\n",
5188 				__FUNCTION__, gpio, status);
5189 			return -1;
5190 		}
5191 	}
5192 
5193 	return 0;
5194 }
5195 
5196 /**
5197  * rtw_halmac_bt_wake_cfg() - Configure BT wake host function
5198  * @d:		struct dvobj_priv*
5199  * @enable:	enable or disable BT wake host function
5200  *		0: disable
5201  *		1: enable
5202  *
5203  * Configure pinmux to allow BT to control BT wake host pin.
5204  *
5205  * Return 0 for OK, otherwise fail.
5206  */
rtw_halmac_bt_wake_cfg(struct dvobj_priv * d,u8 enable)5207 int rtw_halmac_bt_wake_cfg(struct dvobj_priv *d, u8 enable)
5208 {
5209 	return _gpio_cfg(d, HALMAC_GPIO_FUNC_BT_HOST_WAKE1, enable);
5210 }
5211 
_gpio_to_func_for_rfe_ctrl(u8 gpio)5212 static enum halmac_gpio_func _gpio_to_func_for_rfe_ctrl(u8 gpio)
5213 {
5214 	enum halmac_gpio_func f = HALMAC_GPIO_FUNC_UNDEFINE;
5215 
5216 
5217 #ifdef CONFIG_RTL8822C
5218 	switch (gpio) {
5219 	case 1:
5220 		f = HALMAC_GPIO_FUNC_ANTSWB;
5221 		break;
5222 	case 2:
5223 		f = HALMAC_GPIO_FUNC_S1_TRSW;
5224 		break;
5225 	case 3:
5226 		f = HALMAC_GPIO_FUNC_S0_TRSW;
5227 		break;
5228 	case 6:
5229 		f = HALMAC_GPIO_FUNC_S0_PAPE;
5230 		break;
5231 	case 7:
5232 		f = HALMAC_GPIO_FUNC_S0_TRSWB;
5233 		break;
5234 	case 13:
5235 		f = HALMAC_GPIO_FUNC_ANTSW;
5236 		break;
5237 	}
5238 #endif /* CONFIG_RTL8822C */
5239 
5240 	return f;
5241 }
5242 
5243 /**
5244  * rtw_halmac_rfe_ctrl_cfg() - Configure RFE control GPIO
5245  * @d:		struct dvobj_priv*
5246  * @gpio:	gpio number
5247  *
5248  * Configure pinmux to enable RFE control GPIO.
5249  *
5250  * Return 0 for OK, otherwise fail.
5251  */
rtw_halmac_rfe_ctrl_cfg(struct dvobj_priv * d,u8 gpio)5252 int rtw_halmac_rfe_ctrl_cfg(struct dvobj_priv *d, u8 gpio)
5253 {
5254 	enum halmac_gpio_func f;
5255 
5256 
5257 	f = _gpio_to_func_for_rfe_ctrl(gpio);
5258 	if (f == HALMAC_GPIO_FUNC_UNDEFINE)
5259 		return -1;
5260 	return _gpio_cfg(d, f, 1);
5261 }
5262 
5263 #ifdef CONFIG_PNO_SUPPORT
5264 /**
5265  * _halmac_scanoffload() - Switch channel by firmware during scanning
5266  * @d:		struct dvobj_priv*
5267  * @enable:	1: enable, 0: disable
5268  * @nlo:	1: nlo mode (no c2h event), 0: normal mode
5269  * @ssid:	ssid of probe request
5270  * @ssid_len:	ssid length
5271  *
5272  * Switch Channel and Send Porbe Request Offloaded by FW
5273  *
5274  * Return 0 for OK, otherwise fail.
5275  */
_halmac_scanoffload(struct dvobj_priv * d,u32 enable,u8 nlo,u8 * ssid,u8 ssid_len)5276 static int _halmac_scanoffload(struct dvobj_priv *d, u32 enable, u8 nlo,
5277 			       u8 *ssid, u8 ssid_len)
5278 {
5279 	struct _ADAPTER *adapter;
5280 	struct halmac_adapter *mac;
5281 	struct halmac_api *api;
5282 	enum halmac_ret_status status;
5283 	struct halmac_ch_info ch_info;
5284 	struct halmac_ch_switch_option cs_option;
5285 	struct mlme_ext_priv *pmlmeext;
5286 	enum halmac_feature_id id_update, id_ch_sw;
5287 	struct halmac_indicator *indicator, *tbl;
5288 
5289 	int err = 0;
5290 	u8 probereq[64];
5291 	u32 len = 0;
5292 	int i = 0;
5293 	struct pno_ssid pnossid;
5294 	struct rf_ctl_t *rfctl = NULL;
5295 	struct _RT_CHANNEL_INFO *ch_set;
5296 
5297 
5298 	tbl = d->hmpriv.indicator;
5299 	adapter = dvobj_get_primary_adapter(d);
5300 	mac = dvobj_to_halmac(d);
5301 	if (!mac)
5302 		return -1;
5303 	api = HALMAC_GET_API(mac);
5304 	id_update = HALMAC_FEATURE_UPDATE_PACKET;
5305 	id_ch_sw = HALMAC_FEATURE_CHANNEL_SWITCH;
5306 	pmlmeext = &(adapter->mlmeextpriv);
5307 	rfctl = adapter_to_rfctl(adapter);
5308 	ch_set = rfctl->channel_set;
5309 
5310 	RTW_INFO("%s: %s scanoffload, mode: %s\n",
5311 		 __FUNCTION__, enable?"Enable":"Disable",
5312 		 nlo?"PNO/NLO":"Normal");
5313 
5314 	if (enable) {
5315 		_rtw_memset(probereq, 0, sizeof(probereq));
5316 
5317 		_rtw_memset(&pnossid, 0, sizeof(pnossid));
5318 		if (ssid) {
5319 			if (ssid_len > sizeof(pnossid.SSID)) {
5320 				RTW_ERR("%s: SSID length(%d) is too long(>%d)!!\n",
5321 					__FUNCTION__, ssid_len, sizeof(pnossid.SSID));
5322 				return -1;
5323 			}
5324 
5325 			pnossid.SSID_len = ssid_len;
5326 			_rtw_memcpy(pnossid.SSID, ssid, ssid_len);
5327 		}
5328 
5329 		rtw_hal_construct_ProbeReq(adapter, probereq, &len, &pnossid);
5330 
5331 		if (!nlo) {
5332 			err = init_halmac_event(d, id_update, NULL, 0);
5333 			if (err)
5334 				return -1;
5335 		}
5336 
5337 		status = api->halmac_update_packet(mac, HALMAC_PACKET_PROBE_REQ,
5338 						   probereq, len);
5339 		if (status != HALMAC_RET_SUCCESS) {
5340 			if (!nlo)
5341 				free_halmac_event(d, id_update);
5342 			RTW_ERR("%s: halmac_update_packet FAIL(%d)!!\n",
5343 				__FUNCTION__, status);
5344 			return -1;
5345 		}
5346 
5347 		if (!nlo) {
5348 			err = wait_halmac_event(d, id_update);
5349 			if (err)
5350 				RTW_ERR("%s: wait update packet FAIL(%d)!!\n",
5351 					__FUNCTION__, err);
5352 		}
5353 
5354 		api->halmac_clear_ch_info(mac);
5355 
5356 		for (i = 0; i < rfctl->max_chan_nums && ch_set[i].ChannelNum != 0; i++) {
5357 			_rtw_memset(&ch_info, 0, sizeof(ch_info));
5358 			ch_info.extra_info = 0;
5359 			ch_info.channel = ch_set[i].ChannelNum;
5360 			ch_info.bw = HALMAC_BW_20;
5361 			ch_info.pri_ch_idx = HALMAC_CH_IDX_1;
5362 			ch_info.action_id = HALMAC_CS_ACTIVE_SCAN;
5363 			ch_info.timeout = 1;
5364 			status = api->halmac_add_ch_info(mac, &ch_info);
5365 			if (status != HALMAC_RET_SUCCESS) {
5366 				RTW_ERR("%s: add_ch_info FAIL(%d)!!\n",
5367 					__FUNCTION__, status);
5368 				return -1;
5369 			}
5370 		}
5371 
5372 		/* set channel switch option */
5373 		_rtw_memset(&cs_option, 0, sizeof(cs_option));
5374 		cs_option.dest_bw = HALMAC_BW_20;
5375 		cs_option.periodic_option = HALMAC_CS_PERIODIC_2_PHASE;
5376 		cs_option.dest_pri_ch_idx = HALMAC_CH_IDX_UNDEFINE;
5377 		cs_option.tsf_low = 0;
5378 		cs_option.switch_en = 1;
5379 		cs_option.dest_ch_en = 1;
5380 		cs_option.absolute_time_en = 0;
5381 		cs_option.dest_ch = 1;
5382 
5383 		cs_option.normal_period = 5;
5384 		cs_option.normal_period_sel = 0;
5385 		cs_option.normal_cycle = 10;
5386 
5387 		cs_option.phase_2_period = 1;
5388 		cs_option.phase_2_period_sel = 1;
5389 
5390 		/* nlo is for wow fw,  1: no c2h response */
5391 		cs_option.nlo_en = nlo;
5392 
5393 		if (!nlo) {
5394 			err = init_halmac_event(d, id_ch_sw, NULL, 0);
5395 			if (err)
5396 				return -1;
5397 		}
5398 
5399 		status = api->halmac_ctrl_ch_switch(mac, &cs_option);
5400 		if (status != HALMAC_RET_SUCCESS) {
5401 			if (!nlo)
5402 				free_halmac_event(d, id_ch_sw);
5403 			RTW_ERR("%s: halmac_ctrl_ch_switch FAIL(%d)!!\n",
5404 				__FUNCTION__, status);
5405 			return -1;
5406 		}
5407 
5408 		if (!nlo) {
5409 			err = wait_halmac_event(d, id_ch_sw);
5410 			if (err)
5411 				RTW_ERR("%s: wait ctrl_ch_switch FAIL(%d)!!\n",
5412 					__FUNCTION__, err);
5413 		}
5414 	} else {
5415 		api->halmac_clear_ch_info(mac);
5416 
5417 		_rtw_memset(&cs_option, 0, sizeof(cs_option));
5418 		cs_option.switch_en = 0;
5419 
5420 		if (!nlo) {
5421 			err = init_halmac_event(d, id_ch_sw, NULL, 0);
5422 			if (err)
5423 				return -1;
5424 		}
5425 
5426 		status = api->halmac_ctrl_ch_switch(mac, &cs_option);
5427 		if (status != HALMAC_RET_SUCCESS) {
5428 			if (!nlo)
5429 				free_halmac_event(d, id_ch_sw);
5430 			RTW_ERR("%s: halmac_ctrl_ch_switch FAIL(%d)!!\n",
5431 				__FUNCTION__, status);
5432 			return -1;
5433 		}
5434 
5435 		if (!nlo) {
5436 			err = wait_halmac_event(d, id_ch_sw);
5437 			if (err)
5438 				RTW_ERR("%s: wait ctrl_ch_switch FAIL(%d)!!\n",
5439 					__FUNCTION__, err);
5440 		}
5441 	}
5442 
5443 	return 0;
5444 }
5445 
5446 /**
5447  * rtw_halmac_pno_scanoffload() - Control firmware scan AP function for PNO
5448  * @d:		struct dvobj_priv*
5449  * @enable:	1: enable, 0: disable
5450  *
5451  * Switch firmware scan AP function for PNO(prefer network offload) or
5452  * NLO(network list offload).
5453  *
5454  * Return 0 for OK, otherwise fail.
5455  */
rtw_halmac_pno_scanoffload(struct dvobj_priv * d,u32 enable)5456 int rtw_halmac_pno_scanoffload(struct dvobj_priv *d, u32 enable)
5457 {
5458 	return _halmac_scanoffload(d, enable, 1, NULL, 0);
5459 }
5460 #endif /* CONFIG_PNO_SUPPORT */
5461 
5462 #ifdef CONFIG_SDIO_HCI
5463 
5464 /**
5465  * rtw_halmac_preinit_sdio_io_indirect() - Enable indirect I/O or not
5466  * @d:		struct dvobj_priv*
5467  * @enable:	true: enable, false: disable
5468  *
5469  * Enable register access using direct I/O or indirect. This function should be
5470  * called before rtw_halmac_init_adapter(), and the life cycle is the same as
5471  * driver until removing driver.
5472  *
5473  * Return 0 for OK, otherwise fail.
5474  */
rtw_halmac_preinit_sdio_io_indirect(struct dvobj_priv * d,bool enable)5475 int rtw_halmac_preinit_sdio_io_indirect(struct dvobj_priv *d, bool enable)
5476 {
5477 	struct halmac_adapter *halmac;
5478 	struct halmacpriv *priv;
5479 
5480 
5481 	halmac = dvobj_to_halmac(d);
5482 	if (halmac) {
5483 		RTW_WARN("%s: illegal operation! "
5484 			 "preinit function only could be called before init!\n",
5485 			 __FUNCTION__);
5486 		return -1;
5487 	}
5488 
5489 	priv = &d->hmpriv;
5490 	priv->sdio_io_indir = (enable ? 1 : 2);
5491 
5492 	return 0;
5493 }
5494 
5495 /*
5496  * Description:
5497  *	Update queue allocated page number to driver
5498  *
5499  * Parameter:
5500  *	d	pointer to struct dvobj_priv of driver
5501  *
5502  * Return:
5503  *	0	Success, "page" is valid.
5504  *	others	Fail, "page" is invalid.
5505  */
rtw_halmac_query_tx_page_num(struct dvobj_priv * d)5506 int rtw_halmac_query_tx_page_num(struct dvobj_priv *d)
5507 {
5508 	PADAPTER adapter;
5509 	struct halmacpriv *hmpriv;
5510 	struct halmac_adapter *halmac;
5511 	struct halmac_api *api;
5512 	struct halmac_rqpn_map rqpn;
5513 	enum halmac_dma_mapping dmaqueue;
5514 	struct halmac_txff_allocation fifosize;
5515 	enum halmac_ret_status status;
5516 	u8 i;
5517 
5518 
5519 	adapter = dvobj_get_primary_adapter(d);
5520 	hmpriv = &d->hmpriv;
5521 	halmac = dvobj_to_halmac(d);
5522 	api = HALMAC_GET_API(halmac);
5523 	_rtw_memset((void *)&rqpn, 0, sizeof(rqpn));
5524 	_rtw_memset((void *)&fifosize, 0, sizeof(fifosize));
5525 
5526 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RQPN_MAPPING, &rqpn);
5527 	if (status != HALMAC_RET_SUCCESS)
5528 		return -1;
5529 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_TXFF_ALLOCATION, &fifosize);
5530 	if (status != HALMAC_RET_SUCCESS)
5531 		return -1;
5532 
5533 	for (i = 0; i < HW_QUEUE_ENTRY; i++) {
5534 		hmpriv->txpage[i] = 0;
5535 
5536 		/* Driver index mapping to HALMAC DMA queue */
5537 		dmaqueue = HALMAC_DMA_MAPPING_UNDEFINE;
5538 		switch (i) {
5539 		case VO_QUEUE_INX:
5540 			dmaqueue = rqpn.dma_map_vo;
5541 			break;
5542 		case VI_QUEUE_INX:
5543 			dmaqueue = rqpn.dma_map_vi;
5544 			break;
5545 		case BE_QUEUE_INX:
5546 			dmaqueue = rqpn.dma_map_be;
5547 			break;
5548 		case BK_QUEUE_INX:
5549 			dmaqueue = rqpn.dma_map_bk;
5550 			break;
5551 		case MGT_QUEUE_INX:
5552 			dmaqueue = rqpn.dma_map_mg;
5553 			break;
5554 		case HIGH_QUEUE_INX:
5555 			dmaqueue = rqpn.dma_map_hi;
5556 			break;
5557 		case BCN_QUEUE_INX:
5558 		case TXCMD_QUEUE_INX:
5559 			/* Unlimited */
5560 			hmpriv->txpage[i] = 0xFFFF;
5561 			continue;
5562 		}
5563 
5564 		switch (dmaqueue) {
5565 		case HALMAC_DMA_MAPPING_EXTRA:
5566 			hmpriv->txpage[i] = fifosize.extra_queue_pg_num;
5567 			break;
5568 		case HALMAC_DMA_MAPPING_LOW:
5569 			hmpriv->txpage[i] = fifosize.low_queue_pg_num;
5570 			break;
5571 		case HALMAC_DMA_MAPPING_NORMAL:
5572 			hmpriv->txpage[i] = fifosize.normal_queue_pg_num;
5573 			break;
5574 		case HALMAC_DMA_MAPPING_HIGH:
5575 			hmpriv->txpage[i] = fifosize.high_queue_pg_num;
5576 			break;
5577 		case HALMAC_DMA_MAPPING_UNDEFINE:
5578 			break;
5579 		}
5580 		hmpriv->txpage[i] += fifosize.pub_queue_pg_num;
5581 	}
5582 
5583 	return 0;
5584 }
5585 
5586 /*
5587  * Description:
5588  *	Get specific queue allocated page number
5589  *
5590  * Parameter:
5591  *	d	pointer to struct dvobj_priv of driver
5592  *	queue	target queue to query, VO/VI/BE/BK/.../TXCMD_QUEUE_INX
5593  *	page	return allocated page number
5594  *
5595  * Return:
5596  *	0	Success, "page" is valid.
5597  *	others	Fail, "page" is invalid.
5598  */
rtw_halmac_get_tx_queue_page_num(struct dvobj_priv * d,u8 queue,u32 * page)5599 int rtw_halmac_get_tx_queue_page_num(struct dvobj_priv *d, u8 queue, u32 *page)
5600 {
5601 	*page = 0;
5602 	if (queue < HW_QUEUE_ENTRY)
5603 		*page = d->hmpriv.txpage[queue];
5604 
5605 	return 0;
5606 }
5607 
5608 /*
5609  * Return:
5610  *	address for SDIO command
5611  */
rtw_halmac_sdio_get_tx_addr(struct dvobj_priv * d,u8 * desc,u32 size)5612 u32 rtw_halmac_sdio_get_tx_addr(struct dvobj_priv *d, u8 *desc, u32 size)
5613 {
5614 	struct halmac_adapter *mac;
5615 	struct halmac_api *api;
5616 	enum halmac_ret_status status;
5617 	u32 addr;
5618 
5619 
5620 	mac = dvobj_to_halmac(d);
5621 	api = HALMAC_GET_API(mac);
5622 
5623 	status = api->halmac_get_sdio_tx_addr(mac, desc, size, &addr);
5624 	if (HALMAC_RET_SUCCESS != status)
5625 		return 0;
5626 
5627 	return addr;
5628 }
5629 
rtw_halmac_sdio_tx_allowed(struct dvobj_priv * d,u8 * buf,u32 size)5630 int rtw_halmac_sdio_tx_allowed(struct dvobj_priv *d, u8 *buf, u32 size)
5631 {
5632 	struct halmac_adapter *mac;
5633 	struct halmac_api *api;
5634 	enum halmac_ret_status status;
5635 
5636 
5637 	mac = dvobj_to_halmac(d);
5638 	api = HALMAC_GET_API(mac);
5639 
5640 	status = api->halmac_tx_allowed_sdio(mac, buf, size);
5641 	if (HALMAC_RET_SUCCESS != status)
5642 		return -1;
5643 
5644 	return 0;
5645 }
5646 
rtw_halmac_sdio_get_rx_addr(struct dvobj_priv * d,u8 * seq)5647 u32 rtw_halmac_sdio_get_rx_addr(struct dvobj_priv *d, u8 *seq)
5648 {
5649 	u8 id;
5650 
5651 #define RTW_SDIO_ADDR_RX_RX0FF_PRFIX	0x0E000
5652 #define RTW_SDIO_ADDR_RX_RX0FF_GEN(a)	(RTW_SDIO_ADDR_RX_RX0FF_PRFIX|(a&0x3))
5653 
5654 	id = *seq;
5655 	(*seq)++;
5656 	return RTW_SDIO_ADDR_RX_RX0FF_GEN(id);
5657 }
5658 
rtw_halmac_sdio_set_tx_format(struct dvobj_priv * d,enum halmac_sdio_tx_format format)5659 int rtw_halmac_sdio_set_tx_format(struct dvobj_priv *d, enum halmac_sdio_tx_format format)
5660 {
5661 	struct halmac_adapter *mac;
5662 	struct halmac_api *api;
5663 	enum halmac_ret_status status;
5664 
5665 	mac = dvobj_to_halmac(d);
5666 	api = HALMAC_GET_API(mac);
5667 
5668 	status = api->halmac_set_hw_value(mac, HALMAC_HW_SDIO_TX_FORMAT, &format);
5669 	if (HALMAC_RET_SUCCESS != status)
5670 		return -1;
5671 
5672 	return 0;
5673 }
5674 #endif /* CONFIG_SDIO_HCI */
5675 
5676 #ifdef CONFIG_USB_HCI
rtw_halmac_usb_get_bulkout_id(struct dvobj_priv * d,u8 * buf,u32 size)5677 u8 rtw_halmac_usb_get_bulkout_id(struct dvobj_priv *d, u8 *buf, u32 size)
5678 {
5679 	struct halmac_adapter *mac;
5680 	struct halmac_api *api;
5681 	enum halmac_ret_status status;
5682 	u8 bulkout_id;
5683 
5684 
5685 	mac = dvobj_to_halmac(d);
5686 	api = HALMAC_GET_API(mac);
5687 
5688 	status = api->halmac_get_usb_bulkout_id(mac, buf, size, &bulkout_id);
5689 	if (HALMAC_RET_SUCCESS != status)
5690 		return 0;
5691 
5692 	return bulkout_id;
5693 }
5694 
5695 /**
5696  * rtw_halmac_usb_get_txagg_desc_num() - MAX descriptor number in one bulk for TX
5697  * @d:		struct dvobj_priv*
5698  * @size:	TX FIFO size, unit is byte.
5699  *
5700  * Get MAX descriptor number in one bulk out from HALMAC.
5701  *
5702  * Return 0 for OK, otherwise fail.
5703  */
rtw_halmac_usb_get_txagg_desc_num(struct dvobj_priv * d,u8 * num)5704 int rtw_halmac_usb_get_txagg_desc_num(struct dvobj_priv *d, u8 *num)
5705 {
5706 	struct halmac_adapter *halmac;
5707 	struct halmac_api *api;
5708 	enum halmac_ret_status status;
5709 	u8 val = 0;
5710 
5711 
5712 	halmac = dvobj_to_halmac(d);
5713 	api = HALMAC_GET_API(halmac);
5714 
5715 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_USB_TXAGG_DESC_NUM, &val);
5716 	if (status != HALMAC_RET_SUCCESS)
5717 		return -1;
5718 
5719 	*num = val;
5720 
5721 	return 0;
5722 }
5723 
_usb_mode_drv2halmac(enum RTW_USB_SPEED usb_mode)5724 static inline enum halmac_usb_mode _usb_mode_drv2halmac(enum RTW_USB_SPEED usb_mode)
5725 {
5726 	enum halmac_usb_mode halmac_usb_mode = HALMAC_USB_MODE_U2;
5727 
5728 	switch (usb_mode) {
5729 	case RTW_USB_SPEED_2:
5730 		halmac_usb_mode = HALMAC_USB_MODE_U2;
5731 		break;
5732 	case RTW_USB_SPEED_3:
5733 		halmac_usb_mode = HALMAC_USB_MODE_U3;
5734 		break;
5735 	default:
5736 		halmac_usb_mode = HALMAC_USB_MODE_U2;
5737 		break;
5738 	}
5739 
5740 	return halmac_usb_mode;
5741 }
5742 
rtw_halmac_switch_usb_mode(struct dvobj_priv * d,enum RTW_USB_SPEED usb_mode)5743 u8 rtw_halmac_switch_usb_mode(struct dvobj_priv *d, enum RTW_USB_SPEED usb_mode)
5744 {
5745 	PADAPTER adapter;
5746 	struct halmac_adapter *mac;
5747 	struct halmac_api *api;
5748 	enum halmac_ret_status status;
5749 	enum halmac_usb_mode halmac_usb_mode;
5750 
5751 	adapter = dvobj_get_primary_adapter(d);
5752 	mac = dvobj_to_halmac(d);
5753 	api = HALMAC_GET_API(mac);
5754 	halmac_usb_mode = _usb_mode_drv2halmac(usb_mode);
5755 	status = api->halmac_set_hw_value(mac, HALMAC_HW_USB_MODE, (void *)&halmac_usb_mode);
5756 
5757 	if (HALMAC_RET_SUCCESS != status)
5758 		return _FAIL;
5759 
5760 	return _SUCCESS;
5761 }
5762 #endif /* CONFIG_USB_HCI */
5763 
5764 #ifdef CONFIG_BEAMFORMING
5765 #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)5766 int rtw_halmac_bf_add_mu_bfer(struct dvobj_priv *d, u16 paid, u16 csi_para,
5767 		u16 my_aid, enum halmac_csi_seg_len sel, u8 *addr)
5768 {
5769 	struct halmac_adapter *mac;
5770 	struct halmac_api *api;
5771 	enum halmac_ret_status status;
5772 	struct halmac_mu_bfer_init_para param;
5773 
5774 
5775 	mac = dvobj_to_halmac(d);
5776 	api = HALMAC_GET_API(mac);
5777 
5778 	_rtw_memset(&param, 0, sizeof(param));
5779 	param.paid = paid;
5780 	param.csi_para = csi_para;
5781 	param.my_aid = my_aid;
5782 	param.csi_length_sel = sel;
5783 	_rtw_memcpy(param.bfer_address.addr, addr, 6);
5784 
5785 	status = api->halmac_mu_bfer_entry_init(mac, &param);
5786 	if (status != HALMAC_RET_SUCCESS)
5787 		return -1;
5788 
5789 	return 0;
5790 }
5791 
rtw_halmac_bf_del_mu_bfer(struct dvobj_priv * d)5792 int rtw_halmac_bf_del_mu_bfer(struct dvobj_priv *d)
5793 {
5794 	struct halmac_adapter *mac;
5795 	struct halmac_api *api;
5796 	enum halmac_ret_status status;
5797 
5798 
5799 	mac = dvobj_to_halmac(d);
5800 	api = HALMAC_GET_API(mac);
5801 
5802 	status = api->halmac_mu_bfer_entry_del(mac);
5803 	if (status != HALMAC_RET_SUCCESS)
5804 		return -1;
5805 
5806 	return 0;
5807 }
5808 
5809 
rtw_halmac_bf_cfg_sounding(struct dvobj_priv * d,enum halmac_snd_role role,enum halmac_data_rate rate)5810 int rtw_halmac_bf_cfg_sounding(struct dvobj_priv *d,
5811 		enum halmac_snd_role role, enum halmac_data_rate rate)
5812 {
5813 	struct halmac_adapter *mac;
5814 	struct halmac_api *api;
5815 	enum halmac_ret_status status;
5816 
5817 
5818 	mac = dvobj_to_halmac(d);
5819 	api = HALMAC_GET_API(mac);
5820 
5821 	status = api->halmac_cfg_sounding(mac, role, rate);
5822 	if (status != HALMAC_RET_SUCCESS)
5823 		return -1;
5824 
5825 	return 0;
5826 }
5827 
rtw_halmac_bf_del_sounding(struct dvobj_priv * d,enum halmac_snd_role role)5828 int rtw_halmac_bf_del_sounding(struct dvobj_priv *d,
5829 		enum halmac_snd_role role)
5830 {
5831 	struct halmac_adapter *mac;
5832 	struct halmac_api *api;
5833 	enum halmac_ret_status status;
5834 
5835 
5836 	mac = dvobj_to_halmac(d);
5837 	api = HALMAC_GET_API(mac);
5838 
5839 	status = api->halmac_del_sounding(mac, role);
5840 	if (status != HALMAC_RET_SUCCESS)
5841 		return -1;
5842 
5843 	return 0;
5844 }
5845 
5846 /**
5847  * rtw_halmac_bf_cfg_csi_rate() - Config data rate for CSI report frame by RSSI
5848  * @d:		struct dvobj_priv*
5849  * @rssi:	RSSI vlaue, unit is percentage (0~100).
5850  * @current_rate:	Current CSI frame rate
5851  *			Valid value example
5852  *			0	CCK 1M
5853  *			3	CCK 11M
5854  *			4	OFDM 6M
5855  *			and so on
5856  * @fixrate_en:	Enable to fix CSI frame in VHT rate, otherwise legacy OFDM rate.
5857  *		The value "0" for disable, otheriwse enable.
5858  * @new_rate:	Return new data rate, and value range is the same as
5859  *		current_rate
5860  * @bmp_ofdm54: Return to suggest enabling OFDM 54M for CSI report frame or not,
5861  *		The valid values and meanings are:
5862  *		0x00	disable
5863  *		0x01	enable
5864  *		0xFF	Keep current setting
5865  *
5866  * According RSSI to config data rate for CSI report frame of Beamforming.
5867  *
5868  * Return 0 for OK, otherwise fail.
5869  */
rtw_halmac_bf_cfg_csi_rate(struct dvobj_priv * d,u8 rssi,u8 current_rate,u8 fixrate_en,u8 * new_rate,u8 * bmp_ofdm54)5870 int rtw_halmac_bf_cfg_csi_rate(struct dvobj_priv *d, u8 rssi,
5871 			       u8 current_rate, u8 fixrate_en, u8 *new_rate,
5872 			       u8 *bmp_ofdm54)
5873 {
5874 	struct halmac_adapter *mac;
5875 	struct halmac_api *api;
5876 	enum halmac_ret_status status;
5877 
5878 
5879 	mac = dvobj_to_halmac(d);
5880 	api = HALMAC_GET_API(mac);
5881 
5882 	status = api->halmac_cfg_csi_rate(mac,
5883 			rssi, current_rate, fixrate_en, new_rate,
5884 			bmp_ofdm54);
5885 	if (status != HALMAC_RET_SUCCESS)
5886 		return -1;
5887 
5888 	return 0;
5889 }
5890 
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)5891 int rtw_halmac_bf_cfg_mu_mimo(struct dvobj_priv *d, enum halmac_snd_role role,
5892 		u8 *sounding_sts, u16 grouping_bitmap, u8 mu_tx_en,
5893 		u32 *given_gid_tab, u32 *given_user_pos)
5894 {
5895 	struct halmac_adapter *mac;
5896 	struct halmac_api *api;
5897 	enum halmac_ret_status status;
5898 	struct halmac_cfg_mumimo_para param;
5899 
5900 
5901 	mac = dvobj_to_halmac(d);
5902 	api = HALMAC_GET_API(mac);
5903 
5904 	_rtw_memset(&param, 0, sizeof(param));
5905 
5906 	param.role = role;
5907 	param.grouping_bitmap = grouping_bitmap;
5908 	param.mu_tx_en = mu_tx_en;
5909 
5910 	if (sounding_sts)
5911 		_rtw_memcpy(param.sounding_sts, sounding_sts, 6);
5912 
5913 	if (given_gid_tab)
5914 		_rtw_memcpy(param.given_gid_tab, given_gid_tab, 8);
5915 
5916 	if (given_user_pos)
5917 		_rtw_memcpy(param.given_user_pos, given_user_pos, 16);
5918 
5919 	status = api->halmac_cfg_mumimo(mac, &param);
5920 	if (status != HALMAC_RET_SUCCESS)
5921 		return -1;
5922 
5923 	return 0;
5924 }
5925 
5926 #endif /* RTW_BEAMFORMING_VERSION_2 */
5927 #endif /* CONFIG_BEAMFORMING */
5928