xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/rtl8723bs/hal/hal_halmac.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2015 - 2017 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 #define DEFAULT_INDICATOR_TIMELMT	1000	/* ms */
22 #define MSG_PREFIX			"[HALMAC]"
23 
24 /*#define RTW_HALMAC_DLFW_MEM_NO_STOP_TX*/
25 
26 /*
27  * Driver API for HALMAC operations
28  */
29 
30 #ifdef CONFIG_SDIO_HCI
31 #include <rtw_sdio.h>
32 
_halmac_mac_reg_page0_chk(const char * func,struct dvobj_priv * dvobj,u32 offset)33 static u8 _halmac_mac_reg_page0_chk(const char *func, struct dvobj_priv *dvobj, u32 offset)
34 {
35 #if defined(CONFIG_IO_CHECK_IN_ANA_LOW_CLK) && defined(CONFIG_LPS_LCLK)
36 	struct pwrctrl_priv *pwrpriv = &dvobj->pwrctl_priv;
37 	u32 mac_reg_offset = 0;
38 
39 	if (pwrpriv->pwr_mode == PS_MODE_ACTIVE)
40 		return _TRUE;
41 
42 	if (pwrpriv->lps_level == LPS_NORMAL)
43 		return _TRUE;
44 
45 	if (pwrpriv->rpwm >= PS_STATE_S2)
46 		return _TRUE;
47 
48 	if (offset & (WLAN_IOREG_DEVICE_ID << 13))  { /*WLAN_IOREG_OFFSET*/
49 		mac_reg_offset = offset & HALMAC_WLAN_MAC_REG_MSK;
50 		if (mac_reg_offset < 0x100) {
51 			RTW_ERR(FUNC_ADPT_FMT
52 				"access MAC REG -0x%04x in PS-mode:0x%02x (rpwm:0x%02x, lps_level:0x%02x)\n",
53 				FUNC_ADPT_ARG(dvobj_get_primary_adapter(dvobj)), mac_reg_offset,
54 				pwrpriv->pwr_mode, pwrpriv->rpwm, pwrpriv->lps_level);
55 			rtw_warn_on(1);
56 			return _FALSE;
57 		}
58 	}
59 #endif
60 	return _TRUE;
61 }
62 
_halmac_sdio_cmd52_read(void * p,u32 offset)63 static u8 _halmac_sdio_cmd52_read(void *p, u32 offset)
64 {
65 	struct dvobj_priv *d;
66 	u8 val;
67 	u8 ret;
68 
69 
70 	d = (struct dvobj_priv *)p;
71 	_halmac_mac_reg_page0_chk(__func__, d, offset);
72 	ret = rtw_sdio_read_cmd52(d, offset, &val, 1);
73 	if (_FAIL == ret) {
74 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
75 		return SDIO_ERR_VAL8;
76 	}
77 
78 	return val;
79 }
80 
_halmac_sdio_cmd52_write(void * p,u32 offset,u8 val)81 static void _halmac_sdio_cmd52_write(void *p, u32 offset, u8 val)
82 {
83 	struct dvobj_priv *d;
84 	u8 ret;
85 
86 
87 	d = (struct dvobj_priv *)p;
88 	_halmac_mac_reg_page0_chk(__func__, d, offset);
89 	ret = rtw_sdio_write_cmd52(d, offset, &val, 1);
90 	if (_FAIL == ret)
91 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
92 }
93 
_halmac_sdio_reg_read_8(void * p,u32 offset)94 static u8 _halmac_sdio_reg_read_8(void *p, u32 offset)
95 {
96 	struct dvobj_priv *d;
97 	u8 *pbuf;
98 	u8 val;
99 	u8 ret;
100 
101 
102 	d = (struct dvobj_priv *)p;
103 	val = SDIO_ERR_VAL8;
104 	_halmac_mac_reg_page0_chk(__func__, d, offset);
105 	pbuf = rtw_zmalloc(1);
106 	if (!pbuf)
107 		return val;
108 
109 	ret = rtw_sdio_read_cmd53(d, offset, pbuf, 1);
110 	if (ret == _FAIL) {
111 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
112 		goto exit;
113 	}
114 
115 	val = *pbuf;
116 
117 exit:
118 	rtw_mfree(pbuf, 1);
119 
120 	return val;
121 }
122 
_halmac_sdio_reg_read_16(void * p,u32 offset)123 static u16 _halmac_sdio_reg_read_16(void *p, u32 offset)
124 {
125 	struct dvobj_priv *d;
126 	u8 *pbuf;
127 	u16 val;
128 	u8 ret;
129 
130 
131 	d = (struct dvobj_priv *)p;
132 	val = SDIO_ERR_VAL16;
133 	_halmac_mac_reg_page0_chk(__func__, d, offset);
134 	pbuf = rtw_zmalloc(2);
135 	if (!pbuf)
136 		return val;
137 
138 	ret = rtw_sdio_read_cmd53(d, offset, pbuf, 2);
139 	if (ret == _FAIL) {
140 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
141 		goto exit;
142 	}
143 
144 	val = le16_to_cpu(*(u16 *)pbuf);
145 
146 exit:
147 	rtw_mfree(pbuf, 2);
148 
149 	return val;
150 }
151 
_halmac_sdio_reg_read_32(void * p,u32 offset)152 static u32 _halmac_sdio_reg_read_32(void *p, u32 offset)
153 {
154 	struct dvobj_priv *d;
155 	u8 *pbuf;
156 	u32 val;
157 	u8 ret;
158 
159 
160 	d = (struct dvobj_priv *)p;
161 	val = SDIO_ERR_VAL32;
162 	_halmac_mac_reg_page0_chk(__func__, d, offset);
163 	pbuf = rtw_zmalloc(4);
164 	if (!pbuf)
165 		return val;
166 
167 	ret = rtw_sdio_read_cmd53(d, offset, pbuf, 4);
168 	if (ret == _FAIL) {
169 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
170 		goto exit;
171 	}
172 
173 	val = le32_to_cpu(*(u32 *)pbuf);
174 
175 exit:
176 	rtw_mfree(pbuf, 4);
177 
178 	return val;
179 }
180 
_halmac_sdio_reg_read_n(void * p,u32 offset,u32 size,u8 * data)181 static u8 _halmac_sdio_reg_read_n(void *p, u32 offset, u32 size, u8 *data)
182 {
183 	struct dvobj_priv *d = (struct dvobj_priv *)p;
184 	PSDIO_DATA psdio = &d->intf_data;
185 	u8 *pbuf;
186 	u8 ret;
187 	u8 rst = _FALSE;
188 	u32 sdio_read_size;
189 
190 
191 	sdio_read_size = RND4(size);
192 	if (sdio_read_size > psdio->block_transfer_len)
193 		sdio_read_size = _RND(sdio_read_size, psdio->block_transfer_len);
194 
195 	pbuf = rtw_zmalloc(sdio_read_size);
196 	if ((!pbuf) || (!data))
197 		return rst;
198 
199 	ret = rtw_sdio_read_cmd53(d, offset, pbuf, sdio_read_size);
200 	if (ret == _FAIL) {
201 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
202 		goto exit;
203 	}
204 
205 	_rtw_memcpy(data, pbuf, size);
206 	rst = _TRUE;
207 exit:
208 	rtw_mfree(pbuf, sdio_read_size);
209 
210 	return rst;
211 }
212 
_halmac_sdio_reg_write_8(void * p,u32 offset,u8 val)213 static void _halmac_sdio_reg_write_8(void *p, u32 offset, u8 val)
214 {
215 	struct dvobj_priv *d;
216 	u8 *pbuf;
217 	u8 ret;
218 
219 
220 	d = (struct dvobj_priv *)p;
221 	_halmac_mac_reg_page0_chk(__func__, d, offset);
222 	pbuf = rtw_zmalloc(1);
223 	if (!pbuf)
224 		return;
225 	_rtw_memcpy(pbuf, &val, 1);
226 
227 	ret = rtw_sdio_write_cmd53(d, offset, pbuf, 1);
228 	if (ret == _FAIL)
229 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
230 
231 	rtw_mfree(pbuf, 1);
232 }
233 
_halmac_sdio_reg_write_16(void * p,u32 offset,u16 val)234 static void _halmac_sdio_reg_write_16(void *p, u32 offset, u16 val)
235 {
236 	struct dvobj_priv *d;
237 	u8 *pbuf;
238 	u8 ret;
239 
240 
241 	d = (struct dvobj_priv *)p;
242 	_halmac_mac_reg_page0_chk(__func__, d, offset);
243 	val = cpu_to_le16(val);
244 	pbuf = rtw_zmalloc(2);
245 	if (!pbuf)
246 		return;
247 	_rtw_memcpy(pbuf, &val, 2);
248 
249 	ret = rtw_sdio_write_cmd53(d, offset, pbuf, 2);
250 	if (ret == _FAIL)
251 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
252 
253 	rtw_mfree(pbuf, 2);
254 }
255 
_halmac_sdio_reg_write_32(void * p,u32 offset,u32 val)256 static void _halmac_sdio_reg_write_32(void *p, u32 offset, u32 val)
257 {
258 	struct dvobj_priv *d;
259 	u8 *pbuf;
260 	u8 ret;
261 
262 
263 	d = (struct dvobj_priv *)p;
264 	_halmac_mac_reg_page0_chk(__func__, d, offset);
265 	val = cpu_to_le32(val);
266 	pbuf = rtw_zmalloc(4);
267 	if (!pbuf)
268 		return;
269 	_rtw_memcpy(pbuf, &val, 4);
270 
271 	ret = rtw_sdio_write_cmd53(d, offset, pbuf, 4);
272 	if (ret == _FAIL)
273 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
274 
275 	rtw_mfree(pbuf, 4);
276 }
277 
_halmac_sdio_read_cia(void * p,u32 offset)278 static u8 _halmac_sdio_read_cia(void *p, u32 offset)
279 {
280 	struct dvobj_priv *d;
281 	u8 data = 0;
282 	u8 ret;
283 
284 
285 	d = (struct dvobj_priv *)p;
286 
287 	ret = rtw_sdio_f0_read(d, offset, &data, 1);
288 	if (ret == _FAIL)
289 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
290 
291 	return data;
292 }
293 
294 #else /* !CONFIG_SDIO_HCI */
295 
_halmac_reg_read_8(void * p,u32 offset)296 static u8 _halmac_reg_read_8(void *p, u32 offset)
297 {
298 	struct dvobj_priv *d;
299 	PADAPTER adapter;
300 
301 
302 	d = (struct dvobj_priv *)p;
303 	adapter = dvobj_get_primary_adapter(d);
304 
305 	return rtw_read8(adapter, offset);
306 }
307 
_halmac_reg_read_16(void * p,u32 offset)308 static u16 _halmac_reg_read_16(void *p, u32 offset)
309 {
310 	struct dvobj_priv *d;
311 	PADAPTER adapter;
312 
313 
314 	d = (struct dvobj_priv *)p;
315 	adapter = dvobj_get_primary_adapter(d);
316 
317 	return rtw_read16(adapter, offset);
318 }
319 
_halmac_reg_read_32(void * p,u32 offset)320 static u32 _halmac_reg_read_32(void *p, u32 offset)
321 {
322 	struct dvobj_priv *d;
323 	PADAPTER adapter;
324 
325 
326 	d = (struct dvobj_priv *)p;
327 	adapter = dvobj_get_primary_adapter(d);
328 
329 	return rtw_read32(adapter, offset);
330 }
331 
_halmac_reg_write_8(void * p,u32 offset,u8 val)332 static void _halmac_reg_write_8(void *p, u32 offset, u8 val)
333 {
334 	struct dvobj_priv *d;
335 	PADAPTER adapter;
336 	int err;
337 
338 
339 	d = (struct dvobj_priv *)p;
340 	adapter = dvobj_get_primary_adapter(d);
341 
342 	err = rtw_write8(adapter, offset, val);
343 	if (err == _FAIL)
344 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
345 }
346 
_halmac_reg_write_16(void * p,u32 offset,u16 val)347 static void _halmac_reg_write_16(void *p, u32 offset, u16 val)
348 {
349 	struct dvobj_priv *d;
350 	PADAPTER adapter;
351 	int err;
352 
353 
354 	d = (struct dvobj_priv *)p;
355 	adapter = dvobj_get_primary_adapter(d);
356 
357 	err = rtw_write16(adapter, offset, val);
358 	if (err == _FAIL)
359 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
360 }
361 
_halmac_reg_write_32(void * p,u32 offset,u32 val)362 static void _halmac_reg_write_32(void *p, u32 offset, u32 val)
363 {
364 	struct dvobj_priv *d;
365 	PADAPTER adapter;
366 	int err;
367 
368 
369 	d = (struct dvobj_priv *)p;
370 	adapter = dvobj_get_primary_adapter(d);
371 
372 	err = rtw_write32(adapter, offset, val);
373 	if (err == _FAIL)
374 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
375 }
376 #endif /* !CONFIG_SDIO_HCI */
377 
_halmac_mfree(void * p,void * buffer,u32 size)378 static u8 _halmac_mfree(void *p, void *buffer, u32 size)
379 {
380 	rtw_mfree(buffer, size);
381 	return _TRUE;
382 }
383 
_halmac_malloc(void * p,u32 size)384 static void *_halmac_malloc(void *p, u32 size)
385 {
386 	return rtw_zmalloc(size);
387 }
388 
_halmac_memcpy(void * p,void * dest,void * src,u32 size)389 static u8 _halmac_memcpy(void *p, void *dest, void *src, u32 size)
390 {
391 	_rtw_memcpy(dest, src, size);
392 	return _TRUE;
393 }
394 
_halmac_memset(void * p,void * addr,u8 value,u32 size)395 static u8 _halmac_memset(void *p, void *addr, u8 value, u32 size)
396 {
397 	_rtw_memset(addr, value, size);
398 	return _TRUE;
399 }
400 
_halmac_udelay(void * p,u32 us)401 static void _halmac_udelay(void *p, u32 us)
402 {
403 	rtw_udelay_os(us);
404 }
405 
_halmac_mutex_init(void * p,HALMAC_MUTEX * pMutex)406 static u8 _halmac_mutex_init(void *p, HALMAC_MUTEX *pMutex)
407 {
408 	_rtw_mutex_init(pMutex);
409 	return _TRUE;
410 }
411 
_halmac_mutex_deinit(void * p,HALMAC_MUTEX * pMutex)412 static u8 _halmac_mutex_deinit(void *p, HALMAC_MUTEX *pMutex)
413 {
414 	_rtw_mutex_free(pMutex);
415 	return _TRUE;
416 }
417 
_halmac_mutex_lock(void * p,HALMAC_MUTEX * pMutex)418 static u8 _halmac_mutex_lock(void *p, HALMAC_MUTEX *pMutex)
419 {
420 	int err;
421 
422 	err = _enter_critical_mutex(pMutex, NULL);
423 	if (err)
424 		return _FALSE;
425 
426 	return _TRUE;
427 }
428 
_halmac_mutex_unlock(void * p,HALMAC_MUTEX * pMutex)429 static u8 _halmac_mutex_unlock(void *p, HALMAC_MUTEX *pMutex)
430 {
431 	_exit_critical_mutex(pMutex, NULL);
432 	return _TRUE;
433 }
434 
_halmac_msg_print(void * p,u32 msg_type,u8 msg_level,s8 * fmt,...)435 static u8 _halmac_msg_print(void *p, u32 msg_type, u8 msg_level, s8 *fmt, ...)
436 {
437 #define MSG_LEN		100
438 	va_list args;
439 	u8 str[MSG_LEN] = {0};
440 	int err;
441 	u8 ret = _TRUE;
442 
443 
444 	str[0] = '\n';
445 	va_start(args, fmt);
446 	err = vsnprintf(str, MSG_LEN, fmt, args);
447 	va_end(args);
448 
449 	/* An output error is encountered */
450 	if (err < 0)
451 		return _FALSE;
452 	/* Output may be truncated due to size limit */
453 	if ((err == (MSG_LEN - 1)) && (str[MSG_LEN - 2] != '\n'))
454 		ret = _FALSE;
455 
456 	if (msg_level == HALMAC_DBG_ALWAYS)
457 		RTW_PRINT(MSG_PREFIX "%s", str);
458 	else if (msg_level <= HALMAC_DBG_ERR)
459 		RTW_ERR(MSG_PREFIX "%s", str);
460 	else if (msg_level <= HALMAC_DBG_WARN)
461 		RTW_WARN(MSG_PREFIX "%s", str);
462 	else
463 		RTW_DBG(MSG_PREFIX "%s", str);
464 
465 	return ret;
466 }
467 
_halmac_buff_print(void * p,u32 msg_type,u8 msg_level,s8 * buf,u32 size)468 static u8 _halmac_buff_print(void *p, u32 msg_type, u8 msg_level, s8 *buf, u32 size)
469 {
470 	if (msg_level <= HALMAC_DBG_WARN)
471 		RTW_INFO_DUMP(MSG_PREFIX, buf, size);
472 	else
473 		RTW_DBG_DUMP(MSG_PREFIX, buf, size);
474 
475 	return _TRUE;
476 }
477 
478 
479 const char *const RTW_HALMAC_FEATURE_NAME[] = {
480 	"HALMAC_FEATURE_CFG_PARA",
481 	"HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE",
482 	"HALMAC_FEATURE_DUMP_LOGICAL_EFUSE",
483 	"HALMAC_FEATURE_UPDATE_PACKET",
484 	"HALMAC_FEATURE_UPDATE_DATAPACK",
485 	"HALMAC_FEATURE_RUN_DATAPACK",
486 	"HALMAC_FEATURE_CHANNEL_SWITCH",
487 	"HALMAC_FEATURE_IQK",
488 	"HALMAC_FEATURE_POWER_TRACKING",
489 	"HALMAC_FEATURE_PSD",
490 	"HALMAC_FEATURE_FW_SNDING",
491 	"HALMAC_FEATURE_ALL"
492 };
493 
is_valid_id_status(HALMAC_FEATURE_ID id,HALMAC_CMD_PROCESS_STATUS status)494 static inline u8 is_valid_id_status(HALMAC_FEATURE_ID id, HALMAC_CMD_PROCESS_STATUS status)
495 {
496 	switch (id) {
497 	case HALMAC_FEATURE_CFG_PARA:
498 		RTW_DBG("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
499 		break;
500 	case HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE:
501 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
502 		if (HALMAC_CMD_PROCESS_DONE != status)
503 			RTW_INFO("%s: id(%d) unspecified status(%d)!\n",
504 				 __FUNCTION__, id, status);
505 		break;
506 	case HALMAC_FEATURE_DUMP_LOGICAL_EFUSE:
507 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
508 		if (HALMAC_CMD_PROCESS_DONE != status)
509 			RTW_INFO("%s: id(%d) unspecified status(%d)!\n",
510 				 __FUNCTION__, id, status);
511 		break;
512 	case HALMAC_FEATURE_UPDATE_PACKET:
513 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
514 		break;
515 	case HALMAC_FEATURE_UPDATE_DATAPACK:
516 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
517 		break;
518 	case HALMAC_FEATURE_RUN_DATAPACK:
519 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
520 		break;
521 	case HALMAC_FEATURE_CHANNEL_SWITCH:
522 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
523 		break;
524 	case HALMAC_FEATURE_IQK:
525 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
526 		break;
527 	case HALMAC_FEATURE_POWER_TRACKING:
528 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
529 		break;
530 	case HALMAC_FEATURE_PSD:
531 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
532 		break;
533 	case HALMAC_FEATURE_FW_SNDING:
534 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
535 		break;
536 	case HALMAC_FEATURE_ALL:
537 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
538 		break;
539 	default:
540 		RTW_ERR("%s: unknown feature id(%d)\n", __FUNCTION__, id);
541 		return _FALSE;
542 	}
543 
544 	return _TRUE;
545 }
546 
init_halmac_event_with_waittime(struct dvobj_priv * d,HALMAC_FEATURE_ID id,u8 * buf,u32 size,u32 time)547 static int init_halmac_event_with_waittime(struct dvobj_priv *d, HALMAC_FEATURE_ID id, u8 *buf, u32 size, u32 time)
548 {
549 	struct submit_ctx *sctx;
550 
551 
552 	if (!d->hmpriv.indicator[id].sctx) {
553 		sctx = (struct submit_ctx *)rtw_zmalloc(sizeof(*sctx));
554 		if (!sctx)
555 			return -1;
556 	} else {
557 		RTW_WARN("%s: id(%d) sctx is not NULL!!\n", __FUNCTION__, id);
558 		sctx = d->hmpriv.indicator[id].sctx;
559 		d->hmpriv.indicator[id].sctx = NULL;
560 	}
561 
562 	rtw_sctx_init(sctx, time);
563 	d->hmpriv.indicator[id].buffer = buf;
564 	d->hmpriv.indicator[id].buf_size = size;
565 	d->hmpriv.indicator[id].ret_size = 0;
566 	d->hmpriv.indicator[id].status = 0;
567 	/* fill sctx at least to sure other variables are all ready! */
568 	d->hmpriv.indicator[id].sctx = sctx;
569 
570 	return 0;
571 }
572 
init_halmac_event(struct dvobj_priv * d,HALMAC_FEATURE_ID id,u8 * buf,u32 size)573 static inline int init_halmac_event(struct dvobj_priv *d, HALMAC_FEATURE_ID id, u8 *buf, u32 size)
574 {
575 	return init_halmac_event_with_waittime(d, id, buf, size, DEFAULT_INDICATOR_TIMELMT);
576 }
577 
free_halmac_event(struct dvobj_priv * d,HALMAC_FEATURE_ID id)578 static void free_halmac_event(struct dvobj_priv *d, HALMAC_FEATURE_ID id)
579 {
580 	struct submit_ctx *sctx;
581 
582 
583 	if (!d->hmpriv.indicator[id].sctx)
584 		return;
585 
586 	sctx = d->hmpriv.indicator[id].sctx;
587 	d->hmpriv.indicator[id].sctx = NULL;
588 	rtw_mfree((u8 *)sctx, sizeof(*sctx));
589 }
590 
wait_halmac_event(struct dvobj_priv * d,HALMAC_FEATURE_ID id)591 static int wait_halmac_event(struct dvobj_priv *d, HALMAC_FEATURE_ID id)
592 {
593 	PHALMAC_ADAPTER mac;
594 	PHALMAC_API api;
595 	struct submit_ctx *sctx;
596 	int ret;
597 
598 
599 	sctx = d->hmpriv.indicator[id].sctx;
600 	if (!sctx)
601 		return -1;
602 
603 	ret = rtw_sctx_wait(sctx, RTW_HALMAC_FEATURE_NAME[id]);
604 	free_halmac_event(d, id);
605 	if (_SUCCESS == ret)
606 		return 0;
607 
608 	/* timeout! We have to reset halmac state */
609 	RTW_ERR("%s: Wait id(%d, %s) TIMEOUT! Reset HALMAC state!\n",
610 		__FUNCTION__, id, RTW_HALMAC_FEATURE_NAME[id]);
611 	mac = dvobj_to_halmac(d);
612 	api = HALMAC_GET_API(mac);
613 	api->halmac_reset_feature(mac, id);
614 
615 	return -1;
616 }
617 
618 /*
619  * Return:
620  *	Always return _TRUE, HALMAC don't care the return value.
621  */
_halmac_event_indication(void * p,HALMAC_FEATURE_ID feature_id,HALMAC_CMD_PROCESS_STATUS process_status,u8 * buf,u32 size)622 static u8 _halmac_event_indication(void *p, HALMAC_FEATURE_ID feature_id, HALMAC_CMD_PROCESS_STATUS process_status, u8 *buf, u32 size)
623 {
624 	struct dvobj_priv *d;
625 	PADAPTER adapter;
626 	PHAL_DATA_TYPE hal;
627 	struct halmac_indicator *tbl, *indicator;
628 	struct submit_ctx *sctx;
629 	u32 cpsz;
630 	u8 ret;
631 
632 
633 	d = (struct dvobj_priv *)p;
634 	adapter = dvobj_get_primary_adapter(d);
635 	hal = GET_HAL_DATA(adapter);
636 	tbl = d->hmpriv.indicator;
637 
638 	/* Filter(Skip) middle status indication */
639 	ret = is_valid_id_status(feature_id, process_status);
640 	if (_FALSE == ret)
641 		goto exit;
642 
643 	indicator = &tbl[feature_id];
644 	indicator->status = process_status;
645 	indicator->ret_size = size;
646 	if (!indicator->sctx) {
647 		RTW_WARN("%s: No feature id(%d, %s) waiting!!\n", __FUNCTION__, feature_id, RTW_HALMAC_FEATURE_NAME[feature_id]);
648 		goto exit;
649 	}
650 	sctx = indicator->sctx;
651 
652 	if (HALMAC_CMD_PROCESS_ERROR == process_status) {
653 		RTW_ERR("%s: Something wrong id(%d, %s)!!\n", __FUNCTION__, feature_id, RTW_HALMAC_FEATURE_NAME[feature_id]);
654 		rtw_sctx_done_err(&sctx, RTW_SCTX_DONE_UNKNOWN);
655 		goto exit;
656 	}
657 
658 	if (size > indicator->buf_size) {
659 		RTW_WARN("%s: id(%d, %s) buffer is not enough(%d<%d), data will be truncated!\n",
660 			 __FUNCTION__, feature_id, RTW_HALMAC_FEATURE_NAME[feature_id], indicator->buf_size, size);
661 		cpsz = indicator->buf_size;
662 	} else {
663 		cpsz = size;
664 	}
665 	if (cpsz && indicator->buffer)
666 		_rtw_memcpy(indicator->buffer, buf, cpsz);
667 
668 	rtw_sctx_done(&sctx);
669 
670 exit:
671 	return _TRUE;
672 }
673 
674 HALMAC_PLATFORM_API rtw_halmac_platform_api = {
675 	/* R/W register */
676 #ifdef CONFIG_SDIO_HCI
677 	.SDIO_CMD52_READ = _halmac_sdio_cmd52_read,
678 	.SDIO_CMD53_READ_8 = _halmac_sdio_reg_read_8,
679 	.SDIO_CMD53_READ_16 = _halmac_sdio_reg_read_16,
680 	.SDIO_CMD53_READ_32 = _halmac_sdio_reg_read_32,
681 	.SDIO_CMD53_READ_N = _halmac_sdio_reg_read_n,
682 	.SDIO_CMD52_WRITE = _halmac_sdio_cmd52_write,
683 	.SDIO_CMD53_WRITE_8 = _halmac_sdio_reg_write_8,
684 	.SDIO_CMD53_WRITE_16 = _halmac_sdio_reg_write_16,
685 	.SDIO_CMD53_WRITE_32 = _halmac_sdio_reg_write_32,
686 	.SDIO_CMD52_CIA_READ = _halmac_sdio_read_cia,
687 #endif /* CONFIG_SDIO_HCI */
688 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCIE_HCI)
689 	.REG_READ_8 = _halmac_reg_read_8,
690 	.REG_READ_16 = _halmac_reg_read_16,
691 	.REG_READ_32 = _halmac_reg_read_32,
692 	.REG_WRITE_8 = _halmac_reg_write_8,
693 	.REG_WRITE_16 = _halmac_reg_write_16,
694 	.REG_WRITE_32 = _halmac_reg_write_32,
695 #endif /* CONFIG_USB_HCI || CONFIG_PCIE_HCI */
696 
697 	/* Write data */
698 #if 0
699 	/* impletement in HAL-IC level */
700 	.SEND_RSVD_PAGE = sdio_write_data_rsvd_page,
701 	.SEND_H2C_PKT = sdio_write_data_h2c,
702 #endif
703 	/* Memory allocate */
704 	.RTL_FREE = _halmac_mfree,
705 	.RTL_MALLOC = _halmac_malloc,
706 	.RTL_MEMCPY = _halmac_memcpy,
707 	.RTL_MEMSET = _halmac_memset,
708 
709 	/* Sleep */
710 	.RTL_DELAY_US = _halmac_udelay,
711 
712 	/* Process Synchronization */
713 	.MUTEX_INIT = _halmac_mutex_init,
714 	.MUTEX_DEINIT = _halmac_mutex_deinit,
715 	.MUTEX_LOCK = _halmac_mutex_lock,
716 	.MUTEX_UNLOCK = _halmac_mutex_unlock,
717 
718 	.MSG_PRINT = _halmac_msg_print,
719 	.BUFF_PRINT = _halmac_buff_print,
720 	.EVENT_INDICATION = _halmac_event_indication,
721 };
722 
rtw_halmac_read8(struct intf_hdl * pintfhdl,u32 addr)723 u8 rtw_halmac_read8(struct intf_hdl *pintfhdl, u32 addr)
724 {
725 	PHALMAC_ADAPTER mac;
726 	PHALMAC_API api;
727 
728 
729 	/* WARNING: pintf_dev should not be null! */
730 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
731 	api = HALMAC_GET_API(mac);
732 
733 	return api->halmac_reg_read_8(mac, addr);
734 }
735 
rtw_halmac_read16(struct intf_hdl * pintfhdl,u32 addr)736 u16 rtw_halmac_read16(struct intf_hdl *pintfhdl, u32 addr)
737 {
738 	PHALMAC_ADAPTER mac;
739 	PHALMAC_API api;
740 
741 
742 	/* WARNING: pintf_dev should not be null! */
743 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
744 	api = HALMAC_GET_API(mac);
745 
746 	return api->halmac_reg_read_16(mac, addr);
747 }
748 
rtw_halmac_read32(struct intf_hdl * pintfhdl,u32 addr)749 u32 rtw_halmac_read32(struct intf_hdl *pintfhdl, u32 addr)
750 {
751 	PHALMAC_ADAPTER mac;
752 	PHALMAC_API api;
753 
754 
755 	/* WARNING: pintf_dev should not be null! */
756 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
757 	api = HALMAC_GET_API(mac);
758 
759 	return api->halmac_reg_read_32(mac, addr);
760 }
761 
_read_register(struct dvobj_priv * d,u32 addr,u32 cnt,u8 * buf)762 static void _read_register(struct dvobj_priv *d, u32 addr, u32 cnt, u8 *buf)
763 {
764 #if 1
765 	struct _ADAPTER *a;
766 	u32 i, n;
767 	u16 val16;
768 	u32 val32;
769 
770 
771 	a = dvobj_get_primary_adapter(d);
772 
773 	i = addr & 0x3;
774 	/* Handle address not start from 4 bytes alignment case */
775 	if (i) {
776 		val32 = cpu_to_le32(rtw_read32(a, addr & ~0x3));
777 		n = 4 - i;
778 		_rtw_memcpy(buf, ((u8 *)&val32) + i, n);
779 		i = n;
780 		cnt -= n;
781 	}
782 
783 	while (cnt) {
784 		if (cnt >= 4)
785 			n = 4;
786 		else if (cnt >= 2)
787 			n = 2;
788 		else
789 			n = 1;
790 		cnt -= n;
791 
792 		switch (n) {
793 		case 1:
794 			buf[i] = rtw_read8(a, addr+i);
795 			i++;
796 			break;
797 		case 2:
798 			val16 = cpu_to_le16(rtw_read16(a, addr+i));
799 			_rtw_memcpy(&buf[i], &val16, 2);
800 			i += 2;
801 			break;
802 		case 4:
803 			val32 = cpu_to_le32(rtw_read32(a, addr+i));
804 			_rtw_memcpy(&buf[i], &val32, 4);
805 			i += 4;
806 			break;
807 		}
808 	}
809 #else
810 	struct _ADAPTER *a;
811 	u32 i;
812 
813 
814 	a = dvobj_get_primary_adapter(d);
815 	for (i = 0; i < cnt; i++)
816 		buf[i] = rtw_read8(a, addr + i);
817 #endif
818 }
819 
820 #ifdef CONFIG_SDIO_HCI
_sdio_read_local(struct dvobj_priv * d,u32 addr,u32 cnt,u8 * buf)821 static int _sdio_read_local(struct dvobj_priv *d, u32 addr, u32 cnt, u8 *buf)
822 {
823 	struct _HALMAC_ADAPTER *mac;
824 	struct _HALMAC_API *api;
825 	enum _HALMAC_RET_STATUS status;
826 
827 
828 	if (buf == NULL)
829 		return -1;
830 
831 	mac = dvobj_to_halmac(d);
832 	api = HALMAC_GET_API(mac);
833 
834 	status = api->halmac_reg_sdio_cmd53_read_n(mac, addr, cnt, buf);
835 	if (status != HALMAC_RET_SUCCESS) {
836 		RTW_ERR("%s: addr=0x%08x cnt=%d err=%d\n",
837 			__FUNCTION__, addr, cnt, status);
838 		return -1;
839 	}
840 
841 	return 0;
842 }
843 #endif /* CONFIG_SDIO_HCI */
844 
rtw_halmac_read_mem(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * pmem)845 void rtw_halmac_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem)
846 {
847 	struct dvobj_priv *d;
848 
849 
850 	if (pmem == NULL) {
851 		RTW_ERR("pmem is NULL\n");
852 		return;
853 	}
854 
855 	d = pintfhdl->pintf_dev;
856 
857 #ifdef CONFIG_SDIO_HCI
858 	if (addr & 0xFFFF0000) {
859 		int err = 0;
860 
861 		err = _sdio_read_local(d, addr, cnt, pmem);
862 		if (!err)
863 			return;
864 	}
865 #endif /* CONFIG_SDIO_HCI */
866 
867 	_read_register(d, addr, cnt, pmem);
868 }
869 
870 #ifdef CONFIG_SDIO_INDIRECT_ACCESS
rtw_halmac_iread8(struct intf_hdl * pintfhdl,u32 addr)871 u8 rtw_halmac_iread8(struct intf_hdl *pintfhdl, u32 addr)
872 {
873 	PHALMAC_ADAPTER mac;
874 	PHALMAC_API api;
875 
876 	/* WARNING: pintf_dev should not be null! */
877 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
878 	api = HALMAC_GET_API(mac);
879 
880 	/*return api->halmac_reg_read_indirect_8(mac, addr);*/
881 	return api->halmac_reg_read_8(mac, addr);
882 }
883 
rtw_halmac_iread16(struct intf_hdl * pintfhdl,u32 addr)884 u16 rtw_halmac_iread16(struct intf_hdl *pintfhdl, u32 addr)
885 {
886 	PHALMAC_ADAPTER mac;
887 	PHALMAC_API api;
888 	u16 val16 = 0;
889 
890 	/* WARNING: pintf_dev should not be null! */
891 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
892 	api = HALMAC_GET_API(mac);
893 
894 	/*return api->halmac_reg_read_indirect_16(mac, addr);*/
895 	return api->halmac_reg_read_16(mac, addr);
896 }
897 
rtw_halmac_iread32(struct intf_hdl * pintfhdl,u32 addr)898 u32 rtw_halmac_iread32(struct intf_hdl *pintfhdl, u32 addr)
899 {
900 	PHALMAC_ADAPTER mac;
901 	PHALMAC_API api;
902 
903 
904 	/* WARNING: pintf_dev should not be null! */
905 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
906 	api = HALMAC_GET_API(mac);
907 
908 	return api->halmac_reg_read_indirect_32(mac, addr);
909 }
910 #endif /* CONFIG_SDIO_INDIRECT_ACCESS */
911 
rtw_halmac_write8(struct intf_hdl * pintfhdl,u32 addr,u8 value)912 int rtw_halmac_write8(struct intf_hdl *pintfhdl, u32 addr, u8 value)
913 {
914 	PHALMAC_ADAPTER mac;
915 	PHALMAC_API api;
916 	HALMAC_RET_STATUS status;
917 
918 
919 	/* WARNING: pintf_dev should not be null! */
920 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
921 	api = HALMAC_GET_API(mac);
922 
923 	status = api->halmac_reg_write_8(mac, addr, value);
924 
925 	if (status == HALMAC_RET_SUCCESS)
926 		return 0;
927 
928 	return -1;
929 }
930 
rtw_halmac_write16(struct intf_hdl * pintfhdl,u32 addr,u16 value)931 int rtw_halmac_write16(struct intf_hdl *pintfhdl, u32 addr, u16 value)
932 {
933 	PHALMAC_ADAPTER mac;
934 	PHALMAC_API api;
935 	HALMAC_RET_STATUS status;
936 
937 
938 	/* WARNING: pintf_dev should not be null! */
939 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
940 	api = HALMAC_GET_API(mac);
941 
942 	status = api->halmac_reg_write_16(mac, addr, value);
943 
944 	if (status == HALMAC_RET_SUCCESS)
945 		return 0;
946 
947 	return -1;
948 }
949 
rtw_halmac_write32(struct intf_hdl * pintfhdl,u32 addr,u32 value)950 int rtw_halmac_write32(struct intf_hdl *pintfhdl, u32 addr, u32 value)
951 {
952 	PHALMAC_ADAPTER mac;
953 	PHALMAC_API api;
954 	HALMAC_RET_STATUS status;
955 
956 
957 	/* WARNING: pintf_dev should not be null! */
958 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
959 	api = HALMAC_GET_API(mac);
960 
961 	status = api->halmac_reg_write_32(mac, addr, value);
962 
963 	if (status == HALMAC_RET_SUCCESS)
964 		return 0;
965 
966 	return -1;
967 }
968 
init_write_rsvd_page_size(struct dvobj_priv * d)969 static int init_write_rsvd_page_size(struct dvobj_priv *d)
970 {
971 	struct _HALMAC_ADAPTER *mac;
972 	struct _HALMAC_API *api;
973 	u32 size = 0;
974 	struct _HALMAC_OFLD_FUNC_INFO ofld_info;
975 	enum _HALMAC_RET_STATUS status;
976 	int err = 0;
977 
978 
979 #ifdef CONFIG_USB_HCI
980 	/* for USB do not exceed MAX_CMDBUF_SZ */
981 	size = 0x1000;
982 #elif defined(CONFIG_PCIE_HCI)
983 	size = MAX_CMDBUF_SZ - TXDESC_OFFSET;
984 #elif defined(CONFIG_SDIO_HCI)
985 	size = 0x7000; /* 28KB */
986 #endif
987 
988 	/* If size==0, use HALMAC default setting and don't call any function */
989 	if (!size)
990 		return 0;
991 
992 	err = rtw_halmac_set_max_dl_fw_size(d, size);
993 	if (err) {
994 		RTW_ERR("%s: Fail to set max download fw size!\n", __FUNCTION__);
995 		return -1;
996 	}
997 
998 	mac = dvobj_to_halmac(d);
999 	api = HALMAC_GET_API(mac);
1000 
1001 	_rtw_memset(&ofld_info, 0, sizeof(ofld_info));
1002 	ofld_info.halmac_malloc_max_sz = 0xFFFFFFFF;
1003 	ofld_info.rsvd_pg_drv_buf_max_sz = size;
1004 	status = api->halmac_ofld_func_cfg(mac, &ofld_info);
1005 	if (status != HALMAC_RET_SUCCESS) {
1006 		RTW_ERR("%s: Fail to config offload parameters!\n", __FUNCTION__);
1007 		return -1;
1008 	}
1009 
1010 	return 0;
1011 }
1012 
init_priv(struct halmacpriv * priv)1013 static int init_priv(struct halmacpriv *priv)
1014 {
1015 	struct halmac_indicator *indicator;
1016 	u32 count, size;
1017 
1018 
1019 	if (priv->indicator)
1020 		RTW_WARN("%s: HALMAC private data is not CLEAR!\n", __FUNCTION__);
1021 	count = HALMAC_FEATURE_ALL + 1;
1022 	size = sizeof(*indicator) * count;
1023 	indicator = (struct halmac_indicator *)rtw_zmalloc(size);
1024 	if (!indicator)
1025 		return -1;
1026 	priv->indicator = indicator;
1027 
1028 	return 0;
1029 }
1030 
deinit_priv(struct halmacpriv * priv)1031 static void deinit_priv(struct halmacpriv *priv)
1032 {
1033 	struct halmac_indicator *indicator;
1034 
1035 
1036 	indicator = priv->indicator;
1037 	priv->indicator = NULL;
1038 	if (indicator) {
1039 		u32 count, size;
1040 
1041 		count = HALMAC_FEATURE_ALL + 1;
1042 #ifdef CONFIG_RTW_DEBUG
1043 		{
1044 			struct submit_ctx *sctx;
1045 			u32 i;
1046 
1047 			for (i = 0; i < count; i++) {
1048 				if (!indicator[i].sctx)
1049 					continue;
1050 
1051 				RTW_WARN("%s: %s id(%d) sctx still exist!!\n",
1052 					__FUNCTION__, RTW_HALMAC_FEATURE_NAME[i], i);
1053 				sctx = indicator[i].sctx;
1054 				indicator[i].sctx = NULL;
1055 				rtw_mfree((u8 *)sctx, sizeof(*sctx));
1056 			}
1057 		}
1058 #endif /* !CONFIG_RTW_DEBUG */
1059 		size = sizeof(*indicator) * count;
1060 		rtw_mfree((u8 *)indicator, size);
1061 	}
1062 }
1063 
1064 #ifdef CONFIG_SDIO_HCI
_sdio_ver_drv2halmac(struct dvobj_priv * d)1065 static enum _HALMAC_SDIO_SPEC_VER _sdio_ver_drv2halmac(struct dvobj_priv *d)
1066 {
1067 	bool v3;
1068 	enum _HALMAC_SDIO_SPEC_VER ver;
1069 
1070 
1071 	v3 = rtw_is_sdio30(dvobj_get_primary_adapter(d));
1072 	if (v3)
1073 		ver = HALMAC_SDIO_SPEC_VER_3_00;
1074 	else
1075 		ver = HALMAC_SDIO_SPEC_VER_2_00;
1076 
1077 	return ver;
1078 }
1079 #endif /* CONFIG_SDIO_HCI */
1080 
rtw_halmac_get_version(char * str,u32 len)1081 void rtw_halmac_get_version(char *str, u32 len)
1082 {
1083 	HALMAC_RET_STATUS status;
1084 	HALMAC_VER ver;
1085 
1086 
1087 	status = halmac_get_version(&ver);
1088 	if (status != HALMAC_RET_SUCCESS)
1089 		return;
1090 
1091 	rtw_sprintf(str, len, "V%d_%02d_%02d",
1092 		    ver.major_ver, ver.prototype_ver, ver.minor_ver);
1093 }
1094 
rtw_halmac_init_adapter(struct dvobj_priv * d,PHALMAC_PLATFORM_API pf_api)1095 int rtw_halmac_init_adapter(struct dvobj_priv *d, PHALMAC_PLATFORM_API pf_api)
1096 {
1097 	PHALMAC_ADAPTER halmac;
1098 	PHALMAC_API api;
1099 	HALMAC_INTERFACE intf;
1100 	HALMAC_RET_STATUS status;
1101 	int err = 0;
1102 #ifdef CONFIG_SDIO_HCI
1103 	HALMAC_SDIO_HW_INFO info;
1104 #endif /* CONFIG_SDIO_HCI */
1105 
1106 
1107 	halmac = dvobj_to_halmac(d);
1108 	if (halmac) {
1109 		err = 0;
1110 		goto out;
1111 	}
1112 
1113 	err = init_priv(&d->hmpriv);
1114 	if (err)
1115 		goto out;
1116 
1117 #ifdef CONFIG_SDIO_HCI
1118 	intf = HALMAC_INTERFACE_SDIO;
1119 #elif defined(CONFIG_USB_HCI)
1120 	intf = HALMAC_INTERFACE_USB;
1121 #elif defined(CONFIG_PCIE_HCI)
1122 	intf = HALMAC_INTERFACE_PCIE;
1123 #else
1124 #warning "INTERFACE(CONFIG_XXX_HCI) not be defined!!"
1125 	intf = HALMAC_INTERFACE_UNDEFINE;
1126 #endif
1127 	status = halmac_init_adapter(d, pf_api, intf, &halmac, &api);
1128 	if (HALMAC_RET_SUCCESS != status) {
1129 		RTW_ERR("%s: halmac_init_adapter fail!(status=%d)\n", __FUNCTION__, status);
1130 		err = -1;
1131 		goto out;
1132 	}
1133 
1134 	dvobj_set_halmac(d, halmac);
1135 
1136 	status = api->halmac_interface_integration_tuning(halmac);
1137 	if (status != HALMAC_RET_SUCCESS) {
1138 		RTW_ERR("%s: halmac_interface_integration_tuning fail!(status=%d)\n", __FUNCTION__, status);
1139 		err = -1;
1140 		goto out;
1141 	}
1142 
1143 	status = api->halmac_phy_cfg(halmac, HALMAC_INTF_PHY_PLATFORM_ALL);
1144 	if (status != HALMAC_RET_SUCCESS) {
1145 		RTW_ERR("%s: halmac_phy_cfg fail!(status=%d)\n", __FUNCTION__, status);
1146 		err = -1;
1147 		goto out;
1148 	}
1149 
1150 	init_write_rsvd_page_size(d);
1151 
1152 #ifdef CONFIG_SDIO_HCI
1153 	info.spec_ver = _sdio_ver_drv2halmac(d);
1154 	/* clock unit is MHz */
1155 	info.clock_speed = RTW_DIV_ROUND_UP(rtw_sdio_get_clock(d), 1000000);
1156 	RTW_DBG("%s: SDIO clock=%uMHz ver=%u\n", __FUNCTION__, info.clock_speed, info.spec_ver+2);
1157 	status = api->halmac_sdio_hw_info(halmac, &info);
1158 	if (status != HALMAC_RET_SUCCESS) {
1159 		RTW_ERR("%s: halmac_sdio_hw_info fail!(status=%d)\n", __FUNCTION__, status);
1160 		err = -1;
1161 		goto out;
1162 	}
1163 #endif /* CONFIG_SDIO_HCI */
1164 
1165 out:
1166 	if (err)
1167 		rtw_halmac_deinit_adapter(d);
1168 
1169 	return err;
1170 }
1171 
rtw_halmac_deinit_adapter(struct dvobj_priv * d)1172 int rtw_halmac_deinit_adapter(struct dvobj_priv *d)
1173 {
1174 	PHALMAC_ADAPTER halmac;
1175 	HALMAC_RET_STATUS status;
1176 	int err = 0;
1177 
1178 
1179 	halmac = dvobj_to_halmac(d);
1180 	if (!halmac) {
1181 		err = 0;
1182 		goto out;
1183 	}
1184 
1185 	deinit_priv(&d->hmpriv);
1186 
1187 	status = halmac_deinit_adapter(halmac);
1188 	dvobj_set_halmac(d, NULL);
1189 	if (status != HALMAC_RET_SUCCESS) {
1190 		err = -1;
1191 		goto out;
1192 	}
1193 
1194 out:
1195 	return err;
1196 }
1197 
_hw_port_drv2halmac(enum _hw_port hwport)1198 static inline enum _HALMAC_PORTID _hw_port_drv2halmac(enum _hw_port hwport)
1199 {
1200 	enum _HALMAC_PORTID port = HALMAC_PORTIDMAX;
1201 
1202 
1203 	switch (hwport) {
1204 	case HW_PORT0:
1205 		port = HALMAC_PORTID0;
1206 		break;
1207 	case HW_PORT1:
1208 		port = HALMAC_PORTID1;
1209 		break;
1210 	case HW_PORT2:
1211 		port = HALMAC_PORTID2;
1212 		break;
1213 	case HW_PORT3:
1214 		port = HALMAC_PORTID3;
1215 		break;
1216 	case HW_PORT4:
1217 		port = HALMAC_PORTID4;
1218 		break;
1219 	default:
1220 		break;
1221 	}
1222 
1223 	return port;
1224 }
1225 
_network_type_drv2halmac(u8 type)1226 static enum _HALMAC_NETWORK_TYPE_SELECT _network_type_drv2halmac(u8 type)
1227 {
1228 	enum _HALMAC_NETWORK_TYPE_SELECT network = HALMAC_NETWORK_UNDEFINE;
1229 
1230 
1231 	switch (type) {
1232 	case _HW_STATE_NOLINK_:
1233 	case _HW_STATE_MONITOR_:
1234 		network = HALMAC_NETWORK_NO_LINK;
1235 		break;
1236 
1237 	case _HW_STATE_ADHOC_:
1238 		network = HALMAC_NETWORK_ADHOC;
1239 		break;
1240 
1241 	case _HW_STATE_STATION_:
1242 		network = HALMAC_NETWORK_INFRASTRUCTURE;
1243 		break;
1244 
1245 	case _HW_STATE_AP_:
1246 		network = HALMAC_NETWORK_AP;
1247 		break;
1248 	}
1249 
1250 	return network;
1251 }
1252 
_network_type_halmac2drv(enum _HALMAC_NETWORK_TYPE_SELECT network)1253 static u8 _network_type_halmac2drv(enum _HALMAC_NETWORK_TYPE_SELECT network)
1254 {
1255 	u8 type = _HW_STATE_NOLINK_;
1256 
1257 
1258 	switch (network) {
1259 	case HALMAC_NETWORK_NO_LINK:
1260 	case HALMAC_NETWORK_UNDEFINE:
1261 		type = _HW_STATE_NOLINK_;
1262 		break;
1263 
1264 	case HALMAC_NETWORK_ADHOC:
1265 		type = _HW_STATE_ADHOC_;
1266 		break;
1267 
1268 	case HALMAC_NETWORK_INFRASTRUCTURE:
1269 		type = _HW_STATE_STATION_;
1270 		break;
1271 
1272 	case HALMAC_NETWORK_AP:
1273 		type = _HW_STATE_AP_;
1274 		break;
1275 	}
1276 
1277 	return type;
1278 }
1279 
_beacon_ctrl_halmac2drv(struct _HALMAC_BCN_CTRL * ctrl,struct rtw_halmac_bcn_ctrl * drv_ctrl)1280 static void _beacon_ctrl_halmac2drv(struct _HALMAC_BCN_CTRL *ctrl,
1281 				struct rtw_halmac_bcn_ctrl *drv_ctrl)
1282 {
1283 	drv_ctrl->rx_bssid_fit = ctrl->dis_rx_bssid_fit ? 0 : 1;
1284 	drv_ctrl->txbcn_rpt = ctrl->en_txbcn_rpt ? 1 : 0;
1285 	drv_ctrl->tsf_update = ctrl->dis_tsf_udt ? 0 : 1;
1286 	drv_ctrl->enable_bcn = ctrl->en_bcn ? 1 : 0;
1287 	drv_ctrl->rxbcn_rpt = ctrl->en_rxbcn_rpt ? 1 : 0;
1288 	drv_ctrl->p2p_ctwin = ctrl->en_p2p_ctwin ? 1 : 0;
1289 	drv_ctrl->p2p_bcn_area = ctrl->en_p2p_bcn_area ? 1 : 0;
1290 }
1291 
_beacon_ctrl_drv2halmac(struct rtw_halmac_bcn_ctrl * drv_ctrl,struct _HALMAC_BCN_CTRL * ctrl)1292 static void _beacon_ctrl_drv2halmac(struct rtw_halmac_bcn_ctrl *drv_ctrl,
1293 				struct _HALMAC_BCN_CTRL *ctrl)
1294 {
1295 	ctrl->dis_rx_bssid_fit = drv_ctrl->rx_bssid_fit ? 0 : 1;
1296 	ctrl->en_txbcn_rpt = drv_ctrl->txbcn_rpt ? 1 : 0;
1297 	ctrl->dis_tsf_udt = drv_ctrl->tsf_update ? 0 : 1;
1298 	ctrl->en_bcn = drv_ctrl->enable_bcn ? 1 : 0;
1299 	ctrl->en_rxbcn_rpt = drv_ctrl->rxbcn_rpt ? 1 : 0;
1300 	ctrl->en_p2p_ctwin = drv_ctrl->p2p_ctwin ? 1 : 0;
1301 	ctrl->en_p2p_bcn_area = drv_ctrl->p2p_bcn_area ? 1 : 0;
1302 }
1303 
rtw_halmac_get_hw_value(struct dvobj_priv * d,HALMAC_HW_ID hw_id,VOID * pvalue)1304 int rtw_halmac_get_hw_value(struct dvobj_priv *d, HALMAC_HW_ID hw_id, VOID *pvalue)
1305 {
1306 	PHALMAC_ADAPTER mac;
1307 	PHALMAC_API api;
1308 	HALMAC_RET_STATUS status;
1309 
1310 
1311 	mac = dvobj_to_halmac(d);
1312 	api = HALMAC_GET_API(mac);
1313 
1314 	status = api->halmac_get_hw_value(mac, hw_id, pvalue);
1315 	if (HALMAC_RET_SUCCESS != status)
1316 		return -1;
1317 
1318 	return 0;
1319 }
1320 
1321 /**
1322  * rtw_halmac_get_tx_fifo_size() - TX FIFO size
1323  * @d:		struct dvobj_priv*
1324  * @size:	TX FIFO size, unit is byte.
1325  *
1326  * Get TX FIFO size(byte) from HALMAC.
1327  *
1328  * Rteurn 0 for OK, otherwise fail.
1329  */
rtw_halmac_get_tx_fifo_size(struct dvobj_priv * d,u32 * size)1330 int rtw_halmac_get_tx_fifo_size(struct dvobj_priv *d, u32 *size)
1331 {
1332 	struct _HALMAC_ADAPTER *halmac;
1333 	struct _HALMAC_API *api;
1334 	enum _HALMAC_RET_STATUS status;
1335 	u32 val = 0;
1336 
1337 
1338 	halmac = dvobj_to_halmac(d);
1339 	api = HALMAC_GET_API(halmac);
1340 
1341 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_TXFIFO_SIZE, &val);
1342 	if (status != HALMAC_RET_SUCCESS)
1343 		return -1;
1344 
1345 	*size = val;
1346 
1347 	return 0;
1348 }
1349 
1350 /**
1351  * rtw_halmac_get_rx_fifo_size() - RX FIFO size
1352  * @d:		struct dvobj_priv*
1353  * @size:	RX FIFO size, unit is byte
1354  *
1355  * Get RX FIFO size(byte) from HALMAC.
1356  *
1357  * Rteurn 0 for OK, otherwise fail.
1358  */
rtw_halmac_get_rx_fifo_size(struct dvobj_priv * d,u32 * size)1359 int rtw_halmac_get_rx_fifo_size(struct dvobj_priv *d, u32 *size)
1360 {
1361 	struct _HALMAC_ADAPTER *halmac;
1362 	struct _HALMAC_API *api;
1363 	enum _HALMAC_RET_STATUS status;
1364 	u32 val = 0;
1365 
1366 
1367 	halmac = dvobj_to_halmac(d);
1368 	api = HALMAC_GET_API(halmac);
1369 
1370 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RXFIFO_SIZE, &val);
1371 	if (status != HALMAC_RET_SUCCESS)
1372 		return -1;
1373 
1374 	*size = val;
1375 
1376 	return 0;
1377 }
1378 
1379 /**
1380  * rtw_halmac_get_rsvd_drv_pg_bndy() - Reserve page boundary of driver
1381  * @d:		struct dvobj_priv*
1382  * @size:	Page size, unit is byte
1383  *
1384  * Get reserve page boundary of driver from HALMAC.
1385  *
1386  * Rteurn 0 for OK, otherwise fail.
1387  */
rtw_halmac_get_rsvd_drv_pg_bndy(struct dvobj_priv * d,u16 * bndy)1388 int rtw_halmac_get_rsvd_drv_pg_bndy(struct dvobj_priv *d, u16 *bndy)
1389 {
1390 	struct _HALMAC_ADAPTER *halmac;
1391 	struct _HALMAC_API *api;
1392 	enum _HALMAC_RET_STATUS status;
1393 	u16 val = 0;
1394 
1395 
1396 	halmac = dvobj_to_halmac(d);
1397 	api = HALMAC_GET_API(halmac);
1398 
1399 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RSVD_PG_BNDY, &val);
1400 	if (status != HALMAC_RET_SUCCESS)
1401 		return -1;
1402 
1403 	*bndy = val;
1404 
1405 	return 0;
1406 }
1407 
1408 /**
1409  * rtw_halmac_get_page_size() - Page size
1410  * @d:		struct dvobj_priv*
1411  * @size:	Page size, unit is byte
1412  *
1413  * Get TX/RX page size(byte) from HALMAC.
1414  *
1415  * Rteurn 0 for OK, otherwise fail.
1416  */
rtw_halmac_get_page_size(struct dvobj_priv * d,u32 * size)1417 int rtw_halmac_get_page_size(struct dvobj_priv *d, u32 *size)
1418 {
1419 	struct _HALMAC_ADAPTER *halmac;
1420 	struct _HALMAC_API *api;
1421 	enum _HALMAC_RET_STATUS status;
1422 	u32 val = 0;
1423 
1424 
1425 	halmac = dvobj_to_halmac(d);
1426 	api = HALMAC_GET_API(halmac);
1427 
1428 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_PAGE_SIZE, &val);
1429 	if (status != HALMAC_RET_SUCCESS)
1430 		return -1;
1431 
1432 	*size = val;
1433 
1434 	return 0;
1435 }
1436 
1437 /**
1438  * rtw_halmac_get_tx_agg_align_size() - TX aggregation align size
1439  * @d:		struct dvobj_priv*
1440  * @size:	TX aggregation align size, unit is byte
1441  *
1442  * Get TX aggregation align size(byte) from HALMAC.
1443  *
1444  * Rteurn 0 for OK, otherwise fail.
1445  */
rtw_halmac_get_tx_agg_align_size(struct dvobj_priv * d,u16 * size)1446 int rtw_halmac_get_tx_agg_align_size(struct dvobj_priv *d, u16 *size)
1447 {
1448 	struct _HALMAC_ADAPTER *halmac;
1449 	struct _HALMAC_API *api;
1450 	enum _HALMAC_RET_STATUS status;
1451 	u16 val = 0;
1452 
1453 
1454 	halmac = dvobj_to_halmac(d);
1455 	api = HALMAC_GET_API(halmac);
1456 
1457 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_TX_AGG_ALIGN_SIZE, &val);
1458 	if (status != HALMAC_RET_SUCCESS)
1459 		return -1;
1460 
1461 	*size = val;
1462 
1463 	return 0;
1464 }
1465 
1466 /**
1467  * rtw_halmac_get_rx_agg_align_size() - RX aggregation align size
1468  * @d:		struct dvobj_priv*
1469  * @size:	RX aggregation align size, unit is byte
1470  *
1471  * Get RX aggregation align size(byte) from HALMAC.
1472  *
1473  * Rteurn 0 for OK, otherwise fail.
1474  */
rtw_halmac_get_rx_agg_align_size(struct dvobj_priv * d,u8 * size)1475 int rtw_halmac_get_rx_agg_align_size(struct dvobj_priv *d, u8 *size)
1476 {
1477 	struct _HALMAC_ADAPTER *halmac;
1478 	struct _HALMAC_API *api;
1479 	enum _HALMAC_RET_STATUS status;
1480 	u8 val = 0;
1481 
1482 
1483 	halmac = dvobj_to_halmac(d);
1484 	api = HALMAC_GET_API(halmac);
1485 
1486 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RX_AGG_ALIGN_SIZE, &val);
1487 	if (status != HALMAC_RET_SUCCESS)
1488 		return -1;
1489 
1490 	*size = val;
1491 
1492 	return 0;
1493 }
1494 
1495 /*
1496  * Description:
1497  *	Get RX driver info size. RX driver info is a small memory space between
1498  *	scriptor and RX payload.
1499  *
1500  *	+-------------------------+
1501  *	| RX descriptor           |
1502  *	| usually 24 bytes        |
1503  *	+-------------------------+
1504  *	| RX driver info          |
1505  *	| depends on driver cfg   |
1506  *	+-------------------------+
1507  *	| RX paylad               |
1508  *	|                         |
1509  *	+-------------------------+
1510  *
1511  * Parameter:
1512  *	d	pointer to struct dvobj_priv of driver
1513  *	sz	rx driver info size in bytes.
1514  *
1515  * Rteurn:
1516  *	0	Success
1517  *	other	Fail
1518  */
rtw_halmac_get_rx_drv_info_sz(struct dvobj_priv * d,u8 * sz)1519 int rtw_halmac_get_rx_drv_info_sz(struct dvobj_priv *d, u8 *sz)
1520 {
1521 	HALMAC_RET_STATUS status;
1522 	PHALMAC_ADAPTER halmac = dvobj_to_halmac(d);
1523 	PHALMAC_API api = HALMAC_GET_API(halmac);
1524 	u8 dw = 0;
1525 
1526 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_DRV_INFO_SIZE, &dw);
1527 	if (status != HALMAC_RET_SUCCESS)
1528 		return -1;
1529 
1530 	*sz = dw * 8;
1531 	return 0;
1532 }
1533 
1534 /**
1535  * rtw_halmac_get_tx_desc_size() - TX descriptor size
1536  * @d:		struct dvobj_priv*
1537  * @size:	TX descriptor size, unit is byte.
1538  *
1539  * Get TX descriptor size(byte) from HALMAC.
1540  *
1541  * Rteurn 0 for OK, otherwise fail.
1542  */
rtw_halmac_get_tx_desc_size(struct dvobj_priv * d,u32 * size)1543 int rtw_halmac_get_tx_desc_size(struct dvobj_priv *d, u32 *size)
1544 {
1545 	struct _HALMAC_ADAPTER *halmac;
1546 	struct _HALMAC_API *api;
1547 	enum _HALMAC_RET_STATUS status;
1548 	u32 val = 0;
1549 
1550 
1551 	halmac = dvobj_to_halmac(d);
1552 	api = HALMAC_GET_API(halmac);
1553 
1554 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_TX_DESC_SIZE, &val);
1555 	if (status != HALMAC_RET_SUCCESS)
1556 		return -1;
1557 
1558 	*size = val;
1559 
1560 	return 0;
1561 }
1562 
1563 /**
1564  * rtw_halmac_get_rx_desc_size() - RX descriptor size
1565  * @d:		struct dvobj_priv*
1566  * @size:	RX descriptor size, unit is byte.
1567  *
1568  * Get RX descriptor size(byte) from HALMAC.
1569  *
1570  * Rteurn 0 for OK, otherwise fail.
1571  */
rtw_halmac_get_rx_desc_size(struct dvobj_priv * d,u32 * size)1572 int rtw_halmac_get_rx_desc_size(struct dvobj_priv *d, u32 *size)
1573 {
1574 	struct _HALMAC_ADAPTER *halmac;
1575 	struct _HALMAC_API *api;
1576 	enum _HALMAC_RET_STATUS status;
1577 	u32 val = 0;
1578 
1579 
1580 	halmac = dvobj_to_halmac(d);
1581 	api = HALMAC_GET_API(halmac);
1582 
1583 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RX_DESC_SIZE, &val);
1584 	if (status != HALMAC_RET_SUCCESS)
1585 		return -1;
1586 
1587 	*size = val;
1588 
1589 	return 0;
1590 }
1591 
1592 
1593 /**
1594  * rtw_halmac_get_fw_max_size() - Firmware MAX size
1595  * @d:		struct dvobj_priv*
1596  * @size:	MAX Firmware size, unit is byte.
1597  *
1598  * Get Firmware MAX size(byte) from HALMAC.
1599  *
1600  * Rteurn 0 for OK, otherwise fail.
1601  */
rtw_halmac_get_fw_max_size(struct dvobj_priv * d,u32 * size)1602 static int rtw_halmac_get_fw_max_size(struct dvobj_priv *d, u32 *size)
1603 {
1604 	struct _HALMAC_ADAPTER *halmac;
1605 	struct _HALMAC_API *api;
1606 	enum _HALMAC_RET_STATUS status;
1607 	u32 val = 0;
1608 
1609 
1610 	halmac = dvobj_to_halmac(d);
1611 	api = HALMAC_GET_API(halmac);
1612 
1613 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_FW_MAX_SIZE, &val);
1614 	if (status != HALMAC_RET_SUCCESS)
1615 		return -1;
1616 
1617 	*size = val;
1618 
1619 	return 0;
1620 }
1621 
1622 /**
1623  * rtw_halmac_get_ori_h2c_size() - Original H2C MAX size
1624  * @d:		struct dvobj_priv*
1625  * @size:	H2C MAX size, unit is byte.
1626  *
1627  * Get original H2C MAX size(byte) from HALMAC.
1628  *
1629  * Rteurn 0 for OK, otherwise fail.
1630  */
rtw_halmac_get_ori_h2c_size(struct dvobj_priv * d,u32 * size)1631 int rtw_halmac_get_ori_h2c_size(struct dvobj_priv *d, u32 *size)
1632 {
1633 	struct _HALMAC_ADAPTER *halmac;
1634 	struct _HALMAC_API *api;
1635 	enum _HALMAC_RET_STATUS status;
1636 	u32 val = 0;
1637 
1638 
1639 	halmac = dvobj_to_halmac(d);
1640 	api = HALMAC_GET_API(halmac);
1641 
1642 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_ORI_H2C_SIZE, &val);
1643 	if (status != HALMAC_RET_SUCCESS)
1644 		return -1;
1645 
1646 	*size = val;
1647 
1648 	return 0;
1649 }
1650 
rtw_halmac_get_oqt_size(struct dvobj_priv * d,u8 * size)1651 int rtw_halmac_get_oqt_size(struct dvobj_priv *d, u8 *size)
1652 {
1653 	enum _HALMAC_RET_STATUS status;
1654 	struct _HALMAC_ADAPTER *halmac;
1655 	struct _HALMAC_API *api;
1656 	u8 val;
1657 
1658 
1659 	if (!size)
1660 		return -1;
1661 
1662 	halmac = dvobj_to_halmac(d);
1663 	api = HALMAC_GET_API(halmac);
1664 
1665 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_AC_OQT_SIZE, &val);
1666 	if (status != HALMAC_RET_SUCCESS)
1667 		return -1;
1668 
1669 	*size = val;
1670 	return 0;
1671 }
1672 
rtw_halmac_get_ac_queue_number(struct dvobj_priv * d,u8 * num)1673 int rtw_halmac_get_ac_queue_number(struct dvobj_priv *d, u8 *num)
1674 {
1675 	enum _HALMAC_RET_STATUS status;
1676 	struct _HALMAC_ADAPTER *halmac;
1677 	struct _HALMAC_API *api;
1678 	u8 val;
1679 
1680 
1681 	if (!num)
1682 		return -1;
1683 
1684 	halmac = dvobj_to_halmac(d);
1685 	api = HALMAC_GET_API(halmac);
1686 
1687 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_AC_QUEUE_NUM, &val);
1688 	if (status != HALMAC_RET_SUCCESS)
1689 		return -1;
1690 
1691 	*num = val;
1692 	return 0;
1693 }
1694 
1695 /**
1696  * rtw_halmac_get_mac_address() - Get MAC address of specific port
1697  * @d:		struct dvobj_priv*
1698  * @hwport:	port
1699  * @addr:	buffer for storing MAC address
1700  *
1701  * Get MAC address of specific port from HALMAC.
1702  *
1703  * Rteurn 0 for OK, otherwise fail.
1704  */
rtw_halmac_get_mac_address(struct dvobj_priv * d,enum _hw_port hwport,u8 * addr)1705 int rtw_halmac_get_mac_address(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
1706 {
1707 	struct _HALMAC_ADAPTER *halmac;
1708 	struct _HALMAC_API *api;
1709 	enum _HALMAC_PORTID port;
1710 	union _HALMAC_WLAN_ADDR hwa;
1711 	enum _HALMAC_RET_STATUS status;
1712 	int err = -1;
1713 
1714 
1715 	if (!addr)
1716 		goto out;
1717 
1718 	halmac = dvobj_to_halmac(d);
1719 	api = HALMAC_GET_API(halmac);
1720 	port = _hw_port_drv2halmac(hwport);
1721 	_rtw_memset(&hwa, 0, sizeof(hwa));
1722 
1723 	status = api->halmac_get_mac_addr(halmac, port, &hwa);
1724 	if (status != HALMAC_RET_SUCCESS)
1725 		goto out;
1726 
1727 	_rtw_memcpy(addr, hwa.Address, 6);
1728 
1729 	err = 0;
1730 out:
1731 	return err;
1732 }
1733 
1734 /**
1735  * rtw_halmac_get_network_type() - Get network type of specific port
1736  * @d:		struct dvobj_priv*
1737  * @hwport:	port
1738  * @type:	buffer to put network type (_HW_STATE_*)
1739  *
1740  * Get network type of specific port from HALMAC.
1741  *
1742  * Rteurn 0 for OK, otherwise fail.
1743  */
rtw_halmac_get_network_type(struct dvobj_priv * d,enum _hw_port hwport,u8 * type)1744 int rtw_halmac_get_network_type(struct dvobj_priv *d, enum _hw_port hwport, u8 *type)
1745 {
1746 #if 0
1747 	struct _HALMAC_ADAPTER *halmac;
1748 	struct _HALMAC_API *api;
1749 	enum _HALMAC_PORTID port;
1750 	enum _HALMAC_NETWORK_TYPE_SELECT network;
1751 	enum _HALMAC_RET_STATUS status;
1752 	int err = -1;
1753 
1754 
1755 	halmac = dvobj_to_halmac(d);
1756 	api = HALMAC_GET_API(halmac);
1757 	port = _hw_port_drv2halmac(hwport);
1758 	network = HALMAC_NETWORK_UNDEFINE;
1759 
1760 	status = api->halmac_get_net_type(halmac, port, &network);
1761 	if (status != HALMAC_RET_SUCCESS)
1762 		goto out;
1763 
1764 	*type = _network_type_halmac2drv(network);
1765 
1766 	err = 0;
1767 out:
1768 	return err;
1769 #else
1770 	struct _ADAPTER *a;
1771 	enum _HALMAC_PORTID port;
1772 	enum _HALMAC_NETWORK_TYPE_SELECT network;
1773 	u32 val;
1774 	int err = -1;
1775 
1776 
1777 	a = dvobj_get_primary_adapter(d);
1778 	port = _hw_port_drv2halmac(hwport);
1779 	network = HALMAC_NETWORK_UNDEFINE;
1780 
1781 	switch (port) {
1782 	case HALMAC_PORTID0:
1783 		val = rtw_read32(a, REG_CR);
1784 		network = BIT_GET_NETYPE0(val);
1785 		break;
1786 
1787 	case HALMAC_PORTID1:
1788 		val = rtw_read32(a, REG_CR);
1789 		network = BIT_GET_NETYPE1(val);
1790 		break;
1791 
1792 	case HALMAC_PORTID2:
1793 		val = rtw_read32(a, REG_CR_EXT);
1794 		network = BIT_GET_NETYPE2(val);
1795 		break;
1796 
1797 	case HALMAC_PORTID3:
1798 		val = rtw_read32(a, REG_CR_EXT);
1799 		network = BIT_GET_NETYPE3(val);
1800 		break;
1801 
1802 	case HALMAC_PORTID4:
1803 		val = rtw_read32(a, REG_CR_EXT);
1804 		network = BIT_GET_NETYPE4(val);
1805 		break;
1806 
1807 	default:
1808 		goto out;
1809 	}
1810 
1811 	*type = _network_type_halmac2drv(network);
1812 
1813 	err = 0;
1814 out:
1815 	return err;
1816 #endif
1817 }
1818 
1819 /**
1820  * rtw_halmac_get_bcn_ctrl() - Get beacon control setting of specific port
1821  * @d:		struct dvobj_priv*
1822  * @hwport:	port
1823  * @bcn_ctrl:	setting of beacon control
1824  *
1825  * Get beacon control setting of specific port from HALMAC.
1826  *
1827  * Rteurn 0 for OK, otherwise fail.
1828  */
rtw_halmac_get_bcn_ctrl(struct dvobj_priv * d,enum _hw_port hwport,struct rtw_halmac_bcn_ctrl * bcn_ctrl)1829 int rtw_halmac_get_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,
1830 			struct rtw_halmac_bcn_ctrl *bcn_ctrl)
1831 {
1832 	struct _HALMAC_ADAPTER *halmac;
1833 	struct _HALMAC_API *api;
1834 	enum _HALMAC_PORTID port;
1835 	struct _HALMAC_BCN_CTRL ctrl;
1836 	enum _HALMAC_RET_STATUS status;
1837 	int err = -1;
1838 
1839 
1840 	halmac = dvobj_to_halmac(d);
1841 	api = HALMAC_GET_API(halmac);
1842 	port = _hw_port_drv2halmac(hwport);
1843 	_rtw_memset(&ctrl, 0, sizeof(ctrl));
1844 
1845 	status = api->halmac_rw_bcn_ctrl(halmac, port, 0, &ctrl);
1846 	if (status != HALMAC_RET_SUCCESS)
1847 		goto out;
1848 	_beacon_ctrl_halmac2drv(&ctrl, bcn_ctrl);
1849 
1850 	err = 0;
1851 out:
1852 	return err;
1853 }
1854 
1855 /*
1856  * Note:
1857  *	When this function return, the register REG_RCR may be changed.
1858  */
rtw_halmac_config_rx_info(struct dvobj_priv * d,HALMAC_DRV_INFO info)1859 int rtw_halmac_config_rx_info(struct dvobj_priv *d, HALMAC_DRV_INFO info)
1860 {
1861 	PHALMAC_ADAPTER halmac;
1862 	PHALMAC_API api;
1863 	HALMAC_RET_STATUS status;
1864 	int err = -1;
1865 
1866 
1867 	halmac = dvobj_to_halmac(d);
1868 	api = HALMAC_GET_API(halmac);
1869 
1870 	status = api->halmac_cfg_drv_info(halmac, info);
1871 	if (status != HALMAC_RET_SUCCESS)
1872 		goto out;
1873 
1874 	err = 0;
1875 out:
1876 	return err;
1877 }
1878 
1879 /**
1880  * rtw_halmac_set_max_dl_fw_size() - Set the MAX download firmware size
1881  * @d:		struct dvobj_priv*
1882  * @size:	the max download firmware size in one I/O
1883  *
1884  * Set the max download firmware size in one I/O.
1885  * Please also consider the max size of the callback function "SEND_RSVD_PAGE"
1886  * could accept, because download firmware would call "SEND_RSVD_PAGE" to send
1887  * firmware to IC.
1888  *
1889  * If the value of "size" is not even, it would be rounded down to nearest
1890  * even, and 0 and 1 are both invalid value.
1891  *
1892  * Return 0 for setting OK, otherwise fail.
1893  */
rtw_halmac_set_max_dl_fw_size(struct dvobj_priv * d,u32 size)1894 int rtw_halmac_set_max_dl_fw_size(struct dvobj_priv *d, u32 size)
1895 {
1896 	PHALMAC_ADAPTER mac;
1897 	PHALMAC_API api;
1898 	HALMAC_RET_STATUS status;
1899 
1900 
1901 	if (!size || (size == 1))
1902 		return -1;
1903 
1904 	mac = dvobj_to_halmac(d);
1905 	if (!mac) {
1906 		RTW_ERR("%s: HALMAC is not ready!!\n", __FUNCTION__);
1907 		return -1;
1908 	}
1909 	api = HALMAC_GET_API(mac);
1910 
1911 	size &= ~1; /* round down to even */
1912 	status = api->halmac_cfg_max_dl_size(mac, size);
1913 	if (status != HALMAC_RET_SUCCESS) {
1914 		RTW_WARN("%s: Fail to cfg_max_dl_size(%d), err=%d!!\n",
1915 			 __FUNCTION__, size, status);
1916 		return -1;
1917 	}
1918 
1919 	return 0;
1920 }
1921 
1922 /**
1923  * rtw_halmac_set_mac_address() - Set mac address of specific port
1924  * @d:		struct dvobj_priv*
1925  * @hwport:	port
1926  * @addr:	mac address
1927  *
1928  * Set self mac address of specific port to HALMAC.
1929  *
1930  * Rteurn 0 for OK, otherwise fail.
1931  */
rtw_halmac_set_mac_address(struct dvobj_priv * d,enum _hw_port hwport,u8 * addr)1932 int rtw_halmac_set_mac_address(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
1933 {
1934 	PHALMAC_ADAPTER halmac;
1935 	PHALMAC_API api;
1936 	enum _HALMAC_PORTID port;
1937 	HALMAC_WLAN_ADDR hwa;
1938 	HALMAC_RET_STATUS status;
1939 	int err = -1;
1940 
1941 
1942 	halmac = dvobj_to_halmac(d);
1943 	api = HALMAC_GET_API(halmac);
1944 
1945 	port = _hw_port_drv2halmac(hwport);
1946 	_rtw_memset(&hwa, 0, sizeof(hwa));
1947 	_rtw_memcpy(hwa.Address, addr, 6);
1948 
1949 	status = api->halmac_cfg_mac_addr(halmac, port, &hwa);
1950 	if (status != HALMAC_RET_SUCCESS)
1951 		goto out;
1952 
1953 	err = 0;
1954 out:
1955 	return err;
1956 }
1957 
1958 /**
1959  * rtw_halmac_set_bssid() - Set BSSID of specific port
1960  * @d:		struct dvobj_priv*
1961  * @hwport:	port
1962  * @addr:	BSSID, mac address of AP
1963  *
1964  * Set BSSID of specific port to HALMAC.
1965  *
1966  * Rteurn 0 for OK, otherwise fail.
1967  */
rtw_halmac_set_bssid(struct dvobj_priv * d,enum _hw_port hwport,u8 * addr)1968 int rtw_halmac_set_bssid(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
1969 {
1970 	PHALMAC_ADAPTER halmac;
1971 	PHALMAC_API api;
1972 	enum _HALMAC_PORTID port;
1973 	HALMAC_WLAN_ADDR hwa;
1974 	HALMAC_RET_STATUS status;
1975 	int err = -1;
1976 
1977 	halmac = dvobj_to_halmac(d);
1978 	api = HALMAC_GET_API(halmac);
1979 	port = _hw_port_drv2halmac(hwport);
1980 
1981 	_rtw_memset(&hwa, 0, sizeof(HALMAC_WLAN_ADDR));
1982 	_rtw_memcpy(hwa.Address, addr, 6);
1983 	status = api->halmac_cfg_bssid(halmac, port, &hwa);
1984 	if (status != HALMAC_RET_SUCCESS)
1985 		goto out;
1986 
1987 	err = 0;
1988 out:
1989 	return err;
1990 }
1991 
1992 /**
1993  * rtw_halmac_set_tx_address() - Set transmitter address of specific port
1994  * @d:		struct dvobj_priv*
1995  * @hwport:	port
1996  * @addr:	transmitter address
1997  *
1998  * Set transmitter address of specific port to HALMAC.
1999  *
2000  * Rteurn 0 for OK, otherwise fail.
2001  */
rtw_halmac_set_tx_address(struct dvobj_priv * d,enum _hw_port hwport,u8 * addr)2002 int rtw_halmac_set_tx_address(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
2003 {
2004 	struct _HALMAC_ADAPTER *halmac;
2005 	struct _HALMAC_API *api;
2006 	enum _HALMAC_PORTID port;
2007 	union _HALMAC_WLAN_ADDR hwa;
2008 	enum _HALMAC_RET_STATUS status;
2009 	int err = -1;
2010 
2011 
2012 	halmac = dvobj_to_halmac(d);
2013 	api = HALMAC_GET_API(halmac);
2014 	port = _hw_port_drv2halmac(hwport);
2015 	_rtw_memset(&hwa, 0, sizeof(union _HALMAC_WLAN_ADDR));
2016 	_rtw_memcpy(hwa.Address, addr, 6);
2017 
2018 	status = api->halmac_cfg_transmitter_addr(halmac, port, &hwa);
2019 	if (status != HALMAC_RET_SUCCESS)
2020 		goto out;
2021 
2022 	err = 0;
2023 out:
2024 	return err;
2025 }
2026 
2027 /**
2028  * rtw_halmac_set_network_type() - Set network type of specific port
2029  * @d:		struct dvobj_priv*
2030  * @hwport:	port
2031  * @type:	network type (_HW_STATE_*)
2032  *
2033  * Set network type of specific port to HALMAC.
2034  *
2035  * Rteurn 0 for OK, otherwise fail.
2036  */
rtw_halmac_set_network_type(struct dvobj_priv * d,enum _hw_port hwport,u8 type)2037 int rtw_halmac_set_network_type(struct dvobj_priv *d, enum _hw_port hwport, u8 type)
2038 {
2039 	struct _HALMAC_ADAPTER *halmac;
2040 	struct _HALMAC_API *api;
2041 	enum _HALMAC_PORTID port;
2042 	enum _HALMAC_NETWORK_TYPE_SELECT network;
2043 	enum _HALMAC_RET_STATUS status;
2044 	int err = -1;
2045 
2046 
2047 	halmac = dvobj_to_halmac(d);
2048 	api = HALMAC_GET_API(halmac);
2049 	port = _hw_port_drv2halmac(hwport);
2050 	network = _network_type_drv2halmac(type);
2051 
2052 	status = api->halmac_cfg_net_type(halmac, port, network);
2053 	if (status != HALMAC_RET_SUCCESS)
2054 		goto out;
2055 
2056 	err = 0;
2057 out:
2058 	return err;
2059 }
2060 
2061 /**
2062  * rtw_halmac_reset_tsf() - Reset TSF timer of specific port
2063  * @d:		struct dvobj_priv*
2064  * @hwport:	port
2065  *
2066  * Notice HALMAC to reset timing synchronization function(TSF) timer of
2067  * specific port.
2068  *
2069  * Rteurn 0 for OK, otherwise fail.
2070  */
rtw_halmac_reset_tsf(struct dvobj_priv * d,enum _hw_port hwport)2071 int rtw_halmac_reset_tsf(struct dvobj_priv *d, enum _hw_port hwport)
2072 {
2073 	struct _HALMAC_ADAPTER *halmac;
2074 	struct _HALMAC_API *api;
2075 	enum _HALMAC_PORTID port;
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 	port = _hw_port_drv2halmac(hwport);
2083 
2084 	status = api->halmac_cfg_tsf_rst(halmac, port);
2085 	if (status != HALMAC_RET_SUCCESS)
2086 		goto out;
2087 
2088 	err = 0;
2089 out:
2090 	return err;
2091 }
2092 
2093 /**
2094  * rtw_halmac_set_bcn_interval() - Set beacon interval of each port
2095  * @d:		struct dvobj_priv*
2096  * @hwport:	port
2097  * @space:	beacon interval, unit is ms
2098  *
2099  * Set beacon interval of specific port to HALMAC.
2100  *
2101  * Rteurn 0 for OK, otherwise fail.
2102  */
rtw_halmac_set_bcn_interval(struct dvobj_priv * d,enum _hw_port hwport,u32 interval)2103 int rtw_halmac_set_bcn_interval(struct dvobj_priv *d, enum _hw_port hwport,
2104 				u32 interval)
2105 {
2106 	struct _HALMAC_ADAPTER *halmac;
2107 	struct _HALMAC_API *api;
2108 	enum _HALMAC_PORTID port;
2109 	enum _HALMAC_RET_STATUS status;
2110 	int err = -1;
2111 
2112 
2113 	halmac = dvobj_to_halmac(d);
2114 	api = HALMAC_GET_API(halmac);
2115 	port = _hw_port_drv2halmac(hwport);
2116 
2117 	status = api->halmac_cfg_bcn_space(halmac, port, interval);
2118 	if (status != HALMAC_RET_SUCCESS)
2119 		goto out;
2120 
2121 	err = 0;
2122 out:
2123 	return err;
2124 }
2125 
2126 /**
2127  * rtw_halmac_set_bcn_ctrl() - Set beacon control setting of each port
2128  * @d:		struct dvobj_priv*
2129  * @hwport:	port
2130  * @bcn_ctrl:	setting of beacon control
2131  *
2132  * Set beacon control setting of specific port to HALMAC.
2133  *
2134  * Rteurn 0 for OK, otherwise fail.
2135  */
rtw_halmac_set_bcn_ctrl(struct dvobj_priv * d,enum _hw_port hwport,struct rtw_halmac_bcn_ctrl * bcn_ctrl)2136 int rtw_halmac_set_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,
2137 			struct rtw_halmac_bcn_ctrl *bcn_ctrl)
2138 {
2139 	struct _HALMAC_ADAPTER *halmac;
2140 	struct _HALMAC_API *api;
2141 	enum _HALMAC_PORTID port;
2142 	struct _HALMAC_BCN_CTRL ctrl;
2143 	enum _HALMAC_RET_STATUS status;
2144 	int err = -1;
2145 
2146 
2147 	halmac = dvobj_to_halmac(d);
2148 	api = HALMAC_GET_API(halmac);
2149 	port = _hw_port_drv2halmac(hwport);
2150 	_rtw_memset(&ctrl, 0, sizeof(ctrl));
2151 	_beacon_ctrl_drv2halmac(bcn_ctrl, &ctrl);
2152 
2153 	status = api->halmac_rw_bcn_ctrl(halmac, port, 1, &ctrl);
2154 	if (status != HALMAC_RET_SUCCESS)
2155 		goto out;
2156 
2157 	err = 0;
2158 out:
2159 	return err;
2160 }
2161 
2162 /**
2163  * rtw_halmac_set_aid() - Set association identifier(AID) of specific port
2164  * @d:		struct dvobj_priv*
2165  * @hwport:	port
2166  * @aid:	Association identifier
2167  *
2168  * Set association identifier(AID) of specific port to HALMAC.
2169  *
2170  * Rteurn 0 for OK, otherwise fail.
2171  */
rtw_halmac_set_aid(struct dvobj_priv * d,enum _hw_port hwport,u16 aid)2172 int rtw_halmac_set_aid(struct dvobj_priv *d, enum _hw_port hwport, u16 aid)
2173 {
2174 	struct _HALMAC_ADAPTER *halmac;
2175 	struct _HALMAC_API *api;
2176 	enum _HALMAC_PORTID port;
2177 	enum _HALMAC_RET_STATUS status;
2178 	int err = -1;
2179 
2180 
2181 	halmac = dvobj_to_halmac(d);
2182 	api = HALMAC_GET_API(halmac);
2183 	port = _hw_port_drv2halmac(hwport);
2184 
2185 #if 0
2186 	status = api->halmac_cfg_aid(halmac, port, aid);
2187 	if (status != HALMAC_RET_SUCCESS)
2188 		goto out;
2189 #else
2190 {
2191 	struct _ADAPTER *a;
2192 	u32 addr;
2193 	u16 val;
2194 
2195 	a = dvobj_get_primary_adapter(d);
2196 
2197 	switch (port) {
2198 	case 0:
2199 		addr = REG_BCN_PSR_RPT;
2200 		val = rtw_read16(a, addr);
2201 		val = BIT_SET_PS_AID_0(val, aid);
2202 		rtw_write16(a, addr, val);
2203 		break;
2204 
2205 	case 1:
2206 		addr = REG_BCN_PSR_RPT1;
2207 		val = rtw_read16(a, addr);
2208 		val = BIT_SET_PS_AID_1(val, aid);
2209 		rtw_write16(a, addr, val);
2210 		break;
2211 
2212 	case 2:
2213 		addr = REG_BCN_PSR_RPT2;
2214 		val = rtw_read16(a, addr);
2215 		val = BIT_SET_PS_AID_2(val, aid);
2216 		rtw_write16(a, addr, val);
2217 		break;
2218 
2219 	case 3:
2220 		addr = REG_BCN_PSR_RPT3;
2221 		val = rtw_read16(a, addr);
2222 		val = BIT_SET_PS_AID_3(val, aid);
2223 		rtw_write16(a, addr, val);
2224 		break;
2225 
2226 	case 4:
2227 		addr = REG_BCN_PSR_RPT4;
2228 		val = rtw_read16(a, addr);
2229 		val = BIT_SET_PS_AID_4(val, aid);
2230 		rtw_write16(a, addr, val);
2231 		break;
2232 
2233 	default:
2234 		goto out;
2235 	}
2236 }
2237 #endif
2238 
2239 	err = 0;
2240 out:
2241 	return err;
2242 }
2243 
rtw_halmac_set_bandwidth(struct dvobj_priv * d,u8 channel,u8 pri_ch_idx,u8 bw)2244 int rtw_halmac_set_bandwidth(struct dvobj_priv *d, u8 channel, u8 pri_ch_idx, u8 bw)
2245 {
2246 	PHALMAC_ADAPTER mac;
2247 	PHALMAC_API api;
2248 	HALMAC_RET_STATUS status;
2249 
2250 
2251 	mac = dvobj_to_halmac(d);
2252 	api = HALMAC_GET_API(mac);
2253 
2254 	status = api->halmac_cfg_ch_bw(mac, channel, pri_ch_idx, bw);
2255 	if (HALMAC_RET_SUCCESS != status)
2256 		return -1;
2257 
2258 	return 0;
2259 }
2260 
2261 /**
2262  * rtw_halmac_set_edca() - config edca parameter
2263  * @d:		struct dvobj_priv*
2264  * @queue:	XMIT_[VO/VI/BE/BK]_QUEUE
2265  * @aifs:	Arbitration inter-frame space(AIFS)
2266  * @cw:		Contention window(CW)
2267  * @txop:	MAX Transmit Opportunity(TXOP)
2268  *
2269  * Return: 0 if process OK, otherwise -1.
2270  */
rtw_halmac_set_edca(struct dvobj_priv * d,u8 queue,u8 aifs,u8 cw,u16 txop)2271 int rtw_halmac_set_edca(struct dvobj_priv *d, u8 queue, u8 aifs, u8 cw, u16 txop)
2272 {
2273 	PHALMAC_ADAPTER mac;
2274 	PHALMAC_API api;
2275 	HALMAC_ACQ_ID ac;
2276 	HALMAC_EDCA_PARA edca;
2277 	HALMAC_RET_STATUS status;
2278 
2279 
2280 	mac = dvobj_to_halmac(d);
2281 	api = HALMAC_GET_API(mac);
2282 
2283 	switch (queue) {
2284 	case XMIT_VO_QUEUE:
2285 		ac = HALMAC_ACQ_ID_VO;
2286 		break;
2287 	case XMIT_VI_QUEUE:
2288 		ac = HALMAC_ACQ_ID_VI;
2289 		break;
2290 	case XMIT_BE_QUEUE:
2291 		ac = HALMAC_ACQ_ID_BE;
2292 		break;
2293 	case XMIT_BK_QUEUE:
2294 		ac = HALMAC_ACQ_ID_BK;
2295 		break;
2296 	default:
2297 		return -1;
2298 	}
2299 
2300 	edca.aifs = aifs;
2301 	edca.cw = cw;
2302 	edca.txop_limit = txop;
2303 
2304 	status = api->halmac_cfg_edca_para(mac, ac, &edca);
2305 	if (status != HALMAC_RET_SUCCESS)
2306 		return -1;
2307 
2308 	return 0;
2309 }
2310 
2311 /*
2312  * Description:
2313  *	Power on device hardware.
2314  *	[Notice!] If device's power state is on before,
2315  *	it would be power off first and turn on power again.
2316  *
2317  * Return:
2318  *	0	power on success
2319  *	-1	power on fail
2320  *	-2	power state unchange
2321  */
rtw_halmac_poweron(struct dvobj_priv * d)2322 int rtw_halmac_poweron(struct dvobj_priv *d)
2323 {
2324 	PHALMAC_ADAPTER halmac;
2325 	PHALMAC_API api;
2326 	HALMAC_RET_STATUS status;
2327 	int err = -1;
2328 
2329 
2330 	halmac = dvobj_to_halmac(d);
2331 	if (!halmac)
2332 		goto out;
2333 
2334 	api = HALMAC_GET_API(halmac);
2335 
2336 	status = api->halmac_pre_init_system_cfg(halmac);
2337 	if (status != HALMAC_RET_SUCCESS)
2338 		goto out;
2339 
2340 #ifdef CONFIG_SDIO_HCI
2341 	status = api->halmac_sdio_cmd53_4byte(halmac, HALMAC_SDIO_CMD53_4BYTE_MODE_RW);
2342 	if (status != HALMAC_RET_SUCCESS)
2343 		goto out;
2344 #endif /* CONFIG_SDIO_HCI */
2345 
2346 	status = api->halmac_mac_power_switch(halmac, HALMAC_MAC_POWER_ON);
2347 	if (HALMAC_RET_PWR_UNCHANGE == status) {
2348 		/*
2349 		 * Work around for warm reboot but device not power off,
2350 		 * but it would also fall into this case when auto power on is enabled.
2351 		 */
2352 		api->halmac_mac_power_switch(halmac, HALMAC_MAC_POWER_OFF);
2353 		status = api->halmac_mac_power_switch(halmac, HALMAC_MAC_POWER_ON);
2354 		RTW_WARN("%s: Power state abnormal, try to recover...%s\n",
2355 			 __FUNCTION__, (HALMAC_RET_SUCCESS == status)?"OK":"FAIL!");
2356 	}
2357 	if (HALMAC_RET_SUCCESS != status) {
2358 		if (HALMAC_RET_PWR_UNCHANGE == status)
2359 			err = -2;
2360 		goto out;
2361 	}
2362 
2363 	status = api->halmac_init_system_cfg(halmac);
2364 	if (status != HALMAC_RET_SUCCESS)
2365 		goto out;
2366 
2367 	err = 0;
2368 out:
2369 	return err;
2370 }
2371 
2372 /*
2373  * Description:
2374  *	Power off device hardware.
2375  *
2376  * Return:
2377  *	0	Power off success
2378  *	-1	Power off fail
2379  */
rtw_halmac_poweroff(struct dvobj_priv * d)2380 int rtw_halmac_poweroff(struct dvobj_priv *d)
2381 {
2382 	PHALMAC_ADAPTER halmac;
2383 	PHALMAC_API api;
2384 	HALMAC_RET_STATUS status;
2385 	int err = -1;
2386 
2387 
2388 	halmac = dvobj_to_halmac(d);
2389 	if (!halmac)
2390 		goto out;
2391 
2392 	api = HALMAC_GET_API(halmac);
2393 
2394 	status = api->halmac_mac_power_switch(halmac, HALMAC_MAC_POWER_OFF);
2395 	if ((HALMAC_RET_SUCCESS != status)
2396 	    && (HALMAC_RET_PWR_UNCHANGE != status))
2397 		goto out;
2398 
2399 	err = 0;
2400 out:
2401 	return err;
2402 }
2403 
2404 #ifdef CONFIG_SUPPORT_TRX_SHARED
_trx_share_mode_drv2halmac(u8 trx_share_mode)2405 static inline HALMAC_RX_FIFO_EXPANDING_MODE _trx_share_mode_drv2halmac(u8 trx_share_mode)
2406 {
2407 	if (0 == trx_share_mode)
2408 		return HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE;
2409 	else if (1 == trx_share_mode)
2410 		return HALMAC_RX_FIFO_EXPANDING_MODE_1_BLOCK;
2411 	else if (2 == trx_share_mode)
2412 		return HALMAC_RX_FIFO_EXPANDING_MODE_2_BLOCK;
2413 	else if (3 == trx_share_mode)
2414 		return HALMAC_RX_FIFO_EXPANDING_MODE_3_BLOCK;
2415 	else
2416 		return HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE;
2417 }
_rtw_get_trx_share_mode(_adapter * adapter)2418 static HALMAC_RX_FIFO_EXPANDING_MODE _rtw_get_trx_share_mode(_adapter *adapter)
2419 {
2420 	struct registry_priv  *registry_par = &adapter->registrypriv;
2421 
2422 	return _trx_share_mode_drv2halmac(registry_par->trx_share_mode);
2423 }
dump_trx_share_mode(void * sel,_adapter * adapter)2424 void dump_trx_share_mode(void *sel, _adapter *adapter)
2425 {
2426 	struct registry_priv  *registry_par = &adapter->registrypriv;
2427 	u8 mode =  _trx_share_mode_drv2halmac(registry_par->trx_share_mode);
2428 
2429 	if (HALMAC_RX_FIFO_EXPANDING_MODE_1_BLOCK == mode)
2430 		RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "RX_FIFO_EXPANDING_MODE_1");
2431 	else if (HALMAC_RX_FIFO_EXPANDING_MODE_2_BLOCK == mode)
2432 		RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "RX_FIFO_EXPANDING_MODE_2");
2433 	else if (HALMAC_RX_FIFO_EXPANDING_MODE_3_BLOCK == mode)
2434 		RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "RX_FIFO_EXPANDING_MODE_3");
2435 	else
2436 		RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "DISABLE");
2437 }
2438 #endif
2439 
_rsvd_page_num_drv2halmac(u8 num)2440 static enum _HALMAC_DRV_RSVD_PG_NUM _rsvd_page_num_drv2halmac(u8 num)
2441 {
2442 	if (num <= 8)
2443 		return HALMAC_RSVD_PG_NUM8;
2444 	if (num <= 16)
2445 		return HALMAC_RSVD_PG_NUM16;
2446 	if (num <= 24)
2447 		return HALMAC_RSVD_PG_NUM24;
2448 
2449 	if (num > 32)
2450 		RTW_WARN("%s: Fail to allocate RSVD page(%d)!!"
2451 			 " The MAX RSVD page number is 32...\n",
2452 			 __FUNCTION__, num);
2453 
2454 	return HALMAC_RSVD_PG_NUM32;
2455 }
2456 
_rsvd_page_num_halmac2drv(HALMAC_DRV_RSVD_PG_NUM rsvd_page_number)2457 static u8 _rsvd_page_num_halmac2drv(HALMAC_DRV_RSVD_PG_NUM rsvd_page_number)
2458 {
2459 	u8 num = 0;
2460 
2461 
2462 	switch (rsvd_page_number) {
2463 	case HALMAC_RSVD_PG_NUM8:
2464 		num = 8;
2465 		break;
2466 
2467 	case HALMAC_RSVD_PG_NUM16:
2468 		num = 16;
2469 		break;
2470 
2471 	case HALMAC_RSVD_PG_NUM24:
2472 		num = 24;
2473 		break;
2474 
2475 	case HALMAC_RSVD_PG_NUM32:
2476 		num = 32;
2477 		break;
2478 	}
2479 
2480 	return num;
2481 }
2482 
_choose_trx_mode(struct dvobj_priv * d)2483 static HALMAC_TRX_MODE _choose_trx_mode(struct dvobj_priv *d)
2484 {
2485 	PADAPTER p;
2486 
2487 
2488 	p = dvobj_get_primary_adapter(d);
2489 
2490 	if (p->registrypriv.wifi_spec)
2491 		return HALMAC_TRX_MODE_WMM;
2492 
2493 #ifdef CONFIG_SUPPORT_TRX_SHARED
2494 	if (_rtw_get_trx_share_mode(p))
2495 		return HALMAC_TRX_MODE_TRXSHARE;
2496 #endif
2497 
2498 	return HALMAC_TRX_MODE_NORMAL;
2499 }
2500 
_rf_type_drv2halmac(enum rf_type rf_drv)2501 static inline enum _HALMAC_RF_TYPE _rf_type_drv2halmac(enum rf_type rf_drv)
2502 {
2503 	enum _HALMAC_RF_TYPE rf_mac;
2504 
2505 
2506 	switch (rf_drv) {
2507 	case RF_1T1R:
2508 		rf_mac = HALMAC_RF_1T1R;
2509 		break;
2510 	case RF_1T2R:
2511 		rf_mac = HALMAC_RF_1T2R;
2512 		break;
2513 	case RF_2T2R:
2514 		rf_mac = HALMAC_RF_2T2R;
2515 		break;
2516 	case RF_2T3R:
2517 		rf_mac = HALMAC_RF_2T3R;
2518 		break;
2519 	case RF_2T4R:
2520 		rf_mac = HALMAC_RF_2T4R;
2521 		break;
2522 	case RF_3T3R:
2523 		rf_mac = HALMAC_RF_3T3R;
2524 		break;
2525 	case RF_3T4R:
2526 		rf_mac = HALMAC_RF_3T4R;
2527 		break;
2528 	case RF_4T4R:
2529 		rf_mac = HALMAC_RF_4T4R;
2530 		break;
2531 	default:
2532 		rf_mac = HALMAC_RF_MAX_TYPE;
2533 		RTW_ERR("%s: Invalid RF type(0x%x)!\n", __FUNCTION__, rf_drv);
2534 		break;
2535 	}
2536 
2537 	return rf_mac;
2538 }
2539 
_ant_status_by_rf_type(enum rf_type rf,u8 * tx,u8 * rx)2540 static void _ant_status_by_rf_type(enum rf_type rf, u8 *tx, u8 *rx)
2541 {
2542 	switch (rf) {
2543 	case RF_1T1R:
2544 	case RF_1T2R:
2545 		*tx = BB_PATH_A;
2546 		break;
2547 	case RF_2T2R:
2548 	case RF_2T3R:
2549 	case RF_2T4R:
2550 		*tx = BB_PATH_AB;
2551 		break;
2552 	case RF_3T3R:
2553 	case RF_3T4R:
2554 		*tx = BB_PATH_ABC;
2555 		break;
2556 	case RF_4T4R:
2557 	default:
2558 		*tx = BB_PATH_ABCD;
2559 		break;
2560 	}
2561 
2562 	switch (rf) {
2563 	case RF_1T1R:
2564 		*rx = BB_PATH_A;
2565 		break;
2566 	case RF_1T2R:
2567 	case RF_2T2R:
2568 		*rx = BB_PATH_AB;
2569 		break;
2570 	case RF_2T3R:
2571 	case RF_3T3R:
2572 		*rx = BB_PATH_ABC;
2573 		break;
2574 	case RF_2T4R:
2575 	case RF_3T4R:
2576 	case RF_4T4R:
2577 	default:
2578 		*rx = BB_PATH_ABCD;
2579 		break;
2580 	}
2581 }
2582 
_send_general_info(struct dvobj_priv * d)2583 static int _send_general_info(struct dvobj_priv *d)
2584 {
2585 	struct _ADAPTER *adapter;
2586 	struct hal_com_data *hal;
2587 	struct _HALMAC_ADAPTER *halmac;
2588 	struct _HALMAC_API *api;
2589 	struct _HALMAC_GENERAL_INFO info;
2590 	enum _HALMAC_RET_STATUS status;
2591 	enum rf_type rf;
2592 	u8 val8 = 0;
2593 
2594 
2595 	adapter = dvobj_get_primary_adapter(d);
2596 	hal = GET_HAL_DATA(adapter);
2597 	halmac = dvobj_to_halmac(d);
2598 	if (!halmac)
2599 		return -1;
2600 	api = HALMAC_GET_API(halmac);
2601 
2602 	_rtw_memset(&info, 0, sizeof(info));
2603 	info.rfe_type = (u8)hal->rfe_type;
2604 	rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, (u8 *)&val8);
2605 	rf = (enum rf_type)val8;
2606 	info.rf_type = _rf_type_drv2halmac(rf);
2607 	_ant_status_by_rf_type(rf, &info.tx_ant_status, &info.rx_ant_status);
2608 
2609 	status = api->halmac_send_general_info(halmac, &info);
2610 	switch (status) {
2611 	case HALMAC_RET_SUCCESS:
2612 		break;
2613 	case HALMAC_RET_NO_DLFW:
2614 		RTW_WARN("%s: halmac_send_general_info() fail because fw not dl!\n",
2615 			 __FUNCTION__);
2616 		/* go through */
2617 	default:
2618 		return -1;
2619 	}
2620 
2621 	return 0;
2622 }
2623 
_cfg_drv_rsvd_pg_num(struct dvobj_priv * d)2624 static int _cfg_drv_rsvd_pg_num(struct dvobj_priv *d)
2625 {
2626 	struct _ADAPTER *a;
2627 	struct hal_com_data *hal;
2628 	PHALMAC_ADAPTER halmac;
2629 	PHALMAC_API api;
2630 	enum _HALMAC_DRV_RSVD_PG_NUM rsvd_page_number;
2631 	HALMAC_RET_STATUS status;
2632 	u8 drv_rsvd_num;
2633 
2634 
2635 	a = dvobj_get_primary_adapter(d);
2636 	hal = GET_HAL_DATA(a);
2637 	halmac = dvobj_to_halmac(d);
2638 	api = HALMAC_GET_API(halmac);
2639 
2640 	drv_rsvd_num = rtw_hal_get_rsvd_page_num(a);
2641 	rsvd_page_number = _rsvd_page_num_drv2halmac(drv_rsvd_num);
2642 	status = api->halmac_cfg_drv_rsvd_pg_num(halmac, rsvd_page_number);
2643 	if (status != HALMAC_RET_SUCCESS)
2644 		return -1;
2645 	hal->drv_rsvd_page_number = _rsvd_page_num_halmac2drv(rsvd_page_number);
2646 
2647 	if (drv_rsvd_num != hal->drv_rsvd_page_number)
2648 		RTW_INFO("%s: request %d pages, but allocate %d pages\n",
2649 			 __FUNCTION__, drv_rsvd_num, hal->drv_rsvd_page_number);
2650 
2651 	return 0;
2652 }
2653 
_debug_dlfw_fail(struct dvobj_priv * d)2654 static void _debug_dlfw_fail(struct dvobj_priv *d)
2655 {
2656 	struct _ADAPTER *a;
2657 	u32 addr;
2658 	u32 v32, i, n;
2659 	u8 data[0x100] = {0};
2660 
2661 
2662 	a = dvobj_get_primary_adapter(d);
2663 
2664 	/* read 0x80[15:0], 0x10F8[31:0] once */
2665 	addr = 0x80;
2666 	v32 = rtw_read16(a, addr);
2667 	RTW_PRINT("%s: 0x%X = 0x%04x\n", __FUNCTION__, addr, v32);
2668 
2669 	addr = 0x10F8;
2670 	v32 = rtw_read32(a, addr);
2671 	RTW_PRINT("%s: 0x%X = 0x%08x\n", __FUNCTION__, addr, v32);
2672 
2673 	/* read 0x10FC[31:0], 5 times */
2674 	addr = 0x10FC;
2675 	n = 5;
2676 	for (i = 0; i < n; i++) {
2677 		v32 = rtw_read32(a, addr);
2678 		RTW_PRINT("%s: 0x%X = 0x%08x (%u/%u)\n",
2679 			  __FUNCTION__, addr, v32, i, n);
2680 	}
2681 
2682 	/*
2683 	 * write 0x3A[7:0]=0x28 and 0xF6[7:0]=0x01
2684 	 * and then read 0xC0[31:0] 5 times
2685 	 */
2686 	addr = 0x3A;
2687 	v32 = 0x28;
2688 	rtw_write8(a, addr, (u8)v32);
2689 	v32 = rtw_read8(a, addr);
2690 	RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v32);
2691 
2692 	addr = 0xF6;
2693 	v32 = 0x1;
2694 	rtw_write8(a, addr, (u8)v32);
2695 	v32 = rtw_read8(a, addr);
2696 	RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v32);
2697 
2698 	addr = 0xC0;
2699 	n = 5;
2700 	for (i = 0; i < n; i++) {
2701 		v32 = rtw_read32(a, addr);
2702 		RTW_PRINT("%s: 0x%X = 0x%08x (%u/%u)\n",
2703 			  __FUNCTION__, addr, v32, i, n);
2704 	}
2705 
2706 	/* 0x00~0xFF, 0x1000~0x10FF */
2707 	addr = 0;
2708 	n = 0x100;
2709 	for (i = 0; i < n; i+=4)
2710 		*(u32*)&data[i] = cpu_to_le32(rtw_read32(a, addr+i));
2711 	for (i = 0; i < n; i++) {
2712 		if (i % 16 == 0)
2713 			RTW_PRINT("0x%04x\t", addr+i);
2714 		_RTW_PRINT("0x%02x", data[i]);
2715 		if (i % 16 == 15)
2716 			_RTW_PRINT("\n");
2717 		else
2718 			_RTW_PRINT(" ");
2719 	}
2720 
2721 	addr = 0x1000;
2722 	n = 0x100;
2723 	for (i = 0; i < n; i+=4)
2724 		*(u32*)&data[i] = cpu_to_le32(rtw_read32(a, addr+i));
2725 	for (i = 0; i < n; i++) {
2726 		if (i % 16 == 0)
2727 			RTW_PRINT("0x%04x\t", addr+i);
2728 		_RTW_PRINT("0x%02x", data[i]);
2729 		if (i % 16 == 15)
2730 			_RTW_PRINT("\n");
2731 		else
2732 			_RTW_PRINT(" ");
2733 	}
2734 }
2735 
2736 /*
2737  * Description:
2738  *	Downlaod Firmware Flow
2739  *
2740  * Parameters:
2741  *	d	pointer of struct dvobj_priv
2742  *	fw	firmware array
2743  *	fwsize	firmware size
2744  *	re_dl	re-download firmware or not
2745  *		0: run in init hal flow, not re-download
2746  *		1: it is a stand alone operation, not in init hal flow
2747  *
2748  * Return:
2749  *	0	Success
2750  *	others	Fail
2751  */
download_fw(struct dvobj_priv * d,u8 * fw,u32 fwsize,u8 re_dl)2752 static int download_fw(struct dvobj_priv *d, u8 *fw, u32 fwsize, u8 re_dl)
2753 {
2754 	PHALMAC_ADAPTER mac;
2755 	PHALMAC_API api;
2756 	HALMAC_RET_STATUS status;
2757 	int err = 0;
2758 	PHAL_DATA_TYPE hal;
2759 	HALMAC_FW_VERSION fw_vesion;
2760 
2761 
2762 	mac = dvobj_to_halmac(d);
2763 	api = HALMAC_GET_API(mac);
2764 	hal = GET_HAL_DATA(dvobj_get_primary_adapter(d));
2765 
2766 	if ((!fw) || (!fwsize))
2767 		return -1;
2768 
2769 	/* 1. Driver Stop Tx */
2770 	/* ToDo */
2771 
2772 	/* 2. Driver Check Tx FIFO is empty */
2773 	err = rtw_halmac_txfifo_wait_empty(d, 2000); /* wait 2s */
2774 	if (err) {
2775 		err = -1;
2776 		goto resume_tx;
2777 	}
2778 
2779 	/* 3. Config MAX download size */
2780 	/*
2781 	 * Already done in rtw_halmac_init_adapter() or
2782 	 * somewhere calling rtw_halmac_set_max_dl_fw_size().
2783 	 */
2784 
2785 	/* 4. Download Firmware */
2786 	status = api->halmac_download_firmware(mac, fw, fwsize);
2787 	if (status != HALMAC_RET_SUCCESS) {
2788 		RTW_ERR("%s: download firmware FAIL! status=0x%02x\n",
2789 			__FUNCTION__, status);
2790 		_debug_dlfw_fail(d);
2791 		err = -1;
2792 		goto resume_tx;
2793 	}
2794 
2795 resume_tx:
2796 	/* 5. Driver resume TX if needed */
2797 	/* ToDo */
2798 
2799 	if (err)
2800 		goto exit;
2801 
2802 	if (re_dl) {
2803 		HALMAC_TRX_MODE mode;
2804 
2805 		/* 6. Change reserved page size */
2806 		err = _cfg_drv_rsvd_pg_num(d);
2807 		if (err)
2808 			return -1;
2809 
2810 		/* 7. Init TRX Configuration */
2811 		mode = _choose_trx_mode(d);
2812 		status = api->halmac_init_trx_cfg(mac, mode);
2813 		if (HALMAC_RET_SUCCESS != status)
2814 			return -1;
2815 
2816 		/* 8. Config RX Aggregation */
2817 		err = rtw_halmac_rx_agg_switch(d, _TRUE);
2818 		if (err)
2819 			return -1;
2820 
2821 		/* 9. Send General Info */
2822 		err = _send_general_info(d);
2823 		if (err)
2824 			return -1;
2825 	}
2826 
2827 	/* 10. (Driver) Reset driver variables if needed */
2828 	hal->LastHMEBoxNum = 0;
2829 
2830 	/* 11. (Driver) Get FW version */
2831 	status = api->halmac_get_fw_version(mac, &fw_vesion);
2832 	if (status == HALMAC_RET_SUCCESS) {
2833 		hal->firmware_version = fw_vesion.version;
2834 		hal->firmware_sub_version = fw_vesion.sub_version;
2835 		hal->firmware_size = fwsize;
2836 	}
2837 
2838 exit:
2839 	return err;
2840 }
2841 
init_mac_flow(struct dvobj_priv * d)2842 static int init_mac_flow(struct dvobj_priv *d)
2843 {
2844 	PADAPTER p;
2845 	struct hal_com_data *hal;
2846 	PHALMAC_ADAPTER halmac;
2847 	PHALMAC_API api;
2848 	enum _HALMAC_DRV_RSVD_PG_NUM rsvd_page_number;
2849 	HALMAC_WLAN_ADDR hwa;
2850 	HALMAC_TRX_MODE trx_mode;
2851 	HALMAC_RET_STATUS status;
2852 	u8 drv_rsvd_num;
2853 	u8 nettype;
2854 	int err, err_ret = -1;
2855 
2856 
2857 	p = dvobj_get_primary_adapter(d);
2858 	hal = GET_HAL_DATA(p);
2859 	halmac = dvobj_to_halmac(d);
2860 	api = HALMAC_GET_API(halmac);
2861 
2862 #ifdef CONFIG_SUPPORT_TRX_SHARED
2863 	status = api->halmac_cfg_rx_fifo_expanding_mode(halmac, _rtw_get_trx_share_mode(p));
2864 	if (status != HALMAC_RET_SUCCESS)
2865 		goto out;
2866 #endif
2867 
2868 #if 0 /* It is not necessary to call this in normal driver */
2869 	status = api->halmac_cfg_la_mode(halmac, HALMAC_LA_MODE_DISABLE);
2870 	if (status != HALMAC_RET_SUCCESS)
2871 		goto out;
2872 #endif
2873 
2874 	err = _cfg_drv_rsvd_pg_num(d);
2875 	if (err)
2876 		goto out;
2877 
2878 #ifdef CONFIG_USB_HCI
2879 	status = api->halmac_set_bulkout_num(halmac, d->RtNumOutPipes);
2880 	if (status != HALMAC_RET_SUCCESS)
2881 		goto out;
2882 #endif /* CONFIG_USB_HCI */
2883 
2884 	trx_mode = _choose_trx_mode(d);
2885 	status = api->halmac_init_mac_cfg(halmac, trx_mode);
2886 	if (status != HALMAC_RET_SUCCESS)
2887 		goto out;
2888 
2889 	err = rtw_halmac_rx_agg_switch(d, _TRUE);
2890 	if (err)
2891 		goto out;
2892 
2893 	nettype = dvobj_to_regsty(d)->wireless_mode;
2894 	if (is_supported_vht(nettype) == _TRUE)
2895 		status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_AC);
2896 	else if (is_supported_ht(nettype) == _TRUE)
2897 		status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_N);
2898 	else if (IsSupportedTxOFDM(nettype) == _TRUE)
2899 		status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_G);
2900 	else
2901 		status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_B);
2902 	if (status != HALMAC_RET_SUCCESS)
2903 		goto out;
2904 
2905 	err_ret = 0;
2906 out:
2907 	return err_ret;
2908 }
2909 
_drv_enable_trx(struct dvobj_priv * d)2910 static int _drv_enable_trx(struct dvobj_priv *d)
2911 {
2912 	struct _ADAPTER *adapter;
2913 	u32 status;
2914 
2915 
2916 	adapter = dvobj_get_primary_adapter(d);
2917 	if (adapter->bup == _FALSE) {
2918 		status = rtw_start_drv_threads(adapter);
2919 		if (status == _FAIL) {
2920 			RTW_ERR("%s: Start threads Failed!\n", __FUNCTION__);
2921 			return -1;
2922 		}
2923 	}
2924 
2925 	rtw_intf_start(adapter);
2926 
2927 	return 0;
2928 }
2929 
2930 /*
2931  * Notices:
2932  *	Make sure
2933  *	1. rtw_hal_get_hwreg(HW_VAR_RF_TYPE)
2934  *	2. HAL_DATA_TYPE.rfe_type
2935  *	already ready for use before calling this function.
2936  */
_halmac_init_hal(struct dvobj_priv * d,u8 * fw,u32 fwsize)2937 static int _halmac_init_hal(struct dvobj_priv *d, u8 *fw, u32 fwsize)
2938 {
2939 	PADAPTER adapter;
2940 	PHALMAC_ADAPTER halmac;
2941 	PHALMAC_API api;
2942 	HALMAC_RET_STATUS status;
2943 	u32 ok;
2944 	u8 fw_ok = _FALSE;
2945 	int err, err_ret = -1;
2946 
2947 
2948 	adapter = dvobj_get_primary_adapter(d);
2949 	halmac = dvobj_to_halmac(d);
2950 	if (!halmac)
2951 		goto out;
2952 	api = HALMAC_GET_API(halmac);
2953 
2954 	/* StatePowerOff */
2955 
2956 	/* SKIP: halmac_init_adapter (Already done before) */
2957 
2958 	/* halmac_pre_Init_system_cfg */
2959 	/* halmac_mac_power_switch(on) */
2960 	/* halmac_Init_system_cfg */
2961 	ok = rtw_hal_power_on(adapter);
2962 	if (_FAIL == ok)
2963 		goto out;
2964 
2965 	/* StatePowerOn */
2966 
2967 	/* DownloadFW */
2968 	if (fw && fwsize) {
2969 		err = download_fw(d, fw, fwsize, 0);
2970 		if (err)
2971 			goto out;
2972 		fw_ok = _TRUE;
2973 	}
2974 
2975 	/* InitMACFlow */
2976 	err = init_mac_flow(d);
2977 	if (err)
2978 		goto out;
2979 
2980 	/* Driver insert flow: Enable TR/RX */
2981 	err = _drv_enable_trx(d);
2982 	if (err)
2983 		goto out;
2984 
2985 	/* halmac_send_general_info */
2986 	if (_TRUE == fw_ok) {
2987 		err = _send_general_info(d);
2988 		if (err)
2989 			goto out;
2990 	}
2991 
2992 	/* Init Phy parameter-MAC */
2993 	ok = rtw_hal_init_mac_register(adapter);
2994 	if (_FALSE == ok)
2995 		goto out;
2996 
2997 	/* StateMacInitialized */
2998 
2999 	/* halmac_cfg_drv_info */
3000 	err = rtw_halmac_config_rx_info(d, HALMAC_DRV_INFO_PHY_STATUS);
3001 	if (err)
3002 		goto out;
3003 
3004 	/* halmac_set_hw_value(HALMAC_HW_EN_BB_RF) */
3005 	/* Init BB, RF */
3006 	ok = rtw_hal_init_phy(adapter);
3007 	if (_FALSE == ok)
3008 		goto out;
3009 
3010 	status = api->halmac_init_interface_cfg(halmac);
3011 	if (status != HALMAC_RET_SUCCESS)
3012 		goto out;
3013 
3014 	/* SKIP: halmac_verify_platform_api */
3015 	/* SKIP: halmac_h2c_lb */
3016 
3017 	/* StateRxIdle */
3018 
3019 	err_ret = 0;
3020 out:
3021 	return err_ret;
3022 }
3023 
rtw_halmac_init_hal(struct dvobj_priv * d)3024 int rtw_halmac_init_hal(struct dvobj_priv *d)
3025 {
3026 	return _halmac_init_hal(d, NULL, 0);
3027 }
3028 
3029 /*
3030  * Notices:
3031  *	Make sure
3032  *	1. rtw_hal_get_hwreg(HW_VAR_RF_TYPE)
3033  *	2. HAL_DATA_TYPE.rfe_type
3034  *	already ready for use before calling this function.
3035  */
rtw_halmac_init_hal_fw(struct dvobj_priv * d,u8 * fw,u32 fwsize)3036 int rtw_halmac_init_hal_fw(struct dvobj_priv *d, u8 *fw, u32 fwsize)
3037 {
3038 	return _halmac_init_hal(d, fw, fwsize);
3039 }
3040 
3041 /*
3042  * Notices:
3043  *	Make sure
3044  *	1. rtw_hal_get_hwreg(HW_VAR_RF_TYPE)
3045  *	2. HAL_DATA_TYPE.rfe_type
3046  *	already ready for use before calling this function.
3047  */
rtw_halmac_init_hal_fw_file(struct dvobj_priv * d,u8 * fwpath)3048 int rtw_halmac_init_hal_fw_file(struct dvobj_priv *d, u8 *fwpath)
3049 {
3050 	u8 *fw = NULL;
3051 	u32 fwmaxsize = 0, size = 0;
3052 	int err = 0;
3053 
3054 
3055 	err = rtw_halmac_get_fw_max_size(d, &fwmaxsize);
3056 	if (err) {
3057 		RTW_ERR("%s: Fail to get Firmware MAX size(err=%d)\n", __FUNCTION__, err);
3058 		return -1;
3059 	}
3060 
3061 	fw = rtw_zmalloc(fwmaxsize);
3062 	if (!fw)
3063 		return -1;
3064 
3065 	size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
3066 	if (!size) {
3067 		err = -1;
3068 		goto exit;
3069 	}
3070 
3071 	err = _halmac_init_hal(d, fw, size);
3072 
3073 exit:
3074 	rtw_mfree(fw, fwmaxsize);
3075 	/*fw = NULL;*/
3076 
3077 	return err;
3078 }
3079 
rtw_halmac_deinit_hal(struct dvobj_priv * d)3080 int rtw_halmac_deinit_hal(struct dvobj_priv *d)
3081 {
3082 	PADAPTER adapter;
3083 	PHALMAC_ADAPTER halmac;
3084 	PHALMAC_API api;
3085 	HALMAC_RET_STATUS status;
3086 	int err = -1;
3087 
3088 
3089 	adapter = dvobj_get_primary_adapter(d);
3090 	halmac = dvobj_to_halmac(d);
3091 	if (!halmac)
3092 		goto out;
3093 	api = HALMAC_GET_API(halmac);
3094 
3095 	status = api->halmac_deinit_interface_cfg(halmac);
3096 	if (status != HALMAC_RET_SUCCESS)
3097 		goto out;
3098 
3099 	rtw_hal_power_off(adapter);
3100 
3101 	err = 0;
3102 out:
3103 	return err;
3104 }
3105 
rtw_halmac_self_verify(struct dvobj_priv * d)3106 int rtw_halmac_self_verify(struct dvobj_priv *d)
3107 {
3108 	PHALMAC_ADAPTER mac;
3109 	PHALMAC_API api;
3110 	HALMAC_RET_STATUS status;
3111 	int err = -1;
3112 
3113 
3114 	mac = dvobj_to_halmac(d);
3115 	api = HALMAC_GET_API(mac);
3116 
3117 	status = api->halmac_verify_platform_api(mac);
3118 	if (status != HALMAC_RET_SUCCESS)
3119 		goto out;
3120 
3121 	status = api->halmac_h2c_lb(mac);
3122 	if (status != HALMAC_RET_SUCCESS)
3123 		goto out;
3124 
3125 	err = 0;
3126 out:
3127 	return err;
3128 }
3129 
rtw_halmac_txfifo_is_empty(struct dvobj_priv * d)3130 static u8 rtw_halmac_txfifo_is_empty(struct dvobj_priv *d)
3131 {
3132 	struct _HALMAC_ADAPTER *mac;
3133 	struct _HALMAC_API *api;
3134 	enum _HALMAC_RET_STATUS status;
3135 	u32 chk_num = 10;
3136 	u8 rst = _FALSE;
3137 
3138 
3139 	mac = dvobj_to_halmac(d);
3140 	api = HALMAC_GET_API(mac);
3141 
3142 	status = api->halmac_txfifo_is_empty(mac, chk_num);
3143 	if (status == HALMAC_RET_SUCCESS)
3144 		rst = _TRUE;
3145 
3146 	return rst;
3147 }
3148 
3149 /**
3150  * rtw_halmac_txfifo_wait_empty() - Wait TX FIFO to be emtpy
3151  * @d:		struct dvobj_priv*
3152  * @timeout:	time limit of wait, unit is ms
3153  *		0 for no limit
3154  *
3155  * Wait TX FIFO to be emtpy.
3156  *
3157  * Rteurn 0 for TX FIFO is empty, otherwise not empty.
3158  */
rtw_halmac_txfifo_wait_empty(struct dvobj_priv * d,u32 timeout)3159 int rtw_halmac_txfifo_wait_empty(struct dvobj_priv *d, u32 timeout)
3160 {
3161 	struct _ADAPTER *a;
3162 	u8 empty = _FALSE;
3163 	u32 cnt = 0;
3164 	systime start_time = 0;
3165 	u32 pass_time; /* ms */
3166 
3167 
3168 	a = dvobj_get_primary_adapter(d);
3169 	start_time = rtw_get_current_time();
3170 
3171 	do {
3172 		cnt++;
3173 		empty = rtw_halmac_txfifo_is_empty(d);
3174 		if (empty == _TRUE)
3175 			break;
3176 
3177 		if (timeout) {
3178 			pass_time = rtw_get_passing_time_ms(start_time);
3179 			if (pass_time > timeout)
3180 				break;
3181 		}
3182 		if (RTW_CANNOT_IO(a)) {
3183 			RTW_WARN("%s: Interrupted by I/O forbiden!\n", __FUNCTION__);
3184 			break;
3185 		}
3186 
3187 		rtw_msleep_os(2);
3188 	} while (1);
3189 
3190 	if (empty == _FALSE) {
3191 #ifdef CONFIG_RTW_DEBUG
3192 		u16 dbg_reg[] = {0x210, 0x230, 0x234, 0x238, 0x23C, 0x240,
3193 				 0x41A, 0x10FC, 0x10F8, 0x11F4, 0x11F8};
3194 		u8 i;
3195 		u32 val;
3196 
3197 		if (!RTW_CANNOT_IO(a)) {
3198 			for (i = 0; i < ARRAY_SIZE(dbg_reg); i++) {
3199 				val = rtw_read32(a, dbg_reg[i]);
3200 				RTW_ERR("REG_%X:0x%08x\n", dbg_reg[i], val);
3201 			}
3202 		}
3203 #endif /* CONFIG_RTW_DEBUG */
3204 
3205 		RTW_ERR("%s: Fail to wait txfifo empty!(cnt=%d)\n",
3206 			__FUNCTION__, cnt);
3207 		return -1;
3208 	}
3209 
3210 	return 0;
3211 }
3212 
_fw_mem_drv2halmac(enum fw_mem mem,u8 tx_stop)3213 static enum _HALMAC_DLFW_MEM _fw_mem_drv2halmac(enum fw_mem mem, u8 tx_stop)
3214 {
3215 	enum _HALMAC_DLFW_MEM mem_halmac = HALMAC_DLFW_MEM_UNDEFINE;
3216 
3217 
3218 	switch (mem) {
3219 	case FW_EMEM:
3220 		if (tx_stop == _FALSE)
3221 			mem_halmac = HALMAC_DLFW_MEM_EMEM_RSVD_PG;
3222 		else
3223 			mem_halmac = HALMAC_DLFW_MEM_EMEM;
3224 		break;
3225 
3226 	case FW_IMEM:
3227 	case FW_DMEM:
3228 		mem_halmac = HALMAC_DLFW_MEM_UNDEFINE;
3229 		break;
3230 	}
3231 
3232 	return mem_halmac;
3233 }
3234 
rtw_halmac_dlfw_mem(struct dvobj_priv * d,u8 * fw,u32 fwsize,enum fw_mem mem)3235 int rtw_halmac_dlfw_mem(struct dvobj_priv *d, u8 *fw, u32 fwsize, enum fw_mem mem)
3236 {
3237 	struct _HALMAC_ADAPTER *mac;
3238 	struct _HALMAC_API *api;
3239 	enum _HALMAC_RET_STATUS status;
3240 	enum _HALMAC_DLFW_MEM dlfw_mem;
3241 	u8 tx_stop = _FALSE;
3242 	u32 chk_timeout = 2000; /* unit: ms */
3243 	int err = 0;
3244 
3245 
3246 	mac = dvobj_to_halmac(d);
3247 	api = HALMAC_GET_API(mac);
3248 
3249 	if ((!fw) || (!fwsize))
3250 		return -1;
3251 
3252 #ifndef RTW_HALMAC_DLFW_MEM_NO_STOP_TX
3253 	/* 1. Driver Stop Tx */
3254 	/* ToDo */
3255 
3256 	/* 2. Driver Check Tx FIFO is empty */
3257 	err = rtw_halmac_txfifo_wait_empty(d, chk_timeout);
3258 	if (err)
3259 		tx_stop = _FALSE;
3260 	else
3261 		tx_stop = _TRUE;
3262 #endif /* !RTW_HALMAC_DLFW_MEM_NO_STOP_TX */
3263 
3264 	/* 3. Download Firmware MEM */
3265 	dlfw_mem = _fw_mem_drv2halmac(mem, tx_stop);
3266 	if (dlfw_mem == HALMAC_DLFW_MEM_UNDEFINE) {
3267 		err = -1;
3268 		goto resume_tx;
3269 	}
3270 	status = api->halmac_free_download_firmware(mac, dlfw_mem, fw, fwsize);
3271 	if (status != HALMAC_RET_SUCCESS) {
3272 		RTW_ERR("%s: halmac_free_download_firmware fail(err=0x%x)\n",
3273 			__FUNCTION__, status);
3274 		err = -1;
3275 		goto resume_tx;
3276 	}
3277 
3278 resume_tx:
3279 #ifndef RTW_HALMAC_DLFW_MEM_NO_STOP_TX
3280 	/* 4. Driver resume TX if needed */
3281 	/* ToDo */
3282 #endif /* !RTW_HALMAC_DLFW_MEM_NO_STOP_TX */
3283 
3284 	return err;
3285 }
3286 
rtw_halmac_dlfw_mem_from_file(struct dvobj_priv * d,u8 * fwpath,enum fw_mem mem)3287 int rtw_halmac_dlfw_mem_from_file(struct dvobj_priv *d, u8 *fwpath, enum fw_mem mem)
3288 {
3289 	u8 *fw = NULL;
3290 	u32 fwmaxsize = 0, size = 0;
3291 	int err = 0;
3292 
3293 
3294 	err = rtw_halmac_get_fw_max_size(d, &fwmaxsize);
3295 	if (err) {
3296 		RTW_ERR("%s: Fail to get Firmware MAX size(err=%d)\n", __FUNCTION__, err);
3297 		return -1;
3298 	}
3299 
3300 	fw = rtw_zmalloc(fwmaxsize);
3301 	if (!fw)
3302 		return -1;
3303 
3304 	size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
3305 	if (size)
3306 		err = rtw_halmac_dlfw_mem(d, fw, size, mem);
3307 	else
3308 		err = -1;
3309 
3310 	rtw_mfree(fw, fwmaxsize);
3311 	/*fw = NULL;*/
3312 
3313 	return err;
3314 }
3315 
3316 /*
3317  * Return:
3318  *	0	Success
3319  *	-22	Invalid arguemnt
3320  */
rtw_halmac_dlfw(struct dvobj_priv * d,u8 * fw,u32 fwsize)3321 int rtw_halmac_dlfw(struct dvobj_priv *d, u8 *fw, u32 fwsize)
3322 {
3323 	PADAPTER adapter;
3324 	HALMAC_RET_STATUS status;
3325 	u32 ok;
3326 	int err, err_ret = -1;
3327 
3328 
3329 	if (!fw || !fwsize)
3330 		return -22;
3331 
3332 	adapter = dvobj_get_primary_adapter(d);
3333 
3334 	/* re-download firmware */
3335 	if (rtw_is_hw_init_completed(adapter))
3336 		return download_fw(d, fw, fwsize, 1);
3337 
3338 	/* Download firmware before hal init */
3339 	/* Power on, download firmware and init mac */
3340 	ok = rtw_hal_power_on(adapter);
3341 	if (_FAIL == ok)
3342 		goto out;
3343 
3344 	err = download_fw(d, fw, fwsize, 0);
3345 	if (err) {
3346 		err_ret = err;
3347 		goto out;
3348 	}
3349 
3350 	err = init_mac_flow(d);
3351 	if (err)
3352 		goto out;
3353 
3354 	err = _send_general_info(d);
3355 	if (err)
3356 		goto out;
3357 
3358 	err_ret = 0;
3359 
3360 out:
3361 	return err_ret;
3362 }
3363 
rtw_halmac_dlfw_from_file(struct dvobj_priv * d,u8 * fwpath)3364 int rtw_halmac_dlfw_from_file(struct dvobj_priv *d, u8 *fwpath)
3365 {
3366 	u8 *fw = NULL;
3367 	u32 fwmaxsize = 0, size = 0;
3368 	int err = 0;
3369 
3370 
3371 	err = rtw_halmac_get_fw_max_size(d, &fwmaxsize);
3372 	if (err) {
3373 		RTW_ERR("%s: Fail to get Firmware MAX size(err=%d)\n", __FUNCTION__, err);
3374 		return -1;
3375 	}
3376 
3377 	fw = rtw_zmalloc(fwmaxsize);
3378 	if (!fw)
3379 		return -1;
3380 
3381 	size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
3382 	if (size)
3383 		err = rtw_halmac_dlfw(d, fw, size);
3384 	else
3385 		err = -1;
3386 
3387 	rtw_mfree(fw, fwmaxsize);
3388 	/*fw = NULL;*/
3389 
3390 	return err;
3391 }
3392 
3393 /*
3394  * Description:
3395  *	Power on/off BB/RF domain.
3396  *
3397  * Parameters:
3398  *	enable	_TRUE/_FALSE for power on/off
3399  *
3400  * Return:
3401  *	0	Success
3402  *	others	Fail
3403  */
rtw_halmac_phy_power_switch(struct dvobj_priv * d,u8 enable)3404 int rtw_halmac_phy_power_switch(struct dvobj_priv *d, u8 enable)
3405 {
3406 	PADAPTER adapter;
3407 	PHALMAC_ADAPTER halmac;
3408 	PHALMAC_API api;
3409 	HALMAC_RET_STATUS status;
3410 
3411 
3412 	adapter = dvobj_get_primary_adapter(d);
3413 	halmac = dvobj_to_halmac(d);
3414 	if (!halmac)
3415 		return -1;
3416 	api = HALMAC_GET_API(halmac);
3417 
3418 	status = api->halmac_set_hw_value(halmac, HALMAC_HW_EN_BB_RF, &enable);
3419 	if (status != HALMAC_RET_SUCCESS)
3420 		return -1;
3421 
3422 	return 0;
3423 }
3424 
_is_fw_read_cmd_down(PADAPTER adapter,u8 msgbox_num)3425 static u8 _is_fw_read_cmd_down(PADAPTER adapter, u8 msgbox_num)
3426 {
3427 	u8 read_down = _FALSE;
3428 	int retry_cnts = 100;
3429 	u8 valid;
3430 
3431 	do {
3432 		valid = rtw_read8(adapter, REG_HMETFR) & BIT(msgbox_num);
3433 		if (0 == valid)
3434 			read_down = _TRUE;
3435 		else
3436 			rtw_msleep_os(1);
3437 	} while ((!read_down) && (retry_cnts--));
3438 
3439 	if (_FALSE == read_down)
3440 		RTW_WARN("%s, reg_1cc(%x), msg_box(%d)...\n", __func__, rtw_read8(adapter, REG_HMETFR), msgbox_num);
3441 
3442 	return read_down;
3443 }
3444 
3445 /**
3446  * rtw_halmac_send_h2c() - Send H2C to firmware
3447  * @d:		struct dvobj_priv*
3448  * @h2c:	H2C data buffer, suppose to be 8 bytes
3449  *
3450  * Send H2C to firmware by message box register(0x1D0~0x1D3 & 0x1F0~0x1F3).
3451  *
3452  * Return: 0 if process OK, otherwise fail to send this H2C.
3453  */
rtw_halmac_send_h2c(struct dvobj_priv * d,u8 * h2c)3454 int rtw_halmac_send_h2c(struct dvobj_priv *d, u8 *h2c)
3455 {
3456 	PADAPTER adapter = dvobj_get_primary_adapter(d);
3457 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
3458 	u8 h2c_box_num = 0;
3459 	u32 msgbox_addr = 0;
3460 	u32 msgbox_ex_addr = 0;
3461 	u32 h2c_cmd = 0;
3462 	u32 h2c_cmd_ex = 0;
3463 	int err = -1;
3464 
3465 	if (hal->bFWReady == _FALSE) {
3466 		RTW_WARN("%s: return H2C cmd because fw is not ready\n", __FUNCTION__);
3467 		return err;
3468 	}
3469 
3470 	if (!h2c) {
3471 		RTW_WARN("%s: pbuf is NULL\n", __FUNCTION__);
3472 		return err;
3473 	}
3474 
3475 	if (rtw_is_surprise_removed(adapter)) {
3476 		RTW_WARN("%s: surprise removed\n", __FUNCTION__);
3477 		return err;
3478 	}
3479 
3480 	_enter_critical_mutex(&d->h2c_fwcmd_mutex, NULL);
3481 
3482 	/* pay attention to if race condition happened in H2C cmd setting */
3483 	h2c_box_num = hal->LastHMEBoxNum;
3484 
3485 	if (!_is_fw_read_cmd_down(adapter, h2c_box_num)) {
3486 		RTW_WARN(" fw read cmd failed...\n");
3487 #ifdef DBG_CONFIG_ERROR_DETECT
3488 		hal->srestpriv.self_dect_fw = _TRUE;
3489 		hal->srestpriv.self_dect_fw_cnt++;
3490 #endif /* DBG_CONFIG_ERROR_DETECT */
3491 		goto exit;
3492 	}
3493 
3494 	/* Write Ext command (byte 4~7) */
3495 	msgbox_ex_addr = REG_HMEBOX_E0 + (h2c_box_num * EX_MESSAGE_BOX_SIZE);
3496 	_rtw_memcpy((u8 *)(&h2c_cmd_ex), h2c + 4, EX_MESSAGE_BOX_SIZE);
3497 	h2c_cmd_ex = le32_to_cpu(h2c_cmd_ex);
3498 	rtw_write32(adapter, msgbox_ex_addr, h2c_cmd_ex);
3499 
3500 	/* Write command (byte 0~3) */
3501 	msgbox_addr = REG_HMEBOX0 + (h2c_box_num * MESSAGE_BOX_SIZE);
3502 	_rtw_memcpy((u8 *)(&h2c_cmd), h2c, 4);
3503 	h2c_cmd = le32_to_cpu(h2c_cmd);
3504 	rtw_write32(adapter, msgbox_addr, h2c_cmd);
3505 
3506 	/* update last msg box number */
3507 	hal->LastHMEBoxNum = (h2c_box_num + 1) % MAX_H2C_BOX_NUMS;
3508 	err = 0;
3509 
3510 #ifdef DBG_H2C_CONTENT
3511 	RTW_INFO_DUMP("[H2C] - ", h2c, RTW_HALMAC_H2C_MAX_SIZE);
3512 #endif
3513 exit:
3514 	_exit_critical_mutex(&d->h2c_fwcmd_mutex, NULL);
3515 	return err;
3516 }
3517 
3518 /**
3519  * rtw_halmac_c2h_handle() - Handle C2H for HALMAC
3520  * @d:		struct dvobj_priv*
3521  * @c2h:	Full C2H packet, including RX description and payload
3522  * @size:	Size(byte) of c2h
3523  *
3524  * Send C2H packet to HALMAC to process C2H packets, and the expected C2H ID is
3525  * 0xFF. This function won't have any I/O, so caller doesn't have to call it in
3526  * I/O safe place(ex. command thread).
3527  *
3528  * Please sure doesn't call this function in the same thread as someone is
3529  * waiting HALMAC C2H ack, otherwise there is a deadlock happen.
3530  *
3531  * Return: 0 if process OK, otherwise no action for this C2H.
3532  */
rtw_halmac_c2h_handle(struct dvobj_priv * d,u8 * c2h,u32 size)3533 int rtw_halmac_c2h_handle(struct dvobj_priv *d, u8 *c2h, u32 size)
3534 {
3535 	PHALMAC_ADAPTER mac;
3536 	PHALMAC_API api;
3537 	HALMAC_RET_STATUS status;
3538 
3539 
3540 	mac = dvobj_to_halmac(d);
3541 	api = HALMAC_GET_API(mac);
3542 
3543 	status = api->halmac_get_c2h_info(mac, c2h, size);
3544 	if (HALMAC_RET_SUCCESS != status)
3545 		return -1;
3546 
3547 	return 0;
3548 }
3549 
rtw_halmac_get_available_efuse_size(struct dvobj_priv * d,u32 * size)3550 int rtw_halmac_get_available_efuse_size(struct dvobj_priv *d, u32 *size)
3551 {
3552 	PHALMAC_ADAPTER mac;
3553 	PHALMAC_API api;
3554 	HALMAC_RET_STATUS status;
3555 	u32 val;
3556 
3557 
3558 	mac = dvobj_to_halmac(d);
3559 	api = HALMAC_GET_API(mac);
3560 
3561 	status = api->halmac_get_efuse_available_size(mac, &val);
3562 	if (HALMAC_RET_SUCCESS != status)
3563 		return -1;
3564 
3565 	*size = val;
3566 	return 0;
3567 }
3568 
rtw_halmac_get_physical_efuse_size(struct dvobj_priv * d,u32 * size)3569 int rtw_halmac_get_physical_efuse_size(struct dvobj_priv *d, u32 *size)
3570 {
3571 	PHALMAC_ADAPTER mac;
3572 	PHALMAC_API api;
3573 	HALMAC_RET_STATUS status;
3574 	u32 val;
3575 
3576 
3577 	mac = dvobj_to_halmac(d);
3578 	api = HALMAC_GET_API(mac);
3579 
3580 	status = api->halmac_get_efuse_size(mac, &val);
3581 	if (HALMAC_RET_SUCCESS != status)
3582 		return -1;
3583 
3584 	*size = val;
3585 	return 0;
3586 }
3587 
rtw_halmac_read_physical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size)3588 int rtw_halmac_read_physical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size)
3589 {
3590 	PHALMAC_ADAPTER mac;
3591 	PHALMAC_API api;
3592 	HALMAC_RET_STATUS status;
3593 	HALMAC_FEATURE_ID id;
3594 	int ret;
3595 
3596 
3597 	mac = dvobj_to_halmac(d);
3598 	api = HALMAC_GET_API(mac);
3599 	id = HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE;
3600 
3601 	ret = init_halmac_event(d, id, map, size);
3602 	if (ret)
3603 		return -1;
3604 
3605 	status = api->halmac_dump_efuse_map(mac, HALMAC_EFUSE_R_DRV);
3606 	if (HALMAC_RET_SUCCESS != status) {
3607 		free_halmac_event(d, id);
3608 		return -1;
3609 	}
3610 
3611 	ret = wait_halmac_event(d, id);
3612 	if (ret)
3613 		return -1;
3614 
3615 	return 0;
3616 }
3617 
rtw_halmac_read_physical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)3618 int rtw_halmac_read_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
3619 {
3620 	PHALMAC_ADAPTER mac;
3621 	PHALMAC_API api;
3622 	HALMAC_RET_STATUS status;
3623 	u8 v;
3624 	u32 i;
3625 	u8 *efuse = NULL;
3626 	u32 size = 0;
3627 	int err = 0;
3628 
3629 
3630 	mac = dvobj_to_halmac(d);
3631 	api = HALMAC_GET_API(mac);
3632 
3633 	if (api->halmac_read_efuse) {
3634 		for (i = 0; i < cnt; i++) {
3635 			status = api->halmac_read_efuse(mac, offset + i, &v);
3636 			if (HALMAC_RET_SUCCESS != status)
3637 				return -1;
3638 			data[i] = v;
3639 		}
3640 	} else {
3641 		err = rtw_halmac_get_physical_efuse_size(d, &size);
3642 		if (err)
3643 			return -1;
3644 
3645 		efuse = rtw_zmalloc(size);
3646 		if (!efuse)
3647 			return -1;
3648 
3649 		err = rtw_halmac_read_physical_efuse_map(d, efuse, size);
3650 		if (err)
3651 			err = -1;
3652 		else
3653 			_rtw_memcpy(data, efuse + offset, cnt);
3654 
3655 		rtw_mfree(efuse, size);
3656 	}
3657 
3658 	return err;
3659 }
3660 
rtw_halmac_write_physical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)3661 int rtw_halmac_write_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
3662 {
3663 	PHALMAC_ADAPTER mac;
3664 	PHALMAC_API api;
3665 	HALMAC_RET_STATUS status;
3666 	u32 i;
3667 
3668 
3669 	mac = dvobj_to_halmac(d);
3670 	api = HALMAC_GET_API(mac);
3671 
3672 	if (api->halmac_write_efuse == NULL)
3673 		return -1;
3674 
3675 	for (i = 0; i < cnt; i++) {
3676 		status = api->halmac_write_efuse(mac, offset + i, data[i]);
3677 		if (HALMAC_RET_SUCCESS != status)
3678 			return -1;
3679 	}
3680 
3681 	return 0;
3682 }
3683 
rtw_halmac_get_logical_efuse_size(struct dvobj_priv * d,u32 * size)3684 int rtw_halmac_get_logical_efuse_size(struct dvobj_priv *d, u32 *size)
3685 {
3686 	PHALMAC_ADAPTER mac;
3687 	PHALMAC_API api;
3688 	HALMAC_RET_STATUS status;
3689 	u32 val;
3690 
3691 
3692 	mac = dvobj_to_halmac(d);
3693 	api = HALMAC_GET_API(mac);
3694 
3695 	status = api->halmac_get_logical_efuse_size(mac, &val);
3696 	if (HALMAC_RET_SUCCESS != status)
3697 		return -1;
3698 
3699 	*size = val;
3700 	return 0;
3701 }
3702 
rtw_halmac_read_logical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size,u8 * maskmap,u32 masksize)3703 int rtw_halmac_read_logical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size, u8 *maskmap, u32 masksize)
3704 {
3705 	PHALMAC_ADAPTER mac;
3706 	PHALMAC_API api;
3707 	HALMAC_RET_STATUS status;
3708 	HALMAC_FEATURE_ID id;
3709 	int ret;
3710 
3711 
3712 	mac = dvobj_to_halmac(d);
3713 	api = HALMAC_GET_API(mac);
3714 	id = HALMAC_FEATURE_DUMP_LOGICAL_EFUSE;
3715 
3716 	ret = init_halmac_event(d, id, map, size);
3717 	if (ret)
3718 		return -1;
3719 
3720 	status = api->halmac_dump_logical_efuse_map(mac, HALMAC_EFUSE_R_DRV);
3721 	if (HALMAC_RET_SUCCESS != status) {
3722 		free_halmac_event(d, id);
3723 		return -1;
3724 	}
3725 
3726 	ret = wait_halmac_event(d, id);
3727 	if (ret)
3728 		return -1;
3729 
3730 	if (maskmap && masksize) {
3731 		struct _HALMAC_PG_EFUSE_INFO pginfo;
3732 
3733 		pginfo.pEfuse_map = map;
3734 		pginfo.efuse_map_size = size;
3735 		pginfo.pEfuse_mask = maskmap;
3736 		pginfo.efuse_mask_size = masksize;
3737 
3738 		status = api->halmac_mask_logical_efuse(mac, &pginfo);
3739 		if (status != HALMAC_RET_SUCCESS)
3740 			RTW_WARN("%s: mask logical efuse FAIL!\n", __FUNCTION__);
3741 	}
3742 
3743 	return 0;
3744 }
3745 
rtw_halmac_write_logical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size,u8 * maskmap,u32 masksize)3746 int rtw_halmac_write_logical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size, u8 *maskmap, u32 masksize)
3747 {
3748 	PHALMAC_ADAPTER mac;
3749 	PHALMAC_API api;
3750 	HALMAC_PG_EFUSE_INFO pginfo;
3751 	HALMAC_RET_STATUS status;
3752 
3753 
3754 	mac = dvobj_to_halmac(d);
3755 	api = HALMAC_GET_API(mac);
3756 
3757 	pginfo.pEfuse_map = map;
3758 	pginfo.efuse_map_size = size;
3759 	pginfo.pEfuse_mask = maskmap;
3760 	pginfo.efuse_mask_size = masksize;
3761 
3762 	status = api->halmac_pg_efuse_by_map(mac, &pginfo, HALMAC_EFUSE_R_AUTO);
3763 	if (HALMAC_RET_SUCCESS != status)
3764 		return -1;
3765 
3766 	return 0;
3767 }
3768 
rtw_halmac_read_logical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)3769 int rtw_halmac_read_logical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
3770 {
3771 	PHALMAC_ADAPTER mac;
3772 	PHALMAC_API api;
3773 	HALMAC_RET_STATUS status;
3774 	u8 v;
3775 	u32 i;
3776 
3777 
3778 	mac = dvobj_to_halmac(d);
3779 	api = HALMAC_GET_API(mac);
3780 
3781 	for (i = 0; i < cnt; i++) {
3782 		status = api->halmac_read_logical_efuse(mac, offset + i, &v);
3783 		if (HALMAC_RET_SUCCESS != status)
3784 			return -1;
3785 		data[i] = v;
3786 	}
3787 
3788 	return 0;
3789 }
3790 
rtw_halmac_write_logical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)3791 int rtw_halmac_write_logical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
3792 {
3793 	PHALMAC_ADAPTER mac;
3794 	PHALMAC_API api;
3795 	HALMAC_RET_STATUS status;
3796 	u32 i;
3797 
3798 
3799 	mac = dvobj_to_halmac(d);
3800 	api = HALMAC_GET_API(mac);
3801 
3802 	for (i = 0; i < cnt; i++) {
3803 		status = api->halmac_write_logical_efuse(mac, offset + i, data[i]);
3804 		if (HALMAC_RET_SUCCESS != status)
3805 			return -1;
3806 	}
3807 
3808 	return 0;
3809 }
3810 
rtw_halmac_write_bt_physical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)3811 int rtw_halmac_write_bt_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
3812 {
3813 	PHALMAC_ADAPTER mac;
3814 	PHALMAC_API api;
3815 	HALMAC_RET_STATUS status;
3816 	u32 i;
3817 	u8 bank = 1;
3818 
3819 	mac = dvobj_to_halmac(d);
3820 	api = HALMAC_GET_API(mac);
3821 
3822 	for (i = 0; i < cnt; i++) {
3823 		status = api->halmac_write_efuse_bt(mac, offset + i, data[i], bank);
3824 		if (HALMAC_RET_SUCCESS != status) {
3825 			printk("%s: halmac_write_efuse_bt status = %d\n", __FUNCTION__, status);
3826 			return -1;
3827 		}
3828 	}
3829 	printk("%s: halmac_write_efuse_bt status = HALMAC_RET_SUCCESS %d\n", __FUNCTION__, status);
3830 	return 0;
3831 }
3832 
3833 
rtw_halmac_read_bt_physical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size)3834 int rtw_halmac_read_bt_physical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size)
3835 {
3836 	PHALMAC_ADAPTER mac;
3837 	PHALMAC_API api;
3838 	HALMAC_RET_STATUS status;
3839 	HALMAC_FEATURE_ID id;
3840 	int ret;
3841 	int bank = 1;
3842 
3843 	mac = dvobj_to_halmac(d);
3844 	api = HALMAC_GET_API(mac);
3845 
3846 	status = api->halmac_dump_efuse_map_bt(mac, bank, size, map);
3847 	if (HALMAC_RET_SUCCESS != status) {
3848 		printk("%s: halmac_dump_efuse_map_bt fail!\n", __FUNCTION__);
3849 		return -1;
3850 	}
3851 
3852 	printk("%s: OK!\n", __FUNCTION__);
3853 
3854 	return 0;
3855 }
3856 
_fifo_sel_drv2halmac(u8 fifo_sel)3857 static enum _HAL_FIFO_SEL _fifo_sel_drv2halmac(u8 fifo_sel)
3858 {
3859 	switch (fifo_sel) {
3860 	case 0:
3861 		return HAL_FIFO_SEL_TX;
3862 	case 1:
3863 		return HAL_FIFO_SEL_RX;
3864 	case 2:
3865 		return HAL_FIFO_SEL_RSVD_PAGE;
3866 	case 3:
3867 		return HAL_FIFO_SEL_REPORT;
3868 	case 4:
3869 		return HAL_FIFO_SEL_LLT;
3870 	case 5:
3871 		return HAL_FIFO_SEL_RXBUF_FW;
3872 	}
3873 
3874 	return HAL_FIFO_SEL_RSVD_PAGE;
3875 }
3876 
3877 /*#define CONFIG_HALMAC_FIFO_DUMP*/
rtw_halmac_dump_fifo(struct dvobj_priv * d,u8 fifo_sel,u32 addr,u32 size,u8 * buffer)3878 int rtw_halmac_dump_fifo(struct dvobj_priv *d, u8 fifo_sel, u32 addr, u32 size, u8 *buffer)
3879 {
3880 	PHALMAC_ADAPTER mac;
3881 	PHALMAC_API api;
3882 	HALMAC_RET_STATUS status;
3883 	u8 *pfifo_map = NULL;
3884 	u32 fifo_size = 0;
3885 	s8 ret = 0;/* 0:success, -1:error */
3886 	u8 mem_created = _FALSE;
3887 
3888 	HAL_FIFO_SEL halmac_fifo_sel;
3889 
3890 	mac = dvobj_to_halmac(d);
3891 	api = HALMAC_GET_API(mac);
3892 
3893 	if ((size != 0) && (buffer == NULL))
3894 		return -1;
3895 
3896 	halmac_fifo_sel = _fifo_sel_drv2halmac(fifo_sel);
3897 
3898 	if ((size) && (buffer)) {
3899 		pfifo_map = buffer;
3900 		fifo_size = size;
3901 	} else {
3902 		fifo_size = api->halmac_get_fifo_size(mac, halmac_fifo_sel);
3903 
3904 		if (fifo_size)
3905 			pfifo_map = rtw_zvmalloc(fifo_size);
3906 		if (pfifo_map == NULL)
3907 			return -1;
3908 		mem_created = _TRUE;
3909 	}
3910 
3911 	status = api->halmac_dump_fifo(mac, halmac_fifo_sel, addr, fifo_size, pfifo_map);
3912 	if (HALMAC_RET_SUCCESS != status) {
3913 		ret = -1;
3914 		goto _exit;
3915 	}
3916 
3917 #ifdef CONFIG_HALMAC_FIFO_DUMP
3918 	{
3919 		static const char * const fifo_sel_str[] = {
3920 			"TX", "RX", "RSVD_PAGE", "REPORT", "LLT", "RXBUF_FW"
3921 		};
3922 
3923 		RTW_INFO("%s FIFO DUMP [start_addr:0x%04x , size:%d]\n", fifo_sel_str[halmac_fifo_sel], addr, fifo_size);
3924 		RTW_INFO_DUMP("\n", pfifo_map, fifo_size);
3925 		RTW_INFO(" ==================================================\n");
3926 	}
3927 #endif /* CONFIG_HALMAC_FIFO_DUMP */
3928 
3929 _exit:
3930 	if ((mem_created == _TRUE) && pfifo_map)
3931 		rtw_vmfree(pfifo_map, fifo_size);
3932 
3933 	return ret;
3934 }
3935 
rtw_halmac_rx_agg_switch(struct dvobj_priv * d,u8 enable)3936 int rtw_halmac_rx_agg_switch(struct dvobj_priv *d, u8 enable)
3937 {
3938 	PADAPTER adapter;
3939 	PHAL_DATA_TYPE hal;
3940 	PHALMAC_ADAPTER halmac;
3941 	PHALMAC_API api;
3942 	HALMAC_RXAGG_CFG rxaggcfg;
3943 	HALMAC_RET_STATUS status;
3944 	int err = -1;
3945 
3946 
3947 	adapter = dvobj_get_primary_adapter(d);
3948 	hal = GET_HAL_DATA(adapter);
3949 	halmac = dvobj_to_halmac(d);
3950 	api = HALMAC_GET_API(halmac);
3951 	_rtw_memset((void *)&rxaggcfg, 0, sizeof(rxaggcfg));
3952 
3953 	if (_TRUE == enable) {
3954 #ifdef CONFIG_SDIO_HCI
3955 		rxaggcfg.mode = HALMAC_RX_AGG_MODE_DMA;
3956 		rxaggcfg.threshold.drv_define = 0;
3957 		if (hal->rxagg_dma_size || hal->rxagg_dma_timeout) {
3958 			rxaggcfg.threshold.drv_define = 1;
3959 			rxaggcfg.threshold.timeout = hal->rxagg_dma_timeout;
3960 			rxaggcfg.threshold.size = hal->rxagg_dma_size;
3961 			RTW_INFO("%s: RX aggregation threshold: "
3962 				 "timeout=%u size=%u\n",
3963 				 __FUNCTION__,
3964 				 hal->rxagg_dma_timeout,
3965 				 hal->rxagg_dma_size);
3966 		}
3967 #elif defined(CONFIG_USB_HCI) && defined(CONFIG_USB_RX_AGGREGATION)
3968 		switch (hal->rxagg_mode) {
3969 		case RX_AGG_DISABLE:
3970 			rxaggcfg.mode = HALMAC_RX_AGG_MODE_NONE;
3971 			break;
3972 
3973 		case RX_AGG_DMA:
3974 			rxaggcfg.mode = HALMAC_RX_AGG_MODE_DMA;
3975 			if (hal->rxagg_dma_size || hal->rxagg_dma_timeout) {
3976 				rxaggcfg.threshold.drv_define = 1;
3977 				rxaggcfg.threshold.timeout = hal->rxagg_dma_timeout;
3978 				rxaggcfg.threshold.size = hal->rxagg_dma_size;
3979 				RTW_INFO("%s: RX DMA aggregation threshold: "
3980 					 "timeout=%u size=%u\n",
3981 					 __FUNCTION__,
3982 					 hal->rxagg_dma_timeout,
3983 					 hal->rxagg_dma_size);
3984 			}
3985 			break;
3986 
3987 		case RX_AGG_USB:
3988 		case RX_AGG_MIX:
3989 			rxaggcfg.mode = HALMAC_RX_AGG_MODE_USB;
3990 			if (hal->rxagg_usb_size || hal->rxagg_usb_timeout) {
3991 				rxaggcfg.threshold.drv_define = 1;
3992 				rxaggcfg.threshold.timeout = hal->rxagg_usb_timeout;
3993 				rxaggcfg.threshold.size = hal->rxagg_usb_size;
3994 				RTW_INFO("%s: RX USB aggregation threshold: "
3995 					 "timeout=%u size=%u\n",
3996 					 __FUNCTION__,
3997 					 hal->rxagg_usb_timeout,
3998 					 hal->rxagg_usb_size);
3999 			}
4000 			break;
4001 		}
4002 #endif /* CONFIG_USB_HCI */
4003 	} else {
4004 		rxaggcfg.mode = HALMAC_RX_AGG_MODE_NONE;
4005 	}
4006 
4007 	status = api->halmac_cfg_rx_aggregation(halmac, &rxaggcfg);
4008 	if (status != HALMAC_RET_SUCCESS)
4009 		goto out;
4010 
4011 	err = 0;
4012 out:
4013 	return err;
4014 }
4015 
rtw_halmac_download_rsvd_page(struct dvobj_priv * dvobj,u8 pg_offset,u8 * pbuf,u32 size)4016 int rtw_halmac_download_rsvd_page(struct dvobj_priv *dvobj, u8 pg_offset, u8 *pbuf, u32 size)
4017 {
4018 	HALMAC_RET_STATUS status = HALMAC_RET_SUCCESS;
4019 	PHALMAC_ADAPTER halmac = dvobj_to_halmac(dvobj);
4020 	PHALMAC_API api = HALMAC_GET_API(halmac);
4021 
4022 	status = api->halmac_dl_drv_rsvd_page(halmac, pg_offset, pbuf, size);
4023 	if (status != HALMAC_RET_SUCCESS)
4024 		return -1;
4025 
4026 	return 0;
4027 }
4028 
4029 /*
4030  * Description
4031  *	Fill following spec info from HALMAC API:
4032  *	sec_cam_ent_num
4033  *
4034  * Return
4035  *	0	Success
4036  *	others	Fail
4037  */
rtw_halmac_fill_hal_spec(struct dvobj_priv * dvobj,struct hal_spec_t * spec)4038 int rtw_halmac_fill_hal_spec(struct dvobj_priv *dvobj, struct hal_spec_t *spec)
4039 {
4040 	HALMAC_RET_STATUS status;
4041 	PHALMAC_ADAPTER halmac;
4042 	PHALMAC_API api;
4043 	u8 cam = 0;	/* Security Cam Entry Number */
4044 
4045 
4046 	halmac = dvobj_to_halmac(dvobj);
4047 	api = HALMAC_GET_API(halmac);
4048 
4049 	/* Prepare data from HALMAC */
4050 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_CAM_ENTRY_NUM, &cam);
4051 	if (status != HALMAC_RET_SUCCESS)
4052 		return -1;
4053 
4054 	/* Fill data to hal_spec_t */
4055 	spec->sec_cam_ent_num = cam;
4056 
4057 	return 0;
4058 }
4059 
rtw_halmac_p2pps(struct dvobj_priv * dvobj,PHAL_P2P_PS_PARA pp2p_ps_para)4060 int rtw_halmac_p2pps(struct dvobj_priv *dvobj, PHAL_P2P_PS_PARA pp2p_ps_para)
4061 {
4062 	HALMAC_RET_STATUS status = HALMAC_RET_SUCCESS;
4063 	PHALMAC_ADAPTER halmac = dvobj_to_halmac(dvobj);
4064 	PHALMAC_API api = HALMAC_GET_API(halmac);
4065 	HALMAC_P2PPS halmac_p2p_ps;
4066 
4067 	(&halmac_p2p_ps)->offload_en = pp2p_ps_para->offload_en;
4068 	(&halmac_p2p_ps)->role = pp2p_ps_para->role;
4069 	(&halmac_p2p_ps)->ctwindow_en = pp2p_ps_para->ctwindow_en;
4070 	(&halmac_p2p_ps)->noa_en = pp2p_ps_para->noa_en;
4071 	(&halmac_p2p_ps)->noa_sel = pp2p_ps_para->noa_sel;
4072 	(&halmac_p2p_ps)->all_sta_sleep = pp2p_ps_para->all_sta_sleep;
4073 	(&halmac_p2p_ps)->discovery = pp2p_ps_para->discovery;
4074 	(&halmac_p2p_ps)->p2p_port_id = _hw_port_drv2halmac(pp2p_ps_para->p2p_port_id);
4075 	(&halmac_p2p_ps)->p2p_group = pp2p_ps_para->p2p_group;
4076 	(&halmac_p2p_ps)->p2p_macid = pp2p_ps_para->p2p_macid;
4077 	(&halmac_p2p_ps)->ctwindow_length = pp2p_ps_para->ctwindow_length;
4078 	(&halmac_p2p_ps)->noa_duration_para = pp2p_ps_para->noa_duration_para;
4079 	(&halmac_p2p_ps)->noa_interval_para = pp2p_ps_para->noa_interval_para;
4080 	(&halmac_p2p_ps)->noa_start_time_para = pp2p_ps_para->noa_start_time_para;
4081 	(&halmac_p2p_ps)->noa_count_para = pp2p_ps_para->noa_count_para;
4082 
4083 	status = api->halmac_p2pps(halmac, (&halmac_p2p_ps));
4084 	if (status != HALMAC_RET_SUCCESS)
4085 		return -1;
4086 
4087 	return 0;
4088 
4089 }
4090 
4091 /**
4092  * rtw_halmac_iqk() - Run IQ Calibration
4093  * @d:		struct dvobj_priv*
4094  * @clear:	IQK parameters
4095  * @segment:	IQK parameters
4096  *
4097  * Process IQ Calibration(IQK).
4098  *
4099  * Rteurn: 0 for OK, otherwise fail.
4100  */
rtw_halmac_iqk(struct dvobj_priv * d,u8 clear,u8 segment)4101 int rtw_halmac_iqk(struct dvobj_priv *d, u8 clear, u8 segment)
4102 {
4103 	PHALMAC_ADAPTER mac;
4104 	PHALMAC_API api;
4105 	HALMAC_RET_STATUS status;
4106 	HALMAC_FEATURE_ID id;
4107 	HALMAC_IQK_PARA para;
4108 	int ret;
4109 	u8 retry = 3;
4110 	u8 delay = 1; /* ms */
4111 
4112 
4113 	mac = dvobj_to_halmac(d);
4114 	api = HALMAC_GET_API(mac);
4115 	id = HALMAC_FEATURE_IQK;
4116 
4117 	ret = init_halmac_event(d, id, NULL, 0);
4118 	if (ret)
4119 		return -1;
4120 
4121 	para.clear = clear;
4122 	para.segment_iqk = segment;
4123 
4124 	do {
4125 		status = api->halmac_start_iqk(mac, &para);
4126 		if (status != HALMAC_RET_BUSY_STATE)
4127 			break;
4128 		RTW_WARN("%s: Fail to start IQK, status is BUSY! retry=%d\n", __FUNCTION__, retry);
4129 		if (!retry)
4130 			break;
4131 		retry--;
4132 		rtw_msleep_os(delay);
4133 	} while (1);
4134 	if (status != HALMAC_RET_SUCCESS) {
4135 		free_halmac_event(d, id);
4136 		return -1;
4137 	}
4138 
4139 	ret = wait_halmac_event(d, id);
4140 	if (ret)
4141 		return -1;
4142 
4143 	return 0;
4144 }
4145 
_phy_parameter_drv2halmac(struct rtw_phy_parameter * para,struct _HALMAC_PHY_PARAMETER_INFO * info)4146 static int _phy_parameter_drv2halmac(struct rtw_phy_parameter *para, struct _HALMAC_PHY_PARAMETER_INFO *info)
4147 {
4148 	if (!para || !info)
4149 		return -1;
4150 
4151 	_rtw_memset(info, 0, sizeof(*info));
4152 
4153 	switch (para->cmd) {
4154 	case 0:
4155 		/* MAC register */
4156 		switch (para->data.mac.size) {
4157 		case 1:
4158 			info->cmd_id = HALMAC_PARAMETER_CMD_MAC_W8;
4159 			break;
4160 		case 2:
4161 			info->cmd_id = HALMAC_PARAMETER_CMD_MAC_W16;
4162 			break;
4163 		default:
4164 			info->cmd_id = HALMAC_PARAMETER_CMD_MAC_W32;
4165 			break;
4166 		}
4167 		info->content.MAC_REG_W.value = para->data.mac.value;
4168 		info->content.MAC_REG_W.msk = para->data.mac.msk;
4169 		info->content.MAC_REG_W.offset = para->data.mac.offset;
4170 		info->content.MAC_REG_W.msk_en = para->data.mac.msk_en;
4171 		break;
4172 
4173 	case 1:
4174 		/* BB register */
4175 		switch (para->data.bb.size) {
4176 		case 1:
4177 			info->cmd_id = HALMAC_PARAMETER_CMD_BB_W8;
4178 			break;
4179 		case 2:
4180 			info->cmd_id = HALMAC_PARAMETER_CMD_BB_W16;
4181 			break;
4182 		default:
4183 			info->cmd_id = HALMAC_PARAMETER_CMD_BB_W32;
4184 			break;
4185 		}
4186 		info->content.BB_REG_W.value = para->data.mac.value;
4187 		info->content.BB_REG_W.msk = para->data.mac.msk;
4188 		info->content.BB_REG_W.offset = para->data.mac.offset;
4189 		info->content.BB_REG_W.msk_en = para->data.mac.msk_en;
4190 		break;
4191 
4192 	case 2:
4193 		/* RF register */
4194 		info->cmd_id = HALMAC_PARAMETER_CMD_RF_W;
4195 		info->content.RF_REG_W.value = para->data.rf.value;
4196 		info->content.RF_REG_W.msk = para->data.rf.msk;
4197 		info->content.RF_REG_W.offset = para->data.rf.offset;
4198 		info->content.RF_REG_W.msk_en = para->data.rf.msk_en;
4199 		info->content.RF_REG_W.rf_path = para->data.rf.path;
4200 		break;
4201 
4202 	case 3:
4203 		/* Delay register */
4204 		if (para->data.delay.unit == 0)
4205 			info->cmd_id = HALMAC_PARAMETER_CMD_DELAY_US;
4206 		else
4207 			info->cmd_id = HALMAC_PARAMETER_CMD_DELAY_MS;
4208 		info->content.DELAY_TIME.delay_time = para->data.delay.value;
4209 		break;
4210 
4211 	case 0xFF:
4212 		/* Latest(End) command */
4213 		info->cmd_id = HALMAC_PARAMETER_CMD_END;
4214 		break;
4215 
4216 	default:
4217 		return -1;
4218 	}
4219 
4220 	return 0;
4221 }
4222 
4223 /**
4224  * rtw_halmac_cfg_phy_para() - Register(Phy parameter) configuration
4225  * @d:		struct dvobj_priv*
4226  * @para:	phy parameter
4227  *
4228  * Configure registers by firmware using H2C/C2H mechanism.
4229  * The latest command should be para->cmd==0xFF(End command) to finish all
4230  * processes.
4231  *
4232  * Return: 0 for OK, otherwise fail.
4233  */
rtw_halmac_cfg_phy_para(struct dvobj_priv * d,struct rtw_phy_parameter * para)4234 int rtw_halmac_cfg_phy_para(struct dvobj_priv *d, struct rtw_phy_parameter *para)
4235 {
4236 	struct _HALMAC_ADAPTER *mac;
4237 	struct _HALMAC_API *api;
4238 	enum _HALMAC_RET_STATUS status;
4239 	enum _HALMAC_FEATURE_ID id;
4240 	struct _HALMAC_PHY_PARAMETER_INFO info;
4241 	u8 full_fifo;
4242 	int err, ret;
4243 
4244 
4245 	mac = dvobj_to_halmac(d);
4246 	api = HALMAC_GET_API(mac);
4247 	id = HALMAC_FEATURE_CFG_PARA;
4248 	full_fifo = 1; /* ToDo: How to deciede? */
4249 	ret = 0;
4250 
4251 	err = _phy_parameter_drv2halmac(para, &info);
4252 	if (err)
4253 		return -1;
4254 
4255 	err = init_halmac_event(d, id, NULL, 0);
4256 	if (err)
4257 		return -1;
4258 
4259 	status = api->halmac_cfg_parameter(mac, &info, full_fifo);
4260 	if (info.cmd_id == HALMAC_PARAMETER_CMD_END) {
4261 		if (status == HALMAC_RET_SUCCESS) {
4262 			err = wait_halmac_event(d, id);
4263 			if (err)
4264 				ret = -1;
4265 		} else {
4266 			free_halmac_event(d, id);
4267 			ret = -1;
4268 			RTW_ERR("%s: Fail to send END of cfg parameter, status is 0x%x!\n", __FUNCTION__, status);
4269 		}
4270 	} else {
4271 		if (status == HALMAC_RET_PARA_SENDING) {
4272 			err = wait_halmac_event(d, id);
4273 			if (err)
4274 				ret = -1;
4275 		} else {
4276 			free_halmac_event(d, id);
4277 			if (status != HALMAC_RET_SUCCESS) {
4278 				ret = -1;
4279 				RTW_ERR("%s: Fail to cfg parameter, status is 0x%x!\n", __FUNCTION__, status);
4280 			}
4281 		}
4282 	}
4283 
4284 	return ret;
4285 }
4286 
4287 #ifdef CONFIG_SDIO_HCI
4288 
4289 /*
4290  * Description:
4291  *	Update queue allocated page number to driver
4292  *
4293  * Parameter:
4294  *	d	pointer to struct dvobj_priv of driver
4295  *
4296  * Rteurn:
4297  *	0	Success, "page" is valid.
4298  *	others	Fail, "page" is invalid.
4299  */
rtw_halmac_query_tx_page_num(struct dvobj_priv * d)4300 int rtw_halmac_query_tx_page_num(struct dvobj_priv *d)
4301 {
4302 	PADAPTER adapter;
4303 	struct halmacpriv *hmpriv;
4304 	PHALMAC_ADAPTER halmac;
4305 	PHALMAC_API api;
4306 	HALMAC_RQPN_MAP rqpn;
4307 	HALMAC_DMA_MAPPING dmaqueue;
4308 	HALMAC_TXFF_ALLOCATION fifosize;
4309 	HALMAC_RET_STATUS status;
4310 	u8 i;
4311 
4312 
4313 	adapter = dvobj_get_primary_adapter(d);
4314 	hmpriv = &d->hmpriv;
4315 	halmac = dvobj_to_halmac(d);
4316 	api = HALMAC_GET_API(halmac);
4317 	_rtw_memset((void *)&rqpn, 0, sizeof(rqpn));
4318 	_rtw_memset((void *)&fifosize, 0, sizeof(fifosize));
4319 
4320 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RQPN_MAPPING, &rqpn);
4321 	if (status != HALMAC_RET_SUCCESS)
4322 		return -1;
4323 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_TXFF_ALLOCATION, &fifosize);
4324 	if (status != HALMAC_RET_SUCCESS)
4325 		return -1;
4326 
4327 	for (i = 0; i < HW_QUEUE_ENTRY; i++) {
4328 		hmpriv->txpage[i] = 0;
4329 
4330 		/* Driver index mapping to HALMAC DMA queue */
4331 		dmaqueue = HALMAC_DMA_MAPPING_UNDEFINE;
4332 		switch (i) {
4333 		case VO_QUEUE_INX:
4334 			dmaqueue = rqpn.dma_map_vo;
4335 			break;
4336 		case VI_QUEUE_INX:
4337 			dmaqueue = rqpn.dma_map_vi;
4338 			break;
4339 		case BE_QUEUE_INX:
4340 			dmaqueue = rqpn.dma_map_be;
4341 			break;
4342 		case BK_QUEUE_INX:
4343 			dmaqueue = rqpn.dma_map_bk;
4344 			break;
4345 		case MGT_QUEUE_INX:
4346 			dmaqueue = rqpn.dma_map_mg;
4347 			break;
4348 		case HIGH_QUEUE_INX:
4349 			dmaqueue = rqpn.dma_map_hi;
4350 			break;
4351 		case BCN_QUEUE_INX:
4352 		case TXCMD_QUEUE_INX:
4353 			/* Unlimited */
4354 			hmpriv->txpage[i] = 0xFFFF;
4355 			continue;
4356 		}
4357 
4358 		switch (dmaqueue) {
4359 		case HALMAC_DMA_MAPPING_EXTRA:
4360 			hmpriv->txpage[i] = fifosize.extra_queue_pg_num;
4361 			break;
4362 		case HALMAC_DMA_MAPPING_LOW:
4363 			hmpriv->txpage[i] = fifosize.low_queue_pg_num;
4364 			break;
4365 		case HALMAC_DMA_MAPPING_NORMAL:
4366 			hmpriv->txpage[i] = fifosize.normal_queue_pg_num;
4367 			break;
4368 		case HALMAC_DMA_MAPPING_HIGH:
4369 			hmpriv->txpage[i] = fifosize.high_queue_pg_num;
4370 			break;
4371 		case HALMAC_DMA_MAPPING_UNDEFINE:
4372 			break;
4373 		}
4374 		hmpriv->txpage[i] += fifosize.pub_queue_pg_num;
4375 	}
4376 
4377 	return 0;
4378 }
4379 
4380 /*
4381  * Description:
4382  *	Get specific queue allocated page number
4383  *
4384  * Parameter:
4385  *	d	pointer to struct dvobj_priv of driver
4386  *	queue	target queue to query, VO/VI/BE/BK/.../TXCMD_QUEUE_INX
4387  *	page	return allocated page number
4388  *
4389  * Rteurn:
4390  *	0	Success, "page" is valid.
4391  *	others	Fail, "page" is invalid.
4392  */
rtw_halmac_get_tx_queue_page_num(struct dvobj_priv * d,u8 queue,u32 * page)4393 int rtw_halmac_get_tx_queue_page_num(struct dvobj_priv *d, u8 queue, u32 *page)
4394 {
4395 	*page = 0;
4396 	if (queue < HW_QUEUE_ENTRY)
4397 		*page = d->hmpriv.txpage[queue];
4398 
4399 	return 0;
4400 }
4401 
4402 /*
4403  * Return:
4404  *	address for SDIO command
4405  */
rtw_halmac_sdio_get_tx_addr(struct dvobj_priv * d,u8 * desc,u32 size)4406 u32 rtw_halmac_sdio_get_tx_addr(struct dvobj_priv *d, u8 *desc, u32 size)
4407 {
4408 	PHALMAC_ADAPTER mac;
4409 	PHALMAC_API api;
4410 	HALMAC_RET_STATUS status;
4411 	u32 addr;
4412 
4413 
4414 	mac = dvobj_to_halmac(d);
4415 	api = HALMAC_GET_API(mac);
4416 
4417 	status = api->halmac_get_sdio_tx_addr(mac, desc, size, &addr);
4418 	if (HALMAC_RET_SUCCESS != status)
4419 		return 0;
4420 
4421 	return addr;
4422 }
4423 
rtw_halmac_sdio_tx_allowed(struct dvobj_priv * d,u8 * buf,u32 size)4424 int rtw_halmac_sdio_tx_allowed(struct dvobj_priv *d, u8 *buf, u32 size)
4425 {
4426 	PHALMAC_ADAPTER mac;
4427 	PHALMAC_API api;
4428 	HALMAC_RET_STATUS status;
4429 
4430 
4431 	mac = dvobj_to_halmac(d);
4432 	api = HALMAC_GET_API(mac);
4433 
4434 	status = api->halmac_tx_allowed_sdio(mac, buf, size);
4435 	if (HALMAC_RET_SUCCESS != status)
4436 		return -1;
4437 
4438 	return 0;
4439 }
4440 
rtw_halmac_sdio_get_rx_addr(struct dvobj_priv * d,u8 * seq)4441 u32 rtw_halmac_sdio_get_rx_addr(struct dvobj_priv *d, u8 *seq)
4442 {
4443 	u8 id;
4444 
4445 #define RTW_SDIO_ADDR_RX_RX0FF_PRFIX	0x0E000
4446 #define RTW_SDIO_ADDR_RX_RX0FF_GEN(a)	(RTW_SDIO_ADDR_RX_RX0FF_PRFIX|(a&0x3))
4447 
4448 	id = *seq;
4449 	(*seq)++;
4450 	return RTW_SDIO_ADDR_RX_RX0FF_GEN(id);
4451 }
4452 #endif /* CONFIG_SDIO_HCI */
4453 
4454 #ifdef CONFIG_USB_HCI
rtw_halmac_usb_get_bulkout_id(struct dvobj_priv * d,u8 * buf,u32 size)4455 u8 rtw_halmac_usb_get_bulkout_id(struct dvobj_priv *d, u8 *buf, u32 size)
4456 {
4457 	PHALMAC_ADAPTER mac;
4458 	PHALMAC_API api;
4459 	HALMAC_RET_STATUS status;
4460 	u8 bulkout_id;
4461 
4462 
4463 	mac = dvobj_to_halmac(d);
4464 	api = HALMAC_GET_API(mac);
4465 
4466 	status = api->halmac_get_usb_bulkout_id(mac, buf, size, &bulkout_id);
4467 	if (HALMAC_RET_SUCCESS != status)
4468 		return 0;
4469 
4470 	return bulkout_id;
4471 }
4472 
4473 /**
4474  * rtw_halmac_usb_get_txagg_desc_num() - MAX descriptor number in one bulk for TX
4475  * @d:		struct dvobj_priv*
4476  * @size:	TX FIFO size, unit is byte.
4477  *
4478  * Get MAX descriptor number in one bulk out from HALMAC.
4479  *
4480  * Rteurn 0 for OK, otherwise fail.
4481  */
rtw_halmac_usb_get_txagg_desc_num(struct dvobj_priv * d,u8 * num)4482 int rtw_halmac_usb_get_txagg_desc_num(struct dvobj_priv *d, u8 *num)
4483 {
4484 	struct _HALMAC_ADAPTER *halmac;
4485 	struct _HALMAC_API *api;
4486 	enum _HALMAC_RET_STATUS status;
4487 	u8 val = 0;
4488 
4489 
4490 	halmac = dvobj_to_halmac(d);
4491 	api = HALMAC_GET_API(halmac);
4492 
4493 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_USB_TXAGG_DESC_NUM, &val);
4494 	if (status != HALMAC_RET_SUCCESS)
4495 		return -1;
4496 
4497 	*num = val;
4498 
4499 	return 0;
4500 }
4501 
_usb_mode_drv2halmac(enum RTW_USB_SPEED usb_mode)4502 static inline HALMAC_USB_MODE _usb_mode_drv2halmac(enum RTW_USB_SPEED usb_mode)
4503 {
4504 	HALMAC_USB_MODE halmac_usb_mode = HALMAC_USB_MODE_U2;
4505 
4506 	switch (usb_mode) {
4507 	case RTW_USB_SPEED_2:
4508 		halmac_usb_mode = HALMAC_USB_MODE_U2;
4509 		break;
4510 	case RTW_USB_SPEED_3:
4511 		halmac_usb_mode = HALMAC_USB_MODE_U3;
4512 		break;
4513 	default:
4514 		halmac_usb_mode = HALMAC_USB_MODE_U2;
4515 		break;
4516 	}
4517 
4518 	return halmac_usb_mode;
4519 }
4520 
rtw_halmac_switch_usb_mode(struct dvobj_priv * d,enum RTW_USB_SPEED usb_mode)4521 u8 rtw_halmac_switch_usb_mode(struct dvobj_priv *d, enum RTW_USB_SPEED usb_mode)
4522 {
4523 	PHALMAC_ADAPTER mac;
4524 	PHALMAC_API api;
4525 	HALMAC_RET_STATUS status;
4526 	PADAPTER adapter;
4527 	HALMAC_USB_MODE halmac_usb_mode;
4528 
4529 	adapter = dvobj_get_primary_adapter(d);
4530 	mac = dvobj_to_halmac(d);
4531 	api = HALMAC_GET_API(mac);
4532 	halmac_usb_mode = _usb_mode_drv2halmac(usb_mode);
4533 	status = api->halmac_set_hw_value(mac, HALMAC_HW_USB_MODE, (void *)&halmac_usb_mode);
4534 
4535 	if (HALMAC_RET_SUCCESS != status)
4536 		return _FAIL;
4537 
4538 	return _SUCCESS;
4539 }
4540 #endif /* CONFIG_USB_HCI */
4541