/****************************************************************************** * * Copyright(c) 2019 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * *****************************************************************************/ #define _HAL_API_EFUSE_C_ #include "hal_headers.h" #include "efuse/hal_efuse_export.h" /*WIFI Efuse*/ enum rtw_hal_status rtw_hal_efuse_shadow_load(struct hal_info_t *hal_info, bool is_limit) { enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE; status = rtw_efuse_shadow_load(hal_info->efuse, is_limit); return status; } enum rtw_hal_status rtw_hal_efuse_shadow_update(struct hal_info_t *hal_info, bool is_limit) { enum rtw_hal_status status = RTW_HAL_STATUS_EFUSE_PG_FAIL; status = rtw_efuse_shadow_update(hal_info->efuse, is_limit); return status; } enum rtw_hal_status rtw_hal_efuse_shadow_read(struct hal_info_t *hal_info, u8 byte_count, u16 offset, u32 *value, bool is_limit) { enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE; status = rtw_efuse_shadow_read(hal_info->efuse, byte_count, offset, value, is_limit); return status; } enum rtw_hal_status rtw_hal_efuse_shadow_write(struct hal_info_t *hal_info, u8 byte_count, u16 offset, u32 value, bool is_limit) { enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE; status = rtw_efuse_shadow_write(hal_info->efuse, byte_count, offset, value, is_limit); return status; } enum rtw_hal_status rtw_hal_efuse_shadow2buf(struct hal_info_t *hal_info, u8 *pbuf, u16 buflen) { enum rtw_hal_status status = RTW_HAL_STATUS_SUCCESS; status = rtw_efuse_shadow2buf(hal_info->efuse, pbuf, buflen); return status; } enum rtw_hal_status rtw_hal_efuse_file_map_load( struct hal_info_t *hal_info, char *file_path, u8 is_limit) { enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE; hal_status = rtw_efuse_file_map_load(hal_info->efuse, file_path ,is_limit); return hal_status; } enum rtw_hal_status rtw_hal_efuse_file_mask_load( struct hal_info_t *hal_info, char *file_path, u8 is_limit) { enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE; hal_status = rtw_efuse_file_mask_load(hal_info->efuse, file_path, is_limit); return hal_status; } /* usage = used percentage(1 Byte) + used bytes(2 Bytes) */ enum rtw_hal_status rtw_hal_efuse_get_usage(struct hal_info_t *hal_info, u32 *usage) { enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE; status = rtw_efuse_get_usage(hal_info->efuse, usage); return status; } enum rtw_hal_status rtw_hal_efuse_get_logical_size(struct hal_info_t *hal_info, u32 *size) { enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE; status = rtw_efuse_get_logical_size(hal_info->efuse, size, true); return status; } enum rtw_hal_status rtw_hal_efuse_get_size(struct hal_info_t *hal_info, u32 *size) { enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE; status = rtw_efuse_get_size(hal_info->efuse, size); return status; } enum rtw_hal_status rtw_hal_efuse_get_avl(struct hal_info_t *hal_info, u32 *size) { enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE; status = rtw_efuse_get_avl(hal_info->efuse, size); return status; } enum rtw_hal_status rtw_hal_efuse_get_shadowmap_from(struct hal_info_t *hal_info, u8 *val) { enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE; status = rtw_efuse_get_shadowmap_from(hal_info->efuse, val); return status; } enum rtw_hal_status rtw_hal_efuse_get_offset_mask(struct hal_info_t *hal_info, u16 offset, u8 *mask) { enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE; status = rtw_efuse_get_offset_mask(hal_info->efuse, offset, mask); return status; } enum rtw_hal_status rtw_hal_efuse_get_mask_buf(struct hal_info_t *hal_info, u8 *destbuf, u32 *buflen) { enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE; status = rtw_efuse_get_mask_buf(hal_info->efuse, destbuf, buflen); return status; } enum rtw_hal_status rtw_hal_efuse_get_info(struct rtw_hal_com_t *hal_com, enum rtw_efuse_info info_type, void *value, u8 size) { enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE; struct hal_info_t *hal_info = hal_com->hal_priv; status = rtw_efuse_get_info(hal_info->efuse, info_type, value, size); return status; } /* API export to PHL : rtw_hal_get_efuse_info */ enum rtw_hal_status rtw_hal_get_efuse_info(void *hal, enum rtw_efuse_info info_type, void *value, u8 size) { enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE; struct hal_info_t *hal_info = (struct hal_info_t *)hal; status = rtw_efuse_get_info(hal_info->efuse, info_type, value, size); return status; } void rtw_hal_efuse_process(struct hal_info_t *hal_info, char *ic_name) { rtw_efuse_process(hal_info->efuse, ic_name); } enum rtw_hal_status rtw_hal_efuse_init(struct rtw_phl_com_t *phl_com, struct hal_info_t *hal_info) { enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE; struct rtw_hal_com_t *hal_com = hal_info->hal_com; status = rtw_efuse_init(phl_com, hal_com, &(hal_info->efuse)); return status; } void rtw_hal_efuse_deinit(struct rtw_phl_com_t *phl_com, struct hal_info_t *hal_info) { struct rtw_hal_com_t *hal_com = hal_info->hal_com; rtw_efuse_deinit(hal_com, hal_info->efuse); } enum rtw_hal_status rtw_hal_efuse_bt_shadow_load(struct hal_info_t *hal_info) { enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE; status = rtw_efuse_bt_shadow_load(hal_info->efuse); return status; } enum rtw_hal_status rtw_hal_efuse_bt_shadow_update(struct hal_info_t *hal_info) { enum rtw_hal_status status = RTW_HAL_STATUS_EFUSE_PG_FAIL; status = rtw_efuse_bt_shadow_update(hal_info->efuse); return status; } enum rtw_hal_status rtw_hal_efuse_bt_shadow_read(struct hal_info_t *hal_info, u8 byte_count, u16 offset, u32 *value) { enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE; status = rtw_efuse_bt_shadow_read(hal_info->efuse, byte_count, offset, value); return status; } enum rtw_hal_status rtw_hal_efuse_bt_shadow_write(struct hal_info_t *hal_info, u8 byte_count, u16 offset, u32 value) { enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE; status = rtw_efuse_bt_shadow_write(hal_info->efuse, byte_count, offset, value); return status; } enum rtw_hal_status rtw_hal_efuse_bt_shadow2buf(struct hal_info_t *hal_info, u8 *pbuf, u16 buflen) { enum rtw_hal_status status = RTW_HAL_STATUS_SUCCESS; status = rtw_efuse_bt_shadow2buf(hal_info->efuse, pbuf, buflen); return status; } enum rtw_hal_status rtw_hal_efuse_bt_file_map_load( struct hal_info_t *hal_info, char *file_path) { enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE; hal_status = rtw_efuse_bt_file_map_load(hal_info->efuse, file_path); return hal_status; } enum rtw_hal_status rtw_hal_efuse_bt_file_mask_load( struct hal_info_t *hal_info, char *file_path) { enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE; hal_status = rtw_efuse_bt_file_mask_load(hal_info->efuse, file_path); return hal_status; } /* usage = used percentage(1 Byte) + used bytes(2 Bytes) */ enum rtw_hal_status rtw_hal_efuse_bt_get_usage(struct hal_info_t *hal_info, u32 *usage) { enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE; status = rtw_efuse_get_usage(hal_info->efuse, usage); return status; } enum rtw_hal_status rtw_hal_efuse_bt_get_logical_size(struct hal_info_t *hal_info, u32 *size) { enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE; status = rtw_efuse_bt_get_logical_size(hal_info->efuse, size); return status; } enum rtw_hal_status rtw_hal_efuse_bt_get_size(struct hal_info_t *hal_info, u32 *size) { enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE; status = rtw_efuse_bt_get_size(hal_info->efuse, size); return status; } enum rtw_hal_status rtw_hal_efuse_bt_get_avl(struct hal_info_t *hal_info, u32 *size) { enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE; status = rtw_efuse_bt_get_avl(hal_info->efuse, size); return status; } enum rtw_hal_status rtw_hal_efuse_bt_get_offset_mask(struct hal_info_t *hal_info, u16 offset, u8 *mask) { enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE; status = rtw_efuse_bt_get_offset_mask(hal_info->efuse, offset, mask); return status; } enum rtw_hal_status rtw_hal_efuse_bt_get_mask_buf(struct hal_info_t *hal_info, u8 *destbuf, u32 *buflen) { enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE; status = rtw_efuse_bt_get_mask_buf(hal_info->efuse, destbuf, buflen); return status; } enum rtw_hal_status rtw_hal_efuse_bt_read_hidden( struct hal_info_t *hal_info, u32 addr, u32 size, u8 *val) { enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE; hal_status = rtw_efuse_bt_read_hidden(hal_info->efuse, addr, size, val); return hal_status; } enum rtw_hal_status rtw_hal_efuse_bt_write_hidden( struct hal_info_t *hal_info, u32 addr, u8 val) { enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE; hal_status = rtw_efuse_bt_write_hidden(hal_info->efuse, addr, val); return hal_status; } enum rtw_hal_status rtw_hal_efuse_read_phy_efuse( struct hal_info_t *hal_info, u32 addr, u32 size, u8 *data, u8 type) { enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE; status = rtw_efuse_read_phy_wifi(hal_info->efuse, addr, size, data, type); return status; } enum rtw_hal_status rtw_hal_efuse_renew( struct hal_info_t *hal_info, u8 type) { enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE; status = rtw_efuse_renew(hal_info->efuse, type); return status; } void hal_efuse_dump_wifi_map( struct hal_info_t *hal_info, u32 *used_len, char *output, u32 *out_len ) { void *d = hal_info->hal_com->drv_priv; u32 _used_len = *used_len; u32 _out_len = *out_len; u32 map_len = 0; u32 i = 0, j = 0; u8 *buf = NULL; rtw_efuse_get_logical_size(hal_info->efuse, &map_len, true); if(map_len == 0){ PHL_DBG_OUTBUF(_out_len, _used_len, output + _used_len, _out_len - _used_len, "map length is 0!\n"); goto exit; } buf = _os_mem_alloc(d, map_len); if(buf == NULL){ PHL_DBG_OUTBUF(_out_len, _used_len, output + _used_len, _out_len - _used_len, "Allocate buffer fail!\n"); goto exit; } rtw_efuse_shadow2buf(hal_info->efuse, buf, (u16)map_len); PHL_DBG_OUTBUF(_out_len, _used_len, output + _used_len, _out_len - _used_len, "EFUSE Wifi shadow map from %s\n\n", rtw_efuse_get_shadowmap_from_to_str(hal_info->efuse)); PHL_DBG_OUTBUF(_out_len, _used_len, output + _used_len, _out_len - _used_len, "%14s%-6s%-6s%-6s%-6s%-6s%-6s%-6s%-6s\n", " ", "00", "02", "04", "06", "08", "0A", "0C", "0E"); PHL_DBG_OUTBUF(_out_len, _used_len, output + _used_len, _out_len - _used_len, "%14s%s\n", " ", "================================================\n"); for(i = 0; i < map_len; i+=16){ PHL_DBG_OUTBUF(_out_len, _used_len, output + _used_len, _out_len - _used_len, "0x%08X%4s", i, ""); for(j = 0; j<16;j++){ if((i+j) >= map_len) break; PHL_DBG_OUTBUF(_out_len, _used_len, output + _used_len, _out_len - _used_len, "%02X ", buf[i+j]); } PHL_DBG_OUTBUF(_out_len, _used_len, output + _used_len, _out_len - _used_len, "\n"); } if(buf) _os_mem_free(d, buf, map_len); exit: *used_len = _used_len; *out_len = _out_len; } void hal_efuse_dump_wifi_logic_map( struct hal_info_t *hal_info, u32 *used_len, char *output, u32 *out_len ) { void *d = hal_info->hal_com->drv_priv; u32 _used_len = *used_len; u32 _out_len = *out_len; u32 map_len = 0; u32 i = 0, j = 0; u8 *data = NULL; rtw_efuse_get_logical_size(hal_info->efuse, &map_len, true); if(map_len == 0){ PHL_DBG_OUTBUF(_out_len, _used_len, output + _used_len, _out_len - _used_len, "map length is 0!\n"); goto exit; } data = _os_mem_alloc(d, map_len); if(data == NULL){ PHL_DBG_OUTBUF(_out_len, _used_len, output + _used_len, _out_len - _used_len, "Allocate buffer fail!\n"); goto exit; } rtw_efuse_logicmap_buf_load(hal_info->efuse, data, false); PHL_DBG_OUTBUF(_out_len, _used_len, output + _used_len, _out_len - _used_len, "EFUSE Wifi map from HW\n"); PHL_DBG_OUTBUF(_out_len, _used_len, output + _used_len, _out_len - _used_len, "%14s%-6s%-6s%-6s%-6s%-6s%-6s%-6s%-6s\n", " ", "00", "02", "04", "06", "08", "0A", "0C", "0E"); PHL_DBG_OUTBUF(_out_len, _used_len, output + _used_len, _out_len - _used_len, "%14s%s\n", " ", "================================================\n"); for(i = 0; i < map_len; i+=16){ PHL_DBG_OUTBUF(_out_len, _used_len, output + _used_len, _out_len - _used_len, "0x%08X%4s", i, ""); for(j = 0; j<16;j++){ if((i+j) >= map_len) break; PHL_DBG_OUTBUF(_out_len, _used_len, output + _used_len, _out_len - _used_len, "%02X ", data[i+j]); } PHL_DBG_OUTBUF(_out_len, _used_len, output + _used_len, _out_len - _used_len, "\n"); } if(data) _os_mem_free(d, data, map_len); exit: *used_len = _used_len; *out_len = _out_len; } void hal_efuse_cmd_parser( struct hal_info_t *hal_info, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len ) { u32 hal_cmd_ary_size = sizeof(hal_efuse_cmd_i) / sizeof(struct hal_cmd_info); u32 i = 0; u8 id = 0; u32 used = 0; PHL_DBG_OUTBUF(out_len, used, output + used, out_len - used, "\n"); if (hal_cmd_ary_size == 0) return; /* Parsing Cmd ID */ if (input_num) { for (i = 0; i < hal_cmd_ary_size; i++) { if (_os_strcmp(hal_efuse_cmd_i[i].name, input[0]) == 0) { id = hal_efuse_cmd_i[i].id; PHL_INFO("enter EFUSE cmd %s\n", hal_efuse_cmd_i[i].name); break; } } if (i == hal_cmd_ary_size) { PHL_DBG_OUTBUF(out_len, used, output + used, out_len - used, "EFUSE command not found!\n"); return; } } switch (id) { case HAL_EFUSE_HELP: PHL_DBG_OUTBUF(out_len, used, output + used, out_len - used, "EFUSE cmd =>\n"); for (i = 0; i < hal_cmd_ary_size - 1; i++) PHL_DBG_OUTBUF(out_len, used, output + used, out_len - used," %s\n", hal_efuse_cmd_i[i].name); break; case HAL_EFUSE_WIFI_DUMP_MAP: hal_efuse_dump_wifi_map(hal_info, &used, output, &out_len); break; case HAL_EFUSE_WIFI_LOGIC_DUMP_MAP: hal_efuse_dump_wifi_logic_map(hal_info, &used, output, &out_len); break; default: PHL_DBG_OUTBUF(out_len, used, output + used, out_len - used,"Do not support this command\n"); break; } } s32 hal_efuse_cmd( struct hal_info_t *hal_info, char *input, char *output, u32 out_len ) { char *token; u32 argc = 0; char argv[MAX_ARGC][MAX_ARGV]; do { token = _os_strsep(&input, ", "); if (token) { if (_os_strlen((u8*)token) <= MAX_ARGV) _os_strcpy(argv[argc], token); argc++; } else { break; } } while (argc < MAX_ARGC); hal_efuse_cmd_parser(hal_info, argv, argc, output, out_len); return 0; } bool rtw_hal_efuse_proc_cmd( struct hal_info_t *hal_info, struct rtw_proc_cmd *incmd, char *output, u32 out_len ) { if(incmd->in_type == RTW_ARG_TYPE_BUF) hal_efuse_cmd(hal_info, incmd->in.buf, output, out_len); else if(incmd->in_type == RTW_ARG_TYPE_ARRAY){ hal_efuse_cmd_parser(hal_info, incmd->in.vector, incmd->in_cnt_len, output, out_len); } return true; }