[PATCH 1/1] mvpp2: fix second cp110 initialization

Stefan Roese sr at denx.de
Thu Jul 9 10:32:32 CEST 2020


On 01.07.20 17:43, Sven Auhagen wrote:
> Since the mdio code got upstreamed it is not possible
> to activate network ports on CP110 Master and Slave.
> 
> The problem is in mvpp2_base_probe which is called for each
> CP110 and it initializes the buffer area for descs and rx_buffers.
> 
> This should only happen once though and the bd space is actually
> set to 0 after the first run of the function.
> 
> This leads to an error when the second CP110 tries the initialization
> again and disables all network ports on this CP110.
> 
> This patch adds a static variable to check if the buffer area is
> initialized only once globally.
> 
> Signed-off-by: Sven Auhagen <sven.auhagen at voleatech.de>

Reviewed-by: Stefan Roese <sr at denx.de>

Thanks,
Stefan

> ---
>   drivers/net/mvpp2.c | 63 ++++++++++++++++++++++++---------------------
>   1 file changed, 34 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/net/mvpp2.c b/drivers/net/mvpp2.c
> index 19b9375ee2..1296ff9430 100644
> --- a/drivers/net/mvpp2.c
> +++ b/drivers/net/mvpp2.c
> @@ -1263,6 +1263,7 @@ struct buffer_location {
>    * can be enabled at once
>    */
>   static struct buffer_location buffer_loc;
> +static int buffer_loc_init;
>   
>   /*
>    * Page table entries are set to 1MB, or multiples of 1MB
> @@ -5247,40 +5248,44 @@ static int mvpp2_base_probe(struct udevice *dev)
>   	 * be active. Make this area DMA-safe by disabling the D-cache
>   	 */
>   
> -	/* Align buffer area for descs and rx_buffers to 1MiB */
> -	bd_space = memalign(1 << MMU_SECTION_SHIFT, BD_SPACE);
> -	mmu_set_region_dcache_behaviour((unsigned long)bd_space,
> -					BD_SPACE, DCACHE_OFF);
> -
> -	buffer_loc.aggr_tx_descs = (struct mvpp2_tx_desc *)bd_space;
> -	size += MVPP2_AGGR_TXQ_SIZE * MVPP2_DESC_ALIGNED_SIZE;
> -
> -	buffer_loc.tx_descs =
> -		(struct mvpp2_tx_desc *)((unsigned long)bd_space + size);
> -	size += MVPP2_MAX_TXD * MVPP2_DESC_ALIGNED_SIZE;
> +	if (!buffer_loc_init) {
> +		/* Align buffer area for descs and rx_buffers to 1MiB */
> +		bd_space = memalign(1 << MMU_SECTION_SHIFT, BD_SPACE);
> +		mmu_set_region_dcache_behaviour((unsigned long)bd_space,
> +						BD_SPACE, DCACHE_OFF);
> +
> +		buffer_loc.aggr_tx_descs = (struct mvpp2_tx_desc *)bd_space;
> +		size += MVPP2_AGGR_TXQ_SIZE * MVPP2_DESC_ALIGNED_SIZE;
> +
> +		buffer_loc.tx_descs =
> +			(struct mvpp2_tx_desc *)((unsigned long)bd_space + size);
> +		size += MVPP2_MAX_TXD * MVPP2_DESC_ALIGNED_SIZE;
> +
> +		buffer_loc.rx_descs =
> +			(struct mvpp2_rx_desc *)((unsigned long)bd_space + size);
> +		size += MVPP2_MAX_RXD * MVPP2_DESC_ALIGNED_SIZE;
> +
> +		for (i = 0; i < MVPP2_BM_POOLS_NUM; i++) {
> +			buffer_loc.bm_pool[i] =
> +				(unsigned long *)((unsigned long)bd_space + size);
> +			if (priv->hw_version == MVPP21)
> +				size += MVPP2_BM_POOL_SIZE_MAX * 2 * sizeof(u32);
> +			else
> +				size += MVPP2_BM_POOL_SIZE_MAX * 2 * sizeof(u64);
> +		}
>   
> -	buffer_loc.rx_descs =
> -		(struct mvpp2_rx_desc *)((unsigned long)bd_space + size);
> -	size += MVPP2_MAX_RXD * MVPP2_DESC_ALIGNED_SIZE;
> +		for (i = 0; i < MVPP2_BM_LONG_BUF_NUM; i++) {
> +			buffer_loc.rx_buffer[i] =
> +				(unsigned long *)((unsigned long)bd_space + size);
> +			size += RX_BUFFER_SIZE;
> +		}
>   
> -	for (i = 0; i < MVPP2_BM_POOLS_NUM; i++) {
> -		buffer_loc.bm_pool[i] =
> -			(unsigned long *)((unsigned long)bd_space + size);
> -		if (priv->hw_version == MVPP21)
> -			size += MVPP2_BM_POOL_SIZE_MAX * 2 * sizeof(u32);
> -		else
> -			size += MVPP2_BM_POOL_SIZE_MAX * 2 * sizeof(u64);
> -	}
> +		/* Clear the complete area so that all descriptors are cleared */
> +		memset(bd_space, 0, size);
>   
> -	for (i = 0; i < MVPP2_BM_LONG_BUF_NUM; i++) {
> -		buffer_loc.rx_buffer[i] =
> -			(unsigned long *)((unsigned long)bd_space + size);
> -		size += RX_BUFFER_SIZE;
> +		buffer_loc_init = 1;
>   	}
>   
> -	/* Clear the complete area so that all descriptors are cleared */
> -	memset(bd_space, 0, size);
> -
>   	/* Save base addresses for later use */
>   	priv->base = (void *)devfdt_get_addr_index(dev, 0);
>   	if (IS_ERR(priv->base))
> 


Viele Grüße,
Stefan

-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-51 Fax: (+49)-8142-66989-80 Email: sr at denx.de


More information about the U-Boot mailing list