From patchwork Thu Jan 21 13:46:43 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Kazior X-Patchwork-Id: 8081191 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 0148D9F440 for ; Thu, 21 Jan 2016 13:46:00 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 06D8D203A9 for ; Thu, 21 Jan 2016 13:45:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0195420504 for ; Thu, 21 Jan 2016 13:45:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965326AbcAUNpy (ORCPT ); Thu, 21 Jan 2016 08:45:54 -0500 Received: from mail-lb0-f176.google.com ([209.85.217.176]:34551 "EHLO mail-lb0-f176.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965318AbcAUNpv (ORCPT ); Thu, 21 Jan 2016 08:45:51 -0500 Received: by mail-lb0-f176.google.com with SMTP id cl12so23453862lbc.1 for ; Thu, 21 Jan 2016 05:45:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tieto.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=zt2FXmHvPYo8g9RipjI4qRHgbWPaXpKcqPFfU1R966A=; b=A9JO0PGNZYzk0kv3bDBUa3HoUDhR4uZb0XcQEr0jiW/E3a25Sk9mDkem64wgUuVX/6 APMLXT0tX/Zl+nH+gZkKBZC/3djcYJTybHb3JwzZI2R6U0qDb8n0LHIdecrbho6kFnRN u3vKG/uZVGt1bbGWQB7OPEyuQtQ9J+zF1sQX0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=zt2FXmHvPYo8g9RipjI4qRHgbWPaXpKcqPFfU1R966A=; b=Sl5RNJwWPHduHZOuU5hUrWISXx8AiK4PT1rnxGrpSblbvYCCsilhooN8IQqK64s72I ymPpIK9k1IMJF6zqoBD9+tAQa+4NAB3DlA/TkNGv49R9s7DxSJz2QyQ+jF9Uy46O06Eo Dha7IioHiCL6l4Uluvv+uQXFw6AEK4wIE3Cp1kfREr9OaBwtgzjZm2R6r9Sneuc2fola XIXk69qmsu5TSLLEMfcgcJveXo//hQG67Xlu8UwPyY/ZJayAz1YMuBZ1z5ISliC+ryRA i9b/+4FjTuxZNKB5YH8FyB+t+EI0fMrh7uF9QB0XXpb/gU/RFSbUR/1TIwKhoSc3Gm+r pDUQ== X-Gm-Message-State: ALoCoQmvE0njduvOaLoSyGzo/pfuBrpcjzTU4b4FM2nrJizW4v2N8u0nN9l0MPXcs3f0rHhktsxanRYrKnFHzksSapOhMUPYciJUm963vTdSf8W+yVvTp8aZqCgjbgd/mF3ewRMs7pfDpLyFkahpENNiOj+BqRAUPQ== X-Received: by 10.112.52.38 with SMTP id q6mr15475597lbo.112.1453383949991; Thu, 21 Jan 2016 05:45:49 -0800 (PST) Received: from localhost.localdomain ([91.198.246.10]) by smtp.gmail.com with ESMTPSA id c192sm207382lfb.16.2016.01.21.05.45.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 21 Jan 2016 05:45:48 -0800 (PST) From: Michal Kazior To: ath10k@lists.infradead.org Cc: linux-wireless@vger.kernel.org, Michal Kazior Subject: [PATCH 10/13] ath10k: implement flushing of pending frames in txqs Date: Thu, 21 Jan 2016 14:46:43 +0100 Message-Id: <1453384006-31907-11-git-send-email-michal.kazior@tieto.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1453384006-31907-1-git-send-email-michal.kazior@tieto.com> References: <1453384006-31907-1-git-send-email-michal.kazior@tieto.com> X-DomainID: tieto.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_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,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 Firmware supporting pull-push tx model may request a switch between modes. When switching from pull-push to push-only it will be necessary to flush all pending frames. The code will do that once other bits that actually trigger it are added. Signed-off-by: Michal Kazior --- drivers/net/wireless/ath/ath10k/core.h | 1 + drivers/net/wireless/ath/ath10k/htt_rx.c | 3 ++ drivers/net/wireless/ath/ath10k/mac.c | 82 ++++++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath10k/mac.h | 1 + 4 files changed, 87 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index d09d6fdf1149..38ed4bbd220b 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -607,6 +607,7 @@ static inline const char *ath10k_scan_state_str(enum ath10k_scan_state state) enum ath10k_tx_pause_reason { ATH10K_TX_PAUSE_Q_FULL, + ATH10K_TX_PAUSE_Q_FLUSH_PENDING, ATH10K_TX_PAUSE_MAX, }; diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index be7dc88b3316..6e3d95c95568 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -2244,6 +2244,7 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) } ath10k_txrx_tx_unref(htt, &tx_done); + ath10k_mac_tx_push_pending(ar); break; } case HTT_T2H_MSG_TYPE_TX_COMPL_IND: @@ -2370,6 +2371,8 @@ static void ath10k_htt_txrx_compl_task(unsigned long ptr) dev_kfree_skb_any(skb); } + ath10k_mac_tx_push_pending(ar); + spin_lock_bh(&htt->rx_ring.lock); while ((skb = __skb_dequeue(&htt->rx_compl_q))) { resp = (struct htt_resp *)skb->data; diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 205ccf3760a3..42020c22eaed 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -3710,6 +3710,88 @@ static void ath10k_mac_tx_wake(struct ieee80211_hw *hw, ath10k_htt_tx_txq_update(hw, txq); } +struct ath10k_mac_tx_push_arg { + struct ieee80211_hw *hw; + bool more; +}; + +static void ath10k_mac_tx_push_pending_txq(struct ieee80211_hw *hw, + struct ieee80211_txq *txq, + struct ath10k_mac_tx_push_arg *arg) +{ + bool can_push; + bool has_more; + int ret; + + if (!txq) + return; + + while (txq->qdepth > 0) { + if (!ath10k_mac_tx_can_push(hw, txq)) + break; + + ret = ath10k_mac_tx_push_txq(hw, txq); + if (ret) + break; + } + + can_push = ath10k_mac_tx_can_push(hw, txq); + has_more = txq->qdepth > 0; + + if (can_push && has_more) + arg->more = true; +} + +static void ath10k_mac_tx_push_pending_vif_iter(void *data, + u8 *mac, + struct ieee80211_vif *vif) +{ + struct ath10k_mac_tx_push_arg *arg = data; + struct ieee80211_hw *hw = arg->hw; + + ath10k_mac_tx_push_pending_txq(hw, vif->txq, arg); +} + +static void ath10k_mac_tx_push_pending_sta_iter(void *data, + struct ieee80211_sta *sta) +{ + struct ath10k_mac_tx_push_arg *arg = data; + struct ieee80211_hw *hw = arg->hw; + int tid; + + for (tid = 0; tid < ARRAY_SIZE(sta->txq); tid++) + ath10k_mac_tx_push_pending_txq(hw, sta->txq[tid], arg); +} + +void ath10k_mac_tx_push_pending(struct ath10k *ar) +{ + struct ieee80211_hw *hw = ar->hw; + struct ath10k_mac_tx_push_arg arg = {}; + + if (likely(!(ar->tx_paused & BIT(ATH10K_TX_PAUSE_Q_FLUSH_PENDING)))) + return; + + arg.hw = hw; + arg.more = false; + + ieee80211_iterate_active_interfaces_atomic(hw, + IEEE80211_IFACE_ITER_NORMAL, + ath10k_mac_tx_push_pending_vif_iter, + &arg); + if (arg.more) + return; + + ieee80211_iterate_stations_atomic(hw, + ath10k_mac_tx_push_pending_sta_iter, + &arg); + if (arg.more) + return; + + spin_lock_bh(&ar->htt.tx_lock); + ath10k_mac_tx_unlock(ar, ATH10K_TX_PAUSE_Q_FLUSH_PENDING); + spin_unlock_bh(&ar->htt.tx_lock); +} + /************/ /* Scanning */ /************/ diff --git a/drivers/net/wireless/ath/ath10k/mac.h b/drivers/net/wireless/ath/ath10k/mac.h index 53091588090d..453f606a250e 100644 --- a/drivers/net/wireless/ath/ath10k/mac.h +++ b/drivers/net/wireless/ath/ath10k/mac.h @@ -75,6 +75,7 @@ void ath10k_mac_tx_unlock(struct ath10k *ar, int reason); void ath10k_mac_vif_tx_lock(struct ath10k_vif *arvif, int reason); void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason); bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar); +void ath10k_mac_tx_push_pending(struct ath10k *ar); static inline struct ath10k_vif *ath10k_vif_to_arvif(struct ieee80211_vif *vif) {