When dev_alloc_skb() or rtw_sdio_read_port() fails, rtw_sdio_rxfifo_recv() returns without reading data. Because it returned void, the caller still counted rx_len against the loop budget while leaving data stranded in the FIFO. Return an error code from rtw_sdio_rxfifo_recv() on failure and break out of the receive loop in the caller immediately. Fixes: 65371a3f14e7 ("wifi: rtw88: sdio: Add HCI implementation for SDIO based chipsets") Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Alastair D'Silva --- drivers/net/wireless/realtek/rtw88/sdio.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c index dc2fd0f8f9ff..e39284b71837 100644 --- a/drivers/net/wireless/realtek/rtw88/sdio.c +++ b/drivers/net/wireless/realtek/rtw88/sdio.c @@ -1349,7 +1349,7 @@ static void rtw_sdio_rx_skb(struct rtw_dev *rtwdev, struct sk_buff *skb, ieee80211_rx_irqsafe(rtwdev->hw, skb); } -static void rtw_sdio_rxfifo_recv(struct rtw_dev *rtwdev, u32 rx_len) +static int rtw_sdio_rxfifo_recv(struct rtw_dev *rtwdev, u32 rx_len) { struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; const struct rtw_chip_info *chip = rtwdev->chip; @@ -1366,12 +1366,12 @@ static void rtw_sdio_rxfifo_recv(struct rtw_dev *rtwdev, u32 rx_len) skb = dev_alloc_skb(bufsz); if (!skb) - return; + return -ENOMEM; ret = rtw_sdio_read_port(rtwdev, skb->data, bufsz); if (ret) { dev_kfree_skb_any(skb); - return; + return ret; } while (true) { @@ -1380,7 +1380,7 @@ static void rtw_sdio_rxfifo_recv(struct rtw_dev *rtwdev, u32 rx_len) &pkt_stat, &rx_status); if (ret) { dev_kfree_skb_any(skb); - return; + return ret; } pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz + @@ -1416,11 +1416,14 @@ static void rtw_sdio_rxfifo_recv(struct rtw_dev *rtwdev, u32 rx_len) skb_reserve(skb, curr_pkt_len); rx_len -= curr_pkt_len; } + + return 0; } static void rtw_sdio_rx_isr(struct rtw_dev *rtwdev) { u32 rx_len, hisr, total_rx_bytes = 0; + int ret; do { if (rtw_chip_wcpu_8051(rtwdev)) @@ -1431,7 +1434,9 @@ static void rtw_sdio_rx_isr(struct rtw_dev *rtwdev) if (!rx_len) break; - rtw_sdio_rxfifo_recv(rtwdev, rx_len); + ret = rtw_sdio_rxfifo_recv(rtwdev, rx_len); + if (ret) + break; total_rx_bytes += rx_len; -- 2.53.0