diff mbox series

[v3] ath11k: cold boot calibration support

Message ID 1600163991-2093-1-git-send-email-ssreeela@codeaurora.org
State New
Headers show
Series [v3] ath11k: cold boot calibration support | expand

Commit Message

Sowmiya Sree Elavalagan Sept. 15, 2020, 9:59 a.m. UTC
From: Govindaraj Saminathan <gsamin@codeaurora.org>

cold boot calibration is the process to calibrate all the channels
during the boot-up to avoid the calibration delay during the
channel change.
During the boot-up, firmware started with mode “cold_boot_calibration”
Firmware calibrate all channels and generate CalDb(DDR).
Subsequent WIFI ON will reuse the same CalDb.
Firmware restarted with Mission mode to continue the normal operation.

caldb memory address send to firmware through the QMI message.Firmware
use this address to store the caldb data and use it until next reboot.

This will give the improvement during the channel change. But it is
increasing the boot-up time(up to 15sec depend on number of radios).
So if the user want to reduce the boot-up time and accepting for channel
change delay, user can disable this feature using the module param
cold_boot_cal =0.
Tested-on: IPQ8074 WLAN.HK.2.4.0.1-00192-QCAHKSWPL_SILICONZ-1


Signed-off-by: Govindaraj Saminathan <gsamin@codeaurora.org>
Co-developed-by: Sowmiya Sree Elavalagan <ssreeela@codeaurora.org>
Signed-off-by: Sowmiya Sree Elavalagan <ssreeela@codeaurora.org>
---
v2:
   - Fixed compilations warnings
     Reported-by: kernel test robot <lkp@intel.com>
v3:
   - Rebased
     Added cold_boot_calib flag in hw params to enable cold boot calibration only for supported hardware
---
 drivers/net/wireless/ath/ath11k/ahb.c  | 27 ++++++++++++++
 drivers/net/wireless/ath/ath11k/core.c |  3 ++
 drivers/net/wireless/ath/ath11k/core.h |  5 +++
 drivers/net/wireless/ath/ath11k/hw.h   |  1 +
 drivers/net/wireless/ath/ath11k/qmi.c  | 67 ++++++++++++++++++++++++++++++----
 drivers/net/wireless/ath/ath11k/qmi.h  |  3 ++
 6 files changed, 99 insertions(+), 7 deletions(-)

Comments

Peter Oh Sept. 17, 2020, 7:54 p.m. UTC | #1
On 9/15/20 2:59 AM, Sowmiya Sree Elavalagan wrote:
> From: Govindaraj Saminathan <gsamin@codeaurora.org>

>

> cold boot calibration is the process to calibrate all the channels

> during the boot-up to avoid the calibration delay during the

> channel change.

> During the boot-up, firmware started with mode “cold_boot_calibration”

> Firmware calibrate all channels and generate CalDb(DDR).

> Subsequent WIFI ON will reuse the same CalDb.

Can you clarify the definition of "WIFI ON"?
> Firmware restarted with Mission mode to continue the normal operation.


Please change the mission mode to normal according to 
ATH11K_FIRMWARE_MODE_NORMAL.

Which code it sets back to normal mode from cold boot mode? I don't see it.

> +static int ath11k_qmi_process_coldboot_calibration(struct ath11k_base *ab)

> +{

> +	int timeout;

> +	int ret;

> +

> +	ret = ath11k_qmi_wlanfw_mode_send(ab, ATH11K_FIRMWARE_MODE_COLD_BOOT);

> +	if (ret < 0) {

> +		ath11k_warn(ab, "qmi failed to send wlan fw mode:%d\n", ret);

> +		return ret;

> +	}

> +

> +	ath11k_dbg(ab, ATH11K_DBG_QMI, "Coldboot calibration wait started\n");

> +

> +	timeout = wait_event_timeout(ab->qmi.cold_boot_waitq,

> +				     (ab->qmi.cal_done  == 1),

> +				     ATH11K_COLD_BOOT_FW_RESET_DELAY);

> +	if (timeout <= 0) {

> +		ath11k_warn(ab, "Coldboot Calibration timed out\n");

> +		return -ETIMEDOUT;


Does it make ath11k firmware stay in cold boot mode when timeout happens?

If so, is it worthy to have WLAN usuable due to cold boot calibration 
failure?

As I understand, initial calibration on current operation channel will 
be done regardless of cold boot calibration

> +	}

> +

> +	ath11k_dbg(ab, ATH11K_DBG_QMI, "Coldboot calibration wait ended\n");

> +

> +	return 0;

> +}

