Skip to content
Permalink
Browse files
staging: r8188eu: add error handling of rtw_read8
_rtw_read8 function can fail in case of usb transfer failure. But
previous function prototype wasn't designed to return an error to
caller. It can cause a lot uninit value bugs all across the driver code,
since rtw_read8() returns local stack variable to caller.

Fix it by changing the prototype of this function. Now it returns an
int: 0 on success, negative error value on failure and callers should pass
the pointer to storage location for register value.

Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
  • Loading branch information
pskrgag authored and intel-lab-lkp committed Aug 22, 2021
1 parent e539100 commit 2b557bc2dab8449fa9bb37a8a4c36b0714b007f7
Show file tree
Hide file tree
Showing 20 changed files with 569 additions and 158 deletions.
@@ -73,8 +73,8 @@ int proc_get_read_reg(char *page, char **start,
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);

int len = 0;
u32 tmp;
int len = 0, error;

if (proc_get_read_addr == 0xeeeeeeee) {
*eof = 1;
@@ -83,7 +83,12 @@ int proc_get_read_reg(char *page, char **start,

switch (proc_get_read_len) {
case 1:
len += snprintf(page + len, count - len, "rtw_read8(0x%x)=0x%x\n", proc_get_read_addr, rtw_read8(padapter, proc_get_read_addr));
error = rtw_read8(padapter, proc_get_read_addr, (u8 *) &tmp);
if (error)
return len;

len += snprintf(page + len, count - len, "rtw_read8(0x%x)=0x%x\n",
proc_get_read_addr, (u8) tmp);
break;
case 2:
len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n", proc_get_read_addr, rtw_read16(padapter, proc_get_read_addr));
@@ -159,6 +159,7 @@ ReadEFuseByte(
u32 value32;
u8 readbyte;
u16 retry;
int error;

if (pseudo) {
Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf);
@@ -167,11 +168,17 @@ ReadEFuseByte(

/* Write Address */
rtw_write8(Adapter, EFUSE_CTRL + 1, (_offset & 0xff));
readbyte = rtw_read8(Adapter, EFUSE_CTRL + 2);
error = rtw_read8(Adapter, EFUSE_CTRL + 2, &readbyte);
if (error)
return;

rtw_write8(Adapter, EFUSE_CTRL + 2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));

/* Write bit 32 0 */
readbyte = rtw_read8(Adapter, EFUSE_CTRL + 3);
error = rtw_read8(Adapter, EFUSE_CTRL + 3, &readbyte);
if (error)
return;

rtw_write8(Adapter, EFUSE_CTRL + 3, (readbyte & 0x7f));

/* Check bit 32 read-ready */
@@ -244,34 +251,50 @@ u8 EFUSE_Read1Byte(struct adapter *Adapter, u16 Address)
u8 temp = {0x00};
u32 k = 0;
u16 contentLen = 0;
int error;

EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&contentLen, false);

if (Address < contentLen) { /* E-fuse 512Byte */
/* Write E-fuse Register address bit0~7 */
temp = Address & 0xFF;
rtw_write8(Adapter, EFUSE_CTRL + 1, temp);
Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 2);
error = rtw_read8(Adapter, EFUSE_CTRL + 2, &Bytetemp);
if (error)
return 0xFF;

/* Write E-fuse Register address bit8~9 */
temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
rtw_write8(Adapter, EFUSE_CTRL + 2, temp);

/* Write 0x30[31]= 0 */
Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3);
error = rtw_read8(Adapter, EFUSE_CTRL + 3, &Bytetemp);
if (error)
return 0xFF;

temp = Bytetemp & 0x7F;
rtw_write8(Adapter, EFUSE_CTRL + 3, temp);

/* Wait Write-ready (0x30[31]= 1) */
Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3);
error = rtw_read8(Adapter, EFUSE_CTRL + 3, &Bytetemp);
if (error)
return 0xFF;

while (!(Bytetemp & 0x80)) {
Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3);
error = rtw_read8(Adapter, EFUSE_CTRL + 3, &Bytetemp);
if (error)
return 0xFF;

k++;
if (k == 1000) {
k = 0;
break;
}
}
data = rtw_read8(Adapter, EFUSE_CTRL);
error = rtw_read8(Adapter, EFUSE_CTRL, &data);
if (error)
return 0xFF;

