On Fri, Aug 16, 2019 at 11:00:12AM +0300, Emil Karlson wrote:
> Greetings
> 
> On Wed, 14 Aug 2019 10:50:19 +0200
> Stanislaw Gruszka <sgrus...@redhat.com> wrote:
> 
> > (cc linux-wireless mailing list)
> > 
> > On Tue, Aug 13, 2019 at 09:50:00PM +0300, Emil Karlson wrote:
> > > Greetings
> > > 
> > > After upgrading my ap running rt2800usb to linux-5.3-rc1 I noticed
> > > an unusual problem of not being able to connect to my ap with my
> > > android devices (nexus7/flo and nexus5x/bullhead), from tcpdump it
> > > seemed ap was receiving packets from the android devices after
> > > successful association, but android devices were not seeing the
> > > dhcp replies.
> > > 
> > > I reverted drivers/net/wireless/ralink to the state it is in v5.2.8
> > > and android clients can connect again normally. I did not
> > > explicitly set watchdog parameter to any value.
> 
> > Most suspicious are 710e6cc1595e and 41a531ffa4c5 .
> 
> It seems to me that reverting only
> 710e6cc1595e25378c4b9977f7a8b4ad4a72a109
> allows all my android devices to successfully connect to the internet.

Please test attached patch as proposed fix for
710e6cc1595e25378c4b9977f7a8b4ad4a72a109 and report back. Thanks.

Stanislaw
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c 
b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index 4a996550288e..cbec2131e943 100644
--- 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 rt2x00_dev 
*rt2x00dev)
        }
 
        /*
+        * 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++)
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00.h 
b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
index d35ef06c5c7a..1dd54a0d083d 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
@@ -659,6 +659,7 @@ enum rt2x00_state_flags {
        DEVICE_STATE_ENABLED_RADIO,
        DEVICE_STATE_SCANNING,
        DEVICE_STATE_FLUSHING,
+       DEVICE_STATE_RESET,
 
        /*
         * Driver configuration
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c 
b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
index ad063c920323..c3eab767bc21 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
@@ -1253,13 +1253,14 @@ static int rt2x00lib_initialize(struct rt2x00_dev 
*rt2x00dev)
 
 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);
        }
@@ -1270,14 +1271,14 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev)
         */
        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;
@@ -1286,11 +1287,13 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev)
        /* 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)

Reply via email to