Ethernet Compliance Test를 위해 Ethernet PHY 에서 특정 신호를 출력할 수 있게 설정해 주어야 한다.
Ethernet PHY(Broadcom B50612E)의 datasheet를 참조한다.
testmode.c
/*
* Test Mode
*
* The BCM5461 can be placed in one of four transmit test mode by writing bits [15:13] of the 1000BASE-T control register.
* The transmit test modes are defined in IEEE802.3ab. When read, these bits return the last value written. For test modes 1,
* 2, and 4 the PHY must have auto-negotiation disabled, forced to 1000BASE-T mode and auto-MDIX disabled.
*
* Disable auto-neg and force to 1000BASE-T mode (write to register 00h = 0x0040)
* Disable auto-MDIX (write to register 18h, shadow value 111, bit 9 = 0)
* Enter test mode s (write to register 09h, bits[15:13] = the test mode you want)
*
*/
#include <linux/mii.h>
#include <net/if.h>
#include <linux/sockios.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
/* Ethernet dev */
#define NET_DEV "eth1"
/* PHY id */
#define PHY_ADDR (0)
/* Register Map (Broadcom B50612E) */
#define PHY_MII_CTRL_REG (0x00) /* 1000BASE-T/100BASE-TX/10BASE-T MII Control Register */
#define PHY_CTRL_REG (0x09) /* 1000BASE-T Control Register */
#define PHY_MISC_CTRL_REG (0x18) /* 1000BASE-T/100BASE-TX/10BASE-T Miscellaneous Control Register */
int main(int argc, char *argv[])
{
struct ifreq ifr;
struct mii_ioctl_data *mii;
int nSockFD;
int mode;
if (argc < 2)
{
printf("* Usage : ./testmode [mode] \n");
printf("* mode : \n");
printf(" 0 - Normal operation\n");
printf(" 1 - Test mode 1 (Transmit waveform test) \n");
printf(" 2 - Test mode 2 (Master transmit jitter test) \n");
printf(" 3 - Test mode 3 (Slave transmit jitter test) \n");
printf(" 4 - Test mode 4 (Transmitter distortion test) \n");
return -1;
}
printf("\n==== 1000BASE-T Control Test ====\n\n");
nSockFD = socket(AF_INET, SOCK_DGRAM, 0);
if( nSockFD < 0)
{
printf("Failed to create socket (errno: %d)", errno);
return -1;
}
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, NET_DEV);
mii = (struct mii_ioctl_data *)&ifr.ifr_data;
mii->phy_id = PHY_ADDR;
/*
* 1000BASE-T/100BASE-TX/10BASE-T MII Control Register
* Bits [6,13]: 10 = 1000 Mbps
* Bits [12] : 0 = Auto-negotiation Disabled
*/
mii->reg_num = PHY_MII_CTRL_REG;
mii->val_in = 0x0040;
printf("STEP 1. Disable auto-neg and force to 1000BASE-T mode. (Address : %02Xh) \n", mii->reg_num);
if (ioctl(nSockFD, SIOCSMIIREG, &ifr) < 0)
{
perror("Failed to write register value");
close (nSockFD);
return -1;
}
/*
* 1000BASE-T/100BASE-TX/10BASE-T Miscellaneous Control Register
* Bits [9] : 0 = Auto-MDIX is disabled when autonegotiation is disabled
*/
mii->reg_num = PHY_MISC_CTRL_REG;
mii->val_in = 0x01E7;
printf("STEP 2. Disable auto-MDIX (Address : %02Xh) \n", mii->reg_num);
if (ioctl(nSockFD, SIOCSMIIREG, &ifr) < 0)
{
perror("Failed to write register value");
close (nSockFD);
return -1;
}
/*
* 1000BASE-T Control
* Bits[15:13] : 1 X X = Test mode 4—Transmitter distortion test
* 0 1 1 = Test mode 3—Slave transmit jitter test
* 0 1 0 = Test mode 2—Master transmit jitter test
* 0 0 1 = Test mode 1—Transmit waveform test
* 0 0 0 = Normal operation
*/
mii->reg_num = PHY_CTRL_REG;
mode = atoi(argv[1]);
printf("STEP 3. Enter test mode (Address : %02Xh) (Test Mode : %d)\n", mii->reg_num, mode);
switch (mode)
{
case 0 :
mii->val_in = 0x0200; /* Normal operation */
break;
case 1 :
mii->val_in = 0x2200; /* Test Mode 1 */
break;
case 2 :
mii->val_in = 0x5A00; /* Test Mode 2 */
break;
case 3 :
mii->val_in = 0x7A00; /* Test Mode 3 */
break;
case 4 :
mii->val_in = 0x8200; /* Test Mode 4 */
break;
default :
printf("Invalid mode (mode : %d)!!", mode);
close (nSockFD);
return -1;
break;
}
if (ioctl(nSockFD, SIOCSMIIREG, &ifr) < 0)
{
perror("Failed to write register value");
close (nSockFD);
return -1;
}
mii->reg_num = PHY_CTRL_REG;
if (ioctl(nSockFD, SIOCGMIIREG, &ifr) < 0)
{
perror("Failed to get register value");
close (nSockFD);
return -1;
}
printf("1000BASE-T Control Register(Address : %02XH), (Value : %04XH)\n",mii->reg_num, mii->val_out);
close (nSockFD);
return 0;
}
Makefile
CC = mipsel-linux-gcc
INC =
LIBS =
CFLAGS = -g -Wall
OBJS = testmode.o
SRCS = testmode.c
TARGET = testmode
all : $(TARGET)
$(TARGET) : $(OBJS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS)
clean :
rm -rf $(OBJS) $(TARGET)
참 고 :
Tektronix TDSET3 Ethernet Compliance Test Software
[BCM7425] An wireless script for wpa-supplicant (0) | 2014.02.28 |
---|---|
[BCM7425] cross-compile for wireless tools (0) | 2014.02.24 |
[BCM7425] iperf cross-compile (0) | 2014.02.24 |
[BCM7425] Atheros AR9300 802.11n PCI/PCI-E devices (ath9k) driver porting (0) | 2013.11.05 |