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