linux系统读写eth网卡PHY寄存器工具mdio_mmd_indirect

#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 

#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文件系统层,linux学习笔记,linux,phy,mdio)