> +

>   static int

>   ath11k_qmi_driver_event_post(struct ath11k_qmi *qmi,

>   			     enum ath11k_qmi_event_type type,

> @@ -2597,9 +2643,16 @@ static void ath11k_qmi_driver_event_work(struct work_struct *work)

>   				break;

>   			}

>   

> -			ath11k_core_qmi_firmware_ready(ab);

> -			ab->qmi.cal_done = 1;

> -			set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags);

> +			if (ath11k_cold_boot_cal && ab->qmi.cal_done == 0 &&

> +			    ab->hw_params.cold_boot_calib) {

> +				ath11k_qmi_process_coldboot_calibration(ab);

> +			} else {

> +				clear_bit(ATH11K_FLAG_CRASH_FLUSH,

> +					  &ab->dev_flags);

> +				clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);

Please split this patch into a separate patch. It's not directly related 
to cold boot.
> +				ath11k_core_qmi_firmware_ready(ab);

> +				set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags);

> +			}

>   

>   			break;

>   		case ATH11K_QMI_EVENT_COLD_BOOT_CAL_DONE:


Thanks,

Peter
Kalle Valo Sept. 21, 2020, 1:40 p.m. UTC | #2
kernel test robot <lkp@intel.com> writes:

> Thank you for the patch! Yet something to improve:
>
> [auto build test ERROR on ath6kl/ath-next]
> [also build test ERROR on next-20200915]
> [cannot apply to v5.9-rc5]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch]
>
> url:
> https://github.com/0day-ci/linux/commits/Sowmiya-Sree-Elavalagan/ath11k-cold-boot-calibration-support/20200915-180324
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git ath-next
> config: mips-allmodconfig (attached as .config)
> compiler: mips-linux-gcc (GCC) 9.3.0
> reproduce (this is a W=1 build):
>         wget
> https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross
> -O ~/bin/make.cross
>         chmod +x ~/bin/make.cross
>         # save the attached .config to linux build tree
>         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=mips 
>
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp@intel.com>
>
> All errors (new ones prefixed by >>, old ones prefixed by <<):
>
> ERROR: modpost: "fw_arg3" [drivers/mtd/parsers/bcm63xxpart.ko] undefined!
>>> ERROR: modpost: "ath11k_cold_boot_cal"
> [drivers/net/wireless/ath/ath11k/ath11k_ahb.ko] undefined!

For some reason I don't see the kbuild bot report above in patchwork:

https://patchwork.kernel.org/patch/11775953/

This time the message ids seem to be ok:

Message-Id: <1600163991-2093-1-git-send-email-ssreeela@codeaurora.org>
[...]
In-Reply-To: <1600163991-2093-1-git-send-email-ssreeela@codeaurora.org>
References: <1600163991-2093-1-git-send-email-ssreeela@codeaurora.org>

If anyone has ideas why patchwork doesn't see the report, please let me
know.
Kalle Valo Sept. 21, 2020, 1:42 p.m. UTC | #3
Sowmiya Sree Elavalagan <ssreeela@codeaurora.org> wrote:

> From: Govindaraj Saminathan <gsamin@codeaurora.org>

> 

> cold boot calibration is the process to calibrate all the channels

> during the boot-up to avoid the calibration delay during the

> channel change.

> During the boot-up, firmware started with mode “cold_boot_calibration”

> Firmware calibrate all channels and generate CalDb(DDR).

> Subsequent WIFI ON will reuse the same CalDb.

> Firmware restarted with Mission mode to continue the normal operation.

> 

> caldb memory address send to firmware through the QMI message.Firmware

> use this address to store the caldb data and use it until next reboot.

> 

> This will give the improvement during the channel change. But it is

> increasing the boot-up time(up to 15sec depend on number of radios).

