Part Number: DP83867CS
Other Parts Discussed in Thread: DP83867CR
Hi Everyone,
Please note we are in critical phase of project.
We have ZYNC-ZC702 based custom board where we have connected, two DP83867E phys to two macs, GEM0, and GEM1. We have configured the both phys in RGMII mode.
But out of two MACs only one MAC, GEM0 is running at 1000Mbps speed and other GEM1 is working only at 10Mbps and 100Mbps
GEM1,
1. Working at 10/100Mbps only
2. If I do ifconfig up eth1, it will configure itself in full dublex, 1000Mbps and auto-negotiation mode
On Linux:
At 1000Mbps, GEM1 doesn't get the IP through DHCP. I verified that no packets are being sent from this interface by running wireshark, this essentially mean MAC is not working
I have attached dump of phy register contents, after completion of auto-negotiation for both working and non-working MAC instance when running Linux
Please note that in attached archive post_auto_neg.zip,
post_auto_neg_eth0.log - Register dump for Phy registers post auto-neg for working MAC
Register 0x08
1 > Received page is a Message Page.
Register 0x09
1 > Advertise 1000Base-T Full Duplex ability.
Register 0x0A
1 > Manual Master/Slave Configuration fault detected.
2 > Local receiver is not OK.
3 > Remote receiver is not OK.
4 > Link partner not capable of 1000Base-T Full Duplex.
5 > Link partner not capable of 1000Base-T Half Duplex.On Xilinx Baremetal:
In order to debug it further, I tried to perform BIST test. I have attached the pseudo code for same, please let me know whether the steps are correct.
With BIST, following is the result,
Byte count 4098 Error byte count 128
The above result is with auto-negotiation turned on. Auto-neg sets phy to 1000Mbps,Full-duplex link and link is up
Please note that I am not able to disable auto-negotiation bit. Even after clearing 12th bit of BMCR, auto-negotiation is not disabled. SGMII_EN bit 11, is set even though this bit is not set.
Following is our set-up:
I/O voltages that we are using is 2.7V and following are strap register values
Following are registers for strap, in format of <Strap pin, Rhi, Rlo>
==================================================================
Strap pins in Mode 2:
G1LED_0, 6.2K,1.6K
G1LED_1, 6.2K,1.6K
G1LED_2, 6.2K,1.6K
G1ETH_RXD0, 6.2K,1.6K
G1ETH_GPIO1, 6.2K,1.6K
G2LED_0, 6.2K, 1.6K
G2LED_1, 6.2K, 1.6K
G2LED_2, 6.2K, 1.6K
G2ETH_GPIO1, 6.2K, 1.6K
Strap pins in Mode 1:
G1ETH_RXD2, Open, 1.6K
G1ETH_GPIO0, Open, 1.6K
G2ETH_RXD2, Open, 1.6K
G2ETH_GPIO0, Open, 1.6K
Strap pins in Mode 4:
G1ETH_RXCTRL, 960, 1.6K
G2ETH_RXCTRL, 960, 1.6K
G2ETH_RXD0, 960, 1.6K
============================================
/* Set RGMII mode */
reg_val = REGR16(DP_RGMIICT);
reg_val |= (1 << 7);
REGW16(DP_RGMIICT, reg_val);
/* Set MDI mode manually */
reg_val = REGR16(DP_PHYCR);
if (mdix == 0) {
printf("Setting MDI connection manually\n");
reg_val &= ~(3 << 5);
} else {
printf("Setting MDIX connection\n");
reg_val &= ~(3 << 5);
reg_val |= (1 << 5);
}
REGW16(DP_PHYCR, reg_val);
/* Set-up BMCR */
reg_val = REGR16(DP_BMCR);
/* Set-up speed */
printf("Speed: ");
switch (speed) {
case 1000:
printf("1000BaseT\n");
reg_val |= (0x1 << 6); /* Set 1000BaseT*/
reg_val &= ~(0x1 << 13);
break;
case 100:
printf("100BaseT\n");
reg_val &= ~(0x1 << 6); /* Set 100BaseT*/
reg_val |= 0x1 << 13;
break;
case 10:
printf("10BaseT\n");
reg_val &= ~(0x1 << 6); /* Set 10BaseT*/
reg_val &= ~(0x1 << 13);
break;
};
/* Set-up auto negotiation */
printf("Autoneg : %s\n", auto_neg ? "ON" : "OFF");
if (!auto_neg) {
reg_val &= ~(0x1 << 12); /* Disable auto-negotiation */
} else {
reg_val |= (0x1 << 12); /* Enable auto-negotiation */
}
/* Set-up duplex type */
printf("Duplex : %s\n", duplex_type == full_duplex ? "FULL" : "HALF");
if (duplex_type == full_duplex) {
reg_val |= 0x1 << 8; /* Full duplex */
} else {
reg_val &= ~(0x1 << 8); /* Half duplex */
}
REGW16(DP_BMCR, reg_val);
/* Soft reset */
reg_val = REGR16(DP_BMCR);
reg_val |= 0x1 << 15;
REGW16(DP_BMCR, reg_val);
printf("Waiting for reset to complete ...\n");
do {
reg_val = REGR16(DP_BMCR);
} while (reg_val & (1 << 15));
/* Wait for link training to complete */
printf("Link status 0x%x\n", REGR16(DP_PHYSTS));
printf("Waiting for link to be up ..\n");
while (!(REGR16(DP_PHYSTS) & (1 << 10)));
printf("BMCR 0x%x\n", REGR16(DP_BMCR));
/* PRBS count mode */
REGW16_FIELD(DP_BISCR, PRBS_COUNT_MODE, 1);
/* PRBS generate packet */
REGW16_FIELD(DP_BISCR, GEN_PRBS_PACKET, 1);
/* Disable PCS loop-back */
REGW16_FIELD(DP_BISCR, PCS_LOOPBACK, 0);
/* Non-PCS loop-back */
{
switch(loop_back) {
case BISCR_LOOPBACK_MODE_digital_loop:
printf("Digital loop-back\n");
break;
case BISCR_LOOPBACK_MODE_analog_loop:
printf("Analog loop-back\n");
break;
case BISCR_LOOPBACK_MODE_external_loop:
printf("External loop-back\n");
break;
case BISCR_LOOPBACK_MODE_reverse_loop:
printf("Reverse loop-back\n");
break;
};
REGW16_FIELD(DP_BISCR, LOOPBACK_MODE, loop_back);
}
printf("<<<<<<<<<<<<<<<<<<<< Reg dump >>>>>>>>>>>>>>>>>>>>\n");
printf("DP_PHYIDR1 0x%x\n", REGR16(DP_PHYIDR1));
printf("DP_RGMIICT 0x%x\n", REGR16(DP_RGMIICT));
printf("DP_PHYCR 0x%x\n", REGR16(DP_PHYCR));
printf("DP_RGMIIDCTL 0x%x\n", REGR16(DP_RGMIIDCTL));
printf("DP_BMCR 0x%x\n", REGR16(DP_BMCR));
printf("DP_BISCR 0x%x\n", REGR16(DP_BISCR));
printf("==================================================\n");
/* Enable packet generation */
REGW16_FIELD(DP_BISCR, PACKET_GEN_EN, 1);
/* Wait for lock to release */
do {
if (REGR16_FIELD(DP_STS2, PRBS_LOCK) == 1)
locked = 1;
if (--count == 0) {
break;
}
} while (!locked);
if (REGR16_FIELD(DP_STS2, PRBS_LOCK_LOST) == 1)
lost_lock = 1;
byte_cnt = REGR16(DP_BICSR1);
/* Stop and clear PRB counter */
REGW16(DP_BICSR1, 0x3);
/* In continous mode error is checked once packet generator is disabled */
REGW16_FIELD(DP_BISCR, PACKET_GEN_EN, 0);
err_byte_cnt = REGR16_FIELD(DP_BICSR2, PRBS_ERR_CNT);
if (REGR16_FIELD(DP_STS2, PKT_GEN_BUSY) == 1)
busy = 1;
printf("Busy bit 0x%x, Locked status 0x%x\n",
REGR16_FIELD(DP_STS2, PKT_GEN_BUSY),
REGR16_FIELD(DP_STS2, PRBS_LOCK));
locked = REGR16_FIELD(DP_STS2, PRBS_LOCK);
if (locked)
printf("Locked\n");
if (busy)
printf("Busy\n");
if (lost_lock)
printf("lost lock\n");
printf("Byte count %d Error byte count %d\n", byte_cnt, err_byte_cnt);
Regards,
Abhijit