From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.1 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C4515C4360F for ; Thu, 28 Feb 2019 06:39:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9456820842 for ; Thu, 28 Feb 2019 06:39:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="l3liDsch" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730977AbfB1GjZ (ORCPT ); Thu, 28 Feb 2019 01:39:25 -0500 Received: from mail-wm1-f66.google.com ([209.85.128.66]:34476 "EHLO mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725862AbfB1GjY (ORCPT ); Thu, 28 Feb 2019 01:39:24 -0500 Received: by mail-wm1-f66.google.com with SMTP id o10so5908676wmc.1 for ; Wed, 27 Feb 2019 22:39:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:subject:to:cc:message-id:date:user-agent:mime-version :content-language:content-transfer-encoding; bh=KNO+d0fW8iLDo4cGOlaVc+sNkzH1J6SgrmSlrSh/+jU=; b=l3liDschW9xeFxFIuofLI79uU3hYUOEiV6L6IirJ7zxhtCOMW5w/fpcJg0gQfIuG9I AWwVnDxkT9ROHVWvVaqGy12hEQ8MDsOjOKN1BhY1Vq24iwScCdW3SB8eRKVf1yPDu0S9 s1DdaOPuNwVBgDxnU1SukUcRWjhCYRLVfzF9EbqkUoCbjkcSC0OBSkyrADkwFJ/7aC2Z wR7hW2BYX3aPXmXEIW7QBdJQ1L81sD2D247GFm25OuiiJL6jvqrke9gy7HLB89Au8IYy I0ElJ1R3sP6m2D7e8xR2/EW4Jt4LnrNZKoxZN4Y0b5pm9htZ18l3KYstD4pz5a/kVKn+ 9SIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:subject:to:cc:message-id:date:user-agent :mime-version:content-language:content-transfer-encoding; bh=KNO+d0fW8iLDo4cGOlaVc+sNkzH1J6SgrmSlrSh/+jU=; b=qD+YHGI6+cgUkJK6TFn+GDQTp95wnxPIBkukrx4j/yN6WtQ8152iD2W5K1mdYkxQLr j5fpbRyVTJZ0zhiA8wBL5CxqmzIhCPKtojf4VE+MbQgHxV6f/Wr6FZslHbfo+AVzPKj7 Omq2MqPgiuyeJnvcaEt7+X0wB+3/sVI+qYTrnu8SeDxJM0NafnYEZdCchA6Olr/E2FiK Q5Kwwul1y2vCOUe1Qw58KcL3WVDLz4kE47MNipKmAE0BBK6Ab2V0evJJJGqo1Hzm0Act 5ktMKNlXJnQkQTugDSYbGOkWSGKfZq06gvaxhFVqHopKn3DZeNAMa0LPcbVXChQKpmhy ntdQ== X-Gm-Message-State: AHQUAuYOkwylV1V3HxCEe8e9SjYFfK7t2+ibEDG2TyLddvUwIdguYK0f EQL0iyVCT/2huRdbeKoxiDXZdJk1 X-Google-Smtp-Source: APXvYqzTNGKlYt799n0pA3UpVR1GPGBHnTDFSPpGoK4ny2bpuc5quNiuj2bjPF6Kv9q8s+WX2LW50Q== X-Received: by 2002:a1c:44d7:: with SMTP id r206mr1797304wma.40.1551335961766; Wed, 27 Feb 2019 22:39:21 -0800 (PST) Received: from ?IPv6:2003:ea:8bf1:e200:b0d0:4bc1:6d3d:7117? (p200300EA8BF1E200B0D04BC16D3D7117.dip0.t-ipconnect.de. [2003:ea:8bf1:e200:b0d0:4bc1:6d3d:7117]) by smtp.googlemail.com with ESMTPSA id z10sm2306105wml.39.2019.02.27.22.39.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 27 Feb 2019 22:39:20 -0800 (PST) From: Heiner Kallweit Subject: [PATCH v2 net] net: dsa: mv88e6xxx: prevent interrupt storm caused by mv88e6390x_port_set_cmode To: Vivien Didelot , Andrew Lunn , Florian Fainelli , David Miller Cc: "netdev@vger.kernel.org" Message-ID: Date: Thu, 28 Feb 2019 07:39:15 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.5.1 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org When debugging another issue I faced an interrupt storm in this driver (88E6390, port 9 in SGMII mode), consisting of alternating link-up / link-down interrupts. Analysis showed that the driver wanted to set a cmode that was set already. But so far mv88e6390x_port_set_cmode() doesn't check this and powers down SERDES, what causes the link to break, and eventually results in the described interrupt storm. Fix this by checking whether the cmode actually changes. We want that the very first call to mv88e6390x_port_set_cmode() always configures the registers, therefore initialize port.cmode with a value that is different from any supported cmode value. We have to take care that we only init the ports cmode once chip->info->num_ports is set. v2: - add small helper and init the number of actual ports only Fixes: 364e9d7776a3 ("net: dsa: mv88e6xxx: Power on/off SERDES on cmode change") Signed-off-by: Heiner Kallweit --- drivers/net/dsa/mv88e6xxx/chip.c | 10 ++++++++++ drivers/net/dsa/mv88e6xxx/port.c | 4 ++++ drivers/net/dsa/mv88e6xxx/port.h | 1 + 3 files changed, 15 insertions(+) diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index a3a2eb985..f1f228af0 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -4620,6 +4620,14 @@ static int mv88e6xxx_smi_init(struct mv88e6xxx_chip *chip, return 0; } +static void mv88e6xxx_ports_cmode_init(struct mv88e6xxx_chip *chip) +{ + int i; + + for (i = 0; i < mv88e6xxx_num_ports(chip); i++) + chip->ports[i].cmode = MV88E6XXX_PORT_STS_CMODE_INVALID; +} + static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds, int port) { @@ -4656,6 +4664,8 @@ static const char *mv88e6xxx_drv_probe(struct device *dsa_dev, if (err) goto free; + mv88e6xxx_ports_cmode_init(chip); + mutex_lock(&chip->reg_lock); err = mv88e6xxx_switch_reset(chip); mutex_unlock(&chip->reg_lock); diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c index ee7029f4e..e12e0bdfc 100644 --- a/drivers/net/dsa/mv88e6xxx/port.c +++ b/drivers/net/dsa/mv88e6xxx/port.c @@ -398,6 +398,10 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, cmode = 0; } + /* cmode doesn't change, nothing to do for us */ + if (cmode == chip->ports[port].cmode) + return 0; + lane = mv88e6390x_serdes_get_lane(chip, port); if (lane < 0) return lane; diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h index e583641de..4aadf321e 100644 --- a/drivers/net/dsa/mv88e6xxx/port.h +++ b/drivers/net/dsa/mv88e6xxx/port.h @@ -52,6 +52,7 @@ #define MV88E6185_PORT_STS_CMODE_1000BASE_X 0x0005 #define MV88E6185_PORT_STS_CMODE_PHY 0x0006 #define MV88E6185_PORT_STS_CMODE_DISABLED 0x0007 +#define MV88E6XXX_PORT_STS_CMODE_INVALID 0xff /* Offset 0x01: MAC (or PCS or Physical) Control Register */ #define MV88E6XXX_PORT_MAC_CTL 0x01 -- 2.21.0