mac80211: rt2x00: clear IV's on start to fix AP mode regression
authorDaniel Golle <daniel@makrotopia.org>
Mon, 19 Aug 2019 11:40:51 +0000 (13:40 +0200)
committerDaniel Golle <daniel@makrotopia.org>
Mon, 19 Aug 2019 11:46:00 +0000 (13:46 +0200)
To do not brake HW restart we should keep initialization vectors data.
I assumed that on start the data is already initialized to zeros, but
that not true on some scenarios and we should clear it. So add
additional flag to check if we are under HW restart and clear IV's
data if we are not.

Patch fixes AP mode regression.

Patch pending on linux-wireless and imported from patchwork.

Fixes: 0b2c42ced21a ("mac80211: Update to version 5.2-rc7")
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
package/kernel/mac80211/patches/rt2x00/010-rt2x00-clear-IV-s-on-start-to-fix-AP-mode-regression.patch [new file with mode: 0644]
package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch
package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch
package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch
package/kernel/mac80211/patches/rt2x00/650-rt2x00-add-support-for-external-PA-on-MT7620.patch
package/kernel/mac80211/patches/rt2x00/982-rt2x00-add-rf-self-txdc-calibration.patch
package/kernel/mac80211/patches/rt2x00/983-rt2x00-add-r-calibration.patch
package/kernel/mac80211/patches/rt2x00/984-rt2x00-add-rxdcoc-calibration.patch
package/kernel/mac80211/patches/rt2x00/985-rt2x00-add-rxiq-calibration.patch
package/kernel/mac80211/patches/rt2x00/986-rt2x00-add-TX-LOFT-calibration.patch

diff --git a/package/kernel/mac80211/patches/rt2x00/010-rt2x00-clear-IV-s-on-start-to-fix-AP-mode-regression.patch b/package/kernel/mac80211/patches/rt2x00/010-rt2x00-clear-IV-s-on-start-to-fix-AP-mode-regression.patch
new file mode 100644 (file)
index 0000000..8859c0d
--- /dev/null
@@ -0,0 +1,113 @@
+From patchwork Mon Aug 19 11:20:07 2019
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Stanislaw Gruszka <sgruszka@redhat.com>
+X-Patchwork-Id: 11100685
+X-Patchwork-Delegate: kvalo@adurom.com
+Return-Path: <linux-wireless-owner@kernel.org>
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+To: linux-wireless@vger.kernel.org
+Subject: [PATCH 5.3] rt2x00: clear IV's on start to fix AP mode regression
+Date: Mon, 19 Aug 2019 13:20:07 +0200
+Message-Id: <1566213607-6723-1-git-send-email-sgruszka@redhat.com>
+Sender: linux-wireless-owner@vger.kernel.org
+List-ID: <linux-wireless.vger.kernel.org>
+X-Mailing-List: linux-wireless@vger.kernel.org
+
+To do not brake HW restart we should keep initialization vectors data.
+I assumed that on start the data is already initialized to zeros, but
+that not true on some scenarios and we should clear it. So add
+additional flag to check if we are under HW restart and clear IV's
+data if we are not.
+
+Patch fixes AP mode regression.
+
+Reported-and-tested-by: Emil Karlson <jekarl@iki.fi>
+Fixes: 710e6cc1595e ("rt2800: do not nullify initialization vector data")
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.c |  9 +++++++++
+ drivers/net/wireless/ralink/rt2x00/rt2x00.h    |  1 +
+ drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 13 ++++++++-----
+ 3 files changed, 18 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -6095,6 +6095,15 @@ static int rt2800_init_registers(struct
+       }
+       /*
++       * Clear encryption initialization vectors on start, but keep them
++       * for watchdog reset. Otherwise we will have wrong IVs and not be
++       * able to keep connections after reset.
++       */
++      if (!test_bit(DEVICE_STATE_RESET, &rt2x00dev->flags))
++              for (i = 0; i < 256; i++)
++                      rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0);
++
++      /*
+        * Clear all beacons
+        */
+       for (i = 0; i < 8; i++)
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+@@ -658,6 +658,7 @@ enum rt2x00_state_flags {
+       DEVICE_STATE_ENABLED_RADIO,
+       DEVICE_STATE_SCANNING,
+       DEVICE_STATE_FLUSHING,
++      DEVICE_STATE_RESET,
+       /*
+        * Driver configuration
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+@@ -1256,13 +1256,14 @@ static int rt2x00lib_initialize(struct r
+ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev)
+ {
+-      int retval;
++      int retval = 0;
+       if (test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags)) {
+               /*
+                * This is special case for ieee80211_restart_hw(), otherwise
+                * mac80211 never call start() two times in row without stop();
+                */
++              set_bit(DEVICE_STATE_RESET, &rt2x00dev->flags);
+               rt2x00dev->ops->lib->pre_reset_hw(rt2x00dev);
+               rt2x00lib_stop(rt2x00dev);
+       }
+@@ -1273,14 +1274,14 @@ int rt2x00lib_start(struct rt2x00_dev *r
+        */
+       retval = rt2x00lib_load_firmware(rt2x00dev);
+       if (retval)
+-              return retval;
++              goto out;
+       /*
+        * Initialize the device.
+        */
+       retval = rt2x00lib_initialize(rt2x00dev);
+       if (retval)
+-              return retval;
++              goto out;
+       rt2x00dev->intf_ap_count = 0;
+       rt2x00dev->intf_sta_count = 0;
+@@ -1289,11 +1290,13 @@ int rt2x00lib_start(struct rt2x00_dev *r
+       /* Enable the radio */
+       retval = rt2x00lib_enable_radio(rt2x00dev);
+       if (retval)
+-              return retval;
++              goto out;
+       set_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags);
+-      return 0;
++out:
++      clear_bit(DEVICE_STATE_RESET, &rt2x00dev->flags);
++      return retval;
+ }
+ void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev)
index 0c6e5a03b02d6841dcb6ffdfe8b801feb2c6a306..964c243f9197661fe5690a10514cbf64683c6460 100644 (file)
        .drv_init_registers     = rt2800mmio_init_registers,
 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
 +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