> So if the user want to reduce the boot-up time and accepting for channel

> change delay, user can disable this feature using the module param

> cold_boot_cal =0.

> Tested-on: IPQ8074 WLAN.HK.2.4.0.1-00192-QCAHKSWPL_SILICONZ-1

> 

> 

> Signed-off-by: Govindaraj Saminathan <gsamin@codeaurora.org>

> Co-developed-by: Sowmiya Sree Elavalagan <ssreeela@codeaurora.org>

> Signed-off-by: Sowmiya Sree Elavalagan <ssreeela@codeaurora.org>


Fails to apply:

error: patch failed: drivers/net/wireless/ath/ath11k/ahb.c:573
error: drivers/net/wireless/ath/ath11k/ahb.c: patch does not apply
stg import: Diff does not apply cleanly

Patch set to Changes Requested.

-- 
https://patchwork.kernel.org/patch/11775953/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
kernel test robot Sept. 22, 2020, 5:07 a.m. UTC | #4
On 9/21/20 9:40 PM, Kalle Valo wrote:
> kernel test robot <lkp@intel.com> writes:

>

>> Thank you for the patch! Yet something to improve:

>>

>> [auto build test ERROR on ath6kl/ath-next]

>> [also build test ERROR on next-20200915]

>> [cannot apply to v5.9-rc5]

