From patchwork Thu Jan 27 09:15:08 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Natarajan X-Patchwork-Id: 510881 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p0R9FXCk002047 for ; Thu, 27 Jan 2011 09:15:33 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753704Ab1A0JPc (ORCPT ); Thu, 27 Jan 2011 04:15:32 -0500 Received: from mail.atheros.com ([12.19.149.2]:10255 "EHLO mail.atheros.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753363Ab1A0JPb (ORCPT ); Thu, 27 Jan 2011 04:15:31 -0500 Received: from mail.atheros.com ([10.10.20.108]) by sidewinder.atheros.com for ; Thu, 27 Jan 2011 01:15:11 -0800 Received: from smtp.atheros.com (10.12.4.8) by SC1EXHC-02.global.atheros.com (10.10.20.106) with Microsoft SMTP Server (TLS) id 8.2.213.0; Thu, 27 Jan 2011 01:15:29 -0800 Received: by smtp.atheros.com (sSMTP sendmail emulation); Thu, 27 Jan 2011 14:45:22 +0530 From: Vivek Natarajan To: CC: , Vivek Natarajan Subject: [PATCH 2/5] ath9k: Fix a PLL hang issue observed with AR9485. Date: Thu, 27 Jan 2011 14:45:08 +0530 Message-ID: <1296119711-4024-2-git-send-email-vnatarajan@atheros.com> X-Mailer: git-send-email 1.6.3.3 In-Reply-To: <1296119711-4024-1-git-send-email-vnatarajan@atheros.com> References: <1296119711-4024-1-git-send-email-vnatarajan@atheros.com> MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Thu, 27 Jan 2011 09:15:34 +0000 (UTC) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 6636f3c..72a1c0d 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -652,6 +652,7 @@ struct ath_softc { #endif struct ath_beacon_config cur_beacon_conf; struct delayed_work tx_complete_work; + struct delayed_work hw_pll_work; struct ath_btcoex btcoex; struct ath_descdma txsdma; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index facff10..2029665 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -231,6 +231,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, cancel_work_sync(&sc->paprd_work); cancel_work_sync(&sc->hw_check_work); cancel_delayed_work_sync(&sc->tx_complete_work); + cancel_delayed_work_sync(&sc->hw_pll_work); ath9k_ps_wakeup(sc); @@ -291,6 +292,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, if (sc->sc_flags & SC_OP_BEACONS) ath_beacon_config(sc, NULL); ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); + ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2); ath_start_ani(common); } @@ -1298,6 +1300,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) cancel_delayed_work_sync(&sc->ath_led_blink_work); cancel_delayed_work_sync(&sc->tx_complete_work); + cancel_delayed_work_sync(&sc->hw_pll_work); cancel_work_sync(&sc->paprd_work); cancel_work_sync(&sc->hw_check_work); diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index dcac811..c73452d 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -2106,6 +2106,28 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) } } +static void ath_hw_pll_work(struct work_struct *work) +{ + struct ath_softc *sc = container_of(work, struct ath_softc, + hw_pll_work.work); + static int count; + + if (AR_SREV_9485(sc->sc_ah)) { + if (ar9003_get_pll_sqsum_dvc(sc->sc_ah) >= 0x40000) { + count++; + + if (count == 3) { + /* Rx is hung for more than 500ms. Reset it */ + ath_reset(sc, true); + count = 0; + } + } else + count = 0; + + ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5); + } +} + static void ath_tx_complete_poll_work(struct work_struct *work) { struct ath_softc *sc = container_of(work, struct ath_softc, @@ -2330,6 +2352,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) } INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work); + INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { error = ath_tx_edma_init(sc);