Hi SIr
We used AM4377 with SDK 4.03.00.05 for development.
1. PRU MII is connected to RTL8201 and CPSW RGMII is connected to RTL8211.
2. We have done the compliance test for Ethernet PHY.
We found we did the signal quality test failed in PRU Ethernet port
The duplicated is listed as below
1.Set AM4377 PRU Ethernet Port as 100M setting and CPSW Ethernet Port as 1000M setting.
2.We used PRU Ethernet Port for 10M duplex test and send packet by using genpkt command. It failed
3. We used CPSW Ethernet Port for 10M duplex test and send packet by using genpkt command. It passed.
It seems this issue only happened in PRU Ethernet 10M mode.
Below is the information
1. genpkt sample code
/* Ethernet packet generator */
/* Written by Vladimir Zapolsky */
/* mail to avz101c@motolola.com */
/* July 28, 2007 */
#define ETH_FRAME_LEN 1514
#define ETH_HEADER_LEN (2 * ETH_ALEN)
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <netinet/in.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>
#include <sys/ioctl.h>
#include <getopt.h>
#include <unistd.h>
#include <fcntl.h>
typedef struct _Packets
{
unsigned int dst[ETH_ALEN];
unsigned int src[ETH_ALEN];
unsigned char hdr[ETH_HEADER_LEN];
unsigned char payload;
char ifname[5];
int fll;
int cnt;
int rnd;
int len;
} Packets;
Packets packets;
const char* program;
void dump_packets()
{
printf("Interface name: %s\n", packets.ifname);
if (packets.fll)
{
printf("Fillall\n");
}
else
{
printf("Source MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", packets.src[0], packets.src[1], packets.src[2], packets.src[3], packets.src[4], packets.src[5]);
printf("Destination MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", packets.dst[0], packets.dst[1], packets.dst[2], packets.dst[3], packets.dst[4], packets.dst[5]);
}
printf("Count: %d\n", packets.cnt);
printf("Length: %d\n", packets.len);
if (packets.rnd)
{
printf("Payload: random\n");
}
else
{
printf("Payload: %02X\n", packets.payload);
}
}
void src_mac(const int sd, int* index)
{
struct ifreq ifr;
int i;
strcpy(ifr.ifr_name, packets.ifname);
if (ioctl(sd, SIOCGIFINDEX, &ifr) == -1)
{
perror("Cannot get ifindex of the interface");
exit(1);
}
*index = ifr.ifr_ifindex;
if (ioctl(sd, SIOCGIFHWADDR, &ifr) == -1 )
{
perror("Cannot get source MAC ");
exit(1);
}
for (i = 0; i < 6; i++)
{
packets.src[i] = ifr.ifr_hwaddr.sa_data[i];
}
}
void print_usage()
{
printf("Usage: %s [options]\n", program);
printf(" -h --help Display the usage information.\n");
printf(" -p --payload (0x[0-9A-F]{2}|rand) Set payload.\n");
printf(" -i --interface eth[0-9] Set interface.\n");
printf(" -c --count num Set number of packets to send.\n");
printf(" -f --fillall Set packet header similar to payload.\n");
printf(" -d --dest XX:XX:XX:XX:XX Set destination MAC address.\n");
printf(" -l --length num Set whole length of a packet ( min 60, max 1514 )\n");
printf(" Default payload is 0x00, interface is eth0, count of packets is 1, length is 1514.\n");
printf(" Default destination MAC address is 00:00:00:00:00:00.\n");
exit(1);
}
void print_error(char* str)
{
printf("%s\n", str);
exit(1);
}
int main (int argc, char* argv[])
{
int sd = 0;
int rd = 0;
program = argv[0];
int opt;
unsigned char buffer[ETH_FRAME_LEN];
int i;
struct sockaddr_ll saddr;
/* int status;*/
const char* const short_opt = "hp:i:c:fd:l:";
const struct option long_opt[] =
{
{ "help", 0, NULL, 'h' },
{ "payload", 1, NULL, 'p' },
{ "interface", 1, NULL, 'i' },
{ "count", 1, NULL, 'c' },
{ "fillall", 0, NULL, 'f' },
{ "dest", 1, NULL, 'd' },
{ "length", 1, NULL, 'l' }
};
for (i = 0; i < ETH_ALEN; i++)
{
packets.dst[i] = 0x00;
packets.src[i] = 0x00;
}
packets.len = ETH_FRAME_LEN;
packets.rnd = 0;
packets.cnt = 1;
packets.payload = 0x00;
packets.fll = 0;
strcpy(packets.ifname, "eth0");
do
{
opt = getopt_long(argc, argv, short_opt, long_opt, NULL);
switch (opt)
{
case 'h':
print_usage();
case 'p':
if (strlen(optarg) != 4)
{
print_error("Invalid payload");
}
else if (!strcmp("rand", optarg))
{
packets.rnd = 1;
}
else if (!strncmp("0x", optarg, 2))
{
packets.payload = strtol(optarg, (char**)NULL, 16);
}
else
{
print_error("Invalid payload");
}
break;
case 'i':
if (strlen(optarg) > 4 || strncmp("eth", optarg, 3))
{
print_error("Invalid interface name");
}
strcpy(packets.ifname, optarg);
break;
case 'c':
packets.cnt = strtol(optarg, (char**)NULL, 10);
if (packets.cnt <= 0)
{
print_error("Invalid count");
}
break;
case 'f':
packets.fll = 1;
break;
case 'd':
if (strlen(optarg) != 17)
{
print_error("Invalid destination MAC address");
}
else
{
for (i = 0; i < 5; i++)
{
if (optarg[3*i+2] != ':')
{
print_error("Invalid destination MAC address");
}
}
if (sscanf(optarg, "%x:%x:%x:%x:%x:%x", &packets.dst[0], &packets.dst[1], &packets.dst[2], &packets.dst[3], &packets.dst[4], &packets.dst[5]) != ETH_ALEN)
{
print_error("Invalid destination MAC address");
}
}
break;
case 'l':
packets.len = strtol(optarg, (char**)NULL, 10);
if (packets.len > ETH_FRAME_LEN || packets.len < 60)
{
print_error("Invalid length");
}
break;
default:
break;
}
}
while (opt != -1);
/* Body */
if (packets.rnd)
{
rd = open("/dev/urandom", O_RDONLY);
if (rd == -1)
{
printf("Cannot open /dev/urandom, packets are filled with zeroes\n");
packets.rnd = 0;
}
}
sd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (sd == -1)
{
perror("Cannot open socket ");
exit(1);
}
saddr.sll_family = PF_PACKET;
saddr.sll_protocol = htons(ETH_P_IP);
src_mac(sd, &saddr.sll_ifindex);
saddr.sll_hatype = ARPHRD_ETHER;
saddr.sll_pkttype = PACKET_OTHERHOST;
saddr.sll_halen = ETH_ALEN;
/* saddr.sll_addr[i] = packets.dst[i];*/
dump_packets();
/* Generate payload */
for (i = 0; i < ETH_ALEN; i++)
{
packets.hdr[i] = (unsigned char)packets.dst[i];
packets.hdr[i + ETH_ALEN] = (unsigned char)packets.src[i];
}
if (!packets.rnd)
{
memset((void*)buffer, packets.payload, packets.len);
}
if (!packets.fll)
{
memcpy((void*)buffer, (void*)packets.hdr, ETH_HEADER_LEN);
}
while(packets.cnt > 0)
{
if (packets.rnd)
{
if (packets.fll)
{
read(rd, buffer, packets.len);
}
else
{
read(rd, &buffer[ETH_HEADER_LEN], packets.len - ETH_HEADER_LEN);
}
}
if (sendto(sd, buffer, packets.len, 0, (struct sockaddr*)&saddr, sizeof(saddr)) != packets.len)
{
print_error("Cannot send a packet");
perror("");
}
packets.cnt--;
}
printf("Done.\n");
if (rd > 0)
{
close(rd);
}
close(sd);
return(0);
}
2. Below is the test waveform
We found the PRU Ethernet Port test failed and cannot meet right photo requirement
We found the signal from the PRU Ethernet Port has interference (Left Photo)
BTW, we found the inter-space width of left photo is 1.325us. The standard spec should be over 4.2us.
The inter-space width of right photo is 9.28us
Please advise
BR
Yimin




