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