diff mbox

[v2,2/2] ath10k: fix CCK h/w rates for QCA99X0 and newer chipsets

Message ID 1464852235-13110-2-git-send-email-mohammed@qca.qualcomm.com (mailing list archive)
State Not Applicable
Delegated to: Kalle Valo
Headers show

Commit Message

Mohammed Shafi Shajakhan June 2, 2016, 7:23 a.m. UTC
From: Mohammed Shafi Shajakhan <mohammed@qti.qualcomm.com>

CCK hardware table mapping from QCA99X0 onwards got revised.
The CCK hardware rate values are in a proper order wrt. to
rate and preamble as below

ATH10K_HW_RATE_REV2_CCK_LP_1M = 1,
ATH10K_HW_RATE_REV2_CCK_LP_2M = 2,
ATH10K_HW_RATE_REV2_CCK_LP_5_5M = 3,
ATH10K_HW_RATE_REV2_CCK_LP_11M = 4,
ATH10K_HW_RATE_REV2_CCK_SP_2M = 5,
ATH10K_HW_RATE_REV2_CCK_SP_5_5M = 6,
ATH10K_HW_RATE_REV2_CCK_SP_11M = 7,

This results in reporting of rx frames (with CCK rates)
totally wrong for QCA99X0, QCA4019. Fix this by having
separate CCK rate table for these chipsets with rev2 suffix
and registering the correct rate mapping to mac80211 based on
the new hw_param (introduced) 'cck_rate_map_rev2' which shall
be true for any newchipsets from QCA99X0 onwards

Signed-off-by: Mohammed Shafi Shajakhan <mohammed@qti.qualcomm.com>
---
[v2: Enabled the fix for QCA9984 - thanks Kalle]

 drivers/net/wireless/ath/ath10k/core.c |    3 +++
 drivers/net/wireless/ath/ath10k/core.h |    6 +++++
 drivers/net/wireless/ath/ath10k/hw.h   |   10 ++++++++
 drivers/net/wireless/ath/ath10k/mac.c  |   39 ++++++++++++++++++++++++++++++--
 4 files changed, 56 insertions(+), 2 deletions(-)

Comments

Sven Eckelmann Feb. 16, 2018, 10:55 a.m. UTC | #1
On Donnerstag, 2. Juni 2016 12:53:55 CET Mohammed Shafi Shajakhan wrote:
> From: Mohammed Shafi Shajakhan <mohammed@qti.qualcomm.com>
> 
> CCK hardware table mapping from QCA99X0 onwards got revised.
> The CCK hardware rate values are in a proper order wrt. to
> rate and preamble as below
> 
> ATH10K_HW_RATE_REV2_CCK_LP_1M = 1,
> ATH10K_HW_RATE_REV2_CCK_LP_2M = 2,
> ATH10K_HW_RATE_REV2_CCK_LP_5_5M = 3,
> ATH10K_HW_RATE_REV2_CCK_LP_11M = 4,
> ATH10K_HW_RATE_REV2_CCK_SP_2M = 5,
> ATH10K_HW_RATE_REV2_CCK_SP_5_5M = 6,
> ATH10K_HW_RATE_REV2_CCK_SP_11M = 7,
> 
> This results in reporting of rx frames (with CCK rates)
> totally wrong for QCA99X0, QCA4019. Fix this by having
> separate CCK rate table for these chipsets with rev2 suffix
> and registering the correct rate mapping to mac80211 based on
> the new hw_param (introduced) 'cck_rate_map_rev2' which shall
> be true for any newchipsets from QCA99X0 onwards

I just tested it here with QCA4019 + 10.4-3.2.1-00050 for beacons. The 
calculated HW code for 1.0 MBit/s would be 0x41 (rate_code) according to this 
new mapping. But when I set it with 

    	ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
    					ar->wmi.vdev_param->mcast_data_rate,
    					rate_code);

then it sends beacons with 5.5Mbit/s and not with 1.0Mbit/s.

Btw. the rate_code was calculated using:

    		if (ath10k_mac_bitrate_is_cck(sband->bitrates[i].bitrate))
    			preamble = WMI_RATE_PREAMBLE_CCK;
    		else
    			preamble = WMI_RATE_PREAMBLE_OFDM;
    
    		rate_code = ATH10K_HW_RATECODE(hw_value, 0, preamble);

It works fine when using the old mapping (0x43).

This made me rather curious and I've connected a client to the AP which was 
only able to send at 1.0 Mbit/s - this actually resulted in the correctly 
reported rates at in the rx field.

Does this mean that the rates are now inconsistent because the QCA fw doesn't 
provide a consistent interface for hw rates or did I miss anything?

Kind regards,
	Sven
diff mbox

Patch

diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index a003980..2692243 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -148,6 +148,7 @@  static const struct ath10k_hw_params ath10k_hw_params_list[] = {
 		.uart_pin = 7,
 		.otp_exe_param = 0x00000700,
 		.continuous_frag_desc = true,
+		.cck_rate_map_rev2 = true,
 		.channel_counters_freq_hz = 150000,
 		.max_probe_resp_desc_thres = 24,
 		.hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE,
@@ -170,6 +171,7 @@  static const struct ath10k_hw_params ath10k_hw_params_list[] = {
 		.uart_pin = 7,
 		.otp_exe_param = 0x00000700,
 		.continuous_frag_desc = true,
+		.cck_rate_map_rev2 = true,
 		.channel_counters_freq_hz = 150000,
 		.max_probe_resp_desc_thres = 24,
 		.hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE,
@@ -227,6 +229,7 @@  static const struct ath10k_hw_params ath10k_hw_params_list[] = {
 		.has_shifted_cc_wraparound = true,
 		.otp_exe_param = 0x0010000,
 		.continuous_frag_desc = true,
+		.cck_rate_map_rev2 = true,
 		.channel_counters_freq_hz = 125000,
 		.max_probe_resp_desc_thres = 24,
 		.hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE,
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 1852e0e..04cea23 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -716,6 +716,12 @@  struct ath10k {
 		 */
 		bool continuous_frag_desc;
 
+		/* CCK hardware rate table mapping for the newer chipsets
+		 * like QCA99X0, QCA4019 got revised. The CCK h/w rate values
+		 * are in a proper order with respect to the rate/preamble
+		 */
+		bool cck_rate_map_rev2;
+
 		u32 channel_counters_freq_hz;
 
 		/* Mgmt tx descriptors threshold for limiting probe response
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index f41c91c..4ed5be9 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -326,6 +326,16 @@  enum ath10k_hw_rate_cck {
 	ATH10K_HW_RATE_CCK_SP_2M,
 };
 
+enum ath10k_hw_rate_rev2_cck {
+	ATH10K_HW_RATE_REV2_CCK_LP_1M = 1,
+	ATH10K_HW_RATE_REV2_CCK_LP_2M,
+	ATH10K_HW_RATE_REV2_CCK_LP_5_5M,
+	ATH10K_HW_RATE_REV2_CCK_LP_11M,
+	ATH10K_HW_RATE_REV2_CCK_SP_2M,
+	ATH10K_HW_RATE_REV2_CCK_SP_5_5M,
+	ATH10K_HW_RATE_REV2_CCK_SP_11M,
+};
+
 enum ath10k_hw_4addr_pad {
 	ATH10K_HW_4ADDR_PAD_AFTER,
 	ATH10K_HW_4ADDR_PAD_BEFORE,
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 1dd415d..e7162db 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -62,6 +62,32 @@  static struct ieee80211_rate ath10k_rates[] = {
 	{ .bitrate = 540, .hw_value = ATH10K_HW_RATE_OFDM_54M },
 };
 
+static struct ieee80211_rate ath10k_rates_rev2[] = {
+	{ .bitrate = 10,
+	  .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_1M },
+	{ .bitrate = 20,
+	  .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_2M,
+	  .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_2M,
+	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+	{ .bitrate = 55,
+	  .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_5_5M,
+	  .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_5_5M,
+	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+	{ .bitrate = 110,
+	  .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_11M,
+	  .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_11M,
+	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+
+	{ .bitrate = 60, .hw_value = ATH10K_HW_RATE_OFDM_6M },
+	{ .bitrate = 90, .hw_value = ATH10K_HW_RATE_OFDM_9M },
+	{ .bitrate = 120, .hw_value = ATH10K_HW_RATE_OFDM_12M },
+	{ .bitrate = 180, .hw_value = ATH10K_HW_RATE_OFDM_18M },
+	{ .bitrate = 240, .hw_value = ATH10K_HW_RATE_OFDM_24M },
+	{ .bitrate = 360, .hw_value = ATH10K_HW_RATE_OFDM_36M },
+	{ .bitrate = 480, .hw_value = ATH10K_HW_RATE_OFDM_48M },
+	{ .bitrate = 540, .hw_value = ATH10K_HW_RATE_OFDM_54M },
+};
+
 #define ATH10K_MAC_FIRST_OFDM_RATE_IDX 4
 
 #define ath10k_a_rates (ath10k_rates + ATH10K_MAC_FIRST_OFDM_RATE_IDX)
@@ -70,6 +96,9 @@  static struct ieee80211_rate ath10k_rates[] = {
 #define ath10k_g_rates (ath10k_rates + 0)
 #define ath10k_g_rates_size (ARRAY_SIZE(ath10k_rates))
 
+#define ath10k_g_rates_rev2 (ath10k_rates_rev2 + 0)
+#define ath10k_g_rates_rev2_size (ARRAY_SIZE(ath10k_rates_rev2))
+
 static bool ath10k_mac_bitrate_is_cck(int bitrate)
 {
 	switch (bitrate) {
@@ -7696,8 +7725,14 @@  int ath10k_mac_register(struct ath10k *ar)
 		band = &ar->mac.sbands[NL80211_BAND_2GHZ];
 		band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
 		band->channels = channels;
-		band->n_bitrates = ath10k_g_rates_size;
-		band->bitrates = ath10k_g_rates;
+
+		if (ar->hw_params.cck_rate_map_rev2) {
+			band->n_bitrates = ath10k_g_rates_rev2_size;
+			band->bitrates = ath10k_g_rates_rev2;
+		} else {
+			band->n_bitrates = ath10k_g_rates_size;
+			band->bitrates = ath10k_g_rates;
+		}
 
 		ar->hw->wiphy->bands[NL80211_BAND_2GHZ] = band;
 	}