From patchwork Thu Jan 21 13:13:27 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Kazior X-Patchwork-Id: 8081011 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 98B9E9F96D for ; Thu, 21 Jan 2016 13:12:36 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7B79220411 for ; Thu, 21 Jan 2016 13:12:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 661FF20451 for ; Thu, 21 Jan 2016 13:12:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965178AbcAUNMb (ORCPT ); Thu, 21 Jan 2016 08:12:31 -0500 Received: from mail-lf0-f42.google.com ([209.85.215.42]:33035 "EHLO mail-lf0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965018AbcAUNM1 (ORCPT ); Thu, 21 Jan 2016 08:12:27 -0500 Received: by mail-lf0-f42.google.com with SMTP id m198so26302592lfm.0 for ; Thu, 21 Jan 2016 05:12:26 -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=6VzNrwCmb0APmtJ/hdI5aRwn13pQV61JWY1b0Un13Zo=; b=lqLgsWpUTVgjCf/7X/LBsQ4HP4S1eNnbDoeTPny8Vwme/ZddkcgcLeUXfv2rc4qY4L QQnP8O1jVlr9dFKYKn9rESeo2uvvh4pMY7LW2nlMOgatPBPA6hd3Xv+UyLoBAcHYV4Mg MwtZDDtuxF9JMB8R+sDmKFdmDfJXkfUZ2tWv8= 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=6VzNrwCmb0APmtJ/hdI5aRwn13pQV61JWY1b0Un13Zo=; b=TOJBRC5ABjxkXilxGlw9cdZPxS6I1/3hvd5oGxTr31BbSFjPtSgSq7ho/2fB91LVE8 rZ78xIfHHM+m0DYMOr4lzOGZBTUC+zU+UgewBhsyGPBninhwcGNiX7zrR6yJyLMocE07 6QjLZPkpk/XkDA3pEE/7QtYLApBPANI2BnFN/OfxqnlkZtQEehSuR8x/PTCD/zLOn+ce 9xVmWjPTv9svD+2BmfO2unDzLhkL86qeTlkPdSCPoENH4iVkLnZ7tK1QYnnWPiRS10Yc ylLfsGit450aHQOSMASQStAnm+mLSFah60nAYl2ajkuRCU6Lmmt++V5Swxv36dNi3rr2 7Z4Q== X-Gm-Message-State: ALoCoQmXnU+jAJSUezzmkmHGA6XOMQzfG6TsHF6/yRbnc47CXtwq1IbSZ3kKEreuMrNog+7JI2ksQ63bwgv5RansTkjhzc4Wy9CJWP1LzP8r+Czyid+s6WBHPtdFKYQIfH89+dGQY6XlVnEvAT8rBh2w2Pd4+t1Zzg== X-Received: by 10.25.43.20 with SMTP id r20mr12694007lfr.121.1453381946150; Thu, 21 Jan 2016 05:12:26 -0800 (PST) Received: from localhost.localdomain ([91.198.246.10]) by smtp.gmail.com with ESMTPSA id tv1sm189406lbb.4.2016.01.21.05.12.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 21 Jan 2016 05:12:25 -0800 (PST) From: Michal Kazior To: ath10k@lists.infradead.org Cc: linux-wireless@vger.kernel.org, Michal Kazior Subject: [PATCH 5/5] ath10k: implement basic support for new tx path firmware Date: Thu, 21 Jan 2016 14:13:27 +0100 Message-Id: <1453382007-24622-6-git-send-email-michal.kazior@tieto.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1453382007-24622-1-git-send-email-michal.kazior@tieto.com> References: <1452693668-30030-1-git-send-email-michal.kazior@tieto.com> <1453382007-24622-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 This allows to use the new firmware which implements the new tx data path. Without this patch firmware supporting new tx path stops responding shortly after booting. This patch doesn't implement the entire pull-push logic available in the new firmware. This will be done in subsequent patches. Signed-off-by: Michal Kazior --- drivers/net/wireless/ath/ath10k/htt.h | 8 +++ drivers/net/wireless/ath/ath10k/htt_rx.c | 4 +- drivers/net/wireless/ath/ath10k/htt_tx.c | 88 +++++++++++++++++++++++++++++--- 3 files changed, 91 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h index 0c5628dafabf..13391ea4422d 100644 --- a/drivers/net/wireless/ath/ath10k/htt.h +++ b/drivers/net/wireless/ath/ath10k/htt.h @@ -1665,6 +1665,14 @@ struct ath10k_htt { dma_addr_t paddr; struct ath10k_htt_txbuf *vaddr; } txbuf; + + struct { + struct htt_q_state *vaddr; + dma_addr_t paddr; + u16 num_peers; + u16 num_tids; + enum htt_q_depth_type type; + } tx_q_state; }; #define RX_HTT_HDR_STATUS_LEN 64 diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index d923f64e4f42..248405b53ef4 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -2123,10 +2123,12 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) break; case HTT_T2H_MSG_TYPE_AGGR_CONF: break; - case HTT_T2H_MSG_TYPE_EN_STATS: case HTT_T2H_MSG_TYPE_TX_FETCH_IND: case HTT_T2H_MSG_TYPE_TX_FETCH_CONFIRM: case HTT_T2H_MSG_TYPE_TX_MODE_SWITCH_IND: + /* TODO: Implement pull-push logic */ + break; + case HTT_T2H_MSG_TYPE_EN_STATS: default: ath10k_warn(ar, "htt event (%d) not handled\n", resp->hdr.msg_type); diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c index 28b8d7af8506..95acb727c068 100644 --- a/drivers/net/wireless/ath/ath10k/htt_tx.c +++ b/drivers/net/wireless/ath/ath10k/htt_tx.c @@ -132,6 +132,50 @@ static int ath10k_htt_tx_alloc_cont_frag_desc(struct ath10k_htt *htt) return 0; } +static void ath10k_htt_tx_free_txq(struct ath10k_htt *htt) +{ + struct ath10k *ar = htt->ar; + size_t size; + + if (!test_bit(ATH10K_FW_FEATURE_PEER_FLOW_CONTROL, ar->fw_features)) + return; + + size = sizeof(*htt->tx_q_state.vaddr); + + dma_unmap_single(ar->dev, htt->tx_q_state.paddr, size, DMA_TO_DEVICE); + kfree(htt->tx_q_state.vaddr); +} + +static int ath10k_htt_tx_alloc_txq(struct ath10k_htt *htt) +{ + struct ath10k *ar = htt->ar; + size_t size; + int ret; + + if (!test_bit(ATH10K_FW_FEATURE_PEER_FLOW_CONTROL, ar->fw_features)) + return 0; + + htt->tx_q_state.num_peers = HTT_TX_Q_STATE_NUM_PEERS; + htt->tx_q_state.num_tids = HTT_TX_Q_STATE_NUM_TIDS; + htt->tx_q_state.type = HTT_Q_DEPTH_TYPE_BYTES; + + size = sizeof(*htt->tx_q_state.vaddr); + htt->tx_q_state.vaddr = kzalloc(size, GFP_KERNEL); + if (!htt->tx_q_state.vaddr) + return -ENOMEM; + + htt->tx_q_state.paddr = dma_map_single(ar->dev, htt->tx_q_state.vaddr, + size, DMA_TO_DEVICE); + ret = dma_mapping_error(ar->dev, htt->tx_q_state.paddr); + if (ret) { + ath10k_warn(ar, "failed to dma map tx_q_state: %d\n", ret); + kfree(htt->tx_q_state.vaddr); + return -EIO; + } + + return 0; +} + int ath10k_htt_tx_alloc(struct ath10k_htt *htt) { struct ath10k *ar = htt->ar; @@ -159,8 +203,17 @@ int ath10k_htt_tx_alloc(struct ath10k_htt *htt) goto free_txbuf; } + ret = ath10k_htt_tx_alloc_txq(htt); + if (ret) { + ath10k_err(ar, "failed to alloc txq: %d\n", ret); + goto free_frag_desc; + } + return 0; +free_frag_desc: + ath10k_htt_tx_free_cont_frag_desc(htt); + free_txbuf: size = htt->max_num_pending_tx * sizeof(struct ath10k_htt_txbuf); @@ -203,6 +256,7 @@ void ath10k_htt_tx_free(struct ath10k_htt *htt) htt->txbuf.paddr); } + ath10k_htt_tx_free_txq(htt); ath10k_htt_tx_free_cont_frag_desc(htt); } @@ -292,7 +346,9 @@ int ath10k_htt_send_frag_desc_bank_cfg(struct ath10k_htt *htt) struct ath10k *ar = htt->ar; struct sk_buff *skb; struct htt_cmd *cmd; + struct htt_frag_desc_bank_cfg *cfg; int ret, size; + u8 info; if (!ar->hw_params.continuous_frag_desc) return 0; @@ -310,14 +366,30 @@ int ath10k_htt_send_frag_desc_bank_cfg(struct ath10k_htt *htt) skb_put(skb, size); cmd = (struct htt_cmd *)skb->data; cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_FRAG_DESC_BANK_CFG; - cmd->frag_desc_bank_cfg.info = 0; - cmd->frag_desc_bank_cfg.num_banks = 1; - cmd->frag_desc_bank_cfg.desc_size = sizeof(struct htt_msdu_ext_desc); - cmd->frag_desc_bank_cfg.bank_base_addrs[0] = - __cpu_to_le32(htt->frag_desc.paddr); - cmd->frag_desc_bank_cfg.bank_id[0].bank_min_id = 0; - cmd->frag_desc_bank_cfg.bank_id[0].bank_max_id = - __cpu_to_le16(htt->max_num_pending_tx - 1); + + info = 0; + info |= SM(htt->tx_q_state.type, + HTT_FRAG_DESC_BANK_CFG_INFO_Q_STATE_DEPTH_TYPE); + + if (test_bit(ATH10K_FW_FEATURE_PEER_FLOW_CONTROL, ar->fw_features)) + info |= HTT_FRAG_DESC_BANK_CFG_INFO_Q_STATE_VALID; + + cfg = &cmd->frag_desc_bank_cfg; + cfg->info = info; + cfg->num_banks = 1; + cfg->desc_size = sizeof(struct htt_msdu_ext_desc); + cfg->bank_base_addrs[0] = __cpu_to_le32(htt->frag_desc.paddr); + cfg->bank_id[0].bank_min_id = 0; + cfg->bank_id[0].bank_max_id = __cpu_to_le16(htt->max_num_pending_tx - + 1); + + cfg->q_state.paddr = cpu_to_le32(htt->tx_q_state.paddr); + cfg->q_state.num_peers = cpu_to_le16(htt->tx_q_state.num_peers); + cfg->q_state.num_tids = cpu_to_le16(htt->tx_q_state.num_tids); + cfg->q_state.record_size = HTT_TX_Q_STATE_ENTRY_SIZE; + cfg->q_state.record_multiplier = HTT_TX_Q_STATE_ENTRY_MULTIPLIER; + + ath10k_dbg(ar, ATH10K_DBG_HTT, "htt frag desc bank cmd\n"); ret = ath10k_htc_send(&htt->ar->htc, htt->eid, skb); if (ret) {