#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <linux/mii.h>
#include <linux/sockios.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#define MII_MMD_CTRL 0x0d
#define MII_MMD_DATA 0x0e
#define DEVICE getenv("ETH_DEVICE")?getenv("ETH_DEVICE"):"eth0"
static int fd = -1;
static struct ifreq ifr;
static void mdio_read(int skfd)
{
if (ioctl(skfd, SIOCGMIIREG, &ifr) < 0) {
fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name,
strerror(errno));
}
}
static void mdio_write(int skfd)
{
if (ioctl(skfd, SIOCSMIIREG, &ifr) < 0) {
fprintf(stderr, "SIOCSMIIREG on %s failed: %s\n", ifr.ifr_name,
strerror(errno));
}
}
static void help()
{
printf("help :\n");
printf("set ETH_DEVICE to change device\n");
printf("\t\tmdio_mmd_indirect phyaddr devad reg [val]\n");
}
static inline void mdio_phy_mmd_indirect(int skfd, int devad, int reg) {
struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&ifr.ifr_data;
/* Write the desired MMD Devad */
mii->val_in = devad;
mii->reg_num = MII_MMD_CTRL;
mdio_write(skfd);
/* Write the desired MMD register address */
mii->val_in = reg;
mii->reg_num = MII_MMD_DATA;
mdio_write(skfd);
/* Select the Function: DATA with no post increment */
mii->val_in = devad | MII_MMD_CTRL_NOINCR;
mii->reg_num = MII_MMD_CTRL;
mdio_write(skfd);
}
int main(int argc, char *argv[])
{
struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&ifr.ifr_data;
int phyaddr, devad, reg, val=0;
int ret;
if ((argc < 4) || (argc > 5)) {
help();
return 1;
}
phyaddr = strtol(argv[1], NULL, 0);
devad = strtol(argv[2], NULL, 0);
reg = strtol(argv[3], NULL, 0);
if (argc == 5)
val = strtol(argv[4], NULL, 0);
fd = socket(AF_INET, SOCK_DGRAM,0);
if (fd < 0) {
perror("open");
exit(1);
}
strncpy(ifr.ifr_name, DEVICE, IFNAMSIZ);
ret = ioctl(fd, SIOCGMIIPHY, &ifr);
if (ret < 0) {
fprintf(stderr, "SIOCGMIIPHY on %s failed: %s\n", ifr.ifr_name,
strerror(errno));
return -1;
}
if (phyaddr != mii->phy_id) {
perror("wrong phy addr");
exit(1);
}
if (argc == 4) {
mdio_phy_mmd_indirect(fd, devad, reg);
mii->reg_num = MII_MMD_DATA;
mdio_read(fd);
printf("reading : 0x%04x\n", mii->val_out);
} else {
mdio_phy_mmd_indirect(fd, devad, reg);
mii->reg_num = MII_MMD_DATA;
mii->val_in = val;
mdio_write(fd);
printf("write done\n");
}
return 0;
}
linux系统读写eth网卡PHY寄存器工具mdio_mmd_indirect
最新推荐文章于 2024-03-25 16:19:29 发布