Received: by 2002:ac0:a582:0:0:0:0:0 with SMTP id m2-v6csp2233545imm; Thu, 18 Oct 2018 11:07:16 -0700 (PDT) X-Google-Smtp-Source: ACcGV60LDMSLHOdQDhewdP4U9OhMnd+VCGh3SpD+Uajt5H48FsLSw+SnRFzmtnE0jIcepNRKt7pL X-Received: by 2002:a17:902:2808:: with SMTP id e8-v6mr30081018plb.327.1539886036605; Thu, 18 Oct 2018 11:07:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539886036; cv=none; d=google.com; s=arc-20160816; b=aMWq4/NATu1eRV5HheUAcECkkXksXPV50ZfSNg4XvnSzwuBGRtJEj3Xc1dJaDaxZ62 qyoJo8YyE037SyJt7sHmUfuHrymfA/bWraLsHHTcnl2uChImVauz253Zf4eXkM0ap8IJ wsPw/vNmzaJjKinlz6cE8PpY6nBV/5GepQ9iVNV8COnVIIAbqsYdM56z52rt8585tNAt +LbI3cVyOPTpxFW9rBmE7pABtDYBw7YNkbrYNG+wXg5Gv3mlI7rSUOjYwWWqfjO+Lb8t jwKnNHRLx64hhMXeJcsZ+ksp9rbVYiLV3FKJr01vjHTM0PgeZrB6ZMXXl4Jcj8g3n9Vz 4Ebw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=pY031XA1O+8B1e11lEmin++Dy+oeIoRaFzQKcAR3imk=; b=pSBacnEvHoNg/sKZRWyLDMdqXm9N9GiJFfxKxW2ZiqWT6DK/zljCeXzPSw591lZEMf NdALqpGlE07VPDJrskFTGtJD7rdaHRV8CCTWHQdi4QS+zaAUCAoFrNhkHJCzxftYQnFm gLymvGJ05kDQ2jyDAob9Fgw3aMm3NwdoU+5CgbsJ6vLVhhooJ+Rw00b421ur2h/ZxhXW olydHSdncohiHQWNc9zFo1U5DAEdGm4UUHMWrzepad2FWUQXx8Xy/htjh+a4FZv/uPLx 4TFFbeovki14txyiWEzbQ7m6TNsWfdmAgOnejGtj3HbQ3Z1DLoFTBtoi2SwllG3jBzX2 EezA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=G7akvF58; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g1-v6si21688701pgl.202.2018.10.18.11.07.01; Thu, 18 Oct 2018 11:07:16 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=G7akvF58; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730360AbeJSCH6 (ORCPT + 99 others); Thu, 18 Oct 2018 22:07:58 -0400 Received: from mail.kernel.org ([198.145.29.99]:56804 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726599AbeJSCH5 (ORCPT ); Thu, 18 Oct 2018 22:07:57 -0400 Received: from localhost (ip-213-127-77-176.ip.prioritytelecom.net [213.127.77.176]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id EEFEA2145D; Thu, 18 Oct 2018 18:05:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1539885949; bh=b/zkk728Mt4D3wBC2dw9ABLvsSxR4ZTIsmUf4F2XRP4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=G7akvF58v+HDjFoaUQgLNe5AWRPRPUZcIVrb6ORA8BnjWTZvyJqNFAe+hrpBoAT47 0ia+UANNT7z+OVJLEsN1OnM3CkgbFDlXwfbvIxPIC2cD8CjrzoZsFor2J0+MwzwpFj KfHT5kVyX+5tIwRalyjjBA6rj2mYXMjxP+zirdU8= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Shahed Shaikh , "David S. Miller" Subject: [PATCH 4.4 26/48] qlcnic: fix Tx descriptor corruption on 82xx devices Date: Thu, 18 Oct 2018 19:55:01 +0200 Message-Id: <20181018175429.397619045@linuxfoundation.org> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181018175427.133690306@linuxfoundation.org> References: <20181018175427.133690306@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.4-stable review patch. If anyone has any objections, please let me know. ------------------ From: Shahed Shaikh [ Upstream commit c333fa0c4f220f8f7ea5acd6b0ebf3bf13fd684d ] In regular NIC transmission flow, driver always configures MAC using Tx queue zero descriptor as a part of MAC learning flow. But with multi Tx queue supported NIC, regular transmission can occur on any non-zero Tx queue and from that context it uses Tx queue zero descriptor to configure MAC, at the same time TX queue zero could be used by another CPU for regular transmission which could lead to Tx queue zero descriptor corruption and cause FW abort. This patch fixes this in such a way that driver always configures learned MAC address from the same Tx queue which is used for regular transmission. Fixes: 7e2cf4feba05 ("qlcnic: change driver hardware interface mechanism") Signed-off-by: Shahed Shaikh Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 8 +++++--- drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 3 ++- drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 3 ++- drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h | 3 ++- drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | 12 ++++++------ 5 files changed, 17 insertions(+), 12 deletions(-) --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h @@ -1802,7 +1802,8 @@ struct qlcnic_hardware_ops { int (*config_loopback) (struct qlcnic_adapter *, u8); int (*clear_loopback) (struct qlcnic_adapter *, u8); int (*config_promisc_mode) (struct qlcnic_adapter *, u32); - void (*change_l2_filter) (struct qlcnic_adapter *, u64 *, u16); + void (*change_l2_filter)(struct qlcnic_adapter *adapter, u64 *addr, + u16 vlan, struct qlcnic_host_tx_ring *tx_ring); int (*get_board_info) (struct qlcnic_adapter *); void (*set_mac_filter_count) (struct qlcnic_adapter *); void (*free_mac_list) (struct qlcnic_adapter *); @@ -2044,9 +2045,10 @@ static inline int qlcnic_nic_set_promisc } static inline void qlcnic_change_filter(struct qlcnic_adapter *adapter, - u64 *addr, u16 id) + u64 *addr, u16 vlan, + struct qlcnic_host_tx_ring *tx_ring) { - adapter->ahw->hw_ops->change_l2_filter(adapter, addr, id); + adapter->ahw->hw_ops->change_l2_filter(adapter, addr, vlan, tx_ring); } static inline int qlcnic_get_board_info(struct qlcnic_adapter *adapter) --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c @@ -2132,7 +2132,8 @@ out: } void qlcnic_83xx_change_l2_filter(struct qlcnic_adapter *adapter, u64 *addr, - u16 vlan_id) + u16 vlan_id, + struct qlcnic_host_tx_ring *tx_ring) { u8 mac[ETH_ALEN]; memcpy(&mac, addr, ETH_ALEN); --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h @@ -550,7 +550,8 @@ int qlcnic_83xx_wrt_reg_indirect(struct int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *, u32); int qlcnic_83xx_config_hw_lro(struct qlcnic_adapter *, int); int qlcnic_83xx_config_rss(struct qlcnic_adapter *, int); -void qlcnic_83xx_change_l2_filter(struct qlcnic_adapter *, u64 *, u16); +void qlcnic_83xx_change_l2_filter(struct qlcnic_adapter *adapter, u64 *addr, + u16 vlan, struct qlcnic_host_tx_ring *ring); int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *, struct qlcnic_pci_info *); int qlcnic_83xx_set_nic_info(struct qlcnic_adapter *, struct qlcnic_info *); void qlcnic_83xx_initialize_nic(struct qlcnic_adapter *, int); --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h @@ -173,7 +173,8 @@ int qlcnic_82xx_napi_add(struct qlcnic_a struct net_device *netdev); void qlcnic_82xx_get_beacon_state(struct qlcnic_adapter *); void qlcnic_82xx_change_filter(struct qlcnic_adapter *adapter, - u64 *uaddr, u16 vlan_id); + u64 *uaddr, u16 vlan_id, + struct qlcnic_host_tx_ring *tx_ring); int qlcnic_82xx_config_intr_coalesce(struct qlcnic_adapter *, struct ethtool_coalesce *); int qlcnic_82xx_set_rx_coalesce(struct qlcnic_adapter *); --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c @@ -269,13 +269,12 @@ static void qlcnic_add_lb_filter(struct } void qlcnic_82xx_change_filter(struct qlcnic_adapter *adapter, u64 *uaddr, - u16 vlan_id) + u16 vlan_id, struct qlcnic_host_tx_ring *tx_ring) { struct cmd_desc_type0 *hwdesc; struct qlcnic_nic_req *req; struct qlcnic_mac_req *mac_req; struct qlcnic_vlan_req *vlan_req; - struct qlcnic_host_tx_ring *tx_ring = adapter->tx_ring; u32 producer; u64 word; @@ -302,7 +301,8 @@ void qlcnic_82xx_change_filter(struct ql static void qlcnic_send_filter(struct qlcnic_adapter *adapter, struct cmd_desc_type0 *first_desc, - struct sk_buff *skb) + struct sk_buff *skb, + struct qlcnic_host_tx_ring *tx_ring) { struct vlan_ethhdr *vh = (struct vlan_ethhdr *)(skb->data); struct ethhdr *phdr = (struct ethhdr *)(skb->data); @@ -336,7 +336,7 @@ static void qlcnic_send_filter(struct ql tmp_fil->vlan_id == vlan_id) { if (jiffies > (QLCNIC_READD_AGE * HZ + tmp_fil->ftime)) qlcnic_change_filter(adapter, &src_addr, - vlan_id); + vlan_id, tx_ring); tmp_fil->ftime = jiffies; return; } @@ -351,7 +351,7 @@ static void qlcnic_send_filter(struct ql if (!fil) return; - qlcnic_change_filter(adapter, &src_addr, vlan_id); + qlcnic_change_filter(adapter, &src_addr, vlan_id, tx_ring); fil->ftime = jiffies; fil->vlan_id = vlan_id; memcpy(fil->faddr, &src_addr, ETH_ALEN); @@ -767,7 +767,7 @@ netdev_tx_t qlcnic_xmit_frame(struct sk_ } if (adapter->drv_mac_learn) - qlcnic_send_filter(adapter, first_desc, skb); + qlcnic_send_filter(adapter, first_desc, skb, tx_ring); tx_ring->tx_stats.tx_bytes += skb->len; tx_ring->tx_stats.xmit_called++;