From patchwork Tue Dec 2 18:11:11 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Emmanuel Grumbach X-Patchwork-Id: 5422611 Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 74A61BEEBA for ; Tue, 2 Dec 2014 18:12:14 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 740EB20253 for ; Tue, 2 Dec 2014 18:12:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5CB1A202B8 for ; Tue, 2 Dec 2014 18:12:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932850AbaLBSMI (ORCPT ); Tue, 2 Dec 2014 13:12:08 -0500 Received: from mail-wi0-f172.google.com ([209.85.212.172]:33760 "EHLO mail-wi0-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932795AbaLBSLw (ORCPT ); Tue, 2 Dec 2014 13:11:52 -0500 Received: by mail-wi0-f172.google.com with SMTP id n3so28814090wiv.17 for ; Tue, 02 Dec 2014 10:11:51 -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=yDCO3IuSz/ZSKilDnFZ6EZdiThKJV7jZjpsNc2c1fnI=; b=QJ5eU7R+7Hoel8Oex4adq8w/zlDke6z0oZRVrzVg5C3A1WjUFTwxJFn/52hT72lUzP S5GIFMKcRMO65k4yqaOBtf5SBNnZjrLcvu87QPbvpLQpdd+NaCwip1CXZLadabHyCYql wY/fdu/G9B+YamgdUvpI5hU0IlPl2+ntlXtkSP+YvxKRyjbeFVzEY7leAPx1HnS68sIh Zanns9I4gjLQrDzZkRKfDgOYCGKJDJbPAzkqlWbc8IoJhVU2Shfb7Jxmqf/OIsMQBlUx hIZt1p9+XLDdTd4uSc+KlEAi0oYbTsKK4WJqPVAumRp5t9rI0cqN6ECZ85JGPK2if99n By+Q== X-Received: by 10.180.208.69 with SMTP id mc5mr97322077wic.25.1417543911562; Tue, 02 Dec 2014 10:11:51 -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.50 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 02 Dec 2014 10:11:50 -0800 (PST) From: Emmanuel Grumbach To: linux-wireless@vger.kernel.org Cc: Emmanuel Grumbach , Subject: [PATCH 20/26] iwlwifi: dvm: fix flush support for old firmware Date: Tue, 2 Dec 2014 20:11:11 +0200 Message-Id: <1417543877-24193-20-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: Emmanuel Grumbach Since the commit below, iwldvm sends the FLUSH command to the firmware. All the devices that use iwldvm have a firmware that expects the _v3 version of this command, besides 5150. 5150's latest available firmware still expects a _v2 version of the FLUSH command. This means that since the commit below, we had a mismatch for this specific device only. This mismatch led to the NMI below: Loaded firmware version: 8.24.2.2 Start IWL Error Log Dump: Status: 0x0000004C, count: 5 0x00000004 | NMI_INTERRUPT_WDG 0x000006F4 | uPc 0x000005BA | branchlink1 0x000006F8 | branchlink2 0x000008C2 | interruptlink1 0x00005B02 | interruptlink2 0x00000002 | data1 0x07030000 | data2 0x00000068 | line 0x3E80510C | beacon time 0x728A0EF4 | tsf low 0x0000002A | tsf hi 0x00000000 | time gp1 0x01BDC977 | time gp2 0x00000000 | time gp3 0x00010818 | uCode version 0x00000000 | hw version 0x00484704 | board version 0x00000002 | hcmd 0x2FF23080 | isr0 0x0103E000 | isr1 0x0000001A | isr2 0x1443FCC3 | isr3 0x11800112 | isr4 0x00000068 | isr_pref 0x000000D4 | wait_event 0x00000000 | l2p_control 0x00000007 | l2p_duration 0x00103040 | l2p_mhvalid 0x00000007 | l2p_addr_match 0x00000000 | lmpm_pmg_sel 0x00000000 | timestamp 0x00000200 | flow_handler This was reported here: https://bugzilla.kernel.org/show_bug.cgi?id=88961 Cc: Fixes: a0855054e59b ("iwlwifi: dvm: drop non VO frames when flushing") Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/dvm/commands.h | 31 +++++++++++-------- drivers/net/wireless/iwlwifi/dvm/lib.c | 47 +++++++++++++++-------------- 2 files changed, 42 insertions(+), 36 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h index 751ae1d..7a34e4d 100644 --- a/drivers/net/wireless/iwlwifi/dvm/commands.h +++ b/drivers/net/wireless/iwlwifi/dvm/commands.h @@ -966,21 +966,21 @@ struct iwl_rem_sta_cmd { /* WiFi queues mask */ -#define IWL_SCD_BK_MSK cpu_to_le32(BIT(0)) -#define IWL_SCD_BE_MSK cpu_to_le32(BIT(1)) -#define IWL_SCD_VI_MSK cpu_to_le32(BIT(2)) -#define IWL_SCD_VO_MSK cpu_to_le32(BIT(3)) -#define IWL_SCD_MGMT_MSK cpu_to_le32(BIT(3)) +#define IWL_SCD_BK_MSK BIT(0) +#define IWL_SCD_BE_MSK BIT(1) +#define IWL_SCD_VI_MSK BIT(2) +#define IWL_SCD_VO_MSK BIT(3) +#define IWL_SCD_MGMT_MSK BIT(3) /* PAN queues mask */ -#define IWL_PAN_SCD_BK_MSK cpu_to_le32(BIT(4)) -#define IWL_PAN_SCD_BE_MSK cpu_to_le32(BIT(5)) -#define IWL_PAN_SCD_VI_MSK cpu_to_le32(BIT(6)) -#define IWL_PAN_SCD_VO_MSK cpu_to_le32(BIT(7)) -#define IWL_PAN_SCD_MGMT_MSK cpu_to_le32(BIT(7)) -#define IWL_PAN_SCD_MULTICAST_MSK cpu_to_le32(BIT(8)) +#define IWL_PAN_SCD_BK_MSK BIT(4) +#define IWL_PAN_SCD_BE_MSK BIT(5) +#define IWL_PAN_SCD_VI_MSK BIT(6) +#define IWL_PAN_SCD_VO_MSK BIT(7) +#define IWL_PAN_SCD_MGMT_MSK BIT(7) +#define IWL_PAN_SCD_MULTICAST_MSK BIT(8) -#define IWL_AGG_TX_QUEUE_MSK cpu_to_le32(0xffc00) +#define IWL_AGG_TX_QUEUE_MSK 0xffc00 #define IWL_DROP_ALL BIT(1) @@ -1005,12 +1005,17 @@ struct iwl_rem_sta_cmd { * 1: Dump multiple MSDU according to PS, INVALID STA, TTL, TID disable. * 2: Dump all FIFO */ -struct iwl_txfifo_flush_cmd { +struct iwl_txfifo_flush_cmd_v3 { __le32 queue_control; __le16 flush_control; __le16 reserved; } __packed; +struct iwl_txfifo_flush_cmd_v2 { + __le16 queue_control; + __le16 flush_control; +} __packed; + /* * REPLY_WEP_KEY = 0x20 */ diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c index 02e4ede..1d2223d 100644 --- a/drivers/net/wireless/iwlwifi/dvm/lib.c +++ b/drivers/net/wireless/iwlwifi/dvm/lib.c @@ -137,37 +137,38 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv, */ int iwlagn_txfifo_flush(struct iwl_priv *priv, u32 scd_q_msk) { - struct iwl_txfifo_flush_cmd flush_cmd; - struct iwl_host_cmd cmd = { - .id = REPLY_TXFIFO_FLUSH, - .len = { sizeof(struct iwl_txfifo_flush_cmd), }, - .data = { &flush_cmd, }, + struct iwl_txfifo_flush_cmd_v3 flush_cmd_v3 = { + .flush_control = cpu_to_le16(IWL_DROP_ALL), + }; + struct iwl_txfifo_flush_cmd_v2 flush_cmd_v2 = { + .flush_control = cpu_to_le16(IWL_DROP_ALL), }; - memset(&flush_cmd, 0, sizeof(flush_cmd)); + u32 queue_control = IWL_SCD_VO_MSK | IWL_SCD_VI_MSK | + IWL_SCD_BE_MSK | IWL_SCD_BK_MSK | IWL_SCD_MGMT_MSK; - flush_cmd.queue_control = IWL_SCD_VO_MSK | IWL_SCD_VI_MSK | - IWL_SCD_BE_MSK | IWL_SCD_BK_MSK | - IWL_SCD_MGMT_MSK; if ((priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))) - flush_cmd.queue_control |= IWL_PAN_SCD_VO_MSK | - IWL_PAN_SCD_VI_MSK | - IWL_PAN_SCD_BE_MSK | - IWL_PAN_SCD_BK_MSK | - IWL_PAN_SCD_MGMT_MSK | - IWL_PAN_SCD_MULTICAST_MSK; + queue_control |= IWL_PAN_SCD_VO_MSK | IWL_PAN_SCD_VI_MSK | + IWL_PAN_SCD_BE_MSK | IWL_PAN_SCD_BK_MSK | + IWL_PAN_SCD_MGMT_MSK | + IWL_PAN_SCD_MULTICAST_MSK; if (priv->nvm_data->sku_cap_11n_enable) - flush_cmd.queue_control |= IWL_AGG_TX_QUEUE_MSK; + queue_control |= IWL_AGG_TX_QUEUE_MSK; if (scd_q_msk) - flush_cmd.queue_control = cpu_to_le32(scd_q_msk); - - IWL_DEBUG_INFO(priv, "queue control: 0x%x\n", - flush_cmd.queue_control); - flush_cmd.flush_control = cpu_to_le16(IWL_DROP_ALL); - - return iwl_dvm_send_cmd(priv, &cmd); + queue_control = scd_q_msk; + + IWL_DEBUG_INFO(priv, "queue control: 0x%x\n", queue_control); + flush_cmd_v3.queue_control = cpu_to_le32(queue_control); + flush_cmd_v2.queue_control = cpu_to_le16((u16)queue_control); + + if (IWL_UCODE_API(priv->fw->ucode_ver) > 2) + return iwl_dvm_send_cmd_pdu(priv, REPLY_TXFIFO_FLUSH, 0, + sizeof(flush_cmd_v3), + &flush_cmd_v3); + return iwl_dvm_send_cmd_pdu(priv, REPLY_TXFIFO_FLUSH, 0, + sizeof(flush_cmd_v2), &flush_cmd_v2); } void iwlagn_dev_txfifo_flush(struct iwl_priv *priv)