From patchwork Tue Dec 2 18:11:07 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Emmanuel Grumbach X-Patchwork-Id: 5422591 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 D45379F319 for ; Tue, 2 Dec 2014 18:12:09 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B435420254 for ; Tue, 2 Dec 2014 18:12:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9248820253 for ; Tue, 2 Dec 2014 18:12:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932798AbaLBSLv (ORCPT ); Tue, 2 Dec 2014 13:11:51 -0500 Received: from mail-wg0-f48.google.com ([74.125.82.48]:59098 "EHLO mail-wg0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932795AbaLBSLs (ORCPT ); Tue, 2 Dec 2014 13:11:48 -0500 Received: by mail-wg0-f48.google.com with SMTP id y19so17758240wgg.7 for ; Tue, 02 Dec 2014 10:11:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=RoVPfT33qOBmJhHE0dY+UJ84RKr7pQnHI6R99yHtuo4=; b=G2HfGbPU3n9UwS0tZMkaZ7lfzA85I0jIGv5HZkDKjjP1RcgVMBUVU/bR8CijX9H9Vv TqCfO3C17o3n9RyPVWn/Up6eQOx8/SW1TJARZ8u9/Y8l1uUWioHGe3OWD4FQrcTWhOp+ 1POh2GUSxu7rkvjhV89sxvhuOO+5guSp14XZYQcoVEm/swb1PfnK9Iu6DE3bsgpash5M 2rZA1mU51RQgAiJYHSiKDnMip028GEHrXnIw0jx8vQXeXTItuTb2tis5bHaOd/pYGoqW OLPl9pMMjAEbKG22igwn5rZin8k/PV552L9UV2e4az8avVdk/0/Z8LpQ9/jqI30rV0H7 ksFQ== X-Received: by 10.194.58.8 with SMTP id m8mr735224wjq.43.1417543905587; Tue, 02 Dec 2014 10:11:45 -0800 (PST) Received: from localhost.localdomain (46-116-157-79.bb.netvision.net.il. [46.116.157.79]) by mx.google.com with ESMTPSA id j2sm32914384wjs.28.2014.12.02.10.11.44 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 02 Dec 2014 10:11:44 -0800 (PST) From: Emmanuel Grumbach To: linux-wireless@vger.kernel.org Cc: Eran Harary , Liad Kaufman , Emmanuel Grumbach Subject: [PATCH 16/26] iwlwifi: mvm: support ucode load for family_8000 B0 only Date: Tue, 2 Dec 2014 20:11:07 +0200 Message-Id: <1417543877-24193-16-git-send-email-egrumbach@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <0BA3FCBA62E2DC44AF3030971E174FB31B5A7D27@hasmsx107.ger.corp.intel.com> References: <0BA3FCBA62E2DC44AF3030971E174FB31B5A7D27@hasmsx107.ger.corp.intel.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_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, T_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: Eran Harary The ucode load flow changed for B0 hardware step. Change the code accordingly. Signed-off-by: Eran Harary Signed-off-by: Liad Kaufman Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-prph.h | 8 +- drivers/net/wireless/iwlwifi/pcie/trans.c | 135 +++++++++++++++--------------- 2 files changed, 72 insertions(+), 71 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index 1dae702..2df51ea 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -322,6 +322,7 @@ enum secure_boot_config_reg { LMPM_SECURE_BOOT_CONFIG_INSPECTOR_NOT_REQ = 0x00000002, }; +#define LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0 (0xA01E30) #define LMPM_SECURE_BOOT_CPU1_STATUS_ADDR (0x1E30) #define LMPM_SECURE_BOOT_CPU2_STATUS_ADDR (0x1E34) enum secure_boot_status_reg { @@ -333,6 +334,7 @@ enum secure_boot_status_reg { LMPM_SECURE_BOOT_STATUS_SUCCESS = 0x00000003, }; +#define FH_UCODE_LOAD_STATUS (0x1AF0) #define CSR_UCODE_LOAD_STATUS_ADDR (0x1E70) enum secure_load_status_reg { LMPM_CPU_UCODE_LOADING_STARTED = 0x00000001, @@ -349,10 +351,10 @@ enum secure_load_status_reg { #define LMPM_SECURE_INSPECTOR_CODE_MEM_SPACE (0x400000) #define LMPM_SECURE_INSPECTOR_DATA_MEM_SPACE (0x402000) -#define LMPM_SECURE_CPU1_HDR_MEM_SPACE (0x404000) -#define LMPM_SECURE_CPU2_HDR_MEM_SPACE (0x405000) +#define LMPM_SECURE_CPU1_HDR_MEM_SPACE (0x420000) +#define LMPM_SECURE_CPU2_HDR_MEM_SPACE (0x420400) -#define LMPM_SECURE_TIME_OUT (50000) /* 5 msec */ +#define LMPM_SECURE_TIME_OUT (100) /* 10 micro */ /* Rx FIFO */ #define RXF_SIZE_ADDR (0xa00c88) diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 7d7f05e..666925c 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -665,14 +665,14 @@ static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num, return ret; } -static int iwl_pcie_load_cpu_secured_sections(struct iwl_trans *trans, - const struct fw_img *image, - int cpu, - int *first_ucode_section) +static int iwl_pcie_load_cpu_sections_8000b(struct iwl_trans *trans, + const struct fw_img *image, + int cpu, + int *first_ucode_section) { int shift_param; - int i, ret = 0; - u32 last_read_idx = 0; + int i, ret = 0, sec_num = 0x1; + u32 val, last_read_idx = 0; if (cpu == 1) { shift_param = 0; @@ -693,21 +693,16 @@ static int iwl_pcie_load_cpu_secured_sections(struct iwl_trans *trans, break; } - if (i == (*first_ucode_section) + 1) - /* set CPU to started */ - iwl_set_bits_prph(trans, - CSR_UCODE_LOAD_STATUS_ADDR, - LMPM_CPU_HDRS_LOADING_COMPLETED - << shift_param); - ret = iwl_pcie_load_section(trans, i, &image->sec[i]); if (ret) return ret; + + /* Notify the ucode of the loaded section number and status */ + val = iwl_read_direct32(trans, FH_UCODE_LOAD_STATUS); + val = val | (sec_num << shift_param); + iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, val); + sec_num = (sec_num << 1) | 0x1; } - /* image loading complete */ - iwl_set_bits_prph(trans, - CSR_UCODE_LOAD_STATUS_ADDR, - LMPM_CPU_UCODE_LOADING_COMPLETED << shift_param); *first_ucode_section = last_read_idx; @@ -767,39 +762,13 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, int ret = 0; int first_ucode_section; - IWL_DEBUG_FW(trans, - "working with %s CPU\n", + IWL_DEBUG_FW(trans, "working with %s CPU\n", image->is_dual_cpus ? "Dual" : "Single"); - /* configure the ucode to be ready to get the secured image */ - if (iwl_has_secure_boot(trans->hw_rev, trans->cfg->device_family)) { - /* set secure boot inspector addresses */ - iwl_write_prph(trans, - LMPM_SECURE_INSPECTOR_CODE_ADDR, - LMPM_SECURE_INSPECTOR_CODE_MEM_SPACE); - - iwl_write_prph(trans, - LMPM_SECURE_INSPECTOR_DATA_ADDR, - LMPM_SECURE_INSPECTOR_DATA_MEM_SPACE); - - /* set CPU1 header address */ - iwl_write_prph(trans, - LMPM_SECURE_UCODE_LOAD_CPU1_HDR_ADDR, - LMPM_SECURE_CPU1_HDR_MEM_SPACE); - - /* load to FW the binary Secured sections of CPU1 */ - ret = iwl_pcie_load_cpu_secured_sections(trans, image, 1, - &first_ucode_section); - if (ret) - return ret; - - } else { - /* load to FW the binary Non secured sections of CPU1 */ - ret = iwl_pcie_load_cpu_sections(trans, image, 1, - &first_ucode_section); - if (ret) - return ret; - } + /* load to FW the binary non secured sections of CPU1 */ + ret = iwl_pcie_load_cpu_sections(trans, image, 1, &first_ucode_section); + if (ret) + return ret; if (image->is_dual_cpus) { /* set CPU2 header address */ @@ -808,14 +777,8 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, LMPM_SECURE_CPU2_HDR_MEM_SPACE); /* load to FW the binary sections of CPU2 */ - if (iwl_has_secure_boot(trans->hw_rev, - trans->cfg->device_family)) - ret = iwl_pcie_load_cpu_secured_sections( - trans, image, 2, - &first_ucode_section); - else - ret = iwl_pcie_load_cpu_sections(trans, image, 2, - &first_ucode_section); + ret = iwl_pcie_load_cpu_sections(trans, image, 2, + &first_ucode_section); if (ret) return ret; } @@ -840,18 +803,50 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, else iwl_write32(trans, CSR_RESET, 0); - if (iwl_has_secure_boot(trans->hw_rev, trans->cfg->device_family)) { - /* wait for image verification to complete */ - ret = iwl_poll_prph_bit(trans, - LMPM_SECURE_BOOT_CPU1_STATUS_ADDR, - LMPM_SECURE_BOOT_STATUS_SUCCESS, - LMPM_SECURE_BOOT_STATUS_SUCCESS, - LMPM_SECURE_TIME_OUT); + return 0; +} - if (ret < 0) { - IWL_ERR(trans, "Time out on secure boot process\n"); - return ret; - } +static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans, + const struct fw_img *image) +{ + int ret = 0; + int first_ucode_section; + u32 reg; + + IWL_DEBUG_FW(trans, "working with %s CPU\n", + image->is_dual_cpus ? "Dual" : "Single"); + + /* configure the ucode to be ready to get the secured image */ + /* release CPU reset */ + iwl_write_prph(trans, RELEASE_CPU_RESET, RELEASE_CPU_RESET_BIT); + + /* load to FW the binary Secured sections of CPU1 */ + ret = iwl_pcie_load_cpu_sections_8000b(trans, image, 1, + &first_ucode_section); + if (ret) + return ret; + + /* load to FW the binary sections of CPU2 */ + ret = iwl_pcie_load_cpu_sections_8000b(trans, image, 2, + &first_ucode_section); + if (ret) + return ret; + + /* Notify FW loading is done */ + iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, 0xFFFFFFFF); + + /* wait for image verification to complete */ + ret = iwl_poll_prph_bit(trans, LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0, + LMPM_SECURE_BOOT_STATUS_SUCCESS, + LMPM_SECURE_BOOT_STATUS_SUCCESS, + LMPM_SECURE_TIME_OUT); + if (ret < 0) { + reg = iwl_read_prph(trans, + LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0); + + IWL_ERR(trans, "Timeout on secure boot process, reg = %x\n", + reg); + return ret; } return 0; @@ -903,7 +898,11 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); /* Load the given image to the HW */ - return iwl_pcie_load_given_ucode(trans, fw); + if ((trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) && + (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_B_STEP)) + return iwl_pcie_load_given_ucode_8000b(trans, fw); + else + return iwl_pcie_load_given_ucode(trans, fw); } static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr)