From patchwork Wed Mar 4 02:12:11 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Ryazanov X-Patchwork-Id: 5927891 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 211E6BF6C3 for ; Wed, 4 Mar 2015 02:12:26 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 24CA12043C for ; Wed, 4 Mar 2015 02:12:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2E00E2044C for ; Wed, 4 Mar 2015 02:12:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756029AbbCDCMW (ORCPT ); Tue, 3 Mar 2015 21:12:22 -0500 Received: from mail-la0-f46.google.com ([209.85.215.46]:45662 "EHLO mail-la0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754869AbbCDCMV (ORCPT ); Tue, 3 Mar 2015 21:12:21 -0500 Received: by labge10 with SMTP id ge10so41483182lab.12 for ; Tue, 03 Mar 2015 18:12:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=+WCsw4zv+6N/mtKWHb9PA2GkDvukZ8NL8GKC3stBOq8=; b=zRCo/eOyhwuFXthRGDYrbR7R2VIwfChJH7TfCndYfdi9dTawglSK1s5+eZvAsM3qlI CeLcAbiqS+JeruT/+5nouURrSi/U0Hh02rt678FH5d6VfE/O+r8IPQIs17sWugNEF5a3 odOvA+ZVTKzfjIdXN2LN6yYlx+LGAkb17y3tn03jtYR/RC0hW6bl2vQKO3jAPOPXvg69 6rO0X8Pq1yw30l6MMlnznskO33vdP2XROi2XhwujYpN/POIamDO/e38plR5ufyWjcgo9 jJfFFsryhw7SSPqhLpFHJzLtxKs2j+Cvm3VT3wbdyt/2ppnxGefHaoxB00Svrd6UNezb zazA== X-Received: by 10.152.4.39 with SMTP id h7mr1536004lah.58.1425435139747; Tue, 03 Mar 2015 18:12:19 -0800 (PST) Received: from rsa-laptop.internal.lan ([217.25.229.52]) by mx.google.com with ESMTPSA id w9sm481491lae.35.2015.03.03.18.12.17 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 03 Mar 2015 18:12:18 -0800 (PST) From: Sergey Ryazanov To: linux-wireless@vger.kernel.org Cc: Jiri Slaby , Nick Kossifidis , "Luis R. Rodriguez" Subject: [PATCH 2/2] ath5k: fix reset race Date: Wed, 4 Mar 2015 05:12:11 +0300 Message-Id: <1425435131-12701-3-git-send-email-ryazanov.s.a@gmail.com> X-Mailer: git-send-email 2.0.4 In-Reply-To: <1425435131-12701-1-git-send-email-ryazanov.s.a@gmail.com> References: <1425435131-12701-1-git-send-email-ryazanov.s.a@gmail.com> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP To prepare for reset ath5k should finish all asynchronous tasks. At first, it disables the interrupt generation, then it waits for the interrupt handler and tasklets completion, and then proceeds to the HW configuration update. But it does not consider that the interrupt handler or tasklet re-enables the interrupt generation. And we fall in a situation when ath5k assumes that interrupts are disabled, but it is not. This can lead to different consequences, such as reception of the frame, when we do not expect it. Under certain circumstances, this can lead to the following warning: WARNING: at ath5k/base.c:589 ath5k_tasklet_rx+0x318/0x6ec [ath5k]() invalid hw_rix: 1a [..] Call Trace: [<802656a8>] show_stack+0x48/0x70 [<802dd92c>] warn_slowpath_common+0x88/0xbc [<802dd98c>] warn_slowpath_fmt+0x2c/0x38 [<81b51be8>] ath5k_tasklet_rx+0x318/0x6ec [ath5k] [<8028ac64>] tasklet_action+0x8c/0xf0 [<80075804>] __do_softirq+0x180/0x32c [<80196ce8>] irq_exit+0x54/0x70 [<80041848>] ret_from_irq+0x0/0x4 [<80182fdc>] ioread32+0x4/0xc [<81b4c42c>] ath5k_hw_set_sleep_clock+0x2ec/0x474 [ath5k] [<81b4cf28>] ath5k_hw_reset+0x50/0xeb8 [ath5k] [<81b50900>] ath5k_reset+0xd4/0x310 [ath5k] [<81b557e8>] ath5k_config+0x4c/0x104 [ath5k] [<80d01770>] ieee80211_hw_config+0x2f4/0x35c [mac80211] [<80d09aa8>] ieee80211_scan_work+0x2e4/0x414 [mac80211] [<8022c3f4>] process_one_work+0x28c/0x400 [<802df8f8>] worker_thread+0x258/0x3c0 [<801b5710>] kthread+0xe0/0xec [<800418a8>] ret_from_kernel_thread+0x14/0x1c Fix this issue by adding a new status flag, which forbids to re-enable the interrupt generation until the HW configuration is completed. Note: previous patch, which reorders the Rx disable code helps to avoid the above warning, but not fixes the root cause of unexpected frame receiving. CC: Jiri Slaby CC: Nick Kossifidis CC: Luis R. Rodriguez Reported-by: Christophe Prevotaux Tested-by: Christophe Prevotaux Tested-by: Eric Bree Signed-off-by: Sergey Ryazanov --- drivers/net/wireless/ath/ath5k/ath5k.h | 1 + drivers/net/wireless/ath/ath5k/base.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 1ed7a88..7ca0d6f 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1283,6 +1283,7 @@ struct ath5k_hw { #define ATH_STAT_PROMISC 1 #define ATH_STAT_LEDSOFT 2 /* enable LED gpio status */ #define ATH_STAT_STARTED 3 /* opened & irqs enabled */ +#define ATH_STAT_RESET 4 /* hw reset */ unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */ unsigned int fif_filter_flags; /* Current FIF_* filter flags */ diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 34b2f15..41848e1 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1523,6 +1523,9 @@ ath5k_set_current_imask(struct ath5k_hw *ah) enum ath5k_int imask; unsigned long flags; + if (test_bit(ATH_STAT_RESET, ah->status)) + return; + spin_lock_irqsave(&ah->irqlock, flags); imask = ah->imask; if (ah->rx_pending) @@ -2862,6 +2865,8 @@ ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan, ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "resetting\n"); + __set_bit(ATH_STAT_RESET, ah->status); + ath5k_hw_set_imr(ah, 0); synchronize_irq(ah->irq); ath5k_stop_tasklets(ah); @@ -2952,6 +2957,8 @@ ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan, */ /* ath5k_chan_change(ah, c); */ + __clear_bit(ATH_STAT_RESET, ah->status); + ath5k_beacon_config(ah); /* intrs are enabled by ath5k_beacon_config */