Message ID | 20231218071118.21879-1-quic_snehshah@quicinc.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel+bounces-3081-ouuuleilei=gmail.com@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:24d3:b0:fb:cd0c:d3e with SMTP id r19csp1075036dyi; Sun, 17 Dec 2023 23:12:28 -0800 (PST) X-Google-Smtp-Source: AGHT+IEnAuiugOSFsvGPN+UoUTua05oKlFPDH6XPut+cBtJAeDtBryL3uKUO8oBRi1K5KwMVNXM/ X-Received: by 2002:ac8:7f48:0:b0:425:4043:18c9 with SMTP id g8-20020ac87f48000000b00425404318c9mr23380540qtk.124.1702883548796; Sun, 17 Dec 2023 23:12:28 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1702883548; cv=none; d=google.com; s=arc-20160816; b=ngtzWrvDqVsLrWC0uwex2FWxlgv+16YXH0CkmSjyhXnVRr+ATsLcUSo+Sn634NSax5 4utWhAtytxPpWcxavfAcX8l5uAIXPJwBuF5G0ADMvSJQZGsLiSGBDtWRy6CVH3bpuRY3 pk4RavXq9XT2St+ZjIGFB+Nea27otg7a2MAYkdUsrqDN/vxJSn/vCEFdvDcXQ/zM1y5o ObsXME0uInLd7MCmRPsOmE9zd3/eayAFqJkvQBVqxCCoouPedY9LJvzaxcTRUydIguuP aFuy3g3qHKhVgtYyIvcMz4Yqwm5w/pKzjr1jUR7gFNbg+i/F3ZQdhUgbkGXBGcK/FwfB +gQw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-subscribe:list-id:precedence:message-id:date :subject:cc:to:from:dkim-signature; bh=V3p1JFE4C6ua8k53+rwVOsLfLC5EdBhsrQCkXO9H+28=; fh=gcKuIwxwcx3z1X4hsHxbeqcdgBOSbYQMQyUNPBSxPTA=; b=tunw4DstvSB9sQShe9H3TM+vUsG1ytiyzquUQoKhulYwEYa2ZtFQZGq0Lh5lwP01yE SxkiqHY837yO4mI8Py1v2LQN0oMIvkT883CrmN+UCPiXM7Ci26yEta3bLx1PB2wl1PHW FSjsaYam+V5nXnqjxR6XbxmeDlYmkjsRyxOr+4TOi23aZVv/xdPvhfvJ453JRMoUghrl C9qJNeNwZfPGHmUyUy59JXJ5lCvmlwz5F+YV/Vh/zODsMtii2/RIx+MydSfP6dW1zFGd FsVQtXoKE6Y3EM3eqO4Q4+BYeM22MvOTAak+J6DjreBbmxZd2IA5IBAWvoKYQpSMA4aF DunA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=gO4kYuKu; spf=pass (google.com: domain of linux-kernel+bounces-3081-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-3081-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=quicinc.com Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id jx9-20020a05622a810900b0041cbdc9c803si21121519qtb.401.2023.12.17.23.12.28 for <ouuuleilei@gmail.com> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 17 Dec 2023 23:12:28 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-3081-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=gO4kYuKu; spf=pass (google.com: domain of linux-kernel+bounces-3081-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-3081-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=quicinc.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 854931C20B4B for <ouuuleilei@gmail.com>; Mon, 18 Dec 2023 07:12:28 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id D772CF51F; Mon, 18 Dec 2023 07:11:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="gO4kYuKu" X-Original-To: linux-kernel@vger.kernel.org Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7CC2F1FB2; Mon, 18 Dec 2023 07:11:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=qualcomm.com Received: from pps.filterd (m0279869.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 3BI6W2th032313; Mon, 18 Dec 2023 07:11:24 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= from:to:cc:subject:date:message-id; s=qcppdkim1; bh=V3p1JFE4C6ua 8k53+rwVOsLfLC5EdBhsrQCkXO9H+28=; b=gO4kYuKujzcT8NP7HPlW1SoJGLXV fY/lcdE3Jq65e0NtDOh7zqKB7ZRcKU3coLW4fQ9R2srjwKCcRlQim8MaZn095+/f 3pNUP+TNFRkGGg7Y0+gcw262YMTCoSTX/AdwphqLGlaYx3614qRHNqb+Mm9xDKDr ULNIS97+q7eXM1TuN5Y2430/7PBqUw6VXVHxL1+1ZVXeMvWB8bhjgYH5UJEaDl4x wuVDE+XN2HpRQNQYwRPPhk7ZqT2ADxQYF+StnMW7TLwXfzCLD9ZsAzFdPf6rctr9 JwFXHtcZjel4nqOuXV0eLaf8X0RzXjci9/ILR0cT0UfZ9+Ms4ronnLrLVg== Received: from apblrppmta01.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com [103.229.18.19]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3v2gw0r2gu-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 18 Dec 2023 07:11:24 +0000 (GMT) Received: from pps.filterd (APBLRPPMTA01.qualcomm.com [127.0.0.1]) by APBLRPPMTA01.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 3BI7BLno004919; Mon, 18 Dec 2023 07:11:21 GMT Received: from pps.reinject (localhost [127.0.0.1]) by APBLRPPMTA01.qualcomm.com (PPS) with ESMTP id 3v14ykxp2e-1; Mon, 18 Dec 2023 07:11:21 +0000 Received: from APBLRPPMTA01.qualcomm.com (APBLRPPMTA01.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3BI7BLPF004913; Mon, 18 Dec 2023 07:11:21 GMT Received: from hu-maiyas-hyd.qualcomm.com (hu-snehshah-hyd.qualcomm.com [10.147.246.35]) by APBLRPPMTA01.qualcomm.com (PPS) with ESMTP id 3BI7BKnM004911; Mon, 18 Dec 2023 07:11:21 +0000 Received: by hu-maiyas-hyd.qualcomm.com (Postfix, from userid 2319345) id 9CACB5001DB; Mon, 18 Dec 2023 12:41:19 +0530 (+0530) From: Sneh Shah <quic_snehshah@quicinc.com> To: Vinod Koul <vkoul@kernel.org>, Bhupesh Sharma <bhupesh.sharma@linaro.org>, Alexandre Torgue <alexandre.torgue@foss.st.com>, Jose Abreu <joabreu@synopsys.com>, "David S. Miller" <davem@davemloft.net>, Eric Dumazet <edumazet@google.com>, Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>, Maxime Coquelin <mcoquelin.stm32@gmail.com>, netdev@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Andrew Halaney <ahalaney@redhat.com> Cc: Sneh Shah <quic_snehshah@quicinc.com>, kernel@quicinc.com Subject: [PATCH net-next] net: stmmac: dwmac-qcom-ethqos: Add support for 2.5G SGMII Date: Mon, 18 Dec 2023 12:41:18 +0530 Message-Id: <20231218071118.21879-1-quic_snehshah@quicinc.com> X-Mailer: git-send-email 2.17.1 X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: oXJQX_IlBXkALNAjyU-vo8QDVoD6Vehy X-Proofpoint-ORIG-GUID: oXJQX_IlBXkALNAjyU-vo8QDVoD6Vehy X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.997,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-12-09_02,2023-12-07_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 impostorscore=0 mlxscore=0 adultscore=0 malwarescore=0 suspectscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxlogscore=999 phishscore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2311290000 definitions=main-2312180049 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: <linux-kernel.vger.kernel.org> List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org> List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org> X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1785602820235306704 X-GMAIL-MSGID: 1785602820235306704 |
Series |
[net-next] net: stmmac: dwmac-qcom-ethqos: Add support for 2.5G SGMII
|
|
Commit Message
Sneh Shah
Dec. 18, 2023, 7:11 a.m. UTC
Serdes phy needs to operate at 2500 mode for 2.5G speed and 1000
mode for 1G/100M/10M speed.
Added changes to configure serdes phy and mac based on link speed.
Signed-off-by: Sneh Shah <quic_snehshah@quicinc.com>
---
.../stmicro/stmmac/dwmac-qcom-ethqos.c | 31 +++++++++++++++++--
1 file changed, 29 insertions(+), 2 deletions(-)
Comments
Hi, On Mon, 18 Dec 2023 12:41:18 +0530 Sneh Shah <quic_snehshah@quicinc.com> wrote: > Serdes phy needs to operate at 2500 mode for 2.5G speed and 1000 > mode for 1G/100M/10M speed. > Added changes to configure serdes phy and mac based on link speed. > > Signed-off-by: Sneh Shah <quic_snehshah@quicinc.com> > --- > .../stmicro/stmmac/dwmac-qcom-ethqos.c | 31 +++++++++++++++++-- > 1 file changed, 29 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c > index d3bf42d0fceb..b3a28dc19161 100644 > --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c > +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c > @@ -21,6 +21,7 @@ > #define RGMII_IO_MACRO_CONFIG2 0x1C > #define RGMII_IO_MACRO_DEBUG1 0x20 > #define EMAC_SYSTEM_LOW_POWER_DEBUG 0x28 > +#define ETHQOS_MAC_AN_CTRL 0xE0 > > /* RGMII_IO_MACRO_CONFIG fields */ > #define RGMII_CONFIG_FUNC_CLK_EN BIT(30) > @@ -78,6 +79,10 @@ > #define ETHQOS_MAC_CTRL_SPEED_MODE BIT(14) > #define ETHQOS_MAC_CTRL_PORT_SEL BIT(15) > > +/*ETHQOS_MAC_AN_CTRL bits */ > +#define ETHQOS_MAC_AN_CTRL_RAN BIT(9) > +#define ETHQOS_MAC_AN_CTRL_ANE BIT(12) > + > struct ethqos_emac_por { > unsigned int offset; > unsigned int value; > @@ -109,6 +114,7 @@ struct qcom_ethqos { > unsigned int num_por; > bool rgmii_config_loopback_en; > bool has_emac_ge_3; > + unsigned int serdes_speed; Looks like you are storing SPEED_XXX definitions here, which can be negative in case of SPEED_UNKNOWN, so this should be an int. > }; > > static int rgmii_readl(struct qcom_ethqos *ethqos, unsigned int offset) > @@ -600,27 +606,47 @@ static int ethqos_configure_rgmii(struct qcom_ethqos *ethqos) > > static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos) > { > - int val; > - > + int val, mac_an_value; > val = readl(ethqos->mac_base + MAC_CTRL_REG); > + mac_an_value = readl(ethqos->mac_base + ETHQOS_MAC_AN_CTRL); > > switch (ethqos->speed) { > + case SPEED_2500: > + val &= ~ETHQOS_MAC_CTRL_PORT_SEL; > + rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG, > + RGMII_CONFIG2_RGMII_CLK_SEL_CFG, > + RGMII_IO_MACRO_CONFIG2); > + if (ethqos->serdes_speed != SPEED_2500) > + phy_set_speed(ethqos->serdes_phy, ethqos->speed); > + mac_an_value &= ~ETHQOS_MAC_AN_CTRL_ANE; > + break; > case SPEED_1000: > val &= ~ETHQOS_MAC_CTRL_PORT_SEL; > rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG, > RGMII_CONFIG2_RGMII_CLK_SEL_CFG, > RGMII_IO_MACRO_CONFIG2); > + if (ethqos->serdes_speed != SPEED_1000) > + phy_set_speed(ethqos->serdes_phy, ethqos->speed); > + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; > break; > case SPEED_100: > val |= ETHQOS_MAC_CTRL_PORT_SEL | ETHQOS_MAC_CTRL_SPEED_MODE; > + if (ethqos->serdes_speed != SPEED_1000) > + phy_set_speed(ethqos->serdes_phy, ethqos->speed); I understand that SGMII's serdes always runs at 1000 / 2500, but this check doesn't make much sense then, if the speed isn't 1000, then you set the serdes PHY's speed to 100, and the assignment that comes after that switch-case will also set the serdes speed to 100. Also, if the serdes PHY really needs to be configured differently for 10/100/1000, then switching from speed 1000 to speed 100 for example won't trigger a serdes PHY reconfiguration here. My guess is that you want something like : phy_set_speed(ethqos->serdes_phy, SPEED_1000) and the assignment at the end of the switch-case should be SPEED_1000/SPEED_2500 only (see the comment bellow). > + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; > break; > case SPEED_10: > val |= ETHQOS_MAC_CTRL_PORT_SEL; > val &= ~ETHQOS_MAC_CTRL_SPEED_MODE; > + if (ethqos->serdes_speed != SPEED_1000) > + phy_set_speed(ethqos->serdes_phy, ethqos->speed); Same remark here > + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; > break; > } > > writel(val, ethqos->mac_base + MAC_CTRL_REG); > + writel(mac_an_value, ethqos->mac_base + ETHQOS_MAC_AN_CTRL); > + ethqos->serdes_speed = ethqos->speed; Although the code will behave the same, as you are storing the true serdes speed here, shouldn't it be either SPEED_1000 or SPEED_2500 ? You'll end-up storing SPEED_10 / SPEED_100 should the link use these speeds, which doesn't represent the true serdes speed. This would spare serdes reconfigurations when alternating between 10/100/1000M speeds. > return val; > } > @@ -789,6 +815,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev) > "Failed to get serdes phy\n"); > > ethqos->speed = SPEED_1000; > + ethqos->serdes_speed = SPEED_1000; > ethqos_update_link_clk(ethqos, SPEED_1000); > ethqos_set_func_clk_en(ethqos); > Thanks, Maxime
Hi, On 12/18/2023 7:51 PM, Maxime Chevallier wrote: > Hi, > > On Mon, 18 Dec 2023 12:41:18 +0530 > Sneh Shah <quic_snehshah@quicinc.com> wrote: > >> Serdes phy needs to operate at 2500 mode for 2.5G speed and 1000 >> mode for 1G/100M/10M speed. >> Added changes to configure serdes phy and mac based on link speed. >> >> Signed-off-by: Sneh Shah <quic_snehshah@quicinc.com> >> --- >> .../stmicro/stmmac/dwmac-qcom-ethqos.c | 31 +++++++++++++++++-- >> 1 file changed, 29 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c >> index d3bf42d0fceb..b3a28dc19161 100644 >> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c >> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c >> @@ -21,6 +21,7 @@ >> #define RGMII_IO_MACRO_CONFIG2 0x1C >> #define RGMII_IO_MACRO_DEBUG1 0x20 >> #define EMAC_SYSTEM_LOW_POWER_DEBUG 0x28 >> +#define ETHQOS_MAC_AN_CTRL 0xE0 >> >> /* RGMII_IO_MACRO_CONFIG fields */ >> #define RGMII_CONFIG_FUNC_CLK_EN BIT(30) >> @@ -78,6 +79,10 @@ >> #define ETHQOS_MAC_CTRL_SPEED_MODE BIT(14) >> #define ETHQOS_MAC_CTRL_PORT_SEL BIT(15) >> >> +/*ETHQOS_MAC_AN_CTRL bits */ >> +#define ETHQOS_MAC_AN_CTRL_RAN BIT(9) >> +#define ETHQOS_MAC_AN_CTRL_ANE BIT(12) >> + >> struct ethqos_emac_por { >> unsigned int offset; >> unsigned int value; >> @@ -109,6 +114,7 @@ struct qcom_ethqos { >> unsigned int num_por; >> bool rgmii_config_loopback_en; >> bool has_emac_ge_3; >> + unsigned int serdes_speed; > > Looks like you are storing SPEED_XXX definitions here, which can be > negative in case of SPEED_UNKNOWN, so this should be an int. Agree, will update this in next patch. > >> }; >> >> static int rgmii_readl(struct qcom_ethqos *ethqos, unsigned int offset) >> @@ -600,27 +606,47 @@ static int ethqos_configure_rgmii(struct qcom_ethqos *ethqos) >> >> static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos) >> { >> - int val; >> - >> + int val, mac_an_value; >> val = readl(ethqos->mac_base + MAC_CTRL_REG); >> + mac_an_value = readl(ethqos->mac_base + ETHQOS_MAC_AN_CTRL); >> >> switch (ethqos->speed) { >> + case SPEED_2500: >> + val &= ~ETHQOS_MAC_CTRL_PORT_SEL; >> + rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG, >> + RGMII_CONFIG2_RGMII_CLK_SEL_CFG, >> + RGMII_IO_MACRO_CONFIG2); >> + if (ethqos->serdes_speed != SPEED_2500) >> + phy_set_speed(ethqos->serdes_phy, ethqos->speed); >> + mac_an_value &= ~ETHQOS_MAC_AN_CTRL_ANE; >> + break; >> case SPEED_1000: >> val &= ~ETHQOS_MAC_CTRL_PORT_SEL; >> rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG, >> RGMII_CONFIG2_RGMII_CLK_SEL_CFG, >> RGMII_IO_MACRO_CONFIG2); >> + if (ethqos->serdes_speed != SPEED_1000) >> + phy_set_speed(ethqos->serdes_phy, ethqos->speed); >> + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; >> break; >> case SPEED_100: >> val |= ETHQOS_MAC_CTRL_PORT_SEL | ETHQOS_MAC_CTRL_SPEED_MODE; >> + if (ethqos->serdes_speed != SPEED_1000) >> + phy_set_speed(ethqos->serdes_phy, ethqos->speed); > > I understand that SGMII's serdes always runs at 1000 / 2500, but this > check doesn't make much sense then, if the speed isn't 1000, then you > set the serdes PHY's speed to 100, and the assignment that comes after > that switch-case will also set the serdes speed to 100. > > Also, if the serdes PHY really needs to be configured differently for > 10/100/1000, then switching from speed 1000 to speed 100 for example > won't trigger a serdes PHY reconfiguration here. > > My guess is that you want something like : > > phy_set_speed(ethqos->serdes_phy, SPEED_1000) > > and the assignment at the end of the switch-case should be > SPEED_1000/SPEED_2500 only (see the comment bellow). Good point, we have only serdes speed of 1000 and 2500. So for 1000/100/10 we should set ethqos_serdes to speed_1000 and pass speed_1000 to phy_set_speed in case of 1000/100/10. Will update this in next patch. > >> + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; >> break; >> case SPEED_10: >> val |= ETHQOS_MAC_CTRL_PORT_SEL; >> val &= ~ETHQOS_MAC_CTRL_SPEED_MODE; >> + if (ethqos->serdes_speed != SPEED_1000) >> + phy_set_speed(ethqos->serdes_phy, ethqos->speed); > > Same remark here > >> + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; >> break; >> } >> >> writel(val, ethqos->mac_base + MAC_CTRL_REG); >> + writel(mac_an_value, ethqos->mac_base + ETHQOS_MAC_AN_CTRL); >> + ethqos->serdes_speed = ethqos->speed; > > Although the code will behave the same, as you are storing the true > serdes speed here, shouldn't it be either SPEED_1000 or SPEED_2500 ? > > You'll end-up storing SPEED_10 / SPEED_100 should the link use these > speeds, which doesn't represent the true serdes speed. > > This would spare serdes reconfigurations when alternating between > 10/100/1000M speeds. > >> return val; >> } >> @@ -789,6 +815,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev) >> "Failed to get serdes phy\n"); >> >> ethqos->speed = SPEED_1000; >> + ethqos->serdes_speed = SPEED_1000; >> ethqos_update_link_clk(ethqos, SPEED_1000); >> ethqos_set_func_clk_en(ethqos); >> > > Thanks, > > Maxime
On Mon, Dec 18, 2023 at 12:41:18PM +0530, Sneh Shah wrote: > Serdes phy needs to operate at 2500 mode for 2.5G speed and 1000 > mode for 1G/100M/10M speed. > Added changes to configure serdes phy and mac based on link speed. > > Signed-off-by: Sneh Shah <quic_snehshah@quicinc.com> > --- > .../stmicro/stmmac/dwmac-qcom-ethqos.c | 31 +++++++++++++++++-- > 1 file changed, 29 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c > index d3bf42d0fceb..b3a28dc19161 100644 > --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c > +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c > @@ -21,6 +21,7 @@ > #define RGMII_IO_MACRO_CONFIG2 0x1C > #define RGMII_IO_MACRO_DEBUG1 0x20 > #define EMAC_SYSTEM_LOW_POWER_DEBUG 0x28 > +#define ETHQOS_MAC_AN_CTRL 0xE0 > > /* RGMII_IO_MACRO_CONFIG fields */ > #define RGMII_CONFIG_FUNC_CLK_EN BIT(30) > @@ -78,6 +79,10 @@ > #define ETHQOS_MAC_CTRL_SPEED_MODE BIT(14) > #define ETHQOS_MAC_CTRL_PORT_SEL BIT(15) > > +/*ETHQOS_MAC_AN_CTRL bits */ > +#define ETHQOS_MAC_AN_CTRL_RAN BIT(9) > +#define ETHQOS_MAC_AN_CTRL_ANE BIT(12) > + nit: space please add a space before ETHQOS_MAC_AN_CTRL > struct ethqos_emac_por { > unsigned int offset; > unsigned int value; > @@ -109,6 +114,7 @@ struct qcom_ethqos { > unsigned int num_por; > bool rgmii_config_loopback_en; > bool has_emac_ge_3; > + unsigned int serdes_speed; > }; > > static int rgmii_readl(struct qcom_ethqos *ethqos, unsigned int offset) > @@ -600,27 +606,47 @@ static int ethqos_configure_rgmii(struct qcom_ethqos *ethqos) > > static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos) > { > - int val; > - > + int val, mac_an_value; > val = readl(ethqos->mac_base + MAC_CTRL_REG); > + mac_an_value = readl(ethqos->mac_base + ETHQOS_MAC_AN_CTRL); > > switch (ethqos->speed) { > + case SPEED_2500: > + val &= ~ETHQOS_MAC_CTRL_PORT_SEL; > + rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG, > + RGMII_CONFIG2_RGMII_CLK_SEL_CFG, > + RGMII_IO_MACRO_CONFIG2); > + if (ethqos->serdes_speed != SPEED_2500) > + phy_set_speed(ethqos->serdes_phy, ethqos->speed); > + mac_an_value &= ~ETHQOS_MAC_AN_CTRL_ANE; > + break; > case SPEED_1000: > val &= ~ETHQOS_MAC_CTRL_PORT_SEL; > rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG, > RGMII_CONFIG2_RGMII_CLK_SEL_CFG, > RGMII_IO_MACRO_CONFIG2); > + if (ethqos->serdes_speed != SPEED_1000) > + phy_set_speed(ethqos->serdes_phy, ethqos->speed); > + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; > break; > case SPEED_100: > val |= ETHQOS_MAC_CTRL_PORT_SEL | ETHQOS_MAC_CTRL_SPEED_MODE; > + if (ethqos->serdes_speed != SPEED_1000) > + phy_set_speed(ethqos->serdes_phy, ethqos->speed); > + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; > break; > case SPEED_10: > val |= ETHQOS_MAC_CTRL_PORT_SEL; > val &= ~ETHQOS_MAC_CTRL_SPEED_MODE; > + if (ethqos->serdes_speed != SPEED_1000) > + phy_set_speed(ethqos->serdes_phy, ethqos->speed); > + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; > break; > } > > writel(val, ethqos->mac_base + MAC_CTRL_REG); > + writel(mac_an_value, ethqos->mac_base + ETHQOS_MAC_AN_CTRL); > + ethqos->serdes_speed = ethqos->speed; I see these bits are generic and there's some functions in stmmac_pcs.h that muck with these... Could you help me understand if this really should be Qualcomm specific, or if this is something that should be considered for the more core bits of the driver? I feel in either case we should take advantage of the common definitions in that file if possible. > > return val; > } > @@ -789,6 +815,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev) > "Failed to get serdes phy\n"); > > ethqos->speed = SPEED_1000; > + ethqos->serdes_speed = SPEED_1000; > ethqos_update_link_clk(ethqos, SPEED_1000); > ethqos_set_func_clk_en(ethqos); > > -- > 2.17.1 >
On Mon, Dec 18, 2023 at 10:20:03AM -0600, Andrew Halaney wrote: > On Mon, Dec 18, 2023 at 12:41:18PM +0530, Sneh Shah wrote: > > Serdes phy needs to operate at 2500 mode for 2.5G speed and 1000 > > mode for 1G/100M/10M speed. > > Added changes to configure serdes phy and mac based on link speed. > > > > Signed-off-by: Sneh Shah <quic_snehshah@quicinc.com> > > --- > > .../stmicro/stmmac/dwmac-qcom-ethqos.c | 31 +++++++++++++++++-- > > 1 file changed, 29 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c > > index d3bf42d0fceb..b3a28dc19161 100644 > > --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c > > +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c > > @@ -21,6 +21,7 @@ > > #define RGMII_IO_MACRO_CONFIG2 0x1C > > #define RGMII_IO_MACRO_DEBUG1 0x20 > > #define EMAC_SYSTEM_LOW_POWER_DEBUG 0x28 > > +#define ETHQOS_MAC_AN_CTRL 0xE0 > > > > /* RGMII_IO_MACRO_CONFIG fields */ > > #define RGMII_CONFIG_FUNC_CLK_EN BIT(30) > > @@ -78,6 +79,10 @@ > > #define ETHQOS_MAC_CTRL_SPEED_MODE BIT(14) > > #define ETHQOS_MAC_CTRL_PORT_SEL BIT(15) > > > > +/*ETHQOS_MAC_AN_CTRL bits */ > > +#define ETHQOS_MAC_AN_CTRL_RAN BIT(9) > > +#define ETHQOS_MAC_AN_CTRL_ANE BIT(12) > > + > > nit: space please add a space before ETHQOS_MAC_AN_CTRL > > > struct ethqos_emac_por { > > unsigned int offset; > > unsigned int value; > > @@ -109,6 +114,7 @@ struct qcom_ethqos { > > unsigned int num_por; > > bool rgmii_config_loopback_en; > > bool has_emac_ge_3; > > + unsigned int serdes_speed; > > }; > > > > static int rgmii_readl(struct qcom_ethqos *ethqos, unsigned int offset) > > @@ -600,27 +606,47 @@ static int ethqos_configure_rgmii(struct qcom_ethqos *ethqos) > > > > static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos) > > { > > - int val; > > - > > + int val, mac_an_value; > > val = readl(ethqos->mac_base + MAC_CTRL_REG); > > + mac_an_value = readl(ethqos->mac_base + ETHQOS_MAC_AN_CTRL); > > > > switch (ethqos->speed) { > > + case SPEED_2500: > > + val &= ~ETHQOS_MAC_CTRL_PORT_SEL; > > + rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG, > > + RGMII_CONFIG2_RGMII_CLK_SEL_CFG, > > + RGMII_IO_MACRO_CONFIG2); > > + if (ethqos->serdes_speed != SPEED_2500) > > + phy_set_speed(ethqos->serdes_phy, ethqos->speed); Also, please capture the return value here and propagate the error as appropriate. > > + mac_an_value &= ~ETHQOS_MAC_AN_CTRL_ANE; > > + break; > > case SPEED_1000: > > val &= ~ETHQOS_MAC_CTRL_PORT_SEL; > > rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG, > > RGMII_CONFIG2_RGMII_CLK_SEL_CFG, > > RGMII_IO_MACRO_CONFIG2); > > + if (ethqos->serdes_speed != SPEED_1000) > > + phy_set_speed(ethqos->serdes_phy, ethqos->speed); > > + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; > > break; > > case SPEED_100: > > val |= ETHQOS_MAC_CTRL_PORT_SEL | ETHQOS_MAC_CTRL_SPEED_MODE; > > + if (ethqos->serdes_speed != SPEED_1000) > > + phy_set_speed(ethqos->serdes_phy, ethqos->speed); > > + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; > > break; > > case SPEED_10: > > val |= ETHQOS_MAC_CTRL_PORT_SEL; > > val &= ~ETHQOS_MAC_CTRL_SPEED_MODE; > > + if (ethqos->serdes_speed != SPEED_1000) > > + phy_set_speed(ethqos->serdes_phy, ethqos->speed); > > + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; > > break; > > } > > > > writel(val, ethqos->mac_base + MAC_CTRL_REG); > > + writel(mac_an_value, ethqos->mac_base + ETHQOS_MAC_AN_CTRL); > > + ethqos->serdes_speed = ethqos->speed; > > I see these bits are generic and there's some functions in stmmac_pcs.h > that muck with these... > > Could you help me understand if this really should be Qualcomm specific, > or if this is something that should be considered for the more core bits > of the driver? I feel in either case we should take advantage of the > common definitions in that file if possible. > > > > > return val; > > } > > @@ -789,6 +815,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev) > > "Failed to get serdes phy\n"); > > > > ethqos->speed = SPEED_1000; > > + ethqos->serdes_speed = SPEED_1000; > > ethqos_update_link_clk(ethqos, SPEED_1000); > > ethqos_set_func_clk_en(ethqos); > > > > -- > > 2.17.1 > >
On 12/18/2023 9:50 PM, Andrew Halaney wrote: > On Mon, Dec 18, 2023 at 12:41:18PM +0530, Sneh Shah wrote: >> Serdes phy needs to operate at 2500 mode for 2.5G speed and 1000 >> mode for 1G/100M/10M speed. >> Added changes to configure serdes phy and mac based on link speed. >> >> Signed-off-by: Sneh Shah <quic_snehshah@quicinc.com> >> --- >> .../stmicro/stmmac/dwmac-qcom-ethqos.c | 31 +++++++++++++++++-- >> 1 file changed, 29 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c >> index d3bf42d0fceb..b3a28dc19161 100644 >> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c >> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c >> @@ -21,6 +21,7 @@ >> #define RGMII_IO_MACRO_CONFIG2 0x1C >> #define RGMII_IO_MACRO_DEBUG1 0x20 >> #define EMAC_SYSTEM_LOW_POWER_DEBUG 0x28 >> +#define ETHQOS_MAC_AN_CTRL 0xE0 >> >> /* RGMII_IO_MACRO_CONFIG fields */ >> #define RGMII_CONFIG_FUNC_CLK_EN BIT(30) >> @@ -78,6 +79,10 @@ >> #define ETHQOS_MAC_CTRL_SPEED_MODE BIT(14) >> #define ETHQOS_MAC_CTRL_PORT_SEL BIT(15) >> >> +/*ETHQOS_MAC_AN_CTRL bits */ >> +#define ETHQOS_MAC_AN_CTRL_RAN BIT(9) >> +#define ETHQOS_MAC_AN_CTRL_ANE BIT(12) >> + > > nit: space please add a space before ETHQOS_MAC_AN_CTRL > will take care of this in next patch >> struct ethqos_emac_por { >> unsigned int offset; >> unsigned int value; >> @@ -109,6 +114,7 @@ struct qcom_ethqos { >> unsigned int num_por; >> bool rgmii_config_loopback_en; >> bool has_emac_ge_3; >> + unsigned int serdes_speed; >> }; >> >> static int rgmii_readl(struct qcom_ethqos *ethqos, unsigned int offset) >> @@ -600,27 +606,47 @@ static int ethqos_configure_rgmii(struct qcom_ethqos *ethqos) >> >> static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos) >> { >> - int val; >> - >> + int val, mac_an_value; >> val = readl(ethqos->mac_base + MAC_CTRL_REG); >> + mac_an_value = readl(ethqos->mac_base + ETHQOS_MAC_AN_CTRL); >> >> switch (ethqos->speed) { >> + case SPEED_2500: >> + val &= ~ETHQOS_MAC_CTRL_PORT_SEL; >> + rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG, >> + RGMII_CONFIG2_RGMII_CLK_SEL_CFG, >> + RGMII_IO_MACRO_CONFIG2); >> + if (ethqos->serdes_speed != SPEED_2500) >> + phy_set_speed(ethqos->serdes_phy, ethqos->speed); >> + mac_an_value &= ~ETHQOS_MAC_AN_CTRL_ANE; >> + break; >> case SPEED_1000: >> val &= ~ETHQOS_MAC_CTRL_PORT_SEL; >> rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG, >> RGMII_CONFIG2_RGMII_CLK_SEL_CFG, >> RGMII_IO_MACRO_CONFIG2); >> + if (ethqos->serdes_speed != SPEED_1000) >> + phy_set_speed(ethqos->serdes_phy, ethqos->speed); >> + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; >> break; >> case SPEED_100: >> val |= ETHQOS_MAC_CTRL_PORT_SEL | ETHQOS_MAC_CTRL_SPEED_MODE; >> + if (ethqos->serdes_speed != SPEED_1000) >> + phy_set_speed(ethqos->serdes_phy, ethqos->speed); >> + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; >> break; >> case SPEED_10: >> val |= ETHQOS_MAC_CTRL_PORT_SEL; >> val &= ~ETHQOS_MAC_CTRL_SPEED_MODE; >> + if (ethqos->serdes_speed != SPEED_1000) >> + phy_set_speed(ethqos->serdes_phy, ethqos->speed); >> + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; >> break; >> } >> >> writel(val, ethqos->mac_base + MAC_CTRL_REG); >> + writel(mac_an_value, ethqos->mac_base + ETHQOS_MAC_AN_CTRL); >> + ethqos->serdes_speed = ethqos->speed; > > I see these bits are generic and there's some functions in stmmac_pcs.h > that muck with these... > > Could you help me understand if this really should be Qualcomm specific, > or if this is something that should be considered for the more core bits > of the driver? I feel in either case we should take advantage of the > common definitions in that file if possible. > we do have function dwmac_ctrl_ane in core driver which updates same registers. However, it does not have the option to reset ANE bit, it can only set bits. For SPEED_2500 we need to reset ANE bit. Hence I am adding it here. Not sure if we can extend dwmac_ctrl_ane function to reset bits as well. >> >> return val; >> } >> @@ -789,6 +815,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev) >> "Failed to get serdes phy\n"); >> >> ethqos->speed = SPEED_1000; >> + ethqos->serdes_speed = SPEED_1000; >> ethqos_update_link_clk(ethqos, SPEED_1000); >> ethqos_set_func_clk_en(ethqos); >> >> -- >> 2.17.1 >> >
On Wed, Dec 20, 2023 at 01:02:45PM +0530, Sneh Shah wrote: > > > On 12/18/2023 9:50 PM, Andrew Halaney wrote: > > On Mon, Dec 18, 2023 at 12:41:18PM +0530, Sneh Shah wrote: > >> Serdes phy needs to operate at 2500 mode for 2.5G speed and 1000 > >> mode for 1G/100M/10M speed. > >> Added changes to configure serdes phy and mac based on link speed. > >> > >> Signed-off-by: Sneh Shah <quic_snehshah@quicinc.com> > >> --- > >> .../stmicro/stmmac/dwmac-qcom-ethqos.c | 31 +++++++++++++++++-- > >> 1 file changed, 29 insertions(+), 2 deletions(-) > >> > >> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c > >> index d3bf42d0fceb..b3a28dc19161 100644 > >> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c > >> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c > >> @@ -21,6 +21,7 @@ > >> #define RGMII_IO_MACRO_CONFIG2 0x1C > >> #define RGMII_IO_MACRO_DEBUG1 0x20 > >> #define EMAC_SYSTEM_LOW_POWER_DEBUG 0x28 > >> +#define ETHQOS_MAC_AN_CTRL 0xE0 > >> > >> /* RGMII_IO_MACRO_CONFIG fields */ > >> #define RGMII_CONFIG_FUNC_CLK_EN BIT(30) > >> @@ -78,6 +79,10 @@ > >> #define ETHQOS_MAC_CTRL_SPEED_MODE BIT(14) > >> #define ETHQOS_MAC_CTRL_PORT_SEL BIT(15) > >> > >> +/*ETHQOS_MAC_AN_CTRL bits */ > >> +#define ETHQOS_MAC_AN_CTRL_RAN BIT(9) > >> +#define ETHQOS_MAC_AN_CTRL_ANE BIT(12) > >> + > > > > nit: space please add a space before ETHQOS_MAC_AN_CTRL > > > will take care of this in next patch > > >> struct ethqos_emac_por { > >> unsigned int offset; > >> unsigned int value; > >> @@ -109,6 +114,7 @@ struct qcom_ethqos { > >> unsigned int num_por; > >> bool rgmii_config_loopback_en; > >> bool has_emac_ge_3; > >> + unsigned int serdes_speed; Another nit as I look closer: I think this should be grouped by phy_mode etc just for readability. > >> }; > >> > >> static int rgmii_readl(struct qcom_ethqos *ethqos, unsigned int offset) > >> @@ -600,27 +606,47 @@ static int ethqos_configure_rgmii(struct qcom_ethqos *ethqos) > >> > >> static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos) > >> { > >> - int val; > >> - > >> + int val, mac_an_value; > >> val = readl(ethqos->mac_base + MAC_CTRL_REG); > >> + mac_an_value = readl(ethqos->mac_base + ETHQOS_MAC_AN_CTRL); > >> > >> switch (ethqos->speed) { > >> + case SPEED_2500: > >> + val &= ~ETHQOS_MAC_CTRL_PORT_SEL; > >> + rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG, > >> + RGMII_CONFIG2_RGMII_CLK_SEL_CFG, > >> + RGMII_IO_MACRO_CONFIG2); > >> + if (ethqos->serdes_speed != SPEED_2500) > >> + phy_set_speed(ethqos->serdes_phy, ethqos->speed); > >> + mac_an_value &= ~ETHQOS_MAC_AN_CTRL_ANE; > >> + break; > >> case SPEED_1000: > >> val &= ~ETHQOS_MAC_CTRL_PORT_SEL; > >> rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG, > >> RGMII_CONFIG2_RGMII_CLK_SEL_CFG, > >> RGMII_IO_MACRO_CONFIG2); > >> + if (ethqos->serdes_speed != SPEED_1000) > >> + phy_set_speed(ethqos->serdes_phy, ethqos->speed); > >> + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; > >> break; > >> case SPEED_100: > >> val |= ETHQOS_MAC_CTRL_PORT_SEL | ETHQOS_MAC_CTRL_SPEED_MODE; > >> + if (ethqos->serdes_speed != SPEED_1000) > >> + phy_set_speed(ethqos->serdes_phy, ethqos->speed); > >> + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; > >> break; > >> case SPEED_10: > >> val |= ETHQOS_MAC_CTRL_PORT_SEL; > >> val &= ~ETHQOS_MAC_CTRL_SPEED_MODE; > >> + if (ethqos->serdes_speed != SPEED_1000) > >> + phy_set_speed(ethqos->serdes_phy, ethqos->speed); > >> + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; > >> break; > >> } > >> > >> writel(val, ethqos->mac_base + MAC_CTRL_REG); > >> + writel(mac_an_value, ethqos->mac_base + ETHQOS_MAC_AN_CTRL); > >> + ethqos->serdes_speed = ethqos->speed; > > > > I see these bits are generic and there's some functions in stmmac_pcs.h > > that muck with these... > > > > Could you help me understand if this really should be Qualcomm specific, > > or if this is something that should be considered for the more core bits > > of the driver? I feel in either case we should take advantage of the > > common definitions in that file if possible. > > > we do have function dwmac_ctrl_ane in core driver which updates same registers. However, it does not have the option to reset ANE bit, it can only set bits. For SPEED_2500 we need to reset ANE bit. Hence I am adding it here. Not sure if we can extend dwmac_ctrl_ane function to reset bits as well. I'd evaluate if you can update that function to clear the ANE bit when the ane boolean is false. From the usage I see I feel that makes sense, but correct me if you think I'm wrong. At the very least let's use the defines from there, and possibly add a new function if clearing is not acceptable in dwmac_ctrl_ane(). Stepping back, I was asking in general is the need to muck with ANE here is a Qualcomm specific problem, or is that a generic thing that should be handled in the core (and the phy_set_speed() bit stay here)? i.e. would any dwmac5 based IP need to do something like this for SPEED_2500? > >> > >> return val; > >> } > >> @@ -789,6 +815,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev) > >> "Failed to get serdes phy\n"); > >> > >> ethqos->speed = SPEED_1000; > >> + ethqos->serdes_speed = SPEED_1000; > >> ethqos_update_link_clk(ethqos, SPEED_1000); > >> ethqos_set_func_clk_en(ethqos); > >> > >> -- > >> 2.17.1 > >> > > >
On 12/20/2023 9:29 PM, Andrew Halaney wrote: > On Wed, Dec 20, 2023 at 01:02:45PM +0530, Sneh Shah wrote: >> >> >> On 12/18/2023 9:50 PM, Andrew Halaney wrote: >>> On Mon, Dec 18, 2023 at 12:41:18PM +0530, Sneh Shah wrote: >>>> Serdes phy needs to operate at 2500 mode for 2.5G speed and 1000 >>>> mode for 1G/100M/10M speed. >>>> Added changes to configure serdes phy and mac based on link speed. >>>> >>>> Signed-off-by: Sneh Shah <quic_snehshah@quicinc.com> >>>> --- >>>> .../stmicro/stmmac/dwmac-qcom-ethqos.c | 31 +++++++++++++++++-- >>>> 1 file changed, 29 insertions(+), 2 deletions(-) >>>> >>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c >>>> index d3bf42d0fceb..b3a28dc19161 100644 >>>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c >>>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c >>>> @@ -21,6 +21,7 @@ >>>> #define RGMII_IO_MACRO_CONFIG2 0x1C >>>> #define RGMII_IO_MACRO_DEBUG1 0x20 >>>> #define EMAC_SYSTEM_LOW_POWER_DEBUG 0x28 >>>> +#define ETHQOS_MAC_AN_CTRL 0xE0 >>>> >>>> /* RGMII_IO_MACRO_CONFIG fields */ >>>> #define RGMII_CONFIG_FUNC_CLK_EN BIT(30) >>>> @@ -78,6 +79,10 @@ >>>> #define ETHQOS_MAC_CTRL_SPEED_MODE BIT(14) >>>> #define ETHQOS_MAC_CTRL_PORT_SEL BIT(15) >>>> >>>> +/*ETHQOS_MAC_AN_CTRL bits */ >>>> +#define ETHQOS_MAC_AN_CTRL_RAN BIT(9) >>>> +#define ETHQOS_MAC_AN_CTRL_ANE BIT(12) >>>> + >>> >>> nit: space please add a space before ETHQOS_MAC_AN_CTRL >>> >> will take care of this in next patch >> >>>> struct ethqos_emac_por { >>>> unsigned int offset; >>>> unsigned int value; >>>> @@ -109,6 +114,7 @@ struct qcom_ethqos { >>>> unsigned int num_por; >>>> bool rgmii_config_loopback_en; >>>> bool has_emac_ge_3; >>>> + unsigned int serdes_speed; > > Another nit as I look closer: I think this should be grouped by phy_mode > etc just for readability. Didn't get this. can you please elaborate more? > >>>> }; >>>> >>>> static int rgmii_readl(struct qcom_ethqos *ethqos, unsigned int offset) >>>> @@ -600,27 +606,47 @@ static int ethqos_configure_rgmii(struct qcom_ethqos *ethqos) >>>> >>>> static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos) >>>> { >>>> - int val; >>>> - >>>> + int val, mac_an_value; >>>> val = readl(ethqos->mac_base + MAC_CTRL_REG); >>>> + mac_an_value = readl(ethqos->mac_base + ETHQOS_MAC_AN_CTRL); >>>> >>>> switch (ethqos->speed) { >>>> + case SPEED_2500: >>>> + val &= ~ETHQOS_MAC_CTRL_PORT_SEL; >>>> + rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG, >>>> + RGMII_CONFIG2_RGMII_CLK_SEL_CFG, >>>> + RGMII_IO_MACRO_CONFIG2); >>>> + if (ethqos->serdes_speed != SPEED_2500) >>>> + phy_set_speed(ethqos->serdes_phy, ethqos->speed); >>>> + mac_an_value &= ~ETHQOS_MAC_AN_CTRL_ANE; >>>> + break; >>>> case SPEED_1000: >>>> val &= ~ETHQOS_MAC_CTRL_PORT_SEL; >>>> rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG, >>>> RGMII_CONFIG2_RGMII_CLK_SEL_CFG, >>>> RGMII_IO_MACRO_CONFIG2); >>>> + if (ethqos->serdes_speed != SPEED_1000) >>>> + phy_set_speed(ethqos->serdes_phy, ethqos->speed); >>>> + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; >>>> break; >>>> case SPEED_100: >>>> val |= ETHQOS_MAC_CTRL_PORT_SEL | ETHQOS_MAC_CTRL_SPEED_MODE; >>>> + if (ethqos->serdes_speed != SPEED_1000) >>>> + phy_set_speed(ethqos->serdes_phy, ethqos->speed); >>>> + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; >>>> break; >>>> case SPEED_10: >>>> val |= ETHQOS_MAC_CTRL_PORT_SEL; >>>> val &= ~ETHQOS_MAC_CTRL_SPEED_MODE; >>>> + if (ethqos->serdes_speed != SPEED_1000) >>>> + phy_set_speed(ethqos->serdes_phy, ethqos->speed); >>>> + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; >>>> break; >>>> } >>>> >>>> writel(val, ethqos->mac_base + MAC_CTRL_REG); >>>> + writel(mac_an_value, ethqos->mac_base + ETHQOS_MAC_AN_CTRL); >>>> + ethqos->serdes_speed = ethqos->speed; >>> >>> I see these bits are generic and there's some functions in stmmac_pcs.h >>> that muck with these... >>> >>> Could you help me understand if this really should be Qualcomm specific, >>> or if this is something that should be considered for the more core bits >>> of the driver? I feel in either case we should take advantage of the >>> common definitions in that file if possible. >>> >> we do have function dwmac_ctrl_ane in core driver which updates same registers. However, it does not have the option to reset ANE bit, it can only set bits. For SPEED_2500 we need to reset ANE bit. Hence I am adding it here. Not sure if we can extend dwmac_ctrl_ane function to reset bits as well. > > I'd evaluate if you can update that function to clear the ANE bit when > the ane boolean is false. From the usage I see I feel that makes sense, > but correct me if you think I'm wrong. > At the very least let's use the defines from there, and possibly add a > new function if clearing is not acceptable in dwmac_ctrl_ane(). > > Stepping back, I was asking in general is the need to muck with ANE here > is a Qualcomm specific problem, or is that a generic thing that should be > handled in the core (and the phy_set_speed() bit stay here)? i.e. would > any dwmac5 based IP need to do something like this for SPEED_2500? I think disabling ANE for SPEED_2500 is generic not specific to qualcomm. Even in dwxgmac2 versions also we need to disable ANE for SPEED_2500. Autoneg clause 37 stadard doesn't support 2500 speed. So we need to disable autoneg for speed 2500 > >>>> >>>> return val; >>>> } >>>> @@ -789,6 +815,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev) >>>> "Failed to get serdes phy\n"); >>>> >>>> ethqos->speed = SPEED_1000; >>>> + ethqos->serdes_speed = SPEED_1000; >>>> ethqos_update_link_clk(ethqos, SPEED_1000); >>>> ethqos_set_func_clk_en(ethqos); >>>> >>>> -- >>>> 2.17.1 >>>> >>> >> >
On Thu, Dec 21, 2023 at 02:23:57PM +0530, Sneh Shah wrote: > > > On 12/20/2023 9:29 PM, Andrew Halaney wrote: > > On Wed, Dec 20, 2023 at 01:02:45PM +0530, Sneh Shah wrote: > >> > >> > >> On 12/18/2023 9:50 PM, Andrew Halaney wrote: > >>> On Mon, Dec 18, 2023 at 12:41:18PM +0530, Sneh Shah wrote: > >>>> Serdes phy needs to operate at 2500 mode for 2.5G speed and 1000 > >>>> mode for 1G/100M/10M speed. > >>>> Added changes to configure serdes phy and mac based on link speed. > >>>> > >>>> Signed-off-by: Sneh Shah <quic_snehshah@quicinc.com> > >>>> --- > >>>> .../stmicro/stmmac/dwmac-qcom-ethqos.c | 31 +++++++++++++++++-- > >>>> 1 file changed, 29 insertions(+), 2 deletions(-) > >>>> > >>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c > >>>> index d3bf42d0fceb..b3a28dc19161 100644 > >>>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c > >>>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c > >>>> @@ -21,6 +21,7 @@ > >>>> #define RGMII_IO_MACRO_CONFIG2 0x1C > >>>> #define RGMII_IO_MACRO_DEBUG1 0x20 > >>>> #define EMAC_SYSTEM_LOW_POWER_DEBUG 0x28 > >>>> +#define ETHQOS_MAC_AN_CTRL 0xE0 > >>>> > >>>> /* RGMII_IO_MACRO_CONFIG fields */ > >>>> #define RGMII_CONFIG_FUNC_CLK_EN BIT(30) > >>>> @@ -78,6 +79,10 @@ > >>>> #define ETHQOS_MAC_CTRL_SPEED_MODE BIT(14) > >>>> #define ETHQOS_MAC_CTRL_PORT_SEL BIT(15) > >>>> > >>>> +/*ETHQOS_MAC_AN_CTRL bits */ > >>>> +#define ETHQOS_MAC_AN_CTRL_RAN BIT(9) > >>>> +#define ETHQOS_MAC_AN_CTRL_ANE BIT(12) > >>>> + > >>> > >>> nit: space please add a space before ETHQOS_MAC_AN_CTRL > >>> > >> will take care of this in next patch > >> > >>>> struct ethqos_emac_por { > >>>> unsigned int offset; > >>>> unsigned int value; > >>>> @@ -109,6 +114,7 @@ struct qcom_ethqos { > >>>> unsigned int num_por; > >>>> bool rgmii_config_loopback_en; > >>>> bool has_emac_ge_3; > >>>> + unsigned int serdes_speed; > > > > Another nit as I look closer: I think this should be grouped by phy_mode > > etc just for readability. > Didn't get this. can you please elaborate more? I meant instead of this: struct qcom_ethqos { struct platform_device *pdev; void __iomem *rgmii_base; void __iomem *mac_base; int (*configure_func)(struct qcom_ethqos *ethqos); unsigned int link_clk_rate; struct clk *link_clk; struct phy *serdes_phy; unsigned int speed; phy_interface_t phy_mode; const struct ethqos_emac_por *por; unsigned int num_por; bool rgmii_config_loopback_en; bool has_emac_ge_3; unsigned int serdes_speed; }; I think this would make more logical sense: struct qcom_ethqos { struct platform_device *pdev; void __iomem *rgmii_base; void __iomem *mac_base; int (*configure_func)(struct qcom_ethqos *ethqos); unsigned int link_clk_rate; struct clk *link_clk; struct phy *serdes_phy; unsigned int serdes_speed; unsigned int speed; phy_interface_t phy_mode; const struct ethqos_emac_por *por; unsigned int num_por; bool rgmii_config_loopback_en; bool has_emac_ge_3; }; It is definitely nit picking though :) > > > >>>> }; > >>>> > >>>> static int rgmii_readl(struct qcom_ethqos *ethqos, unsigned int offset) > >>>> @@ -600,27 +606,47 @@ static int ethqos_configure_rgmii(struct qcom_ethqos *ethqos) > >>>> > >>>> static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos) > >>>> { > >>>> - int val; > >>>> - > >>>> + int val, mac_an_value; > >>>> val = readl(ethqos->mac_base + MAC_CTRL_REG); > >>>> + mac_an_value = readl(ethqos->mac_base + ETHQOS_MAC_AN_CTRL); > >>>> > >>>> switch (ethqos->speed) { > >>>> + case SPEED_2500: > >>>> + val &= ~ETHQOS_MAC_CTRL_PORT_SEL; > >>>> + rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG, > >>>> + RGMII_CONFIG2_RGMII_CLK_SEL_CFG, > >>>> + RGMII_IO_MACRO_CONFIG2); > >>>> + if (ethqos->serdes_speed != SPEED_2500) > >>>> + phy_set_speed(ethqos->serdes_phy, ethqos->speed); > >>>> + mac_an_value &= ~ETHQOS_MAC_AN_CTRL_ANE; > >>>> + break; > >>>> case SPEED_1000: > >>>> val &= ~ETHQOS_MAC_CTRL_PORT_SEL; > >>>> rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG, > >>>> RGMII_CONFIG2_RGMII_CLK_SEL_CFG, > >>>> RGMII_IO_MACRO_CONFIG2); > >>>> + if (ethqos->serdes_speed != SPEED_1000) > >>>> + phy_set_speed(ethqos->serdes_phy, ethqos->speed); > >>>> + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; > >>>> break; > >>>> case SPEED_100: > >>>> val |= ETHQOS_MAC_CTRL_PORT_SEL | ETHQOS_MAC_CTRL_SPEED_MODE; > >>>> + if (ethqos->serdes_speed != SPEED_1000) > >>>> + phy_set_speed(ethqos->serdes_phy, ethqos->speed); > >>>> + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; > >>>> break; > >>>> case SPEED_10: > >>>> val |= ETHQOS_MAC_CTRL_PORT_SEL; > >>>> val &= ~ETHQOS_MAC_CTRL_SPEED_MODE; > >>>> + if (ethqos->serdes_speed != SPEED_1000) > >>>> + phy_set_speed(ethqos->serdes_phy, ethqos->speed); > >>>> + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; > >>>> break; > >>>> } > >>>> > >>>> writel(val, ethqos->mac_base + MAC_CTRL_REG); > >>>> + writel(mac_an_value, ethqos->mac_base + ETHQOS_MAC_AN_CTRL); > >>>> + ethqos->serdes_speed = ethqos->speed; > >>> > >>> I see these bits are generic and there's some functions in stmmac_pcs.h > >>> that muck with these... > >>> > >>> Could you help me understand if this really should be Qualcomm specific, > >>> or if this is something that should be considered for the more core bits > >>> of the driver? I feel in either case we should take advantage of the > >>> common definitions in that file if possible. > >>> > >> we do have function dwmac_ctrl_ane in core driver which updates same registers. However, it does not have the option to reset ANE bit, it can only set bits. For SPEED_2500 we need to reset ANE bit. Hence I am adding it here. Not sure if we can extend dwmac_ctrl_ane function to reset bits as well. > > > > I'd evaluate if you can update that function to clear the ANE bit when > > the ane boolean is false. From the usage I see I feel that makes sense, > > but correct me if you think I'm wrong. > > At the very least let's use the defines from there, and possibly add a > > new function if clearing is not acceptable in dwmac_ctrl_ane(). > > > > Stepping back, I was asking in general is the need to muck with ANE here > > is a Qualcomm specific problem, or is that a generic thing that should be > > handled in the core (and the phy_set_speed() bit stay here)? i.e. would > > any dwmac5 based IP need to do something like this for SPEED_2500? > I think disabling ANE for SPEED_2500 is generic not specific to qualcomm. Even in dwxgmac2 versions also we need to disable ANE for SPEED_2500. Autoneg clause 37 stadard doesn't support 2500 speed. So we need to disable autoneg for speed 2500 Another nit, sorry for being so picky. Can you please wrap your emails to around 80 characters? That's the general etiquette when replying on-list, makes it easier to read (similar to say a commit message). Thanks for explaining that. Then in my opinion based on what you've said I think the disabling of ANE for SPEED_2500 should be done outside of the Qualcomm platform code. Note, I'm struggling to keep up with the standards at play here, so if someone else who's a bit more wise on these topics has an opinion I'd listen to them. I find myself rewatching this presentation from Maxime/Antoine as a primer on all of this: https://www.youtube.com/watch?v=K962S9gTBVM If anyone's got any recommended resources for me to read in particular I am all ears. I'll be out the next 2-3 weeks, so don't wait for any responses from me :) Thanks, Andrew > > > > >>>> > >>>> return val; > >>>> } > >>>> @@ -789,6 +815,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev) > >>>> "Failed to get serdes phy\n"); > >>>> > >>>> ethqos->speed = SPEED_1000; > >>>> + ethqos->serdes_speed = SPEED_1000; > >>>> ethqos_update_link_clk(ethqos, SPEED_1000); > >>>> ethqos_set_func_clk_en(ethqos); > >>>> > >>>> -- > >>>> 2.17.1 > >>>> > >>> > >> > > >
Hello Andrew, On Thu, 21 Dec 2023 08:30:49 -0600 Andrew Halaney <ahalaney@redhat.com> wrote: [...] > > Note, I'm struggling to keep up with the standards at play here, so if > someone else who's a bit more wise on these topics has an opinion I'd > listen to them. I find myself rewatching this presentation from > Maxime/Antoine as a primer on all of this: > > https://www.youtube.com/watch?v=K962S9gTBVM :) > If anyone's got any recommended resources for me to read in particular I > am all ears. I think Russell and Andrew did a good job clarifying some quirks with all these standards : https://elixir.bootlin.com/linux/latest/source/Documentation/networking/phy.rst#L229 There are some more info in Andrew's LPC talk here : http://vger.kernel.org/lpc_net2018_talks/phylink-and-sfp-slides.pdf (more phylink related though) But I agree that this is hard to fully grasp, there are so many variants everywhere, some standard, some ad-hoc standards, etc. Maxime
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c index d3bf42d0fceb..b3a28dc19161 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c @@ -21,6 +21,7 @@ #define RGMII_IO_MACRO_CONFIG2 0x1C #define RGMII_IO_MACRO_DEBUG1 0x20 #define EMAC_SYSTEM_LOW_POWER_DEBUG 0x28 +#define ETHQOS_MAC_AN_CTRL 0xE0 /* RGMII_IO_MACRO_CONFIG fields */ #define RGMII_CONFIG_FUNC_CLK_EN BIT(30) @@ -78,6 +79,10 @@ #define ETHQOS_MAC_CTRL_SPEED_MODE BIT(14) #define ETHQOS_MAC_CTRL_PORT_SEL BIT(15) +/*ETHQOS_MAC_AN_CTRL bits */ +#define ETHQOS_MAC_AN_CTRL_RAN BIT(9) +#define ETHQOS_MAC_AN_CTRL_ANE BIT(12) + struct ethqos_emac_por { unsigned int offset; unsigned int value; @@ -109,6 +114,7 @@ struct qcom_ethqos { unsigned int num_por; bool rgmii_config_loopback_en; bool has_emac_ge_3; + unsigned int serdes_speed; }; static int rgmii_readl(struct qcom_ethqos *ethqos, unsigned int offset) @@ -600,27 +606,47 @@ static int ethqos_configure_rgmii(struct qcom_ethqos *ethqos) static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos) { - int val; - + int val, mac_an_value; val = readl(ethqos->mac_base + MAC_CTRL_REG); + mac_an_value = readl(ethqos->mac_base + ETHQOS_MAC_AN_CTRL); switch (ethqos->speed) { + case SPEED_2500: + val &= ~ETHQOS_MAC_CTRL_PORT_SEL; + rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG, + RGMII_CONFIG2_RGMII_CLK_SEL_CFG, + RGMII_IO_MACRO_CONFIG2); + if (ethqos->serdes_speed != SPEED_2500) + phy_set_speed(ethqos->serdes_phy, ethqos->speed); + mac_an_value &= ~ETHQOS_MAC_AN_CTRL_ANE; + break; case SPEED_1000: val &= ~ETHQOS_MAC_CTRL_PORT_SEL; rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG, RGMII_CONFIG2_RGMII_CLK_SEL_CFG, RGMII_IO_MACRO_CONFIG2); + if (ethqos->serdes_speed != SPEED_1000) + phy_set_speed(ethqos->serdes_phy, ethqos->speed); + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; break; case SPEED_100: val |= ETHQOS_MAC_CTRL_PORT_SEL | ETHQOS_MAC_CTRL_SPEED_MODE; + if (ethqos->serdes_speed != SPEED_1000) + phy_set_speed(ethqos->serdes_phy, ethqos->speed); + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; break; case SPEED_10: val |= ETHQOS_MAC_CTRL_PORT_SEL; val &= ~ETHQOS_MAC_CTRL_SPEED_MODE; + if (ethqos->serdes_speed != SPEED_1000) + phy_set_speed(ethqos->serdes_phy, ethqos->speed); + mac_an_value |= ETHQOS_MAC_AN_CTRL_RAN | ETHQOS_MAC_AN_CTRL_ANE; break; } writel(val, ethqos->mac_base + MAC_CTRL_REG); + writel(mac_an_value, ethqos->mac_base + ETHQOS_MAC_AN_CTRL); + ethqos->serdes_speed = ethqos->speed; return val; } @@ -789,6 +815,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev) "Failed to get serdes phy\n"); ethqos->speed = SPEED_1000; + ethqos->serdes_speed = SPEED_1000; ethqos_update_link_clk(ethqos, SPEED_1000); ethqos_set_func_clk_en(ethqos);