Subject: [PATCH 1/2] ath10k: Define an enum to enable cycle counter wraparound logic

QCA988X hw implements a different cycle counter wraparound
behaviour when compared to QCA4019. To properly handle different
wraparound logic for these chipsets replace already available
bool hw_params member, has_shifted_cc_wraparound, with an
enum which could be extended to handle different wraparound
behaviour. This patch keeps the existing logic functionally
same and a prepares cycle counter wraparound handling to
extend for other chips.

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.c | 4 ++--
drivers/net/wireless/ath/ath10k/core.h | 8 +++-----
drivers/net/wireless/ath/ath10k/hw.c | 4 +++-
drivers/net/wireless/ath/ath10k/hw.h | 11 +++++++++++
4 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index cedf127..8f66653 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -55,7 +55,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.name = "qca988x hw2.0",
.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
.uart_pin = 7,
- .has_shifted_cc_wraparound = true,
+ .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
.otp_exe_param = 0,
.channel_counters_freq_hz = 88000,
.max_probe_resp_desc_thres = 0,
@@ -224,7 +224,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.name = "qca4019 hw1.0",
.patch_load_addr = QCA4019_HW_1_0_PATCH_LOAD_ADDR,
.uart_pin = 7,
- .has_shifted_cc_wraparound = true,
+ .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
.otp_exe_param = 0x0010000,
.continuous_frag_desc = true,
.channel_counters_freq_hz = 125000,
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 4462c3f..b42b21f 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -710,12 +710,10 @@ struct ath10k {
int uart_pin;
u32 otp_exe_param;

- /* This is true if given HW chip has a quirky Cycle Counter
- * wraparound which resets to 0x7fffffff instead of 0. All
- * other CC related counters (e.g. Rx Clear Count) are divided
- * by 2 so they never wraparound themselves.
+ /* Type of hw cycle counter wraparound logic, for more info
+ * refer enum ath10k_hw_cc_wraparound_type.
*/
- bool has_shifted_cc_wraparound;
+ enum ath10k_hw_cc_wraparound_type cc_wraparound_type;

/* Some of chip expects fragment descriptor to be continuous
* memory for any TX operation. Set continuous_frag_desc flag
diff --git a/drivers/net/wireless/ath/ath10k/hw.c b/drivers/net/wireless/ath/ath10k/hw.c
index f544d48..31ec164 100644
--- a/drivers/net/wireless/ath/ath10k/hw.c
+++ b/drivers/net/wireless/ath/ath10k/hw.c
@@ -179,11 +179,13 @@ void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
u32 cc, u32 rcc, u32 cc_prev, u32 rcc_prev)
{
u32 cc_fix = 0;
+ enum ath10k_hw_cc_wraparound_type wraparound_type;

survey->filled |= SURVEY_INFO_TIME |
SURVEY_INFO_TIME_BUSY;

- if (ar->hw_params.has_shifted_cc_wraparound && cc < cc_prev) {
+ wraparound_type = ar->hw_params.cc_wraparound_type;
+ if (wraparound_type == ATH10K_HW_CC_WRAP_SHIFTED_ALL && cc < cc_prev) {
cc_fix = 0x7fffffff;
survey->filled &= ~SURVEY_INFO_TIME_BUSY;
}
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index f41c91c..64e45b2 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -331,6 +331,17 @@ enum ath10k_hw_4addr_pad {
ATH10K_HW_4ADDR_PAD_BEFORE,
};

+enum ath10k_hw_cc_wraparound_type {
+ ATH10K_HW_CC_WRAP_DISABLED = 0,
+
+ /* This type is when the HW chip has a quirky Cycle Counter
+ * wraparound which resets to 0x7fffffff instead of 0. All
+ * other CC related counters (e.g. Rx Clear Count) are divided
+ * by 2 so they never wraparound themselves.
+ */
+ ATH10K_HW_CC_WRAP_SHIFTED_ALL = 1,
+};
+
/* Target specific defines for MAIN firmware */
#define TARGET_NUM_VDEVS 8
#define TARGET_NUM_PEER_AST 2
--
1.9.1



