From patchwork Thu Jun 25 15:23:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 217134 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=-10.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_HELO_NONE, SPF_PASS, USER_AGENT_GIT 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 C9EA0C433E0 for ; Thu, 25 Jun 2020 15:23:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 92D56206C0 for ; Thu, 25 Jun 2020 15:23:47 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="D8UHSAqO" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2405804AbgFYPXq (ORCPT ); Thu, 25 Jun 2020 11:23:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55306 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2405394AbgFYPXp (ORCPT ); Thu, 25 Jun 2020 11:23:45 -0400 Received: from mail-ej1-x644.google.com (mail-ej1-x644.google.com [IPv6:2a00:1450:4864:20::644]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 66D0DC08C5C1 for ; Thu, 25 Jun 2020 08:23:45 -0700 (PDT) Received: by mail-ej1-x644.google.com with SMTP id o18so1904103eje.7 for ; Thu, 25 Jun 2020 08:23:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Ya6MDcC8RS7KztKqBU+U3BhP3PAjLn6YQX31nYlwXic=; b=D8UHSAqOyX5uMXCxj1zeajjol4jW+OXcdwGF1KQuv39O7Mt6TuFWTZ3uUmma/1a/Pf /IvLHQh50KHkbMZcCCUFytQefvUfGEhXmzzsNoGOgtoTOzPJ66gDgdBJ4XGFza+Z0SBn im+lfBJDV3nLWV84+cKFWl23fjCZE13/9EnkcHkKJMqeHN5x+5RlK3Zhnj1mS/kpmsfK feFFFil84GwG6s2/8tqUwLXTewvzuLN3xaxhJtqyYjk4d6/MPu8JrOiImByCh+VMcIPG KK/dLHgAb3cMBhgGjpXo0pGsE+U3GMRIGmw8moMh/J5qrN0AFDXZyTCD7l2kHv0fUkx6 0ndQ== 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:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Ya6MDcC8RS7KztKqBU+U3BhP3PAjLn6YQX31nYlwXic=; b=laUfrzKpREIRFQIGww/LrtP+8/4gpH7mlw21+iBaHsxgto4nIZzGkj1CUKb4BDEdCx jIgWpLwjNmYALEgxfqKaVx0Qws4f10zVRMbMvyU/GE+4zZyb0YcDAmY2KhToRGZcvoIz IRemFY34u34m02X5nuB9qacro7Ds4qa12MhRVRG2Wp8oe8sb/9fCxz3QX7P4Mp6FRRvW 4K8LB2KhU1Rpuy9ohgcoLFJkr1/iHVCWBfjBV2leNPxcfF2XL+PLwJgUVhzLcrS82ZAf iELUq0NqexevnEfUGdcNYD85vJ/ycRijSshk1BMJM02pVBSpi9uo/tY/AqBrHNz5lJfi vGHw== X-Gm-Message-State: AOAM531PnAkLjcxDwEWPkiU74SxGShPVRMmkKXQ0g5dzh9SOqDY1KCD3 JFB2s27QlaTwSpVTqK3yv9t3E3Dy X-Google-Smtp-Source: ABdhPJynPCsFknYPwbVHnRdce5dy4EBSvVkLECrFwp2L/JpaUOUa62Es5wNs7YyoWW7vSJX8TF7HXQ== X-Received: by 2002:a17:906:ef2:: with SMTP id x18mr6433313eji.547.1593098624149; Thu, 25 Jun 2020 08:23:44 -0700 (PDT) Received: from localhost.localdomain ([188.26.56.128]) by smtp.gmail.com with ESMTPSA id o17sm9102898ejb.105.2020.06.25.08.23.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Jun 2020 08:23:41 -0700 (PDT) From: Vladimir Oltean To: davem@davemloft.net, netdev@vger.kernel.org Cc: andrew@lunn.ch, f.fainelli@gmail.com, vivien.didelot@gmail.com, claudiu.manoil@nxp.com, alexandru.marginean@nxp.com, ioana.ciornei@nxp.com, linux@armlinux.org.uk Subject: [PATCH net-next 1/7] net: dsa: felix: stop writing to read-only fields in MII_BMCR Date: Thu, 25 Jun 2020 18:23:25 +0300 Message-Id: <20200625152331.3784018-2-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200625152331.3784018-1-olteanv@gmail.com> References: <20200625152331.3784018-1-olteanv@gmail.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vladimir Oltean It looks like BMCR_SPEED and BMCR_DUPLEX are read-only, since they are actually configured through the vendor-specific IF_MODE (0x14) register. So, don't perform bogus writes to these fields, giving the impression that those writes do something. Signed-off-by: Vladimir Oltean --- drivers/net/dsa/ocelot/felix_vsc9959.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c index 2067776773f7..3269c76b59ff 100644 --- a/drivers/net/dsa/ocelot/felix_vsc9959.c +++ b/drivers/net/dsa/ocelot/felix_vsc9959.c @@ -845,10 +845,7 @@ static void vsc9959_pcs_init_sgmii(struct phy_device *pcs, ENETC_PCS_IF_MODE_SGMII_EN | ENETC_PCS_IF_MODE_SGMII_SPEED(speed)); - /* Yes, not a mistake: speed is given by IF_MODE. */ - phy_write(pcs, MII_BMCR, BMCR_RESET | - BMCR_SPEED1000 | - BMCR_FULLDPLX); + phy_write(pcs, MII_BMCR, BMCR_RESET); } } @@ -882,9 +879,7 @@ static void vsc9959_pcs_init_2500basex(struct phy_device *pcs, ENETC_PCS_IF_MODE_SGMII_EN | ENETC_PCS_IF_MODE_SGMII_SPEED(ENETC_PCS_SPEED_2500)); - phy_write(pcs, MII_BMCR, BMCR_SPEED1000 | - BMCR_FULLDPLX | - BMCR_RESET); + phy_write(pcs, MII_BMCR, BMCR_RESET); } static void vsc9959_pcs_init_usxgmii(struct phy_device *pcs, From patchwork Thu Jun 25 15:23:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 217133 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=-10.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_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT 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 20A37C433E0 for ; Thu, 25 Jun 2020 15:23:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E5F7D206C0 for ; Thu, 25 Jun 2020 15:23:53 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="MXHNrXpl" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2405815AbgFYPXw (ORCPT ); Thu, 25 Jun 2020 11:23:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55326 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2405394AbgFYPXv (ORCPT ); Thu, 25 Jun 2020 11:23:51 -0400 Received: from mail-ed1-x541.google.com (mail-ed1-x541.google.com [IPv6:2a00:1450:4864:20::541]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6C04DC08C5C1 for ; Thu, 25 Jun 2020 08:23:51 -0700 (PDT) Received: by mail-ed1-x541.google.com with SMTP id g1so4519590edv.6 for ; Thu, 25 Jun 2020 08:23:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=dcE3p1bK1dhx6InYLIRr5s7TD7wLBu088hymDs7RaA0=; b=MXHNrXplZC81sgJ96wy5VJuGv3REuHz0ZXWSLm5KWHgvPHwgvQUKsbGQXFv9+jqMhc a5ykbcmNy1932aTeLIO0PmL9pIq8LNHrFqW7oooa/uvcsG9xuiIw1PcHoFjzFLGMYFPG xutlB4Cp0xv5lIjjm9ykQ8rKnTCff1SyVq/0I/CMxC+fVQWFPzSt5zBKDFVDA/6X6G1E TeySg+psyxY7DyodO6RWwHW4yguWCLbtpsOFDtneJjk/kn5cBiwRgHFbIOwos6KU6222 pSEjzOb+iKG+XHbADXkyg0hKLEsfFC8B0sPQBJHz2kLaNMgdLcOg0DZ/yIN59/a7/4QC T/tQ== 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:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=dcE3p1bK1dhx6InYLIRr5s7TD7wLBu088hymDs7RaA0=; b=jyra1veyfsUhzDWftrYhgTcH2ZmQOx8iSMzTwGnN7qxVOr8S4pAzSMi1Iymj0KAliI AG1Ifk0q+5ivL/KlKxConfschXRZQXP+ZBFzO4tAEly1Ao1OhcIxWVTP8e9udOVYJEHg joBWAP3H5ucsoju9gE/KAib8xMZOTYp31SzfmtS6I2dgj2PJPQbHQhiJQ0qjrzzSy8Bj csnuSYeJLPPcIX70Nd7MHyqXO8vUqmuVXw89KnwbetMgkPWuEik3QPqK9xyM+qm7MUt5 1fnZAMASNsfjVvy0s36kTkDhduIildMkttI9GeX6DCNdjqFx1wehANq5Wz/g6Y1zm9jZ whkA== X-Gm-Message-State: AOAM531fzqvY1bnKy+IsU0sFG8/+oKeK1RMyCzI/WBCrW6UH1VKCtY1A IYWrc6pUh9tKDj6RRQyV+Ig= X-Google-Smtp-Source: ABdhPJyGsTseFn/jsAhcryd+BBmPkwSM4umSDbIRWqUBQZOxWsA/fxq/LW5ZuVpxGaKvbmvBuTp4BQ== X-Received: by 2002:a50:e883:: with SMTP id f3mr6318420edn.220.1593098630127; Thu, 25 Jun 2020 08:23:50 -0700 (PDT) Received: from localhost.localdomain ([188.26.56.128]) by smtp.gmail.com with ESMTPSA id o17sm9102898ejb.105.2020.06.25.08.23.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Jun 2020 08:23:47 -0700 (PDT) From: Vladimir Oltean To: davem@davemloft.net, netdev@vger.kernel.org Cc: andrew@lunn.ch, f.fainelli@gmail.com, vivien.didelot@gmail.com, claudiu.manoil@nxp.com, alexandru.marginean@nxp.com, ioana.ciornei@nxp.com, linux@armlinux.org.uk Subject: [PATCH net-next 3/7] net: dsa: felix: unconditionally configure MAC speed to 1000Mbps Date: Thu, 25 Jun 2020 18:23:27 +0300 Message-Id: <20200625152331.3784018-4-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200625152331.3784018-1-olteanv@gmail.com> References: <20200625152331.3784018-1-olteanv@gmail.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vladimir Oltean In VSC9959, the PCS is the one who performs rate adaptation (symbol duplication) to the speed negotiated by the PHY. The MAC is unaware of that and must remain configured for gigabit. If it is configured at OCELOT_SPEED_10 or OCELOT_SPEED_100, it'll start transmitting PAUSE frames out of control and never recover, _even if_ we then reconfigure it at OCELOT_SPEED_1000 afterwards. This patch fixes a bug that luckily did not have any functional impact. We were writing 10, 100, 1000 etc into this 2-bit field in DEV_CLOCK_CFG, but the hardware expects values in the range 0, 1, 2, 3. So all speed values were getting truncated to 0, which is OCELOT_SPEED_2500, and which also appears to be fine. Signed-off-by: Vladimir Oltean --- drivers/net/dsa/ocelot/felix.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c index 25b340e0a6dd..d229cb5d5f9e 100644 --- a/drivers/net/dsa/ocelot/felix.c +++ b/drivers/net/dsa/ocelot/felix.c @@ -240,9 +240,14 @@ static void felix_phylink_mac_config(struct dsa_switch *ds, int port, u32 mac_fc_cfg; /* Take port out of reset by clearing the MAC_TX_RST, MAC_RX_RST and - * PORT_RST bits in CLOCK_CFG + * PORT_RST bits in DEV_CLOCK_CFG. Note that the way this system is + * integrated is that the MAC speed is fixed and it's the PCS who is + * performing the rate adaptation, so we have to write "1000Mbps" into + * the LINK_SPEED field of DEV_CLOCK_CFG (which is also its default + * value). */ - ocelot_port_writel(ocelot_port, DEV_CLOCK_CFG_LINK_SPEED(state->speed), + ocelot_port_writel(ocelot_port, + DEV_CLOCK_CFG_LINK_SPEED(OCELOT_SPEED_1000), DEV_CLOCK_CFG); /* Flow control. Link speed is only used here to evaluate the time From patchwork Thu Jun 25 15:23:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 217132 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=-10.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_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT 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 BDFB8C433DF for ; Thu, 25 Jun 2020 15:24:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 83E1C206C0 for ; Thu, 25 Jun 2020 15:24:07 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="GM+1O3e8" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2405828AbgFYPYG (ORCPT ); Thu, 25 Jun 2020 11:24:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55368 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2405394AbgFYPYF (ORCPT ); Thu, 25 Jun 2020 11:24:05 -0400 Received: from mail-ej1-x642.google.com (mail-ej1-x642.google.com [IPv6:2a00:1450:4864:20::642]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D1082C08C5C1 for ; Thu, 25 Jun 2020 08:24:04 -0700 (PDT) Received: by mail-ej1-x642.google.com with SMTP id i14so6344330ejr.9 for ; Thu, 25 Jun 2020 08:24:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=uy4cc04lGctIV8y5qbKXSbMwhHgLQfNZ4JjK7jOuGek=; b=GM+1O3e865DRz13ba7+2uyNzGrxTJgyEtYzBiYxpxJFhSIOkagax3009NesAaZsOG0 e59yr34hVWuLLyvtIZTDFB6ZaHEVhPwwzoXPhx01tHja5YS9O7klC7xfKJKcNWaEVBNX us6O+rWUnWwNkxH40nyGIJke8zhZHy1049hdjq39VTY8LPYSoJbtKyYrRCbnEJTUKBw6 xZ7GHoeAcfimC/QUp+ycV4AYcUkhfb2Y45OcX8nS/TkBLeXsHUa3+qeyeR5utLN6hcxO YqZu53J8SnznnA7Wlf1dO9wDy+XLRty16bcHeM/OvgGwonzrsDt0mlh0fePCyE4vv18j TGjQ== 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:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=uy4cc04lGctIV8y5qbKXSbMwhHgLQfNZ4JjK7jOuGek=; b=ov0CKN8j9CY2yBc9FlsnnehqoZVqSc+E5FYuutuk9eNa4YgALpjfL+j91DZ8GTR8Qf IzBFVyVleUJiMilMj7MFiLmnJ3VoTt/oHWGdI3Lae/b3713YSmnVGvMx9V1b3CUYjXr7 M9/aUrdIweq/RE3LmTPslSwVIwXUn2uVwF+indniQgcA0okN8pDDrObudjFDsphODuEM BcGuwcBOiyqZByYpXityyUSqaCe7HKvw41FrJe8Dl8ofT2IZfhV9C/hz8KVw+OWd15eC RnccIjjtcO85uX1QekGyGzDSTXakLS6oU8DDwnfVJOfK+45/C7XwZjKX1yED4IJAX4H1 LeLA== X-Gm-Message-State: AOAM533iy71AWc2khy+VMnpeDXAh1SDliGSghAlMryTofCXVWFuKNjU5 zPZWdgU//NQJ3nVnD797nbk= X-Google-Smtp-Source: ABdhPJy3WgrXToSB6MNkzeEi9iBxec4iNQRFPwKbPqqFrPGPIad/7a16m3egoZRHxAR3O9du2oeVaw== X-Received: by 2002:a17:906:1ed2:: with SMTP id m18mr28958227ejj.529.1593098643565; Thu, 25 Jun 2020 08:24:03 -0700 (PDT) Received: from localhost.localdomain ([188.26.56.128]) by smtp.gmail.com with ESMTPSA id o17sm9102898ejb.105.2020.06.25.08.23.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Jun 2020 08:24:00 -0700 (PDT) From: Vladimir Oltean To: davem@davemloft.net, netdev@vger.kernel.org Cc: andrew@lunn.ch, f.fainelli@gmail.com, vivien.didelot@gmail.com, claudiu.manoil@nxp.com, alexandru.marginean@nxp.com, ioana.ciornei@nxp.com, linux@armlinux.org.uk Subject: [PATCH net-next 5/7] net: dsa: felix: delete .phylink_mac_an_restart code Date: Thu, 25 Jun 2020 18:23:29 +0300 Message-Id: <20200625152331.3784018-6-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200625152331.3784018-1-olteanv@gmail.com> References: <20200625152331.3784018-1-olteanv@gmail.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vladimir Oltean In hardware, the AN_RESTART field for these SerDes protocols (SGMII, USXGMII) clears the resolved configuration from the PCS's auto-negotiation state machine. But PHYLINK has a different interpretation of "AN restart". It assumes that this Linux system is capable of re-triggering an auto-negotiation sequence, something which is only possible with 1000Base-X and 2500Base-X, where the auto-negotiation is symmetrical. In SGMII and USXGMII, there's an AN master and an AN slave, and it isn't so much of "auto-negotiation" as it is "PHY passing the resolved link state on to the MAC". So, in PHYLINK's interpretation of "AN restart", it doesn't make sense to do anything for SGMII and USXGMII. In fact, PHYLINK won't even call us for any other SerDes protocol than 1000Base-X and 2500Base-X. But we are not supporting those. So just remove this code. Signed-off-by: Vladimir Oltean --- drivers/net/dsa/ocelot/felix.c | 10 ------- drivers/net/dsa/ocelot/felix.h | 1 - drivers/net/dsa/ocelot/felix_vsc9959.c | 37 -------------------------- 3 files changed, 48 deletions(-) diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c index da337c63e7ca..4ec05090121c 100644 --- a/drivers/net/dsa/ocelot/felix.c +++ b/drivers/net/dsa/ocelot/felix.c @@ -296,15 +296,6 @@ static void felix_phylink_mac_config(struct dsa_switch *ds, int port, state->speed); } -static void felix_phylink_mac_an_restart(struct dsa_switch *ds, int port) -{ - struct ocelot *ocelot = ds->priv; - struct felix *felix = ocelot_to_felix(ocelot); - - if (felix->info->pcs_an_restart) - felix->info->pcs_an_restart(ocelot, port); -} - static void felix_phylink_mac_link_down(struct dsa_switch *ds, int port, unsigned int link_an_mode, phy_interface_t interface) @@ -812,7 +803,6 @@ static const struct dsa_switch_ops felix_switch_ops = { .phylink_validate = felix_phylink_validate, .phylink_mac_link_state = felix_phylink_mac_pcs_get_state, .phylink_mac_config = felix_phylink_mac_config, - .phylink_mac_an_restart = felix_phylink_mac_an_restart, .phylink_mac_link_down = felix_phylink_mac_link_down, .phylink_mac_link_up = felix_phylink_mac_link_up, .port_enable = felix_port_enable, diff --git a/drivers/net/dsa/ocelot/felix.h b/drivers/net/dsa/ocelot/felix.h index a891736ca006..4a4cebcf04a7 100644 --- a/drivers/net/dsa/ocelot/felix.h +++ b/drivers/net/dsa/ocelot/felix.h @@ -31,7 +31,6 @@ struct felix_info { void (*pcs_init)(struct ocelot *ocelot, int port, unsigned int link_an_mode, const struct phylink_link_state *state); - void (*pcs_an_restart)(struct ocelot *ocelot, int port); void (*pcs_link_state)(struct ocelot *ocelot, int port, struct phylink_link_state *state); int (*prevalidate_phy_mode)(struct ocelot *ocelot, int port, diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c index c1220b488f9c..7d2673dab7d3 100644 --- a/drivers/net/dsa/ocelot/felix_vsc9959.c +++ b/drivers/net/dsa/ocelot/felix_vsc9959.c @@ -728,42 +728,6 @@ static int vsc9959_reset(struct ocelot *ocelot) return 0; } -static void vsc9959_pcs_an_restart_sgmii(struct phy_device *pcs) -{ - phy_set_bits(pcs, MII_BMCR, BMCR_ANRESTART); -} - -static void vsc9959_pcs_an_restart_usxgmii(struct phy_device *pcs) -{ - phy_write_mmd(pcs, MDIO_MMD_VEND2, MII_BMCR, - USXGMII_BMCR_RESET | - USXGMII_BMCR_AN_EN | - USXGMII_BMCR_RST_AN); -} - -static void vsc9959_pcs_an_restart(struct ocelot *ocelot, int port) -{ - struct felix *felix = ocelot_to_felix(ocelot); - struct phy_device *pcs = felix->pcs[port]; - - if (!pcs) - return; - - switch (pcs->interface) { - case PHY_INTERFACE_MODE_SGMII: - case PHY_INTERFACE_MODE_QSGMII: - vsc9959_pcs_an_restart_sgmii(pcs); - break; - case PHY_INTERFACE_MODE_USXGMII: - vsc9959_pcs_an_restart_usxgmii(pcs); - break; - default: - dev_err(ocelot->dev, "Invalid PCS interface type %s\n", - phy_modes(pcs->interface)); - break; - } -} - /* We enable SGMII AN only when the PHY has managed = "in-band-status" in the * device tree. If we are in MLO_AN_PHY mode, we program directly state->speed * into the PCS, which is retrieved out-of-band over MDIO. This also has the @@ -1412,7 +1376,6 @@ struct felix_info felix_info_vsc9959 = { .mdio_bus_alloc = vsc9959_mdio_bus_alloc, .mdio_bus_free = vsc9959_mdio_bus_free, .pcs_init = vsc9959_pcs_init, - .pcs_an_restart = vsc9959_pcs_an_restart, .pcs_link_state = vsc9959_pcs_link_state, .prevalidate_phy_mode = vsc9959_prevalidate_phy_mode, .port_setup_tc = vsc9959_port_setup_tc, From patchwork Thu Jun 25 15:23:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 217131 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=-10.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_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT 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 663A1C433DF for ; Thu, 25 Jun 2020 15:24:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 36AA1207BB for ; Thu, 25 Jun 2020 15:24:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="kEQWhpvF" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2405836AbgFYPYM (ORCPT ); Thu, 25 Jun 2020 11:24:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55386 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2405394AbgFYPYL (ORCPT ); Thu, 25 Jun 2020 11:24:11 -0400 Received: from mail-ej1-x643.google.com (mail-ej1-x643.google.com [IPv6:2a00:1450:4864:20::643]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A06E6C08C5C1 for ; Thu, 25 Jun 2020 08:24:10 -0700 (PDT) Received: by mail-ej1-x643.google.com with SMTP id a1so6319598ejg.12 for ; Thu, 25 Jun 2020 08:24:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=USObexE/hT/6mGpzrbUQp+guMgeFe65PHGORji2BxTU=; b=kEQWhpvFfju0nUKOSs28c0DCuRreiW7NJqmIDBpsfEins+C0JH3oA1VOFP94o3ZdlY kbRmntg8tmXX4tpRlc0wJ7E+z3quMIVlly8KLfB135PoGv2xF0HshenG+Qci8iSB7Xv+ CGZrR8vf77f3vAj0ycMiORd2xHE6V5EmO50YvzQ44yk06v1QDIkU2fwmD7AxgrEUfPx8 B0fjkdbk+VIAoisA8XMRWHjmwOExaOzhyU/EdxQwsmSc64H9f3mx//RBNY9lM9uHtvSn f1wYHqZHAcq9roH9dDVluy+I1s+XzilYDLSPpkF/CN0A6ePUGZ9t93fcpuSJKp5TY8tA rnCA== 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:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=USObexE/hT/6mGpzrbUQp+guMgeFe65PHGORji2BxTU=; b=DcACfnASG9Ror+2IUQDS/T7gEfNU49N1PI1J2FZqVHfkvbDlf97OtekUySCL42H0BT e9mJeMz5uhkJ29Vm/1q+ZL0Edf1OCoSuRnuPAB5zO1YWQvPzN744kXsB84h/fuHVfm68 EFN/c7V/XlfWbpWyN3LXZ1VJudDYiaBWPSj/t6QgnuDmMLY7/Imxk4UNFzeS3T2uPI6P rXRRl3ooO6csmT61bAw7liq2c3WWEmMWob5fws+/YZ4+wyvYROPz7YyA28f/PyqD5QWp 1q/mGG7YkWcMwePFNipLRwai10m3VMTsV4QZGzwaP5IF6bbOnSY9BS8KGQUhWjpLc0xj U8iw== X-Gm-Message-State: AOAM531nRUfH31fuAo85Cc4pxmEmX4Ecjt/Q7huHgNoZiD1OWEOqLQ7z ExZuFbUKgNonef27VG/JUfI= X-Google-Smtp-Source: ABdhPJyiShgecJqQZkqG5jyipbQ1K8rv98BUUT5+pMCszxqMkBpaENuPdduRVsGWJpX85mvpZJkQCQ== X-Received: by 2002:a17:906:9394:: with SMTP id l20mr21380848ejx.467.1593098649231; Thu, 25 Jun 2020 08:24:09 -0700 (PDT) Received: from localhost.localdomain ([188.26.56.128]) by smtp.gmail.com with ESMTPSA id o17sm9102898ejb.105.2020.06.25.08.24.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Jun 2020 08:24:07 -0700 (PDT) From: Vladimir Oltean To: davem@davemloft.net, netdev@vger.kernel.org Cc: andrew@lunn.ch, f.fainelli@gmail.com, vivien.didelot@gmail.com, claudiu.manoil@nxp.com, alexandru.marginean@nxp.com, ioana.ciornei@nxp.com, linux@armlinux.org.uk Subject: [PATCH net-next 7/7] net: dsa: felix: use resolved link config in mac_link_up() Date: Thu, 25 Jun 2020 18:23:31 +0300 Message-Id: <20200625152331.3784018-8-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200625152331.3784018-1-olteanv@gmail.com> References: <20200625152331.3784018-1-olteanv@gmail.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vladimir Oltean PHYLINK now requires that parameters established through auto-negotiation be written into the MAC at the time of the mac_link_up() callback. In the case of felix, that means taking the port out of reset, setting the correct timers for PAUSE frames, and enabling/disabling TX flow control. This patch also splits the inband and noinband configuration of the vsc9959 PCS (currently found in a function called "init") into 2 different functions, which have a nomenclature closer to PHYLINK: "config", for inband setup, and "link_up", for noinband (forced) setup. This is necessary as a preparation step for giving up control of the PCS to PHYLINK, which will be done in further patches. Signed-off-by: Vladimir Oltean --- drivers/net/dsa/ocelot/felix.c | 76 ++++---- drivers/net/dsa/ocelot/felix.h | 10 +- drivers/net/dsa/ocelot/felix_vsc9959.c | 258 ++++++++++++++----------- 3 files changed, 187 insertions(+), 157 deletions(-) diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c index 4ec05090121c..0ac875ac1d65 100644 --- a/drivers/net/dsa/ocelot/felix.c +++ b/drivers/net/dsa/ocelot/felix.c @@ -233,6 +233,32 @@ static int felix_phylink_mac_pcs_get_state(struct dsa_switch *ds, int port, static void felix_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int link_an_mode, const struct phylink_link_state *state) +{ + struct ocelot *ocelot = ds->priv; + struct felix *felix = ocelot_to_felix(ocelot); + + if (felix->info->pcs_config) + felix->info->pcs_config(ocelot, port, link_an_mode, state); +} + +static void felix_phylink_mac_link_down(struct dsa_switch *ds, int port, + unsigned int link_an_mode, + phy_interface_t interface) +{ + struct ocelot *ocelot = ds->priv; + struct ocelot_port *ocelot_port = ocelot->ports[port]; + + ocelot_port_writel(ocelot_port, 0, DEV_MAC_ENA_CFG); + ocelot_rmw_rix(ocelot, 0, QSYS_SWITCH_PORT_MODE_PORT_ENA, + QSYS_SWITCH_PORT_MODE, port); +} + +static void felix_phylink_mac_link_up(struct dsa_switch *ds, int port, + unsigned int link_an_mode, + phy_interface_t interface, + struct phy_device *phydev, + int speed, int duplex, + bool tx_pause, bool rx_pause) { struct ocelot *ocelot = ds->priv; struct ocelot_port *ocelot_port = ocelot->ports[port]; @@ -250,7 +276,7 @@ static void felix_phylink_mac_config(struct dsa_switch *ds, int port, DEV_CLOCK_CFG_LINK_SPEED(OCELOT_SPEED_1000), DEV_CLOCK_CFG); - switch (state->speed) { + switch (speed) { case SPEED_10: mac_fc_cfg = SYS_MAC_FC_CFG_FC_LINK_SPEED(3); break; @@ -261,12 +287,9 @@ static void felix_phylink_mac_config(struct dsa_switch *ds, int port, case SPEED_2500: mac_fc_cfg = SYS_MAC_FC_CFG_FC_LINK_SPEED(1); break; - case SPEED_UNKNOWN: - mac_fc_cfg = SYS_MAC_FC_CFG_FC_LINK_SPEED(0); - break; default: dev_err(ocelot->dev, "Unsupported speed on port %d: %d\n", - port, state->speed); + port, speed); return; } @@ -275,7 +298,7 @@ static void felix_phylink_mac_config(struct dsa_switch *ds, int port, */ mac_fc_cfg |= SYS_MAC_FC_CFG_RX_FC_ENA; - if (state->pause & MLO_PAUSE_TX) + if (tx_pause) mac_fc_cfg |= SYS_MAC_FC_CFG_TX_FC_ENA | SYS_MAC_FC_CFG_PAUSE_VAL_CFG(0xffff) | SYS_MAC_FC_CFG_FC_LATENCY_CFG(0x7) | @@ -288,37 +311,9 @@ static void felix_phylink_mac_config(struct dsa_switch *ds, int port, ocelot_write_rix(ocelot, 0, ANA_POL_FLOWC, port); - if (felix->info->pcs_init) - felix->info->pcs_init(ocelot, port, link_an_mode, state); - - if (felix->info->port_sched_speed_set) - felix->info->port_sched_speed_set(ocelot, port, - state->speed); -} - -static void felix_phylink_mac_link_down(struct dsa_switch *ds, int port, - unsigned int link_an_mode, - phy_interface_t interface) -{ - struct ocelot *ocelot = ds->priv; - struct ocelot_port *ocelot_port = ocelot->ports[port]; - - ocelot_port_writel(ocelot_port, 0, DEV_MAC_ENA_CFG); - ocelot_rmw_rix(ocelot, 0, QSYS_SWITCH_PORT_MODE_PORT_ENA, - QSYS_SWITCH_PORT_MODE, port); -} - -static void felix_phylink_mac_link_up(struct dsa_switch *ds, int port, - unsigned int link_an_mode, - phy_interface_t interface, - struct phy_device *phydev, - int speed, int duplex, - bool tx_pause, bool rx_pause) -{ - struct ocelot *ocelot = ds->priv; - struct ocelot_port *ocelot_port = ocelot->ports[port]; - - /* Enable MAC module */ + /* Undo the effects of felix_phylink_mac_link_down: + * enable MAC module + */ ocelot_port_writel(ocelot_port, DEV_MAC_ENA_CFG_RX_ENA | DEV_MAC_ENA_CFG_TX_ENA, DEV_MAC_ENA_CFG); @@ -335,6 +330,13 @@ static void felix_phylink_mac_link_up(struct dsa_switch *ds, int port, QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG(1) | QSYS_SWITCH_PORT_MODE_PORT_ENA, QSYS_SWITCH_PORT_MODE, port); + + if (felix->info->pcs_link_up) + felix->info->pcs_link_up(ocelot, port, link_an_mode, interface, + speed, duplex); + + if (felix->info->port_sched_speed_set) + felix->info->port_sched_speed_set(ocelot, port, speed); } static void felix_port_qos_map_init(struct ocelot *ocelot, int port) diff --git a/drivers/net/dsa/ocelot/felix.h b/drivers/net/dsa/ocelot/felix.h index 4a4cebcf04a7..00137b64132b 100644 --- a/drivers/net/dsa/ocelot/felix.h +++ b/drivers/net/dsa/ocelot/felix.h @@ -28,9 +28,13 @@ struct felix_info { int imdio_pci_bar; int (*mdio_bus_alloc)(struct ocelot *ocelot); void (*mdio_bus_free)(struct ocelot *ocelot); - void (*pcs_init)(struct ocelot *ocelot, int port, - unsigned int link_an_mode, - const struct phylink_link_state *state); + void (*pcs_config)(struct ocelot *ocelot, int port, + unsigned int link_an_mode, + const struct phylink_link_state *state); + void (*pcs_link_up)(struct ocelot *ocelot, int port, + unsigned int link_an_mode, + phy_interface_t interface, + int speed, int duplex); void (*pcs_link_state)(struct ocelot *ocelot, int port, struct phylink_link_state *state); int (*prevalidate_phy_mode)(struct ocelot *ocelot, int port, diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c index dba62c609efc..f9ddac7f48ae 100644 --- a/drivers/net/dsa/ocelot/felix_vsc9959.c +++ b/drivers/net/dsa/ocelot/felix_vsc9959.c @@ -737,125 +737,54 @@ static int vsc9959_reset(struct ocelot *ocelot) * traffic if SGMII AN is enabled but not completed (acknowledged by us), so * setting MLO_AN_INBAND is actually required for those. */ -static void vsc9959_pcs_init_sgmii(struct phy_device *pcs, - unsigned int link_an_mode, - const struct phylink_link_state *state) +static void vsc9959_pcs_config_sgmii(struct phy_device *pcs, + unsigned int link_an_mode, + const struct phylink_link_state *state) { - if (link_an_mode == MLO_AN_INBAND) { - int bmsr, bmcr; - - /* Some PHYs like VSC8234 don't like it when AN restarts on - * their system side and they restart line side AN too, going - * into an endless link up/down loop. Don't restart PCS AN if - * link is up already. - * We do check that AN is enabled just in case this is the 1st - * call, PCS detects a carrier but AN is disabled from power on - * or by boot loader. - */ - bmcr = phy_read(pcs, MII_BMCR); - if (bmcr < 0) - return; - - bmsr = phy_read(pcs, MII_BMSR); - if (bmsr < 0) - return; - - if ((bmcr & BMCR_ANENABLE) && (bmsr & BMSR_LSTATUS)) - return; - - /* SGMII spec requires tx_config_Reg[15:0] to be exactly 0x4001 - * for the MAC PCS in order to acknowledge the AN. - */ - phy_write(pcs, MII_ADVERTISE, ADVERTISE_SGMII | - ADVERTISE_LPACK); - - phy_write(pcs, ENETC_PCS_IF_MODE, - ENETC_PCS_IF_MODE_SGMII_EN | - ENETC_PCS_IF_MODE_USE_SGMII_AN); - - /* Adjust link timer for SGMII */ - phy_write(pcs, ENETC_PCS_LINK_TIMER1, - ENETC_PCS_LINK_TIMER1_VAL); - phy_write(pcs, ENETC_PCS_LINK_TIMER2, - ENETC_PCS_LINK_TIMER2_VAL); - - phy_write(pcs, MII_BMCR, BMCR_ANRESTART | BMCR_ANENABLE); - } else { - u16 if_mode = ENETC_PCS_IF_MODE_SGMII_EN; - int speed; - - switch (state->speed) { - case SPEED_1000: - speed = ENETC_PCS_SPEED_1000; - break; - case SPEED_100: - speed = ENETC_PCS_SPEED_100; - break; - case SPEED_10: - speed = ENETC_PCS_SPEED_10; - break; - case SPEED_UNKNOWN: - /* Silently don't do anything */ - return; - default: - phydev_err(pcs, "Invalid PCS speed %d\n", state->speed); - return; - } - - if_mode |= ENETC_PCS_IF_MODE_SGMII_SPEED(speed); - if (state->duplex == DUPLEX_HALF) - if_mode |= ENETC_PCS_IF_MODE_DUPLEX_HALF; - - phy_write(pcs, ENETC_PCS_IF_MODE, if_mode); - phy_write(pcs, MII_BMCR, 0); - } -} + int bmsr, bmcr; + + /* Some PHYs like VSC8234 don't like it when AN restarts on + * their system side and they restart line side AN too, going + * into an endless link up/down loop. Don't restart PCS AN if + * link is up already. + * We do check that AN is enabled just in case this is the 1st + * call, PCS detects a carrier but AN is disabled from power on + * or by boot loader. + */ + bmcr = phy_read(pcs, MII_BMCR); + if (bmcr < 0) + return; -/* 2500Base-X is SerDes protocol 7 on Felix and 6 on ENETC. It is a SerDes lane - * clocked at 3.125 GHz which encodes symbols with 8b/10b and does not have - * auto-negotiation of any link parameters. Electrically it is compatible with - * a single lane of XAUI. - * The hardware reference manual wants to call this mode SGMII, but it isn't - * really, since the fundamental features of SGMII: - * - Downgrading the link speed by duplicating symbols - * - Auto-negotiation - * are not there. - * The speed is configured at 1000 in the IF_MODE and BMCR MDIO registers - * because the clock frequency is actually given by a PLL configured in the - * Reset Configuration Word (RCW). - * Since there is no difference between fixed speed SGMII w/o AN and 802.3z w/o - * AN, we call this PHY interface type 2500Base-X. In case a PHY negotiates a - * lower link speed on line side, the system-side interface remains fixed at - * 2500 Mbps and we do rate adaptation through pause frames. - */ -static void vsc9959_pcs_init_2500basex(struct phy_device *pcs, - unsigned int link_an_mode, - const struct phylink_link_state *state) -{ - u16 if_mode = ENETC_PCS_IF_MODE_SGMII_SPEED(ENETC_PCS_SPEED_2500) | - ENETC_PCS_IF_MODE_SGMII_EN; + bmsr = phy_read(pcs, MII_BMSR); + if (bmsr < 0) + return; - if (link_an_mode == MLO_AN_INBAND) { - phydev_err(pcs, "AN not supported on 3.125GHz SerDes lane\n"); + if ((bmcr & BMCR_ANENABLE) && (bmsr & BMSR_LSTATUS)) return; - } - if (state->duplex == DUPLEX_HALF) - if_mode |= ENETC_PCS_IF_MODE_DUPLEX_HALF; + /* SGMII spec requires tx_config_Reg[15:0] to be exactly 0x4001 + * for the MAC PCS in order to acknowledge the AN. + */ + phy_write(pcs, MII_ADVERTISE, ADVERTISE_SGMII | + ADVERTISE_LPACK); - phy_write(pcs, ENETC_PCS_IF_MODE, if_mode); - phy_write(pcs, MII_BMCR, 0); + phy_write(pcs, ENETC_PCS_IF_MODE, + ENETC_PCS_IF_MODE_SGMII_EN | + ENETC_PCS_IF_MODE_USE_SGMII_AN); + + /* Adjust link timer for SGMII */ + phy_write(pcs, ENETC_PCS_LINK_TIMER1, + ENETC_PCS_LINK_TIMER1_VAL); + phy_write(pcs, ENETC_PCS_LINK_TIMER2, + ENETC_PCS_LINK_TIMER2_VAL); + + phy_write(pcs, MII_BMCR, BMCR_ANRESTART | BMCR_ANENABLE); } -static void vsc9959_pcs_init_usxgmii(struct phy_device *pcs, - unsigned int link_an_mode, - const struct phylink_link_state *state) +static void vsc9959_pcs_config_usxgmii(struct phy_device *pcs, + unsigned int link_an_mode, + const struct phylink_link_state *state) { - if (link_an_mode != MLO_AN_INBAND) { - phydev_err(pcs, "USXGMII only supports in-band AN for now\n"); - return; - } - /* Configure device ability for the USXGMII Replicator */ phy_write_mmd(pcs, MDIO_MMD_VEND2, MII_ADVERTISE, USXGMII_ADVERTISE_SPEED(USXGMII_SPEED_2500) | @@ -865,9 +794,9 @@ static void vsc9959_pcs_init_usxgmii(struct phy_device *pcs, USXGMII_ADVERTISE_FDX); } -static void vsc9959_pcs_init(struct ocelot *ocelot, int port, - unsigned int link_an_mode, - const struct phylink_link_state *state) +static void vsc9959_pcs_config(struct ocelot *ocelot, int port, + unsigned int link_an_mode, + const struct phylink_link_state *state) { struct felix *felix = ocelot_to_felix(ocelot); struct phy_device *pcs = felix->pcs[port]; @@ -899,16 +828,110 @@ static void vsc9959_pcs_init(struct ocelot *ocelot, int port, pcs->supported); phy_advertise_supported(pcs); + if (!phylink_autoneg_inband(link_an_mode)) + return; + switch (pcs->interface) { case PHY_INTERFACE_MODE_SGMII: case PHY_INTERFACE_MODE_QSGMII: - vsc9959_pcs_init_sgmii(pcs, link_an_mode, state); + vsc9959_pcs_config_sgmii(pcs, link_an_mode, state); break; case PHY_INTERFACE_MODE_2500BASEX: - vsc9959_pcs_init_2500basex(pcs, link_an_mode, state); + phydev_err(pcs, "AN not supported on 3.125GHz SerDes lane\n"); break; case PHY_INTERFACE_MODE_USXGMII: - vsc9959_pcs_init_usxgmii(pcs, link_an_mode, state); + vsc9959_pcs_config_usxgmii(pcs, link_an_mode, state); + break; + default: + dev_err(ocelot->dev, "Unsupported link mode %s\n", + phy_modes(pcs->interface)); + } +} + +static void vsc9959_pcs_link_up_sgmii(struct phy_device *pcs, + unsigned int link_an_mode, + int speed, int duplex) +{ + u16 if_mode = ENETC_PCS_IF_MODE_SGMII_EN; + + switch (speed) { + case SPEED_1000: + if_mode |= ENETC_PCS_IF_MODE_SGMII_SPEED(ENETC_PCS_SPEED_1000); + break; + case SPEED_100: + if_mode |= ENETC_PCS_IF_MODE_SGMII_SPEED(ENETC_PCS_SPEED_100); + break; + case SPEED_10: + if_mode |= ENETC_PCS_IF_MODE_SGMII_SPEED(ENETC_PCS_SPEED_10); + break; + default: + phydev_err(pcs, "Invalid PCS speed %d\n", speed); + return; + } + + if (duplex == DUPLEX_HALF) + if_mode |= ENETC_PCS_IF_MODE_DUPLEX_HALF; + + phy_write(pcs, ENETC_PCS_IF_MODE, if_mode); + phy_write(pcs, MII_BMCR, 0); +} + +/* 2500Base-X is SerDes protocol 7 on Felix and 6 on ENETC. It is a SerDes lane + * clocked at 3.125 GHz which encodes symbols with 8b/10b and does not have + * auto-negotiation of any link parameters. Electrically it is compatible with + * a single lane of XAUI. + * The hardware reference manual wants to call this mode SGMII, but it isn't + * really, since the fundamental features of SGMII: + * - Downgrading the link speed by duplicating symbols + * - Auto-negotiation + * are not there. + * The speed is configured at 1000 in the IF_MODE and BMCR MDIO registers + * because the clock frequency is actually given by a PLL configured in the + * Reset Configuration Word (RCW). + * Since there is no difference between fixed speed SGMII w/o AN and 802.3z w/o + * AN, we call this PHY interface type 2500Base-X. In case a PHY negotiates a + * lower link speed on line side, the system-side interface remains fixed at + * 2500 Mbps and we do rate adaptation through pause frames. + */ +static void vsc9959_pcs_link_up_2500basex(struct phy_device *pcs, + unsigned int link_an_mode, + int speed, int duplex) +{ + u16 if_mode = ENETC_PCS_IF_MODE_SGMII_SPEED(ENETC_PCS_SPEED_2500) | + ENETC_PCS_IF_MODE_SGMII_EN; + + if (duplex == DUPLEX_HALF) + if_mode |= ENETC_PCS_IF_MODE_DUPLEX_HALF; + + phy_write(pcs, ENETC_PCS_IF_MODE, if_mode); + phy_write(pcs, MII_BMCR, 0); +} + +static void vsc9959_pcs_link_up(struct ocelot *ocelot, int port, + unsigned int link_an_mode, + phy_interface_t interface, + int speed, int duplex) +{ + struct felix *felix = ocelot_to_felix(ocelot); + struct phy_device *pcs = felix->pcs[port]; + + if (!pcs) + return; + + if (phylink_autoneg_inband(link_an_mode)) + return; + + switch (interface) { + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_QSGMII: + vsc9959_pcs_link_up_sgmii(pcs, link_an_mode, speed, duplex); + break; + case PHY_INTERFACE_MODE_2500BASEX: + vsc9959_pcs_link_up_2500basex(pcs, link_an_mode, speed, + duplex); + break; + case PHY_INTERFACE_MODE_USXGMII: + phydev_err(pcs, "USXGMII only supports in-band AN for now\n"); break; default: dev_err(ocelot->dev, "Unsupported link mode %s\n", @@ -1375,7 +1398,8 @@ struct felix_info felix_info_vsc9959 = { .imdio_pci_bar = 0, .mdio_bus_alloc = vsc9959_mdio_bus_alloc, .mdio_bus_free = vsc9959_mdio_bus_free, - .pcs_init = vsc9959_pcs_init, + .pcs_config = vsc9959_pcs_config, + .pcs_link_up = vsc9959_pcs_link_up, .pcs_link_state = vsc9959_pcs_link_state, .prevalidate_phy_mode = vsc9959_prevalidate_phy_mode, .port_setup_tc = vsc9959_port_setup_tc,