return data;
} else {
return 0xFF;
@@ -284,6 +307,8 @@ u8 efuse_OneByteRead(struct adapter *pAdapter, u16 addr, u8 *data, bool pseudo)
{
u8 tmpidx = 0;
u8 result;
u8 tmp;
int error;

if (pseudo) {
result = Efuse_Read1ByteFromFakeContent(pAdapter, addr, data);
@@ -292,16 +317,25 @@ u8 efuse_OneByteRead(struct adapter *pAdapter, u16 addr, u8 *data, bool pseudo)
/* -----------------e-fuse reg ctrl --------------------------------- */
/* address */
rtw_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff));
rtw_write8(pAdapter, EFUSE_CTRL + 2, ((u8)((addr >> 8) & 0x03)) |
(rtw_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC));
error = rtw_read8(pAdapter, EFUSE_CTRL + 2, &tmp);
if (error)
return false;

rtw_write8(pAdapter, EFUSE_CTRL + 2, ((u8)((addr >> 8) & 0x03)) | (tmp & 0xFC));
rtw_write8(pAdapter, EFUSE_CTRL + 3, 0x72);/* read cmd */

while (!(0x80 & rtw_read8(pAdapter, EFUSE_CTRL + 3)) && (tmpidx < 100))
tmpidx++;
do {
error = rtw_read8(pAdapter, EFUSE_CTRL + 3, &tmp);
if (error)
return false;
} while (!(0x80 & tmp) && (++tmpidx < 100));

if (tmpidx < 100) {
*data = rtw_read8(pAdapter, EFUSE_CTRL);
result = true;
error = rtw_read8(pAdapter, EFUSE_CTRL, data);
if (error)
result = false;
else
result = true;
} else {
*data = 0xff;
result = false;
@@ -314,6 +348,8 @@ u8 efuse_OneByteWrite(struct adapter *pAdapter, u16 addr, u8 data, bool pseudo)
{
u8 tmpidx = 0;
u8 result;
u8 tmp;
int error;

if (pseudo) {
result = Efuse_Write1ByteToFakeContent(pAdapter, addr, data);
@@ -323,15 +359,23 @@ u8 efuse_OneByteWrite(struct adapter *pAdapter, u16 addr, u8 data, bool pseudo)
/* -----------------e-fuse reg ctrl --------------------------------- */
/* address */
rtw_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff));

error = rtw_read8(pAdapter, EFUSE_CTRL + 2, &tmp);
if (error)
return false;

rtw_write8(pAdapter, EFUSE_CTRL + 2,
(rtw_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC) |
(tmp & 0xFC) |
(u8)((addr >> 8) & 0x03));
rtw_write8(pAdapter, EFUSE_CTRL, data);/* data */

rtw_write8(pAdapter, EFUSE_CTRL + 3, 0xF2);/* write cmd */

while ((0x80 & rtw_read8(pAdapter, EFUSE_CTRL + 3)) && (tmpidx < 100))
tmpidx++;
do {
error = rtw_read8(pAdapter, EFUSE_CTRL + 3, &tmp);
if (error)
return false;
} while (!(0x80 & tmp) && (++tmpidx < 100));

if (tmpidx < 100)
result = true;
@@ -34,18 +34,15 @@ jackson@realtek.com.tw
#define rtw_cpu_to_le16(val) cpu_to_le16(val)
#define rtw_cpu_to_le32(val) cpu_to_le32(val)

u8 _rtw_read8(struct adapter *adapter, u32 addr)
int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data)
{
u8 r_val;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &pio_priv->intf;
u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr);

int (*_read8)(struct intf_hdl *pintfhdl, u32 addr, u8 *data);

_read8 = pintfhdl->io_ops._read8;
r_val = _read8(pintfhdl, addr);

return r_val;
return _read8(pintfhdl, addr, data);
}

u16 _rtw_read16(struct adapter *adapter, u32 addr)
@@ -243,10 +243,14 @@ void GetPowerTracking(struct adapter *padapter, u8 *enable)
static void disable_dm(struct adapter *padapter)
{
u8 v8;
int error;

/* 3 1. disable firmware dynamic mechanism */
/* disable Power Training, Rate Adaptive */
v8 = rtw_read8(padapter, REG_BCN_CTRL);
error = rtw_read8(padapter, REG_BCN_CTRL, &v8);
if (error)
return;

v8 &= ~EN_BCN_FUNCTION;
rtw_write8(padapter, REG_BCN_CTRL, v8);

@@ -363,8 +367,13 @@ s32 mp_start_test(struct adapter *padapter)
spin_unlock_bh(&pmlmepriv->lock);

if (res == _SUCCESS) {
int error;
/* set MSR to WIFI_FW_ADHOC_STATE */
val8 = rtw_read8(padapter, MSR) & 0xFC; /* 0x0102 */
error = rtw_read8(padapter, MSR, &val8); /* 0x0102 */
if (error)
return _FAIL;

val8 &= 0xFC;
val8 |= WIFI_FW_ADHOC_STATE;
rtw_write8(padapter, MSR, val8); /* Link in ad hoc network */
}
@@ -632,6 +632,7 @@ int rtl8188eu_oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv)
u32 offset, width;
int status = NDIS_STATUS_SUCCESS;
struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
int error;

if (poid_par_priv->type_of_oid != QUERY_OID)
return NDIS_STATUS_NOT_ACCEPTED;
@@ -647,7 +648,9 @@ int rtl8188eu_oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv)

