[PATCH] net: zynq_gem: Wait for SGMII PCS link in zynq_gem_init()

Stefan Roese sr at denx.de
Wed Jan 11 08:29:46 CET 2023


On 1/10/23 19:28, Sean Anderson wrote:
> On 1/10/23 05:38, Stefan Roese wrote:
>> In our system using ZynqMP with an external SGMII PHY it's necessary
>> to wait for the PCS link and auto negotiation to finish before the xfer
>> starts. Otherwise the first packet(s) might get dropped, resulting in a
>> delay at the start of the ethernet transfers.
>>
>> This patch adds the necessary code at the end of zynq_gem_init()
>> including a minimal delay of 10ms which fixes problems of dropped
>> first packages.
>>
>> Signed-off-by: Stefan Roese <sr at denx.de>
>> Cc: Michal Simek <michal.simek at amd.com>
>> Cc: T Karthik Reddy <t.karthik.reddy at amd.com>
>> Cc: Ramon Fried <rfried.dev at gmail.com>
>> ---
>>   drivers/net/zynq_gem.c | 32 +++++++++++++++++++++++++++++++-
>>   1 file changed, 31 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
>> index 507b19b75975..625b0303d6e2 100644
>> --- a/drivers/net/zynq_gem.c
>> +++ b/drivers/net/zynq_gem.c
>> @@ -125,6 +125,10 @@
>>    */
>>   #define PHY_DETECT_MASK 0x1808
>>   
>> +/* PCS (SGMII) Link Status */
>> +#define ZYNQ_GEM_PCSSTATUS_LINK		BIT(2)
>> +#define ZYNQ_GEM_PCSSTATUS_ANEG_COMPL	BIT(5)
>> +
>>   /* TX BD status masks */
>>   #define ZYNQ_GEM_TXBUF_FRMLEN_MASK	0x000007ff
>>   #define ZYNQ_GEM_TXBUF_EXHAUSTED	0x08000000
>> @@ -164,7 +168,8 @@ struct zynq_gem_regs {
>>   	u32 stat[STAT_SIZE]; /* 0x100 - Octects transmitted Low reg */
>>   	u32 reserved9[20];
>>   	u32 pcscntrl;
>> -	u32 rserved12[36];
>> +	u32 pcsstatus;
>> +	u32 rserved12[35];
>>   	u32 dcfg6; /* 0x294 Design config reg6 */
>>   	u32 reserved7[106];
>>   	u32 transmit_q1_ptr; /* 0x440 - Transmit priority queue 1 */
>> @@ -522,6 +527,31 @@ static int zynq_gem_init(struct udevice *dev)
>>   			return ret;
>>   		}
>>   	}
>> +
>> +	/* Wait for SGMII link */
>> +	if (priv->interface == PHY_INTERFACE_MODE_SGMII && priv->int_pcs) {
>> +		u32 pcsstatus;
>> +
>> +		if (priv->phydev->phy_id == PHY_FIXED_ID)
>> +			pcsstatus = ZYNQ_GEM_PCSSTATUS_LINK;
>> +		else
>> +			pcsstatus = ZYNQ_GEM_PCSSTATUS_LINK |
>> +				ZYNQ_GEM_PCSSTATUS_ANEG_COMPL;
> 
> Use BMSR_LSTATUS/BMSR_ANEGCOMPLETE.

The PHY link aneg is done in the PHY code already. But thanks for your
comment. I re-thought about this and testing shows, that only the 10ms
delay is really needed. Regardless of the aneg being in action while
running the network xfer or the link being fully established.

I'll post a new patch replacing this one shortly.

Thanks,
Stefan

>> +
>> +		ret = wait_for_bit_le32(&regs->pcsstatus, pcsstatus,
>> +					true, 5000, true);
>> +		if (ret) {
>> +			dev_err(dev, "no PCS (SGMII) link detected\n");
> 
> This should be an info or lower, since this is normal behavior when there
> is no link partner (e.g. when the cable is unplugged).
> 
> --Seam
> 
>> +			return ret;
>> +		}
>> +
>> +		/*
>> +		 * Some additional minimal delay seems to be needed so that
>> +		 * the first packet will be sent correctly
>> +		 */
>> +		mdelay(10);
>> +	}
>> +
>>   	setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK |
>>   					ZYNQ_GEM_NWCTRL_TXEN_MASK);
>>   
> 

Viele Grüße,
Stefan Roese

-- 
DENX Software Engineering GmbH,      Managing Director: Erika Unter
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