该功能主要用于mdio总线读写phy芯片寄存器。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <poll.h>
#include <sys/time.h>
#include <fcntl.h>
#include <errno.h>
#include <pthread.h>
#include <math.h>
#include <unistd.h>
#include <signal.h>
#include <sys/mman.h>
#include <net/if.h>
#include <linux/sockios.h>
#include <linux/mii.h>
#include <ctype.h>
int MdioWrite(unsigned short u16RegNum, unsigned short u16Value)
{
int sockfd, ret;
struct mii_ioctl_data *mii = NULL;
struct ifreq ifr;
const char *s8Ifrname = "eth0";
if(!s8Ifrname)
{
printf("mdio_write failed, addr null.\n");
return -1;
}
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, s8Ifrname, IFNAMSIZ - 1);
sockfd = socket(PF_LOCAL, SOCK_DGRAM, 0);
if(sockfd < 0)
{
printf("Create socket is failed.\n");
return -1;
}
//get phy address in smi bus
ret = ioctl(sockfd, SIOCGMIIPHY, &ifr);
if(ret < 0)
{
printf("Get phy address is failed.\n");
close(sockfd);
return -1;
}
mii = (struct mii_ioctl_data*)&ifr.ifr_data;
mii->reg_num = u16RegNum;
mii->val_in = u16Value;
ret = ioctl(sockfd, SIOCSMIIREG, &ifr);
if(ret < 0)
{
close(sockfd);
printf("Get phy reg value is failed.\n");
return -1;
}
close(sockfd);
//printf("write phy addr:0x%x reg:0x%x value:0x%x\n", mii->phy_id, mii->reg_num, mii->val_in);
return 0;
}
int MdioRead(unsigned short u16RegNum, unsigned short *u16Value)
{
int sockfd, ret;
struct mii_ioctl_data *mii = NULL;
struct ifreq ifr;
const char *s8Ifrname = "eth0";
if(!s8Ifrname || !u16Value)
{
printf("mdio_read failed, addr null.\n");
return -1;
}
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, s8Ifrname, IFNAMSIZ - 1);
sockfd = socket(PF_LOCAL, SOCK_DGRAM, 0);
if(sockfd < 0)
{
printf("Create socket is failed.\n");
return -1;
}
//get phy address in smi bus
ret = ioctl(sockfd, SIOCGMIIPHY, &ifr);
if(ret < 0)
{
printf("Get phy address is failed.\n");
close(sockfd);
return -1;
}
mii = (struct mii_ioctl_data*)&ifr.ifr_data;
mii->reg_num = u16RegNum;
ret = ioctl(sockfd, SIOCGMIIREG, &ifr);
if(ret < 0)
{
close(sockfd);
printf("Get phy reg value is failed.\n");
return -1;
}
*u16Value = mii->val_out;
close(sockfd);
//printf("read phy addr:0x%x reg:0x%x value:0x%x\n", mii->phy_id, mii->reg_num, mii->val_out);
return 0;
}
int CheckStr(char *str)
{
int i;
for(i = 0;i < strlen(str) - 1;i++)
{
if('0' == str[i] && ('x' == str[i + 1] || 'X' == str[i + 1]))
{
return -1;
}
}
return 0;
}
int main(int argc, char *argv[])
{
int s32Ret = -1, s32Flag;
unsigned short u16Reg, u16Value;
printf("arg: read/write[0/1] reg[xx] value[xxxx]\n\n");
s32Flag = atoi(argv[1]);
printf("s32Flag = %d argc = %d\n\n", s32Flag, argc);
if(s32Flag && 3 != argc)
{
printf("arg is err, must be 3.\n");
return -1;
}
else if(!s32Flag && 4 != argc)
{
printf("arg is err, must be 4.\n");
return -1;
}
s32Ret = CheckStr(argv[2]);
if(s32Ret < 0)
{
printf("input reg format is err, Please enter correct hex without 0x.\n");
return -1;
}
u16Reg = (unsigned short)strtoul(argv[2], NULL, 16);
if(!s32Flag)
{
s32Ret = CheckStr(argv[3]);
if(s32Ret < 0)
{
printf("input value format is err, Please enter correct hex without 0x.\n");
return -1;
}
u16Value = (unsigned short)strtoul(argv[3], NULL, 16);
}
if(s32Flag)
{
s32Ret = MdioRead(u16Reg, &u16Value);
}
else
{
s32Ret = MdioWrite(u16Reg, u16Value);
}
if(s32Ret < 0)
{
printf("mdio write is err.\n");
return -1;
}
printf("reg = 0x%x, value = 0x%x\n", u16Reg, u16Value);
return 0;
}