lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Wed, 12 Jan 2022 00:30:33 +0000
From:   Robert Hancock <robert.hancock@...ian.com>
To:     "netdev@...r.kernel.org" <netdev@...r.kernel.org>
CC:     "davem@...emloft.net" <davem@...emloft.net>,
        "kuba@...nel.org" <kuba@...nel.org>,
        "radhey.shyam.pandey@...inx.com" <radhey.shyam.pandey@...inx.com>
Subject: Re: [PATCH net 1/7] net: axienet: Reset core before accessing MAC and
 wait for core ready

On Tue, 2022-01-11 at 15:13 -0600, Robert Hancock wrote:
> In some cases where the Xilinx Ethernet core was used in 1000Base-X or
> SGMII modes, which use the internal PCS/PMA PHY, and the MGT
> transceiver clock source for the PCS was not running at the time the
> FPGA logic was loaded, the core would come up in a state where the
> PCS could not be found on the MDIO bus. To fix this, the Ethernet core
> (including the PCS) should be reset after enabling the clocks, prior to
> attempting to access the PCS using of_mdio_find_device.
> 
> Also, when resetting the device, wait for the PhyRstCmplt bit to be set
> in the interrupt status register before continuing initialization, to
> ensure that the core is actually ready. The MgtRdy bit could also be
> waited for, but unfortunately when using 7-series devices, the bit does
> not appear to work as documented (it seems to behave as some sort of
> link state indication and not just an indication the transceiver is
> ready) so it can't really be relied on.
> 
> Fixes: 3e08fd4a8298 (net: axienet: Properly handle PCS/PMA PHY for 1000BaseX
> mode)

Patchwork points out that this commit doesn't exist in mainline, it's from the
5.10 stable tree. The corresponding mainline commit is
1a02556086fc0eb16e0a0d09043e9ffb0e31c7db.

> Signed-off-by: Robert Hancock <robert.hancock@...ian.com>
> ---
>  .../net/ethernet/xilinx/xilinx_axienet_main.c | 34 +++++++++++++------
>  1 file changed, 24 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> index 90144ac7aee8..f4ae035bed35 100644
> --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> @@ -496,7 +496,8 @@ static void axienet_setoptions(struct net_device *ndev,
> u32 options)
>  
>  static int __axienet_device_reset(struct axienet_local *lp)
>  {
> -	u32 timeout;
> +	u32 value;
> +	int ret;
>  
>  	/* Reset Axi DMA. This would reset Axi Ethernet core as well. The reset
>  	 * process of Axi DMA takes a while to complete as all pending
> @@ -506,15 +507,23 @@ static int __axienet_device_reset(struct axienet_local
> *lp)
>  	 * they both reset the entire DMA core, so only one needs to be used.
>  	 */
>  	axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, XAXIDMA_CR_RESET_MASK);
> -	timeout = DELAY_OF_ONE_MILLISEC;
> -	while (axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET) &
> -				XAXIDMA_CR_RESET_MASK) {
> -		udelay(1);
> -		if (--timeout == 0) {
> -			netdev_err(lp->ndev, "%s: DMA reset timeout!\n",
> -				   __func__);
> -			return -ETIMEDOUT;
> -		}
> +	ret = read_poll_timeout(axienet_dma_in32, value,
> +				!(value & XAXIDMA_CR_RESET_MASK),
> +				DELAY_OF_ONE_MILLISEC, 50000, false, lp,
> +				XAXIDMA_TX_CR_OFFSET);
> +	if (ret) {
> +		dev_err(lp->dev, "%s: DMA reset timeout!\n", __func__);
> +		return ret;
> +	}
> +
> +	/* Wait for PhyRstCmplt bit to be set, indicating the PHY reset has
> finished */
> +	ret = read_poll_timeout(axienet_ior, value,
> +				value & XAE_INT_PHYRSTCMPLT_MASK,
> +				DELAY_OF_ONE_MILLISEC, 50000, false, lp,
> +				XAE_IS_OFFSET);
> +	if (ret) {
> +		dev_err(lp->dev, "%s: timeout waiting for PhyRstCmplt\n",
> __func__);
> +		return ret;
>  	}
>  
>  	return 0;
> @@ -2046,6 +2055,11 @@ static int axienet_probe(struct platform_device *pdev)
>  	lp->coalesce_count_rx = XAXIDMA_DFT_RX_THRESHOLD;
>  	lp->coalesce_count_tx = XAXIDMA_DFT_TX_THRESHOLD;
>  
> +	/* Reset core now that clocks are enabled, prior to accessing MDIO */
> +	ret = __axienet_device_reset(lp);
> +	if (ret)
> +		goto cleanup_clk;
> +
>  	lp->phy_node = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
>  	if (lp->phy_node) {
>  		ret = axienet_mdio_setup(lp);

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