ath10k: fix CCK h/w rates for QCA99X0 and newer chipsets
authorMohammed Shafi Shajakhan <mohammed@qti.qualcomm.com>
Tue, 7 Jun 2016 12:47:04 +0000 (15:47 +0300)
committerKalle Valo <kvalo@qca.qualcomm.com>
Tue, 14 Jun 2016 11:56:04 +0000 (14:56 +0300)
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>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/ath10k/core.c
drivers/net/wireless/ath/ath10k/core.h
drivers/net/wireless/ath/ath10k/hw.h
drivers/net/wireless/ath/ath10k/mac.c

index 1e88251ca6d074710b934ba57778c8d7be999eb5..2679d00a20e6416dbdac9e78c643da9a60386b67 100644 (file)
@@ -168,6 +168,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,
@@ -190,6 +191,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,
@@ -247,6 +249,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,
index 338773393d738c0ea8d283cc2a3ee358980d39f8..bbc4e0f444f0f176fef60c605ae7a77f5531de9e 100644 (file)
@@ -726,6 +726,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
index 49097af3d12fc6a1b08d8b3f815673808caf7b72..3dbe4975faa2f92730eeaedc1398750df6f06321 100644 (file)
@@ -336,6 +336,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,
index 84a3e4902720900c6eb7bbf7749571202e686d45..3a170b1bf99bcb38960a818880cecc9c0d620cf4 100644 (file)
@@ -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) {
@@ -7709,8 +7738,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;
        }