From patchwork Fri Jan 30 08:41:26 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Kazior X-Patchwork-Id: 5747721 Return-Path: X-Original-To: patchwork-ath10k@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 B6288BF440 for ; Fri, 30 Jan 2015 08:43:24 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B0D5E201BB for ; Fri, 30 Jan 2015 08:43:23 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A7CA5201CE for ; Fri, 30 Jan 2015 08:43:22 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1YH7Ad-0002fw-3J; Fri, 30 Jan 2015 08:43:19 +0000 Received: from mail-wi0-x236.google.com ([2a00:1450:400c:c05::236]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1YH7AX-0002WP-GT for ath10k@lists.infradead.org; Fri, 30 Jan 2015 08:43:15 +0000 Received: by mail-wi0-f182.google.com with SMTP id n3so1240964wiv.3 for ; Fri, 30 Jan 2015 00:42: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=8l9QIDBi05tM9OIvRDkWUghlxeROSkdr8tHrdGcatbg=; b=fWp6HlMKvyruryzU1vYpHwuEt9tFRYktgwuFfu3NBWnwiQskP3LH8WkKRcCJ+dtQHy kjAd38tTVpxjZUJYsl5my9Hf1wv38+wWuy+mpYJhtt1EDuRoDA6ooUpQRe/GpG7TXJzB mQTeWsY1yJ/MuDzVOTWBKifo95uWMA9M7kFWk= 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=8l9QIDBi05tM9OIvRDkWUghlxeROSkdr8tHrdGcatbg=; b=IrPGtjVw061qOTsWTzqn0I1RzdSNd5RiRToxRhxYG2oxRHg1//wI2toDTcUhuY8+F6 xwCx15JegxU6oFMkS0qHQnftY1B7/18W/p04P8a1CDT+ZX2XPM5lmJYMz7zLU4a7gYvG 8NMLgsHOPRKxkWLgk/GSs5Wn5rY3tQjLmtp0rpPKJNzWpZSnsBKALJbtwUZtlibRyxRk HGlRg/06h4Fnnu5X4RA0vdrerlq3CsSD/oGeg70WX33cf2nLrPTIgt8F4B+hiZ+TcPTV IWyWqoxuElBGsEXu4aXPf7kGX4BU63jgYFI5VOinqx47z6/hFLyUiwOAv5WQEuw1fD/2 CWdw== X-Gm-Message-State: ALoCoQldHkWe0SlYO+IIxVhT4k062uxE7Ya4H52gYZ4gWa2nlWQIlAQqUXXQLKraGUS66zUhbmQyysGcJcIyeE42I3UrI1cenmipEEhsjovC4PXkY9SWD1B17HPT1630GQtw3Za+qbvbEENntcE5StKq7QyTBMSNH+u+B1vy9GQM497pJeKk214= X-Received: by 10.194.202.129 with SMTP id ki1mr9631712wjc.76.1422607370549; Fri, 30 Jan 2015 00:42:50 -0800 (PST) Received: from bob.homerouter.cpe (apn-31-1-134-151.dynamic.gprs.plus.pl. [31.1.134.151]) by mx.google.com with ESMTPSA id i3sm5884655wie.23.2015.01.30.00.42.49 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 30 Jan 2015 00:42:50 -0800 (PST) From: Michal Kazior To: ath10k@lists.infradead.org Subject: [PATCH 6/7] ath10k: implement tx pause wmi event Date: Fri, 30 Jan 2015 09:41:26 +0100 Message-Id: <1422607287-12289-7-git-send-email-michal.kazior@tieto.com> X-Mailer: git-send-email 1.8.5.3 In-Reply-To: <1422607287-12289-1-git-send-email-michal.kazior@tieto.com> References: <1422607287-12289-1-git-send-email-michal.kazior@tieto.com> X-DomainID: tieto.com X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150130_004313_895621_F994D4D2 X-CRM114-Status: GOOD ( 14.51 ) X-Spam-Score: -0.8 (/) Cc: linux-wireless@vger.kernel.org, Michal Kazior X-BeenThere: ath10k@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "ath10k" Errors-To: ath10k-bounces+patchwork-ath10k=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable 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 qca6174 wmi-tlv firmware defines a new wmi event for host tx pausing (i.e. stop/wake tx queues). Map these events to ath10k/mac80211 tx queue control. This is important for multi-channel thourghput performance. Signed-off-by: Michal Kazior --- drivers/net/wireless/ath/ath10k/mac.c | 12 +++++ drivers/net/wireless/ath/ath10k/wmi-tlv.c | 86 +++++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath10k/wmi-tlv.h | 42 +++++++++++++++ 3 files changed, 140 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index f84ffc9..eea6b95 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -3482,6 +3482,14 @@ err: return ret; } +static void ath10k_mac_vif_tx_unlock_all(struct ath10k_vif *arvif) +{ + int i; + + for (i = 0; i < BITS_PER_LONG; i++) + ath10k_mac_vif_tx_unlock(arvif, i); +} + static void ath10k_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { @@ -3534,6 +3542,10 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, ath10k_warn(ar, "failed to recalc monitor: %d\n", ret); } + spin_lock_bh(&ar->htt.tx_lock); + ath10k_mac_vif_tx_unlock_all(arvif); + spin_unlock_bh(&ar->htt.tx_lock); + mutex_unlock(&ar->conf_mutex); } diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c index 0e36b34..3763359 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c @@ -16,6 +16,7 @@ */ #include "core.h" #include "debug.h" +#include "mac.h" #include "hw.h" #include "wmi.h" #include "wmi-ops.h" @@ -62,6 +63,8 @@ static const struct wmi_tlv_policy wmi_tlv_policies[] = { = { .min_len = sizeof(struct wmi_tlv_bcn_tx_status_ev) }, [WMI_TLV_TAG_STRUCT_DIAG_DATA_CONTAINER_EVENT] = { .min_len = sizeof(struct wmi_tlv_diag_data_ev) }, + [WMI_TLV_TAG_STRUCT_TX_PAUSE_EVENT] + = { .min_len = sizeof(struct wmi_tlv_tx_pause_ev) }, }; static int @@ -296,6 +299,86 @@ static int ath10k_wmi_tlv_event_diag(struct ath10k *ar, return 0; } +static int ath10k_wmi_tlv_event_tx_pause(struct ath10k *ar, + struct sk_buff *skb) +{ + const void **tb; + const struct wmi_tlv_tx_pause_ev *ev; + int ret, vdev_id; + u32 pause_id, action, vdev_map, peer_id, tid_map; + struct ath10k_vif *arvif; + + tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); + if (IS_ERR(tb)) { + ret = PTR_ERR(tb); + ath10k_warn(ar, "failed to parse tlv: %d\n", ret); + return ret; + } + + ev = tb[WMI_TLV_TAG_STRUCT_TX_PAUSE_EVENT]; + if (!ev) { + kfree(tb); + return -EPROTO; + } + + pause_id = __le32_to_cpu(ev->pause_id); + action = __le32_to_cpu(ev->action); + vdev_map = __le32_to_cpu(ev->vdev_map); + peer_id = __le32_to_cpu(ev->peer_id); + tid_map = __le32_to_cpu(ev->tid_map); + + ath10k_dbg(ar, ATH10K_DBG_WMI, + "wmi tlv tx pause pause_id %u action %u vdev_map 0x%08x peer_id %u tid_map 0x%08x\n", + pause_id, action, vdev_map, peer_id, tid_map); + + for (vdev_id = 0; vdev_map; vdev_id++) { + if (!(vdev_map & BIT(vdev_id))) + continue; + + vdev_map &= ~BIT(vdev_id); + + spin_lock_bh(&ar->htt.tx_lock); + spin_lock_bh(&ar->data_lock); + + arvif = ath10k_get_arvif(ar, vdev_id); + if (!arvif) { + ath10k_warn(ar, "failed to find arvif for vdev %i for tx pause event\n", + vdev_id); + spin_unlock_bh(&ar->data_lock); + spin_unlock_bh(&ar->htt.tx_lock); + continue; + } + + /* FIXME: Some pause_id aren't vdev orinted. Instead they are + * peer_id oriented (mostly for AP mode scenarios). + */ + if (pause_id == WMI_TLV_TX_PAUSE_ID_MCC || + pause_id == WMI_TLV_TX_PAUSE_ID_P2P_CLI_NOA || + pause_id == WMI_TLV_TX_PAUSE_ID_P2P_GO_PS || + pause_id == WMI_TLV_TX_PAUSE_ID_AP_PS || + pause_id == WMI_TLV_TX_PAUSE_ID_IBSS_PS) { + switch (action) { + case WMI_TLV_TX_PAUSE_ACTION_STOP: + ath10k_mac_vif_tx_lock(arvif, pause_id); + break; + case WMI_TLV_TX_PAUSE_ACTION_WAKE: + ath10k_mac_vif_tx_unlock(arvif, pause_id); + break; + default: + ath10k_warn(ar, "received unknown tx pause action %d on vdev %i, ignoring\n", + action, vdev_id); + break; + } + } + + spin_unlock_bh(&ar->data_lock); + spin_unlock_bh(&ar->htt.tx_lock); + } + + kfree(tb); + return 0; +} + /***********/ /* TLV ops */ /***********/ @@ -417,6 +500,9 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb) case WMI_TLV_DIAG_EVENTID: ath10k_wmi_tlv_event_diag(ar, skb); break; + case WMI_TLV_TX_PAUSE_EVENTID: + ath10k_wmi_tlv_event_tx_pause(ar, skb); + break; default: ath10k_warn(ar, "Unknown eventid: %d\n", id); break; diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h index a05952a..3abc85f 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h @@ -1443,6 +1443,48 @@ struct wmi_tlv_adaptive_qcs { __le32 enable; } __packed; +/** + * wmi_tlv_tx_pause_id - firmware tx queue pause reason types + * + * @WMI_TLV_TX_PAUSE_ID_MCC: used for by multi-channel firmware scheduler. + * Only vdev_map is valid. + * @WMI_TLV_TX_PAUSE_ID_AP_PEER_PS: peer in AP mode is asleep. + * Only peer_id is valid. + * @WMI_TLV_TX_PAUSE_ID_AP_PEER_UAPSD: Only peer_id and tid_map are valid. + * @WMI_TLV_TX_PAUSE_ID_P2P_CLI_NOA: Only vdev_map is valid. + * @WMI_TLV_TX_PAUSE_ID_P2P_GO_PS: Only vdev_map is valid. + * @WMI_TLV_TX_PAUSE_ID_STA_ADD_BA: Only peer_id and tid_map are valid. + * @WMI_TLV_TX_PAUSE_ID_AP_PS: When all peers are asleep in AP mode. Only + * vdev_map is valid. + * @WMI_TLV_TX_PAUSE_ID_IBSS_PS: When all peers are asleep in IBSS mode. Only + * vdev_map is valid. + * @WMI_TLV_TX_PAUSE_ID_HOST: Host itself requested tx pause. + */ +enum wmi_tlv_tx_pause_id { + WMI_TLV_TX_PAUSE_ID_MCC = 1, + WMI_TLV_TX_PAUSE_ID_AP_PEER_PS = 2, + WMI_TLV_TX_PAUSE_ID_AP_PEER_UAPSD = 3, + WMI_TLV_TX_PAUSE_ID_P2P_CLI_NOA = 4, + WMI_TLV_TX_PAUSE_ID_P2P_GO_PS = 5, + WMI_TLV_TX_PAUSE_ID_STA_ADD_BA = 6, + WMI_TLV_TX_PAUSE_ID_AP_PS = 7, + WMI_TLV_TX_PAUSE_ID_IBSS_PS = 8, + WMI_TLV_TX_PAUSE_ID_HOST = 21, +}; + +enum wmi_tlv_tx_pause_action { + WMI_TLV_TX_PAUSE_ACTION_STOP, + WMI_TLV_TX_PAUSE_ACTION_WAKE, +}; + +struct wmi_tlv_tx_pause_ev { + __le32 pause_id; + __le32 action; + __le32 vdev_map; + __le32 peer_id; + __le32 tid_map; +} __packed; + void ath10k_wmi_tlv_attach(struct ath10k *ar); #endif