From 3c2c211d371d662cfca9552e98b2b376364f8aae Mon Sep 17 00:00:00 2001 From: Krunal Soni Date: Wed, 19 Dec 2018 20:06:26 -0800 Subject: [PATCH] qcacmn: In SAP-WOW-D0 state, wake-up FW on receiption of unicast pkt When unit test command "iwpriv wlan0 wlan_suspend 0 0" is issued on SAP-DUT (given that one REF-STA is connected), FW would go in WOW-D0 state. In this state, when HW receives the pkt from peer (REF-STA), it generates MSI (REO-interrupt) and host process this pkt but it doesn't wake-up the FW. Due to this situation, no TX is happening on SAP after issueing wlan_suspend command. This situation only happens when iwpriv command issued as this command would be fool the FW by notifying that APSS is in power-down state but actually it is not in active state. When APSS is really in power-down state then up-on receiption of any RX pkt would wake-up the APSS and this waking-up process would wake-up FW as well. Fix this situation by sending explicit FW wake-up event. CRs-Fixed: 2325860 Change-Id: I18937e5c568c742f838cdf3f815c2184a916283c --- hif/src/hif_exec.c | 39 +++++++++++++++++++++++++++++++ hif/src/hif_unit_test_suspend.c | 10 +++++++- hif/src/hif_unit_test_suspend_i.h | 11 +++++++-- 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/hif/src/hif_exec.c b/hif/src/hif_exec.c index be45274b9ebb..1928182879ca 100644 --- a/hif/src/hif_exec.c +++ b/hif/src/hif_exec.c @@ -316,6 +316,32 @@ uint32_t hif_configure_ext_group_interrupts(struct hif_opaque_softc *hif_ctx) } qdf_export_symbol(hif_configure_ext_group_interrupts); +#ifdef WLAN_SUSPEND_RESUME_TEST +/** + * hif_check_and_trigger_ut_resume() - check if unit-test command was used to + * to trigger fake-suspend command, if yes + * then issue resume procedure. + * @scn: opaque HIF software context + * + * This API checks if unit-test command was used to trigger fake-suspend command + * and if answer is yes then it would trigger resume procedure. + * + * Make this API inline to save API-switch overhead and do branch-prediction to + * optimize performance impact. + * + * Return: void + */ +static inline void hif_check_and_trigger_ut_resume(struct hif_softc *scn) +{ + if (qdf_unlikely(hif_irq_trigger_ut_resume(scn))) + hif_ut_fw_resume(scn); +} +#else +static inline void hif_check_and_trigger_ut_resume(struct hif_softc *scn) +{ +} +#endif + /** * hif_ext_group_interrupt_handler() - handler for related interrupts * @irq: irq number of the interrupt @@ -332,6 +358,19 @@ irqreturn_t hif_ext_group_interrupt_handler(int irq, void *context) if (hif_ext_group->irq_requested) { hif_ext_group->irq_disable(hif_ext_group); + /* + * if private ioctl has issued fake suspend command to put + * FW in D0-WOW state then here is our chance to bring FW out + * of WOW mode. + * + * The reason why you need to explicitly wake-up the FW is here: + * APSS should have been in fully awake through-out when + * fake APSS suspend command was issued (to put FW in WOW mode) + * hence organic way of waking-up the FW + * (as part-of APSS-host wake-up) won't happen because + * in reality APSS didn't really suspend. + */ + hif_check_and_trigger_ut_resume(scn); qdf_atomic_inc(&scn->active_grp_tasklet_cnt); hif_ext_group->sched_ops->schedule(hif_ext_group); diff --git a/hif/src/hif_unit_test_suspend.c b/hif/src/hif_unit_test_suspend.c index 938648c325de..112b25fb815c 100644 --- a/hif/src/hif_unit_test_suspend.c +++ b/hif/src/hif_unit_test_suspend.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -112,3 +112,11 @@ QDF_STATUS hif_ut_fw_resume(struct hif_softc *scn) return QDF_STATUS_SUCCESS; } + +bool hif_irq_trigger_ut_resume(struct hif_softc *scn) +{ + if (!hif_is_ut_suspended(scn)) + return false; + + return true; +} diff --git a/hif/src/hif_unit_test_suspend_i.h b/hif/src/hif_unit_test_suspend_i.h index dedb1e51cc92..4a4a4a97ca33 100644 --- a/hif/src/hif_unit_test_suspend_i.h +++ b/hif/src/hif_unit_test_suspend_i.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -63,6 +63,14 @@ bool hif_is_ut_suspended(struct hif_softc *scn); */ QDF_STATUS hif_ut_fw_resume(struct hif_softc *scn); +/** + * hif_irq_trigger_ut_resume() - Test for given hif ctx unit-test resume needed + * @scn: The HIF context to check + * + * Return: true, if unit-test resume procedure is needed, otherwise false + */ +bool hif_irq_trigger_ut_resume(struct hif_softc *scn); + #else /* WLAN_SUSPEND_RESUME_TEST */ struct hif_ut_suspend_context {}; @@ -78,7 +86,6 @@ static inline QDF_STATUS hif_ut_fw_resume(struct hif_softc *scn) { return QDF_STATUS_SUCCESS; } - #endif /* WLAN_SUSPEND_RESUME_TEST */ #endif /* _HIF_UNIT_TEST_SUSPEND_I_H_ */