Commit fed9e604 authored by Pavel Skripkin's avatar Pavel Skripkin Committed by Greg Kroah-Hartman
Browse files

staging: r8188eu: add error handling of rtw_read16



rtw_read16() reads data from device via USB API which may fail. In case
of any failure previous code returned stack data to callers, which is
wrong.

Fix it by changing rtw_read16() prototype and prevent caller from
touching random stack data

Signed-off-by: default avatarPavel Skripkin <paskripkin@gmail.com>
Link: https://lore.kernel.org/r/06b45afda048d0aeddeed983c2318680fe6265f5.1654629778.git.paskripkin@gmail.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 857fe9e5
Loading
Loading
Loading
Loading
+23 −6
Original line number Diff line number Diff line
@@ -200,7 +200,8 @@ efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf)
	kfree(eFuseWord);
}

static void efuse_read_phymap_from_txpktbuf(
/* FIXME: add error handling in callers */
static int efuse_read_phymap_from_txpktbuf(
	struct adapter  *adapter,
	int bcnhead,	/* beacon head, where FW store len(2-byte) and efuse physical map. */
	u8 *content,	/* buffer to store efuse physical map */
@@ -219,7 +220,7 @@ static void efuse_read_phymap_from_txpktbuf(
	if (bcnhead < 0) { /* if not valid */
		res = rtw_read8(adapter, REG_TDECTRL + 1, &reg);
		if (res)
			return;
			return res;

		bcnhead = reg;
	}
@@ -249,11 +250,15 @@ static void efuse_read_phymap_from_txpktbuf(
		hi32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H));

		if (i == 0) {
			u16 reg;

			/* 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.
			 */
			rtw_read16(adapter, REG_PKTBUF_DBG_DATA_L);
			res = rtw_read16(adapter, REG_PKTBUF_DBG_DATA_L, &reg);
			if (res)
				return res;

			len = le32_to_cpu(lo32) & 0x0000ffff;

@@ -280,6 +285,8 @@ static void efuse_read_phymap_from_txpktbuf(
	}
	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
	*size = count;

	return 0;
}

static s32 iol_read_efuse(struct adapter *padapter, u8 txpktbuf_bndy, u16 offset, u16 size_byte, u8 *logical_map)
@@ -355,25 +362,35 @@ int rtl8188e_IOL_exec_cmds_sync(struct adapter *adapter, struct xmit_frame *xmit
void rtl8188e_EfusePowerSwitch(struct adapter *pAdapter, u8 PwrState)
{
	u16	tmpV16;
	int res;

	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);
		res = rtw_read16(pAdapter, REG_SYS_ISO_CTRL, &tmpV16);
		if (res)
			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);
		res = rtw_read16(pAdapter, REG_SYS_FUNC_EN, &tmpV16);
		if (res)
			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);
		res = rtw_read16(pAdapter, REG_SYS_CLKR, &tmpV16);
		if (res)
			return;

		if ((!(tmpV16 & LOADER_CLK_EN))  || (!(tmpV16 & ANA8M))) {
			tmpV16 |= (LOADER_CLK_EN | ANA8M);
			rtw_write16(pAdapter, REG_SYS_CLKR, tmpV16);
+6 −2
Original line number Diff line number Diff line
@@ -484,13 +484,17 @@ PHY_BBConfig8188E(
{
	int	rtStatus = _SUCCESS;
	struct hal_data_8188e *pHalData = &Adapter->haldata;
	u32 RegVal;
	u16 RegVal;
	u8 CrystalCap;
	int res;

	phy_InitBBRFRegisterDefinition(Adapter);

	/*  Enable BB and RF */
	RegVal = rtw_read16(Adapter, REG_SYS_FUNC_EN);
	res = rtw_read16(Adapter, REG_SYS_FUNC_EN, &RegVal);
	if (res)
		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. */
+23 −4
Original line number Diff line number Diff line
@@ -52,6 +52,8 @@ void rtl8188eu_interface_configure(struct adapter *adapt)
u32 rtl8188eu_InitPowerOn(struct adapter *adapt)
{
	u16 value16;
	int res;

	/*  HW Power on sequence */
	struct hal_data_8188e *haldata = &adapt->haldata;
	if (haldata->bMacPwrCtrlOn)
@@ -65,7 +67,10 @@ 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);
	res = rtw_read16(adapt, REG_CR, &value16);
	if (res)
		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. */
@@ -166,7 +171,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 res;

	res = rtw_read16(Adapter, REG_TRXDMA_CTRL, &value16);
	if (res)
		return;

	value16 &= 0x7;

	value16 |= _TXDMA_BEQ_MAP(beQ)	| _TXDMA_BKQ_MAP(bkQ) |
		   _TXDMA_VIQ_MAP(viQ)	| _TXDMA_VOQ_MAP(voQ) |
@@ -640,7 +652,10 @@ 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);
	res = rtw_read16(Adapter, REG_CR, &value16);
	if (res)
		return _FAIL;

	value16 |= (MACTXEN | MACRXEN);
	rtw_write8(Adapter, REG_CR, value16);

@@ -713,7 +728,11 @@ 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));
	res = rtw_read16(Adapter, REG_TXDMA_OFFSET_CHK, &value16);
	if (res)
		return _FAIL;

	rtw_write16(Adapter, REG_TXDMA_OFFSET_CHK, (value16 | DROP_DATA_EN));

	/*  2010/08/26 MH Merge from 8192CE. */
	if (pwrctrlpriv->rf_pwrstate == rf_on) {
+9 −4
Original line number Diff line number Diff line
@@ -103,16 +103,21 @@ int __must_check rtw_read8(struct adapter *adapter, u32 addr, u8 *data)
	return usb_read(intf, value, data, 1);
}

u16 rtw_read16(struct adapter *adapter, u32 addr)
int __must_check rtw_read16(struct adapter *adapter, u32 addr, u16 *data)
{
	struct io_priv *io_priv = &adapter->iopriv;
	struct intf_hdl *intf = &io_priv->intf;
	u16 value = addr & 0xffff;
	__le16 data;
	__le16 le_data;
	int res;

	usb_read(intf, value, &data, 2);
	res = usb_read(intf, value, &le_data, 2);
	if (res)
		return res;

	return le16_to_cpu(data);
	*data = le16_to_cpu(le_data);

	return 0;
}

u32 rtw_read32(struct adapter *adapter, u32 addr)
+1 −1
Original line number Diff line number Diff line
@@ -221,7 +221,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);
u32 rtw_read_port(struct adapter *adapter, u8 *pmem);
Loading