Path: blob/master/ALFA-W1F1/RTL8814AU/core/efuse/rtw_efuse.c
1307 views
/******************************************************************************1*2* Copyright(c) 2007 - 2017 Realtek Corporation.3*4* This program is free software; you can redistribute it and/or modify it5* under the terms of version 2 of the GNU General Public License as6* published by the Free Software Foundation.7*8* This program is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for11* more details.12*13*****************************************************************************/14#define _RTW_EFUSE_C_1516#include <drv_types.h>17#include <hal_data.h>1819#include "../hal/efuse/efuse_mask.h"2021/*------------------------Define local variable------------------------------*/22u8 fakeEfuseBank = {0};23u32 fakeEfuseUsedBytes = {0};24u8 fakeEfuseContent[EFUSE_MAX_HW_SIZE] = {0};25u8 fakeEfuseInitMap[EFUSE_MAX_MAP_LEN] = {0};26u8 fakeEfuseModifiedMap[EFUSE_MAX_MAP_LEN] = {0};2728u32 BTEfuseUsedBytes = {0};29u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE];30u8 BTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0};31u8 BTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0};3233u32 fakeBTEfuseUsedBytes = {0};34u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE];35u8 fakeBTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0};36u8 fakeBTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0};3738u8 maskfileBuffer[64];39u8 btmaskfileBuffer[64];4041/*------------------------Define local variable------------------------------*/42BOOLEAN rtw_file_efuse_IsMasked(PADAPTER pAdapter, u16 Offset, u8 *maskbuf)43{44int r = Offset / 16;45int c = (Offset % 16) / 2;46int result = 0;4748if (pAdapter->registrypriv.boffefusemask)49return FALSE;5051if (c < 4) /* Upper double word */52result = (maskbuf[r] & (0x10 << c));53else54result = (maskbuf[r] & (0x01 << (c - 4)));5556return (result > 0) ? 0 : 1;57}58BOOLEAN efuse_IsBT_Masked(PADAPTER pAdapter, u16 Offset)59{60PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);6162if (pAdapter->registrypriv.boffefusemask)63return FALSE;6465#ifdef CONFIG_BT_EFUSE_MASK66#ifdef CONFIG_USB_HCI67if (IS_HARDWARE_TYPE_8822C(pAdapter))68return (IS_BT_MASKED(8822C, _MUSB, Offset)) ? TRUE : FALSE;69#endif70#ifdef CONFIG_PCI_HCI71if (IS_HARDWARE_TYPE_8822C(pAdapter))72return (IS_BT_MASKED(8822C, _MPCIE, Offset)) ? TRUE : FALSE;73#endif74#ifdef CONFIG_SDIO_HCI75if (IS_HARDWARE_TYPE_8822C(pAdapter))76return (IS_BT_MASKED(8822C, _MSDIO, Offset)) ? TRUE : FALSE;77#endif78#endif /* CONFIG_BT_EFUSE_MASK */79return FALSE;80}8182void rtw_bt_efuse_mask_array(PADAPTER pAdapter, u8 *pArray)83{84PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);8586#ifdef CONFIG_BT_EFUSE_MASK87#ifdef CONFIG_USB_HCI88if (IS_HARDWARE_TYPE_8822CU(pAdapter))89GET_MASK_ARRAY(8822C, _MUSB, pArray);90#endif91#ifdef CONFIG_PCI_HCI92if (IS_HARDWARE_TYPE_8822CE(pAdapter))93GET_MASK_ARRAY(8822C, _MPCIE, pArray);94#endif95#ifdef CONFIG_SDIO_HCI96if (IS_HARDWARE_TYPE_8822CS(pAdapter))97GET_MASK_ARRAY(8822C, _MSDIO, pArray);98#endif99#endif /* CONFIG_BT_EFUSE_MASK */100101}102103u16 rtw_get_bt_efuse_mask_arraylen(PADAPTER pAdapter)104{105HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);106107#ifdef CONFIG_BT_EFUSE_MASK108#ifdef CONFIG_USB_HCI109if (IS_HARDWARE_TYPE_8822CU(pAdapter))110return GET_BT_MASK_ARRAY_LEN(8822C, _MUSB);111#endif112#ifdef CONFIG_PCI_HCI113if (IS_HARDWARE_TYPE_8822CE(pAdapter))114return GET_BT_MASK_ARRAY_LEN(8822C, _MPCIE);115#endif116#ifdef CONFIG_SDIO_HCI117if (IS_HARDWARE_TYPE_8822CS(pAdapter))118return GET_BT_MASK_ARRAY_LEN(8822C, _MSDIO);119#endif120#endif /* CONFIG_BT_EFUSE_MASK */121122return 0;123}124125BOOLEAN efuse_IsMasked(PADAPTER pAdapter, u16 Offset)126{127128if (pAdapter->registrypriv.boffefusemask)129return FALSE;130131#ifdef CONFIG_USB_HCI132#if defined(CONFIG_RTL8188E)133if (IS_HARDWARE_TYPE_8188E(pAdapter))134return (IS_MASKED(8188E, _MUSB, Offset)) ? TRUE : FALSE;135#endif136#if defined(CONFIG_RTL8812A)137if (IS_HARDWARE_TYPE_8812(pAdapter))138return (IS_MASKED(8812A, _MUSB, Offset)) ? TRUE : FALSE;139#endif140#if defined(CONFIG_RTL8821A)141#if 0142if (IS_HARDWARE_TYPE_8811AU(pAdapter))143return (IS_MASKED(8811A, _MUSB, Offset)) ? TRUE : FALSE;144#endif145if (IS_HARDWARE_TYPE_8821(pAdapter))146return (IS_MASKED(8821A, _MUSB, Offset)) ? TRUE : FALSE;147#endif148#if defined(CONFIG_RTL8192E)149if (IS_HARDWARE_TYPE_8192E(pAdapter))150return (IS_MASKED(8192E, _MUSB, Offset)) ? TRUE : FALSE;151#endif152#if defined(CONFIG_RTL8723B)153if (IS_HARDWARE_TYPE_8723B(pAdapter))154return (IS_MASKED(8723B, _MUSB, Offset)) ? TRUE : FALSE;155#endif156#if defined(CONFIG_RTL8703B)157if (IS_HARDWARE_TYPE_8703B(pAdapter))158return (IS_MASKED(8703B, _MUSB, Offset)) ? TRUE : FALSE;159#endif160#if defined(CONFIG_RTL8814A)161if (IS_HARDWARE_TYPE_8814A(pAdapter))162return (IS_MASKED(8814A, _MUSB, Offset)) ? TRUE : FALSE;163#endif164#if defined(CONFIG_RTL8188F)165if (IS_HARDWARE_TYPE_8188F(pAdapter))166return (IS_MASKED(8188F, _MUSB, Offset)) ? TRUE : FALSE;167#endif168#if defined(CONFIG_RTL8188GTV)169if (IS_HARDWARE_TYPE_8188GTV(pAdapter))170return (IS_MASKED(8188GTV, _MUSB, Offset)) ? TRUE : FALSE;171#endif172#if defined(CONFIG_RTL8822B)173if (IS_HARDWARE_TYPE_8822B(pAdapter))174return (IS_MASKED(8822B, _MUSB, Offset)) ? TRUE : FALSE;175#endif176#if defined(CONFIG_RTL8723D)177if (IS_HARDWARE_TYPE_8723D(pAdapter))178return (IS_MASKED(8723D, _MUSB, Offset)) ? TRUE : FALSE;179#endif180#if defined(CONFIG_RTL8710B)181if (IS_HARDWARE_TYPE_8710B(pAdapter))182return (IS_MASKED(8710B, _MUSB, Offset)) ? TRUE : FALSE;183#endif184#if defined(CONFIG_RTL8821C)185if (IS_HARDWARE_TYPE_8821CU(pAdapter))186return (IS_MASKED(8821C, _MUSB, Offset)) ? TRUE : FALSE;187#endif188189#if defined(CONFIG_RTL8192F)190if (IS_HARDWARE_TYPE_8192FU(pAdapter))191return (IS_MASKED(8192F, _MUSB, Offset)) ? TRUE : FALSE;192#endif193#if defined(CONFIG_RTL8822C)194if (IS_HARDWARE_TYPE_8822C(pAdapter))195return (IS_MASKED(8822C, _MUSB, Offset)) ? TRUE : FALSE;196#endif197#if defined(CONFIG_RTL8814B)198if (IS_HARDWARE_TYPE_8814B(pAdapter))199return (IS_MASKED(8814B, _MUSB, Offset)) ? TRUE : FALSE;200#endif201#endif /*CONFIG_USB_HCI*/202203#ifdef CONFIG_PCI_HCI204#if defined(CONFIG_RTL8188E)205if (IS_HARDWARE_TYPE_8188E(pAdapter))206return (IS_MASKED(8188E, _MPCIE, Offset)) ? TRUE : FALSE;207#endif208#if defined(CONFIG_RTL8192E)209if (IS_HARDWARE_TYPE_8192E(pAdapter))210return (IS_MASKED(8192E, _MPCIE, Offset)) ? TRUE : FALSE;211#endif212#if defined(CONFIG_RTL8812A)213if (IS_HARDWARE_TYPE_8812(pAdapter))214return (IS_MASKED(8812A, _MPCIE, Offset)) ? TRUE : FALSE;215#endif216#if defined(CONFIG_RTL8821A)217if (IS_HARDWARE_TYPE_8821(pAdapter))218return (IS_MASKED(8821A, _MPCIE, Offset)) ? TRUE : FALSE;219#endif220#if defined(CONFIG_RTL8723B)221if (IS_HARDWARE_TYPE_8723B(pAdapter))222return (IS_MASKED(8723B, _MPCIE, Offset)) ? TRUE : FALSE;223#endif224#if defined(CONFIG_RTL8814A)225if (IS_HARDWARE_TYPE_8814A(pAdapter))226return (IS_MASKED(8814A, _MPCIE, Offset)) ? TRUE : FALSE;227#endif228#if defined(CONFIG_RTL8822B)229if (IS_HARDWARE_TYPE_8822B(pAdapter))230return (IS_MASKED(8822B, _MPCIE, Offset)) ? TRUE : FALSE;231#endif232#if defined(CONFIG_RTL8821C)233if (IS_HARDWARE_TYPE_8821CE(pAdapter))234return (IS_MASKED(8821C, _MPCIE, Offset)) ? TRUE : FALSE;235#endif236237#if defined(CONFIG_RTL8192F)238if (IS_HARDWARE_TYPE_8192FE(pAdapter))239return (IS_MASKED(8192F, _MPCIE, Offset)) ? TRUE : FALSE;240#endif241#if defined(CONFIG_RTL8822C)242if (IS_HARDWARE_TYPE_8822C(pAdapter))243return (IS_MASKED(8822C, _MPCIE, Offset)) ? TRUE : FALSE;244#endif245#if defined(CONFIG_RTL8814B)246if (IS_HARDWARE_TYPE_8814B(pAdapter))247return (IS_MASKED(8814B, _MPCIE, Offset)) ? TRUE : FALSE;248#endif249#endif /*CONFIG_PCI_HCI*/250251#ifdef CONFIG_SDIO_HCI252#ifdef CONFIG_RTL8188E_SDIO253if (IS_HARDWARE_TYPE_8188E(pAdapter))254return (IS_MASKED(8188E, _MSDIO, Offset)) ? TRUE : FALSE;255#endif256#ifdef CONFIG_RTL8723B257if (IS_HARDWARE_TYPE_8723BS(pAdapter))258return (IS_MASKED(8723B, _MSDIO, Offset)) ? TRUE : FALSE;259#endif260#ifdef CONFIG_RTL8188F261if (IS_HARDWARE_TYPE_8188F(pAdapter))262return (IS_MASKED(8188F, _MSDIO, Offset)) ? TRUE : FALSE;263#endif264#ifdef CONFIG_RTL8188GTV265if (IS_HARDWARE_TYPE_8188GTV(pAdapter))266return (IS_MASKED(8188GTV, _MSDIO, Offset)) ? TRUE : FALSE;267#endif268#ifdef CONFIG_RTL8192E269if (IS_HARDWARE_TYPE_8192ES(pAdapter))270return (IS_MASKED(8192E, _MSDIO, Offset)) ? TRUE : FALSE;271#endif272#if defined(CONFIG_RTL8821A)273if (IS_HARDWARE_TYPE_8821S(pAdapter))274return (IS_MASKED(8821A, _MSDIO, Offset)) ? TRUE : FALSE;275#endif276#if defined(CONFIG_RTL8821C)277if (IS_HARDWARE_TYPE_8821CS(pAdapter))278return (IS_MASKED(8821C, _MSDIO, Offset)) ? TRUE : FALSE;279#endif280#if defined(CONFIG_RTL8822B)281if (IS_HARDWARE_TYPE_8822B(pAdapter))282return (IS_MASKED(8822B, _MSDIO, Offset)) ? TRUE : FALSE;283#endif284#if defined(CONFIG_RTL8192F)285if (IS_HARDWARE_TYPE_8192FS(pAdapter))286return (IS_MASKED(8192F, _MSDIO, Offset)) ? TRUE : FALSE;287#endif288#if defined(CONFIG_RTL8822C)289if (IS_HARDWARE_TYPE_8822C(pAdapter))290return (IS_MASKED(8822C, _MSDIO, Offset)) ? TRUE : FALSE;291#endif292#endif /*CONFIG_SDIO_HCI*/293294return FALSE;295}296297void rtw_efuse_mask_array(PADAPTER pAdapter, u8 *pArray)298{299300#ifdef CONFIG_USB_HCI301#if defined(CONFIG_RTL8188E)302if (IS_HARDWARE_TYPE_8188E(pAdapter))303GET_MASK_ARRAY(8188E, _MUSB, pArray);304#endif305#if defined(CONFIG_RTL8812A)306if (IS_HARDWARE_TYPE_8812(pAdapter))307GET_MASK_ARRAY(8812A, _MUSB, pArray);308#endif309#if defined(CONFIG_RTL8821A)310if (IS_HARDWARE_TYPE_8821(pAdapter))311GET_MASK_ARRAY(8821A, _MUSB, pArray);312#endif313#if defined(CONFIG_RTL8192E)314if (IS_HARDWARE_TYPE_8192E(pAdapter))315GET_MASK_ARRAY(8192E, _MUSB, pArray);316#endif317#if defined(CONFIG_RTL8723B)318if (IS_HARDWARE_TYPE_8723B(pAdapter))319GET_MASK_ARRAY(8723B, _MUSB, pArray);320#endif321#if defined(CONFIG_RTL8703B)322if (IS_HARDWARE_TYPE_8703B(pAdapter))323GET_MASK_ARRAY(8703B, _MUSB, pArray);324#endif325#if defined(CONFIG_RTL8188F)326if (IS_HARDWARE_TYPE_8188F(pAdapter))327GET_MASK_ARRAY(8188F, _MUSB, pArray);328#endif329#if defined(CONFIG_RTL8188GTV)330if (IS_HARDWARE_TYPE_8188GTV(pAdapter))331GET_MASK_ARRAY(8188GTV, _MUSB, pArray);332#endif333#if defined(CONFIG_RTL8814A)334if (IS_HARDWARE_TYPE_8814A(pAdapter))335GET_MASK_ARRAY(8814A, _MUSB, pArray);336#endif337#if defined(CONFIG_RTL8822B)338if (IS_HARDWARE_TYPE_8822B(pAdapter))339GET_MASK_ARRAY(8822B, _MUSB, pArray);340#endif341#if defined(CONFIG_RTL8821C)342if (IS_HARDWARE_TYPE_8821CU(pAdapter))343GET_MASK_ARRAY(8821C, _MUSB, pArray);344#endif345#if defined(CONFIG_RTL8192F)346if (IS_HARDWARE_TYPE_8192FU(pAdapter))347GET_MASK_ARRAY(8192F, _MUSB, pArray);348#endif349#if defined(CONFIG_RTL8822C)350if (IS_HARDWARE_TYPE_8822C(pAdapter))351GET_MASK_ARRAY(8822C, _MUSB, pArray);352#endif353#if defined(CONFIG_RTL8814B)354if (IS_HARDWARE_TYPE_8814B(pAdapter))355GET_MASK_ARRAY(8814B, _MUSB, pArray);356#endif357#endif /*CONFIG_USB_HCI*/358359#ifdef CONFIG_PCI_HCI360#if defined(CONFIG_RTL8188E)361if (IS_HARDWARE_TYPE_8188E(pAdapter))362GET_MASK_ARRAY(8188E, _MPCIE, pArray);363#endif364#if defined(CONFIG_RTL8192E)365if (IS_HARDWARE_TYPE_8192E(pAdapter))366GET_MASK_ARRAY(8192E, _MPCIE, pArray);367#endif368#if defined(CONFIG_RTL8812A)369if (IS_HARDWARE_TYPE_8812(pAdapter))370GET_MASK_ARRAY(8812A, _MPCIE, pArray);371#endif372#if defined(CONFIG_RTL8821A)373if (IS_HARDWARE_TYPE_8821(pAdapter))374GET_MASK_ARRAY(8821A, _MPCIE, pArray);375#endif376#if defined(CONFIG_RTL8723B)377if (IS_HARDWARE_TYPE_8723B(pAdapter))378GET_MASK_ARRAY(8723B, _MPCIE, pArray);379#endif380#if defined(CONFIG_RTL8814A)381if (IS_HARDWARE_TYPE_8814A(pAdapter))382GET_MASK_ARRAY(8814A, _MPCIE, pArray);383#endif384#if defined(CONFIG_RTL8822B)385if (IS_HARDWARE_TYPE_8822B(pAdapter))386GET_MASK_ARRAY(8822B, _MPCIE, pArray);387#endif388#if defined(CONFIG_RTL8821C)389if (IS_HARDWARE_TYPE_8821CE(pAdapter))390GET_MASK_ARRAY(8821C, _MPCIE, pArray);391#endif392#if defined(CONFIG_RTL8192F)393if (IS_HARDWARE_TYPE_8192FE(pAdapter))394GET_MASK_ARRAY(8192F, _MPCIE, pArray);395#endif396#if defined(CONFIG_RTL8822C)397if (IS_HARDWARE_TYPE_8822C(pAdapter))398GET_MASK_ARRAY(8822C, _MPCIE, pArray);399#endif400#if defined(CONFIG_RTL8814B)401if (IS_HARDWARE_TYPE_8814B(pAdapter))402GET_MASK_ARRAY(8814B, _MPCIE, pArray);403#endif404#endif /*CONFIG_PCI_HCI*/405406#ifdef CONFIG_SDIO_HCI407#if defined(CONFIG_RTL8188E)408if (IS_HARDWARE_TYPE_8188E(pAdapter))409GET_MASK_ARRAY(8188E, _MSDIO, pArray);410#endif411#if defined(CONFIG_RTL8723B)412if (IS_HARDWARE_TYPE_8723BS(pAdapter))413GET_MASK_ARRAY(8723B, _MSDIO, pArray);414#endif415#if defined(CONFIG_RTL8188F)416if (IS_HARDWARE_TYPE_8188F(pAdapter))417GET_MASK_ARRAY(8188F, _MSDIO, pArray);418#endif419#if defined(CONFIG_RTL8188GTV)420if (IS_HARDWARE_TYPE_8188GTV(pAdapter))421GET_MASK_ARRAY(8188GTV, _MSDIO, pArray);422#endif423#if defined(CONFIG_RTL8192E)424if (IS_HARDWARE_TYPE_8192ES(pAdapter))425GET_MASK_ARRAY(8192E, _MSDIO, pArray);426#endif427#if defined(CONFIG_RTL8821A)428if (IS_HARDWARE_TYPE_8821S(pAdapter))429GET_MASK_ARRAY(8821A, _MSDIO, pArray);430#endif431#if defined(CONFIG_RTL8821C)432if (IS_HARDWARE_TYPE_8821CS(pAdapter))433GET_MASK_ARRAY(8821C , _MSDIO, pArray);434#endif435#if defined(CONFIG_RTL8822B)436if (IS_HARDWARE_TYPE_8822B(pAdapter))437GET_MASK_ARRAY(8822B , _MSDIO, pArray);438#endif439#if defined(CONFIG_RTL8192F)440if (IS_HARDWARE_TYPE_8192FS(pAdapter))441GET_MASK_ARRAY(8192F, _MSDIO, pArray);442#endif443#if defined(CONFIG_RTL8822C)444if (IS_HARDWARE_TYPE_8822C(pAdapter))445GET_MASK_ARRAY(8822C , _MSDIO, pArray);446#endif447#endif /*CONFIG_SDIO_HCI*/448}449450u16 rtw_get_efuse_mask_arraylen(PADAPTER pAdapter)451{452453#ifdef CONFIG_USB_HCI454#if defined(CONFIG_RTL8188E)455if (IS_HARDWARE_TYPE_8188E(pAdapter))456return GET_MASK_ARRAY_LEN(8188E, _MUSB);457#endif458#if defined(CONFIG_RTL8812A)459if (IS_HARDWARE_TYPE_8812(pAdapter))460return GET_MASK_ARRAY_LEN(8812A, _MUSB);461#endif462#if defined(CONFIG_RTL8821A)463if (IS_HARDWARE_TYPE_8821(pAdapter))464return GET_MASK_ARRAY_LEN(8821A, _MUSB);465#endif466#if defined(CONFIG_RTL8192E)467if (IS_HARDWARE_TYPE_8192E(pAdapter))468return GET_MASK_ARRAY_LEN(8192E, _MUSB);469#endif470#if defined(CONFIG_RTL8723B)471if (IS_HARDWARE_TYPE_8723B(pAdapter))472return GET_MASK_ARRAY_LEN(8723B, _MUSB);473#endif474#if defined(CONFIG_RTL8703B)475if (IS_HARDWARE_TYPE_8703B(pAdapter))476return GET_MASK_ARRAY_LEN(8703B, _MUSB);477#endif478#if defined(CONFIG_RTL8188F)479if (IS_HARDWARE_TYPE_8188F(pAdapter))480return GET_MASK_ARRAY_LEN(8188F, _MUSB);481#endif482#if defined(CONFIG_RTL8188GTV)483if (IS_HARDWARE_TYPE_8188GTV(pAdapter))484return GET_MASK_ARRAY_LEN(8188GTV, _MUSB);485#endif486#if defined(CONFIG_RTL8814A)487if (IS_HARDWARE_TYPE_8814A(pAdapter))488return GET_MASK_ARRAY_LEN(8814A, _MUSB);489#endif490#if defined(CONFIG_RTL8822B)491if (IS_HARDWARE_TYPE_8822B(pAdapter))492return GET_MASK_ARRAY_LEN(8822B, _MUSB);493#endif494#if defined(CONFIG_RTL8821C)495if (IS_HARDWARE_TYPE_8821CU(pAdapter))496return GET_MASK_ARRAY_LEN(8821C, _MUSB);497#endif498#if defined(CONFIG_RTL8192F)499if (IS_HARDWARE_TYPE_8192FU(pAdapter))500return GET_MASK_ARRAY_LEN(8192F, _MUSB);501#endif502#if defined(CONFIG_RTL8822C)503if (IS_HARDWARE_TYPE_8822C(pAdapter))504return GET_MASK_ARRAY_LEN(8822C, _MUSB);505#endif506#if defined(CONFIG_RTL8814B)507if (IS_HARDWARE_TYPE_8814B(pAdapter)) {508return GET_MASK_ARRAY_LEN(8814B, _MUSB);509}510#endif511#endif /*CONFIG_USB_HCI*/512513#ifdef CONFIG_PCI_HCI514#if defined(CONFIG_RTL8188E)515if (IS_HARDWARE_TYPE_8188E(pAdapter))516return GET_MASK_ARRAY_LEN(8188E, _MPCIE);517#endif518#if defined(CONFIG_RTL8192E)519if (IS_HARDWARE_TYPE_8192E(pAdapter))520return GET_MASK_ARRAY_LEN(8192E, _MPCIE);521#endif522#if defined(CONFIG_RTL8812A)523if (IS_HARDWARE_TYPE_8812(pAdapter))524return GET_MASK_ARRAY_LEN(8812A, _MPCIE);525#endif526#if defined(CONFIG_RTL8821A)527if (IS_HARDWARE_TYPE_8821(pAdapter))528return GET_MASK_ARRAY_LEN(8821A, _MPCIE);529#endif530#if defined(CONFIG_RTL8723B)531if (IS_HARDWARE_TYPE_8723B(pAdapter))532return GET_MASK_ARRAY_LEN(8723B, _MPCIE);533#endif534#if defined(CONFIG_RTL8814A)535if (IS_HARDWARE_TYPE_8814A(pAdapter))536return GET_MASK_ARRAY_LEN(8814A, _MPCIE);537#endif538#if defined(CONFIG_RTL8822B)539if (IS_HARDWARE_TYPE_8822B(pAdapter))540return GET_MASK_ARRAY_LEN(8822B, _MPCIE);541#endif542#if defined(CONFIG_RTL8821C)543if (IS_HARDWARE_TYPE_8821CE(pAdapter))544return GET_MASK_ARRAY_LEN(8821C, _MPCIE);545#endif546#if defined(CONFIG_RTL8192F)547if (IS_HARDWARE_TYPE_8192FE(pAdapter))548return GET_MASK_ARRAY_LEN(8192F, _MPCIE);549#endif550#if defined(CONFIG_RTL8822C)551if (IS_HARDWARE_TYPE_8822C(pAdapter))552return GET_MASK_ARRAY_LEN(8822C, _MPCIE);553#endif554#if defined(CONFIG_RTL8814B)555if (IS_HARDWARE_TYPE_8814B(pAdapter))556return GET_MASK_ARRAY_LEN(8814B, _MPCIE);557#endif558#endif /*CONFIG_PCI_HCI*/559560#ifdef CONFIG_SDIO_HCI561#if defined(CONFIG_RTL8188E)562if (IS_HARDWARE_TYPE_8188E(pAdapter))563return GET_MASK_ARRAY_LEN(8188E, _MSDIO);564#endif565#if defined(CONFIG_RTL8723B)566if (IS_HARDWARE_TYPE_8723BS(pAdapter))567return GET_MASK_ARRAY_LEN(8723B, _MSDIO);568#endif569#if defined(CONFIG_RTL8188F)570if (IS_HARDWARE_TYPE_8188F(pAdapter))571return GET_MASK_ARRAY_LEN(8188F, _MSDIO);572#endif573#if defined(CONFIG_RTL8188GTV)574if (IS_HARDWARE_TYPE_8188GTV(pAdapter))575return GET_MASK_ARRAY_LEN(8188GTV, _MSDIO);576#endif577#if defined(CONFIG_RTL8192E)578if (IS_HARDWARE_TYPE_8192ES(pAdapter))579return GET_MASK_ARRAY_LEN(8192E, _MSDIO);580#endif581#if defined(CONFIG_RTL8821A)582if (IS_HARDWARE_TYPE_8821S(pAdapter))583return GET_MASK_ARRAY_LEN(8821A, _MSDIO);584#endif585#if defined(CONFIG_RTL8821C)586if (IS_HARDWARE_TYPE_8821CS(pAdapter))587return GET_MASK_ARRAY_LEN(8821C, _MSDIO);588#endif589#if defined(CONFIG_RTL8822B)590if (IS_HARDWARE_TYPE_8822B(pAdapter))591return GET_MASK_ARRAY_LEN(8822B, _MSDIO);592#endif593#if defined(CONFIG_RTL8192F)594if (IS_HARDWARE_TYPE_8192FS(pAdapter))595return GET_MASK_ARRAY_LEN(8192F, _MSDIO);596#endif597#if defined(CONFIG_RTL8822C)598if (IS_HARDWARE_TYPE_8822C(pAdapter))599return GET_MASK_ARRAY_LEN(8822C, _MSDIO);600#endif601#endif/*CONFIG_SDIO_HCI*/602return 0;603}604605static void rtw_mask_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data)606{607u16 i = 0;608609if (padapter->registrypriv.boffefusemask == 0) {610for (i = 0; i < cnts; i++) {611if (padapter->registrypriv.bFileMaskEfuse == _TRUE) {612if (rtw_file_efuse_IsMasked(padapter, addr + i, maskfileBuffer)) /*use file efuse mask.*/613data[i] = 0xff;614else615RTW_DBG("data[%x] = %x\n", i, data[i]);616} else {617if (efuse_IsMasked(padapter, addr + i))618data[i] = 0xff;619else620RTW_DBG("data[%x] = %x\n", i, data[i]);621}622}623}624}625626u8 rtw_efuse_mask_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data)627{628u8 ret = _SUCCESS;629u16 mapLen = 0;630631EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, _FALSE);632633ret = rtw_efuse_map_read(padapter, addr, cnts , data);634635rtw_mask_map_read(padapter, addr, cnts , data);636637return ret;638639}640641/* ***********************************************************642* Efuse related code643* *********************************************************** */644static u8 hal_EfuseSwitchToBank(645PADAPTER padapter,646u8 bank,647u8 bPseudoTest)648{649u8 bRet = _FALSE;650u32 value32 = 0;651#ifdef HAL_EFUSE_MEMORY652PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);653PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;654#endif655656657RTW_INFO("%s: Efuse switch bank to %d\n", __FUNCTION__, bank);658if (bPseudoTest) {659#ifdef HAL_EFUSE_MEMORY660pEfuseHal->fakeEfuseBank = bank;661#else662fakeEfuseBank = bank;663#endif664bRet = _TRUE;665} else {666value32 = rtw_read32(padapter, 0x34);667bRet = _TRUE;668switch (bank) {669case 0:670value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);671break;672case 1:673value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_0);674break;675case 2:676value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_1);677break;678case 3:679value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_2);680break;681default:682value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);683bRet = _FALSE;684break;685}686rtw_write32(padapter, 0x34, value32);687}688689return bRet;690}691692void rtw_efuse_analyze(PADAPTER padapter, u8 Type, u8 Fake)693{694HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);695PEFUSE_HAL pEfuseHal = &(pHalData->EfuseHal);696u16 eFuse_Addr = 0;697u8 offset, wden;698u16 i, j;699u8 efuseHeader = 0, efuseExtHdr = 0, efuseData[EFUSE_MAX_WORD_UNIT*2] = {0}, dataCnt = 0;700u16 efuseHeader2Byte = 0;701u8 *eFuseWord = NULL;// [EFUSE_MAX_SECTION_NUM][EFUSE_MAX_WORD_UNIT];702u8 offset_2_0 = 0;703u8 pgSectionCnt = 0;704u8 wd_cnt = 0;705u8 max_section = 64;706u16 mapLen = 0, maprawlen = 0;707boolean bExtHeader = _FALSE;708u8 efuseType = EFUSE_WIFI;709boolean bPseudoTest = _FALSE;710u8 bank = 0, startBank = 0, endBank = 1-1;711boolean bCheckNextBank = FALSE;712u8 protectBytesBank = 0;713u16 efuse_max = 0;714u8 ParseEfuseExtHdr, ParseEfuseHeader, ParseOffset, ParseWDEN, ParseOffset2_0;715716eFuseWord = rtw_zmalloc(EFUSE_MAX_SECTION_NUM * (EFUSE_MAX_WORD_UNIT * 2));717718RTW_INFO("\n");719if (Type == 0) {720if (Fake == 0) {721RTW_INFO("\n\tEFUSE_Analyze Wifi Content\n");722efuseType = EFUSE_WIFI;723bPseudoTest = FALSE;724startBank = 0;725endBank = 0;726} else {727RTW_INFO("\n\tEFUSE_Analyze Wifi Pseudo Content\n");728efuseType = EFUSE_WIFI;729bPseudoTest = TRUE;730startBank = 0;731endBank = 0;732}733} else {734if (Fake == 0) {735RTW_INFO("\n\tEFUSE_Analyze BT Content\n");736efuseType = EFUSE_BT;737bPseudoTest = FALSE;738startBank = 1;739endBank = EFUSE_MAX_BANK - 1;740} else {741RTW_INFO("\n\tEFUSE_Analyze BT Pseudo Content\n");742efuseType = EFUSE_BT;743bPseudoTest = TRUE;744startBank = 1;745endBank = EFUSE_MAX_BANK - 1;746if (IS_HARDWARE_TYPE_8821(padapter))747endBank = 3 - 1;/*EFUSE_MAX_BANK_8821A - 1;*/748}749}750751RTW_INFO("\n\r 1Byte header, [7:4]=offset, [3:0]=word enable\n");752RTW_INFO("\n\r 2Byte header, header[7:5]=offset[2:0], header[4:0]=0x0F\n");753RTW_INFO("\n\r 2Byte header, extHeader[7:4]=offset[6:3], extHeader[3:0]=word enable\n");754755EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, bPseudoTest);756EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_MAX_SECTION, (void *)&max_section, bPseudoTest);757EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_PROTECT_BYTES_BANK, (void *)&protectBytesBank, bPseudoTest);758EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_CONTENT_LEN_BANK, (void *)&efuse_max, bPseudoTest);759EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&maprawlen, _FALSE);760761_rtw_memset(eFuseWord, 0xff, EFUSE_MAX_SECTION_NUM * (EFUSE_MAX_WORD_UNIT * 2));762_rtw_memset(pEfuseHal->fakeEfuseInitMap, 0xff, EFUSE_MAX_MAP_LEN);763764if (IS_HARDWARE_TYPE_8821(padapter))765endBank = 3 - 1;/*EFUSE_MAX_BANK_8821A - 1;*/766767for (bank = startBank; bank <= endBank; bank++) {768if (!hal_EfuseSwitchToBank(padapter, bank, bPseudoTest)) {769RTW_INFO("EFUSE_SwitchToBank() Fail!!\n");770goto out_free_buffer;771}772773eFuse_Addr = bank * EFUSE_MAX_BANK_SIZE;774775efuse_OneByteRead(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);776777if (efuseHeader == 0xFF && bank == startBank && Fake != TRUE) {778RTW_INFO("Non-PGed Efuse\n");779goto out_free_buffer;780}781RTW_INFO("EFUSE_REAL_CONTENT_LEN = %d\n", maprawlen);782783while ((efuseHeader != 0xFF) && ((efuseType == EFUSE_WIFI && (eFuse_Addr < maprawlen)) || (efuseType == EFUSE_BT && (eFuse_Addr < (endBank + 1) * EFUSE_MAX_BANK_SIZE)))) {784785RTW_INFO("Analyzing: Offset: 0x%X\n", eFuse_Addr);786787/* Check PG header for section num.*/788if (EXT_HEADER(efuseHeader)) {789bExtHeader = TRUE;790offset_2_0 = GET_HDR_OFFSET_2_0(efuseHeader);791efuse_OneByteRead(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);792793if (efuseExtHdr != 0xff) {794if (ALL_WORDS_DISABLED(efuseExtHdr)) {795/* Read next pg header*/796efuse_OneByteRead(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);797continue;798} else {799offset = ((efuseExtHdr & 0xF0) >> 1) | offset_2_0;800wden = (efuseExtHdr & 0x0F);801efuseHeader2Byte = (efuseExtHdr<<8)|efuseHeader;802RTW_INFO("Find efuseHeader2Byte = 0x%04X, offset=%d, wden=0x%x\n",803efuseHeader2Byte, offset, wden);804}805} else {806RTW_INFO("Error, efuse[%d]=0xff, efuseExtHdr=0xff\n", eFuse_Addr-1);807break;808}809} else {810offset = ((efuseHeader >> 4) & 0x0f);811wden = (efuseHeader & 0x0f);812}813814_rtw_memset(efuseData, '\0', EFUSE_MAX_WORD_UNIT * 2);815dataCnt = 0;816817if (offset < max_section) {818for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {819/* Check word enable condition in the section */820if (!(wden & (0x01<<i))) {821if (!((efuseType == EFUSE_WIFI && (eFuse_Addr + 2 < maprawlen)) ||822(efuseType == EFUSE_BT && (eFuse_Addr + 2 < (endBank + 1) * EFUSE_MAX_BANK_SIZE)))) {823RTW_INFO("eFuse_Addr exceeds, break\n");824break;825}826efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData[dataCnt++], bPseudoTest);827eFuseWord[(offset * 8) + (i * 2)] = (efuseData[dataCnt - 1]);828efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData[dataCnt++], bPseudoTest);829eFuseWord[(offset * 8) + (i * 2 + 1)] = (efuseData[dataCnt - 1]);830}831}832}833834if (bExtHeader) {835RTW_INFO("Efuse PG Section (%d) = ", pgSectionCnt);836RTW_INFO("[ %04X ], [", efuseHeader2Byte);837838} else {839RTW_INFO("Efuse PG Section (%d) = ", pgSectionCnt);840RTW_INFO("[ %02X ], [", efuseHeader);841}842843for (j = 0; j < dataCnt; j++)844RTW_INFO(" %02X ", efuseData[j]);845846RTW_INFO("]\n");847848849if (bExtHeader) {850ParseEfuseExtHdr = (efuseHeader2Byte & 0xff00) >> 8;851ParseEfuseHeader = (efuseHeader2Byte & 0xff);852ParseOffset2_0 = GET_HDR_OFFSET_2_0(ParseEfuseHeader);853ParseOffset = ((ParseEfuseExtHdr & 0xF0) >> 1) | ParseOffset2_0;854ParseWDEN = (ParseEfuseExtHdr & 0x0F);855RTW_INFO("Header=0x%x, ExtHeader=0x%x, ", ParseEfuseHeader, ParseEfuseExtHdr);856} else {857ParseEfuseHeader = efuseHeader;858ParseOffset = ((ParseEfuseHeader >> 4) & 0x0f);859ParseWDEN = (ParseEfuseHeader & 0x0f);860RTW_INFO("Header=0x%x, ", ParseEfuseHeader);861}862RTW_INFO("offset=0x%x(%d), word enable=0x%x\n", ParseOffset, ParseOffset, ParseWDEN);863864wd_cnt = 0;865for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {866if (!(wden & (0x01 << i))) {867RTW_INFO("Map[ %02X ] = %02X %02X\n", ((offset * EFUSE_MAX_WORD_UNIT * 2) + (i * 2)), efuseData[wd_cnt * 2 + 0], efuseData[wd_cnt * 2 + 1]);868wd_cnt++;869}870}871872pgSectionCnt++;873bExtHeader = FALSE;874efuse_OneByteRead(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);875if (efuseHeader == 0xFF) {876if ((eFuse_Addr + protectBytesBank) >= efuse_max)877bCheckNextBank = TRUE;878else879bCheckNextBank = FALSE;880}881}882if (!bCheckNextBank) {883RTW_INFO("Not need to check next bank, eFuse_Addr=%d, protectBytesBank=%d, efuse_max=%d\n",884eFuse_Addr, protectBytesBank, efuse_max);885break;886}887}888/* switch bank back to 0 for BT/wifi later use*/889hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);890891/* 3. Collect 16 sections and 4 word unit into Efuse map.*/892for (i = 0; i < max_section; i++) {893for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {894pEfuseHal->fakeEfuseInitMap[(i*8)+(j*2)] = (eFuseWord[(i*8)+(j*2)]);895pEfuseHal->fakeEfuseInitMap[(i*8)+((j*2)+1)] = (eFuseWord[(i*8)+((j*2)+1)]);896}897}898899RTW_INFO("\n\tEFUSE Analyze Map\n");900i = 0;901j = 0;902903for (i = 0; i < mapLen; i++) {904if (i % 16 == 0)905RTW_PRINT_SEL(RTW_DBGDUMP, "0x%03x: ", i);906_RTW_PRINT_SEL(RTW_DBGDUMP, "%02X%s"907, pEfuseHal->fakeEfuseInitMap[i]908, ((i + 1) % 16 == 0) ? "\n" : (((i + 1) % 8 == 0) ? " " : " ")909);910}911_RTW_PRINT_SEL(RTW_DBGDUMP, "\n");912913out_free_buffer:914if (eFuseWord)915rtw_mfree((u8 *)eFuseWord, EFUSE_MAX_SECTION_NUM * (EFUSE_MAX_WORD_UNIT * 2));916}917918void efuse_PreUpdateAction(919PADAPTER pAdapter,920u32 *BackupRegs)921{922if (IS_HARDWARE_TYPE_8812AU(pAdapter) || IS_HARDWARE_TYPE_8822BU(pAdapter)) {923/* <20131115, Kordan> Turn off Rx to prevent from being busy when writing the EFUSE. (Asked by Chunchu.)*/924BackupRegs[0] = phy_query_mac_reg(pAdapter, REG_RCR, bMaskDWord);925BackupRegs[1] = phy_query_mac_reg(pAdapter, REG_RXFLTMAP0, bMaskDWord);926BackupRegs[2] = phy_query_mac_reg(pAdapter, REG_RXFLTMAP0+4, bMaskDWord);927#ifdef CONFIG_RTL8812A928BackupRegs[3] = phy_query_mac_reg(pAdapter, REG_AFE_MISC, bMaskDWord);929#endif930PlatformEFIOWrite4Byte(pAdapter, REG_RCR, 0x1);931PlatformEFIOWrite1Byte(pAdapter, REG_RXFLTMAP0, 0);932PlatformEFIOWrite1Byte(pAdapter, REG_RXFLTMAP0+1, 0);933PlatformEFIOWrite1Byte(pAdapter, REG_RXFLTMAP0+2, 0);934PlatformEFIOWrite1Byte(pAdapter, REG_RXFLTMAP0+3, 0);935PlatformEFIOWrite1Byte(pAdapter, REG_RXFLTMAP0+4, 0);936PlatformEFIOWrite1Byte(pAdapter, REG_RXFLTMAP0+5, 0);937#ifdef CONFIG_RTL8812A938/* <20140410, Kordan> 0x11 = 0x4E, lower down LX_SPS0 voltage. (Asked by Chunchu)*/939phy_set_mac_reg(pAdapter, REG_AFE_MISC, bMaskByte1, 0x4E);940#endif941RTW_INFO(" %s , done\n", __func__);942943}944}945946947void efuse_PostUpdateAction(948PADAPTER pAdapter,949u32 *BackupRegs)950{951if (IS_HARDWARE_TYPE_8812AU(pAdapter) || IS_HARDWARE_TYPE_8822BU(pAdapter)) {952/* <20131115, Kordan> Turn on Rx and restore the registers. (Asked by Chunchu.)*/953phy_set_mac_reg(pAdapter, REG_RCR, bMaskDWord, BackupRegs[0]);954phy_set_mac_reg(pAdapter, REG_RXFLTMAP0, bMaskDWord, BackupRegs[1]);955phy_set_mac_reg(pAdapter, REG_RXFLTMAP0+4, bMaskDWord, BackupRegs[2]);956#ifdef CONFIG_RTL8812A957phy_set_mac_reg(pAdapter, REG_AFE_MISC, bMaskDWord, BackupRegs[3]);958#endif959RTW_INFO(" %s , done\n", __func__);960}961}962963964#ifdef RTW_HALMAC965#include "../../hal/hal_halmac.h"966967void Efuse_PowerSwitch(PADAPTER adapter, u8 write, u8 pwrstate)968{969}970971void BTEfuse_PowerSwitch(PADAPTER adapter, u8 write, u8 pwrstate)972{973}974975u8 efuse_GetCurrentSize(PADAPTER adapter, u16 *size)976{977*size = 0;978979return _FAIL;980}981982u16 efuse_GetMaxSize(PADAPTER adapter)983{984struct dvobj_priv *d;985u32 size = 0;986int err;987988d = adapter_to_dvobj(adapter);989err = rtw_halmac_get_physical_efuse_size(d, &size);990if (err)991return 0;992993return size;994}995996u16 efuse_GetavailableSize(PADAPTER adapter)997{998struct dvobj_priv *d;999u32 size = 0;1000int err;10011002d = adapter_to_dvobj(adapter);1003err = rtw_halmac_get_available_efuse_size(d, &size);1004if (err)1005return 0;10061007return size;1008}100910101011u8 efuse_bt_GetCurrentSize(PADAPTER adapter, u16 *usesize)1012{1013u8 *efuse_map;10141015*usesize = 0;1016efuse_map = rtw_malloc(EFUSE_BT_MAP_LEN);1017if (efuse_map == NULL) {1018RTW_DBG("%s: malloc FAIL\n", __FUNCTION__);1019return _FAIL;1020}10211022/* for get bt phy efuse last use byte */1023hal_ReadEFuse_BT_logic_map(adapter, 0x00, EFUSE_BT_MAP_LEN, efuse_map);1024*usesize = fakeBTEfuseUsedBytes;10251026if (efuse_map)1027rtw_mfree(efuse_map, EFUSE_BT_MAP_LEN);10281029return _SUCCESS;1030}10311032u16 efuse_bt_GetMaxSize(PADAPTER adapter)1033{1034return EFUSE_BT_REAL_CONTENT_LEN;1035}10361037void EFUSE_GetEfuseDefinition(PADAPTER adapter, u8 efusetype, u8 type, void *out, BOOLEAN test)1038{1039struct dvobj_priv *d;1040u32 v32 = 0;104110421043d = adapter_to_dvobj(adapter);10441045if (adapter->hal_func.EFUSEGetEfuseDefinition) {1046adapter->hal_func.EFUSEGetEfuseDefinition(adapter, efusetype, type, out, test);1047return;1048}10491050if (EFUSE_WIFI == efusetype) {1051switch (type) {1052case TYPE_EFUSE_MAP_LEN:1053rtw_halmac_get_logical_efuse_size(d, &v32);1054*(u16 *)out = (u16)v32;1055return;10561057case TYPE_EFUSE_REAL_CONTENT_LEN:1058rtw_halmac_get_physical_efuse_size(d, &v32);1059*(u16 *)out = (u16)v32;1060return;1061}1062} else if (EFUSE_BT == efusetype) {1063switch (type) {1064case TYPE_EFUSE_MAP_LEN:1065*(u16 *)out = EFUSE_BT_MAP_LEN;1066return;10671068case TYPE_EFUSE_REAL_CONTENT_LEN:1069*(u16 *)out = EFUSE_BT_REAL_CONTENT_LEN;1070return;1071}1072}1073}10741075/*1076* read/write raw efuse data1077*/1078u8 rtw_efuse_access(PADAPTER adapter, u8 write, u16 addr, u16 cnts, u8 *data)1079{1080struct dvobj_priv *d;1081u8 *efuse = NULL;1082u32 size;1083int err;108410851086d = adapter_to_dvobj(adapter);1087err = rtw_halmac_get_physical_efuse_size(d, &size);1088if (err){1089size = EFUSE_MAX_SIZE;1090RTW_INFO(" physical_efuse_size err size %d\n", size);1091}10921093if ((addr + cnts) > size)1094return _FAIL;10951096if (_TRUE == write) {1097err = rtw_halmac_write_physical_efuse(d, addr, cnts, data);1098if (err)1099return _FAIL;1100} else {1101if (cnts > 16)1102efuse = rtw_zmalloc(size);11031104if (efuse) {1105err = rtw_halmac_read_physical_efuse_map(d, efuse, size);1106if (err) {1107rtw_mfree(efuse, size);1108return _FAIL;1109}11101111_rtw_memcpy(data, efuse + addr, cnts);1112rtw_mfree(efuse, size);1113} else {1114err = rtw_halmac_read_physical_efuse(d, addr, cnts, data);1115if (err)1116return _FAIL;1117}1118}11191120return _SUCCESS;1121}11221123static inline void dump_buf(u8 *buf, u32 len)1124{1125u32 i;11261127RTW_INFO("-----------------Len %d----------------\n", len);1128for (i = 0; i < len; i++)1129printk("%2.2x-", *(buf + i));1130printk("\n");1131}11321133/*1134* read/write raw efuse data1135*/1136u8 rtw_efuse_bt_access(PADAPTER adapter, u8 write, u16 addr, u16 cnts, u8 *data)1137{1138struct dvobj_priv *d;1139u8 *efuse = NULL;1140u32 size;1141int err = _FAIL;114211431144d = adapter_to_dvobj(adapter);11451146size = EFUSE_BT_REAL_CONTENT_LEN;11471148if ((addr + cnts) > size)1149return _FAIL;11501151if (_TRUE == write) {1152err = rtw_halmac_write_bt_physical_efuse(d, addr, cnts, data);1153if (err == -1) {1154RTW_ERR("%s: rtw_halmac_write_bt_physical_efuse fail!\n", __FUNCTION__);1155return _FAIL;1156}1157RTW_INFO("%s: rtw_halmac_write_bt_physical_efuse OK! data 0x%x\n", __FUNCTION__, *data);1158} else {1159efuse = rtw_zmalloc(size);11601161if (efuse) {1162err = rtw_halmac_read_bt_physical_efuse_map(d, efuse, size);11631164if (err == -1) {1165RTW_ERR("%s: rtw_halmac_read_bt_physical_efuse_map fail!\n", __FUNCTION__);1166rtw_mfree(efuse, size);1167return _FAIL;1168}1169dump_buf(efuse + addr, cnts);11701171_rtw_memcpy(data, efuse + addr, cnts);11721173RTW_INFO("%s: rtw_halmac_read_bt_physical_efuse_map ok! data 0x%x\n", __FUNCTION__, *data);1174rtw_mfree(efuse, size);1175}1176}11771178return _SUCCESS;1179}11801181u8 rtw_efuse_map_read(PADAPTER adapter, u16 addr, u16 cnts, u8 *data)1182{1183struct dvobj_priv *d;1184u8 *efuse = NULL;1185u32 size, i;1186int err;1187u32 backupRegs[4] = {0};1188u8 status = _SUCCESS;11891190efuse_PreUpdateAction(adapter, backupRegs);11911192d = adapter_to_dvobj(adapter);1193err = rtw_halmac_get_logical_efuse_size(d, &size);1194if (err) {1195status = _FAIL;1196RTW_DBG("halmac_get_logical_efuse_size fail\n");1197goto exit;1198}1199/* size error handle */1200if ((addr + cnts) > size) {1201if (addr < size)1202cnts = size - addr;1203else {1204status = _FAIL;1205RTW_DBG(" %s() ,addr + cnts) > size fail\n", __func__);1206goto exit;1207}1208}12091210if (cnts > 16)1211efuse = rtw_zmalloc(size);12121213if (efuse) {1214err = rtw_halmac_read_logical_efuse_map(d, efuse, size, NULL, 0);1215if (err) {1216rtw_mfree(efuse, size);1217status = _FAIL;1218RTW_DBG(" %s() ,halmac_read_logical_efus map fail\n", __func__);1219goto exit;1220}12211222_rtw_memcpy(data, efuse + addr, cnts);1223rtw_mfree(efuse, size);1224} else {1225err = rtw_halmac_read_logical_efuse(d, addr, cnts, data);1226if (err) {1227status = _FAIL;1228RTW_DBG(" %s() ,halmac_read_logical_efus data fail\n", __func__);1229goto exit;1230}1231}1232status = _SUCCESS;1233exit:1234efuse_PostUpdateAction(adapter, backupRegs);12351236return status;1237}12381239u8 rtw_efuse_map_write(PADAPTER adapter, u16 addr, u16 cnts, u8 *data)1240{1241struct dvobj_priv *d;1242u8 *efuse = NULL;1243u32 size;1244int err;1245u8 mask_buf[64] = "";1246u16 mask_len = sizeof(u8) * rtw_get_efuse_mask_arraylen(adapter);1247u32 backupRegs[4] = {0};1248u8 status = _SUCCESS;;12491250efuse_PreUpdateAction(adapter, backupRegs);12511252d = adapter_to_dvobj(adapter);1253err = rtw_halmac_get_logical_efuse_size(d, &size);1254if (err) {1255status = _FAIL;1256goto exit;1257}12581259if ((addr + cnts) > size) {1260status = _FAIL;1261goto exit;1262}12631264efuse = rtw_zmalloc(size);1265if (!efuse) {1266status = _FAIL;1267goto exit;1268}12691270err = rtw_halmac_read_logical_efuse_map(d, efuse, size, NULL, 0);1271if (err) {1272rtw_mfree(efuse, size);1273status = _FAIL;1274goto exit;1275}12761277_rtw_memcpy(efuse + addr, data, cnts);12781279if (adapter->registrypriv.boffefusemask == 0) {1280RTW_INFO("Use mask Array Len: %d\n", mask_len);12811282if (mask_len != 0) {1283if (adapter->registrypriv.bFileMaskEfuse == _TRUE)1284_rtw_memcpy(mask_buf, maskfileBuffer, mask_len);1285else1286rtw_efuse_mask_array(adapter, mask_buf);12871288err = rtw_halmac_write_logical_efuse_map(d, efuse, size, mask_buf, mask_len);1289} else1290err = rtw_halmac_write_logical_efuse_map(d, efuse, size, NULL, 0);1291} else {1292_rtw_memset(mask_buf, 0xFF, sizeof(mask_buf));1293RTW_INFO("Efuse mask off\n");1294err = rtw_halmac_write_logical_efuse_map(d, efuse, size, mask_buf, size/16);1295}12961297if (err) {1298rtw_mfree(efuse, size);1299status = _FAIL;1300goto exit;1301}13021303rtw_mfree(efuse, size);1304status = _SUCCESS;1305exit :1306efuse_PostUpdateAction(adapter, backupRegs);13071308return status;1309}13101311int Efuse_PgPacketRead(PADAPTER adapter, u8 offset, u8 *data, BOOLEAN test)1312{1313return _FALSE;1314}13151316int Efuse_PgPacketWrite(PADAPTER adapter, u8 offset, u8 word_en, u8 *data, BOOLEAN test)1317{1318return _FALSE;1319}13201321static void rtw_bt_mask_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data)1322{1323u16 i = 0;13241325if (padapter->registrypriv.boffefusemask == 0) {1326for (i = 0; i < cnts; i++) {1327if (padapter->registrypriv.bBTFileMaskEfuse == _TRUE) {1328if (rtw_file_efuse_IsMasked(padapter, addr + i, btmaskfileBuffer)) /*use BT file efuse mask.*/1329data[i] = 0xff;1330else1331RTW_DBG("data[%x] = %x\n", i, data[i]);1332} else {1333if (efuse_IsBT_Masked(padapter, addr + i)) /*use drv internal efuse mask.*/1334data[i] = 0xff;1335else1336RTW_DBG("data[%x] = %x\n", i, data[i]);1337}1338}1339}13401341}13421343u8 rtw_BT_efuse_map_read(PADAPTER adapter, u16 addr, u16 cnts, u8 *data)1344{1345hal_ReadEFuse_BT_logic_map(adapter, addr, cnts, data);13461347rtw_bt_mask_map_read(adapter, addr, cnts, data);13481349return _SUCCESS;1350}13511352u8 rtw_BT_efuse_map_write(PADAPTER adapter, u16 addr, u16 cnts, u8 *data)1353{1354#define RT_ASSERT_RET(expr) \1355if (!(expr)) { \1356printk("Assertion failed! %s at ......\n", #expr); \1357printk(" ......%s,%s, line=%d\n",__FILE__, __FUNCTION__, __LINE__); \1358return _FAIL; \1359}13601361u8 offset, word_en;1362u8 *efuse = NULL;1363u8 *map;1364u8 newdata[PGPKT_DATA_SIZE];1365s32 i = 0, j = 0, idx;1366u8 ret = _SUCCESS;1367u16 mapLen = 1024;13681369if ((addr + cnts) > mapLen)1370return _FAIL;13711372RT_ASSERT_RET(PGPKT_DATA_SIZE == 8); /* have to be 8 byte alignment */1373RT_ASSERT_RET((mapLen & 0x7) == 0); /* have to be PGPKT_DATA_SIZE alignment for memcpy */13741375efuse = rtw_zmalloc(mapLen);1376if (!efuse)1377return _FAIL;13781379map = rtw_zmalloc(mapLen);1380if (map == NULL) {1381rtw_mfree(efuse, mapLen);1382return _FAIL;1383}13841385_rtw_memset(map, 0xFF, mapLen);13861387ret = rtw_BT_efuse_map_read(adapter, 0, mapLen, map);1388if (ret == _FAIL)1389goto exit;13901391_rtw_memcpy(efuse , map, mapLen);1392_rtw_memcpy(efuse + addr, data, cnts);13931394if (adapter->registrypriv.boffefusemask == 0) {1395for (i = 0; i < cnts; i++) {1396if (adapter->registrypriv.bFileMaskEfuse == _TRUE) {1397if (rtw_file_efuse_IsMasked(adapter, addr + i, btmaskfileBuffer)) /*use file efuse mask. */1398efuse[addr + i] = map[addr + i];1399} else {1400if (efuse_IsBT_Masked(adapter, addr + i))1401efuse[addr + i] = map[addr + i];1402}1403RTW_INFO("%s , efuse[%x] = %x, map = %x\n", __func__, addr + i, efuse[ addr + i], map[addr + i]);1404}1405}14061407idx = 0;1408offset = (addr >> 3);1409while (idx < cnts) {1410word_en = 0xF;1411j = (addr + idx) & 0x7;1412_rtw_memcpy(newdata, &map[offset << 3], PGPKT_DATA_SIZE);1413for (i = j; i < PGPKT_DATA_SIZE && idx < cnts; i++, idx++) {1414if (efuse[idx] != map[addr + idx]) {1415word_en &= ~BIT(i >> 1);1416newdata[i] = efuse[idx];1417}1418}14191420if (word_en != 0xF) {1421ret = EfusePgPacketWrite_BT(adapter, offset, word_en, newdata, _FALSE);1422RTW_INFO("offset=%x\n", offset);1423RTW_INFO("word_en=%x\n", word_en);1424RTW_INFO("%s: data=", __FUNCTION__);1425for (i = 0; i < PGPKT_DATA_SIZE; i++)1426RTW_INFO("0x%02X ", newdata[i]);1427RTW_INFO("\n");1428if (ret == _FAIL)1429break;1430}1431offset++;1432}1433exit:1434rtw_mfree(map, mapLen);1435return _SUCCESS;1436}14371438void hal_ReadEFuse_BT_logic_map(1439PADAPTER padapter,1440u16 _offset,1441u16 _size_byte,1442u8 *pbuf1443)1444{14451446PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);14471448u8 *efuseTbl, *phyefuse;1449u8 bank;1450u16 eFuse_Addr = 0;1451u8 efuseHeader, efuseExtHdr, efuseData;1452u8 offset, wden;1453u16 i, total, used;1454u8 efuse_usage;145514561457/* */1458/* Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */1459/* */1460if ((_offset + _size_byte) > EFUSE_BT_MAP_LEN) {1461RTW_INFO("%s: Invalid offset(%#x) with read bytes(%#x)!!\n", __FUNCTION__, _offset, _size_byte);1462return;1463}14641465efuseTbl = rtw_malloc(EFUSE_BT_MAP_LEN);1466phyefuse = rtw_malloc(EFUSE_BT_REAL_CONTENT_LEN);1467if (efuseTbl == NULL || phyefuse == NULL) {1468RTW_INFO("%s: efuseTbl or phyefuse malloc fail!\n", __FUNCTION__);1469goto exit;1470}14711472/* 0xff will be efuse default value instead of 0x00. */1473_rtw_memset(efuseTbl, 0xFF, EFUSE_BT_MAP_LEN);1474_rtw_memset(phyefuse, 0xFF, EFUSE_BT_REAL_CONTENT_LEN);14751476if (rtw_efuse_bt_access(padapter, _FALSE, 0, EFUSE_BT_REAL_CONTENT_LEN, phyefuse))1477dump_buf(phyefuse, EFUSE_BT_REAL_BANK_CONTENT_LEN);14781479total = BANK_NUM;1480for (bank = 1; bank <= total; bank++) { /* 8723d Max bake 0~2 */1481eFuse_Addr = 0;14821483while (AVAILABLE_EFUSE_ADDR(eFuse_Addr)) {1484/* ReadEFuseByte(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest); */1485efuseHeader = phyefuse[eFuse_Addr++];14861487if (efuseHeader == 0xFF)1488break;1489RTW_INFO("%s: efuse[%#X]=0x%02x (header)\n", __FUNCTION__, (((bank - 1) * EFUSE_BT_REAL_CONTENT_LEN) + eFuse_Addr - 1), efuseHeader);14901491/* Check PG header for section num. */1492if (EXT_HEADER(efuseHeader)) { /* extended header */1493offset = GET_HDR_OFFSET_2_0(efuseHeader);1494RTW_INFO("%s: extended header offset_2_0=0x%X\n", __FUNCTION__, offset);14951496/* ReadEFuseByte(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest); */1497efuseExtHdr = phyefuse[eFuse_Addr++];14981499RTW_INFO("%s: efuse[%#X]=0x%02x (ext header)\n", __FUNCTION__, (((bank - 1) * EFUSE_BT_REAL_CONTENT_LEN) + eFuse_Addr - 1), efuseExtHdr);1500if (ALL_WORDS_DISABLED(efuseExtHdr))1501continue;15021503offset |= ((efuseExtHdr & 0xF0) >> 1);1504wden = (efuseExtHdr & 0x0F);1505} else {1506offset = ((efuseHeader >> 4) & 0x0f);1507wden = (efuseHeader & 0x0f);1508}15091510if (offset < EFUSE_BT_MAX_SECTION) {1511u16 addr;15121513/* Get word enable value from PG header */1514RTW_INFO("%s: Offset=%d Worden=%#X\n", __FUNCTION__, offset, wden);15151516addr = offset * PGPKT_DATA_SIZE;1517for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {1518/* Check word enable condition in the section */1519if (!(wden & (0x01 << i))) {1520efuseData = 0;1521/* ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest); */1522efuseData = phyefuse[eFuse_Addr++];15231524RTW_INFO("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr - 1, efuseData);1525efuseTbl[addr] = efuseData;15261527efuseData = 0;1528/* ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest); */1529efuseData = phyefuse[eFuse_Addr++];15301531RTW_INFO("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr - 1, efuseData);1532efuseTbl[addr + 1] = efuseData;1533}1534addr += 2;1535}1536} else {1537RTW_INFO("%s: offset(%d) is illegal!!\n", __FUNCTION__, offset);1538eFuse_Addr += Efuse_CalculateWordCnts(wden) * 2;1539}1540}15411542if ((eFuse_Addr - 1) < total) {1543RTW_INFO("%s: bank(%d) data end at %#x\n", __FUNCTION__, bank, eFuse_Addr - 1);1544break;1545}1546}15471548/* switch bank back to bank 0 for later BT and wifi use. */1549//hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);15501551/* Copy from Efuse map to output pointer memory!!! */1552for (i = 0; i < _size_byte; i++)1553pbuf[i] = efuseTbl[_offset + i];1554/* Calculate Efuse utilization */1555total = EFUSE_BT_REAL_BANK_CONTENT_LEN;15561557used = eFuse_Addr - 1;15581559if (total)1560efuse_usage = (u8)((used * 100) / total);1561else1562efuse_usage = 100;15631564fakeBTEfuseUsedBytes = used;1565RTW_INFO("%s: BTEfuseUsed last Bytes = %#x\n", __FUNCTION__, fakeBTEfuseUsedBytes);15661567exit:1568if (efuseTbl)1569rtw_mfree(efuseTbl, EFUSE_BT_MAP_LEN);1570if (phyefuse)1571rtw_mfree(phyefuse, EFUSE_BT_REAL_BANK_CONTENT_LEN);1572}157315741575static u8 hal_EfusePartialWriteCheck(1576PADAPTER padapter,1577u8 efuseType,1578u16 *pAddr,1579PPGPKT_STRUCT pTargetPkt,1580u8 bPseudoTest)1581{1582u8 bRet = _FALSE;1583u16 startAddr = 0, efuse_max_available_len = EFUSE_BT_REAL_BANK_CONTENT_LEN, efuse_max = EFUSE_BT_REAL_BANK_CONTENT_LEN;1584u8 efuse_data = 0;15851586startAddr = (u16)fakeBTEfuseUsedBytes;15871588startAddr %= efuse_max;1589RTW_INFO("%s: startAddr=%#X\n", __FUNCTION__, startAddr);15901591while (1) {1592if (startAddr >= efuse_max_available_len) {1593bRet = _FALSE;1594RTW_INFO("%s: startAddr(%d) >= efuse_max_available_len(%d)\n",1595__FUNCTION__, startAddr, efuse_max_available_len);1596break;1597}1598if (rtw_efuse_bt_access(padapter, _FALSE, startAddr, 1, &efuse_data)&& (efuse_data != 0xFF)) {1599bRet = _FALSE;1600RTW_INFO("%s: Something Wrong! last bytes(%#X=0x%02X) is not 0xFF\n",1601__FUNCTION__, startAddr, efuse_data);1602break;1603} else {1604/* not used header, 0xff */1605*pAddr = startAddr;1606/* RTW_INFO("%s: Started from unused header offset=%d\n", __FUNCTION__, startAddr)); */1607bRet = _TRUE;1608break;1609}1610}16111612return bRet;1613}161416151616static u8 hal_EfusePgPacketWrite2ByteHeader(1617PADAPTER padapter,1618u8 efuseType,1619u16 *pAddr,1620PPGPKT_STRUCT pTargetPkt,1621u8 bPseudoTest)1622{1623u16 efuse_addr, efuse_max_available_len = EFUSE_BT_REAL_BANK_CONTENT_LEN;1624u8 pg_header = 0, tmp_header = 0;1625u8 repeatcnt = 0;16261627/* RTW_INFO("%s\n", __FUNCTION__); */16281629efuse_addr = *pAddr;1630if (efuse_addr >= efuse_max_available_len) {1631RTW_INFO("%s: addr(%d) over avaliable(%d)!!\n", __FUNCTION__, efuse_addr, efuse_max_available_len);1632return _FALSE;1633}16341635pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F;1636/* RTW_INFO("%s: pg_header=0x%x\n", __FUNCTION__, pg_header); */16371638do {16391640rtw_efuse_bt_access(padapter, _TRUE, efuse_addr, 1, &pg_header);1641rtw_efuse_bt_access(padapter, _FALSE, efuse_addr, 1, &tmp_header);16421643if (tmp_header != 0xFF)1644break;1645if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {1646RTW_INFO("%s: Repeat over limit for pg_header!!\n", __FUNCTION__);1647return _FALSE;1648}1649} while (1);16501651if (tmp_header != pg_header) {1652RTW_ERR("%s: PG Header Fail!!(pg=0x%02X read=0x%02X)\n", __FUNCTION__, pg_header, tmp_header);1653return _FALSE;1654}16551656/* to write ext_header */1657efuse_addr++;1658pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en;16591660do {1661rtw_efuse_bt_access(padapter, _TRUE, efuse_addr, 1, &pg_header);1662rtw_efuse_bt_access(padapter, _FALSE, efuse_addr, 1, &tmp_header);16631664if (tmp_header != 0xFF)1665break;1666if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {1667RTW_INFO("%s: Repeat over limit for ext_header!!\n", __FUNCTION__);1668return _FALSE;1669}1670} while (1);16711672if (tmp_header != pg_header) { /* offset PG fail */1673RTW_ERR("%s: PG EXT Header Fail!!(pg=0x%02X read=0x%02X)\n", __FUNCTION__, pg_header, tmp_header);1674return _FALSE;1675}16761677*pAddr = efuse_addr;16781679return _TRUE;1680}168116821683static u8 hal_EfusePgPacketWrite1ByteHeader(1684PADAPTER pAdapter,1685u8 efuseType,1686u16 *pAddr,1687PPGPKT_STRUCT pTargetPkt,1688u8 bPseudoTest)1689{1690u8 pg_header = 0, tmp_header = 0;1691u16 efuse_addr = *pAddr;1692u8 repeatcnt = 0;169316941695/* RTW_INFO("%s\n", __FUNCTION__); */1696pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en;16971698do {1699rtw_efuse_bt_access(pAdapter, _TRUE, efuse_addr, 1, &pg_header);1700rtw_efuse_bt_access(pAdapter, _FALSE, efuse_addr, 1, &tmp_header);17011702if (tmp_header != 0xFF)1703break;1704if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {1705RTW_INFO("%s: Repeat over limit for pg_header!!\n", __FUNCTION__);1706return _FALSE;1707}1708} while (1);17091710if (tmp_header != pg_header) {1711RTW_ERR("%s: PG Header Fail!!(pg=0x%02X read=0x%02X)\n", __FUNCTION__, pg_header, tmp_header);1712return _FALSE;1713}17141715*pAddr = efuse_addr;17161717return _TRUE;1718}17191720static u8 hal_EfusePgPacketWriteHeader(1721PADAPTER padapter,1722u8 efuseType,1723u16 *pAddr,1724PPGPKT_STRUCT pTargetPkt,1725u8 bPseudoTest)1726{1727u8 bRet = _FALSE;17281729if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE)1730bRet = hal_EfusePgPacketWrite2ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest);1731else1732bRet = hal_EfusePgPacketWrite1ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest);17331734return bRet;1735}173617371738static u81739Hal_EfuseWordEnableDataWrite(1740PADAPTER padapter,1741u16 efuse_addr,1742u8 word_en,1743u8 *data,1744u8 bPseudoTest)1745{1746u16 tmpaddr = 0;1747u16 start_addr = efuse_addr;1748u8 badworden = 0x0F;1749u8 tmpdata[PGPKT_DATA_SIZE];175017511752/* RTW_INFO("%s: efuse_addr=%#x word_en=%#x\n", __FUNCTION__, efuse_addr, word_en); */1753_rtw_memset(tmpdata, 0xFF, PGPKT_DATA_SIZE);17541755if (!(word_en & BIT(0))) {1756tmpaddr = start_addr;1757rtw_efuse_bt_access(padapter, _TRUE, start_addr++, 1, &data[0]);1758rtw_efuse_bt_access(padapter, _TRUE, start_addr++, 1, &data[1]);1759rtw_efuse_bt_access(padapter, _FALSE, tmpaddr, 1, &tmpdata[0]);1760rtw_efuse_bt_access(padapter, _FALSE, tmpaddr + 1, 1, &tmpdata[1]);1761if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1]))1762badworden &= (~BIT(0));1763}1764if (!(word_en & BIT(1))) {1765tmpaddr = start_addr;1766rtw_efuse_bt_access(padapter, _TRUE, start_addr++, 1, &data[2]);1767rtw_efuse_bt_access(padapter, _TRUE, start_addr++, 1, &data[3]);1768rtw_efuse_bt_access(padapter, _FALSE, tmpaddr, 1, &tmpdata[2]);1769rtw_efuse_bt_access(padapter, _FALSE, tmpaddr + 1, 1, &tmpdata[3]);1770if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3]))1771badworden &= (~BIT(1));1772}1773if (!(word_en & BIT(2))) {1774tmpaddr = start_addr;1775rtw_efuse_bt_access(padapter, _TRUE, start_addr++, 1, &data[4]);1776rtw_efuse_bt_access(padapter, _TRUE, start_addr++, 1, &data[5]);1777rtw_efuse_bt_access(padapter, _FALSE, tmpaddr, 1, &tmpdata[4]);1778rtw_efuse_bt_access(padapter, _FALSE, tmpaddr + 1, 1, &tmpdata[5]);1779if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5]))1780badworden &= (~BIT(2));1781}1782if (!(word_en & BIT(3))) {1783tmpaddr = start_addr;1784rtw_efuse_bt_access(padapter, _TRUE, start_addr++, 1, &data[6]);1785rtw_efuse_bt_access(padapter, _TRUE, start_addr++, 1, &data[7]);1786rtw_efuse_bt_access(padapter, _FALSE, tmpaddr, 1, &tmpdata[6]);1787rtw_efuse_bt_access(padapter, _FALSE, tmpaddr + 1, 1, &tmpdata[7]);17881789if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7]))1790badworden &= (~BIT(3));1791}17921793return badworden;1794}17951796static void1797hal_EfuseConstructPGPkt(1798u8 offset,1799u8 word_en,1800u8 *pData,1801PPGPKT_STRUCT pTargetPkt)1802{1803_rtw_memset(pTargetPkt->data, 0xFF, PGPKT_DATA_SIZE);1804pTargetPkt->offset = offset;1805pTargetPkt->word_en = word_en;1806efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data);1807pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);1808}18091810static u81811hal_EfusePgPacketWriteData(1812PADAPTER pAdapter,1813u8 efuseType,1814u16 *pAddr,1815PPGPKT_STRUCT pTargetPkt,1816u8 bPseudoTest)1817{1818u16 efuse_addr;1819u8 badworden;18201821efuse_addr = *pAddr;1822badworden = Hal_EfuseWordEnableDataWrite(pAdapter, efuse_addr + 1, pTargetPkt->word_en, pTargetPkt->data, bPseudoTest);1823if (badworden != 0x0F) {1824RTW_INFO("%s: Fail!!\n", __FUNCTION__);1825return _FALSE;1826} else1827RTW_INFO("%s: OK!!\n", __FUNCTION__);18281829return _TRUE;1830}18311832u8 efuse_OneByteRead(struct _ADAPTER *a, u16 addr, u8 *data, u8 bPseudoTest)1833{1834struct dvobj_priv *d;1835int err;1836u8 ret = _TRUE;18371838d = adapter_to_dvobj(a);1839err = rtw_halmac_read_physical_efuse(d, addr, 1, data);1840if (err) {1841RTW_ERR("%s: addr=0x%x FAIL!!!\n", __FUNCTION__, addr);1842ret = _FALSE;1843}18441845return ret;18461847}18481849static u161850hal_EfuseGetCurrentSize_BT(1851PADAPTER padapter,1852u8 bPseudoTest)1853{1854#ifdef HAL_EFUSE_MEMORY1855PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);1856PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;1857#endif1858u16 btusedbytes;1859u16 efuse_addr;1860u8 bank, startBank;1861u8 hoffset = 0, hworden = 0;1862u8 efuse_data, word_cnts = 0;1863u16 retU2 = 0;186418651866btusedbytes = fakeBTEfuseUsedBytes;18671868efuse_addr = (u16)((btusedbytes % EFUSE_BT_REAL_BANK_CONTENT_LEN));1869startBank = (u8)(1 + (btusedbytes / EFUSE_BT_REAL_BANK_CONTENT_LEN));18701871RTW_INFO("%s: start from bank=%d addr=0x%X\n", __FUNCTION__, startBank, efuse_addr);1872retU2 = EFUSE_BT_REAL_CONTENT_LEN - EFUSE_PROTECT_BYTES_BANK;18731874for (bank = startBank; bank < 3; bank++) {1875if (hal_EfuseSwitchToBank(padapter, bank, bPseudoTest) == _FALSE) {1876RTW_ERR("%s: switch bank(%d) Fail!!\n", __FUNCTION__, bank);1877/* bank = EFUSE_MAX_BANK; */1878break;1879}18801881/* only when bank is switched we have to reset the efuse_addr. */1882if (bank != startBank)1883efuse_addr = 0;188418851886while (AVAILABLE_EFUSE_ADDR(efuse_addr)) {1887if (rtw_efuse_bt_access(padapter, _FALSE, efuse_addr, 1, &efuse_data) == _FALSE) {1888RTW_ERR("%s: efuse_OneByteRead Fail! addr=0x%X !!\n", __FUNCTION__, efuse_addr);1889/* bank = EFUSE_MAX_BANK; */1890break;1891}1892RTW_INFO("%s: efuse_OneByteRead ! addr=0x%X !efuse_data=0x%X! bank =%d\n", __FUNCTION__, efuse_addr, efuse_data, bank);18931894if (efuse_data == 0xFF)1895break;18961897if (EXT_HEADER(efuse_data)) {1898hoffset = GET_HDR_OFFSET_2_0(efuse_data);1899efuse_addr++;1900rtw_efuse_bt_access(padapter, _FALSE, efuse_addr, 1, &efuse_data);1901RTW_INFO("%s: efuse_OneByteRead EXT_HEADER ! addr=0x%X !efuse_data=0x%X! bank =%d\n", __FUNCTION__, efuse_addr, efuse_data, bank);19021903if (ALL_WORDS_DISABLED(efuse_data)) {1904efuse_addr++;1905continue;1906}19071908/* hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1); */1909hoffset |= ((efuse_data & 0xF0) >> 1);1910hworden = efuse_data & 0x0F;1911} else {1912hoffset = (efuse_data >> 4) & 0x0F;1913hworden = efuse_data & 0x0F;1914}19151916RTW_INFO(FUNC_ADPT_FMT": Offset=%d Worden=%#X\n",1917FUNC_ADPT_ARG(padapter), hoffset, hworden);19181919word_cnts = Efuse_CalculateWordCnts(hworden);1920/* read next header */1921efuse_addr += (word_cnts * 2) + 1;1922}1923/* Check if we need to check next bank efuse */1924if (efuse_addr < retU2)1925break;/* don't need to check next bank. */1926}1927retU2 = ((bank - 1) * EFUSE_BT_REAL_BANK_CONTENT_LEN) + efuse_addr;19281929fakeBTEfuseUsedBytes = retU2;1930RTW_INFO("%s: CurrentSize=%d\n", __FUNCTION__, retU2);1931return retU2;1932}193319341935static u81936hal_BT_EfusePgCheckAvailableAddr(1937PADAPTER pAdapter,1938u8 bPseudoTest)1939{1940u16 max_available = EFUSE_BT_REAL_CONTENT_LEN - EFUSE_PROTECT_BYTES_BANK;1941u16 current_size = 0;19421943RTW_INFO("%s: max_available=%d\n", __FUNCTION__, max_available);1944current_size = hal_EfuseGetCurrentSize_BT(pAdapter, bPseudoTest);1945if (current_size >= max_available) {1946RTW_INFO("%s: Error!! current_size(%d)>max_available(%d)\n", __FUNCTION__, current_size, max_available);1947return _FALSE;1948}1949return _TRUE;1950}19511952u8 EfusePgPacketWrite_BT(1953PADAPTER pAdapter,1954u8 offset,1955u8 word_en,1956u8 *pData,1957u8 bPseudoTest)1958{1959PGPKT_STRUCT targetPkt;1960u16 startAddr = 0;1961u8 efuseType = EFUSE_BT;19621963if (!hal_BT_EfusePgCheckAvailableAddr(pAdapter, bPseudoTest))1964return _FALSE;19651966hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);19671968if (!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))1969return _FALSE;19701971if (!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))1972return _FALSE;19731974if (!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))1975return _FALSE;19761977return _TRUE;1978}197919801981#else /* !RTW_HALMAC */1982/* ------------------------------------------------------------------------------ */1983#define REG_EFUSE_CTRL 0x00301984#define EFUSE_CTRL REG_EFUSE_CTRL /* E-Fuse Control. */1985/* ------------------------------------------------------------------------------ */198619871988BOOLEAN1989Efuse_Read1ByteFromFakeContent(1990PADAPTER pAdapter,1991u16 Offset,1992u8 *Value);1993BOOLEAN1994Efuse_Read1ByteFromFakeContent(1995PADAPTER pAdapter,1996u16 Offset,1997u8 *Value)1998{1999if (Offset >= EFUSE_MAX_HW_SIZE)2000return _FALSE;2001/* DbgPrint("Read fake content, offset = %d\n", Offset); */2002if (fakeEfuseBank == 0)2003*Value = fakeEfuseContent[Offset];2004else2005*Value = fakeBTEfuseContent[fakeEfuseBank - 1][Offset];2006return _TRUE;2007}20082009BOOLEAN2010Efuse_Write1ByteToFakeContent(2011PADAPTER pAdapter,2012u16 Offset,2013u8 Value);2014BOOLEAN2015Efuse_Write1ByteToFakeContent(2016PADAPTER pAdapter,2017u16 Offset,2018u8 Value)2019{2020if (Offset >= EFUSE_MAX_HW_SIZE)2021return _FALSE;2022if (fakeEfuseBank == 0)2023fakeEfuseContent[Offset] = Value;2024else2025fakeBTEfuseContent[fakeEfuseBank - 1][Offset] = Value;2026return _TRUE;2027}20282029/*-----------------------------------------------------------------------------2030* Function: Efuse_PowerSwitch2031*2032* Overview: When we want to enable write operation, we should change to2033* pwr on state. When we stop write, we should switch to 500k mode2034* and disable LDO 2.5V.2035*2036* Input: NONE2037*2038* Output: NONE2039*2040* Return: NONE2041*2042* Revised History:2043* When Who Remark2044* 11/17/2008 MHC Create Version 0.2045*2046*---------------------------------------------------------------------------*/2047void2048Efuse_PowerSwitch(2049PADAPTER pAdapter,2050u8 bWrite,2051u8 PwrState)2052{2053pAdapter->hal_func.EfusePowerSwitch(pAdapter, bWrite, PwrState);2054}20552056void2057BTEfuse_PowerSwitch(2058PADAPTER pAdapter,2059u8 bWrite,2060u8 PwrState)2061{2062if (pAdapter->hal_func.BTEfusePowerSwitch)2063pAdapter->hal_func.BTEfusePowerSwitch(pAdapter, bWrite, PwrState);2064}20652066/*-----------------------------------------------------------------------------2067* Function: efuse_GetCurrentSize2068*2069* Overview: Get current efuse size!!!2070*2071* Input: NONE2072*2073* Output: NONE2074*2075* Return: NONE2076*2077* Revised History:2078* When Who Remark2079* 11/16/2008 MHC Create Version 0.2080*2081*---------------------------------------------------------------------------*/2082u162083Efuse_GetCurrentSize(2084PADAPTER pAdapter,2085u8 efuseType,2086BOOLEAN bPseudoTest)2087{2088u16 ret = 0;20892090ret = pAdapter->hal_func.EfuseGetCurrentSize(pAdapter, efuseType, bPseudoTest);20912092return ret;2093}20942095/*2096* Description:2097* Execute E-Fuse read byte operation.2098* Refered from SD1 Richard.2099*2100* Assumption:2101* 1. Boot from E-Fuse and successfully auto-load.2102* 2. PASSIVE_LEVEL (USB interface)2103*2104* Created by Roger, 2008.10.21.2105* */2106void2107ReadEFuseByte(2108PADAPTER Adapter,2109u16 _offset,2110u8 *pbuf,2111BOOLEAN bPseudoTest)2112{2113u32 value32;2114u8 readbyte;2115u16 retry;2116/* systime start=rtw_get_current_time(); */21172118if (bPseudoTest) {2119Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf);2120return;2121}2122if (IS_HARDWARE_TYPE_8723B(Adapter)) {2123/* <20130121, Kordan> For SMIC S55 EFUSE specificatoin. */2124/* 0x34[11]: SW force PGMEN input of efuse to high. (for the bank selected by 0x34[9:8]) */2125phy_set_mac_reg(Adapter, EFUSE_TEST, BIT11, 0);2126}2127/* Write Address */2128rtw_write8(Adapter, EFUSE_CTRL + 1, (_offset & 0xff));2129readbyte = rtw_read8(Adapter, EFUSE_CTRL + 2);2130rtw_write8(Adapter, EFUSE_CTRL + 2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));21312132/* Write bit 32 0 */2133readbyte = rtw_read8(Adapter, EFUSE_CTRL + 3);2134rtw_write8(Adapter, EFUSE_CTRL + 3, (readbyte & 0x7f));21352136/* Check bit 32 read-ready */2137retry = 0;2138value32 = rtw_read32(Adapter, EFUSE_CTRL);2139/* while(!(((value32 >> 24) & 0xff) & 0x80) && (retry<10)) */2140while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) {2141value32 = rtw_read32(Adapter, EFUSE_CTRL);2142retry++;2143}21442145/* 20100205 Joseph: Add delay suggested by SD1 Victor. */2146/* This fix the problem that Efuse read error in high temperature condition. */2147/* Designer says that there shall be some delay after ready bit is set, or the */2148/* result will always stay on last data we read. */2149rtw_udelay_os(50);2150value32 = rtw_read32(Adapter, EFUSE_CTRL);21512152*pbuf = (u8)(value32 & 0xff);2153/* RTW_INFO("ReadEFuseByte _offset:%08u, in %d ms\n",_offset ,rtw_get_passing_time_ms(start)); */21542155}21562157/*2158* Description:2159* 1. Execute E-Fuse read byte operation according as map offset and2160* save to E-Fuse table.2161* 2. Refered from SD1 Richard.2162*2163* Assumption:2164* 1. Boot from E-Fuse and successfully auto-load.2165* 2. PASSIVE_LEVEL (USB interface)2166*2167* Created by Roger, 2008.10.21.2168*2169* 2008/12/12 MH 1. Reorganize code flow and reserve bytes. and add description.2170* 2. Add efuse utilization collect.2171* 2008/12/22 MH Read Efuse must check if we write section 1 data again!!! Sec12172* write addr must be after sec5.2173* */21742175void2176efuse_ReadEFuse(2177PADAPTER Adapter,2178u8 efuseType,2179u16 _offset,2180u16 _size_byte,2181u8 *pbuf,2182BOOLEAN bPseudoTest2183);2184void2185efuse_ReadEFuse(2186PADAPTER Adapter,2187u8 efuseType,2188u16 _offset,2189u16 _size_byte,2190u8 *pbuf,2191BOOLEAN bPseudoTest2192)2193{2194Adapter->hal_func.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);2195}21962197void2198EFUSE_GetEfuseDefinition(2199PADAPTER pAdapter,2200u8 efuseType,2201u8 type,2202void *pOut,2203BOOLEAN bPseudoTest2204)2205{2206pAdapter->hal_func.EFUSEGetEfuseDefinition(pAdapter, efuseType, type, pOut, bPseudoTest);2207}220822092210/* 11/16/2008 MH Read one byte from real Efuse. */2211u82212efuse_OneByteRead(2213PADAPTER pAdapter,2214u16 addr,2215u8 *data,2216BOOLEAN bPseudoTest)2217{2218u32 tmpidx = 0;2219u8 bResult;2220u8 readbyte;2221HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);22222223/* RTW_INFO("===> EFUSE_OneByteRead(), addr = %x\n", addr); */2224/* RTW_INFO("===> EFUSE_OneByteRead() start, 0x34 = 0x%X\n", rtw_read32(pAdapter, EFUSE_TEST)); */22252226if (bPseudoTest) {2227bResult = Efuse_Read1ByteFromFakeContent(pAdapter, addr, data);2228return bResult;2229}22302231#ifdef CONFIG_RTL8710B2232/* <20171208, Peter>, Dont do the following write16(0x34) */2233if (IS_HARDWARE_TYPE_8710B(pAdapter)) {2234bResult = pAdapter->hal_func.efuse_indirect_read4(pAdapter, addr, data);2235return bResult;2236}2237#endif22382239if (IS_HARDWARE_TYPE_8723B(pAdapter) ||2240(IS_HARDWARE_TYPE_8192E(pAdapter) && (!IS_A_CUT(pHalData->version_id))) ||2241(IS_VENDOR_8188E_I_CUT_SERIES(pAdapter)) || (IS_CHIP_VENDOR_SMIC(pHalData->version_id))2242) {2243/* <20130121, Kordan> For SMIC EFUSE specificatoin. */2244/* 0x34[11]: SW force PGMEN input of efuse to high. (for the bank selected by 0x34[9:8]) */2245/* phy_set_mac_reg(pAdapter, 0x34, BIT11, 0); */2246rtw_write16(pAdapter, 0x34, rtw_read16(pAdapter, 0x34) & (~BIT11));2247}22482249/* -----------------e-fuse reg ctrl --------------------------------- */2250/* address */2251rtw_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff));2252rtw_write8(pAdapter, EFUSE_CTRL + 2, ((u8)((addr >> 8) & 0x03)) |2253(rtw_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC));22542255/* rtw_write8(pAdapter, EFUSE_CTRL+3, 0x72); */ /* read cmd */2256/* Write bit 32 0 */2257readbyte = rtw_read8(pAdapter, EFUSE_CTRL + 3);2258rtw_write8(pAdapter, EFUSE_CTRL + 3, (readbyte & 0x7f));22592260while (!(0x80 & rtw_read8(pAdapter, EFUSE_CTRL + 3)) && (tmpidx < 1000)) {2261rtw_mdelay_os(1);2262tmpidx++;2263}2264if (tmpidx < 100) {2265*data = rtw_read8(pAdapter, EFUSE_CTRL);2266bResult = _TRUE;2267} else {2268*data = 0xff;2269bResult = _FALSE;2270RTW_INFO("%s: [ERROR] addr=0x%x bResult=%d time out 1s !!!\n", __FUNCTION__, addr, bResult);2271RTW_INFO("%s: [ERROR] EFUSE_CTRL =0x%08x !!!\n", __FUNCTION__, rtw_read32(pAdapter, EFUSE_CTRL));2272}22732274return bResult;2275}22762277/* 11/16/2008 MH Write one byte to reald Efuse. */2278u82279efuse_OneByteWrite(2280PADAPTER pAdapter,2281u16 addr,2282u8 data,2283BOOLEAN bPseudoTest)2284{2285u8 tmpidx = 0;2286u8 bResult = _FALSE;2287u32 efuseValue = 0;2288HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);22892290/* RTW_INFO("===> EFUSE_OneByteWrite(), addr = %x data=%x\n", addr, data); */2291/* RTW_INFO("===> EFUSE_OneByteWrite() start, 0x34 = 0x%X\n", rtw_read32(pAdapter, EFUSE_TEST)); */22922293if (bPseudoTest) {2294bResult = Efuse_Write1ByteToFakeContent(pAdapter, addr, data);2295return bResult;2296}22972298Efuse_PowerSwitch(pAdapter, _TRUE, _TRUE);22992300/* -----------------e-fuse reg ctrl --------------------------------- */2301/* address */230223032304efuseValue = rtw_read32(pAdapter, EFUSE_CTRL);2305efuseValue |= (BIT21 | BIT31);2306efuseValue &= ~(0x3FFFF);2307efuseValue |= ((addr << 8 | data) & 0x3FFFF);23082309/* <20130227, Kordan> 8192E MP chip A-cut had better not set 0x34[11] until B-Cut. */2310if (IS_HARDWARE_TYPE_8723B(pAdapter) ||2311(IS_HARDWARE_TYPE_8192E(pAdapter) && (!IS_A_CUT(pHalData->version_id))) ||2312(IS_VENDOR_8188E_I_CUT_SERIES(pAdapter)) || (IS_CHIP_VENDOR_SMIC(pHalData->version_id))2313) {2314/* <20130121, Kordan> For SMIC EFUSE specificatoin. */2315/* 0x34[11]: SW force PGMEN input of efuse to high. (for the bank selected by 0x34[9:8]) */2316/* phy_set_mac_reg(pAdapter, 0x34, BIT11, 1); */2317rtw_write16(pAdapter, 0x34, rtw_read16(pAdapter, 0x34) | (BIT11));2318rtw_write32(pAdapter, EFUSE_CTRL, 0x90600000 | ((addr << 8 | data)));2319} else2320rtw_write32(pAdapter, EFUSE_CTRL, efuseValue);23212322rtw_mdelay_os(1);23232324while ((0x80 & rtw_read8(pAdapter, EFUSE_CTRL + 3)) && (tmpidx < 100)) {2325rtw_mdelay_os(1);2326tmpidx++;2327}23282329if (tmpidx < 100)2330bResult = _TRUE;2331else {2332bResult = _FALSE;2333RTW_INFO("%s: [ERROR] addr=0x%x ,efuseValue=0x%x ,bResult=%d time out 1s !!!\n",2334__FUNCTION__, addr, efuseValue, bResult);2335RTW_INFO("%s: [ERROR] EFUSE_CTRL =0x%08x !!!\n", __FUNCTION__, rtw_read32(pAdapter, EFUSE_CTRL));2336}23372338/* disable Efuse program enable */2339if (IS_HARDWARE_TYPE_8723B(pAdapter) ||2340(IS_HARDWARE_TYPE_8192E(pAdapter) && (!IS_A_CUT(pHalData->version_id))) ||2341(IS_VENDOR_8188E_I_CUT_SERIES(pAdapter)) || (IS_CHIP_VENDOR_SMIC(pHalData->version_id))2342)2343phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT(11), 0);23442345Efuse_PowerSwitch(pAdapter, _TRUE, _FALSE);23462347return bResult;2348}23492350int2351Efuse_PgPacketRead(PADAPTER pAdapter,2352u8 offset,2353u8 *data,2354BOOLEAN bPseudoTest)2355{2356int ret = 0;23572358ret = pAdapter->hal_func.Efuse_PgPacketRead(pAdapter, offset, data, bPseudoTest);23592360return ret;2361}23622363int2364Efuse_PgPacketWrite(PADAPTER pAdapter,2365u8 offset,2366u8 word_en,2367u8 *data,2368BOOLEAN bPseudoTest)2369{2370int ret;23712372ret = pAdapter->hal_func.Efuse_PgPacketWrite(pAdapter, offset, word_en, data, bPseudoTest);23732374return ret;2375}237623772378int2379Efuse_PgPacketWrite_BT(PADAPTER pAdapter,2380u8 offset,2381u8 word_en,2382u8 *data,2383BOOLEAN bPseudoTest)2384{2385int ret;23862387ret = pAdapter->hal_func.Efuse_PgPacketWrite_BT(pAdapter, offset, word_en, data, bPseudoTest);23882389return ret;2390}239123922393u82394Efuse_WordEnableDataWrite(PADAPTER pAdapter,2395u16 efuse_addr,2396u8 word_en,2397u8 *data,2398BOOLEAN bPseudoTest)2399{2400u8 ret = 0;24012402ret = pAdapter->hal_func.Efuse_WordEnableDataWrite(pAdapter, efuse_addr, word_en, data, bPseudoTest);24032404return ret;2405}24062407static u8 efuse_read8(PADAPTER padapter, u16 address, u8 *value)2408{2409return efuse_OneByteRead(padapter, address, value, _FALSE);2410}24112412static u8 efuse_write8(PADAPTER padapter, u16 address, u8 *value)2413{2414return efuse_OneByteWrite(padapter, address, *value, _FALSE);2415}24162417/*2418* read/wirte raw efuse data2419*/2420u8 rtw_efuse_access(PADAPTER padapter, u8 bWrite, u16 start_addr, u16 cnts, u8 *data)2421{2422int i = 0;2423u16 real_content_len = 0, max_available_size = 0;2424u8 res = _FAIL ;2425u8(*rw8)(PADAPTER, u16, u8 *);2426u32 backupRegs[4] = {0};242724282429EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&real_content_len, _FALSE);2430EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, _FALSE);24312432if (start_addr > real_content_len)2433return _FAIL;24342435if (_TRUE == bWrite) {2436if ((start_addr + cnts) > max_available_size)2437return _FAIL;2438rw8 = &efuse_write8;2439} else2440rw8 = &efuse_read8;24412442efuse_PreUpdateAction(padapter, backupRegs);24432444Efuse_PowerSwitch(padapter, bWrite, _TRUE);24452446/* e-fuse one byte read / write */2447for (i = 0; i < cnts; i++) {2448if (start_addr >= real_content_len) {2449res = _FAIL;2450break;2451}24522453res = rw8(padapter, start_addr++, data++);2454if (_FAIL == res)2455break;2456}24572458Efuse_PowerSwitch(padapter, bWrite, _FALSE);24592460efuse_PostUpdateAction(padapter, backupRegs);24612462return res;2463}2464/* ------------------------------------------------------------------------------ */2465u16 efuse_GetMaxSize(PADAPTER padapter)2466{2467u16 max_size;24682469max_size = 0;2470EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI , TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_size, _FALSE);2471return max_size;2472}2473/* ------------------------------------------------------------------------------ */2474u8 efuse_GetCurrentSize(PADAPTER padapter, u16 *size)2475{2476Efuse_PowerSwitch(padapter, _FALSE, _TRUE);2477*size = Efuse_GetCurrentSize(padapter, EFUSE_WIFI, _FALSE);2478Efuse_PowerSwitch(padapter, _FALSE, _FALSE);24792480return _SUCCESS;2481}2482/* ------------------------------------------------------------------------------ */2483u16 efuse_bt_GetMaxSize(PADAPTER padapter)2484{2485u16 max_size;24862487max_size = 0;2488EFUSE_GetEfuseDefinition(padapter, EFUSE_BT , TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_size, _FALSE);2489return max_size;2490}24912492u8 efuse_bt_GetCurrentSize(PADAPTER padapter, u16 *size)2493{2494Efuse_PowerSwitch(padapter, _FALSE, _TRUE);2495*size = Efuse_GetCurrentSize(padapter, EFUSE_BT, _FALSE);2496Efuse_PowerSwitch(padapter, _FALSE, _FALSE);24972498return _SUCCESS;2499}25002501u8 rtw_efuse_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data)2502{2503u16 mapLen = 0;25042505EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, _FALSE);25062507if ((addr + cnts) > mapLen)2508return _FAIL;25092510Efuse_PowerSwitch(padapter, _FALSE, _TRUE);25112512efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, _FALSE);25132514Efuse_PowerSwitch(padapter, _FALSE, _FALSE);25152516return _SUCCESS;2517}25182519u8 rtw_BT_efuse_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data)2520{2521u16 mapLen = 0;25222523EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, _FALSE);25242525if ((addr + cnts) > mapLen)2526return _FAIL;25272528Efuse_PowerSwitch(padapter, _FALSE, _TRUE);25292530efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data, _FALSE);25312532Efuse_PowerSwitch(padapter, _FALSE, _FALSE);25332534return _SUCCESS;2535}25362537/* ------------------------------------------------------------------------------ */2538u8 rtw_efuse_map_write(PADAPTER padapter, u16 addr, u16 cnts, u8 *data)2539{2540#define RT_ASSERT_RET(expr) \2541if (!(expr)) { \2542printk("Assertion failed! %s at ......\n", #expr); \2543printk(" ......%s,%s, line=%d\n",__FILE__, __FUNCTION__, __LINE__); \2544return _FAIL; \2545}25462547u8 *efuse = NULL;2548u8 offset, word_en;2549u8 *map = NULL;2550u8 newdata[PGPKT_DATA_SIZE];2551s32 i, j, idx, chk_total_byte;2552u8 ret = _SUCCESS;2553u16 mapLen = 0, startAddr = 0, efuse_max_available_len = 0;2554u32 backupRegs[4] = {0};2555HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);2556PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;255725582559EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, _FALSE);2560EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &efuse_max_available_len, _FALSE);25612562if ((addr + cnts) > mapLen)2563return _FAIL;25642565RT_ASSERT_RET(PGPKT_DATA_SIZE == 8); /* have to be 8 byte alignment */2566RT_ASSERT_RET((mapLen & 0x7) == 0); /* have to be PGPKT_DATA_SIZE alignment for memcpy */25672568efuse = rtw_zmalloc(mapLen);2569if (!efuse)2570return _FAIL;25712572map = rtw_zmalloc(mapLen);2573if (map == NULL) {2574rtw_mfree(efuse, mapLen);2575return _FAIL;2576}25772578_rtw_memset(map, 0xFF, mapLen);25792580ret = rtw_efuse_map_read(padapter, 0, mapLen, map);2581if (ret == _FAIL)2582goto exit;25832584_rtw_memcpy(efuse , map, mapLen);2585_rtw_memcpy(efuse + addr, data, cnts);25862587if (padapter->registrypriv.boffefusemask == 0) {2588for (i = 0; i < cnts; i++) {2589if (padapter->registrypriv.bFileMaskEfuse == _TRUE) {2590if (rtw_file_efuse_IsMasked(padapter, addr + i, maskfileBuffer)) /*use file efuse mask. */2591efuse[addr + i] = map[addr + i];2592} else {2593if (efuse_IsMasked(padapter, addr + i))2594efuse[addr + i] = map[addr + i];2595}2596RTW_INFO("%s , data[%d] = %x, map[addr+i]= %x\n", __func__, addr + i, efuse[ addr + i], map[addr + i]);2597}2598}2599/*Efuse_PowerSwitch(padapter, _TRUE, _TRUE);*/26002601chk_total_byte = 0;2602idx = 0;2603offset = (addr >> 3);26042605while (idx < cnts) {2606word_en = 0xF;2607j = (addr + idx) & 0x7;2608for (i = j; i < PGPKT_DATA_SIZE && idx < cnts; i++, idx++) {2609if (efuse[addr + idx] != map[addr + idx])2610word_en &= ~BIT(i >> 1);2611}26122613if (word_en != 0xF) {2614chk_total_byte += Efuse_CalculateWordCnts(word_en) * 2;26152616if (offset >= EFUSE_MAX_SECTION_BASE) /* Over EFUSE_MAX_SECTION 16 for 2 ByteHeader */2617chk_total_byte += 2;2618else2619chk_total_byte += 1;2620}26212622offset++;2623}26242625RTW_INFO("Total PG bytes Count = %d\n", chk_total_byte);2626rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8 *)&startAddr);26272628if (startAddr == 0) {2629startAddr = Efuse_GetCurrentSize(padapter, EFUSE_WIFI, _FALSE);2630RTW_INFO("%s: Efuse_GetCurrentSize startAddr=%#X\n", __func__, startAddr);2631}2632RTW_DBG("%s: startAddr=%#X\n", __func__, startAddr);26332634if ((startAddr + chk_total_byte) >= efuse_max_available_len) {2635RTW_INFO("%s: startAddr(0x%X) + PG data len %d >= efuse_max_available_len(0x%X)\n",2636__func__, startAddr, chk_total_byte, efuse_max_available_len);2637ret = _FAIL;2638goto exit;2639}26402641efuse_PreUpdateAction(padapter, backupRegs);26422643idx = 0;2644offset = (addr >> 3);2645while (idx < cnts) {2646word_en = 0xF;2647j = (addr + idx) & 0x7;2648_rtw_memcpy(newdata, &map[offset << 3], PGPKT_DATA_SIZE);2649for (i = j; i < PGPKT_DATA_SIZE && idx < cnts; i++, idx++) {2650if (efuse[addr + idx] != map[addr + idx]) {2651word_en &= ~BIT(i >> 1);2652newdata[i] = efuse[addr + idx];2653#ifdef CONFIG_RTL8723B2654if (addr + idx == 0x8) {2655if (IS_C_CUT(pHalData->version_id) || IS_B_CUT(pHalData->version_id)) {2656if (pHalData->adjuseVoltageVal == 6) {2657newdata[i] = map[addr + idx];2658RTW_INFO(" %s ,\n adjuseVoltageVal = %d ,newdata[%d] = %x\n", __func__, pHalData->adjuseVoltageVal, i, newdata[i]);2659}2660}2661}2662#endif2663}2664}26652666if (word_en != 0xF) {2667ret = Efuse_PgPacketWrite(padapter, offset, word_en, newdata, _FALSE);2668RTW_INFO("offset=%x\n", offset);2669RTW_INFO("word_en=%x\n", word_en);26702671for (i = 0; i < PGPKT_DATA_SIZE; i++)2672RTW_INFO("data=%x \t", newdata[i]);2673if (ret == _FAIL)2674break;2675}26762677offset++;2678}26792680/*Efuse_PowerSwitch(padapter, _TRUE, _FALSE);*/26812682efuse_PostUpdateAction(padapter, backupRegs);26832684exit:26852686rtw_mfree(map, mapLen);2687rtw_mfree(efuse, mapLen);26882689return ret;2690}269126922693u8 rtw_BT_efuse_map_write(PADAPTER padapter, u16 addr, u16 cnts, u8 *data)2694{2695#define RT_ASSERT_RET(expr) \2696if (!(expr)) { \2697printk("Assertion failed! %s at ......\n", #expr); \2698printk(" ......%s,%s, line=%d\n",__FILE__, __FUNCTION__, __LINE__); \2699return _FAIL; \2700}27012702u8 offset, word_en;2703u8 *map;2704u8 newdata[PGPKT_DATA_SIZE];2705s32 i = 0, j = 0, idx;2706u8 ret = _SUCCESS;2707u16 mapLen = 0;27082709EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, _FALSE);27102711if ((addr + cnts) > mapLen)2712return _FAIL;27132714RT_ASSERT_RET(PGPKT_DATA_SIZE == 8); /* have to be 8 byte alignment */2715RT_ASSERT_RET((mapLen & 0x7) == 0); /* have to be PGPKT_DATA_SIZE alignment for memcpy */27162717map = rtw_zmalloc(mapLen);2718if (map == NULL)2719return _FAIL;27202721ret = rtw_BT_efuse_map_read(padapter, 0, mapLen, map);2722if (ret == _FAIL)2723goto exit;2724RTW_INFO("OFFSET\tVALUE(hex)\n");2725for (i = 0; i < 1024; i += 16) { /* set 512 because the iwpriv's extra size have limit 0x7FF */2726RTW_INFO("0x%03x\t", i);2727for (j = 0; j < 8; j++)2728RTW_INFO("%02X ", map[i + j]);2729RTW_INFO("\t");2730for (; j < 16; j++)2731RTW_INFO("%02X ", map[i + j]);2732RTW_INFO("\n");2733}2734RTW_INFO("\n");2735Efuse_PowerSwitch(padapter, _TRUE, _TRUE);27362737idx = 0;2738offset = (addr >> 3);2739while (idx < cnts) {2740word_en = 0xF;2741j = (addr + idx) & 0x7;2742_rtw_memcpy(newdata, &map[offset << 3], PGPKT_DATA_SIZE);2743for (i = j; i < PGPKT_DATA_SIZE && idx < cnts; i++, idx++) {2744if (data[idx] != map[addr + idx]) {2745word_en &= ~BIT(i >> 1);2746newdata[i] = data[idx];2747}2748}27492750if (word_en != 0xF) {2751RTW_INFO("offset=%x\n", offset);2752RTW_INFO("word_en=%x\n", word_en);2753RTW_INFO("%s: data=", __FUNCTION__);2754for (i = 0; i < PGPKT_DATA_SIZE; i++)2755RTW_INFO("0x%02X ", newdata[i]);2756RTW_INFO("\n");2757ret = Efuse_PgPacketWrite_BT(padapter, offset, word_en, newdata, _FALSE);2758if (ret == _FAIL)2759break;2760}27612762offset++;2763}27642765Efuse_PowerSwitch(padapter, _TRUE, _FALSE);27662767exit:27682769rtw_mfree(map, mapLen);27702771return ret;2772}27732774/*-----------------------------------------------------------------------------2775* Function: Efuse_ReadAllMap2776*2777* Overview: Read All Efuse content2778*2779* Input: NONE2780*2781* Output: NONE2782*2783* Return: NONE2784*2785* Revised History:2786* When Who Remark2787* 11/11/2008 MHC Create Version 0.2788*2789*---------------------------------------------------------------------------*/2790void2791Efuse_ReadAllMap(2792PADAPTER pAdapter,2793u8 efuseType,2794u8 *Efuse,2795BOOLEAN bPseudoTest);2796void2797Efuse_ReadAllMap(2798PADAPTER pAdapter,2799u8 efuseType,2800u8 *Efuse,2801BOOLEAN bPseudoTest)2802{2803u16 mapLen = 0;28042805Efuse_PowerSwitch(pAdapter, _FALSE, _TRUE);28062807EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, bPseudoTest);28082809efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse, bPseudoTest);28102811Efuse_PowerSwitch(pAdapter, _FALSE, _FALSE);2812}28132814/*-----------------------------------------------------------------------------2815* Function: efuse_ShadowWrite1Byte2816* efuse_ShadowWrite2Byte2817* efuse_ShadowWrite4Byte2818*2819* Overview: Write efuse modify map by one/two/four byte.2820*2821* Input: NONE2822*2823* Output: NONE2824*2825* Return: NONE2826*2827* Revised History:2828* When Who Remark2829* 11/12/2008 MHC Create Version 0.2830*2831*---------------------------------------------------------------------------*/2832#ifdef PLATFORM2833static void2834efuse_ShadowWrite1Byte(2835PADAPTER pAdapter,2836u16 Offset,2837u8 Value);2838#endif /* PLATFORM */2839static void2840efuse_ShadowWrite1Byte(2841PADAPTER pAdapter,2842u16 Offset,2843u8 Value)2844{2845PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);28462847pHalData->efuse_eeprom_data[Offset] = Value;28482849} /* efuse_ShadowWrite1Byte */28502851/* ---------------Write Two Bytes */2852static void2853efuse_ShadowWrite2Byte(2854PADAPTER pAdapter,2855u16 Offset,2856u16 Value)2857{28582859PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);286028612862pHalData->efuse_eeprom_data[Offset] = Value & 0x00FF;2863pHalData->efuse_eeprom_data[Offset + 1] = Value >> 8;28642865} /* efuse_ShadowWrite1Byte */28662867/* ---------------Write Four Bytes */2868static void2869efuse_ShadowWrite4Byte(2870PADAPTER pAdapter,2871u16 Offset,2872u32 Value)2873{2874PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);28752876pHalData->efuse_eeprom_data[Offset] = (u8)(Value & 0x000000FF);2877pHalData->efuse_eeprom_data[Offset + 1] = (u8)((Value >> 8) & 0x0000FF);2878pHalData->efuse_eeprom_data[Offset + 2] = (u8)((Value >> 16) & 0x00FF);2879pHalData->efuse_eeprom_data[Offset + 3] = (u8)((Value >> 24) & 0xFF);28802881} /* efuse_ShadowWrite1Byte */288228832884/*-----------------------------------------------------------------------------2885* Function: EFUSE_ShadowWrite2886*2887* Overview: Write efuse modify map for later update operation to use!!!!!2888*2889* Input: NONE2890*2891* Output: NONE2892*2893* Return: NONE2894*2895* Revised History:2896* When Who Remark2897* 11/12/2008 MHC Create Version 0.2898*2899*---------------------------------------------------------------------------*/2900void2901EFUSE_ShadowWrite(2902PADAPTER pAdapter,2903u8 Type,2904u16 Offset,2905u32 Value);2906void2907EFUSE_ShadowWrite(2908PADAPTER pAdapter,2909u8 Type,2910u16 Offset,2911u32 Value)2912{2913#if (MP_DRIVER == 0)2914return;2915#endif2916if (pAdapter->registrypriv.mp_mode == 0)2917return;291829192920if (Type == 1)2921efuse_ShadowWrite1Byte(pAdapter, Offset, (u8)Value);2922else if (Type == 2)2923efuse_ShadowWrite2Byte(pAdapter, Offset, (u16)Value);2924else if (Type == 4)2925efuse_ShadowWrite4Byte(pAdapter, Offset, (u32)Value);29262927} /* EFUSE_ShadowWrite */29282929#endif /* !RTW_HALMAC */2930/*-----------------------------------------------------------------------------2931* Function: efuse_ShadowRead1Byte2932* efuse_ShadowRead2Byte2933* efuse_ShadowRead4Byte2934*2935* Overview: Read from efuse init map by one/two/four bytes !!!!!2936*2937* Input: NONE2938*2939* Output: NONE2940*2941* Return: NONE2942*2943* Revised History:2944* When Who Remark2945* 11/12/2008 MHC Create Version 0.2946*2947*---------------------------------------------------------------------------*/2948static void2949efuse_ShadowRead1Byte(2950PADAPTER pAdapter,2951u16 Offset,2952u8 *Value)2953{2954PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);29552956*Value = pHalData->efuse_eeprom_data[Offset];29572958} /* EFUSE_ShadowRead1Byte */29592960/* ---------------Read Two Bytes */2961static void2962efuse_ShadowRead2Byte(2963PADAPTER pAdapter,2964u16 Offset,2965u16 *Value)2966{2967PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);29682969*Value = pHalData->efuse_eeprom_data[Offset];2970*Value |= pHalData->efuse_eeprom_data[Offset + 1] << 8;29712972} /* EFUSE_ShadowRead2Byte */29732974/* ---------------Read Four Bytes */2975static void2976efuse_ShadowRead4Byte(2977PADAPTER pAdapter,2978u16 Offset,2979u32 *Value)2980{2981PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);29822983*Value = pHalData->efuse_eeprom_data[Offset];2984*Value |= pHalData->efuse_eeprom_data[Offset + 1] << 8;2985*Value |= pHalData->efuse_eeprom_data[Offset + 2] << 16;2986*Value |= pHalData->efuse_eeprom_data[Offset + 3] << 24;29872988} /* efuse_ShadowRead4Byte */29892990/*-----------------------------------------------------------------------------2991* Function: EFUSE_ShadowRead2992*2993* Overview: Read from pHalData->efuse_eeprom_data2994*---------------------------------------------------------------------------*/2995void2996EFUSE_ShadowRead(2997PADAPTER pAdapter,2998u8 Type,2999u16 Offset,3000u32 *Value)3001{3002if (Type == 1)3003efuse_ShadowRead1Byte(pAdapter, Offset, (u8 *)Value);3004else if (Type == 2)3005efuse_ShadowRead2Byte(pAdapter, Offset, (u16 *)Value);3006else if (Type == 4)3007efuse_ShadowRead4Byte(pAdapter, Offset, (u32 *)Value);30083009} /* EFUSE_ShadowRead */30103011/* 11/16/2008 MH Add description. Get current efuse area enabled word!!. */3012u83013Efuse_CalculateWordCnts(u8 word_en)3014{3015u8 word_cnts = 0;3016if (!(word_en & BIT(0)))3017word_cnts++; /* 0 : write enable */3018if (!(word_en & BIT(1)))3019word_cnts++;3020if (!(word_en & BIT(2)))3021word_cnts++;3022if (!(word_en & BIT(3)))3023word_cnts++;3024return word_cnts;3025}30263027/*-----------------------------------------------------------------------------3028* Function: efuse_WordEnableDataRead3029*3030* Overview: Read allowed word in current efuse section data.3031*3032* Input: NONE3033*3034* Output: NONE3035*3036* Return: NONE3037*3038* Revised History:3039* When Who Remark3040* 11/16/2008 MHC Create Version 0.3041* 11/21/2008 MHC Fix Write bug when we only enable late word.3042*3043*---------------------------------------------------------------------------*/3044void3045efuse_WordEnableDataRead(u8 word_en,3046u8 *sourdata,3047u8 *targetdata)3048{3049if (!(word_en & BIT(0))) {3050targetdata[0] = sourdata[0];3051targetdata[1] = sourdata[1];3052}3053if (!(word_en & BIT(1))) {3054targetdata[2] = sourdata[2];3055targetdata[3] = sourdata[3];3056}3057if (!(word_en & BIT(2))) {3058targetdata[4] = sourdata[4];3059targetdata[5] = sourdata[5];3060}3061if (!(word_en & BIT(3))) {3062targetdata[6] = sourdata[6];3063targetdata[7] = sourdata[7];3064}3065}30663067/*-----------------------------------------------------------------------------3068* Function: EFUSE_ShadowMapUpdate3069*3070* Overview: Transfer current EFUSE content to shadow init and modify map.3071*3072* Input: NONE3073*3074* Output: NONE3075*3076* Return: NONE3077*3078* Revised History:3079* When Who Remark3080* 11/13/2008 MHC Create Version 0.3081*3082*---------------------------------------------------------------------------*/3083void EFUSE_ShadowMapUpdate(3084PADAPTER pAdapter,3085u8 efuseType,3086BOOLEAN bPseudoTest)3087{3088PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);3089u16 mapLen = 0;3090#ifdef RTW_HALMAC3091u8 *efuse_map = NULL;3092int err;309330943095mapLen = EEPROM_MAX_SIZE;3096efuse_map = pHalData->efuse_eeprom_data;3097/* efuse default content is 0xFF */3098_rtw_memset(efuse_map, 0xFF, EEPROM_MAX_SIZE);30993100EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, bPseudoTest);3101if (!mapLen) {3102RTW_WARN("%s: <ERROR> fail to get efuse size!\n", __FUNCTION__);3103mapLen = EEPROM_MAX_SIZE;3104}3105if (mapLen > EEPROM_MAX_SIZE) {3106RTW_WARN("%s: <ERROR> size of efuse data(%d) is large than expected(%d)!\n",3107__FUNCTION__, mapLen, EEPROM_MAX_SIZE);3108mapLen = EEPROM_MAX_SIZE;3109}31103111if (pHalData->bautoload_fail_flag == _FALSE) {3112err = rtw_halmac_read_logical_efuse_map(adapter_to_dvobj(pAdapter), efuse_map, mapLen, NULL, 0);3113if (err)3114RTW_ERR("%s: <ERROR> fail to get efuse map!\n", __FUNCTION__);3115}3116#else /* !RTW_HALMAC */3117EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, bPseudoTest);31183119if (pHalData->bautoload_fail_flag == _TRUE)3120_rtw_memset(pHalData->efuse_eeprom_data, 0xFF, mapLen);3121else {3122#ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE3123if (_SUCCESS != retriveAdaptorInfoFile(pAdapter->registrypriv.adaptor_info_caching_file_path, pHalData->efuse_eeprom_data)) {3124#endif31253126Efuse_ReadAllMap(pAdapter, efuseType, pHalData->efuse_eeprom_data, bPseudoTest);31273128#ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE3129storeAdaptorInfoFile(pAdapter->registrypriv.adaptor_info_caching_file_path, pHalData->efuse_eeprom_data);3130}3131#endif3132}31333134/* PlatformMoveMemory((void *)&pHalData->EfuseMap[EFUSE_MODIFY_MAP][0], */3135/* (void *)&pHalData->EfuseMap[EFUSE_INIT_MAP][0], mapLen); */3136#endif /* !RTW_HALMAC */31373138rtw_mask_map_read(pAdapter, 0x00, mapLen, pHalData->efuse_eeprom_data);31393140rtw_dump_cur_efuse(pAdapter);3141} /* EFUSE_ShadowMapUpdate */31423143const u8 _mac_hidden_max_bw_to_hal_bw_cap[MAC_HIDDEN_MAX_BW_NUM] = {31440,31450,3146(BW_CAP_160M | BW_CAP_80M | BW_CAP_40M | BW_CAP_20M | BW_CAP_10M | BW_CAP_5M),3147(BW_CAP_5M),3148(BW_CAP_10M | BW_CAP_5M),3149(BW_CAP_20M | BW_CAP_10M | BW_CAP_5M),3150(BW_CAP_40M | BW_CAP_20M | BW_CAP_10M | BW_CAP_5M),3151(BW_CAP_80M | BW_CAP_40M | BW_CAP_20M | BW_CAP_10M | BW_CAP_5M),3152};31533154const u8 _mac_hidden_proto_to_hal_proto_cap[MAC_HIDDEN_PROTOCOL_NUM] = {31550,31560,3157(PROTO_CAP_11N | PROTO_CAP_11G | PROTO_CAP_11B),3158(PROTO_CAP_11AC | PROTO_CAP_11N | PROTO_CAP_11G | PROTO_CAP_11B),3159};31603161u8 mac_hidden_wl_func_to_hal_wl_func(u8 func)3162{3163u8 wl_func = 0;31643165if (func & BIT0)3166wl_func |= WL_FUNC_MIRACAST;3167if (func & BIT1)3168wl_func |= WL_FUNC_P2P;3169if (func & BIT2)3170wl_func |= WL_FUNC_TDLS;3171if (func & BIT3)3172wl_func |= WL_FUNC_FTM;31733174return wl_func;3175}31763177#ifdef PLATFORM_LINUX3178#ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE3179/* #include <rtw_eeprom.h> */31803181int isAdaptorInfoFileValid(void)3182{3183return _TRUE;3184}31853186int storeAdaptorInfoFile(char *path, u8 *efuse_data)3187{3188int ret = _SUCCESS;31893190if (path && efuse_data) {3191ret = rtw_store_to_file(path, efuse_data, EEPROM_MAX_SIZE_512);3192if (ret == EEPROM_MAX_SIZE)3193ret = _SUCCESS;3194else3195ret = _FAIL;3196} else {3197RTW_INFO("%s NULL pointer\n", __FUNCTION__);3198ret = _FAIL;3199}3200return ret;3201}32023203int retriveAdaptorInfoFile(char *path, u8 *efuse_data)3204{3205int ret = _SUCCESS;3206mm_segment_t oldfs;3207struct file *fp;32083209if (path && efuse_data) {32103211ret = rtw_retrieve_from_file(path, efuse_data, EEPROM_MAX_SIZE);32123213if (ret == EEPROM_MAX_SIZE)3214ret = _SUCCESS;3215else3216ret = _FAIL;32173218#if 03219if (isAdaptorInfoFileValid())3220return 0;3221else3222return _FAIL;3223#endif32243225} else {3226RTW_INFO("%s NULL pointer\n", __FUNCTION__);3227ret = _FAIL;3228}3229return ret;3230}3231#endif /* CONFIG_ADAPTOR_INFO_CACHING_FILE */32323233u8 rtw_efuse_file_read(PADAPTER padapter, u8 *filepatch, u8 *buf, u32 len)3234{3235char *ptmpbuf = NULL, *ptr;3236u8 val8;3237u32 count, i, j;3238int err;3239u32 bufsize = 4096;32403241ptmpbuf = rtw_zmalloc(bufsize);3242if (ptmpbuf == NULL)3243return _FALSE;32443245count = rtw_retrieve_from_file(filepatch, ptmpbuf, bufsize);3246if (count <= 90) {3247rtw_mfree(ptmpbuf, bufsize);3248RTW_ERR("%s, filepatch %s, size=%d, FAIL!!\n", __FUNCTION__, filepatch, count);3249return _FALSE;3250}3251i = 0;3252j = 0;3253ptr = ptmpbuf;3254while ((j < len) && (i < count)) {3255if (ptmpbuf[i] == '\0')3256break;32573258ptr = strpbrk(&ptmpbuf[i], " \t\n\r");3259if (ptr) {3260if (ptr == &ptmpbuf[i]) {3261i++;3262continue;3263}3264/* Add string terminating null */3265*ptr = 0;3266} else {3267ptr = &ptmpbuf[count-1];3268}32693270err = sscanf(&ptmpbuf[i], "%hhx", &val8);3271if (err != 1) {3272RTW_WARN("Something wrong to parse efuse file, string=%s\n", &ptmpbuf[i]);3273} else {3274buf[j] = val8;3275RTW_DBG("i=%d, j=%d, 0x%02x\n", i, j, buf[j]);3276j++;3277}3278i = ptr - ptmpbuf + 1;3279}3280rtw_mfree(ptmpbuf, bufsize);3281RTW_INFO("%s, filepatch %s, size=%d, done\n", __FUNCTION__, filepatch, count);3282return _TRUE;3283}32843285#ifdef CONFIG_EFUSE_CONFIG_FILE3286u32 rtw_read_efuse_from_file(const char *path, u8 *buf, int map_size)3287{3288u32 i;3289u8 c;3290u8 temp[3];3291u8 temp_i;3292u8 end = _FALSE;3293u32 ret = _FAIL;32943295u8 *file_data = NULL;3296u32 file_size, read_size, pos = 0;3297u8 *map = NULL;32983299if (rtw_is_file_readable_with_size(path, &file_size) != _TRUE) {3300RTW_PRINT("%s %s is not readable\n", __func__, path);3301goto exit;3302}33033304file_data = rtw_vmalloc(file_size);3305if (!file_data) {3306RTW_ERR("%s rtw_vmalloc(%d) fail\n", __func__, file_size);3307goto exit;3308}33093310read_size = rtw_retrieve_from_file(path, file_data, file_size);3311if (read_size == 0) {3312RTW_ERR("%s read from %s fail\n", __func__, path);3313goto exit;3314}33153316map = rtw_vmalloc(map_size);3317if (!map) {3318RTW_ERR("%s rtw_vmalloc(%d) fail\n", __func__, map_size);3319goto exit;3320}3321_rtw_memset(map, 0xff, map_size);33223323temp[2] = 0; /* end of string '\0' */33243325for (i = 0 ; i < map_size ; i++) {3326temp_i = 0;33273328while (1) {3329if (pos >= read_size) {3330end = _TRUE;3331break;3332}3333c = file_data[pos++];33343335/* bypass spece or eol or null before first hex digit */3336if (temp_i == 0 && (is_eol(c) == _TRUE || is_space(c) == _TRUE || is_null(c) == _TRUE))3337continue;33383339if (IsHexDigit(c) == _FALSE) {3340RTW_ERR("%s invalid 8-bit hex format for offset:0x%03x\n", __func__, i);3341goto exit;3342}33433344temp[temp_i++] = c;33453346if (temp_i == 2) {3347/* parse value */3348if (sscanf(temp, "%hhx", &map[i]) != 1) {3349RTW_ERR("%s sscanf fail for offset:0x%03x\n", __func__, i);3350goto exit;3351}3352break;3353}3354}33553356if (end == _TRUE) {3357if (temp_i != 0) {3358RTW_ERR("%s incomplete 8-bit hex format for offset:0x%03x\n", __func__, i);3359goto exit;3360}3361break;3362}3363}33643365RTW_PRINT("efuse file:%s, 0x%03x byte content read\n", path, i);33663367_rtw_memcpy(buf, map, map_size);33683369ret = _SUCCESS;33703371exit:3372if (file_data)3373rtw_vmfree(file_data, file_size);3374if (map)3375rtw_vmfree(map, map_size);33763377return ret;3378}33793380u32 rtw_read_macaddr_from_file(const char *path, u8 *buf)3381{3382u32 i;3383u8 temp[3];3384u32 ret = _FAIL;33853386u8 file_data[17];3387u32 read_size;3388u8 addr[ETH_ALEN];33893390if (rtw_is_file_readable(path) != _TRUE) {3391RTW_PRINT("%s %s is not readable\n", __func__, path);3392goto exit;3393}33943395read_size = rtw_retrieve_from_file(path, file_data, 17);3396if (read_size != 17) {3397RTW_ERR("%s read from %s fail\n", __func__, path);3398goto exit;3399}34003401temp[2] = 0; /* end of string '\0' */34023403for (i = 0 ; i < ETH_ALEN ; i++) {3404if (IsHexDigit(file_data[i * 3]) == _FALSE || IsHexDigit(file_data[i * 3 + 1]) == _FALSE) {3405RTW_ERR("%s invalid 8-bit hex format for address offset:%u\n", __func__, i);3406goto exit;3407}34083409if (i < ETH_ALEN - 1 && file_data[i * 3 + 2] != ':') {3410RTW_ERR("%s invalid separator after address offset:%u\n", __func__, i);3411goto exit;3412}34133414temp[0] = file_data[i * 3];3415temp[1] = file_data[i * 3 + 1];3416if (sscanf(temp, "%hhx", &addr[i]) != 1) {3417RTW_ERR("%s sscanf fail for address offset:0x%03x\n", __func__, i);3418goto exit;3419}3420}34213422_rtw_memcpy(buf, addr, ETH_ALEN);34233424RTW_PRINT("wifi_mac file: %s\n", path);3425#ifdef CONFIG_RTW_DEBUG3426RTW_INFO(MAC_FMT"\n", MAC_ARG(buf));3427#endif34283429ret = _SUCCESS;34303431exit:3432return ret;3433}3434#endif /* CONFIG_EFUSE_CONFIG_FILE */34353436#endif /* PLATFORM_LINUX */343734383439