From patchwork Tue Nov 25 10:24:48 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kalle Valo X-Patchwork-Id: 5374901 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.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id A22789F2F5 for ; Tue, 25 Nov 2014 10:25:20 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id F109F201CD for ; Tue, 25 Nov 2014 10:25:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 23EC9201DD for ; Tue, 25 Nov 2014 10:25:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752141AbaKYKZH (ORCPT ); Tue, 25 Nov 2014 05:25:07 -0500 Received: from wolverine02.qualcomm.com ([199.106.114.251]:28773 "EHLO wolverine02.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752098AbaKYKZF (ORCPT ); Tue, 25 Nov 2014 05:25:05 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=qca.qualcomm.com; i=@qca.qualcomm.com; q=dns/txt; s=qcdkim; t=1416911105; x=1448447105; h=subject:to:from:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=qDNg+Ab5XzvuTNc/6ZhRhHiYbCs7FIaH3aYZK1jZZls=; b=rGxVKYE6eJQqY7zxjZ6/CiQhPgoihG421pQKyXuoo/l2LGUgU1qm083o V5y/Th6V8g1DeZB8eTW0J/oaRAfMs3Lz9fTK8Xtq3kkYF0vhJLjVj7n8B DHwamJ6t9uZy1rmS+a0s9KpNc80G3RyFE02SPgClzv9me/NKgvSYTX3n2 Y=; X-IronPort-AV: E=McAfee;i="5600,1067,7632"; a="179825484" Received: from ironmsg03-r.qualcomm.com ([172.30.46.17]) by wolverine02.qualcomm.com with ESMTP/TLS/DHE-RSA-AES256-SHA; 25 Nov 2014 02:25:05 -0800 X-IronPort-AV: E=Sophos;i="5.07,455,1413270000"; d="scan'208";a="798598221" Received: from nasanexm01g.na.qualcomm.com ([10.85.0.33]) by Ironmsg03-R.qualcomm.com with ESMTP/TLS/RC4-SHA; 25 Nov 2014 02:25:04 -0800 Received: from potku.adurom.net (10.80.80.8) by NASANEXM01G.na.qualcomm.com (10.85.0.33) with Microsoft SMTP Server (TLS) id 15.0.913.22; Tue, 25 Nov 2014 02:25:03 -0800 Subject: [PATCH v3 2/2] ath10k: add memory dump debugfs interface To: From: Kalle Valo CC: Date: Tue, 25 Nov 2014 12:24:48 +0200 Message-ID: <20141125102448.3951.97429.stgit@potku.adurom.net> In-Reply-To: <20141125102302.3951.10641.stgit@potku.adurom.net> References: <20141125102302.3951.10641.stgit@potku.adurom.net> User-Agent: StGit/0.15 MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: NASANEXM01H.na.qualcomm.com (10.85.0.34) To NASANEXM01G.na.qualcomm.com (10.85.0.33) 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,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 From: Yanbo Li Add mem_val debugfs file for dumping the firmware (target) memory and also for writing to the memory. The firmware memory is accessed through one file which uses position of the file as the firmware memory address. For example, with dd use skip parameter for the address. Beucase target memory width is 32 bits it's strongly recommended to use blocksize divisable with 4 when using this interface. For example, when using dd use bs=4 to set the block size to 4 and remember to divide both count and skip values with four. To read 4 kB chunk from address 0x400000: dd if=mem_value bs=4 count=1024 skip=1048576 | xxd -g1 To write value 0x01020304 to address 0x400400: echo 0x01020304 | xxd -r | dd of=mem_value bs=4 seek=1048832 To read 4 KB chunk of memory and then write back after edit: dd if=mem_value of=tmp.bin bs=4 count=1024 skip=1048576 emacs tmp.bin dd if=tmp.bin of=mem_value bs=4 count=1024 seek=1048576 Signed-off-by: Yanbo Li Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/debug.c | 114 +++++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath10k/hif.h | 11 +++ drivers/net/wireless/ath/ath10k/pci.c | 1 3 files changed, 126 insertions(+) -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index d0397d119862..ff831ca507f7 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -1047,6 +1047,117 @@ static const struct file_operations fops_reg_value = { .llseek = default_llseek, }; +static ssize_t ath10k_mem_value_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath10k *ar = file->private_data; + u8 *buf; + int ret; + + if (*ppos < 0) + return -EINVAL; + + if (!count) + return 0; + + mutex_lock(&ar->conf_mutex); + + buf = vmalloc(count); + if (!buf) { + ret = -ENOMEM; + goto exit; + } + + if (ar->state != ATH10K_STATE_ON && + ar->state != ATH10K_STATE_UTF) { + ret = -ENETDOWN; + goto exit; + } + + ret = ath10k_hif_diag_read(ar, *ppos, buf, count); + if (ret) { + ath10k_warn(ar, "failed to read address 0x%08x via diagnose window fnrom debugfs: %d\n", + (u32)(*ppos), ret); + goto exit; + } + + ret = copy_to_user(user_buf, buf, count); + if (ret) { + ret = -EFAULT; + goto exit; + } + + count -= ret; + *ppos += count; + ret = count; + +exit: + vfree(buf); + mutex_unlock(&ar->conf_mutex); + + return ret; +} + +static ssize_t ath10k_mem_value_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath10k *ar = file->private_data; + u8 *buf; + int ret; + + if (*ppos < 0) + return -EINVAL; + + if (!count) + return 0; + + mutex_lock(&ar->conf_mutex); + + buf = vmalloc(count); + if (!buf) { + ret = -ENOMEM; + goto exit; + } + + if (ar->state != ATH10K_STATE_ON && + ar->state != ATH10K_STATE_UTF) { + ret = -ENETDOWN; + goto exit; + } + + ret = copy_from_user(buf, user_buf, count); + if (ret) { + ret = -EFAULT; + goto exit; + } + + ret = ath10k_hif_diag_write(ar, *ppos, buf, count); + if (ret) { + ath10k_warn(ar, "failed to write address 0x%08x via diagnose window from debugfs: %d\n", + (u32)(*ppos), ret); + goto exit; + } + + *ppos += count; + ret = count; + +exit: + vfree(buf); + mutex_unlock(&ar->conf_mutex); + + return ret; +} + +static const struct file_operations fops_mem_value = { + .read = ath10k_mem_value_read, + .write = ath10k_mem_value_write, + .open = simple_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + static int ath10k_debug_htt_stats_req(struct ath10k *ar) { u64 cookie; @@ -1754,6 +1865,9 @@ int ath10k_debug_register(struct ath10k *ar) debugfs_create_file("reg_value", S_IRUSR | S_IWUSR, ar->debug.debugfs_phy, ar, &fops_reg_value); + debugfs_create_file("mem_value", S_IRUSR | S_IWUSR, + ar->debug.debugfs_phy, ar, &fops_mem_value); + debugfs_create_file("chip_id", S_IRUSR, ar->debug.debugfs_phy, ar, &fops_chip_id); diff --git a/drivers/net/wireless/ath/ath10k/hif.h b/drivers/net/wireless/ath/ath10k/hif.h index bad071906540..6ac552304546 100644 --- a/drivers/net/wireless/ath/ath10k/hif.h +++ b/drivers/net/wireless/ath/ath10k/hif.h @@ -48,6 +48,8 @@ struct ath10k_hif_ops { int (*diag_read)(struct ath10k *ar, u32 address, void *buf, size_t buf_len); + int (*diag_write)(struct ath10k *ar, u32 address, const void *data, + int nbytes); /* * API to handle HIF-specific BMI message exchanges, this API is * synchronous and only allowed to be called from a context that @@ -113,6 +115,15 @@ static inline int ath10k_hif_diag_read(struct ath10k *ar, u32 address, void *buf return ar->hif.ops->diag_read(ar, address, buf, buf_len); } +static inline int ath10k_hif_diag_write(struct ath10k *ar, u32 address, + const void *data, int nbytes) +{ + if (!ar->hif.ops->diag_write) + return -EOPNOTSUPP; + + return ar->hif.ops->diag_write(ar, address, data, nbytes); +} + static inline int ath10k_hif_exchange_bmi_msg(struct ath10k *ar, void *request, u32 request_len, void *response, u32 *response_len) diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 328ab6c5d053..0816098af578 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -1988,6 +1988,7 @@ static int ath10k_pci_hif_resume(struct ath10k *ar) static const struct ath10k_hif_ops ath10k_pci_hif_ops = { .tx_sg = ath10k_pci_hif_tx_sg, .diag_read = ath10k_pci_hif_diag_read, + .diag_write = ath10k_pci_diag_write_mem, .exchange_bmi_msg = ath10k_pci_hif_exchange_bmi_msg, .start = ath10k_pci_hif_start, .stop = ath10k_pci_hif_stop,