请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
器件型号:CC3351工具/软件:
我想保持 WiFi 连接的活动状态、因此我启用了 WoWLAN。 但是、当使用 RTC 或串行端口等其他来源唤醒系统时、WiFi 接口无法正常恢复。
检查内核日志后、我观察到以下消息:
[ 84.413671] wlcore: flushing tx buffer: 3 0 [ 84.453673] wlcore: flushing tx buffer: 3 0 [ 84.493674] wlcore: WARNING Unable to flush all TX buffers, timed out (timeout 500 ms [ 84.507403] wlcore: flushing remaining works [ 84.512096] CVTE::imx_thermal_suspend - temp=41277 [ 84.521364] PM: suspend devices took 1.130 seconds [ 84.528715] PM: pm_system_irq_wakeup: 43 triggered rtc alarm [ 84.541226] CVTE::imx_thermal_resume - temp=38197 [ 84.546341] wlcore: mac80211 resume wow=1 [ 84.552052] PM: dpm_run_callback(): wiphy_resume+0x0/0x218 [cfg80211] returns -1662942080 [ 84.560358] PM: Device phy0 failed to resume async: error -1662942080 [ 84.567606] PM: resume devices took 0.030 seconds [ 84.572329] OOM killer enabled. [ 84.575637] Restarting tasks ... done. [ 84.606268] Resume caused by IRQ 43, rtc alarm [ 84.614251] PM: suspend exit
恢复回调函数返回一个意外较大的值
[ 84.552052] PM: dpm_run_callback(): wiphy_resume+0x0/0x218 [cfg80211] returns -1662942080 [ 84.560358] PM: Device phy0 failed to resume async: error -1662942080
因此、我检查了源代码、发现变量 ret 未初始化、因此该函数返回一个未初始化的值。
以下是我编辑后的代码:
static int __maybe_unused cc33xx_op_resume(struct ieee80211_hw *hw)
{
struct cc33xx *wl = hw->priv;
struct cc33xx_vif *wlvif;
unsigned long flags;
bool run_irq_work = false, pending_recovery;
int ret = 0;// -----------------------------------here
cc33xx_debug(DEBUG_MAC80211, "mac80211 resume wow=%d",
wl->keep_device_power);
WARN_ON(!wl->keep_device_power);
/*
* re-enable irq_work enqueuing, and call irq_work directly if
* there is a pending work.
*/
spin_lock_irqsave(&wl->wl_lock, flags);
clear_bit(CC33XX_FLAG_SUSPENDED, &wl->flags);
run_irq_work = test_and_clear_bit(CC33XX_FLAG_PENDING_WORK, &wl->flags);
spin_unlock_irqrestore(&wl->wl_lock, flags);
mutex_lock(&wl->mutex);
/* test the recovery flag before calling any SDIO functions */
pending_recovery = test_bit(CC33XX_FLAG_RECOVERY_IN_PROGRESS,
&wl->flags);
if (run_irq_work) {
cc33xx_debug(DEBUG_MAC80211, "run postponed irq_work directly");
/* don't talk to the HW if recovery is pending */
if (!pending_recovery) {
ret = wlcore_irq_locked(wl);
if (ret)
cc33xx_queue_recovery_work(wl);
}
wlcore_enable_interrupts(wl);
}
if (pending_recovery) {
cc33xx_warning("queuing forgotten recovery on resume");
ieee80211_queue_work(wl->hw, &wl->recovery_work);
goto out;
}
cc33xx_for_each_wlvif(wl, wlvif) {
if (wlcore_is_p2p_mgmt(wlvif))
continue;
cc33xx_configure_resume(wl, wlvif);
}
out:
wl->keep_device_power = false;
/*
* Set a flag to re-init the watchdog on the first Tx after resume.
* That way we avoid possible conditions where Tx-complete interrupts
* fail to arrive and we perform a spurious recovery.
*/
set_bit(CC33XX_FLAG_REINIT_TX_WDOG, &wl->flags);
mutex_unlock(&wl->mutex);
return ret;
}