]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
wifi: rtl8xxxu: Fix the TX power of RTL8192CU, RTL8723AU
authorBitterblue Smith <rtl8821cerfe2@gmail.com>
Mon, 15 Apr 2024 20:59:05 +0000 (23:59 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 16 Jun 2024 11:32:32 +0000 (13:32 +0200)
commit 08b5d052d17a89bb8706b2888277d0b682dc1610 upstream.

Don't subtract 1 from the power index. This was added in commit
2fc0b8e5a17d ("rtl8xxxu: Add TX power base values for gen1 parts")
for unknown reasons. The vendor drivers don't do this.

Also correct the calculations of values written to
REG_OFDM0_X{C,D}_TX_IQ_IMBALANCE. According to the vendor driver,
these are used for TX power training.

With these changes rtl8xxxu sets the TX power of RTL8192CU the same
as the vendor driver.

None of this appears to have any effect on my RTL8192CU device.

Cc: stable@vger.kernel.org
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://msgid.link/6ae5945b-644e-45e4-a78f-4c7d9c987910@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c

index 9efc15e69ae82aaa05b9e59b6957d0e9762215ae..5b27c22e7e5816003bd3dae69828b32526de5d0e 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/wireless.h>
 #include <linux/firmware.h>
 #include <linux/moduleparam.h>
+#include <linux/bitfield.h>
 #include <net/mac80211.h>
 #include "rtl8xxxu.h"
 #include "rtl8xxxu_regs.h"
@@ -1389,13 +1390,13 @@ rtl8xxxu_gen1_set_tx_power(struct rtl8xxxu_priv *priv, int channel, bool ht40)
        u8 cck[RTL8723A_MAX_RF_PATHS], ofdm[RTL8723A_MAX_RF_PATHS];
        u8 ofdmbase[RTL8723A_MAX_RF_PATHS], mcsbase[RTL8723A_MAX_RF_PATHS];
        u32 val32, ofdm_a, ofdm_b, mcs_a, mcs_b;
-       u8 val8;
+       u8 val8, base;
        int group, i;
 
        group = rtl8xxxu_gen1_channel_to_group(channel);
 
-       cck[0] = priv->cck_tx_power_index_A[group] - 1;
-       cck[1] = priv->cck_tx_power_index_B[group] - 1;
+       cck[0] = priv->cck_tx_power_index_A[group];
+       cck[1] = priv->cck_tx_power_index_B[group];
 
        if (priv->hi_pa) {
                if (cck[0] > 0x20)
@@ -1406,10 +1407,6 @@ rtl8xxxu_gen1_set_tx_power(struct rtl8xxxu_priv *priv, int channel, bool ht40)
 
        ofdm[0] = priv->ht40_1s_tx_power_index_A[group];
        ofdm[1] = priv->ht40_1s_tx_power_index_B[group];
-       if (ofdm[0])
-               ofdm[0] -= 1;
-       if (ofdm[1])
-               ofdm[1] -= 1;
 
        ofdmbase[0] = ofdm[0] + priv->ofdm_tx_power_index_diff[group].a;
        ofdmbase[1] = ofdm[1] + priv->ofdm_tx_power_index_diff[group].b;
@@ -1498,20 +1495,19 @@ rtl8xxxu_gen1_set_tx_power(struct rtl8xxxu_priv *priv, int channel, bool ht40)
 
        rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS15_MCS12,
                         mcs_a + power_base->reg_0e1c);
+       val8 = u32_get_bits(mcs_a + power_base->reg_0e1c, 0xff000000);
        for (i = 0; i < 3; i++) {
-               if (i != 2)
-                       val8 = (mcsbase[0] > 8) ? (mcsbase[0] - 8) : 0;
-               else
-                       val8 = (mcsbase[0] > 6) ? (mcsbase[0] - 6) : 0;
+               base = i != 2 ? 8 : 6;
+               val8 = max_t(int, val8 - base, 0);
                rtl8xxxu_write8(priv, REG_OFDM0_XC_TX_IQ_IMBALANCE + i, val8);
        }
+
        rtl8xxxu_write32(priv, REG_TX_AGC_B_MCS15_MCS12,
                         mcs_b + power_base->reg_0868);
+       val8 = u32_get_bits(mcs_b + power_base->reg_0868, 0xff000000);
        for (i = 0; i < 3; i++) {
-               if (i != 2)
-                       val8 = (mcsbase[1] > 8) ? (mcsbase[1] - 8) : 0;
-               else
-                       val8 = (mcsbase[1] > 6) ? (mcsbase[1] - 6) : 0;
+               base = i != 2 ? 8 : 6;
+               val8 = max_t(int, val8 - base, 0);
                rtl8xxxu_write8(priv, REG_OFDM0_XD_TX_IQ_IMBALANCE + i, val8);
        }
 }