From patchwork Mon Aug 26 21:31:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 1153461 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nic.cz Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=nic.cz header.i=@nic.cz header.b="Us4CVRwd"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 46HQFL1KR7z9sN6 for ; Tue, 27 Aug 2019 07:32:06 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728877AbfHZVcD (ORCPT ); Mon, 26 Aug 2019 17:32:03 -0400 Received: from mail.nic.cz ([217.31.204.67]:35088 "EHLO mail.nic.cz" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728803AbfHZVcC (ORCPT ); Mon, 26 Aug 2019 17:32:02 -0400 Received: from dellmb.labs.office.nic.cz (unknown [IPv6:2001:1488:fffe:6:cac7:3539:7f1f:463]) by mail.nic.cz (Postfix) with ESMTP id 02CE0140AFA; Mon, 26 Aug 2019 23:31:59 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=nic.cz; s=default; t=1566855119; bh=+1wosb5BEpssQuHK+l2NG6luTzBCDCO5/XGg0rjHfGc=; h=From:To:Date; b=Us4CVRwdMhrJPaUvA+C8qFZocJqDzGKsLr3wtpnvyZQSlL1cgucir+TXWU8Due455 7xtTpsPMTmozucPNiU8zxThRuSYIYEVi7QnnvWIdOyOvjwQhe+aJrcbg8Z/kzWQsXL mkqjFJxVIxo8qwZyZ7eKOO1ouVRvYBp2FfScUJrQ= From: =?utf-8?q?Marek_Beh=C3=BAn?= To: Vivien Didelot Cc: netdev@vger.kernel.org, Andrew Lunn , Florian Fainelli , Vladimir Oltean , =?utf-8?q?Marek_Beh=C3=BA?= =?utf-8?q?n?= Subject: [PATCH net-next v5 1/6] net: dsa: mv88e6xxx: support 2500base-x in SGMII IRQ handler Date: Mon, 26 Aug 2019 23:31:50 +0200 Message-Id: <20190826213155.14685-2-marek.behun@nic.cz> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190826213155.14685-1-marek.behun@nic.cz> References: <20190826213155.14685-1-marek.behun@nic.cz> MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.100.3 at mail.nic.cz X-Virus-Status: Clean X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.nic.cz Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The mv88e6390_serdes_irq_link_sgmii IRQ handler reads the SERDES PHY status register to determine speed, among other things. If cmode of the port is set to 2500base-x, though, the PHY still reports 1000 Mbps (the PHY register itself does not differentiate between 1000 Mbps and 2500 Mbps - it thinks it is running at 1000 Mbps, although clock is 2.5x faster). Look at the cmode and set SPEED_2500 if cmode is set to 2500base-x. Also tell mv88e6xxx_port_setup_mac the PHY interface mode corresponding to current cmode in terms of phy_interface_t. Signed-off-by: Marek Behún Reviewed-by: Andrew Lunn Tested-by: Vivien Didelot --- drivers/net/dsa/mv88e6xxx/serdes.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c index 20c526c2a9ee..678aaba3d019 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.c +++ b/drivers/net/dsa/mv88e6xxx/serdes.c @@ -505,9 +505,11 @@ int mv88e6390x_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip, int port, int lane) { + u8 cmode = chip->ports[port].cmode; struct dsa_switch *ds = chip->ds; int duplex = DUPLEX_UNKNOWN; int speed = SPEED_UNKNOWN; + phy_interface_t mode; int link, err; u16 status; @@ -527,7 +529,10 @@ static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip, switch (status & MV88E6390_SGMII_PHY_STATUS_SPEED_MASK) { case MV88E6390_SGMII_PHY_STATUS_SPEED_1000: - speed = SPEED_1000; + if (cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) + speed = SPEED_2500; + else + speed = SPEED_1000; break; case MV88E6390_SGMII_PHY_STATUS_SPEED_100: speed = SPEED_100; @@ -541,8 +546,22 @@ static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip, } } + switch (cmode) { + case MV88E6XXX_PORT_STS_CMODE_SGMII: + mode = PHY_INTERFACE_MODE_SGMII; + break; + case MV88E6XXX_PORT_STS_CMODE_1000BASE_X: + mode = PHY_INTERFACE_MODE_1000BASEX; + break; + case MV88E6XXX_PORT_STS_CMODE_2500BASEX: + mode = PHY_INTERFACE_MODE_2500BASEX; + break; + default: + mode = PHY_INTERFACE_MODE_NA; + } + err = mv88e6xxx_port_setup_mac(chip, port, link, speed, duplex, - PAUSE_OFF, PHY_INTERFACE_MODE_NA); + PAUSE_OFF, mode); if (err) dev_err(chip->dev, "can't propagate PHY settings to MAC: %d\n", err); From patchwork Mon Aug 26 21:31:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 1153462 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nic.cz Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=nic.cz header.i=@nic.cz header.b="HInB3h4O"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 46HQFL5Xj1z9sDQ for ; Tue, 27 Aug 2019 07:32:06 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728881AbfHZVcF (ORCPT ); Mon, 26 Aug 2019 17:32:05 -0400 Received: from mail.nic.cz ([217.31.204.67]:35100 "EHLO mail.nic.cz" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728806AbfHZVcD (ORCPT ); Mon, 26 Aug 2019 17:32:03 -0400 Received: from dellmb.labs.office.nic.cz (unknown [IPv6:2001:1488:fffe:6:cac7:3539:7f1f:463]) by mail.nic.cz (Postfix) with ESMTP id 294CA140B22; Mon, 26 Aug 2019 23:31:59 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=nic.cz; s=default; t=1566855119; bh=AMZFYSrjEF+wEqk/h9IVRtryog/E9pgiOB+mvGK7Kc4=; h=From:To:Date; b=HInB3h4Ok9IeQc8mQOIqs5aduHAg+/iECOb8GUgHMjrHwEnxWbuW6yKls6c07KW4/ GI+UNOGRb4XHbN++ymQeGReNltU1NxQ5z2qnQL8gwtC28hf0PNrcICYOtNUH9LY7V1 UidW7vgOPlFgc4+KnRWZD3gnsdUHqEFXA0owZ6sk= From: =?utf-8?q?Marek_Beh=C3=BAn?= To: Vivien Didelot Cc: netdev@vger.kernel.org, Andrew Lunn , Florian Fainelli , Vladimir Oltean , =?utf-8?q?Marek_Beh=C3=BA?= =?utf-8?q?n?= Subject: [PATCH net-next v5 2/6] net: dsa: mv88e6xxx: update code operating on hidden registers Date: Mon, 26 Aug 2019 23:31:51 +0200 Message-Id: <20190826213155.14685-3-marek.behun@nic.cz> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190826213155.14685-1-marek.behun@nic.cz> References: <20190826213155.14685-1-marek.behun@nic.cz> MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.100.3 at mail.nic.cz X-Virus-Status: Clean X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.nic.cz Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This patch moves the functions operating on the hidden debug registers into it's own file, port_hidden.c. The functions prefix is renamed from mv88e6390_hidden_ to mv88e6xxx_port_hidden_, to be consistent with the rest of this driver. The macros are prefixed with MV88E6XXX_ prefix, and are changed not to use the BIT() macro nor bit shifts, since the rest of the port.h file does not use it. We also add the support for setting the Block Address field when operating hidden registers. Marvell's mdio examples for SERDES settings on Topaz use Block Address 0x7 when reading/writing hidden registers, and although the specification says that block must be set to 0xf, those settings are reachable only with Block Address 0x7. Signed-off-by: Marek Behún Reviewed-by: Andrew Lunn Tested-by: Vivien Didelot --- drivers/net/dsa/mv88e6xxx/Makefile | 1 + drivers/net/dsa/mv88e6xxx/chip.c | 58 +------------------- drivers/net/dsa/mv88e6xxx/port.h | 22 +++++--- drivers/net/dsa/mv88e6xxx/port_hidden.c | 70 +++++++++++++++++++++++++ 4 files changed, 87 insertions(+), 64 deletions(-) create mode 100644 drivers/net/dsa/mv88e6xxx/port_hidden.c diff --git a/drivers/net/dsa/mv88e6xxx/Makefile b/drivers/net/dsa/mv88e6xxx/Makefile index e85755dde90b..aa645ff86f64 100644 --- a/drivers/net/dsa/mv88e6xxx/Makefile +++ b/drivers/net/dsa/mv88e6xxx/Makefile @@ -10,6 +10,7 @@ mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_GLOBAL2) += global2_scratch.o mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_PTP) += hwtstamp.o mv88e6xxx-objs += phy.o mv88e6xxx-objs += port.o +mv88e6xxx-objs += port_hidden.o mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_PTP) += ptp.o mv88e6xxx-objs += serdes.o mv88e6xxx-objs += smi.o diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index d0bf98c10b2b..ec4274d71145 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -2317,60 +2317,6 @@ static int mv88e6xxx_stats_setup(struct mv88e6xxx_chip *chip) return mv88e6xxx_g1_stats_clear(chip); } -/* The mv88e6390 has some hidden registers used for debug and - * development. The errata also makes use of them. - */ -static int mv88e6390_hidden_write(struct mv88e6xxx_chip *chip, int port, - int reg, u16 val) -{ - u16 ctrl; - int err; - - err = mv88e6xxx_port_write(chip, PORT_RESERVED_1A_DATA_PORT, - PORT_RESERVED_1A, val); - if (err) - return err; - - ctrl = PORT_RESERVED_1A_BUSY | PORT_RESERVED_1A_WRITE | - PORT_RESERVED_1A_BLOCK | port << PORT_RESERVED_1A_PORT_SHIFT | - reg; - - return mv88e6xxx_port_write(chip, PORT_RESERVED_1A_CTRL_PORT, - PORT_RESERVED_1A, ctrl); -} - -static int mv88e6390_hidden_wait(struct mv88e6xxx_chip *chip) -{ - int bit = __bf_shf(PORT_RESERVED_1A_BUSY); - - return mv88e6xxx_wait_bit(chip, PORT_RESERVED_1A_CTRL_PORT, - PORT_RESERVED_1A, bit, 0); -} - - -static int mv88e6390_hidden_read(struct mv88e6xxx_chip *chip, int port, - int reg, u16 *val) -{ - u16 ctrl; - int err; - - ctrl = PORT_RESERVED_1A_BUSY | PORT_RESERVED_1A_READ | - PORT_RESERVED_1A_BLOCK | port << PORT_RESERVED_1A_PORT_SHIFT | - reg; - - err = mv88e6xxx_port_write(chip, PORT_RESERVED_1A_CTRL_PORT, - PORT_RESERVED_1A, ctrl); - if (err) - return err; - - err = mv88e6390_hidden_wait(chip); - if (err) - return err; - - return mv88e6xxx_port_read(chip, PORT_RESERVED_1A_DATA_PORT, - PORT_RESERVED_1A, val); -} - /* Check if the errata has already been applied. */ static bool mv88e6390_setup_errata_applied(struct mv88e6xxx_chip *chip) { @@ -2379,7 +2325,7 @@ static bool mv88e6390_setup_errata_applied(struct mv88e6xxx_chip *chip) u16 val; for (port = 0; port < mv88e6xxx_num_ports(chip); port++) { - err = mv88e6390_hidden_read(chip, port, 0, &val); + err = mv88e6xxx_port_hidden_read(chip, 0xf, port, 0, &val); if (err) { dev_err(chip->dev, "Error reading hidden register: %d\n", err); @@ -2412,7 +2358,7 @@ static int mv88e6390_setup_errata(struct mv88e6xxx_chip *chip) } for (port = 0; port < mv88e6xxx_num_ports(chip); port++) { - err = mv88e6390_hidden_write(chip, port, 0, 0x01c0); + err = mv88e6xxx_port_hidden_write(chip, 0xf, port, 0, 0x01c0); if (err) return err; } diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h index 1abf5ea033e2..21d2d8f7c8f9 100644 --- a/drivers/net/dsa/mv88e6xxx/port.h +++ b/drivers/net/dsa/mv88e6xxx/port.h @@ -261,14 +261,14 @@ #define MV88E6095_PORT_IEEE_PRIO_REMAP_4567 0x19 /* Offset 0x1a: Magic undocumented errata register */ -#define PORT_RESERVED_1A 0x1a -#define PORT_RESERVED_1A_BUSY BIT(15) -#define PORT_RESERVED_1A_WRITE BIT(14) -#define PORT_RESERVED_1A_READ 0 -#define PORT_RESERVED_1A_PORT_SHIFT 5 -#define PORT_RESERVED_1A_BLOCK (0xf << 10) -#define PORT_RESERVED_1A_CTRL_PORT 4 -#define PORT_RESERVED_1A_DATA_PORT 5 +#define MV88E6XXX_PORT_RESERVED_1A 0x1a +#define MV88E6XXX_PORT_RESERVED_1A_BUSY 0x8000 +#define MV88E6XXX_PORT_RESERVED_1A_WRITE 0x4000 +#define MV88E6XXX_PORT_RESERVED_1A_READ 0x0000 +#define MV88E6XXX_PORT_RESERVED_1A_PORT_SHIFT 5 +#define MV88E6XXX_PORT_RESERVED_1A_BLOCK_SHIFT 10 +#define MV88E6XXX_PORT_RESERVED_1A_CTRL_PORT 0x04 +#define MV88E6XXX_PORT_RESERVED_1A_DATA_PORT 0x05 int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg, u16 *val); @@ -353,4 +353,10 @@ int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port, int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip *chip, int port); int mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip *chip, int port); +int mv88e6xxx_port_hidden_write(struct mv88e6xxx_chip *chip, int block, + int port, int reg, u16 val); +int mv88e6xxx_port_hidden_wait(struct mv88e6xxx_chip *chip); +int mv88e6xxx_port_hidden_read(struct mv88e6xxx_chip *chip, int block, int port, + int reg, u16 *val); + #endif /* _MV88E6XXX_PORT_H */ diff --git a/drivers/net/dsa/mv88e6xxx/port_hidden.c b/drivers/net/dsa/mv88e6xxx/port_hidden.c new file mode 100644 index 000000000000..b49d05f0e117 --- /dev/null +++ b/drivers/net/dsa/mv88e6xxx/port_hidden.c @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Marvell 88E6xxx Switch Hidden Registers support + * + * Copyright (c) 2008 Marvell Semiconductor + * + * Copyright (c) 2019 Andrew Lunn + */ + +#include + +#include "chip.h" +#include "port.h" + +/* The mv88e6390 and mv88e6341 have some hidden registers used for debug and + * development. The errata also makes use of them. + */ +int mv88e6xxx_port_hidden_write(struct mv88e6xxx_chip *chip, int block, + int port, int reg, u16 val) +{ + u16 ctrl; + int err; + + err = mv88e6xxx_port_write(chip, MV88E6XXX_PORT_RESERVED_1A_DATA_PORT, + MV88E6XXX_PORT_RESERVED_1A, val); + if (err) + return err; + + ctrl = MV88E6XXX_PORT_RESERVED_1A_BUSY | + MV88E6XXX_PORT_RESERVED_1A_WRITE | + block << MV88E6XXX_PORT_RESERVED_1A_BLOCK_SHIFT | + port << MV88E6XXX_PORT_RESERVED_1A_PORT_SHIFT | + reg; + + return mv88e6xxx_port_write(chip, MV88E6XXX_PORT_RESERVED_1A_CTRL_PORT, + MV88E6XXX_PORT_RESERVED_1A, ctrl); +} + +int mv88e6xxx_port_hidden_wait(struct mv88e6xxx_chip *chip) +{ + int bit = __bf_shf(MV88E6XXX_PORT_RESERVED_1A_BUSY); + + return mv88e6xxx_wait_bit(chip, MV88E6XXX_PORT_RESERVED_1A_CTRL_PORT, + MV88E6XXX_PORT_RESERVED_1A, bit, 0); +} + +int mv88e6xxx_port_hidden_read(struct mv88e6xxx_chip *chip, int block, int port, + int reg, u16 *val) +{ + u16 ctrl; + int err; + + ctrl = MV88E6XXX_PORT_RESERVED_1A_BUSY | + MV88E6XXX_PORT_RESERVED_1A_READ | + block << MV88E6XXX_PORT_RESERVED_1A_BLOCK_SHIFT | + port << MV88E6XXX_PORT_RESERVED_1A_PORT_SHIFT | + reg; + + err = mv88e6xxx_port_write(chip, MV88E6XXX_PORT_RESERVED_1A_CTRL_PORT, + MV88E6XXX_PORT_RESERVED_1A, ctrl); + if (err) + return err; + + err = mv88e6xxx_port_hidden_wait(chip); + if (err) + return err; + + return mv88e6xxx_port_read(chip, MV88E6XXX_PORT_RESERVED_1A_DATA_PORT, + MV88E6XXX_PORT_RESERVED_1A, val); +} From patchwork Mon Aug 26 21:31:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 1153465 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nic.cz Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=nic.cz header.i=@nic.cz header.b="IWnvUVM9"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 46HQFT1sBDz9sDQ for ; Tue, 27 Aug 2019 07:32:13 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728951AbfHZVcL (ORCPT ); Mon, 26 Aug 2019 17:32:11 -0400 Received: from mail.nic.cz ([217.31.204.67]:35106 "EHLO mail.nic.cz" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728807AbfHZVcD (ORCPT ); Mon, 26 Aug 2019 17:32:03 -0400 Received: from dellmb.labs.office.nic.cz (unknown [IPv6:2001:1488:fffe:6:cac7:3539:7f1f:463]) by mail.nic.cz (Postfix) with ESMTP id 50C8C140B27; Mon, 26 Aug 2019 23:31:59 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=nic.cz; s=default; t=1566855119; bh=bu0bhTrwk08CuwtAEaO+BZo8zEAmsXCzJLTFJAfj4WI=; h=From:To:Date; b=IWnvUVM9oeAB9Cea5BOVYP48UPWTkYbtf/X+WzE8IXUMrZBpl/4C+qkzdP9KffFtA 1aSi/dp8mW6cb8PW1CgXVc5uUkl7tFhdc/p/iOph88eBKxHDjpXgi5ydESLZHM2DkG aOsVW9636E6n7+313SRKCs11rH5nrwCKGT8ql/II= From: =?utf-8?q?Marek_Beh=C3=BAn?= To: Vivien Didelot Cc: netdev@vger.kernel.org, Andrew Lunn , Florian Fainelli , Vladimir Oltean , =?utf-8?q?Marek_Beh=C3=BA?= =?utf-8?q?n?= Subject: [PATCH net-next v5 3/6] net: dsa: mv88e6xxx: create serdes_get_lane chip operation Date: Mon, 26 Aug 2019 23:31:52 +0200 Message-Id: <20190826213155.14685-4-marek.behun@nic.cz> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190826213155.14685-1-marek.behun@nic.cz> References: <20190826213155.14685-1-marek.behun@nic.cz> MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.100.3 at mail.nic.cz X-Virus-Status: Clean X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.nic.cz Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Create a serdes_get_lane() method in the mv88e6xxx operations structure. Use it instead of calling the different implementations. Also change the methods so that their return value is used only for error. The lane number is put into a place referred to by a pointer given as argument. If the port does not have a lane, return -ENODEV. Lanes are phy addresses, so use u8 as their type. Signed-off-by: Marek Behún Reviewed-by: Vivien Didelot Reviewed-by: Andrew Lunn --- drivers/net/dsa/mv88e6xxx/chip.c | 6 + drivers/net/dsa/mv88e6xxx/chip.h | 3 + drivers/net/dsa/mv88e6xxx/port.c | 16 +-- drivers/net/dsa/mv88e6xxx/serdes.c | 197 ++++++++++++++++------------- drivers/net/dsa/mv88e6xxx/serdes.h | 20 ++- 5 files changed, 146 insertions(+), 96 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index ec4274d71145..5a3fff1971b9 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -3255,6 +3255,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = { .vtu_getnext = mv88e6390_g1_vtu_getnext, .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, + .serdes_get_lane = mv88e6390_serdes_get_lane, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3301,6 +3302,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = { .vtu_getnext = mv88e6390_g1_vtu_getnext, .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, .serdes_power = mv88e6390x_serdes_power, + .serdes_get_lane = mv88e6390x_serdes_get_lane, .serdes_irq_setup = mv88e6390x_serdes_irq_setup, .serdes_irq_free = mv88e6390x_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3347,6 +3349,7 @@ static const struct mv88e6xxx_ops mv88e6191_ops = { .vtu_getnext = mv88e6390_g1_vtu_getnext, .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, + .serdes_get_lane = mv88e6390_serdes_get_lane, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .avb_ops = &mv88e6390_avb_ops, @@ -3483,6 +3486,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = { .vtu_getnext = mv88e6390_g1_vtu_getnext, .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, + .serdes_get_lane = mv88e6390_serdes_get_lane, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3800,6 +3804,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = { .vtu_getnext = mv88e6390_g1_vtu_getnext, .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, + .serdes_get_lane = mv88e6390_serdes_get_lane, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3850,6 +3855,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = { .vtu_getnext = mv88e6390_g1_vtu_getnext, .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, .serdes_power = mv88e6390x_serdes_power, + .serdes_get_lane = mv88e6390x_serdes_get_lane, .serdes_irq_setup = mv88e6390x_serdes_irq_setup, .serdes_irq_free = mv88e6390x_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h index a406be2f5652..421e8b84bec3 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.h +++ b/drivers/net/dsa/mv88e6xxx/chip.h @@ -443,6 +443,9 @@ struct mv88e6xxx_ops { /* Power on/off a SERDES interface */ int (*serdes_power)(struct mv88e6xxx_chip *chip, int port, bool on); + /* SERDES lane mapping */ + int (*serdes_get_lane)(struct mv88e6xxx_chip *chip, int port, u8 *lane); + /* SERDES interrupt handling */ int (*serdes_irq_setup)(struct mv88e6xxx_chip *chip, int port); void (*serdes_irq_free)(struct mv88e6xxx_chip *chip, int port); diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c index c95cdb73e5a2..4b0c58c30fea 100644 --- a/drivers/net/dsa/mv88e6xxx/port.c +++ b/drivers/net/dsa/mv88e6xxx/port.c @@ -395,7 +395,7 @@ phy_interface_t mv88e6390x_port_max_speed_mode(int port) int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, phy_interface_t mode) { - int lane; + u8 lane; u16 cmode; u16 reg; int err; @@ -434,11 +434,11 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, if (cmode == chip->ports[port].cmode) return 0; - lane = mv88e6390x_serdes_get_lane(chip, port); - if (lane < 0 && lane != -ENODEV) - return lane; + err = mv88e6xxx_serdes_get_lane(chip, port, &lane); + if (err && err != -ENODEV) + return err; - if (lane >= 0) { + if (err != -ENODEV) { if (chip->ports[port].serdes_irq) { err = mv88e6390_serdes_irq_disable(chip, port, lane); if (err) @@ -466,9 +466,9 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, chip->ports[port].cmode = cmode; - lane = mv88e6390x_serdes_get_lane(chip, port); - if (lane < 0) - return lane; + err = mv88e6xxx_serdes_get_lane(chip, port, &lane); + if (err) + return err; err = mv88e6390x_serdes_power(chip, port, true); if (err) diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c index 678aaba3d019..e58bccc25b7e 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.c +++ b/drivers/net/dsa/mv88e6xxx/serdes.c @@ -286,10 +286,7 @@ void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port) chip->ports[port].serdes_irq = 0; } -/* Return the SERDES lane address a port is using. Only Ports 9 and 10 - * have SERDES lanes. Returns -ENODEV if a port does not have a lane. - */ -static int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) +int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane) { u8 cmode = chip->ports[port].cmode; @@ -297,25 +294,27 @@ static int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) case 9: if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || - cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) - return MV88E6390_PORT9_LANE0; - return -ENODEV; + cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) { + *lane = MV88E6390_PORT9_LANE0; + return 0; + } + break; case 10: if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || - cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) - return MV88E6390_PORT10_LANE0; - return -ENODEV; + cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) { + *lane = MV88E6390_PORT10_LANE0; + return 0; + } + break; default: - return -ENODEV; + break; } + + return -ENODEV; } -/* Return the SERDES lane address a port is using. Ports 9 and 10 can - * use multiple lanes. If so, return the first lane the port uses. - * Returns -ENODEV if a port does not have a lane. - */ -int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) +int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane) { u8 cmode_port9, cmode_port10, cmode_port; @@ -327,72 +326,96 @@ int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) case 2: if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || - cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX) - if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) - return MV88E6390_PORT9_LANE1; - return -ENODEV; + cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX) { + if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) { + *lane = MV88E6390_PORT9_LANE1; + return 0; + } + } + break; case 3: if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || - cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) - if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) - return MV88E6390_PORT9_LANE2; - return -ENODEV; + cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) { + if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) { + *lane = MV88E6390_PORT9_LANE2; + return 0; + } + } + break; case 4: if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || - cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) - if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) - return MV88E6390_PORT9_LANE3; - return -ENODEV; + cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) { + if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) { + *lane = MV88E6390_PORT9_LANE3; + return 0; + } + } + break; case 5: if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || - cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX) - if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) - return MV88E6390_PORT10_LANE1; - return -ENODEV; + cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX) { + if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) { + *lane = MV88E6390_PORT10_LANE1; + return 0; + } + } + break; case 6: if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || - cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) - if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) - return MV88E6390_PORT10_LANE2; - return -ENODEV; + cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) { + if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) { + *lane = MV88E6390_PORT10_LANE2; + return 0; + } + } + break; case 7: if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || - cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) - if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) - return MV88E6390_PORT10_LANE3; - return -ENODEV; + cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) { + if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) { + *lane = MV88E6390_PORT10_LANE3; + return 0; + } + } + break; case 9: if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI || - cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) - return MV88E6390_PORT9_LANE0; - return -ENODEV; + cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) { + *lane = MV88E6390_PORT9_LANE0; + return 0; + } + break; case 10: if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI || - cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) - return MV88E6390_PORT10_LANE0; - return -ENODEV; + cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) { + *lane = MV88E6390_PORT10_LANE0; + return 0; + } + break; default: - return -ENODEV; + break; } + + return -ENODEV; } /* Set the power on/off for 10GBASE-R and 10GBASE-X4/X2 */ -static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, int lane, +static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane, bool on) { u16 val, new_val; @@ -419,7 +442,7 @@ static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, int lane, } /* Set the power on/off for SGMII and 1000Base-X */ -static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, int lane, +static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, u8 lane, bool on) { u16 val, new_val; @@ -445,7 +468,7 @@ static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, int lane, } static int mv88e6390_serdes_power_lane(struct mv88e6xxx_chip *chip, int port, - int lane, bool on) + u8 lane, bool on) { u8 cmode = chip->ports[port].cmode; @@ -464,14 +487,15 @@ static int mv88e6390_serdes_power_lane(struct mv88e6xxx_chip *chip, int port, int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) { - int lane; - - lane = mv88e6390_serdes_get_lane(chip, port); - if (lane == -ENODEV) - return 0; + u8 lane; + int err; - if (lane < 0) - return lane; + err = mv88e6xxx_serdes_get_lane(chip, port, &lane); + if (err) { + if (err == -ENODEV) + err = 0; + return err; + } switch (port) { case 9 ... 10: @@ -483,14 +507,15 @@ int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) int mv88e6390x_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) { - int lane; - - lane = mv88e6390x_serdes_get_lane(chip, port); - if (lane == -ENODEV) - return 0; + u8 lane; + int err; - if (lane < 0) - return lane; + err = mv88e6xxx_serdes_get_lane(chip, port, &lane); + if (err) { + if (err == -ENODEV) + err = 0; + return err; + } switch (port) { case 2 ... 4: @@ -503,7 +528,7 @@ int mv88e6390x_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) } static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip, - int port, int lane) + int port, u8 lane) { u8 cmode = chip->ports[port].cmode; struct dsa_switch *ds = chip->ds; @@ -570,7 +595,7 @@ static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip, } static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip, - int lane) + u8 lane) { return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, MV88E6390_SGMII_INT_ENABLE, @@ -579,14 +604,14 @@ static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip, } static int mv88e6390_serdes_irq_disable_sgmii(struct mv88e6xxx_chip *chip, - int lane) + u8 lane) { return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, MV88E6390_SGMII_INT_ENABLE, 0); } int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, - int lane) + u8 lane) { u8 cmode = chip->ports[port].cmode; int err = 0; @@ -602,7 +627,7 @@ int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, } int mv88e6390_serdes_irq_disable(struct mv88e6xxx_chip *chip, int port, - int lane) + u8 lane) { u8 cmode = chip->ports[port].cmode; int err = 0; @@ -618,7 +643,7 @@ int mv88e6390_serdes_irq_disable(struct mv88e6xxx_chip *chip, int port, } static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip, - int lane, u16 *status) + u8 lane, u16 *status) { int err; @@ -635,10 +660,10 @@ static irqreturn_t mv88e6390_serdes_thread_fn(int irq, void *dev_id) irqreturn_t ret = IRQ_NONE; u8 cmode = port->cmode; u16 status; - int lane; int err; + u8 lane; - lane = mv88e6390x_serdes_get_lane(chip, port->port); + mv88e6xxx_serdes_get_lane(chip, port->port, &lane); mv88e6xxx_reg_lock(chip); @@ -663,16 +688,15 @@ static irqreturn_t mv88e6390_serdes_thread_fn(int irq, void *dev_id) int mv88e6390x_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port) { - int lane; int err; + u8 lane; - lane = mv88e6390x_serdes_get_lane(chip, port); - - if (lane == -ENODEV) - return 0; - - if (lane < 0) - return lane; + err = mv88e6xxx_serdes_get_lane(chip, port, &lane); + if (err) { + if (err == -ENODEV) + err = 0; + return err; + } chip->ports[port].serdes_irq = irq_find_mapping(chip->g2_irq.domain, port); @@ -711,13 +735,16 @@ int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port) void mv88e6390x_serdes_irq_free(struct mv88e6xxx_chip *chip, int port) { - int lane = mv88e6390x_serdes_get_lane(chip, port); - - if (lane == -ENODEV) - return; + int err; + u8 lane; - if (lane < 0) + err = mv88e6xxx_serdes_get_lane(chip, port, &lane); + if (err) { + if (err != -ENODEV) + dev_err(chip->dev, "Unable to free SERDES irq: %d\n", + err); return; + } mv88e6390_serdes_irq_disable(chip, port, lane); diff --git a/drivers/net/dsa/mv88e6xxx/serdes.h b/drivers/net/dsa/mv88e6xxx/serdes.h index ff5b94439335..959b8cef0b67 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.h +++ b/drivers/net/dsa/mv88e6xxx/serdes.h @@ -74,7 +74,21 @@ #define MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID BIT(11) #define MV88E6390_SGMII_PHY_STATUS_LINK BIT(10) -int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port); +/* Put the SERDES lane address a port is using into *lane. If a port has + * multiple lanes, should put the first lane the port is using. If a port does + * not have a lane, return -ENODEV. + */ +static inline int mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip, + int port, u8 *lane) +{ + if (!chip->info->ops->serdes_get_lane) + return -EOPNOTSUPP; + + return chip->info->ops->serdes_get_lane(chip, port, lane); +} + +int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane); +int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane); int mv88e6341_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); @@ -89,9 +103,9 @@ int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip, int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, uint64_t *data); int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, - int lane); + u8 lane); int mv88e6390_serdes_irq_disable(struct mv88e6xxx_chip *chip, int port, - int lane); + u8 lane); int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port); void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port); From patchwork Mon Aug 26 21:31:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 1153463 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nic.cz Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=nic.cz header.i=@nic.cz header.b="hKlNNnHR"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 46HQFM58pxz9sNC for ; Tue, 27 Aug 2019 07:32:07 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728902AbfHZVcG (ORCPT ); Mon, 26 Aug 2019 17:32:06 -0400 Received: from mail.nic.cz ([217.31.204.67]:35110 "EHLO mail.nic.cz" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728810AbfHZVcD (ORCPT ); Mon, 26 Aug 2019 17:32:03 -0400 Received: from dellmb.labs.office.nic.cz (unknown [IPv6:2001:1488:fffe:6:cac7:3539:7f1f:463]) by mail.nic.cz (Postfix) with ESMTP id 74F0D140B41; Mon, 26 Aug 2019 23:31:59 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=nic.cz; s=default; t=1566855119; bh=ynQ6yZa7b+PivtNUZv1tkaPYZTzTc3OKD5cvlYKPb9E=; h=From:To:Date; b=hKlNNnHRFGVpgMuMq+3gj/hqXAAHxe5mzKIZwbIsmGrZPcJFJMehh4AsFasvGtbre I4oJbmO2GWYt/pysvCpgU+tqPOwTD57nnL+Yu05FMRc0SJfaZ++xpUrbZ6RXRZ0uJu unagibQi1mU/+HHeqQlYd/ESilYB7aai0lJ+2IM0= From: =?utf-8?q?Marek_Beh=C3=BAn?= To: Vivien Didelot Cc: netdev@vger.kernel.org, Andrew Lunn , Florian Fainelli , Vladimir Oltean , =?utf-8?q?Marek_Beh=C3=BA?= =?utf-8?q?n?= Subject: [PATCH net-next v5 4/6] net: dsa: mv88e6xxx: simplify SERDES code for Topaz and Peridot Date: Mon, 26 Aug 2019 23:31:53 +0200 Message-Id: <20190826213155.14685-5-marek.behun@nic.cz> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190826213155.14685-1-marek.behun@nic.cz> References: <20190826213155.14685-1-marek.behun@nic.cz> MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.100.3 at mail.nic.cz X-Virus-Status: Clean X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.nic.cz Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org By adding an additional serdes_get_lane implementation (for Topaz), we can merge the implementations of other SERDES functions (powering and IRQs). We can skip checking port numbers, since the serdes_get_lane() methods inform if there is no lane on a port or if the lane cannot be used for given cmode. Signed-off-by: Marek Behún Reviewed-by: Andrew Lunn --- drivers/net/dsa/mv88e6xxx/chip.c | 18 ++--- drivers/net/dsa/mv88e6xxx/port.c | 4 +- drivers/net/dsa/mv88e6xxx/serdes.c | 105 ++++++++--------------------- drivers/net/dsa/mv88e6xxx/serdes.h | 7 +- 4 files changed, 42 insertions(+), 92 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 5a3fff1971b9..202ccce65b1c 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -2927,7 +2927,8 @@ static const struct mv88e6xxx_ops mv88e6141_ops = { .reset = mv88e6352_g1_reset, .vtu_getnext = mv88e6352_g1_vtu_getnext, .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, - .serdes_power = mv88e6341_serdes_power, + .serdes_power = mv88e6390_serdes_power, + .serdes_get_lane = mv88e6341_serdes_get_lane, .gpio_ops = &mv88e6352_gpio_ops, .phylink_validate = mv88e6341_phylink_validate, }; @@ -3301,10 +3302,10 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = { .rmu_disable = mv88e6390_g1_rmu_disable, .vtu_getnext = mv88e6390_g1_vtu_getnext, .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, - .serdes_power = mv88e6390x_serdes_power, + .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6390x_serdes_get_lane, - .serdes_irq_setup = mv88e6390x_serdes_irq_setup, - .serdes_irq_free = mv88e6390x_serdes_irq_free, + .serdes_irq_setup = mv88e6390_serdes_irq_setup, + .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, .phylink_validate = mv88e6390x_phylink_validate, }; @@ -3621,7 +3622,8 @@ static const struct mv88e6xxx_ops mv88e6341_ops = { .reset = mv88e6352_g1_reset, .vtu_getnext = mv88e6352_g1_vtu_getnext, .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, - .serdes_power = mv88e6341_serdes_power, + .serdes_power = mv88e6390_serdes_power, + .serdes_get_lane = mv88e6341_serdes_get_lane, .gpio_ops = &mv88e6352_gpio_ops, .avb_ops = &mv88e6390_avb_ops, .ptp_ops = &mv88e6352_ptp_ops, @@ -3854,10 +3856,10 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = { .rmu_disable = mv88e6390_g1_rmu_disable, .vtu_getnext = mv88e6390_g1_vtu_getnext, .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, - .serdes_power = mv88e6390x_serdes_power, + .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6390x_serdes_get_lane, - .serdes_irq_setup = mv88e6390x_serdes_irq_setup, - .serdes_irq_free = mv88e6390x_serdes_irq_free, + .serdes_irq_setup = mv88e6390_serdes_irq_setup, + .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, .avb_ops = &mv88e6390_avb_ops, .ptp_ops = &mv88e6352_ptp_ops, diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c index 4b0c58c30fea..dde863166da7 100644 --- a/drivers/net/dsa/mv88e6xxx/port.c +++ b/drivers/net/dsa/mv88e6xxx/port.c @@ -445,7 +445,7 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, return err; } - err = mv88e6390x_serdes_power(chip, port, false); + err = mv88e6390_serdes_power(chip, port, false); if (err) return err; } @@ -470,7 +470,7 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, if (err) return err; - err = mv88e6390x_serdes_power(chip, port, true); + err = mv88e6390_serdes_power(chip, port, true); if (err) return err; diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c index e58bccc25b7e..12fcc512afad 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.c +++ b/drivers/net/dsa/mv88e6xxx/serdes.c @@ -286,6 +286,23 @@ void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port) chip->ports[port].serdes_irq = 0; } +int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane) +{ + u8 cmode = chip->ports[port].cmode; + + if (port != 5) + return -ENODEV; + + if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || + cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || + cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) { + *lane = MV88E6341_PORT5_LANE; + return 0; + } + + return -ENODEV; +} + int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane) { u8 cmode = chip->ports[port].cmode; @@ -467,26 +484,9 @@ static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, u8 lane, return err; } -static int mv88e6390_serdes_power_lane(struct mv88e6xxx_chip *chip, int port, - u8 lane, bool on) -{ - u8 cmode = chip->ports[port].cmode; - - switch (cmode) { - case MV88E6XXX_PORT_STS_CMODE_SGMII: - case MV88E6XXX_PORT_STS_CMODE_1000BASE_X: - case MV88E6XXX_PORT_STS_CMODE_2500BASEX: - return mv88e6390_serdes_power_sgmii(chip, lane, on); - case MV88E6XXX_PORT_STS_CMODE_XAUI: - case MV88E6XXX_PORT_STS_CMODE_RXAUI: - return mv88e6390_serdes_power_10g(chip, lane, on); - } - - return 0; -} - int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) { + u8 cmode = chip->ports[port].cmode; u8 lane; int err; @@ -497,31 +497,14 @@ int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) return err; } - switch (port) { - case 9 ... 10: - return mv88e6390_serdes_power_lane(chip, port, lane, on); - } - - return 0; -} - -int mv88e6390x_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) -{ - u8 lane; - int err; - - err = mv88e6xxx_serdes_get_lane(chip, port, &lane); - if (err) { - if (err == -ENODEV) - err = 0; - return err; - } - - switch (port) { - case 2 ... 4: - case 5 ... 7: - case 9 ... 10: - return mv88e6390_serdes_power_lane(chip, port, lane, on); + switch (cmode) { + case MV88E6XXX_PORT_STS_CMODE_SGMII: + case MV88E6XXX_PORT_STS_CMODE_1000BASE_X: + case MV88E6XXX_PORT_STS_CMODE_2500BASEX: + return mv88e6390_serdes_power_sgmii(chip, lane, on); + case MV88E6XXX_PORT_STS_CMODE_XAUI: + case MV88E6XXX_PORT_STS_CMODE_RXAUI: + return mv88e6390_serdes_power_10g(chip, lane, on); } return 0; @@ -686,7 +669,7 @@ static irqreturn_t mv88e6390_serdes_thread_fn(int irq, void *dev_id) return ret; } -int mv88e6390x_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port) +int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port) { int err; u8 lane; @@ -725,15 +708,7 @@ int mv88e6390x_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port) return mv88e6390_serdes_irq_enable(chip, port, lane); } -int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port) -{ - if (port < 9) - return 0; - - return mv88e6390x_serdes_irq_setup(chip, port); -} - -void mv88e6390x_serdes_irq_free(struct mv88e6xxx_chip *chip, int port) +void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port) { int err; u8 lane; @@ -757,27 +732,3 @@ void mv88e6390x_serdes_irq_free(struct mv88e6xxx_chip *chip, int port) chip->ports[port].serdes_irq = 0; } - -void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port) -{ - if (port < 9) - return; - - mv88e6390x_serdes_irq_free(chip, port); -} - -int mv88e6341_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) -{ - u8 cmode = chip->ports[port].cmode; - - if (port != 5) - return 0; - - if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || - cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || - cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) - return mv88e6390_serdes_power_sgmii(chip, MV88E6341_ADDR_SERDES, - on); - - return 0; -} diff --git a/drivers/net/dsa/mv88e6xxx/serdes.h b/drivers/net/dsa/mv88e6xxx/serdes.h index 959b8cef0b67..c2e6fc3ddf8b 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.h +++ b/drivers/net/dsa/mv88e6xxx/serdes.h @@ -28,7 +28,7 @@ #define MV88E6352_SERDES_INT_STATUS 0x13 -#define MV88E6341_ADDR_SERDES 0x15 +#define MV88E6341_PORT5_LANE 0x15 #define MV88E6390_PORT9_LANE0 0x09 #define MV88E6390_PORT9_LANE1 0x12 @@ -87,16 +87,13 @@ static inline int mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip, return chip->info->ops->serdes_get_lane(chip, port, lane); } +int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane); int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane); int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane); -int mv88e6341_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); -int mv88e6390x_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port); void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port); -int mv88e6390x_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port); -void mv88e6390x_serdes_irq_free(struct mv88e6xxx_chip *chip, int port); int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port); int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip, int port, uint8_t *data); From patchwork Mon Aug 26 21:31:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 1153466 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nic.cz Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=nic.cz header.i=@nic.cz header.b="cZm8s58x"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 46HQFV2CcLz9sN6 for ; Tue, 27 Aug 2019 07:32:14 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728943AbfHZVcL (ORCPT ); Mon, 26 Aug 2019 17:32:11 -0400 Received: from mail.nic.cz ([217.31.204.67]:35124 "EHLO mail.nic.cz" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728830AbfHZVcE (ORCPT ); Mon, 26 Aug 2019 17:32:04 -0400 Received: from dellmb.labs.office.nic.cz (unknown [IPv6:2001:1488:fffe:6:cac7:3539:7f1f:463]) by mail.nic.cz (Postfix) with ESMTP id 99916140B4F; Mon, 26 Aug 2019 23:31:59 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=nic.cz; s=default; t=1566855119; bh=6hWqcEOtadbSK/ce+4guf3dYtO7XBPrMkoaMTY1C0QA=; h=From:To:Date; b=cZm8s58xrRsk12MDlurDmXQLmBffzhpP0tDFNIz5npWD6LGGDMLGCJ06yviGMvu8n O31dX8IqCXz+aPTa+MbZXpZuHXFbo8J/MQd/6CZSxPqH+5VM3EjYU3v2CyBuCARgrG pLZepQpJLNrEGxO6EU4LboHZrNGbo8jlocwpboqc= From: =?utf-8?q?Marek_Beh=C3=BAn?= To: Vivien Didelot Cc: netdev@vger.kernel.org, Andrew Lunn , Florian Fainelli , Vladimir Oltean , =?utf-8?q?Marek_Beh=C3=BA?= =?utf-8?q?n?= Subject: [PATCH net-next v5 5/6] net: dsa: mv88e6xxx: rename port cmode macro Date: Mon, 26 Aug 2019 23:31:54 +0200 Message-Id: <20190826213155.14685-6-marek.behun@nic.cz> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190826213155.14685-1-marek.behun@nic.cz> References: <20190826213155.14685-1-marek.behun@nic.cz> MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.100.3 at mail.nic.cz X-Virus-Status: Clean X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.nic.cz Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This is a cosmetic update. We are removing the last underscore from macros MV88E6XXX_PORT_STS_CMODE_100BASE_X and MV88E6XXX_PORT_STS_CMODE_1000BASE_X. The 2500base-x version does not have that underscore. Also PHY_INTERFACE_MODE_ macros do not have it there. Signed-off-by: Marek Behún Reviewed-by: Andrew Lunn --- drivers/net/dsa/mv88e6xxx/port.c | 4 +-- drivers/net/dsa/mv88e6xxx/port.h | 4 +-- drivers/net/dsa/mv88e6xxx/serdes.c | 48 +++++++++++++++--------------- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c index dde863166da7..c7630dab18a8 100644 --- a/drivers/net/dsa/mv88e6xxx/port.c +++ b/drivers/net/dsa/mv88e6xxx/port.c @@ -411,7 +411,7 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, switch (mode) { case PHY_INTERFACE_MODE_1000BASEX: - cmode = MV88E6XXX_PORT_STS_CMODE_1000BASE_X; + cmode = MV88E6XXX_PORT_STS_CMODE_1000BASEX; break; case PHY_INTERFACE_MODE_SGMII: cmode = MV88E6XXX_PORT_STS_CMODE_SGMII; @@ -618,7 +618,7 @@ int mv88e6352_port_link_state(struct mv88e6xxx_chip *chip, int port, else state->interface = PHY_INTERFACE_MODE_RGMII; break; - case MV88E6XXX_PORT_STS_CMODE_1000BASE_X: + case MV88E6XXX_PORT_STS_CMODE_1000BASEX: state->interface = PHY_INTERFACE_MODE_1000BASEX; break; case MV88E6XXX_PORT_STS_CMODE_SGMII: diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h index 21d2d8f7c8f9..6d7a067da0f5 100644 --- a/drivers/net/dsa/mv88e6xxx/port.h +++ b/drivers/net/dsa/mv88e6xxx/port.h @@ -43,8 +43,8 @@ #define MV88E6XXX_PORT_STS_FLOW_CTL 0x0010 #define MV88E6XXX_PORT_STS_CMODE_MASK 0x000f #define MV88E6XXX_PORT_STS_CMODE_RGMII 0x0007 -#define MV88E6XXX_PORT_STS_CMODE_100BASE_X 0x0008 -#define MV88E6XXX_PORT_STS_CMODE_1000BASE_X 0x0009 +#define MV88E6XXX_PORT_STS_CMODE_100BASEX 0x0008 +#define MV88E6XXX_PORT_STS_CMODE_1000BASEX 0x0009 #define MV88E6XXX_PORT_STS_CMODE_SGMII 0x000a #define MV88E6XXX_PORT_STS_CMODE_2500BASEX 0x000b #define MV88E6XXX_PORT_STS_CMODE_XAUI 0x000c diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c index 12fcc512afad..9424e401dbc7 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.c +++ b/drivers/net/dsa/mv88e6xxx/serdes.c @@ -73,8 +73,8 @@ static bool mv88e6352_port_has_serdes(struct mv88e6xxx_chip *chip, int port) { u8 cmode = chip->ports[port].cmode; - if ((cmode == MV88E6XXX_PORT_STS_CMODE_100BASE_X) || - (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) || + if ((cmode == MV88E6XXX_PORT_STS_CMODE_100BASEX) || + (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX) || (cmode == MV88E6XXX_PORT_STS_CMODE_SGMII)) return true; @@ -293,7 +293,7 @@ int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane) if (port != 5) return -ENODEV; - if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || + if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX || cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) { *lane = MV88E6341_PORT5_LANE; @@ -309,7 +309,7 @@ int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane) switch (port) { case 9: - if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || + if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX || cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) { *lane = MV88E6390_PORT9_LANE0; @@ -317,7 +317,7 @@ int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane) } break; case 10: - if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || + if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX || cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) { *lane = MV88E6390_PORT10_LANE0; @@ -341,71 +341,71 @@ int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane) switch (port) { case 2: - if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || + if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX) { - if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) { + if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) { *lane = MV88E6390_PORT9_LANE1; return 0; } } break; case 3: - if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || + if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) { - if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) { + if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) { *lane = MV88E6390_PORT9_LANE2; return 0; } } break; case 4: - if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || + if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) { - if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) { + if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) { *lane = MV88E6390_PORT9_LANE3; return 0; } } break; case 5: - if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || + if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX) { - if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) { + if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) { *lane = MV88E6390_PORT10_LANE1; return 0; } } break; case 6: - if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || + if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) { - if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) { + if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) { *lane = MV88E6390_PORT10_LANE2; return 0; } } break; case 7: - if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || + if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) { - if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) { + if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) { *lane = MV88E6390_PORT10_LANE3; return 0; } } break; case 9: - if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || + if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI || @@ -415,7 +415,7 @@ int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane) } break; case 10: - if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || + if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI || @@ -499,7 +499,7 @@ int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) switch (cmode) { case MV88E6XXX_PORT_STS_CMODE_SGMII: - case MV88E6XXX_PORT_STS_CMODE_1000BASE_X: + case MV88E6XXX_PORT_STS_CMODE_1000BASEX: case MV88E6XXX_PORT_STS_CMODE_2500BASEX: return mv88e6390_serdes_power_sgmii(chip, lane, on); case MV88E6XXX_PORT_STS_CMODE_XAUI: @@ -558,7 +558,7 @@ static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip, case MV88E6XXX_PORT_STS_CMODE_SGMII: mode = PHY_INTERFACE_MODE_SGMII; break; - case MV88E6XXX_PORT_STS_CMODE_1000BASE_X: + case MV88E6XXX_PORT_STS_CMODE_1000BASEX: mode = PHY_INTERFACE_MODE_1000BASEX; break; case MV88E6XXX_PORT_STS_CMODE_2500BASEX: @@ -601,7 +601,7 @@ int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, switch (cmode) { case MV88E6XXX_PORT_STS_CMODE_SGMII: - case MV88E6XXX_PORT_STS_CMODE_1000BASE_X: + case MV88E6XXX_PORT_STS_CMODE_1000BASEX: case MV88E6XXX_PORT_STS_CMODE_2500BASEX: err = mv88e6390_serdes_irq_enable_sgmii(chip, lane); } @@ -617,7 +617,7 @@ int mv88e6390_serdes_irq_disable(struct mv88e6xxx_chip *chip, int port, switch (cmode) { case MV88E6XXX_PORT_STS_CMODE_SGMII: - case MV88E6XXX_PORT_STS_CMODE_1000BASE_X: + case MV88E6XXX_PORT_STS_CMODE_1000BASEX: case MV88E6XXX_PORT_STS_CMODE_2500BASEX: err = mv88e6390_serdes_irq_disable_sgmii(chip, lane); } @@ -652,7 +652,7 @@ static irqreturn_t mv88e6390_serdes_thread_fn(int irq, void *dev_id) switch (cmode) { case MV88E6XXX_PORT_STS_CMODE_SGMII: - case MV88E6XXX_PORT_STS_CMODE_1000BASE_X: + case MV88E6XXX_PORT_STS_CMODE_1000BASEX: case MV88E6XXX_PORT_STS_CMODE_2500BASEX: err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status); if (err) From patchwork Mon Aug 26 21:31:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 1153464 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nic.cz Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=nic.cz header.i=@nic.cz header.b="pv1ZfBR3"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 46HQFN2q5rz9sN6 for ; Tue, 27 Aug 2019 07:32:08 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728910AbfHZVcG (ORCPT ); Mon, 26 Aug 2019 17:32:06 -0400 Received: from mail.nic.cz ([217.31.204.67]:35122 "EHLO mail.nic.cz" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728835AbfHZVcD (ORCPT ); Mon, 26 Aug 2019 17:32:03 -0400 Received: from dellmb.labs.office.nic.cz (unknown [IPv6:2001:1488:fffe:6:cac7:3539:7f1f:463]) by mail.nic.cz (Postfix) with ESMTP id B7FBD140B50; Mon, 26 Aug 2019 23:31:59 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=nic.cz; s=default; t=1566855119; bh=18PBcpj0KmpUiSVakzDOzIS2C1+QrrrT2iSIxhR4LPw=; h=From:To:Date; b=pv1ZfBR3xtVSP1MMP1JHeN1UBBVoqcuxiVA16uU8zQB1KC/tB+SdoMJsFoqJuEkT8 hN94FLcYUsSpviwoKhCkSqp/dTC2RIX49qyx+eaop5WxvOQos2wNDQxVICfkAnGq0w TNAciGMOIXLCK/mFGQTM5X9QQ9xRWPwPkhH0I/0A= From: =?utf-8?q?Marek_Beh=C3=BAn?= To: Vivien Didelot Cc: netdev@vger.kernel.org, Andrew Lunn , Florian Fainelli , Vladimir Oltean , =?utf-8?q?Marek_Beh=C3=BA?= =?utf-8?q?n?= Subject: [PATCH net-next v5 6/6] net: dsa: mv88e6xxx: fully support SERDES on Topaz family Date: Mon, 26 Aug 2019 23:31:55 +0200 Message-Id: <20190826213155.14685-7-marek.behun@nic.cz> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190826213155.14685-1-marek.behun@nic.cz> References: <20190826213155.14685-1-marek.behun@nic.cz> MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.100.3 at mail.nic.cz X-Virus-Status: Clean X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.nic.cz Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Currently we support SERDES on the Topaz family in a limited way: no IRQs and the cmode is not writable, thus the mode is determined by strapping pins. Marvell's examples though show how to make cmode writable on port 5 and support SGMII autonegotiation. It is done by writing hidden registers, for which we already have code. This patch adds support for making the cmode for the SERDES port writable on the Topaz family, via a new chip operation, .port_set_cmode_writable, which is called from mv88e6xxx_port_setup_mac just before .port_set_cmode. SERDES IRQs are also enabled for Topaz. Tested on Turris Mox. Signed-off-by: Marek Behún Reviewed-by: Vivien Didelot Reviewed-by: Andrew Lunn --- drivers/net/dsa/mv88e6xxx/chip.c | 14 +++++++ drivers/net/dsa/mv88e6xxx/chip.h | 1 + drivers/net/dsa/mv88e6xxx/port.c | 65 +++++++++++++++++++++++++++++--- drivers/net/dsa/mv88e6xxx/port.h | 5 +++ 4 files changed, 79 insertions(+), 6 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 202ccce65b1c..54e88aafba2f 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -454,6 +454,12 @@ int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port, int link, goto restore_link; } + if (chip->info->ops->port_set_cmode_writable) { + err = chip->info->ops->port_set_cmode_writable(chip, port); + if (err && err != -EOPNOTSUPP) + goto restore_link; + } + if (chip->info->ops->port_set_cmode) { err = chip->info->ops->port_set_cmode(chip, port, mode); if (err && err != -EOPNOTSUPP) @@ -2913,6 +2919,8 @@ static const struct mv88e6xxx_ops mv88e6141_ops = { .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6352_port_get_cmode, + .port_set_cmode_writable = mv88e6341_port_set_cmode_writable, + .port_set_cmode = mv88e6341_port_set_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port, .stats_snapshot = mv88e6390_g1_stats_snapshot, .stats_set_histogram = mv88e6095_g1_stats_set_histogram, @@ -2929,6 +2937,8 @@ static const struct mv88e6xxx_ops mv88e6141_ops = { .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6341_serdes_get_lane, + .serdes_irq_setup = mv88e6390_serdes_irq_setup, + .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, .phylink_validate = mv88e6341_phylink_validate, }; @@ -3608,6 +3618,8 @@ static const struct mv88e6xxx_ops mv88e6341_ops = { .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6352_port_get_cmode, + .port_set_cmode_writable = mv88e6341_port_set_cmode_writable, + .port_set_cmode = mv88e6341_port_set_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port, .stats_snapshot = mv88e6390_g1_stats_snapshot, .stats_set_histogram = mv88e6095_g1_stats_set_histogram, @@ -3624,6 +3636,8 @@ static const struct mv88e6xxx_ops mv88e6341_ops = { .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6341_serdes_get_lane, + .serdes_irq_setup = mv88e6390_serdes_irq_setup, + .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, .avb_ops = &mv88e6390_avb_ops, .ptp_ops = &mv88e6352_ptp_ops, diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h index 421e8b84bec3..d6b1aa35aa1a 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.h +++ b/drivers/net/dsa/mv88e6xxx/chip.h @@ -400,6 +400,7 @@ struct mv88e6xxx_ops { /* CMODE control what PHY mode the MAC will use, eg. SGMII, RGMII, etc. * Some chips allow this to be configured on specific ports. */ + int (*port_set_cmode_writable)(struct mv88e6xxx_chip *chip, int port); int (*port_set_cmode)(struct mv88e6xxx_chip *chip, int port, phy_interface_t mode); int (*port_get_cmode)(struct mv88e6xxx_chip *chip, int port, u8 *cmode); diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c index c7630dab18a8..542201214c36 100644 --- a/drivers/net/dsa/mv88e6xxx/port.c +++ b/drivers/net/dsa/mv88e6xxx/port.c @@ -392,17 +392,14 @@ phy_interface_t mv88e6390x_port_max_speed_mode(int port) return PHY_INTERFACE_MODE_NA; } -int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, - phy_interface_t mode) +static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, + phy_interface_t mode) { u8 lane; u16 cmode; u16 reg; int err; - if (port != 9 && port != 10) - return -EOPNOTSUPP; - /* Default to a slow mode, so freeing up SERDES interfaces for * other ports which might use them for SFPs. */ @@ -484,9 +481,65 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, return 0; } +int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, + phy_interface_t mode) +{ + if (port != 9 && port != 10) + return -EOPNOTSUPP; + + return mv88e6xxx_port_set_cmode(chip, port, mode); +} + int mv88e6390_port_set_cmode(struct mv88e6xxx_chip *chip, int port, phy_interface_t mode) { + if (port != 9 && port != 10) + return -EOPNOTSUPP; + + switch (mode) { + case PHY_INTERFACE_MODE_NA: + return 0; + case PHY_INTERFACE_MODE_XGMII: + case PHY_INTERFACE_MODE_XAUI: + case PHY_INTERFACE_MODE_RXAUI: + return -EINVAL; + default: + break; + } + + return mv88e6xxx_port_set_cmode(chip, port, mode); +} + +int mv88e6341_port_set_cmode_writable(struct mv88e6xxx_chip *chip, int port) +{ + int err, addr; + u16 reg, bits; + + if (port != 5) + return -EOPNOTSUPP; + + addr = chip->info->port_base_addr + port; + + err = mv88e6xxx_port_hidden_read(chip, 0x7, addr, 0, ®); + if (err) + return err; + + bits = MV88E6341_PORT_RESERVED_1A_FORCE_CMODE | + MV88E6341_PORT_RESERVED_1A_SGMII_AN; + + if ((reg & bits) == bits) + return 0; + + reg |= bits; + return mv88e6xxx_port_hidden_write(chip, 0x7, addr, 0, reg); +} + +int mv88e6341_port_set_cmode(struct mv88e6xxx_chip *chip, int port, + phy_interface_t mode) +{ + if (port != 5) + return -EOPNOTSUPP; + switch (mode) { case PHY_INTERFACE_MODE_NA: return 0; @@ -498,7 +551,7 @@ int mv88e6390_port_set_cmode(struct mv88e6xxx_chip *chip, int port, break; } - return mv88e6390x_port_set_cmode(chip, port, mode); + return mv88e6xxx_port_set_cmode(chip, port, mode); } int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode) diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h index 6d7a067da0f5..e78d68c3e671 100644 --- a/drivers/net/dsa/mv88e6xxx/port.h +++ b/drivers/net/dsa/mv88e6xxx/port.h @@ -269,6 +269,8 @@ #define MV88E6XXX_PORT_RESERVED_1A_BLOCK_SHIFT 10 #define MV88E6XXX_PORT_RESERVED_1A_CTRL_PORT 0x04 #define MV88E6XXX_PORT_RESERVED_1A_DATA_PORT 0x05 +#define MV88E6341_PORT_RESERVED_1A_FORCE_CMODE 0x8000 +#define MV88E6341_PORT_RESERVED_1A_SGMII_AN 0x2000 int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg, u16 *val); @@ -334,6 +336,9 @@ int mv88e6097_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in, u8 out); int mv88e6390_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in, u8 out); +int mv88e6341_port_set_cmode_writable(struct mv88e6xxx_chip *chip, int port); +int mv88e6341_port_set_cmode(struct mv88e6xxx_chip *chip, int port, + phy_interface_t mode); int mv88e6390_port_set_cmode(struct mv88e6xxx_chip *chip, int port, phy_interface_t mode); int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,