xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/rtl8822be/hal/hal_halmac.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2015 - 2016 Realtek Corporation. All rights reserved.
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  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 #define _HAL_HALMAC_C_
21 
22 #include <drv_types.h>		/* PADAPTER, struct dvobj_priv, SDIO_ERR_VAL8 and etc. */
23 #include <hal_data.h>		/* efuse, PHAL_DATA_TYPE and etc. */
24 #include "halmac/halmac_api.h"	/* HALMAC_FW_SIZE_MAX_88XX and etc. */
25 #include "hal_halmac.h"		/* dvobj_to_halmac() and ect. */
26 
27 #define DEFAULT_INDICATOR_TIMELMT	1000	/* ms */
28 #define FIRMWARE_MAX_SIZE		HALMAC_FW_SIZE_MAX_88XX
29 
30 /*
31  * Driver API for HALMAC operations
32  */
33 
34 #ifdef CONFIG_SDIO_HCI
35 #include <rtw_sdio.h>
_halmac_sdio_cmd52_read(void * p,u32 offset)36 static u8 _halmac_sdio_cmd52_read(void *p, u32 offset)
37 {
38 	struct dvobj_priv *d;
39 	u8 val;
40 	u8 ret;
41 
42 
43 	d = (struct dvobj_priv *)p;
44 	ret = rtw_sdio_read_cmd52(d, offset, &val, 1);
45 	if (_FAIL == ret) {
46 		RTW_INFO("%s: [ERROR] I/O FAIL!\n", __FUNCTION__);
47 		return SDIO_ERR_VAL8;
48 	}
49 
50 	return val;
51 }
52 
_halmac_sdio_cmd52_write(void * p,u32 offset,u8 val)53 static void _halmac_sdio_cmd52_write(void *p, u32 offset, u8 val)
54 {
55 	struct dvobj_priv *d;
56 	u8 ret;
57 
58 
59 	d = (struct dvobj_priv *)p;
60 	ret = rtw_sdio_write_cmd52(d, offset, &val, 1);
61 	if (_FAIL == ret)
62 		RTW_INFO("%s: [ERROR] I/O FAIL!\n", __FUNCTION__);
63 }
64 
_halmac_sdio_reg_read_8(void * p,u32 offset)65 static u8 _halmac_sdio_reg_read_8(void *p, u32 offset)
66 {
67 	struct dvobj_priv *d;
68 	u8 *pbuf;
69 	u8 val;
70 	int err;
71 
72 
73 	d = (struct dvobj_priv *)p;
74 	val = SDIO_ERR_VAL8;
75 	pbuf = rtw_zmalloc(1);
76 	if (!pbuf)
77 		return val;
78 
79 	err = d->intf_ops->read(d, offset, pbuf, 1, 0);
80 	if (err) {
81 		RTW_INFO("%s: [ERROR] I/O FAIL!\n", __FUNCTION__);
82 		goto exit;
83 	}
84 
85 	val = *pbuf;
86 
87 exit:
88 	rtw_mfree(pbuf, 1);
89 
90 	return val;
91 }
92 
_halmac_sdio_reg_read_16(void * p,u32 offset)93 static u16 _halmac_sdio_reg_read_16(void *p, u32 offset)
94 {
95 	struct dvobj_priv *d;
96 	u8 *pbuf;
97 	u16 val;
98 	int err;
99 
100 
101 	d = (struct dvobj_priv *)p;
102 	val = SDIO_ERR_VAL16;
103 	pbuf = rtw_zmalloc(2);
104 	if (!pbuf)
105 		return val;
106 
107 	err = d->intf_ops->read(d, offset, pbuf, 2, 0);
108 	if (err) {
109 		RTW_INFO("%s: [ERROR] I/O FAIL!\n", __FUNCTION__);
110 		goto exit;
111 	}
112 
113 	val = le16_to_cpu(*(u16 *)pbuf);
114 
115 exit:
116 	rtw_mfree(pbuf, 2);
117 
118 	return val;
119 }
120 
_halmac_sdio_reg_read_32(void * p,u32 offset)121 static u32 _halmac_sdio_reg_read_32(void *p, u32 offset)
122 {
123 	struct dvobj_priv *d;
124 	u8 *pbuf;
125 	u32 val;
126 	int err;
127 
128 
129 	d = (struct dvobj_priv *)p;
130 	val = SDIO_ERR_VAL32;
131 	pbuf = rtw_zmalloc(4);
132 	if (!pbuf)
133 		return val;
134 
135 	err = d->intf_ops->read(d, offset, pbuf, 4, 0);
136 	if (err) {
137 		RTW_INFO("%s: [ERROR] I/O FAIL!\n", __FUNCTION__);
138 		goto exit;
139 	}
140 
141 	val = le32_to_cpu(*(u32 *)pbuf);
142 
143 exit:
144 	rtw_mfree(pbuf, 4);
145 
146 	return val;
147 }
148 
_halmac_sdio_reg_write_8(void * p,u32 offset,u8 val)149 static void _halmac_sdio_reg_write_8(void *p, u32 offset, u8 val)
150 {
151 	struct dvobj_priv *d;
152 	u8 *pbuf;
153 	int err;
154 
155 
156 	d = (struct dvobj_priv *)p;
157 	pbuf = rtw_zmalloc(1);
158 	if (!pbuf)
159 		return;
160 	_rtw_memcpy(pbuf, &val, 1);
161 
162 	err = d->intf_ops->write(d, offset, pbuf, 1, 0);
163 	if (err)
164 		RTW_INFO("%s: [ERROR] I/O FAIL!\n", __FUNCTION__);
165 
166 	rtw_mfree(pbuf, 1);
167 }
168 
_halmac_sdio_reg_write_16(void * p,u32 offset,u16 val)169 static void _halmac_sdio_reg_write_16(void *p, u32 offset, u16 val)
170 {
171 	struct dvobj_priv *d;
172 	u8 *pbuf;
173 	int err;
174 
175 
176 	d = (struct dvobj_priv *)p;
177 	val = cpu_to_le16(val);
178 	pbuf = rtw_zmalloc(2);
179 	if (!pbuf)
180 		return;
181 	_rtw_memcpy(pbuf, &val, 2);
182 
183 	err = d->intf_ops->write(d, offset, pbuf, 2, 0);
184 	if (err)
185 		RTW_INFO("%s: [ERROR] I/O FAIL!\n", __FUNCTION__);
186 
187 	rtw_mfree(pbuf, 2);
188 }
189 
_halmac_sdio_reg_write_32(void * p,u32 offset,u32 val)190 static void _halmac_sdio_reg_write_32(void *p, u32 offset, u32 val)
191 {
192 	struct dvobj_priv *d;
193 	u8 *pbuf;
194 	int err;
195 
196 
197 	d = (struct dvobj_priv *)p;
198 	val = cpu_to_le32(val);
199 	pbuf = rtw_zmalloc(4);
200 	if (!pbuf)
201 		return;
202 	_rtw_memcpy(pbuf, &val, 4);
203 
204 	err = d->intf_ops->write(d, offset, pbuf, 4, 0);
205 	if (err)
206 		RTW_INFO("%s: [ERROR] I/O FAIL!\n", __FUNCTION__);
207 
208 	rtw_mfree(pbuf, 4);
209 }
210 
211 #else /* !CONFIG_SDIO_HCI */
212 
_halmac_reg_read_8(void * p,u32 offset)213 static u8 _halmac_reg_read_8(void *p, u32 offset)
214 {
215 	struct dvobj_priv *d;
216 	PADAPTER adapter;
217 
218 
219 	d = (struct dvobj_priv *)p;
220 	adapter = d->padapters[IFACE_ID0];
221 
222 	return rtw_read8(adapter, offset);
223 }
224 
_halmac_reg_read_16(void * p,u32 offset)225 static u16 _halmac_reg_read_16(void *p, u32 offset)
226 {
227 	struct dvobj_priv *d;
228 	PADAPTER adapter;
229 
230 
231 	d = (struct dvobj_priv *)p;
232 	adapter = d->padapters[IFACE_ID0];
233 
234 	return rtw_read16(adapter, offset);
235 }
236 
_halmac_reg_read_32(void * p,u32 offset)237 static u32 _halmac_reg_read_32(void *p, u32 offset)
238 {
239 	struct dvobj_priv *d;
240 	PADAPTER adapter;
241 
242 
243 	d = (struct dvobj_priv *)p;
244 	adapter = d->padapters[IFACE_ID0];
245 
246 	return rtw_read32(adapter, offset);
247 }
248 
_halmac_reg_write_8(void * p,u32 offset,u8 val)249 static void _halmac_reg_write_8(void *p, u32 offset, u8 val)
250 {
251 	struct dvobj_priv *d;
252 	PADAPTER adapter;
253 	int err;
254 
255 
256 	d = (struct dvobj_priv *)p;
257 	adapter = d->padapters[IFACE_ID0];
258 
259 	err = rtw_write8(adapter, offset, val);
260 	if (err == _FAIL)
261 		RTW_INFO("%s: [ERROR] I/O FAIL!\n", __FUNCTION__);
262 }
263 
_halmac_reg_write_16(void * p,u32 offset,u16 val)264 static void _halmac_reg_write_16(void *p, u32 offset, u16 val)
265 {
266 	struct dvobj_priv *d;
267 	PADAPTER adapter;
268 	int err;
269 
270 
271 	d = (struct dvobj_priv *)p;
272 	adapter = d->padapters[IFACE_ID0];
273 
274 	err = rtw_write16(adapter, offset, val);
275 	if (err == _FAIL)
276 		RTW_INFO("%s: [ERROR] I/O FAIL!\n", __FUNCTION__);
277 }
278 
_halmac_reg_write_32(void * p,u32 offset,u32 val)279 static void _halmac_reg_write_32(void *p, u32 offset, u32 val)
280 {
281 	struct dvobj_priv *d;
282 	PADAPTER adapter;
283 	int err;
284 
285 
286 	d = (struct dvobj_priv *)p;
287 	adapter = d->padapters[IFACE_ID0];
288 
289 	err = rtw_write32(adapter, offset, val);
290 	if (err == _FAIL)
291 		RTW_INFO("%s: [ERROR] I/O FAIL!\n", __FUNCTION__);
292 }
293 #endif /* !CONFIG_SDIO_HCI */
294 
_halmac_mfree(void * p,void * buffer,u32 size)295 static u8 _halmac_mfree(void *p, void *buffer, u32 size)
296 {
297 	rtw_mfree(buffer, size);
298 	return _TRUE;
299 }
300 
_halmac_malloc(void * p,u32 size)301 static void *_halmac_malloc(void *p, u32 size)
302 {
303 	return rtw_zmalloc(size);
304 }
305 
_halmac_memcpy(void * p,void * dest,void * src,u32 size)306 static u8 _halmac_memcpy(void *p, void *dest, void *src, u32 size)
307 {
308 	_rtw_memcpy(dest, src, size);
309 	return _TRUE;
310 }
311 
_halmac_memset(void * p,void * addr,u8 value,u32 size)312 static u8 _halmac_memset(void *p, void *addr, u8 value, u32 size)
313 {
314 	_rtw_memset(addr, value, size);
315 	return _TRUE;
316 }
317 
_halmac_udelay(void * p,u32 us)318 static void _halmac_udelay(void *p, u32 us)
319 {
320 	rtw_udelay_os(us);
321 }
322 
_halmac_mutex_init(void * p,HALMAC_MUTEX * pMutex)323 static u8 _halmac_mutex_init(void *p, HALMAC_MUTEX *pMutex)
324 {
325 	_rtw_mutex_init(pMutex);
326 	return _TRUE;
327 }
328 
_halmac_mutex_deinit(void * p,HALMAC_MUTEX * pMutex)329 static u8 _halmac_mutex_deinit(void *p, HALMAC_MUTEX *pMutex)
330 {
331 	_rtw_mutex_free(pMutex);
332 	return _TRUE;
333 }
334 
_halmac_mutex_lock(void * p,HALMAC_MUTEX * pMutex)335 static u8 _halmac_mutex_lock(void *p, HALMAC_MUTEX *pMutex)
336 {
337 	int err;
338 
339 	err = _enter_critical_mutex(pMutex, NULL);
340 	if (err)
341 		return _FALSE;
342 
343 	return _TRUE;
344 }
345 
_halmac_mutex_unlock(void * p,HALMAC_MUTEX * pMutex)346 static u8 _halmac_mutex_unlock(void *p, HALMAC_MUTEX *pMutex)
347 {
348 	_exit_critical_mutex(pMutex, NULL);
349 	return _TRUE;
350 }
351 
_halmac_msg_print(void * p,u32 msg_type,u8 msg_level,s8 * fmt,...)352 static u8 _halmac_msg_print(void *p, u32 msg_type, u8 msg_level, s8 *fmt, ...)
353 {
354 #define MSG_LEN		100
355 #define MSG_PREFIX	"[HALMAC]"
356 	va_list args;
357 	u8 str[MSG_LEN] = {0};
358 	u32 type;
359 	u8 level;
360 
361 
362 	str[0] = '\n';
363 	type = 0xFFFFFFFF;
364 	if (rtw_drv_log_level <= _DRV_ERR_)
365 		level = HALMAC_DBG_ERR;
366 	else if (rtw_drv_log_level <= _DRV_INFO_)
367 		level = HALMAC_DBG_WARN;
368 	else
369 		level = HALMAC_DBG_TRACE;
370 
371 	if (!(type & BIT(msg_type)))
372 		return _TRUE;
373 	if (level < msg_level)
374 		return _TRUE;
375 
376 	va_start(args, fmt);
377 	vsnprintf(str, MSG_LEN, fmt, args);
378 	va_end(args);
379 
380 	if (msg_level <= HALMAC_DBG_ERR)
381 		RTW_ERR(MSG_PREFIX "%s", str);
382 	else if (msg_level <= HALMAC_DBG_WARN)
383 		RTW_WARN(MSG_PREFIX "%s", str);
384 	else
385 		RTW_DBG(MSG_PREFIX "%s", str);
386 
387 	return _TRUE;
388 }
389 
390 const char *const RTW_HALMAC_FEATURE_NAME[] = {
391 	"HALMAC_FEATURE_CFG_PARA",
392 	"HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE",
393 	"HALMAC_FEATURE_DUMP_LOGICAL_EFUSE",
394 	"HALMAC_FEATURE_UPDATE_PACKET",
395 	"HALMAC_FEATURE_UPDATE_DATAPACK",
396 	"HALMAC_FEATURE_RUN_DATAPACK",
397 	"HALMAC_FEATURE_CHANNEL_SWITCH",
398 	"HALMAC_FEATURE_IQK",
399 	"HALMAC_FEATURE_POWER_TRACKING",
400 	"HALMAC_FEATURE_PSD",
401 	"HALMAC_FEATURE_ALL"
402 };
403 
is_valid_id_status(HALMAC_FEATURE_ID id,HALMAC_CMD_PROCESS_STATUS status)404 static inline u8 is_valid_id_status(HALMAC_FEATURE_ID id, HALMAC_CMD_PROCESS_STATUS status)
405 {
406 	switch (id) {
407 	case HALMAC_FEATURE_CFG_PARA:
408 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
409 		break;
410 	case HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE:
411 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
412 		if (HALMAC_CMD_PROCESS_DONE != status) {
413 			RTW_INFO("%s: <WARN> id(%d) unspecified status(%d)!\n",
414 				 __FUNCTION__, id, status);
415 		}
416 		break;
417 	case HALMAC_FEATURE_DUMP_LOGICAL_EFUSE:
418 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
419 		if (HALMAC_CMD_PROCESS_DONE != status) {
420 			RTW_INFO("%s: <WARN> id(%d) unspecified status(%d)!\n",
421 				 __FUNCTION__, id, status);
422 		}
423 		break;
424 	case HALMAC_FEATURE_UPDATE_PACKET:
425 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
426 		break;
427 	case HALMAC_FEATURE_UPDATE_DATAPACK:
428 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
429 		break;
430 	case HALMAC_FEATURE_RUN_DATAPACK:
431 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
432 		break;
433 	case HALMAC_FEATURE_CHANNEL_SWITCH:
434 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
435 		break;
436 	case HALMAC_FEATURE_IQK:
437 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
438 		break;
439 	case HALMAC_FEATURE_POWER_TRACKING:
440 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
441 		break;
442 	case HALMAC_FEATURE_PSD:
443 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
444 		break;
445 	case HALMAC_FEATURE_ALL:
446 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
447 		break;
448 	default:
449 		RTW_INFO("%s: unknown feature id(%d)\n", __FUNCTION__, id);
450 		return _FALSE;
451 	}
452 
453 	return _TRUE;
454 }
455 
init_halmac_event_with_waittime(struct dvobj_priv * d,HALMAC_FEATURE_ID id,u8 * buf,u32 size,u32 time)456 static int init_halmac_event_with_waittime(struct dvobj_priv *d, HALMAC_FEATURE_ID id, u8 *buf, u32 size, u32 time)
457 {
458 	struct submit_ctx *sctx;
459 
460 
461 	if (!d->hmpriv.indicator[id].sctx) {
462 		sctx = (struct submit_ctx *)rtw_zmalloc(sizeof(*sctx));
463 		if (!sctx)
464 			return -1;
465 	} else {
466 		RTW_INFO("%s: <WARN> id(%d) sctx is not NULL!!\n", __FUNCTION__, id);
467 		sctx = d->hmpriv.indicator[id].sctx;
468 		d->hmpriv.indicator[id].sctx = NULL;
469 	}
470 
471 	rtw_sctx_init(sctx, time);
472 	d->hmpriv.indicator[id].buffer = buf;
473 	d->hmpriv.indicator[id].buf_size = size;
474 	d->hmpriv.indicator[id].ret_size = 0;
475 	d->hmpriv.indicator[id].status = 0;
476 	/* fill sctx at least to sure other variables are all ready! */
477 	d->hmpriv.indicator[id].sctx = sctx;
478 
479 	return 0;
480 }
481 
init_halmac_event(struct dvobj_priv * d,HALMAC_FEATURE_ID id,u8 * buf,u32 size)482 static inline int init_halmac_event(struct dvobj_priv *d, HALMAC_FEATURE_ID id, u8 *buf, u32 size)
483 {
484 	return init_halmac_event_with_waittime(d, id, buf, size, DEFAULT_INDICATOR_TIMELMT);
485 }
486 
free_halmac_event(struct dvobj_priv * d,HALMAC_FEATURE_ID id)487 static void free_halmac_event(struct dvobj_priv *d, HALMAC_FEATURE_ID id)
488 {
489 	struct submit_ctx *sctx;
490 
491 
492 	if (!d->hmpriv.indicator[id].sctx)
493 		return;
494 
495 	sctx = d->hmpriv.indicator[id].sctx;
496 	d->hmpriv.indicator[id].sctx = NULL;
497 	rtw_mfree((u8 *)sctx, sizeof(*sctx));
498 }
499 
wait_halmac_event(struct dvobj_priv * d,HALMAC_FEATURE_ID id)500 static int wait_halmac_event(struct dvobj_priv *d, HALMAC_FEATURE_ID id)
501 {
502 	struct submit_ctx *sctx;
503 	int ret;
504 
505 
506 	sctx = d->hmpriv.indicator[id].sctx;
507 	if (!sctx)
508 		return -1;
509 
510 	ret = rtw_sctx_wait(sctx, RTW_HALMAC_FEATURE_NAME[id]);
511 	free_halmac_event(d, id);
512 	if (_SUCCESS == ret)
513 		return 0;
514 
515 	return -1;
516 }
517 
518 /*
519  * Return:
520  *	Always return _TRUE, HALMAC don't care the return value.
521  */
_halmac_event_indication(void * p,HALMAC_FEATURE_ID feature_id,HALMAC_CMD_PROCESS_STATUS process_status,u8 * buf,u32 size)522 static u8 _halmac_event_indication(void *p, HALMAC_FEATURE_ID feature_id, HALMAC_CMD_PROCESS_STATUS process_status, u8 *buf, u32 size)
523 {
524 	struct dvobj_priv *d;
525 	PADAPTER adapter;
526 	PHAL_DATA_TYPE hal;
527 	struct halmac_indicator *tbl, *indicator;
528 	struct submit_ctx *sctx;
529 	u32 cpsz;
530 	u8 ret;
531 
532 
533 	d = (struct dvobj_priv *)p;
534 	adapter = d->padapters[IFACE_ID0];
535 	hal = GET_HAL_DATA(adapter);
536 	tbl = d->hmpriv.indicator;
537 
538 	ret = is_valid_id_status(feature_id, process_status);
539 	if (_FALSE == ret)
540 		goto exit;
541 
542 	indicator = &tbl[feature_id];
543 	indicator->status = process_status;
544 	indicator->ret_size = size;
545 	if (!indicator->sctx) {
546 		RTW_INFO("%s: No feature id(%d) waiting!!\n", __FUNCTION__, feature_id);
547 		goto exit;
548 	}
549 	sctx = indicator->sctx;
550 
551 	if (HALMAC_CMD_PROCESS_ERROR == process_status) {
552 		RTW_INFO("%s: Something wrong id(%d)!!\n", __FUNCTION__, feature_id);
553 		rtw_sctx_done_err(&sctx, RTW_SCTX_DONE_UNKNOWN);
554 		goto exit;
555 	}
556 
557 	if (size > indicator->buf_size) {
558 		RTW_INFO("%s: <WARN> id(%d) buffer is not enough(%d<%d), data will be truncated!\n",
559 			 __FUNCTION__, feature_id, indicator->buf_size, size);
560 		cpsz = indicator->buf_size;
561 	} else
562 		cpsz = size;
563 	if (cpsz && indicator->buffer)
564 		_rtw_memcpy(indicator->buffer, buf, cpsz);
565 
566 	rtw_sctx_done(&sctx);
567 
568 exit:
569 	return _TRUE;
570 }
571 
572 HALMAC_PLATFORM_API rtw_halmac_platform_api = {
573 	/* R/W register */
574 #ifdef CONFIG_SDIO_HCI
575 	.SDIO_CMD52_READ = _halmac_sdio_cmd52_read,
576 	.SDIO_CMD53_READ_8 = _halmac_sdio_reg_read_8,
577 	.SDIO_CMD53_READ_16 = _halmac_sdio_reg_read_16,
578 	.SDIO_CMD53_READ_32 = _halmac_sdio_reg_read_32,
579 	.SDIO_CMD52_WRITE = _halmac_sdio_cmd52_write,
580 	.SDIO_CMD53_WRITE_8 = _halmac_sdio_reg_write_8,
581 	.SDIO_CMD53_WRITE_16 = _halmac_sdio_reg_write_16,
582 	.SDIO_CMD53_WRITE_32 = _halmac_sdio_reg_write_32,
583 #endif /* CONFIG_SDIO_HCI */
584 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCIE_HCI)
585 	.REG_READ_8 = _halmac_reg_read_8,
586 	.REG_READ_16 = _halmac_reg_read_16,
587 	.REG_READ_32 = _halmac_reg_read_32,
588 	.REG_WRITE_8 = _halmac_reg_write_8,
589 	.REG_WRITE_16 = _halmac_reg_write_16,
590 	.REG_WRITE_32 = _halmac_reg_write_32,
591 #endif /* CONFIG_USB_HCI || CONFIG_PCIE_HCI */
592 
593 	/* Write data */
594 #if 0
595 	/* impletement in HAL-IC level */
596 	.SEND_RSVD_PAGE = sdio_write_data_rsvd_page,
597 	.SEND_H2C_PKT = sdio_write_data_h2c,
598 #endif
599 	/* Memory allocate */
600 	.RTL_FREE = _halmac_mfree,
601 	.RTL_MALLOC = _halmac_malloc,
602 	.RTL_MEMCPY = _halmac_memcpy,
603 	.RTL_MEMSET = _halmac_memset,
604 
605 	/* Sleep */
606 	.RTL_DELAY_US = _halmac_udelay,
607 
608 	/* Process Synchronization */
609 	.MUTEX_INIT = _halmac_mutex_init,
610 	.MUTEX_DEINIT = _halmac_mutex_deinit,
611 	.MUTEX_LOCK = _halmac_mutex_lock,
612 	.MUTEX_UNLOCK = _halmac_mutex_unlock,
613 
614 	.MSG_PRINT = _halmac_msg_print,
615 	.EVENT_INDICATION = _halmac_event_indication,
616 };
617 
rtw_halmac_read8(struct intf_hdl * pintfhdl,u32 addr)618 u8 rtw_halmac_read8(struct intf_hdl *pintfhdl, u32 addr)
619 {
620 	PHALMAC_ADAPTER mac;
621 	PHALMAC_API api;
622 
623 
624 	/* WARNING: pintf_dev should not be null! */
625 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
626 	api = HALMAC_GET_API(mac);
627 
628 	return api->halmac_reg_read_8(mac, addr);
629 }
630 
rtw_halmac_read16(struct intf_hdl * pintfhdl,u32 addr)631 u16 rtw_halmac_read16(struct intf_hdl *pintfhdl, u32 addr)
632 {
633 	PHALMAC_ADAPTER mac;
634 	PHALMAC_API api;
635 
636 
637 	/* WARNING: pintf_dev should not be null! */
638 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
639 	api = HALMAC_GET_API(mac);
640 
641 	return api->halmac_reg_read_16(mac, addr);
642 }
643 
rtw_halmac_read32(struct intf_hdl * pintfhdl,u32 addr)644 u32 rtw_halmac_read32(struct intf_hdl *pintfhdl, u32 addr)
645 {
646 	PHALMAC_ADAPTER mac;
647 	PHALMAC_API api;
648 
649 
650 	/* WARNING: pintf_dev should not be null! */
651 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
652 	api = HALMAC_GET_API(mac);
653 
654 	return api->halmac_reg_read_32(mac, addr);
655 }
656 
rtw_halmac_write8(struct intf_hdl * pintfhdl,u32 addr,u8 value)657 int rtw_halmac_write8(struct intf_hdl *pintfhdl, u32 addr, u8 value)
658 {
659 	PHALMAC_ADAPTER mac;
660 	PHALMAC_API api;
661 	HALMAC_RET_STATUS status;
662 
663 
664 	/* WARNING: pintf_dev should not be null! */
665 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
666 	api = HALMAC_GET_API(mac);
667 
668 	status = api->halmac_reg_write_8(mac, addr, value);
669 
670 	if (status == HALMAC_RET_SUCCESS)
671 		return 0;
672 
673 	return -1;
674 }
675 
rtw_halmac_write16(struct intf_hdl * pintfhdl,u32 addr,u16 value)676 int rtw_halmac_write16(struct intf_hdl *pintfhdl, u32 addr, u16 value)
677 {
678 	PHALMAC_ADAPTER mac;
679 	PHALMAC_API api;
680 	HALMAC_RET_STATUS status;
681 
682 
683 	/* WARNING: pintf_dev should not be null! */
684 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
685 	api = HALMAC_GET_API(mac);
686 
687 	status = api->halmac_reg_write_16(mac, addr, value);
688 
689 	if (status == HALMAC_RET_SUCCESS)
690 		return 0;
691 
692 	return -1;
693 }
694 
rtw_halmac_write32(struct intf_hdl * pintfhdl,u32 addr,u32 value)695 int rtw_halmac_write32(struct intf_hdl *pintfhdl, u32 addr, u32 value)
696 {
697 	PHALMAC_ADAPTER mac;
698 	PHALMAC_API api;
699 	HALMAC_RET_STATUS status;
700 
701 
702 	/* WARNING: pintf_dev should not be null! */
703 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
704 	api = HALMAC_GET_API(mac);
705 
706 	status = api->halmac_reg_write_32(mac, addr, value);
707 
708 	if (status == HALMAC_RET_SUCCESS)
709 		return 0;
710 
711 	return -1;
712 }
713 
init_priv(struct halmacpriv * priv)714 static int init_priv(struct halmacpriv *priv)
715 {
716 	struct halmac_indicator *indicator;
717 	u32 count, size;
718 
719 
720 	size = sizeof(*priv);
721 	_rtw_memset(priv, 0, size);
722 
723 	count = HALMAC_FEATURE_ALL + 1;
724 	size = sizeof(*indicator) * count;
725 	indicator = (struct halmac_indicator *)rtw_zmalloc(size);
726 	if (!indicator)
727 		return -1;
728 	priv->indicator = indicator;
729 
730 	return 0;
731 }
732 
deinit_priv(struct halmacpriv * priv)733 static void deinit_priv(struct halmacpriv *priv)
734 {
735 	struct halmac_indicator *indicator;
736 
737 
738 	indicator = priv->indicator;
739 	priv->indicator = NULL;
740 	if (indicator) {
741 		u32 count, size;
742 
743 		count = HALMAC_FEATURE_ALL + 1;
744 #ifdef CONFIG_RTW_DEBUG
745 		{
746 			struct submit_ctx *sctx;
747 			u32 i;
748 
749 			for (i = 0; i < count; i++) {
750 				if (!indicator[i].sctx)
751 					continue;
752 
753 				RTW_INFO("%s: <WARN> %s id(%d) sctx still exist!!\n",
754 					__FUNCTION__, RTW_HALMAC_FEATURE_NAME[i], i);
755 				sctx = indicator[i].sctx;
756 				indicator[i].sctx = NULL;
757 				rtw_mfree((u8 *)sctx, sizeof(*sctx));
758 			}
759 		}
760 #endif /* !CONFIG_RTW_DEBUG */
761 		size = sizeof(*indicator) * count;
762 		rtw_mfree((u8 *)indicator, size);
763 	}
764 }
765 
rtw_halmac_init_adapter(struct dvobj_priv * d,PHALMAC_PLATFORM_API pf_api)766 int rtw_halmac_init_adapter(struct dvobj_priv *d, PHALMAC_PLATFORM_API pf_api)
767 {
768 	PHALMAC_ADAPTER halmac;
769 	PHALMAC_API api;
770 	HALMAC_INTERFACE intf;
771 	HALMAC_RET_STATUS status;
772 	int err = 0;
773 
774 
775 	halmac = dvobj_to_halmac(d);
776 	if (halmac) {
777 		err = 0;
778 		goto out;
779 	}
780 
781 	err = init_priv(&d->hmpriv);
782 	if (err)
783 		goto out;
784 
785 #ifdef CONFIG_SDIO_HCI
786 	intf = HALMAC_INTERFACE_SDIO;
787 #elif defined(CONFIG_USB_HCI)
788 	intf = HALMAC_INTERFACE_USB;
789 #elif defined(CONFIG_PCIE_HCI)
790 	intf = HALMAC_INTERFACE_PCIE;
791 #else
792 #warning "INTERFACE(CONFIG_XXX_HCI) not be defined!!"
793 	intf = HALMAC_INTERFACE_UNDEFINE;
794 #endif
795 	status = halmac_init_adapter(d, pf_api, intf, &halmac, &api);
796 	if (HALMAC_RET_SUCCESS != status) {
797 		RTW_INFO("%s: halmac_init_adapter fail!(status=%d)\n", __FUNCTION__, status);
798 		err = -1;
799 		goto out;
800 	}
801 
802 	dvobj_set_halmac(d, halmac);
803 
804 out:
805 	if (err)
806 		rtw_halmac_deinit_adapter(d);
807 
808 	return err;
809 }
810 
rtw_halmac_deinit_adapter(struct dvobj_priv * d)811 int rtw_halmac_deinit_adapter(struct dvobj_priv *d)
812 {
813 	PHALMAC_ADAPTER halmac;
814 	HALMAC_RET_STATUS status;
815 	int err = 0;
816 
817 
818 	halmac = dvobj_to_halmac(d);
819 	if (!halmac) {
820 		err = 0;
821 		goto out;
822 	}
823 
824 	deinit_priv(&d->hmpriv);
825 
826 	status = halmac_deinit_adapter(halmac);
827 	dvobj_set_halmac(d, NULL);
828 	if (status != HALMAC_RET_SUCCESS) {
829 		err = -1;
830 		goto out;
831 	}
832 
833 out:
834 	return err;
835 }
836 
rtw_halmac_poweron(struct dvobj_priv * d)837 int rtw_halmac_poweron(struct dvobj_priv *d)
838 {
839 	PHALMAC_ADAPTER halmac;
840 	PHALMAC_API api;
841 	HALMAC_RET_STATUS status;
842 	int err = -1;
843 
844 
845 	halmac = dvobj_to_halmac(d);
846 	if (!halmac)
847 		goto out;
848 
849 	api = HALMAC_GET_API(halmac);
850 
851 	status = api->halmac_pre_init_system_cfg(halmac);
852 	if (status != HALMAC_RET_SUCCESS)
853 		goto out;
854 
855 	status = api->halmac_mac_power_switch(halmac, HALMAC_MAC_POWER_ON);
856 	if (status != HALMAC_RET_SUCCESS)
857 		goto out;
858 
859 	status = api->halmac_init_system_cfg(halmac);
860 	if (status != HALMAC_RET_SUCCESS)
861 		goto out;
862 
863 	err = 0;
864 out:
865 	return err;
866 }
867 
rtw_halmac_poweroff(struct dvobj_priv * d)868 int rtw_halmac_poweroff(struct dvobj_priv *d)
869 {
870 	PHALMAC_ADAPTER halmac;
871 	PHALMAC_API api;
872 	HALMAC_RET_STATUS status;
873 	int err = -1;
874 
875 
876 	halmac = dvobj_to_halmac(d);
877 	if (!halmac)
878 		goto out;
879 
880 	api = HALMAC_GET_API(halmac);
881 
882 	status = api->halmac_mac_power_switch(halmac, HALMAC_MAC_POWER_OFF);
883 	if (status != HALMAC_RET_SUCCESS)
884 		goto out;
885 
886 	err = 0;
887 out:
888 	return err;
889 }
890 
891 /*
892  * Note:
893  *	When this function return, the register REG_RCR may be changed.
894  */
rtw_halmac_config_rx_info(struct dvobj_priv * d,HALMAC_DRV_INFO info)895 int rtw_halmac_config_rx_info(struct dvobj_priv *d, HALMAC_DRV_INFO info)
896 {
897 	PHALMAC_ADAPTER halmac;
898 	PHALMAC_API api;
899 	HALMAC_RET_STATUS status;
900 	int err = -1;
901 
902 
903 	halmac = dvobj_to_halmac(d);
904 	api = HALMAC_GET_API(halmac);
905 
906 	status = api->halmac_cfg_drv_info(halmac, info);
907 	if (status != HALMAC_RET_SUCCESS)
908 		goto out;
909 
910 	err = 0;
911 out:
912 	return err;
913 }
914 
init_mac_flow(struct dvobj_priv * d)915 static HALMAC_RET_STATUS init_mac_flow(struct dvobj_priv *d)
916 {
917 	PADAPTER p;
918 	PHALMAC_ADAPTER halmac;
919 	PHALMAC_API api;
920 	HALMAC_WLAN_ADDR hwa;
921 	HALMAC_RET_STATUS status;
922 	u8 wifi_test = 0;
923 	u8 nettype;
924 	int err;
925 
926 
927 	p = d->padapters[IFACE_ID0];
928 	halmac = dvobj_to_halmac(d);
929 	api = HALMAC_GET_API(halmac);
930 	if (p->registrypriv.wifi_spec)
931 		wifi_test = 1;
932 
933 #ifdef CONFIG_USB_HCI
934 	status = api->halmac_set_bulkout_num(halmac, d->RtNumOutPipes);
935 	if (status != HALMAC_RET_SUCCESS)
936 		goto out;
937 #endif /* CONFIG_USB_HCI */
938 
939 	if (wifi_test)
940 		status = api->halmac_init_mac_cfg(halmac, HALMAC_TRX_MODE_WMM);
941 	else
942 		status = api->halmac_init_mac_cfg(halmac, HALMAC_TRX_MODE_NORMAL);
943 	if (status != HALMAC_RET_SUCCESS)
944 		goto out;
945 
946 	err = rtw_halmac_rx_agg_switch(d, _TRUE);
947 	if (err)
948 		goto out;
949 
950 	nettype = dvobj_to_regsty(d)->wireless_mode;
951 	if (IsSupportedVHT(nettype) == _TRUE)
952 		status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_AC);
953 	else if (IsSupportedHT(nettype) == _TRUE)
954 		status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_N);
955 	else if (IsSupportedTxOFDM(nettype) == _TRUE)
956 		status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_G);
957 	else
958 		status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_B);
959 	if (status != HALMAC_RET_SUCCESS)
960 		goto out;
961 
962 out:
963 	return status;
964 }
965 
_rf_type_drv2halmac(RT_RF_TYPE_DEF_E rf_drv)966 static inline HALMAC_RF_TYPE _rf_type_drv2halmac(RT_RF_TYPE_DEF_E rf_drv)
967 {
968 	HALMAC_RF_TYPE rf_mac;
969 
970 
971 	switch (rf_drv) {
972 	case RF_1T2R:
973 		rf_mac = HALMAC_RF_1T2R;
974 		break;
975 	case RF_2T4R:
976 		rf_mac = HALMAC_RF_2T4R;
977 		break;
978 	case RF_2T2R:
979 		rf_mac = HALMAC_RF_2T2R;
980 		break;
981 	case RF_1T1R:
982 		rf_mac = HALMAC_RF_1T1R;
983 		break;
984 	case RF_2T2R_GREEN:
985 		rf_mac = HALMAC_RF_2T2R_GREEN;
986 		break;
987 	case RF_2T3R:
988 		rf_mac = HALMAC_RF_2T3R;
989 		break;
990 	case RF_3T3R:
991 		rf_mac = HALMAC_RF_3T3R;
992 		break;
993 	case RF_3T4R:
994 		rf_mac = HALMAC_RF_3T4R;
995 		break;
996 	case RF_4T4R:
997 		rf_mac = HALMAC_RF_4T4R;
998 		break;
999 	default:
1000 		rf_mac = (HALMAC_RF_TYPE)rf_drv;
1001 		break;
1002 	}
1003 
1004 	return rf_mac;
1005 }
1006 
_send_general_info(struct dvobj_priv * d)1007 static int _send_general_info(struct dvobj_priv *d)
1008 {
1009 	PADAPTER adapter;
1010 	PHAL_DATA_TYPE hal;
1011 	PHALMAC_ADAPTER halmac;
1012 	PHALMAC_API api;
1013 	HALMAC_GENERAL_INFO info;
1014 	HALMAC_RET_STATUS status;
1015 	u8 val8;
1016 
1017 
1018 	adapter = d->padapters[IFACE_ID0];
1019 	hal = GET_HAL_DATA(adapter);
1020 	halmac = dvobj_to_halmac(d);
1021 	if (!halmac)
1022 		return -1;
1023 	api = HALMAC_GET_API(halmac);
1024 
1025 	_rtw_memset(&info, 0, sizeof(info));
1026 	info.rfe_type = (u8)hal->RFEType;
1027 	rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, &val8);
1028 	info.rf_type = _rf_type_drv2halmac(val8);
1029 
1030 	status = api->halmac_send_general_info(halmac, &info);
1031 	switch (status) {
1032 	case HALMAC_RET_SUCCESS:
1033 		break;
1034 	case HALMAC_RET_NO_DLFW:
1035 		RTW_WARN("%s: halmac_send_general_info() fail because fw not dl!\n",
1036 			 __FUNCTION__);
1037 		/* go through */
1038 	default:
1039 		return -1;
1040 	}
1041 
1042 	return 0;
1043 }
1044 
1045 /*
1046  * Notices:
1047  *	Make sure
1048  *	1. rtw_hal_get_hwreg(HW_VAR_RF_TYPE)
1049  *	2. HAL_DATA_TYPE.rfe_type
1050  *	already ready for use before calling this function.
1051  */
_halmac_init_hal(struct dvobj_priv * d,u8 * fw,u32 fwsize)1052 static int _halmac_init_hal(struct dvobj_priv *d, u8 *fw, u32 fwsize)
1053 {
1054 	PADAPTER adapter;
1055 	PHALMAC_ADAPTER halmac;
1056 	PHALMAC_API api;
1057 	HALMAC_RET_STATUS status;
1058 	u32 ok = _TRUE;
1059 	u8 fw_ok = _FALSE;
1060 	int err, err_ret = -1;
1061 
1062 
1063 	adapter = d->padapters[IFACE_ID0];
1064 	halmac = dvobj_to_halmac(d);
1065 	if (!halmac)
1066 		goto out;
1067 	api = HALMAC_GET_API(halmac);
1068 
1069 	/* StatePowerOff */
1070 
1071 	/* SKIP: halmac_init_adapter (Already done before) */
1072 
1073 	/* halmac_pre_Init_system_cfg */
1074 	/* halmac_mac_power_switch(on) */
1075 	/* halmac_Init_system_cfg */
1076 	ok = rtw_hal_power_on(adapter);
1077 	if (_FALSE == ok)
1078 		goto out;
1079 
1080 	/* StatePowerOn */
1081 
1082 	/* DownloadFW */
1083 	d->hmpriv.send_general_info = 0;
1084 	if (fw && fwsize) {
1085 		err = rtw_halmac_dlfw(d, fw, fwsize);
1086 		if (err)
1087 			goto out;
1088 		fw_ok = _TRUE;
1089 	}
1090 
1091 	/* InitMACFlow */
1092 	status = init_mac_flow(d);
1093 	if (status != HALMAC_RET_SUCCESS)
1094 		goto out;
1095 
1096 	/* halmac_send_general_info */
1097 	if (_TRUE == fw_ok) {
1098 		d->hmpriv.send_general_info = 0;
1099 		err = _send_general_info(d);
1100 		if (err)
1101 			goto out;
1102 	} else
1103 		d->hmpriv.send_general_info = 1;
1104 
1105 	/* Init Phy parameter-MAC */
1106 	ok = rtw_hal_init_mac_register(adapter);
1107 	if (_FALSE == ok)
1108 		goto out;
1109 
1110 	/* StateMacInitialized */
1111 
1112 	/* halmac_cfg_drv_info */
1113 	err = rtw_halmac_config_rx_info(d, HALMAC_DRV_INFO_PHY_STATUS);
1114 	if (err)
1115 		goto out;
1116 
1117 	/* halmac_set_hw_value(HALMAC_HW_EN_BB_RF) */
1118 	/* Init BB, RF */
1119 	ok = rtw_hal_init_phy(adapter);
1120 	if (_FALSE == ok)
1121 		goto out;
1122 
1123 	status = api->halmac_init_interface_cfg(halmac);
1124 	if (status != HALMAC_RET_SUCCESS)
1125 		goto out;
1126 
1127 	/* SKIP: halmac_verify_platform_api */
1128 	/* SKIP: halmac_h2c_lb */
1129 
1130 	/* StateRxIdle */
1131 
1132 	err_ret = 0;
1133 out:
1134 	return err_ret;
1135 }
1136 
rtw_halmac_init_hal(struct dvobj_priv * d)1137 int rtw_halmac_init_hal(struct dvobj_priv *d)
1138 {
1139 	return _halmac_init_hal(d, NULL, 0);
1140 }
1141 
1142 /*
1143  * Notices:
1144  *	Make sure
1145  *	1. rtw_hal_get_hwreg(HW_VAR_RF_TYPE)
1146  *	2. HAL_DATA_TYPE.rfe_type
1147  *	already ready for use before calling this function.
1148  */
rtw_halmac_init_hal_fw(struct dvobj_priv * d,u8 * fw,u32 fwsize)1149 int rtw_halmac_init_hal_fw(struct dvobj_priv *d, u8 *fw, u32 fwsize)
1150 {
1151 	return _halmac_init_hal(d, fw, fwsize);
1152 }
1153 
1154 /*
1155  * Notices:
1156  *	Make sure
1157  *	1. rtw_hal_get_hwreg(HW_VAR_RF_TYPE)
1158  *	2. HAL_DATA_TYPE.rfe_type
1159  *	already ready for use before calling this function.
1160  */
rtw_halmac_init_hal_fw_file(struct dvobj_priv * d,u8 * fwpath)1161 int rtw_halmac_init_hal_fw_file(struct dvobj_priv *d, u8 *fwpath)
1162 {
1163 	u8 *fw = NULL;
1164 	u32 fwmaxsize, size = 0;
1165 	int err = 0;
1166 
1167 
1168 	fwmaxsize = FIRMWARE_MAX_SIZE;
1169 	fw = rtw_zmalloc(fwmaxsize);
1170 	if (!fw)
1171 		return -1;
1172 
1173 	size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
1174 	if (!size) {
1175 		err = -1;
1176 		goto exit;
1177 	}
1178 
1179 	err = _halmac_init_hal(d, fw, size);
1180 
1181 exit:
1182 	rtw_mfree(fw, fwmaxsize);
1183 	fw = NULL;
1184 
1185 	return err;
1186 }
1187 
rtw_halmac_deinit_hal(struct dvobj_priv * d)1188 int rtw_halmac_deinit_hal(struct dvobj_priv *d)
1189 {
1190 	PADAPTER adapter;
1191 	PHALMAC_ADAPTER halmac;
1192 	PHALMAC_API api;
1193 	HALMAC_RET_STATUS status;
1194 	int err = -1;
1195 
1196 
1197 	adapter = d->padapters[IFACE_ID0];
1198 	halmac = dvobj_to_halmac(d);
1199 	if (!halmac)
1200 		goto out;
1201 	api = HALMAC_GET_API(halmac);
1202 
1203 	status = api->halmac_deinit_interface_cfg(halmac);
1204 	if (status != HALMAC_RET_SUCCESS)
1205 		goto out;
1206 
1207 	rtw_hal_power_off(adapter);
1208 
1209 	err = 0;
1210 out:
1211 	return err;
1212 }
1213 
rtw_halmac_self_verify(struct dvobj_priv * d)1214 int rtw_halmac_self_verify(struct dvobj_priv *d)
1215 {
1216 	PHALMAC_ADAPTER mac;
1217 	PHALMAC_API api;
1218 	HALMAC_RET_STATUS status;
1219 	int err = -1;
1220 
1221 
1222 	mac = dvobj_to_halmac(d);
1223 	api = HALMAC_GET_API(mac);
1224 
1225 	status = api->halmac_verify_platform_api(mac);
1226 	if (status != HALMAC_RET_SUCCESS)
1227 		goto out;
1228 
1229 	status = api->halmac_h2c_lb(mac);
1230 	if (status != HALMAC_RET_SUCCESS)
1231 		goto out;
1232 
1233 	err = 0;
1234 out:
1235 	return err;
1236 }
1237 
rtw_halmac_dlfw(struct dvobj_priv * d,u8 * fw,u32 fwsize)1238 int rtw_halmac_dlfw(struct dvobj_priv *d, u8 *fw, u32 fwsize)
1239 {
1240 	PHALMAC_ADAPTER mac;
1241 	PHALMAC_API api;
1242 	HALMAC_RET_STATUS status;
1243 	int err = 0;
1244 	PHAL_DATA_TYPE hal;
1245 	HALMAC_FW_VERSION fw_vesion;
1246 
1247 
1248 	mac = dvobj_to_halmac(d);
1249 	api = HALMAC_GET_API(mac);
1250 	hal = GET_HAL_DATA(d->padapters[IFACE_ID0]);
1251 
1252 	if ((!fw) || (!fwsize))
1253 		return -1;
1254 
1255 	/* 1. Driver Stop Tx */
1256 	/* ToDo */
1257 
1258 	/* 2. Driver Check Tx FIFO is empty */
1259 	/* ToDo */
1260 
1261 	/* 3. Config MAX download size */
1262 #ifdef CONFIG_USB_HCI
1263 	/* for USB do not exceed MAX_CMDBUF_SZ */
1264 	api->halmac_cfg_max_dl_size(mac, 0x1000);
1265 #elif defined CONFIG_PCIE_HCI
1266 	/* required a even length from u32 */
1267         api->halmac_cfg_max_dl_size(mac, (MAX_CMDBUF_SZ - TXDESC_OFFSET) & 0xFFFFFFFE);
1268 #endif
1269 
1270 	/* 4. Download Firmware */
1271 	status = api->halmac_download_firmware(mac, fw, fwsize);
1272 	if (HALMAC_RET_SUCCESS != status)
1273 		return -1;
1274 
1275 	if (d->hmpriv.send_general_info) {
1276 		d->hmpriv.send_general_info = 0;
1277 		err = _send_general_info(d);
1278 	}
1279 
1280 	/* 5. Driver resume TX if needed */
1281 	/* ToDo */
1282 
1283 	/* 6. Reset driver variables if needed */
1284 	hal->LastHMEBoxNum = 0;
1285 
1286 
1287 	/* 7. Get FW version */
1288 	status = api->halmac_get_fw_version(mac, &fw_vesion);
1289 	if (status == HALMAC_RET_SUCCESS) {
1290 		hal->FirmwareVersion = fw_vesion.version;
1291 		hal->FirmwareSubVersion = fw_vesion.sub_version;
1292 	}
1293 
1294 	return err;
1295 }
1296 
rtw_halmac_dlfw_from_file(struct dvobj_priv * d,u8 * fwpath)1297 int rtw_halmac_dlfw_from_file(struct dvobj_priv *d, u8 *fwpath)
1298 {
1299 	u8 *fw = NULL;
1300 	u32 fwmaxsize, size = 0;
1301 	int err = 0;
1302 
1303 
1304 	fwmaxsize = FIRMWARE_MAX_SIZE;
1305 	fw = rtw_zmalloc(fwmaxsize);
1306 	if (!fw)
1307 		return -1;
1308 
1309 	size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
1310 	if (size)
1311 		err = rtw_halmac_dlfw(d, fw, size);
1312 	else
1313 		err = -1;
1314 
1315 	rtw_mfree(fw, fwmaxsize);
1316 	fw = NULL;
1317 
1318 	return err;
1319 }
1320 
1321 /*
1322  * Description:
1323  *	Power on/off BB/RF domain.
1324  *
1325  * Parameters:
1326  *	enable	_TRUE/_FALSE for power on/off
1327  *
1328  * Return:
1329  *	0	Success
1330  *	others	Fail
1331  */
rtw_halmac_phy_power_switch(struct dvobj_priv * d,u8 enable)1332 int rtw_halmac_phy_power_switch(struct dvobj_priv *d, u8 enable)
1333 {
1334 	PADAPTER adapter;
1335 	PHALMAC_ADAPTER halmac;
1336 	PHALMAC_API api;
1337 	HALMAC_RET_STATUS status;
1338 
1339 
1340 	adapter = d->padapters[IFACE_ID0];
1341 	halmac = dvobj_to_halmac(d);
1342 	if (!halmac)
1343 		return -1;
1344 	api = HALMAC_GET_API(halmac);
1345 
1346 	status = api->halmac_set_hw_value(halmac, HALMAC_HW_EN_BB_RF, &enable);
1347 	if (status != HALMAC_RET_SUCCESS)
1348 		return -1;
1349 
1350 	return 0;
1351 }
1352 
_is_fw_read_cmd_down(PADAPTER adapter,u8 msgbox_num)1353 static u8 _is_fw_read_cmd_down(PADAPTER adapter, u8 msgbox_num)
1354 {
1355 	u8 read_down = _FALSE;
1356 	int retry_cnts = 100;
1357 	u8 valid;
1358 
1359 	/* RTW_INFO("_is_fw_read_cmd_down, reg_1cc(%x), msg_box(%d)...\n", rtw_read8(adapter, REG_HMETFR), msgbox_num); */
1360 
1361 	do {
1362 		valid = rtw_read8(adapter, REG_HMETFR) & BIT(msgbox_num);
1363 		if (0 == valid)
1364 			read_down = _TRUE;
1365 		else
1366 			rtw_msleep_os(1);
1367 	} while ((!read_down) && (retry_cnts--));
1368 
1369 	return read_down;
1370 }
1371 
rtw_halmac_send_h2c(struct dvobj_priv * d,u8 * h2c)1372 int rtw_halmac_send_h2c(struct dvobj_priv *d, u8 *h2c)
1373 {
1374 	PADAPTER adapter = d->padapters[IFACE_ID0];
1375 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
1376 	u8 h2c_box_num = 0;
1377 	u32 msgbox_addr = 0;
1378 	u32 msgbox_ex_addr = 0;
1379 	u32 h2c_cmd = 0;
1380 	u32 h2c_cmd_ex = 0;
1381 	s32 ret = _FAIL;
1382 
1383 	if (adapter->bFWReady == _FALSE) {
1384 		RTW_INFO("%s: return H2C cmd because fw is not ready\n", __FUNCTION__);
1385 		return ret;
1386 	}
1387 
1388 	if (!h2c) {
1389 		RTW_INFO("%s: pbuf is NULL\n", __FUNCTION__);
1390 		return ret;
1391 	}
1392 
1393 	if (rtw_is_surprise_removed(adapter)) {
1394 		RTW_INFO("%s: surprise removed\n", __FUNCTION__);
1395 		return ret;
1396 	}
1397 
1398 	_enter_critical_mutex(&d->h2c_fwcmd_mutex, NULL);
1399 
1400 	/* pay attention to if race condition happened in  H2C cmd setting */
1401 	h2c_box_num = hal->LastHMEBoxNum;
1402 
1403 	if (!_is_fw_read_cmd_down(adapter, h2c_box_num)) {
1404 		RTW_INFO(" fw read cmd failed...\n");
1405 		goto exit;
1406 	}
1407 
1408 	/* Write Ext command(byte 4 -7) */
1409 	msgbox_ex_addr = REG_HMEBOX_E0 + (h2c_box_num * EX_MESSAGE_BOX_SIZE);
1410 	_rtw_memcpy((u8 *)(&h2c_cmd_ex), h2c + 4, EX_MESSAGE_BOX_SIZE);
1411 	h2c_cmd_ex = le32_to_cpu(h2c_cmd_ex);
1412 	rtw_write32(adapter, msgbox_ex_addr, h2c_cmd_ex);
1413 
1414 	/* Write command (byte 0 -3 ) */
1415 	msgbox_addr = REG_HMEBOX0 + (h2c_box_num * MESSAGE_BOX_SIZE);
1416 	_rtw_memcpy((u8 *)(&h2c_cmd), h2c, 4);
1417 	h2c_cmd = le32_to_cpu(h2c_cmd);
1418 	rtw_write32(adapter, msgbox_addr, h2c_cmd);
1419 
1420 	/* update last msg box number */
1421 	hal->LastHMEBoxNum = (h2c_box_num + 1) % MAX_H2C_BOX_NUMS;
1422 	ret = _SUCCESS;
1423 
1424 exit:
1425 	_exit_critical_mutex(&d->h2c_fwcmd_mutex, NULL);
1426 	return ret;
1427 }
1428 
rtw_halmac_c2h_handle(struct dvobj_priv * d,u8 * c2h,u32 size)1429 int rtw_halmac_c2h_handle(struct dvobj_priv *d, u8 *c2h, u32 size)
1430 {
1431 	PHALMAC_ADAPTER mac;
1432 	PHALMAC_API api;
1433 	HALMAC_RET_STATUS status;
1434 
1435 
1436 	mac = dvobj_to_halmac(d);
1437 	api = HALMAC_GET_API(mac);
1438 
1439 	status = api->halmac_get_c2h_info(mac, c2h, size);
1440 	if (HALMAC_RET_SUCCESS != status)
1441 		return -1;
1442 
1443 	return 0;
1444 }
1445 
rtw_halmac_get_available_efuse_size(struct dvobj_priv * d,u32 * size)1446 int rtw_halmac_get_available_efuse_size(struct dvobj_priv *d, u32 *size)
1447 {
1448 	PHALMAC_ADAPTER mac;
1449 	PHALMAC_API api;
1450 	HALMAC_RET_STATUS status;
1451 	u32 val;
1452 
1453 
1454 	mac = dvobj_to_halmac(d);
1455 	api = HALMAC_GET_API(mac);
1456 
1457 	status = api->halmac_get_efuse_available_size(mac, &val);
1458 	if (HALMAC_RET_SUCCESS != status)
1459 		return -1;
1460 
1461 	*size = val;
1462 	return 0;
1463 }
1464 
rtw_halmac_get_physical_efuse_size(struct dvobj_priv * d,u32 * size)1465 int rtw_halmac_get_physical_efuse_size(struct dvobj_priv *d, u32 *size)
1466 {
1467 	PHALMAC_ADAPTER mac;
1468 	PHALMAC_API api;
1469 	HALMAC_RET_STATUS status;
1470 	u32 val;
1471 
1472 
1473 	mac = dvobj_to_halmac(d);
1474 	api = HALMAC_GET_API(mac);
1475 
1476 	status = api->halmac_get_efuse_size(mac, &val);
1477 	if (HALMAC_RET_SUCCESS != status)
1478 		return -1;
1479 
1480 	*size = val;
1481 	return 0;
1482 }
1483 
rtw_halmac_read_physical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size)1484 int rtw_halmac_read_physical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size)
1485 {
1486 	PHALMAC_ADAPTER mac;
1487 	PHALMAC_API api;
1488 	HALMAC_RET_STATUS status;
1489 	HALMAC_FEATURE_ID id;
1490 	int ret;
1491 
1492 
1493 	mac = dvobj_to_halmac(d);
1494 	api = HALMAC_GET_API(mac);
1495 	id = HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE;
1496 
1497 	ret = init_halmac_event(d, id, map, size);
1498 	if (ret)
1499 		return -1;
1500 
1501 	status = api->halmac_dump_efuse_map(mac, HALMAC_EFUSE_R_AUTO);
1502 	if (HALMAC_RET_SUCCESS != status) {
1503 		free_halmac_event(d, id);
1504 		return -1;
1505 	}
1506 
1507 	ret = wait_halmac_event(d, id);
1508 	if (ret)
1509 		return -1;
1510 
1511 	return 0;
1512 }
1513 
rtw_halmac_read_physical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)1514 int rtw_halmac_read_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
1515 {
1516 	PHALMAC_ADAPTER mac;
1517 	PHALMAC_API api;
1518 	HALMAC_RET_STATUS status;
1519 	u8 v;
1520 	u32 i;
1521 
1522 
1523 	mac = dvobj_to_halmac(d);
1524 	api = HALMAC_GET_API(mac);
1525 
1526 	for (i = 0; i < cnt; i++) {
1527 		status = api->halmac_read_efuse(mac, offset + i, &v);
1528 		if (HALMAC_RET_SUCCESS != status)
1529 			return -1;
1530 		data[i] = v;
1531 	}
1532 
1533 	return 0;
1534 }
1535 
rtw_halmac_write_physical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)1536 int rtw_halmac_write_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
1537 {
1538 	PHALMAC_ADAPTER mac;
1539 	PHALMAC_API api;
1540 	HALMAC_RET_STATUS status;
1541 	u32 i;
1542 
1543 
1544 	mac = dvobj_to_halmac(d);
1545 	api = HALMAC_GET_API(mac);
1546 
1547 	for (i = 0; i < cnt; i++) {
1548 		status = api->halmac_write_efuse(mac, offset + i, data[i]);
1549 		if (HALMAC_RET_SUCCESS != status)
1550 			return -1;
1551 	}
1552 
1553 	return 0;
1554 }
1555 
rtw_halmac_get_logical_efuse_size(struct dvobj_priv * d,u32 * size)1556 int rtw_halmac_get_logical_efuse_size(struct dvobj_priv *d, u32 *size)
1557 {
1558 	PHALMAC_ADAPTER mac;
1559 	PHALMAC_API api;
1560 	HALMAC_RET_STATUS status;
1561 	u32 val;
1562 
1563 
1564 	mac = dvobj_to_halmac(d);
1565 	api = HALMAC_GET_API(mac);
1566 
1567 	status = api->halmac_get_logical_efuse_size(mac, &val);
1568 	if (HALMAC_RET_SUCCESS != status)
1569 		return -1;
1570 
1571 	*size = val;
1572 	return 0;
1573 }
1574 
rtw_halmac_read_logical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size)1575 int rtw_halmac_read_logical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size)
1576 {
1577 	PHALMAC_ADAPTER mac;
1578 	PHALMAC_API api;
1579 	HALMAC_RET_STATUS status;
1580 	HALMAC_FEATURE_ID id;
1581 	int ret;
1582 
1583 
1584 	mac = dvobj_to_halmac(d);
1585 	api = HALMAC_GET_API(mac);
1586 	id = HALMAC_FEATURE_DUMP_LOGICAL_EFUSE;
1587 
1588 	ret = init_halmac_event(d, id, map, size);
1589 	if (ret)
1590 		return -1;
1591 
1592 	status = api->halmac_dump_logical_efuse_map(mac, HALMAC_EFUSE_R_AUTO);
1593 	if (HALMAC_RET_SUCCESS != status) {
1594 		free_halmac_event(d, id);
1595 		return -1;
1596 	}
1597 
1598 	ret = wait_halmac_event(d, id);
1599 	if (ret)
1600 		return -1;
1601 
1602 	return 0;
1603 }
1604 
rtw_halmac_write_logical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size,u8 * maskmap,u32 masksize)1605 int rtw_halmac_write_logical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size, u8 *maskmap, u32 masksize)
1606 {
1607 	PHALMAC_ADAPTER mac;
1608 	PHALMAC_API api;
1609 	HALMAC_PG_EFUSE_INFO pginfo;
1610 	HALMAC_RET_STATUS status;
1611 
1612 
1613 	mac = dvobj_to_halmac(d);
1614 	api = HALMAC_GET_API(mac);
1615 
1616 	pginfo.pEfuse_map = map;
1617 	pginfo.efuse_map_size = size;
1618 	pginfo.pEfuse_mask = maskmap;
1619 	pginfo.efuse_mask_size = masksize;
1620 
1621 	status = api->halmac_pg_efuse_by_map(mac, &pginfo, HALMAC_EFUSE_R_AUTO);
1622 	if (HALMAC_RET_SUCCESS != status)
1623 		return -1;
1624 
1625 	return 0;
1626 }
1627 
rtw_halmac_read_logical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)1628 int rtw_halmac_read_logical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
1629 {
1630 	PHALMAC_ADAPTER mac;
1631 	PHALMAC_API api;
1632 	HALMAC_RET_STATUS status;
1633 	u8 v;
1634 	u32 i;
1635 
1636 
1637 	mac = dvobj_to_halmac(d);
1638 	api = HALMAC_GET_API(mac);
1639 
1640 	for (i = 0; i < cnt; i++) {
1641 		status = api->halmac_read_logical_efuse(mac, offset + i, &v);
1642 		if (HALMAC_RET_SUCCESS != status)
1643 			return -1;
1644 		data[i] = v;
1645 	}
1646 
1647 	return 0;
1648 }
1649 
rtw_halmac_write_logical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)1650 int rtw_halmac_write_logical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
1651 {
1652 	PHALMAC_ADAPTER mac;
1653 	PHALMAC_API api;
1654 	HALMAC_RET_STATUS status;
1655 	u32 i;
1656 
1657 
1658 	mac = dvobj_to_halmac(d);
1659 	api = HALMAC_GET_API(mac);
1660 
1661 	for (i = 0; i < cnt; i++) {
1662 		status = api->halmac_write_logical_efuse(mac, offset + i, data[i]);
1663 		if (HALMAC_RET_SUCCESS != status)
1664 			return -1;
1665 	}
1666 
1667 	return 0;
1668 }
1669 
rtw_halmac_write_bt_physical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)1670 int rtw_halmac_write_bt_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
1671 {
1672 	PHALMAC_ADAPTER mac;
1673 	PHALMAC_API api;
1674 	HALMAC_RET_STATUS status;
1675 	u32 i;
1676 	u8 bank = 1;
1677 
1678 	mac = dvobj_to_halmac(d);
1679 	api = HALMAC_GET_API(mac);
1680 
1681 	for (i = 0; i < cnt; i++) {
1682 		status = api->halmac_write_efuse_bt(mac, offset + i, data[i], bank);
1683 		if (HALMAC_RET_SUCCESS != status) {
1684 			printk("%s: halmac_write_efuse_bt status = %d\n", __FUNCTION__, status);
1685 			return -1;
1686 		}
1687 	}
1688 	printk("%s: halmac_write_efuse_bt status = HALMAC_RET_SUCCESS %d\n", __FUNCTION__, status);
1689 	return 0;
1690 }
1691 
1692 
rtw_halmac_read_bt_physical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size)1693 int rtw_halmac_read_bt_physical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size)
1694 {
1695 	PHALMAC_ADAPTER mac;
1696 	PHALMAC_API api;
1697 	HALMAC_RET_STATUS status;
1698 	HALMAC_FEATURE_ID id;
1699 	int ret;
1700 	int bank = 1;
1701 
1702 	mac = dvobj_to_halmac(d);
1703 	api = HALMAC_GET_API(mac);
1704 
1705 	status = api->halmac_dump_efuse_map_bt(mac, bank, size, map);
1706 	if (HALMAC_RET_SUCCESS != status) {
1707 		printk("%s: halmac_dump_efuse_map_bt fail!\n", __FUNCTION__);
1708 		return -1;
1709 	}
1710 
1711 	printk("%s: OK!\n", __FUNCTION__);
1712 
1713 	return 0;
1714 }
1715 
_hw_port_drv2halmac(enum _hw_port hwport)1716 static inline u8 _hw_port_drv2halmac(enum _hw_port hwport)
1717 {
1718 	u8 port = 0;
1719 
1720 
1721 	switch (hwport) {
1722 	case HW_PORT0:
1723 		port = 0;
1724 		break;
1725 	case HW_PORT1:
1726 		port = 1;
1727 		break;
1728 	case HW_PORT2:
1729 		port = 2;
1730 		break;
1731 	case HW_PORT3:
1732 		port = 3;
1733 		break;
1734 	case HW_PORT4:
1735 		port = 4;
1736 		break;
1737 	default:
1738 		port = hwport;
1739 		break;
1740 	}
1741 
1742 	return port;
1743 }
1744 
rtw_halmac_set_mac_address(struct dvobj_priv * d,enum _hw_port hwport,u8 * addr)1745 int rtw_halmac_set_mac_address(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
1746 {
1747 	PHALMAC_ADAPTER halmac;
1748 	PHALMAC_API api;
1749 	u8 port;
1750 	HALMAC_WLAN_ADDR hwa;
1751 	HALMAC_RET_STATUS status;
1752 	int err = -1;
1753 
1754 
1755 	halmac = dvobj_to_halmac(d);
1756 	api = HALMAC_GET_API(halmac);
1757 
1758 	port = _hw_port_drv2halmac(hwport);
1759 	_rtw_memset(&hwa, 0, sizeof(hwa));
1760 	_rtw_memcpy(hwa.Address, addr, 6);
1761 
1762 	status = api->halmac_cfg_mac_addr(halmac, port, &hwa);
1763 	if (status != HALMAC_RET_SUCCESS)
1764 		goto out;
1765 
1766 	err = 0;
1767 out:
1768 	return err;
1769 }
1770 
rtw_halmac_set_bssid(struct dvobj_priv * d,enum _hw_port hwport,u8 * addr)1771 int rtw_halmac_set_bssid(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
1772 {
1773 	PHALMAC_ADAPTER halmac;
1774 	PHALMAC_API api;
1775 	u8 port;
1776 	HALMAC_WLAN_ADDR hwa;
1777 	HALMAC_RET_STATUS status;
1778 	int err = -1;
1779 
1780 	halmac = dvobj_to_halmac(d);
1781 	api = HALMAC_GET_API(halmac);
1782 	port = _hw_port_drv2halmac(hwport);
1783 
1784 	_rtw_memset(&hwa, 0, sizeof(HALMAC_WLAN_ADDR));
1785 	_rtw_memcpy(hwa.Address, addr, 6);
1786 	status = api->halmac_cfg_bssid(halmac, port, &hwa);
1787 	if (status != HALMAC_RET_SUCCESS)
1788 		goto out;
1789 
1790 	err = 0;
1791 out:
1792 	return err;
1793 }
1794 
rtw_halmac_set_bandwidth(struct dvobj_priv * d,u8 channel,u8 pri_ch_idx,u8 bw)1795 int rtw_halmac_set_bandwidth(struct dvobj_priv *d, u8 channel, u8 pri_ch_idx, u8 bw)
1796 {
1797 	PHALMAC_ADAPTER mac;
1798 	PHALMAC_API api;
1799 	HALMAC_RET_STATUS status;
1800 
1801 
1802 	mac = dvobj_to_halmac(d);
1803 	api = HALMAC_GET_API(mac);
1804 
1805 	status = api->halmac_cfg_ch_bw(mac, channel, pri_ch_idx, bw);
1806 	if (HALMAC_RET_SUCCESS != status)
1807 		return -1;
1808 
1809 	return 0;
1810 }
1811 
rtw_halmac_get_hw_value(struct dvobj_priv * d,HALMAC_HW_ID hw_id,VOID * pvalue)1812 int rtw_halmac_get_hw_value(struct dvobj_priv *d, HALMAC_HW_ID hw_id, VOID *pvalue)
1813 {
1814 	PHALMAC_ADAPTER mac;
1815 	PHALMAC_API api;
1816 	HALMAC_RET_STATUS status;
1817 
1818 
1819 	mac = dvobj_to_halmac(d);
1820 	api = HALMAC_GET_API(mac);
1821 
1822 	status = api->halmac_get_hw_value(mac, hw_id, pvalue);
1823 	if (HALMAC_RET_SUCCESS != status)
1824 		return -1;
1825 
1826 	return 0;
1827 }
1828 
rtw_halmac_dump_fifo(struct dvobj_priv * d,HAL_FIFO_SEL halmac_fifo_sel)1829 int rtw_halmac_dump_fifo(struct dvobj_priv *d, HAL_FIFO_SEL halmac_fifo_sel)
1830 {
1831 	PHALMAC_ADAPTER mac;
1832 	PHALMAC_API api;
1833 	HALMAC_RET_STATUS status;
1834 	u8 *pfifo_map = NULL;
1835 	u32 fifo_size = 0;
1836 	s8	ret = 0;
1837 
1838 	mac = dvobj_to_halmac(d);
1839 	api = HALMAC_GET_API(mac);
1840 
1841 	fifo_size = api->halmac_get_fifo_size(mac, halmac_fifo_sel);
1842 	if (fifo_size)
1843 		pfifo_map = rtw_vmalloc(fifo_size);
1844 	if (pfifo_map == NULL)
1845 		return -1;
1846 
1847 	status = api->halmac_dump_fifo(mac, halmac_fifo_sel, pfifo_map, fifo_size);
1848 	if (HALMAC_RET_SUCCESS != status) {
1849 		ret = -1;
1850 		goto _exit;
1851 	}
1852 
1853 _exit:
1854 	if (pfifo_map)
1855 		rtw_vmfree(pfifo_map, fifo_size);
1856 	return ret;
1857 
1858 }
1859 
rtw_halmac_rx_agg_switch(struct dvobj_priv * d,u8 enable)1860 int rtw_halmac_rx_agg_switch(struct dvobj_priv *d, u8 enable)
1861 {
1862 	PADAPTER adapter;
1863 	PHAL_DATA_TYPE hal;
1864 	PHALMAC_ADAPTER halmac;
1865 	PHALMAC_API api;
1866 	HALMAC_RXAGG_CFG rxaggcfg;
1867 	HALMAC_RET_STATUS status;
1868 	int err = -1;
1869 
1870 
1871 	adapter = d->padapters[IFACE_ID0];
1872 	hal = GET_HAL_DATA(adapter);
1873 	halmac = dvobj_to_halmac(d);
1874 	api = HALMAC_GET_API(halmac);
1875 	_rtw_memset((void *)&rxaggcfg, 0, sizeof(rxaggcfg));
1876 
1877 	if (_TRUE == enable) {
1878 #ifdef CONFIG_SDIO_HCI
1879 		rxaggcfg.mode = HALMAC_RX_AGG_MODE_DMA;
1880 		rxaggcfg.threshold.drv_define = 0;
1881 #elif defined(CONFIG_USB_HCI) && defined(CONFIG_USB_RX_AGGREGATION)
1882 		switch (hal->rxagg_mode) {
1883 		case RX_AGG_DISABLE:
1884 			rxaggcfg.mode = HALMAC_RX_AGG_MODE_NONE;
1885 			break;
1886 
1887 		case RX_AGG_DMA:
1888 			rxaggcfg.mode = HALMAC_RX_AGG_MODE_DMA;
1889 			if (hal->rxagg_dma_size || hal->rxagg_dma_timeout) {
1890 				rxaggcfg.threshold.drv_define = 1;
1891 				rxaggcfg.threshold.timeout = hal->rxagg_dma_timeout;
1892 				rxaggcfg.threshold.size = hal->rxagg_dma_size;
1893 			}
1894 			break;
1895 
1896 		case RX_AGG_USB:
1897 		case RX_AGG_MIX:
1898 			rxaggcfg.mode = HALMAC_RX_AGG_MODE_USB;
1899 			if (hal->rxagg_usb_size || hal->rxagg_usb_timeout) {
1900 				rxaggcfg.threshold.drv_define = 1;
1901 				rxaggcfg.threshold.timeout = hal->rxagg_usb_timeout;
1902 				rxaggcfg.threshold.size = hal->rxagg_usb_size;
1903 			}
1904 			break;
1905 		}
1906 #endif /* CONFIG_USB_HCI */
1907 	} else
1908 		rxaggcfg.mode = HALMAC_RX_AGG_MODE_NONE;
1909 
1910 	status = api->halmac_cfg_rx_aggregation(halmac, &rxaggcfg);
1911 	if (status != HALMAC_RET_SUCCESS)
1912 		goto out;
1913 
1914 	err = 0;
1915 out:
1916 	return err;
1917 }
1918 
rtw_halmac_get_wow_reason(struct dvobj_priv * d,u8 * reason)1919 int rtw_halmac_get_wow_reason(struct dvobj_priv *d, u8 *reason)
1920 {
1921 	PADAPTER adapter;
1922 	u8 val8;
1923 	int err = -1;
1924 
1925 
1926 	adapter = d->padapters[IFACE_ID0];
1927 
1928 	val8 = rtw_read8(adapter, 0x1C7);
1929 	if (val8 == 0xEA)
1930 		goto out;
1931 
1932 	*reason = val8;
1933 	err = 0;
1934 out:
1935 	return err;
1936 }
1937 
1938 /*
1939  * Description:
1940  *	Get RX driver info size. RX driver info is a small memory space between
1941  *	scriptor and RX payload.
1942  *
1943  *	+-------------------------+
1944  *	| RX descriptor           |
1945  *	| usually 24 bytes        |
1946  *	+-------------------------+
1947  *	| RX driver info          |
1948  *	| depends on driver cfg   |
1949  *	+-------------------------+
1950  *	| RX paylad               |
1951  *	|                         |
1952  *	+-------------------------+
1953  *
1954  * Parameter:
1955  *	d	pointer to struct dvobj_priv of driver
1956  *	sz	rx driver info size in bytes.
1957  *
1958  * Rteurn:
1959  *	0	Success
1960  *	other	Fail
1961  */
rtw_halmac_get_drv_info_sz(struct dvobj_priv * d,u8 * sz)1962 int rtw_halmac_get_drv_info_sz(struct dvobj_priv *d, u8 *sz)
1963 {
1964 	HALMAC_RET_STATUS status;
1965 	u8 dw = 6; /* max number */
1966 
1967 #if 0 /* TODO wait for halmac ready */
1968 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RX_, &dw);
1969 	if (status != HALMAC_RET_SUCCESS)
1970 		return -1;
1971 #endif
1972 
1973 	*sz = dw * 8;
1974 	return 0;
1975 }
rtw_halmac_get_rsvd_drv_pg_bndy(struct dvobj_priv * dvobj,u16 * drv_pg)1976 int rtw_halmac_get_rsvd_drv_pg_bndy(struct dvobj_priv *dvobj, u16 *drv_pg)
1977 {
1978 	HALMAC_RET_STATUS status;
1979 	PHALMAC_ADAPTER halmac = dvobj_to_halmac(dvobj);
1980 	PHALMAC_API api = HALMAC_GET_API(halmac);
1981 
1982 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RSVD_PG_BNDY, drv_pg);
1983 	if (status != HALMAC_RET_SUCCESS)
1984 		return -1;
1985 
1986 	return 0;
1987 }
1988 
rtw_halmac_download_rsvd_page(struct dvobj_priv * dvobj,u16 page_idx,u8 * pbuf,u8 length)1989 int rtw_halmac_download_rsvd_page(struct dvobj_priv *dvobj, u16 page_idx, u8 *pbuf, u8 length)
1990 {
1991 	HALMAC_RET_STATUS status = HALMAC_RET_SUCCESS;
1992 	PHALMAC_ADAPTER halmac = dvobj_to_halmac(dvobj);
1993 	PHALMAC_API api = HALMAC_GET_API(halmac);
1994 
1995 	/*status = api->halmac_get_hw_value(halmac, HALMAC_HW_RSVD_PG_BNDY, drv_pg);*/
1996 	if (status != HALMAC_RET_SUCCESS)
1997 		return -1;
1998 
1999 	return 0;
2000 
2001 }
2002 
2003 #ifdef CONFIG_SDIO_HCI
2004 
2005 /*
2006  * Description:
2007  *	Update queue allocated page number to driver
2008  *
2009  * Parameter:
2010  *	d	pointer to struct dvobj_priv of driver
2011  *
2012  * Rteurn:
2013  *	0	Success, "page" is valid.
2014  *	others	Fail, "page" is invalid.
2015  */
rtw_halmac_query_tx_page_num(struct dvobj_priv * d)2016 int rtw_halmac_query_tx_page_num(struct dvobj_priv *d)
2017 {
2018 	PADAPTER adapter;
2019 	struct halmacpriv *hmpriv;
2020 	PHALMAC_ADAPTER halmac;
2021 	PHALMAC_API api;
2022 	HALMAC_RQPN_MAP rqpn;
2023 	HALMAC_DMA_MAPPING dmaqueue;
2024 	HALMAC_TXFF_ALLOCATION fifosize;
2025 	HALMAC_RET_STATUS status;
2026 	u8 i;
2027 
2028 
2029 	adapter = d->padapters[IFACE_ID0];
2030 	hmpriv = &d->hmpriv;
2031 	halmac = dvobj_to_halmac(d);
2032 	api = HALMAC_GET_API(halmac);
2033 	_rtw_memset((void *)&rqpn, 0, sizeof(rqpn));
2034 	_rtw_memset((void *)&fifosize, 0, sizeof(fifosize));
2035 
2036 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RQPN_MAPPING, &rqpn);
2037 	if (status != HALMAC_RET_SUCCESS)
2038 		return -1;
2039 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_TXFF_ALLOCATION, &fifosize);
2040 	if (status != HALMAC_RET_SUCCESS)
2041 		return -1;
2042 
2043 	for (i = 0; i < HW_QUEUE_ENTRY; i++) {
2044 		hmpriv->txpage[i] = 0;
2045 
2046 		/* Driver index mapping to HALMAC DMA queue */
2047 		dmaqueue = HALMAC_DMA_MAPPING_UNDEFINE;
2048 		switch (i) {
2049 		case VO_QUEUE_INX:
2050 			dmaqueue = rqpn.dma_map_vo;
2051 			break;
2052 		case VI_QUEUE_INX:
2053 			dmaqueue = rqpn.dma_map_vi;
2054 			break;
2055 		case BE_QUEUE_INX:
2056 			dmaqueue = rqpn.dma_map_be;
2057 			break;
2058 		case BK_QUEUE_INX:
2059 			dmaqueue = rqpn.dma_map_bk;
2060 			break;
2061 		case MGT_QUEUE_INX:
2062 			dmaqueue = rqpn.dma_map_mg;
2063 			break;
2064 		case HIGH_QUEUE_INX:
2065 			dmaqueue = rqpn.dma_map_hi;
2066 			break;
2067 		case BCN_QUEUE_INX:
2068 		case TXCMD_QUEUE_INX:
2069 			/* Unlimited */
2070 			hmpriv->txpage[i] = 0xFFFF;
2071 			continue;
2072 		}
2073 
2074 		switch (dmaqueue) {
2075 		case HALMAC_DMA_MAPPING_EXTRA:
2076 			hmpriv->txpage[i] = fifosize.extra_queue_pg_num;
2077 			break;
2078 		case HALMAC_DMA_MAPPING_LOW:
2079 			hmpriv->txpage[i] = fifosize.low_queue_pg_num;
2080 			break;
2081 		case HALMAC_DMA_MAPPING_NORMAL:
2082 			hmpriv->txpage[i] = fifosize.normal_queue_pg_num;
2083 			break;
2084 		case HALMAC_DMA_MAPPING_HIGH:
2085 			hmpriv->txpage[i] = fifosize.high_queue_pg_num;
2086 			break;
2087 		case HALMAC_DMA_MAPPING_UNDEFINE:
2088 			break;
2089 		}
2090 		hmpriv->txpage[i] += fifosize.pub_queue_pg_num;
2091 	}
2092 
2093 	return 0;
2094 }
2095 
2096 /*
2097  * Description:
2098  *	Get specific queue allocated page number
2099  *
2100  * Parameter:
2101  *	d	pointer to struct dvobj_priv of driver
2102  *	queue	target queue to query, VO/VI/BE/BK/.../TXCMD_QUEUE_INX
2103  *	page	return allocated page number
2104  *
2105  * Rteurn:
2106  *	0	Success, "page" is valid.
2107  *	others	Fail, "page" is invalid.
2108  */
rtw_halmac_get_tx_queue_page_num(struct dvobj_priv * d,u8 queue,u32 * page)2109 int rtw_halmac_get_tx_queue_page_num(struct dvobj_priv *d, u8 queue, u32 *page)
2110 {
2111 	*page = 0;
2112 	if (queue < HW_QUEUE_ENTRY)
2113 		*page = d->hmpriv.txpage[queue];
2114 
2115 	return 0;
2116 }
2117 
2118 /*
2119  * Return:
2120  *	address for SDIO command
2121  */
rtw_halmac_sdio_get_tx_addr(struct dvobj_priv * d,u8 * desc,u32 size)2122 u32 rtw_halmac_sdio_get_tx_addr(struct dvobj_priv *d, u8 *desc, u32 size)
2123 {
2124 	PHALMAC_ADAPTER mac;
2125 	PHALMAC_API api;
2126 	HALMAC_RET_STATUS status;
2127 	u32 addr;
2128 
2129 
2130 	mac = dvobj_to_halmac(d);
2131 	api = HALMAC_GET_API(mac);
2132 
2133 	status = api->halmac_get_sdio_tx_addr(mac, desc, size, &addr);
2134 	if (HALMAC_RET_SUCCESS != status)
2135 		return 0;
2136 
2137 	return addr;
2138 }
2139 
rtw_halmac_sdio_tx_allowed(struct dvobj_priv * d,u8 * buf,u32 size)2140 int rtw_halmac_sdio_tx_allowed(struct dvobj_priv *d, u8 *buf, u32 size)
2141 {
2142 	PHALMAC_ADAPTER mac;
2143 	PHALMAC_API api;
2144 	HALMAC_RET_STATUS status;
2145 
2146 
2147 	mac = dvobj_to_halmac(d);
2148 	api = HALMAC_GET_API(mac);
2149 
2150 	status = api->halmac_tx_allowed_sdio(mac, buf, size);
2151 	if (HALMAC_RET_SUCCESS != status)
2152 		return -1;
2153 
2154 	return 0;
2155 }
2156 
rtw_halmac_sdio_get_rx_addr(struct dvobj_priv * d,u8 * seq)2157 u32 rtw_halmac_sdio_get_rx_addr(struct dvobj_priv *d, u8 *seq)
2158 {
2159 	u8 id;
2160 
2161 #define RTW_SDIO_ADDR_RX_RX0FF_PRFIX	0x0E000
2162 #define RTW_SDIO_ADDR_RX_RX0FF_GEN(a)	(RTW_SDIO_ADDR_RX_RX0FF_PRFIX|(a&0x3))
2163 
2164 	id = *seq;
2165 	(*seq)++;
2166 	return RTW_SDIO_ADDR_RX_RX0FF_GEN(id);
2167 }
2168 #endif /* CONFIG_SDIO_HCI */
2169 
2170 #ifdef CONFIG_USB_HCI
rtw_halmac_usb_get_bulkout_id(struct dvobj_priv * d,u8 * buf,u32 size)2171 u8 rtw_halmac_usb_get_bulkout_id(struct dvobj_priv *d, u8 *buf, u32 size)
2172 {
2173 	PHALMAC_ADAPTER mac;
2174 	PHALMAC_API api;
2175 	HALMAC_RET_STATUS status;
2176 	u8 bulkout_id;
2177 
2178 
2179 	mac = dvobj_to_halmac(d);
2180 	api = HALMAC_GET_API(mac);
2181 
2182 	status = api->halmac_get_usb_bulkout_id(mac, buf, size, &bulkout_id);
2183 	if (HALMAC_RET_SUCCESS != status)
2184 		return 0;
2185 
2186 	return bulkout_id;
2187 }
2188 
_usb_mode_drv2halmac(enum RTW_USB_SPEED usb_mode)2189 static inline HALMAC_USB_MODE _usb_mode_drv2halmac(enum RTW_USB_SPEED usb_mode)
2190 {
2191 	HALMAC_USB_MODE halmac_usb_mode = HALMAC_USB_MODE_U2;
2192 
2193 	switch (usb_mode) {
2194 	case RTW_USB_SPEED_2:
2195 		halmac_usb_mode = HALMAC_USB_MODE_U2;
2196 		break;
2197 	case RTW_USB_SPEED_3:
2198 		halmac_usb_mode = HALMAC_USB_MODE_U3;
2199 		break;
2200 	default:
2201 		halmac_usb_mode = HALMAC_USB_MODE_U2;
2202 		break;
2203 	}
2204 
2205 	return halmac_usb_mode;
2206 }
2207 
rtw_halmac_switch_usb_mode(struct dvobj_priv * d,enum RTW_USB_SPEED usb_mode)2208 u8 rtw_halmac_switch_usb_mode(struct dvobj_priv *d, enum RTW_USB_SPEED usb_mode)
2209 {
2210 	PHALMAC_ADAPTER mac;
2211 	PHALMAC_API api;
2212 	HALMAC_RET_STATUS status;
2213 	PADAPTER adapter;
2214 	HALMAC_USB_MODE halmac_usb_mode;
2215 
2216 	adapter = d->padapters[IFACE_ID0];
2217 	mac = dvobj_to_halmac(d);
2218 	api = HALMAC_GET_API(mac);
2219 	halmac_usb_mode = _usb_mode_drv2halmac(usb_mode);
2220 	status = api->halmac_set_hw_value(mac, HALMAC_HW_USB_MODE, (void *)&halmac_usb_mode);
2221 
2222 	if (HALMAC_RET_SUCCESS != status)
2223 		return _FAIL;
2224 
2225 	return _SUCCESS;
2226 }
2227 #endif /* CONFIG_USB_HCI */
2228