1 /******************************************************************************
3 * Copyright(c) 2015 - 2018 Realtek Corporation.
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.
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
14 *****************************************************************************/
15 #define _HAL_HALMAC_C_
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. */
22 * HALMAC take return value 0 for fail and 1 for success to replace
23 * _FALSE/_TRUE after V1_04_09
25 #define RTW_HALMAC_FAIL 0
26 #define RTW_HALMAC_SUCCESS 1
28 #define DEFAULT_INDICATOR_TIMELMT 1000 /* ms */
29 #define MSG_PREFIX "[HALMAC]"
31 #define RTW_HALMAC_DLFW_MEM_NO_STOP_TX
34 * Driver API for HALMAC operations
37 #ifdef CONFIG_SDIO_HCI
40 static u8 _halmac_mac_reg_page0_chk(const char *func, struct dvobj_priv *dvobj, u32 offset)
42 #if defined(CONFIG_IO_CHECK_IN_ANA_LOW_CLK) && defined(CONFIG_LPS_LCLK)
43 struct pwrctrl_priv *pwrpriv = &dvobj->pwrctl_priv;
44 u32 mac_reg_offset = 0;
46 if (pwrpriv->pwr_mode == PS_MODE_ACTIVE)
49 if (pwrpriv->lps_level == LPS_NORMAL)
52 if (pwrpriv->rpwm >= PS_STATE_S2)
55 if (offset & (WLAN_IOREG_DEVICE_ID << 13)) { /*WLAN_IOREG_OFFSET*/
56 mac_reg_offset = offset & HALMAC_WLAN_MAC_REG_MSK;
57 if (mac_reg_offset < 0x100) {
59 "access MAC REG -0x%04x in PS-mode:0x%02x (rpwm:0x%02x, lps_level:0x%02x)\n",
60 FUNC_ADPT_ARG(dvobj_get_primary_adapter(dvobj)), mac_reg_offset,
61 pwrpriv->pwr_mode, pwrpriv->rpwm, pwrpriv->lps_level);
70 static u8 _halmac_sdio_cmd52_read(void *p, u32 offset)
77 d = (struct dvobj_priv *)p;
78 _halmac_mac_reg_page0_chk(__func__, d, offset);
79 ret = rtw_sdio_read_cmd52(d, offset, &val, 1);
81 RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
88 static void _halmac_sdio_cmd52_write(void *p, u32 offset, u8 val)
94 d = (struct dvobj_priv *)p;
95 _halmac_mac_reg_page0_chk(__func__, d, offset);
96 ret = rtw_sdio_write_cmd52(d, offset, &val, 1);
98 RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
101 static u8 _halmac_sdio_reg_read_8(void *p, u32 offset)
103 struct dvobj_priv *d;
109 d = (struct dvobj_priv *)p;
111 _halmac_mac_reg_page0_chk(__func__, d, offset);
112 pbuf = rtw_zmalloc(1);
116 ret = rtw_sdio_read_cmd53(d, offset, pbuf, 1);
118 RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
130 static u16 _halmac_sdio_reg_read_16(void *p, u32 offset)
132 struct dvobj_priv *d;
138 d = (struct dvobj_priv *)p;
139 val = SDIO_ERR_VAL16;
140 _halmac_mac_reg_page0_chk(__func__, d, offset);
141 pbuf = rtw_zmalloc(2);
145 ret = rtw_sdio_read_cmd53(d, offset, pbuf, 2);
147 RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
151 val = le16_to_cpu(*(u16 *)pbuf);
159 static u32 _halmac_sdio_reg_read_32(void *p, u32 offset)
161 struct dvobj_priv *d;
167 d = (struct dvobj_priv *)p;
168 val = SDIO_ERR_VAL32;
169 _halmac_mac_reg_page0_chk(__func__, d, offset);
170 pbuf = rtw_zmalloc(4);
174 ret = rtw_sdio_read_cmd53(d, offset, pbuf, 4);
176 RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
180 val = le32_to_cpu(*(u32 *)pbuf);
188 static u8 _halmac_sdio_reg_read_n(void *p, u32 offset, u32 size, u8 *data)
190 struct dvobj_priv *d = (struct dvobj_priv *)p;
193 u8 rst = RTW_HALMAC_FAIL;
197 sdio_read_size = RND4(size);
198 sdio_read_size = rtw_sdio_cmd53_align_size(d, sdio_read_size);
200 pbuf = rtw_zmalloc(sdio_read_size);
201 if ((!pbuf) || (!data))
204 ret = rtw_sdio_read_cmd53(d, offset, pbuf, sdio_read_size);
206 RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
210 _rtw_memcpy(data, pbuf, size);
211 rst = RTW_HALMAC_SUCCESS;
213 rtw_mfree(pbuf, sdio_read_size);
218 static void _halmac_sdio_reg_write_8(void *p, u32 offset, u8 val)
220 struct dvobj_priv *d;
225 d = (struct dvobj_priv *)p;
226 _halmac_mac_reg_page0_chk(__func__, d, offset);
227 pbuf = rtw_zmalloc(1);
230 _rtw_memcpy(pbuf, &val, 1);
232 ret = rtw_sdio_write_cmd53(d, offset, pbuf, 1);
234 RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
239 static void _halmac_sdio_reg_write_16(void *p, u32 offset, u16 val)
241 struct dvobj_priv *d;
246 d = (struct dvobj_priv *)p;
247 _halmac_mac_reg_page0_chk(__func__, d, offset);
248 val = cpu_to_le16(val);
249 pbuf = rtw_zmalloc(2);
252 _rtw_memcpy(pbuf, &val, 2);
254 ret = rtw_sdio_write_cmd53(d, offset, pbuf, 2);
256 RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
261 static void _halmac_sdio_reg_write_32(void *p, u32 offset, u32 val)
263 struct dvobj_priv *d;
268 d = (struct dvobj_priv *)p;
269 _halmac_mac_reg_page0_chk(__func__, d, offset);
270 val = cpu_to_le32(val);
271 pbuf = rtw_zmalloc(4);
274 _rtw_memcpy(pbuf, &val, 4);
276 ret = rtw_sdio_write_cmd53(d, offset, pbuf, 4);
278 RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
283 static u8 _halmac_sdio_read_cia(void *p, u32 offset)
285 struct dvobj_priv *d;
290 d = (struct dvobj_priv *)p;
292 ret = rtw_sdio_f0_read(d, offset, &data, 1);
294 RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
299 #else /* !CONFIG_SDIO_HCI */
301 static u8 _halmac_reg_read_8(void *p, u32 offset)
303 struct dvobj_priv *d;
307 d = (struct dvobj_priv *)p;
308 adapter = dvobj_get_primary_adapter(d);
310 return rtw_read8(adapter, offset);
313 static u16 _halmac_reg_read_16(void *p, u32 offset)
315 struct dvobj_priv *d;
319 d = (struct dvobj_priv *)p;
320 adapter = dvobj_get_primary_adapter(d);
322 return rtw_read16(adapter, offset);
325 static u32 _halmac_reg_read_32(void *p, u32 offset)
327 struct dvobj_priv *d;
331 d = (struct dvobj_priv *)p;
332 adapter = dvobj_get_primary_adapter(d);
334 return rtw_read32(adapter, offset);
337 static void _halmac_reg_write_8(void *p, u32 offset, u8 val)
339 struct dvobj_priv *d;
344 d = (struct dvobj_priv *)p;
345 adapter = dvobj_get_primary_adapter(d);
347 err = rtw_write8(adapter, offset, val);
349 RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
352 static void _halmac_reg_write_16(void *p, u32 offset, u16 val)
354 struct dvobj_priv *d;
359 d = (struct dvobj_priv *)p;
360 adapter = dvobj_get_primary_adapter(d);
362 err = rtw_write16(adapter, offset, val);
364 RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
367 static void _halmac_reg_write_32(void *p, u32 offset, u32 val)
369 struct dvobj_priv *d;
374 d = (struct dvobj_priv *)p;
375 adapter = dvobj_get_primary_adapter(d);
377 err = rtw_write32(adapter, offset, val);
379 RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
381 #endif /* !CONFIG_SDIO_HCI */
383 static u8 _halmac_mfree(void *p, void *buffer, u32 size)
385 rtw_mfree(buffer, size);
386 return RTW_HALMAC_SUCCESS;
389 static void *_halmac_malloc(void *p, u32 size)
391 return rtw_zmalloc(size);
394 static u8 _halmac_memcpy(void *p, void *dest, void *src, u32 size)
396 _rtw_memcpy(dest, src, size);
397 return RTW_HALMAC_SUCCESS;
400 static u8 _halmac_memset(void *p, void *addr, u8 value, u32 size)
402 _rtw_memset(addr, value, size);
403 return RTW_HALMAC_SUCCESS;
406 static void _halmac_udelay(void *p, u32 us)
408 /* Most hardware polling wait time < 50us) */
414 rtw_msleep_os(RTW_DIV_ROUND_UP(us, 1000));
417 static u8 _halmac_mutex_init(void *p, HALMAC_MUTEX *pMutex)
419 _rtw_mutex_init(pMutex);
420 return RTW_HALMAC_SUCCESS;
423 static u8 _halmac_mutex_deinit(void *p, HALMAC_MUTEX *pMutex)
425 _rtw_mutex_free(pMutex);
426 return RTW_HALMAC_SUCCESS;
429 static u8 _halmac_mutex_lock(void *p, HALMAC_MUTEX *pMutex)
433 err = _enter_critical_mutex(pMutex, NULL);
435 return RTW_HALMAC_FAIL;
437 return RTW_HALMAC_SUCCESS;
440 static u8 _halmac_mutex_unlock(void *p, HALMAC_MUTEX *pMutex)
442 _exit_critical_mutex(pMutex, NULL);
443 return RTW_HALMAC_SUCCESS;
446 static u8 _halmac_msg_print(void *p, u32 msg_type, u8 msg_level, s8 *fmt, ...)
450 u8 str[MSG_LEN] = {0};
452 u8 ret = RTW_HALMAC_SUCCESS;
457 err = vsnprintf(str, MSG_LEN, fmt, args);
460 /* An output error is encountered */
462 return RTW_HALMAC_FAIL;
463 /* Output may be truncated due to size limit */
464 if ((err == (MSG_LEN - 1)) && (str[MSG_LEN - 2] != '\n'))
465 ret = RTW_HALMAC_FAIL;
467 if (msg_level == HALMAC_DBG_ALWAYS)
468 RTW_PRINT(MSG_PREFIX "%s", str);
469 else if (msg_level <= HALMAC_DBG_ERR)
470 RTW_ERR(MSG_PREFIX "%s", str);
471 else if (msg_level <= HALMAC_DBG_WARN)
472 RTW_WARN(MSG_PREFIX "%s", str);
474 RTW_DBG(MSG_PREFIX "%s", str);
479 static u8 _halmac_buff_print(void *p, u32 msg_type, u8 msg_level, s8 *buf, u32 size)
481 if (msg_level <= HALMAC_DBG_WARN)
482 RTW_INFO_DUMP(MSG_PREFIX, buf, size);
484 RTW_DBG_DUMP(MSG_PREFIX, buf, size);
486 return RTW_HALMAC_SUCCESS;
490 const char *const RTW_HALMAC_FEATURE_NAME[] = {
491 "HALMAC_FEATURE_CFG_PARA",
492 "HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE",
493 "HALMAC_FEATURE_DUMP_LOGICAL_EFUSE",
494 "HALMAC_FEATURE_UPDATE_PACKET",
495 "HALMAC_FEATURE_UPDATE_DATAPACK",
496 "HALMAC_FEATURE_RUN_DATAPACK",
497 "HALMAC_FEATURE_CHANNEL_SWITCH",
498 "HALMAC_FEATURE_IQK",
499 "HALMAC_FEATURE_POWER_TRACKING",
500 "HALMAC_FEATURE_PSD",
501 "HALMAC_FEATURE_FW_SNDING",
505 static inline u8 is_valid_id_status(enum halmac_feature_id id, enum halmac_cmd_process_status status)
508 case HALMAC_FEATURE_CFG_PARA:
509 RTW_DBG("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
511 case HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE:
512 RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
513 if (HALMAC_CMD_PROCESS_DONE != status)
514 RTW_INFO("%s: id(%d) unspecified status(%d)!\n",
515 __FUNCTION__, id, status);
517 case HALMAC_FEATURE_DUMP_LOGICAL_EFUSE:
518 RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
519 if (HALMAC_CMD_PROCESS_DONE != status)
520 RTW_INFO("%s: id(%d) unspecified status(%d)!\n",
521 __FUNCTION__, id, status);
523 case HALMAC_FEATURE_UPDATE_PACKET:
524 RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
526 case HALMAC_FEATURE_UPDATE_DATAPACK:
527 RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
529 case HALMAC_FEATURE_RUN_DATAPACK:
530 RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
532 case HALMAC_FEATURE_CHANNEL_SWITCH:
533 RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
535 case HALMAC_FEATURE_IQK:
536 RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
538 case HALMAC_FEATURE_POWER_TRACKING:
539 RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
541 case HALMAC_FEATURE_PSD:
542 RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
544 case HALMAC_FEATURE_FW_SNDING:
545 RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
547 case HALMAC_FEATURE_ALL:
548 RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
551 RTW_ERR("%s: unknown feature id(%d)\n", __FUNCTION__, id);
558 static int init_halmac_event_with_waittime(struct dvobj_priv *d, enum halmac_feature_id id, u8 *buf, u32 size, u32 time)
560 struct submit_ctx *sctx;
563 if (!d->hmpriv.indicator[id].sctx) {
564 sctx = (struct submit_ctx *)rtw_zmalloc(sizeof(*sctx));
568 RTW_WARN("%s: id(%d) sctx is not NULL!!\n", __FUNCTION__, id);
569 sctx = d->hmpriv.indicator[id].sctx;
570 d->hmpriv.indicator[id].sctx = NULL;
573 rtw_sctx_init(sctx, time);
574 d->hmpriv.indicator[id].buffer = buf;
575 d->hmpriv.indicator[id].buf_size = size;
576 d->hmpriv.indicator[id].ret_size = 0;
577 d->hmpriv.indicator[id].status = 0;
578 /* fill sctx at least to sure other variables are all ready! */
579 d->hmpriv.indicator[id].sctx = sctx;
584 static inline int init_halmac_event(struct dvobj_priv *d, enum halmac_feature_id id, u8 *buf, u32 size)
586 return init_halmac_event_with_waittime(d, id, buf, size, DEFAULT_INDICATOR_TIMELMT);
589 static void free_halmac_event(struct dvobj_priv *d, enum halmac_feature_id id)
591 struct submit_ctx *sctx;
594 if (!d->hmpriv.indicator[id].sctx)
597 sctx = d->hmpriv.indicator[id].sctx;
598 d->hmpriv.indicator[id].sctx = NULL;
599 rtw_mfree((u8 *)sctx, sizeof(*sctx));
602 static int wait_halmac_event(struct dvobj_priv *d, enum halmac_feature_id id)
604 struct halmac_adapter *mac;
605 struct halmac_api *api;
606 struct submit_ctx *sctx;
610 sctx = d->hmpriv.indicator[id].sctx;
614 ret = rtw_sctx_wait(sctx, RTW_HALMAC_FEATURE_NAME[id]);
615 free_halmac_event(d, id);
619 /* timeout! We have to reset halmac state */
620 RTW_ERR("%s: Wait id(%d, %s) TIMEOUT! Reset HALMAC state!\n",
621 __FUNCTION__, id, RTW_HALMAC_FEATURE_NAME[id]);
622 mac = dvobj_to_halmac(d);
623 api = HALMAC_GET_API(mac);
624 api->halmac_reset_feature(mac, id);
631 * Always return RTW_HALMAC_SUCCESS, HALMAC don't care the return value.
633 static u8 _halmac_event_indication(void *p, enum halmac_feature_id feature_id, enum halmac_cmd_process_status process_status, u8 *buf, u32 size)
635 struct dvobj_priv *d;
638 struct halmac_indicator *tbl, *indicator;
639 struct submit_ctx *sctx;
644 d = (struct dvobj_priv *)p;
645 adapter = dvobj_get_primary_adapter(d);
646 hal = GET_HAL_DATA(adapter);
647 tbl = d->hmpriv.indicator;
649 /* Filter(Skip) middle status indication */
650 ret = is_valid_id_status(feature_id, process_status);
654 indicator = &tbl[feature_id];
655 indicator->status = process_status;
656 indicator->ret_size = size;
657 if (!indicator->sctx) {
658 RTW_WARN("%s: No feature id(%d, %s) waiting!!\n", __FUNCTION__, feature_id, RTW_HALMAC_FEATURE_NAME[feature_id]);
661 sctx = indicator->sctx;
663 if (HALMAC_CMD_PROCESS_ERROR == process_status) {
664 RTW_ERR("%s: Something wrong id(%d, %s)!!\n", __FUNCTION__, feature_id, RTW_HALMAC_FEATURE_NAME[feature_id]);
665 rtw_sctx_done_err(&sctx, RTW_SCTX_DONE_UNKNOWN);
669 if (size > indicator->buf_size) {
670 RTW_WARN("%s: id(%d, %s) buffer is not enough(%d<%d), data will be truncated!\n",
671 __FUNCTION__, feature_id, RTW_HALMAC_FEATURE_NAME[feature_id], indicator->buf_size, size);
672 cpsz = indicator->buf_size;
676 if (cpsz && indicator->buffer)
677 _rtw_memcpy(indicator->buffer, buf, cpsz);
679 rtw_sctx_done(&sctx);
682 return RTW_HALMAC_SUCCESS;
685 struct halmac_platform_api rtw_halmac_platform_api = {
687 #ifdef CONFIG_SDIO_HCI
688 .SDIO_CMD52_READ = _halmac_sdio_cmd52_read,
689 .SDIO_CMD53_READ_8 = _halmac_sdio_reg_read_8,
690 .SDIO_CMD53_READ_16 = _halmac_sdio_reg_read_16,
691 .SDIO_CMD53_READ_32 = _halmac_sdio_reg_read_32,
692 .SDIO_CMD53_READ_N = _halmac_sdio_reg_read_n,
693 .SDIO_CMD52_WRITE = _halmac_sdio_cmd52_write,
694 .SDIO_CMD53_WRITE_8 = _halmac_sdio_reg_write_8,
695 .SDIO_CMD53_WRITE_16 = _halmac_sdio_reg_write_16,
696 .SDIO_CMD53_WRITE_32 = _halmac_sdio_reg_write_32,
697 .SDIO_CMD52_CIA_READ = _halmac_sdio_read_cia,
698 #endif /* CONFIG_SDIO_HCI */
699 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
700 .REG_READ_8 = _halmac_reg_read_8,
701 .REG_READ_16 = _halmac_reg_read_16,
702 .REG_READ_32 = _halmac_reg_read_32,
703 .REG_WRITE_8 = _halmac_reg_write_8,
704 .REG_WRITE_16 = _halmac_reg_write_16,
705 .REG_WRITE_32 = _halmac_reg_write_32,
706 #endif /* CONFIG_USB_HCI || CONFIG_PCI_HCI */
710 /* impletement in HAL-IC level */
711 .SEND_RSVD_PAGE = sdio_write_data_rsvd_page,
712 .SEND_H2C_PKT = sdio_write_data_h2c,
714 /* Memory allocate */
715 .RTL_FREE = _halmac_mfree,
716 .RTL_MALLOC = _halmac_malloc,
717 .RTL_MEMCPY = _halmac_memcpy,
718 .RTL_MEMSET = _halmac_memset,
721 .RTL_DELAY_US = _halmac_udelay,
723 /* Process Synchronization */
724 .MUTEX_INIT = _halmac_mutex_init,
725 .MUTEX_DEINIT = _halmac_mutex_deinit,
726 .MUTEX_LOCK = _halmac_mutex_lock,
727 .MUTEX_UNLOCK = _halmac_mutex_unlock,
729 .MSG_PRINT = _halmac_msg_print,
730 .BUFF_PRINT = _halmac_buff_print,
731 .EVENT_INDICATION = _halmac_event_indication,
734 u8 rtw_halmac_read8(struct intf_hdl *pintfhdl, u32 addr)
736 struct halmac_adapter *mac;
737 struct halmac_api *api;
740 /* WARNING: pintf_dev should not be null! */
741 mac = dvobj_to_halmac(pintfhdl->pintf_dev);
742 api = HALMAC_GET_API(mac);
744 return api->halmac_reg_read_8(mac, addr);
747 u16 rtw_halmac_read16(struct intf_hdl *pintfhdl, u32 addr)
749 struct halmac_adapter *mac;
750 struct halmac_api *api;
753 /* WARNING: pintf_dev should not be null! */
754 mac = dvobj_to_halmac(pintfhdl->pintf_dev);
755 api = HALMAC_GET_API(mac);
757 return api->halmac_reg_read_16(mac, addr);
760 u32 rtw_halmac_read32(struct intf_hdl *pintfhdl, u32 addr)
762 struct halmac_adapter *mac;
763 struct halmac_api *api;
766 /* WARNING: pintf_dev should not be null! */
767 mac = dvobj_to_halmac(pintfhdl->pintf_dev);
768 api = HALMAC_GET_API(mac);
770 return api->halmac_reg_read_32(mac, addr);
773 static void _read_register(struct dvobj_priv *d, u32 addr, u32 cnt, u8 *buf)
782 a = dvobj_get_primary_adapter(d);
785 /* Handle address not start from 4 bytes alignment case */
787 val32 = cpu_to_le32(rtw_read32(a, addr & ~0x3));
789 _rtw_memcpy(buf, ((u8 *)&val32) + i, n);
805 buf[i] = rtw_read8(a, addr+i);
809 val16 = cpu_to_le16(rtw_read16(a, addr+i));
810 _rtw_memcpy(&buf[i], &val16, 2);
814 val32 = cpu_to_le32(rtw_read32(a, addr+i));
815 _rtw_memcpy(&buf[i], &val32, 4);
825 a = dvobj_get_primary_adapter(d);
826 for (i = 0; i < cnt; i++)
827 buf[i] = rtw_read8(a, addr + i);
831 #ifdef CONFIG_SDIO_HCI
832 static int _sdio_read_local(struct dvobj_priv *d, u32 addr, u32 cnt, u8 *buf)
834 struct halmac_adapter *mac;
835 struct halmac_api *api;
836 enum halmac_ret_status status;
842 mac = dvobj_to_halmac(d);
843 api = HALMAC_GET_API(mac);
845 status = api->halmac_reg_sdio_cmd53_read_n(mac, addr, cnt, buf);
846 if (status != HALMAC_RET_SUCCESS) {
847 RTW_ERR("%s: addr=0x%08x cnt=%d err=%d\n",
848 __FUNCTION__, addr, cnt, status);
854 #endif /* CONFIG_SDIO_HCI */
856 void rtw_halmac_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem)
858 struct dvobj_priv *d;
862 RTW_ERR("pmem is NULL\n");
866 d = pintfhdl->pintf_dev;
868 #ifdef CONFIG_SDIO_HCI
869 if (addr & 0xFFFF0000) {
872 err = _sdio_read_local(d, addr, cnt, pmem);
876 #endif /* CONFIG_SDIO_HCI */
878 _read_register(d, addr, cnt, pmem);
881 #ifdef CONFIG_SDIO_INDIRECT_ACCESS
882 u8 rtw_halmac_iread8(struct intf_hdl *pintfhdl, u32 addr)
884 struct halmac_adapter *mac;
885 struct halmac_api *api;
887 /* WARNING: pintf_dev should not be null! */
888 mac = dvobj_to_halmac(pintfhdl->pintf_dev);
889 api = HALMAC_GET_API(mac);
891 /*return api->halmac_reg_read_indirect_8(mac, addr);*/
892 return api->halmac_reg_read_8(mac, addr);
895 u16 rtw_halmac_iread16(struct intf_hdl *pintfhdl, u32 addr)
897 struct halmac_adapter *mac;
898 struct halmac_api *api;
901 /* WARNING: pintf_dev should not be null! */
902 mac = dvobj_to_halmac(pintfhdl->pintf_dev);
903 api = HALMAC_GET_API(mac);
905 /*return api->halmac_reg_read_indirect_16(mac, addr);*/
906 return api->halmac_reg_read_16(mac, addr);
909 u32 rtw_halmac_iread32(struct intf_hdl *pintfhdl, u32 addr)
911 struct halmac_adapter *mac;
912 struct halmac_api *api;
915 /* WARNING: pintf_dev should not be null! */
916 mac = dvobj_to_halmac(pintfhdl->pintf_dev);
917 api = HALMAC_GET_API(mac);
919 return api->halmac_reg_read_indirect_32(mac, addr);
921 #endif /* CONFIG_SDIO_INDIRECT_ACCESS */
923 int rtw_halmac_write8(struct intf_hdl *pintfhdl, u32 addr, u8 value)
925 struct halmac_adapter *mac;
926 struct halmac_api *api;
927 enum halmac_ret_status status;
930 /* WARNING: pintf_dev should not be null! */
931 mac = dvobj_to_halmac(pintfhdl->pintf_dev);
932 api = HALMAC_GET_API(mac);
934 status = api->halmac_reg_write_8(mac, addr, value);
936 if (status == HALMAC_RET_SUCCESS)
942 int rtw_halmac_write16(struct intf_hdl *pintfhdl, u32 addr, u16 value)
944 struct halmac_adapter *mac;
945 struct halmac_api *api;
946 enum halmac_ret_status status;
949 /* WARNING: pintf_dev should not be null! */
950 mac = dvobj_to_halmac(pintfhdl->pintf_dev);
951 api = HALMAC_GET_API(mac);
953 status = api->halmac_reg_write_16(mac, addr, value);
955 if (status == HALMAC_RET_SUCCESS)
961 int rtw_halmac_write32(struct intf_hdl *pintfhdl, u32 addr, u32 value)
963 struct halmac_adapter *mac;
964 struct halmac_api *api;
965 enum halmac_ret_status status;
968 /* WARNING: pintf_dev should not be null! */
969 mac = dvobj_to_halmac(pintfhdl->pintf_dev);
970 api = HALMAC_GET_API(mac);
972 status = api->halmac_reg_write_32(mac, addr, value);
974 if (status == HALMAC_RET_SUCCESS)
980 static int init_write_rsvd_page_size(struct dvobj_priv *d)
982 struct halmac_adapter *mac;
983 struct halmac_api *api;
985 struct halmac_ofld_func_info ofld_info;
986 enum halmac_ret_status status;
990 #ifdef CONFIG_USB_HCI
991 /* for USB do not exceed MAX_CMDBUF_SZ */
993 #elif defined(CONFIG_PCI_HCI)
994 size = MAX_CMDBUF_SZ - TXDESC_OFFSET;
995 #elif defined(CONFIG_SDIO_HCI)
996 size = 0x7000; /* 28KB */
999 /* If size==0, use HALMAC default setting and don't call any function */
1003 err = rtw_halmac_set_max_dl_fw_size(d, size);
1005 RTW_ERR("%s: Fail to set max download fw size!\n", __FUNCTION__);
1009 mac = dvobj_to_halmac(d);
1010 api = HALMAC_GET_API(mac);
1012 _rtw_memset(&ofld_info, 0, sizeof(ofld_info));
1013 ofld_info.halmac_malloc_max_sz = 0xFFFFFFFF;
1014 ofld_info.rsvd_pg_drv_buf_max_sz = size;
1015 status = api->halmac_ofld_func_cfg(mac, &ofld_info);
1016 if (status != HALMAC_RET_SUCCESS) {
1017 RTW_ERR("%s: Fail to config offload parameters!\n", __FUNCTION__);
1024 static int init_priv(struct halmacpriv *priv)
1026 struct halmac_indicator *indicator;
1030 if (priv->indicator)
1031 RTW_WARN("%s: HALMAC private data is not CLEAR!\n", __FUNCTION__);
1032 count = HALMAC_FEATURE_ALL + 1;
1033 size = sizeof(*indicator) * count;
1034 indicator = (struct halmac_indicator *)rtw_zmalloc(size);
1037 priv->indicator = indicator;
1042 static void deinit_priv(struct halmacpriv *priv)
1044 struct halmac_indicator *indicator;
1047 indicator = priv->indicator;
1048 priv->indicator = NULL;
1052 count = HALMAC_FEATURE_ALL + 1;
1053 #ifdef CONFIG_RTW_DEBUG
1055 struct submit_ctx *sctx;
1058 for (i = 0; i < count; i++) {
1059 if (!indicator[i].sctx)
1062 RTW_WARN("%s: %s id(%d) sctx still exist!!\n",
1063 __FUNCTION__, RTW_HALMAC_FEATURE_NAME[i], i);
1064 sctx = indicator[i].sctx;
1065 indicator[i].sctx = NULL;
1066 rtw_mfree((u8 *)sctx, sizeof(*sctx));
1069 #endif /* !CONFIG_RTW_DEBUG */
1070 size = sizeof(*indicator) * count;
1071 rtw_mfree((u8 *)indicator, size);
1075 #ifdef CONFIG_SDIO_HCI
1076 static enum halmac_sdio_spec_ver _sdio_ver_drv2halmac(struct dvobj_priv *d)
1079 enum halmac_sdio_spec_ver ver;
1082 v3 = rtw_is_sdio30(dvobj_get_primary_adapter(d));
1084 ver = HALMAC_SDIO_SPEC_VER_3_00;
1086 ver = HALMAC_SDIO_SPEC_VER_2_00;
1090 #endif /* CONFIG_SDIO_HCI */
1092 void rtw_halmac_get_version(char *str, u32 len)
1094 enum halmac_ret_status status;
1095 struct halmac_ver ver;
1098 status = halmac_get_version(&ver);
1099 if (status != HALMAC_RET_SUCCESS)
1102 rtw_sprintf(str, len, "V%d_%02d_%02d",
1103 ver.major_ver, ver.prototype_ver, ver.minor_ver);
1106 int rtw_halmac_init_adapter(struct dvobj_priv *d, struct halmac_platform_api *pf_api)
1108 struct halmac_adapter *halmac;
1109 struct halmac_api *api;
1110 enum halmac_interface intf;
1111 enum halmac_ret_status status;
1113 #ifdef CONFIG_SDIO_HCI
1114 struct halmac_sdio_hw_info info;
1115 #endif /* CONFIG_SDIO_HCI */
1118 halmac = dvobj_to_halmac(d);
1120 RTW_WARN("%s: initialize already completed!\n", __FUNCTION__);
1124 err = init_priv(&d->hmpriv);
1128 #ifdef CONFIG_SDIO_HCI
1129 intf = HALMAC_INTERFACE_SDIO;
1130 #elif defined(CONFIG_USB_HCI)
1131 intf = HALMAC_INTERFACE_USB;
1132 #elif defined(CONFIG_PCI_HCI)
1133 intf = HALMAC_INTERFACE_PCIE;
1135 #warning "INTERFACE(CONFIG_XXX_HCI) not be defined!!"
1136 intf = HALMAC_INTERFACE_UNDEFINE;
1138 status = halmac_init_adapter(d, pf_api, intf, &halmac, &api);
1139 if (HALMAC_RET_SUCCESS != status) {
1140 RTW_ERR("%s: halmac_init_adapter fail!(status=%d)\n", __FUNCTION__, status);
1147 dvobj_set_halmac(d, halmac);
1149 status = api->halmac_interface_integration_tuning(halmac);
1150 if (status != HALMAC_RET_SUCCESS) {
1151 RTW_ERR("%s: halmac_interface_integration_tuning fail!(status=%d)\n", __FUNCTION__, status);
1156 status = api->halmac_phy_cfg(halmac, HALMAC_INTF_PHY_PLATFORM_ALL);
1157 if (status != HALMAC_RET_SUCCESS) {
1158 RTW_ERR("%s: halmac_phy_cfg fail!(status=%d)\n", __FUNCTION__, status);
1163 init_write_rsvd_page_size(d);
1165 #ifdef CONFIG_SDIO_HCI
1166 _rtw_memset(&info, 0, sizeof(info));
1167 info.spec_ver = _sdio_ver_drv2halmac(d);
1168 /* Convert clock speed unit to MHz from Hz */
1169 info.clock_speed = RTW_DIV_ROUND_UP(rtw_sdio_get_clock(d), 1000000);
1170 info.block_size = rtw_sdio_get_block_size(d);
1171 RTW_DBG("%s: SDIO ver=%u clock=%uMHz blk_size=%u bytes\n",
1172 __FUNCTION__, info.spec_ver+2, info.clock_speed,
1174 status = api->halmac_sdio_hw_info(halmac, &info);
1175 if (status != HALMAC_RET_SUCCESS) {
1176 RTW_ERR("%s: halmac_sdio_hw_info fail!(status=%d)\n",
1177 __FUNCTION__, status);
1181 #endif /* CONFIG_SDIO_HCI */
1186 status = halmac_deinit_adapter(halmac);
1187 dvobj_set_halmac(d, NULL);
1188 if (status != HALMAC_RET_SUCCESS)
1189 RTW_ERR("%s: halmac_deinit_adapter fail!(status=%d)\n",
1190 __FUNCTION__, status);
1193 deinit_priv(&d->hmpriv);
1199 int rtw_halmac_deinit_adapter(struct dvobj_priv *d)
1201 struct halmac_adapter *halmac;
1202 enum halmac_ret_status status;
1206 halmac = dvobj_to_halmac(d);
1208 status = halmac_deinit_adapter(halmac);
1209 dvobj_set_halmac(d, NULL);
1210 if (status != HALMAC_RET_SUCCESS)
1214 deinit_priv(&d->hmpriv);
1219 static inline enum halmac_portid _hw_port_drv2halmac(enum _hw_port hwport)
1221 enum halmac_portid port = HALMAC_PORTID_NUM;
1226 port = HALMAC_PORTID0;
1229 port = HALMAC_PORTID1;
1232 port = HALMAC_PORTID2;
1235 port = HALMAC_PORTID3;
1238 port = HALMAC_PORTID4;
1247 static enum halmac_network_type_select _network_type_drv2halmac(u8 type)
1249 enum halmac_network_type_select network = HALMAC_NETWORK_UNDEFINE;
1253 case _HW_STATE_NOLINK_:
1254 case _HW_STATE_MONITOR_:
1255 network = HALMAC_NETWORK_NO_LINK;
1258 case _HW_STATE_ADHOC_:
1259 network = HALMAC_NETWORK_ADHOC;
1262 case _HW_STATE_STATION_:
1263 network = HALMAC_NETWORK_INFRASTRUCTURE;
1267 network = HALMAC_NETWORK_AP;
1274 static u8 _network_type_halmac2drv(enum halmac_network_type_select network)
1276 u8 type = _HW_STATE_NOLINK_;
1280 case HALMAC_NETWORK_NO_LINK:
1281 case HALMAC_NETWORK_UNDEFINE:
1282 type = _HW_STATE_NOLINK_;
1285 case HALMAC_NETWORK_ADHOC:
1286 type = _HW_STATE_ADHOC_;
1289 case HALMAC_NETWORK_INFRASTRUCTURE:
1290 type = _HW_STATE_STATION_;
1293 case HALMAC_NETWORK_AP:
1294 type = _HW_STATE_AP_;
1301 static void _beacon_ctrl_halmac2drv(struct halmac_bcn_ctrl *ctrl,
1302 struct rtw_halmac_bcn_ctrl *drv_ctrl)
1304 drv_ctrl->rx_bssid_fit = ctrl->dis_rx_bssid_fit ? 0 : 1;
1305 drv_ctrl->txbcn_rpt = ctrl->en_txbcn_rpt ? 1 : 0;
1306 drv_ctrl->tsf_update = ctrl->dis_tsf_udt ? 0 : 1;
1307 drv_ctrl->enable_bcn = ctrl->en_bcn ? 1 : 0;
1308 drv_ctrl->rxbcn_rpt = ctrl->en_rxbcn_rpt ? 1 : 0;
1309 drv_ctrl->p2p_ctwin = ctrl->en_p2p_ctwin ? 1 : 0;
1310 drv_ctrl->p2p_bcn_area = ctrl->en_p2p_bcn_area ? 1 : 0;
1313 static void _beacon_ctrl_drv2halmac(struct rtw_halmac_bcn_ctrl *drv_ctrl,
1314 struct halmac_bcn_ctrl *ctrl)
1316 ctrl->dis_rx_bssid_fit = drv_ctrl->rx_bssid_fit ? 0 : 1;
1317 ctrl->en_txbcn_rpt = drv_ctrl->txbcn_rpt ? 1 : 0;
1318 ctrl->dis_tsf_udt = drv_ctrl->tsf_update ? 0 : 1;
1319 ctrl->en_bcn = drv_ctrl->enable_bcn ? 1 : 0;
1320 ctrl->en_rxbcn_rpt = drv_ctrl->rxbcn_rpt ? 1 : 0;
1321 ctrl->en_p2p_ctwin = drv_ctrl->p2p_ctwin ? 1 : 0;
1322 ctrl->en_p2p_bcn_area = drv_ctrl->p2p_bcn_area ? 1 : 0;
1325 int rtw_halmac_get_hw_value(struct dvobj_priv *d, enum halmac_hw_id hw_id, void *pvalue)
1327 struct halmac_adapter *mac;
1328 struct halmac_api *api;
1329 enum halmac_ret_status status;
1332 mac = dvobj_to_halmac(d);
1333 api = HALMAC_GET_API(mac);
1335 status = api->halmac_get_hw_value(mac, hw_id, pvalue);
1336 if (HALMAC_RET_SUCCESS != status)
1343 * rtw_halmac_get_tx_fifo_size() - TX FIFO size
1344 * @d: struct dvobj_priv*
1345 * @size: TX FIFO size, unit is byte.
1347 * Get TX FIFO size(byte) from HALMAC.
1349 * Rteurn 0 for OK, otherwise fail.
1351 int rtw_halmac_get_tx_fifo_size(struct dvobj_priv *d, u32 *size)
1353 struct halmac_adapter *halmac;
1354 struct halmac_api *api;
1355 enum halmac_ret_status status;
1359 halmac = dvobj_to_halmac(d);
1360 api = HALMAC_GET_API(halmac);
1362 status = api->halmac_get_hw_value(halmac, HALMAC_HW_TXFIFO_SIZE, &val);
1363 if (status != HALMAC_RET_SUCCESS)
1372 * rtw_halmac_get_rx_fifo_size() - RX FIFO size
1373 * @d: struct dvobj_priv*
1374 * @size: RX FIFO size, unit is byte
1376 * Get RX FIFO size(byte) from HALMAC.
1378 * Rteurn 0 for OK, otherwise fail.
1380 int rtw_halmac_get_rx_fifo_size(struct dvobj_priv *d, u32 *size)
1382 struct halmac_adapter *halmac;
1383 struct halmac_api *api;
1384 enum halmac_ret_status status;
1388 halmac = dvobj_to_halmac(d);
1389 api = HALMAC_GET_API(halmac);
1391 status = api->halmac_get_hw_value(halmac, HALMAC_HW_RXFIFO_SIZE, &val);
1392 if (status != HALMAC_RET_SUCCESS)
1401 * rtw_halmac_get_rsvd_drv_pg_bndy() - Reserve page boundary of driver
1402 * @d: struct dvobj_priv*
1403 * @size: Page size, unit is byte
1405 * Get reserve page boundary of driver from HALMAC.
1407 * Rteurn 0 for OK, otherwise fail.
1409 int rtw_halmac_get_rsvd_drv_pg_bndy(struct dvobj_priv *d, u16 *bndy)
1411 struct halmac_adapter *halmac;
1412 struct halmac_api *api;
1413 enum halmac_ret_status status;
1417 halmac = dvobj_to_halmac(d);
1418 api = HALMAC_GET_API(halmac);
1420 status = api->halmac_get_hw_value(halmac, HALMAC_HW_RSVD_PG_BNDY, &val);
1421 if (status != HALMAC_RET_SUCCESS)
1430 * rtw_halmac_get_page_size() - Page size
1431 * @d: struct dvobj_priv*
1432 * @size: Page size, unit is byte
1434 * Get TX/RX page size(byte) from HALMAC.
1436 * Rteurn 0 for OK, otherwise fail.
1438 int rtw_halmac_get_page_size(struct dvobj_priv *d, u32 *size)
1440 struct halmac_adapter *halmac;
1441 struct halmac_api *api;
1442 enum halmac_ret_status status;
1446 halmac = dvobj_to_halmac(d);
1447 api = HALMAC_GET_API(halmac);
1449 status = api->halmac_get_hw_value(halmac, HALMAC_HW_PAGE_SIZE, &val);
1450 if (status != HALMAC_RET_SUCCESS)
1459 * rtw_halmac_get_tx_agg_align_size() - TX aggregation align size
1460 * @d: struct dvobj_priv*
1461 * @size: TX aggregation align size, unit is byte
1463 * Get TX aggregation align size(byte) from HALMAC.
1465 * Rteurn 0 for OK, otherwise fail.
1467 int rtw_halmac_get_tx_agg_align_size(struct dvobj_priv *d, u16 *size)
1469 struct halmac_adapter *halmac;
1470 struct halmac_api *api;
1471 enum halmac_ret_status status;
1475 halmac = dvobj_to_halmac(d);
1476 api = HALMAC_GET_API(halmac);
1478 status = api->halmac_get_hw_value(halmac, HALMAC_HW_TX_AGG_ALIGN_SIZE, &val);
1479 if (status != HALMAC_RET_SUCCESS)
1488 * rtw_halmac_get_rx_agg_align_size() - RX aggregation align size
1489 * @d: struct dvobj_priv*
1490 * @size: RX aggregation align size, unit is byte
1492 * Get RX aggregation align size(byte) from HALMAC.
1494 * Rteurn 0 for OK, otherwise fail.
1496 int rtw_halmac_get_rx_agg_align_size(struct dvobj_priv *d, u8 *size)
1498 struct halmac_adapter *halmac;
1499 struct halmac_api *api;
1500 enum halmac_ret_status status;
1504 halmac = dvobj_to_halmac(d);
1505 api = HALMAC_GET_API(halmac);
1507 status = api->halmac_get_hw_value(halmac, HALMAC_HW_RX_AGG_ALIGN_SIZE, &val);
1508 if (status != HALMAC_RET_SUCCESS)
1518 * Get RX driver info size. RX driver info is a small memory space between
1519 * scriptor and RX payload.
1521 * +-------------------------+
1523 * | usually 24 bytes |
1524 * +-------------------------+
1525 * | RX driver info |
1526 * | depends on driver cfg |
1527 * +-------------------------+
1530 * +-------------------------+
1533 * d pointer to struct dvobj_priv of driver
1534 * sz rx driver info size in bytes.
1540 int rtw_halmac_get_rx_drv_info_sz(struct dvobj_priv *d, u8 *sz)
1542 enum halmac_ret_status status;
1543 struct halmac_adapter *halmac = dvobj_to_halmac(d);
1544 struct halmac_api *api = HALMAC_GET_API(halmac);
1547 status = api->halmac_get_hw_value(halmac, HALMAC_HW_DRV_INFO_SIZE, &dw);
1548 if (status != HALMAC_RET_SUCCESS)
1556 * rtw_halmac_get_tx_desc_size() - TX descriptor size
1557 * @d: struct dvobj_priv*
1558 * @size: TX descriptor size, unit is byte.
1560 * Get TX descriptor size(byte) from HALMAC.
1562 * Rteurn 0 for OK, otherwise fail.
1564 int rtw_halmac_get_tx_desc_size(struct dvobj_priv *d, u32 *size)
1566 struct halmac_adapter *halmac;
1567 struct halmac_api *api;
1568 enum halmac_ret_status status;
1572 halmac = dvobj_to_halmac(d);
1573 api = HALMAC_GET_API(halmac);
1575 status = api->halmac_get_hw_value(halmac, HALMAC_HW_TX_DESC_SIZE, &val);
1576 if (status != HALMAC_RET_SUCCESS)
1585 * rtw_halmac_get_rx_desc_size() - RX descriptor size
1586 * @d: struct dvobj_priv*
1587 * @size: RX descriptor size, unit is byte.
1589 * Get RX descriptor size(byte) from HALMAC.
1591 * Rteurn 0 for OK, otherwise fail.
1593 int rtw_halmac_get_rx_desc_size(struct dvobj_priv *d, u32 *size)
1595 struct halmac_adapter *halmac;
1596 struct halmac_api *api;
1597 enum halmac_ret_status status;
1601 halmac = dvobj_to_halmac(d);
1602 api = HALMAC_GET_API(halmac);
1604 status = api->halmac_get_hw_value(halmac, HALMAC_HW_RX_DESC_SIZE, &val);
1605 if (status != HALMAC_RET_SUCCESS)
1615 * rtw_halmac_get_fw_max_size() - Firmware MAX size
1616 * @d: struct dvobj_priv*
1617 * @size: MAX Firmware size, unit is byte.
1619 * Get Firmware MAX size(byte) from HALMAC.
1621 * Rteurn 0 for OK, otherwise fail.
1623 static int rtw_halmac_get_fw_max_size(struct dvobj_priv *d, u32 *size)
1625 struct halmac_adapter *halmac;
1626 struct halmac_api *api;
1627 enum halmac_ret_status status;
1631 halmac = dvobj_to_halmac(d);
1632 api = HALMAC_GET_API(halmac);
1634 status = api->halmac_get_hw_value(halmac, HALMAC_HW_FW_MAX_SIZE, &val);
1635 if (status != HALMAC_RET_SUCCESS)
1644 * rtw_halmac_get_ori_h2c_size() - Original H2C MAX size
1645 * @d: struct dvobj_priv*
1646 * @size: H2C MAX size, unit is byte.
1648 * Get original H2C MAX size(byte) from HALMAC.
1650 * Rteurn 0 for OK, otherwise fail.
1652 int rtw_halmac_get_ori_h2c_size(struct dvobj_priv *d, u32 *size)
1654 struct halmac_adapter *halmac;
1655 struct halmac_api *api;
1656 enum halmac_ret_status status;
1660 halmac = dvobj_to_halmac(d);
1661 api = HALMAC_GET_API(halmac);
1663 status = api->halmac_get_hw_value(halmac, HALMAC_HW_ORI_H2C_SIZE, &val);
1664 if (status != HALMAC_RET_SUCCESS)
1672 int rtw_halmac_get_oqt_size(struct dvobj_priv *d, u8 *size)
1674 enum halmac_ret_status status;
1675 struct halmac_adapter *halmac;
1676 struct halmac_api *api;
1683 halmac = dvobj_to_halmac(d);
1684 api = HALMAC_GET_API(halmac);
1686 status = api->halmac_get_hw_value(halmac, HALMAC_HW_AC_OQT_SIZE, &val);
1687 if (status != HALMAC_RET_SUCCESS)
1694 int rtw_halmac_get_ac_queue_number(struct dvobj_priv *d, u8 *num)
1696 enum halmac_ret_status status;
1697 struct halmac_adapter *halmac;
1698 struct halmac_api *api;
1705 halmac = dvobj_to_halmac(d);
1706 api = HALMAC_GET_API(halmac);
1708 status = api->halmac_get_hw_value(halmac, HALMAC_HW_AC_QUEUE_NUM, &val);
1709 if (status != HALMAC_RET_SUCCESS)
1717 * rtw_halmac_get_mac_address() - Get MAC address of specific port
1718 * @d: struct dvobj_priv*
1720 * @addr: buffer for storing MAC address
1722 * Get MAC address of specific port from HALMAC.
1724 * Rteurn 0 for OK, otherwise fail.
1726 int rtw_halmac_get_mac_address(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
1728 struct halmac_adapter *halmac;
1729 struct halmac_api *api;
1730 enum halmac_portid port;
1731 union halmac_wlan_addr hwa;
1732 enum halmac_ret_status status;
1739 halmac = dvobj_to_halmac(d);
1740 api = HALMAC_GET_API(halmac);
1741 port = _hw_port_drv2halmac(hwport);
1742 _rtw_memset(&hwa, 0, sizeof(hwa));
1744 status = api->halmac_get_mac_addr(halmac, port, &hwa);
1745 if (status != HALMAC_RET_SUCCESS)
1748 _rtw_memcpy(addr, hwa.addr, 6);
1756 * rtw_halmac_get_network_type() - Get network type of specific port
1757 * @d: struct dvobj_priv*
1759 * @type: buffer to put network type (_HW_STATE_*)
1761 * Get network type of specific port from HALMAC.
1763 * Rteurn 0 for OK, otherwise fail.
1765 int rtw_halmac_get_network_type(struct dvobj_priv *d, enum _hw_port hwport, u8 *type)
1768 struct halmac_adapter *halmac;
1769 struct halmac_api *api;
1770 enum halmac_portid port;
1771 enum halmac_network_type_select network;
1772 enum halmac_ret_status status;
1776 halmac = dvobj_to_halmac(d);
1777 api = HALMAC_GET_API(halmac);
1778 port = _hw_port_drv2halmac(hwport);
1779 network = HALMAC_NETWORK_UNDEFINE;
1781 status = api->halmac_get_net_type(halmac, port, &network);
1782 if (status != HALMAC_RET_SUCCESS)
1785 *type = _network_type_halmac2drv(network);
1792 enum halmac_portid port;
1793 enum halmac_network_type_select network;
1798 a = dvobj_get_primary_adapter(d);
1799 port = _hw_port_drv2halmac(hwport);
1800 network = HALMAC_NETWORK_UNDEFINE;
1803 case HALMAC_PORTID0:
1804 val = rtw_read32(a, REG_CR);
1805 network = BIT_GET_NETYPE0(val);
1808 case HALMAC_PORTID1:
1809 val = rtw_read32(a, REG_CR);
1810 network = BIT_GET_NETYPE1(val);
1813 case HALMAC_PORTID2:
1814 val = rtw_read32(a, REG_CR_EXT);
1815 network = BIT_GET_NETYPE2(val);
1818 case HALMAC_PORTID3:
1819 val = rtw_read32(a, REG_CR_EXT);
1820 network = BIT_GET_NETYPE3(val);
1823 case HALMAC_PORTID4:
1824 val = rtw_read32(a, REG_CR_EXT);
1825 network = BIT_GET_NETYPE4(val);
1832 *type = _network_type_halmac2drv(network);
1841 * rtw_halmac_get_bcn_ctrl() - Get beacon control setting of specific port
1842 * @d: struct dvobj_priv*
1844 * @bcn_ctrl: setting of beacon control
1846 * Get beacon control setting of specific port from HALMAC.
1848 * Rteurn 0 for OK, otherwise fail.
1850 int rtw_halmac_get_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,
1851 struct rtw_halmac_bcn_ctrl *bcn_ctrl)
1853 struct halmac_adapter *halmac;
1854 struct halmac_api *api;
1855 enum halmac_portid port;
1856 struct halmac_bcn_ctrl ctrl;
1857 enum halmac_ret_status status;
1861 halmac = dvobj_to_halmac(d);
1862 api = HALMAC_GET_API(halmac);
1863 port = _hw_port_drv2halmac(hwport);
1864 _rtw_memset(&ctrl, 0, sizeof(ctrl));
1866 status = api->halmac_rw_bcn_ctrl(halmac, port, 0, &ctrl);
1867 if (status != HALMAC_RET_SUCCESS)
1869 _beacon_ctrl_halmac2drv(&ctrl, bcn_ctrl);
1878 * When this function return, the register REG_RCR may be changed.
1880 int rtw_halmac_config_rx_info(struct dvobj_priv *d, enum halmac_drv_info info)
1882 struct halmac_adapter *halmac;
1883 struct halmac_api *api;
1884 enum halmac_ret_status status;
1888 halmac = dvobj_to_halmac(d);
1889 api = HALMAC_GET_API(halmac);
1891 status = api->halmac_cfg_drv_info(halmac, info);
1892 if (status != HALMAC_RET_SUCCESS)
1901 * rtw_halmac_set_max_dl_fw_size() - Set the MAX download firmware size
1902 * @d: struct dvobj_priv*
1903 * @size: the max download firmware size in one I/O
1905 * Set the max download firmware size in one I/O.
1906 * Please also consider the max size of the callback function "SEND_RSVD_PAGE"
1907 * could accept, because download firmware would call "SEND_RSVD_PAGE" to send
1910 * If the value of "size" is not even, it would be rounded down to nearest
1911 * even, and 0 and 1 are both invalid value.
1913 * Return 0 for setting OK, otherwise fail.
1915 int rtw_halmac_set_max_dl_fw_size(struct dvobj_priv *d, u32 size)
1917 struct halmac_adapter *mac;
1918 struct halmac_api *api;
1919 enum halmac_ret_status status;
1922 if (!size || (size == 1))
1925 mac = dvobj_to_halmac(d);
1927 RTW_ERR("%s: HALMAC is not ready!!\n", __FUNCTION__);
1930 api = HALMAC_GET_API(mac);
1932 size &= ~1; /* round down to even */
1933 status = api->halmac_cfg_max_dl_size(mac, size);
1934 if (status != HALMAC_RET_SUCCESS) {
1935 RTW_WARN("%s: Fail to cfg_max_dl_size(%d), err=%d!!\n",
1936 __FUNCTION__, size, status);
1944 * rtw_halmac_set_mac_address() - Set mac address of specific port
1945 * @d: struct dvobj_priv*
1947 * @addr: mac address
1949 * Set self mac address of specific port to HALMAC.
1951 * Rteurn 0 for OK, otherwise fail.
1953 int rtw_halmac_set_mac_address(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
1955 struct halmac_adapter *halmac;
1956 struct halmac_api *api;
1957 enum halmac_portid port;
1958 union halmac_wlan_addr hwa;
1959 enum halmac_ret_status status;
1963 halmac = dvobj_to_halmac(d);
1964 api = HALMAC_GET_API(halmac);
1966 port = _hw_port_drv2halmac(hwport);
1967 _rtw_memset(&hwa, 0, sizeof(hwa));
1968 _rtw_memcpy(hwa.addr, addr, 6);
1970 status = api->halmac_cfg_mac_addr(halmac, port, &hwa);
1971 if (status != HALMAC_RET_SUCCESS)
1980 * rtw_halmac_set_bssid() - Set BSSID of specific port
1981 * @d: struct dvobj_priv*
1983 * @addr: BSSID, mac address of AP
1985 * Set BSSID of specific port to HALMAC.
1987 * Rteurn 0 for OK, otherwise fail.
1989 int rtw_halmac_set_bssid(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
1991 struct halmac_adapter *halmac;
1992 struct halmac_api *api;
1993 enum halmac_portid port;
1994 union halmac_wlan_addr hwa;
1995 enum halmac_ret_status status;
1999 halmac = dvobj_to_halmac(d);
2000 api = HALMAC_GET_API(halmac);
2001 port = _hw_port_drv2halmac(hwport);
2003 _rtw_memset(&hwa, 0, sizeof(hwa));
2004 _rtw_memcpy(hwa.addr, addr, 6);
2005 status = api->halmac_cfg_bssid(halmac, port, &hwa);
2006 if (status != HALMAC_RET_SUCCESS)
2015 * rtw_halmac_set_tx_address() - Set transmitter address of specific port
2016 * @d: struct dvobj_priv*
2018 * @addr: transmitter address
2020 * Set transmitter address of specific port to HALMAC.
2022 * Rteurn 0 for OK, otherwise fail.
2024 int rtw_halmac_set_tx_address(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
2026 struct halmac_adapter *halmac;
2027 struct halmac_api *api;
2028 enum halmac_portid port;
2029 union halmac_wlan_addr hwa;
2030 enum halmac_ret_status status;
2034 halmac = dvobj_to_halmac(d);
2035 api = HALMAC_GET_API(halmac);
2036 port = _hw_port_drv2halmac(hwport);
2037 _rtw_memset(&hwa, 0, sizeof(hwa));
2038 _rtw_memcpy(hwa.addr, addr, 6);
2040 status = api->halmac_cfg_transmitter_addr(halmac, port, &hwa);
2041 if (status != HALMAC_RET_SUCCESS)
2050 * rtw_halmac_set_network_type() - Set network type of specific port
2051 * @d: struct dvobj_priv*
2053 * @type: network type (_HW_STATE_*)
2055 * Set network type of specific port to HALMAC.
2057 * Rteurn 0 for OK, otherwise fail.
2059 int rtw_halmac_set_network_type(struct dvobj_priv *d, enum _hw_port hwport, u8 type)
2061 struct halmac_adapter *halmac;
2062 struct halmac_api *api;
2063 enum halmac_portid port;
2064 enum halmac_network_type_select network;
2065 enum halmac_ret_status status;
2069 halmac = dvobj_to_halmac(d);
2070 api = HALMAC_GET_API(halmac);
2071 port = _hw_port_drv2halmac(hwport);
2072 network = _network_type_drv2halmac(type);
2074 status = api->halmac_cfg_net_type(halmac, port, network);
2075 if (status != HALMAC_RET_SUCCESS)
2084 * rtw_halmac_reset_tsf() - Reset TSF timer of specific port
2085 * @d: struct dvobj_priv*
2088 * Notice HALMAC to reset timing synchronization function(TSF) timer of
2091 * Rteurn 0 for OK, otherwise fail.
2093 int rtw_halmac_reset_tsf(struct dvobj_priv *d, enum _hw_port hwport)
2095 struct halmac_adapter *halmac;
2096 struct halmac_api *api;
2097 enum halmac_portid port;
2098 enum halmac_ret_status status;
2102 halmac = dvobj_to_halmac(d);
2103 api = HALMAC_GET_API(halmac);
2104 port = _hw_port_drv2halmac(hwport);
2106 status = api->halmac_cfg_tsf_rst(halmac, port);
2107 if (status != HALMAC_RET_SUCCESS)
2116 * rtw_halmac_set_bcn_interval() - Set beacon interval of each port
2117 * @d: struct dvobj_priv*
2119 * @space: beacon interval, unit is ms
2121 * Set beacon interval of specific port to HALMAC.
2123 * Rteurn 0 for OK, otherwise fail.
2125 int rtw_halmac_set_bcn_interval(struct dvobj_priv *d, enum _hw_port hwport,
2128 struct halmac_adapter *halmac;
2129 struct halmac_api *api;
2130 enum halmac_portid port;
2131 enum halmac_ret_status status;
2135 halmac = dvobj_to_halmac(d);
2136 api = HALMAC_GET_API(halmac);
2137 port = _hw_port_drv2halmac(hwport);
2139 status = api->halmac_cfg_bcn_space(halmac, port, interval);
2140 if (status != HALMAC_RET_SUCCESS)
2149 * rtw_halmac_set_bcn_ctrl() - Set beacon control setting of each port
2150 * @d: struct dvobj_priv*
2152 * @bcn_ctrl: setting of beacon control
2154 * Set beacon control setting of specific port to HALMAC.
2156 * Rteurn 0 for OK, otherwise fail.
2158 int rtw_halmac_set_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,
2159 struct rtw_halmac_bcn_ctrl *bcn_ctrl)
2161 struct halmac_adapter *halmac;
2162 struct halmac_api *api;
2163 enum halmac_portid port;
2164 struct halmac_bcn_ctrl ctrl;
2165 enum halmac_ret_status status;
2169 halmac = dvobj_to_halmac(d);
2170 api = HALMAC_GET_API(halmac);
2171 port = _hw_port_drv2halmac(hwport);
2172 _rtw_memset(&ctrl, 0, sizeof(ctrl));
2173 _beacon_ctrl_drv2halmac(bcn_ctrl, &ctrl);
2175 status = api->halmac_rw_bcn_ctrl(halmac, port, 1, &ctrl);
2176 if (status != HALMAC_RET_SUCCESS)
2185 * rtw_halmac_set_aid() - Set association identifier(AID) of specific port
2186 * @d: struct dvobj_priv*
2188 * @aid: Association identifier
2190 * Set association identifier(AID) of specific port to HALMAC.
2192 * Rteurn 0 for OK, otherwise fail.
2194 int rtw_halmac_set_aid(struct dvobj_priv *d, enum _hw_port hwport, u16 aid)
2196 struct halmac_adapter *halmac;
2197 struct halmac_api *api;
2198 enum halmac_portid port;
2199 enum halmac_ret_status status;
2203 halmac = dvobj_to_halmac(d);
2204 api = HALMAC_GET_API(halmac);
2205 port = _hw_port_drv2halmac(hwport);
2208 status = api->halmac_cfg_aid(halmac, port, aid);
2209 if (status != HALMAC_RET_SUCCESS)
2217 a = dvobj_get_primary_adapter(d);
2221 addr = REG_BCN_PSR_RPT;
2222 val = rtw_read16(a, addr);
2223 val = BIT_SET_PS_AID_0(val, aid);
2224 rtw_write16(a, addr, val);
2228 addr = REG_BCN_PSR_RPT1;
2229 val = rtw_read16(a, addr);
2230 val = BIT_SET_PS_AID_1(val, aid);
2231 rtw_write16(a, addr, val);
2235 addr = REG_BCN_PSR_RPT2;
2236 val = rtw_read16(a, addr);
2237 val = BIT_SET_PS_AID_2(val, aid);
2238 rtw_write16(a, addr, val);
2242 addr = REG_BCN_PSR_RPT3;
2243 val = rtw_read16(a, addr);
2244 val = BIT_SET_PS_AID_3(val, aid);
2245 rtw_write16(a, addr, val);
2249 addr = REG_BCN_PSR_RPT4;
2250 val = rtw_read16(a, addr);
2251 val = BIT_SET_PS_AID_4(val, aid);
2252 rtw_write16(a, addr, val);
2266 int rtw_halmac_set_bandwidth(struct dvobj_priv *d, u8 channel, u8 pri_ch_idx, u8 bw)
2268 struct halmac_adapter *mac;
2269 struct halmac_api *api;
2270 enum halmac_ret_status status;
2273 mac = dvobj_to_halmac(d);
2274 api = HALMAC_GET_API(mac);
2276 status = api->halmac_cfg_ch_bw(mac, channel, pri_ch_idx, bw);
2277 if (HALMAC_RET_SUCCESS != status)
2284 * rtw_halmac_set_edca() - config edca parameter
2285 * @d: struct dvobj_priv*
2286 * @queue: XMIT_[VO/VI/BE/BK]_QUEUE
2287 * @aifs: Arbitration inter-frame space(AIFS)
2288 * @cw: Contention window(CW)
2289 * @txop: MAX Transmit Opportunity(TXOP)
2291 * Return: 0 if process OK, otherwise -1.
2293 int rtw_halmac_set_edca(struct dvobj_priv *d, u8 queue, u8 aifs, u8 cw, u16 txop)
2295 struct halmac_adapter *mac;
2296 struct halmac_api *api;
2297 enum halmac_acq_id ac;
2298 struct halmac_edca_para edca;
2299 enum halmac_ret_status status;
2302 mac = dvobj_to_halmac(d);
2303 api = HALMAC_GET_API(mac);
2307 ac = HALMAC_ACQ_ID_VO;
2310 ac = HALMAC_ACQ_ID_VI;
2313 ac = HALMAC_ACQ_ID_BE;
2316 ac = HALMAC_ACQ_ID_BK;
2324 edca.txop_limit = txop;
2326 status = api->halmac_cfg_edca_para(mac, ac, &edca);
2327 if (status != HALMAC_RET_SUCCESS)
2334 * rtw_halmac_set_rts_full_bw() - Send RTS to all covered channels
2335 * @d: struct dvobj_priv*
2336 * @enable: _TRUE(enable), _FALSE(disable)
2338 * Hradware will duplicate RTS packet to all channels which are covered in used
2341 * Return 0 if process OK, otherwise -1.
2343 int rtw_halmac_set_rts_full_bw(struct dvobj_priv *d, u8 enable)
2345 struct halmac_adapter *mac;
2346 struct halmac_api *api;
2347 enum halmac_ret_status status;
2351 mac = dvobj_to_halmac(d);
2352 api = HALMAC_GET_API(mac);
2353 full = (enable == _TRUE) ? 1 : 0;
2355 status = api->halmac_set_hw_value(mac, HALMAC_HW_RTS_FULL_BW, &full);
2356 if (HALMAC_RET_SUCCESS != status)
2362 #ifdef RTW_HALMAC_DBG_POWER_SWITCH
2363 static void _dump_mac_reg(struct dvobj_priv *d, u32 start, u32 end)
2365 struct _ADAPTER *adapter;
2369 adapter = dvobj_get_primary_adapter(d);
2370 for (i = start; i < end; i += 4) {
2372 RTW_PRINT("0x%04x", i);
2373 _RTW_PRINT(" 0x%08x ", rtw_read32(adapter, i));
2379 void dump_dbg_val(struct _ADAPTER *a, u32 reg)
2384 rtw_write8(a, 0x3A, reg);
2385 v32 = rtw_read32(a, 0xC0);
2386 RTW_PRINT("0x3A = %02x, 0xC0 = 0x%08x\n",reg, v32);
2389 #ifdef CONFIG_PCI_HCI
2390 static void _dump_pcie_cfg_space(struct dvobj_priv *d)
2392 struct _ADAPTER *padapter = dvobj_get_primary_adapter(d);
2393 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
2394 struct pci_dev *pdev = pdvobjpriv->ppcidev;
2395 struct pci_dev *bridge_pdev = pdev->bus->self;
2400 RTW_PRINT("\n***** PCI Device Configuration Space *****\n\n");
2402 for(i = 0; i < 0x100; i += 0x10)
2404 for (j = 0 ; j < 4 ; j++)
2405 pci_read_config_dword(pdev, i + j * 4, tmp+j);
2407 RTW_PRINT("%03x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
2408 i, tmp[0] & 0xFF, (tmp[0] >> 8) & 0xFF, (tmp[0] >> 16) & 0xFF, (tmp[0] >> 24) & 0xFF,
2409 tmp[1] & 0xFF, (tmp[1] >> 8) & 0xFF, (tmp[1] >> 16) & 0xFF, (tmp[1] >> 24) & 0xFF,
2410 tmp[2] & 0xFF, (tmp[2] >> 8) & 0xFF, (tmp[2] >> 16) & 0xFF, (tmp[2] >> 24) & 0xFF,
2411 tmp[3] & 0xFF, (tmp[3] >> 8) & 0xFF, (tmp[3] >> 16) & 0xFF, (tmp[3] >> 24) & 0xFF);
2414 RTW_PRINT("\n***** PCI Host Device Configuration Space*****\n\n");
2416 for(i = 0; i < 0x100; i += 0x10)
2418 for (j = 0 ; j < 4 ; j++)
2419 pci_read_config_dword(bridge_pdev, i + j * 4, tmp+j);
2421 RTW_PRINT("%03x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
2422 i, tmp[0] & 0xFF, (tmp[0] >> 8) & 0xFF, (tmp[0] >> 16) & 0xFF, (tmp[0] >> 24) & 0xFF,
2423 tmp[1] & 0xFF, (tmp[1] >> 8) & 0xFF, (tmp[1] >> 16) & 0xFF, (tmp[1] >> 24) & 0xFF,
2424 tmp[2] & 0xFF, (tmp[2] >> 8) & 0xFF, (tmp[2] >> 16) & 0xFF, (tmp[2] >> 24) & 0xFF,
2425 tmp[3] & 0xFF, (tmp[3] >> 8) & 0xFF, (tmp[3] >> 16) & 0xFF, (tmp[3] >> 24) & 0xFF);
2430 static void _dump_mac_reg_for_power_switch(struct dvobj_priv *d,
2431 const char* caller, char* desc)
2437 RTW_PRINT("%s: %s\n", caller, desc);
2438 RTW_PRINT("======= MAC REG =======\n");
2440 _dump_mac_reg(d, 0x0, 0x200);
2441 _dump_mac_reg(d, 0x300, 0x400); /* also dump page 3 */
2443 /* dump debug register */
2444 a = dvobj_get_primary_adapter(d);
2446 #ifdef CONFIG_PCI_HCI
2447 _dump_pcie_cfg_space(d);
2449 v8 = rtw_read8(a, 0xF6) | 0x01;
2450 rtw_write8(a, 0xF6, v8);
2451 RTW_PRINT("0xF6 = %02x\n", v8);
2453 dump_dbg_val(a, 0x63);
2454 dump_dbg_val(a, 0x64);
2455 dump_dbg_val(a, 0x68);
2456 dump_dbg_val(a, 0x69);
2457 dump_dbg_val(a, 0x6a);
2458 dump_dbg_val(a, 0x6b);
2459 dump_dbg_val(a, 0x71);
2460 dump_dbg_val(a, 0x72);
2464 static enum halmac_ret_status _power_switch(struct halmac_adapter *halmac,
2465 struct halmac_api *api,
2466 enum halmac_mac_power pwr)
2468 enum halmac_ret_status status;
2469 char desc[80] = {0};
2472 rtw_sprintf(desc, 80, "before calling power %s",
2473 (pwr==HALMAC_MAC_POWER_ON)?"on":"off");
2474 _dump_mac_reg_for_power_switch((struct dvobj_priv *)halmac->drv_adapter,
2475 __FUNCTION__, desc);
2477 status = api->halmac_mac_power_switch(halmac, pwr);
2478 RTW_PRINT("%s: status=%d\n", __FUNCTION__, status);
2480 rtw_sprintf(desc, 80, "after calling power %s",
2481 (pwr==HALMAC_MAC_POWER_ON)?"on":"off");
2482 _dump_mac_reg_for_power_switch((struct dvobj_priv *)halmac->drv_adapter,
2483 __FUNCTION__, desc);
2487 #else /* !RTW_HALMAC_DBG_POWER_SWITCH */
2488 #define _power_switch(mac, api, pwr) (api)->halmac_mac_power_switch(mac, pwr)
2489 #endif /* !RTW_HALMAC_DBG_POWER_SWITCH */
2493 * Power on device hardware.
2494 * [Notice!] If device's power state is on before,
2495 * it would be power off first and turn on power again.
2498 * 0 power on success
2500 * -2 power state unchange
2502 int rtw_halmac_poweron(struct dvobj_priv *d)
2504 struct halmac_adapter *halmac;
2505 struct halmac_api *api;
2506 enum halmac_ret_status status;
2508 #if defined(CONFIG_PCI_HCI) && defined(CONFIG_RTL8822B)
2513 a = dvobj_get_primary_adapter(d);
2516 halmac = dvobj_to_halmac(d);
2520 api = HALMAC_GET_API(halmac);
2522 status = api->halmac_pre_init_system_cfg(halmac);
2523 if (status != HALMAC_RET_SUCCESS)
2526 #ifdef CONFIG_SDIO_HCI
2527 status = api->halmac_sdio_cmd53_4byte(halmac, HALMAC_SDIO_CMD53_4BYTE_MODE_RW);
2528 if (status != HALMAC_RET_SUCCESS)
2530 #endif /* CONFIG_SDIO_HCI */
2532 #if defined(CONFIG_PCI_HCI) && defined(CONFIG_RTL8822B)
2534 v8 = rtw_read8(a, addr);
2535 RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v8);
2536 /* are we in pcie debug mode? */
2537 if (!(v8 & BIT(2))) {
2538 RTW_PRINT("%s: Enable pcie debug mode\n", __FUNCTION__);
2540 v8 = rtw_write8(a, addr, v8);
2544 status = _power_switch(halmac, api, HALMAC_MAC_POWER_ON);
2545 if (HALMAC_RET_PWR_UNCHANGE == status) {
2547 #if defined(CONFIG_PCI_HCI) && defined(CONFIG_RTL8822B)
2549 v8 = rtw_read8(a, addr);
2550 RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v8);
2552 /* are we in pcie debug mode? */
2553 if (!(v8 & BIT(2))) {
2554 RTW_PRINT("%s: Enable pcie debug mode\n", __FUNCTION__);
2556 v8 = rtw_write8(a, addr, v8);
2557 } else if (v8 & BIT(0)) {
2560 v8 = rtw_read8(a, addr);
2561 RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v8);
2562 RTW_PRINT("%s: recover DMA stuck\n", __FUNCTION__);
2564 v8 = rtw_write8(a, addr, v8);
2565 RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v8);
2569 * Work around for warm reboot but device not power off,
2570 * but it would also fall into this case when auto power on is enabled.
2572 _power_switch(halmac, api, HALMAC_MAC_POWER_OFF);
2573 status = _power_switch(halmac, api, HALMAC_MAC_POWER_ON);
2574 RTW_WARN("%s: Power state abnormal, try to recover...%s\n",
2575 __FUNCTION__, (HALMAC_RET_SUCCESS == status)?"OK":"FAIL!");
2577 if (HALMAC_RET_SUCCESS != status) {
2578 if (HALMAC_RET_PWR_UNCHANGE == status)
2583 status = api->halmac_init_system_cfg(halmac);
2584 if (status != HALMAC_RET_SUCCESS)
2594 * Power off device hardware.
2597 * 0 Power off success
2600 int rtw_halmac_poweroff(struct dvobj_priv *d)
2602 struct halmac_adapter *halmac;
2603 struct halmac_api *api;
2604 enum halmac_ret_status status;
2608 halmac = dvobj_to_halmac(d);
2612 api = HALMAC_GET_API(halmac);
2614 status = _power_switch(halmac, api, HALMAC_MAC_POWER_OFF);
2615 if ((HALMAC_RET_SUCCESS != status)
2616 && (HALMAC_RET_PWR_UNCHANGE != status))
2624 #ifdef CONFIG_SUPPORT_TRX_SHARED
2625 static inline enum halmac_rx_fifo_expanding_mode _trx_share_mode_drv2halmac(u8 trx_share_mode)
2627 if (0 == trx_share_mode)
2628 return HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE;
2629 else if (1 == trx_share_mode)
2630 return HALMAC_RX_FIFO_EXPANDING_MODE_1_BLOCK;
2631 else if (2 == trx_share_mode)
2632 return HALMAC_RX_FIFO_EXPANDING_MODE_2_BLOCK;
2633 else if (3 == trx_share_mode)
2634 return HALMAC_RX_FIFO_EXPANDING_MODE_3_BLOCK;
2636 return HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE;
2639 static enum halmac_rx_fifo_expanding_mode _rtw_get_trx_share_mode(struct _ADAPTER *adapter)
2641 struct registry_priv *registry_par = &adapter->registrypriv;
2643 return _trx_share_mode_drv2halmac(registry_par->trx_share_mode);
2646 void dump_trx_share_mode(void *sel, struct _ADAPTER *adapter)
2648 struct registry_priv *registry_par = &adapter->registrypriv;
2649 u8 mode = _trx_share_mode_drv2halmac(registry_par->trx_share_mode);
2651 if (HALMAC_RX_FIFO_EXPANDING_MODE_1_BLOCK == mode)
2652 RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "RX_FIFO_EXPANDING_MODE_1");
2653 else if (HALMAC_RX_FIFO_EXPANDING_MODE_2_BLOCK == mode)
2654 RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "RX_FIFO_EXPANDING_MODE_2");
2655 else if (HALMAC_RX_FIFO_EXPANDING_MODE_3_BLOCK == mode)
2656 RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "RX_FIFO_EXPANDING_MODE_3");
2658 RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "DISABLE");
2662 static enum halmac_drv_rsvd_pg_num _rsvd_page_num_drv2halmac(u8 num)
2665 return HALMAC_RSVD_PG_NUM8;
2667 return HALMAC_RSVD_PG_NUM16;
2669 return HALMAC_RSVD_PG_NUM24;
2671 return HALMAC_RSVD_PG_NUM32;
2673 return HALMAC_RSVD_PG_NUM64;
2676 RTW_WARN("%s: Fail to allocate RSVD page(%d)!!"
2677 " The MAX RSVD page number is 128...\n",
2680 return HALMAC_RSVD_PG_NUM128;
2683 static u8 _rsvd_page_num_halmac2drv(enum halmac_drv_rsvd_pg_num rsvd_page_number)
2688 switch (rsvd_page_number) {
2689 case HALMAC_RSVD_PG_NUM8:
2693 case HALMAC_RSVD_PG_NUM16:
2697 case HALMAC_RSVD_PG_NUM24:
2701 case HALMAC_RSVD_PG_NUM32:
2705 case HALMAC_RSVD_PG_NUM64:
2709 case HALMAC_RSVD_PG_NUM128:
2717 static enum halmac_trx_mode _choose_trx_mode(struct dvobj_priv *d)
2722 p = dvobj_get_primary_adapter(d);
2724 if (p->registrypriv.wifi_spec)
2725 return HALMAC_TRX_MODE_WMM;
2727 #ifdef CONFIG_SUPPORT_TRX_SHARED
2728 if (_rtw_get_trx_share_mode(p))
2729 return HALMAC_TRX_MODE_TRXSHARE;
2732 return HALMAC_TRX_MODE_NORMAL;
2735 static inline enum halmac_rf_type _rf_type_drv2halmac(enum rf_type rf_drv)
2737 enum halmac_rf_type rf_mac;
2742 rf_mac = HALMAC_RF_1T1R;
2745 rf_mac = HALMAC_RF_1T2R;
2748 rf_mac = HALMAC_RF_2T2R;
2751 rf_mac = HALMAC_RF_2T3R;
2754 rf_mac = HALMAC_RF_2T4R;
2757 rf_mac = HALMAC_RF_3T3R;
2760 rf_mac = HALMAC_RF_3T4R;
2763 rf_mac = HALMAC_RF_4T4R;
2766 rf_mac = HALMAC_RF_MAX_TYPE;
2767 RTW_ERR("%s: Invalid RF type(0x%x)!\n", __FUNCTION__, rf_drv);
2774 static inline enum rf_type _rf_type_halmac2drv(enum halmac_rf_type rf_mac)
2776 enum rf_type rf_drv;
2780 case HALMAC_RF_1T2R:
2783 case HALMAC_RF_2T4R:
2786 case HALMAC_RF_2T2R:
2787 case HALMAC_RF_2T2R_GREEN:
2790 case HALMAC_RF_2T3R:
2793 case HALMAC_RF_1T1R:
2796 case HALMAC_RF_3T3R:
2799 case HALMAC_RF_3T4R:
2802 case HALMAC_RF_4T4R:
2806 rf_drv = RF_TYPE_MAX;
2807 RTW_ERR("%s: Invalid RF type(0x%x)!\n", __FUNCTION__, rf_mac);
2814 static enum odm_cut_version _cut_version_drv2phydm(
2815 enum tag_HAL_Cut_Version_Definition cut_drv)
2817 enum odm_cut_version cut_phydm = ODM_CUT_A;
2821 if (cut_drv > K_CUT_VERSION)
2822 RTW_WARN("%s: unknown cut_ver=%d !!\n", __FUNCTION__, cut_drv);
2824 diff = cut_drv - A_CUT_VERSION;
2830 static int _send_general_info_by_reg(struct dvobj_priv *d,
2831 struct halmac_general_info *info)
2834 struct hal_com_data *hal;
2835 enum tag_HAL_Cut_Version_Definition cut_drv;
2836 enum rf_type rftype;
2837 enum odm_cut_version cut_phydm;
2838 u8 h2c[RTW_HALMAC_H2C_MAX_SIZE] = {0};
2841 a = dvobj_get_primary_adapter(d);
2842 hal = GET_HAL_DATA(a);
2843 rftype = _rf_type_halmac2drv(info->rf_type);
2844 cut_drv = GET_CVID_CUT_VERSION(hal->version_id);
2845 cut_phydm = _cut_version_drv2phydm(cut_drv);
2847 #define CLASS_GENERAL_INFO_REG 0x02
2848 #define CMD_ID_GENERAL_INFO_REG 0x0C
2849 #define GENERAL_INFO_REG_SET_CMD_ID(buf, v) SET_BITS_TO_LE_4BYTE(buf, 0, 5, v)
2850 #define GENERAL_INFO_REG_SET_CLASS(buf, v) SET_BITS_TO_LE_4BYTE(buf, 5, 3, v)
2851 #define GENERAL_INFO_REG_SET_RFE_TYPE(buf, v) SET_BITS_TO_LE_4BYTE(buf, 8, 8, v)
2852 #define GENERAL_INFO_REG_SET_RF_TYPE(buf, v) SET_BITS_TO_LE_4BYTE(buf, 16, 8, v)
2853 #define GENERAL_INFO_REG_SET_CUT_VERSION(buf, v) SET_BITS_TO_LE_4BYTE(buf, 24, 8, v)
2854 #define GENERAL_INFO_REG_SET_RX_ANT_STATUS(buf, v) SET_BITS_TO_LE_1BYTE(buf+4, 0, 4, v)
2855 #define GENERAL_INFO_REG_SET_TX_ANT_STATUS(buf, v) SET_BITS_TO_LE_1BYTE(buf+4, 4, 4, v)
2857 GENERAL_INFO_REG_SET_CMD_ID(h2c, CMD_ID_GENERAL_INFO_REG);
2858 GENERAL_INFO_REG_SET_CLASS(h2c, CLASS_GENERAL_INFO_REG);
2859 GENERAL_INFO_REG_SET_RFE_TYPE(h2c, info->rfe_type);
2860 GENERAL_INFO_REG_SET_RF_TYPE(h2c, rftype);
2861 GENERAL_INFO_REG_SET_CUT_VERSION(h2c, cut_phydm);
2862 GENERAL_INFO_REG_SET_RX_ANT_STATUS(h2c, info->rx_ant_status);
2863 GENERAL_INFO_REG_SET_TX_ANT_STATUS(h2c, info->tx_ant_status);
2865 return rtw_halmac_send_h2c(d, h2c);
2868 static int _send_general_info(struct dvobj_priv *d)
2870 struct _ADAPTER *adapter;
2871 struct hal_com_data *hal;
2872 struct halmac_adapter *halmac;
2873 struct halmac_api *api;
2874 struct halmac_general_info info;
2875 enum halmac_ret_status status;
2876 enum rf_type rf = RF_1T1R;
2877 enum bb_path txpath = BB_PATH_A;
2878 enum bb_path rxpath = BB_PATH_A;
2882 adapter = dvobj_get_primary_adapter(d);
2883 hal = GET_HAL_DATA(adapter);
2884 halmac = dvobj_to_halmac(d);
2887 api = HALMAC_GET_API(halmac);
2889 _rtw_memset(&info, 0, sizeof(info));
2890 info.rfe_type = (u8)hal->rfe_type;
2891 rtw_hal_get_rf_path(d, &rf, &txpath, &rxpath);
2892 info.rf_type = _rf_type_drv2halmac(rf);
2893 info.tx_ant_status = (u8)txpath;
2894 info.rx_ant_status = (u8)rxpath;
2896 status = api->halmac_send_general_info(halmac, &info);
2898 case HALMAC_RET_SUCCESS:
2900 case HALMAC_RET_NO_DLFW:
2901 RTW_WARN("%s: halmac_send_general_info() fail because fw not dl!\n",
2903 __attribute__((__fallthrough__));
2908 err = _send_general_info_by_reg(d, &info);
2910 RTW_ERR("%s: Fail to send general info by register!\n",
2918 static int _cfg_drv_rsvd_pg_num(struct dvobj_priv *d)
2921 struct hal_com_data *hal;
2922 struct halmac_adapter *halmac;
2923 struct halmac_api *api;
2924 enum halmac_drv_rsvd_pg_num rsvd_page_number;
2925 enum halmac_ret_status status;
2929 a = dvobj_get_primary_adapter(d);
2930 hal = GET_HAL_DATA(a);
2931 halmac = dvobj_to_halmac(d);
2932 api = HALMAC_GET_API(halmac);
2934 drv_rsvd_num = rtw_hal_get_rsvd_page_num(a);
2935 rsvd_page_number = _rsvd_page_num_drv2halmac(drv_rsvd_num);
2936 status = api->halmac_cfg_drv_rsvd_pg_num(halmac, rsvd_page_number);
2937 if (status != HALMAC_RET_SUCCESS)
2939 hal->drv_rsvd_page_number = _rsvd_page_num_halmac2drv(rsvd_page_number);
2941 if (drv_rsvd_num != hal->drv_rsvd_page_number)
2942 RTW_INFO("%s: request %d pages, but allocate %d pages\n",
2943 __FUNCTION__, drv_rsvd_num, hal->drv_rsvd_page_number);
2948 static void _debug_dlfw_fail(struct dvobj_priv *d)
2953 u8 data[0x100] = {0};
2956 a = dvobj_get_primary_adapter(d);
2958 /* read 0x80[15:0], 0x10F8[31:0] once */
2960 v32 = rtw_read16(a, addr);
2961 RTW_PRINT("%s: 0x%X = 0x%04x\n", __FUNCTION__, addr, v32);
2964 v32 = rtw_read32(a, addr);
2965 RTW_PRINT("%s: 0x%X = 0x%08x\n", __FUNCTION__, addr, v32);
2967 /* read 0x10FC[31:0], 5 times */
2970 for (i = 0; i < n; i++) {
2971 v32 = rtw_read32(a, addr);
2972 RTW_PRINT("%s: 0x%X = 0x%08x (%u/%u)\n",
2973 __FUNCTION__, addr, v32, i, n);
2977 * write 0x3A[7:0]=0x28 and 0xF6[7:0]=0x01
2978 * and then read 0xC0[31:0] 5 times
2982 rtw_write8(a, addr, (u8)v32);
2983 v32 = rtw_read8(a, addr);
2984 RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v32);
2988 rtw_write8(a, addr, (u8)v32);
2989 v32 = rtw_read8(a, addr);
2990 RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v32);
2994 for (i = 0; i < n; i++) {
2995 v32 = rtw_read32(a, addr);
2996 RTW_PRINT("%s: 0x%X = 0x%08x (%u/%u)\n",
2997 __FUNCTION__, addr, v32, i, n);
3000 /* 0x00~0xFF, 0x1000~0x10FF */
3003 for (i = 0; i < n; i+=4)
3004 *(u32*)&data[i] = cpu_to_le32(rtw_read32(a, addr+i));
3005 for (i = 0; i < n; i++) {
3007 RTW_PRINT("0x%04x\t", addr+i);
3008 _RTW_PRINT("0x%02x", data[i]);
3017 for (i = 0; i < n; i+=4)
3018 *(u32*)&data[i] = cpu_to_le32(rtw_read32(a, addr+i));
3019 for (i = 0; i < n; i++) {
3021 RTW_PRINT("0x%04x\t", addr+i);
3022 _RTW_PRINT("0x%02x", data[i]);
3029 /* read 0x80 after 10 secs */
3030 rtw_msleep_os(10000);
3032 v32 = rtw_read16(a, addr);
3033 RTW_PRINT("%s: 0x%X = 0x%04x (after 10 secs)\n",
3034 __FUNCTION__, addr, v32);
3037 static enum halmac_ret_status _enter_cpu_sleep_mode(struct dvobj_priv *d)
3039 struct hal_com_data *hal;
3040 struct halmac_adapter *mac;
3041 struct halmac_api *api;
3044 hal = GET_HAL_DATA(dvobj_get_primary_adapter(d));
3045 mac = dvobj_to_halmac(d);
3046 api = HALMAC_GET_API(mac);
3048 #ifdef CONFIG_RTL8822B
3049 /* Support after firmware version 21 */
3050 if (hal->firmware_version < 21)
3051 return HALMAC_RET_NOT_SUPPORT;
3052 #elif defined(CONFIG_RTL8821C)
3053 /* Support after firmware version 13.6 or 16 */
3054 if (hal->firmware_version == 13) {
3055 if (hal->firmware_sub_version < 6)
3056 return HALMAC_RET_NOT_SUPPORT;
3057 } else if (hal->firmware_version < 16) {
3058 return HALMAC_RET_NOT_SUPPORT;
3062 return api->halmac_enter_cpu_sleep_mode(mac);
3066 * _cpu_sleep() - Let IC CPU enter sleep mode
3067 * @d: struct dvobj_priv*
3068 * @timeout: time limit of wait, unit is ms
3071 * Rteurn 0 for CPU in sleep mode, otherwise fail to enter sleep mode.
3072 * Error codes definition are as follow:
3073 * -1 HALMAC enter sleep return fail
3074 * -2 HALMAC get CPU mode return fail
3077 static int _cpu_sleep(struct dvobj_priv *d, u32 timeout)
3079 struct halmac_adapter *mac;
3080 struct halmac_api *api;
3081 enum halmac_ret_status status;
3082 enum halmac_wlcpu_mode mode = HALMAC_WLCPU_UNDEFINE;
3089 mac = dvobj_to_halmac(d);
3090 api = HALMAC_GET_API(mac);
3092 start_t = rtw_get_current_time();
3094 status = _enter_cpu_sleep_mode(d);
3095 if (status != HALMAC_RET_SUCCESS) {
3096 if (status != HALMAC_RET_NOT_SUPPORT)
3104 mode = HALMAC_WLCPU_UNDEFINE;
3105 status = api->halmac_get_cpu_mode(mac, &mode);
3107 period = rtw_get_passing_time_ms(start_t);
3109 if (status != HALMAC_RET_SUCCESS) {
3113 if (mode == HALMAC_WLCPU_SLEEP)
3115 if (period > timeout) {
3125 RTW_ERR("%s: Fail to enter sleep mode! (%d, %d)\n",
3126 __FUNCTION__, status, mode);
3128 RTW_INFO("%s: Cost %dms to polling %u times. (err=%d)\n",
3129 __FUNCTION__, period, cnt, err);
3134 static void _init_trx_cfg_drv(struct dvobj_priv *d)
3136 #ifdef CONFIG_PCI_HCI
3137 rtw_hal_irp_reset(dvobj_get_primary_adapter(d));
3143 * Downlaod Firmware Flow
3146 * d pointer of struct dvobj_priv
3148 * fwsize firmware size
3149 * re_dl re-download firmware or not
3150 * 0: run in init hal flow, not re-download
3151 * 1: it is a stand alone operation, not in init hal flow
3157 static int download_fw(struct dvobj_priv *d, u8 *fw, u32 fwsize, u8 re_dl)
3160 struct halmac_adapter *mac;
3161 struct halmac_api *api;
3162 struct halmac_fw_version fw_vesion;
3163 enum halmac_ret_status status;
3167 hal = GET_HAL_DATA(dvobj_get_primary_adapter(d));
3168 mac = dvobj_to_halmac(d);
3169 api = HALMAC_GET_API(mac);
3171 if ((!fw) || (!fwsize))
3174 /* 1. Driver Stop Tx */
3177 /* 2. Driver Check Tx FIFO is empty */
3178 err = rtw_halmac_txfifo_wait_empty(d, 2000); /* wait 2s */
3184 /* 3. Config MAX download size */
3186 * Already done in rtw_halmac_init_adapter() or
3187 * somewhere calling rtw_halmac_set_max_dl_fw_size().
3191 /* 4. Enter IC CPU sleep mode */
3192 err = _cpu_sleep(d, 2000);
3194 RTW_ERR("%s: IC CPU fail to enter sleep mode!(%d)\n",
3196 /* skip this error */
3201 /* 5. Download Firmware */
3202 status = api->halmac_download_firmware(mac, fw, fwsize);
3203 if (status != HALMAC_RET_SUCCESS) {
3204 RTW_ERR("%s: download firmware FAIL! status=0x%02x\n",
3205 __FUNCTION__, status);
3206 _debug_dlfw_fail(d);
3211 /* 5.1. (Driver) Reset driver variables if needed */
3212 hal->LastHMEBoxNum = 0;
3214 /* 5.2. (Driver) Get FW version */
3215 status = api->halmac_get_fw_version(mac, &fw_vesion);
3216 if (status == HALMAC_RET_SUCCESS) {
3217 hal->firmware_version = fw_vesion.version;
3218 hal->firmware_sub_version = fw_vesion.sub_version;
3219 hal->firmware_size = fwsize;
3223 /* 6. Driver resume TX if needed */
3230 enum halmac_trx_mode mode;
3232 /* 7. Change reserved page size */
3233 err = _cfg_drv_rsvd_pg_num(d);
3237 /* 8. Init TRX Configuration */
3238 mode = _choose_trx_mode(d);
3239 status = api->halmac_init_trx_cfg(mac, mode);
3240 if (HALMAC_RET_SUCCESS != status)
3242 _init_trx_cfg_drv(d);
3244 /* 9. Config RX Aggregation */
3245 err = rtw_halmac_rx_agg_switch(d, _TRUE);
3249 /* 10. Send General Info */
3250 err = _send_general_info(d);
3259 static int init_mac_flow(struct dvobj_priv *d)
3262 struct hal_com_data *hal;
3263 struct halmac_adapter *halmac;
3264 struct halmac_api *api;
3265 enum halmac_drv_rsvd_pg_num rsvd_page_number;
3266 union halmac_wlan_addr hwa;
3267 enum halmac_trx_mode trx_mode;
3268 enum halmac_ret_status status;
3271 int err, err_ret = -1;
3274 p = dvobj_get_primary_adapter(d);
3275 hal = GET_HAL_DATA(p);
3276 halmac = dvobj_to_halmac(d);
3277 api = HALMAC_GET_API(halmac);
3279 #ifdef CONFIG_SUPPORT_TRX_SHARED
3280 status = api->halmac_cfg_rxff_expand_mode(halmac,
3281 _rtw_get_trx_share_mode(p));
3282 if (status != HALMAC_RET_SUCCESS)
3286 #if 0 /* It is not necessary to call this in normal driver */
3287 status = api->halmac_cfg_la_mode(halmac, HALMAC_LA_MODE_DISABLE);
3288 if (status != HALMAC_RET_SUCCESS)
3292 err = _cfg_drv_rsvd_pg_num(d);
3296 #ifdef CONFIG_USB_HCI
3297 status = api->halmac_set_bulkout_num(halmac, d->RtNumOutPipes);
3298 if (status != HALMAC_RET_SUCCESS)
3300 #endif /* CONFIG_USB_HCI */
3302 trx_mode = _choose_trx_mode(d);
3303 status = api->halmac_init_mac_cfg(halmac, trx_mode);
3304 if (status != HALMAC_RET_SUCCESS)
3306 _init_trx_cfg_drv(d);
3308 err = rtw_halmac_rx_agg_switch(d, _TRUE);
3312 nettype = dvobj_to_regsty(d)->wireless_mode;
3313 if (is_supported_vht(nettype) == _TRUE)
3314 status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_AC);
3315 else if (is_supported_ht(nettype) == _TRUE)
3316 status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_N);
3317 else if (IsSupportedTxOFDM(nettype) == _TRUE)
3318 status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_G);
3320 status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_B);
3321 if (status != HALMAC_RET_SUCCESS)
3329 static int _drv_enable_trx(struct dvobj_priv *d)
3331 struct _ADAPTER *adapter;
3335 adapter = dvobj_get_primary_adapter(d);
3336 if (adapter->bup == _FALSE) {
3337 #ifdef CONFIG_NEW_NETDEV_HDL
3338 status = rtw_mi_start_drv_threads(adapter);
3340 status = rtw_start_drv_threads(adapter);
3342 if (status == _FAIL) {
3343 RTW_ERR("%s: Start threads Failed!\n", __FUNCTION__);
3348 rtw_intf_start(adapter);
3356 * 1. rtw_hal_get_hwreg(HW_VAR_RF_TYPE)
3357 * 2. HAL_DATA_TYPE.rfe_type
3358 * already ready for use before calling this function.
3360 static int _halmac_init_hal(struct dvobj_priv *d, u8 *fw, u32 fwsize)
3363 struct halmac_adapter *halmac;
3364 struct halmac_api *api;
3365 enum halmac_ret_status status;
3368 int err, err_ret = -1;
3371 adapter = dvobj_get_primary_adapter(d);
3372 halmac = dvobj_to_halmac(d);
3375 api = HALMAC_GET_API(halmac);
3379 /* SKIP: halmac_init_adapter (Already done before) */
3381 /* halmac_pre_Init_system_cfg */
3382 /* halmac_mac_power_switch(on) */
3383 /* halmac_Init_system_cfg */
3384 ok = rtw_hal_power_on(adapter);
3392 err = download_fw(d, fw, fwsize, 0);
3399 err = init_mac_flow(d);
3403 /* Driver insert flow: Enable TR/RX */
3404 err = _drv_enable_trx(d);
3408 /* halmac_send_general_info */
3409 if (_TRUE == fw_ok) {
3410 err = _send_general_info(d);
3415 /* Init Phy parameter-MAC */
3416 ok = rtw_hal_init_mac_register(adapter);
3420 /* StateMacInitialized */
3422 /* halmac_cfg_drv_info */
3423 err = rtw_halmac_config_rx_info(d, HALMAC_DRV_INFO_PHY_STATUS);
3427 /* halmac_set_hw_value(HALMAC_HW_EN_BB_RF) */
3429 ok = rtw_hal_init_phy(adapter);
3433 status = api->halmac_init_interface_cfg(halmac);
3434 if (status != HALMAC_RET_SUCCESS)
3437 /* SKIP: halmac_verify_platform_api */
3438 /* SKIP: halmac_h2c_lb */
3447 int rtw_halmac_init_hal(struct dvobj_priv *d)
3449 return _halmac_init_hal(d, NULL, 0);
3455 * 1. rtw_hal_get_hwreg(HW_VAR_RF_TYPE)
3456 * 2. HAL_DATA_TYPE.rfe_type
3457 * already ready for use before calling this function.
3459 int rtw_halmac_init_hal_fw(struct dvobj_priv *d, u8 *fw, u32 fwsize)
3461 return _halmac_init_hal(d, fw, fwsize);
3467 * 1. rtw_hal_get_hwreg(HW_VAR_RF_TYPE)
3468 * 2. HAL_DATA_TYPE.rfe_type
3469 * already ready for use before calling this function.
3471 int rtw_halmac_init_hal_fw_file(struct dvobj_priv *d, u8 *fwpath)
3474 u32 fwmaxsize = 0, size = 0;
3478 err = rtw_halmac_get_fw_max_size(d, &fwmaxsize);
3480 RTW_ERR("%s: Fail to get Firmware MAX size(err=%d)\n", __FUNCTION__, err);
3484 fw = rtw_zmalloc(fwmaxsize);
3488 size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
3494 err = _halmac_init_hal(d, fw, size);
3497 rtw_mfree(fw, fwmaxsize);
3503 int rtw_halmac_deinit_hal(struct dvobj_priv *d)
3506 struct halmac_adapter *halmac;
3507 struct halmac_api *api;
3508 enum halmac_ret_status status;
3512 adapter = dvobj_get_primary_adapter(d);
3513 halmac = dvobj_to_halmac(d);
3516 api = HALMAC_GET_API(halmac);
3518 status = api->halmac_deinit_interface_cfg(halmac);
3519 if (status != HALMAC_RET_SUCCESS)
3522 rtw_hal_power_off(adapter);
3529 int rtw_halmac_self_verify(struct dvobj_priv *d)
3531 struct halmac_adapter *mac;
3532 struct halmac_api *api;
3533 enum halmac_ret_status status;
3537 mac = dvobj_to_halmac(d);
3538 api = HALMAC_GET_API(mac);
3540 status = api->halmac_verify_platform_api(mac);
3541 if (status != HALMAC_RET_SUCCESS)
3544 status = api->halmac_h2c_lb(mac);
3545 if (status != HALMAC_RET_SUCCESS)
3553 static u8 rtw_halmac_txfifo_is_empty(struct dvobj_priv *d)
3555 struct halmac_adapter *mac;
3556 struct halmac_api *api;
3557 enum halmac_ret_status status;
3562 mac = dvobj_to_halmac(d);
3563 api = HALMAC_GET_API(mac);
3565 status = api->halmac_txfifo_is_empty(mac, chk_num);
3566 if (status == HALMAC_RET_SUCCESS)
3573 * rtw_halmac_txfifo_wait_empty() - Wait TX FIFO to be emtpy
3574 * @d: struct dvobj_priv*
3575 * @timeout: time limit of wait, unit is ms
3578 * Wait TX FIFO to be emtpy.
3580 * Rteurn 0 for TX FIFO is empty, otherwise not empty.
3582 int rtw_halmac_txfifo_wait_empty(struct dvobj_priv *d, u32 timeout)
3587 systime start_time = 0;
3588 u32 pass_time; /* ms */
3591 a = dvobj_get_primary_adapter(d);
3592 start_time = rtw_get_current_time();
3596 empty = rtw_halmac_txfifo_is_empty(d);
3601 pass_time = rtw_get_passing_time_ms(start_time);
3602 if (pass_time > timeout)
3605 if (RTW_CANNOT_IO(a)) {
3606 RTW_WARN("%s: Interrupted by I/O forbiden!\n", __FUNCTION__);
3613 if (empty == _FALSE) {
3614 #ifdef CONFIG_RTW_DEBUG
3615 u16 dbg_reg[] = {0x210, 0x230, 0x234, 0x238, 0x23C, 0x240,
3616 0x41A, 0x10FC, 0x10F8, 0x11F4, 0x11F8};
3620 if (!RTW_CANNOT_IO(a)) {
3621 for (i = 0; i < ARRAY_SIZE(dbg_reg); i++) {
3622 val = rtw_read32(a, dbg_reg[i]);
3623 RTW_ERR("REG_%X:0x%08x\n", dbg_reg[i], val);
3626 #endif /* CONFIG_RTW_DEBUG */
3628 RTW_ERR("%s: Fail to wait txfifo empty!(cnt=%d)\n",
3636 static enum halmac_dlfw_mem _fw_mem_drv2halmac(enum fw_mem mem, u8 tx_stop)
3638 enum halmac_dlfw_mem mem_halmac = HALMAC_DLFW_MEM_UNDEFINE;
3643 if (tx_stop == _FALSE)
3644 mem_halmac = HALMAC_DLFW_MEM_EMEM_RSVD_PG;
3646 mem_halmac = HALMAC_DLFW_MEM_EMEM;
3651 mem_halmac = HALMAC_DLFW_MEM_UNDEFINE;
3658 int rtw_halmac_dlfw_mem(struct dvobj_priv *d, u8 *fw, u32 fwsize, enum fw_mem mem)
3660 struct halmac_adapter *mac;
3661 struct halmac_api *api;
3662 enum halmac_ret_status status;
3663 enum halmac_dlfw_mem dlfw_mem;
3664 u8 tx_stop = _FALSE;
3665 u32 chk_timeout = 2000; /* unit: ms */
3669 mac = dvobj_to_halmac(d);
3670 api = HALMAC_GET_API(mac);
3672 if ((!fw) || (!fwsize))
3675 #ifndef RTW_HALMAC_DLFW_MEM_NO_STOP_TX
3676 /* 1. Driver Stop Tx */
3679 /* 2. Driver Check Tx FIFO is empty */
3680 err = rtw_halmac_txfifo_wait_empty(d, chk_timeout);
3685 #endif /* !RTW_HALMAC_DLFW_MEM_NO_STOP_TX */
3687 /* 3. Download Firmware MEM */
3688 dlfw_mem = _fw_mem_drv2halmac(mem, tx_stop);
3689 if (dlfw_mem == HALMAC_DLFW_MEM_UNDEFINE) {
3693 status = api->halmac_free_download_firmware(mac, dlfw_mem, fw, fwsize);
3694 if (status != HALMAC_RET_SUCCESS) {
3695 RTW_ERR("%s: halmac_free_download_firmware fail(err=0x%x)\n",
3696 __FUNCTION__, status);
3702 #ifndef RTW_HALMAC_DLFW_MEM_NO_STOP_TX
3703 /* 4. Driver resume TX if needed */
3705 #endif /* !RTW_HALMAC_DLFW_MEM_NO_STOP_TX */
3710 int rtw_halmac_dlfw_mem_from_file(struct dvobj_priv *d, u8 *fwpath, enum fw_mem mem)
3713 u32 fwmaxsize = 0, size = 0;
3717 err = rtw_halmac_get_fw_max_size(d, &fwmaxsize);
3719 RTW_ERR("%s: Fail to get Firmware MAX size(err=%d)\n", __FUNCTION__, err);
3723 fw = rtw_zmalloc(fwmaxsize);
3727 size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
3729 err = rtw_halmac_dlfw_mem(d, fw, size, mem);
3733 rtw_mfree(fw, fwmaxsize);
3742 * -22 Invalid arguemnt
3744 int rtw_halmac_dlfw(struct dvobj_priv *d, u8 *fw, u32 fwsize)
3747 enum halmac_ret_status status;
3749 int err, err_ret = -1;
3755 adapter = dvobj_get_primary_adapter(d);
3757 /* re-download firmware */
3758 if (rtw_is_hw_init_completed(adapter))
3759 return download_fw(d, fw, fwsize, 1);
3761 /* Download firmware before hal init */
3762 /* Power on, download firmware and init mac */
3763 ok = rtw_hal_power_on(adapter);
3767 err = download_fw(d, fw, fwsize, 0);
3773 err = init_mac_flow(d);
3777 err = _send_general_info(d);
3787 int rtw_halmac_dlfw_from_file(struct dvobj_priv *d, u8 *fwpath)
3790 u32 fwmaxsize = 0, size = 0;
3794 err = rtw_halmac_get_fw_max_size(d, &fwmaxsize);
3796 RTW_ERR("%s: Fail to get Firmware MAX size(err=%d)\n", __FUNCTION__, err);
3800 fw = rtw_zmalloc(fwmaxsize);
3804 size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
3806 err = rtw_halmac_dlfw(d, fw, size);
3810 rtw_mfree(fw, fwmaxsize);
3818 * Power on/off BB/RF domain.
3821 * enable _TRUE/_FALSE for power on/off
3827 int rtw_halmac_phy_power_switch(struct dvobj_priv *d, u8 enable)
3830 struct halmac_adapter *halmac;
3831 struct halmac_api *api;
3832 enum halmac_ret_status status;
3836 adapter = dvobj_get_primary_adapter(d);
3837 halmac = dvobj_to_halmac(d);
3840 api = HALMAC_GET_API(halmac);
3841 on = (enable == _TRUE) ? 1 : 0;
3843 status = api->halmac_set_hw_value(halmac, HALMAC_HW_EN_BB_RF, &on);
3844 if (status != HALMAC_RET_SUCCESS)
3850 static u8 _is_fw_read_cmd_down(PADAPTER adapter, u8 msgbox_num)
3852 u8 read_down = _FALSE;
3853 int retry_cnts = 100;
3857 valid = rtw_read8(adapter, REG_HMETFR) & BIT(msgbox_num);
3862 } while ((!read_down) && (retry_cnts--));
3864 if (_FALSE == read_down)
3865 RTW_WARN("%s, reg_1cc(%x), msg_box(%d)...\n", __func__, rtw_read8(adapter, REG_HMETFR), msgbox_num);
3871 * rtw_halmac_send_h2c() - Send H2C to firmware
3872 * @d: struct dvobj_priv*
3873 * @h2c: H2C data buffer, suppose to be 8 bytes
3875 * Send H2C to firmware by message box register(0x1D0~0x1D3 & 0x1F0~0x1F3).
3877 * Assume firmware be ready to accept H2C here, please check
3878 * (hal->bFWReady == _TRUE) before call this function or make sure firmware is
3881 * Return: 0 if process OK, otherwise fail to send this H2C.
3883 int rtw_halmac_send_h2c(struct dvobj_priv *d, u8 *h2c)
3885 PADAPTER adapter = dvobj_get_primary_adapter(d);
3886 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
3888 u32 msgbox_addr = 0;
3889 u32 msgbox_ex_addr = 0;
3896 RTW_WARN("%s: pbuf is NULL\n", __FUNCTION__);
3900 if (rtw_is_surprise_removed(adapter)) {
3901 RTW_WARN("%s: surprise removed\n", __FUNCTION__);
3905 _enter_critical_mutex(&d->h2c_fwcmd_mutex, NULL);
3907 /* pay attention to if race condition happened in H2C cmd setting */
3908 h2c_box_num = hal->LastHMEBoxNum;
3910 if (!_is_fw_read_cmd_down(adapter, h2c_box_num)) {
3911 RTW_WARN(" fw read cmd failed...\n");
3912 #ifdef DBG_CONFIG_ERROR_DETECT
3913 hal->srestpriv.self_dect_fw = _TRUE;
3914 hal->srestpriv.self_dect_fw_cnt++;
3915 #endif /* DBG_CONFIG_ERROR_DETECT */
3919 /* Write Ext command (byte 4~7) */
3920 msgbox_ex_addr = REG_HMEBOX_E0 + (h2c_box_num * EX_MESSAGE_BOX_SIZE);
3921 _rtw_memcpy((u8 *)(&h2c_cmd_ex), h2c + 4, EX_MESSAGE_BOX_SIZE);
3922 h2c_cmd_ex = le32_to_cpu(h2c_cmd_ex);
3923 rtw_write32(adapter, msgbox_ex_addr, h2c_cmd_ex);
3925 /* Write command (byte 0~3) */
3926 msgbox_addr = REG_HMEBOX0 + (h2c_box_num * MESSAGE_BOX_SIZE);
3927 _rtw_memcpy((u8 *)(&h2c_cmd), h2c, 4);
3928 h2c_cmd = le32_to_cpu(h2c_cmd);
3929 rtw_write32(adapter, msgbox_addr, h2c_cmd);
3931 /* update last msg box number */
3932 hal->LastHMEBoxNum = (h2c_box_num + 1) % MAX_H2C_BOX_NUMS;
3935 #ifdef DBG_H2C_CONTENT
3936 RTW_INFO_DUMP("[H2C] - ", h2c, RTW_HALMAC_H2C_MAX_SIZE);
3939 _exit_critical_mutex(&d->h2c_fwcmd_mutex, NULL);
3944 * rtw_halmac_c2h_handle() - Handle C2H for HALMAC
3945 * @d: struct dvobj_priv*
3946 * @c2h: Full C2H packet, including RX description and payload
3947 * @size: Size(byte) of c2h
3949 * Send C2H packet to HALMAC to process C2H packets, and the expected C2H ID is
3950 * 0xFF. This function won't have any I/O, so caller doesn't have to call it in
3951 * I/O safe place(ex. command thread).
3953 * Please sure doesn't call this function in the same thread as someone is
3954 * waiting HALMAC C2H ack, otherwise there is a deadlock happen.
3956 * Return: 0 if process OK, otherwise no action for this C2H.
3958 int rtw_halmac_c2h_handle(struct dvobj_priv *d, u8 *c2h, u32 size)
3960 struct halmac_adapter *mac;
3961 struct halmac_api *api;
3962 enum halmac_ret_status status;
3965 mac = dvobj_to_halmac(d);
3966 api = HALMAC_GET_API(mac);
3968 status = api->halmac_get_c2h_info(mac, c2h, size);
3969 if (HALMAC_RET_SUCCESS != status)
3975 int rtw_halmac_get_available_efuse_size(struct dvobj_priv *d, u32 *size)
3977 struct halmac_adapter *mac;
3978 struct halmac_api *api;
3979 enum halmac_ret_status status;
3983 mac = dvobj_to_halmac(d);
3984 api = HALMAC_GET_API(mac);
3986 status = api->halmac_get_efuse_available_size(mac, &val);
3987 if (HALMAC_RET_SUCCESS != status)
3994 int rtw_halmac_get_physical_efuse_size(struct dvobj_priv *d, u32 *size)
3996 struct halmac_adapter *mac;
3997 struct halmac_api *api;
3998 enum halmac_ret_status status;
4002 mac = dvobj_to_halmac(d);
4003 api = HALMAC_GET_API(mac);
4005 status = api->halmac_get_efuse_size(mac, &val);
4006 if (HALMAC_RET_SUCCESS != status)
4013 int rtw_halmac_read_physical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size)
4015 struct halmac_adapter *mac;
4016 struct halmac_api *api;
4017 enum halmac_ret_status status;
4018 enum halmac_feature_id id;
4022 mac = dvobj_to_halmac(d);
4023 api = HALMAC_GET_API(mac);
4024 id = HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE;
4026 ret = init_halmac_event(d, id, map, size);
4030 status = api->halmac_dump_efuse_map(mac, HALMAC_EFUSE_R_DRV);
4031 if (HALMAC_RET_SUCCESS != status) {
4032 free_halmac_event(d, id);
4036 ret = wait_halmac_event(d, id);
4043 int rtw_halmac_read_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4045 struct halmac_adapter *mac;
4046 struct halmac_api *api;
4047 enum halmac_ret_status status;
4055 mac = dvobj_to_halmac(d);
4056 api = HALMAC_GET_API(mac);
4058 if (api->halmac_read_efuse) {
4059 for (i = 0; i < cnt; i++) {
4060 status = api->halmac_read_efuse(mac, offset + i, &v);
4061 if (HALMAC_RET_SUCCESS != status)
4066 err = rtw_halmac_get_physical_efuse_size(d, &size);
4070 efuse = rtw_zmalloc(size);
4074 err = rtw_halmac_read_physical_efuse_map(d, efuse, size);
4078 _rtw_memcpy(data, efuse + offset, cnt);
4080 rtw_mfree(efuse, size);
4086 int rtw_halmac_write_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4088 struct halmac_adapter *mac;
4089 struct halmac_api *api;
4090 enum halmac_ret_status status;
4094 mac = dvobj_to_halmac(d);
4095 api = HALMAC_GET_API(mac);
4097 if (api->halmac_write_efuse == NULL)
4100 for (i = 0; i < cnt; i++) {
4101 status = api->halmac_write_efuse(mac, offset + i, data[i]);
4102 if (HALMAC_RET_SUCCESS != status)
4109 int rtw_halmac_get_logical_efuse_size(struct dvobj_priv *d, u32 *size)
4111 struct halmac_adapter *mac;
4112 struct halmac_api *api;
4113 enum halmac_ret_status status;
4117 mac = dvobj_to_halmac(d);
4118 api = HALMAC_GET_API(mac);
4120 status = api->halmac_get_logical_efuse_size(mac, &val);
4121 if (HALMAC_RET_SUCCESS != status)
4128 int rtw_halmac_read_logical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size, u8 *maskmap, u32 masksize)
4130 struct halmac_adapter *mac;
4131 struct halmac_api *api;
4132 enum halmac_ret_status status;
4133 enum halmac_feature_id id;
4137 mac = dvobj_to_halmac(d);
4138 api = HALMAC_GET_API(mac);
4139 id = HALMAC_FEATURE_DUMP_LOGICAL_EFUSE;
4141 ret = init_halmac_event(d, id, map, size);
4145 status = api->halmac_dump_logical_efuse_map(mac, HALMAC_EFUSE_R_DRV);
4146 if (HALMAC_RET_SUCCESS != status) {
4147 free_halmac_event(d, id);
4151 ret = wait_halmac_event(d, id);
4155 if (maskmap && masksize) {
4156 struct halmac_pg_efuse_info pginfo;
4158 pginfo.efuse_map = map;
4159 pginfo.efuse_map_size = size;
4160 pginfo.efuse_mask = maskmap;
4161 pginfo.efuse_mask_size = masksize;
4163 status = api->halmac_mask_logical_efuse(mac, &pginfo);
4164 if (status != HALMAC_RET_SUCCESS)
4165 RTW_WARN("%s: mask logical efuse FAIL!\n", __FUNCTION__);
4171 int rtw_halmac_write_logical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size, u8 *maskmap, u32 masksize)
4173 struct halmac_adapter *mac;
4174 struct halmac_api *api;
4175 struct halmac_pg_efuse_info pginfo;
4176 enum halmac_ret_status status;
4179 mac = dvobj_to_halmac(d);
4180 api = HALMAC_GET_API(mac);
4182 pginfo.efuse_map = map;
4183 pginfo.efuse_map_size = size;
4184 pginfo.efuse_mask = maskmap;
4185 pginfo.efuse_mask_size = masksize;
4187 status = api->halmac_pg_efuse_by_map(mac, &pginfo, HALMAC_EFUSE_R_AUTO);
4188 if (HALMAC_RET_SUCCESS != status)
4194 int rtw_halmac_read_logical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4196 struct halmac_adapter *mac;
4197 struct halmac_api *api;
4198 enum halmac_ret_status status;
4203 mac = dvobj_to_halmac(d);
4204 api = HALMAC_GET_API(mac);
4206 for (i = 0; i < cnt; i++) {
4207 status = api->halmac_read_logical_efuse(mac, offset + i, &v);
4208 if (HALMAC_RET_SUCCESS != status)
4216 int rtw_halmac_write_logical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4218 struct halmac_adapter *mac;
4219 struct halmac_api *api;
4220 enum halmac_ret_status status;
4224 mac = dvobj_to_halmac(d);
4225 api = HALMAC_GET_API(mac);
4227 for (i = 0; i < cnt; i++) {
4228 status = api->halmac_write_logical_efuse(mac, offset + i, data[i]);
4229 if (HALMAC_RET_SUCCESS != status)
4236 int rtw_halmac_write_bt_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4238 struct halmac_adapter *mac;
4239 struct halmac_api *api;
4240 enum halmac_ret_status status;
4245 mac = dvobj_to_halmac(d);
4246 api = HALMAC_GET_API(mac);
4248 for (i = 0; i < cnt; i++) {
4249 status = api->halmac_write_efuse_bt(mac, offset + i, data[i], bank);
4250 if (HALMAC_RET_SUCCESS != status) {
4251 printk("%s: halmac_write_efuse_bt status = %d\n", __FUNCTION__, status);
4255 printk("%s: halmac_write_efuse_bt status = HALMAC_RET_SUCCESS %d\n", __FUNCTION__, status);
4260 int rtw_halmac_read_bt_physical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size)
4262 struct halmac_adapter *mac;
4263 struct halmac_api *api;
4264 enum halmac_ret_status status;
4268 mac = dvobj_to_halmac(d);
4269 api = HALMAC_GET_API(mac);
4271 status = api->halmac_dump_efuse_map_bt(mac, bank, size, map);
4272 if (HALMAC_RET_SUCCESS != status) {
4273 printk("%s: halmac_dump_efuse_map_bt fail!\n", __FUNCTION__);
4277 printk("%s: OK!\n", __FUNCTION__);
4282 static enum hal_fifo_sel _fifo_sel_drv2halmac(u8 fifo_sel)
4286 return HAL_FIFO_SEL_TX;
4288 return HAL_FIFO_SEL_RX;
4290 return HAL_FIFO_SEL_RSVD_PAGE;
4292 return HAL_FIFO_SEL_REPORT;
4294 return HAL_FIFO_SEL_LLT;
4296 return HAL_FIFO_SEL_RXBUF_FW;
4299 return HAL_FIFO_SEL_RSVD_PAGE;
4302 /*#define CONFIG_HALMAC_FIFO_DUMP*/
4303 int rtw_halmac_dump_fifo(struct dvobj_priv *d, u8 fifo_sel, u32 addr, u32 size, u8 *buffer)
4305 struct halmac_adapter *mac;
4306 struct halmac_api *api;
4307 enum hal_fifo_sel halmac_fifo_sel;
4308 enum halmac_ret_status status;
4309 u8 *pfifo_map = NULL;
4311 s8 ret = 0;/* 0:success, -1:error */
4312 u8 mem_created = _FALSE;
4315 mac = dvobj_to_halmac(d);
4316 api = HALMAC_GET_API(mac);
4318 if ((size != 0) && (buffer == NULL))
4321 halmac_fifo_sel = _fifo_sel_drv2halmac(fifo_sel);
4323 if ((size) && (buffer)) {
4327 fifo_size = api->halmac_get_fifo_size(mac, halmac_fifo_sel);
4330 pfifo_map = rtw_zvmalloc(fifo_size);
4331 if (pfifo_map == NULL)
4333 mem_created = _TRUE;
4336 status = api->halmac_dump_fifo(mac, halmac_fifo_sel, addr, fifo_size, pfifo_map);
4337 if (HALMAC_RET_SUCCESS != status) {
4342 #ifdef CONFIG_HALMAC_FIFO_DUMP
4344 static const char * const fifo_sel_str[] = {
4345 "TX", "RX", "RSVD_PAGE", "REPORT", "LLT", "RXBUF_FW"
4348 RTW_INFO("%s FIFO DUMP [start_addr:0x%04x , size:%d]\n", fifo_sel_str[halmac_fifo_sel], addr, fifo_size);
4349 RTW_INFO_DUMP("\n", pfifo_map, fifo_size);
4350 RTW_INFO(" ==================================================\n");
4352 #endif /* CONFIG_HALMAC_FIFO_DUMP */
4355 if ((mem_created == _TRUE) && pfifo_map)
4356 rtw_vmfree(pfifo_map, fifo_size);
4362 * rtw_halmac_rx_agg_switch() - Switch RX aggregation function and setting
4363 * @d struct dvobj_priv *
4364 * @enable _FALSE/_TRUE for disable/enable RX aggregation function
4366 * This function could help to on/off bus RX aggregation function, and is only
4367 * useful for SDIO and USB interface. Although only "enable" flag is brough in,
4368 * some setting would be taken from other places, and they are from:
4370 * struct hal_com_data.rxagg_dma_size
4371 * struct hal_com_data.rxagg_dma_timeout
4372 * [USB aggregation] (only use for USB interface)
4373 * struct hal_com_data.rxagg_usb_size
4374 * struct hal_com_data.rxagg_usb_timeout
4375 * If above values of size and timeout are both 0 means driver would not
4376 * control the threshold setting and leave it to HALMAC handle.
4378 * From HALMAC V1_04_04, driver force the size threshold be hard limit, and the
4379 * rx size can not exceed the setting.
4381 * Return 0 for success, otherwise fail.
4383 int rtw_halmac_rx_agg_switch(struct dvobj_priv *d, u8 enable)
4385 struct _ADAPTER *adapter;
4386 struct hal_com_data *hal;
4387 struct halmac_adapter *halmac;
4388 struct halmac_api *api;
4389 struct halmac_rxagg_cfg rxaggcfg;
4390 enum halmac_ret_status status;
4393 adapter = dvobj_get_primary_adapter(d);
4394 hal = GET_HAL_DATA(adapter);
4395 halmac = dvobj_to_halmac(d);
4396 api = HALMAC_GET_API(halmac);
4397 _rtw_memset((void *)&rxaggcfg, 0, sizeof(rxaggcfg));
4398 rxaggcfg.mode = HALMAC_RX_AGG_MODE_NONE;
4400 * Always enable size limit to avoid rx size exceed
4401 * driver defined size.
4403 rxaggcfg.threshold.size_limit_en = 1;
4405 #ifdef RTW_RX_AGGREGATION
4406 if (_TRUE == enable) {
4407 #ifdef CONFIG_SDIO_HCI
4408 rxaggcfg.mode = HALMAC_RX_AGG_MODE_DMA;
4409 rxaggcfg.threshold.drv_define = 0;
4410 if (hal->rxagg_dma_size || hal->rxagg_dma_timeout) {
4411 rxaggcfg.threshold.drv_define = 1;
4412 rxaggcfg.threshold.timeout = hal->rxagg_dma_timeout;
4413 rxaggcfg.threshold.size = hal->rxagg_dma_size;
4414 RTW_INFO("%s: RX aggregation threshold: "
4415 "timeout=%u size=%u\n",
4417 hal->rxagg_dma_timeout,
4418 hal->rxagg_dma_size);
4420 #elif defined(CONFIG_USB_HCI)
4421 switch (hal->rxagg_mode) {
4422 case RX_AGG_DISABLE:
4423 rxaggcfg.mode = HALMAC_RX_AGG_MODE_NONE;
4427 rxaggcfg.mode = HALMAC_RX_AGG_MODE_DMA;
4428 if (hal->rxagg_dma_size || hal->rxagg_dma_timeout) {
4429 rxaggcfg.threshold.drv_define = 1;
4430 rxaggcfg.threshold.timeout = hal->rxagg_dma_timeout;
4431 rxaggcfg.threshold.size = hal->rxagg_dma_size;
4437 rxaggcfg.mode = HALMAC_RX_AGG_MODE_USB;
4438 if (hal->rxagg_usb_size || hal->rxagg_usb_timeout) {
4439 rxaggcfg.threshold.drv_define = 1;
4440 rxaggcfg.threshold.timeout = hal->rxagg_usb_timeout;
4441 rxaggcfg.threshold.size = hal->rxagg_usb_size;
4445 #endif /* CONFIG_USB_HCI */
4447 #endif /* RTW_RX_AGGREGATION */
4449 status = api->halmac_cfg_rx_aggregation(halmac, &rxaggcfg);
4450 if (status != HALMAC_RET_SUCCESS)
4456 int rtw_halmac_download_rsvd_page(struct dvobj_priv *dvobj, u8 pg_offset, u8 *pbuf, u32 size)
4458 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4459 struct halmac_adapter *halmac = dvobj_to_halmac(dvobj);
4460 struct halmac_api *api = HALMAC_GET_API(halmac);
4462 status = api->halmac_dl_drv_rsvd_page(halmac, pg_offset, pbuf, size);
4463 if (status != HALMAC_RET_SUCCESS)
4471 * Fill following spec info from HALMAC API:
4478 int rtw_halmac_fill_hal_spec(struct dvobj_priv *dvobj, struct hal_spec_t *spec)
4480 enum halmac_ret_status status;
4481 struct halmac_adapter *halmac;
4482 struct halmac_api *api;
4483 u8 cam = 0; /* Security Cam Entry Number */
4486 halmac = dvobj_to_halmac(dvobj);
4487 api = HALMAC_GET_API(halmac);
4489 /* Prepare data from HALMAC */
4490 status = api->halmac_get_hw_value(halmac, HALMAC_HW_CAM_ENTRY_NUM, &cam);
4491 if (status != HALMAC_RET_SUCCESS)
4494 /* Fill data to hal_spec_t */
4495 spec->sec_cam_ent_num = cam;
4500 int rtw_halmac_p2pps(struct dvobj_priv *dvobj, struct hal_p2p_ps_para *pp2p_ps_para)
4502 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4503 struct halmac_adapter *halmac = dvobj_to_halmac(dvobj);
4504 struct halmac_api *api = HALMAC_GET_API(halmac);
4505 struct halmac_p2pps halmac_p2p_ps;
4507 (&halmac_p2p_ps)->offload_en = pp2p_ps_para->offload_en;
4508 (&halmac_p2p_ps)->role = pp2p_ps_para->role;
4509 (&halmac_p2p_ps)->ctwindow_en = pp2p_ps_para->ctwindow_en;
4510 (&halmac_p2p_ps)->noa_en = pp2p_ps_para->noa_en;
4511 (&halmac_p2p_ps)->noa_sel = pp2p_ps_para->noa_sel;
4512 (&halmac_p2p_ps)->all_sta_sleep = pp2p_ps_para->all_sta_sleep;
4513 (&halmac_p2p_ps)->discovery = pp2p_ps_para->discovery;
4514 (&halmac_p2p_ps)->p2p_port_id = _hw_port_drv2halmac(pp2p_ps_para->p2p_port_id);
4515 (&halmac_p2p_ps)->p2p_group = pp2p_ps_para->p2p_group;
4516 (&halmac_p2p_ps)->p2p_macid = pp2p_ps_para->p2p_macid;
4517 (&halmac_p2p_ps)->ctwindow_length = pp2p_ps_para->ctwindow_length;
4518 (&halmac_p2p_ps)->noa_duration_para = pp2p_ps_para->noa_duration_para;
4519 (&halmac_p2p_ps)->noa_interval_para = pp2p_ps_para->noa_interval_para;
4520 (&halmac_p2p_ps)->noa_start_time_para = pp2p_ps_para->noa_start_time_para;
4521 (&halmac_p2p_ps)->noa_count_para = pp2p_ps_para->noa_count_para;
4523 status = api->halmac_p2pps(halmac, (&halmac_p2p_ps));
4524 if (status != HALMAC_RET_SUCCESS)
4532 * rtw_halmac_iqk() - Run IQ Calibration
4533 * @d: struct dvobj_priv*
4534 * @clear: IQK parameters
4535 * @segment: IQK parameters
4537 * Process IQ Calibration(IQK).
4539 * Rteurn: 0 for OK, otherwise fail.
4541 int rtw_halmac_iqk(struct dvobj_priv *d, u8 clear, u8 segment)
4543 struct halmac_adapter *mac;
4544 struct halmac_api *api;
4545 enum halmac_ret_status status;
4546 enum halmac_feature_id id;
4547 struct halmac_iqk_para para;
4550 u8 delay = 1; /* ms */
4553 mac = dvobj_to_halmac(d);
4554 api = HALMAC_GET_API(mac);
4555 id = HALMAC_FEATURE_IQK;
4557 ret = init_halmac_event(d, id, NULL, 0);
4562 para.segment_iqk = segment;
4565 status = api->halmac_start_iqk(mac, ¶);
4566 if (status != HALMAC_RET_BUSY_STATE)
4568 RTW_WARN("%s: Fail to start IQK, status is BUSY! retry=%d\n", __FUNCTION__, retry);
4572 rtw_msleep_os(delay);
4574 if (status != HALMAC_RET_SUCCESS) {
4575 free_halmac_event(d, id);
4579 ret = wait_halmac_event(d, id);
4586 static inline u32 _phy_parameter_val_drv2halmac(u32 val, u8 msk_en, u32 msk)
4591 return (val << bitshift(msk));
4594 static int _phy_parameter_drv2halmac(struct rtw_phy_parameter *para, struct halmac_phy_parameter_info *info)
4599 _rtw_memset(info, 0, sizeof(*info));
4601 switch (para->cmd) {
4604 switch (para->data.mac.size) {
4606 info->cmd_id = HALMAC_PARAMETER_CMD_MAC_W8;
4609 info->cmd_id = HALMAC_PARAMETER_CMD_MAC_W16;
4612 info->cmd_id = HALMAC_PARAMETER_CMD_MAC_W32;
4615 info->content.MAC_REG_W.value = _phy_parameter_val_drv2halmac(
4616 para->data.mac.value,
4617 para->data.mac.msk_en,
4618 para->data.mac.msk);
4619 info->content.MAC_REG_W.msk = para->data.mac.msk;
4620 info->content.MAC_REG_W.offset = para->data.mac.offset;
4621 info->content.MAC_REG_W.msk_en = para->data.mac.msk_en;
4626 switch (para->data.bb.size) {
4628 info->cmd_id = HALMAC_PARAMETER_CMD_BB_W8;
4631 info->cmd_id = HALMAC_PARAMETER_CMD_BB_W16;
4634 info->cmd_id = HALMAC_PARAMETER_CMD_BB_W32;
4637 info->content.BB_REG_W.value = _phy_parameter_val_drv2halmac(
4638 para->data.bb.value,
4639 para->data.bb.msk_en,
4641 info->content.BB_REG_W.msk = para->data.bb.msk;
4642 info->content.BB_REG_W.offset = para->data.bb.offset;
4643 info->content.BB_REG_W.msk_en = para->data.bb.msk_en;
4648 info->cmd_id = HALMAC_PARAMETER_CMD_RF_W;
4649 info->content.RF_REG_W.value = _phy_parameter_val_drv2halmac(
4650 para->data.rf.value,
4651 para->data.rf.msk_en,
4653 info->content.RF_REG_W.msk = para->data.rf.msk;
4654 info->content.RF_REG_W.offset = para->data.rf.offset;
4655 info->content.RF_REG_W.msk_en = para->data.rf.msk_en;
4656 info->content.RF_REG_W.rf_path = para->data.rf.path;
4660 /* Delay register */
4661 if (para->data.delay.unit == 0)
4662 info->cmd_id = HALMAC_PARAMETER_CMD_DELAY_US;
4664 info->cmd_id = HALMAC_PARAMETER_CMD_DELAY_MS;
4665 info->content.DELAY_TIME.delay_time = para->data.delay.value;
4669 /* Latest(End) command */
4670 info->cmd_id = HALMAC_PARAMETER_CMD_END;
4681 * rtw_halmac_cfg_phy_para() - Register(Phy parameter) configuration
4682 * @d: struct dvobj_priv*
4683 * @para: phy parameter
4685 * Configure registers by firmware using H2C/C2H mechanism.
4686 * The latest command should be para->cmd==0xFF(End command) to finish all
4689 * Return: 0 for OK, otherwise fail.
4691 int rtw_halmac_cfg_phy_para(struct dvobj_priv *d, struct rtw_phy_parameter *para)
4693 struct halmac_adapter *mac;
4694 struct halmac_api *api;
4695 enum halmac_ret_status status;
4696 enum halmac_feature_id id;
4697 struct halmac_phy_parameter_info info;
4702 mac = dvobj_to_halmac(d);
4703 api = HALMAC_GET_API(mac);
4704 id = HALMAC_FEATURE_CFG_PARA;
4705 full_fifo = 1; /* ToDo: How to deciede? */
4708 err = _phy_parameter_drv2halmac(para, &info);
4712 err = init_halmac_event(d, id, NULL, 0);
4716 status = api->halmac_cfg_parameter(mac, &info, full_fifo);
4717 if (info.cmd_id == HALMAC_PARAMETER_CMD_END) {
4718 if (status == HALMAC_RET_SUCCESS) {
4719 err = wait_halmac_event(d, id);
4723 free_halmac_event(d, id);
4725 RTW_ERR("%s: Fail to send END of cfg parameter, status is 0x%x!\n", __FUNCTION__, status);
4728 if (status == HALMAC_RET_PARA_SENDING) {
4729 err = wait_halmac_event(d, id);
4733 free_halmac_event(d, id);
4734 if (status != HALMAC_RET_SUCCESS) {
4736 RTW_ERR("%s: Fail to cfg parameter, status is 0x%x!\n", __FUNCTION__, status);
4744 static enum halmac_wlled_mode _led_mode_drv2halmac(u8 drv_mode)
4746 enum halmac_wlled_mode halmac_mode;
4751 halmac_mode = HALMAC_WLLED_MODE_TX;
4754 halmac_mode = HALMAC_WLLED_MODE_RX;
4757 halmac_mode = HALMAC_WLLED_MODE_SW_CTRL;
4761 halmac_mode = HALMAC_WLLED_MODE_TRX;
4769 * rtw_halmac_led_cfg() - Configure Hardware LED Mode
4770 * @d: struct dvobj_priv*
4771 * @enable: enable or disable LED function
4774 * @mode: WLan LED mode (valid when enable==1)
4775 * 0: Blink when TX(transmit packet) and RX(receive packet)
4776 * 1: Blink when TX only
4777 * 2: Blink when RX only
4778 * 3: Software control
4780 * Configure hardware WLan LED mode.
4781 * If want to change LED mode after enabled, need to disable LED first and
4782 * enable again to set new mode.
4784 * Rteurn 0 for OK, otherwise fail.
4786 int rtw_halmac_led_cfg(struct dvobj_priv *d, u8 enable, u8 mode)
4788 struct halmac_adapter *halmac;
4789 struct halmac_api *api;
4790 enum halmac_wlled_mode led_mode;
4791 enum halmac_ret_status status;
4794 halmac = dvobj_to_halmac(d);
4795 api = HALMAC_GET_API(halmac);
4798 status = api->halmac_pinmux_set_func(halmac,
4799 HALMAC_GPIO_FUNC_WL_LED);
4800 if (status != HALMAC_RET_SUCCESS) {
4801 RTW_ERR("%s: pinmux set fail!(0x%x)\n",
4802 __FUNCTION__, status);
4806 led_mode = _led_mode_drv2halmac(mode);
4807 status = api->halmac_pinmux_wl_led_mode(halmac, led_mode);
4808 if (status != HALMAC_RET_SUCCESS) {
4809 RTW_ERR("%s: mode set fail!(0x%x)\n",
4810 __FUNCTION__, status);
4814 /* Change LED to software control and turn off */
4815 api->halmac_pinmux_wl_led_mode(halmac,
4816 HALMAC_WLLED_MODE_SW_CTRL);
4817 api->halmac_pinmux_wl_led_sw_ctrl(halmac, 0);
4819 status = api->halmac_pinmux_free_func(halmac,
4820 HALMAC_GPIO_FUNC_WL_LED);
4821 if (status != HALMAC_RET_SUCCESS) {
4822 RTW_ERR("%s: pinmux free fail!(0x%x)\n",
4823 __FUNCTION__, status);
4832 * rtw_halmac_led_switch() - Turn Hardware LED on/off
4833 * @d: struct dvobj_priv*
4834 * @on: LED light or not
4838 * Turn Hardware WLan LED On/Off.
4839 * Before use this function, user should call rtw_halmac_led_ctrl() to switch
4840 * mode to "software control(3)" first, otherwise control would fail.
4841 * The interval between on and off must be longer than 1 ms, or the LED would
4842 * keep light or dark only.
4843 * Ex. Turn off LED at first, turn on after 0.5ms and turn off again after
4844 * 0.5ms. The LED during this flow will only keep dark, and miss the turn on
4845 * operation between two turn off operations.
4847 void rtw_halmac_led_switch(struct dvobj_priv *d, u8 on)
4849 struct halmac_adapter *halmac;
4850 struct halmac_api *api;
4853 halmac = dvobj_to_halmac(d);
4854 api = HALMAC_GET_API(halmac);
4856 api->halmac_pinmux_wl_led_sw_ctrl(halmac, on);
4859 #ifdef CONFIG_SDIO_HCI
4863 * Update queue allocated page number to driver
4866 * d pointer to struct dvobj_priv of driver
4869 * 0 Success, "page" is valid.
4870 * others Fail, "page" is invalid.
4872 int rtw_halmac_query_tx_page_num(struct dvobj_priv *d)
4875 struct halmacpriv *hmpriv;
4876 struct halmac_adapter *halmac;
4877 struct halmac_api *api;
4878 struct halmac_rqpn_map rqpn;
4879 enum halmac_dma_mapping dmaqueue;
4880 struct halmac_txff_allocation fifosize;
4881 enum halmac_ret_status status;
4885 adapter = dvobj_get_primary_adapter(d);
4886 hmpriv = &d->hmpriv;
4887 halmac = dvobj_to_halmac(d);
4888 api = HALMAC_GET_API(halmac);
4889 _rtw_memset((void *)&rqpn, 0, sizeof(rqpn));
4890 _rtw_memset((void *)&fifosize, 0, sizeof(fifosize));
4892 status = api->halmac_get_hw_value(halmac, HALMAC_HW_RQPN_MAPPING, &rqpn);
4893 if (status != HALMAC_RET_SUCCESS)
4895 status = api->halmac_get_hw_value(halmac, HALMAC_HW_TXFF_ALLOCATION, &fifosize);
4896 if (status != HALMAC_RET_SUCCESS)
4899 for (i = 0; i < HW_QUEUE_ENTRY; i++) {
4900 hmpriv->txpage[i] = 0;
4902 /* Driver index mapping to HALMAC DMA queue */
4903 dmaqueue = HALMAC_DMA_MAPPING_UNDEFINE;
4906 dmaqueue = rqpn.dma_map_vo;
4909 dmaqueue = rqpn.dma_map_vi;
4912 dmaqueue = rqpn.dma_map_be;
4915 dmaqueue = rqpn.dma_map_bk;
4918 dmaqueue = rqpn.dma_map_mg;
4920 case HIGH_QUEUE_INX:
4921 dmaqueue = rqpn.dma_map_hi;
4924 case TXCMD_QUEUE_INX:
4926 hmpriv->txpage[i] = 0xFFFF;
4931 case HALMAC_DMA_MAPPING_EXTRA:
4932 hmpriv->txpage[i] = fifosize.extra_queue_pg_num;
4934 case HALMAC_DMA_MAPPING_LOW:
4935 hmpriv->txpage[i] = fifosize.low_queue_pg_num;
4937 case HALMAC_DMA_MAPPING_NORMAL:
4938 hmpriv->txpage[i] = fifosize.normal_queue_pg_num;
4940 case HALMAC_DMA_MAPPING_HIGH:
4941 hmpriv->txpage[i] = fifosize.high_queue_pg_num;
4943 case HALMAC_DMA_MAPPING_UNDEFINE:
4946 hmpriv->txpage[i] += fifosize.pub_queue_pg_num;
4954 * Get specific queue allocated page number
4957 * d pointer to struct dvobj_priv of driver
4958 * queue target queue to query, VO/VI/BE/BK/.../TXCMD_QUEUE_INX
4959 * page return allocated page number
4962 * 0 Success, "page" is valid.
4963 * others Fail, "page" is invalid.
4965 int rtw_halmac_get_tx_queue_page_num(struct dvobj_priv *d, u8 queue, u32 *page)
4968 if (queue < HW_QUEUE_ENTRY)
4969 *page = d->hmpriv.txpage[queue];
4976 * address for SDIO command
4978 u32 rtw_halmac_sdio_get_tx_addr(struct dvobj_priv *d, u8 *desc, u32 size)
4980 struct halmac_adapter *mac;
4981 struct halmac_api *api;
4982 enum halmac_ret_status status;
4986 mac = dvobj_to_halmac(d);
4987 api = HALMAC_GET_API(mac);
4989 status = api->halmac_get_sdio_tx_addr(mac, desc, size, &addr);
4990 if (HALMAC_RET_SUCCESS != status)
4996 int rtw_halmac_sdio_tx_allowed(struct dvobj_priv *d, u8 *buf, u32 size)
4998 struct halmac_adapter *mac;
4999 struct halmac_api *api;
5000 enum halmac_ret_status status;
5003 mac = dvobj_to_halmac(d);
5004 api = HALMAC_GET_API(mac);
5006 status = api->halmac_tx_allowed_sdio(mac, buf, size);
5007 if (HALMAC_RET_SUCCESS != status)
5013 u32 rtw_halmac_sdio_get_rx_addr(struct dvobj_priv *d, u8 *seq)
5017 #define RTW_SDIO_ADDR_RX_RX0FF_PRFIX 0x0E000
5018 #define RTW_SDIO_ADDR_RX_RX0FF_GEN(a) (RTW_SDIO_ADDR_RX_RX0FF_PRFIX|(a&0x3))
5022 return RTW_SDIO_ADDR_RX_RX0FF_GEN(id);
5024 #endif /* CONFIG_SDIO_HCI */
5026 #ifdef CONFIG_USB_HCI
5027 u8 rtw_halmac_usb_get_bulkout_id(struct dvobj_priv *d, u8 *buf, u32 size)
5029 struct halmac_adapter *mac;
5030 struct halmac_api *api;
5031 enum halmac_ret_status status;
5035 mac = dvobj_to_halmac(d);
5036 api = HALMAC_GET_API(mac);
5038 status = api->halmac_get_usb_bulkout_id(mac, buf, size, &bulkout_id);
5039 if (HALMAC_RET_SUCCESS != status)
5046 * rtw_halmac_usb_get_txagg_desc_num() - MAX descriptor number in one bulk for TX
5047 * @d: struct dvobj_priv*
5048 * @size: TX FIFO size, unit is byte.
5050 * Get MAX descriptor number in one bulk out from HALMAC.
5052 * Rteurn 0 for OK, otherwise fail.
5054 int rtw_halmac_usb_get_txagg_desc_num(struct dvobj_priv *d, u8 *num)
5056 struct halmac_adapter *halmac;
5057 struct halmac_api *api;
5058 enum halmac_ret_status status;
5062 halmac = dvobj_to_halmac(d);
5063 api = HALMAC_GET_API(halmac);
5065 status = api->halmac_get_hw_value(halmac, HALMAC_HW_USB_TXAGG_DESC_NUM, &val);
5066 if (status != HALMAC_RET_SUCCESS)
5074 static inline enum halmac_usb_mode _usb_mode_drv2halmac(enum RTW_USB_SPEED usb_mode)
5076 enum halmac_usb_mode halmac_usb_mode = HALMAC_USB_MODE_U2;
5079 case RTW_USB_SPEED_2:
5080 halmac_usb_mode = HALMAC_USB_MODE_U2;
5082 case RTW_USB_SPEED_3:
5083 halmac_usb_mode = HALMAC_USB_MODE_U3;
5086 halmac_usb_mode = HALMAC_USB_MODE_U2;
5090 return halmac_usb_mode;
5093 u8 rtw_halmac_switch_usb_mode(struct dvobj_priv *d, enum RTW_USB_SPEED usb_mode)
5096 struct halmac_adapter *mac;
5097 struct halmac_api *api;
5098 enum halmac_ret_status status;
5099 enum halmac_usb_mode halmac_usb_mode;
5101 adapter = dvobj_get_primary_adapter(d);
5102 mac = dvobj_to_halmac(d);
5103 api = HALMAC_GET_API(mac);
5104 halmac_usb_mode = _usb_mode_drv2halmac(usb_mode);
5105 status = api->halmac_set_hw_value(mac, HALMAC_HW_USB_MODE, (void *)&halmac_usb_mode);
5107 if (HALMAC_RET_SUCCESS != status)
5112 #endif /* CONFIG_USB_HCI */
5114 #ifdef CONFIG_BEAMFORMING
5115 #ifdef RTW_BEAMFORMING_VERSION_2
5116 int rtw_halmac_bf_add_mu_bfer(struct dvobj_priv *d, u16 paid, u16 csi_para,
5117 u16 my_aid, enum halmac_csi_seg_len sel, u8 *addr)
5119 struct halmac_adapter *mac;
5120 struct halmac_api *api;
5121 enum halmac_ret_status status;
5122 struct halmac_mu_bfer_init_para param;
5125 mac = dvobj_to_halmac(d);
5126 api = HALMAC_GET_API(mac);
5128 _rtw_memset(¶m, 0, sizeof(param));
5130 param.csi_para = csi_para;
5131 param.my_aid = my_aid;
5132 param.csi_length_sel = sel;
5133 _rtw_memcpy(param.bfer_address.addr, addr, 6);
5135 status = api->halmac_mu_bfer_entry_init(mac, ¶m);
5136 if (status != HALMAC_RET_SUCCESS)
5142 int rtw_halmac_bf_del_mu_bfer(struct dvobj_priv *d)
5144 struct halmac_adapter *mac;
5145 struct halmac_api *api;
5146 enum halmac_ret_status status;
5149 mac = dvobj_to_halmac(d);
5150 api = HALMAC_GET_API(mac);
5152 status = api->halmac_mu_bfer_entry_del(mac);
5153 if (status != HALMAC_RET_SUCCESS)
5160 int rtw_halmac_bf_cfg_sounding(struct dvobj_priv *d,
5161 enum halmac_snd_role role, enum halmac_data_rate rate)
5163 struct halmac_adapter *mac;
5164 struct halmac_api *api;
5165 enum halmac_ret_status status;
5168 mac = dvobj_to_halmac(d);
5169 api = HALMAC_GET_API(mac);
5171 status = api->halmac_cfg_sounding(mac, role, rate);
5172 if (status != HALMAC_RET_SUCCESS)
5178 int rtw_halmac_bf_del_sounding(struct dvobj_priv *d,
5179 enum halmac_snd_role role)
5181 struct halmac_adapter *mac;
5182 struct halmac_api *api;
5183 enum halmac_ret_status status;
5186 mac = dvobj_to_halmac(d);
5187 api = HALMAC_GET_API(mac);
5189 status = api->halmac_del_sounding(mac, role);
5190 if (status != HALMAC_RET_SUCCESS)
5196 int rtw_halmac_bf_cfg_csi_rate(struct dvobj_priv *d,
5197 u8 rssi, u8 current_rate, u8 fixrate_en,
5200 struct halmac_adapter *mac;
5201 struct halmac_api *api;
5202 enum halmac_ret_status status;
5205 mac = dvobj_to_halmac(d);
5206 api = HALMAC_GET_API(mac);
5208 status = api->halmac_cfg_csi_rate(mac,
5209 rssi, current_rate, fixrate_en, new_rate);
5210 if (status != HALMAC_RET_SUCCESS)
5216 int rtw_halmac_bf_cfg_mu_mimo(struct dvobj_priv *d, enum halmac_snd_role role,
5217 u8 *sounding_sts, u16 grouping_bitmap, u8 mu_tx_en,
5218 u32 *given_gid_tab, u32 *given_user_pos)
5220 struct halmac_adapter *mac;
5221 struct halmac_api *api;
5222 enum halmac_ret_status status;
5223 struct halmac_cfg_mumimo_para param;
5226 mac = dvobj_to_halmac(d);
5227 api = HALMAC_GET_API(mac);
5229 _rtw_memset(¶m, 0, sizeof(param));
5232 param.grouping_bitmap = grouping_bitmap;
5233 param.mu_tx_en = mu_tx_en;
5236 _rtw_memcpy(param.sounding_sts, sounding_sts, 6);
5239 _rtw_memcpy(param.given_gid_tab, given_gid_tab, 8);
5242 _rtw_memcpy(param.given_user_pos, given_user_pos, 16);
5244 status = api->halmac_cfg_mumimo(mac, ¶m);
5245 if (status != HALMAC_RET_SUCCESS)
5251 #endif /* RTW_BEAMFORMING_VERSION_2 */
5252 #endif /* CONFIG_BEAMFORMING */