net: aquantia: fix wol configuration not applied sometimes
authorNikita Danilov <nikita.danilov@aquantia.com>
Tue, 4 Jun 2019 13:23:49 +0000 (13:23 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 11 Jun 2019 10:19:12 +0000 (12:19 +0200)
[ Upstream commit 930b9a0543385d4eb8ef887e88cf84d95a844577 ]

WoL magic packet configuration sometimes does not work due to
couple of leakages found.

Mainly there was a regression introduced during readx_poll refactoring.

Next, fw request waiting time was too small. Sometimes that
caused sleep proxy config function to return with an error
and to skip WoL configuration.
At last, WoL data were passed to FW from not clean buffer.
That could cause FW to accept garbage as a random configuration data.

Fixes: 6a7f2277313b ("net: aquantia: replace AQ_HW_WAIT_FOR with readx_poll_timeout_atomic")
Signed-off-by: Nikita Danilov <nikita.danilov@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c

index eb4b99d56081c776d2369a32609c9f0afcab1631..33d3c3789209748bfda3d762dc2afe7a46b32533 100644 (file)
@@ -335,13 +335,13 @@ static int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 a, u32 *p,
 {
        u32 val;
        int err = 0;
-       bool is_locked;
 
-       is_locked = hw_atl_sem_ram_get(self);
-       if (!is_locked) {
-               err = -ETIME;
+       err = readx_poll_timeout_atomic(hw_atl_sem_ram_get, self,
+                                       val, val == 1U,
+                                       10U, 100000U);
+       if (err < 0)
                goto err_exit;
-       }
+
        if (IS_CHIP_FEATURE(REVISION_B1)) {
                u32 offset = 0;
 
@@ -353,8 +353,8 @@ static int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 a, u32 *p,
                        /* 1000 times by 10us = 10ms */
                        err = readx_poll_timeout_atomic(hw_atl_scrpad12_get,
                                                        self, val,
-                                                       (val & 0xF0000000) ==
-                                                        0x80000000,
+                                                       (val & 0xF0000000) !=
+                                                       0x80000000,
                                                        10U, 10000U);
                }
        } else {
index fe6c5658e016dbcf0470250e04c8345460e988f5..9d0292aa071d2e12f74721e364e6b471bbe30b22 100644 (file)
@@ -349,7 +349,7 @@ static int aq_fw2x_set_sleep_proxy(struct aq_hw_s *self, u8 *mac)
        err = readx_poll_timeout_atomic(aq_fw2x_state2_get,
                                        self, val,
                                        val & HW_ATL_FW2X_CTRL_SLEEP_PROXY,
-                                       1U, 10000U);
+                                       1U, 100000U);
 
 err_exit:
        return err;
@@ -369,6 +369,8 @@ static int aq_fw2x_set_wol_params(struct aq_hw_s *self, u8 *mac)
 
        msg = (struct fw2x_msg_wol *)rpc;
 
+       memset(msg, 0, sizeof(*msg));
+
        msg->msg_id = HAL_ATLANTIC_UTILS_FW2X_MSG_WOL;
        msg->magic_packet_enabled = true;
        memcpy(msg->hw_addr, mac, ETH_ALEN);