/******************************************************************************
|
*
|
* Copyright(c) 2016 - 2019 Realtek Corporation.
|
*
|
* This program is free software; you can redistribute it and/or modify it
|
* under the terms of version 2 of the GNU General Public License as
|
* published by the Free Software Foundation.
|
*
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
* more details.
|
*
|
*****************************************************************************/
|
#define _RTL8852BU_HALINIT_C_
|
#include "../../hal_headers.h"
|
#include "../rtl8852b_hal.h"
|
|
static void _hal_pre_init_8852bu(struct rtw_phl_com_t *phl_com,
|
struct hal_info_t *hal_info,
|
struct hal_init_info_t *init_52bu)
|
{
|
struct mac_ax_trx_info *trx_info = &init_52bu->trx_info;
|
struct mac_ax_host_rpr_cfg *rpr_cfg = (struct mac_ax_host_rpr_cfg *)hal_info->rpr_cfg;
|
|
if (true == phl_com->dev_cap.tx_mu_ru)
|
trx_info->trx_mode = MAC_AX_TRX_SW_MODE;
|
else
|
trx_info->trx_mode = MAC_AX_TRX_HW_MODE;
|
|
if (hal_info->hal_com->dbcc_en == false)
|
trx_info->qta_mode = MAC_AX_QTA_SCC;
|
else
|
trx_info->qta_mode = MAC_AX_QTA_DBCC;
|
|
#ifdef RTW_WKARD_LAMODE
|
PHL_INFO("%s : la_mode %d\n", __func__, phl_com->dev_cap.la_mode);
|
if (phl_com->dev_cap.la_mode)
|
trx_info->qta_mode = MAC_AX_QTA_LAMODE;
|
#endif
|
|
if (phl_com->dev_cap.rpq_agg_num) {
|
rpr_cfg->agg_def = 0;
|
rpr_cfg->agg = phl_com->dev_cap.rpq_agg_num;
|
} else {
|
rpr_cfg->agg_def = 1;
|
}
|
|
rpr_cfg->tmr_def = 1;
|
#ifdef CONFIG_PHL_USB_RELEASE_RPT_ENABLE
|
rpr_cfg->txok_en = MAC_AX_FUNC_EN;
|
rpr_cfg->rty_lmt_en = MAC_AX_FUNC_EN;
|
rpr_cfg->lft_drop_en = MAC_AX_FUNC_EN;
|
rpr_cfg->macid_drop_en = MAC_AX_FUNC_EN;
|
#else
|
rpr_cfg->txok_en = MAC_AX_FUNC_DEF;
|
rpr_cfg->rty_lmt_en = MAC_AX_FUNC_DEF;
|
rpr_cfg->lft_drop_en = MAC_AX_FUNC_DEF;
|
rpr_cfg->macid_drop_en = MAC_AX_FUNC_DEF;
|
#endif /* CONFIG_PHL_USB_RELEASE_RPT_ENABLE */
|
trx_info->rpr_cfg = rpr_cfg;
|
|
init_52bu->ic_name = "rtl8852bu";
|
}
|
|
void init_hal_spec_8852bu(struct rtw_phl_com_t *phl_com,
|
struct hal_info_t *hal)
|
{
|
struct rtw_hal_com_t *hal_com = hal->hal_com;
|
struct bus_hw_cap_t *bus_hw_cap = &hal_com->bus_hw_cap;
|
|
init_hal_spec_8852b(phl_com, hal);
|
phl_com->dev_cap.hw_sup_flags |= HW_SUP_USB_MULTI_FUN;
|
bus_hw_cap->tx_buf_size = 20480;
|
bus_hw_cap->tx_buf_num = 4;
|
bus_hw_cap->tx_mgnt_buf_size = 1536;
|
bus_hw_cap->tx_mgnt_buf_num = 32;
|
bus_hw_cap->tx_h2c_buf_num = MAX_H2C_PKT_NUM;
|
bus_hw_cap->rx_buf_size = 512*60;
|
bus_hw_cap->rx_buf_num = 128;
|
bus_hw_cap->in_token_num = 6;
|
|
hal->hal_com->dev_hw_cap.ps_cap.lps_pause_tx = true;
|
}
|
|
enum rtw_hal_status hal_get_efuse_8852bu(struct rtw_phl_com_t *phl_com,
|
struct hal_info_t *hal_info)
|
{
|
struct hal_init_info_t init_52bu;
|
|
_os_mem_set(hal_to_drvpriv(hal_info), &init_52bu, 0, sizeof(init_52bu));
|
_hal_pre_init_8852bu(phl_com, hal_info, &init_52bu);
|
|
return hal_get_efuse_8852b(phl_com, hal_info, &init_52bu);
|
}
|
|
enum rtw_hal_status hal_init_8852bu(struct rtw_phl_com_t *phl_com,
|
struct hal_info_t *hal_info)
|
{
|
enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
|
|
/* allocate memory for hal */
|
hal_info->rpr_cfg = _os_mem_alloc(phlcom_to_drvpriv(phl_com),
|
sizeof(struct mac_ax_host_rpr_cfg));
|
if (hal_info->rpr_cfg == NULL) {
|
hal_status = RTW_HAL_STATUS_RESOURCE;
|
PHL_ERR("%s: alloc rpr_cfg failed\n", __func__);
|
goto error_rpr_cfg;
|
}
|
|
hal_status = RTW_HAL_STATUS_SUCCESS;
|
|
error_rpr_cfg:
|
return hal_status;
|
}
|
|
void hal_deinit_8852bu(struct rtw_phl_com_t *phl_com,
|
struct hal_info_t *hal_info)
|
{
|
/* free memory for hal */
|
_os_mem_free(phlcom_to_drvpriv(phl_com),
|
hal_info->rpr_cfg,
|
sizeof(struct mac_ax_host_rpr_cfg));
|
}
|
|
enum rtw_hal_status hal_start_8852bu(struct rtw_phl_com_t *phl_com,
|
struct hal_info_t *hal_info)
|
{
|
struct hal_init_info_t init_52bu;
|
|
_os_mem_set(hal_to_drvpriv(hal_info), &init_52bu, 0, sizeof(init_52bu));
|
_hal_pre_init_8852bu(phl_com, hal_info, &init_52bu);
|
|
return hal_start_8852b(phl_com, hal_info, &init_52bu);
|
}
|
|
static void hal_deinit_misc_8852bu(struct hal_info_t *hal)
|
{
|
|
}
|
#ifdef CONFIG_WOWLAN
|
enum rtw_hal_status
|
hal_wow_init_8852bu(struct rtw_phl_com_t *phl_com, struct hal_info_t *hal_info,
|
struct rtw_phl_stainfo_t *sta)
|
{
|
struct hal_init_info_t init_52bu;
|
struct mac_ax_trx_info *trx_info = &init_52bu.trx_info;
|
|
_os_mem_set( hal_to_drvpriv(hal_info), &init_52bu, 0, sizeof(init_52bu));
|
if (true == phl_com->dev_cap.tx_mu_ru)
|
trx_info->trx_mode = MAC_AX_TRX_SW_MODE;
|
else
|
trx_info->trx_mode = MAC_AX_TRX_HW_MODE;
|
trx_info->qta_mode = MAC_AX_QTA_SCC;
|
|
init_52bu.ic_name = "rtl8852bu";
|
|
return hal_wow_init_8852b(phl_com, hal_info, sta, &init_52bu);
|
}
|
|
enum rtw_hal_status
|
hal_wow_deinit_8852bu(struct rtw_phl_com_t *phl_com, struct hal_info_t *hal_info,
|
struct rtw_phl_stainfo_t *sta)
|
{
|
struct hal_init_info_t init_52bu;
|
struct mac_ax_trx_info *trx_info = &init_52bu.trx_info;
|
|
_os_mem_set( hal_to_drvpriv(hal_info), &init_52bu, 0, sizeof(init_52bu));
|
if (true == phl_com->dev_cap.tx_mu_ru)
|
trx_info->trx_mode = MAC_AX_TRX_SW_MODE;
|
else
|
trx_info->trx_mode = MAC_AX_TRX_HW_MODE;
|
trx_info->qta_mode = MAC_AX_QTA_SCC;
|
|
init_52bu.ic_name = "rtl8852bu";
|
|
return hal_wow_deinit_8852b(phl_com, hal_info, sta, &init_52bu);
|
}
|
#endif /* CONFIG_WOWLAN */
|
|
|
enum rtw_hal_status hal_stop_8852bu(struct rtw_phl_com_t *phl_com,
|
struct hal_info_t *hal)
|
{
|
enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
|
|
hal_status = hal_stop_8852b(phl_com, hal);
|
return hal_status;
|
}
|
|
static const char *const _usb_sp[] = {
|
"USB_SPEED_LOW",
|
"USB_SPEED_FULL",
|
"USB_SPEED_HIGH",
|
"USB_SPEED_SUPER",
|
"USB_SPEED_SUPER_10G",
|
"USB_SPEED_SUPER_20G",
|
"USB_SPEED_UNKNOWN"
|
};
|
#define usb_speed_str(_spidx) (((_spidx) >= RTW_USB_SPEED_UNKNOWN)\
|
? _usb_sp[RTW_USB_SPEED_UNKNOWN] : _usb_sp[(_spidx)])
|
|
u32 hal_hci_cfg_8852bu(struct rtw_phl_com_t *phl_com,
|
struct hal_info_t *hal, struct rtw_ic_info *ic_info)
|
{
|
struct hal_spec_t *hal_spec = phl_get_ic_spec(phl_com);
|
|
/*get USB Bus-info from os*/
|
PHL_INFO("%s ===>\n", __func__);
|
PHL_INFO("%s\n", usb_speed_str(ic_info->usb_info.usb_speed));
|
PHL_INFO("Bulk-Out size - %d\n", ic_info->usb_info.usb_bulkout_size);
|
PHL_INFO("Bulk-Out Number - %d\n", ic_info->usb_info.outep_num);
|
PHL_INFO("Bulk-In Number - %d\n", ic_info->usb_info.inep_num);
|
|
hal_spec->max_bulkin_num = ic_info->usb_info.inep_num;
|
hal_spec->max_bulkout_num = ic_info->usb_info.outep_num;
|
hal_spec->cts2_thres_en = false;
|
hal_spec->cts2_thres = 0;
|
|
return RTW_HAL_STATUS_SUCCESS;
|
}
|
|
|
bool hal_recognize_int_8852bu(struct hal_info_t *hal)
|
{
|
struct rtw_hal_com_t *hal_com = hal->hal_com;
|
bool recognized = false;
|
u32 usb_isr = 0;
|
|
usb_isr = hal_read32(hal_com, R_AX_HUSBISR);
|
|
if (usb_isr & B_AX_HS0ISR_IND_INT) { /*B_AX_HS0ISR_IND_INT*/
|
/* halt c2h */
|
hal_com->intr.halt_c2h_int.intr = hal_read32(hal_com, R_AX_HISR0);
|
hal_com->intr.halt_c2h_int.intr &= hal_com->intr.halt_c2h_int.val_mask;
|
hal_write32(hal_com,R_AX_HISR0, hal_com->intr.halt_c2h_int.intr);
|
} else {
|
hal_com->intr.halt_c2h_int.intr = 0;
|
}
|
|
if (usb_isr & B_AX_HD0ISR_IND_INT) { /*B_AX_HD0ISR_IND_INT*/
|
/* watchdog timer */
|
hal_com->intr.watchdog_timer_int.intr = hal_read32(hal_com, R_AX_HD0ISR);
|
hal_com->intr.watchdog_timer_int.intr &= hal_com->intr.watchdog_timer_int.val_mask;
|
hal_write32(hal_com,R_AX_HD0ISR, hal_com->intr.watchdog_timer_int.intr);
|
} else {
|
hal_com->intr.watchdog_timer_int.intr = 0;
|
}
|
|
if (hal_com->intr.halt_c2h_int.intr || hal_com->intr.watchdog_timer_int.intr)
|
recognized = true;
|
|
return recognized;
|
}
|
|
static u32 hal_halt_c2h_handler_8852bu(struct hal_info_t *hal, u32 *handled)
|
{
|
u32 ret = 0;
|
struct rtw_hal_com_t *hal_com = hal->hal_com;
|
|
if (hal_com->intr.halt_c2h_int.intr & B_AX_HALT_C2H_INT_EN) {
|
handled[0] |= B_AX_HALT_C2H_INT_EN;
|
ret = 1;
|
}
|
|
return ret;
|
}
|
|
static u32 hal_watchdog_timer_handler_8852bu(struct hal_info_t *hal, u32 *handled)
|
{
|
u32 ret = 0;
|
struct rtw_hal_com_t *hal_com = hal->hal_com;
|
|
if (hal_com->intr.watchdog_timer_int.intr & B_AX_WDT_PTFM_INT_EN) {
|
handled[1] |= B_AX_WDT_PTFM_INT_EN;
|
ret = 1;
|
}
|
|
return ret;
|
}
|
|
u32 hal_int_hdler_8852bu(struct hal_info_t *hal)
|
{
|
u32 int_hdler_msk = 0x0;
|
u32 generalhandled[8] = {0};
|
|
/* Start General interrupt type */
|
/* <4> Halt C2H related */
|
int_hdler_msk |= (hal_halt_c2h_handler_8852bu(hal, generalhandled) << 4);
|
|
/* <4>watchdog timer related */
|
int_hdler_msk |= (hal_watchdog_timer_handler_8852bu(hal, generalhandled) << 5);
|
|
PHL_TRACE(COMP_PHL_DBG,_PHL_INFO_, "%s: int_hdler_msk = 0x%x\n", __func__, int_hdler_msk);
|
|
return int_hdler_msk;
|
}
|
|
enum rtw_hal_status
|
hal_mp_init_8852bu(struct rtw_phl_com_t *phl_com, struct hal_info_t *hal_info)
|
{
|
enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
|
struct hal_init_info_t init_52bu;
|
|
FUNCIN_WSTS(hal_status);
|
|
_os_mem_set(hal_to_drvpriv(hal_info), &init_52bu, 0, sizeof(init_52bu));
|
|
init_52bu.ic_name = "rtl8852bu";
|
|
hal_status = hal_mp_init_8852b(phl_com, hal_info, &init_52bu);
|
|
FUNCOUT_WSTS(hal_status);
|
return hal_status;
|
}
|
|
enum rtw_hal_status
|
hal_mp_deinit_8852bu(struct rtw_phl_com_t *phl_com, struct hal_info_t *hal_info)
|
{
|
enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
|
struct hal_init_info_t init_52bu;
|
|
FUNCIN_WSTS(hal_status);
|
|
_os_mem_set(hal_to_drvpriv(hal_info), &init_52bu, 0, sizeof(init_52bu));
|
|
init_52bu.ic_name = "rtl8852bu";
|
|
hal_status = hal_mp_deinit_8852b(phl_com, hal_info, &init_52bu);
|
|
if (RTW_HAL_STATUS_SUCCESS != hal_status) {
|
|
PHL_ERR("hal_mp_deinit_8852bu: status = %u\n", hal_status);
|
return hal_status;
|
}
|
|
FUNCOUT_WSTS(hal_status);
|
return hal_status;
|
}
|