Subject: Re: [PATCH 1/2] ath10k: Define an enum to enable cycle counter wraparound logic

>> --- a/drivers/net/wireless/ath/ath10k/core.c
>> +++ b/drivers/net/wireless/ath/ath10k/core.c
>> @@ -55,7 +55,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
>> .name = "qca988x hw2.0",
>> .patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
>> .uart_pin = 7,
>> - .has_shifted_cc_wraparound = true,
>> + .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
>> .otp_exe_param = 0,
>> .channel_counters_freq_hz = 88000,
>> .max_probe_resp_desc_thres = 0,
>> @@ -224,7 +224,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
>> .name = "qca4019 hw1.0",
>> .patch_load_addr = QCA4019_HW_1_0_PATCH_LOAD_ADDR,
>> .uart_pin = 7,
>> - .has_shifted_cc_wraparound = true,
>> + .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
>> .otp_exe_param = 0x0010000,
>> .continuous_frag_desc = true,
>> .channel_counters_freq_hz = 125000,
>
> As the pending branch has the QCA9887 patch I added
> ATH10K_HW_CC_WRAP_SHIFTED_ALL also for QCA9887. Please review my changes
> in the pending branch:
>
> https://git.kernel.org/cgit/linux/kernel/git/kvalo/ath.git/commit/?h=pending&id=2fa32dbd9f26e8b2f323ca30ad116ea486840aba
>

Looks good, thanks.

Vasanth

Subject: [PATCH 2/2] ath10k: Fix cycle counter wraparound handling for QCA4019

In QCA4019, cycle counter wraparound is not tied to rx
clear counter. Each counter would wraparound individually
and after wraparound the respective counter will be reset
to 0x7fffffff while other counter still running unaffected.
Define a new wraparound type for this behaviour and handle
it separately so that rx clear counter wraparound is also
handled just like cycle counter. With this type of
wraparound we can accurately compute and report channel
active/busy time when any of the counter overflows.

