From patchwork Sun Dec 30 08:25:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Klaus Kudielka X-Patchwork-Id: 1019406 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=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Vtlh8i1L"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43SD77454fz9s8J for ; Sun, 30 Dec 2018 19:26:27 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726085AbeL3IZ6 (ORCPT ); Sun, 30 Dec 2018 03:25:58 -0500 Received: from mail-ed1-f65.google.com ([209.85.208.65]:36122 "EHLO mail-ed1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726051AbeL3IZ5 (ORCPT ); Sun, 30 Dec 2018 03:25:57 -0500 Received: by mail-ed1-f65.google.com with SMTP id f23so20622680edb.3 for ; Sun, 30 Dec 2018 00:25:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:message-id:date:user-agent:mime-version :content-transfer-encoding:content-language; bh=iM4pRDmtSKno5C+L0Eh90jes6kqQ9I5ofHeph0xbTvY=; b=Vtlh8i1LqGs8DHqpWpDUplnVdSXciHzJSZJZOKnYhs9o+Fo6WVb96Q9yqdaaLBQ2tW 1cVU+nl48i+lQMRR7/6Mb2avxr4cgyPWiI+fY0jLdz64APlPnXkPd9F5ySUYI1ueCeiT OaHAnPpF0dBnF5wJGqDPN+feMkO+Rg7b7Yh2JF/MR8euO0o9Tb5cjOucQazfbtPliQE5 AWzqkDpxAQWQbQk1waXAh6yaqBYGQaBQJA1o+mxs43kTO86VRlhaLZ2ddtKTWBIJOCVE 0Mjt0iJSyX+aITPw2zNYqocLZ5p9p/NB9Jm8WTdPn/mBdkuvPDxw1PVdYC9vkgZDeMx4 k0sA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:message-id:date:user-agent :mime-version:content-transfer-encoding:content-language; bh=iM4pRDmtSKno5C+L0Eh90jes6kqQ9I5ofHeph0xbTvY=; b=FGCAMVKiWYeiR9iroRa2VrcEYe8mmyprEqTx48XQ5R/CviGPtyBuCnYwLNDzL7lFoJ 9v02duaLbrhk3xx9HVezAuRHHLBcPzumybkkpQkZQzi13pUQuBGlktj/aUjWRM4YpKuZ /76j+QDesMUcxhVX5EkyR3NgP8zZXpRuuXnMOxx4LmxhJ4WwTXoOxOExxXiJQA5jv7pD ls3BxOX3gIyn+EhEJqKsIWteFbLr1jI9CLmLQ78o3Fgn7ZtMu5APtnB6KIegV353m499 qU11aMhXq6phw8GtIp67A6lMZstvpAoUz8O+OH952pegJnIHFNUubEetKhYrcfMzASBN 1OJQ== X-Gm-Message-State: AJcUuketWNVB8T9KH6uIp5NF6WzrF87exHZON2498/MUckFYkMhre9rt q9oPk08Lgwh1x9BD8q5DtKA= X-Google-Smtp-Source: ALg8bN7huZn2rSaPL8vZA+vkR734znXNoTvZqPZxIQi5a+cbngjUwkhuetKL7ZRfsy9WMGtbk3/84w== X-Received: by 2002:a50:ac81:: with SMTP id x1mr11106522edc.71.1546158355172; Sun, 30 Dec 2018 00:25:55 -0800 (PST) Received: from ?IPv6:2a02:168:6806:0:4248:8d7:8636:18b9? ([2a02:168:6806:0:4248:8d7:8636:18b9]) by smtp.gmail.com with ESMTPSA id ec19-v6sm8380783ejb.11.2018.12.30.00.25.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 30 Dec 2018 00:25:54 -0800 (PST) From: Klaus Kudielka To: netdev@vger.kernel.org Cc: Andrew Lunn , Florian Fainelli , Heiner Kallweit , Russell King , =?utf-8?q?Uwe_Kleine-K?= =?utf-8?b?w7ZuaWc=?= , Tomas Hlavacek Subject: [RFC] phylink: support for devices with MAC sharing SFP cage & PHY (e.g. Turris Omnia) Message-ID: <97244846-c507-113b-3353-dddc6a50d72b@gmail.com> Date: Sun, 30 Dec 2018 09:25:53 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.2.1 MIME-Version: 1.0 Content-Language: en-US Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Hello, I own a Turris Omnia, which has basic support included in the Linux kernel (armada-385-turris-omnia.dts). Apart from the 88E1514 PHY specified for eth2, the device also features an SFP cage, which uses the same SGMII of the Armada 385 SoC (a 2:1 multiplexer is driven by the MOD_DEF0 signal). Details can be found on page 5 of https://doc.turris.cz/doc/_media/rtrom01-schema.pdf As far as I understand the situation, phylink does not support such an architecture at the moment. This may be the reason why the SFP cage was never specified in the Turris Omnia DTS. Questions: - Is anybody already working on a solution? - If not, would something like the patch below be acceptable? - Any other suggestions, how to get this supported? Summary of the patch, which is based on the device tree published by Tomas (and my interpretation of phylink.c): I'm specifying *both* the SFP cage and the PHY in the node of the eth2 MAC. In phylink_of_connect, if SFP module is already present: Ignore any PHY specified by the devicetree. After SFP removal, restore the original (device tree based) configuration, which was determined by phylink_create et al. (I don't think that this would harm the generic use case) With this, "hot" insertion and removal work, as long as the network interface is down. I tested this successfully on my Turris Omnia, on a relatively recent openwrt-master (4.14 kernel). SFP module is a TP-LINK TL-SM321B. Insertion/removal in the "up" state would require more work. If this is considered necessary, I can give it a try. I am sorry, the patch is against the 4.14 (openwrt) kernel, but you get the basic idea. --- a/arch/arm/boot/dts/armada-385-turris-omnia.dts +++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts @@ -115,6 +115,16 @@              };          };      }; + +    sfp: sfp { +        compatible = "sff,sfp"; +        i2c-bus = <&i2csfp>; +        tx-fault-gpios = <&pcawan 0 GPIO_ACTIVE_HIGH>; +        tx-disable-gpios = <&pcawan 1 GPIO_ACTIVE_HIGH>; +        rate-select0-gpios = <&pcawan 2 GPIO_ACTIVE_HIGH>; +        los-gpios = <&pcawan 3 GPIO_ACTIVE_HIGH>; +        mod-def0-gpios = <&pcawan 4 GPIO_ACTIVE_LOW>; +    };  };  /* Connected to 88E6176 switch, port 6 */ @@ -148,6 +158,7 @@      status = "okay";      phy-mode = "sgmii";      phy = <&phy1>; +    sfp = <&sfp>;  };  &i2c0 { @@ -210,7 +221,7 @@              /* routed to PCIe2 connector (CN62A) */          }; -        i2c@4 { +        i2csfp: i2c@4 {              #address-cells = <1>;              #size-cells = <0>;              reg = <4>; --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -58,6 +58,12 @@ struct phylink {      bool mac_link_dropped;      struct sfp_bus *sfp_bus; + +    /* Things to remember across a module insertion/removal cycle */ +    u8 default_an_mode; +    u8 default_port; +    struct phylink_link_state default_config; +    bool sfp_module_present;  };  static inline void linkmode_zero(unsigned long *dst) @@ -680,6 +686,10 @@ int phylink_of_phy_connect(struct phylin      if (pl->link_an_mode == MLO_AN_FIXED)          return 0; +    /* If SFP module present, we do not need a separate PHY */ +    if (pl->sfp_module_present) +        return 0; +      phy_node = of_parse_phandle(dn, "phy-handle", 0);      if (!phy_node)          phy_node = of_parse_phandle(dn, "phy", 0); @@ -1371,6 +1381,11 @@ static int phylink_sfp_module_insert(voi      if (mode == MLO_AN_8023Z && pl->phydev)          return -EINVAL; +    pl->default_an_mode = pl->link_an_mode; +    pl->default_port = pl->link_port; +    pl->default_config = pl->link_config; +    pl->sfp_module_present = true; +      changed = !bitmap_equal(pl->supported, support,                  __ETHTOOL_LINK_MODE_MASK_NBITS);      if (changed) { @@ -1399,6 +1414,16 @@ static int phylink_sfp_module_insert(voi      return ret;  } +static void phylink_sfp_module_remove(void *upstream) +{ +    struct phylink *pl = upstream; + +    pl->link_an_mode = pl->default_an_mode; +    pl->link_port = pl->default_port; +    pl->link_config = pl->default_config; +    pl->sfp_module_present = false; +} +  static void phylink_sfp_link_down(void *upstream)  {      struct phylink *pl = upstream; @@ -1432,6 +1457,7 @@ static void phylink_sfp_disconnect_phy(v  static const struct sfp_upstream_ops sfp_phylink_ops = {      .module_insert = phylink_sfp_module_insert, +    .module_remove = phylink_sfp_module_remove,      .link_up = phylink_sfp_link_up,      .link_down = phylink_sfp_link_down,      .connect_phy = phylink_sfp_connect_phy,