/******************************************************************************
|
*
|
* Copyright(c) 2019 Realtek Corporation. All rights reserved.
|
*
|
* 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.
|
*
|
******************************************************************************/
|
#include "efuse.h"
|
|
static struct mac_efuse_tbl efuse_tbl;
|
static struct mac_bank_efuse_info bank_efuse_info;
|
u16 efuse_ctrl = R_AX_EFUSE_CTRL;
|
u16 read_efuse_cnt = EFUSE_WAIT_CNT;
|
bool OTP_test;
|
enum rtw_dv_sel dv_sel = DDV;
|
|
static struct efuse_info_item offset_pcie = {
|
0x400, /* mac_addr */
|
0, /* pid */
|
0x408, /* did */
|
0x406, /* vid */
|
0x40A, /* svid */
|
0x40C, /* smid */
|
};
|
|
static struct efuse_info_item offset_usb_8852a = {
|
0x438, /* mac_addr */
|
0x432, /* pid */
|
0, /* did */
|
0x430, /* vid */
|
0, /* svid */
|
0, /* smid */
|
};
|
|
static struct efuse_info_item offset_usb_8852b = {
|
0x488, /* mac_addr */
|
0x482, /* pid */
|
0, /* did */
|
0x480, /* vid */
|
0, /* svid */
|
0, /* smid */
|
};
|
|
static struct efuse_info_item offset_sdio = {
|
0x41A, /* mac_addr */
|
0, /* pid */
|
0, /* did */
|
0, /* vid */
|
0, /* svid */
|
0, /* smid */
|
};
|
|
static struct efuse_info_item def_val_pcie = {
|
0x0, /* mac_addr */
|
0, /* pid */
|
0x52, /* did */
|
0xEC, /* vid */
|
0xEC, /* svid */
|
0x52, /* smid */
|
};
|
|
static struct efuse_info_item def_val_usb_8852a = {
|
0x0, /* mac_addr */
|
0x5A, /* pid */
|
0, /* did */
|
0xDA, /* vid */
|
0, /* svid */
|
0, /* smid */
|
};
|
|
static struct efuse_info_item def_val_usb_8852b = {
|
0x0, /* mac_addr */
|
0x5B, /* pid */
|
0, /* did */
|
0xDA, /* vid */
|
0, /* svid */
|
0, /* smid */
|
};
|
|
static struct efuse_info_item def_val_sdio = {
|
0x0, /* mac_addr */
|
0, /* pid */
|
0, /* did */
|
0, /* vid */
|
0, /* svid */
|
0, /* smid */
|
};
|
|
static struct efuse_info_item len_pcie = {
|
6, /* mac_addr */
|
0, /* pid */
|
2, /* did */
|
2, /* vid */
|
2, /* svid */
|
2, /* smid */
|
};
|
|
static struct efuse_info_item len_usb = {
|
6, /* mac_addr */
|
2, /* pid */
|
0, /* did */
|
2, /* vid */
|
0, /* svid */
|
0, /* smid */
|
};
|
|
static struct efuse_info_item len_sdio = {
|
6, /* mac_addr */
|
0, /* pid */
|
0, /* did */
|
0, /* vid */
|
0, /* svid */
|
0, /* smid */
|
};
|
|
static struct efuse_info efuse_info_pcie = {
|
&offset_pcie, /* offset */
|
&def_val_pcie, /* def_val */
|
&len_pcie, /* len */
|
};
|
|
static struct efuse_info efuse_info_usb_8852a = {
|
&offset_usb_8852a, /* offset */
|
&def_val_usb_8852a, /* def_val */
|
&len_usb, /* len */
|
};
|
|
static struct efuse_info efuse_info_usb_8852b = {
|
&offset_usb_8852b, /* offset */
|
&def_val_usb_8852b, /* def_val */
|
&len_usb, /* len */
|
};
|
|
static struct efuse_info efuse_info_sdio = {
|
&offset_sdio, /* offset */
|
&def_val_sdio, /* def_val */
|
&len_sdio, /* len */
|
};
|
|
static u32 efuse_map_init(struct mac_ax_adapter *adapter,
|
enum efuse_map_sel map_sel);
|
static u32 efuse_fwcmd_ck(struct mac_ax_adapter *adapter);
|
static u32 efuse_proc_ck(struct mac_ax_adapter *adapter);
|
static u32 cnv_efuse_state(struct mac_ax_adapter *adapter, u8 dest_state);
|
static u32 switch_efuse_bank(struct mac_ax_adapter *adapter,
|
enum mac_ax_efuse_bank bank);
|
static u32 proc_dump_efuse(struct mac_ax_adapter *adapter,
|
enum mac_ax_efuse_read_cfg cfg);
|
static u32 read_hw_efuse(struct mac_ax_adapter *adapter, u32 offset, u32 size,
|
u8 *map);
|
static u32 write_hw_efuse(struct mac_ax_adapter *adapter, u32 offset, u8 value);
|
static u32 cmp_hw_efuse(struct mac_ax_adapter *adapter, u32 offset, u16 val);
|
static u32 eeprom_parser(struct mac_ax_adapter *adapter, u8 *phy_map,
|
u8 *log_map, enum mac_ax_efuse_parser_cfg cfg);
|
static u32 read_log_efuse_map(struct mac_ax_adapter *adapter, u8 *map,
|
u32 log_efuse_size);
|
static u32 proc_pg_efuse_by_map(struct mac_ax_adapter *adapter,
|
struct mac_ax_pg_efuse_info *info,
|
enum mac_ax_efuse_read_cfg cfg);
|
static u32 dump_efuse_drv(struct mac_ax_adapter *adapter);
|
static u32 dump_efuse_fw(struct mac_ax_adapter *adapter);
|
static u32 proc_write_log_efuse(struct mac_ax_adapter *adapter, u32 offset,
|
u8 value);
|
static u32 read_efuse(struct mac_ax_adapter *adapter, u32 offset, u32 size,
|
u8 *map);
|
static u32 update_eeprom_mask(struct mac_ax_adapter *adapter,
|
struct mac_ax_pg_efuse_info *info,
|
u8 *updated_mask, bool pg_sim);
|
static u32 check_efuse_enough(struct mac_ax_adapter *adapter,
|
struct mac_ax_pg_efuse_info *info,
|
u8 *updated_mask);
|
static u32 proc_pg_efuse(struct mac_ax_adapter *adapter,
|
struct mac_ax_pg_efuse_info *info, u8 word_en,
|
u8 pre_word_en, u32 eeprom_offset, bool pg_sim);
|
static u32 program_efuse(struct mac_ax_adapter *adapter,
|
struct mac_ax_pg_efuse_info *info, u8 *updated_mask,
|
bool pg_sim);
|
static void mask_eeprom(struct mac_ax_adapter *adapter,
|
struct mac_ax_pg_efuse_info *info);
|
static u32 query_status_map(struct mac_ax_adapter *adapter,
|
enum mac_ax_efuse_feature_id feature_id,
|
u8 *map, bool is_limit);
|
static u32 adjust_mask(struct mac_ax_adapter *adapter,
|
struct mac_ax_pg_efuse_info *info);
|
static u32 compare_info_length(struct efuse_info *info,
|
enum rtw_efuse_info id, u32 length);
|
static u32 set_check_sum_val(struct mac_ax_adapter *adapter,
|
u8 *map, u16 value);
|
static void cal_check_sum(struct mac_ax_adapter *adapter,
|
u16 *chksum);
|
static u32 compare_version(struct mac_ax_adapter *adapter,
|
struct mac_ax_pg_efuse_info *info, u32 ver_len);
|
static void add_dummy_read(struct mac_ax_adapter *adapter);
|
static void enable_OTP_burst_mode(struct mac_ax_adapter *adapter,
|
bool enable);
|
static void enable_efuse_sw_pwr_cut(struct mac_ax_adapter *adapter,
|
bool is_write);
|
static void disable_efuse_sw_pwr_cut(struct mac_ax_adapter *adapter,
|
bool is_write);
|
static u32 enable_efuse_pwr_cut_dav(struct mac_ax_adapter *adapter,
|
bool is_write);
|
static u32 disable_efuse_pwr_cut_dav(struct mac_ax_adapter *adapter,
|
bool is_write);
|
static u32 read_hw_efuse_dav(struct mac_ax_adapter *adapter, u32 offset, u32 size,
|
u8 *map);
|
static u32 write_hw_efuse_dav(struct mac_ax_adapter *adapter, u32 offset,
|
u8 value);
|
static void switch_dv(struct mac_ax_adapter *adapter, enum rtw_dv_sel);
|
|
u32 mac_dump_efuse_map_wl_plus(struct mac_ax_adapter *adapter,
|
enum mac_ax_efuse_read_cfg cfg, u8 *efuse_map)
|
{
|
u32 ret = 0;
|
struct mac_ax_hw_info *hw_info = adapter->hw_info;
|
u8 chip_id = hw_info->chip_id;
|
|
switch (chip_id) {
|
case MAC_AX_CHIP_ID_8852A:
|
ret = mac_dump_efuse_map_wl(adapter, cfg, efuse_map);
|
break;
|
case MAC_AX_CHIP_ID_8852B:
|
case MAC_AX_CHIP_ID_8852C:
|
case MAC_AX_CHIP_ID_8192XB:
|
ret = mac_dump_efuse_map_wl(adapter, cfg, efuse_map);
|
if (ret)
|
return ret;
|
switch_dv(adapter, DAV);
|
ret = mac_dump_efuse_map_wl(adapter, MAC_AX_EFUSE_R_DRV,
|
efuse_map + hw_info->efuse_size);
|
switch_dv(adapter, DDV);
|
break;
|
default:
|
break;
|
}
|
|
if (ret)
|
return ret;
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_dump_efuse_map_wl(struct mac_ax_adapter *adapter,
|
enum mac_ax_efuse_read_cfg cfg, u8 *efuse_map)
|
{
|
u32 ret, stat;
|
|
#if 0
|
if (cfg == MAC_AX_EFUSE_R_FW ||
|
(cfg == MAC_AX_EFUSE_R_AUTO &&
|
adapter->sm.fwdl == MAC_AX_FWDL_INIT_RDY))
|
return MACNOITEM;
|
#else
|
if (cfg == MAC_AX_EFUSE_R_FW &&
|
adapter->sm.fwdl != MAC_AX_FWDL_INIT_RDY) // no fw file
|
return MACNOFW;
|
#endif
|
|
PLTFM_MSG_TRACE("[TRACE]cfg = %d\n", cfg);
|
|
ret = efuse_proc_ck(adapter);
|
if (ret != 0)
|
return ret;
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_PHY);
|
if (ret != 0)
|
return ret;
|
|
ret = switch_efuse_bank(adapter, MAC_AX_EFUSE_BANK_WIFI);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
if (dv_sel == DAV)
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_PHY_DAV);
|
else
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_PHY_WL);
|
if (ret != 0)
|
return ret;
|
|
ret = proc_dump_efuse(adapter, cfg);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]dump efuse!!\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
query_status_map(adapter, MAC_AX_DUMP_PHYSICAL_EFUSE, efuse_map, 0);
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (ret != 0)
|
return ret;
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_dump_efuse_map_bt(struct mac_ax_adapter *adapter,
|
enum mac_ax_efuse_read_cfg cfg, u8 *efuse_map)
|
{
|
u32 ret, stat;
|
|
#if 0
|
if (cfg == MAC_AX_EFUSE_R_FW ||
|
(cfg == MAC_AX_EFUSE_R_AUTO &&
|
adapter->sm.fwdl == MAC_AX_FWDL_INIT_RDY))
|
return MACNOITEM;
|
#else
|
if (cfg == MAC_AX_EFUSE_R_FW &&
|
adapter->sm.fwdl != MAC_AX_FWDL_INIT_RDY) // no fw file
|
return MACNOFW;
|
#endif
|
|
PLTFM_MSG_TRACE("[TRACE]cfg = %d\n", cfg);
|
|
ret = efuse_proc_ck(adapter);
|
if (ret != 0)
|
return ret;
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_PHY);
|
if (ret != 0)
|
return ret;
|
|
ret = switch_efuse_bank(adapter, MAC_AX_EFUSE_BANK_BT);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_PHY_BT);
|
if (ret != 0)
|
return ret;
|
|
ret = proc_dump_efuse(adapter, cfg);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]dump efuse!!\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
query_status_map(adapter, MAC_AX_DUMP_PHYSICAL_EFUSE, efuse_map, 0);
|
|
ret = switch_efuse_bank(adapter, MAC_AX_EFUSE_BANK_WIFI);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (ret != 0)
|
return ret;
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_write_efuse_plus(struct mac_ax_adapter *adapter, u32 addr, u8 val,
|
enum mac_ax_efuse_bank bank)
|
{
|
u32 ret = 0;
|
struct mac_ax_hw_info *hw_info = adapter->hw_info;
|
u8 chip_id = hw_info->chip_id;
|
u32 efuse_size = hw_info->wl_efuse_size;
|
|
switch (bank) {
|
case MAC_AX_EFUSE_BANK_WIFI:
|
switch (chip_id) {
|
case MAC_AX_CHIP_ID_8852A:
|
ret = mac_write_efuse(adapter, addr, val, bank);
|
break;
|
case MAC_AX_CHIP_ID_8852B:
|
case MAC_AX_CHIP_ID_8852C:
|
case MAC_AX_CHIP_ID_8192XB:
|
if (addr < efuse_size) {
|
ret = mac_write_efuse(adapter, addr, val, bank);
|
} else {
|
switch_dv(adapter, DAV);
|
ret = mac_write_efuse(adapter, addr -
|
efuse_size, val, bank);
|
switch_dv(adapter, DDV);
|
}
|
break;
|
default:
|
break;
|
}
|
break;
|
case MAC_AX_EFUSE_BANK_BT:
|
ret = mac_write_efuse(adapter, addr, val, bank);
|
break;
|
default:
|
break;
|
}
|
if (ret)
|
return ret;
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_write_efuse(struct mac_ax_adapter *adapter, u32 addr, u8 val,
|
enum mac_ax_efuse_bank bank)
|
{
|
u32 ret, stat, efuse_size = 0;
|
|
if (bank == MAC_AX_EFUSE_BANK_WIFI) {
|
if (OTP_test)
|
efuse_size = OTP_PHY_SIZE;
|
else
|
efuse_size = adapter->hw_info->wl_efuse_size;
|
} else if (bank == MAC_AX_EFUSE_BANK_BT) {
|
efuse_size = adapter->hw_info->bt_efuse_size;
|
} else {
|
return MACEFUSEBANK;
|
}
|
|
if (addr >= efuse_size) {
|
PLTFM_MSG_ERR("[ERR]Offset is too large\n");
|
return MACEFUSESIZE;
|
}
|
|
ret = efuse_proc_ck(adapter);
|
if (ret != 0)
|
return ret;
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_PHY);
|
if (ret != 0)
|
return ret;
|
|
ret = switch_efuse_bank(adapter, bank);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
enable_efuse_sw_pwr_cut(adapter, 1);
|
ret = write_hw_efuse(adapter, addr, val);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]write physical efuse\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
disable_efuse_sw_pwr_cut(adapter, 1);
|
|
if (bank == MAC_AX_EFUSE_BANK_BT) {
|
ret = switch_efuse_bank(adapter, MAC_AX_EFUSE_BANK_WIFI);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
}
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (ret != 0)
|
return ret;
|
|
return ret;
|
}
|
|
u32 mac_read_efuse_plus(struct mac_ax_adapter *adapter, u32 addr, u32 size,
|
u8 *val, enum mac_ax_efuse_bank bank)
|
{
|
u32 ret = 0;
|
struct mac_ax_hw_info *hw_info = adapter->hw_info;
|
u8 chip_id = hw_info->chip_id;
|
u32 efuse_size = hw_info->wl_efuse_size;
|
u32 size1, size2;
|
|
switch (bank) {
|
case MAC_AX_EFUSE_BANK_WIFI:
|
switch (chip_id) {
|
case MAC_AX_CHIP_ID_8852A:
|
ret = mac_read_efuse(adapter, addr, size, val, bank);
|
break;
|
case MAC_AX_CHIP_ID_8852B:
|
case MAC_AX_CHIP_ID_8852C:
|
case MAC_AX_CHIP_ID_8192XB:
|
if (addr < efuse_size && addr + size <= efuse_size) {
|
ret = mac_read_efuse(adapter, addr, size,
|
val, bank);
|
} else if (addr >= efuse_size) {
|
switch_dv(adapter, DAV);
|
ret = mac_read_efuse(adapter, addr - efuse_size,
|
size, val, bank);
|
switch_dv(adapter, DDV);
|
} else if (addr < efuse_size &&
|
addr + size > efuse_size) {
|
size1 = efuse_size - addr;
|
size2 = addr + size - efuse_size;
|
|
ret = mac_read_efuse(adapter, addr, size1,
|
val, bank);
|
if (ret)
|
return ret;
|
|
switch_dv(adapter, DAV);
|
ret = mac_read_efuse(adapter, 0, size2,
|
val + size1, bank);
|
switch_dv(adapter, DDV);
|
}
|
if (ret)
|
return ret;
|
break;
|
default:
|
break;
|
}
|
break;
|
case MAC_AX_EFUSE_BANK_BT:
|
ret = mac_read_efuse(adapter, addr, size, val, bank);
|
break;
|
default:
|
break;
|
}
|
if (ret)
|
return ret;
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_read_efuse(struct mac_ax_adapter *adapter, u32 addr, u32 size, u8 *val,
|
enum mac_ax_efuse_bank bank)
|
{
|
u32 ret, stat, efuse_size = 0;
|
|
if (bank == MAC_AX_EFUSE_BANK_WIFI) {
|
if (OTP_test)
|
efuse_size = OTP_PHY_SIZE;
|
else
|
efuse_size = adapter->hw_info->wl_efuse_size;
|
} else if (bank == MAC_AX_EFUSE_BANK_BT) {
|
efuse_size = adapter->hw_info->bt_efuse_size;
|
} else {
|
return MACEFUSEBANK;
|
}
|
|
if (addr >= efuse_size || addr + size > efuse_size) {
|
PLTFM_MSG_ERR("[ERR] Wrong efuse index\n");
|
return MACEFUSESIZE;
|
}
|
|
ret = efuse_proc_ck(adapter);
|
if (ret != 0)
|
return ret;
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_PHY);
|
if (ret != 0)
|
return ret;
|
|
ret = switch_efuse_bank(adapter, bank);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
ret = read_hw_efuse(adapter, addr, size, val);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]read hw efuse\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
if (bank == MAC_AX_EFUSE_BANK_BT) {
|
ret = switch_efuse_bank(adapter, MAC_AX_EFUSE_BANK_WIFI);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
}
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (ret != 0)
|
return ret;
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_get_efuse_avl_size(struct mac_ax_adapter *adapter, u32 *size)
|
{
|
u32 ret;
|
u8 *map;
|
u32 efuse_size = adapter->hw_info->log_efuse_size;
|
struct mac_ax_efuse_param *efuse_param = &adapter->efuse_param;
|
|
map = (u8 *)PLTFM_MALLOC(efuse_size);
|
if (!map) {
|
PLTFM_MSG_ERR("[ERR]malloc map\n");
|
return MACBUFALLOC;
|
}
|
|
ret = mac_dump_log_efuse(adapter, MAC_AX_EFUSE_PARSER_MAP,
|
MAC_AX_EFUSE_R_AUTO, map, 0);
|
|
PLTFM_FREE(map, efuse_size);
|
|
if (ret != 0)
|
return ret;
|
|
*size = adapter->hw_info->efuse_size - efuse_param->efuse_end;
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_get_efuse_avl_size_bt(struct mac_ax_adapter *adapter, u32 *size)
|
{
|
u32 ret;
|
u8 *map;
|
u32 efuse_size = adapter->hw_info->bt_log_efuse_size;
|
struct mac_ax_efuse_param *efuse_param = &adapter->efuse_param;
|
|
map = (u8 *)PLTFM_MALLOC(efuse_size);
|
if (!map) {
|
PLTFM_MSG_ERR("[ERR]malloc map\n");
|
return MACBUFALLOC;
|
}
|
|
ret = mac_dump_log_efuse_bt(adapter, MAC_AX_EFUSE_PARSER_MAP,
|
MAC_AX_EFUSE_R_DRV, map);
|
|
PLTFM_FREE(map, efuse_size);
|
|
if (ret != 0)
|
return ret;
|
|
*size = adapter->hw_info->bt_efuse_size - efuse_param->bt_efuse_end;
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_dump_log_efuse_plus(struct mac_ax_adapter *adapter,
|
enum mac_ax_efuse_parser_cfg parser_cfg,
|
enum mac_ax_efuse_read_cfg cfg,
|
u8 *efuse_map, bool is_limit)
|
{
|
u32 ret = 0;
|
struct mac_ax_hw_info *hw_info = adapter->hw_info;
|
u8 chip_id = hw_info->chip_id;
|
enum mac_ax_intf intf = adapter->hw_info->intf;
|
u32 map_size = hw_info->log_efuse_size;
|
|
switch (chip_id) {
|
case MAC_AX_CHIP_ID_8852A:
|
ret = mac_dump_log_efuse(adapter, parser_cfg, cfg,
|
efuse_map, is_limit);
|
break;
|
case MAC_AX_CHIP_ID_8852B:
|
case MAC_AX_CHIP_ID_8852C:
|
case MAC_AX_CHIP_ID_8192XB:
|
ret = mac_dump_log_efuse(adapter, parser_cfg, cfg,
|
efuse_map, is_limit);
|
if (ret)
|
return ret;
|
switch_dv(adapter, DAV);
|
if (is_limit) {
|
switch (intf) {
|
case MAC_AX_INTF_PCIE:
|
map_size = hw_info->limit_efuse_size_pcie;
|
break;
|
case MAC_AX_INTF_USB:
|
map_size = hw_info->limit_efuse_size_usb;
|
break;
|
case MAC_AX_INTF_SDIO:
|
map_size = hw_info->limit_efuse_size_sdio;
|
break;
|
default:
|
break;
|
}
|
}
|
ret = mac_dump_log_efuse(adapter, parser_cfg,
|
MAC_AX_EFUSE_R_DRV, efuse_map +
|
map_size, 0);
|
switch_dv(adapter, DDV);
|
break;
|
default:
|
break;
|
}
|
|
if (ret)
|
return ret;
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_dump_log_efuse(struct mac_ax_adapter *adapter,
|
enum mac_ax_efuse_parser_cfg parser_cfg,
|
enum mac_ax_efuse_read_cfg cfg,
|
u8 *efuse_map, bool is_limit)
|
{
|
u8 *map = NULL;
|
u32 ret, stat;
|
u32 efuse_size;
|
|
#if 0
|
if (cfg == MAC_AX_EFUSE_R_FW ||
|
(cfg == MAC_AX_EFUSE_R_AUTO &&
|
adapter->sm.fwdl == MAC_AX_FWDL_INIT_RDY))
|
return MACNOITEM;
|
#else
|
if (cfg == MAC_AX_EFUSE_R_FW &&
|
adapter->sm.fwdl != MAC_AX_FWDL_INIT_RDY)
|
return MACNOFW;
|
#endif
|
PLTFM_MSG_TRACE("[TRACE]cfg = %d\n", cfg);
|
|
ret = efuse_proc_ck(adapter);
|
if (ret != 0)
|
return ret;
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_LOG_MAP);
|
if (ret != 0)
|
return ret;
|
|
ret = switch_efuse_bank(adapter, MAC_AX_EFUSE_BANK_WIFI);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
efuse_size = *bank_efuse_info.log_map_size;
|
|
if (dv_sel == DAV) {
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_PHY_DAV);
|
if (ret != 0)
|
return ret;
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_LOG_DAV);
|
} else {
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_LOG);
|
if (ret != 0)
|
return ret;
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_PHY_WL);
|
}
|
if (ret)
|
return ret;
|
|
if (*bank_efuse_info.log_map_valid == 0) {
|
ret = proc_dump_efuse(adapter, cfg);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]dump efuse\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
if (*bank_efuse_info.phy_map_valid == 1) {
|
map = (u8 *)PLTFM_MALLOC(efuse_size);
|
if (!map) {
|
PLTFM_MSG_ERR("[ERR]malloc map\n");
|
stat = cnv_efuse_state(adapter,
|
MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return MACBUFALLOC;
|
}
|
|
ret = eeprom_parser(adapter, *bank_efuse_info.phy_map,
|
map, parser_cfg);
|
if (ret != 0) {
|
PLTFM_FREE(map, efuse_size);
|
stat = cnv_efuse_state(adapter,
|
MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
PLTFM_MUTEX_LOCK(&efuse_tbl.lock);
|
PLTFM_MEMCPY(*bank_efuse_info.log_map, map,
|
efuse_size);
|
*bank_efuse_info.log_map_valid = 1;
|
PLTFM_MUTEX_UNLOCK(&efuse_tbl.lock);
|
PLTFM_FREE(map, efuse_size);
|
}
|
}
|
|
query_status_map(adapter, MAC_AX_DUMP_LOGICAL_EFUSE,
|
efuse_map, is_limit);
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (ret != 0)
|
return ret;
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_read_log_efuse_plus(struct mac_ax_adapter *adapter, u32 addr, u32 size,
|
u8 *val)
|
{
|
u32 ret = 0;
|
struct mac_ax_hw_info *hw_info = adapter->hw_info;
|
u8 chip_id = hw_info->chip_id;
|
u32 efuse_size = hw_info->log_efuse_size;
|
u32 size1, size2;
|
|
switch (chip_id) {
|
case MAC_AX_CHIP_ID_8852A:
|
ret = mac_read_log_efuse(adapter, addr, size, val);
|
break;
|
case MAC_AX_CHIP_ID_8852B:
|
case MAC_AX_CHIP_ID_8852C:
|
case MAC_AX_CHIP_ID_8192XB:
|
if (addr < efuse_size && addr + size <= efuse_size) {
|
ret = mac_read_log_efuse(adapter, addr, size, val);
|
} else if (addr >= efuse_size) {
|
switch_dv(adapter, DAV);
|
ret = mac_read_log_efuse(adapter, addr - efuse_size,
|
size, val);
|
switch_dv(adapter, DDV);
|
} else if (addr < efuse_size && addr + size > efuse_size) {
|
size1 = efuse_size - addr;
|
size2 = addr + size - efuse_size;
|
|
ret = mac_read_log_efuse(adapter, addr, size1, val);
|
if (ret)
|
return ret;
|
|
switch_dv(adapter, DAV);
|
ret = mac_read_log_efuse(adapter, 0, size2,
|
val + size1);
|
switch_dv(adapter, DDV);
|
}
|
if (ret)
|
return ret;
|
break;
|
default:
|
break;
|
}
|
|
if (ret)
|
return ret;
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_read_log_efuse(struct mac_ax_adapter *adapter, u32 addr, u32 size,
|
u8 *val)
|
{
|
u8 *map = NULL;
|
u32 ret = 0, stat;
|
u32 efuse_size;
|
|
ret = efuse_proc_ck(adapter);
|
if (ret != 0)
|
return ret;
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_LOG_MAP);
|
if (ret != 0)
|
return ret;
|
|
ret = switch_efuse_bank(adapter, MAC_AX_EFUSE_BANK_WIFI);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
efuse_size = *bank_efuse_info.log_map_size;
|
|
if (addr >= efuse_size || addr + size > efuse_size) {
|
PLTFM_MSG_ERR("[ERR] Wrong efuse index\n");
|
return MACEFUSESIZE;
|
}
|
|
if (dv_sel == DAV) {
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_PHY_DAV);
|
if (ret)
|
return ret;
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_LOG_DAV);
|
} else {
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_PHY_WL);
|
if (ret)
|
return ret;
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_LOG);
|
}
|
if (ret)
|
return ret;
|
|
map = (u8 *)PLTFM_MALLOC(efuse_size);
|
if (!map) {
|
PLTFM_MSG_ERR("[ERR]malloc map\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return MACBUFALLOC;
|
}
|
|
ret = read_log_efuse_map(adapter, map, efuse_size);
|
if (ret != 0) {
|
PLTFM_FREE(map, efuse_size);
|
PLTFM_MSG_ERR("[ERR]read logical efuse\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
PLTFM_MUTEX_LOCK(&efuse_tbl.lock);
|
PLTFM_MEMCPY(val, map + addr, size);
|
PLTFM_MUTEX_UNLOCK(&efuse_tbl.lock);
|
PLTFM_FREE(map, efuse_size);
|
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_write_log_efuse_plus(struct mac_ax_adapter *adapter, u32 addr, u8 val)
|
{
|
u32 ret = 0;
|
struct mac_ax_hw_info *hw_info = adapter->hw_info;
|
u8 chip_id = hw_info->chip_id;
|
u32 efuse_size = hw_info->log_efuse_size;
|
|
switch (chip_id) {
|
case MAC_AX_CHIP_ID_8852A:
|
ret = mac_write_log_efuse(adapter, addr, val);
|
break;
|
case MAC_AX_CHIP_ID_8852B:
|
case MAC_AX_CHIP_ID_8852C:
|
case MAC_AX_CHIP_ID_8192XB:
|
if (addr < efuse_size) {
|
ret = mac_write_log_efuse(adapter, addr, val);
|
} else {
|
switch_dv(adapter, DAV);
|
ret = mac_write_log_efuse(adapter,
|
addr - efuse_size, val);
|
switch_dv(adapter, DDV);
|
}
|
break;
|
default:
|
break;
|
}
|
|
if (ret)
|
return ret;
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_write_log_efuse(struct mac_ax_adapter *adapter, u32 addr, u8 val)
|
{
|
u32 ret, stat;
|
|
ret = efuse_proc_ck(adapter);
|
if (ret != 0)
|
return ret;
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_LOG_MAP);
|
if (ret != 0)
|
return ret;
|
|
ret = switch_efuse_bank(adapter, MAC_AX_EFUSE_BANK_WIFI);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
if (addr >= *bank_efuse_info.log_map_size) {
|
PLTFM_MSG_ERR("[ERR]addr is too large\n");
|
return MACEFUSESIZE;
|
}
|
|
if (dv_sel == DAV) {
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_PHY_DAV);
|
if (ret)
|
return ret;
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_LOG_DAV);
|
} else {
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_PHY_WL);
|
if (ret)
|
return ret;
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_LOG);
|
}
|
if (ret)
|
return ret;
|
|
ret = proc_write_log_efuse(adapter, addr, val);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]write logical efuse\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (ret != 0)
|
return ret;
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_dump_log_efuse_bt(struct mac_ax_adapter *adapter,
|
enum mac_ax_efuse_parser_cfg parser_cfg,
|
enum mac_ax_efuse_read_cfg cfg,
|
u8 *efuse_map)
|
{
|
u8 *map = NULL;
|
u32 ret, stat;
|
u32 efuse_size = adapter->hw_info->bt_log_efuse_size;
|
struct mac_ax_efuse_param *efuse_param = &adapter->efuse_param;
|
|
#if 0
|
if (cfg == MAC_AX_EFUSE_R_FW ||
|
(cfg == MAC_AX_EFUSE_R_AUTO &&
|
adapter->sm.fwdl == MAC_AX_FWDL_INIT_RDY))
|
return MACNOITEM;
|
#else
|
if (cfg == MAC_AX_EFUSE_R_FW &&
|
adapter->sm.fwdl != MAC_AX_FWDL_INIT_RDY)
|
return MACNOFW;
|
#endif
|
|
PLTFM_MSG_TRACE("[TRACE]cfg = %d\n", cfg);
|
|
ret = efuse_proc_ck(adapter);
|
if (ret != 0)
|
return ret;
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_LOG_MAP);
|
if (ret != 0)
|
return ret;
|
|
ret = switch_efuse_bank(adapter, MAC_AX_EFUSE_BANK_BT);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_LOG_BT);
|
if (ret != 0)
|
return ret;
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_PHY_BT);
|
if (ret != 0)
|
return ret;
|
|
if (efuse_param->bt_log_efuse_map_valid == 0) {
|
ret = proc_dump_efuse(adapter, cfg);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]dump efuse\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
if (efuse_param->bt_efuse_map_valid == 1) {
|
map = (u8 *)PLTFM_MALLOC(efuse_size);
|
if (!map) {
|
PLTFM_MSG_ERR("[ERR]malloc map\n");
|
stat = cnv_efuse_state(adapter,
|
MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return MACBUFALLOC;
|
}
|
|
ret = eeprom_parser(adapter, efuse_param->bt_efuse_map,
|
map, parser_cfg);
|
if (ret != 0) {
|
PLTFM_FREE(map, efuse_size);
|
stat = cnv_efuse_state(adapter,
|
MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
PLTFM_MUTEX_LOCK(&efuse_tbl.lock);
|
PLTFM_MEMCPY(efuse_param->bt_log_efuse_map, map,
|
efuse_size);
|
efuse_param->bt_log_efuse_map_valid = 1;
|
PLTFM_MUTEX_UNLOCK(&efuse_tbl.lock);
|
PLTFM_FREE(map, efuse_size);
|
}
|
}
|
|
query_status_map(adapter, MAC_AX_DUMP_LOGICAL_EFUSE, efuse_map, 0);
|
|
ret = switch_efuse_bank(adapter, MAC_AX_EFUSE_BANK_WIFI);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (ret != 0)
|
return ret;
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_read_log_efuse_bt(struct mac_ax_adapter *adapter, u32 addr, u32 size,
|
u8 *val)
|
{
|
u8 *map = NULL;
|
u32 ret, stat;
|
u32 efuse_size = adapter->hw_info->bt_log_efuse_size;
|
|
if (addr >= efuse_size || addr + size > efuse_size) {
|
PLTFM_MSG_ERR("[ERR] Wrong efuse index\n");
|
return MACEFUSESIZE;
|
}
|
|
ret = efuse_proc_ck(adapter);
|
if (ret != 0)
|
return ret;
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_LOG_MAP);
|
if (ret != 0)
|
return ret;
|
|
ret = switch_efuse_bank(adapter, MAC_AX_EFUSE_BANK_BT);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_PHY_BT);
|
if (ret)
|
return ret;
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_LOG_BT);
|
if (ret)
|
return ret;
|
|
map = (u8 *)PLTFM_MALLOC(efuse_size);
|
if (!map) {
|
PLTFM_MSG_ERR("[ERR]malloc map\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return MACBUFALLOC;
|
}
|
PLTFM_MEMSET(map, 0xFF, efuse_size);
|
|
ret = read_log_efuse_map(adapter, map, efuse_size);
|
if (ret != 0) {
|
PLTFM_FREE(map, efuse_size);
|
PLTFM_MSG_ERR("[ERR]read logical efuse\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
PLTFM_MUTEX_LOCK(&efuse_tbl.lock);
|
PLTFM_MEMCPY(val, map + addr, size);
|
PLTFM_MUTEX_UNLOCK(&efuse_tbl.lock);
|
PLTFM_FREE(map, efuse_size);
|
|
ret = switch_efuse_bank(adapter, MAC_AX_EFUSE_BANK_WIFI);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_write_log_efuse_bt(struct mac_ax_adapter *adapter, u32 addr, u8 val)
|
{
|
u32 ret, stat;
|
|
if (addr >= adapter->hw_info->log_efuse_size) {
|
PLTFM_MSG_ERR("[ERR]addr is too large\n");
|
return MACEFUSESIZE;
|
}
|
|
ret = efuse_proc_ck(adapter);
|
if (ret != 0)
|
return ret;
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_LOG_MAP);
|
if (ret != 0)
|
return ret;
|
|
ret = switch_efuse_bank(adapter, MAC_AX_EFUSE_BANK_BT);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_PHY_BT);
|
if (ret)
|
return ret;
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_LOG_BT);
|
if (ret)
|
return ret;
|
|
ret = proc_write_log_efuse(adapter, addr, val);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]write logical efuse\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
ret = switch_efuse_bank(adapter, MAC_AX_EFUSE_BANK_WIFI);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (ret != 0)
|
return ret;
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_pg_efuse_by_map_plus(struct mac_ax_adapter *adapter,
|
struct mac_ax_pg_efuse_info *info,
|
enum mac_ax_efuse_read_cfg cfg,
|
bool part, bool is_limit)
|
{
|
u8 chip_id = adapter->hw_info->chip_id;
|
u32 ret;
|
struct mac_ax_pg_efuse_info info_DAV;
|
u32 ver_len = 0;
|
struct mac_ax_hw_info *hw_info = adapter->hw_info;
|
enum mac_ax_intf intf = adapter->hw_info->intf;
|
u32 map_size = adapter->hw_info->log_efuse_size;
|
//u8 *phy_map = NULL;
|
|
ret = mac_get_hw_value(adapter,
|
MAC_AX_HW_GET_EFUSE_VERSION_SIZE, &ver_len);
|
if (ret)
|
return ret;
|
|
switch (chip_id) {
|
case MAC_AX_CHIP_ID_8852A:
|
ret = mac_pg_efuse_by_map(adapter, info, cfg, part, is_limit);
|
break;
|
case MAC_AX_CHIP_ID_8852B:
|
case MAC_AX_CHIP_ID_8852C:
|
case MAC_AX_CHIP_ID_8192XB:
|
/* cut map */
|
if (is_limit) {
|
switch (intf) {
|
case MAC_AX_INTF_PCIE:
|
map_size = hw_info->limit_efuse_size_pcie;
|
break;
|
case MAC_AX_INTF_USB:
|
map_size = hw_info->limit_efuse_size_usb;
|
break;
|
case MAC_AX_INTF_SDIO:
|
map_size = hw_info->limit_efuse_size_sdio;
|
break;
|
default:
|
break;
|
}
|
}
|
|
info_DAV.efuse_map_size = hw_info->dav_log_efuse_size;
|
info_DAV.efuse_mask_size = hw_info->dav_log_efuse_size >> 4;
|
|
info_DAV.efuse_map = (u8 *)PLTFM_MALLOC(info_DAV.efuse_map_size + ver_len);
|
if (!info_DAV.efuse_map) {
|
PLTFM_MSG_ERR("[ERR]malloc map\n");
|
return MACBUFALLOC;
|
}
|
info_DAV.efuse_mask = (u8 *)PLTFM_MALLOC(info_DAV.efuse_mask_size + ver_len);
|
if (!info_DAV.efuse_mask) {
|
PLTFM_MSG_ERR("[ERR]malloc map\n");
|
return MACBUFALLOC;
|
}
|
|
PLTFM_MEMCPY(info_DAV.efuse_map, info->efuse_map + map_size,
|
info_DAV.efuse_map_size + ver_len);
|
PLTFM_MEMCPY(info_DAV.efuse_mask,
|
info->efuse_mask + (map_size >> 4),
|
info_DAV.efuse_mask_size + ver_len);
|
|
info->efuse_map_size -= info_DAV.efuse_map_size;
|
info->efuse_mask_size -= info_DAV.efuse_mask_size;
|
|
PLTFM_MEMCPY(info->efuse_map + map_size, info->efuse_map +
|
map_size + info_DAV.efuse_map_size, ver_len);
|
PLTFM_MEMCPY(info->efuse_mask + (map_size >> 4),
|
info->efuse_mask + (map_size >> 4) +
|
info_DAV.efuse_mask_size, ver_len);
|
|
ret = mac_pg_efuse_by_map(adapter, info, cfg, part, is_limit);
|
if (ret)
|
return ret;
|
switch_dv(adapter, DAV);
|
ret = mac_pg_efuse_by_map(adapter,
|
&info_DAV, cfg, part, 0);
|
//phy_map = (u8 *)PLTFM_MALLOC(hw_info->wl_efuse_size_DAV);
|
//if (!phy_map) {
|
// PLTFM_MSG_ERR("[ERR]malloc map\n");
|
// return MACBUFALLOC;
|
//}
|
//PLTFM_MEMSET(phy_map, 0xFF, hw_info->wl_efuse_size_DAV);
|
//ret = mac_pg_simulator(adapter, &info_DAV, phy_map);
|
switch_dv(adapter, DDV);
|
break;
|
default:
|
break;
|
}
|
if (ret)
|
return ret;
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_pg_efuse_by_map(struct mac_ax_adapter *adapter,
|
struct mac_ax_pg_efuse_info *info,
|
enum mac_ax_efuse_read_cfg cfg,
|
bool part, bool is_limit)
|
{
|
u32 ret, stat;
|
enum mac_ax_intf intf = adapter->hw_info->intf;
|
u32 map_size = adapter->hw_info->log_efuse_size;
|
u32 ver_len = 0;
|
|
if (is_limit) {
|
switch (intf) {
|
case MAC_AX_INTF_PCIE:
|
map_size = adapter->hw_info->limit_efuse_size_pcie;
|
break;
|
case MAC_AX_INTF_USB:
|
map_size = adapter->hw_info->limit_efuse_size_usb;
|
break;
|
case MAC_AX_INTF_SDIO:
|
map_size = adapter->hw_info->limit_efuse_size_sdio;
|
break;
|
default:
|
break;
|
}
|
}
|
|
if (dv_sel == DAV)
|
map_size = adapter->hw_info->dav_log_efuse_size;
|
|
if (info->efuse_map_size != map_size) {
|
PLTFM_MSG_ERR("[ERR]map size error\n");
|
return MACEFUSESIZE;
|
}
|
|
if ((info->efuse_map_size & 0xF) > 0) {
|
PLTFM_MSG_ERR("[ERR]not multiple of 16\n");
|
return MACEFUSESIZE;
|
}
|
|
if (info->efuse_mask_size != info->efuse_map_size >> 4) {
|
PLTFM_MSG_ERR("[ERR]mask size error\n");
|
return MACEFUSESIZE;
|
}
|
|
if (!info->efuse_map) {
|
PLTFM_MSG_ERR("[ERR]map is NULL\n");
|
return MACNPTR;
|
}
|
|
if (!info->efuse_mask) {
|
PLTFM_MSG_ERR("[ERR]mask is NULL\n");
|
return MACNPTR;
|
}
|
|
ret = mac_get_hw_value(adapter,
|
MAC_AX_HW_GET_EFUSE_VERSION_SIZE, &ver_len);
|
if (ret)
|
return ret;
|
ret = compare_version(adapter, info, ver_len);
|
if (ret != 0)
|
return ret;
|
|
ret = efuse_proc_ck(adapter);
|
if (ret != 0)
|
return ret;
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_PHY);
|
if (ret != 0)
|
return ret;
|
|
ret = switch_efuse_bank(adapter, MAC_AX_EFUSE_BANK_WIFI);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
if (dv_sel == DAV) {
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_PHY_DAV);
|
if (ret)
|
return ret;
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_LOG_DAV);
|
} else {
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_PHY_WL);
|
if (ret)
|
return ret;
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_LOG);
|
}
|
if (ret)
|
return ret;
|
|
if (part)
|
ret = adjust_mask(adapter, info);
|
if (ret != 0) {
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
ret = proc_pg_efuse_by_map(adapter, info, cfg);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]pg efuse\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (ret != 0)
|
return ret;
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_pg_efuse_by_map_bt(struct mac_ax_adapter *adapter,
|
struct mac_ax_pg_efuse_info *info,
|
enum mac_ax_efuse_read_cfg cfg)
|
{
|
u32 ret, stat;
|
|
if (info->efuse_map_size != adapter->hw_info->bt_log_efuse_size) {
|
PLTFM_MSG_ERR("[ERR]map size error\n");
|
return MACEFUSESIZE;
|
}
|
|
if ((info->efuse_map_size & 0xF) > 0) {
|
PLTFM_MSG_ERR("[ERR]not multiple of 16\n");
|
return MACEFUSESIZE;
|
}
|
|
if (info->efuse_mask_size != info->efuse_map_size >> 4) {
|
PLTFM_MSG_ERR("[ERR]mask size error\n");
|
return MACEFUSESIZE;
|
}
|
|
if (!info->efuse_map) {
|
PLTFM_MSG_ERR("[ERR]map is NULL\n");
|
return MACNPTR;
|
}
|
|
if (!info->efuse_mask) {
|
PLTFM_MSG_ERR("[ERR]mask is NULL\n");
|
return MACNPTR;
|
}
|
|
ret = efuse_proc_ck(adapter);
|
if (ret != 0)
|
return ret;
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_PHY);
|
if (ret != 0)
|
return ret;
|
|
ret = switch_efuse_bank(adapter, MAC_AX_EFUSE_BANK_BT);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
ret = proc_pg_efuse_by_map(adapter, info, cfg);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]pg efuse\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
ret = switch_efuse_bank(adapter, MAC_AX_EFUSE_BANK_WIFI);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (ret != 0)
|
return ret;
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_mask_log_efuse(struct mac_ax_adapter *adapter,
|
struct mac_ax_pg_efuse_info *info)
|
{
|
if (info->efuse_map_size != adapter->hw_info->log_efuse_size) {
|
PLTFM_MSG_ERR("[ERR]map size error\n");
|
return MACEFUSESIZE;
|
}
|
|
if ((info->efuse_map_size & 0xF) > 0) {
|
PLTFM_MSG_ERR("[ERR]not multiple of 16\n");
|
return MACEFUSESIZE;
|
}
|
|
if (info->efuse_mask_size != info->efuse_map_size >> 4) {
|
PLTFM_MSG_ERR("[ERR]mask size error\n");
|
return MACEFUSESIZE;
|
}
|
|
if (!info->efuse_map) {
|
PLTFM_MSG_ERR("[ERR]map is NULL\n");
|
return MACNPTR;
|
}
|
|
if (!info->efuse_mask) {
|
PLTFM_MSG_ERR("[ERR]mask is NULL\n");
|
return MACNPTR;
|
}
|
|
mask_eeprom(adapter, info);
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_pg_sec_data_by_map(struct mac_ax_adapter *adapter,
|
struct mac_ax_pg_efuse_info *info)
|
{
|
u32 ret, stat;
|
u32 addr, efuse_size, sec_data_size;
|
u8 *map_pg;
|
u32 mac_addr_size = 6;
|
|
/*Soar TBD add MAC address PG*/
|
|
map_pg = info->efuse_map;
|
efuse_size = adapter->hw_info->efuse_size;
|
sec_data_size = adapter->hw_info->sec_data_efuse_size;
|
|
if (info->efuse_map_size != adapter->hw_info->sec_data_efuse_size) {
|
PLTFM_MSG_ERR("[ERR]map size error\n");
|
return MACEFUSESIZE;
|
}
|
|
if (!info->efuse_map) {
|
PLTFM_MSG_ERR("[ERR]map is NULL\n");
|
return MACNPTR;
|
}
|
|
ret = efuse_proc_ck(adapter);
|
if (ret != 0)
|
return ret;
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_PHY);
|
if (ret != 0)
|
return ret;
|
|
ret = switch_efuse_bank(adapter, MAC_AX_EFUSE_BANK_WIFI);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
enable_efuse_sw_pwr_cut(adapter, 1);
|
for (addr = mac_addr_size; addr < sec_data_size; addr++) {
|
ret = write_hw_efuse(adapter, addr + efuse_size,
|
*(map_pg + addr));
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]write physical efuse\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
}
|
disable_efuse_sw_pwr_cut(adapter, 1);
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (ret != 0)
|
return ret;
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_cmp_sec_data_by_map(struct mac_ax_adapter *adapter,
|
struct mac_ax_pg_efuse_info *info)
|
{
|
u32 ret, stat;
|
u32 addr, start_addr, sec_data_size;
|
u16 val16;
|
u8 *map_pg;
|
|
map_pg = info->efuse_map;
|
start_addr = adapter->hw_info->efuse_size;
|
sec_data_size = adapter->hw_info->sec_data_efuse_size;
|
|
if (info->efuse_map_size != adapter->hw_info->sec_data_efuse_size) {
|
PLTFM_MSG_ERR("[ERR]map size error\n");
|
return MACEFUSESIZE;
|
}
|
|
if (!info->efuse_map) {
|
PLTFM_MSG_ERR("[ERR]map is NULL\n");
|
return MACNPTR;
|
}
|
|
ret = efuse_proc_ck(adapter);
|
if (ret != 0)
|
return ret;
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_PHY);
|
if (ret != 0)
|
return ret;
|
|
ret = switch_efuse_bank(adapter, MAC_AX_EFUSE_BANK_WIFI);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
return ret;
|
}
|
|
for (addr = 0;
|
addr < sec_data_size; addr += 2) {
|
val16 = *(map_pg + addr) | (*(map_pg + addr + 1) << 8);
|
ret = cmp_hw_efuse(adapter, addr + start_addr, val16);
|
if (ret == MACEFUSECMP) {
|
*(map_pg + addr) = 0xFF;
|
*(map_pg + addr + 1) = 0xFF;
|
} else if (ret == MACEFUSEREAD) {
|
PLTFM_MSG_ERR("[ERR]compare hw efuse\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != 0)
|
return stat;
|
} else if (ret == 0) {
|
*(map_pg + addr) = 0x00;
|
*(map_pg + addr + 1) = 0x00;
|
}
|
}
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (ret != 0)
|
return ret;
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_get_efuse_info(struct mac_ax_adapter *adapter, u8 *efuse_map,
|
enum rtw_efuse_info id, void *value, u32 length,
|
u8 *autoload_status)
|
{
|
u32 offset, def_val;
|
u32 ret;
|
enum mac_ax_intf intf = adapter->hw_info->intf;
|
struct efuse_info info;
|
|
switch (intf) {
|
case MAC_AX_INTF_USB:
|
info = (is_chip_id(adapter, MAC_AX_CHIP_ID_8852A)) ?
|
efuse_info_usb_8852a : efuse_info_usb_8852b;
|
break;
|
case MAC_AX_INTF_PCIE:
|
info = efuse_info_pcie;
|
break;
|
case MAC_AX_INTF_SDIO:
|
info = efuse_info_sdio;
|
break;
|
default:
|
return MACINTF;
|
}
|
|
ret = compare_info_length(&info, id, length);
|
if (ret != MACSUCCESS)
|
return ret;
|
|
switch (id) {
|
case EFUSE_INFO_MAC_ADDR:
|
offset = info.offset->mac_addr;
|
def_val = info.def_val->mac_addr;
|
break;
|
case EFUSE_INFO_MAC_PID:
|
offset = info.offset->pid;
|
def_val = info.def_val->pid;
|
break;
|
case EFUSE_INFO_MAC_DID:
|
offset = info.offset->did;
|
def_val = info.def_val->did;
|
break;
|
case EFUSE_INFO_MAC_VID:
|
offset = info.offset->vid;
|
def_val = info.def_val->vid;
|
break;
|
case EFUSE_INFO_MAC_SVID:
|
offset = info.offset->svid;
|
def_val = info.def_val->svid;
|
break;
|
case EFUSE_INFO_MAC_SMID:
|
offset = info.offset->smid;
|
def_val = info.def_val->smid;
|
break;
|
default:
|
return MACNOITEM;
|
}
|
|
if (*autoload_status == 0)
|
PLTFM_MEMCPY(value, &def_val, 1);
|
else
|
PLTFM_MEMCPY(value, efuse_map + offset, length);
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_set_efuse_info(struct mac_ax_adapter *adapter, u8 *efuse_map,
|
enum rtw_efuse_info id, void *value, u32 length)
|
{
|
u32 offset;
|
u32 ret;
|
enum mac_ax_intf intf = adapter->hw_info->intf;
|
struct efuse_info info;
|
|
switch (intf) {
|
case MAC_AX_INTF_USB:
|
info = (is_chip_id(adapter, MAC_AX_CHIP_ID_8852A)) ?
|
efuse_info_usb_8852a : efuse_info_usb_8852b;
|
break;
|
case MAC_AX_INTF_PCIE:
|
info = efuse_info_pcie;
|
break;
|
case MAC_AX_INTF_SDIO:
|
info = efuse_info_sdio;
|
break;
|
default:
|
return MACINTF;
|
}
|
|
ret = compare_info_length(&info, id, length);
|
if (ret != MACSUCCESS)
|
return ret;
|
|
switch (id) {
|
case EFUSE_INFO_MAC_ADDR:
|
offset = info.offset->mac_addr;
|
break;
|
case EFUSE_INFO_MAC_PID:
|
offset = info.offset->pid;
|
break;
|
case EFUSE_INFO_MAC_DID:
|
offset = info.offset->did;
|
break;
|
case EFUSE_INFO_MAC_VID:
|
offset = info.offset->vid;
|
break;
|
case EFUSE_INFO_MAC_SVID:
|
offset = info.offset->svid;
|
break;
|
case EFUSE_INFO_MAC_SMID:
|
offset = info.offset->smid;
|
break;
|
default:
|
return MACNOITEM;
|
}
|
|
PLTFM_MEMCPY(efuse_map + offset, value, length);
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_read_hidden_rpt(struct mac_ax_adapter *adapter,
|
struct mac_defeature_value *rpt)
|
{
|
#if 0
|
return MACNOITEM;
|
#else
|
u32 ret, stat;
|
struct mac_ax_h2creg_info h2c;
|
struct mac_ax_c2hreg_poll c2h;
|
struct fwcmd_c2hreg *c2h_content;
|
|
ret = efuse_proc_ck(adapter);
|
if (ret != MACSUCCESS)
|
return ret;
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_PHY);
|
if (ret != MACSUCCESS)
|
return ret;
|
|
ret = switch_efuse_bank(adapter, MAC_AX_EFUSE_BANK_WIFI);
|
if (ret != MACSUCCESS) {
|
PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n");
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat != MACSUCCESS)
|
return stat;
|
return ret;
|
}
|
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_PHY_WL);
|
if (ret != MACSUCCESS)
|
return ret;
|
|
h2c.id = FWCMD_H2CREG_FUNC_HIDDEN_GET;
|
h2c.content_len = sizeof(struct mac_efuse_hidden_h2creg);
|
|
c2h.polling_id = FWCMD_C2HREG_FUNC_EFUSE_HIDDEN;
|
c2h.retry_cnt = EFUSE_C2HREG_WAIT_CNT;
|
c2h.retry_wait_us = EFUSE_C2HREG_RETRY_WAIT_US;
|
|
ret = proc_msg_reg(adapter, &h2c, &c2h);
|
if (ret != MACSUCCESS) {
|
PLTFM_MSG_ERR("[ERR]read hidden rpt proc msg reg %d\n", ret);
|
stat = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (stat)
|
return stat;
|
return ret;
|
}
|
|
c2h_content = &c2h.c2hreg_cont.c2h_content;
|
rpt->rx_spatial_stream =
|
GET_FIELD(c2h_content->dword0, FWCMD_C2HREG_EFUSE_HIDDEN_RX_NSS);
|
rpt->bandwidth =
|
GET_FIELD(c2h_content->dword0, FWCMD_C2HREG_EFUSE_HIDDEN_BW);
|
rpt->tx_spatial_stream =
|
GET_FIELD(c2h_content->dword1, FWCMD_C2HREG_EFUSE_HIDDEN_TX_NSS);
|
rpt->protocol_80211 =
|
GET_FIELD(c2h_content->dword1, FWCMD_C2HREG_EFUSE_HIDDEN_PROT80211);
|
rpt->NIC_router =
|
GET_FIELD(c2h_content->dword1, FWCMD_C2HREG_EFUSE_HIDDEN_NIC_ROUTER);
|
rpt->wl_func_support =
|
GET_FIELD(c2h_content->dword1,
|
FWCMD_C2HREG_EFUSE_HIDDEN_WL_FUNC_SUPPORT);
|
rpt->hw_special_type =
|
GET_FIELD(c2h_content->dword2,
|
FWCMD_C2HREG_EFUSE_HIDDEN_HW_SPECIAL_TYPE);
|
rpt->uuid =
|
GET_FIELD(c2h_content->dword3,
|
FWCMD_C2HREG_EFUSE_HIDDEN_UUID_BYTE_3) << 24 |
|
GET_FIELD(c2h_content->dword2,
|
FWCMD_C2HREG_EFUSE_HIDDEN_UUID_BYTE_2) << 16 |
|
GET_FIELD(c2h_content->dword2,
|
FWCMD_C2HREG_EFUSE_HIDDEN_UUID_BYTE_1) << 8 |
|
GET_FIELD(c2h_content->dword2,
|
FWCMD_C2HREG_EFUSE_HIDDEN_UUID_BYTE_0);
|
|
ret = cnv_efuse_state(adapter, MAC_AX_EFUSE_IDLE);
|
if (ret != MACSUCCESS)
|
return ret;
|
|
return MACSUCCESS;
|
#endif
|
}
|
|
u32 mac_check_efuse_autoload(struct mac_ax_adapter *adapter,
|
u8 *autoload_status)
|
{
|
#define AUTOLOAD_SUS 1
|
#define AUTOLOAD_FAIL 0
|
|
struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter);
|
|
if (MAC_REG_R16(R_AX_SYS_EEPROM_CTRL) & B_AX_AUTOLOAD_SUS)
|
*autoload_status = AUTOLOAD_SUS;
|
else
|
*autoload_status = AUTOLOAD_FAIL;
|
|
return MACSUCCESS;
|
|
#undef AUTOLOAD_SUS
|
#undef AUTOLOAD_FAIL
|
}
|
|
u32 mac_pg_simulator_plus(struct mac_ax_adapter *adapter,
|
struct mac_ax_pg_efuse_info *info, u8 *phy_map)
|
{
|
u8 chip_id = adapter->hw_info->chip_id;
|
u32 ret;
|
struct mac_ax_pg_efuse_info info_dav;
|
u32 ver_len = 0;
|
struct mac_ax_hw_info *hw_info = adapter->hw_info;
|
u32 map_size = hw_info->log_efuse_size;
|
|
ret = mac_get_hw_value(adapter,
|
MAC_AX_HW_GET_EFUSE_VERSION_SIZE, &ver_len);
|
if (ret)
|
return ret;
|
|
switch (chip_id) {
|
case MAC_AX_CHIP_ID_8852A:
|
ret = mac_pg_simulator(adapter, info, phy_map);
|
break;
|
case MAC_AX_CHIP_ID_8852B:
|
case MAC_AX_CHIP_ID_8852C:
|
case MAC_AX_CHIP_ID_8192XB:
|
/* cut log map */
|
info_dav.efuse_map_size = hw_info->dav_log_efuse_size;
|
info_dav.efuse_mask_size = hw_info->dav_log_efuse_size >> 4;
|
|
info_dav.efuse_map =
|
(u8 *)PLTFM_MALLOC(info_dav.efuse_map_size + ver_len);
|
if (!info_dav.efuse_map) {
|
PLTFM_MSG_ERR("[ERR]malloc map\n");
|
return MACBUFALLOC;
|
}
|
info_dav.efuse_mask =
|
(u8 *)PLTFM_MALLOC(info_dav.efuse_mask_size +
|
ver_len);
|
if (!info_dav.efuse_mask) {
|
PLTFM_MSG_ERR("[ERR]malloc map\n");
|
return MACBUFALLOC;
|
}
|
|
PLTFM_MEMCPY(info_dav.efuse_map, info->efuse_map + map_size,
|
info_dav.efuse_map_size + ver_len);
|
PLTFM_MEMCPY(info_dav.efuse_mask,
|
info->efuse_mask + (map_size >> 4),
|
info_dav.efuse_mask_size + ver_len);
|
|
info->efuse_map_size -= info_dav.efuse_map_size;
|
info->efuse_mask_size -= info_dav.efuse_mask_size;
|
|
PLTFM_MEMCPY(info->efuse_map + map_size, info->efuse_map +
|
map_size + info_dav.efuse_map_size, ver_len);
|
PLTFM_MEMCPY(info->efuse_mask + (map_size >> 4),
|
info->efuse_mask + (map_size >> 4) +
|
info_dav.efuse_mask_size, ver_len);
|
|
ret = mac_pg_simulator(adapter, info, phy_map);
|
if (ret)
|
return ret;
|
switch_dv(adapter, DAV);
|
ret = mac_pg_simulator(adapter, &info_dav,
|
phy_map + hw_info->wl_efuse_size);
|
switch_dv(adapter, DDV);
|
PLTFM_MEMCPY(info->efuse_map + map_size, info_dav.efuse_map,
|
info_dav.efuse_map_size + ver_len);
|
break;
|
default:
|
break;
|
}
|
if (ret)
|
return ret;
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_pg_simulator(struct mac_ax_adapter *adapter,
|
struct mac_ax_pg_efuse_info *info, u8 *phy_map)
|
{
|
u8 *updated_mask;
|
u32 ret;
|
u32 mask_size;
|
u8 *log_efuse_map = NULL;
|
enum mac_ax_intf intf = adapter->hw_info->intf;
|
u32 map_size = adapter->hw_info->log_efuse_size;
|
u32 ver_len = 0;
|
|
if (info->efuse_map_size != adapter->hw_info->log_efuse_size) {
|
switch (intf) {
|
case MAC_AX_INTF_PCIE:
|
map_size = adapter->hw_info->limit_efuse_size_pcie;
|
break;
|
case MAC_AX_INTF_USB:
|
map_size = adapter->hw_info->limit_efuse_size_usb;
|
break;
|
case MAC_AX_INTF_SDIO:
|
map_size = adapter->hw_info->limit_efuse_size_sdio;
|
break;
|
default:
|
break;
|
}
|
}
|
|
if (dv_sel == DAV)
|
map_size = adapter->hw_info->dav_log_efuse_size;
|
|
if (info->efuse_map_size != map_size) {
|
PLTFM_MSG_ERR("[ERR]map size error\n");
|
return MACEFUSESIZE;
|
}
|
|
mask_size = map_size >> 4;
|
|
ret = mac_get_hw_value(adapter,
|
MAC_AX_HW_GET_EFUSE_VERSION_SIZE, &ver_len);
|
if (ret)
|
return ret;
|
|
ret = compare_version(adapter, info, ver_len);
|
if (ret != 0)
|
return ret;
|
|
ret = switch_efuse_bank(adapter, MAC_AX_EFUSE_BANK_WIFI);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n");
|
return ret;
|
}
|
|
if (dv_sel == DAV) {
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_PHY_DAV);
|
if (ret)
|
return ret;
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_LOG_DAV);
|
} else {
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_PHY_WL);
|
if (ret)
|
return ret;
|
ret = efuse_map_init(adapter, EFUSE_MAP_SEL_LOG);
|
}
|
if (ret)
|
return ret;
|
|
ret = eeprom_parser(adapter, phy_map, *bank_efuse_info.log_map,
|
MAC_AX_EFUSE_PARSER_MAP);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]logical map parser\n");
|
return ret;
|
}
|
PLTFM_MEMCPY(*bank_efuse_info.phy_map, phy_map,
|
*bank_efuse_info.phy_map_size);
|
|
updated_mask = (u8 *)PLTFM_MALLOC(mask_size);
|
if (!updated_mask) {
|
PLTFM_MSG_ERR("[ERR]malloc updated mask\n");
|
return MACBUFALLOC;
|
}
|
PLTFM_MEMSET(updated_mask, 0x00, mask_size);
|
|
ret = update_eeprom_mask(adapter, info, updated_mask, 1);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]update eeprom mask\n");
|
goto error;
|
}
|
|
ret = check_efuse_enough(adapter, info, updated_mask);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]chk efuse enough\n");
|
goto error;
|
}
|
|
ret = program_efuse(adapter, info, updated_mask, 1);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]pg efuse\n");
|
goto error;
|
}
|
|
PLTFM_FREE(updated_mask, mask_size);
|
|
PLTFM_MEMCPY(phy_map, *bank_efuse_info.phy_map,
|
*bank_efuse_info.phy_map_size);
|
ret = eeprom_parser(adapter, phy_map, info->efuse_map,
|
MAC_AX_EFUSE_PARSER_MAP);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]parser error\n");
|
PLTFM_FREE(log_efuse_map, map_size);
|
return ret;
|
}
|
|
/* For subsequent dump */
|
*bank_efuse_info.log_map_valid = 0;
|
*bank_efuse_info.phy_map_valid = 0;
|
|
return MACSUCCESS;
|
|
error:
|
PLTFM_FREE(updated_mask, mask_size);
|
return ret;
|
}
|
|
u32 mac_checksum_update(struct mac_ax_adapter *adapter)
|
{
|
struct mac_ax_hw_info *hw_info = adapter->hw_info;
|
u32 log_efuse_size = hw_info->log_efuse_size;
|
u8 *map;
|
u16 chksum;
|
u32 ret;
|
|
map = (u8 *)PLTFM_MALLOC(log_efuse_size);
|
if (!map) {
|
PLTFM_MSG_ERR("[ERR]malloc map\n");
|
return MACBUFALLOC;
|
}
|
PLTFM_MEMSET(map, 0xFF, log_efuse_size);
|
|
ret = mac_dump_log_efuse(adapter, MAC_AX_EFUSE_PARSER_MAP,
|
MAC_AX_EFUSE_R_AUTO, map, 0);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]Dump log map\n");
|
goto error;
|
}
|
|
cal_check_sum(adapter, &chksum);
|
|
ret = set_check_sum_val(adapter, map, chksum);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]write check sum\n");
|
goto error;
|
}
|
|
PLTFM_FREE(map, log_efuse_size);
|
return MACSUCCESS;
|
error:
|
PLTFM_FREE(map, log_efuse_size);
|
return ret;
|
}
|
|
u32 mac_checksum_rpt(struct mac_ax_adapter *adapter, u16 *chksum)
|
{
|
struct mac_ax_hw_info *hw_info = adapter->hw_info;
|
u32 log_efuse_size = hw_info->log_efuse_size;
|
u8 *tmp;
|
u32 ret;
|
u16 real_chksum = 0;
|
|
/* Read chksum val */
|
tmp = (u8 *)PLTFM_MALLOC(sizeof(real_chksum));
|
if (!tmp) {
|
PLTFM_MSG_ERR("[ERR]malloc tmp\n");
|
return MACBUFALLOC;
|
}
|
ret = mac_read_log_efuse(adapter, chksum_offset_1, sizeof(real_chksum),
|
tmp);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]read log efuse\n");
|
PLTFM_FREE(tmp, sizeof(real_chksum));
|
return ret;
|
}
|
|
real_chksum = *(u16 *)tmp;
|
PLTFM_FREE(tmp, sizeof(real_chksum));
|
|
if (real_chksum == 0xFFFF)
|
return MACCHKSUMEMPTY;
|
|
/* Read log map*/
|
tmp = (u8 *)PLTFM_MALLOC(log_efuse_size);
|
if (!tmp) {
|
PLTFM_MSG_ERR("[ERR]malloc map\n");
|
return MACBUFALLOC;
|
}
|
PLTFM_MEMSET(tmp, 0xFF, log_efuse_size);
|
|
ret = mac_read_log_efuse(adapter, 0, log_efuse_size, tmp);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]read log efuse\n");
|
PLTFM_FREE(tmp, log_efuse_size);
|
return ret;
|
}
|
PLTFM_FREE(tmp, log_efuse_size);
|
|
cal_check_sum(adapter, chksum);
|
if (*chksum != real_chksum)
|
return MACCHKSUMFAIL;
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_disable_rf(struct mac_ax_adapter *adapter,
|
enum mac_ax_disable_rf_func func, enum mac_ax_net_type type)
|
{
|
u32 ret;
|
#if MAC_AX_PHL_H2C
|
struct rtw_h2c_pkt *h2cb;
|
#else
|
struct h2c_buf *h2cb;
|
#endif
|
u8 *buf;
|
struct fwcmd_disable_rf *write_ptr;
|
|
/* H2C */
|
if (adapter->sm.fwdl != MAC_AX_FWDL_INIT_RDY)
|
return MACNOFW;
|
|
h2cb = h2cb_alloc(adapter, H2CB_CLASS_CMD);
|
if (!h2cb)
|
return MACNPTR;
|
|
buf = h2cb_put(h2cb, sizeof(struct mac_ax_pkt_ofld_hdr));
|
if (!buf) {
|
h2cb_free(adapter, h2cb);
|
return MACNOBUF;
|
}
|
|
write_ptr = (struct fwcmd_disable_rf *)buf;
|
write_ptr->dword0 =
|
cpu_to_le32(SET_WORD(func, FWCMD_H2C_DISABLE_RF_FUNC) |
|
SET_WORD(type, FWCMD_H2C_DISABLE_RF_NET_TYPE)
|
);
|
|
ret = h2c_pkt_set_hdr(adapter, h2cb,
|
FWCMD_TYPE_H2C, FWCMD_H2C_CAT_MAC,
|
FWCMD_H2C_CL_FW_OFLD, FWCMD_H2C_FUNC_DISABLE_RF,
|
0, 0);
|
if (ret) {
|
h2cb_free(adapter, h2cb);
|
return ret;
|
}
|
|
ret = h2c_pkt_build_txd(adapter, h2cb);
|
if (ret) {
|
h2cb_free(adapter, h2cb);
|
return ret;
|
}
|
|
#if MAC_AX_PHL_H2C
|
ret = PLTFM_TX(h2cb);
|
#else
|
ret = PLTFM_TX(h2cb->data, h2cb->len);
|
#endif
|
if (ret) {
|
PLTFM_MSG_ERR("[ERR]platform tx\n");
|
h2cb_free(adapter, h2cb);
|
return ret;
|
}
|
|
h2cb_free(adapter, h2cb);
|
|
return MACSUCCESS;
|
}
|
|
u32 mac_check_OTP(struct mac_ax_adapter *adapter, u8 is_start)
|
{
|
#define is_read 0
|
#define secure 1
|
u8 val8;
|
|
if (is_start == 1) {
|
enable_efuse_sw_pwr_cut(adapter, is_read);
|
|
mac_set_efuse_ctrl(adapter, secure);
|
read_efuse_cnt = CHK_OTP_WAIT_CNT;
|
|
mac_read_efuse_plus(adapter, CHK_OTP_ADDR, 1, &val8,
|
MAC_AX_EFUSE_BANK_WIFI);
|
|
disable_efuse_sw_pwr_cut(adapter, is_read);
|
|
mac_set_efuse_ctrl(adapter, !secure);
|
read_efuse_cnt = EFUSE_WAIT_CNT;
|
}
|
|
return MACSUCCESS;
|
}
|
|
void mac_set_efuse_ctrl(struct mac_ax_adapter *adapter, u8 is_secure)
|
{
|
efuse_ctrl = is_secure ? R_AX_EFUSE_CTRL_S : R_AX_EFUSE_CTRL;
|
}
|
|
u32 mac_otp_test(struct mac_ax_adapter *adapter, bool is_OTP_test)
|
{
|
if (is_OTP_test)
|
OTP_test = 1;
|
else
|
OTP_test = 0;
|
|
return MACSUCCESS;
|
}
|
|
void cfg_efuse_auto_ck(struct mac_ax_adapter *adapter, u8 enable)
|
{
|
/*Soar TBD* move to set hw value */
|
|
#ifdef NEVER
|
PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
|
adapter->efuse_param.auto_ck_en = enable;
|
PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
|
#endif /* NEVER */
|
}
|
|
u32 efuse_tbl_init(struct mac_ax_adapter *adapter)
|
{
|
PLTFM_MUTEX_INIT(&efuse_tbl.lock);
|
|
return MACSUCCESS;
|
}
|
|
u32 efuse_tbl_exit(struct mac_ax_adapter *adapter)
|
{
|
PLTFM_MUTEX_DEINIT(&efuse_tbl.lock);
|
|
return MACSUCCESS;
|
}
|
|
static u32 efuse_map_init(struct mac_ax_adapter *adapter,
|
enum efuse_map_sel map_sel)
|
{
|
u32 size;
|
struct mac_ax_efuse_param *efuse_param = &adapter->efuse_param;
|
|
switch (map_sel) {
|
case EFUSE_MAP_SEL_PHY_WL:
|
size = adapter->hw_info->efuse_size;
|
if (!efuse_param->efuse_map) {
|
efuse_param->efuse_map = (u8 *)PLTFM_MALLOC(size);
|
if (!efuse_param->efuse_map) {
|
PLTFM_MSG_ERR("[ERR]malloc map\n");
|
return MACBUFALLOC;
|
}
|
}
|
break;
|
case EFUSE_MAP_SEL_PHY_BT:
|
size = adapter->hw_info->bt_efuse_size;
|
if (!efuse_param->bt_efuse_map) {
|
efuse_param->bt_efuse_map = (u8 *)PLTFM_MALLOC(size);
|
if (!efuse_param->bt_efuse_map) {
|
PLTFM_MSG_ERR("[ERR]malloc map\n");
|
return MACBUFALLOC;
|
}
|
}
|
break;
|
case EFUSE_MAP_SEL_LOG:
|
size = adapter->hw_info->log_efuse_size;
|
if (!efuse_param->log_efuse_map) {
|
efuse_param->log_efuse_map = (u8 *)PLTFM_MALLOC(size);
|
if (!efuse_param->log_efuse_map) {
|
PLTFM_MSG_ERR("[ERR]malloc map\n");
|
return MACBUFALLOC;
|
}
|
}
|
break;
|
case EFUSE_MAP_SEL_LOG_BT:
|
size = adapter->hw_info->bt_log_efuse_size;
|
if (!efuse_param->bt_log_efuse_map) {
|
efuse_param->bt_log_efuse_map =
|
(u8 *)PLTFM_MALLOC(size);
|
if (!efuse_param->bt_log_efuse_map) {
|
PLTFM_MSG_ERR("[ERR]malloc map\n");
|
return MACBUFALLOC;
|
}
|
}
|
break;
|
case EFUSE_MAP_SEL_PHY_DAV:
|
size = adapter->hw_info->dav_efuse_size;
|
if (!efuse_param->dav_efuse_map) {
|
efuse_param->dav_efuse_map = (u8 *)PLTFM_MALLOC(size);
|
if (!efuse_param->dav_efuse_map) {
|
PLTFM_MSG_ERR("[ERR]malloc map\n");
|
return MACBUFALLOC;
|
}
|
}
|
break;
|
case EFUSE_MAP_SEL_LOG_DAV:
|
size = adapter->hw_info->dav_log_efuse_size;
|
if (!efuse_param->dav_log_efuse_map) {
|
efuse_param->dav_log_efuse_map =
|
(u8 *)PLTFM_MALLOC(size);
|
if (!efuse_param->dav_log_efuse_map) {
|
PLTFM_MSG_ERR("[ERR]malloc map\n");
|
return MACBUFALLOC;
|
}
|
}
|
break;
|
default:
|
break;
|
}
|
|
return MACSUCCESS;
|
}
|
|
static u32 efuse_fwcmd_ck(struct mac_ax_adapter *adapter)
|
{
|
/*Soar TBD*/
|
#ifdef NEVER
|
u32 ret;
|
|
ret = fwcmd_wq_idle(adapter,
|
SET_FWCMD_ID(FWCMD_TYPE_H2C,
|
FWCMD_H2C_CAT_MAC,
|
TBD,
|
TBD));
|
if (ret != 0) {
|
PLTFM_MSG_WARN("[WARN]H2C not idle(efuse)\n");
|
return ret;
|
}
|
#endif /* NEVER */
|
return MACSUCCESS;
|
}
|
|
static u32 efuse_proc_ck(struct mac_ax_adapter *adapter)
|
{
|
/*Soar TBD*/
|
#ifdef NEVER
|
u32 ret;
|
|
ret = efuse_fwcmd_ck(adapter);
|
if (ret != 0)
|
return ret;
|
#endif /* NEVER */
|
if (adapter->sm.efuse != MAC_AX_EFUSE_IDLE) {
|
PLTFM_MSG_WARN("[WARN]Proc not idle(efuse)\n");
|
return MACPROCBUSY;
|
}
|
|
if (adapter->sm.pwr != MAC_AX_PWR_ON)
|
PLTFM_MSG_ERR("[ERR]Access efuse in suspend\n");
|
|
return MACSUCCESS;
|
}
|
|
static u32 cnv_efuse_state(struct mac_ax_adapter *adapter, u8 dest_state)
|
{
|
if (adapter->sm.efuse >= MAC_AX_EFUSE_MAX)
|
return MACPROCERR;
|
|
if (adapter->sm.efuse == dest_state)
|
return MACPROCERR;
|
|
if (dest_state != MAC_AX_EFUSE_IDLE) {
|
if (adapter->sm.efuse != MAC_AX_EFUSE_IDLE)
|
return MACPROCERR;
|
}
|
|
adapter->sm.efuse = dest_state;
|
|
return MACSUCCESS;
|
}
|
|
static u32 switch_efuse_bank(struct mac_ax_adapter *adapter,
|
enum mac_ax_efuse_bank bank)
|
{
|
u8 reg_value;
|
struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter);
|
struct mac_ax_efuse_param *efuse_param = &adapter->efuse_param;
|
struct mac_ax_hw_info *hw_info = adapter->hw_info;
|
u8 chip_id = adapter->hw_info->chip_id;
|
|
switch (chip_id) {
|
case MAC_AX_CHIP_ID_8852A:
|
if (bank == MAC_AX_EFUSE_BANK_BT) {
|
/* check bt state */
|
MAC_REG_W8(R_AX_SYSON_FSM_MON + 3, 0x05);
|
reg_value = MAC_REG_R8(R_AX_SYSON_FSM_MON);
|
if (reg_value != 0x04)
|
return MACEFUSEBANK;
|
}
|
|
reg_value = MAC_REG_R8(R_AX_EFUSE_CTRL_1 + 1);
|
if (bank == (reg_value & B_AX_EF_CELL_SEL_MSK))
|
goto set_val;
|
|
reg_value &= ~B_AX_EF_CELL_SEL_MSK;
|
reg_value |= bank;
|
MAC_REG_W8(R_AX_EFUSE_CTRL_1 + 1, reg_value);
|
|
reg_value = MAC_REG_R8(R_AX_EFUSE_CTRL_1 + 1);
|
if ((reg_value & B_AX_EF_CELL_SEL_MSK) == bank)
|
goto set_val;
|
else
|
return MACEFUSEBANK;
|
break;
|
case MAC_AX_CHIP_ID_8852B:
|
case MAC_AX_CHIP_ID_8852C:
|
case MAC_AX_CHIP_ID_8192XB:
|
goto set_val;
|
default:
|
break;
|
}
|
|
set_val:
|
switch (bank) {
|
case MAC_AX_EFUSE_BANK_WIFI:
|
if (dv_sel == DAV) {
|
bank_efuse_info.phy_map = &efuse_param->dav_efuse_map;
|
bank_efuse_info.log_map =
|
&efuse_param->dav_log_efuse_map;
|
bank_efuse_info.phy_map_valid =
|
&efuse_param->dav_efuse_map_valid;
|
bank_efuse_info.log_map_valid =
|
&efuse_param->dav_log_efuse_map_valid;
|
bank_efuse_info.efuse_end =
|
&efuse_param->dav_efuse_end;
|
bank_efuse_info.phy_map_size =
|
&hw_info->dav_efuse_size;
|
bank_efuse_info.log_map_size =
|
&hw_info->dav_log_efuse_size;
|
bank_efuse_info.efuse_start =
|
&hw_info->dav_efuse_start_addr;
|
break;
|
}
|
|
bank_efuse_info.phy_map = &efuse_param->efuse_map;
|
bank_efuse_info.log_map = &efuse_param->log_efuse_map;
|
bank_efuse_info.phy_map_valid = &efuse_param->efuse_map_valid;
|
bank_efuse_info.log_map_valid =
|
&efuse_param->log_efuse_map_valid;
|
bank_efuse_info.efuse_end = &efuse_param->efuse_end;
|
bank_efuse_info.phy_map_size = &hw_info->efuse_size;
|
bank_efuse_info.log_map_size = &hw_info->log_efuse_size;
|
bank_efuse_info.efuse_start = &hw_info->wl_efuse_start_addr;
|
break;
|
case MAC_AX_EFUSE_BANK_BT:
|
bank_efuse_info.phy_map = &efuse_param->bt_efuse_map;
|
bank_efuse_info.log_map = &efuse_param->bt_log_efuse_map;
|
bank_efuse_info.phy_map_valid =
|
&efuse_param->bt_efuse_map_valid;
|
bank_efuse_info.log_map_valid =
|
&efuse_param->bt_log_efuse_map_valid;
|
bank_efuse_info.efuse_end = &efuse_param->bt_efuse_end;
|
bank_efuse_info.phy_map_size = &hw_info->bt_efuse_size;
|
bank_efuse_info.log_map_size = &hw_info->bt_log_efuse_size;
|
bank_efuse_info.efuse_start = &hw_info->bt_efuse_start_addr;
|
break;
|
default:
|
return MACEFUSEBANK;
|
}
|
|
return MACSUCCESS;
|
}
|
|
static u32 proc_dump_efuse(struct mac_ax_adapter *adapter,
|
enum mac_ax_efuse_read_cfg cfg)
|
{
|
u32 ret;
|
|
if (cfg == MAC_AX_EFUSE_R_AUTO) {
|
if (adapter->sm.fwdl != MAC_AX_FWDL_INIT_RDY)
|
ret = dump_efuse_drv(adapter);
|
else
|
ret = dump_efuse_fw(adapter);
|
} else if (cfg == MAC_AX_EFUSE_R_FW) {
|
ret = dump_efuse_fw(adapter);
|
} else {
|
ret = dump_efuse_drv(adapter);
|
}
|
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]dump efsue drv/fw\n");
|
return ret;
|
}
|
|
return MACSUCCESS;
|
}
|
|
static u32 read_hw_efuse(struct mac_ax_adapter *adapter, u32 offset, u32 size,
|
u8 *map)
|
{
|
u32 addr;
|
u32 tmp32 = 0;
|
u32 cnt;
|
struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter);
|
u32 efuse_start = *bank_efuse_info.efuse_start;
|
|
offset += efuse_start;
|
|
if (dv_sel == DDV) {
|
enable_efuse_sw_pwr_cut(adapter, 0);
|
|
for (addr = offset; addr < offset + size; addr++) {
|
MAC_REG_W32(efuse_ctrl,
|
((addr & B_AX_EF_ADDR_MSK) << B_AX_EF_ADDR_SH)
|
& ~B_AX_EF_RDY);
|
|
cnt = read_efuse_cnt;
|
if ((is_chip_id(adapter, MAC_AX_CHIP_ID_8852B) ||
|
is_chip_id(adapter, MAC_AX_CHIP_ID_8852C)) &&
|
efuse_ctrl == R_AX_EFUSE_CTRL)
|
cnt = EFUSE_WAIT_CNT_PLUS;
|
|
while (--cnt) {
|
tmp32 = MAC_REG_R32(efuse_ctrl);
|
if (tmp32 & B_AX_EF_RDY)
|
break;
|
PLTFM_DELAY_US(1);
|
}
|
|
if (!cnt) {
|
PLTFM_MSG_ERR("[ERR]read efuse\n");
|
return MACEFUSEREAD;
|
}
|
|
*(map + addr - offset) = (u8)(tmp32 & 0xFF);
|
}
|
|
disable_efuse_sw_pwr_cut(adapter, 0);
|
} else {
|
read_hw_efuse_dav(adapter, offset, size, map);
|
}
|
|
return MACSUCCESS;
|
}
|
|
static u32 write_hw_efuse(struct mac_ax_adapter *adapter, u32 offset, u8 value)
|
{
|
//const u8 unlock_code = 0x69;
|
u8 value_read = 0;
|
u32 value32;
|
u32 cnt;
|
u32 ret;
|
struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter);
|
struct mac_ax_efuse_param *efuse_param = &adapter->efuse_param;
|
u32 efuse_start = *bank_efuse_info.efuse_start;
|
|
PLTFM_MUTEX_LOCK(&efuse_tbl.lock);
|
*bank_efuse_info.phy_map_valid = 0;
|
*bank_efuse_info.log_map_valid = 0;
|
PLTFM_MUTEX_UNLOCK(&efuse_tbl.lock);
|
|
offset += efuse_start;
|
|
if (dv_sel == DDV) {
|
//MAC_REG_W8(R_AX_PMC_DBG_CTRL2 + 3, unlock_code);
|
|
value32 = value |
|
((offset & B_AX_EF_ADDR_MSK) << B_AX_EF_ADDR_SH);
|
value32 &= ~B_AX_EF_RDY;
|
MAC_REG_W32(efuse_ctrl,
|
value32 | (MODE_WRITE << B_AX_EF_MODE_SEL_SH));
|
|
cnt = EFUSE_WAIT_CNT;
|
while (--cnt) {
|
if (MAC_REG_R32(efuse_ctrl) & B_AX_EF_RDY)
|
break;
|
PLTFM_DELAY_US(1);
|
}
|
|
if (!cnt) {
|
PLTFM_MSG_ERR("[ERR]write efuse\n");
|
return MACEFUSEWRITE;
|
}
|
|
//MAC_REG_W8(R_AX_PMC_DBG_CTRL2 + 3, 0x00);
|
} else {
|
write_hw_efuse_dav(adapter, offset, value);
|
}
|
|
if (efuse_param->auto_ck_en == 1) {
|
ret = read_hw_efuse(adapter, offset, 1, &value_read);
|
if (ret != 0)
|
return ret;
|
|
if (value_read != value) {
|
PLTFM_MSG_ERR("[ERR]efuse compare\n");
|
return MACEFUSEWRITE;
|
}
|
}
|
|
return MACSUCCESS;
|
}
|
|
static u32 cmp_hw_efuse(struct mac_ax_adapter *adapter, u32 offset, u16 val)
|
{
|
u32 val32;
|
u32 tmp32 = 0;
|
u32 cnt;
|
struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter);
|
|
val32 = val | ((offset & B_AX_EF_ADDR_MSK) << B_AX_EF_ADDR_SH);
|
MAC_REG_W32(efuse_ctrl, val32 | (MODE_CMP << B_AX_EF_MODE_SEL_SH));
|
|
cnt = EFUSE_WAIT_CNT;
|
while (--cnt) {
|
tmp32 = MAC_REG_R32(efuse_ctrl);
|
if (tmp32 & B_AX_EF_RDY)
|
break;
|
PLTFM_DELAY_US(1);
|
}
|
|
if (!cnt) {
|
PLTFM_MSG_ERR("[ERR]compare efuse\n");
|
return MACEFUSEREAD;
|
}
|
|
if (0 == (tmp32 & B_AX_EF_COMP_RESULT))
|
return MACEFUSECMP;
|
|
return MACSUCCESS;
|
}
|
|
static u32 eeprom_parser(struct mac_ax_adapter *adapter, u8 *phy_map,
|
u8 *log_map, enum mac_ax_efuse_parser_cfg cfg)
|
{
|
u8 i;
|
u8 value8;
|
u8 blk_idx;
|
u8 word_en;
|
u8 valid;
|
u8 hdr = 0;
|
u8 hdr2 = 0;
|
u32 eeprom_idx;
|
struct mac_ax_hw_info *hw_info = adapter->hw_info;
|
u32 sec_ctrl_size = hw_info->sec_ctrl_efuse_size;
|
u32 efuse_idx;
|
u32 efuse_size = *bank_efuse_info.phy_map_size;
|
bool is_bt = 0;
|
u32 log_efuse_size = *bank_efuse_info.log_map_size;
|
|
PLTFM_MEMSET(log_map, 0xFF, log_efuse_size);
|
|
if (log_efuse_size == hw_info->bt_log_efuse_size) {
|
sec_ctrl_size = 0;
|
is_bt = 1;
|
}
|
efuse_idx = sec_ctrl_size;
|
|
do {
|
if (efuse_idx >= efuse_size) // secure zone
|
break;
|
|
value8 = *(phy_map + efuse_idx);
|
hdr = value8;
|
if (hdr == 0xff)
|
break;
|
efuse_idx++;
|
|
if (is_bt) {
|
if ((hdr & 0xF) != 0xF) {// 1byte entry
|
blk_idx = (hdr & 0xF0) >> 4;
|
word_en = hdr & 0x0F;
|
} else {// 2byte entry
|
value8 = *(phy_map + efuse_idx);
|
hdr2 = value8;
|
if (hdr2 == 0xff)
|
break;
|
|
blk_idx = (((hdr2 & 0xF0) >> 4) << 3) +
|
(((hdr & 0xF0) >> 4) >> 1); // offset
|
word_en = hdr2 & 0x0F;
|
|
efuse_idx++;
|
}
|
} else { // WLAN
|
value8 = *(phy_map + efuse_idx);
|
hdr2 = value8;
|
if (hdr2 == 0xff)
|
break;
|
|
blk_idx = ((hdr2 & 0xF0) >> 4) | ((hdr & 0x0F) << 4);
|
word_en = hdr2 & 0x0F;
|
|
efuse_idx++;
|
}
|
|
if (efuse_idx >= efuse_size - 1)
|
return MACEFUSEPARSE;
|
|
for (i = 0; i < 4; i++) {
|
valid = (u8)((~(word_en >> i)) & BIT(0));
|
if (valid == 1) {
|
eeprom_idx = (blk_idx << 3) + (i << 1);
|
|
if ((eeprom_idx + 1) >
|
*bank_efuse_info.log_map_size) {
|
PLTFM_MSG_ERR("[ERR]efuse idx:0x%X\n",
|
efuse_idx - 1);
|
PLTFM_MSG_ERR("[ERR]read hdr:0x%X\n",
|
hdr);
|
PLTFM_MSG_ERR("[ERR]read hdr2:0x%X\n",
|
hdr2);
|
return MACEFUSEPARSE;
|
}
|
|
if (cfg == MAC_AX_EFUSE_PARSER_MAP) {
|
value8 = *(phy_map + efuse_idx);
|
*(log_map + eeprom_idx) = value8;
|
} else if (cfg == MAC_AX_EFUSE_PARSER_MASK) {
|
*(log_map + eeprom_idx) = 0x00;
|
}
|
|
eeprom_idx++;// 1 byte
|
efuse_idx++;
|
|
if (efuse_idx > efuse_size - 1)
|
return MACEFUSEPARSE;
|
|
if (cfg == MAC_AX_EFUSE_PARSER_MAP) {
|
value8 = *(phy_map + efuse_idx);
|
*(log_map + eeprom_idx) = value8;
|
} else if (cfg == MAC_AX_EFUSE_PARSER_MASK) {
|
*(log_map + eeprom_idx) = 0x00;
|
}
|
|
efuse_idx++;
|
|
if (efuse_idx > efuse_size)
|
return MACEFUSEPARSE;
|
}
|
}
|
} while (1);
|
|
*bank_efuse_info.efuse_end = efuse_idx;
|
|
return MACSUCCESS;
|
}
|
|
static u32 read_log_efuse_map(struct mac_ax_adapter *adapter, u8 *map,
|
u32 log_efuse_size)
|
{
|
u8 *local_map = NULL;
|
u32 efuse_size = *bank_efuse_info.phy_map_size;
|
u32 ret;
|
|
if (*bank_efuse_info.log_map_valid == 0) {
|
if (*bank_efuse_info.phy_map_valid == 0) {
|
local_map = (u8 *)PLTFM_MALLOC(efuse_size);
|
if (!local_map) {
|
PLTFM_MSG_ERR("[ERR]malloc map\n");
|
return MACBUFALLOC;
|
}
|
|
ret = read_efuse(adapter, 0, efuse_size, local_map);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]read efuse\n");
|
goto error;
|
}
|
|
PLTFM_MUTEX_LOCK(&efuse_tbl.lock);
|
PLTFM_MEMCPY(*bank_efuse_info.phy_map, local_map,
|
efuse_size);
|
*bank_efuse_info.phy_map_valid = 1;
|
PLTFM_MUTEX_UNLOCK(&efuse_tbl.lock);
|
|
PLTFM_FREE(local_map, efuse_size);
|
}
|
|
ret = eeprom_parser(adapter, *bank_efuse_info.phy_map, map,
|
MAC_AX_EFUSE_PARSER_MAP);
|
if (ret != 0)
|
return ret;
|
|
PLTFM_MUTEX_LOCK(&efuse_tbl.lock);
|
PLTFM_MEMCPY(*bank_efuse_info.log_map, map, log_efuse_size);
|
*bank_efuse_info.log_map_valid = 1;
|
PLTFM_MUTEX_UNLOCK(&efuse_tbl.lock);
|
} else {
|
PLTFM_MUTEX_LOCK(&efuse_tbl.lock);
|
PLTFM_MEMCPY(map, *bank_efuse_info.log_map, log_efuse_size);
|
PLTFM_MUTEX_UNLOCK(&efuse_tbl.lock);
|
}
|
|
return MACSUCCESS;
|
error:
|
PLTFM_FREE(local_map, efuse_size);
|
return ret;
|
}
|
|
static u32 proc_pg_efuse_by_map(struct mac_ax_adapter *adapter,
|
struct mac_ax_pg_efuse_info *info,
|
enum mac_ax_efuse_read_cfg cfg)
|
{
|
u8 *updated_mask = NULL;
|
u32 ret;
|
u32 log_efuse_size = *bank_efuse_info.log_map_size;
|
u32 mask_size = log_efuse_size >> 4;
|
|
updated_mask = (u8 *)PLTFM_MALLOC(mask_size);
|
if (!updated_mask) {
|
PLTFM_MSG_ERR("[ERR]malloc updated mask\n");
|
return MACBUFALLOC;
|
}
|
PLTFM_MEMSET(updated_mask, 0x00, mask_size);
|
|
ret = update_eeprom_mask(adapter, info, updated_mask, 0);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]update eeprom mask\n");
|
goto error;
|
}
|
|
ret = check_efuse_enough(adapter, info, updated_mask);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]chk efuse enough\n");
|
goto error;
|
}
|
|
ret = program_efuse(adapter, info, updated_mask, 0);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]pg efuse\n");
|
goto error;
|
}
|
|
PLTFM_FREE(updated_mask, mask_size);
|
return MACSUCCESS;
|
error:
|
PLTFM_FREE(updated_mask, mask_size);
|
return ret;
|
}
|
|
static u32 dump_efuse_drv(struct mac_ax_adapter *adapter)
|
{
|
u8 *map = NULL;
|
u32 efuse_size = *bank_efuse_info.phy_map_size;
|
u32 ret;
|
|
if (*bank_efuse_info.phy_map_valid == 0) {
|
map = (u8 *)PLTFM_MALLOC(efuse_size);
|
if (!map) {
|
PLTFM_MSG_ERR("[ERR]malloc map\n");
|
return MACBUFALLOC;
|
}
|
|
ret = read_hw_efuse(adapter, 0, efuse_size, map);
|
if (ret != 0) {
|
PLTFM_FREE(map, efuse_size);
|
return ret;
|
}
|
|
PLTFM_MUTEX_LOCK(&efuse_tbl.lock);
|
PLTFM_MEMCPY(*bank_efuse_info.phy_map, map, efuse_size);
|
*bank_efuse_info.phy_map_valid = 1;
|
PLTFM_MUTEX_UNLOCK(&efuse_tbl.lock);
|
PLTFM_FREE(map, efuse_size);
|
}
|
|
return MACSUCCESS;
|
}
|
|
static u32 dump_efuse_fw(struct mac_ax_adapter *adapter)
|
{
|
u32 ret, cnt;
|
struct mac_ax_ops *ops = adapter->ops;
|
u8 *map = NULL;
|
u32 efuse_size = *bank_efuse_info.phy_map_size;
|
|
if (*bank_efuse_info.phy_map_valid == 0) {
|
/* H2C */
|
ret = ops->dump_efuse_ofld(adapter, efuse_size, 0);
|
if (ret)
|
return ret;
|
|
/* Wait for C2H */
|
cnt = EFUSE_FW_DUMP_WAIT_CNT;
|
while (--cnt) {
|
if (adapter->sm.efuse_ofld == MAC_AX_OFLD_H2C_DONE)
|
break;
|
PLTFM_DELAY_US(1);
|
}
|
if (!cnt) {
|
PLTFM_MSG_ERR("[ERR]efuse C2H\n");
|
adapter->sm.efuse_ofld = MAC_AX_OFLD_H2C_IDLE;
|
return MACPROCERR;
|
}
|
|
/* cpy map */
|
map = (u8 *)PLTFM_MALLOC(efuse_size);
|
if (!map) {
|
PLTFM_MSG_ERR("[ERR]malloc map\n");
|
return MACBUFALLOC;
|
}
|
PLTFM_MEMSET(map, 0xFF, efuse_size);
|
|
ret = ops->efuse_ofld_map(adapter, map, efuse_size);
|
if (ret) {
|
PLTFM_FREE(map, efuse_size);
|
return ret;
|
}
|
|
PLTFM_MUTEX_LOCK(&efuse_tbl.lock);
|
PLTFM_MEMCPY(*bank_efuse_info.phy_map, map, efuse_size);
|
*bank_efuse_info.phy_map_valid = 1;
|
PLTFM_MUTEX_UNLOCK(&efuse_tbl.lock);
|
PLTFM_FREE(map, efuse_size);
|
}
|
|
return MACSUCCESS;
|
}
|
|
static u32 proc_write_log_efuse(struct mac_ax_adapter *adapter, u32 offset,
|
u8 value)
|
{
|
u8 byte1;
|
u8 byte2;
|
u8 blk;
|
u8 blk_idx;
|
u8 hdr;
|
u8 hdr2 = 0;
|
u8 *map = NULL;
|
u32 log_efuse_size = *bank_efuse_info.log_map_size;
|
u32 end, ret;
|
bool is_bt = 0;
|
|
map = (u8 *)PLTFM_MALLOC(log_efuse_size);
|
if (!map) {
|
PLTFM_MSG_ERR("[ERR]malloc map\n");
|
return MACBUFALLOC;
|
}
|
|
if (*bank_efuse_info.log_map_valid == 0) {
|
ret = read_log_efuse_map(adapter, map, log_efuse_size);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]read logical efuse\n");
|
PLTFM_FREE(map, log_efuse_size);
|
return ret;
|
}
|
} else {
|
PLTFM_MUTEX_LOCK(&efuse_tbl.lock);
|
PLTFM_MEMCPY(map, *bank_efuse_info.log_map, log_efuse_size);
|
PLTFM_MUTEX_UNLOCK(&efuse_tbl.lock);
|
}
|
|
if (log_efuse_size == adapter->hw_info->bt_log_efuse_size)
|
is_bt = 1;
|
|
if (*(map + offset) != value) {
|
end = *bank_efuse_info.efuse_end;
|
|
if (is_bt) {
|
if (offset < BT_1B_ENTRY_SIZE) { // 1 byte entry
|
blk = (u8)(offset >> 3);
|
blk_idx = (u8)((offset & (8 - 1)) >> 1);//mod8
|
|
hdr = (u8)((blk << 4) +
|
((0x1 << blk_idx) ^ 0x0F));
|
} else { // 2 byte entry
|
blk = (u8)(offset >> 3 >> 3); // large section
|
blk_idx = (u8)(((offset >> 3) & (8 - 1)) << 1);
|
hdr = (u8)((blk_idx << 4) + 0xF);
|
|
blk_idx = (u8)((offset & (8 - 1)) >> 1);
|
hdr2 = (u8)((blk << 4) +
|
((0x1 << blk_idx) ^ 0x0F));
|
}
|
} else {
|
blk = (u8)(offset >> 3);// offset
|
blk_idx = (u8)((offset & (8 - 1)) >> 1); // mod8 0 1 2 3
|
|
hdr = ((blk & 0xF0) >> 4) | 0x30;
|
hdr2 = (u8)(((blk & 0x0F) << 4) +
|
((0x1 << blk_idx) ^ 0x0F));
|
}
|
|
if ((offset & 1) == 0) {
|
byte1 = value;
|
byte2 = *(map + offset + 1);
|
} else {
|
byte1 = *(map + offset - 1);
|
byte2 = value;
|
}
|
|
if (*bank_efuse_info.phy_map_size <= 4 + end) { // write 4 bytes
|
PLTFM_FREE(map, log_efuse_size);
|
return MACEFUSESIZE;
|
}
|
|
enable_efuse_sw_pwr_cut(adapter, 1);
|
|
ret = write_hw_efuse(adapter, end, hdr);
|
if (ret != 0)
|
goto error;
|
|
if (!is_bt || offset >= BT_1B_ENTRY_SIZE) {
|
ret = write_hw_efuse(adapter, end + 1, hdr2);
|
if (ret != 0)
|
goto error;
|
end++;
|
}
|
|
ret = write_hw_efuse(adapter, end + 1, byte1);
|
if (ret != 0)
|
goto error;
|
|
ret = write_hw_efuse(adapter, end + 2, byte2);
|
if (ret != 0)
|
goto error;
|
|
disable_efuse_sw_pwr_cut(adapter, 1);
|
}
|
|
PLTFM_FREE(map, log_efuse_size);
|
return MACSUCCESS;
|
error:
|
PLTFM_FREE(map, log_efuse_size);
|
return ret;
|
}
|
|
static u32 read_efuse(struct mac_ax_adapter *adapter, u32 offset, u32 size,
|
u8 *map)
|
{
|
u32 ret;
|
|
if (!map) {
|
PLTFM_MSG_ERR("[ERR]malloc map\n");
|
return MACBUFALLOC;
|
}
|
|
if (*bank_efuse_info.phy_map_valid == 1) {
|
PLTFM_MEMCPY(map, *bank_efuse_info.phy_map + offset, size);
|
} else {
|
ret = read_hw_efuse(adapter, offset, size, map);
|
if (ret != 0)
|
return ret;
|
}
|
|
return MACSUCCESS;
|
}
|
|
static u32 update_eeprom_mask(struct mac_ax_adapter *adapter,
|
struct mac_ax_pg_efuse_info *info,
|
u8 *updated_mask, bool pg_sim)
|
{
|
u8 *map = NULL;
|
u8 *mask_map = NULL;
|
u8 clr_bit = 0;
|
u8 *map_pg;
|
u8 *efuse_mask;
|
u32 i;
|
u16 j;
|
u16 map_offset;
|
u16 mask_offset;
|
u32 ret;
|
u32 log_efuse_size = *bank_efuse_info.log_map_size;
|
|
map = (u8 *)PLTFM_MALLOC(log_efuse_size);
|
if (!map) {
|
PLTFM_MSG_ERR("[ERR]malloc map\n");
|
return MACBUFALLOC;
|
}
|
PLTFM_MEMSET(map, 0xFF, log_efuse_size); // default: 0xFF
|
|
if (pg_sim) { //WL
|
PLTFM_MEMCPY(map, *bank_efuse_info.log_map, log_efuse_size);
|
} else {
|
ret = read_log_efuse_map(adapter, map, log_efuse_size);
|
if (ret != 0)
|
goto error;
|
}
|
|
/*log mask*/
|
mask_map = (u8 *)PLTFM_MALLOC(log_efuse_size);
|
if (!mask_map) {
|
PLTFM_MSG_ERR("[ERR]malloc mask map\n");
|
PLTFM_FREE(map, log_efuse_size);
|
return MACBUFALLOC;
|
}
|
PLTFM_MEMSET(mask_map, 0xFF, log_efuse_size);// default: 0xFF
|
|
ret = eeprom_parser(adapter, *bank_efuse_info.phy_map,
|
mask_map, MAC_AX_EFUSE_PARSER_MASK);
|
if (ret != 0) {
|
PLTFM_FREE(mask_map, log_efuse_size);
|
goto error;
|
}
|
|
map_pg = info->efuse_map;
|
efuse_mask = info->efuse_mask;
|
|
PLTFM_MEMCPY(updated_mask, efuse_mask, info->efuse_mask_size);
|
|
for (i = 0; i < info->efuse_map_size; i += 16) {
|
for (j = 0; j < 16; j += 2) {
|
map_offset = i + j;
|
mask_offset = i >> 4;
|
if (*(u16 *)(map_pg + map_offset) ==
|
*(u16 *)(map + map_offset) &&
|
*(mask_map + map_offset) == 0x00) {
|
switch (j) {
|
case 0:
|
clr_bit = BIT(4);
|
break;
|
case 2:
|
clr_bit = BIT(5);
|
break;
|
case 4:
|
clr_bit = BIT(6);
|
break;
|
case 6:
|
clr_bit = BIT(7);
|
break;
|
case 8:
|
clr_bit = BIT(0);
|
break;
|
case 10:
|
clr_bit = BIT(1);
|
break;
|
case 12:
|
clr_bit = BIT(2);
|
break;
|
case 14:
|
clr_bit = BIT(3);
|
break;
|
default:
|
break;
|
}
|
*(updated_mask + mask_offset) &= ~clr_bit;
|
}
|
}
|
}
|
|
PLTFM_FREE(map, log_efuse_size);
|
PLTFM_FREE(mask_map, log_efuse_size);
|
return MACSUCCESS;
|
error:
|
PLTFM_FREE(map, log_efuse_size);
|
return ret;
|
}
|
|
static u32 check_efuse_enough(struct mac_ax_adapter *adapter,
|
struct mac_ax_pg_efuse_info *info,
|
u8 *updated_mask)
|
{
|
u8 pre_word_en;
|
u32 i;
|
u16 j;
|
u32 eeprom_offset;
|
u32 pg_num = 0;
|
|
for (i = 0; i < info->efuse_map_size; i += 8) {
|
eeprom_offset = i;
|
|
if ((eeprom_offset & 0xF) > 0)
|
pre_word_en = (*(updated_mask + (i >> 4)) & 0x0F);
|
else
|
pre_word_en = (*(updated_mask + (i >> 4)) >> 4);
|
|
if (pre_word_en > 0) { // msk ==1 -> write
|
pg_num += 2;
|
for (j = 0; j < 4; j++) {
|
if (((pre_word_en >> j) & 0x1) > 0)
|
pg_num += 2;
|
}
|
}
|
}
|
|
if (*bank_efuse_info.phy_map_size
|
< (pg_num + *bank_efuse_info.efuse_end))
|
return MACEFUSESIZE;
|
|
return MACSUCCESS;
|
}
|
|
static u32 proc_pg_efuse(struct mac_ax_adapter *adapter,
|
struct mac_ax_pg_efuse_info *info, u8 word_en,
|
u8 pre_word_en, u32 eeprom_offset, bool pg_sim)
|
{
|
u8 blk, blk_idx;
|
u8 hdr;
|
u8 hdr2 = 0xFF;
|
u8 i;
|
u32 efuse_end, ret;
|
u8 *efuse_map = *bank_efuse_info.phy_map;
|
bool is_bt = 0;
|
|
if (info->efuse_map_size == adapter->hw_info->bt_log_efuse_size)
|
is_bt = 1;
|
|
efuse_end = *bank_efuse_info.efuse_end;
|
|
if (is_bt) {
|
if (eeprom_offset < BT_1B_ENTRY_SIZE) {
|
blk = (u8)(eeprom_offset >> 3);
|
hdr = (u8)((blk << 4) + word_en);
|
} else {
|
blk = (u8)(eeprom_offset >> 3 >> 3);
|
blk_idx = (u8)(((eeprom_offset >> 3) & (8 - 1)) << 1);
|
hdr = (u8)((blk_idx << 4) | 0xF);
|
hdr2 = (u8)((blk << 4) + word_en);
|
}
|
} else {
|
blk = (u8)(eeprom_offset >> 3);
|
hdr = ((blk & 0xF0) >> 4) | 0x30;
|
hdr2 = (u8)(((blk & 0x0F) << 4) + word_en);
|
}
|
|
if (pg_sim) { //WL
|
*(efuse_map + efuse_end) = hdr;
|
*(efuse_map + efuse_end + 1) = hdr2;
|
|
efuse_end += 2;
|
|
for (i = 0; i < 4; i++) {
|
if (((pre_word_en >> i) & 0x1) > 0) {
|
*(efuse_map + efuse_end) = *(info->efuse_map +
|
eeprom_offset + (i << 1));
|
efuse_end++;
|
|
*(efuse_map + efuse_end) = *(info->efuse_map +
|
eeprom_offset + (i << 1) + 1);
|
efuse_end++;
|
}
|
}
|
} else {
|
ret = write_hw_efuse(adapter, efuse_end, hdr);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]write efuse\n");
|
return ret;
|
}
|
|
if (is_bt == 0 || eeprom_offset >= BT_1B_ENTRY_SIZE) {
|
ret = write_hw_efuse(adapter, efuse_end + 1, hdr2);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]write efuse(+1)\n");
|
return ret;
|
}
|
efuse_end++;
|
}
|
|
efuse_end++;
|
for (i = 0; i < 4; i++) {
|
if (((pre_word_en >> i) & 0x1) > 0) {
|
ret = write_hw_efuse(adapter, efuse_end,
|
*(info->efuse_map +
|
eeprom_offset + (i << 1)));
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]write efuse\n");
|
return ret;
|
}
|
|
ret = write_hw_efuse(adapter, efuse_end + 1,
|
*(info->efuse_map +
|
eeprom_offset +
|
(i << 1) + 1));
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]write efuse+1\n");
|
return ret;
|
}
|
efuse_end = efuse_end + 2;
|
}
|
}
|
}
|
*bank_efuse_info.efuse_end = efuse_end;
|
return MACSUCCESS;
|
}
|
|
static u32 program_efuse(struct mac_ax_adapter *adapter,
|
struct mac_ax_pg_efuse_info *info, u8 *updated_mask,
|
bool pg_sim)
|
{
|
u8 pre_word_en;
|
u8 word_en;
|
u32 i;
|
u32 eeprom_offset, ret;
|
|
enable_efuse_sw_pwr_cut(adapter, 1);
|
|
for (i = 0; i < info->efuse_map_size; i += 8) {
|
eeprom_offset = i;
|
|
if (((eeprom_offset >> 3) & 1) > 0) {
|
pre_word_en = (*(updated_mask + (i >> 4)) & 0x0F);
|
word_en = pre_word_en ^ 0x0F;
|
} else {
|
pre_word_en = (*(updated_mask + (i >> 4)) >> 4);
|
word_en = pre_word_en ^ 0x0F;
|
}
|
|
if (pre_word_en > 0) {
|
ret = proc_pg_efuse(adapter, info, word_en, pre_word_en,
|
eeprom_offset, pg_sim);
|
if (ret != 0) {
|
PLTFM_MSG_ERR("[ERR]pg efuse");
|
return ret;
|
}
|
}
|
}
|
|
disable_efuse_sw_pwr_cut(adapter, 1);
|
|
return MACSUCCESS;
|
}
|
|
static void mask_eeprom(struct mac_ax_adapter *adapter,
|
struct mac_ax_pg_efuse_info *info)
|
{
|
u8 pre_word_en;
|
u8 *updated_mask;
|
u8 *efuse_map;
|
u32 i;
|
u16 j;
|
u32 offset;
|
|
updated_mask = info->efuse_mask;
|
efuse_map = info->efuse_map;
|
|
for (i = 0; i < info->efuse_map_size; i += 8) {
|
offset = i;
|
|
if (((offset >> 3) & 1) > 0)
|
pre_word_en = (*(updated_mask + (i >> 4)) & 0x0F);
|
else
|
pre_word_en = (*(updated_mask + (i >> 4)) >> 4);
|
|
for (j = 0; j < 4; j++) {
|
if (((pre_word_en >> j) & 0x1) == 0) {
|
*(efuse_map + offset + (j << 1)) = 0xFF;
|
*(efuse_map + offset + (j << 1) + 1) = 0xFF;
|
}
|
}
|
}
|
}
|
|
static u32 query_status_map(struct mac_ax_adapter *adapter,
|
enum mac_ax_efuse_feature_id feature_id,
|
u8 *map, bool is_limit)
|
{
|
struct mac_ax_hw_info *hw_info = adapter->hw_info;
|
enum mac_ax_intf intf = adapter->hw_info->intf;
|
u32 map_size = 0;
|
|
PLTFM_MUTEX_LOCK(&efuse_tbl.lock);
|
switch (feature_id) {
|
case MAC_AX_DUMP_PHYSICAL_EFUSE:
|
map_size = *bank_efuse_info.phy_map_size;
|
PLTFM_MEMCPY(map, *bank_efuse_info.phy_map, map_size);
|
break;
|
case MAC_AX_DUMP_LOGICAL_EFUSE:
|
if (!is_limit) {
|
map_size = *bank_efuse_info.log_map_size;
|
} else {// WL
|
switch (intf) {
|
case MAC_AX_INTF_PCIE:
|
map_size = hw_info->limit_efuse_size_pcie;
|
break;
|
case MAC_AX_INTF_USB:
|
map_size = hw_info->limit_efuse_size_usb;
|
break;
|
case MAC_AX_INTF_SDIO:
|
map_size = hw_info->limit_efuse_size_sdio;
|
break;
|
default:
|
break;
|
}
|
}
|
PLTFM_MEMCPY(map, *bank_efuse_info.log_map, map_size);
|
break;
|
default:
|
return MACFUNCINPUT;
|
}
|
PLTFM_MUTEX_UNLOCK(&efuse_tbl.lock);
|
|
return MACSUCCESS;
|
}
|
|
static u32 adjust_mask(struct mac_ax_adapter *adapter,
|
struct mac_ax_pg_efuse_info *info)
|
{
|
u8 *efuse_mask = info->efuse_mask;
|
u8 *efuse_map = info->efuse_map;
|
u32 i = 0;
|
u16 j = 0;
|
u16 map_offset;
|
u16 mask_offset;
|
u8 adj_bit = 0;
|
|
PLTFM_MEMSET(efuse_mask, 0xFF, info->efuse_mask_size);
|
|
for (i = 0; i < info->efuse_map_size; i += 16) {
|
for (j = 0; j < 16; j += 2) {
|
map_offset = i + j;
|
mask_offset = i >> 4;
|
|
if (*(u16 *)(efuse_map + map_offset) == 0xFFFF) {
|
switch (j) {
|
case 0:
|
adj_bit = BIT(4);
|
break;
|
case 2:
|
adj_bit = BIT(5);
|
break;
|
case 4:
|
adj_bit = BIT(6);
|
break;
|
case 6:
|
adj_bit = BIT(7);
|
break;
|
case 8:
|
adj_bit = BIT(0);
|
break;
|
case 10:
|
adj_bit = BIT(1);
|
break;
|
case 12:
|
adj_bit = BIT(2);
|
break;
|
case 14:
|
adj_bit = BIT(3);
|
break;
|
}
|
*(efuse_mask + mask_offset) &= ~adj_bit;
|
}
|
}
|
}
|
|
return MACSUCCESS;
|
}
|
|
static u32 compare_info_length(struct efuse_info *info,
|
enum rtw_efuse_info id, u32 length)
|
{
|
u32 idle_len;
|
|
switch (id) {
|
case EFUSE_INFO_MAC_ADDR:
|
idle_len = info->len->mac_addr;
|
break;
|
case EFUSE_INFO_MAC_PID:
|
idle_len = info->len->pid;
|
break;
|
case EFUSE_INFO_MAC_DID:
|
idle_len = info->len->did;
|
break;
|
case EFUSE_INFO_MAC_VID:
|
idle_len = info->len->vid;
|
break;
|
case EFUSE_INFO_MAC_SVID:
|
idle_len = info->len->svid;
|
break;
|
case EFUSE_INFO_MAC_SMID:
|
idle_len = info->len->smid;
|
break;
|
default:
|
return MACNOITEM;
|
}
|
|
if (length != idle_len || idle_len == 0)
|
return MACLENCMP;
|
|
return MACSUCCESS;
|
}
|
|
static u32 set_check_sum_val(struct mac_ax_adapter *adapter,
|
u8 *map, u16 value)
|
{
|
u8 byte1;
|
u8 byte2;
|
u8 blk;
|
u8 blk_idx;
|
u8 hdr;
|
u8 hdr2;
|
u32 end = *bank_efuse_info.efuse_end, ret;
|
u32 offset = chksum_offset_1;
|
u8 i = 0;
|
u8 value8 = (u8)(value & 0xFF);
|
|
enable_efuse_sw_pwr_cut(adapter, 1);
|
|
for (i = 0; i < 2; i++) {
|
blk = (u8)(offset >> 3);
|
blk_idx = (u8)((offset & (8 - 1)) >> 1);
|
|
hdr = ((blk & 0xF0) >> 4) | 0x30;
|
hdr2 = (u8)(((blk & 0x0F) << 4) + ((0x1 << blk_idx) ^ 0x0F));
|
|
if ((offset & 1) == 0) {
|
byte1 = value8;
|
byte2 = *(map + offset + 1);
|
} else {
|
byte1 = (u8)(value & 0xFF);
|
byte2 = value8;
|
}
|
|
if (*bank_efuse_info.phy_map_size <= 4 + end)
|
return MACEFUSESIZE;
|
|
ret = write_hw_efuse(adapter, end, hdr);
|
if (ret != 0)
|
return ret;
|
|
ret = write_hw_efuse(adapter, end + 1, hdr2);
|
if (ret != 0)
|
return ret;
|
|
ret = write_hw_efuse(adapter, end + 2, byte1);
|
if (ret != 0)
|
return ret;
|
|
ret = write_hw_efuse(adapter, end + 3, byte2);
|
if (ret != 0)
|
return ret;
|
|
offset = chksum_offset_2;
|
value8 = (u8)((value & 0xFF00) >> 8);
|
end += 4;
|
}
|
|
disable_efuse_sw_pwr_cut(adapter, 1);
|
|
return MACSUCCESS;
|
}
|
|
static void cal_check_sum(struct mac_ax_adapter *adapter, u16 *chksum)
|
{
|
u32 i = 0;
|
struct mac_ax_hw_info *hw_info = adapter->hw_info;
|
struct mac_ax_efuse_param *efuse_param = &adapter->efuse_param;
|
u8 *map = efuse_param->log_efuse_map;
|
u16 *data;
|
|
data = (u16 *)map;
|
|
*chksum = 0x0000;
|
for (i = 0; i < hw_info->log_efuse_size >> 2; i++) {
|
if (i == chksum_offset_1 >> 2)
|
*chksum ^= 0x0000 ^ *(data + (2 * i + 1));
|
else
|
*chksum ^= *(data + 2 * i) ^ *(data + (2 * i + 1));
|
}
|
}
|
|
static u32 compare_version(struct mac_ax_adapter *adapter,
|
struct mac_ax_pg_efuse_info *info, u32 ver_len)
|
{
|
u8 *map = info->efuse_map;
|
u8 *mask = info->efuse_mask;
|
u32 map_size = info->efuse_map_size;
|
u32 i = 0;
|
|
for (i = 0; i < ver_len; i++) {
|
if (*(map + map_size + i) != *(mask + (map_size >> 4) + i))
|
return MACVERERR;
|
}
|
return MACSUCCESS;
|
}
|
|
static void add_dummy_read(struct mac_ax_adapter *adapter)
|
{
|
struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter);
|
|
MAC_REG_W32(R_AX_EFUSE_CTRL_S,
|
SET_WORD(CHK_OTP_ADDR, B_AX_EF_ADDR) & ~B_AX_EF_RDY);
|
PLTFM_DELAY_US(DUMMY_READ_DELAY);
|
MAC_REG_W32(R_AX_EFUSE_CTRL,
|
SET_WORD(CHK_OTP_ADDR, B_AX_EF_ADDR) & ~B_AX_EF_RDY);
|
PLTFM_DELAY_US(DUMMY_READ_DELAY);
|
}
|
|
static void enable_OTP_burst_mode(struct mac_ax_adapter *adapter,
|
bool enable)
|
{
|
u32 val32;
|
struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter);
|
|
val32 = MAC_REG_R32(R_AX_EFUSE_CTRL_1_V1);
|
|
if (enable)
|
MAC_REG_W32(R_AX_EFUSE_CTRL_1_V1, val32 | B_AX_EF_BURST);
|
else
|
MAC_REG_W32(R_AX_EFUSE_CTRL_1_V1, val32 & ~B_AX_EF_BURST);
|
}
|
|
static void enable_efuse_sw_pwr_cut(struct mac_ax_adapter *adapter,
|
bool is_write)
|
{
|
u16 val16;
|
u8 val8;
|
struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter);
|
u8 chip_id = adapter->hw_info->chip_id;
|
|
if (dv_sel == DDV) {
|
if (chip_id == MAC_AX_CHIP_ID_8852A && !(is_write))
|
return;
|
|
if (is_write)
|
MAC_REG_W8(R_AX_PMC_DBG_CTRL2 + 3, UNLOCK_CODE);
|
|
val8 = MAC_REG_R8(R_AX_PMC_DBG_CTRL2);
|
MAC_REG_W8(R_AX_PMC_DBG_CTRL2, val8 | B_AX_SYSON_DIS_PMCR_AX_WRMSK);
|
|
val16 = MAC_REG_R16(R_AX_SYS_ISO_CTRL);
|
MAC_REG_W16(R_AX_SYS_ISO_CTRL, val16 | BIT(B_AX_PWC_EV2EF_SH));
|
|
PLTFM_DELAY_US(1000);
|
|
val16 = MAC_REG_R16(R_AX_SYS_ISO_CTRL);
|
MAC_REG_W16(R_AX_SYS_ISO_CTRL,
|
val16 | BIT(B_AX_PWC_EV2EF_SH + 1));
|
|
if (chip_id == MAC_AX_CHIP_ID_8852A) {
|
return;
|
} else if (chip_id == MAC_AX_CHIP_ID_8852B) {
|
val16 = MAC_REG_R16(R_AX_SYS_ISO_CTRL);
|
MAC_REG_W16(R_AX_SYS_ISO_CTRL,
|
val16 & ~(B_AX_ISO_EB2CORE));
|
if (is_cv(adapter, CAV))
|
enable_OTP_burst_mode(adapter, 1);
|
} else {
|
val16 = MAC_REG_R16(R_AX_SYS_ISO_CTRL);
|
MAC_REG_W16(R_AX_SYS_ISO_CTRL,
|
val16 & ~(B_AX_ISO_EB2CORE));
|
}
|
} else {
|
enable_efuse_pwr_cut_dav(adapter, is_write);
|
}
|
}
|
|
static void disable_efuse_sw_pwr_cut(struct mac_ax_adapter *adapter,
|
bool is_write)
|
{
|
u16 value16;
|
u8 value8;
|
struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter);
|
u8 chip_id = adapter->hw_info->chip_id;
|
|
if (dv_sel == DDV) {
|
if (chip_id == MAC_AX_CHIP_ID_8852A) {
|
if (!(is_write))
|
return;
|
} else if (chip_id == MAC_AX_CHIP_ID_8852B) {
|
if (is_cv(adapter, CAV))
|
enable_OTP_burst_mode(adapter, 0);
|
value16 = MAC_REG_R16(R_AX_SYS_ISO_CTRL);
|
MAC_REG_W16(R_AX_SYS_ISO_CTRL,
|
value16 | B_AX_ISO_EB2CORE);
|
} else {
|
value16 = MAC_REG_R16(R_AX_SYS_ISO_CTRL);
|
MAC_REG_W16(R_AX_SYS_ISO_CTRL,
|
value16 | B_AX_ISO_EB2CORE);
|
}
|
|
value16 = MAC_REG_R16(R_AX_SYS_ISO_CTRL);
|
MAC_REG_W16(R_AX_SYS_ISO_CTRL,
|
value16 & ~(BIT(B_AX_PWC_EV2EF_SH + 1)));// [15]=0
|
|
PLTFM_DELAY_US(1000);
|
|
value16 = MAC_REG_R16(R_AX_SYS_ISO_CTRL);
|
MAC_REG_W16(R_AX_SYS_ISO_CTRL,
|
value16 & ~(BIT(B_AX_PWC_EV2EF_SH)));// [14]=0,
|
|
if (is_write)
|
MAC_REG_W8(R_AX_PMC_DBG_CTRL2 + 3, 0x00);
|
|
value8 = MAC_REG_R8(R_AX_PMC_DBG_CTRL2);
|
MAC_REG_W8(R_AX_PMC_DBG_CTRL2, value8 & ~B_AX_SYSON_DIS_PMCR_AX_WRMSK);
|
} else {
|
disable_efuse_pwr_cut_dav(adapter, is_write);
|
}
|
}
|
|
static u32 enable_efuse_pwr_cut_dav(struct mac_ax_adapter *adapter,
|
bool is_write)
|
{
|
u32 ret;
|
u8 chip_id = adapter->hw_info->chip_id;
|
|
if (!(is_write))
|
return MACSUCCESS;
|
|
if (chip_id == MAC_AX_CHIP_ID_8852A) {
|
return MACSUCCESS;
|
} else {
|
ret = mac_write_xtal_si(adapter, XTAL_SI_PWR_CUT,
|
XTAL_SI_SMALL_PWR_CUT,
|
XTAL_SI_SMALL_PWR_CUT);
|
if (ret)
|
return ret;
|
|
ret = mac_write_xtal_si(adapter, XTAL_SI_PWR_CUT,
|
XTAL_SI_BIG_PWR_CUT,
|
XTAL_SI_BIG_PWR_CUT);
|
if (ret)
|
return ret;
|
}
|
|
return MACSUCCESS;
|
}
|
|
static u32 disable_efuse_pwr_cut_dav(struct mac_ax_adapter *adapter,
|
bool is_write)
|
{
|
u32 ret;
|
u8 chip_id = adapter->hw_info->chip_id;
|
|
if (!(is_write))
|
return MACSUCCESS;
|
|
if (chip_id == MAC_AX_CHIP_ID_8852A) {
|
return MACSUCCESS;
|
} else {
|
ret = mac_write_xtal_si(adapter, XTAL_SI_PWR_CUT, 0,
|
XTAL_SI_BIG_PWR_CUT);
|
if (ret)
|
return ret;
|
|
ret = mac_write_xtal_si(adapter, XTAL_SI_PWR_CUT, 0,
|
XTAL_SI_SMALL_PWR_CUT);
|
if (ret)
|
return ret;
|
}
|
|
return MACSUCCESS;
|
}
|
|
static u32 read_hw_efuse_dav(struct mac_ax_adapter *adapter, u32 offset, u32 size,
|
u8 *map)
|
{
|
u32 addr;
|
u8 tmp8;
|
u32 cnt;
|
u32 ret;
|
|
ret = enable_efuse_pwr_cut_dav(adapter, 0);
|
if (ret)
|
return ret;
|
|
for (addr = offset; addr < offset + size; addr++) {
|
/* clear ready bit*/
|
ret = mac_write_xtal_si(adapter, XTAL_SI_CTRL, 0x40, FULL_BIT_MASK);
|
if (ret)
|
return ret;
|
/* set addr */
|
ret = mac_write_xtal_si(adapter, XTAL_SI_LOW_ADDR,
|
(addr & 0xff) << XTAL_SI_LOW_ADDR_SH,
|
XTAL_SI_LOW_ADDR_MSK);
|
if (ret)
|
return ret;
|
ret = mac_write_xtal_si(adapter, XTAL_SI_CTRL, (addr >> 8)
|
<< XTAL_SI_HIGH_ADDR_SH,
|
XTAL_SI_HIGH_ADDR_MSK
|
<< XTAL_SI_HIGH_ADDR_SH);
|
if (ret)
|
return ret;
|
/* set ctrl mode sel */
|
ret = mac_write_xtal_si(adapter, XTAL_SI_CTRL, 0,
|
XTAL_SI_MODE_SEL_MSK
|
<< XTAL_SI_MODE_SEL_SH);
|
if (ret)
|
return ret;
|
|
/* polling */
|
cnt = EFUSE_WAIT_CNT;
|
while (--cnt) {
|
ret = mac_read_xtal_si(adapter, XTAL_SI_CTRL, &tmp8);
|
if (ret)
|
return ret;
|
if (tmp8 & XTAL_SI_RDY)
|
break;
|
PLTFM_DELAY_US(1);
|
}
|
if (!cnt) {
|
PLTFM_MSG_ERR("[ERR]read efuse\n");
|
return MACEFUSEREAD;
|
}
|
|
ret = mac_read_xtal_si(adapter, XTAL_SI_READ_VAL, &tmp8);
|
if (ret)
|
return ret;
|
*(map + addr - offset) = tmp8;
|
}
|
|
ret = disable_efuse_pwr_cut_dav(adapter, 0);
|
if (ret)
|
return ret;
|
|
return MACSUCCESS;
|
}
|
|
static u32 write_hw_efuse_dav(struct mac_ax_adapter *adapter, u32 offset,
|
u8 value)
|
{
|
u32 cnt;
|
u32 ret;
|
u8 tmp8;
|
|
PLTFM_MUTEX_LOCK(&efuse_tbl.lock);
|
*bank_efuse_info.phy_map_valid = 0;
|
*bank_efuse_info.log_map_valid = 0;
|
PLTFM_MUTEX_UNLOCK(&efuse_tbl.lock);
|
|
/* clear ready bit*/
|
ret = mac_write_xtal_si(adapter, XTAL_SI_CTRL, 0x40, FULL_BIT_MASK);
|
if (ret)
|
return ret;
|
/* set val */
|
ret = mac_write_xtal_si(adapter, XTAL_SI_WRITE_VAL, value <<
|
XTAL_SI_WRITE_DATA_SH, XTAL_SI_WRITE_DATA_MSK <<
|
XTAL_SI_WRITE_DATA_SH);
|
if (ret)
|
return ret;
|
/* set addr */
|
ret = mac_write_xtal_si(adapter, XTAL_SI_LOW_ADDR, (offset & 0xff)
|
<< XTAL_SI_LOW_ADDR_SH,
|
XTAL_SI_LOW_ADDR_MSK << XTAL_SI_LOW_ADDR_SH);
|
if (ret)
|
return ret;
|
ret = mac_write_xtal_si(adapter, XTAL_SI_CTRL, (offset >> 8)
|
<< XTAL_SI_HIGH_ADDR_SH,
|
XTAL_SI_HIGH_ADDR_MSK << XTAL_SI_HIGH_ADDR_SH);
|
if (ret)
|
return ret;
|
/* set ctrl mode sel */
|
ret = mac_write_xtal_si(adapter, XTAL_SI_CTRL, 0x2
|
<< XTAL_SI_MODE_SEL_SH,
|
XTAL_SI_MODE_SEL_MSK << XTAL_SI_MODE_SEL_SH);
|
if (ret)
|
return ret;
|
|
/* polling */
|
cnt = EFUSE_WAIT_CNT;
|
while (--cnt) {
|
ret = mac_read_xtal_si(adapter, XTAL_SI_CTRL, &tmp8);
|
if (ret)
|
return ret;
|
if (tmp8 & XTAL_SI_RDY)
|
break;
|
PLTFM_DELAY_US(1);
|
}
|
if (!cnt) {
|
PLTFM_MSG_ERR("[ERR]write efuse\n");
|
return MACEFUSEREAD;
|
}
|
|
return MACSUCCESS;
|
}
|
|
static void switch_dv(struct mac_ax_adapter *adapter, enum rtw_dv_sel sel)
|
{
|
dv_sel = sel;
|
}
|