From patchwork Fri Jul 31 14:17:40 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amitkumar Karwar X-Patchwork-Id: 6913151 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 ADFD19F39D for ; Fri, 31 Jul 2015 14:18:17 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 833AD204A9 for ; Fri, 31 Jul 2015 14:18:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4D714205BA for ; Fri, 31 Jul 2015 14:18:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754688AbbGaOSK (ORCPT ); Fri, 31 Jul 2015 10:18:10 -0400 Received: from mx0a-0016f401.pphosted.com ([67.231.148.174]:54703 "EHLO mx0a-0016f401.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752406AbbGaOSH (ORCPT ); Fri, 31 Jul 2015 10:18:07 -0400 Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.15.0.59/8.15.0.59) with SMTP id t6VEF6VW023617 for ; Fri, 31 Jul 2015 07:18:06 -0700 Received: from sc-exch01.marvell.com ([199.233.58.181]) by mx0a-0016f401.pphosted.com with ESMTP id 1vv91rusds-1 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT) for ; Fri, 31 Jul 2015 07:18:06 -0700 Received: from SC-EXCH01.marvell.com (10.93.176.81) by SC-EXCH01.marvell.com (10.93.176.81) with Microsoft SMTP Server (TLS) id 15.0.1044.25; Fri, 31 Jul 2015 07:18:05 -0700 Received: from maili.marvell.com (10.93.176.43) by SC-EXCH01.marvell.com (10.93.176.81) with Microsoft SMTP Server id 15.0.1044.25 via Frontend Transport; Fri, 31 Jul 2015 07:18:05 -0700 Received: from pe-lt101 (unknown [10.31.130.100]) by maili.marvell.com (Postfix) with ESMTP id 3768F3F703F; Fri, 31 Jul 2015 07:18:04 -0700 (PDT) Received: from pe-lt101 (pe-lt077 [127.0.0.1]) by pe-lt101 (8.14.4/8.14.4) with ESMTP id t6VEHide031823; Fri, 31 Jul 2015 07:17:44 -0700 Received: (from root@localhost) by pe-lt101 (8.14.4/8.14.4/Submit) id t6VEHiiD031822; Fri, 31 Jul 2015 07:17:44 -0700 From: Amitkumar Karwar To: CC: Cathy Luo , Zhaoyang Liu , Amitkumar Karwar Subject: [PATCH 2/3] mwifiex: add firmware dump support for SD8997 Date: Fri, 31 Jul 2015 07:17:40 -0700 Message-ID: <1438352260-31794-1-git-send-email-akarwar@marvell.com> X-Mailer: git-send-email 1.7.3.4 MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2015-07-31_08:, , signatures=0 X-Proofpoint-Spam-Details: rule=inbound_notspam policy=inbound score=0 kscore.is_bulkscore=0 kscore.compositescore=1 compositescore=0.9 suspectscore=1 malwarescore=0 phishscore=0 bulkscore=0 kscore.is_spamscore=0 rbsscore=0.9 spamscore=0 urlsuspectscore=0.9 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1506180000 definitions=main-1507310237 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Spam-Status: No, score=-8.3 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, 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 From: Zhaoyang Liu This patch adds firmware dump feature for SD8997 chipset. The difference here is only one memory type is needed to save all firmware information. Device dump information will be uploaded to usersapace file. Signed-off-by: Zhaoyang Liu Signed-off-by: Cathy Luo Signed-off-by: Amitkumar Karwar --- drivers/net/wireless/mwifiex/sdio.c | 147 +++++++++++++++++++++++++++++++++--- drivers/net/wireless/mwifiex/sdio.h | 11 ++- 2 files changed, 148 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index 9904a77..7cef27e9 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -51,6 +51,10 @@ static unsigned long iface_work_flags; static struct semaphore add_remove_card_sem; +static struct memory_type_mapping generic_mem_type_map[] = { + {"DUMP", NULL, 0, 0xDD}, +}; + static struct memory_type_mapping mem_type_mapping_tbl[] = { {"ITCM", NULL, 0, 0xF0}, {"DTCM", NULL, 0, 0xF1}, @@ -108,6 +112,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) card->mp_tx_agg_buf_size = data->mp_tx_agg_buf_size; card->mp_rx_agg_buf_size = data->mp_rx_agg_buf_size; card->can_dump_fw = data->can_dump_fw; + card->fw_dump_enh = data->fw_dump_enh; card->can_auto_tdls = data->can_auto_tdls; card->can_ext_scan = data->can_ext_scan; } @@ -1969,8 +1974,13 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) adapter->dev = &func->dev; strcpy(adapter->fw_name, card->firmware); - adapter->mem_type_mapping_tbl = mem_type_mapping_tbl; - adapter->num_mem_types = ARRAY_SIZE(mem_type_mapping_tbl); + if (card->fw_dump_enh) { + adapter->mem_type_mapping_tbl = generic_mem_type_map; + adapter->num_mem_types = 1; + } else { + adapter->mem_type_mapping_tbl = mem_type_mapping_tbl; + adapter->num_mem_types = ARRAY_SIZE(mem_type_mapping_tbl); + } return 0; } @@ -2163,8 +2173,8 @@ rdwr_status mwifiex_sdio_rdwr_firmware(struct mwifiex_adapter *adapter, int ret, tries; u8 ctrl_data = 0; - sdio_writeb(card->func, FW_DUMP_HOST_READY, card->reg->fw_dump_ctrl, - &ret); + sdio_writeb(card->func, card->reg->fw_dump_host_ready, + card->reg->fw_dump_ctrl, &ret); if (ret) { mwifiex_dbg(adapter, ERROR, "SDIO Write ERR\n"); return RDWR_STATUS_FAILURE; @@ -2180,10 +2190,10 @@ rdwr_status mwifiex_sdio_rdwr_firmware(struct mwifiex_adapter *adapter, break; if (doneflag && ctrl_data == doneflag) return RDWR_STATUS_DONE; - if (ctrl_data != FW_DUMP_HOST_READY) { + if (ctrl_data != card->reg->fw_dump_host_ready) { mwifiex_dbg(adapter, WARN, - "The ctrl reg was changed, re-try again!\n"); - sdio_writeb(card->func, FW_DUMP_HOST_READY, + "The ctrl reg was changed, re-try again\n"); + sdio_writeb(card->func, card->reg->fw_dump_host_ready, card->reg->fw_dump_ctrl, &ret); if (ret) { mwifiex_dbg(adapter, ERROR, "SDIO write err\n"); @@ -2192,7 +2202,7 @@ rdwr_status mwifiex_sdio_rdwr_firmware(struct mwifiex_adapter *adapter, } usleep_range(100, 200); } - if (ctrl_data == FW_DUMP_HOST_READY) { + if (ctrl_data == card->reg->fw_dump_host_ready) { mwifiex_dbg(adapter, ERROR, "Fail to pull ctrl_data\n"); return RDWR_STATUS_FAILURE; @@ -2325,10 +2335,129 @@ done: sdio_release_host(card->func); } +static void mwifiex_sdio_generic_fw_dump(struct mwifiex_adapter *adapter) +{ + struct sdio_mmc_card *card = adapter->card; + struct memory_type_mapping *entry = &generic_mem_type_map[0]; + unsigned int reg, reg_start, reg_end; + u8 start_flag = 0, done_flag = 0; + u8 *dbg_ptr, *end_ptr; + enum rdwr_status stat; + int ret = -1, tries; + + if (!card->fw_dump_enh) + return; + + if (entry->mem_ptr) { + vfree(entry->mem_ptr); + entry->mem_ptr = NULL; + } + entry->mem_size = 0; + + mwifiex_pm_wakeup_card(adapter); + sdio_claim_host(card->func); + + mwifiex_dbg(adapter, MSG, "== mwifiex firmware dump start ==\n"); + + stat = mwifiex_sdio_rdwr_firmware(adapter, done_flag); + if (stat == RDWR_STATUS_FAILURE) + goto done; + + reg_start = card->reg->fw_dump_start; + reg_end = card->reg->fw_dump_end; + for (reg = reg_start; reg <= reg_end; reg++) { + for (tries = 0; tries < MAX_POLL_TRIES; tries++) { + start_flag = sdio_readb(card->func, reg, &ret); + if (ret) { + mwifiex_dbg(adapter, ERROR, + "SDIO read err\n"); + goto done; + } + if (start_flag == 0) + break; + if (tries == MAX_POLL_TRIES) { + mwifiex_dbg(adapter, ERROR, + "FW not ready to dump\n"); + ret = -1; + goto done; + } + } + usleep_range(100, 200); + } + + entry->mem_ptr = vmalloc(0xf0000 + 1); + if (!entry->mem_ptr) { + ret = -1; + goto done; + } + dbg_ptr = entry->mem_ptr; + entry->mem_size = 0xf0000; + end_ptr = dbg_ptr + entry->mem_size; + + done_flag = entry->done_flag; + mwifiex_dbg(adapter, DUMP, + "Start %s output, please wait...\n", entry->mem_name); + + while (true) { + stat = mwifiex_sdio_rdwr_firmware(adapter, done_flag); + if (stat == RDWR_STATUS_FAILURE) + goto done; + for (reg = reg_start; reg <= reg_end; reg++) { + *dbg_ptr = sdio_readb(card->func, reg, &ret); + if (ret) { + mwifiex_dbg(adapter, ERROR, + "SDIO read err\n"); + goto done; + } + dbg_ptr++; + if (dbg_ptr >= end_ptr) { + u8 *tmp_ptr; + + tmp_ptr = vmalloc(entry->mem_size + 0x4000 + 1); + if (!tmp_ptr) + goto done; + + memcpy(tmp_ptr, entry->mem_ptr, + entry->mem_size); + vfree(entry->mem_ptr); + entry->mem_ptr = tmp_ptr; + tmp_ptr = NULL; + dbg_ptr = entry->mem_ptr + entry->mem_size; + entry->mem_size += 0x4000; + end_ptr = entry->mem_ptr + entry->mem_size; + } + } + if (stat == RDWR_STATUS_DONE) { + entry->mem_size = dbg_ptr - entry->mem_ptr; + mwifiex_dbg(adapter, DUMP, "dump %s done size=0x%x\n", + entry->mem_name, entry->mem_size); + ret = 0; + break; + } + } + mwifiex_dbg(adapter, MSG, "== mwifiex firmware dump end ==\n"); + +done: + if (ret) { + mwifiex_dbg(adapter, ERROR, "firmware dump failed\n"); + if (entry->mem_ptr) { + vfree(entry->mem_ptr); + entry->mem_ptr = NULL; + } + entry->mem_size = 0; + } + sdio_release_host(card->func); +} + static void mwifiex_sdio_device_dump_work(struct mwifiex_adapter *adapter) { + struct sdio_mmc_card *card = adapter->card; + mwifiex_drv_info_dump(adapter); - mwifiex_sdio_fw_dump(adapter); + if (card->fw_dump_enh) + mwifiex_sdio_generic_fw_dump(adapter); + else + mwifiex_sdio_fw_dump(adapter); mwifiex_upload_device_dump(adapter); } diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h index cd149196..b9fbc5c 100644 --- a/drivers/net/wireless/mwifiex/sdio.h +++ b/drivers/net/wireless/mwifiex/sdio.h @@ -223,6 +223,7 @@ struct mwifiex_sdio_card_reg { u8 cmd_cfg_1; u8 cmd_cfg_2; u8 cmd_cfg_3; + u8 fw_dump_host_ready; u8 fw_dump_ctrl; u8 fw_dump_start; u8 fw_dump_end; @@ -258,6 +259,7 @@ struct sdio_mmc_card { bool supports_sdio_new_mode; bool has_control_mask; bool can_dump_fw; + bool fw_dump_enh; bool can_auto_tdls; bool can_ext_scan; @@ -279,6 +281,7 @@ struct mwifiex_sdio_device { bool supports_sdio_new_mode; bool has_control_mask; bool can_dump_fw; + bool fw_dump_enh; bool can_auto_tdls; bool can_ext_scan; }; @@ -354,6 +357,7 @@ static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8897 = { .cmd_cfg_1 = 0xb9, .cmd_cfg_2 = 0xba, .cmd_cfg_3 = 0xbb, + .fw_dump_host_ready = 0xee, .fw_dump_ctrl = 0xe2, .fw_dump_start = 0xe3, .fw_dump_end = 0xea, @@ -404,6 +408,10 @@ static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8997 = { .cmd_cfg_1 = 0xc5, .cmd_cfg_2 = 0xc6, .cmd_cfg_3 = 0xc7, + .fw_dump_host_ready = 0xcc, + .fw_dump_ctrl = 0xf0, + .fw_dump_start = 0xf1, + .fw_dump_end = 0xf8, .func1_dump_reg_start = 0x10, .func1_dump_reg_end = 0x17, .func1_scratch_reg = 0xe8, @@ -532,7 +540,8 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8997 = { .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_MAX, .supports_sdio_new_mode = true, .has_control_mask = false, - .can_dump_fw = false, + .can_dump_fw = true, + .fw_dump_enh = true, .can_auto_tdls = false, .can_ext_scan = true, };