2025-05-10 21:58:58 +08:00

1562 lines
41 KiB
C
Executable File

/******************************************************************************
*
* Copyright(c) 2019 - 2020 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 _HAL_INIT_C_
#include "hal_headers.h"
#if defined(CONFIG_PCI_HCI)
#include "hal_pci.h"
#elif defined(CONFIG_USB_HCI)
#include "hal_usb.h"
#elif defined(CONFIG_SDIO_HCI)
#include "hal_sdio.h"
#endif
/******************* IO APIs *******************/
u8 rtw_hal_read8(void *h, u32 addr)
{
struct hal_info_t *hal_info = (struct hal_info_t *)h;
struct rtw_hal_com_t *hal_com = hal_info->hal_com;
return hal_read8(hal_com, addr);
}
u16 rtw_hal_read16(void *h, u32 addr)
{
struct hal_info_t *hal_info = (struct hal_info_t *)h;
struct rtw_hal_com_t *hal_com = hal_info->hal_com;
return hal_read16(hal_com, addr);
}
u32 rtw_hal_read32(void *h, u32 addr)
{
struct hal_info_t *hal_info = (struct hal_info_t *)h;
struct rtw_hal_com_t *hal_com = hal_info->hal_com;
return hal_read32(hal_com, addr);
}
void rtw_hal_write8(void *h, u32 addr, u8 val)
{
struct hal_info_t *hal_info = (struct hal_info_t *)h;
struct rtw_hal_com_t *hal_com = hal_info->hal_com;
hal_write8(hal_com, addr, val);
}
void rtw_hal_write16(void *h, u32 addr, u16 val)
{
struct hal_info_t *hal_info = (struct hal_info_t *)h;
struct rtw_hal_com_t *hal_com = hal_info->hal_com;
hal_write16(hal_com, addr, val);
}
void rtw_hal_write32(void *h, u32 addr, u32 val)
{
struct hal_info_t *hal_info = (struct hal_info_t *)h;
struct rtw_hal_com_t *hal_com = hal_info->hal_com;
hal_write32(hal_com, addr, val);
}
u32 rtw_hal_read_macreg(void *h, u32 offset, u32 bit_mask)
{
struct hal_info_t *hal = (struct hal_info_t *)h;
struct hal_ops_t *hal_ops = hal_get_ops(hal);
return hal_ops->read_macreg(hal, offset, bit_mask);
}
void rtw_hal_write_macreg(void *h,
u32 offset, u32 bit_mask, u32 data)
{
struct hal_info_t *hal = (struct hal_info_t *)h;
struct hal_ops_t *hal_ops = hal_get_ops(hal);
hal_ops->write_macreg(hal, offset, bit_mask, data);
}
u32 rtw_hal_read_bbreg(void *h, u32 offset, u32 bit_mask)
{
struct hal_info_t *hal = (struct hal_info_t *)h;
struct hal_ops_t *hal_ops = hal_get_ops(hal);
return hal_ops->read_bbreg(hal, offset, bit_mask);
}
void rtw_hal_write_bbreg(void *h,
u32 offset, u32 bit_mask, u32 data)
{
struct hal_info_t *hal = (struct hal_info_t *)h;
struct hal_ops_t *hal_ops = hal_get_ops(hal);
hal_ops->write_bbreg(hal, offset, bit_mask, data);
}
u32 rtw_hal_read_rfreg(void *h,
enum rf_path path, u32 offset, u32 bit_mask)
{
struct hal_info_t *hal = (struct hal_info_t *)h;
struct hal_ops_t *hal_ops = hal_get_ops(hal);
return hal_ops->read_rfreg(hal, path, offset, bit_mask);
}
void rtw_hal_write_rfreg(void *h,
enum rf_path path, u32 offset, u32 bit_mask, u32 data)
{
struct hal_info_t *hal = (struct hal_info_t *)h;
struct hal_ops_t *hal_ops = hal_get_ops(hal);
hal_ops->write_rfreg(hal, path, offset, bit_mask, data);
}
#ifdef PHL_PLATFORM_LINUX
void rtw_hal_mac_reg_dump(void *sel, void *h)
{
struct hal_info_t *hal_info = (struct hal_info_t *)h;
struct rtw_hal_com_t *hal = hal_info->hal_com;
int i, j = 1;
RTW_PRINT_SEL(sel, "======= MAC REG =======\n");
for (i = 0x0; i < 0x800; i += 4) {
if (j % 4 == 1)
RTW_PRINT_SEL(sel, "0x%04x", i);
_RTW_PRINT_SEL(sel, " 0x%08x ", hal_read32(hal, i));
if ((j++) % 4 == 0)
_RTW_PRINT_SEL(sel, "\n");
}
#if 1
for (i = 0x1000; i < 0xF000; i += 4) {
if (j % 4 == 1)
RTW_PRINT_SEL(sel, "0x%04x", i);
_RTW_PRINT_SEL(sel, " 0x%08x ", hal_read32(hal, i));
if ((j++) % 4 == 0)
_RTW_PRINT_SEL(sel, "\n");
}
#endif
}
void rtw_hal_bb_reg_dump(void *sel, void *h)
{
struct hal_info_t *hal_info = (struct hal_info_t *)h;
struct rtw_hal_com_t *hal = hal_info->hal_com;
int i, j = 1;
RTW_PRINT_SEL(sel, "======= BB REG =======\n");
for (i = 0x800; i < 0x1000; i += 4) {
if (j % 4 == 1)
RTW_PRINT_SEL(sel, "0x%04x", i);
_RTW_PRINT_SEL(sel, " 0x%08x ", hal_read32(hal, i));
if ((j++) % 4 == 0)
_RTW_PRINT_SEL(sel, "\n");
}
#if 0
for (i = 0x1800; i < 0x2000; i += 4) {
if (j % 4 == 1)
RTW_PRINT_SEL(sel, "0x%04x", i);
_RTW_PRINT_SEL(sel, " 0x%08x ", hal_read32(hal, i));
if ((j++) % 4 == 0)
_RTW_PRINT_SEL(sel, "\n");
}
#endif
#if 0
for (i = 0x2c00; i < 0x2c60; i += 4) {
if (j % 4 == 1)
RTW_PRINT_SEL(sel, "0x%04x", i);
_RTW_PRINT_SEL(sel, " 0x%08x ", rtw_read32(adapter, i));
if ((j++) % 4 == 0)
_RTW_PRINT_SEL(sel, "\n");
}
for (i = 0x2d00; i < 0x2df0; i += 4) {
if (j % 4 == 1)
RTW_PRINT_SEL(sel, "0x%04x", i);
_RTW_PRINT_SEL(sel, " 0x%08x ", rtw_read32(adapter, i));
if ((j++) % 4 == 0)
_RTW_PRINT_SEL(sel, "\n");
}
for (i = 0x4000; i < 0x4060; i += 4) {
if (j % 4 == 1)
RTW_PRINT_SEL(sel, "0x%04x", i);
_RTW_PRINT_SEL(sel, " 0x%08x ", rtw_read32(adapter, i));
if ((j++) % 4 == 0)
_RTW_PRINT_SEL(sel, "\n");
}
for (i = 0x4100; i < 0x4200; i += 4) {
if (j % 4 == 1)
RTW_PRINT_SEL(sel, "0x%04x", i);
_RTW_PRINT_SEL(sel, " 0x%08x ", rtw_read32(adapter, i));
if ((j++) % 4 == 0)
_RTW_PRINT_SEL(sel, "\n");
}
#endif
}
void rtw_hal_bb_reg_dump_ex(void *sel, void *h)
{
struct hal_info_t *hal_info = (struct hal_info_t *)h;
struct rtw_hal_com_t *hal = hal_info->hal_com;
int i;
RTW_PRINT_SEL(sel, "======= BB REG =======\n");
for (i = 0x800; i < 0x1000; i += 4) {
RTW_PRINT_SEL(sel, "0x%04x", i);
_RTW_PRINT_SEL(sel, " 0x%08x ", hal_read32(hal, i));
_RTW_PRINT_SEL(sel, "\n");
}
#if 0
for (i = 0x1800; i < 0x2000; i += 4) {
RTW_PRINT_SEL(sel, "0x%04x", i);
_RTW_PRINT_SEL(sel, " 0x%08x ", hal_read32(hal, i));
_RTW_PRINT_SEL(sel, "\n");
}
#endif
}
void rtw_hal_rf_reg_dump(void *sel, void *h)
{
#ifdef RTW_WKARD_RF_CR_DUMP
int i, j = 1, path;
struct hal_info_t *hal_info = (struct hal_info_t *)h;
struct rtw_hal_com_t *hal = hal_info->hal_com;
u32 value;
u8 path_nums;
if (hal->rfpath_tx_num > hal->rfpath_rx_num)
path_nums = hal->rfpath_tx_num;
else
path_nums = hal->rfpath_rx_num;
RTW_PRINT_SEL(sel, "======= RF REG =======\n");
for (path = 0; path < path_nums; path++) {
RTW_PRINT_SEL(sel, "RF_Path(%x)\n", path);
for (i = 0; i < 0x100; i++) {
value = rtw_hal_read_rfreg(hal_info, path, i, 0xfffff);
if (j % 4 == 1)
RTW_PRINT_SEL(sel, "0x%02x ", i);
_RTW_PRINT_SEL(sel, " 0x%08x ", value);
if ((j++) % 4 == 0)
_RTW_PRINT_SEL(sel, "\n");
}
j = 1;
#ifdef CONFIG_RTL8852B
for (i = 0x10000; i < 0x10100; i++) {
value = rtw_hal_read_rfreg(hal_info, path, i, 0xfffff);
if (j % 4 == 1)
RTW_PRINT_SEL(sel, "0x%02x ", i);
_RTW_PRINT_SEL(sel, " 0x%08x ", value);
if ((j++) % 4 == 0)
_RTW_PRINT_SEL(sel, "\n");
}
_RTW_PRINT_SEL(sel, "\n");
#endif
}
#endif/*RTW_WKARD_RF_CR_DUMP*/
}
#endif
/**
* rtw_hal_get_sec_cam() - get the security cam raw data from HW
* @h: struct hal_info_t *
* @num: How many cam you wnat to dump from the first one.
* @buf: ptr to buffer which store the content from HW.
* If buf is NULL, use console as debug path.
* @size Size of allocated memroy for @buf.
* The size should be @num * size of security cam offset(0x20).
*
* Return rtw_hal_mac_get_addr_cam's return value in enum rtw_hal_status type.
*/
enum rtw_hal_status
rtw_hal_get_sec_cam(void *h, u16 num, u8 *buf, u16 size)
{
struct hal_info_t *hal_info = (struct hal_info_t *)h;
enum rtw_hal_status ret = RTW_HAL_STATUS_SUCCESS;
ret = rtw_hal_mac_get_sec_cam(hal_info, num, buf, size);
return ret;
}
/**
* rtw_hal_get_addr_cam() - get the address cam raw data from HW
* @h: struct hal_info_t *
* @num: How many cam you wnat to dump from the first one.
* @buf: ptr to buffer which store the content from HW.
* If buf is NULL, use console as debug path.
* @size Size of allocated memroy for @buf.
* The size should be @num * size of Addr cam offset(0x40).
*
* Return rtw_hal_mac_get_addr_cam's return value in enum rtw_hal_status type.
*/
enum rtw_hal_status
rtw_hal_get_addr_cam(void *h, u16 num, u8 *buf, u16 size)
{
struct hal_info_t *hal_info = (struct hal_info_t *)h;
enum rtw_hal_status ret = RTW_HAL_STATUS_SUCCESS;
ret = rtw_hal_mac_get_addr_cam(hal_info, num, buf, size);
return ret;
}
void rtw_hal_enable_interrupt(struct rtw_phl_com_t *phl_com, void *h)
{
struct hal_info_t *hal = (struct hal_info_t *)h;
struct hal_ops_t *hal_ops = hal_get_ops(hal);
if (hal_ops->enable_interrupt)
hal_ops->enable_interrupt(hal);
}
void rtw_hal_disable_interrupt(struct rtw_phl_com_t *phl_com, void *h)
{
struct hal_info_t *hal = (struct hal_info_t *)h;
struct hal_ops_t *hal_ops = hal_get_ops(hal);
if (hal_ops->disable_interrupt)
hal_ops->disable_interrupt(hal);
}
void rtw_hal_config_interrupt(void *h, enum rtw_phl_config_int int_mode)
{
struct hal_info_t *hal = (struct hal_info_t *)h;
struct hal_ops_t *hal_ops = hal_get_ops(hal);
if (hal_ops->config_interrupt)
hal_ops->config_interrupt(hal, int_mode);
}
bool rtw_hal_recognize_interrupt(void *h)
{
struct hal_info_t *hal = (struct hal_info_t *)h;
struct hal_ops_t *hal_ops = hal_get_ops(hal);
if (hal_ops->recognize_interrupt)
return hal_ops->recognize_interrupt(hal);
else
return false;
}
bool rtw_hal_recognize_halt_c2h_interrupt(void *h)
{
struct hal_info_t *hal = (struct hal_info_t *)h;
struct hal_ops_t *hal_ops = hal_get_ops(hal);
if (hal_ops->recognize_halt_c2h_interrupt)
return hal_ops->recognize_halt_c2h_interrupt(hal);
else
return false;
}
void rtw_hal_clear_interrupt(void *h)
{
struct hal_info_t *hal = (struct hal_info_t *)h;
struct hal_ops_t *hal_ops = hal_get_ops(hal);
if (hal_ops->clear_interrupt)
hal_ops->clear_interrupt(hal);
}
u32 rtw_hal_interrupt_handler(void *h)
{
struct hal_info_t *hal = (struct hal_info_t *)h;
struct hal_ops_t *hal_ops = hal_get_ops(hal);
u32 ret = 0;
if (hal_ops->interrupt_handler)
ret = hal_ops->interrupt_handler(hal);
else
PHL_DBG("hal_ops->interrupt_handler is NULL\n");
PHL_DBG("hal_ops->interrupt_handler ret=0x%x\n", ret);
return ret;
}
void rtw_hal_restore_interrupt(struct rtw_phl_com_t *phl_com, void *h)
{
struct hal_info_t *hal = (struct hal_info_t *)h;
struct hal_ops_t *hal_ops = hal_get_ops(hal);
if (hal_ops->restore_interrupt)
hal_ops->restore_interrupt(hal);
}
void rtw_hal_restore_rx_interrupt(void *h)
{
struct hal_info_t *hal = (struct hal_info_t *)h;
struct hal_ops_t *hal_ops = hal_get_ops(hal);
if (hal_ops->restore_rx_interrupt)
hal_ops->restore_rx_interrupt(hal);
else
PHL_DBG("hal_ops->restore_rx_interrupt is NULL\n");
}
static enum rtw_hal_status hal_ops_check(struct hal_info_t *hal)
{
enum rtw_hal_status status = RTW_HAL_STATUS_SUCCESS;
struct hal_ops_t *ops = hal_get_ops(hal);
struct hal_trx_ops *trx_ops = hal_get_trx_ops(hal);
/***hal_ops initialize section ***/
if (!ops->init_hal_spec) {
hal_error_msg("init_hal_spec");
status = RTW_HAL_STATUS_FAILURE;
}
if (!ops->read_chip_version) {
hal_error_msg("read_chip_version");
status = RTW_HAL_STATUS_FAILURE;
}
if (!ops->hal_init) {
hal_error_msg("hal_init");
status = RTW_HAL_STATUS_FAILURE;
}
if (!ops->hal_deinit) {
hal_error_msg("hal_deinit");
status = RTW_HAL_STATUS_FAILURE;
}
if (!ops->hal_start) {
hal_error_msg("hal_start");
status = RTW_HAL_STATUS_FAILURE;
}
if (!ops->hal_stop) {
hal_error_msg("hal_stop");
status = RTW_HAL_STATUS_FAILURE;
}
#ifdef CONFIG_WOWLAN
if (!ops->hal_wow_init) {
hal_error_msg("hal_wow_init");
status = RTW_HAL_STATUS_FAILURE;
}
if (!ops->hal_wow_deinit) {
hal_error_msg("hal_wow_deinit");
status = RTW_HAL_STATUS_FAILURE;
}
#endif /* CONFIG_WOWLAN */
if (!ops->hal_mp_init) {
hal_error_msg("hal_mp_init");
status = RTW_HAL_STATUS_FAILURE;
}
if (!ops->hal_mp_deinit) {
hal_error_msg("hal_mp_deinit");
status = RTW_HAL_STATUS_FAILURE;
}
if (!ops->hal_cfg_fw) {
hal_error_msg("hal_cfg_fw");
status = RTW_HAL_STATUS_FAILURE;
}
if (!ops->init_default_value) {
hal_error_msg("init_default_value");
status = RTW_HAL_STATUS_FAILURE;
}
if (!ops->hal_hci_configure) {
hal_error_msg("hal_hci_configure");
status = RTW_HAL_STATUS_FAILURE;
}
if (!ops->read_macreg) {
hal_error_msg("read_macreg");
status = RTW_HAL_STATUS_FAILURE;
}
if (!ops->write_macreg) {
hal_error_msg("write_macreg");
status = RTW_HAL_STATUS_FAILURE;
}
if (!ops->read_bbreg) {
hal_error_msg("read_bbreg");
status = RTW_HAL_STATUS_FAILURE;
}
if (!ops->write_bbreg) {
hal_error_msg("write_bbreg");
status = RTW_HAL_STATUS_FAILURE;
}
if (!ops->read_rfreg) {
hal_error_msg("read_rfreg");
status = RTW_HAL_STATUS_FAILURE;
}
if (!ops->write_rfreg) {
hal_error_msg("write_rfreg");
status = RTW_HAL_STATUS_FAILURE;
}
#if defined(CONFIG_PCI_HCI) || defined(CONFIG_SDIO_HCI)
if (!ops->enable_interrupt) {
hal_error_msg("enable_interrupt");
status = RTW_HAL_STATUS_FAILURE;
}
if (!ops->disable_interrupt) {
hal_error_msg("disable_interrupt");
status = RTW_HAL_STATUS_FAILURE;
}
#ifdef CONFIG_SDIO_HCI
if (!ops->config_interrupt) {
hal_error_msg("config_interrupt");
status = RTW_HAL_STATUS_FAILURE;
}
if (!ops->recognize_halt_c2h_interrupt) {
hal_error_msg("recognize_halt_c2h_interrupt");
status = RTW_HAL_STATUS_FAILURE;
}
#endif
if (!ops->recognize_interrupt) {
hal_error_msg("recognize_interrupt");
status = RTW_HAL_STATUS_FAILURE;
}
if (!ops->clear_interrupt) {
hal_error_msg("clear_interrupt");
status = RTW_HAL_STATUS_FAILURE;
}
if (!ops->interrupt_handler) {
hal_error_msg("interrupt_handler");
status = RTW_HAL_STATUS_FAILURE;
}
if (!ops->restore_interrupt) {
hal_error_msg("restore_interrupt");
status = RTW_HAL_STATUS_FAILURE;
}
#endif /*defined(CONFIG_PCI_HCI) || defined(CONFIG_SDIO_HCI)*/
/***hal_trx_ops section ***/
if (!trx_ops->init) {
hal_error_msg("trx init");
status = RTW_HAL_STATUS_FAILURE;
}
if (!trx_ops->deinit) {
hal_error_msg("trx deinit");
status = RTW_HAL_STATUS_FAILURE;
}
if (!trx_ops->map_hw_tx_chnl) {
hal_error_msg("trx map_hw_tx_chnl");
status = RTW_HAL_STATUS_FAILURE;
}
if (!trx_ops->get_fwcmd_queue_idx) {
hal_error_msg("trx get_fwcmd_queue_idx");
status = RTW_HAL_STATUS_FAILURE;
}
#ifdef CONFIG_PCI_HCI
if (!trx_ops->query_tx_res) {
hal_error_msg("trx query_tx_res");
status = RTW_HAL_STATUS_FAILURE;
}
if (!trx_ops->query_rx_res) {
hal_error_msg("trx query_rx_res");
status = RTW_HAL_STATUS_FAILURE;
}
if (!trx_ops->cfg_wow_txdma) {
hal_error_msg("trx cfg_wow_txdma");
status = RTW_HAL_STATUS_FAILURE;
}
if (!trx_ops->poll_txdma_idle) {
hal_error_msg("trx poll_txdma_idle");
status = RTW_HAL_STATUS_FAILURE;
}
if (!trx_ops->qsel_to_tid) {
hal_error_msg("trx qsel_to_tid");
status = RTW_HAL_STATUS_FAILURE;
}
if (!trx_ops->query_txch_num) {
hal_error_msg("trx query_txch_num");
status = RTW_HAL_STATUS_FAILURE;
}
if (!trx_ops->query_rxch_num) {
hal_error_msg("trx query_rxch_num");
status = RTW_HAL_STATUS_FAILURE;
}
if (!trx_ops->update_wd) {
hal_error_msg("trx update_wd");
status = RTW_HAL_STATUS_FAILURE;
}
if (!trx_ops->update_txbd) {
hal_error_msg("trx update_txbd");
status = RTW_HAL_STATUS_FAILURE;
}
if (!trx_ops->tx_start) {
hal_error_msg("trx tx_start");
status = RTW_HAL_STATUS_FAILURE;
}
if (!trx_ops->check_rxrdy) {
hal_error_msg("trx check_rxrdy");
status = RTW_HAL_STATUS_FAILURE;
}
if (!trx_ops->handle_rxbd_info) {
hal_error_msg("trx handle_rxbd_info");
status = RTW_HAL_STATUS_FAILURE;
}
if (!trx_ops->handle_rx_buffer) {
hal_error_msg("trx handle_rx_buffer");
status = RTW_HAL_STATUS_FAILURE;
}
if (!trx_ops->update_rxbd) {
hal_error_msg("trx update_rxbd");
status = RTW_HAL_STATUS_FAILURE;
}
if (!trx_ops->notify_rxdone) {
hal_error_msg("trx notify_rxdone");
status = RTW_HAL_STATUS_FAILURE;
}
if (!trx_ops->handle_wp_rpt) {
hal_error_msg("trx handle_wp_rpt");
status = RTW_HAL_STATUS_FAILURE;
}
#endif /*CONFIG_PCIE_HCI*/
#ifdef CONFIG_USB_HCI
if (!trx_ops->hal_fill_wd) {
hal_error_msg("trx hal_fill_wd");
status = RTW_HAL_STATUS_FAILURE;
}
if (!trx_ops->get_bulkout_id) {
hal_error_msg("trx get_bulkout_id");
status = RTW_HAL_STATUS_FAILURE;
}
if (!trx_ops->handle_rx_buffer) {
hal_error_msg("trx handle_rx_buffer");
status = RTW_HAL_STATUS_FAILURE;
}
if (!trx_ops->usb_tx_agg_cfg) {
hal_error_msg("trx usb_tx_agg_cfg");
status = RTW_HAL_STATUS_FAILURE;
}
if (!trx_ops->usb_rx_agg_cfg) {
hal_error_msg("trx usb_rx_agg_cfg");
status = RTW_HAL_STATUS_FAILURE;
}
if (!trx_ops->handle_wp_rpt) {
hal_error_msg("trx handle_wp_rpt");
status = RTW_HAL_STATUS_FAILURE;
}
#endif
#ifdef CONFIG_SDIO_HCI
#endif
return status;
}
static enum rtw_hal_status hal_set_ops(struct rtw_phl_com_t *phl_com,
struct hal_info_t *hal_info)
{
#ifdef CONFIG_PCI_HCI
if (phl_get_hci_type(phl_com) == RTW_HCI_PCIE)
hal_set_ops_pci(phl_com, hal_info);
#endif
#ifdef CONFIG_USB_HCI
if (phl_get_hci_type(phl_com) == RTW_HCI_USB)
hal_set_ops_usb(phl_com, hal_info);
#endif
#ifdef CONFIG_SDIO_HCI
if (phl_get_hci_type(phl_com) == RTW_HCI_SDIO)
hal_set_ops_sdio(phl_com, hal_info);
#endif
return hal_ops_check(hal_info);
}
#ifdef RTW_PHL_BCN
enum rtw_hal_status hal_bcn_init(struct hal_info_t *hal_info)
{
struct bcn_entry_pool *bcn_pool = &hal_info->hal_com->bcn_pool;
hal_info->hal_com->bcn_pool.bcn_num = 0;
INIT_LIST_HEAD(&bcn_pool->bcn_list);
_os_spinlock_init(hal_to_drvpriv(hal_info), &hal_info->hal_com->bcn_pool.bcn_lock);
return RTW_HAL_STATUS_SUCCESS;
}
enum rtw_hal_status hal_bcn_deinit(struct hal_info_t *hal_info)
{
void *drv_priv = hal_to_drvpriv(hal_info);
struct bcn_entry_pool *bcn_pool = &hal_info->hal_com->bcn_pool;
struct rtw_bcn_entry *tmp_entry, *type = NULL;
_os_spinlock(drv_priv, &bcn_pool->bcn_lock, _ps, NULL);
phl_list_for_loop_safe(tmp_entry, type,
struct rtw_bcn_entry, &bcn_pool->bcn_list, list)
{
list_del(&tmp_entry->list);
_os_mem_free(drv_priv, tmp_entry, sizeof(struct rtw_bcn_entry));
}
_os_spinunlock(drv_priv, &bcn_pool->bcn_lock, _ps, NULL);
return RTW_HAL_STATUS_SUCCESS;
}
enum rtw_hal_status hal_alloc_bcn_entry(struct rtw_phl_com_t *phl_com, struct hal_info_t *hal_info,
struct rtw_bcn_entry **bcn_entry, struct rtw_bcn_info_cmn *bcn_cmn)
{
void *drv_priv = hal_to_drvpriv(hal_info);
struct bcn_entry_pool *bcn_pool = &hal_info->hal_com->bcn_pool;
struct rtw_bcn_entry *new_entry = _os_mem_alloc(drv_priv, sizeof(struct rtw_bcn_entry));
if(new_entry == NULL)
return RTW_HAL_STATUS_FAILURE;
_os_spinlock(drv_priv, &bcn_pool->bcn_lock, _ps, NULL);
list_add_tail(&new_entry->list, &bcn_pool->bcn_list);
bcn_pool->bcn_num ++;
_os_spinunlock(drv_priv, &bcn_pool->bcn_lock, _ps, NULL);
*bcn_entry = new_entry;
return RTW_HAL_STATUS_SUCCESS;
}
enum rtw_hal_status hal_free_bcn_entry(struct rtw_phl_com_t *phl_com, struct hal_info_t *hal_info,
u8 bcn_id)
{
void *drv_priv = hal_to_drvpriv(hal_info);
struct bcn_entry_pool *bcn_pool = &hal_info->hal_com->bcn_pool;
struct rtw_bcn_entry *tmp_entry, *type = NULL;
u8 is_found = 0;
_os_spinlock(drv_priv, &bcn_pool->bcn_lock, _ps, NULL);
phl_list_for_loop_safe(tmp_entry, type,
struct rtw_bcn_entry, &bcn_pool->bcn_list, list)
{
if(tmp_entry->bcn_cmn->bcn_id == bcn_id){
is_found = 1;
break;
}
}
_os_spinunlock(drv_priv, &bcn_pool->bcn_lock, _ps, NULL);
if(is_found){
list_del(&tmp_entry->list);
_os_mem_free(drv_priv, tmp_entry, sizeof(struct rtw_bcn_entry));
bcn_pool->bcn_num --;
return RTW_HAL_STATUS_SUCCESS;
}
else
return RTW_HAL_STATUS_FAILURE;
}
enum rtw_hal_status hal_get_bcn_entry(struct rtw_phl_com_t *phl_com, struct hal_info_t *hal_info,
struct rtw_bcn_entry **bcn_entry, u8 bcn_id)
{
void *drv_priv = hal_to_drvpriv(hal_info);
struct bcn_entry_pool *bcn_pool = &hal_info->hal_com->bcn_pool;
struct rtw_bcn_entry *tmp_entry, *type = NULL;
u8 is_found = 0;
_os_spinlock(drv_priv, &bcn_pool->bcn_lock, _ps, NULL);
phl_list_for_loop_safe(tmp_entry, type,
struct rtw_bcn_entry, &bcn_pool->bcn_list, list)
{
if(tmp_entry->bcn_cmn->bcn_id == bcn_id){
is_found = 1;
break;
}
}
_os_spinunlock(drv_priv, &bcn_pool->bcn_lock, _ps, NULL);
if(is_found){
*bcn_entry = tmp_entry;
return RTW_HAL_STATUS_SUCCESS;
}
else
return RTW_HAL_STATUS_FAILURE;
}
enum rtw_hal_status hal_update_bcn_entry(struct rtw_phl_com_t *phl_com, struct hal_info_t *hal_info,
struct rtw_bcn_entry *bcn_entry, struct rtw_bcn_info_cmn *bcn_cmn)
{
struct rtw_wifi_role_t *wrole = &phl_com->wifi_roles[bcn_cmn->role_idx];
struct rtw_phl_stainfo_t *phl_sta = rtw_phl_get_stainfo_self(phl_com->phl_priv, wrole);
bcn_entry->bcn_cmn = bcn_cmn;
bcn_entry->bcn_hw.band = wrole->hw_band;
bcn_entry->bcn_hw.port = wrole->hw_port;
bcn_entry->bcn_hw.mbssid = wrole->hw_mbssid;
bcn_entry->bcn_hw.mac_id = (u8)phl_sta->macid;
return RTW_HAL_STATUS_SUCCESS;
}
enum rtw_hal_status rtw_hal_add_beacon(struct rtw_phl_com_t *phl_com, void *hal,
void *bcn_cmn)
{
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
struct hal_ops_t *hal_ops = hal_get_ops(hal_info);
struct rtw_bcn_entry *bcn_entry = NULL;
if(hal_alloc_bcn_entry(phl_com, hal_info, &bcn_entry, (struct rtw_bcn_info_cmn *)bcn_cmn) == RTW_HAL_STATUS_FAILURE)
return RTW_HAL_STATUS_FAILURE;
if(hal_update_bcn_entry(phl_com, hal_info, bcn_entry, (struct rtw_bcn_info_cmn *)bcn_cmn) == RTW_HAL_STATUS_FAILURE)
return RTW_HAL_STATUS_FAILURE;
if(hal_ops->cfg_bcn(phl_com, hal_info, bcn_entry) == RTW_HAL_STATUS_FAILURE)
return RTW_HAL_STATUS_FAILURE;
if(hal_ops->upt_bcn(phl_com, hal_info, bcn_entry) == RTW_HAL_STATUS_FAILURE)
return RTW_HAL_STATUS_FAILURE;
return RTW_HAL_STATUS_SUCCESS;
}
enum rtw_hal_status rtw_hal_update_beacon(struct rtw_phl_com_t *phl_com, void *hal,
u8 bcn_id)
{
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
struct hal_ops_t *hal_ops = hal_get_ops(hal_info);
struct rtw_bcn_entry *bcn_entry = NULL;
if(hal_get_bcn_entry(phl_com, hal_info, &bcn_entry, bcn_id) == RTW_HAL_STATUS_FAILURE)
return RTW_HAL_STATUS_FAILURE;
if(hal_ops->upt_bcn(phl_com, hal_info, bcn_entry) == RTW_HAL_STATUS_FAILURE)
return RTW_HAL_STATUS_FAILURE;
return RTW_HAL_STATUS_SUCCESS;
}
enum rtw_hal_status rtw_hal_free_beacon(struct rtw_phl_com_t *phl_com, void *hal,
u8 bcn_id)
{
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
if(hal_free_bcn_entry(phl_com, hal_info, bcn_id) == RTW_HAL_STATUS_FAILURE)
return RTW_HAL_STATUS_FAILURE;
return RTW_HAL_STATUS_SUCCESS;
}
#endif
enum rtw_hal_status rtw_hal_pkt_ofld(void *hal, u8 *id, u8 op,
u8 *pkt_buf, u16 *pkt_len)
{
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
struct hal_ops_t *hal_ops = hal_get_ops(hal_info);
return hal_ops->pkt_ofld(hal, id, op, pkt_buf, pkt_len);
}
enum rtw_hal_status rtw_hal_pkt_update_ids(void *hal,
struct pkt_ofld_entry *entry)
{
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
struct hal_ops_t *hal_ops = hal_get_ops(hal_info);
return hal_ops->pkt_update_ids(hal, entry);
}
enum rtw_hal_status rtw_hal_get_pwr_state(void *hal, enum rtw_mac_pwr_st *pwr_state)
{
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
return rtw_hal_mac_get_pwr_state(hal_info, pwr_state);
}
enum rtw_hal_status rtw_hal_init(void *drv_priv,
struct rtw_phl_com_t *phl_com, void **hal, enum rtl_ic_id ic_id)
{
struct hal_info_t *hal_info = NULL;
struct rtw_hal_com_t *hal_com = NULL;
enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
void (*set_intf_ops)(struct rtw_hal_com_t *hal, struct hal_io_ops *ops) = NULL;
enum rtw_chip_id chip_id = CHIP_WIFI6_MAX;
if (ic_id == RTL8852A)
chip_id = CHIP_WIFI6_8852A;
else if(ic_id == RTL8834A)
chip_id = CHIP_WIFI6_8834A;
else if(ic_id == RTL8852B)
chip_id = CHIP_WIFI6_8852B;
else if(ic_id == RTL8852C)
chip_id = CHIP_WIFI6_8852C;
else
return RTW_HAL_STATUS_FAILURE;
hal_info = _os_mem_alloc(drv_priv, sizeof(struct hal_info_t));
if (hal_info == NULL) {
hal_status = RTW_HAL_STATUS_RESOURCE;
PHL_ERR("alloc hal_info failed\n");
goto error_hal_mem;
}
*hal = hal_info;
hal_com = _os_mem_alloc(drv_priv, sizeof(struct rtw_hal_com_t));
if (hal_com == NULL) {
hal_status = RTW_HAL_STATUS_RESOURCE;
PHL_ERR("alloc hal_com failed\n");
goto error_hal_com_mem;
}
hal_info->hal_com = hal_com;
hal_com->drv_priv = drv_priv;
hal_com->hal_priv = hal_info;
hal_com->chip_id = chip_id;
hal_com->dbcc_en = false;
#ifdef DBG_HAL_MEM_MOINTOR
_os_atomic_set(drv_priv, &(hal_com->hal_mem), 0);
#endif
/*set io_ops*/
#ifdef CONFIG_PCI_HCI
if (phl_com->hci_type == RTW_HCI_PCIE)
set_intf_ops = hal_pci_set_io_ops;
#endif
#ifdef CONFIG_USB_HCI
if (phl_com->hci_type == RTW_HCI_USB)
set_intf_ops = hal_usb_set_io_ops;
#endif
#ifdef CONFIG_SDIO_HCI
if (phl_com->hci_type == RTW_HCI_SDIO)
set_intf_ops = hal_sdio_set_io_ops;
#endif
hal_status = hal_init_io_priv(hal_info->hal_com, set_intf_ops);
if (hal_status != RTW_HAL_STATUS_SUCCESS) {
PHL_ERR("hal_init_io_priv failed\n");
goto error_io_priv;
}
/*set hal_ops and hal_hook_trx_ops*/
hal_status = hal_set_ops(phl_com, hal_info);
if (hal_status != RTW_HAL_STATUS_SUCCESS) {
PHL_ERR("hal_set_ops failed\n");
goto error_hal_ops;
}
hal_status = hal_info->hal_ops.hal_init(phl_com, hal_info);
if (hal_status != RTW_HAL_STATUS_SUCCESS) {
PHL_ERR("hal_ops.hal_init failed\n");
goto error_hal_init;
}
hal_status = rtw_hal_mac_init(phl_com, hal_info);
if ((hal_status != RTW_HAL_STATUS_SUCCESS) || (hal_info->mac == NULL)) {
PHL_ERR("rtw_hal_mac_init failed\n");
goto error_mac_init;
}
hal_status = rtw_hal_efuse_init(phl_com, hal_info);
if (hal_status != RTW_HAL_STATUS_SUCCESS) {
PHL_ERR("rtw_hal_efuse_init failed\n");
goto error_efuse_init;
}
hal_status = rtw_hal_bb_init(phl_com, hal_info);
if (hal_status != RTW_HAL_STATUS_SUCCESS) {
PHL_ERR("rtw_hal_bb_init failed\n");
goto error_bb_init;
}
hal_status = rtw_hal_rf_init(phl_com, hal_info);
if (hal_status != RTW_HAL_STATUS_SUCCESS) {
PHL_ERR("rtw_hal_rf_init failed\n");
goto error_rf_init;
}
hal_status = rtw_hal_btc_init(phl_com, hal_info);
if (hal_status != RTW_HAL_STATUS_SUCCESS){
PHL_ERR("rtw_hal_btc_init failed\n");
goto error_btc_init;
}
#ifdef RTW_PHL_BCN
hal_status = hal_bcn_init(hal_info);
if (hal_status != RTW_HAL_STATUS_SUCCESS){
PHL_ERR("hal_bcn_init failed\n");
goto error_bcn_init;
}
#endif
return RTW_HAL_STATUS_SUCCESS;
#ifdef RTW_PHL_BCN
error_bcn_init:
rtw_hal_btc_deinit(phl_com, hal_info);
#endif
error_btc_init:
rtw_hal_rf_deinit(phl_com, hal_info);
error_rf_init:
rtw_hal_bb_deinit(phl_com, hal_info);
error_bb_init:
rtw_hal_efuse_deinit(phl_com, hal_info);
error_efuse_init:
rtw_hal_mac_deinit(phl_com, hal_info);
error_mac_init:
hal_info->hal_ops.hal_deinit(phl_com, hal_info);
error_hal_init:
error_hal_ops:
hal_deinit_io_priv(hal_com);
error_io_priv:
if (hal_com) {
_os_mem_free(drv_priv, hal_com, sizeof(struct rtw_hal_com_t));
hal_com = NULL;
}
error_hal_com_mem:
if (hal_info) {
_os_mem_free(drv_priv, hal_info, sizeof(struct hal_info_t));
*hal = hal_info = NULL;
}
error_hal_mem:
return hal_status;
}
struct rtw_hal_com_t *rtw_hal_get_halcom(void *hal)
{
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
return hal_info->hal_com;
}
void rtw_hal_deinit(struct rtw_phl_com_t *phl_com, void *hal)
{
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
void *drv_priv = hal_to_drvpriv(hal_info);
if(hal_info == NULL)
return;
/* stop mechanism / disassociate hal ops */
#ifdef RTW_PHL_BCN
hal_bcn_deinit(hal_info);
#endif
rtw_hal_btc_deinit(phl_com, hal_info);
rtw_hal_rf_deinit(phl_com, hal_info);
rtw_hal_bb_deinit(phl_com, hal_info);
rtw_hal_efuse_deinit(phl_com, hal_info);
rtw_hal_mac_deinit(phl_com, hal_info);
hal_info->hal_ops.hal_deinit(phl_com, hal_info);
hal_deinit_io_priv(hal_info->hal_com);
#ifdef DBG_HAL_MEM_MOINTOR
PHL_INFO("[PHL-MEM] %s HAL memory :%d\n", __func__,
_os_atomic_read(hal_to_drvpriv(hal_info), &(hal_info->hal_com->hal_mem)));
#endif
if (hal_info->hal_com) {
if(hal_info->hal_com->bf_obj)
hal_bf_deinit(hal_info);
if(hal_info->hal_com->csi_obj)
hal_csi_deinit(hal_info);
if(hal_info->hal_com->snd_obj)
hal_snd_obj_deinit(hal_info);
_os_mem_free(drv_priv,
hal_info->hal_com, sizeof(struct rtw_hal_com_t));
hal_info->hal_com = NULL;
}
if (hal_info) {
_os_mem_free(drv_priv,
hal_info, sizeof(struct hal_info_t));
hal_info = NULL;
}
}
bool rtw_hal_is_inited(struct rtw_phl_com_t *phl_com, void *hal)
{
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
return hal_info->hal_com->is_hal_init;
}
u32 rtw_hal_hci_cfg(struct rtw_phl_com_t *phl_com, void *hal,
struct rtw_ic_info *ic_info)
{
enum rtw_hal_status hal_status = RTW_HAL_STATUS_SUCCESS;
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
struct hal_ops_t *hal_ops = hal_get_ops(hal_info);
#ifdef CONFIG_SDIO_HCI
hal_info->hal_com->block_sz = ic_info->sdio_info.block_sz;
#endif
hal_ops->hal_hci_configure(phl_com, hal_info, ic_info);
return hal_status;
}
u32 rtw_hal_read_chip_info(struct rtw_phl_com_t *phl_com, void *hal)
{
enum rtw_hal_status hal_status = RTW_HAL_STATUS_SUCCESS;
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
struct hal_ops_t *hal_ops = hal_get_ops(hal_info);
hal_ops->read_chip_version(phl_com, hal_info);
/*get mac,bb,rf capability*/
hal_ops->init_hal_spec(phl_com, hal_info);
return hal_status;
}
static void _hal_reset_chandef(struct rtw_hal_com_t *hal_com)
{
struct rtw_chan_def *chandef = NULL;
u8 bid = 0;
for (bid = 0; bid < HW_BAND_MAX; bid++) {
chandef = &(hal_com->band[bid].cur_chandef);
chandef->bw = CHANNEL_WIDTH_MAX;
chandef->chan = 0;
chandef->offset = CHAN_OFFSET_NO_EXT;
}
}
void rtw_hal_set_default_var(void *hal, enum rtw_hal_set_def_var_rsn rsn)
{
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
struct hal_ops_t *hal_ops = hal_get_ops(hal_info);
struct hal_intr_mask_cfg intr_cfg = {0};
switch (rsn) {
case SET_DEF_RSN_HAL_INIT:
intr_cfg.halt_c2h_en = 1;
intr_cfg.wdt_en = 1;
hal_info->hal_com->assoc_sta_cnt = 0;
_hal_reset_chandef(hal_info->hal_com);
break;
case SET_DEF_RSN_WOW_RESUME_HNDL_RX:
intr_cfg.halt_c2h_en = 0;
intr_cfg.wdt_en = 1;
break;
case SET_DEF_RSN_WOW_RESUME_DONE:
intr_cfg.halt_c2h_en = 1;
intr_cfg.wdt_en = 1;
break;
default:
intr_cfg.halt_c2h_en = 1;
intr_cfg.wdt_en = 1;
hal_info->hal_com->assoc_sta_cnt = 0;
_hal_reset_chandef(hal_info->hal_com);
break;
}
PHL_INFO("%s : rsn %d.\n", __func__, rsn);
hal_ops->init_default_value(hal_info, &intr_cfg);
}
u32 rtw_hal_var_init(struct rtw_phl_com_t *phl_com, void *hal)
{
enum rtw_hal_status hal_status = RTW_HAL_STATUS_SUCCESS;
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
struct rtw_hal_com_t *hal_com = hal_info->hal_com;
hal_com->is_hal_init = false;
rtw_hal_set_default_var(hal_info, SET_DEF_RSN_HAL_INIT);
/*csi init shall after read hw chip info*/
hal_status = hal_csi_init(
hal_info,
phl_com->hal_spec.max_csi_buf_su_nr,
phl_com->hal_spec.max_csi_buf_mu_nr);
if (hal_status != RTW_HAL_STATUS_SUCCESS){
PHL_ERR("rtw_hal_csi_init failed\n");
}
/*bf init shall after read hw chip info*/
hal_status = hal_bf_init(
hal_info,
phl_com->hal_spec.max_bf_ent_nr,
phl_com->hal_spec.max_su_sta_nr,
phl_com->hal_spec.max_mu_sta_nr);
if (hal_status != RTW_HAL_STATUS_SUCCESS){
PHL_ERR("rtw_hal_bf_init failed\n");
}
hal_status = hal_snd_obj_init(hal_info);
if (hal_status != RTW_HAL_STATUS_SUCCESS){
PHL_ERR("hal_snd_obj_init failed\n");
}
return hal_status;
}
static int
_hal_parse_macreg(void *drv_priv, u32 *pdest_buf, u8 *psrc_buf, u32 buflen)
{
return 0;
}
enum rf_path _get_path_from_ant_num(u8 antnum)
{
enum rf_path ret = RF_PATH_B;
switch (antnum) {
default:
break;
case 1:
ret = RF_PATH_B;
break;
case 2:
ret = RF_PATH_AB;
break;
case 3:
ret = RF_PATH_ABC;
break;
}
return ret;
}
static void _hal_send_hal_init_hub_msg(struct rtw_phl_com_t *phl_com, u8 init_ok)
{
struct phl_msg msg = {0};
u16 evt_id = (init_ok) ? MSG_EVT_HAL_INIT_OK : MSG_EVT_HAL_INIT_FAIL;
msg.inbuf = NULL;
msg.inlen = 0;
SET_MSG_MDL_ID_FIELD(msg.msg_id, PHL_MDL_PHY_MGNT);
SET_MSG_EVT_ID_FIELD(msg.msg_id, evt_id);
msg.band_idx = HW_BAND_0;
rtw_phl_msg_hub_hal_send(phl_com, NULL, &msg);
}
enum rtw_hal_status rtw_hal_preload(struct rtw_phl_com_t *phl_com, void *hal)
{
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
struct hal_ops_t *hal_ops = hal_get_ops(hal_info);
FUNCIN();
hal_status = hal_ops->hal_get_efuse(phl_com, hal_info);
if (hal_status != RTW_HAL_STATUS_SUCCESS)
return hal_status;
return hal_status;
}
enum rtw_hal_status hal_rfe_type_chk(struct rtw_phl_com_t *phl_com,
struct hal_info_t *hal_info)
{
enum rtw_hal_status hal_status = RTW_HAL_STATUS_UNKNOWN_RFE_TYPE;
if(phl_com->dev_cap.rfe_type != 0xff){
hal_status = RTW_HAL_STATUS_SUCCESS;
}
else {
if(phl_com->dev_cap.bypass_rfe_chk == true){
rtw_hal_rf_get_default_rfe_type(hal_info->hal_com);
rtw_hal_rf_get_default_xtal(hal_info->hal_com);
PHL_WARN("%s: Use default RFE type(0x%x) / XTAL(0x%x) configuration for empty EFUSE\n",
__FUNCTION__,
hal_info->hal_com->dev_hw_cap.rfe_type,
hal_info->hal_com->dev_hw_cap.xcap);
hal_status = RTW_HAL_STATUS_SUCCESS;
}
}
return hal_status;
}
enum rtw_hal_status rtw_hal_start(struct rtw_phl_com_t *phl_com, void *hal)
{
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
struct hal_ops_t *hal_ops = hal_get_ops(hal_info);
#ifdef RTW_WKARD_DEF_CMACTBL_CFG
enum rf_path tx, rx;
#endif
hal_status = hal_rfe_type_chk(phl_com, hal_info);
if(hal_status != RTW_HAL_STATUS_SUCCESS){
PHL_ERR("%s: Unknown RFE type!!!\n", __FUNCTION__);
return hal_status;
}
hal_status = hal_ops->hal_start(phl_com, hal_info);
if (hal_status != RTW_HAL_STATUS_SUCCESS)
return hal_status;
hal_status = RTW_HAL_STATUS_SUCCESS;
hal_info->hal_com->is_hal_init = true;
rtw_hal_set_default_var(hal_info, SET_DEF_RSN_HAL_INIT);
rtw_hal_rf_set_power(hal_info, HW_PHY_0, PWR_BY_RATE);
#ifdef RTW_WKARD_DEF_CMACTBL_CFG
if (phl_com->phy_cap[0].txss < hal_info->hal_com->rfpath_tx_num)
hal_info->hal_com->rfpath_tx_num = phl_com->phy_cap[0].txss;
if (phl_com->phy_cap[0].rxss < hal_info->hal_com->rfpath_rx_num)
hal_info->hal_com->rfpath_rx_num = phl_com->phy_cap[0].rxss;
tx = _get_path_from_ant_num(hal_info->hal_com->rfpath_tx_num);
rx = _get_path_from_ant_num(hal_info->hal_com->rfpath_rx_num);
rtw_hal_bb_trx_path_cfg(hal_info, tx, phl_com->phy_cap[0].txss,
rx, phl_com->phy_cap[0].rxss);
#endif
#ifdef RTW_WKARD_SINGLE_PATH_RSSI
hal_info->hal_com->cur_rx_rfpath =
_get_path_from_ant_num(hal_info->hal_com->rfpath_rx_num);
#endif
#ifdef CONFIG_BTCOEX
rtw_hal_btc_radio_state_ntfy(hal_info, true);
#endif
return hal_status;
}
void rtw_hal_stop(struct rtw_phl_com_t *phl_com, void *hal)
{
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
struct hal_ops_t *hal_ops = hal_get_ops(hal_info);
do {
if (true == TEST_STATUS_FLAG(phl_com->dev_state,
RTW_DEV_SURPRISE_REMOVAL)) {
PHL_WARN("%s(): Device has removed, skip HW stop functions!\n", __func__);
break;
}
#ifdef CONFIG_BTCOEX
rtw_hal_btc_radio_state_ntfy(hal_info, false);
#endif
hal_status = hal_ops->hal_stop(phl_com, hal_info);
hal_info->hal_com->is_hal_init = false;
} while (false);
}
enum rtw_hal_status rtw_hal_restart(struct rtw_phl_com_t *phl_com, void *hal)
{
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
struct hal_ops_t *hal_ops = hal_get_ops(hal_info);
#ifdef CONFIG_BTCOEX
rtw_hal_btc_radio_state_ntfy(hal_info, false);
#endif
hal_status = hal_ops->hal_stop(phl_com, hal_info);
if (hal_status != RTW_HAL_STATUS_SUCCESS)
return hal_status;
hal_status = hal_ops->hal_start(phl_com, hal_info);
if (hal_status != RTW_HAL_STATUS_SUCCESS)
return hal_status;
#ifdef CONFIG_BTCOEX
rtw_hal_btc_radio_state_ntfy(hal_info, true);
#endif
hal_info->hal_com->is_hal_init = true;
return hal_status;
}
enum rtw_hal_status rtw_hal_hal_deinit(struct rtw_phl_com_t *phl_com, void *hal)
{
enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE;
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
hstatus = rtw_hal_mac_hal_deinit(phl_com, hal_info);
return hstatus;
}
enum rtw_hal_status
rtw_hal_role_cfg(void *hal, struct rtw_wifi_role_t *wrole)
{
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
/*enable & configure mac hw-port*/
hal_status = rtw_hal_mac_port_init(hal_info, wrole);
/* init hal mac bfer function if wrole cap if any of bfer cap is true*/
if (wrole->proto_role_cap.he_su_bfmr ||
wrole->proto_role_cap.he_mu_bfmr ||
wrole->proto_role_cap.vht_su_bfmr ||
wrole->proto_role_cap.vht_mu_bfmr ||
wrole->proto_role_cap.ht_su_bfmr) {
if ((PHL_RTYPE_AP == wrole->type) ||
((PHL_RTYPE_STATION == wrole->type) &&
(MLME_LINKED == wrole->mstate))) {
hal_status = hal_bf_hw_mac_init_bfer(hal_info,
wrole->hw_band);
}
}
return hal_status;
}
enum rtw_hal_status
rtw_hal_role_cfg_ex(void *hal, struct rtw_wifi_role_t *wrole,
enum pcfg_type type, void *param)
{
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
hal_status = rtw_hal_mac_port_cfg(hal_info, wrole, type, param);
return hal_status;
}
enum rtw_hal_status
rtw_hal_beacon_stop(void *hal, struct rtw_wifi_role_t *wrole, bool stop)
{
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
enum rtw_hal_status hsts = RTW_HAL_STATUS_FAILURE;
u32 bcn_en = (stop) ? 0 : 1;
PHL_INFO("%s wr-%d, bcn_en:%s\n", __func__, wrole->id, (bcn_en) ? "E" : "D");
hsts = rtw_hal_mac_port_cfg(hal_info, wrole, PCFG_BCN_EN, &bcn_en);
return hsts;
}
enum rtw_hal_status
hal_ver_check(struct rtw_hal_com_t *hal_com)
{
if ((hal_com->mac_vc.mac_ver < hal_com->bb_vc.mac_ver) ||
(hal_com->mac_vc.mac_ver < hal_com->rf_vc.mac_ver) ||
(hal_com->mac_vc.mac_ver < hal_com->btc_vc.mac_ver) ||
(hal_com->mac_vc.mac_ver < hal_com->fw_vc.mac_ver))
return RTW_HAL_STATUS_FAILURE;
return RTW_HAL_STATUS_SUCCESS;
}
enum rtw_hal_status
rtw_hal_watchdog(void *hal)
{
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
hal_status = rtw_hal_bb_watchdog(hal_info, false);
if (hal_status != RTW_HAL_STATUS_SUCCESS) {
PHL_ERR("%s rtw_hal_bb_watchdog fail (%x)\n", __FUNCTION__, hal_status);
goto exit;
}
hal_status = rtw_hal_rf_watchdog(hal_info);
if (hal_status != RTW_HAL_STATUS_SUCCESS) {
PHL_ERR("%s rtw_hal_rf_watchdog fail (%x)\n", __FUNCTION__, hal_status);
goto exit;
}
hal_status = rtw_hal_mac_watchdog(hal_info);
if (hal_status != RTW_HAL_STATUS_SUCCESS) {
PHL_ERR("%s rtw_hal_mac_watchdog fail (%x)\n", __FUNCTION__, hal_status);
goto exit;
}
exit:
return hal_status;
}
enum rtw_hal_status
rtw_hal_simple_watchdog(void *hal, u8 io_en)
{
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
hal_status = rtw_hal_bb_simple_watchdog(hal_info, io_en);
if(hal_status != RTW_HAL_STATUS_SUCCESS){
PHL_INFO("%s fail (%x)\n",
__FUNCTION__, hal_status);
goto exit;
}
exit:
return hal_status;
}
enum rtw_hal_status
rtw_hal_cfg_trx_path(void *hal, enum rf_path tx, u8 tx_nss,
enum rf_path rx, u8 rx_nss)
{
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
if (tx < RF_PATH_AB) {
/* forced tx nss = 1*/
tx_nss = 1;
}
if (rx < RF_PATH_AB) {
/* forced rx nss = 1*/
rx_nss = 1;
}
hal_status = rtw_hal_bb_trx_path_cfg(
hal_info,
tx,
((tx_nss > hal_info->hal_com->rfpath_tx_num) ?
hal_info->hal_com->rfpath_tx_num : tx_nss),
rx,
((rx_nss > hal_info->hal_com->rfpath_rx_num) ?
hal_info->hal_com->rfpath_rx_num : rx_nss));
#ifdef RTW_WKARD_SINGLE_PATH_RSSI
hal_info->hal_com->cur_rx_rfpath = rx;
#endif
return hal_status;
}
enum rtw_hal_status rtw_hal_set_sw_gpio_mode(struct rtw_phl_com_t *phl_com, void *hal, enum rtw_gpio_mode mode, u8 gpio)
{
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
hal_status = rtw_hal_mac_set_sw_gpio_mode(hal_info, mode, gpio);
PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "%s : status(%u).\n", __func__, hal_status);
return hal_status;
}
enum rtw_hal_status rtw_hal_sw_gpio_ctrl(struct rtw_phl_com_t *phl_com, void *hal, u8 high, u8 gpio)
{
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
hal_status = rtw_hal_mac_sw_gpio_ctrl(hal_info, high, gpio);
PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "%s : status(%u).\n", __func__, hal_status);
return hal_status;
}
void rtw_hal_dbg_status_dump(void *hal, struct hal_mac_dbg_dump_cfg *cfg)
{
struct hal_info_t *hal_info = (struct hal_info_t *)hal;
rtw_hal_mac_dbg_status_dump(hal_info, cfg);
}