1: a9335d40623d ! 1: 34af7515ed2e wifi: rtw88: sdio: Handle allocation and read errors in rtw_sdio_rxfifo_recv @@ drivers/net/wireless/realtek/rtw88/sdio.c: static void rtw_sdio_rxfifo_recv(stru }  pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz + +@@ drivers/net/wireless/realtek/rtw88/sdio.c: static void rtw_sdio_rxfifo_recv(struct rtw_dev *rtwdev, u32 rx_len) + "oversized RX packet: %u, %u bytes left\n", + pkt_offset + pkt_stat.pkt_len, rx_len); + dev_kfree_skb_any(skb); +- return; ++ return -EINVAL; + } +  + if ((curr_pkt_len + pkt_desc_sz) >= rx_len) {  @@ drivers/net/wireless/realtek/rtw88/sdio.c: static void rtw_sdio_rxfifo_recv(struct rtw_dev *rtwdev, u32 rx_len) skb_reserve(skb, curr_pkt_len); rx_len -= curr_pkt_len; 2: c4e63f18f15a ! 2: 66b20c166263 wifi: rtw88: sdio: Track running state and cancel TX worker on stop @@ Commit message (similar to PCI), check it at the entry of rtw_sdio_handle_interrupt() and rtw_sdio_tx_handler(), serialize state transitions in rtw_sdio_start() and rtw_sdio_stop() under sdio_claim_host() and irq_lock, cancel the TX - worker synchronously in rtw_sdio_stop(), and re-arm it in rtw_sdio_start() - so any frames left parked across a stop are drained and stopped queues are - woken. + worker synchronously in rtw_sdio_stop(), and purge any remaining frames in + rtwsdio->tx_queue[] while waking any stopped AC queues.  Fixes: 28eaf7971a20 ("wifi: rtw88: sdio: add TX back-pressure and retry on page starvation") Cc: stable@vger.kernel.org @@ drivers/net/wireless/realtek/rtw88/sdio.c: static int rtw_sdio_start(struct rtw_  + }  +  + sdio_release_host(rtwsdio->sdio_func); -+ -+ queue_delayed_work(rtwsdio->txwq, &rtwsdio->tx_handler_data->work, 0);  return 0; } @@ drivers/net/wireless/realtek/rtw88/sdio.c: static int rtw_sdio_start(struct rtw_ {  - rtw_sdio_disable_interrupt(rtwdev);  + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; ++ enum rtw_tx_queue_type queue; ++ int i;  +  + sdio_claim_host(rtwsdio->sdio_func);  + scoped_guard(mutex, &rtwsdio->irq_lock) { @@ drivers/net/wireless/realtek/rtw88/sdio.c: static int rtw_sdio_start(struct rtw_  + sdio_release_host(rtwsdio->sdio_func);  +  + cancel_delayed_work_sync(&rtwsdio->tx_handler_data->work); ++ ++ for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++) ++ ieee80211_purge_tx_queue(rtwdev->hw, &rtwsdio->tx_queue[i]); ++ ++ for (i = 0; i < IEEE80211_NUM_ACS; i++) { ++ queue = rtw_tx_ac_to_hwq(i); ++ if (rtwsdio->tx_queue_stopped[queue]) { ++ rtwsdio->tx_queue_stopped[queue] = false; ++ ieee80211_wake_queue(rtwdev->hw, i); ++ } ++ } }  static void rtw_sdio_deep_ps_enter(struct rtw_dev *rtwdev) 3: d760e1391170 = 3: c50cea8ee36b wifi: rtw88: sdio: Fix unhandled RX request interrupt storm 4: 42d50000a62f = 4: 76bdfa584777 wifi: rtw88: sdio: Split rtw_sdio_rx_isr into 8051 and 3081 variants