Fixes: ee9ca147c59 ("ath10k: Fix survey reporting with QCA4019")
Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.c | 2 +-
drivers/net/wireless/ath/ath10k/hw.c | 24 ++++++++++++++++++++----
drivers/net/wireless/ath/ath10k/hw.h | 9 +++++++++
3 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 8f66653..5ede9a4 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -224,7 +224,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.name = "qca4019 hw1.0",
.patch_load_addr = QCA4019_HW_1_0_PATCH_LOAD_ADDR,
.uart_pin = 7,
- .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
+ .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
.otp_exe_param = 0x0010000,
.continuous_frag_desc = true,
.channel_counters_freq_hz = 125000,
diff --git a/drivers/net/wireless/ath/ath10k/hw.c b/drivers/net/wireless/ath/ath10k/hw.c
index 31ec164..bd86e7a 100644
--- a/drivers/net/wireless/ath/ath10k/hw.c
+++ b/drivers/net/wireless/ath/ath10k/hw.c
@@ -179,19 +179,35 @@ void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
u32 cc, u32 rcc, u32 cc_prev, u32 rcc_prev)
{
u32 cc_fix = 0;
+ u32 rcc_fix = 0;
enum ath10k_hw_cc_wraparound_type wraparound_type;

survey->filled |= SURVEY_INFO_TIME |
SURVEY_INFO_TIME_BUSY;

wraparound_type = ar->hw_params.cc_wraparound_type;
- if (wraparound_type == ATH10K_HW_CC_WRAP_SHIFTED_ALL && cc < cc_prev) {
- cc_fix = 0x7fffffff;
- survey->filled &= ~SURVEY_INFO_TIME_BUSY;
+
+ if (cc < cc_prev || rcc < rcc_prev) {
+ switch (wraparound_type) {
+ case ATH10K_HW_CC_WRAP_SHIFTED_ALL:
+ if (cc < cc_prev) {
+ cc_fix = 0x7fffffff;
+ survey->filled &= ~SURVEY_INFO_TIME_BUSY;
+ }
+ break;
+ case ATH10K_HW_CC_WRAP_SHIFTED_EACH:
+ if (cc < cc_prev)
+ cc_fix = 0x7fffffff;
+ else
+ rcc_fix = 0x7fffffff;
+ break;
+ case ATH10K_HW_CC_WRAP_DISABLED:
+ break;
+ }
}

cc -= cc_prev - cc_fix;
- rcc -= rcc_prev;
+ rcc -= rcc_prev - rcc_fix;

survey->time = CCNT_TO_MSEC(ar, cc);
survey->time_busy = CCNT_TO_MSEC(ar, rcc);
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index 64e45b2..7657c60 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -340,6 +340,15 @@ enum ath10k_hw_cc_wraparound_type {
* by 2 so they never wraparound themselves.
*/
ATH10K_HW_CC_WRAP_SHIFTED_ALL = 1,
+
+ /* Each hw counter wrapsaround independently. When the
+ * counter overflows the repestive counter is right shifted
+ * by 1, i.e reset to 0x7fffffff, and other counters will be
+ * running unaffected. In this type of wraparound, it should
+ * be possible to report accurate Rx busy time unlike the
+ * first type.
+ */
+ ATH10K_HW_CC_WRAP_SHIFTED_EACH = 2,
};

/* Target specific defines for MAIN firmware */
--
1.9.1


2016-06-14 11:59:33

by Kalle Valo

[permalink] [raw]
Subject: Re: [1/2] ath10k: Define an enum to enable cycle counter wraparound logic

Vasanthakumar Thiagarajan <[email protected]> wrote:
> QCA988X hw implements a different cycle counter wraparound
> behaviour when compared to QCA4019. To properly handle different
> wraparound logic for these chipsets replace already available
> bool hw_params member, has_shifted_cc_wraparound, with an
> enum which could be extended to handle different wraparound
> behaviour. This patch keeps the existing logic functionally
> same and a prepares cycle counter wraparound handling to
> extend for other chips.
>
> Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>

Thanks, 2 patches applied to ath-next branch of ath.git:

26c197600b43 ath10k: define an enum to enable cycle counter wraparound logic
8e100354a985 ath10k: fix cycle counter wraparound handling for QCA4019

--
Sent by pwcli
https://patchwork.kernel.org/patch/9153403/


2016-06-04 14:54:07

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 1/2] ath10k: Define an enum to enable cycle counter wraparound logic

Vasanthakumar Thiagarajan <[email protected]> writes:

> QCA988X hw implements a different cycle counter wraparound
> behaviour when compared to QCA4019. To properly handle different
> wraparound logic for these chipsets replace already available
> bool hw_params member, has_shifted_cc_wraparound, with an
> enum which could be extended to handle different wraparound
> behaviour. This patch keeps the existing logic functionally
> same and a prepares cycle counter wraparound handling to
> extend for other chips.
>
> Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>

[...]

> --- a/drivers/net/wireless/ath/ath10k/core.c
> +++ b/drivers/net/wireless/ath/ath10k/core.c
> @@ -55,7 +55,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
> .name = "qca988x hw2.0",
> .patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
> .uart_pin = 7,
> - .has_shifted_cc_wraparound = true,
> + .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
> .otp_exe_param = 0,
> .channel_counters_freq_hz = 88000,
> .max_probe_resp_desc_thres = 0,
> @@ -224,7 +224,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
> .name = "qca4019 hw1.0",
> .patch_load_addr = QCA4019_HW_1_0_PATCH_LOAD_ADDR,
> .uart_pin = 7,
> - .has_shifted_cc_wraparound = true,
> + .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
> .otp_exe_param = 0x0010000,
> .continuous_frag_desc = true,
> .channel_counters_freq_hz = 125000,

As the pending branch has the QCA9887 patch I added
ATH10K_HW_CC_WRAP_SHIFTED_ALL also for QCA9887. Please review my changes
in the pending branch:

https://git.kernel.org/cgit/linux/kernel/git/kvalo/ath.git/commit/?h=pending&id=2fa32dbd9f26e8b2f323ca30ad116ea486840aba

--
Kalle Valo