Lantiq PHY Timing Skew Settings and UDP Errors

Placement, modules, components and accessories; the ones that exist and the the nice-to-be's
Post Reply
mjdbishop
Posts: 7
Joined: Wed Feb 01, 2017 1:51 pm

Lantiq PHY Timing Skew Settings and UDP Errors

Post by mjdbishop » Mon Mar 06, 2017 2:08 pm

If the receive and transmit timing skews on the RGMII interface between the Zynq and PHY (Lantiq PEF 7071) are incorrect "Ethernet" errors almost certainly occur; the "skews" are the adjustment of the clock / data relationship at the input / output of the PHY - for Gb Enet 125 MHz (8 ns period) nibble wide. The skews are set in the PHY, for the PEF 7071 by MDIO register 17h and take values from 0 to 3.5 ns with 500 ps increments. The skews initial / reset values are defined by "soft pin strappings" - details not shown on the schematics - to 1.5 ns (based on read back) for Tx and Rx.

UDP traffic ~ 1 kby packets at Mby /s rates exhibits an ~2.5 E-4 packet drop out rate with 1.5 ns (default) skews. UDP is of course vulnerable to "random" transmission path errors as it lacks the guaranteed delivery through acknowledgement of TCP. Noting that pathological values of drop out rate can be achieved with "bad" choices for skew, e.g. 0 ns or 3.5 ns, what is the optimum value ? Measurements, between a pair of RP boards with a PC as "reference", suggest that 2.5 ns is a good value : zero errors observed on > 1 Mby/s UDP traffic for an extended period (10+ hours).

The required value of skew is sometimes achieved by differences in track length between clock and data, as 10 mm is 33 ps even with serpentine tracks this seems an unlikely source of the delays required. The Zynq's PS RGMII has data sheet timing values,e.g. DS187 Table 36, for Tx tco = +/- 500 ps and for Rx ts and th of 800 ps. Which suggests that : 1.5 to 2.5 ns delays in the PHY are in the correct ballpark for skew corrections. More generally FPGA routing would affect a PHY interfaced through the fabric. Also, see http://ethernetfmc.com/rgmii-interface- ... derations/ for a concise description of the issues.

My essential question is does anyone have a view on the "optimum" values for Tx and Rx skews ?
- e.g. what (range of) values did the designers anticipate, and is the default 1.5 ns design intent ?
- e.g. what values are used in the Linux distros for Red Pitaya ?
And what variability in the "optimum" values one might expect ?
Or know a better test methodology, than verifying (ISO level 6/7) sequence numbers and counting the gaps in UDP packets

Martin

pavel
Posts: 789
Joined: Sat May 23, 2015 5:22 pm

Re: Lantiq PHY Timing Skew Settings and UDP Errors

Post by pavel » Mon Mar 06, 2017 2:58 pm

what values are used in the Linux distros for Red Pitaya
According to this comment in the PHY driver, RX and TX timing skews are set to 2 ns and 2.5 ns.

izi
Posts: 34
Joined: Wed May 27, 2015 11:49 am

Re: Lantiq PHY Timing Skew Settings and UDP Errors

Post by izi » Wed Mar 08, 2017 11:08 am

The PHY driver requires changes on many kernel releases, and original features are not tested beyond "is it working".
For the upcoming kernel 4.9 we plan to use a different driver, which was proposed for upstream inclusion.
https://github.com/RedPitaya/linux-xlnx ... y/lantiq.c

This file was probably used to test various PHY settings:
https://github.com/RedPitaya/RedPitaya/ ... antiq_mdio
I never used it so I am unsure how and if it works.

PHY11G documentation is also a bit difficult to get, here is one document, but I am unsure right now if it is for the same chip version/revision as used on Red Pitaya. Reading the version register would give more details.
https://www.we-online.com/web/fr/index. ... VQFN48.pdf

Regards,
Iztok Jeras

mjdbishop
Posts: 7
Joined: Wed Feb 01, 2017 1:51 pm

Re: Lantiq PHY Timing Skew Settings and UDP Errors

Post by mjdbishop » Mon Mar 13, 2017 3:31 pm

Pavel,
Thank you for the pointer to the lantiq.c file.

I noted that the value written to register 17x is 0x4D00 : implying Rx=2.0 Tx=2.5, Rx clock inactive when link is down, and MII at 2v5. My experience is that both 4D00x and D500x work. However, the power on default of B300x causes Ethernet errors - the Rx=Tx=1.5 ns values result in a packet error rate of ~2E-4 (based on measurements). From the info provided by the "schematics" and data sheet, 2v5 seems the correct setting although I have not seen it make any difference in practice.

I have tested with the setings used in lantiq.c Rx=2.0 ns and Tx=2.5 ns. No errors observed on quite a lot of traffic, just like Rx=Tx=2.5. Which is correct ? Good question. I have changed to the Lantiq.c settings on the premise that they were based on more design information than I have available. Both settings deliver zero observable errors.

Izi,
The data sheet you identify is the top Google hit, and the one I have been using, it seems valid - if a little thin on the explanation of some functionality.

The Red Pitaya's I have to hand (a V1.1 and 125-10 V1.0) report a Phy Id, from registers 2 & 3, of D565_A401x which corresponds to a PHY11G rev 1.5.

