Hi, Greg, Larry and Phillip!
I noticed, that new staging driver was added like 3 weeks ago and I decided
to look at the code, because drivers in staging directory are always buggy.
The first thing I noticed is *no one* was checking read operations result, but
it can fail and driver may start writing random stack values into registers. It
can cause driver misbehavior or device misbehavior.
To avoid this type of bugs, i've expanded read() API with error parametr,
which will be initialized to error if read fails. It helps callers to
break/return earlier and don't write random values to registers or to rely
on random values.
Why is this pacth series RFC?
1. I don't have this device and I cannot test these changes.
2. I don't know how to handle errors in each particular case. For now, function
just returns or returns an error. That's all. I hope, driver maintainers will
help with these bits.
3. I guess, I handled not all uninit value bugs here. I hope, I fixed
at least half of them
This series was build-tested and made on top of staging-testing branch
With regards,
Pavel Skripkin
Pavel Skripkin (3):
staging: r8188eu: add proper rtw_read* error handling
staging: r8188eu: add error handling to ReadFuse
staging: r8188eu: add error argument to read_macreg
drivers/staging/r8188eu/core/rtw_debug.c | 79 +++-
drivers/staging/r8188eu/core/rtw_efuse.c | 119 +++--
drivers/staging/r8188eu/core/rtw_io.c | 18 +-
drivers/staging/r8188eu/core/rtw_mp.c | 38 +-
drivers/staging/r8188eu/core/rtw_mp_ioctl.c | 20 +-
drivers/staging/r8188eu/core/rtw_pwrctrl.c | 6 +-
drivers/staging/r8188eu/core/rtw_sreset.c | 7 +-
drivers/staging/r8188eu/hal/HalPwrSeqCmd.c | 9 +-
drivers/staging/r8188eu/hal/hal_com.c | 22 +-
drivers/staging/r8188eu/hal/hal_intf.c | 6 +-
drivers/staging/r8188eu/hal/odm_interface.c | 12 +-
drivers/staging/r8188eu/hal/rtl8188e_cmd.c | 37 +-
drivers/staging/r8188eu/hal/rtl8188e_dm.c | 6 +-
.../staging/r8188eu/hal/rtl8188e_hal_init.c | 260 ++++++++---
drivers/staging/r8188eu/hal/rtl8188e_phycfg.c | 26 +-
drivers/staging/r8188eu/hal/rtl8188e_sreset.c | 20 +-
drivers/staging/r8188eu/hal/rtl8188eu_led.c | 17 +-
drivers/staging/r8188eu/hal/usb_halinit.c | 412 ++++++++++++++----
drivers/staging/r8188eu/hal/usb_ops_linux.c | 55 ++-
drivers/staging/r8188eu/include/hal_intf.h | 6 +-
.../staging/r8188eu/include/rtl8188e_hal.h | 2 +-
drivers/staging/r8188eu/include/rtw_efuse.h | 4 +-
drivers/staging/r8188eu/include/rtw_io.h | 18 +-
drivers/staging/r8188eu/include/rtw_mp.h | 2 +-
drivers/staging/r8188eu/os_dep/ioctl_linux.c | 168 +++++--
drivers/staging/r8188eu/os_dep/usb_intf.c | 4 +-
26 files changed, 1072 insertions(+), 301 deletions(-)
--
2.32.0
rtw_read*() functions call usb_read* inside. These functions could fail
in some cases; for example: failed to receive control message. These
cases should be handled to prevent uninit value bugs, since usb_read*
functions blindly return stack variable without checking if this value
_actualy_ initialized.
To achive it, all usb_read* and rtw_read*() argument list is expanded
with pointer to error and added error usbctrl_vendorreq() error checking.
If transfer is successful error will be initialized to 0 otherwise to
error returned from usb_control_msg().
To not break the build, added error checking for rtw_read*() call all
across the driver.
Signed-off-by: Pavel Skripkin <[email protected]>
---
drivers/staging/r8188eu/core/rtw_debug.c | 79 +++-
drivers/staging/r8188eu/core/rtw_efuse.c | 83 +++-
drivers/staging/r8188eu/core/rtw_io.c | 18 +-
drivers/staging/r8188eu/core/rtw_mp.c | 37 +-
drivers/staging/r8188eu/core/rtw_mp_ioctl.c | 20 +-
drivers/staging/r8188eu/core/rtw_pwrctrl.c | 6 +-
drivers/staging/r8188eu/core/rtw_sreset.c | 7 +-
drivers/staging/r8188eu/hal/HalPwrSeqCmd.c | 9 +-
drivers/staging/r8188eu/hal/hal_com.c | 22 +-
drivers/staging/r8188eu/hal/odm_interface.c | 12 +-
drivers/staging/r8188eu/hal/rtl8188e_cmd.c | 37 +-
drivers/staging/r8188eu/hal/rtl8188e_dm.c | 6 +-
.../staging/r8188eu/hal/rtl8188e_hal_init.c | 198 +++++++--
drivers/staging/r8188eu/hal/rtl8188e_phycfg.c | 26 +-
drivers/staging/r8188eu/hal/rtl8188e_sreset.c | 20 +-
drivers/staging/r8188eu/hal/rtl8188eu_led.c | 17 +-
drivers/staging/r8188eu/hal/usb_halinit.c | 394 ++++++++++++++----
drivers/staging/r8188eu/hal/usb_ops_linux.c | 16 +-
drivers/staging/r8188eu/include/rtw_io.h | 18 +-
drivers/staging/r8188eu/os_dep/ioctl_linux.c | 168 +++++---
20 files changed, 941 insertions(+), 252 deletions(-)
diff --git a/drivers/staging/r8188eu/core/rtw_debug.c b/drivers/staging/r8188eu/core/rtw_debug.c
index 2ee64cef73f7..9f8df3cf3070 100644
--- a/drivers/staging/r8188eu/core/rtw_debug.c
+++ b/drivers/staging/r8188eu/core/rtw_debug.c
@@ -73,8 +73,9 @@ int proc_get_read_reg(char *page, char **start,
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-
+ int error;
int len = 0;
+ u32 tmp;
if (proc_get_read_addr == 0xeeeeeeee) {
*eof = 1;
@@ -83,19 +84,35 @@ 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));
+ tmp = rtw_read8(padapter, proc_get_read_addr, &error);
+
+ if (error)
+ goto end;
+
+ 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));
+ tmp = rtw_read16(padapter, proc_get_read_addr, &error);
+
+ if (error)
+ goto end;
+
+ len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n", proc_get_read_addr, (u16) tmp);
break;
case 4:
- len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n", proc_get_read_addr, rtw_read32(padapter, proc_get_read_addr));
+ tmp = rtw_read32(padapter, proc_get_read_addr, &error);
+
+ if (error)
+ goto end;
+
+ len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n", proc_get_read_addr, tmp);
break;
default:
len += snprintf(page + len, count - len, "error read length=%d\n", proc_get_read_len);
break;
}
+end:
*eof = 1;
return len;
}
@@ -305,13 +322,20 @@ int proc_get_mac_reg_dump1(char *page, char **start,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1;
+ int error;
+ u32 tmp;
len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
for (i = 0x0; i < 0x300; i += 4) {
if (j % 4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+ tmp = rtw_read32(padapter, i, &error);
+ if (error)
+ return len;
+
+ len += snprintf(page + len, count - len, " 0x%08x ", tmp);
if ((j++) % 4 == 0)
len += snprintf(page + len, count - len, "\n");
}
@@ -328,13 +352,20 @@ int proc_get_mac_reg_dump2(char *page, char **start,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1;
+ int error;
+ u32 tmp;
len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
memset(page, 0, count);
for (i = 0x300; i < 0x600; i += 4) {
if (j % 4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+ tmp = rtw_read32(padapter, i, &error);
+ if (error)
+ return len;
+
+ len += snprintf(page + len, count - len, " 0x%08x ", tmp);
if ((j++) % 4 == 0)
len += snprintf(page + len, count - len, "\n");
}
@@ -351,13 +382,20 @@ int proc_get_mac_reg_dump3(char *page, char **start,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1;
+ int error;
+ u32 tmp;
len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
for (i = 0x600; i < 0x800; i += 4) {
if (j % 4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+ tmp = rtw_read32(padapter, i, &error);
+ if (error)
+ return len;
+
+ len += snprintf(page + len, count - len, " 0x%08x ", tmp);
if ((j++) % 4 == 0)
len += snprintf(page + len, count - len, "\n");
}
@@ -374,12 +412,19 @@ int proc_get_bb_reg_dump1(char *page, char **start,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1;
+ int error;
+ u32 tmp;
len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
for (i = 0x800; i < 0xB00; i += 4) {
if (j % 4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+ tmp = rtw_read32(padapter, i, &error);
+ if (error)
+ return len;
+
+ len += snprintf(page + len, count - len, " 0x%08x ", tmp);
if ((j++) % 4 == 0)
len += snprintf(page + len, count - len, "\n");
}
@@ -395,12 +440,19 @@ int proc_get_bb_reg_dump2(char *page, char **start,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1;
+ int error;
+ u32 tmp;
len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
for (i = 0xB00; i < 0xE00; i += 4) {
if (j % 4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+ tmp = rtw_read32(padapter, i, &error);
+ if (error)
+ return len;
+
+ len += snprintf(page + len, count - len, " 0x%08x ", tmp);
if ((j++) % 4 == 0)
len += snprintf(page + len, count - len, "\n");
}
@@ -416,12 +468,19 @@ int proc_get_bb_reg_dump3(char *page, char **start,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1;
+ int error;
+ u32 tmp;
len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
for (i = 0xE00; i < 0x1000; i += 4) {
if (j % 4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+ tmp = rtw_read32(padapter, i, &error);
+ if (error)
+ return len;
+
+ len += snprintf(page + len, count - len, " 0x%08x ", tmp);
if ((j++) % 4 == 0)
len += snprintf(page + len, count - len, "\n");
}
diff --git a/drivers/staging/r8188eu/core/rtw_efuse.c b/drivers/staging/r8188eu/core/rtw_efuse.c
index decccf7622f0..47ff73b28380 100644
--- a/drivers/staging/r8188eu/core/rtw_efuse.c
+++ b/drivers/staging/r8188eu/core/rtw_efuse.c
@@ -159,6 +159,7 @@ ReadEFuseByte(
u32 value32;
u8 readbyte;
u16 retry;
+ int error;
if (pseudo) {
Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf);
@@ -167,18 +168,27 @@ ReadEFuseByte(
/* Write Address */
rtw_write8(Adapter, EFUSE_CTRL + 1, (_offset & 0xff));
- readbyte = rtw_read8(Adapter, EFUSE_CTRL + 2);
+ readbyte = rtw_read8(Adapter, EFUSE_CTRL + 2, &error);
+ 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);
+ readbyte = rtw_read8(Adapter, EFUSE_CTRL + 3, &error);
+ if (error)
+ return;
rtw_write8(Adapter, EFUSE_CTRL + 3, (readbyte & 0x7f));
/* Check bit 32 read-ready */
retry = 0;
- value32 = rtw_read32(Adapter, EFUSE_CTRL);
+ value32 = rtw_read32(Adapter, EFUSE_CTRL, &error);
+ if (error)
+ return;
+
while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) {
- value32 = rtw_read32(Adapter, EFUSE_CTRL);
+ value32 = rtw_read32(Adapter, EFUSE_CTRL, &error);
+ if (error)
+ return;
retry++;
}
@@ -187,7 +197,9 @@ ReadEFuseByte(
/* Designer says that there shall be some delay after ready bit is set, or the */
/* result will always stay on last data we read. */
udelay(50);
- value32 = rtw_read32(Adapter, EFUSE_CTRL);
+ value32 = rtw_read32(Adapter, EFUSE_CTRL, &error);
+ if (error)
+ return;
*pbuf = (u8)(value32 & 0xff);
}
@@ -244,6 +256,7 @@ 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);
@@ -251,27 +264,41 @@ u8 EFUSE_Read1Byte(struct adapter *Adapter, u16 Address)
/* Write E-fuse Register address bit0~7 */
temp = Address & 0xFF;
rtw_write8(Adapter, EFUSE_CTRL + 1, temp);
- Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 2);
+ Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 2, &error);
+ 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);
+ Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3, &error);
+ 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);
+ Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3, &error);
+ if (error)
+ return 0xFF;
+
while (!(Bytetemp & 0x80)) {
- Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3);
+ Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3, &error);
+ if (error)
+ return 0xFF;
+
k++;
if (k == 1000) {
k = 0;
break;
}
}
- data = rtw_read8(Adapter, EFUSE_CTRL);
+ data = rtw_read8(Adapter, EFUSE_CTRL, &error);
+ if (error)
+ return 0xFF;
return data;
} else {
return 0xFF;
@@ -284,6 +311,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,15 +321,28 @@ 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));
+
+ tmp = rtw_read8(pAdapter, EFUSE_CTRL + 2, &error);
+ if (error)
+ return false;
+
rtw_write8(pAdapter, EFUSE_CTRL + 2, ((u8)((addr >> 8) & 0x03)) |
- (rtw_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC));
+ (tmp & 0xFC));
rtw_write8(pAdapter, EFUSE_CTRL + 3, 0x72);/* read cmd */
- while (!(0x80 & rtw_read8(pAdapter, EFUSE_CTRL + 3)) && (tmpidx < 100))
+ tmp = rtw_read8(pAdapter, EFUSE_CTRL + 3, &error);
+ if (error)
+ return false;
+
+ while (!(0x80 & tmp) && (tmpidx < 100))
tmpidx++;
if (tmpidx < 100) {
- *data = rtw_read8(pAdapter, EFUSE_CTRL);
+ tmp = rtw_read8(pAdapter, EFUSE_CTRL, &error);\
+ if (error)
+ return false;
+
+ *data = tmp;
result = true;
} else {
*data = 0xff;
@@ -314,6 +356,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,14 +367,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));
+
+ tmp = rtw_read8(pAdapter, EFUSE_CTRL + 2, &error);
+ 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))
+ tmp = rtw_read8(pAdapter, EFUSE_CTRL + 3, &error);
+ if (error)
+ return false;
+
+ while ((0x80 & tmp) && (tmpidx < 100))
tmpidx++;
if (tmpidx < 100)
diff --git a/drivers/staging/r8188eu/core/rtw_io.c b/drivers/staging/r8188eu/core/rtw_io.c
index cde0205816b1..d9684aa144c8 100644
--- a/drivers/staging/r8188eu/core/rtw_io.c
+++ b/drivers/staging/r8188eu/core/rtw_io.c
@@ -34,44 +34,44 @@ [email protected]
#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)
+u8 _rtw_read8(struct adapter *adapter, u32 addr, int *error)
{
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);
+ u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr, int *error);
_read8 = pintfhdl->io_ops._read8;
- r_val = _read8(pintfhdl, addr);
+ r_val = _read8(pintfhdl, addr, error);
return r_val;
}
-u16 _rtw_read16(struct adapter *adapter, u32 addr)
+u16 _rtw_read16(struct adapter *adapter, u32 addr, int *error)
{
u16 r_val;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &pio_priv->intf;
- u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
+ u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr, int *error);
_read16 = pintfhdl->io_ops._read16;
- r_val = _read16(pintfhdl, addr);
+ r_val = _read16(pintfhdl, addr, error);
return r_val;
}
-u32 _rtw_read32(struct adapter *adapter, u32 addr)
+u32 _rtw_read32(struct adapter *adapter, u32 addr, int *error)
{
u32 r_val;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &pio_priv->intf;
- u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
+ u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr, int *error);
_read32 = pintfhdl->io_ops._read32;
- r_val = _read32(pintfhdl, addr);
+ r_val = _read32(pintfhdl, addr, error);
return r_val;
}
diff --git a/drivers/staging/r8188eu/core/rtw_mp.c b/drivers/staging/r8188eu/core/rtw_mp.c
index 93bb683b628f..601a1fd5d4e7 100644
--- a/drivers/staging/r8188eu/core/rtw_mp.c
+++ b/drivers/staging/r8188eu/core/rtw_mp.c
@@ -10,16 +10,17 @@
u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz)
{
u32 val = 0;
+ int error;
switch (sz) {
case 1:
- val = rtw_read8(padapter, addr);
+ val = rtw_read8(padapter, addr, &error);
break;
case 2:
- val = rtw_read16(padapter, addr);
+ val = rtw_read16(padapter, addr, &error);
break;
case 4:
- val = rtw_read32(padapter, addr);
+ val = rtw_read32(padapter, addr, &error);
break;
default:
val = 0xffffffff;
@@ -282,10 +283,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);
+ v8 = rtw_read8(padapter, REG_BCN_CTRL, &error);
+ if (error)
+ return;
+
v8 &= ~EN_BCN_FUNCTION;
rtw_write8(padapter, REG_BCN_CTRL, v8);
@@ -310,6 +315,7 @@ s32 mp_start_test(struct adapter *padapter)
struct mp_priv *pmppriv = &padapter->mppriv;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct wlan_network *tgt_network = &pmlmepriv->cur_network;
+ int error;
padapter->registrypriv.mp_mode = 1;
pmppriv->bSetTxPower = 0; /* for manually set tx power */
@@ -403,7 +409,11 @@ s32 mp_start_test(struct adapter *padapter)
if (res == _SUCCESS) {
/* set MSR to WIFI_FW_ADHOC_STATE */
- val8 = rtw_read8(padapter, MSR) & 0xFC; /* 0x0102 */
+ val8 = rtw_read8(padapter, MSR, &error);
+ if (error)
+ return _FAIL;
+
+ val8 &= 0xFC; /* 0x0102 */
val8 |= WIFI_FW_ADHOC_STATE;
rtw_write8(padapter, MSR, val8); /* Link in ad hoc network */
}
@@ -795,12 +805,17 @@ static u32 GetPhyRxPktCounts(struct adapter *pAdapter, u32 selbit)
{
/* selection */
u32 phyrx_set = 0, count = 0;
+ int error;
phyrx_set = _RXERR_RPT_SEL(selbit & 0xF);
rtw_write32(pAdapter, REG_RXERR_RPT, phyrx_set);
/* Read packet count */
- count = rtw_read32(pAdapter, REG_RXERR_RPT) & RXERR_COUNTER_MASK;
+ count = rtw_read32(pAdapter, REG_RXERR_RPT, &error);
+ if (error)
+ return 0;
+
+ count &= RXERR_COUNTER_MASK;
return count;
}
@@ -833,8 +848,12 @@ u32 GetPhyRxPktCRC32Error(struct adapter *pAdapter)
static u32 rtw_GetPSDData(struct adapter *pAdapter, u32 point)
{
int psd_val;
+ int error;
+
+ psd_val = rtw_read32(pAdapter, 0x808, &error);
+ if (error)
+ return error;
- psd_val = rtw_read32(pAdapter, 0x808);
psd_val &= 0xFFBFFC00;
psd_val |= point;
@@ -844,7 +863,9 @@ static u32 rtw_GetPSDData(struct adapter *pAdapter, u32 point)
rtw_write32(pAdapter, 0x808, psd_val);
mdelay(1);
- psd_val = rtw_read32(pAdapter, 0x8B4);
+ psd_val = rtw_read32(pAdapter, 0x8B4, &error);
+ if (error)
+ return error;
psd_val &= 0x0000FFFF;
diff --git a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
index c85f8e467337..ad004b176f94 100644
--- a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
+++ b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
@@ -629,9 +629,10 @@ int rtl8188eu_oid_rt_pro8711_join_bss_hdl(struct oid_par_priv *poid_par_priv)
int rtl8188eu_oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv)
{
struct mp_rw_reg *RegRWStruct;
- u32 offset, width;
+ u32 offset, width, tmp;
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,17 +648,28 @@ 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);
+ tmp = rtw_read8(Adapter, offset, &error);
+ if (error)
+ return NDIS_STATUS_FAILURE;
+
break;
case 2:
- RegRWStruct->value = rtw_read16(Adapter, offset);
+ tmp = rtw_read16(Adapter, offset, &error);
+ if (error)
+ return NDIS_STATUS_FAILURE;
+
break;
default:
width = 4;
- RegRWStruct->value = rtw_read32(Adapter, offset);
+ tmp = rtw_read32(Adapter, offset, &error);
+ if (error)
+ return NDIS_STATUS_FAILURE;
+
break;
}
+ RegRWStruct->value = tmp;
+
_irqlevel_changed_(&oldirql, RAISE);
*poid_par_priv->bytes_rw = width;
diff --git a/drivers/staging/r8188eu/core/rtw_pwrctrl.c b/drivers/staging/r8188eu/core/rtw_pwrctrl.c
index c3897b29121c..f4accd0b01d8 100644
--- a/drivers/staging/r8188eu/core/rtw_pwrctrl.c
+++ b/drivers/staging/r8188eu/core/rtw_pwrctrl.c
@@ -55,6 +55,8 @@ int ips_leave(struct adapter *padapter)
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
int result = _SUCCESS;
int keyid;
+ u32 tmp;
+ int error;
_enter_pwrlock(&pwrpriv->lock);
@@ -83,7 +85,9 @@ int ips_leave(struct adapter *padapter)
}
}
- DBG_88E("==> ips_leave.....LED(0x%08x)...\n", rtw_read32(padapter, 0x4c));
+ tmp = rtw_read32(padapter, 0x4c, &error);
+ if (!error)
+ DBG_88E("==> ips_leave.....LED(0x%08x)...\n", tmp);
pwrpriv->bips_processing = false;
pwrpriv->bkeepfwalive = false;
diff --git a/drivers/staging/r8188eu/core/rtw_sreset.c b/drivers/staging/r8188eu/core/rtw_sreset.c
index 8e1bc62e74e5..1ac3f5c6bdec 100644
--- a/drivers/staging/r8188eu/core/rtw_sreset.c
+++ b/drivers/staging/r8188eu/core/rtw_sreset.c
@@ -29,13 +29,16 @@ u8 sreset_get_wifi_status(struct adapter *padapter)
{
struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
struct sreset_priv *psrtpriv = &pHalData->srestpriv;
-
+ int error;
u8 status = WIFI_STATUS_SUCCESS;
u32 val32 = 0;
if (psrtpriv->silent_reset_inprogress)
return status;
- val32 = rtw_read32(padapter, REG_TXDMA_STATUS);
+ val32 = rtw_read32(padapter, REG_TXDMA_STATUS, &error);
+ if (error)
+ return WIFI_MAC_TXDMA_ERROR;
+
if (val32 == 0xeaeaeaea) {
psrtpriv->Wifi_Error_Status = WIFI_IF_NOT_EXIST;
} else if (val32 != 0) {
diff --git a/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c b/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
index 0fd11aca7ac7..ed24d904e3f6 100644
--- a/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
+++ b/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
@@ -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);
+ value = rtw_read8(padapter, offset, &error);
+ 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);
+ value = rtw_read8(padapter, offset, &error);
+ if (error)
+ return false;
value &= GET_PWR_CFG_MASK(pwrcfgcmd);
if (value == (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd)))
diff --git a/drivers/staging/r8188eu/hal/hal_com.c b/drivers/staging/r8188eu/hal/hal_com.c
index f09d4d49b159..b6cbbf2275c3 100644
--- a/drivers/staging/r8188eu/hal/hal_com.c
+++ b/drivers/staging/r8188eu/hal/hal_com.c
@@ -319,13 +319,15 @@ s32 c2h_evt_read(struct adapter *adapter, u8 *buf)
{
s32 ret = _FAIL;
struct c2h_evt_hdr *c2h_evt;
- int i;
+ int i, error;
u8 trigger;
if (!buf)
goto exit;
- trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
+ trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR, &error);
+ if (error)
+ goto exit;
if (trigger == C2H_EVT_HOST_CLOSE)
goto exit; /* Not ready */
@@ -336,13 +338,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);
+ *buf = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL, &error);
+ if (error)
+ goto clear_evt;
+
+ *(buf + 1) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1, &error);
+ if (error)
+ ;
/* Read the content */
- for (i = 0; i < c2h_evt->plen; i++)
+ for (i = 0; i < c2h_evt->plen; i++) {
c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL +
- sizeof(*c2h_evt) + i);
+ sizeof(*c2h_evt) + i, &error);
+ if (error)
+ goto clear_evt;
+ }
ret = _SUCCESS;
diff --git a/drivers/staging/r8188eu/hal/odm_interface.c b/drivers/staging/r8188eu/hal/odm_interface.c
index 5a01495d74bc..cedc68152401 100644
--- a/drivers/staging/r8188eu/hal/odm_interface.c
+++ b/drivers/staging/r8188eu/hal/odm_interface.c
@@ -7,19 +7,25 @@
u8 ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr)
{
struct adapter *Adapter = pDM_Odm->Adapter;
- return rtw_read8(Adapter, RegAddr);
+ int error;
+
+ return rtw_read8(Adapter, RegAddr, &error);
}
u16 ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr)
{
struct adapter *Adapter = pDM_Odm->Adapter;
- return rtw_read16(Adapter, RegAddr);
+ int error;
+
+ return rtw_read16(Adapter, RegAddr, &error);
}
u32 ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr)
{
struct adapter *Adapter = pDM_Odm->Adapter;
- return rtw_read32(Adapter, RegAddr);
+ int error;
+
+ return rtw_read32(Adapter, RegAddr, &error);
}
void ODM_Write1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 Data)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_cmd.c b/drivers/staging/r8188eu/hal/rtl8188e_cmd.c
index 3e1a45030bc8..4447fa8de275 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_cmd.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_cmd.c
@@ -21,11 +21,15 @@ static u8 _is_fw_read_cmd_down(struct adapter *adapt, u8 msgbox_num)
{
u8 read_down = false;
int retry_cnts = 100;
-
+ int error;
u8 valid;
do {
- valid = rtw_read8(adapt, REG_HMETFR) & BIT(msgbox_num);
+ valid = rtw_read8(adapt, REG_HMETFR, &error);
+ if (error)
+ continue;
+
+ valid &= BIT(msgbox_num);
if (0 == valid)
read_down = true;
} while ((!read_down) && (retry_cnts--));
@@ -580,6 +584,8 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
bool bcn_valid = false;
u8 DLBcnCount = 0;
u32 poll = 0;
+ u8 tmp;
+ int error;
DBG_88E("%s mstatus(%x)\n", __func__, mstatus);
@@ -596,8 +602,17 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
/* Disable Hw protection for a time which revserd for Hw sending beacon. */
/* Fix download reserved page packet fail that access collision with the protection time. */
/* 2010.05.11. Added by tynli. */
- rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) & (~BIT(3)));
- rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) | BIT(4));
+ tmp = rtw_read8(adapt, REG_BCN_CTRL, &error);
+ if (error)
+ return;
+
+ rtw_write8(adapt, REG_BCN_CTRL, tmp & (~BIT(3)));
+
+ tmp = rtw_read8(adapt, REG_BCN_CTRL, &error);
+ if (error)
+ return;
+
+ rtw_write8(adapt, REG_BCN_CTRL, tmp | BIT(4));
if (haldata->RegFwHwTxQCtrl & BIT(6)) {
DBG_88E("HalDownloadRSVDPage(): There is an Adapter is sending beacon.\n");
@@ -639,8 +654,18 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
/* */
/* Enable Bcn */
- rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) | BIT(3));
- rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) & (~BIT(4)));
+
+ tmp = rtw_read8(adapt, REG_BCN_CTRL, &error);
+ if (error)
+ return;
+
+ rtw_write8(adapt, REG_BCN_CTRL, tmp | BIT(3));
+
+ tmp = rtw_read8(adapt, REG_BCN_CTRL, &error);
+ if (error)
+ return;
+
+ rtw_write8(adapt, REG_BCN_CTRL, tmp & (~BIT(4)));
/* To make sure that if there exists an adapter which would like to send beacon. */
/* If exists, the origianl value of 0x422[6] will be 1, we should check this to */
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_dm.c b/drivers/staging/r8188eu/hal/rtl8188e_dm.c
index 78552303c990..c645d7fc8e8b 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_dm.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_dm.c
@@ -16,8 +16,12 @@ static void dm_CheckStatistics(struct adapter *Adapter)
static void dm_InitGPIOSetting(struct adapter *Adapter)
{
u8 tmp1byte;
+ int error;
+
+ tmp1byte = rtw_read8(Adapter, REG_GPIO_MUXCFG, &error);
+ if (error)
+ return;
- tmp1byte = rtw_read8(Adapter, REG_GPIO_MUXCFG);
tmp1byte &= (GPIOSEL_GPIO | ~GPIOSEL_ENBT);
rtw_write8(Adapter, REG_GPIO_MUXCFG, tmp1byte);
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
index 393969f51206..0a2c08a24ad8 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
@@ -13,10 +13,14 @@
static void iol_mode_enable(struct adapter *padapter, u8 enable)
{
u8 reg_0xf0 = 0;
+ int error;
if (enable) {
/* Enable initial offload */
- reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
+ reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG, &error);
+ if (error)
+ return;
+
rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 | SW_OFFLOAD_EN);
if (!padapter->bFWReady) {
@@ -26,7 +30,10 @@ static void iol_mode_enable(struct adapter *padapter, u8 enable)
} else {
/* disable initial offload */
- reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
+ reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG, &error);
+ if (error)
+ return;
+
rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 & ~SW_OFFLOAD_EN);
}
}
@@ -36,18 +43,28 @@ static s32 iol_execute(struct adapter *padapter, u8 control)
s32 status = _FAIL;
u8 reg_0x88 = 0;
u32 start = 0, passing_time = 0;
+ int error;
control = control & 0x0f;
- reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
+ reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0, &error);
+ if (error)
+ return status;
+
rtw_write8(padapter, REG_HMEBOX_E0, reg_0x88 | control);
start = jiffies;
- while ((reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0)) & control &&
- (passing_time = rtw_get_passing_time_ms(start)) < 1000) {
- ;
- }
- reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
+ do {
+ reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0, &error);
+ if (error)
+ return status;
+ } while (reg_0x88 & control &&
+ (passing_time = rtw_get_passing_time_ms(start)) < 1000);
+
+ reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0, &error);
+ if (error)
+ return status;
+
status = (reg_0x88 & control) ? _FAIL : _SUCCESS;
if (reg_0x88 & control << 4)
status = _FAIL;
@@ -201,11 +218,15 @@ static void efuse_read_phymap_from_txpktbuf(
u16 len = 0, count = 0;
int i = 0;
u16 limit = *size;
+ int error;
u8 *pos = content;
- if (bcnhead < 0) /* if not valid */
- bcnhead = rtw_read8(adapter, REG_TDECTRL + 1);
+ if (bcnhead < 0) { /* if not valid */
+ bcnhead = rtw_read8(adapter, REG_TDECTRL + 1, &error);
+ if (error)
+ return;
+ }
DBG_88E("%s bcnhead:%d\n", __func__, bcnhead);
@@ -218,22 +239,37 @@ static void efuse_read_phymap_from_txpktbuf(
rtw_write8(adapter, REG_TXPKTBUF_DBG, 0);
start = jiffies;
- while (!(reg_0x143 = rtw_read8(adapter, REG_TXPKTBUF_DBG)) &&
+
+ reg_0x143 = rtw_read8(adapter, REG_TXPKTBUF_DBG, &error);
+ if (error)
+ return;
+
+ while (!reg_0x143 &&
(passing_time = rtw_get_passing_time_ms(start)) < 1000) {
- DBG_88E("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n", __func__, reg_0x143, rtw_read8(adapter, 0x106));
+ DBG_88E("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n", __func__, reg_0x143, rtw_read8(adapter, 0x106, &error));
rtw_usleep_os(100);
+
+ reg_0x143 = rtw_read8(adapter, REG_TXPKTBUF_DBG, &error);
+ if (error)
+ return;
}
/* data from EEPROM needs to be in LE */
- lo32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L));
- hi32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H));
+ lo32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L, &error));
+ if (error)
+ return;
+ hi32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H, &error));
+ if (error)
+ return;
if (i == 0) {
/* Although lenc is only used in a debug statement,
* do not remove it as the rtw_read16() call consumes
* 2 bytes from the EEPROM source.
*/
- u16 lenc = rtw_read16(adapter, REG_PKTBUF_DBG_DATA_L);
+ u16 lenc = rtw_read16(adapter, REG_PKTBUF_DBG_DATA_L, &error);
+ if (error)
+ return;
len = le32_to_cpu(lo32) & 0x0000ffff;
@@ -342,6 +378,8 @@ void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len)
u32 addr, rstatus, loop = 0;
u16 data_cnts = (data_len / 8) + 1;
u8 *pbuf = vzalloc(data_len + 10);
+ int error;
+
DBG_88E("###### %s ######\n", __func__);
rtw_write8(Adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
@@ -351,12 +389,22 @@ void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len)
rtw_usleep_os(2);
loop = 0;
do {
- rstatus = (reg_140 = rtw_read32(Adapter, REG_PKTBUF_DBG_CTRL) & BIT(24));
+ u32 tmp = rtw_read32(Adapter, REG_PKTBUF_DBG_CTRL, &error);
+
+ if (error)
+ break;
+
+ rstatus = (reg_140 = tmp & BIT(24));
if (rstatus) {
- fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_L);
+ fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_L, &error);
+ if (error)
+ break;
+
memcpy(pbuf + (addr * 8), &fifo_data, 4);
- fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_H);
+ fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_H, &error);
+ if (error)
+ break;
memcpy(pbuf + (addr * 8 + 4), &fifo_data, 4);
}
rtw_usleep_os(2);
@@ -371,18 +419,25 @@ void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len)
static void _FWDownloadEnable(struct adapter *padapter, bool enable)
{
u8 tmp;
+ int error;
if (enable) {
/* MCU firmware download enable. */
- tmp = rtw_read8(padapter, REG_MCUFWDL);
+ tmp = rtw_read8(padapter, REG_MCUFWDL, &error);
+ if (error)
+ return;
rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01);
/* 8051 reset */
- tmp = rtw_read8(padapter, REG_MCUFWDL + 2);
+ tmp = rtw_read8(padapter, REG_MCUFWDL + 2, &error);
+ if (error)
+ return;
rtw_write8(padapter, REG_MCUFWDL + 2, tmp & 0xf7);
} else {
/* MCU firmware download disable. */
- tmp = rtw_read8(padapter, REG_MCUFWDL);
+ tmp = rtw_read8(padapter, REG_MCUFWDL, &error);
+ if (error)
+ return;
rtw_write8(padapter, REG_MCUFWDL, tmp & 0xfe);
/* Reserved for fw extension. */
@@ -452,8 +507,14 @@ static int _PageWrite(struct adapter *padapter, u32 page, void *buffer, u32 size
{
u8 value8;
u8 u8Page = (u8)(page & 0x07);
+ int error;
+ u8 tmp;
- value8 = (rtw_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | u8Page;
+ tmp = rtw_read8(padapter, REG_MCUFWDL + 2, &error);
+ if (error)
+ return _FAIL;
+
+ value8 = (tmp & 0xF8) | u8Page;
rtw_write8(padapter, REG_MCUFWDL + 2, value8);
return _BlockWrite(padapter, buffer, size);
@@ -493,8 +554,12 @@ static int _WriteFW(struct adapter *padapter, void *buffer, u32 size)
void _8051Reset88E(struct adapter *padapter)
{
u8 u1bTmp;
+ int error;
+
+ u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1, &error);
+ if (error)
+ return;
- u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp & (~BIT(2)));
rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp | (BIT(2)));
DBG_88E("=====> _8051Reset88E(): 8051 reset success .\n");
@@ -504,10 +569,13 @@ static s32 _FWFreeToGo(struct adapter *padapter)
{
u32 counter = 0;
u32 value32;
+ int error;
/* polling CheckSum report */
do {
- value32 = rtw_read32(padapter, REG_MCUFWDL);
+ value32 = rtw_read32(padapter, REG_MCUFWDL, &error);
+ if (error)
+ return _FAIL;
if (value32 & FWDL_ChkSum_rpt)
break;
} while (counter++ < POLLING_READY_TIMEOUT_COUNT);
@@ -518,7 +586,10 @@ static s32 _FWFreeToGo(struct adapter *padapter)
}
DBG_88E("%s: Checksum report OK! REG_MCUFWDL:0x%08x\n", __func__, value32);
- value32 = rtw_read32(padapter, REG_MCUFWDL);
+ value32 = rtw_read32(padapter, REG_MCUFWDL, &error);
+ if (error)
+ return _FAIL;
+
value32 |= MCUFWDL_RDY;
value32 &= ~WINTINI_RDY;
rtw_write32(padapter, REG_MCUFWDL, value32);
@@ -528,7 +599,10 @@ static s32 _FWFreeToGo(struct adapter *padapter)
/* polling for FW ready */
counter = 0;
do {
- value32 = rtw_read32(padapter, REG_MCUFWDL);
+ value32 = rtw_read32(padapter, REG_MCUFWDL, &error);
+ if (error)
+ return -FAIL;
+
if (value32 & WINTINI_RDY) {
DBG_88E("%s: Polling FW ready success!! REG_MCUFWDL:0x%08x\n", __func__, value32);
return _SUCCESS;
@@ -591,6 +665,8 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
u8 *pFirmwareBuf;
u32 FirmwareLen;
static int log_version;
+ int error;
+ u8 tmp;
if (!dvobj->firmware.szFwBuffer)
rtStatus = load_firmware(&dvobj->firmware, device);
@@ -621,7 +697,11 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
/* Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself, */
/* or it will cause download Fw fail. 2010.02.01. by tynli. */
- if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) { /* 8051 RAM code */
+ tmp = rtw_read8(padapter, REG_MCUFWDL, &error);
+ if (error)
+ return _FAIL;
+
+ if (tmp & RAM_DL_SEL) { /* 8051 RAM code */
rtw_write8(padapter, REG_MCUFWDL, 0x00);
_8051Reset88E(padapter);
}
@@ -629,8 +709,12 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
_FWDownloadEnable(padapter, true);
fwdl_start_time = jiffies;
while (1) {
+ tmp = rtw_read8(padapter, REG_MCUFWDL, &error);
+ if (error)
+ return _FAIL;
+
/* reset the FWDL chksum */
- rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL) | FWDL_ChkSum_rpt);
+ rtw_write8(padapter, REG_MCUFWDL, tmp | FWDL_ChkSum_rpt);
rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen);
@@ -715,25 +799,35 @@ hal_EfusePowerSwitch_RTL8188E(
{
u8 tempval;
u16 tmpV16;
+ int error;
if (PwrState) {
rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
/* 1.2V Power: From VDDON with Power Cut(0x0000h[15]), defualt valid */
- tmpV16 = rtw_read16(pAdapter, REG_SYS_ISO_CTRL);
+ tmpV16 = rtw_read16(pAdapter, REG_SYS_ISO_CTRL, &error);
+ if (error)
+ return;
+
if (!(tmpV16 & PWC_EV12V)) {
tmpV16 |= PWC_EV12V;
rtw_write16(pAdapter, REG_SYS_ISO_CTRL, tmpV16);
}
/* Reset: 0x0000h[28], default valid */
- tmpV16 = rtw_read16(pAdapter, REG_SYS_FUNC_EN);
+ tmpV16 = rtw_read16(pAdapter, REG_SYS_FUNC_EN, &error);
+ if (error)
+ return;
+
if (!(tmpV16 & FEN_ELDR)) {
tmpV16 |= FEN_ELDR;
rtw_write16(pAdapter, REG_SYS_FUNC_EN, tmpV16);
}
/* Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */
- tmpV16 = rtw_read16(pAdapter, REG_SYS_CLKR);
+ tmpV16 = rtw_read16(pAdapter, REG_SYS_CLKR, &error);
+ if (error)
+ return;
+
if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) {
tmpV16 |= (LOADER_CLK_EN | ANA8M);
rtw_write16(pAdapter, REG_SYS_CLKR, tmpV16);
@@ -741,7 +835,9 @@ hal_EfusePowerSwitch_RTL8188E(
if (bWrite) {
/* Enable LDO 2.5V before read/write action */
- tempval = rtw_read8(pAdapter, EFUSE_TEST + 3);
+ tempval = rtw_read8(pAdapter, EFUSE_TEST + 3, &error);
+ if (error)
+ return;
tempval &= 0x0F;
tempval |= (VOLTAGE_V25 << 4);
rtw_write8(pAdapter, EFUSE_TEST + 3, (tempval | 0x80));
@@ -751,7 +847,9 @@ hal_EfusePowerSwitch_RTL8188E(
if (bWrite) {
/* Disable LDO 2.5V after read/write action */
- tempval = rtw_read8(pAdapter, EFUSE_TEST + 3);
+ tempval = rtw_read8(pAdapter, EFUSE_TEST + 3, &error);
+ if (error)
+ return;
rtw_write8(pAdapter, EFUSE_TEST + 3, (tempval & 0x7F));
}
}
@@ -1692,12 +1790,15 @@ static int rtl8188e_Efuse_PgPacketWrite(struct adapter *pAdapter, u8 offset, u8
static struct HAL_VERSION ReadChipVersion8188E(struct adapter *padapter)
{
u32 value32;
- struct HAL_VERSION ChipVersion;
+ struct HAL_VERSION ChipVersion = { };
struct hal_data_8188e *pHalData;
+ int error;
pHalData = GET_HAL_DATA(padapter);
- value32 = rtw_read32(padapter, REG_SYS_CFG);
+ value32 = rtw_read32(padapter, REG_SYS_CFG, &error);
+ if (error)
+ return ChipVersion;
ChipVersion.ICType = CHIP_8188E;
ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
@@ -1784,12 +1885,23 @@ void rtl8188e_stop_thread(struct adapter *padapter)
static void hal_notch_filter_8188e(struct adapter *adapter, bool enable)
{
+ int error;
+ u8 tmp;
+
if (enable) {
DBG_88E("Enable notch filter\n");
- rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) | BIT(1));
+ tmp = rtw_read8(adapter, rOFDM0_RxDSP + 1, &error);
+ if (error)
+ return;
+
+ rtw_write8(adapter, rOFDM0_RxDSP + 1, tmp | BIT(1));
} else {
DBG_88E("Disable notch filter\n");
- rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) & ~BIT(1));
+ tmp = rtw_read8(adapter, rOFDM0_RxDSP + 1, &error);
+ if (error)
+ return;
+
+ rtw_write8(adapter, rOFDM0_RxDSP + 1, TCA_DUMP_FLAGS_TERSE & ~BIT(1));
}
}
void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc)
@@ -1845,8 +1957,12 @@ u8 GetEEPROMSize8188E(struct adapter *padapter)
{
u8 size = 0;
u32 cr;
+ int error;
+
+ cr = rtw_read16(padapter, REG_9346CR, &error);
+ if (error)
+ return size;
- cr = rtw_read16(padapter, REG_9346CR);
/* 6: EEPROM used is 93C46, 4: boot from E-Fuse. */
size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
@@ -1866,12 +1982,16 @@ static s32 _LLTWrite(struct adapter *padapter, u32 address, u32 data)
s32 count = 0;
u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
u16 LLTReg = REG_LLT_INIT;
+ int error;
rtw_write32(padapter, LLTReg, value);
/* polling */
do {
- value = rtw_read32(padapter, LLTReg);
+ value = rtw_read32(padapter, LLTReg, &error);
+ if (error)
+ return _FAIL;
+
if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
break;
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
index 30a9dca8f453..6264778ed9c3 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
@@ -75,8 +75,12 @@ rtl8188e_PHY_QueryBBReg(
)
{
u32 ReturnValue = 0, OriginalValue, BitShift;
+ int error;
+
+ OriginalValue = rtw_read32(Adapter, RegAddr, &error);
+ if (error)
+ return ReturnValue;
- OriginalValue = rtw_read32(Adapter, RegAddr);
BitShift = phy_CalculateBitShift(BitMask);
ReturnValue = (OriginalValue & BitMask) >> BitShift;
return ReturnValue;
@@ -103,9 +107,12 @@ rtl8188e_PHY_QueryBBReg(
void rtl8188e_PHY_SetBBReg(struct adapter *Adapter, u32 RegAddr, u32 BitMask, u32 Data)
{
u32 OriginalValue, BitShift;
+ int error;
if (BitMask != bMaskDWord) { /* if not "double word" write */
- OriginalValue = rtw_read32(Adapter, RegAddr);
+ OriginalValue = rtw_read32(Adapter, RegAddr, &error);
+ if (error)
+ return;
BitShift = phy_CalculateBitShift(BitMask);
Data = ((OriginalValue & (~BitMask)) | (Data << BitShift));
}
@@ -577,11 +584,15 @@ PHY_BBConfig8188E(
struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter);
u32 RegVal;
u8 CrystalCap;
+ int error;
phy_InitBBRFRegisterDefinition(Adapter);
/* Enable BB and RF */
- RegVal = rtw_read16(Adapter, REG_SYS_FUNC_EN);
+ RegVal = rtw_read16(Adapter, REG_SYS_FUNC_EN, &error);
+ if (error)
+ return -FAIL;
+
rtw_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal | BIT(13) | BIT(0) | BIT(1)));
/* 20090923 Joseph: Advised by Steven and Jenyu. Power sequence before init RF. */
@@ -960,6 +971,7 @@ _PHY_SetBWMode92C(
struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter);
u8 regBwOpMode;
u8 regRRSR_RSC;
+ int error;
if (pHalData->rf_chip == RF_PSEUDO_11N)
return;
@@ -975,8 +987,12 @@ _PHY_SetBWMode92C(
/* 3<1>Set MAC register */
/* 3 */
- regBwOpMode = rtw_read8(Adapter, REG_BWOPMODE);
- regRRSR_RSC = rtw_read8(Adapter, REG_RRSR + 2);
+ regBwOpMode = rtw_read8(Adapter, REG_BWOPMODE, &error);
+ if (error)
+ return;
+ regRRSR_RSC = rtw_read8(Adapter, REG_RRSR + 2, &error);
+ if (error)
+ return;
switch (pHalData->CurrentChannelBW) {
case HT_CHANNEL_WIDTH_20:
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_sreset.c b/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
index 16fa249e35d3..1bb86629574d 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
@@ -14,13 +14,16 @@ void rtl8188e_sreset_xmit_status_check(struct adapter *padapter)
{
struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
struct sreset_priv *psrtpriv = &pHalData->srestpriv;
-
+ int error;
unsigned long current_time;
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
unsigned int diff_time;
u32 txdma_status;
- txdma_status = rtw_read32(padapter, REG_TXDMA_STATUS);
+ txdma_status = rtw_read32(padapter, REG_TXDMA_STATUS, &error);
+ if (error)
+ return;
+
if (txdma_status != 0x00) {
DBG_88E("%s REG_TXDMA_STATUS:0x%08x\n", __func__, txdma_status);
rtw_write32(padapter, REG_TXDMA_STATUS, txdma_status);
@@ -49,12 +52,21 @@ void rtl8188e_sreset_linked_status_check(struct adapter *padapter)
{
u32 rx_dma_status = 0;
u8 fw_status = 0;
- rx_dma_status = rtw_read32(padapter, REG_RXDMA_STATUS);
+ int error;
+
+ rx_dma_status = rtw_read32(padapter, REG_RXDMA_STATUS, &error);
+ if (error)
+ return;
+
if (rx_dma_status != 0x00) {
DBG_88E("%s REG_RXDMA_STATUS:0x%08x\n", __func__, rx_dma_status);
rtw_write32(padapter, REG_RXDMA_STATUS, rx_dma_status);
}
- fw_status = rtw_read8(padapter, REG_FMETHR);
+
+ fw_status = rtw_read8(padapter, REG_FMETHR, &error);
+ if (error)
+ return;
+
if (fw_status != 0x00) {
if (fw_status == 1)
DBG_88E("%s REG_FW_STATUS (0x%02x), Read_Efuse_Fail !!\n", __func__, fw_status);
diff --git a/drivers/staging/r8188eu/hal/rtl8188eu_led.c b/drivers/staging/r8188eu/hal/rtl8188eu_led.c
index 452d4bb87aba..2467adb51f7d 100644
--- a/drivers/staging/r8188eu/hal/rtl8188eu_led.c
+++ b/drivers/staging/r8188eu/hal/rtl8188eu_led.c
@@ -14,10 +14,15 @@
void SwLedOn(struct adapter *padapter, struct LED_871x *pLed)
{
u8 LedCfg;
+ int error;
if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
return;
- LedCfg = rtw_read8(padapter, REG_LEDCFG2);
+
+ LedCfg = rtw_read8(padapter, REG_LEDCFG2, &error);
+ if (error)
+ return;
+
switch (pLed->LedPin) {
case LED_PIN_LED0:
rtw_write8(padapter, REG_LEDCFG2, (LedCfg & 0xf0) | BIT(5) | BIT(6)); /* SW control led0 on. */
@@ -37,11 +42,14 @@ void SwLedOff(struct adapter *padapter, struct LED_871x *pLed)
{
u8 LedCfg;
struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
+ int error;
if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
goto exit;
- LedCfg = rtw_read8(padapter, REG_LEDCFG2);/* 0x4E */
+ LedCfg = rtw_read8(padapter, REG_LEDCFG2, &error);/* 0x4E */
+ if (error)
+ return;
switch (pLed->LedPin) {
case LED_PIN_LED0:
@@ -49,7 +57,10 @@ void SwLedOff(struct adapter *padapter, struct LED_871x *pLed)
/* Open-drain arrangement for controlling the LED) */
LedCfg &= 0x90; /* Set to software control. */
rtw_write8(padapter, REG_LEDCFG2, (LedCfg | BIT(3)));
- LedCfg = rtw_read8(padapter, REG_MAC_PINMUX_CFG);
+ LedCfg = rtw_read8(padapter, REG_MAC_PINMUX_CFG, &error);
+ if (error)
+ return;
+
LedCfg &= 0xFE;
rtw_write8(padapter, REG_MAC_PINMUX_CFG, LedCfg);
} else {
diff --git a/drivers/staging/r8188eu/hal/usb_halinit.c b/drivers/staging/r8188eu/hal/usb_halinit.c
index 5cdabf43d4fd..73ef2e0ead19 100644
--- a/drivers/staging/r8188eu/hal/usb_halinit.c
+++ b/drivers/staging/r8188eu/hal/usb_halinit.c
@@ -90,6 +90,8 @@ static u32 rtl8188eu_InitPowerOn(struct adapter *adapt)
u16 value16;
/* HW Power on sequence */
struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
+ int error;
+
if (haldata->bMacPwrCtrlOn)
return _SUCCESS;
@@ -103,7 +105,10 @@ static u32 rtl8188eu_InitPowerOn(struct adapter *adapt)
rtw_write16(adapt, REG_CR, 0x00); /* suggseted by zhouzhou, by page, 20111230 */
/* Enable MAC DMA/WMAC/SCHEDULE/SEC block */
- value16 = rtw_read16(adapt, REG_CR);
+ value16 = rtw_read16(adapt, REG_CR, &error);
+ if (error)
+ return _FAIL;
+
value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN
| PROTOCOL_EN | SCHEDULE_EN | ENSEC | CALTMR_EN);
/* for SDIO - Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy. Added by tynli. 2011.08.31. */
@@ -120,6 +125,7 @@ static void _InitInterrupt(struct adapter *Adapter)
u32 imr, imr_ex;
u8 usb_opt;
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
+ int error;
/* HISR write one to clear */
rtw_write32(Adapter, REG_HISR_88E, 0xFFFFFFFF);
@@ -135,7 +141,9 @@ static void _InitInterrupt(struct adapter *Adapter)
/* REG_USB_SPECIAL_OPTION - BIT(4) */
/* 0; Use interrupt endpoint to upload interrupt pkt */
/* 1; Use bulk endpoint to upload interrupt pkt, */
- usb_opt = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION);
+ usb_opt = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION, &error);
+ if (error)
+ return;
if (!adapter_to_dvobj(Adapter)->ishighspeed)
usb_opt = usb_opt & (~INT_BULK_SEL);
@@ -204,7 +212,14 @@ static void _InitNormalChipRegPriority(struct adapter *Adapter, u16 beQ,
u16 bkQ, u16 viQ, u16 voQ, u16 mgtQ,
u16 hiQ)
{
- u16 value16 = (rtw_read16(Adapter, REG_TRXDMA_CTRL) & 0x7);
+ u16 value16;
+ int error;
+
+ value16 = rtw_read16(Adapter, REG_TRXDMA_CTRL, &error);
+ if (error)
+ return;
+
+ value16 &= 0x7;
value16 |= _TXDMA_BEQ_MAP(beQ) | _TXDMA_BKQ_MAP(bkQ) |
_TXDMA_VIQ_MAP(viQ) | _TXDMA_VOQ_MAP(voQ) |
@@ -323,8 +338,11 @@ static void _InitQueuePriority(struct adapter *Adapter)
static void _InitNetworkType(struct adapter *Adapter)
{
u32 value32;
+ int error;
- value32 = rtw_read32(Adapter, REG_CR);
+ value32 = rtw_read32(Adapter, REG_CR, &error);
+ if (error)
+ return;
/* TODO: use the other function to set network type */
value32 = (value32 & ~MASK_NETTYPE) | _NETTYPE(NT_LINK_AP);
@@ -366,9 +384,13 @@ static void _InitAdaptiveCtrl(struct adapter *Adapter)
{
u16 value16;
u32 value32;
+ int error;
/* Response Rate Set */
- value32 = rtw_read32(Adapter, REG_RRSR);
+ value32 = rtw_read32(Adapter, REG_RRSR, &error);
+ if (error)
+ return;
+
value32 &= ~RATE_BITMAP_ALL;
value32 |= RATE_RRSR_CCK_ONLY_1M;
rtw_write32(Adapter, REG_RRSR, value32);
@@ -435,8 +457,11 @@ static void _InitRxSetting(struct adapter *Adapter)
static void _InitRetryFunction(struct adapter *Adapter)
{
u8 value8;
+ int error;
- value8 = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL);
+ value8 = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL, &error);
+ if (error)
+ return;
value8 |= EN_AMPDU_RTY_NEW;
rtw_write8(Adapter, REG_FWHW_TXQ_CTRL, value8);
@@ -463,12 +488,16 @@ static void usb_AggSettingTxUpdate(struct adapter *Adapter)
{
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
u32 value32;
+ int error;
if (Adapter->registrypriv.wifi_spec)
haldata->UsbTxAggMode = false;
if (haldata->UsbTxAggMode) {
- value32 = rtw_read32(Adapter, REG_TDECTRL);
+ value32 = rtw_read32(Adapter, REG_TDECTRL, &error);
+ if (error)
+ return;
+
value32 = value32 & ~(BLK_DESC_NUM_MASK << BLK_DESC_NUM_SHIFT);
value32 |= ((haldata->UsbTxAggDescNum & BLK_DESC_NUM_MASK) << BLK_DESC_NUM_SHIFT);
@@ -499,9 +528,14 @@ usb_AggSettingRxUpdate(
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
u8 valueDMA;
u8 valueUSB;
+ int error;
- valueDMA = rtw_read8(Adapter, REG_TRXDMA_CTRL);
- valueUSB = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION);
+ valueDMA = rtw_read8(Adapter, REG_TRXDMA_CTRL, &error);
+ if (error)
+ return;
+ valueUSB = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION, &error);
+ if (error)
+ return;
switch (haldata->UsbRxAggMode) {
case USB_RX_AGG_DMA:
@@ -589,6 +623,7 @@ static void _InitOperationMode(struct adapter *Adapter)
static void _InitBeaconParameters(struct adapter *Adapter)
{
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
+ int error;
rtw_write16(Adapter, REG_BCN_CTRL, 0x1010);
@@ -601,11 +636,11 @@ static void _InitBeaconParameters(struct adapter *Adapter)
/* beacause test chip does not contension before sending beacon. by tynli. 2009.11.03 */
rtw_write16(Adapter, REG_BCNTCFG, 0x660F);
- haldata->RegBcnCtrlVal = rtw_read8(Adapter, REG_BCN_CTRL);
- haldata->RegTxPause = rtw_read8(Adapter, REG_TXPAUSE);
- haldata->RegFwHwTxQCtrl = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL + 2);
- haldata->RegReg542 = rtw_read8(Adapter, REG_TBTT_PROHIBIT + 2);
- haldata->RegCR_1 = rtw_read8(Adapter, REG_CR + 1);
+ haldata->RegBcnCtrlVal = rtw_read8(Adapter, REG_BCN_CTRL, &error);
+ haldata->RegTxPause = rtw_read8(Adapter, REG_TXPAUSE, &error);
+ haldata->RegFwHwTxQCtrl = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL + 2, &error);
+ haldata->RegReg542 = rtw_read8(Adapter, REG_TBTT_PROHIBIT + 2, &error);
+ haldata->RegCR_1 = rtw_read8(Adapter, REG_CR + 1, &error);
}
static void _BeaconFunctionEnable(struct adapter *Adapter,
@@ -631,12 +666,18 @@ enum {
static void _InitAntenna_Selection(struct adapter *Adapter)
{
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
+ int error;
+ u32 tmp;
if (haldata->AntDivCfg == 0)
return;
DBG_88E("==> %s ....\n", __func__);
- rtw_write32(Adapter, REG_LEDCFG0, rtw_read32(Adapter, REG_LEDCFG0) | BIT(23));
+ tmp = rtw_read32(Adapter, REG_LEDCFG0, &error);
+ if (error)
+ return;
+
+ rtw_write32(Adapter, REG_LEDCFG0, tmp | BIT(23));
PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, BIT(13), 0x01);
if (PHY_QueryBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, 0x300) == Antenna_A)
@@ -665,14 +706,22 @@ enum rt_rf_power_state RfOnOffDetect(struct adapter *adapt)
{
u8 val8;
enum rt_rf_power_state rfpowerstate = rf_off;
+ int error;
if (adapt->pwrctrlpriv.bHWPowerdown) {
- val8 = rtw_read8(adapt, REG_HSISR);
+ val8 = rtw_read8(adapt, REG_HSISR, &error);
+ if (error)
+ return rfpowerstate;
DBG_88E("pwrdown, 0x5c(BIT(7))=%02x\n", val8);
rfpowerstate = (val8 & BIT(7)) ? rf_off : rf_on;
} else { /* rf on/off */
- rtw_write8(adapt, REG_MAC_PINMUX_CFG, rtw_read8(adapt, REG_MAC_PINMUX_CFG) & ~(BIT(3)));
- val8 = rtw_read8(adapt, REG_GPIO_IO_SEL);
+ val8 = rtw_read8(adapt, REG_MAC_PINMUX_CFG, &error);
+ if (error)
+ return rfpowerstate;
+ rtw_write8(adapt, REG_MAC_PINMUX_CFG, val8 & ~(BIT(3)));
+ val8 = rtw_read8(adapt, REG_GPIO_IO_SEL, &error);
+ if (error)
+ return rfpowerstate;
DBG_88E("GPIO_IN=%02x\n", val8);
rfpowerstate = (val8 & BIT(3)) ? rf_on : rf_off;
}
@@ -683,12 +732,14 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
{
u8 value8 = 0;
u16 value16;
+ u32 value32;
u8 txpktbuf_bndy;
u32 status = _SUCCESS;
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv;
struct registry_priv *pregistrypriv = &Adapter->registrypriv;
u32 init_start_time = jiffies;
+ int error;
#define HAL_INIT_PROFILE_TAG(stage) do {} while (0)
@@ -826,7 +877,12 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
/* Hw bug which Hw initials RxFF boundary size to a value which is larger than the real Rx buffer size in 88E. */
/* */
/* Enable MACTXEN/MACRXEN block */
- value16 = rtw_read16(Adapter, REG_CR);
+ value16 = rtw_read16(Adapter, REG_CR, &error);
+ if (error) {
+ status = _FAIL;
+ goto exit;
+ }
+
value16 |= (MACTXEN | MACRXEN);
rtw_write8(Adapter, REG_CR, value16);
@@ -835,7 +891,11 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
/* Enable TX Report */
/* Enable Tx Report Timer */
- value8 = rtw_read8(Adapter, REG_TX_RPT_CTRL);
+ value8 = rtw_read8(Adapter, REG_TX_RPT_CTRL, &error);
+ if (error) {
+ status = _FAIL;
+ goto exit;
+ }
rtw_write8(Adapter, REG_TX_RPT_CTRL, (value8 | BIT(1) | BIT(0)));
/* Set MAX RPT MACID */
rtw_write8(Adapter, REG_TX_RPT_CTRL + 1, 2);/* FOR sta mode ,0: bc/mc ,1:AP */
@@ -910,7 +970,13 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
rtw_write16(Adapter, REG_TX_RPT_TIME, 0x3DF0);
/* enable tx DMA to drop the redundate data of packet */
- rtw_write16(Adapter, REG_TXDMA_OFFSET_CHK, (rtw_read16(Adapter, REG_TXDMA_OFFSET_CHK) | DROP_DATA_EN));
+ value16 = rtw_read16(Adapter, REG_TXDMA_OFFSET_CHK, &error);
+ if (error) {
+ status = _FAIL;
+ goto exit;
+ }
+
+ rtw_write16(Adapter, REG_TXDMA_OFFSET_CHK, (value16 | DROP_DATA_EN));
HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_IQK);
/* 2010/08/26 MH Merge from 8192CE. */
@@ -936,7 +1002,13 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
rtw_write8(Adapter, REG_USB_HRPWM, 0);
/* ack for xmit mgmt frames. */
- rtw_write32(Adapter, REG_FWHW_TXQ_CTRL, rtw_read32(Adapter, REG_FWHW_TXQ_CTRL) | BIT(12));
+ value32 = rtw_read32(Adapter, REG_FWHW_TXQ_CTRL, &error);
+ if (error) {
+ status = _FAIL;
+ goto exit;
+ }
+
+ rtw_write32(Adapter, REG_FWHW_TXQ_CTRL, value32 | BIT(12));
exit:
HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_END);
@@ -962,9 +1034,13 @@ static void CardDisableRTL8188EU(struct adapter *Adapter)
{
u8 val8;
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
+ int error;
/* Stop Tx Report Timer. 0x4EC[Bit1]=b'0 */
- val8 = rtw_read8(Adapter, REG_TX_RPT_CTRL);
+ val8 = rtw_read8(Adapter, REG_TX_RPT_CTRL, &error);
+ if (error)
+ return;
+
rtw_write8(Adapter, REG_TX_RPT_CTRL, val8 & (~BIT(1)));
/* stop rx */
@@ -975,10 +1051,16 @@ static void CardDisableRTL8188EU(struct adapter *Adapter)
/* 2. 0x1F[7:0] = 0 turn off RF */
- val8 = rtw_read8(Adapter, REG_MCUFWDL);
+ val8 = rtw_read8(Adapter, REG_MCUFWDL, &error);
+ if (error)
+ return;
+
if ((val8 & RAM_DL_SEL) && Adapter->bFWReady) { /* 8051 RAM code */
/* Reset MCU 0x2[10]=0. */
- val8 = rtw_read8(Adapter, REG_SYS_FUNC_EN + 1);
+ val8 = rtw_read8(Adapter, REG_SYS_FUNC_EN + 1, &error);
+ if (error)
+ return;
+
val8 &= ~BIT(2); /* 0x2[10], FEN_CPUEN */
rtw_write8(Adapter, REG_SYS_FUNC_EN + 1, val8);
}
@@ -988,26 +1070,44 @@ static void CardDisableRTL8188EU(struct adapter *Adapter)
/* YJ,add,111212 */
/* Disable 32k */
- val8 = rtw_read8(Adapter, REG_32K_CTRL);
+ val8 = rtw_read8(Adapter, REG_32K_CTRL, &error);
+ if (error)
+ return;
+
rtw_write8(Adapter, REG_32K_CTRL, val8 & (~BIT(0)));
/* Card disable power action flow */
HalPwrSeqCmdParsing(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, Rtl8188E_NIC_DISABLE_FLOW);
/* Reset MCU IO Wrapper */
- val8 = rtw_read8(Adapter, REG_RSV_CTRL + 1);
+ val8 = rtw_read8(Adapter, REG_RSV_CTRL + 1, &error);
+ if (error)
+ return;
+
rtw_write8(Adapter, REG_RSV_CTRL + 1, (val8 & (~BIT(3))));
- val8 = rtw_read8(Adapter, REG_RSV_CTRL + 1);
+ val8 = rtw_read8(Adapter, REG_RSV_CTRL + 1, &error);
+ if (error)
+ return;
+
rtw_write8(Adapter, REG_RSV_CTRL + 1, val8 | BIT(3));
/* YJ,test add, 111207. For Power Consumption. */
- val8 = rtw_read8(Adapter, GPIO_IN);
+ val8 = rtw_read8(Adapter, GPIO_IN, &error);
+ if (error)
+ return;
+
rtw_write8(Adapter, GPIO_OUT, val8);
rtw_write8(Adapter, GPIO_IO_SEL, 0xFF);/* Reg0x46 */
- val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL);
+ val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL, &error);
+ if (error)
+ return;
+
rtw_write8(Adapter, REG_GPIO_IO_SEL, (val8 << 4));
- val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL + 1);
+ val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL + 1, &error);
+ if (error)
+ return;
+
rtw_write8(Adapter, REG_GPIO_IO_SEL + 1, val8 | 0x0F);/* Reg0x43 */
rtw_write32(Adapter, REG_BB_PAD_CTRL, 0x00080808);/* set LNA ,TRSW,EX_PA Pin to output mode */
haldata->bMacPwrCtrlOn = false;
@@ -1181,9 +1281,13 @@ static void _ReadPROMContent(
{
struct eeprom_priv *eeprom = GET_EEPROM_EFUSE_PRIV(Adapter);
u8 eeValue;
+ int error;
/* check system boot selection */
- eeValue = rtw_read8(Adapter, REG_9346CR);
+ eeValue = rtw_read8(Adapter, REG_9346CR, &error);
+ if (error)
+ return;
+
eeprom->EepromOrEfuse = (eeValue & BOOT_FROM_EEPROM) ? true : false;
eeprom->bautoload_fail_flag = (eeValue & EEPROM_EN) ? false : true;
@@ -1262,12 +1366,23 @@ static void hw_var_set_opmode(struct adapter *Adapter, u8 variable, u8 *val)
{
u8 val8;
u8 mode = *((u8 *)val);
+ u8 tmp;
+ int error;
/* disable Port0 TSF update */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4));
+ tmp = rtw_read8(Adapter, REG_BCN_CTRL, &error);
+ if (error)
+ return;
+
+ rtw_write8(Adapter, REG_BCN_CTRL, tmp | BIT(4));
/* set net_type */
- val8 = rtw_read8(Adapter, MSR) & 0x0c;
+ val8 = rtw_read8(Adapter, MSR, &error);
+ if (error)
+ return;
+
+ val8 &= 0x0c;
+
val8 |= mode;
rtw_write8(Adapter, MSR, val8);
@@ -1304,14 +1419,22 @@ static void hw_var_set_opmode(struct adapter *Adapter, u8 variable, u8 *val)
rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0));
/* BIT(3) - If set 0, hw will clr bcnq when tx becon ok/fail or port 0 */
- rtw_write8(Adapter, REG_MBID_NUM, rtw_read8(Adapter, REG_MBID_NUM) | BIT(3) | BIT(4));
+ tmp = rtw_read8(Adapter, REG_MBID_NUM, &error);
+ if (error)
+ return;
+
+ rtw_write8(Adapter, REG_MBID_NUM, tmp | BIT(3) | BIT(4));
/* enable BCN0 Function for if1 */
/* don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received) */
rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT0_NORMAL_CHIP | EN_BCN_FUNCTION | BIT(1)));
/* dis BCN1 ATIM WND if if2 is station */
- rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1) | BIT(0));
+ tmp = rtw_read8(Adapter, REG_BCN_CTRL_1, &error);
+ if (error)
+ return;
+
+ rtw_write8(Adapter, REG_BCN_CTRL_1, tmp | BIT(0));
}
}
@@ -1340,13 +1463,20 @@ static void hw_var_set_bssid(struct adapter *Adapter, u8 variable, u8 *val)
static void hw_var_set_bcn_func(struct adapter *Adapter, u8 variable, u8 *val)
{
u32 bcn_ctrl_reg;
+ u8 tmp;
+ int error;
bcn_ctrl_reg = REG_BCN_CTRL;
- if (*((u8 *)val))
+ if (*((u8 *)val)) {
rtw_write8(Adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
- else
- rtw_write8(Adapter, bcn_ctrl_reg, rtw_read8(Adapter, bcn_ctrl_reg) & (~(EN_BCN_FUNCTION | EN_TXBCN_RPT)));
+ } else {
+ tmp = rtw_read8(Adapter, bcn_ctrl_reg, &error);
+ if (error)
+ return;
+
+ rtw_write8(Adapter, bcn_ctrl_reg, tmp & (~(EN_BCN_FUNCTION | EN_TXBCN_RPT)));
+ }
}
static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
@@ -1354,13 +1484,21 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
struct dm_priv *pdmpriv = &haldata->dmpriv;
struct odm_dm_struct *podmpriv = &haldata->odmpriv;
+ int error;
+ u32 val32;
+ u8 val8;
switch (variable) {
case HW_VAR_MEDIA_STATUS:
{
u8 val8;
- val8 = rtw_read8(Adapter, MSR) & 0x0c;
+ val8 = rtw_read8(Adapter, MSR, &error);
+ if (error)
+ return;
+
+ val8 &= 0x0c;
+
val8 |= *((u8 *)val);
rtw_write8(Adapter, MSR, val8);
}
@@ -1369,7 +1507,12 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
{
u8 val8;
- val8 = rtw_read8(Adapter, MSR) & 0x03;
+ val8 = rtw_read8(Adapter, MSR, &error);
+ if (error)
+ return;
+
+ val8 &= 0x03;
+
val8 |= *((u8 *)val) << 2;
rtw_write8(Adapter, MSR, val8);
}
@@ -1407,7 +1550,12 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
/* Set RRSR rate table. */
rtw_write8(Adapter, REG_RRSR, BrateCfg & 0xff);
rtw_write8(Adapter, REG_RRSR + 1, (BrateCfg >> 8) & 0xff);
- rtw_write8(Adapter, REG_RRSR + 2, rtw_read8(Adapter, REG_RRSR + 2) & 0xf0);
+
+ val8 = rtw_read8(Adapter, REG_RRSR + 2, &error);
+ if (error)
+ return;
+
+ rtw_write8(Adapter, REG_RRSR + 2, val8 & 0xf0);
/* Set RTS initial rate */
while (BrateCfg > 0x1) {
@@ -1437,13 +1585,19 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
StopTxBeacon(Adapter);
/* disable related TSF function */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(3)));
+ val8 = rtw_read8(Adapter, REG_BCN_CTRL, &error);
+ if (error)
+ return;
+ rtw_write8(Adapter, REG_BCN_CTRL, val8 & (~BIT(3)));
rtw_write32(Adapter, REG_TSFTR, tsf);
rtw_write32(Adapter, REG_TSFTR + 4, tsf >> 32);
/* enable related TSF function */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(3));
+ val8 = rtw_read8(Adapter, REG_BCN_CTRL, &error);
+ if (error)
+ return;
+ rtw_write8(Adapter, REG_BCN_CTRL, val8 | BIT(3));
if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
ResumeTxBeacon(Adapter);
@@ -1451,11 +1605,17 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
break;
case HW_VAR_CHECK_BSSID:
if (*((u8 *)val)) {
- rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+ val32 = rtw_read32(Adapter, REG_RCR, &error);
+ if (error)
+ return;
+
+ rtw_write32(Adapter, REG_RCR, val32 | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
} else {
- u32 val32;
- val32 = rtw_read32(Adapter, REG_RCR);
+ val32 = rtw_read32(Adapter, REG_RCR, &error);
+
+ if (error)
+ return;
val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
@@ -1471,19 +1631,29 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
rtw_write8(Adapter, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
/* disable update TSF */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4));
+ val8 = rtw_read8(Adapter, REG_BCN_CTRL, &error);
+ if (error)
+ return;
+ rtw_write8(Adapter, REG_BCN_CTRL, val8 | BIT(4));
break;
case HW_VAR_MLME_SITESURVEY:
if (*((u8 *)val)) { /* under sitesurvey */
/* config RCR to receive different BSSID & not to receive data frame */
- u32 v = rtw_read32(Adapter, REG_RCR);
+ u32 v = rtw_read32(Adapter, REG_RCR, &error);
+
+ if (error)
+ return;
+
v &= ~(RCR_CBSSID_BCN);
rtw_write32(Adapter, REG_RCR, v);
/* reject all data frame */
rtw_write16(Adapter, REG_RXFLTMAP2, 0x00);
/* disable update TSF */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4));
+ val8 = rtw_read8(Adapter, REG_BCN_CTRL, &error);
+ if (error)
+ return;
+ rtw_write8(Adapter, REG_BCN_CTRL, val8 | BIT(4));
} else { /* sitesurvey done */
struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
@@ -1494,21 +1664,39 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
/* enable update TSF */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4)));
+ val8 = rtw_read8(Adapter, REG_BCN_CTRL, &error);
+ if (error)
+ return;
+ rtw_write8(Adapter, REG_BCN_CTRL, val8 & (~BIT(4)));
} else if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
/* enable update TSF */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4)));
+ val8 = rtw_read8(Adapter, REG_BCN_CTRL, &error);
+ if (error)
+ return;
+ rtw_write8(Adapter, REG_BCN_CTRL, val8 & (~BIT(4)));
}
if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
- rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN);
+ val32 = rtw_read32(Adapter, REG_RCR, &error);
+ if (error)
+ return;
+
+ rtw_write32(Adapter, REG_RCR, val32 | RCR_CBSSID_BCN);
} else {
if (Adapter->in_cta_test) {
- u32 v = rtw_read32(Adapter, REG_RCR);
+ u32 v = rtw_read32(Adapter, REG_RCR, &error);
+
+ if (error)
+ return;
+
v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* RCR_ADF */
rtw_write32(Adapter, REG_RCR, v);
} else {
- rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN);
+ val32 = rtw_read32(Adapter, REG_RCR, &error);
+ if (error)
+ return;
+
+ rtw_write32(Adapter, REG_RCR, val32 | RCR_CBSSID_BCN);
}
}
}
@@ -1524,11 +1712,20 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
if (Adapter->in_cta_test) {
- u32 v = rtw_read32(Adapter, REG_RCR);
+ u32 v = rtw_read32(Adapter, REG_RCR, &error);
+
+ if (error)
+ return;
+
v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* RCR_ADF */
rtw_write32(Adapter, REG_RCR, v);
} else {
- rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+ val32 = rtw_read32(Adapter, REG_RCR, &error);
+
+ if (error)
+ return;
+
+ rtw_write32(Adapter, REG_RCR, val32 | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
}
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
@@ -1541,7 +1738,10 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
} else if (type == 2) {
/* sta add event call back */
/* enable update TSF */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4)));
+ val8 = rtw_read8(Adapter, REG_BCN_CTRL, &error);
+ if (error)
+ return;
+ rtw_write8(Adapter, REG_BCN_CTRL, val8 & (~BIT(4)));
if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
RetryLimit = 0x7;
@@ -1671,7 +1871,10 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
case HW_VAR_ACM_CTRL:
{
u8 acm_ctrl = *((u8 *)val);
- u8 AcmCtrl = rtw_read8(Adapter, REG_ACMHWCTRL);
+ u8 AcmCtrl = rtw_read8(Adapter, REG_ACMHWCTRL, &error);
+
+ if (error)
+ return;
if (acm_ctrl > 1)
AcmCtrl = AcmCtrl | 0x1;
@@ -1719,7 +1922,11 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
}
if (MinSpacingToSet < SecMinSpace)
MinSpacingToSet = SecMinSpace;
- rtw_write8(Adapter, REG_AMPDU_MIN_SPACE, (rtw_read8(Adapter, REG_AMPDU_MIN_SPACE) & 0xf8) | MinSpacingToSet);
+
+ val8 = rtw_read8(Adapter, REG_AMPDU_MIN_SPACE, &error);
+ if (error)
+ return;
+ rtw_write8(Adapter, REG_AMPDU_MIN_SPACE, (val8 & 0xf8) | MinSpacingToSet);
}
}
break;
@@ -1826,18 +2033,31 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
{
struct pwrctrl_priv *pwrpriv = &Adapter->pwrctrlpriv;
u8 trycnt = 100;
+ u32 tmp;
/* pause tx */
rtw_write8(Adapter, REG_TXPAUSE, 0xff);
/* keep sn */
- Adapter->xmitpriv.nqos_ssn = rtw_read16(Adapter, REG_NQOS_SEQ);
+ tmp = rtw_read16(Adapter, REG_NQOS_SEQ, &error);
+ if (error)
+ return;
+
+ Adapter->xmitpriv.nqos_ssn = (u16) tmp;
if (!pwrpriv->bkeepfwalive) {
/* RX DMA stop */
- rtw_write32(Adapter, REG_RXPKT_NUM, (rtw_read32(Adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
+ tmp = rtw_read32(Adapter, REG_RXPKT_NUM, &error);
+ if (error)
+ return;
+
+ rtw_write32(Adapter, REG_RXPKT_NUM, tmp | RW_RELEASE_EN);
do {
- if (!(rtw_read32(Adapter, REG_RXPKT_NUM) & RXDMA_IDLE))
+ tmp = rtw_read32(Adapter, REG_RXPKT_NUM, &error);
+ if (error)
+ continue;
+
+ if (!(tmp & RXDMA_IDLE))
break;
} while (trycnt--);
if (trycnt == 0)
@@ -1868,7 +2088,10 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
break;
case HW_VAR_BCN_VALID:
/* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
- rtw_write8(Adapter, REG_TDECTRL + 2, rtw_read8(Adapter, REG_TDECTRL + 2) | BIT(0));
+ val8 = rtw_read8(Adapter, REG_TDECTRL + 2, &error);
+ if (error)
+ return;
+ rtw_write8(Adapter, REG_TDECTRL + 2, val8 | BIT(0));
break;
default:
break;
@@ -1880,17 +2103,26 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
{
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
struct odm_dm_struct *podmpriv = &haldata->odmpriv;
+ int error;
+ u32 tmp;
switch (variable) {
case HW_VAR_BASIC_RATE:
*((u16 *)(val)) = haldata->BasicRateSet;
fallthrough;
case HW_VAR_TXPAUSE:
- val[0] = rtw_read8(Adapter, REG_TXPAUSE);
+ tmp = rtw_read8(Adapter, REG_TXPAUSE, &error);
+ if (error)
+ return;
+
+ val[0] = tmp;
break;
case HW_VAR_BCN_VALID:
/* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2 */
- val[0] = (BIT(0) & rtw_read8(Adapter, REG_TDECTRL + 2)) ? true : false;
+ tmp = rtw_read8(Adapter, REG_TDECTRL + 2, &error);
+ if (error)
+ return;
+ val[0] = (BIT(0) & tmp) ? true : false;
break;
case HW_VAR_DM_FLAG:
val[0] = podmpriv->SupportAbility;
@@ -1907,7 +2139,9 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
val[0] = true;
} else {
u32 valRCR;
- valRCR = rtw_read32(Adapter, REG_RCR);
+ valRCR = rtw_read32(Adapter, REG_RCR, &error);
+ if (error)
+ return;
valRCR &= 0x00070000;
if (valRCR)
val[0] = false;
@@ -1926,7 +2160,11 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
*val = haldata->bMacPwrCtrlOn;
break;
case HW_VAR_CHK_HI_QUEUE_EMPTY:
- *val = ((rtw_read32(Adapter, REG_HGQ_INFORMATION) & 0x0000ff00) == 0) ? true : false;
+ tmp = rtw_read32(Adapter, REG_HGQ_INFORMATION, &error);
+ if (error)
+ return;
+
+ *val = ((tmp & 0x0000ff00) == 0) ? true : false;
break;
default:
break;
@@ -2041,6 +2279,7 @@ static u8 SetHalDefVar8188EUsb(struct adapter *Adapter, enum hal_def_variable eV
{
u8 dm_func = *((u8 *)pValue);
struct odm_dm_struct *podmpriv = &haldata->odmpriv;
+ int error;
if (dm_func == 0) { /* disable all dynamic func */
podmpriv->SupportAbility = DYNAMIC_FUNC_DISABLE;
@@ -2058,7 +2297,12 @@ static u8 SetHalDefVar8188EUsb(struct adapter *Adapter, enum hal_def_variable eV
} else if (dm_func == 6) {/* turn on all dynamic func */
if (!(podmpriv->SupportAbility & DYNAMIC_BB_DIG)) {
struct rtw_dig *pDigTable = &podmpriv->DM_DigTable;
- pDigTable->CurIGValue = rtw_read8(Adapter, 0xc50);
+ u8 tmp = rtw_read8(Adapter, 0xc50, &error);
+
+ if (error)
+ return _FAIL;
+
+ pDigTable->CurIGValue = tmp;
}
podmpriv->SupportAbility = DYNAMIC_ALL_FUNC_ENABLE;
DBG_88E("==> Turn on all dynamic function...\n");
@@ -2168,6 +2412,8 @@ static void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
u32 bcn_ctrl_reg = REG_BCN_CTRL;
+ int error;
+ u8 tmp;
/* reset TSF, enable update TSF, correcting TSF On Beacon */
/* BCN interval */
@@ -2178,7 +2424,9 @@ static void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
rtw_write8(adapt, REG_SLOT, 0x09);
- value32 = rtw_read32(adapt, REG_TCR);
+ value32 = rtw_read32(adapt, REG_TCR, &error);
+ if (error)
+ return;
value32 &= ~TSFRST;
rtw_write32(adapt, REG_TCR, value32);
@@ -2193,7 +2441,11 @@ static void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
ResumeTxBeacon(adapt);
- rtw_write8(adapt, bcn_ctrl_reg, rtw_read8(adapt, bcn_ctrl_reg) | BIT(1));
+ tmp = rtw_read8(adapt, bcn_ctrl_reg, &error);
+ if (error)
+ return;
+
+ rtw_write8(adapt, bcn_ctrl_reg, tmp | BIT(1));
}
static void rtl8188eu_init_default_value(struct adapter *adapt)
diff --git a/drivers/staging/r8188eu/hal/usb_ops_linux.c b/drivers/staging/r8188eu/hal/usb_ops_linux.c
index 953fa05dc30c..980af6c02be5 100644
--- a/drivers/staging/r8188eu/hal/usb_ops_linux.c
+++ b/drivers/staging/r8188eu/hal/usb_ops_linux.c
@@ -101,29 +101,31 @@ static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u16 value, void *pdata,
return status;
}
-static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr)
+static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr, int *error)
{
u8 requesttype;
u16 wvalue;
u16 len;
u8 data = 0;
+ int res;
-
+ if (unlikely(!error))
+ WARN_ON_ONCE("r8188eu: Reading w/o error checking is bad idea\n");
requesttype = 0x01;/* read_in */
wvalue = (u16)(addr & 0x0000ffff);
len = 1;
- usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
-
-
+ res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
+ if (likely(error))
+ *error = res < 0? res: 0;
return data;
}
-static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
+static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr, int *error)
{
u8 requesttype;
u16 wvalue;
@@ -138,7 +140,7 @@ static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
return (u16)(le32_to_cpu(data) & 0xffff);
}
-static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
+static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr, int *error)
{
u8 requesttype;
u16 wvalue;
diff --git a/drivers/staging/r8188eu/include/rtw_io.h b/drivers/staging/r8188eu/include/rtw_io.h
index f1b3074fa075..7933c267b130 100644
--- a/drivers/staging/r8188eu/include/rtw_io.h
+++ b/drivers/staging/r8188eu/include/rtw_io.h
@@ -85,9 +85,9 @@ struct intf_hdl;
struct io_queue;
struct _io_ops {
- u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr);
- u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
- u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
+ u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr, int *error);
+ u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr, int *error);
+ u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr, int *error);
int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
@@ -248,9 +248,9 @@ void unregister_intf_hdl(struct intf_hdl *pintfhdl);
void _rtw_attrib_read(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
void _rtw_attrib_write(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
-u8 _rtw_read8(struct adapter *adapter, u32 addr);
-u16 _rtw_read16(struct adapter *adapter, u32 addr);
-u32 _rtw_read32(struct adapter *adapter, u32 addr);
+u8 _rtw_read8(struct adapter *adapter, u32 addr, int *error);
+u16 _rtw_read16(struct adapter *adapter, u32 addr, int *error);
+u32 _rtw_read32(struct adapter *adapter, u32 addr, int *error);
void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
void _rtw_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
void _rtw_read_port_cancel(struct adapter *adapter);
@@ -270,9 +270,9 @@ u32 _rtw_write_port_and_wait(struct adapter *adapter, u32 addr, u32 cnt,
u8 *pmem, int timeout_ms);
void _rtw_write_port_cancel(struct adapter *adapter);
-#define rtw_read8(adapter, addr) _rtw_read8((adapter), (addr))
-#define rtw_read16(adapter, addr) _rtw_read16((adapter), (addr))
-#define rtw_read32(adapter, addr) _rtw_read32((adapter), (addr))
+#define rtw_read8(adapter, addr, err) _rtw_read8((adapter), (addr), (err))
+#define rtw_read16(adapter, addr, err) _rtw_read16((adapter), (addr), (err))
+#define rtw_read32(adapter, addr, err) _rtw_read32((adapter), (addr), (err))
#define rtw_read_mem(adapter, addr, cnt, mem) \
_rtw_read_mem((adapter), (addr), (cnt), (mem))
#define rtw_read_port(adapter, addr, cnt, mem) \
diff --git a/drivers/staging/r8188eu/os_dep/ioctl_linux.c b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
index ab4a9200f079..f5ec1daf1c30 100644
--- a/drivers/staging/r8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
@@ -2074,6 +2074,7 @@ static int rtw_wx_read32(struct net_device *dev,
u32 data32;
u32 bytes;
u8 *ptmp;
+ int error;
padapter = (struct adapter *)rtw_netdev_priv(dev);
p = &wrqu->data;
@@ -2093,15 +2094,21 @@ static int rtw_wx_read32(struct net_device *dev,
switch (bytes) {
case 1:
- data32 = rtw_read8(padapter, addr);
+ data32 = rtw_read8(padapter, addr, &error);
+ if (error)
+ goto end;
sprintf(extra, "0x%02X", data32);
break;
case 2:
- data32 = rtw_read16(padapter, addr);
+ data32 = rtw_read16(padapter, addr, &error);
+ if (error)
+ goto end;
sprintf(extra, "0x%04X", data32);
break;
case 4:
- data32 = rtw_read32(padapter, addr);
+ data32 = rtw_read32(padapter, addr, &error);
+ if (error)
+ goto end;
sprintf(extra, "0x%08X", data32);
break;
default:
@@ -2110,8 +2117,9 @@ static int rtw_wx_read32(struct net_device *dev,
}
DBG_88E(KERN_INFO "%s: addr = 0x%08X data =%s\n", __func__, addr, extra);
+end:
kfree(ptmp);
- return 0;
+ return error;
}
static int rtw_wx_write32(struct net_device *dev,
@@ -2251,6 +2259,7 @@ static void rtw_dbg_mode_hdl(struct adapter *padapter, u32 id, u8 *pdata, u32 le
u8 path;
u8 offset;
u32 value;
+ int error;
DBG_88E("%s\n", __func__);
@@ -2262,13 +2271,13 @@ static void rtw_dbg_mode_hdl(struct adapter *padapter, u32 id, u8 *pdata, u32 le
RegRWStruct = (struct mp_rw_reg *)pdata;
switch (RegRWStruct->width) {
case 1:
- RegRWStruct->value = rtw_read8(padapter, RegRWStruct->offset);
+ RegRWStruct->value = rtw_read8(padapter, RegRWStruct->offset, &error);
break;
case 2:
- RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset);
+ RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset, &error);
break;
case 4:
- RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset);
+ RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset, &error);
break;
default:
break;
@@ -3815,12 +3824,20 @@ static int rtw_cta_test_start(struct net_device *dev,
padapter->in_cta_test = 0;
if (padapter->in_cta_test) {
- u32 v = rtw_read32(padapter, REG_RCR);
+ u32 v = rtw_read32(padapter, REG_RCR, &ret);
+
+ if (ret)
+ return ret;
+
v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* RCR_ADF */
rtw_write32(padapter, REG_RCR, v);
DBG_88E("enable RCR_ADF\n");
} else {
- u32 v = rtw_read32(padapter, REG_RCR);
+ u32 v = rtw_read32(padapter, REG_RCR, &ret);
+
+ if (ret)
+ return ret;
+
v |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;/* RCR_ADF */
rtw_write32(padapter, REG_RCR, v);
DBG_88E("disable RCR_ADF\n");
@@ -3890,18 +3907,19 @@ static int rtw_rereg_nd_name(struct net_device *dev,
static void mac_reg_dump(struct adapter *padapter)
{
int i, j = 1;
+ int error;
pr_info("\n ======= MAC REG =======\n");
for (i = 0x0; i < 0x300; i += 4) {
if (j % 4 == 1)
pr_info("0x%02x", i);
- pr_info(" 0x%08x ", rtw_read32(padapter, i));
+ pr_info(" 0x%08x ", rtw_read32(padapter, i, &error));
if ((j++) % 4 == 0)
pr_info("\n");
}
for (i = 0x400; i < 0x800; i += 4) {
if (j % 4 == 1)
pr_info("0x%02x", i);
- pr_info(" 0x%08x ", rtw_read32(padapter, i));
+ pr_info(" 0x%08x ", rtw_read32(padapter, i, &error));
if ((j++) % 4 == 0)
pr_info("\n");
}
@@ -3910,12 +3928,13 @@ static void mac_reg_dump(struct adapter *padapter)
static void bb_reg_dump(struct adapter *padapter)
{
int i, j = 1;
+ int error;
pr_info("\n ======= BB REG =======\n");
for (i = 0x800; i < 0x1000; i += 4) {
if (j % 4 == 1)
pr_info("0x%02x", i);
- pr_info(" 0x%08x ", rtw_read32(padapter, i));
+ pr_info(" 0x%08x ", rtw_read32(padapter, i, &error));
if ((j++) % 4 == 0)
pr_info("\n");
}
@@ -3964,6 +3983,8 @@ static int rtw_dbg_port(struct net_device *dev,
struct security_priv *psecuritypriv = &padapter->securitypriv;
struct wlan_network *cur_network = &pmlmepriv->cur_network;
struct sta_priv *pstapriv = &padapter->stapriv;
+ int error;
+ u32 tmp;
pdata = (u32 *)&wrqu->data;
@@ -3978,13 +3999,22 @@ static int rtw_dbg_port(struct net_device *dev,
case 0x70:/* read_reg */
switch (minor_cmd) {
case 1:
- DBG_88E("rtw_read8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg));
+ tmp = rtw_read8(padapter, arg, &error);
+ if (error)
+ return error;
+ DBG_88E("rtw_read8(0x%x) = 0x%02x\n", arg, (u8) tmp);
break;
case 2:
- DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
+ tmp = rtw_read16(padapter, arg, &error);
+ if (error)
+ return error;
+ DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, (u16) tmp);
break;
case 4:
- DBG_88E("rtw_read32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
+ tmp = rtw_read32(padapter, arg, &error);
+ if (error)
+ return error;
+ DBG_88E("rtw_read32(0x%x) = 0x%08x\n", arg, tmp);
break;
}
break;
@@ -3992,15 +4022,15 @@ static int rtw_dbg_port(struct net_device *dev,
switch (minor_cmd) {
case 1:
rtw_write8(padapter, arg, extra_arg);
- DBG_88E("rtw_write8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg));
+ DBG_88E("rtw_write8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg, &error));
break;
case 2:
rtw_write16(padapter, arg, extra_arg);
- DBG_88E("rtw_write16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
+ DBG_88E("rtw_write16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg, &error));
break;
case 4:
rtw_write32(padapter, arg, extra_arg);
- DBG_88E("rtw_write32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
+ DBG_88E("rtw_write32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg, &error));
break;
}
break;
@@ -4096,7 +4126,10 @@ static int rtw_dbg_port(struct net_device *dev,
if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
ret = -EPERM;
- final = rtw_read8(padapter, reg);
+ final = rtw_read8(padapter, reg, &error);
+ if (error)
+ return error;
+
if (start_value + write_num - 1 == final)
DBG_88E("continuous IOL_CMD_WB_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
else
@@ -4125,7 +4158,9 @@ static int rtw_dbg_port(struct net_device *dev,
if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
ret = -EPERM;
- final = rtw_read16(padapter, reg);
+ final = rtw_read16(padapter, reg, &error);
+ if (error)
+ return error;
if (start_value + write_num - 1 == final)
DBG_88E("continuous IOL_CMD_WW_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
else
@@ -4153,7 +4188,9 @@ static int rtw_dbg_port(struct net_device *dev,
if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
ret = -EPERM;
- final = rtw_read32(padapter, reg);
+ final = rtw_read32(padapter, reg, &error);
+ if (error)
+ return error;
if (start_value + write_num - 1 == final)
DBG_88E("continuous IOL_CMD_WD_REG to 0x%x %u times Success, start:%u, final:%u\n",
reg, write_num, start_value, final);
@@ -4423,39 +4460,39 @@ static int rtw_dbg_port(struct net_device *dev,
case 0xfd:
rtw_write8(padapter, 0xc50, arg);
- DBG_88E("wr(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50));
+ DBG_88E("wr(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50, &error));
rtw_write8(padapter, 0xc58, arg);
- DBG_88E("wr(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58));
+ DBG_88E("wr(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58, &error));
break;
case 0xfe:
- DBG_88E("rd(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50));
- DBG_88E("rd(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58));
+ DBG_88E("rd(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50, &error));
+ DBG_88E("rd(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58, &error));
break;
case 0xff:
- DBG_88E("dbg(0x210) = 0x%x\n", rtw_read32(padapter, 0x210));
- DBG_88E("dbg(0x608) = 0x%x\n", rtw_read32(padapter, 0x608));
- DBG_88E("dbg(0x280) = 0x%x\n", rtw_read32(padapter, 0x280));
- DBG_88E("dbg(0x284) = 0x%x\n", rtw_read32(padapter, 0x284));
- DBG_88E("dbg(0x288) = 0x%x\n", rtw_read32(padapter, 0x288));
+ DBG_88E("dbg(0x210) = 0x%x\n", rtw_read32(padapter, 0x210, &error));
+ DBG_88E("dbg(0x608) = 0x%x\n", rtw_read32(padapter, 0x608, &error));
+ DBG_88E("dbg(0x280) = 0x%x\n", rtw_read32(padapter, 0x280, &error));
+ DBG_88E("dbg(0x284) = 0x%x\n", rtw_read32(padapter, 0x284, &error));
+ DBG_88E("dbg(0x288) = 0x%x\n", rtw_read32(padapter, 0x288, &error));
- DBG_88E("dbg(0x664) = 0x%x\n", rtw_read32(padapter, 0x664));
+ DBG_88E("dbg(0x664) = 0x%x\n", rtw_read32(padapter, 0x664, &error));
DBG_88E("\n");
- DBG_88E("dbg(0x430) = 0x%x\n", rtw_read32(padapter, 0x430));
- DBG_88E("dbg(0x438) = 0x%x\n", rtw_read32(padapter, 0x438));
+ DBG_88E("dbg(0x430) = 0x%x\n", rtw_read32(padapter, 0x430, &error));
+ DBG_88E("dbg(0x438) = 0x%x\n", rtw_read32(padapter, 0x438, &error));
- DBG_88E("dbg(0x440) = 0x%x\n", rtw_read32(padapter, 0x440));
+ DBG_88E("dbg(0x440) = 0x%x\n", rtw_read32(padapter, 0x440, &error));
- DBG_88E("dbg(0x458) = 0x%x\n", rtw_read32(padapter, 0x458));
+ DBG_88E("dbg(0x458) = 0x%x\n", rtw_read32(padapter, 0x458, &error));
- DBG_88E("dbg(0x484) = 0x%x\n", rtw_read32(padapter, 0x484));
- DBG_88E("dbg(0x488) = 0x%x\n", rtw_read32(padapter, 0x488));
+ DBG_88E("dbg(0x484) = 0x%x\n", rtw_read32(padapter, 0x484, &error));
+ DBG_88E("dbg(0x488) = 0x%x\n", rtw_read32(padapter, 0x488, &error));
- DBG_88E("dbg(0x444) = 0x%x\n", rtw_read32(padapter, 0x444));
- DBG_88E("dbg(0x448) = 0x%x\n", rtw_read32(padapter, 0x448));
- DBG_88E("dbg(0x44c) = 0x%x\n", rtw_read32(padapter, 0x44c));
- DBG_88E("dbg(0x450) = 0x%x\n", rtw_read32(padapter, 0x450));
+ DBG_88E("dbg(0x444) = 0x%x\n", rtw_read32(padapter, 0x444, &error));
+ DBG_88E("dbg(0x448) = 0x%x\n", rtw_read32(padapter, 0x448, &error));
+ DBG_88E("dbg(0x44c) = 0x%x\n", rtw_read32(padapter, 0x44c, &error));
+ DBG_88E("dbg(0x450) = 0x%x\n", rtw_read32(padapter, 0x450, &error));
break;
}
break;
@@ -5326,6 +5363,8 @@ static int rtw_mp_read_reg(struct net_device *dev,
char data[20], tmp[20];
u32 addr;
u32 ret, i = 0, j = 0, strtout = 0;
+ int error;
+ u32 tmp_;
if (!input)
return -ENOMEM;
@@ -5361,12 +5400,20 @@ static int rtw_mp_read_reg(struct net_device *dev,
switch (width) {
case 'b':
/* 1 byte */
- sprintf(extra, "%d\n", rtw_read8(padapter, addr));
+ tmp_ = rtw_read16(padapter, addr, &error);
+ if (error)
+ return error;
+
+ sprintf(extra, "%d\n", (u8) tmp_);
wrqu->length = strlen(extra);
break;
case 'w':
/* 2 bytes */
- sprintf(data, "%04x\n", rtw_read16(padapter, addr));
+ tmp_ = rtw_read16(padapter, addr, &error);
+ if (error)
+ return error;
+
+ sprintf(data, "%04x\n", (u16) tmp_);
for (i = 0; i <= strlen(data); i++) {
if (i % 2 == 0) {
tmp[j] = ' ';
@@ -5396,8 +5443,12 @@ static int rtw_mp_read_reg(struct net_device *dev,
wrqu->length = 6;
break;
case 'd':
+ tmp_ = rtw_read32(padapter, addr, &error);
+ if (error)
+ return error;
+
/* 4 bytes */
- sprintf(data, "%08x", rtw_read32(padapter, addr));
+ sprintf(data, "%08x", tmp_);
/* add read data format blank */
for (i = 0; i <= strlen(data); i++) {
if (i % 2 == 0) {
@@ -5889,6 +5940,8 @@ static int rtw_mp_arx(struct net_device *dev,
u32 cckok = 0, cckcrc = 0, ofdmok = 0, ofdmcrc = 0, htok = 0, htcrc = 0, OFDM_FA = 0, CCK_FA = 0;
char *input = kmalloc(wrqu->length, GFP_KERNEL);
struct adapter *padapter = rtw_netdev_priv(dev);
+ u8 tmp;
+ int error;
if (!input)
return -ENOMEM;
@@ -5934,7 +5987,18 @@ static int rtw_mp_arx(struct net_device *dev,
OFDM_FA = read_bbreg(padapter, 0xda4, 0x0000FFFF);
OFDM_FA = read_bbreg(padapter, 0xda4, 0xFFFF0000);
OFDM_FA = read_bbreg(padapter, 0xda8, 0x0000FFFF);
- CCK_FA = (rtw_read8(padapter, 0xa5b) << 8) | (rtw_read8(padapter, 0xa5c));
+
+ tmp = rtw_read8(padapter, 0xa5b, &error);
+ if (error)
+ return error;
+
+ CCK_FA = (tmp << 8);
+
+ tmp = rtw_read8(padapter, 0xa5c, &error);
+ if (error)
+ return error;
+
+ CCK_FA |= (tmp);
sprintf(extra, "Phy Received packet OK:%d CRC error:%d FA Counter: %d", cckok + ofdmok + htok, cckcrc + ofdmcrc + htcrc, OFDM_FA + CCK_FA);
}
@@ -6097,20 +6161,30 @@ static int rtw_mp_dump(struct net_device *dev,
u8 rf_type, path_nums = 0;
u32 i, j = 1, path;
struct adapter *padapter = rtw_netdev_priv(dev);
+ int error;
+ u32 tmp;
if (strncmp(extra, "all", 4) == 0) {
DBG_88E("\n ======= MAC REG =======\n");
for (i = 0x0; i < 0x300; i += 4) {
if (j % 4 == 1)
DBG_88E("0x%02x", i);
- DBG_88E(" 0x%08x ", rtw_read32(padapter, i));
+
+ tmp = rtw_read32(padapter, i, &error);
+ if (!error)
+ DBG_88E(" 0x%08x ", tmp);
+
if ((j++) % 4 == 0)
DBG_88E("\n");
}
for (i = 0x400; i < 0x1000; i += 4) {
if (j % 4 == 1)
DBG_88E("0x%02x", i);
- DBG_88E(" 0x%08x ", rtw_read32(padapter, i));
+
+ tmp = rtw_read32(padapter, i, &error);
+ if (!error)
+ DBG_88E(" 0x%08x ", tmp);
+
if ((j++) % 4 == 0)
DBG_88E("\n");
}
--
2.32.0
ReadEFuseByte() internally calls rtw_read8() which can fail. To avoid
uninit value bugs we should properly handle error sutiation and deliver
the error to caller.
To achieve it, some functions now return an int, and the error
which could occur in ReadEFuseByte() is handled on the top level.
Signed-off-by: Pavel Skripkin <[email protected]>
---
drivers/staging/r8188eu/core/rtw_efuse.c | 46 +++++++++-----
drivers/staging/r8188eu/hal/hal_intf.c | 6 +-
.../staging/r8188eu/hal/rtl8188e_hal_init.c | 62 +++++++++++++------
drivers/staging/r8188eu/hal/usb_halinit.c | 20 ++++--
drivers/staging/r8188eu/hal/usb_ops_linux.c | 43 +++++++++++--
drivers/staging/r8188eu/include/hal_intf.h | 6 +-
.../staging/r8188eu/include/rtl8188e_hal.h | 2 +-
drivers/staging/r8188eu/include/rtw_efuse.h | 4 +-
drivers/staging/r8188eu/os_dep/usb_intf.c | 4 +-
9 files changed, 138 insertions(+), 55 deletions(-)
diff --git a/drivers/staging/r8188eu/core/rtw_efuse.c b/drivers/staging/r8188eu/core/rtw_efuse.c
index 47ff73b28380..5fcff0d6eb26 100644
--- a/drivers/staging/r8188eu/core/rtw_efuse.c
+++ b/drivers/staging/r8188eu/core/rtw_efuse.c
@@ -149,7 +149,7 @@ Efuse_CalculateWordCnts(u8 word_en)
/* */
/* Created by Roger, 2008.10.21. */
/* */
-void
+int
ReadEFuseByte(
struct adapter *Adapter,
u16 _offset,
@@ -163,32 +163,32 @@ ReadEFuseByte(
if (pseudo) {
Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf);
- return;
+ return 0;
}
/* Write Address */
rtw_write8(Adapter, EFUSE_CTRL + 1, (_offset & 0xff));
readbyte = rtw_read8(Adapter, EFUSE_CTRL + 2, &error);
if (error)
- return;
+ return error;
rtw_write8(Adapter, EFUSE_CTRL + 2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
/* Write bit 32 0 */
readbyte = rtw_read8(Adapter, EFUSE_CTRL + 3, &error);
if (error)
- return;
+ return error;
rtw_write8(Adapter, EFUSE_CTRL + 3, (readbyte & 0x7f));
/* Check bit 32 read-ready */
retry = 0;
value32 = rtw_read32(Adapter, EFUSE_CTRL, &error);
if (error)
- return;
+ return error;
while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) {
value32 = rtw_read32(Adapter, EFUSE_CTRL, &error);
if (error)
- return;
+ return error;
retry++;
}
@@ -199,9 +199,11 @@ ReadEFuseByte(
udelay(50);
value32 = rtw_read32(Adapter, EFUSE_CTRL, &error);
if (error)
- return;
+ return error;
*pbuf = (u8)(value32 & 0xff);
+
+ return 0;
}
/* */
@@ -222,9 +224,9 @@ ReadEFuseByte(
/* write addr must be after sec5. */
/* */
-static void efuse_ReadEFuse(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool pseudo)
+static int efuse_ReadEFuse(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool pseudo)
{
- Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, pseudo);
+ return Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, pseudo);
}
void EFUSE_GetEfuseDefinition(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut, bool pseudo
@@ -539,6 +541,7 @@ u8 efuse_GetCurrentSize(struct adapter *padapter, u16 *size)
u8 rtw_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
{
u16 mapLen = 0;
+ int res;
EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false);
@@ -547,7 +550,9 @@ u8 rtw_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
Efuse_PowerSwitch(padapter, false, true);
- efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, false);
+ res = efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, false);
+ if (res)
+ return _FAIL;
Efuse_PowerSwitch(padapter, false, false);
@@ -557,6 +562,7 @@ u8 rtw_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
u8 rtw_BT_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
{
u16 mapLen = 0;
+ int res;
EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false);
@@ -565,7 +571,9 @@ u8 rtw_BT_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
Efuse_PowerSwitch(padapter, false, true);
- efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data, false);
+ res = efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data, false);
+ if (res)
+ return _FAIL;
Efuse_PowerSwitch(padapter, false, false);
@@ -836,17 +844,22 @@ efuse_ShadowRead4Byte(
* 11/11/2008 MHC Create Version 0.
*
*---------------------------------------------------------------------------*/
-static void Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse, bool pseudo)
+static int Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse, bool pseudo)
{
u16 mapLen = 0;
+ int res;
Efuse_PowerSwitch(pAdapter, false, true);
EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, pseudo);
- efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse, pseudo);
+ res = efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse, pseudo);
+ if (res)
+ return res;
Efuse_PowerSwitch(pAdapter, false, false);
+
+ return res;
}
/*-----------------------------------------------------------------------------
@@ -865,20 +878,23 @@ static void Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse,
* 11/13/2008 MHC Create Version 0.
*
*---------------------------------------------------------------------------*/
-void EFUSE_ShadowMapUpdate(
+int EFUSE_ShadowMapUpdate(
struct adapter *pAdapter,
u8 efuseType,
bool pseudo)
{
struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
u16 mapLen = 0;
+ int res = 0;
EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, pseudo);
if (pEEPROM->bautoload_fail_flag)
memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen);
else
- Efuse_ReadAllMap(pAdapter, efuseType, pEEPROM->efuse_eeprom_data, pseudo);
+ res = Efuse_ReadAllMap(pAdapter, efuseType, pEEPROM->efuse_eeprom_data, pseudo);
+
+ return res;
} /* EFUSE_ShadowMapUpdate */
/*-----------------------------------------------------------------------------
diff --git a/drivers/staging/r8188eu/hal/hal_intf.c b/drivers/staging/r8188eu/hal/hal_intf.c
index a6d589e89aeb..94536659cd7c 100644
--- a/drivers/staging/r8188eu/hal/hal_intf.c
+++ b/drivers/staging/r8188eu/hal/hal_intf.c
@@ -12,10 +12,12 @@ void rtw_hal_chip_configure(struct adapter *adapt)
adapt->HalFunc.intf_chip_configure(adapt);
}
-void rtw_hal_read_chip_info(struct adapter *adapt)
+int rtw_hal_read_chip_info(struct adapter *adapt)
{
if (adapt->HalFunc.read_adapter_info)
- adapt->HalFunc.read_adapter_info(adapt);
+ return adapt->HalFunc.read_adapter_info(adapt);
+
+ return 0;
}
void rtw_hal_read_chip_version(struct adapter *adapt)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
index 0a2c08a24ad8..2ab58891ee9a 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
@@ -864,7 +864,7 @@ rtl8188e_EfusePowerSwitch(
hal_EfusePowerSwitch_RTL8188E(pAdapter, bWrite, PwrState);
}
-static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
+static int Hal_EfuseReadEFuse88E(struct adapter *Adapter,
u16 _offset,
u16 _size_byte,
u8 *pbuf,
@@ -879,6 +879,7 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
u16 **eFuseWord = NULL;
u16 efuse_utilized = 0;
u8 u1temp = 0;
+ int error;
/* */
/* Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */
@@ -909,12 +910,16 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
/* 1. Read the first byte to check if efuse is empty!!! */
/* */
/* */
- ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
- if (*rtemp8 != 0xFF) {
+ error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ if (error) {
+ DBG_88E("Failed to read EFUSE byte\n");
+ goto exit;
+ } else if (*rtemp8 != 0xFF) {
efuse_utilized++;
eFuse_Addr++;
} else {
DBG_88E("EFUSE is empty efuse_Addr-%d efuse_data =%x\n", eFuse_Addr, *rtemp8);
+ error = -ENOENT;
goto exit;
}
@@ -926,11 +931,15 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
if ((*rtemp8 & 0x1F) == 0x0F) { /* extended header */
u1temp = ((*rtemp8 & 0xE0) >> 5);
- ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ if (error)
+ goto exit;
if ((*rtemp8 & 0x0F) == 0x0F) {
eFuse_Addr++;
- ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ if (error)
+ goto exit;
if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
eFuse_Addr++;
@@ -951,13 +960,19 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
/* Check word enable condition in the section */
if (!(wren & 0x01)) {
- ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ if (error)
+ goto exit;
+
eFuse_Addr++;
efuse_utilized++;
eFuseWord[offset][i] = (*rtemp8 & 0xff);
if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
break;
- ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ if (error)
+ goto exit;
+
eFuse_Addr++;
efuse_utilized++;
eFuseWord[offset][i] |= (((u16)*rtemp8 << 8) & 0xff00);
@@ -969,7 +984,9 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
}
/* Read next PG header */
- ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ if (error)
+ goto exit;
if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
efuse_utilized++;
@@ -995,10 +1012,14 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
exit:
kfree(efuseTbl);
kfree(eFuseWord);
+
+ return error;
}
-static void ReadEFuseByIC(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
+static int ReadEFuseByIC(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
{
+ int res = 0;
+
if (!bPseudoTest) {
int ret = _FAIL;
if (rtw_IOL_applied(Adapter)) {
@@ -1012,25 +1033,25 @@ static void ReadEFuseByIC(struct adapter *Adapter, u8 efuseType, u16 _offset, u1
goto exit;
}
}
- Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
+ res = Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
exit:
- return;
+ return res;
}
-static void ReadEFuse_Pseudo(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
+static int ReadEFuse_Pseudo(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
{
- Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
+ return Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
}
-static void rtl8188e_ReadEFuse(struct adapter *Adapter, u8 efuseType,
+static int rtl8188e_ReadEFuse(struct adapter *Adapter, u8 efuseType,
u16 _offset, u16 _size_byte, u8 *pbuf,
bool bPseudoTest)
{
if (bPseudoTest)
- ReadEFuse_Pseudo(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
+ return ReadEFuse_Pseudo(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
else
- ReadEFuseByIC(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
+ return ReadEFuseByIC(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
}
/* Do not support BT */
@@ -2043,21 +2064,24 @@ s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy)
return status;
}
-void
+int
Hal_InitPGData88E(struct adapter *padapter)
{
struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
+ int res = 0;
if (!pEEPROM->bautoload_fail_flag) { /* autoload OK. */
if (!is_boot_from_eeprom(padapter)) {
/* Read EFUSE real map to shadow. */
- EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
+ res = EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
}
} else {/* autoload fail */
/* update to default value 0xFF */
if (!is_boot_from_eeprom(padapter))
- EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
+ res = EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
}
+
+ return res;
}
void
diff --git a/drivers/staging/r8188eu/hal/usb_halinit.c b/drivers/staging/r8188eu/hal/usb_halinit.c
index 73ef2e0ead19..8df8a8b7c738 100644
--- a/drivers/staging/r8188eu/hal/usb_halinit.c
+++ b/drivers/staging/r8188eu/hal/usb_halinit.c
@@ -1275,7 +1275,7 @@ readAdapterInfo_8188EU(
_ReadLEDSetting(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag);
}
-static void _ReadPROMContent(
+static int _ReadPROMContent(
struct adapter *Adapter
)
{
@@ -1286,7 +1286,7 @@ static void _ReadPROMContent(
/* check system boot selection */
eeValue = rtw_read8(Adapter, REG_9346CR, &error);
if (error)
- return;
+ return error;
eeprom->EepromOrEfuse = (eeValue & BOOT_FROM_EEPROM) ? true : false;
eeprom->bautoload_fail_flag = (eeValue & EEPROM_EN) ? false : true;
@@ -1294,8 +1294,13 @@ static void _ReadPROMContent(
DBG_88E("Boot from %s, Autoload %s !\n", (eeprom->EepromOrEfuse ? "EEPROM" : "EFUSE"),
(eeprom->bautoload_fail_flag ? "Fail" : "OK"));
- Hal_InitPGData88E(Adapter);
+ error = Hal_InitPGData88E(Adapter);
+ if (error)
+ return error;
+
readAdapterInfo_8188EU(Adapter);
+
+ return 0;
}
static void _ReadRFType(struct adapter *Adapter)
@@ -1308,23 +1313,26 @@ static void _ReadRFType(struct adapter *Adapter)
static int _ReadAdapterInfo8188EU(struct adapter *Adapter)
{
u32 start = jiffies;
+ int res;
MSG_88E("====> %s\n", __func__);
_ReadRFType(Adapter);/* rf_chip -> _InitRFType() */
- _ReadPROMContent(Adapter);
+ res = _ReadPROMContent(Adapter);
+ if (res)
+ return _FAIL;
MSG_88E("<==== %s in %d ms\n", __func__, rtw_get_passing_time_ms(start));
return _SUCCESS;
}
-static void ReadAdapterInfo8188EU(struct adapter *Adapter)
+static int ReadAdapterInfo8188EU(struct adapter *Adapter)
{
/* Read EEPROM size before call any EEPROM function */
Adapter->EepromAddressSize = GetEEPROMSize8188E(Adapter);
- _ReadAdapterInfo8188EU(Adapter);
+ return _ReadAdapterInfo8188EU(Adapter);
}
#define GPIO_DEBUG_PORT_NUM 0
diff --git a/drivers/staging/r8188eu/hal/usb_ops_linux.c b/drivers/staging/r8188eu/hal/usb_ops_linux.c
index 980af6c02be5..f137b775976c 100644
--- a/drivers/staging/r8188eu/hal/usb_ops_linux.c
+++ b/drivers/staging/r8188eu/hal/usb_ops_linux.c
@@ -118,8 +118,14 @@ static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr, int *error)
len = 1;
res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
- if (likely(error))
- *error = res < 0? res: 0;
+ if (likely(error)) {
+ if (res < 0) {
+ pr_err("r8188eu: Failed to read 8 bytes: %d\n", res);
+ *error = res;
+ } else {
+ *error = 0;
+ }
+ }
return data;
@@ -130,12 +136,25 @@ static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr, int *error)
u8 requesttype;
u16 wvalue;
u16 len;
- __le32 data;
+ __le32 data = 0;
+ int res;
+
+ if (unlikely(!error))
+ WARN_ON_ONCE("r8188eu: Reading w/o error checking is bad idea\n");
requesttype = 0x01;/* read_in */
wvalue = (u16)(addr & 0x0000ffff);
len = 2;
- usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
+
+ res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
+ if (likely(error)) {
+ if (res < 0) {
+ pr_err("r8188eu: Failed to read 8 bytes: %d\n", res);
+ *error = res;
+ } else {
+ *error = 0;
+ }
+ }
return (u16)(le32_to_cpu(data) & 0xffff);
}
@@ -145,14 +164,26 @@ static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr, int *error)
u8 requesttype;
u16 wvalue;
u16 len;
- __le32 data;
+ __le32 data = 0;
+ int res;
+
+ if (unlikely(!error))
+ WARN_ON_ONCE("r8188eu: Reading w/o error checking is bad idea\n");
requesttype = 0x01;/* read_in */
wvalue = (u16)(addr & 0x0000ffff);
len = 4;
- usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
+ res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
+ if (likely(error)) {
+ if (res < 0) {
+ pr_err("r8188eu: Failed to read 8 bytes: %d\n", res);
+ *error = res;
+ } else {
+ *error = 0;
+ }
+ }
return le32_to_cpu(data);
}
diff --git a/drivers/staging/r8188eu/include/hal_intf.h b/drivers/staging/r8188eu/include/hal_intf.h
index fa252540e596..9241af39e3a3 100644
--- a/drivers/staging/r8188eu/include/hal_intf.h
+++ b/drivers/staging/r8188eu/include/hal_intf.h
@@ -154,7 +154,7 @@ struct hal_ops {
void (*intf_chip_configure)(struct adapter *padapter);
- void (*read_adapter_info)(struct adapter *padapter);
+ int (*read_adapter_info)(struct adapter *padapter);
void (*enable_interrupt)(struct adapter *padapter);
void (*disable_interrupt)(struct adapter *padapter);
@@ -222,7 +222,7 @@ struct hal_ops {
void (*EfusePowerSwitch)(struct adapter *padapter, u8 bWrite,
u8 PwrState);
- void (*ReadEFuse)(struct adapter *padapter, u8 efuseType, u16 _offset,
+ int (*ReadEFuse)(struct adapter *padapter, u8 efuseType, u16 _offset,
u16 _size_byte, u8 *pbuf, bool bPseudoTest);
void (*EFUSEGetEfuseDefinition)(struct adapter *padapter, u8 efuseType,
u8 type, void *pOut, bool bPseudoTest);
@@ -324,7 +324,7 @@ void rtw_hal_set_hwreg(struct adapter *padapter, u8 variable, u8 *val);
void rtw_hal_get_hwreg(struct adapter *padapter, u8 variable, u8 *val);
void rtw_hal_chip_configure(struct adapter *padapter);
-void rtw_hal_read_chip_info(struct adapter *padapter);
+int rtw_hal_read_chip_info(struct adapter *padapter);
void rtw_hal_read_chip_version(struct adapter *padapter);
u8 rtw_hal_set_def_var(struct adapter *padapter,
diff --git a/drivers/staging/r8188eu/include/rtl8188e_hal.h b/drivers/staging/r8188eu/include/rtl8188e_hal.h
index 3939bf053de1..db9adbd0b024 100644
--- a/drivers/staging/r8188eu/include/rtl8188e_hal.h
+++ b/drivers/staging/r8188eu/include/rtl8188e_hal.h
@@ -410,7 +410,7 @@ s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy);
/* EFuse */
u8 GetEEPROMSize8188E(struct adapter *padapter);
-void Hal_InitPGData88E(struct adapter *padapter);
+int Hal_InitPGData88E(struct adapter *padapter);
void Hal_EfuseParseIDCode88E(struct adapter *padapter, u8 *hwinfo);
void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *hwinfo,
bool AutoLoadFail);
diff --git a/drivers/staging/r8188eu/include/rtw_efuse.h b/drivers/staging/r8188eu/include/rtw_efuse.h
index b3ff46db2091..9657b66679e3 100644
--- a/drivers/staging/r8188eu/include/rtw_efuse.h
+++ b/drivers/staging/r8188eu/include/rtw_efuse.h
@@ -113,7 +113,7 @@ u8 rtw_BT_efuse_map_write(struct adapter *adapter, u16 addr,
u16 cnts, u8 *data);
u16 Efuse_GetCurrentSize(struct adapter *adapter, u8 efusetype, bool test);
u8 Efuse_CalculateWordCnts(u8 word_en);
-void ReadEFuseByte(struct adapter *adapter, u16 _offset, u8 *pbuf, bool test);
+int ReadEFuseByte(struct adapter *adapter, u16 _offset, u8 *pbuf, bool test);
void EFUSE_GetEfuseDefinition(struct adapter *adapt, u8 type, u8 type1,
void *out, bool bPseudoTest);
u8 efuse_OneByteRead(struct adapter *adapter, u16 addr, u8 *data, bool test);
@@ -128,7 +128,7 @@ u8 Efuse_WordEnableDataWrite(struct adapter *adapter, u16 efuse_addr,
u8 word_en, u8 *data, bool test);
u8 EFUSE_Read1Byte(struct adapter *adapter, u16 address);
-void EFUSE_ShadowMapUpdate(struct adapter *adapter, u8 efusetype, bool test);
+int EFUSE_ShadowMapUpdate(struct adapter *adapter, u8 efusetype, bool test);
void EFUSE_ShadowRead(struct adapter *adapt, u8 type, u16 offset, u32 *val);
#endif
diff --git a/drivers/staging/r8188eu/os_dep/usb_intf.c b/drivers/staging/r8188eu/os_dep/usb_intf.c
index e002070f7fba..f950a31d061e 100644
--- a/drivers/staging/r8188eu/os_dep/usb_intf.c
+++ b/drivers/staging/r8188eu/os_dep/usb_intf.c
@@ -608,7 +608,9 @@ static struct adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj,
rtw_hal_chip_configure(padapter);
/* step read efuse/eeprom data and get mac_addr */
- rtw_hal_read_chip_info(padapter);
+ status = rtw_hal_read_chip_info(padapter);
+ if (status)
+ goto free_hal_data;
/* step 5. */
if (rtw_init_drv_sw(padapter) == _FAIL)
--
2.32.0
Since read_macreg() calls rtw_read*() internally we should tell
callers about an error on the read side.
Signed-off-by: Pavel Skripkin <[email protected]>
---
drivers/staging/r8188eu/core/rtw_mp.c | 9 ++++-----
drivers/staging/r8188eu/include/rtw_mp.h | 2 +-
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/staging/r8188eu/core/rtw_mp.c b/drivers/staging/r8188eu/core/rtw_mp.c
index 601a1fd5d4e7..6bbea1cc364a 100644
--- a/drivers/staging/r8188eu/core/rtw_mp.c
+++ b/drivers/staging/r8188eu/core/rtw_mp.c
@@ -7,20 +7,19 @@
#include "../include/odm_precomp.h"
#include "../include/rtl8188e_hal.h"
-u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz)
+u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz, int *error)
{
u32 val = 0;
- int error;
switch (sz) {
case 1:
- val = rtw_read8(padapter, addr, &error);
+ val = rtw_read8(padapter, addr, error);
break;
case 2:
- val = rtw_read16(padapter, addr, &error);
+ val = rtw_read16(padapter, addr, error);
break;
case 4:
- val = rtw_read32(padapter, addr, &error);
+ val = rtw_read32(padapter, addr, error);
break;
default:
val = 0xffffffff;
diff --git a/drivers/staging/r8188eu/include/rtw_mp.h b/drivers/staging/r8188eu/include/rtw_mp.h
index b64b16554343..c063e6216249 100644
--- a/drivers/staging/r8188eu/include/rtw_mp.h
+++ b/drivers/staging/r8188eu/include/rtw_mp.h
@@ -410,7 +410,7 @@ void mp_stop_test(struct adapter *padapter);
u32 _read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask);
void _write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask, u32 val);
-u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz);
+u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz, int *error);
void write_macreg(struct adapter *padapter, u32 addr, u32 val, u32 sz);
u32 read_bbreg(struct adapter *padapter, u32 addr, u32 bitmask);
void write_bbreg(struct adapter *padapter, u32 addr, u32 bitmask, u32 val);
--
2.32.0
On 8/20/21 8:07 PM, Pavel Skripkin wrote:
[snip]
> @@ -336,13 +338,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);
> + *buf = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL, &error);
> + if (error)
> + goto clear_evt;
> +
> + *(buf + 1) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1, &error);
> + if (error)
> + ;
^^^^^^^
Should be goto clear_evt;. Will fix in v2, I want to receive some
feedback first :)
With regards,
Pavel Skripkin
On Fri, 2021-08-20 at 20:07 +0300, Pavel Skripkin wrote:
> Hi, Greg, Larry and Phillip!
>
> I noticed, that new staging driver was added like 3 weeks ago and I
> decided
> to look at the code, because drivers in staging directory are always
> buggy.
>
> The first thing I noticed is *no one* was checking read operations
> result, but
> it can fail and driver may start writing random stack values into
> registers. It
> can cause driver misbehavior or device misbehavior.
>
> To avoid this type of bugs, i've expanded read() API with error
> parametr,
> which will be initialized to error if read fails. It helps callers to
> break/return earlier and don't write random values to registers or to
> rely
> on random values.
>
> Why is this pacth series RFC?
> Â 1. I don't have this device and I cannot test these changes.
> Â 2. I don't know how to handle errors in each particular case. For
> now, function
> Â Â Â Â just returns or returns an error. That's all. I hope, driver
> maintainers will
> Â Â Â Â help with these bits.
> Â 3. I guess, I handled not all uninit value bugs here. I hope, I
> fixed
> Â Â Â Â at least half of them
>
> This series was build-tested and made on top of staging-testing
> branch
>
>
> With regards,
> Pavel Skripkin
>
> Pavel Skripkin (3):
> Â staging: r8188eu: add proper rtw_read* error handling
> Â staging: r8188eu: add error handling to ReadFuse
> Â staging: r8188eu: add error argument to read_macreg
>
>  drivers/staging/r8188eu/core/rtw_debug.c     | 79 +++-
>  drivers/staging/r8188eu/core/rtw_efuse.c     | 119 +++--
>  drivers/staging/r8188eu/core/rtw_io.c        | 18 +-
>  drivers/staging/r8188eu/core/rtw_mp.c        | 38 +-
>  drivers/staging/r8188eu/core/rtw_mp_ioctl.c  | 20 +-
>  drivers/staging/r8188eu/core/rtw_pwrctrl.c   |  6 +-
>  drivers/staging/r8188eu/core/rtw_sreset.c    |  7 +-
>  drivers/staging/r8188eu/hal/HalPwrSeqCmd.c   |  9 +-
>  drivers/staging/r8188eu/hal/hal_com.c        | 22 +-
>  drivers/staging/r8188eu/hal/hal_intf.c       |  6 +-
>  drivers/staging/r8188eu/hal/odm_interface.c  | 12 +-
>  drivers/staging/r8188eu/hal/rtl8188e_cmd.c   | 37 +-
>  drivers/staging/r8188eu/hal/rtl8188e_dm.c    |  6 +-
>  .../staging/r8188eu/hal/rtl8188e_hal_init.c  | 260 ++++++++---
> Â drivers/staging/r8188eu/hal/rtl8188e_phycfg.c |Â 26 +-
> Â drivers/staging/r8188eu/hal/rtl8188e_sreset.c |Â 20 +-
>  drivers/staging/r8188eu/hal/rtl8188eu_led.c  | 17 +-
>  drivers/staging/r8188eu/hal/usb_halinit.c    | 412 ++++++++++++++--
> --
>  drivers/staging/r8188eu/hal/usb_ops_linux.c  | 55 ++-
>  drivers/staging/r8188eu/include/hal_intf.h   |  6 +-
>  .../staging/r8188eu/include/rtl8188e_hal.h   |  2 +-
>  drivers/staging/r8188eu/include/rtw_efuse.h  |  4 +-
>  drivers/staging/r8188eu/include/rtw_io.h     | 18 +-
>  drivers/staging/r8188eu/include/rtw_mp.h     |  2 +-
>  drivers/staging/r8188eu/os_dep/ioctl_linux.c | 168 +++++--
>  drivers/staging/r8188eu/os_dep/usb_intf.c    |  4 +-
> Â 26 files changed, 1072 insertions(+), 301 deletions(-)
>
Dear Pavel,
Firstly, thank you for this contribution, it is much appreciated.
Whilst I'm still learning myself when it comes to this driver and to
kernel code in general, I can certainly say the code looks pretty good
in general so far. I will try and offer individual comments on each
patch.
Regards,
Phil
On Fri, 2021-08-20 at 20:07 +0300, Pavel Skripkin wrote:
> Since read_macreg() calls rtw_read*() internally we should tell
> callers about an error on the read side.
>
> Signed-off-by: Pavel Skripkin <[email protected]>
> ---
>  drivers/staging/r8188eu/core/rtw_mp.c   | 9 ++++-----
> Â drivers/staging/r8188eu/include/rtw_mp.h | 2 +-
> Â 2 files changed, 5 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/staging/r8188eu/core/rtw_mp.c
> b/drivers/staging/r8188eu/core/rtw_mp.c
> index 601a1fd5d4e7..6bbea1cc364a 100644
> --- a/drivers/staging/r8188eu/core/rtw_mp.c
> +++ b/drivers/staging/r8188eu/core/rtw_mp.c
> @@ -7,20 +7,19 @@
> Â #include "../include/odm_precomp.h"
> Â #include "../include/rtl8188e_hal.h"
> Â
> -u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz)
> +u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz, int
> *error)
Dear Pavel,
Correct me if I'm wrong, but this read_macreg function seems to be
completely unused by the rest of the driver. Rather than changing the
signature to do error handling, maybe it would be better to just remove
it?
That is just my view though, would be interested to see what others
think - perhaps it could come in handy at some point.
Regards,
Phil
On Fri, 2021-08-20 at 20:07 +0300, Pavel Skripkin wrote:
> rtw_read*() functions call usb_read* inside. These functions could
> fail
> in some cases; for example: failed to receive control message. These
> cases should be handled to prevent uninit value bugs, since usb_read*
> functions blindly return stack variable without checking if this
> value
> _actualy_ initialized.
>
> To achive it, all usb_read* and rtw_read*() argument list is expanded
> with pointer to error and added error usbctrl_vendorreq() error
> checking.
> If transfer is successful error will be initialized to 0 otherwise to
> error returned from usb_control_msg().
>
> To not break the build, added error checking for rtw_read*() call all
> across the driver.
>
> Signed-off-by: Pavel Skripkin <[email protected]>
> ---
>  drivers/staging/r8188eu/core/rtw_debug.c     | 79 +++-
>  drivers/staging/r8188eu/core/rtw_efuse.c     | 83 +++-
>  drivers/staging/r8188eu/core/rtw_io.c        | 18 +-
>  drivers/staging/r8188eu/core/rtw_mp.c        | 37 +-
>  drivers/staging/r8188eu/core/rtw_mp_ioctl.c  | 20 +-
>  drivers/staging/r8188eu/core/rtw_pwrctrl.c   |  6 +-
>  drivers/staging/r8188eu/core/rtw_sreset.c    |  7 +-
>  drivers/staging/r8188eu/hal/HalPwrSeqCmd.c   |  9 +-
>  drivers/staging/r8188eu/hal/hal_com.c        | 22 +-
>  drivers/staging/r8188eu/hal/odm_interface.c  | 12 +-
>  drivers/staging/r8188eu/hal/rtl8188e_cmd.c   | 37 +-
>  drivers/staging/r8188eu/hal/rtl8188e_dm.c    |  6 +-
>  .../staging/r8188eu/hal/rtl8188e_hal_init.c  | 198 +++++++--
> Â drivers/staging/r8188eu/hal/rtl8188e_phycfg.c |Â 26 +-
> Â drivers/staging/r8188eu/hal/rtl8188e_sreset.c |Â 20 +-
>  drivers/staging/r8188eu/hal/rtl8188eu_led.c  | 17 +-
>  drivers/staging/r8188eu/hal/usb_halinit.c    | 394 ++++++++++++++--
> --
>  drivers/staging/r8188eu/hal/usb_ops_linux.c  | 16 +-
>  drivers/staging/r8188eu/include/rtw_io.h     | 18 +-
>  drivers/staging/r8188eu/os_dep/ioctl_linux.c | 168 +++++---
> Â 20 files changed, 941 insertions(+), 252 deletions(-)
>
...
> diff --git a/drivers/staging/r8188eu/hal/usb_ops_linux.c
> b/drivers/staging/r8188eu/hal/usb_ops_linux.c
> index 953fa05dc30c..980af6c02be5 100644
> --- a/drivers/staging/r8188eu/hal/usb_ops_linux.c
> +++ b/drivers/staging/r8188eu/hal/usb_ops_linux.c
> @@ -101,29 +101,31 @@ static int usbctrl_vendorreq(struct intf_hdl
> *pintfhdl, u16 value, void *pdata,
> Â Â Â Â Â Â Â Â return status;
> Â }
> Â
> -static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr)
> +static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr, int *error)
> Â {
> Â Â Â Â Â Â Â Â u8 requesttype;
> Â Â Â Â Â Â Â Â u16 wvalue;
> Â Â Â Â Â Â Â Â u16 len;
> Â Â Â Â Â Â Â Â u8 data = 0;
> +Â Â Â Â Â Â Â int res;
> Â
> -
> +Â Â Â Â Â Â Â if (unlikely(!error))
> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â WARN_ON_ONCE("r8188eu: Reading w/o error checking is
> bad idea\n");
> Â
> Â Â Â Â Â Â Â Â requesttype = 0x01;/* read_in */
> Â
> Â Â Â Â Â Â Â Â wvalue = (u16)(addr & 0x0000ffff);
> Â Â Â Â Â Â Â Â len = 1;
> Â
> -Â Â Â Â Â Â Â usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> -
> -
> +Â Â Â Â Â Â Â res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len,
> requesttype);
> +Â Â Â Â Â Â Â if (likely(error))
> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â *error = res < 0? res: 0;
> Â
> Â Â Â Â Â Â Â Â return data;
> Â
> Â }
> Â
> -static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
> +static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr, int
> *error)
> Â {
> Â Â Â Â Â Â Â Â u8 requesttype;
> Â Â Â Â Â Â Â Â u16 wvalue;
> @@ -138,7 +140,7 @@ static u16 usb_read16(struct intf_hdl *pintfhdl,
> u32 addr)
> Â Â Â Â Â Â Â Â return (u16)(le32_to_cpu(data) & 0xffff);
> Â }
> Â
> -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> +static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr, int
> *error)
> Â {
> Â Â Â Â Â Â Â Â u8 requesttype;
> Â Â Â Â Â Â Â Â u16 wvalue;
Dear Pavel,
For this patch, you modify the signature of the usb_read*() functions,
but only introduce the usbctrl_vendorreq checks for usb_read8.
I can see from the following patch that you have done the others too
later on, but really I would say for changes like this, they should be
grouped in the same patch. Also, just me nitpicking probably, but the
patch is rather large - sometimes unavoidable I know, but perhaps
better to group logically into areas (files or types of change) in
order to get the patches smaller and thus more easily reviewable. Many
thanks.
In terms of what we do with the errors, I would invite comments from
others on this too due to my inexperience, but I like your thinking.
Regards,
Phil
On Fri, 20 Aug 2021 at 18:07, Pavel Skripkin <[email protected]> wrote:
>
> ReadEFuseByte() internally calls rtw_read8() which can fail. To avoid
> uninit value bugs we should properly handle error sutiation and deliver
> the error to caller.
>
> To achieve it, some functions now return an int, and the error
> which could occur in ReadEFuseByte() is handled on the top level.
>
> Signed-off-by: Pavel Skripkin <[email protected]>
> ---
> drivers/staging/r8188eu/core/rtw_efuse.c | 46 +++++++++-----
> drivers/staging/r8188eu/hal/hal_intf.c | 6 +-
> .../staging/r8188eu/hal/rtl8188e_hal_init.c | 62 +++++++++++++------
> drivers/staging/r8188eu/hal/usb_halinit.c | 20 ++++--
> drivers/staging/r8188eu/hal/usb_ops_linux.c | 43 +++++++++++--
> drivers/staging/r8188eu/include/hal_intf.h | 6 +-
> .../staging/r8188eu/include/rtl8188e_hal.h | 2 +-
> drivers/staging/r8188eu/include/rtw_efuse.h | 4 +-
> drivers/staging/r8188eu/os_dep/usb_intf.c | 4 +-
> 9 files changed, 138 insertions(+), 55 deletions(-)
>
Dear Pavel,
I like the code, just a few things though:
(1) the comments I made in the previous e-mail r.e. what we actually
do with the errors, and grouping logically related changes (the rest
of the usb_read*() changes being in this patch for example).
(2) I got trailing whitespace errors from this patch and the last one.
For a v2 I would say stripping the whitespace is a good idea too - I
have submitted many patches myself to this driver that had whitespace
in - indeed, the original version of my patch series to import the
driver still had a load as well :-)
Regards,
Phil
Dear Pavel
On Saturday, August 21, 2021 1:51:57 AM CEST Phillip Potter wrote:
> On Fri, 20 Aug 2021 at 18:07, Pavel Skripkin <[email protected]> wrote:
> >
> > ReadEFuseByte() internally calls rtw_read8() which can fail. To avoid
> > uninit value bugs we should properly handle error sutiation and deliver
sutiation --> situation.
> > the error to caller.
> >
> > To achieve it, some functions now return an int, and the error
> > which could occur in ReadEFuseByte() is handled on the top level.
> >
> > Signed-off-by: Pavel Skripkin <[email protected]>
> > ---
> > drivers/staging/r8188eu/core/rtw_efuse.c | 46 +++++++++-----
> > drivers/staging/r8188eu/hal/hal_intf.c | 6 +-
> > .../staging/r8188eu/hal/rtl8188e_hal_init.c | 62 +++++++++++++------
> > drivers/staging/r8188eu/hal/usb_halinit.c | 20 ++++--
> > drivers/staging/r8188eu/hal/usb_ops_linux.c | 43 +++++++++++--
> > drivers/staging/r8188eu/include/hal_intf.h | 6 +-
> > .../staging/r8188eu/include/rtl8188e_hal.h | 2 +-
> > drivers/staging/r8188eu/include/rtw_efuse.h | 4 +-
> > drivers/staging/r8188eu/os_dep/usb_intf.c | 4 +-
> > 9 files changed, 138 insertions(+), 55 deletions(-)
> >
Please change the Subject: ReadFuse --> ReadEFuse() or
ReadFuse --> ReadEFuseByte().
>
> Dear Pavel,
>
> I like the code, just a few things though:
> (1) the comments I made in the previous e-mail r.e. what we actually
> do with the errors, and grouping logically related changes (the rest
> of the usb_read*() changes being in this patch for example).
I agree with Philip on splitting 1/3 into more patches, perhaps one for each
of the three rtw_read*(), but I disagree on merging the usb_read*() changes
into this. They should go to another patch because they are not strictly
related to "add[ing] error handling to ReadFuse".
Regards,
Fabio
> (2) I got trailing whitespace errors from this patch and the last one.
> For a v2 I would say stripping the whitespace is a good idea too - I
> have submitted many patches myself to this driver that had whitespace
> in - indeed, the original version of my patch series to import the
> driver still had a load as well :-)
>
> Regards,
> Phil
>
On Friday, August 20, 2021 7:07:36 PM CEST Pavel Skripkin wrote:
> rtw_read*() functions call usb_read* inside. These functions could fail
> in some cases; for example: failed to receive control message. These
> cases should be handled to prevent uninit value bugs, since usb_read*
> functions blindly return stack variable without checking if this value
> _actualy_ initialized.
>
> To achive it, all usb_read* and rtw_read*() argument list is expanded
Dear Pavel,
Please, achive --> achieve.
> with pointer to error and added error usbctrl_vendorreq() error checking.
> If transfer is successful error will be initialized to 0 otherwise to
> error returned from usb_control_msg().
>
> To not break the build, added error checking for rtw_read*() call all
> across the driver.
>
> Signed-off-by: Pavel Skripkin <[email protected]>
> ---
> drivers/staging/r8188eu/core/rtw_debug.c | 79 +++-
> drivers/staging/r8188eu/core/rtw_efuse.c | 83 +++-
> drivers/staging/r8188eu/core/rtw_io.c | 18 +-
> drivers/staging/r8188eu/core/rtw_mp.c | 37 +-
> drivers/staging/r8188eu/core/rtw_mp_ioctl.c | 20 +-
> drivers/staging/r8188eu/core/rtw_pwrctrl.c | 6 +-
> drivers/staging/r8188eu/core/rtw_sreset.c | 7 +-
> drivers/staging/r8188eu/hal/HalPwrSeqCmd.c | 9 +-
> drivers/staging/r8188eu/hal/hal_com.c | 22 +-
> drivers/staging/r8188eu/hal/odm_interface.c | 12 +-
> drivers/staging/r8188eu/hal/rtl8188e_cmd.c | 37 +-
> drivers/staging/r8188eu/hal/rtl8188e_dm.c | 6 +-
> .../staging/r8188eu/hal/rtl8188e_hal_init.c | 198 +++++++--
> drivers/staging/r8188eu/hal/rtl8188e_phycfg.c | 26 +-
> drivers/staging/r8188eu/hal/rtl8188e_sreset.c | 20 +-
> drivers/staging/r8188eu/hal/rtl8188eu_led.c | 17 +-
> drivers/staging/r8188eu/hal/usb_halinit.c | 394 ++++++++++++++----
> drivers/staging/r8188eu/hal/usb_ops_linux.c | 16 +-
> drivers/staging/r8188eu/include/rtw_io.h | 18 +-
> drivers/staging/r8188eu/os_dep/ioctl_linux.c | 168 +++++---
> 20 files changed, 941 insertions(+), 252 deletions(-)
I agree with Philip: please, split this long patch. If I were you, I'd make
one patch for each of the three rtw_read*() and a fourth patch for usb_read*().
> --- a/drivers/staging/r8188eu/core/rtw_io.c
> +++ b/drivers/staging/r8188eu/core/rtw_io.c
> @@ -34,44 +34,44 @@ [email protected]
> #define rtw_cpu_to_le16(val) cpu_to_le16(val)
> #define rtw_cpu_to_le32(val) cpu_to_le32(val)
Not related to your patch, these macros are useless and misleading.
> -u8 _rtw_read8(struct adapter *adapter, u32 addr)
> +u8 _rtw_read8(struct adapter *adapter, u32 addr, int *error)
> {
> 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);
> + u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr, int *error);
>
>
> _read8 = pintfhdl->io_ops._read8;
> - r_val = _read8(pintfhdl, addr);
> + r_val = _read8(pintfhdl, addr, error);
>
> return r_val;
> }
I really don't like passing errors through arguments. Why don't you pass
a storage location where the function save the byte read and instead use the
return for errors? I think that this would result in a cleaner design. Furthermore,
it is used everywhere in the kernel.
> -u16 _rtw_read16(struct adapter *adapter, u32 addr)
> +u16 _rtw_read16(struct adapter *adapter, u32 addr, int *error)
> {
> u16 r_val;
> struct io_priv *pio_priv = &adapter->iopriv;
> struct intf_hdl *pintfhdl = &pio_priv->intf;
> - u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
> + u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr, int *error);
>
> _read16 = pintfhdl->io_ops._read16;
>
> - r_val = _read16(pintfhdl, addr);
> + r_val = _read16(pintfhdl, addr, error);
>
> return r_val;
> }
Same.
> -u32 _rtw_read32(struct adapter *adapter, u32 addr)
> +u32 _rtw_read32(struct adapter *adapter, u32 addr, int *error)
> {
> u32 r_val;
> struct io_priv *pio_priv = &adapter->iopriv;
> struct intf_hdl *pintfhdl = &pio_priv->intf;
> - u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
> + u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr, int *error);
>
> _read32 = pintfhdl->io_ops._read32;
>
> - r_val = _read32(pintfhdl, addr);
> + r_val = _read32(pintfhdl, addr, error);
>
> return r_val;
> }
Same.
I'm done for now: too many lines to read all at once :)
Regards,
Fabio
On 8/21/21 8:55 AM, Fabio M. De Francesco wrote:
> On Friday, August 20, 2021 7:07:36 PM CEST Pavel Skripkin wrote:
>> rtw_read*() functions call usb_read* inside. These functions could fail
>> in some cases; for example: failed to receive control message. These
>> cases should be handled to prevent uninit value bugs, since usb_read*
>> functions blindly return stack variable without checking if this value
>> _actualy_ initialized.
>>
>> To achive it, all usb_read* and rtw_read*() argument list is expanded
>
> Dear Pavel,
>
> Please, achive --> achieve.
>
>> with pointer to error and added error usbctrl_vendorreq() error checking.
>> If transfer is successful error will be initialized to 0 otherwise to
>> error returned from usb_control_msg().
>>
>> To not break the build, added error checking for rtw_read*() call all
>> across the driver.
>>
>> Signed-off-by: Pavel Skripkin <[email protected]>
>> ---
>> drivers/staging/r8188eu/core/rtw_debug.c | 79 +++-
>> drivers/staging/r8188eu/core/rtw_efuse.c | 83 +++-
>> drivers/staging/r8188eu/core/rtw_io.c | 18 +-
>> drivers/staging/r8188eu/core/rtw_mp.c | 37 +-
>> drivers/staging/r8188eu/core/rtw_mp_ioctl.c | 20 +-
>> drivers/staging/r8188eu/core/rtw_pwrctrl.c | 6 +-
>> drivers/staging/r8188eu/core/rtw_sreset.c | 7 +-
>> drivers/staging/r8188eu/hal/HalPwrSeqCmd.c | 9 +-
>> drivers/staging/r8188eu/hal/hal_com.c | 22 +-
>> drivers/staging/r8188eu/hal/odm_interface.c | 12 +-
>> drivers/staging/r8188eu/hal/rtl8188e_cmd.c | 37 +-
>> drivers/staging/r8188eu/hal/rtl8188e_dm.c | 6 +-
>> .../staging/r8188eu/hal/rtl8188e_hal_init.c | 198 +++++++--
>> drivers/staging/r8188eu/hal/rtl8188e_phycfg.c | 26 +-
>> drivers/staging/r8188eu/hal/rtl8188e_sreset.c | 20 +-
>> drivers/staging/r8188eu/hal/rtl8188eu_led.c | 17 +-
>> drivers/staging/r8188eu/hal/usb_halinit.c | 394 ++++++++++++++----
>> drivers/staging/r8188eu/hal/usb_ops_linux.c | 16 +-
>> drivers/staging/r8188eu/include/rtw_io.h | 18 +-
>> drivers/staging/r8188eu/os_dep/ioctl_linux.c | 168 +++++---
>> 20 files changed, 941 insertions(+), 252 deletions(-)
>
Hi, Fabio!
Thank you for feedback
> I agree with Philip: please, split this long patch. If I were you, I'd make
> one patch for each of the three rtw_read*() and a fourth patch for usb_read*().
>
Make sense. Will fix in v2.
>> --- a/drivers/staging/r8188eu/core/rtw_io.c
>> +++ b/drivers/staging/r8188eu/core/rtw_io.c
>> @@ -34,44 +34,44 @@ [email protected]
>> #define rtw_cpu_to_le16(val) cpu_to_le16(val)
>> #define rtw_cpu_to_le32(val) cpu_to_le32(val)
>
> Not related to your patch, these macros are useless and misleading.
>
Sorry, I don't get it. I didn't touch these macros, it's part of diffstat.
>> -u8 _rtw_read8(struct adapter *adapter, u32 addr)
>> +u8 _rtw_read8(struct adapter *adapter, u32 addr, int *error)
>> {
>> 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);
>> + u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr, int *error);
>>
>>
>> _read8 = pintfhdl->io_ops._read8;
>> - r_val = _read8(pintfhdl, addr);
>> + r_val = _read8(pintfhdl, addr, error);
>>
>> return r_val;
>> }
>
> I really don't like passing errors through arguments. Why don't you pass
> a storage location where the function save the byte read and instead use the
> return for errors? I think that this would result in a cleaner design. Furthermore,
> it is used everywhere in the kernel.
>
Yep, this will be more cleaner, but I decided to receive some feedback
first about the idea. If this error handling is really necessary, I will
rework this approach :)
>> -u16 _rtw_read16(struct adapter *adapter, u32 addr)
>> +u16 _rtw_read16(struct adapter *adapter, u32 addr, int *error)
>> {
>> u16 r_val;
>> struct io_priv *pio_priv = &adapter->iopriv;
>> struct intf_hdl *pintfhdl = &pio_priv->intf;
>> - u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
>> + u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr, int *error);
>>
>> _read16 = pintfhdl->io_ops._read16;
>>
>> - r_val = _read16(pintfhdl, addr);
>> + r_val = _read16(pintfhdl, addr, error);
>>
>> return r_val;
>> }
>
> Same.
>
>> -u32 _rtw_read32(struct adapter *adapter, u32 addr)
>> +u32 _rtw_read32(struct adapter *adapter, u32 addr, int *error)
>> {
>> u32 r_val;
>> struct io_priv *pio_priv = &adapter->iopriv;
>> struct intf_hdl *pintfhdl = &pio_priv->intf;
>> - u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
>> + u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr, int *error);
>>
>> _read32 = pintfhdl->io_ops._read32;
>>
>> - r_val = _read32(pintfhdl, addr);
>> + r_val = _read32(pintfhdl, addr, error);
>>
>> return r_val;
>> }
>
> Same.
>
> I'm done for now: too many lines to read all at once :)
>
With regards,
Pavel Skripkin
On 8/21/21 2:18 AM, Phillip Potter wrote:
> On Fri, 2021-08-20 at 20:07 +0300, Pavel Skripkin wrote:
>> Since read_macreg() calls rtw_read*() internally we should tell
>> callers about an error on the read side.
>>
>> Signed-off-by: Pavel Skripkin <[email protected]>
>> ---
>>  drivers/staging/r8188eu/core/rtw_mp.c   | 9 ++++-----
>> Â drivers/staging/r8188eu/include/rtw_mp.h | 2 +-
>> Â 2 files changed, 5 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/staging/r8188eu/core/rtw_mp.c
>> b/drivers/staging/r8188eu/core/rtw_mp.c
>> index 601a1fd5d4e7..6bbea1cc364a 100644
>> --- a/drivers/staging/r8188eu/core/rtw_mp.c
>> +++ b/drivers/staging/r8188eu/core/rtw_mp.c
>> @@ -7,20 +7,19 @@
>> Â #include "../include/odm_precomp.h"
>> Â #include "../include/rtl8188e_hal.h"
>>
>> -u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz)
>> +u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz, int
>> *error)
>
> Dear Pavel,
>
> Correct me if I'm wrong, but this read_macreg function seems to be
> completely unused by the rest of the driver. Rather than changing the
> signature to do error handling, maybe it would be better to just remove
> it?
>
> That is just my view though, would be interested to see what others
> think - perhaps it could come in handy at some point.
>
yes, this function is unused for now, but I am aware about plans for
this function :) If no one has plans for it, it can be removed.
With regards,
Pavel Skripkin
On 8/21/21 2:12 AM, Phillip Potter wrote:
> On Fri, 2021-08-20 at 20:07 +0300, Pavel Skripkin wrote:
>> Hi, Greg, Larry and Phillip!
>>
>> I noticed, that new staging driver was added like 3 weeks ago and I
>> decided
>> to look at the code, because drivers in staging directory are always
>> buggy.
>>
>> The first thing I noticed is *no one* was checking read operations
>> result, but
>> it can fail and driver may start writing random stack values into
>> registers. It
>> can cause driver misbehavior or device misbehavior.
>>
>> To avoid this type of bugs, i've expanded read() API with error
>> parametr,
>> which will be initialized to error if read fails. It helps callers to
>> break/return earlier and don't write random values to registers or to
>> rely
>> on random values.
>>
>> Why is this pacth series RFC?
>> Â 1. I don't have this device and I cannot test these changes.
>> Â 2. I don't know how to handle errors in each particular case. For
>> now, function
>> Â Â Â Â just returns or returns an error. That's all. I hope, driver
>> maintainers will
>> Â Â Â Â help with these bits.
>> Â 3. I guess, I handled not all uninit value bugs here. I hope, I
>> fixed
>> Â Â Â Â at least half of them
>>
>> This series was build-tested and made on top of staging-testing
>> branch
>>
>>
>> With regards,
>> Pavel Skripkin
>>
>> Pavel Skripkin (3):
>> Â staging: r8188eu: add proper rtw_read* error handling
>> Â staging: r8188eu: add error handling to ReadFuse
>> Â staging: r8188eu: add error argument to read_macreg
>>
>>  drivers/staging/r8188eu/core/rtw_debug.c     | 79 +++-
>>  drivers/staging/r8188eu/core/rtw_efuse.c     | 119 +++--
>>  drivers/staging/r8188eu/core/rtw_io.c        | 18 +-
>>  drivers/staging/r8188eu/core/rtw_mp.c        | 38 +-
>>  drivers/staging/r8188eu/core/rtw_mp_ioctl.c  | 20 +-
>>  drivers/staging/r8188eu/core/rtw_pwrctrl.c   |  6 +-
>>  drivers/staging/r8188eu/core/rtw_sreset.c    |  7 +-
>>  drivers/staging/r8188eu/hal/HalPwrSeqCmd.c   |  9 +-
>>  drivers/staging/r8188eu/hal/hal_com.c        | 22 +-
>>  drivers/staging/r8188eu/hal/hal_intf.c       |  6 +-
>>  drivers/staging/r8188eu/hal/odm_interface.c  | 12 +-
>>  drivers/staging/r8188eu/hal/rtl8188e_cmd.c   | 37 +-
>>  drivers/staging/r8188eu/hal/rtl8188e_dm.c    |  6 +-
>>  .../staging/r8188eu/hal/rtl8188e_hal_init.c  | 260 ++++++++---
>> Â drivers/staging/r8188eu/hal/rtl8188e_phycfg.c |Â 26 +-
>> Â drivers/staging/r8188eu/hal/rtl8188e_sreset.c |Â 20 +-
>>  drivers/staging/r8188eu/hal/rtl8188eu_led.c  | 17 +-
>>  drivers/staging/r8188eu/hal/usb_halinit.c    | 412 ++++++++++++++--
>> --
>>  drivers/staging/r8188eu/hal/usb_ops_linux.c  | 55 ++-
>>  drivers/staging/r8188eu/include/hal_intf.h   |  6 +-
>>  .../staging/r8188eu/include/rtl8188e_hal.h   |  2 +-
>>  drivers/staging/r8188eu/include/rtw_efuse.h  |  4 +-
>>  drivers/staging/r8188eu/include/rtw_io.h     | 18 +-
>>  drivers/staging/r8188eu/include/rtw_mp.h     |  2 +-
>>  drivers/staging/r8188eu/os_dep/ioctl_linux.c | 168 +++++--
>>  drivers/staging/r8188eu/os_dep/usb_intf.c    |  4 +-
>> Â 26 files changed, 1072 insertions(+), 301 deletions(-)
>>
>
> Dear Pavel,
>
> Firstly, thank you for this contribution, it is much appreciated.
> Whilst I'm still learning myself when it comes to this driver and to
> kernel code in general, I can certainly say the code looks pretty good
> in general so far. I will try and offer individual comments on each
> patch.
>
Thank you for your feedback. So, I will prepare a v2 version in few days
and, I think, I will leave RFC prefix.
Also, I want to receive some feedback from Larry about error handling in
each particular case, I guess, he can help us with it.
So, I will split each rtw_read* changes into separate patche and make
them return an error instead of read value.
Again, big thanks to you and Fabio for feedback, I appreciate it :)
With regards,
Pavel Skripkin
On Saturday, August 21, 2021 12:35:48 PM CEST Pavel Skripkin wrote:
> On 8/21/21 8:55 AM, Fabio M. De Francesco wrote:
> > On Friday, August 20, 2021 7:07:36 PM CEST Pavel Skripkin wrote:
> >> rtw_read*() functions call usb_read* inside. These functions could fail
> >> in some cases; for example: failed to receive control message. These
> >> cases should be handled to prevent uninit value bugs, since usb_read*
> >> functions blindly return stack variable without checking if this value
> >> _actualy_ initialized.
> >>
> >> To achive it, all usb_read* and rtw_read*() argument list is expanded
> >
> > []
> >
> >> --- a/drivers/staging/r8188eu/core/rtw_io.c
> >> +++ b/drivers/staging/r8188eu/core/rtw_io.c
> >> @@ -34,44 +34,44 @@ [email protected]
> >> #define rtw_cpu_to_le16(val) cpu_to_le16(val)
> >> #define rtw_cpu_to_le32(val) cpu_to_le32(val)
> >
> > Not related to your patch, these macros are useless and misleading.
> >
>
> Sorry, I don't get it. I didn't touch these macros, it's part of diffstat.
Yes, correct; in fact I wrote: "not related to your patch".
I just saw those macros while reading your patch. The code is I just noticed
that those macros are useless (in case someone wanted to
address that issue).
Obviously, if you find it interesting, you shouldn't do that in your series,
because it is entirely unrelated to the purpose of your work.
I hope now I've made it clearer, sorry.
Regards,
Fabio
On Friday, August 20, 2021 7:07:28 PM CEST Pavel Skripkin wrote:
> Hi, Greg, Larry and Phillip!
>
> I noticed, that new staging driver was added like 3 weeks ago and I decided
> to look at the code, because drivers in staging directory are always buggy.
>
> The first thing I noticed is *no one* was checking read operations result,
but
> it can fail and driver may start writing random stack values into registers.
It
> can cause driver misbehavior or device misbehavior.
After the messages I wrote yesterday, I had some minutes to look deeper at the
code that would be changed by these patches.
I think that it does not look like that the driver could return "random stack
values into registers" and I think this entire series in unnecessary.
As far as I understand this driver (though I must admit that I really don't
know how to write drivers, and I'm not interested in understanding - at the
moment, at least), all the usb_read*() call usbctrl_vendorreq() and the latter
*does* proper error checking before returning to the callers the read data.
Please, look at the code copied from usbctrl_vendorreq() and pasted here (some
comments are mine):
/* start of code */
static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u16 value, void
*pdata, u16 len, u8 requesttype)
{
/* test if everything is OK for transfers and setup the necessary variables */
[...]
status = usb_control_msg(udev, pipe, REALTEK_USB_VENQT_CMD_REQ,
reqtype, value,
REALTEK_USB_VENQT_CMD_IDX,
pIo_buf, len,
RTW_USB_CONTROL_MSG_TIMEOUT);
if (status == len) { /* Success this control transfer. */
rtw_reset_continual_urb_error(dvobjpriv);
if (requesttype == 0x01)
memcpy(pdata, pIo_buf, len); /* pdata
receives the read data */
} else { /* error cases */
[...]
}
/* end of code */
So, *I cannot ack this RFC*, unless maintainers say I'm missing something.
Larry, Philip, since you have much more knowledge than me about r8188eu (and,
more in general, on device drivers) may you please say what you think about my
arguments against this series?
Thanks,
Fabio
> To avoid this type of bugs, i've expanded read() API with error parametr,
> which will be initialized to error if read fails. It helps callers to
> break/return earlier and don't write random values to registers or to rely
> on random values.
>
> Why is this pacth series RFC?
> 1. I don't have this device and I cannot test these changes.
> 2. I don't know how to handle errors in each particular case. For now,
function
> just returns or returns an error. That's all. I hope, driver
maintainers will
> help with these bits.
> 3. I guess, I handled not all uninit value bugs here. I hope, I fixed
> at least half of them
>
> This series was build-tested and made on top of staging-testing branch
>
>
> With regards,
> Pavel Skripkin
On 8/22/21 12:53 PM, Fabio M. De Francesco wrote:
> On Friday, August 20, 2021 7:07:28 PM CEST Pavel Skripkin wrote:
>> Hi, Greg, Larry and Phillip!
>>
>> I noticed, that new staging driver was added like 3 weeks ago and I decided
>> to look at the code, because drivers in staging directory are always buggy.
>>
>> The first thing I noticed is *no one* was checking read operations result,
> but
>> it can fail and driver may start writing random stack values into registers.
> It
>> can cause driver misbehavior or device misbehavior.
>
> After the messages I wrote yesterday, I had some minutes to look deeper at the
> code that would be changed by these patches.
>
> I think that it does not look like that the driver could return "random stack
> values into registers" and I think this entire series in unnecessary.
>
> As far as I understand this driver (though I must admit that I really don't
> know how to write drivers, and I'm not interested in understanding - at the
> moment, at least), all the usb_read*() call usbctrl_vendorreq() and the latter
> *does* proper error checking before returning to the callers the read data.
>
> Please, look at the code copied from usbctrl_vendorreq() and pasted here (some
> comments are mine):
>
> /* start of code */
> static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u16 value, void
> *pdata, u16 len, u8 requesttype)
> {
>
> /* test if everything is OK for transfers and setup the necessary variables */
> [...]
>
> status = usb_control_msg(udev, pipe, REALTEK_USB_VENQT_CMD_REQ,
> reqtype, value,
> REALTEK_USB_VENQT_CMD_IDX,
> pIo_buf, len,
> RTW_USB_CONTROL_MSG_TIMEOUT);
>
> if (status == len) { /* Success this control transfer. */
> rtw_reset_continual_urb_error(dvobjpriv);
> if (requesttype == 0x01)
> memcpy(pdata, pIo_buf, len); /* pdata
> receives the read data */
> } else { /* error cases */
>
> [...]
>
> }
> /* end of code */
>
> So, *I cannot ack this RFC*, unless maintainers say I'm missing something.
>
> Larry, Philip, since you have much more knowledge than me about r8188eu (and,
> more in general, on device drivers) may you please say what you think about my
> arguments against this series?
>
Hi, Fabio!
Thank you for looking into this, but I still can see the case when pdata
won't be initialized:
pdata is initialized only in case of successful transfer, i.e len > 0.
It means some data was received (maybe not full length, but anyway). In
case of usb_control_msg() error (for example -ENOMEM) code only does
this code block:
if (status < 0) {
if (status == (-ESHUTDOWN) || status == -ENODEV) {
adapt->bSurpriseRemoved = true;
} else {
struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
haldata->srestpriv.Wifi_Error_Status = USB_VEN_REQ_CMD_FAIL;
}
}
And then just loops further. In case of 10 ENOMEM in a row,. passed
pdata won't be initialized at all and driver doesn't do anything about
it. I believe, it's not good approach to play with random values. We
should somehow handle transfer errors all across the driver.
If I am missing something, please, let me know :)
With regards,
Pavel Skripkin
On Sunday, August 22, 2021 12:09:29 PM CEST Pavel Skripkin wrote:
> On 8/22/21 12:53 PM, Fabio M. De Francesco wrote:
> > On Friday, August 20, 2021 7:07:28 PM CEST Pavel Skripkin wrote:
> >> Hi, Greg, Larry and Phillip!
> >>
> >> I noticed, that new staging driver was added like 3 weeks ago and I
decided
> >> to look at the code, because drivers in staging directory are always
buggy.
> >>
> >> The first thing I noticed is *no one* was checking read operations
result,
> >
> > but
> >
> >> it can fail and driver may start writing random stack values into
registers.
> >
> > It
> >
> >> can cause driver misbehavior or device misbehavior.
> >
> > After the messages I wrote yesterday, I had some minutes to look deeper at
the
> > code that would be changed by these patches.
> >
> > I think that it does not look like that the driver could return "random
stack
> > values into registers" and I think this entire series in unnecessary.
> >
> > As far as I understand this driver (though I must admit that I really
don't
> > know how to write drivers, and I'm not interested in understanding - at
the
> > moment, at least), all the usb_read*() call usbctrl_vendorreq() and the
latter
> > *does* proper error checking before returning to the callers the read
data.
> >
> > Please, look at the code copied from usbctrl_vendorreq() and pasted here
(some
> > comments are mine):
> >
> > /* start of code */
> > static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u16 value, void
> > *pdata, u16 len, u8 requesttype)
> > {
> >
> > /* test if everything is OK for transfers and setup the necessary
variables */
> > [...]
> >
> > status = usb_control_msg(udev, pipe, REALTEK_USB_VENQT_CMD_REQ,
> >
> > reqtype, value,
> >
> > REALTEK_USB_VENQT_CMD_IDX,
> >
> > pIo_buf, len,
> >
> > RTW_USB_CONTROL_MSG_TIMEOUT);
> >
> > if (status == len) { /* Success this control transfer.
*/
> >
> > rtw_reset_continual_urb_error(dvobjpriv);
> > if (requesttype == 0x01)
> >
> > memcpy(pdata, pIo_buf, len); /* pdata
> >
> > receives the read data */
> >
> > } else { /* error cases */
> >
> > [...]
> >
> > }
> > /* end of code */
> >
> > So, *I cannot ack this RFC*, unless maintainers say I'm missing something.
> >
> > Larry, Philip, since you have much more knowledge than me about r8188eu
(and,
> > more in general, on device drivers) may you please say what you think
about my
> > arguments against this series?
>
> Hi, Fabio!
>
> Thank you for looking into this, but I still can see the case when pdata
> won't be initialized:
>
>
> pdata is initialized only in case of successful transfer, i.e len > 0.
> It means some data was received (maybe not full length, but anyway). In
> case of usb_control_msg() error (for example -ENOMEM) code only does
> this code block:
>
> if (status < 0) {
> if (status == (-ESHUTDOWN) || status == -ENODEV) {
> adapt->bSurpriseRemoved = true;
> } else {
> struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
> haldata->srestpriv.Wifi_Error_Status =
USB_VEN_REQ_CMD_FAIL;
> }
> }
It's up to the callers of _rtw_usb*() to check return values and then act
accordingly.
It doesn't matter whether or not *pdata is initialized because usb_read*()
returns data = 0 if usb_control_msg() has not initialized/changed its third
parameter. Then _rtw_read*() receive 0 or initialized data depending on errors
or no errors. Finally _rtw_read*() returns that same value to the callers (via
r_val).
So, it's up to the callers to test if (!_rtw_read*()) and then act
accordingly. If they get 0 they should know how to handle the errors.
Furthermore, we have already either adapt->bSurpriseRemoved = true or haldata-
>srestpriv.Wifi_Error_Status = USB_VEN_REQ_CMD_FAIL. Depending on contexts
where _rtw_read*() are called, perhaps they could also check the two variables
above.
In summation. if anything should be changed, it is the code of the callers of
_rtw_read*() if you find out they they don't properly handle the returning
values of this function. You should find every place where _rtw_read*() are
called and figure out if the returns are properly checked and handled; if not,
make some change only there.
Larry, Philip, where are you? Am I missing something?
Thanks,
Fabio
>
> And then just loops further. In case of 10 ENOMEM in a row,. passed
> pdata won't be initialized at all and driver doesn't do anything about
> it. I believe, it's not good approach to play with random values. We
> should somehow handle transfer errors all across the driver.
>
> If I am missing something, please, let me know :)
>
>
>
> With regards,
> Pavel Skripkin
On Sunday, August 22, 2021 12:59:13 PM CEST Fabio M. De Francesco wrote:
> It's up to the callers of _rtw_usb*() to check return values and then act
> accordingly.
Typo.
Replace "_rtw_usb*()" with "_rtw_read*()".
My fault. Sorry :(
Fabio
On 8/22/21 1:59 PM, Fabio M. De Francesco wrote:
> On Sunday, August 22, 2021 12:09:29 PM CEST Pavel Skripkin wrote:
>> On 8/22/21 12:53 PM, Fabio M. De Francesco wrote:
>> > On Friday, August 20, 2021 7:07:28 PM CEST Pavel Skripkin wrote:
>> >> Hi, Greg, Larry and Phillip!
>> >>
>> >> I noticed, that new staging driver was added like 3 weeks ago and I
> decided
>> >> to look at the code, because drivers in staging directory are always
> buggy.
>> >>
>> >> The first thing I noticed is *no one* was checking read operations
> result,
>> >
>> > but
>> >
>> >> it can fail and driver may start writing random stack values into
> registers.
>> >
>> > It
>> >
>> >> can cause driver misbehavior or device misbehavior.
>> >
>> > After the messages I wrote yesterday, I had some minutes to look deeper at
> the
>> > code that would be changed by these patches.
>> >
>> > I think that it does not look like that the driver could return "random
> stack
>> > values into registers" and I think this entire series in unnecessary.
>> >
>> > As far as I understand this driver (though I must admit that I really
> don't
>> > know how to write drivers, and I'm not interested in understanding - at
> the
>> > moment, at least), all the usb_read*() call usbctrl_vendorreq() and the
> latter
>> > *does* proper error checking before returning to the callers the read
> data.
>> >
>> > Please, look at the code copied from usbctrl_vendorreq() and pasted here
> (some
>> > comments are mine):
>> >
>> > /* start of code */
>> > static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u16 value, void
>> > *pdata, u16 len, u8 requesttype)
>> > {
>> >
>> > /* test if everything is OK for transfers and setup the necessary
> variables */
>> > [...]
>> >
>> > status = usb_control_msg(udev, pipe, REALTEK_USB_VENQT_CMD_REQ,
>> >
>> > reqtype, value,
>> >
>> > REALTEK_USB_VENQT_CMD_IDX,
>> >
>> > pIo_buf, len,
>> >
>> > RTW_USB_CONTROL_MSG_TIMEOUT);
>> >
>> > if (status == len) { /* Success this control transfer.
> */
>> >
>> > rtw_reset_continual_urb_error(dvobjpriv);
>> > if (requesttype == 0x01)
>> >
>> > memcpy(pdata, pIo_buf, len); /* pdata
>> >
>> > receives the read data */
>> >
>> > } else { /* error cases */
>> >
>> > [...]
>> >
>> > }
>> > /* end of code */
>> >
>> > So, *I cannot ack this RFC*, unless maintainers say I'm missing something.
>> >
>> > Larry, Philip, since you have much more knowledge than me about r8188eu
> (and,
>> > more in general, on device drivers) may you please say what you think
> about my
>> > arguments against this series?
>>
>> Hi, Fabio!
>>
>> Thank you for looking into this, but I still can see the case when pdata
>> won't be initialized:
>>
>>
>> pdata is initialized only in case of successful transfer, i.e len > 0.
>> It means some data was received (maybe not full length, but anyway). In
>> case of usb_control_msg() error (for example -ENOMEM) code only does
>> this code block:
>>
>> if (status < 0) {
>> if (status == (-ESHUTDOWN) || status == -ENODEV) {
>> adapt->bSurpriseRemoved = true;
>> } else {
>> struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
>> haldata->srestpriv.Wifi_Error_Status =
> USB_VEN_REQ_CMD_FAIL;
>> }
>> }
>
> It's up to the callers of _rtw_usb*() to check return values and then act
> accordingly.
>
> It doesn't matter whether or not *pdata is initialized because usb_read*()
> returns data = 0 if usb_control_msg() has not initialized/changed its third
> parameter. Then _rtw_read*() receive 0 or initialized data depending on errors
> or no errors. Finally _rtw_read*() returns that same value to the callers (via
> r_val).
>
> So, it's up to the callers to test if (!_rtw_read*()) and then act
> accordingly. If they get 0 they should know how to handle the errors.
>
Yes, but _rtw_read*() == 0 indicates 2 states:
1. Error on transfer side
2. Actual register value is 0
> Furthermore, we have already either adapt->bSurpriseRemoved = true or haldata-
>>srestpriv.Wifi_Error_Status = USB_VEN_REQ_CMD_FAIL. Depending on contexts
> where _rtw_read*() are called, perhaps they could also check the two variables
> above.
Yes, Wifi_Error_Status can be used, but it's set every time an error
occurred. For example if 8th usb_control_msg() was successful
Wifi_Error_Status will be set to error anyway. It's can be easily fixed,
of course.
IMO, we should switch to standard way of handling these type of errors
to move the driver out of staging someday
BTW: syzbot already found uninit value bug in r817xu driver:
https://syzkaller.appspot.com/bug?id=3cd92b1d85428b128503bfa7a250294c9ae00bd8
The usb related code in these drivers is the same, so bugs I am talking
about are real.
>
> In summation. if anything should be changed, it is the code of the callers of
> _rtw_read*() if you find out they they don't properly handle the returning
> values of this function. You should find every place where _rtw_read*() are
> called and figure out if the returns are properly checked and handled; if not,
> make some change only there.
>
> Larry, Philip, where are you? Am I missing something?
>
I am waiting for their replies too :) I have almost ready v2, so...
With regards,
Pavel Skripkin
On Sun, Aug 22, 2021 at 03:10:56PM +0300, Pavel Skripkin wrote:
> On 8/22/21 1:59 PM, Fabio M. De Francesco wrote:
> > On Sunday, August 22, 2021 12:09:29 PM CEST Pavel Skripkin wrote:
> > > On 8/22/21 12:53 PM, Fabio M. De Francesco wrote:
> > > > On Friday, August 20, 2021 7:07:28 PM CEST Pavel Skripkin wrote:
> > > >> Hi, Greg, Larry and Phillip!
> > > >> >> I noticed, that new staging driver was added like 3 weeks ago
> > > and I
> > decided
> > > >> to look at the code, because drivers in staging directory are
> > > always
> > buggy.
> > > >> >> The first thing I noticed is *no one* was checking read
> > > operations
> > result,
> > > > > but
> > > > >> it can fail and driver may start writing random stack values
> > > into
> > registers.
> > > > > It
> > > > >> can cause driver misbehavior or device misbehavior.
> > > > > After the messages I wrote yesterday, I had some minutes to look
> > > deeper at
> > the
> > > > code that would be changed by these patches.
> > > > > I think that it does not look like that the driver could return
> > > "random
> > stack
> > > > values into registers" and I think this entire series in unnecessary.
> > > > > As far as I understand this driver (though I must admit that I
> > > really
> > don't
> > > > know how to write drivers, and I'm not interested in understanding
> > > - at
> > the
> > > > moment, at least), all the usb_read*() call usbctrl_vendorreq()
> > > and the
> > latter
> > > > *does* proper error checking before returning to the callers the
> > > read
> > data.
> > > > > Please, look at the code copied from usbctrl_vendorreq() and
> > > pasted here
> > (some
> > > > comments are mine):
> > > > > /* start of code */
> > > > static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u16 value, void
> > > > *pdata, u16 len, u8 requesttype)
> > > > {
> > > > > /* test if everything is OK for transfers and setup the
> > > necessary
> > variables */
> > > > [...]
> > > > > status = usb_control_msg(udev, pipe, REALTEK_USB_VENQT_CMD_REQ,
> > > > > reqtype, value,
> > > > > REALTEK_USB_VENQT_CMD_IDX,
> > > > > pIo_buf, len,
> > > > > RTW_USB_CONTROL_MSG_TIMEOUT);
> > > > > if (status == len) { /* Success this control
> > > transfer.
> > */
> > > > >
> > > rtw_reset_continual_urb_error(dvobjpriv);
> > > > if (requesttype == 0x01)
> > > > >
> > > memcpy(pdata, pIo_buf, len); /* pdata
> > > > > receives the read data */
> > > > > } else { /* error cases */
> > > > > [...]
> > > > > }
> > > > /* end of code */
> > > > > So, *I cannot ack this RFC*, unless maintainers say I'm missing
> > > something.
> > > > > Larry, Philip, since you have much more knowledge than me about
> > > r8188eu
> > (and,
> > > > more in general, on device drivers) may you please say what you
> > > think
> > about my
> > > > arguments against this series?
> > >
> > > Hi, Fabio!
> > >
> > > Thank you for looking into this, but I still can see the case when pdata
> > > won't be initialized:
> > >
> > >
> > > pdata is initialized only in case of successful transfer, i.e len > 0.
> > > It means some data was received (maybe not full length, but anyway). In
> > > case of usb_control_msg() error (for example -ENOMEM) code only does
> > > this code block:
> > >
> > > if (status < 0) {
> > > if (status == (-ESHUTDOWN) || status == -ENODEV) {
> > > adapt->bSurpriseRemoved = true;
> > > } else {
> > > struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
> > > haldata->srestpriv.Wifi_Error_Status =
> > USB_VEN_REQ_CMD_FAIL;
> > > }
> > > }
> >
> > It's up to the callers of _rtw_usb*() to check return values and then act
> > accordingly.
> >
> > It doesn't matter whether or not *pdata is initialized because usb_read*()
> > returns data = 0 if usb_control_msg() has not initialized/changed its third
> > parameter. Then _rtw_read*() receive 0 or initialized data depending on errors
> > or no errors. Finally _rtw_read*() returns that same value to the callers (via
> > r_val).
> >
> > So, it's up to the callers to test if (!_rtw_read*()) and then act
> > accordingly. If they get 0 they should know how to handle the errors.
> >
>
> Yes, but _rtw_read*() == 0 indicates 2 states:
>
> 1. Error on transfer side
> 2. Actual register value is 0
That's not a good design, it should be fixed. Note there is the new
usb_control_msg_recv() function which should probably be used instead
here, to prevent this problem from happening.
> > In summation. if anything should be changed, it is the code of the callers of
> > _rtw_read*() if you find out they they don't properly handle the returning
> > values of this function. You should find every place where _rtw_read*() are
> > called and figure out if the returns are properly checked and handled; if not,
> > make some change only there.
> >
> > Larry, Philip, where are you? Am I missing something?
Relax, there is no need to get jumpy, people do not have to respond
instantly to emails here. Especially when it is not their job to do so.
greg k-h
On 8/22/21 3:39 PM, Greg KH wrote:
>>
>> Yes, but _rtw_read*() == 0 indicates 2 states:
>>
>> 1. Error on transfer side
>> 2. Actual register value is 0
>
> That's not a good design, it should be fixed. Note there is the new
> usb_control_msg_recv() function which should probably be used instead
> here, to prevent this problem from happening.
>
Thank you, Greg, for confirmation. That's was the point why I started to
write this series :)
I think, usb_control_msg_recv() won't help us with this problem, since
all rtw_read*() functions return an unsigned value now. In future, when
driver code will be fixed (ex: a lot of void function, which can fail
and leave passed pointer uninitialized) we can move to new usb API and
then move driver out of staging :)
With regards,
Pavel Skripkin
On Sun, Aug 22, 2021 at 03:50:35PM +0300, Pavel Skripkin wrote:
> On 8/22/21 3:39 PM, Greg KH wrote:
> > >
> > > Yes, but _rtw_read*() == 0 indicates 2 states:
> > >
> > > 1. Error on transfer side
> > > 2. Actual register value is 0
> >
> > That's not a good design, it should be fixed. Note there is the new
> > usb_control_msg_recv() function which should probably be used instead
> > here, to prevent this problem from happening.
> >
>
> Thank you, Greg, for confirmation. That's was the point why I started to
> write this series :)
>
> I think, usb_control_msg_recv() won't help us with this problem, since all
> rtw_read*() functions return an unsigned value now. In future, when driver
> code will be fixed (ex: a lot of void function, which can fail and leave
> passed pointer uninitialized) we can move to new usb API and then move
> driver out of staging :)
That function _should_ be used at the lower levels of this call chain.
If you want to go from the top -> down or bottom -> up of fixing this is
your choice, but as others have pointed out, this patch series as-is
still needs some work.
thanks,
greg k-h
On Sunday, August 22, 2021 2:39:34 PM CEST Greg KH wrote:
> On Sun, Aug 22, 2021 at 03:10:56PM +0300, Pavel Skripkin wrote:
> > On 8/22/21 1:59 PM, Fabio M. De Francesco wrote:
> > > On Sunday, August 22, 2021 12:09:29 PM CEST Pavel Skripkin wrote:
[...]
> > > So, it's up to the callers to test if (!_rtw_read*()) and then act
> > > accordingly. If they get 0 they should know how to handle the errors.
> >
> > Yes, but _rtw_read*() == 0 indicates 2 states:
> > 1. Error on transfer side
> > 2. Actual register value is 0
>
> That's not a good design, it should be fixed. Note there is the new
> usb_control_msg_recv() function which should probably be used instead
> here, to prevent this problem from happening.
I think that no functions should return 0 for signaling FAILURE. If I'm not
wrong, the kernel quite always prefers to return 0 on SUCCESS and <0 on
FAILURE. Why don't you just fix this?
> > > In summation. if anything should be changed, it is the code of the
callers of
> > > _rtw_read*() if you find out they they don't properly handle the
returning
> > > values of this function. You should find every place where _rtw_read*()
are
> > > called and figure out if the returns are properly checked and handled;
if not,
> > > make some change only there.
> > >
> > > Larry, Philip, where are you? Am I missing something?
>
> Relax, there is no need to get jumpy, people do not have to respond
> instantly to emails here. Especially when it is not their job to do so.
I should have placed a big smile at the end of the phrase. I was just kidding
while trying to get their attention. I know there is no hurry and that no one
has any obligation of this kind. Again, just kidding :)
Thanks,
Fabio
> greg k-h
On Sun, Aug 22, 2021 at 03:21:30PM +0200, Fabio M. De Francesco wrote:
> On Sunday, August 22, 2021 2:39:34 PM CEST Greg KH wrote:
> > On Sun, Aug 22, 2021 at 03:10:56PM +0300, Pavel Skripkin wrote:
> > > On 8/22/21 1:59 PM, Fabio M. De Francesco wrote:
> > > > On Sunday, August 22, 2021 12:09:29 PM CEST Pavel Skripkin wrote:
> [...]
> > > > So, it's up to the callers to test if (!_rtw_read*()) and then act
> > > > accordingly. If they get 0 they should know how to handle the errors.
> > >
> > > Yes, but _rtw_read*() == 0 indicates 2 states:
> > > 1. Error on transfer side
> > > 2. Actual register value is 0
> >
> > That's not a good design, it should be fixed. Note there is the new
> > usb_control_msg_recv() function which should probably be used instead
> > here, to prevent this problem from happening.
>
> I think that no functions should return 0 for signaling FAILURE. If I'm not
> wrong, the kernel quite always prefers to return 0 on SUCCESS and <0 on
> FAILURE. Why don't you just fix this?
Fix what specifically here? The usb_control_msg() call? If so, that is
why usb_control_msg_recv() was created, as sometimes you do want to do
what usb_control_msg() does today (see the users in the USB core today
for examples of why this is needed.)
In general, yes, 0 is success, negative is error, and positive is the
number of bytes read/written.
Anyway, let's see the second round of patches here before continuing
this thread...
thanks,
greg k-h
On 8/22/21 4:21 PM, Fabio M. De Francesco wrote:
> On Sunday, August 22, 2021 2:39:34 PM CEST Greg KH wrote:
>> On Sun, Aug 22, 2021 at 03:10:56PM +0300, Pavel Skripkin wrote:
>> > On 8/22/21 1:59 PM, Fabio M. De Francesco wrote:
>> > > On Sunday, August 22, 2021 12:09:29 PM CEST Pavel Skripkin wrote:
> [...]
>> > > So, it's up to the callers to test if (!_rtw_read*()) and then act
>> > > accordingly. If they get 0 they should know how to handle the errors.
>> >
>> > Yes, but _rtw_read*() == 0 indicates 2 states:
>> > 1. Error on transfer side
>> > 2. Actual register value is 0
>>
>> That's not a good design, it should be fixed. Note there is the new
>> usb_control_msg_recv() function which should probably be used instead
>> here, to prevent this problem from happening.
>
> I think that no functions should return 0 for signaling FAILURE. If I'm not
> wrong, the kernel quite always prefers to return 0 on SUCCESS and <0 on
> FAILURE. Why don't you just fix this?
>
That's what I've done in v2. All rtw_read* family will have following
prototype in v2:
int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data);
Was it your idea, or you were talking about different approach?
With regards,
Pavel Skripkin
Hi, Greg, Larry and Phillip!
I noticed, that new staging driver was added like 3 weeks ago and I decided
to look at the code, because drivers in staging directory are always buggy.
The first thing I noticed is *no one* was checking read operations result, but
it can fail and driver may start writing random stack values into registers. It
can cause driver misbehavior or device misbehavior.
To avoid this type of bugs, i've changed rtw_read* API. Now all rtw_read
funtions return an error, when something went wrong with usb transfer.
It helps callers to break/return earlier and don't write random values to
registers or to rely on random values.
Why is this pacth series RFC?
1. I don't have this device and I cannot test these changes.
2. I don't know how to handle errors in each particular case. For now, function
just returns or returns an error. That's all. I hope, driver maintainers will
help with these bits.
3. I guess, I handled not all uninit value bugs here. I hope, I fixed
at least half of them
v1 -> v2:
1. Make rtw_read*() return an error instead of initializing pointer to error
2. Split one huge patch to smaller ones for each rtw_read{8,16,32} function
changes
3. Add new macro for printing register values (It helps to not copy-paste error
handling)
4. Removed {read,write}_macreg (Suggested by Phillip)
5. Rebased on top of staging-next
6. Cleaned checkpatch errors and warnings
Only build-tested, since I don't have device with r8118eu chip
Pavel Skripkin (6):
staging: r8188eu: remove {read,write}_macreg
staging: r8188eu: add helper macro for printing registers
staging: r8188eu: add error handling of rtw_read8
staging: r8188eu: add error handling of rtw_read16
staging: r8188eu: add error handling of rtw_read32
staging: r8188eu: make ReadEFuse return an int
drivers/staging/r8188eu/core/rtw_debug.c | 79 +++-
drivers/staging/r8188eu/core/rtw_efuse.c | 125 +++--
drivers/staging/r8188eu/core/rtw_io.c | 27 +-
drivers/staging/r8188eu/core/rtw_mp.c | 70 ++-
drivers/staging/r8188eu/core/rtw_mp_ioctl.c | 13 +-
drivers/staging/r8188eu/core/rtw_pwrctrl.c | 5 +-
drivers/staging/r8188eu/core/rtw_sreset.c | 9 +-
.../r8188eu/hal/Hal8188ERateAdaptive.c | 8 +-
drivers/staging/r8188eu/hal/HalPhyRf_8188e.c | 21 +-
drivers/staging/r8188eu/hal/HalPwrSeqCmd.c | 9 +-
drivers/staging/r8188eu/hal/hal_com.c | 23 +-
drivers/staging/r8188eu/hal/hal_intf.c | 6 +-
drivers/staging/r8188eu/hal/odm_interface.c | 12 +-
drivers/staging/r8188eu/hal/rtl8188e_cmd.c | 33 +-
drivers/staging/r8188eu/hal/rtl8188e_dm.c | 6 +-
.../staging/r8188eu/hal/rtl8188e_hal_init.c | 285 +++++++++---
drivers/staging/r8188eu/hal/rtl8188e_phycfg.c | 27 +-
drivers/staging/r8188eu/hal/rtl8188e_sreset.c | 22 +-
drivers/staging/r8188eu/hal/rtl8188eu_led.c | 18 +-
drivers/staging/r8188eu/hal/usb_halinit.c | 439 +++++++++++++++---
drivers/staging/r8188eu/hal/usb_ops_linux.c | 57 ++-
drivers/staging/r8188eu/include/hal_intf.h | 6 +-
.../staging/r8188eu/include/odm_interface.h | 6 +-
.../staging/r8188eu/include/rtl8188e_hal.h | 2 +-
drivers/staging/r8188eu/include/rtw_debug.h | 13 +
drivers/staging/r8188eu/include/rtw_efuse.h | 4 +-
drivers/staging/r8188eu/include/rtw_io.h | 18 +-
drivers/staging/r8188eu/include/rtw_mp.h | 2 -
drivers/staging/r8188eu/os_dep/ioctl_linux.c | 179 +++++--
drivers/staging/r8188eu/os_dep/usb_intf.c | 3 +-
30 files changed, 1138 insertions(+), 389 deletions(-)
--
2.32.0
These 2 functions are unused, so they can be simply removed
Signed-off-by: Pavel Skripkin <[email protected]>
---
drivers/staging/r8188eu/core/rtw_mp.c | 39 ------------------------
drivers/staging/r8188eu/include/rtw_mp.h | 2 --
2 files changed, 41 deletions(-)
diff --git a/drivers/staging/r8188eu/core/rtw_mp.c b/drivers/staging/r8188eu/core/rtw_mp.c
index 93bb683b628f..0a0a24fd37b0 100644
--- a/drivers/staging/r8188eu/core/rtw_mp.c
+++ b/drivers/staging/r8188eu/core/rtw_mp.c
@@ -7,45 +7,6 @@
#include "../include/odm_precomp.h"
#include "../include/rtl8188e_hal.h"
-u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz)
-{
- u32 val = 0;
-
- switch (sz) {
- case 1:
- val = rtw_read8(padapter, addr);
- break;
- case 2:
- val = rtw_read16(padapter, addr);
- break;
- case 4:
- val = rtw_read32(padapter, addr);
- break;
- default:
- val = 0xffffffff;
- break;
- }
-
- return val;
-}
-
-void write_macreg(struct adapter *padapter, u32 addr, u32 val, u32 sz)
-{
- switch (sz) {
- case 1:
- rtw_write8(padapter, addr, (u8)val);
- break;
- case 2:
- rtw_write16(padapter, addr, (u16)val);
- break;
- case 4:
- rtw_write32(padapter, addr, val);
- break;
- default:
- break;
- }
-}
-
u32 read_bbreg(struct adapter *padapter, u32 addr, u32 bitmask)
{
return rtw_hal_read_bbreg(padapter, addr, bitmask);
diff --git a/drivers/staging/r8188eu/include/rtw_mp.h b/drivers/staging/r8188eu/include/rtw_mp.h
index b64b16554343..3a259d991348 100644
--- a/drivers/staging/r8188eu/include/rtw_mp.h
+++ b/drivers/staging/r8188eu/include/rtw_mp.h
@@ -410,8 +410,6 @@ void mp_stop_test(struct adapter *padapter);
u32 _read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask);
void _write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask, u32 val);
-u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz);
-void write_macreg(struct adapter *padapter, u32 addr, u32 val, u32 sz);
u32 read_bbreg(struct adapter *padapter, u32 addr, u32 bitmask);
void write_bbreg(struct adapter *padapter, u32 addr, u32 bitmask, u32 val);
u32 read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr);
--
2.32.0
There are a lof of places, where DBG_88E() is used to print register
value. Since following patches change _rtw_read*() family
prototypes, we can wrap printing registers into useful macro to avoid
open-coding error checking like this:
u32 tmp;
if (!rtw_read(&tmp))
DBG("reg = %d\n", tmp);
So, added DBG_88E_REG{8,16,32} macros for printing register values.
Signed-off-by: Pavel Skripkin <[email protected]>
---
drivers/staging/r8188eu/include/rtw_debug.h | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/staging/r8188eu/include/rtw_debug.h b/drivers/staging/r8188eu/include/rtw_debug.h
index 3c3bf2a4f30e..059647b9cd3a 100644
--- a/drivers/staging/r8188eu/include/rtw_debug.h
+++ b/drivers/staging/r8188eu/include/rtw_debug.h
@@ -72,6 +72,19 @@ extern u32 GlobalDebugLevel;
pr_info(DRIVER_PREFIX __VA_ARGS__); \
} while (0)
+#define __DBG_88E_REG(fmt, adap, reg, size) \
+ do { \
+ u##size __tmp__; \
+ if (rtw_read##size((adap), (reg), &__tmp__)) \
+ break; \
+ if (_drv_err_ <= GlobalDebugLevel) \
+ pr_info(DRIVER_PREFIX fmt, __tmp__); \
+ } while (0)
+
+#define DBG_88E_REG8(fmt, adap, reg) __DBG_88E_REG(fmt, adap, reg, 8)
+#define DBG_88E_REG16(fmt, adap, reg) __DBG_88E_REG(fmt, adap, reg, 16)
+#define DBG_88E_REG32(fmt, adap, reg) __DBG_88E_REG(fmt, adap, reg, 32)
+
int proc_get_drv_version(char *page, char **start,
off_t offset, int count,
int *eof, void *data);
--
2.32.0
_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 <[email protected]>
---
drivers/staging/r8188eu/core/rtw_debug.c | 11 +-
drivers/staging/r8188eu/core/rtw_efuse.c | 76 +++--
drivers/staging/r8188eu/core/rtw_io.c | 9 +-
drivers/staging/r8188eu/core/rtw_mp.c | 13 +-
drivers/staging/r8188eu/core/rtw_mp_ioctl.c | 5 +-
drivers/staging/r8188eu/hal/HalPhyRf_8188e.c | 19 +-
drivers/staging/r8188eu/hal/HalPwrSeqCmd.c | 9 +-
drivers/staging/r8188eu/hal/hal_com.c | 23 +-
drivers/staging/r8188eu/hal/odm_interface.c | 4 +-
drivers/staging/r8188eu/hal/rtl8188e_cmd.c | 33 ++-
drivers/staging/r8188eu/hal/rtl8188e_dm.c | 6 +-
.../staging/r8188eu/hal/rtl8188e_hal_init.c | 128 +++++++--
drivers/staging/r8188eu/hal/rtl8188e_phycfg.c | 10 +-
drivers/staging/r8188eu/hal/rtl8188e_sreset.c | 8 +-
drivers/staging/r8188eu/hal/rtl8188eu_led.c | 18 +-
drivers/staging/r8188eu/hal/usb_halinit.c | 267 +++++++++++++++---
drivers/staging/r8188eu/hal/usb_ops_linux.c | 19 +-
.../staging/r8188eu/include/odm_interface.h | 2 +-
drivers/staging/r8188eu/include/rtw_io.h | 6 +-
drivers/staging/r8188eu/os_dep/ioctl_linux.c | 61 +++-
20 files changed, 569 insertions(+), 158 deletions(-)
diff --git a/drivers/staging/r8188eu/core/rtw_debug.c b/drivers/staging/r8188eu/core/rtw_debug.c
index 2ee64cef73f7..8b7d3eb12bd0 100644
--- a/drivers/staging/r8188eu/core/rtw_debug.c
+++ b/drivers/staging/r8188eu/core/rtw_debug.c
@@ -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));
diff --git a/drivers/staging/r8188eu/core/rtw_efuse.c b/drivers/staging/r8188eu/core/rtw_efuse.c
index decccf7622f0..b471f6446f78 100644
--- a/drivers/staging/r8188eu/core/rtw_efuse.c
+++ b/drivers/staging/r8188eu/core/rtw_efuse.c
@@ -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,6 +251,7 @@ 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);
@@ -251,27 +259,42 @@ u8 EFUSE_Read1Byte(struct adapter *Adapter, u16 Address)
/* 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;
diff --git a/drivers/staging/r8188eu/core/rtw_io.c b/drivers/staging/r8188eu/core/rtw_io.c
index cde0205816b1..2714506c8ffb 100644
--- a/drivers/staging/r8188eu/core/rtw_io.c
+++ b/drivers/staging/r8188eu/core/rtw_io.c
@@ -34,18 +34,15 @@ [email protected]
#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)
diff --git a/drivers/staging/r8188eu/core/rtw_mp.c b/drivers/staging/r8188eu/core/rtw_mp.c
index 0a0a24fd37b0..76f0bc399819 100644
--- a/drivers/staging/r8188eu/core/rtw_mp.c
+++ b/drivers/staging/r8188eu/core/rtw_mp.c
@@ -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 */
}
diff --git a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
index c85f8e467337..894ab456f202 100644
--- a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
+++ b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
@@ -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);
diff --git a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
index 356885e27edd..3545ad60dc00 100644
--- a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
+++ b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
@@ -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);
}
diff --git a/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c b/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
index 0fd11aca7ac7..74e83381ef06 100644
--- a/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
+++ b/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
@@ -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)))
diff --git a/drivers/staging/r8188eu/hal/hal_com.c b/drivers/staging/r8188eu/hal/hal_com.c
index f09d4d49b159..833c88c85e3f 100644
--- a/drivers/staging/r8188eu/hal/hal_com.c
+++ b/drivers/staging/r8188eu/hal/hal_com.c
@@ -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;
diff --git a/drivers/staging/r8188eu/hal/odm_interface.c b/drivers/staging/r8188eu/hal/odm_interface.c
index 5a01495d74bc..9a9df98da727 100644
--- a/drivers/staging/r8188eu/hal/odm_interface.c
+++ b/drivers/staging/r8188eu/hal/odm_interface.c
@@ -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)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_cmd.c b/drivers/staging/r8188eu/hal/rtl8188e_cmd.c
index 3e1a45030bc8..53636c0e4786 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_cmd.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_cmd.c
@@ -21,12 +21,14 @@ static u8 _is_fw_read_cmd_down(struct adapter *adapt, u8 msgbox_num)
{
u8 read_down = false;
int retry_cnts = 100;
-
+ int error;
u8 valid;
do {
- valid = rtw_read8(adapt, REG_HMETFR) & BIT(msgbox_num);
- if (0 == valid)
+ error = rtw_read8(adapt, REG_HMETFR, &valid);
+ if (error)
+ return read_down;
+ else if (!(valid & BIT(msgbox_num)))
read_down = true;
} while ((!read_down) && (retry_cnts--));
@@ -578,8 +580,9 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
bool bSendBeacon = false;
bool bcn_valid = false;
- u8 DLBcnCount = 0;
+ u8 DLBcnCount = 0, val8;
u32 poll = 0;
+ int error;
DBG_88E("%s mstatus(%x)\n", __func__, mstatus);
@@ -596,8 +599,15 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
/* Disable Hw protection for a time which revserd for Hw sending beacon. */
/* Fix download reserved page packet fail that access collision with the protection time. */
/* 2010.05.11. Added by tynli. */
- rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) & (~BIT(3)));
- rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) | BIT(4));
+ error = rtw_read8(adapt, REG_BCN_CTRL, &val8);
+ if (error)
+ return;
+ rtw_write8(adapt, REG_BCN_CTRL, val8 & (~BIT(3)));
+
+ error = rtw_read8(adapt, REG_BCN_CTRL, &val8);
+ if (error)
+ return;
+ rtw_write8(adapt, REG_BCN_CTRL, val8 | BIT(4));
if (haldata->RegFwHwTxQCtrl & BIT(6)) {
DBG_88E("HalDownloadRSVDPage(): There is an Adapter is sending beacon.\n");
@@ -639,8 +649,15 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
/* */
/* Enable Bcn */
- rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) | BIT(3));
- rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) & (~BIT(4)));
+ error = rtw_read8(adapt, REG_BCN_CTRL, &val8);
+ if (error)
+ return;
+ rtw_write8(adapt, REG_BCN_CTRL, val8 | BIT(3));
+
+ error = rtw_read8(adapt, REG_BCN_CTRL, &val8);
+ if (error)
+ return;
+ rtw_write8(adapt, REG_BCN_CTRL, val8 & (~BIT(4)));
/* To make sure that if there exists an adapter which would like to send beacon. */
/* If exists, the origianl value of 0x422[6] will be 1, we should check this to */
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_dm.c b/drivers/staging/r8188eu/hal/rtl8188e_dm.c
index 78552303c990..5cb3d6369449 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_dm.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_dm.c
@@ -16,8 +16,12 @@ static void dm_CheckStatistics(struct adapter *Adapter)
static void dm_InitGPIOSetting(struct adapter *Adapter)
{
u8 tmp1byte;
+ int error;
+
+ error = rtw_read8(Adapter, REG_GPIO_MUXCFG, &tmp1byte);
+ if (error)
+ return;
- tmp1byte = rtw_read8(Adapter, REG_GPIO_MUXCFG);
tmp1byte &= (GPIOSEL_GPIO | ~GPIOSEL_ENBT);
rtw_write8(Adapter, REG_GPIO_MUXCFG, tmp1byte);
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
index 393969f51206..cfc429965b7d 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
@@ -13,10 +13,14 @@
static void iol_mode_enable(struct adapter *padapter, u8 enable)
{
u8 reg_0xf0 = 0;
+ int error;
if (enable) {
/* Enable initial offload */
- reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
+ error = rtw_read8(padapter, REG_SYS_CFG, ®_0xf0);
+ if (error)
+ return;
+
rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 | SW_OFFLOAD_EN);
if (!padapter->bFWReady) {
@@ -26,7 +30,10 @@ static void iol_mode_enable(struct adapter *padapter, u8 enable)
} else {
/* disable initial offload */
- reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
+ error = rtw_read8(padapter, REG_SYS_CFG, ®_0xf0);
+ if (error)
+ return;
+
rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 & ~SW_OFFLOAD_EN);
}
}
@@ -35,19 +42,28 @@ static s32 iol_execute(struct adapter *padapter, u8 control)
{
s32 status = _FAIL;
u8 reg_0x88 = 0;
- u32 start = 0, passing_time = 0;
+ u32 start = 0;
+ int error;
control = control & 0x0f;
- reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
+ error = rtw_read8(padapter, REG_HMEBOX_E0, ®_0x88);
+ if (error)
+ return status;
+
rtw_write8(padapter, REG_HMEBOX_E0, reg_0x88 | control);
start = jiffies;
- while ((reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0)) & control &&
- (passing_time = rtw_get_passing_time_ms(start)) < 1000) {
- ;
- }
- reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
+ do {
+ error = rtw_read8(padapter, REG_HMEBOX_E0, ®_0x88);
+ if (error)
+ return status;
+ } while (reg_0x88 & control && rtw_get_passing_time_ms(start) < 1000);
+
+ error = rtw_read8(padapter, REG_HMEBOX_E0, ®_0x88);
+ if (error)
+ return status;
+
status = (reg_0x88 & control) ? _FAIL : _SUCCESS;
if (reg_0x88 & control << 4)
status = _FAIL;
@@ -195,17 +211,20 @@ static void efuse_read_phymap_from_txpktbuf(
)
{
u16 dbg_addr = 0;
- u32 start = 0, passing_time = 0;
+ u32 start = 0;
u8 reg_0x143 = 0;
__le32 lo32 = 0, hi32 = 0;
u16 len = 0, count = 0;
int i = 0;
u16 limit = *size;
-
+ int error;
u8 *pos = content;
- if (bcnhead < 0) /* if not valid */
- bcnhead = rtw_read8(adapter, REG_TDECTRL + 1);
+ if (bcnhead < 0) { /* if not valid */
+ error = rtw_read8(adapter, REG_TDECTRL + 1, (u8 *) &bcnhead);
+ if (error)
+ return;
+ }
DBG_88E("%s bcnhead:%d\n", __func__, bcnhead);
@@ -218,11 +237,21 @@ static void efuse_read_phymap_from_txpktbuf(
rtw_write8(adapter, REG_TXPKTBUF_DBG, 0);
start = jiffies;
- while (!(reg_0x143 = rtw_read8(adapter, REG_TXPKTBUF_DBG)) &&
- (passing_time = rtw_get_passing_time_ms(start)) < 1000) {
- DBG_88E("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n", __func__, reg_0x143, rtw_read8(adapter, 0x106));
+
+ do {
+ u8 tmp;
+
+ error = rtw_read8(adapter, REG_TXPKTBUF_DBG, ®_0x143);
+ if (error)
+ return;
+
+ if (!rtw_read8(adapter, 0x106, &tmp))
+ DBG_88E("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n",
+ __func__, reg_0x143, tmp);
+
rtw_usleep_os(100);
- }
+ } while (!reg_0x143 && rtw_get_passing_time_ms(start) < 1000);
+
/* data from EEPROM needs to be in LE */
lo32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L));
@@ -371,18 +400,28 @@ void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len)
static void _FWDownloadEnable(struct adapter *padapter, bool enable)
{
u8 tmp;
+ int error;
if (enable) {
/* MCU firmware download enable. */
- tmp = rtw_read8(padapter, REG_MCUFWDL);
+ error = rtw_read8(padapter, REG_MCUFWDL, &tmp);
+ if (error)
+ return;
+
rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01);
/* 8051 reset */
- tmp = rtw_read8(padapter, REG_MCUFWDL + 2);
+ error = rtw_read8(padapter, REG_MCUFWDL + 2, &tmp);
+ if (error)
+ return;
+
rtw_write8(padapter, REG_MCUFWDL + 2, tmp & 0xf7);
} else {
/* MCU firmware download disable. */
- tmp = rtw_read8(padapter, REG_MCUFWDL);
+ error = rtw_read8(padapter, REG_MCUFWDL, &tmp);
+ if (error)
+ return;
+
rtw_write8(padapter, REG_MCUFWDL, tmp & 0xfe);
/* Reserved for fw extension. */
@@ -452,8 +491,14 @@ static int _PageWrite(struct adapter *padapter, u32 page, void *buffer, u32 size
{
u8 value8;
u8 u8Page = (u8)(page & 0x07);
+ int error;
- value8 = (rtw_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | u8Page;
+ error = rtw_read8(padapter, REG_MCUFWDL + 2, &value8);
+ if (error)
+ return error;
+
+ value8 &= 0xF8;
+ value8 |= u8Page;
rtw_write8(padapter, REG_MCUFWDL + 2, value8);
return _BlockWrite(padapter, buffer, size);
@@ -493,8 +538,12 @@ static int _WriteFW(struct adapter *padapter, void *buffer, u32 size)
void _8051Reset88E(struct adapter *padapter)
{
u8 u1bTmp;
+ int error;
+
+ error = rtw_read8(padapter, REG_SYS_FUNC_EN + 1, &u1bTmp);
+ if (error)
+ return;
- u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp & (~BIT(2)));
rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp | (BIT(2)));
DBG_88E("=====> _8051Reset88E(): 8051 reset success .\n");
@@ -582,7 +631,7 @@ static int load_firmware(struct rt_firmware *pFirmware, struct device *device)
s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
{
s32 rtStatus = _SUCCESS;
- u8 writeFW_retry = 0;
+ u8 writeFW_retry = 0, tmp;
u32 fwdl_start_time;
struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
@@ -591,6 +640,7 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
u8 *pFirmwareBuf;
u32 FirmwareLen;
static int log_version;
+ int error;
if (!dvobj->firmware.szFwBuffer)
rtStatus = load_firmware(&dvobj->firmware, device);
@@ -621,7 +671,10 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
/* Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself, */
/* or it will cause download Fw fail. 2010.02.01. by tynli. */
- if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) { /* 8051 RAM code */
+ error = rtw_read8(padapter, REG_MCUFWDL, &tmp);
+ if (error) {
+ return _FAIL;
+ } else if (tmp & RAM_DL_SEL) { /* 8051 RAM code */
rtw_write8(padapter, REG_MCUFWDL, 0x00);
_8051Reset88E(padapter);
}
@@ -630,7 +683,11 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
fwdl_start_time = jiffies;
while (1) {
/* reset the FWDL chksum */
- rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL) | FWDL_ChkSum_rpt);
+ error = rtw_read8(padapter, REG_MCUFWDL, &tmp);
+ if (error)
+ return _FAIL;
+
+ rtw_write8(padapter, REG_MCUFWDL, tmp | FWDL_ChkSum_rpt);
rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen);
@@ -715,6 +772,7 @@ hal_EfusePowerSwitch_RTL8188E(
{
u8 tempval;
u16 tmpV16;
+ int error;
if (PwrState) {
rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
@@ -741,7 +799,10 @@ hal_EfusePowerSwitch_RTL8188E(
if (bWrite) {
/* Enable LDO 2.5V before read/write action */
- tempval = rtw_read8(pAdapter, EFUSE_TEST + 3);
+ error = rtw_read8(pAdapter, EFUSE_TEST + 3, &tempval);
+ if (error)
+ return;
+
tempval &= 0x0F;
tempval |= (VOLTAGE_V25 << 4);
rtw_write8(pAdapter, EFUSE_TEST + 3, (tempval | 0x80));
@@ -751,7 +812,9 @@ hal_EfusePowerSwitch_RTL8188E(
if (bWrite) {
/* Disable LDO 2.5V after read/write action */
- tempval = rtw_read8(pAdapter, EFUSE_TEST + 3);
+ error = rtw_read8(pAdapter, EFUSE_TEST + 3, &tempval);
+ if (error)
+ return;
rtw_write8(pAdapter, EFUSE_TEST + 3, (tempval & 0x7F));
}
}
@@ -1784,12 +1847,19 @@ void rtl8188e_stop_thread(struct adapter *padapter)
static void hal_notch_filter_8188e(struct adapter *adapter, bool enable)
{
+ int error;
+ u8 tmp;
+
+ error = rtw_read8(adapter, rOFDM0_RxDSP + 1, &tmp);
+ if (error)
+ return;
+
if (enable) {
DBG_88E("Enable notch filter\n");
- rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) | BIT(1));
+ rtw_write8(adapter, rOFDM0_RxDSP + 1, tmp | BIT(1));
} else {
DBG_88E("Disable notch filter\n");
- rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) & ~BIT(1));
+ rtw_write8(adapter, rOFDM0_RxDSP + 1, tmp & ~BIT(1));
}
}
void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
index 30a9dca8f453..f6d4c91a97a2 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
@@ -960,6 +960,7 @@ _PHY_SetBWMode92C(
struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter);
u8 regBwOpMode;
u8 regRRSR_RSC;
+ int error;
if (pHalData->rf_chip == RF_PSEUDO_11N)
return;
@@ -975,8 +976,13 @@ _PHY_SetBWMode92C(
/* 3<1>Set MAC register */
/* 3 */
- regBwOpMode = rtw_read8(Adapter, REG_BWOPMODE);
- regRRSR_RSC = rtw_read8(Adapter, REG_RRSR + 2);
+ error = rtw_read8(Adapter, REG_BWOPMODE, ®BwOpMode);
+ if (error)
+ return;
+
+ error = rtw_read8(Adapter, REG_RRSR + 2, ®RRSR_RSC);
+ if (error)
+ return;
switch (pHalData->CurrentChannelBW) {
case HT_CHANNEL_WIDTH_20:
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_sreset.c b/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
index 16fa249e35d3..39dacfb23570 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
@@ -49,13 +49,17 @@ void rtl8188e_sreset_linked_status_check(struct adapter *padapter)
{
u32 rx_dma_status = 0;
u8 fw_status = 0;
+ int error;
+
rx_dma_status = rtw_read32(padapter, REG_RXDMA_STATUS);
if (rx_dma_status != 0x00) {
DBG_88E("%s REG_RXDMA_STATUS:0x%08x\n", __func__, rx_dma_status);
rtw_write32(padapter, REG_RXDMA_STATUS, rx_dma_status);
}
- fw_status = rtw_read8(padapter, REG_FMETHR);
- if (fw_status != 0x00) {
+ error = rtw_read8(padapter, REG_FMETHR, &fw_status);
+ if (error) {
+ return;
+ } else if (fw_status != 0x00) {
if (fw_status == 1)
DBG_88E("%s REG_FW_STATUS (0x%02x), Read_Efuse_Fail !!\n", __func__, fw_status);
else if (fw_status == 2)
diff --git a/drivers/staging/r8188eu/hal/rtl8188eu_led.c b/drivers/staging/r8188eu/hal/rtl8188eu_led.c
index 452d4bb87aba..7f793b7ce609 100644
--- a/drivers/staging/r8188eu/hal/rtl8188eu_led.c
+++ b/drivers/staging/r8188eu/hal/rtl8188eu_led.c
@@ -14,10 +14,15 @@
void SwLedOn(struct adapter *padapter, struct LED_871x *pLed)
{
u8 LedCfg;
+ int error;
if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
return;
- LedCfg = rtw_read8(padapter, REG_LEDCFG2);
+
+ error = rtw_read8(padapter, REG_LEDCFG2, &LedCfg);
+ if (error)
+ return;
+
switch (pLed->LedPin) {
case LED_PIN_LED0:
rtw_write8(padapter, REG_LEDCFG2, (LedCfg & 0xf0) | BIT(5) | BIT(6)); /* SW control led0 on. */
@@ -37,11 +42,14 @@ void SwLedOff(struct adapter *padapter, struct LED_871x *pLed)
{
u8 LedCfg;
struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
+ int error;
if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
goto exit;
- LedCfg = rtw_read8(padapter, REG_LEDCFG2);/* 0x4E */
+ error = rtw_read8(padapter, REG_LEDCFG2, &LedCfg);/* 0x4E */
+ if (error)
+ return;
switch (pLed->LedPin) {
case LED_PIN_LED0:
@@ -49,7 +57,11 @@ void SwLedOff(struct adapter *padapter, struct LED_871x *pLed)
/* Open-drain arrangement for controlling the LED) */
LedCfg &= 0x90; /* Set to software control. */
rtw_write8(padapter, REG_LEDCFG2, (LedCfg | BIT(3)));
- LedCfg = rtw_read8(padapter, REG_MAC_PINMUX_CFG);
+
+ error = rtw_read8(padapter, REG_MAC_PINMUX_CFG, &LedCfg);
+ if (error)
+ return;
+
LedCfg &= 0xFE;
rtw_write8(padapter, REG_MAC_PINMUX_CFG, LedCfg);
} else {
diff --git a/drivers/staging/r8188eu/hal/usb_halinit.c b/drivers/staging/r8188eu/hal/usb_halinit.c
index 5cdabf43d4fd..4f1d7f9b43c3 100644
--- a/drivers/staging/r8188eu/hal/usb_halinit.c
+++ b/drivers/staging/r8188eu/hal/usb_halinit.c
@@ -120,6 +120,7 @@ static void _InitInterrupt(struct adapter *Adapter)
u32 imr, imr_ex;
u8 usb_opt;
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
+ int error;
/* HISR write one to clear */
rtw_write32(Adapter, REG_HISR_88E, 0xFFFFFFFF);
@@ -135,7 +136,9 @@ static void _InitInterrupt(struct adapter *Adapter)
/* REG_USB_SPECIAL_OPTION - BIT(4) */
/* 0; Use interrupt endpoint to upload interrupt pkt */
/* 1; Use bulk endpoint to upload interrupt pkt, */
- usb_opt = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION);
+ error = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION, &usb_opt);
+ if (error)
+ return;
if (!adapter_to_dvobj(Adapter)->ishighspeed)
usb_opt = usb_opt & (~INT_BULK_SEL);
@@ -435,8 +438,12 @@ static void _InitRxSetting(struct adapter *Adapter)
static void _InitRetryFunction(struct adapter *Adapter)
{
u8 value8;
+ int error;
+
+ error = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL, &value8);
+ if (error)
+ return;
- value8 = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL);
value8 |= EN_AMPDU_RTY_NEW;
rtw_write8(Adapter, REG_FWHW_TXQ_CTRL, value8);
@@ -499,9 +506,15 @@ usb_AggSettingRxUpdate(
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
u8 valueDMA;
u8 valueUSB;
+ int error;
- valueDMA = rtw_read8(Adapter, REG_TRXDMA_CTRL);
- valueUSB = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION);
+ error = rtw_read8(Adapter, REG_TRXDMA_CTRL, &valueDMA);
+ if (error)
+ return;
+
+ error = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION, &valueUSB);
+ if (error)
+ return;
switch (haldata->UsbRxAggMode) {
case USB_RX_AGG_DMA:
@@ -589,6 +602,7 @@ static void _InitOperationMode(struct adapter *Adapter)
static void _InitBeaconParameters(struct adapter *Adapter)
{
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
+ int error;
rtw_write16(Adapter, REG_BCN_CTRL, 0x1010);
@@ -601,11 +615,25 @@ static void _InitBeaconParameters(struct adapter *Adapter)
/* beacause test chip does not contension before sending beacon. by tynli. 2009.11.03 */
rtw_write16(Adapter, REG_BCNTCFG, 0x660F);
- haldata->RegBcnCtrlVal = rtw_read8(Adapter, REG_BCN_CTRL);
- haldata->RegTxPause = rtw_read8(Adapter, REG_TXPAUSE);
- haldata->RegFwHwTxQCtrl = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL + 2);
- haldata->RegReg542 = rtw_read8(Adapter, REG_TBTT_PROHIBIT + 2);
- haldata->RegCR_1 = rtw_read8(Adapter, REG_CR + 1);
+ error = rtw_read8(Adapter, REG_BCN_CTRL, (u8 *) &haldata->RegBcnCtrlVal);
+ if (error)
+ return;
+
+ error = rtw_read8(Adapter, REG_TXPAUSE, &haldata->RegTxPause);
+ if (error)
+ return;
+
+ error = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL + 2, &haldata->RegFwHwTxQCtrl);
+ if (error)
+ return;
+
+ error = rtw_read8(Adapter, REG_TBTT_PROHIBIT + 2, &haldata->RegReg542);
+ if (error)
+ return;
+
+ error = rtw_read8(Adapter, REG_CR + 1, &haldata->RegCR_1);
+ if (error)
+ return;
}
static void _BeaconFunctionEnable(struct adapter *Adapter,
@@ -665,14 +693,27 @@ enum rt_rf_power_state RfOnOffDetect(struct adapter *adapt)
{
u8 val8;
enum rt_rf_power_state rfpowerstate = rf_off;
+ int error;
if (adapt->pwrctrlpriv.bHWPowerdown) {
- val8 = rtw_read8(adapt, REG_HSISR);
+ error = rtw_read8(adapt, REG_HSISR, &val8);
+ if (error)
+ return rfpowerstate;
+
DBG_88E("pwrdown, 0x5c(BIT(7))=%02x\n", val8);
rfpowerstate = (val8 & BIT(7)) ? rf_off : rf_on;
} else { /* rf on/off */
- rtw_write8(adapt, REG_MAC_PINMUX_CFG, rtw_read8(adapt, REG_MAC_PINMUX_CFG) & ~(BIT(3)));
- val8 = rtw_read8(adapt, REG_GPIO_IO_SEL);
+
+ error = rtw_read8(adapt, REG_MAC_PINMUX_CFG, &val8);
+ if (error)
+ return rfpowerstate;
+
+ rtw_write8(adapt, REG_MAC_PINMUX_CFG, val8 & ~(BIT(3)));
+
+ error = rtw_read8(adapt, REG_GPIO_IO_SEL, &val8);
+ if (error)
+ return rfpowerstate;
+
DBG_88E("GPIO_IN=%02x\n", val8);
rfpowerstate = (val8 & BIT(3)) ? rf_on : rf_off;
}
@@ -689,6 +730,7 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv;
struct registry_priv *pregistrypriv = &Adapter->registrypriv;
u32 init_start_time = jiffies;
+ int error;
#define HAL_INIT_PROFILE_TAG(stage) do {} while (0)
@@ -835,7 +877,11 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
/* Enable TX Report */
/* Enable Tx Report Timer */
- value8 = rtw_read8(Adapter, REG_TX_RPT_CTRL);
+ error = rtw_read8(Adapter, REG_TX_RPT_CTRL, &value8);
+ if (error) {
+ status = _FAIL;
+ goto exit;
+ }
rtw_write8(Adapter, REG_TX_RPT_CTRL, (value8 | BIT(1) | BIT(0)));
/* Set MAX RPT MACID */
rtw_write8(Adapter, REG_TX_RPT_CTRL + 1, 2);/* FOR sta mode ,0: bc/mc ,1:AP */
@@ -962,9 +1008,13 @@ static void CardDisableRTL8188EU(struct adapter *Adapter)
{
u8 val8;
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
+ int error;
/* Stop Tx Report Timer. 0x4EC[Bit1]=b'0 */
- val8 = rtw_read8(Adapter, REG_TX_RPT_CTRL);
+ error = rtw_read8(Adapter, REG_TX_RPT_CTRL, &val8);
+ if (error)
+ return;
+
rtw_write8(Adapter, REG_TX_RPT_CTRL, val8 & (~BIT(1)));
/* stop rx */
@@ -975,10 +1025,15 @@ static void CardDisableRTL8188EU(struct adapter *Adapter)
/* 2. 0x1F[7:0] = 0 turn off RF */
- val8 = rtw_read8(Adapter, REG_MCUFWDL);
- if ((val8 & RAM_DL_SEL) && Adapter->bFWReady) { /* 8051 RAM code */
+ error = rtw_read8(Adapter, REG_MCUFWDL, &val8);
+ if (error) {
+ return;
+ } else if ((val8 & RAM_DL_SEL) && Adapter->bFWReady) { /* 8051 RAM code */
/* Reset MCU 0x2[10]=0. */
- val8 = rtw_read8(Adapter, REG_SYS_FUNC_EN + 1);
+ error = rtw_read8(Adapter, REG_SYS_FUNC_EN + 1, &val8);
+ if (error)
+ return;
+
val8 &= ~BIT(2); /* 0x2[10], FEN_CPUEN */
rtw_write8(Adapter, REG_SYS_FUNC_EN + 1, val8);
}
@@ -988,26 +1043,43 @@ static void CardDisableRTL8188EU(struct adapter *Adapter)
/* YJ,add,111212 */
/* Disable 32k */
- val8 = rtw_read8(Adapter, REG_32K_CTRL);
+ error = rtw_read8(Adapter, REG_32K_CTRL, &val8);
+ if (error)
+ return;
rtw_write8(Adapter, REG_32K_CTRL, val8 & (~BIT(0)));
/* Card disable power action flow */
HalPwrSeqCmdParsing(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, Rtl8188E_NIC_DISABLE_FLOW);
/* Reset MCU IO Wrapper */
- val8 = rtw_read8(Adapter, REG_RSV_CTRL + 1);
+ error = rtw_read8(Adapter, REG_RSV_CTRL + 1, &val8);
+ if (error)
+ return;
+
rtw_write8(Adapter, REG_RSV_CTRL + 1, (val8 & (~BIT(3))));
- val8 = rtw_read8(Adapter, REG_RSV_CTRL + 1);
+ error = rtw_read8(Adapter, REG_RSV_CTRL + 1, &val8);
+ if (error)
+ return;
rtw_write8(Adapter, REG_RSV_CTRL + 1, val8 | BIT(3));
/* YJ,test add, 111207. For Power Consumption. */
- val8 = rtw_read8(Adapter, GPIO_IN);
+ error = rtw_read8(Adapter, GPIO_IN, &val8);
+ if (error)
+ return;
+
rtw_write8(Adapter, GPIO_OUT, val8);
rtw_write8(Adapter, GPIO_IO_SEL, 0xFF);/* Reg0x46 */
- val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL);
+ error = rtw_read8(Adapter, REG_GPIO_IO_SEL, &val8);
+ if (error)
+ return;
+
rtw_write8(Adapter, REG_GPIO_IO_SEL, (val8 << 4));
- val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL + 1);
+
+ error = rtw_read8(Adapter, REG_GPIO_IO_SEL + 1, &val8);
+ if (error)
+ return;
+
rtw_write8(Adapter, REG_GPIO_IO_SEL + 1, val8 | 0x0F);/* Reg0x43 */
rtw_write32(Adapter, REG_BB_PAD_CTRL, 0x00080808);/* set LNA ,TRSW,EX_PA Pin to output mode */
haldata->bMacPwrCtrlOn = false;
@@ -1181,9 +1253,13 @@ static void _ReadPROMContent(
{
struct eeprom_priv *eeprom = GET_EEPROM_EFUSE_PRIV(Adapter);
u8 eeValue;
+ int error;
/* check system boot selection */
- eeValue = rtw_read8(Adapter, REG_9346CR);
+ error = rtw_read8(Adapter, REG_9346CR, &eeValue);
+ if (error)
+ return;
+
eeprom->EepromOrEfuse = (eeValue & BOOT_FROM_EEPROM) ? true : false;
eeprom->bautoload_fail_flag = (eeValue & EEPROM_EN) ? false : true;
@@ -1262,12 +1338,21 @@ static void hw_var_set_opmode(struct adapter *Adapter, u8 variable, u8 *val)
{
u8 val8;
u8 mode = *((u8 *)val);
+ int error;
+
+ error = rtw_read8(Adapter, REG_BCN_CTRL, &val8);
+ if (error)
+ return;
/* disable Port0 TSF update */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4));
+ rtw_write8(Adapter, REG_BCN_CTRL, val8 | BIT(4));
/* set net_type */
- val8 = rtw_read8(Adapter, MSR) & 0x0c;
+ error = rtw_read8(Adapter, MSR, &val8);
+ if (error)
+ return;
+
+ val8 &= 0x0c;
val8 |= mode;
rtw_write8(Adapter, MSR, val8);
@@ -1304,14 +1389,20 @@ static void hw_var_set_opmode(struct adapter *Adapter, u8 variable, u8 *val)
rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0));
/* BIT(3) - If set 0, hw will clr bcnq when tx becon ok/fail or port 0 */
- rtw_write8(Adapter, REG_MBID_NUM, rtw_read8(Adapter, REG_MBID_NUM) | BIT(3) | BIT(4));
+ error = rtw_read8(Adapter, REG_MBID_NUM, &val8);
+ if (error)
+ return;
+ rtw_write8(Adapter, REG_MBID_NUM, val8 | BIT(3) | BIT(4));
/* enable BCN0 Function for if1 */
/* don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received) */
rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT0_NORMAL_CHIP | EN_BCN_FUNCTION | BIT(1)));
/* dis BCN1 ATIM WND if if2 is station */
- rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1) | BIT(0));
+ error = rtw_read8(Adapter, REG_BCN_CTRL_1, &val8);
+ if (error)
+ return;
+ rtw_write8(Adapter, REG_BCN_CTRL_1, val8 | BIT(0));
}
}
@@ -1345,8 +1436,16 @@ static void hw_var_set_bcn_func(struct adapter *Adapter, u8 variable, u8 *val)
if (*((u8 *)val))
rtw_write8(Adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
- else
- rtw_write8(Adapter, bcn_ctrl_reg, rtw_read8(Adapter, bcn_ctrl_reg) & (~(EN_BCN_FUNCTION | EN_TXBCN_RPT)));
+ else {
+ u8 tmp;
+ int error;
+
+ error = rtw_read8(Adapter, bcn_ctrl_reg, &tmp);
+ if (error)
+ return;
+
+ rtw_write8(Adapter, bcn_ctrl_reg, tmp & (~(EN_BCN_FUNCTION | EN_TXBCN_RPT)));
+ }
}
static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
@@ -1354,13 +1453,19 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
struct dm_priv *pdmpriv = &haldata->dmpriv;
struct odm_dm_struct *podmpriv = &haldata->odmpriv;
+ int error;
+ u8 tmp;
switch (variable) {
case HW_VAR_MEDIA_STATUS:
{
u8 val8;
- val8 = rtw_read8(Adapter, MSR) & 0x0c;
+ error = rtw_read8(Adapter, MSR, &val8);
+ if (error)
+ return;
+
+ val8 &= 0x0c;
val8 |= *((u8 *)val);
rtw_write8(Adapter, MSR, val8);
}
@@ -1369,7 +1474,11 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
{
u8 val8;
- val8 = rtw_read8(Adapter, MSR) & 0x03;
+ error = rtw_read8(Adapter, MSR, &val8);
+ if (error)
+ return;
+
+ val8 &= 0x03;
val8 |= *((u8 *)val) << 2;
rtw_write8(Adapter, MSR, val8);
}
@@ -1407,7 +1516,12 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
/* Set RRSR rate table. */
rtw_write8(Adapter, REG_RRSR, BrateCfg & 0xff);
rtw_write8(Adapter, REG_RRSR + 1, (BrateCfg >> 8) & 0xff);
- rtw_write8(Adapter, REG_RRSR + 2, rtw_read8(Adapter, REG_RRSR + 2) & 0xf0);
+
+ error = rtw_read8(Adapter, REG_RRSR + 2, &tmp);
+ if (error)
+ return;
+
+ rtw_write8(Adapter, REG_RRSR + 2, tmp & 0xf0);
/* Set RTS initial rate */
while (BrateCfg > 0x1) {
@@ -1437,13 +1551,21 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
StopTxBeacon(Adapter);
/* disable related TSF function */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(3)));
+ error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
+ if (error)
+ return;
+
+ rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(3)));
rtw_write32(Adapter, REG_TSFTR, tsf);
rtw_write32(Adapter, REG_TSFTR + 4, tsf >> 32);
/* enable related TSF function */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(3));
+ error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
+ if (error)
+ return;
+
+ rtw_write8(Adapter, REG_BCN_CTRL, tmp | BIT(3));
if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
ResumeTxBeacon(Adapter);
@@ -1471,35 +1593,48 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
rtw_write8(Adapter, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
/* disable update TSF */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4));
+ error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
+ if (error)
+ return;
+
+ rtw_write8(Adapter, REG_BCN_CTRL, tmp | BIT(4));
break;
case HW_VAR_MLME_SITESURVEY:
if (*((u8 *)val)) { /* under sitesurvey */
/* config RCR to receive different BSSID & not to receive data frame */
u32 v = rtw_read32(Adapter, REG_RCR);
+
v &= ~(RCR_CBSSID_BCN);
rtw_write32(Adapter, REG_RCR, v);
/* reject all data frame */
rtw_write16(Adapter, REG_RXFLTMAP2, 0x00);
/* disable update TSF */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4));
+ error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
+ if (error)
+ return;
+ rtw_write8(Adapter, REG_BCN_CTRL, tmp | BIT(4));
} else { /* sitesurvey done */
struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
+ error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
+ if (error)
+ return;
+
if ((is_client_associated_to_ap(Adapter)) ||
((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) {
/* enable to rx data frame */
rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
/* enable update TSF */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4)));
+ rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(4)));
} else if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
/* enable update TSF */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4)));
+ rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(4)));
}
+
if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN);
} else {
@@ -1517,6 +1652,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
{
u8 RetryLimit = 0x30;
u8 type = *((u8 *)val);
+ u8 tmp;
struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
if (type == 0) { /* prepare to join */
@@ -1541,7 +1677,11 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
} else if (type == 2) {
/* sta add event call back */
/* enable update TSF */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4)));
+ error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
+ if (error)
+ return;
+
+ rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(4)));
if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
RetryLimit = 0x7;
@@ -1671,7 +1811,11 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
case HW_VAR_ACM_CTRL:
{
u8 acm_ctrl = *((u8 *)val);
- u8 AcmCtrl = rtw_read8(Adapter, REG_ACMHWCTRL);
+ u8 AcmCtrl;
+
+ error = rtw_read8(Adapter, REG_ACMHWCTRL, &AcmCtrl);
+ if (error)
+ return;
if (acm_ctrl > 1)
AcmCtrl = AcmCtrl | 0x1;
@@ -1699,6 +1843,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
{
u8 MinSpacingToSet;
u8 SecMinSpace;
+ u8 tmp;
MinSpacingToSet = *((u8 *)val);
if (MinSpacingToSet <= 7) {
@@ -1719,7 +1864,13 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
}
if (MinSpacingToSet < SecMinSpace)
MinSpacingToSet = SecMinSpace;
- rtw_write8(Adapter, REG_AMPDU_MIN_SPACE, (rtw_read8(Adapter, REG_AMPDU_MIN_SPACE) & 0xf8) | MinSpacingToSet);
+
+ error = rtw_read8(Adapter, REG_AMPDU_MIN_SPACE, &tmp);
+ if (error)
+ return;
+
+ rtw_write8(Adapter, REG_AMPDU_MIN_SPACE, (tmp & 0xf8) |
+ MinSpacingToSet);
}
}
break;
@@ -1868,7 +2019,13 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
break;
case HW_VAR_BCN_VALID:
/* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
- rtw_write8(Adapter, REG_TDECTRL + 2, rtw_read8(Adapter, REG_TDECTRL + 2) | BIT(0));
+ u8 tmp;
+
+ error = rtw_read8(Adapter, REG_TDECTRL + 2, &tmp);
+ if (error)
+ return;
+
+ rtw_write8(Adapter, REG_TDECTRL + 2, tmp | BIT(0));
break;
default:
break;
@@ -1880,17 +2037,23 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
{
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
struct odm_dm_struct *podmpriv = &haldata->odmpriv;
+ int error;
+ u8 tmp;
switch (variable) {
case HW_VAR_BASIC_RATE:
*((u16 *)(val)) = haldata->BasicRateSet;
fallthrough;
case HW_VAR_TXPAUSE:
- val[0] = rtw_read8(Adapter, REG_TXPAUSE);
+ error = rtw_read8(Adapter, REG_TXPAUSE, val);
break;
case HW_VAR_BCN_VALID:
/* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2 */
- val[0] = (BIT(0) & rtw_read8(Adapter, REG_TDECTRL + 2)) ? true : false;
+ error = rtw_read8(Adapter, REG_TDECTRL + 2, &tmp);
+ if (error)
+ break;
+
+ val[0] = (BIT(0) & tmp) ? true : false;
break;
case HW_VAR_DM_FLAG:
val[0] = podmpriv->SupportAbility;
@@ -2035,6 +2198,7 @@ static u8 SetHalDefVar8188EUsb(struct adapter *Adapter, enum hal_def_variable eV
{
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
u8 bResult = _SUCCESS;
+ int error;
switch (eVariable) {
case HAL_DEF_DBG_DM_FUNC:
@@ -2058,7 +2222,10 @@ static u8 SetHalDefVar8188EUsb(struct adapter *Adapter, enum hal_def_variable eV
} else if (dm_func == 6) {/* turn on all dynamic func */
if (!(podmpriv->SupportAbility & DYNAMIC_BB_DIG)) {
struct rtw_dig *pDigTable = &podmpriv->DM_DigTable;
- pDigTable->CurIGValue = rtw_read8(Adapter, 0xc50);
+
+ error = rtw_read8(Adapter, 0xc50, &pDigTable->CurIGValue);
+ if (error)
+ return _FAIL;
}
podmpriv->SupportAbility = DYNAMIC_ALL_FUNC_ENABLE;
DBG_88E("==> Turn on all dynamic function...\n");
@@ -2168,6 +2335,8 @@ static void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
u32 bcn_ctrl_reg = REG_BCN_CTRL;
+ int error;
+ u8 tmp;
/* reset TSF, enable update TSF, correcting TSF On Beacon */
/* BCN interval */
@@ -2193,7 +2362,11 @@ static void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
ResumeTxBeacon(adapt);
- rtw_write8(adapt, bcn_ctrl_reg, rtw_read8(adapt, bcn_ctrl_reg) | BIT(1));
+ error = rtw_read8(adapt, bcn_ctrl_reg, &tmp);
+ if (error)
+ return;
+
+ rtw_write8(adapt, bcn_ctrl_reg, tmp | BIT(1));
}
static void rtl8188eu_init_default_value(struct adapter *adapt)
diff --git a/drivers/staging/r8188eu/hal/usb_ops_linux.c b/drivers/staging/r8188eu/hal/usb_ops_linux.c
index 953fa05dc30c..380d126c8b2f 100644
--- a/drivers/staging/r8188eu/hal/usb_ops_linux.c
+++ b/drivers/staging/r8188eu/hal/usb_ops_linux.c
@@ -101,26 +101,29 @@ static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u16 value, void *pdata,
return status;
}
-static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr)
+static int usb_read8(struct intf_hdl *pintfhdl, u32 addr, u8 *data)
{
u8 requesttype;
u16 wvalue;
u16 len;
- u8 data = 0;
-
+ int res;
+ if (WARN_ON(unlikely(!data)))
+ return -EINVAL;
requesttype = 0x01;/* read_in */
wvalue = (u16)(addr & 0x0000ffff);
len = 1;
- usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
-
-
-
- return data;
+ res = usbctrl_vendorreq(pintfhdl, wvalue, data, len, requesttype);
+ if (res < 0)
+ dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 8 bytes: %d\n", res);
+ else
+ /* Noone cares about positive return value */
+ res = 0;
+ return res;
}
static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
diff --git a/drivers/staging/r8188eu/include/odm_interface.h b/drivers/staging/r8188eu/include/odm_interface.h
index 6b589413d56c..8e531d272927 100644
--- a/drivers/staging/r8188eu/include/odm_interface.h
+++ b/drivers/staging/r8188eu/include/odm_interface.h
@@ -60,7 +60,7 @@ typedef void (*RT_WORKITEM_CALL_BACK)(void *pContext);
/* =========== EXtern Function Prototype */
-u8 ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr);
+int ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 *data);
u16 ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr);
diff --git a/drivers/staging/r8188eu/include/rtw_io.h b/drivers/staging/r8188eu/include/rtw_io.h
index f1b3074fa075..fd99b36abca6 100644
--- a/drivers/staging/r8188eu/include/rtw_io.h
+++ b/drivers/staging/r8188eu/include/rtw_io.h
@@ -85,7 +85,7 @@ struct intf_hdl;
struct io_queue;
struct _io_ops {
- u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr);
+ int (*_read8)(struct intf_hdl *pintfhdl, u32 addr, u8 *data);
u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
@@ -248,7 +248,7 @@ void unregister_intf_hdl(struct intf_hdl *pintfhdl);
void _rtw_attrib_read(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
void _rtw_attrib_write(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
-u8 _rtw_read8(struct adapter *adapter, u32 addr);
+int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data);
u16 _rtw_read16(struct adapter *adapter, u32 addr);
u32 _rtw_read32(struct adapter *adapter, u32 addr);
void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
@@ -270,7 +270,7 @@ u32 _rtw_write_port_and_wait(struct adapter *adapter, u32 addr, u32 cnt,
u8 *pmem, int timeout_ms);
void _rtw_write_port_cancel(struct adapter *adapter);
-#define rtw_read8(adapter, addr) _rtw_read8((adapter), (addr))
+#define rtw_read8(adapter, addr, data) _rtw_read8((adapter), (addr), (data))
#define rtw_read16(adapter, addr) _rtw_read16((adapter), (addr))
#define rtw_read32(adapter, addr) _rtw_read32((adapter), (addr))
#define rtw_read_mem(adapter, addr, cnt, mem) \
diff --git a/drivers/staging/r8188eu/os_dep/ioctl_linux.c b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
index ab4a9200f079..c9f0772bcbe1 100644
--- a/drivers/staging/r8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
@@ -2074,6 +2074,7 @@ static int rtw_wx_read32(struct net_device *dev,
u32 data32;
u32 bytes;
u8 *ptmp;
+ int error;
padapter = (struct adapter *)rtw_netdev_priv(dev);
p = &wrqu->data;
@@ -2093,7 +2094,10 @@ static int rtw_wx_read32(struct net_device *dev,
switch (bytes) {
case 1:
- data32 = rtw_read8(padapter, addr);
+ error = rtw_read8(padapter, addr, (u8 *) &data32);
+ if (error)
+ return error;
+
sprintf(extra, "0x%02X", data32);
break;
case 2:
@@ -2251,6 +2255,7 @@ static void rtw_dbg_mode_hdl(struct adapter *padapter, u32 id, u8 *pdata, u32 le
u8 path;
u8 offset;
u32 value;
+ int error;
DBG_88E("%s\n", __func__);
@@ -2262,7 +2267,8 @@ static void rtw_dbg_mode_hdl(struct adapter *padapter, u32 id, u8 *pdata, u32 le
RegRWStruct = (struct mp_rw_reg *)pdata;
switch (RegRWStruct->width) {
case 1:
- RegRWStruct->value = rtw_read8(padapter, RegRWStruct->offset);
+ error = rtw_read8(padapter, RegRWStruct->offset,
+ (u8 *) &RegRWStruct->value);
break;
case 2:
RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset);
@@ -3964,6 +3970,8 @@ static int rtw_dbg_port(struct net_device *dev,
struct security_priv *psecuritypriv = &padapter->securitypriv;
struct wlan_network *cur_network = &pmlmepriv->cur_network;
struct sta_priv *pstapriv = &padapter->stapriv;
+ int error;
+ u32 tmp;
pdata = (u32 *)&wrqu->data;
@@ -3978,7 +3986,8 @@ static int rtw_dbg_port(struct net_device *dev,
case 0x70:/* read_reg */
switch (minor_cmd) {
case 1:
- DBG_88E("rtw_read8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg));
+ if (!rtw_read8(padapter, arg, (u8 *) &tmp))
+ DBG_88E("rtw_read8(0x%x) = 0x%02x\n", arg, (u8) tmp);
break;
case 2:
DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
@@ -3992,7 +4001,9 @@ static int rtw_dbg_port(struct net_device *dev,
switch (minor_cmd) {
case 1:
rtw_write8(padapter, arg, extra_arg);
- DBG_88E("rtw_write8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg));
+ if (rtw_read8(padapter, arg, (u8 *) &tmp))
+ DBG_88E("rtw_write8(0x%x) = 0x%02x\n", arg, (u8) tmp);
+
break;
case 2:
rtw_write16(padapter, arg, extra_arg);
@@ -4096,8 +4107,10 @@ static int rtw_dbg_port(struct net_device *dev,
if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
ret = -EPERM;
- final = rtw_read8(padapter, reg);
- if (start_value + write_num - 1 == final)
+ error = rtw_read8(padapter, reg, &final);
+ if (error)
+ return error;
+ else if (start_value + write_num - 1 == final)
DBG_88E("continuous IOL_CMD_WB_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
else
DBG_88E("continuous IOL_CMD_WB_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
@@ -4423,13 +4436,16 @@ static int rtw_dbg_port(struct net_device *dev,
case 0xfd:
rtw_write8(padapter, 0xc50, arg);
- DBG_88E("wr(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50));
+ DBG_88E_REG8("wr(0xc50) = 0x%x\n", padapter, 0xc50);
rtw_write8(padapter, 0xc58, arg);
- DBG_88E("wr(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58));
+ error = rtw_read8(padapter, 0xc58, (u8 *) &tmp);
+ if (error)
+ return error;
+ DBG_88E("wr(0xc58) = 0x%x\n", (u8) tmp);
break;
case 0xfe:
- DBG_88E("rd(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50));
- DBG_88E("rd(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58));
+ DBG_88E_REG8("rd(0xc50) = 0x%x\n", padapter, 0xc50);
+ DBG_88E_REG8("rd(0xc58) = 0x%x\n", padapter, 0xc58);
break;
case 0xff:
DBG_88E("dbg(0x210) = 0x%x\n", rtw_read32(padapter, 0x210));
@@ -5326,6 +5342,8 @@ static int rtw_mp_read_reg(struct net_device *dev,
char data[20], tmp[20];
u32 addr;
u32 ret, i = 0, j = 0, strtout = 0;
+ u32 val32;
+ int error;
if (!input)
return -ENOMEM;
@@ -5361,7 +5379,10 @@ static int rtw_mp_read_reg(struct net_device *dev,
switch (width) {
case 'b':
/* 1 byte */
- sprintf(extra, "%d\n", rtw_read8(padapter, addr));
+ error = rtw_read8(padapter, addr, (u8 *) &val32);
+ if (error)
+ return error;
+ sprintf(extra, "%d\n", (u8) val32);
wrqu->length = strlen(extra);
break;
case 'w':
@@ -5889,6 +5910,8 @@ static int rtw_mp_arx(struct net_device *dev,
u32 cckok = 0, cckcrc = 0, ofdmok = 0, ofdmcrc = 0, htok = 0, htcrc = 0, OFDM_FA = 0, CCK_FA = 0;
char *input = kmalloc(wrqu->length, GFP_KERNEL);
struct adapter *padapter = rtw_netdev_priv(dev);
+ int error = 0;
+ u8 tmp;
if (!input)
return -ENOMEM;
@@ -5934,13 +5957,25 @@ static int rtw_mp_arx(struct net_device *dev,
OFDM_FA = read_bbreg(padapter, 0xda4, 0x0000FFFF);
OFDM_FA = read_bbreg(padapter, 0xda4, 0xFFFF0000);
OFDM_FA = read_bbreg(padapter, 0xda8, 0x0000FFFF);
- CCK_FA = (rtw_read8(padapter, 0xa5b) << 8) | (rtw_read8(padapter, 0xa5c));
+
+ error = rtw_read8(padapter, 0xa5b, &tmp);
+ if (error)
+ goto end;
+
+ CCK_FA = tmp << 8;
+
+ error = rtw_read8(padapter, 0xa5c, &tmp);
+ if (error)
+ goto end;
+
+ CCK_FA |= tmp;
sprintf(extra, "Phy Received packet OK:%d CRC error:%d FA Counter: %d", cckok + ofdmok + htok, cckcrc + ofdmcrc + htcrc, OFDM_FA + CCK_FA);
}
wrqu->length = strlen(extra) + 1;
+end:
kfree(input);
- return 0;
+ return error;
}
static int rtw_mp_trx_query(struct net_device *dev,
--
2.32.0
_rtw_read16 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_read16() 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 <[email protected]>
---
drivers/staging/r8188eu/core/rtw_debug.c | 7 +++-
drivers/staging/r8188eu/core/rtw_io.c | 9 ++---
drivers/staging/r8188eu/core/rtw_mp_ioctl.c | 4 +-
drivers/staging/r8188eu/hal/odm_interface.c | 4 +-
.../staging/r8188eu/hal/rtl8188e_hal_init.c | 29 +++++++++++----
drivers/staging/r8188eu/hal/rtl8188e_phycfg.c | 5 ++-
drivers/staging/r8188eu/hal/usb_halinit.c | 37 ++++++++++++++++---
drivers/staging/r8188eu/hal/usb_ops_linux.c | 19 ++++++++--
.../staging/r8188eu/include/odm_interface.h | 2 +-
drivers/staging/r8188eu/include/rtw_io.h | 6 +--
drivers/staging/r8188eu/os_dep/ioctl_linux.c | 28 +++++++++++---
11 files changed, 112 insertions(+), 38 deletions(-)
diff --git a/drivers/staging/r8188eu/core/rtw_debug.c b/drivers/staging/r8188eu/core/rtw_debug.c
index 8b7d3eb12bd0..a41675e101ac 100644
--- a/drivers/staging/r8188eu/core/rtw_debug.c
+++ b/drivers/staging/r8188eu/core/rtw_debug.c
@@ -91,7 +91,12 @@ int proc_get_read_reg(char *page, char **start,
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));
+ error = rtw_read16(padapter, proc_get_read_addr, (u16 *) &tmp);
+ if (error)
+ return len;
+
+ len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n",
+ proc_get_read_addr, (u16) tmp);
break;
case 4:
len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n", proc_get_read_addr, rtw_read32(padapter, proc_get_read_addr));
diff --git a/drivers/staging/r8188eu/core/rtw_io.c b/drivers/staging/r8188eu/core/rtw_io.c
index 2714506c8ffb..fd64893c778d 100644
--- a/drivers/staging/r8188eu/core/rtw_io.c
+++ b/drivers/staging/r8188eu/core/rtw_io.c
@@ -45,18 +45,15 @@ int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data)
return _read8(pintfhdl, addr, data);
}
-u16 _rtw_read16(struct adapter *adapter, u32 addr)
+int __must_check _rtw_read16(struct adapter *adapter, u32 addr, u16 *data)
{
- u16 r_val;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &pio_priv->intf;
- u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
+ int (*_read16)(struct intf_hdl *pintfhdl, u32 addr, u16 *data);
_read16 = pintfhdl->io_ops._read16;
- r_val = _read16(pintfhdl, addr);
-
- return r_val;
+ return _read16(pintfhdl, addr, data);
}
u32 _rtw_read32(struct adapter *adapter, u32 addr)
diff --git a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
index 894ab456f202..c6f7636c2174 100644
--- a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
+++ b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
@@ -653,7 +653,9 @@ int rtl8188eu_oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv)
status = NDIS_STATUS_NOT_ACCEPTED;
break;
case 2:
- RegRWStruct->value = rtw_read16(Adapter, offset);
+ error = rtw_read16(Adapter, offset, (u16 *) &RegRWStruct->value);
+ if (error)
+ status = NDIS_STATUS_NOT_ACCEPTED;
break;
default:
width = 4;
diff --git a/drivers/staging/r8188eu/hal/odm_interface.c b/drivers/staging/r8188eu/hal/odm_interface.c
index 9a9df98da727..669d3e5eafb6 100644
--- a/drivers/staging/r8188eu/hal/odm_interface.c
+++ b/drivers/staging/r8188eu/hal/odm_interface.c
@@ -10,10 +10,10 @@ int ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 *data)
return rtw_read8(Adapter, RegAddr, data);
}
-u16 ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr)
+int ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u16 *data)
{
struct adapter *Adapter = pDM_Odm->Adapter;
- return rtw_read16(Adapter, RegAddr);
+ return rtw_read16(Adapter, RegAddr, data);
}
u32 ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
index cfc429965b7d..94e2828c328e 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
@@ -262,7 +262,11 @@ static void efuse_read_phymap_from_txpktbuf(
* do not remove it as the rtw_read16() call consumes
* 2 bytes from the EEPROM source.
*/
- u16 lenc = rtw_read16(adapter, REG_PKTBUF_DBG_DATA_L);
+ u16 lenc;
+
+ error = rtw_read16(adapter, REG_PKTBUF_DBG_DATA_L, &lenc);
+ if (error)
+ return;
len = le32_to_cpu(lo32) & 0x0000ffff;
@@ -778,21 +782,27 @@ hal_EfusePowerSwitch_RTL8188E(
rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
/* 1.2V Power: From VDDON with Power Cut(0x0000h[15]), defualt valid */
- tmpV16 = rtw_read16(pAdapter, REG_SYS_ISO_CTRL);
- if (!(tmpV16 & PWC_EV12V)) {
+ error = rtw_read16(pAdapter, REG_SYS_ISO_CTRL, &tmpV16);
+ if (error) {
+ return;
+ } else if (!(tmpV16 & PWC_EV12V)) {
tmpV16 |= PWC_EV12V;
rtw_write16(pAdapter, REG_SYS_ISO_CTRL, tmpV16);
}
/* Reset: 0x0000h[28], default valid */
- tmpV16 = rtw_read16(pAdapter, REG_SYS_FUNC_EN);
- if (!(tmpV16 & FEN_ELDR)) {
+ error = rtw_read16(pAdapter, REG_SYS_FUNC_EN, &tmpV16);
+ if (error) {
+ return;
+ } else if (!(tmpV16 & FEN_ELDR)) {
tmpV16 |= FEN_ELDR;
rtw_write16(pAdapter, REG_SYS_FUNC_EN, tmpV16);
}
/* Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */
- tmpV16 = rtw_read16(pAdapter, REG_SYS_CLKR);
- if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) {
+ error = rtw_read16(pAdapter, REG_SYS_CLKR, &tmpV16);
+ if (error) {
+ return;
+ } else if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) {
tmpV16 |= (LOADER_CLK_EN | ANA8M);
rtw_write16(pAdapter, REG_SYS_CLKR, tmpV16);
}
@@ -1915,8 +1925,11 @@ u8 GetEEPROMSize8188E(struct adapter *padapter)
{
u8 size = 0;
u32 cr;
+ int error;
- cr = rtw_read16(padapter, REG_9346CR);
+ error = rtw_read16(padapter, REG_9346CR, (u16 *) &cr);
+ if (error)
+ return size;
/* 6: EEPROM used is 93C46, 4: boot from E-Fuse. */
size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
index f6d4c91a97a2..3afb66195413 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
@@ -577,11 +577,14 @@ PHY_BBConfig8188E(
struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter);
u32 RegVal;
u8 CrystalCap;
+ int error;
phy_InitBBRFRegisterDefinition(Adapter);
/* Enable BB and RF */
- RegVal = rtw_read16(Adapter, REG_SYS_FUNC_EN);
+ error = rtw_read16(Adapter, REG_SYS_FUNC_EN, (u16 *) &RegVal);
+ if (error)
+ return _FAIL;
rtw_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal | BIT(13) | BIT(0) | BIT(1)));
/* 20090923 Joseph: Advised by Steven and Jenyu. Power sequence before init RF. */
diff --git a/drivers/staging/r8188eu/hal/usb_halinit.c b/drivers/staging/r8188eu/hal/usb_halinit.c
index 4f1d7f9b43c3..4ecccc6499aa 100644
--- a/drivers/staging/r8188eu/hal/usb_halinit.c
+++ b/drivers/staging/r8188eu/hal/usb_halinit.c
@@ -90,6 +90,8 @@ static u32 rtl8188eu_InitPowerOn(struct adapter *adapt)
u16 value16;
/* HW Power on sequence */
struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
+ int error;
+
if (haldata->bMacPwrCtrlOn)
return _SUCCESS;
@@ -103,7 +105,10 @@ static u32 rtl8188eu_InitPowerOn(struct adapter *adapt)
rtw_write16(adapt, REG_CR, 0x00); /* suggseted by zhouzhou, by page, 20111230 */
/* Enable MAC DMA/WMAC/SCHEDULE/SEC block */
- value16 = rtw_read16(adapt, REG_CR);
+ error = rtw_read16(adapt, REG_CR, &value16);
+ if (error)
+ return _FAIL;
+
value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN
| PROTOCOL_EN | SCHEDULE_EN | ENSEC | CALTMR_EN);
/* for SDIO - Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy. Added by tynli. 2011.08.31. */
@@ -207,7 +212,14 @@ static void _InitNormalChipRegPriority(struct adapter *Adapter, u16 beQ,
u16 bkQ, u16 viQ, u16 voQ, u16 mgtQ,
u16 hiQ)
{
- u16 value16 = (rtw_read16(Adapter, REG_TRXDMA_CTRL) & 0x7);
+ u16 value16;
+ int error;
+
+ error = rtw_read16(Adapter, REG_TRXDMA_CTRL, &value16);
+ if (error)
+ return;
+
+ value16 &= 0x7;
value16 |= _TXDMA_BEQ_MAP(beQ) | _TXDMA_BKQ_MAP(bkQ) |
_TXDMA_VIQ_MAP(viQ) | _TXDMA_VOQ_MAP(voQ) |
@@ -868,7 +880,12 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
/* Hw bug which Hw initials RxFF boundary size to a value which is larger than the real Rx buffer size in 88E. */
/* */
/* Enable MACTXEN/MACRXEN block */
- value16 = rtw_read16(Adapter, REG_CR);
+ error = rtw_read16(Adapter, REG_CR, &value16);
+ if (error) {
+ status = _FAIL;
+ goto exit;
+ }
+
value16 |= (MACTXEN | MACRXEN);
rtw_write8(Adapter, REG_CR, value16);
@@ -937,6 +954,8 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
Adapter->mppriv.channel = haldata->CurrentChannel;
MPT_InitializeAdapter(Adapter, Adapter->mppriv.channel);
} else {
+ u16 val16;
+
/* 2010/08/11 MH Merge from 8192SE for Minicard init. We need to confirm current radio status */
/* and then decide to enable RF or not.!!!??? For Selective suspend mode. We may not */
/* call initstruct adapter. May cause some problem?? */
@@ -956,7 +975,13 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
rtw_write16(Adapter, REG_TX_RPT_TIME, 0x3DF0);
/* enable tx DMA to drop the redundate data of packet */
- rtw_write16(Adapter, REG_TXDMA_OFFSET_CHK, (rtw_read16(Adapter, REG_TXDMA_OFFSET_CHK) | DROP_DATA_EN));
+ error = rtw_read16(Adapter, REG_TXDMA_OFFSET_CHK, &val16);
+ if (error) {
+ status = _FAIL;
+ goto exit;
+ }
+
+ rtw_write16(Adapter, REG_TXDMA_OFFSET_CHK, (val16 | DROP_DATA_EN));
HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_IQK);
/* 2010/08/26 MH Merge from 8192CE. */
@@ -1982,7 +2007,9 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
rtw_write8(Adapter, REG_TXPAUSE, 0xff);
/* keep sn */
- Adapter->xmitpriv.nqos_ssn = rtw_read16(Adapter, REG_NQOS_SEQ);
+ error = rtw_read16(Adapter, REG_NQOS_SEQ, &Adapter->xmitpriv.nqos_ssn);
+ if (error)
+ return;
if (!pwrpriv->bkeepfwalive) {
/* RX DMA stop */
diff --git a/drivers/staging/r8188eu/hal/usb_ops_linux.c b/drivers/staging/r8188eu/hal/usb_ops_linux.c
index 380d126c8b2f..58e852555f54 100644
--- a/drivers/staging/r8188eu/hal/usb_ops_linux.c
+++ b/drivers/staging/r8188eu/hal/usb_ops_linux.c
@@ -126,19 +126,30 @@ static int usb_read8(struct intf_hdl *pintfhdl, u32 addr, u8 *data)
return res;
}
-static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
+static int usb_read16(struct intf_hdl *pintfhdl, u32 addr, u16 *data)
{
u8 requesttype;
u16 wvalue;
u16 len;
- __le32 data;
+ int res;
+ __le32 tmp;
+
+ if (WARN_ON(unlikely(!data)))
+ return -EINVAL;
requesttype = 0x01;/* read_in */
wvalue = (u16)(addr & 0x0000ffff);
len = 2;
- usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
+ res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
+ if (res < 0) {
+ dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 16 bytes: %d\n", res);
+ } else {
+ /* Noone cares about positive return value */
+ *data = le32_to_cpu(tmp) & 0xffff;
+ res = 0;
+ }
- return (u16)(le32_to_cpu(data) & 0xffff);
+ return res;
}
static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
diff --git a/drivers/staging/r8188eu/include/odm_interface.h b/drivers/staging/r8188eu/include/odm_interface.h
index 8e531d272927..2455dae6eebb 100644
--- a/drivers/staging/r8188eu/include/odm_interface.h
+++ b/drivers/staging/r8188eu/include/odm_interface.h
@@ -62,7 +62,7 @@ typedef void (*RT_WORKITEM_CALL_BACK)(void *pContext);
int ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 *data);
-u16 ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr);
+int ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u16 *data);
u32 ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr);
diff --git a/drivers/staging/r8188eu/include/rtw_io.h b/drivers/staging/r8188eu/include/rtw_io.h
index fd99b36abca6..c44554c848cf 100644
--- a/drivers/staging/r8188eu/include/rtw_io.h
+++ b/drivers/staging/r8188eu/include/rtw_io.h
@@ -86,7 +86,7 @@ struct io_queue;
struct _io_ops {
int (*_read8)(struct intf_hdl *pintfhdl, u32 addr, u8 *data);
- u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
+ int (*_read16)(struct intf_hdl *pintfhdl, u32 addr, u16 *data);
u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
@@ -249,7 +249,7 @@ void _rtw_attrib_read(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
void _rtw_attrib_write(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data);
-u16 _rtw_read16(struct adapter *adapter, u32 addr);
+int __must_check _rtw_read16(struct adapter *adapter, u32 addr, u16 *data);
u32 _rtw_read32(struct adapter *adapter, u32 addr);
void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
void _rtw_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
@@ -271,7 +271,7 @@ u32 _rtw_write_port_and_wait(struct adapter *adapter, u32 addr, u32 cnt,
void _rtw_write_port_cancel(struct adapter *adapter);
#define rtw_read8(adapter, addr, data) _rtw_read8((adapter), (addr), (data))
-#define rtw_read16(adapter, addr) _rtw_read16((adapter), (addr))
+#define rtw_read16(adapter, addr, data) _rtw_read16((adapter), (addr), (data))
#define rtw_read32(adapter, addr) _rtw_read32((adapter), (addr))
#define rtw_read_mem(adapter, addr, cnt, mem) \
_rtw_read_mem((adapter), (addr), (cnt), (mem))
diff --git a/drivers/staging/r8188eu/os_dep/ioctl_linux.c b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
index c9f0772bcbe1..79f0fbaa841e 100644
--- a/drivers/staging/r8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
@@ -2101,7 +2101,10 @@ static int rtw_wx_read32(struct net_device *dev,
sprintf(extra, "0x%02X", data32);
break;
case 2:
- data32 = rtw_read16(padapter, addr);
+ error = rtw_read16(padapter, addr, (u16 *) &data32);
+ if (error)
+ return error;
+
sprintf(extra, "0x%04X", data32);
break;
case 4:
@@ -2271,7 +2274,8 @@ static void rtw_dbg_mode_hdl(struct adapter *padapter, u32 id, u8 *pdata, u32 le
(u8 *) &RegRWStruct->value);
break;
case 2:
- RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset);
+ error = rtw_read16(padapter, RegRWStruct->offset,
+ (u16 *) &RegRWStruct->value);
break;
case 4:
RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset);
@@ -3990,7 +3994,8 @@ static int rtw_dbg_port(struct net_device *dev,
DBG_88E("rtw_read8(0x%x) = 0x%02x\n", arg, (u8) tmp);
break;
case 2:
- DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
+ if (!rtw_read16(padapter, arg, (u16 *) &tmp))
+ DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, (u16) tmp);
break;
case 4:
DBG_88E("rtw_read32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
@@ -4006,8 +4011,12 @@ static int rtw_dbg_port(struct net_device *dev,
break;
case 2:
+ error = rtw_read16(padapter, arg, (u16 *) &tmp);
+ if (error)
+ return error;
+
rtw_write16(padapter, arg, extra_arg);
- DBG_88E("rtw_write16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
+ DBG_88E("rtw_write16(0x%x) = 0x%04x\n", arg, (u16) tmp);
break;
case 4:
rtw_write32(padapter, arg, extra_arg);
@@ -4138,7 +4147,10 @@ static int rtw_dbg_port(struct net_device *dev,
if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
ret = -EPERM;
- final = rtw_read16(padapter, reg);
+ error = rtw_read16(padapter, reg, &final);
+ if (error)
+ return error;
+
if (start_value + write_num - 1 == final)
DBG_88E("continuous IOL_CMD_WW_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
else
@@ -5387,7 +5399,11 @@ static int rtw_mp_read_reg(struct net_device *dev,
break;
case 'w':
/* 2 bytes */
- sprintf(data, "%04x\n", rtw_read16(padapter, addr));
+ error = rtw_read16(padapter, addr, (u16 *) &val32);
+ if (error)
+ return error;
+
+ sprintf(data, "%04x\n", (u16) val32);
for (i = 0; i <= strlen(data); i++) {
if (i % 2 == 0) {
tmp[j] = ' ';
--
2.32.0
ReadEFuse can fail in case of _rtw_read() failure. Callers should
handle this error to avoid uninit value bugs, since ReadEFuse
won't initialized passed pbuf in case of usb transfer failure.
To achieve it, ReadEFuseByte() now returns an int and all callers of
ReadEFuseByte() passes error code up to calltrace to rtw_usb_if1_init(),
which fails when reading regiters fails.
Signed-off-by: Pavel Skripkin <[email protected]>
---
drivers/staging/r8188eu/core/rtw_efuse.c | 45 ++++++++-----
drivers/staging/r8188eu/hal/hal_intf.c | 6 +-
.../staging/r8188eu/hal/rtl8188e_hal_init.c | 65 ++++++++++++-------
drivers/staging/r8188eu/hal/usb_halinit.c | 18 +++--
drivers/staging/r8188eu/include/hal_intf.h | 6 +-
.../staging/r8188eu/include/rtl8188e_hal.h | 2 +-
drivers/staging/r8188eu/include/rtw_efuse.h | 4 +-
drivers/staging/r8188eu/os_dep/usb_intf.c | 3 +-
8 files changed, 96 insertions(+), 53 deletions(-)
diff --git a/drivers/staging/r8188eu/core/rtw_efuse.c b/drivers/staging/r8188eu/core/rtw_efuse.c
index dfe60bc6a547..5bfcf80b2678 100644
--- a/drivers/staging/r8188eu/core/rtw_efuse.c
+++ b/drivers/staging/r8188eu/core/rtw_efuse.c
@@ -149,7 +149,7 @@ Efuse_CalculateWordCnts(u8 word_en)
/* */
/* Created by Roger, 2008.10.21. */
/* */
-void
+int
ReadEFuseByte(
struct adapter *Adapter,
u16 _offset,
@@ -163,21 +163,21 @@ ReadEFuseByte(
if (pseudo) {
Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf);
- return;
+ return 0;
}
/* Write Address */
rtw_write8(Adapter, EFUSE_CTRL + 1, (_offset & 0xff));
error = rtw_read8(Adapter, EFUSE_CTRL + 2, &readbyte);
if (error)
- return;
+ return error;
rtw_write8(Adapter, EFUSE_CTRL + 2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
/* Write bit 32 0 */
error = rtw_read8(Adapter, EFUSE_CTRL + 3, &readbyte);
if (error)
- return;
+ return error;
rtw_write8(Adapter, EFUSE_CTRL + 3, (readbyte & 0x7f));
@@ -185,12 +185,12 @@ ReadEFuseByte(
retry = 0;
error = rtw_read32(Adapter, EFUSE_CTRL, &value32);
if (error)
- return;
+ return error;
while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) {
error = rtw_read32(Adapter, EFUSE_CTRL, &value32);
if (error)
- return;
+ return error;
retry++;
}
@@ -202,9 +202,11 @@ ReadEFuseByte(
udelay(50);
error = rtw_read32(Adapter, EFUSE_CTRL, &value32);
if (error)
- return;
+ return error;
*pbuf = (u8)(value32 & 0xff);
+
+ return 0;
}
/* */
@@ -225,9 +227,9 @@ ReadEFuseByte(
/* write addr must be after sec5. */
/* */
-static void efuse_ReadEFuse(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool pseudo)
+static int efuse_ReadEFuse(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool pseudo)
{
- Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, pseudo);
+ return Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, pseudo);
}
void EFUSE_GetEfuseDefinition(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut, bool pseudo
@@ -538,6 +540,7 @@ u8 efuse_GetCurrentSize(struct adapter *padapter, u16 *size)
u8 rtw_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
{
u16 mapLen = 0;
+ int error;
EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false);
@@ -546,7 +549,9 @@ u8 rtw_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
Efuse_PowerSwitch(padapter, false, true);
- efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, false);
+ error = efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, false);
+ if (error)
+ return _FAIL;
Efuse_PowerSwitch(padapter, false, false);
@@ -556,6 +561,7 @@ u8 rtw_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
u8 rtw_BT_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
{
u16 mapLen = 0;
+ int error;
EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false);
@@ -564,7 +570,9 @@ u8 rtw_BT_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
Efuse_PowerSwitch(padapter, false, true);
- efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data, false);
+ error = efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data, false);
+ if (error)
+ return _FAIL;
Efuse_PowerSwitch(padapter, false, false);
@@ -835,17 +843,22 @@ efuse_ShadowRead4Byte(
* 11/11/2008 MHC Create Version 0.
*
*---------------------------------------------------------------------------*/
-static void Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse, bool pseudo)
+static int Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse, bool pseudo)
{
u16 mapLen = 0;
+ int error;
Efuse_PowerSwitch(pAdapter, false, true);
EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, pseudo);
- efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse, pseudo);
+ error = efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse, pseudo);
+ if (error)
+ return error;
Efuse_PowerSwitch(pAdapter, false, false);
+
+ return 0;
}
/*-----------------------------------------------------------------------------
@@ -864,7 +877,7 @@ static void Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse,
* 11/13/2008 MHC Create Version 0.
*
*---------------------------------------------------------------------------*/
-void EFUSE_ShadowMapUpdate(
+int EFUSE_ShadowMapUpdate(
struct adapter *pAdapter,
u8 efuseType,
bool pseudo)
@@ -877,7 +890,9 @@ void EFUSE_ShadowMapUpdate(
if (pEEPROM->bautoload_fail_flag)
memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen);
else
- Efuse_ReadAllMap(pAdapter, efuseType, pEEPROM->efuse_eeprom_data, pseudo);
+ return Efuse_ReadAllMap(pAdapter, efuseType, pEEPROM->efuse_eeprom_data, pseudo);
+
+ return 0;
} /* EFUSE_ShadowMapUpdate */
/*-----------------------------------------------------------------------------
diff --git a/drivers/staging/r8188eu/hal/hal_intf.c b/drivers/staging/r8188eu/hal/hal_intf.c
index a6d589e89aeb..dce9a58eaf6f 100644
--- a/drivers/staging/r8188eu/hal/hal_intf.c
+++ b/drivers/staging/r8188eu/hal/hal_intf.c
@@ -12,10 +12,12 @@ void rtw_hal_chip_configure(struct adapter *adapt)
adapt->HalFunc.intf_chip_configure(adapt);
}
-void rtw_hal_read_chip_info(struct adapter *adapt)
+int rtw_hal_read_chip_info(struct adapter *adapt)
{
if (adapt->HalFunc.read_adapter_info)
- adapt->HalFunc.read_adapter_info(adapt);
+ return adapt->HalFunc.read_adapter_info(adapt);
+
+ return _FAIL;
}
void rtw_hal_read_chip_version(struct adapter *adapt)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
index 69649a381727..41cf432398e2 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
@@ -871,7 +871,7 @@ rtl8188e_EfusePowerSwitch(
hal_EfusePowerSwitch_RTL8188E(pAdapter, bWrite, PwrState);
}
-static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
+static int Hal_EfuseReadEFuse88E(struct adapter *Adapter,
u16 _offset,
u16 _size_byte,
u8 *pbuf,
@@ -886,24 +886,26 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
u16 **eFuseWord = NULL;
u16 efuse_utilized = 0;
u8 u1temp = 0;
+ int error = 0;
/* */
/* Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */
/* */
if ((_offset + _size_byte) > EFUSE_MAP_LEN_88E) {/* total E-Fuse table is 512bytes */
DBG_88E("Hal_EfuseReadEFuse88E(): Invalid offset(%#x) with read bytes(%#x)!!\n", _offset, _size_byte);
- goto exit;
+ return -EINVAL;
}
efuseTbl = kzalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL);
if (!efuseTbl) {
DBG_88E("%s: alloc efuseTbl fail!\n", __func__);
- goto exit;
+ return -ENOMEM;
}
eFuseWord = rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
if (!eFuseWord) {
DBG_88E("%s: alloc eFuseWord fail!\n", __func__);
+ error = -ENOMEM;
goto exit;
}
@@ -916,12 +918,16 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
/* 1. Read the first byte to check if efuse is empty!!! */
/* */
/* */
- ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ if (error)
+ goto exit;
+
if (*rtemp8 != 0xFF) {
efuse_utilized++;
eFuse_Addr++;
} else {
DBG_88E("EFUSE is empty efuse_Addr-%d efuse_data =%x\n", eFuse_Addr, *rtemp8);
+ error = -EAGAIN;
goto exit;
}
@@ -933,11 +939,15 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
if ((*rtemp8 & 0x1F) == 0x0F) { /* extended header */
u1temp = ((*rtemp8 & 0xE0) >> 5);
- ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ if (error)
+ goto exit;
if ((*rtemp8 & 0x0F) == 0x0F) {
eFuse_Addr++;
- ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ if (error)
+ goto exit;
if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
eFuse_Addr++;
@@ -958,13 +968,19 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
/* Check word enable condition in the section */
if (!(wren & 0x01)) {
- ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ if (error)
+ goto exit;
+
eFuse_Addr++;
efuse_utilized++;
eFuseWord[offset][i] = (*rtemp8 & 0xff);
if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
break;
- ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ if (error)
+ goto exit;
+
eFuse_Addr++;
efuse_utilized++;
eFuseWord[offset][i] |= (((u16)*rtemp8 << 8) & 0xff00);
@@ -976,7 +992,9 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
}
/* Read next PG header */
- ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ if (error)
+ goto exit;
if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
efuse_utilized++;
@@ -1002,9 +1020,11 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
exit:
kfree(efuseTbl);
kfree(eFuseWord);
+
+ return error;
}
-static void ReadEFuseByIC(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
+static int ReadEFuseByIC(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
{
if (!bPseudoTest) {
int ret = _FAIL;
@@ -1016,28 +1036,25 @@ static void ReadEFuseByIC(struct adapter *Adapter, u8 efuseType, u16 _offset, u1
iol_mode_enable(Adapter, 0);
if (_SUCCESS == ret)
- goto exit;
+ return 0;
}
}
- Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
-
-exit:
- return;
+ return Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
}
-static void ReadEFuse_Pseudo(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
+static int ReadEFuse_Pseudo(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
{
- Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
+ return Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
}
-static void rtl8188e_ReadEFuse(struct adapter *Adapter, u8 efuseType,
+static int rtl8188e_ReadEFuse(struct adapter *Adapter, u8 efuseType,
u16 _offset, u16 _size_byte, u8 *pbuf,
bool bPseudoTest)
{
if (bPseudoTest)
- ReadEFuse_Pseudo(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
+ return ReadEFuse_Pseudo(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
else
- ReadEFuseByIC(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
+ return ReadEFuseByIC(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
}
/* Do not support BT */
@@ -2045,7 +2062,7 @@ s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy)
return status;
}
-void
+int
Hal_InitPGData88E(struct adapter *padapter)
{
struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
@@ -2053,13 +2070,15 @@ Hal_InitPGData88E(struct adapter *padapter)
if (!pEEPROM->bautoload_fail_flag) { /* autoload OK. */
if (!is_boot_from_eeprom(padapter)) {
/* Read EFUSE real map to shadow. */
- EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
+ return EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
}
} else {/* autoload fail */
/* update to default value 0xFF */
if (!is_boot_from_eeprom(padapter))
- EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
+ return EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
}
+
+ return 0;
}
void
diff --git a/drivers/staging/r8188eu/hal/usb_halinit.c b/drivers/staging/r8188eu/hal/usb_halinit.c
index 3826476e3396..687baf4d9d97 100644
--- a/drivers/staging/r8188eu/hal/usb_halinit.c
+++ b/drivers/staging/r8188eu/hal/usb_halinit.c
@@ -1296,7 +1296,7 @@ readAdapterInfo_8188EU(
_ReadLEDSetting(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag);
}
-static void _ReadPROMContent(
+static int _ReadPROMContent(
struct adapter *Adapter
)
{
@@ -1307,7 +1307,7 @@ static void _ReadPROMContent(
/* check system boot selection */
error = rtw_read8(Adapter, REG_9346CR, &eeValue);
if (error)
- return;
+ return error;
eeprom->EepromOrEfuse = (eeValue & BOOT_FROM_EEPROM) ? true : false;
eeprom->bautoload_fail_flag = (eeValue & EEPROM_EN) ? false : true;
@@ -1315,8 +1315,13 @@ static void _ReadPROMContent(
DBG_88E("Boot from %s, Autoload %s !\n", (eeprom->EepromOrEfuse ? "EEPROM" : "EFUSE"),
(eeprom->bautoload_fail_flag ? "Fail" : "OK"));
- Hal_InitPGData88E(Adapter);
+ error = Hal_InitPGData88E(Adapter);
+ if (error)
+ return error;
+
readAdapterInfo_8188EU(Adapter);
+
+ return 0;
}
static void _ReadRFType(struct adapter *Adapter)
@@ -1333,19 +1338,20 @@ static int _ReadAdapterInfo8188EU(struct adapter *Adapter)
MSG_88E("====> %s\n", __func__);
_ReadRFType(Adapter);/* rf_chip -> _InitRFType() */
- _ReadPROMContent(Adapter);
+ if (_ReadPROMContent(Adapter))
+ return _FAIL;
MSG_88E("<==== %s in %d ms\n", __func__, rtw_get_passing_time_ms(start));
return _SUCCESS;
}
-static void ReadAdapterInfo8188EU(struct adapter *Adapter)
+static int ReadAdapterInfo8188EU(struct adapter *Adapter)
{
/* Read EEPROM size before call any EEPROM function */
Adapter->EepromAddressSize = GetEEPROMSize8188E(Adapter);
- _ReadAdapterInfo8188EU(Adapter);
+ return _ReadAdapterInfo8188EU(Adapter);
}
#define GPIO_DEBUG_PORT_NUM 0
diff --git a/drivers/staging/r8188eu/include/hal_intf.h b/drivers/staging/r8188eu/include/hal_intf.h
index fa252540e596..9241af39e3a3 100644
--- a/drivers/staging/r8188eu/include/hal_intf.h
+++ b/drivers/staging/r8188eu/include/hal_intf.h
@@ -154,7 +154,7 @@ struct hal_ops {
void (*intf_chip_configure)(struct adapter *padapter);
- void (*read_adapter_info)(struct adapter *padapter);
+ int (*read_adapter_info)(struct adapter *padapter);
void (*enable_interrupt)(struct adapter *padapter);
void (*disable_interrupt)(struct adapter *padapter);
@@ -222,7 +222,7 @@ struct hal_ops {
void (*EfusePowerSwitch)(struct adapter *padapter, u8 bWrite,
u8 PwrState);
- void (*ReadEFuse)(struct adapter *padapter, u8 efuseType, u16 _offset,
+ int (*ReadEFuse)(struct adapter *padapter, u8 efuseType, u16 _offset,
u16 _size_byte, u8 *pbuf, bool bPseudoTest);
void (*EFUSEGetEfuseDefinition)(struct adapter *padapter, u8 efuseType,
u8 type, void *pOut, bool bPseudoTest);
@@ -324,7 +324,7 @@ void rtw_hal_set_hwreg(struct adapter *padapter, u8 variable, u8 *val);
void rtw_hal_get_hwreg(struct adapter *padapter, u8 variable, u8 *val);
void rtw_hal_chip_configure(struct adapter *padapter);
-void rtw_hal_read_chip_info(struct adapter *padapter);
+int rtw_hal_read_chip_info(struct adapter *padapter);
void rtw_hal_read_chip_version(struct adapter *padapter);
u8 rtw_hal_set_def_var(struct adapter *padapter,
diff --git a/drivers/staging/r8188eu/include/rtl8188e_hal.h b/drivers/staging/r8188eu/include/rtl8188e_hal.h
index 3939bf053de1..db9adbd0b024 100644
--- a/drivers/staging/r8188eu/include/rtl8188e_hal.h
+++ b/drivers/staging/r8188eu/include/rtl8188e_hal.h
@@ -410,7 +410,7 @@ s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy);
/* EFuse */
u8 GetEEPROMSize8188E(struct adapter *padapter);
-void Hal_InitPGData88E(struct adapter *padapter);
+int Hal_InitPGData88E(struct adapter *padapter);
void Hal_EfuseParseIDCode88E(struct adapter *padapter, u8 *hwinfo);
void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *hwinfo,
bool AutoLoadFail);
diff --git a/drivers/staging/r8188eu/include/rtw_efuse.h b/drivers/staging/r8188eu/include/rtw_efuse.h
index b3ff46db2091..9657b66679e3 100644
--- a/drivers/staging/r8188eu/include/rtw_efuse.h
+++ b/drivers/staging/r8188eu/include/rtw_efuse.h
@@ -113,7 +113,7 @@ u8 rtw_BT_efuse_map_write(struct adapter *adapter, u16 addr,
u16 cnts, u8 *data);
u16 Efuse_GetCurrentSize(struct adapter *adapter, u8 efusetype, bool test);
u8 Efuse_CalculateWordCnts(u8 word_en);
-void ReadEFuseByte(struct adapter *adapter, u16 _offset, u8 *pbuf, bool test);
+int ReadEFuseByte(struct adapter *adapter, u16 _offset, u8 *pbuf, bool test);
void EFUSE_GetEfuseDefinition(struct adapter *adapt, u8 type, u8 type1,
void *out, bool bPseudoTest);
u8 efuse_OneByteRead(struct adapter *adapter, u16 addr, u8 *data, bool test);
@@ -128,7 +128,7 @@ u8 Efuse_WordEnableDataWrite(struct adapter *adapter, u16 efuse_addr,
u8 word_en, u8 *data, bool test);
u8 EFUSE_Read1Byte(struct adapter *adapter, u16 address);
-void EFUSE_ShadowMapUpdate(struct adapter *adapter, u8 efusetype, bool test);
+int EFUSE_ShadowMapUpdate(struct adapter *adapter, u8 efusetype, bool test);
void EFUSE_ShadowRead(struct adapter *adapt, u8 type, u16 offset, u32 *val);
#endif
diff --git a/drivers/staging/r8188eu/os_dep/usb_intf.c b/drivers/staging/r8188eu/os_dep/usb_intf.c
index e002070f7fba..7a1a296f66b5 100644
--- a/drivers/staging/r8188eu/os_dep/usb_intf.c
+++ b/drivers/staging/r8188eu/os_dep/usb_intf.c
@@ -608,7 +608,8 @@ static struct adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj,
rtw_hal_chip_configure(padapter);
/* step read efuse/eeprom data and get mac_addr */
- rtw_hal_read_chip_info(padapter);
+ if (rtw_hal_read_chip_info(padapter) == _FAIL)
+ goto free_hal_data;
/* step 5. */
if (rtw_init_drv_sw(padapter) == _FAIL)
--
2.32.0
_rtw_read32 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_read32() 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 <[email protected]>
---
drivers/staging/r8188eu/core/rtw_debug.c | 61 +++++++--
drivers/staging/r8188eu/core/rtw_efuse.c | 14 ++-
drivers/staging/r8188eu/core/rtw_io.c | 9 +-
drivers/staging/r8188eu/core/rtw_mp.c | 18 ++-
drivers/staging/r8188eu/core/rtw_mp_ioctl.c | 4 +-
drivers/staging/r8188eu/core/rtw_pwrctrl.c | 5 +-
drivers/staging/r8188eu/core/rtw_sreset.c | 9 +-
.../r8188eu/hal/Hal8188ERateAdaptive.c | 8 +-
drivers/staging/r8188eu/hal/HalPhyRf_8188e.c | 2 +-
drivers/staging/r8188eu/hal/odm_interface.c | 4 +-
.../staging/r8188eu/hal/rtl8188e_hal_init.c | 63 ++++++++--
drivers/staging/r8188eu/hal/rtl8188e_phycfg.c | 12 +-
drivers/staging/r8188eu/hal/rtl8188e_sreset.c | 14 ++-
drivers/staging/r8188eu/hal/usb_halinit.c | 119 +++++++++++++++---
drivers/staging/r8188eu/hal/usb_ops_linux.c | 19 ++-
.../staging/r8188eu/include/odm_interface.h | 2 +-
drivers/staging/r8188eu/include/rtw_io.h | 6 +-
drivers/staging/r8188eu/os_dep/ioctl_linux.c | 90 ++++++++-----
18 files changed, 354 insertions(+), 105 deletions(-)
diff --git a/drivers/staging/r8188eu/core/rtw_debug.c b/drivers/staging/r8188eu/core/rtw_debug.c
index a41675e101ac..c76feb44ecfa 100644
--- a/drivers/staging/r8188eu/core/rtw_debug.c
+++ b/drivers/staging/r8188eu/core/rtw_debug.c
@@ -99,7 +99,12 @@ int proc_get_read_reg(char *page, char **start,
proc_get_read_addr, (u16) tmp);
break;
case 4:
- len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n", proc_get_read_addr, rtw_read32(padapter, proc_get_read_addr));
+ error = rtw_read32(padapter, proc_get_read_addr, &tmp);
+ if (error)
+ return len;
+
+ len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n",
+ proc_get_read_addr, tmp);
break;
default:
len += snprintf(page + len, count - len, "error read length=%d\n", proc_get_read_len);
@@ -315,13 +320,20 @@ int proc_get_mac_reg_dump1(char *page, char **start,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1;
+ int error;
+ u32 tmp;
len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
for (i = 0x0; i < 0x300; i += 4) {
if (j % 4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+ error = rtw_read32(padapter, i, &tmp);
+ if (error)
+ return len;
+
+ len += snprintf(page + len, count - len, " 0x%08x ", tmp);
if ((j++) % 4 == 0)
len += snprintf(page + len, count - len, "\n");
}
@@ -338,13 +350,20 @@ int proc_get_mac_reg_dump2(char *page, char **start,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1;
+ int error;
+ u32 tmp;
len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
memset(page, 0, count);
for (i = 0x300; i < 0x600; i += 4) {
if (j % 4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+ error = rtw_read32(padapter, i, &tmp);
+ if (error)
+ return len;
+
+ len += snprintf(page + len, count - len, " 0x%08x ", tmp);
if ((j++) % 4 == 0)
len += snprintf(page + len, count - len, "\n");
}
@@ -361,13 +380,20 @@ int proc_get_mac_reg_dump3(char *page, char **start,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1;
+ int error;
+ u32 tmp;
len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
for (i = 0x600; i < 0x800; i += 4) {
if (j % 4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+ error = rtw_read32(padapter, i, &tmp);
+ if (error)
+ return error;
+
+ len += snprintf(page + len, count - len, " 0x%08x ", tmp);
if ((j++) % 4 == 0)
len += snprintf(page + len, count - len, "\n");
}
@@ -384,12 +410,19 @@ int proc_get_bb_reg_dump1(char *page, char **start,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1;
+ int error;
+ u32 tmp;
len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
for (i = 0x800; i < 0xB00; i += 4) {
if (j % 4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+ error = rtw_read32(padapter, i, &tmp);
+ if (error)
+ return len;
+
+ len += snprintf(page + len, count - len, " 0x%08x ", tmp);
if ((j++) % 4 == 0)
len += snprintf(page + len, count - len, "\n");
}
@@ -405,12 +438,19 @@ int proc_get_bb_reg_dump2(char *page, char **start,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1;
+ int error;
+ u32 tmp;
len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
for (i = 0xB00; i < 0xE00; i += 4) {
if (j % 4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+ error = rtw_read32(padapter, i, &tmp);
+ if (error)
+ return len;
+
+ len += snprintf(page + len, count - len, " 0x%08x ", tmp);
if ((j++) % 4 == 0)
len += snprintf(page + len, count - len, "\n");
}
@@ -426,12 +466,19 @@ int proc_get_bb_reg_dump3(char *page, char **start,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1;
+ int error;
+ u32 tmp;
len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
for (i = 0xE00; i < 0x1000; i += 4) {
if (j % 4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+ error = rtw_read32(padapter, i, &tmp);
+ if (error)
+ return len;
+
+ len += snprintf(page + len, count - len, " 0x%08x ", tmp);
if ((j++) % 4 == 0)
len += snprintf(page + len, count - len, "\n");
}
diff --git a/drivers/staging/r8188eu/core/rtw_efuse.c b/drivers/staging/r8188eu/core/rtw_efuse.c
index b471f6446f78..dfe60bc6a547 100644
--- a/drivers/staging/r8188eu/core/rtw_efuse.c
+++ b/drivers/staging/r8188eu/core/rtw_efuse.c
@@ -183,9 +183,15 @@ ReadEFuseByte(
/* Check bit 32 read-ready */
retry = 0;
- value32 = rtw_read32(Adapter, EFUSE_CTRL);
+ error = rtw_read32(Adapter, EFUSE_CTRL, &value32);
+ if (error)
+ return;
+
while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) {
- value32 = rtw_read32(Adapter, EFUSE_CTRL);
+ error = rtw_read32(Adapter, EFUSE_CTRL, &value32);
+ if (error)
+ return;
+
retry++;
}
@@ -194,7 +200,9 @@ ReadEFuseByte(
/* Designer says that there shall be some delay after ready bit is set, or the */
/* result will always stay on last data we read. */
udelay(50);
- value32 = rtw_read32(Adapter, EFUSE_CTRL);
+ error = rtw_read32(Adapter, EFUSE_CTRL, &value32);
+ if (error)
+ return;
*pbuf = (u8)(value32 & 0xff);
}
diff --git a/drivers/staging/r8188eu/core/rtw_io.c b/drivers/staging/r8188eu/core/rtw_io.c
index fd64893c778d..df4d8ac8aadc 100644
--- a/drivers/staging/r8188eu/core/rtw_io.c
+++ b/drivers/staging/r8188eu/core/rtw_io.c
@@ -56,18 +56,15 @@ int __must_check _rtw_read16(struct adapter *adapter, u32 addr, u16 *data)
return _read16(pintfhdl, addr, data);
}
-u32 _rtw_read32(struct adapter *adapter, u32 addr)
+int __must_check _rtw_read32(struct adapter *adapter, u32 addr, u32 *data)
{
- u32 r_val;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &pio_priv->intf;
- u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
+ int (*_read32)(struct intf_hdl *pintfhdl, u32 addr, u32 *data);
_read32 = pintfhdl->io_ops._read32;
- r_val = _read32(pintfhdl, addr);
-
- return r_val;
+ return _read32(pintfhdl, addr, data);
}
int _rtw_write8(struct adapter *adapter, u32 addr, u8 val)
diff --git a/drivers/staging/r8188eu/core/rtw_mp.c b/drivers/staging/r8188eu/core/rtw_mp.c
index 76f0bc399819..e990e81966af 100644
--- a/drivers/staging/r8188eu/core/rtw_mp.c
+++ b/drivers/staging/r8188eu/core/rtw_mp.c
@@ -765,12 +765,17 @@ static u32 GetPhyRxPktCounts(struct adapter *pAdapter, u32 selbit)
{
/* selection */
u32 phyrx_set = 0, count = 0;
+ int error;
phyrx_set = _RXERR_RPT_SEL(selbit & 0xF);
rtw_write32(pAdapter, REG_RXERR_RPT, phyrx_set);
/* Read packet count */
- count = rtw_read32(pAdapter, REG_RXERR_RPT) & RXERR_COUNTER_MASK;
+ error = rtw_read32(pAdapter, REG_RXERR_RPT, &count);
+ if (error)
+ return count;
+
+ count &= RXERR_COUNTER_MASK;
return count;
}
@@ -803,8 +808,12 @@ u32 GetPhyRxPktCRC32Error(struct adapter *pAdapter)
static u32 rtw_GetPSDData(struct adapter *pAdapter, u32 point)
{
int psd_val;
+ int error;
+
+ error = rtw_read32(pAdapter, 0x808, &psd_val);
+ if (error)
+ return 0;
- psd_val = rtw_read32(pAdapter, 0x808);
psd_val &= 0xFFBFFC00;
psd_val |= point;
@@ -814,7 +823,10 @@ static u32 rtw_GetPSDData(struct adapter *pAdapter, u32 point)
rtw_write32(pAdapter, 0x808, psd_val);
mdelay(1);
- psd_val = rtw_read32(pAdapter, 0x8B4);
+
+ error = rtw_read32(pAdapter, 0x8B4, &psd_val);
+ if (error)
+ return 0;
psd_val &= 0x0000FFFF;
diff --git a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
index c6f7636c2174..9eaef9c73516 100644
--- a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
+++ b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
@@ -659,7 +659,9 @@ int rtl8188eu_oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv)
break;
default:
width = 4;
- RegRWStruct->value = rtw_read32(Adapter, offset);
+ error = rtw_read32(Adapter, offset, &RegRWStruct->value);
+ if (error)
+ status = NDIS_STATUS_NOT_ACCEPTED;
break;
}
diff --git a/drivers/staging/r8188eu/core/rtw_pwrctrl.c b/drivers/staging/r8188eu/core/rtw_pwrctrl.c
index c3897b29121c..4335907acbc3 100644
--- a/drivers/staging/r8188eu/core/rtw_pwrctrl.c
+++ b/drivers/staging/r8188eu/core/rtw_pwrctrl.c
@@ -55,6 +55,7 @@ int ips_leave(struct adapter *padapter)
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
int result = _SUCCESS;
int keyid;
+ u32 tmp;
_enter_pwrlock(&pwrpriv->lock);
@@ -83,7 +84,9 @@ int ips_leave(struct adapter *padapter)
}
}
- DBG_88E("==> ips_leave.....LED(0x%08x)...\n", rtw_read32(padapter, 0x4c));
+ if (!rtw_read32(padapter, 0x4c, &tmp))
+ DBG_88E("==> ips_leave.....LED(0x%08x)...\n", tmp);
+
pwrpriv->bips_processing = false;
pwrpriv->bkeepfwalive = false;
diff --git a/drivers/staging/r8188eu/core/rtw_sreset.c b/drivers/staging/r8188eu/core/rtw_sreset.c
index 8e1bc62e74e5..ec5d070e1641 100644
--- a/drivers/staging/r8188eu/core/rtw_sreset.c
+++ b/drivers/staging/r8188eu/core/rtw_sreset.c
@@ -29,13 +29,18 @@ u8 sreset_get_wifi_status(struct adapter *padapter)
{
struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
struct sreset_priv *psrtpriv = &pHalData->srestpriv;
-
+ int error;
u8 status = WIFI_STATUS_SUCCESS;
u32 val32 = 0;
if (psrtpriv->silent_reset_inprogress)
return status;
- val32 = rtw_read32(padapter, REG_TXDMA_STATUS);
+ error = rtw_read32(padapter, REG_TXDMA_STATUS, &val32);
+ if (error) {
+ psrtpriv->Wifi_Error_Status = WIFI_MAC_TXDMA_ERROR;
+ return WIFI_MAC_TXDMA_ERROR;
+ }
+
if (val32 == 0xeaeaeaea) {
psrtpriv->Wifi_Error_Status = WIFI_IF_NOT_EXIST;
} else if (val32 != 0) {
diff --git a/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c b/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c
index d873672feb27..bd4580eba0a9 100644
--- a/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c
+++ b/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c
@@ -316,19 +316,19 @@ static int odm_ARFBRefresh_8188E(struct odm_dm_struct *dm_odm, struct odm_ra_inf
pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x0000000d;
break;
case 12:
- MaskFromReg = ODM_Read4Byte(dm_odm, REG_ARFR0);
+ ODM_Read4Byte(dm_odm, REG_ARFR0, &MaskFromReg);
pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;
break;
case 13:
- MaskFromReg = ODM_Read4Byte(dm_odm, REG_ARFR1);
+ ODM_Read4Byte(dm_odm, REG_ARFR1, &MaskFromReg);
pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;
break;
case 14:
- MaskFromReg = ODM_Read4Byte(dm_odm, REG_ARFR2);
+ ODM_Read4Byte(dm_odm, REG_ARFR2, &MaskFromReg);
pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;
break;
case 15:
- MaskFromReg = ODM_Read4Byte(dm_odm, REG_ARFR3);
+ ODM_Read4Byte(dm_odm, REG_ARFR3, &MaskFromReg);
pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;
break;
default:
diff --git a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
index 3545ad60dc00..725a18dc3979 100644
--- a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
+++ b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
@@ -667,7 +667,7 @@ static void _PHY_SaveMACRegisters(
if (error)
return;
}
- MACBackup[i] = ODM_Read4Byte(dm_odm, MACReg[i]);
+ ODM_Read4Byte(dm_odm, MACReg[i], MACBackup + i);
}
static void reload_adda_reg(struct adapter *adapt, u32 *ADDAReg, u32 *ADDABackup, u32 RegiesterNum)
diff --git a/drivers/staging/r8188eu/hal/odm_interface.c b/drivers/staging/r8188eu/hal/odm_interface.c
index 669d3e5eafb6..a47319dec231 100644
--- a/drivers/staging/r8188eu/hal/odm_interface.c
+++ b/drivers/staging/r8188eu/hal/odm_interface.c
@@ -16,10 +16,10 @@ int ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u16 *data)
return rtw_read16(Adapter, RegAddr, data);
}
-u32 ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr)
+int ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u32 *data)
{
struct adapter *Adapter = pDM_Odm->Adapter;
- return rtw_read32(Adapter, RegAddr);
+ return rtw_read32(Adapter, RegAddr, data);
}
void ODM_Write1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 Data)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
index 94e2828c328e..69649a381727 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
@@ -254,8 +254,16 @@ static void efuse_read_phymap_from_txpktbuf(
/* data from EEPROM needs to be in LE */
- lo32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L));
- hi32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H));
+ error = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L, &lo32);
+ if (error)
+ return;
+ lo32 = cpu_to_le32(lo32);
+
+
+ error = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H, &hi32);
+ if (error)
+ return;
+ hi32 = cpu_to_le32(hi32);
if (i == 0) {
/* Although lenc is only used in a debug statement,
@@ -375,6 +383,8 @@ void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len)
u32 addr, rstatus, loop = 0;
u16 data_cnts = (data_len / 8) + 1;
u8 *pbuf = vzalloc(data_len + 10);
+ int error;
+
DBG_88E("###### %s ######\n", __func__);
rtw_write8(Adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
@@ -384,12 +394,25 @@ void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len)
rtw_usleep_os(2);
loop = 0;
do {
- rstatus = (reg_140 = rtw_read32(Adapter, REG_PKTBUF_DBG_CTRL) & BIT(24));
+ error = rtw_read32(Adapter, REG_PKTBUF_DBG_CTRL, ®_140);
+ if (error)
+ return;
+
+ reg_140 &= BIT(24);
+ rstatus = reg_140;
if (rstatus) {
- fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_L);
+ error = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_L,
+ &fifo_data);
+ if (error)
+ return;
+
memcpy(pbuf + (addr * 8), &fifo_data, 4);
- fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_H);
+ error = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_H,
+ &fifo_data);
+ if (error)
+ return;
+
memcpy(pbuf + (addr * 8 + 4), &fifo_data, 4);
}
rtw_usleep_os(2);
@@ -557,10 +580,14 @@ static s32 _FWFreeToGo(struct adapter *padapter)
{
u32 counter = 0;
u32 value32;
+ int error;
/* polling CheckSum report */
do {
- value32 = rtw_read32(padapter, REG_MCUFWDL);
+ error = rtw_read32(padapter, REG_MCUFWDL, &value32);
+ if (error)
+ return _FAIL;
+
if (value32 & FWDL_ChkSum_rpt)
break;
} while (counter++ < POLLING_READY_TIMEOUT_COUNT);
@@ -571,7 +598,10 @@ static s32 _FWFreeToGo(struct adapter *padapter)
}
DBG_88E("%s: Checksum report OK! REG_MCUFWDL:0x%08x\n", __func__, value32);
- value32 = rtw_read32(padapter, REG_MCUFWDL);
+ error = rtw_read32(padapter, REG_MCUFWDL, &value32);
+ if (error)
+ return _FAIL;
+
value32 |= MCUFWDL_RDY;
value32 &= ~WINTINI_RDY;
rtw_write32(padapter, REG_MCUFWDL, value32);
@@ -581,8 +611,10 @@ static s32 _FWFreeToGo(struct adapter *padapter)
/* polling for FW ready */
counter = 0;
do {
- value32 = rtw_read32(padapter, REG_MCUFWDL);
- if (value32 & WINTINI_RDY) {
+ error = rtw_read32(padapter, REG_MCUFWDL, &value32);
+ if (error) {
+ return _FAIL;
+ } else if (value32 & WINTINI_RDY) {
DBG_88E("%s: Polling FW ready success!! REG_MCUFWDL:0x%08x\n", __func__, value32);
return _SUCCESS;
}
@@ -1765,12 +1797,16 @@ static int rtl8188e_Efuse_PgPacketWrite(struct adapter *pAdapter, u8 offset, u8
static struct HAL_VERSION ReadChipVersion8188E(struct adapter *padapter)
{
u32 value32;
- struct HAL_VERSION ChipVersion;
+ struct HAL_VERSION ChipVersion = {};
struct hal_data_8188e *pHalData;
+ int error;
pHalData = GET_HAL_DATA(padapter);
- value32 = rtw_read32(padapter, REG_SYS_CFG);
+ error = rtw_read32(padapter, REG_SYS_CFG, &value32);
+ if (error)
+ return ChipVersion;
+
ChipVersion.ICType = CHIP_8188E;
ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
@@ -1949,12 +1985,15 @@ static s32 _LLTWrite(struct adapter *padapter, u32 address, u32 data)
s32 count = 0;
u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
u16 LLTReg = REG_LLT_INIT;
+ int error;
rtw_write32(padapter, LLTReg, value);
/* polling */
do {
- value = rtw_read32(padapter, LLTReg);
+ error = rtw_read32(padapter, LLTReg, &value);
+ if (error)
+ return _FAIL;
if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
break;
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
index 3afb66195413..24b2afb62d68 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
@@ -75,8 +75,12 @@ rtl8188e_PHY_QueryBBReg(
)
{
u32 ReturnValue = 0, OriginalValue, BitShift;
+ int error;
+
+ error = rtw_read32(Adapter, RegAddr, &OriginalValue);
+ if (error)
+ return ReturnValue;
- OriginalValue = rtw_read32(Adapter, RegAddr);
BitShift = phy_CalculateBitShift(BitMask);
ReturnValue = (OriginalValue & BitMask) >> BitShift;
return ReturnValue;
@@ -103,9 +107,13 @@ rtl8188e_PHY_QueryBBReg(
void rtl8188e_PHY_SetBBReg(struct adapter *Adapter, u32 RegAddr, u32 BitMask, u32 Data)
{
u32 OriginalValue, BitShift;
+ int error;
if (BitMask != bMaskDWord) { /* if not "double word" write */
- OriginalValue = rtw_read32(Adapter, RegAddr);
+ error = rtw_read32(Adapter, RegAddr, &OriginalValue);
+ if (error)
+ return;
+
BitShift = phy_CalculateBitShift(BitMask);
Data = ((OriginalValue & (~BitMask)) | (Data << BitShift));
}
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_sreset.c b/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
index 39dacfb23570..a023a0669ffd 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
@@ -14,14 +14,16 @@ void rtl8188e_sreset_xmit_status_check(struct adapter *padapter)
{
struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
struct sreset_priv *psrtpriv = &pHalData->srestpriv;
-
+ int error;
unsigned long current_time;
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
unsigned int diff_time;
u32 txdma_status;
- txdma_status = rtw_read32(padapter, REG_TXDMA_STATUS);
- if (txdma_status != 0x00) {
+ error = rtw_read32(padapter, REG_TXDMA_STATUS, &txdma_status);
+ if (error) {
+ return;
+ } else if (txdma_status != 0x00) {
DBG_88E("%s REG_TXDMA_STATUS:0x%08x\n", __func__, txdma_status);
rtw_write32(padapter, REG_TXDMA_STATUS, txdma_status);
rtl8188e_silentreset_for_specific_platform(padapter);
@@ -51,8 +53,10 @@ void rtl8188e_sreset_linked_status_check(struct adapter *padapter)
u8 fw_status = 0;
int error;
- rx_dma_status = rtw_read32(padapter, REG_RXDMA_STATUS);
- if (rx_dma_status != 0x00) {
+ error = rtw_read32(padapter, REG_RXDMA_STATUS, &rx_dma_status);
+ if (error) {
+ return;
+ } else if (rx_dma_status != 0x00) {
DBG_88E("%s REG_RXDMA_STATUS:0x%08x\n", __func__, rx_dma_status);
rtw_write32(padapter, REG_RXDMA_STATUS, rx_dma_status);
}
diff --git a/drivers/staging/r8188eu/hal/usb_halinit.c b/drivers/staging/r8188eu/hal/usb_halinit.c
index 4ecccc6499aa..3826476e3396 100644
--- a/drivers/staging/r8188eu/hal/usb_halinit.c
+++ b/drivers/staging/r8188eu/hal/usb_halinit.c
@@ -338,8 +338,12 @@ static void _InitQueuePriority(struct adapter *Adapter)
static void _InitNetworkType(struct adapter *Adapter)
{
u32 value32;
+ int error;
+
+ error = rtw_read32(Adapter, REG_CR, &value32);
+ if (error)
+ return;
- value32 = rtw_read32(Adapter, REG_CR);
/* TODO: use the other function to set network type */
value32 = (value32 & ~MASK_NETTYPE) | _NETTYPE(NT_LINK_AP);
@@ -381,9 +385,13 @@ static void _InitAdaptiveCtrl(struct adapter *Adapter)
{
u16 value16;
u32 value32;
+ int error;
/* Response Rate Set */
- value32 = rtw_read32(Adapter, REG_RRSR);
+ error = rtw_read32(Adapter, REG_RRSR, &value32);
+ if (error)
+ return;
+
value32 &= ~RATE_BITMAP_ALL;
value32 |= RATE_RRSR_CCK_ONLY_1M;
rtw_write32(Adapter, REG_RRSR, value32);
@@ -482,12 +490,16 @@ static void usb_AggSettingTxUpdate(struct adapter *Adapter)
{
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
u32 value32;
+ int error;
if (Adapter->registrypriv.wifi_spec)
haldata->UsbTxAggMode = false;
if (haldata->UsbTxAggMode) {
- value32 = rtw_read32(Adapter, REG_TDECTRL);
+ error = rtw_read32(Adapter, REG_TDECTRL, &value32);
+ if (error)
+ return;
+
value32 = value32 & ~(BLK_DESC_NUM_MASK << BLK_DESC_NUM_SHIFT);
value32 |= ((haldata->UsbTxAggDescNum & BLK_DESC_NUM_MASK) << BLK_DESC_NUM_SHIFT);
@@ -671,12 +683,18 @@ enum {
static void _InitAntenna_Selection(struct adapter *Adapter)
{
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
+ u32 val32;
+ int error;
if (haldata->AntDivCfg == 0)
return;
DBG_88E("==> %s ....\n", __func__);
- rtw_write32(Adapter, REG_LEDCFG0, rtw_read32(Adapter, REG_LEDCFG0) | BIT(23));
+ error = rtw_read32(Adapter, REG_LEDCFG0, &val32);
+ if (error)
+ return;
+
+ rtw_write32(Adapter, REG_LEDCFG0, val32 | BIT(23));
PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, BIT(13), 0x01);
if (PHY_QueryBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, 0x300) == Antenna_A)
@@ -737,7 +755,7 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
u8 value8 = 0;
u16 value16;
u8 txpktbuf_bndy;
- u32 status = _SUCCESS;
+ u32 status = _SUCCESS, val32;
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv;
struct registry_priv *pregistrypriv = &Adapter->registrypriv;
@@ -1007,7 +1025,13 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
rtw_write8(Adapter, REG_USB_HRPWM, 0);
/* ack for xmit mgmt frames. */
- rtw_write32(Adapter, REG_FWHW_TXQ_CTRL, rtw_read32(Adapter, REG_FWHW_TXQ_CTRL) | BIT(12));
+ error = rtw_read32(Adapter, REG_FWHW_TXQ_CTRL, &val32);
+ if (error) {
+ status = _FAIL;
+ goto exit;
+ }
+
+ rtw_write32(Adapter, REG_FWHW_TXQ_CTRL, val32 | BIT(12));
exit:
HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_END);
@@ -1480,6 +1504,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
struct odm_dm_struct *podmpriv = &haldata->odmpriv;
int error;
u8 tmp;
+ u32 val32;
switch (variable) {
case HW_VAR_MEDIA_STATUS:
@@ -1598,11 +1623,17 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
break;
case HW_VAR_CHECK_BSSID:
if (*((u8 *)val)) {
- rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+ error = rtw_read32(Adapter, REG_RCR, &val32);
+ if (error)
+ return;
+
+ rtw_write32(Adapter, REG_RCR, val32 | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
} else {
u32 val32;
- val32 = rtw_read32(Adapter, REG_RCR);
+ error = rtw_read32(Adapter, REG_RCR, &val32);
+ if (error)
+ return;
val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
@@ -1627,7 +1658,11 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
case HW_VAR_MLME_SITESURVEY:
if (*((u8 *)val)) { /* under sitesurvey */
/* config RCR to receive different BSSID & not to receive data frame */
- u32 v = rtw_read32(Adapter, REG_RCR);
+ u32 v;
+
+ error = rtw_read32(Adapter, REG_RCR, &v);
+ if (error)
+ return;
v &= ~(RCR_CBSSID_BCN);
rtw_write32(Adapter, REG_RCR, v);
@@ -1661,14 +1696,27 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
}
if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
- rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN);
+ error = rtw_read32(Adapter, REG_RCR, &val32);
+ if (error)
+ return;
+
+ rtw_write32(Adapter, REG_RCR, val32 | RCR_CBSSID_BCN);
} else {
+ u32 v;
+
if (Adapter->in_cta_test) {
- u32 v = rtw_read32(Adapter, REG_RCR);
+ error = rtw_read32(Adapter, REG_RCR, &v);
+ if (error)
+ return;
+
v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* RCR_ADF */
rtw_write32(Adapter, REG_RCR, v);
} else {
- rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN);
+ error = rtw_read32(Adapter, REG_RCR, &v);
+ if (error)
+ return;
+
+ rtw_write32(Adapter, REG_RCR, v | RCR_CBSSID_BCN);
}
}
}
@@ -1679,17 +1727,26 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
u8 type = *((u8 *)val);
u8 tmp;
struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
+ u32 v;
if (type == 0) { /* prepare to join */
/* enable to rx data frame.Accept all data frame */
rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
if (Adapter->in_cta_test) {
- u32 v = rtw_read32(Adapter, REG_RCR);
+ error = rtw_read32(Adapter, REG_RCR, &v);
+ if (error)
+ return;
+
v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* RCR_ADF */
rtw_write32(Adapter, REG_RCR, v);
} else {
- rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+ error = rtw_read32(Adapter, REG_RCR, &v);
+ if (error)
+ return;
+
+ rtw_write32(Adapter, REG_RCR,
+ v | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
}
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
@@ -2002,6 +2059,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
{
struct pwrctrl_priv *pwrpriv = &Adapter->pwrctrlpriv;
u8 trycnt = 100;
+ u32 v;
/* pause tx */
rtw_write8(Adapter, REG_TXPAUSE, 0xff);
@@ -2013,9 +2071,18 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
if (!pwrpriv->bkeepfwalive) {
/* RX DMA stop */
- rtw_write32(Adapter, REG_RXPKT_NUM, (rtw_read32(Adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
+
+ error = rtw_read32(Adapter, REG_RXPKT_NUM, &v);
+ if (error)
+ return;
+
+ rtw_write32(Adapter, REG_RXPKT_NUM, (v | RW_RELEASE_EN));
do {
- if (!(rtw_read32(Adapter, REG_RXPKT_NUM) & RXDMA_IDLE))
+ error = rtw_read32(Adapter, REG_RXPKT_NUM, &v);
+ if (error)
+ return;
+
+ if (!(v & RXDMA_IDLE))
break;
} while (trycnt--);
if (trycnt == 0)
@@ -2066,6 +2133,7 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
struct odm_dm_struct *podmpriv = &haldata->odmpriv;
int error;
u8 tmp;
+ u32 val32;
switch (variable) {
case HW_VAR_BASIC_RATE:
@@ -2097,7 +2165,13 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
val[0] = true;
} else {
u32 valRCR;
- valRCR = rtw_read32(Adapter, REG_RCR);
+
+ error = rtw_read32(Adapter, REG_RCR, &valRCR);
+ if (error) {
+ *val = false;
+ return;
+ }
+
valRCR &= 0x00070000;
if (valRCR)
val[0] = false;
@@ -2116,7 +2190,11 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
*val = haldata->bMacPwrCtrlOn;
break;
case HW_VAR_CHK_HI_QUEUE_EMPTY:
- *val = ((rtw_read32(Adapter, REG_HGQ_INFORMATION) & 0x0000ff00) == 0) ? true : false;
+ error = rtw_read32(Adapter, REG_HGQ_INFORMATION, &val32);
+ if (error || val32 & 0x0000ff00)
+ *val = false;
+ else
+ *val = true;
break;
default:
break;
@@ -2374,7 +2452,10 @@ static void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
rtw_write8(adapt, REG_SLOT, 0x09);
- value32 = rtw_read32(adapt, REG_TCR);
+ error = rtw_read32(adapt, REG_TCR, &value32);
+ if (error)
+ return;
+
value32 &= ~TSFRST;
rtw_write32(adapt, REG_TCR, value32);
diff --git a/drivers/staging/r8188eu/hal/usb_ops_linux.c b/drivers/staging/r8188eu/hal/usb_ops_linux.c
index 58e852555f54..bcb589777b51 100644
--- a/drivers/staging/r8188eu/hal/usb_ops_linux.c
+++ b/drivers/staging/r8188eu/hal/usb_ops_linux.c
@@ -152,21 +152,32 @@ static int usb_read16(struct intf_hdl *pintfhdl, u32 addr, u16 *data)
return res;
}
-static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
+static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
{
u8 requesttype;
u16 wvalue;
u16 len;
- __le32 data;
+ int res;
+ __le32 tmp;
+
+ if (WARN_ON(unlikely(!data)))
+ return -EINVAL;
requesttype = 0x01;/* read_in */
wvalue = (u16)(addr & 0x0000ffff);
len = 4;
- usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
+ res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
+ if (res < 0) {
+ dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
+ } else {
+ /* Noone cares about positive return value */
+ *data = le32_to_cpu(tmp);
+ res = 0;
+ }
- return le32_to_cpu(data);
+ return res;
}
static int usb_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val)
diff --git a/drivers/staging/r8188eu/include/odm_interface.h b/drivers/staging/r8188eu/include/odm_interface.h
index 2455dae6eebb..bbb1045c9e7d 100644
--- a/drivers/staging/r8188eu/include/odm_interface.h
+++ b/drivers/staging/r8188eu/include/odm_interface.h
@@ -64,7 +64,7 @@ int ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 *data);
int ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u16 *data);
-u32 ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr);
+int ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u32 *data);
void ODM_Write1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 Data);
diff --git a/drivers/staging/r8188eu/include/rtw_io.h b/drivers/staging/r8188eu/include/rtw_io.h
index c44554c848cf..501168457518 100644
--- a/drivers/staging/r8188eu/include/rtw_io.h
+++ b/drivers/staging/r8188eu/include/rtw_io.h
@@ -87,7 +87,7 @@ struct io_queue;
struct _io_ops {
int (*_read8)(struct intf_hdl *pintfhdl, u32 addr, u8 *data);
int (*_read16)(struct intf_hdl *pintfhdl, u32 addr, u16 *data);
- u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
+ int (*_read32)(struct intf_hdl *pintfhdl, u32 addr, u32 *data);
int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
@@ -250,7 +250,7 @@ void _rtw_attrib_write(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data);
int __must_check _rtw_read16(struct adapter *adapter, u32 addr, u16 *data);
-u32 _rtw_read32(struct adapter *adapter, u32 addr);
+int __must_check _rtw_read32(struct adapter *adapter, u32 addr, u32 *data);
void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
void _rtw_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
void _rtw_read_port_cancel(struct adapter *adapter);
@@ -272,7 +272,7 @@ void _rtw_write_port_cancel(struct adapter *adapter);
#define rtw_read8(adapter, addr, data) _rtw_read8((adapter), (addr), (data))
#define rtw_read16(adapter, addr, data) _rtw_read16((adapter), (addr), (data))
-#define rtw_read32(adapter, addr) _rtw_read32((adapter), (addr))
+#define rtw_read32(adapter, addr, data) _rtw_read32((adapter), (addr), (data))
#define rtw_read_mem(adapter, addr, cnt, mem) \
_rtw_read_mem((adapter), (addr), (cnt), (mem))
#define rtw_read_port(adapter, addr, cnt, mem) \
diff --git a/drivers/staging/r8188eu/os_dep/ioctl_linux.c b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
index 79f0fbaa841e..65b240d6c544 100644
--- a/drivers/staging/r8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
@@ -2108,7 +2108,10 @@ static int rtw_wx_read32(struct net_device *dev,
sprintf(extra, "0x%04X", data32);
break;
case 4:
- data32 = rtw_read32(padapter, addr);
+ error = rtw_read32(padapter, addr, &data32);
+ if (error)
+ return error;
+
sprintf(extra, "0x%08X", data32);
break;
default:
@@ -2278,7 +2281,7 @@ static void rtw_dbg_mode_hdl(struct adapter *padapter, u32 id, u8 *pdata, u32 le
(u16 *) &RegRWStruct->value);
break;
case 4:
- RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset);
+ error = rtw_read32(padapter, RegRWStruct->offset, &RegRWStruct->value);
break;
default:
break;
@@ -3818,6 +3821,8 @@ static int rtw_cta_test_start(struct net_device *dev,
{
int ret = 0;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ int error;
+
DBG_88E("%s %s\n", __func__, extra);
if (!strcmp(extra, "1"))
padapter->in_cta_test = 1;
@@ -3825,12 +3830,22 @@ static int rtw_cta_test_start(struct net_device *dev,
padapter->in_cta_test = 0;
if (padapter->in_cta_test) {
- u32 v = rtw_read32(padapter, REG_RCR);
+ u32 v;
+
+ error = rtw_read32(padapter, REG_RCR, &v);
+ if (error)
+ return error;
+
v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* RCR_ADF */
rtw_write32(padapter, REG_RCR, v);
DBG_88E("enable RCR_ADF\n");
} else {
- u32 v = rtw_read32(padapter, REG_RCR);
+ u32 v;
+
+ error = rtw_read32(padapter, REG_RCR, &v);
+ if (error)
+ return error;
+
v |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;/* RCR_ADF */
rtw_write32(padapter, REG_RCR, v);
DBG_88E("disable RCR_ADF\n");
@@ -3900,18 +3915,23 @@ static int rtw_rereg_nd_name(struct net_device *dev,
static void mac_reg_dump(struct adapter *padapter)
{
int i, j = 1;
+
pr_info("\n ======= MAC REG =======\n");
for (i = 0x0; i < 0x300; i += 4) {
if (j % 4 == 1)
pr_info("0x%02x", i);
- pr_info(" 0x%08x ", rtw_read32(padapter, i));
+
+ DBG_88E_REG32(" 0x%08x ", padapter, i);
+
if ((j++) % 4 == 0)
pr_info("\n");
}
for (i = 0x400; i < 0x800; i += 4) {
if (j % 4 == 1)
pr_info("0x%02x", i);
- pr_info(" 0x%08x ", rtw_read32(padapter, i));
+
+ DBG_88E_REG32(" 0x%08x ", padapter, i);
+
if ((j++) % 4 == 0)
pr_info("\n");
}
@@ -3920,12 +3940,14 @@ static void mac_reg_dump(struct adapter *padapter)
static void bb_reg_dump(struct adapter *padapter)
{
int i, j = 1;
+
pr_info("\n ======= BB REG =======\n");
for (i = 0x800; i < 0x1000; i += 4) {
if (j % 4 == 1)
pr_info("0x%02x", i);
- pr_info(" 0x%08x ", rtw_read32(padapter, i));
+ DBG_88E_REG32(" 0x%08x ", padapter, i);
+
if ((j++) % 4 == 0)
pr_info("\n");
}
@@ -3998,7 +4020,8 @@ static int rtw_dbg_port(struct net_device *dev,
DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, (u16) tmp);
break;
case 4:
- DBG_88E("rtw_read32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
+ if (!rtw_read32(padapter, arg, &val32))
+ DBG_88E("rtw_read32(0x%x) = 0x%08x\n", arg, val32);
break;
}
break;
@@ -4020,7 +4043,9 @@ static int rtw_dbg_port(struct net_device *dev,
break;
case 4:
rtw_write32(padapter, arg, extra_arg);
- DBG_88E("rtw_write32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
+
+ if (!rtw_read32(padapter, arg, &val32))
+ DBG_88E("rtw_write32(0x%x) = 0x%08x\n", arg, val32);
break;
}
break;
@@ -4178,7 +4203,10 @@ static int rtw_dbg_port(struct net_device *dev,
if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
ret = -EPERM;
- final = rtw_read32(padapter, reg);
+ error = rtw_read32(padapter, reg, &final);
+ if (error)
+ break;
+
if (start_value + write_num - 1 == final)
DBG_88E("continuous IOL_CMD_WD_REG to 0x%x %u times Success, start:%u, final:%u\n",
reg, write_num, start_value, final);
@@ -4460,30 +4488,30 @@ static int rtw_dbg_port(struct net_device *dev,
DBG_88E_REG8("rd(0xc58) = 0x%x\n", padapter, 0xc58);
break;
case 0xff:
- DBG_88E("dbg(0x210) = 0x%x\n", rtw_read32(padapter, 0x210));
- DBG_88E("dbg(0x608) = 0x%x\n", rtw_read32(padapter, 0x608));
- DBG_88E("dbg(0x280) = 0x%x\n", rtw_read32(padapter, 0x280));
- DBG_88E("dbg(0x284) = 0x%x\n", rtw_read32(padapter, 0x284));
- DBG_88E("dbg(0x288) = 0x%x\n", rtw_read32(padapter, 0x288));
+ DBG_88E_REG32("dbg(0x210) = 0x%x\n", padapter, 0x210);
+ DBG_88E_REG32("dbg(0x608) = 0x%x\n", padapter, 0x608);
+ DBG_88E_REG32("dbg(0x280) = 0x%x\n", padapter, 0x280);
+ DBG_88E_REG32("dbg(0x284) = 0x%x\n", padapter, 0x284);
+ DBG_88E_REG32("dbg(0x288) = 0x%x\n", padapter, 0x288);
- DBG_88E("dbg(0x664) = 0x%x\n", rtw_read32(padapter, 0x664));
+ DBG_88E_REG32("dbg(0x664) = 0x%x\n", padapter, 0x664);
DBG_88E("\n");
- DBG_88E("dbg(0x430) = 0x%x\n", rtw_read32(padapter, 0x430));
- DBG_88E("dbg(0x438) = 0x%x\n", rtw_read32(padapter, 0x438));
+ DBG_88E_REG32("dbg(0x430) = 0x%x\n", padapter, 0x430);
+ DBG_88E_REG32("dbg(0x438) = 0x%x\n", padapter, 0x438);
- DBG_88E("dbg(0x440) = 0x%x\n", rtw_read32(padapter, 0x440));
+ DBG_88E_REG32("dbg(0x440) = 0x%x\n", padapter, 0x440);
- DBG_88E("dbg(0x458) = 0x%x\n", rtw_read32(padapter, 0x458));
+ DBG_88E_REG32("dbg(0x458) = 0x%x\n", padapter, 0x458);
- DBG_88E("dbg(0x484) = 0x%x\n", rtw_read32(padapter, 0x484));
- DBG_88E("dbg(0x488) = 0x%x\n", rtw_read32(padapter, 0x488));
+ DBG_88E_REG32("dbg(0x484) = 0x%x\n", padapter, 0x484);
+ DBG_88E_REG32("dbg(0x488) = 0x%x\n", padapter, 0x488);
- DBG_88E("dbg(0x444) = 0x%x\n", rtw_read32(padapter, 0x444));
- DBG_88E("dbg(0x448) = 0x%x\n", rtw_read32(padapter, 0x448));
- DBG_88E("dbg(0x44c) = 0x%x\n", rtw_read32(padapter, 0x44c));
- DBG_88E("dbg(0x450) = 0x%x\n", rtw_read32(padapter, 0x450));
+ DBG_88E_REG32("dbg(0x444) = 0x%x\n", padapter, 0x444);
+ DBG_88E_REG32("dbg(0x448) = 0x%x\n", padapter, 0x448);
+ DBG_88E_REG32("dbg(0x44c) = 0x%x\n", padapter, 0x44c);
+ DBG_88E_REG32("dbg(0x450) = 0x%x\n", padapter, 0x450);
break;
}
break;
@@ -5434,7 +5462,11 @@ static int rtw_mp_read_reg(struct net_device *dev,
break;
case 'd':
/* 4 bytes */
- sprintf(data, "%08x", rtw_read32(padapter, addr));
+ error = rtw_read32(padapter, addr, &val32);
+ if (error)
+ return error;
+
+ sprintf(data, "%08x", val32);
/* add read data format blank */
for (i = 0; i <= strlen(data); i++) {
if (i % 2 == 0) {
@@ -6154,14 +6186,14 @@ static int rtw_mp_dump(struct net_device *dev,
for (i = 0x0; i < 0x300; i += 4) {
if (j % 4 == 1)
DBG_88E("0x%02x", i);
- DBG_88E(" 0x%08x ", rtw_read32(padapter, i));
+ DBG_88E_REG32(" 0x%08x ", padapter, i);
if ((j++) % 4 == 0)
DBG_88E("\n");
}
for (i = 0x400; i < 0x1000; i += 4) {
if (j % 4 == 1)
DBG_88E("0x%02x", i);
- DBG_88E(" 0x%08x ", rtw_read32(padapter, i));
+ DBG_88E_REG32(" 0x%08x ", padapter, i);
if ((j++) % 4 == 0)
DBG_88E("\n");
}
--
2.32.0
On Sun, 22 Aug 2021 at 14:21, Fabio M. De Francesco
<[email protected]> wrote:
>
> On Sunday, August 22, 2021 2:39:34 PM CEST Greg KH wrote:
> > On Sun, Aug 22, 2021 at 03:10:56PM +0300, Pavel Skripkin wrote:
> > > On 8/22/21 1:59 PM, Fabio M. De Francesco wrote:
> > > > On Sunday, August 22, 2021 12:09:29 PM CEST Pavel Skripkin wrote:
> [...]
> > > > So, it's up to the callers to test if (!_rtw_read*()) and then act
> > > > accordingly. If they get 0 they should know how to handle the errors.
> > >
> > > Yes, but _rtw_read*() == 0 indicates 2 states:
> > > 1. Error on transfer side
> > > 2. Actual register value is 0
> >
> > That's not a good design, it should be fixed. Note there is the new
> > usb_control_msg_recv() function which should probably be used instead
> > here, to prevent this problem from happening.
>
> I think that no functions should return 0 for signaling FAILURE. If I'm not
> wrong, the kernel quite always prefers to return 0 on SUCCESS and <0 on
> FAILURE. Why don't you just fix this?
>
> > > > In summation. if anything should be changed, it is the code of the
> callers of
> > > > _rtw_read*() if you find out they they don't properly handle the
> returning
> > > > values of this function. You should find every place where _rtw_read*()
> are
> > > > called and figure out if the returns are properly checked and handled;
> if not,
> > > > make some change only there.
> > > >
> > > > Larry, Philip, where are you? Am I missing something?
> >
> > Relax, there is no need to get jumpy, people do not have to respond
> > instantly to emails here. Especially when it is not their job to do so.
>
> I should have placed a big smile at the end of the phrase. I was just kidding
> while trying to get their attention. I know there is no hurry and that no one
> has any obligation of this kind. Again, just kidding :)
>
> Thanks,
>
> Fabio
>
> > greg k-h
>
>
>
>
Dear Fabio,
I can't speak for anyone else, but I will reply to as many e-mails as
I'm able - there is no need to try and get my attention, you shall
have it by default, as and when I am able to give it :-)
As V2 has been sent out by Pavel, I will try and take a look soon.
Regards,
Phil
On 8/22/21 5:35 PM, Pavel Skripkin wrote:
> Hi, Greg, Larry and Phillip!
>
> I noticed, that new staging driver was added like 3 weeks ago and I decided
> to look at the code, because drivers in staging directory are always buggy.
>
> The first thing I noticed is *no one* was checking read operations result, but
> it can fail and driver may start writing random stack values into registers. It
> can cause driver misbehavior or device misbehavior.
>
> To avoid this type of bugs, i've changed rtw_read* API. Now all rtw_read
> funtions return an error, when something went wrong with usb transfer.
>
> It helps callers to break/return earlier and don't write random values to
> registers or to rely on random values.
>
> Why is this pacth series RFC?
> 1. I don't have this device and I cannot test these changes.
> 2. I don't know how to handle errors in each particular case. For now, function
> just returns or returns an error. That's all. I hope, driver maintainers will
> help with these bits.
> 3. I guess, I handled not all uninit value bugs here. I hope, I fixed
> at least half of them
>
>
> v1 -> v2:
> 1. Make rtw_read*() return an error instead of initializing pointer to error
> 2. Split one huge patch to smaller ones for each rtw_read{8,16,32} function
> changes
> 3. Add new macro for printing register values (It helps to not copy-paste error
> handling)
> 4. Removed {read,write}_macreg (Suggested by Phillip)
> 5. Rebased on top of staging-next
> 6. Cleaned checkpatch errors and warnings
>
> Only build-tested, since I don't have device with r8118eu chip
>
BTW, can you recommend any devices with this chip except for ASUS
USB-N10 Nano? I didn't find any of them with delivery/reasonable
delivery price to Russia.
I want to help with testing and moving this driver out of staging
directory :)
With regards,
Pavel Skripkin
On Sunday, August 22, 2021 3:31:31 PM CEST Pavel Skripkin wrote:
> On 8/22/21 4:21 PM, Fabio M. De Francesco wrote:
> > On Sunday, August 22, 2021 2:39:34 PM CEST Greg KH wrote:
> >> On Sun, Aug 22, 2021 at 03:10:56PM +0300, Pavel Skripkin wrote:
> >> > On 8/22/21 1:59 PM, Fabio M. De Francesco wrote:
> >> > > On Sunday, August 22, 2021 12:09:29 PM CEST Pavel Skripkin wrote:
> > [...]
> >> > > So, it's up to the callers to test if (!_rtw_read*()) and then act
> >> > > accordingly. If they get 0 they should know how to handle the errors.
> >> >
> >> > Yes, but _rtw_read*() == 0 indicates 2 states:
> >> > 1. Error on transfer side
> >> > 2. Actual register value is 0
> >>
> >> That's not a good design, it should be fixed. Note there is the new
> >> usb_control_msg_recv() function which should probably be used instead
> >> here, to prevent this problem from happening.
> >
> > I think that no functions should return 0 for signaling FAILURE. If I'm not
> > wrong, the kernel quite always prefers to return 0 on SUCCESS and <0 on
> > FAILURE. Why don't you just fix this?
> >
> That's what I've done in v2. All rtw_read* family will have following
> prototype in v2:
>
> int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data);
>
> Was it your idea, or you were talking about different approach?
>
> With regards,
> Pavel Skripkin
Pavel,
Yes, it is correct.
However, after that I had time to look at the calls chain and understand what
each function does and then I saw that my initial proposal should be made
along with another one...
The calls chain is:
(1) _rtw_read8() <--- (returns the data read from next function in chain)
(no errors returned, see possible fix in next function)
(2) usb_read8() <--- (returns the data read from next function in chain)
(_data_may_be_unitialised_, no errors returned)
(possible fix: from "u8 data"; to "char data = -1;")
(3) usbctrl_vendorreq() <---- (returns data read from next function in chain)
(data is always a valid pointer saved to third argument)
(if it fails, the third argument is unchanged because it
still has the address of the "data" argument given by the caller)
(4) usb_control_msg() <---- (it always returns how many bytes read or valid error codes)
(it _never_ returns 0: either positive or negative values)
I have not yet looked at the usb_control_msg_recv() which Greg talked about.
To summarize: in function (2) "u8 data" should become "char data = -1;".
Regards,
Fabio
P.S.: I was about to send this message while I see that you sent v2. Since I've already have
this response to your question I send it and soon after I'm going to read your v2 patches.
On 8/22/21 5:30 PM, Pavel Skripkin wrote:
> BTW, can you recommend any devices with this chip except for ASUS
> USB-N10 Nano? I didn't find any of them with delivery/reasonable
> delivery price to Russia.
>
> I want to help with testing and moving this driver out of staging
> directory :)
Hi Pavel,
My one is a TP-LINK WN725N (not sure, but I guess v2).
You could also have a look at the device table in os_dep/usb_intf.c
Regards,
Michael
On 8/22/21 7:03 PM, Fabio M. De Francesco wrote:
> On Sunday, August 22, 2021 3:31:31 PM CEST Pavel Skripkin wrote:
>> On 8/22/21 4:21 PM, Fabio M. De Francesco wrote:
>> > On Sunday, August 22, 2021 2:39:34 PM CEST Greg KH wrote:
>> >> On Sun, Aug 22, 2021 at 03:10:56PM +0300, Pavel Skripkin wrote:
>> >> > On 8/22/21 1:59 PM, Fabio M. De Francesco wrote:
>> >> > > On Sunday, August 22, 2021 12:09:29 PM CEST Pavel Skripkin wrote:
>> > [...]
>> >> > > So, it's up to the callers to test if (!_rtw_read*()) and then act
>> >> > > accordingly. If they get 0 they should know how to handle the errors.
>> >> >
>> >> > Yes, but _rtw_read*() == 0 indicates 2 states:
>> >> > 1. Error on transfer side
>> >> > 2. Actual register value is 0
>> >>
>> >> That's not a good design, it should be fixed. Note there is the new
>> >> usb_control_msg_recv() function which should probably be used instead
>> >> here, to prevent this problem from happening.
>> >
>> > I think that no functions should return 0 for signaling FAILURE. If I'm not
>> > wrong, the kernel quite always prefers to return 0 on SUCCESS and <0 on
>> > FAILURE. Why don't you just fix this?
>> >
>> That's what I've done in v2. All rtw_read* family will have following
>> prototype in v2:
>>
>> int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data);
>>
(*)
>> Was it your idea, or you were talking about different approach?
>>
>> With regards,
>> Pavel Skripkin
>
> Pavel,
>
> Yes, it is correct.
>
> However, after that I had time to look at the calls chain and understand what
> each function does and then I saw that my initial proposal should be made
> along with another one...
>
> The calls chain is:
>
> (1) _rtw_read8() <--- (returns the data read from next function in chain)
> (no errors returned, see possible fix in next function)
> (2) usb_read8() <--- (returns the data read from next function in chain)
> (_data_may_be_unitialised_, no errors returned)
> (possible fix: from "u8 data"; to "char data = -1;")
Anyway char will be cast to u8 and -1 will become 0xff. 0xff is still
valid register value, I guess.
> (3) usbctrl_vendorreq() <---- (returns data read from next function in chain)
> (data is always a valid pointer saved to third argument)
> (if it fails, the third argument is unchanged because it
> still has the address of the "data" argument given by the caller) > (4) usb_control_msg() <---- (it always returns how
many bytes read or valid error codes)
> (it _never_ returns 0: either positive or negative values)
>
> I have not yet looked at the usb_control_msg_recv() which Greg talked about.
>
> To summarize: in function (2) "u8 data" should become "char data = -1;".
>
So, anyway caller _should_ somehow receive an error from
usb_control_msg(). We can just change rtw_read{8,16,32} return values
from u{8,16,32} to int32, but anyway it will require all changes, that
I've done in this series, but in slightly different form. I.e temp int32
variable + error checking + casting int to u{8,16,32}.
Doesn't it make sense to just switch to more standard prototype (*)? All
other drivers use this prototype for their private reading functions.
With regards,
Pavel Skripkin
On 8/22/21 7:05 PM, Michael Straube wrote:
> Hi Pavel,
>
> My one is a TP-LINK WN725N (not sure, but I guess v2).
Wow! I found this one in my city, thank you!
> You could also have a look at the device table in os_dep/usb_intf.c
>
Yep, but I wanted to hear from driver reviewers/maintainers about what
they use to test. I guess, some devices could be broken or not unwieldy
to use. Thank you for recommendation, will buy one in few days :)
With regards,
Pavel Skripkin
On 8/22/21 8:36 PM, Fabio M. De Francesco wrote:
> On Sunday, August 22, 2021 4:35:05 PM CEST Pavel Skripkin wrote:
>> Hi, Greg, Larry and Phillip!
>>
>> I noticed, that new staging driver was added like 3 weeks ago and I decided
>> to look at the code, because drivers in staging directory are always buggy.
>>
>> The first thing I noticed is *no one* was checking read operations result, but
>> it can fail and driver may start writing random stack values into registers. It
>> can cause driver misbehavior or device misbehavior.
>>
>> To avoid this type of bugs, I've changed rtw_read* API. Now all rtw_read
>> funtions return an error, when something went wrong with usb transfer.
>>
>> It helps callers to break/return earlier and don't write random values to
>> registers or to rely on random values.
>>
>> Why is this pacth series RFC?
>> 1. I don't have this device and I cannot test these changes.
>> 2. I don't know how to handle errors in each particular case. For now, function
>> just returns or returns an error. That's all. I hope, driver maintainers will
>> help with these bits.
>> 3. I guess, I handled not all uninit value bugs here. I hope, I fixed
>> at least half of them
>>
>> v1 -> v2:
>> 1. Make rtw_read*() return an error instead of initializing pointer to error
>> 2. Split one huge patch to smaller ones for each rtw_read{8,16,32} function
>> changes
>> 3. Add new macro for printing register values (It helps to not copy-paste error
>> handling)
>> 4. Removed {read,write}_macreg (Suggested by Phillip)
>> 5. Rebased on top of staging-next
>> 6. Cleaned checkpatch errors and warnings
>>
>> Only build-tested, since I don't have device with r8118eu chip
>>
>> Pavel Skripkin (6):
>> staging: r8188eu: remove {read,write}_macreg
>> staging: r8188eu: add helper macro for printing registers
>> staging: r8188eu: add error handling of rtw_read8
>> staging: r8188eu: add error handling of rtw_read16
>> staging: r8188eu: add error handling of rtw_read32
>> staging: r8188eu: make ReadEFuse return an int
>
> Hi Pavel,
>
> I've just read your v2 of the series. I had no time to read each and every line,
> however, I suppose that I saw enough to say that I think they are a huge
> improvement over v1. I really like your patches and if I were you, I'd drop
> that RFC tag.
>
Thank you, Fabio! I appreciate it :)
With regards,
Pavel Skripkin
On Sunday, August 22, 2021 4:35:05 PM CEST Pavel Skripkin wrote:
> Hi, Greg, Larry and Phillip!
>
> I noticed, that new staging driver was added like 3 weeks ago and I decided
> to look at the code, because drivers in staging directory are always buggy.
>
> The first thing I noticed is *no one* was checking read operations result, but
> it can fail and driver may start writing random stack values into registers. It
> can cause driver misbehavior or device misbehavior.
>
> To avoid this type of bugs, I've changed rtw_read* API. Now all rtw_read
> funtions return an error, when something went wrong with usb transfer.
>
> It helps callers to break/return earlier and don't write random values to
> registers or to rely on random values.
>
> Why is this pacth series RFC?
> 1. I don't have this device and I cannot test these changes.
> 2. I don't know how to handle errors in each particular case. For now, function
> just returns or returns an error. That's all. I hope, driver maintainers will
> help with these bits.
> 3. I guess, I handled not all uninit value bugs here. I hope, I fixed
> at least half of them
>
> v1 -> v2:
> 1. Make rtw_read*() return an error instead of initializing pointer to error
> 2. Split one huge patch to smaller ones for each rtw_read{8,16,32} function
> changes
> 3. Add new macro for printing register values (It helps to not copy-paste error
> handling)
> 4. Removed {read,write}_macreg (Suggested by Phillip)
> 5. Rebased on top of staging-next
> 6. Cleaned checkpatch errors and warnings
>
> Only build-tested, since I don't have device with r8118eu chip
>
> Pavel Skripkin (6):
> staging: r8188eu: remove {read,write}_macreg
> staging: r8188eu: add helper macro for printing registers
> staging: r8188eu: add error handling of rtw_read8
> staging: r8188eu: add error handling of rtw_read16
> staging: r8188eu: add error handling of rtw_read32
> staging: r8188eu: make ReadEFuse return an int
Hi Pavel,
I've just read your v2 of the series. I had no time to read each and every line,
however, I suppose that I saw enough to say that I think they are a huge
improvement over v1. I really like your patches and if I were you, I'd drop
that RFC tag.
Thanks,
Fabio
v1 design.
not needed because
On Sunday, August 22, 2021 7:38:11 PM CEST Pavel Skripkin wrote:
> On 8/22/21 8:36 PM, Fabio M. De Francesco wrote:
> > On Sunday, August 22, 2021 4:35:05 PM CEST Pavel Skripkin wrote:
> >> Hi, Greg, Larry and Phillip!
> >>
> >> I noticed, that new staging driver was added like 3 weeks ago and I decided
> >> to look at the code, because drivers in staging directory are always buggy.
> >>
> >> The first thing I noticed is *no one* was checking read operations result, but
> >> it can fail and driver may start writing random stack values into registers. It
> >> can cause driver misbehavior or device misbehavior.
> >>
> >> To avoid this type of bugs, I've changed rtw_read* API. Now all rtw_read
> >> funtions return an error, when something went wrong with usb transfer.
> >>
> >> It helps callers to break/return earlier and don't write random values to
> >> registers or to rely on random values.
> >>
> >> Why is this pacth series RFC?
> >> 1. I don't have this device and I cannot test these changes.
> >> 2. I don't know how to handle errors in each particular case. For now, function
> >> just returns or returns an error. That's all. I hope, driver maintainers will
> >> help with these bits.
> >> 3. I guess, I handled not all uninit value bugs here. I hope, I fixed
> >> at least half of them
> >>
> >> v1 -> v2:
> >> 1. Make rtw_read*() return an error instead of initializing pointer to error
> >> 2. Split one huge patch to smaller ones for each rtw_read{8,16,32} function
> >> changes
> >> 3. Add new macro for printing register values (It helps to not copy-paste error
> >> handling)
> >> 4. Removed {read,write}_macreg (Suggested by Phillip)
> >> 5. Rebased on top of staging-next
> >> 6. Cleaned checkpatch errors and warnings
> >>
> >> Only build-tested, since I don't have device with r8118eu chip
> >>
> >> Pavel Skripkin (6):
> >> staging: r8188eu: remove {read,write}_macreg
> >> staging: r8188eu: add helper macro for printing registers
> >> staging: r8188eu: add error handling of rtw_read8
> >> staging: r8188eu: add error handling of rtw_read16
> >> staging: r8188eu: add error handling of rtw_read32
> >> staging: r8188eu: make ReadEFuse return an int
> >
> > Hi Pavel,
> >
> > I've just read your v2 of the series. I had no time to read each and every line,
> > however, I suppose that I saw enough to say that I think they are a huge
> > improvement over v1. I really like your patches and if I were you, I'd drop
> > that RFC tag.
> >
>
> Thank you, Fabio! I appreciate it :)
>
>
> With regards,
> Pavel Skripkin
Hi Pavel,
I've read more code of your series and I'm ready to give a formal ack. However,
I'm not sure about the rules: can it be also given to RFC or only to "real" patches?
As I've already said, they look good and I like them. So, the entire series is...
Acked-by: Fabio M. De Francesco <[email protected]>
If the rules don't allow to formally ack RFC, I will be happy to ack again the final product.
I also want to say that I enjoyed discussing this work with you on this long thread. :-)
Thanks,
Fabio
On 8/22/21 11:06 PM, Fabio M. De Francesco wrote:
> On Sunday, August 22, 2021 7:38:11 PM CEST Pavel Skripkin wrote:
>> On 8/22/21 8:36 PM, Fabio M. De Francesco wrote:
>> > On Sunday, August 22, 2021 4:35:05 PM CEST Pavel Skripkin wrote:
>> >> Hi, Greg, Larry and Phillip!
>> >>
>> >> I noticed, that new staging driver was added like 3 weeks ago and I decided
>> >> to look at the code, because drivers in staging directory are always buggy.
>> >>
>> >> The first thing I noticed is *no one* was checking read operations result, but
>> >> it can fail and driver may start writing random stack values into registers. It
>> >> can cause driver misbehavior or device misbehavior.
>> >>
>> >> To avoid this type of bugs, I've changed rtw_read* API. Now all rtw_read
>> >> funtions return an error, when something went wrong with usb transfer.
>> >>
>> >> It helps callers to break/return earlier and don't write random values to
>> >> registers or to rely on random values.
>> >>
>> >> Why is this pacth series RFC?
>> >> 1. I don't have this device and I cannot test these changes.
>> >> 2. I don't know how to handle errors in each particular case. For now, function
>> >> just returns or returns an error. That's all. I hope, driver maintainers will
>> >> help with these bits.
>> >> 3. I guess, I handled not all uninit value bugs here. I hope, I fixed
>> >> at least half of them
>> >>
>> >> v1 -> v2:
>> >> 1. Make rtw_read*() return an error instead of initializing pointer to error
>> >> 2. Split one huge patch to smaller ones for each rtw_read{8,16,32} function
>> >> changes
>> >> 3. Add new macro for printing register values (It helps to not copy-paste error
>> >> handling)
>> >> 4. Removed {read,write}_macreg (Suggested by Phillip)
>> >> 5. Rebased on top of staging-next
>> >> 6. Cleaned checkpatch errors and warnings
>> >>
>> >> Only build-tested, since I don't have device with r8118eu chip
>> >>
>> >> Pavel Skripkin (6):
>> >> staging: r8188eu: remove {read,write}_macreg
>> >> staging: r8188eu: add helper macro for printing registers
>> >> staging: r8188eu: add error handling of rtw_read8
>> >> staging: r8188eu: add error handling of rtw_read16
>> >> staging: r8188eu: add error handling of rtw_read32
>> >> staging: r8188eu: make ReadEFuse return an int
>> >
>> > Hi Pavel,
>> >
>> > I've just read your v2 of the series. I had no time to read each and every line,
>> > however, I suppose that I saw enough to say that I think they are a huge
>> > improvement over v1. I really like your patches and if I were you, I'd drop
>> > that RFC tag.
>> >
>>
>> Thank you, Fabio! I appreciate it :)
>>
>>
>> With regards,
>> Pavel Skripkin
>
> Hi Pavel,
>
> I've read more code of your series and I'm ready to give a formal ack. However,
> I'm not sure about the rules: can it be also given to RFC or only to "real" patches?
>
> As I've already said, they look good and I like them. So, the entire series is...
>
AFAIK, RFC patches can be treated as normal patches, if
reviewers/maintainers don't have objections to code. I am not sure about
it, since it's my first experience with RFCs :)
Anyway, thank you for ACKing. Let's see what Larry thinks about it. I
believe, he can find some bugs in my code since it's not tested at all
:) I hope, my r8118eu device will come soon and I will be able to test
this series...
> Acked-by: Fabio M. De Francesco <[email protected]>
>
> If the rules don't allow to formally ack RFC, I will be happy to ack again the final product.
>
> I also want to say that I enjoyed discussing this work with you on this long thread. :-)
>
Me too, thank you. Technical discussions are the best part of linux
kernel development process, IMO :)
With regards,
Pavel Skripkin
On Sun, 22 Aug 2021 at 17:26, Pavel Skripkin <[email protected]> wrote:
>
> On 8/22/21 7:05 PM, Michael Straube wrote:
>
> > Hi Pavel,
> >
> > My one is a TP-LINK WN725N (not sure, but I guess v2).
>
> Wow! I found this one in my city, thank you!
>
> > You could also have a look at the device table in os_dep/usb_intf.c
> >
>
> Yep, but I wanted to hear from driver reviewers/maintainers about what
> they use to test. I guess, some devices could be broken or not unwieldy
> to use. Thank you for recommendation, will buy one in few days :)
>
>
>
> With regards,
> Pavel Skripkin
Dear Pavel,
Glad you found one :-) Mine is the N10-Nano as that was all I could
find at the time.
Regards,
Phil
On Sun, 22 Aug 2021 at 15:35, Pavel Skripkin <[email protected]> wrote:
>
> Hi, Greg, Larry and Phillip!
>
> I noticed, that new staging driver was added like 3 weeks ago and I decided
> to look at the code, because drivers in staging directory are always buggy.
>
> The first thing I noticed is *no one* was checking read operations result, but
> it can fail and driver may start writing random stack values into registers. It
> can cause driver misbehavior or device misbehavior.
>
> To avoid this type of bugs, i've changed rtw_read* API. Now all rtw_read
> funtions return an error, when something went wrong with usb transfer.
>
> It helps callers to break/return earlier and don't write random values to
> registers or to rely on random values.
>
> Why is this pacth series RFC?
> 1. I don't have this device and I cannot test these changes.
> 2. I don't know how to handle errors in each particular case. For now, function
> just returns or returns an error. That's all. I hope, driver maintainers will
> help with these bits.
> 3. I guess, I handled not all uninit value bugs here. I hope, I fixed
> at least half of them
>
>
> v1 -> v2:
> 1. Make rtw_read*() return an error instead of initializing pointer to error
> 2. Split one huge patch to smaller ones for each rtw_read{8,16,32} function
> changes
> 3. Add new macro for printing register values (It helps to not copy-paste error
> handling)
> 4. Removed {read,write}_macreg (Suggested by Phillip)
> 5. Rebased on top of staging-next
> 6. Cleaned checkpatch errors and warnings
>
> Only build-tested, since I don't have device with r8118eu chip
>
> Pavel Skripkin (6):
> staging: r8188eu: remove {read,write}_macreg
> staging: r8188eu: add helper macro for printing registers
> staging: r8188eu: add error handling of rtw_read8
> staging: r8188eu: add error handling of rtw_read16
> staging: r8188eu: add error handling of rtw_read32
> staging: r8188eu: make ReadEFuse return an int
>
> drivers/staging/r8188eu/core/rtw_debug.c | 79 +++-
> drivers/staging/r8188eu/core/rtw_efuse.c | 125 +++--
> drivers/staging/r8188eu/core/rtw_io.c | 27 +-
> drivers/staging/r8188eu/core/rtw_mp.c | 70 ++-
> drivers/staging/r8188eu/core/rtw_mp_ioctl.c | 13 +-
> drivers/staging/r8188eu/core/rtw_pwrctrl.c | 5 +-
> drivers/staging/r8188eu/core/rtw_sreset.c | 9 +-
> .../r8188eu/hal/Hal8188ERateAdaptive.c | 8 +-
> drivers/staging/r8188eu/hal/HalPhyRf_8188e.c | 21 +-
> drivers/staging/r8188eu/hal/HalPwrSeqCmd.c | 9 +-
> drivers/staging/r8188eu/hal/hal_com.c | 23 +-
> drivers/staging/r8188eu/hal/hal_intf.c | 6 +-
> drivers/staging/r8188eu/hal/odm_interface.c | 12 +-
> drivers/staging/r8188eu/hal/rtl8188e_cmd.c | 33 +-
> drivers/staging/r8188eu/hal/rtl8188e_dm.c | 6 +-
> .../staging/r8188eu/hal/rtl8188e_hal_init.c | 285 +++++++++---
> drivers/staging/r8188eu/hal/rtl8188e_phycfg.c | 27 +-
> drivers/staging/r8188eu/hal/rtl8188e_sreset.c | 22 +-
> drivers/staging/r8188eu/hal/rtl8188eu_led.c | 18 +-
> drivers/staging/r8188eu/hal/usb_halinit.c | 439 +++++++++++++++---
> drivers/staging/r8188eu/hal/usb_ops_linux.c | 57 ++-
> drivers/staging/r8188eu/include/hal_intf.h | 6 +-
> .../staging/r8188eu/include/odm_interface.h | 6 +-
> .../staging/r8188eu/include/rtl8188e_hal.h | 2 +-
> drivers/staging/r8188eu/include/rtw_debug.h | 13 +
> drivers/staging/r8188eu/include/rtw_efuse.h | 4 +-
> drivers/staging/r8188eu/include/rtw_io.h | 18 +-
> drivers/staging/r8188eu/include/rtw_mp.h | 2 -
> drivers/staging/r8188eu/os_dep/ioctl_linux.c | 179 +++++--
> drivers/staging/r8188eu/os_dep/usb_intf.c | 3 +-
> 30 files changed, 1138 insertions(+), 389 deletions(-)
>
> --
> 2.32.0
>
Dear Pavel,
Thanks for this. I like the code a lot. One thing I am conflicted on
is the helper macro for the printing of register values though. Whilst
I'm not necessarily opposed to the concept of the macro itself, I
don't think it should rely on GlobalDebugLevel for one thing - if we
are going to control printing of messages at runtime then in my mind
this should be done via debugfs and pr_debug or similar - an in-kernel
mechanism rather than something driver-provided. Also, the example you
give of:
u32 tmp;
if (!rtw_read(&tmp))
DBG("reg = %d\n", tmp);
Doesn't seem overly unclear to me if DBG was a pr_debug or similar,
but I get what you're saying about repetition. This is just a small
thing though, would be interested to see what others think. Many
thanks.
Regards,
Phil
On 8/23/21 3:12 AM, Phillip Potter wrote:
> On Sun, 22 Aug 2021 at 15:35, Pavel Skripkin <[email protected]> wrote:
>>
>> Hi, Greg, Larry and Phillip!
>>
>> I noticed, that new staging driver was added like 3 weeks ago and I decided
>> to look at the code, because drivers in staging directory are always buggy.
>>
>> The first thing I noticed is *no one* was checking read operations result, but
>> it can fail and driver may start writing random stack values into registers. It
>> can cause driver misbehavior or device misbehavior.
>>
>> To avoid this type of bugs, i've changed rtw_read* API. Now all rtw_read
>> funtions return an error, when something went wrong with usb transfer.
>>
>> It helps callers to break/return earlier and don't write random values to
>> registers or to rely on random values.
>>
>> Why is this pacth series RFC?
>> 1. I don't have this device and I cannot test these changes.
>> 2. I don't know how to handle errors in each particular case. For now, function
>> just returns or returns an error. That's all. I hope, driver maintainers will
>> help with these bits.
>> 3. I guess, I handled not all uninit value bugs here. I hope, I fixed
>> at least half of them
>>
>>
>> v1 -> v2:
>> 1. Make rtw_read*() return an error instead of initializing pointer to error
>> 2. Split one huge patch to smaller ones for each rtw_read{8,16,32} function
>> changes
>> 3. Add new macro for printing register values (It helps to not copy-paste error
>> handling)
>> 4. Removed {read,write}_macreg (Suggested by Phillip)
>> 5. Rebased on top of staging-next
>> 6. Cleaned checkpatch errors and warnings
>>
>> Only build-tested, since I don't have device with r8118eu chip
>>
>> Pavel Skripkin (6):
>> staging: r8188eu: remove {read,write}_macreg
>> staging: r8188eu: add helper macro for printing registers
>> staging: r8188eu: add error handling of rtw_read8
>> staging: r8188eu: add error handling of rtw_read16
>> staging: r8188eu: add error handling of rtw_read32
>> staging: r8188eu: make ReadEFuse return an int
>>
>> drivers/staging/r8188eu/core/rtw_debug.c | 79 +++-
>> drivers/staging/r8188eu/core/rtw_efuse.c | 125 +++--
>> drivers/staging/r8188eu/core/rtw_io.c | 27 +-
>> drivers/staging/r8188eu/core/rtw_mp.c | 70 ++-
>> drivers/staging/r8188eu/core/rtw_mp_ioctl.c | 13 +-
>> drivers/staging/r8188eu/core/rtw_pwrctrl.c | 5 +-
>> drivers/staging/r8188eu/core/rtw_sreset.c | 9 +-
>> .../r8188eu/hal/Hal8188ERateAdaptive.c | 8 +-
>> drivers/staging/r8188eu/hal/HalPhyRf_8188e.c | 21 +-
>> drivers/staging/r8188eu/hal/HalPwrSeqCmd.c | 9 +-
>> drivers/staging/r8188eu/hal/hal_com.c | 23 +-
>> drivers/staging/r8188eu/hal/hal_intf.c | 6 +-
>> drivers/staging/r8188eu/hal/odm_interface.c | 12 +-
>> drivers/staging/r8188eu/hal/rtl8188e_cmd.c | 33 +-
>> drivers/staging/r8188eu/hal/rtl8188e_dm.c | 6 +-
>> .../staging/r8188eu/hal/rtl8188e_hal_init.c | 285 +++++++++---
>> drivers/staging/r8188eu/hal/rtl8188e_phycfg.c | 27 +-
>> drivers/staging/r8188eu/hal/rtl8188e_sreset.c | 22 +-
>> drivers/staging/r8188eu/hal/rtl8188eu_led.c | 18 +-
>> drivers/staging/r8188eu/hal/usb_halinit.c | 439 +++++++++++++++---
>> drivers/staging/r8188eu/hal/usb_ops_linux.c | 57 ++-
>> drivers/staging/r8188eu/include/hal_intf.h | 6 +-
>> .../staging/r8188eu/include/odm_interface.h | 6 +-
>> .../staging/r8188eu/include/rtl8188e_hal.h | 2 +-
>> drivers/staging/r8188eu/include/rtw_debug.h | 13 +
>> drivers/staging/r8188eu/include/rtw_efuse.h | 4 +-
>> drivers/staging/r8188eu/include/rtw_io.h | 18 +-
>> drivers/staging/r8188eu/include/rtw_mp.h | 2 -
>> drivers/staging/r8188eu/os_dep/ioctl_linux.c | 179 +++++--
>> drivers/staging/r8188eu/os_dep/usb_intf.c | 3 +-
>> 30 files changed, 1138 insertions(+), 389 deletions(-)
>>
>> --
>> 2.32.0
>>
>
> Dear Pavel,
>
> Thanks for this. I like the code a lot. One thing I am conflicted on
> is the helper macro for the printing of register values though. Whilst
> I'm not necessarily opposed to the concept of the macro itself, I
> don't think it should rely on GlobalDebugLevel for one thing - if we
> are going to control printing of messages at runtime then in my mind
> this should be done via debugfs and pr_debug or similar - an in-kernel
> mechanism rather than something driver-provided. Also, the example you
I've copy-pasted previous DBG() macro. I have a plan to clean up these
debug macros in future, but I want to make these clean ups on top of
this RFC to not rebase this huge patch set many times :)
> give of:
>
> u32 tmp;
> if (!rtw_read(&tmp))
> DBG("reg = %d\n", tmp);
>
> Doesn't seem overly unclear to me if DBG was a pr_debug or similar,
> but I get what you're saying about repetition. This is just a small
> thing though, would be interested to see what others think. Many
> thanks.
>
To be honest, I made this macro, because I am lazy :P rtw_dbg_port() had
a lot DBG_88E() calls with just register value, so I decided to wrap this.
I still believe, that this macro is useful, since callers won't care
about creating temp variable and checking read() error code. This macro
doesn't cover situation, where we want to print register + smth else, so
if you have any idea about improvements, please, let me know :)
With regards,
Pavel Skripkin
On 8/23/21 3:12 AM, Phillip Potter wrote:
> On Sun, 22 Aug 2021 at 15:35, Pavel Skripkin <[email protected]> wrote:
>>
>> Hi, Greg, Larry and Phillip!
>>
>> I noticed, that new staging driver was added like 3 weeks ago and I decided
>> to look at the code, because drivers in staging directory are always buggy.
>>
>> The first thing I noticed is *no one* was checking read operations result, but
>> it can fail and driver may start writing random stack values into registers. It
>> can cause driver misbehavior or device misbehavior.
>>
>> To avoid this type of bugs, i've changed rtw_read* API. Now all rtw_read
>> funtions return an error, when something went wrong with usb transfer.
>>
>> It helps callers to break/return earlier and don't write random values to
>> registers or to rely on random values.
>>
>> Why is this pacth series RFC?
>> 1. I don't have this device and I cannot test these changes.
>> 2. I don't know how to handle errors in each particular case. For now, function
>> just returns or returns an error. That's all. I hope, driver maintainers will
>> help with these bits.
>> 3. I guess, I handled not all uninit value bugs here. I hope, I fixed
>> at least half of them
>>
>>
>> v1 -> v2:
>> 1. Make rtw_read*() return an error instead of initializing pointer to error
>> 2. Split one huge patch to smaller ones for each rtw_read{8,16,32} function
>> changes
>> 3. Add new macro for printing register values (It helps to not copy-paste error
>> handling)
>> 4. Removed {read,write}_macreg (Suggested by Phillip)
>> 5. Rebased on top of staging-next
>> 6. Cleaned checkpatch errors and warnings
>>
>> Only build-tested, since I don't have device with r8118eu chip
>>
>> Pavel Skripkin (6):
>> staging: r8188eu: remove {read,write}_macreg
>> staging: r8188eu: add helper macro for printing registers
>> staging: r8188eu: add error handling of rtw_read8
>> staging: r8188eu: add error handling of rtw_read16
>> staging: r8188eu: add error handling of rtw_read32
>> staging: r8188eu: make ReadEFuse return an int
>>
>> drivers/staging/r8188eu/core/rtw_debug.c | 79 +++-
>> drivers/staging/r8188eu/core/rtw_efuse.c | 125 +++--
>> drivers/staging/r8188eu/core/rtw_io.c | 27 +-
>> drivers/staging/r8188eu/core/rtw_mp.c | 70 ++-
>> drivers/staging/r8188eu/core/rtw_mp_ioctl.c | 13 +-
>> drivers/staging/r8188eu/core/rtw_pwrctrl.c | 5 +-
>> drivers/staging/r8188eu/core/rtw_sreset.c | 9 +-
>> .../r8188eu/hal/Hal8188ERateAdaptive.c | 8 +-
>> drivers/staging/r8188eu/hal/HalPhyRf_8188e.c | 21 +-
>> drivers/staging/r8188eu/hal/HalPwrSeqCmd.c | 9 +-
>> drivers/staging/r8188eu/hal/hal_com.c | 23 +-
>> drivers/staging/r8188eu/hal/hal_intf.c | 6 +-
>> drivers/staging/r8188eu/hal/odm_interface.c | 12 +-
>> drivers/staging/r8188eu/hal/rtl8188e_cmd.c | 33 +-
>> drivers/staging/r8188eu/hal/rtl8188e_dm.c | 6 +-
>> .../staging/r8188eu/hal/rtl8188e_hal_init.c | 285 +++++++++---
>> drivers/staging/r8188eu/hal/rtl8188e_phycfg.c | 27 +-
>> drivers/staging/r8188eu/hal/rtl8188e_sreset.c | 22 +-
>> drivers/staging/r8188eu/hal/rtl8188eu_led.c | 18 +-
>> drivers/staging/r8188eu/hal/usb_halinit.c | 439 +++++++++++++++---
>> drivers/staging/r8188eu/hal/usb_ops_linux.c | 57 ++-
>> drivers/staging/r8188eu/include/hal_intf.h | 6 +-
>> .../staging/r8188eu/include/odm_interface.h | 6 +-
>> .../staging/r8188eu/include/rtl8188e_hal.h | 2 +-
>> drivers/staging/r8188eu/include/rtw_debug.h | 13 +
>> drivers/staging/r8188eu/include/rtw_efuse.h | 4 +-
>> drivers/staging/r8188eu/include/rtw_io.h | 18 +-
>> drivers/staging/r8188eu/include/rtw_mp.h | 2 -
>> drivers/staging/r8188eu/os_dep/ioctl_linux.c | 179 +++++--
>> drivers/staging/r8188eu/os_dep/usb_intf.c | 3 +-
>> 30 files changed, 1138 insertions(+), 389 deletions(-)
>>
>> --
>> 2.32.0
>>
>
> Dear Pavel,
>
> Thanks for this. I like the code a lot. One thing I am conflicted on
> is the helper macro for the printing of register values though. Whilst
> I'm not necessarily opposed to the concept of the macro itself, I
> don't think it should rely on GlobalDebugLevel for one thing - if we
> are going to control printing of messages at runtime then in my mind
> this should be done via debugfs and pr_debug or similar - an in-kernel
> mechanism rather than something driver-provided. Also, the example you
> give of:
>
> u32 tmp;
> if (!rtw_read(&tmp))
> DBG("reg = %d\n", tmp);
>
> Doesn't seem overly unclear to me if DBG was a pr_debug or similar,
> but I get what you're saying about repetition. This is just a small
> thing though, would be interested to see what others think. Many
> thanks.
>
Btw, did you have a chance to test these changes? My r8188eu device
_should_ come in few days, so I am not able to test it right now :)
With regards,
Pavel Skripkin
On Sun, 22 Aug 2021 at 15:36, Pavel Skripkin <[email protected]> wrote:
> -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
> {
> u8 requesttype;
> u16 wvalue;
> u16 len;
> - __le32 data;
> + int res;
> + __le32 tmp;
> +
> + if (WARN_ON(unlikely(!data)))
> + return -EINVAL;
>
> requesttype = 0x01;/* read_in */
>
> wvalue = (u16)(addr & 0x0000ffff);
> len = 4;
>
> - usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> + res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> + if (res < 0) {
> + dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
> + } else {
> + /* Noone cares about positive return value */
> + *data = le32_to_cpu(tmp);
> + res = 0;
> + }
>
> - return le32_to_cpu(data);
> + return res;
> }
Dear Pavel,
OK, found the issue with decoded stack trace after reviewing this
usb_read32 function. Your line:
res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
should read:
res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
With this change, the driver runs fine with no crashes/oopses. I will
explain the issue but you can probably see already, so I hope I'm not
coming across as patronising, just trying to be helpful :-)
Essentially, you are taking the address of the data function parameter
on this line with &data, a pointer to u32, which is giving you a
pointer to a pointer to u32 (u32 **) for this function parameter
variable. When passed to usbctrl_vendorreq, it is being passed to
memcpy inside this function as a void *, meaning that memcpy
subsequently overwrites the value of the memory address inside data to
point to a different location, which is problem when it is later
deferenced at:
*data = le32_to_cpu(tmp);
causing the OOPS
Also, as written, you can probably see that tmp is uninitialised. This
looks like a typo, so guessing this wasn't your intention. Anyhow,
with that small change, usbctrl_vendorreq reads into tmp, which is
then passed to le32_to_cpu whose return value is stored via the
deferenced data ptr (which now has its original address within and not
inadvertently modified). Hope this helps, and I'd be happy to Ack the
series if you want to resend this patch. Many thanks.
Regards,
Phil
On Tuesday, August 24, 2021 1:33:46 AM CEST Phillip Potter wrote:
> On Sun, 22 Aug 2021 at 15:36, Pavel Skripkin <[email protected]> wrote:
> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
> > {
> > u8 requesttype;
> > u16 wvalue;
> > u16 len;
> > - __le32 data;
> > + int res;
> > + __le32 tmp;
> > +
> > + if (WARN_ON(unlikely(!data)))
> > + return -EINVAL;
> >
> > requesttype = 0x01;/* read_in */
> >
> > wvalue = (u16)(addr & 0x0000ffff);
> > len = 4;
> >
> > - usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> > + res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> > + if (res < 0) {
> > + dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
> > + } else {
> > + /* Noone cares about positive return value */
> > + *data = le32_to_cpu(tmp);
> > + res = 0;
> > + }
> >
> > - return le32_to_cpu(data);
> > + return res;
> > }
>
> Dear Pavel,
>
> OK, found the issue with decoded stack trace after reviewing this
> usb_read32 function. Your line:
> res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>
> should read:
> res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
Dear Philip,
No, it should read:
res = usbctrl_vendorreq(pintfhdl, wvalue, data, len, requesttype);
I suspect that Pavel didn't notice he was reusing a line of the old code
wth no due changes.
> With this change, the driver runs fine with no crashes/oopses. I will
> explain the issue but you can probably see already, so I hope I'm not
> coming across as patronising, just trying to be helpful :-)
>
> Essentially, you are taking the address of the data function parameter
> on this line with &data, a pointer to u32, which is giving you a
> pointer to a pointer to u32 (u32 **) for this function parameter
> variable. When passed to usbctrl_vendorreq, it is being passed to
> memcpy inside this function as a void *, meaning that memcpy
> subsequently overwrites the value of the memory address inside data to
> point to a different location, which is problem when it is later
> deferenced at:
> *data = le32_to_cpu(tmp);
> causing the OOPS
>
> Also, as written, you can probably see that tmp is uninitialised. This
> looks like a typo, so guessing this wasn't your intention. Anyhow,
> with that small change, usbctrl_vendorreq reads into tmp, which is
> then passed to le32_to_cpu whose return value is stored via the
> deferenced data ptr (which now has its original address within and not
> inadvertently modified). Hope this helps, and I'd be happy to Ack the
> series if you want to resend this patch. Many thanks.
I think that another typo is having 'tmp', because that variable is unnecessary
and "*data = le32_to_cpu(tmp);" is wrong too.
Now I also see that also usb_read16() is wrong, while usb_read8() (the one that
I had read yesterday) is the only correct function of the three usb_read*().
Regards,
Fabio
>
> Regards,
> Phil
>
On 8/24/21 3:10 AM, Fabio M. De Francesco wrote:
> On Tuesday, August 24, 2021 1:33:46 AM CEST Phillip Potter wrote:
>> On Sun, 22 Aug 2021 at 15:36, Pavel Skripkin <[email protected]> wrote:
>> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
>> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
>> > {
>> > u8 requesttype;
>> > u16 wvalue;
>> > u16 len;
>> > - __le32 data;
>> > + int res;
>> > + __le32 tmp;
>> > +
>> > + if (WARN_ON(unlikely(!data)))
>> > + return -EINVAL;
>> >
>> > requesttype = 0x01;/* read_in */
>> >
>> > wvalue = (u16)(addr & 0x0000ffff);
>> > len = 4;
>> >
>> > - usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>> > + res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>> > + if (res < 0) {
>> > + dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
>> > + } else {
>> > + /* Noone cares about positive return value */
>> > + *data = le32_to_cpu(tmp);
>> > + res = 0;
>> > + }
>> >
>> > - return le32_to_cpu(data);
>> > + return res;
>> > }
>>
>> Dear Pavel,
>>
>> OK, found the issue with decoded stack trace after reviewing this
>> usb_read32 function. Your line:
>> res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>>
>> should read:
>> res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
>
> Dear Philip,
>
> No, it should read:
>
> res = usbctrl_vendorreq(pintfhdl, wvalue, data, len, requesttype);
>
> I suspect that Pavel didn't notice he was reusing a line of the old code
> wth no due changes.
>
>> With this change, the driver runs fine with no crashes/oopses. I will
>> explain the issue but you can probably see already, so I hope I'm not
>> coming across as patronising, just trying to be helpful :-)
>>
>> Essentially, you are taking the address of the data function parameter
>> on this line with &data, a pointer to u32, which is giving you a
>> pointer to a pointer to u32 (u32 **) for this function parameter
>> variable. When passed to usbctrl_vendorreq, it is being passed to
>> memcpy inside this function as a void *, meaning that memcpy
>> subsequently overwrites the value of the memory address inside data to
>> point to a different location, which is problem when it is later
>> deferenced at:
>> *data = le32_to_cpu(tmp);
>> causing the OOPS
>>
>> Also, as written, you can probably see that tmp is uninitialised. This
>> looks like a typo, so guessing this wasn't your intention. Anyhow,
>> with that small change, usbctrl_vendorreq reads into tmp, which is
>> then passed to le32_to_cpu whose return value is stored via the
>> deferenced data ptr (which now has its original address within and not
>> inadvertently modified). Hope this helps, and I'd be happy to Ack the
>> series if you want to resend this patch. Many thanks.
>
> I think that another typo is having 'tmp', because that variable is unnecessary
> and "*data = le32_to_cpu(tmp);" is wrong too.
>
> Now I also see that also usb_read16() is wrong, while usb_read8() (the one that
> I had read yesterday) is the only correct function of the three usb_read*().
>
Hi, guys!
Sorry for breaking your system, Phillip. This code was part of "last
minute" changes and yes, it's broken :)
I get what Phillip said, because I _should_ read into tmp variable
instead of directly to data, but I don't get Fabio's idea, sorry.
Data from chip comes in little-endian, so we _should_ convert it to
cpu's endian. Temp variable is needed to make smatch and all other
static anylis tools happy about this code.
If I am missing something, please, let me know :) v3 is on the way...
With regards,
Pavel Skripkin
On 8/24/21 2:33 AM, Phillip Potter wrote:
> On Sun, 22 Aug 2021 at 15:36, Pavel Skripkin <[email protected]> wrote:
>> -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
>> +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
>> {
>> u8 requesttype;
>> u16 wvalue;
>> u16 len;
>> - __le32 data;
>> + int res;
>> + __le32 tmp;
>> +
>> + if (WARN_ON(unlikely(!data)))
>> + return -EINVAL;
>>
>> requesttype = 0x01;/* read_in */
>>
>> wvalue = (u16)(addr & 0x0000ffff);
>> len = 4;
>>
>> - usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>> + res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>> + if (res < 0) {
>> + dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
>> + } else {
>> + /* Noone cares about positive return value */
>> + *data = le32_to_cpu(tmp);
>> + res = 0;
>> + }
>>
>> - return le32_to_cpu(data);
>> + return res;
>> }
>
> Dear Pavel,
>
> OK, found the issue with decoded stack trace after reviewing this
> usb_read32 function. Your line:
> res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>
> should read:
> res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
>
> With this change, the driver runs fine with no crashes/oopses. I will
> explain the issue but you can probably see already, so I hope I'm not
> coming across as patronising, just trying to be helpful :-)
>
> Essentially, you are taking the address of the data function parameter
> on this line with &data, a pointer to u32, which is giving you a
> pointer to a pointer to u32 (u32 **) for this function parameter
> variable. When passed to usbctrl_vendorreq, it is being passed to
> memcpy inside this function as a void *, meaning that memcpy
> subsequently overwrites the value of the memory address inside data to
> point to a different location, which is problem when it is later
> deferenced at:
> *data = le32_to_cpu(tmp);
> causing the OOPS
>
The most strange thing is why gcc didn't complain about different
pointer types... I think, that gcc must complain about this type of not
explicit casts, because 99% it's a bug.
Again big thanks for analysis :)
With regards,
Pavel Skripkin
On Sun, Aug 22, 2021 at 05:36:01PM +0300, Pavel Skripkin wrote:
> -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
> {
> u8 requesttype;
> u16 wvalue;
> u16 len;
> - __le32 data;
> + int res;
> + __le32 tmp;
> +
> + if (WARN_ON(unlikely(!data)))
> + return -EINVAL;
>
> requesttype = 0x01;/* read_in */
>
> wvalue = (u16)(addr & 0x0000ffff);
> len = 4;
>
> - usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> + res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> + if (res < 0) {
> + dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
Add a return here. Try to keep the success path and the failure path
as separate as possible. Try to keep the success path indented at one
tab so the code looks like this:
success();
success();
if (fail)
handle_failure();
success();
success();
Try to deal with exceptions as quickly as possible so that the reader
has less to remember.
> + } else {
> + /* Noone cares about positive return value */
Ugh... That's unfortunate. We should actually care. The
usbctrl_vendorreq() has an information leak where it copies len (4)
bytes of data even if usb_control_msg() is not able to read len bytes.
The best fix would be to remove the information leak and make
usbctrl_vendorreq() return zero on success. In other words something
like:
status = usb_control_msg();
if (status < 0)
return status;
if (status != len)
return -EIO;
status = 0;
> + *data = le32_to_cpu(tmp);
> + res = 0;
> + }
>
> - return le32_to_cpu(data);
> + return res;
> }
On 8/24/21 9:58 AM, Dan Carpenter wrote:
> On Sun, Aug 22, 2021 at 05:36:01PM +0300, Pavel Skripkin wrote:
>> -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
>> +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
>> {
>> u8 requesttype;
>> u16 wvalue;
>> u16 len;
>> - __le32 data;
>> + int res;
>> + __le32 tmp;
>> +
>> + if (WARN_ON(unlikely(!data)))
>> + return -EINVAL;
>>
>> requesttype = 0x01;/* read_in */
>>
>> wvalue = (u16)(addr & 0x0000ffff);
>> len = 4;
>>
>> - usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>> + res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>> + if (res < 0) {
>> + dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
>
> Add a return here. Try to keep the success path and the failure path
> as separate as possible. Try to keep the success path indented at one
> tab so the code looks like this:
>
> success();
> success();
> if (fail)
> handle_failure();
> success();
> success();
>
> Try to deal with exceptions as quickly as possible so that the reader
> has less to remember.
>
>> + } else {
>> + /* Noone cares about positive return value */
>
> Ugh... That's unfortunate. We should actually care. The
> usbctrl_vendorreq() has an information leak where it copies len (4)
> bytes of data even if usb_control_msg() is not able to read len bytes.
>
> The best fix would be to remove the information leak and make
> usbctrl_vendorreq() return zero on success. In other words something
> like:
>
> status = usb_control_msg();
> if (status < 0)
> return status;
> if (status != len)
> return -EIO;
> status = 0;
>
I see, thank you for reviewing, will fix in v3! I fully forgot, that
usb_control_msg() can receive only part of the message :)
With regards,
Pavel Skripkin
Hi, Greg, Larry and Phillip!
I noticed, that new staging driver was added like 3 weeks ago and I decided
to look at the code, because drivers in staging directory are always buggy.
The first thing I noticed is *no one* was checking read operations result, but
it can fail and driver may start writing random stack values into registers. It
can cause driver misbehavior or device misbehavior.
To avoid this type of bugs, i've changed rtw_read* API. Now all rtw_read
funtions return an error, when something went wrong with usb transfer.
It helps callers to break/return earlier and don't write random values to
registers or to rely on random values.
v2 -> v3:
1. Fixed OOPS in usb_read32(), caused by writing to u32 **
2. Fixed style in rtw_read32, rtw_read16 and rtw_read8 (Suggested by Dan)
3. Added error hanling when usb_control_msg() returns ret != len
NOTE: Dan suggested to add this to usbctrl_vendorreq(), but there is
pending series, which will get rid of usb_control_msg(), so (res != len)
check can be removed, when Fabio's series will go in
4. Removed RFC tag
v1 -> v2:
1. Make rtw_read*() return an error instead of initializing pointer to error
2. Split one huge patch to smaller ones for each rtw_read{8,16,32} function
changes
3. Add new macro for printing register values (It helps to not copy-paste error
handling)
4. Removed {read,write}_macreg (Suggested by Phillip)
5. Rebased on top of staging-next
6. Cleaned checkpatch errors and warnings
Phillip has tested fixed v2 version, AFAIU
Pavel Skripkin (6):
staging: r8188eu: remove {read,write}_macreg
staging: r8188eu: add helper macro for printing registers
staging: r8188eu: add error handling of rtw_read8
staging: r8188eu: add error handling of rtw_read16
staging: r8188eu: add error handling of rtw_read32
staging: r8188eu: make ReadEFuse return an int
drivers/staging/r8188eu/core/rtw_debug.c | 79 +++-
drivers/staging/r8188eu/core/rtw_efuse.c | 125 +++--
drivers/staging/r8188eu/core/rtw_io.c | 27 +-
drivers/staging/r8188eu/core/rtw_mp.c | 70 ++-
drivers/staging/r8188eu/core/rtw_mp_ioctl.c | 13 +-
drivers/staging/r8188eu/core/rtw_pwrctrl.c | 5 +-
drivers/staging/r8188eu/core/rtw_sreset.c | 9 +-
.../r8188eu/hal/Hal8188ERateAdaptive.c | 8 +-
drivers/staging/r8188eu/hal/HalPhyRf_8188e.c | 21 +-
drivers/staging/r8188eu/hal/HalPwrSeqCmd.c | 9 +-
drivers/staging/r8188eu/hal/hal_com.c | 23 +-
drivers/staging/r8188eu/hal/hal_intf.c | 6 +-
drivers/staging/r8188eu/hal/odm_interface.c | 12 +-
drivers/staging/r8188eu/hal/rtl8188e_cmd.c | 33 +-
drivers/staging/r8188eu/hal/rtl8188e_dm.c | 6 +-
.../staging/r8188eu/hal/rtl8188e_hal_init.c | 285 +++++++++---
drivers/staging/r8188eu/hal/rtl8188e_phycfg.c | 27 +-
drivers/staging/r8188eu/hal/rtl8188e_sreset.c | 22 +-
drivers/staging/r8188eu/hal/rtl8188eu_led.c | 18 +-
drivers/staging/r8188eu/hal/usb_halinit.c | 439 +++++++++++++++---
drivers/staging/r8188eu/hal/usb_ops_linux.c | 62 ++-
drivers/staging/r8188eu/include/hal_intf.h | 6 +-
.../staging/r8188eu/include/odm_interface.h | 6 +-
.../staging/r8188eu/include/rtl8188e_hal.h | 2 +-
drivers/staging/r8188eu/include/rtw_debug.h | 13 +
drivers/staging/r8188eu/include/rtw_efuse.h | 4 +-
drivers/staging/r8188eu/include/rtw_io.h | 18 +-
drivers/staging/r8188eu/include/rtw_mp.h | 2 -
drivers/staging/r8188eu/os_dep/ioctl_linux.c | 179 +++++--
drivers/staging/r8188eu/os_dep/usb_intf.c | 3 +-
30 files changed, 1143 insertions(+), 389 deletions(-)
--
2.32.0
_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 <[email protected]>
---
drivers/staging/r8188eu/core/rtw_debug.c | 11 +-
drivers/staging/r8188eu/core/rtw_efuse.c | 76 +++--
drivers/staging/r8188eu/core/rtw_io.c | 9 +-
drivers/staging/r8188eu/core/rtw_mp.c | 13 +-
drivers/staging/r8188eu/core/rtw_mp_ioctl.c | 5 +-
drivers/staging/r8188eu/hal/HalPhyRf_8188e.c | 19 +-
drivers/staging/r8188eu/hal/HalPwrSeqCmd.c | 9 +-
drivers/staging/r8188eu/hal/hal_com.c | 23 +-
drivers/staging/r8188eu/hal/odm_interface.c | 4 +-
drivers/staging/r8188eu/hal/rtl8188e_cmd.c | 33 ++-
drivers/staging/r8188eu/hal/rtl8188e_dm.c | 6 +-
.../staging/r8188eu/hal/rtl8188e_hal_init.c | 128 +++++++--
drivers/staging/r8188eu/hal/rtl8188e_phycfg.c | 10 +-
drivers/staging/r8188eu/hal/rtl8188e_sreset.c | 8 +-
drivers/staging/r8188eu/hal/rtl8188eu_led.c | 18 +-
drivers/staging/r8188eu/hal/usb_halinit.c | 267 +++++++++++++++---
drivers/staging/r8188eu/hal/usb_ops_linux.c | 18 +-
.../staging/r8188eu/include/odm_interface.h | 2 +-
drivers/staging/r8188eu/include/rtw_io.h | 6 +-
drivers/staging/r8188eu/os_dep/ioctl_linux.c | 61 +++-
20 files changed, 568 insertions(+), 158 deletions(-)
diff --git a/drivers/staging/r8188eu/core/rtw_debug.c b/drivers/staging/r8188eu/core/rtw_debug.c
index 2ee64cef73f7..8b7d3eb12bd0 100644
--- a/drivers/staging/r8188eu/core/rtw_debug.c
+++ b/drivers/staging/r8188eu/core/rtw_debug.c
@@ -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));
diff --git a/drivers/staging/r8188eu/core/rtw_efuse.c b/drivers/staging/r8188eu/core/rtw_efuse.c
index decccf7622f0..b471f6446f78 100644
--- a/drivers/staging/r8188eu/core/rtw_efuse.c
+++ b/drivers/staging/r8188eu/core/rtw_efuse.c
@@ -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,6 +251,7 @@ 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);
@@ -251,27 +259,42 @@ u8 EFUSE_Read1Byte(struct adapter *Adapter, u16 Address)
/* 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;
diff --git a/drivers/staging/r8188eu/core/rtw_io.c b/drivers/staging/r8188eu/core/rtw_io.c
index cde0205816b1..2714506c8ffb 100644
--- a/drivers/staging/r8188eu/core/rtw_io.c
+++ b/drivers/staging/r8188eu/core/rtw_io.c
@@ -34,18 +34,15 @@ [email protected]
#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)
diff --git a/drivers/staging/r8188eu/core/rtw_mp.c b/drivers/staging/r8188eu/core/rtw_mp.c
index 0a0a24fd37b0..76f0bc399819 100644
--- a/drivers/staging/r8188eu/core/rtw_mp.c
+++ b/drivers/staging/r8188eu/core/rtw_mp.c
@@ -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 */
}
diff --git a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
index c85f8e467337..894ab456f202 100644
--- a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
+++ b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
@@ -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);
diff --git a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
index 356885e27edd..3545ad60dc00 100644
--- a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
+++ b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
@@ -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);
}
diff --git a/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c b/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
index 0fd11aca7ac7..74e83381ef06 100644
--- a/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
+++ b/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
@@ -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)))
diff --git a/drivers/staging/r8188eu/hal/hal_com.c b/drivers/staging/r8188eu/hal/hal_com.c
index f09d4d49b159..833c88c85e3f 100644
--- a/drivers/staging/r8188eu/hal/hal_com.c
+++ b/drivers/staging/r8188eu/hal/hal_com.c
@@ -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;
diff --git a/drivers/staging/r8188eu/hal/odm_interface.c b/drivers/staging/r8188eu/hal/odm_interface.c
index 5a01495d74bc..9a9df98da727 100644
--- a/drivers/staging/r8188eu/hal/odm_interface.c
+++ b/drivers/staging/r8188eu/hal/odm_interface.c
@@ -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)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_cmd.c b/drivers/staging/r8188eu/hal/rtl8188e_cmd.c
index 3e1a45030bc8..53636c0e4786 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_cmd.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_cmd.c
@@ -21,12 +21,14 @@ static u8 _is_fw_read_cmd_down(struct adapter *adapt, u8 msgbox_num)
{
u8 read_down = false;
int retry_cnts = 100;
-
+ int error;
u8 valid;
do {
- valid = rtw_read8(adapt, REG_HMETFR) & BIT(msgbox_num);
- if (0 == valid)
+ error = rtw_read8(adapt, REG_HMETFR, &valid);
+ if (error)
+ return read_down;
+ else if (!(valid & BIT(msgbox_num)))
read_down = true;
} while ((!read_down) && (retry_cnts--));
@@ -578,8 +580,9 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
bool bSendBeacon = false;
bool bcn_valid = false;
- u8 DLBcnCount = 0;
+ u8 DLBcnCount = 0, val8;
u32 poll = 0;
+ int error;
DBG_88E("%s mstatus(%x)\n", __func__, mstatus);
@@ -596,8 +599,15 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
/* Disable Hw protection for a time which revserd for Hw sending beacon. */
/* Fix download reserved page packet fail that access collision with the protection time. */
/* 2010.05.11. Added by tynli. */
- rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) & (~BIT(3)));
- rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) | BIT(4));
+ error = rtw_read8(adapt, REG_BCN_CTRL, &val8);
+ if (error)
+ return;
+ rtw_write8(adapt, REG_BCN_CTRL, val8 & (~BIT(3)));
+
+ error = rtw_read8(adapt, REG_BCN_CTRL, &val8);
+ if (error)
+ return;
+ rtw_write8(adapt, REG_BCN_CTRL, val8 | BIT(4));
if (haldata->RegFwHwTxQCtrl & BIT(6)) {
DBG_88E("HalDownloadRSVDPage(): There is an Adapter is sending beacon.\n");
@@ -639,8 +649,15 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
/* */
/* Enable Bcn */
- rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) | BIT(3));
- rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) & (~BIT(4)));
+ error = rtw_read8(adapt, REG_BCN_CTRL, &val8);
+ if (error)
+ return;
+ rtw_write8(adapt, REG_BCN_CTRL, val8 | BIT(3));
+
+ error = rtw_read8(adapt, REG_BCN_CTRL, &val8);
+ if (error)
+ return;
+ rtw_write8(adapt, REG_BCN_CTRL, val8 & (~BIT(4)));
/* To make sure that if there exists an adapter which would like to send beacon. */
/* If exists, the origianl value of 0x422[6] will be 1, we should check this to */
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_dm.c b/drivers/staging/r8188eu/hal/rtl8188e_dm.c
index 78552303c990..5cb3d6369449 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_dm.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_dm.c
@@ -16,8 +16,12 @@ static void dm_CheckStatistics(struct adapter *Adapter)
static void dm_InitGPIOSetting(struct adapter *Adapter)
{
u8 tmp1byte;
+ int error;
+
+ error = rtw_read8(Adapter, REG_GPIO_MUXCFG, &tmp1byte);
+ if (error)
+ return;
- tmp1byte = rtw_read8(Adapter, REG_GPIO_MUXCFG);
tmp1byte &= (GPIOSEL_GPIO | ~GPIOSEL_ENBT);
rtw_write8(Adapter, REG_GPIO_MUXCFG, tmp1byte);
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
index 393969f51206..cfc429965b7d 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
@@ -13,10 +13,14 @@
static void iol_mode_enable(struct adapter *padapter, u8 enable)
{
u8 reg_0xf0 = 0;
+ int error;
if (enable) {
/* Enable initial offload */
- reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
+ error = rtw_read8(padapter, REG_SYS_CFG, ®_0xf0);
+ if (error)
+ return;
+
rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 | SW_OFFLOAD_EN);
if (!padapter->bFWReady) {
@@ -26,7 +30,10 @@ static void iol_mode_enable(struct adapter *padapter, u8 enable)
} else {
/* disable initial offload */
- reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
+ error = rtw_read8(padapter, REG_SYS_CFG, ®_0xf0);
+ if (error)
+ return;
+
rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 & ~SW_OFFLOAD_EN);
}
}
@@ -35,19 +42,28 @@ static s32 iol_execute(struct adapter *padapter, u8 control)
{
s32 status = _FAIL;
u8 reg_0x88 = 0;
- u32 start = 0, passing_time = 0;
+ u32 start = 0;
+ int error;
control = control & 0x0f;
- reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
+ error = rtw_read8(padapter, REG_HMEBOX_E0, ®_0x88);
+ if (error)
+ return status;
+
rtw_write8(padapter, REG_HMEBOX_E0, reg_0x88 | control);
start = jiffies;
- while ((reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0)) & control &&
- (passing_time = rtw_get_passing_time_ms(start)) < 1000) {
- ;
- }
- reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
+ do {
+ error = rtw_read8(padapter, REG_HMEBOX_E0, ®_0x88);
+ if (error)
+ return status;
+ } while (reg_0x88 & control && rtw_get_passing_time_ms(start) < 1000);
+
+ error = rtw_read8(padapter, REG_HMEBOX_E0, ®_0x88);
+ if (error)
+ return status;
+
status = (reg_0x88 & control) ? _FAIL : _SUCCESS;
if (reg_0x88 & control << 4)
status = _FAIL;
@@ -195,17 +211,20 @@ static void efuse_read_phymap_from_txpktbuf(
)
{
u16 dbg_addr = 0;
- u32 start = 0, passing_time = 0;
+ u32 start = 0;
u8 reg_0x143 = 0;
__le32 lo32 = 0, hi32 = 0;
u16 len = 0, count = 0;
int i = 0;
u16 limit = *size;
-
+ int error;
u8 *pos = content;
- if (bcnhead < 0) /* if not valid */
- bcnhead = rtw_read8(adapter, REG_TDECTRL + 1);
+ if (bcnhead < 0) { /* if not valid */
+ error = rtw_read8(adapter, REG_TDECTRL + 1, (u8 *) &bcnhead);
+ if (error)
+ return;
+ }
DBG_88E("%s bcnhead:%d\n", __func__, bcnhead);
@@ -218,11 +237,21 @@ static void efuse_read_phymap_from_txpktbuf(
rtw_write8(adapter, REG_TXPKTBUF_DBG, 0);
start = jiffies;
- while (!(reg_0x143 = rtw_read8(adapter, REG_TXPKTBUF_DBG)) &&
- (passing_time = rtw_get_passing_time_ms(start)) < 1000) {
- DBG_88E("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n", __func__, reg_0x143, rtw_read8(adapter, 0x106));
+
+ do {
+ u8 tmp;
+
+ error = rtw_read8(adapter, REG_TXPKTBUF_DBG, ®_0x143);
+ if (error)
+ return;
+
+ if (!rtw_read8(adapter, 0x106, &tmp))
+ DBG_88E("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n",
+ __func__, reg_0x143, tmp);
+
rtw_usleep_os(100);
- }
+ } while (!reg_0x143 && rtw_get_passing_time_ms(start) < 1000);
+
/* data from EEPROM needs to be in LE */
lo32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L));
@@ -371,18 +400,28 @@ void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len)
static void _FWDownloadEnable(struct adapter *padapter, bool enable)
{
u8 tmp;
+ int error;
if (enable) {
/* MCU firmware download enable. */
- tmp = rtw_read8(padapter, REG_MCUFWDL);
+ error = rtw_read8(padapter, REG_MCUFWDL, &tmp);
+ if (error)
+ return;
+
rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01);
/* 8051 reset */
- tmp = rtw_read8(padapter, REG_MCUFWDL + 2);
+ error = rtw_read8(padapter, REG_MCUFWDL + 2, &tmp);
+ if (error)
+ return;
+
rtw_write8(padapter, REG_MCUFWDL + 2, tmp & 0xf7);
} else {
/* MCU firmware download disable. */
- tmp = rtw_read8(padapter, REG_MCUFWDL);
+ error = rtw_read8(padapter, REG_MCUFWDL, &tmp);
+ if (error)
+ return;
+
rtw_write8(padapter, REG_MCUFWDL, tmp & 0xfe);
/* Reserved for fw extension. */
@@ -452,8 +491,14 @@ static int _PageWrite(struct adapter *padapter, u32 page, void *buffer, u32 size
{
u8 value8;
u8 u8Page = (u8)(page & 0x07);
+ int error;
- value8 = (rtw_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | u8Page;
+ error = rtw_read8(padapter, REG_MCUFWDL + 2, &value8);
+ if (error)
+ return error;
+
+ value8 &= 0xF8;
+ value8 |= u8Page;
rtw_write8(padapter, REG_MCUFWDL + 2, value8);
return _BlockWrite(padapter, buffer, size);
@@ -493,8 +538,12 @@ static int _WriteFW(struct adapter *padapter, void *buffer, u32 size)
void _8051Reset88E(struct adapter *padapter)
{
u8 u1bTmp;
+ int error;
+
+ error = rtw_read8(padapter, REG_SYS_FUNC_EN + 1, &u1bTmp);
+ if (error)
+ return;
- u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp & (~BIT(2)));
rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp | (BIT(2)));
DBG_88E("=====> _8051Reset88E(): 8051 reset success .\n");
@@ -582,7 +631,7 @@ static int load_firmware(struct rt_firmware *pFirmware, struct device *device)
s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
{
s32 rtStatus = _SUCCESS;
- u8 writeFW_retry = 0;
+ u8 writeFW_retry = 0, tmp;
u32 fwdl_start_time;
struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
@@ -591,6 +640,7 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
u8 *pFirmwareBuf;
u32 FirmwareLen;
static int log_version;
+ int error;
if (!dvobj->firmware.szFwBuffer)
rtStatus = load_firmware(&dvobj->firmware, device);
@@ -621,7 +671,10 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
/* Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself, */
/* or it will cause download Fw fail. 2010.02.01. by tynli. */
- if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) { /* 8051 RAM code */
+ error = rtw_read8(padapter, REG_MCUFWDL, &tmp);
+ if (error) {
+ return _FAIL;
+ } else if (tmp & RAM_DL_SEL) { /* 8051 RAM code */
rtw_write8(padapter, REG_MCUFWDL, 0x00);
_8051Reset88E(padapter);
}
@@ -630,7 +683,11 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
fwdl_start_time = jiffies;
while (1) {
/* reset the FWDL chksum */
- rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL) | FWDL_ChkSum_rpt);
+ error = rtw_read8(padapter, REG_MCUFWDL, &tmp);
+ if (error)
+ return _FAIL;
+
+ rtw_write8(padapter, REG_MCUFWDL, tmp | FWDL_ChkSum_rpt);
rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen);
@@ -715,6 +772,7 @@ hal_EfusePowerSwitch_RTL8188E(
{
u8 tempval;
u16 tmpV16;
+ int error;
if (PwrState) {
rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
@@ -741,7 +799,10 @@ hal_EfusePowerSwitch_RTL8188E(
if (bWrite) {
/* Enable LDO 2.5V before read/write action */
- tempval = rtw_read8(pAdapter, EFUSE_TEST + 3);
+ error = rtw_read8(pAdapter, EFUSE_TEST + 3, &tempval);
+ if (error)
+ return;
+
tempval &= 0x0F;
tempval |= (VOLTAGE_V25 << 4);
rtw_write8(pAdapter, EFUSE_TEST + 3, (tempval | 0x80));
@@ -751,7 +812,9 @@ hal_EfusePowerSwitch_RTL8188E(
if (bWrite) {
/* Disable LDO 2.5V after read/write action */
- tempval = rtw_read8(pAdapter, EFUSE_TEST + 3);
+ error = rtw_read8(pAdapter, EFUSE_TEST + 3, &tempval);
+ if (error)
+ return;
rtw_write8(pAdapter, EFUSE_TEST + 3, (tempval & 0x7F));
}
}
@@ -1784,12 +1847,19 @@ void rtl8188e_stop_thread(struct adapter *padapter)
static void hal_notch_filter_8188e(struct adapter *adapter, bool enable)
{
+ int error;
+ u8 tmp;
+
+ error = rtw_read8(adapter, rOFDM0_RxDSP + 1, &tmp);
+ if (error)
+ return;
+
if (enable) {
DBG_88E("Enable notch filter\n");
- rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) | BIT(1));
+ rtw_write8(adapter, rOFDM0_RxDSP + 1, tmp | BIT(1));
} else {
DBG_88E("Disable notch filter\n");
- rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) & ~BIT(1));
+ rtw_write8(adapter, rOFDM0_RxDSP + 1, tmp & ~BIT(1));
}
}
void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
index 30a9dca8f453..f6d4c91a97a2 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
@@ -960,6 +960,7 @@ _PHY_SetBWMode92C(
struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter);
u8 regBwOpMode;
u8 regRRSR_RSC;
+ int error;
if (pHalData->rf_chip == RF_PSEUDO_11N)
return;
@@ -975,8 +976,13 @@ _PHY_SetBWMode92C(
/* 3<1>Set MAC register */
/* 3 */
- regBwOpMode = rtw_read8(Adapter, REG_BWOPMODE);
- regRRSR_RSC = rtw_read8(Adapter, REG_RRSR + 2);
+ error = rtw_read8(Adapter, REG_BWOPMODE, ®BwOpMode);
+ if (error)
+ return;
+
+ error = rtw_read8(Adapter, REG_RRSR + 2, ®RRSR_RSC);
+ if (error)
+ return;
switch (pHalData->CurrentChannelBW) {
case HT_CHANNEL_WIDTH_20:
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_sreset.c b/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
index 16fa249e35d3..39dacfb23570 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
@@ -49,13 +49,17 @@ void rtl8188e_sreset_linked_status_check(struct adapter *padapter)
{
u32 rx_dma_status = 0;
u8 fw_status = 0;
+ int error;
+
rx_dma_status = rtw_read32(padapter, REG_RXDMA_STATUS);
if (rx_dma_status != 0x00) {
DBG_88E("%s REG_RXDMA_STATUS:0x%08x\n", __func__, rx_dma_status);
rtw_write32(padapter, REG_RXDMA_STATUS, rx_dma_status);
}
- fw_status = rtw_read8(padapter, REG_FMETHR);
- if (fw_status != 0x00) {
+ error = rtw_read8(padapter, REG_FMETHR, &fw_status);
+ if (error) {
+ return;
+ } else if (fw_status != 0x00) {
if (fw_status == 1)
DBG_88E("%s REG_FW_STATUS (0x%02x), Read_Efuse_Fail !!\n", __func__, fw_status);
else if (fw_status == 2)
diff --git a/drivers/staging/r8188eu/hal/rtl8188eu_led.c b/drivers/staging/r8188eu/hal/rtl8188eu_led.c
index 452d4bb87aba..7f793b7ce609 100644
--- a/drivers/staging/r8188eu/hal/rtl8188eu_led.c
+++ b/drivers/staging/r8188eu/hal/rtl8188eu_led.c
@@ -14,10 +14,15 @@
void SwLedOn(struct adapter *padapter, struct LED_871x *pLed)
{
u8 LedCfg;
+ int error;
if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
return;
- LedCfg = rtw_read8(padapter, REG_LEDCFG2);
+
+ error = rtw_read8(padapter, REG_LEDCFG2, &LedCfg);
+ if (error)
+ return;
+
switch (pLed->LedPin) {
case LED_PIN_LED0:
rtw_write8(padapter, REG_LEDCFG2, (LedCfg & 0xf0) | BIT(5) | BIT(6)); /* SW control led0 on. */
@@ -37,11 +42,14 @@ void SwLedOff(struct adapter *padapter, struct LED_871x *pLed)
{
u8 LedCfg;
struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
+ int error;
if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
goto exit;
- LedCfg = rtw_read8(padapter, REG_LEDCFG2);/* 0x4E */
+ error = rtw_read8(padapter, REG_LEDCFG2, &LedCfg);/* 0x4E */
+ if (error)
+ return;
switch (pLed->LedPin) {
case LED_PIN_LED0:
@@ -49,7 +57,11 @@ void SwLedOff(struct adapter *padapter, struct LED_871x *pLed)
/* Open-drain arrangement for controlling the LED) */
LedCfg &= 0x90; /* Set to software control. */
rtw_write8(padapter, REG_LEDCFG2, (LedCfg | BIT(3)));
- LedCfg = rtw_read8(padapter, REG_MAC_PINMUX_CFG);
+
+ error = rtw_read8(padapter, REG_MAC_PINMUX_CFG, &LedCfg);
+ if (error)
+ return;
+
LedCfg &= 0xFE;
rtw_write8(padapter, REG_MAC_PINMUX_CFG, LedCfg);
} else {
diff --git a/drivers/staging/r8188eu/hal/usb_halinit.c b/drivers/staging/r8188eu/hal/usb_halinit.c
index 5cdabf43d4fd..4f1d7f9b43c3 100644
--- a/drivers/staging/r8188eu/hal/usb_halinit.c
+++ b/drivers/staging/r8188eu/hal/usb_halinit.c
@@ -120,6 +120,7 @@ static void _InitInterrupt(struct adapter *Adapter)
u32 imr, imr_ex;
u8 usb_opt;
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
+ int error;
/* HISR write one to clear */
rtw_write32(Adapter, REG_HISR_88E, 0xFFFFFFFF);
@@ -135,7 +136,9 @@ static void _InitInterrupt(struct adapter *Adapter)
/* REG_USB_SPECIAL_OPTION - BIT(4) */
/* 0; Use interrupt endpoint to upload interrupt pkt */
/* 1; Use bulk endpoint to upload interrupt pkt, */
- usb_opt = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION);
+ error = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION, &usb_opt);
+ if (error)
+ return;
if (!adapter_to_dvobj(Adapter)->ishighspeed)
usb_opt = usb_opt & (~INT_BULK_SEL);
@@ -435,8 +438,12 @@ static void _InitRxSetting(struct adapter *Adapter)
static void _InitRetryFunction(struct adapter *Adapter)
{
u8 value8;
+ int error;
+
+ error = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL, &value8);
+ if (error)
+ return;
- value8 = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL);
value8 |= EN_AMPDU_RTY_NEW;
rtw_write8(Adapter, REG_FWHW_TXQ_CTRL, value8);
@@ -499,9 +506,15 @@ usb_AggSettingRxUpdate(
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
u8 valueDMA;
u8 valueUSB;
+ int error;
- valueDMA = rtw_read8(Adapter, REG_TRXDMA_CTRL);
- valueUSB = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION);
+ error = rtw_read8(Adapter, REG_TRXDMA_CTRL, &valueDMA);
+ if (error)
+ return;
+
+ error = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION, &valueUSB);
+ if (error)
+ return;
switch (haldata->UsbRxAggMode) {
case USB_RX_AGG_DMA:
@@ -589,6 +602,7 @@ static void _InitOperationMode(struct adapter *Adapter)
static void _InitBeaconParameters(struct adapter *Adapter)
{
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
+ int error;
rtw_write16(Adapter, REG_BCN_CTRL, 0x1010);
@@ -601,11 +615,25 @@ static void _InitBeaconParameters(struct adapter *Adapter)
/* beacause test chip does not contension before sending beacon. by tynli. 2009.11.03 */
rtw_write16(Adapter, REG_BCNTCFG, 0x660F);
- haldata->RegBcnCtrlVal = rtw_read8(Adapter, REG_BCN_CTRL);
- haldata->RegTxPause = rtw_read8(Adapter, REG_TXPAUSE);
- haldata->RegFwHwTxQCtrl = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL + 2);
- haldata->RegReg542 = rtw_read8(Adapter, REG_TBTT_PROHIBIT + 2);
- haldata->RegCR_1 = rtw_read8(Adapter, REG_CR + 1);
+ error = rtw_read8(Adapter, REG_BCN_CTRL, (u8 *) &haldata->RegBcnCtrlVal);
+ if (error)
+ return;
+
+ error = rtw_read8(Adapter, REG_TXPAUSE, &haldata->RegTxPause);
+ if (error)
+ return;
+
+ error = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL + 2, &haldata->RegFwHwTxQCtrl);
+ if (error)
+ return;
+
+ error = rtw_read8(Adapter, REG_TBTT_PROHIBIT + 2, &haldata->RegReg542);
+ if (error)
+ return;
+
+ error = rtw_read8(Adapter, REG_CR + 1, &haldata->RegCR_1);
+ if (error)
+ return;
}
static void _BeaconFunctionEnable(struct adapter *Adapter,
@@ -665,14 +693,27 @@ enum rt_rf_power_state RfOnOffDetect(struct adapter *adapt)
{
u8 val8;
enum rt_rf_power_state rfpowerstate = rf_off;
+ int error;
if (adapt->pwrctrlpriv.bHWPowerdown) {
- val8 = rtw_read8(adapt, REG_HSISR);
+ error = rtw_read8(adapt, REG_HSISR, &val8);
+ if (error)
+ return rfpowerstate;
+
DBG_88E("pwrdown, 0x5c(BIT(7))=%02x\n", val8);
rfpowerstate = (val8 & BIT(7)) ? rf_off : rf_on;
} else { /* rf on/off */
- rtw_write8(adapt, REG_MAC_PINMUX_CFG, rtw_read8(adapt, REG_MAC_PINMUX_CFG) & ~(BIT(3)));
- val8 = rtw_read8(adapt, REG_GPIO_IO_SEL);
+
+ error = rtw_read8(adapt, REG_MAC_PINMUX_CFG, &val8);
+ if (error)
+ return rfpowerstate;
+
+ rtw_write8(adapt, REG_MAC_PINMUX_CFG, val8 & ~(BIT(3)));
+
+ error = rtw_read8(adapt, REG_GPIO_IO_SEL, &val8);
+ if (error)
+ return rfpowerstate;
+
DBG_88E("GPIO_IN=%02x\n", val8);
rfpowerstate = (val8 & BIT(3)) ? rf_on : rf_off;
}
@@ -689,6 +730,7 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv;
struct registry_priv *pregistrypriv = &Adapter->registrypriv;
u32 init_start_time = jiffies;
+ int error;
#define HAL_INIT_PROFILE_TAG(stage) do {} while (0)
@@ -835,7 +877,11 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
/* Enable TX Report */
/* Enable Tx Report Timer */
- value8 = rtw_read8(Adapter, REG_TX_RPT_CTRL);
+ error = rtw_read8(Adapter, REG_TX_RPT_CTRL, &value8);
+ if (error) {
+ status = _FAIL;
+ goto exit;
+ }
rtw_write8(Adapter, REG_TX_RPT_CTRL, (value8 | BIT(1) | BIT(0)));
/* Set MAX RPT MACID */
rtw_write8(Adapter, REG_TX_RPT_CTRL + 1, 2);/* FOR sta mode ,0: bc/mc ,1:AP */
@@ -962,9 +1008,13 @@ static void CardDisableRTL8188EU(struct adapter *Adapter)
{
u8 val8;
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
+ int error;
/* Stop Tx Report Timer. 0x4EC[Bit1]=b'0 */
- val8 = rtw_read8(Adapter, REG_TX_RPT_CTRL);
+ error = rtw_read8(Adapter, REG_TX_RPT_CTRL, &val8);
+ if (error)
+ return;
+
rtw_write8(Adapter, REG_TX_RPT_CTRL, val8 & (~BIT(1)));
/* stop rx */
@@ -975,10 +1025,15 @@ static void CardDisableRTL8188EU(struct adapter *Adapter)
/* 2. 0x1F[7:0] = 0 turn off RF */
- val8 = rtw_read8(Adapter, REG_MCUFWDL);
- if ((val8 & RAM_DL_SEL) && Adapter->bFWReady) { /* 8051 RAM code */
+ error = rtw_read8(Adapter, REG_MCUFWDL, &val8);
+ if (error) {
+ return;
+ } else if ((val8 & RAM_DL_SEL) && Adapter->bFWReady) { /* 8051 RAM code */
/* Reset MCU 0x2[10]=0. */
- val8 = rtw_read8(Adapter, REG_SYS_FUNC_EN + 1);
+ error = rtw_read8(Adapter, REG_SYS_FUNC_EN + 1, &val8);
+ if (error)
+ return;
+
val8 &= ~BIT(2); /* 0x2[10], FEN_CPUEN */
rtw_write8(Adapter, REG_SYS_FUNC_EN + 1, val8);
}
@@ -988,26 +1043,43 @@ static void CardDisableRTL8188EU(struct adapter *Adapter)
/* YJ,add,111212 */
/* Disable 32k */
- val8 = rtw_read8(Adapter, REG_32K_CTRL);
+ error = rtw_read8(Adapter, REG_32K_CTRL, &val8);
+ if (error)
+ return;
rtw_write8(Adapter, REG_32K_CTRL, val8 & (~BIT(0)));
/* Card disable power action flow */
HalPwrSeqCmdParsing(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, Rtl8188E_NIC_DISABLE_FLOW);
/* Reset MCU IO Wrapper */
- val8 = rtw_read8(Adapter, REG_RSV_CTRL + 1);
+ error = rtw_read8(Adapter, REG_RSV_CTRL + 1, &val8);
+ if (error)
+ return;
+
rtw_write8(Adapter, REG_RSV_CTRL + 1, (val8 & (~BIT(3))));
- val8 = rtw_read8(Adapter, REG_RSV_CTRL + 1);
+ error = rtw_read8(Adapter, REG_RSV_CTRL + 1, &val8);
+ if (error)
+ return;
rtw_write8(Adapter, REG_RSV_CTRL + 1, val8 | BIT(3));
/* YJ,test add, 111207. For Power Consumption. */
- val8 = rtw_read8(Adapter, GPIO_IN);
+ error = rtw_read8(Adapter, GPIO_IN, &val8);
+ if (error)
+ return;
+
rtw_write8(Adapter, GPIO_OUT, val8);
rtw_write8(Adapter, GPIO_IO_SEL, 0xFF);/* Reg0x46 */
- val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL);
+ error = rtw_read8(Adapter, REG_GPIO_IO_SEL, &val8);
+ if (error)
+ return;
+
rtw_write8(Adapter, REG_GPIO_IO_SEL, (val8 << 4));
- val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL + 1);
+
+ error = rtw_read8(Adapter, REG_GPIO_IO_SEL + 1, &val8);
+ if (error)
+ return;
+
rtw_write8(Adapter, REG_GPIO_IO_SEL + 1, val8 | 0x0F);/* Reg0x43 */
rtw_write32(Adapter, REG_BB_PAD_CTRL, 0x00080808);/* set LNA ,TRSW,EX_PA Pin to output mode */
haldata->bMacPwrCtrlOn = false;
@@ -1181,9 +1253,13 @@ static void _ReadPROMContent(
{
struct eeprom_priv *eeprom = GET_EEPROM_EFUSE_PRIV(Adapter);
u8 eeValue;
+ int error;
/* check system boot selection */
- eeValue = rtw_read8(Adapter, REG_9346CR);
+ error = rtw_read8(Adapter, REG_9346CR, &eeValue);
+ if (error)
+ return;
+
eeprom->EepromOrEfuse = (eeValue & BOOT_FROM_EEPROM) ? true : false;
eeprom->bautoload_fail_flag = (eeValue & EEPROM_EN) ? false : true;
@@ -1262,12 +1338,21 @@ static void hw_var_set_opmode(struct adapter *Adapter, u8 variable, u8 *val)
{
u8 val8;
u8 mode = *((u8 *)val);
+ int error;
+
+ error = rtw_read8(Adapter, REG_BCN_CTRL, &val8);
+ if (error)
+ return;
/* disable Port0 TSF update */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4));
+ rtw_write8(Adapter, REG_BCN_CTRL, val8 | BIT(4));
/* set net_type */
- val8 = rtw_read8(Adapter, MSR) & 0x0c;
+ error = rtw_read8(Adapter, MSR, &val8);
+ if (error)
+ return;
+
+ val8 &= 0x0c;
val8 |= mode;
rtw_write8(Adapter, MSR, val8);
@@ -1304,14 +1389,20 @@ static void hw_var_set_opmode(struct adapter *Adapter, u8 variable, u8 *val)
rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0));
/* BIT(3) - If set 0, hw will clr bcnq when tx becon ok/fail or port 0 */
- rtw_write8(Adapter, REG_MBID_NUM, rtw_read8(Adapter, REG_MBID_NUM) | BIT(3) | BIT(4));
+ error = rtw_read8(Adapter, REG_MBID_NUM, &val8);
+ if (error)
+ return;
+ rtw_write8(Adapter, REG_MBID_NUM, val8 | BIT(3) | BIT(4));
/* enable BCN0 Function for if1 */
/* don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received) */
rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT0_NORMAL_CHIP | EN_BCN_FUNCTION | BIT(1)));
/* dis BCN1 ATIM WND if if2 is station */
- rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1) | BIT(0));
+ error = rtw_read8(Adapter, REG_BCN_CTRL_1, &val8);
+ if (error)
+ return;
+ rtw_write8(Adapter, REG_BCN_CTRL_1, val8 | BIT(0));
}
}
@@ -1345,8 +1436,16 @@ static void hw_var_set_bcn_func(struct adapter *Adapter, u8 variable, u8 *val)
if (*((u8 *)val))
rtw_write8(Adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
- else
- rtw_write8(Adapter, bcn_ctrl_reg, rtw_read8(Adapter, bcn_ctrl_reg) & (~(EN_BCN_FUNCTION | EN_TXBCN_RPT)));
+ else {
+ u8 tmp;
+ int error;
+
+ error = rtw_read8(Adapter, bcn_ctrl_reg, &tmp);
+ if (error)
+ return;
+
+ rtw_write8(Adapter, bcn_ctrl_reg, tmp & (~(EN_BCN_FUNCTION | EN_TXBCN_RPT)));
+ }
}
static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
@@ -1354,13 +1453,19 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
struct dm_priv *pdmpriv = &haldata->dmpriv;
struct odm_dm_struct *podmpriv = &haldata->odmpriv;
+ int error;
+ u8 tmp;
switch (variable) {
case HW_VAR_MEDIA_STATUS:
{
u8 val8;
- val8 = rtw_read8(Adapter, MSR) & 0x0c;
+ error = rtw_read8(Adapter, MSR, &val8);
+ if (error)
+ return;
+
+ val8 &= 0x0c;
val8 |= *((u8 *)val);
rtw_write8(Adapter, MSR, val8);
}
@@ -1369,7 +1474,11 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
{
u8 val8;
- val8 = rtw_read8(Adapter, MSR) & 0x03;
+ error = rtw_read8(Adapter, MSR, &val8);
+ if (error)
+ return;
+
+ val8 &= 0x03;
val8 |= *((u8 *)val) << 2;
rtw_write8(Adapter, MSR, val8);
}
@@ -1407,7 +1516,12 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
/* Set RRSR rate table. */
rtw_write8(Adapter, REG_RRSR, BrateCfg & 0xff);
rtw_write8(Adapter, REG_RRSR + 1, (BrateCfg >> 8) & 0xff);
- rtw_write8(Adapter, REG_RRSR + 2, rtw_read8(Adapter, REG_RRSR + 2) & 0xf0);
+
+ error = rtw_read8(Adapter, REG_RRSR + 2, &tmp);
+ if (error)
+ return;
+
+ rtw_write8(Adapter, REG_RRSR + 2, tmp & 0xf0);
/* Set RTS initial rate */
while (BrateCfg > 0x1) {
@@ -1437,13 +1551,21 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
StopTxBeacon(Adapter);
/* disable related TSF function */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(3)));
+ error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
+ if (error)
+ return;
+
+ rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(3)));
rtw_write32(Adapter, REG_TSFTR, tsf);
rtw_write32(Adapter, REG_TSFTR + 4, tsf >> 32);
/* enable related TSF function */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(3));
+ error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
+ if (error)
+ return;
+
+ rtw_write8(Adapter, REG_BCN_CTRL, tmp | BIT(3));
if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
ResumeTxBeacon(Adapter);
@@ -1471,35 +1593,48 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
rtw_write8(Adapter, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
/* disable update TSF */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4));
+ error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
+ if (error)
+ return;
+
+ rtw_write8(Adapter, REG_BCN_CTRL, tmp | BIT(4));
break;
case HW_VAR_MLME_SITESURVEY:
if (*((u8 *)val)) { /* under sitesurvey */
/* config RCR to receive different BSSID & not to receive data frame */
u32 v = rtw_read32(Adapter, REG_RCR);
+
v &= ~(RCR_CBSSID_BCN);
rtw_write32(Adapter, REG_RCR, v);
/* reject all data frame */
rtw_write16(Adapter, REG_RXFLTMAP2, 0x00);
/* disable update TSF */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4));
+ error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
+ if (error)
+ return;
+ rtw_write8(Adapter, REG_BCN_CTRL, tmp | BIT(4));
} else { /* sitesurvey done */
struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
+ error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
+ if (error)
+ return;
+
if ((is_client_associated_to_ap(Adapter)) ||
((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) {
/* enable to rx data frame */
rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
/* enable update TSF */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4)));
+ rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(4)));
} else if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
/* enable update TSF */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4)));
+ rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(4)));
}
+
if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN);
} else {
@@ -1517,6 +1652,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
{
u8 RetryLimit = 0x30;
u8 type = *((u8 *)val);
+ u8 tmp;
struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
if (type == 0) { /* prepare to join */
@@ -1541,7 +1677,11 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
} else if (type == 2) {
/* sta add event call back */
/* enable update TSF */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4)));
+ error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
+ if (error)
+ return;
+
+ rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(4)));
if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
RetryLimit = 0x7;
@@ -1671,7 +1811,11 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
case HW_VAR_ACM_CTRL:
{
u8 acm_ctrl = *((u8 *)val);
- u8 AcmCtrl = rtw_read8(Adapter, REG_ACMHWCTRL);
+ u8 AcmCtrl;
+
+ error = rtw_read8(Adapter, REG_ACMHWCTRL, &AcmCtrl);
+ if (error)
+ return;
if (acm_ctrl > 1)
AcmCtrl = AcmCtrl | 0x1;
@@ -1699,6 +1843,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
{
u8 MinSpacingToSet;
u8 SecMinSpace;
+ u8 tmp;
MinSpacingToSet = *((u8 *)val);
if (MinSpacingToSet <= 7) {
@@ -1719,7 +1864,13 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
}
if (MinSpacingToSet < SecMinSpace)
MinSpacingToSet = SecMinSpace;
- rtw_write8(Adapter, REG_AMPDU_MIN_SPACE, (rtw_read8(Adapter, REG_AMPDU_MIN_SPACE) & 0xf8) | MinSpacingToSet);
+
+ error = rtw_read8(Adapter, REG_AMPDU_MIN_SPACE, &tmp);
+ if (error)
+ return;
+
+ rtw_write8(Adapter, REG_AMPDU_MIN_SPACE, (tmp & 0xf8) |
+ MinSpacingToSet);
}
}
break;
@@ -1868,7 +2019,13 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
break;
case HW_VAR_BCN_VALID:
/* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
- rtw_write8(Adapter, REG_TDECTRL + 2, rtw_read8(Adapter, REG_TDECTRL + 2) | BIT(0));
+ u8 tmp;
+
+ error = rtw_read8(Adapter, REG_TDECTRL + 2, &tmp);
+ if (error)
+ return;
+
+ rtw_write8(Adapter, REG_TDECTRL + 2, tmp | BIT(0));
break;
default:
break;
@@ -1880,17 +2037,23 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
{
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
struct odm_dm_struct *podmpriv = &haldata->odmpriv;
+ int error;
+ u8 tmp;
switch (variable) {
case HW_VAR_BASIC_RATE:
*((u16 *)(val)) = haldata->BasicRateSet;
fallthrough;
case HW_VAR_TXPAUSE:
- val[0] = rtw_read8(Adapter, REG_TXPAUSE);
+ error = rtw_read8(Adapter, REG_TXPAUSE, val);
break;
case HW_VAR_BCN_VALID:
/* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2 */
- val[0] = (BIT(0) & rtw_read8(Adapter, REG_TDECTRL + 2)) ? true : false;
+ error = rtw_read8(Adapter, REG_TDECTRL + 2, &tmp);
+ if (error)
+ break;
+
+ val[0] = (BIT(0) & tmp) ? true : false;
break;
case HW_VAR_DM_FLAG:
val[0] = podmpriv->SupportAbility;
@@ -2035,6 +2198,7 @@ static u8 SetHalDefVar8188EUsb(struct adapter *Adapter, enum hal_def_variable eV
{
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
u8 bResult = _SUCCESS;
+ int error;
switch (eVariable) {
case HAL_DEF_DBG_DM_FUNC:
@@ -2058,7 +2222,10 @@ static u8 SetHalDefVar8188EUsb(struct adapter *Adapter, enum hal_def_variable eV
} else if (dm_func == 6) {/* turn on all dynamic func */
if (!(podmpriv->SupportAbility & DYNAMIC_BB_DIG)) {
struct rtw_dig *pDigTable = &podmpriv->DM_DigTable;
- pDigTable->CurIGValue = rtw_read8(Adapter, 0xc50);
+
+ error = rtw_read8(Adapter, 0xc50, &pDigTable->CurIGValue);
+ if (error)
+ return _FAIL;
}
podmpriv->SupportAbility = DYNAMIC_ALL_FUNC_ENABLE;
DBG_88E("==> Turn on all dynamic function...\n");
@@ -2168,6 +2335,8 @@ static void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
u32 bcn_ctrl_reg = REG_BCN_CTRL;
+ int error;
+ u8 tmp;
/* reset TSF, enable update TSF, correcting TSF On Beacon */
/* BCN interval */
@@ -2193,7 +2362,11 @@ static void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
ResumeTxBeacon(adapt);
- rtw_write8(adapt, bcn_ctrl_reg, rtw_read8(adapt, bcn_ctrl_reg) | BIT(1));
+ error = rtw_read8(adapt, bcn_ctrl_reg, &tmp);
+ if (error)
+ return;
+
+ rtw_write8(adapt, bcn_ctrl_reg, tmp | BIT(1));
}
static void rtl8188eu_init_default_value(struct adapter *adapt)
diff --git a/drivers/staging/r8188eu/hal/usb_ops_linux.c b/drivers/staging/r8188eu/hal/usb_ops_linux.c
index 953fa05dc30c..c4f114c3d571 100644
--- a/drivers/staging/r8188eu/hal/usb_ops_linux.c
+++ b/drivers/staging/r8188eu/hal/usb_ops_linux.c
@@ -101,26 +101,28 @@ static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u16 value, void *pdata,
return status;
}
-static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr)
+static int usb_read8(struct intf_hdl *pintfhdl, u32 addr, u8 *data)
{
u8 requesttype;
u16 wvalue;
u16 len;
- u8 data = 0;
-
+ int res;
+ if (WARN_ON(unlikely(!data)))
+ return -EINVAL;
requesttype = 0x01;/* read_in */
wvalue = (u16)(addr & 0x0000ffff);
len = 1;
- usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
-
-
-
- return data;
+ res = usbctrl_vendorreq(pintfhdl, wvalue, data, len, requesttype);
+ if (res < 0) {
+ dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 8 bytes: %d\n", res);
+ return res;
+ }
+ return 0;
}
static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
diff --git a/drivers/staging/r8188eu/include/odm_interface.h b/drivers/staging/r8188eu/include/odm_interface.h
index 6b589413d56c..8e531d272927 100644
--- a/drivers/staging/r8188eu/include/odm_interface.h
+++ b/drivers/staging/r8188eu/include/odm_interface.h
@@ -60,7 +60,7 @@ typedef void (*RT_WORKITEM_CALL_BACK)(void *pContext);
/* =========== EXtern Function Prototype */
-u8 ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr);
+int ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 *data);
u16 ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr);
diff --git a/drivers/staging/r8188eu/include/rtw_io.h b/drivers/staging/r8188eu/include/rtw_io.h
index f1b3074fa075..fd99b36abca6 100644
--- a/drivers/staging/r8188eu/include/rtw_io.h
+++ b/drivers/staging/r8188eu/include/rtw_io.h
@@ -85,7 +85,7 @@ struct intf_hdl;
struct io_queue;
struct _io_ops {
- u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr);
+ int (*_read8)(struct intf_hdl *pintfhdl, u32 addr, u8 *data);
u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
@@ -248,7 +248,7 @@ void unregister_intf_hdl(struct intf_hdl *pintfhdl);
void _rtw_attrib_read(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
void _rtw_attrib_write(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
-u8 _rtw_read8(struct adapter *adapter, u32 addr);
+int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data);
u16 _rtw_read16(struct adapter *adapter, u32 addr);
u32 _rtw_read32(struct adapter *adapter, u32 addr);
void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
@@ -270,7 +270,7 @@ u32 _rtw_write_port_and_wait(struct adapter *adapter, u32 addr, u32 cnt,
u8 *pmem, int timeout_ms);
void _rtw_write_port_cancel(struct adapter *adapter);
-#define rtw_read8(adapter, addr) _rtw_read8((adapter), (addr))
+#define rtw_read8(adapter, addr, data) _rtw_read8((adapter), (addr), (data))
#define rtw_read16(adapter, addr) _rtw_read16((adapter), (addr))
#define rtw_read32(adapter, addr) _rtw_read32((adapter), (addr))
#define rtw_read_mem(adapter, addr, cnt, mem) \
diff --git a/drivers/staging/r8188eu/os_dep/ioctl_linux.c b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
index ab4a9200f079..c9f0772bcbe1 100644
--- a/drivers/staging/r8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
@@ -2074,6 +2074,7 @@ static int rtw_wx_read32(struct net_device *dev,
u32 data32;
u32 bytes;
u8 *ptmp;
+ int error;
padapter = (struct adapter *)rtw_netdev_priv(dev);
p = &wrqu->data;
@@ -2093,7 +2094,10 @@ static int rtw_wx_read32(struct net_device *dev,
switch (bytes) {
case 1:
- data32 = rtw_read8(padapter, addr);
+ error = rtw_read8(padapter, addr, (u8 *) &data32);
+ if (error)
+ return error;
+
sprintf(extra, "0x%02X", data32);
break;
case 2:
@@ -2251,6 +2255,7 @@ static void rtw_dbg_mode_hdl(struct adapter *padapter, u32 id, u8 *pdata, u32 le
u8 path;
u8 offset;
u32 value;
+ int error;
DBG_88E("%s\n", __func__);
@@ -2262,7 +2267,8 @@ static void rtw_dbg_mode_hdl(struct adapter *padapter, u32 id, u8 *pdata, u32 le
RegRWStruct = (struct mp_rw_reg *)pdata;
switch (RegRWStruct->width) {
case 1:
- RegRWStruct->value = rtw_read8(padapter, RegRWStruct->offset);
+ error = rtw_read8(padapter, RegRWStruct->offset,
+ (u8 *) &RegRWStruct->value);
break;
case 2:
RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset);
@@ -3964,6 +3970,8 @@ static int rtw_dbg_port(struct net_device *dev,
struct security_priv *psecuritypriv = &padapter->securitypriv;
struct wlan_network *cur_network = &pmlmepriv->cur_network;
struct sta_priv *pstapriv = &padapter->stapriv;
+ int error;
+ u32 tmp;
pdata = (u32 *)&wrqu->data;
@@ -3978,7 +3986,8 @@ static int rtw_dbg_port(struct net_device *dev,
case 0x70:/* read_reg */
switch (minor_cmd) {
case 1:
- DBG_88E("rtw_read8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg));
+ if (!rtw_read8(padapter, arg, (u8 *) &tmp))
+ DBG_88E("rtw_read8(0x%x) = 0x%02x\n", arg, (u8) tmp);
break;
case 2:
DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
@@ -3992,7 +4001,9 @@ static int rtw_dbg_port(struct net_device *dev,
switch (minor_cmd) {
case 1:
rtw_write8(padapter, arg, extra_arg);
- DBG_88E("rtw_write8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg));
+ if (rtw_read8(padapter, arg, (u8 *) &tmp))
+ DBG_88E("rtw_write8(0x%x) = 0x%02x\n", arg, (u8) tmp);
+
break;
case 2:
rtw_write16(padapter, arg, extra_arg);
@@ -4096,8 +4107,10 @@ static int rtw_dbg_port(struct net_device *dev,
if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
ret = -EPERM;
- final = rtw_read8(padapter, reg);
- if (start_value + write_num - 1 == final)
+ error = rtw_read8(padapter, reg, &final);
+ if (error)
+ return error;
+ else if (start_value + write_num - 1 == final)
DBG_88E("continuous IOL_CMD_WB_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
else
DBG_88E("continuous IOL_CMD_WB_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
@@ -4423,13 +4436,16 @@ static int rtw_dbg_port(struct net_device *dev,
case 0xfd:
rtw_write8(padapter, 0xc50, arg);
- DBG_88E("wr(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50));
+ DBG_88E_REG8("wr(0xc50) = 0x%x\n", padapter, 0xc50);
rtw_write8(padapter, 0xc58, arg);
- DBG_88E("wr(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58));
+ error = rtw_read8(padapter, 0xc58, (u8 *) &tmp);
+ if (error)
+ return error;
+ DBG_88E("wr(0xc58) = 0x%x\n", (u8) tmp);
break;
case 0xfe:
- DBG_88E("rd(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50));
- DBG_88E("rd(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58));
+ DBG_88E_REG8("rd(0xc50) = 0x%x\n", padapter, 0xc50);
+ DBG_88E_REG8("rd(0xc58) = 0x%x\n", padapter, 0xc58);
break;
case 0xff:
DBG_88E("dbg(0x210) = 0x%x\n", rtw_read32(padapter, 0x210));
@@ -5326,6 +5342,8 @@ static int rtw_mp_read_reg(struct net_device *dev,
char data[20], tmp[20];
u32 addr;
u32 ret, i = 0, j = 0, strtout = 0;
+ u32 val32;
+ int error;
if (!input)
return -ENOMEM;
@@ -5361,7 +5379,10 @@ static int rtw_mp_read_reg(struct net_device *dev,
switch (width) {
case 'b':
/* 1 byte */
- sprintf(extra, "%d\n", rtw_read8(padapter, addr));
+ error = rtw_read8(padapter, addr, (u8 *) &val32);
+ if (error)
+ return error;
+ sprintf(extra, "%d\n", (u8) val32);
wrqu->length = strlen(extra);
break;
case 'w':
@@ -5889,6 +5910,8 @@ static int rtw_mp_arx(struct net_device *dev,
u32 cckok = 0, cckcrc = 0, ofdmok = 0, ofdmcrc = 0, htok = 0, htcrc = 0, OFDM_FA = 0, CCK_FA = 0;
char *input = kmalloc(wrqu->length, GFP_KERNEL);
struct adapter *padapter = rtw_netdev_priv(dev);
+ int error = 0;
+ u8 tmp;
if (!input)
return -ENOMEM;
@@ -5934,13 +5957,25 @@ static int rtw_mp_arx(struct net_device *dev,
OFDM_FA = read_bbreg(padapter, 0xda4, 0x0000FFFF);
OFDM_FA = read_bbreg(padapter, 0xda4, 0xFFFF0000);
OFDM_FA = read_bbreg(padapter, 0xda8, 0x0000FFFF);
- CCK_FA = (rtw_read8(padapter, 0xa5b) << 8) | (rtw_read8(padapter, 0xa5c));
+
+ error = rtw_read8(padapter, 0xa5b, &tmp);
+ if (error)
+ goto end;
+
+ CCK_FA = tmp << 8;
+
+ error = rtw_read8(padapter, 0xa5c, &tmp);
+ if (error)
+ goto end;
+
+ CCK_FA |= tmp;
sprintf(extra, "Phy Received packet OK:%d CRC error:%d FA Counter: %d", cckok + ofdmok + htok, cckcrc + ofdmcrc + htcrc, OFDM_FA + CCK_FA);
}
wrqu->length = strlen(extra) + 1;
+end:
kfree(input);
- return 0;
+ return error;
}
static int rtw_mp_trx_query(struct net_device *dev,
--
2.32.0
ReadEFuse can fail in case of _rtw_read() failure. Callers should
handle this error to avoid uninit value bugs, since ReadEFuse
won't initialized passed pbuf in case of usb transfer failure.
To achieve it, ReadEFuseByte() now returns an int and all callers of
ReadEFuseByte() passes error code up to calltrace to rtw_usb_if1_init(),
which fails when reading regiters fails.
Signed-off-by: Pavel Skripkin <[email protected]>
---
drivers/staging/r8188eu/core/rtw_efuse.c | 45 ++++++++-----
drivers/staging/r8188eu/hal/hal_intf.c | 6 +-
.../staging/r8188eu/hal/rtl8188e_hal_init.c | 65 ++++++++++++-------
drivers/staging/r8188eu/hal/usb_halinit.c | 18 +++--
drivers/staging/r8188eu/include/hal_intf.h | 6 +-
.../staging/r8188eu/include/rtl8188e_hal.h | 2 +-
drivers/staging/r8188eu/include/rtw_efuse.h | 4 +-
drivers/staging/r8188eu/os_dep/usb_intf.c | 3 +-
8 files changed, 96 insertions(+), 53 deletions(-)
diff --git a/drivers/staging/r8188eu/core/rtw_efuse.c b/drivers/staging/r8188eu/core/rtw_efuse.c
index dfe60bc6a547..5bfcf80b2678 100644
--- a/drivers/staging/r8188eu/core/rtw_efuse.c
+++ b/drivers/staging/r8188eu/core/rtw_efuse.c
@@ -149,7 +149,7 @@ Efuse_CalculateWordCnts(u8 word_en)
/* */
/* Created by Roger, 2008.10.21. */
/* */
-void
+int
ReadEFuseByte(
struct adapter *Adapter,
u16 _offset,
@@ -163,21 +163,21 @@ ReadEFuseByte(
if (pseudo) {
Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf);
- return;
+ return 0;
}
/* Write Address */
rtw_write8(Adapter, EFUSE_CTRL + 1, (_offset & 0xff));
error = rtw_read8(Adapter, EFUSE_CTRL + 2, &readbyte);
if (error)
- return;
+ return error;
rtw_write8(Adapter, EFUSE_CTRL + 2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
/* Write bit 32 0 */
error = rtw_read8(Adapter, EFUSE_CTRL + 3, &readbyte);
if (error)
- return;
+ return error;
rtw_write8(Adapter, EFUSE_CTRL + 3, (readbyte & 0x7f));
@@ -185,12 +185,12 @@ ReadEFuseByte(
retry = 0;
error = rtw_read32(Adapter, EFUSE_CTRL, &value32);
if (error)
- return;
+ return error;
while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) {
error = rtw_read32(Adapter, EFUSE_CTRL, &value32);
if (error)
- return;
+ return error;
retry++;
}
@@ -202,9 +202,11 @@ ReadEFuseByte(
udelay(50);
error = rtw_read32(Adapter, EFUSE_CTRL, &value32);
if (error)
- return;
+ return error;
*pbuf = (u8)(value32 & 0xff);
+
+ return 0;
}
/* */
@@ -225,9 +227,9 @@ ReadEFuseByte(
/* write addr must be after sec5. */
/* */
-static void efuse_ReadEFuse(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool pseudo)
+static int efuse_ReadEFuse(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool pseudo)
{
- Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, pseudo);
+ return Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, pseudo);
}
void EFUSE_GetEfuseDefinition(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut, bool pseudo
@@ -538,6 +540,7 @@ u8 efuse_GetCurrentSize(struct adapter *padapter, u16 *size)
u8 rtw_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
{
u16 mapLen = 0;
+ int error;
EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false);
@@ -546,7 +549,9 @@ u8 rtw_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
Efuse_PowerSwitch(padapter, false, true);
- efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, false);
+ error = efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, false);
+ if (error)
+ return _FAIL;
Efuse_PowerSwitch(padapter, false, false);
@@ -556,6 +561,7 @@ u8 rtw_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
u8 rtw_BT_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
{
u16 mapLen = 0;
+ int error;
EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false);
@@ -564,7 +570,9 @@ u8 rtw_BT_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
Efuse_PowerSwitch(padapter, false, true);
- efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data, false);
+ error = efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data, false);
+ if (error)
+ return _FAIL;
Efuse_PowerSwitch(padapter, false, false);
@@ -835,17 +843,22 @@ efuse_ShadowRead4Byte(
* 11/11/2008 MHC Create Version 0.
*
*---------------------------------------------------------------------------*/
-static void Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse, bool pseudo)
+static int Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse, bool pseudo)
{
u16 mapLen = 0;
+ int error;
Efuse_PowerSwitch(pAdapter, false, true);
EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, pseudo);
- efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse, pseudo);
+ error = efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse, pseudo);
+ if (error)
+ return error;
Efuse_PowerSwitch(pAdapter, false, false);
+
+ return 0;
}
/*-----------------------------------------------------------------------------
@@ -864,7 +877,7 @@ static void Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse,
* 11/13/2008 MHC Create Version 0.
*
*---------------------------------------------------------------------------*/
-void EFUSE_ShadowMapUpdate(
+int EFUSE_ShadowMapUpdate(
struct adapter *pAdapter,
u8 efuseType,
bool pseudo)
@@ -877,7 +890,9 @@ void EFUSE_ShadowMapUpdate(
if (pEEPROM->bautoload_fail_flag)
memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen);
else
- Efuse_ReadAllMap(pAdapter, efuseType, pEEPROM->efuse_eeprom_data, pseudo);
+ return Efuse_ReadAllMap(pAdapter, efuseType, pEEPROM->efuse_eeprom_data, pseudo);
+
+ return 0;
} /* EFUSE_ShadowMapUpdate */
/*-----------------------------------------------------------------------------
diff --git a/drivers/staging/r8188eu/hal/hal_intf.c b/drivers/staging/r8188eu/hal/hal_intf.c
index a6d589e89aeb..dce9a58eaf6f 100644
--- a/drivers/staging/r8188eu/hal/hal_intf.c
+++ b/drivers/staging/r8188eu/hal/hal_intf.c
@@ -12,10 +12,12 @@ void rtw_hal_chip_configure(struct adapter *adapt)
adapt->HalFunc.intf_chip_configure(adapt);
}
-void rtw_hal_read_chip_info(struct adapter *adapt)
+int rtw_hal_read_chip_info(struct adapter *adapt)
{
if (adapt->HalFunc.read_adapter_info)
- adapt->HalFunc.read_adapter_info(adapt);
+ return adapt->HalFunc.read_adapter_info(adapt);
+
+ return _FAIL;
}
void rtw_hal_read_chip_version(struct adapter *adapt)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
index 69649a381727..41cf432398e2 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
@@ -871,7 +871,7 @@ rtl8188e_EfusePowerSwitch(
hal_EfusePowerSwitch_RTL8188E(pAdapter, bWrite, PwrState);
}
-static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
+static int Hal_EfuseReadEFuse88E(struct adapter *Adapter,
u16 _offset,
u16 _size_byte,
u8 *pbuf,
@@ -886,24 +886,26 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
u16 **eFuseWord = NULL;
u16 efuse_utilized = 0;
u8 u1temp = 0;
+ int error = 0;
/* */
/* Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */
/* */
if ((_offset + _size_byte) > EFUSE_MAP_LEN_88E) {/* total E-Fuse table is 512bytes */
DBG_88E("Hal_EfuseReadEFuse88E(): Invalid offset(%#x) with read bytes(%#x)!!\n", _offset, _size_byte);
- goto exit;
+ return -EINVAL;
}
efuseTbl = kzalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL);
if (!efuseTbl) {
DBG_88E("%s: alloc efuseTbl fail!\n", __func__);
- goto exit;
+ return -ENOMEM;
}
eFuseWord = rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
if (!eFuseWord) {
DBG_88E("%s: alloc eFuseWord fail!\n", __func__);
+ error = -ENOMEM;
goto exit;
}
@@ -916,12 +918,16 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
/* 1. Read the first byte to check if efuse is empty!!! */
/* */
/* */
- ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ if (error)
+ goto exit;
+
if (*rtemp8 != 0xFF) {
efuse_utilized++;
eFuse_Addr++;
} else {
DBG_88E("EFUSE is empty efuse_Addr-%d efuse_data =%x\n", eFuse_Addr, *rtemp8);
+ error = -EAGAIN;
goto exit;
}
@@ -933,11 +939,15 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
if ((*rtemp8 & 0x1F) == 0x0F) { /* extended header */
u1temp = ((*rtemp8 & 0xE0) >> 5);
- ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ if (error)
+ goto exit;
if ((*rtemp8 & 0x0F) == 0x0F) {
eFuse_Addr++;
- ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ if (error)
+ goto exit;
if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
eFuse_Addr++;
@@ -958,13 +968,19 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
/* Check word enable condition in the section */
if (!(wren & 0x01)) {
- ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ if (error)
+ goto exit;
+
eFuse_Addr++;
efuse_utilized++;
eFuseWord[offset][i] = (*rtemp8 & 0xff);
if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
break;
- ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ if (error)
+ goto exit;
+
eFuse_Addr++;
efuse_utilized++;
eFuseWord[offset][i] |= (((u16)*rtemp8 << 8) & 0xff00);
@@ -976,7 +992,9 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
}
/* Read next PG header */
- ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ if (error)
+ goto exit;
if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
efuse_utilized++;
@@ -1002,9 +1020,11 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
exit:
kfree(efuseTbl);
kfree(eFuseWord);
+
+ return error;
}
-static void ReadEFuseByIC(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
+static int ReadEFuseByIC(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
{
if (!bPseudoTest) {
int ret = _FAIL;
@@ -1016,28 +1036,25 @@ static void ReadEFuseByIC(struct adapter *Adapter, u8 efuseType, u16 _offset, u1
iol_mode_enable(Adapter, 0);
if (_SUCCESS == ret)
- goto exit;
+ return 0;
}
}
- Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
-
-exit:
- return;
+ return Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
}
-static void ReadEFuse_Pseudo(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
+static int ReadEFuse_Pseudo(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
{
- Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
+ return Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
}
-static void rtl8188e_ReadEFuse(struct adapter *Adapter, u8 efuseType,
+static int rtl8188e_ReadEFuse(struct adapter *Adapter, u8 efuseType,
u16 _offset, u16 _size_byte, u8 *pbuf,
bool bPseudoTest)
{
if (bPseudoTest)
- ReadEFuse_Pseudo(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
+ return ReadEFuse_Pseudo(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
else
- ReadEFuseByIC(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
+ return ReadEFuseByIC(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
}
/* Do not support BT */
@@ -2045,7 +2062,7 @@ s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy)
return status;
}
-void
+int
Hal_InitPGData88E(struct adapter *padapter)
{
struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
@@ -2053,13 +2070,15 @@ Hal_InitPGData88E(struct adapter *padapter)
if (!pEEPROM->bautoload_fail_flag) { /* autoload OK. */
if (!is_boot_from_eeprom(padapter)) {
/* Read EFUSE real map to shadow. */
- EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
+ return EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
}
} else {/* autoload fail */
/* update to default value 0xFF */
if (!is_boot_from_eeprom(padapter))
- EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
+ return EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
}
+
+ return 0;
}
void
diff --git a/drivers/staging/r8188eu/hal/usb_halinit.c b/drivers/staging/r8188eu/hal/usb_halinit.c
index 3826476e3396..687baf4d9d97 100644
--- a/drivers/staging/r8188eu/hal/usb_halinit.c
+++ b/drivers/staging/r8188eu/hal/usb_halinit.c
@@ -1296,7 +1296,7 @@ readAdapterInfo_8188EU(
_ReadLEDSetting(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag);
}
-static void _ReadPROMContent(
+static int _ReadPROMContent(
struct adapter *Adapter
)
{
@@ -1307,7 +1307,7 @@ static void _ReadPROMContent(
/* check system boot selection */
error = rtw_read8(Adapter, REG_9346CR, &eeValue);
if (error)
- return;
+ return error;
eeprom->EepromOrEfuse = (eeValue & BOOT_FROM_EEPROM) ? true : false;
eeprom->bautoload_fail_flag = (eeValue & EEPROM_EN) ? false : true;
@@ -1315,8 +1315,13 @@ static void _ReadPROMContent(
DBG_88E("Boot from %s, Autoload %s !\n", (eeprom->EepromOrEfuse ? "EEPROM" : "EFUSE"),
(eeprom->bautoload_fail_flag ? "Fail" : "OK"));
- Hal_InitPGData88E(Adapter);
+ error = Hal_InitPGData88E(Adapter);
+ if (error)
+ return error;
+
readAdapterInfo_8188EU(Adapter);
+
+ return 0;
}
static void _ReadRFType(struct adapter *Adapter)
@@ -1333,19 +1338,20 @@ static int _ReadAdapterInfo8188EU(struct adapter *Adapter)
MSG_88E("====> %s\n", __func__);
_ReadRFType(Adapter);/* rf_chip -> _InitRFType() */
- _ReadPROMContent(Adapter);
+ if (_ReadPROMContent(Adapter))
+ return _FAIL;
MSG_88E("<==== %s in %d ms\n", __func__, rtw_get_passing_time_ms(start));
return _SUCCESS;
}
-static void ReadAdapterInfo8188EU(struct adapter *Adapter)
+static int ReadAdapterInfo8188EU(struct adapter *Adapter)
{
/* Read EEPROM size before call any EEPROM function */
Adapter->EepromAddressSize = GetEEPROMSize8188E(Adapter);
- _ReadAdapterInfo8188EU(Adapter);
+ return _ReadAdapterInfo8188EU(Adapter);
}
#define GPIO_DEBUG_PORT_NUM 0
diff --git a/drivers/staging/r8188eu/include/hal_intf.h b/drivers/staging/r8188eu/include/hal_intf.h
index fa252540e596..9241af39e3a3 100644
--- a/drivers/staging/r8188eu/include/hal_intf.h
+++ b/drivers/staging/r8188eu/include/hal_intf.h
@@ -154,7 +154,7 @@ struct hal_ops {
void (*intf_chip_configure)(struct adapter *padapter);
- void (*read_adapter_info)(struct adapter *padapter);
+ int (*read_adapter_info)(struct adapter *padapter);
void (*enable_interrupt)(struct adapter *padapter);
void (*disable_interrupt)(struct adapter *padapter);
@@ -222,7 +222,7 @@ struct hal_ops {
void (*EfusePowerSwitch)(struct adapter *padapter, u8 bWrite,
u8 PwrState);
- void (*ReadEFuse)(struct adapter *padapter, u8 efuseType, u16 _offset,
+ int (*ReadEFuse)(struct adapter *padapter, u8 efuseType, u16 _offset,
u16 _size_byte, u8 *pbuf, bool bPseudoTest);
void (*EFUSEGetEfuseDefinition)(struct adapter *padapter, u8 efuseType,
u8 type, void *pOut, bool bPseudoTest);
@@ -324,7 +324,7 @@ void rtw_hal_set_hwreg(struct adapter *padapter, u8 variable, u8 *val);
void rtw_hal_get_hwreg(struct adapter *padapter, u8 variable, u8 *val);
void rtw_hal_chip_configure(struct adapter *padapter);
-void rtw_hal_read_chip_info(struct adapter *padapter);
+int rtw_hal_read_chip_info(struct adapter *padapter);
void rtw_hal_read_chip_version(struct adapter *padapter);
u8 rtw_hal_set_def_var(struct adapter *padapter,
diff --git a/drivers/staging/r8188eu/include/rtl8188e_hal.h b/drivers/staging/r8188eu/include/rtl8188e_hal.h
index 3939bf053de1..db9adbd0b024 100644
--- a/drivers/staging/r8188eu/include/rtl8188e_hal.h
+++ b/drivers/staging/r8188eu/include/rtl8188e_hal.h
@@ -410,7 +410,7 @@ s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy);
/* EFuse */
u8 GetEEPROMSize8188E(struct adapter *padapter);
-void Hal_InitPGData88E(struct adapter *padapter);
+int Hal_InitPGData88E(struct adapter *padapter);
void Hal_EfuseParseIDCode88E(struct adapter *padapter, u8 *hwinfo);
void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *hwinfo,
bool AutoLoadFail);
diff --git a/drivers/staging/r8188eu/include/rtw_efuse.h b/drivers/staging/r8188eu/include/rtw_efuse.h
index b3ff46db2091..9657b66679e3 100644
--- a/drivers/staging/r8188eu/include/rtw_efuse.h
+++ b/drivers/staging/r8188eu/include/rtw_efuse.h
@@ -113,7 +113,7 @@ u8 rtw_BT_efuse_map_write(struct adapter *adapter, u16 addr,
u16 cnts, u8 *data);
u16 Efuse_GetCurrentSize(struct adapter *adapter, u8 efusetype, bool test);
u8 Efuse_CalculateWordCnts(u8 word_en);
-void ReadEFuseByte(struct adapter *adapter, u16 _offset, u8 *pbuf, bool test);
+int ReadEFuseByte(struct adapter *adapter, u16 _offset, u8 *pbuf, bool test);
void EFUSE_GetEfuseDefinition(struct adapter *adapt, u8 type, u8 type1,
void *out, bool bPseudoTest);
u8 efuse_OneByteRead(struct adapter *adapter, u16 addr, u8 *data, bool test);
@@ -128,7 +128,7 @@ u8 Efuse_WordEnableDataWrite(struct adapter *adapter, u16 efuse_addr,
u8 word_en, u8 *data, bool test);
u8 EFUSE_Read1Byte(struct adapter *adapter, u16 address);
-void EFUSE_ShadowMapUpdate(struct adapter *adapter, u8 efusetype, bool test);
+int EFUSE_ShadowMapUpdate(struct adapter *adapter, u8 efusetype, bool test);
void EFUSE_ShadowRead(struct adapter *adapt, u8 type, u16 offset, u32 *val);
#endif
diff --git a/drivers/staging/r8188eu/os_dep/usb_intf.c b/drivers/staging/r8188eu/os_dep/usb_intf.c
index e002070f7fba..7a1a296f66b5 100644
--- a/drivers/staging/r8188eu/os_dep/usb_intf.c
+++ b/drivers/staging/r8188eu/os_dep/usb_intf.c
@@ -608,7 +608,8 @@ static struct adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj,
rtw_hal_chip_configure(padapter);
/* step read efuse/eeprom data and get mac_addr */
- rtw_hal_read_chip_info(padapter);
+ if (rtw_hal_read_chip_info(padapter) == _FAIL)
+ goto free_hal_data;
/* step 5. */
if (rtw_init_drv_sw(padapter) == _FAIL)
--
2.32.0
There are a lof of places, where DBG_88E() is used to print register
value. Since following patches change _rtw_read*() family
prototypes, we can wrap printing registers into useful macro to avoid
open-coding error checking like this:
u32 tmp;
if (!rtw_read(&tmp))
DBG("reg = %d\n", tmp);
So, added DBG_88E_REG{8,16,32} macros for printing register values.
Signed-off-by: Pavel Skripkin <[email protected]>
---
drivers/staging/r8188eu/include/rtw_debug.h | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/staging/r8188eu/include/rtw_debug.h b/drivers/staging/r8188eu/include/rtw_debug.h
index 3c3bf2a4f30e..059647b9cd3a 100644
--- a/drivers/staging/r8188eu/include/rtw_debug.h
+++ b/drivers/staging/r8188eu/include/rtw_debug.h
@@ -72,6 +72,19 @@ extern u32 GlobalDebugLevel;
pr_info(DRIVER_PREFIX __VA_ARGS__); \
} while (0)
+#define __DBG_88E_REG(fmt, adap, reg, size) \
+ do { \
+ u##size __tmp__; \
+ if (rtw_read##size((adap), (reg), &__tmp__)) \
+ break; \
+ if (_drv_err_ <= GlobalDebugLevel) \
+ pr_info(DRIVER_PREFIX fmt, __tmp__); \
+ } while (0)
+
+#define DBG_88E_REG8(fmt, adap, reg) __DBG_88E_REG(fmt, adap, reg, 8)
+#define DBG_88E_REG16(fmt, adap, reg) __DBG_88E_REG(fmt, adap, reg, 16)
+#define DBG_88E_REG32(fmt, adap, reg) __DBG_88E_REG(fmt, adap, reg, 32)
+
int proc_get_drv_version(char *page, char **start,
off_t offset, int count,
int *eof, void *data);
--
2.32.0
_rtw_read16 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_read16() 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 <[email protected]>
---
drivers/staging/r8188eu/core/rtw_debug.c | 7 +++-
drivers/staging/r8188eu/core/rtw_io.c | 9 ++---
drivers/staging/r8188eu/core/rtw_mp_ioctl.c | 4 +-
drivers/staging/r8188eu/hal/odm_interface.c | 4 +-
.../staging/r8188eu/hal/rtl8188e_hal_init.c | 29 +++++++++++----
drivers/staging/r8188eu/hal/rtl8188e_phycfg.c | 5 ++-
drivers/staging/r8188eu/hal/usb_halinit.c | 37 ++++++++++++++++---
drivers/staging/r8188eu/hal/usb_ops_linux.c | 22 +++++++++--
.../staging/r8188eu/include/odm_interface.h | 2 +-
drivers/staging/r8188eu/include/rtw_io.h | 6 +--
drivers/staging/r8188eu/os_dep/ioctl_linux.c | 28 +++++++++++---
11 files changed, 115 insertions(+), 38 deletions(-)
diff --git a/drivers/staging/r8188eu/core/rtw_debug.c b/drivers/staging/r8188eu/core/rtw_debug.c
index 8b7d3eb12bd0..a41675e101ac 100644
--- a/drivers/staging/r8188eu/core/rtw_debug.c
+++ b/drivers/staging/r8188eu/core/rtw_debug.c
@@ -91,7 +91,12 @@ int proc_get_read_reg(char *page, char **start,
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));
+ error = rtw_read16(padapter, proc_get_read_addr, (u16 *) &tmp);
+ if (error)
+ return len;
+
+ len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n",
+ proc_get_read_addr, (u16) tmp);
break;
case 4:
len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n", proc_get_read_addr, rtw_read32(padapter, proc_get_read_addr));
diff --git a/drivers/staging/r8188eu/core/rtw_io.c b/drivers/staging/r8188eu/core/rtw_io.c
index 2714506c8ffb..fd64893c778d 100644
--- a/drivers/staging/r8188eu/core/rtw_io.c
+++ b/drivers/staging/r8188eu/core/rtw_io.c
@@ -45,18 +45,15 @@ int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data)
return _read8(pintfhdl, addr, data);
}
-u16 _rtw_read16(struct adapter *adapter, u32 addr)
+int __must_check _rtw_read16(struct adapter *adapter, u32 addr, u16 *data)
{
- u16 r_val;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &pio_priv->intf;
- u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
+ int (*_read16)(struct intf_hdl *pintfhdl, u32 addr, u16 *data);
_read16 = pintfhdl->io_ops._read16;
- r_val = _read16(pintfhdl, addr);
-
- return r_val;
+ return _read16(pintfhdl, addr, data);
}
u32 _rtw_read32(struct adapter *adapter, u32 addr)
diff --git a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
index 894ab456f202..c6f7636c2174 100644
--- a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
+++ b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
@@ -653,7 +653,9 @@ int rtl8188eu_oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv)
status = NDIS_STATUS_NOT_ACCEPTED;
break;
case 2:
- RegRWStruct->value = rtw_read16(Adapter, offset);
+ error = rtw_read16(Adapter, offset, (u16 *) &RegRWStruct->value);
+ if (error)
+ status = NDIS_STATUS_NOT_ACCEPTED;
break;
default:
width = 4;
diff --git a/drivers/staging/r8188eu/hal/odm_interface.c b/drivers/staging/r8188eu/hal/odm_interface.c
index 9a9df98da727..669d3e5eafb6 100644
--- a/drivers/staging/r8188eu/hal/odm_interface.c
+++ b/drivers/staging/r8188eu/hal/odm_interface.c
@@ -10,10 +10,10 @@ int ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 *data)
return rtw_read8(Adapter, RegAddr, data);
}
-u16 ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr)
+int ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u16 *data)
{
struct adapter *Adapter = pDM_Odm->Adapter;
- return rtw_read16(Adapter, RegAddr);
+ return rtw_read16(Adapter, RegAddr, data);
}
u32 ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
index cfc429965b7d..94e2828c328e 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
@@ -262,7 +262,11 @@ static void efuse_read_phymap_from_txpktbuf(
* do not remove it as the rtw_read16() call consumes
* 2 bytes from the EEPROM source.
*/
- u16 lenc = rtw_read16(adapter, REG_PKTBUF_DBG_DATA_L);
+ u16 lenc;
+
+ error = rtw_read16(adapter, REG_PKTBUF_DBG_DATA_L, &lenc);
+ if (error)
+ return;
len = le32_to_cpu(lo32) & 0x0000ffff;
@@ -778,21 +782,27 @@ hal_EfusePowerSwitch_RTL8188E(
rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
/* 1.2V Power: From VDDON with Power Cut(0x0000h[15]), defualt valid */
- tmpV16 = rtw_read16(pAdapter, REG_SYS_ISO_CTRL);
- if (!(tmpV16 & PWC_EV12V)) {
+ error = rtw_read16(pAdapter, REG_SYS_ISO_CTRL, &tmpV16);
+ if (error) {
+ return;
+ } else if (!(tmpV16 & PWC_EV12V)) {
tmpV16 |= PWC_EV12V;
rtw_write16(pAdapter, REG_SYS_ISO_CTRL, tmpV16);
}
/* Reset: 0x0000h[28], default valid */
- tmpV16 = rtw_read16(pAdapter, REG_SYS_FUNC_EN);
- if (!(tmpV16 & FEN_ELDR)) {
+ error = rtw_read16(pAdapter, REG_SYS_FUNC_EN, &tmpV16);
+ if (error) {
+ return;
+ } else if (!(tmpV16 & FEN_ELDR)) {
tmpV16 |= FEN_ELDR;
rtw_write16(pAdapter, REG_SYS_FUNC_EN, tmpV16);
}
/* Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */
- tmpV16 = rtw_read16(pAdapter, REG_SYS_CLKR);
- if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) {
+ error = rtw_read16(pAdapter, REG_SYS_CLKR, &tmpV16);
+ if (error) {
+ return;
+ } else if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) {
tmpV16 |= (LOADER_CLK_EN | ANA8M);
rtw_write16(pAdapter, REG_SYS_CLKR, tmpV16);
}
@@ -1915,8 +1925,11 @@ u8 GetEEPROMSize8188E(struct adapter *padapter)
{
u8 size = 0;
u32 cr;
+ int error;
- cr = rtw_read16(padapter, REG_9346CR);
+ error = rtw_read16(padapter, REG_9346CR, (u16 *) &cr);
+ if (error)
+ return size;
/* 6: EEPROM used is 93C46, 4: boot from E-Fuse. */
size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
index f6d4c91a97a2..3afb66195413 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
@@ -577,11 +577,14 @@ PHY_BBConfig8188E(
struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter);
u32 RegVal;
u8 CrystalCap;
+ int error;
phy_InitBBRFRegisterDefinition(Adapter);
/* Enable BB and RF */
- RegVal = rtw_read16(Adapter, REG_SYS_FUNC_EN);
+ error = rtw_read16(Adapter, REG_SYS_FUNC_EN, (u16 *) &RegVal);
+ if (error)
+ return _FAIL;
rtw_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal | BIT(13) | BIT(0) | BIT(1)));
/* 20090923 Joseph: Advised by Steven and Jenyu. Power sequence before init RF. */
diff --git a/drivers/staging/r8188eu/hal/usb_halinit.c b/drivers/staging/r8188eu/hal/usb_halinit.c
index 4f1d7f9b43c3..4ecccc6499aa 100644
--- a/drivers/staging/r8188eu/hal/usb_halinit.c
+++ b/drivers/staging/r8188eu/hal/usb_halinit.c
@@ -90,6 +90,8 @@ static u32 rtl8188eu_InitPowerOn(struct adapter *adapt)
u16 value16;
/* HW Power on sequence */
struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
+ int error;
+
if (haldata->bMacPwrCtrlOn)
return _SUCCESS;
@@ -103,7 +105,10 @@ static u32 rtl8188eu_InitPowerOn(struct adapter *adapt)
rtw_write16(adapt, REG_CR, 0x00); /* suggseted by zhouzhou, by page, 20111230 */
/* Enable MAC DMA/WMAC/SCHEDULE/SEC block */
- value16 = rtw_read16(adapt, REG_CR);
+ error = rtw_read16(adapt, REG_CR, &value16);
+ if (error)
+ return _FAIL;
+
value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN
| PROTOCOL_EN | SCHEDULE_EN | ENSEC | CALTMR_EN);
/* for SDIO - Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy. Added by tynli. 2011.08.31. */
@@ -207,7 +212,14 @@ static void _InitNormalChipRegPriority(struct adapter *Adapter, u16 beQ,
u16 bkQ, u16 viQ, u16 voQ, u16 mgtQ,
u16 hiQ)
{
- u16 value16 = (rtw_read16(Adapter, REG_TRXDMA_CTRL) & 0x7);
+ u16 value16;
+ int error;
+
+ error = rtw_read16(Adapter, REG_TRXDMA_CTRL, &value16);
+ if (error)
+ return;
+
+ value16 &= 0x7;
value16 |= _TXDMA_BEQ_MAP(beQ) | _TXDMA_BKQ_MAP(bkQ) |
_TXDMA_VIQ_MAP(viQ) | _TXDMA_VOQ_MAP(voQ) |
@@ -868,7 +880,12 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
/* Hw bug which Hw initials RxFF boundary size to a value which is larger than the real Rx buffer size in 88E. */
/* */
/* Enable MACTXEN/MACRXEN block */
- value16 = rtw_read16(Adapter, REG_CR);
+ error = rtw_read16(Adapter, REG_CR, &value16);
+ if (error) {
+ status = _FAIL;
+ goto exit;
+ }
+
value16 |= (MACTXEN | MACRXEN);
rtw_write8(Adapter, REG_CR, value16);
@@ -937,6 +954,8 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
Adapter->mppriv.channel = haldata->CurrentChannel;
MPT_InitializeAdapter(Adapter, Adapter->mppriv.channel);
} else {
+ u16 val16;
+
/* 2010/08/11 MH Merge from 8192SE for Minicard init. We need to confirm current radio status */
/* and then decide to enable RF or not.!!!??? For Selective suspend mode. We may not */
/* call initstruct adapter. May cause some problem?? */
@@ -956,7 +975,13 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
rtw_write16(Adapter, REG_TX_RPT_TIME, 0x3DF0);
/* enable tx DMA to drop the redundate data of packet */
- rtw_write16(Adapter, REG_TXDMA_OFFSET_CHK, (rtw_read16(Adapter, REG_TXDMA_OFFSET_CHK) | DROP_DATA_EN));
+ error = rtw_read16(Adapter, REG_TXDMA_OFFSET_CHK, &val16);
+ if (error) {
+ status = _FAIL;
+ goto exit;
+ }
+
+ rtw_write16(Adapter, REG_TXDMA_OFFSET_CHK, (val16 | DROP_DATA_EN));
HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_IQK);
/* 2010/08/26 MH Merge from 8192CE. */
@@ -1982,7 +2007,9 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
rtw_write8(Adapter, REG_TXPAUSE, 0xff);
/* keep sn */
- Adapter->xmitpriv.nqos_ssn = rtw_read16(Adapter, REG_NQOS_SEQ);
+ error = rtw_read16(Adapter, REG_NQOS_SEQ, &Adapter->xmitpriv.nqos_ssn);
+ if (error)
+ return;
if (!pwrpriv->bkeepfwalive) {
/* RX DMA stop */
diff --git a/drivers/staging/r8188eu/hal/usb_ops_linux.c b/drivers/staging/r8188eu/hal/usb_ops_linux.c
index c4f114c3d571..f713ee4bdbc8 100644
--- a/drivers/staging/r8188eu/hal/usb_ops_linux.c
+++ b/drivers/staging/r8188eu/hal/usb_ops_linux.c
@@ -125,19 +125,33 @@ static int usb_read8(struct intf_hdl *pintfhdl, u32 addr, u8 *data)
return 0;
}
-static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
+static int usb_read16(struct intf_hdl *pintfhdl, u32 addr, u16 *data)
{
u8 requesttype;
u16 wvalue;
u16 len;
- __le32 data;
+ int res;
+ __le32 tmp;
+
+ if (WARN_ON(unlikely(!data)))
+ return -EINVAL;
requesttype = 0x01;/* read_in */
wvalue = (u16)(addr & 0x0000ffff);
len = 2;
- usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
+ res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
+ if (res < 0) {
+ dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 16 bytes: %d\n", res);
+ return res;
+ } else if (res != len) {
+ dev_err(dvobj_to_dev(pintfhdl->pintf_dev),
+ "Failed to read 16 bytes, could read only %d bytes\n", res);
+ return -EIO;
+ }
- return (u16)(le32_to_cpu(data) & 0xffff);
+ *data = le32_to_cpu(tmp) & 0xffff;
+
+ return 0;
}
static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
diff --git a/drivers/staging/r8188eu/include/odm_interface.h b/drivers/staging/r8188eu/include/odm_interface.h
index 8e531d272927..2455dae6eebb 100644
--- a/drivers/staging/r8188eu/include/odm_interface.h
+++ b/drivers/staging/r8188eu/include/odm_interface.h
@@ -62,7 +62,7 @@ typedef void (*RT_WORKITEM_CALL_BACK)(void *pContext);
int ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 *data);
-u16 ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr);
+int ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u16 *data);
u32 ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr);
diff --git a/drivers/staging/r8188eu/include/rtw_io.h b/drivers/staging/r8188eu/include/rtw_io.h
index fd99b36abca6..c44554c848cf 100644
--- a/drivers/staging/r8188eu/include/rtw_io.h
+++ b/drivers/staging/r8188eu/include/rtw_io.h
@@ -86,7 +86,7 @@ struct io_queue;
struct _io_ops {
int (*_read8)(struct intf_hdl *pintfhdl, u32 addr, u8 *data);
- u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
+ int (*_read16)(struct intf_hdl *pintfhdl, u32 addr, u16 *data);
u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
@@ -249,7 +249,7 @@ void _rtw_attrib_read(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
void _rtw_attrib_write(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data);
-u16 _rtw_read16(struct adapter *adapter, u32 addr);
+int __must_check _rtw_read16(struct adapter *adapter, u32 addr, u16 *data);
u32 _rtw_read32(struct adapter *adapter, u32 addr);
void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
void _rtw_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
@@ -271,7 +271,7 @@ u32 _rtw_write_port_and_wait(struct adapter *adapter, u32 addr, u32 cnt,
void _rtw_write_port_cancel(struct adapter *adapter);
#define rtw_read8(adapter, addr, data) _rtw_read8((adapter), (addr), (data))
-#define rtw_read16(adapter, addr) _rtw_read16((adapter), (addr))
+#define rtw_read16(adapter, addr, data) _rtw_read16((adapter), (addr), (data))
#define rtw_read32(adapter, addr) _rtw_read32((adapter), (addr))
#define rtw_read_mem(adapter, addr, cnt, mem) \
_rtw_read_mem((adapter), (addr), (cnt), (mem))
diff --git a/drivers/staging/r8188eu/os_dep/ioctl_linux.c b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
index c9f0772bcbe1..79f0fbaa841e 100644
--- a/drivers/staging/r8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
@@ -2101,7 +2101,10 @@ static int rtw_wx_read32(struct net_device *dev,
sprintf(extra, "0x%02X", data32);
break;
case 2:
- data32 = rtw_read16(padapter, addr);
+ error = rtw_read16(padapter, addr, (u16 *) &data32);
+ if (error)
+ return error;
+
sprintf(extra, "0x%04X", data32);
break;
case 4:
@@ -2271,7 +2274,8 @@ static void rtw_dbg_mode_hdl(struct adapter *padapter, u32 id, u8 *pdata, u32 le
(u8 *) &RegRWStruct->value);
break;
case 2:
- RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset);
+ error = rtw_read16(padapter, RegRWStruct->offset,
+ (u16 *) &RegRWStruct->value);
break;
case 4:
RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset);
@@ -3990,7 +3994,8 @@ static int rtw_dbg_port(struct net_device *dev,
DBG_88E("rtw_read8(0x%x) = 0x%02x\n", arg, (u8) tmp);
break;
case 2:
- DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
+ if (!rtw_read16(padapter, arg, (u16 *) &tmp))
+ DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, (u16) tmp);
break;
case 4:
DBG_88E("rtw_read32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
@@ -4006,8 +4011,12 @@ static int rtw_dbg_port(struct net_device *dev,
break;
case 2:
+ error = rtw_read16(padapter, arg, (u16 *) &tmp);
+ if (error)
+ return error;
+
rtw_write16(padapter, arg, extra_arg);
- DBG_88E("rtw_write16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
+ DBG_88E("rtw_write16(0x%x) = 0x%04x\n", arg, (u16) tmp);
break;
case 4:
rtw_write32(padapter, arg, extra_arg);
@@ -4138,7 +4147,10 @@ static int rtw_dbg_port(struct net_device *dev,
if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
ret = -EPERM;
- final = rtw_read16(padapter, reg);
+ error = rtw_read16(padapter, reg, &final);
+ if (error)
+ return error;
+
if (start_value + write_num - 1 == final)
DBG_88E("continuous IOL_CMD_WW_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
else
@@ -5387,7 +5399,11 @@ static int rtw_mp_read_reg(struct net_device *dev,
break;
case 'w':
/* 2 bytes */
- sprintf(data, "%04x\n", rtw_read16(padapter, addr));
+ error = rtw_read16(padapter, addr, (u16 *) &val32);
+ if (error)
+ return error;
+
+ sprintf(data, "%04x\n", (u16) val32);
for (i = 0; i <= strlen(data); i++) {
if (i % 2 == 0) {
tmp[j] = ' ';
--
2.32.0
These 2 functions are unused, so they can be simply removed
Signed-off-by: Pavel Skripkin <[email protected]>
---
drivers/staging/r8188eu/core/rtw_mp.c | 39 ------------------------
drivers/staging/r8188eu/include/rtw_mp.h | 2 --
2 files changed, 41 deletions(-)
diff --git a/drivers/staging/r8188eu/core/rtw_mp.c b/drivers/staging/r8188eu/core/rtw_mp.c
index 93bb683b628f..0a0a24fd37b0 100644
--- a/drivers/staging/r8188eu/core/rtw_mp.c
+++ b/drivers/staging/r8188eu/core/rtw_mp.c
@@ -7,45 +7,6 @@
#include "../include/odm_precomp.h"
#include "../include/rtl8188e_hal.h"
-u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz)
-{
- u32 val = 0;
-
- switch (sz) {
- case 1:
- val = rtw_read8(padapter, addr);
- break;
- case 2:
- val = rtw_read16(padapter, addr);
- break;
- case 4:
- val = rtw_read32(padapter, addr);
- break;
- default:
- val = 0xffffffff;
- break;
- }
-
- return val;
-}
-
-void write_macreg(struct adapter *padapter, u32 addr, u32 val, u32 sz)
-{
- switch (sz) {
- case 1:
- rtw_write8(padapter, addr, (u8)val);
- break;
- case 2:
- rtw_write16(padapter, addr, (u16)val);
- break;
- case 4:
- rtw_write32(padapter, addr, val);
- break;
- default:
- break;
- }
-}
-
u32 read_bbreg(struct adapter *padapter, u32 addr, u32 bitmask)
{
return rtw_hal_read_bbreg(padapter, addr, bitmask);
diff --git a/drivers/staging/r8188eu/include/rtw_mp.h b/drivers/staging/r8188eu/include/rtw_mp.h
index b64b16554343..3a259d991348 100644
--- a/drivers/staging/r8188eu/include/rtw_mp.h
+++ b/drivers/staging/r8188eu/include/rtw_mp.h
@@ -410,8 +410,6 @@ void mp_stop_test(struct adapter *padapter);
u32 _read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask);
void _write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask, u32 val);
-u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz);
-void write_macreg(struct adapter *padapter, u32 addr, u32 val, u32 sz);
u32 read_bbreg(struct adapter *padapter, u32 addr, u32 bitmask);
void write_bbreg(struct adapter *padapter, u32 addr, u32 bitmask, u32 val);
u32 read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr);
--
2.32.0
_rtw_read32 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_read32() 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 <[email protected]>
---
drivers/staging/r8188eu/core/rtw_debug.c | 61 +++++++--
drivers/staging/r8188eu/core/rtw_efuse.c | 14 ++-
drivers/staging/r8188eu/core/rtw_io.c | 9 +-
drivers/staging/r8188eu/core/rtw_mp.c | 18 ++-
drivers/staging/r8188eu/core/rtw_mp_ioctl.c | 4 +-
drivers/staging/r8188eu/core/rtw_pwrctrl.c | 5 +-
drivers/staging/r8188eu/core/rtw_sreset.c | 9 +-
.../r8188eu/hal/Hal8188ERateAdaptive.c | 8 +-
drivers/staging/r8188eu/hal/HalPhyRf_8188e.c | 2 +-
drivers/staging/r8188eu/hal/odm_interface.c | 4 +-
.../staging/r8188eu/hal/rtl8188e_hal_init.c | 63 ++++++++--
drivers/staging/r8188eu/hal/rtl8188e_phycfg.c | 12 +-
drivers/staging/r8188eu/hal/rtl8188e_sreset.c | 14 ++-
drivers/staging/r8188eu/hal/usb_halinit.c | 119 +++++++++++++++---
drivers/staging/r8188eu/hal/usb_ops_linux.c | 22 +++-
.../staging/r8188eu/include/odm_interface.h | 2 +-
drivers/staging/r8188eu/include/rtw_io.h | 6 +-
drivers/staging/r8188eu/os_dep/ioctl_linux.c | 90 ++++++++-----
18 files changed, 357 insertions(+), 105 deletions(-)
diff --git a/drivers/staging/r8188eu/core/rtw_debug.c b/drivers/staging/r8188eu/core/rtw_debug.c
index a41675e101ac..c76feb44ecfa 100644
--- a/drivers/staging/r8188eu/core/rtw_debug.c
+++ b/drivers/staging/r8188eu/core/rtw_debug.c
@@ -99,7 +99,12 @@ int proc_get_read_reg(char *page, char **start,
proc_get_read_addr, (u16) tmp);
break;
case 4:
- len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n", proc_get_read_addr, rtw_read32(padapter, proc_get_read_addr));
+ error = rtw_read32(padapter, proc_get_read_addr, &tmp);
+ if (error)
+ return len;
+
+ len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n",
+ proc_get_read_addr, tmp);
break;
default:
len += snprintf(page + len, count - len, "error read length=%d\n", proc_get_read_len);
@@ -315,13 +320,20 @@ int proc_get_mac_reg_dump1(char *page, char **start,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1;
+ int error;
+ u32 tmp;
len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
for (i = 0x0; i < 0x300; i += 4) {
if (j % 4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+ error = rtw_read32(padapter, i, &tmp);
+ if (error)
+ return len;
+
+ len += snprintf(page + len, count - len, " 0x%08x ", tmp);
if ((j++) % 4 == 0)
len += snprintf(page + len, count - len, "\n");
}
@@ -338,13 +350,20 @@ int proc_get_mac_reg_dump2(char *page, char **start,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1;
+ int error;
+ u32 tmp;
len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
memset(page, 0, count);
for (i = 0x300; i < 0x600; i += 4) {
if (j % 4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+ error = rtw_read32(padapter, i, &tmp);
+ if (error)
+ return len;
+
+ len += snprintf(page + len, count - len, " 0x%08x ", tmp);
if ((j++) % 4 == 0)
len += snprintf(page + len, count - len, "\n");
}
@@ -361,13 +380,20 @@ int proc_get_mac_reg_dump3(char *page, char **start,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1;
+ int error;
+ u32 tmp;
len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
for (i = 0x600; i < 0x800; i += 4) {
if (j % 4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+ error = rtw_read32(padapter, i, &tmp);
+ if (error)
+ return error;
+
+ len += snprintf(page + len, count - len, " 0x%08x ", tmp);
if ((j++) % 4 == 0)
len += snprintf(page + len, count - len, "\n");
}
@@ -384,12 +410,19 @@ int proc_get_bb_reg_dump1(char *page, char **start,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1;
+ int error;
+ u32 tmp;
len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
for (i = 0x800; i < 0xB00; i += 4) {
if (j % 4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+ error = rtw_read32(padapter, i, &tmp);
+ if (error)
+ return len;
+
+ len += snprintf(page + len, count - len, " 0x%08x ", tmp);
if ((j++) % 4 == 0)
len += snprintf(page + len, count - len, "\n");
}
@@ -405,12 +438,19 @@ int proc_get_bb_reg_dump2(char *page, char **start,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1;
+ int error;
+ u32 tmp;
len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
for (i = 0xB00; i < 0xE00; i += 4) {
if (j % 4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+ error = rtw_read32(padapter, i, &tmp);
+ if (error)
+ return len;
+
+ len += snprintf(page + len, count - len, " 0x%08x ", tmp);
if ((j++) % 4 == 0)
len += snprintf(page + len, count - len, "\n");
}
@@ -426,12 +466,19 @@ int proc_get_bb_reg_dump3(char *page, char **start,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1;
+ int error;
+ u32 tmp;
len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
for (i = 0xE00; i < 0x1000; i += 4) {
if (j % 4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+ error = rtw_read32(padapter, i, &tmp);
+ if (error)
+ return len;
+
+ len += snprintf(page + len, count - len, " 0x%08x ", tmp);
if ((j++) % 4 == 0)
len += snprintf(page + len, count - len, "\n");
}
diff --git a/drivers/staging/r8188eu/core/rtw_efuse.c b/drivers/staging/r8188eu/core/rtw_efuse.c
index b471f6446f78..dfe60bc6a547 100644
--- a/drivers/staging/r8188eu/core/rtw_efuse.c
+++ b/drivers/staging/r8188eu/core/rtw_efuse.c
@@ -183,9 +183,15 @@ ReadEFuseByte(
/* Check bit 32 read-ready */
retry = 0;
- value32 = rtw_read32(Adapter, EFUSE_CTRL);
+ error = rtw_read32(Adapter, EFUSE_CTRL, &value32);
+ if (error)
+ return;
+
while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) {
- value32 = rtw_read32(Adapter, EFUSE_CTRL);
+ error = rtw_read32(Adapter, EFUSE_CTRL, &value32);
+ if (error)
+ return;
+
retry++;
}
@@ -194,7 +200,9 @@ ReadEFuseByte(
/* Designer says that there shall be some delay after ready bit is set, or the */
/* result will always stay on last data we read. */
udelay(50);
- value32 = rtw_read32(Adapter, EFUSE_CTRL);
+ error = rtw_read32(Adapter, EFUSE_CTRL, &value32);
+ if (error)
+ return;
*pbuf = (u8)(value32 & 0xff);
}
diff --git a/drivers/staging/r8188eu/core/rtw_io.c b/drivers/staging/r8188eu/core/rtw_io.c
index fd64893c778d..df4d8ac8aadc 100644
--- a/drivers/staging/r8188eu/core/rtw_io.c
+++ b/drivers/staging/r8188eu/core/rtw_io.c
@@ -56,18 +56,15 @@ int __must_check _rtw_read16(struct adapter *adapter, u32 addr, u16 *data)
return _read16(pintfhdl, addr, data);
}
-u32 _rtw_read32(struct adapter *adapter, u32 addr)
+int __must_check _rtw_read32(struct adapter *adapter, u32 addr, u32 *data)
{
- u32 r_val;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &pio_priv->intf;
- u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
+ int (*_read32)(struct intf_hdl *pintfhdl, u32 addr, u32 *data);
_read32 = pintfhdl->io_ops._read32;
- r_val = _read32(pintfhdl, addr);
-
- return r_val;
+ return _read32(pintfhdl, addr, data);
}
int _rtw_write8(struct adapter *adapter, u32 addr, u8 val)
diff --git a/drivers/staging/r8188eu/core/rtw_mp.c b/drivers/staging/r8188eu/core/rtw_mp.c
index 76f0bc399819..e990e81966af 100644
--- a/drivers/staging/r8188eu/core/rtw_mp.c
+++ b/drivers/staging/r8188eu/core/rtw_mp.c
@@ -765,12 +765,17 @@ static u32 GetPhyRxPktCounts(struct adapter *pAdapter, u32 selbit)
{
/* selection */
u32 phyrx_set = 0, count = 0;
+ int error;
phyrx_set = _RXERR_RPT_SEL(selbit & 0xF);
rtw_write32(pAdapter, REG_RXERR_RPT, phyrx_set);
/* Read packet count */
- count = rtw_read32(pAdapter, REG_RXERR_RPT) & RXERR_COUNTER_MASK;
+ error = rtw_read32(pAdapter, REG_RXERR_RPT, &count);
+ if (error)
+ return count;
+
+ count &= RXERR_COUNTER_MASK;
return count;
}
@@ -803,8 +808,12 @@ u32 GetPhyRxPktCRC32Error(struct adapter *pAdapter)
static u32 rtw_GetPSDData(struct adapter *pAdapter, u32 point)
{
int psd_val;
+ int error;
+
+ error = rtw_read32(pAdapter, 0x808, &psd_val);
+ if (error)
+ return 0;
- psd_val = rtw_read32(pAdapter, 0x808);
psd_val &= 0xFFBFFC00;
psd_val |= point;
@@ -814,7 +823,10 @@ static u32 rtw_GetPSDData(struct adapter *pAdapter, u32 point)
rtw_write32(pAdapter, 0x808, psd_val);
mdelay(1);
- psd_val = rtw_read32(pAdapter, 0x8B4);
+
+ error = rtw_read32(pAdapter, 0x8B4, &psd_val);
+ if (error)
+ return 0;
psd_val &= 0x0000FFFF;
diff --git a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
index c6f7636c2174..9eaef9c73516 100644
--- a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
+++ b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
@@ -659,7 +659,9 @@ int rtl8188eu_oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv)
break;
default:
width = 4;
- RegRWStruct->value = rtw_read32(Adapter, offset);
+ error = rtw_read32(Adapter, offset, &RegRWStruct->value);
+ if (error)
+ status = NDIS_STATUS_NOT_ACCEPTED;
break;
}
diff --git a/drivers/staging/r8188eu/core/rtw_pwrctrl.c b/drivers/staging/r8188eu/core/rtw_pwrctrl.c
index c3897b29121c..4335907acbc3 100644
--- a/drivers/staging/r8188eu/core/rtw_pwrctrl.c
+++ b/drivers/staging/r8188eu/core/rtw_pwrctrl.c
@@ -55,6 +55,7 @@ int ips_leave(struct adapter *padapter)
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
int result = _SUCCESS;
int keyid;
+ u32 tmp;
_enter_pwrlock(&pwrpriv->lock);
@@ -83,7 +84,9 @@ int ips_leave(struct adapter *padapter)
}
}
- DBG_88E("==> ips_leave.....LED(0x%08x)...\n", rtw_read32(padapter, 0x4c));
+ if (!rtw_read32(padapter, 0x4c, &tmp))
+ DBG_88E("==> ips_leave.....LED(0x%08x)...\n", tmp);
+
pwrpriv->bips_processing = false;
pwrpriv->bkeepfwalive = false;
diff --git a/drivers/staging/r8188eu/core/rtw_sreset.c b/drivers/staging/r8188eu/core/rtw_sreset.c
index 8e1bc62e74e5..ec5d070e1641 100644
--- a/drivers/staging/r8188eu/core/rtw_sreset.c
+++ b/drivers/staging/r8188eu/core/rtw_sreset.c
@@ -29,13 +29,18 @@ u8 sreset_get_wifi_status(struct adapter *padapter)
{
struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
struct sreset_priv *psrtpriv = &pHalData->srestpriv;
-
+ int error;
u8 status = WIFI_STATUS_SUCCESS;
u32 val32 = 0;
if (psrtpriv->silent_reset_inprogress)
return status;
- val32 = rtw_read32(padapter, REG_TXDMA_STATUS);
+ error = rtw_read32(padapter, REG_TXDMA_STATUS, &val32);
+ if (error) {
+ psrtpriv->Wifi_Error_Status = WIFI_MAC_TXDMA_ERROR;
+ return WIFI_MAC_TXDMA_ERROR;
+ }
+
if (val32 == 0xeaeaeaea) {
psrtpriv->Wifi_Error_Status = WIFI_IF_NOT_EXIST;
} else if (val32 != 0) {
diff --git a/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c b/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c
index d873672feb27..bd4580eba0a9 100644
--- a/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c
+++ b/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c
@@ -316,19 +316,19 @@ static int odm_ARFBRefresh_8188E(struct odm_dm_struct *dm_odm, struct odm_ra_inf
pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x0000000d;
break;
case 12:
- MaskFromReg = ODM_Read4Byte(dm_odm, REG_ARFR0);
+ ODM_Read4Byte(dm_odm, REG_ARFR0, &MaskFromReg);
pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;
break;
case 13:
- MaskFromReg = ODM_Read4Byte(dm_odm, REG_ARFR1);
+ ODM_Read4Byte(dm_odm, REG_ARFR1, &MaskFromReg);
pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;
break;
case 14:
- MaskFromReg = ODM_Read4Byte(dm_odm, REG_ARFR2);
+ ODM_Read4Byte(dm_odm, REG_ARFR2, &MaskFromReg);
pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;
break;
case 15:
- MaskFromReg = ODM_Read4Byte(dm_odm, REG_ARFR3);
+ ODM_Read4Byte(dm_odm, REG_ARFR3, &MaskFromReg);
pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;
break;
default:
diff --git a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
index 3545ad60dc00..725a18dc3979 100644
--- a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
+++ b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
@@ -667,7 +667,7 @@ static void _PHY_SaveMACRegisters(
if (error)
return;
}
- MACBackup[i] = ODM_Read4Byte(dm_odm, MACReg[i]);
+ ODM_Read4Byte(dm_odm, MACReg[i], MACBackup + i);
}
static void reload_adda_reg(struct adapter *adapt, u32 *ADDAReg, u32 *ADDABackup, u32 RegiesterNum)
diff --git a/drivers/staging/r8188eu/hal/odm_interface.c b/drivers/staging/r8188eu/hal/odm_interface.c
index 669d3e5eafb6..a47319dec231 100644
--- a/drivers/staging/r8188eu/hal/odm_interface.c
+++ b/drivers/staging/r8188eu/hal/odm_interface.c
@@ -16,10 +16,10 @@ int ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u16 *data)
return rtw_read16(Adapter, RegAddr, data);
}
-u32 ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr)
+int ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u32 *data)
{
struct adapter *Adapter = pDM_Odm->Adapter;
- return rtw_read32(Adapter, RegAddr);
+ return rtw_read32(Adapter, RegAddr, data);
}
void ODM_Write1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 Data)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
index 94e2828c328e..69649a381727 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
@@ -254,8 +254,16 @@ static void efuse_read_phymap_from_txpktbuf(
/* data from EEPROM needs to be in LE */
- lo32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L));
- hi32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H));
+ error = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L, &lo32);
+ if (error)
+ return;
+ lo32 = cpu_to_le32(lo32);
+
+
+ error = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H, &hi32);
+ if (error)
+ return;
+ hi32 = cpu_to_le32(hi32);
if (i == 0) {
/* Although lenc is only used in a debug statement,
@@ -375,6 +383,8 @@ void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len)
u32 addr, rstatus, loop = 0;
u16 data_cnts = (data_len / 8) + 1;
u8 *pbuf = vzalloc(data_len + 10);
+ int error;
+
DBG_88E("###### %s ######\n", __func__);
rtw_write8(Adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
@@ -384,12 +394,25 @@ void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len)
rtw_usleep_os(2);
loop = 0;
do {
- rstatus = (reg_140 = rtw_read32(Adapter, REG_PKTBUF_DBG_CTRL) & BIT(24));
+ error = rtw_read32(Adapter, REG_PKTBUF_DBG_CTRL, ®_140);
+ if (error)
+ return;
+
+ reg_140 &= BIT(24);
+ rstatus = reg_140;
if (rstatus) {
- fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_L);
+ error = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_L,
+ &fifo_data);
+ if (error)
+ return;
+
memcpy(pbuf + (addr * 8), &fifo_data, 4);
- fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_H);
+ error = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_H,
+ &fifo_data);
+ if (error)
+ return;
+
memcpy(pbuf + (addr * 8 + 4), &fifo_data, 4);
}
rtw_usleep_os(2);
@@ -557,10 +580,14 @@ static s32 _FWFreeToGo(struct adapter *padapter)
{
u32 counter = 0;
u32 value32;
+ int error;
/* polling CheckSum report */
do {
- value32 = rtw_read32(padapter, REG_MCUFWDL);
+ error = rtw_read32(padapter, REG_MCUFWDL, &value32);
+ if (error)
+ return _FAIL;
+
if (value32 & FWDL_ChkSum_rpt)
break;
} while (counter++ < POLLING_READY_TIMEOUT_COUNT);
@@ -571,7 +598,10 @@ static s32 _FWFreeToGo(struct adapter *padapter)
}
DBG_88E("%s: Checksum report OK! REG_MCUFWDL:0x%08x\n", __func__, value32);
- value32 = rtw_read32(padapter, REG_MCUFWDL);
+ error = rtw_read32(padapter, REG_MCUFWDL, &value32);
+ if (error)
+ return _FAIL;
+
value32 |= MCUFWDL_RDY;
value32 &= ~WINTINI_RDY;
rtw_write32(padapter, REG_MCUFWDL, value32);
@@ -581,8 +611,10 @@ static s32 _FWFreeToGo(struct adapter *padapter)
/* polling for FW ready */
counter = 0;
do {
- value32 = rtw_read32(padapter, REG_MCUFWDL);
- if (value32 & WINTINI_RDY) {
+ error = rtw_read32(padapter, REG_MCUFWDL, &value32);
+ if (error) {
+ return _FAIL;
+ } else if (value32 & WINTINI_RDY) {
DBG_88E("%s: Polling FW ready success!! REG_MCUFWDL:0x%08x\n", __func__, value32);
return _SUCCESS;
}
@@ -1765,12 +1797,16 @@ static int rtl8188e_Efuse_PgPacketWrite(struct adapter *pAdapter, u8 offset, u8
static struct HAL_VERSION ReadChipVersion8188E(struct adapter *padapter)
{
u32 value32;
- struct HAL_VERSION ChipVersion;
+ struct HAL_VERSION ChipVersion = {};
struct hal_data_8188e *pHalData;
+ int error;
pHalData = GET_HAL_DATA(padapter);
- value32 = rtw_read32(padapter, REG_SYS_CFG);
+ error = rtw_read32(padapter, REG_SYS_CFG, &value32);
+ if (error)
+ return ChipVersion;
+
ChipVersion.ICType = CHIP_8188E;
ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
@@ -1949,12 +1985,15 @@ static s32 _LLTWrite(struct adapter *padapter, u32 address, u32 data)
s32 count = 0;
u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
u16 LLTReg = REG_LLT_INIT;
+ int error;
rtw_write32(padapter, LLTReg, value);
/* polling */
do {
- value = rtw_read32(padapter, LLTReg);
+ error = rtw_read32(padapter, LLTReg, &value);
+ if (error)
+ return _FAIL;
if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
break;
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
index 3afb66195413..24b2afb62d68 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
@@ -75,8 +75,12 @@ rtl8188e_PHY_QueryBBReg(
)
{
u32 ReturnValue = 0, OriginalValue, BitShift;
+ int error;
+
+ error = rtw_read32(Adapter, RegAddr, &OriginalValue);
+ if (error)
+ return ReturnValue;
- OriginalValue = rtw_read32(Adapter, RegAddr);
BitShift = phy_CalculateBitShift(BitMask);
ReturnValue = (OriginalValue & BitMask) >> BitShift;
return ReturnValue;
@@ -103,9 +107,13 @@ rtl8188e_PHY_QueryBBReg(
void rtl8188e_PHY_SetBBReg(struct adapter *Adapter, u32 RegAddr, u32 BitMask, u32 Data)
{
u32 OriginalValue, BitShift;
+ int error;
if (BitMask != bMaskDWord) { /* if not "double word" write */
- OriginalValue = rtw_read32(Adapter, RegAddr);
+ error = rtw_read32(Adapter, RegAddr, &OriginalValue);
+ if (error)
+ return;
+
BitShift = phy_CalculateBitShift(BitMask);
Data = ((OriginalValue & (~BitMask)) | (Data << BitShift));
}
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_sreset.c b/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
index 39dacfb23570..a023a0669ffd 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
@@ -14,14 +14,16 @@ void rtl8188e_sreset_xmit_status_check(struct adapter *padapter)
{
struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
struct sreset_priv *psrtpriv = &pHalData->srestpriv;
-
+ int error;
unsigned long current_time;
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
unsigned int diff_time;
u32 txdma_status;
- txdma_status = rtw_read32(padapter, REG_TXDMA_STATUS);
- if (txdma_status != 0x00) {
+ error = rtw_read32(padapter, REG_TXDMA_STATUS, &txdma_status);
+ if (error) {
+ return;
+ } else if (txdma_status != 0x00) {
DBG_88E("%s REG_TXDMA_STATUS:0x%08x\n", __func__, txdma_status);
rtw_write32(padapter, REG_TXDMA_STATUS, txdma_status);
rtl8188e_silentreset_for_specific_platform(padapter);
@@ -51,8 +53,10 @@ void rtl8188e_sreset_linked_status_check(struct adapter *padapter)
u8 fw_status = 0;
int error;
- rx_dma_status = rtw_read32(padapter, REG_RXDMA_STATUS);
- if (rx_dma_status != 0x00) {
+ error = rtw_read32(padapter, REG_RXDMA_STATUS, &rx_dma_status);
+ if (error) {
+ return;
+ } else if (rx_dma_status != 0x00) {
DBG_88E("%s REG_RXDMA_STATUS:0x%08x\n", __func__, rx_dma_status);
rtw_write32(padapter, REG_RXDMA_STATUS, rx_dma_status);
}
diff --git a/drivers/staging/r8188eu/hal/usb_halinit.c b/drivers/staging/r8188eu/hal/usb_halinit.c
index 4ecccc6499aa..3826476e3396 100644
--- a/drivers/staging/r8188eu/hal/usb_halinit.c
+++ b/drivers/staging/r8188eu/hal/usb_halinit.c
@@ -338,8 +338,12 @@ static void _InitQueuePriority(struct adapter *Adapter)
static void _InitNetworkType(struct adapter *Adapter)
{
u32 value32;
+ int error;
+
+ error = rtw_read32(Adapter, REG_CR, &value32);
+ if (error)
+ return;
- value32 = rtw_read32(Adapter, REG_CR);
/* TODO: use the other function to set network type */
value32 = (value32 & ~MASK_NETTYPE) | _NETTYPE(NT_LINK_AP);
@@ -381,9 +385,13 @@ static void _InitAdaptiveCtrl(struct adapter *Adapter)
{
u16 value16;
u32 value32;
+ int error;
/* Response Rate Set */
- value32 = rtw_read32(Adapter, REG_RRSR);
+ error = rtw_read32(Adapter, REG_RRSR, &value32);
+ if (error)
+ return;
+
value32 &= ~RATE_BITMAP_ALL;
value32 |= RATE_RRSR_CCK_ONLY_1M;
rtw_write32(Adapter, REG_RRSR, value32);
@@ -482,12 +490,16 @@ static void usb_AggSettingTxUpdate(struct adapter *Adapter)
{
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
u32 value32;
+ int error;
if (Adapter->registrypriv.wifi_spec)
haldata->UsbTxAggMode = false;
if (haldata->UsbTxAggMode) {
- value32 = rtw_read32(Adapter, REG_TDECTRL);
+ error = rtw_read32(Adapter, REG_TDECTRL, &value32);
+ if (error)
+ return;
+
value32 = value32 & ~(BLK_DESC_NUM_MASK << BLK_DESC_NUM_SHIFT);
value32 |= ((haldata->UsbTxAggDescNum & BLK_DESC_NUM_MASK) << BLK_DESC_NUM_SHIFT);
@@ -671,12 +683,18 @@ enum {
static void _InitAntenna_Selection(struct adapter *Adapter)
{
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
+ u32 val32;
+ int error;
if (haldata->AntDivCfg == 0)
return;
DBG_88E("==> %s ....\n", __func__);
- rtw_write32(Adapter, REG_LEDCFG0, rtw_read32(Adapter, REG_LEDCFG0) | BIT(23));
+ error = rtw_read32(Adapter, REG_LEDCFG0, &val32);
+ if (error)
+ return;
+
+ rtw_write32(Adapter, REG_LEDCFG0, val32 | BIT(23));
PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, BIT(13), 0x01);
if (PHY_QueryBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, 0x300) == Antenna_A)
@@ -737,7 +755,7 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
u8 value8 = 0;
u16 value16;
u8 txpktbuf_bndy;
- u32 status = _SUCCESS;
+ u32 status = _SUCCESS, val32;
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv;
struct registry_priv *pregistrypriv = &Adapter->registrypriv;
@@ -1007,7 +1025,13 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
rtw_write8(Adapter, REG_USB_HRPWM, 0);
/* ack for xmit mgmt frames. */
- rtw_write32(Adapter, REG_FWHW_TXQ_CTRL, rtw_read32(Adapter, REG_FWHW_TXQ_CTRL) | BIT(12));
+ error = rtw_read32(Adapter, REG_FWHW_TXQ_CTRL, &val32);
+ if (error) {
+ status = _FAIL;
+ goto exit;
+ }
+
+ rtw_write32(Adapter, REG_FWHW_TXQ_CTRL, val32 | BIT(12));
exit:
HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_END);
@@ -1480,6 +1504,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
struct odm_dm_struct *podmpriv = &haldata->odmpriv;
int error;
u8 tmp;
+ u32 val32;
switch (variable) {
case HW_VAR_MEDIA_STATUS:
@@ -1598,11 +1623,17 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
break;
case HW_VAR_CHECK_BSSID:
if (*((u8 *)val)) {
- rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+ error = rtw_read32(Adapter, REG_RCR, &val32);
+ if (error)
+ return;
+
+ rtw_write32(Adapter, REG_RCR, val32 | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
} else {
u32 val32;
- val32 = rtw_read32(Adapter, REG_RCR);
+ error = rtw_read32(Adapter, REG_RCR, &val32);
+ if (error)
+ return;
val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
@@ -1627,7 +1658,11 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
case HW_VAR_MLME_SITESURVEY:
if (*((u8 *)val)) { /* under sitesurvey */
/* config RCR to receive different BSSID & not to receive data frame */
- u32 v = rtw_read32(Adapter, REG_RCR);
+ u32 v;
+
+ error = rtw_read32(Adapter, REG_RCR, &v);
+ if (error)
+ return;
v &= ~(RCR_CBSSID_BCN);
rtw_write32(Adapter, REG_RCR, v);
@@ -1661,14 +1696,27 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
}
if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
- rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN);
+ error = rtw_read32(Adapter, REG_RCR, &val32);
+ if (error)
+ return;
+
+ rtw_write32(Adapter, REG_RCR, val32 | RCR_CBSSID_BCN);
} else {
+ u32 v;
+
if (Adapter->in_cta_test) {
- u32 v = rtw_read32(Adapter, REG_RCR);
+ error = rtw_read32(Adapter, REG_RCR, &v);
+ if (error)
+ return;
+
v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* RCR_ADF */
rtw_write32(Adapter, REG_RCR, v);
} else {
- rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN);
+ error = rtw_read32(Adapter, REG_RCR, &v);
+ if (error)
+ return;
+
+ rtw_write32(Adapter, REG_RCR, v | RCR_CBSSID_BCN);
}
}
}
@@ -1679,17 +1727,26 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
u8 type = *((u8 *)val);
u8 tmp;
struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
+ u32 v;
if (type == 0) { /* prepare to join */
/* enable to rx data frame.Accept all data frame */
rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
if (Adapter->in_cta_test) {
- u32 v = rtw_read32(Adapter, REG_RCR);
+ error = rtw_read32(Adapter, REG_RCR, &v);
+ if (error)
+ return;
+
v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* RCR_ADF */
rtw_write32(Adapter, REG_RCR, v);
} else {
- rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+ error = rtw_read32(Adapter, REG_RCR, &v);
+ if (error)
+ return;
+
+ rtw_write32(Adapter, REG_RCR,
+ v | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
}
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
@@ -2002,6 +2059,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
{
struct pwrctrl_priv *pwrpriv = &Adapter->pwrctrlpriv;
u8 trycnt = 100;
+ u32 v;
/* pause tx */
rtw_write8(Adapter, REG_TXPAUSE, 0xff);
@@ -2013,9 +2071,18 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
if (!pwrpriv->bkeepfwalive) {
/* RX DMA stop */
- rtw_write32(Adapter, REG_RXPKT_NUM, (rtw_read32(Adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
+
+ error = rtw_read32(Adapter, REG_RXPKT_NUM, &v);
+ if (error)
+ return;
+
+ rtw_write32(Adapter, REG_RXPKT_NUM, (v | RW_RELEASE_EN));
do {
- if (!(rtw_read32(Adapter, REG_RXPKT_NUM) & RXDMA_IDLE))
+ error = rtw_read32(Adapter, REG_RXPKT_NUM, &v);
+ if (error)
+ return;
+
+ if (!(v & RXDMA_IDLE))
break;
} while (trycnt--);
if (trycnt == 0)
@@ -2066,6 +2133,7 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
struct odm_dm_struct *podmpriv = &haldata->odmpriv;
int error;
u8 tmp;
+ u32 val32;
switch (variable) {
case HW_VAR_BASIC_RATE:
@@ -2097,7 +2165,13 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
val[0] = true;
} else {
u32 valRCR;
- valRCR = rtw_read32(Adapter, REG_RCR);
+
+ error = rtw_read32(Adapter, REG_RCR, &valRCR);
+ if (error) {
+ *val = false;
+ return;
+ }
+
valRCR &= 0x00070000;
if (valRCR)
val[0] = false;
@@ -2116,7 +2190,11 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
*val = haldata->bMacPwrCtrlOn;
break;
case HW_VAR_CHK_HI_QUEUE_EMPTY:
- *val = ((rtw_read32(Adapter, REG_HGQ_INFORMATION) & 0x0000ff00) == 0) ? true : false;
+ error = rtw_read32(Adapter, REG_HGQ_INFORMATION, &val32);
+ if (error || val32 & 0x0000ff00)
+ *val = false;
+ else
+ *val = true;
break;
default:
break;
@@ -2374,7 +2452,10 @@ static void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
rtw_write8(adapt, REG_SLOT, 0x09);
- value32 = rtw_read32(adapt, REG_TCR);
+ error = rtw_read32(adapt, REG_TCR, &value32);
+ if (error)
+ return;
+
value32 &= ~TSFRST;
rtw_write32(adapt, REG_TCR, value32);
diff --git a/drivers/staging/r8188eu/hal/usb_ops_linux.c b/drivers/staging/r8188eu/hal/usb_ops_linux.c
index f713ee4bdbc8..b82dd3e16200 100644
--- a/drivers/staging/r8188eu/hal/usb_ops_linux.c
+++ b/drivers/staging/r8188eu/hal/usb_ops_linux.c
@@ -154,21 +154,35 @@ static int usb_read16(struct intf_hdl *pintfhdl, u32 addr, u16 *data)
return 0;
}
-static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
+static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
{
u8 requesttype;
u16 wvalue;
u16 len;
- __le32 data;
+ int res;
+ __le32 tmp;
+
+ if (WARN_ON(unlikely(!data)))
+ return -EINVAL;
requesttype = 0x01;/* read_in */
wvalue = (u16)(addr & 0x0000ffff);
len = 4;
- usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
+ res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
+ if (res < 0) {
+ dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
+ return res;
+ } else if (res != len) {
+ dev_err(dvobj_to_dev(pintfhdl->pintf_dev),
+ "Failed to read 32 bytes, could read only %d bytes\n", res);
+ return -EIO;
+ }
+
+ *data = le32_to_cpu(tmp);
- return le32_to_cpu(data);
+ return 0;
}
static int usb_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val)
diff --git a/drivers/staging/r8188eu/include/odm_interface.h b/drivers/staging/r8188eu/include/odm_interface.h
index 2455dae6eebb..bbb1045c9e7d 100644
--- a/drivers/staging/r8188eu/include/odm_interface.h
+++ b/drivers/staging/r8188eu/include/odm_interface.h
@@ -64,7 +64,7 @@ int ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 *data);
int ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u16 *data);
-u32 ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr);
+int ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u32 *data);
void ODM_Write1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 Data);
diff --git a/drivers/staging/r8188eu/include/rtw_io.h b/drivers/staging/r8188eu/include/rtw_io.h
index c44554c848cf..501168457518 100644
--- a/drivers/staging/r8188eu/include/rtw_io.h
+++ b/drivers/staging/r8188eu/include/rtw_io.h
@@ -87,7 +87,7 @@ struct io_queue;
struct _io_ops {
int (*_read8)(struct intf_hdl *pintfhdl, u32 addr, u8 *data);
int (*_read16)(struct intf_hdl *pintfhdl, u32 addr, u16 *data);
- u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
+ int (*_read32)(struct intf_hdl *pintfhdl, u32 addr, u32 *data);
int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
@@ -250,7 +250,7 @@ void _rtw_attrib_write(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data);
int __must_check _rtw_read16(struct adapter *adapter, u32 addr, u16 *data);
-u32 _rtw_read32(struct adapter *adapter, u32 addr);
+int __must_check _rtw_read32(struct adapter *adapter, u32 addr, u32 *data);
void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
void _rtw_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
void _rtw_read_port_cancel(struct adapter *adapter);
@@ -272,7 +272,7 @@ void _rtw_write_port_cancel(struct adapter *adapter);
#define rtw_read8(adapter, addr, data) _rtw_read8((adapter), (addr), (data))
#define rtw_read16(adapter, addr, data) _rtw_read16((adapter), (addr), (data))
-#define rtw_read32(adapter, addr) _rtw_read32((adapter), (addr))
+#define rtw_read32(adapter, addr, data) _rtw_read32((adapter), (addr), (data))
#define rtw_read_mem(adapter, addr, cnt, mem) \
_rtw_read_mem((adapter), (addr), (cnt), (mem))
#define rtw_read_port(adapter, addr, cnt, mem) \
diff --git a/drivers/staging/r8188eu/os_dep/ioctl_linux.c b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
index 79f0fbaa841e..65b240d6c544 100644
--- a/drivers/staging/r8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
@@ -2108,7 +2108,10 @@ static int rtw_wx_read32(struct net_device *dev,
sprintf(extra, "0x%04X", data32);
break;
case 4:
- data32 = rtw_read32(padapter, addr);
+ error = rtw_read32(padapter, addr, &data32);
+ if (error)
+ return error;
+
sprintf(extra, "0x%08X", data32);
break;
default:
@@ -2278,7 +2281,7 @@ static void rtw_dbg_mode_hdl(struct adapter *padapter, u32 id, u8 *pdata, u32 le
(u16 *) &RegRWStruct->value);
break;
case 4:
- RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset);
+ error = rtw_read32(padapter, RegRWStruct->offset, &RegRWStruct->value);
break;
default:
break;
@@ -3818,6 +3821,8 @@ static int rtw_cta_test_start(struct net_device *dev,
{
int ret = 0;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+ int error;
+
DBG_88E("%s %s\n", __func__, extra);
if (!strcmp(extra, "1"))
padapter->in_cta_test = 1;
@@ -3825,12 +3830,22 @@ static int rtw_cta_test_start(struct net_device *dev,
padapter->in_cta_test = 0;
if (padapter->in_cta_test) {
- u32 v = rtw_read32(padapter, REG_RCR);
+ u32 v;
+
+ error = rtw_read32(padapter, REG_RCR, &v);
+ if (error)
+ return error;
+
v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* RCR_ADF */
rtw_write32(padapter, REG_RCR, v);
DBG_88E("enable RCR_ADF\n");
} else {
- u32 v = rtw_read32(padapter, REG_RCR);
+ u32 v;
+
+ error = rtw_read32(padapter, REG_RCR, &v);
+ if (error)
+ return error;
+
v |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;/* RCR_ADF */
rtw_write32(padapter, REG_RCR, v);
DBG_88E("disable RCR_ADF\n");
@@ -3900,18 +3915,23 @@ static int rtw_rereg_nd_name(struct net_device *dev,
static void mac_reg_dump(struct adapter *padapter)
{
int i, j = 1;
+
pr_info("\n ======= MAC REG =======\n");
for (i = 0x0; i < 0x300; i += 4) {
if (j % 4 == 1)
pr_info("0x%02x", i);
- pr_info(" 0x%08x ", rtw_read32(padapter, i));
+
+ DBG_88E_REG32(" 0x%08x ", padapter, i);
+
if ((j++) % 4 == 0)
pr_info("\n");
}
for (i = 0x400; i < 0x800; i += 4) {
if (j % 4 == 1)
pr_info("0x%02x", i);
- pr_info(" 0x%08x ", rtw_read32(padapter, i));
+
+ DBG_88E_REG32(" 0x%08x ", padapter, i);
+
if ((j++) % 4 == 0)
pr_info("\n");
}
@@ -3920,12 +3940,14 @@ static void mac_reg_dump(struct adapter *padapter)
static void bb_reg_dump(struct adapter *padapter)
{
int i, j = 1;
+
pr_info("\n ======= BB REG =======\n");
for (i = 0x800; i < 0x1000; i += 4) {
if (j % 4 == 1)
pr_info("0x%02x", i);
- pr_info(" 0x%08x ", rtw_read32(padapter, i));
+ DBG_88E_REG32(" 0x%08x ", padapter, i);
+
if ((j++) % 4 == 0)
pr_info("\n");
}
@@ -3998,7 +4020,8 @@ static int rtw_dbg_port(struct net_device *dev,
DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, (u16) tmp);
break;
case 4:
- DBG_88E("rtw_read32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
+ if (!rtw_read32(padapter, arg, &val32))
+ DBG_88E("rtw_read32(0x%x) = 0x%08x\n", arg, val32);
break;
}
break;
@@ -4020,7 +4043,9 @@ static int rtw_dbg_port(struct net_device *dev,
break;
case 4:
rtw_write32(padapter, arg, extra_arg);
- DBG_88E("rtw_write32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
+
+ if (!rtw_read32(padapter, arg, &val32))
+ DBG_88E("rtw_write32(0x%x) = 0x%08x\n", arg, val32);
break;
}
break;
@@ -4178,7 +4203,10 @@ static int rtw_dbg_port(struct net_device *dev,
if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
ret = -EPERM;
- final = rtw_read32(padapter, reg);
+ error = rtw_read32(padapter, reg, &final);
+ if (error)
+ break;
+
if (start_value + write_num - 1 == final)
DBG_88E("continuous IOL_CMD_WD_REG to 0x%x %u times Success, start:%u, final:%u\n",
reg, write_num, start_value, final);
@@ -4460,30 +4488,30 @@ static int rtw_dbg_port(struct net_device *dev,
DBG_88E_REG8("rd(0xc58) = 0x%x\n", padapter, 0xc58);
break;
case 0xff:
- DBG_88E("dbg(0x210) = 0x%x\n", rtw_read32(padapter, 0x210));
- DBG_88E("dbg(0x608) = 0x%x\n", rtw_read32(padapter, 0x608));
- DBG_88E("dbg(0x280) = 0x%x\n", rtw_read32(padapter, 0x280));
- DBG_88E("dbg(0x284) = 0x%x\n", rtw_read32(padapter, 0x284));
- DBG_88E("dbg(0x288) = 0x%x\n", rtw_read32(padapter, 0x288));
+ DBG_88E_REG32("dbg(0x210) = 0x%x\n", padapter, 0x210);
+ DBG_88E_REG32("dbg(0x608) = 0x%x\n", padapter, 0x608);
+ DBG_88E_REG32("dbg(0x280) = 0x%x\n", padapter, 0x280);
+ DBG_88E_REG32("dbg(0x284) = 0x%x\n", padapter, 0x284);
+ DBG_88E_REG32("dbg(0x288) = 0x%x\n", padapter, 0x288);
- DBG_88E("dbg(0x664) = 0x%x\n", rtw_read32(padapter, 0x664));
+ DBG_88E_REG32("dbg(0x664) = 0x%x\n", padapter, 0x664);
DBG_88E("\n");
- DBG_88E("dbg(0x430) = 0x%x\n", rtw_read32(padapter, 0x430));
- DBG_88E("dbg(0x438) = 0x%x\n", rtw_read32(padapter, 0x438));
+ DBG_88E_REG32("dbg(0x430) = 0x%x\n", padapter, 0x430);
+ DBG_88E_REG32("dbg(0x438) = 0x%x\n", padapter, 0x438);
- DBG_88E("dbg(0x440) = 0x%x\n", rtw_read32(padapter, 0x440));
+ DBG_88E_REG32("dbg(0x440) = 0x%x\n", padapter, 0x440);
- DBG_88E("dbg(0x458) = 0x%x\n", rtw_read32(padapter, 0x458));
+ DBG_88E_REG32("dbg(0x458) = 0x%x\n", padapter, 0x458);
- DBG_88E("dbg(0x484) = 0x%x\n", rtw_read32(padapter, 0x484));
- DBG_88E("dbg(0x488) = 0x%x\n", rtw_read32(padapter, 0x488));
+ DBG_88E_REG32("dbg(0x484) = 0x%x\n", padapter, 0x484);
+ DBG_88E_REG32("dbg(0x488) = 0x%x\n", padapter, 0x488);
- DBG_88E("dbg(0x444) = 0x%x\n", rtw_read32(padapter, 0x444));
- DBG_88E("dbg(0x448) = 0x%x\n", rtw_read32(padapter, 0x448));
- DBG_88E("dbg(0x44c) = 0x%x\n", rtw_read32(padapter, 0x44c));
- DBG_88E("dbg(0x450) = 0x%x\n", rtw_read32(padapter, 0x450));
+ DBG_88E_REG32("dbg(0x444) = 0x%x\n", padapter, 0x444);
+ DBG_88E_REG32("dbg(0x448) = 0x%x\n", padapter, 0x448);
+ DBG_88E_REG32("dbg(0x44c) = 0x%x\n", padapter, 0x44c);
+ DBG_88E_REG32("dbg(0x450) = 0x%x\n", padapter, 0x450);
break;
}
break;
@@ -5434,7 +5462,11 @@ static int rtw_mp_read_reg(struct net_device *dev,
break;
case 'd':
/* 4 bytes */
- sprintf(data, "%08x", rtw_read32(padapter, addr));
+ error = rtw_read32(padapter, addr, &val32);
+ if (error)
+ return error;
+
+ sprintf(data, "%08x", val32);
/* add read data format blank */
for (i = 0; i <= strlen(data); i++) {
if (i % 2 == 0) {
@@ -6154,14 +6186,14 @@ static int rtw_mp_dump(struct net_device *dev,
for (i = 0x0; i < 0x300; i += 4) {
if (j % 4 == 1)
DBG_88E("0x%02x", i);
- DBG_88E(" 0x%08x ", rtw_read32(padapter, i));
+ DBG_88E_REG32(" 0x%08x ", padapter, i);
if ((j++) % 4 == 0)
DBG_88E("\n");
}
for (i = 0x400; i < 0x1000; i += 4) {
if (j % 4 == 1)
DBG_88E("0x%02x", i);
- DBG_88E(" 0x%08x ", rtw_read32(padapter, i));
+ DBG_88E_REG32(" 0x%08x ", padapter, i);
if ((j++) % 4 == 0)
DBG_88E("\n");
}
--
2.32.0
On Tuesday, August 24, 2021 8:40:18 AM CEST Pavel Skripkin wrote:
> On 8/24/21 3:10 AM, Fabio M. De Francesco wrote:
> > On Tuesday, August 24, 2021 1:33:46 AM CEST Phillip Potter wrote:
> >> On Sun, 22 Aug 2021 at 15:36, Pavel Skripkin <[email protected]> wrote:
> >> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> >> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
> >> > {
> >> > u8 requesttype;
> >> > u16 wvalue;
> >> > u16 len;
> >> > - __le32 data;
> >> > + int res;
> >> > + __le32 tmp;
> >> > +
> >> > + if (WARN_ON(unlikely(!data)))
> >> > + return -EINVAL;
> >> >
> >> > requesttype = 0x01;/* read_in */
> >> >
> >> > wvalue = (u16)(addr & 0x0000ffff);
> >> > len = 4;
> >> >
> >> > - usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >> > + res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >> > + if (res < 0) {
> >> > + dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
> >> > + } else {
> >> > + /* Noone cares about positive return value */
> >> > + *data = le32_to_cpu(tmp);
> >> > + res = 0;
> >> > + }
> >> >
> >> > - return le32_to_cpu(data);
> >> > + return res;
> >> > }
> >>
> >> Dear Pavel,
> >>
> >> OK, found the issue with decoded stack trace after reviewing this
> >> usb_read32 function. Your line:
> >> res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >>
> >> should read:
> >> res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
> >
> > Dear Philip,
> >
> > No, it should read:
> >
> > res = usbctrl_vendorreq(pintfhdl, wvalue, data, len, requesttype);
> >
> > I suspect that Pavel didn't notice he was reusing a line of the old code
> > wth no due changes.
> >
> >> With this change, the driver runs fine with no crashes/oopses. I will
> >> explain the issue but you can probably see already, so I hope I'm not
> >> coming across as patronising, just trying to be helpful :-)
> >>
> >> Essentially, you are taking the address of the data function parameter
> >> on this line with &data, a pointer to u32, which is giving you a
> >> pointer to a pointer to u32 (u32 **) for this function parameter
> >> variable. When passed to usbctrl_vendorreq, it is being passed to
> >> memcpy inside this function as a void *, meaning that memcpy
> >> subsequently overwrites the value of the memory address inside data to
> >> point to a different location, which is problem when it is later
> >> deferenced at:
> >> *data = le32_to_cpu(tmp);
> >> causing the OOPS
> >>
> >> Also, as written, you can probably see that tmp is uninitialised. This
> >> looks like a typo, so guessing this wasn't your intention. Anyhow,
> >> with that small change, usbctrl_vendorreq reads into tmp, which is
> >> then passed to le32_to_cpu whose return value is stored via the
> >> deferenced data ptr (which now has its original address within and not
> >> inadvertently modified). Hope this helps, and I'd be happy to Ack the
> >> series if you want to resend this patch. Many thanks.
> >
> > I think that another typo is having 'tmp', because that variable is unnecessary
> > and "*data = le32_to_cpu(tmp);" is wrong too.
> >
> > Now I also see that also usb_read16() is wrong, while usb_read8() (the one that
> > I had read yesterday) is the only correct function of the three usb_read*().
> >
>
> Hi, guys!
>
>
> Sorry for breaking your system, Phillip. This code was part of "last
> minute" changes and yes, it's broken :)
>
> I get what Phillip said, because I _should_ read into tmp variable
> instead of directly to data, but I don't get Fabio's idea, sorry.
Hi Pavel,
I (wrongly?) assumed from the prototype of usb_read32() that u32 *data is in native
endianness. So, I didn't see the necessity of using _le32 tmp and then convert that tmp
with le32_to_cpu().
I simply thought that data could be passed to usbctrl_vendorreq as it-is.
> Data from chip comes in little-endian, so we _should_ convert it to
> cpu's endian. Temp variable is needed to make smatch and all other
> static anylis tools happy about this code.
Now that you explained that "Data from chip comes in little-endian", obviously
I must agree with you that the code needs tmp and that tmp must be
swapped by le32_to_cpu(), ahead of assigning it to *data.
Just a curiosity... Since I was not able to see that *data is returned in little endian,
can you please point me where in the code you found out that it is? There must
be some place in the code that I'm unable to find and see that *data is LE.
Thanks in advance,
Fabio
>
> If I am missing something, please, let me know :) v3 is on the way...
>
> With regards,
> Pavel Skripkin
>
On 8/24/21 11:38 AM, Fabio M. De Francesco wrote:
> On Tuesday, August 24, 2021 8:40:18 AM CEST Pavel Skripkin wrote:
>> On 8/24/21 3:10 AM, Fabio M. De Francesco wrote:
>> > On Tuesday, August 24, 2021 1:33:46 AM CEST Phillip Potter wrote:
>> >> On Sun, 22 Aug 2021 at 15:36, Pavel Skripkin <[email protected]> wrote:
>> >> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
>> >> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
>> >> > {
>> >> > u8 requesttype;
>> >> > u16 wvalue;
>> >> > u16 len;
>> >> > - __le32 data;
>> >> > + int res;
>> >> > + __le32 tmp;
>> >> > +
>> >> > + if (WARN_ON(unlikely(!data)))
>> >> > + return -EINVAL;
>> >> >
>> >> > requesttype = 0x01;/* read_in */
>> >> >
>> >> > wvalue = (u16)(addr & 0x0000ffff);
>> >> > len = 4;
>> >> >
>> >> > - usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>> >> > + res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>> >> > + if (res < 0) {
>> >> > + dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
>> >> > + } else {
>> >> > + /* Noone cares about positive return value */
>> >> > + *data = le32_to_cpu(tmp);
>> >> > + res = 0;
>> >> > + }
>> >> >
>> >> > - return le32_to_cpu(data);
>> >> > + return res;
>> >> > }
>> >>
>> >> Dear Pavel,
>> >>
>> >> OK, found the issue with decoded stack trace after reviewing this
>> >> usb_read32 function. Your line:
>> >> res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>> >>
>> >> should read:
>> >> res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
>> >
>> > Dear Philip,
>> >
>> > No, it should read:
>> >
>> > res = usbctrl_vendorreq(pintfhdl, wvalue, data, len, requesttype);
>> >
>> > I suspect that Pavel didn't notice he was reusing a line of the old code
>> > wth no due changes.
>> >
>> >> With this change, the driver runs fine with no crashes/oopses. I will
>> >> explain the issue but you can probably see already, so I hope I'm not
>> >> coming across as patronising, just trying to be helpful :-)
>> >>
>> >> Essentially, you are taking the address of the data function parameter
>> >> on this line with &data, a pointer to u32, which is giving you a
>> >> pointer to a pointer to u32 (u32 **) for this function parameter
>> >> variable. When passed to usbctrl_vendorreq, it is being passed to
>> >> memcpy inside this function as a void *, meaning that memcpy
>> >> subsequently overwrites the value of the memory address inside data to
>> >> point to a different location, which is problem when it is later
>> >> deferenced at:
>> >> *data = le32_to_cpu(tmp);
>> >> causing the OOPS
>> >>
>> >> Also, as written, you can probably see that tmp is uninitialised. This
>> >> looks like a typo, so guessing this wasn't your intention. Anyhow,
>> >> with that small change, usbctrl_vendorreq reads into tmp, which is
>> >> then passed to le32_to_cpu whose return value is stored via the
>> >> deferenced data ptr (which now has its original address within and not
>> >> inadvertently modified). Hope this helps, and I'd be happy to Ack the
>> >> series if you want to resend this patch. Many thanks.
>> >
>> > I think that another typo is having 'tmp', because that variable is unnecessary
>> > and "*data = le32_to_cpu(tmp);" is wrong too.
>> >
>> > Now I also see that also usb_read16() is wrong, while usb_read8() (the one that
>> > I had read yesterday) is the only correct function of the three usb_read*().
>> >
>>
>> Hi, guys!
>>
>>
>> Sorry for breaking your system, Phillip. This code was part of "last
>> minute" changes and yes, it's broken :)
>>
>> I get what Phillip said, because I _should_ read into tmp variable
>> instead of directly to data, but I don't get Fabio's idea, sorry.
>
> Hi Pavel,
>
> I (wrongly?) assumed from the prototype of usb_read32() that u32 *data is in native
> endianness. So, I didn't see the necessity of using _le32 tmp and then convert that tmp
> with le32_to_cpu().
>
> I simply thought that data could be passed to usbctrl_vendorreq as it-is.
>
>> Data from chip comes in little-endian, so we _should_ convert it to
>> cpu's endian. Temp variable is needed to make smatch and all other
>> static anylis tools happy about this code.
>
> Now that you explained that "Data from chip comes in little-endian", obviously
> I must agree with you that the code needs tmp and that tmp must be
> swapped by le32_to_cpu(), ahead of assigning it to *data.
>
> Just a curiosity... Since I was not able to see that *data is returned in little endian,
> can you please point me where in the code you found out that it is? There must
> be some place in the code that I'm unable to find and see that *data is LE.
>
> Thanks in advance,
>
> Fabio
Hi, Fabio!
previous usb_read16() realization, which is 100% right:
static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
{
u8 requesttype;
u16 wvalue;
u16 len;
__le32 data;
requesttype = 0x01;/* read_in */
wvalue = (u16)(addr & 0x0000ffff);
len = 2;
usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
return (u16)(le32_to_cpu(data) & 0xffff);
}
Bases on this code, I think, it's oblivious, that data comes in
little-endian. That's why I leaved temp variable for casting le32 to
cpu's endianess.
I could just read into u{16,32} * and then make smth like
*data = le32_to_cpu(*data)
but static analysis tools will complain about wrong data type passed to
le32_to_cpu()
+ Phillip tested fixed v2 version and it worked well for him. I guess,
Phillip was able to spot weird driver behavior, if this cast is wrong.
With regards,
Pavel Skripkin
On 8/24/21 11:47 AM, Pavel Skripkin wrote:
> On 8/24/21 11:38 AM, Fabio M. De Francesco wrote:
>> On Tuesday, August 24, 2021 8:40:18 AM CEST Pavel Skripkin wrote:
>>> On 8/24/21 3:10 AM, Fabio M. De Francesco wrote:
>>> > On Tuesday, August 24, 2021 1:33:46 AM CEST Phillip Potter wrote:
>>> >> On Sun, 22 Aug 2021 at 15:36, Pavel Skripkin <[email protected]> wrote:
>>> >> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
>>> >> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
>>> >> > {
>>> >> > u8 requesttype;
>>> >> > u16 wvalue;
>>> >> > u16 len;
>>> >> > - __le32 data;
>>> >> > + int res;
>>> >> > + __le32 tmp;
>>> >> > +
>>> >> > + if (WARN_ON(unlikely(!data)))
>>> >> > + return -EINVAL;
>>> >> >
>>> >> > requesttype = 0x01;/* read_in */
>>> >> >
>>> >> > wvalue = (u16)(addr & 0x0000ffff);
>>> >> > len = 4;
>>> >> >
>>> >> > - usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>>> >> > + res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>>> >> > + if (res < 0) {
>>> >> > + dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
>>> >> > + } else {
>>> >> > + /* Noone cares about positive return value */
>>> >> > + *data = le32_to_cpu(tmp);
>>> >> > + res = 0;
>>> >> > + }
>>> >> >
>>> >> > - return le32_to_cpu(data);
>>> >> > + return res;
>>> >> > }
>>> >>
>>> >> Dear Pavel,
>>> >>
>>> >> OK, found the issue with decoded stack trace after reviewing this
>>> >> usb_read32 function. Your line:
>>> >> res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>>> >>
>>> >> should read:
>>> >> res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
>>> >
>>> > Dear Philip,
>>> >
>>> > No, it should read:
>>> >
>>> > res = usbctrl_vendorreq(pintfhdl, wvalue, data, len, requesttype);
>>> >
>>> > I suspect that Pavel didn't notice he was reusing a line of the old code
>>> > wth no due changes.
>>> >
>>> >> With this change, the driver runs fine with no crashes/oopses. I will
>>> >> explain the issue but you can probably see already, so I hope I'm not
>>> >> coming across as patronising, just trying to be helpful :-)
>>> >>
>>> >> Essentially, you are taking the address of the data function parameter
>>> >> on this line with &data, a pointer to u32, which is giving you a
>>> >> pointer to a pointer to u32 (u32 **) for this function parameter
>>> >> variable. When passed to usbctrl_vendorreq, it is being passed to
>>> >> memcpy inside this function as a void *, meaning that memcpy
>>> >> subsequently overwrites the value of the memory address inside data to
>>> >> point to a different location, which is problem when it is later
>>> >> deferenced at:
>>> >> *data = le32_to_cpu(tmp);
>>> >> causing the OOPS
>>> >>
>>> >> Also, as written, you can probably see that tmp is uninitialised. This
>>> >> looks like a typo, so guessing this wasn't your intention. Anyhow,
>>> >> with that small change, usbctrl_vendorreq reads into tmp, which is
>>> >> then passed to le32_to_cpu whose return value is stored via the
>>> >> deferenced data ptr (which now has its original address within and not
>>> >> inadvertently modified). Hope this helps, and I'd be happy to Ack the
>>> >> series if you want to resend this patch. Many thanks.
>>> >
>>> > I think that another typo is having 'tmp', because that variable is unnecessary
>>> > and "*data = le32_to_cpu(tmp);" is wrong too.
>>> >
>>> > Now I also see that also usb_read16() is wrong, while usb_read8() (the one that
>>> > I had read yesterday) is the only correct function of the three usb_read*().
>>> >
>>>
>>> Hi, guys!
>>>
>>>
>>> Sorry for breaking your system, Phillip. This code was part of "last
>>> minute" changes and yes, it's broken :)
>>>
>>> I get what Phillip said, because I _should_ read into tmp variable
>>> instead of directly to data, but I don't get Fabio's idea, sorry.
>>
>> Hi Pavel,
>>
>> I (wrongly?) assumed from the prototype of usb_read32() that u32 *data is in native
>> endianness. So, I didn't see the necessity of using _le32 tmp and then convert that tmp
>> with le32_to_cpu().
>>
>> I simply thought that data could be passed to usbctrl_vendorreq as it-is.
>>
>>> Data from chip comes in little-endian, so we _should_ convert it to
>>> cpu's endian. Temp variable is needed to make smatch and all other
>>> static anylis tools happy about this code.
>>
>> Now that you explained that "Data from chip comes in little-endian", obviously
>> I must agree with you that the code needs tmp and that tmp must be
>> swapped by le32_to_cpu(), ahead of assigning it to *data.
>>
>> Just a curiosity... Since I was not able to see that *data is returned in little endian,
>> can you please point me where in the code you found out that it is? There must
>> be some place in the code that I'm unable to find and see that *data is LE.
>>
>> Thanks in advance,
>>
>> Fabio
>
> Hi, Fabio!
>
> previous usb_read16() realization, which is 100% right:
>
>
> static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
> {
> u8 requesttype;
> u16 wvalue;
> u16 len;
> __le32 data;
>
> requesttype = 0x01;/* read_in */
> wvalue = (u16)(addr & 0x0000ffff);
> len = 2;
> usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>
> return (u16)(le32_to_cpu(data) & 0xffff);
> }
>
>
> Bases on this code, I think, it's oblivious, that data comes in
> little-endian. That's why I leaved temp variable for casting le32 to
> cpu's endianess.
>
> I could just read into u{16,32} * and then make smth like
>
> *data = le32_to_cpu(*data)
>
> but static analysis tools will complain about wrong data type passed to
> le32_to_cpu()
>
> + Phillip tested fixed v2 version and it worked well for him. I guess,
> Phillip was able to spot weird driver behavior, if this cast is wrong.
>
^^^^^&
I am wrong with this statement, I guess. Most likely, Phillip is testing
on smth like x64 and this arch is le, so...
With regards,
Pavel Skripkin
On Tuesday, August 24, 2021 10:53:35 AM CEST Pavel Skripkin wrote:
> On 8/24/21 11:47 AM, Pavel Skripkin wrote:
> > On 8/24/21 11:38 AM, Fabio M. De Francesco wrote:
> >
> > Hi, Fabio!
> >
> > previous usb_read16() realization, which is 100% right:
> >
> >
> > static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
> > {
> > u8 requesttype;
> > u16 wvalue;
> > u16 len;
> > __le32 data;
Ah, it was in plain sight! How didn't I notice it? :(
> >
> > requesttype = 0x01;/* read_in */
> > wvalue = (u16)(addr & 0x0000ffff);
> > len = 2;
> > usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >
> > return (u16)(le32_to_cpu(data) & 0xffff);
> > }
> >
> >
> > Bases on this code, I think, it's oblivious, that data comes in
> > little-endian. That's why I leaved temp variable for casting le32 to
> > cpu's endianess.
Yes you did well (if we trust the old code :)), anyway I guess it
was correct because I've just seen that data is __le32 also in other Realtek
drivers.
> >
> > I could just read into u{16,32} * and then make smth like
> >
> > *data = le32_to_cpu(*data)
> >
> > but static analysis tools will complain about wrong data type passed to
> > le32_to_cpu()
Obviously the (not broken) tools should catch that and complain.
> > + Phillip tested fixed v2 version and it worked well for him. I guess,
> > Phillip was able to spot weird driver behavior, if this cast is wrong.
> >
> ^^^^^&
>
> I am wrong with this statement, I guess. Most likely, Phillip is testing
> on smth like x64 and this arch is le, so...
>
> With regards,
> Pavel Skripkin
>
Thanks,
Fabio
On Tuesday, August 24, 2021 9:01:23 AM CEST Pavel Skripkin wrote:
> On 8/24/21 9:58 AM, Dan Carpenter wrote:
> > On Sun, Aug 22, 2021 at 05:36:01PM +0300, Pavel Skripkin wrote:
> >> -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> >> +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
> >> {
> >> u8 requesttype;
> >> u16 wvalue;
> >> u16 len;
> >> - __le32 data;
> >> + int res;
> >> + __le32 tmp;
> >> +
> >> + if (WARN_ON(unlikely(!data)))
> >> + return -EINVAL;
> >>
> >> requesttype = 0x01;/* read_in */
> >>
> >> wvalue = (u16)(addr & 0x0000ffff);
> >> len = 4;
> >>
> >> - usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >> + res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >> + if (res < 0) {
> >> + dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
> >
> > Add a return here. Try to keep the success path and the failure path
> > as separate as possible. Try to keep the success path indented at one
> > tab so the code looks like this:
> >
> > success();
> > success();
> > if (fail)
> > handle_failure();
> > success();
> > success();
> >
> > Try to deal with exceptions as quickly as possible so that the reader
> > has less to remember.
> >
> >> + } else {
> >> + /* Noone cares about positive return value */
> >
> > Ugh... That's unfortunate. We should actually care. The
> > usbctrl_vendorreq() has an information leak where it copies len (4)
> > bytes of data even if usb_control_msg() is not able to read len bytes.
> >
> > The best fix would be to remove the information leak and make
> > usbctrl_vendorreq() return zero on success. In other words something
> > like:
> >
> > status = usb_control_msg();
> > if (status < 0)
> > return status;
> > if (status != len)
> > return -EIO;
> > status = 0;
> >
>
> I see, thank you for reviewing, will fix in v3! I fully forgot, that
> usb_control_msg() can receive only part of the message :)
With the use of the new API I think that you don't have anymore
partial messages. usb_control_msg() returns the number of bytes
transferred, while usb_control_msg_recv/send return only 0 if successful
otherwise a negative error number.
Regards,
Fabio
> With regards,
> Pavel Skripkin
>
On Tue, 24 Aug 2021 at 09:47, Pavel Skripkin <[email protected]> wrote:
>
> On 8/24/21 11:38 AM, Fabio M. De Francesco wrote:
> > On Tuesday, August 24, 2021 8:40:18 AM CEST Pavel Skripkin wrote:
> >> On 8/24/21 3:10 AM, Fabio M. De Francesco wrote:
> >> > On Tuesday, August 24, 2021 1:33:46 AM CEST Phillip Potter wrote:
> >> >> On Sun, 22 Aug 2021 at 15:36, Pavel Skripkin <[email protected]> wrote:
> >> >> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> >> >> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
> >> >> > {
> >> >> > u8 requesttype;
> >> >> > u16 wvalue;
> >> >> > u16 len;
> >> >> > - __le32 data;
> >> >> > + int res;
> >> >> > + __le32 tmp;
> >> >> > +
> >> >> > + if (WARN_ON(unlikely(!data)))
> >> >> > + return -EINVAL;
> >> >> >
> >> >> > requesttype = 0x01;/* read_in */
> >> >> >
> >> >> > wvalue = (u16)(addr & 0x0000ffff);
> >> >> > len = 4;
> >> >> >
> >> >> > - usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >> >> > + res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >> >> > + if (res < 0) {
> >> >> > + dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
> >> >> > + } else {
> >> >> > + /* Noone cares about positive return value */
> >> >> > + *data = le32_to_cpu(tmp);
> >> >> > + res = 0;
> >> >> > + }
> >> >> >
> >> >> > - return le32_to_cpu(data);
> >> >> > + return res;
> >> >> > }
> >> >>
> >> >> Dear Pavel,
> >> >>
> >> >> OK, found the issue with decoded stack trace after reviewing this
> >> >> usb_read32 function. Your line:
> >> >> res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >> >>
> >> >> should read:
> >> >> res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
> >> >
> >> > Dear Philip,
> >> >
> >> > No, it should read:
> >> >
> >> > res = usbctrl_vendorreq(pintfhdl, wvalue, data, len, requesttype);
> >> >
> >> > I suspect that Pavel didn't notice he was reusing a line of the old code
> >> > wth no due changes.
> >> >
> >> >> With this change, the driver runs fine with no crashes/oopses. I will
> >> >> explain the issue but you can probably see already, so I hope I'm not
> >> >> coming across as patronising, just trying to be helpful :-)
> >> >>
> >> >> Essentially, you are taking the address of the data function parameter
> >> >> on this line with &data, a pointer to u32, which is giving you a
> >> >> pointer to a pointer to u32 (u32 **) for this function parameter
> >> >> variable. When passed to usbctrl_vendorreq, it is being passed to
> >> >> memcpy inside this function as a void *, meaning that memcpy
> >> >> subsequently overwrites the value of the memory address inside data to
> >> >> point to a different location, which is problem when it is later
> >> >> deferenced at:
> >> >> *data = le32_to_cpu(tmp);
> >> >> causing the OOPS
> >> >>
> >> >> Also, as written, you can probably see that tmp is uninitialised. This
> >> >> looks like a typo, so guessing this wasn't your intention. Anyhow,
> >> >> with that small change, usbctrl_vendorreq reads into tmp, which is
> >> >> then passed to le32_to_cpu whose return value is stored via the
> >> >> deferenced data ptr (which now has its original address within and not
> >> >> inadvertently modified). Hope this helps, and I'd be happy to Ack the
> >> >> series if you want to resend this patch. Many thanks.
> >> >
> >> > I think that another typo is having 'tmp', because that variable is unnecessary
> >> > and "*data = le32_to_cpu(tmp);" is wrong too.
> >> >
> >> > Now I also see that also usb_read16() is wrong, while usb_read8() (the one that
> >> > I had read yesterday) is the only correct function of the three usb_read*().
> >> >
> >>
> >> Hi, guys!
> >>
> >>
> >> Sorry for breaking your system, Phillip. This code was part of "last
> >> minute" changes and yes, it's broken :)
> >>
> >> I get what Phillip said, because I _should_ read into tmp variable
> >> instead of directly to data, but I don't get Fabio's idea, sorry.
> >
> > Hi Pavel,
> >
> > I (wrongly?) assumed from the prototype of usb_read32() that u32 *data is in native
> > endianness. So, I didn't see the necessity of using _le32 tmp and then convert that tmp
> > with le32_to_cpu().
> >
> > I simply thought that data could be passed to usbctrl_vendorreq as it-is.
> >
> >> Data from chip comes in little-endian, so we _should_ convert it to
> >> cpu's endian. Temp variable is needed to make smatch and all other
> >> static anylis tools happy about this code.
> >
> > Now that you explained that "Data from chip comes in little-endian", obviously
> > I must agree with you that the code needs tmp and that tmp must be
> > swapped by le32_to_cpu(), ahead of assigning it to *data.
> >
> > Just a curiosity... Since I was not able to see that *data is returned in little endian,
> > can you please point me where in the code you found out that it is? There must
> > be some place in the code that I'm unable to find and see that *data is LE.
> >
> > Thanks in advance,
> >
> > Fabio
>
> Hi, Fabio!
>
> previous usb_read16() realization, which is 100% right:
>
>
> static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
> {
> u8 requesttype;
> u16 wvalue;
> u16 len;
> __le32 data;
>
> requesttype = 0x01;/* read_in */
> wvalue = (u16)(addr & 0x0000ffff);
> len = 2;
> usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>
> return (u16)(le32_to_cpu(data) & 0xffff);
> }
>
>
> Bases on this code, I think, it's oblivious, that data comes in
> little-endian. That's why I leaved temp variable for casting le32 to
> cpu's endianess.
>
> I could just read into u{16,32} * and then make smth like
>
> *data = le32_to_cpu(*data)
>
> but static analysis tools will complain about wrong data type passed to
> le32_to_cpu()
>
> + Phillip tested fixed v2 version and it worked well for him. I guess,
> Phillip was able to spot weird driver behavior, if this cast is wrong.
>
>
>
>
> With regards,
> Pavel Skripkin
In my mind we can't necessarily assume we are running on a little
endian CPU, even if we probably are for practical purposes. That's why
my fix looked how it did, but I'm happy to be corrected :-) Also, I
can see Dan has looked at the code with suggestions as well. I know
you have published v3 - sorry, not had time to review/test it yet.
Regards,
Phil
On Tue, 24 Aug 2021 at 09:53, Pavel Skripkin <[email protected]> wrote:
>
> On 8/24/21 11:47 AM, Pavel Skripkin wrote:
> > On 8/24/21 11:38 AM, Fabio M. De Francesco wrote:
> >> On Tuesday, August 24, 2021 8:40:18 AM CEST Pavel Skripkin wrote:
> >>> On 8/24/21 3:10 AM, Fabio M. De Francesco wrote:
> >>> > On Tuesday, August 24, 2021 1:33:46 AM CEST Phillip Potter wrote:
> >>> >> On Sun, 22 Aug 2021 at 15:36, Pavel Skripkin <[email protected]> wrote:
> >>> >> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> >>> >> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
> >>> >> > {
> >>> >> > u8 requesttype;
> >>> >> > u16 wvalue;
> >>> >> > u16 len;
> >>> >> > - __le32 data;
> >>> >> > + int res;
> >>> >> > + __le32 tmp;
> >>> >> > +
> >>> >> > + if (WARN_ON(unlikely(!data)))
> >>> >> > + return -EINVAL;
> >>> >> >
> >>> >> > requesttype = 0x01;/* read_in */
> >>> >> >
> >>> >> > wvalue = (u16)(addr & 0x0000ffff);
> >>> >> > len = 4;
> >>> >> >
> >>> >> > - usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >>> >> > + res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >>> >> > + if (res < 0) {
> >>> >> > + dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
> >>> >> > + } else {
> >>> >> > + /* Noone cares about positive return value */
> >>> >> > + *data = le32_to_cpu(tmp);
> >>> >> > + res = 0;
> >>> >> > + }
> >>> >> >
> >>> >> > - return le32_to_cpu(data);
> >>> >> > + return res;
> >>> >> > }
> >>> >>
> >>> >> Dear Pavel,
> >>> >>
> >>> >> OK, found the issue with decoded stack trace after reviewing this
> >>> >> usb_read32 function. Your line:
> >>> >> res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >>> >>
> >>> >> should read:
> >>> >> res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
> >>> >
> >>> > Dear Philip,
> >>> >
> >>> > No, it should read:
> >>> >
> >>> > res = usbctrl_vendorreq(pintfhdl, wvalue, data, len, requesttype);
> >>> >
> >>> > I suspect that Pavel didn't notice he was reusing a line of the old code
> >>> > wth no due changes.
> >>> >
> >>> >> With this change, the driver runs fine with no crashes/oopses. I will
> >>> >> explain the issue but you can probably see already, so I hope I'm not
> >>> >> coming across as patronising, just trying to be helpful :-)
> >>> >>
> >>> >> Essentially, you are taking the address of the data function parameter
> >>> >> on this line with &data, a pointer to u32, which is giving you a
> >>> >> pointer to a pointer to u32 (u32 **) for this function parameter
> >>> >> variable. When passed to usbctrl_vendorreq, it is being passed to
> >>> >> memcpy inside this function as a void *, meaning that memcpy
> >>> >> subsequently overwrites the value of the memory address inside data to
> >>> >> point to a different location, which is problem when it is later
> >>> >> deferenced at:
> >>> >> *data = le32_to_cpu(tmp);
> >>> >> causing the OOPS
> >>> >>
> >>> >> Also, as written, you can probably see that tmp is uninitialised. This
> >>> >> looks like a typo, so guessing this wasn't your intention. Anyhow,
> >>> >> with that small change, usbctrl_vendorreq reads into tmp, which is
> >>> >> then passed to le32_to_cpu whose return value is stored via the
> >>> >> deferenced data ptr (which now has its original address within and not
> >>> >> inadvertently modified). Hope this helps, and I'd be happy to Ack the
> >>> >> series if you want to resend this patch. Many thanks.
> >>> >
> >>> > I think that another typo is having 'tmp', because that variable is unnecessary
> >>> > and "*data = le32_to_cpu(tmp);" is wrong too.
> >>> >
> >>> > Now I also see that also usb_read16() is wrong, while usb_read8() (the one that
> >>> > I had read yesterday) is the only correct function of the three usb_read*().
> >>> >
> >>>
> >>> Hi, guys!
> >>>
> >>>
> >>> Sorry for breaking your system, Phillip. This code was part of "last
> >>> minute" changes and yes, it's broken :)
> >>>
> >>> I get what Phillip said, because I _should_ read into tmp variable
> >>> instead of directly to data, but I don't get Fabio's idea, sorry.
> >>
> >> Hi Pavel,
> >>
> >> I (wrongly?) assumed from the prototype of usb_read32() that u32 *data is in native
> >> endianness. So, I didn't see the necessity of using _le32 tmp and then convert that tmp
> >> with le32_to_cpu().
> >>
> >> I simply thought that data could be passed to usbctrl_vendorreq as it-is.
> >>
> >>> Data from chip comes in little-endian, so we _should_ convert it to
> >>> cpu's endian. Temp variable is needed to make smatch and all other
> >>> static anylis tools happy about this code.
> >>
> >> Now that you explained that "Data from chip comes in little-endian", obviously
> >> I must agree with you that the code needs tmp and that tmp must be
> >> swapped by le32_to_cpu(), ahead of assigning it to *data.
> >>
> >> Just a curiosity... Since I was not able to see that *data is returned in little endian,
> >> can you please point me where in the code you found out that it is? There must
> >> be some place in the code that I'm unable to find and see that *data is LE.
> >>
> >> Thanks in advance,
> >>
> >> Fabio
> >
> > Hi, Fabio!
> >
> > previous usb_read16() realization, which is 100% right:
> >
> >
> > static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
> > {
> > u8 requesttype;
> > u16 wvalue;
> > u16 len;
> > __le32 data;
> >
> > requesttype = 0x01;/* read_in */
> > wvalue = (u16)(addr & 0x0000ffff);
> > len = 2;
> > usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >
> > return (u16)(le32_to_cpu(data) & 0xffff);
> > }
> >
> >
> > Bases on this code, I think, it's oblivious, that data comes in
> > little-endian. That's why I leaved temp variable for casting le32 to
> > cpu's endianess.
> >
> > I could just read into u{16,32} * and then make smth like
> >
> > *data = le32_to_cpu(*data)
> >
> > but static analysis tools will complain about wrong data type passed to
> > le32_to_cpu()
> >
> > + Phillip tested fixed v2 version and it worked well for him. I guess,
> > Phillip was able to spot weird driver behavior, if this cast is wrong.
> >
> ^^^^^&
>
> I am wrong with this statement, I guess. Most likely, Phillip is testing
> on smth like x64 and this arch is le, so...
>
>
>
>
> With regards,
> Pavel Skripkin
Dear Pavel,
You're correct in your assumption, my testing environment is an
little-endian x64 QEMU VM with USB passthrough for the wireless
adapter. I prefer to test this way so that driver crashes don't bring
down the whole machine :-)
Regards,
Phil
On Tuesday, August 24, 2021 9:27:35 AM CEST Pavel Skripkin wrote:
> _rtw_read16 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_read16() 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 <[email protected]>
>
> [...]
>
> -static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
> +static int usb_read16(struct intf_hdl *pintfhdl, u32 addr, u16 *data)
> {
> u8 requesttype;
> u16 wvalue;
> u16 len;
> - __le32 data;
> + int res;
> + __le32 tmp;
> +
> + if (WARN_ON(unlikely(!data)))
> + return -EINVAL;
>
> requesttype = 0x01;/* read_in */
> wvalue = (u16)(addr & 0x0000ffff);
> len = 2;
> - usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> + res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
> + if (res < 0) {
> + dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 16 bytes: %d\n", res);
> + return res;
> + } else if (res != len) {
Dear Pavel,
Please note that if and when my patch "Use usb_control_msg_recv / send () in
usbctrl_vendorreq ()" will be merged, "if (res! = len)" will always evaluate 'true'
and usb_read16 () will always return -EIO even if usbctrl_vendorreq () succeeds.
> + dev_err(dvobj_to_dev(pintfhdl->pintf_dev),
> + "Failed to read 16 bytes, could read only %d bytes\n", res);
> + return -EIO;
> + }
>
> - return (u16)(le32_to_cpu(data) & 0xffff);
> + *data = le32_to_cpu(tmp) & 0xffff;
> +
> + return 0;
> }
[...]
Regards,
Fabio
On Tuesday, August 24, 2021 9:27:42 AM CEST Pavel Skripkin wrote:
> _rtw_read32 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_read32() 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 <[email protected]>
>
> [...]
>
> -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
> {
> u8 requesttype;
> u16 wvalue;
> u16 len;
> - __le32 data;
> + int res;
> + __le32 tmp;
> +
> + if (WARN_ON(unlikely(!data)))
> + return -EINVAL;
>
> requesttype = 0x01;/* read_in */
>
> wvalue = (u16)(addr & 0x0000ffff);
> len = 4;
>
> - usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> + res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
> + if (res < 0) {
> + dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
> + return res;
> + } else if (res != len) {
Dear Pavel,
Please note that if and when my patch "Use usb_control_msg_recv / send () in
usbctrl_vendorreq ()" will be merged, "if (res! = len)" will always evaluate 'true'
and usb_read32() will always return -EIO even if usbctrl_vendorreq () succeeds.
> + dev_err(dvobj_to_dev(pintfhdl->pintf_dev),
> + "Failed to read 32 bytes, could read only %d bytes\n", res);
> + return -EIO;
> + }
> +
> + *data = le32_to_cpu(tmp);
>
> - return le32_to_cpu(data);
> + return 0;
> }
>
> [...]
>
Regards,
Fabio
On Wednesday, August 25, 2021 10:22:16 AM CEST Pavel Skripkin wrote:
> On 8/25/21 7:35 AM, Fabio M. De Francesco wrote:
> > Dear Pavel,
> >
> > Please note that if and when my patch "Use usb_control_msg_recv / send () in
> > usbctrl_vendorreq ()" will be merged, "if (res! = len)" will always evaluate 'true'
> > and usb_read16 () will always return -EIO even if usbctrl_vendorreq () succeeds.
> >
>
> Yep, thank you, but it depends on which series will go in first :)
>
> There is a chance, that you will need to clean up this part, if mine
> will be merged before yours
>
Ha-ha ... I know that beautiful rule: whoever breaks must fix!
However there should be another rule which says that
the old (me) takes precedence over the young (you) :-)
Seriously, thank you so much for your help and the "Reviewed by"
tag on my work.
Regards,
Fabio
> With regards,
> Pavel Skripkin
>
On 8/25/21 12:48 PM, Fabio M. De Francesco wrote:
> On Wednesday, August 25, 2021 10:22:16 AM CEST Pavel Skripkin wrote:
>> On 8/25/21 7:35 AM, Fabio M. De Francesco wrote:
>> > Dear Pavel,
>> >
>> > Please note that if and when my patch "Use usb_control_msg_recv / send () in
>> > usbctrl_vendorreq ()" will be merged, "if (res! = len)" will always evaluate 'true'
>> > and usb_read16 () will always return -EIO even if usbctrl_vendorreq () succeeds.
>> >
>>
>> Yep, thank you, but it depends on which series will go in first :)
>>
>> There is a chance, that you will need to clean up this part, if mine
>> will be merged before yours
>>
>
> Ha-ha ... I know that beautiful rule: whoever breaks must fix!
> However there should be another rule which says that
> the old (me) takes precedence over the young (you) :-)
>
The main problem, that no one knows who is the "old". Greg can take
patches in any order he wants, because they are naturally independent :)
We only can say smth like "this one depends on this one" as reply to
patch to inform Greg about the situation.
> Seriously, thank you so much for your help and the "Reviewed by"
> tag on my work.
>
You too :) We are doing same job here for the good of community and
kernel itself
With regards,
Pavel Skripkin
On Wed, Aug 25, 2021 at 12:55:37PM +0300, Pavel Skripkin wrote:
> The main problem, that no one knows who is the "old". Greg can take patches
> in any order he wants
Patches are always taken in first come first serve.
regards,
dan carpenter
On Tuesday, August 24, 2021 9:25:45 AM CEST Pavel Skripkin wrote:
> Hi, Greg, Larry and Phillip!
>
> I noticed, that new staging driver was added like 3 weeks ago and I decided
> to look at the code, because drivers in staging directory are always buggy.
>
> The first thing I noticed is *no one* was checking read operations result, but
> it can fail and driver may start writing random stack values into registers. It
> can cause driver misbehavior or device misbehavior.
>
> To avoid this type of bugs, I've changed rtw_read* API. Now all rtw_read
> funtions return an error, when something went wrong with usb transfer.
>
> It helps callers to break/return earlier and don't write random values to
> registers or to rely on random values.
>
>
> v2 -> v3:
> 1. Fixed OOPS in usb_read32(), caused by writing to u32 **
> 2. Fixed style in rtw_read32, rtw_read16 and rtw_read8 (Suggested by Dan)
> 3. Added error hanling when usb_control_msg() returns ret != len
> NOTE: Dan suggested to add this to usbctrl_vendorreq(), but there is
> pending series, which will get rid of usb_control_msg(), so (res != len)
> check can be removed, when Fabio's series will go in
> 4. Removed RFC tag
>
> v1 -> v2:
> 1. Make rtw_read*() return an error instead of initializing pointer to error
> 2. Split one huge patch to smaller ones for each rtw_read{8,16,32} function
> changes
> 3. Add new macro for printing register values (It helps to not copy-paste error
> handling)
> 4. Removed {read,write}_macreg (Suggested by Phillip)
> 5. Rebased on top of staging-next
> 6. Cleaned checkpatch errors and warnings
>
>
> Phillip has tested fixed v2 version, AFAIU
I had already acked your series when it was an RFC but I guess
the tag gets lost now that you have submitted the "real" patches.
As said, I like the purpose and the overall design. Furthermore,
I have compiled and linked the whole series (make C=2 -j8
drivers/staging/r8188eu W=1) and I can confirm it does not
introduce any errors and/or warnings.
Anyway I couldn't test the module, so (for all six patches)...
Acked-by: Fabio M. De Francesco <[email protected]>
Thanks,
Fabio
> Pavel Skripkin (6):
> staging: r8188eu: remove {read,write}_macreg
> staging: r8188eu: add helper macro for printing registers
> staging: r8188eu: add error handling of rtw_read8
> staging: r8188eu: add error handling of rtw_read16
> staging: r8188eu: add error handling of rtw_read32
> staging: r8188eu: make ReadEFuse return an int
>
> drivers/staging/r8188eu/core/rtw_debug.c | 79 +++-
> drivers/staging/r8188eu/core/rtw_efuse.c | 125 +++--
> drivers/staging/r8188eu/core/rtw_io.c | 27 +-
> drivers/staging/r8188eu/core/rtw_mp.c | 70 ++-
> drivers/staging/r8188eu/core/rtw_mp_ioctl.c | 13 +-
> drivers/staging/r8188eu/core/rtw_pwrctrl.c | 5 +-
> drivers/staging/r8188eu/core/rtw_sreset.c | 9 +-
> .../r8188eu/hal/Hal8188ERateAdaptive.c | 8 +-
> drivers/staging/r8188eu/hal/HalPhyRf_8188e.c | 21 +-
> drivers/staging/r8188eu/hal/HalPwrSeqCmd.c | 9 +-
> drivers/staging/r8188eu/hal/hal_com.c | 23 +-
> drivers/staging/r8188eu/hal/hal_intf.c | 6 +-
> drivers/staging/r8188eu/hal/odm_interface.c | 12 +-
> drivers/staging/r8188eu/hal/rtl8188e_cmd.c | 33 +-
> drivers/staging/r8188eu/hal/rtl8188e_dm.c | 6 +-
> .../staging/r8188eu/hal/rtl8188e_hal_init.c | 285 +++++++++---
> drivers/staging/r8188eu/hal/rtl8188e_phycfg.c | 27 +-
> drivers/staging/r8188eu/hal/rtl8188e_sreset.c | 22 +-
> drivers/staging/r8188eu/hal/rtl8188eu_led.c | 18 +-
> drivers/staging/r8188eu/hal/usb_halinit.c | 439 +++++++++++++++---
> drivers/staging/r8188eu/hal/usb_ops_linux.c | 62 ++-
> drivers/staging/r8188eu/include/hal_intf.h | 6 +-
> .../staging/r8188eu/include/odm_interface.h | 6 +-
> .../staging/r8188eu/include/rtl8188e_hal.h | 2 +-
> drivers/staging/r8188eu/include/rtw_debug.h | 13 +
> drivers/staging/r8188eu/include/rtw_efuse.h | 4 +-
> drivers/staging/r8188eu/include/rtw_io.h | 18 +-
> drivers/staging/r8188eu/include/rtw_mp.h | 2 -
> drivers/staging/r8188eu/os_dep/ioctl_linux.c | 179 +++++--
> drivers/staging/r8188eu/os_dep/usb_intf.c | 3 +-
> 30 files changed, 1143 insertions(+), 389 deletions(-)
>
> --
> 2.32.0
>
>
On 8/25/21 1:06 PM, Dan Carpenter wrote:
> On Wed, Aug 25, 2021 at 12:55:37PM +0300, Pavel Skripkin wrote:
>> The main problem, that no one knows who is the "old". Greg can take patches
>> in any order he wants
>
> Patches are always taken in first come first serve.
>
Ok, but if pending patch needs new version, then it will be taken at the
end?
Here is the situation we have:
I have the patch series based on old function behavior, it was
posted first
Then Fabio posted refactoring of the function and it changes
return values.
Both series are pending right now and made on top of staging-next
branch. Who needs to rebase? I think, applying these series as-is can
broke the driver, since error handling will be broken
With regards,
Pavel Skripkin
On Wed, Aug 25, 2021 at 01:13:54PM +0300, Pavel Skripkin wrote:
> On 8/25/21 1:06 PM, Dan Carpenter wrote:
> > On Wed, Aug 25, 2021 at 12:55:37PM +0300, Pavel Skripkin wrote:
> > > The main problem, that no one knows who is the "old". Greg can take patches
> > > in any order he wants
> >
> > Patches are always taken in first come first serve.
> >
>
>
> Ok, but if pending patch needs new version, then it will be taken at the
> end?
Versions don't matter. No one is tracking any of that.
A patch arrives. It is either applied or rejected. First come first
serve.
>
> Here is the situation we have:
>
> I have the patch series based on old function behavior, it was
> posted first
>
> Then Fabio posted refactoring of the function and it changes
> return values.
>
>
> Both series are pending right now and made on top of staging-next branch.
> Who needs to rebase? I think, applying these series as-is can broke the
> driver, since error handling will be broken
That's a bug then. The patch should be rejected. You're not allowed to
break the code.
Also don't write patches which lead to merge order breaking the code
silently. That makes it difficult for stable as well. For example,
don't do this:
-void frob(int a, int b);
+void frob(int b, int a);
In that case, you would change the name of the function so that the
build would break when people mix old and new code.
regards,
dan carpenter
On 8/25/21 1:38 PM, Dan Carpenter wrote:
> On Wed, Aug 25, 2021 at 01:13:54PM +0300, Pavel Skripkin wrote:
>> On 8/25/21 1:06 PM, Dan Carpenter wrote:
>> > On Wed, Aug 25, 2021 at 12:55:37PM +0300, Pavel Skripkin wrote:
>> > > The main problem, that no one knows who is the "old". Greg can take patches
>> > > in any order he wants
>> >
>> > Patches are always taken in first come first serve.
>> >
>>
>>
>> Ok, but if pending patch needs new version, then it will be taken at the
>> end?
>
> Versions don't matter. No one is tracking any of that.
>
> A patch arrives. It is either applied or rejected. First come first
> serve.
>
Ok, big thanks for explanation
>>
>> Here is the situation we have:
>>
>> I have the patch series based on old function behavior, it was
>> posted first
>>
>> Then Fabio posted refactoring of the function and it changes
>> return values.
>>
>>
>> Both series are pending right now and made on top of staging-next branch.
>> Who needs to rebase? I think, applying these series as-is can broke the
>> driver, since error handling will be broken
>
> That's a bug then. The patch should be rejected. You're not allowed to
> break the code.
>
> Also don't write patches which lead to merge order breaking the code
> silently. That makes it difficult for stable as well. For example,
> don't do this:
>
> -void frob(int a, int b);
> +void frob(int b, int a);
>
> In that case, you would change the name of the function so that the
> build would break when people mix old and new code.
>
Understandable, thank you :)
With regards,
Pavel Skripkin
On 8/25/21 7:35 AM, Fabio M. De Francesco wrote:
> On Tuesday, August 24, 2021 9:27:35 AM CEST Pavel Skripkin wrote:
>> _rtw_read16 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_read16() 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 <[email protected]>
>>
>> [...]
>>
>> -static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
>> +static int usb_read16(struct intf_hdl *pintfhdl, u32 addr, u16 *data)
>> {
>> u8 requesttype;
>> u16 wvalue;
>> u16 len;
>> - __le32 data;
>> + int res;
>> + __le32 tmp;
>> +
>> + if (WARN_ON(unlikely(!data)))
>> + return -EINVAL;
>>
>> requesttype = 0x01;/* read_in */
>> wvalue = (u16)(addr & 0x0000ffff);
>> len = 2;
>> - usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>> + res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
>> + if (res < 0) {
>> + dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 16 bytes: %d\n", res);
>> + return res;
>> + } else if (res != len) {
>
> Dear Pavel,
>
> Please note that if and when my patch "Use usb_control_msg_recv / send () in
> usbctrl_vendorreq ()" will be merged, "if (res! = len)" will always evaluate 'true'
> and usb_read16 () will always return -EIO even if usbctrl_vendorreq () succeeds.
>
Yep, thank you, but it depends on which series will go in first :)
There is a chance, that you will need to clean up this part, if mine
will be merged before yours
With regards,
Pavel Skripkin
On Wednesday, August 25, 2021 1:06:40 PM CEST Fabio M. De Francesco wrote:
> On Wednesday, August 25, 2021 12:38:02 PM CEST Dan Carpenter wrote:
> > That's a bug then. The patch should be rejected. You're not allowed to
> > break the code.
>
> Sorry Dan, I disagree. It's not a bug. No one intend to break the code.
> How could anyone know that someone else is working simultaneously on
> some code that is not compatible with the work of the other developer?
>
> Pavel and I worked simultaneously on code based on the current Greg's tree.
>
> We incidentally got to know that mine breaks his.
>
> I suppose that Greg will take Pavel's work first, because it was submitted few
> hours before mine and then will ask me to take into account Pavel's patches,
> rebase, fix and resend mine.
>
> Each series is self contained and does not introduce bugs to the current tree.
> The bugs will arise when Greg will have applied one of the two series as usually
> in a FIFO order.
>
> There's no practical means to know who is working to what just by reading all
> the messages of the lists. Who reads all the messages before deciding to work
> on something? This issue will be solved a way or the other, I really don't think it
> is a big problem, it's unavoidable when a lot of people work on the same
> driver or subsystem.
>
> Regards,
>
> Fabio
For sake of completeness I want to say that when Pavel had only submitted RFC v2
my code didn't break his. It was only with his v3 that the bug went out. But v3 was
submitted just few hours before mine.
Fabio
On Wednesday, August 25, 2021 12:38:02 PM CEST Dan Carpenter wrote:
> On Wed, Aug 25, 2021 at 01:13:54PM +0300, Pavel Skripkin wrote:
> > On 8/25/21 1:06 PM, Dan Carpenter wrote:
> > > On Wed, Aug 25, 2021 at 12:55:37PM +0300, Pavel Skripkin wrote:
> > > > The main problem, that no one knows who is the "old". Greg can take patches
> > > > in any order he wants
> > >
> > > Patches are always taken in first come first serve.
> > >
> >
> >
> > OK, but if pending patch needs new version, then it will be taken at the
> > end?
>
> Versions don't matter. No one is tracking any of that.
>
> A patch arrives. It is either applied or rejected. First come first
> serve.
>
> >
> > Here is the situation we have:
> >
> > I have the patch series based on old function behavior, it was
> > posted first
> >
> > Then Fabio posted refactoring of the function and it changes
> > return values.
> >
> >
> > Both series are pending right now and made on top of staging-next branch.
> > Who needs to rebase? I think, applying these series as-is can broke the
> > driver, since error handling will be broken
>
> That's a bug then. The patch should be rejected. You're not allowed to
> break the code.
Sorry Dan, I disagree. It's not a bug. No one intend to break the code.
How could anyone know that someone else is working simultaneously on
some code that is not compatible with the work of the other developer?
Pavel and I worked simultaneously on code based on the current Greg's tree.
We incidentally got to know that mine breaks his.
I suppose that Greg will take Pavel's work first, because it was submitted few
hours before mine and then will ask me to take into account Pavel's patches,
rebase, fix and resend mine.
Each series is self contained and does not introduce bugs to the current tree.
The bugs will arise when Greg will have applied one of the two series as usually
in a FIFO order.
There's no practical means to know who is working to what just by reading all
the messages of the lists. Who reads all the messages before deciding to work
on something? This issue will be solved a way or the other, I really don't think it
is a big problem, it's unavoidable when a lot of people work on the same
driver or subsystem.
Regards,
Fabio
> Also don't write patches which lead to merge order breaking the code
> silently. That makes it difficult for stable as well. For example,
> don't do this:
>
> -void frob(int a, int b);
> +void frob(int b, int a);
>
> In that case, you would change the name of the function so that the
> build would break when people mix old and new code.
>
> regards,
> dan carpenter
>
>
Hi Pavel,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on staging/staging-testing]
url: https://github.com/0day-ci/linux/commits/Pavel-Skripkin/staging-r8188eu-remove-read-write-_macreg/20210824-162756
base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git 093991aaadf0fbb34184fa37a46e7a157da3f386
config: arm-buildonly-randconfig-r001-20210825 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project ea08c4cd1c0869ec5024a8bb3f5cdf06ab03ae83)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install arm cross compiling tool for clang build
# apt-get install binutils-arm-linux-gnueabi
# https://github.com/0day-ci/linux/commit/d4e4bbed4e59df37967086f60fe92cb1b4504d37
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Pavel-Skripkin/staging-r8188eu-remove-read-write-_macreg/20210824-162756
git checkout d4e4bbed4e59df37967086f60fe92cb1b4504d37
# save the attached .config to linux build tree
mkdir build_dir
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross O=build_dir ARCH=arm SHELL=/bin/bash drivers/staging/r8188eu/
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>
All errors (new ones prefixed by >>):
>> drivers/staging/r8188eu/hal/usb_halinit.c:2022:3: error: expected expression
u8 tmp;
^
1 error generated.
Kconfig warnings: (for reference only)
WARNING: unmet direct dependencies detected for QCOM_SCM
Depends on (ARM || ARM64) && HAVE_ARM_SMCCC
Selected by
- ARM_QCOM_SPM_CPUIDLE && CPU_IDLE && (ARM || ARM64) && (ARCH_QCOM || COMPILE_TEST && !ARM64 && MMU
vim +2022 drivers/staging/r8188eu/hal/usb_halinit.c
1450
1451 static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
1452 {
1453 struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
1454 struct dm_priv *pdmpriv = &haldata->dmpriv;
1455 struct odm_dm_struct *podmpriv = &haldata->odmpriv;
1456 int error;
1457 u8 tmp;
1458
1459 switch (variable) {
1460 case HW_VAR_MEDIA_STATUS:
1461 {
1462 u8 val8;
1463
1464 error = rtw_read8(Adapter, MSR, &val8);
1465 if (error)
1466 return;
1467
1468 val8 &= 0x0c;
1469 val8 |= *((u8 *)val);
1470 rtw_write8(Adapter, MSR, val8);
1471 }
1472 break;
1473 case HW_VAR_MEDIA_STATUS1:
1474 {
1475 u8 val8;
1476
1477 error = rtw_read8(Adapter, MSR, &val8);
1478 if (error)
1479 return;
1480
1481 val8 &= 0x03;
1482 val8 |= *((u8 *)val) << 2;
1483 rtw_write8(Adapter, MSR, val8);
1484 }
1485 break;
1486 case HW_VAR_SET_OPMODE:
1487 hw_var_set_opmode(Adapter, variable, val);
1488 break;
1489 case HW_VAR_MAC_ADDR:
1490 hw_var_set_macaddr(Adapter, variable, val);
1491 break;
1492 case HW_VAR_BSSID:
1493 hw_var_set_bssid(Adapter, variable, val);
1494 break;
1495 case HW_VAR_BASIC_RATE:
1496 {
1497 u16 BrateCfg = 0;
1498 u8 RateIndex = 0;
1499
1500 /* 2007.01.16, by Emily */
1501 /* Select RRSR (in Legacy-OFDM and CCK) */
1502 /* For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate. */
1503 /* We do not use other rates. */
1504 HalSetBrateCfg(Adapter, val, &BrateCfg);
1505 DBG_88E("HW_VAR_BASIC_RATE: BrateCfg(%#x)\n", BrateCfg);
1506
1507 /* 2011.03.30 add by Luke Lee */
1508 /* CCK 2M ACK should be disabled for some BCM and Atheros AP IOT */
1509 /* because CCK 2M has poor TXEVM */
1510 /* CCK 5.5M & 11M ACK should be enabled for better performance */
1511
1512 BrateCfg = (BrateCfg | 0xd) & 0x15d;
1513 haldata->BasicRateSet = BrateCfg;
1514
1515 BrateCfg |= 0x01; /* default enable 1M ACK rate */
1516 /* Set RRSR rate table. */
1517 rtw_write8(Adapter, REG_RRSR, BrateCfg & 0xff);
1518 rtw_write8(Adapter, REG_RRSR + 1, (BrateCfg >> 8) & 0xff);
1519
1520 error = rtw_read8(Adapter, REG_RRSR + 2, &tmp);
1521 if (error)
1522 return;
1523
1524 rtw_write8(Adapter, REG_RRSR + 2, tmp & 0xf0);
1525
1526 /* Set RTS initial rate */
1527 while (BrateCfg > 0x1) {
1528 BrateCfg = (BrateCfg >> 1);
1529 RateIndex++;
1530 }
1531 /* Ziv - Check */
1532 rtw_write8(Adapter, REG_INIRTS_RATE_SEL, RateIndex);
1533 }
1534 break;
1535 case HW_VAR_TXPAUSE:
1536 rtw_write8(Adapter, REG_TXPAUSE, *((u8 *)val));
1537 break;
1538 case HW_VAR_BCN_FUNC:
1539 hw_var_set_bcn_func(Adapter, variable, val);
1540 break;
1541 case HW_VAR_CORRECT_TSF:
1542 {
1543 u64 tsf;
1544 struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
1545 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1546
1547 tsf = pmlmeext->TSFValue - do_div(pmlmeext->TSFValue,
1548 pmlmeinfo->bcn_interval * 1024) - 1024; /* us */
1549
1550 if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
1551 StopTxBeacon(Adapter);
1552
1553 /* disable related TSF function */
1554 error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
1555 if (error)
1556 return;
1557
1558 rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(3)));
1559
1560 rtw_write32(Adapter, REG_TSFTR, tsf);
1561 rtw_write32(Adapter, REG_TSFTR + 4, tsf >> 32);
1562
1563 /* enable related TSF function */
1564 error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
1565 if (error)
1566 return;
1567
1568 rtw_write8(Adapter, REG_BCN_CTRL, tmp | BIT(3));
1569
1570 if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
1571 ResumeTxBeacon(Adapter);
1572 }
1573 break;
1574 case HW_VAR_CHECK_BSSID:
1575 if (*((u8 *)val)) {
1576 rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1577 } else {
1578 u32 val32;
1579
1580 val32 = rtw_read32(Adapter, REG_RCR);
1581
1582 val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1583
1584 rtw_write32(Adapter, REG_RCR, val32);
1585 }
1586 break;
1587 case HW_VAR_MLME_DISCONNECT:
1588 /* Set RCR to not to receive data frame when NO LINK state */
1589 /* reject all data frames */
1590 rtw_write16(Adapter, REG_RXFLTMAP2, 0x00);
1591
1592 /* reset TSF */
1593 rtw_write8(Adapter, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
1594
1595 /* disable update TSF */
1596 error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
1597 if (error)
1598 return;
1599
1600 rtw_write8(Adapter, REG_BCN_CTRL, tmp | BIT(4));
1601 break;
1602 case HW_VAR_MLME_SITESURVEY:
1603 if (*((u8 *)val)) { /* under sitesurvey */
1604 /* config RCR to receive different BSSID & not to receive data frame */
1605 u32 v = rtw_read32(Adapter, REG_RCR);
1606
1607 v &= ~(RCR_CBSSID_BCN);
1608 rtw_write32(Adapter, REG_RCR, v);
1609 /* reject all data frame */
1610 rtw_write16(Adapter, REG_RXFLTMAP2, 0x00);
1611
1612 /* disable update TSF */
1613 error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
1614 if (error)
1615 return;
1616 rtw_write8(Adapter, REG_BCN_CTRL, tmp | BIT(4));
1617 } else { /* sitesurvey done */
1618 struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
1619 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1620
1621 error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
1622 if (error)
1623 return;
1624
1625 if ((is_client_associated_to_ap(Adapter)) ||
1626 ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) {
1627 /* enable to rx data frame */
1628 rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
1629
1630 /* enable update TSF */
1631 rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(4)));
1632 } else if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
1633 rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
1634 /* enable update TSF */
1635 rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(4)));
1636 }
1637
1638 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
1639 rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN);
1640 } else {
1641 if (Adapter->in_cta_test) {
1642 u32 v = rtw_read32(Adapter, REG_RCR);
1643 v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* RCR_ADF */
1644 rtw_write32(Adapter, REG_RCR, v);
1645 } else {
1646 rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN);
1647 }
1648 }
1649 }
1650 break;
1651 case HW_VAR_MLME_JOIN:
1652 {
1653 u8 RetryLimit = 0x30;
1654 u8 type = *((u8 *)val);
1655 u8 tmp;
1656 struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
1657
1658 if (type == 0) { /* prepare to join */
1659 /* enable to rx data frame.Accept all data frame */
1660 rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
1661
1662 if (Adapter->in_cta_test) {
1663 u32 v = rtw_read32(Adapter, REG_RCR);
1664 v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* RCR_ADF */
1665 rtw_write32(Adapter, REG_RCR, v);
1666 } else {
1667 rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1668 }
1669
1670 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
1671 RetryLimit = (haldata->CustomerID == RT_CID_CCX) ? 7 : 48;
1672 else /* Ad-hoc Mode */
1673 RetryLimit = 0x7;
1674 } else if (type == 1) {
1675 /* joinbss_event call back when join res < 0 */
1676 rtw_write16(Adapter, REG_RXFLTMAP2, 0x00);
1677 } else if (type == 2) {
1678 /* sta add event call back */
1679 /* enable update TSF */
1680 error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
1681 if (error)
1682 return;
1683
1684 rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(4)));
1685
1686 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
1687 RetryLimit = 0x7;
1688 }
1689 rtw_write16(Adapter, REG_RL, RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT);
1690 }
1691 break;
1692 case HW_VAR_BEACON_INTERVAL:
1693 rtw_write16(Adapter, REG_BCN_INTERVAL, *((u16 *)val));
1694 break;
1695 case HW_VAR_SLOT_TIME:
1696 {
1697 u8 u1bAIFS, aSifsTime;
1698 struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
1699 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1700
1701 rtw_write8(Adapter, REG_SLOT, val[0]);
1702
1703 if (pmlmeinfo->WMM_enable == 0) {
1704 if (pmlmeext->cur_wireless_mode == WIRELESS_11B)
1705 aSifsTime = 10;
1706 else
1707 aSifsTime = 16;
1708
1709 u1bAIFS = aSifsTime + (2 * pmlmeinfo->slotTime);
1710
1711 /* <Roger_EXP> Temporary removed, 2008.06.20. */
1712 rtw_write8(Adapter, REG_EDCA_VO_PARAM, u1bAIFS);
1713 rtw_write8(Adapter, REG_EDCA_VI_PARAM, u1bAIFS);
1714 rtw_write8(Adapter, REG_EDCA_BE_PARAM, u1bAIFS);
1715 rtw_write8(Adapter, REG_EDCA_BK_PARAM, u1bAIFS);
1716 }
1717 }
1718 break;
1719 case HW_VAR_RESP_SIFS:
1720 /* RESP_SIFS for CCK */
1721 rtw_write8(Adapter, REG_R2T_SIFS, val[0]); /* SIFS_T2T_CCK (0x08) */
1722 rtw_write8(Adapter, REG_R2T_SIFS + 1, val[1]); /* SIFS_R2T_CCK(0x08) */
1723 /* RESP_SIFS for OFDM */
1724 rtw_write8(Adapter, REG_T2T_SIFS, val[2]); /* SIFS_T2T_OFDM (0x0a) */
1725 rtw_write8(Adapter, REG_T2T_SIFS + 1, val[3]); /* SIFS_R2T_OFDM(0x0a) */
1726 break;
1727 case HW_VAR_ACK_PREAMBLE:
1728 {
1729 u8 regTmp;
1730 u8 bShortPreamble = *((bool *)val);
1731 /* Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily) */
1732 regTmp = (haldata->nCur40MhzPrimeSC) << 5;
1733 if (bShortPreamble)
1734 regTmp |= 0x80;
1735
1736 rtw_write8(Adapter, REG_RRSR + 2, regTmp);
1737 }
1738 break;
1739 case HW_VAR_SEC_CFG:
1740 rtw_write8(Adapter, REG_SECCFG, *((u8 *)val));
1741 break;
1742 case HW_VAR_DM_FLAG:
1743 podmpriv->SupportAbility = *((u8 *)val);
1744 break;
1745 case HW_VAR_DM_FUNC_OP:
1746 if (val[0])
1747 podmpriv->BK_SupportAbility = podmpriv->SupportAbility;
1748 else
1749 podmpriv->SupportAbility = podmpriv->BK_SupportAbility;
1750 break;
1751 case HW_VAR_DM_FUNC_SET:
1752 if (*((u32 *)val) == DYNAMIC_ALL_FUNC_ENABLE) {
1753 pdmpriv->DMFlag = pdmpriv->InitDMFlag;
1754 podmpriv->SupportAbility = pdmpriv->InitODMFlag;
1755 } else {
1756 podmpriv->SupportAbility |= *((u32 *)val);
1757 }
1758 break;
1759 case HW_VAR_DM_FUNC_CLR:
1760 podmpriv->SupportAbility &= *((u32 *)val);
1761 break;
1762 case HW_VAR_CAM_EMPTY_ENTRY:
1763 {
1764 u8 ucIndex = *((u8 *)val);
1765 u8 i;
1766 u32 ulCommand = 0;
1767 u32 ulContent = 0;
1768 u32 ulEncAlgo = CAM_AES;
1769
1770 for (i = 0; i < CAM_CONTENT_COUNT; i++) {
1771 /* filled id in CAM config 2 byte */
1772 if (i == 0)
1773 ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo) << 2);
1774 else
1775 ulContent = 0;
1776 /* polling bit, and No Write enable, and address */
1777 ulCommand = CAM_CONTENT_COUNT * ucIndex + i;
1778 ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
1779 /* write content 0 is equall to mark invalid */
1780 rtw_write32(Adapter, WCAMI, ulContent); /* delay_ms(40); */
1781 rtw_write32(Adapter, RWCAM, ulCommand); /* delay_ms(40); */
1782 }
1783 }
1784 break;
1785 case HW_VAR_CAM_INVALID_ALL:
1786 rtw_write32(Adapter, RWCAM, BIT(31) | BIT(30));
1787 break;
1788 case HW_VAR_CAM_WRITE:
1789 {
1790 u32 cmd;
1791 u32 *cam_val = (u32 *)val;
1792 rtw_write32(Adapter, WCAMI, cam_val[0]);
1793
1794 cmd = CAM_POLLINIG | CAM_WRITE | cam_val[1];
1795 rtw_write32(Adapter, RWCAM, cmd);
1796 }
1797 break;
1798 case HW_VAR_AC_PARAM_VO:
1799 rtw_write32(Adapter, REG_EDCA_VO_PARAM, ((u32 *)(val))[0]);
1800 break;
1801 case HW_VAR_AC_PARAM_VI:
1802 rtw_write32(Adapter, REG_EDCA_VI_PARAM, ((u32 *)(val))[0]);
1803 break;
1804 case HW_VAR_AC_PARAM_BE:
1805 haldata->AcParam_BE = ((u32 *)(val))[0];
1806 rtw_write32(Adapter, REG_EDCA_BE_PARAM, ((u32 *)(val))[0]);
1807 break;
1808 case HW_VAR_AC_PARAM_BK:
1809 rtw_write32(Adapter, REG_EDCA_BK_PARAM, ((u32 *)(val))[0]);
1810 break;
1811 case HW_VAR_ACM_CTRL:
1812 {
1813 u8 acm_ctrl = *((u8 *)val);
1814 u8 AcmCtrl;
1815
1816 error = rtw_read8(Adapter, REG_ACMHWCTRL, &AcmCtrl);
1817 if (error)
1818 return;
1819
1820 if (acm_ctrl > 1)
1821 AcmCtrl = AcmCtrl | 0x1;
1822
1823 if (acm_ctrl & BIT(3))
1824 AcmCtrl |= AcmHw_VoqEn;
1825 else
1826 AcmCtrl &= (~AcmHw_VoqEn);
1827
1828 if (acm_ctrl & BIT(2))
1829 AcmCtrl |= AcmHw_ViqEn;
1830 else
1831 AcmCtrl &= (~AcmHw_ViqEn);
1832
1833 if (acm_ctrl & BIT(1))
1834 AcmCtrl |= AcmHw_BeqEn;
1835 else
1836 AcmCtrl &= (~AcmHw_BeqEn);
1837
1838 DBG_88E("[HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl);
1839 rtw_write8(Adapter, REG_ACMHWCTRL, AcmCtrl);
1840 }
1841 break;
1842 case HW_VAR_AMPDU_MIN_SPACE:
1843 {
1844 u8 MinSpacingToSet;
1845 u8 SecMinSpace;
1846 u8 tmp;
1847
1848 MinSpacingToSet = *((u8 *)val);
1849 if (MinSpacingToSet <= 7) {
1850 switch (Adapter->securitypriv.dot11PrivacyAlgrthm) {
1851 case _NO_PRIVACY_:
1852 case _AES_:
1853 SecMinSpace = 0;
1854 break;
1855 case _WEP40_:
1856 case _WEP104_:
1857 case _TKIP_:
1858 case _TKIP_WTMIC_:
1859 SecMinSpace = 6;
1860 break;
1861 default:
1862 SecMinSpace = 7;
1863 break;
1864 }
1865 if (MinSpacingToSet < SecMinSpace)
1866 MinSpacingToSet = SecMinSpace;
1867
1868 error = rtw_read8(Adapter, REG_AMPDU_MIN_SPACE, &tmp);
1869 if (error)
1870 return;
1871
1872 rtw_write8(Adapter, REG_AMPDU_MIN_SPACE, (tmp & 0xf8) |
1873 MinSpacingToSet);
1874 }
1875 }
1876 break;
1877 case HW_VAR_AMPDU_FACTOR:
1878 {
1879 u8 RegToSet_Normal[4] = {0x41, 0xa8, 0x72, 0xb9};
1880 u8 FactorToSet;
1881 u8 *pRegToSet;
1882 u8 index = 0;
1883
1884 pRegToSet = RegToSet_Normal; /* 0xb972a841; */
1885 FactorToSet = *((u8 *)val);
1886 if (FactorToSet <= 3) {
1887 FactorToSet = (1 << (FactorToSet + 2));
1888 if (FactorToSet > 0xf)
1889 FactorToSet = 0xf;
1890
1891 for (index = 0; index < 4; index++) {
1892 if ((pRegToSet[index] & 0xf0) > (FactorToSet << 4))
1893 pRegToSet[index] = (pRegToSet[index] & 0x0f) | (FactorToSet << 4);
1894
1895 if ((pRegToSet[index] & 0x0f) > FactorToSet)
1896 pRegToSet[index] = (pRegToSet[index] & 0xf0) | (FactorToSet);
1897
1898 rtw_write8(Adapter, (REG_AGGLEN_LMT + index), pRegToSet[index]);
1899 }
1900 }
1901 }
1902 break;
1903 case HW_VAR_RXDMA_AGG_PG_TH:
1904 {
1905 u8 threshold = *((u8 *)val);
1906 if (threshold == 0)
1907 threshold = haldata->UsbRxAggPageCount;
1908 rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH, threshold);
1909 }
1910 break;
1911 case HW_VAR_SET_RPWM:
1912 break;
1913 case HW_VAR_H2C_FW_PWRMODE:
1914 {
1915 u8 psmode = (*(u8 *)val);
1916
1917 /* Forece leave RF low power mode for 1T1R to prevent conficting setting in Fw power */
1918 /* saving sequence. 2010.06.07. Added by tynli. Suggested by SD3 yschang. */
1919 if ((psmode != PS_MODE_ACTIVE) && (!IS_92C_SERIAL(haldata->VersionID)))
1920 ODM_RF_Saving(podmpriv, true);
1921 rtl8188e_set_FwPwrMode_cmd(Adapter, psmode);
1922 }
1923 break;
1924 case HW_VAR_H2C_FW_JOINBSSRPT:
1925 {
1926 u8 mstatus = (*(u8 *)val);
1927 rtl8188e_set_FwJoinBssReport_cmd(Adapter, mstatus);
1928 }
1929 break;
1930 #ifdef CONFIG_88EU_P2P
1931 case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
1932 {
1933 u8 p2p_ps_state = (*(u8 *)val);
1934 rtl8188e_set_p2p_ps_offload_cmd(Adapter, p2p_ps_state);
1935 }
1936 break;
1937 #endif
1938 case HW_VAR_INITIAL_GAIN:
1939 {
1940 struct rtw_dig *pDigTable = &podmpriv->DM_DigTable;
1941 u32 rx_gain = ((u32 *)(val))[0];
1942
1943 if (rx_gain == 0xff) {/* restore rx gain */
1944 ODM_Write_DIG(podmpriv, pDigTable->BackupIGValue);
1945 } else {
1946 pDigTable->BackupIGValue = pDigTable->CurIGValue;
1947 ODM_Write_DIG(podmpriv, rx_gain);
1948 }
1949 }
1950 break;
1951 case HW_VAR_TRIGGER_GPIO_0:
1952 rtl8192cu_trigger_gpio_0(Adapter);
1953 break;
1954 case HW_VAR_RPT_TIMER_SETTING:
1955 {
1956 u16 min_rpt_time = (*(u16 *)val);
1957 ODM_RA_Set_TxRPT_Time(podmpriv, min_rpt_time);
1958 }
1959 break;
1960 case HW_VAR_ANTENNA_DIVERSITY_SELECT:
1961 {
1962 u8 Optimum_antenna = (*(u8 *)val);
1963 u8 Ant;
1964 /* switch antenna to Optimum_antenna */
1965 if (haldata->CurAntenna != Optimum_antenna) {
1966 Ant = (Optimum_antenna == 2) ? MAIN_ANT : AUX_ANT;
1967 ODM_UpdateRxIdleAnt_88E(&haldata->odmpriv, Ant);
1968
1969 haldata->CurAntenna = Optimum_antenna;
1970 }
1971 }
1972 break;
1973 case HW_VAR_EFUSE_BYTES: /* To set EFUE total used bytes, added by Roger, 2008.12.22. */
1974 haldata->EfuseUsedBytes = *((u16 *)val);
1975 break;
1976 case HW_VAR_FIFO_CLEARN_UP:
1977 {
1978 struct pwrctrl_priv *pwrpriv = &Adapter->pwrctrlpriv;
1979 u8 trycnt = 100;
1980
1981 /* pause tx */
1982 rtw_write8(Adapter, REG_TXPAUSE, 0xff);
1983
1984 /* keep sn */
1985 Adapter->xmitpriv.nqos_ssn = rtw_read16(Adapter, REG_NQOS_SEQ);
1986
1987 if (!pwrpriv->bkeepfwalive) {
1988 /* RX DMA stop */
1989 rtw_write32(Adapter, REG_RXPKT_NUM, (rtw_read32(Adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
1990 do {
1991 if (!(rtw_read32(Adapter, REG_RXPKT_NUM) & RXDMA_IDLE))
1992 break;
1993 } while (trycnt--);
1994 if (trycnt == 0)
1995 DBG_88E("Stop RX DMA failed......\n");
1996
1997 /* RQPN Load 0 */
1998 rtw_write16(Adapter, REG_RQPN_NPQ, 0x0);
1999 rtw_write32(Adapter, REG_RQPN, 0x80000000);
2000 mdelay(10);
2001 }
2002 }
2003 break;
2004 case HW_VAR_CHECK_TXBUF:
2005 break;
2006 case HW_VAR_APFM_ON_MAC:
2007 haldata->bMacPwrCtrlOn = *val;
2008 DBG_88E("%s: bMacPwrCtrlOn=%d\n", __func__, haldata->bMacPwrCtrlOn);
2009 break;
2010 case HW_VAR_TX_RPT_MAX_MACID:
2011 {
2012 u8 maxMacid = *val;
2013 DBG_88E("### MacID(%d),Set Max Tx RPT MID(%d)\n", maxMacid, maxMacid + 1);
2014 rtw_write8(Adapter, REG_TX_RPT_CTRL + 1, maxMacid + 1);
2015 }
2016 break;
2017 case HW_VAR_H2C_MEDIA_STATUS_RPT:
2018 rtl8188e_set_FwMediaStatus_cmd(Adapter, (*(__le16 *)val));
2019 break;
2020 case HW_VAR_BCN_VALID:
2021 /* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
> 2022 u8 tmp;
2023
2024 error = rtw_read8(Adapter, REG_TDECTRL + 2, &tmp);
2025 if (error)
2026 return;
2027
2028 rtw_write8(Adapter, REG_TDECTRL + 2, tmp | BIT(0));
2029 break;
2030 default:
2031 break;
2032 }
2033
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]
On Wednesday, August 25, 2021 11:55:37 AM CEST Pavel Skripkin wrote:
> On 8/25/21 12:48 PM, Fabio M. De Francesco wrote:
> > On Wednesday, August 25, 2021 10:22:16 AM CEST Pavel Skripkin wrote:
> >> On 8/25/21 7:35 AM, Fabio M. De Francesco wrote:
> >> > Dear Pavel,
> >> >
> >> > Please note that if and when my patch "Use usb_control_msg_recv / send () in
> >> > usbctrl_vendorreq ()" will be merged, "if (res! = len)" will always evaluate 'true'
> >> > and usb_read16 () will always return -EIO even if usbctrl_vendorreq () succeeds.
> >> >
> >>
> >> Yep, thank you, but it depends on which series will go in first :)
> >>
> >> There is a chance, that you will need to clean up this part, if mine
> >> will be merged before yours
> >>
> >
> > Ha-ha ... I know that beautiful rule: whoever breaks must fix!
> > However there should be another rule which says that
> > the old (me) takes precedence over the young (you) :-)
> >
>
> The main problem, that no one knows who is the "old". Greg can take
> patches in any order he wants, because they are naturally independent :)
>
>
> We only can say smth like "this one depends on this one" as reply to
> patch to inform Greg about the situation.
>
> > Seriously, thank you so much for your help and the "Reviewed by"
> > tag on my work.
> >
>
> You too :) We are doing same job here for the good of community and
> kernel itself
>
Pavel, Dan,
Did you really take my "old" vs. "young" precedence rule seriously?
I was just kidding, ahead of thanking Pavel for his "Reviewed-by" tag
to my patch.
That statement deserved no comment. I thought it was
clear it was just a joke :)
Thanks,
Fabio
>
>
> With regards,
> Pavel Skripkin
>
On Wed, Aug 25, 2021 at 01:06:40PM +0200, Fabio M. De Francesco wrote:
> On Wednesday, August 25, 2021 12:38:02 PM CEST Dan Carpenter wrote:
> > On Wed, Aug 25, 2021 at 01:13:54PM +0300, Pavel Skripkin wrote:
> > > Both series are pending right now and made on top of staging-next branch.
> > > Who needs to rebase? I think, applying these series as-is can broke the
> > > driver, since error handling will be broken
> >
> > That's a bug then. The patch should be rejected. You're not allowed to
> > break the code.
>
> Sorry Dan, I disagree. It's not a bug. No one intend to break the code.
> How could anyone know that someone else is working simultaneously on
> some code that is not compatible with the work of the other developer?
Okay, I haven't been following the discussion closely. If these patches
introduce a known bug, then I am going to be cross.
I'm really stressed out right now. If you at all suspect that your
patches are going to introduce bugs then just go back and say "Sorry,
don't take this one, the way it conflicts with Pavels ends up
introducing a bug. I'll resend after Pavel's patches are applied."
regards,
dan carpenter
On Wednesday, August 25, 2021 1:31:22 PM CEST Dan Carpenter wrote:
> On Wed, Aug 25, 2021 at 01:06:40PM +0200, Fabio M. De Francesco wrote:
> > On Wednesday, August 25, 2021 12:38:02 PM CEST Dan Carpenter wrote:
> > > On Wed, Aug 25, 2021 at 01:13:54PM +0300, Pavel Skripkin wrote:
> > > > Both series are pending right now and made on top of staging-next branch.
> > > > Who needs to rebase? I think, applying these series as-is can broke the
> > > > driver, since error handling will be broken
> > >
> > > That's a bug then. The patch should be rejected. You're not allowed to
> > > break the code.
> >
> > Sorry Dan, I disagree. It's not a bug. No one intend to break the code.
> > How could anyone know that someone else is working simultaneously on
> > some code that is not compatible with the work of the other developer?
>
> Okay, I haven't been following the discussion closely. If these patches
> introduce a known bug, then I am going to be cross.
>
> I'm really stressed out right now. If you at all suspect that your
> patches are going to introduce bugs then just go back and say "Sorry,
> don't take this one, the way it conflicts with Pavel's ends up
> introducing a bug. I'll resend after Pavel's patches are applied."
>
> regards,
> dan carpenter
>
Dear Dan,
Yours is a nice solution to this problem.
I had thought that I should have waited for Greg to ask to take into account Pavel's
series, change some lines of his code (because they are the only users of the new
version of the helper function, that is my work - as suggested by Greg himself),
rebase and resend, I really think that your idea is better.
I'll do as you suggest ASAP, within the end of the day (now I have to go).
Thanks very much.
Fabio
On Wed, Aug 25, 2021 at 03:17:06PM +0300, Pavel Skripkin wrote:
> On 8/25/21 3:05 PM, kernel test robot wrote:
> > Hi Pavel,
> >
> > Thank you for the patch! Yet something to improve:
> >
> > [auto build test ERROR on staging/staging-testing]
> >
> > url: https://github.com/0day-ci/linux/commits/Pavel-Skripkin/staging-r8188eu-remove-read-write-_macreg/20210824-162756
> > base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git 093991aaadf0fbb34184fa37a46e7a157da3f386
> > config: arm-buildonly-randconfig-r001-20210825 (attached as .config)
> > compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project ea08c4cd1c0869ec5024a8bb3f5cdf06ab03ae83)
> > reproduce (this is a W=1 build):
> > wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> > chmod +x ~/bin/make.cross
> > # install arm cross compiling tool for clang build
> > # apt-get install 11.1.1
> > # https://github.com/0day-ci/linux/commit/d4e4bbed4e59df37967086f60fe92cb1b4504d37
> > git remote add linux-review https://github.com/0day-ci/linux
> > git fetch --no-tags linux-review Pavel-Skripkin/staging-r8188eu-remove-read-write-_macreg/20210824-162756
> > git checkout d4e4bbed4e59df37967086f60fe92cb1b4504d37
> > # save the attached .config to linux build tree
> > mkdir build_dir
> > COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross O=build_dir ARCH=arm SHELL=/bin/bash drivers/staging/r8188eu/
> >
> > If you fix the issue, kindly add following tag as appropriate
> > Reported-by: kernel test robot <[email protected]>
> >
> > All errors (new ones prefixed by >>):
> >
> > > > drivers/staging/r8188eu/hal/usb_halinit.c:2022:3: error: expected expression
> > u8 tmp;
> > ^
> > 1 error generated.
> >
> > Kconfig warnings: (for reference only)
> > WARNING: unmet direct dependencies detected for QCOM_SCM
> > Depends on (ARM || ARM64) && HAVE_ARM_SMCCC
> > Selected by
> > - ARM_QCOM_SPM_CPUIDLE && CPU_IDLE && (ARM || ARM64) && (ARCH_QCOM || COMPILE_TEST && !ARM64 && MMU
> >
> >
>
> We need to fix Kconfig, ok, I will take a look at it later
>
This is not related to your patch. Ignore it.
> > vim +2022 drivers/staging/r8188eu/hal/usb_halinit.c
> >
>
> > 2020 case HW_VAR_BCN_VALID:
> > 2021 /* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
> > > 2022 u8 tmp;
>
> Hm, I don't know anything about ARM compilers, so should I wrap this code
> block with {}?
Yep.
>
> My local gcc 11.1.1 (x86_64) does not produce any warnings/errors
>
You should figure out whats up with that because it shouldn't compile
with the gcc options that the kernel uses.
regards,
dan carpenter
On 8/25/21 3:51 PM, Dan Carpenter wrote:
> On Wed, Aug 25, 2021 at 03:17:06PM +0300, Pavel Skripkin wrote:
>> On 8/25/21 3:05 PM, kernel test robot wrote:
>> > Hi Pavel,
>> >
>> > Thank you for the patch! Yet something to improve:
>> >
>> > [auto build test ERROR on staging/staging-testing]
>> >
>> > url: https://github.com/0day-ci/linux/commits/Pavel-Skripkin/staging-r8188eu-remove-read-write-_macreg/20210824-162756
>> > base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git 093991aaadf0fbb34184fa37a46e7a157da3f386
>> > config: arm-buildonly-randconfig-r001-20210825 (attached as .config)
>> > compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project ea08c4cd1c0869ec5024a8bb3f5cdf06ab03ae83)
>> > reproduce (this is a W=1 build):
>> > wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>> > chmod +x ~/bin/make.cross
>> > # install arm cross compiling tool for clang build
>> > # apt-get install 11.1.1
>> > # https://github.com/0day-ci/linux/commit/d4e4bbed4e59df37967086f60fe92cb1b4504d37
>> > git remote add linux-review https://github.com/0day-ci/linux
>> > git fetch --no-tags linux-review Pavel-Skripkin/staging-r8188eu-remove-read-write-_macreg/20210824-162756
>> > git checkout d4e4bbed4e59df37967086f60fe92cb1b4504d37
>> > # save the attached .config to linux build tree
>> > mkdir build_dir
>> > COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross O=build_dir ARCH=arm SHELL=/bin/bash drivers/staging/r8188eu/
>> >
>> > If you fix the issue, kindly add following tag as appropriate
>> > Reported-by: kernel test robot <[email protected]>
>> >
>> > All errors (new ones prefixed by >>):
>> >
>> > > > drivers/staging/r8188eu/hal/usb_halinit.c:2022:3: error: expected expression
>> > u8 tmp;
>> > ^
>> > 1 error generated.
>> >
>> > Kconfig warnings: (for reference only)
>> > WARNING: unmet direct dependencies detected for QCOM_SCM
>> > Depends on (ARM || ARM64) && HAVE_ARM_SMCCC
>> > Selected by
>> > - ARM_QCOM_SPM_CPUIDLE && CPU_IDLE && (ARM || ARM64) && (ARCH_QCOM || COMPILE_TEST && !ARM64 && MMU
>> >
>> >
>>
>> We need to fix Kconfig, ok, I will take a look at it later
>>
>
> This is not related to your patch. Ignore it.
>
>
>> > vim +2022 drivers/staging/r8188eu/hal/usb_halinit.c
>> >
>>
>> > 2020 case HW_VAR_BCN_VALID:
>> > 2021 /* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
>> > > 2022 u8 tmp;
>>
>> Hm, I don't know anything about ARM compilers, so should I wrap this code
>> block with {}?
>
> Yep.
>
>>
>> My local gcc 11.1.1 (x86_64) does not produce any warnings/errors
>>
>
> You should figure out whats up with that because it shouldn't compile
> with the gcc options that the kernel uses.
>
AFAIK, at least 2 guys except me in this CC list compiled my series
without errors/warnings. Maybe, staging tree is missing some Makefile
updates?
I'll resend series this evening anyway, but this is strange....
With regards,
Pavel Skripkin
On 8/25/21 4:34 PM, Dan Carpenter wrote:
> On Wed, Aug 25, 2021 at 04:02:26PM +0300, Pavel Skripkin wrote:
>> > This is not related to your patch. Ignore it.
>> >
>> >
>> > > > vim +2022 drivers/staging/r8188eu/hal/usb_halinit.c
>> > > >
>> > >
>> > > > 2020 case HW_VAR_BCN_VALID:
>> > > > 2021 /* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
>> > > > > 2022 u8 tmp;
>> > >
>> > > Hm, I don't know anything about ARM compilers, so should I wrap this code
>> > > block with {}?
>> >
>> > Yep.
>> >
>> > >
>> > > My local gcc 11.1.1 (x86_64) does not produce any warnings/errors
>> > >
>> >
>> > You should figure out whats up with that because it shouldn't compile
>> > with the gcc options that the kernel uses.
>> >
>>
>> AFAIK, at least 2 guys except me in this CC list compiled my series without
>> errors/warnings. Maybe, staging tree is missing some Makefile updates?
>>
>>
>> I'll resend series this evening anyway, but this is strange....
>
> Hm... In my version of GCC the error is:
>
> drivers/staging/r8188eu/hal/usb_halinit.c:1870:3: error: a label can only be part of a statement and a declaration is not a statement
>
> That's a different error from what I was expecting. It's caused by
> having a declaration directly after a case statement. The warning that
> I was expecting was from -Wdeclaration-after-statement and it looks
> like this:
>
> warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
>
> You really should try investigate why this compiles for you because
> something is going wrong. It should not build without a warning.
>
Looks like it's bug in gcc 11.1.1. I've rebuilt this module with gcc 10
(gcc-10 (SUSE Linux) 10.3.1 20210707 [revision
048117e16c77f82598fca9af585500572d46ad73]) and build fails with error
described above
My default gcc is
gcc (SUSE Linux) 11.1.1 20210721 [revision
076930b9690ac3564638636f6b13bbb6bc608aea]
Any idea? :)
With regards,
Pavel Skripkin
On 8/25/21 3:05 PM, kernel test robot wrote:
> Hi Pavel,
>
> Thank you for the patch! Yet something to improve:
>
> [auto build test ERROR on staging/staging-testing]
>
> url: https://github.com/0day-ci/linux/commits/Pavel-Skripkin/staging-r8188eu-remove-read-write-_macreg/20210824-162756
> base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git 093991aaadf0fbb34184fa37a46e7a157da3f386
> config: arm-buildonly-randconfig-r001-20210825 (attached as .config)
> compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project ea08c4cd1c0869ec5024a8bb3f5cdf06ab03ae83)
> reproduce (this is a W=1 build):
> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # install arm cross compiling tool for clang build
> # apt-get install 11.1.1
> # https://github.com/0day-ci/linux/commit/d4e4bbed4e59df37967086f60fe92cb1b4504d37
> git remote add linux-review https://github.com/0day-ci/linux
> git fetch --no-tags linux-review Pavel-Skripkin/staging-r8188eu-remove-read-write-_macreg/20210824-162756
> git checkout d4e4bbed4e59df37967086f60fe92cb1b4504d37
> # save the attached .config to linux build tree
> mkdir build_dir
> COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross O=build_dir ARCH=arm SHELL=/bin/bash drivers/staging/r8188eu/
>
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <[email protected]>
>
> All errors (new ones prefixed by >>):
>
>>> drivers/staging/r8188eu/hal/usb_halinit.c:2022:3: error: expected expression
> u8 tmp;
> ^
> 1 error generated.
>
> Kconfig warnings: (for reference only)
> WARNING: unmet direct dependencies detected for QCOM_SCM
> Depends on (ARM || ARM64) && HAVE_ARM_SMCCC
> Selected by
> - ARM_QCOM_SPM_CPUIDLE && CPU_IDLE && (ARM || ARM64) && (ARCH_QCOM || COMPILE_TEST && !ARM64 && MMU
>
>
We need to fix Kconfig, ok, I will take a look at it later
> vim +2022 drivers/staging/r8188eu/hal/usb_halinit.c
>
> 2020 case HW_VAR_BCN_VALID:
> 2021 /* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
>> 2022 u8 tmp;
Hm, I don't know anything about ARM compilers, so should I wrap this
code block with {}?
My local gcc 11.1.1 (x86_64) does not produce any warnings/errors
> 2023
> 2024 error = rtw_read8(Adapter, REG_TDECTRL + 2, &tmp);
> 2025 if (error)
> 2026 return;
> 2027
> 2028 rtw_write8(Adapter, REG_TDECTRL + 2, tmp | BIT(0));
> 2029 break;
> 2030 default:
> 2031 break;
> 2032 }
> 2033
>
With regards,
Pavel Skripkin
On Wed, Aug 25, 2021 at 04:02:26PM +0300, Pavel Skripkin wrote:
> > This is not related to your patch. Ignore it.
> >
> >
> > > > vim +2022 drivers/staging/r8188eu/hal/usb_halinit.c
> > > >
> > >
> > > > 2020 case HW_VAR_BCN_VALID:
> > > > 2021 /* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
> > > > > 2022 u8 tmp;
> > >
> > > Hm, I don't know anything about ARM compilers, so should I wrap this code
> > > block with {}?
> >
> > Yep.
> >
> > >
> > > My local gcc 11.1.1 (x86_64) does not produce any warnings/errors
> > >
> >
> > You should figure out whats up with that because it shouldn't compile
> > with the gcc options that the kernel uses.
> >
>
> AFAIK, at least 2 guys except me in this CC list compiled my series without
> errors/warnings. Maybe, staging tree is missing some Makefile updates?
>
>
> I'll resend series this evening anyway, but this is strange....
Hm... In my version of GCC the error is:
drivers/staging/r8188eu/hal/usb_halinit.c:1870:3: error: a label can only be part of a statement and a declaration is not a statement
That's a different error from what I was expecting. It's caused by
having a declaration directly after a case statement. The warning that
I was expecting was from -Wdeclaration-after-statement and it looks
like this:
warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
You really should try investigate why this compiles for you because
something is going wrong. It should not build without a warning.
regards,
dan carpenter
On Wed, Aug 25, 2021 at 6:44 AM Pavel Skripkin <[email protected]> wrote:
>
> On 8/25/21 4:34 PM, Dan Carpenter wrote:
> > On Wed, Aug 25, 2021 at 04:02:26PM +0300, Pavel Skripkin wrote:
> >> > This is not related to your patch. Ignore it.
> >> >
> >> >
> >> > > > vim +2022 drivers/staging/r8188eu/hal/usb_halinit.c
> >> > > >
> >> > >
> >> > > > 2020 case HW_VAR_BCN_VALID:
> >> > > > 2021 /* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
> >> > > > > 2022 u8 tmp;
> >> > >
> >> > > Hm, I don't know anything about ARM compilers, so should I wrap this code
> >> > > block with {}?
> >> >
> >> > Yep.
> >> >
> >> > >
> >> > > My local gcc 11.1.1 (x86_64) does not produce any warnings/errors
> >> > >
> >> >
> >> > You should figure out whats up with that because it shouldn't compile
> >> > with the gcc options that the kernel uses.
> >> >
> >>
> >> AFAIK, at least 2 guys except me in this CC list compiled my series without
> >> errors/warnings. Maybe, staging tree is missing some Makefile updates?
> >>
> >>
> >> I'll resend series this evening anyway, but this is strange....
> >
> > Hm... In my version of GCC the error is:
> >
> > drivers/staging/r8188eu/hal/usb_halinit.c:1870:3: error: a label can only be part of a statement and a declaration is not a statement
> >
> > That's a different error from what I was expecting. It's caused by
> > having a declaration directly after a case statement. The warning that
> > I was expecting was from -Wdeclaration-after-statement and it looks
> > like this:
> >
> > warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
> >
> > You really should try investigate why this compiles for you because
> > something is going wrong. It should not build without a warning.
> >
>
> Looks like it's bug in gcc 11.1.1. I've rebuilt this module with gcc 10
> (gcc-10 (SUSE Linux) 10.3.1 20210707 [revision
> 048117e16c77f82598fca9af585500572d46ad73]) and build fails with error
> described above
>
>
> My default gcc is
>
> gcc (SUSE Linux) 11.1.1 20210721 [revision
> 076930b9690ac3564638636f6b13bbb6bc608aea]
>
>
> Any idea? :)
The original report said the build was with clang-14, which is near
top of tree and unreleased. It's possible that that build had a bug
that hopefully was reverted.
--
Thanks,
~Nick Desaulniers
On Tuesday, August 24, 2021 9:27:27 AM CEST Pavel Skripkin wrote:
> _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 <[email protected]>
Dear Pavel,
I have to inform you that building patch v3 3/6 with gcc (version 11.1.1 20210721
[revision 076930b9690ac3564638636f6b13bbb6bc608aea] (SUSE Linux)), gives
the following warning:
drivers/staging/r8188eu/os_dep/ioctl_linux.c:2258:13: warning: variable ‘error’ set but not used [-Wunused-but-set-variable]
2258 | int error;
| ^~~~~
I'm sorry, but I guess that for some reason previously I had only built v2 of your patch
which had no warnings at all.
Unfortunately, introducing warnings is not allowed.
While we are at this, I can also confirm that GCC 11.1.1 _does_ _not_ emit the warning
that has been reported by the kernel test robot.
Regards,
Fabio
On 8/26/21 2:45 AM, Fabio M. De Francesco wrote:
> On Tuesday, August 24, 2021 9:27:27 AM CEST Pavel Skripkin wrote:
>> _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 <[email protected]>
>
> Dear Pavel,
>
> I have to inform you that building patch v3 3/6 with gcc (version 11.1.1 20210721
> [revision 076930b9690ac3564638636f6b13bbb6bc608aea] (SUSE Linux)), gives
> the following warning:
>
> drivers/staging/r8188eu/os_dep/ioctl_linux.c:2258:13: warning: variable ‘error’ set but not used [-Wunused-but-set-variable]
> 2258 | int error;
> | ^~~~~
>
> I'm sorry, but I guess that for some reason previously I had only built v2 of your patch
> which had no warnings at all.
>
> Unfortunately, introducing warnings is not allowed.
>
> While we are at this, I can also confirm that GCC 11.1.1 _does_ _not_ emit the warning
> that has been reported by the kernel test robot.
>
Yep, I see, thank you. v4 is on the way... I had a plan to send v4
yesterday, but I've finally received r8188eu device.
I tried to connect it and test and.... driver didn't work :) So, I will
try to figure out the problem with driver (or device) and will send v4.
Again, thank you for report :) My default gcc is too polite...
With regards,
Pavel Skripkin
From: Pavel Skripkin
> Sent: 24 August 2021 08:27
>
> _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.
...
> + len += snprintf(page + len, count - len, "rtw_read8(0x%x)=0x%x\n",
> + proc_get_read_addr, (u8) tmp);
That is broken.
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
On Thu, 26 Aug 2021 08:21:34 +0000
David Laight <[email protected]> wrote:
> From: Pavel Skripkin
> > Sent: 24 August 2021 08:27
> >
> > _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.
>
> ...
> > + len += snprintf(page + len, count - len,
> > "rtw_read8(0x%x)=0x%x\n",
> > + proc_get_read_addr, (u8) tmp);
>
> That is broken.
>
Don't get it, sorry. Previous code did exactly the same thing, but
didn't check if read() was successful.
With regards,
Pavel Skripkin
From: Pavel Skripkin <[email protected]>
> Sent: 24 August 2021 08:28
>
> _rtw_read32 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_read32() 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.
Pretty horrid API interface.
Functions like readl() - which can fail just return ~0u and let
the caller worry about whether that causes serious grief.
You could make all the read functions return __u64 and return ~0ull
on error.
Testing for (value & 1ull << 63) will be reasonable even on 32bit.
...
> -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
> {
> u8 requesttype;
> u16 wvalue;
> u16 len;
> - __le32 data;
> + int res;
> + __le32 tmp;
> +
> + if (WARN_ON(unlikely(!data)))
> + return -EINVAL;
>
Kill the NULL check - it is a silly coding error.
An OOPS is just as easy to debug.
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
On Thu, 26 Aug 2021 08:51:23 +0000
David Laight <[email protected]> wrote:
> From: Pavel Skripkin <[email protected]>
> > Sent: 24 August 2021 08:28
> >
> > _rtw_read32 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_read32() 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.
>
> Pretty horrid API interface.
> Functions like readl() - which can fail just return ~0u and let
> the caller worry about whether that causes serious grief.
>
> You could make all the read functions return __u64 and return ~0ull
> on error.
> Testing for (value & 1ull << 63) will be reasonable even on 32bit.
>
I am not the best at API related questions, so can you, please,
explain why your approach is better?
As I can see, most of the drivers in usb/ directory use smth like this
interface for private reading funcions. We anyway creating tmp variable
(but 64 bit _always_) and checking for mistery error, which we cannot
pass up to callers.
Sorry, if it's _too_ dumb question, but I really can't get your
point....
> ...
> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32
> > *data) {
> > u8 requesttype;
> > u16 wvalue;
> > u16 len;
> > - __le32 data;
> > + int res;
> > + __le32 tmp;
> > +
> > + if (WARN_ON(unlikely(!data)))
> > + return -EINVAL;
> >
>
> Kill the NULL check - it is a silly coding error.
> An OOPS is just as easy to debug.
>
I don't think that one single driver should kill the whole system. It's
100% an error, but kernel can recover from it (for example disconnect
the driver, since it's broken).
AFIAK, Greg and Linus do not like BUG_ONs in recoverable state...
Correct me, if I am wrong
With regards,
Pavel Skripkin
On 8/26/21 12:22 PM, Pavel Skripkin wrote:
> On Thu, 26 Aug 2021 08:51:23 +0000
> David Laight <[email protected]> wrote:
>
>> From: Pavel Skripkin <[email protected]>
>> > Sent: 24 August 2021 08:28
>> >
>> > _rtw_read32 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_read32() 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.
>>
>> Pretty horrid API interface.
>> Functions like readl() - which can fail just return ~0u and let
>> the caller worry about whether that causes serious grief.
>>
>> You could make all the read functions return __u64 and return ~0ull
>> on error.
>> Testing for (value & 1ull << 63) will be reasonable even on 32bit.
>>
>
> I am not the best at API related questions, so can you, please,
> explain why your approach is better?
>
> As I can see, most of the drivers in usb/ directory use smth like this
> interface for private reading funcions. We anyway creating tmp variable
> (but 64 bit _always_) and checking for mistery error, which we cannot
> pass up to callers.
>
> Sorry, if it's _too_ dumb question, but I really can't get your
> point....
>
>
>
>
>
>> ...
>> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
>> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32
>> > *data) {
>> > u8 requesttype;
>> > u16 wvalue;
>> > u16 len;
>> > - __le32 data;
>> > + int res;
>> > + __le32 tmp;
>> > +
>> > + if (WARN_ON(unlikely(!data)))
>> > + return -EINVAL;
>> >
>>
>> Kill the NULL check - it is a silly coding error.
>> An OOPS is just as easy to debug.
>>
>
>
> I don't think that one single driver should kill the whole system. It's
> 100% an error, but kernel can recover from it (for example disconnect
> the driver, since it's broken).
>
>
> AFIAK, Greg and Linus do not like BUG_ONs in recoverable state...
> Correct me, if I am wrong
>
Oops, I thought about BUG_ON() instead of WARN_ON(), sorry for
confusion. My point is "we should not let the box boom".
With regards,
Pavel Skripkin
From: Pavel Skripkin
> Sent: 26 August 2021 09:28
>
> On Thu, 26 Aug 2021 08:21:34 +0000
> David Laight <[email protected]> wrote:
>
> > From: Pavel Skripkin
> > > Sent: 24 August 2021 08:27
> > >
> > > _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.
> >
> > ...
> > > + len += snprintf(page + len, count - len,
> > > "rtw_read8(0x%x)=0x%x\n",
> > > + proc_get_read_addr, (u8) tmp);
> >
> > That is broken.
> >
>
> Don't get it, sorry. Previous code did exactly the same thing, but
> didn't check if read() was successful.
Look up the return value of snprintf().
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
From: Pavel Skripkin
> Sent: 26 August 2021 10:28
>
> On 8/26/21 12:22 PM, Pavel Skripkin wrote:
> > On Thu, 26 Aug 2021 08:51:23 +0000
> > David Laight <[email protected]> wrote:
...
> >> ...
> >> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> >> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32
> >> > *data) {
> >> > u8 requesttype;
> >> > u16 wvalue;
> >> > u16 len;
> >> > - __le32 data;
> >> > + int res;
> >> > + __le32 tmp;
> >> > +
> >> > + if (WARN_ON(unlikely(!data)))
> >> > + return -EINVAL;
> >> >
> >>
> >> Kill the NULL check - it is a silly coding error.
> >> An OOPS is just as easy to debug.
> >>
> >
> >
> > I don't think that one single driver should kill the whole system. It's
> > 100% an error, but kernel can recover from it (for example disconnect
> > the driver, since it's broken).
> >
> >
> > AFIAK, Greg and Linus do not like BUG_ONs in recoverable state...
> > Correct me, if I am wrong
> >
> Oops, I thought about BUG_ON() instead of WARN_ON(), sorry for
> confusion. My point is "we should not let the box boom".
There is no point checking for NULL that just can't happen.
In this case all the callers will pass the address of a local.
There really is no point checking.
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
On Tue, Aug 24, 2021 at 10:27:20AM +0300, Pavel Skripkin wrote:
> There are a lof of places, where DBG_88E() is used to print register
> value. Since following patches change _rtw_read*() family
> prototypes, we can wrap printing registers into useful macro to avoid
> open-coding error checking like this:
>
> u32 tmp;
> if (!rtw_read(&tmp))
> DBG("reg = %d\n", tmp);
>
> So, added DBG_88E_REG{8,16,32} macros for printing register values.
No, please work to remove these messy things, do not add new ones.
Why is this ever needed? And if it is, use the correct in-kernel debug
functions please.
thanks,
greg k-h
On Tue, Aug 24, 2021 at 10:27:13AM +0300, Pavel Skripkin wrote:
> These 2 functions are unused, so they can be simply removed
>
> Signed-off-by: Pavel Skripkin <[email protected]>
> ---
> drivers/staging/r8188eu/core/rtw_mp.c | 39 ------------------------
> drivers/staging/r8188eu/include/rtw_mp.h | 2 --
> 2 files changed, 41 deletions(-)
write_macreg_hdl and the read version can also be removed, right?
thanks,
greg k-h
On Tue, Aug 24, 2021 at 10:27:13AM +0300, Pavel Skripkin wrote:
> These 2 functions are unused, so they can be simply removed
>
> Signed-off-by: Pavel Skripkin <[email protected]>
> ---
> drivers/staging/r8188eu/core/rtw_mp.c | 39 ------------------------
> drivers/staging/r8188eu/include/rtw_mp.h | 2 --
> 2 files changed, 41 deletions(-)
I took this one patch of this series, please redo the rest of them and
resend.
thanks,
greg k-h
On Tue, Aug 24, 2021 at 10:27:35AM +0300, Pavel Skripkin wrote:
> _rtw_read16 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_read16() 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 <[email protected]>
> ---
> drivers/staging/r8188eu/core/rtw_debug.c | 7 +++-
> drivers/staging/r8188eu/core/rtw_io.c | 9 ++---
> drivers/staging/r8188eu/core/rtw_mp_ioctl.c | 4 +-
> drivers/staging/r8188eu/hal/odm_interface.c | 4 +-
> .../staging/r8188eu/hal/rtl8188e_hal_init.c | 29 +++++++++++----
> drivers/staging/r8188eu/hal/rtl8188e_phycfg.c | 5 ++-
> drivers/staging/r8188eu/hal/usb_halinit.c | 37 ++++++++++++++++---
> drivers/staging/r8188eu/hal/usb_ops_linux.c | 22 +++++++++--
> .../staging/r8188eu/include/odm_interface.h | 2 +-
> drivers/staging/r8188eu/include/rtw_io.h | 6 +--
> drivers/staging/r8188eu/os_dep/ioctl_linux.c | 28 +++++++++++---
> 11 files changed, 115 insertions(+), 38 deletions(-)
>
> diff --git a/drivers/staging/r8188eu/core/rtw_debug.c b/drivers/staging/r8188eu/core/rtw_debug.c
> index 8b7d3eb12bd0..a41675e101ac 100644
> --- a/drivers/staging/r8188eu/core/rtw_debug.c
> +++ b/drivers/staging/r8188eu/core/rtw_debug.c
> @@ -91,7 +91,12 @@ int proc_get_read_reg(char *page, char **start,
> 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));
> + error = rtw_read16(padapter, proc_get_read_addr, (u16 *) &tmp);
> + if (error)
> + return len;
> +
> + len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n",
> + proc_get_read_addr, (u16) tmp);
> break;
> case 4:
> len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n", proc_get_read_addr, rtw_read32(padapter, proc_get_read_addr));
> diff --git a/drivers/staging/r8188eu/core/rtw_io.c b/drivers/staging/r8188eu/core/rtw_io.c
> index 2714506c8ffb..fd64893c778d 100644
> --- a/drivers/staging/r8188eu/core/rtw_io.c
> +++ b/drivers/staging/r8188eu/core/rtw_io.c
> @@ -45,18 +45,15 @@ int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data)
> return _read8(pintfhdl, addr, data);
> }
>
> -u16 _rtw_read16(struct adapter *adapter, u32 addr)
> +int __must_check _rtw_read16(struct adapter *adapter, u32 addr, u16 *data)
> {
> - u16 r_val;
> struct io_priv *pio_priv = &adapter->iopriv;
> struct intf_hdl *pintfhdl = &pio_priv->intf;
> - u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
> + int (*_read16)(struct intf_hdl *pintfhdl, u32 addr, u16 *data);
>
> _read16 = pintfhdl->io_ops._read16;
Why do you need this extra pointer abstraction anyway? Please unwind
that first, which will make this function go away (or get easier to
understand at the least...)
thanks,
greg k-h
On 8/26/21 1:22 PM, David Laight wrote:
> From: Pavel Skripkin
>> Sent: 26 August 2021 10:28
>>
>> On 8/26/21 12:22 PM, Pavel Skripkin wrote:
>> > On Thu, 26 Aug 2021 08:51:23 +0000
>> > David Laight <[email protected]> wrote:
> ...
>> >> ...
>> >> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
>> >> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32
>> >> > *data) {
>> >> > u8 requesttype;
>> >> > u16 wvalue;
>> >> > u16 len;
>> >> > - __le32 data;
>> >> > + int res;
>> >> > + __le32 tmp;
>> >> > +
>> >> > + if (WARN_ON(unlikely(!data)))
>> >> > + return -EINVAL;
>> >> >
>> >>
>> >> Kill the NULL check - it is a silly coding error.
>> >> An OOPS is just as easy to debug.
>> >>
>> >
>> >
>> > I don't think that one single driver should kill the whole system. It's
>> > 100% an error, but kernel can recover from it (for example disconnect
>> > the driver, since it's broken).
>> >
>> >
>> > AFIAK, Greg and Linus do not like BUG_ONs in recoverable state...
>> > Correct me, if I am wrong
>> >
>> Oops, I thought about BUG_ON() instead of WARN_ON(), sorry for
>> confusion. My point is "we should not let the box boom".
>
>
> There is no point checking for NULL that just can't happen.
> In this case all the callers will pass the address of a local.
> There really is no point checking.
>
We not always read in local variable, there are few places, where we
read into passed buffer.
With regards,
Pavel Skripkin
On 8/26/21 1:50 PM, Greg KH wrote:
> On Tue, Aug 24, 2021 at 10:27:35AM +0300, Pavel Skripkin wrote:
>> _rtw_read16 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_read16() 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 <[email protected]>
>> ---
>> drivers/staging/r8188eu/core/rtw_debug.c | 7 +++-
>> drivers/staging/r8188eu/core/rtw_io.c | 9 ++---
>> drivers/staging/r8188eu/core/rtw_mp_ioctl.c | 4 +-
>> drivers/staging/r8188eu/hal/odm_interface.c | 4 +-
>> .../staging/r8188eu/hal/rtl8188e_hal_init.c | 29 +++++++++++----
>> drivers/staging/r8188eu/hal/rtl8188e_phycfg.c | 5 ++-
>> drivers/staging/r8188eu/hal/usb_halinit.c | 37 ++++++++++++++++---
>> drivers/staging/r8188eu/hal/usb_ops_linux.c | 22 +++++++++--
>> .../staging/r8188eu/include/odm_interface.h | 2 +-
>> drivers/staging/r8188eu/include/rtw_io.h | 6 +--
>> drivers/staging/r8188eu/os_dep/ioctl_linux.c | 28 +++++++++++---
>> 11 files changed, 115 insertions(+), 38 deletions(-)
>>
>> diff --git a/drivers/staging/r8188eu/core/rtw_debug.c b/drivers/staging/r8188eu/core/rtw_debug.c
>> index 8b7d3eb12bd0..a41675e101ac 100644
>> --- a/drivers/staging/r8188eu/core/rtw_debug.c
>> +++ b/drivers/staging/r8188eu/core/rtw_debug.c
>> @@ -91,7 +91,12 @@ int proc_get_read_reg(char *page, char **start,
>> 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));
>> + error = rtw_read16(padapter, proc_get_read_addr, (u16 *) &tmp);
>> + if (error)
>> + return len;
>> +
>> + len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n",
>> + proc_get_read_addr, (u16) tmp);
>> break;
>> case 4:
>> len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n", proc_get_read_addr, rtw_read32(padapter, proc_get_read_addr));
>> diff --git a/drivers/staging/r8188eu/core/rtw_io.c b/drivers/staging/r8188eu/core/rtw_io.c
>> index 2714506c8ffb..fd64893c778d 100644
>> --- a/drivers/staging/r8188eu/core/rtw_io.c
>> +++ b/drivers/staging/r8188eu/core/rtw_io.c
>> @@ -45,18 +45,15 @@ int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data)
>> return _read8(pintfhdl, addr, data);
>> }
>>
>> -u16 _rtw_read16(struct adapter *adapter, u32 addr)
>> +int __must_check _rtw_read16(struct adapter *adapter, u32 addr, u16 *data)
>> {
>> - u16 r_val;
>> struct io_priv *pio_priv = &adapter->iopriv;
>> struct intf_hdl *pintfhdl = &pio_priv->intf;
>> - u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
>> + int (*_read16)(struct intf_hdl *pintfhdl, u32 addr, u16 *data);
>>
>> _read16 = pintfhdl->io_ops._read16;
>
> Why do you need this extra pointer abstraction anyway? Please unwind
> that first, which will make this function go away (or get easier to
> understand at the least...)
>
It was there before my changes :) I had a plan to clean up DBG macros
and this abstraction after adding error handling...
If you feel, that these clean up are needed before error handling, I can
add them to this series :) Anyway, some of them are already in my local
tree
With regards,
Pavel Skripkin
From: Pavel Skripkin
> Sent: 26 August 2021 11:55
>
> On 8/26/21 1:22 PM, David Laight wrote:
> > From: Pavel Skripkin
> >> Sent: 26 August 2021 10:28
> >>
> >> On 8/26/21 12:22 PM, Pavel Skripkin wrote:
> >> > On Thu, 26 Aug 2021 08:51:23 +0000
> >> > David Laight <[email protected]> wrote:
> > ...
> >> >> ...
> >> >> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> >> >> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32
> >> >> > *data) {
> >> >> > u8 requesttype;
> >> >> > u16 wvalue;
> >> >> > u16 len;
> >> >> > - __le32 data;
> >> >> > + int res;
> >> >> > + __le32 tmp;
> >> >> > +
> >> >> > + if (WARN_ON(unlikely(!data)))
> >> >> > + return -EINVAL;
> >> >> >
> >> >>
> >> >> Kill the NULL check - it is a silly coding error.
> >> >> An OOPS is just as easy to debug.
> >> >>
> >> >
> >> >
> >> > I don't think that one single driver should kill the whole system. It's
> >> > 100% an error, but kernel can recover from it (for example disconnect
> >> > the driver, since it's broken).
> >> >
> >> >
> >> > AFIAK, Greg and Linus do not like BUG_ONs in recoverable state...
> >> > Correct me, if I am wrong
> >> >
> >> Oops, I thought about BUG_ON() instead of WARN_ON(), sorry for
> >> confusion. My point is "we should not let the box boom".
> >
> >
> > There is no point checking for NULL that just can't happen.
> > In this case all the callers will pass the address of a local.
> > There really is no point checking.
> >
>
> We not always read in local variable, there are few places, where we
> read into passed buffer.
It is still a very local coding bug.
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
On Wed, Aug 25, 2021 at 10:11:45AM -0700, Nick Desaulniers wrote:
> On Wed, Aug 25, 2021 at 6:44 AM Pavel Skripkin <[email protected]> wrote:
> >
> > On 8/25/21 4:34 PM, Dan Carpenter wrote:
> > > On Wed, Aug 25, 2021 at 04:02:26PM +0300, Pavel Skripkin wrote:
> > >> > This is not related to your patch. Ignore it.
> > >> >
> > >> >
> > >> > > > vim +2022 drivers/staging/r8188eu/hal/usb_halinit.c
> > >> > > >
> > >> > >
> > >> > > > 2020 case HW_VAR_BCN_VALID:
> > >> > > > 2021 /* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
> > >> > > > > 2022 u8 tmp;
> > >> > >
> > >> > > Hm, I don't know anything about ARM compilers, so should I wrap this code
> > >> > > block with {}?
> > >> >
> > >> > Yep.
> > >> >
> > >> > >
> > >> > > My local gcc 11.1.1 (x86_64) does not produce any warnings/errors
> > >> > >
> > >> >
> > >> > You should figure out whats up with that because it shouldn't compile
> > >> > with the gcc options that the kernel uses.
> > >> >
> > >>
> > >> AFAIK, at least 2 guys except me in this CC list compiled my series without
> > >> errors/warnings. Maybe, staging tree is missing some Makefile updates?
> > >>
> > >>
> > >> I'll resend series this evening anyway, but this is strange....
> > >
> > > Hm... In my version of GCC the error is:
> > >
> > > drivers/staging/r8188eu/hal/usb_halinit.c:1870:3: error: a label can only be part of a statement and a declaration is not a statement
> > >
> > > That's a different error from what I was expecting. It's caused by
> > > having a declaration directly after a case statement. The warning that
> > > I was expecting was from -Wdeclaration-after-statement and it looks
> > > like this:
> > >
> > > warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
> > >
> > > You really should try investigate why this compiles for you because
> > > something is going wrong. It should not build without a warning.
> > >
> >
> > Looks like it's bug in gcc 11.1.1. I've rebuilt this module with gcc 10
> > (gcc-10 (SUSE Linux) 10.3.1 20210707 [revision
> > 048117e16c77f82598fca9af585500572d46ad73]) and build fails with error
> > described above
> >
> >
> > My default gcc is
> >
> > gcc (SUSE Linux) 11.1.1 20210721 [revision
> > 076930b9690ac3564638636f6b13bbb6bc608aea]
> >
> >
> > Any idea? :)
>
> The original report said the build was with clang-14, which is near
> top of tree and unreleased. It's possible that that build had a bug
> that hopefully was reverted.
No, Clang is right to refuse to build the code. It's GCC 11.1.1 which
is wrong because it allows it. I'm not C language expert but we're
using the -Wdeclaration-after-statement because we don't want this.
regards,
dan carpenter
On Thu, Aug 26, 2021 at 10:19:40AM +0000, David Laight wrote:
> From: Pavel Skripkin
> > Sent: 26 August 2021 09:28
> >
> > On Thu, 26 Aug 2021 08:21:34 +0000
> > David Laight <[email protected]> wrote:
> >
> > > From: Pavel Skripkin
> > > > Sent: 24 August 2021 08:27
> > > >
> > > > _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.
> > >
> > > ...
> > > > + len += snprintf(page + len, count - len,
> > > > "rtw_read8(0x%x)=0x%x\n",
> > > > + proc_get_read_addr, (u8) tmp);
> > >
> > > That is broken.
> > >
> >
> > Don't get it, sorry. Previous code did exactly the same thing, but
> > didn't check if read() was successful.
>
> Look up the return value of snprintf().
>
It's hard to understand what you are saying. I think you are confusing
libc snprintf with the kernel snprintf? In libc the snprintf function
can return negatives but in the kernel it cannot. This is not going
to change. Any code which checks for negative snprintf returns in the
kernel is wrong and should be fixed.
Anyway, the code works fine. snprintf here is going to return a number
between 18-32 range. It's not going to overflow the PAGE_SIZE buffer.
It would be nicer to use scnprint() but that's an unrelated patch.
Also this is all dead code. It needs to be converted to sysfs. The
caller is ifdeffed out because it doesn't compile.
regards,
dan carpenter
On 8/26/21 1:59 PM, David Laight wrote:
> From: Pavel Skripkin
>> Sent: 26 August 2021 11:55
>>
>> On 8/26/21 1:22 PM, David Laight wrote:
>> > From: Pavel Skripkin
>> >> Sent: 26 August 2021 10:28
>> >>
>> >> On 8/26/21 12:22 PM, Pavel Skripkin wrote:
>> >> > On Thu, 26 Aug 2021 08:51:23 +0000
>> >> > David Laight <[email protected]> wrote:
>> > ...
>> >> >> ...
>> >> >> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
>> >> >> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32
>> >> >> > *data) {
>> >> >> > u8 requesttype;
>> >> >> > u16 wvalue;
>> >> >> > u16 len;
>> >> >> > - __le32 data;
>> >> >> > + int res;
>> >> >> > + __le32 tmp;
>> >> >> > +
>> >> >> > + if (WARN_ON(unlikely(!data)))
>> >> >> > + return -EINVAL;
>> >> >> >
>> >> >>
>> >> >> Kill the NULL check - it is a silly coding error.
>> >> >> An OOPS is just as easy to debug.
>> >> >>
>> >> >
>> >> >
>> >> > I don't think that one single driver should kill the whole system. It's
>> >> > 100% an error, but kernel can recover from it (for example disconnect
>> >> > the driver, since it's broken).
>> >> >
>> >> >
>> >> > AFIAK, Greg and Linus do not like BUG_ONs in recoverable state...
>> >> > Correct me, if I am wrong
>> >> >
>> >> Oops, I thought about BUG_ON() instead of WARN_ON(), sorry for
>> >> confusion. My point is "we should not let the box boom".
>> >
>> >
>> > There is no point checking for NULL that just can't happen.
>> > In this case all the callers will pass the address of a local.
>> > There really is no point checking.
>> >
>>
>> We not always read in local variable, there are few places, where we
>> read into passed buffer.
>
> It is still a very local coding bug.
>
> David
>
Sure, but is defensive programming so bad?
Greg, what your opinion about this NULL check?
With regards,
Pavel Skripkin
On Thu, Aug 26, 2021 at 11:03:04PM +0300, Pavel Skripkin wrote:
> On 8/26/21 1:59 PM, David Laight wrote:
> > From: Pavel Skripkin
> > > Sent: 26 August 2021 11:55
> > >
> > > On 8/26/21 1:22 PM, David Laight wrote:
> > > > From: Pavel Skripkin
> > > >> Sent: 26 August 2021 10:28
> > > >>
> > > >> On 8/26/21 12:22 PM, Pavel Skripkin wrote:
> > > >> > On Thu, 26 Aug 2021 08:51:23 +0000
> > > >> > David Laight <[email protected]> wrote:
> > > > ...
> > > >> >> ...
> > > >> >> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> > > >> >> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32
> > > >> >> > *data) {
> > > >> >> > u8 requesttype;
> > > >> >> > u16 wvalue;
> > > >> >> > u16 len;
> > > >> >> > - __le32 data;
> > > >> >> > + int res;
> > > >> >> > + __le32 tmp;
> > > >> >> > +
> > > >> >> > + if (WARN_ON(unlikely(!data)))
> > > >> >> > + return -EINVAL;
> > > >> >> >
> > > >> >>
> > > >> >> Kill the NULL check - it is a silly coding error.
> > > >> >> An OOPS is just as easy to debug.
> > > >> >>
> > > >> >
> > > >> >
> > > >> > I don't think that one single driver should kill the whole system. It's
> > > >> > 100% an error, but kernel can recover from it (for example disconnect
> > > >> > the driver, since it's broken).
> > > >> >
> > > >> >
> > > >> > AFIAK, Greg and Linus do not like BUG_ONs in recoverable state...
> > > >> > Correct me, if I am wrong
> > > >> >
> > > >> Oops, I thought about BUG_ON() instead of WARN_ON(), sorry for
> > > >> confusion. My point is "we should not let the box boom".
> > > >
> > > >
> > > > There is no point checking for NULL that just can't happen.
> > > > In this case all the callers will pass the address of a local.
> > > > There really is no point checking.
> > > >
> > >
> > > We not always read in local variable, there are few places, where we
> > > read into passed buffer.
> >
> > It is still a very local coding bug.
> >
> > David
> >
>
> Sure, but is defensive programming so bad?
Yes it is, for when it is not needed.
> Greg, what your opinion about this NULL check?
Never check for things that you know are not going to happen. Otherwise
the kernel would just be full of pointless checks everywhere.
And why are you waiting for me to tell you this? Why do you not believe
David?
thanks,
greg k-h
On 8/27/21 10:12 AM, [email protected] wrote:
> On Thu, Aug 26, 2021 at 11:03:04PM +0300, Pavel Skripkin wrote:
>> On 8/26/21 1:59 PM, David Laight wrote:
>> > From: Pavel Skripkin
>> > > Sent: 26 August 2021 11:55
>> > >
>> > > On 8/26/21 1:22 PM, David Laight wrote:
>> > > > From: Pavel Skripkin
>> > > >> Sent: 26 August 2021 10:28
>> > > >>
>> > > >> On 8/26/21 12:22 PM, Pavel Skripkin wrote:
>> > > >> > On Thu, 26 Aug 2021 08:51:23 +0000
>> > > >> > David Laight <[email protected]> wrote:
>> > > > ...
>> > > >> >> ...
>> > > >> >> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
>> > > >> >> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32
>> > > >> >> > *data) {
>> > > >> >> > u8 requesttype;
>> > > >> >> > u16 wvalue;
>> > > >> >> > u16 len;
>> > > >> >> > - __le32 data;
>> > > >> >> > + int res;
>> > > >> >> > + __le32 tmp;
>> > > >> >> > +
>> > > >> >> > + if (WARN_ON(unlikely(!data)))
>> > > >> >> > + return -EINVAL;
>> > > >> >> >
>> > > >> >>
>> > > >> >> Kill the NULL check - it is a silly coding error.
>> > > >> >> An OOPS is just as easy to debug.
>> > > >> >>
>> > > >> >
>> > > >> >
>> > > >> > I don't think that one single driver should kill the whole system. It's
>> > > >> > 100% an error, but kernel can recover from it (for example disconnect
>> > > >> > the driver, since it's broken).
>> > > >> >
>> > > >> >
>> > > >> > AFIAK, Greg and Linus do not like BUG_ONs in recoverable state...
>> > > >> > Correct me, if I am wrong
>> > > >> >
>> > > >> Oops, I thought about BUG_ON() instead of WARN_ON(), sorry for
>> > > >> confusion. My point is "we should not let the box boom".
>> > > >
>> > > >
>> > > > There is no point checking for NULL that just can't happen.
>> > > > In this case all the callers will pass the address of a local.
>> > > > There really is no point checking.
>> > > >
>> > >
>> > > We not always read in local variable, there are few places, where we
>> > > read into passed buffer.
>> >
>> > It is still a very local coding bug.
>> >
>> > David
>> >
>>
>> Sure, but is defensive programming so bad?
>
> Yes it is, for when it is not needed.
>
>> Greg, what your opinion about this NULL check?
>
> Never check for things that you know are not going to happen. Otherwise
> the kernel would just be full of pointless checks everywhere.
>
> And why are you waiting for me to tell you this? Why do you not believe
> David?
>
Just wanted to hear more opinions on this check. I believe David, but
opinions of other people are important too, IMO
With regards,
Pavel Skripkin
On Tue, Aug 24, 2021 at 10:25:45AM +0300, Pavel Skripkin wrote:
> Hi, Greg, Larry and Phillip!
>
> I noticed, that new staging driver was added like 3 weeks ago and I decided
> to look at the code, because drivers in staging directory are always buggy.
>
> The first thing I noticed is *no one* was checking read operations result, but
> it can fail and driver may start writing random stack values into registers. It
> can cause driver misbehavior or device misbehavior.
>
> To avoid this type of bugs, i've changed rtw_read* API. Now all rtw_read
> funtions return an error, when something went wrong with usb transfer.
>
> It helps callers to break/return earlier and don't write random values to
> registers or to rely on random values.
>
>
> v2 -> v3:
Hi Pavel.
If v4 is needed can you please send it without replying to old message.
This thread is so hard to follow because always new version is answer to
old subject. This depens a little bit how you setup your email, but some
of us is grouping all emails in same thread and this thread is out of
control :D
Thanks
Kari Argillander
> 1. Fixed OOPS in usb_read32(), caused by writing to u32 **
> 2. Fixed style in rtw_read32, rtw_read16 and rtw_read8 (Suggested by Dan)
> 3. Added error hanling when usb_control_msg() returns ret != len
> NOTE: Dan suggested to add this to usbctrl_vendorreq(), but there is
> pending series, which will get rid of usb_control_msg(), so (res != len)
> check can be removed, when Fabio's series will go in
> 4. Removed RFC tag
>
> v1 -> v2:
> 1. Make rtw_read*() return an error instead of initializing pointer to error
> 2. Split one huge patch to smaller ones for each rtw_read{8,16,32} function
> changes
> 3. Add new macro for printing register values (It helps to not copy-paste error
> handling)
> 4. Removed {read,write}_macreg (Suggested by Phillip)
> 5. Rebased on top of staging-next
> 6. Cleaned checkpatch errors and warnings
>
>
> Phillip has tested fixed v2 version, AFAIU
>
> Pavel Skripkin (6):
> staging: r8188eu: remove {read,write}_macreg
> staging: r8188eu: add helper macro for printing registers
> staging: r8188eu: add error handling of rtw_read8
> staging: r8188eu: add error handling of rtw_read16
> staging: r8188eu: add error handling of rtw_read32
> staging: r8188eu: make ReadEFuse return an int
>
> drivers/staging/r8188eu/core/rtw_debug.c | 79 +++-
> drivers/staging/r8188eu/core/rtw_efuse.c | 125 +++--
> drivers/staging/r8188eu/core/rtw_io.c | 27 +-
> drivers/staging/r8188eu/core/rtw_mp.c | 70 ++-
> drivers/staging/r8188eu/core/rtw_mp_ioctl.c | 13 +-
> drivers/staging/r8188eu/core/rtw_pwrctrl.c | 5 +-
> drivers/staging/r8188eu/core/rtw_sreset.c | 9 +-
> .../r8188eu/hal/Hal8188ERateAdaptive.c | 8 +-
> drivers/staging/r8188eu/hal/HalPhyRf_8188e.c | 21 +-
> drivers/staging/r8188eu/hal/HalPwrSeqCmd.c | 9 +-
> drivers/staging/r8188eu/hal/hal_com.c | 23 +-
> drivers/staging/r8188eu/hal/hal_intf.c | 6 +-
> drivers/staging/r8188eu/hal/odm_interface.c | 12 +-
> drivers/staging/r8188eu/hal/rtl8188e_cmd.c | 33 +-
> drivers/staging/r8188eu/hal/rtl8188e_dm.c | 6 +-
> .../staging/r8188eu/hal/rtl8188e_hal_init.c | 285 +++++++++---
> drivers/staging/r8188eu/hal/rtl8188e_phycfg.c | 27 +-
> drivers/staging/r8188eu/hal/rtl8188e_sreset.c | 22 +-
> drivers/staging/r8188eu/hal/rtl8188eu_led.c | 18 +-
> drivers/staging/r8188eu/hal/usb_halinit.c | 439 +++++++++++++++---
> drivers/staging/r8188eu/hal/usb_ops_linux.c | 62 ++-
> drivers/staging/r8188eu/include/hal_intf.h | 6 +-
> .../staging/r8188eu/include/odm_interface.h | 6 +-
> .../staging/r8188eu/include/rtl8188e_hal.h | 2 +-
> drivers/staging/r8188eu/include/rtw_debug.h | 13 +
> drivers/staging/r8188eu/include/rtw_efuse.h | 4 +-
> drivers/staging/r8188eu/include/rtw_io.h | 18 +-
> drivers/staging/r8188eu/include/rtw_mp.h | 2 -
> drivers/staging/r8188eu/os_dep/ioctl_linux.c | 179 +++++--
> drivers/staging/r8188eu/os_dep/usb_intf.c | 3 +-
> 30 files changed, 1143 insertions(+), 389 deletions(-)
>
> --
> 2.32.0
>
On 8/27/21 10:49 AM, Kari Argillander wrote:
> On Tue, Aug 24, 2021 at 10:25:45AM +0300, Pavel Skripkin wrote:
>> Hi, Greg, Larry and Phillip!
>>
>> I noticed, that new staging driver was added like 3 weeks ago and I decided
>> to look at the code, because drivers in staging directory are always buggy.
>>
>> The first thing I noticed is *no one* was checking read operations result, but
>> it can fail and driver may start writing random stack values into registers. It
>> can cause driver misbehavior or device misbehavior.
>>
>> To avoid this type of bugs, i've changed rtw_read* API. Now all rtw_read
>> funtions return an error, when something went wrong with usb transfer.
>>
>> It helps callers to break/return earlier and don't write random values to
>> registers or to rely on random values.
>>
>>
>> v2 -> v3:
>
> Hi Pavel.
>
> If v4 is needed can you please send it without replying to old message.
> This thread is so hard to follow because always new version is answer to
> old subject. This depens a little bit how you setup your email, but some
> of us is grouping all emails in same thread and this thread is out of
> control :D
>
Hi, Kari!
v4 will be posted soon, yep. I will post v4 as separate thread :) It's
unreal to follow the discussion for sure. I often spend about a minute
to find an actual mail to reply xd
With regards,
Pavel Skripkin
From: Dan Carpenter
> Sent: 26 August 2021 12:21
...
> > > > ...
> > > > > + len += snprintf(page + len, count - len,
> > > > > "rtw_read8(0x%x)=0x%x\n",
> > > > > + proc_get_read_addr, (u8) tmp);
> > > >
> > > > That is broken.
> > > >
> > >
> > > Don't get it, sorry. Previous code did exactly the same thing, but
> > > didn't check if read() was successful.
> >
> > Look up the return value of snprintf().
> >
>
> It's hard to understand what you are saying. I think you are confusing
> libc snprintf with the kernel snprintf? In libc the snprintf function
> can return negatives but in the kernel it cannot. This is not going
> to change. Any code which checks for negative snprintf returns in the
> kernel is wrong and should be fixed.
>
> Anyway, the code works fine. snprintf here is going to return a number
> between 18-32 range. It's not going to overflow the PAGE_SIZE buffer.
IIRC it is also in a loop ...
Maybe, but the idiom is just broken.
Largely the result of snprintf() is never the value you are looking
for and should be ignored.
Userspace fprintf() is even worse.
If you care about the write failing you need to call fflush()
and then ferror() (typically before fclose()).
Fortunately I've never seen a 'must check' attribute on it.
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
On 8/27/21 11:14 AM, David Laight wrote:
> From: Dan Carpenter
>> Sent: 26 August 2021 12:21
> ...
>> > > > ...
>> > > > > + len += snprintf(page + len, count - len,
>> > > > > "rtw_read8(0x%x)=0x%x\n",
>> > > > > + proc_get_read_addr, (u8) tmp);
>> > > >
>> > > > That is broken.
>> > > >
>> > >
>> > > Don't get it, sorry. Previous code did exactly the same thing, but
>> > > didn't check if read() was successful.
>> >
>> > Look up the return value of snprintf().
>> >
>>
>> It's hard to understand what you are saying. I think you are confusing
>> libc snprintf with the kernel snprintf? In libc the snprintf function
>> can return negatives but in the kernel it cannot. This is not going
>> to change. Any code which checks for negative snprintf returns in the
>> kernel is wrong and should be fixed.
>>
>> Anyway, the code works fine. snprintf here is going to return a number
>> between 18-32 range. It's not going to overflow the PAGE_SIZE buffer.
>
> IIRC it is also in a loop ...
>
> Maybe, but the idiom is just broken.
> Largely the result of snprintf() is never the value you are looking
> for and should be ignored.
>
AFAIK, snprintf return value is largely used in sysfs at least.
$ grep -Ir "= snprintf" | wc -l
1200
Anyway, I will convert this dead code to sysfs interface and maybe
snprintf will go away...
Thank you for your help and comments
> Userspace fprintf() is even worse.
> If you care about the write failing you need to call fflush()
> and then ferror() (typically before fclose()).
>
> Fortunately I've never seen a 'must check' attribute on it.
>
> David
>
> -
> Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
> Registration No: 1397386 (Wales)
>
With regards,
Pavel Skripkin
On Tue, Aug 24, 2021 at 10:27:27AM +0300, Pavel Skripkin wrote:
> @@ -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;
Oh my goodness... :P
If you look at what proc_get_read_addr is, it turns out it's a 32bit
address which is controlled by the user in proc_set_read_reg(). LOL!
Just a giant security hole.
My advise is just delete this dead code. No one is using it so how
necessary can it be?
regards,
dan carpenter
On 8/27/21 12:07 PM, Dan Carpenter wrote:
> On Tue, Aug 24, 2021 at 10:27:27AM +0300, Pavel Skripkin wrote:
>> @@ -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;
>
> Oh my goodness... :P
>
> If you look at what proc_get_read_addr is, it turns out it's a 32bit
> address which is controlled by the user in proc_set_read_reg(). LOL!
> Just a giant security hole.
>
> My advise is just delete this dead code. No one is using it so how
> necessary can it be?
Yep, it's dead code as was already mentioned. My plan is to convert all
this code to sysfs. One thing I am wondering about should I include
these changes into this series?...
With regards,
Pavel Skripkin
On Fri, Aug 27, 2021 at 12:16:25PM +0300, Pavel Skripkin wrote:
> On 8/27/21 12:07 PM, Dan Carpenter wrote:
> > On Tue, Aug 24, 2021 at 10:27:27AM +0300, Pavel Skripkin wrote:
> > > @@ -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;
> >
> > Oh my goodness... :P
> >
> > If you look at what proc_get_read_addr is, it turns out it's a 32bit
> > address which is controlled by the user in proc_set_read_reg(). LOL!
> > Just a giant security hole.
> >
> > My advise is just delete this dead code. No one is using it so how
> > necessary can it be?
>
>
> Yep, it's dead code as was already mentioned. My plan is to convert all this
> code to sysfs.
I thought this was a good plan until a few minutes ago when I noticed it
was a ***GIANT SECURITY HOLE***! :P
I mean presumably this is root controlled but these days we try to
restrict root as well in some ways. Even confined to root only, this
code is incredibly risky and bad. Don't convert it. Just delete it.
regards,
dan carpenter
Hi Pavel,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on staging/staging-testing]
url: https://github.com/0day-ci/linux/commits/Pavel-Skripkin/staging-r8188eu-remove-read-write-_macreg/20210824-162756
base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git 093991aaadf0fbb34184fa37a46e7a157da3f386
config: x86_64-allyesconfig (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
# https://github.com/0day-ci/linux/commit/d4e4bbed4e59df37967086f60fe92cb1b4504d37
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Pavel-Skripkin/staging-r8188eu-remove-read-write-_macreg/20210824-162756
git checkout d4e4bbed4e59df37967086f60fe92cb1b4504d37
# save the attached .config to linux build tree
mkdir build_dir
make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/staging/r8188eu/
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>
All errors (new ones prefixed by >>):
drivers/staging/r8188eu/hal/usb_halinit.c: In function 'SetHwReg8188EU':
>> drivers/staging/r8188eu/hal/usb_halinit.c:2022:3: error: a label can only be part of a statement and a declaration is not a statement
2022 | u8 tmp;
| ^~
vim +2022 drivers/staging/r8188eu/hal/usb_halinit.c
1450
1451 static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
1452 {
1453 struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
1454 struct dm_priv *pdmpriv = &haldata->dmpriv;
1455 struct odm_dm_struct *podmpriv = &haldata->odmpriv;
1456 int error;
1457 u8 tmp;
1458
1459 switch (variable) {
1460 case HW_VAR_MEDIA_STATUS:
1461 {
1462 u8 val8;
1463
1464 error = rtw_read8(Adapter, MSR, &val8);
1465 if (error)
1466 return;
1467
1468 val8 &= 0x0c;
1469 val8 |= *((u8 *)val);
1470 rtw_write8(Adapter, MSR, val8);
1471 }
1472 break;
1473 case HW_VAR_MEDIA_STATUS1:
1474 {
1475 u8 val8;
1476
1477 error = rtw_read8(Adapter, MSR, &val8);
1478 if (error)
1479 return;
1480
1481 val8 &= 0x03;
1482 val8 |= *((u8 *)val) << 2;
1483 rtw_write8(Adapter, MSR, val8);
1484 }
1485 break;
1486 case HW_VAR_SET_OPMODE:
1487 hw_var_set_opmode(Adapter, variable, val);
1488 break;
1489 case HW_VAR_MAC_ADDR:
1490 hw_var_set_macaddr(Adapter, variable, val);
1491 break;
1492 case HW_VAR_BSSID:
1493 hw_var_set_bssid(Adapter, variable, val);
1494 break;
1495 case HW_VAR_BASIC_RATE:
1496 {
1497 u16 BrateCfg = 0;
1498 u8 RateIndex = 0;
1499
1500 /* 2007.01.16, by Emily */
1501 /* Select RRSR (in Legacy-OFDM and CCK) */
1502 /* For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate. */
1503 /* We do not use other rates. */
1504 HalSetBrateCfg(Adapter, val, &BrateCfg);
1505 DBG_88E("HW_VAR_BASIC_RATE: BrateCfg(%#x)\n", BrateCfg);
1506
1507 /* 2011.03.30 add by Luke Lee */
1508 /* CCK 2M ACK should be disabled for some BCM and Atheros AP IOT */
1509 /* because CCK 2M has poor TXEVM */
1510 /* CCK 5.5M & 11M ACK should be enabled for better performance */
1511
1512 BrateCfg = (BrateCfg | 0xd) & 0x15d;
1513 haldata->BasicRateSet = BrateCfg;
1514
1515 BrateCfg |= 0x01; /* default enable 1M ACK rate */
1516 /* Set RRSR rate table. */
1517 rtw_write8(Adapter, REG_RRSR, BrateCfg & 0xff);
1518 rtw_write8(Adapter, REG_RRSR + 1, (BrateCfg >> 8) & 0xff);
1519
1520 error = rtw_read8(Adapter, REG_RRSR + 2, &tmp);
1521 if (error)
1522 return;
1523
1524 rtw_write8(Adapter, REG_RRSR + 2, tmp & 0xf0);
1525
1526 /* Set RTS initial rate */
1527 while (BrateCfg > 0x1) {
1528 BrateCfg = (BrateCfg >> 1);
1529 RateIndex++;
1530 }
1531 /* Ziv - Check */
1532 rtw_write8(Adapter, REG_INIRTS_RATE_SEL, RateIndex);
1533 }
1534 break;
1535 case HW_VAR_TXPAUSE:
1536 rtw_write8(Adapter, REG_TXPAUSE, *((u8 *)val));
1537 break;
1538 case HW_VAR_BCN_FUNC:
1539 hw_var_set_bcn_func(Adapter, variable, val);
1540 break;
1541 case HW_VAR_CORRECT_TSF:
1542 {
1543 u64 tsf;
1544 struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
1545 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1546
1547 tsf = pmlmeext->TSFValue - do_div(pmlmeext->TSFValue,
1548 pmlmeinfo->bcn_interval * 1024) - 1024; /* us */
1549
1550 if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
1551 StopTxBeacon(Adapter);
1552
1553 /* disable related TSF function */
1554 error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
1555 if (error)
1556 return;
1557
1558 rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(3)));
1559
1560 rtw_write32(Adapter, REG_TSFTR, tsf);
1561 rtw_write32(Adapter, REG_TSFTR + 4, tsf >> 32);
1562
1563 /* enable related TSF function */
1564 error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
1565 if (error)
1566 return;
1567
1568 rtw_write8(Adapter, REG_BCN_CTRL, tmp | BIT(3));
1569
1570 if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
1571 ResumeTxBeacon(Adapter);
1572 }
1573 break;
1574 case HW_VAR_CHECK_BSSID:
1575 if (*((u8 *)val)) {
1576 rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1577 } else {
1578 u32 val32;
1579
1580 val32 = rtw_read32(Adapter, REG_RCR);
1581
1582 val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1583
1584 rtw_write32(Adapter, REG_RCR, val32);
1585 }
1586 break;
1587 case HW_VAR_MLME_DISCONNECT:
1588 /* Set RCR to not to receive data frame when NO LINK state */
1589 /* reject all data frames */
1590 rtw_write16(Adapter, REG_RXFLTMAP2, 0x00);
1591
1592 /* reset TSF */
1593 rtw_write8(Adapter, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
1594
1595 /* disable update TSF */
1596 error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
1597 if (error)
1598 return;
1599
1600 rtw_write8(Adapter, REG_BCN_CTRL, tmp | BIT(4));
1601 break;
1602 case HW_VAR_MLME_SITESURVEY:
1603 if (*((u8 *)val)) { /* under sitesurvey */
1604 /* config RCR to receive different BSSID & not to receive data frame */
1605 u32 v = rtw_read32(Adapter, REG_RCR);
1606
1607 v &= ~(RCR_CBSSID_BCN);
1608 rtw_write32(Adapter, REG_RCR, v);
1609 /* reject all data frame */
1610 rtw_write16(Adapter, REG_RXFLTMAP2, 0x00);
1611
1612 /* disable update TSF */
1613 error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
1614 if (error)
1615 return;
1616 rtw_write8(Adapter, REG_BCN_CTRL, tmp | BIT(4));
1617 } else { /* sitesurvey done */
1618 struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
1619 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1620
1621 error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
1622 if (error)
1623 return;
1624
1625 if ((is_client_associated_to_ap(Adapter)) ||
1626 ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) {
1627 /* enable to rx data frame */
1628 rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
1629
1630 /* enable update TSF */
1631 rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(4)));
1632 } else if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
1633 rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
1634 /* enable update TSF */
1635 rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(4)));
1636 }
1637
1638 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
1639 rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN);
1640 } else {
1641 if (Adapter->in_cta_test) {
1642 u32 v = rtw_read32(Adapter, REG_RCR);
1643 v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* RCR_ADF */
1644 rtw_write32(Adapter, REG_RCR, v);
1645 } else {
1646 rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN);
1647 }
1648 }
1649 }
1650 break;
1651 case HW_VAR_MLME_JOIN:
1652 {
1653 u8 RetryLimit = 0x30;
1654 u8 type = *((u8 *)val);
1655 u8 tmp;
1656 struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
1657
1658 if (type == 0) { /* prepare to join */
1659 /* enable to rx data frame.Accept all data frame */
1660 rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
1661
1662 if (Adapter->in_cta_test) {
1663 u32 v = rtw_read32(Adapter, REG_RCR);
1664 v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* RCR_ADF */
1665 rtw_write32(Adapter, REG_RCR, v);
1666 } else {
1667 rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1668 }
1669
1670 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
1671 RetryLimit = (haldata->CustomerID == RT_CID_CCX) ? 7 : 48;
1672 else /* Ad-hoc Mode */
1673 RetryLimit = 0x7;
1674 } else if (type == 1) {
1675 /* joinbss_event call back when join res < 0 */
1676 rtw_write16(Adapter, REG_RXFLTMAP2, 0x00);
1677 } else if (type == 2) {
1678 /* sta add event call back */
1679 /* enable update TSF */
1680 error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
1681 if (error)
1682 return;
1683
1684 rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(4)));
1685
1686 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
1687 RetryLimit = 0x7;
1688 }
1689 rtw_write16(Adapter, REG_RL, RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT);
1690 }
1691 break;
1692 case HW_VAR_BEACON_INTERVAL:
1693 rtw_write16(Adapter, REG_BCN_INTERVAL, *((u16 *)val));
1694 break;
1695 case HW_VAR_SLOT_TIME:
1696 {
1697 u8 u1bAIFS, aSifsTime;
1698 struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
1699 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1700
1701 rtw_write8(Adapter, REG_SLOT, val[0]);
1702
1703 if (pmlmeinfo->WMM_enable == 0) {
1704 if (pmlmeext->cur_wireless_mode == WIRELESS_11B)
1705 aSifsTime = 10;
1706 else
1707 aSifsTime = 16;
1708
1709 u1bAIFS = aSifsTime + (2 * pmlmeinfo->slotTime);
1710
1711 /* <Roger_EXP> Temporary removed, 2008.06.20. */
1712 rtw_write8(Adapter, REG_EDCA_VO_PARAM, u1bAIFS);
1713 rtw_write8(Adapter, REG_EDCA_VI_PARAM, u1bAIFS);
1714 rtw_write8(Adapter, REG_EDCA_BE_PARAM, u1bAIFS);
1715 rtw_write8(Adapter, REG_EDCA_BK_PARAM, u1bAIFS);
1716 }
1717 }
1718 break;
1719 case HW_VAR_RESP_SIFS:
1720 /* RESP_SIFS for CCK */
1721 rtw_write8(Adapter, REG_R2T_SIFS, val[0]); /* SIFS_T2T_CCK (0x08) */
1722 rtw_write8(Adapter, REG_R2T_SIFS + 1, val[1]); /* SIFS_R2T_CCK(0x08) */
1723 /* RESP_SIFS for OFDM */
1724 rtw_write8(Adapter, REG_T2T_SIFS, val[2]); /* SIFS_T2T_OFDM (0x0a) */
1725 rtw_write8(Adapter, REG_T2T_SIFS + 1, val[3]); /* SIFS_R2T_OFDM(0x0a) */
1726 break;
1727 case HW_VAR_ACK_PREAMBLE:
1728 {
1729 u8 regTmp;
1730 u8 bShortPreamble = *((bool *)val);
1731 /* Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily) */
1732 regTmp = (haldata->nCur40MhzPrimeSC) << 5;
1733 if (bShortPreamble)
1734 regTmp |= 0x80;
1735
1736 rtw_write8(Adapter, REG_RRSR + 2, regTmp);
1737 }
1738 break;
1739 case HW_VAR_SEC_CFG:
1740 rtw_write8(Adapter, REG_SECCFG, *((u8 *)val));
1741 break;
1742 case HW_VAR_DM_FLAG:
1743 podmpriv->SupportAbility = *((u8 *)val);
1744 break;
1745 case HW_VAR_DM_FUNC_OP:
1746 if (val[0])
1747 podmpriv->BK_SupportAbility = podmpriv->SupportAbility;
1748 else
1749 podmpriv->SupportAbility = podmpriv->BK_SupportAbility;
1750 break;
1751 case HW_VAR_DM_FUNC_SET:
1752 if (*((u32 *)val) == DYNAMIC_ALL_FUNC_ENABLE) {
1753 pdmpriv->DMFlag = pdmpriv->InitDMFlag;
1754 podmpriv->SupportAbility = pdmpriv->InitODMFlag;
1755 } else {
1756 podmpriv->SupportAbility |= *((u32 *)val);
1757 }
1758 break;
1759 case HW_VAR_DM_FUNC_CLR:
1760 podmpriv->SupportAbility &= *((u32 *)val);
1761 break;
1762 case HW_VAR_CAM_EMPTY_ENTRY:
1763 {
1764 u8 ucIndex = *((u8 *)val);
1765 u8 i;
1766 u32 ulCommand = 0;
1767 u32 ulContent = 0;
1768 u32 ulEncAlgo = CAM_AES;
1769
1770 for (i = 0; i < CAM_CONTENT_COUNT; i++) {
1771 /* filled id in CAM config 2 byte */
1772 if (i == 0)
1773 ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo) << 2);
1774 else
1775 ulContent = 0;
1776 /* polling bit, and No Write enable, and address */
1777 ulCommand = CAM_CONTENT_COUNT * ucIndex + i;
1778 ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
1779 /* write content 0 is equall to mark invalid */
1780 rtw_write32(Adapter, WCAMI, ulContent); /* delay_ms(40); */
1781 rtw_write32(Adapter, RWCAM, ulCommand); /* delay_ms(40); */
1782 }
1783 }
1784 break;
1785 case HW_VAR_CAM_INVALID_ALL:
1786 rtw_write32(Adapter, RWCAM, BIT(31) | BIT(30));
1787 break;
1788 case HW_VAR_CAM_WRITE:
1789 {
1790 u32 cmd;
1791 u32 *cam_val = (u32 *)val;
1792 rtw_write32(Adapter, WCAMI, cam_val[0]);
1793
1794 cmd = CAM_POLLINIG | CAM_WRITE | cam_val[1];
1795 rtw_write32(Adapter, RWCAM, cmd);
1796 }
1797 break;
1798 case HW_VAR_AC_PARAM_VO:
1799 rtw_write32(Adapter, REG_EDCA_VO_PARAM, ((u32 *)(val))[0]);
1800 break;
1801 case HW_VAR_AC_PARAM_VI:
1802 rtw_write32(Adapter, REG_EDCA_VI_PARAM, ((u32 *)(val))[0]);
1803 break;
1804 case HW_VAR_AC_PARAM_BE:
1805 haldata->AcParam_BE = ((u32 *)(val))[0];
1806 rtw_write32(Adapter, REG_EDCA_BE_PARAM, ((u32 *)(val))[0]);
1807 break;
1808 case HW_VAR_AC_PARAM_BK:
1809 rtw_write32(Adapter, REG_EDCA_BK_PARAM, ((u32 *)(val))[0]);
1810 break;
1811 case HW_VAR_ACM_CTRL:
1812 {
1813 u8 acm_ctrl = *((u8 *)val);
1814 u8 AcmCtrl;
1815
1816 error = rtw_read8(Adapter, REG_ACMHWCTRL, &AcmCtrl);
1817 if (error)
1818 return;
1819
1820 if (acm_ctrl > 1)
1821 AcmCtrl = AcmCtrl | 0x1;
1822
1823 if (acm_ctrl & BIT(3))
1824 AcmCtrl |= AcmHw_VoqEn;
1825 else
1826 AcmCtrl &= (~AcmHw_VoqEn);
1827
1828 if (acm_ctrl & BIT(2))
1829 AcmCtrl |= AcmHw_ViqEn;
1830 else
1831 AcmCtrl &= (~AcmHw_ViqEn);
1832
1833 if (acm_ctrl & BIT(1))
1834 AcmCtrl |= AcmHw_BeqEn;
1835 else
1836 AcmCtrl &= (~AcmHw_BeqEn);
1837
1838 DBG_88E("[HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl);
1839 rtw_write8(Adapter, REG_ACMHWCTRL, AcmCtrl);
1840 }
1841 break;
1842 case HW_VAR_AMPDU_MIN_SPACE:
1843 {
1844 u8 MinSpacingToSet;
1845 u8 SecMinSpace;
1846 u8 tmp;
1847
1848 MinSpacingToSet = *((u8 *)val);
1849 if (MinSpacingToSet <= 7) {
1850 switch (Adapter->securitypriv.dot11PrivacyAlgrthm) {
1851 case _NO_PRIVACY_:
1852 case _AES_:
1853 SecMinSpace = 0;
1854 break;
1855 case _WEP40_:
1856 case _WEP104_:
1857 case _TKIP_:
1858 case _TKIP_WTMIC_:
1859 SecMinSpace = 6;
1860 break;
1861 default:
1862 SecMinSpace = 7;
1863 break;
1864 }
1865 if (MinSpacingToSet < SecMinSpace)
1866 MinSpacingToSet = SecMinSpace;
1867
1868 error = rtw_read8(Adapter, REG_AMPDU_MIN_SPACE, &tmp);
1869 if (error)
1870 return;
1871
1872 rtw_write8(Adapter, REG_AMPDU_MIN_SPACE, (tmp & 0xf8) |
1873 MinSpacingToSet);
1874 }
1875 }
1876 break;
1877 case HW_VAR_AMPDU_FACTOR:
1878 {
1879 u8 RegToSet_Normal[4] = {0x41, 0xa8, 0x72, 0xb9};
1880 u8 FactorToSet;
1881 u8 *pRegToSet;
1882 u8 index = 0;
1883
1884 pRegToSet = RegToSet_Normal; /* 0xb972a841; */
1885 FactorToSet = *((u8 *)val);
1886 if (FactorToSet <= 3) {
1887 FactorToSet = (1 << (FactorToSet + 2));
1888 if (FactorToSet > 0xf)
1889 FactorToSet = 0xf;
1890
1891 for (index = 0; index < 4; index++) {
1892 if ((pRegToSet[index] & 0xf0) > (FactorToSet << 4))
1893 pRegToSet[index] = (pRegToSet[index] & 0x0f) | (FactorToSet << 4);
1894
1895 if ((pRegToSet[index] & 0x0f) > FactorToSet)
1896 pRegToSet[index] = (pRegToSet[index] & 0xf0) | (FactorToSet);
1897
1898 rtw_write8(Adapter, (REG_AGGLEN_LMT + index), pRegToSet[index]);
1899 }
1900 }
1901 }
1902 break;
1903 case HW_VAR_RXDMA_AGG_PG_TH:
1904 {
1905 u8 threshold = *((u8 *)val);
1906 if (threshold == 0)
1907 threshold = haldata->UsbRxAggPageCount;
1908 rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH, threshold);
1909 }
1910 break;
1911 case HW_VAR_SET_RPWM:
1912 break;
1913 case HW_VAR_H2C_FW_PWRMODE:
1914 {
1915 u8 psmode = (*(u8 *)val);
1916
1917 /* Forece leave RF low power mode for 1T1R to prevent conficting setting in Fw power */
1918 /* saving sequence. 2010.06.07. Added by tynli. Suggested by SD3 yschang. */
1919 if ((psmode != PS_MODE_ACTIVE) && (!IS_92C_SERIAL(haldata->VersionID)))
1920 ODM_RF_Saving(podmpriv, true);
1921 rtl8188e_set_FwPwrMode_cmd(Adapter, psmode);
1922 }
1923 break;
1924 case HW_VAR_H2C_FW_JOINBSSRPT:
1925 {
1926 u8 mstatus = (*(u8 *)val);
1927 rtl8188e_set_FwJoinBssReport_cmd(Adapter, mstatus);
1928 }
1929 break;
1930 #ifdef CONFIG_88EU_P2P
1931 case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
1932 {
1933 u8 p2p_ps_state = (*(u8 *)val);
1934 rtl8188e_set_p2p_ps_offload_cmd(Adapter, p2p_ps_state);
1935 }
1936 break;
1937 #endif
1938 case HW_VAR_INITIAL_GAIN:
1939 {
1940 struct rtw_dig *pDigTable = &podmpriv->DM_DigTable;
1941 u32 rx_gain = ((u32 *)(val))[0];
1942
1943 if (rx_gain == 0xff) {/* restore rx gain */
1944 ODM_Write_DIG(podmpriv, pDigTable->BackupIGValue);
1945 } else {
1946 pDigTable->BackupIGValue = pDigTable->CurIGValue;
1947 ODM_Write_DIG(podmpriv, rx_gain);
1948 }
1949 }
1950 break;
1951 case HW_VAR_TRIGGER_GPIO_0:
1952 rtl8192cu_trigger_gpio_0(Adapter);
1953 break;
1954 case HW_VAR_RPT_TIMER_SETTING:
1955 {
1956 u16 min_rpt_time = (*(u16 *)val);
1957 ODM_RA_Set_TxRPT_Time(podmpriv, min_rpt_time);
1958 }
1959 break;
1960 case HW_VAR_ANTENNA_DIVERSITY_SELECT:
1961 {
1962 u8 Optimum_antenna = (*(u8 *)val);
1963 u8 Ant;
1964 /* switch antenna to Optimum_antenna */
1965 if (haldata->CurAntenna != Optimum_antenna) {
1966 Ant = (Optimum_antenna == 2) ? MAIN_ANT : AUX_ANT;
1967 ODM_UpdateRxIdleAnt_88E(&haldata->odmpriv, Ant);
1968
1969 haldata->CurAntenna = Optimum_antenna;
1970 }
1971 }
1972 break;
1973 case HW_VAR_EFUSE_BYTES: /* To set EFUE total used bytes, added by Roger, 2008.12.22. */
1974 haldata->EfuseUsedBytes = *((u16 *)val);
1975 break;
1976 case HW_VAR_FIFO_CLEARN_UP:
1977 {
1978 struct pwrctrl_priv *pwrpriv = &Adapter->pwrctrlpriv;
1979 u8 trycnt = 100;
1980
1981 /* pause tx */
1982 rtw_write8(Adapter, REG_TXPAUSE, 0xff);
1983
1984 /* keep sn */
1985 Adapter->xmitpriv.nqos_ssn = rtw_read16(Adapter, REG_NQOS_SEQ);
1986
1987 if (!pwrpriv->bkeepfwalive) {
1988 /* RX DMA stop */
1989 rtw_write32(Adapter, REG_RXPKT_NUM, (rtw_read32(Adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
1990 do {
1991 if (!(rtw_read32(Adapter, REG_RXPKT_NUM) & RXDMA_IDLE))
1992 break;
1993 } while (trycnt--);
1994 if (trycnt == 0)
1995 DBG_88E("Stop RX DMA failed......\n");
1996
1997 /* RQPN Load 0 */
1998 rtw_write16(Adapter, REG_RQPN_NPQ, 0x0);
1999 rtw_write32(Adapter, REG_RQPN, 0x80000000);
2000 mdelay(10);
2001 }
2002 }
2003 break;
2004 case HW_VAR_CHECK_TXBUF:
2005 break;
2006 case HW_VAR_APFM_ON_MAC:
2007 haldata->bMacPwrCtrlOn = *val;
2008 DBG_88E("%s: bMacPwrCtrlOn=%d\n", __func__, haldata->bMacPwrCtrlOn);
2009 break;
2010 case HW_VAR_TX_RPT_MAX_MACID:
2011 {
2012 u8 maxMacid = *val;
2013 DBG_88E("### MacID(%d),Set Max Tx RPT MID(%d)\n", maxMacid, maxMacid + 1);
2014 rtw_write8(Adapter, REG_TX_RPT_CTRL + 1, maxMacid + 1);
2015 }
2016 break;
2017 case HW_VAR_H2C_MEDIA_STATUS_RPT:
2018 rtl8188e_set_FwMediaStatus_cmd(Adapter, (*(__le16 *)val));
2019 break;
2020 case HW_VAR_BCN_VALID:
2021 /* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
> 2022 u8 tmp;
2023
2024 error = rtw_read8(Adapter, REG_TDECTRL + 2, &tmp);
2025 if (error)
2026 return;
2027
2028 rtw_write8(Adapter, REG_TDECTRL + 2, tmp | BIT(0));
2029 break;
2030 default:
2031 break;
2032 }
2033
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]