/****************************************************************************** * * 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); }