I have quickly skimmed the lantiq.c file you have as a candidate for kernel 4.9. I can see no configuration of x17, and the Rx Tx timings, only blinkenlites activities. If that is the case I would black ball it, as the removal of the x17 configuration not only breaks the "ain't broke don't fix it rule" but also on the basis of my investigations will introduce a finite error rate into the Tx traffic (due to timing violations between EmacPs and PHY).

The test methodology I have used is to look for skips in packets transmitted by UDP, a higher level protocol (e.g. RTP RFC 3550) provides the sequence numbers. With traffic in the Mb/s range and long runs (overnight), effectively zero error rates have been observed through local Gb switches. If you are using UDP, it is necessary to work the problem to this degree. Accepting the loss of throughput which attends a packet error rate of ~2E-4 on TCP is not an option, you loose data. I have observed the occasional grumble regarding finite error rates on UDP (in other contexts) and wonder if the MII interface timing issues we are considering might not be involved.

FYI I have appended the code I use to initialise the PHY11G, in code using the Xilinx standalone framework. The only thing which seems to matter is setting x17. The reset, auto negotiation, etc is all good practice but I am unconvinced of its necessity.

Finally, thank you for your assistance

Regards

Martin

static u32_t get_Lantiq_phy_speed(XEmacPs *xemacpsp, u32_t phy_addr)
{
u16_t control;
u16_t status;
u16_t status_speed;
u32_t timeout_counter = 0;
u16_t MiiCtrlReg;
int i;
u16_t value;
u32_t RetStatus;

printf("%s_%d %s phy%d Starting Autonegotiation\r\n",
Tally, CpuNo, __func__, phy_addr);

// reset the MAC
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &MiiCtrlReg);
MiiCtrlReg |= IEEE_CTRL_RESET_MASK;
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, MiiCtrlReg);

// wait for reset to complete
timeout_counter = 0;
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &status);

while ((status & IEEE_CTRL_RESET_MASK) )
{
BusyWait_us(1000);
timeout_counter++;

if (timeout_counter == 10000)
{
printf("%s_%d %s phy%d Reset timeout after %d ms\r\n",
Tally, CpuNo, __func__, phy_addr, timeout_counter);
return XST_FAILURE;
}
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &status);
}

printf("%s_%d %s phy%d Phy reset completed after %d ms\r\n",
Tally, CpuNo, __func__, phy_addr, timeout_counter);

// skew := 2.0 Rx & 2.5 Tx ns
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_MII_CONTROL_REG, &control);
printf("%s_%d Lantiq Mdio.MiiCtrl %04Xx Rst Skews Rx=%d Tx=%d (ps)\r\n",
Tally, CpuNo, control, ((control >> 12) & 0x7)*500, ((control >> 8) & 0x7)*500);
control &= ~0xFF00; // mask off Rx & Tx skew fields etc
control |= 0x4D00; // configure Rx & Tx skew fields etc - iaw Linux driver
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_MII_CONTROL_REG, control);
printf("%s_%d Lantiq Mdio.MiiCtrl %04Xx Set Skews Rx=%d Tx=%d (ps)\r\n",
Tally, CpuNo, control, ((control >> 12) & 0x7)*500, ((control >> 8) & 0x7)*500);

// advertise 10M / 100M / a/sym pause
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control);
control |= IEEE_ASYMMETRIC_PAUSE_MASK;
control |= IEEE_PAUSE_MASK;
control |= ADVERTISE_100;
control |= ADVERTISE_10;
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control);

// advertise 1000M
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET, &control);
control |= ADVERTISE_1000;
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET, control);

// request autonegotiation
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
control |= IEEE_CTRL_AUTONEGOTIATE_ENABLE;
control |= IEEE_CTRL_AUTONEGOTIATE_RESTART;
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);

timeout_counter = 0;
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);

printf("%s_%d %s phy%d Waiting for PHY to complete autonegotiation\r\n",
Tally, CpuNo, __func__, phy_addr);

while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) )
{
BusyWait_us(1000);
timeout_counter++;

if (timeout_counter == 30000)
{
printf("%s_%d %s phy%d Autonegotiation timeout after %d ms\r\n",
Tally, CpuNo, __func__, phy_addr, timeout_counter);
return XST_FAILURE;
}
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
}

// obtain MII status
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_MII_STATUS_REG, &status_speed);

printf("%s_%d %s phy%d Autonegotiation successful after %d ms MiiStatus = %04Xx\r\n",
Tally, CpuNo, __func__, phy_addr, timeout_counter, status_speed);

// dump Mdio registers
for (i = 0; i < 0x20; i++)
{
XEmacPs_PhyRead(xemacpsp, phy_addr, i, &value);
printf("%s_%d %s phy%d MdioRegister %2Xx = %04Xx\r\n",
Tally, CpuNo, __func__, phy_addr, i, value);
}

// note hooks
Lantiq_xemacpsp = xemacpsp;
Lantiq_phy_addr = phy_addr;

// return speed
switch (status_speed & 0x0003)
{
case 0:
return 10;
break;
case 1:
return 100;
break;
case 2:
return 1000;
break;
default:
return XST_FAILURE;
break;
}
}

Post Reply
jadalnie klasyczne ekskluzywne meble wypoczynkowe do salonu ekskluzywne meble tapicerowane ekskluzywne meble do sypialni ekskluzywne meble włoskie

Who is online

Users browsing this forum: No registered users and 20 guests