>> [If your patch is applied to the wrong git tree, kindly drop us a note.

>> And when submitting patch, we suggest to use '--base' as documented in

>> https://git-scm.com/docs/git-format-patch]

>>

>> url:

>> https://github.com/0day-ci/linux/commits/Sowmiya-Sree-Elavalagan/ath11k-cold-boot-calibration-support/20200915-180324

>> base:   https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git ath-next

>> config: mips-allmodconfig (attached as .config)

>> compiler: mips-linux-gcc (GCC) 9.3.0

>> reproduce (this is a W=1 build):

>>          wget

>> https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross

>> -O ~/bin/make.cross

>>          chmod +x ~/bin/make.cross

>>          # save the attached .config to linux build tree

>>          COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=mips

>>

>> If you fix the issue, kindly add following tag as appropriate

>> Reported-by: kernel test robot <lkp@intel.com>

>>

>> All errors (new ones prefixed by >>, old ones prefixed by <<):

>>

>> ERROR: modpost: "fw_arg3" [drivers/mtd/parsers/bcm63xxpart.ko] undefined!

>>>> ERROR: modpost: "ath11k_cold_boot_cal"

>> [drivers/net/wireless/ath/ath11k/ath11k_ahb.ko] undefined!

> For some reason I don't see the kbuild bot report above in patchwork:

>

> https://patchwork.kernel.org/patch/11775953/

>

> This time the message ids seem to be ok:

>

> Message-Id: <1600163991-2093-1-git-send-email-ssreeela@codeaurora.org>

> [...]

> In-Reply-To: <1600163991-2093-1-git-send-email-ssreeela@codeaurora.org>

> References: <1600163991-2093-1-git-send-email-ssreeela@codeaurora.org>

>

> If anyone has ideas why patchwork doesn't see the report, please let me

> know.

>


Hi Kalle,

We hided the reports for patchwork, please see 
https://gitlab.freedesktop.org/patchwork-fdo/patchwork-fdo/-/issues/21

Best Regards,
Rong Chen
Kalle Valo Sept. 22, 2020, 5:54 a.m. UTC | #5
Rong Chen <rong.a.chen@intel.com> writes:

> On 9/21/20 9:40 PM, Kalle Valo wrote:
>> kernel test robot <lkp@intel.com> writes:
>>
>>> Thank you for the patch! Yet something to improve:
>>>
>>> [auto build test ERROR on ath6kl/ath-next]
>>> [also build test ERROR on next-20200915]
>>> [cannot apply to v5.9-rc5]
>>> [If your patch is applied to the wrong git tree, kindly drop us a note.
>>> And when submitting patch, we suggest to use '--base' as documented in
>>> https://git-scm.com/docs/git-format-patch]
>>>
>>> url:
>>> https://github.com/0day-ci/linux/commits/Sowmiya-Sree-Elavalagan/ath11k-cold-boot-calibration-support/20200915-180324
>>> base:   https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git ath-next
>>> config: mips-allmodconfig (attached as .config)
>>> compiler: mips-linux-gcc (GCC) 9.3.0
>>> reproduce (this is a W=1 build):
>>>          wget
>>> https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross
>>> -O ~/bin/make.cross
>>>          chmod +x ~/bin/make.cross
>>>          # save the attached .config to linux build tree
>>>          COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=mips
>>>
>>> If you fix the issue, kindly add following tag as appropriate
>>> Reported-by: kernel test robot <lkp@intel.com>
>>>
>>> All errors (new ones prefixed by >>, old ones prefixed by <<):
>>>
>>> ERROR: modpost: "fw_arg3" [drivers/mtd/parsers/bcm63xxpart.ko] undefined!
>>>>> ERROR: modpost: "ath11k_cold_boot_cal"
>>> [drivers/net/wireless/ath/ath11k/ath11k_ahb.ko] undefined!
>> For some reason I don't see the kbuild bot report above in patchwork:
>>
>> https://patchwork.kernel.org/patch/11775953/
>>
>> This time the message ids seem to be ok:
>>
>> Message-Id: <1600163991-2093-1-git-send-email-ssreeela@codeaurora.org>
>> [...]
>> In-Reply-To: <1600163991-2093-1-git-send-email-ssreeela@codeaurora.org>
>> References: <1600163991-2093-1-git-send-email-ssreeela@codeaurora.org>
>>
>> If anyone has ideas why patchwork doesn't see the report, please let me
>> know.
>>
>
> Hi Kalle,
>
> We hided the reports for patchwork, please see
> https://gitlab.freedesktop.org/patchwork-fdo/patchwork-fdo/-/issues/21

Didn't we discuss before and concluded that hiding the reports from
patchwork is a VERY bad idea? As it should be the opposite, the kbuild
reports should be visible in patchwork so that maintainers see them. For
example, when I'm about to apply a patch I only check the comments in
patchwork (and not from my email folder), so if the report from the bot
is not on patchwork I will not see it.

But having X-Patchwork-Hint set in the automatically created patches
sent by kbuild bot is ok, and I believe that's what kbuild bot currently
does. The bot should not set X-Patchwork-Hint in report emails.
 
Anyway, I don't think that was the problem in this case as I don't see
X-Patchwork-Hint header set in the report above.
kernel test robot Sept. 22, 2020, 6:29 a.m. UTC | #6
On 9/22/20 1:54 PM, Kalle Valo wrote:
> Rong Chen <rong.a.chen@intel.com> writes:
>
>> On 9/21/20 9:40 PM, Kalle Valo wrote:
>>> kernel test robot <lkp@intel.com> writes:
>>>
>>>> Thank you for the patch! Yet something to improve:
>>>>
>>>> [auto build test ERROR on ath6kl/ath-next]
>>>> [also build test ERROR on next-20200915]
>>>> [cannot apply to v5.9-rc5]
>>>> [If your patch is applied to the wrong git tree, kindly drop us a note.
>>>> And when submitting patch, we suggest to use '--base' as documented in
>>>> https://git-scm.com/docs/git-format-patch]
>>>>
>>>> url:
>>>> https://github.com/0day-ci/linux/commits/Sowmiya-Sree-Elavalagan/ath11k-cold-boot-calibration-support/20200915-180324
>>>> base:   https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git ath-next
>>>> config: mips-allmodconfig (attached as .config)
>>>> compiler: mips-linux-gcc (GCC) 9.3.0
>>>> reproduce (this is a W=1 build):
>>>>           wget
>>>> https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross
>>>> -O ~/bin/make.cross
>>>>           chmod +x ~/bin/make.cross
>>>>           # save the attached .config to linux build tree
>>>>           COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=mips
>>>>
>>>> If you fix the issue, kindly add following tag as appropriate
>>>> Reported-by: kernel test robot <lkp@intel.com>
>>>>
>>>> All errors (new ones prefixed by >>, old ones prefixed by <<):
>>>>
>>>> ERROR: modpost: "fw_arg3" [drivers/mtd/parsers/bcm63xxpart.ko] undefined!
>>>>>> ERROR: modpost: "ath11k_cold_boot_cal"
>>>> [drivers/net/wireless/ath/ath11k/ath11k_ahb.ko] undefined!
>>> For some reason I don't see the kbuild bot report above in patchwork:
>>>
>>> https://patchwork.kernel.org/patch/11775953/
>>>
>>> This time the message ids seem to be ok:
>>>
>>> Message-Id: <1600163991-2093-1-git-send-email-ssreeela@codeaurora.org>
>>> [...]
>>> In-Reply-To: <1600163991-2093-1-git-send-email-ssreeela@codeaurora.org>
>>> References: <1600163991-2093-1-git-send-email-ssreeela@codeaurora.org>
>>>
>>> If anyone has ideas why patchwork doesn't see the report, please let me
>>> know.
>>>
>> Hi Kalle,
>>
>> We hided the reports for patchwork, please see
>> https://gitlab.freedesktop.org/patchwork-fdo/patchwork-fdo/-/issues/21
> Didn't we discuss before and concluded that hiding the reports from
> patchwork is a VERY bad idea? As it should be the opposite, the kbuild
> reports should be visible in patchwork so that maintainers see them. For
> example, when I'm about to apply a patch I only check the comments in
> patchwork (and not from my email folder), so if the report from the bot
> is not on patchwork I will not see it.
>
> But having X-Patchwork-Hint set in the automatically created patches
> sent by kbuild bot is ok, and I believe that's what kbuild bot currently
> does. The bot should not set X-Patchwork-Hint in report emails.
>   
> Anyway, I don't think that was the problem in this case as I don't see
> X-Patchwork-Hint header set in the report above.
>

Hi Kalle,

Sorry for the misunderstanding, you reminded me that we do changed to
only set X-Patchwork-Hint for patches from bot, and I double checked the
original mail that there's no X-Patchwork-Hint in it, I have no idea why
patchwork can't see this report now.

Best Regards,
Rong Chen
Sowmiya Sree Elavalagan Oct. 15, 2020, 11:37 a.m. UTC | #7
On 2020-09-18 01:24, Peter Oh wrote:
> On 9/15/20 2:59 AM, Sowmiya Sree Elavalagan wrote:
>> From: Govindaraj Saminathan <gsamin@codeaurora.org>
>> 
>> cold boot calibration is the process to calibrate all the channels
>> during the boot-up to avoid the calibration delay during the
>> channel change.
>> During the boot-up, firmware started with mode “cold_boot_calibration”
>> Firmware calibrate all channels and generate CalDb(DDR).
>> Subsequent WIFI ON will reuse the same CalDb.
> Can you clarify the definition of "WIFI ON"?

WIFI ON here refers to wireless interfaces bring
up(reinitialised) in normal mode

>> Firmware restarted with Mission mode to continue the normal operation.
> 
> Please change the mission mode to normal according to
> ATH11K_FIRMWARE_MODE_NORMAL.

Sure we will change that
> 
> Which code it sets back to normal mode from cold boot mode? I don't see 
> it.
> 

Please check the function ath11k_qmi_fwreset_from_cold_boot where 
firmware is reset.
During restart, firmware mode will be reset to normal.
>> +static int ath11k_qmi_process_coldboot_calibration(struct ath11k_base 
>> *ab)
>> +{
>> +	int timeout;
>> +	int ret;
>> +
>> +	ret = ath11k_qmi_wlanfw_mode_send(ab, 
>> ATH11K_FIRMWARE_MODE_COLD_BOOT);
>> +	if (ret < 0) {
>> +		ath11k_warn(ab, "qmi failed to send wlan fw mode:%d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	ath11k_dbg(ab, ATH11K_DBG_QMI, "Coldboot calibration wait 
>> started\n");
>> +
>> +	timeout = wait_event_timeout(ab->qmi.cold_boot_waitq,
>> +				     (ab->qmi.cal_done  == 1),
>> +				     ATH11K_COLD_BOOT_FW_RESET_DELAY);
>> +	if (timeout <= 0) {
>> +		ath11k_warn(ab, "Coldboot Calibration timed out\n");
>> +		return -ETIMEDOUT;
> 
> Does it make ath11k firmware stay in cold boot mode when timeout 
> happens?
> 
> If so, is it worthy to have WLAN usuable due to cold boot calibration 
> failure?
> 
> As I understand, initial calibration on current operation channel will
> be done regardless of cold boot calibration
> 

Agreed, these comments will be addressed in the next patch set.
>> +	}
>> +
>> +	ath11k_dbg(ab, ATH11K_DBG_QMI, "Coldboot calibration wait ended\n");
>> +
>> +	return 0;
>> +}
>> +
>>   static int
>>   ath11k_qmi_driver_event_post(struct ath11k_qmi *qmi,
>>   			     enum ath11k_qmi_event_type type,
>> @@ -2597,9 +2643,16 @@ static void ath11k_qmi_driver_event_work(struct 
>> work_struct *work)
>>   				break;
>>   			}
>>   -			ath11k_core_qmi_firmware_ready(ab);
>> -			ab->qmi.cal_done = 1;
>> -			set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags);
>> +			if (ath11k_cold_boot_cal && ab->qmi.cal_done == 0 &&
>> +			    ab->hw_params.cold_boot_calib) {
>> +				ath11k_qmi_process_coldboot_calibration(ab);
>> +			} else {
>> +				clear_bit(ATH11K_FLAG_CRASH_FLUSH,
>> +					  &ab->dev_flags);
>> +				clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
> Please split this patch into a separate patch. It's not directly
> related to cold boot.

This resets the flag to commence normal operation when firmware switches 
to normal mode after cold boot calibration.
Once the firmware is ready we clear this flag so that it will not block 
any further communication with firmware.
>> +				ath11k_core_qmi_firmware_ready(ab);
>> +				set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags);
>> +			}
>>     			break;
>>   		case ATH11K_QMI_EVENT_COLD_BOOT_CAL_DONE:
> 
> Thanks,
> 
> Peter
diff mbox series

Patch

diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c
index 6380d48..ccb6d40 100644
--- a/drivers/net/wireless/ath/ath11k/ahb.c
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
@@ -573,6 +573,31 @@  static void ath11k_ahb_power_down(struct ath11k_base *ab)
 	rproc_shutdown(ab->tgt_rproc);
 }
 
+static int ath11k_ahb_fwreset_from_cold_boot(struct ath11k_base *ab)
+{
+	int timeout;
+
+	if (ath11k_cold_boot_cal == 0 || ab->qmi.cal_done ||
+	    ab->hw_params.cold_boot_calib == 0)
+		return 0;
+
+	ath11k_dbg(ab, ATH11K_DBG_AHB, "wait for cold boot done\n");
+	timeout = wait_event_timeout(ab->qmi.cold_boot_waitq,
+				     (ab->qmi.cal_done  == 1),
+				     ATH11K_COLD_BOOT_FW_RESET_DELAY);
+	if (timeout <= 0) {
+		ath11k_warn(ab, "Coldboot Calibration timed out\n");
+		return -ETIMEDOUT;
+	}
+
+	/* reset the firmware */
+	ath11k_ahb_power_down(ab);
+	ath11k_ahb_power_up(ab);
+
+	ath11k_dbg(ab, ATH11K_DBG_AHB, "exit wait for cold boot done\n");
+	return 0;
+}
+
 static void ath11k_ahb_init_qmi_ce_config(struct ath11k_base *ab)
 {
 	struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg;
@@ -903,6 +928,8 @@  static int ath11k_ahb_probe(struct platform_device *pdev)
 		goto err_ce_free;
 	}
 
+	ath11k_ahb_fwreset_from_cold_boot(ab);
+
 	return 0;
 
 err_ce_free:
diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
index 437b112..c7db0e1 100644
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -43,6 +43,7 @@  static const struct ath11k_hw_params ath11k_hw_params[] = {
 		.vdev_start_delay = false,
 		.htt_peer_map_v2 = true,
 		.tcl_0_only = false,
+		.cold_boot_calib = true,
 	},
 	{
 		.name = "qca6390 hw2.0",
@@ -68,6 +69,7 @@  static const struct ath11k_hw_params ath11k_hw_params[] = {
 		.vdev_start_delay = true,
 		.htt_peer_map_v2 = false,
 		.tcl_0_only = true,
+		.cold_boot_calib = false,
 	},
 };
 
@@ -871,6 +873,7 @@  struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size,
 	INIT_LIST_HEAD(&ab->peers);
 	init_waitqueue_head(&ab->peer_mapping_wq);
 	init_waitqueue_head(&ab->wmi_ab.tx_credits_wq);
+	init_waitqueue_head(&ab->qmi.cold_boot_waitq);
 	INIT_WORK(&ab->restart_work, ath11k_core_restart);
 	timer_setup(&ab->rx_replenish_retry, ath11k_ce_rx_replenish_retry, 0);
 	ab->dev = dev;
diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
index d21191c..1d8242e 100644
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -99,8 +99,13 @@  enum ath11k_firmware_mode {
 
 	/* factory tests etc */
 	ATH11K_FIRMWARE_MODE_FTM,
+
+	/* Cold boot calibration */
+	ATH11K_FIRMWARE_MODE_COLD_BOOT = 7,
 };
 
+extern bool ath11k_cold_boot_cal;
+
 #define ATH11K_IRQ_NUM_MAX 52
 #define ATH11K_EXT_IRQ_NUM_MAX	16
 
diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h
index d15fa7f..a585772 100644
--- a/drivers/net/wireless/ath/ath11k/hw.h
+++ b/drivers/net/wireless/ath/ath11k/hw.h
@@ -152,6 +152,7 @@  struct ath11k_hw_params {
 	bool vdev_start_delay;
 	bool htt_peer_map_v2;
 	bool tcl_0_only;
+	bool cold_boot_calib;
 };
 
 struct ath11k_hw_ops {
diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c
index b906b50..25c99de 100644
--- a/drivers/net/wireless/ath/ath11k/qmi.c
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
@@ -12,6 +12,12 @@ 
 #define SLEEP_CLOCK_SELECT_INTERNAL_BIT	0x02
 #define HOST_CSTATE_BIT			0x04
 
+bool ath11k_cold_boot_cal = 1;
+module_param_named(cold_boot_cal, ath11k_cold_boot_cal, bool, 0644);
+MODULE_PARM_DESC(cold_boot_cal,
+		 "Cold boot will bring down the channel switch time but "
+		 "it will increase the driver load time (enable:1, disable:0)");
+
 static struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = {
 	{
 		.data_type	= QMI_OPT_FLAG,
@@ -1767,9 +1773,16 @@  static int ath11k_qmi_assign_target_mem_chunk(struct ath11k_base *ab)
 				ath11k_warn(ab, "qmi mem size is low to load caldata\n");
 				return -EINVAL;
 			}
-			/* TODO ath11k does not support cold boot calibration */
-			ab->qmi.target_mem[idx].paddr = 0;
-			ab->qmi.target_mem[idx].vaddr = NULL;
+
+			if (ath11k_cold_boot_cal && ab->hw_params.cold_boot_calib) {
+				ab->qmi.target_mem[idx].paddr =
+						     ATH11K_QMI_CALDB_ADDRESS;
+				ab->qmi.target_mem[idx].vaddr =
+						     (void *)ATH11K_QMI_CALDB_ADDRESS;
+			} else {
+				ab->qmi.target_mem[idx].paddr = 0;
+				ab->qmi.target_mem[idx].vaddr = NULL;
+			}
 			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
 			ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
 			idx++;
@@ -2331,6 +2344,32 @@  int ath11k_qmi_firmware_start(struct ath11k_base *ab,
 	return 0;
 }
 
+static int ath11k_qmi_process_coldboot_calibration(struct ath11k_base *ab)
+{
+	int timeout;
+	int ret;
+
+	ret = ath11k_qmi_wlanfw_mode_send(ab, ATH11K_FIRMWARE_MODE_COLD_BOOT);
+	if (ret < 0) {
+		ath11k_warn(ab, "qmi failed to send wlan fw mode:%d\n", ret);
+		return ret;
+	}
+
+	ath11k_dbg(ab, ATH11K_DBG_QMI, "Coldboot calibration wait started\n");
+
+	timeout = wait_event_timeout(ab->qmi.cold_boot_waitq,
+				     (ab->qmi.cal_done  == 1),
+				     ATH11K_COLD_BOOT_FW_RESET_DELAY);
+	if (timeout <= 0) {
+		ath11k_warn(ab, "Coldboot Calibration timed out\n");
+		return -ETIMEDOUT;
+	}
+
+	ath11k_dbg(ab, ATH11K_DBG_QMI, "Coldboot calibration wait ended\n");
+
+	return 0;
+}
+
 static int
 ath11k_qmi_driver_event_post(struct ath11k_qmi *qmi,
 			     enum ath11k_qmi_event_type type,
@@ -2480,11 +2519,18 @@  static void ath11k_qmi_msg_fw_ready_cb(struct qmi_handle *qmi_hdl,
 	ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_READY, NULL);
 }
 
-static void ath11k_qmi_msg_cold_boot_cal_done_cb(struct qmi_handle *qmi,
+static void ath11k_qmi_msg_cold_boot_cal_done_cb(struct qmi_handle *qmi_hdl,
 						 struct sockaddr_qrtr *sq,
 						 struct qmi_txn *txn,
 						 const void *decoded)
 {
+	struct ath11k_qmi *qmi = container_of(qmi_hdl,
+					      struct ath11k_qmi, handle);
+	struct ath11k_base *ab = qmi->ab;
+
+	ab->qmi.cal_done = 1;
+	wake_up(&ab->qmi.cold_boot_waitq);
+	ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi cold boot calibration done\n");
 }
 
 static const struct qmi_msg_handler ath11k_qmi_msg_handlers[] = {
@@ -2597,9 +2643,16 @@  static void ath11k_qmi_driver_event_work(struct work_struct *work)
 				break;
 			}
 
-			ath11k_core_qmi_firmware_ready(ab);
-			ab->qmi.cal_done = 1;
-			set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags);
+			if (ath11k_cold_boot_cal && ab->qmi.cal_done == 0 &&
+			    ab->hw_params.cold_boot_calib) {
+				ath11k_qmi_process_coldboot_calibration(ab);
+			} else {
+				clear_bit(ATH11K_FLAG_CRASH_FLUSH,
+					  &ab->dev_flags);
+				clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
+				ath11k_core_qmi_firmware_ready(ab);
+				set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags);
+			}
 
 			break;
 		case ATH11K_QMI_EVENT_COLD_BOOT_CAL_DONE:
diff --git a/drivers/net/wireless/ath/ath11k/qmi.h b/drivers/net/wireless/ath/ath11k/qmi.h
index 60e9046..8eee3d5 100644
--- a/drivers/net/wireless/ath/ath11k/qmi.h
+++ b/drivers/net/wireless/ath/ath11k/qmi.h
@@ -12,6 +12,7 @@ 
 #define ATH11K_HOST_VERSION_STRING		"WIN"
 #define ATH11K_QMI_WLANFW_TIMEOUT_MS		5000
 #define ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE	64
+#define ATH11K_QMI_CALDB_ADDRESS		0x4BA00000
 #define ATH11K_QMI_BDF_MAX_SIZE			(256 * 1024)
 #define ATH11K_QMI_CALDATA_OFFSET		(128 * 1024)
 #define ATH11K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01	128
@@ -33,6 +34,7 @@ 
 #define QMI_WLANFW_MAX_DATA_SIZE_V01		6144
 #define ATH11K_FIRMWARE_MODE_OFF		4
 #define ATH11K_QMI_TARGET_MEM_MODE_DEFAULT	0
+#define ATH11K_COLD_BOOT_FW_RESET_DELAY		(40 * HZ)
 
 struct ath11k_base;
 
@@ -125,6 +127,7 @@  struct ath11k_qmi {
 	struct target_info target;
 	struct m3_mem_region m3_mem;
 	unsigned int service_ins_id;
+	wait_queue_head_t cold_boot_waitq;
 };
 
 #define QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN		189