From patchwork Sat Sep 30 17:37:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: silexcommon@gmail.com X-Patchwork-Id: 9979565 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 2C5F46034B for ; Sat, 30 Sep 2017 17:39:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 158BE28EF7 for ; Sat, 30 Sep 2017 17:39:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0A24228EFE; Sat, 30 Sep 2017 17:39:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, DKIM_VALID, FREEMAIL_FROM, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 94C3728EF7 for ; Sat, 30 Sep 2017 17:39:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=j3qX5eVMxCoviBsABrRIZ1xykKrf/YJ2jogIKX1gM/U=; b=KajpkuEXwwFfbAwaPg2/75C+eu rCdFNoG7ZTRS+W1+KHdG5PoqfrRwD+TfeS7nDoxL35nRJ4VtWiqUBE6YJj/dDpzw4iVv4pRifgTHV xFZ/q7OBmwHB0v29kMXzECFC8Xk8+nlMC0rUcbH98EnnvY/9eF/1egkWNljC1kJm3lPeMye1I5ULu i1bURBxjGKDv9LQ61/WnNRpRgntibtrnv9iHOzdNkupOlXW5Zg4BQ9OPNG/PTY5O4DiQUpApA0eq5 1UbWU2swPKkUEOMWYmUeURFwUTkWjnaUqcHVPaG5tblVnnFiTPuaVWIu4uEC36f8l7u3wzoJUZdyf gl6Pideg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dyLjD-0001e4-Hk; Sat, 30 Sep 2017 17:39:03 +0000 Received: from mail-pg0-x242.google.com ([2607:f8b0:400e:c05::242]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dyLj3-0001P5-4Q for ath10k@lists.infradead.org; Sat, 30 Sep 2017 17:39:00 +0000 Received: by mail-pg0-x242.google.com with SMTP id j16so1849545pga.2 for ; Sat, 30 Sep 2017 10:38:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=cvoVIj0mELUiMIfEom3/Pe1V6VmWEVHcGcrM64aQAoo=; b=OETSLxHDYkpPe8bq0wZF/RSd/xIsU1kxQBu+DEI+zUPKpQ5EwReSfhiG/Mp6R3Uoat vxMY1LAglYOfYuGIAAJZ9jxV47gB0jOCntQJmXuNHbQrBENn5sSUdHJNUu8FwiMOcQRT qg/rujqAuxqd2m9/kt1flEoyohavy610E4o2MRq6KBr0Lz3EVofa3rHOLjdYgPHt2ku9 hlQtjVp28eb1PyAspLdazUTots9cWwLSDhPw0ZolGX3vmGt77pbiXd+bAk4RHud2gJnr 8QbPDv1ndLZ+OB2jTrDcQue02i7QMRAmYCokz7KE5WU1keWoblgjk57SgPGv9IpehAp9 p8pg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=cvoVIj0mELUiMIfEom3/Pe1V6VmWEVHcGcrM64aQAoo=; b=jlqrDF8YazV0+MXEWAHSO18mAE8yz/ei/9Sn2qBOGhcmXGmwdwbBc8FBmN7Z4Ay72M knVXDdgkru+LHlbC97zYQqVPrd+Ue0W9SE9Rj3k8CRinBF3xvvPkKPed5zXtcY7+yvWy hQTI/FV4HrwZFuwzvtXOB3oXYg971q6IcVGOtwF65q1JS83qdBL33DKLqhDB6URARlT4 SPBnoIkxRscBpmcofUrWNYO4atHUR2w9facUAUW6QCt3DiOTVlcauvblotNHs4uRiI0/ u5E5AwLBeT0NNWq/54YxlQuWiX+FC7ln9VU4uE7efVp3nYA93wHdnL5nrdSvqPRheC84 ucLA== X-Gm-Message-State: AHPjjUjeXJsPZTCk+8n807IsHzm2zKKNvf7nTCSfqWpwwj45ywSrRahN F665YmOqyRSXT39SuqOKll8Tjv3yxsI= X-Google-Smtp-Source: AOwi7QC9tWgEIdWcpMv3roLNHPAeI7+VpyvlFyikI8nAOo5YMTK35Sl11SyL3ZTTuZ9cGbGuhG8zcA== X-Received: by 10.99.174.78 with SMTP id e14mr8530810pgp.155.1506793112424; Sat, 30 Sep 2017 10:38:32 -0700 (PDT) Received: from localhost.localdomain ([171.60.245.167]) by smtp.gmail.com with ESMTPSA id q15sm11197640pgc.64.2017.09.30.10.38.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 30 Sep 2017 10:38:31 -0700 (PDT) From: silexcommon@gmail.com X-Google-Original-From: alagusankar@silex-india.com To: ath10k@lists.infradead.org Subject: [PATCH 03/11] ath10k_sdio: DMA bounce buffers for read write Date: Sat, 30 Sep 2017 23:07:40 +0530 Message-Id: <1506793068-27445-4-git-send-email-alagusankar@silex-india.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1506793068-27445-1-git-send-email-alagusankar@silex-india.com> References: <1506793068-27445-1-git-send-email-alagusankar@silex-india.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170930_103853_500137_747D0516 X-CRM114-Status: GOOD ( 15.54 ) X-BeenThere: ath10k@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alagu Sankar , linux-wireless@vger.kernel.org MIME-Version: 1.0 Sender: "ath10k" Errors-To: ath10k-bounces+patchwork-ath10k=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Alagu Sankar Some SD host controllers still need bounce buffers for SDIO data transfers. While the transfers worked fine on x86 platforms, this is found to be required for i.MX6 based systems. Changes are similar to and derived from the ath6kl sdio driver. Signed-off-by: Alagu Sankar --- drivers/net/wireless/ath/ath10k/sdio.c | 59 ++++++++++++++++++++++++++++++++-- drivers/net/wireless/ath/ath10k/sdio.h | 5 +++ 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c index 03a69e5..77d4fa4 100644 --- a/drivers/net/wireless/ath/ath10k/sdio.c +++ b/drivers/net/wireless/ath/ath10k/sdio.c @@ -34,8 +34,20 @@ #include "trace.h" #include "sdio.h" +#define ATH10K_SDIO_DMA_BUF_SIZE (32 * 1024) + /* inlined helper functions */ +/* Macro to check if DMA buffer is WORD-aligned and DMA-able. + * Most host controllers assume the buffer is DMA'able and will + * bug-check otherwise (i.e. buffers on the stack). virt_addr_valid + * check fails on stack memory. + */ +static inline bool buf_needs_bounce(const u8 *buf) +{ + return ((unsigned long)buf & 0x3) || !virt_addr_valid(buf); +} + static inline int ath10k_sdio_calc_txrx_padded_len(struct ath10k_sdio *ar_sdio, size_t len) { @@ -303,15 +315,29 @@ static int ath10k_sdio_read(struct ath10k *ar, u32 addr, void *buf, size_t len) { struct ath10k_sdio *ar_sdio = ath10k_sdio_priv(ar); struct sdio_func *func = ar_sdio->func; + bool bounced = false; + u8 *tbuf = NULL; int ret; + if (buf_needs_bounce(buf)) { + if (!ar_sdio->dma_buffer) + return -ENOMEM; + mutex_lock(&ar_sdio->dma_buffer_mutex); + tbuf = ar_sdio->dma_buffer; + bounced = true; + } else { + tbuf = buf; + } + sdio_claim_host(func); - ret = sdio_memcpy_fromio(func, buf, addr, len); + ret = sdio_memcpy_fromio(func, tbuf, addr, len); if (ret) { ath10k_warn(ar, "failed to read from address 0x%x: %d\n", addr, ret); goto out; + } else if (bounced) { + memcpy(buf, tbuf, len); } ath10k_dbg(ar, ATH10K_DBG_SDIO, "sdio read addr 0x%x buf 0x%p len %zu\n", @@ -320,6 +346,8 @@ static int ath10k_sdio_read(struct ath10k *ar, u32 addr, void *buf, size_t len) out: sdio_release_host(func); + if (bounced) + mutex_unlock(&ar_sdio->dma_buffer_mutex); return ret; } @@ -328,14 +356,27 @@ static int ath10k_sdio_write(struct ath10k *ar, u32 addr, const void *buf, size_ { struct ath10k_sdio *ar_sdio = ath10k_sdio_priv(ar); struct sdio_func *func = ar_sdio->func; + bool bounced = false; + u8 *tbuf = NULL; int ret; + if (buf_needs_bounce(buf)) { + if (!ar_sdio->dma_buffer) + return -ENOMEM; + mutex_lock(&ar_sdio->dma_buffer_mutex); + tbuf = ar_sdio->dma_buffer; + memcpy(tbuf, buf, len); + bounced = true; + } else { + tbuf = (u8 *)buf; + } + sdio_claim_host(func); /* For some reason toio() doesn't have const for the buffer, need * an ugly hack to workaround that. */ - ret = sdio_memcpy_toio(func, addr, (void *)buf, len); + ret = sdio_memcpy_toio(func, addr, (void *)tbuf, len); if (ret) { ath10k_warn(ar, "failed to write to address 0x%x: %d\n", addr, ret); @@ -348,6 +389,8 @@ static int ath10k_sdio_write(struct ath10k *ar, u32 addr, const void *buf, size_ out: sdio_release_host(func); + if (bounced) + mutex_unlock(&ar_sdio->dma_buffer_mutex); return ret; } @@ -1978,6 +2021,12 @@ static int ath10k_sdio_probe(struct sdio_func *func, goto err_free_en_reg; } + ar_sdio->dma_buffer = kzalloc(ATH10K_SDIO_DMA_BUF_SIZE, GFP_KERNEL); + if (!ar_sdio->dma_buffer) { + ret = -ENOMEM; + goto err_free_bmi_buf; + } + ar_sdio->func = func; sdio_set_drvdata(func, ar_sdio); @@ -1987,6 +2036,7 @@ static int ath10k_sdio_probe(struct sdio_func *func, spin_lock_init(&ar_sdio->lock); spin_lock_init(&ar_sdio->wr_async_lock); mutex_init(&ar_sdio->irq_data.mtx); + mutex_init(&ar_sdio->dma_buffer_mutex); INIT_LIST_HEAD(&ar_sdio->bus_req_freeq); INIT_LIST_HEAD(&ar_sdio->wr_asyncq); @@ -1995,7 +2045,7 @@ static int ath10k_sdio_probe(struct sdio_func *func, ar_sdio->workqueue = create_singlethread_workqueue("ath10k_sdio_wq"); if (!ar_sdio->workqueue) { ret = -ENOMEM; - goto err_free_bmi_buf; + goto err_dma; } for (i = 0; i < ATH10K_SDIO_BUS_REQUEST_MAX_NUM; i++) @@ -2040,6 +2090,8 @@ static int ath10k_sdio_probe(struct sdio_func *func, err_free_wq: destroy_workqueue(ar_sdio->workqueue); +err_dma: + kfree(ar_sdio->dma_buffer); err_free_bmi_buf: kfree(ar_sdio->bmi_buf); err_free_en_reg: @@ -2065,6 +2117,7 @@ static void ath10k_sdio_remove(struct sdio_func *func) cancel_work_sync(&ar_sdio->wr_async_work); ath10k_core_unregister(ar); ath10k_core_destroy(ar); + kfree(ar_sdio->dma_buffer); } static const struct sdio_device_id ath10k_sdio_devices[] = { diff --git a/drivers/net/wireless/ath/ath10k/sdio.h b/drivers/net/wireless/ath/ath10k/sdio.h index 4ff7b54..718b8b7 100644 --- a/drivers/net/wireless/ath/ath10k/sdio.h +++ b/drivers/net/wireless/ath/ath10k/sdio.h @@ -207,6 +207,11 @@ struct ath10k_sdio { struct ath10k *ar; struct ath10k_sdio_irq_data irq_data; + u8 *dma_buffer; + + /* protects access to dma_buffer */ + struct mutex dma_buffer_mutex; + /* temporary buffer for BMI requests */ u8 *bmi_buf;