-@@ -694,6 +694,7 @@ enum rt2x00_capability_flags {
+@@ -695,6 +695,7 @@ enum rt2x00_capability_flags {
        REQUIRE_HT_TX_DESC,
        REQUIRE_PS_AUTOWAKE,
        REQUIRE_DELAYED_RFKILL,
  
        /*
         * Capabilities
-@@ -970,6 +971,11 @@ struct rt2x00_dev {
+@@ -971,6 +972,11 @@ struct rt2x00_dev {
        const struct firmware *fw;
  
        /*
        DECLARE_KFIFO_PTR(txstatus_fifo, u32);
 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
 +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-@@ -1418,6 +1418,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
+@@ -1421,6 +1421,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
        INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup);
        INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep);
  
        /*
         * Let the driver probe the device to detect the capabilities.
         */
-@@ -1561,6 +1565,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
+@@ -1564,6 +1568,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
         * Free the driver data.
         */
        kfree(rt2x00dev->drv_data);
index ed2f6173b52a347d81497abc7e24799c0b76f373..76a2d1c2caddc0a93ba68de7471168299501078c 100644 (file)
@@ -8,7 +8,7 @@
  
  #include "rt2x00.h"
  #include "rt2800lib.h"
-@@ -9526,6 +9527,17 @@ static int rt2800_init_eeprom(struct rt2
+@@ -9535,6 +9536,17 @@ static int rt2800_init_eeprom(struct rt2
        rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
        rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY);
  
index d909a2e6c62ff6da833f4240ff22a0bc78ca56e4..aa2b25ba7f5da5a539978ff3770e4ac4444fdaa7 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
 +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-@@ -1356,7 +1356,7 @@ static inline void rt2x00lib_set_if_comb
+@@ -1359,7 +1359,7 @@ static inline void rt2x00lib_set_if_comb
         */
        if_limit = &rt2x00dev->if_limits_ap;
        if_limit->max = rt2x00dev->ops->max_ap_intf;
index 3f03a68f591fdb66636694973eb00e4dba8ccc26..2d733a3180dcc8a1457e0f1f39a0e1e5200dde66 100644 (file)
@@ -76,7 +76,7 @@ Signed-off-by: Tomislav Po=C5=BEega <pozega.tomislav@gmail.com>
        bbp = rt2800_bbp_read(rt2x00dev, 4);
        rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf));
        rt2800_bbp_write(rt2x00dev, 4, bbp);
-@@ -9555,7 +9594,8 @@ static int rt2800_init_eeprom(struct rt2
+@@ -9564,7 +9603,8 @@ static int rt2800_init_eeprom(struct rt2
         */
        eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1);
  
@@ -86,7 +86,7 @@ Signed-off-by: Tomislav Po=C5=BEega <pozega.tomislav@gmail.com>
                if (rt2x00_get_field16(eeprom,
                    EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352))
                    __set_bit(CAPABILITY_EXTERNAL_PA_TX0,
-@@ -9566,6 +9606,18 @@ static int rt2800_init_eeprom(struct rt2
+@@ -9575,6 +9615,18 @@ static int rt2800_init_eeprom(struct rt2
                              &rt2x00dev->cap_flags);
        }
  
index 73413217b7557dc5fd34a791cdb27134cebf8f68..e8e28eac0552b93f52351205170b0e5591c36afb 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -8417,6 +8417,58 @@ static void rt2800_init_rfcsr_5592(struc
+@@ -8426,6 +8426,58 @@ static void rt2800_init_rfcsr_5592(struc
        rt2800_led_open_drain_enable(rt2x00dev);
  }
  
@@ -59,7 +59,7 @@
  static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
                                       bool set_bw, bool is_ht40)
  {
-@@ -9024,6 +9076,7 @@ static void rt2800_init_rfcsr_6352(struc
+@@ -9033,6 +9085,7 @@ static void rt2800_init_rfcsr_6352(struc
        rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
        rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
  
index 23dde9b07c27f2efa81cc4bba423aa5f83c74814..da4d9a39e3626a4df8fadec5d244092df73d1599 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -8469,6 +8469,160 @@ void rt2800_rf_self_txdc_cal(struct rt2x
+@@ -8478,6 +8478,160 @@ void rt2800_rf_self_txdc_cal(struct rt2x
  }
  EXPORT_SYMBOL_GPL(rt2800_rf_self_txdc_cal);
  
  static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
                                       bool set_bw, bool is_ht40)
  {
-@@ -9076,6 +9230,7 @@ static void rt2800_init_rfcsr_6352(struc
+@@ -9085,6 +9239,7 @@ static void rt2800_init_rfcsr_6352(struc
        rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
        rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
  
index 3a638f82e3b01836c61baa19e5af8d4854b31eb8..1dd4746be95fa1054acf0a16c0e2c8a50c98a425 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -8623,6 +8623,71 @@ void rt2800_r_calibration(struct rt2x00_
+@@ -8632,6 +8632,71 @@ void rt2800_r_calibration(struct rt2x00_
  }
  EXPORT_SYMBOL_GPL(rt2800_r_calibration);
  
@@ -72,7 +72,7 @@
  static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
                                       bool set_bw, bool is_ht40)
  {
-@@ -9232,6 +9297,7 @@ static void rt2800_init_rfcsr_6352(struc
+@@ -9241,6 +9306,7 @@ static void rt2800_init_rfcsr_6352(struc
  
        rt2800_r_calibration(rt2x00dev);
        rt2800_rf_self_txdc_cal(rt2x00dev);
index 5bd53b7a21902130d43597ff37d853afd2dbd032..e820d1c264680c94829dac8b3a74ef02883fd1ab 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -8688,6 +8688,386 @@ void rt2800_rxdcoc_calibration(struct rt
+@@ -8697,6 +8697,386 @@ void rt2800_rxdcoc_calibration(struct rt
  }
  EXPORT_SYMBOL_GPL(rt2800_rxdcoc_calibration);
  
  static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
                                       bool set_bw, bool is_ht40)
  {
-@@ -9300,6 +9680,7 @@ static void rt2800_init_rfcsr_6352(struc
+@@ -9309,6 +9689,7 @@ static void rt2800_init_rfcsr_6352(struc
        rt2800_rxdcoc_calibration(rt2x00dev);
        rt2800_bw_filter_calibration(rt2x00dev, true);
        rt2800_bw_filter_calibration(rt2x00dev, false);
index 464db9c9213578ddcacb805347ac7eebba1cabd7..7048a84dbc71ac26c583e90482a6920ace1f0f5d 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
 +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -9068,6 +9068,954 @@ restore_value:
+@@ -9077,6 +9077,954 @@ restore_value:
  }
  EXPORT_SYMBOL_GPL(rt2800_rxiq_calibration);
  
  static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
                                       bool set_bw, bool is_ht40)
  {
-@@ -9680,6 +10628,7 @@ static void rt2800_init_rfcsr_6352(struc
+@@ -9689,6 +10637,7 @@ static void rt2800_init_rfcsr_6352(struc
        rt2800_rxdcoc_calibration(rt2x00dev);
        rt2800_bw_filter_calibration(rt2x00dev, true);
        rt2800_bw_filter_calibration(rt2x00dev, false);