switch (width) {
case 1:
RegRWStruct->value = rtw_read8(Adapter, offset);
error = rtw_read8(Adapter, offset, (u8 *) &RegRWStruct->value);
if (error)
status = NDIS_STATUS_NOT_ACCEPTED;
break;
case 2:
RegRWStruct->value = rtw_read16(Adapter, offset);
@@ -660,8 +660,12 @@ static void _PHY_SaveMACRegisters(
u32 i;
struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt);
struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
int error;

for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
MACBackup[i] = ODM_Read1Byte(dm_odm, MACReg[i]);
error = ODM_Read1Byte(dm_odm, MACReg[i], (u8 *) &MACBackup[i]);
if (error)
return;
}
MACBackup[i] = ODM_Read4Byte(dm_odm, MACReg[i]);
}
@@ -1010,9 +1014,12 @@ static void phy_LCCalibrate_8188E(struct adapter *adapt, bool is2t)
u32 RF_Amode = 0, RF_Bmode = 0, LC_Cal;
struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt);
struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
int error;

/* Check continuous TX and Packet TX */
tmpreg = ODM_Read1Byte(dm_odm, 0xd03);
error = ODM_Read1Byte(dm_odm, 0xd03, &tmpreg);
if (error)
return;

if ((tmpreg & 0x70) != 0) /* Deal with contisuous TX case */
ODM_Write1Byte(dm_odm, 0xd03, tmpreg & 0x8F); /* disable all continuous TX */
@@ -1232,7 +1239,13 @@ static void phy_setrfpathswitch_8188e(struct adapter *adapt, bool main, bool is2

if (!adapt->hw_init_completed) {
u8 u1btmp;
u1btmp = ODM_Read1Byte(dm_odm, REG_LEDCFG2) | BIT(7);
int error;

error = ODM_Read1Byte(dm_odm, REG_LEDCFG2, &u1btmp);
if (error)
return;

u1btmp |= BIT(7);
ODM_Write1Byte(dm_odm, REG_LEDCFG2, u1btmp);
ODM_SetBBReg(dm_odm, rFPGA0_XAB_RFParameter, BIT(13), 0x01);
}
@@ -35,6 +35,7 @@ u8 HalPwrSeqCmdParsing(struct adapter *padapter, u8 cut_vers, u8 fab_vers,
u32 offset = 0;
u32 poll_count = 0; /* polling autoload done. */
u32 max_poll_count = 5000;
int error;

do {
pwrcfgcmd = pwrseqcmd[aryidx];
@@ -48,7 +49,9 @@ u8 HalPwrSeqCmdParsing(struct adapter *padapter, u8 cut_vers, u8 fab_vers,
offset = GET_PWR_CFG_OFFSET(pwrcfgcmd);

/* Read the value from system register */
value = rtw_read8(padapter, offset);
error = rtw_read8(padapter, offset, &value);
if (error)
return false;

value &= ~(GET_PWR_CFG_MASK(pwrcfgcmd));
value |= (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd));
@@ -60,7 +63,9 @@ u8 HalPwrSeqCmdParsing(struct adapter *padapter, u8 cut_vers, u8 fab_vers,
poll_bit = false;
offset = GET_PWR_CFG_OFFSET(pwrcfgcmd);
do {
value = rtw_read8(padapter, offset);
error = rtw_read8(padapter, offset, &value);
if (error)
return false;

value &= GET_PWR_CFG_MASK(pwrcfgcmd);
if (value == (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd)))
@@ -321,11 +321,14 @@ s32 c2h_evt_read(struct adapter *adapter, u8 *buf)
struct c2h_evt_hdr *c2h_evt;
int i;
u8 trigger;
int error;

if (!buf)
goto exit;

trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
error = rtw_read8(adapter, REG_C2HEVT_CLEAR, &trigger);
if (error)
goto exit;

if (trigger == C2H_EVT_HOST_CLOSE)
goto exit; /* Not ready */
@@ -336,13 +339,21 @@ s32 c2h_evt_read(struct adapter *adapter, u8 *buf)

memset(c2h_evt, 0, 16);

*buf = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
*(buf + 1) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1);
error = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL, buf);
if (error)
goto clear_evt;

error = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1, buf + 1);
if (error)
goto clear_evt;

/* Read the content */
for (i = 0; i < c2h_evt->plen; i++)
c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL +
sizeof(*c2h_evt) + i);
for (i = 0; i < c2h_evt->plen; i++) {
error = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + sizeof(*c2h_evt) + i,
c2h_evt->payload + i);
if (error)
goto clear_evt;
}

ret = _SUCCESS;

@@ -4,10 +4,10 @@
#include "../include/odm_precomp.h"
/* ODM IO Relative API. */

u8 ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr)
int ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 *data)
{
struct adapter *Adapter = pDM_Odm->Adapter;
return rtw_read8(Adapter, RegAddr);
return rtw_read8(Adapter, RegAddr, data);
}

u16 ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr)

0 comments on commit 2b557bc

Please sign in to comment.