blob: edbf6af1c8b70a76749e7554bff3f718a8a431ad [file] [log] [blame]
/******************************************************************************
*
* Copyright(c) 2016 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.
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "halmac_88xx_cfg.h"
/**
* halmac_init_adapter_para_88xx() - int halmac adapter
* @halmac_adapter
*
* SD1 internal use
*
* Author : KaiYuan Chang/Ivan Lin
* Return : void
*/
void halmac_init_adapter_para_88xx(struct halmac_adapter *halmac_adapter)
{
halmac_adapter->api_record.array_wptr = 0;
halmac_adapter->hal_adapter_backup = halmac_adapter;
halmac_adapter->hal_efuse_map = (u8 *)NULL;
halmac_adapter->hal_efuse_map_valid = false;
halmac_adapter->efuse_end = 0;
halmac_adapter->hal_mac_addr[0].address_l_h.address_low = 0;
halmac_adapter->hal_mac_addr[0].address_l_h.address_high = 0;
halmac_adapter->hal_mac_addr[1].address_l_h.address_low = 0;
halmac_adapter->hal_mac_addr[1].address_l_h.address_high = 0;
halmac_adapter->hal_bss_addr[0].address_l_h.address_low = 0;
halmac_adapter->hal_bss_addr[0].address_l_h.address_high = 0;
halmac_adapter->hal_bss_addr[1].address_l_h.address_low = 0;
halmac_adapter->hal_bss_addr[1].address_l_h.address_high = 0;
halmac_adapter->low_clk = false;
halmac_adapter->max_download_size = HALMAC_FW_MAX_DL_SIZE_88XX;
/* Init LPS Option */
halmac_adapter->fwlps_option.mode = 0x01; /*0:Active 1:LPS 2:WMMPS*/
halmac_adapter->fwlps_option.awake_interval = 1;
halmac_adapter->fwlps_option.enter_32K = 1;
halmac_adapter->fwlps_option.clk_request = 0;
halmac_adapter->fwlps_option.rlbm = 0;
halmac_adapter->fwlps_option.smart_ps = 0;
halmac_adapter->fwlps_option.awake_interval = 1;
halmac_adapter->fwlps_option.all_queue_uapsd = 0;
halmac_adapter->fwlps_option.pwr_state = 0;
halmac_adapter->fwlps_option.low_pwr_rx_beacon = 0;
halmac_adapter->fwlps_option.ant_auto_switch = 0;
halmac_adapter->fwlps_option.ps_allow_bt_high_priority = 0;
halmac_adapter->fwlps_option.protect_bcn = 0;
halmac_adapter->fwlps_option.silence_period = 0;
halmac_adapter->fwlps_option.fast_bt_connect = 0;
halmac_adapter->fwlps_option.two_antenna_en = 0;
halmac_adapter->fwlps_option.adopt_user_setting = 1;
halmac_adapter->fwlps_option.drv_bcn_early_shift = 0;
halmac_adapter->config_para_info.cfg_para_buf = NULL;
halmac_adapter->config_para_info.para_buf_w = NULL;
halmac_adapter->config_para_info.para_num = 0;
halmac_adapter->config_para_info.full_fifo_mode = false;
halmac_adapter->config_para_info.para_buf_size = 0;
halmac_adapter->config_para_info.avai_para_buf_size = 0;
halmac_adapter->config_para_info.offset_accumulation = 0;
halmac_adapter->config_para_info.value_accumulation = 0;
halmac_adapter->config_para_info.datapack_segment = 0;
halmac_adapter->ch_sw_info.ch_info_buf = NULL;
halmac_adapter->ch_sw_info.ch_info_buf_w = NULL;
halmac_adapter->ch_sw_info.extra_info_en = 0;
halmac_adapter->ch_sw_info.buf_size = 0;
halmac_adapter->ch_sw_info.avai_buf_size = 0;
halmac_adapter->ch_sw_info.total_size = 0;
halmac_adapter->ch_sw_info.ch_num = 0;
halmac_adapter->drv_info_size = 0;
memset(halmac_adapter->api_record.api_array, HALMAC_API_STUFF,
sizeof(halmac_adapter->api_record.api_array));
halmac_adapter->txff_allocation.tx_fifo_pg_num = 0;
halmac_adapter->txff_allocation.ac_q_pg_num = 0;
halmac_adapter->txff_allocation.rsvd_pg_bndy = 0;
halmac_adapter->txff_allocation.rsvd_drv_pg_bndy = 0;
halmac_adapter->txff_allocation.rsvd_h2c_extra_info_pg_bndy = 0;
halmac_adapter->txff_allocation.rsvd_h2c_queue_pg_bndy = 0;
halmac_adapter->txff_allocation.rsvd_cpu_instr_pg_bndy = 0;
halmac_adapter->txff_allocation.rsvd_fw_txbuff_pg_bndy = 0;
halmac_adapter->txff_allocation.pub_queue_pg_num = 0;
halmac_adapter->txff_allocation.high_queue_pg_num = 0;
halmac_adapter->txff_allocation.low_queue_pg_num = 0;
halmac_adapter->txff_allocation.normal_queue_pg_num = 0;
halmac_adapter->txff_allocation.extra_queue_pg_num = 0;
halmac_adapter->txff_allocation.la_mode = HALMAC_LA_MODE_DISABLE;
halmac_adapter->txff_allocation.rx_fifo_expanding_mode =
HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE;
halmac_init_adapter_dynamic_para_88xx(halmac_adapter);
halmac_init_state_machine_88xx(halmac_adapter);
}
/**
* halmac_init_adapter_dynamic_para_88xx() - int halmac adapter
* @halmac_adapter
*
* SD1 internal use
*
* Author : KaiYuan Chang/Ivan Lin
* Return : void
*/
void halmac_init_adapter_dynamic_para_88xx(
struct halmac_adapter *halmac_adapter)
{
halmac_adapter->h2c_packet_seq = 0;
halmac_adapter->h2c_buf_free_space = 0;
halmac_adapter->gen_info_valid = false;
}
/**
* halmac_init_state_machine_88xx() - init halmac software state machine
* @halmac_adapter
*
* SD1 internal use.
*
* Author : KaiYuan Chang/Ivan Lin
* Return : void
*/
void halmac_init_state_machine_88xx(struct halmac_adapter *halmac_adapter)
{
struct halmac_state *state = &halmac_adapter->halmac_state;
halmac_init_offload_feature_state_machine_88xx(halmac_adapter);
state->api_state = HALMAC_API_STATE_INIT;
state->dlfw_state = HALMAC_DLFW_NONE;
state->mac_power = HALMAC_MAC_POWER_OFF;
state->ps_state = HALMAC_PS_STATE_UNDEFINE;
}
/**
* halmac_mount_api_88xx() - attach functions to function pointer
* @halmac_adapter
*
* SD1 internal use
*
* Author : KaiYuan Chang/Ivan Lin
* Return : enum halmac_ret_status
*/
enum halmac_ret_status
halmac_mount_api_88xx(struct halmac_adapter *halmac_adapter)
{
void *driver_adapter = halmac_adapter->driver_adapter;
struct halmac_api *halmac_api = (struct halmac_api *)NULL;
halmac_adapter->halmac_api =
kzalloc(sizeof(struct halmac_api), GFP_KERNEL);
if (!halmac_adapter->halmac_api)
return HALMAC_RET_MALLOC_FAIL;
halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
HALMAC_SVN_VER_88XX "\n");
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"HALMAC_MAJOR_VER_88XX = %x\n", HALMAC_MAJOR_VER_88XX);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"HALMAC_PROTOTYPE_88XX = %x\n",
HALMAC_PROTOTYPE_VER_88XX);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"HALMAC_MINOR_VER_88XX = %x\n", HALMAC_MINOR_VER_88XX);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"HALMAC_PATCH_VER_88XX = %x\n", HALMAC_PATCH_VER_88XX);
/* Mount function pointer */
halmac_api->halmac_download_firmware = halmac_download_firmware_88xx;
halmac_api->halmac_free_download_firmware =
halmac_free_download_firmware_88xx;
halmac_api->halmac_get_fw_version = halmac_get_fw_version_88xx;
halmac_api->halmac_cfg_mac_addr = halmac_cfg_mac_addr_88xx;
halmac_api->halmac_cfg_bssid = halmac_cfg_bssid_88xx;
halmac_api->halmac_cfg_multicast_addr = halmac_cfg_multicast_addr_88xx;
halmac_api->halmac_pre_init_system_cfg =
halmac_pre_init_system_cfg_88xx;
halmac_api->halmac_init_system_cfg = halmac_init_system_cfg_88xx;
halmac_api->halmac_init_edca_cfg = halmac_init_edca_cfg_88xx;
halmac_api->halmac_cfg_operation_mode = halmac_cfg_operation_mode_88xx;
halmac_api->halmac_cfg_ch_bw = halmac_cfg_ch_bw_88xx;
halmac_api->halmac_cfg_bw = halmac_cfg_bw_88xx;
halmac_api->halmac_init_wmac_cfg = halmac_init_wmac_cfg_88xx;
halmac_api->halmac_init_mac_cfg = halmac_init_mac_cfg_88xx;
halmac_api->halmac_init_sdio_cfg = halmac_init_sdio_cfg_88xx;
halmac_api->halmac_init_usb_cfg = halmac_init_usb_cfg_88xx;
halmac_api->halmac_init_pcie_cfg = halmac_init_pcie_cfg_88xx;
halmac_api->halmac_deinit_sdio_cfg = halmac_deinit_sdio_cfg_88xx;
halmac_api->halmac_deinit_usb_cfg = halmac_deinit_usb_cfg_88xx;
halmac_api->halmac_deinit_pcie_cfg = halmac_deinit_pcie_cfg_88xx;
halmac_api->halmac_dump_efuse_map = halmac_dump_efuse_map_88xx;
halmac_api->halmac_dump_efuse_map_bt = halmac_dump_efuse_map_bt_88xx;
halmac_api->halmac_write_efuse_bt = halmac_write_efuse_bt_88xx;
halmac_api->halmac_dump_logical_efuse_map =
halmac_dump_logical_efuse_map_88xx;
halmac_api->halmac_pg_efuse_by_map = halmac_pg_efuse_by_map_88xx;
halmac_api->halmac_get_efuse_size = halmac_get_efuse_size_88xx;
halmac_api->halmac_get_efuse_available_size =
halmac_get_efuse_available_size_88xx;
halmac_api->halmac_get_c2h_info = halmac_get_c2h_info_88xx;
halmac_api->halmac_get_logical_efuse_size =
halmac_get_logical_efuse_size_88xx;
halmac_api->halmac_write_logical_efuse =
halmac_write_logical_efuse_88xx;
halmac_api->halmac_read_logical_efuse = halmac_read_logical_efuse_88xx;
halmac_api->halmac_cfg_fwlps_option = halmac_cfg_fwlps_option_88xx;
halmac_api->halmac_cfg_fwips_option = halmac_cfg_fwips_option_88xx;
halmac_api->halmac_enter_wowlan = halmac_enter_wowlan_88xx;
halmac_api->halmac_leave_wowlan = halmac_leave_wowlan_88xx;
halmac_api->halmac_enter_ps = halmac_enter_ps_88xx;
halmac_api->halmac_leave_ps = halmac_leave_ps_88xx;
halmac_api->halmac_h2c_lb = halmac_h2c_lb_88xx;
halmac_api->halmac_debug = halmac_debug_88xx;
halmac_api->halmac_cfg_parameter = halmac_cfg_parameter_88xx;
halmac_api->halmac_update_datapack = halmac_update_datapack_88xx;
halmac_api->halmac_run_datapack = halmac_run_datapack_88xx;
halmac_api->halmac_cfg_drv_info = halmac_cfg_drv_info_88xx;
halmac_api->halmac_send_bt_coex = halmac_send_bt_coex_88xx;
halmac_api->halmac_verify_platform_api =
halmac_verify_platform_api_88xx;
halmac_api->halmac_update_packet = halmac_update_packet_88xx;
halmac_api->halmac_bcn_ie_filter = halmac_bcn_ie_filter_88xx;
halmac_api->halmac_cfg_txbf = halmac_cfg_txbf_88xx;
halmac_api->halmac_cfg_mumimo = halmac_cfg_mumimo_88xx;
halmac_api->halmac_cfg_sounding = halmac_cfg_sounding_88xx;
halmac_api->halmac_del_sounding = halmac_del_sounding_88xx;
halmac_api->halmac_su_bfer_entry_init = halmac_su_bfer_entry_init_88xx;
halmac_api->halmac_su_bfee_entry_init = halmac_su_bfee_entry_init_88xx;
halmac_api->halmac_mu_bfer_entry_init = halmac_mu_bfer_entry_init_88xx;
halmac_api->halmac_mu_bfee_entry_init = halmac_mu_bfee_entry_init_88xx;
halmac_api->halmac_su_bfer_entry_del = halmac_su_bfer_entry_del_88xx;
halmac_api->halmac_su_bfee_entry_del = halmac_su_bfee_entry_del_88xx;
halmac_api->halmac_mu_bfer_entry_del = halmac_mu_bfer_entry_del_88xx;
halmac_api->halmac_mu_bfee_entry_del = halmac_mu_bfee_entry_del_88xx;
halmac_api->halmac_add_ch_info = halmac_add_ch_info_88xx;
halmac_api->halmac_add_extra_ch_info = halmac_add_extra_ch_info_88xx;
halmac_api->halmac_ctrl_ch_switch = halmac_ctrl_ch_switch_88xx;
halmac_api->halmac_p2pps = halmac_p2pps_88xx;
halmac_api->halmac_clear_ch_info = halmac_clear_ch_info_88xx;
halmac_api->halmac_send_general_info = halmac_send_general_info_88xx;
halmac_api->halmac_start_iqk = halmac_start_iqk_88xx;
halmac_api->halmac_ctrl_pwr_tracking = halmac_ctrl_pwr_tracking_88xx;
halmac_api->halmac_psd = halmac_psd_88xx;
halmac_api->halmac_cfg_la_mode = halmac_cfg_la_mode_88xx;
halmac_api->halmac_cfg_rx_fifo_expanding_mode =
halmac_cfg_rx_fifo_expanding_mode_88xx;
halmac_api->halmac_config_security = halmac_config_security_88xx;
halmac_api->halmac_get_used_cam_entry_num =
halmac_get_used_cam_entry_num_88xx;
halmac_api->halmac_read_cam_entry = halmac_read_cam_entry_88xx;
halmac_api->halmac_write_cam = halmac_write_cam_88xx;
halmac_api->halmac_clear_cam_entry = halmac_clear_cam_entry_88xx;
halmac_api->halmac_get_hw_value = halmac_get_hw_value_88xx;
halmac_api->halmac_set_hw_value = halmac_set_hw_value_88xx;
halmac_api->halmac_cfg_drv_rsvd_pg_num =
halmac_cfg_drv_rsvd_pg_num_88xx;
halmac_api->halmac_get_chip_version = halmac_get_chip_version_88xx;
halmac_api->halmac_query_status = halmac_query_status_88xx;
halmac_api->halmac_reset_feature = halmac_reset_feature_88xx;
halmac_api->halmac_check_fw_status = halmac_check_fw_status_88xx;
halmac_api->halmac_dump_fw_dmem = halmac_dump_fw_dmem_88xx;
halmac_api->halmac_cfg_max_dl_size = halmac_cfg_max_dl_size_88xx;
halmac_api->halmac_dump_fifo = halmac_dump_fifo_88xx;
halmac_api->halmac_get_fifo_size = halmac_get_fifo_size_88xx;
halmac_api->halmac_chk_txdesc = halmac_chk_txdesc_88xx;
halmac_api->halmac_dl_drv_rsvd_page = halmac_dl_drv_rsvd_page_88xx;
halmac_api->halmac_cfg_csi_rate = halmac_cfg_csi_rate_88xx;
halmac_api->halmac_sdio_cmd53_4byte = halmac_sdio_cmd53_4byte_88xx;
halmac_api->halmac_txfifo_is_empty = halmac_txfifo_is_empty_88xx;
if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
halmac_api->halmac_cfg_rx_aggregation =
halmac_cfg_rx_aggregation_88xx_sdio;
halmac_api->halmac_init_interface_cfg =
halmac_init_sdio_cfg_88xx;
halmac_api->halmac_deinit_interface_cfg =
halmac_deinit_sdio_cfg_88xx;
halmac_api->halmac_reg_read_8 = halmac_reg_read_8_sdio_88xx;
halmac_api->halmac_reg_write_8 = halmac_reg_write_8_sdio_88xx;
halmac_api->halmac_reg_read_16 = halmac_reg_read_16_sdio_88xx;
halmac_api->halmac_reg_write_16 = halmac_reg_write_16_sdio_88xx;
halmac_api->halmac_reg_read_32 = halmac_reg_read_32_sdio_88xx;
halmac_api->halmac_reg_write_32 = halmac_reg_write_32_sdio_88xx;
halmac_api->halmac_reg_read_indirect_32 =
halmac_reg_read_indirect_32_sdio_88xx;
halmac_api->halmac_reg_sdio_cmd53_read_n =
halmac_reg_read_nbyte_sdio_88xx;
} else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_USB) {
halmac_api->halmac_cfg_rx_aggregation =
halmac_cfg_rx_aggregation_88xx_usb;
halmac_api->halmac_init_interface_cfg =
halmac_init_usb_cfg_88xx;
halmac_api->halmac_deinit_interface_cfg =
halmac_deinit_usb_cfg_88xx;
halmac_api->halmac_reg_read_8 = halmac_reg_read_8_usb_88xx;
halmac_api->halmac_reg_write_8 = halmac_reg_write_8_usb_88xx;
halmac_api->halmac_reg_read_16 = halmac_reg_read_16_usb_88xx;
halmac_api->halmac_reg_write_16 = halmac_reg_write_16_usb_88xx;
halmac_api->halmac_reg_read_32 = halmac_reg_read_32_usb_88xx;
halmac_api->halmac_reg_write_32 = halmac_reg_write_32_usb_88xx;
} else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_PCIE) {
halmac_api->halmac_cfg_rx_aggregation =
halmac_cfg_rx_aggregation_88xx_pcie;
halmac_api->halmac_init_interface_cfg =
halmac_init_pcie_cfg_88xx;
halmac_api->halmac_deinit_interface_cfg =
halmac_deinit_pcie_cfg_88xx;
halmac_api->halmac_reg_read_8 = halmac_reg_read_8_pcie_88xx;
halmac_api->halmac_reg_write_8 = halmac_reg_write_8_pcie_88xx;
halmac_api->halmac_reg_read_16 = halmac_reg_read_16_pcie_88xx;
halmac_api->halmac_reg_write_16 = halmac_reg_write_16_pcie_88xx;
halmac_api->halmac_reg_read_32 = halmac_reg_read_32_pcie_88xx;
halmac_api->halmac_reg_write_32 = halmac_reg_write_32_pcie_88xx;
} else {
pr_err("Set halmac io function Error!!\n");
}
halmac_api->halmac_set_bulkout_num = halmac_set_bulkout_num_88xx;
halmac_api->halmac_get_sdio_tx_addr = halmac_get_sdio_tx_addr_88xx;
halmac_api->halmac_get_usb_bulkout_id = halmac_get_usb_bulkout_id_88xx;
halmac_api->halmac_timer_2s = halmac_timer_2s_88xx;
halmac_api->halmac_fill_txdesc_checksum =
halmac_fill_txdesc_check_sum_88xx;
if (halmac_adapter->chip_id == HALMAC_CHIP_ID_8822B) {
/*mount 8822b function and data*/
halmac_mount_api_8822b(halmac_adapter);
} else if (halmac_adapter->chip_id == HALMAC_CHIP_ID_8821C) {
} else if (halmac_adapter->chip_id == HALMAC_CHIP_ID_8814B) {
} else if (halmac_adapter->chip_id == HALMAC_CHIP_ID_8197F) {
} else {
pr_err("Chip ID undefine!!\n");
return HALMAC_RET_CHIP_NOT_SUPPORT;
}
return HALMAC_RET_SUCCESS;
}
/**
* halmac_download_firmware_88xx() - download Firmware
* @halmac_adapter : the adapter of halmac
* @hamacl_fw : firmware bin
* @halmac_fw_size : firmware size
* Author : KaiYuan Chang/Ivan Lin
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_download_firmware_88xx(struct halmac_adapter *halmac_adapter,
u8 *hamacl_fw, u32 halmac_fw_size)
{
u8 value8;
u8 *file_ptr;
u32 dest;
u16 value16;
u32 restore_index = 0;
u32 halmac_h2c_ver = 0, fw_h2c_ver = 0;
u32 iram_pkt_size, dmem_pkt_size, eram_pkt_size = 0;
void *driver_adapter = NULL;
struct halmac_api *halmac_api;
struct halmac_restore_info restore_info[DLFW_RESTORE_REG_NUM_88XX];
u32 temp;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DOWNLOAD_FIRMWARE);
driver_adapter = halmac_adapter->driver_adapter;
halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s ==========>\n", __func__);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s start!!\n", __func__);
if (halmac_fw_size > HALMAC_FW_SIZE_MAX_88XX ||
halmac_fw_size < HALMAC_FWHDR_SIZE_88XX) {
pr_err("FW size error!\n");
return HALMAC_RET_FW_SIZE_ERR;
}
fw_h2c_ver = le32_to_cpu(
*((__le32 *)
(hamacl_fw + HALMAC_FWHDR_OFFSET_H2C_FORMAT_VER_88XX)));
halmac_h2c_ver = H2C_FORMAT_VERSION;
HALMAC_RT_TRACE(
driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"halmac h2c/c2h format = %x, fw h2c/c2h format = %x!!\n",
halmac_h2c_ver, fw_h2c_ver);
if (fw_h2c_ver != halmac_h2c_ver)
HALMAC_RT_TRACE(
driver_adapter, HALMAC_MSG_INIT, DBG_WARNING,
"[WARN]H2C/C2H version between HALMAC and FW is compatible!!\n");
halmac_adapter->halmac_state.dlfw_state = HALMAC_DLFW_NONE;
value8 = HALMAC_REG_READ_8(halmac_adapter, REG_SYS_FUNC_EN + 1);
value8 = (u8)(value8 & ~(BIT(2)));
HALMAC_REG_WRITE_8(halmac_adapter, REG_SYS_FUNC_EN + 1,
value8); /* Disable CPU reset */
value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RSV_CTRL + 1);
value8 = (u8)(value8 & ~(BIT(0)));
HALMAC_REG_WRITE_8(halmac_adapter, REG_RSV_CTRL + 1, value8);
restore_info[restore_index].length = 1;
restore_info[restore_index].mac_register = REG_TXDMA_PQ_MAP + 1;
restore_info[restore_index].value =
HALMAC_REG_READ_8(halmac_adapter, REG_TXDMA_PQ_MAP + 1);
restore_index++;
value8 = HALMAC_DMA_MAPPING_HIGH << 6;
HALMAC_REG_WRITE_8(halmac_adapter, REG_TXDMA_PQ_MAP + 1,
value8); /* set HIQ to hi priority */
/* DLFW only use HIQ, map HIQ to hi priority */
halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_HI] =
HALMAC_DMA_MAPPING_HIGH;
restore_info[restore_index].length = 1;
restore_info[restore_index].mac_register = REG_CR;
restore_info[restore_index].value =
HALMAC_REG_READ_8(halmac_adapter, REG_CR);
restore_index++;
restore_info[restore_index].length = 4;
restore_info[restore_index].mac_register = REG_H2CQ_CSR;
restore_info[restore_index].value = BIT(31);
restore_index++;
value8 = BIT_HCI_TXDMA_EN | BIT_TXDMA_EN;
HALMAC_REG_WRITE_8(halmac_adapter, REG_CR, value8);
HALMAC_REG_WRITE_32(halmac_adapter, REG_H2CQ_CSR, BIT(31));
/* Config hi priority queue and public priority queue page number
* (only for DLFW)
*/
restore_info[restore_index].length = 2;
restore_info[restore_index].mac_register = REG_FIFOPAGE_INFO_1;
restore_info[restore_index].value =
HALMAC_REG_READ_16(halmac_adapter, REG_FIFOPAGE_INFO_1);
restore_index++;
restore_info[restore_index].length = 4;
restore_info[restore_index].mac_register = REG_RQPN_CTRL_2;
restore_info[restore_index].value =
HALMAC_REG_READ_32(halmac_adapter, REG_RQPN_CTRL_2) | BIT(31);
restore_index++;
HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_INFO_1, 0x200);
HALMAC_REG_WRITE_32(halmac_adapter, REG_RQPN_CTRL_2,
restore_info[restore_index - 1].value);
if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
HALMAC_REG_READ_32(halmac_adapter, REG_SDIO_FREE_TXPG);
HALMAC_REG_WRITE_32(halmac_adapter, REG_SDIO_TX_CTRL,
0x00000000);
}
halmac_adapter->fw_version.version = le16_to_cpu(
*((__le16 *)(hamacl_fw + HALMAC_FWHDR_OFFSET_VERSION_88XX)));
halmac_adapter->fw_version.sub_version =
*(hamacl_fw + HALMAC_FWHDR_OFFSET_SUBVERSION_88XX);
halmac_adapter->fw_version.sub_index =
*(hamacl_fw + HALMAC_FWHDR_OFFSET_SUBINDEX_88XX);
halmac_adapter->fw_version.h2c_version = (u16)fw_h2c_ver;
dmem_pkt_size = le32_to_cpu(*((__le32 *)(hamacl_fw +
HALMAC_FWHDR_OFFSET_DMEM_SIZE_88XX)));
iram_pkt_size = le32_to_cpu(*((__le32 *)(hamacl_fw +
HALMAC_FWHDR_OFFSET_IRAM_SIZE_88XX)));
if (((*(hamacl_fw + HALMAC_FWHDR_OFFSET_MEM_USAGE_88XX)) & BIT(4)) != 0)
eram_pkt_size =
le32_to_cpu(*((__le32 *)(hamacl_fw +
HALMAC_FWHDR_OFFSET_ERAM_SIZE_88XX)));
dmem_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
iram_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
if (eram_pkt_size != 0)
eram_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
if (halmac_fw_size != (HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size +
iram_pkt_size + eram_pkt_size)) {
pr_err("FW size mismatch the real fw size!\n");
goto DLFW_FAIL;
}
value8 = HALMAC_REG_READ_8(halmac_adapter, REG_CR + 1);
restore_info[restore_index].length = 1;
restore_info[restore_index].mac_register = REG_CR + 1;
restore_info[restore_index].value = value8;
restore_index++;
value8 = (u8)(value8 | BIT(0));
HALMAC_REG_WRITE_8(halmac_adapter, REG_CR + 1,
value8); /* Enable SW TX beacon */
value8 = HALMAC_REG_READ_8(halmac_adapter, REG_BCN_CTRL);
restore_info[restore_index].length = 1;
restore_info[restore_index].mac_register = REG_BCN_CTRL;
restore_info[restore_index].value = value8;
restore_index++;
value8 = (u8)((value8 & (~BIT(3))) | BIT(4));
HALMAC_REG_WRITE_8(halmac_adapter, REG_BCN_CTRL,
value8); /* Disable beacon related functions */
value8 = HALMAC_REG_READ_8(halmac_adapter, REG_FWHW_TXQ_CTRL + 2);
restore_info[restore_index].length = 1;
restore_info[restore_index].mac_register = REG_FWHW_TXQ_CTRL + 2;
restore_info[restore_index].value = value8;
restore_index++;
value8 = (u8)(value8 & ~(BIT(6)));
HALMAC_REG_WRITE_8(halmac_adapter, REG_FWHW_TXQ_CTRL + 2,
value8); /* Disable ptcl tx bcnq */
restore_info[restore_index].length = 2;
restore_info[restore_index].mac_register = REG_FIFOPAGE_CTRL_2;
restore_info[restore_index].value =
HALMAC_REG_READ_16(halmac_adapter, REG_FIFOPAGE_CTRL_2) |
BIT(15);
restore_index++;
value16 = 0x8000;
HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
value16); /* Set beacon header to 0 */
value16 = (u16)(HALMAC_REG_READ_16(halmac_adapter, REG_MCUFW_CTRL) &
0x3800);
value16 |= BIT(0);
HALMAC_REG_WRITE_16(halmac_adapter, REG_MCUFW_CTRL,
value16); /* MCU/FW setting */
value8 = HALMAC_REG_READ_8(halmac_adapter, REG_CPU_DMEM_CON + 2);
value8 &= ~(BIT(0));
HALMAC_REG_WRITE_8(halmac_adapter, REG_CPU_DMEM_CON + 2, value8);
value8 |= BIT(0);
HALMAC_REG_WRITE_8(halmac_adapter, REG_CPU_DMEM_CON + 2, value8);
/* Download to DMEM */
file_ptr = hamacl_fw + HALMAC_FWHDR_SIZE_88XX;
temp = le32_to_cpu(*((__le32 *)(hamacl_fw +
HALMAC_FWHDR_OFFSET_DMEM_ADDR_88XX))) &
~(BIT(31));
if (halmac_dlfw_to_mem_88xx(halmac_adapter, file_ptr, temp,
dmem_pkt_size) != HALMAC_RET_SUCCESS)
goto DLFW_END;
/* Download to IMEM */
file_ptr = hamacl_fw + HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size;
temp = le32_to_cpu(*((__le32 *)(hamacl_fw +
HALMAC_FWHDR_OFFSET_IRAM_ADDR_88XX))) &
~(BIT(31));
if (halmac_dlfw_to_mem_88xx(halmac_adapter, file_ptr, temp,
iram_pkt_size) != HALMAC_RET_SUCCESS)
goto DLFW_END;
/* Download to EMEM */
if (eram_pkt_size != 0) {
file_ptr = hamacl_fw + HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size +
iram_pkt_size;
dest = le32_to_cpu((*((__le32 *)(hamacl_fw +
HALMAC_FWHDR_OFFSET_EMEM_ADDR_88XX)))) &
~(BIT(31));
if (halmac_dlfw_to_mem_88xx(halmac_adapter, file_ptr, dest,
eram_pkt_size) !=
HALMAC_RET_SUCCESS)
goto DLFW_END;
}
halmac_init_offload_feature_state_machine_88xx(halmac_adapter);
DLFW_END:
halmac_restore_mac_register_88xx(halmac_adapter, restore_info,
DLFW_RESTORE_REG_NUM_88XX);
if (halmac_dlfw_end_flow_88xx(halmac_adapter) != HALMAC_RET_SUCCESS)
goto DLFW_FAIL;
halmac_adapter->halmac_state.dlfw_state = HALMAC_DLFW_DONE;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
DLFW_FAIL:
/* Disable FWDL_EN */
HALMAC_REG_WRITE_8(
halmac_adapter, REG_MCUFW_CTRL,
(u8)(HALMAC_REG_READ_8(halmac_adapter, REG_MCUFW_CTRL) &
~(BIT(0))));
return HALMAC_RET_DLFW_FAIL;
}
/**
* halmac_free_download_firmware_88xx() - download specific memory firmware
* @halmac_adapter
* @dlfw_mem : memory selection
* @hamacl_fw : firmware bin
* @halmac_fw_size : firmware size
* Author : KaiYuan Chang/Ivan Lin
* Return : enum halmac_ret_status
*/
enum halmac_ret_status
halmac_free_download_firmware_88xx(struct halmac_adapter *halmac_adapter,
enum halmac_dlfw_mem dlfw_mem, u8 *hamacl_fw,
u32 halmac_fw_size)
{
u8 tx_pause_backup;
u8 *file_ptr;
u32 dest;
u16 bcn_head_backup;
u32 iram_pkt_size, dmem_pkt_size, eram_pkt_size = 0;
void *driver_adapter = NULL;
enum halmac_ret_status status = HALMAC_RET_DLFW_FAIL;
struct halmac_api *halmac_api;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_NO_DLFW;
driver_adapter = halmac_adapter->driver_adapter;
halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"[TRACE]%s ==========>\n", __func__);
if (halmac_fw_size > HALMAC_FW_SIZE_MAX_88XX ||
halmac_fw_size < HALMAC_FWHDR_SIZE_88XX) {
pr_err("[ERR]FW size error!\n");
return HALMAC_RET_FW_SIZE_ERR;
}
dmem_pkt_size =
le32_to_cpu(*(__le32 *)(hamacl_fw +
HALMAC_FWHDR_OFFSET_DMEM_SIZE_88XX));
iram_pkt_size =
le32_to_cpu(*(__le32 *)(hamacl_fw +
HALMAC_FWHDR_OFFSET_IRAM_SIZE_88XX));
if (((*(hamacl_fw + HALMAC_FWHDR_OFFSET_MEM_USAGE_88XX)) & BIT(4)) != 0)
eram_pkt_size =
le32_to_cpu(*(__le32 *)(hamacl_fw +
HALMAC_FWHDR_OFFSET_ERAM_SIZE_88XX));
dmem_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
iram_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
if (eram_pkt_size != 0)
eram_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
if (halmac_fw_size != (HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size +
iram_pkt_size + eram_pkt_size)) {
pr_err("[ERR]FW size mismatch the real fw size!\n");
return HALMAC_RET_DLFW_FAIL;
}
tx_pause_backup = HALMAC_REG_READ_8(halmac_adapter, REG_TXPAUSE);
HALMAC_REG_WRITE_8(halmac_adapter, REG_TXPAUSE,
tx_pause_backup | BIT(7));
bcn_head_backup =
HALMAC_REG_READ_16(halmac_adapter, REG_FIFOPAGE_CTRL_2) |
BIT(15);
HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2, 0x8000);
if (eram_pkt_size != 0) {
file_ptr = hamacl_fw + HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size +
iram_pkt_size;
dest = le32_to_cpu(*((__le32 *)(hamacl_fw +
HALMAC_FWHDR_OFFSET_EMEM_ADDR_88XX))) &
~(BIT(31));
status = halmac_dlfw_to_mem_88xx(halmac_adapter, file_ptr, dest,
eram_pkt_size);
if (status != HALMAC_RET_SUCCESS)
goto DL_FREE_FW_END;
}
status = halmac_free_dl_fw_end_flow_88xx(halmac_adapter);
DL_FREE_FW_END:
HALMAC_REG_WRITE_8(halmac_adapter, REG_TXPAUSE, tx_pause_backup);
HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
bcn_head_backup);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"[TRACE]%s <==========\n", __func__);
return status;
}
/**
* halmac_get_fw_version_88xx() - get FW version
* @halmac_adapter : the adapter of halmac
* @fw_version : fw version info
* Author : Ivan Lin
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_get_fw_version_88xx(struct halmac_adapter *halmac_adapter,
struct halmac_fw_version *fw_version)
{
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_adapter->halmac_state.dlfw_state == 0)
return HALMAC_RET_DLFW_FAIL;
fw_version->version = halmac_adapter->fw_version.version;
fw_version->sub_version = halmac_adapter->fw_version.sub_version;
fw_version->sub_index = halmac_adapter->fw_version.sub_index;
return HALMAC_RET_SUCCESS;
}
/**
* halmac_cfg_mac_addr_88xx() - config mac address
* @halmac_adapter : the adapter of halmac
* @halmac_port :0 for port0, 1 for port1, 2 for port2, 3 for port3, 4 for port4
* @hal_address : mac address
* Author : KaiYuan Chang/Ivan Lin
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_cfg_mac_addr_88xx(struct halmac_adapter *halmac_adapter, u8 halmac_port,
union halmac_wlan_addr *hal_address)
{
u16 mac_address_H;
u32 mac_address_L;
void *driver_adapter = NULL;
struct halmac_api *halmac_api;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
driver_adapter = halmac_adapter->driver_adapter;
halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"[TRACE]%s ==========>\n", __func__);
if (halmac_port >= HALMAC_PORTIDMAX) {
pr_err("[ERR]port index > 5\n");
return HALMAC_RET_PORT_NOT_SUPPORT;
}
mac_address_L = le32_to_cpu(hal_address->address_l_h.le_address_low);
mac_address_H = le16_to_cpu(hal_address->address_l_h.le_address_high);
halmac_adapter->hal_mac_addr[halmac_port].address_l_h.address_low =
mac_address_L;
halmac_adapter->hal_mac_addr[halmac_port].address_l_h.address_high =
mac_address_H;
switch (halmac_port) {
case HALMAC_PORTID0:
HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID, mac_address_L);
HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID + 4,
mac_address_H);
break;
case HALMAC_PORTID1:
HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID1, mac_address_L);
HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID1 + 4,
mac_address_H);
break;
case HALMAC_PORTID2:
HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID2, mac_address_L);
HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID2 + 4,
mac_address_H);
break;
case HALMAC_PORTID3:
HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID3, mac_address_L);
HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID3 + 4,
mac_address_H);
break;
case HALMAC_PORTID4:
HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID4, mac_address_L);
HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID4 + 4,
mac_address_H);
break;
default:
break;
}
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"[TRACE]%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
/**
* halmac_cfg_bssid_88xx() - config BSSID
* @halmac_adapter : the adapter of halmac
* @halmac_port :0 for port0, 1 for port1, 2 for port2, 3 for port3, 4 for port4
* @hal_address : bssid
* Author : KaiYuan Chang/Ivan Lin
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_cfg_bssid_88xx(struct halmac_adapter *halmac_adapter, u8 halmac_port,
union halmac_wlan_addr *hal_address)
{
u16 bssid_address_H;
u32 bssid_address_L;
void *driver_adapter = NULL;
struct halmac_api *halmac_api;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
driver_adapter = halmac_adapter->driver_adapter;
halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"[TRACE]%s ==========>\n", __func__);
if (halmac_port >= HALMAC_PORTIDMAX) {
pr_err("[ERR]port index > 5\n");
return HALMAC_RET_PORT_NOT_SUPPORT;
}
bssid_address_L = le32_to_cpu(hal_address->address_l_h.le_address_low);
bssid_address_H = le16_to_cpu(hal_address->address_l_h.le_address_high);
halmac_adapter->hal_bss_addr[halmac_port].address_l_h.address_low =
bssid_address_L;
halmac_adapter->hal_bss_addr[halmac_port].address_l_h.address_high =
bssid_address_H;
switch (halmac_port) {
case HALMAC_PORTID0:
HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID, bssid_address_L);
HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID + 4,
bssid_address_H);
break;
case HALMAC_PORTID1:
HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID1,
bssid_address_L);
HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID1 + 4,
bssid_address_H);
break;
case HALMAC_PORTID2:
HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID2,
bssid_address_L);
HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID2 + 4,
bssid_address_H);
break;
case HALMAC_PORTID3:
HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID3,
bssid_address_L);
HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID3 + 4,
bssid_address_H);
break;
case HALMAC_PORTID4:
HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID4,
bssid_address_L);
HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID4 + 4,
bssid_address_H);
break;
default:
break;
}
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"[TRACE]%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
/**
* halmac_cfg_multicast_addr_88xx() - config multicast address
* @halmac_adapter : the adapter of halmac
* @hal_address : multicast address
* Author : KaiYuan Chang/Ivan Lin
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_cfg_multicast_addr_88xx(struct halmac_adapter *halmac_adapter,
union halmac_wlan_addr *hal_address)
{
u16 address_H;
u32 address_L;
void *driver_adapter = NULL;
struct halmac_api *halmac_api;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter,
HALMAC_API_CFG_MULTICAST_ADDR);
driver_adapter = halmac_adapter->driver_adapter;
halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s ==========>\n", __func__);
address_L = le32_to_cpu(hal_address->address_l_h.le_address_low);
address_H = le16_to_cpu(hal_address->address_l_h.le_address_high);
HALMAC_REG_WRITE_32(halmac_adapter, REG_MAR, address_L);
HALMAC_REG_WRITE_16(halmac_adapter, REG_MAR + 4, address_H);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
/**
* halmac_pre_init_system_cfg_88xx() - pre-init system config
* @halmac_adapter : the adapter of halmac
* Author : KaiYuan Chang/Ivan Lin
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_pre_init_system_cfg_88xx(struct halmac_adapter *halmac_adapter)
{
u32 value32, counter;
void *driver_adapter = NULL;
struct halmac_api *halmac_api;
bool enable_bb;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter,
HALMAC_API_PRE_INIT_SYSTEM_CFG);
driver_adapter = halmac_adapter->driver_adapter;
halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"halmac_pre_init_system_cfg ==========>\n");
if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
HALMAC_REG_WRITE_8(
halmac_adapter, REG_SDIO_HSUS_CTRL,
HALMAC_REG_READ_8(halmac_adapter, REG_SDIO_HSUS_CTRL) &
~(BIT(0)));
counter = 10000;
while (!(HALMAC_REG_READ_8(halmac_adapter, REG_SDIO_HSUS_CTRL) &
0x02)) {
counter--;
if (counter == 0)
return HALMAC_RET_SDIO_LEAVE_SUSPEND_FAIL;
}
} else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_USB) {
if (HALMAC_REG_READ_8(halmac_adapter, REG_SYS_CFG2 + 3) ==
0x20) /* usb3.0 */
HALMAC_REG_WRITE_8(
halmac_adapter, 0xFE5B,
HALMAC_REG_READ_8(halmac_adapter, 0xFE5B) |
BIT(4));
}
/* Config PIN Mux */
value32 = HALMAC_REG_READ_32(halmac_adapter, REG_PAD_CTRL1);
value32 = value32 & (~(BIT(28) | BIT(29)));
value32 = value32 | BIT(28) | BIT(29);
HALMAC_REG_WRITE_32(halmac_adapter, REG_PAD_CTRL1, value32);
value32 = HALMAC_REG_READ_32(halmac_adapter, REG_LED_CFG);
value32 = value32 & (~(BIT(25) | BIT(26)));
HALMAC_REG_WRITE_32(halmac_adapter, REG_LED_CFG, value32);
value32 = HALMAC_REG_READ_32(halmac_adapter, REG_GPIO_MUXCFG);
value32 = value32 & (~(BIT(2)));
value32 = value32 | BIT(2);
HALMAC_REG_WRITE_32(halmac_adapter, REG_GPIO_MUXCFG, value32);
enable_bb = false;
halmac_set_hw_value_88xx(halmac_adapter, HALMAC_HW_EN_BB_RF,
&enable_bb);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"halmac_pre_init_system_cfg <==========\n");
return HALMAC_RET_SUCCESS;
}
/**
* halmac_init_system_cfg_88xx() - init system config
* @halmac_adapter : the adapter of halmac
* Author : KaiYuan Chang/Ivan Lin
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_init_system_cfg_88xx(struct halmac_adapter *halmac_adapter)
{
void *driver_adapter = NULL;
struct halmac_api *halmac_api;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_SYSTEM_CFG);
driver_adapter = halmac_adapter->driver_adapter;
halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"halmac_init_system_cfg ==========>\n");
HALMAC_REG_WRITE_8(halmac_adapter, REG_SYS_FUNC_EN + 1,
HALMAC_FUNCTION_ENABLE_88XX);
HALMAC_REG_WRITE_32(
halmac_adapter, REG_SYS_SDIO_CTRL,
(u32)(HALMAC_REG_READ_32(halmac_adapter, REG_SYS_SDIO_CTRL) |
BIT_LTE_MUX_CTRL_PATH));
HALMAC_REG_WRITE_32(
halmac_adapter, REG_CPU_DMEM_CON,
(u32)(HALMAC_REG_READ_32(halmac_adapter, REG_CPU_DMEM_CON) |
BIT_WL_PLATFORM_RST));
/* halmac_api->halmac_init_h2c(halmac_adapter); */
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"halmac_init_system_cfg <==========\n");
return HALMAC_RET_SUCCESS;
}
/**
* halmac_init_edca_cfg_88xx() - init EDCA config
* @halmac_adapter : the adapter of halmac
* Author : KaiYuan Chang/Ivan Lin
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_init_edca_cfg_88xx(struct halmac_adapter *halmac_adapter)
{
u8 value8;
u32 value32;
void *driver_adapter = NULL;
struct halmac_api *halmac_api;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_EDCA_CFG);
driver_adapter = halmac_adapter->driver_adapter;
halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s ==========>\n", __func__);
/* Clear TX pause */
HALMAC_REG_WRITE_16(halmac_adapter, REG_TXPAUSE, 0x0000);
HALMAC_REG_WRITE_8(halmac_adapter, REG_SLOT, HALMAC_SLOT_TIME_88XX);
HALMAC_REG_WRITE_8(halmac_adapter, REG_PIFS, HALMAC_PIFS_TIME_88XX);
value32 = HALMAC_SIFS_CCK_CTX_88XX |
(HALMAC_SIFS_OFDM_CTX_88XX << BIT_SHIFT_SIFS_OFDM_CTX) |
(HALMAC_SIFS_CCK_TRX_88XX << BIT_SHIFT_SIFS_CCK_TRX) |
(HALMAC_SIFS_OFDM_TRX_88XX << BIT_SHIFT_SIFS_OFDM_TRX);
HALMAC_REG_WRITE_32(halmac_adapter, REG_SIFS, value32);
HALMAC_REG_WRITE_32(
halmac_adapter, REG_EDCA_VO_PARAM,
HALMAC_REG_READ_32(halmac_adapter, REG_EDCA_VO_PARAM) & 0xFFFF);
HALMAC_REG_WRITE_16(halmac_adapter, REG_EDCA_VO_PARAM + 2,
HALMAC_VO_TXOP_LIMIT_88XX);
HALMAC_REG_WRITE_16(halmac_adapter, REG_EDCA_VI_PARAM + 2,
HALMAC_VI_TXOP_LIMIT_88XX);
HALMAC_REG_WRITE_32(halmac_adapter, REG_RD_NAV_NXT,
HALMAC_RDG_NAV_88XX | (HALMAC_TXOP_NAV_88XX << 16));
HALMAC_REG_WRITE_16(halmac_adapter, REG_RXTSF_OFFSET_CCK,
HALMAC_CCK_RX_TSF_88XX |
(HALMAC_OFDM_RX_TSF_88XX) << 8);
value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RD_CTRL + 1);
value8 |=
(BIT_VOQ_RD_INIT_EN | BIT_VIQ_RD_INIT_EN | BIT_BEQ_RD_INIT_EN);
HALMAC_REG_WRITE_8(halmac_adapter, REG_RD_CTRL + 1, value8);
/* Set beacon cotnrol - enable TSF and other related functions */
HALMAC_REG_WRITE_8(
halmac_adapter, REG_BCN_CTRL,
(u8)(HALMAC_REG_READ_8(halmac_adapter, REG_BCN_CTRL) |
BIT_EN_BCN_FUNCTION));
/* Set send beacon related registers */
HALMAC_REG_WRITE_32(halmac_adapter, REG_TBTT_PROHIBIT,
HALMAC_TBTT_PROHIBIT_88XX |
(HALMAC_TBTT_HOLD_TIME_88XX
<< BIT_SHIFT_TBTT_HOLD_TIME_AP));
HALMAC_REG_WRITE_8(halmac_adapter, REG_DRVERLYINT,
HALMAC_DRIVER_EARLY_INT_88XX);
HALMAC_REG_WRITE_8(halmac_adapter, REG_BCNDMATIM,
HALMAC_BEACON_DMA_TIM_88XX);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
/**
* halmac_init_wmac_cfg_88xx() - init wmac config
* @halmac_adapter : the adapter of halmac
* Author : KaiYuan Chang/Ivan Lin
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_init_wmac_cfg_88xx(struct halmac_adapter *halmac_adapter)
{
void *driver_adapter = NULL;
struct halmac_api *halmac_api;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_WMAC_CFG);
driver_adapter = halmac_adapter->driver_adapter;
halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s ==========>\n", __func__);
HALMAC_REG_WRITE_32(halmac_adapter, REG_RXFLTMAP0,
HALMAC_RX_FILTER0_88XX);
HALMAC_REG_WRITE_16(halmac_adapter, REG_RXFLTMAP,
HALMAC_RX_FILTER_88XX);
HALMAC_REG_WRITE_32(halmac_adapter, REG_RCR, HALMAC_RCR_CONFIG_88XX);
HALMAC_REG_WRITE_8(
halmac_adapter, REG_TCR + 1,
(u8)(HALMAC_REG_READ_8(halmac_adapter, REG_TCR + 1) | 0x30));
HALMAC_REG_WRITE_8(halmac_adapter, REG_TCR + 2, 0x30);
HALMAC_REG_WRITE_8(halmac_adapter, REG_TCR + 1, 0x00);
HALMAC_REG_WRITE_32(halmac_adapter, REG_WMAC_OPTION_FUNCTION + 8,
0x30810041);
HALMAC_REG_WRITE_32(halmac_adapter, REG_WMAC_OPTION_FUNCTION + 4,
0x50802080);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
/**
* halmac_init_mac_cfg_88xx() - config page1~page7 register
* @halmac_adapter : the adapter of halmac
* @mode : trx mode
* Author : KaiYuan Chang/Ivan Lin
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_init_mac_cfg_88xx(struct halmac_adapter *halmac_adapter,
enum halmac_trx_mode mode)
{
void *driver_adapter = NULL;
struct halmac_api *halmac_api;
enum halmac_ret_status status = HALMAC_RET_SUCCESS;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_MAC_CFG);
driver_adapter = halmac_adapter->driver_adapter;
halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s ==========>mode = %d\n", __func__,
mode);
status = halmac_api->halmac_init_trx_cfg(halmac_adapter, mode);
if (status != HALMAC_RET_SUCCESS) {
pr_err("halmac_init_trx_cfg error = %x\n", status);
return status;
}
status = halmac_api->halmac_init_protocol_cfg(halmac_adapter);
if (status != HALMAC_RET_SUCCESS) {
pr_err("halmac_init_protocol_cfg_88xx error = %x\n", status);
return status;
}
status = halmac_init_edca_cfg_88xx(halmac_adapter);
if (status != HALMAC_RET_SUCCESS) {
pr_err("halmac_init_edca_cfg_88xx error = %x\n", status);
return status;
}
status = halmac_init_wmac_cfg_88xx(halmac_adapter);
if (status != HALMAC_RET_SUCCESS) {
pr_err("halmac_init_wmac_cfg_88xx error = %x\n", status);
return status;
}
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s <==========\n", __func__);
return status;
}
/**
* halmac_cfg_operation_mode_88xx() - config operation mode
* @halmac_adapter : the adapter of halmac
* @wireless_mode : 802.11 standard(b/g/n/ac)
* Author : KaiYuan Chang/Ivan Lin
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_cfg_operation_mode_88xx(struct halmac_adapter *halmac_adapter,
enum halmac_wireless_mode wireless_mode)
{
void *driver_adapter = NULL;
enum halmac_wireless_mode wireless_mode_local =
HALMAC_WIRELESS_MODE_UNDEFINE;
wireless_mode_local = wireless_mode;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter,
HALMAC_API_CFG_OPERATION_MODE);
driver_adapter = halmac_adapter->driver_adapter;
HALMAC_RT_TRACE(
driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s ==========>wireless_mode = %d\n", __func__,
wireless_mode);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
/**
* halmac_cfg_ch_bw_88xx() - config channel & bandwidth
* @halmac_adapter : the adapter of halmac
* @channel : WLAN channel, support 2.4G & 5G
* @pri_ch_idx : primary channel index, idx1, idx2, idx3, idx4
* @bw : band width, 20, 40, 80, 160, 5 ,10
* Author : KaiYuan Chang
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_cfg_ch_bw_88xx(struct halmac_adapter *halmac_adapter, u8 channel,
enum halmac_pri_ch_idx pri_ch_idx, enum halmac_bw bw)
{
void *driver_adapter = NULL;
struct halmac_api *halmac_api;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_CH_BW);
driver_adapter = halmac_adapter->driver_adapter;
halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s ==========>ch = %d, idx=%d, bw=%d\n", __func__,
channel, pri_ch_idx, bw);
halmac_cfg_pri_ch_idx_88xx(halmac_adapter, pri_ch_idx);
halmac_cfg_bw_88xx(halmac_adapter, bw);
halmac_cfg_ch_88xx(halmac_adapter, channel);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
enum halmac_ret_status halmac_cfg_ch_88xx(struct halmac_adapter *halmac_adapter,
u8 channel)
{
u8 value8;
void *driver_adapter = NULL;
struct halmac_api *halmac_api;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_CH_BW);
driver_adapter = halmac_adapter->driver_adapter;
halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s ==========>ch = %d\n", __func__, channel);
value8 = HALMAC_REG_READ_8(halmac_adapter, REG_CCK_CHECK);
value8 = value8 & (~(BIT(7)));
if (channel > 35)
value8 = value8 | BIT(7);
HALMAC_REG_WRITE_8(halmac_adapter, REG_CCK_CHECK, value8);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
enum halmac_ret_status
halmac_cfg_pri_ch_idx_88xx(struct halmac_adapter *halmac_adapter,
enum halmac_pri_ch_idx pri_ch_idx)
{
u8 txsc_40 = 0, txsc_20 = 0;
void *driver_adapter = NULL;
struct halmac_api *halmac_api;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_CH_BW);
driver_adapter = halmac_adapter->driver_adapter;
halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s ==========> idx=%d\n", __func__,
pri_ch_idx);
txsc_20 = pri_ch_idx;
if (txsc_20 == HALMAC_CH_IDX_1 || txsc_20 == HALMAC_CH_IDX_3)
txsc_40 = 9;
else
txsc_40 = 10;
HALMAC_REG_WRITE_8(halmac_adapter, REG_DATA_SC,
BIT_TXSC_20M(txsc_20) | BIT_TXSC_40M(txsc_40));
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
/**
* halmac_cfg_bw_88xx() - config bandwidth
* @halmac_adapter : the adapter of halmac
* @bw : band width, 20, 40, 80, 160, 5 ,10
* Author : KaiYuan Chang
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status halmac_cfg_bw_88xx(struct halmac_adapter *halmac_adapter,
enum halmac_bw bw)
{
u32 value32;
void *driver_adapter = NULL;
struct halmac_api *halmac_api;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_BW);
driver_adapter = halmac_adapter->driver_adapter;
halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s ==========>bw=%d\n", __func__, bw);
/* RF mode */
value32 = HALMAC_REG_READ_32(halmac_adapter, REG_WMAC_TRXPTCL_CTL);
value32 = value32 & (~(BIT(7) | BIT(8)));
switch (bw) {
case HALMAC_BW_80:
value32 = value32 | BIT(7);
break;
case HALMAC_BW_40:
value32 = value32 | BIT(8);
break;
case HALMAC_BW_20:
case HALMAC_BW_10:
case HALMAC_BW_5:
break;
default:
pr_err("%s switch case not support\n", __func__);
break;
}
HALMAC_REG_WRITE_32(halmac_adapter, REG_WMAC_TRXPTCL_CTL, value32);
/* MAC CLK */
value32 = HALMAC_REG_READ_32(halmac_adapter, REG_AFE_CTRL1);
value32 = (value32 & (~(BIT(20) | BIT(21)))) |
(HALMAC_MAC_CLOCK_HW_DEF_80M << BIT_SHIFT_MAC_CLK_SEL);
HALMAC_REG_WRITE_32(halmac_adapter, REG_AFE_CTRL1, value32);
HALMAC_REG_WRITE_8(halmac_adapter, REG_USTIME_TSF,
HALMAC_MAC_CLOCK_88XX);
HALMAC_REG_WRITE_8(halmac_adapter, REG_USTIME_EDCA,
HALMAC_MAC_CLOCK_88XX);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
/**
* halmac_dump_efuse_map_88xx() - dump "physical" efuse map
* @halmac_adapter : the adapter of halmac
* @cfg : dump efuse method
* Author : Ivan Lin/KaiYuan Chang
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_dump_efuse_map_88xx(struct halmac_adapter *halmac_adapter,
enum halmac_efuse_read_cfg cfg)
{
void *driver_adapter = NULL;
enum halmac_ret_status status = HALMAC_RET_SUCCESS;
enum halmac_cmd_process_status *process_status =
&halmac_adapter->halmac_state.efuse_state_set.process_status;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DUMP_EFUSE_MAP);
driver_adapter = halmac_adapter->driver_adapter;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s ==========>cfg=%d\n", __func__, cfg);
if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"Wait event(dump efuse)...\n");
return HALMAC_RET_BUSY_STATE;
}
if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"Not idle state(dump efuse)...\n");
return HALMAC_RET_ERROR_STATE;
}
if (halmac_adapter->halmac_state.mac_power == HALMAC_MAC_POWER_OFF)
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_WARNING,
"[WARN]Dump efuse in suspend mode\n");
*process_status = HALMAC_CMD_PROCESS_IDLE;
halmac_adapter->event_trigger.physical_efuse_map = 1;
status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
HALMAC_EFUSE_BANK_WIFI);
if (status != HALMAC_RET_SUCCESS) {
pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
return status;
}
status = halmac_dump_efuse_88xx(halmac_adapter, cfg);
if (status != HALMAC_RET_SUCCESS) {
pr_err("halmac_read_efuse error = %x\n", status);
return status;
}
if (halmac_adapter->hal_efuse_map_valid) {
*process_status = HALMAC_CMD_PROCESS_DONE;
PLATFORM_EVENT_INDICATION(
driver_adapter, HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE,
*process_status, halmac_adapter->hal_efuse_map,
halmac_adapter->hw_config_info.efuse_size);
halmac_adapter->event_trigger.physical_efuse_map = 0;
}
if (halmac_transition_efuse_state_88xx(
halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
HALMAC_RET_SUCCESS)
return HALMAC_RET_ERROR_STATE;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
/**
* halmac_dump_efuse_map_bt_88xx() - dump "BT physical" efuse map
* @halmac_adapter : the adapter of halmac
* @halmac_efuse_bank : bt efuse bank
* @bt_efuse_map_size : bt efuse map size. get from halmac_get_efuse_size API
* @bt_efuse_map : bt efuse map
* Author : Soar / Ivan Lin
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_dump_efuse_map_bt_88xx(struct halmac_adapter *halmac_adapter,
enum halmac_efuse_bank halmac_efuse_bank,
u32 bt_efuse_map_size, u8 *bt_efuse_map)
{
void *driver_adapter = NULL;
enum halmac_ret_status status = HALMAC_RET_SUCCESS;
enum halmac_cmd_process_status *process_status =
&halmac_adapter->halmac_state.efuse_state_set.process_status;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DUMP_EFUSE_MAP_BT);
driver_adapter = halmac_adapter->driver_adapter;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s ==========>\n", __func__);
if (halmac_adapter->hw_config_info.bt_efuse_size != bt_efuse_map_size)
return HALMAC_RET_EFUSE_SIZE_INCORRECT;
if ((halmac_efuse_bank >= HALMAC_EFUSE_BANK_MAX) ||
halmac_efuse_bank == HALMAC_EFUSE_BANK_WIFI) {
pr_err("Undefined BT bank\n");
return HALMAC_RET_EFUSE_BANK_INCORRECT;
}
if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"Wait event(dump efuse)...\n");
return HALMAC_RET_BUSY_STATE;
}
if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"Not idle state(dump efuse)...\n");
return HALMAC_RET_ERROR_STATE;
}
status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
halmac_efuse_bank);
if (status != HALMAC_RET_SUCCESS) {
pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
return status;
}
status = halmac_read_hw_efuse_88xx(halmac_adapter, 0, bt_efuse_map_size,
bt_efuse_map);
if (status != HALMAC_RET_SUCCESS) {
pr_err("halmac_read_hw_efuse_88xx error = %x\n", status);
return status;
}
if (halmac_transition_efuse_state_88xx(
halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
HALMAC_RET_SUCCESS)
return HALMAC_RET_ERROR_STATE;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
/**
* halmac_write_efuse_bt_88xx() - write "BT physical" efuse offset
* @halmac_adapter : the adapter of halmac
* @halmac_offset : offset
* @halmac_value : Write value
* @bt_efuse_map : bt efuse map
* Author : Soar
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_write_efuse_bt_88xx(struct halmac_adapter *halmac_adapter,
u32 halmac_offset, u8 halmac_value,
enum halmac_efuse_bank halmac_efuse_bank)
{
void *driver_adapter = NULL;
enum halmac_ret_status status = HALMAC_RET_SUCCESS;
enum halmac_cmd_process_status *process_status =
&halmac_adapter->halmac_state.efuse_state_set.process_status;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_WRITE_EFUSE_BT);
driver_adapter = halmac_adapter->driver_adapter;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
"%s ==========>\n", __func__);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
"offset : %X value : %X Bank : %X\n", halmac_offset,
halmac_value, halmac_efuse_bank);
if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"Wait/Rcvd event(dump efuse)...\n");
return HALMAC_RET_BUSY_STATE;
}
if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"Not idle state(dump efuse)...\n");
return HALMAC_RET_ERROR_STATE;
}
if (halmac_offset >= halmac_adapter->hw_config_info.efuse_size) {
pr_err("Offset is too large\n");
return HALMAC_RET_EFUSE_SIZE_INCORRECT;
}
if (halmac_efuse_bank > HALMAC_EFUSE_BANK_MAX ||
halmac_efuse_bank == HALMAC_EFUSE_BANK_WIFI) {
pr_err("Undefined BT bank\n");
return HALMAC_RET_EFUSE_BANK_INCORRECT;
}
status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
halmac_efuse_bank);
if (status != HALMAC_RET_SUCCESS) {
pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
return status;
}
status = halmac_func_write_efuse_88xx(halmac_adapter, halmac_offset,
halmac_value);
if (status != HALMAC_RET_SUCCESS) {
pr_err("halmac_func_write_efuse error = %x\n", status);
return status;
}
if (halmac_transition_efuse_state_88xx(
halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
HALMAC_RET_SUCCESS)
return HALMAC_RET_ERROR_STATE;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
/**
* halmac_get_efuse_available_size_88xx() - get efuse available size
* @halmac_adapter : the adapter of halmac
* @halmac_size : physical efuse available size
* Author : Soar
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_get_efuse_available_size_88xx(struct halmac_adapter *halmac_adapter,
u32 *halmac_size)
{
enum halmac_ret_status status;
void *driver_adapter = NULL;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
driver_adapter = halmac_adapter->driver_adapter;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
"%s ==========>\n", __func__);
status = halmac_dump_logical_efuse_map_88xx(halmac_adapter,
HALMAC_EFUSE_R_DRV);
if (status != HALMAC_RET_SUCCESS)
return status;
*halmac_size = halmac_adapter->hw_config_info.efuse_size -
HALMAC_PROTECTED_EFUSE_SIZE_88XX -
halmac_adapter->efuse_end;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
/**
* halmac_get_efuse_size_88xx() - get "physical" efuse size
* @halmac_adapter : the adapter of halmac
* @halmac_size : physical efuse size
* Author : Ivan Lin/KaiYuan Chang
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_get_efuse_size_88xx(struct halmac_adapter *halmac_adapter,
u32 *halmac_size)
{
void *driver_adapter = NULL;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_GET_EFUSE_SIZE);
driver_adapter = halmac_adapter->driver_adapter;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
"%s ==========>\n", __func__);
*halmac_size = halmac_adapter->hw_config_info.efuse_size;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
/**
* halmac_get_logical_efuse_size_88xx() - get "logical" efuse size
* @halmac_adapter : the adapter of halmac
* @halmac_size : logical efuse size
* Author : Ivan Lin/KaiYuan Chang
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_get_logical_efuse_size_88xx(struct halmac_adapter *halmac_adapter,
u32 *halmac_size)
{
void *driver_adapter = NULL;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter,
HALMAC_API_GET_LOGICAL_EFUSE_SIZE);
driver_adapter = halmac_adapter->driver_adapter;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
"%s ==========>\n", __func__);
*halmac_size = halmac_adapter->hw_config_info.eeprom_size;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
/**
* halmac_dump_logical_efuse_map_88xx() - dump "logical" efuse map
* @halmac_adapter : the adapter of halmac
* @cfg : dump efuse method
* Author : Soar
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_dump_logical_efuse_map_88xx(struct halmac_adapter *halmac_adapter,
enum halmac_efuse_read_cfg cfg)
{
u8 *eeprom_map = NULL;
u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
void *driver_adapter = NULL;
enum halmac_ret_status status = HALMAC_RET_SUCCESS;
enum halmac_cmd_process_status *process_status =
&halmac_adapter->halmac_state.efuse_state_set.process_status;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter,
HALMAC_API_DUMP_LOGICAL_EFUSE_MAP);
driver_adapter = halmac_adapter->driver_adapter;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
"%s ==========>cfg = %d\n", __func__, cfg);
if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"Wait/Rcvd event(dump efuse)...\n");
return HALMAC_RET_BUSY_STATE;
}
if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"Not idle state(dump efuse)...\n");
return HALMAC_RET_ERROR_STATE;
}
if (halmac_adapter->halmac_state.mac_power == HALMAC_MAC_POWER_OFF)
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_WARNING,
"[WARN]Dump logical efuse in suspend mode\n");
*process_status = HALMAC_CMD_PROCESS_IDLE;
halmac_adapter->event_trigger.logical_efuse_map = 1;
status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
HALMAC_EFUSE_BANK_WIFI);
if (status != HALMAC_RET_SUCCESS) {
pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
return status;
}
status = halmac_dump_efuse_88xx(halmac_adapter, cfg);
if (status != HALMAC_RET_SUCCESS) {
pr_err("halmac_eeprom_parser_88xx error = %x\n", status);
return status;
}
if (halmac_adapter->hal_efuse_map_valid) {
*process_status = HALMAC_CMD_PROCESS_DONE;
eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
if (!eeprom_map) {
/* out of memory */
return HALMAC_RET_MALLOC_FAIL;
}
memset(eeprom_map, 0xFF, eeprom_size);
if (halmac_eeprom_parser_88xx(halmac_adapter,
halmac_adapter->hal_efuse_map,
eeprom_map) != HALMAC_RET_SUCCESS) {
kfree(eeprom_map);
return HALMAC_RET_EEPROM_PARSING_FAIL;
}
PLATFORM_EVENT_INDICATION(
driver_adapter, HALMAC_FEATURE_DUMP_LOGICAL_EFUSE,
*process_status, eeprom_map, eeprom_size);
halmac_adapter->event_trigger.logical_efuse_map = 0;
kfree(eeprom_map);
}
if (halmac_transition_efuse_state_88xx(
halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
HALMAC_RET_SUCCESS)
return HALMAC_RET_ERROR_STATE;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
/**
* halmac_read_logical_efuse_88xx() - read logical efuse map 1 byte
* @halmac_adapter : the adapter of halmac
* @halmac_offset : offset
* @value : 1 byte efuse value
* Author : Soar
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_read_logical_efuse_88xx(struct halmac_adapter *halmac_adapter,
u32 halmac_offset, u8 *value)
{
u8 *eeprom_map = NULL;
u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
void *driver_adapter = NULL;
enum halmac_ret_status status = HALMAC_RET_SUCCESS;
enum halmac_cmd_process_status *process_status =
&halmac_adapter->halmac_state.efuse_state_set.process_status;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter,
HALMAC_API_READ_LOGICAL_EFUSE);
driver_adapter = halmac_adapter->driver_adapter;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
"%s ==========>\n", __func__);
if (halmac_offset >= eeprom_size) {
pr_err("Offset is too large\n");
return HALMAC_RET_EFUSE_SIZE_INCORRECT;
}
if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"Wait/Rcvd event(dump efuse)...\n");
return HALMAC_RET_BUSY_STATE;
}
if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"Not idle state(dump efuse)...\n");
return HALMAC_RET_ERROR_STATE;
}
status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
HALMAC_EFUSE_BANK_WIFI);
if (status != HALMAC_RET_SUCCESS) {
pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
return status;
}
eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
if (!eeprom_map) {
/* out of memory */
return HALMAC_RET_MALLOC_FAIL;
}
memset(eeprom_map, 0xFF, eeprom_size);
status = halmac_read_logical_efuse_map_88xx(halmac_adapter, eeprom_map);
if (status != HALMAC_RET_SUCCESS) {
pr_err("halmac_read_logical_efuse_map error = %x\n", status);
kfree(eeprom_map);
return status;
}
*value = *(eeprom_map + halmac_offset);
if (halmac_transition_efuse_state_88xx(
halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
HALMAC_RET_SUCCESS) {
kfree(eeprom_map);
return HALMAC_RET_ERROR_STATE;
}
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
"%s <==========\n", __func__);
kfree(eeprom_map);
return HALMAC_RET_SUCCESS;
}
/**
* halmac_write_logical_efuse_88xx() - write "logical" efuse offset
* @halmac_adapter : the adapter of halmac
* @halmac_offset : offset
* @halmac_value : value
* Author : Soar
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_write_logical_efuse_88xx(struct halmac_adapter *halmac_adapter,
u32 halmac_offset, u8 halmac_value)
{
void *driver_adapter = NULL;
struct halmac_api *halmac_api;
enum halmac_ret_status status = HALMAC_RET_SUCCESS;
enum halmac_cmd_process_status *process_status =
&halmac_adapter->halmac_state.efuse_state_set.process_status;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter,
HALMAC_API_WRITE_LOGICAL_EFUSE);
driver_adapter = halmac_adapter->driver_adapter;
halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
"%s ==========>\n", __func__);
if (halmac_offset >= halmac_adapter->hw_config_info.eeprom_size) {
pr_err("Offset is too large\n");
return HALMAC_RET_EFUSE_SIZE_INCORRECT;
}
if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"Wait/Rcvd event(dump efuse)...\n");
return HALMAC_RET_BUSY_STATE;
}
if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"Not idle state(dump efuse)...\n");
return HALMAC_RET_ERROR_STATE;
}
status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
HALMAC_EFUSE_BANK_WIFI);
if (status != HALMAC_RET_SUCCESS) {
pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
return status;
}
status = halmac_func_write_logical_efuse_88xx(
halmac_adapter, halmac_offset, halmac_value);
if (status != HALMAC_RET_SUCCESS) {
pr_err("halmac_write_logical_efuse error = %x\n", status);
return status;
}
if (halmac_transition_efuse_state_88xx(
halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
HALMAC_RET_SUCCESS)
return HALMAC_RET_ERROR_STATE;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
/**
* halmac_pg_efuse_by_map_88xx() - pg logical efuse by map
* @halmac_adapter : the adapter of halmac
* @pg_efuse_info : efuse map information
* @cfg : dump efuse method
* Author : Soar
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_pg_efuse_by_map_88xx(struct halmac_adapter *halmac_adapter,
struct halmac_pg_efuse_info *pg_efuse_info,
enum halmac_efuse_read_cfg cfg)
{
void *driver_adapter = NULL;
enum halmac_ret_status status = HALMAC_RET_SUCCESS;
enum halmac_cmd_process_status *process_status =
&halmac_adapter->halmac_state.efuse_state_set.process_status;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_PG_EFUSE_BY_MAP);
driver_adapter = halmac_adapter->driver_adapter;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
"%s ==========>\n", __func__);
if (pg_efuse_info->efuse_map_size !=
halmac_adapter->hw_config_info.eeprom_size) {
pr_err("efuse_map_size is incorrect, should be %d bytes\n",
halmac_adapter->hw_config_info.eeprom_size);
return HALMAC_RET_EFUSE_SIZE_INCORRECT;
}
if ((pg_efuse_info->efuse_map_size & 0xF) > 0) {
pr_err("efuse_map_size should be multiple of 16\n");
return HALMAC_RET_EFUSE_SIZE_INCORRECT;
}
if (pg_efuse_info->efuse_mask_size !=
pg_efuse_info->efuse_map_size >> 4) {
pr_err("efuse_mask_size is incorrect, should be %d bytes\n",
pg_efuse_info->efuse_map_size >> 4);
return HALMAC_RET_EFUSE_SIZE_INCORRECT;
}
if (!pg_efuse_info->efuse_map) {
pr_err("efuse_map is NULL\n");
return HALMAC_RET_NULL_POINTER;
}
if (!pg_efuse_info->efuse_mask) {
pr_err("efuse_mask is NULL\n");
return HALMAC_RET_NULL_POINTER;
}
if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"Wait/Rcvd event(dump efuse)...\n");
return HALMAC_RET_BUSY_STATE;
}
if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"Not idle state(dump efuse)...\n");
return HALMAC_RET_ERROR_STATE;
}
status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
HALMAC_EFUSE_BANK_WIFI);
if (status != HALMAC_RET_SUCCESS) {
pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
return status;
}
status = halmac_func_pg_efuse_by_map_88xx(halmac_adapter, pg_efuse_info,
cfg);
if (status != HALMAC_RET_SUCCESS) {
pr_err("halmac_pg_efuse_by_map error = %x\n", status);
return status;
}
if (halmac_transition_efuse_state_88xx(
halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
HALMAC_RET_SUCCESS)
return HALMAC_RET_ERROR_STATE;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
/**
* halmac_get_c2h_info_88xx() - process halmac C2H packet
* @halmac_adapter : the adapter of halmac
* @halmac_buf : RX Packet pointer
* @halmac_size : RX Packet size
* Author : KaiYuan Chang/Ivan Lin
*
* Used to process c2h packet info from RX path. After receiving the packet,
* user need to call this api and pass the packet pointer.
*
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_get_c2h_info_88xx(struct halmac_adapter *halmac_adapter, u8 *halmac_buf,
u32 halmac_size)
{
void *driver_adapter = NULL;
enum halmac_ret_status status = HALMAC_RET_SUCCESS;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_GET_C2H_INFO);
driver_adapter = halmac_adapter->driver_adapter;
/* Check if it is C2H packet */
if (GET_RX_DESC_C2H(halmac_buf)) {
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
"C2H packet, start parsing!\n");
status = halmac_parse_c2h_packet_88xx(halmac_adapter,
halmac_buf, halmac_size);
if (status != HALMAC_RET_SUCCESS) {
pr_err("halmac_parse_c2h_packet_88xx error = %x\n",
status);
return status;
}
}
return HALMAC_RET_SUCCESS;
}
enum halmac_ret_status
halmac_cfg_fwlps_option_88xx(struct halmac_adapter *halmac_adapter,
struct halmac_fwlps_option *lps_option)
{
void *driver_adapter = NULL;
struct halmac_fwlps_option *hal_fwlps_option;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_FWLPS_OPTION);
driver_adapter = halmac_adapter->driver_adapter;
hal_fwlps_option = &halmac_adapter->fwlps_option;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
"%s ==========>\n", __func__);
hal_fwlps_option->mode = lps_option->mode;
hal_fwlps_option->clk_request = lps_option->clk_request;
hal_fwlps_option->rlbm = lps_option->rlbm;
hal_fwlps_option->smart_ps = lps_option->smart_ps;
hal_fwlps_option->awake_interval = lps_option->awake_interval;
hal_fwlps_option->all_queue_uapsd = lps_option->all_queue_uapsd;
hal_fwlps_option->pwr_state = lps_option->pwr_state;
hal_fwlps_option->low_pwr_rx_beacon = lps_option->low_pwr_rx_beacon;
hal_fwlps_option->ant_auto_switch = lps_option->ant_auto_switch;
hal_fwlps_option->ps_allow_bt_high_priority =
lps_option->ps_allow_bt_high_priority;
hal_fwlps_option->protect_bcn = lps_option->protect_bcn;
hal_fwlps_option->silence_period = lps_option->silence_period;
hal_fwlps_option->fast_bt_connect = lps_option->fast_bt_connect;
hal_fwlps_option->two_antenna_en = lps_option->two_antenna_en;
hal_fwlps_option->adopt_user_setting = lps_option->adopt_user_setting;
hal_fwlps_option->drv_bcn_early_shift = lps_option->drv_bcn_early_shift;
hal_fwlps_option->enter_32K = lps_option->enter_32K;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
enum halmac_ret_status
halmac_cfg_fwips_option_88xx(struct halmac_adapter *halmac_adapter,
struct halmac_fwips_option *ips_option)
{
void *driver_adapter = NULL;
struct halmac_fwips_option *ips_option_local;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_FWIPS_OPTION);
driver_adapter = halmac_adapter->driver_adapter;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
"%s ==========>\n", __func__);
ips_option_local = ips_option;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
enum halmac_ret_status
halmac_enter_wowlan_88xx(struct halmac_adapter *halmac_adapter,
struct halmac_wowlan_option *wowlan_option)
{
void *driver_adapter = NULL;
struct halmac_wowlan_option *wowlan_option_local;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_ENTER_WOWLAN);
driver_adapter = halmac_adapter->driver_adapter;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
"%s ==========>\n", __func__);
wowlan_option_local = wowlan_option;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
enum halmac_ret_status
halmac_leave_wowlan_88xx(struct halmac_adapter *halmac_adapter)
{
void *driver_adapter = NULL;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_LEAVE_WOWLAN);
driver_adapter = halmac_adapter->driver_adapter;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
"%s ==========>\n", __func__);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
enum halmac_ret_status
halmac_enter_ps_88xx(struct halmac_adapter *halmac_adapter,
enum halmac_ps_state ps_state)
{
u8 rpwm;
void *driver_adapter = NULL;
struct halmac_api *halmac_api;
enum halmac_ret_status status = HALMAC_RET_SUCCESS;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_NO_DLFW;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_ENTER_PS);
driver_adapter = halmac_adapter->driver_adapter;
halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
"%s ==========>\n", __func__);
if (ps_state == halmac_adapter->halmac_state.ps_state) {
pr_err("power state is already in PS State!!\n");
return HALMAC_RET_SUCCESS;
}
if (ps_state == HALMAC_PS_STATE_LPS) {
status = halmac_send_h2c_set_pwr_mode_88xx(
halmac_adapter, &halmac_adapter->fwlps_option);
if (status != HALMAC_RET_SUCCESS) {
pr_err("halmac_send_h2c_set_pwr_mode_88xx error = %x!!\n",
status);
return status;
}
} else if (ps_state == HALMAC_PS_STATE_IPS) {
}
halmac_adapter->halmac_state.ps_state = ps_state;
/* Enter 32K */
if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
if (halmac_adapter->fwlps_option.enter_32K) {
rpwm = (u8)(((halmac_adapter->rpwm_record ^ (BIT(7))) |
(BIT(0))) &
0x81);
HALMAC_REG_WRITE_8(halmac_adapter, REG_SDIO_HRPWM1,
rpwm);
halmac_adapter->low_clk = true;
}
} else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_USB) {
if (halmac_adapter->fwlps_option.enter_32K) {
rpwm = (u8)(((halmac_adapter->rpwm_record ^ (BIT(7))) |
(BIT(0))) &
0x81);
HALMAC_REG_WRITE_8(halmac_adapter, 0xFE58, rpwm);
halmac_adapter->low_clk = true;
}
}
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
enum halmac_ret_status
halmac_leave_ps_88xx(struct halmac_adapter *halmac_adapter)
{
u8 rpwm, cpwm;
u32 counter;
void *driver_adapter = NULL;
struct halmac_api *halmac_api;
struct halmac_fwlps_option fw_lps_option;
enum halmac_ret_status status = HALMAC_RET_SUCCESS;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_NO_DLFW;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_LEAVE_PS);
driver_adapter = halmac_adapter->driver_adapter;
halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
"%s ==========>\n", __func__);
if (halmac_adapter->halmac_state.ps_state == HALMAC_PS_STATE_ACT) {
pr_err("power state is already in active!!\n");
return HALMAC_RET_SUCCESS;
}
if (halmac_adapter->low_clk) {
cpwm = HALMAC_REG_READ_8(halmac_adapter, REG_SDIO_HRPWM1);
rpwm = (u8)(
((halmac_adapter->rpwm_record ^ (BIT(7))) | (BIT(6))) &
0xC0);
HALMAC_REG_WRITE_8(halmac_adapter, REG_SDIO_HRPWM1, rpwm);
cpwm = (u8)((cpwm ^ BIT(7)) & BIT(7));
counter = 100;
while (cpwm !=
(HALMAC_REG_READ_8(halmac_adapter, REG_SDIO_HRPWM1) &
BIT(7))) {
usleep_range(50, 60);
counter--;
if (counter == 0)
return HALMAC_RET_CHANGE_PS_FAIL;
}
halmac_adapter->low_clk = false;
}
memcpy(&fw_lps_option, &halmac_adapter->fwlps_option,
sizeof(struct halmac_fwlps_option));
fw_lps_option.mode = 0;
status = halmac_send_h2c_set_pwr_mode_88xx(halmac_adapter,
&fw_lps_option);
if (status != HALMAC_RET_SUCCESS) {
pr_err("halmac_send_h2c_set_pwr_mode_88xx error!!=%x\n",
status);
return status;
}
halmac_adapter->halmac_state.ps_state = HALMAC_PS_STATE_ACT;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
/**
* (debug API)halmac_h2c_lb_88xx() - send h2c loopback packet
* @halmac_adapter : the adapter of halmac
* Author : KaiYuan Chang/Ivan Lin
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status halmac_h2c_lb_88xx(struct halmac_adapter *halmac_adapter)
{
void *driver_adapter = NULL;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_H2C_LB);
driver_adapter = halmac_adapter->driver_adapter;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
"%s ==========>\n", __func__);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
/**
* halmac_debug_88xx() - dump information for debugging
* @halmac_adapter : the adapter of halmac
* Author : KaiYuan Chang/Ivan Lin
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status halmac_debug_88xx(struct halmac_adapter *halmac_adapter)
{
u8 temp8 = 0;
u32 i = 0, temp32 = 0;
void *driver_adapter = NULL;
struct halmac_api *halmac_api;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DEBUG);
driver_adapter = halmac_adapter->driver_adapter;
halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s ==========>\n", __func__);
if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
/* Dump CCCR, it needs new platform api */
/*Dump SDIO Local Register, use CMD52*/
for (i = 0x10250000; i < 0x102500ff; i++) {
temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
HALMAC_RT_TRACE(
driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"halmac_debug: sdio[%x]=%x\n", i, temp8);
}
/*Dump MAC Register*/
for (i = 0x0000; i < 0x17ff; i++) {
temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
DBG_DMESG, "halmac_debug: mac[%x]=%x\n",
i, temp8);
}
/*Check RX Fifo status*/
i = REG_RXFF_PTR_V1;
temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"halmac_debug: mac[%x]=%x\n", i, temp8);
i = REG_RXFF_WTR_V1;
temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"halmac_debug: mac[%x]=%x\n", i, temp8);
i = REG_RXFF_PTR_V1;
temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"halmac_debug: mac[%x]=%x\n", i, temp8);
i = REG_RXFF_WTR_V1;
temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"halmac_debug: mac[%x]=%x\n", i, temp8);
} else {
/*Dump MAC Register*/
for (i = 0x0000; i < 0x17fc; i += 4) {
temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
DBG_DMESG, "halmac_debug: mac[%x]=%x\n",
i, temp32);
}
/*Check RX Fifo status*/
i = REG_RXFF_PTR_V1;
temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"halmac_debug: mac[%x]=%x\n", i, temp32);
i = REG_RXFF_WTR_V1;
temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"halmac_debug: mac[%x]=%x\n", i, temp32);
i = REG_RXFF_PTR_V1;
temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"halmac_debug: mac[%x]=%x\n", i, temp32);
i = REG_RXFF_WTR_V1;
temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"halmac_debug: mac[%x]=%x\n", i, temp32);
}
/* TODO: Add check register code, including MAC CLK, CPU CLK */
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
/**
* halmac_cfg_parameter_88xx() - config parameter by FW
* @halmac_adapter : the adapter of halmac
* @para_info : cmd id, content
* @full_fifo : parameter information
*
* If msk_en = true, the format of array is {reg_info, mask, value}.
* If msk_en =_FAUSE, the format of array is {reg_info, value}
* The format of reg_info is
* reg_info[31]=rf_reg, 0: MAC_BB reg, 1: RF reg
* reg_info[27:24]=rf_path, 0: path_A, 1: path_B
* if rf_reg=0(MAC_BB reg), rf_path is meaningless.
* ref_info[15:0]=offset
*
* Example: msk_en = false
* {0x8100000a, 0x00001122}
* =>Set RF register, path_B, offset 0xA to 0x00001122
* {0x00000824, 0x11224433}
* =>Set MAC_BB register, offset 0x800 to 0x11224433
*
* Note : full fifo mode only for init flow
*
* Author : KaiYuan Chang/Ivan Lin
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_cfg_parameter_88xx(struct halmac_adapter *halmac_adapter,
struct halmac_phy_parameter_info *para_info,
u8 full_fifo)
{
void *driver_adapter = NULL;
enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
enum halmac_cmd_process_status *process_status =
&halmac_adapter->halmac_state.cfg_para_state_set.process_status;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_NO_DLFW;
if (halmac_adapter->fw_version.h2c_version < 4)
return HALMAC_RET_FW_NO_SUPPORT;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_PARAMETER);
driver_adapter = halmac_adapter->driver_adapter;
if (halmac_adapter->halmac_state.dlfw_state == HALMAC_DLFW_NONE) {
pr_err("%s Fail due to DLFW NONE!!\n", __func__);
return HALMAC_RET_DLFW_FAIL;
}
if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"Wait event(cfg para)...\n");
return HALMAC_RET_BUSY_STATE;
}
if (halmac_query_cfg_para_curr_state_88xx(halmac_adapter) !=
HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE &&
halmac_query_cfg_para_curr_state_88xx(halmac_adapter) !=
HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING) {
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"Not idle state(cfg para)...\n");
return HALMAC_RET_BUSY_STATE;
}
*process_status = HALMAC_CMD_PROCESS_IDLE;
ret_status = halmac_send_h2c_phy_parameter_88xx(halmac_adapter,
para_info, full_fifo);
if (ret_status != HALMAC_RET_SUCCESS) {
pr_err("halmac_send_h2c_phy_parameter_88xx Fail!! = %x\n",
ret_status);
return ret_status;
}
return ret_status;
}
/**
* halmac_update_packet_88xx() - send specific packet to FW
* @halmac_adapter : the adapter of halmac
* @pkt_id : packet id, to know the purpose of this packet
* @pkt : packet
* @pkt_size : packet size
*
* Note : TX_DESC is not included in the pkt
*
* Author : KaiYuan Chang/Ivan Lin
* Return : enum halmac_ret_status
* More details of status code can be found in prototype document
*/
enum halmac_ret_status
halmac_update_packet_88xx(struct halmac_adapter *halmac_adapter,
enum halmac_packet_id pkt_id, u8 *pkt, u32 pkt_size)
{
void *driver_adapter = NULL;
struct halmac_api *halmac_api;
enum halmac_ret_status status = HALMAC_RET_SUCCESS;
enum halmac_cmd_process_status *process_status =
&halmac_adapter->halmac_state.update_packet_set.process_status;
if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_ADAPTER_INVALID;
if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_API_INVALID;
if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
return HALMAC_RET_NO_DLFW;
if (halmac_adapter->fw_version.h2c_version < 4)
return HALMAC_RET_FW_NO_SUPPORT;
halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_UPDATE_PACKET);
driver_adapter = halmac_adapter->driver_adapter;
halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
"%s ==========>\n", __func__);
if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
"Wait event(update_packet)...\n");
return HALMAC_RET_BUSY_STATE;
}
*process_status = HALMAC_CMD_PROCESS_SENDING;
status = halmac_send_h2c_update_packet_88xx(halmac_adapter, pkt_id, pkt,
pkt_size);
if (status != HALMAC_RET_SUCCESS) {
pr_err("halmac_send_h2c_update_packet_88xx packet = %x, fail = %x!!\n",
pkt_id, status);
return status;
}
HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
"%s <==========\n", __func__);
return HALMAC_RET_SUCCESS;
}
enum halmac_ret_status